|
@@ -927,6 +927,14 @@ static int __gpiod_request(struct gpio_desc *desc, const char *label)
|
|
|
spin_lock_irqsave(&gpio_lock, flags);
|
|
|
}
|
|
|
done:
|
|
|
+ if (status < 0) {
|
|
|
+ /* Clear flags that might have been set by the caller before
|
|
|
+ * requesting the GPIO.
|
|
|
+ */
|
|
|
+ clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
|
|
|
+ clear_bit(FLAG_OPEN_DRAIN, &desc->flags);
|
|
|
+ clear_bit(FLAG_OPEN_SOURCE, &desc->flags);
|
|
|
+ }
|
|
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
|
|
return status;
|
|
|
}
|
|
@@ -2041,13 +2049,28 @@ struct gpio_desc *__must_check gpiod_get_optional(struct device *dev,
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(gpiod_get_optional);
|
|
|
|
|
|
+/**
|
|
|
+ * gpiod_parse_flags - helper function to parse GPIO lookup flags
|
|
|
+ * @desc: gpio to be setup
|
|
|
+ * @lflags: gpio_lookup_flags - returned from of_find_gpio() or
|
|
|
+ * of_get_gpio_hog()
|
|
|
+ *
|
|
|
+ * Set the GPIO descriptor flags based on the given GPIO lookup flags.
|
|
|
+ */
|
|
|
+static void gpiod_parse_flags(struct gpio_desc *desc, unsigned long lflags)
|
|
|
+{
|
|
|
+ if (lflags & GPIO_ACTIVE_LOW)
|
|
|
+ set_bit(FLAG_ACTIVE_LOW, &desc->flags);
|
|
|
+ if (lflags & GPIO_OPEN_DRAIN)
|
|
|
+ set_bit(FLAG_OPEN_DRAIN, &desc->flags);
|
|
|
+ if (lflags & GPIO_OPEN_SOURCE)
|
|
|
+ set_bit(FLAG_OPEN_SOURCE, &desc->flags);
|
|
|
+}
|
|
|
|
|
|
/**
|
|
|
* gpiod_configure_flags - helper function to configure a given GPIO
|
|
|
* @desc: gpio whose value will be assigned
|
|
|
* @con_id: function within the GPIO consumer
|
|
|
- * @lflags: gpio_lookup_flags - returned from of_find_gpio() or
|
|
|
- * of_get_gpio_hog()
|
|
|
* @dflags: gpiod_flags - optional GPIO initialization flags
|
|
|
*
|
|
|
* Return 0 on success, -ENOENT if no GPIO has been assigned to the
|
|
@@ -2055,17 +2078,10 @@ EXPORT_SYMBOL_GPL(gpiod_get_optional);
|
|
|
* occurred while trying to acquire the GPIO.
|
|
|
*/
|
|
|
static int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
|
|
|
- unsigned long lflags, enum gpiod_flags dflags)
|
|
|
+ enum gpiod_flags dflags)
|
|
|
{
|
|
|
int status;
|
|
|
|
|
|
- if (lflags & GPIO_ACTIVE_LOW)
|
|
|
- set_bit(FLAG_ACTIVE_LOW, &desc->flags);
|
|
|
- if (lflags & GPIO_OPEN_DRAIN)
|
|
|
- set_bit(FLAG_OPEN_DRAIN, &desc->flags);
|
|
|
- if (lflags & GPIO_OPEN_SOURCE)
|
|
|
- set_bit(FLAG_OPEN_SOURCE, &desc->flags);
|
|
|
-
|
|
|
/* No particular flag request, return here... */
|
|
|
if (!(dflags & GPIOD_FLAGS_BIT_DIR_SET)) {
|
|
|
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,
|
|
|
return desc;
|
|
|
}
|
|
|
|
|
|
+ gpiod_parse_flags(desc, lookupflags);
|
|
|
+
|
|
|
status = gpiod_request(desc, con_id);
|
|
|
if (status < 0)
|
|
|
return ERR_PTR(status);
|
|
|
|
|
|
- status = gpiod_configure_flags(desc, con_id, lookupflags, flags);
|
|
|
+ status = gpiod_configure_flags(desc, con_id, flags);
|
|
|
if (status < 0) {
|
|
|
dev_dbg(dev, "setup of GPIO %s failed\n", con_id);
|
|
|
gpiod_put(desc);
|
|
@@ -2190,14 +2208,14 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
|
|
|
if (IS_ERR(desc))
|
|
|
return desc;
|
|
|
|
|
|
- ret = gpiod_request(desc, NULL);
|
|
|
- if (ret)
|
|
|
- return ERR_PTR(ret);
|
|
|
-
|
|
|
/* Only value flag can be set from both DT and ACPI is active_low */
|
|
|
if (active_low)
|
|
|
set_bit(FLAG_ACTIVE_LOW, &desc->flags);
|
|
|
|
|
|
+ ret = gpiod_request(desc, NULL);
|
|
|
+ if (ret)
|
|
|
+ return ERR_PTR(ret);
|
|
|
+
|
|
|
return desc;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(fwnode_get_named_gpiod);
|
|
@@ -2250,6 +2268,8 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
|
|
|
chip = gpiod_to_chip(desc);
|
|
|
hwnum = gpio_chip_hwgpio(desc);
|
|
|
|
|
|
+ gpiod_parse_flags(desc, lflags);
|
|
|
+
|
|
|
local_desc = gpiochip_request_own_desc(chip, hwnum, name);
|
|
|
if (IS_ERR(local_desc)) {
|
|
|
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,
|
|
|
return PTR_ERR(local_desc);
|
|
|
}
|
|
|
|
|
|
- status = gpiod_configure_flags(desc, name, lflags, dflags);
|
|
|
+ status = gpiod_configure_flags(desc, name, dflags);
|
|
|
if (status < 0) {
|
|
|
pr_err("setup of hog GPIO %s (chip %s, offset %d) failed\n",
|
|
|
name, chip->label, hwnum);
|