linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] DT bindings Cortex A9 peripherals
@ 2011-06-01 16:37 Rob Herring
  2011-06-01 16:37 ` [PATCH 1/3] ARM: pmu: add OF probing support Rob Herring
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Rob Herring @ 2011-06-01 16:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

This series adds DT based initialization and bindings for the pmu, gic and l2x0
found on Cortex-A9's.

Rob

Rob Herring (3):
  ARM: pmu: add OF probing support
  ARM: gic: add OF based initialization
  ARM: l2x0: Add OF based initialization

 arch/arm/common/gic.c                      |   35 +++++++++++++++++++++++++++
 arch/arm/include/asm/hardware/cache-l2x0.h |    1 +
 arch/arm/include/asm/hardware/gic.h        |    1 +
 arch/arm/kernel/pmu.c                      |   23 ++++++++++++++----
 arch/arm/mm/cache-l2x0.c                   |   36 ++++++++++++++++++++++++++++
 5 files changed, 91 insertions(+), 5 deletions(-)

-- 
1.7.4.1

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

* [PATCH 1/3] ARM: pmu: add OF probing support
  2011-06-01 16:37 [PATCH 0/3] DT bindings Cortex A9 peripherals Rob Herring
@ 2011-06-01 16:37 ` Rob Herring
  2011-06-01 18:37   ` Olof Johansson
  2011-06-01 16:37 ` [PATCH 2/3] ARM: gic: add OF based initialization Rob Herring
  2011-06-01 16:37 ` [PATCH 3/3] ARM: l2x0: Add " Rob Herring
  2 siblings, 1 reply; 12+ messages in thread
From: Rob Herring @ 2011-06-01 16:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

Add OF match table to enable OF style driver binding. The dts entry is like
this:

pmu {
	compatible = "arm,cortex-a9-pmu";
	interrupts = <100 101>;
};

The use of pdev->id as an index breaks with OF device binding, so set the type
based on the OF compatible string.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/kernel/pmu.c |   23 ++++++++++++++++++-----
 1 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c
index 2c79eec..41bc972 100644
--- a/arch/arm/kernel/pmu.c
+++ b/arch/arm/kernel/pmu.c
@@ -27,27 +27,40 @@ static struct platform_device *pmu_devices[ARM_NUM_PMU_DEVICES];
 
 static int __devinit pmu_device_probe(struct platform_device *pdev)
 {
+	enum arm_pmu_type type = pdev->id;
 
-	if (pdev->id < 0 || pdev->id >= ARM_NUM_PMU_DEVICES) {
+	if (pdev->dev.of_node)
+		type = ARM_PMU_DEVICE_CPU;
+
+	if (type < 0 || type >= ARM_NUM_PMU_DEVICES) {
 		pr_warning("received registration request for unknown "
 				"device %d\n", pdev->id);
 		return -EINVAL;
 	}
 
-	if (pmu_devices[pdev->id])
+	if (pmu_devices[type])
 		pr_warning("registering new PMU device type %d overwrites "
-				"previous registration!\n", pdev->id);
+				"previous registration!\n", type);
 	else
 		pr_info("registered new PMU device of type %d\n",
-				pdev->id);
+				type);
 
-	pmu_devices[pdev->id] = pdev;
+	pmu_devices[type] = pdev;
 	return 0;
 }
 
+static struct of_device_id pmu_device_ids[] = {
+	{ .compatible = "arm,cortex-a9-pmu" },
+	{ .compatible = "arm,cortex-a8-pmu" },
+	{ .compatible = "arm,arm1136-pmu" },
+	{ .compatible = "arm,arm1176-pmu" },
+	{},
+};
+
 static struct platform_driver pmu_driver = {
 	.driver		= {
 		.name	= "arm-pmu",
+		.of_match_table = pmu_device_ids,
 	},
 	.probe		= pmu_device_probe,
 };
-- 
1.7.4.1

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

* [PATCH 2/3] ARM: gic: add OF based initialization
  2011-06-01 16:37 [PATCH 0/3] DT bindings Cortex A9 peripherals Rob Herring
  2011-06-01 16:37 ` [PATCH 1/3] ARM: pmu: add OF probing support Rob Herring
@ 2011-06-01 16:37 ` Rob Herring
  2011-06-01 16:37 ` [PATCH 3/3] ARM: l2x0: Add " Rob Herring
  2 siblings, 0 replies; 12+ messages in thread
