Input: add support for polling to input devices
Separating "normal" and "polled" input devices was a mistake, as often we want to allow the very same device work on both interrupt-driven and polled mode, depending on the board on which the device is used. This introduces new APIs: - input_setup_polling - input_set_poll_interval - input_set_min_poll_interval - input_set_max_poll_interval These new APIs allow switching an input device into polled mode with sysfs attributes matching drivers using input_polled_dev APIs that will be eventually removed. Tested-by: Michal Vokáč <michal.vokac@ysoft.com> Acked-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include "input-compat.h"
|
||||
#include "input-poller.h"
|
||||
|
||||
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
|
||||
MODULE_DESCRIPTION("Input core");
|
||||
@@ -603,20 +604,31 @@ int input_open_device(struct input_handle *handle)
|
||||
|
||||
handle->open++;
|
||||
|
||||
if (!dev->users++ && dev->open)
|
||||
retval = dev->open(dev);
|
||||
if (dev->users++) {
|
||||
/*
|
||||
* Device is already opened, so we can exit immediately and
|
||||
* report success.
|
||||
*/
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (retval) {
|
||||
dev->users--;
|
||||
if (!--handle->open) {
|
||||
if (dev->open) {
|
||||
retval = dev->open(dev);
|
||||
if (retval) {
|
||||
dev->users--;
|
||||
handle->open--;
|
||||
/*
|
||||
* Make sure we are not delivering any more events
|
||||
* through this handle
|
||||
*/
|
||||
synchronize_rcu();
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->poller)
|
||||
input_dev_poller_start(dev->poller);
|
||||
|
||||
out:
|
||||
mutex_unlock(&dev->mutex);
|
||||
return retval;
|
||||
@@ -655,8 +667,13 @@ void input_close_device(struct input_handle *handle)
|
||||
|
||||
__input_release_device(handle);
|
||||
|
||||
if (!--dev->users && dev->close)
|
||||
dev->close(dev);
|
||||
if (!--dev->users) {
|
||||
if (dev->poller)
|
||||
input_dev_poller_stop(dev->poller);
|
||||
|
||||
if (dev->close)
|
||||
dev->close(dev);
|
||||
}
|
||||
|
||||
if (!--handle->open) {
|
||||
/*
|
||||
@@ -1502,6 +1519,7 @@ static const struct attribute_group *input_dev_attr_groups[] = {
|
||||
&input_dev_attr_group,
|
||||
&input_dev_id_attr_group,
|
||||
&input_dev_caps_attr_group,
|
||||
&input_poller_attribute_group,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -1511,6 +1529,7 @@ static void input_dev_release(struct device *device)
|
||||
|
||||
input_ff_destroy(dev);
|
||||
input_mt_destroy_slots(dev);
|
||||
kfree(dev->poller);
|
||||
kfree(dev->absinfo);
|
||||
kfree(dev->vals);
|
||||
kfree(dev);
|
||||
@@ -2175,6 +2194,9 @@ int input_register_device(struct input_dev *dev)
|
||||
if (!dev->setkeycode)
|
||||
dev->setkeycode = input_default_setkeycode;
|
||||
|
||||
if (dev->poller)
|
||||
input_dev_poller_finalize(dev->poller);
|
||||
|
||||
error = device_add(&dev->dev);
|
||||
if (error)
|
||||
goto err_free_vals;
|
||||
|
||||
Reference in New Issue
Block a user