Devicetree
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Alexandre Hamamdjian" <azkali.limited@gmail.com>
Cc: linux-input@vger.kernel.org, devicetree@vger.kernel.org,
	robh@kernel.org, conor+dt@kernel.org, dmitry.torokhov@gmail.com
Subject: Re: [PATCH 4/4] Input: edt-ft5x06 - poll while a contact is down to recover dropped releases
Date: Thu, 23 Jul 2026 11:39:58 +0000	[thread overview]
Message-ID: <20260723113959.5396E1F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260723-b4-ft5426-v1-4-d4b4e32be042@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] The polling worker can be erroneously re-armed during device suspend, leading to invalid I2C accesses while the device is powered off.
- [Medium] A single transient I2C read failure after an idle period immediately triggers a spurious controller reset.
- [Medium] The controller reset recovery logic breaks permanently after ~24.8 days of uptime on 32-bit systems due to jiffies wrap-around.
--

--- Patch [4]: [PATCH 4/4] Input: edt-ft5x06 - poll while a contact is down to recover dropped releases ---
commit 601140d3fc50fbfeaa9e78699c5e29c00098c932
Author: Alexandre Hamamdjian <azkali.limited@gmail.com>

Input: edt-ft5x06 - poll while a contact is down to recover dropped releases

This commit adds a polling mechanism to recover from dropped release events
on unreliable I2C buses. It tracks active contacts and polls the panel while
any are down, synthesizing releases if contacts disappear. It also adds a
bounded retry for transient bus errors and a controller reset mechanism if
reads fail for over a second.

> diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
> index ac61ac44fd649..794c0650f5cb3 100644
> --- a/drivers/input/touchscreen/edt-ft5x06.c
> +++ b/drivers/input/touchscreen/edt-ft5x06.c
[ ... ]
> @@ -321,26 +333,83 @@ static int edt_ft5x06_bulk_read(struct regmap *map, unsigned int start,
[ ... ]
> +static void edt_ft5x06_fetch_and_report(struct edt_ft5x06_ts_data *tsdata)
>  {
[ ... ]
> +	for (tries = 0; tries < 4; tries++) {
[ ... ]
> +	}
>  	if (error) {
>  		dev_err_ratelimited(dev, "Unable to fetch data, error: %d\n",
>  				    error);
> -		goto out;
> +		/*
> +		 * A run of failed reads with no success for over a second means
> +		 * the controller is wedged rather than just glitching; pulse the
> +		 * reset line to recover it and drop any held contacts, since the
> +		 * post-reset finger state is unknown.
> +		 */
> +		if (tsdata->reset_gpio &&
> +		    time_after(jiffies, tsdata->last_success + HZ) &&
> +		    time_after(jiffies, tsdata->last_reset + 2 * HZ)) {

[Severity: Medium]
Will a single transient I2C read failure after an idle period immediately
trigger a spurious controller reset?

If the device sits idle for > 1 second, tsdata->last_success becomes stale.
When a new touch arrives, if the very first I2C read fails due to a transient
bus error, the time_after(jiffies, tsdata->last_success + HZ) check evaluates
to true.

This bypasses the intended 1-second delay of continuous failures, and
immediately pulses the reset line, causing a 300ms stall and dropping the
initial touch.

[Severity: Medium]
Does the controller reset recovery logic break permanently after ~24.8 days of
uptime on 32-bit systems due to jiffies wrap-around?

If the system runs for more than 24.8 days (exceeding MAX_JIFFY_OFFSET)
without the touchscreen wedging, tsdata->last_reset remains at its
initialization value.

A subsequent I2C bus error triggering the recovery path would cause the
time_after(jiffies, tsdata->last_reset + 2 * HZ) check to evaluate to false
due to signed integer overflow, bypassing the reset entirely until jiffies
wraps around the rest of the 32-bit space.

> +			tsdata->last_reset = jiffies;
> +			gpiod_set_value_cansleep(tsdata->reset_gpio, 1);
[ ... ]
> +static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
> +{
> +	struct edt_ft5x06_ts_data *tsdata = dev_id;
> +
> +	guard(mutex)(&tsdata->io_lock);
> +	edt_ft5x06_fetch_and_report(tsdata);
> +	if (tsdata->down_mask)
> +		mod_delayed_work(system_wq, &tsdata->poll_work,
> +				 msecs_to_jiffies(EDT_POLL_INTERVAL_MS));
>  
> -out:
>  	return IRQ_HANDLED;
>  }
[ ... ]
> @@ -1383,6 +1521,9 @@ static int edt_ft5x06_ts_suspend(struct device *dev)
>  	struct gpio_desc *reset_gpio = tsdata->reset_gpio;
>  	int ret;
>  
> +	/* stop the poll worker so it cannot touch i2c after power-down */
> +	cancel_delayed_work_sync(&tsdata->poll_work);
> +

[Severity: High]
Can the polling worker be erroneously re-armed during device suspend?

In edt_ft5x06_ts_suspend(), cancel_delayed_work_sync() is called to stop
the poll worker, but the device's interrupt is not disabled until several
operations later (or never disabled in HIBERNATE mode).

If an interrupt occurs in this window, the ISR edt_ft5x06_ts_isr() runs,
observes a non-zero down_mask, and unconditionally calls mod_delayed_work().

This could cause the worker to execute after the suspend function has disabled
regulators and suspended the I2C adapter, potentially leading to I2C access
timeouts or hardware hangs.

>  	if (device_may_wakeup(dev))
>  		return 0;
>

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260723-b4-ft5426-v1-0-d4b4e32be042@gmail.com?part=4

      reply	other threads:[~2026-07-23 11:39 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-23 11:27 [PATCH 0/4] Input: edt-ft5x06: robustness fixes for a FocalTech FT5426 on a marginal bus Alexandre Hamamdjian via B4 Relay
2026-07-23 11:27 ` [PATCH 1/4] Input: edt-ft5x06 - ignore contacts with an out-of-range slot id Alexandre Hamamdjian via B4 Relay
2026-07-23 11:40   ` sashiko-bot
2026-07-23 11:27 ` [PATCH 2/4] dt-bindings: input: edt-ft5x06 - add no-regmap-bulk-read property Alexandre Hamamdjian via B4 Relay
2026-07-23 11:35   ` sashiko-bot
2026-07-23 11:27 ` [PATCH 3/4] Input: edt-ft5x06 - allow reading the touch frame one register at a time Alexandre Hamamdjian via B4 Relay
2026-07-23 11:39   ` sashiko-bot
2026-07-23 11:27 ` [PATCH 4/4] Input: edt-ft5x06 - poll while a contact is down to recover dropped releases Alexandre Hamamdjian via B4 Relay
2026-07-23 11:39   ` sashiko-bot [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260723113959.5396E1F00A3A@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=azkali.limited@gmail.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=linux-input@vger.kernel.org \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox