[PATCH 3/3] Input: cyttsp5 - only launch the application when in bootloader mode
flat view
COOLING6d
From: Marc-Olivier Champagne <hidden>
Date: 2026-10-02 18:42:19
Also in:
lkml, stable
Subsystem:
cyttsp touchscreen driver, input (keyboard, mouse, joystick, touchscreen) drivers, the rest · Maintainers:
Linus Walleij, Dmitry Torokhov, Linus Torvalds
The driver unconditionally sends the bootloader LAUNCH_APP command at startup, assuming the device always comes out of a reset in bootloader mode. This is not true in general: reset-gpios is optional, so the device may already be running the application when the driver probes (for instance after a driver reload or a warm reboot without a power cycle). The running application does not answer the bootloader command, so the command times out and probe fails: cyttsp5 1-0024: HID output cmd execution timed out cyttsp5 1-0024: Error on launch app r=-110 cyttsp5 1-0024: Fail initial startup r=-110 The mode the device is running in can be told from the report ID carried by its HID descriptor: 0xFF for the bootloader and 0xF7 for the application. Add cyttsp5_get_mode() to read the descriptor and decode that ID, and only send LAUNCH_APP when the bootloader is running. The HID descriptor is then read again only after the application has been launched, as it describes the running mode, and startup now fails if the application is not running at that point instead of going on with the bootloader descriptor. The same problem was previously addressed as part of a larger series that did not get merged: https://lore.kernel.org/all/20250110-nekocwd-upstreaming-cyttsp5-v3-0-b33659c8effc@gmail.com/ (local) Fixes: 5b0c03e24a06 ("Input: Add driver for Cypress Generation 5 touchscreen") Cc: stable@vger.kernel.org Suggested-by: Hugo Villeneuve <hvilleneuve@dimonoff.com> Assisted-by: Copilot:claude-fable-5.1 Signed-off-by: Marc-Olivier Champagne <redacted> --- drivers/input/touchscreen/cyttsp5.c | 76 ++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 11 deletions(-)
diff --git a/drivers/input/touchscreen/cyttsp5.c b/drivers/input/touchscreen/cyttsp5.c
index beeb7d5bcd2c..e88fcc11716e 100644
--- a/drivers/input/touchscreen/cyttsp5.c
+++ b/drivers/input/touchscreen/cyttsp5.c@@ -70,6 +70,10 @@ #define HID_BL_OUTPUT_REPORT_ID 0x40 #define HID_RESPONSE_REPORT_ID 0xF0 +/* Report ID found in the HID descriptor, identifies the running mode */ +#define HID_DESCRIPTOR_BOOTLOADER_REPORT_ID 0xFF +#define HID_DESCRIPTOR_APPLICATION_REPORT_ID 0xF7 + #define HID_OUTPUT_RESPONSE_REPORT_OFFSET 2 #define HID_OUTPUT_RESPONSE_CMD_OFFSET 4 #define HID_OUTPUT_RESPONSE_CMD_MASK GENMASK(6, 0)
@@ -807,24 +811,74 @@ static int cyttsp5_fill_all_touch(struct cyttsp5 *ts) return 0; } +/* + * Returns the report ID advertised by the HID descriptor, which tells + * whether the bootloader or the application is running, or a negative + * error code. + */ +static int cyttsp5_get_mode(struct cyttsp5 *ts) +{ + const char *mode_str; + int mode; + int error; + + error = cyttsp5_get_hid_descriptor(ts, &ts->hid_desc); + if (error < 0) + return error; + + mode = ts->hid_desc.packet_id; + + switch (mode) { + case HID_DESCRIPTOR_BOOTLOADER_REPORT_ID: + mode_str = "bootloader"; + break; + case HID_DESCRIPTOR_APPLICATION_REPORT_ID: + mode_str = "application"; + break; + default: + dev_err(ts->dev, "Unknown mode, report ID 0x%02x\n", mode); + return -ENODEV; + } + + dev_dbg(ts->dev, "Device is in %s mode\n", mode_str); + + return mode; +} + static int cyttsp5_startup(struct cyttsp5 *ts) { + int mode; int error; + mode = cyttsp5_get_mode(ts); + if (mode < 0) { + dev_err(ts->dev, "Error on getting mode r=%d\n", mode); + return mode; + } + /* - * Launch the application as the device starts in bootloader mode - * because of a power-on-reset + * The device starts in bootloader mode after a reset; the + * application then has to be launched explicitly and the HID + * descriptor read again, as it describes the running mode. Skip + * this step when the application is already running. */ - error = cyttsp5_hid_output_bl_launch_app(ts); - if (error < 0) { - dev_err(ts->dev, "Error on launch app r=%d\n", error); - return error; - } + if (mode == HID_DESCRIPTOR_BOOTLOADER_REPORT_ID) { + error = cyttsp5_hid_output_bl_launch_app(ts); + if (error < 0) { + dev_err(ts->dev, "Error on launch app r=%d\n", error); + return error; + } - error = cyttsp5_get_hid_descriptor(ts, &ts->hid_desc); - if (error < 0) { - dev_err(ts->dev, "Error on getting HID descriptor r=%d\n", error); - return error; + mode = cyttsp5_get_mode(ts); + if (mode < 0) { + dev_err(ts->dev, "Error on getting mode r=%d\n", mode); + return mode; + } + + if (mode != HID_DESCRIPTOR_APPLICATION_REPORT_ID) { + dev_err(ts->dev, "Application not running after launch\n"); + return -ENODEV; + } } error = cyttsp5_fill_all_touch(ts);
--
2.34.1