Skip to content

Commit 6bbebcc

Browse files
committed
regmap: Merge up fix for window/paging issue
This was too late and could potentially impact too many drivers for me to be comfortable sending it before the merge window.
2 parents 6a2e332 + 0ec7731 commit 6bbebcc

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

drivers/base/regmap/regcache-rbtree.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,8 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
453453
if (!rbnode)
454454
return -ENOMEM;
455455
regcache_rbtree_set_register(map, rbnode,
456-
reg - rbnode->base_reg, value);
456+
(reg - rbnode->base_reg) / map->reg_stride,
457+
value);
457458
regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode);
458459
rbtree_ctx->cached_rbnode = rbnode;
459460
}

drivers/base/regmap/regcache.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,11 @@ static int regcache_default_sync(struct regmap *map, unsigned int min,
334334
return 0;
335335
}
336336

337+
static int rbtree_all(const void *key, const struct rb_node *node)
338+
{
339+
return 0;
340+
}
341+
337342
/**
338343
* regcache_sync - Sync the register cache with the hardware.
339344
*
@@ -351,6 +356,7 @@ int regcache_sync(struct regmap *map)
351356
unsigned int i;
352357
const char *name;
353358
bool bypass;
359+
struct rb_node *node;
354360

355361
if (WARN_ON(map->cache_type == REGCACHE_NONE))
356362
return -EINVAL;
@@ -392,6 +398,30 @@ int regcache_sync(struct regmap *map)
392398
/* Restore the bypass state */
393399
map->cache_bypass = bypass;
394400
map->no_sync_defaults = false;
401+
402+
/*
403+
* If we did any paging with cache bypassed and a cached
404+
* paging register then the register and cache state might
405+
* have gone out of sync, force writes of all the paging
406+
* registers.
407+
*/
408+
rb_for_each(node, 0, &map->range_tree, rbtree_all) {
409+
struct regmap_range_node *this =
410+
rb_entry(node, struct regmap_range_node, node);
411+
412+
/* If there's nothing in the cache there's nothing to sync */
413+
ret = regcache_read(map, this->selector_reg, &i);
414+
if (ret != 0)
415+
continue;
416+
417+
ret = _regmap_write(map, this->selector_reg, i);
418+
if (ret != 0) {
419+
dev_err(map->dev, "Failed to write %x = %x: %d\n",
420+
this->selector_reg, i, ret);
421+
break;
422+
}
423+
}
424+
395425
map->unlock(map->lock_arg);
396426

397427
regmap_async_complete(map);

drivers/base/regmap/regmap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1478,7 +1478,7 @@ static int dev_get_regmap_match(struct device *dev, void *res, void *data)
14781478

14791479
/* If the user didn't specify a name match any */
14801480
if (data)
1481-
return !strcmp((*r)->name, data);
1481+
return (*r)->name && !strcmp((*r)->name, data);
14821482
else
14831483
return 1;
14841484
}

0 commit comments

Comments
 (0)