All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ARM: irqchip: add support for MOXA ART SoCs
@ 2013-06-18  9:59 ` Jonas Jensen
  0 siblings, 0 replies; 23+ messages in thread
From: Jonas Jensen @ 2013-06-18  9:59 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds an irqchip driver for the main interrupt controller found
on MOXA ART SoCs.

Applies to 3.10-rc1 and arm-soc/for-next (2013-06-15)

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---
 drivers/irqchip/Makefile     |    1 +
 drivers/irqchip/irq-moxart.c |  163 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 164 insertions(+), 0 deletions(-)
 create mode 100644 drivers/irqchip/irq-moxart.c

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index cda4cb5..956d129 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_RENESAS_INTC_IRQPIN)	+= irq-renesas-intc-irqpin.o
 obj-$(CONFIG_RENESAS_IRQC)		+= irq-renesas-irqc.o
 obj-$(CONFIG_VERSATILE_FPGA_IRQ)	+= irq-versatile-fpga.o
 obj-$(CONFIG_ARCH_VT8500)		+= irq-vt8500.o
+obj-$(CONFIG_ARCH_MOXART)		+= irq-moxart.o
diff --git a/drivers/irqchip/irq-moxart.c b/drivers/irqchip/irq-moxart.c
new file mode 100644
index 0000000..8606089
--- /dev/null
+++ b/drivers/irqchip/irq-moxart.c
@@ -0,0 +1,163 @@
+/*
+ * MOXA ART SoCs IRQ chip driver.
+ *
+ * Copyright (C) 2013 Jonas Jensen
+ *
+ * Jonas Jensen <jonas.jensen@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+
+#include <asm/exception.h>
+
+#include "irqchip.h"
+
+#define IRQ_SOURCE_REG      0
+#define IRQ_MASK_REG        0x04
+#define IRQ_CLEAR_REG       0x08
+#define IRQ_MODE_REG        0x0c
+#define IRQ_LEVEL_REG       0x10
+#define IRQ_STATUS_REG      0x14
+
+#define FIQ_SOURCE_REG      0x20
+#define FIQ_MASK_REG        0x24
+#define FIQ_CLEAR_REG       0x28
+#define FIQ_MODE_REG        0x2c
+#define FIQ_LEVEL_REG       0x30
+#define FIQ_STATUS_REG      0x34
+
+#define IRQ_SOURCE(base_addr)   (base_addr + 0x00)
+#define IRQ_MASK(base_addr)     (base_addr + 0x04)
+#define IRQ_CLEAR(base_addr)    (base_addr + 0x08)
+#define IRQ_TMODE(base_addr)    (base_addr + 0x0C)
+#define IRQ_TLEVEL(base_addr)   (base_addr + 0x10)
+#define IRQ_STATUS(base_addr)   (base_addr + 0x14)
+#define FIQ_SOURCE(base_addr)   (base_addr + 0x20)
+#define FIQ_MASK(base_addr)     (base_addr + 0x24)
+#define FIQ_CLEAR(base_addr)    (base_addr + 0x28)
+#define FIQ_TMODE(base_addr)    (base_addr + 0x2C)
+#define FIQ_TLEVEL(base_addr)   (base_addr + 0x30)
+#define FIQ_STATUS(base_addr)   (base_addr + 0x34)
+
+static void __iomem *moxart_irq_base;
+static struct irq_domain *moxart_irq_domain;
+static unsigned int interrupt_mask;
+
+asmlinkage void __exception_irq_entry moxart_handle_irq(struct pt_regs *regs);
+
+void moxart_irq_ack(struct irq_data *irqd)
+{
+	unsigned int irq = irqd_to_hwirq(irqd);
+
+	writel(1 << irq, IRQ_CLEAR(moxart_irq_base));
+}
+
+static void moxart_irq_mask(struct irq_data *irqd)
+{
+	unsigned int irq = irqd_to_hwirq(irqd);
+	unsigned int mask;
+
+	mask = readl(IRQ_MASK(moxart_irq_base));
+	mask &= ~(1 << irq);
+	writel(mask, IRQ_MASK(moxart_irq_base));
+}
+
+static void moxart_irq_unmask(struct irq_data *irqd)
+{
+	unsigned int irq = irqd_to_hwirq(irqd);
+	unsigned int mask;
+
+	mask = readl(IRQ_MASK(moxart_irq_base));
+	mask |= (1 << irq);
+	writel(mask, IRQ_MASK(moxart_irq_base));
+}
+
+static struct irq_chip moxart_irq_chip = {
+	.name		= "moxart_irq",
+	.irq_ack	= moxart_irq_ack,
+	.irq_mask	= moxart_irq_mask,
+	.irq_unmask	= moxart_irq_unmask,
+	.irq_set_wake = NULL,
+};
+
+static int moxart_irq_map(struct irq_domain *d, unsigned int virq,
+			 irq_hw_number_t hw)
+{
+	if ((1 << hw) && interrupt_mask) {
+		irq_set_chip_and_handler(virq, &moxart_irq_chip,
+			handle_edge_irq);
+		pr_info("%s: irq_set_chip_and_handler edge virq=%d hw=%d\n",
+			__func__, virq, (unsigned int) hw);
+	} else {
+		irq_set_chip_and_handler(virq, &moxart_irq_chip,
+			handle_level_irq);
+		pr_info("%s: irq_set_chip_and_handler level virq=%d hw=%d\n",
+			__func__, virq, (unsigned int) hw);
+	}
+
+	set_irq_flags(virq, IRQF_VALID);
+
+	return 0;
+}
+
+static struct irq_domain_ops moxart_irq_ops = {
+	.map = moxart_irq_map,
+	.xlate = irq_domain_xlate_twocell,
+};
+
+static int __init moxart_of_init(struct device_node *node,
+				struct device_node *parent)
+{
+	interrupt_mask = be32_to_cpup(of_get_property(node,
+		"interrupt-mask", NULL));
+	pr_debug("%s: interrupt-mask=%x\n", node->full_name, interrupt_mask);
+
+	moxart_irq_base = of_iomap(node, 0);
+	if (!moxart_irq_base)
+		panic("%s: unable to map IC registers\n", node->full_name);
+
+	moxart_irq_domain = irq_domain_add_linear(node,
+		32, &moxart_irq_ops, NULL);
+
+	if (!moxart_irq_domain)
+		panic("%s: unable to create IRQ domain\n", node->full_name);
+
+	writel(0, IRQ_MASK(moxart_irq_base));
+	writel(0xffffffff, IRQ_CLEAR(moxart_irq_base));
+
+	writel(interrupt_mask, IRQ_TMODE(moxart_irq_base));
+	writel(interrupt_mask, IRQ_TLEVEL(moxart_irq_base));
+
+	set_handle_irq(moxart_handle_irq);
+
+	pr_info("%s: %s finished\n", node->full_name, __func__);
+
+	return 0;
+}
+IRQCHIP_DECLARE(moxa_moxart_ic, "moxa,moxart-interrupt-controller",
+	moxart_of_init);
+
+asmlinkage void __exception_irq_entry moxart_handle_irq(struct pt_regs *regs)
+{
+	u32 irqstat;
+	int hwirq;
+
+	irqstat = readl(moxart_irq_base + IRQ_STATUS_REG);
+
+	while (irqstat) {
+		hwirq = ffs(irqstat) - 1;
+		handle_IRQ(irq_find_mapping(moxart_irq_domain, hwirq), regs);
+		irqstat &= ~(1 << hwirq);
+	}
+}
+
+
-- 
1.7.2.5

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

* [PATCH] ARM: irqchip: add support for MOXA ART SoCs
@ 2013-06-18  9:59 ` Jonas Jensen
  0 siblings, 0 replies; 23+ messages in thread
From: Jonas Jensen @ 2013-06-18  9:59 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: linux-kernel, arm, tglx, Jonas Jensen

This patch adds an irqchip driver for the main interrupt controller found
on MOXA ART SoCs.

Applies to 3.10-rc1 and arm-soc/for-next (2013-06-15)

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---
 drivers/irqchip/Makefile     |    1 +
 drivers/irqchip/irq-moxart.c |  163 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 164 insertions(+), 0 deletions(-)
 create mode 100644 drivers/irqchip/irq-moxart.c

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index cda4cb5..956d129 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_RENESAS_INTC_IRQPIN)	+= irq-renesas-intc-irqpin.o
 obj-$(CONFIG_RENESAS_IRQC)		+= irq-renesas-irqc.o
 obj-$(CONFIG_VERSATILE_FPGA_IRQ)	+= irq-versatile-fpga.o
 obj-$(CONFIG_ARCH_VT8500)		+= irq-vt8500.o
+obj-$(CONFIG_ARCH_MOXART)		+= irq-moxart.o
diff --git a/drivers/irqchip/irq-moxart.c b/drivers/irqchip/irq-moxart.c
new file mode 100644
index 0000000..8606089
--- /dev/null
+++ b/drivers/irqchip/irq-moxart.c
@@ -0,0 +1,163 @@
+/*
+ * MOXA ART SoCs IRQ chip driver.
+ *
+ * Copyright (C) 2013 Jonas Jensen
+ *
+ * Jonas Jensen <jonas.jensen@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+
+#include <asm/exception.h>
+
+#include "irqchip.h"
+
+#define IRQ_SOURCE_REG      0
+#define IRQ_MASK_REG        0x04
+#define IRQ_CLEAR_REG       0x08
+#define IRQ_MODE_REG        0x0c
+#define IRQ_LEVEL_REG       0x10
+#define IRQ_STATUS_REG      0x14
+
+#define FIQ_SOURCE_REG      0x20
+#define FIQ_MASK_REG        0x24
+#define FIQ_CLEAR_REG       0x28
+#define FIQ_MODE_REG        0x2c
+#define FIQ_LEVEL_REG       0x30
+#define FIQ_STATUS_REG      0x34
+
+#define IRQ_SOURCE(base_addr)   (base_addr + 0x00)
+#define IRQ_MASK(base_addr)     (base_addr + 0x04)
+#define IRQ_CLEAR(base_addr)    (base_addr + 0x08)
+#define IRQ_TMODE(base_addr)    (base_addr + 0x0C)
+#define IRQ_TLEVEL(base_addr)   (base_addr + 0x10)
+#define IRQ_STATUS(base_addr)   (base_addr + 0x14)
+#define FIQ_SOURCE(base_addr)   (base_addr + 0x20)
+#define FIQ_MASK(base_addr)     (base_addr + 0x24)
+#define FIQ_CLEAR(base_addr)    (base_addr + 0x28)
+#define FIQ_TMODE(base_addr)    (base_addr + 0x2C)
+#define FIQ_TLEVEL(base_addr)   (base_addr + 0x30)
+#define FIQ_STATUS(base_addr)   (base_addr + 0x34)
+
+static void __iomem *moxart_irq_base;
+static struct irq_domain *moxart_irq_domain;
+static unsigned int interrupt_mask;
+
+asmlinkage void __exception_irq_entry moxart_handle_irq(struct pt_regs *regs);
+
+void moxart_irq_ack(struct irq_data *irqd)
+{
+	unsigned int irq = irqd_to_hwirq(irqd);
+
+	writel(1 << irq, IRQ_CLEAR(moxart_irq_base));
+}
+
+static void moxart_irq_mask(struct irq_data *irqd)
+{
+	unsigned int irq = irqd_to_hwirq(irqd);
+	unsigned int mask;
+
+	mask = readl(IRQ_MASK(moxart_irq_base));
+	mask &= ~(1 << irq);
+	writel(mask, IRQ_MASK(moxart_irq_base));
+}
+
+static void moxart_irq_unmask(struct irq_data *irqd)
+{
+	unsigned int irq = irqd_to_hwirq(irqd);
+	unsigned int mask;
+
+	mask = readl(IRQ_MASK(moxart_irq_base));
+	mask |= (1 << irq);
+	writel(mask, IRQ_MASK(moxart_irq_base));
+}
+
+static struct irq_chip moxart_irq_chip = {
+	.name		= "moxart_irq",
+	.irq_ack	= moxart_irq_ack,
+	.irq_mask	= moxart_irq_mask,
+	.irq_unmask	= moxart_irq_unmask,
+	.irq_set_wake = NULL,
+};
+
+static int moxart_irq_map(struct irq_domain *d, unsigned int virq,
+			 irq_hw_number_t hw)
+{
+	if ((1 << hw) && interrupt_mask) {
+		irq_set_chip_and_handler(virq, &moxart_irq_chip,
+			handle_edge_irq);
+		pr_info("%s: irq_set_chip_and_handler edge virq=%d hw=%d\n",
+			__func__, virq, (unsigned int) hw);
+	} else {
+		irq_set_chip_and_handler(virq, &moxart_irq_chip,
+			handle_level_irq);
+		pr_info("%s: irq_set_chip_and_handler level virq=%d hw=%d\n",
+			__func__, virq, (unsigned int) hw);
+	}
+
+	set_irq_flags(virq, IRQF_VALID);
+
+	return 0;
+}
+
+static struct irq_domain_ops moxart_irq_ops = {
+	.map = moxart_irq_map,
+	.xlate = irq_domain_xlate_twocell,
+};
+
+static int __init moxart_of_init(struct device_node *node,
+				struct device_node *parent)
+{
+	interrupt_mask = be32_to_cpup(of_get_property(node,
+		"interrupt-mask", NULL));
+	pr_debug("%s: interrupt-mask=%x\n", node->full_name, interrupt_mask);
+
+	moxart_irq_base = of_iomap(node, 0);
+	if (!moxart_irq_base)
+		panic("%s: unable to map IC registers\n", node->full_name);
+
+	moxart_irq_domain = irq_domain_add_linear(node,
+		32, &moxart_irq_ops, NULL);
+
+	if (!moxart_irq_domain)
+		panic("%s: unable to create IRQ domain\n", node->full_name);
+
+	writel(0, IRQ_MASK(moxart_irq_base));
+	writel(0xffffffff, IRQ_CLEAR(moxart_irq_base));
+
+	writel(interrupt_mask, IRQ_TMODE(moxart_irq_base));
+	writel(interrupt_mask, IRQ_TLEVEL(moxart_irq_base));
+
+	set_handle_irq(moxart_handle_irq);
+
+	pr_info("%s: %s finished\n", node->full_name, __func__);
+
+	return 0;
+}
+IRQCHIP_DECLARE(moxa_moxart_ic, "moxa,moxart-interrupt-controller",
+	moxart_of_init);
+
+asmlinkage void __exception_irq_entry moxart_handle_irq(struct pt_regs *regs)
+{
+	u32 irqstat;
+	int hwirq;
+
+	irqstat = readl(moxart_irq_base + IRQ_STATUS_REG);
+
+	while (irqstat) {
+		hwirq = ffs(irqstat) - 1;
+		handle_IRQ(irq_find_mapping(moxart_irq_domain, hwirq), regs);
+		irqstat &= ~(1 << hwirq);
+	}
+}
+
+
-- 
1.7.2.5


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

* [PATCH] ARM: irqchip: add support for MOXA ART SoCs
  2013-06-18  9:59 ` Jonas Jensen
@ 2013-06-18 10:35   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 23+ messages in thread
From: Russell King - ARM Linux @ 2013-06-18 10:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 18, 2013 at 11:59:44AM +0200, Jonas Jensen wrote:
> +void moxart_irq_ack(struct irq_data *irqd)
> +{
> +	unsigned int irq = irqd_to_hwirq(irqd);
> +
> +	writel(1 << irq, IRQ_CLEAR(moxart_irq_base));
> +}
> +
> +static void moxart_irq_mask(struct irq_data *irqd)
> +{
> +	unsigned int irq = irqd_to_hwirq(irqd);
> +	unsigned int mask;
> +
> +	mask = readl(IRQ_MASK(moxart_irq_base));
> +	mask &= ~(1 << irq);
> +	writel(mask, IRQ_MASK(moxart_irq_base));
> +}
> +
> +static void moxart_irq_unmask(struct irq_data *irqd)
> +{
> +	unsigned int irq = irqd_to_hwirq(irqd);
> +	unsigned int mask;
> +
> +	mask = readl(IRQ_MASK(moxart_irq_base));
> +	mask |= (1 << irq);
> +	writel(mask, IRQ_MASK(moxart_irq_base));
> +}

Is there a reason this isn't using the irq_chip_generic stuff which would
eliminate all the above?

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

* Re: [PATCH] ARM: irqchip: add support for MOXA ART SoCs
@ 2013-06-18 10:35   ` Russell King - ARM Linux
  0 siblings, 0 replies; 23+ messages in thread
From: Russell King - ARM Linux @ 2013-06-18 10:35 UTC (permalink / raw)
  To: Jonas Jensen; +Cc: linux-arm-kernel, linux-kernel, arm, tglx

On Tue, Jun 18, 2013 at 11:59:44AM +0200, Jonas Jensen wrote:
> +void moxart_irq_ack(struct irq_data *irqd)
> +{
> +	unsigned int irq = irqd_to_hwirq(irqd);
> +
> +	writel(1 << irq, IRQ_CLEAR(moxart_irq_base));
> +}
> +
> +static void moxart_irq_mask(struct irq_data *irqd)
> +{
> +	unsigned int irq = irqd_to_hwirq(irqd);
> +	unsigned int mask;
> +
> +	mask = readl(IRQ_MASK(moxart_irq_base));
> +	mask &= ~(1 << irq);
> +	writel(mask, IRQ_MASK(moxart_irq_base));
> +}
> +
> +static void moxart_irq_unmask(struct irq_data *irqd)
> +{
> +	unsigned int irq = irqd_to_hwirq(irqd);
> +	unsigned int mask;
> +
> +	mask = readl(IRQ_MASK(moxart_irq_base));
> +	mask |= (1 << irq);
> +	writel(mask, IRQ_MASK(moxart_irq_base));
> +}

Is there a reason this isn't using the irq_chip_generic stuff which would
eliminate all the above?

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

* [PATCH] ARM: irqchip: add support for MOXA ART SoCs
  2013-06-18 10:35   ` Russell King - ARM Linux
@ 2013-06-18 12:54     ` Arnd Bergmann
  -1 siblings, 0 replies; 23+ messages in thread
From: Arnd Bergmann @ 2013-06-18 12:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 18 June 2013, Russell King - ARM Linux wrote:
> Is there a reason this isn't using the irq_chip_generic stuff which would
> eliminate all the above?

When I first reviewed the moxart code, the generic irqchip wasn't compatible
with the linear irq domain. However this has changed now and it should indeed
use that.

	Arnd

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

* Re: [PATCH] ARM: irqchip: add support for MOXA ART SoCs
@ 2013-06-18 12:54     ` Arnd Bergmann
  0 siblings, 0 replies; 23+ messages in thread
From: Arnd Bergmann @ 2013-06-18 12:54 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Jonas Jensen, linux-arm-kernel, linux-kernel, arm, tglx

On Tuesday 18 June 2013, Russell King - ARM Linux wrote:
> Is there a reason this isn't using the irq_chip_generic stuff which would
> eliminate all the above?

When I first reviewed the moxart code, the generic irqchip wasn't compatible
with the linear irq domain. However this has changed now and it should indeed
use that.

	Arnd

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

* [PATCH] ARM: irqchip: add support for MOXA ART SoCs
  2013-06-18  9:59 ` Jonas Jensen
@ 2013-06-18 13:41   ` Thomas Petazzoni
  -1 siblings, 0 replies; 23+ messages in thread
From: Thomas Petazzoni @ 2013-06-18 13:41 UTC (permalink / raw)
  To: linux-arm-kernel

Dear Jonas Jensen,

On Tue, 18 Jun 2013 11:59:44 +0200, Jonas Jensen wrote:

> +asmlinkage void __exception_irq_entry moxart_handle_irq(struct pt_regs *regs);

This forward declaration could be removed if moxart_handle_irq() was
implemented before the initialization function of your driver.

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH] ARM: irqchip: add support for MOXA ART SoCs
@ 2013-06-18 13:41   ` Thomas Petazzoni
  0 siblings, 0 replies; 23+ messages in thread
From: Thomas Petazzoni @ 2013-06-18 13:41 UTC (permalink / raw)
  To: Jonas Jensen; +Cc: linux-arm-kernel, tglx, arm, linux-kernel

Dear Jonas Jensen,

On Tue, 18 Jun 2013 11:59:44 +0200, Jonas Jensen wrote:

> +asmlinkage void __exception_irq_entry moxart_handle_irq(struct pt_regs *regs);

This forward declaration could be removed if moxart_handle_irq() was
implemented before the initialization function of your driver.

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH v2] irqchip: add support for MOXA ART SoCs
  2013-06-18 13:41   ` Thomas Petazzoni
@ 2013-06-20  8:58     ` Jonas Jensen
  -1 siblings, 0 replies; 23+ messages in thread
From: Jonas Jensen @ 2013-06-20  8:58 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds an irqchip driver for the main interrupt controller found
on MOXA ART SoCs.

v2:
* use irq_chip_generic
* remove macro duplicates

Applies to next-20130619

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---
 drivers/irqchip/Makefile     |    1 +
 drivers/irqchip/irq-moxart.c |  109 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 110 insertions(+), 0 deletions(-)
 create mode 100644 drivers/irqchip/irq-moxart.c

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index cda4cb5..956d129 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_RENESAS_INTC_IRQPIN)	+= irq-renesas-intc-irqpin.o
 obj-$(CONFIG_RENESAS_IRQC)		+= irq-renesas-irqc.o
 obj-$(CONFIG_VERSATILE_FPGA_IRQ)	+= irq-versatile-fpga.o
 obj-$(CONFIG_ARCH_VT8500)		+= irq-vt8500.o
+obj-$(CONFIG_ARCH_MOXART)		+= irq-moxart.o
diff --git a/drivers/irqchip/irq-moxart.c b/drivers/irqchip/irq-moxart.c
new file mode 100644
index 0000000..25c0ff7
--- /dev/null
+++ b/drivers/irqchip/irq-moxart.c
@@ -0,0 +1,109 @@
+/*
+ * MOXA ART SoCs IRQ chip driver.
+ *
+ * Copyright (C) 2013 Jonas Jensen
+ *
+ * Jonas Jensen <jonas.jensen@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+
+#include <asm/exception.h>
+
+#include "irqchip.h"
+
+#define IRQ_SOURCE_REG      0
+#define IRQ_MASK_REG        0x04
+#define IRQ_CLEAR_REG       0x08
+#define IRQ_MODE_REG        0x0c
+#define IRQ_LEVEL_REG       0x10
+#define IRQ_STATUS_REG      0x14
+
+#define FIQ_SOURCE_REG      0x20
+#define FIQ_MASK_REG        0x24
+#define FIQ_CLEAR_REG       0x28
+#define FIQ_MODE_REG        0x2c
+#define FIQ_LEVEL_REG       0x30
+#define FIQ_STATUS_REG      0x34
+
+static void __iomem *moxart_irq_base;
+static struct irq_domain *moxart_irq_domain;
+static unsigned int interrupt_mask;
+
+asmlinkage void __exception_irq_entry moxart_handle_irq(struct pt_regs *regs)
+{
+	u32 irqstat;
+	int hwirq;
+
+	irqstat = readl(moxart_irq_base + IRQ_STATUS_REG);
+
+	while (irqstat) {
+		hwirq = ffs(irqstat) - 1;
+		handle_IRQ(irq_find_mapping(moxart_irq_domain, hwirq), regs);
+		irqstat &= ~(1 << hwirq);
+	}
+}
+
+static __init void moxart_alloc_gc(void __iomem *base,
+	unsigned int irq_start, unsigned int num)
+{
+	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+	int ret;
+	struct irq_chip_generic *gc;
+
+	ret = irq_alloc_domain_generic_chips(moxart_irq_domain, 32, 1,
+		"MOXARTINTC", handle_edge_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE);
+
+	if (ret)
+		pr_err("%s: could not alloc generic chip\n", __func__);
+
+	gc = irq_get_domain_generic_chip(moxart_irq_domain, 0);
+
+	gc->reg_base = base;
+	gc->chip_types[0].regs.mask = IRQ_MASK_REG;
+	gc->chip_types[0].regs.ack = IRQ_CLEAR_REG;
+	gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
+	gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
+	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
+}
+
+static int __init moxart_of_init(struct device_node *node,
+	struct device_node *parent)
+{
+	interrupt_mask = be32_to_cpup(of_get_property(node,
+		"interrupt-mask", NULL));
+	pr_debug("%s: interrupt-mask=%x\n", node->full_name, interrupt_mask);
+
+	moxart_irq_base = of_iomap(node, 0);
+	if (!moxart_irq_base)
+		panic("%s: unable to map INTC CPU registers\n",
+			node->full_name);
+
+	moxart_irq_domain = irq_domain_add_linear(node,
+		32, &irq_generic_chip_ops, moxart_irq_base);
+
+	moxart_alloc_gc(moxart_irq_base, 0, 32);
+
+	writel(0, moxart_irq_base + IRQ_MASK_REG);
+	writel(0xffffffff, moxart_irq_base + IRQ_CLEAR_REG);
+
+	writel(interrupt_mask, moxart_irq_base + IRQ_MODE_REG);
+	writel(interrupt_mask, moxart_irq_base + IRQ_LEVEL_REG);
+
+	set_handle_irq(moxart_handle_irq);
+
+	pr_info("%s: %s finished\n", node->full_name, __func__);
+
+	return 0;
+}
+IRQCHIP_DECLARE(moxa_moxart_ic, "moxa,moxart-interrupt-controller",
+	moxart_of_init);
-- 
1.7.2.5

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

* [PATCH v2] irqchip: add support for MOXA ART SoCs
@ 2013-06-20  8:58     ` Jonas Jensen
  0 siblings, 0 replies; 23+ messages in thread
From: Jonas Jensen @ 2013-06-20  8:58 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: arm, linux-kernel, tglx, thomas.petazzoni, arnd, Jonas Jensen

This patch adds an irqchip driver for the main interrupt controller found
on MOXA ART SoCs.

v2:
* use irq_chip_generic
* remove macro duplicates

Applies to next-20130619

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---
 drivers/irqchip/Makefile     |    1 +
 drivers/irqchip/irq-moxart.c |  109 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 110 insertions(+), 0 deletions(-)
 create mode 100644 drivers/irqchip/irq-moxart.c

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index cda4cb5..956d129 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_RENESAS_INTC_IRQPIN)	+= irq-renesas-intc-irqpin.o
 obj-$(CONFIG_RENESAS_IRQC)		+= irq-renesas-irqc.o
 obj-$(CONFIG_VERSATILE_FPGA_IRQ)	+= irq-versatile-fpga.o
 obj-$(CONFIG_ARCH_VT8500)		+= irq-vt8500.o
+obj-$(CONFIG_ARCH_MOXART)		+= irq-moxart.o
diff --git a/drivers/irqchip/irq-moxart.c b/drivers/irqchip/irq-moxart.c
new file mode 100644
index 0000000..25c0ff7
--- /dev/null
+++ b/drivers/irqchip/irq-moxart.c
@@ -0,0 +1,109 @@
+/*
+ * MOXA ART SoCs IRQ chip driver.
+ *
+ * Copyright (C) 2013 Jonas Jensen
+ *
+ * Jonas Jensen <jonas.jensen@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+
+#include <asm/exception.h>
+
+#include "irqchip.h"
+
+#define IRQ_SOURCE_REG      0
+#define IRQ_MASK_REG        0x04
+#define IRQ_CLEAR_REG       0x08
+#define IRQ_MODE_REG        0x0c
+#define IRQ_LEVEL_REG       0x10
+#define IRQ_STATUS_REG      0x14
+
+#define FIQ_SOURCE_REG      0x20
+#define FIQ_MASK_REG        0x24
+#define FIQ_CLEAR_REG       0x28
+#define FIQ_MODE_REG        0x2c
+#define FIQ_LEVEL_REG       0x30
+#define FIQ_STATUS_REG      0x34
+
+static void __iomem *moxart_irq_base;
+static struct irq_domain *moxart_irq_domain;
+static unsigned int interrupt_mask;
+
+asmlinkage void __exception_irq_entry moxart_handle_irq(struct pt_regs *regs)
+{
+	u32 irqstat;
+	int hwirq;
+
+	irqstat = readl(moxart_irq_base + IRQ_STATUS_REG);
+
+	while (irqstat) {
+		hwirq = ffs(irqstat) - 1;
+		handle_IRQ(irq_find_mapping(moxart_irq_domain, hwirq), regs);
+		irqstat &= ~(1 << hwirq);
+	}
+}
+
+static __init void moxart_alloc_gc(void __iomem *base,
+	unsigned int irq_start, unsigned int num)
+{
+	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+	int ret;
+	struct irq_chip_generic *gc;
+
+	ret = irq_alloc_domain_generic_chips(moxart_irq_domain, 32, 1,
+		"MOXARTINTC", handle_edge_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE);
+
+	if (ret)
+		pr_err("%s: could not alloc generic chip\n", __func__);
+
+	gc = irq_get_domain_generic_chip(moxart_irq_domain, 0);
+
+	gc->reg_base = base;
+	gc->chip_types[0].regs.mask = IRQ_MASK_REG;
+	gc->chip_types[0].regs.ack = IRQ_CLEAR_REG;
+	gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
+	gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
+	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
+}
+
+static int __init moxart_of_init(struct device_node *node,
+	struct device_node *parent)
+{
+	interrupt_mask = be32_to_cpup(of_get_property(node,
+		"interrupt-mask", NULL));
+	pr_debug("%s: interrupt-mask=%x\n", node->full_name, interrupt_mask);
+
+	moxart_irq_base = of_iomap(node, 0);
+	if (!moxart_irq_base)
+		panic("%s: unable to map INTC CPU registers\n",
+			node->full_name);
+
+	moxart_irq_domain = irq_domain_add_linear(node,
+		32, &irq_generic_chip_ops, moxart_irq_base);
+
+	moxart_alloc_gc(moxart_irq_base, 0, 32);
+
+	writel(0, moxart_irq_base + IRQ_MASK_REG);
+	writel(0xffffffff, moxart_irq_base + IRQ_CLEAR_REG);
+
+	writel(interrupt_mask, moxart_irq_base + IRQ_MODE_REG);
+	writel(interrupt_mask, moxart_irq_base + IRQ_LEVEL_REG);
+
+	set_handle_irq(moxart_handle_irq);
+
+	pr_info("%s: %s finished\n", node->full_name, __func__);
+
+	return 0;
+}
+IRQCHIP_DECLARE(moxa_moxart_ic, "moxa,moxart-interrupt-controller",
+	moxart_of_init);
-- 
1.7.2.5


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

* [PATCH v2] irqchip: add support for MOXA ART SoCs
  2013-06-20  8:58     ` Jonas Jensen
@ 2013-06-20 10:17       ` Arnd Bergmann
  -1 siblings, 0 replies; 23+ messages in thread
From: Arnd Bergmann @ 2013-06-20 10:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 20 June 2013, Jonas Jensen wrote:
> This patch adds an irqchip driver for the main interrupt controller found
> on MOXA ART SoCs.
> 
> v2:
> * use irq_chip_generic
> * remove macro duplicates
> 
> Applies to next-20130619
> 
> Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>

Acked-by: Arnd Bergmann <arnd@arndb.de>

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

* Re: [PATCH v2] irqchip: add support for MOXA ART SoCs
@ 2013-06-20 10:17       ` Arnd Bergmann
  0 siblings, 0 replies; 23+ messages in thread
From: Arnd Bergmann @ 2013-06-20 10:17 UTC (permalink / raw)
  To: Jonas Jensen; +Cc: linux-arm-kernel, arm, linux-kernel, tglx, thomas.petazzoni

On Thursday 20 June 2013, Jonas Jensen wrote:
> This patch adds an irqchip driver for the main interrupt controller found
> on MOXA ART SoCs.
> 
> v2:
> * use irq_chip_generic
> * remove macro duplicates
> 
> Applies to next-20130619
> 
> Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>

Acked-by: Arnd Bergmann <arnd@arndb.de>

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

* [PATCH v2] irqchip: add support for MOXA ART SoCs
  2013-06-20  8:58     ` Jonas Jensen
@ 2013-06-24 13:18       ` Grant Likely
  -1 siblings, 0 replies; 23+ messages in thread
From: Grant Likely @ 2013-06-24 13:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 20 Jun 2013 10:58:52 +0200, Jonas Jensen <jonas.jensen@gmail.com> wrote:
> This patch adds an irqchip driver for the main interrupt controller found
> on MOXA ART SoCs.
> 
> v2:
> * use irq_chip_generic
> * remove macro duplicates
> 
> Applies to next-20130619
> 
> Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
> ---
>  drivers/irqchip/Makefile     |    1 +
>  drivers/irqchip/irq-moxart.c |  109 ++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 110 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/irqchip/irq-moxart.c
> 
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index cda4cb5..956d129 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -16,3 +16,4 @@ obj-$(CONFIG_RENESAS_INTC_IRQPIN)	+= irq-renesas-intc-irqpin.o
>  obj-$(CONFIG_RENESAS_IRQC)		+= irq-renesas-irqc.o
>  obj-$(CONFIG_VERSATILE_FPGA_IRQ)	+= irq-versatile-fpga.o
>  obj-$(CONFIG_ARCH_VT8500)		+= irq-vt8500.o
> +obj-$(CONFIG_ARCH_MOXART)		+= irq-moxart.o
> diff --git a/drivers/irqchip/irq-moxart.c b/drivers/irqchip/irq-moxart.c
> new file mode 100644
> index 0000000..25c0ff7
> --- /dev/null
> +++ b/drivers/irqchip/irq-moxart.c
> @@ -0,0 +1,109 @@
> +/*
> + * MOXA ART SoCs IRQ chip driver.
> + *
> + * Copyright (C) 2013 Jonas Jensen
> + *
> + * Jonas Jensen <jonas.jensen@gmail.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/irqdomain.h>
> +
> +#include <asm/exception.h>
> +
> +#include "irqchip.h"
> +
> +#define IRQ_SOURCE_REG      0
> +#define IRQ_MASK_REG        0x04
> +#define IRQ_CLEAR_REG       0x08
> +#define IRQ_MODE_REG        0x0c
> +#define IRQ_LEVEL_REG       0x10
> +#define IRQ_STATUS_REG      0x14
> +
> +#define FIQ_SOURCE_REG      0x20
> +#define FIQ_MASK_REG        0x24
> +#define FIQ_CLEAR_REG       0x28
> +#define FIQ_MODE_REG        0x2c
> +#define FIQ_LEVEL_REG       0x30
> +#define FIQ_STATUS_REG      0x34
> +
> +static void __iomem *moxart_irq_base;
> +static struct irq_domain *moxart_irq_domain;
> +static unsigned int interrupt_mask;
> +
> +asmlinkage void __exception_irq_entry moxart_handle_irq(struct pt_regs *regs)
> +{
> +	u32 irqstat;
> +	int hwirq;
> +
> +	irqstat = readl(moxart_irq_base + IRQ_STATUS_REG);
> +
> +	while (irqstat) {
> +		hwirq = ffs(irqstat) - 1;
> +		handle_IRQ(irq_find_mapping(moxart_irq_domain, hwirq), regs);
> +		irqstat &= ~(1 << hwirq);
> +	}
> +}
> +
> +static __init void moxart_alloc_gc(void __iomem *base,
> +	unsigned int irq_start, unsigned int num)
> +{
> +	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
> +	int ret;
> +	struct irq_chip_generic *gc;
> +
> +	ret = irq_alloc_domain_generic_chips(moxart_irq_domain, 32, 1,
> +		"MOXARTINTC", handle_edge_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE);
> +
> +	if (ret)
> +		pr_err("%s: could not alloc generic chip\n", __func__);

If this failure point is hit, the code following it will segfault. Need
to bail at this point.

> +
> +	gc = irq_get_domain_generic_chip(moxart_irq_domain, 0);
> +
> +	gc->reg_base = base;
> +	gc->chip_types[0].regs.mask = IRQ_MASK_REG;
> +	gc->chip_types[0].regs.ack = IRQ_CLEAR_REG;
> +	gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
> +	gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
> +	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
> +}

Why is this split into a separate function? There really isn't any need
to.

> +
> +static int __init moxart_of_init(struct device_node *node,
> +	struct device_node *parent)
> +{
> +	interrupt_mask = be32_to_cpup(of_get_property(node,
> +		"interrupt-mask", NULL));
> +	pr_debug("%s: interrupt-mask=%x\n", node->full_name, interrupt_mask);
> +
> +	moxart_irq_base = of_iomap(node, 0);
> +	if (!moxart_irq_base)
> +		panic("%s: unable to map INTC CPU registers\n",
> +			node->full_name);

Is in necessary to panic here? Often even if the interrupt controller
setup fails, it is valueable to print an error, exit gracefully and let
the kernel try to continue. There is a greater chance of getting some
form output useful for debug that way.

> +
> +	moxart_irq_domain = irq_domain_add_linear(node,
> +		32, &irq_generic_chip_ops, moxart_irq_base);
> +
> +	moxart_alloc_gc(moxart_irq_base, 0, 32);
> +
> +	writel(0, moxart_irq_base + IRQ_MASK_REG);
> +	writel(0xffffffff, moxart_irq_base + IRQ_CLEAR_REG);
> +
> +	writel(interrupt_mask, moxart_irq_base + IRQ_MODE_REG);
> +	writel(interrupt_mask, moxart_irq_base + IRQ_LEVEL_REG);
> +
> +	set_handle_irq(moxart_handle_irq);
> +
> +	pr_info("%s: %s finished\n", node->full_name, __func__);
> +
> +	return 0;
> +}
> +IRQCHIP_DECLARE(moxa_moxart_ic, "moxa,moxart-interrupt-controller",
> +	moxart_of_init);
> -- 
> 1.7.2.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

-- 
email sent from notmuch.vim plugin

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

* Re: [PATCH v2] irqchip: add support for MOXA ART SoCs
@ 2013-06-24 13:18       ` Grant Likely
  0 siblings, 0 replies; 23+ messages in thread
From: Grant Likely @ 2013-06-24 13:18 UTC (permalink / raw)
  To: Jonas Jensen, linux-arm-kernel
  Cc: arm, linux-kernel, tglx, thomas.petazzoni, arnd, Jonas Jensen

On Thu, 20 Jun 2013 10:58:52 +0200, Jonas Jensen <jonas.jensen@gmail.com> wrote:
> This patch adds an irqchip driver for the main interrupt controller found
> on MOXA ART SoCs.
> 
> v2:
> * use irq_chip_generic
> * remove macro duplicates
> 
> Applies to next-20130619
> 
> Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
> ---
>  drivers/irqchip/Makefile     |    1 +
>  drivers/irqchip/irq-moxart.c |  109 ++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 110 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/irqchip/irq-moxart.c
> 
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index cda4cb5..956d129 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -16,3 +16,4 @@ obj-$(CONFIG_RENESAS_INTC_IRQPIN)	+= irq-renesas-intc-irqpin.o
>  obj-$(CONFIG_RENESAS_IRQC)		+= irq-renesas-irqc.o
>  obj-$(CONFIG_VERSATILE_FPGA_IRQ)	+= irq-versatile-fpga.o
>  obj-$(CONFIG_ARCH_VT8500)		+= irq-vt8500.o
> +obj-$(CONFIG_ARCH_MOXART)		+= irq-moxart.o
> diff --git a/drivers/irqchip/irq-moxart.c b/drivers/irqchip/irq-moxart.c
> new file mode 100644
> index 0000000..25c0ff7
> --- /dev/null
> +++ b/drivers/irqchip/irq-moxart.c
> @@ -0,0 +1,109 @@
> +/*
> + * MOXA ART SoCs IRQ chip driver.
> + *
> + * Copyright (C) 2013 Jonas Jensen
> + *
> + * Jonas Jensen <jonas.jensen@gmail.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/irqdomain.h>
> +
> +#include <asm/exception.h>
> +
> +#include "irqchip.h"
> +
> +#define IRQ_SOURCE_REG      0
> +#define IRQ_MASK_REG        0x04
> +#define IRQ_CLEAR_REG       0x08
> +#define IRQ_MODE_REG        0x0c
> +#define IRQ_LEVEL_REG       0x10
> +#define IRQ_STATUS_REG      0x14
> +
> +#define FIQ_SOURCE_REG      0x20
> +#define FIQ_MASK_REG        0x24
> +#define FIQ_CLEAR_REG       0x28
> +#define FIQ_MODE_REG        0x2c
> +#define FIQ_LEVEL_REG       0x30
> +#define FIQ_STATUS_REG      0x34
> +
> +static void __iomem *moxart_irq_base;
> +static struct irq_domain *moxart_irq_domain;
> +static unsigned int interrupt_mask;
> +
> +asmlinkage void __exception_irq_entry moxart_handle_irq(struct pt_regs *regs)
> +{
> +	u32 irqstat;
> +	int hwirq;
> +
> +	irqstat = readl(moxart_irq_base + IRQ_STATUS_REG);
> +
> +	while (irqstat) {
> +		hwirq = ffs(irqstat) - 1;
> +		handle_IRQ(irq_find_mapping(moxart_irq_domain, hwirq), regs);
> +		irqstat &= ~(1 << hwirq);
> +	}
> +}
> +
> +static __init void moxart_alloc_gc(void __iomem *base,
> +	unsigned int irq_start, unsigned int num)
> +{
> +	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
> +	int ret;
> +	struct irq_chip_generic *gc;
> +
> +	ret = irq_alloc_domain_generic_chips(moxart_irq_domain, 32, 1,
> +		"MOXARTINTC", handle_edge_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE);
> +
> +	if (ret)
> +		pr_err("%s: could not alloc generic chip\n", __func__);

If this failure point is hit, the code following it will segfault. Need
to bail at this point.

> +
> +	gc = irq_get_domain_generic_chip(moxart_irq_domain, 0);
> +
> +	gc->reg_base = base;
> +	gc->chip_types[0].regs.mask = IRQ_MASK_REG;
> +	gc->chip_types[0].regs.ack = IRQ_CLEAR_REG;
> +	gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
> +	gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
> +	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
> +}

Why is this split into a separate function? There really isn't any need
to.

> +
> +static int __init moxart_of_init(struct device_node *node,
> +	struct device_node *parent)
> +{
> +	interrupt_mask = be32_to_cpup(of_get_property(node,
> +		"interrupt-mask", NULL));
> +	pr_debug("%s: interrupt-mask=%x\n", node->full_name, interrupt_mask);
> +
> +	moxart_irq_base = of_iomap(node, 0);
> +	if (!moxart_irq_base)
> +		panic("%s: unable to map INTC CPU registers\n",
> +			node->full_name);

Is in necessary to panic here? Often even if the interrupt controller
setup fails, it is valueable to print an error, exit gracefully and let
the kernel try to continue. There is a greater chance of getting some
form output useful for debug that way.

> +
> +	moxart_irq_domain = irq_domain_add_linear(node,
> +		32, &irq_generic_chip_ops, moxart_irq_base);
> +
> +	moxart_alloc_gc(moxart_irq_base, 0, 32);
> +
> +	writel(0, moxart_irq_base + IRQ_MASK_REG);
> +	writel(0xffffffff, moxart_irq_base + IRQ_CLEAR_REG);
> +
> +	writel(interrupt_mask, moxart_irq_base + IRQ_MODE_REG);
> +	writel(interrupt_mask, moxart_irq_base + IRQ_LEVEL_REG);
> +
> +	set_handle_irq(moxart_handle_irq);
> +
> +	pr_info("%s: %s finished\n", node->full_name, __func__);
> +
> +	return 0;
> +}
> +IRQCHIP_DECLARE(moxa_moxart_ic, "moxa,moxart-interrupt-controller",
> +	moxart_of_init);
> -- 
> 1.7.2.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

-- 
email sent from notmuch.vim plugin

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

* [PATCH v3] ARM: irqchip: add support for MOXA ART SoCs
  2013-06-20  8:58     ` Jonas Jensen
@ 2013-06-27 13:29       ` Jonas Jensen
  -1 siblings, 0 replies; 23+ messages in thread
From: Jonas Jensen @ 2013-06-27 13:29 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds an irqchip driver for the main interrupt controller found
on MOXA ART SoCs.

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Applies to next-20130619
    
    Changes since v2:
    
    1. bail if irq_alloc_domain_generic_chips fails
    2. remove separate function "moxart_alloc_gc", move all code to main init
    3. if of_iomap fails, instead of panic, print error and return -EINVAL
    4. use of_property_read_u32 instead of be32_to_cpup(of_get_property(..))

 drivers/irqchip/Makefile     |   1 +
 drivers/irqchip/irq-moxart.c | 110 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 111 insertions(+)
 create mode 100644 drivers/irqchip/irq-moxart.c

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index cda4cb5..956d129 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_RENESAS_INTC_IRQPIN)	+= irq-renesas-intc-irqpin.o
 obj-$(CONFIG_RENESAS_IRQC)		+= irq-renesas-irqc.o
 obj-$(CONFIG_VERSATILE_FPGA_IRQ)	+= irq-versatile-fpga.o
 obj-$(CONFIG_ARCH_VT8500)		+= irq-vt8500.o
+obj-$(CONFIG_ARCH_MOXART)		+= irq-moxart.o
diff --git a/drivers/irqchip/irq-moxart.c b/drivers/irqchip/irq-moxart.c
new file mode 100644
index 0000000..0815108
--- /dev/null
+++ b/drivers/irqchip/irq-moxart.c
@@ -0,0 +1,110 @@
+/*
+ * MOXA ART SoCs IRQ chip driver.
+ *
+ * Copyright (C) 2013 Jonas Jensen
+ *
+ * Jonas Jensen <jonas.jensen@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+
+#include <asm/exception.h>
+
+#include "irqchip.h"
+
+#define IRQ_SOURCE_REG		0
+#define IRQ_MASK_REG		0x04
+#define IRQ_CLEAR_REG		0x08
+#define IRQ_MODE_REG		0x0c
+#define IRQ_LEVEL_REG		0x10
+#define IRQ_STATUS_REG		0x14
+
+#define FIQ_SOURCE_REG		0x20
+#define FIQ_MASK_REG		0x24
+#define FIQ_CLEAR_REG		0x28
+#define FIQ_MODE_REG		0x2c
+#define FIQ_LEVEL_REG		0x30
+#define FIQ_STATUS_REG		0x34
+
+static void __iomem *moxart_irq_base;
+static struct irq_domain *moxart_irq_domain;
+static unsigned int interrupt_mask;
+
+asmlinkage void __exception_irq_entry moxart_handle_irq(struct pt_regs *regs)
+{
+	u32 irqstat;
+	int hwirq;
+
+	irqstat = readl(moxart_irq_base + IRQ_STATUS_REG);
+
+	while (irqstat) {
+		hwirq = ffs(irqstat) - 1;
+		handle_IRQ(irq_find_mapping(moxart_irq_domain, hwirq), regs);
+		irqstat &= ~(1 << hwirq);
+	}
+}
+
+static int __init moxart_of_intc_init(struct device_node *node,
+	struct device_node *parent)
+{
+	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+	int ret;
+	struct irq_chip_generic *gc;
+
+	ret = of_property_read_u32(node, "interrupt-mask", &interrupt_mask);
+	if (ret)
+		pr_err("%s: can't read interrupt-mask DT property\n",
+			   node->full_name);
+	pr_debug("%s: interrupt-mask=%x\n", node->full_name, interrupt_mask);
+
+	moxart_irq_base = of_iomap(node, 0);
+	if (!moxart_irq_base) {
+		pr_err("%s: unable to map INTC CPU registers\n",
+			   node->full_name);
+		return -EINVAL;
+	}
+
+	moxart_irq_domain = irq_domain_add_linear(node,	32,
+					&irq_generic_chip_ops, moxart_irq_base);
+
+	ret = irq_alloc_domain_generic_chips(moxart_irq_domain, 32, 1,
+					"MOXARTINTC", handle_edge_irq,
+					clr, 0, IRQ_GC_INIT_MASK_CACHE);
+
+	if (ret) {
+		pr_err("%s: could not allocate generic chip\n", __func__);
+		return -EINVAL;
+	}
+
+	gc = irq_get_domain_generic_chip(moxart_irq_domain, 0);
+
+	gc->reg_base = moxart_irq_base;
+	gc->chip_types[0].regs.mask = IRQ_MASK_REG;
+	gc->chip_types[0].regs.ack = IRQ_CLEAR_REG;
+	gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
+	gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
+	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
+
+	writel(0, moxart_irq_base + IRQ_MASK_REG);
+	writel(0xffffffff, moxart_irq_base + IRQ_CLEAR_REG);
+
+	writel(interrupt_mask, moxart_irq_base + IRQ_MODE_REG);
+	writel(interrupt_mask, moxart_irq_base + IRQ_LEVEL_REG);
+
+	set_handle_irq(moxart_handle_irq);
+
+	pr_info("%s: %s finished\n", node->full_name, __func__);
+
+	return 0;
+}
+IRQCHIP_DECLARE(moxa_moxart_ic, "moxa,moxart-interrupt-controller",
+				moxart_of_intc_init);
-- 
1.8.2.1

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

* [PATCH v3] ARM: irqchip: add support for MOXA ART SoCs
@ 2013-06-27 13:29       ` Jonas Jensen
  0 siblings, 0 replies; 23+ messages in thread
From: Jonas Jensen @ 2013-06-27 13:29 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, arm, tglx, grant.likely, thomas.petazzoni, arnd,
	Jonas Jensen

This patch adds an irqchip driver for the main interrupt controller found
on MOXA ART SoCs.

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Applies to next-20130619
    
    Changes since v2:
    
    1. bail if irq_alloc_domain_generic_chips fails
    2. remove separate function "moxart_alloc_gc", move all code to main init
    3. if of_iomap fails, instead of panic, print error and return -EINVAL
    4. use of_property_read_u32 instead of be32_to_cpup(of_get_property(..))

 drivers/irqchip/Makefile     |   1 +
 drivers/irqchip/irq-moxart.c | 110 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 111 insertions(+)
 create mode 100644 drivers/irqchip/irq-moxart.c

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index cda4cb5..956d129 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_RENESAS_INTC_IRQPIN)	+= irq-renesas-intc-irqpin.o
 obj-$(CONFIG_RENESAS_IRQC)		+= irq-renesas-irqc.o
 obj-$(CONFIG_VERSATILE_FPGA_IRQ)	+= irq-versatile-fpga.o
 obj-$(CONFIG_ARCH_VT8500)		+= irq-vt8500.o
+obj-$(CONFIG_ARCH_MOXART)		+= irq-moxart.o
diff --git a/drivers/irqchip/irq-moxart.c b/drivers/irqchip/irq-moxart.c
new file mode 100644
index 0000000..0815108
--- /dev/null
+++ b/drivers/irqchip/irq-moxart.c
@@ -0,0 +1,110 @@
+/*
+ * MOXA ART SoCs IRQ chip driver.
+ *
+ * Copyright (C) 2013 Jonas Jensen
+ *
+ * Jonas Jensen <jonas.jensen@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+
+#include <asm/exception.h>
+
+#include "irqchip.h"
+
+#define IRQ_SOURCE_REG		0
+#define IRQ_MASK_REG		0x04
+#define IRQ_CLEAR_REG		0x08
+#define IRQ_MODE_REG		0x0c
+#define IRQ_LEVEL_REG		0x10
+#define IRQ_STATUS_REG		0x14
+
+#define FIQ_SOURCE_REG		0x20
+#define FIQ_MASK_REG		0x24
+#define FIQ_CLEAR_REG		0x28
+#define FIQ_MODE_REG		0x2c
+#define FIQ_LEVEL_REG		0x30
+#define FIQ_STATUS_REG		0x34
+
+static void __iomem *moxart_irq_base;
+static struct irq_domain *moxart_irq_domain;
+static unsigned int interrupt_mask;
+
+asmlinkage void __exception_irq_entry moxart_handle_irq(struct pt_regs *regs)
+{
+	u32 irqstat;
+	int hwirq;
+
+	irqstat = readl(moxart_irq_base + IRQ_STATUS_REG);
+
+	while (irqstat) {
+		hwirq = ffs(irqstat) - 1;
+		handle_IRQ(irq_find_mapping(moxart_irq_domain, hwirq), regs);
+		irqstat &= ~(1 << hwirq);
+	}
+}
+
+static int __init moxart_of_intc_init(struct device_node *node,
+	struct device_node *parent)
+{
+	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+	int ret;
+	struct irq_chip_generic *gc;
+
+	ret = of_property_read_u32(node, "interrupt-mask", &interrupt_mask);
+	if (ret)
+		pr_err("%s: can't read interrupt-mask DT property\n",
+			   node->full_name);
+	pr_debug("%s: interrupt-mask=%x\n", node->full_name, interrupt_mask);
+
+	moxart_irq_base = of_iomap(node, 0);
+	if (!moxart_irq_base) {
+		pr_err("%s: unable to map INTC CPU registers\n",
+			   node->full_name);
+		return -EINVAL;
+	}
+
+	moxart_irq_domain = irq_domain_add_linear(node,	32,
+					&irq_generic_chip_ops, moxart_irq_base);
+
+	ret = irq_alloc_domain_generic_chips(moxart_irq_domain, 32, 1,
+					"MOXARTINTC", handle_edge_irq,
+					clr, 0, IRQ_GC_INIT_MASK_CACHE);
+
+	if (ret) {
+		pr_err("%s: could not allocate generic chip\n", __func__);
+		return -EINVAL;
+	}
+
+	gc = irq_get_domain_generic_chip(moxart_irq_domain, 0);
+
+	gc->reg_base = moxart_irq_base;
+	gc->chip_types[0].regs.mask = IRQ_MASK_REG;
+	gc->chip_types[0].regs.ack = IRQ_CLEAR_REG;
+	gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
+	gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
+	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
+
+	writel(0, moxart_irq_base + IRQ_MASK_REG);
+	writel(0xffffffff, moxart_irq_base + IRQ_CLEAR_REG);
+
+	writel(interrupt_mask, moxart_irq_base + IRQ_MODE_REG);
+	writel(interrupt_mask, moxart_irq_base + IRQ_LEVEL_REG);
+
+	set_handle_irq(moxart_handle_irq);
+
+	pr_info("%s: %s finished\n", node->full_name, __func__);
+
+	return 0;
+}
+IRQCHIP_DECLARE(moxa_moxart_ic, "moxa,moxart-interrupt-controller",
+				moxart_of_intc_init);
-- 
1.8.2.1


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

* [PATCH v3] ARM: irqchip: add support for MOXA ART SoCs
  2013-06-27 13:29       ` Jonas Jensen
@ 2013-06-27 17:49         ` Uwe Kleine-König
  -1 siblings, 0 replies; 23+ messages in thread
From: Uwe Kleine-König @ 2013-06-27 17:49 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jonas,

On Thu, Jun 27, 2013 at 03:29:33PM +0200, Jonas Jensen wrote:
> This patch adds an irqchip driver for the main interrupt controller found
> on MOXA ART SoCs.
> 
> Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
> ---
> 
> Notes:
>     Applies to next-20130619
>     
>     Changes since v2:
>     
>     1. bail if irq_alloc_domain_generic_chips fails
>     2. remove separate function "moxart_alloc_gc", move all code to main init
>     3. if of_iomap fails, instead of panic, print error and return -EINVAL
>     4. use of_property_read_u32 instead of be32_to_cpup(of_get_property(..))
> 
>  drivers/irqchip/Makefile     |   1 +
>  drivers/irqchip/irq-moxart.c | 110 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 111 insertions(+)
>  create mode 100644 drivers/irqchip/irq-moxart.c
> 
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index cda4cb5..956d129 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -16,3 +16,4 @@ obj-$(CONFIG_RENESAS_INTC_IRQPIN)	+= irq-renesas-intc-irqpin.o
>  obj-$(CONFIG_RENESAS_IRQC)		+= irq-renesas-irqc.o
>  obj-$(CONFIG_VERSATILE_FPGA_IRQ)	+= irq-versatile-fpga.o
>  obj-$(CONFIG_ARCH_VT8500)		+= irq-vt8500.o
> +obj-$(CONFIG_ARCH_MOXART)		+= irq-moxart.o
> diff --git a/drivers/irqchip/irq-moxart.c b/drivers/irqchip/irq-moxart.c
> new file mode 100644
> index 0000000..0815108
> --- /dev/null
> +++ b/drivers/irqchip/irq-moxart.c
> @@ -0,0 +1,110 @@
> +/*
> + * MOXA ART SoCs IRQ chip driver.
> + *
> + * Copyright (C) 2013 Jonas Jensen
> + *
> + * Jonas Jensen <jonas.jensen@gmail.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/irqdomain.h>
> +
> +#include <asm/exception.h>
> +
> +#include "irqchip.h"
> +
> +#define IRQ_SOURCE_REG		0
> +#define IRQ_MASK_REG		0x04
> +#define IRQ_CLEAR_REG		0x08
> +#define IRQ_MODE_REG		0x0c
> +#define IRQ_LEVEL_REG		0x10
> +#define IRQ_STATUS_REG		0x14
> +
> +#define FIQ_SOURCE_REG		0x20
> +#define FIQ_MASK_REG		0x24
> +#define FIQ_CLEAR_REG		0x28
> +#define FIQ_MODE_REG		0x2c
> +#define FIQ_LEVEL_REG		0x30
> +#define FIQ_STATUS_REG		0x34
> +
> +static void __iomem *moxart_irq_base;
> +static struct irq_domain *moxart_irq_domain;
> +static unsigned int interrupt_mask;
I would pack this into a struct s.t. you have only one global variable
for the chip instance. More or less a matter of taste.

> +
> +asmlinkage void __exception_irq_entry moxart_handle_irq(struct pt_regs *regs)
can this be static?

> +{
> +	u32 irqstat;
> +	int hwirq;
> +
> +	irqstat = readl(moxart_irq_base + IRQ_STATUS_REG);
> +
> +	while (irqstat) {
> +		hwirq = ffs(irqstat) - 1;
> +		handle_IRQ(irq_find_mapping(moxart_irq_domain, hwirq), regs);
Call irq_linear_revmap instead of irq_find_mapping.

> +		irqstat &= ~(1 << hwirq);
> +	}
> +}
> +
> +static int __init moxart_of_intc_init(struct device_node *node,
> +	struct device_node *parent)
wrong indention.

> +{
> +	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
> +	int ret;
> +	struct irq_chip_generic *gc;
> +
> +	ret = of_property_read_u32(node, "interrupt-mask", &interrupt_mask);
> +	if (ret)
> +		pr_err("%s: can't read interrupt-mask DT property\n",
> +			   node->full_name);
ditto

> +	pr_debug("%s: interrupt-mask=%x\n", node->full_name, interrupt_mask);
> +
> +	moxart_irq_base = of_iomap(node, 0);
> +	if (!moxart_irq_base) {
> +		pr_err("%s: unable to map INTC CPU registers\n",
> +			   node->full_name);
> +		return -EINVAL;
> +	}
> +
> +	moxart_irq_domain = irq_domain_add_linear(node,	32,
> +					&irq_generic_chip_ops, moxart_irq_base);
if (!moxart_irq_domain) {
	/* error handling */
}

