设备树描述
plic 是一个简单的中断控制器,且该计算机系统中只有一个,所以 CONFIG_IRQ_DOMAIN_HIERARCHY=n
interrupt-controller@e4000000 {
compatible = "riscv,plic0";
#address-cells = <0x2>;
#interrupt-cells = <0x2>;
interrupt-controller;
reg = <0x0 0xe4000000 0x0 0x2000000>;
riscv,ndev = <0x47>;
interrupts-extended = <0x2 0xb 0x2 0x9 0x3 0xb 0x3 0x9 0x4 0xb 0x4 0x9 0x5 0xb 0x5 0x9>;
phandle = <0x6>;
};
驱动逻辑
plic_init
plic_regs = of_iomap(node, 0);
of_property_read_u32(node, "riscv,ndev", &nr_irqs);
nr_contexts = of_irq_count(node);
plic_irqdomain = irq_domain_add_linear(node, nr_irqs + 1, &plic_irqdomain_ops, NULL);
for (i = 0; i < nr_contexts; i++) {}
set_handle_irq(plic_handle_irq);
irq_domain_ops 的创建时机
plic_irqdomain = irq_domain_add_linear(node, nr_irqs + 1, &plic_irqdomain_ops, NULL);
irq_domain_ops 的实现
static const struct irq_domain_ops plic_irqdomain_ops = {
.map = plic_irqdomain_map,
.xlate = irq_domain_xlate_onecell,
};
irq_chip 的绑定时机 在 map 实现中
下面代码中的 desc->irq_data.chip = chip;
plic_irqdomain_map
irq_set_chip_and_handler/irq_set_chip_and_handler_name
irq_set_chip
desc->irq_data.chip = chip;
__irq_set_handler
irq_chip 的实现
static struct irq_chip plic_chip = {
.name = "SiFive PLIC",
.irq_mask = plic_irq_mask,
.irq_unmask = plic_irq_unmask,
.irq_eoi = plic_irq_eoi,
.irq_set_wake = plic_set_wake,
#ifdef CONFIG_SMP
.irq_set_affinity = plic_set_affinity,
#endif
};