aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-02-26 14:30:38 +0100
committerTakashi Iwai <tiwai@suse.de>2015-03-04 10:30:29 +0100
commit238afa9890477b5ab7953ed707a9006c714cce25 (patch)
treed27221945b54eafa3d4bbe238e2820e901553228
parente4695d96d596fd279fa4aeeae5a9e85003b7124d (diff)
downloadsound-unstable-history/hda-regmap2.tar.gz
ALSA: hda - Reduce verbs during generic parser initializationhistory/hda-regmap2
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@suse.de>
-rw-r--r--include/sound/hdaudio.h1
-rw-r--r--sound/hda/hdac_regmap.c6
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/hda_generic.c4
4 files changed, 11 insertions, 1 deletions
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 8a1808394025e..db163a9ca79fa 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -78,6 +78,7 @@ struct hdac_device {
struct snd_array vendor_verbs;
bool lazy_cache:1; /* don't wake up for writes */
bool caps_overwriting:1; /* caps overwrite being in process */
+ bool cached_write:1; /* write only to caches */
};
/* device/driver type used for matching */
diff --git a/sound/hda/hdac_regmap.c b/sound/hda/hdac_regmap.c
index 6fe345050bfc5..0ceb3181edb19 100644
--- a/sound/hda/hdac_regmap.c
+++ b/sound/hda/hdac_regmap.c
@@ -113,6 +113,12 @@ static int hda_reg_write(void *context, unsigned int reg, unsigned int val)
unsigned int verb;
int i, bytes, err;
+ /* 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 codec->lazy_cache ? 0 : -EAGAIN;
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 2555083589b00..d270139897566 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -279,7 +279,6 @@ struct hda_codec {
unsigned int inv_eapd:1; /* broken h/w: inverted EAPD control */
unsigned int inv_jack_detect:1; /* broken h/w: inverted detection bit */
unsigned int pcm_format_first:1; /* PCM format must be set first */
- unsigned int cached_write:1; /* write only to caches */
unsigned int dp_mst:1; /* support DP1.2 Multi-stream transport */
unsigned int dump_coef:1; /* dump processing coefs in codec proc file */
#ifdef CONFIG_PM
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index d98633d86459a..532b0f31bb79f 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -5414,6 +5414,9 @@ int snd_hda_gen_init(struct hda_codec *codec)
snd_hda_apply_verbs(codec);
+ regcache_mark_dirty(codec->core.regmap);
+ codec->core.cached_write = 1;
+
init_multi_out(codec);
init_extra_out(codec);
init_multi_io(codec);
@@ -5427,6 +5430,7 @@ int snd_hda_gen_init(struct hda_codec *codec)
/* call init functions of standard auto-mute helpers */
update_automute_all(codec);
+ codec->core.cached_write = 0;
regcache_sync(codec->core.regmap);
if (spec->vmaster_mute.sw_kctl && spec->vmaster_mute.hook)