> +
> +	ret = irq_alloc_domain_generic_chips(moxart_irq_domain, 32, 1,
> +					"MOXARTINTC", handle_edge_irq,
> +					clr, 0, IRQ_GC_INIT_MASK_CACHE);
> +
> +	if (ret) {
> +		pr_err("%s: could not allocate generic chip\n", __func__);
you should free moxart_irq_domain here.

> +		return -EINVAL;
> +	}
> +
> +	gc = irq_get_domain_generic_chip(moxart_irq_domain, 0);
> +
> +	gc->reg_base = moxart_irq_base;
> +	gc->chip_types[0].regs.mask = IRQ_MASK_REG;
> +	gc->chip_types[0].regs.ack = IRQ_CLEAR_REG;
> +	gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
> +	gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
> +	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
> +
> +	writel(0, moxart_irq_base + IRQ_MASK_REG);
> +	writel(0xffffffff, moxart_irq_base + IRQ_CLEAR_REG);
> +
> +	writel(interrupt_mask, moxart_irq_base + IRQ_MODE_REG);
> +	writel(interrupt_mask, moxart_irq_base + IRQ_LEVEL_REG);
> +
> +	set_handle_irq(moxart_handle_irq);
> +
> +	pr_info("%s: %s finished\n", node->full_name, __func__);
"finished" looks like a debug message. IMHO either drop the message or
write something more useful.
> +
> +	return 0;
> +}
> +IRQCHIP_DECLARE(moxa_moxart_ic, "moxa,moxart-interrupt-controller",
> +				moxart_of_intc_init);
> -- 
Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* Re: [PATCH v3] ARM: irqchip: add support for MOXA ART SoCs
@ 2013-06-27 17:49         ` Uwe Kleine-König
  0 siblings, 0 replies; 23+ messages in thread
From: Uwe Kleine-König @ 2013-06-27 17:49 UTC (permalink / raw)
  To: Jonas Jensen
  Cc: linux-arm-kernel, thomas.petazzoni, arnd, linux-kernel,
	grant.likely, arm, tglx

Hi Jonas,

On Thu, Jun 27, 2013 at 03:29:33PM +0200, Jonas Jensen wrote:
> This patch adds an irqchip driver for the main interrupt controller found
> on MOXA ART SoCs.
> 
> Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
> ---
> 
> Notes:
>     Applies to next-20130619
>     
>     Changes since v2:
>     
>     1. bail if irq_alloc_domain_generic_chips fails
>     2. remove separate function "moxart_alloc_gc", move all code to main init
>     3. if of_iomap fails, instead of panic, print error and return -EINVAL
>     4. use of_property_read_u32 instead of be32_to_cpup(of_get_property(..))
> 
>  drivers/irqchip/Makefile     |   1 +
>  drivers/irqchip/irq-moxart.c | 110 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 111 insertions(+)
>  create mode 100644 drivers/irqchip/irq-moxart.c
> 
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index cda4cb5..956d129 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -16,3 +16,4 @@ obj-$(CONFIG_RENESAS_INTC_IRQPIN)	+= irq-renesas-intc-irqpin.o
>  obj-$(CONFIG_RENESAS_IRQC)		+= irq-renesas-irqc.o
>  obj-$(CONFIG_VERSATILE_FPGA_IRQ)	+= irq-versatile-fpga.o
>  obj-$(CONFIG_ARCH_VT8500)		+= irq-vt8500.o
> +obj-$(CONFIG_ARCH_MOXART)		+= irq-moxart.o
> diff --git a/drivers/irqchip/irq-moxart.c b/drivers/irqchip/irq-moxart.c
> new file mode 100644
> index 0000000..0815108
> --- /dev/null
> +++ b/drivers/irqchip/irq-moxart.c
> @@ -0,0 +1,110 @@
> +/*
> + * MOXA ART SoCs IRQ chip driver.
> + *
> + * Copyright (C) 2013 Jonas Jensen
> + *
> + * Jonas Jensen <jonas.jensen@gmail.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/irqdomain.h>
> +
> +#include <asm/exception.h>
> +
> +#include "irqchip.h"
> +
> +#define IRQ_SOURCE_REG		0
> +#define IRQ_MASK_REG		0x04
> +#define IRQ_CLEAR_REG		0x08
> +#define IRQ_MODE_REG		0x0c
> +#define IRQ_LEVEL_REG		0x10
> +#define IRQ_STATUS_REG		0x14
> +
> +#define FIQ_SOURCE_REG		0x20
> +#define FIQ_MASK_REG		0x24
> +#define FIQ_CLEAR_REG		0x28
> +#define FIQ_MODE_REG		0x2c
> +#define FIQ_LEVEL_REG		0x30
> +#define FIQ_STATUS_REG		0x34
> +
> +static void __iomem *moxart_irq_base;
> +static struct irq_domain *moxart_irq_domain;
> +static unsigned int interrupt_mask;
I would pack this into a struct s.t. you have only one global variable
for the chip instance. More or less a matter of taste.

> +
> +asmlinkage void __exception_irq_entry moxart_handle_irq(struct pt_regs *regs)
can this be static?

> +{
> +	u32 irqstat;
> +	int hwirq;
> +
> +	irqstat = readl(moxart_irq_base + IRQ_STATUS_REG);
> +
> +	while (irqstat) {
> +		hwirq = ffs(irqstat) - 1;
> +		handle_IRQ(irq_find_mapping(moxart_irq_domain, hwirq), regs);
Call irq_linear_revmap instead of irq_find_mapping.

> +		irqstat &= ~(1 << hwirq);
> +	}
> +}
> +
> +static int __init moxart_of_intc_init(struct device_node *node,
> +	struct device_node *parent)
wrong indention.

> +{
> +	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
> +	int ret;
> +	struct irq_chip_generic *gc;
> +
> +	ret = of_property_read_u32(node, "interrupt-mask", &interrupt_mask);
> +	if (ret)
> +		pr_err("%s: can't read interrupt-mask DT property\n",
> +			   node->full_name);
ditto

> +	pr_debug("%s: interrupt-mask=%x\n", node->full_name, interrupt_mask);
> +
> +	moxart_irq_base = of_iomap(node, 0);
> +	if (!moxart_irq_base) {
> +		pr_err("%s: unable to map INTC CPU registers\n",
> +			   node->full_name);
> +		return -EINVAL;
> +	}
> +
> +	moxart_irq_domain = irq_domain_add_linear(node,	32,
> +					&irq_generic_chip_ops, moxart_irq_base);
if (!moxart_irq_domain) {
	/* error handling */
}

> +
> +	ret = irq_alloc_domain_generic_chips(moxart_irq_domain, 32, 1,
> +					"MOXARTINTC", handle_edge_irq,
> +					clr, 0, IRQ_GC_INIT_MASK_CACHE);
> +
> +	if (ret) {
> +		pr_err("%s: could not allocate generic chip\n", __func__);
you should free moxart_irq_domain here.

> +		return -EINVAL;
> +	}
> +
> +	gc = irq_get_domain_generic_chip(moxart_irq_domain, 0);
> +
> +	gc->reg_base = moxart_irq_base;
> +	gc->chip_types[0].regs.mask = IRQ_MASK_REG;
> +	gc->chip_types[0].regs.ack = IRQ_CLEAR_REG;
> +	gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
> +	gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
> +	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
> +
> +	writel(0, moxart_irq_base + IRQ_MASK_REG);
> +	writel(0xffffffff, moxart_irq_base + IRQ_CLEAR_REG);
> +
> +	writel(interrupt_mask, moxart_irq_base + IRQ_MODE_REG);
> +	writel(interrupt_mask, moxart_irq_base + IRQ_LEVEL_REG);
> +
> +	set_handle_irq(moxart_handle_irq);
> +
> +	pr_info("%s: %s finished\n", node->full_name, __func__);
"finished" looks like a debug message. IMHO either drop the message or
write something more useful.
> +
> +	return 0;
> +}
> +IRQCHIP_DECLARE(moxa_moxart_ic, "moxa,moxart-interrupt-controller",
> +				moxart_of_intc_init);
> -- 
Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH v4] ARM: irqchip: add support for MOXA ART SoCs
  2013-06-27 13:29       ` Jonas Jensen
