pinctrl: s32cc: add update and overwrite options when setting pinconf
authorAndrei Stefanescu <andrei.stefanescu@oss.nxp.com>
Tue, 23 Jul 2024 13:18:32 +0000 (16:18 +0300)
committerLinus Walleij <linus.walleij@linaro.org>
Mon, 5 Aug 2024 08:17:43 +0000 (10:17 +0200)
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@nxp.com>
Signed-off-by: Florin Buica <florin.buica@nxp.com>
Signed-off-by: Andrei Stefanescu <andrei.stefanescu@oss.nxp.com>
Link: https://lore.kernel.org/20240723131832.1171036-4-andrei.stefanescu@oss.nxp.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/pinctrl/nxp/pinctrl-s32cc.c

index f0430354e8321f56081c3dd8d8bb673d0ce7bc14..501eb296c76050aa05386c51ef6ae0f97d4c76c3 100644 (file)
 #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,
@@ -552,10 +557,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;
@@ -574,10 +580,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);
 }
@@ -593,8 +609,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,
@@ -607,8 +623,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;
        }