From 116721a560d66dee488f291a1d218b5fc6050678 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Mon, 1 May 2023 16:59:37 -0700 Subject: Input: drv260x - fix typo in register value define ANANLOG should be ANALOG. Fix the typo. Fixes: 7132fe4f5687 ("Input: drv260x - add TI drv260x haptics driver") Signed-off-by: Luca Weiss Link: https://lore.kernel.org/r/20230430-drv260x-improvements-v1-1-1fb28b4cc698@z3ntu.xyz Signed-off-by: Dmitry Torokhov --- drivers/input/misc/drv260x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c index 8a9ebfc04a2d..e95c4e775b5d 100644 --- a/drivers/input/misc/drv260x.c +++ b/drivers/input/misc/drv260x.c @@ -149,7 +149,7 @@ /* Control 3 Register */ #define DRV260X_LRA_OPEN_LOOP (1 << 0) -#define DRV260X_ANANLOG_IN (1 << 1) +#define DRV260X_ANALOG_IN (1 << 1) #define DRV260X_LRA_DRV_MODE (1 << 2) #define DRV260X_RTP_UNSIGNED_DATA (1 << 3) #define DRV260X_SUPPLY_COMP_DIS (1 << 4) @@ -322,7 +322,7 @@ static const struct reg_sequence drv260x_lra_init_regs[] = { DRV260X_BEMF_GAIN_3 }, { DRV260X_CTRL1, DRV260X_STARTUP_BOOST }, { DRV260X_CTRL2, DRV260X_SAMP_TIME_250 }, - { DRV260X_CTRL3, DRV260X_NG_THRESH_2 | DRV260X_ANANLOG_IN }, + { DRV260X_CTRL3, DRV260X_NG_THRESH_2 | DRV260X_ANALOG_IN }, { DRV260X_CTRL4, DRV260X_AUTOCAL_TIME_500MS }, }; -- cgit v1.2.3 From efef661dfa6bf8cbafe4cd6a97433fcef0118967 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Mon, 1 May 2023 17:01:45 -0700 Subject: Input: drv260x - sleep between polling GO bit When doing the initial startup there's no need to poll without any delay and spam the I2C bus. Let's sleep 15ms between each attempt, which is the same time as used in the vendor driver. Fixes: 7132fe4f5687 ("Input: drv260x - add TI drv260x haptics driver") Signed-off-by: Luca Weiss Link: https://lore.kernel.org/r/20230430-drv260x-improvements-v1-2-1fb28b4cc698@z3ntu.xyz Signed-off-by: Dmitry Torokhov --- drivers/input/misc/drv260x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/input') diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c index e95c4e775b5d..884d43eb4b61 100644 --- a/drivers/input/misc/drv260x.c +++ b/drivers/input/misc/drv260x.c @@ -435,6 +435,7 @@ static int drv260x_init(struct drv260x_data *haptics) } do { + usleep_range(15000, 15500); error = regmap_read(haptics->regmap, DRV260X_GO, &cal_buf); if (error) { dev_err(&haptics->client->dev, -- cgit v1.2.3 From 980626ec1ca82a10dc04026a79dcbade23cc3438 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Mon, 1 May 2023 17:02:10 -0700 Subject: Input: drv260x - remove unused .reg_defaults Since the driver has disabled regmap caching with REGCACHE_NONE, it's warning us that we provide defaults that are not used. Remove them. [ 0.561159] drv260x-haptics 0-005a: No cache used with register defaults set! Fixes: 7132fe4f5687 ("Input: drv260x - add TI drv260x haptics driver") Signed-off-by: Luca Weiss Link: https://lore.kernel.org/r/20230430-drv260x-improvements-v1-3-1fb28b4cc698@z3ntu.xyz Signed-off-by: Dmitry Torokhov --- drivers/input/misc/drv260x.c | 40 ---------------------------------------- 1 file changed, 40 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c index 884d43eb4b61..a7e3120bdc13 100644 --- a/drivers/input/misc/drv260x.c +++ b/drivers/input/misc/drv260x.c @@ -193,44 +193,6 @@ struct drv260x_data { int overdrive_voltage; }; -static const struct reg_default drv260x_reg_defs[] = { - { DRV260X_STATUS, 0xe0 }, - { DRV260X_MODE, 0x40 }, - { DRV260X_RT_PB_IN, 0x00 }, - { DRV260X_LIB_SEL, 0x00 }, - { DRV260X_WV_SEQ_1, 0x01 }, - { DRV260X_WV_SEQ_2, 0x00 }, - { DRV260X_WV_SEQ_3, 0x00 }, - { DRV260X_WV_SEQ_4, 0x00 }, - { DRV260X_WV_SEQ_5, 0x00 }, - { DRV260X_WV_SEQ_6, 0x00 }, - { DRV260X_WV_SEQ_7, 0x00 }, - { DRV260X_WV_SEQ_8, 0x00 }, - { DRV260X_GO, 0x00 }, - { DRV260X_OVERDRIVE_OFF, 0x00 }, - { DRV260X_SUSTAIN_P_OFF, 0x00 }, - { DRV260X_SUSTAIN_N_OFF, 0x00 }, - { DRV260X_BRAKE_OFF, 0x00 }, - { DRV260X_A_TO_V_CTRL, 0x05 }, - { DRV260X_A_TO_V_MIN_INPUT, 0x19 }, - { DRV260X_A_TO_V_MAX_INPUT, 0xff }, - { DRV260X_A_TO_V_MIN_OUT, 0x19 }, - { DRV260X_A_TO_V_MAX_OUT, 0xff }, - { DRV260X_RATED_VOLT, 0x3e }, - { DRV260X_OD_CLAMP_VOLT, 0x8c }, - { DRV260X_CAL_COMP, 0x0c }, - { DRV260X_CAL_BACK_EMF, 0x6c }, - { DRV260X_FEEDBACK_CTRL, 0x36 }, - { DRV260X_CTRL1, 0x93 }, - { DRV260X_CTRL2, 0xfa }, - { DRV260X_CTRL3, 0xa0 }, - { DRV260X_CTRL4, 0x20 }, - { DRV260X_CTRL5, 0x80 }, - { DRV260X_LRA_LOOP_PERIOD, 0x33 }, - { DRV260X_VBAT_MON, 0x00 }, - { DRV260X_LRA_RES_PERIOD, 0x00 }, -}; - #define DRV260X_DEF_RATED_VOLT 0x90 #define DRV260X_DEF_OD_CLAMP_VOLT 0x90 @@ -453,8 +415,6 @@ static const struct regmap_config drv260x_regmap_config = { .val_bits = 8, .max_register = DRV260X_MAX_REG, - .reg_defaults = drv260x_reg_defs, - .num_reg_defaults = ARRAY_SIZE(drv260x_reg_defs), .cache_type = REGCACHE_NONE, }; -- cgit v1.2.3 From d09dbc7a018c4d479d7ab0d3b4f6a3211b110923 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Mon, 1 May 2023 17:02:56 -0700 Subject: Input: drv260x - fix magnitude handling First of all, previously the 16-bit magnitude was written as-is to the device which actually discarded the upper 8 bits since the device has 8-bit registers only. This meant that a strong_magnitude of 0xFF00 would result in 0. To correct this shift the strong_magnitude / weak_magnitude input values so we discard the lower 8 bits and keep the upper bits instead. Secondly the RTP mode that is used by default interprets the values as signed (2s complement), so 0x81 = 0%, 0x00 = 50%, 0x7F = 100%. This doesn't match the FF_RUMBLE interface at all, so let's tell the device to interpret the data as unsigned instead which gets us 0x00 = 0% and 0xFF = 100%. As last change switch ERM to using "Closed-Loop Mode, Unidirectional" instead of "Open-Loop Mode" since it's recommended by the datasheet compared to open loop and better matches our use case of 0% - 100% vibration. Signed-off-by: Luca Weiss Link: https://lore.kernel.org/r/20230430-drv260x-improvements-v1-4-1fb28b4cc698@z3ntu.xyz Signed-off-by: Dmitry Torokhov --- drivers/input/misc/drv260x.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c index a7e3120bdc13..f5e96b36acda 100644 --- a/drivers/input/misc/drv260x.c +++ b/drivers/input/misc/drv260x.c @@ -186,7 +186,7 @@ struct drv260x_data { struct work_struct work; struct gpio_desc *enable_gpio; struct regulator *regulator; - u32 magnitude; + u8 magnitude; u32 mode; u32 library; int rated_voltage; @@ -237,10 +237,11 @@ static int drv260x_haptics_play(struct input_dev *input, void *data, haptics->mode = DRV260X_LRA_NO_CAL_MODE; + /* Scale u16 magnitude into u8 register value */ if (effect->u.rumble.strong_magnitude > 0) - haptics->magnitude = effect->u.rumble.strong_magnitude; + haptics->magnitude = effect->u.rumble.strong_magnitude >> 8; else if (effect->u.rumble.weak_magnitude > 0) - haptics->magnitude = effect->u.rumble.weak_magnitude; + haptics->magnitude = effect->u.rumble.weak_magnitude >> 8; else haptics->magnitude = 0; @@ -266,7 +267,7 @@ static void drv260x_close(struct input_dev *input) static const struct reg_sequence drv260x_lra_cal_regs[] = { { DRV260X_MODE, DRV260X_AUTO_CAL }, - { DRV260X_CTRL3, DRV260X_NG_THRESH_2 }, + { DRV260X_CTRL3, DRV260X_NG_THRESH_2 | DRV260X_RTP_UNSIGNED_DATA }, { DRV260X_FEEDBACK_CTRL, DRV260X_FB_REG_LRA_MODE | DRV260X_BRAKE_FACTOR_4X | DRV260X_LOOP_GAIN_HIGH }, }; @@ -284,7 +285,7 @@ static const struct reg_sequence drv260x_lra_init_regs[] = { DRV260X_BEMF_GAIN_3 }, { DRV260X_CTRL1, DRV260X_STARTUP_BOOST }, { DRV260X_CTRL2, DRV260X_SAMP_TIME_250 }, - { DRV260X_CTRL3, DRV260X_NG_THRESH_2 | DRV260X_ANALOG_IN }, + { DRV260X_CTRL3, DRV260X_NG_THRESH_2 | DRV260X_RTP_UNSIGNED_DATA | DRV260X_ANALOG_IN }, { DRV260X_CTRL4, DRV260X_AUTOCAL_TIME_500MS }, }; @@ -299,7 +300,7 @@ static const struct reg_sequence drv260x_erm_cal_regs[] = { { DRV260X_CTRL1, DRV260X_STARTUP_BOOST }, { DRV260X_CTRL2, DRV260X_SAMP_TIME_250 | DRV260X_BLANK_TIME_75 | DRV260X_IDISS_TIME_75 }, - { DRV260X_CTRL3, DRV260X_NG_THRESH_2 | DRV260X_ERM_OPEN_LOOP }, + { DRV260X_CTRL3, DRV260X_NG_THRESH_2 | DRV260X_RTP_UNSIGNED_DATA }, { DRV260X_CTRL4, DRV260X_AUTOCAL_TIME_500MS }, }; -- cgit v1.2.3 From 14d55bc3606b17765d39210c012e7782ee423d84 Mon Sep 17 00:00:00 2001 From: Maximilian Weigand Date: Mon, 1 May 2023 17:13:25 -0700 Subject: Input: cyttsp5 - remove unused code The removed lines are remnants of the vendor driver and are not used in the upstream driver. Signed-off-by: Maximilian Weigand Reviewed-by: Alistair Francis Link: https://lore.kernel.org/r/20230501113010.891786-3-mweigand@mweigand.net Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/cyttsp5.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/cyttsp5.c b/drivers/input/touchscreen/cyttsp5.c index 16caffa35dd9..308061e9a830 100644 --- a/drivers/input/touchscreen/cyttsp5.c +++ b/drivers/input/touchscreen/cyttsp5.c @@ -600,12 +600,7 @@ static int cyttsp5_get_hid_descriptor(struct cyttsp5 *ts, struct cyttsp5_hid_desc *desc) { struct device *dev = ts->dev; - __le16 hid_desc_register = cpu_to_le16(HID_DESC_REG); int rc; - u8 cmd[2]; - - /* Set HID descriptor register */ - memcpy(cmd, &hid_desc_register, sizeof(hid_desc_register)); rc = cyttsp5_write(ts, HID_DESC_REG, NULL, 0); if (rc) { -- cgit v1.2.3 From dbe836576f12743a7d2d170ad4ad4fd324c4d47a Mon Sep 17 00:00:00 2001 From: Duoming Zhou Date: Mon, 1 May 2023 17:37:02 -0700 Subject: Input: cyttsp4_core - change del_timer_sync() to timer_shutdown_sync() The watchdog_timer can schedule tx_timeout_task and watchdog_work can also arm watchdog_timer. The process is shown below: ----------- timer schedules work ------------ cyttsp4_watchdog_timer() //timer handler schedule_work(&cd->watchdog_work) ----------- work arms timer ------------ cyttsp4_watchdog_work() //workqueue callback function cyttsp4_start_wd_timer() mod_timer(&cd->watchdog_timer, ...) Although del_timer_sync() and cancel_work_sync() are called in cyttsp4_remove(), the timer and workqueue could still be rearmed. As a result, the possible use after free bugs could happen. The process is shown below: (cleanup routine) | (timer and workqueue routine) cyttsp4_remove() | cyttsp4_watchdog_timer() //timer cyttsp4_stop_wd_timer() | schedule_work() del_timer_sync() | | cyttsp4_watchdog_work() //worker | cyttsp4_start_wd_timer() | mod_timer() cancel_work_sync() | | cyttsp4_watchdog_timer() //timer | schedule_work() del_timer_sync() | kfree(cd) //FREE | | cyttsp4_watchdog_work() // reschedule! | cd-> //USE This patch changes del_timer_sync() to timer_shutdown_sync(), which could prevent rearming of the timer from the workqueue. Fixes: 17fb1563d69b ("Input: cyttsp4 - add core driver for Cypress TMA4XX touchscreen devices") Signed-off-by: Duoming Zhou Link: https://lore.kernel.org/r/20230421082919.8471-1-duoming@zju.edu.cn Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/cyttsp4_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/cyttsp4_core.c b/drivers/input/touchscreen/cyttsp4_core.c index 0cd6f626adec..7cb26929dc73 100644 --- a/drivers/input/touchscreen/cyttsp4_core.c +++ b/drivers/input/touchscreen/cyttsp4_core.c @@ -1263,9 +1263,8 @@ static void cyttsp4_stop_wd_timer(struct cyttsp4 *cd) * Ensure we wait until the watchdog timer * running on a different CPU finishes */ - del_timer_sync(&cd->watchdog_timer); + timer_shutdown_sync(&cd->watchdog_timer); cancel_work_sync(&cd->watchdog_work); - del_timer_sync(&cd->watchdog_timer); } static void cyttsp4_watchdog_timer(struct timer_list *t) -- cgit v1.2.3 From 9780432158de0a0da88c3b506d6bdf63da43bc75 Mon Sep 17 00:00:00 2001 From: André Apitzsch Date: Mon, 1 May 2023 20:16:52 -0700 Subject: Input: atmel_mxt_ts - support capacitive keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for touch keys found in some Atmel touch controller configurations. Reviewed-by: Claudiu Beznea Reviewed-by: Linus Walleij Signed-off-by: André Apitzsch Link: https://lore.kernel.org/r/20230407-atmel_keys-v2-2-92446a4343cb@apitzsch.eu Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/atmel_mxt_ts.c | 85 ++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 996bf434e1cb..edea1823fd36 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -55,6 +55,7 @@ #define MXT_TOUCH_KEYARRAY_T15 15 #define MXT_TOUCH_PROXIMITY_T23 23 #define MXT_TOUCH_PROXKEY_T52 52 +#define MXT_TOUCH_PTC_KEYS_T97 97 #define MXT_PROCI_GRIPFACE_T20 20 #define MXT_PROCG_NOISE_T22 22 #define MXT_PROCI_ONETOUCH_T24 24 @@ -326,9 +327,13 @@ struct mxt_data { u16 T71_address; u8 T9_reportid_min; u8 T9_reportid_max; + u8 T15_reportid_min; + u8 T15_reportid_max; u16 T18_address; u8 T19_reportid; u16 T44_address; + u8 T97_reportid_min; + u8 T97_reportid_max; u8 T100_reportid_min; u8 T100_reportid_max; @@ -344,6 +349,9 @@ struct mxt_data { u32 *t19_keymap; unsigned int t19_num_keys; + u32 *t15_keymap; + unsigned int t15_num_keys; + enum mxt_suspend_mode suspend_mode; u32 wakeup_method; @@ -375,6 +383,7 @@ static bool mxt_object_readable(unsigned int type) case MXT_TOUCH_KEYARRAY_T15: case MXT_TOUCH_PROXIMITY_T23: case MXT_TOUCH_PROXKEY_T52: + case MXT_TOUCH_PTC_KEYS_T97: case MXT_TOUCH_MULTITOUCHSCREEN_T100: case MXT_PROCI_GRIPFACE_T20: case MXT_PROCG_NOISE_T22: @@ -891,6 +900,24 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 *message) data->update_input = true; } +static void mxt_proc_t15_messages(struct mxt_data *data, u8 *message) +{ + struct input_dev *input_dev = data->input_dev; + unsigned long keystates = get_unaligned_le32(&message[2]); + int key; + + for (key = 0; key < data->t15_num_keys; key++) + input_report_key(input_dev, data->t15_keymap[key], + keystates & BIT(key)); + + data->update_input = true; +} + +static void mxt_proc_t97_messages(struct mxt_data *data, u8 *message) +{ + mxt_proc_t15_messages(data, message); +} + static void mxt_proc_t100_message(struct mxt_data *data, u8 *message) { struct device *dev = &data->client->dev; @@ -1017,6 +1044,12 @@ static int mxt_proc_message(struct mxt_data *data, u8 *message) } else if (report_id >= data->T9_reportid_min && report_id <= data->T9_reportid_max) { mxt_proc_t9_message(data, message); + } else if (report_id >= data->T15_reportid_min && + report_id <= data->T15_reportid_max) { + mxt_proc_t15_messages(data, message); + } else if (report_id >= data->T97_reportid_min && + report_id <= data->T97_reportid_max) { + mxt_proc_t97_messages(data, message); } else if (report_id >= data->T100_reportid_min && report_id <= data->T100_reportid_max) { mxt_proc_t100_message(data, message); @@ -1689,9 +1722,13 @@ static void mxt_free_object_table(struct mxt_data *data) data->T71_address = 0; data->T9_reportid_min = 0; data->T9_reportid_max = 0; + data->T15_reportid_min = 0; + data->T15_reportid_max = 0; data->T18_address = 0; data->T19_reportid = 0; data->T44_address = 0; + data->T97_reportid_min = 0; + data->T97_reportid_max = 0; data->T100_reportid_min = 0; data->T100_reportid_max = 0; data->max_reportid = 0; @@ -1764,6 +1801,10 @@ static int mxt_parse_object_table(struct mxt_data *data, object->num_report_ids - 1; data->num_touchids = object->num_report_ids; break; + case MXT_TOUCH_KEYARRAY_T15: + data->T15_reportid_min = min_id; + data->T15_reportid_max = max_id; + break; case MXT_SPT_COMMSCONFIG_T18: data->T18_address = object->start_address; break; @@ -1773,6 +1814,10 @@ static int mxt_parse_object_table(struct mxt_data *data, case MXT_SPT_GPIOPWM_T19: data->T19_reportid = min_id; break; + case MXT_TOUCH_PTC_KEYS_T97: + data->T97_reportid_min = min_id; + data->T97_reportid_max = max_id; + break; case MXT_TOUCH_MULTITOUCHSCREEN_T100: data->multitouch = MXT_TOUCH_MULTITOUCHSCREEN_T100; data->T100_reportid_min = min_id; @@ -2050,6 +2095,7 @@ static int mxt_initialize_input_device(struct mxt_data *data) int error; unsigned int num_mt_slots; unsigned int mt_flags = 0; + int i; switch (data->multitouch) { case MXT_TOUCH_MULTI_T9: @@ -2095,6 +2141,10 @@ static int mxt_initialize_input_device(struct mxt_data *data) input_dev->open = mxt_input_open; input_dev->close = mxt_input_close; + input_dev->keycode = data->t15_keymap; + input_dev->keycodemax = data->t15_num_keys; + input_dev->keycodesize = sizeof(data->t15_keymap[0]); + input_set_capability(input_dev, EV_KEY, BTN_TOUCH); /* For single touch */ @@ -2162,6 +2212,13 @@ static int mxt_initialize_input_device(struct mxt_data *data) 0, 255, 0, 0); } + /* For T15 and T97 Key Array */ + if (data->T15_reportid_min || data->T97_reportid_min) { + for (i = 0; i < data->t15_num_keys; i++) + input_set_capability(input_dev, + EV_KEY, data->t15_keymap[i]); + } + input_set_drvdata(input_dev, data); error = input_register_device(input_dev); @@ -3080,8 +3137,10 @@ static void mxt_input_close(struct input_dev *dev) static int mxt_parse_device_properties(struct mxt_data *data) { static const char keymap_property[] = "linux,gpio-keymap"; + static const char buttons_property[] = "linux,keycodes"; struct device *dev = &data->client->dev; u32 *keymap; + u32 *buttonmap; int n_keys; int error; @@ -3111,6 +3170,32 @@ static int mxt_parse_device_properties(struct mxt_data *data) data->t19_num_keys = n_keys; } + if (device_property_present(dev, buttons_property)) { + n_keys = device_property_count_u32(dev, buttons_property); + if (n_keys <= 0) { + error = n_keys < 0 ? n_keys : -EINVAL; + dev_err(dev, "invalid/malformed '%s' property: %d\n", + buttons_property, error); + return error; + } + + buttonmap = devm_kmalloc_array(dev, n_keys, sizeof(*buttonmap), + GFP_KERNEL); + if (!buttonmap) + return -ENOMEM; + + error = device_property_read_u32_array(dev, buttons_property, + buttonmap, n_keys); + if (error) { + dev_err(dev, "failed to parse '%s' property: %d\n", + buttons_property, error); + return error; + } + + data->t15_keymap = buttonmap; + data->t15_num_keys = n_keys; + } + return 0; } -- cgit v1.2.3 From 3a2df60200a03f78173f1fd831aa54c08464dcde Mon Sep 17 00:00:00 2001 From: Biswarup Pal Date: Mon, 1 May 2023 20:19:19 -0700 Subject: Input: uinput - allow injecting event times Currently, uinput doesn't use the input_set_timestamp API, so any event injected using uinput is not accurately timestamped in terms of measuring when the actual event happened. Hence, call the input_set_timestamp API from uinput in order to provide a more accurate sense of time for the event. Propagate only the timestamps which are a) positive, b) within a pre-defined offset (10 secs) from the current time, and c) not in the future. Signed-off-by: Biswarup Pal Reviewed-by: Peter Hutterer Reviewed-by: Siarhei Vishniakou Link: https://lore.kernel.org/r/20230427000152.1407471-1-biswarupp@google.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/uinput.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'drivers/input') diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index f2593133e524..d98212d55108 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -33,6 +33,7 @@ #define UINPUT_NAME "uinput" #define UINPUT_BUFFER_SIZE 16 #define UINPUT_NUM_REQUESTS 16 +#define UINPUT_TIMESTAMP_ALLOWED_OFFSET_SECS 10 enum uinput_state { UIST_NEW_DEVICE, UIST_SETUP_COMPLETE, UIST_CREATED }; @@ -569,11 +570,40 @@ static int uinput_setup_device_legacy(struct uinput_device *udev, return retval; } +/* + * Returns true if the given timestamp is valid (i.e., if all the following + * conditions are satisfied), false otherwise. + * 1) given timestamp is positive + * 2) it's within the allowed offset before the current time + * 3) it's not in the future + */ +static bool is_valid_timestamp(const ktime_t timestamp) +{ + ktime_t zero_time; + ktime_t current_time; + ktime_t min_time; + ktime_t offset; + + zero_time = ktime_set(0, 0); + if (ktime_compare(zero_time, timestamp) >= 0) + return false; + + current_time = ktime_get(); + offset = ktime_set(UINPUT_TIMESTAMP_ALLOWED_OFFSET_SECS, 0); + min_time = ktime_sub(current_time, offset); + + if (ktime_after(min_time, timestamp) || ktime_after(timestamp, current_time)) + return false; + + return true; +} + 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; + ktime_t timestamp; if (count != 0 && count < input_event_size()) return -EINVAL; @@ -588,6 +618,10 @@ static ssize_t uinput_inject_events(struct uinput_device *udev, if (input_event_from_user(buffer + bytes, &ev)) return -EFAULT; + timestamp = ktime_set(ev.input_event_sec, ev.input_event_usec * NSEC_PER_USEC); + if (is_valid_timestamp(timestamp)) + input_set_timestamp(udev->dev, timestamp); + input_event(udev->dev, ev.type, ev.code, ev.value); bytes += input_event_size(); cond_resched(); -- cgit v1.2.3 From fd75f3694b1dd5070408ea4a58ca7f8e0a3fcbcd Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 2 May 2023 09:41:46 -0700 Subject: Input: tests - fix use-after-free and refcount underflow in input_test_exit() With CONFIG_DEBUG_SLAB=y: # Subtest: input_core 1..3 input: Test input device as /devices/virtual/input/input1 8<--- cut here --- Unable to handle kernel paging request at virtual address 6b6b6dd7 when read ... __lock_acquire from lock_acquire+0x26c/0x300 lock_acquire from _raw_spin_lock_irqsave+0x50/0x64 _raw_spin_lock_irqsave from devres_remove+0x20/0x7c devres_remove from devres_destroy+0x8/0x24 devres_destroy from input_free_device+0x2c/0x60 input_free_device from kunit_try_run_case+0x70/0x94 [kunit] Without CONFIG_DEBUG_SLAB=y: KTAP version 1 # Subtest: input_core 1..3 input: Test input device as /devices/virtual/input/input1 ------------[ cut here ]------------ WARNING: CPU: 0 PID: 694 at lib/refcount.c:28 refcount_warn_saturate+0x54/0x100 refcount_t: underflow; use-after-free. ... Call Trace: [<0037cad4>] dump_stack+0xc/0x10 [<00377614>] __warn+0x7e/0xb4 [<0037768c>] warn_slowpath_fmt+0x42/0x62 [<001eee1c>] refcount_warn_saturate+0x54/0x100 [<000b1d34>] kfree_const+0x0/0x20 [<0036290a>] __kobject_del+0x0/0x6e [<001eee1c>] refcount_warn_saturate+0x54/0x100 [<00362a1a>] kobject_put+0xa2/0xb6 [<11965770>] kunit_generic_run_threadfn_adapter+0x0/0x1c [kunit] As per the comments for input_allocate_device() and input_register_device(), input_free_device() must be called only to free devices that have not been registered. input_unregister_device() already calls input_put_device(), thus leading to a use-after-free. Moreover, the kunit_suite.exit() method is called after every test case, even on failures. As the test itself already does cleanups in its failure paths, this may lead to a second use-after-free. Fix the first issue by dropping the call to input_allocate_device() from input_test_exit(). Fix the second issue by making the cleanup code conditional on a successful test. Fixes: fdefcbdd6f361841 ("Input: Add KUnit tests for some of the input core helper functions") Signed-off-by: Geert Uytterhoeven Reviewed-by: Javier Martinez Canillas Link: https://lore.kernel.org/r/957b3b309a44d39fb6e38b2a526b250f69ea3d2c.1683022164.git.geert+renesas@glider.be Signed-off-by: Dmitry Torokhov --- drivers/input/tests/input_test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/tests/input_test.c b/drivers/input/tests/input_test.c index e5a6c1ad2167..8b8ac3412a70 100644 --- a/drivers/input/tests/input_test.c +++ b/drivers/input/tests/input_test.c @@ -43,8 +43,8 @@ static void input_test_exit(struct kunit *test) { struct input_dev *input_dev = test->priv; - input_unregister_device(input_dev); - input_free_device(input_dev); + if (input_dev) + input_unregister_device(input_dev); } static void input_test_poll(struct input_dev *input) { } -- cgit v1.2.3 From e0f41f836f5e861bdcaf4719f160b62dbb8e9485 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 2 May 2023 09:42:29 -0700 Subject: Input: tests - modular KUnit tests should not depend on KUNIT=y While KUnit tests that cannot be built as a loadable module must depend on "KUNIT=y", this is not true for modular tests, where it adds an unnecessary limitation. Fix this by relaxing the dependency to "KUNIT". Fixes: fdefcbdd6f361841 ("Input: Add KUnit tests for some of the input core helper functions") Signed-off-by: Geert Uytterhoeven Reviewed-by: Javier Martinez Canillas Link: https://lore.kernel.org/r/483c4f520e4acc6357ebba3e605977b4c56374df.1683022164.git.geert+renesas@glider.be Signed-off-by: Dmitry Torokhov --- drivers/input/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/input') diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 735f90b74ee5..3bdbd34314b3 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -168,7 +168,7 @@ config INPUT_EVBUG config INPUT_KUNIT_TEST tristate "KUnit tests for Input" if !KUNIT_ALL_TESTS - depends on INPUT && KUNIT=y + depends on INPUT && KUNIT default KUNIT_ALL_TESTS help Say Y here if you want to build the KUnit tests for the input -- cgit v1.2.3 From 3516fa162a01f6611c3c129ce9529bdc720d36b7 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 2 May 2023 13:16:57 -0700 Subject: Input: avoid calling input_set_abs_val() in the event handling core input_abs_set_val() can nominally call input_alloc_absinfo() which may allocate memory with GFP_KERNEL flag. This does not happen when input_abs_set_val() is called by the input core to set current MT slot when handling a new input event, but it trips certain static analyzers. Rearrange the code to access the relevant structures directly. Reported-by: Teng Qi Reviewed-by: Peter Hutterer Link: https://lore.kernel.org/r/ZFBg379uuHjf+YEM@google.com Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/input.c b/drivers/input/input.c index 37e876d45eb9..f791d14ecf23 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -190,6 +190,7 @@ static int input_handle_abs_event(struct input_dev *dev, unsigned int code, int *pval) { struct input_mt *mt = dev->mt; + bool is_new_slot = false; bool is_mt_event; int *pold; @@ -210,6 +211,7 @@ static int input_handle_abs_event(struct input_dev *dev, pold = &dev->absinfo[code].value; } else if (mt) { pold = &mt->slots[mt->slot].abs[code - ABS_MT_FIRST]; + is_new_slot = mt->slot != dev->absinfo[ABS_MT_SLOT].value; } else { /* * Bypass filtering for multi-touch events when @@ -228,8 +230,8 @@ static int input_handle_abs_event(struct input_dev *dev, } /* Flush pending "slot" event */ - if (is_mt_event && mt && mt->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { - input_abs_set_val(dev, ABS_MT_SLOT, mt->slot); + if (is_new_slot) { + dev->absinfo[ABS_MT_SLOT].value = mt->slot; return INPUT_PASS_TO_HANDLERS | INPUT_SLOT; } -- cgit v1.2.3 From c73b4db076faf827d0656665ef5e97b76926b60f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 5 May 2023 11:16:29 -0700 Subject: Input: tests - fix input_test_match_device_id test Properly initialize input_device_id structure in input_test_match_device_id test to make sure it contains no garbage causing the test to randomly fail. Fixes: fdefcbdd6f36 ("Input: Add KUnit tests for some of the input core helper functions") Reported-by: Geert Uytterhoeven Tested-by: Geert Uytterhoeven Reviewed-by: Javier Martinez Canillas Link: https://lore.kernel.org/r/ZFLI7T2qZTGJ1UUK@google.com Signed-off-by: Dmitry Torokhov --- drivers/input/tests/input_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/input') diff --git a/drivers/input/tests/input_test.c b/drivers/input/tests/input_test.c index 8b8ac3412a70..0540225f0288 100644 --- a/drivers/input/tests/input_test.c +++ b/drivers/input/tests/input_test.c @@ -87,7 +87,7 @@ static void input_test_timestamp(struct kunit *test) static void input_test_match_device_id(struct kunit *test) { struct input_dev *input_dev = test->priv; - struct input_device_id id; + struct input_device_id id = { 0 }; /* * Must match when the input device bus, vendor, product, version -- cgit v1.2.3 From 3c98b8dbdced5d93cc7dfed0a1991fb265488bd9 Mon Sep 17 00:00:00 2001 From: Maximilian Weigand Date: Fri, 5 May 2023 11:30:12 -0700 Subject: Input: cyttsp5 - implement proper sleep and wakeup procedures The touchscreen can be put into a deep sleep state that prevents it from emitting touch irqs. Put the touchscreen into deep sleep during suspend if it is not marked as a wakeup source. This also fixes a problem with the touchscreen getting unresponsive after system resume when a falling edge trigger is used for the interrupt. When left on during suspend, the touchscreen would pull the interrupt line down in response to touch events, leaving the interrupt effectively disabled after resume. Signed-off-by: Maximilian Weigand Reviewed-by: Alistair Francis Link: https://lore.kernel.org/r/20230504120316.408687-2-mweigand2017@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/cyttsp5.c | 77 +++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/cyttsp5.c b/drivers/input/touchscreen/cyttsp5.c index 308061e9a830..84a004dde237 100644 --- a/drivers/input/touchscreen/cyttsp5.c +++ b/drivers/input/touchscreen/cyttsp5.c @@ -43,6 +43,7 @@ #define HID_DESC_REG 0x1 #define HID_INPUT_REG 0x3 #define HID_OUTPUT_REG 0x4 +#define HID_COMMAND_REG 0x5 #define REPORT_ID_TOUCH 0x1 #define REPORT_ID_BTN 0x3 @@ -68,6 +69,7 @@ #define HID_APP_OUTPUT_REPORT_ID 0x2F #define HID_BL_RESPONSE_REPORT_ID 0x30 #define HID_BL_OUTPUT_REPORT_ID 0x40 +#define HID_RESPONSE_REPORT_ID 0xF0 #define HID_OUTPUT_RESPONSE_REPORT_OFFSET 2 #define HID_OUTPUT_RESPONSE_CMD_OFFSET 4 @@ -78,9 +80,15 @@ #define HID_SYSINFO_BTN_MASK GENMASK(7, 0) #define HID_SYSINFO_MAX_BTN 8 +#define HID_CMD_SET_POWER 0x8 + +#define HID_POWER_ON 0x0 +#define HID_POWER_SLEEP 0x1 + #define CY_HID_OUTPUT_TIMEOUT_MS 200 #define CY_HID_OUTPUT_GET_SYSINFO_TIMEOUT_MS 3000 #define CY_HID_GET_HID_DESCRIPTOR_TIMEOUT_MS 4000 +#define CY_HID_SET_POWER_TIMEOUT 500 /* maximum number of concurrent tracks */ #define TOUCH_REPORT_SIZE 10 @@ -100,6 +108,14 @@ #define TOUCH_REPORT_USAGE_PG_MIN 0xFF010063 #define TOUCH_COL_USAGE_PG 0x000D0022 +#define SET_CMD_LOW(byte, bits) \ + ((byte) = (((byte) & 0xF0) | ((bits) & 0x0F))) +#define SET_CMD_HIGH(byte, bits)\ + ((byte) = (((byte) & 0x0F) | ((bits) & 0xF0))) +#define SET_CMD_OPCODE(byte, opcode) SET_CMD_LOW(byte, opcode) +#define SET_CMD_REPORT_TYPE(byte, type) SET_CMD_HIGH(byte, ((type) << 4)) +#define SET_CMD_REPORT_ID(byte, id) SET_CMD_LOW(byte, id) + /* System Information interface definitions */ struct cyttsp5_sensing_conf_data_dev { u8 electrodes_x; @@ -556,6 +572,40 @@ static int cyttsp5_hid_output_get_sysinfo(struct cyttsp5 *ts) return cyttsp5_get_sysinfo_regs(ts); } +static int cyttsp5_power_control(struct cyttsp5 *ts, bool on) +{ + u8 state = on ? HID_POWER_ON : HID_POWER_SLEEP; + u8 cmd[2] = { 0 }; + int rc; + + SET_CMD_REPORT_TYPE(cmd[0], 0); + SET_CMD_REPORT_ID(cmd[0], HID_POWER_SLEEP); + SET_CMD_OPCODE(cmd[1], HID_CMD_SET_POWER); + + rc = cyttsp5_write(ts, HID_COMMAND_REG, cmd, sizeof(cmd)); + if (rc) { + dev_err(ts->dev, "Failed to write power command %d", rc); + return rc; + } + + rc = wait_for_completion_interruptible_timeout(&ts->cmd_done, + msecs_to_jiffies(CY_HID_SET_POWER_TIMEOUT)); + if (rc <= 0) { + dev_err(ts->dev, "HID power cmd execution timed out\n"); + return -ETIMEDOUT; + } + + if (ts->response_buf[2] != HID_RESPONSE_REPORT_ID || + (ts->response_buf[3] & 0x03) != state || + (ts->response_buf[4] & 0x0f) != HID_CMD_SET_POWER) { + dev_err(ts->dev, "Validation of the %s response failed\n", + on ? "wakeup" : "sleep"); + return -EINVAL; + } + + return 0; +} + static int cyttsp5_hid_output_bl_launch_app(struct cyttsp5 *ts) { int rc; @@ -669,6 +719,10 @@ static irqreturn_t cyttsp5_handle_irq(int irq, void *handle) case HID_BTN_REPORT_ID: cyttsp5_btn_attention(ts->dev); break; + case HID_RESPONSE_REPORT_ID: + memcpy(ts->response_buf, ts->input_buf, size); + complete(&ts->cmd_done); + break; default: /* It is not an input but a command response */ memcpy(ts->response_buf, ts->input_buf, size); @@ -880,10 +934,33 @@ static const struct i2c_device_id cyttsp5_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, cyttsp5_i2c_id); +static int __maybe_unused cyttsp5_suspend(struct device *dev) +{ + struct cyttsp5 *ts = dev_get_drvdata(dev); + + if (!device_may_wakeup(dev)) + cyttsp5_power_control(ts, false); + + return 0; +} + +static int __maybe_unused cyttsp5_resume(struct device *dev) +{ + struct cyttsp5 *ts = dev_get_drvdata(dev); + + if (!device_may_wakeup(dev)) + cyttsp5_power_control(ts, true); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(cyttsp5_pm, cyttsp5_suspend, cyttsp5_resume); + static struct i2c_driver cyttsp5_i2c_driver = { .driver = { .name = CYTTSP5_NAME, .of_match_table = cyttsp5_of_match, + .pm = &cyttsp5_pm, }, .probe_new = cyttsp5_i2c_probe, .id_table = cyttsp5_i2c_id, -- cgit v1.2.3 From 5672bd308ef23b81eb40dd2963f925fd671a66c2 Mon Sep 17 00:00:00 2001 From: Philipp Puschmann Date: Fri, 5 May 2023 11:48:45 -0700 Subject: Input: edt-ft5x06 - add delay after waking up The touch controller needs some time to wake-up after setting the wake-up gpio. Without having a delay after wake-up probing regularly fails in edt_ft5x06_ts_identify() with an error (i.e. EREMOTEIO) that was caused by a failed i2c transfer. The datasheet sets the wake-up time to 5 ms, although it is not entirely clear. Signed-off-by: Philipp Puschmann Link: https://lore.kernel.org/r/20230505115823.545803-1-p.puschmann@pironex.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/edt-ft5x06.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 24ab9e9f5b21..3a1a5e76cd68 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c @@ -1241,6 +1241,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client) if (tsdata->wake_gpio) { usleep_range(5000, 6000); gpiod_set_value_cansleep(tsdata->wake_gpio, 1); + usleep_range(5000, 6000); } if (tsdata->reset_gpio) { -- cgit v1.2.3 From e1141b0c625e495006c814edc3ffc58ef9ee86b5 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 6 May 2023 11:40:03 -0700 Subject: Input: ili210x - probe even if no resolution information Probe the touch controller driver even if resolution information is not available. This can happen e.g. in case the touch controller suffered a failed firmware update and is stuck in bootloader mode. Signed-off-by: Marek Vasut Link: https://lore.kernel.org/r/20230217025200.203833-1-marex@denx.de Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ili210x.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index 4897fafa4204..ee4e739936dd 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -370,22 +370,33 @@ static int ili251x_firmware_update_resolution(struct device *dev) /* The firmware update blob might have changed the resolution. */ error = priv->chip->read_reg(client, REG_PANEL_INFO, &rs, sizeof(rs)); - if (error) - return error; + if (!error) { + resx = le16_to_cpup((__le16 *)rs); + resy = le16_to_cpup((__le16 *)(rs + 2)); - resx = le16_to_cpup((__le16 *)rs); - resy = le16_to_cpup((__le16 *)(rs + 2)); + /* The value reported by the firmware is invalid. */ + if (!resx || resx == 0xffff || !resy || resy == 0xffff) + error = -EINVAL; + } - /* The value reported by the firmware is invalid. */ - if (!resx || resx == 0xffff || !resy || resy == 0xffff) - return -EINVAL; + /* + * In case of error, the firmware might be stuck in bootloader mode, + * e.g. after a failed firmware update. Set maximum resolution, but + * do not fail to probe, so the user can re-trigger the firmware + * update and recover the touch controller. + */ + if (error) { + dev_warn(dev, "Invalid resolution reported by controller.\n"); + resx = 16384; + resy = 16384; + } input_abs_set_max(priv->input, ABS_X, resx - 1); input_abs_set_max(priv->input, ABS_Y, resy - 1); input_abs_set_max(priv->input, ABS_MT_POSITION_X, resx - 1); input_abs_set_max(priv->input, ABS_MT_POSITION_Y, resy - 1); - return 0; + return error; } static ssize_t ili251x_firmware_update_firmware_version(struct device *dev) @@ -977,11 +988,10 @@ static int ili210x_i2c_probe(struct i2c_client *client) if (priv->chip->has_pressure_reg) input_set_abs_params(input, ABS_MT_PRESSURE, 0, 0xa, 0, 0); error = ili251x_firmware_update_cached_state(dev); - if (error) { - dev_err(dev, "Unable to cache firmware information, err: %d\n", - error); - return error; - } + if (error) + dev_warn(dev, "Unable to cache firmware information, err: %d\n", + error); + touchscreen_parse_properties(input, true, &priv->prop); error = input_mt_init_slots(input, priv->chip->max_touches, -- cgit v1.2.3 From 29ebf697f18d9eeaa8d53c7bd16c4e6962508019 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Mon, 8 May 2023 09:41:40 -0700 Subject: Input: pwm-vibra - add newline to dev_err prints Make sure all printed messages end with a newline. Signed-off-by: Luca Weiss Reviewed-by: Caleb Connolly Reviewed-by: Brian Masney Reviewed-by: Sebastian Reichel Link: https://lore.kernel.org/r/20230427-hammerhead-vibra-v1-2-e87eeb94da51@z3ntu.xyz Signed-off-by: Dmitry Torokhov --- drivers/input/misc/pwm-vibra.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/misc/pwm-vibra.c b/drivers/input/misc/pwm-vibra.c index d0e58a7cdfa3..c08971c97ad6 100644 --- a/drivers/input/misc/pwm-vibra.c +++ b/drivers/input/misc/pwm-vibra.c @@ -42,7 +42,7 @@ static int pwm_vibrator_start(struct pwm_vibrator *vibrator) if (!vibrator->vcc_on) { err = regulator_enable(vibrator->vcc); if (err) { - dev_err(pdev, "failed to enable regulator: %d", err); + dev_err(pdev, "failed to enable regulator: %d\n", err); return err; } vibrator->vcc_on = true; @@ -54,7 +54,7 @@ static int pwm_vibrator_start(struct pwm_vibrator *vibrator) err = pwm_apply_state(vibrator->pwm, &state); if (err) { - dev_err(pdev, "failed to apply pwm state: %d", err); + dev_err(pdev, "failed to apply pwm state: %d\n", err); return err; } @@ -65,7 +65,7 @@ static int pwm_vibrator_start(struct pwm_vibrator *vibrator) err = pwm_apply_state(vibrator->pwm_dir, &state); if (err) { - dev_err(pdev, "failed to apply dir-pwm state: %d", err); + dev_err(pdev, "failed to apply dir-pwm state: %d\n", err); pwm_disable(vibrator->pwm); return err; } @@ -137,7 +137,7 @@ static int pwm_vibrator_probe(struct platform_device *pdev) err = PTR_ERR_OR_ZERO(vibrator->vcc); if (err) { if (err != -EPROBE_DEFER) - dev_err(&pdev->dev, "Failed to request regulator: %d", + dev_err(&pdev->dev, "Failed to request regulator: %d\n", err); return err; } @@ -146,7 +146,7 @@ static int pwm_vibrator_probe(struct platform_device *pdev) err = PTR_ERR_OR_ZERO(vibrator->pwm); if (err) { if (err != -EPROBE_DEFER) - dev_err(&pdev->dev, "Failed to request main pwm: %d", + dev_err(&pdev->dev, "Failed to request main pwm: %d\n", err); return err; } @@ -158,7 +158,7 @@ static int pwm_vibrator_probe(struct platform_device *pdev) state.enabled = false; err = pwm_apply_state(vibrator->pwm, &state); if (err) { - dev_err(&pdev->dev, "failed to apply initial PWM state: %d", + dev_err(&pdev->dev, "failed to apply initial PWM state: %d\n", err); return err; } @@ -172,7 +172,7 @@ static int pwm_vibrator_probe(struct platform_device *pdev) state.enabled = false; err = pwm_apply_state(vibrator->pwm_dir, &state); if (err) { - dev_err(&pdev->dev, "failed to apply initial PWM state: %d", + dev_err(&pdev->dev, "failed to apply initial PWM state: %d\n", err); return err; } @@ -189,7 +189,7 @@ static int pwm_vibrator_probe(struct platform_device *pdev) break; default: - dev_err(&pdev->dev, "Failed to request direction pwm: %d", err); + dev_err(&pdev->dev, "Failed to request direction pwm: %d\n", err); fallthrough; case -EPROBE_DEFER: @@ -207,13 +207,13 @@ static int pwm_vibrator_probe(struct platform_device *pdev) err = input_ff_create_memless(vibrator->input, NULL, pwm_vibrator_play_effect); if (err) { - dev_err(&pdev->dev, "Couldn't create FF dev: %d", err); + dev_err(&pdev->dev, "Couldn't create FF dev: %d\n", err); return err; } err = input_register_device(vibrator->input); if (err) { - dev_err(&pdev->dev, "Couldn't register input dev: %d", err); + dev_err(&pdev->dev, "Couldn't register input dev: %d\n", err); return err; } -- cgit v1.2.3 From bcf784985e35fc39d682f0dde750162e7f54a1f0 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Mon, 8 May 2023 09:41:54 -0700 Subject: Input: pwm-vibra - add support for enable GPIO Some pwm vibrators have a dedicated enable GPIO that needs to be set high so that the vibrator works. Add support for that optionally. Signed-off-by: Luca Weiss Reviewed-by: Brian Masney Reviewed-by: Sebastian Reichel Reviewed-by: Caleb Connolly Link: https://lore.kernel.org/r/20230427-hammerhead-vibra-v1-3-e87eeb94da51@z3ntu.xyz Signed-off-by: Dmitry Torokhov --- drivers/input/misc/pwm-vibra.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers/input') diff --git a/drivers/input/misc/pwm-vibra.c b/drivers/input/misc/pwm-vibra.c index c08971c97ad6..2ba035299db8 100644 --- a/drivers/input/misc/pwm-vibra.c +++ b/drivers/input/misc/pwm-vibra.c @@ -11,6 +11,7 @@ * Copyright (C) 2010, Lars-Peter Clausen */ +#include #include #include #include @@ -23,6 +24,7 @@ struct pwm_vibrator { struct input_dev *input; + struct gpio_desc *enable_gpio; struct pwm_device *pwm; struct pwm_device *pwm_dir; struct regulator *vcc; @@ -48,6 +50,8 @@ static int pwm_vibrator_start(struct pwm_vibrator *vibrator) vibrator->vcc_on = true; } + gpiod_set_value_cansleep(vibrator->enable_gpio, 1); + pwm_get_state(vibrator->pwm, &state); pwm_set_relative_duty_cycle(&state, vibrator->level, 0xffff); state.enabled = true; @@ -80,6 +84,8 @@ static void pwm_vibrator_stop(struct pwm_vibrator *vibrator) pwm_disable(vibrator->pwm_dir); pwm_disable(vibrator->pwm); + gpiod_set_value_cansleep(vibrator->enable_gpio, 0); + if (vibrator->vcc_on) { regulator_disable(vibrator->vcc); vibrator->vcc_on = false; @@ -142,6 +148,16 @@ static int pwm_vibrator_probe(struct platform_device *pdev) return err; } + vibrator->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable", + GPIOD_OUT_LOW); + err = PTR_ERR_OR_ZERO(vibrator->enable_gpio); + if (err) { + if (err != -EPROBE_DEFER) + dev_err(&pdev->dev, "Failed to request enable gpio: %d\n", + err); + return err; + } + vibrator->pwm = devm_pwm_get(&pdev->dev, "enable"); err = PTR_ERR_OR_ZERO(vibrator->pwm); if (err) { -- cgit v1.2.3 From e96220bce5176ed2309f77f061dcc0430b82b25e Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 10 May 2023 17:27:55 -0700 Subject: Input: adxl34x - do not hardcode interrupt trigger type Instead of hardcoding IRQ trigger type to IRQF_TRIGGER_HIGH, let's respect the settings specified in the firmware description. Fixes: e27c729219ad ("Input: add driver for ADXL345/346 Digital Accelerometers") Signed-off-by: Marek Vasut Acked-by: Michael Hennerich Link: https://lore.kernel.org/r/20230509203555.549158-1-marex@denx.de Signed-off-by: Dmitry Torokhov --- drivers/input/misc/adxl34x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c index eecca671b588..a3f45e0ee0c7 100644 --- a/drivers/input/misc/adxl34x.c +++ b/drivers/input/misc/adxl34x.c @@ -817,8 +817,7 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, AC_WRITE(ac, POWER_CTL, 0); err = request_threaded_irq(ac->irq, NULL, adxl34x_irq, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, - dev_name(dev), ac); + IRQF_ONESHOT, dev_name(dev), ac); if (err) { dev_err(dev, "irq %d busy?\n", ac->irq); goto err_free_mem; -- cgit v1.2.3 From d8bde56dfd86a0bba9206de8574e58c8aaac4f0f Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 17 May 2023 09:55:42 -0700 Subject: Input: Switch i2c drivers back to use .probe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After commit b8a1a4cd5a98 ("i2c: Provide a temporary .probe_new() call-back type"), all drivers being converted to .probe_new() and then 03c835f498b5 ("i2c: Switch .probe() to not take an id parameter") convert back to (the new) .probe() to be able to eventually drop .probe_new() from struct i2c_driver. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20230517164645.162294-1-u.kleine-koenig@pengutronix.de Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/as5011.c | 2 +- drivers/input/joystick/qwiic-joystick.c | 2 +- drivers/input/keyboard/adp5588-keys.c | 2 +- drivers/input/keyboard/adp5589-keys.c | 2 +- drivers/input/keyboard/cap11xx.c | 2 +- drivers/input/keyboard/cypress-sf.c | 2 +- drivers/input/keyboard/dlink-dir685-touchkeys.c | 2 +- drivers/input/keyboard/lm8323.c | 2 +- drivers/input/keyboard/lm8333.c | 2 +- drivers/input/keyboard/max7359_keypad.c | 2 +- drivers/input/keyboard/mcs_touchkey.c | 2 +- drivers/input/keyboard/mpr121_touchkey.c | 2 +- drivers/input/keyboard/pinephone-keyboard.c | 2 +- drivers/input/keyboard/qt1050.c | 2 +- drivers/input/keyboard/qt1070.c | 2 +- drivers/input/keyboard/qt2160.c | 2 +- drivers/input/keyboard/tca6416-keypad.c | 2 +- drivers/input/keyboard/tca8418_keypad.c | 2 +- drivers/input/keyboard/tm2-touchkey.c | 2 +- drivers/input/misc/ad714x-i2c.c | 2 +- drivers/input/misc/adxl34x-i2c.c | 2 +- drivers/input/misc/apanel.c | 2 +- drivers/input/misc/atmel_captouch.c | 2 +- drivers/input/misc/bma150.c | 2 +- drivers/input/misc/cma3000_d0x_i2c.c | 2 +- drivers/input/misc/da7280.c | 2 +- drivers/input/misc/drv260x.c | 2 +- drivers/input/misc/drv2665.c | 2 +- drivers/input/misc/drv2667.c | 2 +- drivers/input/misc/ibm-panel.c | 2 +- drivers/input/misc/iqs269a.c | 2 +- drivers/input/misc/iqs626a.c | 2 +- drivers/input/misc/iqs7222.c | 2 +- drivers/input/misc/kxtj9.c | 2 +- drivers/input/misc/mma8450.c | 2 +- drivers/input/misc/pcf8574_keypad.c | 2 +- drivers/input/mouse/cyapa.c | 2 +- drivers/input/mouse/elan_i2c_core.c | 2 +- drivers/input/mouse/synaptics_i2c.c | 2 +- drivers/input/rmi4/rmi_i2c.c | 2 +- drivers/input/rmi4/rmi_smbus.c | 2 +- drivers/input/touchscreen/ad7879-i2c.c | 2 +- drivers/input/touchscreen/ar1021_i2c.c | 2 +- drivers/input/touchscreen/atmel_mxt_ts.c | 2 +- drivers/input/touchscreen/auo-pixcir-ts.c | 2 +- drivers/input/touchscreen/bu21013_ts.c | 2 +- drivers/input/touchscreen/bu21029_ts.c | 2 +- drivers/input/touchscreen/chipone_icn8318.c | 2 +- drivers/input/touchscreen/chipone_icn8505.c | 2 +- drivers/input/touchscreen/cy8ctma140.c | 2 +- drivers/input/touchscreen/cy8ctmg110_ts.c | 2 +- drivers/input/touchscreen/cyttsp4_i2c.c | 2 +- drivers/input/touchscreen/cyttsp5.c | 2 +- drivers/input/touchscreen/cyttsp_i2c.c | 2 +- drivers/input/touchscreen/edt-ft5x06.c | 2 +- drivers/input/touchscreen/eeti_ts.c | 2 +- drivers/input/touchscreen/egalax_ts.c | 2 +- drivers/input/touchscreen/ektf2127.c | 2 +- drivers/input/touchscreen/elants_i2c.c | 2 +- drivers/input/touchscreen/exc3000.c | 2 +- drivers/input/touchscreen/goodix.c | 2 +- drivers/input/touchscreen/hideep.c | 2 +- drivers/input/touchscreen/himax_hx83112b.c | 2 +- drivers/input/touchscreen/hycon-hy46xx.c | 2 +- drivers/input/touchscreen/hynitron_cstxxx.c | 2 +- drivers/input/touchscreen/ili210x.c | 2 +- drivers/input/touchscreen/ilitek_ts_i2c.c | 2 +- drivers/input/touchscreen/imagis.c | 2 +- drivers/input/touchscreen/iqs5xx.c | 2 +- drivers/input/touchscreen/max11801_ts.c | 2 +- drivers/input/touchscreen/mcs5000_ts.c | 2 +- drivers/input/touchscreen/melfas_mip4.c | 2 +- drivers/input/touchscreen/migor_ts.c | 2 +- drivers/input/touchscreen/mms114.c | 2 +- drivers/input/touchscreen/msg2638.c | 2 +- drivers/input/touchscreen/novatek-nvt-ts.c | 2 +- drivers/input/touchscreen/pixcir_i2c_ts.c | 2 +- drivers/input/touchscreen/raydium_i2c_ts.c | 2 +- drivers/input/touchscreen/rohm_bu21023.c | 2 +- drivers/input/touchscreen/s6sy761.c | 2 +- drivers/input/touchscreen/silead.c | 2 +- drivers/input/touchscreen/sis_i2c.c | 2 +- drivers/input/touchscreen/st1232.c | 2 +- drivers/input/touchscreen/stmfts.c | 2 +- drivers/input/touchscreen/sx8654.c | 2 +- drivers/input/touchscreen/tsc2004.c | 2 +- drivers/input/touchscreen/tsc2007_core.c | 2 +- drivers/input/touchscreen/wacom_i2c.c | 2 +- drivers/input/touchscreen/wdt87xx_i2c.c | 2 +- drivers/input/touchscreen/zet6223.c | 2 +- drivers/input/touchscreen/zforce_ts.c | 2 +- drivers/input/touchscreen/zinitix.c | 2 +- 92 files changed, 92 insertions(+), 92 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/joystick/as5011.c b/drivers/input/joystick/as5011.c index 3b88f0b49e01..bf8b1cc0ea9c 100644 --- a/drivers/input/joystick/as5011.c +++ b/drivers/input/joystick/as5011.c @@ -348,7 +348,7 @@ static struct i2c_driver as5011_driver = { .driver = { .name = "as5011", }, - .probe_new = as5011_probe, + .probe = as5011_probe, .remove = as5011_remove, .id_table = as5011_id, }; diff --git a/drivers/input/joystick/qwiic-joystick.c b/drivers/input/joystick/qwiic-joystick.c index d4da31c0616c..7d88d76b14d6 100644 --- a/drivers/input/joystick/qwiic-joystick.c +++ b/drivers/input/joystick/qwiic-joystick.c @@ -137,7 +137,7 @@ static struct i2c_driver qwiic_driver = { .of_match_table = of_match_ptr(of_qwiic_match), }, .id_table = qwiic_id_table, - .probe_new = qwiic_probe, + .probe = qwiic_probe, }; module_i2c_driver(qwiic_driver); diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index 72ae5ce72956..896a5a989ddc 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -866,7 +866,7 @@ static struct i2c_driver adp5588_driver = { .of_match_table = adp5588_of_match, .pm = pm_sleep_ptr(&adp5588_dev_pm_ops), }, - .probe_new = adp5588_probe, + .probe = adp5588_probe, .remove = adp5588_remove, .id_table = adp5588_id, }; diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c index 38d7073863a8..8996e00cd63a 100644 --- a/drivers/input/keyboard/adp5589-keys.c +++ b/drivers/input/keyboard/adp5589-keys.c @@ -1054,7 +1054,7 @@ static struct i2c_driver adp5589_driver = { .name = KBUILD_MODNAME, .pm = pm_sleep_ptr(&adp5589_dev_pm_ops), }, - .probe_new = adp5589_probe, + .probe = adp5589_probe, .id_table = adp5589_id, }; diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c index 040696d0e49c..1b4937dce672 100644 --- a/drivers/input/keyboard/cap11xx.c +++ b/drivers/input/keyboard/cap11xx.c @@ -518,7 +518,7 @@ static struct i2c_driver cap11xx_i2c_driver = { .of_match_table = cap11xx_dt_ids, }, .id_table = cap11xx_i2c_ids, - .probe_new = cap11xx_i2c_probe, + .probe = cap11xx_i2c_probe, }; module_i2c_driver(cap11xx_i2c_driver); diff --git a/drivers/input/keyboard/cypress-sf.c b/drivers/input/keyboard/cypress-sf.c index 686388f40317..2bacd9d80ecf 100644 --- a/drivers/input/keyboard/cypress-sf.c +++ b/drivers/input/keyboard/cypress-sf.c @@ -229,7 +229,7 @@ static struct i2c_driver cypress_sf_driver = { .of_match_table = of_match_ptr(cypress_sf_of_match), }, .id_table = cypress_sf_id_table, - .probe_new = cypress_sf_probe, + .probe = cypress_sf_probe, }; module_i2c_driver(cypress_sf_driver); diff --git a/drivers/input/keyboard/dlink-dir685-touchkeys.c b/drivers/input/keyboard/dlink-dir685-touchkeys.c index ddba2bc861da..6c065eff5a5a 100644 --- a/drivers/input/keyboard/dlink-dir685-touchkeys.c +++ b/drivers/input/keyboard/dlink-dir685-touchkeys.c @@ -145,7 +145,7 @@ static struct i2c_driver dir685_tk_i2c_driver = { .name = "dlink-dir685-touchkeys", .of_match_table = of_match_ptr(dir685_tk_of_match), }, - .probe_new = dir685_tk_probe, + .probe = dir685_tk_probe, .id_table = dir685_tk_id, }; module_i2c_driver(dir685_tk_i2c_driver); diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c index 5df4d5a7ed9e..3964f6e0f6af 100644 --- a/drivers/input/keyboard/lm8323.c +++ b/drivers/input/keyboard/lm8323.c @@ -826,7 +826,7 @@ static struct i2c_driver lm8323_i2c_driver = { .name = "lm8323", .pm = pm_sleep_ptr(&lm8323_pm_ops), }, - .probe_new = lm8323_probe, + .probe = lm8323_probe, .remove = lm8323_remove, .id_table = lm8323_id, }; diff --git a/drivers/input/keyboard/lm8333.c b/drivers/input/keyboard/lm8333.c index 7457c3220f90..c9f05764e36d 100644 --- a/drivers/input/keyboard/lm8333.c +++ b/drivers/input/keyboard/lm8333.c @@ -218,7 +218,7 @@ static struct i2c_driver lm8333_driver = { .driver = { .name = "lm8333", }, - .probe_new = lm8333_probe, + .probe = lm8333_probe, .remove = lm8333_remove, .id_table = lm8333_id, }; diff --git a/drivers/input/keyboard/max7359_keypad.c b/drivers/input/keyboard/max7359_keypad.c index b363749d02e2..faab7691c219 100644 --- a/drivers/input/keyboard/max7359_keypad.c +++ b/drivers/input/keyboard/max7359_keypad.c @@ -280,7 +280,7 @@ static struct i2c_driver max7359_i2c_driver = { .name = "max7359", .pm = pm_sleep_ptr(&max7359_pm), }, - .probe_new = max7359_probe, + .probe = max7359_probe, .id_table = max7359_ids, }; diff --git a/drivers/input/keyboard/mcs_touchkey.c b/drivers/input/keyboard/mcs_touchkey.c index d414e19e4559..de312d8eb974 100644 --- a/drivers/input/keyboard/mcs_touchkey.c +++ b/drivers/input/keyboard/mcs_touchkey.c @@ -258,7 +258,7 @@ static struct i2c_driver mcs_touchkey_driver = { .name = "mcs_touchkey", .pm = pm_sleep_ptr(&mcs_touchkey_pm_ops), }, - .probe_new = mcs_touchkey_probe, + .probe = mcs_touchkey_probe, .remove = mcs_touchkey_remove, .shutdown = mcs_touchkey_shutdown, .id_table = mcs_touchkey_id, diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c index 74ad353462a3..d434753afab1 100644 --- a/drivers/input/keyboard/mpr121_touchkey.c +++ b/drivers/input/keyboard/mpr121_touchkey.c @@ -389,7 +389,7 @@ static struct i2c_driver mpr_touchkey_driver = { .of_match_table = of_match_ptr(mpr121_touchkey_dt_match_table), }, .id_table = mpr121_id, - .probe_new = mpr_touchkey_probe, + .probe = mpr_touchkey_probe, }; module_i2c_driver(mpr_touchkey_driver); diff --git a/drivers/input/keyboard/pinephone-keyboard.c b/drivers/input/keyboard/pinephone-keyboard.c index 5548699b8b38..038ff3549a7a 100644 --- a/drivers/input/keyboard/pinephone-keyboard.c +++ b/drivers/input/keyboard/pinephone-keyboard.c @@ -455,7 +455,7 @@ static const struct of_device_id ppkb_of_match[] = { MODULE_DEVICE_TABLE(of, ppkb_of_match); static struct i2c_driver ppkb_driver = { - .probe_new = ppkb_probe, + .probe = ppkb_probe, .driver = { .name = DRV_NAME, .of_match_table = ppkb_of_match, diff --git a/drivers/input/keyboard/qt1050.c b/drivers/input/keyboard/qt1050.c index 317fe2b1f827..6953097db445 100644 --- a/drivers/input/keyboard/qt1050.c +++ b/drivers/input/keyboard/qt1050.c @@ -588,7 +588,7 @@ static struct i2c_driver qt1050_driver = { .of_match_table = of_match_ptr(qt1050_of_match), .pm = pm_sleep_ptr(&qt1050_pm_ops), }, - .probe_new = qt1050_probe, + .probe = qt1050_probe, }; module_i2c_driver(qt1050_driver); diff --git a/drivers/input/keyboard/qt1070.c b/drivers/input/keyboard/qt1070.c index fabb50bde844..91aaa9fc43a4 100644 --- a/drivers/input/keyboard/qt1070.c +++ b/drivers/input/keyboard/qt1070.c @@ -271,7 +271,7 @@ static struct i2c_driver qt1070_driver = { .pm = pm_sleep_ptr(&qt1070_pm_ops), }, .id_table = qt1070_id, - .probe_new = qt1070_probe, + .probe = qt1070_probe, .remove = qt1070_remove, }; diff --git a/drivers/input/keyboard/qt2160.c b/drivers/input/keyboard/qt2160.c index 04d2ee6ff577..599ea85cfd30 100644 --- a/drivers/input/keyboard/qt2160.c +++ b/drivers/input/keyboard/qt2160.c @@ -460,7 +460,7 @@ static struct i2c_driver qt2160_driver = { }, .id_table = qt2160_idtable, - .probe_new = qt2160_probe, + .probe = qt2160_probe, .remove = qt2160_remove, }; diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c index 673b905af6fe..2f745cabf4f2 100644 --- a/drivers/input/keyboard/tca6416-keypad.c +++ b/drivers/input/keyboard/tca6416-keypad.c @@ -350,7 +350,7 @@ static struct i2c_driver tca6416_keypad_driver = { .name = "tca6416-keypad", .pm = pm_sleep_ptr(&tca6416_keypad_dev_pm_ops), }, - .probe_new = tca6416_keypad_probe, + .probe = tca6416_keypad_probe, .remove = tca6416_keypad_remove, .id_table = tca6416_id, }; diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c index 3d7492f38337..76fc19ffe21d 100644 --- a/drivers/input/keyboard/tca8418_keypad.c +++ b/drivers/input/keyboard/tca8418_keypad.c @@ -370,7 +370,7 @@ static struct i2c_driver tca8418_keypad_driver = { .name = "tca8418_keypad", .of_match_table = tca8418_dt_ids, }, - .probe_new = tca8418_keypad_probe, + .probe = tca8418_keypad_probe, .id_table = tca8418_id, }; diff --git a/drivers/input/keyboard/tm2-touchkey.c b/drivers/input/keyboard/tm2-touchkey.c index 4e20571cb4c3..75bd3ea51194 100644 --- a/drivers/input/keyboard/tm2-touchkey.c +++ b/drivers/input/keyboard/tm2-touchkey.c @@ -356,7 +356,7 @@ static struct i2c_driver tm2_touchkey_driver = { .pm = pm_sleep_ptr(&tm2_touchkey_pm_ops), .of_match_table = tm2_touchkey_of_match, }, - .probe_new = tm2_touchkey_probe, + .probe = tm2_touchkey_probe, .id_table = tm2_touchkey_id_table, }; module_i2c_driver(tm2_touchkey_driver); diff --git a/drivers/input/misc/ad714x-i2c.c b/drivers/input/misc/ad714x-i2c.c index d8e39f4a57ac..679fcfea942c 100644 --- a/drivers/input/misc/ad714x-i2c.c +++ b/drivers/input/misc/ad714x-i2c.c @@ -86,7 +86,7 @@ static struct i2c_driver ad714x_i2c_driver = { .name = "ad714x_captouch", .pm = pm_sleep_ptr(&ad714x_pm), }, - .probe_new = ad714x_i2c_probe, + .probe = ad714x_i2c_probe, .id_table = ad714x_id, }; diff --git a/drivers/input/misc/adxl34x-i2c.c b/drivers/input/misc/adxl34x-i2c.c index 1c75d98c85a7..6b880e282d99 100644 --- a/drivers/input/misc/adxl34x-i2c.c +++ b/drivers/input/misc/adxl34x-i2c.c @@ -135,7 +135,7 @@ static struct i2c_driver adxl34x_driver = { .pm = pm_sleep_ptr(&adxl34x_pm), .of_match_table = adxl34x_of_id, }, - .probe_new = adxl34x_i2c_probe, + .probe = adxl34x_i2c_probe, .remove = adxl34x_i2c_remove, .id_table = adxl34x_id, }; diff --git a/drivers/input/misc/apanel.c b/drivers/input/misc/apanel.c index f42d3219cdcc..b5219bbe856d 100644 --- a/drivers/input/misc/apanel.c +++ b/drivers/input/misc/apanel.c @@ -201,7 +201,7 @@ static struct i2c_driver apanel_driver = { .driver = { .name = APANEL, }, - .probe_new = apanel_probe, + .probe = apanel_probe, .shutdown = apanel_shutdown, .id_table = apanel_id, }; diff --git a/drivers/input/misc/atmel_captouch.c b/drivers/input/misc/atmel_captouch.c index d9704b174d3a..b6a30044e814 100644 --- a/drivers/input/misc/atmel_captouch.c +++ b/drivers/input/misc/atmel_captouch.c @@ -263,7 +263,7 @@ static const struct i2c_device_id atmel_captouch_id[] = { MODULE_DEVICE_TABLE(i2c, atmel_captouch_id); static struct i2c_driver atmel_captouch_driver = { - .probe_new = atmel_captouch_probe, + .probe = atmel_captouch_probe, .id_table = atmel_captouch_id, .driver = { .name = "atmel_captouch", diff --git a/drivers/input/misc/bma150.c b/drivers/input/misc/bma150.c index 3f9da5c3cb53..0fb4cc628f29 100644 --- a/drivers/input/misc/bma150.c +++ b/drivers/input/misc/bma150.c @@ -551,7 +551,7 @@ static struct i2c_driver bma150_driver = { }, .class = I2C_CLASS_HWMON, .id_table = bma150_id, - .probe_new = bma150_probe, + .probe = bma150_probe, .remove = bma150_remove, }; diff --git a/drivers/input/misc/cma3000_d0x_i2c.c b/drivers/input/misc/cma3000_d0x_i2c.c index 136eb3715870..a4dfb3052dc0 100644 --- a/drivers/input/misc/cma3000_d0x_i2c.c +++ b/drivers/input/misc/cma3000_d0x_i2c.c @@ -97,7 +97,7 @@ static const struct i2c_device_id cma3000_i2c_id[] = { MODULE_DEVICE_TABLE(i2c, cma3000_i2c_id); static struct i2c_driver cma3000_i2c_driver = { - .probe_new = cma3000_i2c_probe, + .probe = cma3000_i2c_probe, .remove = cma3000_i2c_remove, .id_table = cma3000_i2c_id, .driver = { diff --git a/drivers/input/misc/da7280.c b/drivers/input/misc/da7280.c index b85a19e3554f..ce82548916bb 100644 --- a/drivers/input/misc/da7280.c +++ b/drivers/input/misc/da7280.c @@ -1321,7 +1321,7 @@ static struct i2c_driver da7280_driver = { .of_match_table = of_match_ptr(da7280_of_match), .pm = pm_sleep_ptr(&da7280_pm_ops), }, - .probe_new = da7280_probe, + .probe = da7280_probe, .id_table = da7280_i2c_id, }; module_i2c_driver(da7280_driver); diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c index f5e96b36acda..6717e3c9549b 100644 --- a/drivers/input/misc/drv260x.c +++ b/drivers/input/misc/drv260x.c @@ -615,7 +615,7 @@ static const struct of_device_id drv260x_of_match[] = { MODULE_DEVICE_TABLE(of, drv260x_of_match); static struct i2c_driver drv260x_driver = { - .probe_new = drv260x_probe, + .probe = drv260x_probe, .driver = { .name = "drv260x-haptics", .of_match_table = drv260x_of_match, diff --git a/drivers/input/misc/drv2665.c b/drivers/input/misc/drv2665.c index 9145096f80ea..de27e6079d84 100644 --- a/drivers/input/misc/drv2665.c +++ b/drivers/input/misc/drv2665.c @@ -297,7 +297,7 @@ MODULE_DEVICE_TABLE(of, drv2665_of_match); #endif static struct i2c_driver drv2665_driver = { - .probe_new = drv2665_probe, + .probe = drv2665_probe, .driver = { .name = "drv2665-haptics", .of_match_table = of_match_ptr(drv2665_of_match), diff --git a/drivers/input/misc/drv2667.c b/drivers/input/misc/drv2667.c index 88b4dbe3e5b5..11c5855256e8 100644 --- a/drivers/input/misc/drv2667.c +++ b/drivers/input/misc/drv2667.c @@ -474,7 +474,7 @@ MODULE_DEVICE_TABLE(of, drv2667_of_match); #endif static struct i2c_driver drv2667_driver = { - .probe_new = drv2667_probe, + .probe = drv2667_probe, .driver = { .name = "drv2667-haptics", .of_match_table = of_match_ptr(drv2667_of_match), diff --git a/drivers/input/misc/ibm-panel.c b/drivers/input/misc/ibm-panel.c index 3969ffc1bc8d..867ac7aa10d2 100644 --- a/drivers/input/misc/ibm-panel.c +++ b/drivers/input/misc/ibm-panel.c @@ -189,7 +189,7 @@ static struct i2c_driver ibm_panel_driver = { .name = DEVICE_NAME, .of_match_table = ibm_panel_match, }, - .probe_new = ibm_panel_probe, + .probe = ibm_panel_probe, .remove = ibm_panel_remove, }; module_i2c_driver(ibm_panel_driver); diff --git a/drivers/input/misc/iqs269a.c b/drivers/input/misc/iqs269a.c index f4c3aff3895b..1272ef7b5794 100644 --- a/drivers/input/misc/iqs269a.c +++ b/drivers/input/misc/iqs269a.c @@ -1746,7 +1746,7 @@ static struct i2c_driver iqs269_i2c_driver = { .of_match_table = iqs269_of_match, .pm = pm_sleep_ptr(&iqs269_pm), }, - .probe_new = iqs269_probe, + .probe = iqs269_probe, }; module_i2c_driver(iqs269_i2c_driver); diff --git a/drivers/input/misc/iqs626a.c b/drivers/input/misc/iqs626a.c index 90f997a905b5..50035c25c3f7 100644 --- a/drivers/input/misc/iqs626a.c +++ b/drivers/input/misc/iqs626a.c @@ -1822,7 +1822,7 @@ static struct i2c_driver iqs626_i2c_driver = { .of_match_table = iqs626_of_match, .pm = pm_sleep_ptr(&iqs626_pm), }, - .probe_new = iqs626_probe, + .probe = iqs626_probe, }; module_i2c_driver(iqs626_i2c_driver); diff --git a/drivers/input/misc/iqs7222.c b/drivers/input/misc/iqs7222.c index e47ab6c1177f..096b0925f41b 100644 --- a/drivers/input/misc/iqs7222.c +++ b/drivers/input/misc/iqs7222.c @@ -2593,7 +2593,7 @@ static struct i2c_driver iqs7222_i2c_driver = { .name = "iqs7222", .of_match_table = iqs7222_of_match, }, - .probe_new = iqs7222_probe, + .probe = iqs7222_probe, }; module_i2c_driver(iqs7222_i2c_driver); diff --git a/drivers/input/misc/kxtj9.c b/drivers/input/misc/kxtj9.c index 4e806d56c55d..912e614d039d 100644 --- a/drivers/input/misc/kxtj9.c +++ b/drivers/input/misc/kxtj9.c @@ -538,7 +538,7 @@ static struct i2c_driver kxtj9_driver = { .name = NAME, .pm = pm_sleep_ptr(&kxtj9_pm_ops), }, - .probe_new = kxtj9_probe, + .probe = kxtj9_probe, .id_table = kxtj9_id, }; diff --git a/drivers/input/misc/mma8450.c b/drivers/input/misc/mma8450.c index b12152536976..76a190b2220b 100644 --- a/drivers/input/misc/mma8450.c +++ b/drivers/input/misc/mma8450.c @@ -202,7 +202,7 @@ static struct i2c_driver mma8450_driver = { .name = MMA8450_DRV_NAME, .of_match_table = mma8450_dt_ids, }, - .probe_new = mma8450_probe, + .probe = mma8450_probe, .id_table = mma8450_id, }; diff --git a/drivers/input/misc/pcf8574_keypad.c b/drivers/input/misc/pcf8574_keypad.c index 6323c3d37ef7..536cedeb38e6 100644 --- a/drivers/input/misc/pcf8574_keypad.c +++ b/drivers/input/misc/pcf8574_keypad.c @@ -199,7 +199,7 @@ static struct i2c_driver pcf8574_kp_driver = { .name = DRV_NAME, .pm = pm_sleep_ptr(&pcf8574_kp_pm_ops), }, - .probe_new = pcf8574_kp_probe, + .probe = pcf8574_kp_probe, .remove = pcf8574_kp_remove, .id_table = pcf8574_kp_id, }; diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c index dd7b0d70d791..05851bc32541 100644 --- a/drivers/input/mouse/cyapa.c +++ b/drivers/input/mouse/cyapa.c @@ -1489,7 +1489,7 @@ static struct i2c_driver cyapa_driver = { .of_match_table = of_match_ptr(cyapa_of_match), }, - .probe_new = cyapa_probe, + .probe = cyapa_probe, .id_table = cyapa_id_table, }; diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index 5f0d75a45c80..0cff742302a9 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -1424,7 +1424,7 @@ static struct i2c_driver elan_driver = { .probe_type = PROBE_PREFER_ASYNCHRONOUS, .dev_groups = elan_sysfs_groups, }, - .probe_new = elan_probe, + .probe = elan_probe, .id_table = elan_id, }; diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c index 068692a8aba5..af5cc64c622d 100644 --- a/drivers/input/mouse/synaptics_i2c.c +++ b/drivers/input/mouse/synaptics_i2c.c @@ -650,7 +650,7 @@ static struct i2c_driver synaptics_i2c_driver = { .pm = pm_sleep_ptr(&synaptics_i2c_pm), }, - .probe_new = synaptics_i2c_probe, + .probe = synaptics_i2c_probe, .remove = synaptics_i2c_remove, .id_table = synaptics_i2c_id_table, diff --git a/drivers/input/rmi4/rmi_i2c.c b/drivers/input/rmi4/rmi_i2c.c index d69569ce8d8d..091d4e23b629 100644 --- a/drivers/input/rmi4/rmi_i2c.c +++ b/drivers/input/rmi4/rmi_i2c.c @@ -377,7 +377,7 @@ static struct i2c_driver rmi_i2c_driver = { .of_match_table = of_match_ptr(rmi_i2c_of_match), }, .id_table = rmi_id, - .probe_new = rmi_i2c_probe, + .probe = rmi_i2c_probe, }; module_i2c_driver(rmi_i2c_driver); diff --git a/drivers/input/rmi4/rmi_smbus.c b/drivers/input/rmi4/rmi_smbus.c index 4bf0e1df6a4a..7059a2762aeb 100644 --- a/drivers/input/rmi4/rmi_smbus.c +++ b/drivers/input/rmi4/rmi_smbus.c @@ -418,7 +418,7 @@ static struct i2c_driver rmi_smb_driver = { .pm = pm_ptr(&rmi_smb_pm), }, .id_table = rmi_id, - .probe_new = rmi_smb_probe, + .probe = rmi_smb_probe, .remove = rmi_smb_remove, }; diff --git a/drivers/input/touchscreen/ad7879-i2c.c b/drivers/input/touchscreen/ad7879-i2c.c index dd8f31737bb8..feaa6f8b01ed 100644 --- a/drivers/input/touchscreen/ad7879-i2c.c +++ b/drivers/input/touchscreen/ad7879-i2c.c @@ -62,7 +62,7 @@ static struct i2c_driver ad7879_i2c_driver = { .pm = &ad7879_pm_ops, .of_match_table = of_match_ptr(ad7879_i2c_dt_ids), }, - .probe_new = ad7879_i2c_probe, + .probe = ad7879_i2c_probe, .id_table = ad7879_id, }; diff --git a/drivers/input/touchscreen/ar1021_i2c.c b/drivers/input/touchscreen/ar1021_i2c.c index 3a5b65cae360..64dfb749386f 100644 --- a/drivers/input/touchscreen/ar1021_i2c.c +++ b/drivers/input/touchscreen/ar1021_i2c.c @@ -182,7 +182,7 @@ static struct i2c_driver ar1021_i2c_driver = { .of_match_table = ar1021_i2c_of_match, }, - .probe_new = ar1021_i2c_probe, + .probe = ar1021_i2c_probe, .id_table = ar1021_i2c_id, }; module_i2c_driver(ar1021_i2c_driver); diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index edea1823fd36..20094b9899f0 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -3462,7 +3462,7 @@ static struct i2c_driver mxt_driver = { .acpi_match_table = ACPI_PTR(mxt_acpi_id), .pm = pm_sleep_ptr(&mxt_pm_ops), }, - .probe_new = mxt_probe, + .probe = mxt_probe, .remove = mxt_remove, .id_table = mxt_id, }; diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c index 5359efc80b2b..90c682e7407f 100644 --- a/drivers/input/touchscreen/auo-pixcir-ts.c +++ b/drivers/input/touchscreen/auo-pixcir-ts.c @@ -636,7 +636,7 @@ static struct i2c_driver auo_pixcir_driver = { .pm = pm_sleep_ptr(&auo_pixcir_pm_ops), .of_match_table = of_match_ptr(auo_pixcir_ts_dt_idtable), }, - .probe_new = auo_pixcir_probe, + .probe = auo_pixcir_probe, .id_table = auo_pixcir_idtable, }; diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c index c994ab6f4e58..85332cfaa29d 100644 --- a/drivers/input/touchscreen/bu21013_ts.c +++ b/drivers/input/touchscreen/bu21013_ts.c @@ -617,7 +617,7 @@ static struct i2c_driver bu21013_driver = { .name = DRIVER_TP, .pm = pm_sleep_ptr(&bu21013_dev_pm_ops), }, - .probe_new = bu21013_probe, + .probe = bu21013_probe, .remove = bu21013_remove, .id_table = bu21013_id, }; diff --git a/drivers/input/touchscreen/bu21029_ts.c b/drivers/input/touchscreen/bu21029_ts.c index 8f1442894ff9..c8126d2efe95 100644 --- a/drivers/input/touchscreen/bu21029_ts.c +++ b/drivers/input/touchscreen/bu21029_ts.c @@ -474,7 +474,7 @@ static struct i2c_driver bu21029_driver = { .pm = pm_sleep_ptr(&bu21029_pm_ops), }, .id_table = bu21029_ids, - .probe_new = bu21029_probe, + .probe = bu21029_probe, }; module_i2c_driver(bu21029_driver); diff --git a/drivers/input/touchscreen/chipone_icn8318.c b/drivers/input/touchscreen/chipone_icn8318.c index 32b714a6ed2d..9fbeaf17f00b 100644 --- a/drivers/input/touchscreen/chipone_icn8318.c +++ b/drivers/input/touchscreen/chipone_icn8318.c @@ -264,7 +264,7 @@ static struct i2c_driver icn8318_driver = { .pm = pm_sleep_ptr(&icn8318_pm_ops), .of_match_table = icn8318_of_match, }, - .probe_new = icn8318_probe, + .probe = icn8318_probe, .id_table = icn8318_i2c_id, }; diff --git a/drivers/input/touchscreen/chipone_icn8505.c b/drivers/input/touchscreen/chipone_icn8505.c index 246bee0bee53..b56954830b33 100644 --- a/drivers/input/touchscreen/chipone_icn8505.c +++ b/drivers/input/touchscreen/chipone_icn8505.c @@ -498,7 +498,7 @@ static struct i2c_driver icn8505_driver = { .pm = pm_sleep_ptr(&icn8505_pm_ops), .acpi_match_table = icn8505_acpi_match, }, - .probe_new = icn8505_probe, + .probe = icn8505_probe, }; module_i2c_driver(icn8505_driver); diff --git a/drivers/input/touchscreen/cy8ctma140.c b/drivers/input/touchscreen/cy8ctma140.c index cd86477d971a..967ecde23e83 100644 --- a/drivers/input/touchscreen/cy8ctma140.c +++ b/drivers/input/touchscreen/cy8ctma140.c @@ -344,7 +344,7 @@ static struct i2c_driver cy8ctma140_driver = { .of_match_table = cy8ctma140_of_match, }, .id_table = cy8ctma140_idtable, - .probe_new = cy8ctma140_probe, + .probe = cy8ctma140_probe, }; module_i2c_driver(cy8ctma140_driver); diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c index dcf50fbf6dc7..54d6c4869eb0 100644 --- a/drivers/input/touchscreen/cy8ctmg110_ts.c +++ b/drivers/input/touchscreen/cy8ctmg110_ts.c @@ -279,7 +279,7 @@ static struct i2c_driver cy8ctmg110_driver = { .pm = pm_sleep_ptr(&cy8ctmg110_pm), }, .id_table = cy8ctmg110_idtable, - .probe_new = cy8ctmg110_probe, + .probe = cy8ctmg110_probe, }; module_i2c_driver(cy8ctmg110_driver); diff --git a/drivers/input/touchscreen/cyttsp4_i2c.c b/drivers/input/touchscreen/cyttsp4_i2c.c index ec7a4779f3fb..80a6890cd45a 100644 --- a/drivers/input/touchscreen/cyttsp4_i2c.c +++ b/drivers/input/touchscreen/cyttsp4_i2c.c @@ -60,7 +60,7 @@ static struct i2c_driver cyttsp4_i2c_driver = { .name = CYTTSP4_I2C_NAME, .pm = pm_ptr(&cyttsp4_pm_ops), }, - .probe_new = cyttsp4_i2c_probe, + .probe = cyttsp4_i2c_probe, .remove = cyttsp4_i2c_remove, .id_table = cyttsp4_i2c_id, }; diff --git a/drivers/input/touchscreen/cyttsp5.c b/drivers/input/touchscreen/cyttsp5.c index 84a004dde237..026d1b88a317 100644 --- a/drivers/input/touchscreen/cyttsp5.c +++ b/drivers/input/touchscreen/cyttsp5.c @@ -962,7 +962,7 @@ static struct i2c_driver cyttsp5_i2c_driver = { .of_match_table = cyttsp5_of_match, .pm = &cyttsp5_pm, }, - .probe_new = cyttsp5_i2c_probe, + .probe = cyttsp5_i2c_probe, .id_table = cyttsp5_i2c_id, }; module_i2c_driver(cyttsp5_i2c_driver); diff --git a/drivers/input/touchscreen/cyttsp_i2c.c b/drivers/input/touchscreen/cyttsp_i2c.c index 3f91cb43ec82..127a8fda1da4 100644 --- a/drivers/input/touchscreen/cyttsp_i2c.c +++ b/drivers/input/touchscreen/cyttsp_i2c.c @@ -66,7 +66,7 @@ static struct i2c_driver cyttsp_i2c_driver = { .pm = pm_sleep_ptr(&cyttsp_pm_ops), .of_match_table = cyttsp_of_i2c_match, }, - .probe_new = cyttsp_i2c_probe, + .probe = cyttsp_i2c_probe, .id_table = cyttsp_i2c_id, }; diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 3a1a5e76cd68..795c7dad22bf 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c @@ -1511,7 +1511,7 @@ static struct i2c_driver edt_ft5x06_ts_driver = { .probe_type = PROBE_PREFER_ASYNCHRONOUS, }, .id_table = edt_ft5x06_ts_id, - .probe_new = edt_ft5x06_ts_probe, + .probe = edt_ft5x06_ts_probe, .remove = edt_ft5x06_ts_remove, }; diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c index 56fa21688bdb..5e4167f6c63e 100644 --- a/drivers/input/touchscreen/eeti_ts.c +++ b/drivers/input/touchscreen/eeti_ts.c @@ -291,7 +291,7 @@ static struct i2c_driver eeti_ts_driver = { .pm = pm_sleep_ptr(&eeti_ts_pm), .of_match_table = of_match_ptr(of_eeti_ts_match), }, - .probe_new = eeti_ts_probe, + .probe = eeti_ts_probe, .id_table = eeti_ts_id, }; diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c index 1a9805938e6d..a7f7e7308267 100644 --- a/drivers/input/touchscreen/egalax_ts.c +++ b/drivers/input/touchscreen/egalax_ts.c @@ -264,7 +264,7 @@ static struct i2c_driver egalax_ts_driver = { .of_match_table = egalax_ts_dt_ids, }, .id_table = egalax_ts_id, - .probe_new = egalax_ts_probe, + .probe = egalax_ts_probe, }; module_i2c_driver(egalax_ts_driver); diff --git a/drivers/input/touchscreen/ektf2127.c b/drivers/input/touchscreen/ektf2127.c index e6f1e46d003d..fd8724a3c19f 100644 --- a/drivers/input/touchscreen/ektf2127.c +++ b/drivers/input/touchscreen/ektf2127.c @@ -351,7 +351,7 @@ static struct i2c_driver ektf2127_driver = { .pm = pm_sleep_ptr(&ektf2127_pm_ops), .of_match_table = of_match_ptr(ektf2127_of_match), }, - .probe_new = ektf2127_probe, + .probe = ektf2127_probe, .id_table = ektf2127_i2c_id, }; module_i2c_driver(ektf2127_driver); diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c index 8a16eb51481f..2da1db64126d 100644 --- a/drivers/input/touchscreen/elants_i2c.c +++ b/drivers/input/touchscreen/elants_i2c.c @@ -1673,7 +1673,7 @@ MODULE_DEVICE_TABLE(of, elants_of_match); #endif static struct i2c_driver elants_i2c_driver = { - .probe_new = elants_i2c_probe, + .probe = elants_i2c_probe, .id_table = elants_i2c_id, .driver = { .name = DEVICE_NAME, diff --git a/drivers/input/touchscreen/exc3000.c b/drivers/input/touchscreen/exc3000.c index 69eae79e2087..4af4c1e5d0da 100644 --- a/drivers/input/touchscreen/exc3000.c +++ b/drivers/input/touchscreen/exc3000.c @@ -460,7 +460,7 @@ static struct i2c_driver exc3000_driver = { .of_match_table = of_match_ptr(exc3000_of_match), }, .id_table = exc3000_id, - .probe_new = exc3000_probe, + .probe = exc3000_probe, }; module_i2c_driver(exc3000_driver); diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index b348172f19c3..f6beef523140 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -1536,7 +1536,7 @@ MODULE_DEVICE_TABLE(of, goodix_of_match); #endif static struct i2c_driver goodix_ts_driver = { - .probe_new = goodix_ts_probe, + .probe = goodix_ts_probe, .remove = goodix_ts_remove, .id_table = goodix_ts_id, .driver = { diff --git a/drivers/input/touchscreen/hideep.c b/drivers/input/touchscreen/hideep.c index 7c7020099b0f..404153338df7 100644 --- a/drivers/input/touchscreen/hideep.c +++ b/drivers/input/touchscreen/hideep.c @@ -1136,7 +1136,7 @@ static struct i2c_driver hideep_driver = { .pm = pm_sleep_ptr(&hideep_pm_ops), }, .id_table = hideep_i2c_id, - .probe_new = hideep_probe, + .probe = hideep_probe, }; module_i2c_driver(hideep_driver); diff --git a/drivers/input/touchscreen/himax_hx83112b.c b/drivers/input/touchscreen/himax_hx83112b.c index e96150d80a48..4f6609dcdef3 100644 --- a/drivers/input/touchscreen/himax_hx83112b.c +++ b/drivers/input/touchscreen/himax_hx83112b.c @@ -349,7 +349,7 @@ MODULE_DEVICE_TABLE(of, himax_of_match); #endif static struct i2c_driver himax_ts_driver = { - .probe_new = himax_probe, + .probe = himax_probe, .id_table = himax_ts_id, .driver = { .name = "Himax-hx83112b-TS", diff --git a/drivers/input/touchscreen/hycon-hy46xx.c b/drivers/input/touchscreen/hycon-hy46xx.c index 8f4989aba9a4..2450cfa14de9 100644 --- a/drivers/input/touchscreen/hycon-hy46xx.c +++ b/drivers/input/touchscreen/hycon-hy46xx.c @@ -580,7 +580,7 @@ static struct i2c_driver hycon_hy46xx_driver = { .probe_type = PROBE_PREFER_ASYNCHRONOUS, }, .id_table = hycon_hy46xx_id, - .probe_new = hycon_hy46xx_probe, + .probe = hycon_hy46xx_probe, }; module_i2c_driver(hycon_hy46xx_driver); diff --git a/drivers/input/touchscreen/hynitron_cstxxx.c b/drivers/input/touchscreen/hynitron_cstxxx.c index e86c85addb38..05946fee4fd4 100644 --- a/drivers/input/touchscreen/hynitron_cstxxx.c +++ b/drivers/input/touchscreen/hynitron_cstxxx.c @@ -488,7 +488,7 @@ static struct i2c_driver hynitron_i2c_driver = { .probe_type = PROBE_PREFER_ASYNCHRONOUS, }, .id_table = hyn_tpd_id, - .probe_new = hyn_probe, + .probe = hyn_probe, }; module_i2c_driver(hynitron_i2c_driver); diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index ee4e739936dd..f7cd773f7292 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -1053,7 +1053,7 @@ static struct i2c_driver ili210x_ts_driver = { .of_match_table = ili210x_dt_ids, }, .id_table = ili210x_i2c_id, - .probe_new = ili210x_i2c_probe, + .probe = ili210x_i2c_probe, }; module_i2c_driver(ili210x_ts_driver); diff --git a/drivers/input/touchscreen/ilitek_ts_i2c.c b/drivers/input/touchscreen/ilitek_ts_i2c.c index d69809338498..2f872e95fbba 100644 --- a/drivers/input/touchscreen/ilitek_ts_i2c.c +++ b/drivers/input/touchscreen/ilitek_ts_i2c.c @@ -679,7 +679,7 @@ static struct i2c_driver ilitek_ts_i2c_driver = { .of_match_table = of_match_ptr(ilitek_ts_i2c_match), .acpi_match_table = ACPI_PTR(ilitekts_acpi_id), }, - .probe_new = ilitek_ts_i2c_probe, + .probe = ilitek_ts_i2c_probe, .id_table = ilitek_ts_i2c_id, }; module_i2c_driver(ilitek_ts_i2c_driver); diff --git a/drivers/input/touchscreen/imagis.c b/drivers/input/touchscreen/imagis.c index de1b16e94bb8..07111ca24455 100644 --- a/drivers/input/touchscreen/imagis.c +++ b/drivers/input/touchscreen/imagis.c @@ -357,7 +357,7 @@ static struct i2c_driver imagis_ts_driver = { .pm = pm_sleep_ptr(&imagis_pm_ops), .of_match_table = of_match_ptr(imagis_of_match), }, - .probe_new = imagis_probe, + .probe = imagis_probe, }; module_i2c_driver(imagis_ts_driver); diff --git a/drivers/input/touchscreen/iqs5xx.c b/drivers/input/touchscreen/iqs5xx.c index c73e9c5c0077..0aa9d6492df8 100644 --- a/drivers/input/touchscreen/iqs5xx.c +++ b/drivers/input/touchscreen/iqs5xx.c @@ -1093,7 +1093,7 @@ static struct i2c_driver iqs5xx_i2c_driver = { .pm = pm_sleep_ptr(&iqs5xx_pm), }, .id_table = iqs5xx_id, - .probe_new = iqs5xx_probe, + .probe = iqs5xx_probe, }; module_i2c_driver(iqs5xx_i2c_driver); diff --git a/drivers/input/touchscreen/max11801_ts.c b/drivers/input/touchscreen/max11801_ts.c index 461023fd6a09..8be6dade118c 100644 --- a/drivers/input/touchscreen/max11801_ts.c +++ b/drivers/input/touchscreen/max11801_ts.c @@ -230,7 +230,7 @@ static struct i2c_driver max11801_ts_driver = { .of_match_table = max11801_ts_dt_ids, }, .id_table = max11801_ts_id, - .probe_new = max11801_ts_probe, + .probe = max11801_ts_probe, }; module_i2c_driver(max11801_ts_driver); diff --git a/drivers/input/touchscreen/mcs5000_ts.c b/drivers/input/touchscreen/mcs5000_ts.c index 704e36087ca2..ac28019ba4c3 100644 --- a/drivers/input/touchscreen/mcs5000_ts.c +++ b/drivers/input/touchscreen/mcs5000_ts.c @@ -272,7 +272,7 @@ static const struct i2c_device_id mcs5000_ts_id[] = { MODULE_DEVICE_TABLE(i2c, mcs5000_ts_id); static struct i2c_driver mcs5000_ts_driver = { - .probe_new = mcs5000_ts_probe, + .probe = mcs5000_ts_probe, .driver = { .name = "mcs5000_ts", .pm = pm_sleep_ptr(&mcs5000_ts_pm), diff --git a/drivers/input/touchscreen/melfas_mip4.c b/drivers/input/touchscreen/melfas_mip4.c index 89b6020a9a61..32896e5085bd 100644 --- a/drivers/input/touchscreen/melfas_mip4.c +++ b/drivers/input/touchscreen/melfas_mip4.c @@ -1591,7 +1591,7 @@ MODULE_DEVICE_TABLE(i2c, mip4_i2c_ids); static struct i2c_driver mip4_driver = { .id_table = mip4_i2c_ids, - .probe_new = mip4_probe, + .probe = mip4_probe, .driver = { .name = MIP4_DEVICE_NAME, .of_match_table = of_match_ptr(mip4_of_match), diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c index 69fcc88d4f80..2384ea69a3f8 100644 --- a/drivers/input/touchscreen/migor_ts.c +++ b/drivers/input/touchscreen/migor_ts.c @@ -221,7 +221,7 @@ static struct i2c_driver migor_ts_driver = { .name = "migor_ts", .pm = pm_sleep_ptr(&migor_ts_pm), }, - .probe_new = migor_ts_probe, + .probe = migor_ts_probe, .remove = migor_ts_remove, .id_table = migor_ts_id, }; diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c index 4dbca1aad89d..ac12494c7930 100644 --- a/drivers/input/touchscreen/mms114.c +++ b/drivers/input/touchscreen/mms114.c @@ -638,7 +638,7 @@ static struct i2c_driver mms114_driver = { .pm = pm_sleep_ptr(&mms114_pm_ops), .of_match_table = of_match_ptr(mms114_dt_match), }, - .probe_new = mms114_probe, + .probe = mms114_probe, .id_table = mms114_id, }; diff --git a/drivers/input/touchscreen/msg2638.c b/drivers/input/touchscreen/msg2638.c index b23db689d995..a38af3fee34a 100644 --- a/drivers/input/touchscreen/msg2638.c +++ b/drivers/input/touchscreen/msg2638.c @@ -492,7 +492,7 @@ static const struct of_device_id msg2638_of_match[] = { MODULE_DEVICE_TABLE(of, msg2638_of_match); static struct i2c_driver msg2638_ts_driver = { - .probe_new = msg2638_ts_probe, + .probe = msg2638_ts_probe, .driver = { .name = "MStar-TS", .pm = pm_sleep_ptr(&msg2638_pm_ops), diff --git a/drivers/input/touchscreen/novatek-nvt-ts.c b/drivers/input/touchscreen/novatek-nvt-ts.c index 3e551f9d31d7..7f7d879aac6d 100644 --- a/drivers/input/touchscreen/novatek-nvt-ts.c +++ b/drivers/input/touchscreen/novatek-nvt-ts.c @@ -290,7 +290,7 @@ static struct i2c_driver nvt_ts_driver = { .name = "novatek-nvt-ts", .pm = pm_sleep_ptr(&nvt_ts_pm_ops), }, - .probe_new = nvt_ts_probe, + .probe = nvt_ts_probe, .id_table = nvt_ts_i2c_id, }; diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c index f09f4831bad4..554e179c2e48 100644 --- a/drivers/input/touchscreen/pixcir_i2c_ts.c +++ b/drivers/input/touchscreen/pixcir_i2c_ts.c @@ -617,7 +617,7 @@ static struct i2c_driver pixcir_i2c_ts_driver = { .pm = pm_sleep_ptr(&pixcir_dev_pm_ops), .of_match_table = of_match_ptr(pixcir_of_match), }, - .probe_new = pixcir_i2c_ts_probe, + .probe = pixcir_i2c_ts_probe, .id_table = pixcir_i2c_ts_id, }; diff --git a/drivers/input/touchscreen/raydium_i2c_ts.c b/drivers/input/touchscreen/raydium_i2c_ts.c index 49a06d3876cf..76e7d62d5870 100644 --- a/drivers/input/touchscreen/raydium_i2c_ts.c +++ b/drivers/input/touchscreen/raydium_i2c_ts.c @@ -1273,7 +1273,7 @@ MODULE_DEVICE_TABLE(of, raydium_of_match); #endif static struct i2c_driver raydium_i2c_driver = { - .probe_new = raydium_i2c_probe, + .probe = raydium_i2c_probe, .id_table = raydium_i2c_id, .driver = { .name = "raydium_ts", diff --git a/drivers/input/touchscreen/rohm_bu21023.c b/drivers/input/touchscreen/rohm_bu21023.c index 833422e5fd6d..240424f06b98 100644 --- a/drivers/input/touchscreen/rohm_bu21023.c +++ b/drivers/input/touchscreen/rohm_bu21023.c @@ -1183,7 +1183,7 @@ static struct i2c_driver rohm_bu21023_i2c_driver = { .driver = { .name = BU21023_NAME, }, - .probe_new = rohm_bu21023_i2c_probe, + .probe = rohm_bu21023_i2c_probe, .id_table = rohm_bu21023_i2c_id, }; module_i2c_driver(rohm_bu21023_i2c_driver); diff --git a/drivers/input/touchscreen/s6sy761.c b/drivers/input/touchscreen/s6sy761.c index 371cf4848ad5..998d99d18911 100644 --- a/drivers/input/touchscreen/s6sy761.c +++ b/drivers/input/touchscreen/s6sy761.c @@ -538,7 +538,7 @@ static struct i2c_driver s6sy761_driver = { .of_match_table = of_match_ptr(s6sy761_of_match), .pm = pm_ptr(&s6sy761_pm_ops), }, - .probe_new = s6sy761_probe, + .probe = s6sy761_probe, .remove = s6sy761_remove, .id_table = s6sy761_id, }; diff --git a/drivers/input/touchscreen/silead.c b/drivers/input/touchscreen/silead.c index a37fac089010..9e28f962e059 100644 --- a/drivers/input/touchscreen/silead.c +++ b/drivers/input/touchscreen/silead.c @@ -826,7 +826,7 @@ MODULE_DEVICE_TABLE(of, silead_ts_of_match); #endif static struct i2c_driver silead_ts_driver = { - .probe_new = silead_ts_probe, + .probe = silead_ts_probe, .id_table = silead_ts_id, .driver = { .name = SILEAD_TS_NAME, diff --git a/drivers/input/touchscreen/sis_i2c.c b/drivers/input/touchscreen/sis_i2c.c index 5a493b15b25d..426564d0fc39 100644 --- a/drivers/input/touchscreen/sis_i2c.c +++ b/drivers/input/touchscreen/sis_i2c.c @@ -393,7 +393,7 @@ static struct i2c_driver sis_ts_driver = { .name = SIS_I2C_NAME, .of_match_table = of_match_ptr(sis_ts_dt_ids), }, - .probe_new = sis_ts_probe, + .probe = sis_ts_probe, .id_table = sis_ts_id, }; module_i2c_driver(sis_ts_driver); diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index f49566dc96f8..6475084aee1b 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -384,7 +384,7 @@ static const struct of_device_id st1232_ts_dt_ids[] = { MODULE_DEVICE_TABLE(of, st1232_ts_dt_ids); static struct i2c_driver st1232_ts_driver = { - .probe_new = st1232_ts_probe, + .probe = st1232_ts_probe, .id_table = st1232_ts_id, .driver = { .name = ST1232_TS_NAME, diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c index fdbf5e68943c..56e371fd88fa 100644 --- a/drivers/input/touchscreen/stmfts.c +++ b/drivers/input/touchscreen/stmfts.c @@ -808,7 +808,7 @@ static struct i2c_driver stmfts_driver = { .pm = pm_ptr(&stmfts_pm_ops), .probe_type = PROBE_PREFER_ASYNCHRONOUS, }, - .probe_new = stmfts_probe, + .probe = stmfts_probe, .remove = stmfts_remove, .id_table = stmfts_id, }; diff --git a/drivers/input/touchscreen/sx8654.c b/drivers/input/touchscreen/sx8654.c index 52ae73035830..0293c493bc79 100644 --- a/drivers/input/touchscreen/sx8654.c +++ b/drivers/input/touchscreen/sx8654.c @@ -470,7 +470,7 @@ static struct i2c_driver sx8654_driver = { .of_match_table = of_match_ptr(sx8654_of_match), }, .id_table = sx8654_id_table, - .probe_new = sx8654_probe, + .probe = sx8654_probe, }; module_i2c_driver(sx8654_driver); diff --git a/drivers/input/touchscreen/tsc2004.c b/drivers/input/touchscreen/tsc2004.c index 45f39eb20638..b5e904c5b7c4 100644 --- a/drivers/input/touchscreen/tsc2004.c +++ b/drivers/input/touchscreen/tsc2004.c @@ -68,7 +68,7 @@ static struct i2c_driver tsc2004_driver = { .pm = pm_sleep_ptr(&tsc200x_pm_ops), }, .id_table = tsc2004_idtable, - .probe_new = tsc2004_probe, + .probe = tsc2004_probe, .remove = tsc2004_remove, }; module_i2c_driver(tsc2004_driver); diff --git a/drivers/input/touchscreen/tsc2007_core.c b/drivers/input/touchscreen/tsc2007_core.c index 21916a30fb76..b3655250d4a7 100644 --- a/drivers/input/touchscreen/tsc2007_core.c +++ b/drivers/input/touchscreen/tsc2007_core.c @@ -418,7 +418,7 @@ static struct i2c_driver tsc2007_driver = { .of_match_table = tsc2007_of_match, }, .id_table = tsc2007_idtable, - .probe_new = tsc2007_probe, + .probe = tsc2007_probe, }; module_i2c_driver(tsc2007_driver); diff --git a/drivers/input/touchscreen/wacom_i2c.c b/drivers/input/touchscreen/wacom_i2c.c index a145b9105255..f389f9c004a9 100644 --- a/drivers/input/touchscreen/wacom_i2c.c +++ b/drivers/input/touchscreen/wacom_i2c.c @@ -264,7 +264,7 @@ static struct i2c_driver wacom_i2c_driver = { .pm = pm_sleep_ptr(&wacom_i2c_pm), }, - .probe_new = wacom_i2c_probe, + .probe = wacom_i2c_probe, .id_table = wacom_i2c_id, }; module_i2c_driver(wacom_i2c_driver); diff --git a/drivers/input/touchscreen/wdt87xx_i2c.c b/drivers/input/touchscreen/wdt87xx_i2c.c index 771962af3d0a..cbc4750c53f9 100644 --- a/drivers/input/touchscreen/wdt87xx_i2c.c +++ b/drivers/input/touchscreen/wdt87xx_i2c.c @@ -1169,7 +1169,7 @@ static const struct acpi_device_id wdt87xx_acpi_id[] = { MODULE_DEVICE_TABLE(acpi, wdt87xx_acpi_id); static struct i2c_driver wdt87xx_driver = { - .probe_new = wdt87xx_ts_probe, + .probe = wdt87xx_ts_probe, .id_table = wdt87xx_dev_id, .driver = { .name = WDT87XX_NAME, diff --git a/drivers/input/touchscreen/zet6223.c b/drivers/input/touchscreen/zet6223.c index bfa0c637d569..1a034471f103 100644 --- a/drivers/input/touchscreen/zet6223.c +++ b/drivers/input/touchscreen/zet6223.c @@ -248,7 +248,7 @@ static struct i2c_driver zet6223_driver = { .name = "zet6223", .of_match_table = zet6223_of_match, }, - .probe_new = zet6223_probe, + .probe = zet6223_probe, .id_table = zet6223_id }; module_i2c_driver(zet6223_driver); diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c index 76b194285e1c..5be5112845e1 100644 --- a/drivers/input/touchscreen/zforce_ts.c +++ b/drivers/input/touchscreen/zforce_ts.c @@ -944,7 +944,7 @@ static struct i2c_driver zforce_driver = { .pm = pm_sleep_ptr(&zforce_pm_ops), .of_match_table = of_match_ptr(zforce_dt_idtable), }, - .probe_new = zforce_probe, + .probe = zforce_probe, .id_table = zforce_idtable, }; diff --git a/drivers/input/touchscreen/zinitix.c b/drivers/input/touchscreen/zinitix.c index b6ece47151b8..1b4807ba4624 100644 --- a/drivers/input/touchscreen/zinitix.c +++ b/drivers/input/touchscreen/zinitix.c @@ -617,7 +617,7 @@ MODULE_DEVICE_TABLE(of, zinitix_of_match); #endif static struct i2c_driver zinitix_ts_driver = { - .probe_new = zinitix_ts_probe, + .probe = zinitix_ts_probe, .driver = { .name = "Zinitix-TS", .pm = pm_sleep_ptr(&zinitix_pm_ops), -- cgit v1.2.3 From 100e16959c3ca8cb7be788ed3e2c5867481f35f6 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 11 May 2023 11:52:41 -0700 Subject: Input: libps2 - attach ps2dev instances as serio port's drvdata In preparation of having unified interrupt handler for PS/2 devices, instead of attaching instances of psmouse and atkbd structures as serio's driver data, switch to attaching ps2dev instances. Reviewed-by: Raul Rangel Link: https://lore.kernel.org/r/20230511185252.386941-2-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/atkbd.c | 23 +++++++++++++++-------- drivers/input/mouse/psmouse-base.c | 35 ++++++++++++++++++++--------------- drivers/input/mouse/psmouse.h | 2 ++ drivers/input/mouse/synaptics.c | 10 +++++----- drivers/input/mouse/trackpoint.c | 2 +- drivers/input/serio/libps2.c | 1 + 6 files changed, 44 insertions(+), 29 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 246958795f60..2fb2ad73e796 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -309,12 +309,19 @@ static ssize_t atkbd_show_function_row_physmap(struct atkbd *atkbd, char *buf) return vivaldi_function_row_physmap_show(&atkbd->vdata, buf); } +static struct atkbd *atkbd_from_serio(struct serio *serio) +{ + struct ps2dev *ps2dev = serio_get_drvdata(serio); + + return container_of(ps2dev, struct atkbd, ps2dev); +} + static umode_t atkbd_attr_is_visible(struct kobject *kobj, struct attribute *attr, int i) { struct device *dev = kobj_to_dev(kobj); struct serio *serio = to_serio_port(dev); - struct atkbd *atkbd = serio_get_drvdata(serio); + struct atkbd *atkbd = atkbd_from_serio(serio); if (attr == &atkbd_attr_function_row_physmap.attr && !atkbd->vdata.num_function_row_keys) @@ -399,7 +406,7 @@ static unsigned int atkbd_compat_scancode(struct atkbd *atkbd, unsigned int code static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags) { - struct atkbd *atkbd = serio_get_drvdata(serio); + struct atkbd *atkbd = atkbd_from_serio(serio); struct input_dev *dev = atkbd->dev; unsigned int code = data; int scroll = 0, hscroll = 0, click = -1; @@ -909,7 +916,7 @@ static int atkbd_reset_state(struct atkbd *atkbd) static void atkbd_cleanup(struct serio *serio) { - struct atkbd *atkbd = serio_get_drvdata(serio); + struct atkbd *atkbd = atkbd_from_serio(serio); atkbd_disable(atkbd); ps2_command(&atkbd->ps2dev, NULL, ATKBD_CMD_RESET_DEF); @@ -922,7 +929,7 @@ static void atkbd_cleanup(struct serio *serio) static void atkbd_disconnect(struct serio *serio) { - struct atkbd *atkbd = serio_get_drvdata(serio); + struct atkbd *atkbd = atkbd_from_serio(serio); atkbd_disable(atkbd); @@ -1188,7 +1195,7 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) static void atkbd_parse_fwnode_data(struct serio *serio) { - struct atkbd *atkbd = serio_get_drvdata(serio); + struct atkbd *atkbd = atkbd_from_serio(serio); struct device *dev = &serio->dev; int n; @@ -1295,7 +1302,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) static int atkbd_reconnect(struct serio *serio) { - struct atkbd *atkbd = serio_get_drvdata(serio); + struct atkbd *atkbd = atkbd_from_serio(serio); struct serio_driver *drv = serio->drv; int retval = -1; @@ -1389,7 +1396,7 @@ static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, ssize_t (*handler)(struct atkbd *, char *)) { struct serio *serio = to_serio_port(dev); - struct atkbd *atkbd = serio_get_drvdata(serio); + struct atkbd *atkbd = atkbd_from_serio(serio); return handler(atkbd, buf); } @@ -1398,7 +1405,7 @@ static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t ssize_t (*handler)(struct atkbd *, const char *, size_t)) { struct serio *serio = to_serio_port(dev); - struct atkbd *atkbd = serio_get_drvdata(serio); + struct atkbd *atkbd = atkbd_from_serio(serio); int retval; retval = mutex_lock_interruptible(&atkbd->mutex); diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index c9a7e87b273e..ed5376099fba 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -116,6 +116,13 @@ static DEFINE_MUTEX(psmouse_mutex); static struct workqueue_struct *kpsmoused_wq; +struct psmouse *psmouse_from_serio(struct serio *serio) +{ + struct ps2dev *ps2dev = serio_get_drvdata(serio); + + return container_of(ps2dev, struct psmouse, ps2dev); +} + void psmouse_report_standard_buttons(struct input_dev *dev, u8 buttons) { input_report_key(dev, BTN_LEFT, buttons & BIT(0)); @@ -336,7 +343,7 @@ static void psmouse_handle_oob_data(struct psmouse *psmouse, u8 data) static irqreturn_t psmouse_interrupt(struct serio *serio, u8 data, unsigned int flags) { - struct psmouse *psmouse = serio_get_drvdata(serio); + struct psmouse *psmouse = psmouse_from_serio(serio); if (psmouse->state == PSMOUSE_IGNORE) goto out; @@ -1344,7 +1351,7 @@ static void psmouse_resync(struct work_struct *work) goto out; if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { - parent = serio_get_drvdata(serio->parent); + parent = psmouse_from_serio(serio->parent); psmouse_deactivate(parent); } @@ -1428,13 +1435,13 @@ static void psmouse_resync(struct work_struct *work) */ static void psmouse_cleanup(struct serio *serio) { - struct psmouse *psmouse = serio_get_drvdata(serio); + struct psmouse *psmouse = psmouse_from_serio(serio); struct psmouse *parent = NULL; mutex_lock(&psmouse_mutex); if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { - parent = serio_get_drvdata(serio->parent); + parent = psmouse_from_serio(serio->parent); psmouse_deactivate(parent); } @@ -1476,7 +1483,7 @@ static void psmouse_cleanup(struct serio *serio) */ static void psmouse_disconnect(struct serio *serio) { - struct psmouse *psmouse = serio_get_drvdata(serio); + struct psmouse *psmouse = psmouse_from_serio(serio); struct psmouse *parent = NULL; mutex_lock(&psmouse_mutex); @@ -1489,7 +1496,7 @@ static void psmouse_disconnect(struct serio *serio) mutex_lock(&psmouse_mutex); if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { - parent = serio_get_drvdata(serio->parent); + parent = psmouse_from_serio(serio->parent); psmouse_deactivate(parent); } @@ -1588,7 +1595,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) * connected to this port can be successfully identified */ if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { - parent = serio_get_drvdata(serio->parent); + parent = psmouse_from_serio(serio->parent); psmouse_deactivate(parent); } @@ -1604,8 +1611,6 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); - serio_set_drvdata(serio, psmouse); - error = serio_open(serio, drv); if (error) goto err_clear_drvdata; @@ -1676,7 +1681,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) static int __psmouse_reconnect(struct serio *serio, bool fast_reconnect) { - struct psmouse *psmouse = serio_get_drvdata(serio); + struct psmouse *psmouse = psmouse_from_serio(serio); struct psmouse *parent = NULL; int (*reconnect_handler)(struct psmouse *); enum psmouse_type type; @@ -1695,7 +1700,7 @@ static int __psmouse_reconnect(struct serio *serio, bool fast_reconnect) } if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { - parent = serio_get_drvdata(serio->parent); + parent = psmouse_from_serio(serio->parent); psmouse_deactivate(parent); } @@ -1794,7 +1799,7 @@ ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *de { struct serio *serio = to_serio_port(dev); struct psmouse_attribute *attr = to_psmouse_attr(devattr); - struct psmouse *psmouse = serio_get_drvdata(serio); + struct psmouse *psmouse = psmouse_from_serio(serio); if (psmouse->protocol->smbus_companion && devattr != &psmouse_attr_protocol.dattr) @@ -1815,7 +1820,7 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev if (retval) goto out; - psmouse = serio_get_drvdata(serio); + psmouse = psmouse_from_serio(serio); if (psmouse->protocol->smbus_companion && devattr != &psmouse_attr_protocol.dattr) { @@ -1830,7 +1835,7 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev } if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { - parent = serio_get_drvdata(serio->parent); + parent = psmouse_from_serio(serio->parent); psmouse_deactivate(parent); } @@ -1925,7 +1930,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co } if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { - parent = serio_get_drvdata(serio->parent); + parent = psmouse_from_serio(serio->parent); if (parent->pt_deactivate) parent->pt_deactivate(parent); } diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index 64c3a5d3fb3e..4d8acfe0d82a 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h @@ -130,6 +130,8 @@ struct psmouse { void (*pt_deactivate)(struct psmouse *psmouse); }; +struct psmouse *psmouse_from_serio(struct serio *serio); + void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work, unsigned long delay); int psmouse_reset(struct psmouse *psmouse); diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index fa021af8506e..ada299ec5bba 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -628,7 +628,7 @@ static void synaptics_set_rate(struct psmouse *psmouse, unsigned int rate) ****************************************************************************/ static int synaptics_pt_write(struct serio *serio, u8 c) { - struct psmouse *parent = serio_get_drvdata(serio->parent); + struct psmouse *parent = psmouse_from_serio(serio->parent); u8 rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */ int error; @@ -645,7 +645,7 @@ static int synaptics_pt_write(struct serio *serio, u8 c) static int synaptics_pt_start(struct serio *serio) { - struct psmouse *parent = serio_get_drvdata(serio->parent); + struct psmouse *parent = psmouse_from_serio(serio->parent); struct synaptics_data *priv = parent->private; serio_pause_rx(parent->ps2dev.serio); @@ -657,7 +657,7 @@ static int synaptics_pt_start(struct serio *serio) static void synaptics_pt_stop(struct serio *serio) { - struct psmouse *parent = serio_get_drvdata(serio->parent); + struct psmouse *parent = psmouse_from_serio(serio->parent); struct synaptics_data *priv = parent->private; serio_pause_rx(parent->ps2dev.serio); @@ -672,7 +672,7 @@ static int synaptics_is_pt_packet(u8 *buf) static void synaptics_pass_pt_packet(struct serio *ptport, u8 *packet) { - struct psmouse *child = serio_get_drvdata(ptport); + struct psmouse *child = psmouse_from_serio(ptport); if (child && child->state == PSMOUSE_ACTIVATED) { serio_interrupt(ptport, packet[1], 0); @@ -688,7 +688,7 @@ static void synaptics_pass_pt_packet(struct serio *ptport, u8 *packet) static void synaptics_pt_activate(struct psmouse *psmouse) { struct synaptics_data *priv = psmouse->private; - struct psmouse *child = serio_get_drvdata(priv->pt_port); + struct psmouse *child = psmouse_from_serio(priv->pt_port); /* adjust the touchpad to child's choice of protocol */ if (child) { diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index 4a86b3e31d3b..5f6643b69a2c 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c @@ -216,7 +216,7 @@ static umode_t trackpoint_is_attr_visible(struct kobject *kobj, { struct device *dev = kobj_to_dev(kobj); struct serio *serio = to_serio_port(dev); - struct psmouse *psmouse = serio_get_drvdata(serio); + struct psmouse *psmouse = psmouse_from_serio(serio); return trackpoint_is_attr_available(psmouse, attr) ? attr->mode : 0; } diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index 3e19344eda93..764990723847 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c @@ -382,6 +382,7 @@ void ps2_init(struct ps2dev *ps2dev, struct serio *serio) lockdep_set_subclass(&ps2dev->cmd_mutex, serio->depth); init_waitqueue_head(&ps2dev->wait); ps2dev->serio = serio; + serio_set_drvdata(serio, ps2dev); } EXPORT_SYMBOL(ps2_init); -- cgit v1.2.3 From fc522f3bdf43efa75b54775978b6b6c19d0d997d Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 11 May 2023 11:52:42 -0700 Subject: Input: libps2 - remove special handling of ACK for command byte When getting unexpected data while waiting for an acknowledgement it does not matter what command phase is currently executed, and ps2_handle_ack() should indicate that no further processing is needed for the received data byte. Remove PS2_FLAG_ACK_CMD and associated handling. Note that while it is possible to make ps2_handle_ack (and ps2_handle_repsonse) return void, it will be done when the code will be converted to common PS/2 interrupt handler later. Reviewed-by: Raul E Rangel Link: https://lore.kernel.org/r/20230511185252.386941-3-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/serio/libps2.c | 9 ++------- include/linux/libps2.h | 1 - 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index 764990723847..399cda0d34f5 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c @@ -253,9 +253,6 @@ int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command) for (i = 0; i < receive; i++) ps2dev->cmdbuf[(receive - 1) - i] = param[i]; - /* Signal that we are sending the command byte */ - ps2dev->flags |= PS2_FLAG_ACK_CMD; - /* * Some devices (Synaptics) peform the reset before * ACKing the reset command, and so it can take a long @@ -267,9 +264,7 @@ int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command) if (rc) goto out_reset_flags; - /* Now we are sending command parameters, if any */ - ps2dev->flags &= ~PS2_FLAG_ACK_CMD; - + /* Send command parameters, if any. */ for (i = 0; i < send; i++) { rc = ps2_do_sendbyte(ps2dev, param[i], 200, 2); if (rc) @@ -436,7 +431,7 @@ bool ps2_handle_ack(struct ps2dev *ps2dev, u8 data) */ dev_dbg(&ps2dev->serio->dev, "unexpected %#02x\n", data); ps2dev->flags &= ~PS2_FLAG_WAITID; - return ps2dev->flags & PS2_FLAG_ACK_CMD; + return true; } if (!ps2dev->nak) { diff --git a/include/linux/libps2.h b/include/linux/libps2.h index 53f7e4d0f4b7..193dd53ad18b 100644 --- a/include/linux/libps2.h +++ b/include/linux/libps2.h @@ -28,7 +28,6 @@ #define PS2_FLAG_CMD1 BIT(2) /* Waiting for the first byte of command response */ #define PS2_FLAG_WAITID BIT(3) /* Command executing is GET ID */ #define PS2_FLAG_NAK BIT(4) /* Last transmission was NAKed */ -#define PS2_FLAG_ACK_CMD BIT(5) /* Waiting to ACK the command (first) byte */ struct ps2dev { struct serio *serio; -- cgit v1.2.3 From df9fe0e653c28756ab98f58175f8c58baf156ef1 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 11 May 2023 11:52:43 -0700 Subject: Input: libps2 - rework handling of command response It is not entirely correct that libps2 sets PS2_FLAG_CMD1 after the device acknowledges each byte sent to the device by the host. Rework the code so that PS2_FLAG_CMD1 and PS2_FLAG_CMD are set only once, at the beginning of PS/2 command execution. Reviewed-by: Raul E Rangel Link: https://lore.kernel.org/r/20230511185252.386941-4-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/serio/libps2.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index 399cda0d34f5..d09450eca9a7 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c @@ -247,14 +247,19 @@ int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command) serio_pause_rx(ps2dev->serio); + /* Some mice do not ACK the "get ID" command, prepare to handle this. */ ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0; ps2dev->cmdcnt = receive; - if (receive && param) - for (i = 0; i < receive; i++) - ps2dev->cmdbuf[(receive - 1) - i] = param[i]; + if (receive) { + /* Indicate that we expect response to the command. */ + ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1; + if (param) + for (i = 0; i < receive; i++) + ps2dev->cmdbuf[(receive - 1) - i] = param[i]; + } /* - * Some devices (Synaptics) peform the reset before + * Some devices (Synaptics) perform the reset before * ACKing the reset command, and so it can take a long * time before the ACK arrives. */ @@ -434,11 +439,8 @@ bool ps2_handle_ack(struct ps2dev *ps2dev, u8 data) return true; } - if (!ps2dev->nak) { + if (!ps2dev->nak) ps2dev->flags &= ~PS2_FLAG_NAK; - if (ps2dev->cmdcnt) - ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1; - } ps2dev->flags &= ~PS2_FLAG_ACK; wake_up(&ps2dev->wait); -- cgit v1.2.3 From 1db0fd245b6016c21097b5ae01aeb447484de951 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 11 May 2023 11:52:44 -0700 Subject: Input: libps2 - fix NAK handling Do not try to process "resend" or "reject" responses from the device as normal response data for a command. Reviewed-by: Raul E Rangel Link: https://lore.kernel.org/r/20230511185252.386941-5-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/serio/libps2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/input') diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index d09450eca9a7..14b70a78875d 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c @@ -445,7 +445,7 @@ bool ps2_handle_ack(struct ps2dev *ps2dev, u8 data) ps2dev->flags &= ~PS2_FLAG_ACK; wake_up(&ps2dev->wait); - if (data != PS2_RET_ACK) + if (!ps2dev->nak && data != PS2_RET_ACK) ps2_handle_response(ps2dev, data); return true; -- cgit v1.2.3 From 7d674f9150c361e5b992551b46516d41eede3722 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 11 May 2023 11:52:45 -0700 Subject: Input: libps2 - fix aborting PS/2 commands When aborting PS/2 command the kernel should [re]set all flags before waking up waiters, otherwise waiting thread may read obsolete values of flags. Reported-by: Raul Rangel Reviewed-by: Raul E Rangel Link: https://lore.kernel.org/r/20230511185252.386941-6-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/serio/libps2.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index 14b70a78875d..09eb605364bb 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c @@ -478,15 +478,22 @@ bool ps2_handle_response(struct ps2dev *ps2dev, u8 data) } EXPORT_SYMBOL(ps2_handle_response); +/* + * Clears state of PS/2 device after communication error by resetting majority + * of flags and waking up waiters, if any. + */ void ps2_cmd_aborted(struct ps2dev *ps2dev) { - if (ps2dev->flags & PS2_FLAG_ACK) + unsigned long old_flags = ps2dev->flags; + + /* reset all flags except last nak */ + ps2dev->flags &= PS2_FLAG_NAK; + + if (old_flags & PS2_FLAG_ACK) ps2dev->nak = 1; - if (ps2dev->flags & (PS2_FLAG_ACK | PS2_FLAG_CMD)) + if (old_flags & (PS2_FLAG_ACK | PS2_FLAG_CMD)) wake_up(&ps2dev->wait); - /* reset all flags except last nack */ - ps2dev->flags &= PS2_FLAG_NAK; } EXPORT_SYMBOL(ps2_cmd_aborted); -- cgit v1.2.3 From c4c7eac8ee78d896635ce05d7a1c3f813fcbe24c Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 15 May 2023 16:14:29 -0700 Subject: Input: libps2 - introduce common interrupt handler Instead of exposing inner workings of libps2 to drivers such as atkbd and psmouse, have them define pre-receive and receive callbacks, and provide a common handler that can be used with underlying serio port. While at this add kerneldoc to the module. Link: https://lore.kernel.org/r/ZGK81cxqjr/KS1kA@google.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/atkbd.c | 81 +++++++------ drivers/input/mouse/psmouse-base.c | 53 ++++----- drivers/input/serio/libps2.c | 226 ++++++++++++++++++++++++++----------- include/linux/libps2.h | 61 ++++++---- 4 files changed, 269 insertions(+), 152 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 2fb2ad73e796..c92e544c792d 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -399,46 +399,60 @@ static unsigned int atkbd_compat_scancode(struct atkbd *atkbd, unsigned int code } /* - * atkbd_interrupt(). Here takes place processing of data received from - * the keyboard into events. + * Tries to handle frame or parity error by requesting the keyboard controller + * to resend the last byte. This historically not done on x86 as controllers + * there typically do not implement this command. */ - -static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, - unsigned int flags) +static bool __maybe_unused atkbd_handle_frame_error(struct ps2dev *ps2dev, + u8 data, unsigned int flags) { - struct atkbd *atkbd = atkbd_from_serio(serio); - struct input_dev *dev = atkbd->dev; - unsigned int code = data; - int scroll = 0, hscroll = 0, click = -1; - int value; - unsigned short keycode; + struct atkbd *atkbd = container_of(ps2dev, struct atkbd, ps2dev); + struct serio *serio = ps2dev->serio; - dev_dbg(&serio->dev, "Received %02x flags %02x\n", data, flags); - -#if !defined(__i386__) && !defined (__x86_64__) - if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) { + if ((flags & (SERIO_FRAME | SERIO_PARITY)) && + (~flags & SERIO_TIMEOUT) && + !atkbd->resend && atkbd->write) { dev_warn(&serio->dev, "Frame/parity error: %02x\n", flags); serio_write(serio, ATKBD_CMD_RESEND); atkbd->resend = true; - goto out; + return true; } if (!flags && data == ATKBD_RET_ACK) atkbd->resend = false; + + return false; +} + +static enum ps2_disposition atkbd_pre_receive_byte(struct ps2dev *ps2dev, + u8 data, unsigned int flags) +{ + struct serio *serio = ps2dev->serio; + + dev_dbg(&serio->dev, "Received %02x flags %02x\n", data, flags); + +#if !defined(__i386__) && !defined (__x86_64__) + if (atkbd_handle_frame_error(ps2dev, data, flags)) + return PS2_IGNORE; #endif - if (unlikely(atkbd->ps2dev.flags & PS2_FLAG_ACK)) - if (ps2_handle_ack(&atkbd->ps2dev, data)) - goto out; + return PS2_PROCESS; +} - if (unlikely(atkbd->ps2dev.flags & PS2_FLAG_CMD)) - if (ps2_handle_response(&atkbd->ps2dev, data)) - goto out; +static void atkbd_receive_byte(struct ps2dev *ps2dev, u8 data) +{ + struct serio *serio = ps2dev->serio; + struct atkbd *atkbd = container_of(ps2dev, struct atkbd, ps2dev); + struct input_dev *dev = atkbd->dev; + unsigned int code = data; + int scroll = 0, hscroll = 0, click = -1; + int value; + unsigned short keycode; pm_wakeup_event(&serio->dev, 0); if (!atkbd->enabled) - goto out; + return; input_event(dev, EV_MSC, MSC_RAW, code); @@ -460,16 +474,16 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, case ATKBD_RET_BAT: atkbd->enabled = false; serio_reconnect(atkbd->ps2dev.serio); - goto out; + return; case ATKBD_RET_EMUL0: atkbd->emul = 1; - goto out; + return; case ATKBD_RET_EMUL1: atkbd->emul = 2; - goto out; + return; case ATKBD_RET_RELEASE: atkbd->release = true; - goto out; + return; case ATKBD_RET_ACK: case ATKBD_RET_NAK: if (printk_ratelimit()) @@ -477,18 +491,18 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, "Spurious %s on %s. " "Some program might be trying to access hardware directly.\n", data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); - goto out; + return; case ATKBD_RET_ERR: atkbd->err_count++; dev_dbg(&serio->dev, "Keyboard on %s reports too many keys pressed.\n", serio->phys); - goto out; + return; } code = atkbd_compat_scancode(atkbd, code); if (atkbd->emul && --atkbd->emul) - goto out; + return; keycode = atkbd->keycode[code]; @@ -564,8 +578,6 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, } atkbd->release = false; -out: - return IRQ_HANDLED; } static int atkbd_set_repeat_rate(struct atkbd *atkbd) @@ -1229,7 +1241,8 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) goto fail1; atkbd->dev = dev; - ps2_init(&atkbd->ps2dev, serio); + ps2_init(&atkbd->ps2dev, serio, + atkbd_pre_receive_byte, atkbd_receive_byte); INIT_DELAYED_WORK(&atkbd->event_work, atkbd_event_work); mutex_init(&atkbd->mutex); @@ -1385,7 +1398,7 @@ static struct serio_driver atkbd_drv = { }, .description = DRIVER_DESC, .id_table = atkbd_serio_ids, - .interrupt = atkbd_interrupt, + .interrupt = ps2_interrupt, .connect = atkbd_connect, .reconnect = atkbd_reconnect, .disconnect = atkbd_disconnect, diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index ed5376099fba..a0aac76b1e41 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -336,17 +336,14 @@ static void psmouse_handle_oob_data(struct psmouse *psmouse, u8 data) } } -/* - * psmouse_interrupt() handles incoming characters, either passing them - * for normal processing or gathering them as command response. - */ -static irqreturn_t psmouse_interrupt(struct serio *serio, - u8 data, unsigned int flags) +static enum ps2_disposition psmouse_pre_receive_byte(struct ps2dev *ps2dev, + u8 data, + unsigned int flags) { - struct psmouse *psmouse = psmouse_from_serio(serio); + struct psmouse *psmouse = container_of(ps2dev, struct psmouse, ps2dev); if (psmouse->state == PSMOUSE_IGNORE) - goto out; + return PS2_IGNORE; if (unlikely((flags & SERIO_TIMEOUT) || ((flags & SERIO_PARITY) && @@ -357,27 +354,25 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, "bad data from KBC -%s%s\n", flags & SERIO_TIMEOUT ? " timeout" : "", flags & SERIO_PARITY ? " bad parity" : ""); - ps2_cmd_aborted(&psmouse->ps2dev); - goto out; + return PS2_ERROR; } if (flags & SERIO_OOB_DATA) { psmouse_handle_oob_data(psmouse, data); - goto out; + return PS2_IGNORE; } - if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_ACK)) - if (ps2_handle_ack(&psmouse->ps2dev, data)) - goto out; + return PS2_PROCESS; +} - if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_CMD)) - if (ps2_handle_response(&psmouse->ps2dev, data)) - goto out; +static void psmouse_receive_byte(struct ps2dev *ps2dev, u8 data) +{ + struct psmouse *psmouse = container_of(ps2dev, struct psmouse, ps2dev); - pm_wakeup_event(&serio->dev, 0); + pm_wakeup_event(&ps2dev->serio->dev, 0); if (psmouse->state <= PSMOUSE_RESYNCING) - goto out; + return; if (psmouse->state == PSMOUSE_ACTIVATED && psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) { @@ -386,7 +381,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, psmouse->badbyte = psmouse->packet[0]; __psmouse_set_state(psmouse, PSMOUSE_RESYNCING); psmouse_queue_work(psmouse, &psmouse->resync_work, 0); - goto out; + return; } psmouse->packet[psmouse->pktcnt++] = data; @@ -395,21 +390,21 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) { if (psmouse->pktcnt == 1) { psmouse->last = jiffies; - goto out; + return; } if (psmouse->packet[1] == PSMOUSE_RET_ID || (psmouse->protocol->type == PSMOUSE_HGPK && psmouse->packet[1] == PSMOUSE_RET_BAT)) { __psmouse_set_state(psmouse, PSMOUSE_IGNORE); - serio_reconnect(serio); - goto out; + serio_reconnect(ps2dev->serio); + return; } /* Not a new device, try processing first byte normally */ psmouse->pktcnt = 1; if (psmouse_handle_byte(psmouse)) - goto out; + return; psmouse->packet[psmouse->pktcnt++] = data; } @@ -424,14 +419,11 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, psmouse->badbyte = psmouse->packet[0]; __psmouse_set_state(psmouse, PSMOUSE_RESYNCING); psmouse_queue_work(psmouse, &psmouse->resync_work, 0); - goto out; + return; } psmouse->last = jiffies; psmouse_handle_byte(psmouse); - - out: - return IRQ_HANDLED; } /* @@ -1604,7 +1596,8 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) if (!psmouse || !input_dev) goto err_free; - ps2_init(&psmouse->ps2dev, serio); + ps2_init(&psmouse->ps2dev, serio, + psmouse_pre_receive_byte, psmouse_receive_byte); INIT_DELAYED_WORK(&psmouse->resync_work, psmouse_resync); psmouse->dev = input_dev; snprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys); @@ -1786,7 +1779,7 @@ static struct serio_driver psmouse_drv = { }, .description = DRIVER_DESC, .id_table = psmouse_serio_ids, - .interrupt = psmouse_interrupt, + .interrupt = ps2_interrupt, .connect = psmouse_connect, .reconnect = psmouse_reconnect, .fast_reconnect = psmouse_fast_reconnect, diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index 09eb605364bb..7c5fc853072a 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c @@ -19,9 +19,22 @@ #define DRIVER_DESC "PS/2 driver library" -MODULE_AUTHOR("Dmitry Torokhov "); -MODULE_DESCRIPTION("PS/2 driver library"); -MODULE_LICENSE("GPL"); +#define PS2_CMD_SETSCALE11 0x00e6 +#define PS2_CMD_SETRES 0x10e8 +#define PS2_CMD_GETID 0x02f2 +#define PS2_CMD_RESET_BAT 0x02ff + +#define PS2_RET_BAT 0xaa +#define PS2_RET_ID 0x00 +#define PS2_RET_ACK 0xfa +#define PS2_RET_NAK 0xfe +#define PS2_RET_ERR 0xfc + +#define PS2_FLAG_ACK BIT(0) /* Waiting for ACK/NAK */ +#define PS2_FLAG_CMD BIT(1) /* Waiting for a command to finish */ +#define PS2_FLAG_CMD1 BIT(2) /* Waiting for the first byte of command response */ +#define PS2_FLAG_WAITID BIT(3) /* Command executing is GET ID */ +#define PS2_FLAG_NAK BIT(4) /* Last transmission was NAKed */ static int ps2_do_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout, unsigned int max_attempts) @@ -76,14 +89,17 @@ static int ps2_do_sendbyte(struct ps2dev *ps2dev, u8 byte, return error; } -/* - * ps2_sendbyte() sends a byte to the device and waits for acknowledge. - * It doesn't handle retransmission, the caller is expected to handle +/** + * ps2_sendbyte - sends a byte to the device and wait for acknowledgement + * @ps2dev: a PS/2 device to send the data to + * @byte: data to be sent to the device + * @timeout: timeout for sending the data and receiving an acknowledge + * + * The function doesn't handle retransmission, the caller is expected to handle * it when needed. * * ps2_sendbyte() can only be called from a process context. */ - int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout) { int retval; @@ -99,6 +115,13 @@ int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout) } EXPORT_SYMBOL(ps2_sendbyte); +/** + * ps2_begin_command - mark beginning of execution of a complex command + * @ps2dev: a PS/2 device executing the command + * + * Serializes a complex/compound command. Once command is finished + * ps2_end_command() should be called. + */ void ps2_begin_command(struct ps2dev *ps2dev) { struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex; @@ -107,6 +130,10 @@ void ps2_begin_command(struct ps2dev *ps2dev) } EXPORT_SYMBOL(ps2_begin_command); +/** + * ps2_end_command - mark end of execution of a complex command + * @ps2dev: a PS/2 device executing the command + */ void ps2_end_command(struct ps2dev *ps2dev) { struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex; @@ -115,11 +142,13 @@ void ps2_end_command(struct ps2dev *ps2dev) } EXPORT_SYMBOL(ps2_end_command); -/* - * ps2_drain() waits for device to transmit requested number of bytes - * and discards them. +/** + * ps2_drain - waits for device to transmit requested number of bytes + * and discards them + * @ps2dev: the PS/2 device that should be drained + * @maxbytes: maximum number of bytes to be drained + * @timeout: time to drain the device */ - void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout) { if (maxbytes > sizeof(ps2dev->cmdbuf)) { @@ -142,11 +171,11 @@ void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout) } EXPORT_SYMBOL(ps2_drain); -/* - * ps2_is_keyboard_id() checks received ID byte against the list of - * known keyboard IDs. +/** + * ps2_is_keyboard_id - checks received ID byte against the list of + * known keyboard IDs + * @id_byte: data byte that should be checked */ - bool ps2_is_keyboard_id(u8 id_byte) { static const u8 keyboard_ids[] = { @@ -167,7 +196,6 @@ EXPORT_SYMBOL(ps2_is_keyboard_id); * response and tries to reduce remaining timeout to speed up command * completion. */ - static int ps2_adjust_timeout(struct ps2dev *ps2dev, unsigned int command, unsigned int timeout) { @@ -217,13 +245,19 @@ static int ps2_adjust_timeout(struct ps2dev *ps2dev, return timeout; } -/* - * ps2_command() sends a command and its parameters to the mouse, - * then waits for the response and puts it in the param array. +/** + * __ps2_command - send a command to PS/2 device + * @ps2dev: the PS/2 device that should execute the command + * @param: a buffer containing parameters to be sent along with the command, + * or place where the results of the command execution will be deposited, + * or both + * @command: command word that encodes the command itself, as well as number of + * additional parameter bytes that should be sent to the device and expected + * length of the command response * - * ps2_command() can only be called from a process context + * Not serialized. Callers should use ps2_begin_command() and ps2_end_command() + * to ensure proper serialization for complex commands. */ - int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command) { unsigned int timeout; @@ -327,6 +361,20 @@ int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command) } EXPORT_SYMBOL(__ps2_command); +/** + * ps2_command - send a command to PS/2 device + * @ps2dev: the PS/2 device that should execute the command + * @param: a buffer containing parameters to be sent along with the command, + * or place where the results of the command execution will be deposited, + * or both + * @command: command word that encodes the command itself, as well as number of + * additional parameter bytes that should be sent to the device and expected + * length of the command response + * + * Note: ps2_command() serializes the command execution so that only one + * command can be executed at a time for either individual port or the entire + * 8042 controller. + */ int ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command) { int rc; @@ -339,14 +387,16 @@ int ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command) } EXPORT_SYMBOL(ps2_command); -/* - * ps2_sliced_command() sends an extended PS/2 command to the mouse - * using sliced syntax, understood by advanced devices, such as Logitech - * or Synaptics touchpads. The command is encoded as: +/** + * ps2_sliced_command - sends an extended PS/2 command to a mouse + * @ps2dev: the PS/2 device that should execute the command + * @command: command byte + * + * The command is sent using "sliced" syntax understood by advanced devices, + * such as Logitech or Synaptics touchpads. The command is encoded as: * 0xE6 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu * is the command. */ - int ps2_sliced_command(struct ps2dev *ps2dev, u8 command) { int i; @@ -372,12 +422,22 @@ out: } EXPORT_SYMBOL(ps2_sliced_command); -/* - * ps2_init() initializes ps2dev structure +/** + * ps2_init - initializes ps2dev structure + * @ps2dev: structure to be initialized + * @serio: serio port associated with the PS/2 device + * @pre_receive_handler: validation handler to check basic communication state + * @receive_handler: main protocol handler + * + * Prepares ps2dev structure for use in drivers for PS/2 devices. */ - -void ps2_init(struct ps2dev *ps2dev, struct serio *serio) +void ps2_init(struct ps2dev *ps2dev, struct serio *serio, + ps2_pre_receive_handler_t pre_receive_handler, + ps2_receive_handler_t receive_handler) { + ps2dev->pre_receive_handler = pre_receive_handler; + ps2dev->receive_handler = receive_handler; + mutex_init(&ps2dev->cmd_mutex); lockdep_set_subclass(&ps2dev->cmd_mutex, serio->depth); init_waitqueue_head(&ps2dev->wait); @@ -387,11 +447,35 @@ void ps2_init(struct ps2dev *ps2dev, struct serio *serio) EXPORT_SYMBOL(ps2_init); /* - * ps2_handle_ack() is supposed to be used in interrupt handler - * to properly process ACK/NAK of a command from a PS/2 device. + * ps2_handle_response() stores device's response to a command and notifies + * the process waiting for completion of the command. Note that there is a + * distinction between waiting for the first byte of the response, and + * waiting for subsequent bytes. It is done so that callers could shorten + * timeouts once first byte of response is received. */ +static void ps2_handle_response(struct ps2dev *ps2dev, u8 data) +{ + if (ps2dev->cmdcnt) + ps2dev->cmdbuf[--ps2dev->cmdcnt] = data; -bool ps2_handle_ack(struct ps2dev *ps2dev, u8 data) + if (ps2dev->flags & PS2_FLAG_CMD1) { + ps2dev->flags &= ~PS2_FLAG_CMD1; + if (ps2dev->cmdcnt) + wake_up(&ps2dev->wait); + } + + if (!ps2dev->cmdcnt) { + ps2dev->flags &= ~PS2_FLAG_CMD; + wake_up(&ps2dev->wait); + } +} + +/* + * ps2_handle_ack() processes ACK/NAK of a command from a PS/2 device, + * possibly applying workarounds for mice not acknowledging the "get ID" + * command. + */ +static void ps2_handle_ack(struct ps2dev *ps2dev, u8 data) { switch (data) { case PS2_RET_ACK: @@ -436,53 +520,25 @@ bool ps2_handle_ack(struct ps2dev *ps2dev, u8 data) */ dev_dbg(&ps2dev->serio->dev, "unexpected %#02x\n", data); ps2dev->flags &= ~PS2_FLAG_WAITID; - return true; + return; } if (!ps2dev->nak) ps2dev->flags &= ~PS2_FLAG_NAK; ps2dev->flags &= ~PS2_FLAG_ACK; - wake_up(&ps2dev->wait); if (!ps2dev->nak && data != PS2_RET_ACK) ps2_handle_response(ps2dev, data); - - return true; -} -EXPORT_SYMBOL(ps2_handle_ack); - -/* - * ps2_handle_response() is supposed to be used in interrupt handler - * to properly store device's response to a command and notify process - * waiting for completion of the command. - */ - -bool ps2_handle_response(struct ps2dev *ps2dev, u8 data) -{ - if (ps2dev->cmdcnt) - ps2dev->cmdbuf[--ps2dev->cmdcnt] = data; - - if (ps2dev->flags & PS2_FLAG_CMD1) { - ps2dev->flags &= ~PS2_FLAG_CMD1; - if (ps2dev->cmdcnt) - wake_up(&ps2dev->wait); - } - - if (!ps2dev->cmdcnt) { - ps2dev->flags &= ~PS2_FLAG_CMD; + else wake_up(&ps2dev->wait); - } - - return true; } -EXPORT_SYMBOL(ps2_handle_response); /* * Clears state of PS/2 device after communication error by resetting majority * of flags and waking up waiters, if any. */ -void ps2_cmd_aborted(struct ps2dev *ps2dev) +static void ps2_cleanup(struct ps2dev *ps2dev) { unsigned long old_flags = ps2dev->flags; @@ -494,6 +550,46 @@ void ps2_cmd_aborted(struct ps2dev *ps2dev) if (old_flags & (PS2_FLAG_ACK | PS2_FLAG_CMD)) wake_up(&ps2dev->wait); +} +/** + * ps2_interrupt - common interrupt handler for PS/2 devices + * @serio: serio port for the device + * @data: a data byte received from the device + * @flags: flags such as %SERIO_PARITY or %SERIO_TIMEOUT indicating state of + * the data transfer + * + * ps2_interrupt() invokes pre-receive handler, optionally handles command + * acknowledgement and response from the device, and finally passes the data + * to the main protocol handler for future processing. + */ +irqreturn_t ps2_interrupt(struct serio *serio, u8 data, unsigned int flags) { + struct ps2dev *ps2dev = serio_get_drvdata(serio); + enum ps2_disposition rc; + + rc = ps2dev->pre_receive_handler(ps2dev, data, flags); + switch (rc) { + case PS2_ERROR: + ps2_cleanup(ps2dev); + break; + + case PS2_IGNORE: + break; + + case PS2_PROCESS: + if (ps2dev->flags & PS2_FLAG_ACK) + ps2_handle_ack(ps2dev, data); + else if (ps2dev->flags & PS2_FLAG_CMD) + ps2_handle_response(ps2dev, data); + else + ps2dev->receive_handler(ps2dev, data); + break; + } + + return IRQ_HANDLED; } -EXPORT_SYMBOL(ps2_cmd_aborted); +EXPORT_SYMBOL(ps2_interrupt); + +MODULE_AUTHOR("Dmitry Torokhov "); +MODULE_DESCRIPTION("PS/2 driver library"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/libps2.h b/include/linux/libps2.h index 193dd53ad18b..9ca9ce4e6e64 100644 --- a/include/linux/libps2.h +++ b/include/linux/libps2.h @@ -8,43 +8,59 @@ */ #include +#include #include #include #include -#define PS2_CMD_SETSCALE11 0x00e6 -#define PS2_CMD_SETRES 0x10e8 -#define PS2_CMD_GETID 0x02f2 -#define PS2_CMD_RESET_BAT 0x02ff +struct ps2dev; -#define PS2_RET_BAT 0xaa -#define PS2_RET_ID 0x00 -#define PS2_RET_ACK 0xfa -#define PS2_RET_NAK 0xfe -#define PS2_RET_ERR 0xfc +/** + * enum ps2_disposition - indicates how received byte should be handled + * @PS2_PROCESS: pass to the main protocol handler, process normally + * @PS2_IGNORE: skip the byte + * @PS2_ERROR: do not process the byte, abort command in progress + */ +enum ps2_disposition { + PS2_PROCESS, + PS2_IGNORE, + PS2_ERROR, +}; -#define PS2_FLAG_ACK BIT(0) /* Waiting for ACK/NAK */ -#define PS2_FLAG_CMD BIT(1) /* Waiting for a command to finish */ -#define PS2_FLAG_CMD1 BIT(2) /* Waiting for the first byte of command response */ -#define PS2_FLAG_WAITID BIT(3) /* Command executing is GET ID */ -#define PS2_FLAG_NAK BIT(4) /* Last transmission was NAKed */ +typedef enum ps2_disposition (*ps2_pre_receive_handler_t)(struct ps2dev *, u8, + unsigned int); +typedef void (*ps2_receive_handler_t)(struct ps2dev *, u8); +/** + * struct ps2dev - represents a device using PS/2 protocol + * @serio: a serio port used by the PS/2 device + * @cmd_mutex: a mutex ensuring that only one command is executing at a time + * @wait: a waitqueue used to signal completion from the serio interrupt handler + * @flags: various internal flags indicating stages of PS/2 command execution + * @cmdbuf: buffer holding command response + * @cmdcnt: outstanding number of bytes of the command response + * @nak: a byte transmitted by the device when it refuses command + * @pre_receive_handler: checks communication errors and returns disposition + * (&enum ps2_disposition) of the received data byte + * @receive_handler: main handler of particular PS/2 protocol, such as keyboard + * or mouse protocol + */ struct ps2dev { struct serio *serio; - - /* Ensures that only one command is executing at a time */ struct mutex cmd_mutex; - - /* Used to signal completion from interrupt handler */ wait_queue_head_t wait; - unsigned long flags; u8 cmdbuf[8]; u8 cmdcnt; u8 nak; + + ps2_pre_receive_handler_t pre_receive_handler; + ps2_receive_handler_t receive_handler; }; -void ps2_init(struct ps2dev *ps2dev, struct serio *serio); +void ps2_init(struct ps2dev *ps2dev, struct serio *serio, + ps2_pre_receive_handler_t pre_receive_handler, + ps2_receive_handler_t receive_handler); int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout); void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout); void ps2_begin_command(struct ps2dev *ps2dev); @@ -52,9 +68,8 @@ void ps2_end_command(struct ps2dev *ps2dev); int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command); int ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command); int ps2_sliced_command(struct ps2dev *ps2dev, u8 command); -bool ps2_handle_ack(struct ps2dev *ps2dev, u8 data); -bool ps2_handle_response(struct ps2dev *ps2dev, u8 data); -void ps2_cmd_aborted(struct ps2dev *ps2dev); bool ps2_is_keyboard_id(u8 id); +irqreturn_t ps2_interrupt(struct serio *serio, u8 data, unsigned int flags); + #endif /* _LIBPS2_H */ -- cgit v1.2.3 From f219050af06d83f436945880fc9c04db3bb2860f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 11 May 2023 11:52:47 -0700 Subject: Input: libps2 - do not discard non-ack bytes when controlling LEDs Upon receiving a PS/2 command the device and controller are supposed to stop sending normal data (scancodes or movement packets) and instead immediately start delivering ACK/NAK and command response. Unfortunately often EC has an output buffer which may contain latched data by the time the EC receives a command from the host. The kernel used to ignore such data, but that may cause "stuck" keys if the data dropped happens to be a break code or a part of a break code. This occasionally happens, for example, on Chromebooks when the kernel tries to toggle CapsLock LED on a keyboard while user releases Alt+Search keyboard shortcut. Fix this by passing the first non-ACK byte to the normal handler for a handful of PS/2 commands that are expected to be used during normal device operation (as opposed to probe/configuration time). Reviewed-by: Raul E Rangel Link: https://lore.kernel.org/r/20230511185252.386941-8-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/serio/libps2.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index 7c5fc853072a..6d78a1fe00c1 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c @@ -21,7 +21,10 @@ #define PS2_CMD_SETSCALE11 0x00e6 #define PS2_CMD_SETRES 0x10e8 +#define PS2_CMD_EX_SETLEDS 0x20eb +#define PS2_CMD_SETLEDS 0x10ed #define PS2_CMD_GETID 0x02f2 +#define PS2_CMD_SETREP 0x10f3 /* Set repeat rate/set report rate */ #define PS2_CMD_RESET_BAT 0x02ff #define PS2_RET_BAT 0xaa @@ -35,6 +38,7 @@ #define PS2_FLAG_CMD1 BIT(2) /* Waiting for the first byte of command response */ #define PS2_FLAG_WAITID BIT(3) /* Command executing is GET ID */ #define PS2_FLAG_NAK BIT(4) /* Last transmission was NAKed */ +#define PS2_FLAG_PASS_NOACK BIT(5) /* Pass non-ACK byte to receive handler */ static int ps2_do_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout, unsigned int max_attempts) @@ -281,9 +285,28 @@ int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command) serio_pause_rx(ps2dev->serio); - /* Some mice do not ACK the "get ID" command, prepare to handle this. */ - ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0; ps2dev->cmdcnt = receive; + + switch (command) { + case PS2_CMD_GETID: + /* + * Some mice do not ACK the "get ID" command, prepare to + * handle this. + */ + ps2dev->flags = PS2_FLAG_WAITID; + break; + + case PS2_CMD_SETLEDS: + case PS2_CMD_EX_SETLEDS: + case PS2_CMD_SETREP: + ps2dev->flags = PS2_FLAG_PASS_NOACK; + break; + + default: + ps2dev->flags = 0; + break; + } + if (receive) { /* Indicate that we expect response to the command. */ ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1; @@ -512,14 +535,19 @@ static void ps2_handle_ack(struct ps2dev *ps2dev, u8 data) * Do not signal errors if we get unexpected reply while * waiting for an ACK to the initial (first) command byte: * the device might not be quiesced yet and continue - * delivering data. + * delivering data. For certain commands (such as set leds and + * set repeat rate) that can be used during normal device + * operation, we even pass this data byte to the normal receive + * handler. * Note that we reset PS2_FLAG_WAITID flag, so the workaround * for mice not acknowledging the Get ID command only triggers * on the 1st byte; if device spews data we really want to see * a real ACK from it. */ dev_dbg(&ps2dev->serio->dev, "unexpected %#02x\n", data); - ps2dev->flags &= ~PS2_FLAG_WAITID; + if (ps2dev->flags & PS2_FLAG_PASS_NOACK) + ps2dev->receive_handler(ps2dev, data); + ps2dev->flags &= ~(PS2_FLAG_WAITID | PS2_FLAG_PASS_NOACK); return; } -- cgit v1.2.3 From 50cd8714a12b1b8ac42139d2b453b2c1d406f0a9 Mon Sep 17 00:00:00 2001 From: Niklas Schnelle Date: Mon, 22 May 2023 14:52:24 -0700 Subject: Input: add HAS_IOPORT dependencies In a future patch HAS_IOPORT=n will result in inb()/outb() and friends not being declared. We thus need to add HAS_IOPORT as dependency for those drivers using them. Co-developed-by: Arnd Bergmann Signed-off-by: Arnd Bergmann Signed-off-by: Niklas Schnelle Link: https://lore.kernel.org/r/20230522105049.1467313-16-schnelle@linux.ibm.com Signed-off-by: Dmitry Torokhov --- drivers/input/serio/Kconfig | 1 + drivers/input/touchscreen/Kconfig | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/input') diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index f39b7b3f7942..17edc1597446 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig @@ -148,6 +148,7 @@ config HIL_MLC config SERIO_PCIPS2 tristate "PCI PS/2 keyboard and PS/2 mouse controller" depends on PCI + depends on HAS_IOPORT help Say Y here if you have a Mobility Docking station with PS/2 keyboard and mice ports. diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 143ff43c67ae..c2cbd332af1d 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -700,6 +700,7 @@ config TOUCHSCREEN_INEXIO config TOUCHSCREEN_MK712 tristate "ICS MicroClock MK712 touchscreen" + depends on ISA help Say Y here if you have the ICS MicroClock MK712 touchscreen controller chip in your system. -- cgit v1.2.3 From 9284d3b9a3609db30a528947ec4e5178055cd268 Mon Sep 17 00:00:00 2001 From: Ismael Ferreras Morezuelas Date: Mon, 22 May 2023 17:21:07 -0700 Subject: Input: xpad - spelling fixes for "Xbox" The Linux kernel is notorious for misspelling X-Box, X-box, XBox or XBOX; the official spelling is actually just Xbox. Plain and simple. Tried to respect the existing notes but still following the style guide. No functional changes intended. This only affects ancillary parts. Signed-off-by: Ismael Ferreras Morezuelas Link: https://lore.kernel.org/r/401b1d94-1348-15fd-b48f-a80e8885c7a4@gmail.com Signed-off-by: Dmitry Torokhov --- Documentation/input/devices/xpad.rst | 10 +++--- Documentation/input/gamepad.rst | 2 +- drivers/input/joystick/Kconfig | 14 ++++---- drivers/input/joystick/xpad.c | 64 ++++++++++++++++++------------------ 4 files changed, 45 insertions(+), 45 deletions(-) (limited to 'drivers/input') diff --git a/Documentation/input/devices/xpad.rst b/Documentation/input/devices/xpad.rst index 173c2acda9fd..a480bc781565 100644 --- a/Documentation/input/devices/xpad.rst +++ b/Documentation/input/devices/xpad.rst @@ -4,16 +4,16 @@ xpad - Linux USB driver for Xbox compatible controllers This driver exposes all first-party and third-party Xbox compatible controllers. It has a long history and has enjoyed considerable usage -as Window's xinput library caused most PC games to focus on Xbox +as Windows' xinput library caused most PC games to focus on Xbox controller compatibility. Due to backwards compatibility all buttons are reported as digital. -This only effects Original Xbox controllers. All later controller models +This only affects Original Xbox controllers. All later controller models have only digital face buttons. Rumble is supported on some models of Xbox 360 controllers but not of Original Xbox controllers nor on Xbox One controllers. As of writing -the Xbox One's rumble protocol has not been reverse engineered but in +the Xbox One's rumble protocol has not been reverse-engineered but in the future could be supported. @@ -82,7 +82,7 @@ I've tested this with Stepmania, and it works quite well. Unknown Controllers ------------------- -If you have an unknown xbox controller, it should work just fine with +If you have an unknown Xbox controller, it should work just fine with the default settings. HOWEVER if you have an unknown dance pad not listed below, it will not @@ -123,7 +123,7 @@ can be found on the net ([1]_, [2]_, [3]_). Thanks to the trip splitter found on the cable you don't even need to cut the original one. You can buy an extension cable and cut that instead. That way, -you can still use the controller with your X-Box, if you have one ;) +you can still use the controller with your Xbox, if you have one ;) diff --git a/Documentation/input/gamepad.rst b/Documentation/input/gamepad.rst index 71019de46036..eca17a7f5258 100644 --- a/Documentation/input/gamepad.rst +++ b/Documentation/input/gamepad.rst @@ -184,7 +184,7 @@ Gamepads report the following events: Many pads also have a third button which is branded or has a special symbol and meaning. Such buttons are mapped as BTN_MODE. Examples are the Nintendo - "HOME" button, the XBox "X"-button or Sony "PS" button. + "HOME" button, the Xbox "X" button or the Sony PlayStation "PS" button. - Rumble: diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig index 04ca3d1c2816..ac6925ce8366 100644 --- a/drivers/input/joystick/Kconfig +++ b/drivers/input/joystick/Kconfig @@ -292,33 +292,33 @@ config JOYSTICK_JOYDUMP module will be called joydump. config JOYSTICK_XPAD - tristate "X-Box gamepad support" + tristate "Xbox gamepad support" depends on USB_ARCH_HAS_HCD select USB help - Say Y here if you want to use the X-Box pad with your computer. + Say Y here if you want to use Xbox pads with your computer. Make sure to say Y to "Joystick support" (CONFIG_INPUT_JOYDEV) and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well. - For information about how to connect the X-Box pad to USB, see + For information about how to connect the Xbox pad to USB, see . To compile this driver as a module, choose M here: the module will be called xpad. config JOYSTICK_XPAD_FF - bool "X-Box gamepad rumble support" + bool "Xbox gamepad rumble support" depends on JOYSTICK_XPAD && INPUT select INPUT_FF_MEMLESS help - Say Y here if you want to take advantage of xbox 360 rumble features. + Say Y here if you want to take advantage of Xbox 360 rumble features. config JOYSTICK_XPAD_LEDS - bool "LED Support for Xbox360 controller 'BigX' LED" + bool "LED Support for the Xbox 360 controller Guide button" depends on JOYSTICK_XPAD && (LEDS_CLASS=y || LEDS_CLASS=JOYSTICK_XPAD) help This option enables support for the LED which surrounds the Big X on - XBox 360 controller. + Xbox 360 controllers. config JOYSTICK_WALKERA0701 tristate "Walkera WK-0701 RC transmitter" diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 50ecff681b89..5d6a25b42bf9 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* - * X-Box gamepad driver + * Xbox gamepad driver * * Copyright (c) 2002 Marko Friedemann * 2004 Oliver Schwartz , @@ -23,8 +23,8 @@ * - ITO Takayuki for providing essential xpad information on his website * - Vojtech Pavlik - iforce driver / input subsystem * - Greg Kroah-Hartman - usb-skeleton driver - * - XBOX Linux project - extra USB id's - * - Pekka Pöyry (quantus) - Xbox One controller reverse engineering + * - Xbox Linux project - extra USB IDs + * - Pekka Pöyry (quantus) - Xbox One controller reverse-engineering * * TODO: * - fine tune axes (especially trigger axes) @@ -52,7 +52,7 @@ * 2002-07-17 - 0.0.5 : simplified d-pad handling * * 2004-10-02 - 0.0.6 : DDR pad support - * - borrowed from the XBOX linux kernel + * - borrowed from the Xbox Linux kernel * - USB id's for commonly used dance pads are present * - dance pads will map D-PAD to buttons, not axes * - pass the module paramater 'dpad_to_buttons' to force @@ -455,49 +455,49 @@ static const signed short xpad_btn_paddles[] = { { XPAD_XBOXONE_VENDOR_PROTOCOL((vend), 208) } static const struct usb_device_id xpad_table[] = { - { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ - XPAD_XBOX360_VENDOR(0x0079), /* GPD Win 2 Controller */ + { USB_INTERFACE_INFO('X', 'B', 0) }, /* Xbox USB-IF not-approved class */ + XPAD_XBOX360_VENDOR(0x0079), /* GPD Win 2 controller */ XPAD_XBOX360_VENDOR(0x03eb), /* Wooting Keyboards (Legacy) */ - XPAD_XBOX360_VENDOR(0x044f), /* Thrustmaster X-Box 360 controllers */ - XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ - XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft X-Box One controllers */ - XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ + XPAD_XBOX360_VENDOR(0x044f), /* Thrustmaster Xbox 360 controllers */ + XPAD_XBOX360_VENDOR(0x045e), /* Microsoft Xbox 360 controllers */ + XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft Xbox One controllers */ + XPAD_XBOX360_VENDOR(0x046d), /* Logitech Xbox 360-style controllers */ XPAD_XBOX360_VENDOR(0x056e), /* Elecom JC-U3613M */ XPAD_XBOX360_VENDOR(0x06a3), /* Saitek P3600 */ - XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */ + XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz Xbox 360 controllers */ { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ XPAD_XBOXONE_VENDOR(0x0738), /* Mad Catz FightStick TE 2 */ - XPAD_XBOX360_VENDOR(0x07ff), /* Mad Catz GamePad */ + XPAD_XBOX360_VENDOR(0x07ff), /* Mad Catz Gamepad */ XPAD_XBOX360_VENDOR(0x0c12), /* Zeroplus X-Box 360 controllers */ - XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */ - XPAD_XBOXONE_VENDOR(0x0e6f), /* 0x0e6f X-Box One controllers */ - XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */ - XPAD_XBOXONE_VENDOR(0x0f0d), /* Hori Controllers */ - XPAD_XBOX360_VENDOR(0x1038), /* SteelSeries Controllers */ + XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f Xbox 360 controllers */ + XPAD_XBOXONE_VENDOR(0x0e6f), /* 0x0e6f Xbox One controllers */ + XPAD_XBOX360_VENDOR(0x0f0d), /* Hori controllers */ + XPAD_XBOXONE_VENDOR(0x0f0d), /* Hori controllers */ + XPAD_XBOX360_VENDOR(0x1038), /* SteelSeries controllers */ XPAD_XBOXONE_VENDOR(0x10f5), /* Turtle Beach Controllers */ XPAD_XBOX360_VENDOR(0x11c9), /* Nacon GC100XF */ XPAD_XBOX360_VENDOR(0x1209), /* Ardwiino Controllers */ - XPAD_XBOX360_VENDOR(0x12ab), /* X-Box 360 dance pads */ - XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */ - XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */ + XPAD_XBOX360_VENDOR(0x12ab), /* Xbox 360 dance pads */ + XPAD_XBOX360_VENDOR(0x1430), /* RedOctane Xbox 360 controllers */ + XPAD_XBOX360_VENDOR(0x146b), /* Bigben Interactive controllers */ XPAD_XBOX360_VENDOR(0x1532), /* Razer Sabertooth */ XPAD_XBOXONE_VENDOR(0x1532), /* Razer Wildcat */ - XPAD_XBOX360_VENDOR(0x15e4), /* Numark X-Box 360 controllers */ - XPAD_XBOX360_VENDOR(0x162e), /* Joytech X-Box 360 controllers */ + XPAD_XBOX360_VENDOR(0x15e4), /* Numark Xbox 360 controllers */ + XPAD_XBOX360_VENDOR(0x162e), /* Joytech Xbox 360 controllers */ XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */ XPAD_XBOX360_VENDOR(0x1949), /* Amazon controllers */ - XPAD_XBOX360_VENDOR(0x1bad), /* Harminix Rock Band Guitar and Drums */ - XPAD_XBOX360_VENDOR(0x20d6), /* PowerA Controllers */ - XPAD_XBOXONE_VENDOR(0x20d6), /* PowerA Controllers */ - XPAD_XBOX360_VENDOR(0x24c6), /* PowerA Controllers */ - XPAD_XBOXONE_VENDOR(0x24c6), /* PowerA Controllers */ + XPAD_XBOX360_VENDOR(0x1bad), /* Harmonix Rock Band guitar and drums */ + XPAD_XBOX360_VENDOR(0x20d6), /* PowerA controllers */ + XPAD_XBOXONE_VENDOR(0x20d6), /* PowerA controllers */ + XPAD_XBOX360_VENDOR(0x24c6), /* PowerA controllers */ + XPAD_XBOXONE_VENDOR(0x24c6), /* PowerA controllers */ XPAD_XBOX360_VENDOR(0x2563), /* OneXPlayer Gamepad */ XPAD_XBOX360_VENDOR(0x260d), /* Dareu H101 */ XPAD_XBOX360_VENDOR(0x2c22), /* Qanba Controllers */ XPAD_XBOX360_VENDOR(0x2dc8), /* 8BitDo Pro 2 Wired Controller */ XPAD_XBOXONE_VENDOR(0x2dc8), /* 8BitDo Pro 2 Wired Controller for Xbox */ - XPAD_XBOXONE_VENDOR(0x2e24), /* Hyperkin Duke X-Box One pad */ - XPAD_XBOX360_VENDOR(0x2f24), /* GameSir Controllers */ + XPAD_XBOXONE_VENDOR(0x2e24), /* Hyperkin Duke Xbox One pad */ + XPAD_XBOX360_VENDOR(0x2f24), /* GameSir controllers */ XPAD_XBOX360_VENDOR(0x31e3), /* Wooting Keyboards */ XPAD_XBOX360_VENDOR(0x3285), /* Nacon GC-100 */ { } @@ -725,7 +725,7 @@ static void xpad360w_poweroff_controller(struct usb_xpad *xpad); * Completes a request by converting the data into events for the * input subsystem. * - * The used report descriptor was taken from ITO Takayukis website: + * The used report descriptor was taken from ITO Takayuki's website: * http://euc.jp/periphs/xbox-controller.ja.html */ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data) @@ -1569,7 +1569,7 @@ struct xpad_led { }; /* - * set the LEDs on Xbox360 / Wireless Controllers + * set the LEDs on Xbox 360 / Wireless Controllers * @param command * 0: off * 1: all blink, then previous setting @@ -2229,5 +2229,5 @@ static struct usb_driver xpad_driver = { module_usb_driver(xpad_driver); MODULE_AUTHOR("Marko Friedemann "); -MODULE_DESCRIPTION("X-Box pad driver"); +MODULE_DESCRIPTION("Xbox pad driver"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 3615536c921bda1a7166e78281b8316d6c363cc1 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 23 May 2023 14:42:15 -0700 Subject: Input: gpio-keys - use input_report_key() Use the input_report_key() helper instead of open-coding the same operation. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/185f3320e39000159d4bd843fd3119b94c30d607.1684854795.git.geert+renesas@glider.be Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/gpio_keys.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index c42f86ad0766..c928829a8b0c 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -456,7 +456,7 @@ static enum hrtimer_restart gpio_keys_irq_timer(struct hrtimer *t) struct input_dev *input = bdata->input; if (bdata->key_pressed) { - input_event(input, EV_KEY, *bdata->code, 0); + input_report_key(input, *bdata->code, 0); input_sync(input); bdata->key_pressed = false; } @@ -478,11 +478,11 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) if (bdata->button->wakeup) pm_wakeup_event(bdata->input->dev.parent, 0); - input_event(input, EV_KEY, *bdata->code, 1); + input_report_key(input, *bdata->code, 1); input_sync(input); if (!bdata->release_delay) { - input_event(input, EV_KEY, *bdata->code, 0); + input_report_key(input, *bdata->code, 0); input_sync(input); goto out; } -- cgit v1.2.3 From b00315628095075da4af8d6d519d85d95117de09 Mon Sep 17 00:00:00 2001 From: Dana Elfassy Date: Tue, 23 May 2023 14:49:42 -0700 Subject: Input: tests - add test to cover all input_grab_device() function Currently input_grab_device() isn't covered by any tests Thus, adding a test to cover the cases: 1. The device is grabbed successfully 2. Trying to grab a device that is already grabbed by another input handle Signed-off-by: Dana Elfassy Tested-by: Javier Martinez Canillas Reviewed-by: Javier Martinez Canillas Reviewed-by: Dmitry Torokhov Link: https://lore.kernel.org/r/20230522215514.722564-1-dangel101@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/tests/input_test.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'drivers/input') diff --git a/drivers/input/tests/input_test.c b/drivers/input/tests/input_test.c index 0540225f0288..2fa5b725ae0a 100644 --- a/drivers/input/tests/input_test.c +++ b/drivers/input/tests/input_test.c @@ -130,10 +130,42 @@ static void input_test_match_device_id(struct kunit *test) KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id)); } +static void input_test_grab(struct kunit *test) +{ + struct input_dev *input_dev = test->priv; + struct input_handle test_handle; + struct input_handler handler; + struct input_handle handle; + struct input_device_id id; + int res; + + handler.name = "handler"; + handler.id_table = &id; + + handle.dev = input_get_device(input_dev); + handle.name = dev_name(&input_dev->dev); + handle.handler = &handler; + res = input_grab_device(&handle); + KUNIT_ASSERT_TRUE(test, res == 0); + + test_handle.dev = input_get_device(input_dev); + test_handle.name = dev_name(&input_dev->dev); + test_handle.handler = &handler; + res = input_grab_device(&test_handle); + KUNIT_ASSERT_EQ(test, res, -EBUSY); + + input_release_device(&handle); + input_put_device(input_dev); + res = input_grab_device(&test_handle); + KUNIT_ASSERT_TRUE(test, res == 0); + input_put_device(input_dev); +} + static struct kunit_case input_tests[] = { KUNIT_CASE(input_test_polling), KUNIT_CASE(input_test_timestamp), KUNIT_CASE(input_test_match_device_id), + KUNIT_CASE(input_test_grab), { /* sentinel */ } }; -- cgit v1.2.3 From ab892b7fd44a68feead30e2f53ba31818ca84749 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 6 Jun 2023 10:27:24 -0700 Subject: Input: tps65219-pwrbutton - convert to .remove_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning). To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new() which already returns void. Eventually after all drivers are converted, .remove_new() is renamed to .remove(). Before this driver might have returned an error. In this case emit a warning that tells more about the problem than the generic warning by the core, and instead of making the remove callback return zero unconditionally, convert to .remove_new() which is equivalent. Signed-off-by: Uwe Kleine-König Reviewed-by: Markus Schneider-Pargmann Link: https://lore.kernel.org/r/20230605161458.117361-1-u.kleine-koenig@pengutronix.de Signed-off-by: Dmitry Torokhov --- drivers/input/misc/tps65219-pwrbutton.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/misc/tps65219-pwrbutton.c b/drivers/input/misc/tps65219-pwrbutton.c index 245134bdb59e..b2d9e5d2bcfd 100644 --- a/drivers/input/misc/tps65219-pwrbutton.c +++ b/drivers/input/misc/tps65219-pwrbutton.c @@ -117,14 +117,17 @@ static int tps65219_pb_probe(struct platform_device *pdev) return 0; } -static int tps65219_pb_remove(struct platform_device *pdev) +static void tps65219_pb_remove(struct platform_device *pdev) { struct tps65219 *tps = dev_get_drvdata(pdev->dev.parent); + int ret; /* Disable interrupt for the pushbutton */ - return regmap_update_bits(tps->regmap, TPS65219_REG_MASK_CONFIG, - TPS65219_REG_MASK_INT_FOR_PB_MASK, - TPS65219_REG_MASK_INT_FOR_PB_MASK); + ret = regmap_update_bits(tps->regmap, TPS65219_REG_MASK_CONFIG, + TPS65219_REG_MASK_INT_FOR_PB_MASK, + TPS65219_REG_MASK_INT_FOR_PB_MASK); + if (ret) + dev_warn(&pdev->dev, "Failed to disable irq (%pe)\n", ERR_PTR(ret)); } static const struct platform_device_id tps65219_pwrbtn_id_table[] = { @@ -135,7 +138,7 @@ MODULE_DEVICE_TABLE(platform, tps65219_pwrbtn_id_table); static struct platform_driver tps65219_pb_driver = { .probe = tps65219_pb_probe, - .remove = tps65219_pb_remove, + .remove_new = tps65219_pb_remove, .driver = { .name = "tps65219_pwrbutton", }, -- cgit v1.2.3 From d9f12a3bbb6d1afe872425a8fa2612945975cfb8 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 6 Jun 2023 10:42:36 -0700 Subject: Input: tps65219-pwrbutton - use regmap_set_bits() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit regmap_set_bits() is equivalent to regmap_update_bits() if mask == val. The probe function uses regmap_clear_bits() to enable irqs, so symmetrically make use of regmap_set_bits() to disable them. There is no semantic difference. Signed-off-by: Uwe Kleine-König Reviewed-by: Markus Schneider-Pargmann Link: https://lore.kernel.org/r/20230605161458.117361-2-u.kleine-koenig@pengutronix.de Signed-off-by: Dmitry Torokhov --- drivers/input/misc/tps65219-pwrbutton.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/misc/tps65219-pwrbutton.c b/drivers/input/misc/tps65219-pwrbutton.c index b2d9e5d2bcfd..eeb9f2334ab4 100644 --- a/drivers/input/misc/tps65219-pwrbutton.c +++ b/drivers/input/misc/tps65219-pwrbutton.c @@ -123,9 +123,8 @@ static void tps65219_pb_remove(struct platform_device *pdev) int ret; /* Disable interrupt for the pushbutton */ - ret = regmap_update_bits(tps->regmap, TPS65219_REG_MASK_CONFIG, - TPS65219_REG_MASK_INT_FOR_PB_MASK, - TPS65219_REG_MASK_INT_FOR_PB_MASK); + ret = regmap_set_bits(tps->regmap, TPS65219_REG_MASK_CONFIG, + TPS65219_REG_MASK_INT_FOR_PB_MASK); if (ret) dev_warn(&pdev->dev, "Failed to disable irq (%pe)\n", ERR_PTR(ret)); } -- cgit v1.2.3 From f11f1a92c17385ff4d6e2bc8002d59aed70b98c4 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 6 Jun 2023 11:16:25 -0700 Subject: Input: gameport - provide default trigger() and read() Instead of constantly checking pointer(s) for non-NULL-ness provide default implementations of trigger() and read() and instantiate them during pore registration if driver-specific versions were not provided. Link: https://lore.kernel.org/r/ZGvoqP5PAAsJuky4@google.com Signed-off-by: Dmitry Torokhov --- drivers/input/gameport/gameport.c | 18 ++++++++++++++++-- include/linux/gameport.h | 11 ++--------- 2 files changed, 18 insertions(+), 11 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index db58a01b23d3..a1443320b419 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -21,8 +22,6 @@ #include #include -/*#include */ - MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Generic gameport layer"); MODULE_LICENSE("GPL"); @@ -518,6 +517,16 @@ void gameport_set_phys(struct gameport *gameport, const char *fmt, ...) } EXPORT_SYMBOL(gameport_set_phys); +static void gameport_default_trigger(struct gameport *gameport) +{ + outb(0xff, gameport->io); +} + +static unsigned char gameport_default_read(struct gameport *gameport) +{ + return inb(gameport->io); +} + /* * Prepare gameport port for registration. */ @@ -536,6 +545,11 @@ static void gameport_init_port(struct gameport *gameport) if (gameport->parent) gameport->dev.parent = &gameport->parent->dev; + if (!gameport->trigger) + gameport->trigger = gameport_default_trigger; + if (!gameport->read) + gameport->read = gameport_default_read; + INIT_LIST_HEAD(&gameport->node); spin_lock_init(&gameport->timer_lock); timer_setup(&gameport->poll_timer, gameport_run_poll_handler, 0); diff --git a/include/linux/gameport.h b/include/linux/gameport.h index 8c2f00018e89..0a221e768ea4 100644 --- a/include/linux/gameport.h +++ b/include/linux/gameport.h @@ -5,7 +5,6 @@ #ifndef _GAMEPORT_H #define _GAMEPORT_H -#include #include #include #include @@ -165,18 +164,12 @@ void gameport_unregister_driver(struct gameport_driver *drv); static inline void gameport_trigger(struct gameport *gameport) { - if (gameport->trigger) - gameport->trigger(gameport); - else - outb(0xff, gameport->io); + gameport->trigger(gameport); } static inline unsigned char gameport_read(struct gameport *gameport) { - if (gameport->read) - return gameport->read(gameport); - else - return inb(gameport->io); + return gameport->read(gameport); } static inline int gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons) -- cgit v1.2.3 From 8c9cce9cb81b5fdc6e66bf3f129727b89e8daab7 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Tue, 6 Jun 2023 12:05:32 -0700 Subject: Input: pm8941-powerkey - fix debounce on gen2+ PMICs Since PM8998/PM660, the power key debounce register was redefined to support shorter debounce times. On PM8941 the shortest debounce time (represented by register value 0) was 15625us, on PM8998 the shortest debounce time is 62us, with the default being 2ms. Adjust the bit shift to correctly program debounce on PM8998 and newer. Fixes: 68c581d5e7d8 ("Input: add Qualcomm PM8941 power key driver") Signed-off-by: Caleb Connolly Link: https://lore.kernel.org/r/20230529-pm8941-pwrkey-debounce-v1-2-c043a6d5c814@linaro.org Signed-off-by: Dmitry Torokhov --- drivers/input/misc/pm8941-pwrkey.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/misc/pm8941-pwrkey.c b/drivers/input/misc/pm8941-pwrkey.c index b6a27ebae977..74d77d8aaeff 100644 --- a/drivers/input/misc/pm8941-pwrkey.c +++ b/drivers/input/misc/pm8941-pwrkey.c @@ -50,7 +50,10 @@ #define PON_RESIN_PULL_UP BIT(0) #define PON_DBC_CTL 0x71 -#define PON_DBC_DELAY_MASK 0x7 +#define PON_DBC_DELAY_MASK_GEN1 0x7 +#define PON_DBC_DELAY_MASK_GEN2 0xf +#define PON_DBC_SHIFT_GEN1 6 +#define PON_DBC_SHIFT_GEN2 14 struct pm8941_data { unsigned int pull_up_bit; @@ -247,7 +250,7 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev) struct device *parent; struct device_node *regmap_node; const __be32 *addr; - u32 req_delay; + u32 req_delay, mask, delay_shift; int error; if (of_property_read_u32(pdev->dev.of_node, "debounce", &req_delay)) @@ -336,12 +339,20 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev) pwrkey->input->phys = pwrkey->data->phys; if (pwrkey->data->supports_debounce_config) { - req_delay = (req_delay << 6) / USEC_PER_SEC; + if (pwrkey->subtype >= PON_SUBTYPE_GEN2_PRIMARY) { + mask = PON_DBC_DELAY_MASK_GEN2; + delay_shift = PON_DBC_SHIFT_GEN2; + } else { + mask = PON_DBC_DELAY_MASK_GEN1; + delay_shift = PON_DBC_SHIFT_GEN1; + } + + req_delay = (req_delay << delay_shift) / USEC_PER_SEC; req_delay = ilog2(req_delay); error = regmap_update_bits(pwrkey->regmap, pwrkey->baseaddr + PON_DBC_CTL, - PON_DBC_DELAY_MASK, + mask, req_delay); if (error) { dev_err(&pdev->dev, "failed to set debounce: %d\n", -- cgit v1.2.3