forked from mirrors/linux
		
	gpiolib: rework quirk handling in of_find_gpio()
Instead of having a string of "if" statements let's put all quirks into an array and iterate over them. Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
This commit is contained in:
		
							parent
							
								
									984914ec4f
								
							
						
					
					
						commit
						a2b5e207ca
					
				
					 1 changed files with 26 additions and 36 deletions
				
			
		| 
						 | 
				
			
			@ -372,14 +372,12 @@ EXPORT_SYMBOL_GPL(gpiod_get_from_of_node);
 | 
			
		|||
 * properties should be named "foo-gpios" so we have this special kludge for
 | 
			
		||||
 * them.
 | 
			
		||||
 */
 | 
			
		||||
static struct gpio_desc *of_find_spi_gpio(struct device *dev,
 | 
			
		||||
static struct gpio_desc *of_find_spi_gpio(struct device_node *np,
 | 
			
		||||
					  const char *con_id,
 | 
			
		||||
					  unsigned int idx,
 | 
			
		||||
					  enum of_gpio_flags *of_flags)
 | 
			
		||||
{
 | 
			
		||||
	char prop_name[32]; /* 32 is max size of property name */
 | 
			
		||||
	const struct device_node *np = dev->of_node;
 | 
			
		||||
	struct gpio_desc *desc;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Hopefully the compiler stubs the rest of the function if this
 | 
			
		||||
| 
						 | 
				
			
			@ -395,8 +393,7 @@ static struct gpio_desc *of_find_spi_gpio(struct device *dev,
 | 
			
		|||
	/* Will be "gpio-sck", "gpio-mosi" or "gpio-miso" */
 | 
			
		||||
	snprintf(prop_name, sizeof(prop_name), "%s-%s", "gpio", con_id);
 | 
			
		||||
 | 
			
		||||
	desc = of_get_named_gpiod_flags(np, prop_name, idx, of_flags);
 | 
			
		||||
	return desc;
 | 
			
		||||
	return of_get_named_gpiod_flags(np, prop_name, idx, of_flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -404,13 +401,11 @@ static struct gpio_desc *of_find_spi_gpio(struct device *dev,
 | 
			
		|||
 * lines rather than "cs-gpios" like all other SPI hardware. Account for this
 | 
			
		||||
 * with a special quirk.
 | 
			
		||||
 */
 | 
			
		||||
static struct gpio_desc *of_find_spi_cs_gpio(struct device *dev,
 | 
			
		||||
static struct gpio_desc *of_find_spi_cs_gpio(struct device_node *np,
 | 
			
		||||
					     const char *con_id,
 | 
			
		||||
					     unsigned int idx,
 | 
			
		||||
					     enum of_gpio_flags *of_flags)
 | 
			
		||||
{
 | 
			
		||||
	const struct device_node *np = dev->of_node;
 | 
			
		||||
 | 
			
		||||
	if (!IS_ENABLED(CONFIG_SPI_MASTER))
 | 
			
		||||
		return ERR_PTR(-ENOENT);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -428,7 +423,7 @@ static struct gpio_desc *of_find_spi_cs_gpio(struct device *dev,
 | 
			
		|||
	 * uses just "gpios" so translate to that when "cs-gpios" is
 | 
			
		||||
	 * requested.
 | 
			
		||||
	 */
 | 
			
		||||
	return of_get_named_gpiod_flags(dev->of_node, "gpios", idx, of_flags);
 | 
			
		||||
	return of_get_named_gpiod_flags(np, "gpios", idx, of_flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -436,7 +431,7 @@ static struct gpio_desc *of_find_spi_cs_gpio(struct device *dev,
 | 
			
		|||
 * properties should be named "foo-gpios" so we have this special kludge for
 | 
			
		||||
 * them.
 | 
			
		||||
 */
 | 
			
		||||
static struct gpio_desc *of_find_regulator_gpio(struct device *dev,
 | 
			
		||||
static struct gpio_desc *of_find_regulator_gpio(struct device_node *np,
 | 
			
		||||
						const char *con_id,
 | 
			
		||||
						unsigned int idx,
 | 
			
		||||
						enum of_gpio_flags *of_flags)
 | 
			
		||||
| 
						 | 
				
			
			@ -447,8 +442,6 @@ static struct gpio_desc *of_find_regulator_gpio(struct device *dev,
 | 
			
		|||
		"wlf,ldo1ena", /* WM8994 */
 | 
			
		||||
		"wlf,ldo2ena", /* WM8994 */
 | 
			
		||||
	};
 | 
			
		||||
	const struct device_node *np = dev->of_node;
 | 
			
		||||
	struct gpio_desc *desc;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	if (!IS_ENABLED(CONFIG_REGULATOR))
 | 
			
		||||
| 
						 | 
				
			
			@ -461,11 +454,10 @@ static struct gpio_desc *of_find_regulator_gpio(struct device *dev,
 | 
			
		|||
	if (i < 0)
 | 
			
		||||
		return ERR_PTR(-ENOENT);
 | 
			
		||||
 | 
			
		||||
	desc = of_get_named_gpiod_flags(np, con_id, idx, of_flags);
 | 
			
		||||
	return desc;
 | 
			
		||||
	return of_get_named_gpiod_flags(np, con_id, idx, of_flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct gpio_desc *of_find_arizona_gpio(struct device *dev,
 | 
			
		||||
static struct gpio_desc *of_find_arizona_gpio(struct device_node *np,
 | 
			
		||||
					      const char *con_id,
 | 
			
		||||
					      unsigned int idx,
 | 
			
		||||
					      enum of_gpio_flags *of_flags)
 | 
			
		||||
| 
						 | 
				
			
			@ -476,10 +468,10 @@ static struct gpio_desc *of_find_arizona_gpio(struct device *dev,
 | 
			
		|||
	if (!con_id || strcmp(con_id, "wlf,reset"))
 | 
			
		||||
		return ERR_PTR(-ENOENT);
 | 
			
		||||
 | 
			
		||||
	return of_get_named_gpiod_flags(dev->of_node, con_id, idx, of_flags);
 | 
			
		||||
	return of_get_named_gpiod_flags(np, con_id, idx, of_flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct gpio_desc *of_find_usb_gpio(struct device *dev,
 | 
			
		||||
static struct gpio_desc *of_find_usb_gpio(struct device_node *np,
 | 
			
		||||
					  const char *con_id,
 | 
			
		||||
					  unsigned int idx,
 | 
			
		||||
					  enum of_gpio_flags *of_flags)
 | 
			
		||||
| 
						 | 
				
			
			@ -495,14 +487,27 @@ static struct gpio_desc *of_find_usb_gpio(struct device *dev,
 | 
			
		|||
	if (!con_id || strcmp(con_id, "fcs,int_n"))
 | 
			
		||||
		return ERR_PTR(-ENOENT);
 | 
			
		||||
 | 
			
		||||
	return of_get_named_gpiod_flags(dev->of_node, con_id, idx, of_flags);
 | 
			
		||||
	return of_get_named_gpiod_flags(np, con_id, idx, of_flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct gpio_desc *(*of_find_gpio_quirk)(struct device_node *np,
 | 
			
		||||
						const char *con_id,
 | 
			
		||||
						unsigned int idx,
 | 
			
		||||
						enum of_gpio_flags *of_flags);
 | 
			
		||||
static const of_find_gpio_quirk of_find_gpio_quirks[] = {
 | 
			
		||||
	of_find_spi_gpio,
 | 
			
		||||
	of_find_spi_cs_gpio,
 | 
			
		||||
	of_find_regulator_gpio,
 | 
			
		||||
	of_find_arizona_gpio,
 | 
			
		||||
	of_find_usb_gpio,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
 | 
			
		||||
			       unsigned int idx, unsigned long *flags)
 | 
			
		||||
{
 | 
			
		||||
	char prop_name[32]; /* 32 is max size of property name */
 | 
			
		||||
	enum of_gpio_flags of_flags;
 | 
			
		||||
	const of_find_gpio_quirk *q;
 | 
			
		||||
	struct gpio_desc *desc;
 | 
			
		||||
	unsigned int i;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -522,24 +527,9 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
 | 
			
		|||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (gpiod_not_found(desc)) {
 | 
			
		||||
		/* Special handling for SPI GPIOs if used */
 | 
			
		||||
		desc = of_find_spi_gpio(dev, con_id, idx, &of_flags);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (gpiod_not_found(desc))
 | 
			
		||||
		desc = of_find_spi_cs_gpio(dev, con_id, idx, &of_flags);
 | 
			
		||||
 | 
			
		||||
	if (gpiod_not_found(desc)) {
 | 
			
		||||
		/* Special handling for regulator GPIOs if used */
 | 
			
		||||
		desc = of_find_regulator_gpio(dev, con_id, idx, &of_flags);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (gpiod_not_found(desc))
 | 
			
		||||
		desc = of_find_arizona_gpio(dev, con_id, idx, &of_flags);
 | 
			
		||||
 | 
			
		||||
	if (gpiod_not_found(desc))
 | 
			
		||||
		desc = of_find_usb_gpio(dev, con_id, idx, &of_flags);
 | 
			
		||||
	/* Properly named GPIO was not found, try workarounds */
 | 
			
		||||
	for (q = of_find_gpio_quirks; gpiod_not_found(desc) && *q; q++)
 | 
			
		||||
		desc = (*q)(dev->of_node, con_id, idx, &of_flags);
 | 
			
		||||
 | 
			
		||||
	if (IS_ERR(desc))
 | 
			
		||||
		return desc;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue