[PATCH 3/3] pinctrl: s32cc: add update and overwrite options when setting pinconf

From: Andrei Stefanescu
Date: Tue Jul 23 2024 - 09:21:46 EST


The previous pinconf settings(made by the bootloader) need to be
overwritten when configuring the pinctrl of a driver during the boot
process.

Configuring the bias of a GPIO at runtime (e.g. pull-up) needs to
preserve the other settings unaltered.

This patch introduces changes to differentiate between the two cases.

Signed-off-by: Radu Pirea <radu-nicolae.pirea@xxxxxxx>
Signed-off-by: Florin Buica <florin.buica@xxxxxxx>
Signed-off-by: Andrei Stefanescu <andrei.stefanescu@xxxxxxxxxxx>
---
drivers/pinctrl/nxp/pinctrl-s32cc.c | 30 ++++++++++++++++++++++-------
1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/drivers/pinctrl/nxp/pinctrl-s32cc.c b/drivers/pinctrl/nxp/pinctrl-s32cc.c
index 48d9d6df953f..9c730f2ca172 100644
--- a/drivers/pinctrl/nxp/pinctrl-s32cc.c
+++ b/drivers/pinctrl/nxp/pinctrl-s32cc.c
@@ -39,6 +39,11 @@
#define S32_MSCR_ODE BIT(20)
#define S32_MSCR_OBE BIT(21)

+enum s32_write_type {
+ S32_PINCONF_UPDATE_ONLY,
+ S32_PINCONF_OVERWRITE,
+};
+
static struct regmap_config s32_regmap_config = {
.reg_bits = 32,
.val_bits = 32,
@@ -557,10 +562,11 @@ static int s32_parse_pincfg(unsigned long pincfg, unsigned int *mask,
return 0;
}

-static int s32_pinconf_mscr_update(struct pinctrl_dev *pctldev,
+static int s32_pinconf_mscr_write(struct pinctrl_dev *pctldev,
unsigned int pin_id,
unsigned long *configs,
- unsigned int num_configs)
+ unsigned int num_configs,
+ enum s32_write_type write_type)
{
struct s32_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
unsigned int config = 0, mask = 0;
@@ -579,10 +585,20 @@ static int s32_pinconf_mscr_update(struct pinctrl_dev *pctldev,
return ret;
}

+ /* If the MSCR configuration has to be written,
+ * the SSS field should not be touched.
+ */
+ if (write_type == S32_PINCONF_OVERWRITE)
+ mask = (unsigned int)~S32_MSCR_SSS_MASK;
+
if (!config && !mask)
return 0;

- dev_dbg(ipctl->dev, "update: pin %u cfg 0x%x\n", pin_id, config);
+ if (write_type == S32_PINCONF_OVERWRITE)
+ dev_dbg(ipctl->dev, "set: pin %u cfg 0x%x\n", pin_id, config);
+ else
+ dev_dbg(ipctl->dev, "update: pin %u cfg 0x%x\n", pin_id,
+ config);

return s32_regmap_update(pctldev, pin_id, mask, config);
}
@@ -598,8 +614,8 @@ static int s32_pinconf_set(struct pinctrl_dev *pctldev,
unsigned int pin_id, unsigned long *configs,
unsigned int num_configs)
{
- return s32_pinconf_mscr_update(pctldev, pin_id, configs,
- num_configs);
+ return s32_pinconf_mscr_write(pctldev, pin_id, configs,
+ num_configs, S32_PINCONF_UPDATE_ONLY);
}

static int s32_pconf_group_set(struct pinctrl_dev *pctldev, unsigned int selector,
@@ -612,8 +628,8 @@ static int s32_pconf_group_set(struct pinctrl_dev *pctldev, unsigned int selecto

grp = &info->groups[selector];
for (i = 0; i < grp->data.npins; i++) {
- ret = s32_pinconf_mscr_update(pctldev, grp->data.pins[i],
- configs, num_configs);
+ ret = s32_pinconf_mscr_write(pctldev, grp->data.pins[i],
+ configs, num_configs, S32_PINCONF_OVERWRITE);
if (ret)
return ret;
}
--
2.45.2