linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/2] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
@ 2016-01-23 12:57 Alban Bedel
  2016-01-23 12:57 ` [PATCH v2 2/2] MIPS: ath79: irq: Move the CPU IRQ " Alban Bedel
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Alban Bedel @ 2016-01-23 12:57 UTC (permalink / raw)
  To: linux-mips
  Cc: Ralf Baechle, Thomas Gleixner, Jason Cooper, Marc Zyngier,
	Alexander Couzens, Joel Porquet, linux-kernel, Alban Bedel

The driver stays the same but the initialization changes a bit.
For OF boards we now get the memory map from the OF node and use
a linear mapping instead of the legacy mapping. For legacy boards
we still use a legacy mapping and just pass down all the parameters
from the board init code.

Signed-off-by: Alban Bedel <albeu@free.fr>
---
Changelog:
v2: * Added the missing calls to chained_irq_enter/leave()
---
 arch/mips/ath79/irq.c                    | 163 +++-----------------------
 arch/mips/include/asm/mach-ath79/ath79.h |   3 +
 drivers/irqchip/Makefile                 |   1 +
 drivers/irqchip/irq-ath79-misc.c         | 189 +++++++++++++++++++++++++++++++
 4 files changed, 208 insertions(+), 148 deletions(-)
 create mode 100644 drivers/irqchip/irq-ath79-misc.c

diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
index 511c065..05b4514 100644
--- a/arch/mips/ath79/irq.c
+++ b/arch/mips/ath79/irq.c
@@ -26,90 +26,6 @@
 #include "common.h"
 #include "machtypes.h"
 
-static void __init ath79_misc_intc_domain_init(
-	struct device_node *node, int irq);
-
-static void ath79_misc_irq_handler(struct irq_desc *desc)
-{
-	struct irq_domain *domain = irq_desc_get_handler_data(desc);
-	void __iomem *base = domain->host_data;
-	u32 pending;
-
-	pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) &
-		  __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
-
-	if (!pending) {
-		spurious_interrupt();
-		return;
-	}
-
-	while (pending) {
-		int bit = __ffs(pending);
-
-		generic_handle_irq(irq_linear_revmap(domain, bit));
-		pending &= ~BIT(bit);
-	}
-}
-
-static void ar71xx_misc_irq_unmask(struct irq_data *d)
-{
-	void __iomem *base = irq_data_get_irq_chip_data(d);
-	unsigned int irq = d->hwirq;
-	u32 t;
-
-	t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
-	__raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
-
-	/* flush write */
-	__raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
-}
-
-static void ar71xx_misc_irq_mask(struct irq_data *d)
-{
-	void __iomem *base = irq_data_get_irq_chip_data(d);
-	unsigned int irq = d->hwirq;
-	u32 t;
-
-	t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
-	__raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
-
-	/* flush write */
-	__raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
-}
-
-static void ar724x_misc_irq_ack(struct irq_data *d)
-{
-	void __iomem *base = irq_data_get_irq_chip_data(d);
-	unsigned int irq = d->hwirq;
-	u32 t;
-
-	t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
-	__raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS);
-
-	/* flush write */
-	__raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
-}
-
-static struct irq_chip ath79_misc_irq_chip = {
-	.name		= "MISC",
-	.irq_unmask	= ar71xx_misc_irq_unmask,
-	.irq_mask	= ar71xx_misc_irq_mask,
-};
-
-static void __init ath79_misc_irq_init(void)
-{
-	if (soc_is_ar71xx() || soc_is_ar913x())
-		ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
-	else if (soc_is_ar724x() ||
-		 soc_is_ar933x() ||
-		 soc_is_ar934x() ||
-		 soc_is_qca955x())
-		ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
-	else
-		BUG();
-
-	ath79_misc_intc_domain_init(NULL, ATH79_CPU_IRQ(6));
-}
 
 static void ar934x_ip2_irq_dispatch(struct irq_desc *desc)
 {
@@ -248,69 +164,6 @@ asmlinkage void plat_irq_dispatch(void)
 	}
 }
 
-static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
-{
-	irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq);
-	irq_set_chip_data(irq, d->host_data);
-	return 0;
-}
-
-static const struct irq_domain_ops misc_irq_domain_ops = {
-	.xlate = irq_domain_xlate_onecell,
-	.map = misc_map,
-};
-
-static void __init ath79_misc_intc_domain_init(
-	struct device_node *node, int irq)
-{
-	void __iomem *base = ath79_reset_base;
-	struct irq_domain *domain;
-
-	domain = irq_domain_add_legacy(node, ATH79_MISC_IRQ_COUNT,
-			ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, base);
-	if (!domain)
-		panic("Failed to add MISC irqdomain");
-
-	/* Disable and clear all interrupts */
-	__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
-	__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
-
-	irq_set_chained_handler_and_data(irq, ath79_misc_irq_handler, domain);
-}
-
-static int __init ath79_misc_intc_of_init(
-	struct device_node *node, struct device_node *parent)
-{
-	int irq;
-
-	irq = irq_of_parse_and_map(node, 0);
-	if (!irq)
-		panic("Failed to get MISC IRQ");
-
-	ath79_misc_intc_domain_init(node, irq);
-	return 0;
-}
-
-static int __init ar7100_misc_intc_of_init(
-	struct device_node *node, struct device_node *parent)
-{
-	ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
-	return ath79_misc_intc_of_init(node, parent);
-}
-
-IRQCHIP_DECLARE(ar7100_misc_intc, "qca,ar7100-misc-intc",
-		ar7100_misc_intc_of_init);
-
-static int __init ar7240_misc_intc_of_init(
-	struct device_node *node, struct device_node *parent)
-{
-	ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
-	return ath79_misc_intc_of_init(node, parent);
-}
-
-IRQCHIP_DECLARE(ar7240_misc_intc, "qca,ar7240-misc-intc",
-		ar7240_misc_intc_of_init);
-
 static int __init ar79_cpu_intc_of_init(
 	struct device_node *node, struct device_node *parent)
 {
@@ -348,6 +201,8 @@ IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc",
 
 void __init arch_init_irq(void)
 {
+	bool misc_is_ar71xx;
+
 	if (mips_machtype == ATH79_MACH_GENERIC_OF) {
 		irqchip_init();
 		return;
@@ -362,7 +217,19 @@ void __init arch_init_irq(void)
 	}
 
 	mips_cpu_irq_init();
-	ath79_misc_irq_init();
+
+	if (soc_is_ar71xx() || soc_is_ar913x())
+		misc_is_ar71xx = true;
+	else if (soc_is_ar724x() ||
+		 soc_is_ar933x() ||
+		 soc_is_ar934x() ||
+		 soc_is_qca955x())
+		misc_is_ar71xx = false;
+	else
+		BUG();
+	ath79_misc_irq_init(
+		ath79_reset_base + AR71XX_RESET_REG_MISC_INT_STATUS,
+		ATH79_CPU_IRQ(6), ATH79_MISC_IRQ_BASE, misc_is_ar71xx);
 
 	if (soc_is_ar934x())
 		ar934x_ip2_irq_init();
diff --git a/arch/mips/include/asm/mach-ath79/ath79.h b/arch/mips/include/asm/mach-ath79/ath79.h
index 2b34872..22a2f56 100644
--- a/arch/mips/include/asm/mach-ath79/ath79.h
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -144,4 +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_misc_irq_init(void __iomem *regs, int irq,
+			int irq_base, bool is_ar71xx);
+
 #endif /* __ASM_MACH_ATH79_H */
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 177f78f..a8f9075 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_IRQCHIP)			+= irqchip.o
 
+obj-$(CONFIG_ATH79)			+= irq-ath79-misc.o
 obj-$(CONFIG_ARCH_BCM2835)		+= irq-bcm2835.o
 obj-$(CONFIG_ARCH_BCM2835)		+= irq-bcm2836.o
 obj-$(CONFIG_ARCH_EXYNOS)		+= exynos-combiner.o
diff --git a/drivers/irqchip/irq-ath79-misc.c b/drivers/irqchip/irq-ath79-misc.c
new file mode 100644
index 0000000..aa72907
--- /dev/null
+++ b/drivers/irqchip/irq-ath79-misc.c
@@ -0,0 +1,189 @@
+/*
+ *  Atheros AR71xx/AR724x/AR913x MISC interrupt controller
+ *
+ *  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/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#define AR71XX_RESET_REG_MISC_INT_STATUS	0
+#define AR71XX_RESET_REG_MISC_INT_ENABLE	4
+
+#define ATH79_MISC_IRQ_COUNT			32
+
+static void ath79_misc_irq_handler(struct irq_desc *desc)
+{
+	struct irq_domain *domain = irq_desc_get_handler_data(desc);
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	void __iomem *base = domain->host_data;
+	u32 pending;
+
+	chained_irq_enter(chip, desc);
+
+	pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) &
+		  __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+	if (!pending) {
+		spurious_interrupt();
+		chained_irq_exit(chip, desc);
+		return;
+	}
+
+	while (pending) {
+		int bit = __ffs(pending);
+
+		generic_handle_irq(irq_linear_revmap(domain, bit));
+		pending &= ~BIT(bit);
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+static void ar71xx_misc_irq_unmask(struct irq_data *d)
+{
+	void __iomem *base = irq_data_get_irq_chip_data(d);
+	unsigned int irq = d->hwirq;
+	u32 t;
+
+	t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+	__raw_writel(t | BIT(irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+	/* flush write */
+	__raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+}
+
+static void ar71xx_misc_irq_mask(struct irq_data *d)
+{
+	void __iomem *base = irq_data_get_irq_chip_data(d);
+	unsigned int irq = d->hwirq;
+	u32 t;
+
+	t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+	__raw_writel(t & ~BIT(irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+	/* flush write */
+	__raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+}
+
+static void ar724x_misc_irq_ack(struct irq_data *d)
+{
+	void __iomem *base = irq_data_get_irq_chip_data(d);
+	unsigned int irq = d->hwirq;
+	u32 t;
+
+	t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
+	__raw_writel(t & ~BIT(irq), base + AR71XX_RESET_REG_MISC_INT_STATUS);
+
+	/* flush write */
+	__raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
+}
+
+static struct irq_chip ath79_misc_irq_chip = {
+	.name		= "MISC",
+	.irq_unmask	= ar71xx_misc_irq_unmask,
+	.irq_mask	= ar71xx_misc_irq_mask,
+};
+
+static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
+{
+	irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq);
+	irq_set_chip_data(irq, d->host_data);
+	return 0;
+}
+
+static const struct irq_domain_ops misc_irq_domain_ops = {
+	.xlate = irq_domain_xlate_onecell,
+	.map = misc_map,
+};
+
+static void __init ath79_misc_intc_domain_init(
+	struct irq_domain *domain, int irq)
+{
+	void __iomem *base = domain->host_data;
+
+	/* Disable and clear all interrupts */
+	__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+	__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
+
+	irq_set_chained_handler_and_data(irq, ath79_misc_irq_handler, domain);
+}
+
+static int __init ath79_misc_intc_of_init(
+	struct device_node *node, struct device_node *parent)
+{
+	struct irq_domain *domain;
+	void __iomem *base;
+	int irq;
+
+	irq = irq_of_parse_and_map(node, 0);
+	if (!irq) {
+		pr_err("Failed to get MISC IRQ\n");
+		return -EINVAL;
+	}
+
+	base = of_iomap(node, 0);
+	if (!base) {
+		pr_err("Failed to get MISC IRQ registers\n");
+		return -ENOMEM;
+	}
+
+	domain = irq_domain_add_linear(node, ATH79_MISC_IRQ_COUNT,
+				&misc_irq_domain_ops, base);
+	if (!domain) {
+		pr_err("Failed to add MISC irqdomain\n");
+		return -EINVAL;
+	}
+
+	ath79_misc_intc_domain_init(domain, irq);
+	return 0;
+}
+
+static int __init ar7100_misc_intc_of_init(
+	struct device_node *node, struct device_node *parent)
+{
+	ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
+	return ath79_misc_intc_of_init(node, parent);
+}
+
+IRQCHIP_DECLARE(ar7100_misc_intc, "qca,ar7100-misc-intc",
+		ar7100_misc_intc_of_init);
+
+static int __init ar7240_misc_intc_of_init(
+	struct device_node *node, struct device_node *parent)
+{
+	ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
+	return ath79_misc_intc_of_init(node, parent);
+}
+
+IRQCHIP_DECLARE(ar7240_misc_intc, "qca,ar7240-misc-intc",
+		ar7240_misc_intc_of_init);
+
+void __init ath79_misc_irq_init(void __iomem *regs, int irq,
+				int irq_base, bool is_ar71xx)
+{
+	struct irq_domain *domain;
+
+	if (is_ar71xx)
+		ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
+	else
+		ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
+
+	domain = irq_domain_add_legacy(NULL, ATH79_MISC_IRQ_COUNT,
+			irq_base, 0, &misc_irq_domain_ops, regs);
+	if (!domain)
+		panic("Failed to create MISC irqdomain");
+
+	ath79_misc_intc_domain_init(domain, irq);
+}
-- 
2.0.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 2/2] MIPS: ath79: irq: Move the CPU IRQ driver to drivers/irqchip
  2016-01-23 12:57 [PATCH v2 1/2] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip Alban Bedel
@ 2016-01-23 12:57 ` Alban Bedel
  2016-01-23 15:02 ` [PATCH v2 1/2] MIPS: ath79: irq: Move the MISC " Marc Zyngier
  2016-02-17 21:17 ` Jason Cooper
  2 siblings, 0 replies; 7+ messages in thread
