Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

regmap: Implemented default cache sync operation

This can be used for cache types for which syncing values one by one is
equally efficient as syncing a range, such as the flat cache.

Signed-off-by: Maarten ter Huurne <maarten@treewalker.org>
Signed-off-by: Mark Brown <broonie@linaro.org>

authored by

Maarten ter Huurne and committed by
Mark Brown
d856fce4 92ab1aab

+42 -4
+42 -4
drivers/base/regmap/regcache.c
··· 250 250 return 0; 251 251 } 252 252 253 + static int regcache_default_sync(struct regmap *map, unsigned int min, 254 + unsigned int max) 255 + { 256 + unsigned int reg; 257 + 258 + for (reg = min; reg <= max; reg++) { 259 + unsigned int val; 260 + int ret; 261 + 262 + if (regmap_volatile(map, reg)) 263 + continue; 264 + 265 + ret = regcache_read(map, reg, &val); 266 + if (ret) 267 + return ret; 268 + 269 + /* Is this the hardware default? If so skip. */ 270 + ret = regcache_lookup_reg(map, reg); 271 + if (ret >= 0 && val == map->reg_defaults[ret].def) 272 + continue; 273 + 274 + map->cache_bypass = 1; 275 + ret = _regmap_write(map, reg, val); 276 + map->cache_bypass = 0; 277 + if (ret) 278 + return ret; 279 + dev_dbg(map->dev, "Synced register %#x, value %#x\n", reg, val); 280 + } 281 + 282 + return 0; 283 + } 284 + 253 285 /** 254 286 * regcache_sync: Sync the register cache with the hardware. 255 287 * ··· 300 268 const char *name; 301 269 unsigned int bypass; 302 270 303 - BUG_ON(!map->cache_ops || !map->cache_ops->sync); 271 + BUG_ON(!map->cache_ops); 304 272 305 273 map->lock(map->lock_arg); 306 274 /* Remember the initial bypass state */ ··· 329 297 } 330 298 map->cache_bypass = 0; 331 299 332 - ret = map->cache_ops->sync(map, 0, map->max_register); 300 + if (map->cache_ops->sync) 301 + ret = map->cache_ops->sync(map, 0, map->max_register); 302 + else 303 + ret = regcache_default_sync(map, 0, map->max_register); 333 304 334 305 if (ret == 0) 335 306 map->cache_dirty = false; ··· 366 331 const char *name; 367 332 unsigned int bypass; 368 333 369 - BUG_ON(!map->cache_ops || !map->cache_ops->sync); 334 + BUG_ON(!map->cache_ops); 370 335 371 336 map->lock(map->lock_arg); 372 337 ··· 381 346 if (!map->cache_dirty) 382 347 goto out; 383 348 384 - ret = map->cache_ops->sync(map, min, max); 349 + if (map->cache_ops->sync) 350 + ret = map->cache_ops->sync(map, min, max); 351 + else 352 + ret = regcache_default_sync(map, min, max); 385 353 386 354 out: 387 355 trace_regcache_sync(map->dev, name, "stop region");