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>

SVN-Revision: 43578
This commit is contained in:
Jonas Gorski 2014-12-08 16:11:52 +00:00
parent ed7d8a0450
commit bdb1ee51f8
48 changed files with 595 additions and 474 deletions

View file

@ -14,6 +14,8 @@ CONFIG_B53_PHY_DRIVER=y
CONFIG_B53_PHY_FIXUP=y CONFIG_B53_PHY_FIXUP=y
CONFIG_B53_SPI_DRIVER=y CONFIG_B53_SPI_DRIVER=y
# CONFIG_B53_SRAB_DRIVER is not set # CONFIG_B53_SRAB_DRIVER is not set
CONFIG_BCM6345_EXT_IRQ=y
CONFIG_BCM6345_PERIPH_IRQ=y
CONFIG_BCM63XX=y CONFIG_BCM63XX=y
CONFIG_BCM63XX_CPU_3368=y CONFIG_BCM63XX_CPU_3368=y
CONFIG_BCM63XX_CPU_6318=y CONFIG_BCM63XX_CPU_6318=y
@ -71,7 +73,6 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CMOS_UPDATE=y CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_GENERIC_IO=y CONFIG_GENERIC_IO=y
CONFIG_GENERIC_IRQ_SHOW=y CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_NET_UTILS=y
CONFIG_GENERIC_PCI_IOMAP=y CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GPIOLIB=y CONFIG_GPIOLIB=y

View file

@ -18,7 +18,7 @@ CONFIG_B53_PHY_FIXUP=y
CONFIG_B53_SPI_DRIVER=y CONFIG_B53_SPI_DRIVER=y
# CONFIG_B53_SRAB_DRIVER is not set # CONFIG_B53_SRAB_DRIVER is not set
CONFIG_BCM6345_EXT_IRQ=y CONFIG_BCM6345_EXT_IRQ=y
CONFIG_BCM6345_L2_IRQ=y CONFIG_BCM6345_PERIPH_IRQ=y
CONFIG_BCM63XX=y CONFIG_BCM63XX=y
CONFIG_BCM63XX_CPU_3368=y CONFIG_BCM63XX_CPU_3368=y
CONFIG_BCM63XX_CPU_6318=y CONFIG_BCM63XX_CPU_6318=y
@ -61,6 +61,7 @@ CONFIG_CPU_GENERIC_DUMP_TLB=y
CONFIG_CPU_HAS_PREFETCH=y CONFIG_CPU_HAS_PREFETCH=y
CONFIG_CPU_HAS_SYNC=y CONFIG_CPU_HAS_SYNC=y
CONFIG_CPU_MIPS32=y CONFIG_CPU_MIPS32=y
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
CONFIG_CPU_R4K_CACHE_TLB=y CONFIG_CPU_R4K_CACHE_TLB=y
CONFIG_CPU_R4K_FPU=y CONFIG_CPU_R4K_FPU=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y

View file

