* [PATCH 0/3] irqchip/renesas-rzg2l: Bug fixes and NMI support
@ 2026-03-28 10:33 Biju
2026-03-28 10:33 ` [PATCH 1/3] irqchip/renesas-rzg2l: Fix shared IRQ bit not cleared on free Biju
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Biju @ 2026-03-28 10:33 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Biju Das, linux-kernel, Geert Uytterhoeven, Prabhakar Mahadev Lad,
Biju Das, linux-renesas-soc
From: Biju Das <biju.das.jz@bp.renesas.com>
This series contains two bug fixes and a new feature for the Renesas
RZ/G2L IRQC driver.
Patch 1 fixes a bug where the shared IRQ bit is not cleared on free.
When irq_domain_free_irqs_common() is called, it internally resets
irq_data->hwirq to 0 via irq_domain_reset_irq_data(). The fix caches hwirq
before calling irq_domain_free_irqs_common().
Patch 2 simplifies the locking logic in rzg2l_irq_set_type() by replacing
the open-coded raw_spin_{lock,unlock} pair with guard(), and adds the
missing cleanup.h header.
Patch 3 adds NMI support, introducing a dedicated IRQ chip with EOI
handling, trigger type configuration, and suspend/resume support.
NMI Testing on RZ/G3L SMARC EVK:
:~# cat /proc/interrupts | grep NMI
59: 0 0 0 0 rzg2l-irqc 0 Edge NMI
Pull down GP_INT# line on green pack device by I2C command
:~# i2cset -y -f 0 0x38 0x30 0x00; sleep 1; i2cset -y -f 0 0x38 0x30 0x18
:~# cat /proc/interrupts | grep NMI
59: 1 0 0 0 rzg2l-irqc 0 Edge NMI
root@smarc-rzg3l:~#
Biju Das (3):
irqchip/renesas-rzg2l: Fix shared IRQ bit not cleared on free
irqchip/renesas-rzg2l: Replace raw_spin_{lock,unlock} with guard() in
rzg2l_irq_set_type()
irqchip/renesas-rzg2l: Add NMI support
drivers/irqchip/irq-renesas-rzg2l.c | 105 +++++++++++++++++++++++++---
1 file changed, 97 insertions(+), 8 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/3] irqchip/renesas-rzg2l: Fix shared IRQ bit not cleared on free
2026-03-28 10:33 [PATCH 0/3] irqchip/renesas-rzg2l: Bug fixes and NMI support Biju
@ 2026-03-28 10:33 ` Biju
2026-03-31 17:26 ` [tip: irq/drivers] irqchip/renesas-rzg2l: Clear the shared interrupt bit in rzg2l_irqc_free() tip-bot2 for Biju Das
2026-03-28 10:33 ` [PATCH 2/3] irqchip/renesas-rzg2l: Replace raw_spin_{lock,unlock} with guard() in rzg2l_irq_set_type() Biju
2026-03-28 10:33 ` [PATCH 3/3] irqchip/renesas-rzg2l: Add NMI support Biju
2 siblings, 1 reply; 13+ messages in thread
From: Biju @ 2026-03-28 10:33 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Biju Das, linux-kernel, Geert Uytterhoeven, Prabhakar Mahadev Lad,
Biju Das, linux-renesas-soc
From: Biju Das <biju.das.jz@bp.renesas.com>
Calling irq_domain_free_irqs_common() internally calls
irq_domain_reset_irq_data(), which explicitly sets irq_data->hwirq
to 0. Consequently, irqd_to_hwirq(d) returns 0 when called after it.
Since 0 falls outside the valid shared IRQ ranges,
rzg2l_irqc_is_shared_and_get_irq_num() evaluates to false, completely
bypassing the test_and_clear_bit() operation. This leaves the bit set
in priv->used_irqs, causing future allocations to fail with -EBUSY.
Fix this by retrieving irq_data and caching hwirq before calling
irq_domain_free_irqs_common().
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
drivers/irqchip/irq-renesas-rzg2l.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index f5c4d7e0aec3..3cc1efd8d914 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -699,15 +699,14 @@ static int rzg2l_irqc_alloc(struct irq_domain *domain, unsigned int virq,
static void rzg2l_irqc_free(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs)
{
+ struct irq_data *d = irq_domain_get_irq_data(domain, virq);
struct rzg2l_irqc_priv *priv = domain->host_data;
+ irq_hw_number_t hwirq = irqd_to_hwirq(d);
irq_domain_free_irqs_common(domain, virq, nr_irqs);
- if (priv->info.shared_irq_cnt) {
- struct irq_data *d = irq_domain_get_irq_data(domain, virq);
-
- rzg2l_irqc_shared_irq_free(priv, irqd_to_hwirq(d));
- }
+ if (priv->info.shared_irq_cnt)
+ rzg2l_irqc_shared_irq_free(priv, hwirq);
}
static const struct irq_domain_ops rzg2l_irqc_domain_ops = {
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 2/3] irqchip/renesas-rzg2l: Replace raw_spin_{lock,unlock} with guard() in rzg2l_irq_set_type()
2026-03-28 10:33 [PATCH 0/3] irqchip/renesas-rzg2l: Bug fixes and NMI support Biju
2026-03-28 10:33 ` [PATCH 1/3] irqchip/renesas-rzg2l: Fix shared IRQ bit not cleared on free Biju
@ 2026-03-28 10:33 ` Biju
2026-03-28 13:20 ` [tip: irq/drivers] " tip-bot2 for Biju Das
2026-03-28 10:33 ` [PATCH 3/3] irqchip/renesas-rzg2l: Add NMI support Biju
2 siblings, 1 reply; 13+ messages in thread
From: Biju @ 2026-03-28 10:33 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Biju Das, linux-kernel, Geert Uytterhoeven, Prabhakar Mahadev Lad,
Biju Das, linux-renesas-soc
From: Biju Das <biju.das.jz@bp.renesas.com>
Simplify the locking logic in rzg2l_irq_set_type() by using guard(),
eliminating the need for an explicit unlock call.
While at it, add the missing cleanup.h header file.
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
drivers/irqchip/irq-renesas-rzg2l.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index 3cc1efd8d914..0f1157d5ce55 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -8,6 +8,7 @@
*/
#include <linux/bitfield.h>
+#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
@@ -373,14 +374,13 @@ static int rzg2l_irq_set_type(struct irq_data *d, unsigned int type)
return -EINVAL;
}
- raw_spin_lock(&priv->lock);
+ guard(raw_spinlock)(&priv->lock);
tmp = readl_relaxed(priv->base + IITSR);
tmp &= ~IITSR_IITSEL_MASK(iitseln);
tmp |= IITSR_IITSEL(iitseln, sense);
if (clear_irq_int)
rzg2l_clear_irq_int(priv, hwirq);
writel_relaxed(tmp, priv->base + IITSR);
- raw_spin_unlock(&priv->lock);
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 3/3] irqchip/renesas-rzg2l: Add NMI support
2026-03-28 10:33 [PATCH 0/3] irqchip/renesas-rzg2l: Bug fixes and NMI support Biju
2026-03-28 10:33 ` [PATCH 1/3] irqchip/renesas-rzg2l: Fix shared IRQ bit not cleared on free Biju
2026-03-28 10:33 ` [PATCH 2/3] irqchip/renesas-rzg2l: Replace raw_spin_{lock,unlock} with guard() in rzg2l_irq_set_type() Biju
@ 2026-03-28 10:33 ` Biju
2026-03-28 16:19 ` Wolfram Sang
2026-03-31 16:15 ` Thomas Gleixner
2 siblings, 2 replies; 13+ messages in thread
From: Biju @ 2026-03-28 10:33 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Biju Das, linux-kernel, Geert Uytterhoeven, Prabhakar Mahadev Lad,
Biju Das, linux-renesas-soc
From: Biju Das <biju.das.jz@bp.renesas.com>
The RZ/G3L SoC has an NMI interrupt. Add support for the NMI interrupt.
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
drivers/irqchip/irq-renesas-rzg2l.c | 92 ++++++++++++++++++++++++++++-
1 file changed, 91 insertions(+), 1 deletion(-)
diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index 0f1157d5ce55..622a9045b606 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -21,11 +21,14 @@
#include <linux/spinlock.h>
#include <linux/syscore_ops.h>
+#define IRQC_NMI 0
#define IRQC_IRQ_START 1
#define IRQC_TINT_COUNT 32
#define IRQC_SHARED_IRQ_COUNT 8
#define IRQC_IRQ_SHARED_START (IRQC_IRQ_START + IRQC_SHARED_IRQ_COUNT)
+#define NSCR 0x0
+#define NITSR 0x4
#define ISCR 0x10
#define IITSR 0x14
#define TSCR 0x20
@@ -44,6 +47,9 @@
#define TSSR_OFFSET(n) ((n) % 4)
#define TSSR_INDEX(n) ((n) / 4)
+#define NITSR_NTSEL_EDGE_FALLING 0
+#define NITSR_NTSEL_EDGE_RISING 1
+
#define TITSR_TITSEL_EDGE_RISING 0
#define TITSR_TITSEL_EDGE_FALLING 1
#define TITSR_TITSEL_LEVEL_HIGH 2
@@ -64,11 +70,13 @@
/**
* struct rzg2l_irqc_reg_cache - registers cache (necessary for suspend/resume)
+ * @nitsr: NITSR register
* @iitsr: IITSR register
* @inttsel: INTTSEL register
* @titsr: TITSR registers
*/
struct rzg2l_irqc_reg_cache {
+ u32 nitsr;
u32 iitsr;
u32 inttsel;
u32 titsr[2];
@@ -117,6 +125,22 @@ static struct rzg2l_irqc_priv *irq_data_to_priv(struct irq_data *data)
return data->domain->host_data;
}
+static void rzg2l_clear_nmi_int(struct rzg2l_irqc_priv *priv, unsigned int hwirq)
+{
+ u32 bit = BIT(hwirq);
+ u32 reg;
+
+ reg = readl_relaxed(priv->base + NSCR);
+ if (reg & bit) {
+ writel_relaxed(reg & ~bit, priv->base + NSCR);
+ /*
+ * Enforce that the posted write is flushed to prevent that the
+ * just handled interrupt is raised again.
+ */
+ readl_relaxed(priv->base + NSCR);
+ }
+}
+
static void rzg2l_clear_irq_int(struct rzg2l_irqc_priv *priv, unsigned int hwirq)
{
unsigned int hw_irq = hwirq - IRQC_IRQ_START;
@@ -156,6 +180,17 @@ static void rzg2l_clear_tint_int(struct rzg2l_irqc_priv *priv, unsigned int hwir
}
}
+static void rzg2l_irqc_nmi_eoi(struct irq_data *d)
+{
+ struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
+ unsigned int hw_irq = irqd_to_hwirq(d);
+
+ scoped_guard(raw_spinlock, &priv->lock)
+ rzg2l_clear_nmi_int(priv, hw_irq);
+
+ irq_chip_eoi_parent(d);
+}
+
static void rzg2l_irqc_irq_eoi(struct irq_data *d)
{
struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
@@ -342,6 +377,29 @@ static void rzg2l_irqc_tint_enable(struct irq_data *d)
irq_chip_enable_parent(d);
}
+static int rzg2l_nmi_set_type(struct irq_data *d, unsigned int type)
+{
+ struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
+ u32 sense;
+
+ switch (type & IRQ_TYPE_SENSE_MASK) {
+ case IRQ_TYPE_EDGE_FALLING:
+ sense = NITSR_NTSEL_EDGE_FALLING;
+ break;
+
+ case IRQ_TYPE_EDGE_RISING:
+ sense = NITSR_NTSEL_EDGE_RISING;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ writel_relaxed(sense, priv->base + NITSR);
+
+ return 0;
+}
+
static int rzg2l_irq_set_type(struct irq_data *d, unsigned int type)
{
struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
@@ -468,11 +526,23 @@ static int rzg2l_irqc_tint_set_type(struct irq_data *d, unsigned int type)
return irq_chip_set_type_parent(d, IRQ_TYPE_LEVEL_HIGH);
}
+static int rzg2l_irqc_nmi_set_type(struct irq_data *d, unsigned int type)
+{
+ int ret;
+
+ ret = rzg2l_nmi_set_type(d, type);
+ if (ret)
+ return ret;
+
+ return irq_chip_set_type_parent(d, IRQ_TYPE_LEVEL_HIGH);
+}
+
static int rzg2l_irqc_irq_suspend(void *data)
{
struct rzg2l_irqc_reg_cache *cache = &rzg2l_irqc_data->cache;
void __iomem *base = rzg2l_irqc_data->base;
+ cache->nitsr = readl_relaxed(base + NITSR);
cache->iitsr = readl_relaxed(base + IITSR);
if (rzg2l_irqc_data->info.shared_irq_cnt)
cache->inttsel = readl_relaxed(base + INTTSEL);
@@ -497,6 +567,7 @@ static void rzg2l_irqc_irq_resume(void *data)
if (rzg2l_irqc_data->info.shared_irq_cnt)
writel_relaxed(cache->inttsel, base + INTTSEL);
writel_relaxed(cache->iitsr, base + IITSR);
+ writel_relaxed(cache->nitsr, base + NITSR);
}
static const struct syscore_ops rzg2l_irqc_syscore_ops = {
@@ -508,6 +579,23 @@ static struct syscore rzg2l_irqc_syscore = {
.ops = &rzg2l_irqc_syscore_ops,
};
+static const struct irq_chip rzg2l_irqc_nmi_chip = {
+ .name = "rzg2l-irqc",
+ .irq_eoi = rzg2l_irqc_nmi_eoi,
+ .irq_mask = irq_chip_mask_parent,
+ .irq_unmask = irq_chip_unmask_parent,
+ .irq_disable = irq_chip_disable_parent,
+ .irq_enable = irq_chip_enable_parent,
+ .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_nmi_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 rzg2l_irqc_irq_chip = {
.name = "rzg2l-irqc",
.irq_eoi = rzg2l_irqc_irq_eoi,
@@ -663,7 +751,9 @@ static int rzg2l_irqc_alloc(struct irq_domain *domain, unsigned int virq,
* from 16-31 bits. TINT from the pinctrl driver needs to be programmed
* in IRQC registers to enable a given gpio pin as interrupt.
*/
- if (hwirq > priv->info.irq_count) {
+ if (hwirq == IRQC_NMI) {
+ chip = &rzg2l_irqc_nmi_chip;
+ } else if (hwirq > priv->info.irq_count) {
tint = TINT_EXTRACT_GPIOINT(hwirq);
hwirq = TINT_EXTRACT_HWIRQ(hwirq);
chip = priv->tint_chip;
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [tip: irq/drivers] irqchip/renesas-rzg2l: Replace raw_spin_{lock,unlock} with guard() in rzg2l_irq_set_type()
2026-03-28 10:33 ` [PATCH 2/3] irqchip/renesas-rzg2l: Replace raw_spin_{lock,unlock} with guard() in rzg2l_irq_set_type() Biju
@ 2026-03-28 13:20 ` tip-bot2 for Biju Das
0 siblings, 0 replies; 13+ messages in thread
From: tip-bot2 for Biju Das @ 2026-03-28 13:20 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Biju Das, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the irq/drivers branch of tip:
Commit-ID: 9fd2170d70178faa0427adaa9d2dfdbfa231d1b7
Gitweb: https://git.kernel.org/tip/9fd2170d70178faa0427adaa9d2dfdbfa231d1b7
Author: Biju Das <biju.das.jz@bp.renesas.com>
AuthorDate: Sat, 28 Mar 2026 10:33:19
Committer: Thomas Gleixner <tglx@kernel.org>
CommitterDate: Sat, 28 Mar 2026 14:14:51 +01:00
irqchip/renesas-rzg2l: Replace raw_spin_{lock,unlock} with guard() in rzg2l_irq_set_type()
Simplify the locking logic in rzg2l_irq_set_type() by using guard(),
eliminating the need for an explicit unlock call.
[ tglx: Remove the pointless cleanup.h include. The spinlock guards come
from spinlock.h ]
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Link: https://patch.msgid.link/20260328103324.134131-3-biju.das.jz@bp.renesas.com
---
drivers/irqchip/irq-renesas-rzg2l.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index f5c4d7e..755fac3 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -373,14 +373,13 @@ static int rzg2l_irq_set_type(struct irq_data *d, unsigned int type)
return -EINVAL;
}
- raw_spin_lock(&priv->lock);
+ guard(raw_spinlock)(&priv->lock);
tmp = readl_relaxed(priv->base + IITSR);
tmp &= ~IITSR_IITSEL_MASK(iitseln);
tmp |= IITSR_IITSEL(iitseln, sense);
if (clear_irq_int)
rzg2l_clear_irq_int(priv, hwirq);
writel_relaxed(tmp, priv->base + IITSR);
- raw_spin_unlock(&priv->lock);
return 0;
}
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 3/3] irqchip/renesas-rzg2l: Add NMI support
2026-03-28 10:33 ` [PATCH 3/3] irqchip/renesas-rzg2l: Add NMI support Biju
@ 2026-03-28 16:19 ` Wolfram Sang
2026-03-31 17:35 ` Biju Das
2026-03-31 16:15 ` Thomas Gleixner
1 sibling, 1 reply; 13+ messages in thread
From: Wolfram Sang @ 2026-03-28 16:19 UTC (permalink / raw)
To: Biju
Cc: Thomas Gleixner, Biju Das, linux-kernel, Geert Uytterhoeven,
Prabhakar Mahadev Lad, linux-renesas-soc
[-- Attachment #1: Type: text/plain, Size: 111 bytes --]
> +static const struct irq_chip rzg2l_irqc_nmi_chip = {
> + .name = "rzg2l-irqc",
"rzg2l-irqc-nmi" maybe?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/3] irqchip/renesas-rzg2l: Add NMI support
2026-03-28 10:33 ` [PATCH 3/3] irqchip/renesas-rzg2l: Add NMI support Biju
2026-03-28 16:19 ` Wolfram Sang
@ 2026-03-31 16:15 ` Thomas Gleixner
2026-03-31 17:10 ` Biju Das
1 sibling, 1 reply; 13+ messages in thread
From: Thomas Gleixner @ 2026-03-31 16:15 UTC (permalink / raw)
To: Biju
Cc: Biju Das, linux-kernel, Geert Uytterhoeven, Prabhakar Mahadev Lad,
Biju Das, linux-renesas-soc
On Sat, Mar 28 2026 at 10:33, Biju wrote:
> +static void rzg2l_irqc_nmi_eoi(struct irq_data *d)
> +{
> + struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
> + unsigned int hw_irq = irqd_to_hwirq(d);
> +
> + scoped_guard(raw_spinlock, &priv->lock)
> + rzg2l_clear_nmi_int(priv, hw_irq);
Is priv is shared between regular interrupts and the NMI?
If so, then you can't take the lock.
// Some other context (task, interrupt)
raw_spinlock(priv->lock);
--> NMI
raw_spinlock(priv->lock);
--> Livelock.
Thanks,
tglx
^ permalink raw reply [flat|nested] 13+ messages in thread
* RE: [PATCH 3/3] irqchip/renesas-rzg2l: Add NMI support
2026-03-31 16:15 ` Thomas Gleixner
@ 2026-03-31 17:10 ` Biju Das
2026-03-31 20:29 ` Thomas Gleixner
0 siblings, 1 reply; 13+ messages in thread
From: Biju Das @ 2026-03-31 17:10 UTC (permalink / raw)
To: Thomas Gleixner, biju.das.au
Cc: linux-kernel@vger.kernel.org, Geert Uytterhoeven,
Prabhakar Mahadev Lad, biju.das.au,
linux-renesas-soc@vger.kernel.org
Hi Thomas,
Thanks for the feedback.
> -----Original Message-----
> From: Thomas Gleixner <tglx@kernel.org>
> Sent: 31 March 2026 17:16
> Subject: Re: [PATCH 3/3] irqchip/renesas-rzg2l: Add NMI support
>
> On Sat, Mar 28 2026 at 10:33, Biju wrote:
> > +static void rzg2l_irqc_nmi_eoi(struct irq_data *d) {
> > + struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
> > + unsigned int hw_irq = irqd_to_hwirq(d);
> > +
> > + scoped_guard(raw_spinlock, &priv->lock)
> > + rzg2l_clear_nmi_int(priv, hw_irq);
>
> Is priv is shared between regular interrupts and the NMI?
Yes.
>
> If so, then you can't take the lock.
OK.
>
> // Some other context (task, interrupt)
> raw_spinlock(priv->lock);
>
> --> NMI
>
> raw_spinlock(priv->lock);
>
> --> Livelock.
Will drop the lock as it is not RMW operation.
Cheers,
Biju
^ permalink raw reply [flat|nested] 13+ messages in thread
* [tip: irq/drivers] irqchip/renesas-rzg2l: Clear the shared interrupt bit in rzg2l_irqc_free()
2026-03-28 10:33 ` [PATCH 1/3] irqchip/renesas-rzg2l: Fix shared IRQ bit not cleared on free Biju
@ 2026-03-31 17:26 ` tip-bot2 for Biju Das
0 siblings, 0 replies; 13+ messages in thread
From: tip-bot2 for Biju Das @ 2026-03-31 17:26 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Biju Das, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the irq/drivers branch of tip:
Commit-ID: d3689cd02c5de52ff5f3044169c482aee0dd5a78
Gitweb: https://git.kernel.org/tip/d3689cd02c5de52ff5f3044169c482aee0dd5a78
Author: Biju Das <biju.das.jz@bp.renesas.com>
AuthorDate: Sat, 28 Mar 2026 10:33:18
Committer: Thomas Gleixner <tglx@kernel.org>
CommitterDate: Tue, 31 Mar 2026 18:25:29 +02:00
irqchip/renesas-rzg2l: Clear the shared interrupt bit in rzg2l_irqc_free()
rzg2l_irqc_free() invokes irq_domain_free_irqs_common(), which internally
calls irq_domain_reset_irq_data(). That explicitly sets irq_data->hwirq to
0. Consequently, irqd_to_hwirq(d) returns 0 when called after it.
Since 0 falls outside the valid shared IRQ ranges,
rzg2l_irqc_is_shared_and_get_irq_num() evaluates to false, completely
bypassing the test_and_clear_bit() operation.
This leaves the bit set in priv->used_irqs, causing future allocations to
fail with -EBUSY.
Fix this by retrieving irq_data and caching hwirq before calling
irq_domain_free_irqs_common().
Fixes: e0fcae27ff57 ("irqchip/renesas-rzg2l: Add shared interrupt support")
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Link: https://patch.msgid.link/20260328103324.134131-2-biju.das.jz@bp.renesas.com
---
drivers/irqchip/irq-renesas-rzg2l.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index 755fac3..199b3c6 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -698,15 +698,14 @@ shared_irq_free:
static void rzg2l_irqc_free(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs)
{
+ struct irq_data *d = irq_domain_get_irq_data(domain, virq);
struct rzg2l_irqc_priv *priv = domain->host_data;
+ irq_hw_number_t hwirq = irqd_to_hwirq(d);
irq_domain_free_irqs_common(domain, virq, nr_irqs);
- if (priv->info.shared_irq_cnt) {
- struct irq_data *d = irq_domain_get_irq_data(domain, virq);
-
- rzg2l_irqc_shared_irq_free(priv, irqd_to_hwirq(d));
- }
+ if (priv->info.shared_irq_cnt)
+ rzg2l_irqc_shared_irq_free(priv, hwirq);
}
static const struct irq_domain_ops rzg2l_irqc_domain_ops = {
^ permalink raw reply related [flat|nested] 13+ messages in thread
* RE: [PATCH 3/3] irqchip/renesas-rzg2l: Add NMI support
2026-03-28 16:19 ` Wolfram Sang
@ 2026-03-31 17:35 ` Biju Das
0 siblings, 0 replies; 13+ messages in thread
From: Biju Das @ 2026-03-31 17:35 UTC (permalink / raw)
To: wsa+renesas, biju.das.au
Cc: Thomas Gleixner, linux-kernel@vger.kernel.org, Geert Uytterhoeven,
Prabhakar Mahadev Lad, linux-renesas-soc@vger.kernel.org
Hi Wolfram Sang,
Thanks for the feedback.
> -----Original Message-----
> From: Wolfram Sang <wsa+renesas@sang-engineering.com>
> Sent: 28 March 2026 16:19
> Subject: Re: [PATCH 3/3] irqchip/renesas-rzg2l: Add NMI support
>
>
> > +static const struct irq_chip rzg2l_irqc_nmi_chip = {
> > + .name = "rzg2l-irqc",
>
> "rzg2l-irqc-nmi" maybe?
irq chip for tint and external interrupt are using "rzg2l-irqc"
for consistency "rzg2l-irqc" better compared to "rzg2l-irqc-nmi"
It reduces memory as a single pointer will be used in the
structure and also reduces number of changes.
Otherwise, we need to change
rzg2l-irqc-irq --> RZ/G2L irq interrupt
rzg2l-irqc-tint--> RZ/G2L tint interrupt
rzg2l-irqc-nmi --> RZ/{G2L,Five} nmi interrupt
rzfive-irqc-irq--> RZ/Five irq interrupt
rzfive-irqc-tint--> RZ/Five tint interrupt
Cheers,
Biju
^ permalink raw reply [flat|nested] 13+ messages in thread
* RE: [PATCH 3/3] irqchip/renesas-rzg2l: Add NMI support
2026-03-31 17:10 ` Biju Das
@ 2026-03-31 20:29 ` Thomas Gleixner
2026-04-01 7:30 ` Biju Das
0 siblings, 1 reply; 13+ messages in thread
From: Thomas Gleixner @ 2026-03-31 20:29 UTC (permalink / raw)
To: Biju Das, biju.das.au
Cc: linux-kernel@vger.kernel.org, Geert Uytterhoeven,
Prabhakar Mahadev Lad, biju.das.au,
linux-renesas-soc@vger.kernel.org
On Tue, Mar 31 2026 at 17:10, Biju Das wrote:
>> From: Thomas Gleixner <tglx@kernel.org>
> Will drop the lock as it is not RMW operation.
Huch?
> +static void rzg2l_clear_nmi_int(struct rzg2l_irqc_priv *priv, unsigned int hwirq)
> +{
> + u32 bit = BIT(hwirq);
> + u32 reg;
> +
> + reg = readl_relaxed(priv->base + NSCR);
> + if (reg & bit) {
> + writel_relaxed(reg & ~bit, priv->base + NSCR);
> + /*
> + * Enforce that the posted write is flushed to prevent that the
> + * just handled interrupt is raised again.
> + */
> + readl_relaxed(priv->base + NSCR);
> + }
> +}
How is that not RMW?
I assume that you want to explain that it's not a RMW on a shared
register, right?
Thanks,
tglx
^ permalink raw reply [flat|nested] 13+ messages in thread
* RE: [PATCH 3/3] irqchip/renesas-rzg2l: Add NMI support
2026-03-31 20:29 ` Thomas Gleixner
@ 2026-04-01 7:30 ` Biju Das
2026-04-01 11:22 ` Thomas Gleixner
0 siblings, 1 reply; 13+ messages in thread
From: Biju Das @ 2026-04-01 7:30 UTC (permalink / raw)
To: Thomas Gleixner, biju.das.au
Cc: linux-kernel@vger.kernel.org, Geert Uytterhoeven,
Prabhakar Mahadev Lad, biju.das.au,
linux-renesas-soc@vger.kernel.org
Hi Thomas,
> -----Original Message-----
> From: Thomas Gleixner <tglx@kernel.org>
> Sent: 31 March 2026 21:30
> Subject: RE: [PATCH 3/3] irqchip/renesas-rzg2l: Add NMI support
>
> On Tue, Mar 31 2026 at 17:10, Biju Das wrote:
> >> From: Thomas Gleixner <tglx@kernel.org>
> > Will drop the lock as it is not RMW operation.
>
> Huch?
>
> > +static void rzg2l_clear_nmi_int(struct rzg2l_irqc_priv *priv,
> > +unsigned int hwirq) {
> > + u32 bit = BIT(hwirq);
> > + u32 reg;
> > +
> > + reg = readl_relaxed(priv->base + NSCR);
> > + if (reg & bit) {
> > + writel_relaxed(reg & ~bit, priv->base + NSCR);
> > + /*
> > + * Enforce that the posted write is flushed to prevent that the
> > + * just handled interrupt is raised again.
> > + */
> > + readl_relaxed(priv->base + NSCR);
> > + }
> > +}
>
> How is that not RMW?
It is not a shared reg, as there is only a single NMI interrupt and hwirq is always 0.
I will drop BIT(hwirq) to avoid confusion related to the shared register.
>
> I assume that you want to explain that it's not a RMW on a shared register, right?
Bit16 - NSMON: NMI pin signal level monitor register (read only)
Bit0 - NSTAT: NMI interrupt status. Writing is allowed only when NSTAT is 1.
Yes, I will add a comment: Writing is allowed only when NSTAT is 1.
Cheers,
Biju
^ permalink raw reply [flat|nested] 13+ messages in thread
* RE: [PATCH 3/3] irqchip/renesas-rzg2l: Add NMI support
2026-04-01 7:30 ` Biju Das
@ 2026-04-01 11:22 ` Thomas Gleixner
0 siblings, 0 replies; 13+ messages in thread
From: Thomas Gleixner @ 2026-04-01 11:22 UTC (permalink / raw)
To: Biju Das, biju.das.au
Cc: linux-kernel@vger.kernel.org, Geert Uytterhoeven,
Prabhakar Mahadev Lad, biju.das.au,
linux-renesas-soc@vger.kernel.org
On Wed, Apr 01 2026 at 07:30, Biju Das wrote:
>> From: Thomas Gleixner <tglx@kernel.org>
>>
>> How is that not RMW?
>
> It is not a shared reg, as there is only a single NMI interrupt and hwirq is always 0.
> I will drop BIT(hwirq) to avoid confusion related to the shared register.
>
>>
>> I assume that you want to explain that it's not a RMW on a shared register, right?
>
> Bit16 - NSMON: NMI pin signal level monitor register (read only)
> Bit0 - NSTAT: NMI interrupt status. Writing is allowed only when NSTAT is 1.
>
> Yes, I will add a comment: Writing is allowed only when NSTAT is 1.
Yes please.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-04-01 11:22 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-28 10:33 [PATCH 0/3] irqchip/renesas-rzg2l: Bug fixes and NMI support Biju
2026-03-28 10:33 ` [PATCH 1/3] irqchip/renesas-rzg2l: Fix shared IRQ bit not cleared on free Biju
2026-03-31 17:26 ` [tip: irq/drivers] irqchip/renesas-rzg2l: Clear the shared interrupt bit in rzg2l_irqc_free() tip-bot2 for Biju Das
2026-03-28 10:33 ` [PATCH 2/3] irqchip/renesas-rzg2l: Replace raw_spin_{lock,unlock} with guard() in rzg2l_irq_set_type() Biju
2026-03-28 13:20 ` [tip: irq/drivers] " tip-bot2 for Biju Das
2026-03-28 10:33 ` [PATCH 3/3] irqchip/renesas-rzg2l: Add NMI support Biju
2026-03-28 16:19 ` Wolfram Sang
2026-03-31 17:35 ` Biju Das
2026-03-31 16:15 ` Thomas Gleixner
2026-03-31 17:10 ` Biju Das
2026-03-31 20:29 ` Thomas Gleixner
2026-04-01 7:30 ` Biju Das
2026-04-01 11:22 ` Thomas Gleixner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox