Skip to content

drivers/touch/cst816: take the i2c lock around the hardware reset - #1896

Draft
Mearman wants to merge 1 commit into
coredevices:mainfrom
Mearman:fix/cst816-reset-under-i2c-lock
Draft

drivers/touch/cst816: take the i2c lock around the hardware reset#1896
Mearman wants to merge 1 commit into
coredevices:mainfrom
Mearman:fix/cst816-reset-under-i2c-lock

Conversation

@Mearman

@Mearman Mearman commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Draft — still validating on hardware.

The vaguest of the failures I saw while playing with touch a few weeks ago: very occasional glitched or dropped touch input, never reproducible on demand. Looking at the driver, there is a real unsynchronised window for it.

cst816_hw_reset toggles the chip's reset pin with no synchronisation against the bus: touch_sensor_set_enabled is reached synchronously from arbitrary tasks (subscribe/unsubscribe callbacks, the backlight and system-hold toggles) and calls the reset as its first statement, while the system task may be mid-transfer inside prv_read_data clocking the same chip. A chip hit by reset mid-byte stops ACKing and corrupts the in-flight transfer.

This takes s_i2c_lock inside cst816_hw_reset — the same per-transfer lock the read/write paths use. No caller holds it already (the only lock-takers are prv_read_data and prv_write_data, neither of which resets), so the acquisition cannot self-deadlock, and the bootmode/fw-update sequences keep their existing per-operation interleaving.

No unit test: the driver has no test target (it sits on real I2C, GPIO and EXTI) and the race is a cross-task timing window against hardware. Validated by call-site audit and a full firmware build.

cst816_hw_reset toggles the chip's reset pin with no synchronisation
against the bus: touch_sensor_set_enabled is reached synchronously from
arbitrary tasks (subscribe/unsubscribe callbacks, the backlight and
system-hold toggles) and calls the reset as its first statement, while
the system task may be mid-transfer inside prv_read_data clocking the
same chip. A chip hit by reset mid-byte stops ACKing and corrupts the
in-flight transfer.

Take s_i2c_lock inside cst816_hw_reset, the same per-transfer lock the
read/write paths use. No caller holds it already -- the only lock-takers
are prv_read_data and prv_write_data, neither of which resets -- so the
acquisition cannot self-deadlock, and the bootmode/fw-update sequences
keep their existing per-operation interleaving.

Not unit-testable: the driver has no test target (it sits on real I2C,
GPIO and EXTI), and the race is a cross-task timing window against
hardware. Validated by call-site audit and a full firmware build.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Joseph Mearman <joseph@mearman.co.uk>
@Mearman
Mearman force-pushed the fix/cst816-reset-under-i2c-lock branch from eea8d9c to a6fd810 Compare August 19, 2026 21:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant