[PATCH v2 2/7] ARM: imx5: adopt generic_chip irq_domain support for tzic
Rob Herring
robherring2 at gmail.com
Wed Feb 15 22:43:01 EST 2012
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 at linaro.org>
One comment below, otherwise:
Acked-by: Rob Herring <rob.herring at 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 at 73fa0000 {
> + compatible = "fsl,imx51-gpt", "fsl,gpt";
> + reg = <0x73fa0000 0x4000>;
> + interrupts = <39>;
> + };
> +
> uart1: uart at 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 at 53fa0000 {
> + compatible = "fsl,imx53-gpt", "fsl,gpt";
> + reg = <0x53fa0000 0x4000>;
> + interrupts = <39>;
> + };
> +
> uart1: uart at 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 */
More information about the linux-arm-kernel
mailing list