[alsa-devel] [PATCH 7/7] ALSA: hda - Reduce verbs during generic parser initialization

Takashi Iwai tiwai at suse.de
Fri Feb 27 22:28:22 CET 2015


For reducing the number of verbs performed during the initialization
and the resume of the generic parser, this patch (re-)introduces the
mechanism to cache everything in init and sync later.

However, it became a bit tricky in the end: we can't use regcache's
cache_only flag straightforwardly here because we do want the actual
hardware access for reads if needed, but forbids only the writes.
So, instead, the regmap reg_write callback checks the own flag
(reusing the existing codec->cached_write) and skips the actual
access.  This works by assumption of regmap dumping the whole
registers via regcache_sync() at a later point.

Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
 sound/pci/hda/hda_generic.c | 4 ++++
 sound/pci/hda/hda_regmap.c  | 6 ++++++
 2 files changed, 10 insertions(+)

diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 33de31c83d6e..bcaed93f8795 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -5411,6 +5411,8 @@ int snd_hda_gen_init(struct hda_codec *codec)
 
 	snd_hda_apply_verbs(codec);
 
+	codec->cached_write = 1;
+
 	init_multi_out(codec);
 	init_extra_out(codec);
 	init_multi_io(codec);
@@ -5424,6 +5426,8 @@ int snd_hda_gen_init(struct hda_codec *codec)
 	/* call init functions of standard auto-mute helpers */
 	update_automute_all(codec);
 
+	codec->cached_write = 0;
+
 	regcache_sync(codec->regmap);
 
 	if (spec->vmaster_mute.sw_kctl && spec->vmaster_mute.hook)
diff --git a/sound/pci/hda/hda_regmap.c b/sound/pci/hda/hda_regmap.c
index 38934c06a813..79da06da286d 100644
--- a/sound/pci/hda/hda_regmap.c
+++ b/sound/pci/hda/hda_regmap.c
@@ -116,6 +116,12 @@ static int hda_reg_write(void *context, unsigned int reg, unsigned int val)
 	unsigned int verb;
 	int i, bytes;
 
+	/* skip h/w write when cached_write flag is set, assuming that
+	 * regcache_sync() will dump the all registers at a later point
+	 */
+	if (codec->cached_write)
+		return 0;
+
 	if (!codec_is_running(codec))
 		return 0; /* skip the h/w write, it'll be synced later */
 
-- 
2.3.0



More information about the Alsa-devel mailing list