diff options
author | Takashi Iwai <tiwai@suse.de> | 2015-02-26 14:30:38 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-03-04 10:30:29 +0100 |
commit | 238afa9890477b5ab7953ed707a9006c714cce25 (patch) | |
tree | d27221945b54eafa3d4bbe238e2820e901553228 | |
parent | e4695d96d596fd279fa4aeeae5a9e85003b7124d (diff) | |
download | sound-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.h | 1 | ||||
-rw-r--r-- | sound/hda/hdac_regmap.c | 6 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 1 | ||||
-rw-r--r-- | sound/pci/hda/hda_generic.c | 4 |
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) |