Messages in this thread Patch in this message | | | From | Kyle Moffett <> | Subject | [RFC PATCH 2/3] of_gpio: Add new helpers for easily requesting lots of GPIOs | Date | Fri, 2 Dec 2011 15:38:00 -0500 |
| |
Mirroring the new gpio_request_array() interface, we add several a few helper functions for operating on entire arrays of GPIOs.
Also, to make it easier to write various combinations of "of_get_gpio()" followed by "gpio_request()", add several other new inline wrappers.
Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com> --- drivers/of/gpio.c | 96 +++++++++++++++++++++++++++++ include/linux/of_gpio.h | 154 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 250 insertions(+), 0 deletions(-)
diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c index f349aaf..4c04f2f 100644 --- a/drivers/of/gpio.c +++ b/drivers/of/gpio.c @@ -83,6 +83,47 @@ err0: EXPORT_SYMBOL(of_get_named_gpio_flags); /** + * of_get_gpio_array_flags() - Get array of gpios to use with GPIO API + * @np: device node to get GPIOs from + * @of_gpios: array of "struct of_gpio" to select which GPIOs to look up + * @of_flags: array of "enum of_gpio_flags" to be filled in (may be NULL) + * @gpios: array of "struct gpio" to be filled in + * @num: the number of GPIOs to look up + * + * Takes a constant array of "struct of_gpio" and looks up each item in the + * indicated device-node. The results are stored into the @gpios array, + * along with the optional GPIO "label" and "flags" values from the "of_gpio" + * structure. + * + * If an array of @of_flags is provided then any flags from the translate + * function will be stored into the corresponding element there. + */ +int of_get_gpio_array_flags(struct device_node *np, + const struct of_gpio *of_gpios, enum of_gpio_flags *of_flags, + struct gpio *gpios, size_t num) +{ + int err = 0; + + size_t i; + for (i = 0; i < num; i++) { + /* Copy over the GPIO values */ + gpios[i].flags = of_gpios[i].gpio_flags; + gpios[i].label = of_gpios[i].gpio_label; + + /* Now dig the rest out of the device-tree */ + gpios[i].gpio = of_get_named_gpio_flags(np, + of_gpios[i].propname, of_gpios[i].index, + (of_flags ? &of_flags[num] : NULL)); + + if (gpios[i].gpio < 0) + err = err ?: gpios[i].gpio; + } + + return err; +} +EXPORT_SYMBOL(of_get_gpio_array_flags); + +/** * of_gpio_count_named - Count GPIOs for a device * @np: device node to count GPIOs for * @propname: property name containing gpio specifier(s) @@ -116,6 +157,61 @@ unsigned int of_gpio_count_named(struct device_node *np, const char *propname) EXPORT_SYMBOL(of_gpio_count_named); /** + * of_gpio_request_named_flags() - Request a GPIO using the device-tree + * @np: device node to get GPIO from + * @propname: property name containing gpio specifier(s) + * @index: index of the GPIO + * @flags: a flags pointer to fill in + * @gpio_flags: The setup flags to pass into the GPIO API + * @gpio_label: The label to pass into the GPIO API + * + * This is a simple wrapper around gpio_request_one() that looks up the GPIO + * from the device-tree first using of_get_named_gpio_flags(). + */ +int of_gpio_request_named_flags(struct device_node *np, + const char *propname, int index, enum of_gpio_flags *of_flags, + unsigned long gpio_flags, const char *gpio_label) +{ + int err; + + /* Retrieve the GPIO information from the device-tree */ + int gpio = of_get_named_gpio_flags(np, propname, index, of_flags); + if (gpio < 0) + return gpio; + + /* Request the GPIO */ + err = gpio_request_one(gpio, gpio_flags, gpio_label); + return err ? err : gpio; +} +EXPORT_SYMBOL(of_gpio_request_named_flags); + +/** + * of_gpio_request_array_flags() - Request GPIOs using the device-tree + * @np: device node to get GPIO from + * @of_gpios: array of "struct of_gpio" to select which GPIOs to request + * @of_flags: array of "enum of_gpio_flags" to be filled in (may be NULL) + * @gpios: array of "struct gpio" to be filled in + * @num: the number of GPIOs to request + * + * This is a simple wrapper around gpio_request_array() that looks up the + * GPIOs from the device-tree first using of_get_gpio_array_flags(). + */ +int of_gpio_request_array_flags(struct device_node *np, + const struct of_gpio *of_gpios, enum of_gpio_flags *of_flags, + struct gpio *gpios, size_t num) +{ + /* Retrieve the GPIO information from the device-tree */ + int err = of_get_gpio_array_flags(np, of_gpios, + of_flags, gpios, num); + if (err) + return err; + + /* Request all of the GPIOs */ + return gpio_request_array(gpios, num); +} +EXPORT_SYMBOL(of_gpio_request_array_flags); + +/** * of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags * @gc: pointer to the gpio_chip structure * @np: device node of the GPIO chip diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h index 1411a06..babce09 100644 --- a/include/linux/of_gpio.h +++ b/include/linux/of_gpio.h @@ -30,6 +30,20 @@ enum of_gpio_flags { OF_GPIO_ACTIVE_LOW = 0x1, }; +/* + * This struct is passed to of_named_gpio_request_array() to initialize the + * passed-in array of "struct gpio" for use by gpio_request_array(). + */ +struct of_gpio { + /* These values are used to locate the GPIO in the device-tree */ + const char *propname; + int index; + + /* These values are used to request the discovered GPIO */ + unsigned long gpio_flags; + const char *gpio_label; +}; + #ifdef CONFIG_OF_GPIO /* @@ -49,9 +63,21 @@ static inline struct of_mm_gpio_chip *to_of_mm_gpio_chip(struct gpio_chip *gc) extern int of_get_named_gpio_flags(struct device_node *np, const char *list_name, int index, enum of_gpio_flags *flags); +extern int of_get_gpio_array_flags(struct device_node *np, + const struct of_gpio *of_gpios, enum of_gpio_flags *of_flags, + struct gpio *gpios, size_t num); + extern unsigned int of_gpio_count_named(struct device_node *np, const char *propname); +extern int of_gpio_request_named_flags(struct device_node *np, + const char *propname, int index, enum of_gpio_flags *of_flags, + unsigned long gpio_flags, const char *gpio_label); + +extern int of_gpio_request_array_flags(struct device_node *np, + const struct of_gpio *of_gpios, enum of_gpio_flags *of_flags, + struct gpio *gpios, size_t num); + extern int of_mm_gpiochip_add(struct device_node *np, struct of_mm_gpio_chip *mm_gc); @@ -70,12 +96,51 @@ static inline int of_get_named_gpio_flags(struct device_node *np, return -ENOSYS; } +static inline int of_get_gpio_array_flags(struct device_node *np, + const struct of_gpio *of_gpios, enum of_gpio_flags *of_flags, + struct gpio *gpios, size_t num) +{ + /* + * This function must always initialize all the "struct gpio"s even + * if they cannot be probed to allow the user to detect the source of + * each error. + */ + size_t i; + for (i = 0; i < num; i++) { + gpios[i].gpio = -ENOSYS; + gpios[i].label = of_gpios[i].label; + gpios[i].flags = of_gpios[i].flags; + } + return -ENOSYS; +} + static inline unsigned int of_gpio_count_named(struct device_node *np, const char *propname) { return 0; } +static inline int of_gpio_request_named_flags(struct device_node *np, + const char *propname, int index, enum of_gpio_flags *of_flags, + unsigned long gpio_flags, const char *gpio_label) +{ + return -ENOSYS; +} + +static inline int of_gpio_request_array_flags(struct device_node *np, + const struct of_gpio *of_gpios, enum of_gpio_flags *of_flags, + struct gpio *gpios, size_t num) +{ + /* Same initialization as of_get_gpio_array_flags() above */ + size_t i; + for (i = 0; i < num; i++) { + gpios[i].gpio = -ENOSYS; + gpios[i].label = of_gpios[i].label; + gpios[i].flags = of_gpios[i].flags; + } + return -ENOSYS; +} + static inline int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, const void *gpio_spec, u32 *flags) @@ -153,4 +218,93 @@ static inline int of_get_gpio(struct device_node *np, int index) return of_get_gpio_flags(np, index, NULL); } +/** + * of_gpio_request_one_flags() - Request a GPIO using the device-tree + * @np: device node to get GPIO from + * @index: index of the GPIO + * @flags: a flags pointer to fill in + * @gpio_flags: The setup flags to pass into the GPIO API + * @gpio_label: The label to pass into the GPIO API + * + * This is a simple wrapper around gpio_request_one() that looks up the GPIO + * from the device-tree first using of_get_gpio_flags(). + */ +static inline int of_gpio_request_one_flags(struct device_node *np, + int index, enum of_gpio_flags *of_flags, + unsigned long gpio_flags, const char *gpio_label) +{ + return of_gpio_request_named_flags(np, "gpios", index, + of_flags, gpio_flags, gpio_label); +} + +/** + * of_gpio_request_named() - Request a GPIO using the device-tree + * @np: device node to get GPIO from + * @propname: Name of property containing gpio specifier(s) + * @index: index of the GPIO + * @gpio_flags: The setup flags to pass into the GPIO API + * @gpio_label: The label to pass into the GPIO API + * + * This is a simple wrapper around gpio_request_one() that looks up the GPIO + * from the device-tree first using of_get_named_gpio(). + */ +static inline int of_gpio_request_named(struct device_node *np, + const char *propname, int index, + unsigned long gpio_flags, const char *gpio_label) +{ + return of_gpio_request_named_flags(np, propname, index, + NULL, gpio_flags, gpio_label); +} + +/** + * of_gpio_request_one() - Request a GPIO using the device-tree + * @np: device node to get GPIO from + * @index: index of the GPIO + * @gpio_flags: The setup flags to pass into the GPIO API + * @gpio_label: The label to pass into the GPIO API + * + * This is a simple wrapper around gpio_request_one() that looks up the GPIO + * from the device-tree first using of_get_gpio(). + */ +static inline int of_gpio_request_one(struct device_node *np, + int index, unsigned long gpio_flags, const char *gpio_label) +{ + return of_gpio_request_one_flags(np, index, NULL, + gpio_flags, gpio_label); +} + +/** + * of_get_gpio_array() - Get an array of GPIO numbers to use with GPIO API + * @np: device node to get GPIO from + * @of_gpios: array of "struct of_gpio" to select which GPIOs to look up + * @gpios: array of "struct gpio" to be filled in + * @num: the number of GPIOs to look up + * + * Takes a constant array of "struct of_gpio" and looks up each item in the + * indicated device-node. The results are stored into the @gpios array, + * along with the optional GPIO "label" and "flags" values from the "of_gpio" + * structure. + */ +static inline int of_get_gpio_array(struct device_node *np, + const struct of_gpio *of_gpios, struct gpio *gpios, size_t num) +{ + return of_get_gpio_array_flags(np, of_gpios, NULL, gpios, num); +} + +/** + * of_gpio_request_array() - Request GPIOs using the device-tree + * @np: device node to get GPIO from + * @of_gpios: array of "struct of_gpio" to select which GPIOs to request + * @gpios: array of "struct gpio" to be filled in + * @num: the number of GPIOs to request + * + * This is a simple wrapper around gpio_request_array() that looks up the + * GPIOs from the device-tree first using of_get_gpio_array(). + */ +static inline int of_gpio_request_array(struct device_node *np, + const struct of_gpio *of_gpios, struct gpio *gpios, size_t num) +{ + return of_gpio_request_array_flags(np, of_gpios, NULL, gpios, num); +} + #endif /* __LINUX_OF_GPIO_H */ -- 1.7.2.5
| |