Commit 6abab2d4 authored by Heiko Stübner's avatar Heiko Stübner Committed by Linus Walleij

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: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarHeiko Stuebner <heiko@sntech.de>
Reviewed-by: default avatarJames Hogan <james.hogan@imgtec.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent e4a8844c
...@@ -182,7 +182,7 @@ int pinconf_generic_parse_dt_config(struct device_node *np, ...@@ -182,7 +182,7 @@ int pinconf_generic_parse_dt_config(struct device_node *np,
unsigned long **configs, unsigned long **configs,
unsigned int *nconfigs) unsigned int *nconfigs)
{ {
unsigned long cfg[ARRAY_SIZE(dt_params)]; unsigned long *cfg;
unsigned int ncfg = 0; unsigned int ncfg = 0;
int ret; int ret;
int i; int i;
...@@ -191,6 +191,11 @@ int pinconf_generic_parse_dt_config(struct device_node *np, ...@@ -191,6 +191,11 @@ int pinconf_generic_parse_dt_config(struct device_node *np,
if (!np) if (!np)
return -EINVAL; return -EINVAL;
/* allocate a temporary array big enough to hold one of each option */
cfg = kzalloc(sizeof(*cfg) * ARRAY_SIZE(dt_params), GFP_KERNEL);
if (!cfg)
return -ENOMEM;
for (i = 0; i < ARRAY_SIZE(dt_params); i++) { for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
struct pinconf_generic_dt_params *par = &dt_params[i]; struct pinconf_generic_dt_params *par = &dt_params[i];
ret = of_property_read_u32(np, par->property, &val); ret = of_property_read_u32(np, par->property, &val);
...@@ -208,11 +213,13 @@ int pinconf_generic_parse_dt_config(struct device_node *np, ...@@ -208,11 +213,13 @@ int pinconf_generic_parse_dt_config(struct device_node *np,
ncfg++; ncfg++;
} }
ret = 0;
/* no configs found at all */ /* no configs found at all */
if (ncfg == 0) { if (ncfg == 0) {
*configs = NULL; *configs = NULL;
*nconfigs = 0; *nconfigs = 0;
return 0; goto out;
} }
/* /*
...@@ -220,11 +227,16 @@ int pinconf_generic_parse_dt_config(struct device_node *np, ...@@ -220,11 +227,16 @@ int pinconf_generic_parse_dt_config(struct device_node *np,
* found properties. * found properties.
*/ */
*configs = kzalloc(ncfg * sizeof(unsigned long), GFP_KERNEL); *configs = kzalloc(ncfg * sizeof(unsigned long), GFP_KERNEL);
if (!*configs) if (!*configs) {
return -ENOMEM; ret = -ENOMEM;
goto out;
}
memcpy(*configs, &cfg, ncfg * sizeof(unsigned long)); memcpy(*configs, cfg, ncfg * sizeof(unsigned long));
*nconfigs = ncfg; *nconfigs = ncfg;
return 0;
out:
kfree(cfg);
return ret;
} }
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment