drivers/irqchip/irq-loongson-liointc.c
Source file repositories/reference/linux-study-clean/drivers/irqchip/irq-loongson-liointc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/irqchip/irq-loongson-liointc.c- Extension
.c- Size
- 11007 bytes
- Lines
- 422
- 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/errno.hlinux/init.hlinux/types.hlinux/interrupt.hlinux/ioport.hlinux/irqchip.hlinux/of_address.hlinux/of_irq.hlinux/io.hlinux/smp.hlinux/irqchip/chained_irq.hloongson.hasm/loongson.hirq-loongson.h
Detected Declarations
struct liointc_handler_datastruct liointc_privfunction liointc_chained_handle_irqfunction liointc_set_bitfunction liointc_set_typefunction liointc_suspendfunction liointc_resumefunction liointc_domain_xlatefunction liointc_initfunction liointc_of_initfunction htintc_parse_madtfunction acpi_cascade_irqdomain_initfunction liointc_acpi_init
Annotated Snippet
struct liointc_handler_data {
struct liointc_priv *priv;
u32 parent_int_map;
};
struct liointc_priv {
struct irq_chip_generic *gc;
struct liointc_handler_data handler[LIOINTC_NUM_PARENT];
void __iomem *core_isr[LIOINTC_NUM_CORES];
u8 map_cache[LIOINTC_CHIP_IRQ];
u32 int_pol;
u32 int_edge;
bool has_lpc_irq_errata;
};
struct fwnode_handle *liointc_handle;
static void liointc_chained_handle_irq(struct irq_desc *desc)
{
struct liointc_handler_data *handler = irq_desc_get_handler_data(desc);
struct irq_chip *chip = irq_desc_get_chip(desc);
struct irq_chip_generic *gc = handler->priv->gc;
int core = liointc_core_id % LIOINTC_NUM_CORES;
u32 pending;
chained_irq_enter(chip, desc);
pending = readl(handler->priv->core_isr[core]);
if (!pending) {
/* Always blame LPC IRQ if we have that bug */
if (handler->priv->has_lpc_irq_errata &&
(handler->parent_int_map & gc->mask_cache &
BIT(LIOINTC_ERRATA_IRQ)))
pending = BIT(LIOINTC_ERRATA_IRQ);
else
spurious_interrupt();
}
while (pending) {
int bit = __ffs(pending);
generic_handle_domain_irq(gc->domain, bit);
pending &= ~BIT(bit);
}
chained_irq_exit(chip, desc);
}
static void liointc_set_bit(struct irq_chip_generic *gc,
unsigned int offset,
u32 mask, bool set)
{
if (set)
writel(readl(gc->reg_base + offset) | mask,
gc->reg_base + offset);
else
writel(readl(gc->reg_base + offset) & ~mask,
gc->reg_base + offset);
}
static int liointc_set_type(struct irq_data *data, unsigned int type)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
u32 mask = data->mask;
guard(raw_spinlock)(&gc->lock);
switch (type) {
case IRQ_TYPE_LEVEL_HIGH:
liointc_set_bit(gc, LIOINTC_REG_INTC_EDGE, mask, false);
liointc_set_bit(gc, LIOINTC_REG_INTC_POL, mask, false);
break;
case IRQ_TYPE_LEVEL_LOW:
liointc_set_bit(gc, LIOINTC_REG_INTC_EDGE, mask, false);
liointc_set_bit(gc, LIOINTC_REG_INTC_POL, mask, true);
break;
case IRQ_TYPE_EDGE_RISING:
liointc_set_bit(gc, LIOINTC_REG_INTC_EDGE, mask, true);
liointc_set_bit(gc, LIOINTC_REG_INTC_POL, mask, false);
break;
case IRQ_TYPE_EDGE_FALLING:
liointc_set_bit(gc, LIOINTC_REG_INTC_EDGE, mask, true);
liointc_set_bit(gc, LIOINTC_REG_INTC_POL, mask, true);
break;
default:
return -EINVAL;
}
irqd_set_trigger_type(data, type);
return 0;
Annotation
- Immediate include surface: `linux/errno.h`, `linux/init.h`, `linux/types.h`, `linux/interrupt.h`, `linux/ioport.h`, `linux/irqchip.h`, `linux/of_address.h`, `linux/of_irq.h`.
- Detected declarations: `struct liointc_handler_data`, `struct liointc_priv`, `function liointc_chained_handle_irq`, `function liointc_set_bit`, `function liointc_set_type`, `function liointc_suspend`, `function liointc_resume`, `function liointc_domain_xlate`, `function liointc_init`, `function liointc_of_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.