diff options
Diffstat (limited to 'drivers/input/input.c')
| -rw-r--r-- | drivers/input/input.c | 114 |
1 files changed, 85 insertions, 29 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index ce01332f7b3..29ca0bb4f56 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -257,9 +257,10 @@ static int input_handle_abs_event(struct input_dev *dev, } static int input_get_disposition(struct input_dev *dev, - unsigned int type, unsigned int code, int value) + unsigned int type, unsigned int code, int *pval) { int disposition = INPUT_IGNORE_EVENT; + int value = *pval; switch (type) { @@ -357,6 +358,7 @@ static int input_get_disposition(struct input_dev *dev, break; } + *pval = value; return disposition; } @@ -365,7 +367,7 @@ static void input_handle_event(struct input_dev *dev, { int disposition; - disposition = input_get_disposition(dev, type, code, value); + disposition = input_get_disposition(dev, type, code, &value); if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event) dev->event(dev, type, code, value); @@ -1653,35 +1655,36 @@ static void input_dev_toggle(struct input_dev *dev, bool activate) */ void input_reset_device(struct input_dev *dev) { - mutex_lock(&dev->mutex); + unsigned long flags; - if (dev->users) { - input_dev_toggle(dev, true); + mutex_lock(&dev->mutex); + spin_lock_irqsave(&dev->event_lock, flags); - /* - * Keys that have been pressed at suspend time are unlikely - * to be still pressed when we resume. - */ - spin_lock_irq(&dev->event_lock); - input_dev_release_keys(dev); - spin_unlock_irq(&dev->event_lock); - } + input_dev_toggle(dev, true); + input_dev_release_keys(dev); + spin_unlock_irqrestore(&dev->event_lock, flags); mutex_unlock(&dev->mutex); } EXPORT_SYMBOL(input_reset_device); -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int input_dev_suspend(struct device *dev) { struct input_dev *input_dev = to_input_dev(dev); - mutex_lock(&input_dev->mutex); + spin_lock_irq(&input_dev->event_lock); - if (input_dev->users) - input_dev_toggle(input_dev, false); + /* + * Keys that are pressed now are unlikely to be + * still pressed when we resume. + */ + input_dev_release_keys(input_dev); - mutex_unlock(&input_dev->mutex); + /* Turn off LEDs and sounds, if any are active. */ + input_dev_toggle(input_dev, false); + + spin_unlock_irq(&input_dev->event_lock); return 0; } @@ -1690,7 +1693,43 @@ static int input_dev_resume(struct device *dev) { struct input_dev *input_dev = to_input_dev(dev); - input_reset_device(input_dev); + spin_lock_irq(&input_dev->event_lock); + + /* Restore state of LEDs and sounds, if any were active. */ + input_dev_toggle(input_dev, true); + + spin_unlock_irq(&input_dev->event_lock); + + return 0; +} + +static int input_dev_freeze(struct device *dev) +{ + struct input_dev *input_dev = to_input_dev(dev); + + spin_lock_irq(&input_dev->event_lock); + + /* + * Keys that are pressed now are unlikely to be + * still pressed when we resume. + */ + input_dev_release_keys(input_dev); + + spin_unlock_irq(&input_dev->event_lock); + + return 0; +} + +static int input_dev_poweroff(struct device *dev) +{ + struct input_dev *input_dev = to_input_dev(dev); + + spin_lock_irq(&input_dev->event_lock); + + /* Turn off LEDs and sounds, if any are active. */ + input_dev_toggle(input_dev, false); + + spin_unlock_irq(&input_dev->event_lock); return 0; } @@ -1698,7 +1737,8 @@ static int input_dev_resume(struct device *dev) static const struct dev_pm_ops input_dev_pm_ops = { .suspend = input_dev_suspend, .resume = input_dev_resume, - .poweroff = input_dev_suspend, + .freeze = input_dev_freeze, + .poweroff = input_dev_poweroff, .restore = input_dev_resume, }; #endif /* CONFIG_PM */ @@ -1707,7 +1747,7 @@ static struct device_type input_dev_type = { .groups = input_dev_attr_groups, .release = input_dev_release, .uevent = input_dev_uevent, -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP .pm = &input_dev_pm_ops, #endif }; @@ -1734,6 +1774,7 @@ EXPORT_SYMBOL_GPL(input_class); */ struct input_dev *input_allocate_device(void) { + static atomic_t input_no = ATOMIC_INIT(0); struct input_dev *dev; dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL); @@ -1743,9 +1784,13 @@ struct input_dev *input_allocate_device(void) device_initialize(&dev->dev); mutex_init(&dev->mutex); spin_lock_init(&dev->event_lock); + init_timer(&dev->timer); INIT_LIST_HEAD(&dev->h_list); INIT_LIST_HEAD(&dev->node); + dev_set_name(&dev->dev, "input%ld", + (unsigned long) atomic_inc_return(&input_no) - 1); + __module_get(THIS_MODULE); } @@ -1785,12 +1830,13 @@ static void devm_input_device_release(struct device *dev, void *res) * its driver (or binding fails). Once managed input device is allocated, * it is ready to be set up and registered in the same fashion as regular * input device. There are no special devm_input_device_[un]register() - * variants, regular ones work with both managed and unmanaged devices. + * variants, regular ones work with both managed and unmanaged devices, + * should you need them. In most cases however, managed input device need + * not be explicitly unregistered or freed. * * NOTE: the owner device is set up as parent of input device and users * should not override it. */ - struct input_dev *devm_input_allocate_device(struct device *dev) { struct input_dev *input; @@ -1865,6 +1911,10 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int break; case EV_ABS: + input_alloc_absinfo(dev); + if (!dev->absinfo) + return; + __set_bit(code, dev->absbit); break; @@ -2004,10 +2054,20 @@ static void devm_input_device_unregister(struct device *dev, void *res) * Once device has been successfully registered it can be unregistered * with input_unregister_device(); input_free_device() should not be * called in this case. + * + * Note that this function is also used to register managed input devices + * (ones allocated with devm_input_allocate_device()). Such managed input + * devices need not be explicitly unregistered or freed, their tear down + * is controlled by the devres infrastructure. It is also worth noting + * that tear down of managed input devices is internally a 2-step process: + * registered managed input device is first unregistered, but stays in + * memory and can still handle input_event() calls (although events will + * not be delivered anywhere). The freeing of managed input device will + * happen later, when devres stack is unwound to the point where device + * allocation was made. */ int input_register_device(struct input_dev *dev) { - static atomic_t input_no = ATOMIC_INIT(0); struct input_devres *devres = NULL; struct input_handler *handler; unsigned int packet_size; @@ -2036,7 +2096,7 @@ int input_register_device(struct input_dev *dev) if (dev->hint_events_per_packet < packet_size) dev->hint_events_per_packet = packet_size; - dev->max_vals = max(dev->hint_events_per_packet, packet_size) + 2; + dev->max_vals = dev->hint_events_per_packet + 2; dev->vals = kcalloc(dev->max_vals, sizeof(*dev->vals), GFP_KERNEL); if (!dev->vals) { error = -ENOMEM; @@ -2047,7 +2107,6 @@ int input_register_device(struct input_dev *dev) * If delay and period are pre-set by the driver, then autorepeating * is handled by the driver itself and we don't do it in input.c. */ - init_timer(&dev->timer); if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) { dev->timer.data = (long) dev; dev->timer.function = input_repeat_key; @@ -2061,9 +2120,6 @@ int input_register_device(struct input_dev *dev) if (!dev->setkeycode) dev->setkeycode = input_default_setkeycode; - dev_set_name(&dev->dev, "input%ld", - (unsigned long) atomic_inc_return(&input_no) - 1); - error = device_add(&dev->dev); if (error) goto err_free_vals; |
