diff options
Diffstat (limited to 'drivers/base/regmap/regmap.c')
-rw-r--r-- | drivers/base/regmap/regmap.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 31cfe70e6d53..ae63bb0875ea 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -93,6 +93,29 @@ bool regmap_writeable(struct regmap *map, unsigned int reg) return true; } +bool regmap_cached(struct regmap *map, unsigned int reg) +{ + int ret; + unsigned int val; + + if (map->cache == REGCACHE_NONE) + return false; + + if (!map->cache_ops) + return false; + + if (map->max_register && reg > map->max_register) + return false; + + map->lock(map->lock_arg); + ret = regcache_read(map, reg, &val); + map->unlock(map->lock_arg); + if (ret) + return false; + + return true; +} + bool regmap_readable(struct regmap *map, unsigned int reg) { if (!map->reg_read) @@ -1497,6 +1520,12 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg, ret = map->bus->write(map->bus_context, buf, len); kfree(buf); + } else if (ret != 0 && !map->cache_bypass && map->format.parse_val) { + /* regcache_drop_region() takes lock that we already have, + * thus call map->cache_ops->drop() directly + */ + if (map->cache_ops && map->cache_ops->drop) + map->cache_ops->drop(map, reg, reg + 1); } trace_regmap_hw_write_done(map, reg, val_len / map->format.val_bytes); |