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 --- 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 */