diff options
| author | Joachim Eastwood <manabian@gmail.com> | 2016-02-25 22:44:37 +0100 | 
|---|---|---|
| committer | Linus Walleij <linus.walleij@linaro.org> | 2016-03-07 10:41:20 +0700 | 
| commit | b18537cd8ec2e5280ba19d24ea8812b80e5b3208 (patch) | |
| tree | 4e0384f11a062ee3ecb1141501d543b284a4ff2f /drivers/pinctrl/core.c | |
| parent | 5e9a207547079a23c3d4ecb4bad050ba8acc3f59 (diff) | |
pinctrl: core: create nolock version of pinctrl_find_gpio_range_from_pin
pinctrl_find_gpio_range_from_pin takes the pctldev->mutex but so
does pinconf_pins_show and this will cause a deadlock if
pinctrl_find_gpio_range_from_pin is used in .pin_config_get
callback.
Create a nolock version of pinctrl_find_gpio_range_from_pin to
allow pin to gpio lookup to be used from pinconf_pins_show.
Signed-off-by: Joachim Eastwood <manabian@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/core.c')
| -rw-r--r-- | drivers/pinctrl/core.c | 35 | 
1 files changed, 23 insertions, 12 deletions
| diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 2686a4450dfc..f67a8b7a4e18 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -481,18 +481,12 @@ int pinctrl_get_group_pins(struct pinctrl_dev *pctldev, const char *pin_group,  }  EXPORT_SYMBOL_GPL(pinctrl_get_group_pins); -/** - * pinctrl_find_gpio_range_from_pin() - locate the GPIO range for a pin - * @pctldev: the pin controller device to look in - * @pin: a controller-local number to find the range for - */  struct pinctrl_gpio_range * -pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev, -				 unsigned int pin) +pinctrl_find_gpio_range_from_pin_nolock(struct pinctrl_dev *pctldev, +					unsigned int pin)  {  	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 */ @@ -500,15 +494,32 @@ pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev,  			int a;  			for (a = 0; a < range->npins; a++) {  				if (range->pins[a] == pin) -					goto out; +					return range;  			}  		} else if (pin >= range->pin_base &&  			   pin < range->pin_base + range->npins) -			goto out; +			return range;  	} -	range = NULL; -out: + +	return NULL; +} +EXPORT_SYMBOL_GPL(pinctrl_find_gpio_range_from_pin_nolock); + +/** + * pinctrl_find_gpio_range_from_pin() - locate the GPIO range for a pin + * @pctldev: the pin controller device to look in + * @pin: a controller-local number to find the range for + */ +struct pinctrl_gpio_range * +pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev, +				 unsigned int pin) +{ +	struct pinctrl_gpio_range *range; + +	mutex_lock(&pctldev->mutex); +	range = pinctrl_find_gpio_range_from_pin_nolock(pctldev, pin);  	mutex_unlock(&pctldev->mutex); +  	return range;  }  EXPORT_SYMBOL_GPL(pinctrl_find_gpio_range_from_pin); | 
