diff mbox

[v2,2/7] ARM: imx5: adopt generic_chip irq_domain support for tzic

Message ID 1329331668-30325-3-git-send-email-shawn.guo@linaro.org
State New
Headers show

Commit Message

Shawn Guo Feb. 15, 2012, 6:47 p.m. UTC
It separates the DT initialization for tzic and gpt from non-DT code
path, so that base address and irq can retrieved from device tree
rather than static definition.

With the DT initialization flow corrected as above, the generic_chip
irq_domain support is adopted for tzic interrupt controller, so that
the irq_domain initialization for tzic in imx5 DT platform code can be
removed.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/boot/dts/imx51.dtsi            |    6 ++++
 arch/arm/boot/dts/imx53.dtsi            |    6 ++++
 arch/arm/mach-mx5/clock-mx51-mx53.c     |   47 ++++++++++++++++++++++++++++--
 arch/arm/mach-mx5/imx51-dt.c            |   22 ++++++++++----
 arch/arm/mach-mx5/imx53-dt.c            |   22 ++++++++++----
 arch/arm/mach-mx5/mm.c                  |    6 ++--
 arch/arm/plat-mxc/include/mach/common.h |    3 +-
 arch/arm/plat-mxc/tzic.c                |   32 ++++++++++-----------
 8 files changed, 105 insertions(+), 39 deletions(-)

Comments

Rob Herring Feb. 16, 2012, 3:43 a.m. UTC | #1
On 02/15/2012 12:47 PM, Shawn Guo wrote:
> It separates the DT initialization for tzic and gpt from non-DT code
> path, so that base address and irq can retrieved from device tree
> rather than static definition.
> 
> With the DT initialization flow corrected as above, the generic_chip
> irq_domain support is adopted for tzic interrupt controller, so that
> the irq_domain initialization for tzic in imx5 DT platform code can be
> removed.
> 
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>

One comment below, otherwise:

Acked-by: Rob Herring <rob.herring@calxeda.com>

> ---
>  arch/arm/boot/dts/imx51.dtsi            |    6 ++++
>  arch/arm/boot/dts/imx53.dtsi            |    6 ++++
>  arch/arm/mach-mx5/clock-mx51-mx53.c     |   47 ++++++++++++++++++++++++++++--
>  arch/arm/mach-mx5/imx51-dt.c            |   22 ++++++++++----
>  arch/arm/mach-mx5/imx53-dt.c            |   22 ++++++++++----
>  arch/arm/mach-mx5/mm.c                  |    6 ++--
>  arch/arm/plat-mxc/include/mach/common.h |    3 +-
>  arch/arm/plat-mxc/tzic.c                |   32 ++++++++++-----------
>  8 files changed, 105 insertions(+), 39 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
> index 6663986..a5fda43 100644
> --- a/arch/arm/boot/dts/imx51.dtsi
> +++ b/arch/arm/boot/dts/imx51.dtsi
> @@ -171,6 +171,12 @@
>  				status = "disabled";
>  			};
>  
> +			gpt@73fa0000 {
> +				compatible = "fsl,imx51-gpt", "fsl,gpt";
> +				reg = <0x73fa0000 0x4000>;
> +				interrupts = <39>;
> +			};
> +
>  			uart1: uart@73fbc000 {
>  				compatible = "fsl,imx51-uart", "fsl,imx21-uart";
>  				reg = <0x73fbc000 0x4000>;
> diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
> index 5dd91b9..05e6412 100644
> --- a/arch/arm/boot/dts/imx53.dtsi
> +++ b/arch/arm/boot/dts/imx53.dtsi
> @@ -173,6 +173,12 @@
>  				status = "disabled";
>  			};
>  
> +			gpt@53fa0000 {
> +				compatible = "fsl,imx53-gpt", "fsl,gpt";
> +				reg = <0x53fa0000 0x4000>;
> +				interrupts = <39>;
> +			};
> +
>  			uart1: uart@53fbc000 {
>  				compatible = "fsl,imx53-uart", "fsl,imx21-uart";
>  				reg = <0x53fbc000 0x4000>;
> diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
> index 4cb2769..200a3d7 100644
> --- a/arch/arm/mach-mx5/clock-mx51-mx53.c
> +++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
> @@ -16,6 +16,8 @@
>  #include <linux/io.h>
>  #include <linux/clkdev.h>
>  #include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
>  
>  #include <asm/div64.h>
>  
> @@ -1555,10 +1557,16 @@ static void clk_tree_init(void)
>  	__raw_writel(reg, MXC_CCM_CBCDR);
>  }
>  
> +static inline void __iomem *get_gpt_base_dt(struct device_node *np);
> +static inline int get_gpt_irq_dt(struct device_node *np);
> +
>  int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
>  			unsigned long ckih1, unsigned long ckih2)
>  {
>  	int i;
> +	int gpt_irq = MX51_INT_GPT;
> +	void __iomem *gpt_base = MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR);
> +	struct device_node *np = of_find_compatible_node(NULL, NULL, "fsl,gpt");
>  
>  	external_low_reference = ckil;
>  	external_high_reference = ckih1;
> @@ -1592,8 +1600,12 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
>  	clk_set_rate(&esdhc2_clk, 166250000);
>  
>  	/* System timer */
> -	mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
> -		MX51_INT_GPT);
> +	if (np) {
> +		gpt_base = get_gpt_base_dt(np);
> +		gpt_irq = get_gpt_irq_dt(np);
> +	}
> +	WARN_ON(!gpt_base);
> +	mxc_timer_init(&gpt_clk, gpt_base, gpt_irq);
>  	return 0;
>  }
>  
> @@ -1601,6 +1613,9 @@ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc,
>  			unsigned long ckih1, unsigned long ckih2)
>  {
>  	int i;
> +	int gpt_irq = MX53_INT_GPT;
> +	void __iomem *gpt_base = MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR);
> +	struct device_node *np = of_find_compatible_node(NULL, NULL, "fsl,gpt");
>  
>  	external_low_reference = ckil;
>  	external_high_reference = ckih1;
> @@ -1629,8 +1644,12 @@ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc,
>  	clk_set_rate(&esdhc3_mx53_clk, 200000000);
>  
>  	/* System timer */
> -	mxc_timer_init(&gpt_clk, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR),
> -		MX53_INT_GPT);
> +	if (np) {
> +		gpt_base = get_gpt_base_dt(np);
> +		gpt_irq = get_gpt_irq_dt(np);
> +	}
> +	WARN_ON(!gpt_base);
> +	mxc_timer_init(&gpt_clk, gpt_base, gpt_irq);
>  	return 0;
>  }
>  
> @@ -1672,4 +1691,24 @@ int __init mx53_clocks_init_dt(void)
>  	clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
>  	return mx53_clocks_init(ckil, osc, ckih1, ckih2);
>  }
> +
> +static inline void __iomem *get_gpt_base_dt(struct device_node *np)
> +{
> +	return of_iomap(np, 0);
> +}
> +
> +static inline int get_gpt_irq_dt(struct device_node *np)
> +{
> +	return irq_of_parse_and_map(np, 0);
> +}
> +#else
> +static inline void __iomem *get_gpt_base_dt(struct device_node *np)
> +{
> +	return NULL;
> +}
> +
> +static inline int get_gpt_irq_dt(struct device_node *np)
> +{
> +	return -ENODEV;
> +}

