pinctrl: dynamically alloc temp array when parsing dt pinconf options
authorHeiko Stübner <heiko@sntech.de>
Fri, 14 Jun 2013 15:43:55 +0000 (17:43 +0200)
committerMark Brown <broonie@linaro.org>
Fri, 4 Apr 2014 15:22:41 +0000 (16:22 +0100)
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>
drivers/pinctrl/pinconf-generic.c

index ea9da175225290d91f9efb4215bc2311bfad737d..794dad7d68d8ac1adec371c4a71a9f789e4d414e 100644 (file)
@@ -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