public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Francesco Lavra <flavra@baylibre.com>
To: Martyn Welch <martyn.welch@collabora.com>,
	Linus Walleij <linus.walleij@linaro.org>,
	Hugo Villeneuve <hvilleneuve@dimonoff.com>,
	 Maria Garcia <mariagarcia7293@gmail.com>,
	Sascha Hauer <s.hauer@pengutronix.de>,
	Emanuele Ghidoli <emanuele.ghidoli@toradex.com>,
	Potin Lai <potin.lai.pt@gmail.com>,
	Mark Tomlinson <mark.tomlinson@alliedtelesis.co.nz>,
	Fabio Estevam <festevam@denx.de>,
	Ian Ray <ian.ray@gehealthcare.com>
Cc: Bartosz Golaszewski <brgl@bgdev.pl>,
	linux-gpio@vger.kernel.org,  linux-kernel@vger.kernel.org
Subject: Re: [PATCH] gpio: pca953x: enable latch only on edge-triggered inputs
Date: Thu, 09 Oct 2025 09:44:07 +0200	[thread overview]
Message-ID: <02a02848044c32e78cfc806a3b95c1cb0d93d7fc.camel@baylibre.com> (raw)
In-Reply-To: <c75a89f8-9eb7-4300-979e-e11159dc6888@collabora.com>

[-- Attachment #1: Type: text/plain, Size: 4720 bytes --]

On Thu, 2025-10-09 at 08:17 +0100, Martyn Welch wrote:
> On 09/10/2025 07:03, Linus Walleij wrote:
> > Hi Francesco,
> > 
> > thanks for your patch!
> > 
> > On Wed, Oct 8, 2025 at 12:43 PM Francesco Lavra <flavra@baylibre.com>
> > wrote:
> > 
> > 
> > > The latched input feature of the pca953x GPIO controller is useful
> > > when an input is configured to trigger interrupts on rising or
> > > falling edges, because it allows retrieving which edge type caused
> > > a given interrupt even if the pin state changes again before the
> > > interrupt handler has a chance to run. But for level-triggered
> > > interrupts, reading the latched input state can cause an active
> > > interrupt condition to be missed, e.g. if an active-low signal (for
> > > which an IRQ_TYPE_LEVEL_LOW interrupt has been configured) triggers
> > > an interrupt when switching to the inactive state, but then becomes
> > > active again before the interrupt handler has a chance to run: in
> > > this case, if the interrupt handler reads the latched input state,
> > > it will wrongly assume that the interrupt is not pending.
> > > Fix the above issue by enabling the latch only on edge-triggered
> > > inputs, instead of all interrupt-enabled inputs.
> > > 
> > > Signed-off-by: Francesco Lavra <flavra@baylibre.com>
> > > ---
> > >   drivers/gpio/gpio-pca953x.c | 7 +++++--
> > >   1 file changed, 5 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-
> > > pca953x.c
> > > index e80a96f39788..e87ef2c3ff82 100644
> > > --- a/drivers/gpio/gpio-pca953x.c
> > > +++ b/drivers/gpio/gpio-pca953x.c
> > > @@ -761,10 +761,13 @@ static void pca953x_irq_bus_sync_unlock(struct
> > > irq_data *d)
> > >          int level;
> > > 
> > >          if (chip->driver_data & PCA_PCAL) {
> > > +               DECLARE_BITMAP(latched_inputs, MAX_LINE);
> > >                  guard(mutex)(&chip->i2c_lock);
> > > 
> > > -               /* Enable latch on interrupt-enabled inputs */
> > > -               pca953x_write_regs(chip, PCAL953X_IN_LATCH, chip-
> > > >irq_mask);
> > > +               /* Enable latch on edge-triggered interrupt-enabled
> > > inputs */
> > > +               bitmap_or(latched_inputs, chip->irq_trig_fall, chip-
> > > >irq_trig_raise, gc->ngpio);
> > > +               bitmap_and(latched_inputs, latched_inputs, chip-
> > > >irq_mask, gc->ngpio);
> > > +               pca953x_write_regs(chip, PCAL953X_IN_LATCH,
> > > latched_inputs);
> > 
> > This driver is used by a *lot* of systems and people.
> > 
> > It is maybe the most used GPIO driver in the kernel.
> > 
> > So I added a lot of affected developers to the To: line of
> > the mail so we can get a wider review and testing.
> > 
> 
> I don't have access to the relevant hardware to test this anymore and 
> it's been a while since I thought much about edge vs. level triggered 
> interrupts. But if the state of the interrupt is unilaterally returning 
> to an inactive state, it sounds like that should be configured as an 
> edge triggered interrupt, not a level triggered one...

I will try to better describe the problematic scenario:
- a device has an IRQ line that becomes active when the device needs to be
serviced, and becomes inactive when the device has been serviced (e.g. by
reading a status register); this is the classic use case for level-
triggered interrupts
- the IRQ line of this device is connected to a pca953x input, and this
input is configured as a level-triggered interrupt
- the device IRQ line becomes active, this triggers an interrupt in the
pca953x, the pca953x interrupt handler is invoked, it reads the input
state, then calls the nested interrupt handler
- the nested interrupt handler services the device, which causes the IRQ
line to become inactive: this triggers a second interrupt in the pca953x
- before the pca953x interrupt handler is invoked for the second time, the
device IRQ line becomes active again
- the pca953x interrupt handler is invoked, it reads the input state, which
shows the line as inactive (because that is the state that triggered the
second interrupt), and as a result the nested interrupt handler is not
invoked, and the device will stay forever with the interrupt line asserted

With my proposed change, in the last step above the pca953x interrupt
handler will read the current input state instead of the state that caused
the second interrupt, and thus will correctly invoke the nested interrupt
handler for the second time.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

  reply	other threads:[~2025-10-09  7:44 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-08 10:43 [PATCH] gpio: pca953x: enable latch only on edge-triggered inputs Francesco Lavra
2025-10-09  6:03 ` Linus Walleij
2025-10-09  7:17   ` Martyn Welch
2025-10-09  7:44     ` Francesco Lavra [this message]
2025-10-09 10:24       ` Martyn Welch
2025-10-10  8:36         ` Ian Ray
2025-10-16 14:30 ` Bartosz Golaszewski

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=02a02848044c32e78cfc806a3b95c1cb0d93d7fc.camel@baylibre.com \
    --to=flavra@baylibre.com \
    --cc=brgl@bgdev.pl \
    --cc=emanuele.ghidoli@toradex.com \
    --cc=festevam@denx.de \
    --cc=hvilleneuve@dimonoff.com \
    --cc=ian.ray@gehealthcare.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mariagarcia7293@gmail.com \
    --cc=mark.tomlinson@alliedtelesis.co.nz \
    --cc=martyn.welch@collabora.com \
    --cc=potin.lai.pt@gmail.com \
    --cc=s.hauer@pengutronix.de \
    /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