diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2011-12-12 11:25:57 -0500 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2011-12-12 15:40:16 -0500 |
commit | 15c9a0acc3f7873db4b7d35d016729b2dc229b49 (patch) | |
tree | cfd9d6dd645d8116709521001e90dd75ffc19992 /drivers/of/gpio.c | |
parent | 1a2d397a6eb5cf40c382d9e3d4bc04aaeb025336 (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.c | 43 |
1 files changed, 19 insertions, 24 deletions
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; |
77 | err1: | 72 | err1: |
78 | of_node_put(gpio_np); | 73 | of_node_put(gpiospec.np); |
79 | err0: | 74 | err0: |
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 | */ |
130 | int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, | 125 | int 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 | } |
155 | EXPORT_SYMBOL(of_gpio_simple_xlate); | 150 | EXPORT_SYMBOL(of_gpio_simple_xlate); |
156 | 151 | ||