]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
irqchip/renesas-rzg2l: Add RZ/G3L support
authorBiju Das <biju.das.jz@bp.renesas.com>
Wed, 25 Mar 2026 19:24:30 +0000 (19:24 +0000)
committerThomas Gleixner <tglx@kernel.org>
Thu, 26 Mar 2026 15:56:23 +0000 (16:56 +0100)
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>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Link: https://patch.msgid.link/20260325192451.172562-16-biju.das.jz@bp.renesas.com
drivers/irqchip/irq-renesas-rzg2l.c

index 5387e901075ecb2c1534c0f9ce9cbb6d387711c0..970126b5eec478ff480e3a6605880933834e40cb 100644 (file)
@@ -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;
@@ -331,9 +333,9 @@ static int rzg2l_irq_set_type(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 iitseln = hwirq - IRQC_IRQ_START;
+       unsigned int iitseln = hwirq - IRQC_IRQ_START;
        bool clear_irq_int = false;
-       u16 sense, tmp;
+       unsigned int sense, tmp;
 
        switch (type & IRQ_TYPE_SENSE_MASK) {
        case IRQ_TYPE_LEVEL_LOW:
@@ -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 */
@@ -681,6 +688,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,
@@ -693,6 +730,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,
@@ -701,6 +744,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>");