@ 2013-07-01 14:34         ` Jonas Jensen
  -1 siblings, 0 replies; 23+ messages in thread
From: Jonas Jensen @ 2013-07-01 14:34 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds an irqchip driver for the main interrupt controller found
on MOXA ART SoCs.

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Applies to next-20130619
    
    Changes since v3:
    
    1. pack global variables in struct
    2. make handle_irq function static
    3. call irq_linear_revmap instead of irq_find_mapping
    4. fix indentation
    5. add error handling after irq_domain_add_linear
    6. free the domain if irq_alloc_domain_generic_chips fails
    7. use node->full_name instead of __func__ in messages
    8. remove debug messages
    9. make messages more consistent

 drivers/irqchip/Makefile     |   1 +
 drivers/irqchip/irq-moxart.c | 118 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 119 insertions(+)
 create mode 100644 drivers/irqchip/irq-moxart.c

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index cda4cb5..956d129 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_RENESAS_INTC_IRQPIN)	+= irq-renesas-intc-irqpin.o
 obj-$(CONFIG_RENESAS_IRQC)		+= irq-renesas-irqc.o
 obj-$(CONFIG_VERSATILE_FPGA_IRQ)	+= irq-versatile-fpga.o
 obj-$(CONFIG_ARCH_VT8500)		+= irq-vt8500.o
+obj-$(CONFIG_ARCH_MOXART)		+= irq-moxart.o
diff --git a/drivers/irqchip/irq-moxart.c b/drivers/irqchip/irq-moxart.c
new file mode 100644
index 0000000..a84b001
--- /dev/null
+++ b/drivers/irqchip/irq-moxart.c
@@ -0,0 +1,118 @@
+/*
+ * MOXA ART SoCs IRQ chip driver.
+ *
+ * Copyright (C) 2013 Jonas Jensen
+ *
+ * Jonas Jensen <jonas.jensen@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+
+#include <asm/exception.h>
+
+#include "irqchip.h"
+
+#define IRQ_SOURCE_REG		0
+#define IRQ_MASK_REG		0x04
+#define IRQ_CLEAR_REG		0x08
+#define IRQ_MODE_REG		0x0c
+#define IRQ_LEVEL_REG		0x10
+#define IRQ_STATUS_REG		0x14
+
+#define FIQ_SOURCE_REG		0x20
+#define FIQ_MASK_REG		0x24
+#define FIQ_CLEAR_REG		0x28
+#define FIQ_MODE_REG		0x2c
+#define FIQ_LEVEL_REG		0x30
+#define FIQ_STATUS_REG		0x34
+
+
+struct moxart_irq_data {
+	void __iomem *base;
+	struct irq_domain *domain;
+	unsigned int interrupt_mask;
+};
+
+static struct moxart_irq_data intc;
+
+static asmlinkage void __exception_irq_entry handle_irq(struct pt_regs *regs)
+{
+	u32 irqstat;
+	int hwirq;
+
+	irqstat = readl(intc.base + IRQ_STATUS_REG);
+
+	while (irqstat) {
+		hwirq = ffs(irqstat) - 1;
+		handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs);
+		irqstat &= ~(1 << hwirq);
+	}
+}
+
+static int __init moxart_of_intc_init(struct device_node *node,
+				      struct device_node *parent)
+{
+	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+	int ret;
+	struct irq_chip_generic *gc;
+
+	intc.base = of_iomap(node, 0);
+	if (!intc.base) {
+		pr_err("%s: unable to map IC registers\n",
+		       node->full_name);
+		return -EINVAL;
+	}
+
+	intc.domain = irq_domain_add_linear(node, 32, &irq_generic_chip_ops,
+					    intc.base);
+	if (!intc.domain) {
+		pr_err("%s: unable to create IRQ domain\n", node->full_name);
+		return -EINVAL;
+	}
+
+	ret = irq_alloc_domain_generic_chips(intc.domain, 32, 1,
+					     "MOXARTINTC", handle_edge_irq,
+					     clr, 0, IRQ_GC_INIT_MASK_CACHE);
+	if (ret) {
+		pr_err("%s: could not allocate generic chip\n",
+		       node->full_name);
+		irq_domain_remove(intc.domain);
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(node, "interrupt-mask",
+				   &intc.interrupt_mask);
+	if (ret)
+		pr_err("%s: could not read interrupt-mask DT property\n",
+		       node->full_name);
+
+	gc = irq_get_domain_generic_chip(intc.domain, 0);
+
+	gc->reg_base = intc.base;
+	gc->chip_types[0].regs.mask = IRQ_MASK_REG;
+	gc->chip_types[0].regs.ack = IRQ_CLEAR_REG;
+	gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
+	gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
+	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
+
+	writel(0, intc.base + IRQ_MASK_REG);
+	writel(0xffffffff, intc.base + IRQ_CLEAR_REG);
+
+	writel(intc.interrupt_mask, intc.base + IRQ_MODE_REG);
+	writel(intc.interrupt_mask, intc.base + IRQ_LEVEL_REG);
+
+	set_handle_irq(handle_irq);
+
+	return 0;
+}
+IRQCHIP_DECLARE(moxa_moxart_ic, "moxa,moxart-interrupt-controller",
+		moxart_of_intc_init);
-- 
1.8.2.1

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

* [PATCH v4] ARM: irqchip: add support for MOXA ART SoCs
@ 2013-07-01 14:34         ` Jonas Jensen
  0 siblings, 0 replies; 23+ messages in thread