From: Alban Bedel @ 2016-01-23 12:57 UTC (permalink / raw)
  To: linux-mips
  Cc: Ralf Baechle, Thomas Gleixner, Jason Cooper, Marc Zyngier,
	Alexander Couzens, Joel Porquet, linux-kernel, Alban Bedel

Signed-off-by: Alban Bedel <albeu@free.fr>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/mips/ath79/irq.c                    | 81 ++------------------------
 arch/mips/include/asm/mach-ath79/ath79.h |  1 +
 drivers/irqchip/Makefile                 |  1 +
 drivers/irqchip/irq-ath79-cpu.c          | 97 ++++++++++++++++++++++++++++++++
 4 files changed, 105 insertions(+), 75 deletions(-)
 create mode 100644 drivers/irqchip/irq-ath79-cpu.c

diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
index 05b4514..2dfff1f 100644
--- a/arch/mips/ath79/irq.c
+++ b/arch/mips/ath79/irq.c
@@ -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;
diff --git a/arch/mips/include/asm/mach-ath79/ath79.h b/arch/mips/include/asm/mach-ath79/ath79.h
index 22a2f56..441faa9 100644
--- a/arch/mips/include/asm/mach-ath79/ath79.h
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -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);
 
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index a8f9075..91c24ed 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -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
index 0000000..befe93c
--- /dev/null
+++ b/drivers/irqchip/irq-ath79-cpu.c
@@ -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();
+}
-- 
2.0.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/2] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
  2016-01-23 12:57 [PATCH v2 1/2] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip Alban Bedel
  2016-01-23 12:57 ` [PATCH v2 2/2] MIPS: ath79: irq: Move the CPU IRQ " Alban Bedel
@ 2016-01-23 15:02 ` Marc Zyngier
  2016-01-23 16:31   ` Jason Cooper
  2016-02-17 21:17 ` Jason Cooper
  2 siblings, 1 reply; 7+ messages in thread
