diff options
Diffstat (limited to 'drivers/pinctrl/core.c')
| -rw-r--r-- | drivers/pinctrl/core.c | 62 | 
1 files changed, 61 insertions, 1 deletions
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 0f1ec9e8ff1..5cdee8669ea 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -345,6 +345,62 @@ void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev,  }  EXPORT_SYMBOL_GPL(pinctrl_add_gpio_ranges); +struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname, +		struct pinctrl_gpio_range *range) +{ +	struct pinctrl_dev *pctldev = get_pinctrl_dev_from_devname(devname); + +	/* +	 * If we can't find this device, let's assume that is because +	 * it has not probed yet, so the driver trying to register this +	 * range need to defer probing. +	 */ +	if (!pctldev) +		return ERR_PTR(-EPROBE_DEFER); + +	pinctrl_add_gpio_range(pctldev, range); +	return pctldev; +} +EXPORT_SYMBOL_GPL(pinctrl_find_and_add_gpio_range); + +/** + * 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 = NULL; + +	/* Loop over the ranges */ +	list_for_each_entry(range, &pctldev->gpio_ranges, node) { +		/* Check if we're in the valid range */ +		if (pin >= range->pin_base && +		    pin < range->pin_base + range->npins) { +			return range; +		} +	} + +	return NULL; +} +EXPORT_SYMBOL_GPL(pinctrl_find_gpio_range_from_pin); + +/** + * pinctrl_remove_gpio_range() - remove a range of GPIOs fro a pin controller + * @pctldev: pin controller device to remove the range from + * @range: the GPIO range to remove + */ +void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, +			       struct pinctrl_gpio_range *range) +{ +	mutex_lock(&pinctrl_mutex); +	list_del(&range->node); +	mutex_unlock(&pinctrl_mutex); +} +EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range); +  /**   * pinctrl_get_group_selector() - returns the group selector for a group   * @pctldev: the pin controller handling the group @@ -563,6 +619,8 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map)  		return -EPROBE_DEFER;  	} +	setting->dev_name = map->dev_name; +  	switch (map->type) {  	case PIN_MAP_TYPE_MUX_GROUP:  		ret = pinmux_map_to_setting(map, setting); @@ -1061,8 +1119,10 @@ static int pinctrl_groups_show(struct seq_file *s, void *what)  			seq_printf(s, "group: %s\n", gname);  			for (i = 0; i < num_pins; i++) {  				pname = pin_get_name(pctldev, pins[i]); -				if (WARN_ON(!pname)) +				if (WARN_ON(!pname)) { +					mutex_unlock(&pinctrl_mutex);  					return -EINVAL; +				}  				seq_printf(s, "pin %d (%s)\n", pins[i], pname);  			}  			seq_puts(s, "\n");  |