diff --git a/target/linux/brcm63xx/dts/bcm6318.dtsi b/target/linux/brcm63xx/dts/bcm6318.dtsi index 115b15c7fe..776698068d 100644 --- a/target/linux/brcm63xx/dts/bcm6318.dtsi +++ b/target/linux/brcm63xx/dts/bcm6318.dtsi @@ -36,7 +36,7 @@ compatible = "simple-bus"; ext_intc: interrupt-controller@10000018 { - compatible = "brcm,bcm6345-ext-intc"; + compatible = "brcm,bcm6318-ext-intc"; reg = <0x10000018 0x4>; interrupt-controller; diff --git a/target/linux/brcm63xx/patches-4.4/321-irqchip-add-support-for-bcm6345-style-external-inter.patch b/target/linux/brcm63xx/patches-4.4/321-irqchip-add-support-for-bcm6345-style-external-inter.patch index 252645695f..2271b66f0e 100644 --- a/target/linux/brcm63xx/patches-4.4/321-irqchip-add-support-for-bcm6345-style-external-inter.patch +++ b/target/linux/brcm63xx/patches-4.4/321-irqchip-add-support-for-bcm6345-style-external-inter.patch @@ -23,7 +23,7 @@ Signed-off-by: Jonas Gorski + +Required properties: + -+- compatible: Should be "brcm,bcm6345-ext-intc". ++- compatible: Should be "brcm,bcm6345-ext-intc" or "brcm,bcm6318-ext-intc". +- reg: Specifies the base physical addresses and size of the registers. +- interrupt-controller: identifies the node as an interrupt controller. +- #interrupt-cells: Specifies the number of cells needed to encode an interrupt @@ -73,7 +73,7 @@ Signed-off-by: Jonas Gorski obj-$(CONFIG_METAG) += irq-metag-ext.o --- /dev/null +++ b/drivers/irqchip/irq-bcm6345-ext.c -@@ -0,0 +1,288 @@ +@@ -0,0 +1,301 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive @@ -119,6 +119,7 @@ Signed-off-by: Jonas Gorski + int parent_irq[MAX_IRQS]; + void __iomem *reg; + int shift; ++ unsigned int toggle_clear_on_ack:1; +}; + +static void bcm6345_ext_intc_irq_handle(struct irq_desc *desc) @@ -148,8 +149,10 @@ Signed-off-by: Jonas Gorski + + raw_spin_lock(&priv->lock); + reg = __raw_readl(priv->reg); -+ reg |= 1 << (hwirq + EXTIRQ_CFG_CLEAR * priv->shift); -+ __raw_writel(reg, priv->reg); ++ __raw_writel(reg | (1 << (hwirq + EXTIRQ_CFG_CLEAR * priv->shift)), ++ priv->reg); ++ if (priv->toggle_clear_on_ack) ++ __raw_writel(reg, priv->reg); + raw_spin_unlock(&priv->lock); +} + @@ -263,7 +266,8 @@ Signed-off-by: Jonas Gorski + +static int __init __bcm6345_ext_intc_init(struct device_node *node, + int num_irqs, int *irqs, -+ void __iomem *reg, int shift) ++ void __iomem *reg, int shift, ++ bool toggle_clear_on_ack) +{ + struct intc_data *data; + unsigned int i; @@ -284,6 +288,7 @@ Signed-off-by: Jonas Gorski + + data->reg = reg; + data->shift = shift; ++ data->toggle_clear_on_ack = toggle_clear_on_ack; + + data->chip.name = "bcm6345-ext-intc"; + data->chip.irq_ack = bcm6345_ext_intc_irq_ack; @@ -314,7 +319,7 @@ Signed-off-by: Jonas Gorski +void __init bcm6345_ext_intc_init(int num_irqs, int *irqs, void __iomem *reg, + int shift) +{ -+ __bcm6345_ext_intc_init(NULL, num_irqs, irqs, reg, shift); ++ __bcm6345_ext_intc_init(NULL, num_irqs, irqs, reg, shift, false); +} + +#ifdef CONFIG_OF @@ -326,6 +331,7 @@ Signed-off-by: Jonas Gorski + void __iomem *base; + int irqs[MAX_IRQS] = { 0 }; + u32 shift; ++ bool toggle_clear_on_ack = false; + + num_irqs = of_irq_count(node); + @@ -335,6 +341,10 @@ Signed-off-by: Jonas Gorski + if (of_property_read_u32(node, "brcm,field-width", &shift)) + shift = 4; + ++ /* on BCM6318 setting CLEAR seems to continuously mask interrupts */ ++ if (of_device_is_compatible(node, "brcm,bcm6318-ext-intc")) ++ toggle_clear_on_ack = true; ++ + for (i = 0; i < num_irqs; i++) { + irqs[i] = irq_of_parse_and_map(node, i); + if (!irqs[i]) { @@ -347,7 +357,8 @@ Signed-off-by: Jonas Gorski + if (!base) + goto out_unmap; + -+ ret = __bcm6345_ext_intc_init(node, num_irqs, irqs, base, shift); ++ ret = __bcm6345_ext_intc_init(node, num_irqs, irqs, base, shift, ++ toggle_clear_on_ack); + if (!ret) + return 0; +out_unmap: @@ -359,6 +370,8 @@ Signed-off-by: Jonas Gorski + return ret; +} + ++IRQCHIP_DECLARE(bcm6318_ext_intc, "brcm,bcm6318-ext-intc", ++ bcm6345_ext_intc_of_init); +IRQCHIP_DECLARE(bcm6345_ext_intc, "brcm,bcm6345-ext-intc", + bcm6345_ext_intc_of_init); +#endif