@ -42,7 +42,7 @@
}; };
periph_intc: interrupt-controller@10000020 { periph_intc: interrupt-controller@10000020 {
compatible = "brcm,bcm6345-l2-intc"; compatible = "brcm,bcm6345-periph-intc";
reg = <0x10000020 0x20>; reg = <0x10000020 0x20>;
interrupt-controller; interrupt-controller;

View file

@ -48,7 +48,7 @@
}; };
periph_intc: interrupt-controller@10000020 { periph_intc: interrupt-controller@10000020 {
compatible = "brcm,bcm6345-l2-intc"; compatible = "brcm,bcm6345-periph-intc";
reg = <0x10000020 0x20>, reg = <0x10000020 0x20>,
<0x10000040 0x20>; <0x10000040 0x20>;

View file

@ -42,7 +42,7 @@
}; };
periph_intc: interrupt-controller@10000020 { periph_intc: interrupt-controller@10000020 {
compatible = "brcm,bcm6345-l2-intc"; compatible = "brcm,bcm6345-periph-intc";
reg = <0x10000020 0x10>; reg = <0x10000020 0x10>;
interrupt-controller; interrupt-controller;

View file

@ -45,7 +45,7 @@
compatible = "simple-bus"; compatible = "simple-bus";
periph_intc: interrupt-controller@fffe000c { periph_intc: interrupt-controller@fffe000c {
compatible = "brcm,bcm6345-l2-intc"; compatible = "brcm,bcm6345-periph-intc";
reg = <0xfffe000c 0x8>; reg = <0xfffe000c 0x8>;
interrupt-controller; interrupt-controller;

View file

@ -45,7 +45,7 @@
compatible = "simple-bus"; compatible = "simple-bus";
periph_intc: interrupt-controller@fffe000c { periph_intc: interrupt-controller@fffe000c {
compatible = "brcm,bcm6345-l2-intc"; compatible = "brcm,bcm6345-periph-intc";
reg = <0xfffe000c 0x9>; reg = <0xfffe000c 0x9>;
interrupt-controller; interrupt-controller;

View file

@ -45,7 +45,7 @@
compatible = "simple-bus"; compatible = "simple-bus";
periph_intc: interrupt-controller@fffe000c { periph_intc: interrupt-controller@fffe000c {
compatible = "brcm,bcm6345-l2-intc"; compatible = "brcm,bcm6345-periph-intc";
reg = <0xfffe000c 0x8>; reg = <0xfffe000c 0x8>;
interrupt-controller; interrupt-controller;
@ -64,6 +64,8 @@
interrupt-parent = <&cpu_intc>; interrupt-parent = <&cpu_intc>;
interrupts = <3>, <4>, <5>, <6>; interrupts = <3>, <4>, <5>, <6>;
brcm,field-width = <5>;
}; };
}; };
}; };

View file

@ -51,7 +51,7 @@
compatible = "simple-bus"; compatible = "simple-bus";
periph_intc: interrupt-controller@fffe000c { periph_intc: interrupt-controller@fffe000c {
compatible = "brcm,bcm6345-l2-intc"; compatible = "brcm,bcm6345-periph-intc";
reg = <0xfffe000c 0x8>, reg = <0xfffe000c 0x8>,
<0xfffe0038 0x8>; <0xfffe0038 0x8>;

View file

@ -48,7 +48,7 @@
}; };
periph_intc: interrupt-controller@10000020 { periph_intc: interrupt-controller@10000020 {
compatible = "brcm,bcm6345-l2-intc"; compatible = "brcm,bcm6345-periph-intc";
reg = <0x10000020 0x10>, reg = <0x10000020 0x10>,
<0x10000030 0x10>; <0x10000030 0x10>;

View file

@ -63,7 +63,7 @@
}; };
periph_intc: interrupt-controller@10000020 { periph_intc: interrupt-controller@10000020 {
compatible = "brcm,bcm6345-l2-intc"; compatible = "brcm,bcm6345-periph-intc";
reg = <0x10000020 0x10>, reg = <0x10000020 0x10>,
<0x10000030 0x10>; <0x10000030 0x10>;

View file

@ -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> From: Jonas Gorski <jogo@openwrt.org>
Date: Sun, 30 Nov 2014 14:53:12 +0100 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 controller
Signed-off-by: Jonas Gorski <jogo@openwrt.org> 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/Kconfig | 4 +
drivers/irqchip/Makefile | 1 + drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-bcm6345-l2.c | 320 ++++++++++++++++++++ drivers/irqchip/irq-bcm6345-periph.c | 325 ++++++++++++++++++++
include/linux/irqchip/irq-bcm6345-l2-intc.h | 16 + include/linux/irqchip/irq-bcm6345-periph.h | 16 +
5 files changed, 366 insertions(+) 5 files changed, 396 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-l2-intc.txt create mode 100644 Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-periph-intc.txt
create mode 100644 drivers/irqchip/irq-bcm6345-l2.c create mode 100644 drivers/irqchip/irq-bcm6345-periph.c
create mode 100644 include/linux/irqchip/irq-bcm6345-l2-intc.h create mode 100644 include/linux/irqchip/irq-bcm6345-periph.h
--- /dev/null --- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-l2-intc.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-periph-intc.txt
@@ -0,0 +1,25 @@ @@ -0,0 +1,50 @@
+Broadcom BCM6345 Level 2 interrupt controller +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: +Required properties:
+ +
+- compatible: should be "brcm,bcm6345-l2-intc" +- compatible: Should be "brcm,bcm6345-periph-intc".
+- reg: specifies the base physical address and size of the registers; +- reg: Specifies the base physical address and size of the registers.
+ multiple regs may be specified, and must match the amount of parent interrupts + Multiple register addresses may be specified, and must match the amount of
+- interrupt-controller: identifies the node as an interrupt controller + parent interrupts.
+- #interrupt-cells: specifies the number of cells needed to encode an interrupt +- interrupt-controller: Identifies the node as an interrupt controller.
+ source, should be 1 +- #interrupt-cells: Specifies the number of cells needed to encode an interrupt
+- interrupt-parent: specifies the phandle to the parent interrupt controller + source, should be 1.
+ this one is cascaded from +- interrupt-parent: Specifies the phandle to the parent interrupt controller
+- interrupts: specifies the interrupt line(s) in the interrupt-parent controller + this one is cascaded from.
+ node, valid values depend on the type of parent interrupt controller +- 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: +Example:
+ +
+periph_intc: interrupt-controller@f0406800 { +periph_intc: interrupt-controller@f0406800 {
+ compatible = "brcm,bcm6345-l2-intc"; + compatible = "brcm,bcm6345-periph-intc";
+ interrupt-parent = <&mips_intc>; + reg = <0x10000020 0x10>, <0x10000030 0x10>;
+ #interrupt-cells = <1>; +
+ reg = <0x10000020 0x10> <0x10000030 0x10>;
+ interrupt-controller; + interrupt-controller;
+ #interrupt-cells = <1>;
+
+ interrupt-parent = <&cpu_intc>;
+ interrupts = <2>, <3>; + interrupts = <2>, <3>;
+}; +};
--- a/drivers/irqchip/Kconfig --- 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 The maximum number of VICs available in the system, for
power management. power management.
+config BCM6345_L2_IRQ +config BCM6345_PERIPH_IRQ
+ bool + bool
+ select IRQ_DOMAIN + 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_MVEBU) += irq-armada-370-xp.o
obj-$(CONFIG_ARCH_MXS) += irq-mxs.o obj-$(CONFIG_ARCH_MXS) += irq-mxs.o
obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.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_DW_APB_ICTL) += irq-dw-apb-ictl.o
obj-$(CONFIG_METAG) += irq-metag-ext.o obj-$(CONFIG_METAG) += irq-metag-ext.o
obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o
--- /dev/null --- /dev/null
+++ b/drivers/irqchip/irq-bcm6345-l2.c +++ b/drivers/irqchip/irq-bcm6345-periph.c
@@ -0,0 +1,320 @@ @@ -0,0 +1,340 @@
+/* +/*
+ * This file is subject to the terms and conditions of the GNU General Public + * 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 + * 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/ioport.h>
+#include <linux/irq.h> +#include <linux/irq.h>
+#include <linux/irqchip/chained_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/kernel.h>
+#include <linux/of.h> +#include <linux/of.h>
+#include <linux/of_irq.h> +#include <linux/of_irq.h>
@ -118,10 +143,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ int num_words; + int num_words;
+ +
+ struct irq_domain *domain; + 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 intc_data *data = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_chip *chip = irq_desc_get_chip(desc);
@ -139,43 +164,36 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ unsigned long pending; + unsigned long pending;
+ int hw_irq; + int hw_irq;
+ +
+ raw_spin_lock(data->lock); + raw_spin_lock(&data->lock);
+ pending = __raw_readl(block->en_reg[idx]) & + pending = __raw_readl(block->en_reg[idx]) &
+ __raw_readl(block->status_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) { + 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); + 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)
+{ +{
+ unsigned int i, reg, bit; + u32 val;
+ struct intc_data *priv = data->domain->host_data;
+ irq_hw_number_t hwirq = irqd_to_hwirq(data);
+ +
+ reg = hwirq / IRQS_PER_WORD; + val = __raw_readl(block->en_reg[reg]);
+ bit = hwirq % IRQS_PER_WORD; + if (enable)
+ + val |= BIT(bit);
+ raw_spin_lock(priv->lock); + else
+ for (i = 0; i < MAX_PARENT_IRQS; i++) { + val &= ~BIT(bit);
+ struct intc_block *block = &priv->block[i]; + __raw_writel(val, block->en_reg[reg]);
+ u32 val;
+
+ if (!block->parent_irq)
+ break;
+
+ val = __raw_readl(block->en_reg[reg]);
+ __raw_writel(val & ~BIT(bit), block->en_reg[reg]);
+ }
+ raw_spin_unlock(priv->lock);
+} +}
+ +
+static void bcm6345_l2_intc_irq_unmask(struct irq_data *data) +static void bcm6345_periph_irq_mask(struct irq_data *data)
+{ +{
+ unsigned int i, reg, bit; + unsigned int i, reg, bit;
+ struct intc_data *priv = data->domain->host_data; + struct intc_data *priv = data->domain->host_data;
@ -184,35 +202,51 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ reg = hwirq / IRQS_PER_WORD; + reg = hwirq / IRQS_PER_WORD;
+ bit = 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++) { + for (i = 0; i < MAX_PARENT_IRQS; i++) {
+ struct intc_block *block = &priv->block[i]; + struct intc_block *block = &priv->block[i];
+ u32 val;
+ +
+ if (!block->parent_irq) + if (!block->parent_irq)
+ break; + break;
+ +
+ val = __raw_readl(block->en_reg[reg]); + __bcm6345_periph_enable(block, reg, bit, false);
+ }
+ raw_spin_unlock(&priv->lock);
+}
+
+static void bcm6345_periph_irq_unmask(struct irq_data *data)
+{
+ 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);
+ for (i = 0; i < MAX_PARENT_IRQS; i++) {
+ struct intc_block *block = &priv->block[i];
+
+ if (!block->parent_irq)
+ break;
+ +
+ if (block->mask_cache[reg] & BIT(bit)) + if (block->mask_cache[reg] & BIT(bit))
+ val |= BIT(bit); + __bcm6345_periph_enable(block, reg, bit, true);
+ else + else
+ val &= ~BIT(bit); + __bcm6345_periph_enable(block, reg, bit, false);
+
+ __raw_writel(val, block->en_reg[reg]);
+ +
+ } + }
+ raw_spin_unlock(priv->lock); + raw_spin_unlock(&priv->lock);
+} +}
+ +
+#ifdef CONFIG_SMP +#ifdef CONFIG_SMP
+static int bcm6345_l2_intc_set_affinity(struct irq_data *data, +static int bcm6345_periph_set_affinity(struct irq_data *data,
+ const struct cpumask *mask, + const struct cpumask *mask, bool force)
+ bool force)
+{ +{
+ irq_hw_number_t hwirq = irqd_to_hwirq(data); + irq_hw_number_t hwirq = irqd_to_hwirq(data);
+ struct intc_data *priv = data->domain->host_data; + struct intc_data *priv = data->domain->host_data;
+ unsigned int i, reg, bit; + unsigned int i, reg, bit;
+ bool enabled;
+ int cpu; + int cpu;
+ +
+ reg = hwirq / IRQS_PER_WORD; + reg = hwirq / IRQS_PER_WORD;
@ -231,21 +265,30 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ if (!priv->block[cpu].parent_irq) + if (!priv->block[cpu].parent_irq)
+ return -EINVAL; + 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++) { + for (i = 0; i < MAX_PARENT_IRQS; i++) {
+ if (i == cpu) + struct intc_block *block = &priv->block[i];
+ priv->block[i].mask_cache[reg] |= BIT(bit); +
+ else + if (!block->parent_irq)
+ priv->block[i].mask_cache[reg] &= ~BIT(bit); + 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; + return 0;
+} +}
+#endif +#endif
+ +
+static int bcm6345_l2_map(struct irq_domain *d, unsigned int irq, +static int bcm6345_periph_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; + struct intc_data *priv = d->host_data;
+ +
@ -254,14 +297,14 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return 0; + 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, + .xlate = irq_domain_xlate_onecell,
+ .map = bcm6345_l2_map, + .map = bcm6345_periph_map,
+}; +};
+ +
+static int __init __bcm6345_l2_intc_init(struct device_node *node, +static int __init __bcm6345_periph_intc_init(struct device_node *node,
+ int num_blocks, int *irq, + int num_blocks, int *irq,
+ void __iomem **base, int num_words) + void __iomem **base, int num_words)
+{ +{
+ struct intc_data *data; + struct intc_data *data;
+ unsigned int i, w, status_offset; + unsigned int i, w, status_offset;
@ -270,6 +313,8 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ if (!data) + if (!data)
+ return -ENOMEM; + return -ENOMEM;
+ +
+ raw_spin_lock_init(&data->lock);
+
+ status_offset = num_words * sizeof(u32); + status_offset = num_words * sizeof(u32);
+ +
+ for (i = 0; i < num_blocks; i++) { + 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_handler_data(block->parent_irq, data);
+ irq_set_chained_handler(block->parent_irq, + irq_set_chained_handler(block->parent_irq,
+ bcm6345_l2_intc_irq_handle); + bcm6345_periph_irq_handle);
+ } + }
+ +
+ data->num_words = num_words; + data->num_words = num_words;
+ +
+ data->chip.name = "bcm6345-l2-intc"; + data->chip.name = "bcm6345-periph-intc";
+ data->chip.irq_mask = bcm6345_l2_intc_irq_mask; + data->chip.irq_mask = bcm6345_periph_irq_mask;
+ data->chip.irq_unmask = bcm6345_l2_intc_irq_unmask; + data->chip.irq_unmask = bcm6345_periph_irq_unmask;
+ +
+#ifdef CONFIG_SMP +#ifdef CONFIG_SMP
+ if (num_blocks > 1) + if (num_blocks > 1)
+ data->chip.set_affinity = bcm6345_l2_intc_set_affinity; + data->chip.irq_set_affinity = bcm6345_periph_set_affinity;
+#endif +#endif
+ +
+ data->domain = irq_domain_add_simple(node, IRQS_PER_WORD * num_words, + data->domain = irq_domain_add_simple(node, IRQS_PER_WORD * num_words,
+ VIRQ_BASE, &bcm6345_l2_domain_ops, + VIRQ_BASE,
+ data); + &bcm6345_periph_domain_ops, data);
+ if (!data->domain) { + if (!data->domain) {
+ kfree(data); + kfree(data);
+ return -EINVAL; + return -EINVAL;
@ -317,15 +362,15 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return 0; + return 0;
+} +}
+ +
+void __init bcm6345_l2_intc_init(int num_blocks, int *irq, void __iomem **base, +void __init bcm6345_periph_intc_init(int num_blocks, int *irq,
+ int num_words) + 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 +#ifdef CONFIG_OF
+static int __init bcm6345_l2_intc_of_init(struct device_node *node, +static int __init bcm6345_periph_of_init(struct device_node *node,
+ struct device_node *parent) + struct device_node *parent)
+{ +{
+ struct resource res; + struct resource res;
+ int num_irqs, ret = -EINVAL; + 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) + if (!ret)
+ return 0; + return 0;
+ +
@ -387,11 +432,11 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return ret; + return ret;
+} +}
+ +
+IRQCHIP_DECLARE(bcm6345_l2_intc, "brcm,bcm6345-l2-intc", +IRQCHIP_DECLARE(bcm6345_periph_intc, "brcm,bcm6345-periph-intc",
+ bcm6345_l2_intc_of_init); + bcm6345_periph_of_init);
+#endif +#endif
--- /dev/null --- /dev/null
+++ b/include/linux/irqchip/irq-bcm6345-l2-intc.h +++ b/include/linux/irqchip/irq-bcm6345-periph.h
@@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
+/* +/*
+ * This file is subject to the terms and conditions of the GNU General Public + * 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> + * Copyright (C) 2008 Nicolas Schichan <nschichan@freebox.fr>
+ */ + */
+ +
+#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_L2_INTC_H +#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_PERIPH_H
+#define __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_L2_INTC_H +#define __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_PERIPH_H
+ +
+void bcm6345_l2_intc_init(int num_blocks, int *irq, void __iomem **base, +void bcm6345_periph_intc_init(int num_blocks, int *irq, void __iomem **base,
+ int num_words); + int num_words);
+ +
+#endif /* __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_L2_INTC_H */ +#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;
}

View file

@ -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> From: Jonas Gorski <jogo@openwrt.org>
Date: Sun, 30 Nov 2014 14:54:27 +0100 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 interrupt controller
Signed-off-by: Jonas Gorski <jogo@openwrt.org> 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/Kconfig | 4 +
drivers/irqchip/Makefile | 1 + drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-bcm6345-ext.c | 296 ++++++++++++++++++++ drivers/irqchip/irq-bcm6345-ext.c | 286 ++++++++++++++++++++
include/linux/irqchip/irq-bcm6345-ext-intc.h | 14 + include/linux/irqchip/irq-bcm6345-ext.h | 14 +
5 files changed, 339 insertions(+) 5 files changed, 334 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-ext-intc.txt 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 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 --- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-ext-intc.txt +++ 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 +Broadcom BCM6345-style external interrupt controller
+ +
+Required properties: +Required properties:
+ +
+- compatible: should be "brcm,bcm6345-l2-intc" or "brcm,bcm6345-l2-intc" +- compatible: Should be "brcm,bcm6345-l2-intc".
+- reg: specifies the base physical addresses and size of the registers. +- reg: Specifies the base physical addresses and size of the registers.
+- interrupt-controller: identifies the node as an interrupt controller +- interrupt-controller: identifies the node as an interrupt controller.
+- #interrupt-cells: specifies the number of cells needed to encode an interrupt +- #interrupt-cells: Specifies the number of cells needed to encode an interrupt
+ source, should be 2 + source, Should be 2.
+- interrupt-parent: specifies the phandle to the parent interrupt controller +- interrupt-parent: Specifies the phandle to the parent interrupt controller
+ this one is cascaded from + this one is cascaded from.
+- interrupts: specifies the interrupt line(s) in the interrupt-parent controller +- interrupts: Specifies the interrupt line(s) in the interrupt-parent controller
+ node, valid values depend on the type of parent interrupt 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: +Example:
+ +
@ -53,7 +58,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ bool + bool
+ select IRQ_DOMAIN + select IRQ_DOMAIN
+ +
config BCM6345_L2_IRQ config BCM6345_PERIPH_IRQ
bool bool
select IRQ_DOMAIN select IRQ_DOMAIN
--- a/drivers/irqchip/Makefile --- 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_MXS) += irq-mxs.o
obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o
+obj-$(CONFIG_BCM6345_EXT_IRQ) += irq-bcm6345-ext.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_DW_APB_ICTL) += irq-dw-apb-ictl.o
obj-$(CONFIG_METAG) += irq-metag-ext.o obj-$(CONFIG_METAG) += irq-metag-ext.o
--- /dev/null --- /dev/null
+++ b/drivers/irqchip/irq-bcm6345-ext.c +++ 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 + * 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 + * 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/ioport.h>
+#include <linux/irq.h> +#include <linux/irq.h>
+#include <linux/irqchip/chained_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/kernel.h>
+#include <linux/of.h> +#include <linux/of.h>
+#include <linux/of_irq.h> +#include <linux/of_irq.h>
@ -110,7 +115,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+struct intc_data { +struct intc_data {
+ struct irq_chip chip; + struct irq_chip chip;
+ struct irq_domain *domain; + struct irq_domain *domain;
+ spinlock_t lock; + raw_spinlock_t lock;
+ +
+ int parent_irq[MAX_IRQS]; + int parent_irq[MAX_IRQS];
+ void __iomem *reg; + void __iomem *reg;
@ -141,11 +146,11 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ irq_hw_number_t hwirq = irqd_to_hwirq(data); + irq_hw_number_t hwirq = irqd_to_hwirq(data);
+ u32 reg; + u32 reg;
+ +
+ raw_spin_lock(priv->lock); + raw_spin_lock(&priv->lock);
+ reg = __raw_readl(priv->reg); + reg = __raw_readl(priv->reg);
+ reg |= hwirq << (EXTIRQ_CFG_CLEAR * priv->shift); + reg |= hwirq << (EXTIRQ_CFG_CLEAR * priv->shift);
+ __raw_writel(reg, priv->reg); + __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) +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); + irq_hw_number_t hwirq = irqd_to_hwirq(data);
+ u32 reg; + u32 reg;
+ +
+ raw_spin_lock(priv->lock); + raw_spin_lock(&priv->lock);
+ reg = __raw_readl(priv->reg); + reg = __raw_readl(priv->reg);
+ reg &= ~(hwirq << (EXTIRQ_CFG_MASK * priv->shift)); + reg &= ~(hwirq << (EXTIRQ_CFG_MASK * priv->shift));
+ __raw_writel(reg, priv->reg); + __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) +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); + irq_hw_number_t hwirq = irqd_to_hwirq(data);
+ u32 reg; + u32 reg;
+ +
+ raw_spin_lock(priv->lock); + raw_spin_lock(&priv->lock);
+ reg = __raw_readl(priv->reg); + reg = __raw_readl(priv->reg);
+ reg |= hwirq << (EXTIRQ_CFG_MASK * priv->shift); + reg |= hwirq << (EXTIRQ_CFG_MASK * priv->shift);
+ __raw_writel(reg, priv->reg); + __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, +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; + return -EINVAL;
+ } + }
+ +
+ raw_spin_lock(priv->lock); + raw_spin_lock(&priv->lock);
+ reg = __raw_readl(priv->reg); + reg = __raw_readl(priv->reg);
+ +
+ if (levelsense) + if (levelsense)
@ -230,7 +235,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ reg &= ~(hwirq << (EXTIRQ_CFG_BOTHEDGE * priv->shift)); + reg &= ~(hwirq << (EXTIRQ_CFG_BOTHEDGE * priv->shift));
+ +
+ __raw_writel(reg, priv->reg); + __raw_writel(reg, priv->reg);
+ raw_spin_unlock(priv->lock); + raw_spin_unlock(&priv->lock);
+ +
+ irqd_set_trigger_type(data, flow_type); + irqd_set_trigger_type(data, flow_type);
+ if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) + 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) + if (!data)
+ return -ENOMEM; + return -ENOMEM;
+ +
+ raw_spin_lock_init(&data->lock);
+
+ for (i = 0; i < num_irqs; i++) { + for (i = 0; i < num_irqs; i++) {
+ data->parent_irq[i] = irqs[i]; + data->parent_irq[i] = irqs[i];
+ +
@ -311,20 +318,23 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+} +}
+ +
+#ifdef CONFIG_OF +#ifdef CONFIG_OF
+static int __init bcm63xx_ext_intc_of_init(struct device_node *node, +static int __init bcm6345_ext_intc_of_init(struct device_node *node,
+ struct device_node *parent, + struct device_node *parent)
+ int shift)
+{ +{
+ int num_irqs, ret = -EINVAL; + int num_irqs, ret = -EINVAL;
+ unsigned i; + unsigned i;
+ void __iomem *base; + void __iomem *base;
+ int irqs[MAX_IRQS] = { 0 }; + int irqs[MAX_IRQS] = { 0 };
+ u32 shift;
+ +
+ num_irqs = of_irq_count(node); + num_irqs = of_irq_count(node);
+ +
+ if (!num_irqs || num_irqs > MAX_IRQS) + if (!num_irqs || num_irqs > MAX_IRQS)
+ return -EINVAL; + return -EINVAL;
+ +
+ if (of_property_read_u32(node, "brcm,field-width", &shift))
+ shift = 4;
+
+ for (i = 0; i < num_irqs; i++) { + for (i = 0; i < num_irqs; i++) {
+ irqs[i] = irq_of_parse_and_map(node, i); + irqs[i] = irq_of_parse_and_map(node, i);
+ if (!irqs[i]) { + if (!irqs[i]) {
@ -349,24 +359,11 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return ret; + 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", +IRQCHIP_DECLARE(bcm6345_ext_intc, "brcm,bcm6345-ext-intc",
+ bcm6345_ext_intc_of_init); + bcm6345_ext_intc_of_init);
+IRQCHIP_DECLARE(bcm6348_ext_intc, "brcm,bcm6348-ext-intc",
+ bcm6348_ext_intc_of_init);
+#endif +#endif
--- /dev/null --- /dev/null
+++ b/include/linux/irqchip/irq-bcm6345-ext-intc.h +++ b/include/linux/irqchip/irq-bcm6345-ext.h
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
+/* +/*
+ * This file is subject to the terms and conditions of the GNU General Public + * 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> + * Copyright (C) 2014 Jonas Gorski <jogo@openwrt.org>
+ */ + */
+ +
+#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_INTC_H +#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_H
+#define __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_INTC_H +#define __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_H
+ +
+void bcm6345_ext_intc_init(int n_irqs, int *irqs, void __iomem *reg, int shift); +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 */

View file

@ -19,7 +19,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
select DMA_NONCOHERENT select DMA_NONCOHERENT
select IRQ_CPU select IRQ_CPU
+ select BCM6345_EXT_IRQ + select BCM6345_EXT_IRQ
+ select BCM6345_L2_IRQ + select BCM6345_PERIPH_IRQ
+ select IRQ_DOMAIN + select IRQ_DOMAIN
select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_BIG_ENDIAN
@ -32,8 +32,8 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
#include <linux/irq.h> #include <linux/irq.h>
-#include <linux/spinlock.h> -#include <linux/spinlock.h>
+#include <linux/irqchip.h> +#include <linux/irqchip.h>
+#include <linux/irqchip/irq-bcm6345-ext-intc.h> +#include <linux/irqchip/irq-bcm6345-ext.h>
+#include <linux/irqchip/irq-bcm6345-l2-intc.h> +#include <linux/irqchip/irq-bcm6345-periph.h>
#include <asm/irq_cpu.h> #include <asm/irq_cpu.h>
#include <asm/mipsregs.h> #include <asm/mipsregs.h>
#include <bcm63xx_cpu.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_mask_addr[0] = bcm63xx_regset_address(RSET_PERF);
- irq_stat_addr[1] = bcm63xx_regset_address(RSET_PERF); - irq_stat_addr[1] = bcm63xx_regset_address(RSET_PERF);
- irq_mask_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]; + void __iomem *ext_intc_bases[2];
+ int l2_irq_count, l2_width, ext_irq_count, ext_shift; + int periph_irq_count, periph_width, ext_irq_count, ext_shift;
+ int l2_irqs[2] = { 2, 3 }; + int periph_irqs[2] = { 2, 3 };
+ int ext_irqs[6]; + int ext_irqs[6];
+ +
+ l2_intc_bases[0] = (void __iomem *)bcm63xx_regset_address(RSET_PERF); + periph_bases[0] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
+ l2_intc_bases[1] = (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[0] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
+ ext_intc_bases[1] = (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; - irq_bits = 32;
- ext_irq_count = 4; - ext_irq_count = 4;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_3368; - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_3368;
+ l2_intc_bases[0] += PERF_IRQMASK_3368_REG; + periph_bases[0] += PERF_IRQMASK_3368_REG;
+ l2_irq_count = 1; + periph_irq_count = 1;
+ l2_width = 1; + periph_width = 1;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_3368; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_3368;
+ ext_irq_count = 4; + 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_start = BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE;
- ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE; - ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328; - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328;
+ l2_intc_bases[0] += PERF_IRQMASK_6328_REG(0); + periph_bases[0] += PERF_IRQMASK_6328_REG(0);
+ l2_intc_bases[1] += PERF_IRQMASK_6328_REG(1); + periph_bases[1] += PERF_IRQMASK_6328_REG(1);
+ l2_irq_count = 2; + periph_irq_count = 2;
+ l2_width = 2; + periph_width = 2;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6328; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6328;
+ ext_irq_count = 4; + ext_irq_count = 4;
@ -513,9 +513,9 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- irq_bits = 32; - irq_bits = 32;
- ext_irq_count = 4; - ext_irq_count = 4;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6338; - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6338;
+ l2_intc_bases[0] += PERF_IRQMASK_6338_REG; + periph_bases[0] += PERF_IRQMASK_6338_REG;
+ l2_irq_count = 1; + periph_irq_count = 1;
+ l2_width = 1; + periph_width = 1;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6338; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6338;
+ ext_irq_count = 4; + ext_irq_count = 4;
@ -533,9 +533,9 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- irq_bits = 32; - irq_bits = 32;
- ext_irq_count = 4; - ext_irq_count = 4;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6345; - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6345;
+ l2_intc_bases[0] += PERF_IRQMASK_6345_REG; + periph_bases[0] += PERF_IRQMASK_6345_REG;
+ l2_irq_count = 1; + periph_irq_count = 1;
+ l2_width = 1; + periph_width = 1;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6345; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6345;
+ ext_irq_count = 4; + ext_irq_count = 4;
@ -553,9 +553,9 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- irq_bits = 32; - irq_bits = 32;
- ext_irq_count = 4; - ext_irq_count = 4;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6348; - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6348;
+ l2_intc_bases[0] += PERF_IRQMASK_6348_REG; + periph_bases[0] += PERF_IRQMASK_6348_REG;
+ l2_irq_count = 1; + periph_irq_count = 1;
+ l2_width = 1; + periph_width = 1;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6348; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6348;
+ ext_irq_count = 4; + 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_start = BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE;
- ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE; - ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6358; - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6358;
+ l2_intc_bases[0] += PERF_IRQMASK_6358_REG(0); + periph_bases[0] += PERF_IRQMASK_6358_REG(0);
+ l2_intc_bases[1] += PERF_IRQMASK_6358_REG(1); + periph_bases[1] += PERF_IRQMASK_6358_REG(1);
+ l2_irq_count = 2; + periph_irq_count = 2;
+ l2_width = 1; + periph_width = 1;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6358; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6358;
+ ext_irq_count = 4; + 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_start = BCM_6362_EXT_IRQ0 - IRQ_INTERNAL_BASE;
- ext_irq_end = BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE; - ext_irq_end = BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6362; - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6362;
+ l2_intc_bases[0] += PERF_IRQMASK_6362_REG(0); + periph_bases[0] += PERF_IRQMASK_6362_REG(0);
+ l2_intc_bases[1] += PERF_IRQMASK_6362_REG(1); + periph_bases[1] += PERF_IRQMASK_6362_REG(1);
+ l2_irq_count = 2; + periph_irq_count = 2;
+ l2_width = 2; + periph_width = 2;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6362; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6362;
+ ext_irq_count = 4; + 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_stat_addr[1] += PERF_IRQSTAT_6368_REG(1);
- irq_mask_addr[1] += PERF_IRQMASK_6368_REG(1); - irq_mask_addr[1] += PERF_IRQMASK_6368_REG(1);
- irq_bits = 64; - irq_bits = 64;
+ l2_intc_bases[0] += PERF_IRQMASK_6368_REG(0); + periph_bases[0] += PERF_IRQMASK_6368_REG(0);
+ l2_intc_bases[1] += PERF_IRQMASK_6368_REG(1); + periph_bases[1] += PERF_IRQMASK_6368_REG(1);
+ l2_irq_count = 2; + periph_irq_count = 2;
+ l2_width = 2; + periph_width = 2;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6368; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6368;
+ ext_intc_bases[1] += PERF_EXTIRQ_CFG_REG2_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; - internal_irq_unmask = __internal_irq_unmask_64;
- } - }
+ mips_cpu_irq_init(); + 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); + bcm6345_ext_intc_init(4, ext_irqs, ext_intc_bases[0], ext_shift);
+ if (ext_irq_count > 4) + if (ext_irq_count > 4)
+ bcm6345_ext_intc_init(2, &ext_irqs[4], ext_intc_bases[1], + bcm6345_ext_intc_init(2, &ext_irqs[4], ext_intc_bases[1],

View file

@ -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> From: Jonas Gorski <jogo@openwrt.org>
Date: Sun, 30 Nov 2014 20:20:30 +0100 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 and 5
Due to the external interrupts being non consecutive, the previous 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 --- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c +++ b/arch/mips/bcm63xx/irq.c
@@ -109,11 +109,14 @@ static void bcm63xx_init_irq(void) @@ -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_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6358;
- ext_irq_count = 4; - ext_irq_count = 4;

View file

@ -289,10 +289,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
ext_shift = 4; ext_shift = 4;
break; break;
+ case BCM63268_CPU_ID: + case BCM63268_CPU_ID:
+ l2_intc_bases[0] += PERF_IRQSTAT_63268_REG(0); + periph_bases[0] += PERF_IRQSTAT_63268_REG(0);
+ l2_intc_bases[1] += PERF_IRQSTAT_63268_REG(1); + periph_bases[1] += PERF_IRQSTAT_63268_REG(1);
+ l2_irq_count = 2; + periph_irq_count = 2;
+ l2_width = 4; + periph_width = 4;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_63268; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_63268;
+ ext_irq_count = 4; + ext_irq_count = 4;

View file

@ -199,9 +199,9 @@ Subject: [PATCH 51/53] MIPS: BCM63XX: add support for BCM6318
ext_shift = 4; ext_shift = 4;
break; break;
+ case BCM6318_CPU_ID: + case BCM6318_CPU_ID:
+ l2_intc_bases[0] += PERF_IRQMASK_6318_REG; + periph_bases[0] += PERF_IRQMASK_6318_REG;
+ l2_irq_count = 1; + periph_irq_count = 1;
+ l2_width = 4; + periph_width = 4;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6318; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6318;
+ ext_irq_count = 4; + ext_irq_count = 4;
@ -212,8 +212,8 @@ Subject: [PATCH 51/53] MIPS: BCM63XX: add support for BCM6318
+ ext_shift = 4; + ext_shift = 4;
+ break; + break;
case BCM6328_CPU_ID: case BCM6328_CPU_ID:
l2_intc_bases[0] += PERF_IRQMASK_6328_REG(0); periph_bases[0] += PERF_IRQMASK_6328_REG(0);
l2_intc_bases[1] += PERF_IRQMASK_6328_REG(1); periph_bases[1] += PERF_IRQMASK_6328_REG(1);
--- a/arch/mips/bcm63xx/prom.c --- a/arch/mips/bcm63xx/prom.c
+++ b/arch/mips/bcm63xx/prom.c +++ b/arch/mips/bcm63xx/prom.c
@@ -72,7 +72,7 @@ void __init prom_init(void) @@ -72,7 +72,7 @@ void __init prom_init(void)

View file

@ -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> From: Jonas Gorski <jogo@openwrt.org>
Date: Mon, 1 Dec 2014 00:20:07 +0100 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> Signed-off-by: Jonas Gorski <jogo@openwrt.org>
--- ---
arch/mips/bcm63xx/irq.c | 10 +++++++++- arch/mips/bcm63xx/irq.c | 12 +++++++++++-
1 file changed, 9 insertions(+), 1 deletion(-) 1 file changed, 11 insertions(+), 1 deletion(-)
--- a/arch/mips/bcm63xx/irq.c --- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c +++ b/arch/mips/bcm63xx/irq.c
@@ -15,6 +15,8 @@ @@ -15,6 +15,8 @@
#include <linux/irqchip.h> #include <linux/irqchip.h>
#include <linux/irqchip/irq-bcm6345-ext-intc.h> #include <linux/irqchip/irq-bcm6345-ext.h>
#include <linux/irqchip/irq-bcm6345-l2-intc.h> #include <linux/irqchip/irq-bcm6345-periph.h>
+#include <linux/of.h> +#include <linux/of.h>
+#include <linux/of_fdt.h> +#include <linux/of_fdt.h>
#include <asm/irq_cpu.h> #include <asm/irq_cpu.h>
#include <asm/mipsregs.h> #include <asm/mipsregs.h>
#include <bcm63xx_cpu.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); ext_shift);
} }
@ -31,8 +31,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
void __init arch_init_irq(void) void __init arch_init_irq(void)
{ {
- bcm63xx_init_irq(); - bcm63xx_init_irq();
+#ifdef CONFIG_OF
+ if (initial_boot_params) + if (initial_boot_params)
+ irqchip_init(); + irqchip_init();
+ else + else
+#endif
+ bcm63xx_init_irq(); + bcm63xx_init_irq();
} }

View file

@ -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> From: Jonas Gorski <jogo@openwrt.org>
Date: Sun, 30 Nov 2014 14:53:12 +0100 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 controller
Signed-off-by: Jonas Gorski <jogo@openwrt.org> 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/Kconfig | 4 +
drivers/irqchip/Makefile | 1 + drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-bcm6345-l2.c | 320 ++++++++++++++++++++ drivers/irqchip/irq-bcm6345-periph.c | 339 ++++++++++++++++++++
include/linux/irqchip/irq-bcm6345-l2-intc.h | 16 + include/linux/irqchip/irq-bcm6345-periph.h | 16 +
5 files changed, 366 insertions(+) 5 files changed, 410 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-l2-intc.txt create mode 100644 Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-periph-intc.txt
create mode 100644 drivers/irqchip/irq-bcm6345-l2.c create mode 100644 drivers/irqchip/irq-bcm6345-periph.c
create mode 100644 include/linux/irqchip/irq-bcm6345-l2-intc.h create mode 100644 include/linux/irqchip/irq-bcm6345-periph.h
--- /dev/null --- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-l2-intc.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-periph-intc.txt
@@ -0,0 +1,25 @@ @@ -0,0 +1,50 @@
+Broadcom BCM6345 Level 2 interrupt controller +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: +Required properties:
+ +
+- compatible: should be "brcm,bcm6345-l2-intc" +- compatible: Should be "brcm,bcm6345-periph-intc".
+- reg: specifies the base physical address and size of the registers; +- reg: Specifies the base physical address and size of the registers.
+ multiple regs may be specified, and must match the amount of parent interrupts + Multiple register addresses may be specified, and must match the amount of
+- interrupt-controller: identifies the node as an interrupt controller + parent interrupts.
+- #interrupt-cells: specifies the number of cells needed to encode an interrupt +- interrupt-controller: Identifies the node as an interrupt controller.
+ source, should be 1 +- #interrupt-cells: Specifies the number of cells needed to encode an interrupt
+- interrupt-parent: specifies the phandle to the parent interrupt controller + source, should be 1.
+ this one is cascaded from +- interrupt-parent: Specifies the phandle to the parent interrupt controller
+- interrupts: specifies the interrupt line(s) in the interrupt-parent controller + this one is cascaded from.
+ node, valid values depend on the type of parent interrupt controller +- 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: +Example:
+ +
+periph_intc: interrupt-controller@f0406800 { +periph_intc: interrupt-controller@f0406800 {
+ compatible = "brcm,bcm6345-l2-intc"; + compatible = "brcm,bcm6345-periph-intc";
+ interrupt-parent = <&mips_intc>; + reg = <0x10000020 0x10>, <0x10000030 0x10>;
+ #interrupt-cells = <1>; +
+ reg = <0x10000020 0x10> <0x10000030 0x10>;
+ interrupt-controller; + interrupt-controller;
+ #interrupt-cells = <1>;
+
+ interrupt-parent = <&cpu_intc>;
+ interrupts = <2>, <3>; + interrupts = <2>, <3>;
+}; +};
--- a/drivers/irqchip/Kconfig --- a/drivers/irqchip/Kconfig
@ -50,7 +75,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
select GENERIC_IRQ_CHIP select GENERIC_IRQ_CHIP
select IRQ_DOMAIN select IRQ_DOMAIN
+config BCM6345_L2_IRQ +config BCM6345_PERIPH_IRQ
+ bool + bool
+ select IRQ_DOMAIN + 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_MVEBU) += irq-armada-370-xp.o
obj-$(CONFIG_ARCH_MXS) += irq-mxs.o obj-$(CONFIG_ARCH_MXS) += irq-mxs.o
obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.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_DW_APB_ICTL) += irq-dw-apb-ictl.o
obj-$(CONFIG_METAG) += irq-metag-ext.o obj-$(CONFIG_METAG) += irq-metag-ext.o
obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o
--- /dev/null --- /dev/null
+++ b/drivers/irqchip/irq-bcm6345-l2.c +++ b/drivers/irqchip/irq-bcm6345-periph.c
@@ -0,0 +1,320 @@ @@ -0,0 +1,339 @@
+/* +/*
+ * This file is subject to the terms and conditions of the GNU General Public + * 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 + * 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/ioport.h>
+#include <linux/irq.h> +#include <linux/irq.h>
+#include <linux/irqchip/chained_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/kernel.h>
+#include <linux/of.h> +#include <linux/of.h>
+#include <linux/of_irq.h> +#include <linux/of_irq.h>
@ -118,10 +143,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ int num_words; + int num_words;
+ +
+ struct irq_domain *domain; + 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 intc_data *data = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_chip *chip = irq_desc_get_chip(desc);
@ -139,43 +164,36 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ unsigned long pending; + unsigned long pending;
+ int hw_irq; + int hw_irq;
+ +
+ raw_spin_lock(data->lock); + raw_spin_lock(&data->lock);
+ pending = __raw_readl(block->en_reg[idx]) & + pending = __raw_readl(block->en_reg[idx]) &
+ __raw_readl(block->status_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) { + 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); + 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)
+{ +{
+ unsigned int i, reg, bit; + u32 val;
+ struct intc_data *priv = data->domain->host_data;
+ irq_hw_number_t hwirq = irqd_to_hwirq(data);
+ +
+ reg = hwirq / IRQS_PER_WORD; + val = __raw_readl(block->en_reg[reg]);
+ bit = hwirq % IRQS_PER_WORD; + if (enable)
+ + val |= BIT(bit);
+ raw_spin_lock(priv->lock); + else
+ for (i = 0; i < MAX_PARENT_IRQS; i++) { + val &= ~BIT(bit);
+ struct intc_block *block = &priv->block[i]; + __raw_writel(val, block->en_reg[reg]);
+ u32 val;
+
+ if (!block->parent_irq)
+ break;
+
+ val = __raw_readl(block->en_reg[reg]);
+ __raw_writel(val & ~BIT(bit), block->en_reg[reg]);
+ }
+ raw_spin_unlock(priv->lock);
+} +}
+ +
+static void bcm6345_l2_intc_irq_unmask(struct irq_data *data) +static void bcm6345_periph_irq_mask(struct irq_data *data)
+{ +{
+ unsigned int i, reg, bit; + unsigned int i, reg, bit;
+ struct intc_data *priv = data->domain->host_data; + struct intc_data *priv = data->domain->host_data;
@ -184,35 +202,51 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ reg = hwirq / IRQS_PER_WORD; + reg = hwirq / IRQS_PER_WORD;
+ bit = 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++) { + for (i = 0; i < MAX_PARENT_IRQS; i++) {
+ struct intc_block *block = &priv->block[i]; + struct intc_block *block = &priv->block[i];
+ u32 val;
+ +
+ if (!block->parent_irq) + if (!block->parent_irq)
+ break; + break;
+ +
+ val = __raw_readl(block->en_reg[reg]); + __bcm6345_periph_enable(block, reg, bit, false);
+ }
+ raw_spin_unlock(&priv->lock);
+}
+
+static void bcm6345_periph_irq_unmask(struct irq_data *data)
+{
+ 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);
+ for (i = 0; i < MAX_PARENT_IRQS; i++) {
+ struct intc_block *block = &priv->block[i];
+
+ if (!block->parent_irq)
+ break;
+ +
+ if (block->mask_cache[reg] & BIT(bit)) + if (block->mask_cache[reg] & BIT(bit))
+ val |= BIT(bit); + __bcm6345_periph_enable(block, reg, bit, true);
+ else + else
+ val &= ~BIT(bit); + __bcm6345_periph_enable(block, reg, bit, false);
+
+ __raw_writel(val, block->en_reg[reg]);
+
+ } + }
+ raw_spin_unlock(priv->lock); + raw_spin_unlock(&priv->lock);
+} +}
+ +
+#ifdef CONFIG_SMP +#ifdef CONFIG_SMP
+static int bcm6345_l2_intc_set_affinity(struct irq_data *data, +static int bcm6345_periph_set_affinity(struct irq_data *data,
+ const struct cpumask *mask, + const struct cpumask *mask, bool force)
+ bool force)
+{ +{
+ irq_hw_number_t hwirq = irqd_to_hwirq(data); + irq_hw_number_t hwirq = irqd_to_hwirq(data);
+ struct intc_data *priv = data->domain->host_data; + struct intc_data *priv = data->domain->host_data;
+ unsigned int i, reg, bit; + unsigned int i, reg, bit;
+ unsigned long flags;
+ bool enabled;
+ int cpu; + int cpu;
+ +
+ reg = hwirq / IRQS_PER_WORD; + reg = hwirq / IRQS_PER_WORD;
@ -231,21 +265,30 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ if (!priv->block[cpu].parent_irq) + if (!priv->block[cpu].parent_irq)
+ return -EINVAL; + 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++) { + for (i = 0; i < MAX_PARENT_IRQS; i++) {
+ if (i == cpu) + struct intc_block *block = &priv->block[i];
+ priv->block[i].mask_cache[reg] |= BIT(bit); +
+ else + if (!block->parent_irq)
+ priv->block[i].mask_cache[reg] &= ~BIT(bit); + 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; + return 0;
+} +}
+#endif +#endif
+ +
+static int bcm6345_l2_map(struct irq_domain *d, unsigned int irq, +static int bcm6345_periph_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; + struct intc_data *priv = d->host_data;
+ +
@ -254,14 +297,14 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return 0; + 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, + .xlate = irq_domain_xlate_onecell,
+ .map = bcm6345_l2_map, + .map = bcm6345_periph_map,
+}; +};
+ +
+static int __init __bcm6345_l2_intc_init(struct device_node *node, +static int __init __bcm6345_periph_intc_init(struct device_node *node,
+ int num_blocks, int *irq, + int num_blocks, int *irq,
+ void __iomem **base, int num_words) + void __iomem **base, int num_words)
+{ +{
+ struct intc_data *data; + struct intc_data *data;
+ unsigned int i, w, status_offset; + unsigned int i, w, status_offset;
@ -270,6 +313,8 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ if (!data) + if (!data)
+ return -ENOMEM; + return -ENOMEM;
+ +
+ raw_spin_lock_init(&data->lock);
+
+ status_offset = num_words * sizeof(u32); + status_offset = num_words * sizeof(u32);
+ +
+ for (i = 0; i < num_blocks; i++) { + 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] = base[i] + status_offset;
+ block->status_reg[w] += word_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) + if (i == 0)
+ block->mask_cache[w] = 0xffffffff; + block->mask_cache[w] = 0xffffffff;
+ } + }
+ +
+ irq_set_handler_data(block->parent_irq, data); + irq_set_handler_data(block->parent_irq, data);
+ irq_set_chained_handler(block->parent_irq, + irq_set_chained_handler(block->parent_irq,
+ bcm6345_l2_intc_irq_handle); + bcm6345_periph_irq_handle);
+ } + }
+ +
+ data->num_words = num_words; + data->num_words = num_words;
+ +
+ data->chip.name = "bcm6345-l2-intc"; + data->chip.name = "bcm6345-periph-intc";
+ data->chip.irq_mask = bcm6345_l2_intc_irq_mask; + data->chip.irq_mask = bcm6345_periph_irq_mask;
+ data->chip.irq_unmask = bcm6345_l2_intc_irq_unmask; + data->chip.irq_unmask = bcm6345_periph_irq_unmask;
+ +
+#ifdef CONFIG_SMP +#ifdef CONFIG_SMP
+ if (num_blocks > 1) + if (num_blocks > 1)
+ data->chip.set_affinity = bcm6345_l2_intc_set_affinity; + data->chip.irq_set_affinity = bcm6345_periph_set_affinity;
+#endif +#endif
+ +
+ data->domain = irq_domain_add_simple(node, IRQS_PER_WORD * num_words, + data->domain = irq_domain_add_simple(node, IRQS_PER_WORD * num_words,
+ VIRQ_BASE, &bcm6345_l2_domain_ops, + VIRQ_BASE,
+ data); + &bcm6345_periph_domain_ops, data);
+ if (!data->domain) { + if (!data->domain) {
+ kfree(data); + kfree(data);
+ return -EINVAL; + return -EINVAL;
@ -317,15 +362,15 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return 0; + return 0;
+} +}
+ +
+void __init bcm6345_l2_intc_init(int num_blocks, int *irq, void __iomem **base, +void __init bcm6345_periph_intc_init(int num_blocks, int *irq,
+ int num_words) + 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 +#ifdef CONFIG_OF
+static int __init bcm6345_l2_intc_of_init(struct device_node *node, +static int __init bcm6345_periph_of_init(struct device_node *node,
+ struct device_node *parent) + struct device_node *parent)
+{ +{
+ struct resource res; + struct resource res;
+ int num_irqs, ret = -EINVAL; + int num_irqs, ret = -EINVAL;
@ -346,19 +391,18 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ if (!irqs[i]) + if (!irqs[i])
+ goto out_unmap; + goto out_unmap;
+ +
+ if (of_address_to_resource(node, i, &res)) { + if (of_address_to_resource(node, i, &res))
+ goto out_unmap; + goto out_unmap;
+ }
+ +
+ size = resource_size(&res); + size = resource_size(&res);
+ switch (size) { + switch (size) {
+ case 8: + case 8:
+ case 16: + case 16:
+ case 32: + case 32:
+ size = size / 8; + size = size / 8;
+ break; + break;
+ default: + default:
+ goto out_unmap; + goto out_unmap;
+ } + }
+ +
+ if (words && words != size) { + 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) + if (!ret)
+ return 0; + return 0;
+ +
@ -387,11 +431,11 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return ret; + return ret;
+} +}
+ +
+IRQCHIP_DECLARE(bcm6345_l2_intc, "brcm,bcm6345-l2-intc", +IRQCHIP_DECLARE(bcm6345_periph_intc, "brcm,bcm6345-periph-intc",
+ bcm6345_l2_intc_of_init); + bcm6345_periph_of_init);
+#endif +#endif
--- /dev/null --- /dev/null
+++ b/include/linux/irqchip/irq-bcm6345-l2-intc.h +++ b/include/linux/irqchip/irq-bcm6345-periph.h
@@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
+/* +/*
+ * This file is subject to the terms and conditions of the GNU General Public + * 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> + * Copyright (C) 2008 Nicolas Schichan <nschichan@freebox.fr>
+ */ + */
+ +
+#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_L2_INTC_H +#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_PERIPH_H
+#define __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_L2_INTC_H +#define __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_PERIPH_H
+ +
+void bcm6345_l2_intc_init(int num_blocks, int *irq, void __iomem **base, +void bcm6345_periph_intc_init(int num_blocks, int *irq, void __iomem **base,
+ int num_words); + int num_words);
+ +
+#endif /* __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_L2_INTC_H */ +#endif /* __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_PERIPH_H */

