Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Documentation: gpio: pca953x: clarify interrupt source detection

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 <ernest.vanhoecke@toradex.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20260107093125.4053468-1-ernestvanhoecke@gmail.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>

authored by

Ernest Van Hoecke and committed by
Bartosz Golaszewski
8ba37987 da64eb51

+75
+75
Documentation/driver-api/gpio/pca953x.rst
··· 389 389 Currently the driver enables the latch for each line with interrupt 390 390 enabled. 391 391 392 + An interrupt status register records which pins triggered an interrupt. 393 + However, the status register and the input port register must be read 394 + separately; there is no atomic mechanism to read both simultaneously, so races 395 + are possible. Refer to the chapter `Interrupt source detection`_ to understand 396 + the implications of this and how the driver still makes use of the latching 397 + feature. 398 + 392 399 1. base offset 0x40, bank 2, bank offsets of 2^n 393 400 - pcal6408 394 401 - pcal6416 ··· 529 522 - pcal6534 530 523 531 524 Currently not supported by the driver. 525 + 526 + Interrupt source detection 527 + ========================== 528 + 529 + When triggered by the GPIO expander's interrupt, the driver determines which 530 + IRQs are pending by reading the input port register. 531 + 532 + To be able to filter on specific interrupt events for all compatible devices, 533 + the driver keeps track of the previous input state of the lines, and emits an 534 + IRQ only for the correct edge or level. This system works irrespective of the 535 + number of enabled interrupts. Events will not be missed even if they occur 536 + between the GPIO expander's interrupt and the actual I2C read. Edges could of 537 + course be missed if the related signal level changes back to the value 538 + previously saved by the driver before the I2C read. PCAL variants offer input 539 + latching for that reason. 540 + 541 + PCAL input latching 542 + ------------------- 543 + 544 + The PCAL variants have an input latch and the driver enables this for all 545 + interrupt-enabled lines. The interrupt is then only cleared when the input port 546 + is read out. These variants provide an interrupt status register that records 547 + which pins triggered an interrupt, but the status and input registers cannot be 548 + read atomically. If another interrupt occurs on a different line after the 549 + status register has been read but before the input port register is sampled, 550 + that event will not be reflected in the earlier status snapshot, so relying 551 + solely on the interrupt status register is insufficient. 552 + 553 + Thus, the PCAL variants also have to use the existing level-change logic. 554 + 555 + For short pulses, the first edge is captured when the input register is read, 556 + but if the signal returns to its previous level before this read, the second 557 + edge is not observed. As a result, successive pulses can produce identical 558 + input values at read time and no level change is detected, causing interrupts 559 + to be missed. Below timing diagram shows this situation where the top signal is 560 + the input pin level and the bottom signal indicates the latched value:: 561 + 562 + ─────┐ ┌──*───────────────┐ ┌──*─────────────────┐ ┌──*─── 563 + │ │ . │ │ . │ │ . 564 + │ │ │ │ │ │ │ │ │ 565 + └──*──┘ │ └──*──┘ │ └──*──┘ │ 566 + Input │ │ │ │ │ │ 567 + ▼ │ ▼ │ ▼ │ 568 + IRQ │ IRQ │ IRQ │ 569 + . . . 570 + ─────┐ .┌──────────────┐ .┌────────────────┐ .┌── 571 + │ │ │ │ │ │ 572 + │ │ │ │ │ │ 573 + └────────*┘ └────────*┘ └────────*┘ 574 + Latched │ │ │ 575 + ▼ ▼ ▼ 576 + READ 0 READ 0 READ 0 577 + NO CHANGE NO CHANGE 578 + 579 + To deal with this, events indicated by the interrupt status register are merged 580 + with events detected through the existing level-change logic. As a result: 581 + 582 + - short pulses, whose second edges are invisible, are detected via the 583 + interrupt status register, and 584 + - interrupts that occur between the status and input reads are still 585 + caught by the generic level-change logic. 586 + 587 + Note that this is still best-effort: the status and input registers are read 588 + separately, and short pulses on other lines may occur in between those reads. 589 + Such pulses can still be latched as an interrupt without leaving an observable 590 + level change at read time, and may not be attributable to a specific edge. This 591 + does not reduce detection compared to the generic path, but reflects inherent 592 + atomicity limitations. 532 593 533 594 Datasheets 534 595 ==========