From: Rob Herring @ 2011-06-01 16:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

This adds gic initialization using device tree data. An example device tree
binding looks like this:

intc: interrupt-controller at fff11000 {
        compatible = "arm,cortex-a9-gic";
        #interrupt-cells = <1>;
        interrupt-controller;
        reg = <0xfff11000 0x1000>,
              <0xfff10100 0x100>;
        irq-start = <29>;
};

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/common/gic.c               |   35 +++++++++++++++++++++++++++++++++++
 arch/arm/include/asm/hardware/gic.h |    1 +
 2 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 4ddd0a6..d44ca5b 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -28,6 +28,8 @@
 #include <linux/smp.h>
 #include <linux/cpumask.h>
 #include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
@@ -401,3 +403,36 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
 	writel_relaxed(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);
 }
 #endif
+
+#ifdef CONFIG_OF
+static struct of_device_id gic_ids[] __initdata = {
+	{ .compatible = "arm,cortex-a9-gic" },
+};
+
+void __init gic_of_init(void)
+{
+	struct device_node *np;
+	void __iomem *cpu_base;
+	void __iomem *dist_base;
+	__u32 irq_start = 16;
+	const __be32 *val;
+
+	np = of_find_matching_node(NULL, gic_ids);
+	if (!np)
+		panic("unable to find compatible gic node in dtb\n");
+
+	dist_base = of_iomap(np, 0);
+	if (!dist_base)
+		panic("unable to map gic dist registers\n");
+
+	cpu_base = of_iomap(np, 1);
+	if (!cpu_base)
+		panic("unable to map gic cpu registers\n");
+
+	if ((val = of_get_property(np, "irq-start", NULL)) != NULL)
+		irq_start = of_read_ulong(val, 1);
+	of_node_put(np);
+
+	gic_init(0, irq_start, dist_base, cpu_base);
+}
+#endif
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index 0691f9d..954a08e 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -37,6 +37,7 @@ extern void __iomem *gic_cpu_base_addr;
 extern struct irq_chip gic_arch_extn;
 
 void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *);
+void gic_of_init(void);
 void gic_secondary_init(unsigned int);
 void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
 void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
-- 
1.7.4.1

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

* [PATCH 3/3] ARM: l2x0: Add OF based initialization
  2011-06-01 16:37 [PATCH 0/3] DT bindings Cortex A9 peripherals Rob Herring
  2011-06-01 16:37 ` [PATCH 1/3] ARM: pmu: add OF probing support Rob Herring
  2011-06-01 16:37 ` [PATCH 2/3] ARM: gic: add OF based initialization Rob Herring
@ 2011-06-01 16:37 ` Rob Herring
  2011-06-01 18:40   ` Olof Johansson
  2 siblings, 1 reply; 12+ messages in thread
From: Rob Herring @ 2011-06-01 16:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

This adds probing for pl310 cache controller via device tree. An example
binding looks like this:

L2: l2-cache {
	compatible = "arm,pl310-cache", "cache";
	reg = <0xfff12000 0x1000>;
	aux-value = <0>;
	aux-mask = <0xffffffff>;
	cache-unified;
	cache-level = <2>;
};

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/include/asm/hardware/cache-l2x0.h |    1 +
 arch/arm/mm/cache-l2x0.c                   |   36 ++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index 16bd480..1d36632 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -74,6 +74,7 @@
 
 #ifndef __ASSEMBLY__
 extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
+extern int l2x0_of_init(void);
 #endif
 
 #endif
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index ef59099..6dd521c 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -16,9 +16,12 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
+#include <linux/err.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 
 #include <asm/cacheflush.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -344,3 +347,36 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
 	printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
 			ways, cache_id, aux, l2x0_size);
 }