View file

@ -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> From: Jonas Gorski <jogo@openwrt.org>
Date: Sun, 30 Nov 2014 14:54:27 +0100 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 interrupt controller
Signed-off-by: Jonas Gorski <jogo@openwrt.org> 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/Kconfig | 4 +
drivers/irqchip/Makefile | 1 + drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-bcm6345-ext.c | 296 ++++++++++++++++++++ drivers/irqchip/irq-bcm6345-ext.c | 287 ++++++++++++++++++++
include/linux/irqchip/irq-bcm6345-ext-intc.h | 14 + include/linux/irqchip/irq-bcm6345-ext.h | 14 +
5 files changed, 339 insertions(+) 5 files changed, 335 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-ext-intc.txt 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 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 --- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-ext-intc.txt +++ 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 +Broadcom BCM6345-style external interrupt controller
+ +
+Required properties: +Required properties:
+ +
+- compatible: should be "brcm,bcm6345-l2-intc" or "brcm,bcm6345-l2-intc" +- compatible: Should be "brcm,bcm6345-l2-intc".
+- reg: specifies the base physical addresses and size of the registers. +- reg: Specifies the base physical addresses and size of the registers.
+- interrupt-controller: identifies the node as an interrupt controller +- interrupt-controller: identifies the node as an interrupt controller.
+- #interrupt-cells: specifies the number of cells needed to encode an interrupt +- #interrupt-cells: Specifies the number of cells needed to encode an interrupt
+ source, should be 2 + source, Should be 2.
+- interrupt-parent: specifies the phandle to the parent interrupt controller +- interrupt-parent: Specifies the phandle to the parent interrupt controller
+ this one is cascaded from + this one is cascaded from.
+- interrupts: specifies the interrupt line(s) in the interrupt-parent controller +- interrupts: Specifies the interrupt line(s) in the interrupt-parent controller
+ node, valid values depend on the type of parent interrupt 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: +Example:
+ +
@ -53,7 +58,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ bool + bool
+ select IRQ_DOMAIN + select IRQ_DOMAIN
+ +
config BCM6345_L2_IRQ config BCM6345_PERIPH_IRQ
bool bool
select IRQ_DOMAIN select IRQ_DOMAIN
--- a/drivers/irqchip/Makefile --- 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_MXS) += irq-mxs.o
obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o
+obj-$(CONFIG_BCM6345_EXT_IRQ) += irq-bcm6345-ext.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_DW_APB_ICTL) += irq-dw-apb-ictl.o
obj-$(CONFIG_METAG) += irq-metag-ext.o obj-$(CONFIG_METAG) += irq-metag-ext.o
--- /dev/null --- /dev/null
+++ b/drivers/irqchip/irq-bcm6345-ext.c +++ 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 + * 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 + * License. See the file "COPYING" in the main directory of this archive
+ * for more details. + * for more details.
+ * + *
+ * Copyright (C) 2014 Jonas Gorski <jogo@openwrt.org> + * Copyright (C) 2014 Jonas Gorski <jogo@openwrt.org>
+i */ + */
+ +
+#include <linux/ioport.h> +#include <linux/ioport.h>
+#include <linux/irq.h> +#include <linux/irq.h>
+#include <linux/irqchip/chained_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/kernel.h>
+#include <linux/of.h> +#include <linux/of.h>
+#include <linux/of_irq.h> +#include <linux/of_irq.h>
@ -110,7 +115,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+struct intc_data { +struct intc_data {
+ struct irq_chip chip; + struct irq_chip chip;
+ struct irq_domain *domain; + struct irq_domain *domain;
+ spinlock_t lock; + raw_spinlock_t lock;
+ +
+ int parent_irq[MAX_IRQS]; + int parent_irq[MAX_IRQS];
+ void __iomem *reg; + void __iomem *reg;
@ -141,11 +146,11 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ irq_hw_number_t hwirq = irqd_to_hwirq(data); + irq_hw_number_t hwirq = irqd_to_hwirq(data);
+ u32 reg; + u32 reg;
+ +
+ raw_spin_lock(priv->lock); + raw_spin_lock(&priv->lock);
+ reg = __raw_readl(priv->reg); + reg = __raw_readl(priv->reg);
+ reg |= hwirq << (EXTIRQ_CFG_CLEAR * priv->shift); + reg |= hwirq << (EXTIRQ_CFG_CLEAR * priv->shift);
+ __raw_writel(reg, priv->reg); + __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) +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); + irq_hw_number_t hwirq = irqd_to_hwirq(data);
+ u32 reg; + u32 reg;
+ +
+ raw_spin_lock(priv->lock); + raw_spin_lock(&priv->lock);
+ reg = __raw_readl(priv->reg); + reg = __raw_readl(priv->reg);
+ reg &= ~(hwirq << (EXTIRQ_CFG_MASK * priv->shift)); + reg &= ~(hwirq << (EXTIRQ_CFG_MASK * priv->shift));
+ __raw_writel(reg, priv->reg); + __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) +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); + irq_hw_number_t hwirq = irqd_to_hwirq(data);
+ u32 reg; + u32 reg;
+ +
+ raw_spin_lock(priv->lock); + raw_spin_lock(&priv->lock);
+ reg = __raw_readl(priv->reg); + reg = __raw_readl(priv->reg);
+ reg |= hwirq << (EXTIRQ_CFG_MASK * priv->shift); + reg |= hwirq << (EXTIRQ_CFG_MASK * priv->shift);
+ __raw_writel(reg, priv->reg); + __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, +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; + return -EINVAL;
+ } + }
+ +
+ raw_spin_lock(priv->lock); + raw_spin_lock(&priv->lock);
+ reg = __raw_readl(priv->reg); + reg = __raw_readl(priv->reg);
+ +
+ if (levelsense) + if (levelsense)
@ -230,7 +235,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ reg &= ~(hwirq << (EXTIRQ_CFG_BOTHEDGE * priv->shift)); + reg &= ~(hwirq << (EXTIRQ_CFG_BOTHEDGE * priv->shift));
+ +
+ __raw_writel(reg, priv->reg); + __raw_writel(reg, priv->reg);
+ raw_spin_unlock(priv->lock); + raw_spin_unlock(&priv->lock);
+ +
+ irqd_set_trigger_type(data, flow_type); + irqd_set_trigger_type(data, flow_type);
+ if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) + 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, +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; + struct intc_data *priv = d->host_data;
+ +
@ -251,7 +256,6 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return 0; + return 0;
+} +}
+ +
+
+static const struct irq_domain_ops bcm6345_ext_domain_ops = { +static const struct irq_domain_ops bcm6345_ext_domain_ops = {
+ .xlate = irq_domain_xlate_twocell, + .xlate = irq_domain_xlate_twocell,
+ .map = bcm6345_ext_intc_map, + .map = bcm6345_ext_intc_map,
@ -269,6 +273,8 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ if (!data) + if (!data)
+ return -ENOMEM; + return -ENOMEM;
+ +
+ raw_spin_lock_init(&data->lock);
+
+ for (i = 0; i < num_irqs; i++) { + for (i = 0; i < num_irqs; i++) {
+ data->parent_irq[i] = irqs[i]; + data->parent_irq[i] = irqs[i];
+ +
@ -311,20 +317,23 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+} +}
+ +
+#ifdef CONFIG_OF +#ifdef CONFIG_OF
+static int __init bcm63xx_ext_intc_of_init(struct device_node *node, +static int __init bcm6345_ext_intc_of_init(struct device_node *node,
+ struct device_node *parent, + struct device_node *parent)
+ int shift)
+{ +{
+ int num_irqs, ret = -EINVAL; + int num_irqs, ret = -EINVAL;
+ unsigned i; + unsigned i;
+ void __iomem *base; + void __iomem *base;
+ int irqs[MAX_IRQS] = { 0 }; + int irqs[MAX_IRQS] = { 0 };
+ u32 shift;
+ +
+ num_irqs = of_irq_count(node); + num_irqs = of_irq_count(node);
+ +
+ if (!num_irqs || num_irqs > MAX_IRQS) + if (!num_irqs || num_irqs > MAX_IRQS)
+ return -EINVAL; + return -EINVAL;
+ +
+ if (of_property_read_u32(node, "brcm,field-width", &shift))
+ shift = 4;
+
+ for (i = 0; i < num_irqs; i++) { + for (i = 0; i < num_irqs; i++) {
+ irqs[i] = irq_of_parse_and_map(node, i); + irqs[i] = irq_of_parse_and_map(node, i);
+ if (!irqs[i]) { + if (!irqs[i]) {
@ -349,24 +358,11 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ return ret; + 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", +IRQCHIP_DECLARE(bcm6345_ext_intc, "brcm,bcm6345-ext-intc",
+ bcm6345_ext_intc_of_init); + bcm6345_ext_intc_of_init);
+IRQCHIP_DECLARE(bcm6348_ext_intc, "brcm,bcm6348-ext-intc",
+ bcm6348_ext_intc_of_init);
+#endif +#endif
--- /dev/null --- /dev/null
+++ b/include/linux/irqchip/irq-bcm6345-ext-intc.h +++ b/include/linux/irqchip/irq-bcm6345-ext.h
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
+/* +/*
+ * This file is subject to the terms and conditions of the GNU General Public + * 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> + * Copyright (C) 2014 Jonas Gorski <jogo@openwrt.org>
+ */ + */
+ +
+#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_INTC_H +#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_H
+#define __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_INTC_H +#define __INCLUDE_LINUX_IRQCHIP_IRQ_BCM6345_EXT_H
+ +
+void bcm6345_ext_intc_init(int n_irqs, int *irqs, void __iomem *reg, int shift); +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 */

View file

@ -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> From: Jonas Gorski <jogo@openwrt.org>
Date: Sun, 30 Nov 2014 14:55:02 +0100 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, Now that we have working IRQ_DOMAIN drivers for both interrupt controllers,
switch to using them. switch to using them.
@ -9,8 +9,8 @@ switch to using them.
Signed-off-by: Jonas Gorski <jogo@openwrt.org> Signed-off-by: Jonas Gorski <jogo@openwrt.org>
--- ---
arch/mips/Kconfig | 3 + arch/mips/Kconfig | 3 +
arch/mips/bcm63xx/irq.c | 608 ++++++++--------------------------------------- arch/mips/bcm63xx/irq.c | 609 +++++++++--------------------------------------
2 files changed, 108 insertions(+), 503 deletions(-) 2 files changed, 109 insertions(+), 503 deletions(-)
--- a/arch/mips/Kconfig --- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig +++ b/arch/mips/Kconfig
@ -19,7 +19,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
select DMA_NONCOHERENT select DMA_NONCOHERENT
select IRQ_CPU select IRQ_CPU
+ select BCM6345_EXT_IRQ + select BCM6345_EXT_IRQ
+ select BCM6345_L2_IRQ + select BCM6345_PERIPH_IRQ
+ select IRQ_DOMAIN + select IRQ_DOMAIN
select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_BIG_ENDIAN
@ -32,12 +32,12 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
#include <linux/irq.h> #include <linux/irq.h>
-#include <linux/spinlock.h> -#include <linux/spinlock.h>
+#include <linux/irqchip.h> +#include <linux/irqchip.h>
+#include <linux/irqchip/irq-bcm6345-ext-intc.h> +#include <linux/irqchip/irq-bcm6345-ext.h>
+#include <linux/irqchip/irq-bcm6345-l2-intc.h> +#include <linux/irqchip/irq-bcm6345-periph.h>
#include <asm/irq_cpu.h> #include <asm/irq_cpu.h>
#include <asm/mipsregs.h> #include <asm/mipsregs.h>
#include <bcm63xx_cpu.h> #include <bcm63xx_cpu.h>
@@ -20,544 +22,144 @@ @@ -20,544 +22,145 @@
#include <bcm63xx_io.h> #include <bcm63xx_io.h>
#include <bcm63xx_irq.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_mask_addr[0] = bcm63xx_regset_address(RSET_PERF);
- irq_stat_addr[1] = bcm63xx_regset_address(RSET_PERF); - irq_stat_addr[1] = bcm63xx_regset_address(RSET_PERF);
- irq_mask_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]; + void __iomem *ext_intc_bases[2];
+ int l2_irq_count, l2_width, ext_irq_count, ext_shift; + int periph_irq_count, periph_width, ext_irq_count, ext_shift;
+ int l2_irqs[2] = { 2, 3 }; + int periph_irqs[2] = { 2, 3 };
+ int ext_irqs[6]; + int ext_irqs[6];
+ +
+ l2_intc_bases[0] = (void __iomem *)bcm63xx_regset_address(RSET_PERF); + periph_bases[0] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
+ l2_intc_bases[1] = (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[0] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
+ ext_intc_bases[1] = (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; - irq_bits = 32;
- ext_irq_count = 4; - ext_irq_count = 4;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_3368; - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_3368;
+ l2_intc_bases[0] += PERF_IRQMASK_3368_REG; + periph_bases[0] += PERF_IRQMASK_3368_REG;
+ l2_irq_count = 1; + periph_irq_count = 1;
+ l2_width = 1; + periph_width = 1;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_3368; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_3368;
+ ext_irq_count = 4; + 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_start = BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE;
- ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE; - ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328; - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328;
+ l2_intc_bases[0] += PERF_IRQMASK_6328_REG(0); + periph_bases[0] += PERF_IRQMASK_6328_REG(0);
+ l2_intc_bases[1] += PERF_IRQMASK_6328_REG(1); + periph_bases[1] += PERF_IRQMASK_6328_REG(1);
+ l2_irq_count = 2; + periph_irq_count = 2;
+ l2_width = 2; + periph_width = 2;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6328; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6328;
+ ext_irq_count = 4; + ext_irq_count = 4;
@ -513,9 +513,9 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- irq_bits = 32; - irq_bits = 32;
- ext_irq_count = 4; - ext_irq_count = 4;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6338; - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6338;
+ l2_intc_bases[0] += PERF_IRQMASK_6338_REG; + periph_bases[0] += PERF_IRQMASK_6338_REG;
+ l2_irq_count = 1; + periph_irq_count = 1;
+ l2_width = 1; + periph_width = 1;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6338; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6338;
+ ext_irq_count = 4; + ext_irq_count = 4;
@ -533,9 +533,9 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- irq_bits = 32; - irq_bits = 32;
- ext_irq_count = 4; - ext_irq_count = 4;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6345; - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6345;
+ l2_intc_bases[0] += PERF_IRQMASK_6345_REG; + periph_bases[0] += PERF_IRQMASK_6345_REG;
+ l2_irq_count = 1; + periph_irq_count = 1;
+ l2_width = 1; + periph_width = 1;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6345; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6345;
+ ext_irq_count = 4; + ext_irq_count = 4;
@ -553,9 +553,9 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
- irq_bits = 32; - irq_bits = 32;
- ext_irq_count = 4; - ext_irq_count = 4;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6348; - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6348;
+ l2_intc_bases[0] += PERF_IRQMASK_6348_REG; + periph_bases[0] += PERF_IRQMASK_6348_REG;
+ l2_irq_count = 1; + periph_irq_count = 1;
+ l2_width = 1; + periph_width = 1;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6348; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6348;
+ ext_irq_count = 4; + 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_start = BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE;
- ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE; - ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6358; - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6358;
+ l2_intc_bases[0] += PERF_IRQMASK_6358_REG(0); + periph_bases[0] += PERF_IRQMASK_6358_REG(0);
+ l2_intc_bases[1] += PERF_IRQMASK_6358_REG(1); + periph_bases[1] += PERF_IRQMASK_6358_REG(1);
+ l2_irq_count = 2; + periph_irq_count = 2;
+ l2_width = 1; + periph_width = 1;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6358; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6358;
+ ext_irq_count = 4; + 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_start = BCM_6362_EXT_IRQ0 - IRQ_INTERNAL_BASE;
- ext_irq_end = BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE; - ext_irq_end = BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE;
- ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6362; - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6362;
+ l2_intc_bases[0] += PERF_IRQMASK_6362_REG(0); + periph_bases[0] += PERF_IRQMASK_6362_REG(0);
+ l2_intc_bases[1] += PERF_IRQMASK_6362_REG(1); + periph_bases[1] += PERF_IRQMASK_6362_REG(1);
+ l2_irq_count = 2; + periph_irq_count = 2;
+ l2_width = 2; + periph_width = 2;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6362; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6362;
+ ext_irq_count = 4; + 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_stat_addr[1] += PERF_IRQSTAT_6368_REG(1);
- irq_mask_addr[1] += PERF_IRQMASK_6368_REG(1); - irq_mask_addr[1] += PERF_IRQMASK_6368_REG(1);
- irq_bits = 64; - irq_bits = 64;
+ l2_intc_bases[0] += PERF_IRQMASK_6368_REG(0); + periph_bases[0] += PERF_IRQMASK_6368_REG(0);
+ l2_intc_bases[1] += PERF_IRQMASK_6368_REG(1); + periph_bases[1] += PERF_IRQMASK_6368_REG(1);
+ l2_irq_count = 2; + periph_irq_count = 2;
+ l2_width = 2; + periph_width = 2;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6368; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6368;
+ ext_intc_bases[1] += PERF_EXTIRQ_CFG_REG2_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; - internal_irq_unmask = __internal_irq_unmask_64;
- } - }
+ mips_cpu_irq_init(); + 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); + bcm6345_ext_intc_init(4, ext_irqs, ext_intc_bases[0], ext_shift);
+ if (ext_irq_count > 4) + if (ext_irq_count > 4)
+ bcm6345_ext_intc_init(2, &ext_irqs[4], ext_intc_bases[1], + bcm6345_ext_intc_init(2, &ext_irqs[4], ext_intc_bases[1],

View file

@ -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> From: Jonas Gorski <jogo@openwrt.org>
Date: Sun, 30 Nov 2014 20:20:30 +0100 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 and 5
Due to the external interrupts being non consecutive, the previous 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 --- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c +++ b/arch/mips/bcm63xx/irq.c
@@ -109,11 +109,14 @@ static void bcm63xx_init_irq(void) @@ -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_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6358;
- ext_irq_count = 4; - ext_irq_count = 4;

View file

@ -289,10 +289,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
ext_shift = 4; ext_shift = 4;
break; break;
+ case BCM63268_CPU_ID: + case BCM63268_CPU_ID:
+ l2_intc_bases[0] += PERF_IRQSTAT_63268_REG(0); + periph_bases[0] += PERF_IRQSTAT_63268_REG(0);
+ l2_intc_bases[1] += PERF_IRQSTAT_63268_REG(1); + periph_bases[1] += PERF_IRQSTAT_63268_REG(1);
+ l2_irq_count = 2; + periph_irq_count = 2;
+ l2_width = 4; + periph_width = 4;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_63268; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_63268;
+ ext_irq_count = 4; + ext_irq_count = 4;

View file

@ -199,9 +199,9 @@ Subject: [PATCH 51/53] MIPS: BCM63XX: add support for BCM6318
ext_shift = 4; ext_shift = 4;
break; break;
+ case BCM6318_CPU_ID: + case BCM6318_CPU_ID:
+ l2_intc_bases[0] += PERF_IRQMASK_6318_REG; + periph_bases[0] += PERF_IRQMASK_6318_REG;
+ l2_irq_count = 1; + periph_irq_count = 1;
+ l2_width = 4; + periph_width = 4;
+ +
+ ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6318; + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6318;
+ ext_irq_count = 4; + ext_irq_count = 4;
@ -212,8 +212,8 @@ Subject: [PATCH 51/53] MIPS: BCM63XX: add support for BCM6318
+ ext_shift = 4; + ext_shift = 4;
+ break; + break;
case BCM6328_CPU_ID: case BCM6328_CPU_ID:
l2_intc_bases[0] += PERF_IRQMASK_6328_REG(0); periph_bases[0] += PERF_IRQMASK_6328_REG(0);
l2_intc_bases[1] += PERF_IRQMASK_6328_REG(1); periph_bases[1] += PERF_IRQMASK_6328_REG(1);
--- a/arch/mips/bcm63xx/prom.c --- a/arch/mips/bcm63xx/prom.c
+++ b/arch/mips/bcm63xx/prom.c +++ b/arch/mips/bcm63xx/prom.c
@@ -72,7 +72,7 @@ void __init prom_init(void) @@ -72,7 +72,7 @@ void __init prom_init(void)

View file

@ -43,7 +43,7 @@ Completely untested on anything except MIPS32 / big endian.
--- a/arch/mips/Kconfig --- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig +++ b/arch/mips/Kconfig
@@ -2645,6 +2645,24 @@ config RAPIDIO @@ -2655,6 +2655,24 @@ config RAPIDIO
source "drivers/rapidio/Kconfig" source "drivers/rapidio/Kconfig"

View file

@ -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> From: Jonas Gorski <jogo@openwrt.org>
Date: Mon, 1 Dec 2014 00:20:07 +0100 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> Signed-off-by: Jonas Gorski <jogo@openwrt.org>
--- ---
arch/mips/bcm63xx/irq.c | 10 +++++++++- arch/mips/bcm63xx/irq.c | 12 +++++++++++-
1 file changed, 9 insertions(+), 1 deletion(-) 1 file changed, 11 insertions(+), 1 deletion(-)
--- a/arch/mips/bcm63xx/irq.c --- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c +++ b/arch/mips/bcm63xx/irq.c
@@ -15,6 +15,8 @@ @@ -15,6 +15,8 @@
#include <linux/irqchip.h> #include <linux/irqchip.h>
#include <linux/irqchip/irq-bcm6345-ext-intc.h> #include <linux/irqchip/irq-bcm6345-ext.h>
#include <linux/irqchip/irq-bcm6345-l2-intc.h> #include <linux/irqchip/irq-bcm6345-periph.h>
+#include <linux/of.h> +#include <linux/of.h>
+#include <linux/of_fdt.h> +#include <linux/of_fdt.h>
#include <asm/irq_cpu.h> #include <asm/irq_cpu.h>
#include <asm/mipsregs.h> #include <asm/mipsregs.h>
#include <bcm63xx_cpu.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); ext_shift);
} }
@ -29,8 +29,10 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
void __init arch_init_irq(void) void __init arch_init_irq(void)
{ {
- bcm63xx_init_irq(); - bcm63xx_init_irq();
+#ifdef CONFIG_OF
+ if (initial_boot_params) + if (initial_boot_params)
+ irqchip_init(); + irqchip_init();
+ else + else
+#endif
+ bcm63xx_init_irq(); + bcm63xx_init_irq();
} }

View file

@ -519,7 +519,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr, void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
@@ -167,8 +145,8 @@ void dma_free_noncoherent(struct device @@ -167,8 +145,8 @@ void dma_free_noncoherent(struct device
} }
EXPORT_SYMBOL(dma_free_noncoherent); EXPORT_SYMBOL(dma_free_noncoherent);
@ -659,7 +659,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
void dma_cache_sync(struct device *dev, void *vaddr, size_t size, void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction) enum dma_data_direction direction)
@@ -360,23 +238,10 @@ void dma_cache_sync(struct device *dev, @@ -360,23 +238,10 @@ void dma_cache_sync(struct device *dev,
EXPORT_SYMBOL(dma_cache_sync); EXPORT_SYMBOL(dma_cache_sync);

View file

@ -1,6 +1,6 @@
--- a/scripts/kallsyms.c --- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c +++ b/scripts/kallsyms.c
@@ -58,6 +58,7 @@ static struct addr_range percpu_range = @@ -58,6 +58,7 @@ static struct addr_range percpu_range =
static struct sym_entry *table; static struct sym_entry *table;
static unsigned int table_size, table_cnt; static unsigned int table_size, table_cnt;
static int all_symbols = 0; static int all_symbols = 0;

View file

@ -72,7 +72,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
#ifdef MODULE #ifdef MODULE
#define __MODULE_INFO(tag, name, info) \ #define __MODULE_INFO(tag, name, info) \
static const char __UNIQUE_ID(name)[] \ static const char __UNIQUE_ID(name)[] \
@@ -23,8 +33,7 @@ static const char __UNIQUE_ID(name)[] @@ -23,8 +33,7 @@ static const char __UNIQUE_ID(name)[]
= __stringify(tag) "=" info = __stringify(tag) "=" info
#else /* !MODULE */ #else /* !MODULE */
/* This struct is here for syntactic coherency, it is not used */ /* This struct is here for syntactic coherency, it is not used */
@ -82,7 +82,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
#endif #endif
#define __MODULE_PARM_TYPE(name, _type) \ #define __MODULE_PARM_TYPE(name, _type) \
__MODULE_INFO(parmtype, name##type, #name ":" _type) __MODULE_INFO(parmtype, name##type, #name ":" _type)
@@ -32,7 +41,7 @@ static const char __UNIQUE_ID(name)[] @@ -32,7 +41,7 @@ static const char __UNIQUE_ID(name)[]
/* One for each parameter, describing how to use it. Some files do /* One for each parameter, describing how to use it. Some files do
multiple of these per line, so can't just use MODULE_INFO. */ multiple of these per line, so can't just use MODULE_INFO. */
#define MODULE_PARM_DESC(_parm, desc) \ #define MODULE_PARM_DESC(_parm, desc) \

View file

@ -1,6 +1,6 @@
--- a/scripts/Makefile.lib --- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib +++ b/scripts/Makefile.lib
@@ -325,7 +325,7 @@ cmd_bzip2 = (cat $(filter-out FORCE,$^) @@ -325,7 +325,7 @@ cmd_bzip2 = (cat $(filter-out FORCE,$^)
quiet_cmd_lzma = LZMA $@ quiet_cmd_lzma = LZMA $@
cmd_lzma = (cat $(filter-out FORCE,$^) | \ cmd_lzma = (cat $(filter-out FORCE,$^) | \

View file

@ -1,6 +1,6 @@
--- a/arch/mips/include/asm/string.h --- a/arch/mips/include/asm/string.h
+++ b/arch/mips/include/asm/string.h +++ b/arch/mips/include/asm/string.h
@@ -133,11 +133,44 @@ strncmp(__const__ char *__cs, __const__ @@ -133,11 +133,44 @@ strncmp(__const__ char *__cs, __const__
#define __HAVE_ARCH_MEMSET #define __HAVE_ARCH_MEMSET
extern void *memset(void *__s, int __c, size_t __count); extern void *memset(void *__s, int __c, size_t __count);

View file

@ -14,7 +14,7 @@
default y default y
--- a/drivers/mtd/mtdpart.c --- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c
@@ -681,6 +681,47 @@ mtd_pad_erasesize(struct mtd_info *mtd, @@ -681,6 +681,47 @@ mtd_pad_erasesize(struct mtd_info *mtd,
return len; return len;
} }

View file

@ -17,7 +17,7 @@
u64 offset, uint32_t mask_flags) u64 offset, uint32_t mask_flags)
{ {
part->name = name; part->name = name;
@@ -58,6 +59,26 @@ static void bcm47xxpart_add_part(struct @@ -58,6 +59,26 @@ static void bcm47xxpart_add_part(struct
part->mask_flags = mask_flags; part->mask_flags = mask_flags;
} }

View file

@ -8,7 +8,7 @@
static struct proc_dir_entry *my_proc_entry; static struct proc_dir_entry *my_proc_entry;
static char *yaffs_dump_dev_part0(char *buf, struct yaffs_dev *dev) static char *yaffs_dump_dev_part0(char *buf, struct yaffs_dev *dev)
@@ -3398,6 +3399,7 @@ static int yaffs_proc_write(struct file @@ -3398,6 +3399,7 @@ static int yaffs_proc_write(struct file
return yaffs_proc_debug_write(file, buf, count, data); return yaffs_proc_debug_write(file, buf, count, data);
return yaffs_proc_write_trace_options(file, buf, count, data); return yaffs_proc_write_trace_options(file, buf, count, data);
} }

View file

@ -30,7 +30,7 @@
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
--- a/net/netfilter/Makefile --- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile +++ b/net/netfilter/Makefile
@@ -162,6 +162,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT) @@ -162,6 +162,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT)
obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o

View file

@ -8,7 +8,7 @@
#include <net/net_namespace.h> #include <net/net_namespace.h>
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
#include <linux/sysctl.h> #include <linux/sysctl.h>
@@ -268,10 +269,66 @@ static int ct_open(struct inode *inode, @@ -268,10 +269,66 @@ static int ct_open(struct inode *inode,
sizeof(struct ct_iter_state)); sizeof(struct ct_iter_state));
} }

View file

@ -37,7 +37,7 @@
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
--- a/net/netfilter/Makefile --- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile +++ b/net/netfilter/Makefile
@@ -140,6 +140,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_ESP) += @@ -140,6 +140,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_ESP) +=
obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o
obj-$(CONFIG_NETFILTER_XT_MATCH_HL) += xt_hl.o obj-$(CONFIG_NETFILTER_XT_MATCH_HL) += xt_hl.o

View file

@ -25,7 +25,7 @@
Ethernet bridge, which means that the different Ethernet segments it Ethernet bridge, which means that the different Ethernet segments it
--- a/net/ipv6/Makefile --- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile +++ b/net/ipv6/Makefile
@@ -45,6 +45,7 @@ obj-y += addrconf_core.o exthdrs_core.o @@ -45,6 +45,7 @@ obj-y += addrconf_core.o exthdrs_core.o
obj-$(CONFIG_INET) += output_core.o protocol.o $(ipv6-offload) obj-$(CONFIG_INET) += output_core.o protocol.o $(ipv6-offload)
obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o

View file

@ -195,7 +195,7 @@
} }
#endif #endif
@@ -1556,6 +1581,7 @@ static int br_multicast_ipv4_rcv(struct @@ -1556,6 +1581,7 @@ static int br_multicast_ipv4_rcv(struct
struct sk_buff *skb, struct sk_buff *skb,
u16 vid) u16 vid)
{ {
@ -203,7 +203,7 @@
struct sk_buff *skb2 = skb; struct sk_buff *skb2 = skb;
const struct iphdr *iph; const struct iphdr *iph;
struct igmphdr *ih; struct igmphdr *ih;
@@ -1629,7 +1655,7 @@ static int br_multicast_ipv4_rcv(struct @@ -1629,7 +1655,7 @@ static int br_multicast_ipv4_rcv(struct
case IGMP_HOST_MEMBERSHIP_REPORT: case IGMP_HOST_MEMBERSHIP_REPORT:
case IGMPV2_HOST_MEMBERSHIP_REPORT: case IGMPV2_HOST_MEMBERSHIP_REPORT:
BR_INPUT_SKB_CB(skb)->mrouters_only = 1; BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
@ -212,7 +212,7 @@
break; break;
case IGMPV3_HOST_MEMBERSHIP_REPORT: case IGMPV3_HOST_MEMBERSHIP_REPORT:
err = br_ip4_multicast_igmp3_report(br, port, skb2, vid); err = br_ip4_multicast_igmp3_report(br, port, skb2, vid);
@@ -1638,7 +1664,7 @@ static int br_multicast_ipv4_rcv(struct @@ -1638,7 +1664,7 @@ static int br_multicast_ipv4_rcv(struct
err = br_ip4_multicast_query(br, port, skb2, vid); err = br_ip4_multicast_query(br, port, skb2, vid);
break; break;
case IGMP_HOST_LEAVE_MESSAGE: case IGMP_HOST_LEAVE_MESSAGE:
@ -221,7 +221,7 @@
break; break;
} }
@@ -1656,6 +1682,7 @@ static int br_multicast_ipv6_rcv(struct @@ -1656,6 +1682,7 @@ static int br_multicast_ipv6_rcv(struct
struct sk_buff *skb, struct sk_buff *skb,
u16 vid) u16 vid)
{ {
@ -229,7 +229,7 @@
struct sk_buff *skb2; struct sk_buff *skb2;
const struct ipv6hdr *ip6h; const struct ipv6hdr *ip6h;
u8 icmp6_type; u8 icmp6_type;
@@ -1765,7 +1792,8 @@ static int br_multicast_ipv6_rcv(struct @@ -1765,7 +1792,8 @@ static int br_multicast_ipv6_rcv(struct
} }
mld = (struct mld_msg *)skb_transport_header(skb2); mld = (struct mld_msg *)skb_transport_header(skb2);
BR_INPUT_SKB_CB(skb)->mrouters_only = 1; BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
@ -239,7 +239,7 @@
break; break;
} }
case ICMPV6_MLD2_REPORT: case ICMPV6_MLD2_REPORT:
@@ -1782,7 +1810,7 @@ static int br_multicast_ipv6_rcv(struct @@ -1782,7 +1810,7 @@ static int br_multicast_ipv6_rcv(struct
goto out; goto out;
} }
mld = (struct mld_msg *)skb_transport_header(skb2); mld = (struct mld_msg *)skb_transport_header(skb2);

View file

@ -1,6 +1,6 @@
--- a/net/netlink/af_netlink.c --- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c
@@ -1715,27 +1715,7 @@ void netlink_detachskb(struct sock *sk, @@ -1715,27 +1715,7 @@ void netlink_detachskb(struct sock *sk,
static struct sk_buff *netlink_trim(struct sk_buff *skb, gfp_t allocation) static struct sk_buff *netlink_trim(struct sk_buff *skb, gfp_t allocation)
{ {

View file

@ -24,7 +24,7 @@ commont qdiscs.
} }
--- a/net/sched/sch_fifo.c --- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c +++ b/net/sched/sch_fifo.c
@@ -29,17 +29,21 @@ static int bfifo_enqueue(struct sk_buff @@ -29,17 +29,21 @@ static int bfifo_enqueue(struct sk_buff
static int pfifo_enqueue(struct sk_buff *skb, struct Qdisc *sch) static int pfifo_enqueue(struct sk_buff *skb, struct Qdisc *sch)
{ {

View file

@ -308,7 +308,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
err = ip6_tnl_xmit2(skb, dev, dsfield, &fl6, encap_limit, &mtu); err = ip6_tnl_xmit2(skb, dev, dsfield, &fl6, encap_limit, &mtu);
if (err != 0) { if (err != 0) {
/* XXX: send ICMP error even if DF is not set. */ /* XXX: send ICMP error even if DF is not set. */
@@ -1263,6 +1413,14 @@ ip6_tnl_change(struct ip6_tnl *t, const @@ -1263,6 +1413,14 @@ ip6_tnl_change(struct ip6_tnl *t, const
t->parms.flowinfo = p->flowinfo; t->parms.flowinfo = p->flowinfo;
t->parms.link = p->link; t->parms.link = p->link;
t->parms.proto = p->proto; t->parms.proto = p->proto;

View file

@ -55,7 +55,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
--- a/net/ipv4/fib_semantics.c --- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c
@@ -138,6 +138,10 @@ const struct fib_prop fib_props[RTN_MAX @@ -138,6 +138,10 @@ const struct fib_prop fib_props[RTN_MAX
.error = -EINVAL, .error = -EINVAL,
.scope = RT_SCOPE_NOWHERE, .scope = RT_SCOPE_NOWHERE,
}, },

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/hostap/hostap_ap.c --- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -2403,13 +2403,13 @@ int prism2_ap_get_sta_qual(local_info_t @@ -2403,13 +2403,13 @@ int prism2_ap_get_sta_qual(local_info_t
addr[count].sa_family = ARPHRD_ETHER; addr[count].sa_family = ARPHRD_ETHER;
memcpy(addr[count].sa_data, sta->addr, ETH_ALEN); memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
if (sta->last_rx_silence == 0) if (sta->last_rx_silence == 0)

View file

@ -12,7 +12,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
#include <bcm47xx_nvram.h> #include <bcm47xx_nvram.h>
static const struct bcma_device_id bgmac_bcma_tbl[] = { static const struct bcma_device_id bgmac_bcma_tbl[] = {
@@ -1405,6 +1406,17 @@ static void bgmac_mii_unregister(struct @@ -1405,6 +1406,17 @@ static void bgmac_mii_unregister(struct
mdiobus_free(mii_bus); mdiobus_free(mii_bus);
} }

View file

@ -15,7 +15,7 @@
default y default y
--- a/drivers/pci/quirks.c --- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c
@@ -41,6 +41,7 @@ static void quirk_mmio_always_on(struct @@ -41,6 +41,7 @@ static void quirk_mmio_always_on(struct
DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID, DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_BRIDGE_HOST, 8, quirk_mmio_always_on); PCI_CLASS_BRIDGE_HOST, 8, quirk_mmio_always_on);

View file

@ -199,7 +199,7 @@
&fib_triestat_fops)) &fib_triestat_fops))
goto out2; goto out2;
@@ -2594,17 +2596,21 @@ int __net_init fib_proc_init(struct net @@ -2594,17 +2596,21 @@ int __net_init fib_proc_init(struct net
return 0; return 0;
out3: out3:

View file

@ -24,7 +24,7 @@
* All of these routines try to estimate how many bits of randomness a * All of these routines try to estimate how many bits of randomness a
* particular randomness source. They do this by keeping track of the * particular randomness source. They do this by keeping track of the
* first and second order deltas of the event timings. * first and second order deltas of the event timings.
@@ -938,6 +948,63 @@ void add_disk_randomness(struct gendisk @@ -938,6 +948,63 @@ void add_disk_randomness(struct gendisk
EXPORT_SYMBOL_GPL(add_disk_randomness); EXPORT_SYMBOL_GPL(add_disk_randomness);
#endif #endif