diff options
Diffstat (limited to 'drivers/pinctrl/core.c')
| -rw-r--r-- | drivers/pinctrl/core.c | 781 |
1 files changed, 463 insertions, 318 deletions
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index c5e2c5705058..83254a95ef17 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Core driver for the pin control subsystem * @@ -8,35 +9,33 @@ * Author: Linus Walleij <linus.walleij@linaro.org> * * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. - * - * License terms: GNU General Public License (GPL) version 2 */ #define pr_fmt(fmt) "pinctrl core: " fmt -#include <linux/kernel.h> -#include <linux/kref.h> -#include <linux/export.h> -#include <linux/init.h> +#include <linux/array_size.h> +#include <linux/cleanup.h> +#include <linux/debugfs.h> #include <linux/device.h> -#include <linux/slab.h> #include <linux/err.h> +#include <linux/export.h> +#include <linux/init.h> +#include <linux/kref.h> #include <linux/list.h> -#include <linux/sysfs.h> -#include <linux/debugfs.h> #include <linux/seq_file.h> +#include <linux/slab.h> + +#include <linux/gpio.h> +#include <linux/gpio/driver.h> + #include <linux/pinctrl/consumer.h> -#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/devinfo.h> #include <linux/pinctrl/machine.h> - -#ifdef CONFIG_GPIOLIB -#include <asm-generic/gpio.h> -#endif +#include <linux/pinctrl/pinctrl.h> #include "core.h" #include "devicetree.h" -#include "pinmux.h" #include "pinconf.h" - +#include "pinmux.h" static bool pinctrl_dummy_state; @@ -71,6 +70,7 @@ void pinctrl_provide_dummies(void) { pinctrl_dummy_state = true; } +EXPORT_SYMBOL_GPL(pinctrl_provide_dummies); const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev) { @@ -100,7 +100,7 @@ EXPORT_SYMBOL_GPL(pinctrl_dev_get_drvdata); */ struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *devname) { - struct pinctrl_dev *pctldev = NULL; + struct pinctrl_dev *pctldev; if (!devname) return NULL; @@ -127,7 +127,7 @@ struct pinctrl_dev *get_pinctrl_dev_from_of_node(struct device_node *np) mutex_lock(&pinctrldev_list_mutex); list_for_each_entry(pctldev, &pinctrldev_list, node) - if (pctldev->dev->of_node == np) { + if (device_match_of_node(pctldev->dev, np)) { mutex_unlock(&pinctrldev_list_mutex); return pctldev; } @@ -144,7 +144,7 @@ struct pinctrl_dev *get_pinctrl_dev_from_of_node(struct device_node *np) */ int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name) { - unsigned i, pin; + unsigned int i, pin; /* The pin number can be retrived from the pin controller descriptor */ for (i = 0; i < pctldev->desc->npins; i++) { @@ -161,11 +161,11 @@ int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name) } /** - * pin_get_name_from_id() - look up a pin name from a pin id + * pin_get_name() - look up a pin name from a pin id * @pctldev: the pin control device to lookup the pin on - * @name: the name of the pin to look up + * @pin: pin number/id to look up */ -const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin) +const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned int pin) { const struct pin_desc *desc; @@ -178,34 +178,12 @@ const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin) return desc->name; } - -/** - * pin_is_valid() - check if pin exists on controller - * @pctldev: the pin control device to check the pin on - * @pin: pin to check, use the local pin controller index number - * - * This tells us whether a certain pin exist on a certain pin controller or - * not. Pin lists may be sparse, so some pins may not exist. - */ -bool pin_is_valid(struct pinctrl_dev *pctldev, int pin) -{ - struct pin_desc *pindesc; - - if (pin < 0) - return false; - - mutex_lock(&pctldev->mutex); - pindesc = pin_desc_get(pctldev, pin); - mutex_unlock(&pctldev->mutex); - - return pindesc != NULL; -} -EXPORT_SYMBOL_GPL(pin_is_valid); +EXPORT_SYMBOL_GPL(pin_get_name); /* Deletes a range of pin descriptors */ static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev, const struct pinctrl_pin_desc *pins, - unsigned num_pins) + unsigned int num_pins) { int i; @@ -228,6 +206,7 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, const struct pinctrl_pin_desc *pin) { struct pin_desc *pindesc; + int error; pindesc = pin_desc_get(pctldev, pin->number); if (pindesc) { @@ -242,6 +221,9 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, /* Set owner */ pindesc->pctldev = pctldev; +#ifdef CONFIG_PINMUX + mutex_init(&pindesc->mux_lock); +#endif /* Copy basic pin info */ if (pin->name) { @@ -249,25 +231,32 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, } else { pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", pin->number); if (!pindesc->name) { - kfree(pindesc); - return -ENOMEM; + error = -ENOMEM; + goto failed; } pindesc->dynamic_name = true; } pindesc->drv_data = pin->drv_data; - radix_tree_insert(&pctldev->pin_desc_tree, pin->number, pindesc); + error = radix_tree_insert(&pctldev->pin_desc_tree, pin->number, pindesc); + if (error) + goto failed; + pr_debug("registered pin %d (%s) on %s\n", pin->number, pindesc->name, pctldev->desc->name); return 0; + +failed: + kfree(pindesc); + return error; } static int pinctrl_register_pins(struct pinctrl_dev *pctldev, - struct pinctrl_pin_desc const *pins, - unsigned num_descs) + const struct pinctrl_pin_desc *pins, + unsigned int num_descs) { - unsigned i; + unsigned int i; int ret = 0; for (i = 0; i < num_descs; i++) { @@ -282,7 +271,8 @@ static int pinctrl_register_pins(struct pinctrl_dev *pctldev, /** * gpio_to_pin() - GPIO range GPIO number to pin number translation * @range: GPIO range used for the translation - * @gpio: gpio pin to translate to a pin number + * @gc: GPIO chip structure from the GPIO subsystem + * @offset: hardware offset of the GPIO relative to the controller * * Finds the pin number for a given GPIO using the specified GPIO range * as a base for translation. The distinction between linear GPIO ranges @@ -293,34 +283,36 @@ static int pinctrl_register_pins(struct pinctrl_dev *pctldev, * result of successful pinctrl_get_device_gpio_range calls)! */ static inline int gpio_to_pin(struct pinctrl_gpio_range *range, - unsigned int gpio) + struct gpio_chip *gc, unsigned int offset) { - unsigned int offset = gpio - range->base; + unsigned int pin = gc->base + offset - range->base; if (range->pins) - return range->pins[offset]; + return range->pins[pin]; else - return range->pin_base + offset; + return range->pin_base + pin; } /** * pinctrl_match_gpio_range() - check if a certain GPIO pin is in range * @pctldev: pin controller device to check - * @gpio: gpio pin to check taken from the global GPIO pin space + * @gc: GPIO chip structure from the GPIO subsystem + * @offset: hardware offset of the GPIO relative to the controller * * Tries to match a GPIO pin number to the ranges handled by a certain pin * controller, return the range or NULL */ static struct pinctrl_gpio_range * -pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio) +pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, struct gpio_chip *gc, + unsigned int offset) { - struct pinctrl_gpio_range *range = NULL; + struct pinctrl_gpio_range *range; mutex_lock(&pctldev->mutex); /* Loop over the ranges */ list_for_each_entry(range, &pctldev->gpio_ranges, node) { /* Check if we're in the valid range */ - if (gpio >= range->base && - gpio < range->base + range->npins) { + if ((gc->base + offset) >= range->base && + (gc->base + offset) < range->base + range->npins) { mutex_unlock(&pctldev->mutex); return range; } @@ -332,7 +324,8 @@ pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio) /** * pinctrl_ready_for_gpio_range() - check if other GPIO pins of * the same GPIO chip are in range - * @gpio: gpio pin to check taken from the global GPIO pin space + * @gc: GPIO chip structure from the GPIO subsystem + * @offset: hardware offset of the GPIO relative to the controller * * This function is complement of pinctrl_match_gpio_range(). If the return * value of pinctrl_match_gpio_range() is NULL, this function could be used @@ -343,14 +336,11 @@ pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio) * is false, it means that pinctrl device may not be ready. */ #ifdef CONFIG_GPIOLIB -static bool pinctrl_ready_for_gpio_range(unsigned gpio) +static bool pinctrl_ready_for_gpio_range(struct gpio_chip *gc, + unsigned int offset) { struct pinctrl_dev *pctldev; struct pinctrl_gpio_range *range = NULL; - struct gpio_chip *chip = gpio_to_chip(gpio); - - if (WARN(!chip, "no gpio_chip for gpio%i?", gpio)) - return false; mutex_lock(&pinctrldev_list_mutex); @@ -360,8 +350,8 @@ static bool pinctrl_ready_for_gpio_range(unsigned gpio) mutex_lock(&pctldev->mutex); list_for_each_entry(range, &pctldev->gpio_ranges, node) { /* Check if any gpio range overlapped with gpio chip */ - if (range->base + range->npins - 1 < chip->base || - range->base > chip->base + chip->ngpio - 1) + if (range->base + range->npins - 1 < gc->base || + range->base > gc->base + gc->ngpio - 1) continue; mutex_unlock(&pctldev->mutex); mutex_unlock(&pinctrldev_list_mutex); @@ -375,12 +365,17 @@ static bool pinctrl_ready_for_gpio_range(unsigned gpio) return false; } #else -static bool pinctrl_ready_for_gpio_range(unsigned gpio) { return true; } +static inline bool +pinctrl_ready_for_gpio_range(struct gpio_chip *gc, unsigned int offset) +{ + return true; +} #endif /** * pinctrl_get_device_gpio_range() - find device for GPIO range - * @gpio: the pin to locate the pin controller for + * @gc: GPIO chip structure from the GPIO subsystem + * @offset: hardware offset of the GPIO relative to the controller * @outdev: the pin control device if found * @outrange: the GPIO range if found * @@ -389,11 +384,12 @@ static bool pinctrl_ready_for_gpio_range(unsigned gpio) { return true; } * -EPROBE_DEFER if the GPIO range could not be found in any device since it * may still have not been registered. */ -static int pinctrl_get_device_gpio_range(unsigned gpio, +static int pinctrl_get_device_gpio_range(struct gpio_chip *gc, + unsigned int offset, struct pinctrl_dev **outdev, struct pinctrl_gpio_range **outrange) { - struct pinctrl_dev *pctldev = NULL; + struct pinctrl_dev *pctldev; mutex_lock(&pinctrldev_list_mutex); @@ -401,7 +397,7 @@ static int pinctrl_get_device_gpio_range(unsigned gpio, list_for_each_entry(pctldev, &pinctrldev_list, node) { struct pinctrl_gpio_range *range; - range = pinctrl_match_gpio_range(pctldev, gpio); + range = pinctrl_match_gpio_range(pctldev, gc, offset); if (range) { *outdev = pctldev; *outrange = range; @@ -420,6 +416,10 @@ static int pinctrl_get_device_gpio_range(unsigned gpio, * @pctldev: pin controller device to add the range to * @range: the GPIO range to add * + * DEPRECATED: Don't use this function in new code. See section 2 of + * Documentation/devicetree/bindings/gpio/gpio.txt on how to bind pinctrl and + * gpio drivers. + * * This adds a range of GPIOs to be handled by a certain pin controller. Call * this to register handled ranges after registering your pin controller. */ @@ -434,7 +434,7 @@ EXPORT_SYMBOL_GPL(pinctrl_add_gpio_range); void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *ranges, - unsigned nranges) + unsigned int nranges) { int i; @@ -455,9 +455,9 @@ struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname, * it has not probed yet, so the driver trying to register this * range need to defer probing. */ - if (!pctldev) { + if (!pctldev) return ERR_PTR(-EPROBE_DEFER); - } + pinctrl_add_gpio_range(pctldev, range); return pctldev; @@ -465,7 +465,7 @@ struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname, EXPORT_SYMBOL_GPL(pinctrl_find_and_add_gpio_range); int pinctrl_get_group_pins(struct pinctrl_dev *pctldev, const char *pin_group, - const unsigned **pins, unsigned *num_pins) + const unsigned int **pins, unsigned int *num_pins) { const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; int gs; @@ -565,7 +565,7 @@ const char *pinctrl_generic_get_group_name(struct pinctrl_dev *pctldev, if (!group) return NULL; - return group->name; + return group->grp.name; } EXPORT_SYMBOL_GPL(pinctrl_generic_get_group_name); @@ -591,8 +591,8 @@ int pinctrl_generic_get_group_pins(struct pinctrl_dev *pctldev, return -EINVAL; } - *pins = group->pins; - *num_pins = group->num_pins; + *pins = group->grp.pins; + *num_pins = group->grp.npins; return 0; } @@ -601,7 +601,7 @@ EXPORT_SYMBOL_GPL(pinctrl_generic_get_group_pins); /** * pinctrl_generic_get_group() - returns a pin group based on the number * @pctldev: pin controller device - * @gselector: group number + * @selector: group number */ struct group_desc *pinctrl_generic_get_group(struct pinctrl_dev *pctldev, unsigned int selector) @@ -617,6 +617,26 @@ struct group_desc *pinctrl_generic_get_group(struct pinctrl_dev *pctldev, } EXPORT_SYMBOL_GPL(pinctrl_generic_get_group); +static int pinctrl_generic_group_name_to_selector(struct pinctrl_dev *pctldev, + const char *function) +{ + const struct pinctrl_ops *ops = pctldev->desc->pctlops; + int ngroups = ops->get_groups_count(pctldev); + int selector = 0; + + /* See if this pctldev has this group */ + while (selector < ngroups) { + const char *gname = ops->get_group_name(pctldev, selector); + + if (gname && !strcmp(function, gname)) + return selector; + + selector++; + } + + return -EINVAL; +} + /** * pinctrl_generic_add_group() - adds a new pin group * @pctldev: pin controller device @@ -628,25 +648,33 @@ EXPORT_SYMBOL_GPL(pinctrl_generic_get_group); * Note that the caller must take care of locking. */ int pinctrl_generic_add_group(struct pinctrl_dev *pctldev, const char *name, - int *pins, int num_pins, void *data) + const unsigned int *pins, int num_pins, void *data) { struct group_desc *group; + int selector, error; + + if (!name) + return -EINVAL; + + selector = pinctrl_generic_group_name_to_selector(pctldev, name); + if (selector >= 0) + return selector; + + selector = pctldev->num_groups; group = devm_kzalloc(pctldev->dev, sizeof(*group), GFP_KERNEL); if (!group) return -ENOMEM; - group->name = name; - group->pins = pins; - group->num_pins = num_pins; - group->data = data; + *group = PINCTRL_GROUP_DESC(name, pins, num_pins, data); - radix_tree_insert(&pctldev->pin_group_tree, pctldev->num_groups, - group); + error = radix_tree_insert(&pctldev->pin_group_tree, selector, group); + if (error) + return error; pctldev->num_groups++; - return 0; + return selector; } EXPORT_SYMBOL_GPL(pinctrl_generic_add_group); @@ -686,7 +714,7 @@ EXPORT_SYMBOL_GPL(pinctrl_generic_remove_group); static void pinctrl_generic_free_groups(struct pinctrl_dev *pctldev) { struct radix_tree_iter iter; - void **slot; + void __rcu **slot; radix_tree_for_each_slot(slot, &pctldev->pin_group_tree, &iter, 0) radix_tree_delete(&pctldev->pin_group_tree, iter.index); @@ -709,13 +737,13 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev, const char *pin_group) { const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; - unsigned ngroups = pctlops->get_groups_count(pctldev); - unsigned group_selector = 0; + unsigned int ngroups = pctlops->get_groups_count(pctldev); + unsigned int group_selector = 0; while (group_selector < ngroups) { const char *gname = pctlops->get_group_name(pctldev, group_selector); - if (!strcmp(gname, pin_group)) { + if (gname && !strcmp(gname, pin_group)) { dev_dbg(pctldev->dev, "found group selector %u for %s\n", group_selector, @@ -732,24 +760,52 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev, return -EINVAL; } +bool pinctrl_gpio_can_use_line(struct gpio_chip *gc, unsigned int offset) +{ + struct pinctrl_dev *pctldev; + struct pinctrl_gpio_range *range; + bool result; + int pin; + + /* + * Try to obtain GPIO range, if it fails + * we're probably dealing with GPIO driver + * without a backing pin controller - bail out. + */ + if (pinctrl_get_device_gpio_range(gc, offset, &pctldev, &range)) + return true; + + mutex_lock(&pctldev->mutex); + + /* Convert to the pin controllers number space */ + pin = gpio_to_pin(range, gc, offset); + + result = pinmux_can_be_used_for_gpio(pctldev, pin); + + mutex_unlock(&pctldev->mutex); + + return result; +} +EXPORT_SYMBOL_GPL(pinctrl_gpio_can_use_line); + /** - * pinctrl_request_gpio() - request a single pin to be used as GPIO - * @gpio: the GPIO pin number from the GPIO subsystem number space + * pinctrl_gpio_request() - request a single pin to be used as GPIO + * @gc: GPIO chip structure from the GPIO subsystem + * @offset: hardware offset of the GPIO relative to the controller * * This function should *ONLY* be used from gpiolib-based GPIO drivers, * as part of their gpio_request() semantics, platforms and individual drivers * shall *NOT* request GPIO pins to be muxed in. */ -int pinctrl_request_gpio(unsigned gpio) +int pinctrl_gpio_request(struct gpio_chip *gc, unsigned int offset) { - struct pinctrl_dev *pctldev; struct pinctrl_gpio_range *range; - int ret; - int pin; + struct pinctrl_dev *pctldev; + int ret, pin; - ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); + ret = pinctrl_get_device_gpio_range(gc, offset, &pctldev, &range); if (ret) { - if (pinctrl_ready_for_gpio_range(gpio)) + if (pinctrl_ready_for_gpio_range(gc, offset)) ret = 0; return ret; } @@ -757,54 +813,55 @@ int pinctrl_request_gpio(unsigned gpio) mutex_lock(&pctldev->mutex); /* Convert to the pin controllers number space */ - pin = gpio_to_pin(range, gpio); + pin = gpio_to_pin(range, gc, offset); - ret = pinmux_request_gpio(pctldev, range, pin, gpio); + ret = pinmux_request_gpio(pctldev, range, pin, gc->base + offset); mutex_unlock(&pctldev->mutex); return ret; } -EXPORT_SYMBOL_GPL(pinctrl_request_gpio); +EXPORT_SYMBOL_GPL(pinctrl_gpio_request); /** - * pinctrl_free_gpio() - free control on a single pin, currently used as GPIO - * @gpio: the GPIO pin number from the GPIO subsystem number space + * pinctrl_gpio_free() - free control on a single pin, currently used as GPIO + * @gc: GPIO chip structure from the GPIO subsystem + * @offset: hardware offset of the GPIO relative to the controller * * This function should *ONLY* be used from gpiolib-based GPIO drivers, - * as part of their gpio_free() semantics, platforms and individual drivers - * shall *NOT* request GPIO pins to be muxed out. + * as part of their gpio_request() semantics, platforms and individual drivers + * shall *NOT* request GPIO pins to be muxed in. */ -void pinctrl_free_gpio(unsigned gpio) +void pinctrl_gpio_free(struct gpio_chip *gc, unsigned int offset) { - struct pinctrl_dev *pctldev; struct pinctrl_gpio_range *range; - int ret; - int pin; + struct pinctrl_dev *pctldev; + int ret, pin; - ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); - if (ret) { + ret = pinctrl_get_device_gpio_range(gc, offset, &pctldev, &range); + if (ret) return; - } + mutex_lock(&pctldev->mutex); /* Convert to the pin controllers number space */ - pin = gpio_to_pin(range, gpio); + pin = gpio_to_pin(range, gc, offset); pinmux_free_gpio(pctldev, pin, range); mutex_unlock(&pctldev->mutex); } -EXPORT_SYMBOL_GPL(pinctrl_free_gpio); +EXPORT_SYMBOL_GPL(pinctrl_gpio_free); -static int pinctrl_gpio_direction(unsigned gpio, bool input) +static int pinctrl_gpio_direction(struct gpio_chip *gc, unsigned int offset, + bool input) { struct pinctrl_dev *pctldev; struct pinctrl_gpio_range *range; int ret; int pin; - ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); + ret = pinctrl_get_device_gpio_range(gc, offset, &pctldev, &range); if (ret) { return ret; } @@ -812,7 +869,7 @@ static int pinctrl_gpio_direction(unsigned gpio, bool input) mutex_lock(&pctldev->mutex); /* Convert to the pin controllers number space */ - pin = gpio_to_pin(range, gpio); + pin = gpio_to_pin(range, gc, offset); ret = pinmux_gpio_direction(pctldev, range, pin, input); mutex_unlock(&pctldev->mutex); @@ -822,54 +879,58 @@ static int pinctrl_gpio_direction(unsigned gpio, bool input) /** * pinctrl_gpio_direction_input() - request a GPIO pin to go into input mode - * @gpio: the GPIO pin number from the GPIO subsystem number space + * @gc: GPIO chip structure from the GPIO subsystem + * @offset: hardware offset of the GPIO relative to the controller * * This function should *ONLY* be used from gpiolib-based GPIO drivers, * as part of their gpio_direction_input() semantics, platforms and individual * drivers shall *NOT* touch pin control GPIO calls. */ -int pinctrl_gpio_direction_input(unsigned gpio) +int pinctrl_gpio_direction_input(struct gpio_chip *gc, unsigned int offset) { - return pinctrl_gpio_direction(gpio, true); + return pinctrl_gpio_direction(gc, offset, true); } EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_input); /** * pinctrl_gpio_direction_output() - request a GPIO pin to go into output mode - * @gpio: the GPIO pin number from the GPIO subsystem number space + * @gc: GPIO chip structure from the GPIO subsystem + * @offset: hardware offset of the GPIO relative to the controller * * This function should *ONLY* be used from gpiolib-based GPIO drivers, * as part of their gpio_direction_output() semantics, platforms and individual * drivers shall *NOT* touch pin control GPIO calls. */ -int pinctrl_gpio_direction_output(unsigned gpio) +int pinctrl_gpio_direction_output(struct gpio_chip *gc, unsigned int offset) { - return pinctrl_gpio_direction(gpio, false); + return pinctrl_gpio_direction(gc, offset, false); } EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output); /** * pinctrl_gpio_set_config() - Apply config to given GPIO pin - * @gpio: the GPIO pin number from the GPIO subsystem number space + * @gc: GPIO chip structure from the GPIO subsystem + * @offset: hardware offset of the GPIO relative to the controller * @config: the configuration to apply to the GPIO * * This function should *ONLY* be used from gpiolib-based GPIO drivers, if * they need to call the underlying pin controller to change GPIO config * (for example set debounce time). */ -int pinctrl_gpio_set_config(unsigned gpio, unsigned long config) +int pinctrl_gpio_set_config(struct gpio_chip *gc, unsigned int offset, + unsigned long config) { unsigned long configs[] = { config }; struct pinctrl_gpio_range *range; struct pinctrl_dev *pctldev; int ret, pin; - ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); + ret = pinctrl_get_device_gpio_range(gc, offset, &pctldev, &range); if (ret) return ret; mutex_lock(&pctldev->mutex); - pin = gpio_to_pin(range, gpio); + pin = gpio_to_pin(range, gc, offset); ret = pinconf_set_config(pctldev, pin, configs, ARRAY_SIZE(configs)); mutex_unlock(&pctldev->mutex); @@ -907,7 +968,7 @@ static struct pinctrl_state *create_state(struct pinctrl *p, } static int add_setting(struct pinctrl *p, struct pinctrl_dev *pctldev, - struct pinctrl_map const *map) + const struct pinctrl_map *map) { struct pinctrl_state *state; struct pinctrl_setting *setting; @@ -994,8 +1055,7 @@ static struct pinctrl *create_pinctrl(struct device *dev, struct pinctrl *p; const char *devname; struct pinctrl_maps *maps_node; - int i; - struct pinctrl_map const *map; + const struct pinctrl_map *map; int ret; /* @@ -1020,7 +1080,7 @@ static struct pinctrl *create_pinctrl(struct device *dev, mutex_lock(&pinctrl_maps_mutex); /* Iterate over the pin control maps to locate the right ones */ - for_each_maps(maps_node, i, map) { + for_each_pin_map(maps_node, map) { /* Map must be for this device */ if (strcmp(map->dev_name, devname)) continue; @@ -1050,8 +1110,8 @@ static struct pinctrl *create_pinctrl(struct device *dev, * an -EPROBE_DEFER later, as that is the worst case. */ if (ret == -EPROBE_DEFER) { - pinctrl_free(p, false); mutex_unlock(&pinctrl_maps_mutex); + pinctrl_free(p, false); return ERR_PTR(ret); } } @@ -1188,37 +1248,53 @@ struct pinctrl_state *pinctrl_lookup_state(struct pinctrl *p, } EXPORT_SYMBOL_GPL(pinctrl_lookup_state); +static void pinctrl_link_add(struct pinctrl_dev *pctldev, + struct device *consumer) +{ + if (pctldev->desc->link_consumers) + device_link_add(consumer, pctldev->dev, + DL_FLAG_PM_RUNTIME | + DL_FLAG_AUTOREMOVE_CONSUMER); +} + +static void pinctrl_cond_disable_mux_setting(struct pinctrl_state *state, + struct pinctrl_setting *target_setting) +{ + struct pinctrl_setting *setting; + + list_for_each_entry(setting, &state->settings, node) { + if (target_setting && (&setting->node == &target_setting->node)) + break; + + if (setting->type == PIN_MAP_TYPE_MUX_GROUP) + pinmux_disable_setting(setting); + } +} + /** - * pinctrl_select_state() - select/activate/program a pinctrl state to HW + * pinctrl_commit_state() - select/activate/program a pinctrl state to HW * @p: the pinctrl handle for the device that requests configuration * @state: the state handle to select/activate/program */ -int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) +static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state) { - struct pinctrl_setting *setting, *setting2; - struct pinctrl_state *old_state = p->state; + struct pinctrl_setting *setting; + struct pinctrl_state *old_state = READ_ONCE(p->state); int ret; - if (p->state == state) - return 0; - - if (p->state) { + if (old_state) { /* * For each pinmux setting in the old state, forget SW's record * of mux owner for that pingroup. Any pingroups which are * still owned by the new state will be re-acquired by the call * to pinmux_enable_setting() in the loop below. */ - list_for_each_entry(setting, &p->state->settings, node) { - if (setting->type != PIN_MAP_TYPE_MUX_GROUP) - continue; - pinmux_disable_setting(setting); - } + pinctrl_cond_disable_mux_setting(old_state, NULL); } p->state = NULL; - /* Apply all the settings for the new state */ + /* Apply all the settings for the new state - pinmux first */ list_for_each_entry(setting, &state->settings, node) { switch (setting->type) { case PIN_MAP_TYPE_MUX_GROUP: @@ -1226,6 +1302,29 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) break; case PIN_MAP_TYPE_CONFIGS_PIN: case PIN_MAP_TYPE_CONFIGS_GROUP: + ret = 0; + break; + default: + ret = -EINVAL; + break; + } + + if (ret < 0) + goto unapply_new_state; + + /* Do not link hogs (circular dependency) */ + if (p != setting->pctldev->p) + pinctrl_link_add(setting->pctldev, p->dev); + } + + /* Apply all the settings for the new state - pinconf after */ + list_for_each_entry(setting, &state->settings, node) { + switch (setting->type) { + case PIN_MAP_TYPE_MUX_GROUP: + ret = 0; + break; + case PIN_MAP_TYPE_CONFIGS_PIN: + case PIN_MAP_TYPE_CONFIGS_GROUP: ret = pinconf_apply_setting(setting); break; default: @@ -1234,37 +1333,54 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) } if (ret < 0) { - goto unapply_new_state; + goto unapply_mux_setting; } + + /* Do not link hogs (circular dependency) */ + if (p != setting->pctldev->p) + pinctrl_link_add(setting->pctldev, p->dev); } p->state = state; return 0; +unapply_mux_setting: + pinctrl_cond_disable_mux_setting(state, NULL); + goto restore_old_state; + unapply_new_state: dev_err(p->dev, "Error applying setting, reverse things back\n"); - list_for_each_entry(setting2, &state->settings, node) { - if (&setting2->node == &setting->node) - break; - /* - * All we can do here is pinmux_disable_setting. - * That means that some pins are muxed differently now - * than they were before applying the setting (We can't - * "unmux a pin"!), but it's not a big deal since the pins - * are free to be muxed by another apply_setting. - */ - if (setting2->type == PIN_MAP_TYPE_MUX_GROUP) - pinmux_disable_setting(setting2); - } + /* + * All we can do here is pinmux_disable_setting. + * That means that some pins are muxed differently now + * than they were before applying the setting (We can't + * "unmux a pin"!), but it's not a big deal since the pins + * are free to be muxed by another apply_setting. + */ + pinctrl_cond_disable_mux_setting(state, setting); +restore_old_state: /* There's no infinite recursive loop here because p->state is NULL */ if (old_state) pinctrl_select_state(p, old_state); return ret; } + +/** + * pinctrl_select_state() - select/activate/program a pinctrl state to HW + * @p: the pinctrl handle for the device that requests configuration + * @state: the state handle to select/activate/program + */ +int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) +{ + if (p->state == state) + return 0; + + return pinctrl_commit_state(p, state); +} EXPORT_SYMBOL_GPL(pinctrl_select_state); static void devm_pinctrl_release(struct device *dev, void *res) @@ -1273,7 +1389,7 @@ static void devm_pinctrl_release(struct device *dev, void *res) } /** - * struct devm_pinctrl_get() - Resource managed pinctrl_get() + * devm_pinctrl_get() - Resource managed pinctrl_get() * @dev: the device to obtain the handle for * * If there is a need to explicitly destroy the returned struct pinctrl, @@ -1321,8 +1437,15 @@ void devm_pinctrl_put(struct pinctrl *p) } EXPORT_SYMBOL_GPL(devm_pinctrl_put); -int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, - bool dup) +/** + * pinctrl_register_mappings() - register a set of pin controller mappings + * @maps: the pincontrol mappings table to register. Note the pinctrl-core + * keeps a reference to the passed in maps, so they should _not_ be + * marked with __initdata. + * @num_maps: the number of maps in the mapping table + */ +int pinctrl_register_mappings(const struct pinctrl_map *maps, + unsigned int num_maps) { int i, ret; struct pinctrl_maps *maps_node; @@ -1375,18 +1498,8 @@ int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, if (!maps_node) return -ENOMEM; + maps_node->maps = maps; maps_node->num_maps = num_maps; - if (dup) { - maps_node->maps = kmemdup(maps, sizeof(*maps) * num_maps, - GFP_KERNEL); - if (!maps_node->maps) { - pr_err("failed to duplicate mapping table\n"); - kfree(maps_node); - return -ENOMEM; - } - } else { - maps_node->maps = maps; - } mutex_lock(&pinctrl_maps_mutex); list_add_tail(&maps_node->node, &pinctrl_maps); @@ -1394,21 +1507,14 @@ int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, return 0; } +EXPORT_SYMBOL_GPL(pinctrl_register_mappings); /** - * pinctrl_register_mappings() - register a set of pin controller mappings - * @maps: the pincontrol mappings table to register. This should probably be - * marked with __initdata so it can be discarded after boot. This - * function will perform a shallow copy for the mapping entries. - * @num_maps: the number of maps in the mapping table + * pinctrl_unregister_mappings() - unregister a set of pin controller mappings + * @map: the pincontrol mappings table passed to pinctrl_register_mappings() + * when registering the mappings. */ -int pinctrl_register_mappings(struct pinctrl_map const *maps, - unsigned num_maps) -{ - return pinctrl_register_map(maps, num_maps, true); -} - -void pinctrl_unregister_map(struct pinctrl_map const *map) +void pinctrl_unregister_mappings(const struct pinctrl_map *map) { struct pinctrl_maps *maps_node; @@ -1423,6 +1529,36 @@ void pinctrl_unregister_map(struct pinctrl_map const *map) } mutex_unlock(&pinctrl_maps_mutex); } +EXPORT_SYMBOL_GPL(pinctrl_unregister_mappings); + +static void devm_pinctrl_unregister_mappings(void *maps) +{ + pinctrl_unregister_mappings(maps); +} + +/** + * devm_pinctrl_register_mappings() - Resource managed pinctrl_register_mappings() + * @dev: device for which mappings are registered + * @maps: the pincontrol mappings table to register. Note the pinctrl-core + * keeps a reference to the passed in maps, so they should _not_ be + * marked with __initdata. + * @num_maps: the number of maps in the mapping table + * + * Returns: 0 on success, or negative errno on failure. + */ +int devm_pinctrl_register_mappings(struct device *dev, + const struct pinctrl_map *maps, + unsigned int num_maps) +{ + int ret; + + ret = pinctrl_register_mappings(maps, num_maps); + if (ret) + return ret; + + return devm_add_action_or_reset(dev, devm_pinctrl_unregister_mappings, (void *)maps); +} +EXPORT_SYMBOL_GPL(devm_pinctrl_register_mappings); /** * pinctrl_force_sleep() - turn a given controller device into sleep state @@ -1431,7 +1567,7 @@ void pinctrl_unregister_map(struct pinctrl_map const *map) int pinctrl_force_sleep(struct pinctrl_dev *pctldev) { if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_sleep)) - return pinctrl_select_state(pctldev->p, pctldev->hog_sleep); + return pinctrl_commit_state(pctldev->p, pctldev->hog_sleep); return 0; } EXPORT_SYMBOL_GPL(pinctrl_force_sleep); @@ -1443,7 +1579,7 @@ EXPORT_SYMBOL_GPL(pinctrl_force_sleep); int pinctrl_force_default(struct pinctrl_dev *pctldev) { if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_default)) - return pinctrl_select_state(pctldev->p, pctldev->hog_default); + return pinctrl_commit_state(pctldev->p, pctldev->hog_default); return 0; } EXPORT_SYMBOL_GPL(pinctrl_force_default); @@ -1480,15 +1616,8 @@ int pinctrl_init_done(struct device *dev) return ret; } -#ifdef CONFIG_PM - -/** - * pinctrl_pm_select_state() - select pinctrl state for PM - * @dev: device to select default state for - * @state: state to set - */ -static int pinctrl_pm_select_state(struct device *dev, - struct pinctrl_state *state) +static int pinctrl_select_bound_state(struct device *dev, + struct pinctrl_state *state) { struct dev_pin_info *pins = dev->pins; int ret; @@ -1503,17 +1632,42 @@ static int pinctrl_pm_select_state(struct device *dev, } /** + * pinctrl_select_default_state() - select default pinctrl state + * @dev: device to select default state for + */ +int pinctrl_select_default_state(struct device *dev) +{ + if (!dev->pins) + return 0; + + return pinctrl_select_bound_state(dev, dev->pins->default_state); +} +EXPORT_SYMBOL_GPL(pinctrl_select_default_state); + +#ifdef CONFIG_PM + +/** * pinctrl_pm_select_default_state() - select default pinctrl state for PM * @dev: device to select default state for */ int pinctrl_pm_select_default_state(struct device *dev) { + return pinctrl_select_default_state(dev); +} +EXPORT_SYMBOL_GPL(pinctrl_pm_select_default_state); + +/** + * pinctrl_pm_select_init_state() - select init pinctrl state for PM + * @dev: device to select init state for + */ +int pinctrl_pm_select_init_state(struct device *dev) +{ if (!dev->pins) return 0; - return pinctrl_pm_select_state(dev, dev->pins->default_state); + return pinctrl_select_bound_state(dev, dev->pins->init_state); } -EXPORT_SYMBOL_GPL(pinctrl_pm_select_default_state); +EXPORT_SYMBOL_GPL(pinctrl_pm_select_init_state); /** * pinctrl_pm_select_sleep_state() - select sleep pinctrl state for PM @@ -1524,7 +1678,7 @@ int pinctrl_pm_select_sleep_state(struct device *dev) if (!dev->pins) return 0; - return pinctrl_pm_select_state(dev, dev->pins->sleep_state); + return pinctrl_select_bound_state(dev, dev->pins->sleep_state); } EXPORT_SYMBOL_GPL(pinctrl_pm_select_sleep_state); @@ -1537,7 +1691,7 @@ int pinctrl_pm_select_idle_state(struct device *dev) if (!dev->pins) return 0; - return pinctrl_pm_select_state(dev, dev->pins->idle_state); + return pinctrl_select_bound_state(dev, dev->pins->idle_state); } EXPORT_SYMBOL_GPL(pinctrl_pm_select_idle_state); #endif @@ -1548,7 +1702,12 @@ static int pinctrl_pins_show(struct seq_file *s, void *what) { struct pinctrl_dev *pctldev = s->private; const struct pinctrl_ops *ops = pctldev->desc->pctlops; - unsigned i, pin; + unsigned int i, pin; +#ifdef CONFIG_GPIOLIB + struct gpio_device *gdev = NULL; + struct pinctrl_gpio_range *range; + int gpio_num; +#endif seq_printf(s, "registered pins: %d\n", pctldev->desc->npins); @@ -1566,6 +1725,40 @@ static int pinctrl_pins_show(struct seq_file *s, void *what) seq_printf(s, "pin %d (%s) ", pin, desc->name); +#ifdef CONFIG_GPIOLIB + gdev = NULL; + gpio_num = -1; + list_for_each_entry(range, &pctldev->gpio_ranges, node) { + if (range->pins != NULL) { + for (int i = 0; i < range->npins; ++i) { + if (range->pins[i] == pin) { + gpio_num = range->base + i; + break; + } + } + } else if ((pin >= range->pin_base) && + (pin < (range->pin_base + range->npins))) { + gpio_num = + range->base + (pin - range->pin_base); + } + if (gpio_num != -1) + break; + } + if (gpio_num >= 0) + /* + * FIXME: gpio_num comes from the global GPIO numberspace. + * we need to get rid of the range->base eventually and + * get the descriptor directly from the gpio_chip. + */ + gdev = gpiod_to_gpio_device(gpio_to_desc(gpio_num)); + if (gdev) + seq_printf(s, "%u:%s ", + gpio_num - gpio_device_get_base(gdev), + gpio_device_get_label(gdev)); + else + seq_puts(s, "0:? "); +#endif + /* Driver-specific info per pin */ if (ops->pin_dbg_show) ops->pin_dbg_show(pctldev, s, pin); @@ -1577,12 +1770,13 @@ static int pinctrl_pins_show(struct seq_file *s, void *what) return 0; } +DEFINE_SHOW_ATTRIBUTE(pinctrl_pins); static int pinctrl_groups_show(struct seq_file *s, void *what) { struct pinctrl_dev *pctldev = s->private; const struct pinctrl_ops *ops = pctldev->desc->pctlops; - unsigned ngroups, selector = 0; + unsigned int ngroups, selector = 0; mutex_lock(&pctldev->mutex); @@ -1590,8 +1784,8 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) seq_puts(s, "registered pin groups:\n"); while (selector < ngroups) { - const unsigned *pins = NULL; - unsigned num_pins = 0; + const unsigned int *pins = NULL; + unsigned int num_pins = 0; const char *gname = ops->get_group_name(pctldev, selector); const char *pname; int ret = 0; @@ -1622,11 +1816,12 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) return 0; } +DEFINE_SHOW_ATTRIBUTE(pinctrl_groups); static int pinctrl_gpioranges_show(struct seq_file *s, void *what) { struct pinctrl_dev *pctldev = s->private; - struct pinctrl_gpio_range *range = NULL; + struct pinctrl_gpio_range *range; seq_puts(s, "GPIO ranges handled:\n"); @@ -1655,6 +1850,7 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what) return 0; } +DEFINE_SHOW_ATTRIBUTE(pinctrl_gpioranges); static int pinctrl_devices_show(struct seq_file *s, void *what) { @@ -1681,6 +1877,7 @@ static int pinctrl_devices_show(struct seq_file *s, void *what) return 0; } +DEFINE_SHOW_ATTRIBUTE(pinctrl_devices); static inline const char *map_type(enum pinctrl_map_type type) { @@ -1701,13 +1898,12 @@ static inline const char *map_type(enum pinctrl_map_type type) static int pinctrl_maps_show(struct seq_file *s, void *what) { struct pinctrl_maps *maps_node; - int i; - struct pinctrl_map const *map; + const struct pinctrl_map *map; seq_puts(s, "Pinctrl maps:\n"); mutex_lock(&pinctrl_maps_mutex); - for_each_maps(maps_node, i, map) { + for_each_pin_map(maps_node, map) { seq_printf(s, "device %s\nstate %s\ntype %s (%d)\n", map->dev_name, map->name, map_type(map->type), map->type); @@ -1734,6 +1930,7 @@ static int pinctrl_maps_show(struct seq_file *s, void *what) return 0; } +DEFINE_SHOW_ATTRIBUTE(pinctrl_maps); static int pinctrl_show(struct seq_file *s, void *what) { @@ -1779,87 +1976,30 @@ static int pinctrl_show(struct seq_file *s, void *what) return 0; } - -static int pinctrl_pins_open(struct inode *inode, struct file *file) -{ - return single_open(file, pinctrl_pins_show, inode->i_private); -} - -static int pinctrl_groups_open(struct inode *inode, struct file *file) -{ - return single_open(file, pinctrl_groups_show, inode->i_private); -} - -static int pinctrl_gpioranges_open(struct inode *inode, struct file *file) -{ - return single_open(file, pinctrl_gpioranges_show, inode->i_private); -} - -static int pinctrl_devices_open(struct inode *inode, struct file *file) -{ - return single_open(file, pinctrl_devices_show, NULL); -} - -static int pinctrl_maps_open(struct inode *inode, struct file *file) -{ - return single_open(file, pinctrl_maps_show, NULL); -} - -static int pinctrl_open(struct inode *inode, struct file *file) -{ - return single_open(file, pinctrl_show, NULL); -} - -static const struct file_operations pinctrl_pins_ops = { - .open = pinctrl_pins_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations pinctrl_groups_ops = { - .open = pinctrl_groups_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations pinctrl_gpioranges_ops = { - .open = pinctrl_gpioranges_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations pinctrl_devices_ops = { - .open = pinctrl_devices_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations pinctrl_maps_ops = { - .open = pinctrl_maps_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations pinctrl_ops = { - .open = pinctrl_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(pinctrl); static struct dentry *debugfs_root; static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) { struct dentry *device_root; + const char *debugfs_name; + + if (pctldev->desc->name && + strcmp(dev_name(pctldev->dev), pctldev->desc->name)) { + debugfs_name = devm_kasprintf(pctldev->dev, GFP_KERNEL, + "%s-%s", dev_name(pctldev->dev), + pctldev->desc->name); + if (!debugfs_name) { + pr_warn("failed to determine debugfs dir name for %s\n", + dev_name(pctldev->dev)); + return; + } + } else { + debugfs_name = dev_name(pctldev->dev); + } - device_root = debugfs_create_dir(dev_name(pctldev->dev), - debugfs_root); + device_root = debugfs_create_dir(debugfs_name, debugfs_root); pctldev->device_root = device_root; if (IS_ERR(device_root) || !device_root) { @@ -1867,12 +2007,12 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) dev_name(pctldev->dev)); return; } - debugfs_create_file("pins", S_IFREG | S_IRUGO, - device_root, pctldev, &pinctrl_pins_ops); - debugfs_create_file("pingroups", S_IFREG | S_IRUGO, - device_root, pctldev, &pinctrl_groups_ops); - debugfs_create_file("gpio-ranges", S_IFREG | S_IRUGO, - device_root, pctldev, &pinctrl_gpioranges_ops); + debugfs_create_file("pins", 0444, + device_root, pctldev, &pinctrl_pins_fops); + debugfs_create_file("pingroups", 0444, + device_root, pctldev, &pinctrl_groups_fops); + debugfs_create_file("gpio-ranges", 0444, + device_root, pctldev, &pinctrl_gpioranges_fops); if (pctldev->desc->pmxops) pinmux_init_device_debugfs(device_root, pctldev); if (pctldev->desc->confops) @@ -1887,18 +2027,18 @@ static void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev) static void pinctrl_init_debugfs(void) { debugfs_root = debugfs_create_dir("pinctrl", NULL); - if (IS_ERR(debugfs_root) || !debugfs_root) { + if (IS_ERR(debugfs_root)) { pr_warn("failed to create debugfs directory\n"); debugfs_root = NULL; return; } - debugfs_create_file("pinctrl-devices", S_IFREG | S_IRUGO, - debugfs_root, NULL, &pinctrl_devices_ops); - debugfs_create_file("pinctrl-maps", S_IFREG | S_IRUGO, - debugfs_root, NULL, &pinctrl_maps_ops); - debugfs_create_file("pinctrl-handles", S_IFREG | S_IRUGO, - debugfs_root, NULL, &pinctrl_ops); + debugfs_create_file("pinctrl-devices", 0444, + debugfs_root, NULL, &pinctrl_devices_fops); + debugfs_create_file("pinctrl-maps", 0444, + debugfs_root, NULL, &pinctrl_maps_fops); + debugfs_create_file("pinctrl-handles", 0444, + debugfs_root, NULL, &pinctrl_fops); } #else /* CONFIG_DEBUG_FS */ @@ -1936,7 +2076,7 @@ static int pinctrl_check_ops(struct pinctrl_dev *pctldev) * @driver_data: private pin controller data for this pin controller */ static struct pinctrl_dev * -pinctrl_init_controller(struct pinctrl_desc *pctldesc, struct device *dev, +pinctrl_init_controller(const struct pinctrl_desc *pctldesc, struct device *dev, void *driver_data) { struct pinctrl_dev *pctldev; @@ -2006,6 +2146,15 @@ out_err: return ERR_PTR(ret); } +static void pinctrl_uninit_controller(struct pinctrl_dev *pctldev, + const struct pinctrl_desc *pctldesc) +{ + pinctrl_free_pindescs(pctldev, pctldesc->pins, + pctldesc->npins); + mutex_destroy(&pctldev->mutex); + kfree(pctldev); +} + static int pinctrl_claim_hogs(struct pinctrl_dev *pctldev) { pctldev->p = create_pinctrl(pctldev->dev, pctldev); @@ -2022,7 +2171,6 @@ static int pinctrl_claim_hogs(struct pinctrl_dev *pctldev) return PTR_ERR(pctldev->p); } - kref_get(&pctldev->p->users); pctldev->hog_default = pinctrl_lookup_state(pctldev->p, PINCTRL_STATE_DEFAULT); if (IS_ERR(pctldev->hog_default)) { @@ -2051,11 +2199,7 @@ int pinctrl_enable(struct pinctrl_dev *pctldev) error = pinctrl_claim_hogs(pctldev); if (error) { - dev_err(pctldev->dev, "could not claim hogs: %i\n", - error); - mutex_destroy(&pctldev->mutex); - kfree(pctldev); - + dev_err(pctldev->dev, "could not claim hogs: %i\n", error); return error; } @@ -2080,7 +2224,7 @@ EXPORT_SYMBOL_GPL(pinctrl_enable); * struct pinctrl_dev handle. To avoid issues later on, please use the * new pinctrl_register_and_init() below instead. */ -struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, +struct pinctrl_dev *pinctrl_register(const struct pinctrl_desc *pctldesc, struct device *dev, void *driver_data) { struct pinctrl_dev *pctldev; @@ -2091,11 +2235,12 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, return pctldev; error = pinctrl_enable(pctldev); - if (error) + if (error) { + pinctrl_uninit_controller(pctldev, pctldesc); return ERR_PTR(error); + } return pctldev; - } EXPORT_SYMBOL_GPL(pinctrl_register); @@ -2109,7 +2254,7 @@ EXPORT_SYMBOL_GPL(pinctrl_register); * Note that pinctrl_enable() still needs to be manually called after * this once the driver is ready. */ -int pinctrl_register_and_init(struct pinctrl_desc *pctldesc, +int pinctrl_register_and_init(const struct pinctrl_desc *pctldesc, struct device *dev, void *driver_data, struct pinctrl_dev **pctldev) { @@ -2200,7 +2345,7 @@ static int devm_pinctrl_dev_match(struct device *dev, void *res, void *data) * The pinctrl device will be automatically released when the device is unbound. */ struct pinctrl_dev *devm_pinctrl_register(struct device *dev, - struct pinctrl_desc *pctldesc, + const struct pinctrl_desc *pctldesc, void *driver_data) { struct pinctrl_dev **ptr, *pctldev; @@ -2227,14 +2372,14 @@ EXPORT_SYMBOL_GPL(devm_pinctrl_register); * @dev: parent device for this pin controller * @pctldesc: descriptor for this pin controller * @driver_data: private pin controller data for this pin controller + * @pctldev: pin controller device * - * Returns an error pointer if pincontrol register failed. Otherwise - * it returns valid pinctrl handle. + * Returns zero on success or an error number on failure. * * The pinctrl device will be automatically released when the device is unbound. */ int devm_pinctrl_register_and_init(struct device *dev, - struct pinctrl_desc *pctldesc, + const struct pinctrl_desc *pctldesc, void *driver_data, struct pinctrl_dev **pctldev) { @@ -2260,7 +2405,7 @@ EXPORT_SYMBOL_GPL(devm_pinctrl_register_and_init); /** * devm_pinctrl_unregister() - Resource managed version of pinctrl_unregister(). - * @dev: device for which which resource was allocated + * @dev: device for which resource was allocated * @pctldev: the pinctrl device to unregister. */ void devm_pinctrl_unregister(struct device *dev, struct pinctrl_dev *pctldev) @@ -2272,7 +2417,7 @@ EXPORT_SYMBOL_GPL(devm_pinctrl_unregister); static int __init pinctrl_init(void) { - pr_info("initialized pinctrl subsystem\n"); + pr_debug("initialized pinctrl subsystem\n"); pinctrl_init_debugfs(); return 0; } |
