diff options
author | Heiko Stübner <heiko@sntech.de> | 2013-06-14 17:43:55 +0200 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-04-04 16:22:41 +0100 |
commit | 2feed75860c8e11c5e36a062fe03f60d47b779df (patch) | |
tree | 8f2e86d6e6b5add73a3c54ed75650bea1b77c171 | |
parent | 374b02f771b24b9f4207d6b1c87564968c2615f9 (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>
(cherry picked from commit 6abab2d4bec982bcefbe99201ddee5f25227daf4)
Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r-- | drivers/pinctrl/pinconf-generic.c | 24 |
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, unsigned long **configs, unsigned int *nconfigs) { - unsigned long cfg[ARRAY_SIZE(dt_params)]; + unsigned long *cfg; unsigned int ncfg = 0; int ret; int i; @@ -191,6 +191,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); @@ -208,11 +213,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; } /* @@ -220,11 +227,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 |