[source] brcm63xx: fix external interrupts on BCM6318
LEDE Commits
lede-commits at lists.infradead.org
Thu Feb 9 05:31:20 PST 2017
jogo pushed a commit to source.git, branch master:
https://git.lede-project.org/94bbd1f057c5fdccc3a6ef80b1c533064220a2ff
commit 94bbd1f057c5fdccc3a6ef80b1c533064220a2ff
Author: Jonas Gorski <jonas.gorski at gmail.com>
AuthorDate: Mon Dec 19 13:02:21 2016 +0100
brcm63xx: fix external interrupts on BCM6318
Setting the clear bit for an interrupt seems to cause interrupts to be
deasserted again immediately. So unset the bit for BCM6318 to allow
subsequent interrupts to still work.
Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
---
target/linux/brcm63xx/dts/bcm6318.dtsi | 2 +-
...-support-for-bcm6345-style-external-inter.patch | 27 ++++++++++++++++------
2 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/target/linux/brcm63xx/dts/bcm6318.dtsi b/target/linux/brcm63xx/dts/bcm6318.dtsi
index 115b15c..7766980 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 at 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 2526456..2271b66 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 <jogo at openwrt.org>
+
+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 <jogo at openwrt.org>
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 <jogo at openwrt.org>
+ 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 <jogo at openwrt.org>
+
+ 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 <jogo at openwrt.org>
+
+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 <jogo at openwrt.org>
+
+ 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 <jogo at openwrt.org>
+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 <jogo at openwrt.org>
+ 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 <jogo at openwrt.org>
+ 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 <jogo at openwrt.org>
+ 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 <jogo at openwrt.org>
+ 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
More information about the lede-commits
mailing list