![]() |
RT-Thread RTOS
An open source embedded real-time operating system
|
How **interrupts** properties become virtual IRQs via **irq_parse** + **irq_map**.
Sources: **pic.c** (ofw_pic_init), **ofw/irq.c** (rt_ofw_map_irq).
**rt_pic_init()** → **ofw_pic_init()**:
**RT_PIC_OFW_DECLARE(name, ids, handler)** expands to **RT_OFW_STUB_EXPORT(..., pic, handler)** — same mechanism as other OFW stubs, linker section **.rt_ofw_data.stub.***.
Handler (e.g. **gicv2_ofw_init**) must:
rt_pic_linear_irq**rt_pic_add_traps** (root only)rt_ofw_data(np) = &pic****rt_dm_dev_get_irq(dev, index)** → **ofw_api_call(get_irq)** → **rt_ofw_get_irq** → **rt_ofw_map_irq**.
| Step | Responsibility |
|---|---|
**rt_ofw_parse_irq_cells** | Fill **rt_ofw_cell_args** from **interrupts** |
**irq_parse** | Set **out_pirq->hwirq**, **mode** (GIC: type + number) |
**irq_map** | **rt_pic_config_irq**, return virtual IRQ |
**rt_pic_dynamic_cast**: finds **struct rt_pic** embedded after **rt_device** or **rt_object** (name **"PIC"**).
From **pic-gicv2.c** / **pic-gicv3.c**:
| Cell 0 | Cell 1 | Cell 2 |
|---|---|---|
| 0 = SPI, 1 = PPI, … | Interrupt number | Flags → **RT_IRQ_MODE_*** |
SPI DT number 0 → hwirq 32 (args[1] + 32).
DTS example (Raspberry Pi 4, **bcm2711-rpi-4-b.dts**):
Child node must expose **interrupt-controller** + **#interrupt-cells** and set **rt_ofw_data** to its **struct rt_pic**.
Consumers use **interrupt-parent = <&child_ic>** or inherited parent.
PCI interrupt-map: resolves to parent GIC cells via PCI and device tree — still ends in **rt_ofw_map_irq**.
ops | Required for DT devices |
|---|---|
**irq_parse** | Yes |
**irq_map** | Yes |
**irq_mask / irq_unmask** | Strongly recommended |
Without **irq_map**, **rt_ofw_map_irq** logs error and fails.
Non-root: no **rt_pic_add_traps**; use parent ISR or cascade.
| Issue | Mitigation |
|---|---|
**rt_ofw_data NULL** | Provider not probed — **rt_platform_ofw_request** before cast |
**irq_parse returns error** | **rt_ofw_map_irq** fails — check cell count |
Wrong **interrupt-parent** | Walk **rt_ofw_find_irq_parent** in OFW IRQ code |
| Mix hwirq / virtual in driver | Only use **rt_dm_dev_get_irq** return value |