pinctrl: renesas: Implement unlock register masks
authorUlrich Hecht <uli+renesas@fpond.eu>
Tue, 12 Jan 2021 16:59:07 +0000 (17:59 +0100)
committerGeert Uytterhoeven <geert+renesas@glider.be>
Thu, 14 Jan 2021 11:06:12 +0000 (12:06 +0100)
The V3U SoC has several unlock registers, one per register group. They
reside at offset zero in each 0x200 bytes-sized block.

To avoid adding yet another table to the PFC implementation, this
patch adds the option to specify an address mask instead of the fixed
address in sh_pfc_soc_info::unlock_reg.

Signed-off-by: Ulrich Hecht <uli+renesas@fpond.eu>
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Link: https://lore.kernel.org/r/20210112165912.30876-2-uli+renesas@fpond.eu
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
drivers/pinctrl/renesas/core.c
drivers/pinctrl/renesas/sh_pfc.h

index 291d2c6..979407f 100644 (file)
@@ -175,13 +175,25 @@ u32 sh_pfc_read(struct sh_pfc *pfc, u32 reg)
        return sh_pfc_read_raw_reg(sh_pfc_phys_to_virt(pfc, reg), 32);
 }
 
-void sh_pfc_write(struct sh_pfc *pfc, u32 reg, u32 data)
+static void sh_pfc_unlock_reg(struct sh_pfc *pfc, u32 reg, u32 data)
 {
-       if (pfc->info->unlock_reg)
-               sh_pfc_write_raw_reg(
-                       sh_pfc_phys_to_virt(pfc, pfc->info->unlock_reg), 32,
-                       ~data);
+       u32 unlock;
+
+       if (!pfc->info->unlock_reg)
+               return;
 
+       if (pfc->info->unlock_reg >= 0x80000000UL)
+               unlock = pfc->info->unlock_reg;
+       else
+               /* unlock_reg is a mask */
+               unlock = reg & ~pfc->info->unlock_reg;
+
+       sh_pfc_write_raw_reg(sh_pfc_phys_to_virt(pfc, unlock), 32, ~data);
+}
+
+void sh_pfc_write(struct sh_pfc *pfc, u32 reg, u32 data)
+{
+       sh_pfc_unlock_reg(pfc, reg, data);
        sh_pfc_write_raw_reg(sh_pfc_phys_to_virt(pfc, reg), 32, data);
 }
 
@@ -227,11 +239,7 @@ static void sh_pfc_write_config_reg(struct sh_pfc *pfc,
        data &= mask;
        data |= value;
 
-       if (pfc->info->unlock_reg)
-               sh_pfc_write_raw_reg(
-                       sh_pfc_phys_to_virt(pfc, pfc->info->unlock_reg), 32,
-                       ~data);
-
+       sh_pfc_unlock_reg(pfc, crp->reg, data);
        sh_pfc_write_raw_reg(mapped_reg, crp->reg_width, data);
 }
 
index dc484c1..1404bd8 100644 (file)
@@ -300,7 +300,7 @@ struct sh_pfc_soc_info {
        const u16 *pinmux_data;
        unsigned int pinmux_data_size;
 
-       u32 unlock_reg;
+       u32 unlock_reg;         /* can be literal address or mask */
 };
 
 extern const struct sh_pfc_soc_info emev2_pinmux_info;