diff options
author | Ulrich Hecht <uli+renesas@fpond.eu> | 2021-01-12 19:59:07 +0300 |
---|---|---|
committer | Geert Uytterhoeven <geert+renesas@glider.be> | 2021-01-14 14:06:12 +0300 |
commit | e127ef2ed0a6099ca6ccc55ff11a812514b6aee6 (patch) | |
tree | 023829f445a619bebb33775aa540dfde7a73c240 /drivers/pinctrl/renesas | |
parent | 88a1590b1407207a51788d56746f46cbd6e6ab4e (diff) | |
download | linux-e127ef2ed0a6099ca6ccc55ff11a812514b6aee6.tar.xz |
pinctrl: renesas: Implement unlock register masks
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>
Diffstat (limited to 'drivers/pinctrl/renesas')
-rw-r--r-- | drivers/pinctrl/renesas/core.c | 28 | ||||
-rw-r--r-- | drivers/pinctrl/renesas/sh_pfc.h | 2 |
2 files changed, 19 insertions, 11 deletions
diff --git a/drivers/pinctrl/renesas/core.c b/drivers/pinctrl/renesas/core.c index 291d2c673b8f..979407f2cac6 100644 --- a/drivers/pinctrl/renesas/core.c +++ b/drivers/pinctrl/renesas/core.c @@ -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); } diff --git a/drivers/pinctrl/renesas/sh_pfc.h b/drivers/pinctrl/renesas/sh_pfc.h index dc484c13f59c..1404bd897d25 100644 --- a/drivers/pinctrl/renesas/sh_pfc.h +++ b/drivers/pinctrl/renesas/sh_pfc.h @@ -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; |