+
+#ifdef CONFIG_OF
+static struct of_device_id l2x0_ids[] __initdata = {
+	{ .compatible = "arm,pl310-cache" },
+	{ .compatible = "arm,l220-cache" },
+	{ .compatible = "arm,l210-cache" },
+};
+
+int __init l2x0_of_init(void)
+{
+	struct device_node *np;
+	void __iomem *l2_base;
+	__u32 aux_val = 0;
+	__u32 aux_mask = ~0UL;
+	const __be32 *val;
+
+	np = of_find_matching_node(NULL, l2x0_ids);
+	if (!np)
+		return -ENODEV;
+	l2_base = of_iomap(np, 0);
+	if (!l2_base)
+		return -ENOMEM;
+
+	if ((val = of_get_property(np, "aux-value", NULL)) != NULL);
+		aux_val = of_read_ulong(val, 1);
+
+	if ((val = of_get_property(np, "aux-mask", NULL)) != NULL);
+		aux_mask = of_read_ulong(val, 1);
+
+	l2x0_init(l2_base, aux_val, aux_mask);
+	return 0;
+}
+#endif
-- 
1.7.4.1

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

* [PATCH 1/3] ARM: pmu: add OF probing support
  2011-06-01 16:37 ` [PATCH 1/3] ARM: pmu: add OF probing support Rob Herring
@ 2011-06-01 18:37   ` Olof Johansson
  0 siblings, 0 replies; 12+ messages in thread
From: Olof Johansson @ 2011-06-01 18:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 1, 2011 at 9:37 AM, Rob Herring <robherring2@gmail.com> wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> Add OF match table to enable OF style driver binding. The dts entry is like
> this:
>
> pmu {
> ? ? ? ?compatible = "arm,cortex-a9-pmu";
> ? ? ? ?interrupts = <100 101>;
> };
>
> The use of pdev->id as an index breaks with OF device binding, so set the type
> based on the OF compatible string.

Even though they're simple, new bindings like these need to be
documented. Current location for that is
Documentation/devicetree/bindings/.

Can you start an ARM directory there and add corresponding docs for the this?


Thanks!

-Olof

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

* [PATCH 3/3] ARM: l2x0: Add OF based initialization
  2011-06-01 16:37 ` [PATCH 3/3] ARM: l2x0: Add " Rob Herring
@ 2011-06-01 18:40   ` Olof Johansson
  2011-06-01 19:01     ` Rob Herring
  0 siblings, 1 reply; 12+ messages in thread
From: Olof Johansson @ 2011-06-01 18:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 1, 2011 at 9:37 AM, Rob Herring <robherring2@gmail.com> wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> This adds probing for pl310 cache controller via device tree. An example
> binding looks like this:
>
> L2: l2-cache {
> ? ? ? ?compatible = "arm,pl310-cache", "cache";

"cache" is too generic to be useful. "arm,pl2x0-cache" would be a more
meaningful fallback, I think?

(Same comment as for 1/3: The bindings need to be documented. Same
applies to 2/3, obviousy).

-Olof

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

* [PATCH 3/3] ARM: l2x0: Add OF based initialization
  2011-06-01 18:40   ` Olof Johansson
