Skip to content

Commit b8c82b6

Browse files
committed
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
2 parents ed0a0ec + 7ad222b commit b8c82b6

File tree

11 files changed

+75
-101
lines changed

11 files changed

+75
-101
lines changed

drivers/input/keyboard/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ config KEYBOARD_MPR121
420420

421421
config KEYBOARD_SNVS_PWRKEY
422422
tristate "IMX SNVS Power Key Driver"
423-
depends on SOC_IMX6SX
423+
depends on SOC_IMX6SX || SOC_IMX7D
424424
depends on OF
425425
help
426426
This is the snvs powerkey driver for the Freescale i.MX application

drivers/input/keyboard/cap11xx.c

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,7 @@
7575
struct cap11xx_led {
7676
struct cap11xx_priv *priv;
7777
struct led_classdev cdev;
78-
struct work_struct work;
7978
u32 reg;
80-
enum led_brightness new_brightness;
8179
};
8280
#endif
8381

@@ -233,30 +231,21 @@ static void cap11xx_input_close(struct input_dev *idev)
233231
}
234232

235233
#ifdef CONFIG_LEDS_CLASS
236-
static void cap11xx_led_work(struct work_struct *work)
234+
static int cap11xx_led_set(struct led_classdev *cdev,
235+
enum led_brightness value)
237236
{
238-
struct cap11xx_led *led = container_of(work, struct cap11xx_led, work);
237+
struct cap11xx_led *led = container_of(cdev, struct cap11xx_led, cdev);
239238
struct cap11xx_priv *priv = led->priv;
240-
int value = led->new_brightness;
241239

242240
/*
243-
* All LEDs share the same duty cycle as this is a HW limitation.
244-
* Brightness levels per LED are either 0 (OFF) and 1 (ON).
241+
* All LEDs share the same duty cycle as this is a HW
242+
* limitation. Brightness levels per LED are either
243+
* 0 (OFF) and 1 (ON).
245244
*/
246-
regmap_update_bits(priv->regmap, CAP11XX_REG_LED_OUTPUT_CONTROL,
247-
BIT(led->reg), value ? BIT(led->reg) : 0);
248-
}
249-
250-
static void cap11xx_led_set(struct led_classdev *cdev,
251-
enum led_brightness value)
252-
{
253-
struct cap11xx_led *led = container_of(cdev, struct cap11xx_led, cdev);
254-
255-
if (led->new_brightness == value)
256-
return;
257-
258-
led->new_brightness = value;
259-
schedule_work(&led->work);
245+
return regmap_update_bits(priv->regmap,
246+
CAP11XX_REG_LED_OUTPUT_CONTROL,
247+
BIT(led->reg),
248+
value ? BIT(led->reg) : 0);
260249
}
261250

