aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm63xx
diff options
context:
space:
mode:
authorJonas Gorski <jogo@openwrt.org>2014-12-08 16:11:52 +0000
committerJonas Gorski <jogo@openwrt.org>2014-12-08 16:11:52 +0000
commit4bf6221ffae31f5e86eba8e5eb1800649c4a494c (patch)
tree26994cca2f7499b9be1dad09c4ddd235dd60cecf /target/linux/brcm63xx
parent7d2edba42a4eaa0e4efc76cbc37efa7d96ff9bb9 (diff)
downloadupstream-4bf6221ffae31f5e86eba8e5eb1800649c4a494c.tar.gz
upstream-4bf6221ffae31f5e86eba8e5eb1800649c4a494c.tar.bz2
upstream-4bf6221ffae31f5e86eba8e5eb1800649c4a494c.zip
brcm63xx: fix a few issues in irq chip drivers
Fix locking and lock usage, making it compile for SMP. Signed-off-by: Jonas Gorski <jogo@openwrt.org> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@43578 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/brcm63xx')
-rw-r--r--target/linux/brcm63xx/config-3.143
-rw-r--r--target/linux/brcm63xx/config-3.183
-rw-r--r--target/linux/brcm63xx/dts/bcm6318.dtsi2
-rw-r--r--target/linux/brcm63xx/dts/bcm63268.dtsi2
-rw-r--r--target/linux/brcm63xx/dts/bcm6328.dtsi2
-rw-r--r--target/linux/brcm63xx/dts/bcm6338.dtsi2
-rw-r--r--target/linux/brcm63xx/dts/bcm6345.dtsi2
-rw-r--r--target/linux/brcm63xx/dts/bcm6348.dtsi4
-rw-r--r--target/linux/brcm63xx/dts/bcm6358.dtsi2
-rw-r--r--target/linux/brcm63xx/dts/bcm6362.dtsi2
-rw-r--r--target/linux/brcm63xx/dts/bcm6368.dtsi2
-rw-r--r--target/linux/brcm63xx/patches-3.14/320-irqchip-add-support-for-bcm6345-style-periphery-irq-.patch (renamed from target/linux/brcm63xx/patches-3.14/320-irqchip-add-support-for-bcm6345-style-l2-irq-control.patch)259
-rw-r--r--target/linux/brcm63xx/patches-3.14/321-irqchip-add-support-for-bcm6345-style-external-inter.patch97
-rw-r--r--target/linux/brcm63xx/patches-3.14/322-MIPS-BCM63XX-switch-to-IRQ_DOMAIN.patch74
-rw-r--r--target/linux/brcm63xx/patches-3.14/323-MIPS-BCM63XX-wire-up-BCM6358-s-external-interrupts-4.patch6
-rw-r--r--target/linux/brcm63xx/patches-3.14/339-MIPS-BCM63XX-add-support-for-BCM63268.patch8
-rw-r--r--target/linux/brcm63xx/patches-3.14/341-MIPS-BCM63XX-add-support-for-BCM6318.patch10
-rw-r--r--target/linux/brcm63xx/patches-3.14/373-MIPS-BCM63XX-register-interrupt-controllers-through-.patch16
-rw-r--r--target/linux/brcm63xx/patches-3.18/320-irqchip-add-support-for-bcm6345-style-periphery-irq-.patch (renamed from target/linux/brcm63xx/patches-3.18/320-irqchip-add-support-for-bcm6345-style-l2-irq-control.patch)246
-rw-r--r--target/linux/brcm63xx/patches-3.18/321-irqchip-add-support-for-bcm6345-style-external-inter.patch102
-rw-r--r--target/linux/brcm63xx/patches-3.18/322-MIPS-BCM63XX-switch-to-IRQ_DOMAIN.patch85
-rw-r--r--target/linux/brcm63xx/patches-3.18/323-MIPS-BCM63XX-wire-up-BCM6358-s-external-interrupts-4.patch6
-rw-r--r--target/linux/brcm63xx/patches-3.18/339-MIPS-BCM63XX-add-support-for-BCM63268.patch8
-rw-r--r--target/linux/brcm63xx/patches-3.18/341-MIPS-BCM63XX-add-support-for-BCM6318.patch10
-rw-r--r--target/linux/brcm63xx/patches-3.18/366-MIPS-add-support-for-vmlinux.bin-appended-DTB.patch2
-rw-r--r--target/linux/brcm63xx/patches-3.18/373-MIPS-BCM63XX-register-interrupt-controllers-through-.patch16
26 files changed, 546 insertions, 425 deletions
diff --git a/target/linux/brcm63xx/config-3.14 b/target/linux/brcm63xx/config-3.14
index 1fee6392bd..dd27f473bb 100644
--- a/target/linux/brcm63xx/config-3.14
+++ b/target/linux/brcm63xx/config-3.14
@@ -14,6 +14,8 @@ CONFIG_B53_PHY_DRIVER=y
CONFIG_B53_PHY_FIXUP=y
CONFIG_B53_SPI_DRIVER=y
# CONFIG_B53_SRAB_DRIVER is not set
+CONFIG_BCM6345_EXT_IRQ=y
+CONFIG_BCM6345_PERIPH_IRQ=y
CONFIG_BCM63XX=y
CONFIG_BCM63XX_CPU_3368=y
CONFIG_BCM63XX_CPU_6318=y
@@ -71,7 +73,6 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_GENERIC_IO=y
CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_NET_UTILS=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GPIOLIB=y
diff --git a/target/linux/brcm63xx/config-3.18 b/target/linux/brcm63xx/config-3.18
index b323da40ca..e3cf020a99 100644
--- a/target/linux/brcm63xx/config-3.18
+++ b/target/linux/brcm63xx/config-3.18
@@ -18,7 +18,7 @@ CONFIG_B53_PHY_FIXUP=y
CONFIG_B53_SPI_DRIVER=y
# CONFIG_B53_SRAB_DRIVER is not set
CONFIG_BCM6345_EXT_IRQ=y
-CONFIG_BCM6345_L2_IRQ=y
+CONFIG_BCM6345_PERIPH_IRQ=y
CONFIG_BCM63XX=y
CONFIG_BCM63XX_CPU_3368=y
CONFIG_BCM63XX_CPU_6318=y
@@ -61,6 +61,7 @@ CONFIG_CPU_GENERIC_DUMP_TLB=y
CONFIG_CPU_HAS_PREFETCH=y
CONFIG_CPU_HAS_SYNC=y
CONFIG_CPU_MIPS32=y
+CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
CONFIG_CPU_R4K_CACHE_TLB=y
CONFIG_CPU_R4K_FPU=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
diff --git a/target/linux/brcm63xx/dts/bcm6318.dtsi b/target/linux/brcm63xx/dts/bcm6318.dtsi
index 723c488f20..97bdea7b5b 100644
--- a/target/linux/brcm63xx/dts/bcm6318.dtsi
+++ b/target/linux/brcm63xx/dts/bcm6318.dtsi
@@ -42,7 +42,7 @@
};
periph_intc: interrupt-controller@10000020 {
- compatible = "brcm,bcm6345-l2-intc";
+ compatible = "brcm,bcm6345-periph-intc";
reg = <0x10000020 0x20>;
interrupt-controller;
diff --git a/target/linux/brcm63xx/dts/bcm63268.dtsi b/target/linux/brcm63xx/dts/bcm63268.dtsi
index 214cd6266c..bc80d70575 100644
--- a/target/linux/brcm63xx/dts/bcm63268.dtsi
+++ b/target/linux/brcm63xx/dts/bcm63268.dtsi
@@ -48,7 +48,7 @@
};
periph_intc: interrupt-controller@10000020 {
- compatible = "brcm,bcm6345-l2-intc";
+ compatible = "brcm,bcm6345-periph-intc";
reg = <0x10000020 0x20>,
<0x10000040 0x20>;
diff --git a/target/linux/brcm63xx/dts/bcm6328.dtsi b/target/linux/brcm63xx/dts/bcm6328.dtsi
index 0ed186e185..53f96ff009 100644
--- a/target/linux/brcm63xx/dts/bcm6328.dtsi
+++ b/target/linux/brcm63xx/dts/bcm6328.dtsi
@@ -42,7 +42,7 @@
};
periph_intc: interrupt-controller@10000020 {
- compatible = "brcm,bcm6345-l2-intc";
+ compatible = "brcm,bcm6345-periph-intc";
reg = <0x10000020 0x10>;
interrupt-controller;
diff --git a/target/linux/brcm63xx/dts/bcm6338.dtsi b/target/linux/brcm63xx/dts/bcm6338.dtsi
index b527781060..c1980f4036 100644
--- a/target/linux/brcm63xx/dts/bcm6338.dtsi
+++ b/target/linux/brcm63xx/dts/bcm6338.dtsi
@@ -45,7 +45,7 @@
compatible = "simple-bus";
periph_intc: interrupt-controller@fffe000c {
- compatible = "brcm,bcm6345-l2-intc";
+ compatible = "brcm,bcm6345-periph-intc";
reg = <0xfffe000c 0x8>;
interrupt-controller;
diff --git a/target/linux/brcm63xx/dts/bcm6345.dtsi b/target/linux/brcm63xx/dts/bcm6345.dtsi
index 16ba8bd6c0..e8e7016ff7 100644
--- a/target/linux/brcm63xx/dts/bcm6345.dtsi
+++ b/target/linux/brcm63xx/dts/bcm6345.dtsi
@@ -45,7 +45,7 @@
compatible = "simple-bus";
periph_intc: interrupt-controller@fffe000c {
- compatible = "brcm,bcm6345-l2-intc";
+ compatible = "brcm,bcm6345-periph-intc";
reg = <0xfffe000c 0x9>;
interrupt-controller;
diff --git a/target/linux/brcm63xx/dts/bcm6348.dtsi b/target/linux/brcm63xx/dts/bcm6348.dtsi
index 06ecbaa1f9..7dd423b9ca 100644
--- a/target/linux/brcm63xx/dts/bcm6348.dtsi
+++ b/target/linux/brcm63xx/dts/bcm6348.dtsi
@@ -45,7 +45,7 @@
compatible = "simple-bus";
periph_intc: interrupt-controller@fffe000c {
- compatible = "brcm,bcm6345-l2-intc";
+ compatible = "brcm,bcm6345-periph-intc";
reg = <0xfffe000c 0x8>;
interrupt-controller;
@@ -64,6 +64,8 @@
interrupt-parent = <&cpu_intc>;
interrupts = <3>, <4>, <5>, <6>;
+
+ brcm,field-width = <5>;
};
};
};
diff --git a/target/linux/brcm63xx/dts/bcm6358.dtsi b/target/linux/brcm63xx/dts/bcm6358.dtsi
index a4af2144a8..7217b8db6e 100644
--- a/target/linux/brcm63xx/dts/bcm6358.dtsi
+++ b/target/linux/brcm63xx/dts/bcm6358.dtsi
@@ -51,7 +51,7 @@
compatible = "simple-bus";
periph_intc: interrupt-controller@fffe000c {
- compatible = "brcm,bcm6345-l2-intc";
+ compatible = "brcm,bcm6345-periph-intc";
reg = <0xfffe000c 0x8>,
<0xfffe0038 0x8>;
diff --git a/target/linux/brcm63xx/dts/bcm6362.dtsi b/target/linux/brcm63xx/dts/bcm6362.dtsi
index 36765b0eba..4e2e41d5d4 100644
--- a/target/linux/brcm63xx/dts/bcm6362.dtsi
+++ b/target/linux/brcm63xx/dts/bcm6362.dtsi
@@ -48,7 +48,7 @@
};
periph_intc: interrupt-controller@10000020 {
- compatible = "brcm,bcm6345-l2-intc";
+ compatible = "brcm,bcm6345-periph-intc";
reg = <0x10000020 0x10>,
<0x10000030 0x10>;
diff --git a/target/linux/brcm63xx/dts/bcm6368.dtsi b/target/linux/brcm63xx/dts/bcm6368.dtsi
index dcbbdbfe81..27b9f62b69 100644
--- a/target/linux/brcm63xx/dts/bcm6368.dtsi
+++ b/target/linux/brcm63xx/dts/bcm6368.dtsi
@@ -63,7 +63,7 @@
};
periph_intc: interrupt-controller@10000020 {
- compatible = "brcm,bcm6345-l2-intc";
+ compatible = "brcm,bcm6345-periph-intc";
reg = <0x10000020 0x10>,
<0x10000030 0x10>;
diff --git a/target/linux/brcm63xx/patches-3.14/320-irqchip-add-support-for-bcm6345-style-l2-irq-control.patch b/target/linux/brcm63xx/patches-3.14/320-irqchip-add-support-for-bcm6345-style-periphery-irq-.patch
index a260a1b0fe..2fd1568e27 100644
--- a/target/linux/brcm63xx/patches-3.14/320-irqchip-add-support-for-bcm6345-style-l2-irq-control.patch
+++ b/target/linux/brcm63xx/patches-3.14/320-irqchip-add-support-for-bcm6345-style-periphery-irq-.patch
@@ -1,47 +1,72 @@
-From 4d3886359d6f6ac475e143d5f3e3b389542a0510 Mon Sep 17 00:00:00 2001
+From 7aaa70416d87434792b73077beb328202975e541 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Sun, 30 Nov 2014 14:53:12 +0100
-Subject: [PATCH 17/20] irqchip: add support for bcm6345-style l2 irq
+Subject: [PATCH 1/5] irqchip: add support for bcm6345-style periphery irq
controller
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
- .../interrupt-controller/brcm,bcm6345-l2-intc.txt | 25 ++
+ .../brcm,bcm6345-periph-intc.txt | 50 +++
drivers/irqchip/Kconfig | 4 +
drivers/irqchip/Makefile | 1 +
- drivers/irqchip/irq-bcm6345-l2.c | 320 ++++++++++++++++++++
- include/linux/irqchip/irq-bcm6345-l2-intc.h | 16 +
- 5 files changed, 366 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-l2-intc.txt
- create mode 100644 drivers/irqchip/irq-bcm6345-l2.c
- create mode 100644 include/linux/irqchip/irq-bcm6345-l2-intc.h
+ drivers/irqchip/irq-bcm6345-periph.c | 325 ++++++++++++++++++++
+ include/linux/irqchip/irq-bcm6345-periph.h | 16 +
+ 5 files changed, 396 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-periph-intc.txt
+ create mode 100644 drivers/irqchip/irq-bcm6345-periph.c
+ create mode 100644 include/linux/irqchip/irq-bcm6345-periph.h
--- /dev/null
-+++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-l2-intc.txt
-@@ -0,0 +1,25 @@
-+Broadcom BCM6345 Level 2 interrupt controller
++++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-periph-intc.txt
+@@ -0,0 +1,50 @@
++Broadcom BCM6345 Level 1 periphery interrupt controller
++
++This block is a interrupt controller that is typically connected directly
++to one of the HW INT lines on each CPU. Every BCM63XX xDSL chip since
++BCM6345 has contained this hardware.
++
++Key elements of the hardware design include:
++
++- 32, 64, or 128 incoming level IRQ lines
++
++- All onchip peripherals are wired directly to an L2 input
++
++- A separate instance of the register set for each CPU, allowing individual
++ peripheral IRQs to be routed to any CPU
++
++- No atomic mask/unmask operations
++
++- No polarity/level/edge settings
++
++- No FIFO or priority encoder logic; software is expected to read all
++ 1-4 status words to determine which IRQs are pending
+
+Required properties:
+
-+- compatible: should be "brcm,bcm6345-l2-intc"
-+- reg: specifies the base physical address and size of the registers;
-+ multiple regs may be specified, and must match the amount of parent interrupts
-+- interrupt-controller: identifies the node as an interrupt controller
-+- #interrupt-cells: specifies the number of cells needed to encode an interrupt
-+ source, should be 1
-+- interrupt-parent: specifies the phandle to the parent interrupt controller
-+ this one is cascaded from
-+- interrupts: specifies the interrupt line(s) in the interrupt-parent controller
-+ node, valid values depend on the type of parent interrupt controller
++- compatible: Should be "brcm,bcm6345-periph-intc".
++- reg: Specifies the base physical address and size of the registers.
++ Multiple register addresses may be specified, and must match the amount of
++ parent interrupts.
++- interrupt-controller: Identifies the node as an interrupt controller.
++- #interrupt-cells: Specifies the number of cells needed to encode an interrupt
++ source, should be 1.
++- interrupt-parent: Specifies the phandle to the parent interrupt controller
++ this one is cascaded from.
++- interrupts: Specifies the interrupt line(s) in the interrupt-parent controller
++ node, valid values depend on the type of parent interrupt controller.
++ Multiple lines are used to route interrupts to different cpus, with the first
++ assumed to be for the boot CPU.
+
+Example:
+
+periph_intc: interrupt-controller@f0406800 {
-+ compatible = "brcm,bcm6345-l2-intc";
-+ interrupt-parent = <&mips_intc>;
-+ #interrupt-cells = <1>;
-+ reg = <0x10000020 0x10> <0x10000030 0x10>;
++ compatible = "brcm,bcm6345-periph-intc";
++ reg = <0x10000020 0x10>, <0x10000030 0x10>;
++
+ interrupt-controller;
++ #interrupt-cells = <1>;
++
++ interrupt-parent = <&cpu_intc>;
+ interrupts = <2>, <3>;
+};
--- a/drivers/irqchip/Kconfig
@@ -50,7 +75,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
The maximum number of VICs available in the system, for
power management.
-+config BCM6345_L2_IRQ
++config BCM6345_PERIPH_IRQ
+ bool
+ select IRQ_DOMAIN
+
@@ -63,13 +88,13 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
obj-$(CONFIG_ARCH_MVEBU) += irq-armada-370-xp.o
obj-$(CONFIG_ARCH_MXS) += irq-mxs.o
obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o
-+obj-$(CONFIG_BCM6345_L2_IRQ) += irq-bcm6345-l2.o
++obj-$(CONFIG_BCM6345_PERIPH_IRQ) += irq-bcm6345-periph.o
obj-$(CONFIG_DW_APB_ICTL) += irq-dw-apb-ictl.o
obj-$(CONFIG_METAG) += irq-metag-ext.o
obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o
--- /dev/null
-+++ b/drivers/irqchip/irq-bcm6345-l2.c
-@@ -0,0 +1,320 @@
++++ b/drivers/irqchip/irq-bcm6345-periph.c
+@@ -0,0 +1,340 @@
+/*
+ * 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
@@ -81,7 +106,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
-+#include <linux/irqchip/irq-bcm6345-l2-intc.h>
++#include <linux/irqchip/irq-bcm6345-periph.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
@@ -118,10 +143,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ int num_words;
+
+ struct irq_domain *domain;
-+ spinlock_t lock;
++ raw_spinlock_t lock;
+};
+
-+static void bcm6345_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc)
++static void bcm6345_periph_irq_handle(unsigned int irq, struct irq_desc *desc)
+{
+ struct intc_data *data = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
@@ -139,20 +164,36 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ unsigned long pending;
+ int hw_irq;
+
-+ raw_spin_lock(data->lock);
++ raw_spin_lock(&data->lock);
+ pending = __raw_readl(block->en_reg[idx]) &
+ __raw_readl(block->status_reg[idx]);
-+ raw_spin_unlock(data->lock);
++ raw_spin_unlock(&data->lock);
+
+ for_each_set_bit(hw_irq, &pending, IRQS_PER_WORD) {
-+ generic_handle_irq(irq_find_mapping(data->domain, base + hw_irq));
++ int virq;
++
++ virq = irq_find_mapping(data->domain, base + hw_irq);
++ generic_handle_irq(virq);
+ }
+ }
+
+ chained_irq_exit(chip, desc);
+}
+
-+static void bcm6345_l2_intc_irq_mask(struct irq_data *data)
++static void __bcm6345_periph_enable(struct intc_block *block, int reg, int bit,
++ bool enable)
++{
++ u32 val;
++
++ val = __raw_readl(block->en_reg[reg]);
++ if (enable)
++ val |= BIT(bit);
++ else
++ val &= ~BIT(bit);
++ __raw_writel(val, block->en_reg[reg]);
++}
++
++static void bcm6345_periph_irq_mask(struct irq_data *data)
+{
+ unsigned int i, reg, bit;
+ struct intc_data *priv = data->domain->host_data;
@@ -161,58 +202,51 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ reg = hwirq / IRQS_PER_WORD;
+ bit = hwirq % IRQS_PER_WORD;
+
-+ raw_spin_lock(priv->lock);
++ raw_spin_lock(&priv->lock);
+ for (i = 0; i < MAX_PARENT_IRQS; i++) {
+ struct intc_block *block = &priv->block[i];
-+ u32 val;
+
+ if (!block->parent_irq)
+ break;
+
-+ val = __raw_readl(block->en_reg[reg]);
-+ __raw_writel(val & ~BIT(bit), block->en_reg[reg]);
++ __bcm6345_periph_enable(block, reg, bit, false);
+ }
-+ raw_spin_unlock(priv->lock);
++ raw_spin_unlock(&priv->lock);
+}
+
-+static void bcm6345_l2_intc_irq_unmask(struct irq_data *data)
++static void bcm6345_periph_irq_unmask(struct irq_data *data)
+{
-+ unsigned int i, reg, bit;
+ struct intc_data *priv = data->domain->host_data;
+ irq_hw_number_t hwirq = irqd_to_hwirq(data);
++ unsigned int i, reg, bit;
+
+ reg = hwirq / IRQS_PER_WORD;
+ bit = hwirq % IRQS_PER_WORD;
+
-+ raw_spin_lock(priv->lock);
++ raw_spin_lock(&priv->lock);
+ for (i = 0; i < MAX_PARENT_IRQS; i++) {
+ struct intc_block *block = &priv->block[i];
-+ u32 val;
+
+ if (!block->parent_irq)
+ break;
+
-+ val = __raw_readl(block->en_reg[reg]);
-+
+ if (block->mask_cache[reg] & BIT(bit))
-+ val |= BIT(bit);
++ __bcm6345_periph_enable(block, reg, bit, true);
+ else
-+ val &= ~BIT(bit);
-+
-+ __raw_writel(val, block->en_reg[reg]);
++ __bcm6345_periph_enable(block, reg, bit, false);
+
+ }
-+ raw_spin_unlock(priv->lock);
++ raw_spin_unlock(&priv->lock);
+}
+
+#ifdef CONFIG_SMP
-+static int bcm6345_l2_intc_set_affinity(struct irq_data *data,
-+ const struct cpumask *mask,
-+ bool force)
++static int bcm6345_periph_set_affinity(struct irq_data *data,
++ const struct cpumask *mask, bool force)
+{
+ irq_hw_number_t hwirq = irqd_to_hwirq(data);
+ struct intc_data *priv = data->domain->host_data;
+ unsigned int i, reg, bit;
++ bool enabled;
+ int cpu;
+
+ reg = hwirq / IRQS_PER_WORD;
@@ -231,21 +265,30 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ if (!priv->block[cpu].parent_irq)
+ return -EINVAL;
+
-+ raw_spin_lock(priv->lock);
++ raw_spin_lock(&priv->lock);
++ enabled = !irqd_irq_masked(data);
+ for (i = 0; i < MAX_PARENT_IRQS; i++) {
-+ if (i == cpu)
-+ priv->block[i].mask_cache[reg] |= BIT(bit);
-+ else
-+ priv->block[i].mask_cache[reg] &= ~BIT(bit);
++ struct intc_block *block = &priv->block[i];
++
++ if (!block->parent_irq)
++ break;
++
++ if (i == cpu) {
++ block->mask_cache[reg] |= BIT(bit);
++ __bcm6345_periph_enable(block, reg, bit, enabled);
++ } else {
++ block->mask_cache[reg] &= ~BIT(bit);
++ __bcm6345_periph_enable(block, reg, bit, false);
++ }
+ }
-+ raw_spin_unlock(priv->lock);
++ raw_spin_unlock(&priv->lock);
+
+ return 0;
+}
+#endif
+
-+static int bcm6345_l2_map(struct irq_domain *d, unsigned int irq,
-+ irq_hw_number_t hw)
++static int bcm6345_periph_map(struct irq_domain *d, unsigned int irq,
++ irq_hw_number_t hw)
+{
+ struct intc_data *priv = d->host_data;
+
@@ -254,14 +297,14 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return 0;
+}
+
-+static const struct irq_domain_ops bcm6345_l2_domain_ops = {
++static const struct irq_domain_ops bcm6345_periph_domain_ops = {
+ .xlate = irq_domain_xlate_onecell,
-+ .map = bcm6345_l2_map,
++ .map = bcm6345_periph_map,
+};
+
-+static int __init __bcm6345_l2_intc_init(struct device_node *node,
-+ int num_blocks, int *irq,
-+ void __iomem **base, int num_words)
++static int __init __bcm6345_periph_intc_init(struct device_node *node,
++ int num_blocks, int *irq,
++ void __iomem **base, int num_words)
+{
+ struct intc_data *data;
+ unsigned int i, w, status_offset;
@@ -270,6 +313,8 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ if (!data)
+ return -ENOMEM;
+
++ raw_spin_lock_init(&data->lock);
++
+ status_offset = num_words * sizeof(u32);
+
+ for (i = 0; i < num_blocks; i++) {
@@ -292,23 +337,23 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+
+ irq_set_handler_data(block->parent_irq, data);
+ irq_set_chained_handler(block->parent_irq,
-+ bcm6345_l2_intc_irq_handle);
++ bcm6345_periph_irq_handle);
+ }
+
+ data->num_words = num_words;
+
-+ data->chip.name = "bcm6345-l2-intc";
-+ data->chip.irq_mask = bcm6345_l2_intc_irq_mask;
-+ data->chip.irq_unmask = bcm6345_l2_intc_irq_unmask;
++ data->chip.name = "bcm6345-periph-intc";
++ data->chip.irq_mask = bcm6345_periph_irq_mask;
++ data->chip.irq_unmask = bcm6345_periph_irq_unmask;
+
+#ifdef CONFIG_SMP
+ if (num_blocks > 1)
-+ data->chip.set_affinity = bcm6345_l2_intc_set_affinity;
++ data->chip.irq_set_affinity = bcm6345_periph_set_affinity;
+#endif
+
+ data->domain = irq_domain_add_simple(node, IRQS_PER_WORD * num_words,
-+ VIRQ_BASE, &bcm6345_l2_domain_ops,
-+ data);
++ VIRQ_BASE,
++ &bcm6345_periph_domain_ops, data);
+ if (!data->domain) {
+ kfree(data);
+ return -EINVAL;
@@ -317,15 +362,15 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return 0;
+}
+
-+void __init bcm6345_l2_intc_init(int num_blocks, int *irq, void __iomem **base,
-+ int num_words)
++void __init bcm6345_periph_intc_init(int num_blocks, int *irq,
++ void __iomem **base, int num_words)
+{
-+ __bcm6345_l2_intc_init(NULL, num_blocks, irq, base, num_words);
++ __bcm6345_periph_intc_init(NULL, num_blocks, irq, base, num_words);
+}
+
+#ifdef CONFIG_OF
-+static int __init bcm6345_l2_intc_of_init(struct device_node *node,
-+ struct device_node *parent)
++static int __init bcm6345_periph_of_init(struct device_node *node,
++ struct device_node *parent)
+{
+ struct resource res;
+ int num_irqs, ret = -EINVAL;
@@ -374,7 +419,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ }
+ }
+
-+ ret = __bcm6345_l2_intc_init(node, num_irqs, irqs, bases, words);
++ ret = __bcm6345_periph_intc_init(node, num_irqs, irqs, bases, words);
+ if (!ret)
+ return 0;
+
@@ -387,11 +432,11 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return ret;
+}
+
-+IRQCHIP_DECLARE(bcm6345_l2_intc, "brcm,bcm6345-l2-intc",
-+ bcm6345_l2_intc_of_init);
++IRQCHIP_DECLARE(bcm6345_periph_intc, "brcm,bcm6345-periph-intc",
++ bcm6345_periph_of_init);
+#endif
--- /dev/null
-+++ b/include/linux/irqchip/irq-bcm6345-l2-intc.h
++++ b/include/linux/irqchip/irq-bcm6345-periph.h
@@ -0,0 +1,16 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
@@ -402,10 +447,40 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ * Copyright (C) 2008 Nicolas Schichan <nschichan@freebox.fr>
+ */
+
-+#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_L2_INTC_H
-+#define __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_L2_INTC_H
-+
-+void bcm6345_l2_intc_init(int num_blocks, int *irq, void __iomem **base,
-+ int num_words);
-+
-+#endif /* __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_L2_INTC_H */
++#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_PERIPH_H
++#define __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_PERIPH_H
++
++void bcm6345_periph_intc_init(int num_blocks, int *irq, void __iomem **base,
++ int num_words);
++
++#endif /* __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_PERIPH_H */
+diff --git a/drivers/irqchip/irq-bcm6345-periph.c b/drivers/irqchip/irq-bcm6345-periph.c
+index dfab88e..b280164 100644
+--- a/drivers/irqchip/irq-bcm6345-periph.c
++++ b/drivers/irqchip/irq-bcm6345-periph.c
+@@ -149,6 +149,7 @@ static int bcm6345_periph_set_affinity(struct irq_data *data,
+ irq_hw_number_t hwirq = irqd_to_hwirq(data);
+ struct intc_data *priv = data->domain->host_data;
+ unsigned int i, reg, bit;
++ unsigned long flags;
+ bool enabled;
+ int cpu;
+
+@@ -168,7 +169,7 @@ static int bcm6345_periph_set_affinity(struct irq_data *data,
+ if (!priv->block[cpu].parent_irq)
+ return -EINVAL;
+
+- raw_spin_lock(&priv->lock);
++ raw_spin_lock_irqsave(&priv->lock, flags);
+ enabled = !irqd_irq_masked(data);
+ for (i = 0; i < MAX_PARENT_IRQS; i++) {
+ struct intc_block *block = &priv->block[i];
+@@ -184,7 +185,7 @@ static int bcm6345_periph_set_affinity(struct irq_data *data,
+ __bcm6345_periph_enable(block, reg, bit, false);
+ }
+ }
+- raw_spin_unlock(&priv->lock);
++ raw_spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+ }
diff --git a/target/linux/brcm63xx/patches-3.14/321-irqchip-add-support-for-bcm6345-style-external-inter.patch b/target/linux/brcm63xx/patches-3.14/321-irqchip-add-support-for-bcm6345-style-external-inter.patch
index d53deba0ca..964d9fc60f 100644
--- a/target/linux/brcm63xx/patches-3.14/321-irqchip-add-support-for-bcm6345-style-external-inter.patch
+++ b/target/linux/brcm63xx/patches-3.14/321-irqchip-add-support-for-bcm6345-style-external-inter.patch
@@ -1,37 +1,42 @@
-From 6896b5f0538a7a7cfb7fac2d9ed3c6841c72ed40 Mon Sep 17 00:00:00 2001
+From ac60253478d58fc73b4c0a390eb6229222460e8a Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Sun, 30 Nov 2014 14:54:27 +0100
-Subject: [PATCH 18/20] irqchip: add support for bcm6345-style external
+Subject: [PATCH 2/5] irqchip: add support for bcm6345-style external
interrupt controller
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
- .../interrupt-controller/brcm,bcm6345-ext-intc.txt | 24 ++
+ .../interrupt-controller/brcm,bcm6345-ext-intc.txt | 29 ++
drivers/irqchip/Kconfig | 4 +
drivers/irqchip/Makefile | 1 +
- drivers/irqchip/irq-bcm6345-ext.c | 296 ++++++++++++++++++++
- include/linux/irqchip/irq-bcm6345-ext-intc.h | 14 +
- 5 files changed, 339 insertions(+)
+ drivers/irqchip/irq-bcm6345-ext.c | 286 ++++++++++++++++++++
+ include/linux/irqchip/irq-bcm6345-ext.h | 14 +
+ 5 files changed, 334 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-ext-intc.txt
create mode 100644 drivers/irqchip/irq-bcm6345-ext.c
- create mode 100644 include/linux/irqchip/irq-bcm6345-ext-intc.h
+ create mode 100644 include/linux/irqchip/irq-bcm6345-ext.h
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-ext-intc.txt
-@@ -0,0 +1,24 @@
+@@ -0,0 +1,29 @@
+Broadcom BCM6345-style external interrupt controller
+
+Required properties:
+
-+- compatible: should be "brcm,bcm6345-l2-intc" or "brcm,bcm6345-l2-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
-+ source, should be 2
-+- interrupt-parent: specifies the phandle to the parent interrupt controller
-+ this one is cascaded from
-+- interrupts: specifies the interrupt line(s) in the interrupt-parent controller
-+ node, valid values depend on the type of parent interrupt controller
++- compatible: Should be "brcm,bcm6345-l2-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
++ source, Should be 2.
++- interrupt-parent: Specifies the phandle to the parent interrupt controller
++ this one is cascaded from.
++- interrupts: Specifies the interrupt line(s) in the interrupt-parent controller
++ node, valid values depend on the type of parent interrupt controller.
++
++Optional properties:
++
++- brcm,field-width: Size of each field (mask, clear, sense, ...) in bits in the
++ register. Defaults to 4.
+
+Example:
+
@@ -53,7 +58,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ bool
+ select IRQ_DOMAIN
+
- config BCM6345_L2_IRQ
+ config BCM6345_PERIPH_IRQ
bool
select IRQ_DOMAIN
--- a/drivers/irqchip/Makefile
@@ -63,12 +68,12 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
obj-$(CONFIG_ARCH_MXS) += irq-mxs.o
obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o
+obj-$(CONFIG_BCM6345_EXT_IRQ) += irq-bcm6345-ext.o
- obj-$(CONFIG_BCM6345_L2_IRQ) += irq-bcm6345-l2.o
+ obj-$(CONFIG_BCM6345_PERIPH_IRQ) += irq-bcm6345-periph.o
obj-$(CONFIG_DW_APB_ICTL) += irq-dw-apb-ictl.o
obj-$(CONFIG_METAG) += irq-metag-ext.o
--- /dev/null
+++ b/drivers/irqchip/irq-bcm6345-ext.c
-@@ -0,0 +1,296 @@
+@@ -0,0 +1,288 @@
+/*
+ * 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
@@ -80,7 +85,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
-+#include <linux/irqchip/irq-bcm6345-ext-intc.h>
++#include <linux/irqchip/irq-bcm6345-ext.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
@@ -110,7 +115,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+struct intc_data {
+ struct irq_chip chip;
+ struct irq_domain *domain;
-+ spinlock_t lock;
++ raw_spinlock_t lock;
+
+ int parent_irq[MAX_IRQS];
+ void __iomem *reg;
@@ -141,11 +146,11 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ irq_hw_number_t hwirq = irqd_to_hwirq(data);
+ u32 reg;
+
-+ raw_spin_lock(priv->lock);
++ raw_spin_lock(&priv->lock);
+ reg = __raw_readl(priv->reg);
+ reg |= hwirq << (EXTIRQ_CFG_CLEAR * priv->shift);
+ __raw_writel(reg, priv->reg);
-+ raw_spin_unlock(priv->lock);
++ raw_spin_unlock(&priv->lock);
+}
+
+static void bcm6345_ext_intc_irq_mask(struct irq_data *data)
@@ -154,11 +159,11 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ irq_hw_number_t hwirq = irqd_to_hwirq(data);
+ u32 reg;
+
-+ raw_spin_lock(priv->lock);
++ raw_spin_lock(&priv->lock);
+ reg = __raw_readl(priv->reg);
+ reg &= ~(hwirq << (EXTIRQ_CFG_MASK * priv->shift));
+ __raw_writel(reg, priv->reg);
-+ raw_spin_unlock(priv->lock);
++ raw_spin_unlock(&priv->lock);
+}
+
+static void bcm6345_ext_intc_irq_unmask(struct irq_data *data)
@@ -167,11 +172,11 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ irq_hw_number_t hwirq = irqd_to_hwirq(data);
+ u32 reg;
+
-+ raw_spin_lock(priv->lock);
++ raw_spin_lock(&priv->lock);
+ reg = __raw_readl(priv->reg);
+ reg |= hwirq << (EXTIRQ_CFG_MASK * priv->shift);
+ __raw_writel(reg, priv->reg);
-+ raw_spin_unlock(priv->lock);
++ raw_spin_unlock(&priv->lock);
+}
+
+static int bcm6345_ext_intc_set_type(struct irq_data *data,
@@ -213,7 +218,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return -EINVAL;
+ }
+
-+ raw_spin_lock(priv->lock);
++ raw_spin_lock(&priv->lock);
+ reg = __raw_readl(priv->reg);
+
+ if (levelsense)
@@ -230,7 +235,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ reg &= ~(hwirq << (EXTIRQ_CFG_BOTHEDGE * priv->shift));
+
+ __raw_writel(reg, priv->reg);
-+ raw_spin_unlock(priv->lock);
++ raw_spin_unlock(&priv->lock);
+
+ irqd_set_trigger_type(data, flow_type);
+ if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
@@ -269,6 +274,8 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ if (!data)
+ return -ENOMEM;
+
++ raw_spin_lock_init(&data->lock);
++
+ for (i = 0; i < num_irqs; i++) {
+ data->parent_irq[i] = irqs[i];
+
@@ -311,20 +318,23 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+}
+
+#ifdef CONFIG_OF
-+static int __init bcm63xx_ext_intc_of_init(struct device_node *node,
-+ struct device_node *parent,
-+ int shift)
++static int __init bcm6345_ext_intc_of_init(struct device_node *node,
++ struct device_node *parent)
+{
+ int num_irqs, ret = -EINVAL;
+ unsigned i;
+ void __iomem *base;
+ int irqs[MAX_IRQS] = { 0 };
++ u32 shift;
+
+ num_irqs = of_irq_count(node);
+
+ if (!num_irqs || num_irqs > MAX_IRQS)
+ return -EINVAL;
+
++ if (of_property_read_u32(node, "brcm,field-width", &shift))
++ shift = 4;
++
+ for (i = 0; i < num_irqs; i++) {
+ irqs[i] = irq_of_parse_and_map(node, i);
+ if (!irqs[i]) {
@@ -349,24 +359,11 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return ret;
+}
+
-+static int __init bcm6345_ext_intc_of_init(struct device_node *node,
-+ struct device_node *parent)
-+{
-+ return bcm63xx_ext_intc_of_init(node, parent, 4);
-+}
-+static int __init bcm6348_ext_intc_of_init(struct device_node *node,
-+ struct device_node *parent)
-+{
-+ return bcm63xx_ext_intc_of_init(node, parent, 5);
-+}
-+
+IRQCHIP_DECLARE(bcm6345_ext_intc, "brcm,bcm6345-ext-intc",
+ bcm6345_ext_intc_of_init);
-+IRQCHIP_DECLARE(bcm6348_ext_intc, "brcm,bcm6348-ext-intc",
-+ bcm6348_ext_intc_of_init);
+#endif
--- /dev/null
-+++ b/include/linux/irqchip/irq-bcm6345-ext-intc.h
++++ b/include/linux/irqchip/irq-bcm6345-ext.h
@@ -0,0 +1,14 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
@@ -376,9 +373,9 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ * Copyright (C) 2014 Jonas Gorski <jogo@openwrt.org>
+ */
+
-+#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_INTC_H
-+#define __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_INTC_H
++#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_H
++#define __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_H
+
+void bcm6345_ext_intc_init(int n_irqs, int *irqs, void __iomem *reg, int shift);
+
-+#endif /* __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_INTC_H */
++#endif /* __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_H */
diff --git a/target/linux/brcm63xx/patches-3.14/322-MIPS-BCM63XX-switch-to-IRQ_DOMAIN.patch b/target/linux/brcm63xx/patches-3.14/322-MIPS-BCM63XX-switch-to-IRQ_DOMAIN.patch
index 63384773ea..7f3682c417 100644
--- a/target/linux/brcm63xx/patches-3.14/322-MIPS-BCM63XX-switch-to-IRQ_DOMAIN.patch
+++ b/target/linux/brcm63xx/patches-3.14/322-MIPS-BCM63XX-switch-to-IRQ_DOMAIN.patch
@@ -19,7 +19,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
select DMA_NONCOHERENT
select IRQ_CPU
+ select BCM6345_EXT_IRQ
-+ select BCM6345_L2_IRQ
++ select BCM6345_PERIPH_IRQ
+ select IRQ_DOMAIN
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
@@ -32,8 +32,8 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
#include <linux/irq.h>
-#include <linux/spinlock.h>
+#include <linux/irqchip.h>
-+#include <linux/irqchip/irq-bcm6345-ext-intc.h>
-+#include <linux/irqchip/irq-bcm6345-l2-intc.h>
++#include <linux/irqchip/irq-bcm6345-ext.h>
++#include <linux/irqchip/irq-bcm6345-periph.h>
#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
#include <bcm63xx_cpu.h>
@@ -449,14 +449,14 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- irq_mask_addr[0] = bcm63xx_regset_address(RSET_PERF);
- irq_stat_addr[1] = bcm63xx_regset_address(RSET_PERF);
- irq_mask_addr[1] = bcm63xx_regset_address(RSET_PERF);
-+ void __iomem *l2_intc_bases[2];
++ void __iomem *periph_bases[2];
+ void __iomem *ext_intc_bases[2];
-+ int l2_irq_count, l2_width, ext_irq_count, ext_shift;
-+ int l2_irqs[2] = { 2, 3 };
++ int periph_irq_count, periph_width, ext_irq_count, ext_shift;
++ int periph_irqs[2] = { 2, 3 };
+ int ext_irqs[6];
+
-+ l2_intc_bases[0] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
-+ l2_intc_bases[1] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
++ periph_bases[0] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
++ periph_bases[1] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
+ ext_intc_bases[0] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
+ ext_intc_bases[1] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
@@ -469,9 +469,9 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- irq_bits = 32;
- ext_irq_count = 4;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_3368;
-+ l2_intc_bases[0] += PERF_IRQMASK_3368_REG;
-+ l2_irq_count = 1;
-+ l2_width = 1;
++ periph_bases[0] += PERF_IRQMASK_3368_REG;
++ periph_irq_count = 1;
++ periph_width = 1;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_3368;
+ ext_irq_count = 4;
@@ -492,10 +492,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- ext_irq_start = BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE;
- ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328;
-+ l2_intc_bases[0] += PERF_IRQMASK_6328_REG(0);
-+ l2_intc_bases[1] += PERF_IRQMASK_6328_REG(1);
-+ l2_irq_count = 2;
-+ l2_width = 2;
++ periph_bases[0] += PERF_IRQMASK_6328_REG(0);
++ periph_bases[1] += PERF_IRQMASK_6328_REG(1);
++ periph_irq_count = 2;
++ periph_width = 2;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6328;
+ ext_irq_count = 4;
@@ -513,9 +513,9 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- irq_bits = 32;
- ext_irq_count = 4;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6338;
-+ l2_intc_bases[0] += PERF_IRQMASK_6338_REG;
-+ l2_irq_count = 1;
-+ l2_width = 1;
++ periph_bases[0] += PERF_IRQMASK_6338_REG;
++ periph_irq_count = 1;
++ periph_width = 1;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6338;
+ ext_irq_count = 4;
@@ -533,9 +533,9 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- irq_bits = 32;
- ext_irq_count = 4;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6345;
-+ l2_intc_bases[0] += PERF_IRQMASK_6345_REG;
-+ l2_irq_count = 1;
-+ l2_width = 1;
++ periph_bases[0] += PERF_IRQMASK_6345_REG;
++ periph_irq_count = 1;
++ periph_width = 1;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6345;
+ ext_irq_count = 4;
@@ -553,9 +553,9 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- irq_bits = 32;
- ext_irq_count = 4;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6348;
-+ l2_intc_bases[0] += PERF_IRQMASK_6348_REG;
-+ l2_irq_count = 1;
-+ l2_width = 1;
++ periph_bases[0] += PERF_IRQMASK_6348_REG;
++ periph_irq_count = 1;
++ periph_width = 1;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6348;
+ ext_irq_count = 4;
@@ -576,10 +576,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- ext_irq_start = BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE;
- ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6358;
-+ l2_intc_bases[0] += PERF_IRQMASK_6358_REG(0);
-+ l2_intc_bases[1] += PERF_IRQMASK_6358_REG(1);
-+ l2_irq_count = 2;
-+ l2_width = 1;
++ periph_bases[0] += PERF_IRQMASK_6358_REG(0);
++ periph_bases[1] += PERF_IRQMASK_6358_REG(1);
++ periph_irq_count = 2;
++ periph_width = 1;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6358;
+ ext_irq_count = 4;
@@ -600,10 +600,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- ext_irq_start = BCM_6362_EXT_IRQ0 - IRQ_INTERNAL_BASE;
- ext_irq_end = BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6362;
-+ l2_intc_bases[0] += PERF_IRQMASK_6362_REG(0);
-+ l2_intc_bases[1] += PERF_IRQMASK_6362_REG(1);
-+ l2_irq_count = 2;
-+ l2_width = 2;
++ periph_bases[0] += PERF_IRQMASK_6362_REG(0);
++ periph_bases[1] += PERF_IRQMASK_6362_REG(1);
++ periph_irq_count = 2;
++ periph_width = 2;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6362;
+ ext_irq_count = 4;
@@ -619,10 +619,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- irq_stat_addr[1] += PERF_IRQSTAT_6368_REG(1);
- irq_mask_addr[1] += PERF_IRQMASK_6368_REG(1);
- irq_bits = 64;
-+ l2_intc_bases[0] += PERF_IRQMASK_6368_REG(0);
-+ l2_intc_bases[1] += PERF_IRQMASK_6368_REG(1);
-+ l2_irq_count = 2;
-+ l2_width = 2;
++ periph_bases[0] += PERF_IRQMASK_6368_REG(0);
++ periph_bases[1] += PERF_IRQMASK_6368_REG(1);
++ periph_irq_count = 2;
++ periph_width = 2;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6368;
+ ext_intc_bases[1] += PERF_EXTIRQ_CFG_REG2_6368;
@@ -654,7 +654,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- internal_irq_unmask = __internal_irq_unmask_64;
- }
+ mips_cpu_irq_init();
-+ bcm6345_l2_intc_init(l2_irq_count, l2_irqs, l2_intc_bases, l2_width);
++ bcm6345_periph_intc_init(periph_irq_count, periph_irqs, periph_bases, periph_width);
+ bcm6345_ext_intc_init(4, ext_irqs, ext_intc_bases[0], ext_shift);
+ if (ext_irq_count > 4)
+ bcm6345_ext_intc_init(2, &ext_irqs[4], ext_intc_bases[1],
diff --git a/target/linux/brcm63xx/patches-3.14/323-MIPS-BCM63XX-wire-up-BCM6358-s-external-interrupts-4.patch b/target/linux/brcm63xx/patches-3.14/323-MIPS-BCM63XX-wire-up-BCM6358-s-external-interrupts-4.patch
index fac3d5c764..5d7371ccf9 100644
--- a/target/linux/brcm63xx/patches-3.14/323-MIPS-BCM63XX-wire-up-BCM6358-s-external-interrupts-4.patch
+++ b/target/linux/brcm63xx/patches-3.14/323-MIPS-BCM63XX-wire-up-BCM6358-s-external-interrupts-4.patch
@@ -1,7 +1,7 @@
-From e3c68bbba30b212326fb69bf64b2220750dead3e Mon Sep 17 00:00:00 2001
+From fc8b863c38be9b2ccf805dd5ae17dbffb6bfbe87 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Sun, 30 Nov 2014 20:20:30 +0100
-Subject: [PATCH 20/20] MIPS: BCM63XX: wire up BCM6358's external interrupts 4
+Subject: [PATCH 4/5] MIPS: BCM63XX: wire up BCM6358's external interrupts 4
and 5
Due to the external interrupts being non consecutive, the previous
@@ -19,7 +19,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -109,11 +109,14 @@ static void bcm63xx_init_irq(void)
- l2_width = 1;
+ periph_width = 1;
ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6358;
- ext_irq_count = 4;
diff --git a/target/linux/brcm63xx/patches-3.14/339-MIPS-BCM63XX-add-support-for-BCM63268.patch b/target/linux/brcm63xx/patches-3.14/339-MIPS-BCM63XX-add-support-for-BCM63268.patch
index 7dd5e083d8..4d29f6f2d3 100644
--- a/target/linux/brcm63xx/patches-3.14/339-MIPS-BCM63XX-add-support-for-BCM63268.patch
+++ b/target/linux/brcm63xx/patches-3.14/339-MIPS-BCM63XX-add-support-for-BCM63268.patch
@@ -289,10 +289,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
ext_shift = 4;
break;
+ case BCM63268_CPU_ID:
-+ l2_intc_bases[0] += PERF_IRQSTAT_63268_REG(0);
-+ l2_intc_bases[1] += PERF_IRQSTAT_63268_REG(1);
-+ l2_irq_count = 2;
-+ l2_width = 4;
++ periph_bases[0] += PERF_IRQSTAT_63268_REG(0);
++ periph_bases[1] += PERF_IRQSTAT_63268_REG(1);
++ periph_irq_count = 2;
++ periph_width = 4;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_63268;
+ ext_irq_count = 4;
diff --git a/target/linux/brcm63xx/patches-3.14/341-MIPS-BCM63XX-add-support-for-BCM6318.patch b/target/linux/brcm63xx/patches-3.14/341-MIPS-BCM63XX-add-support-for-BCM6318.patch
index be7264c3cb..7d9578bfcb 100644
--- a/target/linux/brcm63xx/patches-3.14/341-MIPS-BCM63XX-add-support-for-BCM6318.patch
+++ b/target/linux/brcm63xx/patches-3.14/341-MIPS-BCM63XX-add-support-for-BCM6318.patch
@@ -199,9 +199,9 @@ Subject: [PATCH 51/53] MIPS: BCM63XX: add support for BCM6318
ext_shift = 4;
break;
+ case BCM6318_CPU_ID:
-+ l2_intc_bases[0] += PERF_IRQMASK_6318_REG;
-+ l2_irq_count = 1;
-+ l2_width = 4;
++ periph_bases[0] += PERF_IRQMASK_6318_REG;
++ periph_irq_count = 1;
++ periph_width = 4;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6318;
+ ext_irq_count = 4;
@@ -212,8 +212,8 @@ Subject: [PATCH 51/53] MIPS: BCM63XX: add support for BCM6318
+ ext_shift = 4;
+ break;
case BCM6328_CPU_ID:
- l2_intc_bases[0] += PERF_IRQMASK_6328_REG(0);
- l2_intc_bases[1] += PERF_IRQMASK_6328_REG(1);
+ periph_bases[0] += PERF_IRQMASK_6328_REG(0);
+ periph_bases[1] += PERF_IRQMASK_6328_REG(1);
--- a/arch/mips/bcm63xx/prom.c
+++ b/arch/mips/bcm63xx/prom.c
@@ -72,7 +72,7 @@ void __init prom_init(void)
diff --git a/target/linux/brcm63xx/patches-3.14/373-MIPS-BCM63XX-register-interrupt-controllers-through-.patch b/target/linux/brcm63xx/patches-3.14/373-MIPS-BCM63XX-register-interrupt-controllers-through-.patch
index 5a74ddb839..c8c212b08f 100644
--- a/target/linux/brcm63xx/patches-3.14/373-MIPS-BCM63XX-register-interrupt-controllers-through-.patch
+++ b/target/linux/brcm63xx/patches-3.14/373-MIPS-BCM63XX-register-interrupt-controllers-through-.patch
@@ -1,25 +1,25 @@
-From 7c22b08baba941a8c83072047b0d2b55a6b952aa Mon Sep 17 00:00:00 2001
+From 40c0e6e4f68ce0c759eb216b44cdfbe18de328b0 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Mon, 1 Dec 2014 00:20:07 +0100
-Subject: [PATCH] MIPS: BCM63XX: register interrupt controllers through DT
+Subject: [PATCH 5/5] MIPS: BCM63XX: register interrupt controllers through DT
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
- arch/mips/bcm63xx/irq.c | 10 +++++++++-
- 1 file changed, 9 insertions(+), 1 deletion(-)
+ arch/mips/bcm63xx/irq.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -15,6 +15,8 @@
#include <linux/irqchip.h>
- #include <linux/irqchip/irq-bcm6345-ext-intc.h>
- #include <linux/irqchip/irq-bcm6345-l2-intc.h>
+ #include <linux/irqchip/irq-bcm6345-ext.h>
+ #include <linux/irqchip/irq-bcm6345-periph.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
#include <bcm63xx_cpu.h>
-@@ -189,7 +191,15 @@ static void bcm63xx_init_irq(void)
+@@ -189,7 +191,17 @@ static void bcm63xx_init_irq(void)
ext_shift);
}
@@ -31,8 +31,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
void __init arch_init_irq(void)
{
- bcm63xx_init_irq();
++#ifdef CONFIG_OF
+ if (initial_boot_params)
+ irqchip_init();
+ else
++#endif
+ bcm63xx_init_irq();
}
diff --git a/target/linux/brcm63xx/patches-3.18/320-irqchip-add-support-for-bcm6345-style-l2-irq-control.patch b/target/linux/brcm63xx/patches-3.18/320-irqchip-add-support-for-bcm6345-style-periphery-irq-.patch
index c709394b35..11eedf9b93 100644
--- a/target/linux/brcm63xx/patches-3.18/320-irqchip-add-support-for-bcm6345-style-l2-irq-control.patch
+++ b/target/linux/brcm63xx/patches-3.18/320-irqchip-add-support-for-bcm6345-style-periphery-irq-.patch
@@ -1,47 +1,72 @@
-From 4d3886359d6f6ac475e143d5f3e3b389542a0510 Mon Sep 17 00:00:00 2001
+From 301744ecbeece89ab3a9d6beef7802fa22598f00 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Sun, 30 Nov 2014 14:53:12 +0100
-Subject: [PATCH 17/20] irqchip: add support for bcm6345-style l2 irq
+Subject: [PATCH 1/5] irqchip: add support for bcm6345-style periphery irq
controller
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
- .../interrupt-controller/brcm,bcm6345-l2-intc.txt | 25 ++
+ .../brcm,bcm6345-periph-intc.txt | 50 +++
drivers/irqchip/Kconfig | 4 +
drivers/irqchip/Makefile | 1 +
- drivers/irqchip/irq-bcm6345-l2.c | 320 ++++++++++++++++++++
- include/linux/irqchip/irq-bcm6345-l2-intc.h | 16 +
- 5 files changed, 366 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-l2-intc.txt
- create mode 100644 drivers/irqchip/irq-bcm6345-l2.c
- create mode 100644 include/linux/irqchip/irq-bcm6345-l2-intc.h
+ drivers/irqchip/irq-bcm6345-periph.c | 339 ++++++++++++++++++++
+ include/linux/irqchip/irq-bcm6345-periph.h | 16 +
+ 5 files changed, 410 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-periph-intc.txt
+ create mode 100644 drivers/irqchip/irq-bcm6345-periph.c
+ create mode 100644 include/linux/irqchip/irq-bcm6345-periph.h
--- /dev/null
-+++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-l2-intc.txt
-@@ -0,0 +1,25 @@
-+Broadcom BCM6345 Level 2 interrupt controller
++++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-periph-intc.txt
+@@ -0,0 +1,50 @@
++Broadcom BCM6345 Level 1 periphery interrupt controller
++
++This block is a interrupt controller that is typically connected directly
++to one of the HW INT lines on each CPU. Every BCM63XX xDSL chip since
++BCM6345 has contained this hardware.
++
++Key elements of the hardware design include:
++
++- 32, 64, or 128 incoming level IRQ lines
++
++- All onchip peripherals are wired directly to an L2 input
++
++- A separate instance of the register set for each CPU, allowing individual
++ peripheral IRQs to be routed to any CPU
++
++- No atomic mask/unmask operations
++
++- No polarity/level/edge settings
++
++- No FIFO or priority encoder logic; software is expected to read all
++ 1-4 status words to determine which IRQs are pending
+
+Required properties:
+
-+- compatible: should be "brcm,bcm6345-l2-intc"
-+- reg: specifies the base physical address and size of the registers;
-+ multiple regs may be specified, and must match the amount of parent interrupts
-+- interrupt-controller: identifies the node as an interrupt controller
-+- #interrupt-cells: specifies the number of cells needed to encode an interrupt
-+ source, should be 1
-+- interrupt-parent: specifies the phandle to the parent interrupt controller
-+ this one is cascaded from
-+- interrupts: specifies the interrupt line(s) in the interrupt-parent controller
-+ node, valid values depend on the type of parent interrupt controller
++- compatible: Should be "brcm,bcm6345-periph-intc".
++- reg: Specifies the base physical address and size of the registers.
++ Multiple register addresses may be specified, and must match the amount of
++ parent interrupts.
++- interrupt-controller: Identifies the node as an interrupt controller.
++- #interrupt-cells: Specifies the number of cells needed to encode an interrupt
++ source, should be 1.
++- interrupt-parent: Specifies the phandle to the parent interrupt controller
++ this one is cascaded from.
++- interrupts: Specifies the interrupt line(s) in the interrupt-parent controller
++ node, valid values depend on the type of parent interrupt controller.
++ Multiple lines are used to route interrupts to different cpus, with the first
++ assumed to be for the boot CPU.
+
+Example:
+
+periph_intc: interrupt-controller@f0406800 {
-+ compatible = "brcm,bcm6345-l2-intc";
-+ interrupt-parent = <&mips_intc>;
-+ #interrupt-cells = <1>;
-+ reg = <0x10000020 0x10> <0x10000030 0x10>;
++ compatible = "brcm,bcm6345-periph-intc";
++ reg = <0x10000020 0x10>, <0x10000030 0x10>;
++
+ interrupt-controller;
++ #interrupt-cells = <1>;
++
++ interrupt-parent = <&cpu_intc>;
+ interrupts = <2>, <3>;
+};
--- a/drivers/irqchip/Kconfig
@@ -50,7 +75,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
-+config BCM6345_L2_IRQ
++config BCM6345_PERIPH_IRQ
+ bool
+ select IRQ_DOMAIN
+
@@ -63,13 +88,13 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
obj-$(CONFIG_ARCH_MVEBU) += irq-armada-370-xp.o
obj-$(CONFIG_ARCH_MXS) += irq-mxs.o
obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o
-+obj-$(CONFIG_BCM6345_L2_IRQ) += irq-bcm6345-l2.o
++obj-$(CONFIG_BCM6345_PERIPH_IRQ) += irq-bcm6345-periph.o
obj-$(CONFIG_DW_APB_ICTL) += irq-dw-apb-ictl.o
obj-$(CONFIG_METAG) += irq-metag-ext.o
obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o
--- /dev/null
-+++ b/drivers/irqchip/irq-bcm6345-l2.c
-@@ -0,0 +1,320 @@
++++ b/drivers/irqchip/irq-bcm6345-periph.c
+@@ -0,0 +1,339 @@
+/*
+ * 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
@@ -81,7 +106,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
-+#include <linux/irqchip/irq-bcm6345-l2-intc.h>
++#include <linux/irqchip/irq-bcm6345-periph.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
@@ -118,10 +143,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ int num_words;
+
+ struct irq_domain *domain;
-+ spinlock_t lock;
++ raw_spinlock_t lock;
+};
+
-+static void bcm6345_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc)
++static void bcm6345_periph_irq_handle(unsigned int irq, struct irq_desc *desc)
+{
+ struct intc_data *data = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
@@ -139,20 +164,36 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ unsigned long pending;
+ int hw_irq;
+
-+ raw_spin_lock(data->lock);
++ raw_spin_lock(&data->lock);
+ pending = __raw_readl(block->en_reg[idx]) &
+ __raw_readl(block->status_reg[idx]);
-+ raw_spin_unlock(data->lock);
++ raw_spin_unlock(&data->lock);
+
+ for_each_set_bit(hw_irq, &pending, IRQS_PER_WORD) {
-+ generic_handle_irq(irq_find_mapping(data->domain, base + hw_irq));
++ int virq;
++
++ virq = irq_find_mapping(data->domain, base + hw_irq);
++ generic_handle_irq(virq);
+ }
+ }
+
+ chained_irq_exit(chip, desc);
+}
+
-+static void bcm6345_l2_intc_irq_mask(struct irq_data *data)
++static void __bcm6345_periph_enable(struct intc_block *block, int reg, int bit,
++ bool enable)
++{
++ u32 val;
++
++ val = __raw_readl(block->en_reg[reg]);
++ if (enable)
++ val |= BIT(bit);
++ else
++ val &= ~BIT(bit);
++ __raw_writel(val, block->en_reg[reg]);
++}
++
++static void bcm6345_periph_irq_mask(struct irq_data *data)
+{
+ unsigned int i, reg, bit;
+ struct intc_data *priv = data->domain->host_data;
@@ -161,58 +202,51 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ reg = hwirq / IRQS_PER_WORD;
+ bit = hwirq % IRQS_PER_WORD;
+
-+ raw_spin_lock(priv->lock);
++ raw_spin_lock(&priv->lock);
+ for (i = 0; i < MAX_PARENT_IRQS; i++) {
+ struct intc_block *block = &priv->block[i];
-+ u32 val;
+
+ if (!block->parent_irq)
+ break;
+
-+ val = __raw_readl(block->en_reg[reg]);
-+ __raw_writel(val & ~BIT(bit), block->en_reg[reg]);
++ __bcm6345_periph_enable(block, reg, bit, false);
+ }
-+ raw_spin_unlock(priv->lock);
++ raw_spin_unlock(&priv->lock);
+}
+
-+static void bcm6345_l2_intc_irq_unmask(struct irq_data *data)
++static void bcm6345_periph_irq_unmask(struct irq_data *data)
+{
-+ unsigned int i, reg, bit;
+ struct intc_data *priv = data->domain->host_data;
+ irq_hw_number_t hwirq = irqd_to_hwirq(data);
++ unsigned int i, reg, bit;
+
+ reg = hwirq / IRQS_PER_WORD;
+ bit = hwirq % IRQS_PER_WORD;
+
-+ raw_spin_lock(priv->lock);
++ raw_spin_lock(&priv->lock);
+ for (i = 0; i < MAX_PARENT_IRQS; i++) {
+ struct intc_block *block = &priv->block[i];
-+ u32 val;
+
+ if (!block->parent_irq)
+ break;
+
-+ val = __raw_readl(block->en_reg[reg]);
-+
+ if (block->mask_cache[reg] & BIT(bit))
-+ val |= BIT(bit);
++ __bcm6345_periph_enable(block, reg, bit, true);
+ else
-+ val &= ~BIT(bit);
-+
-+ __raw_writel(val, block->en_reg[reg]);
-+
++ __bcm6345_periph_enable(block, reg, bit, false);
+ }
-+ raw_spin_unlock(priv->lock);
++ raw_spin_unlock(&priv->lock);
+}
+
+#ifdef CONFIG_SMP
-+static int bcm6345_l2_intc_set_affinity(struct irq_data *data,
-+ const struct cpumask *mask,
-+ bool force)
++static int bcm6345_periph_set_affinity(struct irq_data *data,
++ const struct cpumask *mask, bool force)
+{
+ irq_hw_number_t hwirq = irqd_to_hwirq(data);
+ struct intc_data *priv = data->domain->host_data;
+ unsigned int i, reg, bit;
++ unsigned long flags;
++ bool enabled;
+ int cpu;
+
+ reg = hwirq / IRQS_PER_WORD;
@@ -231,21 +265,30 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ if (!priv->block[cpu].parent_irq)
+ return -EINVAL;
+
-+ raw_spin_lock(priv->lock);
++ raw_spin_lock_irqsave(&priv->lock, flags);
++ enabled = !irqd_irq_masked(data);
+ for (i = 0; i < MAX_PARENT_IRQS; i++) {
-+ if (i == cpu)
-+ priv->block[i].mask_cache[reg] |= BIT(bit);
-+ else
-+ priv->block[i].mask_cache[reg] &= ~BIT(bit);
++ struct intc_block *block = &priv->block[i];
++
++ if (!block->parent_irq)
++ break;
++
++ if (i == cpu) {
++ block->mask_cache[reg] |= BIT(bit);
++ __bcm6345_periph_enable(block, reg, bit, enabled);
++ } else {
++ block->mask_cache[reg] &= ~BIT(bit);
++ __bcm6345_periph_enable(block, reg, bit, false);
++ }
+ }
-+ raw_spin_unlock(priv->lock);
++ raw_spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+#endif
+
-+static int bcm6345_l2_map(struct irq_domain *d, unsigned int irq,
-+ irq_hw_number_t hw)
++static int bcm6345_periph_map(struct irq_domain *d, unsigned int irq,
++ irq_hw_number_t hw)
+{
+ struct intc_data *priv = d->host_data;
+
@@ -254,14 +297,14 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return 0;
+}
+
-+static const struct irq_domain_ops bcm6345_l2_domain_ops = {
++static const struct irq_domain_ops bcm6345_periph_domain_ops = {
+ .xlate = irq_domain_xlate_onecell,
-+ .map = bcm6345_l2_map,
++ .map = bcm6345_periph_map,
+};
+
-+static int __init __bcm6345_l2_intc_init(struct device_node *node,
-+ int num_blocks, int *irq,
-+ void __iomem **base, int num_words)
++static int __init __bcm6345_periph_intc_init(struct device_node *node,
++ int num_blocks, int *irq,
++ void __iomem **base, int num_words)
+{
+ struct intc_data *data;
+ unsigned int i, w, status_offset;
@@ -270,6 +313,8 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ if (!data)
+ return -ENOMEM;
+
++ raw_spin_lock_init(&data->lock);
++
+ status_offset = num_words * sizeof(u32);
+
+ for (i = 0; i < num_blocks; i++) {
@@ -285,30 +330,30 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ block->status_reg[w] = base[i] + status_offset;
+ block->status_reg[w] += word_offset;
+
-+ /* route all interrups to line 0 by default */
++ /* route all interrupts to line 0 by default */
+ if (i == 0)
+ block->mask_cache[w] = 0xffffffff;
+ }
+
+ irq_set_handler_data(block->parent_irq, data);
+ irq_set_chained_handler(block->parent_irq,
-+ bcm6345_l2_intc_irq_handle);
++ bcm6345_periph_irq_handle);
+ }
+
+ data->num_words = num_words;
+
-+ data->chip.name = "bcm6345-l2-intc";
-+ data->chip.irq_mask = bcm6345_l2_intc_irq_mask;
-+ data->chip.irq_unmask = bcm6345_l2_intc_irq_unmask;
++ data->chip.name = "bcm6345-periph-intc";
++ data->chip.irq_mask = bcm6345_periph_irq_mask;
++ data->chip.irq_unmask = bcm6345_periph_irq_unmask;
+
+#ifdef CONFIG_SMP
+ if (num_blocks > 1)
-+ data->chip.set_affinity = bcm6345_l2_intc_set_affinity;
++ data->chip.irq_set_affinity = bcm6345_periph_set_affinity;
+#endif
+
+ data->domain = irq_domain_add_simple(node, IRQS_PER_WORD * num_words,
-+ VIRQ_BASE, &bcm6345_l2_domain_ops,
-+ data);
++ VIRQ_BASE,
++ &bcm6345_periph_domain_ops, data);
+ if (!data->domain) {
+ kfree(data);
+ return -EINVAL;
@@ -317,15 +362,15 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return 0;
+}
+
-+void __init bcm6345_l2_intc_init(int num_blocks, int *irq, void __iomem **base,
-+ int num_words)
++void __init bcm6345_periph_intc_init(int num_blocks, int *irq,
++ void __iomem **base, int num_words)
+{
-+ __bcm6345_l2_intc_init(NULL, num_blocks, irq, base, num_words);
++ __bcm6345_periph_intc_init(NULL, num_blocks, irq, base, num_words);
+}
+
+#ifdef CONFIG_OF
-+static int __init bcm6345_l2_intc_of_init(struct device_node *node,
-+ struct device_node *parent)
++static int __init bcm6345_periph_of_init(struct device_node *node,
++ struct device_node *parent)
+{
+ struct resource res;
+ int num_irqs, ret = -EINVAL;
@@ -346,19 +391,18 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ if (!irqs[i])
+ goto out_unmap;
+
-+ if (of_address_to_resource(node, i, &res)) {
++ if (of_address_to_resource(node, i, &res))
+ goto out_unmap;
-+ }
+
+ size = resource_size(&res);
+ switch (size) {
-+ case 8:
-+ case 16:
-+ case 32:
-+ size = size / 8;
-+ break;
-+ default:
-+ goto out_unmap;
++ case 8:
++ case 16:
++ case 32:
++ size = size / 8;
++ break;
++ default:
++ goto out_unmap;
+ }
+
+ if (words && words != size) {
@@ -374,7 +418,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ }
+ }
+
-+ ret = __bcm6345_l2_intc_init(node, num_irqs, irqs, bases, words);
++ ret = __bcm6345_periph_intc_init(node, num_irqs, irqs, bases, words);
+ if (!ret)
+ return 0;
+
@@ -387,11 +431,11 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return ret;
+}
+
-+IRQCHIP_DECLARE(bcm6345_l2_intc, "brcm,bcm6345-l2-intc",
-+ bcm6345_l2_intc_of_init);
++IRQCHIP_DECLARE(bcm6345_periph_intc, "brcm,bcm6345-periph-intc",
++ bcm6345_periph_of_init);
+#endif
--- /dev/null
-+++ b/include/linux/irqchip/irq-bcm6345-l2-intc.h
++++ b/include/linux/irqchip/irq-bcm6345-periph.h
@@ -0,0 +1,16 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
@@ -402,10 +446,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ * Copyright (C) 2008 Nicolas Schichan <nschichan@freebox.fr>
+ */
+
-+#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_L2_INTC_H
-+#define __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_L2_INTC_H
++#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_PERIPH_H
++#define __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_PERIPH_H
+
-+void bcm6345_l2_intc_init(int num_blocks, int *irq, void __iomem **base,
-+ int num_words);
++void bcm6345_periph_intc_init(int num_blocks, int *irq, void __iomem **base,
++ int num_words);
+
-+#endif /* __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_L2_INTC_H */
++#endif /* __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_PERIPH_H */
diff --git a/target/linux/brcm63xx/patches-3.18/321-irqchip-add-support-for-bcm6345-style-external-inter.patch b/target/linux/brcm63xx/patches-3.18/321-irqchip-add-support-for-bcm6345-style-external-inter.patch
index 8189e7e807..547b2f1a84 100644
--- a/target/linux/brcm63xx/patches-3.18/321-irqchip-add-support-for-bcm6345-style-external-inter.patch
+++ b/target/linux/brcm63xx/patches-3.18/321-irqchip-add-support-for-bcm6345-style-external-inter.patch
@@ -1,37 +1,42 @@
-From 6896b5f0538a7a7cfb7fac2d9ed3c6841c72ed40 Mon Sep 17 00:00:00 2001
+From cf908990d4a8ccdb73ee4484aa8cadad379ca314 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Sun, 30 Nov 2014 14:54:27 +0100
-Subject: [PATCH 18/20] irqchip: add support for bcm6345-style external
+Subject: [PATCH 2/5] irqchip: add support for bcm6345-style external
interrupt controller
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
- .../interrupt-controller/brcm,bcm6345-ext-intc.txt | 24 ++
+ .../interrupt-controller/brcm,bcm6345-ext-intc.txt | 29 ++
drivers/irqchip/Kconfig | 4 +
drivers/irqchip/Makefile | 1 +
- drivers/irqchip/irq-bcm6345-ext.c | 296 ++++++++++++++++++++
- include/linux/irqchip/irq-bcm6345-ext-intc.h | 14 +
- 5 files changed, 339 insertions(+)
+ drivers/irqchip/irq-bcm6345-ext.c | 287 ++++++++++++++++++++
+ include/linux/irqchip/irq-bcm6345-ext.h | 14 +
+ 5 files changed, 335 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-ext-intc.txt
create mode 100644 drivers/irqchip/irq-bcm6345-ext.c
- create mode 100644 include/linux/irqchip/irq-bcm6345-ext-intc.h
+ create mode 100644 include/linux/irqchip/irq-bcm6345-ext.h
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-ext-intc.txt
-@@ -0,0 +1,24 @@
+@@ -0,0 +1,29 @@
+Broadcom BCM6345-style external interrupt controller
+
+Required properties:
+
-+- compatible: should be "brcm,bcm6345-l2-intc" or "brcm,bcm6345-l2-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
-+ source, should be 2
-+- interrupt-parent: specifies the phandle to the parent interrupt controller
-+ this one is cascaded from
-+- interrupts: specifies the interrupt line(s) in the interrupt-parent controller
-+ node, valid values depend on the type of parent interrupt controller
++- compatible: Should be "brcm,bcm6345-l2-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
++ source, Should be 2.
++- interrupt-parent: Specifies the phandle to the parent interrupt controller
++ this one is cascaded from.
++- interrupts: Specifies the interrupt line(s) in the interrupt-parent controller
++ node, valid values depend on the type of parent interrupt controller.
++
++Optional properties:
++
++- brcm,field-width: Size of each field (mask, clear, sense, ...) in bits in the
++ register. Defaults to 4.
+
+Example:
+
@@ -53,7 +58,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ bool
+ select IRQ_DOMAIN
+
- config BCM6345_L2_IRQ
+ config BCM6345_PERIPH_IRQ
bool
select IRQ_DOMAIN
--- a/drivers/irqchip/Makefile
@@ -63,24 +68,24 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
obj-$(CONFIG_ARCH_MXS) += irq-mxs.o
obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o
+obj-$(CONFIG_BCM6345_EXT_IRQ) += irq-bcm6345-ext.o
- obj-$(CONFIG_BCM6345_L2_IRQ) += irq-bcm6345-l2.o
+ obj-$(CONFIG_BCM6345_PERIPH_IRQ) += irq-bcm6345-periph.o
obj-$(CONFIG_DW_APB_ICTL) += irq-dw-apb-ictl.o
obj-$(CONFIG_METAG) += irq-metag-ext.o
--- /dev/null
+++ b/drivers/irqchip/irq-bcm6345-ext.c
-@@ -0,0 +1,296 @@
+@@ -0,0 +1,287 @@
+/*
+ * 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
+ * for more details.
+ *
+ * Copyright (C) 2014 Jonas Gorski <jogo@openwrt.org>
-+i */
++ */
+
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
-+#include <linux/irqchip/irq-bcm6345-ext-intc.h>
++#include <linux/irqchip/irq-bcm6345-ext.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
@@ -110,7 +115,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+struct intc_data {
+ struct irq_chip chip;
+ struct irq_domain *domain;
-+ spinlock_t lock;
++ raw_spinlock_t lock;
+
+ int parent_irq[MAX_IRQS];
+ void __iomem *reg;
@@ -141,11 +146,11 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ irq_hw_number_t hwirq = irqd_to_hwirq(data);
+ u32 reg;
+
-+ raw_spin_lock(priv->lock);
++ raw_spin_lock(&priv->lock);
+ reg = __raw_readl(priv->reg);
+ reg |= hwirq << (EXTIRQ_CFG_CLEAR * priv->shift);
+ __raw_writel(reg, priv->reg);
-+ raw_spin_unlock(priv->lock);
++ raw_spin_unlock(&priv->lock);
+}
+
+static void bcm6345_ext_intc_irq_mask(struct irq_data *data)
@@ -154,11 +159,11 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ irq_hw_number_t hwirq = irqd_to_hwirq(data);
+ u32 reg;
+
-+ raw_spin_lock(priv->lock);
++ raw_spin_lock(&priv->lock);
+ reg = __raw_readl(priv->reg);
+ reg &= ~(hwirq << (EXTIRQ_CFG_MASK * priv->shift));
+ __raw_writel(reg, priv->reg);
-+ raw_spin_unlock(priv->lock);
++ raw_spin_unlock(&priv->lock);
+}
+
+static void bcm6345_ext_intc_irq_unmask(struct irq_data *data)
@@ -167,11 +172,11 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ irq_hw_number_t hwirq = irqd_to_hwirq(data);
+ u32 reg;
+
-+ raw_spin_lock(priv->lock);
++ raw_spin_lock(&priv->lock);
+ reg = __raw_readl(priv->reg);
+ reg |= hwirq << (EXTIRQ_CFG_MASK * priv->shift);
+ __raw_writel(reg, priv->reg);
-+ raw_spin_unlock(priv->lock);
++ raw_spin_unlock(&priv->lock);
+}
+
+static int bcm6345_ext_intc_set_type(struct irq_data *data,
@@ -213,7 +218,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return -EINVAL;
+ }
+
-+ raw_spin_lock(priv->lock);
++ raw_spin_lock(&priv->lock);
+ reg = __raw_readl(priv->reg);
+
+ if (levelsense)
@@ -230,7 +235,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ reg &= ~(hwirq << (EXTIRQ_CFG_BOTHEDGE * priv->shift));
+
+ __raw_writel(reg, priv->reg);
-+ raw_spin_unlock(priv->lock);
++ raw_spin_unlock(&priv->lock);
+
+ irqd_set_trigger_type(data, flow_type);
+ if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
@@ -242,7 +247,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+}
+
+static int bcm6345_ext_intc_map(struct irq_domain *d, unsigned int irq,
-+ irq_hw_number_t hw)
++ irq_hw_number_t hw)
+{
+ struct intc_data *priv = d->host_data;
+
@@ -251,7 +256,6 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return 0;
+}
+
-+
+static const struct irq_domain_ops bcm6345_ext_domain_ops = {
+ .xlate = irq_domain_xlate_twocell,
+ .map = bcm6345_ext_intc_map,
@@ -269,6 +273,8 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ if (!data)
+ return -ENOMEM;
+
++ raw_spin_lock_init(&data->lock);
++
+ for (i = 0; i < num_irqs; i++) {
+ data->parent_irq[i] = irqs[i];
+
@@ -311,20 +317,23 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+}
+
+#ifdef CONFIG_OF
-+static int __init bcm63xx_ext_intc_of_init(struct device_node *node,
-+ struct device_node *parent,
-+ int shift)
++static int __init bcm6345_ext_intc_of_init(struct device_node *node,
++ struct device_node *parent)
+{
+ int num_irqs, ret = -EINVAL;
+ unsigned i;
+ void __iomem *base;
+ int irqs[MAX_IRQS] = { 0 };
++ u32 shift;
+
+ num_irqs = of_irq_count(node);
+
+ if (!num_irqs || num_irqs > MAX_IRQS)
+ return -EINVAL;
+
++ if (of_property_read_u32(node, "brcm,field-width", &shift))
++ shift = 4;
++
+ for (i = 0; i < num_irqs; i++) {
+ irqs[i] = irq_of_parse_and_map(node, i);
+ if (!irqs[i]) {
@@ -349,24 +358,11 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return ret;
+}
+
-+static int __init bcm6345_ext_intc_of_init(struct device_node *node,
-+ struct device_node *parent)
-+{
-+ return bcm63xx_ext_intc_of_init(node, parent, 4);
-+}
-+static int __init bcm6348_ext_intc_of_init(struct device_node *node,
-+ struct device_node *parent)
-+{
-+ return bcm63xx_ext_intc_of_init(node, parent, 5);
-+}
-+
+IRQCHIP_DECLARE(bcm6345_ext_intc, "brcm,bcm6345-ext-intc",
+ bcm6345_ext_intc_of_init);
-+IRQCHIP_DECLARE(bcm6348_ext_intc, "brcm,bcm6348-ext-intc",
-+ bcm6348_ext_intc_of_init);
+#endif
--- /dev/null
-+++ b/include/linux/irqchip/irq-bcm6345-ext-intc.h
++++ b/include/linux/irqchip/irq-bcm6345-ext.h
@@ -0,0 +1,14 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
@@ -376,9 +372,9 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ * Copyright (C) 2014 Jonas Gorski <jogo@openwrt.org>
+ */
+
-+#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_INTC_H
-+#define __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_INTC_H
++#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_H
++#define __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_H
+
+void bcm6345_ext_intc_init(int n_irqs, int *irqs, void __iomem *reg, int shift);
+
-+#endif /* __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_INTC_H */
++#endif /* __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_H */
diff --git a/target/linux/brcm63xx/patches-3.18/322-MIPS-BCM63XX-switch-to-IRQ_DOMAIN.patch b/target/linux/brcm63xx/patches-3.18/322-MIPS-BCM63XX-switch-to-IRQ_DOMAIN.patch
index 49c5bccb21..54d9094064 100644
--- a/target/linux/brcm63xx/patches-3.18/322-MIPS-BCM63XX-switch-to-IRQ_DOMAIN.patch
+++ b/target/linux/brcm63xx/patches-3.18/322-MIPS-BCM63XX-switch-to-IRQ_DOMAIN.patch
@@ -1,7 +1,7 @@
-From d93661c9e164ccc41820eeb4f1881e59a34a9e5c Mon Sep 17 00:00:00 2001
+From cfe7647c2a4decf874dff8abb60704e9917f76fe Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Sun, 30 Nov 2014 14:55:02 +0100
-Subject: [PATCH 19/20] MIPS: BCM63XX: switch to IRQ_DOMAIN
+Subject: [PATCH 3/5] MIPS: BCM63XX: switch to IRQ_DOMAIN
Now that we have working IRQ_DOMAIN drivers for both interrupt controllers,
switch to using them.
@@ -9,8 +9,8 @@ switch to using them.
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
arch/mips/Kconfig | 3 +
- arch/mips/bcm63xx/irq.c | 608 ++++++++---------------------------------------
- 2 files changed, 108 insertions(+), 503 deletions(-)
+ arch/mips/bcm63xx/irq.c | 609 +++++++++--------------------------------------
+ 2 files changed, 109 insertions(+), 503 deletions(-)
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -19,7 +19,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
select DMA_NONCOHERENT
select IRQ_CPU
+ select BCM6345_EXT_IRQ
-+ select BCM6345_L2_IRQ
++ select BCM6345_PERIPH_IRQ
+ select IRQ_DOMAIN
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
@@ -32,12 +32,12 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
#include <linux/irq.h>
-#include <linux/spinlock.h>
+#include <linux/irqchip.h>
-+#include <linux/irqchip/irq-bcm6345-ext-intc.h>
-+#include <linux/irqchip/irq-bcm6345-l2-intc.h>
++#include <linux/irqchip/irq-bcm6345-ext.h>
++#include <linux/irqchip/irq-bcm6345-periph.h>
#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
#include <bcm63xx_cpu.h>
-@@ -20,544 +22,144 @@
+@@ -20,544 +22,145 @@
#include <bcm63xx_io.h>
#include <bcm63xx_irq.h>
@@ -449,14 +449,14 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- irq_mask_addr[0] = bcm63xx_regset_address(RSET_PERF);
- irq_stat_addr[1] = bcm63xx_regset_address(RSET_PERF);
- irq_mask_addr[1] = bcm63xx_regset_address(RSET_PERF);
-+ void __iomem *l2_intc_bases[2];
++ void __iomem *periph_bases[2];
+ void __iomem *ext_intc_bases[2];
-+ int l2_irq_count, l2_width, ext_irq_count, ext_shift;
-+ int l2_irqs[2] = { 2, 3 };
++ int periph_irq_count, periph_width, ext_irq_count, ext_shift;
++ int periph_irqs[2] = { 2, 3 };
+ int ext_irqs[6];
+
-+ l2_intc_bases[0] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
-+ l2_intc_bases[1] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
++ periph_bases[0] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
++ periph_bases[1] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
+ ext_intc_bases[0] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
+ ext_intc_bases[1] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
@@ -469,9 +469,9 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- irq_bits = 32;
- ext_irq_count = 4;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_3368;
-+ l2_intc_bases[0] += PERF_IRQMASK_3368_REG;
-+ l2_irq_count = 1;
-+ l2_width = 1;
++ periph_bases[0] += PERF_IRQMASK_3368_REG;
++ periph_irq_count = 1;
++ periph_width = 1;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_3368;
+ ext_irq_count = 4;
@@ -492,10 +492,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- ext_irq_start = BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE;
- ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328;
-+ l2_intc_bases[0] += PERF_IRQMASK_6328_REG(0);
-+ l2_intc_bases[1] += PERF_IRQMASK_6328_REG(1);
-+ l2_irq_count = 2;
-+ l2_width = 2;
++ periph_bases[0] += PERF_IRQMASK_6328_REG(0);
++ periph_bases[1] += PERF_IRQMASK_6328_REG(1);
++ periph_irq_count = 2;
++ periph_width = 2;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6328;
+ ext_irq_count = 4;
@@ -513,9 +513,9 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- irq_bits = 32;
- ext_irq_count = 4;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6338;
-+ l2_intc_bases[0] += PERF_IRQMASK_6338_REG;
-+ l2_irq_count = 1;
-+ l2_width = 1;
++ periph_bases[0] += PERF_IRQMASK_6338_REG;
++ periph_irq_count = 1;
++ periph_width = 1;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6338;
+ ext_irq_count = 4;
@@ -533,9 +533,9 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- irq_bits = 32;
- ext_irq_count = 4;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6345;
-+ l2_intc_bases[0] += PERF_IRQMASK_6345_REG;
-+ l2_irq_count = 1;
-+ l2_width = 1;
++ periph_bases[0] += PERF_IRQMASK_6345_REG;
++ periph_irq_count = 1;
++ periph_width = 1;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6345;
+ ext_irq_count = 4;
@@ -553,9 +553,9 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- irq_bits = 32;
- ext_irq_count = 4;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6348;
-+ l2_intc_bases[0] += PERF_IRQMASK_6348_REG;
-+ l2_irq_count = 1;
-+ l2_width = 1;
++ periph_bases[0] += PERF_IRQMASK_6348_REG;
++ periph_irq_count = 1;
++ periph_width = 1;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6348;
+ ext_irq_count = 4;
@@ -576,10 +576,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- ext_irq_start = BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE;
- ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6358;
-+ l2_intc_bases[0] += PERF_IRQMASK_6358_REG(0);
-+ l2_intc_bases[1] += PERF_IRQMASK_6358_REG(1);
-+ l2_irq_count = 2;
-+ l2_width = 1;
++ periph_bases[0] += PERF_IRQMASK_6358_REG(0);
++ periph_bases[1] += PERF_IRQMASK_6358_REG(1);
++ periph_irq_count = 2;
++ periph_width = 1;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6358;
+ ext_irq_count = 4;
@@ -600,10 +600,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- ext_irq_start = BCM_6362_EXT_IRQ0 - IRQ_INTERNAL_BASE;
- ext_irq_end = BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6362;
-+ l2_intc_bases[0] += PERF_IRQMASK_6362_REG(0);
-+ l2_intc_bases[1] += PERF_IRQMASK_6362_REG(1);
-+ l2_irq_count = 2;
-+ l2_width = 2;
++ periph_bases[0] += PERF_IRQMASK_6362_REG(0);
++ periph_bases[1] += PERF_IRQMASK_6362_REG(1);
++ periph_irq_count = 2;
++ periph_width = 2;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6362;
+ ext_irq_count = 4;
@@ -619,10 +619,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- irq_stat_addr[1] += PERF_IRQSTAT_6368_REG(1);
- irq_mask_addr[1] += PERF_IRQMASK_6368_REG(1);
- irq_bits = 64;
-+ l2_intc_bases[0] += PERF_IRQMASK_6368_REG(0);
-+ l2_intc_bases[1] += PERF_IRQMASK_6368_REG(1);
-+ l2_irq_count = 2;
-+ l2_width = 2;
++ periph_bases[0] += PERF_IRQMASK_6368_REG(0);
++ periph_bases[1] += PERF_IRQMASK_6368_REG(1);
++ periph_irq_count = 2;
++ periph_width = 2;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6368;
+ ext_intc_bases[1] += PERF_EXTIRQ_CFG_REG2_6368;
@@ -654,7 +654,8 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- internal_irq_unmask = __internal_irq_unmask_64;
- }
+ mips_cpu_irq_init();
-+ bcm6345_l2_intc_init(l2_irq_count, l2_irqs, l2_intc_bases, l2_width);
++ bcm6345_periph_intc_init(periph_irq_count, periph_irqs, periph_bases,
++ periph_width);
+ bcm6345_ext_intc_init(4, ext_irqs, ext_intc_bases[0], ext_shift);
+ if (ext_irq_count > 4)
+ bcm6345_ext_intc_init(2, &ext_irqs[4], ext_intc_bases[1],
diff --git a/target/linux/brcm63xx/patches-3.18/323-MIPS-BCM63XX-wire-up-BCM6358-s-external-interrupts-4.patch b/target/linux/brcm63xx/patches-3.18/323-MIPS-BCM63XX-wire-up-BCM6358-s-external-interrupts-4.patch
index 3e718772ca..a2ee1b67fe 100644
--- a/target/linux/brcm63xx/patches-3.18/323-MIPS-BCM63XX-wire-up-BCM6358-s-external-interrupts-4.patch
+++ b/target/linux/brcm63xx/patches-3.18/323-MIPS-BCM63XX-wire-up-BCM6358-s-external-interrupts-4.patch
@@ -1,7 +1,7 @@
-From e3c68bbba30b212326fb69bf64b2220750dead3e Mon Sep 17 00:00:00 2001
+From 4fd286c3e5a5bebab0391cf1937695b3ed6721a3 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Sun, 30 Nov 2014 20:20:30 +0100
-Subject: [PATCH 20/20] MIPS: BCM63XX: wire up BCM6358's external interrupts 4
+Subject: [PATCH 4/5] MIPS: BCM63XX: wire up BCM6358's external interrupts 4
and 5
Due to the external interrupts being non consecutive, the previous
@@ -19,7 +19,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -109,11 +109,14 @@ static void bcm63xx_init_irq(void)
- l2_width = 1;
+ periph_width = 1;
ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6358;
- ext_irq_count = 4;
diff --git a/target/linux/brcm63xx/patches-3.18/339-MIPS-BCM63XX-add-support-for-BCM63268.patch b/target/linux/brcm63xx/patches-3.18/339-MIPS-BCM63XX-add-support-for-BCM63268.patch
index 5abdd9d09f..ba0df35251 100644
--- a/target/linux/brcm63xx/patches-3.18/339-MIPS-BCM63XX-add-support-for-BCM63268.patch
+++ b/target/linux/brcm63xx/patches-3.18/339-MIPS-BCM63XX-add-support-for-BCM63268.patch
@@ -289,10 +289,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
ext_shift = 4;
break;
+ case BCM63268_CPU_ID:
-+ l2_intc_bases[0] += PERF_IRQSTAT_63268_REG(0);
-+ l2_intc_bases[1] += PERF_IRQSTAT_63268_REG(1);
-+ l2_irq_count = 2;
-+ l2_width = 4;
++ periph_bases[0] += PERF_IRQSTAT_63268_REG(0);
++ periph_bases[1] += PERF_IRQSTAT_63268_REG(1);
++ periph_irq_count = 2;
++ periph_width = 4;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_63268;
+ ext_irq_count = 4;
diff --git a/target/linux/brcm63xx/patches-3.18/341-MIPS-BCM63XX-add-support-for-BCM6318.patch b/target/linux/brcm63xx/patches-3.18/341-MIPS-BCM63XX-add-support-for-BCM6318.patch
index 440a30ead7..0e4df97731 100644
--- a/target/linux/brcm63xx/patches-3.18/341-MIPS-BCM63XX-add-support-for-BCM6318.patch
+++ b/target/linux/brcm63xx/patches-3.18/341-MIPS-BCM63XX-add-support-for-BCM6318.patch
@@ -199,9 +199,9 @@ Subject: [PATCH 51/53] MIPS: BCM63XX: add support for BCM6318
ext_shift = 4;
break;
+ case BCM6318_CPU_ID:
-+ l2_intc_bases[0] += PERF_IRQMASK_6318_REG;
-+ l2_irq_count = 1;
-+ l2_width = 4;
++ periph_bases[0] += PERF_IRQMASK_6318_REG;
++ periph_irq_count = 1;
++ periph_width = 4;
+
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6318;
+ ext_irq_count = 4;
@@ -212,8 +212,8 @@ Subject: [PATCH 51/53] MIPS: BCM63XX: add support for BCM6318
+ ext_shift = 4;
+ break;
case BCM6328_CPU_ID:
- l2_intc_bases[0] += PERF_IRQMASK_6328_REG(0);
- l2_intc_bases[1] += PERF_IRQMASK_6328_REG(1);
+ periph_bases[0] += PERF_IRQMASK_6328_REG(0);
+ periph_bases[1] += PERF_IRQMASK_6328_REG(1);
--- a/arch/mips/bcm63xx/prom.c
+++ b/arch/mips/bcm63xx/prom.c
@@ -72,7 +72,7 @@ void __init prom_init(void)
diff --git a/target/linux/brcm63xx/patches-3.18/366-MIPS-add-support-for-vmlinux.bin-appended-DTB.patch b/target/linux/brcm63xx/patches-3.18/366-MIPS-add-support-for-vmlinux.bin-appended-DTB.patch
index 7c19ee590d..ff455dddc9 100644
--- a/target/linux/brcm63xx/patches-3.18/366-MIPS-add-support-for-vmlinux.bin-appended-DTB.patch
+++ b/target/linux/brcm63xx/patches-3.18/366-MIPS-add-support-for-vmlinux.bin-appended-DTB.patch
@@ -43,7 +43,7 @@ Completely untested on anything except MIPS32 / big endian.
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
-@@ -2645,6 +2645,24 @@ config RAPIDIO
+@@ -2655,6 +2655,24 @@ config RAPIDIO
source "drivers/rapidio/Kconfig"
diff --git a/target/linux/brcm63xx/patches-3.18/373-MIPS-BCM63XX-register-interrupt-controllers-through-.patch b/target/linux/brcm63xx/patches-3.18/373-MIPS-BCM63XX-register-interrupt-controllers-through-.patch
index 3b15589baa..edc05d95fb 100644
--- a/target/linux/brcm63xx/patches-3.18/373-MIPS-BCM63XX-register-interrupt-controllers-through-.patch
+++ b/target/linux/brcm63xx/patches-3.18/373-MIPS-BCM63XX-register-interrupt-controllers-through-.patch
@@ -1,25 +1,25 @@
-From 7c22b08baba941a8c83072047b0d2b55a6b952aa Mon Sep 17 00:00:00 2001
+From 8a0803979163c647736cb234ee1620c049c4915c Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Mon, 1 Dec 2014 00:20:07 +0100
-Subject: [PATCH] MIPS: BCM63XX: register interrupt controllers through DT
+Subject: [PATCH 5/5] MIPS: BCM63XX: register interrupt controllers through DT
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
- arch/mips/bcm63xx/irq.c | 10 +++++++++-
- 1 file changed, 9 insertions(+), 1 deletion(-)
+ arch/mips/bcm63xx/irq.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -15,6 +15,8 @@
#include <linux/irqchip.h>
- #include <linux/irqchip/irq-bcm6345-ext-intc.h>
- #include <linux/irqchip/irq-bcm6345-l2-intc.h>
+ #include <linux/irqchip/irq-bcm6345-ext.h>
+ #include <linux/irqchip/irq-bcm6345-periph.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
#include <bcm63xx_cpu.h>
-@@ -189,7 +191,13 @@ static void bcm63xx_init_irq(void)
+@@ -190,7 +192,15 @@ static void bcm63xx_init_irq(void)
ext_shift);
}
@@ -29,8 +29,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
void __init arch_init_irq(void)
{
- bcm63xx_init_irq();
++#ifdef CONFIG_OF
+ if (initial_boot_params)
+ irqchip_init();
+ else
++#endif
+ bcm63xx_init_irq();
}