Skip to contentSkip to conversation

ARM: Exynos: Add irq domain and device tree support for interrupt combiner

PATCH RESEND Superseded Thomas Abraham 2 participants 3 messages Dec 11, 2011 – Dec 12, 2011

Subsystems (4)

v1 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

PATCH RESEND 1/1 ARM: Exynos: Add irq domain and device tree support for interrupt combiner

A common irq domain for the interrupts managed by the interrupt combiners is setup. All the instances of irq combiner reference the common irq domain for translating hardware interrupts to linux irq number.

In case of device tree based boot, a interrupt specifier translator is setup that can translate interrupt specifiers for device nodes which use combiner as their interrupt parent.

---
Please ignore the previous post patch since that patch has a compilation error when CONFIG_OF was not defined.

This patch is based on the following tree.
http://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git for-next

 .../bindings/arm/samsung/interrupt-combiner.txt    |   27 +++++++++
 arch/arm/mach-exynos/cpu.c                         |   29 ++++++---
 arch/arm/mach-exynos/irq-combiner.c                |   62 +++++++++++++++++---
 3 files changed, 100 insertions(+), 18 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt
Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt new file +27 -0
new file mode 100644
index 0000000..6c960dc
@@ -0,0 +1,27 @@
+* Samsung Exynos Interrupt Combiner Controller
+
+Samsung's Exynos4 architecture includes a interrupt combiner which can combine
+interrupt sources as a group and provide a single interrupt request for the
+group. The interrupt request from each group are connected to a parent interrupt
+controller, such as GIC in case of Exynos4210.
+
+Required properties:
+- compatible: should be "samsung,exynos4210-combiner".
+- #interrupt-cells: should be <2>. The meaning of the cells are
+	* First Cell: Combiner Group Number.
+	* Second Cell: Interrupt number within the group.
+- reg: Base address and size of interrupt combiner registers.
+- interrupt-controller: Identifies the node as an interrupt controller.
+
+Optional properties:
+- interrupt-parent: pHandle of the parent interrupt controller, if not
+  inherited from the parent node.
+
+Example:
+
+	combiner:interrupt-controller@10440000 {
+		compatible = "samsung,exynos4120-combiner";
+		#interrupt-cells = <2>;
+		interrupt-controoler;
+		reg = <0x10440000 0x1000>;
+	};
arch/arm/mach-exynos/cpu.c +20 -9
index 8e09f34..14f86ba 100644
@@ -37,9 +37,10 @@
 
 unsigned int gic_bank_offset __read_mostly;
 
-extern int combiner_init(unsigned int combiner_nr, void __iomem *base,
-			 unsigned int irq_start);
+extern int combiner_init(unsigned int combiner_nr, void __iomem *base);
 extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq);
+extern int combiner_init_irq_domain(unsigned int irq_base, unsigned int nr_irq,
+					struct device_node *np);
 
 /* Initial IO mappings */
 static struct map_desc exynos_iodesc[] __initdata = {
@@ -242,16 +243,30 @@ static void exynos4_gic_irq_fix_base(struct irq_data *d)
 			    (gic_bank_offset * smp_processor_id());
 }
 
