From: Biju Das Date: Wed, 25 Mar 2026 19:24:20 +0000 (+0000) Subject: irqchip/renesas-rzg2l: Replace single irq_chip with per-region irq_chip instances X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4b11d14cac6ae198ea855b871c73dc208a177a0e;p=thirdparty%2Fkernel%2Flinux.git irqchip/renesas-rzg2l: Replace single irq_chip with per-region irq_chip instances The driver uses a single irq_chip instance shared across all interrupt types, relying on dispatcher callbacks to differentiate between IRQ and TINT regions at runtime. Replace the per-SoC irq_chip and its dispatcher callbacks with dedicated irq_chip instances for each interrupt region: IRQ and TINT. Subsequent patches will add per-region callbacks for IRQ and TINT from the common code. Signed-off-by: Biju Das Signed-off-by: Thomas Gleixner Link: https://patch.msgid.link/20260325192451.172562-6-biju.das.jz@bp.renesas.com --- diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c index 8587d4c5f1101..1d1df49533681 100644 --- a/drivers/irqchip/irq-renesas-rzg2l.c +++ b/drivers/irqchip/irq-renesas-rzg2l.c @@ -71,14 +71,16 @@ struct rzg2l_irqc_reg_cache { /** * struct rzg2l_irqc_priv - IRQ controller private data structure * @base: Controller's base address - * @irqchip: Pointer to struct irq_chip + * @irq_chip: Pointer to struct irq_chip for irq + * @tint_chip: Pointer to struct irq_chip for tint * @fwspec: IRQ firmware specific data * @lock: Lock to serialize access to hardware registers * @cache: Registers cache for suspend/resume */ static struct rzg2l_irqc_priv { void __iomem *base; - const struct irq_chip *irqchip; + const struct irq_chip *irq_chip; + const struct irq_chip *tint_chip; struct irq_fwspec fwspec[IRQC_NUM_IRQ]; raw_spinlock_t lock; struct rzg2l_irqc_reg_cache cache; @@ -434,7 +436,7 @@ static struct syscore rzg2l_irqc_syscore = { .ops = &rzg2l_irqc_syscore_ops, }; -static const struct irq_chip rzg2l_irqc_chip = { +static const struct irq_chip rzg2l_irqc_irq_chip = { .name = "rzg2l-irqc", .irq_eoi = rzg2l_irqc_eoi, .irq_mask = irq_chip_mask_parent, @@ -451,7 +453,41 @@ static const struct irq_chip rzg2l_irqc_chip = { IRQCHIP_SKIP_SET_WAKE, }; -static const struct irq_chip rzfive_irqc_chip = { +static const struct irq_chip rzg2l_irqc_tint_chip = { + .name = "rzg2l-irqc", + .irq_eoi = rzg2l_irqc_eoi, + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_disable = rzg2l_irqc_irq_disable, + .irq_enable = rzg2l_irqc_irq_enable, + .irq_get_irqchip_state = irq_chip_get_parent_state, + .irq_set_irqchip_state = irq_chip_set_parent_state, + .irq_retrigger = irq_chip_retrigger_hierarchy, + .irq_set_type = rzg2l_irqc_set_type, + .irq_set_affinity = irq_chip_set_affinity_parent, + .flags = IRQCHIP_MASK_ON_SUSPEND | + IRQCHIP_SET_TYPE_MASKED | + IRQCHIP_SKIP_SET_WAKE, +}; + +static const struct irq_chip rzfive_irqc_irq_chip = { + .name = "rzfive-irqc", + .irq_eoi = rzg2l_irqc_eoi, + .irq_mask = rzfive_irqc_mask, + .irq_unmask = rzfive_irqc_unmask, + .irq_disable = rzfive_irqc_irq_disable, + .irq_enable = rzfive_irqc_irq_enable, + .irq_get_irqchip_state = irq_chip_get_parent_state, + .irq_set_irqchip_state = irq_chip_set_parent_state, + .irq_retrigger = irq_chip_retrigger_hierarchy, + .irq_set_type = rzg2l_irqc_set_type, + .irq_set_affinity = irq_chip_set_affinity_parent, + .flags = IRQCHIP_MASK_ON_SUSPEND | + IRQCHIP_SET_TYPE_MASKED | + IRQCHIP_SKIP_SET_WAKE, +}; + +static const struct irq_chip rzfive_irqc_tint_chip = { .name = "rzfive-irqc", .irq_eoi = rzg2l_irqc_eoi, .irq_mask = rzfive_irqc_mask, @@ -472,6 +508,7 @@ static int rzg2l_irqc_alloc(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs, void *arg) { struct rzg2l_irqc_priv *priv = domain->host_data; + const struct irq_chip *chip; unsigned long tint = 0; irq_hw_number_t hwirq; unsigned int type; @@ -491,13 +528,15 @@ static int rzg2l_irqc_alloc(struct irq_domain *domain, unsigned int virq, if (hwirq > IRQC_IRQ_COUNT) { tint = TINT_EXTRACT_GPIOINT(hwirq); hwirq = TINT_EXTRACT_HWIRQ(hwirq); + chip = priv->tint_chip; + } else { + chip = priv->irq_chip; } if (hwirq > (IRQC_NUM_IRQ - 1)) return -EINVAL; - ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, priv->irqchip, - (void *)(uintptr_t)tint); + ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, chip, (void *)(uintptr_t)tint); if (ret) return ret; @@ -529,7 +568,8 @@ static int rzg2l_irqc_parse_interrupts(struct rzg2l_irqc_priv *priv, } static int rzg2l_irqc_common_probe(struct platform_device *pdev, struct device_node *parent, - const struct irq_chip *irq_chip) + const struct irq_chip *irq_chip, + const struct irq_chip *tint_chip) { struct irq_domain *irq_domain, *parent_domain; struct device_node *node = pdev->dev.of_node; @@ -545,7 +585,8 @@ static int rzg2l_irqc_common_probe(struct platform_device *pdev, struct device_n if (!rzg2l_irqc_data) return -ENOMEM; - rzg2l_irqc_data->irqchip = irq_chip; + rzg2l_irqc_data->irq_chip = irq_chip; + rzg2l_irqc_data->tint_chip = tint_chip; rzg2l_irqc_data->base = devm_of_iomap(dev, dev->of_node, 0, NULL); if (IS_ERR(rzg2l_irqc_data->base)) @@ -585,12 +626,12 @@ static int rzg2l_irqc_common_probe(struct platform_device *pdev, struct device_n static int rzg2l_irqc_probe(struct platform_device *pdev, struct device_node *parent) { - return rzg2l_irqc_common_probe(pdev, parent, &rzg2l_irqc_chip); + return rzg2l_irqc_common_probe(pdev, parent, &rzg2l_irqc_irq_chip, &rzg2l_irqc_tint_chip); } static int rzfive_irqc_probe(struct platform_device *pdev, struct device_node *parent) { - return rzg2l_irqc_common_probe(pdev, parent, &rzfive_irqc_chip); + return rzg2l_irqc_common_probe(pdev, parent, &rzfive_irqc_irq_chip, &rzfive_irqc_tint_chip); } IRQCHIP_PLATFORM_DRIVER_BEGIN(rzg2l_irqc)