summaryrefslogtreecommitdiff
path: root/drivers/base
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-02-23 20:53:37 +0000
committerSimone Willett <swillett@nvidia.com>2012-04-15 13:50:26 -0700
commitfe5d7a370e86d9a3ba10e94f834bd3d2619d0f73 (patch)
treecdaae96ffa1ab537b0cfec61aa44c9c287e51b4a /drivers/base
parent9d586b202c93d646167b235864e0cd21b2b2c87c (diff)
regmap: Allow drivers to sync only part of the register cache
Provide a regcache_sync_region() operation which allows drivers to write only part of the cache back to the hardware. This is intended for use in cases like power domains or DSP memories where part of the device register map may be reset without fully resetting the device. Fully supporting these devices is likely to require additional work to make specific regions of the register map cache only while they are in reset, but this is enough for most devices. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> (cherry picked from commit 4d4cfd1656b5f6c88eae51c40741a695b108b006) Change-Id: Ia8cccf7986611485ae090e234bb68084671d7641 Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Reviewed-on: http://git-master/r/96490 Reviewed-by: Simone Willett <swillett@nvidia.com> Tested-by: Simone Willett <swillett@nvidia.com>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/regmap/regcache.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index 53c596ecb5f2..76c65b898814 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -301,6 +301,51 @@ out:
EXPORT_SYMBOL_GPL(regcache_sync);
/**
+ * regcache_sync_region: Sync part of the register cache with the hardware.
+ *
+ * @map: map to sync.
+ * @min: first register to sync
+ * @max: last register to sync
+ *
+ * Write all non-default register values in the specified region to
+ * the hardware.
+ *
+ * Return a negative value on failure, 0 on success.
+ */
+int regcache_sync_region(struct regmap *map, unsigned int min,
+ unsigned int max)
+{
+ int ret = 0;
+ const char *name;
+ unsigned int bypass;
+
+ BUG_ON(!map->cache_ops || !map->cache_ops->sync);
+
+ mutex_lock(&map->lock);
+
+ /* Remember the initial bypass state */
+ bypass = map->cache_bypass;
+
+ name = map->cache_ops->name;
+ dev_dbg(map->dev, "Syncing %s cache from %d-%d\n", name, min, max);
+
+ trace_regcache_sync(map->dev, name, "start region");
+
+ if (!map->cache_dirty)
+ goto out;
+
+ ret = map->cache_ops->sync(map, min, max);
+
+out:
+ trace_regcache_sync(map->dev, name, "stop region");
+ /* Restore the bypass state */
+ map->cache_bypass = bypass;
+ mutex_unlock(&map->lock);
+
+ return ret;
+}
+
+/**
* regcache_cache_only: Put a register map into cache only mode
*
* @map: map to configure