linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kevin Cernekee <cernekee@chromium.org>
To: lgirdwood@gmail.com, broonie@kernel.org
Cc: lars@metafoo.de, dgreid@chromium.org, abrestic@chromium.org,
	olofj@chromium.org, alsa-devel@alsa-project.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH V4 2/5] regmap: Use regcache_mark_dirty() to indicate power loss or reset
Date: Tue,  5 May 2015 15:14:14 -0700	[thread overview]
Message-ID: <1430864057-3848-3-git-send-email-cernekee@chromium.org> (raw)
In-Reply-To: <1430864057-3848-1-git-send-email-cernekee@chromium.org>

Existing regmap users call regcache_mark_dirty() as part of the
suspend/resume sequence, to tell regcache that non-default values need to
be resynced post-resume.  Add an internal "no_sync_defaults" regmap flag
to remember this state, so that regcache_sync() can differentiate between
these two cases:

1) HW was reset, so any cache values that match map->reg_defaults can be
safely skipped.  On some chips there are a lot of registers in the
reg_defaults list, so this optimization speeds things up quite a bit.

2) HW was not reset (maybe it was just clock-gated), so if we cached
any writes, they should be sent to the hardware regardless of whether
they match the HW default.  Currently this will write out all values in
the regcache, since we don't maintain per-register dirty bits.

Suggested-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Kevin Cernekee <cernekee@chromium.org>
---
 drivers/base/regmap/internal.h |  3 +++
 drivers/base/regmap/regcache.c | 19 +++++++++++++++----
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index a13587b5c2be..b2b2849fc6d3 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -131,7 +131,10 @@ struct regmap {
 	struct reg_default *reg_defaults;
 	const void *reg_defaults_raw;
 	void *cache;
+	/* if set, the cache contains newer data than the HW */
 	u32 cache_dirty;
+	/* if set, the HW registers are known to match map->reg_defaults */
+	bool no_sync_defaults;
 
 	struct reg_default *patch;
 	int patch_regs;
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index c58493eaf050..b9862d741a56 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -254,6 +254,10 @@ static bool regcache_reg_needs_sync(struct regmap *map, unsigned int reg,
 {
 	int ret;
 
+	/* If we don't know the chip just got reset, then sync everything. */
+	if (!map->no_sync_defaults)
+		return true;
+
 	/* Is this the hardware default?  If so skip. */
 	ret = regcache_lookup_reg(map, reg);
 	if (ret >= 0 && val == map->reg_defaults[ret].def)
@@ -352,6 +356,7 @@ out:
 	/* Restore the bypass state */
 	map->async = false;
 	map->cache_bypass = bypass;
+	map->no_sync_defaults = false;
 	map->unlock(map->lock_arg);
 
 	regmap_async_complete(map);
@@ -407,6 +412,7 @@ out:
 	/* Restore the bypass state */
 	map->cache_bypass = bypass;
 	map->async = false;
+	map->no_sync_defaults = false;
 	map->unlock(map->lock_arg);
 
 	regmap_async_complete(map);
@@ -471,18 +477,23 @@ void regcache_cache_only(struct regmap *map, bool enable)
 EXPORT_SYMBOL_GPL(regcache_cache_only);
 
 /**
- * regcache_mark_dirty: Mark the register cache as dirty
+ * regcache_mark_dirty: Indicate that HW registers were reset to default values
  *
  * @map: map to mark
  *
- * Mark the register cache as dirty, for example due to the device
- * having been powered down for suspend.  If the cache is not marked
- * as dirty then the cache sync will be suppressed.
+ * Inform regcache that the device has been powered down or reset, so that
+ * on resume, regcache_sync() knows to write out all non-default values
+ * stored in the cache.
+ *
+ * If this function is not called, regcache_sync() will assume that
+ * the hardware state still matches the cache state, modulo any writes that
+ * happened when cache_only was true.
  */
 void regcache_mark_dirty(struct regmap *map)
 {
 	map->lock(map->lock_arg);
 	map->cache_dirty = true;
+	map->no_sync_defaults = true;
 	map->unlock(map->lock_arg);
 }
 EXPORT_SYMBOL_GPL(regcache_mark_dirty);
-- 
2.2.0.rc0.207.ga3a616c


  parent reply	other threads:[~2015-05-05 22:23 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-05 22:14 [PATCH V4 0/5] tas571x amplifier driver Kevin Cernekee
2015-05-05 22:14 ` [PATCH V4 1/5] regmap: Add a helper function for regcache sync test Kevin Cernekee
2015-05-06 12:01   ` Mark Brown
2015-05-05 22:14 ` Kevin Cernekee [this message]
2015-05-06 12:01   ` [PATCH V4 2/5] regmap: Use regcache_mark_dirty() to indicate power loss or reset Mark Brown
2015-05-05 22:14 ` [PATCH V4 3/5] ASoC: tas571x: Add DT binding document Kevin Cernekee
2015-05-05 22:32   ` Mark Brown
2015-05-05 22:56     ` Kevin Cernekee
2015-05-05 23:01       ` Mark Brown
2015-05-05 22:14 ` [PATCH V4 4/5] ASoC: tas571x: New driver for TI TAS571x power amplifiers Kevin Cernekee
2015-05-05 22:14 ` [PATCH V4 5/5] MAINTAINERS: Add entry for tas571x ASoC codec driver Kevin Cernekee

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1430864057-3848-3-git-send-email-cernekee@chromium.org \
    --to=cernekee@chromium.org \
    --cc=abrestic@chromium.org \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dgreid@chromium.org \
    --cc=lars@metafoo.de \
    --cc=lgirdwood@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=olofj@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).