drivers/irqchip/irq-dw-apb-ictl.c
Source file repositories/reference/linux-study-clean/drivers/irqchip/irq-dw-apb-ictl.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/irqchip/irq-dw-apb-ictl.c- Extension
.c- Size
- 5906 bytes
- Lines
- 218
- Domain
- Driver Families
- Bucket
- drivers/irqchip
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/io.hlinux/irq.hlinux/irqchip.hlinux/irqchip/chained_irq.hlinux/of_address.hlinux/of_irq.hlinux/interrupt.h
Detected Declarations
function dw_apb_ictl_handle_irqfunction dw_apb_ictl_handle_irq_cascadedfunction dw_apb_ictl_irq_domain_allocfunction dw_apb_ictl_resumefunction dw_apb_ictl_init
Annotated Snippet
while (stat) {
u32 hwirq = ffs(stat) - 1;
generic_handle_domain_irq(d, hwirq);
stat &= ~BIT(hwirq);
}
}
}
static void dw_apb_ictl_handle_irq_cascaded(struct irq_desc *desc)
{
struct irq_domain *d = irq_desc_get_handler_data(desc);
struct irq_chip *chip = irq_desc_get_chip(desc);
int n;
chained_irq_enter(chip, desc);
for (n = 0; n < d->revmap_size; n += 32) {
struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, n);
u32 stat = readl_relaxed(gc->reg_base + APB_INT_FINALSTATUS_L);
while (stat) {
u32 hwirq = ffs(stat) - 1;
generic_handle_domain_irq(d, gc->irq_base + hwirq);
stat &= ~BIT(hwirq);
}
}
chained_irq_exit(chip, desc);
}
static int dw_apb_ictl_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
unsigned int nr_irqs, void *arg)
{
int i, ret;
irq_hw_number_t hwirq;
unsigned int type = IRQ_TYPE_NONE;
struct irq_fwspec *fwspec = arg;
ret = irq_domain_translate_onecell(domain, fwspec, &hwirq, &type);
if (ret)
return ret;
for (i = 0; i < nr_irqs; i++)
irq_map_generic_chip(domain, virq + i, hwirq + i);
return 0;
}
static const struct irq_domain_ops dw_apb_ictl_irq_domain_ops = {
.translate = irq_domain_translate_onecell,
.alloc = dw_apb_ictl_irq_domain_alloc,
.free = irq_domain_free_irqs_top,
};
#ifdef CONFIG_PM
static void dw_apb_ictl_resume(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct irq_chip_type *ct = irq_data_get_chip_type(d);
guard(raw_spinlock)(&gc->lock);
writel_relaxed(~0, gc->reg_base + ct->regs.enable);
writel_relaxed(*ct->mask_cache, gc->reg_base + ct->regs.mask);
}
#else
#define dw_apb_ictl_resume NULL
#endif /* CONFIG_PM */
static int __init dw_apb_ictl_init(struct device_node *np,
struct device_node *parent)
{
const struct irq_domain_ops *domain_ops;
unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
struct resource r;
struct irq_domain *domain;
struct irq_chip_generic *gc;
void __iomem *iobase;
int ret, nrirqs, parent_irq, i;
u32 reg;
if (!parent) {
/* Used as the primary interrupt controller */
parent_irq = 0;
domain_ops = &dw_apb_ictl_irq_domain_ops;
} else {
/* Map the parent interrupt for the chained handler */
parent_irq = irq_of_parse_and_map(np, 0);
if (parent_irq <= 0) {
Annotation
- Immediate include surface: `linux/io.h`, `linux/irq.h`, `linux/irqchip.h`, `linux/irqchip/chained_irq.h`, `linux/of_address.h`, `linux/of_irq.h`, `linux/interrupt.h`.
- Detected declarations: `function dw_apb_ictl_handle_irq`, `function dw_apb_ictl_handle_irq_cascaded`, `function dw_apb_ictl_irq_domain_alloc`, `function dw_apb_ictl_resume`, `function dw_apb_ictl_init`.
- Atlas domain: Driver Families / drivers/irqchip.
- Implementation status: source implementation candidate.
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.