irqchip/ath79-cpu: Move the CPU IRQ driver from arch/mips/ath79/
authorAlban Bedel <albeu@free.fr>
Sat, 23 Jan 2016 12:57:47 +0000 (13:57 +0100)
committerJason Cooper <jason@lakedaemon.net>
Wed, 17 Feb 2016 13:47:19 +0000 (13:47 +0000)
Signed-off-by: Alban Bedel <albeu@free.fr>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Link: https://lkml.kernel.org/r/1453553867-27003-2-git-send-email-albeu@free.fr
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
arch/mips/ath79/irq.c
arch/mips/include/asm/mach-ath79/ath79.h
drivers/irqchip/Makefile
drivers/irqchip/irq-ath79-cpu.c [new file with mode: 0644]

index 05b45140bc1fe79616482f0996be0c1722debc5f..2dfff1f19004326c06ec366033418e8152f76309 100644 (file)
@@ -128,79 +128,10 @@ static void qca955x_irq_init(void)
        irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch);
 }
 
-/*
- * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for
- * these devices typically allocate coherent DMA memory, however the
- * DMA controller may still have some unsynchronized data in the FIFO.
- * Issue a flush in the handlers to ensure that the driver sees
- * the update.
- *
- * This array map the interrupt lines to the DDR write buffer channels.
- */
-
-static unsigned irq_wb_chan[8] = {
-       -1, -1, -1, -1, -1, -1, -1, -1,
-};
-
-asmlinkage void plat_irq_dispatch(void)
-{
-       unsigned long pending;
-       int irq;
-
-       pending = read_c0_status() & read_c0_cause() & ST0_IM;
-
-       if (!pending) {
-               spurious_interrupt();
-               return;
-       }
-
-       pending >>= CAUSEB_IP;
-       while (pending) {
-               irq = fls(pending) - 1;
-               if (irq < ARRAY_SIZE(irq_wb_chan) && irq_wb_chan[irq] != -1)
-                       ath79_ddr_wb_flush(irq_wb_chan[irq]);
-               do_IRQ(MIPS_CPU_IRQ_BASE + irq);
-               pending &= ~BIT(irq);
-       }
-}
-
-static int __init ar79_cpu_intc_of_init(
-       struct device_node *node, struct device_node *parent)
-{
-       int err, i, count;
-
-       /* Fill the irq_wb_chan table */
-       count = of_count_phandle_with_args(
-               node, "qca,ddr-wb-channels", "#qca,ddr-wb-channel-cells");
-
-       for (i = 0; i < count; i++) {
-               struct of_phandle_args args;
-               u32 irq = i;
-
-               of_property_read_u32_index(
-                       node, "qca,ddr-wb-channel-interrupts", i, &irq);
-               if (irq >= ARRAY_SIZE(irq_wb_chan))
-                       continue;
-
-               err = of_parse_phandle_with_args(
-                       node, "qca,ddr-wb-channels",
-                       "#qca,ddr-wb-channel-cells",
-                       i, &args);
-               if (err)
-                       return err;
-
-               irq_wb_chan[irq] = args.args[0];
-               pr_info("IRQ: Set flush channel of IRQ%d to %d\n",
-                       irq, args.args[0]);
-       }
-
-       return mips_cpu_irq_of_init(node, parent);
-}
-IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc",
-               ar79_cpu_intc_of_init);
-
 void __init arch_init_irq(void)
 {
+       unsigned irq_wb_chan2 = -1;
+       unsigned irq_wb_chan3 = -1;
        bool misc_is_ar71xx;
 
        if (mips_machtype == ATH79_MACH_GENERIC_OF) {
@@ -210,13 +141,13 @@ void __init arch_init_irq(void)
 
        if (soc_is_ar71xx() || soc_is_ar724x() ||
            soc_is_ar913x() || soc_is_ar933x()) {
-               irq_wb_chan[2] = 3;
-               irq_wb_chan[3] = 2;
+               irq_wb_chan2 = 3;
+               irq_wb_chan3 = 2;
        } else if (soc_is_ar934x()) {
-               irq_wb_chan[3] = 2;
+               irq_wb_chan3 = 2;
        }
 
-       mips_cpu_irq_init();
+       ath79_cpu_irq_init(irq_wb_chan2, irq_wb_chan3);
 
        if (soc_is_ar71xx() || soc_is_ar913x())
                misc_is_ar71xx = true;
index 22a2f56ad5e9b4bd8a6a982821ab9590675a5369..441faa92c3cd488ac97685a1930597f7449a88f4 100644 (file)
@@ -144,6 +144,7 @@ static inline u32 ath79_reset_rr(unsigned reg)
 void ath79_device_reset_set(u32 mask);
 void ath79_device_reset_clear(u32 mask);
 
+void ath79_cpu_irq_init(unsigned irq_wb_chan2, unsigned irq_wb_chan3);
 void ath79_misc_irq_init(void __iomem *regs, int irq,
                        int irq_base, bool is_ar71xx);
 
index b873d4a081b404237a675093f7250c3af920ea96..aeb9200f0e16097234d560a511c7145a1feb3fe9 100644 (file)
@@ -1,5 +1,6 @@
 obj-$(CONFIG_IRQCHIP)                  += irqchip.o
 
+obj-$(CONFIG_ATH79)                    += irq-ath79-cpu.o
 obj-$(CONFIG_ATH79)                    += irq-ath79-misc.o
 obj-$(CONFIG_ARCH_BCM2835)             += irq-bcm2835.o
 obj-$(CONFIG_ARCH_BCM2835)             += irq-bcm2836.o
diff --git a/drivers/irqchip/irq-ath79-cpu.c b/drivers/irqchip/irq-ath79-cpu.c
new file mode 100644 (file)
index 0000000..befe93c
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ *  Atheros AR71xx/AR724x/AR913x specific interrupt handling
+ *
+ *  Copyright (C) 2015 Alban Bedel <albeu@free.fr>
+ *  Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
+ *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irqchip.h>
+#include <linux/of.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mach-ath79/ath79.h>
+
+/*
+ * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for
+ * these devices typically allocate coherent DMA memory, however the
+ * DMA controller may still have some unsynchronized data in the FIFO.
+ * Issue a flush in the handlers to ensure that the driver sees
+ * the update.
+ *
+ * This array map the interrupt lines to the DDR write buffer channels.
+ */
+
+static unsigned irq_wb_chan[8] = {
+       -1, -1, -1, -1, -1, -1, -1, -1,
+};
+
+asmlinkage void plat_irq_dispatch(void)
+{
+       unsigned long pending;
+       int irq;
+
+       pending = read_c0_status() & read_c0_cause() & ST0_IM;
+
+       if (!pending) {
+               spurious_interrupt();
+               return;
+       }
+
+       pending >>= CAUSEB_IP;
+       while (pending) {
+               irq = fls(pending) - 1;
+               if (irq < ARRAY_SIZE(irq_wb_chan) && irq_wb_chan[irq] != -1)
+                       ath79_ddr_wb_flush(irq_wb_chan[irq]);
+               do_IRQ(MIPS_CPU_IRQ_BASE + irq);
+               pending &= ~BIT(irq);
+       }
+}
+
+static int __init ar79_cpu_intc_of_init(
+       struct device_node *node, struct device_node *parent)
+{
+       int err, i, count;
+
+       /* Fill the irq_wb_chan table */
+       count = of_count_phandle_with_args(
+               node, "qca,ddr-wb-channels", "#qca,ddr-wb-channel-cells");
+
+       for (i = 0; i < count; i++) {
+               struct of_phandle_args args;
+               u32 irq = i;
+
+               of_property_read_u32_index(
+                       node, "qca,ddr-wb-channel-interrupts", i, &irq);
+               if (irq >= ARRAY_SIZE(irq_wb_chan))
+                       continue;
+
+               err = of_parse_phandle_with_args(
+                       node, "qca,ddr-wb-channels",
+                       "#qca,ddr-wb-channel-cells",
+                       i, &args);
+               if (err)
+                       return err;
+
+               irq_wb_chan[irq] = args.args[0];
+       }
+
+       return mips_cpu_irq_of_init(node, parent);
+}
+IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc",
+               ar79_cpu_intc_of_init);
+
+void __init ath79_cpu_irq_init(unsigned irq_wb_chan2, unsigned irq_wb_chan3)
+{
+       irq_wb_chan[2] = irq_wb_chan2;
+       irq_wb_chan[3] = irq_wb_chan3;
+       mips_cpu_irq_init();
+}