From: Marc Zyngier @ 2016-01-23 15:02 UTC (permalink / raw)
  To: Alban Bedel
  Cc: linux-mips, Ralf Baechle, Thomas Gleixner, Jason Cooper,
	Alexander Couzens, Joel Porquet, linux-kernel

On Sat, 23 Jan 2016 13:57:46 +0100
Alban Bedel <albeu@free.fr> wrote:

> The driver stays the same but the initialization changes a bit.
> For OF boards we now get the memory map from the OF node and use
> a linear mapping instead of the legacy mapping. For legacy boards
> we still use a legacy mapping and just pass down all the parameters
> from the board init code.
> 
> Signed-off-by: Alban Bedel <albeu@free.fr>

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/2] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
  2016-01-23 15:02 ` [PATCH v2 1/2] MIPS: ath79: irq: Move the MISC " Marc Zyngier
@ 2016-01-23 16:31   ` Jason Cooper
  2016-02-17 13:15     ` Alban
  0 siblings, 1 reply; 7+ messages in thread
From: Jason Cooper @ 2016-01-23 16:31 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Alban Bedel, linux-mips, Ralf Baechle, Thomas Gleixner,
	Alexander Couzens, Joel Porquet, linux-kernel

On Sat, Jan 23, 2016 at 03:02:00PM +0000, Marc Zyngier wrote:
> On Sat, 23 Jan 2016 13:57:46 +0100
> Alban Bedel <albeu@free.fr> wrote:
> 
> > The driver stays the same but the initialization changes a bit.
> > For OF boards we now get the memory map from the OF node and use
> > a linear mapping instead of the legacy mapping. For legacy boards
> > we still use a legacy mapping and just pass down all the parameters
> > from the board init code.
> > 
> > Signed-off-by: Alban Bedel <albeu@free.fr>
> 
> Acked-by: Marc Zyngier <marc.zyngier@arm.com>

Thanks Marc, I'll pick this up when -rc1 drops.

thx,

Jason.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/2] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
  2016-01-23 16:31   ` Jason Cooper
