Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b18537cd authored by Joachim Eastwood's avatar Joachim Eastwood Committed by Linus Walleij
Browse files

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: default avatarJoachim Eastwood <manabian@gmail.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 5e9a2075
Loading
Loading
Loading
Loading
+23 −12
Original line number Diff line number Diff line
@@ -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,
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;
	}

	return NULL;
}
	range = NULL;
out:
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);
+4 −0
Original line number Diff line number Diff line
@@ -182,6 +182,10 @@ static inline struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev,
	return radix_tree_lookup(&pctldev->pin_desc_tree, pin);
}

extern struct pinctrl_gpio_range *
pinctrl_find_gpio_range_from_pin_nolock(struct pinctrl_dev *pctldev,
					unsigned int pin);

int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps,
			 bool dup);
void pinctrl_unregister_map(struct pinctrl_map const *map);