Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull input fixes from Dmitry Torokhov:

- tweaks to Elan drivers (both PS/2 and I2C) to support new devices.
Also revert of one of IDs as that device should really be driven by
i2c-hid + hid-multitouch

- a few drivers have been switched to set_brightness_blocking() call
because they either were sleeping the their set_brightness()
implementation or used workqueue but were not canceling it on unbind.

- ps2-gpio and matrix_keypad needed to [properly] flush their works to
avoid potential use-after-free on unbind.

- other miscellaneous fixes.

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
Input: elan_i2c - add ACPI ID for touchpad in Lenovo V330-15ISK
Input: st-keyscan - fix potential zalloc NULL dereference
Input: apanel - switch to using brightness_set_blocking()
Revert "Input: elan_i2c - add ACPI ID for touchpad in ASUS Aspire F5-573G"
Input: qt2160 - switch to using brightness_set_blocking()
Input: matrix_keypad - use flush_delayed_work()
Input: ps2-gpio - flush TX work when closing port
Input: cap11xx - switch to using set_brightness_blocking()
Input: elantech - enable 3rd button support on Fujitsu CELSIUS H780
Input: bma150 - register input device after setting private data
Input: pwm-vibra - stop regulator after disabling pwm, not before
Input: pwm-vibra - prevent unbalanced regulator
Input: snvs_pwrkey - allow selecting driver for i.MX 7D

