All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] MIPS: ath79: Move the IRQ drivers to drivers/irqchip
@ 2015-11-17 19:34 Alban Bedel
  2015-11-17 19:34 ` [PATCH 1/6] MIPS: ath79: Fix the size of the MISC INTC registers in ar9132.dtsi Alban Bedel
                   ` (5 more replies)
  0 siblings, 6 replies; 23+ messages in thread
From: Alban Bedel @ 2015-11-17 19:34 UTC (permalink / raw)
  To: linux-mips
  Cc: Ralf Baechle, Thomas Gleixner, Jason Cooper, Marc Zyngier,
	Alexander Couzens, Joel Porquet, Andrew Bresticker, linux-kernel,
	Alban Bedel

Hi all,

A first round of cleanup on the IRQ code to move most of it to
drivers/irqchip. After this the handlers for the cascaded interrupts on the
 ar934x and qca955x is the only IRQ code left in the platform directory.
For these two a new driver must be written first.

Alban

Alban Bedel (6):
  MIPS: ath79: Fix the size of the MISC INTC registers in ar9132.dtsi
  MIPS: ath79: irq: Remove useless #ifdef CONFIG_IRQCHIP
  MIPS: ath79: irq: Prepare moving the MISC driver to drivers/irqchip
  MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
  MIPS: ath79: Allow using ath79_ddr_wb_flush() from drivers
  MIPS: ath79: irq: Move the CPU IRQ driver to drivers/irqchip

 arch/mips/ath79/common.h                 |   1 -
 arch/mips/ath79/irq.c                    | 249 +++----------------------------
 arch/mips/boot/dts/qca/ar9132.dtsi       |   2 +-
 arch/mips/include/asm/mach-ath79/ath79.h |   5 +
 drivers/irqchip/Makefile                 |   2 +
 drivers/irqchip/irq-ath79-cpu.c          |  97 ++++++++++++
 drivers/irqchip/irq-ath79-misc.c         | 182 ++++++++++++++++++++++
 7 files changed, 308 insertions(+), 230 deletions(-)
 create mode 100644 drivers/irqchip/irq-ath79-cpu.c
 create mode 100644 drivers/irqchip/irq-ath79-misc.c

-- 
2.0.0


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

* [PATCH 1/6] MIPS: ath79: Fix the size of the MISC INTC registers in ar9132.dtsi
  2015-11-17 19:34 [PATCH 0/6] MIPS: ath79: Move the IRQ drivers to drivers/irqchip Alban Bedel
@ 2015-11-17 19:34 ` Alban Bedel
  2015-11-17 19:34 ` [PATCH 2/6] MIPS: ath79: irq: Remove useless #ifdef CONFIG_IRQCHIP Alban Bedel
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 23+ messages in thread
From: Alban Bedel @ 2015-11-17 19:34 UTC (permalink / raw)
  To: linux-mips
  Cc: Ralf Baechle, Thomas Gleixner, Jason Cooper, Marc Zyngier,
	Alexander Couzens, Joel Porquet, Andrew Bresticker, linux-kernel,
	Alban Bedel

There is 2 registers that is 8 bytes long, not 4.

Signed-off-by: Alban Bedel <albeu@free.fr>
---
 arch/mips/boot/dts/qca/ar9132.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/boot/dts/qca/ar9132.dtsi b/arch/mips/boot/dts/qca/ar9132.dtsi
