aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpiolib.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r--drivers/gpio/gpiolib.c52
1 files changed, 36 insertions, 16 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 8eba02db5608..1615cc904702 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -927,6 +927,14 @@ static int __gpiod_request(struct gpio_desc *desc, const char *label)
927 spin_lock_irqsave(&gpio_lock, flags); 927 spin_lock_irqsave(&gpio_lock, flags);
928 } 928 }
929done: 929done:
930 if (status < 0) {
931 /* Clear flags that might have been set by the caller before
932 * requesting the GPIO.
933 */
934 clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
935 clear_bit(FLAG_OPEN_DRAIN, &desc->flags);
936 clear_bit(FLAG_OPEN_SOURCE, &desc->flags);
937 }
930 spin_unlock_irqrestore(&gpio_lock, flags); 938 spin_unlock_irqrestore(&gpio_lock, flags);
931 return status; 939 return status;
932} 940}
@@ -2041,13 +2049,28 @@ struct gpio_desc *__must_check gpiod_get_optional(struct device *dev,
2041} 2049}
2042EXPORT_SYMBOL_GPL(gpiod_get_optional); 2050EXPORT_SYMBOL_GPL(gpiod_get_optional);
2043 2051
2052/**
2053 * gpiod_parse_flags - helper function to parse GPIO lookup flags
2054 * @desc: gpio to be setup
2055 * @lflags: gpio_lookup_flags - returned from of_find_gpio() or
2056 * of_get_gpio_hog()
2057 *
2058 * Set the GPIO descriptor flags based on the given GPIO lookup flags.
2059 */
2060static void gpiod_parse_flags(struct gpio_desc *desc, unsigned long lflags)
2061{
2062 if (lflags & GPIO_ACTIVE_LOW)
2063 set_bit(FLAG_ACTIVE_LOW, &desc->flags);
2064 if (lflags & GPIO_OPEN_DRAIN)
2065 set_bit(FLAG_OPEN_DRAIN, &desc->flags);
2066 if (lflags & GPIO_OPEN_SOURCE)
2067 set_bit(FLAG_OPEN_SOURCE, &desc->flags);
2068}
2044 2069
2045/** 2070/**
2046 * gpiod_configure_flags - helper function to configure a given GPIO 2071 * gpiod_configure_flags - helper function to configure a given GPIO
2047 * @desc: gpio whose value will be assigned 2072 * @desc: gpio whose value will be assigned
2048 * @con_id: function within the GPIO consumer 2073 * @con_id: function within the GPIO consumer
2049 * @lflags: gpio_lookup_flags - returned from of_find_gpio() or
2050 * of_get_gpio_hog()
2051 * @dflags: gpiod_flags - optional GPIO initialization flags 2074 * @dflags: gpiod_flags - optional GPIO initialization flags
2052 * 2075 *
2053 * Return 0 on success, -ENOENT if no GPIO has been assigned to the 2076 * Return 0 on success, -ENOENT if no GPIO has been assigned to the
@@ -2055,17 +2078,10 @@ EXPORT_SYMBOL_GPL(gpiod_get_optional);
2055 * occurred while trying to acquire the GPIO. 2078 * occurred while trying to acquire the GPIO.
2056 */ 2079 */
2057static int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id, 2080static int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
2058 unsigned long lflags, enum gpiod_flags dflags) 2081 enum gpiod_flags dflags)
2059{ 2082{
2060 int status; 2083 int status;
2061 2084
2062 if (lflags & GPIO_ACTIVE_LOW)
2063 set_bit(FLAG_ACTIVE_LOW, &desc->flags);
2064 if (lflags & GPIO_OPEN_DRAIN)
2065 set_bit(FLAG_OPEN_DRAIN, &desc->flags);
2066 if (lflags & GPIO_OPEN_SOURCE)
2067 set_bit(FLAG_OPEN_SOURCE, &desc->flags);
2068
2069 /* No particular flag request, return here... */ 2085 /* No particular flag request, return here... */
2070 if (!(dflags & GPIOD_FLAGS_BIT_DIR_SET)) { 2086 if (!(dflags & GPIOD_FLAGS_BIT_DIR_SET)) {
2071 pr_debug("no flags found for %s\n", con_id); 2087 pr_debug("no flags found for %s\n", con_id);
@@ -2132,11 +2148,13 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
2132 return desc; 2148 return desc;
2133 } 2149 }
2134 2150
2151 gpiod_parse_flags(desc, lookupflags);
2152
2135 status = gpiod_request(desc, con_id); 2153 status = gpiod_request(desc, con_id);
2136 if (status < 0) 2154 if (status < 0)
2137 return ERR_PTR(status); 2155 return ERR_PTR(status);
2138 2156
2139 status = gpiod_configure_flags(desc, con_id, lookupflags, flags); 2157 status = gpiod_configure_flags(desc, con_id, flags);
2140 if (status < 0) { 2158 if (status < 0) {
2141 dev_dbg(dev, "setup of GPIO %s failed\n", con_id); 2159 dev_dbg(dev, "setup of GPIO %s failed\n", con_id);
2142 gpiod_put(desc); 2160 gpiod_put(desc);
@@ -2190,14 +2208,14 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
2190 if (IS_ERR(desc)) 2208 if (IS_ERR(desc))
2191 return desc; 2209 return desc;
2192 2210
2193 ret = gpiod_request(desc, NULL);
2194 if (ret)
2195 return ERR_PTR(ret);
2196
2197 /* Only value flag can be set from both DT and ACPI is active_low */ 2211 /* Only value flag can be set from both DT and ACPI is active_low */
2198 if (active_low) 2212 if (active_low)
2199 set_bit(FLAG_ACTIVE_LOW, &desc->flags); 2213 set_bit(FLAG_ACTIVE_LOW, &desc->flags);
2200 2214
2215 ret = gpiod_request(desc, NULL);
2216 if (ret)
2217 return ERR_PTR(ret);
2218
2201 return desc; 2219 return desc;
2202} 2220}
2203EXPORT_SYMBOL_GPL(fwnode_get_named_gpiod); 2221EXPORT_SYMBOL_GPL(fwnode_get_named_gpiod);
@@ -2250,6 +2268,8 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
2250 chip = gpiod_to_chip(desc); 2268 chip = gpiod_to_chip(desc);
2251 hwnum = gpio_chip_hwgpio(desc); 2269 hwnum = gpio_chip_hwgpio(desc);
2252 2270
2271 gpiod_parse_flags(desc, lflags);
2272
2253 local_desc = gpiochip_request_own_desc(chip, hwnum, name); 2273 local_desc = gpiochip_request_own_desc(chip, hwnum, name);
2254 if (IS_ERR(local_desc)) { 2274 if (IS_ERR(local_desc)) {
2255 pr_err("requesting hog GPIO %s (chip %s, offset %d) failed\n", 2275 pr_err("requesting hog GPIO %s (chip %s, offset %d) failed\n",
@@ -2257,7 +2277,7 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
2257 return PTR_ERR(local_desc); 2277 return PTR_ERR(local_desc);
2258 } 2278 }
2259 2279
2260 status = gpiod_configure_flags(desc, name, lflags, dflags); 2280 status = gpiod_configure_flags(desc, name, dflags);
2261 if (status < 0) { 2281 if (status < 0) {
2262 pr_err("setup of hog GPIO %s (chip %s, offset %d) failed\n", 2282 pr_err("setup of hog GPIO %s (chip %s, offset %d) failed\n",
2263 name, chip->label, hwnum); 2283 name, chip->label, hwnum);