of/gpio: Implement of_get_gpio_flags()
This adds a new function, of_get_gpio_flags, which is like of_get_gpio(), but accepts a new "flags" argument. This new function will be used by the drivers that need to retrieve additional GPIO information, such as active-low flag. Also, this changes the default ("simple") .xlate routine to warn about bogus (< 2) #gpio-cells usage: the second cell should always be present for GPIO flags. Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
parent
2fd091f3ee
commit
b908b53d58
2 changed files with 63 additions and 11 deletions
|
@ -19,14 +19,17 @@
|
|||
#include <asm/prom.h>
|
||||
|
||||
/**
|
||||
* of_get_gpio - Get a GPIO number from the device tree to use with GPIO API
|
||||
* of_get_gpio_flags - Get a GPIO number and flags to use with GPIO API
|
||||
* @np: device node to get GPIO from
|
||||
* @index: index of the GPIO
|
||||
* @flags: a flags pointer to fill in
|
||||
*
|
||||
* Returns GPIO number to use with Linux generic GPIO API, or one of the errno
|
||||
* value on the error condition.
|
||||
* value on the error condition. If @flags is not NULL the function also fills
|
||||
* in flags for the GPIO.
|
||||
*/
|
||||
int of_get_gpio(struct device_node *np, int index)
|
||||
int of_get_gpio_flags(struct device_node *np, int index,
|
||||
enum of_gpio_flags *flags)
|
||||
{
|
||||
int ret;
|
||||
struct device_node *gc;
|
||||
|
@ -59,7 +62,11 @@ int of_get_gpio(struct device_node *np, int index)
|
|||
goto err1;
|
||||
}
|
||||
|
||||
ret = of_gc->xlate(of_gc, np, gpio_spec);
|
||||
/* .xlate might decide to not fill in the flags, so clear it. */
|
||||
if (flags)
|
||||
*flags = 0;
|
||||
|
||||
ret = of_gc->xlate(of_gc, np, gpio_spec, flags);
|
||||
if (ret < 0)
|
||||
goto err1;
|
||||
|
||||
|
@ -70,26 +77,41 @@ int of_get_gpio(struct device_node *np, int index)
|
|||
pr_debug("%s exited with status %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_gpio);
|
||||
EXPORT_SYMBOL(of_get_gpio_flags);
|
||||
|
||||
/**
|
||||
* of_gpio_simple_xlate - translate gpio_spec to the GPIO number
|
||||
* of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags
|
||||
* @of_gc: pointer to the of_gpio_chip structure
|
||||
* @np: device node of the GPIO chip
|
||||
* @gpio_spec: gpio specifier as found in the device tree
|
||||
* @flags: a flags pointer to fill in
|
||||
*
|
||||
* This is simple translation function, suitable for the most 1:1 mapped
|
||||
* gpio chips. This function performs only one sanity check: whether gpio
|
||||
* is less than ngpios (that is specified in the gpio_chip).
|
||||
*/
|
||||
int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np,
|
||||
const void *gpio_spec)
|
||||
const void *gpio_spec, enum of_gpio_flags *flags)
|
||||
{
|
||||
const u32 *gpio = gpio_spec;
|
||||
|
||||
/*
|
||||
* We're discouraging gpio_cells < 2, since that way you'll have to
|
||||
* write your own xlate function (that will have to retrive the GPIO
|
||||
* number and the flags from a single gpio cell -- this is possible,
|
||||
* but not recommended).
|
||||
*/
|
||||
if (of_gc->gpio_cells < 2) {
|
||||
WARN_ON(1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (*gpio > of_gc->gc.ngpio)
|
||||
return -EINVAL;
|
||||
|
||||
if (flags)
|
||||
*flags = gpio[1];
|
||||
|
||||
return *gpio;
|
||||
}
|
||||
EXPORT_SYMBOL(of_gpio_simple_xlate);
|
||||
|
|
|
@ -14,9 +14,22 @@
|
|||
#ifndef __LINUX_OF_GPIO_H
|
||||
#define __LINUX_OF_GPIO_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
struct device_node;
|
||||
|
||||
/*
|
||||
* This is Linux-specific flags. By default controllers' and Linux' mapping
|
||||
* match, but GPIO controllers are free to translate their own flags to
|
||||
* Linux-specific in their .xlate callback. Though, 1:1 mapping is recommended.
|
||||
*/
|
||||
enum of_gpio_flags {
|
||||
OF_GPIO_ACTIVE_LOW = 0x1,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF_GPIO
|
||||
|
||||
/*
|
||||
|
@ -26,7 +39,7 @@ struct of_gpio_chip {
|
|||
struct gpio_chip gc;
|
||||
int gpio_cells;
|
||||
int (*xlate)(struct of_gpio_chip *of_gc, struct device_node *np,
|
||||
const void *gpio_spec);
|
||||
const void *gpio_spec, enum of_gpio_flags *flags);
|
||||
};
|
||||
|
||||
static inline struct of_gpio_chip *to_of_gpio_chip(struct gpio_chip *gc)
|
||||
|
@ -50,20 +63,37 @@ static inline struct of_mm_gpio_chip *to_of_mm_gpio_chip(struct gpio_chip *gc)
|
|||
return container_of(of_gc, struct of_mm_gpio_chip, of_gc);
|
||||
}
|
||||
|
||||
extern int of_get_gpio(struct device_node *np, int index);
|
||||
extern int of_get_gpio_flags(struct device_node *np, int index,
|
||||
enum of_gpio_flags *flags);
|
||||
|
||||
extern int of_mm_gpiochip_add(struct device_node *np,
|
||||
struct of_mm_gpio_chip *mm_gc);
|
||||
extern int of_gpio_simple_xlate(struct of_gpio_chip *of_gc,
|
||||
struct device_node *np,
|
||||
const void *gpio_spec);
|
||||
const void *gpio_spec,
|
||||
enum of_gpio_flags *flags);
|
||||
#else
|
||||
|
||||
/* Drivers may not strictly depend on the GPIO support, so let them link. */
|
||||
static inline int of_get_gpio(struct device_node *np, int index)
|
||||
static inline int of_get_gpio_flags(struct device_node *np, int index,
|
||||
enum of_gpio_flags *flags)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_OF_GPIO */
|
||||
|
||||
/**
|
||||
* of_get_gpio - Get a GPIO number to use with GPIO API
|
||||
* @np: device node to get GPIO from
|
||||
* @index: index of the GPIO
|
||||
*
|
||||
* Returns GPIO number to use with Linux generic GPIO API, or one of the errno
|
||||
* value on the error condition.
|
||||
*/
|
||||
static inline int of_get_gpio(struct device_node *np, int index)
|
||||
{
|
||||
return of_get_gpio_flags(np, index, NULL);
|
||||
}
|
||||
|
||||
#endif /* __LINUX_OF_GPIO_H */
|
||||
|
|
Loading…
Reference in a new issue