index 857ca48..3ad4ba9 100644
--- a/arch/mips/boot/dts/qca/ar9132.dtsi
+++ b/arch/mips/boot/dts/qca/ar9132.dtsi
@@ -107,7 +107,7 @@
 			miscintc: interrupt-controller@18060010 {
 				compatible = "qca,ar9132-misc-intc",
 					   "qca,ar7100-misc-intc";
-				reg = <0x18060010 0x4>;
+				reg = <0x18060010 0x8>;
 
 				interrupt-parent = <&cpuintc>;
 				interrupts = <6>;
-- 
2.0.0


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

* [PATCH 2/6] MIPS: ath79: irq: Remove useless #ifdef CONFIG_IRQCHIP
  2015-11-17 19:34 [PATCH 0/6] MIPS: ath79: Move the IRQ drivers to drivers/irqchip Alban Bedel
  2015-11-17 19:34 ` [PATCH 1/6] MIPS: ath79: Fix the size of the MISC INTC registers in ar9132.dtsi Alban Bedel
@ 2015-11-17 19:34 ` Alban Bedel
  2015-11-17 19:34 ` [PATCH 3/6] MIPS: ath79: irq: Prepare moving the MISC driver to drivers/irqchip Alban Bedel
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 23+ messages in thread
From: Alban Bedel @ 2015-11-17 19:34 UTC (permalink / raw)
  To: linux-mips
  Cc: Ralf Baechle, Thomas Gleixner, Jason Cooper, Marc Zyngier,
	Alexander Couzens, Joel Porquet, Andrew Bresticker, linux-kernel,
	Alban Bedel

IRQCHIP is always enabled, so the #ifdef can just be removed.

Signed-off-by: Alban Bedel <albeu@free.fr>
---
 arch/mips/ath79/irq.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
index eeb3953..26f8d1b 100644
--- a/arch/mips/ath79/irq.c
+++ b/arch/mips/ath79/irq.c
@@ -256,7 +256,6 @@ asmlinkage void plat_irq_dispatch(void)
 	}
 }
 
-#ifdef CONFIG_IRQCHIP
 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);
@@ -349,8 +348,6 @@ static int __init ar79_cpu_intc_of_init(
 IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc",
 		ar79_cpu_intc_of_init);
 
-#endif
-
 void __init arch_init_irq(void)
 {
 	if (mips_machtype == ATH79_MACH_GENERIC_OF) {
-- 
2.0.0


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

* [PATCH 3/6] MIPS: ath79: irq: Prepare moving the MISC driver to drivers/irqchip
  2015-11-17 19:34 [PATCH 0/6] MIPS: ath79: Move the IRQ drivers to drivers/irqchip Alban Bedel
  2015-11-17 19:34 ` [PATCH 1/6] MIPS: ath79: Fix the size of the MISC INTC registers in ar9132.dtsi Alban Bedel
  2015-11-17 19:34 ` [PATCH 2/6] MIPS: ath79: irq: Remove useless #ifdef CONFIG_IRQCHIP Alban Bedel
@ 2015-11-17 19:34 ` Alban Bedel
  2015-11-17 19:34 ` [PATCH 4/6] MIPS: ath79: irq: Move " Alban Bedel
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 23+ messages in thread
From: Alban Bedel @ 2015-11-17 19:34 UTC (permalink / raw)
  To: linux-mips
  Cc: Ralf Baechle, Thomas Gleixner, Jason Cooper, Marc Zyngier,
	Alexander Couzens, Joel Porquet, Andrew Bresticker, linux-kernel,
	Alban Bedel

To prepare moving out of the arch directory rework the MISC
implementation to use irq domains instead of hard coded IRQ numbers.
Also remove the uses of the ath79_reset_base global pointer in the IRQ
methods.

Signed-off-by: Alban Bedel <albeu@free.fr>
---
 arch/mips/ath79/irq.c | 58 +++++++++++++++++++++++++--------------------------
 1 file changed, 28 insertions(+), 30 deletions(-)

diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
index 26f8d1b..511c065 100644
--- a/arch/mips/ath79/irq.c
+++ b/arch/mips/ath79/irq.c
@@ -26,9 +26,13 @@
 #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)
 {
-	void __iomem *base = ath79_reset_base;
+	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) &
@@ -42,15 +46,15 @@ static void ath79_misc_irq_handler(struct irq_desc *desc)
 	while (pending) {
 		int bit = __ffs(pending);
 
-		generic_handle_irq(ATH79_MISC_IRQ(bit));
+		generic_handle_irq(irq_linear_revmap(domain, bit));
 		pending &= ~BIT(bit);
 	}
 }
 
 static void ar71xx_misc_irq_unmask(struct irq_data *d)
 {
-	unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
-	void __iomem *base = ath79_reset_base;
+	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);
@@ -62,8 +66,8 @@ static void ar71xx_misc_irq_unmask(struct irq_data *d)
 
 static void ar71xx_misc_irq_mask(struct irq_data *d)
 {
-	unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
-	void __iomem *base = ath79_reset_base;
+	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);
@@ -75,8 +79,8 @@ static void ar71xx_misc_irq_mask(struct irq_data *d)
 
 static void ar724x_misc_irq_ack(struct irq_data *d)
 {
-	unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
-	void __iomem *base = ath79_reset_base;
+	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);
@@ -94,12 +98,6 @@ static struct irq_chip ath79_misc_irq_chip = {
 
 static void __init ath79_misc_irq_init(void)
 {
-	void __iomem *base = ath79_reset_base;
-	int i;
-
-	__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
-	__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
-
 	if (soc_is_ar71xx() || soc_is_ar913x())
 		ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
 	else if (soc_is_ar724x() ||
@@ -110,13 +108,7 @@ static void __init ath79_misc_irq_init(void)
 	else
 		BUG();
 
-	for (i = ATH79_MISC_IRQ_BASE;
-	     i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) {
-		irq_set_chip_and_handler(i, &ath79_misc_irq_chip,
-					 handle_level_irq);
-	}
-
-	irq_set_chained_handler(ATH79_CPU_IRQ(6), ath79_misc_irq_handler);
+	ath79_misc_intc_domain_init(NULL, ATH79_CPU_IRQ(6));
 }
 
 static void ar934x_ip2_irq_dispatch(struct irq_desc *desc)
@@ -259,6 +251,7 @@ 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;
 }
 
@@ -267,19 +260,14 @@ static const struct irq_domain_ops misc_irq_domain_ops = {
 	.map = misc_map,
 };
 
-static int __init ath79_misc_intc_of_init(
-	struct device_node *node, struct device_node *parent)
+static void __init ath79_misc_intc_domain_init(
+	struct device_node *node, int irq)
 {
 	void __iomem *base = ath79_reset_base;
 	struct irq_domain *domain;
-	int irq;
-
-	irq = irq_of_parse_and_map(node, 0);
-	if (!irq)
-		panic("Failed to get MISC IRQ");
 
 	domain = irq_domain_add_legacy(node, ATH79_MISC_IRQ_COUNT,
-			ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, NULL);
+			ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, base);
 	if (!domain)
 		panic("Failed to add MISC irqdomain");
 
@@ -287,9 +275,19 @@ static int __init ath79_misc_intc_of_init(
 	__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);
+}
 
-	irq_set_chained_handler(irq, ath79_misc_irq_handler);
+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;
 }
 
-- 
2.0.0


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

* [PATCH 4/6] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
  2015-11-17 19:34 [PATCH 0/6] MIPS: ath79: Move the IRQ drivers to drivers/irqchip Alban Bedel
                   ` (2 preceding siblings ...)
  2015-11-17 19:34 ` [PATCH 3/6] MIPS: ath79: irq: Prepare moving the MISC driver to drivers/irqchip Alban Bedel
@ 2015-11-17 19:34 ` Alban Bedel
  2015-11-17 20:03   ` Jason Cooper
                     ` (2 more replies)
  2015-11-17 19:34 ` [PATCH 5/6] MIPS: ath79: Allow using ath79_ddr_wb_flush() from drivers Alban Bedel
  2015-11-17 19:34 ` [PATCH 6/6] MIPS: ath79: irq: Move the CPU IRQ driver to drivers/irqchip Alban Bedel
  5 siblings, 3 replies; 23+ messages in thread
From: Alban Bedel @ 2015-11-17 19:34 UTC (permalink / raw)
  To: linux-mips
  Cc: Ralf Baechle, Thomas Gleixner, Jason Cooper, Marc Zyngier,
	Alexander Couzens, Joel Porquet, Andrew Bresticker, 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>
---
 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         | 182 +++++++++++++++++++++++++++++++
 4 files changed, 201 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 4eee221..ce493fc 100644
--- a/arch/mips/include/asm/mach-ath79/ath79.h
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -143,4 +143,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..bd2121f1
--- /dev/null
+++ b/drivers/irqchip/irq-ath79-misc.c
@@ -0,0 +1,182 @@
+/*
+ *  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/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);
+	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 | 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] 23+ messages in thread

* [PATCH 5/6] MIPS: ath79: Allow using ath79_ddr_wb_flush() from drivers
  2015-11-17 19:34 [PATCH 0/6] MIPS: ath79: Move the IRQ drivers to drivers/irqchip Alban Bedel
                   ` (3 preceding siblings ...)
  2015-11-17 19:34 ` [PATCH 4/6] MIPS: ath79: irq: Move " Alban Bedel
@ 2015-11-17 19:34 ` Alban Bedel
  2015-11-17 19:34 ` [PATCH 6/6] MIPS: ath79: irq: Move the CPU IRQ driver to drivers/irqchip Alban Bedel
  5 siblings, 0 replies; 23+ messages in thread
From: Alban Bedel @ 2015-11-17 19:34 UTC (permalink / raw)
  To: linux-mips
  Cc: Ralf Baechle, Thomas Gleixner, Jason Cooper, Marc Zyngier,
	Alexander Couzens, Joel Porquet, Andrew Bresticker, linux-kernel,
	Alban Bedel

Move the declaration of ath79_ddr_wb_flush() to asm/mach-ath79/ath79.h
to allow using it from drivers. This is needed to move the CPU IRQ
driver to drivers/irqchip.

Signed-off-by: Alban Bedel <albeu@free.fr>
---
 arch/mips/ath79/common.h                 | 1 -
 arch/mips/include/asm/mach-ath79/ath79.h | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/ath79/common.h b/arch/mips/ath79/common.h
index ca7cc19..870c6b2 100644
--- a/arch/mips/ath79/common.h
+++ b/arch/mips/ath79/common.h
@@ -23,7 +23,6 @@ void ath79_clocks_init(void);
 unsigned long ath79_get_sys_clk_rate(const char *id);
 
 void ath79_ddr_ctrl_init(void);
-void ath79_ddr_wb_flush(unsigned int reg);
 
 void ath79_gpio_init(void);
 
diff --git a/arch/mips/include/asm/mach-ath79/ath79.h b/arch/mips/include/asm/mach-ath79/ath79.h
index ce493fc..22a2f56 100644
--- a/arch/mips/include/asm/mach-ath79/ath79.h
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -115,6 +115,7 @@ static inline int soc_is_qca955x(void)
 	return soc_is_qca9556() || soc_is_qca9558();
 }
 
+void ath79_ddr_wb_flush(unsigned int reg);
 void ath79_ddr_set_pci_windows(void);
 
 extern void __iomem *ath79_pll_base;
-- 
2.0.0


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

* [PATCH 6/6] MIPS: ath79: irq: Move the CPU IRQ driver to drivers/irqchip
  2015-11-17 19:34 [PATCH 0/6] MIPS: ath79: Move the IRQ drivers to drivers/irqchip Alban Bedel
                   ` (4 preceding siblings ...)
  2015-11-17 19:34 ` [PATCH 5/6] MIPS: ath79: Allow using ath79_ddr_wb_flush() from drivers Alban Bedel
@ 2015-11-17 19:34 ` Alban Bedel
  2016-01-20 12:49     ` Marc Zyngier
  5 siblings, 1 reply; 23+ messages in thread
From: Alban Bedel @ 2015-11-17 19:34 UTC (permalink / raw)
  To: linux-mips
  Cc: Ralf Baechle, Thomas Gleixner, Jason Cooper, Marc Zyngier,
	Alexander Couzens, Joel Porquet, Andrew Bresticker, linux-kernel,
	Alban Bedel

Signed-off-by: Alban Bedel <albeu@free.fr>
---
 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] 23+ messages in thread

* Re: [PATCH 4/6] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
  2015-11-17 19:34 ` [PATCH 4/6] MIPS: ath79: irq: Move " Alban Bedel
@ 2015-11-17 20:03   ` Jason Cooper
  2015-11-17 20:06     ` Thomas Gleixner
  2015-12-30 13:53     ` Alban
  2016-01-20 12:38     ` Marc Zyngier
  2 siblings, 1 reply; 23+ messages in thread
From: Jason Cooper @ 2015-11-17 20:03 UTC (permalink / raw)
  To: Alban Bedel
  Cc: linux-mips, Ralf Baechle, Thomas Gleixner, Marc Zyngier,
	Alexander Couzens, Joel Porquet, Andrew Bresticker, linux-kernel

Hi Alban,

On Tue, Nov 17, 2015 at 08:34:54PM +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>
> ---
>  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         | 182 +++++++++++++++++++++++++++++++
>  4 files changed, 201 insertions(+), 148 deletions(-)
>  create mode 100644 drivers/irqchip/irq-ath79-misc.c
...
> 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

CONFIG_ARCH_ATH79 ?

Same for the last patch in the series (cpu driver).

thx,

Jason.

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

* Re: [PATCH 4/6] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
  2015-11-17 20:03   ` Jason Cooper
@ 2015-11-17 20:06     ` Thomas Gleixner
  2015-11-17 20:09       ` Jason Cooper
  0 siblings, 1 reply; 23+ messages in thread
From: Thomas Gleixner @ 2015-11-17 20:06 UTC (permalink / raw)
  To: Jason Cooper
  Cc: Alban Bedel, linux-mips, Ralf Baechle, Marc Zyngier,
	Alexander Couzens, Joel Porquet, Andrew Bresticker, linux-kernel

On Tue, 17 Nov 2015, Jason Cooper wrote:
> Hi Alban,
> 
> On Tue, Nov 17, 2015 at 08:34:54PM +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>
> > ---
> >  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         | 182 +++++++++++++++++++++++++++++++
> >  4 files changed, 201 insertions(+), 148 deletions(-)
> >  create mode 100644 drivers/irqchip/irq-ath79-misc.c
> ...
> > 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
> 
> CONFIG_ARCH_ATH79 ?

Nope.

arch/mips/Kconfig:config ATH79

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

* Re: [PATCH 4/6] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
  2015-11-17 20:06     ` Thomas Gleixner
@ 2015-11-17 20:09       ` Jason Cooper
  0 siblings, 0 replies; 23+ messages in thread
From: Jason Cooper @ 2015-11-17 20:09 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Alban Bedel, linux-mips, Ralf Baechle, Marc Zyngier,
	Alexander Couzens, Joel Porquet, Andrew Bresticker, linux-kernel

On Tue, Nov 17, 2015 at 09:06:47PM +0100, Thomas Gleixner wrote:
> On Tue, 17 Nov 2015, Jason Cooper wrote:
> > Hi Alban,
> > 
> > On Tue, Nov 17, 2015 at 08:34:54PM +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>
> > > ---
> > >  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         | 182 +++++++++++++++++++++++++++++++
> > >  4 files changed, 201 insertions(+), 148 deletions(-)
> > >  create mode 100644 drivers/irqchip/irq-ath79-misc.c
> > ...
> > > 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
> > 
> > CONFIG_ARCH_ATH79 ?
> 
> Nope.

dabbit.

> arch/mips/Kconfig:config ATH79

So it is.

thx,

Jason.

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

* Re: [PATCH 4/6] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
@ 2015-12-30 13:53     ` Alban
  0 siblings, 0 replies; 23+ messages in thread
From: Alban @ 2015-12-30 13:53 UTC (permalink / raw)
  Cc: Aban Bedel, linux-mips, Ralf Baechle, Thomas Gleixner,
	Jason Cooper, Marc Zyngier, Alexander Couzens, Joel Porquet,
	Andrew Bresticker, linux-kernel

On Tue, 17 Nov 2015 20:34:54 +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>

Most of this series has been applied to the MIPS tree, but patch 4
and 6 are still waiting for an ACK from the irqchip maintainers.
Is there any problem with those patches?

Alban

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

* Re: [PATCH 4/6] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
@ 2015-12-30 13:53     ` Alban
  0 siblings, 0 replies; 23+ messages in thread
From: Alban @ 2015-12-30 13:53 UTC (permalink / raw)
  Cc: Aban Bedel, linux-mips, Ralf Baechle, Thomas Gleixner,
	Jason Cooper, Marc Zyngier, Alexander Couzens, Joel Porquet,
	Andrew Bresticker, linux-kernel

On Tue, 17 Nov 2015 20:34:54 +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>

Most of this series has been applied to the MIPS tree, but patch 4
and 6 are still waiting for an ACK from the irqchip maintainers.
Is there any problem with those patches?

Alban

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

* Re: [PATCH 4/6] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
@ 2016-01-20  8:15       ` Alban
  0 siblings, 0 replies; 23+ messages in thread
From: Alban @ 2016-01-20  8:15 UTC (permalink / raw)
  Cc: Aban Bedel, linux-mips, Ralf Baechle, Thomas Gleixner,
	Jason Cooper, Marc Zyngier, Alexander Couzens, Joel Porquet,
	Andrew Bresticker, linux-kernel

On Wed, 30 Dec 2015 14:53:29 +0100
Alban <albeu@free.fr> wrote:

> On Tue, 17 Nov 2015 20:34:54 +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>
> 
> Most of this series has been applied to the MIPS tree, but patch 4
> and 6 are still waiting for an ACK from the irqchip maintainers.
> Is there any problem with those patches?

Ping? This change has been explicitly requested by the IRQ chip
maintainers several times. Can we get at least a comment for these 2
patches? I would really like to finally get them in for 4.5.

Alban

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

* Re: [PATCH 4/6] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
@ 2016-01-20  8:15       ` Alban
  0 siblings, 0 replies; 23+ messages in thread
From: Alban @ 2016-01-20  8:15 UTC (permalink / raw)
  Cc: Aban Bedel, linux-mips, Ralf Baechle, Thomas Gleixner,
	Jason Cooper, Marc Zyngier, Alexander Couzens, Joel Porquet,
	Andrew Bresticker, linux-kernel

On Wed, 30 Dec 2015 14:53:29 +0100
Alban <albeu@free.fr> wrote:

> On Tue, 17 Nov 2015 20:34:54 +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>
> 
> Most of this series has been applied to the MIPS tree, but patch 4
> and 6 are still waiting for an ACK from the irqchip maintainers.
> Is there any problem with those patches?

Ping? This change has been explicitly requested by the IRQ chip
maintainers several times. Can we get at least a comment for these 2
patches? I would really like to finally get them in for 4.5.

Alban

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

* Re: [PATCH 4/6] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
@ 2016-01-20 12:38     ` Marc Zyngier
  0 siblings, 0 replies; 23+ messages in thread
From: Marc Zyngier @ 2016-01-20 12:38 UTC (permalink / raw)
  To: Alban Bedel
  Cc: linux-mips, Ralf Baechle, Thomas Gleixner, Jason Cooper,
	Alexander Couzens, Joel Porquet, Andrew Bresticker, linux-kernel

On Tue, 17 Nov 2015 20:34:54 +0100
Alban Bedel <albeu@free.fr> wrote:

Hi Alban,

> 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>
> ---
>  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         | 182 +++++++++++++++++++++++++++++++
>  4 files changed, 201 insertions(+), 148 deletions(-)
>  create mode 100644 drivers/irqchip/irq-ath79-misc.c
> 

[...]

> diff --git a/drivers/irqchip/irq-ath79-misc.c b/drivers/irqchip/irq-ath79-misc.c
> new file mode 100644
> index 0000000..bd2121f1
> --- /dev/null
> +++ b/drivers/irqchip/irq-ath79-misc.c
> @@ -0,0 +1,182 @@
> +/*
> + *  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/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);
> +	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);
> +	}
> +}

Given that this function is used as a chained handler, it seems to be
missing the usual chained_irq_enter/exit...

> +
> +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);
> +}

Other than that, this looks OK.

Thanks,

	M.
-- 
AAAFNRAA

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

* Re: [PATCH 4/6] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
@ 2016-01-20 12:38     ` Marc Zyngier
  0 siblings, 0 replies; 23+ messages in thread
From: Marc Zyngier @ 2016-01-20 12:38 UTC (permalink / raw)
  To: Alban Bedel
  Cc: linux-mips, Ralf Baechle, Thomas Gleixner, Jason Cooper,
	Alexander Couzens, Joel Porquet, Andrew Bresticker, linux-kernel

On Tue, 17 Nov 2015 20:34:54 +0100
Alban Bedel <albeu@free.fr> wrote:

Hi Alban,

> 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>
> ---
>  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         | 182 +++++++++++++++++++++++++++++++
>  4 files changed, 201 insertions(+), 148 deletions(-)
>  create mode 100644 drivers/irqchip/irq-ath79-misc.c
> 

[...]

> diff --git a/drivers/irqchip/irq-ath79-misc.c b/drivers/irqchip/irq-ath79-misc.c
> new file mode 100644
> index 0000000..bd2121f1
> --- /dev/null
> +++ b/drivers/irqchip/irq-ath79-misc.c
> @@ -0,0 +1,182 @@
> +/*
> + *  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/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);
> +	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);
> +	}
> +}

Given that this function is used as a chained handler, it seems to be
missing the usual chained_irq_enter/exit...

> +
> +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);
> +}

Other than that, this looks OK.

Thanks,

	M.
-- 
AAAFNRAA

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

* Re: [PATCH 6/6] MIPS: ath79: irq: Move the CPU IRQ driver to drivers/irqchip
@ 2016-01-20 12:49     ` Marc Zyngier
  0 siblings, 0 replies; 23+ messages in thread
From: Marc Zyngier @ 2016-01-20 12:49 UTC (permalink / raw)
  To: Alban Bedel
  Cc: linux-mips, Ralf Baechle, Thomas Gleixner, Jason Cooper,
	Alexander Couzens, Joel Porquet, Andrew Bresticker, linux-kernel

On Tue, 17 Nov 2015 20:34:56 +0100
Alban Bedel <albeu@free.fr> wrote:

> Signed-off-by: Alban Bedel <albeu@free.fr>
> ---
>  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/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);

I'm rather unfamiliar with the MIPS IRQ handling, but I'm vaguely
surprised by the lack of domain. How do you unsure that the IRQ space
used here doesn't clash with the one created in your "misc" irqchip?

> +		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();
> +}

Thanks,

	M.
-- 
AAAFNRAA

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

* Re: [PATCH 6/6] MIPS: ath79: irq: Move the CPU IRQ driver to drivers/irqchip
@ 2016-01-20 12:49     ` Marc Zyngier
  0 siblings, 0 replies; 23+ messages in thread
From: Marc Zyngier @ 2016-01-20 12:49 UTC (permalink / raw)
  To: Alban Bedel
  Cc: linux-mips, Ralf Baechle, Thomas Gleixner, Jason Cooper,
	Alexander Couzens, Joel Porquet, Andrew Bresticker, linux-kernel

On Tue, 17 Nov 2015 20:34:56 +0100
Alban Bedel <albeu@free.fr> wrote:

> Signed-off-by: Alban Bedel <albeu@free.fr>
> ---
>  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/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);

I'm rather unfamiliar with the MIPS IRQ handling, but I'm vaguely
surprised by the lack of domain. How do you unsure that the IRQ space
used here doesn't clash with the one created in your "misc" irqchip?

> +		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();
> +}

Thanks,

	M.
-- 
AAAFNRAA

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

* Re: [PATCH 6/6] MIPS: ath79: irq: Move the CPU IRQ driver to drivers/irqchip
@ 2016-01-20 19:46       ` Alban
  0 siblings, 0 replies; 23+ messages in thread
From: Alban @ 2016-01-20 19:46 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Aban Bedel, linux-mips, Ralf Baechle, Thomas Gleixner,
	Jason Cooper, Alexander Couzens, Joel Porquet, Andrew Bresticker,
	linux-kernel

On Wed, 20 Jan 2016 12:49:48 +0000
Marc Zyngier <marc.zyngier@arm.com> wrote:

> On Tue, 17 Nov 2015 20:34:56 +0100
> Alban Bedel <albeu@free.fr> wrote:
> 
> > Signed-off-by: Alban Bedel <albeu@free.fr>
> > ---
> >  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
> >
 
 [...]

> > +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);
> 
> I'm rather unfamiliar with the MIPS IRQ handling, but I'm vaguely
> surprised by the lack of domain. How do you unsure that the IRQ space
> used here doesn't clash with the one created in your "misc" irqchip?

This driver extend the irq-mips-cpu driver which take care of setting up
a legacy domain starting from MIPS_CPU_IRQ_BASE for these interrupts. I
don't find this very nice either, but this patch is about moving the
code out of arch/mips, so I tried to minimize unrelated changes.

Alban

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

* Re: [PATCH 6/6] MIPS: ath79: irq: Move the CPU IRQ driver to drivers/irqchip
@ 2016-01-20 19:46       ` Alban
  0 siblings, 0 replies; 23+ messages in thread
From: Alban @ 2016-01-20 19:46 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Aban Bedel, linux-mips, Ralf Baechle, Thomas Gleixner,
	Jason Cooper, Alexander Couzens, Joel Porquet, Andrew Bresticker,
	linux-kernel

On Wed, 20 Jan 2016 12:49:48 +0000
Marc Zyngier <marc.zyngier@arm.com> wrote:

> On Tue, 17 Nov 2015 20:34:56 +0100
> Alban Bedel <albeu@free.fr> wrote:
> 
> > Signed-off-by: Alban Bedel <albeu@free.fr>
> > ---
> >  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
> >
 
 [...]

> > +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);
> 
> I'm rather unfamiliar with the MIPS IRQ handling, but I'm vaguely
> surprised by the lack of domain. How do you unsure that the IRQ space
> used here doesn't clash with the one created in your "misc" irqchip?

This driver extend the irq-mips-cpu driver which take care of setting up
a legacy domain starting from MIPS_CPU_IRQ_BASE for these interrupts. I
don't find this very nice either, but this patch is about moving the
code out of arch/mips, so I tried to minimize unrelated changes.

Alban

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

* Re: [PATCH 4/6] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
@ 2016-01-20 19:51       ` Alban
  0 siblings, 0 replies; 23+ messages in thread
From: Alban @ 2016-01-20 19:51 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Aban Bedel, linux-mips, Ralf Baechle, Thomas Gleixner,
	Jason Cooper, Alexander Couzens, Joel Porquet, Andrew Bresticker,
	linux-kernel

On Wed, 20 Jan 2016 12:38:41 +0000
Marc Zyngier <marc.zyngier@arm.com> wrote:

> On Tue, 17 Nov 2015 20:34:54 +0100
> Alban Bedel <albeu@free.fr> wrote:
> 
> Hi Alban,
> 
> > 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>
> > ---
> >  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         | 182 +++++++++++++++++++++++++++++++
> >  4 files changed, 201 insertions(+), 148 deletions(-)
> >  create mode 100644 drivers/irqchip/irq-ath79-misc.c
> > 
> 
> [...]
> 
> > diff --git a/drivers/irqchip/irq-ath79-misc.c b/drivers/irqchip/irq-ath79-misc.c
> > new file mode 100644
> > index 0000000..bd2121f1
> > --- /dev/null
> > +++ b/drivers/irqchip/irq-ath79-misc.c
> > @@ -0,0 +1,182 @@
> > +/*
> > + *  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/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);
> > +	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);
> > +	}
> > +}
> 
> Given that this function is used as a chained handler, it seems to be
> missing the usual chained_irq_enter/exit...

I'll fix this.

> > +
> > +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);
> > +}
> 
> Other than that, this looks OK.
> 
> Thanks,

Great, thanks for the review.

Alban

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

* Re: [PATCH 4/6] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
@ 2016-01-20 19:51       ` Alban
  0 siblings, 0 replies; 23+ messages in thread
From: Alban @ 2016-01-20 19:51 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Aban Bedel, linux-mips, Ralf Baechle, Thomas Gleixner,
	Jason Cooper, Alexander Couzens, Joel Porquet, Andrew Bresticker,
	linux-kernel

On Wed, 20 Jan 2016 12:38:41 +0000
Marc Zyngier <marc.zyngier@arm.com> wrote:

> On Tue, 17 Nov 2015 20:34:54 +0100
> Alban Bedel <albeu@free.fr> wrote:
> 
> Hi Alban,
> 
> > 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>
> > ---
> >  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         | 182 +++++++++++++++++++++++++++++++
> >  4 files changed, 201 insertions(+), 148 deletions(-)
> >  create mode 100644 drivers/irqchip/irq-ath79-misc.c
> > 
> 
> [...]
> 
> > diff --git a/drivers/irqchip/irq-ath79-misc.c b/drivers/irqchip/irq-ath79-misc.c
> > new file mode 100644
> > index 0000000..bd2121f1
> > --- /dev/null
> > +++ b/drivers/irqchip/irq-ath79-misc.c
> > @@ -0,0 +1,182 @@
> > +/*
> > + *  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/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);
> > +	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);
> > +	}
> > +}
> 
> Given that this function is used as a chained handler, it seems to be
> missing the usual chained_irq_enter/exit...

I'll fix this.

> > +
> > +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);
> > +}
> 
> Other than that, this looks OK.
> 
> Thanks,

Great, thanks for the review.

Alban

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

* Re: [PATCH 6/6] MIPS: ath79: irq: Move the CPU IRQ driver to drivers/irqchip
  2016-01-20 19:46       ` Alban
  (?)
@ 2016-01-21  8:52       ` Marc Zyngier
  -1 siblings, 0 replies; 23+ messages in thread
From: Marc Zyngier @ 2016-01-21  8:52 UTC (permalink / raw)
  To: Alban
  Cc: linux-mips, Ralf Baechle, Thomas Gleixner, Jason Cooper,
	Alexander Couzens, Joel Porquet, Andrew Bresticker, linux-kernel

On 20/01/16 19:46, Alban wrote:
> On Wed, 20 Jan 2016 12:49:48 +0000
> Marc Zyngier <marc.zyngier@arm.com> wrote:
> 
>> On Tue, 17 Nov 2015 20:34:56 +0100
>> Alban Bedel <albeu@free.fr> wrote:
>>
>>> Signed-off-by: Alban Bedel <albeu@free.fr>
>>> ---
>>>  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
>>>
>  
>  [...]
> 
>>> +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);
>>
>> I'm rather unfamiliar with the MIPS IRQ handling, but I'm vaguely
>> surprised by the lack of domain. How do you unsure that the IRQ space
>> used here doesn't clash with the one created in your "misc" irqchip?
> 
> This driver extend the irq-mips-cpu driver which take care of setting up
> a legacy domain starting from MIPS_CPU_IRQ_BASE for these interrupts. I
> don't find this very nice either, but this patch is about moving the
> code out of arch/mips, so I tried to minimize unrelated changes.

As long as there is an underlying domain reserving the CPU range, then
this is fine.

So for this patch:

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

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

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

end of thread, other threads:[~2016-01-21  8:52 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-17 19:34 [PATCH 0/6] MIPS: ath79: Move the IRQ drivers to drivers/irqchip Alban Bedel
2015-11-17 19:34 ` [PATCH 1/6] MIPS: ath79: Fix the size of the MISC INTC registers in ar9132.dtsi Alban Bedel
2015-11-17 19:34 ` [PATCH 2/6] MIPS: ath79: irq: Remove useless #ifdef CONFIG_IRQCHIP Alban Bedel
2015-11-17 19:34 ` [PATCH 3/6] MIPS: ath79: irq: Prepare moving the MISC driver to drivers/irqchip Alban Bedel
2015-11-17 19:34 ` [PATCH 4/6] MIPS: ath79: irq: Move " Alban Bedel
2015-11-17 20:03   ` Jason Cooper
2015-11-17 20:06     ` Thomas Gleixner
2015-11-17 20:09       ` Jason Cooper
2015-12-30 13:53   ` Alban
2015-12-30 13:53     ` Alban
2016-01-20  8:15     ` Alban
2016-01-20  8:15       ` Alban
2016-01-20 12:38   ` Marc Zyngier
2016-01-20 12:38     ` Marc Zyngier
2016-01-20 19:51     ` Alban
2016-01-20 19:51       ` Alban
2015-11-17 19:34 ` [PATCH 5/6] MIPS: ath79: Allow using ath79_ddr_wb_flush() from drivers Alban Bedel
2015-11-17 19:34 ` [PATCH 6/6] MIPS: ath79: irq: Move the CPU IRQ driver to drivers/irqchip Alban Bedel
2016-01-20 12:49   ` Marc Zyngier
2016-01-20 12:49     ` Marc Zyngier
2016-01-20 19:46     ` Alban
2016-01-20 19:46       ` Alban
2016-01-21  8:52       ` Marc Zyngier

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.