static int regcache_default_sync(struct regmap *map, unsigned int min, unsigned int max) { unsigned int reg; for (reg = min; reg <= max; reg += map->reg_stride) { unsigned int val; int ret; if (regmap_volatile(map, reg) || !regmap_writeable(map, reg)) continue; ret = regcache_read(map, reg, &val); if (ret) return ret; if (!regcache_reg_needs_sync(map, reg, val)) continue; map->cache_bypass = true; ret = _regmap_write(map, reg, val); map->cache_bypass = false; if (ret) { dev_err(map->dev, "Unable to sync register %#x. %d\n", reg, ret); return ret; } dev_dbg(map->dev, "Synced register %#x, value %#x\n", reg, val); } return 0; }
static int regcache_default_sync(struct regmap *map, unsigned int min, unsigned int max) { unsigned int reg; for (reg = min; reg <= max; reg += map->reg_stride) { unsigned int val; int ret; if (regmap_volatile(map, reg) || !regmap_writeable(map, reg)) continue; ret = regcache_read(map, reg, &val); if (ret) return ret; /* Is this the hardware default? If so skip. */ ret = regcache_lookup_reg(map, reg); if (ret >= 0 && val == map->reg_defaults[ret].def) continue; map->cache_bypass = 1; ret = _regmap_write(map, reg, val); map->cache_bypass = 0; if (ret) return ret; dev_dbg(map->dev, "Synced register %#x, value %#x\n", reg, val); } return 0; }
static int regcache_default_sync(struct regmap *map, unsigned int min, unsigned int max) { unsigned int reg; for (reg = min; reg <= max; reg++) { unsigned int val; int ret; if (regmap_volatile(map, reg)) continue; ret = regcache_read(map, reg, &val); if (ret) return ret; if (!regcache_reg_needs_sync(map, reg, val)) continue; map->cache_bypass = 1; ret = _regmap_write(map, reg, val); map->cache_bypass = 0; if (ret) return ret; dev_dbg(map->dev, "Synced register %#x, value %#x\n", reg, val); } return 0; }
static int _regmap_read(struct regmap *map, unsigned int reg, unsigned int *val) { int ret; if (!map->format.parse_val) return -EINVAL; if (!map->cache_bypass) { ret = regcache_read(map, reg, val); if (ret == 0) return 0; } if (map->cache_only) return -EBUSY; ret = _regmap_raw_read(map, reg, map->work_buf, map->format.val_bytes); if (ret == 0) { *val = map->format.parse_val(map->work_buf); trace_regmap_reg_read(map->dev, reg, *val); } return ret; }
/** * regcache_sync: Sync the register cache with the hardware. * * @map: map to configure. * * Any registers that should not be synced should be marked as * volatile. In general drivers can choose not to use the provided * syncing functionality if they so require. * * Return a negative value on failure, 0 on success. */ int regcache_sync(struct regmap *map) { int ret = 0; unsigned int val; unsigned int i; const char *name; unsigned int bypass; BUG_ON(!map->cache_ops); mutex_lock(&map->lock); /* Remember the initial bypass state */ bypass = map->cache_bypass; dev_dbg(map->dev, "Syncing %s cache\n", map->cache_ops->name); name = map->cache_ops->name; trace_regcache_sync(map->dev, name, "start"); if (map->cache_ops->sync) { ret = map->cache_ops->sync(map); } else { for (i = 0; i < map->num_reg_defaults; i++) { ret = regcache_read(map, i, &val); if (ret < 0) goto out; map->cache_bypass = 1; ret = _regmap_write(map, i, val); map->cache_bypass = 0; if (ret < 0) goto out; dev_dbg(map->dev, "Synced register %#x, value %#x\n", map->reg_defaults[i].reg, map->reg_defaults[i].def); } } out: trace_regcache_sync(map->dev, name, "stop"); /* Restore the bypass state */ map->cache_bypass = bypass; mutex_unlock(&map->lock); return ret; }