Reorder so you don't need forward declarations.

Once again, I think this is too intermixed with DT and non-DT, but you
are getting the data from DT so I guess it's fine for now.

>  #endif
> diff --git a/arch/arm/mach-mx5/imx51-dt.c b/arch/arm/mach-mx5/imx51-dt.c
> index 1e03ef4..636ef34 100644
> --- a/arch/arm/mach-mx5/imx51-dt.c
> +++ b/arch/arm/mach-mx5/imx51-dt.c
> @@ -12,6 +12,7 @@
>  
>  #include <linux/irq.h>
>  #include <linux/irqdomain.h>
> +#include <linux/of_address.h>
>  #include <linux/of_irq.h>
>  #include <linux/of_platform.h>
>  #include <asm/mach/arch.h>
> @@ -44,10 +45,14 @@ static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = {
>  	{ /* sentinel */ }
>  };
>  
> -static int __init imx51_tzic_add_irq_domain(struct device_node *np,
> -				struct device_node *interrupt_parent)
> +static int __init imx51_tzic_init_cb(struct device_node *np,
> +				     struct device_node *interrupt_parent)
>  {
> -	irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL);
> +	void __iomem *base = of_iomap(np, 0);
> +
> +	WARN_ON(!base);
> +	tzic_init_irq(base, np);
> +
>  	return 0;
>  }
>  
> @@ -63,7 +68,7 @@ static int __init imx51_gpio_add_irq_domain(struct device_node *np,
>  }
>  
>  static const struct of_device_id imx51_irq_match[] __initconst = {
> -	{ .compatible = "fsl,imx51-tzic", .data = imx51_tzic_add_irq_domain, },
> +	{ .compatible = "fsl,imx51-tzic", .data = imx51_tzic_init_cb, },
>  	{ .compatible = "fsl,imx51-gpio", .data = imx51_gpio_add_irq_domain, },
>  	{ /* sentinel */ }
>  };
> @@ -73,14 +78,17 @@ static const struct of_device_id imx51_iomuxc_of_match[] __initconst = {
>  	{ /* sentinel */ }
>  };
>  
> +static void __init imx51_dt_irq_init(void)
> +{
> +	of_irq_init(imx51_irq_match);
> +}
> +
>  static void __init imx51_dt_init(void)
>  {
>  	struct device_node *node;
>  	const struct of_device_id *of_id;
>  	void (*func)(void);
>  
> -	of_irq_init(imx51_irq_match);
> -
>  	node = of_find_matching_node(NULL, imx51_iomuxc_of_match);
>  	if (node) {
>  		of_id = of_match_node(imx51_iomuxc_of_match, node);
> @@ -110,7 +118,7 @@ static const char *imx51_dt_board_compat[] __initdata = {
>  DT_MACHINE_START(IMX51_DT, "Freescale i.MX51 (Device Tree Support)")
>  	.map_io		= mx51_map_io,
>  	.init_early	= imx51_init_early,
> -	.init_irq	= mx51_init_irq,
> +	.init_irq	= imx51_dt_irq_init,
>  	.handle_irq	= imx51_handle_irq,
>  	.timer		= &imx51_timer,
>  	.init_machine	= imx51_dt_init,
> diff --git a/arch/arm/mach-mx5/imx53-dt.c b/arch/arm/mach-mx5/imx53-dt.c
> index fd5be0f..ce2b700 100644
> --- a/arch/arm/mach-mx5/imx53-dt.c
> +++ b/arch/arm/mach-mx5/imx53-dt.c
> @@ -13,6 +13,7 @@
>  #include <linux/io.h>
>  #include <linux/irq.h>
>  #include <linux/irqdomain.h>
> +#include <linux/of_address.h>
>  #include <linux/of_irq.h>
>  #include <linux/of_platform.h>
>  #include <asm/mach/arch.h>
> @@ -48,10 +49,14 @@ static const struct of_dev_auxdata imx53_auxdata_lookup[] __initconst = {
>  	{ /* sentinel */ }
>  };
>  
> -static int __init imx53_tzic_add_irq_domain(struct device_node *np,
> -				struct device_node *interrupt_parent)
> +static int __init imx53_tzic_init_cb(struct device_node *np,
> +				     struct device_node *interrupt_parent)
>  {
> -	irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL);
> +	void __iomem *base = of_iomap(np, 0);
> +
> +	WARN_ON(!base);
> +	tzic_init_irq(base, np);
> +
>  	return 0;
>  }
>  
> @@ -67,7 +72,7 @@ static int __init imx53_gpio_add_irq_domain(struct device_node *np,
>  }
>  
>  static const struct of_device_id imx53_irq_match[] __initconst = {
> -	{ .compatible = "fsl,imx53-tzic", .data = imx53_tzic_add_irq_domain, },
> +	{ .compatible = "fsl,imx53-tzic", .data = imx53_tzic_init_cb, },
>  	{ .compatible = "fsl,imx53-gpio", .data = imx53_gpio_add_irq_domain, },
>  	{ /* sentinel */ }
>  };
> @@ -80,14 +85,17 @@ static const struct of_device_id imx53_iomuxc_of_match[] __initconst = {
>  	{ /* sentinel */ }
>  };
>  
> +static void __init imx53_dt_irq_init(void)
> +{
> +	of_irq_init(imx53_irq_match);
> +}
> +
>  static void __init imx53_dt_init(void)
>  {
>  	struct device_node *node;
>  	const struct of_device_id *of_id;
>  	void (*func)(void);
>  
> -	of_irq_init(imx53_irq_match);
> -
>  	node = of_find_matching_node(NULL, imx53_iomuxc_of_match);
>  	if (node) {
>  		of_id = of_match_node(imx53_iomuxc_of_match, node);
> @@ -120,7 +128,7 @@ static const char *imx53_dt_board_compat[] __initdata = {
>  DT_MACHINE_START(IMX53_DT, "Freescale i.MX53 (Device Tree Support)")
>  	.map_io		= mx53_map_io,
>  	.init_early	= imx53_init_early,
> -	.init_irq	= mx53_init_irq,
> +	.init_irq	= imx53_dt_irq_init,
>  	.handle_irq	= imx53_handle_irq,
>  	.timer		= &imx53_timer,
>  	.init_machine	= imx53_dt_init,
> diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c
> index bc17dfe..bed8562 100644
> --- a/arch/arm/mach-mx5/mm.c
> +++ b/arch/arm/mach-mx5/mm.c
> @@ -120,17 +120,17 @@ void __init imx53_init_early(void)
>  
>  void __init mx50_init_irq(void)
>  {
> -	tzic_init_irq(MX50_IO_ADDRESS(MX50_TZIC_BASE_ADDR));
> +	tzic_init_irq(MX50_IO_ADDRESS(MX50_TZIC_BASE_ADDR), NULL);
>  }
>  
>  void __init mx51_init_irq(void)
>  {
> -	tzic_init_irq(MX51_IO_ADDRESS(MX51_TZIC_BASE_ADDR));
> +	tzic_init_irq(MX51_IO_ADDRESS(MX51_TZIC_BASE_ADDR), NULL);
>  }
>  
>  void __init mx53_init_irq(void)
>  {
> -	tzic_init_irq(MX53_IO_ADDRESS(MX53_TZIC_BASE_ADDR));
> +	tzic_init_irq(MX53_IO_ADDRESS(MX53_TZIC_BASE_ADDR), NULL);
>  }
>  
>  static struct sdma_script_start_addrs imx51_sdma_script __initdata = {
> diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
> index 1bf0df8..4291992 100644
> --- a/arch/arm/plat-mxc/include/mach/common.h
> +++ b/arch/arm/plat-mxc/include/mach/common.h
> @@ -11,6 +11,7 @@
>  #ifndef __ASM_ARCH_MXC_COMMON_H__
>  #define __ASM_ARCH_MXC_COMMON_H__
>  
> +struct device_node;
>  struct platform_device;
>  struct clk;
>  enum mxc_cpu_pwr_mode;
> @@ -34,7 +35,7 @@ extern void imx50_init_early(void);
>  extern void imx51_init_early(void);
>  extern void imx53_init_early(void);
>  extern void mxc_init_irq(void __iomem *);
> -extern void tzic_init_irq(void __iomem *);
> +extern void tzic_init_irq(void __iomem *, struct device_node *np);
>  extern void mx1_init_irq(void);
>  extern void mx21_init_irq(void);
>  extern void mx25_init_irq(void);
> diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
> index 98308ec..8288187 100644
> --- a/arch/arm/plat-mxc/tzic.c
> +++ b/arch/arm/plat-mxc/tzic.c
> @@ -15,6 +15,7 @@
>  #include <linux/device.h>
>  #include <linux/errno.h>
>  #include <linux/io.h>
> +#include <linux/irqdomain.h>
>  
>  #include <asm/mach/irq.h>
>  #include <asm/exception.h>
> @@ -49,6 +50,7 @@
>  #define TZIC_ID0	0x0FD0	/* Indentification Register 0 */
>  
>  void __iomem *tzic_base; /* Used as irq controller base in entry-macro.S */
> +static struct irq_chip_generic *tzic_gc;
>  
>  #define TZIC_NUM_IRQS 128
>  
> @@ -77,15 +79,14 @@ static int tzic_set_irq_fiq(unsigned int irq, unsigned int type)
>  static void tzic_irq_suspend(struct irq_data *d)
>  {
>  	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
> -	int idx = gc->irq_base >> 5;
> +	int idx = d->hwirq / 32;
>  
>  	__raw_writel(gc->wake_active, tzic_base + TZIC_WAKEUP0(idx));
>  }
>  
>  static void tzic_irq_resume(struct irq_data *d)
>  {
> -	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
> -	int idx = gc->irq_base >> 5;
> +	int idx = d->hwirq / 32;
>  
>  	__raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(idx)),
>  		     tzic_base + TZIC_WAKEUP0(idx));
> @@ -102,18 +103,14 @@ static struct mxc_extra_irq tzic_extra_irq = {
>  #endif
>  };
>  
> -static __init void tzic_init_gc(unsigned int irq_start)
> +static __init void tzic_init_gc(struct irq_chip_generic *gc)
>  {
> -	struct irq_chip_generic *gc;
> -	struct irq_chip_type *ct;
> -	int idx = irq_start >> 5;
> +	struct irq_chip_type *ct = gc->chip_types;
> +	int idx = gc->hwirq_base / 32;
>  
> -	gc = irq_alloc_generic_chip("tzic", 1, irq_start, tzic_base,
> -				    handle_level_irq);
> -	gc->private = &tzic_extra_irq;
> +	tzic_gc = gc;
>  	gc->wake_enabled = IRQ_MSK(32);
>  
> -	ct = gc->chip_types;
>  	ct->chip.irq_mask = irq_gc_mask_disable_reg;
>  	ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
>  	ct->chip.irq_set_wake = irq_gc_set_wake;
> @@ -121,8 +118,6 @@ static __init void tzic_init_gc(unsigned int irq_start)
>  	ct->chip.irq_resume = tzic_irq_resume;
>  	ct->regs.disable = TZIC_ENCLEAR0(idx);
>  	ct->regs.enable = TZIC_ENSET0(idx);
> -
> -	irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0);
>  }
>  
>  asmlinkage void __exception_irq_entry tzic_handle_irq(struct pt_regs *regs)
> @@ -140,7 +135,8 @@ asmlinkage void __exception_irq_entry tzic_handle_irq(struct pt_regs *regs)
>  			while (stat) {
>  				handled = 1;
>  				irqofs = fls(stat) - 1;
> -				handle_IRQ(irqofs + i * 32, regs);
> +				handle_IRQ(irq_find_mapping(tzic_gc->domain,
> +						irqofs + i * 32), regs);
>  				stat &= ~(1 << irqofs);
>  			}
>  		}
> @@ -152,7 +148,7 @@ asmlinkage void __exception_irq_entry tzic_handle_irq(struct pt_regs *regs)
>   * interrupts. It registers the interrupt enable and disable functions
>   * to the kernel for each interrupt source.
>   */
> -void __init tzic_init_irq(void __iomem *irqbase)
> +void __init tzic_init_irq(void __iomem *irqbase, struct device_node *np)
>  {
>  	int i;
>  
> @@ -175,8 +171,10 @@ void __init tzic_init_irq(void __iomem *irqbase)
>  
>  	/* all IRQ no FIQ Warning :: No selection */
>  
> -	for (i = 0; i < TZIC_NUM_IRQS; i += 32)
> -		tzic_init_gc(i);
> +	irq_setup_generic_chip_domain("tzic", np, 1, 0, tzic_base,
> +				      handle_level_irq, TZIC_NUM_IRQS, 0,
> +				      IRQ_NOREQUEST, 0,
> +				      tzic_init_gc, &tzic_extra_irq);
>  
>  #ifdef CONFIG_FIQ
>  	/* Initialize FIQ */
Shawn Guo Feb. 16, 2012, 4:59 a.m. UTC | #2
On Wed, Feb 15, 2012 at 09:43:01PM -0600, Rob Herring wrote:
...
> > +static inline void __iomem *get_gpt_base_dt(struct device_node *np);
> > +static inline int get_gpt_irq_dt(struct device_node *np);
> > +
> >  int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
> >  			unsigned long ckih1, unsigned long ckih2)
> >  {
> >  	int i;
> > +	int gpt_irq = MX51_INT_GPT;
> > +	void __iomem *gpt_base = MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR);
> > +	struct device_node *np = of_find_compatible_node(NULL, NULL, "fsl,gpt");
> >  
> >  	external_low_reference = ckil;
> >  	external_high_reference = ckih1;
> > @@ -1592,8 +1600,12 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
> >  	clk_set_rate(&esdhc2_clk, 166250000);
> >  
> >  	/* System timer */
> > -	mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
> > -		MX51_INT_GPT);
> > +	if (np) {
> > +		gpt_base = get_gpt_base_dt(np);
> > +		gpt_irq = get_gpt_irq_dt(np);
> > +	}
> > +	WARN_ON(!gpt_base);
> > +	mxc_timer_init(&gpt_clk, gpt_base, gpt_irq);
> >  	return 0;
> >  }
> >  
> > @@ -1601,6 +1613,9 @@ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc,
> >  			unsigned long ckih1, unsigned long ckih2)
> >  {
> >  	int i;
> > +	int gpt_irq = MX53_INT_GPT;
> > +	void __iomem *gpt_base = MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR);
> > +	struct device_node *np = of_find_compatible_node(NULL, NULL, "fsl,gpt");
> >  
> >  	external_low_reference = ckil;
> >  	external_high_reference = ckih1;
> > @@ -1629,8 +1644,12 @@ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc,
> >  	clk_set_rate(&esdhc3_mx53_clk, 200000000);
> >  
> >  	/* System timer */
> > -	mxc_timer_init(&gpt_clk, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR),
> > -		MX53_INT_GPT);
> > +	if (np) {
> > +		gpt_base = get_gpt_base_dt(np);
> > +		gpt_irq = get_gpt_irq_dt(np);
> > +	}
> > +	WARN_ON(!gpt_base);
> > +	mxc_timer_init(&gpt_clk, gpt_base, gpt_irq);
> >  	return 0;
> >  }
> >  
> > @@ -1672,4 +1691,24 @@ int __init mx53_clocks_init_dt(void)
> >  	clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
> >  	return mx53_clocks_init(ckil, osc, ckih1, ckih2);
> >  }
> > +
> > +static inline void __iomem *get_gpt_base_dt(struct device_node *np)
> > +{
> > +	return of_iomap(np, 0);
> > +}
> > +
> > +static inline int get_gpt_irq_dt(struct device_node *np)
> > +{
> > +	return irq_of_parse_and_map(np, 0);
> > +}
> > +#else
> > +static inline void __iomem *get_gpt_base_dt(struct device_node *np)
> > +{
> > +	return NULL;
> > +}
> > +
> > +static inline int get_gpt_irq_dt(struct device_node *np)
> > +{
> > +	return -ENODEV;
> > +}
> 
> Reorder so you don't need forward declarations.
> 
I'm trying to save one more occurrence of "#ifdef CONFIG_OF", or I
to move around the whole block wrapped by #ifdef, which will make
unnecessary diffstat churn.

