]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge tag 'sh-pfc-for-v5.4-tag2' of https://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Walleij <linus.walleij@linaro.org>
Fri, 23 Aug 2019 21:07:04 +0000 (23:07 +0200)
committerLinus Walleij <linus.walleij@linaro.org>
Fri, 23 Aug 2019 21:07:04 +0000 (23:07 +0200)
pinctrl: sh-pfc: Updates for v5.4 (take two)

  - Support switching between function and gpio at runtime,
  - Small fixes and cleanups.

drivers/pinctrl/pinctrl-rza1.c
drivers/pinctrl/pinctrl-rza2.c
drivers/pinctrl/sh-pfc/gpio.c
drivers/pinctrl/sh-pfc/pinctrl.c

index 68aeefe29144822f8a489facb04be4c3ae84b5e6..017fc6b3e27ec80e26a24ac0cebb9ab3212f844c 100644 (file)
@@ -866,8 +866,10 @@ static int rza1_dt_node_pin_count(struct device_node *np)
        npins = 0;
        for_each_child_of_node(np, child) {
                of_pins = of_find_property(child, "pinmux", NULL);
-               if (!of_pins)
+               if (!of_pins) {
+                       of_node_put(child);
                        return -EINVAL;
+               }
 
                npins += of_pins->length / sizeof(u32);
        }
@@ -1025,8 +1027,10 @@ static int rza1_dt_node_to_map(struct pinctrl_dev *pctldev,
                for_each_child_of_node(np, child) {
                        ret = rza1_parse_pinmux_node(rza1_pctl, child, mux_conf,
                                                     grpin);
-                       if (ret < 0)
+                       if (ret < 0) {
+                               of_node_put(child);
                                return ret;
+                       }
 
                        grpin += ret;
                        mux_conf += ret;
@@ -1272,8 +1276,10 @@ static int rza1_gpio_register(struct rza1_pinctrl *rza1_pctl)
 
                ret = rza1_parse_gpiochip(rza1_pctl, child, &gpio_chips[i],
                                          &gpio_ranges[i]);
-               if (ret)
+               if (ret) {
+                       of_node_put(child);
                        return ret;
+               }
 
                ++i;
        }
index 5b951c7422ccb5c4b24e3deafd4a13ea5eccfe6a..3be1d833bf25e13b3edc326cf7023319fe27d9c1 100644 (file)
@@ -11,7 +11,8 @@
  */
 
 #include <linux/bitops.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
+#include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/pinctrl/pinmux.h>
@@ -115,7 +116,7 @@ static void rza2_pin_to_gpio(void __iomem *pfc_base, unsigned int offset,
        mask16 = RZA2_PDR_MASK << (pin * 2);
        reg16 &= ~mask16;
 
-       if (dir == GPIOF_DIR_IN)
+       if (dir)
                reg16 |= RZA2_PDR_INPUT << (pin * 2);   /* pin as input */
        else
                reg16 |= RZA2_PDR_OUTPUT << (pin * 2);  /* pin as output */
@@ -134,18 +135,18 @@ static int rza2_chip_get_direction(struct gpio_chip *chip, unsigned int offset)
        reg16 = (reg16 >> (pin * 2)) & RZA2_PDR_MASK;
 
        if (reg16 == RZA2_PDR_OUTPUT)
-               return GPIOF_DIR_OUT;
+               return 0;
 
        if (reg16 == RZA2_PDR_INPUT)
-               return GPIOF_DIR_IN;
+               return 1;
 
        /*
         * This GPIO controller has a default Hi-Z state that is not input or
         * output, so force the pin to input now.
         */
-       rza2_pin_to_gpio(priv->base, offset, GPIOF_DIR_IN);
+       rza2_pin_to_gpio(priv->base, offset, 1);
 
-       return GPIOF_DIR_IN;
+       return 1;
 }
 
 static int rza2_chip_direction_input(struct gpio_chip *chip,
@@ -153,7 +154,7 @@ static int rza2_chip_direction_input(struct gpio_chip *chip,
 {
        struct rza2_pinctrl_priv *priv = gpiochip_get_data(chip);
 
-       rza2_pin_to_gpio(priv->base, offset, GPIOF_DIR_IN);
+       rza2_pin_to_gpio(priv->base, offset, 1);
 
        return 0;
 }
@@ -191,7 +192,7 @@ static int rza2_chip_direction_output(struct gpio_chip *chip,
        struct rza2_pinctrl_priv *priv = gpiochip_get_data(chip);
 
        rza2_chip_set(chip, offset, val);
-       rza2_pin_to_gpio(priv->base, offset, GPIOF_DIR_OUT);
+       rza2_pin_to_gpio(priv->base, offset, 0);
 
        return 0;
 }
index 64c09aa374ae011f2b46364d0c6b8db22697b375..5a55b8da7919520e42807215a7329f506e6f35e2 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <linux/device.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/pinctrl/consumer.h>
index 2824be4eb887d5bb07fdc05730ceca536374d6fb..99f4ebd69861477bf1d7b5c680557253af2758b3 100644 (file)
@@ -26,7 +26,9 @@
 #include "../pinconf.h"
 
 struct sh_pfc_pin_config {
-       u32 type;
+       unsigned int mux_mark;
+       bool mux_set;
+       bool gpio_enabled;
 };
 
 struct sh_pfc_pinctrl {
@@ -355,16 +357,25 @@ static int sh_pfc_func_set_mux(struct pinctrl_dev *pctldev, unsigned selector,
                int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]);
                struct sh_pfc_pin_config *cfg = &pmx->configs[idx];
 
-               if (cfg->type != PINMUX_TYPE_NONE) {
-                       ret = -EBUSY;
+               /*
+                * This driver cannot manage both gpio and mux when the gpio
+                * pin is already enabled. So, this function fails.
+                */
+               if (cfg->gpio_enabled)
+                       return -EBUSY;
+
+               ret = sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION);
+               if (ret < 0)
                        goto done;
-               }
        }
 
+       /* All group pins are configured, mark the pins as mux_set */
        for (i = 0; i < grp->nr_pins; ++i) {
-               ret = sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION);
-               if (ret < 0)
-                       break;
+               int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]);
+               struct sh_pfc_pin_config *cfg = &pmx->configs[idx];
+
+               cfg->mux_set = true;
+               cfg->mux_mark = grp->mux[i];
        }
 
 done:
