mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 23:32:14 +00:00
pinctrl: check pinctrl ready for gpio range
pinctrl_get_device_gpio_range() only checks whether a certain GPIO pin is in gpio range. But maybe some GPIO pins don't have back-end pinctrl interface, it means that these pins are always configured as GPIO function. For example, gpio159 isn't related to back-end pinctrl device in Hi3620 while other GPIO pins are related to back-end pinctrl device. Append pinctrl_ready_for_gpio_range() that is used to check whether pinctrl device with GPIO range is ready. This function will be called after pinctrl_get_device_gpio_range() fails. If pinctrl device with GPIO range is found, it means that pinctrl device is already launched and a certain GPIO pin just don't have back-end pinctrl interface. Then pinctrl_request_gpio() shouldn't return -EPROBE_DEFER in this case. Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
f1f70479e9
commit
51e13c2475
1 changed files with 36 additions and 0 deletions
|
@ -27,6 +27,7 @@
|
||||||
#include <linux/pinctrl/consumer.h>
|
#include <linux/pinctrl/consumer.h>
|
||||||
#include <linux/pinctrl/pinctrl.h>
|
#include <linux/pinctrl/pinctrl.h>
|
||||||
#include <linux/pinctrl/machine.h>
|
#include <linux/pinctrl/machine.h>
|
||||||
|
#include <asm-generic/gpio.h>
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "devicetree.h"
|
#include "devicetree.h"
|
||||||
#include "pinmux.h"
|
#include "pinmux.h"
|
||||||
|
@ -276,6 +277,39 @@ pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* to check whether pinctrl device is ready or not. Maybe some GPIO pins
|
||||||
|
* of the same GPIO chip don't have back-end pinctrl interface.
|
||||||
|
* If the return value is true, it means that pinctrl device is ready & the
|
||||||
|
* certain GPIO pin doesn't have back-end pinctrl device. If the return value
|
||||||
|
* is false, it means that pinctrl device may not be ready.
|
||||||
|
*/
|
||||||
|
static bool pinctrl_ready_for_gpio_range(unsigned gpio)
|
||||||
|
{
|
||||||
|
struct pinctrl_dev *pctldev;
|
||||||
|
struct pinctrl_gpio_range *range = NULL;
|
||||||
|
struct gpio_chip *chip = gpio_to_chip(gpio);
|
||||||
|
|
||||||
|
/* Loop over the pin controllers */
|
||||||
|
list_for_each_entry(pctldev, &pinctrldev_list, node) {
|
||||||
|
/* Loop over the ranges */
|
||||||
|
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)
|
||||||
|
continue;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pinctrl_get_device_gpio_range() - find device for GPIO range
|
* pinctrl_get_device_gpio_range() - find device for GPIO range
|
||||||
* @gpio: the pin to locate the pin controller for
|
* @gpio: the pin to locate the pin controller for
|
||||||
|
@ -443,6 +477,8 @@ int pinctrl_request_gpio(unsigned gpio)
|
||||||
|
|
||||||
ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
|
ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
if (pinctrl_ready_for_gpio_range(gpio))
|
||||||
|
ret = 0;
|
||||||
mutex_unlock(&pinctrl_mutex);
|
mutex_unlock(&pinctrl_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue