mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v6 00/15] Add RZ/G3L IRQC support
@ 2026-03-22 12:23 Biju
  2026-03-22 12:23 ` [PATCH v6 01/15] dt-bindings: interrupt-controller: renesas,rzg2l-irqc: Use pattern for interrupt-names Biju
                   ` (14 more replies)
  0 siblings, 15 replies; 22+ messages in thread
From: Biju @ 2026-03-22 12:23 UTC (permalink / raw)
  To: Thomas Gleixner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven, Magnus Damm
  Cc: Biju Das, Lad Prabhakar, linux-kernel, devicetree,
	linux-renesas-soc, Biju Das

From: Biju Das <biju.das.jz@bp.renesas.com>

The IRQC block on RZ/G3L SoC is almost identical to one found on the
RZ/G3S SoC with the difference like it support more external interrupts,
GPT error Interrupts and also has additional registers for GPT/MTU
interrupt selection, shared interrupt selection between external interrupt
and TINT.

It has 16 external interrupts of which 8 interrupts are shared with
TINT[24:31] and are mutually exclusive. The external IRQ/TINT interrupt
selection is based on a register in the ICU block.

Ref:
  v5: https://lore.kernel.org/all/20260311192459.609064-1-biju.das.jz@bp.renesas.com/
  v4: https://lore.kernel.org/all/20260227140316.308106-1-biju.das.jz@bp.renesas.com/
  v3: https://lore.kernel.org/all/20260206111658.231934-1-biju.das.jz@bp.renesas.com/
  v2: https://lore.kernel.org/all/20260204180632.249139-1-biju.das.jz@bp.renesas.com/
  v1: https://lore.kernel.org/all/20260204142320.103184-1-biju.das.jz@bp.renesas.com/
v5->v6:
 * Collected tag for binding patch#2
 * Updated commit description for patch#5,#7,#8,#9,#12and#15
 * Simplified rzg2l_irqc_{irq,tint}_eoi() by replacing raw_spin_lock
   locking/unlocking with scoped_guard().
 * Updated the variable type of offset, tssr_offset, and tssr_index to
   unsigned int, in rzfive_irqc_irq_enable() as these variables are used
   only for calculation.
 * Simplified rzfive_irqc_irq_enable() by replacing raw_spin_lock
   locking/unlocking with guard().
 * Simplified rzfive_{irq,tint}_endisable by replacing raw_spin_lock
   locking/unlocking with guard().
 * Updated the variable type of offset, tssr_offset, and tssr_index to
   unsigned int, in rzfive_tint_endisable() as these variables are used
   only for calculation.
 * Dropped stray newline in rzfive_tint_endisable().
 * Simplified rzfive_irqc_{irq,tint}_{mask,unmask}() by replacing
   raw_spin_lock locking/unlocking with scoped_guard().
 * Updated the variable type of titseln, tssr_offset, tssr_index, index,
   and sense to unsigned int, in rzg2l_tint_set_edge() as these variables
   are used only for calculation.
 * Switched to using irq_domain_ops::{alloc,free} callbacks for mutual
   exclusion between external interrupts and GPIO interrupts as using
   irq_{request,release}_resources() leading to irq storm()
 * Dropped irq_{request,release}_resources().
 * Replaced the macro TINTSEL->INTTSEL_TINTSEL
 * Added macros INTTSEL_TINTSEL_START, IRQC_SHARED_IRQ_COUNT and
   IRQC_IRQ_SHARED_START.
 * Added used_irqs bitmap to struct rzg2l_irqc_priv to track allocation
   state of shared_interrupt
 * Added rzg2l_irqc_set_inttsel() for configuring INTTSEL register.
 * Replaced irq_domain_free_irqs_common()->rzg2l_irqc_free() as 
   rzg2l_irqc_domain_ops::free() callback.
 * Replaced the 8->IRQC_SHARED_IRQ_COUNT in shared_irq_cnt varaible as
   the same macro used in bitmap.
v4->v5:
 * Added support for separate interrupt chips so that the decision is made
   at setup time and not at every interrupt delivery in the hotpath.
 * Dropped the hw_irq range check involving info.{num_irq,tint_start,
   irq_count}
 * Updated rzg3l_irqc_probe() for supporting separate interrupt chips.
 * Added callback irq_{request,release}_resources() to both irq and tint
   interrupt chips.
 * Dropped SoC dtsi patch from this series, will post later.
v3->v4:
 * Collected tag from Rob for binding patch#1
 * Updated commit description for binding patch#{1,2}.
 * Updated commit header for patch#3
 * Replaced IRQs->interrupts in commit description
 * Fixed the typo Dynamicaly->Dynamically
 * Updated commit description IRQs->interrupts in patch#4
 * Replaced the variable type for num_irq in struct rzg2l_hw_info from
   u8->unsigned int
 * Replaced the pointer variable info from irqc_priv and instead embed a
   struct hwinfo into irqc_priv and copy the data into it at probe time.
 * Replaced the check 'hwirq > (priv->info->num_irq - 1)' with
   hwirq >= priv->info.num_irq
 * Updated commit description 'this differences->this difference' in
   patch#5.
 * Updated tint_start variable type from u8-> unsigned int.
 * Updated commit description IRQs->interrupts in patch#6.
 * Updated variable type of irq_count from u8->unsigned int.
 * Updated commit description IRQs->interrupts in patch#7.
 * Updated rzg2l_disable_tint_and_set_tint_source() for making
   tint assignment very clear in the code.
 * Formatted rzg3l_tssel_lut as table format.
 * Updated commit header irq->interrupt in patch#8.
 * Updated commit description IRQs->interrupts.
 * Updated shared_irq_cnt variable type from u8->unsigned int.
v2->v3:
 * Dropped items and instead used enum for single compatible values
 * Add minItems for interrupts and interrupt-names properties of 
   the RZ/{G2L,G2UL,Five,V2L} SoCs
 * Replaced maxItems->minItems for interrupts and interrupt-names
   properties of the RZ/G3L SoC.
v1->v2:
 * Simplified the binding by using pattern for intterrupt-names
 * Fixed the binding warnings reported by bot.

Biju Das (15):
  dt-bindings: interrupt-controller: renesas,rzg2l-irqc: Use pattern for
    interrupt-names
  dt-bindings: interrupt-controller: renesas,rzg2l-irqc: Document RZ/G3L
    SoC
  irqchip/renesas-rzg2l: Drop redundant IRQC_TINT_START check in
    rzg2l_irqc_alloc()
  irqchip/renesas-rzg2l: Replace single irq_chip with per-region
    irq_chip instances
  irqchip/renesas-rzg2l: Split EOI handler into separate IRQ and TINT
    functions
  irqchip/renesas-rzg2l: Split set_type handler into separate IRQ and
    TINT functions
  irqchip/renesas-rzg2l: Replace rzg2l_irqc_irq_{enable,disable} with
    TINT-specific handlers
  irqchip/renesas-rzg2l: Split rzfive_tint_irq_endisable() into separate
    IRQ and TINT helpers
  irqchip/renesas-rzg2l: Split rzfive_irqc_{mask,unmask} into separate
    IRQ and TINT handlers
  irqchip/renesas-rzg2l: Dynamically allocate fwspec array
  irqchip/renesas-rzg2l: Drop IRQC_NUM_IRQ macro
  irqchip/renesas-rzg2l: Drop IRQC_TINT_START macro
  irqchip/renesas-rzg2l: Drop IRQC_IRQ_COUNT macro
  irqchip/renesas-rzg2l: Add RZ/G3L support
  irqchip/renesas-rzg2l: Add shared interrupt support

 .../renesas,rzg2l-irqc.yaml                   | 157 +++---
 drivers/irqchip/irq-renesas-rzg2l.c           | 461 ++++++++++++++----
 2 files changed, 412 insertions(+), 206 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 01/15] dt-bindings: interrupt-controller: renesas,rzg2l-irqc: Use pattern for interrupt-names
  2026-03-22 12:23 [PATCH v6 00/15] Add RZ/G3L IRQC support Biju
@ 2026-03-22 12:23 ` Biju
  2026-03-22 12:23 ` [PATCH v6 02/15] dt-bindings: interrupt-controller: renesas,rzg2l-irqc: Document RZ/G3L SoC Biju
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Biju @ 2026-03-22 12:23 UTC (permalink / raw)
  To: Thomas Gleixner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven, Magnus Damm
  Cc: Biju Das, Lad Prabhakar, linux-kernel, devicetree,
	linux-renesas-soc, Biju Das

From: Biju Das <biju.das.jz@bp.renesas.com>

Simplify the bindings by using pattern property for interrupt-names.
It also allows to change the ordering of interrupts.

Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v5->v6:
 * No change.
v4->v5:
 * No change.
v3->v4:
 * Updated commit description.
v2->v3: [3]
 * Dropped items and instead used enum for single compatible values
 * Add minItems for interrupts and interrupt-names properties of 
   the RZ/{G2L,G2UL,Five,V2L} SoCs
 * Replaced maxItems->minItems for interrupts and interrupt-names
   properties of the RZ/G3L SoC.
v1->v2: [2]
 * Simplified the binding using pattern

[3] https://lore.kernel.org/all/20260204180632.249139-3-biju.das.jz@bp.renesas.com/
[2] https://lore.kernel.org/all/20260206111658.231934-3-biju.das.jz@bp.renesas.com/
[1]https://lore.kernel.org/all/20260204142320.103184-2-biju.das.jz@bp.renesas.com/
---
v3->v4:
 * Collected tag from Rob [1]
 * Updated commit description and kept the tag as it is trivial change.
v2->v3: [2]
 * No change
v1->v2:
 * New patch [1].

[1] https://lore.kernel.org/all/20260204180632.249139-2-biju.das.jz@bp.renesas.com/
[2] https://lore.kernel.org/all/20260206111658.231934-2-biju.das.jz@bp.renesas.com/
---
 .../renesas,rzg2l-irqc.yaml                   | 120 ++++--------------
 1 file changed, 23 insertions(+), 97 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/renesas,rzg2l-irqc.yaml b/Documentation/devicetree/bindings/interrupt-controller/renesas,rzg2l-irqc.yaml
index 44b6ae5fc802..a0b57d808639 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/renesas,rzg2l-irqc.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,rzg2l-irqc.yaml
@@ -48,107 +48,33 @@ properties:
 
   interrupts:
     minItems: 45
-    items:
-      - description: NMI interrupt
-      - description: IRQ0 interrupt
-      - description: IRQ1 interrupt
-      - description: IRQ2 interrupt
-      - description: IRQ3 interrupt
-      - description: IRQ4 interrupt
-      - description: IRQ5 interrupt
-      - description: IRQ6 interrupt
-      - description: IRQ7 interrupt
-      - description: GPIO interrupt, TINT0
-      - description: GPIO interrupt, TINT1
-      - description: GPIO interrupt, TINT2
-      - description: GPIO interrupt, TINT3
-      - description: GPIO interrupt, TINT4
-      - description: GPIO interrupt, TINT5
-      - description: GPIO interrupt, TINT6
-      - description: GPIO interrupt, TINT7
-      - description: GPIO interrupt, TINT8
-      - description: GPIO interrupt, TINT9
-      - description: GPIO interrupt, TINT10
-      - description: GPIO interrupt, TINT11
-      - description: GPIO interrupt, TINT12
-      - description: GPIO interrupt, TINT13
-      - description: GPIO interrupt, TINT14
-      - description: GPIO interrupt, TINT15
-      - description: GPIO interrupt, TINT16
-      - description: GPIO interrupt, TINT17
-      - description: GPIO interrupt, TINT18
-      - description: GPIO interrupt, TINT19
-      - description: GPIO interrupt, TINT20
-      - description: GPIO interrupt, TINT21
-      - description: GPIO interrupt, TINT22
-      - description: GPIO interrupt, TINT23
-      - description: GPIO interrupt, TINT24
-      - description: GPIO interrupt, TINT25
-      - description: GPIO interrupt, TINT26
-      - description: GPIO interrupt, TINT27
-      - description: GPIO interrupt, TINT28
-      - description: GPIO interrupt, TINT29
-      - description: GPIO interrupt, TINT30
-      - description: GPIO interrupt, TINT31
-      - description: Bus error interrupt
-      - description: ECCRAM0 or combined ECCRAM0/1 1bit error interrupt
-      - description: ECCRAM0 or combined ECCRAM0/1 2bit error interrupt
-      - description: ECCRAM0 or combined ECCRAM0/1 error overflow interrupt
-      - description: ECCRAM1 1bit error interrupt
-      - description: ECCRAM1 2bit error interrupt
-      - description: ECCRAM1 error overflow interrupt
+    maxItems: 48
 
   interrupt-names:
     minItems: 45
+    maxItems: 48
     items:
-      - const: nmi
-      - const: irq0
-      - const: irq1
-      - const: irq2
-      - const: irq3
-      - const: irq4
-      - const: irq5
-      - const: irq6
-      - const: irq7
-      - const: tint0
-      - const: tint1
-      - const: tint2
-      - const: tint3
-      - const: tint4
-      - const: tint5
-      - const: tint6
-      - const: tint7
-      - const: tint8
-      - const: tint9
-      - const: tint10
-      - const: tint11
-      - const: tint12
-      - const: tint13
-      - const: tint14
-      - const: tint15
-      - const: tint16
-      - const: tint17
-      - const: tint18
-      - const: tint19
-      - const: tint20
-      - const: tint21
-      - const: tint22
-      - const: tint23
-      - const: tint24
-      - const: tint25
-      - const: tint26
-      - const: tint27
-      - const: tint28
-      - const: tint29
-      - const: tint30
-      - const: tint31
-      - const: bus-err
-      - const: ec7tie1-0
-      - const: ec7tie2-0
-      - const: ec7tiovf-0
-      - const: ec7tie1-1
-      - const: ec7tie2-1
-      - const: ec7tiovf-1
+      oneOf:
+        - description: NMI interrupt
+          const: nmi
+        - description: External IRQ interrupt
+          pattern: '^irq([0-7])$'
+        - description: GPIO interrupt
+          pattern: '^tint([0-9]|1[0-9]|2[0-9]|3[0-1])$'
+        - description: Bus error interrupt
+          const: bus-err
+        - description: ECCRAM0 or combined ECCRAM0/1 1bit error interrupt
+          const: ec7tie1-0
+        - description: ECCRAM0 or combined ECCRAM0/1 2bit error interrupt
+          const: ec7tie2-0
+        - description: ECCRAM0 or combined ECCRAM0/1 error overflow interrupt
+          const: ec7tiovf-0
+        - description: ECCRAM1 1bit error interrupt
+          const: ec7tie1-1
+        - description: ECCRAM1 2bit error interrupt
+          const: ec7tie2-1
+        - description: ECCRAM1 error overflow interrupt
+          const: ec7tiovf-1
 
   clocks:
     maxItems: 2
