diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-04-27 23:20:16 -0700 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-04-27 23:22:01 -0700 |
commit | e490ebdc3ce1a58e66aeacc485294a45710067f5 (patch) | |
tree | 56ac678bc0dfcbde51dd49bbd5e5668067771248 /drivers/input/input-polldev.c | |
parent | 34abeeb23575c9c25b8c582d582e5bcfcd1cf338 (diff) | |
download | lwn-e490ebdc3ce1a58e66aeacc485294a45710067f5.tar.gz lwn-e490ebdc3ce1a58e66aeacc485294a45710067f5.zip |
Input: input-polldev - use system-wide freezable workqueue
With introduction of concurrency-managed work queues there is rarely
a point in creating private workqueues.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/input-polldev.c')
-rw-r--r-- | drivers/input/input-polldev.c | 56 |
1 files changed, 3 insertions, 53 deletions
diff --git a/drivers/input/input-polldev.c b/drivers/input/input-polldev.c index 3037842a60d8..b1aabde87523 100644 --- a/drivers/input/input-polldev.c +++ b/drivers/input/input-polldev.c @@ -13,6 +13,7 @@ #include <linux/jiffies.h> #include <linux/slab.h> #include <linux/mutex.h> +#include <linux/workqueue.h> #include <linux/input-polldev.h> MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>"); @@ -20,44 +21,6 @@ MODULE_DESCRIPTION("Generic implementation of a polled input device"); MODULE_LICENSE("GPL v2"); MODULE_VERSION("0.1"); -static DEFINE_MUTEX(polldev_mutex); -static int polldev_users; -static struct workqueue_struct *polldev_wq; - -static int input_polldev_start_workqueue(void) -{ - int retval; - - retval = mutex_lock_interruptible(&polldev_mutex); - if (retval) - return retval; - - if (!polldev_users) { - polldev_wq = create_singlethread_workqueue("ipolldevd"); - if (!polldev_wq) { - pr_err("failed to create ipolldevd workqueue\n"); - retval = -ENOMEM; - goto out; - } - } - - polldev_users++; - - out: - mutex_unlock(&polldev_mutex); - return retval; -} - -static void input_polldev_stop_workqueue(void) -{ - mutex_lock(&polldev_mutex); - - if (!--polldev_users) - destroy_workqueue(polldev_wq); - - mutex_unlock(&polldev_mutex); -} - static void input_polldev_queue_work(struct input_polled_dev *dev) { unsigned long delay; @@ -66,7 +29,7 @@ static void input_polldev_queue_work(struct input_polled_dev *dev) if (delay >= HZ) delay = round_jiffies_relative(delay); - queue_delayed_work(polldev_wq, &dev->work, delay); + queue_delayed_work(system_freezable_wq, &dev->work, delay); } static void input_polled_device_work(struct work_struct *work) @@ -81,18 +44,13 @@ static void input_polled_device_work(struct work_struct *work) static int input_open_polled_device(struct input_dev *input) { struct input_polled_dev *dev = input_get_drvdata(input); - int error; - - error = input_polldev_start_workqueue(); - if (error) - return error; if (dev->open) dev->open(dev); /* Only start polling if polling is enabled */ if (dev->poll_interval > 0) - queue_delayed_work(polldev_wq, &dev->work, 0); + queue_delayed_work(system_freezable_wq, &dev->work, 0); return 0; } @@ -102,13 +60,6 @@ static void input_close_polled_device(struct input_dev *input) struct input_polled_dev *dev = input_get_drvdata(input); cancel_delayed_work_sync(&dev->work); - /* - * Clean up work struct to remove references to the workqueue. - * It may be destroyed by the next call. This causes problems - * at next device open-close in case of poll_interval == 0. - */ - INIT_DELAYED_WORK(&dev->work, dev->work.work.func); - input_polldev_stop_workqueue(); if (dev->close) dev->close(dev); @@ -295,4 +246,3 @@ void input_unregister_polled_device(struct input_polled_dev *dev) input_unregister_device(dev->input); } EXPORT_SYMBOL(input_unregister_polled_device); - |