drivers/of/irq.c
Source file repositories/reference/linux-study-clean/drivers/of/irq.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/of/irq.c- Extension
.c- Size
- 25022 bytes
- Lines
- 907
- Domain
- Driver Families
- Bucket
- drivers/of
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/cleanup.hlinux/device.hlinux/errno.hlinux/list.hlinux/module.hlinux/of.hlinux/of_irq.hlinux/string.hlinux/slab.hof_private.h
Detected Declarations
struct of_intc_descfunction Copyrightfunction of_imap_parser_initfunction of_irq_parse_rawfunction of_irq_parse_onefunction of_irq_to_resourcefunction of_irq_getfunction of_irq_get_bynamefunction of_irq_countfunction of_irq_to_resource_tablefunction of_irq_initfunction for_each_matching_node_and_matchfunction list_for_each_entry_safefunction list_for_each_entry_safefunction of_check_msi_parentfunction of_msi_xlatefunction of_for_each_phandlefunction of_msi_configureexport irq_of_parse_and_mapexport of_irq_find_parentexport of_imap_parser_initexport of_imap_parser_oneexport of_irq_parse_rawexport of_irq_parse_oneexport of_irq_to_resourceexport of_irq_getexport of_irq_get_bynameexport of_irq_countexport of_irq_to_resource_tableexport of_msi_xlateexport of_msi_get_domainexport of_msi_configure
Annotated Snippet
struct of_intc_desc {
struct list_head list;
of_irq_init_cb_t irq_init_cb;
struct device_node *dev;
struct device_node *interrupt_parent;
};
/**
* of_irq_init - Scan and init matching interrupt controllers in DT
* @matches: 0 terminated array of nodes to match and init function to call
*
* This function scans the device tree for matching interrupt controller nodes,
* and calls their initialization functions in order with parents first.
*/
void __init of_irq_init(const struct of_device_id *matches)
{
const struct of_device_id *match;
struct device_node *np, *parent = NULL;
struct of_intc_desc *desc, *temp_desc;
struct list_head intc_desc_list, intc_parent_list;
INIT_LIST_HEAD(&intc_desc_list);
INIT_LIST_HEAD(&intc_parent_list);
for_each_matching_node_and_match(np, matches, &match) {
if (!of_property_read_bool(np, "interrupt-controller") ||
!of_device_is_available(np))
continue;
if (WARN(!match->data, "of_irq_init: no init function for %s\n",
match->compatible))
continue;
/*
* Here, we allocate and populate an of_intc_desc with the node
* pointer, interrupt-parent device_node etc.
*/
desc = kzalloc_obj(*desc);
if (!desc) {
of_node_put(np);
goto err;
}
desc->irq_init_cb = match->data;
desc->dev = of_node_get(np);
/*
* interrupts-extended can reference multiple parent domains.
* Arbitrarily pick the first one; assume any other parents
* are the same distance away from the root irq controller.
*/
desc->interrupt_parent = of_parse_phandle(np, "interrupts-extended", 0);
if (!desc->interrupt_parent && of_property_present(np, "interrupts"))
desc->interrupt_parent = of_irq_find_parent(np);
else if (!desc->interrupt_parent)
desc->interrupt_parent = of_parse_phandle(np, "interrupt-parent", 0);
if (desc->interrupt_parent == np) {
of_node_put(desc->interrupt_parent);
desc->interrupt_parent = NULL;
}
list_add_tail(&desc->list, &intc_desc_list);
}
/*
* The root irq controller is the one without an interrupt-parent.
* That one goes first, followed by the controllers that reference it,
* followed by the ones that reference the 2nd level controllers, etc.
*/
while (!list_empty(&intc_desc_list)) {
/*
* Process all controllers with the current 'parent'.
* First pass will be looking for NULL as the parent.
* The assumption is that NULL parent means a root controller.
*/
list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
int ret;
if (desc->interrupt_parent != parent)
continue;
list_del(&desc->list);
of_node_set_flag(desc->dev, OF_POPULATED);
pr_debug("of_irq_init: init %pOF (%p), parent %p\n",
desc->dev,
desc->dev, desc->interrupt_parent);
ret = desc->irq_init_cb(desc->dev,
desc->interrupt_parent);
if (ret) {
pr_err("%s: Failed to init %pOF (%p), parent %p\n",
Annotation
- Immediate include surface: `linux/cleanup.h`, `linux/device.h`, `linux/errno.h`, `linux/list.h`, `linux/module.h`, `linux/of.h`, `linux/of_irq.h`, `linux/string.h`.
- Detected declarations: `struct of_intc_desc`, `function Copyright`, `function of_imap_parser_init`, `function of_irq_parse_raw`, `function of_irq_parse_one`, `function of_irq_to_resource`, `function of_irq_get`, `function of_irq_get_byname`, `function of_irq_count`, `function of_irq_to_resource_table`.
- Atlas domain: Driver Families / drivers/of.
- Implementation status: integration 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.