@ 2011-06-01 19:01     ` Rob Herring
  0 siblings, 0 replies; 12+ messages in thread
From: Rob Herring @ 2011-06-01 19:01 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/01/2011 01:40 PM, Olof Johansson wrote:
> On Wed, Jun 1, 2011 at 9:37 AM, Rob Herring<robherring2@gmail.com>  wrote:
>> From: Rob Herring<rob.herring@calxeda.com>
>>
>> This adds probing for pl310 cache controller via device tree. An example
>> binding looks like this:
>>
>> L2: l2-cache {
>>         compatible = "arm,pl310-cache", "cache";
>
> "cache" is too generic to be useful. "arm,pl2x0-cache" would be a more
> meaningful fallback, I think?

I agree. This is what ePAPR says should be present for caches along with 
a more specific string.

Based on the prior discussion on pmu naming, it should be the specific 
model. There is no such thing as a pl2x0. The models of L2 controllers 
the cache-l2x0.c code supports are:

PL310
L220
L210

And my compatible strings reflect that.

>
> (Same comment as for 1/3: The bindings need to be documented. Same
> applies to 2/3, obviousy).
>

Will do.

Rob

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

* [PATCH 2/3] ARM: gic: add OF based initialization
  2011-06-07 14:22 [PATCH v2 0/3] DT bindings for Cortex A9 peripherals Rob Herring
@ 2011-06-07 14:22 ` Rob Herring
  2011-06-13 16:53   ` Grant Likely
  0 siblings, 1 reply; 12+ messages in thread
From: Rob Herring @ 2011-06-07 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

This adds gic initialization using device tree data. An example device tree
binding looks like this:

intc: interrupt-controller at fff11000 {
        compatible = "arm,cortex-a9-gic";
        #interrupt-cells = <1>;
        interrupt-controller;
        reg = <0xfff11000 0x1000>,
              <0xfff10100 0x100>;
        irq-start = <29>;
};

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 Documentation/devicetree/bindings/arm/gic.txt |   31 +++++++++++++++++++++
 arch/arm/common/gic.c                         |   36 +++++++++++++++++++++++++
 arch/arm/include/asm/hardware/gic.h           |    1 +
 3 files changed, 68 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/gic.txt

diff --git a/Documentation/devicetree/bindings/arm/gic.txt b/Documentation/devicetree/bindings/arm/gic.txt
new file mode 100644
index 0000000..491a503
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/gic.txt
@@ -0,0 +1,31 @@
+* ARM Generic Interrupt Controller
+
+Some ARM cores have an interrupt controller called GIC. The ARM GIC
+representation in the device tree should be done as under:-
+
+Required properties:
+
+- compatible : should be one of:
+	"arm,cortex-a9-gic"
+	"arm,arm11mp-gic"
+	"nvidia,tegra250-gic"
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode an
+  interrupt source.  The type shall be a <u32> and the value shall be 1.
+- reg : Specifies base physical address(s) and size of the GIC registers. The
+  first 2 values are the GIC distributor register base and size. The 2nd 2
+  values are the GIC cpu interface register base and size.
+- irq-start : The first actual interrupt that is connected to h/w.
+
+Example:
+
+intc: interrupt-controller at fff11000 {
+        compatible = "arm,cortex-a9-gic";
+        #interrupt-cells = <1>;
+        interrupt-controller;
+        reg = <0xfff11000 0x1000>,
+              <0xfff10100 0x100>;
+        irq-start = <29>;
+};
+
+
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 4ddd0a6..024414d 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -28,6 +28,8 @@
 #include <linux/smp.h>
 #include <linux/cpumask.h>
 #include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
@@ -401,3 +403,37 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
 	writel_relaxed(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);
 }
 #endif
+
+#ifdef CONFIG_OF
+static struct of_device_id gic_ids[] __initdata = {
+	{ .compatible = "arm,cortex-a9-gic" },
+};
+
+void __init gic_of_init(void)
+{
+	struct device_node *np;
+	void __iomem *cpu_base;
+	void __iomem *dist_base;
+	__u32 irq_start = 16;
+	const __be32 *val;
+
+	np = of_find_matching_node(NULL, gic_ids);
+	if (!np)
+		panic("unable to find compatible gic node in dtb\n");
+
+	dist_base = of_iomap(np, 0);
+	if (!dist_base)
+		panic("unable to map gic dist registers\n");
+
+	cpu_base = of_iomap(np, 1);
+	if (!cpu_base)
+		panic("unable to map gic cpu registers\n");
+
+	val = of_get_property(np, "irq-start", NULL);
+	if (val != NULL)
+		irq_start = of_read_ulong(val, 1);
+	of_node_put(np);
+
+	gic_init(0, irq_start, dist_base, cpu_base);
+}
+#endif
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index 0691f9d..954a08e 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -37,6 +37,7 @@ extern void __iomem *gic_cpu_base_addr;
 extern struct irq_chip gic_arch_extn;
 
 void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *);
+void gic_of_init(void);
 void gic_secondary_init(unsigned int);
 void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
 void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
-- 
1.7.4.1

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

* [PATCH 2/3] ARM: gic: add OF based initialization
  2011-06-07 14:22 ` [PATCH 2/3] ARM: gic: add OF based initialization Rob Herring