From: Jonas Jensen @ 2013-07-01 14:34 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, arm, tglx, grant.likely, thomas.petazzoni, arnd,
	u.kleine-koenig, linux, Jonas Jensen

This patch adds an irqchip driver for the main interrupt controller found
on MOXA ART SoCs.

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Applies to next-20130619
    
    Changes since v3:
    
    1. pack global variables in struct
    2. make handle_irq function static
    3. call irq_linear_revmap instead of irq_find_mapping
    4. fix indentation
    5. add error handling after irq_domain_add_linear
    6. free the domain if irq_alloc_domain_generic_chips fails
    7. use node->full_name instead of __func__ in messages
    8. remove debug messages
    9. make messages more consistent

 drivers/irqchip/Makefile     |   1 +
 drivers/irqchip/irq-moxart.c | 118 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 119 insertions(+)
 create mode 100644 drivers/irqchip/irq-moxart.c

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index cda4cb5..956d129 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_RENESAS_INTC_IRQPIN)	+= irq-renesas-intc-irqpin.o
 obj-$(CONFIG_RENESAS_IRQC)		+= irq-renesas-irqc.o
 obj-$(CONFIG_VERSATILE_FPGA_IRQ)	+= irq-versatile-fpga.o
 obj-$(CONFIG_ARCH_VT8500)		+= irq-vt8500.o
