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