@ 2011-06-13 16:53   ` Grant Likely
  2011-06-13 21:39     ` Rob Herring
  2011-06-13 22:14     ` Russell King - ARM Linux
  0 siblings, 2 replies; 12+ messages in thread
From: Grant Likely @ 2011-06-13 16:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 07, 2011 at 09:22:20AM -0500, Rob Herring wrote:
> From: Rob Herring <rob.herring@calxeda.com>
> 
> This adds gic initialization using device tree data. An example device tree
> binding looks like this:
> 
> intc: interrupt-controller at fff11000 {
>         compatible = "arm,cortex-a9-gic";
>         #interrupt-cells = <1>;
>         interrupt-controller;
>         reg = <0xfff11000 0x1000>,
>               <0xfff10100 0x100>;
>         irq-start = <29>;
> };
> 
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> ---
>  Documentation/devicetree/bindings/arm/gic.txt |   31 +++++++++++++++++++++
>  arch/arm/common/gic.c                         |   36 +++++++++++++++++++++++++
>  arch/arm/include/asm/hardware/gic.h           |    1 +
>  3 files changed, 68 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/arm/gic.txt
> 
> diff --git a/Documentation/devicetree/bindings/arm/gic.txt b/Documentation/devicetree/bindings/arm/gic.txt
> new file mode 100644
> index 0000000..491a503
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/gic.txt
> @@ -0,0 +1,31 @@
> +* ARM Generic Interrupt Controller
> +
> +Some ARM cores have an interrupt controller called GIC. The ARM GIC
> +representation in the device tree should be done as under:-
> +
> +Required properties:
> +
> +- compatible : should be one of:
> +	"arm,cortex-a9-gic"
> +	"arm,arm11mp-gic"
> +	"nvidia,tegra250-gic"

This doesn't match the implementation in this patch.  The
implementation only matches against the cortex-a9 gic.

Also, I expect that the gic is different between the arm,cortex-a9-gic
and the arm,arm11-mp-gic.  Is the tegra also a different gic
implementation?  Or can it be expected that the tegra gic will simply
claim compatibility with the a9 gic?

> +- interrupt-controller : Identifies the node as an interrupt controller
> +- #interrupt-cells : Specifies the number of cells needed to encode an
> +  interrupt source.  The type shall be a <u32> and the value shall be 1.
> +- reg : Specifies base physical address(s) and size of the GIC registers. The
> +  first 2 values are the GIC distributor register base and size. The 2nd 2
> +  values are the GIC cpu interface register base and size.
> +- irq-start : The first actual interrupt that is connected to h/w.

Drop irq-start.  That's a Linux internal implementation detail, and
Linux can easily handle dynamic assignment of irq ranges.

If board support code still has special needs on specific platforms,
then we can manually override the assigned range for that specific
platform only as a short term workaround.

> +
> +Example:
> +
> +intc: interrupt-controller at fff11000 {
> +        compatible = "arm,cortex-a9-gic";
> +        #interrupt-cells = <1>;
> +        interrupt-controller;
> +        reg = <0xfff11000 0x1000>,
> +              <0xfff10100 0x100>;
> +        irq-start = <29>;
> +};
> +
> +
> diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
> index 4ddd0a6..024414d 100644
> --- a/arch/arm/common/gic.c
> +++ b/arch/arm/common/gic.c
> @@ -28,6 +28,8 @@
>  #include <linux/smp.h>
>  #include <linux/cpumask.h>
>  #include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
>  
>  #include <asm/irq.h>
>  #include <asm/mach/irq.h>
> @@ -401,3 +403,37 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
>  	writel_relaxed(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);
>  }
>  #endif
> +
> +#ifdef CONFIG_OF
> +static struct of_device_id gic_ids[] __initdata = {
> +	{ .compatible = "arm,cortex-a9-gic" },
> +};
> +
> +void __init gic_of_init(void)
> +{
> +	struct device_node *np;
> +	void __iomem *cpu_base;
> +	void __iomem *dist_base;
> +	__u32 irq_start = 16;
> +	const __be32 *val;
> +
> +	np = of_find_matching_node(NULL, gic_ids);
> +	if (!np)
> +		panic("unable to find compatible gic node in dtb\n");
> +
> +	dist_base = of_iomap(np, 0);
> +	if (!dist_base)
> +		panic("unable to map gic dist registers\n");
> +
> +	cpu_base = of_iomap(np, 1);
> +	if (!cpu_base)
> +		panic("unable to map gic cpu registers\n");
> +
> +	val = of_get_property(np, "irq-start", NULL);
> +	if (val != NULL)
> +		irq_start = of_read_ulong(val, 1);
> +	of_node_put(np);
> +
> +	gic_init(0, irq_start, dist_base, cpu_base);

This can only handle a single gic in a system.  This is a start, but
multiple interrupt controllers must be supported, like for the Samsung
socs.

I've been toying with writing some code that walks the interrupt
controller tree, finds the root controller, and then sets up each
child controller as a cascade.

> +}
> +#endif
> diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
> index 0691f9d..954a08e 100644
> --- a/arch/arm/include/asm/hardware/gic.h
> +++ b/arch/arm/include/asm/hardware/gic.h
> @@ -37,6 +37,7 @@ extern void __iomem *gic_cpu_base_addr;
>  extern struct irq_chip gic_arch_extn;
>  
>  void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *);
> +void gic_of_init(void);
>  void gic_secondary_init(unsigned int);
>  void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
>  void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
> -- 
> 1.7.4.1
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

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

* [PATCH 2/3] ARM: gic: add OF based initialization
  2011-06-13 16:53   ` Grant Likely