@@ -385,14 +396,6 @@ static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev,
 
        spin_lock_irqsave(&pfc->lock, flags);
 
-       if (cfg->type != PINMUX_TYPE_NONE) {
-               dev_err(pfc->dev,
-                       "Pin %u is busy, can't configure it as GPIO.\n",
-                       offset);
-               ret = -EBUSY;
-               goto done;
-       }
-
        if (!pfc->gpio) {
                /* If GPIOs are handled externally the pin mux type need to be
                 * set to GPIO here.
@@ -404,7 +407,7 @@ static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev,
                        goto done;
        }
 
-       cfg->type = PINMUX_TYPE_GPIO;
+       cfg->gpio_enabled = true;
 
        ret = 0;
 
@@ -425,7 +428,10 @@ static void sh_pfc_gpio_disable_free(struct pinctrl_dev *pctldev,
        unsigned long flags;
 
        spin_lock_irqsave(&pfc->lock, flags);
-       cfg->type = PINMUX_TYPE_NONE;
+       cfg->gpio_enabled = false;
+       /* If mux is already set, this configures it here */
+       if (cfg->mux_set)
+               sh_pfc_config_mux(pfc, cfg->mux_mark, PINMUX_TYPE_FUNCTION);
        spin_unlock_irqrestore(&pfc->lock, flags);
 }
 
@@ -438,7 +444,6 @@ static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev,
        int new_type = input ? PINMUX_TYPE_INPUT : PINMUX_TYPE_OUTPUT;
        int idx = sh_pfc_get_pin_index(pfc, offset);
        const struct sh_pfc_pin *pin = &pfc->info->pins[idx];
-       struct sh_pfc_pin_config *cfg = &pmx->configs[idx];
        unsigned long flags;
        unsigned int dir;
        int ret;
@@ -458,8 +463,6 @@ static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev,
        if (ret < 0)
                goto done;
 
-       cfg->type = new_type;
-
 done:
        spin_unlock_irqrestore(&pfc->lock, flags);
        return ret;
@@ -782,13 +785,11 @@ static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx)
 
        for (i = 0; i < pfc->info->nr_pins; ++i) {
                const struct sh_pfc_pin *info = &pfc->info->pins[i];
-               struct sh_pfc_pin_config *cfg = &pmx->configs[i];
                struct pinctrl_pin_desc *pin = &pmx->pins[i];
 
                /* If the pin number is equal to -1 all pins are considered */
                pin->number = info->pin != (u16)-1 ? info->pin : i;
                pin->name = info->name;
-               cfg->type = PINMUX_TYPE_NONE;
        }
 
        return 0;