mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
regmap: Fixes for v7.2
These patches fix some issues which were noticed in some drivers where caches were not fully resynced after suspend. Drivers are supposed to be sorting the table of register defaults they provide to the core and the core was relying on that but it turns out there are many cases where this does not happen, it's easy to get wrong when using named defines for registers rather than numbers. It is more robust to remove the requirement for sorting and instead have the core ensure everything it needs sorting is sorted so do that. There will be patches during the merge window sorting the tables in drivers since it is more efficient to do that but this will just be a minor performance win rather than a correctness fix. -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmp5yXcACgkQJNaLcl1U h9AdhQf+OuDvmAGl6VpkbUBQqK/E9YO7mXqEOKGpbhi5e4CDUN+pY1HsMIgChMC7 e2gvLNwUY1zYUlon2RzXAYJ3fV/JmIZmz/8qp65VN2qljltAS+PT47qYpZb0WKKa RAGdUOCthmaNwGou/ofO/MpAqRbgXY89H3AlBBRfR5jGsVJTqyvMsKVCR2h/X7SN 7rlEV6/a9gubTGrZEXaNEl6SvCsI1JmTidQHO4A9ROvo38alrYU4fMCgbSJ/W7cA U5oBbO0qIixgR/xGNkMrLMKoIRfXElJ2he9idOQDcfbAMzlUeyZkj2xHqF9gHNRs Zx/l0QrCagcLjUNVDMhpgE85Q+dfqQ== =7QwV -----END PGP SIGNATURE----- Merge tag 'regmap-fix-v7.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap Pull regmap fixes from Mark Brown: "These fix some issues which were noticed in some drivers where caches were not fully resynced after suspend. Drivers are supposed to be sorting the table of register defaults they provide to the core and the core was relying on that but it turns out there are many cases where this does not happen, it's easy to get wrong when using named defines for registers rather than numbers. It is more robust to remove the requirement for sorting and instead have the core ensure everything it needs sorting is sorted so do that. There will be patches during the merge window sorting the tables in drivers since it is more efficient to do that but this will just be a minor performance win rather than a correctness fix" * tag 'regmap-fix-v7.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap: regcache: Sort the local copy of an unsorted reg_defaults array regcache: Use a consistent sort for defaults table
This commit is contained in:
commit
d58772d852
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user