@ 2016-02-17 13:15     ` Alban
  2016-02-17 16:13       ` Jason Cooper
  0 siblings, 1 reply; 7+ messages in thread
From: Alban @ 2016-02-17 13:15 UTC (permalink / raw)
  To: Jason Cooper
  Cc: Aban Bedel, Marc Zyngier, linux-mips, Ralf Baechle,
	Thomas Gleixner, Alexander Couzens, Joel Porquet, linux-kernel

On Sat, 23 Jan 2016 16:31:22 +0000
Jason Cooper <jason@lakedaemon.net> wrote:

> On Sat, Jan 23, 2016 at 03:02:00PM +0000, Marc Zyngier wrote:
> > On Sat, 23 Jan 2016 13:57:46 +0100
> > Alban Bedel <albeu@free.fr> wrote:
> > 
> > > The driver stays the same but the initialization changes a bit.
> > > For OF boards we now get the memory map from the OF node and use
> > > a linear mapping instead of the legacy mapping. For legacy boards
> > > we still use a legacy mapping and just pass down all the parameters
> > > from the board init code.
> > > 
> > > Signed-off-by: Alban Bedel <albeu@free.fr>
> > 
> > Acked-by: Marc Zyngier <marc.zyngier@arm.com>
> 
> Thanks Marc, I'll pick this up when -rc1 drops.