+83 -109
+1 -1
drivers/input/keyboard/Kconfig
··· 420 420 421 421 config KEYBOARD_SNVS_PWRKEY 422 422 tristate "IMX SNVS Power Key Driver" 423 - depends on SOC_IMX6SX 423 + depends on SOC_IMX6SX || SOC_IMX7D 424 424 depends on OF 425 425 help 426 426 This is the snvs powerkey driver for the Freescale i.MX application
+13 -26
drivers/input/keyboard/cap11xx.c
··· 75 75 struct cap11xx_led { 76 76 struct cap11xx_priv *priv; 77 77 struct led_classdev cdev; 78 - struct work_struct work; 79 78 u32 reg; 80 - enum led_brightness new_brightness; 81 79 }; 82 80 #endif 83 81 ··· 231 233 } 232 234 233 235 #ifdef CONFIG_LEDS_CLASS 234 - static void cap11xx_led_work(struct work_struct *work) 235 - { 236 - struct cap11xx_led *led = container_of(work, struct cap11xx_led, work); 237 - struct cap11xx_priv *priv = led->priv; 238 - int value = led->new_brightness; 239 - 240 - /* 241 - * All LEDs share the same duty cycle as this is a HW limitation. 242 - * Brightness levels per LED are either 0 (OFF) and 1 (ON). 243 - */ 244 - regmap_update_bits(priv->regmap, CAP11XX_REG_LED_OUTPUT_CONTROL, 245 - BIT(led->reg), value ? BIT(led->reg) : 0); 246 - } 247 - 248 - static void cap11xx_led_set(struct led_classdev *cdev, 249 - enum led_brightness value) 236 + static int cap11xx_led_set(struct led_classdev *cdev, 237 + enum led_brightness value) 250 238 { 251 239 struct cap11xx_led *led = container_of(cdev, struct cap11xx_led, cdev); 240 + struct cap11xx_priv *priv = led->priv; 252 241 253 - if (led->new_brightness == value) 254 - return; 255 - 256 - led->new_brightness = value; 257 - schedule_work(&led->work); 242 + /* 243 + * All LEDs share the same duty cycle as this is a HW 244 + * limitation. Brightness levels per LED are either 245 + * 0 (OFF) and 1 (ON). 246 + */ 247 + return regmap_update_bits(priv->regmap, 248 + CAP11XX_REG_LED_OUTPUT_CONTROL, 249 + BIT(led->reg), 250 + value ? BIT(led->reg) : 0); 258 251 } 259 252 260 253 static int cap11xx_init_leds(struct device *dev, ··· 288 299 led->cdev.default_trigger = 289 300 of_get_property(child, "linux,default-trigger", NULL); 290 301 led->cdev.flags = 0; 291 - led->cdev.brightness_set = cap11xx_led_set; 302 + led->cdev.brightness_set_blocking = cap11xx_led_set; 292 303 led->cdev.max_brightness = 1; 293 304 led->cdev.brightness = LED_OFF; 294 305 ··· 300 311 301 312 led->reg = reg; 302 313 led->priv = priv; 303 - 304 - INIT_WORK(&led->work, cap11xx_led_work); 305 314 306 315 error = devm_led_classdev_register(dev, &led->cdev); 307 316 if (error) {
+1 -1
drivers/input/keyboard/matrix_keypad.c
··· 222 222 keypad->stopped = true; 223 223 spin_unlock_irq(&keypad->lock); 224 224 225 - flush_work(&keypad->work.work); 225 + flush_delayed_work(&keypad->work); 226 226 /* 227 227 * matrix_keypad_scan() will leave IRQs enabled; 228 228 * we should disable them now.
+33 -48
drivers/input/keyboard/qt2160.c
··· 58 58 struct qt2160_led { 59 59 struct qt2160_data *qt2160; 60 60 struct led_classdev cdev; 61 - struct work_struct work; 62 61 char name[32]; 63 62 int id; 64 - enum led_brightness new_brightness; 63 + enum led_brightness brightness; 65 64 }; 66 65 #endif 67 66 ··· 73 74 u16 key_matrix; 74 75 #ifdef CONFIG_LEDS_CLASS 75 76 struct qt2160_led leds[QT2160_NUM_LEDS_X]; 76 - struct mutex led_lock; 77 77 #endif 78 78 }; 79 79 ··· 81 83 82 84 #ifdef CONFIG_LEDS_CLASS 83 85 84 - static void qt2160_led_work(struct work_struct *work) 85 - { 86 - struct qt2160_led *led = container_of(work, struct qt2160_led, work); 87 - struct qt2160_data *qt2160 = led->qt2160; 88 - struct i2c_client *client = qt2160->client; 89 - int value = led->new_brightness; 90 - u32 drive, pwmen; 91 - 92 - mutex_lock(&qt2160->led_lock); 93 - 94 - drive = qt2160_read(client, QT2160_CMD_DRIVE_X); 95 - pwmen = qt2160_read(client, QT2160_CMD_PWMEN_X); 96 - if (value != LED_OFF) { 97 - drive |= (1 << led->id); 98 - pwmen |= (1 << led->id); 99 - 100 - } else { 101 - drive &= ~(1 << led->id); 102 - pwmen &= ~(1 << led->id); 103 - } 104 - qt2160_write(client, QT2160_CMD_DRIVE_X, drive); 105 - qt2160_write(client, QT2160_CMD_PWMEN_X, pwmen); 106 - 107 - /* 108 - * Changing this register will change the brightness 109 - * of every LED in the qt2160. It's a HW limitation. 110 - */ 111 - if (value != LED_OFF) 112 - qt2160_write(client, QT2160_CMD_PWM_DUTY, value); 113 - 114 - mutex_unlock(&qt2160->led_lock); 115 - } 116 - 117 - static void qt2160_led_set(struct led_classdev *cdev, 118 - enum led_brightness value) 86 + static int qt2160_led_set(struct led_classdev *cdev, 87 + enum led_brightness value) 119 88 { 120 89 struct qt2160_led *led = container_of(cdev, struct qt2160_led, cdev); 90 + struct qt2160_data *qt2160 = led->qt2160; 91 + struct i2c_client *client = qt2160->client; 92 + u32 drive, pwmen; 121 93 122 - led->new_brightness = value; 123 - schedule_work(&led->work); 94 + if (value != led->brightness) { 95 + drive = qt2160_read(client, QT2160_CMD_DRIVE_X); 96 + pwmen = qt2160_read(client, QT2160_CMD_PWMEN_X); 97 + if (value != LED_OFF) { 98 + drive |= BIT(led->id); 99 + pwmen |= BIT(led->id); 100 + 101 + } else { 102 + drive &= ~BIT(led->id); 103 + pwmen &= ~BIT(led->id); 104 + } 105 + qt2160_write(client, QT2160_CMD_DRIVE_X, drive); 106 + qt2160_write(client, QT2160_CMD_PWMEN_X, pwmen); 107 + 108 + /* 109 + * Changing this register will change the brightness 110 + * of every LED in the qt2160. It's a HW limitation. 111 + */ 112 + if (value != LED_OFF) 113 + qt2160_write(client, QT2160_CMD_PWM_DUTY, value); 114 + 115 + led->brightness = value; 116 + } 117 + 118 + return 0; 124 119 } 125 120 126 121 #endif /* CONFIG_LEDS_CLASS */ ··· 284 293 int ret; 285 294 int i; 286 295 287 - mutex_init(&qt2160->led_lock); 288 - 289 296 for (i = 0; i < QT2160_NUM_LEDS_X; i++) { 290 297 struct qt2160_led *led = &qt2160->leds[i]; 291 298 292 299 snprintf(led->name, sizeof(led->name), "qt2160:x%d", i); 293 300 led->cdev.name = led->name; 294 - led->cdev.brightness_set = qt2160_led_set; 301 + led->cdev.brightness_set_blocking = qt2160_led_set; 295 302 led->cdev.brightness = LED_OFF; 296 303 led->id = i; 297 304 led->qt2160 = qt2160; 298 - 299 - INIT_WORK(&led->work, qt2160_led_work); 300 305 301 306 ret = led_classdev_register(&client->dev, &led->cdev); 302 307 if (ret < 0) ··· 311 324 { 312 325 int i; 313 326 314 - for (i = 0; i < QT2160_NUM_LEDS_X; i++) { 327 + for (i = 0; i < QT2160_NUM_LEDS_X; i++) 315 328 led_classdev_unregister(&qt2160->leds[i].cdev); 316 - cancel_work_sync(&qt2160->leds[i].work); 317 - } 318 329 } 319 330 320 331 #else
+2 -2
drivers/input/keyboard/st-keyscan.c
··· 153 153 154 154 input_dev->id.bustype = BUS_HOST; 155 155 156 + keypad_data->input_dev = input_dev; 157 + 156 158 error = keypad_matrix_key_parse_dt(keypad_data); 157 159 if (error) 158 160 return error; ··· 169 167 } 170 168 171 169 input_set_drvdata(input_dev, keypad_data); 172 - 173 - keypad_data->input_dev = input_dev; 174 170 175 171 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 176 172 keypad_data->base = devm_ioremap_resource(&pdev->dev, res);
+4 -20
drivers/input/misc/apanel.c
··· 22 22 #include <linux/io.h> 23 23 #include <linux/input-polldev.h> 24 24 #include <linux/i2c.h> 25 - #include <linux/workqueue.h> 26 25 #include <linux/leds.h> 27 26 28 27 #define APANEL_NAME "Fujitsu Application Panel" ··· 58 59 struct i2c_client *client; 59 60 unsigned short keymap[MAX_PANEL_KEYS]; 60 61 u16 nkeys; 61 - u16 led_bits; 62 - struct work_struct led_work; 63 62 struct led_classdev mail_led; 64 63 }; 65 64 ··· 106 109 report_key(idev, ap->keymap[i]); 107 110 } 108 111 109 - /* Track state changes of LED */ 110 - static void led_update(struct work_struct *work) 111 - { 112 - struct apanel *ap = container_of(work, struct apanel, led_work); 113 - 114 - i2c_smbus_write_word_data(ap->client, 0x10, ap->led_bits); 115 - } 116 - 117 - static void mail_led_set(struct led_classdev *led, 112 + static int mail_led_set(struct led_classdev *led, 118 113 enum led_brightness value) 119 114 { 120 115 struct apanel *ap = container_of(led, struct apanel, mail_led); 116 + u16 led_bits = value != LED_OFF ? 0x8000 : 0x0000; 121 117 122 - if (value != LED_OFF) 123 - ap->led_bits |= 0x8000; 124 - else 125 - ap->led_bits &= ~0x8000; 126 - 127 - schedule_work(&ap->led_work); 118 + return i2c_smbus_write_word_data(ap->client, 0x10, led_bits); 128 119 } 129 120 130 121 static int apanel_remove(struct i2c_client *client) ··· 164 179 }, 165 180 .mail_led = { 166 181 .name = "mail:blue", 167 - .brightness_set = mail_led_set, 182 + .brightness_set_blocking = mail_led_set, 168 183 }, 169 184 }; 170 185 ··· 220 235 if (err) 221 236 goto out3; 222 237 223 - INIT_WORK(&ap->led_work, led_update); 224 238 if (device_chip[APANEL_DEV_LED] != CHIP_NONE) { 225 239 err = led_classdev_register(&client->dev, &ap->mail_led); 226 240 if (err)
+5 -4
drivers/input/misc/bma150.c
··· 481 481 idev->close = bma150_irq_close; 482 482 input_set_drvdata(idev, bma150); 483 483 484 + bma150->input = idev; 485 + 484 486 error = input_register_device(idev); 485 487 if (error) { 486 488 input_free_device(idev); 487 489 return error; 488 490 } 489 491 490 - bma150->input = idev; 491 492 return 0; 492 493 } 493 494 ··· 511 510 512 511 bma150_init_input_device(bma150, ipoll_dev->input); 513 512 513 + bma150->input_polled = ipoll_dev; 514 + bma150->input = ipoll_dev->input; 515 + 514 516 error = input_register_polled_device(ipoll_dev); 515 517 if (error) { 516 518 input_free_polled_device(ipoll_dev); 517 519 return error; 518 520 } 519 - 520 - bma150->input_polled = ipoll_dev; 521 - bma150->input = ipoll_dev->input; 522 521 523 522 return 0; 524 523 }
+13 -6
drivers/input/misc/pwm-vibra.c
··· 34 34 struct work_struct play_work; 35 35 u16 level; 36 36 u32 direction_duty_cycle; 37 + bool vcc_on; 37 38 }; 38 39 39 40 static int pwm_vibrator_start(struct pwm_vibrator *vibrator) ··· 43 42 struct pwm_state state; 44 43 int err; 45 44 46 - err = regulator_enable(vibrator->vcc); 47 - if (err) { 48 - dev_err(pdev, "failed to enable regulator: %d", err); 49 - return err; 45 + if (!vibrator->vcc_on) { 46 + err = regulator_enable(vibrator->vcc); 47 + if (err) { 48 + dev_err(pdev, "failed to enable regulator: %d", err); 49 + return err; 50 + } 51 + vibrator->vcc_on = true; 50 52 } 51 53 52 54 pwm_get_state(vibrator->pwm, &state); ··· 80 76 81 77 static void pwm_vibrator_stop(struct pwm_vibrator *vibrator) 82 78 { 83 - regulator_disable(vibrator->vcc); 84 - 85 79 if (vibrator->pwm_dir) 86 80 pwm_disable(vibrator->pwm_dir); 87 81 pwm_disable(vibrator->pwm); 82 + 83 + if (vibrator->vcc_on) { 84 + regulator_disable(vibrator->vcc); 85 + vibrator->vcc_on = false; 86 + } 88 87 } 89 88 90 89 static void pwm_vibrator_play_work(struct work_struct *work)
+1 -1
drivers/input/mouse/elan_i2c_core.c
··· 1336 1336 static const struct acpi_device_id elan_acpi_id[] = { 1337 1337 { "ELAN0000", 0 }, 1338 1338 { "ELAN0100", 0 }, 1339 - { "ELAN0501", 0 }, 1340 1339 { "ELAN0600", 0 }, 1341 1340 { "ELAN0602", 0 }, 1342 1341 { "ELAN0605", 0 }, ··· 1345 1346 { "ELAN060C", 0 }, 1346 1347 { "ELAN0611", 0 }, 1347 1348 { "ELAN0612", 0 }, 1349 + { "ELAN0617", 0 }, 1348 1350 { "ELAN0618", 0 }, 1349 1351 { "ELAN061C", 0 }, 1350 1352 { "ELAN061D", 0 },
+9
drivers/input/mouse/elantech.c
··· 1119 1119 * Asus UX31 0x361f00 20, 15, 0e clickpad 1120 1120 * Asus UX32VD 0x361f02 00, 15, 0e clickpad 1121 1121 * Avatar AVIU-145A2 0x361f00 ? clickpad 1122 + * Fujitsu CELSIUS H760 0x570f02 40, 14, 0c 3 hw buttons (**) 1123 + * Fujitsu CELSIUS H780 0x5d0f02 41, 16, 0d 3 hw buttons (**) 1122 1124 * Fujitsu LIFEBOOK E544 0x470f00 d0, 12, 09 2 hw buttons 1123 1125 * Fujitsu LIFEBOOK E546 0x470f00 50, 12, 09 2 hw buttons 1124 1126 * Fujitsu LIFEBOOK E547 0x470f00 50, 12, 09 2 hw buttons ··· 1171 1169 .matches = { 1172 1170 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 1173 1171 DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H760"), 1172 + }, 1173 + }, 1174 + { 1175 + /* Fujitsu H780 also has a middle button */ 1176 + .matches = { 1177 + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 1178 + DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H780"), 1174 1179 }, 1175 1180 }, 1176 1181 #endif
+1
drivers/input/serio/ps2-gpio.c
··· 76 76 { 77 77 struct ps2_gpio_data *drvdata = serio->port_data; 78 78 79 + flush_delayed_work(&drvdata->tx_work); 79 80 disable_irq(drvdata->irq); 80 81 } 81 82