I hope we can stop this nasty #ifdef at some point by select CONFIG_OF
for the imx architecture.

> Once again, I think this is too intermixed with DT and non-DT, but you
> are getting the data from DT so I guess it's fine for now.
> 
I guess that's the situation we have to live with until the non-DT
support gets completely removed.
diff mbox

Patch

diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
index 6663986..a5fda43 100644
--- a/arch/arm/boot/dts/imx51.dtsi
+++ b/arch/arm/boot/dts/imx51.dtsi
@@ -171,6 +171,12 @@ 
 				status = "disabled";
 			};
 
+			gpt@73fa0000 {
+				compatible = "fsl,imx51-gpt", "fsl,gpt";
+				reg = <0x73fa0000 0x4000>;
+				interrupts = <39>;
+			};
+
 			uart1: uart@73fbc000 {
 				compatible = "fsl,imx51-uart", "fsl,imx21-uart";
 				reg = <0x73fbc000 0x4000>;
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index 5dd91b9..05e6412 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -173,6 +173,12 @@ 
 				status = "disabled";
 			};
 
+			gpt@53fa0000 {
+				compatible = "fsl,imx53-gpt", "fsl,gpt";
+				reg = <0x53fa0000 0x4000>;
+				interrupts = <39>;
+			};
+
 			uart1: uart@53fbc000 {
 				compatible = "fsl,imx53-uart", "fsl,imx21-uart";
 				reg = <0x53fbc000 0x4000>;
diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
index 4cb2769..200a3d7 100644
--- a/arch/arm/mach-mx5/clock-mx51-mx53.c
+++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
@@ -16,6 +16,8 @@ 
 #include <linux/io.h>
 #include <linux/clkdev.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 
 #include <asm/div64.h>
 
@@ -1555,10 +1557,16 @@  static void clk_tree_init(void)
 	__raw_writel(reg, MXC_CCM_CBCDR);
 }
 
