Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bdd272cb authored by Linus Walleij's avatar Linus Walleij
Browse files

irqchip: versatile FPGA: support cascaded interrupts from DT



The Versatile FPGA interrupt controller supports cascading interrupts,
i.e. that its output is connected to the input of another interrupt
controller. This makes it possible to pass a parent interrupt from
the device tree and print it in the boot log if applicable.

Acked-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent fe989145
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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.
+13 −2
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>

#include <asm/exception.h>
#include <asm/mach/irq.h>
@@ -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);