drivers/irqchip/irq-bcm7120-l2.c
Source file repositories/reference/linux-study-clean/drivers/irqchip/irq-bcm7120-l2.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/irqchip/irq-bcm7120-l2.c- Extension
.c- Size
- 9374 bytes
- Lines
- 348
- 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.
- 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/init.hlinux/slab.hlinux/module.hlinux/kernel.hlinux/platform_device.hlinux/of.hlinux/of_irq.hlinux/of_address.hlinux/of_platform.hlinux/interrupt.hlinux/irq.hlinux/io.hlinux/irqdomain.hlinux/reboot.hlinux/bitops.hlinux/irqchip.hlinux/irqchip/chained_irq.h
Detected Declarations
struct bcm7120_l1_intc_datastruct bcm7120_l2_intc_datafunction bcm7120_l2_intc_irq_handlefunction scoped_guardfunction bcm7120_l2_intc_suspendfunction bcm7120_l2_intc_resumefunction bcm7120_l2_intc_init_onefunction bcm7120_l2_intc_iomap_7120function bcm7120_l2_intc_iomap_3380function bcm7120_l2_intc_probefunction bcm7120_l2_intc_probe_7120function bcm7120_l2_intc_probe_3380
Annotated Snippet
struct bcm7120_l1_intc_data {
struct bcm7120_l2_intc_data *b;
u32 irq_map_mask[MAX_WORDS];
};
struct bcm7120_l2_intc_data {
unsigned int n_words;
void __iomem *map_base[MAX_MAPPINGS];
void __iomem *pair_base[MAX_WORDS];
int en_offset[MAX_WORDS];
int stat_offset[MAX_WORDS];
struct irq_domain *domain;
bool can_wake;
u32 irq_fwd_mask[MAX_WORDS];
struct bcm7120_l1_intc_data *l1_data;
int num_parent_irqs;
const __be32 *map_mask_prop;
};
static void bcm7120_l2_intc_irq_handle(struct irq_desc *desc)
{
struct bcm7120_l1_intc_data *data = irq_desc_get_handler_data(desc);
struct bcm7120_l2_intc_data *b = data->b;
struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned int idx;
chained_irq_enter(chip, desc);
for (idx = 0; idx < b->n_words; idx++) {
int base = idx * IRQS_PER_WORD;
struct irq_chip_generic *gc;
unsigned long pending;
int hwirq;
gc = irq_get_domain_generic_chip(b->domain, base);
scoped_guard (raw_spinlock, &gc->lock) {
pending = irq_reg_readl(gc, b->stat_offset[idx]) & gc->mask_cache &
data->irq_map_mask[idx];
}
for_each_set_bit(hwirq, &pending, IRQS_PER_WORD)
generic_handle_domain_irq(b->domain, base + hwirq);
}
chained_irq_exit(chip, desc);
}
static void bcm7120_l2_intc_suspend(struct irq_chip_generic *gc)
{
struct bcm7120_l2_intc_data *b = gc->private;
struct irq_chip_type *ct = gc->chip_types;
guard(raw_spinlock)(&gc->lock);
if (b->can_wake)
irq_reg_writel(gc, gc->mask_cache | gc->wake_active, ct->regs.mask);
}
static void bcm7120_l2_intc_resume(struct irq_chip_generic *gc)
{
struct irq_chip_type *ct = gc->chip_types;
/* Restore the saved mask */
guard(raw_spinlock)(&gc->lock);
irq_reg_writel(gc, gc->mask_cache, ct->regs.mask);
}
static int bcm7120_l2_intc_init_one(struct device_node *dn,
struct bcm7120_l2_intc_data *data,
int irq, u32 *valid_mask)
{
struct bcm7120_l1_intc_data *l1_data = &data->l1_data[irq];
int parent_irq;
unsigned int idx;
parent_irq = irq_of_parse_and_map(dn, irq);
if (!parent_irq) {
pr_err("failed to map interrupt %d\n", irq);
return -EINVAL;
}
/* For multiple parent IRQs with multiple words, this looks like:
* <irq0_w0 irq0_w1 irq1_w0 irq1_w1 ...>
*
* We need to associate a given parent interrupt with its corresponding
* map_mask in order to mask the status register with it because we
* have the same handler being called for multiple parent interrupts.
*
* This is typically something needed on BCM7xxx (STB chips).
*/
for (idx = 0; idx < data->n_words; idx++) {
Annotation
- Immediate include surface: `linux/init.h`, `linux/slab.h`, `linux/module.h`, `linux/kernel.h`, `linux/platform_device.h`, `linux/of.h`, `linux/of_irq.h`, `linux/of_address.h`.
- Detected declarations: `struct bcm7120_l1_intc_data`, `struct bcm7120_l2_intc_data`, `function bcm7120_l2_intc_irq_handle`, `function scoped_guard`, `function bcm7120_l2_intc_suspend`, `function bcm7120_l2_intc_resume`, `function bcm7120_l2_intc_init_one`, `function bcm7120_l2_intc_iomap_7120`, `function bcm7120_l2_intc_iomap_3380`, `function bcm7120_l2_intc_probe`.
- 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.