drivers/irqchip/irq-crossbar.c
Source file repositories/reference/linux-study-clean/drivers/irqchip/irq-crossbar.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/irqchip/irq-crossbar.c- Extension
.c- Size
- 8447 bytes
- Lines
- 365
- 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.
- 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/err.hlinux/io.hlinux/irqchip.hlinux/irqdomain.hlinux/of_address.hlinux/of_irq.hlinux/slab.h
Detected Declarations
struct crossbar_devicefunction crossbar_writelfunction crossbar_writewfunction crossbar_writebfunction allocate_gic_irqfunction crossbar_domain_allocfunction crossbar_domain_freefunction crossbar_domain_translatefunction crossbar_of_initfunction irqcrossbar_init
Annotated Snippet
struct crossbar_device {
raw_spinlock_t lock;
uint int_max;
uint safe_map;
uint max_crossbar_sources;
uint *irq_map;
void __iomem *crossbar_base;
int *register_offsets;
void (*write)(int, int);
};
static struct crossbar_device *cb;
static void crossbar_writel(int irq_no, int cb_no)
{
writel(cb_no, cb->crossbar_base + cb->register_offsets[irq_no]);
}
static void crossbar_writew(int irq_no, int cb_no)
{
writew(cb_no, cb->crossbar_base + cb->register_offsets[irq_no]);
}
static void crossbar_writeb(int irq_no, int cb_no)
{
writeb(cb_no, cb->crossbar_base + cb->register_offsets[irq_no]);
}
static struct irq_chip crossbar_chip = {
.name = "CBAR",
.irq_eoi = irq_chip_eoi_parent,
.irq_mask = irq_chip_mask_parent,
.irq_unmask = irq_chip_unmask_parent,
.irq_retrigger = irq_chip_retrigger_hierarchy,
.irq_set_type = irq_chip_set_type_parent,
.flags = IRQCHIP_MASK_ON_SUSPEND |
IRQCHIP_SKIP_SET_WAKE,
#ifdef CONFIG_SMP
.irq_set_affinity = irq_chip_set_affinity_parent,
#endif
};
static int allocate_gic_irq(struct irq_domain *domain, unsigned virq,
irq_hw_number_t hwirq)
{
struct irq_fwspec fwspec;
int i;
int err;
if (!irq_domain_get_of_node(domain->parent))
return -EINVAL;
raw_spin_lock(&cb->lock);
for (i = cb->int_max - 1; i >= 0; i--) {
if (cb->irq_map[i] == IRQ_FREE) {
cb->irq_map[i] = hwirq;
break;
}
}
raw_spin_unlock(&cb->lock);
if (i < 0)
return -ENODEV;
fwspec.fwnode = domain->parent->fwnode;
fwspec.param_count = 3;
fwspec.param[0] = 0; /* SPI */
fwspec.param[1] = i;
fwspec.param[2] = IRQ_TYPE_LEVEL_HIGH;
err = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
if (err)
cb->irq_map[i] = IRQ_FREE;
else
cb->write(i, hwirq);
return err;
}
static int crossbar_domain_alloc(struct irq_domain *d, unsigned int virq,
unsigned int nr_irqs, void *data)
{
struct irq_fwspec *fwspec = data;
irq_hw_number_t hwirq;
int i;
if (fwspec->param_count != 3)
return -EINVAL; /* Not GIC compliant */
if (fwspec->param[0] != 0)
return -EINVAL; /* No PPI should point to this domain */
Annotation
- Immediate include surface: `linux/err.h`, `linux/io.h`, `linux/irqchip.h`, `linux/irqdomain.h`, `linux/of_address.h`, `linux/of_irq.h`, `linux/slab.h`.
- Detected declarations: `struct crossbar_device`, `function crossbar_writel`, `function crossbar_writew`, `function crossbar_writeb`, `function allocate_gic_irq`, `function crossbar_domain_alloc`, `function crossbar_domain_free`, `function crossbar_domain_translate`, `function crossbar_of_init`, `function irqcrossbar_init`.
- 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.
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.