diff options
author | Takashi Iwai <tiwai@suse.de> | 2018-12-08 17:31:49 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2018-12-11 08:06:55 +0100 |
commit | 029d92c289bdad08ed08e61bf31b17cdc9ee61cf (patch) | |
tree | aaccdd1b5f6aefc45c9406def67b6d142deeba0b /sound/pci/hda/hda_codec.c | |
parent | 3baffc4a84d759ba54c461e8e4583bd8890c749a (diff) |
ALSA: hda: Refactor display power management
The current HD-audio code manages the DRM audio power via too complex
redirections, and this seems even still unbalanced in a corner case as
Intel DRM CI has been intermittently reporting. This patch is a big
surgery for addressing the complexity and the possible unbalance.
Basically the patch changes the display PM in the following ways:
- Both HD-audio controller and codec drivers call a single helper,
snd_hdac_display_power(). (Formerly, the display power control from
a codec was done indirectly via link_power bus ops.)
- snd_hdac_display_power() receives the codec address index. For
turning on/off from the controller, pass HDA_CODEC_IDX_CONTROLLER.
- snd_hdac_display_power() doesn't manage refcounts any longer, but
keeps the power status in bitmap. If any of controller or codecs is
turned on, the function updates the DRM power state via get_power()
or put_power().
Also this refactor allows us more cleanup:
- The link_power bus ops is dropped, so there is no longer indirect
management, as mentioned in the above.
- hdac_device link_power_control flag is moved to hda_codec
display_power_control flag, as it's only for HDA legacy.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=106525
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 0957813939e5..9f8d59e7e89f 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -36,6 +36,7 @@ #include "hda_beep.h" #include "hda_jack.h" #include <sound/hda_hwdep.h> +#include <sound/hda_component.h> #define codec_in_pm(codec) snd_hdac_is_in_pm(&codec->core) #define hda_codec_is_power_on(codec) snd_hdac_is_power_on(&codec->core) @@ -799,6 +800,13 @@ void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec) static unsigned int hda_set_power_state(struct hda_codec *codec, unsigned int power_state); +/* enable/disable display power per codec */ +static void codec_display_power(struct hda_codec *codec, bool enable) +{ + if (codec->display_power_control) + snd_hdac_display_power(&codec->bus->core, codec->addr, enable); +} + /* also called from hda_bind.c */ void snd_hda_codec_register(struct hda_codec *codec) { @@ -806,7 +814,7 @@ void snd_hda_codec_register(struct hda_codec *codec) return; if (device_is_registered(hda_codec_dev(codec))) { snd_hda_register_beep_device(codec); - snd_hdac_link_power(&codec->core, true); + codec_display_power(codec, true); pm_runtime_enable(hda_codec_dev(codec)); /* it was powered up in snd_hda_codec_new(), now all done */ snd_hda_power_down(codec); @@ -834,7 +842,7 @@ static int snd_hda_codec_dev_free(struct snd_device *device) codec->in_freeing = 1; snd_hdac_device_unregister(&codec->core); - snd_hdac_link_power(&codec->core, false); + codec_display_power(codec, false); put_device(hda_codec_dev(codec)); return 0; } @@ -2926,7 +2934,7 @@ static int hda_codec_runtime_suspend(struct device *dev) (codec_has_clkstop(codec) && codec_has_epss(codec) && (state & AC_PWRST_CLK_STOP_OK))) snd_hdac_codec_link_down(&codec->core); - snd_hdac_link_power(&codec->core, false); + codec_display_power(codec, false); return 0; } @@ -2934,7 +2942,7 @@ static int hda_codec_runtime_resume(struct device *dev) { struct hda_codec *codec = dev_to_hda_codec(dev); - snd_hdac_link_power(&codec->core, true); + codec_display_power(codec, true); snd_hdac_codec_link_up(&codec->core); hda_call_codec_resume(codec); pm_runtime_mark_last_busy(dev); |