+static inline void __iomem *get_gpt_base_dt(struct device_node *np);
+static inline int get_gpt_irq_dt(struct device_node *np);
+
 int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
 			unsigned long ckih1, unsigned long ckih2)
 {
 	int i;
+	int gpt_irq = MX51_INT_GPT;
+	void __iomem *gpt_base = MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR);
+	struct device_node *np = of_find_compatible_node(NULL, NULL, "fsl,gpt");
 
 	external_low_reference = ckil;
 	external_high_reference = ckih1;
@@ -1592,8 +1600,12 @@  int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
 	clk_set_rate(&esdhc2_clk, 166250000);
 
 	/* System timer */
-	mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
-		MX51_INT_GPT);
+	if (np) {
+		gpt_base = get_gpt_base_dt(np);
+		gpt_irq = get_gpt_irq_dt(np);
+	}
+	WARN_ON(!gpt_base);
+	mxc_timer_init(&gpt_clk, gpt_base, gpt_irq);
 	return 0;
 }
 
@@ -1601,6 +1613,9 @@  int __init mx53_clocks_init(unsigned long ckil, unsigned long osc,
 			unsigned long ckih1, unsigned long ckih2)
 {
 	int i;
+	int gpt_irq = MX53_INT_GPT;
+	void __iomem *gpt_base = MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR);
+	struct device_node *np = of_find_compatible_node(NULL, NULL, "fsl,gpt");
 
 	external_low_reference = ckil;
 	external_high_reference = ckih1;
