From: Heiko Stübner Date: Fri, 14 Jun 2013 15:43:55 +0000 (+0200) Subject: pinctrl: dynamically alloc temp array when parsing dt pinconf options X-Git-Tag: firefly_0821_release~6475 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=7058de4ba0b1e32cc6e4706d47e57ae272042a1b;p=firefly-linux-kernel-4.4.55.git 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 Signed-off-by: Heiko Stuebner Reviewed-by: James Hogan Signed-off-by: Linus Walleij --- diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c index f6e6ea1b7643..d6479631fae8 100644 --- a/drivers/pinctrl/pinconf-generic.c +++ b/drivers/pinctrl/pinconf-generic.c @@ -178,7 +178,7 @@ int pinconf_generic_parse_dt_config(struct device_node *np, unsigned long **configs, unsigned int *nconfigs) { - unsigned long cfg[ARRAY_SIZE(dt_params)]; + unsigned long *cfg; unsigned int ncfg = 0; int ret; int i; @@ -187,6 +187,11 @@ int pinconf_generic_parse_dt_config(struct device_node *np, if (!np) 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++) { struct pinconf_generic_dt_params *par = &dt_params[i]; ret = of_property_read_u32(np, par->property, &val); @@ -204,11 +209,13 @@ int pinconf_generic_parse_dt_config(struct device_node *np, ncfg++; } + ret = 0; + /* no configs found at all */ if (ncfg == 0) { *configs = NULL; *nconfigs = 0; - return 0; + goto out; } /* @@ -216,11 +223,16 @@ int pinconf_generic_parse_dt_config(struct device_node *np, * found properties. */ *configs = kzalloc(ncfg * sizeof(unsigned long), GFP_KERNEL); - if (!*configs) - return -ENOMEM; + if (!*configs) { + ret = -ENOMEM; + goto out; + } - memcpy(*configs, &cfg, ncfg * sizeof(unsigned long)); + memcpy(*configs, cfg, ncfg * sizeof(unsigned long)); *nconfigs = ncfg; - return 0; + +out: + kfree(cfg); + return ret; } #endif