RC1 has been released for a while now, however I still can't see
these patches in the irqchip git trees. I checked both tree:

git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
git://git.infradead.org/users/jcooper/linux.git irqchip/core

or are these still queued and going to be merged later?

Alban

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/2] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
  2016-02-17 13:15     ` Alban
@ 2016-02-17 16:13       ` Jason Cooper
  0 siblings, 0 replies; 7+ messages in thread
From: Jason Cooper @ 2016-02-17 16:13 UTC (permalink / raw)
  To: Alban
  Cc: Marc Zyngier, linux-mips, Ralf Baechle, Thomas Gleixner,
	Alexander Couzens, Joel Porquet, linux-kernel

Hey Alban,

On Wed, Feb 17, 2016 at 02:15:29PM +0100, Alban wrote:
> On Sat, 23 Jan 2016 16:31:22 +0000
> Jason Cooper <jason@lakedaemon.net> wrote:
> 
> > On Sat, Jan 23, 2016 at 03:02:00PM +0000, Marc Zyngier wrote:
> > > On Sat, 23 Jan 2016 13:57:46 +0100
> > > Alban Bedel <albeu@free.fr> wrote:
> > > 
> > > > The driver stays the same but the initialization changes a bit.
> > > > For OF boards we now get the memory map from the OF node and use
> > > > a linear mapping instead of the legacy mapping. For legacy boards
> > > > we still use a legacy mapping and just pass down all the parameters
> > > > from the board init code.
> > > > 
> > > > Signed-off-by: Alban Bedel <albeu@free.fr>
> > > 
> > > Acked-by: Marc Zyngier <marc.zyngier@arm.com>
> > 
> > Thanks Marc, I'll pick this up when -rc1 drops.
> 
> RC1 has been released for a while now, however I still can't see
> these patches in the irqchip git trees. I checked both tree:
> 
> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
> git://git.infradead.org/users/jcooper/linux.git irqchip/core
> 
> or are these still queued and going to be merged later?

