Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

of: create of_phandle_args to simplify return of phandle parsing data

of_parse_phandle_with_args() needs to return quite a bit of data. Rather
than making each datum a separate **out_ argument, this patch creates
struct of_phandle_args to contain all the returned data and reworks the
user of the function. This patch also enables of_parse_phandle_with_args()
to return the device node pointer for the phandle node.

This patch also ends up being fairly major surgery to
of_parse_handle_with_args(). The existing structure didn't work well
when extending to use of_phandle_args, and I discovered bugs during testing.
I also took the opportunity to rename the function to be like the
existing of_parse_phandle().

v2: - moved declaration of of_phandle_args to fix compile on non-DT builds
- fixed incorrect index in example usage
- fixed incorrect return code handling for empty entries

Reviewed-by: Shawn Guo <shawn.guo@freescale.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>

+111 -102
+74 -70
drivers/of/base.c
··· 824 824 EXPORT_SYMBOL(of_parse_phandle); 825 825 826 826 /** 827 - * of_parse_phandles_with_args - Find a node pointed by phandle in a list 827 + * of_parse_phandle_with_args() - Find a node pointed by phandle in a list 828 828 * @np: pointer to a device tree node containing a list 829 829 * @list_name: property name that contains a list 830 830 * @cells_name: property name that specifies phandles' arguments count 831 831 * @index: index of a phandle to parse out 832 - * @out_node: optional pointer to device_node struct pointer (will be filled) 833 - * @out_args: optional pointer to arguments pointer (will be filled) 832 + * @out_args: optional pointer to output arguments structure (will be filled) 834 833 * 835 834 * This function is useful to parse lists of phandles and their arguments. 836 - * Returns 0 on success and fills out_node and out_args, on error returns 837 - * appropriate errno value. 835 + * Returns 0 on success and fills out_args, on error returns appropriate 836 + * errno value. 837 + * 838 + * Caller is responsible to call of_node_put() on the returned out_args->node 839 + * pointer. 838 840 * 839 841 * Example: 840 842 * ··· 853 851 * } 854 852 * 855 853 * To get a device_node of the `node2' node you may call this: 856 - * of_parse_phandles_with_args(node3, "list", "#list-cells", 2, &node2, &args); 854 + * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args); 857 855 */ 858 - int of_parse_phandles_with_args(struct device_node *np, const char *list_name, 856 + int of_parse_phandle_with_args(struct device_node *np, const char *list_name, 859 857 const char *cells_name, int index, 860 - struct device_node **out_node, 861 - const void **out_args) 858 + struct of_phandle_args *out_args) 862 859 { 863 - int ret = -EINVAL; 864 - const __be32 *list; 865 - const __be32 *list_end; 866 - int size; 867 - int cur_index = 0; 860 + const __be32 *list, *list_end; 861 + int size, cur_index = 0; 862 + uint32_t count = 0; 868 863 struct device_node *node = NULL; 869 - const void *args = NULL; 864 + phandle phandle; 870 865 866 + /* Retrieve the phandle list property */ 871 867 list = of_get_property(np, list_name, &size); 872 - if (!list) { 873 - ret = -ENOENT; 874 - goto err0; 875 - } 868 + if (!list) 869 + return -EINVAL; 876 870 list_end = list + size / sizeof(*list); 877 871 872 + /* Loop over the phandles until all the requested entry is found */ 878 873 while (list < list_end) { 879 - const __be32 *cells; 880 - phandle phandle; 874 + count = 0; 881 875 876 + /* 877 + * If phandle is 0, then it is an empty entry with no 878 + * arguments. Skip forward to the next entry. 879 + */ 882 880 phandle = be32_to_cpup(list++); 883 - args = list; 881 + if (phandle) { 882 + /* 883 + * Find the provider node and parse the #*-cells 884 + * property to determine the argument length 885 + */ 886 + node = of_find_node_by_phandle(phandle); 887 + if (!node) { 888 + pr_err("%s: could not find phandle\n", 889 + np->full_name); 890 + break; 891 + } 892 + if (of_property_read_u32(node, cells_name, &count)) { 893 + pr_err("%s: could not get %s for %s\n", 894 + np->full_name, cells_name, 895 + node->full_name); 896 + break; 897 + } 884 898 885 - /* one cell hole in the list = <>; */ 886 - if (!phandle) 887 - goto next; 888 - 889 - node = of_find_node_by_phandle(phandle); 890 - if (!node) { 891 - pr_debug("%s: could not find phandle\n", 892 - np->full_name); 893 - goto err0; 899 + /* 900 + * Make sure that the arguments actually fit in the 901 + * remaining property data length 902 + */ 903 + if (list + count > list_end) { 904 + pr_err("%s: arguments longer than property\n", 905 + np->full_name); 906 + break; 907 + } 894 908 } 895 909 896 - cells = of_get_property(node, cells_name, &size); 897 - if (!cells || size != sizeof(*cells)) { 898 - pr_debug("%s: could not get %s for %s\n", 899 - np->full_name, cells_name, node->full_name); 900 - goto err1; 901 - } 910 + /* 911 + * All of the error cases above bail out of the loop, so at 912 + * this point, the parsing is successful. If the requested 913 + * index matches, then fill the out_args structure and return, 914 + * or return -ENOENT for an empty entry. 915 + */ 916 + if (cur_index == index) { 917 + if (!phandle) 918 + return -ENOENT; 902 919 903 - list += be32_to_cpup(cells); 904 - if (list > list_end) { 905 - pr_debug("%s: insufficient arguments length\n", 906 - np->full_name); 907 - goto err1; 920 + if (out_args) { 921 + int i; 922 + if (WARN_ON(count > MAX_PHANDLE_ARGS)) 923 + count = MAX_PHANDLE_ARGS; 924 + out_args->np = node; 925 + out_args->args_count = count; 926 + for (i = 0; i < count; i++) 927 + out_args->args[i] = be32_to_cpup(list++); 928 + } 929 + return 0; 908 930 } 909 - next: 910 - if (cur_index == index) 911 - break; 912 931 913 932 of_node_put(node); 914 933 node = NULL; 915 - args = NULL; 934 + list += count; 916 935 cur_index++; 917 936 } 918 937 919 - if (!node) { 920 - /* 921 - * args w/o node indicates that the loop above has stopped at 922 - * the 'hole' cell. Report this differently. 923 - */ 924 - if (args) 925 - ret = -EEXIST; 926 - else 927 - ret = -ENOENT; 928 - goto err0; 929 - } 930 - 931 - if (out_node) 932 - *out_node = node; 933 - if (out_args) 934 - *out_args = args; 935 - 936 - return 0; 937 - err1: 938 - of_node_put(node); 939 - err0: 940 - pr_debug("%s failed with status %d\n", __func__, ret); 941 - return ret; 938 + /* Loop exited without finding a valid entry; return an error */ 939 + if (node) 940 + of_node_put(node); 941 + return -EINVAL; 942 942 } 943 - EXPORT_SYMBOL(of_parse_phandles_with_args); 943 + EXPORT_SYMBOL(of_parse_phandle_with_args); 944 944 945 945 /** 946 946 * prom_add_property - Add a property to a node
+19 -24
drivers/of/gpio.c
··· 35 35 int index, enum of_gpio_flags *flags) 36 36 { 37 37 int ret; 38 - struct device_node *gpio_np; 39 38 struct gpio_chip *gc; 40 - int size; 41 - const void *gpio_spec; 42 - const __be32 *gpio_cells; 39 + struct of_phandle_args gpiospec; 43 40 44 - ret = of_parse_phandles_with_args(np, propname, "#gpio-cells", index, 45 - &gpio_np, &gpio_spec); 41 + ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index, 42 + &gpiospec); 46 43 if (ret) { 47 44 pr_debug("%s: can't parse gpios property\n", __func__); 48 45 goto err0; 49 46 } 50 47 51 - gc = of_node_to_gpiochip(gpio_np); 48 + gc = of_node_to_gpiochip(gpiospec.np); 52 49 if (!gc) { 53 50 pr_debug("%s: gpio controller %s isn't registered\n", 54 - np->full_name, gpio_np->full_name); 51 + np->full_name, gpiospec.np->full_name); 55 52 ret = -ENODEV; 56 53 goto err1; 57 54 } 58 55 59 - gpio_cells = of_get_property(gpio_np, "#gpio-cells", &size); 60 - if (!gpio_cells || size != sizeof(*gpio_cells) || 61 - be32_to_cpup(gpio_cells) != gc->of_gpio_n_cells) { 56 + if (gpiospec.args_count != gc->of_gpio_n_cells) { 62 57 pr_debug("%s: wrong #gpio-cells for %s\n", 63 - np->full_name, gpio_np->full_name); 58 + np->full_name, gpiospec.np->full_name); 64 59 ret = -EINVAL; 65 60 goto err1; 66 61 } ··· 64 69 if (flags) 65 70 *flags = 0; 66 71 67 - ret = gc->of_xlate(gc, np, gpio_spec, flags); 72 + ret = gc->of_xlate(gc, &gpiospec, flags); 68 73 if (ret < 0) 69 74 goto err1; 70 75 71 76 ret += gc->base; 72 77 err1: 73 - of_node_put(gpio_np); 78 + of_node_put(gpiospec.np); 74 79 err0: 75 80 pr_debug("%s exited with status %d\n", __func__, ret); 76 81 return ret; ··· 100 105 do { 101 106 int ret; 102 107 103 - ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", 104 - cnt, NULL, NULL); 108 + ret = of_parse_phandle_with_args(np, "gpios", "#gpio-cells", 109 + cnt, NULL); 105 110 /* A hole in the gpios = <> counts anyway. */ 106 111 if (ret < 0 && ret != -EEXIST) 107 112 break; ··· 122 127 * gpio chips. This function performs only one sanity check: whether gpio 123 128 * is less than ngpios (that is specified in the gpio_chip). 124 129 */ 125 - int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, 126 - const void *gpio_spec, u32 *flags) 130 + int of_gpio_simple_xlate(struct gpio_chip *gc, 131 + const struct of_phandle_args *gpiospec, u32 *flags) 127 132 { 128 - const __be32 *gpio = gpio_spec; 129 - const u32 n = be32_to_cpup(gpio); 130 - 131 133 /* 132 134 * We're discouraging gpio_cells < 2, since that way you'll have to 133 135 * write your own xlate function (that will have to retrive the GPIO ··· 136 144 return -EINVAL; 137 145 } 138 146 139 - if (n > gc->ngpio) 147 + if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells)) 148 + return -EINVAL; 149 + 150 + if (gpiospec->args[0] > gc->ngpio) 140 151 return -EINVAL; 141 152 142 153 if (flags) 143 - *flags = be32_to_cpu(gpio[1]); 154 + *flags = gpiospec->args[1]; 144 155 145 - return n; 156 + return gpiospec->args[0]; 146 157 } 147 158 EXPORT_SYMBOL(of_gpio_simple_xlate); 148 159
+3 -2
include/asm-generic/gpio.h
··· 4 4 #include <linux/kernel.h> 5 5 #include <linux/types.h> 6 6 #include <linux/errno.h> 7 + #include <linux/of.h> 7 8 8 9 #ifdef CONFIG_GPIOLIB 9 10 ··· 129 128 */ 130 129 struct device_node *of_node; 131 130 int of_gpio_n_cells; 132 - int (*of_xlate)(struct gpio_chip *gc, struct device_node *np, 133 - const void *gpio_spec, u32 *flags); 131 + int (*of_xlate)(struct gpio_chip *gc, 132 + const struct of_phandle_args *gpiospec, u32 *flags); 134 133 #endif 135 134 }; 136 135
+9 -2
include/linux/of.h
··· 65 65 #endif 66 66 }; 67 67 68 + #define MAX_PHANDLE_ARGS 8 69 + struct of_phandle_args { 70 + struct device_node *np; 71 + int args_count; 72 + uint32_t args[MAX_PHANDLE_ARGS]; 73 + }; 74 + 68 75 #ifdef CONFIG_OF 69 76 70 77 /* Pointer for first entry in chain of all nodes. */ ··· 237 230 extern struct device_node *of_parse_phandle(struct device_node *np, 238 231 const char *phandle_name, 239 232 int index); 240 - extern int of_parse_phandles_with_args(struct device_node *np, 233 + extern int of_parse_phandle_with_args(struct device_node *np, 241 234 const char *list_name, const char *cells_name, int index, 242 - struct device_node **out_node, const void **out_args); 235 + struct of_phandle_args *out_args); 243 236 244 237 extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)); 245 238 extern int of_alias_get_id(struct device_node *np, const char *stem);
+6 -4
include/linux/of_gpio.h
··· 18 18 #include <linux/kernel.h> 19 19 #include <linux/errno.h> 20 20 #include <linux/gpio.h> 21 + #include <linux/of.h> 21 22 22 23 struct device_node; 23 24 ··· 58 57 extern void of_gpiochip_add(struct gpio_chip *gc); 59 58 extern void of_gpiochip_remove(struct gpio_chip *gc); 60 59 extern struct gpio_chip *of_node_to_gpiochip(struct device_node *np); 61 - extern int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, 62 - const void *gpio_spec, u32 *flags); 60 + extern int of_gpio_simple_xlate(struct gpio_chip *gc, 61 + const struct of_phandle_args *gpiospec, 62 + u32 *flags); 63 63 64 64 #else /* CONFIG_OF_GPIO */ 65 65 ··· 77 75 } 78 76 79 77 static inline int of_gpio_simple_xlate(struct gpio_chip *gc, 80 - struct device_node *np, 81 - const void *gpio_spec, u32 *flags) 78 + const struct of_phandle_args *gpiospec, 79 + u32 *flags) 82 80 { 83 81 return -ENOSYS; 84 82 }