Re: [PATCH 2/2] gpio: rcar: Add R-Car X5H (R8A78000) support
From: Bartosz Golaszewski
Date: Mon Jul 06 2026 - 06:14:49 EST
On Sat, 4 Jul 2026 17:13:47 +0200, Marek Vasut
<marek.vasut+renesas@xxxxxxxxxxx> said:
> R-Car X5H (R8A78000) is the first member of the R-Car Gen5 family.
> Add support for R-Car X5H, which has slightly different GPIO block
> register layout compared to previous generations. Introduce offset
> remap function which performs 1:1 remap for R-Car Gen1..4 and a bit
> more complex remap for R-Car Gen5.
>
> The GPIO block register offsets on R-Car Gen5 changed and the change
> can be divided into five groups, registers which remained at the
> same offset, INDT register shifted by +0x10, OUTDTSEL register
> shifted by -0x34, INEN register shifted by -0x38 and the rest of
> the registers used by the driver shifted by +0x70 .
>
> Signed-off-by: Marek Vasut <marek.vasut+renesas@xxxxxxxxxxx>
> ---
> Cc: Bartosz Golaszewski <brgl@xxxxxxxxxx>
> Cc: Conor Dooley <conor+dt@xxxxxxxxxx>
> Cc: Geert Uytterhoeven <geert+renesas@xxxxxxxxx>
> Cc: Krzysztof Kozlowski <krzk+dt@xxxxxxxxxx>
> Cc: Linus Walleij <linusw@xxxxxxxxxx>
> Cc: Rob Herring <robh@xxxxxxxxxx>
> Cc: devicetree@xxxxxxxxxxxxxxx
> Cc: linux-gpio@xxxxxxxxxxxxxxx
> Cc: linux-kernel@xxxxxxxxxxxxxxx
> Cc: linux-renesas-soc@xxxxxxxxxxxxxxx
> ---
> drivers/gpio/gpio-rcar.c | 61 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 61 insertions(+)
>
> diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
> index 09bebde5c4260..a22112d9dce0f 100644
> --- a/drivers/gpio/gpio-rcar.c
> +++ b/drivers/gpio/gpio-rcar.c
> @@ -36,6 +36,7 @@ struct gpio_rcar_info {
> bool has_both_edge_trigger;
> bool has_always_in;
> bool has_inen;
> + bool has_layout_gen5;
> };
>
> struct gpio_rcar_priv {
> @@ -65,14 +66,59 @@ struct gpio_rcar_priv {
>
> #define RCAR_MAX_GPIO_PER_BANK 32
>
> +static inline int gpio_rcar_remap_offset(struct gpio_rcar_priv *p, int *offs)
> +{
> + /* R-Car Gen4 and older do not need any offset remap. */
> + if (!p->info.has_layout_gen5)
> + return 0;
> +
> + /*
> + * R-Car Gen5 register layout is slightly different and the offsets
> + * that have to be added to or subtracted from each register offset
> + * can be divided into five groups, listed below.
> + */
> + switch (*offs) {
> + case IOINTSEL...OUTDT:
> + return 0;
> + case INDT:
> + *offs += 0x10;
> + return 0;
> + case INTDT...EDGLEVEL:
> + fallthrough;
> + case BOTHEDGE:
> + *offs += 0x70;
> + return 0;
> + case OUTDTSEL:
> + *offs -= 0x34;
> + return 0;
> + case INEN:
> + *offs -= 0x38;
> + return 0;
> + default:
> + /*
> + * This here must never be reached, if this is reached, that
> + * means there is a catastrophic failure in the driver. Skip
> + * any IO read/write to prevent further damage.
> + */
> + WARN_ON(1);
> + return -EINVAL;
> + }
> +}
> +
> static inline u32 gpio_rcar_read(struct gpio_rcar_priv *p, int offs)
> {
> + if (gpio_rcar_remap_offset(p, &offs))
> + return 0;
> +
> return ioread32(p->base + offs);
> }
>
> static inline void gpio_rcar_write(struct gpio_rcar_priv *p, int offs,
> u32 value)
> {
> + if (gpio_rcar_remap_offset(p, &offs))
> + return;
> +
> iowrite32(value, p->base + offs);
> }
>
> @@ -399,6 +445,7 @@ static const struct gpio_rcar_info gpio_rcar_info_gen1 = {
> .has_both_edge_trigger = false,
> .has_always_in = false,
> .has_inen = false,
> + .has_layout_gen5 = false,
> };
>
> static const struct gpio_rcar_info gpio_rcar_info_gen2 = {
> @@ -406,6 +453,7 @@ static const struct gpio_rcar_info gpio_rcar_info_gen2 = {
> .has_both_edge_trigger = true,
> .has_always_in = false,
> .has_inen = false,
> + .has_layout_gen5 = false,
> };
>
> static const struct gpio_rcar_info gpio_rcar_info_gen3 = {
> @@ -413,6 +461,7 @@ static const struct gpio_rcar_info gpio_rcar_info_gen3 = {
> .has_both_edge_trigger = true,
> .has_always_in = true,
> .has_inen = false,
> + .has_layout_gen5 = false,
> };
>
> static const struct gpio_rcar_info gpio_rcar_info_gen4 = {
> @@ -420,6 +469,15 @@ static const struct gpio_rcar_info gpio_rcar_info_gen4 = {
> .has_both_edge_trigger = true,
> .has_always_in = true,
> .has_inen = true,
> + .has_layout_gen5 = false,
This looks good but do we really need to change these lines if it's zeroes
anyway?
Bart
> +};
> +
> +static const struct gpio_rcar_info gpio_rcar_info_gen5 = {
> + .has_outdtsel = true,
> + .has_both_edge_trigger = true,
> + .has_always_in = true,
> + .has_inen = true,
> + .has_layout_gen5 = true,
> };
>
> static const struct of_device_id gpio_rcar_of_table[] = {
> @@ -438,6 +496,9 @@ static const struct of_device_id gpio_rcar_of_table[] = {
> }, {
> .compatible = "renesas,rcar-gen4-gpio",
> .data = &gpio_rcar_info_gen4,
> + }, {
> + .compatible = "renesas,rcar-gen5-gpio",
> + .data = &gpio_rcar_info_gen5,
> }, {
> .compatible = "renesas,gpio-rcar",
> .data = &gpio_rcar_info_gen1,
> --
> 2.53.0
>
>