From: Ciprian Marian Costea Date: Wed, 11 Mar 2026 08:11:52 +0000 (+0100) Subject: irqchip/imx-irqsteer: Add NXP S32N79 support X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5e72917802dd65ad1ff57f2158a9d221b4fddf0b;p=thirdparty%2Flinux.git irqchip/imx-irqsteer: Add NXP S32N79 support Add support for the interrupt steering controller found in NXP S32N79 series automotive SoCs. The S32N79 IRQ_STEER variant differs from the i.MX version by not implementing the CHANCTRL register. To handle this hardware difference, introduce a device type data structure with quirks field. The IRQSTEER_QUIRK_NO_CHANCTRL quirk skips CHANCTRL register access for S32N79 variants. The interrupt routing functionality and register layout are otherwise identical between the two variants. Co-developed-by: Larisa Grigore Signed-off-by: Larisa Grigore Signed-off-by: Ciprian Marian Costea Signed-off-by: Thomas Gleixner Link: https://patch.msgid.link/20260311081154.381881-4-ciprianmarian.costea@oss.nxp.com --- diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index dc26effa5b364..2feecfb5a28d9 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -544,11 +544,11 @@ config CSKY_APB_INTC config IMX_IRQSTEER bool "i.MX IRQSTEER support" - depends on ARCH_MXC || COMPILE_TEST - default ARCH_MXC + depends on ARCH_MXC || ARCH_S32 || COMPILE_TEST + default y if ARCH_MXC || ARCH_S32 select IRQ_DOMAIN help - Support for the i.MX IRQSTEER interrupt multiplexer/remapper. + Support for the i.MX and S32 IRQSTEER interrupt multiplexer/remapper. config IMX_INTMUX bool "i.MX INTMUX support" if COMPILE_TEST diff --git a/drivers/irqchip/irq-imx-irqsteer.c b/drivers/irqchip/irq-imx-irqsteer.c index 4682ce5bf8d3c..87b07f517be35 100644 --- a/drivers/irqchip/irq-imx-irqsteer.c +++ b/drivers/irqchip/irq-imx-irqsteer.c @@ -26,19 +26,38 @@ #define CHAN_MAX_OUTPUT_INT 0xF +/* SoC does not implement the CHANCTRL register */ +#define IRQSTEER_QUIRK_NO_CHANCTRL BIT(0) + +struct irqsteer_devtype_data { + u32 quirks; +}; + struct irqsteer_data { - void __iomem *regs; - struct clk *ipg_clk; - int irq[CHAN_MAX_OUTPUT_INT]; - int irq_count; - raw_spinlock_t lock; - int reg_num; - int channel; - struct irq_domain *domain; - u32 *saved_reg; - struct device *dev; + void __iomem *regs; + struct clk *ipg_clk; + int irq[CHAN_MAX_OUTPUT_INT]; + int irq_count; + raw_spinlock_t lock; + int reg_num; + int channel; + struct irq_domain *domain; + u32 *saved_reg; + struct device *dev; + const struct irqsteer_devtype_data *devtype_data; +}; + +static const struct irqsteer_devtype_data imx_data = { }; + +static const struct irqsteer_devtype_data s32n79_data = { + .quirks = IRQSTEER_QUIRK_NO_CHANCTRL, }; +static bool irqsteer_has_chanctrl(const struct irqsteer_devtype_data *data) +{ + return !(data->quirks & IRQSTEER_QUIRK_NO_CHANCTRL); +} + static int imx_irqsteer_get_reg_index(struct irqsteer_data *data, unsigned long irqnum) { @@ -188,6 +207,10 @@ static int imx_irqsteer_probe(struct platform_device *pdev) if (ret) return ret; + data->devtype_data = device_get_match_data(&pdev->dev); + if (!data->devtype_data) + return dev_err_probe(&pdev->dev, -ENODEV, "failed to match device data\n"); + /* * There is one output irq for each group of 64 inputs. * One register bit map can represent 32 input interrupts. @@ -210,7 +233,8 @@ static int imx_irqsteer_probe(struct platform_device *pdev) } /* steer all IRQs into configured channel */ - writel_relaxed(BIT(data->channel), data->regs + CHANCTRL); + if (irqsteer_has_chanctrl(data->devtype_data)) + writel_relaxed(BIT(data->channel), data->regs + CHANCTRL); data->domain = irq_domain_create_linear(dev_fwnode(&pdev->dev), data->reg_num * 32, &imx_irqsteer_domain_ops, data); @@ -279,7 +303,9 @@ static void imx_irqsteer_restore_regs(struct irqsteer_data *data) { int i; - writel_relaxed(BIT(data->channel), data->regs + CHANCTRL); + if (irqsteer_has_chanctrl(data->devtype_data)) + writel_relaxed(BIT(data->channel), data->regs + CHANCTRL); + for (i = 0; i < data->reg_num; i++) writel_relaxed(data->saved_reg[i], data->regs + CHANMASK(i, data->reg_num)); @@ -319,7 +345,8 @@ static const struct dev_pm_ops imx_irqsteer_pm_ops = { }; static const struct of_device_id imx_irqsteer_dt_ids[] = { - { .compatible = "fsl,imx-irqsteer", }, + { .compatible = "fsl,imx-irqsteer", .data = &imx_data }, + { .compatible = "nxp,s32n79-irqsteer", .data = &s32n79_data }, {}, };