-- 
2.43.0


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 02/15] dt-bindings: interrupt-controller: renesas,rzg2l-irqc: Document RZ/G3L SoC
  2026-03-22 12:23 [PATCH v6 00/15] Add RZ/G3L IRQC support Biju
  2026-03-22 12:23 ` [PATCH v6 01/15] dt-bindings: interrupt-controller: renesas,rzg2l-irqc: Use pattern for interrupt-names Biju
@ 2026-03-22 12:23 ` Biju
  2026-03-22 12:23 ` [PATCH v6 03/15] irqchip/renesas-rzg2l: Drop redundant IRQC_TINT_START check in rzg2l_irqc_alloc() Biju
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Biju @ 2026-03-22 12:23 UTC (permalink / raw)
  To: Thomas Gleixner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven, Magnus Damm
  Cc: Biju Das, Lad Prabhakar, linux-kernel, devicetree,
	linux-renesas-soc, Biju Das

From: Biju Das <biju.das.jz@bp.renesas.com>

Document RZ/G3L (R9A08G046) IRQC. The IRQC block on the RZ/G3L SoC is
nearly identical to that found on the RZ/G3S SoC, with the following
differences: it supports more external interrupts and GPT error
interrupts, and adds registers for GPT/MTU interrupt selection and shared
interrupt selection between external interrupt and TINT. A new compatible
string "renesas,r9a08g046-irqc" is therefore introduced for the RZ/G3L
SoC.

Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v5->v6:
 * Collected tag.
v4->v5:
 * No change.
v3->v4: [4]
 * Updated commit description.
v2->v3: [3]
 * Dropped items and instead used enum for single compatible values
 * Add minItems for interrupts and interrupt-names properties of 
   the RZ/{G2L,G2UL,Five,V2L} SoCs
 * Replaced maxItems->minItems for interrupts and interrupt-names
   properties of the RZ/G3L SoC.
v1->v2: [2]
 * Simplified the binding using pattern

[4] https://lore.kernel.org/all/20260227140316.308106-3-biju.das.jz@bp.renesas.com/
[3] https://lore.kernel.org/all/20260204180632.249139-3-biju.das.jz@bp.renesas.com/
[2] https://lore.kernel.org/all/20260206111658.231934-3-biju.das.jz@bp.renesas.com/
[1]https://lore.kernel.org/all/20260204142320.103184-2-biju.das.jz@bp.renesas.com/
---
 .../renesas,rzg2l-irqc.yaml                   | 43 ++++++++++++++++---
 1 file changed, 36 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/renesas,rzg2l-irqc.yaml b/Documentation/devicetree/bindings/interrupt-controller/renesas,rzg2l-irqc.yaml
index a0b57d808639..3a221e1800a0 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/renesas,rzg2l-irqc.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,rzg2l-irqc.yaml
@@ -30,7 +30,9 @@ properties:
               - renesas,r9a08g045-irqc     # RZ/G3S
           - const: renesas,rzg2l-irqc
 
-      - const: renesas,r9a07g043f-irqc     # RZ/Five
+      - enum:
+          - renesas,r9a07g043f-irqc    # RZ/Five
+          - renesas,r9a08g046-irqc     # RZ/G3L
 
   '#interrupt-cells':
     description: The first cell should contain a macro RZG2L_{NMI,IRQX} included in the
@@ -48,17 +50,17 @@ properties:
 
   interrupts:
     minItems: 45
-    maxItems: 48
+    maxItems: 61
 
   interrupt-names:
     minItems: 45
-    maxItems: 48
+    maxItems: 61
     items:
       oneOf:
         - description: NMI interrupt
           const: nmi
         - description: External IRQ interrupt
-          pattern: '^irq([0-7])$'
+          pattern: '^irq([0-9]|1[0-5])$'
         - description: GPIO interrupt
           pattern: '^tint([0-9]|1[0-9]|2[0-9]|3[0-1])$'
         - description: Bus error interrupt
@@ -75,6 +77,8 @@ properties:
           const: ec7tie2-1
         - description: ECCRAM1 error overflow interrupt
           const: ec7tiovf-1
+        - description: Integrated GPT Error interrupt
+          pattern: '^ovfunf([0-7])$'
 
   clocks:
     maxItems: 2
@@ -106,6 +110,24 @@ required:
 allOf:
   - $ref: /schemas/interrupt-controller.yaml#
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - renesas,r9a07g043f-irqc
+              - renesas,r9a07g043u-irqc
+              - renesas,r9a07g044-irqc
+              - renesas,r9a07g054-irqc
+    then:
+      properties:
+        interrupts:
+          minItems: 48
+          maxItems: 48
+        interrupt-names:
+          minItems: 48
+          maxItems: 48
+
   - if:
       properties:
         compatible:
@@ -118,12 +140,19 @@ allOf:
           maxItems: 45
         interrupt-names:
           maxItems: 45
-    else:
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - renesas,r9a08g046-irqc
+    then:
       properties:
         interrupts:
-          minItems: 48
+          minItems: 61
         interrupt-names:
-          minItems: 48
+          minItems: 61
 
 unevaluatedProperties: false
 
-- 
2.43.0


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 03/15] irqchip/renesas-rzg2l: Drop redundant IRQC_TINT_START check in rzg2l_irqc_alloc()
  2026-03-22 12:23 [PATCH v6 00/15] Add RZ/G3L IRQC support Biju
  2026-03-22 12:23 ` [PATCH v6 01/15] dt-bindings: interrupt-controller: renesas,rzg2l-irqc: Use pattern for interrupt-names Biju
  2026-03-22 12:23 ` [PATCH v6 02/15] dt-bindings: interrupt-controller: renesas,rzg2l-irqc: Document RZ/G3L SoC Biju
@ 2026-03-22 12:23 ` Biju
  2026-03-23 11:58   ` Biju Das
  2026-03-22 12:23 ` [PATCH v6 04/15] irqchip/renesas-rzg2l: Replace single irq_chip with per-region irq_chip instances Biju
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 22+ messages in thread
From: Biju @ 2026-03-22 12:23 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 check `hwirq < IRQC_TINT_START` in rzg2l_irqc_alloc() is unnecessary
as the condition is already guaranteed to be false at that point in the
code. The outer `if (hwirq > IRQC_IRQ_COUNT)` block ensures that hwirq
is always above IRQC_IRQ_COUNT before reaching this check, and since
IRQC_TINT_START <= IRQC_IRQ_COUNT, the guard can never trigger.

Remove the dead code to simplify the allocation path.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v5->v6:
 * No change.
v5:
 * New patch.
---
 drivers/irqchip/irq-renesas-rzg2l.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index e73d426cea6d..ed8044b0a339 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -491,9 +491,6 @@ 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);
-
-		if (hwirq < IRQC_TINT_START)
-			return -EINVAL;
 	}
 
 	if (hwirq > (IRQC_NUM_IRQ - 1))
-- 
2.43.0


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 04/15] irqchip/renesas-rzg2l: Replace single irq_chip with per-region irq_chip instances
  2026-03-22 12:23 [PATCH v6 00/15] Add RZ/G3L IRQC support Biju
                   ` (2 preceding siblings ...)
  2026-03-22 12:23 ` [PATCH v6 03/15] irqchip/renesas-rzg2l: Drop redundant IRQC_TINT_START check in rzg2l_irqc_alloc() Biju
@ 2026-03-22 12:23 ` Biju
  2026-03-22 12:23 ` [PATCH v6 05/15] irqchip/renesas-rzg2l: Split EOI handler into separate IRQ and TINT functions Biju
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Biju @ 2026-03-22 12:23 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 driver previously used 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 <biju.das.jz@bp.renesas.com>
---
v5->v6:
 * No change.
v5:
 * New patch.
---
 drivers/irqchip/irq-renesas-rzg2l.c | 61 ++++++++++++++++++++++++-----
 1 file changed, 51 insertions(+), 10 deletions(-)

diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index ed8044b0a339..a0f03f81d5ef 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)
-- 
2.43.0


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 05/15] irqchip/renesas-rzg2l: Split EOI handler into separate IRQ and TINT functions
  2026-03-22 12:23 [PATCH v6 00/15] Add RZ/G3L IRQC support Biju
                   ` (3 preceding siblings ...)
  2026-03-22 12:23 ` [PATCH v6 04/15] irqchip/renesas-rzg2l: Replace single irq_chip with per-region irq_chip instances Biju
@ 2026-03-22 12:23 ` Biju
  2026-03-22 12:23 ` [PATCH v6 06/15] irqchip/renesas-rzg2l: Split set_type " Biju
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Biju @ 2026-03-22 12:23 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 single rzg2l_irqc_eoi() handler used a conditional to determine
whether to clear an IRQ or TINT interrupt. Split this into two dedicated
handlers, rzg2l_irqc_irq_eoi() and rzg2l_irqc_tint_eoi(), each handling
only their respective interrupt type without the need for range checks.

While at it, simplify rzg2l_irqc_{irq,tint}_eoi() by replacing
raw_spin_lock locking/unlocking with scoped_guard().

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v5->v6:
 * Simplified rzg2l_irqc_{irq,tint}_eoi() by replacing raw_spin_lock
   locking/unlocking with scoped_guard().
 * Updated commit description.
v5:
 * New patch.
---
 drivers/irqchip/irq-renesas-rzg2l.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index a0f03f81d5ef..0683559c31bf 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -130,17 +130,25 @@ static void rzg2l_clear_tint_int(struct rzg2l_irqc_priv *priv, unsigned int hwir
 	}
 }
 
-static void rzg2l_irqc_eoi(struct irq_data *d)
+static void rzg2l_irqc_irq_eoi(struct irq_data *d)
 {
 	struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
 	unsigned int hw_irq = irqd_to_hwirq(d);
 
-	raw_spin_lock(&priv->lock);
-	if (hw_irq >= IRQC_IRQ_START && hw_irq <= IRQC_IRQ_COUNT)
+	scoped_guard(raw_spinlock, &priv->lock)
 		rzg2l_clear_irq_int(priv, hw_irq);
-	else if (hw_irq >= IRQC_TINT_START && hw_irq < IRQC_NUM_IRQ)
+
+	irq_chip_eoi_parent(d);
+}
+
+static void rzg2l_irqc_tint_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_tint_int(priv, hw_irq);
-	raw_spin_unlock(&priv->lock);
+
 	irq_chip_eoi_parent(d);
 }
 
