pinctrl: bcm2835: Only return non-GPIOs to inputs
authorPhil Elwell <phil@raspberrypi.com>
Wed, 30 Mar 2022 08:48:41 +0000 (09:48 +0100)
committerPhil Elwell <phil@raspberrypi.com>
Wed, 30 Mar 2022 08:48:41 +0000 (09:48 +0100)
Allowing GPIO state to persist allows the use of gpioset to control
GPIO levels without having to use the --mode=wait feature.

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
drivers/pinctrl/bcm/pinctrl-bcm2835.c

index a68f440..358fc1c 100644 (file)
@@ -892,9 +892,12 @@ static int bcm2835_pmx_free(struct pinctrl_dev *pctldev,
                unsigned offset)
 {
        struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+       enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, offset);
+
+       /* Return non-GPIOs to GPIO_IN */
+       if (fsel != BCM2835_FSEL_GPIO_IN && fsel != BCM2835_FSEL_GPIO_OUT)
+               bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN);
 
-       /* disable by setting to GPIO_IN */
-       bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN);
        return 0;
 }
 
@@ -936,10 +939,7 @@ static void bcm2835_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
                struct pinctrl_gpio_range *range,
                unsigned offset)
 {
-       struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
-
-       /* disable by setting to GPIO_IN */
-       bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN);
+       (void)bcm2835_pmx_free(pctldev, offset);
 }
 
 static int bcm2835_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,