@@ -1629,8 +1644,12 @@  int __init mx53_clocks_init(unsigned long ckil, unsigned long osc,
 	clk_set_rate(&esdhc3_mx53_clk, 200000000);
 
 	/* System timer */
-	mxc_timer_init(&gpt_clk, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR),
-		MX53_INT_GPT);
+	if (np) {
+		gpt_base = get_gpt_base_dt(np);
+		gpt_irq = get_gpt_irq_dt(np);
+	}
+	WARN_ON(!gpt_base);
+	mxc_timer_init(&gpt_clk, gpt_base, gpt_irq);
 	return 0;
 }
 
@@ -1672,4 +1691,24 @@  int __init mx53_clocks_init_dt(void)
 	clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
 	return mx53_clocks_init(ckil, osc, ckih1, ckih2);
 }
+
+static inline void __iomem *get_gpt_base_dt(struct device_node *np)
+{
+	return of_iomap(np, 0);
+}
+
+static inline int get_gpt_irq_dt(struct device_node *np)
+{
+	return irq_of_parse_and_map(np, 0);
+}
+#else
+static inline void __iomem *get_gpt_base_dt(struct device_node *np)
+{
+	return NULL;
+}
+
+static inline int get_gpt_irq_dt(struct device_node *np)
+{
+	return -ENODEV;
+}
 #endif
