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>
|
#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
|
* @np: device node to get GPIO from
|
||||||
* @index: index of the GPIO
|
* @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
|
* 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;
|
int ret;
|
||||||
struct device_node *gc;
|
struct device_node *gc;
|
||||||
|
@ -59,7 +62,11 @@ int of_get_gpio(struct device_node *np, int index)
|
||||||
goto err1;
|
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)
|
if (ret < 0)
|
||||||
goto err1;
|
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);
|
pr_debug("%s exited with status %d\n", __func__, ret);
|
||||||
return 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
|
* @of_gc: pointer to the of_gpio_chip structure
|
||||||
* @np: device node of the GPIO chip
|
* @np: device node of the GPIO chip
|
||||||
* @gpio_spec: gpio specifier as found in the device tree
|
* @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
|
* This is simple translation function, suitable for the most 1:1 mapped
|
||||||
* gpio chips. This function performs only one sanity check: whether gpio
|
* gpio chips. This function performs only one sanity check: whether gpio
|
||||||
* is less than ngpios (that is specified in the gpio_chip).
|
* 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,
|
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;
|
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)
|
if (*gpio > of_gc->gc.ngpio)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (flags)
|
||||||
|
*flags = gpio[1];
|
||||||
|
|
||||||
return *gpio;
|
return *gpio;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(of_gpio_simple_xlate);
|
EXPORT_SYMBOL(of_gpio_simple_xlate);
|
||||||
|
|
|
@ -14,9 +14,22 @@
|
||||||
#ifndef __LINUX_OF_GPIO_H
|
#ifndef __LINUX_OF_GPIO_H
|
||||||
#define __LINUX_OF_GPIO_H
|
#define __LINUX_OF_GPIO_H
|
||||||
|
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/gpio.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
|
#ifdef CONFIG_OF_GPIO
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -26,7 +39,7 @@ struct of_gpio_chip {
|
||||||
struct gpio_chip gc;
|
struct gpio_chip gc;
|
||||||
int gpio_cells;
|
int gpio_cells;
|
||||||
int (*xlate)(struct of_gpio_chip *of_gc, struct device_node *np,
|
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)
|
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);
|
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,
|
extern int of_mm_gpiochip_add(struct device_node *np,
|
||||||
struct of_mm_gpio_chip *mm_gc);
|
struct of_mm_gpio_chip *mm_gc);
|
||||||
extern int of_gpio_simple_xlate(struct of_gpio_chip *of_gc,
|
extern int of_gpio_simple_xlate(struct of_gpio_chip *of_gc,
|
||||||
struct device_node *np,
|
struct device_node *np,
|
||||||
const void *gpio_spec);
|
const void *gpio_spec,
|
||||||
|
enum of_gpio_flags *flags);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* Drivers may not strictly depend on the GPIO support, so let them link. */
|
/* 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;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_OF_GPIO */
|
#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 */
|
#endif /* __LINUX_OF_GPIO_H */
|
||||||
|
|
Loading…
Reference in a new issue