drivers/irqchip/irq-bcm2712-mip.c
Source file repositories/reference/linux-study-clean/drivers/irqchip/irq-bcm2712-mip.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/irqchip/irq-bcm2712-mip.c- Extension
.c- Size
- 7251 bytes
- Lines
- 289
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/bitmap.hlinux/irqchip.hlinux/irqdomain.hlinux/msi.hlinux/of_address.hlinux/of_platform.hlinux/irqchip/irq-msi-lib.h
Detected Declarations
struct mip_privfunction mip_compose_msi_msgfunction mip_alloc_hwirqfunction mip_free_hwirqfunction mip_middle_domain_allocfunction mip_middle_domain_freefunction mip_init_domainsfunction mip_parse_dtfunction mip_msi_probe
Annotated Snippet
struct mip_priv {
spinlock_t lock;
void __iomem *base;
u64 msg_addr;
u32 msi_base;
u32 num_msis;
u32 msi_offset;
unsigned long *bitmap;
struct irq_domain *parent;
struct device *dev;
};
static void mip_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
{
struct mip_priv *mip = irq_data_get_irq_chip_data(d);
msg->address_hi = upper_32_bits(mip->msg_addr);
msg->address_lo = lower_32_bits(mip->msg_addr);
msg->data = d->hwirq;
}
static struct irq_chip mip_middle_irq_chip = {
.name = "MIP",
.irq_mask = irq_chip_mask_parent,
.irq_unmask = irq_chip_unmask_parent,
.irq_eoi = irq_chip_eoi_parent,
.irq_set_affinity = irq_chip_set_affinity_parent,
.irq_set_type = irq_chip_set_type_parent,
.irq_compose_msi_msg = mip_compose_msi_msg,
};
static int mip_alloc_hwirq(struct mip_priv *mip, unsigned int nr_irqs)
{
guard(spinlock)(&mip->lock);
return bitmap_find_free_region(mip->bitmap, mip->num_msis, ilog2(nr_irqs));
}
static void mip_free_hwirq(struct mip_priv *mip, unsigned int hwirq,
unsigned int nr_irqs)
{
guard(spinlock)(&mip->lock);
bitmap_release_region(mip->bitmap, hwirq, ilog2(nr_irqs));
}
static int mip_middle_domain_alloc(struct irq_domain *domain, unsigned int virq,
unsigned int nr_irqs, void *arg)
{
struct mip_priv *mip = domain->host_data;
struct irq_fwspec fwspec = {0};
unsigned int hwirq, i;
struct irq_data *irqd;
int irq, ret;
irq = mip_alloc_hwirq(mip, nr_irqs);
if (irq < 0)
return irq;
hwirq = irq + mip->msi_offset;
fwspec.fwnode = domain->parent->fwnode;
fwspec.param_count = 3;
fwspec.param[0] = 0;
fwspec.param[1] = hwirq + mip->msi_base;
fwspec.param[2] = IRQ_TYPE_EDGE_RISING;
ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &fwspec);
if (ret)
goto err_free_hwirq;
for (i = 0; i < nr_irqs; i++) {
irqd = irq_domain_get_irq_data(domain->parent, virq + i);
irqd->chip->irq_set_type(irqd, IRQ_TYPE_EDGE_RISING);
ret = irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
&mip_middle_irq_chip, mip);
if (ret)
goto err_free;
irqd = irq_get_irq_data(virq + i);
irqd_set_single_target(irqd);
irqd_set_affinity_on_activate(irqd);
}
return 0;
err_free:
irq_domain_free_irqs_parent(domain, virq, nr_irqs);
err_free_hwirq:
mip_free_hwirq(mip, irq, nr_irqs);
return ret;
Annotation
- Immediate include surface: `linux/bitmap.h`, `linux/irqchip.h`, `linux/irqdomain.h`, `linux/msi.h`, `linux/of_address.h`, `linux/of_platform.h`, `linux/irqchip/irq-msi-lib.h`.
- Detected declarations: `struct mip_priv`, `function mip_compose_msi_msg`, `function mip_alloc_hwirq`, `function mip_free_hwirq`, `function mip_middle_domain_alloc`, `function mip_middle_domain_free`, `function mip_init_domains`, `function mip_parse_dt`, `function mip_msi_probe`.
- Atlas domain: Driver Families / drivers/irqchip.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- 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.