diff options
| author | Olof Johansson <olof@lixom.net> | 2012-03-10 09:11:31 -0800 | 
|---|---|---|
| committer | Olof Johansson <olof@lixom.net> | 2012-03-10 09:11:31 -0800 | 
| commit | cdc3df6f44f72c5924a16a47e1663c3fb0e57820 (patch) | |
| tree | 834f1c4423899e605dc3d226282910e67f1ce260 | |
| parent | a58f67e70a6cad021ceebd1c8919b898dd5d5de3 (diff) | |
| parent | 328ae2cb50af2f96b6061eb462aa92966a462bbc (diff) | |
| download | olio-linux-3.10-cdc3df6f44f72c5924a16a47e1663c3fb0e57820.tar.xz olio-linux-3.10-cdc3df6f44f72c5924a16a47e1663c3fb0e57820.zip  | |
Merge branch 'dt-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/dt
* 'dt-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
  arm/dts: mt_ventoux: very basic support for TeeJet Mt.Ventoux board
  ARM: OMAP2+: Remove extra ifdefs for board-generic
  ARM: OMAP2+: Fix build error when only ARCH_OMAP2/3 or 4 is selected
  ARM: OMAP2+: board-generic: Use of_irq_init API
  arm/dts: OMAP3: Add interrupt-controller bindings for INTC
  ARM: OMAP2/3: intc: Add DT support for TI interrupt controller
