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)
committer黄涛 <huangtao@rock-chips.com>
Sat, 30 Nov 2013 04:04:37 +0000 (12:04 +0800)
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>
drivers/pinctrl/pinconf-generic.c

index f6e6ea1b7643db572ed1d7d7cd4661f27d6d9cff..d6479631fae8e6f38f5eff63d79ca4382cc3daa6 100644 (file)
@@ -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