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>
This commit is contained in:
parent
34abeeb235
commit
e490ebdc3c
1 changed files with 3 additions and 53 deletions
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue