On 10:21-20150117, Marc Zyngier wrote:
> Commit 9a1091ef0017 (irqchip: gic: Support hierarchy irq domain)
should have been
Commit 9a1091ef0017 ("irqchip: gic: Support hierarchy irq domain")

> changed the GIC driver to use a non-legacy IRQ domain on DT
> platforms. This patch assumes that DT-driven systems are getting
> all of their interrupts from device tree.
> 
> Turns out that OMAP has quite a few hidden gems, and still uses
> hardcoded interrupts despite having fairly complete DTs.
> 
> This patch attempts to work around these by offering a translation
> method that can be called directly from the hwmod code, if present.
> The same hack is sprinkled over PRCM and TWL.
> 
> It isn't pretty, but it seems to do the job without having to add
> more hacks to the interrupt controller code.
> 
> Tested on OMAP4 (Panda-ES) and OMAP5 (UEVM5432).
> 
> Signed-off-by: Marc Zyngier <[email protected]>

Other than that, This looks good to me.
Acked-by: Nishanth Menon <[email protected]>

> ---
> From v1:
> - OMAP4 can either get the PRM interrupt from hwmod or from device tree.
>   In the latter case, remove the xlate_irq method.
> 
>  arch/arm/mach-omap2/common.h               |  1 +
>  arch/arm/mach-omap2/omap4-common.c         | 32 
> ++++++++++++++++++++++++++++++
>  arch/arm/mach-omap2/omap_hwmod.c           | 10 ++++++++--
>  arch/arm/mach-omap2/omap_hwmod.h           |  1 +
>  arch/arm/mach-omap2/omap_hwmod_44xx_data.c |  5 +++++
>  arch/arm/mach-omap2/omap_hwmod_54xx_data.c |  1 +
>  arch/arm/mach-omap2/prcm-common.h          |  1 +
>  arch/arm/mach-omap2/prm44xx.c              |  5 ++++-
>  arch/arm/mach-omap2/prm_common.c           | 14 +++++++++++--
>  arch/arm/mach-omap2/twl-common.c           |  5 ++++-
>  10 files changed, 69 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
> index 377eea8..b664494 100644
> --- a/arch/arm/mach-omap2/common.h
> +++ b/arch/arm/mach-omap2/common.h
> @@ -211,6 +211,7 @@ extern struct device *omap2_get_iva_device(void);
>  extern struct device *omap2_get_l3_device(void);
>  extern struct device *omap4_get_dsp_device(void);
>  
> +unsigned int omap4_xlate_irq(unsigned int hwirq);
>  void omap_gic_of_init(void);
>  
>  #ifdef CONFIG_CACHE_L2X0
> diff --git a/arch/arm/mach-omap2/omap4-common.c 
> b/arch/arm/mach-omap2/omap4-common.c
> index b7cb44a..cc30e49 100644
> --- a/arch/arm/mach-omap2/omap4-common.c
> +++ b/arch/arm/mach-omap2/omap4-common.c
> @@ -256,6 +256,38 @@ static int __init omap4_sar_ram_init(void)
>  }
>  omap_early_initcall(omap4_sar_ram_init);
>  
> +static struct of_device_id gic_match[] = {
> +     { .compatible = "arm,cortex-a9-gic", },
> +     { .compatible = "arm,cortex-a15-gic", },
> +     { },
> +};
> +
> +static struct device_node *gic_node;
> +
> +unsigned int omap4_xlate_irq(unsigned int hwirq)
> +{
> +     struct of_phandle_args irq_data;
> +     unsigned int irq;
> +
> +     if (!gic_node)
> +             gic_node = of_find_matching_node(NULL, gic_match);
> +
> +     if (WARN_ON(!gic_node))
> +             return hwirq;
> +
> +     irq_data.np = gic_node;
> +     irq_data.args_count = 3;
> +     irq_data.args[0] = 0;
> +     irq_data.args[1] = hwirq - OMAP44XX_IRQ_GIC_START;
> +     irq_data.args[2] = IRQ_TYPE_LEVEL_HIGH;
> +
> +     irq = irq_create_of_mapping(&irq_data);
> +     if (WARN_ON(!irq))
> +             irq = hwirq;
> +
> +     return irq;
> +}
> +
>  void __init omap_gic_of_init(void)
>  {
>       struct device_node *np;
> diff --git a/arch/arm/mach-omap2/omap_hwmod.c 
> b/arch/arm/mach-omap2/omap_hwmod.c
> index cbb908d..9025fff 100644
> --- a/arch/arm/mach-omap2/omap_hwmod.c
> +++ b/arch/arm/mach-omap2/omap_hwmod.c
> @@ -3534,9 +3534,15 @@ int omap_hwmod_fill_resources(struct omap_hwmod *oh, 
> struct resource *res)
>  
>       mpu_irqs_cnt = _count_mpu_irqs(oh);
>       for (i = 0; i < mpu_irqs_cnt; i++) {
> +             unsigned int irq;
> +
> +             if (oh->xlate_irq)
> +                     irq = oh->xlate_irq((oh->mpu_irqs + i)->irq);
> +             else
> +                     irq = (oh->mpu_irqs + i)->irq;
>               (res + r)->name = (oh->mpu_irqs + i)->name;
> -             (res + r)->start = (oh->mpu_irqs + i)->irq;
> -             (res + r)->end = (oh->mpu_irqs + i)->irq;
> +             (res + r)->start = irq;
> +             (res + r)->end = irq;
>               (res + r)->flags = IORESOURCE_IRQ;
>               r++;
>       }
> diff --git a/arch/arm/mach-omap2/omap_hwmod.h 
> b/arch/arm/mach-omap2/omap_hwmod.h
> index 35ca6ef..5b42faf 100644
> --- a/arch/arm/mach-omap2/omap_hwmod.h
> +++ b/arch/arm/mach-omap2/omap_hwmod.h
> @@ -676,6 +676,7 @@ struct omap_hwmod {
>       spinlock_t                      _lock;
>       struct list_head                node;
>       struct omap_hwmod_ocp_if        *_mpu_port;
> +     unsigned int                    (*xlate_irq)(unsigned int);
>       u16                             flags;
>       u8                              mpu_rt_idx;
>       u8                              response_lat;
> diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c 
> b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
> index c314b3c..f5e68a7 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
> @@ -479,6 +479,7 @@ static struct omap_hwmod omap44xx_dma_system_hwmod = {
>       .class          = &omap44xx_dma_hwmod_class,
>       .clkdm_name     = "l3_dma_clkdm",
>       .mpu_irqs       = omap44xx_dma_system_irqs,
> +     .xlate_irq      = omap4_xlate_irq,
>       .main_clk       = "l3_div_ck",
>       .prcm = {
>               .omap4 = {
> @@ -640,6 +641,7 @@ static struct omap_hwmod omap44xx_dss_dispc_hwmod = {
>       .class          = &omap44xx_dispc_hwmod_class,
>       .clkdm_name     = "l3_dss_clkdm",
>       .mpu_irqs       = omap44xx_dss_dispc_irqs,
> +     .xlate_irq      = omap4_xlate_irq,
>       .sdma_reqs      = omap44xx_dss_dispc_sdma_reqs,
>       .main_clk       = "dss_dss_clk",
>       .prcm = {
> @@ -693,6 +695,7 @@ static struct omap_hwmod omap44xx_dss_dsi1_hwmod = {
>       .class          = &omap44xx_dsi_hwmod_class,
>       .clkdm_name     = "l3_dss_clkdm",
>       .mpu_irqs       = omap44xx_dss_dsi1_irqs,
> +     .xlate_irq      = omap4_xlate_irq,
>       .sdma_reqs      = omap44xx_dss_dsi1_sdma_reqs,
>       .main_clk       = "dss_dss_clk",
>       .prcm = {
> @@ -726,6 +729,7 @@ static struct omap_hwmod omap44xx_dss_dsi2_hwmod = {
>       .class          = &omap44xx_dsi_hwmod_class,
>       .clkdm_name     = "l3_dss_clkdm",
>       .mpu_irqs       = omap44xx_dss_dsi2_irqs,
> +     .xlate_irq      = omap4_xlate_irq,
>       .sdma_reqs      = omap44xx_dss_dsi2_sdma_reqs,
>       .main_clk       = "dss_dss_clk",
>       .prcm = {
> @@ -784,6 +788,7 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = {
>        */
>       .flags          = HWMOD_SWSUP_SIDLE,
>       .mpu_irqs       = omap44xx_dss_hdmi_irqs,
> +     .xlate_irq      = omap4_xlate_irq,
>       .sdma_reqs      = omap44xx_dss_hdmi_sdma_reqs,
>       .main_clk       = "dss_48mhz_clk",
>       .prcm = {
> diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c 
> b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
> index 3e95230..7c3fac0 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
> @@ -288,6 +288,7 @@ static struct omap_hwmod omap54xx_dma_system_hwmod = {
>       .class          = &omap54xx_dma_hwmod_class,
>       .clkdm_name     = "dma_clkdm",
>       .mpu_irqs       = omap54xx_dma_system_irqs,
> +     .xlate_irq      = omap4_xlate_irq,
>       .main_clk       = "l3_iclk_div",
>       .prcm = {
>               .omap4 = {
> diff --git a/arch/arm/mach-omap2/prcm-common.h 
> b/arch/arm/mach-omap2/prcm-common.h
> index a8e4b58..6163d66 100644
> --- a/arch/arm/mach-omap2/prcm-common.h
> +++ b/arch/arm/mach-omap2/prcm-common.h
> @@ -498,6 +498,7 @@ struct omap_prcm_irq_setup {
>       u8 nr_irqs;
>       const struct omap_prcm_irq *irqs;
>       int irq;
> +     unsigned int (*xlate_irq)(unsigned int);
>       void (*read_pending_irqs)(unsigned long *events);
>       void (*ocp_barrier)(void);
>       void (*save_and_clear_irqen)(u32 *saved_mask);
> diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
> index cc170fb..408c64e 100644
> --- a/arch/arm/mach-omap2/prm44xx.c
> +++ b/arch/arm/mach-omap2/prm44xx.c
> @@ -49,6 +49,7 @@ static struct omap_prcm_irq_setup omap4_prcm_irq_setup = {
>       .irqs                   = omap4_prcm_irqs,
>       .nr_irqs                = ARRAY_SIZE(omap4_prcm_irqs),
>       .irq                    = 11 + OMAP44XX_IRQ_GIC_START,
> +     .xlate_irq              = omap4_xlate_irq,
>       .read_pending_irqs      = &omap44xx_prm_read_pending_irqs,
>       .ocp_barrier            = &omap44xx_prm_ocp_barrier,
>       .save_and_clear_irqen   = &omap44xx_prm_save_and_clear_irqen,
> @@ -751,8 +752,10 @@ static int omap44xx_prm_late_init(void)
>               }
>  
>               /* Once OMAP4 DT is filled as well */
> -             if (irq_num >= 0)
> +             if (irq_num >= 0) {
>                       omap4_prcm_irq_setup.irq = irq_num;
> +                     omap4_prcm_irq_setup.xlate_irq = NULL;
> +             }
>       }
>  
>       omap44xx_prm_enable_io_wakeup();
> diff --git a/arch/arm/mach-omap2/prm_common.c 
> b/arch/arm/mach-omap2/prm_common.c
> index 779940c..dea2833 100644
> --- a/arch/arm/mach-omap2/prm_common.c
> +++ b/arch/arm/mach-omap2/prm_common.c
> @@ -187,6 +187,7 @@ int omap_prcm_event_to_irq(const char *name)
>   */
>  void omap_prcm_irq_cleanup(void)
>  {
> +     unsigned int irq;
>       int i;
>  
>       if (!prcm_irq_setup) {
> @@ -211,7 +212,11 @@ void omap_prcm_irq_cleanup(void)
>       kfree(prcm_irq_setup->priority_mask);
>       prcm_irq_setup->priority_mask = NULL;
>  
> -     irq_set_chained_handler(prcm_irq_setup->irq, NULL);
> +     if (prcm_irq_setup->xlate_irq)
> +             irq = prcm_irq_setup->xlate_irq(prcm_irq_setup->irq);
> +     else
> +             irq = prcm_irq_setup->irq;
> +     irq_set_chained_handler(irq, NULL);
>  
>       if (prcm_irq_setup->base_irq > 0)
>               irq_free_descs(prcm_irq_setup->base_irq,
> @@ -259,6 +264,7 @@ int omap_prcm_register_chain_handler(struct 
> omap_prcm_irq_setup *irq_setup)
>       int offset, i;
>       struct irq_chip_generic *gc;
>       struct irq_chip_type *ct;
> +     unsigned int irq;
>  
>       if (!irq_setup)
>               return -EINVAL;
> @@ -298,7 +304,11 @@ int omap_prcm_register_chain_handler(struct 
> omap_prcm_irq_setup *irq_setup)
>                               1 << (offset & 0x1f);
>       }
>  
> -     irq_set_chained_handler(irq_setup->irq, omap_prcm_irq_handler);
> +     if (irq_setup->xlate_irq)
> +             irq = irq_setup->xlate_irq(irq_setup->irq);
> +     else
> +             irq = irq_setup->irq;
> +     irq_set_chained_handler(irq, omap_prcm_irq_handler);
>  
>       irq_setup->base_irq = irq_alloc_descs(-1, 0, irq_setup->nr_regs * 32,
>               0);
> diff --git a/arch/arm/mach-omap2/twl-common.c 
> b/arch/arm/mach-omap2/twl-common.c
> index 4457e73..3031ee1 100644
> --- a/arch/arm/mach-omap2/twl-common.c
> +++ b/arch/arm/mach-omap2/twl-common.c
> @@ -71,9 +71,12 @@ void __init omap4_pmic_init(const char *pmic_type,
>                   struct i2c_board_info *devices, int nr_devices)
>  {
>       /* PMIC part*/
> +     unsigned int irq;
> +
>       omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | 
> OMAP_PIN_OFF_WAKEUPENABLE);
>       omap_mux_init_signal("fref_clk0_out.sys_drm_msecure", OMAP_PIN_OUTPUT);
> -     omap_pmic_init(1, 400, pmic_type, 7 + OMAP44XX_IRQ_GIC_START, 
> pmic_data);
> +     irq = omap4_xlate_irq(7 + OMAP44XX_IRQ_GIC_START);
> +     omap_pmic_init(1, 400, pmic_type, irq, pmic_data);
>  
>       /* Register additional devices on i2c1 bus if needed */
>       if (devices)
> -- 
> 2.1.3
> 

-- 
Regards,
Nishanth Menon
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to