diff --git a/Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt b/Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt index 9989eda755d9..c9cf605bb995 100644 --- a/Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt +++ b/Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt @@ -29,3 +29,8 @@ pic: pic@14000000 { clear-mask = <0xffffffff>; valid-mask = <0x003fffff>; }; + +Optional properties: +- interrupts: if the FPGA IRQ controller is cascaded, i.e. if its IRQ + output is simply connected to the input of another IRQ controller, + then the parent IRQ shall be specified in this property. diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c index 47a52ab580d8..3ae2bb8d9cf2 100644 --- a/drivers/irqchip/irq-versatile-fpga.c +++ b/drivers/irqchip/irq-versatile-fpga.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -167,8 +168,12 @@ void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start, f->used_irqs++; } - pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n", + pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs", fpga_irq_id, name, base, f->used_irqs); + if (parent_irq != -1) + pr_cont(", parent IRQ: %d\n", parent_irq); + else + pr_cont("\n"); fpga_irq_id++; } @@ -180,6 +185,7 @@ int __init fpga_irq_of_init(struct device_node *node, void __iomem *base; u32 clear_mask; u32 valid_mask; + int parent_irq; if (WARN_ON(!node)) return -ENODEV; @@ -193,7 +199,12 @@ int __init fpga_irq_of_init(struct device_node *node, if (of_property_read_u32(node, "valid-mask", &valid_mask)) valid_mask = 0; - fpga_irq_init(base, node->name, 0, -1, valid_mask, node); + /* Some chips are cascaded from a parent IRQ */ + parent_irq = irq_of_parse_and_map(node, 0); + if (!parent_irq) + parent_irq = -1; + + fpga_irq_init(base, node->name, 0, parent_irq, valid_mask, node); writel(clear_mask, base + IRQ_ENABLE_CLEAR); writel(clear_mask, base + FIQ_ENABLE_CLEAR);