diff options
Diffstat (limited to 'drivers/input/misc')
-rw-r--r-- | drivers/input/misc/Kconfig | 14 | ||||
-rw-r--r-- | drivers/input/misc/Makefile | 1 | ||||
-rw-r--r-- | drivers/input/misc/ad714x-spi.c | 1 | ||||
-rw-r--r-- | drivers/input/misc/adxl34x.c | 2 | ||||
-rw-r--r-- | drivers/input/misc/cm109.c | 14 | ||||
-rw-r--r-- | drivers/input/misc/cobalt_btns.c | 2 | ||||
-rw-r--r-- | drivers/input/misc/hp_sdc_rtc.c | 5 | ||||
-rw-r--r-- | drivers/input/misc/ideapad_slidebar.c | 358 | ||||
-rw-r--r-- | drivers/input/misc/ixp4xx-beeper.c | 25 | ||||
-rw-r--r-- | drivers/input/misc/mma8450.c | 4 | ||||
-rw-r--r-- | drivers/input/misc/mpu3050.c | 1 | ||||
-rw-r--r-- | drivers/input/misc/pcf8574_keypad.c | 7 | ||||
-rw-r--r-- | drivers/input/misc/pwm-beeper.c | 3 | ||||
-rw-r--r-- | drivers/input/misc/rb532_button.c | 1 | ||||
-rw-r--r-- | drivers/input/misc/rotary_encoder.c | 1 | ||||
-rw-r--r-- | drivers/input/misc/sirfsoc-onkey.c | 2 | ||||
-rw-r--r-- | drivers/input/misc/twl6040-vibra.c | 41 | ||||
-rw-r--r-- | drivers/input/misc/uinput.c | 26 | ||||
-rw-r--r-- | drivers/input/misc/wistron_btns.c | 6 |
19 files changed, 451 insertions, 63 deletions
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 0b541cdf9b8e..5f4967d01bc3 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -156,7 +156,7 @@ config INPUT_MAX8925_ONKEY config INPUT_MAX8997_HAPTIC tristate "MAXIM MAX8997 haptic controller support" - depends on HAVE_PWM && MFD_MAX8997 + depends on PWM && HAVE_PWM && MFD_MAX8997 select INPUT_FF_MEMLESS help This option enables device driver support for the haptic controller @@ -461,7 +461,7 @@ config INPUT_PCF8574 config INPUT_PWM_BEEPER tristate "PWM beeper support" - depends on HAVE_PWM || PWM + depends on PWM && HAVE_PWM help Say Y here to get support for PWM based beeper devices. @@ -647,4 +647,14 @@ config INPUT_SIRFSOC_ONKEY If unsure, say N. +config INPUT_IDEAPAD_SLIDEBAR + tristate "IdeaPad Laptop Slidebar" + depends on INPUT + depends on SERIO_I8042 + help + Say Y here if you have an IdeaPad laptop with a slidebar. + + To compile this driver as a module, choose M here: the + module will be called ideapad_slidebar. + endif diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 829de43a2427..0ebfb6dbf0f7 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -61,3 +61,4 @@ obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o obj-$(CONFIG_INPUT_YEALINK) += yealink.o +obj-$(CONFIG_INPUT_IDEAPAD_SLIDEBAR) += ideapad_slidebar.o diff --git a/drivers/input/misc/ad714x-spi.c b/drivers/input/misc/ad714x-spi.c index 61891486067c..3a90b710e309 100644 --- a/drivers/input/misc/ad714x-spi.c +++ b/drivers/input/misc/ad714x-spi.c @@ -108,7 +108,6 @@ static int ad714x_spi_remove(struct spi_device *spi) struct ad714x_chip *chip = spi_get_drvdata(spi); ad714x_remove(chip); - spi_set_drvdata(spi, NULL); return 0; } diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c index 0735de3a6468..1cb1da294419 100644 --- a/drivers/input/misc/adxl34x.c +++ b/drivers/input/misc/adxl34x.c @@ -158,7 +158,7 @@ /* ORIENT ADXL346 only */ #define ADXL346_2D_VALID (1 << 6) -#define ADXL346_2D_ORIENT(x) (((x) & 0x3) >> 4) +#define ADXL346_2D_ORIENT(x) (((x) & 0x30) >> 4) #define ADXL346_3D_VALID (1 << 3) #define ADXL346_3D_ORIENT(x) ((x) & 0x7) #define ADXL346_2D_PORTRAIT_POS 0 /* +X */ diff --git a/drivers/input/misc/cm109.c b/drivers/input/misc/cm109.c index 082684e7f390..9365535ba7f1 100644 --- a/drivers/input/misc/cm109.c +++ b/drivers/input/misc/cm109.c @@ -351,7 +351,9 @@ static void cm109_urb_irq_callback(struct urb *urb) if (status) { if (status == -ESHUTDOWN) return; - dev_err(&dev->intf->dev, "%s: urb status %d\n", __func__, status); + dev_err_ratelimited(&dev->intf->dev, "%s: urb status %d\n", + __func__, status); + goto out; } /* Special keys */ @@ -418,8 +420,12 @@ static void cm109_urb_ctl_callback(struct urb *urb) dev->ctl_data->byte[2], dev->ctl_data->byte[3]); - if (status) - dev_err(&dev->intf->dev, "%s: urb status %d\n", __func__, status); + if (status) { + if (status == -ESHUTDOWN) + return; + dev_err_ratelimited(&dev->intf->dev, "%s: urb status %d\n", + __func__, status); + } spin_lock(&dev->ctl_submit_lock); @@ -427,7 +433,7 @@ static void cm109_urb_ctl_callback(struct urb *urb) if (likely(!dev->shutdown)) { - if (dev->buzzer_pending) { + if (dev->buzzer_pending || status) { dev->buzzer_pending = 0; dev->ctl_urb_pending = 1; cm109_submit_buzz_toggle(dev); diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c index 4f77f87847e8..b5d71d245854 100644 --- a/drivers/input/misc/cobalt_btns.c +++ b/drivers/input/misc/cobalt_btns.c @@ -131,7 +131,6 @@ static int cobalt_buttons_probe(struct platform_device *pdev) err_free_mem: input_free_polled_device(poll_dev); kfree(bdev); - dev_set_drvdata(&pdev->dev, NULL); return error; } @@ -144,7 +143,6 @@ static int cobalt_buttons_remove(struct platform_device *pdev) input_free_polled_device(bdev->poll_dev); iounmap(bdev->reg); kfree(bdev); - dev_set_drvdata(dev, NULL); return 0; } diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c index 86b822806e95..45e0e3e55de2 100644 --- a/drivers/input/misc/hp_sdc_rtc.c +++ b/drivers/input/misc/hp_sdc_rtc.c @@ -180,7 +180,10 @@ static int64_t hp_sdc_rtc_read_i8042timer (uint8_t loadcmd, int numreg) if (WARN_ON(down_interruptible(&i8042tregs))) return -1; - if (hp_sdc_enqueue_transaction(&t)) return -1; + if (hp_sdc_enqueue_transaction(&t)) { + up(&i8042tregs); + return -1; + } /* Sleep until results come back. */ if (WARN_ON(down_interruptible(&i8042tregs))) diff --git a/drivers/input/misc/ideapad_slidebar.c b/drivers/input/misc/ideapad_slidebar.c new file mode 100644 index 000000000000..edfd6239f131 --- /dev/null +++ b/drivers/input/misc/ideapad_slidebar.c @@ -0,0 +1,358 @@ +/* + * Input driver for slidebars on some Lenovo IdeaPad laptops + * + * Copyright (C) 2013 Andrey Moiseev <o2g.org.ru@gmail.com> + * + * Reverse-engineered from Lenovo SlideNav software (SBarHook.dll). + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * Trademarks are the property of their respective owners. + */ + +/* + * Currently tested and works on: + * Lenovo IdeaPad Y550 + * Lenovo IdeaPad Y550P + * + * Other models can be added easily. To test, + * load with 'force' parameter set 'true'. + * + * LEDs blinking and input mode are managed via sysfs, + * (hex, unsigned byte value): + * /sys/devices/platform/ideapad_slidebar/slidebar_mode + * + * The value is in byte range, however, I only figured out + * how bits 0b10011001 work. Some other bits, probably, + * are meaningfull too. + * + * Possible states: + * + * STD_INT, ONMOV_INT, OFF_INT, LAST_POLL, OFF_POLL + * + * Meaning: + * released touched + * STD 'heartbeat' lights follow the finger + * ONMOV no lights lights follow the finger + * LAST at last pos lights follow the finger + * OFF no lights no lights + * + * INT all input events are generated, interrupts are used + * POLL no input events by default, to get them, + * send 0b10000000 (read below) + * + * Commands: write + * + * All | 0b01001 -> STD_INT + * possible | 0b10001 -> ONMOV_INT + * states | 0b01000 -> OFF_INT + * + * | 0b0 -> LAST_POLL + * STD_INT or ONMOV_INT | + * | 0b1 -> STD_INT + * + * | 0b0 -> OFF_POLL + * OFF_INT or OFF_POLL | + * | 0b1 -> OFF_INT + * + * Any state | 0b10000000 -> if the slidebar has updated data, + * produce one input event (last position), + * switch to respective POLL mode + * (like 0x0), if not in POLL mode yet. + * + * Get current state: read + * + * masked by 0x11 read value means: + * + * 0x00 LAST + * 0x01 STD + * 0x10 OFF + * 0x11 ONMOV + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/dmi.h> +#include <linux/spinlock.h> +#include <linux/platform_device.h> +#include <linux/input.h> +#include <linux/io.h> +#include <linux/ioport.h> +#include <linux/i8042.h> +#include <linux/serio.h> + +#define IDEAPAD_BASE 0xff29 + +static bool force; +module_param(force, bool, 0); +MODULE_PARM_DESC(force, "Force driver load, ignore DMI data"); + +static DEFINE_SPINLOCK(io_lock); + +static struct input_dev *slidebar_input_dev; +static struct platform_device *slidebar_platform_dev; + +static u8 slidebar_pos_get(void) +{ + u8 res; + unsigned long flags; + + spin_lock_irqsave(&io_lock, flags); + outb(0xf4, 0xff29); + outb(0xbf, 0xff2a); + res = inb(0xff2b); + spin_unlock_irqrestore(&io_lock, flags); + + return res; +} + +static u8 slidebar_mode_get(void) +{ + u8 res; + unsigned long flags; + + spin_lock_irqsave(&io_lock, flags); + outb(0xf7, 0xff29); + outb(0x8b, 0xff2a); + res = inb(0xff2b); + spin_unlock_irqrestore(&io_lock, flags); + + return res; +} + +static void slidebar_mode_set(u8 mode) +{ + unsigned long flags; + + spin_lock_irqsave(&io_lock, flags); + outb(0xf7, 0xff29); + outb(0x8b, 0xff2a); + outb(mode, 0xff2b); + spin_unlock_irqrestore(&io_lock, flags); +} + +static bool slidebar_i8042_filter(unsigned char data, unsigned char str, + struct serio *port) +{ + static bool extended = false; + + /* We are only interested in data coming form KBC port */ + if (str & I8042_STR_AUXDATA) + return false; + + /* Scancodes: e03b on move, e0bb on release. */ + if (data == 0xe0) { + extended = true; + return true; + } + + if (!extended) + return false; + + extended = false; + + if (likely((data & 0x7f) != 0x3b)) { + serio_interrupt(port, 0xe0, 0); + return false; + } + + if (data & 0x80) { + input_report_key(slidebar_input_dev, BTN_TOUCH, 0); + } else { + input_report_key(slidebar_input_dev, BTN_TOUCH, 1); + input_report_abs(slidebar_input_dev, ABS_X, slidebar_pos_get()); + } + input_sync(slidebar_input_dev); + + return true; +} + +static ssize_t show_slidebar_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%x\n", slidebar_mode_get()); +} + +static ssize_t store_slidebar_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + u8 mode; + int error; + + error = kstrtou8(buf, 0, &mode); + if (error) + return error; + + slidebar_mode_set(mode); + + return count; +} + +static DEVICE_ATTR(slidebar_mode, S_IWUSR | S_IRUGO, + show_slidebar_mode, store_slidebar_mode); + +static struct attribute *ideapad_attrs[] = { + &dev_attr_slidebar_mode.attr, + NULL +}; + +static struct attribute_group ideapad_attr_group = { + .attrs = ideapad_attrs +}; + +static const struct attribute_group *ideapad_attr_groups[] = { + &ideapad_attr_group, + NULL +}; + +static int __init ideapad_probe(struct platform_device* pdev) +{ + int err; + + if (!request_region(IDEAPAD_BASE, 3, "ideapad_slidebar")) { + dev_err(&pdev->dev, "IO ports are busy\n"); + return -EBUSY; + } + + slidebar_input_dev = input_allocate_device(); + if (!slidebar_input_dev) { + dev_err(&pdev->dev, "Failed to allocate input device\n"); + err = -ENOMEM; + goto err_release_ports; + } + + slidebar_input_dev->name = "IdeaPad Slidebar"; + slidebar_input_dev->id.bustype = BUS_HOST; + slidebar_input_dev->dev.parent = &pdev->dev; + input_set_capability(slidebar_input_dev, EV_KEY, BTN_TOUCH); + input_set_capability(slidebar_input_dev, EV_ABS, ABS_X); + input_set_abs_params(slidebar_input_dev, ABS_X, 0, 0xff, 0, 0); + + err = i8042_install_filter(slidebar_i8042_filter); + if (err) { + dev_err(&pdev->dev, + "Failed to install i8042 filter: %d\n", err); + goto err_free_dev; + } + + err = input_register_device(slidebar_input_dev); + if (err) { + dev_err(&pdev->dev, + "Failed to register input device: %d\n", err); + goto err_remove_filter; + } + + return 0; + +err_remove_filter: + i8042_remove_filter(slidebar_i8042_filter); +err_free_dev: + input_free_device(slidebar_input_dev); +err_release_ports: + release_region(IDEAPAD_BASE, 3); + return err; +} + +static int ideapad_remove(struct platform_device *pdev) +{ + i8042_remove_filter(slidebar_i8042_filter); + input_unregister_device(slidebar_input_dev); + release_region(IDEAPAD_BASE, 3); + + return 0; +} + +static struct platform_driver slidebar_drv = { + .driver = { + .name = "ideapad_slidebar", + .owner = THIS_MODULE, + }, + .remove = ideapad_remove, +}; + +static int __init ideapad_dmi_check(const struct dmi_system_id *id) +{ + pr_info("Laptop model '%s'\n", id->ident); + return 1; +} + +static const struct dmi_system_id ideapad_dmi[] __initconst = { + { + .ident = "Lenovo IdeaPad Y550", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20017"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo IdeaPad Y550") + }, + .callback = ideapad_dmi_check + }, + { + .ident = "Lenovo IdeaPad Y550P", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20035"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo IdeaPad Y550P") + }, + .callback = ideapad_dmi_check + }, + { NULL, } +}; +MODULE_DEVICE_TABLE(dmi, ideapad_dmi); + +static int __init slidebar_init(void) +{ + int err; + + if (!force && !dmi_check_system(ideapad_dmi)) { + pr_err("DMI does not match\n"); + return -ENODEV; + } + + slidebar_platform_dev = platform_device_alloc("ideapad_slidebar", -1); + if (!slidebar_platform_dev) { + pr_err("Not enough memory\n"); + return -ENOMEM; + } + + slidebar_platform_dev->dev.groups = ideapad_attr_groups; + + err = platform_device_add(slidebar_platform_dev); + if (err) { + pr_err("Failed to register platform device\n"); + goto err_free_dev; + } + + err = platform_driver_probe(&slidebar_drv, ideapad_probe); + if (err) { + pr_err("Failed to register platform driver\n"); + goto err_delete_dev; + } + + return 0; + +err_delete_dev: + platform_device_del(slidebar_platform_dev); +err_free_dev: + platform_device_put(slidebar_platform_dev); + return err; +} + +static void __exit slidebar_exit(void) +{ + platform_device_unregister(slidebar_platform_dev); + platform_driver_unregister(&slidebar_drv); +} + +module_init(slidebar_init); +module_exit(slidebar_exit); + +MODULE_AUTHOR("Andrey Moiseev <o2g.org.ru@gmail.com>"); +MODULE_DESCRIPTION("Slidebar input support for some Lenovo IdeaPad laptops"); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c index f34beb228d36..17ccba88d636 100644 --- a/drivers/input/misc/ixp4xx-beeper.c +++ b/drivers/input/misc/ixp4xx-beeper.c @@ -20,6 +20,7 @@ #include <linux/delay.h> #include <linux/platform_device.h> #include <linux/interrupt.h> +#include <linux/gpio.h> #include <mach/hardware.h> MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); @@ -35,15 +36,12 @@ static void ixp4xx_spkr_control(unsigned int pin, unsigned int count) spin_lock_irqsave(&beep_lock, flags); - if (count) { - gpio_line_config(pin, IXP4XX_GPIO_OUT); - gpio_line_set(pin, IXP4XX_GPIO_LOW); - + if (count) { + gpio_direction_output(pin, 0); *IXP4XX_OSRT2 = (count & ~IXP4XX_OST_RELOAD_MASK) | IXP4XX_OST_ENABLE; } else { - gpio_line_config(pin, IXP4XX_GPIO_IN); - gpio_line_set(pin, IXP4XX_GPIO_HIGH); - + gpio_direction_output(pin, 1); + gpio_direction_input(pin); *IXP4XX_OSRT2 = 0; } @@ -78,11 +76,13 @@ static int ixp4xx_spkr_event(struct input_dev *dev, unsigned int type, unsigned static irqreturn_t ixp4xx_spkr_interrupt(int irq, void *dev_id) { + unsigned int pin = (unsigned int) dev_id; + /* clear interrupt */ *IXP4XX_OSST = IXP4XX_OSST_TIMER_2_PEND; /* flip the beeper output */ - *IXP4XX_GPIO_GPOUTR ^= (1 << (unsigned int) dev_id); + gpio_set_value(pin, !gpio_get_value(pin)); return IRQ_HANDLED; } @@ -110,11 +110,15 @@ static int ixp4xx_spkr_probe(struct platform_device *dev) input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); input_dev->event = ixp4xx_spkr_event; + err = gpio_request(dev->id, "ixp4-beeper"); + if (err) + goto err_free_device; + err = request_irq(IRQ_IXP4XX_TIMER2, &ixp4xx_spkr_interrupt, IRQF_NO_SUSPEND, "ixp4xx-beeper", (void *) dev->id); if (err) - goto err_free_device; + goto err_free_gpio; err = input_register_device(input_dev); if (err) @@ -126,6 +130,8 @@ static int ixp4xx_spkr_probe(struct platform_device *dev) err_free_irq: free_irq(IRQ_IXP4XX_TIMER2, (void *)dev->id); + err_free_gpio: + gpio_free(dev->id); err_free_device: input_free_device(input_dev); @@ -144,6 +150,7 @@ static int ixp4xx_spkr_remove(struct platform_device *dev) ixp4xx_spkr_control(pin, 0); free_irq(IRQ_IXP4XX_TIMER2, (void *)dev->id); + gpio_free(dev->id); return 0; } diff --git a/drivers/input/misc/mma8450.c b/drivers/input/misc/mma8450.c index f3309696d053..59d4dcddf6de 100644 --- a/drivers/input/misc/mma8450.c +++ b/drivers/input/misc/mma8450.c @@ -168,7 +168,7 @@ static void mma8450_close(struct input_polled_dev *dev) * I2C init/probing/exit functions */ static int mma8450_probe(struct i2c_client *c, - const struct i2c_device_id *id) + const struct i2c_device_id *id) { struct input_polled_dev *idev; struct mma8450 *m; @@ -204,6 +204,8 @@ static int mma8450_probe(struct i2c_client *c, goto err_free_mem; } + i2c_set_clientdata(c, m); + return 0; err_free_mem: diff --git a/drivers/input/misc/mpu3050.c b/drivers/input/misc/mpu3050.c index dce0d95943c5..6983ffbbfb94 100644 --- a/drivers/input/misc/mpu3050.c +++ b/drivers/input/misc/mpu3050.c @@ -383,6 +383,7 @@ static int mpu3050_probe(struct i2c_client *client, pm_runtime_enable(&client->dev); pm_runtime_set_autosuspend_delay(&client->dev, MPU3050_AUTO_DELAY); + i2c_set_clientdata(client, sensor); return 0; diff --git a/drivers/input/misc/pcf8574_keypad.c b/drivers/input/misc/pcf8574_keypad.c index e37392976fdd..0deca5a3c87f 100644 --- a/drivers/input/misc/pcf8574_keypad.c +++ b/drivers/input/misc/pcf8574_keypad.c @@ -113,9 +113,12 @@ static int pcf8574_kp_probe(struct i2c_client *client, const struct i2c_device_i idev->keycodemax = ARRAY_SIZE(lp->btncode); for (i = 0; i < ARRAY_SIZE(pcf8574_kp_btncode); i++) { - lp->btncode[i] = pcf8574_kp_btncode[i]; - __set_bit(lp->btncode[i] & KEY_MAX, idev->keybit); + if (lp->btncode[i] <= KEY_MAX) { + lp->btncode[i] = pcf8574_kp_btncode[i]; + __set_bit(lp->btncode[i], idev->keybit); + } } + __clear_bit(KEY_RESERVED, idev->keybit); sprintf(lp->name, DRV_NAME); sprintf(lp->phys, "kp_data/input0"); diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c index a37f0c909aba..940566e7be13 100644 --- a/drivers/input/misc/pwm-beeper.c +++ b/drivers/input/misc/pwm-beeper.c @@ -16,6 +16,7 @@ #include <linux/input.h> #include <linux/module.h> #include <linux/kernel.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/pwm.h> #include <linux/slab.h> @@ -143,7 +144,7 @@ static int pwm_beeper_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int pwm_beeper_suspend(struct device *dev) { struct pwm_beeper *beeper = dev_get_drvdata(dev); diff --git a/drivers/input/misc/rb532_button.c b/drivers/input/misc/rb532_button.c index fb4f8ac3343b..83fff38b86b3 100644 --- a/drivers/input/misc/rb532_button.c +++ b/drivers/input/misc/rb532_button.c @@ -87,7 +87,6 @@ static int rb532_button_remove(struct platform_device *pdev) input_unregister_polled_device(poll_dev); input_free_polled_device(poll_dev); - dev_set_drvdata(&pdev->dev, NULL); return 0; } diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 5b1aff825138..f920ba7ab51f 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c @@ -24,6 +24,7 @@ #include <linux/gpio.h> #include <linux/rotary_encoder.h> #include <linux/slab.h> +#include <linux/of.h> #include <linux/of_platform.h> #include <linux/of_gpio.h> diff --git a/drivers/input/misc/sirfsoc-onkey.c b/drivers/input/misc/sirfsoc-onkey.c index 0621c367049a..7b8b03e0d0be 100644 --- a/drivers/input/misc/sirfsoc-onkey.c +++ b/drivers/input/misc/sirfsoc-onkey.c @@ -153,7 +153,7 @@ static struct platform_driver sirfsoc_pwrc_driver = { .name = "sirfsoc-pwrc", .owner = THIS_MODULE, .pm = &sirfsoc_pwrc_pm_ops, - .of_match_table = of_match_ptr(sirfsoc_pwrc_of_match), + .of_match_table = sirfsoc_pwrc_of_match, } }; diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c index 0c2dfc8e9691..7864b0c3ebb3 100644 --- a/drivers/input/misc/twl6040-vibra.c +++ b/drivers/input/misc/twl6040-vibra.c @@ -257,7 +257,6 @@ static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL); static int twl6040_vibra_probe(struct platform_device *pdev) { - struct twl6040_vibra_data *pdata = pdev->dev.platform_data; struct device *twl6040_core_dev = pdev->dev.parent; struct device_node *twl6040_core_node = NULL; struct vibra_info *info; @@ -270,8 +269,8 @@ static int twl6040_vibra_probe(struct platform_device *pdev) "vibra"); #endif - if (!pdata && !twl6040_core_node) { - dev_err(&pdev->dev, "platform_data not available\n"); + if (!twl6040_core_node) { + dev_err(&pdev->dev, "parent of node is missing?\n"); return -EINVAL; } @@ -284,27 +283,17 @@ static int twl6040_vibra_probe(struct platform_device *pdev) info->dev = &pdev->dev; info->twl6040 = dev_get_drvdata(pdev->dev.parent); - if (pdata) { - info->vibldrv_res = pdata->vibldrv_res; - info->vibrdrv_res = pdata->vibrdrv_res; - info->viblmotor_res = pdata->viblmotor_res; - info->vibrmotor_res = pdata->vibrmotor_res; - vddvibl_uV = pdata->vddvibl_uV; - vddvibr_uV = pdata->vddvibr_uV; - } else { - of_property_read_u32(twl6040_core_node, "ti,vibldrv-res", - &info->vibldrv_res); - of_property_read_u32(twl6040_core_node, "ti,vibrdrv-res", - &info->vibrdrv_res); - of_property_read_u32(twl6040_core_node, "ti,viblmotor-res", - &info->viblmotor_res); - of_property_read_u32(twl6040_core_node, "ti,vibrmotor-res", - &info->vibrmotor_res); - of_property_read_u32(twl6040_core_node, "ti,vddvibl-uV", - &vddvibl_uV); - of_property_read_u32(twl6040_core_node, "ti,vddvibr-uV", - &vddvibr_uV); - } + + of_property_read_u32(twl6040_core_node, "ti,vibldrv-res", + &info->vibldrv_res); + of_property_read_u32(twl6040_core_node, "ti,vibrdrv-res", + &info->vibrdrv_res); + of_property_read_u32(twl6040_core_node, "ti,viblmotor-res", + &info->viblmotor_res); + of_property_read_u32(twl6040_core_node, "ti,vibrmotor-res", + &info->vibrmotor_res); + of_property_read_u32(twl6040_core_node, "ti,vddvibl-uV", &vddvibl_uV); + of_property_read_u32(twl6040_core_node, "ti,vddvibr-uV", &vddvibr_uV); if ((!info->vibldrv_res && !info->viblmotor_res) || (!info->vibrdrv_res && !info->vibrmotor_res)) { @@ -334,8 +323,8 @@ static int twl6040_vibra_probe(struct platform_device *pdev) * When booted with Device tree the regulators are attached to the * parent device (twl6040 MFD core) */ - ret = regulator_bulk_get(pdata ? info->dev : twl6040_core_dev, - ARRAY_SIZE(info->supplies), info->supplies); + ret = regulator_bulk_get(twl6040_core_dev, ARRAY_SIZE(info->supplies), + info->supplies); if (ret) { dev_err(info->dev, "couldn't get regulators %d\n", ret); return ret; diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index a0a4bbaef02c..772835938a52 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -430,20 +430,30 @@ static int uinput_setup_device(struct uinput_device *udev, return retval; } -static ssize_t uinput_inject_event(struct uinput_device *udev, - const char __user *buffer, size_t count) +static ssize_t uinput_inject_events(struct uinput_device *udev, + const char __user *buffer, size_t count) { struct input_event ev; + size_t bytes = 0; - if (count < input_event_size()) + if (count != 0 && count < input_event_size()) return -EINVAL; - if (input_event_from_user(buffer, &ev)) - return -EFAULT; + while (bytes + input_event_size() <= count) { + /* + * Note that even if some events were fetched successfully + * we are still going to return EFAULT instead of partial + * count to let userspace know that it got it's buffers + * all wrong. + */ + if (input_event_from_user(buffer + bytes, &ev)) + return -EFAULT; - input_event(udev->dev, ev.type, ev.code, ev.value); + input_event(udev->dev, ev.type, ev.code, ev.value); + bytes += input_event_size(); + } - return input_event_size(); + return bytes; } static ssize_t uinput_write(struct file *file, const char __user *buffer, @@ -460,7 +470,7 @@ static ssize_t uinput_write(struct file *file, const char __user *buffer, return retval; retval = udev->state == UIST_CREATED ? - uinput_inject_event(udev, buffer, count) : + uinput_inject_events(udev, buffer, count) : uinput_setup_device(udev, buffer, count); mutex_unlock(&udev->mutex); diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 56536f4b9572..b6505454bcc4 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -46,7 +46,6 @@ MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>"); MODULE_DESCRIPTION("Wistron laptop button driver"); MODULE_LICENSE("GPL v2"); -MODULE_VERSION("0.3"); static bool force; /* = 0; */ module_param(force, bool, 0); @@ -563,7 +562,7 @@ static struct key_entry keymap_wistron_md96500[] __initdata = { { KE_KEY, 0x36, {KEY_WWW} }, { KE_WIFI, 0x30 }, { KE_BLUETOOTH, 0x44 }, - { KE_END, FE_UNTESTED } + { KE_END, 0 } }; static struct key_entry keymap_wistron_generic[] __initdata = { @@ -635,7 +634,7 @@ static struct key_entry keymap_prestigio[] __initdata = { * a list of buttons and their key codes (reported when loading this module * with force=1) and the output of dmidecode to $MODULE_AUTHOR. */ -static const struct dmi_system_id __initconst dmi_ids[] = { +static const struct dmi_system_id dmi_ids[] __initconst = { { /* Fujitsu-Siemens Amilo Pro V2000 */ .callback = dmi_matched, @@ -972,6 +971,7 @@ static const struct dmi_system_id __initconst dmi_ids[] = { }, { NULL, } }; +MODULE_DEVICE_TABLE(dmi, dmi_ids); /* Copy the good keymap, as the original ones are free'd */ static int __init copy_keymap(void) |