From nobody Sun Feb 8 00:49:32 2026 Received: from mail-ed1-f66.google.com (mail-ed1-f66.google.com [209.85.208.66]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BE4C02C21C5 for ; Wed, 7 Jan 2026 09:31:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.66 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767778319; cv=none; b=JABYzSI9OHjqnciO5Zy7JLRl43n9YQUGAtfqfulis+SzEt0CPYN4ItDCnn4qI5EVL2kLariolXtCPET2kn/+Vaobun8tL8d6WB6RA61Ht/kAMM08dRsIE15+xpw5XczsI/7YxJAmXJ8DtzlfswKIokR1DWXvvTVJcB/SXwPrhSs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767778319; c=relaxed/simple; bh=SL4jNbeZEI1+nkTGrXJvZLEhXFUFJa7CeOBZacq7IWM=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type; b=kWImXRbuBiMChAYZZVtk3C7WmO7PPa0c/IU5ap/cqmzuX1BdOGSuv5qtLAzvPshKvg8u0NgQyJN6591B32SUvptQxeje97a+riRvtXQMMlQM/V1K6W7odmby6Ici7NEK0msAtPlgOGlD7wU2GWsNnHp5r89m5OUd/13hvyS0pns= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=HoUaIJOe; arc=none smtp.client-ip=209.85.208.66 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="HoUaIJOe" Received: by mail-ed1-f66.google.com with SMTP id 4fb4d7f45d1cf-6505cac9879so3040944a12.1 for ; Wed, 07 Jan 2026 01:31:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1767778316; x=1768383116; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=+V9JM8ZWElgqZZrdiMgxMNgv8OJd9DEJ1L+S/izWH/0=; b=HoUaIJOebui5XQ3NeE2ViuRfstEVpNelcdJ7UXuhdvnA5juPCbscOk7J5JANhuISsf XT3/2j6hD5eVQx413yi2SXJKI0LcjxXzVbil28/W3wiP+eFECjOoZ9+2R+OkhGNcYozF 0PB+KkuIw8esiTwKbi7jrjOcxPJRnFTBz3DZkVWc9vC68P8RLmAi1qkOhGxnvgd6YN9V RLfoPjdfRAx697fASXAKONq+1T1c+Mp9yR6m2naJxJqjclQNQIHfaYumCE8lzClZ0aCf 9OmYsdkxVUc5My9vO+v4EPtEzYB89twnXYwVjwZturu7GBIQJ+iWqokOXy0fUviSEYRb db+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767778316; x=1768383116; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=+V9JM8ZWElgqZZrdiMgxMNgv8OJd9DEJ1L+S/izWH/0=; b=ZNeNorPyfsC9ssGp4dwLdtyZVCgXmbmRMaWF0UyRqbK8oCB22Mt+LmQ0BQKbQgOTyS nq2CzQTLT9nK0tC/WcZqulM9gDZ/b3tHSrERdDjcUw3f/WX6Vf9YEHv9H9/wkwzZ2gC3 UV4e/EUXsb4Mr1u0ClGxm8dHzzv2IGnR7nuscpGX61S7hX64fAylGjzIDYfPOHce7Q/8 XG6JCxSE3QHr58x+P5zkidjAxM0yWaiO3s6OXbD5EQVb/b1Jyx/UV1GmJkabK8Mcm1TP uEoHRHFJ0fwmhRnhs3bA+/+v7m7m0S18X2Xp4vIudocay/yuRLHGd0Ut5nyJCJ6D8Y7d azfA== X-Forwarded-Encrypted: i=1; AJvYcCXlukmkJrIuGQQD2/LFV6dKc70K6b3Ykwz17i+eeEn+bmDsY06ZyuCytniLIq19bQmaq+DhrnovSXURQtE=@vger.kernel.org X-Gm-Message-State: AOJu0YzmA31cwjLyt+7aD5rbWHWOHu0J4K4b7Mzi6KkadlbaYliWrqzK LgxleYY/7wJeC8ILlkahJqUT7nSYUwHFmlb8K+UUcUHKVimvnPcso953 X-Gm-Gg: AY/fxX6SHR9OL3ljNr4aC+FwCL0kyTJmMYzgCqdKs7vDbvpwsOC9Nhv+H7KARdryIar IahMN/k3D1MTIyO1GgbQxyCQdGJpoW07FVcHqH7raOF8mOcPsNDRncHtyUyj/KC7VoLkywEXLeL zLkyMCKoMipPktmtIdmlnj2tGUU0osaVQ9W88o8BeOqf1zCngi/5Kw9TmxASu5N8v0ABOafQLxD 050/XVn51fndW/NJGXiyoP2klp96QFSqT5K1iLGpqEYpIi3wtq290AkOYBOQhHITYrZ428nY08c YRKmVaG84D68YexvfLxCd3x/4fu934m5cLeeaxDWAuRCjdOkzSkxmVtODG5yCRKIbFjhKNtX/Kl VqEMi9BXoCLlFAlwRjmeqkHBtdpr2htBEco9D4fRwOAPtHA3lXZwM+eXM4vTbOz6EwMJ48nkTK9 rRDDlOLiHjYA8Njka6oBy7+JoBUIzcausm8ZLaeMIfcsZ55Mbc8e8d/kHkxoigpyDqnSGohtpbG gC28l3pOCotKkpxSmiHt8c= X-Google-Smtp-Source: AGHT+IHN2t3DCkb0dmUHVIbl1BEhOZmHoBfyIGL+xoDRHJx3mpr43XpNECcaL/w1IjZijF2tGzr93g== X-Received: by 2002:a17:907:a49:b0:b7c:e4e9:b13f with SMTP id a640c23a62f3a-b8444f4e435mr201321066b.39.1767778311260; Wed, 07 Jan 2026 01:31:51 -0800 (PST) Received: from ernest.corp.toradex.com (248.201.173.83.static.wline.lns.sme.cust.swisscom.ch. [83.173.201.248]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b842a4d3831sm483455066b.44.2026.01.07.01.31.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Jan 2026 01:31:50 -0800 (PST) From: Ernest Van Hoecke To: Linus Walleij , Bartosz Golaszewski , Jonathan Corbet , Andy Shevchenko Cc: Ernest Van Hoecke , Francesco Dolcini , linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v1] Documentation: gpio: pca953x: clarify interrupt source detection Date: Wed, 7 Jan 2026 10:31:22 +0100 Message-ID: <20260107093125.4053468-1-ernestvanhoecke@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Ernest Van Hoecke There are multiple design tradeoffs and considerations in how the PCA953x driver detects the source(s) of an interrupt. This driver supports PCAL variants with input latching, a feature that is constrained by the fact that the interrupt status and input port registers cannot be read atomically. These limits and the design decisions deserve an in-depth explanation. Update the documentation to clarify these hardware limits and describe how the driver determines pending interrupts, and how it makes use of the PCAL input latching. Signed-off-by: Ernest Van Hoecke Reviewed-by: Andy Shevchenko Reviewed-by: Linus Walleij --- This documents behaviour implemented in a previously submitted patch and bases some of the descriptions on parts of that commit message: https://lore.kernel.org/all/20251217153050.142057-1-ernestvanhoecke@gmail.c= om/ --- Documentation/driver-api/gpio/pca953x.rst | 75 +++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/Documentation/driver-api/gpio/pca953x.rst b/Documentation/driv= er-api/gpio/pca953x.rst index 4bd7cf1120cb..57e6c613c478 100644 --- a/Documentation/driver-api/gpio/pca953x.rst +++ b/Documentation/driver-api/gpio/pca953x.rst @@ -383,6 +383,13 @@ disabled. Currently the driver enables the latch for each line with interrupt enabled. =20 +An interrupt status register records which pins triggered an interrupt. +However, the status register and the input port register must be read +separately; there is no atomic mechanism to read both simultaneously, so r= aces +are possible. Refer to the chapter `Interrupt source detection`_ to unders= tand +the implications of this and how the driver still makes use of the latching +feature. + 1. base offset 0x40, bank 2, bank offsets of 2^n - pcal6408 - pcal6416 @@ -511,6 +518,74 @@ bits drive strength =20 Currently not supported by the driver. =20 +Interrupt source detection +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D + +When triggered by the GPIO expander's interrupt, the driver determines whi= ch +IRQs are pending by reading the input port register. + +To be able to filter on specific interrupt events for all compatible devic= es, +the driver keeps track of the previous input state of the lines, and emits= an +IRQ only for the correct edge or level. This system works irrespective of = the +number of enabled interrupts. Events will not be missed even if they occur +between the GPIO expander's interrupt and the actual I2C read. Edges could= of +course be missed if the related signal level changes back to the value +previously saved by the driver before the I2C read. PCAL variants offer in= put +latching for that reason. + +PCAL input latching +------------------- + +The PCAL variants have an input latch and the driver enables this for all +interrupt-enabled lines. The interrupt is then only cleared when the input= port +is read out. These variants provide an interrupt status register that reco= rds +which pins triggered an interrupt, but the status and input registers cann= ot be +read atomically. If another interrupt occurs on a different line after the +status register has been read but before the input port register is sample= d, +that event will not be reflected in the earlier status snapshot, so relying +solely on the interrupt status register is insufficient. + +Thus, the PCAL variants also have to use the existing level-change logic. + +For short pulses, the first edge is captured when the input register is re= ad, +but if the signal returns to its previous level before this read, the seco= nd +edge is not observed. As a result, successive pulses can produce identical +input values at read time and no level change is detected, causing interru= pts +to be missed. Below timing diagram shows this situation where the top sign= al is +the input pin level and the bottom signal indicates the latched value:: + + =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=90 =E2=94=8C=E2= =94=80=E2=94=80*=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=90 =E2=94=8C=E2=94=80=E2=94=80*=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=90 =E2=94=8C=E2= =94=80=E2=94=80*=E2=94=80=E2=94=80=E2=94=80 + =E2=94=82 =E2=94=82 . =E2=94=82 =E2=94=82 .= =E2=94=82 =E2=94=82 . + =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2= =94=82 =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82 + =E2=94=94=E2=94=80=E2=94=80*=E2=94=80=E2=94=80=E2=94=98 =E2=94=82 = =E2=94=94=E2=94=80=E2=94=80*=E2=94=80=E2=94=80=E2=94=98 =E2= =94=82 =E2=94=94=E2=94=80=E2=94=80*=E2=94=80=E2=94=80=E2=94= =98 =E2=94=82 + Input =E2=94=82 =E2=94=82 =E2=94=82 =E2=94=82= =E2=94=82 =E2=94=82 + =E2=96=BC =E2=94=82 =E2=96=BC =E2=94=82= =E2=96=BC =E2=94=82 + IRQ =E2=94=82 IRQ =E2=94=82 = IRQ =E2=94=82 + . . . + =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=90 .=E2=94=8C= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=90 .=E2=94= =8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=90 .=E2=94=8C=E2=94=80=E2=94=80 + =E2=94=82 =E2=94=82 =E2=94=82 =E2=94= =82 =E2=94=82 =E2=94=82 + =E2=94=82 =E2=94=82 =E2=94=82 =E2=94= =82 =E2=94=82 =E2=94=82 + =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80*=E2=94=98 =E2=94=94=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80*=E2=94=98 =E2= =94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80*=E2=94=98 + Latched =E2=94=82 =E2=94=82 = =E2=94=82 + =E2=96=BC =E2=96=BC = =E2=96=BC + READ 0 READ 0 READ 0 + NO CHANGE NO CHANGE + +To deal with this, events indicated by the interrupt status register are m= erged +with events detected through the existing level-change logic. As a result: + +- short pulses, whose second edges are invisible, are detected via the + interrupt status register, and +- interrupts that occur between the status and input reads are still + caught by the generic level-change logic. + +Note that this is still best-effort: the status and input registers are re= ad +separately, and short pulses on other lines may occur in between those rea= ds. +Such pulses can still be latched as an interrupt without leaving an observ= able +level change at read time, and may not be attributable to a specific edge.= This +does not reduce detection compared to the generic path, but reflects inher= ent +atomicity limitations. + Datasheets =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 --=20 2.43.0