@ 2011-06-13 21:39     ` Rob Herring
  2011-06-13 22:14     ` Russell King - ARM Linux
  1 sibling, 0 replies; 12+ messages in thread
From: Rob Herring @ 2011-06-13 21:39 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/13/2011 11:53 AM, Grant Likely wrote:
> On Tue, Jun 07, 2011 at 09:22:20AM -0500, Rob Herring wrote:
>> From: Rob Herring <rob.herring@calxeda.com>
>>
>> This adds gic initialization using device tree data. An example device tree
>> binding looks like this:
>>
>> intc: interrupt-controller at fff11000 {
>>         compatible = "arm,cortex-a9-gic";
>>         #interrupt-cells = <1>;
>>         interrupt-controller;
>>         reg = <0xfff11000 0x1000>,
>>               <0xfff10100 0x100>;
>>         irq-start = <29>;
>> };
>>
>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
>> ---
>>  Documentation/devicetree/bindings/arm/gic.txt |   31 +++++++++++++++++++++
>>  arch/arm/common/gic.c                         |   36 +++++++++++++++++++++++++
>>  arch/arm/include/asm/hardware/gic.h           |    1 +
>>  3 files changed, 68 insertions(+), 0 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/arm/gic.txt
>>
>> diff --git a/Documentation/devicetree/bindings/arm/gic.txt b/Documentation/devicetree/bindings/arm/gic.txt
>> new file mode 100644
>> index 0000000..491a503
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/arm/gic.txt
>> @@ -0,0 +1,31 @@
>> +* ARM Generic Interrupt Controller
>> +
>> +Some ARM cores have an interrupt controller called GIC. The ARM GIC
>> +representation in the device tree should be done as under:-
>> +
>> +Required properties:
>> +
>> +- compatible : should be one of:
>> +	"arm,cortex-a9-gic"
>> +	"arm,arm11mp-gic"
>> +	"nvidia,tegra250-gic"
> 
> This doesn't match the implementation in this patch.  The
> implementation only matches against the cortex-a9 gic.
> 
I was just trying to make the doc somewhat complete although I'm missing
msm.

> Also, I expect that the gic is different between the arm,cortex-a9-gic
> and the arm,arm11-mp-gic.  Is the tegra also a different gic
> implementation?  Or can it be expected that the tegra gic will simply
> claim compatibility with the a9 gic?
> 
They are all using the same code today, so yes thay are all compatible.
I'm not even sure that tegra is different than standard A9. I pulled
that from your tree. There are some h/w differences in terms of
powergating of the GIC or not and when. How to handle that is still
being hashed out a bit.

>> +- interrupt-controller : Identifies the node as an interrupt controller
>> +- #interrupt-cells : Specifies the number of cells needed to encode an
>> +  interrupt source.  The type shall be a <u32> and the value shall be 1.
>> +- reg : Specifies base physical address(s) and size of the GIC registers. The
>> +  first 2 values are the GIC distributor register base and size. The 2nd 2
>> +  values are the GIC cpu interface register base and size.
>> +- irq-start : The first actual interrupt that is connected to h/w.
> 
> Drop irq-start.  That's a Linux internal implementation detail, and
> Linux can easily handle dynamic assignment of irq ranges.
> 
> If board support code still has special needs on specific platforms,
> then we can manually override the assigned range for that specific
> platform only as a short term workaround.
> 

It's really about skipping the SGI interrupts and unused PPIs which is
h/w specific. That isn't really necessary AFAICT, but I'm not too sure
why it was even done in the first place.