I've just queued them up, but ran into a needed git gc...  They should
be pushed by the end of the day.

thx,

Jason.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/2] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
  2016-01-23 12:57 [PATCH v2 1/2] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip Alban Bedel
  2016-01-23 12:57 ` [PATCH v2 2/2] MIPS: ath79: irq: Move the CPU IRQ " Alban Bedel
  2016-01-23 15:02 ` [PATCH v2 1/2] MIPS: ath79: irq: Move the MISC " Marc Zyngier
@ 2016-02-17 21:17 ` Jason Cooper
  2 siblings, 0 replies; 7+ messages in thread
From: Jason Cooper @ 2016-02-17 21:17 UTC (permalink / raw)
  To: Alban Bedel
  Cc: linux-mips, Ralf Baechle, Thomas Gleixner, Marc Zyngier,
	Alexander Couzens, Joel Porquet, linux-kernel

Hi Alban,

On Sat, Jan 23, 2016 at 01:57:46PM +0100, Alban Bedel wrote:
> The driver stays the same but the initialization changes a bit.
> For OF boards we now get the memory map from the OF node and use
> a linear mapping instead of the legacy mapping. For legacy boards
> we still use a legacy mapping and just pass down all the parameters
> from the board init code.
> 
> Signed-off-by: Alban Bedel <albeu@free.fr>
> ---
> Changelog:
> v2: * Added the missing calls to chained_irq_enter/leave()
> ---
>  arch/mips/ath79/irq.c                    | 163 +++-----------------------
>  arch/mips/include/asm/mach-ath79/ath79.h |   3 +
>  drivers/irqchip/Makefile                 |   1 +
>  drivers/irqchip/irq-ath79-misc.c         | 189 +++++++++++++++++++++++++++++++
>  4 files changed, 208 insertions(+), 148 deletions(-)
>  create mode 100644 drivers/irqchip/irq-ath79-misc.c

Both applied to irqchip/mips with Marc's Acked-by.

thx,

Jason.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-02-17 21:18 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-23 12:57 [PATCH v2 1/2] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip Alban Bedel
2016-01-23 12:57 ` [PATCH v2 2/2] MIPS: ath79: irq: Move the CPU IRQ " Alban Bedel
2016-01-23 15:02 ` [PATCH v2 1/2] MIPS: ath79: irq: Move the MISC " Marc Zyngier
2016-01-23 16:31   ` Jason Cooper
2016-02-17 13:15     ` Alban
2016-02-17 16:13       ` Jason Cooper
2016-02-17 21:17 ` Jason Cooper

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).