aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Stübner <heiko@sntech.de>2013-06-14 11:43:55 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-06-17 12:18:31 -0400
commit6abab2d4bec982bcefbe99201ddee5f25227daf4 (patch)
treebc70b4fb53bb9154d3c44c6b592f25a78274e536
parente4a8844c04c00a1a64c6779692e1baff3851c1f7 (diff)
pinctrl: dynamically alloc temp array when parsing dt pinconf options
Allocating the temorary array in pinconf_generic_parse_dt_config on stack might cause problems later on, when the number of options grows over time. Therefore also allocate this array dynamically to be on the safe side. Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Heiko Stuebner <heiko@sntech.de> Reviewed-by: James Hogan <james.hogan@imgtec.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/pinctrl/pinconf-generic.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c
index ea9da1752252..794dad7d68d8 100644
--- a/drivers/pinctrl/pinconf-generic.c
+++ b/drivers/pinctrl/pinconf-generic.c
@@ -182,7 +182,7 @@ int pinconf_generic_parse_dt_config(struct device_node *np,
182 unsigned long **configs, 182 unsigned long **configs,
183 unsigned int *nconfigs) 183 unsigned int *nconfigs)
184{ 184{
185 unsigned long cfg[ARRAY_SIZE(dt_params)]; 185 unsigned long *cfg;
186 unsigned int ncfg = 0; 186 unsigned int ncfg = 0;
187 int ret; 187 int ret;
188 int i; 188 int i;
@@ -191,6 +191,11 @@ int pinconf_generic_parse_dt_config(struct device_node *np,
191 if (!np) 191 if (!np)
192 return -EINVAL; 192 return -EINVAL;
193 193
194 /* allocate a temporary array big enough to hold one of each option */
195 cfg = kzalloc(sizeof(*cfg) * ARRAY_SIZE(dt_params), GFP_KERNEL);
196 if (!cfg)
197 return -ENOMEM;
198
194 for (i = 0; i < ARRAY_SIZE(dt_params); i++) { 199 for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
195 struct pinconf_generic_dt_params *par = &dt_params[i]; 200 struct pinconf_generic_dt_params *par = &dt_params[i];
196 ret = of_property_read_u32(np, par->property, &val); 201 ret = of_property_read_u32(np, par->property, &val);
@@ -208,11 +213,13 @@ int pinconf_generic_parse_dt_config(struct device_node *np,
208 ncfg++; 213 ncfg++;
209 } 214 }
210 215
216 ret = 0;
217
211 /* no configs found at all */ 218 /* no configs found at all */
212 if (ncfg == 0) { 219 if (ncfg == 0) {
213 *configs = NULL; 220 *configs = NULL;
214 *nconfigs = 0; 221 *nconfigs = 0;
215 return 0; 222 goto out;
216 } 223 }
217 224
218 /* 225 /*
@@ -220,11 +227,16 @@ int pinconf_generic_parse_dt_config(struct device_node *np,
220 * found properties. 227 * found properties.
221 */ 228 */
222 *configs = kzalloc(ncfg * sizeof(unsigned long), GFP_KERNEL); 229 *configs = kzalloc(ncfg * sizeof(unsigned long), GFP_KERNEL);
223 if (!*configs) 230 if (!*configs) {
224 return -ENOMEM; 231 ret = -ENOMEM;
232 goto out;
233 }
225 234
226 memcpy(*configs, &cfg, ncfg * sizeof(unsigned long)); 235 memcpy(*configs, cfg, ncfg * sizeof(unsigned long));
227 *nconfigs = ncfg; 236 *nconfigs = ncfg;
228 return 0; 237
238out:
239 kfree(cfg);
240 return ret;
229} 241}
230#endif 242#endif