drivers/irqchip/qcom-irq-combiner.c
Source file repositories/reference/linux-study-clean/drivers/irqchip/qcom-irq-combiner.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/irqchip/qcom-irq-combiner.c- Extension
.c- Size
- 7078 bytes
- Lines
- 277
- 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/acpi.hlinux/irqchip/chained_irq.hlinux/irqdomain.hlinux/platform_device.h
Detected Declarations
struct combiner_regstruct combinerstruct get_registers_contextfunction irq_nrfunction combiner_handle_irqfunction combiner_irq_chip_mask_irqfunction combiner_irq_chip_unmask_irqfunction combiner_irq_mapfunction combiner_irq_unmapfunction combiner_irq_translatefunction count_registers_cbfunction count_registersfunction get_registers_cbfunction get_registersfunction combiner_probe
Annotated Snippet
struct combiner_reg {
void __iomem *addr;
unsigned long enabled;
};
struct combiner {
struct irq_domain *domain;
int parent_irq;
u32 nirqs;
u32 nregs;
struct combiner_reg regs[];
};
static inline int irq_nr(u32 reg, u32 bit)
{
return reg * REG_SIZE + bit;
}
/*
* Handler for the cascaded IRQ.
*/
static void combiner_handle_irq(struct irq_desc *desc)
{
struct combiner *combiner = irq_desc_get_handler_data(desc);
struct irq_chip *chip = irq_desc_get_chip(desc);
u32 reg;
chained_irq_enter(chip, desc);
for (reg = 0; reg < combiner->nregs; reg++) {
int hwirq;
u32 bit;
u32 status;
bit = readl_relaxed(combiner->regs[reg].addr);
status = bit & combiner->regs[reg].enabled;
if (bit && !status)
pr_warn_ratelimited("Unexpected IRQ on CPU%d: (%08x %08lx %p)\n",
smp_processor_id(), bit,
combiner->regs[reg].enabled,
combiner->regs[reg].addr);
while (status) {
bit = __ffs(status);
status &= ~(1 << bit);
hwirq = irq_nr(reg, bit);
generic_handle_domain_irq(combiner->domain, hwirq);
}
}
chained_irq_exit(chip, desc);
}
static void combiner_irq_chip_mask_irq(struct irq_data *data)
{
struct combiner *combiner = irq_data_get_irq_chip_data(data);
struct combiner_reg *reg = combiner->regs + data->hwirq / REG_SIZE;
clear_bit(data->hwirq % REG_SIZE, ®->enabled);
}
static void combiner_irq_chip_unmask_irq(struct irq_data *data)
{
struct combiner *combiner = irq_data_get_irq_chip_data(data);
struct combiner_reg *reg = combiner->regs + data->hwirq / REG_SIZE;
set_bit(data->hwirq % REG_SIZE, ®->enabled);
}
static struct irq_chip irq_chip = {
.irq_mask = combiner_irq_chip_mask_irq,
.irq_unmask = combiner_irq_chip_unmask_irq,
.name = "qcom-irq-combiner"
};
static int combiner_irq_map(struct irq_domain *domain, unsigned int irq,
irq_hw_number_t hwirq)
{
irq_set_chip_and_handler(irq, &irq_chip, handle_level_irq);
irq_set_chip_data(irq, domain->host_data);
irq_set_noprobe(irq);
return 0;
}
static void combiner_irq_unmap(struct irq_domain *domain, unsigned int irq)
{
irq_domain_reset_irq_data(irq_get_irq_data(irq));
}
static int combiner_irq_translate(struct irq_domain *d, struct irq_fwspec *fws,
Annotation
- Immediate include surface: `linux/acpi.h`, `linux/irqchip/chained_irq.h`, `linux/irqdomain.h`, `linux/platform_device.h`.
- Detected declarations: `struct combiner_reg`, `struct combiner`, `struct get_registers_context`, `function irq_nr`, `function combiner_handle_irq`, `function combiner_irq_chip_mask_irq`, `function combiner_irq_chip_unmask_irq`, `function combiner_irq_map`, `function combiner_irq_unmap`, `function combiner_irq_translate`.
- 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.