drivers/acpi/riscv/irq.c
Source file repositories/reference/linux-study-clean/drivers/acpi/riscv/irq.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/acpi/riscv/irq.c- Extension
.c- Size
- 10935 bytes
- Lines
- 407
- Domain
- Driver Families
- Bucket
- drivers/acpi
- 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.
- 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/acpi.hlinux/sort.hlinux/irq.hinit.h
Detected Declarations
struct riscv_ext_intc_liststruct acpi_irq_dep_ctxfunction irqchip_cmp_funcfunction RINTCfunction riscv_acpi_update_gsi_handlefunction list_for_each_safefunction riscv_acpi_update_gsi_rangefunction list_for_each_entryfunction riscv_acpi_get_gsi_infofunction list_for_eachfunction list_for_eachfunction riscv_acpi_register_ext_intcfunction riscv_acpi_create_gsi_map_smsifunction riscv_acpi_create_gsi_mapfunction riscv_acpi_aplic_parse_madtfunction riscv_acpi_plic_parse_madtfunction riscv_acpi_init_gsi_mappingfunction riscv_acpi_get_gsi_handlefunction list_for_eachfunction riscv_acpi_irq_get_parentfunction riscv_acpi_irq_get_depfunction riscv_acpi_add_prt_depfunction riscv_acpi_add_irq_depfunction arch_acpi_add_auto_dep
Annotated Snippet
struct riscv_ext_intc_list {
acpi_handle handle;
u32 gsi_base;
u32 nr_irqs;
u32 nr_idcs;
u32 id;
u32 type;
u32 flag;
struct list_head list;
};
struct acpi_irq_dep_ctx {
int rc;
unsigned int index;
acpi_handle handle;
};
LIST_HEAD(ext_intc_list);
static int irqchip_cmp_func(const void *in0, const void *in1)
{
struct acpi_probe_entry *elem0 = (struct acpi_probe_entry *)in0;
struct acpi_probe_entry *elem1 = (struct acpi_probe_entry *)in1;
return (elem0->type > elem1->type) - (elem0->type < elem1->type);
}
/*
* On RISC-V, RINTC structures in MADT should be probed before any other
* interrupt controller structures and IMSIC before APLIC. The interrupt
* controller subtypes in MADT of ACPI spec for RISC-V are defined in
* the incremental order like RINTC(24)->IMSIC(25)->APLIC(26)->PLIC(27).
* Hence, simply sorting the subtypes in incremental order will
* establish the required order.
*/
void arch_sort_irqchip_probe(struct acpi_probe_entry *ap_head, int nr)
{
struct acpi_probe_entry *ape = ap_head;
if (nr == 1 || !ACPI_COMPARE_NAMESEG(ACPI_SIG_MADT, ape->id))
return;
sort(ape, nr, sizeof(*ape), irqchip_cmp_func, NULL);
}
static acpi_status riscv_acpi_update_gsi_handle(u32 gsi_base, acpi_handle handle)
{
struct riscv_ext_intc_list *ext_intc_element;
struct list_head *i, *tmp;
list_for_each_safe(i, tmp, &ext_intc_list) {
ext_intc_element = list_entry(i, struct riscv_ext_intc_list, list);
if (gsi_base == ext_intc_element->gsi_base) {
ext_intc_element->handle = handle;
return AE_OK;
}
}
return AE_NOT_FOUND;
}
int riscv_acpi_update_gsi_range(u32 gsi_base, u32 nr_irqs)
{
struct riscv_ext_intc_list *ext_intc_element;
list_for_each_entry(ext_intc_element, &ext_intc_list, list) {
if (gsi_base == ext_intc_element->gsi_base &&
(ext_intc_element->flag & RISCV_ACPI_INTC_FLAG_PENDING)) {
ext_intc_element->nr_irqs = nr_irqs;
ext_intc_element->flag &= ~RISCV_ACPI_INTC_FLAG_PENDING;
return 0;
}
}
return -ENODEV;
}
int riscv_acpi_get_gsi_info(struct fwnode_handle *fwnode, u32 *gsi_base,
u32 *id, u32 *nr_irqs, u32 *nr_idcs)
{
struct riscv_ext_intc_list *ext_intc_element;
struct list_head *i;
list_for_each(i, &ext_intc_list) {
ext_intc_element = list_entry(i, struct riscv_ext_intc_list, list);
if (ext_intc_element->handle == ACPI_HANDLE_FWNODE(fwnode)) {
*gsi_base = ext_intc_element->gsi_base;
*id = ext_intc_element->id;
*nr_irqs = ext_intc_element->nr_irqs;
if (nr_idcs)
*nr_idcs = ext_intc_element->nr_idcs;
Annotation
- Immediate include surface: `linux/acpi.h`, `linux/sort.h`, `linux/irq.h`, `init.h`.
- Detected declarations: `struct riscv_ext_intc_list`, `struct acpi_irq_dep_ctx`, `function irqchip_cmp_func`, `function RINTC`, `function riscv_acpi_update_gsi_handle`, `function list_for_each_safe`, `function riscv_acpi_update_gsi_range`, `function list_for_each_entry`, `function riscv_acpi_get_gsi_info`, `function list_for_each`.
- Atlas domain: Driver Families / drivers/acpi.
- Implementation status: source implementation candidate.
- 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.