From 6441dfa8307a564f797b868a74205fe9c2f42eb0 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 22 Nov 2019 09:38:29 +0100 Subject: of: Add of_property_read_string_array() of_property_read_string_array() is used to read a multistring device tree property into an array of strings. This is taken from the kernel. It is implemented around of_property_read_string_helper() which can be used to implement of_property_count_strings() and of_property_read_string_index() as well. Signed-off-by: Sascha Hauer --- include/of.h | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 70 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/include/of.h b/include/of.h index 98ddf795cb..f63a3efe13 100644 --- a/include/of.h +++ b/include/of.h @@ -197,14 +197,12 @@ extern int of_property_read_u64(const struct device_node *np, extern int of_property_read_string(struct device_node *np, const char *propname, const char **out_string); -extern int of_property_read_string_index(struct device_node *np, - const char *propname, - int index, const char **output); extern int of_property_match_string(struct device_node *np, const char *propname, const char *string); -extern int of_property_count_strings(struct device_node *np, - const char *propname); +extern int of_property_read_string_helper(const struct device_node *np, + const char *propname, + const char **out_strs, size_t sz, int index); extern const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, u32 *pu); @@ -444,20 +442,15 @@ static inline int of_property_read_string(struct device_node *np, return -ENOSYS; } -static inline int of_property_read_string_index(struct device_node *np, - const char *propname, int index, const char **output) -{ - return -ENOSYS; -} - static inline int of_property_match_string(struct device_node *np, const char *propname, const char *string) { return -ENOSYS; } -static inline int of_property_count_strings(struct device_node *np, - const char *propname) +static inline int of_property_read_string_helper(const struct device_node *np, + const char *propname, + const char **out_strs, size_t sz, int index) { return -ENOSYS; } @@ -752,6 +745,70 @@ static inline struct device_node *of_find_matching_node( for (child = of_get_next_available_child(parent, NULL); child != NULL; \ child = of_get_next_available_child(parent, child)) +/** + * of_property_read_string_array() - Read an array of strings from a multiple + * strings property. + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @out_strs: output array of string pointers. + * @sz: number of array elements to read. + * + * Search for a property in a device tree node and retrieve a list of + * terminated string values (pointer to data, not a copy) in that property. + * + * If @out_strs is NULL, the number of strings in the property is returned. + */ +static inline int of_property_read_string_array(const struct device_node *np, + const char *propname, const char **out_strs, + size_t sz) +{ + return of_property_read_string_helper(np, propname, out_strs, sz, 0); +} + +/** + * of_property_count_strings() - Find and return the number of strings from a + * multiple strings property. + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * + * Search for a property in a device tree node and retrieve the number of null + * terminated string contain in it. Returns the number of strings on + * success, -EINVAL if the property does not exist, -ENODATA if property + * does not have a value, and -EILSEQ if the string is not null-terminated + * within the length of the property data. + */ +static inline int of_property_count_strings(const struct device_node *np, + const char *propname) +{ + return of_property_read_string_helper(np, propname, NULL, 0, 0); +} + +/** + * of_property_read_string_index() - Find and read a string from a multiple + * strings property. + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @index: index of the string in the list of strings + * @out_string: pointer to null terminated return string, modified only if + * return value is 0. + * + * Search for a property in a device tree node and retrieve a null + * terminated string value (pointer to data, not a copy) in the list of strings + * contained in that property. + * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if + * property does not have a value, and -EILSEQ if the string is not + * null-terminated within the length of the property data. + * + * The out_string pointer is modified only if a valid string can be decoded. + */ +static inline int of_property_read_string_index(const struct device_node *np, + const char *propname, + int index, const char **output) +{ + int rc = of_property_read_string_helper(np, propname, output, 1, index); + return rc < 0 ? rc : 0; +} + /** * of_property_read_bool - Findfrom a property * @np: device node from which the property value is to be read. -- cgit v1.2.3 From 17a517c0fcf21cbd1882108c18fa845930927563 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 22 Nov 2019 09:41:24 +0100 Subject: gpio: Introduce GPIO names This introduces GPIO names. So far we only have labels which are given by the requester. In contrast names are given by the provider and do not change depending on whoever requests a GPIO. The gpio commands now also accept to reference a GPIO by name. The printing of the gpioinfo command is adjusted to nicely print both the label and the name. Signed-off-by: Sascha Hauer --- commands/gpio.c | 4 +++- drivers/gpio/gpiolib.c | 31 +++++++++++++++++++++++++------ include/gpio.h | 6 ++++++ 3 files changed, 34 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/commands/gpio.c b/commands/gpio.c index 951ad2c285..6d88ab6bbe 100644 --- a/commands/gpio.c +++ b/commands/gpio.c @@ -25,7 +25,9 @@ static int get_gpio_and_value(int argc, char *argv[], if (argc < count) return COMMAND_ERROR_USAGE; - *gpio = gpio_find_by_label(argv[1]); + *gpio = gpio_find_by_name(argv[1]); + if (*gpio < 0) + *gpio = gpio_find_by_label(argv[1]); if (*gpio < 0) { ret = kstrtoint(argv[1], 0, gpio); if (ret < 0) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index f96009896a..057cea43cc 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -16,6 +16,7 @@ struct gpio_info { bool requested; bool active_low; char *label; + char *name; }; static struct gpio_info *gpio_desc; @@ -108,6 +109,23 @@ int gpio_find_by_label(const char *label) return -ENOENT; } +int gpio_find_by_name(const char *name) +{ + int i; + + for (i = 0; i < ARCH_NR_GPIOS; i++) { + struct gpio_info *info = &gpio_desc[i]; + + if (!info->chip || !info->name) + continue; + + if (!strcmp(info->name, name)) + return i; + } + + return -ENOENT; +} + void gpio_free(unsigned gpio) { struct gpio_info *gi = gpio_to_desc(gpio); @@ -500,7 +518,7 @@ static int do_gpiolib(int argc, char *argv[]) gi->chip->base, gi->chip->base + gi->chip->ngpio - 1, gi->chip->dev->name); - printf("%*cdir val requested label\n", 13, ' '); + printf(" %-3s %-3s %-9s %-20s %-20s\n", "dir", "val", "requested", "name", "label"); } if (gi->chip->ops->get_direction) @@ -510,11 +528,12 @@ static int do_gpiolib(int argc, char *argv[]) val = gi->chip->ops->get(gi->chip, i - gi->chip->base); - printf(" GPIO %*d: %*s %*s %*s %s\n", 4, i, - 3, (dir < 0) ? "unk" : ((dir == GPIOF_DIR_IN) ? "in" : "out"), - 3, (val < 0) ? "unk" : ((val == 0) ? "lo" : "hi"), - 12, gi->requested ? (gi->active_low ? "active low" : "true") : "false", - (gi->requested && gi->label) ? gi->label : ""); + printf(" GPIO %4d: %-3s %-3s %-9s %-20s %-20s\n", i, + (dir < 0) ? "unk" : ((dir == GPIOF_DIR_IN) ? "in" : "out"), + (val < 0) ? "unk" : ((val == 0) ? "lo" : "hi"), + gi->requested ? (gi->active_low ? "active low" : "true") : "false", + gi->name ? gi->name : "", + gi->label ? gi->label : ""); } return 0; diff --git a/include/gpio.h b/include/gpio.h index 4d5f2c25c7..0c0c0337e0 100644 --- a/include/gpio.h +++ b/include/gpio.h @@ -114,6 +114,11 @@ static inline int gpio_request(unsigned gpio, const char *label) return 0; } +static inline int gpio_find_by_name(const char *name) +{ + return -ENOSYS; +} + static inline int gpio_find_by_label(const char *label) { return -ENOSYS; @@ -141,6 +146,7 @@ static inline void gpio_free_array(const struct gpio *array, size_t num) } #else int gpio_request(unsigned gpio, const char *label); +int gpio_find_by_name(const char *name); int gpio_find_by_label(const char *label); void gpio_free(unsigned gpio); int gpio_request_one(unsigned gpio, unsigned long flags, const char *label); -- cgit v1.2.3