| -rw-r--r-- | Documentation/devicetree/bindings/arm/omap/intc.txt | 27 | ||||
| -rw-r--r-- | arch/arm/boot/dts/am3517_mt_ventoux.dts | 27 | ||||
| -rw-r--r-- | arch/arm/boot/dts/omap3.dtsi | 6 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/board-generic.c | 99 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/common.h | 12 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/irq.c | 60 | 
6 files changed, 168 insertions, 63 deletions
diff --git a/Documentation/devicetree/bindings/arm/omap/intc.txt b/Documentation/devicetree/bindings/arm/omap/intc.txt new file mode 100644 index 00000000000..f2583e6ec06 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/omap/intc.txt @@ -0,0 +1,27 @@ +* OMAP Interrupt Controller + +OMAP2/3 are using a TI interrupt controller that can support several +configurable number of interrupts. + +Main node required properties: + +- compatible : should be: +	"ti,omap2-intc" +- 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. + +  The cell contains the interrupt number in the range [0-128]. +- ti,intc-size: Number of interrupts handled by the interrupt controller. +- reg: physical base address and size of the intc registers map. + +Example: + +	intc: interrupt-controller@1 { +		compatible = "ti,omap2-intc"; +		interrupt-controller; +		#interrupt-cells = <1>; +		ti,intc-size = <96>; +		reg = <0x48200000 0x1000>; +	}; + diff --git a/arch/arm/boot/dts/am3517_mt_ventoux.dts b/arch/arm/boot/dts/am3517_mt_ventoux.dts new file mode 100644 index 00000000000..5eb26d7d9b4 --- /dev/null +++ b/arch/arm/boot/dts/am3517_mt_ventoux.dts @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2011 Ilya Yanok, EmCraft Systems + * + * 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/ "omap3.dtsi" + +/ { +	model = "TeeJet Mt.Ventoux"; +	compatible = "teejet,mt_ventoux", "ti,omap3"; + +	memory { +		device_type = "memory"; +		reg = <0x80000000 0x10000000>; /* 256 MB */ +	}; + +	/* AM35xx doesn't have IVA */ +	soc { +		iva { +			status = "disabled"; +		}; +	}; +}; diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index e6980643287..c6121357c1e 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -61,10 +61,12 @@  		ranges;  		ti,hwmods = "l3_main"; -		intc: interrupt-controller@1 { -			compatible = "ti,omap3-intc"; +		intc: interrupt-controller@48200000 { +			compatible = "ti,omap2-intc";  			interrupt-controller;  			#interrupt-cells = <1>; +			ti,intc-size = <96>; +			reg = <0x48200000 0x1000>;  		};  		uart1: serial@4806a000 { diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 02d7e828a14..74e1687b517 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -12,6 +12,7 @@   * published by the Free Software Foundation.   */  #include <linux/io.h> +#include <linux/of_irq.h>  #include <linux/of_platform.h>  #include <linux/irqdomain.h>  #include <linux/i2c/twl.h> @@ -24,33 +25,23 @@  #include "common.h"  #include "common-board-devices.h" -/* - * XXX: Still needed to boot until the i2c & twl driver is adapted to - * device-tree - */ -#ifdef CONFIG_ARCH_OMAP4 -static struct twl4030_platform_data sdp4430_twldata = { -	.irq_base	= TWL6030_IRQ_BASE, -	.irq_end	= TWL6030_IRQ_END, -}; - -static void __init omap4_i2c_init(void) -{ -	omap4_pmic_init("twl6030", &sdp4430_twldata); -} +#if !(defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)) +#define omap_intc_of_init	NULL +#endif +#ifndef CONFIG_ARCH_OMAP4 +#define gic_of_init		NULL  #endif -#ifdef CONFIG_ARCH_OMAP3 -static struct twl4030_platform_data beagle_twldata = { -	.irq_base	= TWL4030_IRQ_BASE, -	.irq_end	= TWL4030_IRQ_END, +static struct of_device_id irq_match[] __initdata = { +	{ .compatible = "ti,omap2-intc", .data = omap_intc_of_init, }, +	{ .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, +	{ }  }; -static void __init omap3_i2c_init(void) +static void __init omap_init_irq(void)  { -	omap3_pmic_init("twl4030", &beagle_twldata); +	of_irq_init(irq_match);  } -#endif  static struct of_device_id omap_dt_match_table[] __initdata = {  	{ .compatible = "simple-bus", }, @@ -58,39 +49,13 @@ static struct of_device_id omap_dt_match_table[] __initdata = {  	{ }  }; -static struct of_device_id intc_match[] __initdata = { -	{ .compatible = "ti,omap3-intc", }, -	{ .compatible = "arm,cortex-a9-gic", }, -	{ } -}; -  static void __init omap_generic_init(void)  { -	struct device_node *node = of_find_matching_node(NULL, intc_match); -	if (node) -		irq_domain_add_legacy(node, 32, 0, 0, &irq_domain_simple_ops, NULL); -  	omap_sdrc_init(NULL, NULL);  	of_platform_populate(NULL, omap_dt_match_table, NULL, NULL);  } -#ifdef CONFIG_ARCH_OMAP4 -static void __init omap4_init(void) -{ -	omap4_i2c_init(); -	omap_generic_init(); -} -#endif - -#ifdef CONFIG_ARCH_OMAP3 -static void __init omap3_init(void) -{ -	omap3_i2c_init(); -	omap_generic_init(); -} -#endif -  #ifdef CONFIG_SOC_OMAP2420  static const char *omap242x_boards_compat[] __initdata = {  	"ti,omap2420", @@ -101,7 +66,7 @@ DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)")  	.reserve	= omap_reserve,  	.map_io		= omap242x_map_io,  	.init_early	= omap2420_init_early, -	.init_irq	= omap2_init_irq, +	.init_irq	= omap_init_irq,  	.handle_irq	= omap2_intc_handle_irq,  	.init_machine	= omap_generic_init,  	.timer		= &omap2_timer, @@ -120,7 +85,7 @@ DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)")  	.reserve	= omap_reserve,  	.map_io		= omap243x_map_io,  	.init_early	= omap2430_init_early, -	.init_irq	= omap2_init_irq, +	.init_irq	= omap_init_irq,  	.handle_irq	= omap2_intc_handle_irq,  	.init_machine	= omap_generic_init,  	.timer		= &omap2_timer, @@ -130,6 +95,22 @@ MACHINE_END  #endif  #ifdef CONFIG_ARCH_OMAP3 +static struct twl4030_platform_data beagle_twldata = { +	.irq_base	= TWL4030_IRQ_BASE, +	.irq_end	= TWL4030_IRQ_END, +}; + +static void __init omap3_i2c_init(void) +{ +	omap3_pmic_init("twl4030", &beagle_twldata); +} + +static void __init omap3_init(void) +{ +	omap3_i2c_init(); +	omap_generic_init(); +} +  static const char *omap3_boards_compat[] __initdata = {  	"ti,omap3",  	NULL, @@ -139,7 +120,7 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")  	.reserve	= omap_reserve,  	.map_io		= omap3_map_io,  	.init_early	= omap3430_init_early, -	.init_irq	= omap3_init_irq, +	.init_irq	= omap_init_irq,  	.handle_irq	= omap3_intc_handle_irq,  	.init_machine	= omap3_init,  	.timer		= &omap3_timer, @@ -149,6 +130,22 @@ MACHINE_END  #endif  #ifdef CONFIG_ARCH_OMAP4 +static struct twl4030_platform_data sdp4430_twldata = { +	.irq_base	= TWL6030_IRQ_BASE, +	.irq_end	= TWL6030_IRQ_END, +}; + +static void __init omap4_i2c_init(void) +{ +	omap4_pmic_init("twl6030", &sdp4430_twldata); +} + +static void __init omap4_init(void) +{ +	omap4_i2c_init(); +	omap_generic_init(); +} +  static const char *omap4_boards_compat[] __initdata = {  	"ti,omap4",  	NULL, @@ -158,7 +155,7 @@ DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)")  	.reserve	= omap_reserve,  	.map_io		= omap4_map_io,  	.init_early	= omap4430_init_early, -	.init_irq	= gic_init_irq, +	.init_irq	= omap_init_irq,  	.handle_irq	= gic_handle_irq,  	.init_machine	= omap4_init,  	.timer		= &omap4_timer, diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 7e9338e8d68..99604d36430 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -175,6 +175,18 @@ void omap3_intc_handle_irq(struct pt_regs *regs);  extern void __iomem *omap4_get_l2cache_base(void);  #endif +struct device_node; +#ifdef CONFIG_OF +int __init omap_intc_of_init(struct device_node *node, +			     struct device_node *parent); +#else +int __init omap_intc_of_init(struct device_node *node, +			     struct device_node *parent) +{ +	return 0; +} +#endif +  #ifdef CONFIG_SMP  extern void __iomem *omap4_get_scu_base(void);  #else diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index 1fef061f792..26eaf37ce4d 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -11,12 +11,16 @@   * for more details.   */  #include <linux/kernel.h> +#include <linux/module.h>  #include <linux/init.h>  #include <linux/interrupt.h>  #include <linux/io.h>  #include <mach/hardware.h>  #include <asm/exception.h>  #include <asm/mach/irq.h> +#include <linux/irqdomain.h> +#include <linux/of.h> +#include <linux/of_address.h>  /* selected INTC register offsets */ @@ -57,6 +61,8 @@ static struct omap_irq_bank {  	},  }; +static struct irq_domain *domain; +  /* Structure to save interrupt controller context */  struct omap3_intc_regs {  	u32 sysconfig; @@ -147,17 +153,27 @@ omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)  				IRQ_NOREQUEST | IRQ_NOPROBE, 0);  } -static void __init omap_init_irq(u32 base, int nr_irqs) +static void __init omap_init_irq(u32 base, int nr_irqs, +				 struct device_node *node)  {  	void __iomem *omap_irq_base;  	unsigned long nr_of_irqs = 0;  	unsigned int nr_banks = 0; -	int i, j; +	int i, j, irq_base;  	omap_irq_base = ioremap(base, SZ_4K);  	if (WARN_ON(!omap_irq_base))  		return; +	irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0); +	if (irq_base < 0) { +		pr_warn("Couldn't allocate IRQ numbers\n"); +		irq_base = 0; +	} + +	domain = irq_domain_add_legacy(node, nr_irqs, irq_base, 0, +				       &irq_domain_simple_ops, NULL); +  	for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {  		struct omap_irq_bank *bank = irq_banks + i; @@ -166,36 +182,36 @@ static void __init omap_init_irq(u32 base, int nr_irqs)  		/* Static mapping, never released */  		bank->base_reg = ioremap(base, SZ_4K);  		if (!bank->base_reg) { -			printk(KERN_ERR "Could not ioremap irq bank%i\n", i); +			pr_err("Could not ioremap irq bank%i\n", i);  			continue;  		}  		omap_irq_bank_init_one(bank);  		for (j = 0; j < bank->nr_irqs; j += 32) -			omap_alloc_gc(bank->base_reg + j, j, 32); +			omap_alloc_gc(bank->base_reg + j, j + irq_base, 32);  		nr_of_irqs += bank->nr_irqs;  		nr_banks++;  	} -	printk(KERN_INFO "Total of %ld interrupts on %d active controller%s\n", -	       nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : ""); +	pr_info("Total of %ld interrupts on %d active controller%s\n", +		nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : "");  }  void __init omap2_init_irq(void)  { -	omap_init_irq(OMAP24XX_IC_BASE, 96); +	omap_init_irq(OMAP24XX_IC_BASE, 96, NULL);  }  void __init omap3_init_irq(void)  { -	omap_init_irq(OMAP34XX_IC_BASE, 96); +	omap_init_irq(OMAP34XX_IC_BASE, 96, NULL);  }  void __init ti81xx_init_irq(void)  { -	omap_init_irq(OMAP34XX_IC_BASE, 128); +	omap_init_irq(OMAP34XX_IC_BASE, 128, NULL);  }  static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs *regs) @@ -225,8 +241,10 @@ out:  		irqnr = readl_relaxed(base_addr + INTCPS_SIR_IRQ_OFFSET);  		irqnr &= ACTIVEIRQ_MASK; -		if (irqnr) +		if (irqnr) { +			irqnr = irq_find_mapping(domain, irqnr);  			handle_IRQ(irqnr, regs); +		}  	} while (irqnr);  } @@ -236,6 +254,28 @@ asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs *regs  	omap_intc_handle_irq(base_addr, regs);  } +int __init omap_intc_of_init(struct device_node *node, +			     struct device_node *parent) +{ +	struct resource res; +	u32 nr_irqs = 96; + +	if (WARN_ON(!node)) +		return -ENODEV; + +	if (of_address_to_resource(node, 0, &res)) { +		WARN(1, "unable to get intc registers\n"); +		return -EINVAL; +	} + +	if (of_property_read_u32(node, "ti,intc-size", &nr_irqs)) +		pr_warn("unable to get intc-size, default to %d\n", nr_irqs); + +	omap_init_irq(res.start, nr_irqs, of_node_get(node)); + +	return 0; +} +  #ifdef CONFIG_ARCH_OMAP3  static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)];  |