@@ -1587,6 +1587,13 @@ EXPORT_SYMBOL(input_reset_device);
static int input_dev_suspend(struct device *dev)
{
struct input_dev *input_dev = to_input_dev(dev);
+ int ret;
+
+ if (input_dev->input_dev_reset) {
+ ret = input_dev->input_dev_reset(input_dev, false);
+ if (ret)
+ return ret;
+ }
mutex_lock(&input_dev->mutex);
@@ -1601,10 +1608,14 @@ static int input_dev_suspend(struct devi
static int input_dev_resume(struct device *dev)
{
struct input_dev *input_dev = to_input_dev(dev);
+ int ret = 0;
input_reset_device(input_dev);
- return 0;
+ if (input_dev->input_dev_reset)
+ ret = input_dev->input_dev_reset(input_dev, true);
+
+ return ret;
}
static const struct dev_pm_ops input_dev_pm_ops = {
@@ -52,6 +52,7 @@ static int input_open_polled_device(stru
if (dev->poll_interval > 0)
queue_delayed_work(system_freezable_wq, &dev->work, 0);
+ dev->opened = 1;
return 0;
}
@@ -63,6 +64,24 @@ static void input_close_polled_device(st
if (dev->close)
dev->close(dev);
+
+ dev->opened = 0;
+}
+
+static int input_polled_dev_reset(struct input_dev *input, bool activate)
+{
+ struct input_polled_dev *dev = input_get_drvdata(input);
+
+ if (!dev->opened)
+ return 0;
+
+ if (activate) {
+ /* Only start polling if polling is enabled */
+ if (dev->poll_interval > 0)
+ queue_delayed_work(system_freezable_wq, &dev->work, 0);
+ } else
+ cancel_delayed_work_sync(&dev->work);
+ return 0;
}
/* SYSFS interface */
@@ -205,6 +224,7 @@ int input_register_polled_device(struct
dev->poll_interval_max = dev->poll_interval;
input->open = input_open_polled_device;
input->close = input_close_polled_device;
+ input->input_dev_reset = input_polled_dev_reset;
error = input_register_device(input);
if (error)
@@ -1269,6 +1269,7 @@ struct input_dev {
void (*close)(struct input_dev *dev);
int (*flush)(struct input_dev *dev, struct file *file);
int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
+ int (*input_dev_reset)(struct input_dev *dev, bool activate);
struct input_handle __rcu *grab;
@@ -44,6 +44,8 @@ struct input_polled_dev {
unsigned int poll_interval_max; /* msec */
unsigned int poll_interval_min; /* msec */
+ int opened;
+
struct input_dev *input;
/* private: */