From: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx> The IRQC block on RZ/G2UL SoC is almost identical to one found on the RZ/G2L SoC the only difference being it can support BUS_ERR_INT for which it has additional registers. This patch adds a new entry for "renesas,rzg2ul-irqc" compatible string and now that we have interrupt-names property the driver code parses the interrupts based on names and for backward compatibility we fallback to parse interrupts based on index. For now we will be using rzg2l_irqc_init() as a callback for RZ/G2UL SoC too and in future when the interrupt handler will be registered for BUS_ERR_INT we will have to implement a new callback. Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx> --- v1 -> v2 * New patch --- drivers/irqchip/irq-renesas-rzg2l.c | 80 ++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 6 deletions(-) diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c index 7918fe201218..5bdf0106ef51 100644 --- a/drivers/irqchip/irq-renesas-rzg2l.c +++ b/drivers/irqchip/irq-renesas-rzg2l.c @@ -299,19 +299,86 @@ static const struct irq_domain_ops rzg2l_irqc_domain_ops = { .translate = irq_domain_translate_twocell, }; -static int rzg2l_irqc_parse_interrupts(struct rzg2l_irqc_priv *priv, - struct device_node *np) +static int rzg2l_irqc_parse_interrupt_to_fwspec(struct rzg2l_irqc_priv *priv, + struct device_node *np, + unsigned int index, + unsigned int fwspec_index) { struct of_phandle_args map; + int ret; + + ret = of_irq_parse_one(np, index, &map); + if (ret) + return ret; + + of_phandle_args_to_fwspec(np, map.args, map.args_count, + &priv->fwspec[fwspec_index]); + + return 0; +} + +static int rzg2l_irqc_parse_interrupt_by_name_to_fwspec(struct rzg2l_irqc_priv *priv, + struct device_node *np, + char *irq_name, + unsigned int fwspec_index) +{ + int index; + + index = of_property_match_string(np, "interrupt-names", irq_name); + if (index < 0) + return index; + + return rzg2l_irqc_parse_interrupt_to_fwspec(priv, np, index, fwspec_index); +} + +/* Parse hierarchy domain interrupts ie only IRQ0-7 and TINT0-31 */ +static int rzg2l_irqc_parse_hierarchy_interrupts(struct rzg2l_irqc_priv *priv, + struct device_node *np) +{ + struct property *pp; unsigned int i; int ret; + /* + * first check if interrupt-names property exists if so parse them by name + * or else parse them by index for backward compatibility. + */ + pp = of_find_property(np, "interrupt-names", NULL); + if (pp) { + char *irq_name; + + /* parse IRQ0-7 */ + for (i = 0; i < IRQC_IRQ_COUNT; i++) { + irq_name = kasprintf(GFP_KERNEL, "irq%d", i); + if (!irq_name) + return -ENOMEM; + + ret = rzg2l_irqc_parse_interrupt_by_name_to_fwspec(priv, np, irq_name, i); + kfree(irq_name); + if (ret) + return ret; + } + + /* parse TINT0-31 */ + for (i = 0; i < IRQC_TINT_COUNT; i++) { + irq_name = kasprintf(GFP_KERNEL, "tint%d", i); + if (!irq_name) + return -ENOMEM; + + ret = rzg2l_irqc_parse_interrupt_by_name_to_fwspec(priv, np, irq_name, + i + IRQC_IRQ_COUNT); + kfree(irq_name); + if (ret) + return ret; + } + + return 0; + } + for (i = 1; i <= IRQC_NUM_HIERARCHY_IRQ; i++) { - ret = of_irq_parse_one(np, i, &map); + ret = rzg2l_irqc_parse_interrupt_to_fwspec(priv, np, i, i - 1); if (ret) return ret; - of_phandle_args_to_fwspec(np, map.args, map.args_count, - &priv->fwspec[i - 1]); } return 0; @@ -343,7 +410,7 @@ static int rzg2l_irqc_init(struct device_node *node, struct device_node *parent) if (IS_ERR(priv->base)) return PTR_ERR(priv->base); - ret = rzg2l_irqc_parse_interrupts(priv, node); + ret = rzg2l_irqc_parse_hierarchy_interrupts(priv, node); if (ret) { dev_err(&pdev->dev, "cannot parse interrupts: %d\n", ret); return ret; @@ -389,6 +456,7 @@ static int rzg2l_irqc_init(struct device_node *node, struct device_node *parent) IRQCHIP_PLATFORM_DRIVER_BEGIN(rzg2l_irqc) IRQCHIP_MATCH("renesas,rzg2l-irqc", rzg2l_irqc_init) +IRQCHIP_MATCH("renesas,rzg2ul-irqc", rzg2l_irqc_init) IRQCHIP_PLATFORM_DRIVER_END(rzg2l_irqc) MODULE_AUTHOR("Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx>"); MODULE_DESCRIPTION("Renesas RZ/G2L IRQC Driver"); -- 2.25.1