summaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2014-04-28 22:16:00 +0200
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-05-15 01:40:03 +0200
commitd1fefd5b73ba9fe301441e84ebea06044d8f5ea4 (patch)
tree6fb8fb7babfc6194047603a859ee5f60da190a62 /drivers/input
parentInput: gpio_keys - more conversions to devm-* API (diff)
downloadlinux-d1fefd5b73ba9fe301441e84ebea06044d8f5ea4.tar.xz
linux-d1fefd5b73ba9fe301441e84ebea06044d8f5ea4.zip
Input: remove race when instantiating polled device attributes
Polled device's attributes controlling polling rate and whether polling is enabled are attached to input device. We should have device core instantiate them for us, so that they are created by the time new device notification is sent to userspace, instead of doing it ourselves afterwards. Tested-by: Alexander Shiyan <shc_work@mail.ru> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/input-polldev.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/drivers/input/input-polldev.c b/drivers/input/input-polldev.c
index 7f161d93203c..4b191908d5de 100644
--- a/drivers/input/input-polldev.c
+++ b/drivers/input/input-polldev.c
@@ -147,6 +147,11 @@ static struct attribute_group input_polldev_attribute_group = {
.attrs = sysfs_attrs
};
+static const struct attribute_group *input_polldev_attribute_groups[] = {
+ &input_polldev_attribute_group,
+ NULL
+};
+
/**
* input_allocate_polled_device - allocate memory for polled device
*
@@ -204,24 +209,21 @@ int input_register_polled_device(struct input_polled_dev *dev)
input_set_drvdata(input, dev);
INIT_DELAYED_WORK(&dev->work, input_polled_device_work);
+
if (!dev->poll_interval)
dev->poll_interval = 500;
if (!dev->poll_interval_max)
dev->poll_interval_max = dev->poll_interval;
+
input->open = input_open_polled_device;
input->close = input_close_polled_device;
+ input->dev.groups = input_polldev_attribute_groups;
+
error = input_register_device(input);
if (error)
return error;
- error = sysfs_create_group(&input->dev.kobj,
- &input_polldev_attribute_group);
- if (error) {
- input_unregister_device(input);
- return error;
- }
-
/*
* Take extra reference to the underlying input device so
* that it survives call to input_unregister_polled_device()
@@ -245,9 +247,6 @@ EXPORT_SYMBOL(input_register_polled_device);
*/
void input_unregister_polled_device(struct input_polled_dev *dev)
{
- sysfs_remove_group(&dev->input->dev.kobj,
- &input_polldev_attribute_group);
-
input_unregister_device(dev->input);
}
EXPORT_SYMBOL(input_unregister_polled_device);