regcache: Preserve cache synchronization errors in regcache_sync()

regcache_sync() currently stores the return value from both cache
synchronization and selector register rewriting in the same variable.
As a result, a successful selector register rewrite can overwrite an
earlier cache synchronization error, causing regcache_sync() to return
success even though synchronization failed.

Track the two operations with separate return variables and preserve the
cache synchronization error. Errors from rewriting selector registers are
returned only if cache synchronization completed successfully.

Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
Link: https://patch.msgid.link/20260713050312.38729-2-phucduc.bui@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
bui duc phuc 2026-07-13 12:03:11 +07:00 committed by Mark Brown
parent 35845da94b
commit 85da24aac1
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -401,7 +401,8 @@ static int rbtree_all(const void *key, const struct rb_node *node)
*/
int regcache_sync(struct regmap *map)
{
int ret = 0;
int sync_ret = 0;
int selector_ret = 0;
unsigned int i;
const char *name;
bool bypass;
@ -426,21 +427,21 @@ int regcache_sync(struct regmap *map)
/* Apply any patch first */
map->cache_bypass = true;
for (i = 0; i < map->patch_regs; i++) {
ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def);
if (ret != 0) {
sync_ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def);
if (sync_ret != 0) {
dev_err(map->dev, "Failed to write %x = %x: %d\n",
map->patch[i].reg, map->patch[i].def, ret);
map->patch[i].reg, map->patch[i].def, sync_ret);
goto out;
}
}
map->cache_bypass = false;
if (map->cache_ops->sync)
ret = map->cache_ops->sync(map, 0, map->max_register);
sync_ret = map->cache_ops->sync(map, 0, map->max_register);
else
ret = regcache_default_sync(map, 0, map->max_register);
sync_ret = regcache_default_sync(map, 0, map->max_register);
if (ret == 0)
if (sync_ret == 0)
map->cache_dirty = false;
out:
@ -462,10 +463,10 @@ int regcache_sync(struct regmap *map)
if (regcache_read(map, this->selector_reg, &i) != 0)
continue;
ret = _regmap_write(map, this->selector_reg, i);
if (ret != 0) {
selector_ret = _regmap_write(map, this->selector_reg, i);
if (selector_ret != 0) {
dev_err(map->dev, "Failed to write %x = %x: %d\n",
this->selector_reg, i, ret);
this->selector_reg, i, selector_ret);
break;
}
}
@ -476,7 +477,7 @@ int regcache_sync(struct regmap *map)
trace_regcache_sync(map, name, "stop");
return ret;
return sync_ret ? sync_ret : selector_ret;
}
EXPORT_SYMBOL_GPL(regcache_sync);