From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
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 <larisa.grigore@nxp.com>
Signed-off-by: Larisa Grigore <larisa.grigore@nxp.com>
Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
---
drivers/irqchip/Kconfig | 6 ++--
drivers/irqchip/irq-imx-irqsteer.c | 53 ++++++++++++++++++++++--------
2 files changed, 43 insertions(+), 16 deletions(-)
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index f07b00d7fef9..ad32a084afba 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -541,11 +541,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 4682ce5bf8d3..fb3594b9a244 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 },
{},
};
--
2.43.0
On Wed, Mar 11 2026 at 09:11, Ciprian Costea wrote:
> From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
>
> 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 <larisa.grigore@nxp.com>
> Signed-off-by: Larisa Grigore <larisa.grigore@nxp.com>
> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
I've picked up this one. Can the ARM64 folks please pick up the DT muck
as that really has close to zero relevance to irqchips.
Thanks,
tglx
On Wed, Mar 11, 2026 at 10:09:37AM +0100, Thomas Gleixner wrote: > On Wed, Mar 11 2026 at 09:11, Ciprian Costea wrote: > > From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com> > > > > 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 <larisa.grigore@nxp.com> > > Signed-off-by: Larisa Grigore <larisa.grigore@nxp.com> > > Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com> > > I've picked up this one. Can the ARM64 folks please pick up the DT muck > as that really has close to zero relevance to irqchips. Did you pick binding one? PATCH v6 1/5] dt-bindings: interrupt-controller: fsl,irqsteer: add S32N79 support I have not founnd at linux-next yet. Frank > > Thanks, > > tglx
On Wed, Mar 11, 2026 at 11:50:44AM -0400, Frank Li wrote: > On Wed, Mar 11, 2026 at 10:09:37AM +0100, Thomas Gleixner wrote: > > On Wed, Mar 11 2026 at 09:11, Ciprian Costea wrote: > > > From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com> > > > > > > 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 <larisa.grigore@nxp.com> > > > Signed-off-by: Larisa Grigore <larisa.grigore@nxp.com> > > > Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com> > > > > I've picked up this one. Can the ARM64 folks please pick up the DT muck > > as that really has close to zero relevance to irqchips. > > Did you pick binding one? The replies to the thread clearly say what was applied. > PATCH v6 1/5] dt-bindings: interrupt-controller: fsl,irqsteer: add S32N79 support > > I have not founnd at linux-next yet. Please take the binding with the .dts file changes. Rob
The following commit has been merged into the irq/drivers branch of tip:
Commit-ID: 5e72917802dd65ad1ff57f2158a9d221b4fddf0b
Gitweb: https://git.kernel.org/tip/5e72917802dd65ad1ff57f2158a9d221b4fddf0b
Author: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
AuthorDate: Wed, 11 Mar 2026 09:11:52 +01:00
Committer: Thomas Gleixner <tglx@kernel.org>
CommitterDate: Wed, 11 Mar 2026 09:55:26 +01:00
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 <larisa.grigore@nxp.com>
Signed-off-by: Larisa Grigore <larisa.grigore@nxp.com>
Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Link: https://patch.msgid.link/20260311081154.381881-4-ciprianmarian.costea@oss.nxp.com
---
drivers/irqchip/Kconfig | 6 +--
drivers/irqchip/irq-imx-irqsteer.c | 53 +++++++++++++++++++++--------
2 files changed, 43 insertions(+), 16 deletions(-)
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index dc26eff..2feecfb 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 4682ce5..87b07f5 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 },
{},
};
© 2016 - 2026 Red Hat, Inc.