diff --git a/arch/arm/mach-mx5/imx51-dt.c b/arch/arm/mach-mx5/imx51-dt.c
index 1e03ef4..636ef34 100644
--- a/arch/arm/mach-mx5/imx51-dt.c
+++ b/arch/arm/mach-mx5/imx51-dt.c
@@ -12,6 +12,7 @@ 
 
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
+#include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
@@ -44,10 +45,14 @@  static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = {
 	{ /* sentinel */ }
 };
 
-static int __init imx51_tzic_add_irq_domain(struct device_node *np,
-				struct device_node *interrupt_parent)
+static int __init imx51_tzic_init_cb(struct device_node *np,
+				     struct device_node *interrupt_parent)
 {
-	irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL);
+	void __iomem *base = of_iomap(np, 0);
+
+	WARN_ON(!base);
+	tzic_init_irq(base, np);
+
 	return 0;
 }
 
@@ -63,7 +68,7 @@  static int __init imx51_gpio_add_irq_domain(struct device_node *np,
 }
 
 static const struct of_device_id imx51_irq_match[] __initconst = {
-	{ .compatible = "fsl,imx51-tzic", .data = imx51_tzic_add_irq_domain, },
+	{ .compatible = "fsl,imx51-tzic", .data = imx51_tzic_init_cb, },
 	{ .compatible = "fsl,imx51-gpio", .data = imx51_gpio_add_irq_domain, },
 	{ /* sentinel */ }
 };