>> +
>> +Example:
>> +
>> +intc: interrupt-controller at fff11000 {
>> +        compatible = "arm,cortex-a9-gic";
>> +        #interrupt-cells = <1>;
>> +        interrupt-controller;
>> +        reg = <0xfff11000 0x1000>,
>> +              <0xfff10100 0x100>;
>> +        irq-start = <29>;
>> +};
>> +
>> +
>> diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
>> index 4ddd0a6..024414d 100644
>> --- a/arch/arm/common/gic.c
>> +++ b/arch/arm/common/gic.c
>> @@ -28,6 +28,8 @@
>>  #include <linux/smp.h>
>>  #include <linux/cpumask.h>
>>  #include <linux/io.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>>  
>>  #include <asm/irq.h>
>>  #include <asm/mach/irq.h>
>> @@ -401,3 +403,37 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
>>  	writel_relaxed(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);
>>  }
>>  #endif
>> +
>> +#ifdef CONFIG_OF
>> +static struct of_device_id gic_ids[] __initdata = {
>> +	{ .compatible = "arm,cortex-a9-gic" },
>> +};
>> +
>> +void __init gic_of_init(void)
>> +{
>> +	struct device_node *np;
>> +	void __iomem *cpu_base;
>> +	void __iomem *dist_base;
>> +	__u32 irq_start = 16;
>> +	const __be32 *val;
>> +
>> +	np = of_find_matching_node(NULL, gic_ids);
>> +	if (!np)
>> +		panic("unable to find compatible gic node in dtb\n");
>> +
>> +	dist_base = of_iomap(np, 0);
>> +	if (!dist_base)
>> +		panic("unable to map gic dist registers\n");
>> +
>> +	cpu_base = of_iomap(np, 1);
>> +	if (!cpu_base)
>> +		panic("unable to map gic cpu registers\n");
>> +
>> +	val = of_get_property(np, "irq-start", NULL);
>> +	if (val != NULL)
>> +		irq_start = of_read_ulong(val, 1);
>> +	of_node_put(np);
>> +
>> +	gic_init(0, irq_start, dist_base, cpu_base);
> 
> This can only handle a single gic in a system.  This is a start, but
> multiple interrupt controllers must be supported, like for the Samsung
> socs.

Huh? Only Realview boards have a 2nd level controller. The Samsung
boards are using the VIC. Are you referring to something not in mainline
yet?

> 
> I've been toying with writing some code that walks the interrupt
> controller tree, finds the root controller, and then sets up each
> child controller as a cascade.
> 

That would be interesting especially if gpio controllers were included.
It's probably overkill for just the few platforms that have multiple GICs.

Rob

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

* [PATCH 2/3] ARM: gic: add OF based initialization
  2011-06-13 16:53   ` Grant Likely
  2011-06-13 21:39     ` Rob Herring
@ 2011-06-13 22:14     ` Russell King - ARM Linux
  2011-06-14 13:56       ` Grant Likely
  1 sibling, 1 reply; 12+ messages in thread
From: Russell King - ARM Linux @ 2011-06-13 22:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 13, 2011 at 10:53:16AM -0600, Grant Likely wrote:
> On Tue, Jun 07, 2011 at 09:22:20AM -0500, Rob Herring wrote:
> > +- interrupt-controller : Identifies the node as an interrupt controller
> > +- #interrupt-cells : Specifies the number of cells needed to encode an
> > +  interrupt source.  The type shall be a <u32> and the value shall be 1.
> > +- reg : Specifies base physical address(s) and size of the GIC registers. The
> > +  first 2 values are the GIC distributor register base and size. The 2nd 2
> > +  values are the GIC cpu interface register base and size.
> > +- irq-start : The first actual interrupt that is connected to h/w.
> 
> Drop irq-start.  That's a Linux internal implementation detail, and
> Linux can easily handle dynamic assignment of irq ranges.

Something has to be done with the IRQs on GIC, because Linux probably
won't have a 1:1 mapping between the hardware IRQ numbers and the Linux
IRQ numbers

Have you seen the patches from Marc which deal with the per-CPU
interrupts by creating individual Linux IRQ numbers for each CPU for
each per-CPU interrupt?  So you can end up with 16 per-CPU x 4 CPUs =
64 Linux interrupts for 16 "hardware" interrupts.

How would DT deal with that - and how would you specify a connection
between a per-CPU PMU and one of the per-CPU interrupts?

The sensible thing from a DT point of view I think would be to ignore
that abstraction, and have some kind of mapping layer between DT and
drivers which knew about that.  But that sounds like a world of pain.

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

* [PATCH 2/3] ARM: gic: add OF based initialization
  2011-06-13 22:14     ` Russell King - ARM Linux
@ 2011-06-14 13:56       ` Grant Likely
  0 siblings, 0 replies; 12+ messages in thread
From: Grant Likely @ 2011-06-14 13:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 13, 2011 at 4:14 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Mon, Jun 13, 2011 at 10:53:16AM -0600, Grant Likely wrote:
>> On Tue, Jun 07, 2011 at 09:22:20AM -0500, Rob Herring wrote:
>> > +- interrupt-controller : Identifies the node as an interrupt controller
>> > +- #interrupt-cells : Specifies the number of cells needed to encode an
>> > + ?interrupt source. ?The type shall be a <u32> and the value shall be 1.
>> > +- reg : Specifies base physical address(s) and size of the GIC registers. The
>> > + ?first 2 values are the GIC distributor register base and size. The 2nd 2
>> > + ?values are the GIC cpu interface register base and size.
>> > +- irq-start : The first actual interrupt that is connected to h/w.
>>
>> Drop irq-start. ?That's a Linux internal implementation detail, and
>> Linux can easily handle dynamic assignment of irq ranges.
>
> Something has to be done with the IRQs on GIC, because Linux probably
> won't have a 1:1 mapping between the hardware IRQ numbers and the Linux
> IRQ numbers
>
> Have you seen the patches from Marc which deal with the per-CPU
> interrupts by creating individual Linux IRQ numbers for each CPU for
> each per-CPU interrupt? ?So you can end up with 16 per-CPU x 4 CPUs =
> 64 Linux interrupts for 16 "hardware" interrupts.
>
> How would DT deal with that - and how would you specify a connection
> between a per-CPU PMU and one of the per-CPU interrupts?

In general, bindings focus on the hardware and hardware configuration
instead of what Linux needs internally.  For a lot of interrupt
controllers, an irq specifier consists of two u32 values.  The first
value being the hardware irq number (perhaps 0-15 in this case), and
the second value being a set of flags.

Without looking deeply and the GIC interface details, I suspect that
the CPU affinity would best be represented as a field in the flags
value.

The per-CPU PMU connections then wouldn't be any different from any
other irq in that the irq specifier would include a CPU affinity
value.

>
> The sensible thing from a DT point of view I think would be to ignore
> that abstraction, and have some kind of mapping layer between DT and
> drivers which knew about that.

Yup, and that is exactly what is done.  On powerpc it uses the virtual
irq infrastructure.  For ARM and everyone else, there are patches on
list for irq_domain which implements the required behaviour.  The
interrupt controller driver can make decisions about how to map the
hardware irq to a linux irq number.  For most irq controllers, it will
be a simple 1:1 mapping, but for something complex like the gic, it
can do something different if need be.

> ?But that sounds like a world of pain.

Actually, it turns out not to be.  We've been needing/wanting some
form of irq_domains anyway for a while now to better manage hwirq ->
linuxirq mappings.  Adding DT to the mix means also suppling a DT
decode function to get the hwirq number from the interrupt specifier.

I'll be reposting a bunch of patches in the next few days that fills
in most of the missing pieces for irq mapping.

g.

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

end of thread, other threads:[~2011-06-14 13:56 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-06-01 16:37 [PATCH 0/3] DT bindings Cortex A9 peripherals Rob Herring
2011-06-01 16:37 ` [PATCH 1/3] ARM: pmu: add OF probing support Rob Herring
2011-06-01 18:37   ` Olof Johansson
2011-06-01 16:37 ` [PATCH 2/3] ARM: gic: add OF based initialization Rob Herring
2011-06-01 16:37 ` [PATCH 3/3] ARM: l2x0: Add " Rob Herring
2011-06-01 18:40   ` Olof Johansson
2011-06-01 19:01     ` Rob Herring
  -- strict thread matches above, loose matches on Subject: below --
2011-06-07 14:22 [PATCH v2 0/3] DT bindings for Cortex A9 peripherals Rob Herring
2011-06-07 14:22 ` [PATCH 2/3] ARM: gic: add OF based initialization Rob Herring
2011-06-13 16:53   ` Grant Likely
2011-06-13 21:39     ` Rob Herring
2011-06-13 22:14     ` Russell King - ARM Linux
2011-06-14 13:56       ` Grant Likely

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).