• Samuel Holland's avatar
    of/irq: Use interrupts-extended to find parent · e9103362
    Samuel Holland authored
    The RISC-V PLIC binding uses interrupts-extended to specify its parent
    domain(s). That binding does not allow the interrupt-parent property to
    appear in the irqchip node. This prevents of_irq_init from properly
    detecting the irqchip hierarchy.
    
    If no interrupt-parent property is present in the enclosing bus or root
    node, then desc->interrupt_parent will be NULL for both the per-CPU
    RISC-V INTC (the actual root domain) and the RISC-V PLIC. Similarly, if
    the bus or root node specifies `interrupt-parent = <&plic>`, then
    of_irq_init will hit the `desc->interrupt_parent == np` check, and again
    all parents will be NULL. So things happen to work today for some boards
    due to Makefile ordering.
    
    However, things break when another irqchip ("foo") is stacked on top of
    the PLIC. The bus or root node will have `interrupt-parent = <&foo>`,
    since that is what all of the other peripherals need. When of_irq_init
    runs, it will try to find the PLIC's parent domain. of_irq_find_parent
    will fall back to using the interrupt-parent property of the PLIC's
    parent node (i.e. the bus or root node), and of_irq_init will see "foo"
    as the PLIC's parent domain. But this is wrong, because "foo" is
    actually the PLIC's child domain!
    
    So of_irq_init wrongly attempts to init the stacked irqchip before the
    PLIC. This fails and breaks booting.
    
    Fix this by using the first node referenced by interrupts-extended as
    the parent when that property is present. This allows of_irq_init to see
    the relationship between the PLIC and the per-CPU RISC-V INTC, and thus
    only the RISC-V INTC is (correctly) considered a root domain.
    Signed-off-by: default avatarSamuel Holland <samuel@sholland.org>
    Signed-off-by: default avatarRob Herring <robh@kernel.org>
    Link: https://lore.kernel.org/r/20220412051529.6293-1-samuel@sholland.org
    e9103362
irq.c 20.1 KB