From: "Heiko Stübner" <heiko@sntech.de>
To: Kukjin Kim <kgene.kim@samsung.com>
Cc: Grant Likely <grant.likely@secretlab.ca>,
Rob Herring <rob.herring@calxeda.com>,
Thomas Abraham <thomas.abraham@linaro.org>,
devicetree-discuss@lists.ozlabs.org,
linux-arm-kernel@lists.infradead.org,
linux-samsung-soc@vger.kernel.org
Subject: [PATCH v3 5/6] irqchip: s3c24xx: add devicetree support
Date: Sun, 17 Mar 2013 14:07:58 +0100 [thread overview]
Message-ID: <201303171407.59128.heiko@sntech.de> (raw)
In-Reply-To: <201303171404.06146.heiko@sntech.de>
Add the necessary code to initialize the interrupt controller
thru devicetree data using the irqchip infrastructure.
On dt machines the eint-type interrupts in the main interrupt controller
get mapped as regular edge-types, as their wakeup and interrupt type
properties will be handled by the upcoming pinctrl driver.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
.../interrupt-controller/samsung,s3c24xx-irq.txt | 54 +++++
drivers/irqchip/irq-s3c24xx.c | 222 ++++++++++++++++++++
2 files changed, 276 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24xx-irq.txt
diff --git a/Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24xx-irq.txt b/Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24xx-irq.txt
new file mode 100644
index 0000000..be5dead
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24xx-irq.txt
@@ -0,0 +1,54 @@
+Samsung S3C24XX Interrupt Controllers
+
+The S3C24XX SoCs contain a custom set of interrupt controllers providing a
+varying number of interrupt sources. The set consists of a main- and sub-
+controller and on newer SoCs even a second main controller.
+
+Required properties:
+- compatible: Compatible property value should be one of "samsung,s3c2410-irq",
+ "samsung,s3c2412-irq", "samsung,s3c2416-irq", "samsung,s3c2440-irq",
+ "samsung,s3c2442-irq", "samsung,s3c2443-irq" depending on the SoC variant.
+
+- reg: Physical base address of the controller and length of memory mapped
+ region.
+
+- interrupt-controller : Identifies the node as an interrupt controller
+
+Sub-controllers as child nodes:
+ The interrupt controllers that should be referenced by device nodes are
+ represented by child nodes. Valid names are intc, subintc and intc2.
+ The interrupt values in device nodes are then mapped directly to the
+ bit-numbers of the pending register of the named interrupt controller.
+
+Required properties:
+- interrupt-controller : Identifies the node as an interrupt controller
+
+- #interrupt-cells : Specifies the number of cells needed to encode an
+ interrupt source. The value shall be 2.
+
+Example:
+
+ interrupt-controller@4a000000 {
+ compatible = "samsung,s3c2416-irq";
+ reg = <0x4a000000 0x100>;
+ interrupt-controller;
+
+ intc:intc {
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ subintc:subintc {
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ [...]
+
+ serial@50000000 {
+ compatible = "samsung,s3c2410-uart";
+ reg = <0x50000000 0x4000>;
+ interrupt-parent = <&subintc>;
+ interrupts = <0 0>, <1 0>;
+ };
diff --git a/drivers/irqchip/irq-s3c24xx.c b/drivers/irqchip/irq-s3c24xx.c
index 1eba289..55cb363 100644
--- a/drivers/irqchip/irq-s3c24xx.c
+++ b/drivers/irqchip/irq-s3c24xx.c
@@ -25,6 +25,9 @@
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
#include <asm/exception.h>
#include <asm/mach/irq.h>
@@ -36,6 +39,8 @@
#include <plat/regs-irqtype.h>
#include <plat/pm.h>
+#include "irqchip.h"
+
#define S3C_IRQTYPE_NONE 0
#define S3C_IRQTYPE_EINT 1
#define S3C_IRQTYPE_EDGE 2
@@ -380,6 +385,10 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
parent_intc = intc->parent;
+ /* on dt platforms the extints get handled by the pinctrl driver */
+ if (h->of_node && irq_data->type == S3C_IRQTYPE_EINT)
+ irq_data->type = S3C_IRQTYPE_EDGE;
+
/* set handler and flags */
switch (irq_data->type) {
case S3C_IRQTYPE_NONE:
@@ -1104,3 +1113,216 @@ void __init s3c2443_init_irq(void)
s3c24xx_init_intc(NULL, &init_s3c2443subint[0], main_intc, 0x4a000018);
}
#endif
+
+#ifdef CONFIG_OF
+struct s3c24xx_irq_of_ctrl {
+ char *name;
+ unsigned long offset;
+ struct s3c_irq_data *irq_data;
+ struct s3c_irq_intc **handle;
+ struct s3c_irq_intc **parent;
+};
+
+#define S3C24XX_IRQCTRL(n, o, d, h, p) \
+{ \
+ .name = n, \
+ .offset = o, \
+ .irq_data = d, \
+ .handle = h, \
+ .parent = p, \
+}
+
+struct s3c24xx_irq_of_data {
+ struct s3c24xx_irq_of_ctrl *irq_ctrl;
+ int num_ctrl;
+};
+
+#ifdef CONFIG_CPU_S3C2410
+static struct s3c24xx_irq_of_ctrl s3c2410_ctrl[] = {
+ S3C24XX_IRQCTRL("intc", 0, init_s3c2410base, &main_intc, NULL),
+ S3C24XX_IRQCTRL("subintc", 0x18, init_s3c2410subint, NULL, &main_intc),
+};
+
+static struct s3c24xx_irq_of_data s3c2410_irq_data = {
+ .irq_ctrl = s3c2410_ctrl,
+ .num_ctrl = ARRAY_SIZE(s3c2410_ctrl),
+};
+#endif
+
+#ifdef CONFIG_CPU_S3C2412
+static struct s3c24xx_irq_of_ctrl s3c2412_ctrl[] = {
+ S3C24XX_IRQCTRL("intc", 0, init_s3c2412base, &main_intc, NULL),
+ S3C24XX_IRQCTRL("subintc", 0x18, init_s3c2412subint, NULL, &main_intc),
+};
+
+static struct s3c24xx_irq_of_data s3c2412_irq_data = {
+ .irq_ctrl = s3c2412_ctrl,
+ .num_ctrl = ARRAY_SIZE(s3c2412_ctrl),
+};
+#endif
+
+#ifdef CONFIG_CPU_S3C2416
+static struct s3c24xx_irq_of_ctrl s3c2416_ctrl[] = {
+ S3C24XX_IRQCTRL("intc", 0, init_s3c2416base, &main_intc, NULL),
+ S3C24XX_IRQCTRL("subintc", 0x18, init_s3c2416subint, NULL, &main_intc),
+ S3C24XX_IRQCTRL("intc2", 0x40, init_s3c2416_second, &main_intc2, NULL),
+};
+
+static struct s3c24xx_irq_of_data s3c2416_irq_data = {
+ .irq_ctrl = s3c2416_ctrl,
+ .num_ctrl = ARRAY_SIZE(s3c2416_ctrl),
+};
+#endif
+
+#ifdef CONFIG_CPU_S3C2440
+static struct s3c24xx_irq_of_ctrl s3c2440_ctrl[] = {
+ S3C24XX_IRQCTRL("intc", 0, init_s3c2440base, &main_intc, NULL),
+ S3C24XX_IRQCTRL("subintc", 0x18, init_s3c2440subint, NULL, &main_intc),
+};
+
+static struct s3c24xx_irq_of_data s3c2440_irq_data = {
+ .irq_ctrl = s3c2440_ctrl,
+ .num_ctrl = ARRAY_SIZE(s3c2440_ctrl),
+};
+#endif
+
+#ifdef CONFIG_CPU_S3C2442
+static struct s3c24xx_irq_of_ctrl s3c2442_ctrl[] = {
+ S3C24XX_IRQCTRL("intc", 0, init_s3c2442base, &main_intc, NULL),
+ S3C24XX_IRQCTRL("subintc", 0x18, init_s3c2442subint, NULL, &main_intc),
+};
+
+static struct s3c24xx_irq_of_data s3c2442_irq_data = {
+ .irq_ctrl = s3c2442_ctrl,
+ .num_ctrl = ARRAY_SIZE(s3c2442_ctrl),
+};
+#endif
+
+#ifdef CONFIG_CPU_S3C2443
+static struct s3c24xx_irq_of_ctrl s3c2443_ctrl[] = {
+ S3C24XX_IRQCTRL("intc", 0, init_s3c2443base, &main_intc, NULL),
+ S3C24XX_IRQCTRL("subintc", 0x18, init_s3c2443subint, NULL, &main_intc),
+};
+
+static struct s3c24xx_irq_of_data s3c2443_irq_data = {
+ .irq_ctrl = s3c2443_ctrl,
+ .num_ctrl = ARRAY_SIZE(s3c2443_ctrl),
+};
+#endif
+
+static const struct of_device_id intc_list[] = {
+#ifdef CONFIG_CPU_S3C2410
+ { .compatible = "samsung,s3c2410-irq", .data = &s3c2410_irq_data },
+#endif
+#ifdef CONFIG_CPU_S3C2412
+ { .compatible = "samsung,s3c2412-irq", .data = &s3c2412_irq_data },
+#endif
+#ifdef CONFIG_CPU_S3C2416
+ { .compatible = "samsung,s3c2416-irq", .data = &s3c2416_irq_data },
+#endif
+#ifdef CONFIG_CPU_S3C2440
+ { .compatible = "samsung,s3c2440-irq", .data = &s3c2440_irq_data },
+#endif
+#ifdef CONFIG_CPU_S3C2442
+ { .compatible = "samsung,s3c2442-irq", .data = &s3c2442_irq_data },
+#endif
+#ifdef CONFIG_CPU_S3C2443
+ { .compatible = "samsung,s3c2443-irq", .data = &s3c2443_irq_data },
+#endif
+ {},
+};
+
+int __init s3c24xx_init_intc_of(struct device_node *np,
+ struct device_node *interrupt_parent)
+{
+ const struct of_device_id *match;
+ const struct s3c24xx_irq_of_data *ctrl_data;
+ struct device_node *intc_node;
+ struct s3c24xx_irq_of_ctrl *ctrl;
+ struct s3c_irq_intc *intc;
+ void __iomem *reg_base;
+ int i;
+
+ match = of_match_node(intc_list, np);
+ if (!match) {
+ pr_err("irq-s3c24xx: could not find matching irqdata\n");
+ return -EINVAL;
+ }
+
+ ctrl_data = match->data;
+
+ reg_base = of_iomap(np, 0);
+ if (!reg_base) {
+ pr_err("irq-s3c24xx: could not map irq memory\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < ctrl_data->num_ctrl; i++) {
+ ctrl = &ctrl_data->irq_ctrl[i];
+
+ intc_node = of_find_node_by_name(np, ctrl->name);
+ if (!intc_node) {
+ pr_debug("irq: no device node for %s\n",
+ ctrl->name);
+ continue;
+ }
+
+ intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
+ if (!intc) {
+ of_node_put(intc_node);
+ return -ENOMEM;
+ }
+
+ pr_debug("irq: found controller %s\n", ctrl->name);
+
+ intc->irqs = ctrl->irq_data;
+
+ if (ctrl->parent) {
+ if (*(ctrl->parent)) {
+ intc->parent = *(ctrl->parent);
+ } else {
+ pr_warn("irq: parent of %s missing\n",
+ ctrl->name);
+ kfree(intc);
+ of_node_put(intc_node);
+ continue;
+ }
+ }
+
+ if (!ctrl->parent) {
+ intc->reg_pending = reg_base + ctrl->offset;
+ intc->reg_mask = reg_base + ctrl->offset + 0x08;
+ intc->reg_intpnd = reg_base + ctrl->offset + 0x10;
+ } else {
+ intc->reg_pending = reg_base + ctrl->offset;
+ intc->reg_mask = reg_base + ctrl->offset + 0x4;
+ }
+
+ /* now that all the data is complete, init the irq-domain */
+ s3c24xx_clear_intc(intc);
+ intc->domain = irq_domain_add_linear(intc_node, 32,
+ &s3c24xx_irq_ops, intc);
+ if (!intc->domain) {
+ pr_err("irq: could not create irq-domain\n");
+ kfree(intc);
+ of_node_put(intc_node);
+ continue;
+ }
+
+ if (ctrl->handle)
+ *(ctrl->handle) = intc;
+ }
+
+ set_handle_irq(s3c24xx_handle_irq);
+
+ return 0;
+}
+
+IRQCHIP_DECLARE(s3c2410_irq, "samsung,s3c2410-irq", s3c24xx_init_intc_of);
+IRQCHIP_DECLARE(s3c2412_irq, "samsung,s3c2412-irq", s3c24xx_init_intc_of);
+IRQCHIP_DECLARE(s3c2416_irq, "samsung,s3c2416-irq", s3c24xx_init_intc_of);
+IRQCHIP_DECLARE(s3c2440_irq, "samsung,s3c2440-irq", s3c24xx_init_intc_of);
+IRQCHIP_DECLARE(s3c2442_irq, "samsung,s3c2442-irq", s3c24xx_init_intc_of);
+IRQCHIP_DECLARE(s3c2443_irq, "samsung,s3c2443-irq", s3c24xx_init_intc_of);
+IRQCHIP_DECLARE(s3c2450_irq, "samsung,s3c2450-irq", s3c24xx_init_intc_of);
+#endif
--
1.7.2.3
WARNING: multiple messages have this Message-ID (diff)
From: heiko@sntech.de (Heiko Stübner)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 5/6] irqchip: s3c24xx: add devicetree support
Date: Sun, 17 Mar 2013 14:07:58 +0100 [thread overview]
Message-ID: <201303171407.59128.heiko@sntech.de> (raw)
In-Reply-To: <201303171404.06146.heiko@sntech.de>
Add the necessary code to initialize the interrupt controller
thru devicetree data using the irqchip infrastructure.
On dt machines the eint-type interrupts in the main interrupt controller
get mapped as regular edge-types, as their wakeup and interrupt type
properties will be handled by the upcoming pinctrl driver.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
.../interrupt-controller/samsung,s3c24xx-irq.txt | 54 +++++
drivers/irqchip/irq-s3c24xx.c | 222 ++++++++++++++++++++
2 files changed, 276 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24xx-irq.txt
diff --git a/Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24xx-irq.txt b/Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24xx-irq.txt
new file mode 100644
index 0000000..be5dead
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24xx-irq.txt
@@ -0,0 +1,54 @@
+Samsung S3C24XX Interrupt Controllers
+
+The S3C24XX SoCs contain a custom set of interrupt controllers providing a
+varying number of interrupt sources. The set consists of a main- and sub-
+controller and on newer SoCs even a second main controller.
+
+Required properties:
+- compatible: Compatible property value should be one of "samsung,s3c2410-irq",
+ "samsung,s3c2412-irq", "samsung,s3c2416-irq", "samsung,s3c2440-irq",
+ "samsung,s3c2442-irq", "samsung,s3c2443-irq" depending on the SoC variant.
+
+- reg: Physical base address of the controller and length of memory mapped
+ region.
+
+- interrupt-controller : Identifies the node as an interrupt controller
+
+Sub-controllers as child nodes:
+ The interrupt controllers that should be referenced by device nodes are
+ represented by child nodes. Valid names are intc, subintc and intc2.
+ The interrupt values in device nodes are then mapped directly to the
+ bit-numbers of the pending register of the named interrupt controller.
+
+Required properties:
+- interrupt-controller : Identifies the node as an interrupt controller
+
+- #interrupt-cells : Specifies the number of cells needed to encode an
+ interrupt source. The value shall be 2.
+
+Example:
+
+ interrupt-controller at 4a000000 {
+ compatible = "samsung,s3c2416-irq";
+ reg = <0x4a000000 0x100>;
+ interrupt-controller;
+
+ intc:intc {
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ subintc:subintc {
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ [...]
+
+ serial at 50000000 {
+ compatible = "samsung,s3c2410-uart";
+ reg = <0x50000000 0x4000>;
+ interrupt-parent = <&subintc>;
+ interrupts = <0 0>, <1 0>;
+ };
diff --git a/drivers/irqchip/irq-s3c24xx.c b/drivers/irqchip/irq-s3c24xx.c
index 1eba289..55cb363 100644
--- a/drivers/irqchip/irq-s3c24xx.c
+++ b/drivers/irqchip/irq-s3c24xx.c
@@ -25,6 +25,9 @@
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
#include <asm/exception.h>
#include <asm/mach/irq.h>
@@ -36,6 +39,8 @@
#include <plat/regs-irqtype.h>
#include <plat/pm.h>
+#include "irqchip.h"
+
#define S3C_IRQTYPE_NONE 0
#define S3C_IRQTYPE_EINT 1
#define S3C_IRQTYPE_EDGE 2
@@ -380,6 +385,10 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
parent_intc = intc->parent;
+ /* on dt platforms the extints get handled by the pinctrl driver */
+ if (h->of_node && irq_data->type == S3C_IRQTYPE_EINT)
+ irq_data->type = S3C_IRQTYPE_EDGE;
+
/* set handler and flags */
switch (irq_data->type) {
case S3C_IRQTYPE_NONE:
@@ -1104,3 +1113,216 @@ void __init s3c2443_init_irq(void)
s3c24xx_init_intc(NULL, &init_s3c2443subint[0], main_intc, 0x4a000018);
}
#endif
+
+#ifdef CONFIG_OF
+struct s3c24xx_irq_of_ctrl {
+ char *name;
+ unsigned long offset;
+ struct s3c_irq_data *irq_data;
+ struct s3c_irq_intc **handle;
+ struct s3c_irq_intc **parent;
+};
+
+#define S3C24XX_IRQCTRL(n, o, d, h, p) \
+{ \
+ .name = n, \
+ .offset = o, \
+ .irq_data = d, \
+ .handle = h, \
+ .parent = p, \
+}
+
+struct s3c24xx_irq_of_data {
+ struct s3c24xx_irq_of_ctrl *irq_ctrl;
+ int num_ctrl;
+};
+
+#ifdef CONFIG_CPU_S3C2410
+static struct s3c24xx_irq_of_ctrl s3c2410_ctrl[] = {
+ S3C24XX_IRQCTRL("intc", 0, init_s3c2410base, &main_intc, NULL),
+ S3C24XX_IRQCTRL("subintc", 0x18, init_s3c2410subint, NULL, &main_intc),
+};
+
+static struct s3c24xx_irq_of_data s3c2410_irq_data = {
+ .irq_ctrl = s3c2410_ctrl,
+ .num_ctrl = ARRAY_SIZE(s3c2410_ctrl),
+};
+#endif
+
+#ifdef CONFIG_CPU_S3C2412
+static struct s3c24xx_irq_of_ctrl s3c2412_ctrl[] = {
+ S3C24XX_IRQCTRL("intc", 0, init_s3c2412base, &main_intc, NULL),
+ S3C24XX_IRQCTRL("subintc", 0x18, init_s3c2412subint, NULL, &main_intc),
+};
+
+static struct s3c24xx_irq_of_data s3c2412_irq_data = {
+ .irq_ctrl = s3c2412_ctrl,
+ .num_ctrl = ARRAY_SIZE(s3c2412_ctrl),
+};
+#endif
+
+#ifdef CONFIG_CPU_S3C2416
+static struct s3c24xx_irq_of_ctrl s3c2416_ctrl[] = {
+ S3C24XX_IRQCTRL("intc", 0, init_s3c2416base, &main_intc, NULL),
+ S3C24XX_IRQCTRL("subintc", 0x18, init_s3c2416subint, NULL, &main_intc),
+ S3C24XX_IRQCTRL("intc2", 0x40, init_s3c2416_second, &main_intc2, NULL),
+};
+
+static struct s3c24xx_irq_of_data s3c2416_irq_data = {
+ .irq_ctrl = s3c2416_ctrl,
+ .num_ctrl = ARRAY_SIZE(s3c2416_ctrl),
+};
+#endif
+
+#ifdef CONFIG_CPU_S3C2440
+static struct s3c24xx_irq_of_ctrl s3c2440_ctrl[] = {
+ S3C24XX_IRQCTRL("intc", 0, init_s3c2440base, &main_intc, NULL),
+ S3C24XX_IRQCTRL("subintc", 0x18, init_s3c2440subint, NULL, &main_intc),
+};
+
+static struct s3c24xx_irq_of_data s3c2440_irq_data = {
+ .irq_ctrl = s3c2440_ctrl,
+ .num_ctrl = ARRAY_SIZE(s3c2440_ctrl),
+};
+#endif
+
+#ifdef CONFIG_CPU_S3C2442
+static struct s3c24xx_irq_of_ctrl s3c2442_ctrl[] = {
+ S3C24XX_IRQCTRL("intc", 0, init_s3c2442base, &main_intc, NULL),
+ S3C24XX_IRQCTRL("subintc", 0x18, init_s3c2442subint, NULL, &main_intc),
+};
+
+static struct s3c24xx_irq_of_data s3c2442_irq_data = {
+ .irq_ctrl = s3c2442_ctrl,
+ .num_ctrl = ARRAY_SIZE(s3c2442_ctrl),
+};
+#endif
+
+#ifdef CONFIG_CPU_S3C2443
+static struct s3c24xx_irq_of_ctrl s3c2443_ctrl[] = {
+ S3C24XX_IRQCTRL("intc", 0, init_s3c2443base, &main_intc, NULL),
+ S3C24XX_IRQCTRL("subintc", 0x18, init_s3c2443subint, NULL, &main_intc),
+};
+
+static struct s3c24xx_irq_of_data s3c2443_irq_data = {
+ .irq_ctrl = s3c2443_ctrl,
+ .num_ctrl = ARRAY_SIZE(s3c2443_ctrl),
+};
+#endif
+
+static const struct of_device_id intc_list[] = {
+#ifdef CONFIG_CPU_S3C2410
+ { .compatible = "samsung,s3c2410-irq", .data = &s3c2410_irq_data },
+#endif
+#ifdef CONFIG_CPU_S3C2412
+ { .compatible = "samsung,s3c2412-irq", .data = &s3c2412_irq_data },
+#endif
+#ifdef CONFIG_CPU_S3C2416
+ { .compatible = "samsung,s3c2416-irq", .data = &s3c2416_irq_data },
+#endif
+#ifdef CONFIG_CPU_S3C2440
+ { .compatible = "samsung,s3c2440-irq", .data = &s3c2440_irq_data },
+#endif
+#ifdef CONFIG_CPU_S3C2442
+ { .compatible = "samsung,s3c2442-irq", .data = &s3c2442_irq_data },
+#endif
+#ifdef CONFIG_CPU_S3C2443
+ { .compatible = "samsung,s3c2443-irq", .data = &s3c2443_irq_data },
+#endif
+ {},
+};
+
+int __init s3c24xx_init_intc_of(struct device_node *np,
+ struct device_node *interrupt_parent)
+{
+ const struct of_device_id *match;
+ const struct s3c24xx_irq_of_data *ctrl_data;
+ struct device_node *intc_node;
+ struct s3c24xx_irq_of_ctrl *ctrl;
+ struct s3c_irq_intc *intc;
+ void __iomem *reg_base;
+ int i;
+
+ match = of_match_node(intc_list, np);
+ if (!match) {
+ pr_err("irq-s3c24xx: could not find matching irqdata\n");
+ return -EINVAL;
+ }
+
+ ctrl_data = match->data;
+
+ reg_base = of_iomap(np, 0);
+ if (!reg_base) {
+ pr_err("irq-s3c24xx: could not map irq memory\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < ctrl_data->num_ctrl; i++) {
+ ctrl = &ctrl_data->irq_ctrl[i];
+
+ intc_node = of_find_node_by_name(np, ctrl->name);
+ if (!intc_node) {
+ pr_debug("irq: no device node for %s\n",
+ ctrl->name);
+ continue;
+ }
+
+ intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
+ if (!intc) {
+ of_node_put(intc_node);
+ return -ENOMEM;
+ }
+
+ pr_debug("irq: found controller %s\n", ctrl->name);
+
+ intc->irqs = ctrl->irq_data;
+
+ if (ctrl->parent) {
+ if (*(ctrl->parent)) {
+ intc->parent = *(ctrl->parent);
+ } else {
+ pr_warn("irq: parent of %s missing\n",
+ ctrl->name);
+ kfree(intc);
+ of_node_put(intc_node);
+ continue;
+ }
+ }
+
+ if (!ctrl->parent) {
+ intc->reg_pending = reg_base + ctrl->offset;
+ intc->reg_mask = reg_base + ctrl->offset + 0x08;
+ intc->reg_intpnd = reg_base + ctrl->offset + 0x10;
+ } else {
+ intc->reg_pending = reg_base + ctrl->offset;
+ intc->reg_mask = reg_base + ctrl->offset + 0x4;
+ }
+
+ /* now that all the data is complete, init the irq-domain */
+ s3c24xx_clear_intc(intc);
+ intc->domain = irq_domain_add_linear(intc_node, 32,
+ &s3c24xx_irq_ops, intc);
+ if (!intc->domain) {
+ pr_err("irq: could not create irq-domain\n");
+ kfree(intc);
+ of_node_put(intc_node);
+ continue;
+ }
+
+ if (ctrl->handle)
+ *(ctrl->handle) = intc;
+ }
+
+ set_handle_irq(s3c24xx_handle_irq);
+
+ return 0;
+}
+
+IRQCHIP_DECLARE(s3c2410_irq, "samsung,s3c2410-irq", s3c24xx_init_intc_of);
+IRQCHIP_DECLARE(s3c2412_irq, "samsung,s3c2412-irq", s3c24xx_init_intc_of);
+IRQCHIP_DECLARE(s3c2416_irq, "samsung,s3c2416-irq", s3c24xx_init_intc_of);
+IRQCHIP_DECLARE(s3c2440_irq, "samsung,s3c2440-irq", s3c24xx_init_intc_of);
+IRQCHIP_DECLARE(s3c2442_irq, "samsung,s3c2442-irq", s3c24xx_init_intc_of);
+IRQCHIP_DECLARE(s3c2443_irq, "samsung,s3c2443-irq", s3c24xx_init_intc_of);
+IRQCHIP_DECLARE(s3c2450_irq, "samsung,s3c2450-irq", s3c24xx_init_intc_of);
+#endif
--
1.7.2.3
next prev parent reply other threads:[~2013-03-17 13:08 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-17 13:04 [PATCH v3 0/6] move s3c24xx-irq to drivers/irqchip and add dt support Heiko Stübner
2013-03-17 13:04 ` Heiko Stübner
[not found] ` <201303171404.06146.heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
2013-03-17 13:04 ` [PATCH v3 1/6] ARM: S3C24XX: move irq driver to drivers/irqchip Heiko Stübner
2013-03-17 13:04 ` Heiko Stübner
2013-03-17 13:05 ` [PATCH v3 2/6] irqchip: s3c24xx: fix comments on some camera interrupts Heiko Stübner
2013-03-17 13:05 ` Heiko Stübner
2013-03-17 13:06 ` [PATCH v3 3/6] irqchip: s3c24xx: fix irqlist of second s3c2416 controller Heiko Stübner
2013-03-17 13:06 ` Heiko Stübner
2013-03-17 13:07 ` [PATCH v3 4/6] irqchip: s3c24xx: use irq_create_mapping for parent irqs Heiko Stübner
2013-03-17 13:07 ` Heiko Stübner
2013-03-17 13:07 ` Heiko Stübner [this message]
2013-03-17 13:07 ` [PATCH v3 5/6] irqchip: s3c24xx: add devicetree support Heiko Stübner
2013-03-17 22:37 ` Heiko Stübner
2013-03-17 22:37 ` Heiko Stübner
2013-03-18 18:59 ` Rob Herring
2013-03-18 18:59 ` Rob Herring
2013-03-17 13:09 ` [PATCH v3 6/6] irqchip: s3c24xx: add s3c2450 interrupt definitions Heiko Stübner
2013-03-17 13:09 ` Heiko Stübner
2013-03-18 15:54 ` Rob Herring
2013-03-18 15:54 ` Rob Herring
2013-03-18 16:53 ` Heiko Stübner
2013-03-18 16:53 ` Heiko Stübner
[not found] ` <201303181753.16547.heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
2013-03-18 22:14 ` Rob Herring
2013-03-18 22:14 ` Rob Herring
2013-03-18 22:21 ` Arnd Bergmann
2013-03-18 22:21 ` Arnd Bergmann
[not found] ` <514791DC.9070600-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2013-03-18 23:34 ` Heiko Stübner
2013-03-18 23:34 ` Heiko Stübner
2013-03-19 2:28 ` Rob Herring
2013-03-19 2:28 ` Rob Herring
2013-03-19 18:38 ` Heiko Stübner
2013-03-19 18:38 ` Heiko Stübner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201303171407.59128.heiko@sntech.de \
--to=heiko@sntech.de \
--cc=devicetree-discuss@lists.ozlabs.org \
--cc=grant.likely@secretlab.ca \
--cc=kgene.kim@samsung.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-samsung-soc@vger.kernel.org \
--cc=rob.herring@calxeda.com \
--cc=thomas.abraham@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.