@@ -438,7 +446,7 @@ static struct syscore rzg2l_irqc_syscore = {
 
 static const struct irq_chip rzg2l_irqc_irq_chip = {
 	.name			= "rzg2l-irqc",
-	.irq_eoi		= rzg2l_irqc_eoi,
+	.irq_eoi		= rzg2l_irqc_irq_eoi,
 	.irq_mask		= irq_chip_mask_parent,
 	.irq_unmask		= irq_chip_unmask_parent,
 	.irq_disable		= rzg2l_irqc_irq_disable,
@@ -455,7 +463,7 @@ static const struct irq_chip rzg2l_irqc_irq_chip = {
 
 static const struct irq_chip rzg2l_irqc_tint_chip = {
 	.name			= "rzg2l-irqc",
-	.irq_eoi		= rzg2l_irqc_eoi,
+	.irq_eoi		= rzg2l_irqc_tint_eoi,
 	.irq_mask		= irq_chip_mask_parent,
 	.irq_unmask		= irq_chip_unmask_parent,
 	.irq_disable		= rzg2l_irqc_irq_disable,
@@ -472,7 +480,7 @@ static const struct irq_chip rzg2l_irqc_tint_chip = {
 
 static const struct irq_chip rzfive_irqc_irq_chip = {
 	.name			= "rzfive-irqc",
-	.irq_eoi		= rzg2l_irqc_eoi,
+	.irq_eoi		= rzg2l_irqc_irq_eoi,
 	.irq_mask		= rzfive_irqc_mask,
 	.irq_unmask		= rzfive_irqc_unmask,
 	.irq_disable		= rzfive_irqc_irq_disable,
@@ -489,7 +497,7 @@ static const struct irq_chip rzfive_irqc_irq_chip = {
 
 static const struct irq_chip rzfive_irqc_tint_chip = {
 	.name			= "rzfive-irqc",
-	.irq_eoi		= rzg2l_irqc_eoi,
+	.irq_eoi		= rzg2l_irqc_tint_eoi,
 	.irq_mask		= rzfive_irqc_mask,
 	.irq_unmask		= rzfive_irqc_unmask,
 	.irq_disable		= rzfive_irqc_irq_disable,
-- 
2.43.0


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 06/15] irqchip/renesas-rzg2l: Split set_type handler into separate IRQ and TINT functions
  2026-03-22 12:23 [PATCH v6 00/15] Add RZ/G3L IRQC support Biju
                   ` (4 preceding siblings ...)
  2026-03-22 12:23 ` [PATCH v6 05/15] irqchip/renesas-rzg2l: Split EOI handler into separate IRQ and TINT functions Biju
@ 2026-03-22 12:23 ` Biju
  2026-03-22 12:23 ` [PATCH v6 07/15] irqchip/renesas-rzg2l: Replace rzg2l_irqc_irq_{enable,disable} with TINT-specific handlers Biju
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Biju @ 2026-03-22 12:23 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 single rzg2l_irqc_set_type() handler used hw_irq range checks to
dispatch to either rzg2l_irq_set_type() or rzg2l_tint_set_edge(). Split
this into two dedicated handlers, rzg2l_irqc_irq_set_type() and
rzg2l_irqc_tint_set_type(), each calling only their respective type
configuration function without runtime conditionals.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v5->v6:
 * No change.
v5:
 * New patch.
---
 drivers/irqchip/irq-renesas-rzg2l.c | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index 0683559c31bf..84dded4beae6 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -393,15 +393,22 @@ static int rzg2l_tint_set_edge(struct irq_data *d, unsigned int type)
 	return 0;
 }
 
-static int rzg2l_irqc_set_type(struct irq_data *d, unsigned int type)
+static int rzg2l_irqc_irq_set_type(struct irq_data *d, unsigned int type)
 {
-	unsigned int hw_irq = irqd_to_hwirq(d);
-	int ret = -EINVAL;
+	int ret;
+
+	ret = rzg2l_irq_set_type(d, type);
+	if (ret)
+		return ret;
+
+	return irq_chip_set_type_parent(d, IRQ_TYPE_LEVEL_HIGH);
+}
+
+static int rzg2l_irqc_tint_set_type(struct irq_data *d, unsigned int type)
+{
+	int ret;
 
-	if (hw_irq >= IRQC_IRQ_START && hw_irq <= IRQC_IRQ_COUNT)
-		ret = rzg2l_irq_set_type(d, type);
-	else if (hw_irq >= IRQC_TINT_START && hw_irq < IRQC_NUM_IRQ)
-		ret = rzg2l_tint_set_edge(d, type);
+	ret = rzg2l_tint_set_edge(d, type);
 	if (ret)
 		return ret;
 
@@ -454,7 +461,7 @@ static const struct irq_chip rzg2l_irqc_irq_chip = {
 	.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_type		= rzg2l_irqc_irq_set_type,
 	.irq_set_affinity	= irq_chip_set_affinity_parent,
 	.flags			= IRQCHIP_MASK_ON_SUSPEND |
 				  IRQCHIP_SET_TYPE_MASKED |
@@ -471,7 +478,7 @@ static const struct irq_chip rzg2l_irqc_tint_chip = {
 	.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_type		= rzg2l_irqc_tint_set_type,
 	.irq_set_affinity	= irq_chip_set_affinity_parent,
 	.flags			= IRQCHIP_MASK_ON_SUSPEND |
 				  IRQCHIP_SET_TYPE_MASKED |
@@ -488,7 +495,7 @@ static const struct irq_chip rzfive_irqc_irq_chip = {
 	.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_type		= rzg2l_irqc_irq_set_type,
 	.irq_set_affinity	= irq_chip_set_affinity_parent,
 	.flags			= IRQCHIP_MASK_ON_SUSPEND |
 				  IRQCHIP_SET_TYPE_MASKED |
@@ -505,7 +512,7 @@ static const struct irq_chip rzfive_irqc_tint_chip = {
 	.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_type		= rzg2l_irqc_tint_set_type,
 	.irq_set_affinity	= irq_chip_set_affinity_parent,
 	.flags			= IRQCHIP_MASK_ON_SUSPEND |
 				  IRQCHIP_SET_TYPE_MASKED |
-- 
2.43.0


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 07/15] irqchip/renesas-rzg2l: Replace rzg2l_irqc_irq_{enable,disable} with TINT-specific handlers
  2026-03-22 12:23 [PATCH v6 00/15] Add RZ/G3L IRQC support Biju
                   ` (5 preceding siblings ...)
  2026-03-22 12:23 ` [PATCH v6 06/15] irqchip/renesas-rzg2l: Split set_type " Biju
@ 2026-03-22 12:23 ` Biju
  2026-03-22 12:23 ` [PATCH v6 08/15] irqchip/renesas-rzg2l: Split rzfive_tint_irq_endisable() into separate IRQ and TINT helpers Biju
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Biju @ 2026-03-22 12:23 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>

rzg2l_irqc_irq_disable() and rzg2l_irqc_irq_enable() were used by both
the IRQ and TINT chips, but only performed TINT-specific work via
rzg2l_tint_irq_endisable(), guarded by a hw_irq range check. Since the
IRQ chip does not require this extra enable/disable handling, replace its
callbacks with the generic irq_chip_disable_parent() and
irq_chip_enable_parent() directly.

While at it, simplify rzfive_irqc_irq_enable() by replacing raw_spin_lock
locking/unlocking with guard() and update the variable type of offset,
tssr_offset, and tssr_index to unsigned int, as these variables are used
only for calculation.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v5->v6:
 * Updated the variable type of offset, tssr_offset, and tssr_index to
   unsigned int, in rzfive_irqc_irq_enable() as these variables are used
   only for calculation.
 * Simplified rzfive_irqc_irq_enable() by replacing raw_spin_lock
   locking/unlocking with guard().
 * Updated commit description.
v5:
 * New patch.
---
 drivers/irqchip/irq-renesas-rzg2l.c | 40 +++++++++++++----------------
 1 file changed, 18 insertions(+), 22 deletions(-)

diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index 84dded4beae6..78cf451c8798 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -259,33 +259,29 @@ static void rzfive_irqc_irq_enable(struct irq_data *d)
 
 static void rzg2l_tint_irq_endisable(struct irq_data *d, bool enable)
 {
+	struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
 	unsigned int hw_irq = irqd_to_hwirq(d);
+	unsigned int offset = hw_irq - IRQC_TINT_START;
+	unsigned int tssr_offset = TSSR_OFFSET(offset);
+	unsigned int tssr_index = TSSR_INDEX(offset);
+	u32 reg;
 
-	if (hw_irq >= IRQC_TINT_START && hw_irq < IRQC_NUM_IRQ) {
-		struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
-		u32 offset = hw_irq - IRQC_TINT_START;
-		u32 tssr_offset = TSSR_OFFSET(offset);
-		u8 tssr_index = TSSR_INDEX(offset);
-		u32 reg;
-
-		raw_spin_lock(&priv->lock);
-		reg = readl_relaxed(priv->base + TSSR(tssr_index));
-		if (enable)
-			reg |= TIEN << TSSEL_SHIFT(tssr_offset);
-		else
-			reg &= ~(TIEN << TSSEL_SHIFT(tssr_offset));
-		writel_relaxed(reg, priv->base + TSSR(tssr_index));
-		raw_spin_unlock(&priv->lock);
-	}
+	guard(raw_spinlock)(&priv->lock);
+	reg = readl_relaxed(priv->base + TSSR(tssr_index));
+	if (enable)
+		reg |= TIEN << TSSEL_SHIFT(tssr_offset);
+	else
+		reg &= ~(TIEN << TSSEL_SHIFT(tssr_offset));
+	writel_relaxed(reg, priv->base + TSSR(tssr_index));
 }
 
-static void rzg2l_irqc_irq_disable(struct irq_data *d)
+static void rzg2l_irqc_tint_disable(struct irq_data *d)
 {
 	irq_chip_disable_parent(d);
 	rzg2l_tint_irq_endisable(d, false);
 }
 
-static void rzg2l_irqc_irq_enable(struct irq_data *d)
+static void rzg2l_irqc_tint_enable(struct irq_data *d)
 {
 	rzg2l_tint_irq_endisable(d, true);
 	irq_chip_enable_parent(d);
@@ -456,8 +452,8 @@ static const struct irq_chip rzg2l_irqc_irq_chip = {
 	.irq_eoi		= rzg2l_irqc_irq_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_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,
@@ -473,8 +469,8 @@ static const struct irq_chip rzg2l_irqc_tint_chip = {
 	.irq_eoi		= rzg2l_irqc_tint_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_disable		= rzg2l_irqc_tint_disable,
+	.irq_enable		= rzg2l_irqc_tint_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,
-- 
2.43.0


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 08/15] irqchip/renesas-rzg2l: Split rzfive_tint_irq_endisable() into separate IRQ and TINT helpers
  2026-03-22 12:23 [PATCH v6 00/15] Add RZ/G3L IRQC support Biju
                   ` (6 preceding siblings ...)
  2026-03-22 12:23 ` [PATCH v6 07/15] irqchip/renesas-rzg2l: Replace rzg2l_irqc_irq_{enable,disable} with TINT-specific handlers Biju
@ 2026-03-22 12:23 ` Biju
  2026-03-22 12:23 ` [PATCH v6 09/15] irqchip/renesas-rzg2l: Split rzfive_irqc_{mask,unmask} into separate IRQ and TINT handlers Biju
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Biju @ 2026-03-22 12:23 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>

rzfive_tint_irq_endisable() handled both IRQ and TINT enable/disable
paths via a hw_irq range check. Split this into two dedicated helpers,
rzfive_irq_endisable() for IRQ interrupts and rzfive_tint_endisable()
for TINT interrupts, each operating unconditionally on their respective
interrupt type.

While at it, simplify rzfive_{irq,tint}_endisable by replacing
raw_spin_lock locking/unlocking with guard() and update the variable type
of offset, tssr_offset, and tssr_index to unsigned int, as these variables
are used only for calculation.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v5->v6:
 * Simplified rzfive_{irq,tint}_endisable by replacing raw_spin_lock
   locking/unlocking with guard().
 * Updated the variable type of offset, tssr_offset, and tssr_index to
   unsigned int, in rzfive_tint_endisable() as these variables are used
   only for calculation.
 * Dropped stray newline in rzfive_tint_endisable().
 * Updated commit description.
v5:
 * New patch.
---
 drivers/irqchip/irq-renesas-rzg2l.c | 75 +++++++++++++++++------------
 1 file changed, 44 insertions(+), 31 deletions(-)

diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index 78cf451c8798..71bde07675d9 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -212,48 +212,61 @@ static void rzfive_irqc_unmask(struct irq_data *d)
 	irq_chip_unmask_parent(d);
 }
 
-static void rzfive_tint_irq_endisable(struct irq_data *d, bool enable)
+static void rzfive_irq_endisable(struct irq_data *d, bool enable)
 {
 	struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
 	unsigned int hwirq = irqd_to_hwirq(d);
 
-	if (hwirq >= IRQC_TINT_START && hwirq < IRQC_NUM_IRQ) {
-		u32 offset = hwirq - IRQC_TINT_START;
-		u32 tssr_offset = TSSR_OFFSET(offset);
-		u8 tssr_index = TSSR_INDEX(offset);
-		u32 reg;
-
-		raw_spin_lock(&priv->lock);
-		if (enable)
-			rzfive_irqc_unmask_tint_interrupt(priv, hwirq);
-		else
-			rzfive_irqc_mask_tint_interrupt(priv, hwirq);
-		reg = readl_relaxed(priv->base + TSSR(tssr_index));
-		if (enable)
-			reg |= TIEN << TSSEL_SHIFT(tssr_offset);
-		else
-			reg &= ~(TIEN << TSSEL_SHIFT(tssr_offset));
-		writel_relaxed(reg, priv->base + TSSR(tssr_index));
-		raw_spin_unlock(&priv->lock);
-	} else {
-		raw_spin_lock(&priv->lock);
-		if (enable)
-			rzfive_irqc_unmask_irq_interrupt(priv, hwirq);
-		else
-			rzfive_irqc_mask_irq_interrupt(priv, hwirq);
-		raw_spin_unlock(&priv->lock);
-	}
+	guard(raw_spinlock)(&priv->lock);
+	if (enable)
+		rzfive_irqc_unmask_irq_interrupt(priv, hwirq);
+	else
+		rzfive_irqc_mask_irq_interrupt(priv, hwirq);
+}
+
+static void rzfive_tint_endisable(struct irq_data *d, bool enable)
+{
+	struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
+	unsigned int hwirq = irqd_to_hwirq(d);
+	unsigned int offset = hwirq - IRQC_TINT_START;
+	unsigned int tssr_offset = TSSR_OFFSET(offset);
+	unsigned int tssr_index = TSSR_INDEX(offset);
+	u32 reg;
+
+	guard(raw_spinlock)(&priv->lock);
+	if (enable)
+		rzfive_irqc_unmask_tint_interrupt(priv, hwirq);
+	else
+		rzfive_irqc_mask_tint_interrupt(priv, hwirq);
+	reg = readl_relaxed(priv->base + TSSR(tssr_index));
+	if (enable)
+		reg |= TIEN << TSSEL_SHIFT(tssr_offset);
+	else
+		reg &= ~(TIEN << TSSEL_SHIFT(tssr_offset));
+	writel_relaxed(reg, priv->base + TSSR(tssr_index));
 }
 
 static void rzfive_irqc_irq_disable(struct irq_data *d)
 {
 	irq_chip_disable_parent(d);
-	rzfive_tint_irq_endisable(d, false);
+	rzfive_irq_endisable(d, false);
 }
 
 static void rzfive_irqc_irq_enable(struct irq_data *d)
 {
-	rzfive_tint_irq_endisable(d, true);
+	rzfive_irq_endisable(d, true);
+	irq_chip_enable_parent(d);
+}
+
+static void rzfive_irqc_tint_disable(struct irq_data *d)
+{
+	irq_chip_disable_parent(d);
+	rzfive_tint_endisable(d, false);
+}
+
+static void rzfive_irqc_tint_enable(struct irq_data *d)
+{
+	rzfive_tint_endisable(d, true);
 	irq_chip_enable_parent(d);
 }
 
@@ -503,8 +516,8 @@ static const struct irq_chip rzfive_irqc_tint_chip = {
 	.irq_eoi		= rzg2l_irqc_tint_eoi,
 	.irq_mask		= rzfive_irqc_mask,
 	.irq_unmask		= rzfive_irqc_unmask,
-	.irq_disable		= rzfive_irqc_irq_disable,
-	.irq_enable		= rzfive_irqc_irq_enable,
+	.irq_disable		= rzfive_irqc_tint_disable,
+	.irq_enable		= rzfive_irqc_tint_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,
-- 
2.43.0


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 09/15] irqchip/renesas-rzg2l: Split rzfive_irqc_{mask,unmask} into separate IRQ and TINT handlers
  2026-03-22 12:23 [PATCH v6 00/15] Add RZ/G3L IRQC support Biju
                   ` (7 preceding siblings ...)
  2026-03-22 12:23 ` [PATCH v6 08/15] irqchip/renesas-rzg2l: Split rzfive_tint_irq_endisable() into separate IRQ and TINT helpers Biju
@ 2026-03-22 12:23 ` Biju
  2026-03-22 12:23 ` [PATCH v6 10/15] irqchip/renesas-rzg2l: Dynamically allocate fwspec array Biju
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Biju @ 2026-03-22 12:23 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>

rzfive_irqc_mask() and rzfive_irqc_unmask() used hw_irq range checks to
dispatch between IRQ and TINT masking operations. Split each into two
dedicated handlers — rzfive_irqc_irq_mask(), rzfive_irqc_tint_mask(),
rzfive_irqc_irq_unmask(), and rzfive_irqc_tint_unmask() — each
operating unconditionally on its respective interrupt type, removing
the runtime conditionals.

Assign the IRQ-specific handlers to rzfive_irqc_irq_chip and the
TINT-specific handlers to rzfive_irqc_tint_chip, consistent with the
separation applied to the EOI, set_type, and enable/disable callbacks in
previous patches.

While at it, simplify rzfive_irqc_{irq,tint}_{mask,unmask}() by replacing
raw_spin_lock locking/unlocking with scoped_guard().

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v5->v6:
 * Updated commit description.
 * Simplified rzfive_irqc_{irq,tint}_{mask,unmask}() by replacing
   raw_spin_lock locking/unlocking with scoped_guard().
v5:
 * New patch.
---
 drivers/irqchip/irq-renesas-rzg2l.c | 44 ++++++++++++++++++++---------
 1 file changed, 30 insertions(+), 14 deletions(-)

diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index 71bde07675d9..0b1bad002653 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -184,31 +184,47 @@ static void rzfive_irqc_unmask_tint_interrupt(struct rzg2l_irqc_priv *priv,
 	writel_relaxed(readl_relaxed(priv->base + TMSK) & ~bit, priv->base + TMSK);
 }
 
-static void rzfive_irqc_mask(struct irq_data *d)
+static void rzfive_irqc_irq_mask(struct irq_data *d)
 {
 	struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
 	unsigned int hwirq = irqd_to_hwirq(d);
 
-	raw_spin_lock(&priv->lock);
-	if (hwirq >= IRQC_IRQ_START && hwirq <= IRQC_IRQ_COUNT)
+	scoped_guard(raw_spinlock, &priv->lock)
 		rzfive_irqc_mask_irq_interrupt(priv, hwirq);
-	else if (hwirq >= IRQC_TINT_START && hwirq < IRQC_NUM_IRQ)
+
+	irq_chip_mask_parent(d);
+}
+
+static void rzfive_irqc_tint_mask(struct irq_data *d)
+{
+	struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
+	unsigned int hwirq = irqd_to_hwirq(d);
+
+	scoped_guard(raw_spinlock, &priv->lock)
 		rzfive_irqc_mask_tint_interrupt(priv, hwirq);
-	raw_spin_unlock(&priv->lock);
+
 	irq_chip_mask_parent(d);
 }
 
-static void rzfive_irqc_unmask(struct irq_data *d)
+static void rzfive_irqc_irq_unmask(struct irq_data *d)
 {
 	struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
 	unsigned int hwirq = irqd_to_hwirq(d);
 
-	raw_spin_lock(&priv->lock);
-	if (hwirq >= IRQC_IRQ_START && hwirq <= IRQC_IRQ_COUNT)
+	scoped_guard(raw_spinlock, &priv->lock)
 		rzfive_irqc_unmask_irq_interrupt(priv, hwirq);
-	else if (hwirq >= IRQC_TINT_START && hwirq < IRQC_NUM_IRQ)
+
+	irq_chip_unmask_parent(d);
+}
+
+static void rzfive_irqc_tint_unmask(struct irq_data *d)
+{
+	struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
+	unsigned int hwirq = irqd_to_hwirq(d);
+
+	scoped_guard(raw_spinlock, &priv->lock)
 		rzfive_irqc_unmask_tint_interrupt(priv, hwirq);
-	raw_spin_unlock(&priv->lock);
+
 	irq_chip_unmask_parent(d);
 }
 
@@ -497,8 +513,8 @@ static const struct irq_chip rzg2l_irqc_tint_chip = {
 static const struct irq_chip rzfive_irqc_irq_chip = {
 	.name			= "rzfive-irqc",
 	.irq_eoi		= rzg2l_irqc_irq_eoi,
-	.irq_mask		= rzfive_irqc_mask,
-	.irq_unmask		= rzfive_irqc_unmask,
+	.irq_mask		= rzfive_irqc_irq_mask,
+	.irq_unmask		= rzfive_irqc_irq_unmask,
 	.irq_disable		= rzfive_irqc_irq_disable,
 	.irq_enable		= rzfive_irqc_irq_enable,
 	.irq_get_irqchip_state	= irq_chip_get_parent_state,
@@ -514,8 +530,8 @@ static const struct irq_chip rzfive_irqc_irq_chip = {
 static const struct irq_chip rzfive_irqc_tint_chip = {
 	.name			= "rzfive-irqc",
 	.irq_eoi		= rzg2l_irqc_tint_eoi,
-	.irq_mask		= rzfive_irqc_mask,
-	.irq_unmask		= rzfive_irqc_unmask,
+	.irq_mask		= rzfive_irqc_tint_mask,
+	.irq_unmask		= rzfive_irqc_tint_unmask,
 	.irq_disable		= rzfive_irqc_tint_disable,
 	.irq_enable		= rzfive_irqc_tint_enable,
 	.irq_get_irqchip_state	= irq_chip_get_parent_state,
-- 
2.43.0


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 10/15] irqchip/renesas-rzg2l: Dynamically allocate fwspec array
  2026-03-22 12:23 [PATCH v6 00/15] Add RZ/G3L IRQC support Biju
                   ` (8 preceding siblings ...)
  2026-03-22 12:23 ` [PATCH v6 09/15] irqchip/renesas-rzg2l: Split rzfive_irqc_{mask,unmask} into separate IRQ and TINT handlers Biju
@ 2026-03-22 12:23 ` Biju
  2026-03-22 12:23 ` [PATCH v6 11/15] irqchip/renesas-rzg2l: Drop IRQC_NUM_IRQ macro Biju
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Biju @ 2026-03-22 12:23 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 total number of interrupts in RZ/G2L and RZ/G3L SoC are different. The
RZ/G3L has 16 external interrupts whereas RZ/G2L has only 8 external
interrupts. Dynamically allocate fwspec memory instead of static
allocation to support both SoCs.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v5->v6:
 * No change.
v4->v5:
 * No change.
v3->v4:
 * Updated commit header
 * Replaced IRQs->interrupts in commit description
 * Fixed the typo Dynamicaly->Dynamically
v2->v3:
 * No change
v1->v2:
 * No change
---
 drivers/irqchip/irq-renesas-rzg2l.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index 0b1bad002653..cf0d45c40083 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -81,7 +81,7 @@ static struct rzg2l_irqc_priv {
 	void __iomem			*base;
 	const struct irq_chip		*irq_chip;
 	const struct irq_chip		*tint_chip;
-	struct irq_fwspec		fwspec[IRQC_NUM_IRQ];
+	struct irq_fwspec		*fwspec;
 	raw_spinlock_t			lock;
 	struct rzg2l_irqc_reg_cache	cache;
 } *rzg2l_irqc_data;
@@ -632,6 +632,11 @@ static int rzg2l_irqc_common_probe(struct platform_device *pdev, struct device_n
 	if (IS_ERR(rzg2l_irqc_data->base))
 		return PTR_ERR(rzg2l_irqc_data->base);
 
+	rzg2l_irqc_data->fwspec = devm_kcalloc(&pdev->dev, IRQC_NUM_IRQ,
+					       sizeof(*rzg2l_irqc_data->fwspec), GFP_KERNEL);
+	if (!rzg2l_irqc_data->fwspec)
+		return -ENOMEM;
+
 	ret = rzg2l_irqc_parse_interrupts(rzg2l_irqc_data, node);
 	if (ret)
 		return dev_err_probe(dev, ret, "cannot parse interrupts: %d\n", ret);
-- 
2.43.0


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 11/15] irqchip/renesas-rzg2l: Drop IRQC_NUM_IRQ macro
  2026-03-22 12:23 [PATCH v6 00/15] Add RZ/G3L IRQC support Biju
                   ` (9 preceding siblings ...)
  2026-03-22 12:23 ` [PATCH v6 10/15] irqchip/renesas-rzg2l: Dynamically allocate fwspec array Biju
@ 2026-03-22 12:23 ` Biju
  2026-03-22 12:23 ` [PATCH v6 12/15] irqchip/renesas-rzg2l: Drop IRQC_TINT_START macro Biju
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Biju @ 2026-03-22 12:23 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 total number of interrupts in RZ/G2L and RZ/G3L SoC are different.
Introduce struct rzg2l_hw_info to handle the hardware differences and
replace the macro IRQC_NUM_IRQ with num_irq variable in struct
rzg2l_hw_info.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v5->v6:
 * No change.
v4->v5:
 * Dropped the hw_irq range check involving info.num_irq
v3->v4:
 * Updated commit description IRQs->interrupts
 * Replaced the variable type for num_irq in struct rzg2l_hw_info from
   u8->unsigned int
 * Replaced the pointer variable info from irqc_priv and instead embed a
   struct hwinfo into irqc_priv and copy the data into it at probe time.
 * Replaced the check 'hwirq > (priv->info->num_irq - 1)' with
   hwirq >= priv->info.num_irq
v2->v3:
 * No change
v1->v2:
 * No change
---
 drivers/irqchip/irq-renesas-rzg2l.c | 34 ++++++++++++++++++++++-------
 1 file changed, 26 insertions(+), 8 deletions(-)

diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index cf0d45c40083..5a21bca91e4e 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -24,7 +24,6 @@
 #define IRQC_IRQ_COUNT			8
 #define IRQC_TINT_START			(IRQC_IRQ_START + IRQC_IRQ_COUNT)
 #define IRQC_TINT_COUNT			32
-#define IRQC_NUM_IRQ			(IRQC_TINT_START + IRQC_TINT_COUNT)
 
 #define ISCR				0x10
 #define IITSR				0x14
@@ -68,6 +67,14 @@ struct rzg2l_irqc_reg_cache {
 	u32	titsr[2];
 };
 
+/**
+ * struct rzg2l_hw_info - Interrupt Control Unit controller hardware info structure.
+ * @num_irq:		Total Number of interrupts
+ */
+struct rzg2l_hw_info {
+	unsigned int	num_irq;
+};
+
 /**
  * struct rzg2l_irqc_priv - IRQ controller private data structure
  * @base:	Controller's base address
@@ -75,6 +82,7 @@ struct rzg2l_irqc_reg_cache {
  * @tint_chip:	Pointer to struct irq_chip for tint
  * @fwspec:	IRQ firmware specific data
  * @lock:	Lock to serialize access to hardware registers
+ * @info:	Hardware specific data
  * @cache:	Registers cache for suspend/resume
  */
 static struct rzg2l_irqc_priv {
@@ -83,6 +91,7 @@ static struct rzg2l_irqc_priv {
 	const struct irq_chip		*tint_chip;
 	struct irq_fwspec		*fwspec;
 	raw_spinlock_t			lock;
+	struct rzg2l_hw_info		info;
 	struct rzg2l_irqc_reg_cache	cache;
 } *rzg2l_irqc_data;
 
@@ -573,7 +582,7 @@ static int rzg2l_irqc_alloc(struct irq_domain *domain, unsigned int virq,
 		chip = priv->irq_chip;
 	}
 
-	if (hwirq > (IRQC_NUM_IRQ - 1))
+	if (hwirq >= priv->info.num_irq)
 		return -EINVAL;
 
 	ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, chip, (void *)(uintptr_t)tint);
@@ -596,7 +605,7 @@ static int rzg2l_irqc_parse_interrupts(struct rzg2l_irqc_priv *priv,
 	unsigned int i;
 	int ret;
 
-	for (i = 0; i < IRQC_NUM_IRQ; i++) {
+	for (i = 0; i < priv->info.num_irq; i++) {
 		ret = of_irq_parse_one(np, i, &map);
 		if (ret)
 			return ret;
@@ -609,7 +618,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 *tint_chip)
+				   const struct irq_chip *tint_chip,
+				   const struct rzg2l_hw_info info)
 {
 	struct irq_domain *irq_domain, *parent_domain;
 	struct device_node *node = pdev->dev.of_node;
@@ -632,7 +642,9 @@ static int rzg2l_irqc_common_probe(struct platform_device *pdev, struct device_n
 	if (IS_ERR(rzg2l_irqc_data->base))
 		return PTR_ERR(rzg2l_irqc_data->base);
 
-	rzg2l_irqc_data->fwspec = devm_kcalloc(&pdev->dev, IRQC_NUM_IRQ,
+	rzg2l_irqc_data->info = info;
+
+	rzg2l_irqc_data->fwspec = devm_kcalloc(&pdev->dev, info.num_irq,
 					       sizeof(*rzg2l_irqc_data->fwspec), GFP_KERNEL);
 	if (!rzg2l_irqc_data->fwspec)
 		return -ENOMEM;
@@ -657,7 +669,7 @@ static int rzg2l_irqc_common_probe(struct platform_device *pdev, struct device_n
 
 	raw_spin_lock_init(&rzg2l_irqc_data->lock);
 
-	irq_domain = irq_domain_create_hierarchy(parent_domain, 0, IRQC_NUM_IRQ, dev_fwnode(dev),
+	irq_domain = irq_domain_create_hierarchy(parent_domain, 0, info.num_irq, dev_fwnode(dev),
 						 &rzg2l_irqc_domain_ops, rzg2l_irqc_data);
 	if (!irq_domain) {
 		pm_runtime_put(dev);
@@ -669,14 +681,20 @@ static int rzg2l_irqc_common_probe(struct platform_device *pdev, struct device_n
 	return 0;
 }
 
+static const struct rzg2l_hw_info rzg2l_hw_params = {
+	.num_irq	= IRQC_IRQ_START + IRQC_IRQ_COUNT + IRQC_TINT_COUNT,
+};
+
 static int rzg2l_irqc_probe(struct platform_device *pdev, struct device_node *parent)
 {
-	return rzg2l_irqc_common_probe(pdev, parent, &rzg2l_irqc_irq_chip, &rzg2l_irqc_tint_chip);
+	return rzg2l_irqc_common_probe(pdev, parent, &rzg2l_irqc_irq_chip, &rzg2l_irqc_tint_chip,
+				       rzg2l_hw_params);
 }
 
 static int rzfive_irqc_probe(struct platform_device *pdev, struct device_node *parent)
 {
-	return rzg2l_irqc_common_probe(pdev, parent, &rzfive_irqc_irq_chip, &rzfive_irqc_tint_chip);
+	return rzg2l_irqc_common_probe(pdev, parent, &rzfive_irqc_irq_chip, &rzfive_irqc_tint_chip,
+				       rzg2l_hw_params);
 }
 
 IRQCHIP_PLATFORM_DRIVER_BEGIN(rzg2l_irqc)
-- 
2.43.0


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 12/15] irqchip/renesas-rzg2l: Drop IRQC_TINT_START macro
  2026-03-22 12:23 [PATCH v6 00/15] Add RZ/G3L IRQC support Biju
                   ` (10 preceding siblings ...)
  2026-03-22 12:23 ` [PATCH v6 11/15] irqchip/renesas-rzg2l: Drop IRQC_NUM_IRQ macro Biju
@ 2026-03-22 12:23 ` Biju
  2026-03-22 12:23 ` [PATCH v6 13/15] irqchip/renesas-rzg2l: Drop IRQC_IRQ_COUNT macro Biju
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Biju @ 2026-03-22 12:23 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 IRQC_TINT_START value is different for RZ/G3L and RZ/G2L SoC. Add
tint_start variable in struct rzg2l_hw_info to handle this difference
and drop the macro IRQC_TINT_START.

While at it, update the variable type of titseln, tssr_offset, tssr_index,
index, and sense to unsigned int, in rzg2l_tint_set_edge() as these
variables are used only for calculation.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v5->v6
 * Updated the variable type of titseln, tssr_offset, tssr_index, index,
   and sense to unsigned int, in rzg2l_tint_set_edge() as these variables
   are used only for calculation.
 * Updated commit description.
v4->v5:
 * Dropped the hw_irq range check involving info.tint_start
v3->v4:
 * Updated commit description 'this differences->this difference'.
 * Updated tint_start variable type from u8-> unsigned int.
v2->v3:
 * No change
v1->v2:
 * No change
---
 drivers/irqchip/irq-renesas-rzg2l.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index 5a21bca91e4e..922d9dfeddcd 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -22,7 +22,6 @@
 
 #define IRQC_IRQ_START			1
 #define IRQC_IRQ_COUNT			8
-#define IRQC_TINT_START			(IRQC_IRQ_START + IRQC_IRQ_COUNT)
 #define IRQC_TINT_COUNT			32
 
 #define ISCR				0x10
@@ -69,9 +68,11 @@ struct rzg2l_irqc_reg_cache {
 
 /**
  * struct rzg2l_hw_info - Interrupt Control Unit controller hardware info structure.
+ * @tint_start:		Start of TINT interrupts
  * @num_irq:		Total Number of interrupts
  */
 struct rzg2l_hw_info {
+	unsigned int	tint_start;
 	unsigned int	num_irq;
 };
 
@@ -125,7 +126,7 @@ static void rzg2l_clear_irq_int(struct rzg2l_irqc_priv *priv, unsigned int hwirq
 
 static void rzg2l_clear_tint_int(struct rzg2l_irqc_priv *priv, unsigned int hwirq)
 {
-	u32 bit = BIT(hwirq - IRQC_TINT_START);
+	u32 bit = BIT(hwirq - priv->info.tint_start);
 	u32 reg;
 
 	reg = readl_relaxed(priv->base + TSCR);
@@ -180,7 +181,7 @@ static void rzfive_irqc_unmask_irq_interrupt(struct rzg2l_irqc_priv *priv,
 static void rzfive_irqc_mask_tint_interrupt(struct rzg2l_irqc_priv *priv,
 					    unsigned int hwirq)
 {
-	u32 bit = BIT(hwirq - IRQC_TINT_START);
+	u32 bit = BIT(hwirq - priv->info.tint_start);
 
 	writel_relaxed(readl_relaxed(priv->base + TMSK) | bit, priv->base + TMSK);
 }
@@ -188,7 +189,7 @@ static void rzfive_irqc_mask_tint_interrupt(struct rzg2l_irqc_priv *priv,
 static void rzfive_irqc_unmask_tint_interrupt(struct rzg2l_irqc_priv *priv,
 					      unsigned int hwirq)
 {
-	u32 bit = BIT(hwirq - IRQC_TINT_START);
+	u32 bit = BIT(hwirq - priv->info.tint_start);
 
 	writel_relaxed(readl_relaxed(priv->base + TMSK) & ~bit, priv->base + TMSK);
 }
@@ -253,7 +254,7 @@ static void rzfive_tint_endisable(struct irq_data *d, bool enable)
 {
 	struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
 	unsigned int hwirq = irqd_to_hwirq(d);
-	unsigned int offset = hwirq - IRQC_TINT_START;
+	unsigned int offset = hwirq - priv->info.tint_start;
 	unsigned int tssr_offset = TSSR_OFFSET(offset);
 	unsigned int tssr_index = TSSR_INDEX(offset);
 	u32 reg;
@@ -299,7 +300,7 @@ static void rzg2l_tint_irq_endisable(struct irq_data *d, bool enable)
 {
 	struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
 	unsigned int hw_irq = irqd_to_hwirq(d);
-	unsigned int offset = hw_irq - IRQC_TINT_START;
+	unsigned int offset = hw_irq - priv->info.tint_start;
 	unsigned int tssr_offset = TSSR_OFFSET(offset);
 	unsigned int tssr_index = TSSR_INDEX(offset);
 	u32 reg;
@@ -388,10 +389,10 @@ static int rzg2l_tint_set_edge(struct irq_data *d, unsigned int type)
 {
 	struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
 	unsigned int hwirq = irqd_to_hwirq(d);
-	u32 titseln = hwirq - IRQC_TINT_START;
-	u32 tssr_offset = TSSR_OFFSET(titseln);
-	u8 tssr_index = TSSR_INDEX(titseln);
-	u8 index, sense;
+	unsigned int titseln = hwirq - priv->info.tint_start;
+	unsigned int tssr_offset = TSSR_OFFSET(titseln);
+	unsigned int tssr_index = TSSR_INDEX(titseln);
+	unsigned int index, sense;
 	u32 reg, tssr;
 
 	switch (type & IRQ_TYPE_SENSE_MASK) {
@@ -682,6 +683,7 @@ static int rzg2l_irqc_common_probe(struct platform_device *pdev, struct device_n
 }
 
 static const struct rzg2l_hw_info rzg2l_hw_params = {
+	.tint_start	= IRQC_IRQ_START + IRQC_IRQ_COUNT,
 	.num_irq	= IRQC_IRQ_START + IRQC_IRQ_COUNT + IRQC_TINT_COUNT,
 };
 
-- 
2.43.0


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 13/15] irqchip/renesas-rzg2l: Drop IRQC_IRQ_COUNT macro
  2026-03-22 12:23 [PATCH v6 00/15] Add RZ/G3L IRQC support Biju
                   ` (11 preceding siblings ...)
  2026-03-22 12:23 ` [PATCH v6 12/15] irqchip/renesas-rzg2l: Drop IRQC_TINT_START macro Biju
@ 2026-03-22 12:23 ` Biju
  2026-03-22 12:23 ` [PATCH v6 14/15] irqchip/renesas-rzg2l: Add RZ/G3L support Biju
  2026-03-22 12:23 ` [PATCH v6 15/15] irqchip/renesas-rzg2l: Add shared interrupt support Biju
  14 siblings, 0 replies; 22+ messages in thread
From: Biju @ 2026-03-22 12:23 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 total number of external interrupts in RZ/G2L and RZ/G3L SoC are
different. The RZ/G3L has 16 external interrupts whereas RZ/G2L has only 8
external interrupts. Add irq_count variable in struct rzg2l_hw_info to
handle these differences and drop the macro IRQC_IRQ_COUNT.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v5->v6:
 * No change
v4->v5:
 * Dropped hw_irq range check involving info.irq_count.
v3->v4:
 * Updated commit description IRQs->interrupts.
 * Updated variable type of irq_count from u8->unsigned int.
v2->v3:
 * No change
v1->v2:
 * No change
---
 drivers/irqchip/irq-renesas-rzg2l.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index 922d9dfeddcd..8aff8b9d49c9 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -21,7 +21,6 @@
 #include <linux/syscore_ops.h>
 
 #define IRQC_IRQ_START			1
-#define IRQC_IRQ_COUNT			8
 #define IRQC_TINT_COUNT			32
 
 #define ISCR				0x10
@@ -68,10 +67,12 @@ struct rzg2l_irqc_reg_cache {
 
 /**
  * struct rzg2l_hw_info - Interrupt Control Unit controller hardware info structure.
+ * @irq_count:		Number of IRQC interrupts
  * @tint_start:		Start of TINT interrupts
  * @num_irq:		Total Number of interrupts
  */
 struct rzg2l_hw_info {
+	unsigned int	irq_count;
 	unsigned int	tint_start;
 	unsigned int	num_irq;
 };
@@ -575,7 +576,7 @@ 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 > IRQC_IRQ_COUNT) {
+	if (hwirq > priv->info.irq_count) {
 		tint = TINT_EXTRACT_GPIOINT(hwirq);
 		hwirq = TINT_EXTRACT_HWIRQ(hwirq);
 		chip = priv->tint_chip;
@@ -683,8 +684,9 @@ static int rzg2l_irqc_common_probe(struct platform_device *pdev, struct device_n
 }
 
 static const struct rzg2l_hw_info rzg2l_hw_params = {
-	.tint_start	= IRQC_IRQ_START + IRQC_IRQ_COUNT,
-	.num_irq	= IRQC_IRQ_START + IRQC_IRQ_COUNT + IRQC_TINT_COUNT,
+	.irq_count	= 8,
+	.tint_start	= IRQC_IRQ_START + 8,
+	.num_irq	= IRQC_IRQ_START + 8 + IRQC_TINT_COUNT,
 };
 
 static int rzg2l_irqc_probe(struct platform_device *pdev, struct device_node *parent)
-- 
2.43.0


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 14/15] irqchip/renesas-rzg2l: Add RZ/G3L support
  2026-03-22 12:23 [PATCH v6 00/15] Add RZ/G3L IRQC support Biju
                   ` (12 preceding siblings ...)
  2026-03-22 12:23 ` [PATCH v6 13/15] irqchip/renesas-rzg2l: Drop IRQC_IRQ_COUNT macro Biju
@ 2026-03-22 12:23 ` Biju
  2026-03-23 11:36   ` Biju Das
  2026-03-22 12:23 ` [PATCH v6 15/15] irqchip/renesas-rzg2l: Add shared interrupt support Biju
  14 siblings, 1 reply; 22+ messages in thread
From: Biju @ 2026-03-22 12:23 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 IRQC block on the RZ/G3L SoC is almost identical to the one found on
the RZ/G2L SoC, with the following differences:

 - The number of GPIO interrupts for TINT selection is 113 instead of 123.
 - The pin index and TINT selection index are not in the 1:1 map.
 - The number of external interrupts are 16 instead of 8, out of these
   8 external interrupts are shared with TINT.

Add support for the RZ/G3L driver by filling the rzg2l_hw_info table and
adding LUT for mapping between pin index and TINT selection index.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v5->v6:
 * No change.
v4->v5:
 * Updated rzg3l_irqc_probe() for supporting separate interrupt chips.
v3->v4:
 * Updated commit description IRQs->interrupts.
 * Updated rzg2l_disable_tint_and_set_tint_source() for making
   tint assignment very clear in the code.
 * Formatted rzg3l_tssel_lut as table format.
v2->v3:
 * No change
v1->v2:
 * No change
---
 drivers/irqchip/irq-renesas-rzg2l.c | 44 +++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index 8aff8b9d49c9..1ff1c0efed66 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -67,11 +67,13 @@ struct rzg2l_irqc_reg_cache {
 
 /**
  * struct rzg2l_hw_info - Interrupt Control Unit controller hardware info structure.
+ * @tssel_lut:		TINT lookup table
  * @irq_count:		Number of IRQC interrupts
  * @tint_start:		Start of TINT interrupts
  * @num_irq:		Total Number of interrupts
  */
 struct rzg2l_hw_info {
+	const u8	*tssel_lut;
 	unsigned int	irq_count;
 	unsigned int	tint_start;
 	unsigned int	num_irq;
@@ -377,6 +379,11 @@ static u32 rzg2l_disable_tint_and_set_tint_source(struct irq_data *d, struct rzg
 	u32 tint = (u32)(uintptr_t)irq_data_get_irq_chip_data(d);
 	u32 tien = reg & (TIEN << TSSEL_SHIFT(tssr_offset));
 
+	if (priv->info.tssel_lut)
+		tint = priv->info.tssel_lut[tint];
+	else
+		tint = (u32)(uintptr_t)irq_data_get_irq_chip_data(d);
+
 	/* Clear the relevant byte in reg */
 	reg &= ~(TSSEL_MASK << TSSEL_SHIFT(tssr_offset));
 	/* Set TINT and leave TIEN clear */
@@ -683,6 +690,36 @@ static int rzg2l_irqc_common_probe(struct platform_device *pdev, struct device_n
 	return 0;
 }
 
+/* Mapping based on port index on Table 4.2-1 and GPIOINT on Table 4.6-7 */
+static const u8 rzg3l_tssel_lut[] = {
+	 83,  84,					/* P20-P21 */
+	  7,   8,   9,  10,  11,  12,  13,		/* P30-P36 */
+	 85,  86,  87,  88,  89,  90,  91,		/* P50-P56 */
+	 92,  93,  94,  95,  96,  97,  98,		/* P60-P66 */
+	 99, 100, 101, 102, 103, 104, 105, 106,		/* P70-P77 */
+	107, 108, 109, 110, 111, 112,			/* P80-P85 */
+	 45,  46,  47,  48,  49,  50,  51,  52,		/* PA0-PA7 */
+	 53,  54,  55,  56,  57,  58,  59,  60,		/* PB0-PB7 */
+	 61,  62,  63,					/* PC0-PC2 */
+	 64,  65,  66,  67,  68,  69,  70,  71,		/* PD0-PD7 */
+	 72,  73,  74,  75,  76,  77,  78,  79,		/* PE0-PE7 */
+	 80,  81,  82,					/* PF0-PF2 */
+	 27,  28,  29,  30,  31,  32,  33,  34,		/* PG0-PG7 */
+	 35,  36,  37,  38,  39,  40,			/* PH0-PH5 */
+	  2,   3,   4,   5,   6,			/* PJ0-PJ4 */
+	 41,  42,  43,  44,				/* PK0-PK3 */
+	 14,  15,  16,  17,  26,			/* PL0-PL4 */
+	 18,  19,  20,  21,  22,  23,  24,  25,		/* PM0-PM7 */
+	  0,   1					/* PS0-PS1 */
+};
+
+static const struct rzg2l_hw_info rzg3l_hw_params = {
+	.tssel_lut	= rzg3l_tssel_lut,
+	.irq_count	= 16,
+	.tint_start	= IRQC_IRQ_START + 16,
+	.num_irq	= IRQC_IRQ_START + 16 + IRQC_TINT_COUNT,
+};
+
 static const struct rzg2l_hw_info rzg2l_hw_params = {
 	.irq_count	= 8,
 	.tint_start	= IRQC_IRQ_START + 8,
@@ -695,6 +732,12 @@ static int rzg2l_irqc_probe(struct platform_device *pdev, struct device_node *pa
 				       rzg2l_hw_params);
 }
 
+static int rzg3l_irqc_probe(struct platform_device *pdev, struct device_node *parent)
+{
+	return rzg2l_irqc_common_probe(pdev, parent, &rzg2l_irqc_irq_chip, &rzg2l_irqc_tint_chip,
+				       rzg3l_hw_params);
+}
+
 static int rzfive_irqc_probe(struct platform_device *pdev, struct device_node *parent)
 {
 	return rzg2l_irqc_common_probe(pdev, parent, &rzfive_irqc_irq_chip, &rzfive_irqc_tint_chip,
@@ -703,6 +746,7 @@ static int rzfive_irqc_probe(struct platform_device *pdev, struct device_node *p
 
 IRQCHIP_PLATFORM_DRIVER_BEGIN(rzg2l_irqc)
 IRQCHIP_MATCH("renesas,rzg2l-irqc", rzg2l_irqc_probe)
+IRQCHIP_MATCH("renesas,r9a08g046-irqc", rzg3l_irqc_probe)
 IRQCHIP_MATCH("renesas,r9a07g043f-irqc", rzfive_irqc_probe)
 IRQCHIP_PLATFORM_DRIVER_END(rzg2l_irqc)
 MODULE_AUTHOR("Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>");
-- 
2.43.0


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 15/15] irqchip/renesas-rzg2l: Add shared interrupt support
  2026-03-22 12:23 [PATCH v6 00/15] Add RZ/G3L IRQC support Biju
                   ` (13 preceding siblings ...)
  2026-03-22 12:23 ` [PATCH v6 14/15] irqchip/renesas-rzg2l: Add RZ/G3L support Biju
@ 2026-03-22 12:23 ` Biju
  2026-03-23 11:34   ` Biju Das
  2026-03-25 18:00   ` kernel test robot
  14 siblings, 2 replies; 22+ messages in thread
From: Biju @ 2026-03-22 12:23 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 16 external interrupts, of which 8 are shared with
TINT (GPIO interrupts), whereas RZ/G2L has only 8 external interrupts
with no sharing. The shared interrupt line selection between external
interrupt and GPIO interrupt is based on the INTTSEL register. Add
shared_irq_cnt variable to struct rzg2l_hw_info handle these differences.

Add used_irqs bitmap to struct rzg2l_irqc_priv to track allocation state.
In the alloc callback, use test_and_set_bit() to enforce mutual exclusion
and configure the INTTSEL register to route to either the external
interrupt or TINT. In the free callback, use test_and_clear_bit() to
release the shared interrupt line and reset the INTTSEL. Also add INTTSEL
register save/restore support to the suspend/resume path.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v5->v6:
 * Updated commit description.
 * Switched to using irq_domain_ops::{alloc,free} callbacks for mutual
   exclusion between external interrupts and GPIO interrupts as using
   irq_{request,release}_resources() leading to irq storm()
 * Dropped irq_{request,release}_resources().
 * Replaced the macro TINTSEL->INTTSEL_TINTSEL
 * Added macros INTTSEL_TINTSEL_START, IRQC_SHARED_IRQ_COUNT and
   IRQC_IRQ_SHARED_START.
 * Added used_irqs bitmap to struct rzg2l_irqc_priv to track allocation
   state of shared_interrupt
 * Added rzg2l_irqc_set_inttsel() for configuring INTTSEL register.
 * Replaced irq_domain_free_irqs_common()->rzg2l_irqc_free() as 
   rzg2l_irqc_domain_ops::free() callback.
 * Replaced the 8->IRQC_SHARED_IRQ_COUNT in shared_irq_cnt varaible as
   the same macro used in bitmap.
v4->v5:
 * Added callback irq_{request,release}_resources() to both irq and tint
   interrupt chips.
v3->v4:
 * Updated commit header irq->interrupt.
 * Updated commit description IRQs->interrupts.
 * Updated shared_irq_cnt variable type from u8->unsigned int.
v2->v3:
 * No change
v1->v2:
 * No change
---
 drivers/irqchip/irq-renesas-rzg2l.c | 104 +++++++++++++++++++++++++++-
 1 file changed, 103 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index 1ff1c0efed66..97bbaaaeedb0 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -22,6 +22,8 @@
 
 #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 ISCR				0x10
 #define IITSR				0x14
@@ -29,6 +31,7 @@
 #define TITSR(n)			(0x24 + (n) * 4)
 #define TITSR0_MAX_INT			16
 #define TITSEL_WIDTH			0x2
+#define INTTSEL				0x2c
 #define TSSR(n)				(0x30 + ((n) * 4))
 #define TIEN				BIT(7)
 #define TSSEL_SHIFT(n)			(8 * (n))
@@ -52,16 +55,21 @@
 #define IITSR_IITSEL_EDGE_BOTH		3
 #define IITSR_IITSEL_MASK(n)		IITSR_IITSEL((n), 3)
 
+#define INTTSEL_TINTSEL(n)		BIT(n)
+#define INTTSEL_TINTSEL_START		24
+
 #define TINT_EXTRACT_HWIRQ(x)		FIELD_GET(GENMASK(15, 0), (x))
 #define TINT_EXTRACT_GPIOINT(x)		FIELD_GET(GENMASK(31, 16), (x))
 
 /**
  * struct rzg2l_irqc_reg_cache - registers cache (necessary for suspend/resume)
  * @iitsr: IITSR register
+ * @inttsel: INTTSEL register
  * @titsr: TITSR registers
  */
 struct rzg2l_irqc_reg_cache {
 	u32	iitsr;
+	u32	inttsel;
 	u32	titsr[2];
 };
 
@@ -71,12 +79,14 @@ struct rzg2l_irqc_reg_cache {
  * @irq_count:		Number of IRQC interrupts
  * @tint_start:		Start of TINT interrupts
  * @num_irq:		Total Number of interrupts
+ * @shared_irq_cnt:	Number of shared interrupts
  */
 struct rzg2l_hw_info {
 	const u8	*tssel_lut;
 	unsigned int	irq_count;
 	unsigned int	tint_start;
 	unsigned int	num_irq;
+	unsigned int	shared_irq_cnt;
 };
 
 /**
@@ -88,6 +98,7 @@ struct rzg2l_hw_info {
  * @lock:	Lock to serialize access to hardware registers
  * @info:	Hardware specific data
  * @cache:	Registers cache for suspend/resume
+ * @used_irqs	Bitmap to manage the shared interrupts
  */
 static struct rzg2l_irqc_priv {
 	void __iomem			*base;
@@ -97,6 +108,7 @@ static struct rzg2l_irqc_priv {
 	raw_spinlock_t			lock;
 	struct rzg2l_hw_info		info;
 	struct rzg2l_irqc_reg_cache	cache;
+	DECLARE_BITMAP(used_irqs, IRQC_SHARED_IRQ_COUNT);
 } *rzg2l_irqc_data;
 
 static struct rzg2l_irqc_priv *irq_data_to_priv(struct irq_data *data)
@@ -464,6 +476,8 @@ static int rzg2l_irqc_irq_suspend(void *data)
 	void __iomem *base = rzg2l_irqc_data->base;
 
 	cache->iitsr = readl_relaxed(base + IITSR);
+	if (rzg2l_irqc_data->info.shared_irq_cnt)
+		cache->inttsel = readl_relaxed(base + INTTSEL);
 	for (u8 i = 0; i < 2; i++)
 		cache->titsr[i] = readl_relaxed(base + TITSR(i));
 
@@ -482,6 +496,8 @@ static void rzg2l_irqc_irq_resume(void *data)
 	 */
 	for (u8 i = 0; i < 2; i++)
 		writel_relaxed(cache->titsr[i], base + TITSR(i));
+	if (rzg2l_irqc_data->info.shared_irq_cnt)
+		writel_relaxed(cache->inttsel, base + INTTSEL);
 	writel_relaxed(cache->iitsr, base + IITSR);
 }
 
@@ -562,6 +578,72 @@ static const struct irq_chip rzfive_irqc_tint_chip = {
 				  IRQCHIP_SKIP_SET_WAKE,
 };
 
+static bool rzg2l_irqc_is_shared_irqc(const struct rzg2l_hw_info info, unsigned int hw_irq)
+{
+	return ((hw_irq >= (info.tint_start - info.shared_irq_cnt)) && hw_irq < info.tint_start);
+}
+
+static bool rzg2l_irqc_is_shared_tint(const struct rzg2l_hw_info info, unsigned int hw_irq)
+{
+	return ((hw_irq >= (info.num_irq - info.shared_irq_cnt)) && hw_irq < info.num_irq);
+}
+
+static bool rzg2l_irq_is_shared_and_get_irq_num(struct rzg2l_irqc_priv *priv,
+						irq_hw_number_t hwirq, unsigned int *irq_num)
+{
+	bool is_shared = false;
+
+	if (rzg2l_irqc_is_shared_irqc(priv->info, hwirq)) {
+		*irq_num = hwirq - IRQC_IRQ_SHARED_START;
+		is_shared = true;
+	} else if (rzg2l_irqc_is_shared_tint(priv->info, hwirq)) {
+		*irq_num = hwirq - IRQC_TINT_COUNT - IRQC_IRQ_SHARED_START;
+		is_shared = true;
+	}
+
+	return is_shared;
+}
+
+static void rzg2l_irqc_set_inttsel(struct rzg2l_irqc_priv *priv, unsigned int offset,
+				   unsigned int select_irq)
+{
+	u32 reg;
+
+	guard(raw_spinlock)(&priv->lock);
+	reg = readl_relaxed(priv->base + INTTSEL);
+	if (select_irq)
+		reg |= INTTSEL_TINTSEL(offset);
+	else
+		reg &= ~INTTSEL_TINTSEL(offset);
+	writel_relaxed(reg, priv->base + INTTSEL);
+}
+
+static int rzg2l_irqc_shared_irq_alloc(struct rzg2l_irqc_priv *priv, irq_hw_number_t hwirq)
+{
+	unsigned int irq_num;
+
+	if (rzg2l_irq_is_shared_and_get_irq_num(priv, hwirq, &irq_num)) {
+		if (test_and_set_bit(irq_num, priv->used_irqs))
+			return -EBUSY;
+
+		if (hwirq < priv->info.tint_start)
+			rzg2l_irqc_set_inttsel(priv, INTTSEL_TINTSEL_START + irq_num, 1);
+		else
+			rzg2l_irqc_set_inttsel(priv, INTTSEL_TINTSEL_START + irq_num, 0);
+	}
+
+	return 0;
+}
+
+static void rzg2l_irqc_shared_irq_free(struct rzg2l_irqc_priv *priv, irq_hw_number_t hwirq)
+{
+	unsigned int irq_num;
+
+	if (rzg2l_irq_is_shared_and_get_irq_num(priv, hwirq, &irq_num) &&
+	    test_and_clear_bit(irq_num, priv->used_irqs))
+		rzg2l_irqc_set_inttsel(priv, INTTSEL_TINTSEL_START + irq_num, 0);
+}
+
 static int rzg2l_irqc_alloc(struct irq_domain *domain, unsigned int virq,
 			    unsigned int nr_irqs, void *arg)
 {
@@ -594,6 +676,12 @@ static int rzg2l_irqc_alloc(struct irq_domain *domain, unsigned int virq,
 	if (hwirq >= priv->info.num_irq)
 		return -EINVAL;
 
+	if (priv->info.shared_irq_cnt) {
+		ret = rzg2l_irqc_shared_irq_alloc(priv, hwirq);
+		if (ret)
+			return ret;
+	}
+
 	ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, chip, (void *)(uintptr_t)tint);
 	if (ret)
 		return ret;
@@ -601,9 +689,22 @@ static int rzg2l_irqc_alloc(struct irq_domain *domain, unsigned int virq,
 	return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &priv->fwspec[hwirq]);
 }
 
+static void rzg2l_irqc_free(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs)
+{
+	struct rzg2l_irqc_priv *priv = domain->host_data;
+
+	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));
+	}
+
+	return irq_domain_free_irqs_common(domain, virq, nr_irqs);
+}
+
 static const struct irq_domain_ops rzg2l_irqc_domain_ops = {
 	.alloc = rzg2l_irqc_alloc,
-	.free = irq_domain_free_irqs_common,
+	.free = rzg2l_irqc_free,
 	.translate = irq_domain_translate_twocell,
 };
 
@@ -718,6 +819,7 @@ static const struct rzg2l_hw_info rzg3l_hw_params = {
 	.irq_count	= 16,
 	.tint_start	= IRQC_IRQ_START + 16,
 	.num_irq	= IRQC_IRQ_START + 16 + IRQC_TINT_COUNT,
+	.shared_irq_cnt	= IRQC_SHARED_IRQ_COUNT,
 };
 
 static const struct rzg2l_hw_info rzg2l_hw_params = {
-- 
2.43.0


^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: [PATCH v6 15/15] irqchip/renesas-rzg2l: Add shared interrupt support
  2026-03-22 12:23 ` [PATCH v6 15/15] irqchip/renesas-rzg2l: Add shared interrupt support Biju
@ 2026-03-23 11:34   ` Biju Das
  2026-03-25 18:00   ` kernel test robot
  1 sibling, 0 replies; 22+ messages in thread
From: Biju Das @ 2026-03-23 11:34 UTC (permalink / raw)
  To: biju.das.au, Thomas Gleixner
  Cc: linux-kernel, Geert Uytterhoeven, Prabhakar Mahadev Lad,
	biju.das.au, linux-renesas-soc

Hi All,

> -----Original Message-----
> From: Biju <biju.das.au@gmail.com>
> Sent: 22 March 2026 12:24
> Subject: [PATCH v6 15/15] irqchip/renesas-rzg2l: Add shared interrupt support
> 
> From: Biju Das <biju.das.jz@bp.renesas.com>
> 
> The RZ/G3L SoC has 16 external interrupts, of which 8 are shared with TINT (GPIO interrupts), whereas
> RZ/G2L has only 8 external interrupts with no sharing. The shared interrupt line selection between
> external interrupt and GPIO interrupt is based on the INTTSEL register. Add shared_irq_cnt variable to
> struct rzg2l_hw_info handle these differences.
> 
> Add used_irqs bitmap to struct rzg2l_irqc_priv to track allocation state.
> In the alloc callback, use test_and_set_bit() to enforce mutual exclusion and configure the INTTSEL
> register to route to either the external interrupt or TINT. In the free callback, use
> test_and_clear_bit() to release the shared interrupt line and reset the INTTSEL. Also add INTTSEL
> register save/restore support to the suspend/resume path.
> 
> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
> ---
> v5->v6:
>  * Updated commit description.
>  * Switched to using irq_domain_ops::{alloc,free} callbacks for mutual
>    exclusion between external interrupts and GPIO interrupts as using
>    irq_{request,release}_resources() leading to irq storm()
>  * Dropped irq_{request,release}_resources().
>  * Replaced the macro TINTSEL->INTTSEL_TINTSEL
>  * Added macros INTTSEL_TINTSEL_START, IRQC_SHARED_IRQ_COUNT and
>    IRQC_IRQ_SHARED_START.
>  * Added used_irqs bitmap to struct rzg2l_irqc_priv to track allocation
>    state of shared_interrupt
>  * Added rzg2l_irqc_set_inttsel() for configuring INTTSEL register.
>  * Replaced irq_domain_free_irqs_common()->rzg2l_irqc_free() as
>    rzg2l_irqc_domain_ops::free() callback.
>  * Replaced the 8->IRQC_SHARED_IRQ_COUNT in shared_irq_cnt varaible as
>    the same macro used in bitmap.
> v4->v5:
>  * Added callback irq_{request,release}_resources() to both irq and tint
>    interrupt chips.
> v3->v4:
>  * Updated commit header irq->interrupt.
>  * Updated commit description IRQs->interrupts.
>  * Updated shared_irq_cnt variable type from u8->unsigned int.
> v2->v3:
>  * No change
> v1->v2:
>  * No change
> ---
>  drivers/irqchip/irq-renesas-rzg2l.c | 104 +++++++++++++++++++++++++++-
>  1 file changed, 103 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
> index 1ff1c0efed66..97bbaaaeedb0 100644
> --- a/drivers/irqchip/irq-renesas-rzg2l.c
> +++ b/drivers/irqchip/irq-renesas-rzg2l.c
> @@ -22,6 +22,8 @@
> 
>  #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 ISCR				0x10
>  #define IITSR				0x14
> @@ -29,6 +31,7 @@
>  #define TITSR(n)			(0x24 + (n) * 4)
>  #define TITSR0_MAX_INT			16
>  #define TITSEL_WIDTH			0x2
> +#define INTTSEL				0x2c
>  #define TSSR(n)				(0x30 + ((n) * 4))
>  #define TIEN				BIT(7)
>  #define TSSEL_SHIFT(n)			(8 * (n))
> @@ -52,16 +55,21 @@
>  #define IITSR_IITSEL_EDGE_BOTH		3
>  #define IITSR_IITSEL_MASK(n)		IITSR_IITSEL((n), 3)
> 
> +#define INTTSEL_TINTSEL(n)		BIT(n)
> +#define INTTSEL_TINTSEL_START		24
> +
>  #define TINT_EXTRACT_HWIRQ(x)		FIELD_GET(GENMASK(15, 0), (x))
>  #define TINT_EXTRACT_GPIOINT(x)		FIELD_GET(GENMASK(31, 16), (x))
> 
>  /**
>   * struct rzg2l_irqc_reg_cache - registers cache (necessary for suspend/resume)
>   * @iitsr: IITSR register
> + * @inttsel: INTTSEL register
>   * @titsr: TITSR registers
>   */
>  struct rzg2l_irqc_reg_cache {
>  	u32	iitsr;
> +	u32	inttsel;
>  	u32	titsr[2];
>  };
> 
> @@ -71,12 +79,14 @@ struct rzg2l_irqc_reg_cache {
>   * @irq_count:		Number of IRQC interrupts
>   * @tint_start:		Start of TINT interrupts
>   * @num_irq:		Total Number of interrupts
> + * @shared_irq_cnt:	Number of shared interrupts
>   */
>  struct rzg2l_hw_info {
>  	const u8	*tssel_lut;
>  	unsigned int	irq_count;
>  	unsigned int	tint_start;
>  	unsigned int	num_irq;
> +	unsigned int	shared_irq_cnt;
>  };
> 
>  /**
> @@ -88,6 +98,7 @@ struct rzg2l_hw_info {
>   * @lock:	Lock to serialize access to hardware registers
>   * @info:	Hardware specific data
>   * @cache:	Registers cache for suspend/resume
> + * @used_irqs	Bitmap to manage the shared interrupts
>   */
>  static struct rzg2l_irqc_priv {
>  	void __iomem			*base;
> @@ -97,6 +108,7 @@ static struct rzg2l_irqc_priv {
>  	raw_spinlock_t			lock;
>  	struct rzg2l_hw_info		info;
>  	struct rzg2l_irqc_reg_cache	cache;
> +	DECLARE_BITMAP(used_irqs, IRQC_SHARED_IRQ_COUNT);
>  } *rzg2l_irqc_data;
> 
>  static struct rzg2l_irqc_priv *irq_data_to_priv(struct irq_data *data) @@ -464,6 +476,8 @@ static int
> rzg2l_irqc_irq_suspend(void *data)
>  	void __iomem *base = rzg2l_irqc_data->base;
> 
>  	cache->iitsr = readl_relaxed(base + IITSR);
> +	if (rzg2l_irqc_data->info.shared_irq_cnt)
> +		cache->inttsel = readl_relaxed(base + INTTSEL);
>  	for (u8 i = 0; i < 2; i++)
>  		cache->titsr[i] = readl_relaxed(base + TITSR(i));
> 
> @@ -482,6 +496,8 @@ static void rzg2l_irqc_irq_resume(void *data)
>  	 */
>  	for (u8 i = 0; i < 2; i++)
>  		writel_relaxed(cache->titsr[i], base + TITSR(i));
> +	if (rzg2l_irqc_data->info.shared_irq_cnt)
> +		writel_relaxed(cache->inttsel, base + INTTSEL);
>  	writel_relaxed(cache->iitsr, base + IITSR);  }
> 
> @@ -562,6 +578,72 @@ static const struct irq_chip rzfive_irqc_tint_chip = {
>  				  IRQCHIP_SKIP_SET_WAKE,
>  };
> 
> +static bool rzg2l_irqc_is_shared_irqc(const struct rzg2l_hw_info info,
> +unsigned int hw_irq) {
> +	return ((hw_irq >= (info.tint_start - info.shared_irq_cnt)) && hw_irq
> +< info.tint_start); }
> +
> +static bool rzg2l_irqc_is_shared_tint(const struct rzg2l_hw_info info,
> +unsigned int hw_irq) {
> +	return ((hw_irq >= (info.num_irq - info.shared_irq_cnt)) && hw_irq <
> +info.num_irq); }
> +
> +static bool rzg2l_irq_is_shared_and_get_irq_num(struct rzg2l_irqc_priv *priv,
> +						irq_hw_number_t hwirq, unsigned int *irq_num) {

For consistency rzg2l_irqc_is_shared_and_get_irq_num()


> +	bool is_shared = false;
> +
> +	if (rzg2l_irqc_is_shared_irqc(priv->info, hwirq)) {
> +		*irq_num = hwirq - IRQC_IRQ_SHARED_START;
> +		is_shared = true;
> +	} else if (rzg2l_irqc_is_shared_tint(priv->info, hwirq)) {
> +		*irq_num = hwirq - IRQC_TINT_COUNT - IRQC_IRQ_SHARED_START;
> +		is_shared = true;
> +	}
> +
> +	return is_shared;
> +}
> +
> +static void rzg2l_irqc_set_inttsel(struct rzg2l_irqc_priv *priv, unsigned int offset,
> +				   unsigned int select_irq)
> +{
> +	u32 reg;
> +
> +	guard(raw_spinlock)(&priv->lock);

This may lead to dead lock, so need to use raw_spinlock_save.
Driver probe and eoi handler executing on the same CPU.

> +	reg = readl_relaxed(priv->base + INTTSEL);
> +	if (select_irq)
> +		reg |= INTTSEL_TINTSEL(offset);
> +	else
> +		reg &= ~INTTSEL_TINTSEL(offset);
> +	writel_relaxed(reg, priv->base + INTTSEL); }
> +
> +static int rzg2l_irqc_shared_irq_alloc(struct rzg2l_irqc_priv *priv,
> +irq_hw_number_t hwirq) {
> +	unsigned int irq_num;
> +
> +	if (rzg2l_irq_is_shared_and_get_irq_num(priv, hwirq, &irq_num)) {
> +		if (test_and_set_bit(irq_num, priv->used_irqs))
> +			return -EBUSY;
> +
> +		if (hwirq < priv->info.tint_start)
> +			rzg2l_irqc_set_inttsel(priv, INTTSEL_TINTSEL_START + irq_num, 1);
> +		else
> +			rzg2l_irqc_set_inttsel(priv, INTTSEL_TINTSEL_START + irq_num, 0);
> +	}
> +
> +	return 0;
> +}
> +
> +static void rzg2l_irqc_shared_irq_free(struct rzg2l_irqc_priv *priv,
> +irq_hw_number_t hwirq) {
> +	unsigned int irq_num;
> +
> +	if (rzg2l_irq_is_shared_and_get_irq_num(priv, hwirq, &irq_num) &&
> +	    test_and_clear_bit(irq_num, priv->used_irqs))
> +		rzg2l_irqc_set_inttsel(priv, INTTSEL_TINTSEL_START + irq_num, 0); }
> +
>  static int rzg2l_irqc_alloc(struct irq_domain *domain, unsigned int virq,
>  			    unsigned int nr_irqs, void *arg)  { @@ -594,6 +676,12 @@ static int
> rzg2l_irqc_alloc(struct irq_domain *domain, unsigned int virq,
>  	if (hwirq >= priv->info.num_irq)
>  		return -EINVAL;
> 
> +	if (priv->info.shared_irq_cnt) {
> +		ret = rzg2l_irqc_shared_irq_alloc(priv, hwirq);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, chip, (void *)(uintptr_t)tint);
>  	if (ret)
>  		return ret;

If this fails, rzg2l_irqc_shared_irq_free() to be called.

I will fix this in next version.

Cheers,
Biju

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: [PATCH v6 14/15] irqchip/renesas-rzg2l: Add RZ/G3L support
  2026-03-22 12:23 ` [PATCH v6 14/15] irqchip/renesas-rzg2l: Add RZ/G3L support Biju
@ 2026-03-23 11:36   ` Biju Das
  0 siblings, 0 replies; 22+ messages in thread
From: Biju Das @ 2026-03-23 11:36 UTC (permalink / raw)
  To: biju.das.au, Thomas Gleixner
  Cc: linux-kernel, Geert Uytterhoeven, Prabhakar Mahadev Lad,
	biju.das.au, linux-renesas-soc

Hi All,

> -----Original Message-----
> From: Biju <biju.das.au@gmail.com>
> Sent: 22 March 2026 12:24
> Subject: [PATCH v6 14/15] irqchip/renesas-rzg2l: Add RZ/G3L support
> 
> From: Biju Das <biju.das.jz@bp.renesas.com>
> 
> The IRQC block on the RZ/G3L SoC is almost identical to the one found on the RZ/G2L SoC, with the
> following differences:
> 
>  - The number of GPIO interrupts for TINT selection is 113 instead of 123.
>  - The pin index and TINT selection index are not in the 1:1 map.
>  - The number of external interrupts are 16 instead of 8, out of these
>    8 external interrupts are shared with TINT.
> 
> Add support for the RZ/G3L driver by filling the rzg2l_hw_info table and adding LUT for mapping
> between pin index and TINT selection index.
> 
> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
> ---
> v5->v6:
>  * No change.
> v4->v5:
>  * Updated rzg3l_irqc_probe() for supporting separate interrupt chips.
> v3->v4:
>  * Updated commit description IRQs->interrupts.
>  * Updated rzg2l_disable_tint_and_set_tint_source() for making
>    tint assignment very clear in the code.
>  * Formatted rzg3l_tssel_lut as table format.
> v2->v3:
>  * No change
> v1->v2:
>  * No change
> ---
>  drivers/irqchip/irq-renesas-rzg2l.c | 44 +++++++++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
> index 8aff8b9d49c9..1ff1c0efed66 100644
> --- a/drivers/irqchip/irq-renesas-rzg2l.c
> +++ b/drivers/irqchip/irq-renesas-rzg2l.c
> @@ -67,11 +67,13 @@ struct rzg2l_irqc_reg_cache {
> 
>  /**
>   * struct rzg2l_hw_info - Interrupt Control Unit controller hardware info structure.
> + * @tssel_lut:		TINT lookup table
>   * @irq_count:		Number of IRQC interrupts
>   * @tint_start:		Start of TINT interrupts
>   * @num_irq:		Total Number of interrupts
>   */
>  struct rzg2l_hw_info {
> +	const u8	*tssel_lut;
>  	unsigned int	irq_count;
>  	unsigned int	tint_start;
>  	unsigned int	num_irq;
> @@ -377,6 +379,11 @@ static u32 rzg2l_disable_tint_and_set_tint_source(struct irq_data *d, struct rzg
>  	u32 tint = (u32)(uintptr_t)irq_data_get_irq_chip_data(d);
>  	u32 tien = reg & (TIEN << TSSEL_SHIFT(tssr_offset));
> 
> +	if (priv->info.tssel_lut)
> +		tint = priv->info.tssel_lut[tint];
> +	else
> +		tint = (u32)(uintptr_t)irq_data_get_irq_chip_data(d);
> +
>  	/* Clear the relevant byte in reg */
>  	reg &= ~(TSSEL_MASK << TSSEL_SHIFT(tssr_offset));
>  	/* Set TINT and leave TIEN clear */
> @@ -683,6 +690,36 @@ static int rzg2l_irqc_common_probe(struct platform_device *pdev, struct device_n
>  	return 0;
>  }
> 
> +/* Mapping based on port index on Table 4.2-1 and GPIOINT on Table
> +4.6-7 */ static const u8 rzg3l_tssel_lut[] = {
> +	 83,  84,					/* P20-P21 */
> +	  7,   8,   9,  10,  11,  12,  13,		/* P30-P36 */
> +	 85,  86,  87,  88,  89,  90,  91,		/* P50-P56 */
> +	 92,  93,  94,  95,  96,  97,  98,		/* P60-P66 */
> +	 99, 100, 101, 102, 103, 104, 105, 106,		/* P70-P77 */
> +	107, 108, 109, 110, 111, 112,			/* P80-P85 */
> +	 45,  46,  47,  48,  49,  50,  51,  52,		/* PA0-PA7 */
> +	 53,  54,  55,  56,  57,  58,  59,  60,		/* PB0-PB7 */
> +	 61,  62,  63,					/* PC0-PC2 */
> +	 64,  65,  66,  67,  68,  69,  70,  71,		/* PD0-PD7 */
> +	 72,  73,  74,  75,  76,  77,  78,  79,		/* PE0-PE7 */
> +	 80,  81,  82,					/* PF0-PF2 */
> +	 27,  28,  29,  30,  31,  32,  33,  34,		/* PG0-PG7 */
> +	 35,  36,  37,  38,  39,  40,			/* PH0-PH5 */
> +	  2,   3,   4,   5,   6,			/* PJ0-PJ4 */
> +	 41,  42,  43,  44,				/* PK0-PK3 */
> +	 14,  15,  16,  17,  26,			/* PL0-PL4 */
> +	 18,  19,  20,  21,  22,  23,  24,  25,		/* PM0-PM7 */
> +	  0,   1					/* PS0-PS1 */
> +};
> +
> +static const struct rzg2l_hw_info rzg3l_hw_params = {
> +	.tssel_lut	= rzg3l_tssel_lut,
> +	.irq_count	= 16,
> +	.tint_start	= IRQC_IRQ_START + 16,
> +	.num_irq	= IRQC_IRQ_START + 16 + IRQC_TINT_COUNT,
> +};
> +
>  static const struct rzg2l_hw_info rzg2l_hw_params = {
>  	.irq_count	= 8,
>  	.tint_start	= IRQC_IRQ_START + 8,
> @@ -695,6 +732,12 @@ static int rzg2l_irqc_probe(struct platform_device *pdev, struct device_node *pa
>  				       rzg2l_hw_params);
>  }
> 
> +static int rzg3l_irqc_probe(struct platform_device *pdev, struct
> +device_node *parent) {
> +	return rzg2l_irqc_common_probe(pdev, parent, &rzg2l_irqc_irq_chip, &rzg2l_irqc_tint_chip,
> +				       rzg3l_hw_params);
> +}
> +
>  static int rzfive_irqc_probe(struct platform_device *pdev, struct device_node *parent)  {
>  	return rzg2l_irqc_common_probe(pdev, parent, &rzfive_irqc_irq_chip, &rzfive_irqc_tint_chip, @@ -
> 703,6 +746,7 @@ static int rzfive_irqc_probe(struct platform_device *pdev, struct device_node *p
> 
>  IRQCHIP_PLATFORM_DRIVER_BEGIN(rzg2l_irqc)
>  IRQCHIP_MATCH("renesas,rzg2l-irqc", rzg2l_irqc_probe)
> +IRQCHIP_MATCH("renesas,r9a08g046-irqc", rzg3l_irqc_probe)
>  IRQCHIP_MATCH("renesas,r9a07g043f-irqc", rzfive_irqc_probe)
>  IRQCHIP_PLATFORM_DRIVER_END(rzg2l_irqc)
>  MODULE_AUTHOR("Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>");


I need to update rzg2l_irq_set_type() replacing
u16-> unsigned int.

I will fix this in next version.

Cheers,
Biju

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: [PATCH v6 03/15] irqchip/renesas-rzg2l: Drop redundant IRQC_TINT_START check in rzg2l_irqc_alloc()
  2026-03-22 12:23 ` [PATCH v6 03/15] irqchip/renesas-rzg2l: Drop redundant IRQC_TINT_START check in rzg2l_irqc_alloc() Biju
@ 2026-03-23 11:58   ` Biju Das
  2026-03-23 20:14     ` Biju Das
  0 siblings, 1 reply; 22+ messages in thread
From: Biju Das @ 2026-03-23 11:58 UTC (permalink / raw)
  To: biju.das.au, Thomas Gleixner
  Cc: linux-kernel, Geert Uytterhoeven, Prabhakar Mahadev Lad,
	biju.das.au, linux-renesas-soc

Hi All,

> -----Original Message-----
> From: Biju <biju.das.au@gmail.com>
> Sent: 22 March 2026 12:24
> Subject: [PATCH v6 03/15] irqchip/renesas-rzg2l: Drop redundant IRQC_TINT_START check in
> rzg2l_irqc_alloc()
> 
> From: Biju Das <biju.das.jz@bp.renesas.com>
> 
> The check `hwirq < IRQC_TINT_START` in rzg2l_irqc_alloc() is unnecessary as the condition is already
> guaranteed to be false at that point in the code. The outer `if (hwirq > IRQC_IRQ_COUNT)` block
> ensures that hwirq is always above IRQC_IRQ_COUNT before reaching this check, and since
> IRQC_TINT_START <= IRQC_IRQ_COUNT, the guard can never trigger.
> 
> Remove the dead code to simplify the allocation path.
> 
> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
> ---
> v5->v6:
>  * No change.
> v5:
>  * New patch.
> ---
>  drivers/irqchip/irq-renesas-rzg2l.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
> index e73d426cea6d..ed8044b0a339 100644
> --- a/drivers/irqchip/irq-renesas-rzg2l.c
> +++ b/drivers/irqchip/irq-renesas-rzg2l.c
> @@ -491,9 +491,6 @@ 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);
> -
> -		if (hwirq < IRQC_TINT_START)
> -			return -EINVAL;

I am planning to drop this patch as 0x10005 is invalid for TINT IRQ
This check will return proper error.

Cheers,
Biju

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: [PATCH v6 03/15] irqchip/renesas-rzg2l: Drop redundant IRQC_TINT_START check in rzg2l_irqc_alloc()
  2026-03-23 11:58   ` Biju Das
@ 2026-03-23 20:14     ` Biju Das
  0 siblings, 0 replies; 22+ messages in thread
From: Biju Das @ 2026-03-23 20:14 UTC (permalink / raw)
  To: biju.das.au, Thomas Gleixner
  Cc: linux-kernel, Geert Uytterhoeven, Prabhakar Mahadev Lad,
	biju.das.au, linux-renesas-soc

Hi,

> -----Original Message-----
> From: Biju Das
> Sent: 23 March 2026 11:59
> Subject: RE: [PATCH v6 03/15] irqchip/renesas-rzg2l: Drop redundant IRQC_TINT_START check in
> rzg2l_irqc_alloc()
> 
> Hi All,
> 
> > -----Original Message-----
> > From: Biju <biju.das.au@gmail.com>
> > Sent: 22 March 2026 12:24
> > Subject: [PATCH v6 03/15] irqchip/renesas-rzg2l: Drop redundant
> > IRQC_TINT_START check in
> > rzg2l_irqc_alloc()
> >
> > From: Biju Das <biju.das.jz@bp.renesas.com>
> >
> > The check `hwirq < IRQC_TINT_START` in rzg2l_irqc_alloc() is
> > unnecessary as the condition is already guaranteed to be false at that
> > point in the code. The outer `if (hwirq > IRQC_IRQ_COUNT)` block
> > ensures that hwirq is always above IRQC_IRQ_COUNT before reaching this check, and since
> IRQC_TINT_START <= IRQC_IRQ_COUNT, the guard can never trigger.
> >
> > Remove the dead code to simplify the allocation path.
> >
> > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
> > ---
> > v5->v6:
> >  * No change.
> > v5:
> >  * New patch.
> > ---
> >  drivers/irqchip/irq-renesas-rzg2l.c | 3 ---
> >  1 file changed, 3 deletions(-)
> >
> > diff --git a/drivers/irqchip/irq-renesas-rzg2l.c
> > b/drivers/irqchip/irq-renesas-rzg2l.c
> > index e73d426cea6d..ed8044b0a339 100644
> > --- a/drivers/irqchip/irq-renesas-rzg2l.c
> > +++ b/drivers/irqchip/irq-renesas-rzg2l.c
> > @@ -491,9 +491,6 @@ 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);
> > -
> > -		if (hwirq < IRQC_TINT_START)
> > -			return -EINVAL;
> 
> I am planning to drop this patch as 0x10005 is invalid for TINT IRQ This check will return proper
> error.

I will retain the patch, based on [1] this never happens.

[1] https://elixir.bootlin.com/linux/v7.0-rc5/source/drivers/pinctrl/renesas/pinctrl-rzg2l.c#L2609

Cheers,
Biju

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v6 15/15] irqchip/renesas-rzg2l: Add shared interrupt support
  2026-03-22 12:23 ` [PATCH v6 15/15] irqchip/renesas-rzg2l: Add shared interrupt support Biju
  2026-03-23 11:34   ` Biju Das
@ 2026-03-25 18:00   ` kernel test robot
  2026-03-25 18:12     ` Biju Das
  1 sibling, 1 reply; 22+ messages in thread
From: kernel test robot @ 2026-03-25 18:00 UTC (permalink / raw)
  To: Biju, Thomas Gleixner
  Cc: oe-kbuild-all, Biju Das, linux-kernel, Geert Uytterhoeven,
	Prabhakar Mahadev Lad, linux-renesas-soc

Hi Biju,

kernel test robot noticed the following build warnings:

[auto build test WARNING on tip/irq/core]
[also build test WARNING on linus/master v7.0-rc5 next-20260323]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Biju/dt-bindings-interrupt-controller-renesas-rzg2l-irqc-Use-pattern-for-interrupt-names/20260323-002740
base:   tip/irq/core
patch link:    https://lore.kernel.org/r/20260322122421.132474-16-biju.das.jz%40bp.renesas.com
patch subject: [PATCH v6 15/15] irqchip/renesas-rzg2l: Add shared interrupt support
config: arc-allyesconfig (https://download.01.org/0day-ci/archive/20260326/202603260117.5j4fMpip-lkp@intel.com/config)
compiler: arc-linux-gcc (GCC) 15.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260326/202603260117.5j4fMpip-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603260117.5j4fMpip-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> Warning: drivers/irqchip/irq-renesas-rzg2l.c:111 struct member 'used_irqs' not described in 'rzg2l_irqc_priv'
>> Warning: drivers/irqchip/irq-renesas-rzg2l.c:111 struct member 'used_irqs' not described in 'rzg2l_irqc_priv'

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: [PATCH v6 15/15] irqchip/renesas-rzg2l: Add shared interrupt support
  2026-03-25 18:00   ` kernel test robot
@ 2026-03-25 18:12     ` Biju Das
  0 siblings, 0 replies; 22+ messages in thread
From: Biju Das @ 2026-03-25 18:12 UTC (permalink / raw)
  To: kernel test robot, biju.das.au, Thomas Gleixner
  Cc: oe-kbuild-all, linux-kernel, Geert Uytterhoeven,
	Prabhakar Mahadev Lad, linux-renesas-soc

Hi,

Thanks for the review.

> -----Original Message-----
> From: kernel test robot <lkp@intel.com>
> Sent: 25 March 2026 18:01
> Subject: Re: [PATCH v6 15/15] irqchip/renesas-rzg2l: Add shared interrupt support
> 
> Hi Biju,
> 
> kernel test robot noticed the following build warnings:
> 
> [auto build test WARNING on tip/irq/core] [also build test WARNING on linus/master v7.0-rc5 next-
> 20260323] [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-
> format-patch#_base_tree_information]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Biju/dt-bindings-interrupt-controller-renesas-
> rzg2l-irqc-Use-pattern-for-interrupt-names/20260323-002740
> base:   tip/irq/core
> patch link:    https://lore.kernel.org/r/20260322122421.132474-16-biju.das.jz%40bp.renesas.com
> patch subject: [PATCH v6 15/15] irqchip/renesas-rzg2l: Add shared interrupt support
> config: arc-allyesconfig (https://download.01.org/0day-ci/archive/20260326/202603260117.5j4fMpip-
> lkp@intel.com/config)
> compiler: arc-linux-gcc (GCC) 15.2.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-
> ci/archive/20260326/202603260117.5j4fMpip-lkp@intel.com/reproduce)
> 
> If you fix the issue in a separate patch/commit (i.e. not just a new version of the same
> patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes:
> | https://lore.kernel.org/oe-kbuild-all/202603260117.5j4fMpip-lkp@intel.
> | com/
> 
> All warnings (new ones prefixed by >>):
> 
> >> Warning: drivers/irqchip/irq-renesas-rzg2l.c:111 struct member 'used_irqs' not described in
> 'rzg2l_irqc_priv'
> >> Warning: drivers/irqchip/irq-renesas-rzg2l.c:111 struct member 'used_irqs' not described in
> 'rzg2l_irqc_priv'

I missed to add ':' in kernel doc. Will fix it.

Cheers,
Biju

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2026-03-25 18:12 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-03-22 12:23 [PATCH v6 00/15] Add RZ/G3L IRQC support Biju
2026-03-22 12:23 ` [PATCH v6 01/15] dt-bindings: interrupt-controller: renesas,rzg2l-irqc: Use pattern for interrupt-names Biju
2026-03-22 12:23 ` [PATCH v6 02/15] dt-bindings: interrupt-controller: renesas,rzg2l-irqc: Document RZ/G3L SoC Biju
2026-03-22 12:23 ` [PATCH v6 03/15] irqchip/renesas-rzg2l: Drop redundant IRQC_TINT_START check in rzg2l_irqc_alloc() Biju
2026-03-23 11:58   ` Biju Das
2026-03-23 20:14     ` Biju Das
2026-03-22 12:23 ` [PATCH v6 04/15] irqchip/renesas-rzg2l: Replace single irq_chip with per-region irq_chip instances Biju
2026-03-22 12:23 ` [PATCH v6 05/15] irqchip/renesas-rzg2l: Split EOI handler into separate IRQ and TINT functions Biju
2026-03-22 12:23 ` [PATCH v6 06/15] irqchip/renesas-rzg2l: Split set_type " Biju
2026-03-22 12:23 ` [PATCH v6 07/15] irqchip/renesas-rzg2l: Replace rzg2l_irqc_irq_{enable,disable} with TINT-specific handlers Biju
2026-03-22 12:23 ` [PATCH v6 08/15] irqchip/renesas-rzg2l: Split rzfive_tint_irq_endisable() into separate IRQ and TINT helpers Biju
2026-03-22 12:23 ` [PATCH v6 09/15] irqchip/renesas-rzg2l: Split rzfive_irqc_{mask,unmask} into separate IRQ and TINT handlers Biju
2026-03-22 12:23 ` [PATCH v6 10/15] irqchip/renesas-rzg2l: Dynamically allocate fwspec array Biju
2026-03-22 12:23 ` [PATCH v6 11/15] irqchip/renesas-rzg2l: Drop IRQC_NUM_IRQ macro Biju
2026-03-22 12:23 ` [PATCH v6 12/15] irqchip/renesas-rzg2l: Drop IRQC_TINT_START macro Biju
2026-03-22 12:23 ` [PATCH v6 13/15] irqchip/renesas-rzg2l: Drop IRQC_IRQ_COUNT macro Biju
2026-03-22 12:23 ` [PATCH v6 14/15] irqchip/renesas-rzg2l: Add RZ/G3L support Biju
2026-03-23 11:36   ` Biju Das
2026-03-22 12:23 ` [PATCH v6 15/15] irqchip/renesas-rzg2l: Add shared interrupt support Biju
2026-03-23 11:34   ` Biju Das
2026-03-25 18:00   ` kernel test robot
2026-03-25 18:12     ` Biju Das

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®