aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/gpio.c
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 /drivers/of/gpio.c
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>
Diffstat (limited to 'drivers/of/gpio.c')
-rw-r--r--drivers/of/gpio.c43
1 files changed, 19 insertions, 24 deletions
diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
index ea4f2faab22..7e62d15d60f 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