262251
static int cap11xx_init_leds(struct device *dev,
@@ -299,7 +288,7 @@ static int cap11xx_init_leds(struct device *dev,
299288
led->cdev.default_trigger =
300289
of_get_property(child, "linux,default-trigger", NULL);
301290
led->cdev.flags = 0;
302-
led->cdev.brightness_set = cap11xx_led_set;
291+
led->cdev.brightness_set_blocking = cap11xx_led_set;
303292
led->cdev.max_brightness = 1;
304293
led->cdev.brightness = LED_OFF;
305294

@@ -312,8 +301,6 @@ static int cap11xx_init_leds(struct device *dev,
312301
led->reg = reg;
313302
led->priv = priv;
314303

315-
INIT_WORK(&led->work, cap11xx_led_work);
316-
317304
error = devm_led_classdev_register(dev, &led->cdev);
318305
if (error) {
319306
of_node_put(child);

drivers/input/keyboard/matrix_keypad.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ static void matrix_keypad_stop(struct input_dev *dev)
222222
keypad->stopped = true;
223223
spin_unlock_irq(&keypad->lock);
224224

225-
flush_work(&keypad->work.work);
225+
flush_delayed_work(&keypad->work);
226226
/*
227227
* matrix_keypad_scan() will leave IRQs enabled;
228228
* we should disable them now.

drivers/input/keyboard/qt2160.c

Lines changed: 27 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,9 @@ static unsigned char qt2160_key2code[] = {
5858
struct qt2160_led {
5959
struct qt2160_data *qt2160;
6060
struct led_classdev cdev;
61-
struct work_struct work;
6261
char name[32];
6362
int id;
64-
enum led_brightness new_brightness;
63+
enum led_brightness brightness;
6564
};
6665
#endif
6766

@@ -74,7 +73,6 @@ struct qt2160_data {
7473
u16 key_matrix;
7574
#ifdef CONFIG_LEDS_CLASS
7675
struct qt2160_led leds[QT2160_NUM_LEDS_X];
77-
struct mutex led_lock;
7876
#endif
7977
};
8078

@@ -83,46 +81,39 @@ static int qt2160_write(struct i2c_client *client, u8 reg, u8 data);
8381

8482
#ifdef CONFIG_LEDS_CLASS
8583

86-
static void qt2160_led_work(struct work_struct *work)
84+
static int qt2160_led_set(struct led_classdev *cdev,
85+
enum led_brightness value)
8786
{
88-
struct qt2160_led *led = container_of(work, struct qt2160_led, work);
87+
struct qt2160_led *led = container_of(cdev, struct qt2160_led, cdev);
8988
struct qt2160_data *qt2160 = led->qt2160;
9089
struct i2c_client *client = qt2160->client;
91-
int value = led->new_brightness;
9290
u32 drive, pwmen;
9391

94-
mutex_lock(&qt2160->led_lock);
95-
96-
drive = qt2160_read(client, QT2160_CMD_DRIVE_X);
97-
pwmen = qt2160_read(client, QT2160_CMD_PWMEN_X);
98-
if (value != LED_OFF) {
99-
drive |= (1 << led->id);
100-
pwmen |= (1 << led->id);
101-
102-
} else {
103-
drive &= ~(1 << led->id);
104-
pwmen &= ~(1 << led->id);
105-
}
106-
qt2160_write(client, QT2160_CMD_DRIVE_X, drive);
107-
qt2160_write(client, QT2160_CMD_PWMEN_X, pwmen);
92+
if (value != led->brightness) {
93+
drive = qt2160_read(client, QT2160_CMD_DRIVE_X);
94+
pwmen = qt2160_read(client, QT2160_CMD_PWMEN_X);
95+
if (value != LED_OFF) {
96+
drive |= BIT(led->id);
97+
pwmen |= BIT(led->id);
10898

109-
/*
110-
* Changing this register will change the brightness
111-
* of every LED in the qt2160. It's a HW limitation.
112-
*/
113-
if (value != LED_OFF)
114-
qt2160_write(client, QT2160_CMD_PWM_DUTY, value);
99+
} else {
100+
drive &= ~BIT(led->id);
101+
pwmen &= ~BIT(led->id);
102+
}
103+
qt2160_write(client, QT2160_CMD_DRIVE_X, drive);
104+
qt2160_write(client, QT2160_CMD_PWMEN_X, pwmen);
115105

116-
mutex_unlock(&qt2160->led_lock);
117-
}
106+
/*
107+
* Changing this register will change the brightness
108+
* of every LED in the qt2160. It's a HW limitation.
109+
*/
110+
if (value != LED_OFF)
111+
qt2160_write(client, QT2160_CMD_PWM_DUTY, value);
118112

119-
static void qt2160_led_set(struct led_classdev *cdev,
120-
enum led_brightness value)
121-
{
122-
struct qt2160_led *led = container_of(cdev, struct qt2160_led, cdev);
113+
led->brightness = value;
114+
}
123115

124-
led->new_brightness = value;
125-
schedule_work(&led->work);
116+
return 0;
126117
}
127118

128119
#endif /* CONFIG_LEDS_CLASS */
@@ -293,20 +284,16 @@ static int qt2160_register_leds(struct qt2160_data *qt2160)
293284
int ret;
294285
int i;
295286

296-
mutex_init(&qt2160->led_lock);
297-
298287
for (i = 0; i < QT2160_NUM_LEDS_X; i++) {
299288
struct qt2160_led *led = &qt2160->leds[i];
300289

301290
snprintf(led->name, sizeof(led->name), "qt2160:x%d", i);
302291
led->cdev.name = led->name;
303-
led->cdev.brightness_set = qt2160_led_set;
292+
led->cdev.brightness_set_blocking = qt2160_led_set;
304293
led->cdev.brightness = LED_OFF;
305294
led->id = i;
306295
led->qt2160 = qt2160;
307296

308-
INIT_WORK(&led->work, qt2160_led_work);
309-
310297
ret = led_classdev_register(&client->dev, &led->cdev);
311298
if (ret < 0)
312299
return ret;
@@ -324,10 +311,8 @@ static void qt2160_unregister_leds(struct qt2160_data *qt2160)
324311
{
325312
int i;
326313

327-
for (i = 0; i < QT2160_NUM_LEDS_X; i++) {
314+
for (i = 0; i < QT2160_NUM_LEDS_X; i++)
328315
led_classdev_unregister(&qt2160->leds[i].cdev);
329-
cancel_work_sync(&qt2160->leds[i].work);
330-
}
331316
}
332317

333318
#else

drivers/input/keyboard/st-keyscan.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ static int keyscan_probe(struct platform_device *pdev)
153153

154154
input_dev->id.bustype = BUS_HOST;
155155

156+
keypad_data->input_dev = input_dev;
157+
156158
error = keypad_matrix_key_parse_dt(keypad_data);
157159
if (error)
158160
return error;
@@ -168,8 +170,6 @@ static int keyscan_probe(struct platform_device *pdev)
168170

169171
input_set_drvdata(input_dev, keypad_data);
170172

171-
keypad_data->input_dev = input_dev;
172-
173173
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
174174
keypad_data->base = devm_ioremap_resource(&pdev->dev, res);
175175
if (IS_ERR(keypad_data->base))

drivers/input/misc/apanel.c

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include <linux/io.h>
2323
#include <linux/input-polldev.h>
2424
#include <linux/i2c.h>
25-
#include <linux/workqueue.h>
2625
#include <linux/leds.h>
2726

2827
#define APANEL_NAME "Fujitsu Application Panel"
@@ -59,8 +58,6 @@ struct apanel {
5958
struct i2c_client *client;
6059
unsigned short keymap[MAX_PANEL_KEYS];
6160
u16 nkeys;
62-
u16 led_bits;
63-
struct work_struct led_work;
6461
struct led_classdev mail_led;
6562
};
6663

@@ -109,25 +106,13 @@ static void apanel_poll(struct input_polled_dev *ipdev)
109106
report_key(idev, ap->keymap[i]);
110107
}
111108

112-
/* Track state changes of LED */
113-
static void led_update(struct work_struct *work)
114-
{
115-
struct apanel *ap = container_of(work, struct apanel, led_work);
116-
117-
i2c_smbus_write_word_data(ap->client, 0x10, ap->led_bits);
118-
}
119-
120-
static void mail_led_set(struct led_classdev *led,
109+
static int mail_led_set(struct led_classdev *led,
121110
enum led_brightness value)
122111
{
123112
struct apanel *ap = container_of(led, struct apanel, mail_led);
113+
u16 led_bits = value != LED_OFF ? 0x8000 : 0x0000;
124114

125-
if (value != LED_OFF)
126-
ap->led_bits |= 0x8000;
127-
else
128-
ap->led_bits &= ~0x8000;
129-
130-
schedule_work(&ap->led_work);
115+
return i2c_smbus_write_word_data(ap->client, 0x10, led_bits);
131116
}
132117

133118
static int apanel_remove(struct i2c_client *client)
@@ -179,7 +164,7 @@ static struct apanel apanel = {
179164
},
180165
.mail_led = {
181166
.name = "mail:blue",
182-
.brightness_set = mail_led_set,
167+
.brightness_set_blocking = mail_led_set,
183168
},
184169
};
185170

@@ -235,7 +220,6 @@ static int apanel_probe(struct i2c_client *client,
235220
if (err)
236221
goto out3;
237222

238-
INIT_WORK(&ap->led_work, led_update);
239223
if (device_chip[APANEL_DEV_LED] != CHIP_NONE) {
240224
err = led_classdev_register(&client->dev, &ap->mail_led);
241225
if (err)

drivers/input/misc/bma150.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -481,13 +481,14 @@ static int bma150_register_input_device(struct bma150_data *bma150)
481481
idev->close = bma150_irq_close;
482482
input_set_drvdata(idev, bma150);
483483

484+
bma150->input = idev;
485+
484486
error = input_register_device(idev);
485487
if (error) {
486488
input_free_device(idev);
487489
return error;
488490
}
489491

490-
bma150->input = idev;
491492
return 0;
492493
}
493494

@@ -510,15 +511,15 @@ static int bma150_register_polled_device(struct bma150_data *bma150)
510511

511512
bma150_init_input_device(bma150, ipoll_dev->input);
512513

514+
bma150->input_polled = ipoll_dev;
515+
bma150->input = ipoll_dev->input;
516+
513517
error = input_register_polled_device(ipoll_dev);
514518
if (error) {
515519
input_free_polled_device(ipoll_dev);
516520
return error;
517521
}
518522

519-
bma150->input_polled = ipoll_dev;
520-
bma150->input = ipoll_dev->input;
521-
522523
return 0;
523524
}
524525

drivers/input/misc/pwm-vibra.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ struct pwm_vibrator {
3434
struct work_struct play_work;
3535
u16 level;
3636
u32 direction_duty_cycle;
37+
bool vcc_on;
3738
};
3839

3940
static int pwm_vibrator_start(struct pwm_vibrator *vibrator)
@@ -42,10 +43,13 @@ static int pwm_vibrator_start(struct pwm_vibrator *vibrator)
4243
struct pwm_state state;
4344
int err;
4445

45-
err = regulator_enable(vibrator->vcc);
46-
if (err) {
47-
dev_err(pdev, "failed to enable regulator: %d", err);
48-
return err;
46+
if (!vibrator->vcc_on) {
47+
err = regulator_enable(vibrator->vcc);
48+
if (err) {
49+
dev_err(pdev, "failed to enable regulator: %d", err);
50+
return err;
51+
}
52+
vibrator->vcc_on = true;
4953
}
5054

5155
pwm_get_state(vibrator->pwm, &state);
@@ -76,11 +80,14 @@ static int pwm_vibrator_start(struct pwm_vibrator *vibrator)
7680

7781
static void pwm_vibrator_stop(struct pwm_vibrator *vibrator)
7882
{
79-
regulator_disable(vibrator->vcc);
80-
8183
if (vibrator->pwm_dir)
8284
pwm_disable(vibrator->pwm_dir);
8385
pwm_disable(vibrator->pwm);
86+
87+
if (vibrator->vcc_on) {
88+
regulator_disable(vibrator->vcc);
89+
vibrator->vcc_on = false;
90+
}
8491
}
8592

8693
static void pwm_vibrator_play_work(struct work_struct *work)

drivers/input/mouse/elan_i2c_core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1336,7 +1336,6 @@ MODULE_DEVICE_TABLE(i2c, elan_id);
13361336
static const struct acpi_device_id elan_acpi_id[] = {
13371337
{ "ELAN0000", 0 },
13381338
{ "ELAN0100", 0 },
1339-
{ "ELAN0501", 0 },
13401339
{ "ELAN0600", 0 },
13411340
{ "ELAN0602", 0 },
13421341
{ "ELAN0605", 0 },
@@ -1346,6 +1345,7 @@ static const struct acpi_device_id elan_acpi_id[] = {
13461345
{ "ELAN060C", 0 },
13471346
{ "ELAN0611", 0 },
13481347
{ "ELAN0612", 0 },
1348+
{ "ELAN0617", 0 },
13491349
{ "ELAN0618", 0 },
13501350
{ "ELAN061C", 0 },
13511351
{ "ELAN061D", 0 },

0 commit comments

Comments
 (0)