@@ -73,14 +78,17 @@  static const struct of_device_id imx51_iomuxc_of_match[] __initconst = {
 	{ /* sentinel */ }
 };
 
+static void __init imx51_dt_irq_init(void)
+{
+	of_irq_init(imx51_irq_match);
+}
+
 static void __init imx51_dt_init(void)
 {
 	struct device_node *node;
 	const struct of_device_id *of_id;
 	void (*func)(void);
 
-	of_irq_init(imx51_irq_match);
-
 	node = of_find_matching_node(NULL, imx51_iomuxc_of_match);
 	if (node) {
 		of_id = of_match_node(imx51_iomuxc_of_match, node);
@@ -110,7 +118,7 @@  static const char *imx51_dt_board_compat[] __initdata = {
 DT_MACHINE_START(IMX51_DT, "Freescale i.MX51 (Device Tree Support)")
 	.map_io		= mx51_map_io,
 	.init_early	= imx51_init_early,
-	.init_irq	= mx51_init_irq,
+	.init_irq	= imx51_dt_irq_init,
 	.handle_irq	= imx51_handle_irq,
 	.timer		= &imx51_timer,
 	.init_machine	= imx51_dt_init,
diff --git a/arch/arm/mach-mx5/imx53-dt.c b/arch/arm/mach-mx5/imx53-dt.c
index fd5be0f..ce2b700 100644
--- a/arch/arm/mach-mx5/imx53-dt.c
+++ b/arch/arm/mach-mx5/imx53-dt.c
@@ -13,6 +13,7 @@ 
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
+#include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
@@ -48,10 +49,14 @@  static const struct of_dev_auxdata imx53_auxdata_lookup[] __initconst = {
 	{ /* sentinel */ }
 };
 
-static int __init imx53_tzic_add_irq_domain(struct device_node *np,
-				struct device_node *interrupt_parent)
+static int __init imx53_tzic_init_cb(struct device_node *np,
+				     struct device_node *interrupt_parent)
 {
-	irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL);
+	void __iomem *base = of_iomap(np, 0);
+
+	WARN_ON(!base);
+	tzic_init_irq(base, np);
+
 	return 0;
 }
 
@@ -67,7 +72,7 @@  static int __init imx53_gpio_add_irq_domain(struct device_node *np,
 }
 
 static const struct of_device_id imx53_irq_match[] __initconst = {
-	{ .compatible = "fsl,imx53-tzic", .data = imx53_tzic_add_irq_domain, },
+	{ .compatible = "fsl,imx53-tzic", .data = imx53_tzic_init_cb, },
 	{ .compatible = "fsl,imx53-gpio", .data = imx53_gpio_add_irq_domain, },
 	{ /* sentinel */ }
 };
@@ -80,14 +85,17 @@  static const struct of_device_id imx53_iomuxc_of_match[] __initconst = {
 	{ /* sentinel */ }
 };
 
+static void __init imx53_dt_irq_init(void)
+{
+	of_irq_init(imx53_irq_match);
+}
+
 static void __init imx53_dt_init(void)
 {
 	struct device_node *node;
 	const struct of_device_id *of_id;
 	void (*func)(void);
 
-	of_irq_init(imx53_irq_match);
-
 	node = of_find_matching_node(NULL, imx53_iomuxc_of_match);
 	if (node) {
 		of_id = of_match_node(imx53_iomuxc_of_match, node);
@@ -120,7 +128,7 @@  static const char *imx53_dt_board_compat[] __initdata = {
 DT_MACHINE_START(IMX53_DT, "Freescale i.MX53 (Device Tree Support)")
 	.map_io		= mx53_map_io,
 	.init_early	= imx53_init_early,
-	.init_irq	= mx53_init_irq,
+	.init_irq	= imx53_dt_irq_init,
 	.handle_irq	= imx53_handle_irq,
 	.timer		= &imx53_timer,
 	.init_machine	= imx53_dt_init,
diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c
index bc17dfe..bed8562 100644
--- a/arch/arm/mach-mx5/mm.c
+++ b/arch/arm/mach-mx5/mm.c
@@ -120,17 +120,17 @@  void __init imx53_init_early(void)
 
 void __init mx50_init_irq(void)
 {
-	tzic_init_irq(MX50_IO_ADDRESS(MX50_TZIC_BASE_ADDR));
+	tzic_init_irq(MX50_IO_ADDRESS(MX50_TZIC_BASE_ADDR), NULL);
 }
 
 void __init mx51_init_irq(void)
 {
-	tzic_init_irq(MX51_IO_ADDRESS(MX51_TZIC_BASE_ADDR));
+	tzic_init_irq(MX51_IO_ADDRESS(MX51_TZIC_BASE_ADDR), NULL);
 }
 
 void __init mx53_init_irq(void)
 {
-	tzic_init_irq(MX53_IO_ADDRESS(MX53_TZIC_BASE_ADDR));
+	tzic_init_irq(MX53_IO_ADDRESS(MX53_TZIC_BASE_ADDR), NULL);
 }
 
 static struct sdma_script_start_addrs imx51_sdma_script __initdata = {
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 1bf0df8..4291992 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -11,6 +11,7 @@ 
 #ifndef __ASM_ARCH_MXC_COMMON_H__
 #define __ASM_ARCH_MXC_COMMON_H__
 
+struct device_node;
 struct platform_device;
 struct clk;
 enum mxc_cpu_pwr_mode;
@@ -34,7 +35,7 @@  extern void imx50_init_early(void);
 extern void imx51_init_early(void);
 extern void imx53_init_early(void);
 extern void mxc_init_irq(void __iomem *);
-extern void tzic_init_irq(void __iomem *);
+extern void tzic_init_irq(void __iomem *, struct device_node *np);
 extern void mx1_init_irq(void);
 extern void mx21_init_irq(void);
 extern void mx25_init_irq(void);
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
index 98308ec..8288187 100644
--- a/arch/arm/plat-mxc/tzic.c
+++ b/arch/arm/plat-mxc/tzic.c
@@ -15,6 +15,7 @@ 
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/io.h>
+#include <linux/irqdomain.h>
 
 #include <asm/mach/irq.h>
 #include <asm/exception.h>
@@ -49,6 +50,7 @@ 
 #define TZIC_ID0	0x0FD0	/* Indentification Register 0 */
 
 void __iomem *tzic_base; /* Used as irq controller base in entry-macro.S */
+static struct irq_chip_generic *tzic_gc;
 
 #define TZIC_NUM_IRQS 128
 
@@ -77,15 +79,14 @@  static int tzic_set_irq_fiq(unsigned int irq, unsigned int type)
 static void tzic_irq_suspend(struct irq_data *d)
 {
 	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
-	int idx = gc->irq_base >> 5;
+	int idx = d->hwirq / 32;
 
 	__raw_writel(gc->wake_active, tzic_base + TZIC_WAKEUP0(idx));
 }
 
 static void tzic_irq_resume(struct irq_data *d)
 {
-	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
-	int idx = gc->irq_base >> 5;
+	int idx = d->hwirq / 32;
 
 	__raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(idx)),
 		     tzic_base + TZIC_WAKEUP0(idx));
@@ -102,18 +103,14 @@  static struct mxc_extra_irq tzic_extra_irq = {
 #endif
 };
 
-static __init void tzic_init_gc(unsigned int irq_start)
+static __init void tzic_init_gc(struct irq_chip_generic *gc)
 {
-	struct irq_chip_generic *gc;
-	struct irq_chip_type *ct;
-	int idx = irq_start >> 5;
+	struct irq_chip_type *ct = gc->chip_types;
+	int idx = gc->hwirq_base / 32;
 
-	gc = irq_alloc_generic_chip("tzic", 1, irq_start, tzic_base,
-				    handle_level_irq);
-	gc->private = &tzic_extra_irq;
+	tzic_gc = gc;
 	gc->wake_enabled = IRQ_MSK(32);
 
-	ct = gc->chip_types;
 	ct->chip.irq_mask = irq_gc_mask_disable_reg;
 	ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
 	ct->chip.irq_set_wake = irq_gc_set_wake;
@@ -121,8 +118,6 @@  static __init void tzic_init_gc(unsigned int irq_start)
 	ct->chip.irq_resume = tzic_irq_resume;
 	ct->regs.disable = TZIC_ENCLEAR0(idx);
 	ct->regs.enable = TZIC_ENSET0(idx);
-
-	irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0);
 }
 
 asmlinkage void __exception_irq_entry tzic_handle_irq(struct pt_regs *regs)
@@ -140,7 +135,8 @@  asmlinkage void __exception_irq_entry tzic_handle_irq(struct pt_regs *regs)
 			while (stat) {
 				handled = 1;
 				irqofs = fls(stat) - 1;
-				handle_IRQ(irqofs + i * 32, regs);
+				handle_IRQ(irq_find_mapping(tzic_gc->domain,
+						irqofs + i * 32), regs);
 				stat &= ~(1 << irqofs);
 			}
 		}
@@ -152,7 +148,7 @@  asmlinkage void __exception_irq_entry tzic_handle_irq(struct pt_regs *regs)
  * interrupts. It registers the interrupt enable and disable functions
  * to the kernel for each interrupt source.
  */
-void __init tzic_init_irq(void __iomem *irqbase)
+void __init tzic_init_irq(void __iomem *irqbase, struct device_node *np)
 {
 	int i;
 
@@ -175,8 +171,10 @@  void __init tzic_init_irq(void __iomem *irqbase)
 
 	/* all IRQ no FIQ Warning :: No selection */
 
-	for (i = 0; i < TZIC_NUM_IRQS; i += 32)
-		tzic_init_gc(i);
+	irq_setup_generic_chip_domain("tzic", np, 1, 0, tzic_base,
+				      handle_level_irq, TZIC_NUM_IRQS, 0,
+				      IRQ_NOREQUEST, 0,
+				      tzic_init_gc, &tzic_extra_irq);
 
 #ifdef CONFIG_FIQ
 	/* Initialize FIQ */