From 1d7765ba15aca68f3bc52f59434c1c34855bbb54 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 26 Mar 2019 17:21:14 +0200 Subject: gpiolib: Don't WARN on gpiod_put() for optional GPIO In case of debug and optional GPIO requested, the gpiod_put() is not aware of and will WARN, which is not the case. Make gpiod_put() NULL-aware to keep silent for optional GPIOs. Signed-off-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpio/gpiolib.c') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 144af0733581..36445e24ee89 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -4616,7 +4616,8 @@ EXPORT_SYMBOL_GPL(gpiod_get_array_optional); */ void gpiod_put(struct gpio_desc *desc) { - gpiod_free(desc); + if (desc) + gpiod_free(desc); } EXPORT_SYMBOL_GPL(gpiod_put); -- cgit v1.2.3 From 7e9fa3c9d3e3d4f5f13f66383666cd0f32ef3b81 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 28 Mar 2019 14:13:49 +0100 Subject: gpio: Remove obsolete comment about gpiochip_free_hogs() usage gpiochip_free_hogs() was always called from gpiochip_remove(), not of_gpiochip_remove(). It is now also called from the failure patch in gpiochip_add_data_with_key(). Fixes: f625d4601759f1cf ("gpio: add GPIO hogging mechanism") Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpio/gpiolib.c') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 144af0733581..f41ad889124f 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -4445,8 +4445,6 @@ int gpiod_hog(struct gpio_desc *desc, const char *name, /** * gpiochip_free_hogs - Scan gpio-controller chip and release GPIO hog * @chip: gpio chip to act on - * - * This is only used by of_gpiochip_remove to free hogged gpios */ static void gpiochip_free_hogs(struct gpio_chip *chip) { -- cgit v1.2.3 From 542f36159f9466faf4bd8d776fdc79f07c048c42 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 14 Mar 2019 20:32:50 +0100 Subject: gpio: Set proper argument value to set_config The gpio_set_config function creates a pinconf configuration for a given pinc_config_param. However, it always uses an arg of 0, which might not be a valid argument for a given param. A good example of that would be the bias parameters, where 0 means that the pull up or down resistor is null, and the pin is directly connected to VCC/GND. The framework uses in some other places the value 1 as a default argument to enable the pull resistor, so let's use the same one here. Signed-off-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers/gpio/gpiolib.c') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index f41ad889124f..e5c3c4bff6fe 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2565,8 +2565,20 @@ EXPORT_SYMBOL_GPL(gpiochip_free_own_desc); static int gpio_set_config(struct gpio_chip *gc, unsigned offset, enum pin_config_param mode) { - unsigned long config = { PIN_CONF_PACKED(mode, 0) }; + unsigned long config; + unsigned arg; + switch (mode) { + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_BIAS_PULL_UP: + arg = 1; + break; + + default: + arg = 0; + } + + config = PIN_CONF_PACKED(mode, arg); return gc->set_config ? gc->set_config(gc, offset, config) : -ENOTSUPP; } -- cgit v1.2.3 From fed7026adc7c3a67f992d28d7a5309ff749d3776 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 10 Apr 2019 18:39:16 +0300 Subject: gpiolib: Make use of enum gpio_lookup_flags consistent The library uses enum gpio_lookup_flags to define the possible characteristics of GPIO pin. Since enumerator listed only individual bits the common use of it is in a form of a bitmask of gpio_lookup_flags GPIO_* values. The more correct type for this is unsigned long. Due to above convert all users to use unsigned long instead of enum gpio_lookup_flags except enumerator definition. While here, make field and parameter descriptions consistent as well. Suggested-by: Mika Westerberg Signed-off-by: Andy Shevchenko Reviewed-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-acpi.c | 14 +++++++++----- drivers/gpio/gpiolib-of.c | 11 +++++------ drivers/gpio/gpiolib.c | 13 ++++++------- drivers/gpio/gpiolib.h | 9 ++++----- include/linux/gpio/machine.h | 8 ++++---- 5 files changed, 28 insertions(+), 27 deletions(-) (limited to 'drivers/gpio/gpiolib.c') diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index e9ddf66f2d14..962bdd89cd8f 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -696,7 +696,7 @@ struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id, unsigned int idx, enum gpiod_flags *dflags, - enum gpio_lookup_flags *lookupflags) + unsigned long *lookupflags) { struct acpi_device *adev = ACPI_COMPANION(dev); struct acpi_gpio_info info; @@ -995,9 +995,12 @@ static void acpi_gpiochip_free_regions(struct acpi_gpio_chip *achip) } } -static struct gpio_desc *acpi_gpiochip_parse_own_gpio( - struct acpi_gpio_chip *achip, struct fwnode_handle *fwnode, - const char **name, unsigned int *lflags, unsigned int *dflags) +static struct gpio_desc * +acpi_gpiochip_parse_own_gpio(struct acpi_gpio_chip *achip, + struct fwnode_handle *fwnode, + const char **name, + unsigned long *lflags, + unsigned int *dflags) { struct gpio_chip *chip = achip->chip; struct gpio_desc *desc; @@ -1040,7 +1043,8 @@ static void acpi_gpiochip_scan_gpios(struct acpi_gpio_chip *achip) struct fwnode_handle *fwnode; device_for_each_child_node(chip->parent, fwnode) { - unsigned int lflags, dflags; + unsigned long lflags; + unsigned int dflags; struct gpio_desc *desc; const char *name; int ret; diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 3a6bb53d89df..c5547df4f6cd 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -287,8 +287,7 @@ static struct gpio_desc *of_find_regulator_gpio(struct device *dev, const char * } struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, - unsigned int idx, - enum gpio_lookup_flags *flags) + unsigned int idx, unsigned long *flags) { char prop_name[32]; /* 32 is max size of property name */ enum of_gpio_flags of_flags; @@ -361,8 +360,8 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, * @chip: GPIO chip whose hog is parsed * @idx: Index of the GPIO to parse * @name: GPIO line name - * @lflags: gpio_lookup_flags - returned from of_find_gpio() or - * of_parse_own_gpio() + * @lflags: bitmask of gpio_lookup_flags GPIO_* values - returned from + * of_find_gpio() or of_parse_own_gpio() * @dflags: gpiod_flags - optional GPIO initialization flags * * Returns GPIO descriptor to use with Linux GPIO API, or one of the errno @@ -371,7 +370,7 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, static struct gpio_desc *of_parse_own_gpio(struct device_node *np, struct gpio_chip *chip, unsigned int idx, const char **name, - enum gpio_lookup_flags *lflags, + unsigned long *lflags, enum gpiod_flags *dflags) { struct device_node *chip_np; @@ -444,7 +443,7 @@ static int of_gpiochip_scan_gpios(struct gpio_chip *chip) struct gpio_desc *desc = NULL; struct device_node *np; const char *name; - enum gpio_lookup_flags lflags; + unsigned long lflags; enum gpiod_flags dflags; unsigned int i; int ret; diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 982845e8212c..e9909c07517b 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -3923,8 +3923,7 @@ found: } static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id, - unsigned int idx, - enum gpio_lookup_flags *flags) + unsigned int idx, unsigned long *flags) { struct gpio_desc *desc = ERR_PTR(-ENOENT); struct gpiod_lookup_table *table; @@ -4080,8 +4079,8 @@ EXPORT_SYMBOL_GPL(gpiod_get_optional); * 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() + * @lflags: bitmask of gpio_lookup_flags GPIO_* values - 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 @@ -4163,9 +4162,9 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, unsigned int idx, enum gpiod_flags flags) { + unsigned long lookupflags = 0; struct gpio_desc *desc = NULL; int status; - enum gpio_lookup_flags lookupflags = 0; /* Maybe we have a device name, maybe not */ const char *devname = dev ? dev_name(dev) : "?"; @@ -4403,8 +4402,8 @@ EXPORT_SYMBOL_GPL(gpiod_get_index_optional); * gpiod_hog - Hog the specified GPIO desc given the provided flags * @desc: gpio whose value will be assigned * @name: gpio line name - * @lflags: gpio_lookup_flags - returned from of_find_gpio() or - * of_get_gpio_hog() + * @lflags: bitmask of gpio_lookup_flags GPIO_* values - returned from + * of_find_gpio() or of_get_gpio_hog() * @dflags: gpiod_flags - optional GPIO initialization flags */ int gpiod_hog(struct gpio_desc *desc, const char *name, diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 078ab17b96bf..5dbfce616ae1 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -17,7 +17,6 @@ #include enum of_gpio_flags; -enum gpio_lookup_flags; struct acpi_device; /** @@ -95,7 +94,7 @@ static __maybe_unused const char * const gpio_suffixes[] = { "gpios", "gpio" }; struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, unsigned int idx, - enum gpio_lookup_flags *flags); + unsigned long *lookupflags); struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np, const char *list_name, int index, enum of_gpio_flags *flags); int of_gpiochip_add(struct gpio_chip *gc); @@ -104,7 +103,7 @@ void of_gpiochip_remove(struct gpio_chip *gc); static inline struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, unsigned int idx, - enum gpio_lookup_flags *flags) + unsigned long *lookupflags) { return ERR_PTR(-ENOENT); } @@ -131,7 +130,7 @@ struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id, unsigned int idx, enum gpiod_flags *dflags, - enum gpio_lookup_flags *lookupflags); + unsigned long *lookupflags); struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode, const char *propname, int index, struct acpi_gpio_info *info); @@ -158,7 +157,7 @@ acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, struct acpi_gpio_info *inf static inline struct gpio_desc * acpi_find_gpio(struct device *dev, const char *con_id, unsigned int idx, enum gpiod_flags *dflags, - enum gpio_lookup_flags *lookupflags) + unsigned long *lookupflags) { return ERR_PTR(-ENOENT); } diff --git a/include/linux/gpio/machine.h b/include/linux/gpio/machine.h index a0a981676490..dad392158550 100644 --- a/include/linux/gpio/machine.h +++ b/include/linux/gpio/machine.h @@ -22,7 +22,7 @@ enum gpio_lookup_flags { * @chip_hwnum: hardware number (i.e. relative to the chip) of the GPIO * @con_id: name of the GPIO from the device's point of view * @idx: index of the GPIO in case several GPIOs share the same name - * @flags: mask of GPIO_* values + * @flags: bitmask of gpio_lookup_flags GPIO_* values * * gpiod_lookup is a lookup table for associating GPIOs to specific devices and * functions using platform data. @@ -32,7 +32,7 @@ struct gpiod_lookup { u16 chip_hwnum; const char *con_id; unsigned int idx; - enum gpio_lookup_flags flags; + unsigned long flags; }; struct gpiod_lookup_table { @@ -46,7 +46,7 @@ struct gpiod_lookup_table { * @chip_label: name of the chip the GPIO belongs to * @chip_hwnum: hardware number (i.e. relative to the chip) of the GPIO * @line_name: consumer name for the hogged line - * @lflags: mask of GPIO lookup flags + * @lflags: bitmask of gpio_lookup_flags GPIO_* values * @dflags: GPIO flags used to specify the direction and value */ struct gpiod_hog { @@ -54,7 +54,7 @@ struct gpiod_hog { const char *chip_label; u16 chip_hwnum; const char *line_name; - enum gpio_lookup_flags lflags; + unsigned long lflags; int dflags; }; -- cgit v1.2.3 From 2d6c06f5a4094ab4ea15b63af72d2dab74e9415a Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 10 Apr 2019 18:39:17 +0300 Subject: gpiolib: Introduce GPIO_LOOKUP_FLAGS_DEFAULT Since GPIO library operates with enumerator when it's subject to handle the GPIO lookup flags, it will be better to clearly see what default means. Thus, introduce GPIO_LOOKUP_FLAGS_DEFAULT entry to describe the default assumptions. While here, replace 0 by newly introduced constant. Signed-off-by: Andy Shevchenko Reviewed-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-acpi.c | 5 +++-- drivers/gpio/gpiolib-of.c | 2 +- drivers/gpio/gpiolib.c | 9 +++++---- include/linux/gpio/machine.h | 2 ++ 4 files changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers/gpio/gpiolib.c') diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 962bdd89cd8f..6ee929d90a6a 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -819,6 +819,7 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) return PTR_ERR(desc); if (info.gpioint && idx++ == index) { + unsigned long lflags = GPIO_LOOKUP_FLAGS_DEFAULT; char label[32]; int irq; @@ -830,7 +831,7 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) return irq; snprintf(label, sizeof(label), "GpioInt() %d", index); - ret = gpiod_configure_flags(desc, label, 0, info.flags); + ret = gpiod_configure_flags(desc, label, lflags, info.flags); if (ret < 0) return ret; @@ -1007,7 +1008,7 @@ acpi_gpiochip_parse_own_gpio(struct acpi_gpio_chip *achip, u32 gpios[2]; int ret; - *lflags = 0; + *lflags = GPIO_LOOKUP_FLAGS_DEFAULT; *dflags = 0; *name = NULL; diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index c5547df4f6cd..aec7bd86ae7e 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -386,7 +386,7 @@ static struct gpio_desc *of_parse_own_gpio(struct device_node *np, return ERR_PTR(-EINVAL); xlate_flags = 0; - *lflags = 0; + *lflags = GPIO_LOOKUP_FLAGS_DEFAULT; *dflags = 0; ret = of_property_read_u32(chip_np, "#gpio-cells", &tmp); diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index e9909c07517b..b8e4c9cd7b9e 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2515,6 +2515,7 @@ struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *chip, u16 hwnum, const char *label, enum gpiod_flags flags) { + unsigned long lflags = GPIO_LOOKUP_FLAGS_DEFAULT; struct gpio_desc *desc = gpiochip_get_desc(chip, hwnum); int err; @@ -2527,7 +2528,7 @@ struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *chip, u16 hwnum, if (err < 0) return ERR_PTR(err); - err = gpiod_configure_flags(desc, label, 0, flags); + err = gpiod_configure_flags(desc, label, lflags, flags); if (err) { chip_err(chip, "setup of own GPIO %s failed\n", label); gpiod_free_commit(desc); @@ -4162,7 +4163,7 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, unsigned int idx, enum gpiod_flags flags) { - unsigned long lookupflags = 0; + unsigned long lookupflags = GPIO_LOOKUP_FLAGS_DEFAULT; struct gpio_desc *desc = NULL; int status; /* Maybe we have a device name, maybe not */ @@ -4249,8 +4250,8 @@ struct gpio_desc *gpiod_get_from_of_node(struct device_node *node, enum gpiod_flags dflags, const char *label) { + unsigned long lflags = GPIO_LOOKUP_FLAGS_DEFAULT; struct gpio_desc *desc; - unsigned long lflags = 0; enum of_gpio_flags flags; bool active_low = false; bool single_ended = false; @@ -4328,8 +4329,8 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, enum gpiod_flags dflags, const char *label) { + unsigned long lflags = GPIO_LOOKUP_FLAGS_DEFAULT; struct gpio_desc *desc = ERR_PTR(-ENODEV); - unsigned long lflags = 0; int ret; if (!fwnode) diff --git a/include/linux/gpio/machine.h b/include/linux/gpio/machine.h index dad392158550..35f299d1f6a7 100644 --- a/include/linux/gpio/machine.h +++ b/include/linux/gpio/machine.h @@ -14,6 +14,8 @@ enum gpio_lookup_flags { GPIO_TRANSITORY = (1 << 3), GPIO_PULL_UP = (1 << 4), GPIO_PULL_DOWN = (1 << 5), + + GPIO_LOOKUP_FLAGS_DEFAULT = GPIO_ACTIVE_HIGH | GPIO_PERSISTENT, }; /** -- cgit v1.2.3 From 606be34440ee3e6da3799691fcab7b69e1ad06cd Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 10 Apr 2019 18:39:20 +0300 Subject: gpiolib: acpi: Add acpi_gpio_update_gpiod_lookup_flags() helper This helper consolidates all settings of GPIO descriptor lookup flags and quirks in the future if any. No functional change intended. Signed-off-by: Andy Shevchenko Acked-by: Hans de Goede Reviewed-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-acpi.c | 13 ++++++++++--- drivers/gpio/gpiolib.c | 4 +--- drivers/gpio/gpiolib.h | 8 ++++++++ 3 files changed, 19 insertions(+), 6 deletions(-) (limited to 'drivers/gpio/gpiolib.c') diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 878c7a7dea8b..9c6ebaaa02fe 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -525,6 +525,15 @@ acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, struct acpi_gpio_info *inf return ret; } +int acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags, + struct acpi_gpio_info *info) +{ + if (info->polarity == GPIO_ACTIVE_LOW) + *lookupflags |= GPIO_ACTIVE_LOW; + + return 0; +} + struct acpi_gpio_lookup { struct acpi_gpio_info info; int index; @@ -745,10 +754,8 @@ struct gpio_desc *acpi_find_gpio(struct device *dev, return ERR_PTR(-ENOENT); } - if (info.polarity == GPIO_ACTIVE_LOW) - *lookupflags |= GPIO_ACTIVE_LOW; - acpi_gpio_update_gpiod_flags(dflags, &info); + acpi_gpio_update_gpiod_lookup_flags(lookupflags, &info); return desc; } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index b8e4c9cd7b9e..bfbe5d7af372 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -4350,9 +4350,7 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, return desc; acpi_gpio_update_gpiod_flags(&dflags, &info); - - if (info.polarity == GPIO_ACTIVE_LOW) - lflags |= GPIO_ACTIVE_LOW; + acpi_gpio_update_gpiod_lookup_flags(&lflags, &info); } /* Currently only ACPI takes this path */ diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 5dbfce616ae1..e1636e152a6c 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -125,6 +125,8 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip); int acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, struct acpi_gpio_info *info); +int acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags, + struct acpi_gpio_info *info); struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id, @@ -153,6 +155,12 @@ acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, struct acpi_gpio_info *inf { return 0; } +static inline int +acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags, + struct acpi_gpio_info *info) +{ + return 0; +} static inline struct gpio_desc * acpi_find_gpio(struct device *dev, const char *con_id, -- cgit v1.2.3