drivers/net/ipa/ipa_interrupt.c
Source file repositories/reference/linux-study-clean/drivers/net/ipa/ipa_interrupt.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ipa/ipa_interrupt.c- Extension
.c- Size
- 9018 bytes
- Lines
- 345
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/interrupt.hlinux/platform_device.hlinux/pm_runtime.hlinux/pm_wakeirq.hlinux/types.hipa.hipa_endpoint.hipa_interrupt.hipa_power.hipa_reg.hipa_uc.h
Detected Declarations
struct ipa_interruptfunction ipa_interrupt_suspend_clear_allfunction ipa_interrupt_processfunction ipa_isr_threadfunction ipa_interrupt_enabled_updatefunction ipa_interrupt_enablefunction ipa_interrupt_disablefunction ipa_interrupt_irq_disablefunction ipa_interrupt_irq_enablefunction ipa_interrupt_suspend_controlfunction ipa_interrupt_suspend_enablefunction ipa_interrupt_suspend_disablefunction ipa_interrupt_simulate_suspendfunction ipa_interrupt_configfunction ipa_interrupt_deconfigfunction ipa_interrupt_exit
Annotated Snippet
struct ipa_interrupt {
struct ipa *ipa;
u32 irq;
u32 enabled;
unsigned long *suspend_enabled;
};
/* Clear the suspend interrupt for all endpoints that signaled it */
static void ipa_interrupt_suspend_clear_all(struct ipa_interrupt *interrupt)
{
struct ipa *ipa = interrupt->ipa;
u32 unit_count;
u32 unit;
unit_count = DIV_ROUND_UP(ipa->endpoint_count, 32);
for (unit = 0; unit < unit_count; unit++) {
const struct reg *reg;
u32 val;
reg = ipa_reg(ipa, IRQ_SUSPEND_INFO);
val = ioread32(ipa->reg_virt + reg_n_offset(reg, unit));
/* SUSPEND interrupt status isn't cleared on IPA version 3.0 */
if (!val || ipa->version == IPA_VERSION_3_0)
continue;
reg = ipa_reg(ipa, IRQ_SUSPEND_CLR);
iowrite32(val, ipa->reg_virt + reg_n_offset(reg, unit));
}
}
/* Process a particular interrupt type that has been received */
static void ipa_interrupt_process(struct ipa_interrupt *interrupt, u32 irq_id)
{
struct ipa *ipa = interrupt->ipa;
const struct reg *reg;
u32 mask = BIT(irq_id);
u32 offset;
reg = ipa_reg(ipa, IPA_IRQ_CLR);
offset = reg_offset(reg);
switch (irq_id) {
case IPA_IRQ_UC_0:
case IPA_IRQ_UC_1:
/* For microcontroller interrupts, clear the interrupt right
* away, "to avoid clearing unhandled interrupts."
*/
iowrite32(mask, ipa->reg_virt + offset);
ipa_uc_interrupt_handler(ipa, irq_id);
break;
case IPA_IRQ_TX_SUSPEND:
/* Clearing the SUSPEND_TX interrupt also clears the
* register that tells us which suspended endpoint(s)
* caused the interrupt, so defer clearing until after
* the handler has been called.
*/
ipa_interrupt_suspend_clear_all(interrupt);
fallthrough;
default: /* Silently ignore (and clear) any other condition */
iowrite32(mask, ipa->reg_virt + offset);
break;
}
}
/* IPA IRQ handler is threaded */
static irqreturn_t ipa_isr_thread(int irq, void *dev_id)
{
struct ipa_interrupt *interrupt = dev_id;
struct ipa *ipa = interrupt->ipa;
u32 enabled = interrupt->enabled;
struct device *dev = ipa->dev;
const struct reg *reg;
u32 pending;
u32 offset;
u32 mask;
int ret;
ret = pm_runtime_get_sync(dev);
if (WARN_ON(ret < 0))
goto out_power_put;
/* The status register indicates which conditions are present,
* including conditions whose interrupt is not enabled. Handle
* only the enabled ones.
*/
reg = ipa_reg(ipa, IPA_IRQ_STTS);
offset = reg_offset(reg);
Annotation
- Immediate include surface: `linux/interrupt.h`, `linux/platform_device.h`, `linux/pm_runtime.h`, `linux/pm_wakeirq.h`, `linux/types.h`, `ipa.h`, `ipa_endpoint.h`, `ipa_interrupt.h`.
- Detected declarations: `struct ipa_interrupt`, `function ipa_interrupt_suspend_clear_all`, `function ipa_interrupt_process`, `function ipa_isr_thread`, `function ipa_interrupt_enabled_update`, `function ipa_interrupt_enable`, `function ipa_interrupt_disable`, `function ipa_interrupt_irq_disable`, `function ipa_interrupt_irq_enable`, `function ipa_interrupt_suspend_control`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.