From 5bd83ed0984b0b0ac51d648b0ec167b36291f87e Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 9 Oct 2014 17:02:53 +0800 Subject: regmap: cache: cleanup regcache_hw_init() Remove the redundant code for regmap cache. Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- drivers/base/regmap/regcache.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index f1280dc356d0..7558e6b01c04 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -57,12 +57,9 @@ static int regcache_hw_init(struct regmap *map) } /* calculate the size of reg_defaults */ - for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) { - val = regcache_get_val(map, map->reg_defaults_raw, i); - if (regmap_volatile(map, i * map->reg_stride)) - continue; - count++; - } + for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) + if (!regmap_volatile(map, i * map->reg_stride)) + count++; map->reg_defaults = kmalloc(count * sizeof(struct reg_default), GFP_KERNEL); -- cgit v1.2.3 From ba3f1c85a6e05e0ff90215d817249617fcbee523 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 9 Oct 2014 17:02:54 +0800 Subject: regmap: cache: fix errno in regcache_hw_init() When kmalloc() fails, we should return -ENOMEM. Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- drivers/base/regmap/regcache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/base') diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 7558e6b01c04..6bec659e35d9 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -44,7 +44,7 @@ static int regcache_hw_init(struct regmap *map) map->cache_bypass = 1; tmp_buf = kmalloc(map->cache_size_raw, GFP_KERNEL); if (!tmp_buf) - return -EINVAL; + return -ENOMEM; ret = regmap_raw_read(map, 0, tmp_buf, map->num_reg_defaults_raw); map->cache_bypass = cache_bypass; -- cgit v1.2.3 From fbba43c527d851088a891ed83346d5cc9f095b64 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 9 Oct 2014 17:02:55 +0800 Subject: regmap: cache: speed regcache_hw_init() up. This may speed regcache_hw_init() up for some cases that there has volatile registers. Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- drivers/base/regmap/regcache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/base') diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 6bec659e35d9..0852c890b4b5 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -71,9 +71,9 @@ static int regcache_hw_init(struct regmap *map) /* fill the reg_defaults */ map->num_reg_defaults = count; for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) { - val = regcache_get_val(map, map->reg_defaults_raw, i); if (regmap_volatile(map, i * map->reg_stride)) continue; + val = regcache_get_val(map, map->reg_defaults_raw, i); map->reg_defaults[j].reg = i * map->reg_stride; map->reg_defaults[j].def = val; j++; -- cgit v1.2.3 From 06f9c24e55075e50ebc8b249a7853ad31bc1b3d1 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 9 Oct 2014 17:02:56 +0800 Subject: regmap: cache: use kmalloc_array instead of kmalloc This patch fixes checkpatch.pl warning for regmap cache. WARNING : prefer kmalloc_array over kmalloc with multiply Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- drivers/base/regmap/regcache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 0852c890b4b5..726d956f6a29 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -61,8 +61,8 @@ static int regcache_hw_init(struct regmap *map) if (!regmap_volatile(map, i * map->reg_stride)) count++; - map->reg_defaults = kmalloc(count * sizeof(struct reg_default), - GFP_KERNEL); + map->reg_defaults = kmalloc_array(count, sizeof(struct reg_default), + GFP_KERNEL); if (!map->reg_defaults) { ret = -ENOMEM; goto err_free; -- cgit v1.2.3 From fb70067e4a2cc45d273864f071fd6cf62143137a Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 9 Oct 2014 17:02:57 +0800 Subject: regmap: cache: Fix possible ZERO_SIZE_PTR pointer dereferencing error. When all the registers are volatile(unlikely, but logically and mostly will happen for some 'device' who has very few registers), then the count will be euqal to 0, then kmalloc() will return ZERO_SIZE_PTR, which equals to ((void *)16). So this patch fix this with just doing the zero check before calling kmalloc(). If the count == 0, so we can make sure that all the registers are volatile, so no cache is need. Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- drivers/base/regmap/regcache.c | 50 ++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 21 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 726d956f6a29..d815929ba745 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -36,6 +36,23 @@ static int regcache_hw_init(struct regmap *map) if (!map->num_reg_defaults_raw) return -EINVAL; + /* calculate the size of reg_defaults */ + for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) + if (!regmap_volatile(map, i * map->reg_stride)) + count++; + + /* all registers are volatile, so just bypass */ + if (!count) { + map->cache_bypass = true; + return 0; + } + + map->num_reg_defaults = count; + map->reg_defaults = kmalloc_array(count, sizeof(struct reg_default), + GFP_KERNEL); + if (!map->reg_defaults) + return -ENOMEM; + if (!map->reg_defaults_raw) { u32 cache_bypass = map->cache_bypass; dev_warn(map->dev, "No cache defaults, reading back from HW\n"); @@ -43,33 +60,21 @@ static int regcache_hw_init(struct regmap *map) /* Bypass the cache access till data read from HW*/ map->cache_bypass = 1; tmp_buf = kmalloc(map->cache_size_raw, GFP_KERNEL); - if (!tmp_buf) - return -ENOMEM; + if (!tmp_buf) { + ret = -ENOMEM; + goto err_free; + } ret = regmap_raw_read(map, 0, tmp_buf, map->num_reg_defaults_raw); map->cache_bypass = cache_bypass; - if (ret < 0) { - kfree(tmp_buf); - return ret; - } + if (ret < 0) + goto err_cache_free; + map->reg_defaults_raw = tmp_buf; map->cache_free = 1; } - /* calculate the size of reg_defaults */ - for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) - if (!regmap_volatile(map, i * map->reg_stride)) - count++; - - map->reg_defaults = kmalloc_array(count, sizeof(struct reg_default), - GFP_KERNEL); - if (!map->reg_defaults) { - ret = -ENOMEM; - goto err_free; - } - /* fill the reg_defaults */ - map->num_reg_defaults = count; for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) { if (regmap_volatile(map, i * map->reg_stride)) continue; @@ -81,9 +86,10 @@ static int regcache_hw_init(struct regmap *map) return 0; +err_cache_free: + kfree(tmp_buf); err_free: - if (map->cache_free) - kfree(map->reg_defaults_raw); + kfree(map->reg_defaults); return ret; } @@ -147,6 +153,8 @@ int regcache_init(struct regmap *map, const struct regmap_config *config) ret = regcache_hw_init(map); if (ret < 0) return ret; + if (map->cache_bypass) + return 0; } if (!map->max_register) -- cgit v1.2.3