+obj-$(CONFIG_ARCH_MOXART)		+= irq-moxart.o
diff --git a/drivers/irqchip/irq-moxart.c b/drivers/irqchip/irq-moxart.c
new file mode 100644
index 0000000..a84b001
--- /dev/null
+++ b/drivers/irqchip/irq-moxart.c
@@ -0,0 +1,118 @@
+/*
+ * MOXA ART SoCs IRQ chip driver.
+ *
+ * Copyright (C) 2013 Jonas Jensen
+ *
+ * Jonas Jensen <jonas.jensen@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+
+#include <asm/exception.h>
+
+#include "irqchip.h"
+
+#define IRQ_SOURCE_REG		0
+#define IRQ_MASK_REG		0x04
+#define IRQ_CLEAR_REG		0x08
+#define IRQ_MODE_REG		0x0c
+#define IRQ_LEVEL_REG		0x10
+#define IRQ_STATUS_REG		0x14
+
+#define FIQ_SOURCE_REG		0x20
+#define FIQ_MASK_REG		0x24
+#define FIQ_CLEAR_REG		0x28
+#define FIQ_MODE_REG		0x2c
+#define FIQ_LEVEL_REG		0x30
+#define FIQ_STATUS_REG		0x34
+
+
+struct moxart_irq_data {
+	void __iomem *base;
+	struct irq_domain *domain;
+	unsigned int interrupt_mask;
+};
+
+static struct moxart_irq_data intc;
+
+static asmlinkage void __exception_irq_entry handle_irq(struct pt_regs *regs)
+{
+	u32 irqstat;
+	int hwirq;
+
+	irqstat = readl(intc.base + IRQ_STATUS_REG);
+
+	while (irqstat) {
+		hwirq = ffs(irqstat) - 1;
+		handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs);
+		irqstat &= ~(1 << hwirq);
+	}
+}
+
+static int __init moxart_of_intc_init(struct device_node *node,
+				      struct device_node *parent)
+{
+	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+	int ret;
+	struct irq_chip_generic *gc;
+
+	intc.base = of_iomap(node, 0);
+	if (!intc.base) {
+		pr_err("%s: unable to map IC registers\n",
+		       node->full_name);
+		return -EINVAL;
+	}
+
+	intc.domain = irq_domain_add_linear(node, 32, &irq_generic_chip_ops,
+					    intc.base);
+	if (!intc.domain) {
+		pr_err("%s: unable to create IRQ domain\n", node->full_name);
+		return -EINVAL;
+	}
+
+	ret = irq_alloc_domain_generic_chips(intc.domain, 32, 1,
+					     "MOXARTINTC", handle_edge_irq,
+					     clr, 0, IRQ_GC_INIT_MASK_CACHE);
+	if (ret) {
+		pr_err("%s: could not allocate generic chip\n",
+		       node->full_name);
+		irq_domain_remove(intc.domain);
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(node, "interrupt-mask",
+				   &intc.interrupt_mask);
+	if (ret)
+		pr_err("%s: could not read interrupt-mask DT property\n",
+		       node->full_name);
+
+	gc = irq_get_domain_generic_chip(intc.domain, 0);
+
+	gc->reg_base = intc.base;
+	gc->chip_types[0].regs.mask = IRQ_MASK_REG;
+	gc->chip_types[0].regs.ack = IRQ_CLEAR_REG;
+	gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
+	gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
+	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
+
+	writel(0, intc.base + IRQ_MASK_REG);
+	writel(0xffffffff, intc.base + IRQ_CLEAR_REG);
+
+	writel(intc.interrupt_mask, intc.base + IRQ_MODE_REG);
+	writel(intc.interrupt_mask, intc.base + IRQ_LEVEL_REG);
+
+	set_handle_irq(handle_irq);
+
+	return 0;
+}
+IRQCHIP_DECLARE(moxa_moxart_ic, "moxa,moxart-interrupt-controller",
+		moxart_of_intc_init);
-- 
1.8.2.1


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

* [PATCH v5] ARM: irqchip: add support for MOXA ART SoCs
  2013-07-01 14:34         ` Jonas Jensen
@ 2013-07-04 12:38           ` Jonas Jensen
  -1 siblings, 0 replies; 23+ messages in thread
From: Jonas Jensen @ 2013-07-04 12:38 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds an irqchip driver for the main interrupt controller found
on MOXA ART SoCs.

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Applies to next-20130703
    
    Changes since v4:
    
    1. shorten DT compatible value to "moxart-ic"
    2. use alphabetic ordering in Makefile

 drivers/irqchip/Makefile     |   1 +
 drivers/irqchip/irq-moxart.c | 118 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 119 insertions(+)
 create mode 100644 drivers/irqchip/irq-moxart.c

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 2065ef6..e65c41a 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_ARCH_MXS)			+= irq-mxs.o
 obj-$(CONFIG_ARCH_S3C24XX)		+= irq-s3c24xx.o
 obj-$(CONFIG_METAG)			+= irq-metag-ext.o
 obj-$(CONFIG_METAG_PERFCOUNTER_IRQS)	+= irq-metag.o
+obj-$(CONFIG_ARCH_MOXART)		+= irq-moxart.o
 obj-$(CONFIG_ORION_IRQCHIP)		+= irq-orion.o
 obj-$(CONFIG_ARCH_SUNXI)		+= irq-sun4i.o
 obj-$(CONFIG_ARCH_SPEAR3XX)		+= spear-shirq.o
diff --git a/drivers/irqchip/irq-moxart.c b/drivers/irqchip/irq-moxart.c
new file mode 100644
index 0000000..a9d9f36
--- /dev/null
+++ b/drivers/irqchip/irq-moxart.c
@@ -0,0 +1,118 @@
+/*
+ * MOXA ART SoCs IRQ chip driver.
+ *
+ * Copyright (C) 2013 Jonas Jensen
+ *
+ * Jonas Jensen <jonas.jensen@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+
+#include <asm/exception.h>
+
+#include "irqchip.h"
+
+#define IRQ_SOURCE_REG		0
+#define IRQ_MASK_REG		0x04
+#define IRQ_CLEAR_REG		0x08
+#define IRQ_MODE_REG		0x0c
+#define IRQ_LEVEL_REG		0x10
+#define IRQ_STATUS_REG		0x14
+
+#define FIQ_SOURCE_REG		0x20
+#define FIQ_MASK_REG		0x24
+#define FIQ_CLEAR_REG		0x28
+#define FIQ_MODE_REG		0x2c
+#define FIQ_LEVEL_REG		0x30
+#define FIQ_STATUS_REG		0x34
+
+
+struct moxart_irq_data {
+	void __iomem *base;
+	struct irq_domain *domain;
+	unsigned int interrupt_mask;
+};
+
+static struct moxart_irq_data intc;
+
+static asmlinkage void __exception_irq_entry handle_irq(struct pt_regs *regs)
+{
+	u32 irqstat;
+	int hwirq;
+
+	irqstat = readl(intc.base + IRQ_STATUS_REG);
+
+	while (irqstat) {
+		hwirq = ffs(irqstat) - 1;
+		handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs);
+		irqstat &= ~(1 << hwirq);
+	}
+}
+
+static int __init moxart_of_intc_init(struct device_node *node,
+				      struct device_node *parent)
+{
+	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+	int ret;
+	struct irq_chip_generic *gc;
+
+	intc.base = of_iomap(node, 0);
+	if (!intc.base) {
+		pr_err("%s: unable to map IC registers\n",
+		       node->full_name);
+		return -EINVAL;
+	}
+
+	intc.domain = irq_domain_add_linear(node, 32, &irq_generic_chip_ops,
+					    intc.base);
+	if (!intc.domain) {
+		pr_err("%s: unable to create IRQ domain\n", node->full_name);
+		return -EINVAL;
+	}
+
+	ret = irq_alloc_domain_generic_chips(intc.domain, 32, 1,
+					     "MOXARTINTC", handle_edge_irq,
+					     clr, 0, IRQ_GC_INIT_MASK_CACHE);
+	if (ret) {
+		pr_err("%s: could not allocate generic chip\n",
+		       node->full_name);
+		irq_domain_remove(intc.domain);
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(node, "interrupt-mask",
+				   &intc.interrupt_mask);
+	if (ret)
+		pr_err("%s: could not read interrupt-mask DT property\n",
+		       node->full_name);
+
+	gc = irq_get_domain_generic_chip(intc.domain, 0);
+
+	gc->reg_base = intc.base;
+	gc->chip_types[0].regs.mask = IRQ_MASK_REG;
+	gc->chip_types[0].regs.ack = IRQ_CLEAR_REG;
+	gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
+	gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
+	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
+
+	writel(0, intc.base + IRQ_MASK_REG);
+	writel(0xffffffff, intc.base + IRQ_CLEAR_REG);
+
+	writel(intc.interrupt_mask, intc.base + IRQ_MODE_REG);
+	writel(intc.interrupt_mask, intc.base + IRQ_LEVEL_REG);
+
+	set_handle_irq(handle_irq);
+
+	return 0;
+}
+IRQCHIP_DECLARE(moxa_moxart_ic, "moxa,moxart-ic",
+		moxart_of_intc_init);
-- 
1.8.2.1

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

* [PATCH v5] ARM: irqchip: add support for MOXA ART SoCs
@ 2013-07-04 12:38           ` Jonas Jensen
  0 siblings, 0 replies; 23+ messages in thread
From: Jonas Jensen @ 2013-07-04 12:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, arm, tglx, grant.likely, thomas.petazzoni, arnd,
	u.kleine-koenig, linux, Jonas Jensen

This patch adds an irqchip driver for the main interrupt controller found
on MOXA ART SoCs.

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Applies to next-20130703
    
    Changes since v4:
    
    1. shorten DT compatible value to "moxart-ic"
    2. use alphabetic ordering in Makefile

 drivers/irqchip/Makefile     |   1 +
 drivers/irqchip/irq-moxart.c | 118 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 119 insertions(+)
 create mode 100644 drivers/irqchip/irq-moxart.c

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 2065ef6..e65c41a 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_ARCH_MXS)			+= irq-mxs.o
 obj-$(CONFIG_ARCH_S3C24XX)		+= irq-s3c24xx.o
 obj-$(CONFIG_METAG)			+= irq-metag-ext.o
 obj-$(CONFIG_METAG_PERFCOUNTER_IRQS)	+= irq-metag.o
+obj-$(CONFIG_ARCH_MOXART)		+= irq-moxart.o
 obj-$(CONFIG_ORION_IRQCHIP)		+= irq-orion.o
 obj-$(CONFIG_ARCH_SUNXI)		+= irq-sun4i.o
 obj-$(CONFIG_ARCH_SPEAR3XX)		+= spear-shirq.o
diff --git a/drivers/irqchip/irq-moxart.c b/drivers/irqchip/irq-moxart.c
new file mode 100644
index 0000000..a9d9f36
--- /dev/null
+++ b/drivers/irqchip/irq-moxart.c
@@ -0,0 +1,118 @@
+/*
+ * MOXA ART SoCs IRQ chip driver.
+ *
+ * Copyright (C) 2013 Jonas Jensen
+ *
+ * Jonas Jensen <jonas.jensen@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+
+#include <asm/exception.h>
+
+#include "irqchip.h"
+
+#define IRQ_SOURCE_REG		0
+#define IRQ_MASK_REG		0x04
+#define IRQ_CLEAR_REG		0x08
+#define IRQ_MODE_REG		0x0c
+#define IRQ_LEVEL_REG		0x10
+#define IRQ_STATUS_REG		0x14
+
+#define FIQ_SOURCE_REG		0x20
+#define FIQ_MASK_REG		0x24
+#define FIQ_CLEAR_REG		0x28
+#define FIQ_MODE_REG		0x2c
+#define FIQ_LEVEL_REG		0x30
+#define FIQ_STATUS_REG		0x34
+
+
+struct moxart_irq_data {
+	void __iomem *base;
+	struct irq_domain *domain;
+	unsigned int interrupt_mask;
+};
+
+static struct moxart_irq_data intc;
+
+static asmlinkage void __exception_irq_entry handle_irq(struct pt_regs *regs)
+{
+	u32 irqstat;
+	int hwirq;
+
+	irqstat = readl(intc.base + IRQ_STATUS_REG);
+
+	while (irqstat) {
+		hwirq = ffs(irqstat) - 1;
+		handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs);
+		irqstat &= ~(1 << hwirq);
+	}
+}
+
+static int __init moxart_of_intc_init(struct device_node *node,
+				      struct device_node *parent)
+{
+	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+	int ret;
+	struct irq_chip_generic *gc;
+
+	intc.base = of_iomap(node, 0);
+	if (!intc.base) {
+		pr_err("%s: unable to map IC registers\n",
+		       node->full_name);
+		return -EINVAL;
+	}
+
+	intc.domain = irq_domain_add_linear(node, 32, &irq_generic_chip_ops,
+					    intc.base);
+	if (!intc.domain) {
+		pr_err("%s: unable to create IRQ domain\n", node->full_name);
+		return -EINVAL;
+	}
+
+	ret = irq_alloc_domain_generic_chips(intc.domain, 32, 1,
+					     "MOXARTINTC", handle_edge_irq,
+					     clr, 0, IRQ_GC_INIT_MASK_CACHE);
+	if (ret) {
+		pr_err("%s: could not allocate generic chip\n",
+		       node->full_name);
+		irq_domain_remove(intc.domain);
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(node, "interrupt-mask",
+				   &intc.interrupt_mask);
+	if (ret)
+		pr_err("%s: could not read interrupt-mask DT property\n",
+		       node->full_name);
+
+	gc = irq_get_domain_generic_chip(intc.domain, 0);
+
+	gc->reg_base = intc.base;
+	gc->chip_types[0].regs.mask = IRQ_MASK_REG;
+	gc->chip_types[0].regs.ack = IRQ_CLEAR_REG;
+	gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
+	gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
+	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
+
+	writel(0, intc.base + IRQ_MASK_REG);
+	writel(0xffffffff, intc.base + IRQ_CLEAR_REG);
+
+	writel(intc.interrupt_mask, intc.base + IRQ_MODE_REG);
+	writel(intc.interrupt_mask, intc.base + IRQ_LEVEL_REG);
+
+	set_handle_irq(handle_irq);
+
+	return 0;
+}
+IRQCHIP_DECLARE(moxa_moxart_ic, "moxa,moxart-ic",
+		moxart_of_intc_init);
-- 
1.8.2.1


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

* [tip:irq/urgent] irqchip: Add support for MOXA ART SoCs
  2013-07-04 12:38           ` Jonas Jensen
  (?)
@ 2013-07-05  9:49           ` tip-bot for Jonas Jensen
  -1 siblings, 0 replies; 23+ messages in thread
From: tip-bot for Jonas Jensen @ 2013-07-05  9:49 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, jonas.jensen, tglx

Commit-ID:  4de563ae821b1935b3c467a4606e5738b0b0df87
Gitweb:     http://git.kernel.org/tip/4de563ae821b1935b3c467a4606e5738b0b0df87
Author:     Jonas Jensen <jonas.jensen@gmail.com>
AuthorDate: Thu, 4 Jul 2013 14:38:51 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Fri, 5 Jul 2013 11:39:25 +0200

irqchip: Add support for MOXA ART SoCs

This patch adds an irqchip driver for the main interrupt controller
found on MOXA ART SoCs.

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
Cc: grant.likely@secretlab.ca
Cc: thomas.petazzoni@free-electrons.com
Cc: arnd@arndb.de
Cc: u.kleine-koenig@pengutronix.de
Cc: linux@arm.linux.org.uk
Cc: linux-arm-kernel@lists.infradead.org
Link: http://lkml.kernel.org/r/1372941531-6393-1-git-send-email-jonas.jensen@gmail.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/irqchip/Makefile     |   1 +
 drivers/irqchip/irq-moxart.c | 117 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 118 insertions(+)

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 2065ef6..e65c41a 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_ARCH_MXS)			+= irq-mxs.o
 obj-$(CONFIG_ARCH_S3C24XX)		+= irq-s3c24xx.o
 obj-$(CONFIG_METAG)			+= irq-metag-ext.o
 obj-$(CONFIG_METAG_PERFCOUNTER_IRQS)	+= irq-metag.o
+obj-$(CONFIG_ARCH_MOXART)		+= irq-moxart.o
 obj-$(CONFIG_ORION_IRQCHIP)		+= irq-orion.o
 obj-$(CONFIG_ARCH_SUNXI)		+= irq-sun4i.o
 obj-$(CONFIG_ARCH_SPEAR3XX)		+= spear-shirq.o
diff --git a/drivers/irqchip/irq-moxart.c b/drivers/irqchip/irq-moxart.c
new file mode 100644
index 0000000..5552fc2
--- /dev/null
+++ b/drivers/irqchip/irq-moxart.c
@@ -0,0 +1,117 @@
+/*
+ * MOXA ART SoCs IRQ chip driver.
+ *
+ * Copyright (C) 2013 Jonas Jensen
+ *
+ * Jonas Jensen <jonas.jensen@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+
+#include <asm/exception.h>
+
+#include "irqchip.h"
+
+#define IRQ_SOURCE_REG		0
+#define IRQ_MASK_REG		0x04
+#define IRQ_CLEAR_REG		0x08
+#define IRQ_MODE_REG		0x0c
+#define IRQ_LEVEL_REG		0x10
+#define IRQ_STATUS_REG		0x14
+
+#define FIQ_SOURCE_REG		0x20
+#define FIQ_MASK_REG		0x24
+#define FIQ_CLEAR_REG		0x28
+#define FIQ_MODE_REG		0x2c
+#define FIQ_LEVEL_REG		0x30
+#define FIQ_STATUS_REG		0x34
+
+
+struct moxart_irq_data {
+	void __iomem *base;
+	struct irq_domain *domain;
+	unsigned int interrupt_mask;
+};
+
+static struct moxart_irq_data intc;
+
+static asmlinkage void __exception_irq_entry handle_irq(struct pt_regs *regs)
+{
+	u32 irqstat;
+	int hwirq;
+
+	irqstat = readl(intc.base + IRQ_STATUS_REG);
+
+	while (irqstat) {
+		hwirq = ffs(irqstat) - 1;
+		handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs);
+		irqstat &= ~(1 << hwirq);
+	}
+}
+
+static int __init moxart_of_intc_init(struct device_node *node,
+				      struct device_node *parent)
+{
+	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+	int ret;
+	struct irq_chip_generic *gc;
+
+	intc.base = of_iomap(node, 0);
+	if (!intc.base) {
+		pr_err("%s: unable to map IC registers\n",
+		       node->full_name);
+		return -EINVAL;
+	}
+
+	intc.domain = irq_domain_add_linear(node, 32, &irq_generic_chip_ops,
+					    intc.base);
+	if (!intc.domain) {
+		pr_err("%s: unable to create IRQ domain\n", node->full_name);
+		return -EINVAL;
+	}
+
+	ret = irq_alloc_domain_generic_chips(intc.domain, 32, 1,
+					     "MOXARTINTC", handle_edge_irq,
+					     clr, 0, IRQ_GC_INIT_MASK_CACHE);
+	if (ret) {
+		pr_err("%s: could not allocate generic chip\n",
+		       node->full_name);
+		irq_domain_remove(intc.domain);
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(node, "interrupt-mask",
+				   &intc.interrupt_mask);
+	if (ret)
+		pr_err("%s: could not read interrupt-mask DT property\n",
+		       node->full_name);
+
+	gc = irq_get_domain_generic_chip(intc.domain, 0);
+
+	gc->reg_base = intc.base;
+	gc->chip_types[0].regs.mask = IRQ_MASK_REG;
+	gc->chip_types[0].regs.ack = IRQ_CLEAR_REG;
+	gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
+	gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
+	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
+
+	writel(0, intc.base + IRQ_MASK_REG);
+	writel(0xffffffff, intc.base + IRQ_CLEAR_REG);
+
+	writel(intc.interrupt_mask, intc.base + IRQ_MODE_REG);
+	writel(intc.interrupt_mask, intc.base + IRQ_LEVEL_REG);
+
+	set_handle_irq(handle_irq);
+
+	return 0;
+}
+IRQCHIP_DECLARE(moxa_moxart_ic, "moxa,moxart-ic", moxart_of_intc_init);

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

end of thread, other threads:[~2013-07-05  9:49 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-18  9:59 [PATCH] ARM: irqchip: add support for MOXA ART SoCs Jonas Jensen
2013-06-18  9:59 ` Jonas Jensen
2013-06-18 10:35 ` Russell King - ARM Linux
2013-06-18 10:35   ` Russell King - ARM Linux
2013-06-18 12:54   ` Arnd Bergmann
2013-06-18 12:54     ` Arnd Bergmann
2013-06-18 13:41 ` Thomas Petazzoni
2013-06-18 13:41   ` Thomas Petazzoni
2013-06-20  8:58   ` [PATCH v2] " Jonas Jensen
2013-06-20  8:58     ` Jonas Jensen
2013-06-20 10:17     ` Arnd Bergmann
2013-06-20 10:17       ` Arnd Bergmann
2013-06-24 13:18     ` Grant Likely
2013-06-24 13:18       ` Grant Likely
2013-06-27 13:29     ` [PATCH v3] ARM: " Jonas Jensen
2013-06-27 13:29       ` Jonas Jensen
2013-06-27 17:49       ` Uwe Kleine-König
2013-06-27 17:49         ` Uwe Kleine-König
2013-07-01 14:34       ` [PATCH v4] " Jonas Jensen
2013-07-01 14:34         ` Jonas Jensen
2013-07-04 12:38         ` [PATCH v5] " Jonas Jensen
2013-07-04 12:38           ` Jonas Jensen
2013-07-05  9:49           ` [tip:irq/urgent] irqchip: Add " tip-bot for Jonas Jensen

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.