Level-Triggered Sensor Interrupts: Clear the Device Cause Before Re-Enabling the Line
A level-triggered interrupt can fire again immediately if the peripheral still asserts its interrupt output when the host unmasks the line. Acknowledging the interrupt controller does not necessarily clear the sensor’s cause. Determine the exact device acknowledgement operation, preserve the information it consumes, and complete that service before normal interrupt delivery resumes.
Applicability: the concrete sensor is Analog Devices ADXL345, Revision G, May 2022, with one dedicated interrupt connection. Linux IRQ terminology refers to v6.12. The proposed tests are not executed results. Shared electrical interrupt wiring, sensor threshold selection, and hardware timing limits require separate qualification.

1. Draw cause, output, and host masking separately
Use three timelines: the sensor’s pending condition, its physical interrupt pin, and the host controller’s masked/unmasked state. Add software entry and exit only after those signals are distinct. This prevents an “interrupt acknowledged” log message from ambiguously referring to three different operations.
The Linux v6.12 generic IRQ guide describes controller-level mask, acknowledge, and unmask operations for level handling. Those framework operations do not themselves know which sensor register or FIFO action removes a peripheral condition.
Verify active polarity and trigger mode from the actual sensor configuration and board wiring. A latched high output connected to a high-level IRQ is different from an edge-only pulse source. Do not change the host to edge triggering solely to conceal repeated delivery while leaving the device condition unresolved.
2. Build a source-specific acknowledgement table
The ADXL345 interrupt and INT_SOURCE sections distinguish two clearing mechanisms. Activity, tap, inactivity, and free-fall event bits clear when INT_SOURCE is read. DATA_READY, watermark, and overrun instead clear through data-register reads, with the required reads depending on the data condition and FIFO mode.
For example, reading INT_SOURCE can capture and clear a latched activity event, while a watermark remains asserted until FIFO occupancy falls below its configured threshold. A generic “read status to acknowledge” helper is therefore incomplete for a pin carrying both kinds of source.
Record every enabled source and its mapped output pin. Include whether status is destructive to read, whether data must be consumed, and what a still-active physical condition can do after acknowledgement. The ADXL345 routes selected sources to INT1 or INT2; multiple sources can contribute to one output.
Do not write an invented clear mask to a read-only source register. Likewise, a write-one-to-clear convention from another device cannot be transferred to this part. The acknowledgement table must come from the exact register map.
3. Preserve destructive status before dispatching work
Make one owner responsible for reading destructive status and distributing the resulting event snapshot. A diagnostic reader that independently polls INT_SOURCE can consume information before the real handler sees it. Logging should use the captured value rather than issue a second read for convenience.
In a hypothetical configuration with only activity routed to the dedicated interrupt pin, the handler reads INT_SOURCE once, checks the transport result, saves the activity indication, and then handles the saved event. A later read returning no activity does not prove the first interrupt was spurious; the first successful read may already have cleared it.
If the first read fails, the cause has not been reliably captured or acknowledged. Do not manufacture an empty status snapshot and resume as if service succeeded. Enter a bounded recovery or fault-reporting path whose masking behavior is explicitly defined for this dedicated connection.
4. Complete data-related service without an endless loop
For a watermark source, service enough complete entries to remove the condition according to the selected FIFO mode. Merely reading the source byte leaves the underlying queue state unchanged. New samples can arrive during service, so evaluate the condition after the intended drain operation rather than assuming the entry count is static.
Place a work or time budget around the service pass. If the source cannot be cleared within that budget, distinguish legitimate continuous production from a broken clear operation, wrong mode, bus failure, or an overloaded service path. Repeated immediate interrupts are evidence to classify, not an invitation to spin indefinitely.
A driver may need to reduce the source, schedule additional work, or enter recovery. The correct action depends on data-loss and latency requirements. Permanently masking the line without exposing the fault merely turns an interrupt storm into silent loss.
5. Re-enable using a race-aware policy
For a threaded dedicated-line design, IRQF_ONESHOT keeps delivery masked while the IRQ thread runs, as documented by the generic IRQ API. Perform any sleeping sensor transactions in the permitted context and complete the cause-service policy before the thread returns. This does not replace device acknowledgement.
Allow for an event arriving after the last status observation but before delivery resumes. With a correctly configured retained level, the new pending condition can assert the line and cause another service pass. Do not clear every bit blindly at the end, since that can erase information that was not included in the saved snapshot.
Event bits are often indications, not counters. Two physical events occurring before a destructive status read may collapse into one pending bit. Define whether the application needs event presence, exact event count, or retained data; the interrupt API cannot create information the sensor did not preserve.
6. Test persistent causes and newly arriving events
| Proposed fixture | Evidence to require |
|---|---|
| One latched activity event | One captured status snapshot, documented clear operation, and appropriate line deassertion. |
| Watermark remains above threshold | Source-byte read alone does not falsely count as complete service. |
| New event during handler completion | The next service pass retains the new condition under the documented latch model. |
| Status read fails | Visible bounded failure without a fabricated empty status. |
| Cause persists beyond service budget | Explicit recovery or loss policy rather than an unbounded interrupt loop. |
Capture the sensor output, relevant bus reads, and software service markers together where feasible. Compare the observed ordering with the cause table. A handler-count graph alone cannot distinguish a persistent source from many genuine events.
No sensor interrupt was generated or measured for this article. The deliverable is a per-source clear contract, a single-owner destructive-status policy, and a bounded cause/line/unmask test matrix. Acceptance requires explaining both why the old condition is gone and how a new condition remains observable.