diff options
| -rw-r--r-- | drivers/base/regmap/regcache.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index aa8f2efed779..623db7a1f3bd 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -123,6 +123,8 @@ static void regcache_hw_exit(struct regmap *map) int regcache_init(struct regmap *map, const struct regmap_config *config) { + bool sort_defaults = false; + unsigned int reg_prev = 0; int count = 0; int ret; int i; @@ -149,10 +151,16 @@ int regcache_init(struct regmap *map, const struct regmap_config *config) return -EINVAL; } - for (i = 0; i < config->num_reg_defaults; i++) + for (i = 0; i < config->num_reg_defaults; i++) { if (config->reg_defaults[i].reg % map->reg_stride) return -EINVAL; + if (reg_prev > config->reg_defaults[i].reg) + sort_defaults = true; + + reg_prev = config->reg_defaults[i].reg; + } + for (i = 0; i < ARRAY_SIZE(cache_types); i++) if (cache_types[i]->type == map->cache_type) break; @@ -186,6 +194,13 @@ int regcache_init(struct regmap *map, const struct regmap_config *config) sizeof(*map->reg_defaults), GFP_KERNEL); if (!tmp_buf) return -ENOMEM; + + /* regcache_lookup_reg() bsearch()es this array */ + if (sort_defaults) { + dev_warn(map->dev, + "Driver needs fixing: Unsorted reg_defaults, sorting the copy\n"); + regcache_sort_defaults(tmp_buf, map->num_reg_defaults); + } map->reg_defaults = tmp_buf; } else if (map->num_reg_defaults_raw) { count = regcache_count_cacheable_registers(map); @@ -727,14 +742,6 @@ unsigned int regcache_get_val(struct regmap *map, const void *base, return -1; } -static int regcache_default_cmp(const void *a, const void *b) -{ - const struct reg_default *_a = a; - const struct reg_default *_b = b; - - return _a->reg - _b->reg; -} - int regcache_lookup_reg(struct regmap *map, unsigned int reg) { struct reg_default key; @@ -744,7 +751,7 @@ int regcache_lookup_reg(struct regmap *map, unsigned int reg) key.def = 0; r = bsearch(&key, map->reg_defaults, map->num_reg_defaults, - sizeof(struct reg_default), regcache_default_cmp); + sizeof(struct reg_default), regcache_defaults_cmp); if (r) return r - map->reg_defaults; |
