diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-17 20:53:16 (GMT) |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-17 20:53:16 (GMT) |
commit | 74a205a3f1a07cf0b72bf7816d75735a0d9c4c6b (patch) | |
tree | d977fe81c74a0728130c7e212f2c27eef8146e91 /fs/sysfs/file.c | |
parent | dd26bf6d95f050c42cc8f15e750b09851e1fd30b (diff) | |
parent | 912335c43bb10d124471bf063a85e132aa814214 (diff) | |
download | linux-fsl-qoriq-74a205a3f1a07cf0b72bf7816d75735a0d9c4c6b.tar.xz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6:
UIO: fix specific device driver missing statement for depmod
Driver core: remove pr_fmt() from dynamic_dev_dbg() printk
driver core: prevent device_for_each_child from oopsing
dynamic debug: resurrect old pr_debug() semantics as pr_devel()
Driver Core: early platform driver
proc: mounts_poll() make consistent to mdstat_poll
sysfs: sysfs poll keep the poll rule of regular file.
driver core: allow non-root users to listen to uevents
driver core: fix driver_match_device
sysfs: don't use global workqueue in sysfs_schedule_callback()
Diffstat (limited to 'fs/sysfs/file.c')
-rw-r--r-- | fs/sysfs/file.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 289c43a..b1606e0 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -446,11 +446,11 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait) if (buffer->event != atomic_read(&od->event)) goto trigger; - return 0; + return DEFAULT_POLLMASK; trigger: buffer->needs_read_fill = 1; - return POLLERR|POLLPRI; + return DEFAULT_POLLMASK|POLLERR|POLLPRI; } void sysfs_notify_dirent(struct sysfs_dirent *sd) @@ -667,6 +667,7 @@ struct sysfs_schedule_callback_struct { struct work_struct work; }; +static struct workqueue_struct *sysfs_workqueue; static DEFINE_MUTEX(sysfs_workq_mutex); static LIST_HEAD(sysfs_workq); static void sysfs_schedule_callback_work(struct work_struct *work) @@ -715,11 +716,20 @@ int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), mutex_lock(&sysfs_workq_mutex); list_for_each_entry_safe(ss, tmp, &sysfs_workq, workq_list) if (ss->kobj == kobj) { + module_put(owner); mutex_unlock(&sysfs_workq_mutex); return -EAGAIN; } mutex_unlock(&sysfs_workq_mutex); + if (sysfs_workqueue == NULL) { + sysfs_workqueue = create_workqueue("sysfsd"); + if (sysfs_workqueue == NULL) { + module_put(owner); + return -ENOMEM; + } + } + ss = kmalloc(sizeof(*ss), GFP_KERNEL); if (!ss) { module_put(owner); @@ -735,7 +745,7 @@ int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), mutex_lock(&sysfs_workq_mutex); list_add_tail(&ss->workq_list, &sysfs_workq); mutex_unlock(&sysfs_workq_mutex); - schedule_work(&ss->work); + queue_work(sysfs_workqueue, &ss->work); return 0; } EXPORT_SYMBOL_GPL(sysfs_schedule_callback); |