+void __init combiner_of_init(struct device_node *np, struct device_node *parent)
+{
+	int irq;
+
+	if (combiner_init_irq_domain(COMBINER_IRQ(0, 0), MAX_COMBINER_NR *
+					MAX_IRQ_IN_COMBINER, np))
+		BUG();
+	for (irq = 0; irq < MAX_COMBINER_NR; irq++) {
+		combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq));
+		combiner_cascade_irq(irq, IRQ_SPI(irq));
+	}
+}
+
 #ifdef CONFIG_OF
 static const struct of_device_id exynos4_dt_irq_match[] = {
 	{ .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
+	{ .compatible = "samsung,exynos4120-combiner",
+			.data = combiner_of_init, },
 	{},
 };
 #endif
 
 void __init exynos4_init_irq(void)
 {
-	int irq;
 
 	gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
 
@@ -266,12 +281,8 @@ void __init exynos4_init_irq(void)
 	gic_arch_extn.irq_unmask = exynos4_gic_irq_fix_base;
 	gic_arch_extn.irq_mask = exynos4_gic_irq_fix_base;
 
-	for (irq = 0; irq < MAX_COMBINER_NR; irq++) {
-
-		combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
-				COMBINER_IRQ(irq, 0));
-		combiner_cascade_irq(irq, IRQ_SPI(irq));
-	}
+	if (!of_have_populated_dt())
+		combiner_of_init(NULL, NULL);
 
 	/* The parameters of s5p_init_irq() are for VIC init.
 	 * Theses parameters should be NULL and 0 because EXYNOS4
arch/arm/mach-exynos/irq-combiner.c +53 -9

109 lines not on this page · raw message

Signature · 1 line
1.6.6.rc2
#1 lore raw

PATCH RESEND 1/1 ARM: Exynos: Add irq domain and device tree support for interrupt combiner

Quoted 43 lines · Thomas Abraham

A common irq domain for the interrupts managed by the interrupt combiners is setup. All the instances of irq combiner reference the common irq domain for translating hardware interrupts to linux irq number.

In case of device tree based boot, a interrupt specifier translator is setup that can translate interrupt specifiers for device nodes which use combiner as their interrupt parent.

---
Please ignore the previous post patch since that patch has a compilation error when CONFIG_OF was not defined.

This patch is based on the following tree.
http://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git for-next

 .../bindings/arm/samsung/interrupt-combiner.txt    |   27 +++++++++
 arch/arm/mach-exynos/cpu.c                         |   29 ++++++---
 arch/arm/mach-exynos/irq-combiner.c                |   62 +++++++++++++++++---
 3 files changed, 100 insertions(+), 18 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt
Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt new file +15 -0
new file mode 100644
index 0000000..6c960dc
@@ -0,0 +1,27 @@
+* Samsung Exynos Interrupt Combiner Controller
+
+Samsung's Exynos4 architecture includes a interrupt combiner which can combine
+interrupt sources as a group and provide a single interrupt request for the
+group. The interrupt request from each group are connected to a parent interrupt
+controller, such as GIC in case of Exynos4210.
+
+Required properties:
+- compatible: should be "samsung,exynos4210-combiner".
+- #interrupt-cells: should be <2>. The meaning of the cells are
+	* First Cell: Combiner Group Number.
+	* Second Cell: Interrupt number within the group.
+- reg: Base address and size of interrupt combiner registers.
+- interrupt-controller: Identifies the node as an interrupt controller.
+

Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt line 25

Quoted 10 lines
Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt new file +10 -0
+Optional properties:
+- interrupt-parent: pHandle of the parent interrupt controller, if not
+  inherited from the parent node.
+
+Example:
+
+	combiner:interrupt-controller at 10440000 {
+		compatible = "samsung,exynos4120-combiner";
+		#interrupt-cells = <2>;
+		interrupt-controoler;

s/controoler/controller/

Quoted 2 lines
Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt new file +2 -0
+		reg = <0x10440000 0x1000>;
+	};

[snip]

Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt

Quoted 2 lines
Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt new file +2 -0
+
+int __init combiner_init_irq_domain(unsigned int irq_base, unsigned int nr_irq,

Make irq_base signed.

Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt

Quoted 5 lines
Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt new file +5 -0
+					struct device_node *np)
+{
+	struct irq_domain *domain = &combiner_irq_domain;
+
+	domain->irq_base = irq_alloc_descs(irq_base, irq_base, nr_irq, 0);

This should be irq_alloc_descs(irq_base, 1,

So that dynamic allocation can work when irq_base is -1.

Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt

Quoted 3 lines
Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt new file +3 -0
+	if (domain->irq_base < 0) {
+		pr_err("failed to alloc irq descs, combiner init failed\n");
+		return -EBUSY;

On failure, just warn and do:

domain->irq_base = irq_base

instead of returning unless all platforms using this are completely converted over to support dynamic Linux virq mapping.

Also you should update your platforms' to set mdesc.nr_irq to NR_IRQS_LEGACY. And test with SPARSE_IRQ turned on.

Rob

Quoted 7 lines
Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt new file +7 -0
+	}
+	domain->nr_irq = nr_irq;
+	domain->ops = &combiner_irq_domain_ops;
+	domain->of_node = np;
+	irq_domain_add(domain);
+	return 0;
+}
#2 lore raw

PATCH RESEND 1/1 ARM: Exynos: Add irq domain and device tree support for interrupt combiner

Hi Rob,

Quoted 8 lines · Rob Herring

Review

Quoted 6 lines
(quoted diff) +6 -0
+Example:
+
+ ? ? combiner:interrupt-controller at 10440000 {
+ ? ? ? ? ? ? compatible = "samsung,exynos4120-combiner";
+ ? ? ? ? ? ? #interrupt-cells = <2>;
+ ? ? ? ? ? ? interrupt-controoler;

s/controoler/controller/

Ok. I will fix this.

Quoted 10 lines
Quoted 3 lines

+ ? ? ? ? ? ? reg = <0x10440000 0x1000>;
+ ? ? };

[snip]

Review

Quoted 2 lines
(quoted diff) +2 -0
+
+int __init combiner_init_irq_domain(unsigned int irq_base, unsigned int nr_irq,

Make irq_base signed.

Ok.

Quoted 10 lines

arch/arm/mach-exynos/cpu.c static void exynos4_gic_irq_fix_base(struct irq_data *d)

Quoted 6 lines

+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct device_node *np)

arch/arm/mach-exynos/cpu.c +4 -0
+{
+ ? ? struct irq_domain *domain = &combiner_irq_domain;
+
+ ? ? domain->irq_base = irq_alloc_descs(irq_base, irq_base, nr_irq, 0);

This should be irq_alloc_descs(irq_base, 1,

So that dynamic allocation can work when irq_base is -1.

Ok. I will modify this.

Quoted 11 lines
Quoted 4 lines

+ ? ? if (domain->irq_base < 0) {
+ ? ? ? ? ? ? pr_err("failed to alloc irq descs, combiner init failed\n");
+ ? ? ? ? ? ? return -EBUSY;

On failure, just warn and do:

domain->irq_base = irq_base

instead of returning unless all platforms using this are completely converted over to support dynamic Linux virq mapping.

Ok.

Quoted 3 lines

Also you should update your platforms' to set mdesc.nr_irq to NR_IRQS_LEGACY. And test with SPARSE_IRQ turned on.

Ok. I will test with NR_IRQS_LEGACY. Hope nothing breaks!

Thank you Rob for you review and comments on this patch.

Regards,
Thomas.

Quoted 2 lines

Rob