forked from Minki/linux
gpiolib: separation of pin concerns
The fact that of_gpiochip_add_pin_range() and gpiochip_add_pin_range() share too much code is fragile and will invariably mean that bugs need to be fixed in two places instead of one. So separate the concerns of gpiolib.c and gpiolib-of.c and have the latter call the former as back-end. This is necessary also when going forward with other device descriptions such as ACPI. This is done by: - Adding a return code to gpiochip_add_pin_range() so we can reliably check whether this succeeds. - Get rid of the custom of_pinctrl_add_gpio_range() from pinctrl. Instead create of_pinctrl_get() to just retrive the pin controller per se from an OF node. This composite function was just begging to be deleted, it was way to purpose-specific. - Use pinctrl_dev_get_name() to get the name of the retrieved pin controller and use that to call back into the generic gpiochip_add_pin_range(). Now the pin range is only allocated and tied to a pin controller from the core implementation in gpiolib.c. Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
9ef0d6f762
commit
1e63d7b936
@ -221,8 +221,8 @@ EXPORT_SYMBOL(of_mm_gpiochip_add);
|
|||||||
static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
|
static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
|
||||||
{
|
{
|
||||||
struct device_node *np = chip->of_node;
|
struct device_node *np = chip->of_node;
|
||||||
struct gpio_pin_range *pin_range;
|
|
||||||
struct of_phandle_args pinspec;
|
struct of_phandle_args pinspec;
|
||||||
|
struct pinctrl_dev *pctldev;
|
||||||
int index = 0, ret;
|
int index = 0, ret;
|
||||||
|
|
||||||
if (!np)
|
if (!np)
|
||||||
@ -234,22 +234,17 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
|
|||||||
if (ret)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
pin_range = devm_kzalloc(chip->dev, sizeof(*pin_range),
|
pctldev = of_pinctrl_get(pinspec.np);
|
||||||
GFP_KERNEL);
|
if (!pctldev)
|
||||||
if (!pin_range) {
|
|
||||||
pr_err("%s: GPIO chip: failed to allocate pin ranges\n",
|
|
||||||
chip->label);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
pin_range->range.name = chip->label;
|
ret = gpiochip_add_pin_range(chip,
|
||||||
pin_range->range.base = chip->base;
|
pinctrl_dev_get_name(pctldev),
|
||||||
pin_range->range.pin_base = pinspec.args[0];
|
pinspec.args[0],
|
||||||
pin_range->range.npins = pinspec.args[1];
|
pinspec.args[1]);
|
||||||
pin_range->pctldev = of_pinctrl_add_gpio_range(pinspec.np,
|
|
||||||
&pin_range->range);
|
|
||||||
|
|
||||||
list_add_tail(&pin_range->node, &chip->pin_ranges);
|
if (ret)
|
||||||
|
break;
|
||||||
|
|
||||||
} while (index++);
|
} while (index++);
|
||||||
}
|
}
|
||||||
|
@ -1187,8 +1187,8 @@ EXPORT_SYMBOL_GPL(gpiochip_find);
|
|||||||
|
|
||||||
#ifdef CONFIG_PINCTRL
|
#ifdef CONFIG_PINCTRL
|
||||||
|
|
||||||
void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
|
int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
|
||||||
unsigned int pin_base, unsigned int npins)
|
unsigned int pin_base, unsigned int npins)
|
||||||
{
|
{
|
||||||
struct gpio_pin_range *pin_range;
|
struct gpio_pin_range *pin_range;
|
||||||
|
|
||||||
@ -1196,7 +1196,7 @@ void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
|
|||||||
if (!pin_range) {
|
if (!pin_range) {
|
||||||
pr_err("%s: GPIO chip: failed to allocate pin ranges\n",
|
pr_err("%s: GPIO chip: failed to allocate pin ranges\n",
|
||||||
chip->label);
|
chip->label);
|
||||||
return;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
pin_range->range.name = chip->label;
|
pin_range->range.name = chip->label;
|
||||||
@ -1207,6 +1207,8 @@ void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
|
|||||||
&pin_range->range);
|
&pin_range->range);
|
||||||
|
|
||||||
list_add_tail(&pin_range->node, &chip->pin_ranges);
|
list_add_tail(&pin_range->node, &chip->pin_ranges);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(gpiochip_add_pin_range);
|
EXPORT_SYMBOL_GPL(gpiochip_add_pin_range);
|
||||||
|
|
||||||
|
@ -106,8 +106,7 @@ static struct pinctrl_dev *find_pinctrl_by_of_node(struct device_node *np)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np,
|
struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
|
||||||
struct pinctrl_gpio_range *range)
|
|
||||||
{
|
{
|
||||||
struct pinctrl_dev *pctldev;
|
struct pinctrl_dev *pctldev;
|
||||||
|
|
||||||
@ -115,7 +114,6 @@ struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np,
|
|||||||
if (!pctldev)
|
if (!pctldev)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
pinctrl_add_gpio_range(pctldev, range);
|
|
||||||
return pctldev;
|
return pctldev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,8 +63,8 @@ struct gpio_pin_range {
|
|||||||
struct pinctrl_gpio_range range;
|
struct pinctrl_gpio_range range;
|
||||||
};
|
};
|
||||||
|
|
||||||
void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
|
int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
|
||||||
unsigned int pin_base, unsigned int npins);
|
unsigned int pin_base, unsigned int npins);
|
||||||
void gpiochip_remove_pin_ranges(struct gpio_chip *chip);
|
void gpiochip_remove_pin_ranges(struct gpio_chip *chip);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -233,7 +233,7 @@ static inline int irq_to_gpio(unsigned irq)
|
|||||||
|
|
||||||
#ifdef CONFIG_PINCTRL
|
#ifdef CONFIG_PINCTRL
|
||||||
|
|
||||||
static inline void
|
static inline int
|
||||||
gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
|
gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
|
||||||
unsigned int pin_base, unsigned int npins)
|
unsigned int pin_base, unsigned int npins)
|
||||||
{
|
{
|
||||||
|
@ -141,16 +141,13 @@ extern struct pinctrl_dev *find_pinctrl_and_add_gpio_range(const char *devname,
|
|||||||
struct pinctrl_gpio_range *range);
|
struct pinctrl_gpio_range *range);
|
||||||
|
|
||||||
#ifdef CONFIG_OF
|
#ifdef CONFIG_OF
|
||||||
extern struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np,
|
extern struct pinctrl_dev *of_pinctrl_get(struct device_node *np);
|
||||||
struct pinctrl_gpio_range *range);
|
|
||||||
#else
|
#else
|
||||||
static inline
|
static inline
|
||||||
struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np,
|
struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
|
||||||
struct pinctrl_gpio_range *range)
|
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_OF */
|
#endif /* CONFIG_OF */
|
||||||
|
|
||||||
extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev);
|
extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev);
|
||||||
|
Loading…
Reference in New Issue
Block a user