* [RFC 0/2] ARM: S3C24XX: Add devicetree support
@ 2012-11-25 0:45 Heiko Stübner
2012-11-25 0:47 ` [RFC 1/2] ARM: S3C24XX: add devicetree support for interrupts Heiko Stübner
2012-11-25 0:48 ` [RFC 2/2] ARM: S3C24XX: Add devicetree support and dt-board file for s3c2416 SoCs Heiko Stübner
0 siblings, 2 replies; 10+ messages in thread
From: Heiko Stübner @ 2012-11-25 0:45 UTC (permalink / raw)
To: linux-arm-kernel
This series builts on my not-yet-accepted irq rework and provides the
last bits to use devicetree on s3c2416 boards. It also requires the
patch "serial: samsung: add devicetree properties for non-Exynos SoCs"
which adds the missing device names to the mapping table.
Thanks to the work of other developers all the drivers used already
support dt, so only the interrupt controllers and board support was
missing.
This of course easily expandable to the other s3c24xx SoCs in the
future.
So, while the underlying irq rework might still need changes, I'd really
like to get feedback, especially on the irq controller bindings.
The whole thing boots and runs sucessfully on my s3c2416 based board,
which shares most caracteristics and all the used gpio with the smdk2416.
Heiko Stuebner (2):
ARM: S3C24XX: add devicetree support for interrupts
ARM: S3C24XX: Add devicetree support and dt-board file for s3c2416 SoCs
.../interrupt-controller/samsung,s3c24xx-irq.txt | 57 ++++++
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/s3c2416-smdk2416.dts | 79 ++++++++
arch/arm/boot/dts/s3c2416.dtsi | 193 +++++++++++++++++++
arch/arm/boot/dts/s3c24xx.dtsi | 158 ++++++++++++++++
arch/arm/mach-s3c24xx/Kconfig | 9 +
arch/arm/mach-s3c24xx/Makefile | 1 +
arch/arm/mach-s3c24xx/common.h | 1 +
arch/arm/mach-s3c24xx/mach-s3c2416-dt.c | 91 +++++++++
arch/arm/plat-s3c24xx/irq.c | 197 ++++++++++++++++++++
10 files changed, 787 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24xx-irq.txt
create mode 100644 arch/arm/boot/dts/s3c2416-smdk2416.dts
create mode 100644 arch/arm/boot/dts/s3c2416.dtsi
create mode 100644 arch/arm/boot/dts/s3c24xx.dtsi
create mode 100644 arch/arm/mach-s3c24xx/mach-s3c2416-dt.c
--
1.7.2.3
^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC 1/2] ARM: S3C24XX: add devicetree support for interrupts
2012-11-25 0:45 [RFC 0/2] ARM: S3C24XX: Add devicetree support Heiko Stübner
@ 2012-11-25 0:47 ` Heiko Stübner
2012-11-26 11:03 ` Thomas Abraham
2012-11-25 0:48 ` [RFC 2/2] ARM: S3C24XX: Add devicetree support and dt-board file for s3c2416 SoCs Heiko Stübner
1 sibling, 1 reply; 10+ messages in thread
From: Heiko Stübner @ 2012-11-25 0:47 UTC (permalink / raw)
To: linux-arm-kernel
This adds devicetree parsing of the controller-data for the
interrupt controllers on S3C24XX architectures.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
.../interrupt-controller/samsung,s3c24xx-irq.txt | 57 ++++++
arch/arm/mach-s3c24xx/common.h | 1 +
arch/arm/plat-s3c24xx/irq.c | 197 ++++++++++++++++++++
3 files changed, 255 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..c637637
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24xx-irq.txt
@@ -0,0 +1,57 @@
+Samsung S3C24XX Interrupt Controllers
+
+The S3C24XX SoCs contain custom set of interrupt controllers providing a
+varying number of interrupt sources.
+
+The set consists of a main- and a sub-controller as well as a controller
+for the external interrupts and on newer SoCs even a second main controller.
+
+The bit-to-interrupt and parent mapping of the controllers is not fixed
+over all SoCs and therefore must be defined in the controller description.
+
+Required properties:
+- compatible: Compatible property value should be "samsung,s3c24xx-irq".
+
+- reg: Physical base address of the controller and length of memory mapped
+ region.
+
+- 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.
+
+- s3c24xx,irqlist : List of irqtypes found on this controller as
+ two-value pairs consisting of irqtype and parent-irq
+
+ parent-irq is always the list position of the irq in the irqlist
+ of the parent controller (0..31)
+
+ irqtypes are:
+ - 0 .. none
+ - 1 .. external interrupts in the main register (GPF0 .. GPF3)
+ - 2 .. edge irq in the main register
+ - 3 .. for parent-irqs, that have sub-irqs in child controllers
+ - 4 .. level irqs in the sub-register
+ - 5 .. edge irqs in the sub-register
+ - 6 .. external irqs in the external irq register (starting with GPF4)
+ - 7 .. irq in the second base irq controller of S3C2416/S3C2450 SoCs
+
+Optional properties:
+- interrupt_parent : The parent interrupt controller
+
+Example:
+
+ intc2:interrupt-controller at 4a000040 {
+ compatible = "samsung,s3c24xx-irq";
+ reg = <0x4a000040 0x18>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ s3c24xx,irqlist = <7 0 /* 2D */
+ 7 0 /* IIC1 */
+ 0 0 /* reserved */
+ 0 0 /* reserved */
+ 7 0 /* PCM0 */
+ 7 0 /* PCM1 */
+ 7 0 /* I2S0 */
+ 7 0>; /* I2S1 */
+ };
diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c24xx/common.h
index ed6276f..7a7b770 100644
--- a/arch/arm/mach-s3c24xx/common.h
+++ b/arch/arm/mach-s3c24xx/common.h
@@ -16,5 +16,6 @@ void s3c2410_restart(char mode, const char *cmd);
void s3c244x_restart(char mode, const char *cmd);
extern struct syscore_ops s3c24xx_irq_syscore_ops;
+extern void s3c24xx_init_irq_of(void);
#endif /* __ARCH_ARM_MACH_S3C24XX_COMMON_H */
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index 0510627..4f8fe4a 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -25,6 +25,9 @@
#include <linux/slab.h>
#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
@@ -956,3 +959,197 @@ void __init s3c2443_init_irq(void)
s3c24xx_init_irq();
}
#endif
+
+#ifdef CONFIG_OF
+static int __init s3c24xx_init_intc_of(struct device_node *np,
+ struct device_node *interrupt_parent)
+{
+ struct s3c_irq_intc *intc;
+ struct s3c_irq_intc *parent;
+ struct s3c_irq_data *irq_data;
+ struct property *intc_prop;
+ int irq_num = 0, irq_start = 0, irq_offset = 0;
+ int ret, i, cnt;
+ const __be32 *p;
+ u32 val;
+
+ intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
+ if (!intc)
+ return -ENOMEM;
+
+ p = of_get_address(np, 0, NULL, NULL);
+ if (!p) {
+ pr_err("irq: register address missing\n");
+ ret = -EINVAL;
+ goto err_addr;
+ }
+
+ /* select the correct data for the controller.
+ * Need to hard code the irq num start and offset
+ * to preserve the static mapping for now
+ */
+ switch (of_translate_address(np, p)) {
+ case 0x4a000000:
+ pr_debug("irq: found main intc\n");
+ intc->reg_pending = S3C2410_SRCPND;
+ intc->reg_intpnd = S3C2410_INTPND;
+ intc->reg_mask = S3C2410_INTMSK;
+ irq_num = 32;
+ irq_start = S3C2410_IRQ(0);
+ irq_offset = 0;
+ break;
+ case 0x560000a4:
+ pr_debug("irq: found extintc\n");
+ intc->reg_pending = S3C2410_EINTPEND;
+ intc->reg_mask = S3C2410_EINTMASK;
+ irq_num = 20;
+ irq_start = S3C2410_IRQ(32);
+ irq_offset = 4;
+ break;
+ case 0x4a000018:
+ pr_debug("irq: found subintc\n");
+ intc->reg_pending = S3C2410_SUBSRCPND;
+ intc->reg_mask = S3C2410_INTSUBMSK;
+ irq_num = 29;
+ irq_start = S3C2410_IRQSUB(0);
+ irq_offset = 0;
+ break;
+ case 0x4a000040:
+ pr_debug("irq: found intc2\n");
+ intc->reg_pending = S3C2416_SRCPND2;
+ intc->reg_intpnd = S3C2416_INTPND2;
+ intc->reg_mask = S3C2416_INTMSK2;
+ irq_num = 8;
+ irq_start = S3C2416_IRQ(0);
+ irq_offset = 0;
+ break;
+ case 0:
+ pr_err("irq: couldn't translate address\n");
+ ret = -EINVAL;
+ goto err_addr;
+ default:
+ pr_err("irq: unsupported controller address\n");
+ ret = -EINVAL;
+ goto err_addr;
+ }
+
+ irq_data = kzalloc(sizeof(struct s3c_irq_data) * 32, GFP_KERNEL);
+ if (!irq_data) {
+ ret = -ENOMEM;
+ goto err_addr;
+ }
+
+ cnt = 0;
+ intc_prop = of_find_property(np, "s3c24xx,irqlist", NULL);
+ if (!intc_prop) {
+ pr_err("irq: irqlist not found\n");
+ ret = -EINVAL;
+ goto err_data;
+ }
+
+ /* build the irq_data list */
+ p = NULL;
+ for (i = 0; i < 32; i++) {
+ p = of_prop_next_u32(intc_prop, p, &val);
+
+ /* when we hit the first non-valid element, assume it's
+ * the end of the list. The rest of the fields are
+ * already of type S3C_IRQTYPE_NONE (value 0)
+ */
+ if (!p)
+ break;
+
+ irq_data[i].type = val;
+
+ p = of_prop_next_u32(intc_prop, p, &val);
+ if (!p) {
+ pr_warn("irq: uneven number of elements in irqlist, last value will be dropped\n");
+ irq_data[i].type = 0;
+ break;
+ }
+
+ irq_data[i].parent_irq = val;
+
+ pr_debug("irq: found hwirq %d with type %d and parent %lu\n",
+ i, irq_data[i].type, irq_data[i].parent_irq);
+ cnt++;
+ }
+
+ /* if we haven't found any irq definition@all,
+ * something is very wrong.
+ */
+ if (!cnt) {
+ pr_err("irq: empty irq definition\n");
+ ret = -EINVAL;
+ goto err_data;
+ }
+
+ intc->irqs = irq_data;
+
+ /* put the intc into the dt as property, so we can access it from
+ * as the interrupt_parent later
+ */
+
+ intc_prop = kzalloc(sizeof(struct property), GFP_KERNEL);
+ if (!intc_prop) {
+ ret = -ENOMEM;
+ goto err_data;
+ }
+
+ intc_prop->name = kstrdup("s3c-irq-intc", GFP_KERNEL);
+ intc_prop->value = intc;
+ intc_prop->length = sizeof(struct s3c_irq_intc);
+
+ ret = prom_add_property(np, intc_prop);
+ if (ret) {
+ pr_err("irq: failed to add dt property\n");
+ goto err_prop;
+ }
+
+ /* set the parent relationship */
+ if (interrupt_parent) {
+ parent = (struct s3c_irq_intc *)of_get_property(
+ interrupt_parent, "s3c-irq-intc", NULL);
+ if (!parent) {
+ pr_err("irq: no parent for non-root controller found\n");
+ goto err_domain;
+ }
+
+ intc->parent = parent;
+ }
+
+ /* now that all the data is complete, init the irq-domain */
+ s3c24xx_clear_intc(intc);
+ intc->domain = irq_domain_add_legacy(np, irq_num, irq_start,
+ irq_offset, &s3c24xx_irq_ops,
+ intc);
+ if (!intc->domain) {
+ pr_err("irq: could not create irq-domain\n");
+ ret = -EINVAL;
+ goto err_domain;
+ }
+
+ return 0;
+
+err_domain:
+ prom_remove_property(np, intc_prop);
+err_prop:
+ kfree(intc_prop);
+err_data:
+ kfree(irq_data);
+err_addr:
+ kfree(intc);
+
+ return ret;
+}
+
+static const struct of_device_id s3c24xx_irq_match[] __initconst = {
+ { .compatible = "samsung,s3c24xx-irq", .data = s3c24xx_init_intc_of, },
+ { /* sentinel */ }
+};
+
+void __init s3c24xx_init_irq_of(void)
+{
+ of_irq_init(s3c24xx_irq_match);
+}
+#endif
--
1.7.2.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFC 2/2] ARM: S3C24XX: Add devicetree support and dt-board file for s3c2416 SoCs
2012-11-25 0:45 [RFC 0/2] ARM: S3C24XX: Add devicetree support Heiko Stübner
2012-11-25 0:47 ` [RFC 1/2] ARM: S3C24XX: add devicetree support for interrupts Heiko Stübner
@ 2012-11-25 0:48 ` Heiko Stübner
1 sibling, 0 replies; 10+ messages in thread
From: Heiko Stübner @ 2012-11-25 0:48 UTC (permalink / raw)
To: linux-arm-kernel
This adds a board file and the devicetree source files to support boards
using the Samsung S3C2416 SoC.
The dt source files contain the definitions generic to all S3C24XX SoCs
in the s3c24xx.dtsi file which then gets extendes with S3C2416 specific
definitions.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/s3c2416-smdk2416.dts | 79 +++++++++++++
arch/arm/boot/dts/s3c2416.dtsi | 193 +++++++++++++++++++++++++++++++
arch/arm/boot/dts/s3c24xx.dtsi | 158 +++++++++++++++++++++++++
arch/arm/mach-s3c24xx/Kconfig | 9 ++
arch/arm/mach-s3c24xx/Makefile | 1 +
arch/arm/mach-s3c24xx/mach-s3c2416-dt.c | 91 +++++++++++++++
7 files changed, 532 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/boot/dts/s3c2416-smdk2416.dts
create mode 100644 arch/arm/boot/dts/s3c2416.dtsi
create mode 100644 arch/arm/boot/dts/s3c24xx.dtsi
create mode 100644 arch/arm/mach-s3c24xx/mach-s3c2416-dt.c
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 8cfd013..d8256f0 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -89,6 +89,7 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
am335x-bone.dtb
dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
dtb-$(CONFIG_ARCH_U8500) += snowball.dtb
+dtb-$(CONFIG_ARCH_S3C24XX) += s3c2416-smdk2416.dtb
dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \
r8a7740-armadillo800eva.dtb \
sh73a0-kzm9g.dtb \
diff --git a/arch/arm/boot/dts/s3c2416-smdk2416.dts b/arch/arm/boot/dts/s3c2416-smdk2416.dts
new file mode 100644
index 0000000..6863be6
--- /dev/null
+++ b/arch/arm/boot/dts/s3c2416-smdk2416.dts
@@ -0,0 +1,79 @@
+/*
+ * SAMSUNG SMDK2416 board device tree source
+ *
+ * Copyright (c) 2012 Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+/include/ "s3c2416.dtsi"
+
+/ {
+ model = "SMDK2416";
+ compatible = "samsung,s3c2416";
+
+ memory {
+ reg = <0x30000000 0x8000000>;
+ };
+
+ sdhci at 4AC00000 {
+ bus-width = <4>;
+ gpios = <&gpe 5 2 0>, /* clock line */
+ <&gpe 6 2 0>, /* command line */
+ <&gpe 7 2 0>, /* data line 0 */
+ <&gpe 8 2 0>, /* data line 1 */
+ <&gpe 9 2 0>, /* data line 2 */
+ <&gpe 10 2 0>; /* data line 3 */
+ cd-gpios = <&gpf 1 2 2>;
+ cd-inverted;
+ status = "okay";
+ };
+
+ sdhci at 4A800000 {
+ bus-width = <4>;
+ gpios = <&gpl 9 2 0>, /* clock line */
+ <&gpl 8 2 0>, /* command line */
+ <&gpl 0 2 0>, /* data line 0 */
+ <&gpl 1 2 0>, /* data line 1 */
+ <&gpl 2 2 0>, /* data line 2 */
+ <&gpl 3 2 0>; /* data line 3 */
+
+ broken-cd;
+ status = "okay";
+ };
+
+ serial at 50000000 {
+ status = "okay";
+ };
+
+ serial at 50004000 {
+ status = "okay";
+ };
+
+ serial at 50008000 {
+ status = "okay";
+ };
+
+ serial at 5000C000 {
+ status = "okay";
+ };
+
+ watchdog at 53000000 {
+ status = "okay";
+ };
+
+ rtc at 57000000 {
+ status = "okay";
+ };
+
+ i2c at 54000000 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <100000>;
+ gpios = <&gpe 15 2 0>, /* SDA */
+ <&gpe 14 2 0>; /* SCL */
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/s3c2416.dtsi b/arch/arm/boot/dts/s3c2416.dtsi
new file mode 100644
index 0000000..6663f28
--- /dev/null
+++ b/arch/arm/boot/dts/s3c2416.dtsi
@@ -0,0 +1,193 @@
+/*
+ * Samsung's S3C2416 SoC device tree source
+ *
+ * Copyright (c) 2012 Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/include/ "s3c24xx.dtsi"
+
+/ {
+ model = "Samsung S3C2416 SoC";
+ compatible = "samsung,s3c2416";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu at 0 {
+ compatible = "arm,arm926ejs";
+ reg = <0>;
+ };
+ };
+
+ intc:interrupt-controller at 4a000000 {
+ s3c24xx,irqlist = <1 0 /* EINT0 */
+ 1 0 /* EINT1 */
+ 1 0 /* EINT2 */
+ 1 0 /* EINT3 */
+ 3 0 /* EINT4to7 */
+ 3 0 /* EINT8to23 */
+ 0 0 /* reserved */
+ 2 0 /* nBATT_FLT */
+ 2 0 /* TICK */
+ 3 0 /* WDT/AC97 */
+ 2 0 /* TIMER0 */
+ 2 0 /* TIMER1 */
+ 2 0 /* TIMER2 */
+ 2 0 /* TIMER3 */
+ 2 0 /* TIMER4 */
+ 3 0 /* UART2 */
+ 3 0 /* LCD */
+ 3 0 /* DMA */
+ 3 0 /* UART3 */
+ 0 0 /* reserved */
+ 2 0 /* SDI1 */
+ 2 0 /* SDI0 */
+ 2 0 /* SPI0 */
+ 3 0 /* UART1 */
+ 2 0 /* NAND */
+ 2 0 /* USBD */
+ 2 0 /* USBH */
+ 2 0 /* IIC */
+ 3 0 /* UART0 */
+ 0 0 /* reserved */
+ 2 0 /* RTC */
+ 3 0>; /* ADCPARENT */
+ };
+
+ subintc:interrupt-controller at 4a000018 {
+ s3c24xx,irqlist = <4 28 /* UART0-RX */
+ 4 28 /* UART0-TX */
+ 4 28 /* UART0-ERR */
+ 4 23 /* UART1-RX */
+ 4 23 /* UART1-TX */
+ 4 23 /* UART1-ERR */
+ 4 15 /* UART2-RX */
+ 4 15 /* UART2-TX */
+ 4 15 /* UART2-ERR */
+ 5 31 /* TC */
+ 5 31 /* ADC */
+ 0 0 /* reserved */
+ 0 0 /* reserved */
+ 0 0 /* reserved */
+ 0 0 /* reserved */
+ 4 16 /* LCD2 */
+ 4 16 /* LCD3 */
+ 4 16 /* LCD4 */
+ 4 17 /* DMA0 */
+ 4 17 /* DMA1 */
+ 4 17 /* DMA2 */
+ 4 17 /* DMA3 */
+ 4 17 /* DMA4 */
+ 4 17 /* DMA5 */
+ 4 18 /* UART3-RX */
+ 4 18 /* UART3-TX */
+ 4 18 /* UART3-ERR */
+ 4 9 /* WDT */
+ 4 9>; /* AC97 */
+ };
+
+ intc2:interrupt-controller at 4a000040 {
+ compatible = "samsung,s3c24xx-irq";
+ reg = <0x4a000040 0x18>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ s3c24xx,irqlist = <7 0 /* 2D */
+ 7 0 /* IIC1 */
+ 0 0 /* reserved */
+ 0 0 /* reserved */
+ 7 0 /* PCM0 */
+ 7 0 /* PCM1 */
+ 7 0 /* I2S0 */
+ 7 0>; /* I2S1 */
+ };
+
+ serial at 50000000 {
+ compatible = "samsung,s3c2440-uart";
+ status = "disabled";
+ };
+
+ serial at 50004000 {
+ compatible = "samsung,s3c2440-uart";
+ status = "disabled";
+ };
+
+ serial at 50008000 {
+ compatible = "samsung,s3c2440-uart";
+ status = "disabled";
+ };
+
+ serial at 5000C000 {
+ compatible = "samsung,s3c2440-uart";
+ reg = <0x5000C000 0x4000>;
+ interrupt-parent = <&subintc>;
+ interrupts = <24 0>, <25 0>;
+ status = "disabled";
+ };
+
+ sdhci at 4AC00000 {
+ compatible = "samsung,s3c6410-sdhci";
+ reg = <0x4AC00000 0x100>;
+ interrupt-parent = <&intc>;
+ interrupts = <21 0>;
+ status = "disabled";
+ };
+
+ sdhci at 4A800000 {
+ compatible = "samsung,s3c6410-sdhci";
+ reg = <0x4A800000 0x100>;
+ interrupt-parent = <&intc>;
+ interrupts = <20 0>;
+ status = "disabled";
+ };
+
+ watchdog at 53000000 {
+ interrupt-parent = <&subintc>;
+ interrupts = <27 0>;
+ };
+
+ rtc at 57000000 {
+ compatible = "samsung,s3c2416-rtc";
+ };
+
+ i2c at 54000000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x54000000 0x100>;
+ interrupt-parent = <&intc>;
+ interrupts = <27 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ gpio-controllers {
+ gpj: gpio-controller at 560000D0 {
+ compatible = "samsung,s3c24xx-gpio";
+ reg = <0x560000D0 0x10>;
+ #gpio-cells = <3>;
+ };
+
+ gpk: gpio-controller at 560000E0 {
+ compatible = "samsung,s3c24xx-gpio";
+ reg = <0x560000E0 0x10>;
+ #gpio-cells = <3>;
+ };
+
+ gpl: gpio-controller at 560000F0 {
+ compatible = "samsung,s3c24xx-gpio";
+ reg = <0x560000F0 0x10>;
+ #gpio-cells = <3>;
+ };
+
+ gpm: gpio-controller at 56000100 {
+ compatible = "samsung,s3c24xx-gpio";
+ reg = <0x56000100 0x10>;
+ #gpio-cells = <3>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/s3c24xx.dtsi b/arch/arm/boot/dts/s3c24xx.dtsi
new file mode 100644
index 0000000..8126c4f
--- /dev/null
+++ b/arch/arm/boot/dts/s3c24xx.dtsi
@@ -0,0 +1,158 @@
+/*
+ * Samsung's S3C24XX family device tree source
+ *
+ * Copyright (c) 2012 Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "Samsung S3C24XX SoC family";
+
+ intc:interrupt-controller at 4a000000 {
+ compatible = "samsung,s3c24xx-irq";
+ reg = <0x4a000000 0x18>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ extintc:interrupt-controller at 560000a4 {
+ compatible = "samsung,s3c24xx-irq";
+ reg = <0x560000a4 0x8>;
+ interrupt-controller;
+ interrupt-parent = <&intc>;
+ #interrupt-cells = <2>;
+
+ s3c24xx,irqlist = <0 0 /* reserved */
+ 0 0 /* reserved */
+ 0 0 /* reserved */
+ 0 0 /* reserved */
+ 6 4 /* EINT4 */
+ 6 4 /* EINT5 */
+ 6 4 /* EINT6 */
+ 6 4 /* EINT7 */
+ 6 5 /* EINT8 */
+ 6 5 /* EINT9 */
+ 6 5 /* EINT10 */
+ 6 5 /* EINT11 */
+ 6 5 /* EINT12 */
+ 6 5 /* EINT13 */
+ 6 5 /* EINT14 */
+ 6 5 /* EINT15 */
+ 6 5 /* EINT16 */
+ 6 5 /* EINT17 */
+ 6 5 /* EINT18 */
+ 6 5 /* EINT19 */
+ 6 5 /* EINT20 */
+ 6 5 /* EINT21 */
+ 6 5 /* EINT22 */
+ 6 5>; /* EINT23 */
+ };
+
+ subintc:interrupt-controller at 4a000018 {
+ compatible = "samsung,s3c24xx-irq";
+ reg = <0x4a000018 0x8>;
+ interrupt-controller;
+ interrupt-parent = <&intc>;
+ #interrupt-cells = <2>;
+ };
+
+ gpio-controllers {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ gpio-controller;
+ ranges;
+
+ gpa: gpio-controller at 56000000 {
+ compatible = "samsung,s3c24xx-gpio";
+ reg = <0x56000000 0x10>;
+ #gpio-cells = <3>;
+ };
+
+ gpb: gpio-controller at 56000010 {
+ compatible = "samsung,s3c24xx-gpio";
+ reg = <0x56000010 0x10>;
+ #gpio-cells = <3>;
+ };
+
+ gpc: gpio-controller at 56000020 {
+ compatible = "samsung,s3c24xx-gpio";
+ reg = <0x56000020 0x10>;
+ #gpio-cells = <3>;
+ };
+
+ gpd: gpio-controller at 56000030 {
+ compatible = "samsung,s3c24xx-gpio";
+ reg = <0x56000030 0x10>;
+ #gpio-cells = <3>;
+ };
+
+ gpe: gpio-controller at 56000040 {
+ compatible = "samsung,s3c24xx-gpio";
+ reg = <0x56000040 0x10>;
+ #gpio-cells = <3>;
+ };
+
+ gpf: gpio-controller at 56000050 {
+ compatible = "samsung,s3c24xx-gpio";
+ reg = <0x56000050 0x10>;
+ #gpio-cells = <3>;
+ };
+
+ gpg: gpio-controller at 56000060 {
+ compatible = "samsung,s3c24xx-gpio";
+ reg = <0x56000060 0x10>;
+ #gpio-cells = <3>;
+ };
+
+ gph: gpio-controller at 56000070 {
+ compatible = "samsung,s3c24xx-gpio";
+ reg = <0x56000070 0x10>;
+ #gpio-cells = <3>;
+ };
+ };
+
+ serial at 50000000 {
+ compatible = "samsung,s3c2410-uart";
+ reg = <0x50000000 0x4000>;
+ interrupt-parent = <&subintc>;
+ interrupts = <0 0>, <1 0>;
+ status = "disabled";
+ };
+
+ serial at 50004000 {
+ compatible = "samsung,s3c2410-uart";
+ reg = <0x50004000 0x4000>;
+ interrupt-parent = <&subintc>;
+ interrupts = <3 0>, <4 0>;
+ status = "disabled";
+ };
+
+ serial at 50008000 {
+ compatible = "samsung,s3c2410-uart";
+ reg = <0x50008000 0x4000>;
+ interrupt-parent = <&subintc>;
+ interrupts = <6 0>, <7 0>;
+ status = "disabled";
+ };
+
+ watchdog at 53000000 {
+ compatible = "samsung,s3c2410-wdt";
+ reg = <0x53000000 0x100>;
+ interrupt-parent = <&intc>;
+ interrupts = <9 0>;
+ status = "disabled";
+ };
+
+ rtc at 57000000 {
+ compatible = "samsung,s3c2410-rtc";
+ reg = <0x57000000 0x100>;
+ interrupt-parent = <&intc>;
+ interrupts = <30 0>, <8 0>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index 2b6cb5f..ec137db 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -361,6 +361,15 @@ config MACH_SMDK2416
help
Say Y here if you are using an SMDK2416
+config MACH_S3C2416_DT
+ bool "Samsung S3C2416 machine using devicetree"
+ select USE_OF
+ help
+ Machine support for Samsung S3C2416 machines with device tree enabled.
+ Select this if a fdt blob is available for the S3C2416 SoC based board.
+ Note: This is under development and not all peripherals can be supported
+ with this machine file.
+
endif # CPU_S3C2416
if CPU_S3C2440
diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
index 6019b7c..a48ea40 100644
--- a/arch/arm/mach-s3c24xx/Makefile
+++ b/arch/arm/mach-s3c24xx/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_MACH_SMDK2413) += mach-smdk2413.o
obj-$(CONFIG_MACH_VSTMS) += mach-vstms.o
obj-$(CONFIG_MACH_SMDK2416) += mach-smdk2416.o
+obj-$(CONFIG_MACH_S3C2416_DT) += mach-s3c2416-dt.o
obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o
obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o
diff --git a/arch/arm/mach-s3c24xx/mach-s3c2416-dt.c b/arch/arm/mach-s3c24xx/mach-s3c2416-dt.c
new file mode 100644
index 0000000..8ffc8c9
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-s3c2416-dt.c
@@ -0,0 +1,91 @@
+/*
+ * Samsung's S3C2416 flattened device tree enabled machine
+ *
+ * Copyright (c) 2012 Heiko Stuebner <heiko@sntech.de>
+ *
+ * based on mach-exynos/mach-exynos4-dt.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Copyright (c) 2010-2011 Linaro Ltd.
+ * www.linaro.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/of_platform.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/arch.h>
+#include <mach/map.h>
+
+#include <plat/s3c2416.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/regs-serial.h>
+
+#include "common.h"
+
+/*
+ * The following lookup table is used to override device names when devices
+ * are registered from device tree. This is temporarily added to enable
+ * device tree support addition for the S3C2416 architecture.
+ *
+ * For drivers that require platform data to be provided from the machine
+ * file, a platform data pointer can also be supplied along with the
+ * devices names. Usually, the platform data elements that cannot be parsed
+ * from the device tree by the drivers (example: function pointers) are
+ * supplied. But it should be noted that this is a temporary mechanism and
+ * at some point, the drivers should be capable of parsing all the platform
+ * data from the device tree.
+ */
+static const struct of_dev_auxdata s3c2416_auxdata_lookup[] __initconst = {
+ OF_DEV_AUXDATA("samsung,s3c2440-uart", S3C2410_PA_UART0,
+ "s3c2440-uart.0", NULL),
+ OF_DEV_AUXDATA("samsung,s3c2440-uart", S3C2410_PA_UART1,
+ "s3c2440-uart.1", NULL),
+ OF_DEV_AUXDATA("samsung,s3c2440-uart", S3C2410_PA_UART2,
+ "s3c2440-uart.2", NULL),
+ OF_DEV_AUXDATA("samsung,s3c2440-uart", S3C2443_PA_UART3,
+ "s3c2440-uart.3", NULL),
+ OF_DEV_AUXDATA("samsung,s3c6410-sdhci", S3C_PA_HSMMC0,
+ "s3c-sdhci.0", NULL),
+ OF_DEV_AUXDATA("samsung,s3c6410-sdhci", S3C_PA_HSMMC1,
+ "s3c-sdhci.1", NULL),
+ OF_DEV_AUXDATA("samsung,s3c2440-i2c", S3C_PA_IIC,
+ "s3c2440-i2c.0", NULL),
+ {},
+};
+
+static void __init s3c2416_dt_map_io(void)
+{
+ s3c24xx_init_io(NULL, 0);
+ s3c24xx_init_clocks(12000000);
+}
+
+static void __init s3c2416_dt_machine_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table,
+ s3c2416_auxdata_lookup, NULL);
+
+ s3c_pm_init();
+}
+
+static char const *s3c2416_dt_compat[] __initdata = {
+ "samsung,s3c2416",
+ "samsung,s3c2450",
+ NULL
+};
+
+DT_MACHINE_START(S3C2416_DT, "Samsung S3C2416 (Flattened Device Tree)")
+ /* Maintainer: Heiko Stuebner <heiko@sntech.de> */
+ .init_irq = s3c24xx_init_irq_of,
+ .map_io = s3c2416_dt_map_io,
+ .init_machine = s3c2416_dt_machine_init,
+ .timer = &s3c24xx_timer,
+ .dt_compat = s3c2416_dt_compat,
+ .restart = s3c2416_restart,
+MACHINE_END
--
1.7.2.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFC 1/2] ARM: S3C24XX: add devicetree support for interrupts
2012-11-25 0:47 ` [RFC 1/2] ARM: S3C24XX: add devicetree support for interrupts Heiko Stübner
@ 2012-11-26 11:03 ` Thomas Abraham
2012-11-26 12:13 ` Heiko Stübner
0 siblings, 1 reply; 10+ messages in thread
From: Thomas Abraham @ 2012-11-26 11:03 UTC (permalink / raw)
To: linux-arm-kernel
Hi Heiko,
On 25 November 2012 06:17, Heiko St?bner <heiko@sntech.de> wrote:
> This adds devicetree parsing of the controller-data for the
> interrupt controllers on S3C24XX architectures.
>
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> ---
> .../interrupt-controller/samsung,s3c24xx-irq.txt | 57 ++++++
> arch/arm/mach-s3c24xx/common.h | 1 +
> arch/arm/plat-s3c24xx/irq.c | 197 ++++++++++++++++++++
> 3 files changed, 255 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..c637637
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24xx-irq.txt
> @@ -0,0 +1,57 @@
> +Samsung S3C24XX Interrupt Controllers
> +
> +The S3C24XX SoCs contain custom set of interrupt controllers providing a
> +varying number of interrupt sources.
> +
> +The set consists of a main- and a sub-controller as well as a controller
> +for the external interrupts and on newer SoCs even a second main controller.
> +
> +The bit-to-interrupt and parent mapping of the controllers is not fixed
> +over all SoCs and therefore must be defined in the controller description.
> +
> +Required properties:
> +- compatible: Compatible property value should be "samsung,s3c24xx-irq".
> +
> +- reg: Physical base address of the controller and length of memory mapped
> + region.
> +
> +- 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.
> +
> +- s3c24xx,irqlist : List of irqtypes found on this controller as
> + two-value pairs consisting of irqtype and parent-irq
> +
> + parent-irq is always the list position of the irq in the irqlist
> + of the parent controller (0..31)
> +
> + irqtypes are:
> + - 0 .. none
> + - 1 .. external interrupts in the main register (GPF0 .. GPF3)
> + - 2 .. edge irq in the main register
> + - 3 .. for parent-irqs, that have sub-irqs in child controllers
> + - 4 .. level irqs in the sub-register
> + - 5 .. edge irqs in the sub-register
> + - 6 .. external irqs in the external irq register (starting with GPF4)
> + - 7 .. irq in the second base irq controller of S3C2416/S3C2450 SoCs
Instead of defining the type of interrupt controller as above, is it
possible to create multiple device nodes, with each node representing
a type of interrupt controller with a unique compatible string and
corresponding properties. There will be a init function for each type
of interrupt controller. There should be a irq-domain for each of
these different types of interrupt controller. And then, in the device
tree source file, a proper tree like hierarchy of interrupt
controllers can defined (using the interrupt-parent property for each
controller node). The client nodes that generate the interrupt can
specify the parent node and the interrupt number within the parent to
which they generate the interrupt.
Thanks,
Thomas.
> +
> +Optional properties:
> +- interrupt_parent : The parent interrupt controller
> +
> +Example:
> +
> + intc2:interrupt-controller at 4a000040 {
> + compatible = "samsung,s3c24xx-irq";
> + reg = <0x4a000040 0x18>;
> + interrupt-controller;
> + #interrupt-cells = <2>;
> +
> + s3c24xx,irqlist = <7 0 /* 2D */
> + 7 0 /* IIC1 */
> + 0 0 /* reserved */
> + 0 0 /* reserved */
> + 7 0 /* PCM0 */
> + 7 0 /* PCM1 */
> + 7 0 /* I2S0 */
> + 7 0>; /* I2S1 */
> + };
> diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c24xx/common.h
> index ed6276f..7a7b770 100644
> --- a/arch/arm/mach-s3c24xx/common.h
> +++ b/arch/arm/mach-s3c24xx/common.h
> @@ -16,5 +16,6 @@ void s3c2410_restart(char mode, const char *cmd);
> void s3c244x_restart(char mode, const char *cmd);
>
> extern struct syscore_ops s3c24xx_irq_syscore_ops;
> +extern void s3c24xx_init_irq_of(void);
>
> #endif /* __ARCH_ARM_MACH_S3C24XX_COMMON_H */
> diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
> index 0510627..4f8fe4a 100644
> --- a/arch/arm/plat-s3c24xx/irq.c
> +++ b/arch/arm/plat-s3c24xx/irq.c
> @@ -25,6 +25,9 @@
> #include <linux/slab.h>
>
> #include <linux/irqdomain.h>
> +#include <linux/of.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_address.h>
>
> #include <asm/irq.h>
> #include <asm/mach/irq.h>
> @@ -956,3 +959,197 @@ void __init s3c2443_init_irq(void)
> s3c24xx_init_irq();
> }
> #endif
> +
> +#ifdef CONFIG_OF
> +static int __init s3c24xx_init_intc_of(struct device_node *np,
> + struct device_node *interrupt_parent)
> +{
> + struct s3c_irq_intc *intc;
> + struct s3c_irq_intc *parent;
> + struct s3c_irq_data *irq_data;
> + struct property *intc_prop;
> + int irq_num = 0, irq_start = 0, irq_offset = 0;
> + int ret, i, cnt;
> + const __be32 *p;
> + u32 val;
> +
> + intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
> + if (!intc)
> + return -ENOMEM;
> +
> + p = of_get_address(np, 0, NULL, NULL);
> + if (!p) {
> + pr_err("irq: register address missing\n");
> + ret = -EINVAL;
> + goto err_addr;
> + }
> +
> + /* select the correct data for the controller.
> + * Need to hard code the irq num start and offset
> + * to preserve the static mapping for now
> + */
> + switch (of_translate_address(np, p)) {
> + case 0x4a000000:
> + pr_debug("irq: found main intc\n");
> + intc->reg_pending = S3C2410_SRCPND;
> + intc->reg_intpnd = S3C2410_INTPND;
> + intc->reg_mask = S3C2410_INTMSK;
> + irq_num = 32;
> + irq_start = S3C2410_IRQ(0);
> + irq_offset = 0;
> + break;
> + case 0x560000a4:
> + pr_debug("irq: found extintc\n");
> + intc->reg_pending = S3C2410_EINTPEND;
> + intc->reg_mask = S3C2410_EINTMASK;
> + irq_num = 20;
> + irq_start = S3C2410_IRQ(32);
> + irq_offset = 4;
> + break;
> + case 0x4a000018:
> + pr_debug("irq: found subintc\n");
> + intc->reg_pending = S3C2410_SUBSRCPND;
> + intc->reg_mask = S3C2410_INTSUBMSK;
> + irq_num = 29;
> + irq_start = S3C2410_IRQSUB(0);
> + irq_offset = 0;
> + break;
> + case 0x4a000040:
> + pr_debug("irq: found intc2\n");
> + intc->reg_pending = S3C2416_SRCPND2;
> + intc->reg_intpnd = S3C2416_INTPND2;
> + intc->reg_mask = S3C2416_INTMSK2;
> + irq_num = 8;
> + irq_start = S3C2416_IRQ(0);
> + irq_offset = 0;
> + break;
> + case 0:
> + pr_err("irq: couldn't translate address\n");
> + ret = -EINVAL;
> + goto err_addr;
> + default:
> + pr_err("irq: unsupported controller address\n");
> + ret = -EINVAL;
> + goto err_addr;
> + }
> +
> + irq_data = kzalloc(sizeof(struct s3c_irq_data) * 32, GFP_KERNEL);
> + if (!irq_data) {
> + ret = -ENOMEM;
> + goto err_addr;
> + }
> +
> + cnt = 0;
> + intc_prop = of_find_property(np, "s3c24xx,irqlist", NULL);
> + if (!intc_prop) {
> + pr_err("irq: irqlist not found\n");
> + ret = -EINVAL;
> + goto err_data;
> + }
> +
> + /* build the irq_data list */
> + p = NULL;
> + for (i = 0; i < 32; i++) {
> + p = of_prop_next_u32(intc_prop, p, &val);
> +
> + /* when we hit the first non-valid element, assume it's
> + * the end of the list. The rest of the fields are
> + * already of type S3C_IRQTYPE_NONE (value 0)
> + */
> + if (!p)
> + break;
> +
> + irq_data[i].type = val;
> +
> + p = of_prop_next_u32(intc_prop, p, &val);
> + if (!p) {
> + pr_warn("irq: uneven number of elements in irqlist, last value will be dropped\n");
> + irq_data[i].type = 0;
> + break;
> + }
> +
> + irq_data[i].parent_irq = val;
> +
> + pr_debug("irq: found hwirq %d with type %d and parent %lu\n",
> + i, irq_data[i].type, irq_data[i].parent_irq);
> + cnt++;
> + }
> +
> + /* if we haven't found any irq definition at all,
> + * something is very wrong.
> + */
> + if (!cnt) {
> + pr_err("irq: empty irq definition\n");
> + ret = -EINVAL;
> + goto err_data;
> + }
> +
> + intc->irqs = irq_data;
> +
> + /* put the intc into the dt as property, so we can access it from
> + * as the interrupt_parent later
> + */
> +
> + intc_prop = kzalloc(sizeof(struct property), GFP_KERNEL);
> + if (!intc_prop) {
> + ret = -ENOMEM;
> + goto err_data;
> + }
> +
> + intc_prop->name = kstrdup("s3c-irq-intc", GFP_KERNEL);
> + intc_prop->value = intc;
> + intc_prop->length = sizeof(struct s3c_irq_intc);
> +
> + ret = prom_add_property(np, intc_prop);
> + if (ret) {
> + pr_err("irq: failed to add dt property\n");
> + goto err_prop;
> + }
> +
> + /* set the parent relationship */
> + if (interrupt_parent) {
> + parent = (struct s3c_irq_intc *)of_get_property(
> + interrupt_parent, "s3c-irq-intc", NULL);
> + if (!parent) {
> + pr_err("irq: no parent for non-root controller found\n");
> + goto err_domain;
> + }
> +
> + intc->parent = parent;
> + }
> +
> + /* now that all the data is complete, init the irq-domain */
> + s3c24xx_clear_intc(intc);
> + intc->domain = irq_domain_add_legacy(np, irq_num, irq_start,
> + irq_offset, &s3c24xx_irq_ops,
> + intc);
> + if (!intc->domain) {
> + pr_err("irq: could not create irq-domain\n");
> + ret = -EINVAL;
> + goto err_domain;
> + }
> +
> + return 0;
> +
> +err_domain:
> + prom_remove_property(np, intc_prop);
> +err_prop:
> + kfree(intc_prop);
> +err_data:
> + kfree(irq_data);
> +err_addr:
> + kfree(intc);
> +
> + return ret;
> +}
> +
> +static const struct of_device_id s3c24xx_irq_match[] __initconst = {
> + { .compatible = "samsung,s3c24xx-irq", .data = s3c24xx_init_intc_of, },
> + { /* sentinel */ }
> +};
> +
> +void __init s3c24xx_init_irq_of(void)
> +{
> + of_irq_init(s3c24xx_irq_match);
> +}
> +#endif
> --
> 1.7.2.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC 1/2] ARM: S3C24XX: add devicetree support for interrupts
2012-11-26 11:03 ` Thomas Abraham
@ 2012-11-26 12:13 ` Heiko Stübner
2012-11-26 15:23 ` Thomas Abraham
0 siblings, 1 reply; 10+ messages in thread
From: Heiko Stübner @ 2012-11-26 12:13 UTC (permalink / raw)
To: linux-arm-kernel
Hi Thomas,
Am Montag, 26. November 2012, 12:03:22 schrieb Thomas Abraham:
> Hi Heiko,
>
> On 25 November 2012 06:17, Heiko St?bner <heiko@sntech.de> wrote:
> > This adds devicetree parsing of the controller-data for the
> > interrupt controllers on S3C24XX architectures.
> >
> > Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> > ---
> >
> > .../interrupt-controller/samsung,s3c24xx-irq.txt | 57 ++++++
> > arch/arm/mach-s3c24xx/common.h | 1 +
> > arch/arm/plat-s3c24xx/irq.c | 197
> > ++++++++++++++++++++ 3 files changed, 255 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..c637637
> > --- /dev/null
> > +++
> > b/Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24xx
> > -irq.txt @@ -0,0 +1,57 @@
> > +Samsung S3C24XX Interrupt Controllers
> > +
> > +The S3C24XX SoCs contain custom set of interrupt controllers providing a
> > +varying number of interrupt sources.
> > +
> > +The set consists of a main- and a sub-controller as well as a controller
> > +for the external interrupts and on newer SoCs even a second main
> > controller. +
> > +The bit-to-interrupt and parent mapping of the controllers is not fixed
> > +over all SoCs and therefore must be defined in the controller
> > description. +
> > +Required properties:
> > +- compatible: Compatible property value should be "samsung,s3c24xx-irq".
> > +
> > +- reg: Physical base address of the controller and length of memory
> > mapped + region.
> > +
> > +- 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.
> > +
> > +- s3c24xx,irqlist : List of irqtypes found on this controller as
> > + two-value pairs consisting of irqtype and parent-irq
> > +
> > + parent-irq is always the list position of the irq in the irqlist
> > + of the parent controller (0..31)
> > +
> > + irqtypes are:
> > + - 0 .. none
> > + - 1 .. external interrupts in the main register (GPF0 .. GPF3)
> > + - 2 .. edge irq in the main register
> > + - 3 .. for parent-irqs, that have sub-irqs in child controllers
> > + - 4 .. level irqs in the sub-register
> > + - 5 .. edge irqs in the sub-register
> > + - 6 .. external irqs in the external irq register (starting with GPF4)
> > + - 7 .. irq in the second base irq controller of S3C2416/S3C2450 SoCs
>
> Instead of defining the type of interrupt controller as above, is it
> possible to create multiple device nodes, with each node representing
> a type of interrupt controller with a unique compatible string and
> corresponding properties. There will be a init function for each type
> of interrupt controller. There should be a irq-domain for each of
> these different types of interrupt controller. And then, in the device
> tree source file, a proper tree like hierarchy of interrupt
> controllers can defined (using the interrupt-parent property for each
> controller node). The client nodes that generate the interrupt can
> specify the parent node and the interrupt number within the parent to
> which they generate the interrupt.
I'm not sure I understand yet :-). The list describes the types of interrupts
inside the individual controllers.
On all the s3c24xx we have three register sets denoting the main (SRCPND,
INTPND, INTMSK), sub (SUBSRCPEND, INTSUBMASK) and extint (EINTPEND, EINTMASK)
controllers. The bits of these registers are used for quite different irqs.
For example is bit 17 of the main register set used as DMA0 on earlier socs
while the dma interrupts moved to the subint registers for s3c2443 and later.
So the entries in the irqlist describe the needed handlers for the hwirq bits
of the indidual controllers. So in this scheme you set for dt-devices the
interrupt parent to the correct register set and the interrupts field then
matches the bit of the register, according to the datasheet.
When I changed the basic interrupt handling in the previous set, the changed
irq.c can for exmaple be found on [0], I created these lists in the code and
soc specific routines to init them for the still valid non-dt case.
But as dt is about describing the hardware, I found the current solution nice,
because will I only need exactly one dt-init-function for all s3c24xx-socs,
instead of representing all the slight variances in code.
I'm definitly not sure if all the different types of individual irq handlers
are strictly necessary yet, but they represent all the variants that were in
use in the original code.
Heiko
[0] https://github.com/mmind/linux-es600/blob/topic/es600-devel/arch/arm/plat-
s3c24xx/irq.c
> > +
> > +Optional properties:
> > +- interrupt_parent : The parent interrupt controller
> > +
> > +Example:
> > +
> > + intc2:interrupt-controller at 4a000040 {
> > + compatible = "samsung,s3c24xx-irq";
> > + reg = <0x4a000040 0x18>;
> > + interrupt-controller;
> > + #interrupt-cells = <2>;
> > +
> > + s3c24xx,irqlist = <7 0 /* 2D */
> > + 7 0 /* IIC1 */
> > + 0 0 /* reserved */
> > + 0 0 /* reserved */
> > + 7 0 /* PCM0 */
> > + 7 0 /* PCM1 */
> > + 7 0 /* I2S0 */
> > + 7 0>; /* I2S1 */
> > + };
> > diff --git a/arch/arm/mach-s3c24xx/common.h
> > b/arch/arm/mach-s3c24xx/common.h index ed6276f..7a7b770 100644
> > --- a/arch/arm/mach-s3c24xx/common.h
> > +++ b/arch/arm/mach-s3c24xx/common.h
> > @@ -16,5 +16,6 @@ void s3c2410_restart(char mode, const char *cmd);
> >
> > void s3c244x_restart(char mode, const char *cmd);
> >
> > extern struct syscore_ops s3c24xx_irq_syscore_ops;
> >
> > +extern void s3c24xx_init_irq_of(void);
> >
> > #endif /* __ARCH_ARM_MACH_S3C24XX_COMMON_H */
> >
> > diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
> > index 0510627..4f8fe4a 100644
> > --- a/arch/arm/plat-s3c24xx/irq.c
> > +++ b/arch/arm/plat-s3c24xx/irq.c
> > @@ -25,6 +25,9 @@
> >
> > #include <linux/slab.h>
> >
> > #include <linux/irqdomain.h>
> >
> > +#include <linux/of.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_address.h>
> >
> > #include <asm/irq.h>
> > #include <asm/mach/irq.h>
> >
> > @@ -956,3 +959,197 @@ void __init s3c2443_init_irq(void)
> >
> > s3c24xx_init_irq();
> >
> > }
> > #endif
> >
> > +
> > +#ifdef CONFIG_OF
> > +static int __init s3c24xx_init_intc_of(struct device_node *np,
> > + struct device_node
> > *interrupt_parent) +{
> > + struct s3c_irq_intc *intc;
> > + struct s3c_irq_intc *parent;
> > + struct s3c_irq_data *irq_data;
> > + struct property *intc_prop;
> > + int irq_num = 0, irq_start = 0, irq_offset = 0;
> > + int ret, i, cnt;
> > + const __be32 *p;
> > + u32 val;
> > +
> > + intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
> > + if (!intc)
> > + return -ENOMEM;
> > +
> > + p = of_get_address(np, 0, NULL, NULL);
> > + if (!p) {
> > + pr_err("irq: register address missing\n");
> > + ret = -EINVAL;
> > + goto err_addr;
> > + }
> > +
> > + /* select the correct data for the controller.
> > + * Need to hard code the irq num start and offset
> > + * to preserve the static mapping for now
> > + */
> > + switch (of_translate_address(np, p)) {
> > + case 0x4a000000:
> > + pr_debug("irq: found main intc\n");
> > + intc->reg_pending = S3C2410_SRCPND;
> > + intc->reg_intpnd = S3C2410_INTPND;
> > + intc->reg_mask = S3C2410_INTMSK;
> > + irq_num = 32;
> > + irq_start = S3C2410_IRQ(0);
> > + irq_offset = 0;
> > + break;
> > + case 0x560000a4:
> > + pr_debug("irq: found extintc\n");
> > + intc->reg_pending = S3C2410_EINTPEND;
> > + intc->reg_mask = S3C2410_EINTMASK;
> > + irq_num = 20;
> > + irq_start = S3C2410_IRQ(32);
> > + irq_offset = 4;
> > + break;
> > + case 0x4a000018:
> > + pr_debug("irq: found subintc\n");
> > + intc->reg_pending = S3C2410_SUBSRCPND;
> > + intc->reg_mask = S3C2410_INTSUBMSK;
> > + irq_num = 29;
> > + irq_start = S3C2410_IRQSUB(0);
> > + irq_offset = 0;
> > + break;
> > + case 0x4a000040:
> > + pr_debug("irq: found intc2\n");
> > + intc->reg_pending = S3C2416_SRCPND2;
> > + intc->reg_intpnd = S3C2416_INTPND2;
> > + intc->reg_mask = S3C2416_INTMSK2;
> > + irq_num = 8;
> > + irq_start = S3C2416_IRQ(0);
> > + irq_offset = 0;
> > + break;
> > + case 0:
> > + pr_err("irq: couldn't translate address\n");
> > + ret = -EINVAL;
> > + goto err_addr;
> > + default:
> > + pr_err("irq: unsupported controller address\n");
> > + ret = -EINVAL;
> > + goto err_addr;
> > + }
> > +
> > + irq_data = kzalloc(sizeof(struct s3c_irq_data) * 32, GFP_KERNEL);
> > + if (!irq_data) {
> > + ret = -ENOMEM;
> > + goto err_addr;
> > + }
> > +
> > + cnt = 0;
> > + intc_prop = of_find_property(np, "s3c24xx,irqlist", NULL);
> > + if (!intc_prop) {
> > + pr_err("irq: irqlist not found\n");
> > + ret = -EINVAL;
> > + goto err_data;
> > + }
> > +
> > + /* build the irq_data list */
> > + p = NULL;
> > + for (i = 0; i < 32; i++) {
> > + p = of_prop_next_u32(intc_prop, p, &val);
> > +
> > + /* when we hit the first non-valid element, assume it's
> > + * the end of the list. The rest of the fields are
> > + * already of type S3C_IRQTYPE_NONE (value 0)
> > + */
> > + if (!p)
> > + break;
> > +
> > + irq_data[i].type = val;
> > +
> > + p = of_prop_next_u32(intc_prop, p, &val);
> > + if (!p) {
> > + pr_warn("irq: uneven number of elements in
> > irqlist, last value will be dropped\n"); +
> > irq_data[i].type = 0;
> > + break;
> > + }
> > +
> > + irq_data[i].parent_irq = val;
> > +
> > + pr_debug("irq: found hwirq %d with type %d and parent
> > %lu\n", + i, irq_data[i].type,
> > irq_data[i].parent_irq); + cnt++;
> > + }
> > +
> > + /* if we haven't found any irq definition at all,
> > + * something is very wrong.
> > + */
> > + if (!cnt) {
> > + pr_err("irq: empty irq definition\n");
> > + ret = -EINVAL;
> > + goto err_data;
> > + }
> > +
> > + intc->irqs = irq_data;
> > +
> > + /* put the intc into the dt as property, so we can access it from
> > + * as the interrupt_parent later
> > + */
> > +
> > + intc_prop = kzalloc(sizeof(struct property), GFP_KERNEL);
> > + if (!intc_prop) {
> > + ret = -ENOMEM;
> > + goto err_data;
> > + }
> > +
> > + intc_prop->name = kstrdup("s3c-irq-intc", GFP_KERNEL);
> > + intc_prop->value = intc;
> > + intc_prop->length = sizeof(struct s3c_irq_intc);
> > +
> > + ret = prom_add_property(np, intc_prop);
> > + if (ret) {
> > + pr_err("irq: failed to add dt property\n");
> > + goto err_prop;
> > + }
> > +
> > + /* set the parent relationship */
> > + if (interrupt_parent) {
> > + parent = (struct s3c_irq_intc *)of_get_property(
> > + interrupt_parent, "s3c-irq-intc",
> > NULL); + if (!parent) {
> > + pr_err("irq: no parent for non-root controller
> > found\n"); + goto err_domain;
> > + }
> > +
> > + intc->parent = parent;
> > + }
> > +
> > + /* now that all the data is complete, init the irq-domain */
> > + s3c24xx_clear_intc(intc);
> > + intc->domain = irq_domain_add_legacy(np, irq_num, irq_start,
> > + irq_offset,
> > &s3c24xx_irq_ops, + intc);
> > + if (!intc->domain) {
> > + pr_err("irq: could not create irq-domain\n");
> > + ret = -EINVAL;
> > + goto err_domain;
> > + }
> > +
> > + return 0;
> > +
> > +err_domain:
> > + prom_remove_property(np, intc_prop);
> > +err_prop:
> > + kfree(intc_prop);
> > +err_data:
> > + kfree(irq_data);
> > +err_addr:
> > + kfree(intc);
> > +
> > + return ret;
> > +}
> > +
> > +static const struct of_device_id s3c24xx_irq_match[] __initconst = {
> > + { .compatible = "samsung,s3c24xx-irq", .data =
> > s3c24xx_init_intc_of, }, + { /* sentinel */ }
> > +};
> > +
> > +void __init s3c24xx_init_irq_of(void)
> > +{
> > + of_irq_init(s3c24xx_irq_match);
> > +}
> > +#endif
> > --
> > 1.7.2.3
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe
> > linux-samsung-soc" in the body of a message to majordomo at vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC 1/2] ARM: S3C24XX: add devicetree support for interrupts
2012-11-26 12:13 ` Heiko Stübner
@ 2012-11-26 15:23 ` Thomas Abraham
2012-11-26 16:04 ` Heiko Stübner
0 siblings, 1 reply; 10+ messages in thread
From: Thomas Abraham @ 2012-11-26 15:23 UTC (permalink / raw)
To: linux-arm-kernel
On 26 November 2012 17:43, Heiko St?bner <heiko@sntech.de> wrote:
> Hi Thomas,
>
> Am Montag, 26. November 2012, 12:03:22 schrieb Thomas Abraham:
>> Hi Heiko,
>>
>> On 25 November 2012 06:17, Heiko St?bner <heiko@sntech.de> wrote:
>> > This adds devicetree parsing of the controller-data for the
>> > interrupt controllers on S3C24XX architectures.
>> >
>> > Signed-off-by: Heiko Stuebner <heiko@sntech.de>
>> > ---
>> >
>> > .../interrupt-controller/samsung,s3c24xx-irq.txt | 57 ++++++
>> > arch/arm/mach-s3c24xx/common.h | 1 +
>> > arch/arm/plat-s3c24xx/irq.c | 197
>> > ++++++++++++++++++++ 3 files changed, 255 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..c637637
>> > --- /dev/null
>> > +++
>> > b/Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24xx
>> > -irq.txt @@ -0,0 +1,57 @@
>> > +Samsung S3C24XX Interrupt Controllers
>> > +
>> > +The S3C24XX SoCs contain custom set of interrupt controllers providing a
>> > +varying number of interrupt sources.
>> > +
>> > +The set consists of a main- and a sub-controller as well as a controller
>> > +for the external interrupts and on newer SoCs even a second main
>> > controller. +
>> > +The bit-to-interrupt and parent mapping of the controllers is not fixed
>> > +over all SoCs and therefore must be defined in the controller
>> > description. +
>> > +Required properties:
>> > +- compatible: Compatible property value should be "samsung,s3c24xx-irq".
>> > +
>> > +- reg: Physical base address of the controller and length of memory
>> > mapped + region.
>> > +
>> > +- 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.
>> > +
>> > +- s3c24xx,irqlist : List of irqtypes found on this controller as
>> > + two-value pairs consisting of irqtype and parent-irq
>> > +
>> > + parent-irq is always the list position of the irq in the irqlist
>> > + of the parent controller (0..31)
>> > +
>> > + irqtypes are:
>> > + - 0 .. none
>> > + - 1 .. external interrupts in the main register (GPF0 .. GPF3)
>> > + - 2 .. edge irq in the main register
>> > + - 3 .. for parent-irqs, that have sub-irqs in child controllers
>> > + - 4 .. level irqs in the sub-register
>> > + - 5 .. edge irqs in the sub-register
>> > + - 6 .. external irqs in the external irq register (starting with GPF4)
>> > + - 7 .. irq in the second base irq controller of S3C2416/S3C2450 SoCs
>>
>> Instead of defining the type of interrupt controller as above, is it
>> possible to create multiple device nodes, with each node representing
>> a type of interrupt controller with a unique compatible string and
>> corresponding properties. There will be a init function for each type
>> of interrupt controller. There should be a irq-domain for each of
>> these different types of interrupt controller. And then, in the device
>> tree source file, a proper tree like hierarchy of interrupt
>> controllers can defined (using the interrupt-parent property for each
>> controller node). The client nodes that generate the interrupt can
>> specify the parent node and the interrupt number within the parent to
>> which they generate the interrupt.
>
> I'm not sure I understand yet :-). The list describes the types of interrupts
> inside the individual controllers.
>
> On all the s3c24xx we have three register sets denoting the main (SRCPND,
> INTPND, INTMSK), sub (SUBSRCPEND, INTSUBMASK) and extint (EINTPEND, EINTMASK)
> controllers. The bits of these registers are used for quite different irqs.
We could consider main, sub and extint as three separate interrupt
controllers and thus three different nodes in device tree. So the
interrupt nodes could be something like (referring to 2416 manual).
main at 0x4a000000 {
compatible = "samsung,s3c2410-main";
reg = <0x4a000000 0x100>;
interrupt-controller;
#interrupt-cells = <2>;
};
sub at 0x4a001000 {
compatible = "samsung,s3c2410-sub";
reg = <0x4a001000 0x100>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&main>;
interrupts = <28 0>, <23 0>, <..... /*uart0/uart1/..*/
};
eint@0x4a002000 {
compatible = "samsung,s3c2410-eint";
reg = <0x4a002000 0x100>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&main>;
interrupts = <0 0>, <1 0>,
<2 0>, <3 0>,
<4 0>, <5 0>;
};
There should be a corresponding irqchip driver code to handle each of
these types of controllers. They should have their own irq-domain
supported.
Then the client nodes can specify the interrupt parent and interrupt
number. For example, the uart node would be
uart at 50000000 {
compatible = "samsung,s3c2410-uart";
reg = <0x50000000 0x100>;
interrupt-parent = <&sub>;
interrupts = <0 0>, <1 0>, <2 0>; /*tx/rx/err*/
};
> For example is bit 17 of the main register set used as DMA0 on earlier socs
> while the dma interrupts moved to the subint registers for s3c2443 and later.
Writing the nodes with the correct interrupt parent and the interrupt
number should take care of this.
>
> So the entries in the irqlist describe the needed handlers for the hwirq bits
> of the indidual controllers. So in this scheme you set for dt-devices the
> interrupt parent to the correct register set and the interrupts field then
> matches the bit of the register, according to the datasheet.
>
> When I changed the basic interrupt handling in the previous set, the changed
> irq.c can for exmaple be found on [0], I created these lists in the code and
> soc specific routines to init them for the still valid non-dt case.
>
> But as dt is about describing the hardware, I found the current solution nice,
> because will I only need exactly one dt-init-function for all s3c24xx-socs,
> instead of representing all the slight variances in code.
>
> I'm definitly not sure if all the different types of individual irq handlers
> are strictly necessary yet, but they represent all the variants that were in
> use in the original code.
I have brought up this point just for discussion. You could choose the
implementation that you prefer. I understand that implementing with
different interrupt controller nodes might require lot of code
changes.
Thanks,
Thomas.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC 1/2] ARM: S3C24XX: add devicetree support for interrupts
2012-11-26 15:23 ` Thomas Abraham
@ 2012-11-26 16:04 ` Heiko Stübner
2012-11-27 6:12 ` Thomas Abraham
0 siblings, 1 reply; 10+ messages in thread
From: Heiko Stübner @ 2012-11-26 16:04 UTC (permalink / raw)
To: linux-arm-kernel
Hi Thomas,
Am Montag, 26. November 2012, 16:23:00 schrieb Thomas Abraham:
> On 26 November 2012 17:43, Heiko St?bner <heiko@sntech.de> wrote:
> > Hi Thomas,
> >
> > Am Montag, 26. November 2012, 12:03:22 schrieb Thomas Abraham:
> >> Hi Heiko,
> >>
> >> On 25 November 2012 06:17, Heiko St?bner <heiko@sntech.de> wrote:
> >> > This adds devicetree parsing of the controller-data for the
> >> > interrupt controllers on S3C24XX architectures.
> >> >
> >> > Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> >> > ---
> >> >
> >> > .../interrupt-controller/samsung,s3c24xx-irq.txt | 57 ++++++
> >> > arch/arm/mach-s3c24xx/common.h | 1 +
> >> > arch/arm/plat-s3c24xx/irq.c | 197
> >> > ++++++++++++++++++++ 3 files changed, 255 insertions(+), 0
> >> > deletions(-) create mode 100644
> >> > Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24x
> >> > x- irq.txt
> >> >
> >> > diff --git
> >> > a/Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24
> >> > xx -irq.txt
> >> > b/Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24
> >> > xx -irq.txt new file mode 100644
> >> > index 0000000..c637637
> >> > --- /dev/null
> >> > +++
> >> > b/Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24
> >> > xx -irq.txt @@ -0,0 +1,57 @@
> >> > +Samsung S3C24XX Interrupt Controllers
> >> > +
> >> > +The S3C24XX SoCs contain custom set of interrupt controllers
> >> > providing a +varying number of interrupt sources.
> >> > +
> >> > +The set consists of a main- and a sub-controller as well as a
> >> > controller +for the external interrupts and on newer SoCs even a
> >> > second main controller. +
> >> > +The bit-to-interrupt and parent mapping of the controllers is not
> >> > fixed +over all SoCs and therefore must be defined in the controller
> >> > description. +
> >> > +Required properties:
> >> > +- compatible: Compatible property value should be
> >> > "samsung,s3c24xx-irq". +
> >> > +- reg: Physical base address of the controller and length of memory
> >> > mapped + region.
> >> > +
> >> > +- 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.
> >> > +
> >> > +- s3c24xx,irqlist : List of irqtypes found on this controller as
> >> > + two-value pairs consisting of irqtype and parent-irq
> >> > +
> >> > + parent-irq is always the list position of the irq in the irqlist
> >> > + of the parent controller (0..31)
> >> > +
> >> > + irqtypes are:
> >> > + - 0 .. none
> >> > + - 1 .. external interrupts in the main register (GPF0 .. GPF3)
> >> > + - 2 .. edge irq in the main register
> >> > + - 3 .. for parent-irqs, that have sub-irqs in child controllers
> >> > + - 4 .. level irqs in the sub-register
> >> > + - 5 .. edge irqs in the sub-register
> >> > + - 6 .. external irqs in the external irq register (starting with
> >> > GPF4) + - 7 .. irq in the second base irq controller of
> >> > S3C2416/S3C2450 SoCs
> >>
> >> Instead of defining the type of interrupt controller as above, is it
> >> possible to create multiple device nodes, with each node representing
> >> a type of interrupt controller with a unique compatible string and
> >> corresponding properties. There will be a init function for each type
> >> of interrupt controller. There should be a irq-domain for each of
> >> these different types of interrupt controller. And then, in the device
> >> tree source file, a proper tree like hierarchy of interrupt
> >> controllers can defined (using the interrupt-parent property for each
> >> controller node). The client nodes that generate the interrupt can
> >> specify the parent node and the interrupt number within the parent to
> >> which they generate the interrupt.
> >
> > I'm not sure I understand yet :-). The list describes the types of
> > interrupts inside the individual controllers.
> >
> > On all the s3c24xx we have three register sets denoting the main (SRCPND,
> > INTPND, INTMSK), sub (SUBSRCPEND, INTSUBMASK) and extint (EINTPEND,
> > EINTMASK) controllers. The bits of these registers are used for quite
> > different irqs.
>
> We could consider main, sub and extint as three separate interrupt
> controllers and thus three different nodes in device tree. So the
> interrupt nodes could be something like (referring to 2416 manual).
>
> main at 0x4a000000 {
> compatible = "samsung,s3c2410-main";
> reg = <0x4a000000 0x100>;
> interrupt-controller;
> #interrupt-cells = <2>;
> };
>
> sub at 0x4a001000 {
> compatible = "samsung,s3c2410-sub";
> reg = <0x4a001000 0x100>;
> interrupt-controller;
> #interrupt-cells = <2>;
> interrupt-parent = <&main>;
> interrupts = <28 0>, <23 0>, <..... /*uart0/uart1/..*/
> };
>
> eint at 0x4a002000 {
> compatible = "samsung,s3c2410-eint";
> reg = <0x4a002000 0x100>;
> interrupt-controller;
> #interrupt-cells = <2>;
> interrupt-parent = <&main>;
> interrupts = <0 0>, <1 0>,
> <2 0>, <3 0>,
> <4 0>, <5 0>;
> };
>
> There should be a corresponding irqchip driver code to handle each of
> these types of controllers. They should have their own irq-domain
> supported.
>
> Then the client nodes can specify the interrupt parent and interrupt
> number. For example, the uart node would be
>
> uart at 50000000 {
> compatible = "samsung,s3c2410-uart";
> reg = <0x50000000 0x100>;
> interrupt-parent = <&sub>;
> interrupts = <0 0>, <1 0>, <2 0>; /*tx/rx/err*/
> };
>
> > For example is bit 17 of the main register set used as DMA0 on earlier
> > socs while the dma interrupts moved to the subint registers for s3c2443
> > and later.
>
> Writing the nodes with the correct interrupt parent and the interrupt
> number should take care of this.
>
> > So the entries in the irqlist describe the needed handlers for the hwirq
> > bits of the indidual controllers. So in this scheme you set for
> > dt-devices the interrupt parent to the correct register set and the
> > interrupts field then matches the bit of the register, according to the
> > datasheet.
> >
> > When I changed the basic interrupt handling in the previous set, the
> > changed irq.c can for exmaple be found on [0], I created these lists in
> > the code and soc specific routines to init them for the still valid
> > non-dt case.
> >
> > But as dt is about describing the hardware, I found the current solution
> > nice, because will I only need exactly one dt-init-function for all
> > s3c24xx-socs, instead of representing all the slight variances in code.
> >
> > I'm definitly not sure if all the different types of individual irq
> > handlers are strictly necessary yet, but they represent all the variants
> > that were in use in the original code.
>
> I have brought up this point just for discussion. You could choose the
> implementation that you prefer. I understand that implementing with
> different interrupt controller nodes might require lot of code
> changes.
first of all, thanks for the feedback. Working on this is like moving in a fog
where I don't really see where I'm going - so I don't claim to be right.
But somehow I have the feeling we're talking about similar things here :-)
If you look in the second patch, you'll see that there are already the three
(or 4 in the case of the s3c2416) interrupt controllers defined [intc,
subintc, extintc]. But as they contain the data of their individual interrupts
inside the devicetree definitions, they don't need individual init functions
but only one which constructs the interrupt data out of the list provided.
The real list for a platform in the second patch might also help in showing
why this list was necessary.
The basic problem is, that each individual interrupt inside one of the
controllers might need a different handler and access a specific parent
interrupt. For example the uart0-rx,tx,err interrupts in the subintc must
ack/mask the uart0 interrupt in the main intc; similar for a lot of other
interrupts. And the s3c24xx,irqlist provides this mapping to handler and
parent, so it does not need to be codified.
And of course the second problem this approach should solve is, that the
interrupts in the controllers differ and also move between most of the s3c24xx
sub-architectures.
Thanks
Heiko
^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC 1/2] ARM: S3C24XX: add devicetree support for interrupts
2012-11-26 16:04 ` Heiko Stübner
@ 2012-11-27 6:12 ` Thomas Abraham
2012-11-27 16:24 ` Heiko Stübner
0 siblings, 1 reply; 10+ messages in thread
From: Thomas Abraham @ 2012-11-27 6:12 UTC (permalink / raw)
To: linux-arm-kernel
On 26 November 2012 21:34, Heiko St?bner <heiko@sntech.de> wrote:
> Hi Thomas,
>
> Am Montag, 26. November 2012, 16:23:00 schrieb Thomas Abraham:
>> On 26 November 2012 17:43, Heiko St?bner <heiko@sntech.de> wrote:
>> > Hi Thomas,
>> >
>> > Am Montag, 26. November 2012, 12:03:22 schrieb Thomas Abraham:
>> >> Hi Heiko,
>> >>
>> >> On 25 November 2012 06:17, Heiko St?bner <heiko@sntech.de> wrote:
>> >> > This adds devicetree parsing of the controller-data for the
>> >> > interrupt controllers on S3C24XX architectures.
>> >> >
>> >> > Signed-off-by: Heiko Stuebner <heiko@sntech.de>
>> >> > ---
>> >> >
>> >> > .../interrupt-controller/samsung,s3c24xx-irq.txt | 57 ++++++
>> >> > arch/arm/mach-s3c24xx/common.h | 1 +
>> >> > arch/arm/plat-s3c24xx/irq.c | 197
>> >> > ++++++++++++++++++++ 3 files changed, 255 insertions(+), 0
>> >> > deletions(-) create mode 100644
>> >> > Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24x
>> >> > x- irq.txt
>> >> >
>> >> > diff --git
>> >> > a/Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24
>> >> > xx -irq.txt
>> >> > b/Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24
>> >> > xx -irq.txt new file mode 100644
>> >> > index 0000000..c637637
>> >> > --- /dev/null
>> >> > +++
>> >> > b/Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24
>> >> > xx -irq.txt @@ -0,0 +1,57 @@
>> >> > +Samsung S3C24XX Interrupt Controllers
>> >> > +
>> >> > +The S3C24XX SoCs contain custom set of interrupt controllers
>> >> > providing a +varying number of interrupt sources.
>> >> > +
>> >> > +The set consists of a main- and a sub-controller as well as a
>> >> > controller +for the external interrupts and on newer SoCs even a
>> >> > second main controller. +
>> >> > +The bit-to-interrupt and parent mapping of the controllers is not
>> >> > fixed +over all SoCs and therefore must be defined in the controller
>> >> > description. +
>> >> > +Required properties:
>> >> > +- compatible: Compatible property value should be
>> >> > "samsung,s3c24xx-irq". +
>> >> > +- reg: Physical base address of the controller and length of memory
>> >> > mapped + region.
>> >> > +
>> >> > +- 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.
>> >> > +
>> >> > +- s3c24xx,irqlist : List of irqtypes found on this controller as
>> >> > + two-value pairs consisting of irqtype and parent-irq
>> >> > +
>> >> > + parent-irq is always the list position of the irq in the irqlist
>> >> > + of the parent controller (0..31)
>> >> > +
>> >> > + irqtypes are:
>> >> > + - 0 .. none
>> >> > + - 1 .. external interrupts in the main register (GPF0 .. GPF3)
>> >> > + - 2 .. edge irq in the main register
>> >> > + - 3 .. for parent-irqs, that have sub-irqs in child controllers
>> >> > + - 4 .. level irqs in the sub-register
>> >> > + - 5 .. edge irqs in the sub-register
>> >> > + - 6 .. external irqs in the external irq register (starting with
>> >> > GPF4) + - 7 .. irq in the second base irq controller of
>> >> > S3C2416/S3C2450 SoCs
>> >>
>> >> Instead of defining the type of interrupt controller as above, is it
>> >> possible to create multiple device nodes, with each node representing
>> >> a type of interrupt controller with a unique compatible string and
>> >> corresponding properties. There will be a init function for each type
>> >> of interrupt controller. There should be a irq-domain for each of
>> >> these different types of interrupt controller. And then, in the device
>> >> tree source file, a proper tree like hierarchy of interrupt
>> >> controllers can defined (using the interrupt-parent property for each
>> >> controller node). The client nodes that generate the interrupt can
>> >> specify the parent node and the interrupt number within the parent to
>> >> which they generate the interrupt.
>> >
>> > I'm not sure I understand yet :-). The list describes the types of
>> > interrupts inside the individual controllers.
>> >
>> > On all the s3c24xx we have three register sets denoting the main (SRCPND,
>> > INTPND, INTMSK), sub (SUBSRCPEND, INTSUBMASK) and extint (EINTPEND,
>> > EINTMASK) controllers. The bits of these registers are used for quite
>> > different irqs.
>>
>> We could consider main, sub and extint as three separate interrupt
>> controllers and thus three different nodes in device tree. So the
>> interrupt nodes could be something like (referring to 2416 manual).
>>
>> main at 0x4a000000 {
>> compatible = "samsung,s3c2410-main";
>> reg = <0x4a000000 0x100>;
>> interrupt-controller;
>> #interrupt-cells = <2>;
>> };
>>
>> sub at 0x4a001000 {
>> compatible = "samsung,s3c2410-sub";
>> reg = <0x4a001000 0x100>;
>> interrupt-controller;
>> #interrupt-cells = <2>;
>> interrupt-parent = <&main>;
>> interrupts = <28 0>, <23 0>, <..... /*uart0/uart1/..*/
>> };
>>
>> eint at 0x4a002000 {
>> compatible = "samsung,s3c2410-eint";
>> reg = <0x4a002000 0x100>;
>> interrupt-controller;
>> #interrupt-cells = <2>;
>> interrupt-parent = <&main>;
>> interrupts = <0 0>, <1 0>,
>> <2 0>, <3 0>,
>> <4 0>, <5 0>;
>> };
>>
>> There should be a corresponding irqchip driver code to handle each of
>> these types of controllers. They should have their own irq-domain
>> supported.
>>
>> Then the client nodes can specify the interrupt parent and interrupt
>> number. For example, the uart node would be
>>
>> uart at 50000000 {
>> compatible = "samsung,s3c2410-uart";
>> reg = <0x50000000 0x100>;
>> interrupt-parent = <&sub>;
>> interrupts = <0 0>, <1 0>, <2 0>; /*tx/rx/err*/
>> };
>>
>> > For example is bit 17 of the main register set used as DMA0 on earlier
>> > socs while the dma interrupts moved to the subint registers for s3c2443
>> > and later.
>>
>> Writing the nodes with the correct interrupt parent and the interrupt
>> number should take care of this.
>>
>> > So the entries in the irqlist describe the needed handlers for the hwirq
>> > bits of the indidual controllers. So in this scheme you set for
>> > dt-devices the interrupt parent to the correct register set and the
>> > interrupts field then matches the bit of the register, according to the
>> > datasheet.
>> >
>> > When I changed the basic interrupt handling in the previous set, the
>> > changed irq.c can for exmaple be found on [0], I created these lists in
>> > the code and soc specific routines to init them for the still valid
>> > non-dt case.
>> >
>> > But as dt is about describing the hardware, I found the current solution
>> > nice, because will I only need exactly one dt-init-function for all
>> > s3c24xx-socs, instead of representing all the slight variances in code.
>> >
>> > I'm definitly not sure if all the different types of individual irq
>> > handlers are strictly necessary yet, but they represent all the variants
>> > that were in use in the original code.
>>
>> I have brought up this point just for discussion. You could choose the
>> implementation that you prefer. I understand that implementing with
>> different interrupt controller nodes might require lot of code
>> changes.
>
> first of all, thanks for the feedback. Working on this is like moving in a fog
> where I don't really see where I'm going - so I don't claim to be right.
>
>
> But somehow I have the feeling we're talking about similar things here :-)
>
> If you look in the second patch, you'll see that there are already the three
> (or 4 in the case of the s3c2416) interrupt controllers defined [intc,
> subintc, extintc]. But as they contain the data of their individual interrupts
> inside the devicetree definitions, they don't need individual init functions
> but only one which constructs the interrupt data out of the list provided.
>
> The real list for a platform in the second patch might also help in showing
> why this list was necessary.
Ok, I had not looked at the second patch carefully enough. There are
four interrupt controller nodes but I am still not sure if the
bindings for those nodes are correct. The question here is, did we
design the binding to suit a specific linux implementation of the
interrupt controller. Ideally, the bindings should just be enough to
explain the interconnection between the interrupt controller and the
client devices. And should be OS agnostic as much as possible. The
seven irqtypes in the binding definition seems to suggest that we are
encoding a software defined abstraction into the binding, which does
not seem right.
>
> The basic problem is, that each individual interrupt inside one of the
> controllers might need a different handler and access a specific parent
> interrupt. For example the uart0-rx,tx,err interrupts in the subintc must
> ack/mask the uart0 interrupt in the main intc; similar for a lot of other
> interrupts. And the s3c24xx,irqlist provides this mapping to handler and
> parent, so it does not need to be codified.
I believe the three node example that I listed above should be able to
handle this, but yes, it might require additional code to support it.
For example, the uart device node has listed three interrupts. The
uart controller drivers can register three separate interrupt handlers
for these interrupts. As far as the interrupt handling for 'main'
controller, I see that this is very similar to the way interrupt
combiner module has been coded for exynos soc's. So the combiner
interrupt controller code in mach-exynos/common.c file can be used a
reference on how this can be handled.
>
> And of course the second problem this approach should solve is, that the
> interrupts in the controllers differ and also move between most of the s3c24xx
> sub-architectures.
Yes, I understand how difficult it can get while writing a generalized
code for all soc's in s3c24xx family.
Thanks,
Thomas.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC 1/2] ARM: S3C24XX: add devicetree support for interrupts
2012-11-27 6:12 ` Thomas Abraham
@ 2012-11-27 16:24 ` Heiko Stübner
2012-11-28 14:10 ` Thomas Abraham
0 siblings, 1 reply; 10+ messages in thread
From: Heiko Stübner @ 2012-11-27 16:24 UTC (permalink / raw)
To: linux-arm-kernel
Am Dienstag, 27. November 2012, 07:12:52 schrieb Thomas Abraham:
> On 26 November 2012 21:34, Heiko St?bner <heiko@sntech.de> wrote:
> > Hi Thomas,
> >
> > Am Montag, 26. November 2012, 16:23:00 schrieb Thomas Abraham:
> >> On 26 November 2012 17:43, Heiko St?bner <heiko@sntech.de> wrote:
> >> > Hi Thomas,
> >> >
> >> > Am Montag, 26. November 2012, 12:03:22 schrieb Thomas Abraham:
> >> >> Hi Heiko,
> >> >>
> >> >> On 25 November 2012 06:17, Heiko St?bner <heiko@sntech.de> wrote:
> >> >> > This adds devicetree parsing of the controller-data for the
> >> >> > interrupt controllers on S3C24XX architectures.
> >> >> >
> >> >> > Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> >> >> > ---
> >> >> >
> >> >> > .../interrupt-controller/samsung,s3c24xx-irq.txt | 57 ++++++
> >> >> > arch/arm/mach-s3c24xx/common.h | 1 +
> >> >> > arch/arm/plat-s3c24xx/irq.c | 197
> >> >> > ++++++++++++++++++++ 3 files changed, 255 insertions(+), 0
> >> >> > deletions(-) create mode 100644
> >> >> > Documentation/devicetree/bindings/interrupt-controller/samsung,s3c
> >> >> > 24x x- irq.txt
> >> >> >
> >> >> > diff --git
> >> >> > a/Documentation/devicetree/bindings/interrupt-controller/samsung,s3
> >> >> > c24 xx -irq.txt
> >> >> > b/Documentation/devicetree/bindings/interrupt-controller/samsung,s3
> >> >> > c24 xx -irq.txt new file mode 100644
> >> >> > index 0000000..c637637
> >> >> > --- /dev/null
> >> >> > +++
> >> >> > b/Documentation/devicetree/bindings/interrupt-controller/samsung,s3
> >> >> > c24 xx -irq.txt @@ -0,0 +1,57 @@
> >> >> > +Samsung S3C24XX Interrupt Controllers
> >> >> > +
> >> >> > +The S3C24XX SoCs contain custom set of interrupt controllers
> >> >> > providing a +varying number of interrupt sources.
> >> >> > +
> >> >> > +The set consists of a main- and a sub-controller as well as a
> >> >> > controller +for the external interrupts and on newer SoCs even a
> >> >> > second main controller. +
> >> >> > +The bit-to-interrupt and parent mapping of the controllers is not
> >> >> > fixed +over all SoCs and therefore must be defined in the
> >> >> > controller description. +
> >> >> > +Required properties:
> >> >> > +- compatible: Compatible property value should be
> >> >> > "samsung,s3c24xx-irq". +
> >> >> > +- reg: Physical base address of the controller and length of
> >> >> > memory mapped + region.
> >> >> > +
> >> >> > +- 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.
> >> >> > +
> >> >> > +- s3c24xx,irqlist : List of irqtypes found on this controller as
> >> >> > + two-value pairs consisting of irqtype and parent-irq
> >> >> > +
> >> >> > + parent-irq is always the list position of the irq in the irqlist
> >> >> > + of the parent controller (0..31)
> >> >> > +
> >> >> > + irqtypes are:
> >> >> > + - 0 .. none
> >> >> > + - 1 .. external interrupts in the main register (GPF0 .. GPF3)
> >> >> > + - 2 .. edge irq in the main register
> >> >> > + - 3 .. for parent-irqs, that have sub-irqs in child controllers
> >> >> > + - 4 .. level irqs in the sub-register
> >> >> > + - 5 .. edge irqs in the sub-register
> >> >> > + - 6 .. external irqs in the external irq register (starting with
> >> >> > GPF4) + - 7 .. irq in the second base irq controller of
> >> >> > S3C2416/S3C2450 SoCs
> >> >>
> >> >> Instead of defining the type of interrupt controller as above, is it
> >> >> possible to create multiple device nodes, with each node representing
> >> >> a type of interrupt controller with a unique compatible string and
> >> >> corresponding properties. There will be a init function for each type
> >> >> of interrupt controller. There should be a irq-domain for each of
> >> >> these different types of interrupt controller. And then, in the
> >> >> device tree source file, a proper tree like hierarchy of interrupt
> >> >> controllers can defined (using the interrupt-parent property for each
> >> >> controller node). The client nodes that generate the interrupt can
> >> >> specify the parent node and the interrupt number within the parent to
> >> >> which they generate the interrupt.
> >> >
> >> > I'm not sure I understand yet :-). The list describes the types of
> >> > interrupts inside the individual controllers.
> >> >
> >> > On all the s3c24xx we have three register sets denoting the main
> >> > (SRCPND, INTPND, INTMSK), sub (SUBSRCPEND, INTSUBMASK) and extint
> >> > (EINTPEND, EINTMASK) controllers. The bits of these registers are
> >> > used for quite different irqs.
> >>
> >> We could consider main, sub and extint as three separate interrupt
> >> controllers and thus three different nodes in device tree. So the
> >> interrupt nodes could be something like (referring to 2416 manual).
> >>
> >> main at 0x4a000000 {
> >>
> >> compatible = "samsung,s3c2410-main";
> >> reg = <0x4a000000 0x100>;
> >> interrupt-controller;
> >> #interrupt-cells = <2>;
> >>
> >> };
> >>
> >> sub at 0x4a001000 {
> >>
> >> compatible = "samsung,s3c2410-sub";
> >> reg = <0x4a001000 0x100>;
> >> interrupt-controller;
> >> #interrupt-cells = <2>;
> >> interrupt-parent = <&main>;
> >> interrupts = <28 0>, <23 0>, <..... /*uart0/uart1/..*/
> >>
> >> };
> >>
> >> eint at 0x4a002000 {
> >>
> >> compatible = "samsung,s3c2410-eint";
> >> reg = <0x4a002000 0x100>;
> >> interrupt-controller;
> >> #interrupt-cells = <2>;
> >> interrupt-parent = <&main>;
> >> interrupts = <0 0>, <1 0>,
> >>
> >> <2 0>, <3 0>,
> >> <4 0>, <5 0>;
> >>
> >> };
> >>
> >> There should be a corresponding irqchip driver code to handle each of
> >> these types of controllers. They should have their own irq-domain
> >> supported.
> >>
> >> Then the client nodes can specify the interrupt parent and interrupt
> >> number. For example, the uart node would be
> >>
> >> uart at 50000000 {
> >>
> >> compatible = "samsung,s3c2410-uart";
> >> reg = <0x50000000 0x100>;
> >> interrupt-parent = <&sub>;
> >> interrupts = <0 0>, <1 0>, <2 0>; /*tx/rx/err*/
> >>
> >> };
> >> >
> >> > For example is bit 17 of the main register set used as DMA0 on earlier
> >> > socs while the dma interrupts moved to the subint registers for
> >> > s3c2443 and later.
> >>
> >> Writing the nodes with the correct interrupt parent and the interrupt
> >> number should take care of this.
> >>
> >> > So the entries in the irqlist describe the needed handlers for the
> >> > hwirq bits of the indidual controllers. So in this scheme you set for
> >> > dt-devices the interrupt parent to the correct register set and the
> >> > interrupts field then matches the bit of the register, according to
> >> > the datasheet.
> >> >
> >> > When I changed the basic interrupt handling in the previous set, the
> >> > changed irq.c can for exmaple be found on [0], I created these lists
> >> > in the code and soc specific routines to init them for the still
> >> > valid non-dt case.
> >> >
> >> > But as dt is about describing the hardware, I found the current
> >> > solution nice, because will I only need exactly one dt-init-function
> >> > for all s3c24xx-socs, instead of representing all the slight
> >> > variances in code.
> >> >
> >> > I'm definitly not sure if all the different types of individual irq
> >> > handlers are strictly necessary yet, but they represent all the
> >> > variants that were in use in the original code.
> >>
> >> I have brought up this point just for discussion. You could choose the
> >> implementation that you prefer. I understand that implementing with
> >> different interrupt controller nodes might require lot of code
> >> changes.
> >
> > first of all, thanks for the feedback. Working on this is like moving in
> > a fog where I don't really see where I'm going - so I don't claim to be
> > right.
> >
> >
> >
> > But somehow I have the feeling we're talking about similar things here
> > :-)
> >
> > If you look in the second patch, you'll see that there are already the
> > three (or 4 in the case of the s3c2416) interrupt controllers defined
> > [intc, subintc, extintc]. But as they contain the data of their
> > individual interrupts inside the devicetree definitions, they don't need
> > individual init functions but only one which constructs the interrupt
> > data out of the list provided.
> >
> > The real list for a platform in the second patch might also help in
> > showing why this list was necessary.
>
> Ok, I had not looked at the second patch carefully enough. There are
> four interrupt controller nodes but I am still not sure if the
> bindings for those nodes are correct. The question here is, did we
> design the binding to suit a specific linux implementation of the
> interrupt controller. Ideally, the bindings should just be enough to
> explain the interconnection between the interrupt controller and the
> client devices. And should be OS agnostic as much as possible. The
> seven irqtypes in the binding definition seems to suggest that we are
> encoding a software defined abstraction into the binding, which does
> not seem right.
Because of the mails from yesterday I took another look at my code, after
letting it sit for the previous days and I found more optimization
possiblities.
It should be possible to trim the irqtypes down to level,edge and eint types
and do the gathering of the other informations in the code. This would make
the list more os-agnostic.
The list itself does describe the interconnections between the controllers, so
I think it's not false per se, just the multitude of probably redundant types
used should probably go down.
The other option could be to really change to individual initializers for the
different implementations and have all the data in the code instead of the dt.
For this I've compared all the different implementations and it seems this
would lead to at least handlers for s3c2410, s3c2440, s3c2442, s3c2412 and
s3c2443. For the time being they will be in the code in any case, because of
all the non-dt boards
If anyone is interested, the comparison can be found on [0].
Btw. do you know if it would have bad effects to register (but not use) for
example the cam interrupt-handler on a machine that does not have it. (The
additional cam, cf and spi1 interrupts are the only things differing between
the s3c2443 and s3c2416 SoCs).
> > The basic problem is, that each individual interrupt inside one of the
> > controllers might need a different handler and access a specific parent
> > interrupt. For example the uart0-rx,tx,err interrupts in the subintc must
> > ack/mask the uart0 interrupt in the main intc; similar for a lot of other
> > interrupts. And the s3c24xx,irqlist provides this mapping to handler and
> > parent, so it does not need to be codified.
>
> I believe the three node example that I listed above should be able to
> handle this, but yes, it might require additional code to support it.
> For example, the uart device node has listed three interrupts. The
> uart controller drivers can register three separate interrupt handlers
> for these interrupts. As far as the interrupt handling for 'main'
> controller, I see that this is very similar to the way interrupt
> combiner module has been coded for exynos soc's. So the combiner
> interrupt controller code in mach-exynos/common.c file can be used a
> reference on how this can be handled.
I'v seen the combiner code as well, but from the code itself I've not managed
to understand the combiner this well yet. And Exynos datasheets, to get a
textual description of the combiner, are not this easy to come by ;-) .
> > And of course the second problem this approach should solve is, that the
> > interrupts in the controllers differ and also move between most of the
> > s3c24xx sub-architectures.
>
> Yes, I understand how difficult it can get while writing a generalized
> code for all soc's in s3c24xx family.
again, thanks for taking the time to read and answer all these mails :-)
Thanks
Heiko
[0]
https://docs.google.com/spreadsheet/pub?key=0Am5FJAmTa7wydENkdkwwRVA5eEVTb09fb0RtcGhnTlE&output=html
^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC 1/2] ARM: S3C24XX: add devicetree support for interrupts
2012-11-27 16:24 ` Heiko Stübner
@ 2012-11-28 14:10 ` Thomas Abraham
0 siblings, 0 replies; 10+ messages in thread
From: Thomas Abraham @ 2012-11-28 14:10 UTC (permalink / raw)
To: linux-arm-kernel
Hi Heiko,
On 27 November 2012 21:54, Heiko St?bner <heiko@sntech.de> wrote:
[...]
>
>
> Because of the mails from yesterday I took another look at my code, after
> letting it sit for the previous days and I found more optimization
> possiblities.
>
> It should be possible to trim the irqtypes down to level,edge and eint types
> and do the gathering of the other informations in the code. This would make
> the list more os-agnostic.
> The list itself does describe the interconnections between the controllers, so
> I think it's not false per se, just the multitude of probably redundant types
> used should probably go down.
Ok.
>
> The other option could be to really change to individual initializers for the
> different implementations and have all the data in the code instead of the dt.
> For this I've compared all the different implementations and it seems this
> would lead to at least handlers for s3c2410, s3c2440, s3c2442, s3c2412 and
> s3c2443. For the time being they will be in the code in any case, because of
> all the non-dt boards
I did feel that it this could have been handled with dt + some kernel
code for all s3c24xx soc's but probably I am under estimating the
effort here. If it helps, the dt code need not be intermixed with
non-dt code and there can be runtime check on whether to take dt and
non-dt path.
>
> If anyone is interested, the comparison can be found on [0].
>
>
> Btw. do you know if it would have bad effects to register (but not use) for
> example the cam interrupt-handler on a machine that does not have it. (The
> additional cam, cf and spi1 interrupts are the only things differing between
> the s3c2443 and s3c2416 SoCs).
I am not aware of any bad effects of this (if those interrupts are
never enabled). But logically, it might be better not to do this. Is
this something that cannot be handled by checking the machine
compatible value.
>
>
[...]
>
> I'v seen the combiner code as well, but from the code itself I've not managed
> to understand the combiner this well yet. And Exynos datasheets, to get a
> textual description of the combiner, are not this easy to come by ;-) .
Yes, I understand. Basically interrupt combiner combines upto 8
interrupts into one interrupt that is delivered to combiner's
interrupt parent, which is the gic interrupt controller in case of
exynos. There are 16 to 32 interrupt combiners in a soc. Combiner has
the basic mask, pend and unmask registers.
Thanks,
Thomas.
[...]
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2012-11-28 14:10 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-25 0:45 [RFC 0/2] ARM: S3C24XX: Add devicetree support Heiko Stübner
2012-11-25 0:47 ` [RFC 1/2] ARM: S3C24XX: add devicetree support for interrupts Heiko Stübner
2012-11-26 11:03 ` Thomas Abraham
2012-11-26 12:13 ` Heiko Stübner
2012-11-26 15:23 ` Thomas Abraham
2012-11-26 16:04 ` Heiko Stübner
2012-11-27 6:12 ` Thomas Abraham
2012-11-27 16:24 ` Heiko Stübner
2012-11-28 14:10 ` Thomas Abraham
2012-11-25 0:48 ` [RFC 2/2] ARM: S3C24XX: Add devicetree support and dt-board file for s3c2416 SoCs Heiko Stübner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).