From 029d92c289bdad08ed08e61bf31b17cdc9ee61cf Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 8 Dec 2018 17:31:49 +0100 Subject: 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 --- sound/soc/codecs/hdac_hdmi.c | 7 +++---- sound/soc/intel/skylake/skl.c | 10 +++++----- 2 files changed, 8 insertions(+), 9 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index e63d6e33df48..c3d551d2af7f 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -2031,14 +2031,13 @@ static int hdac_hdmi_dev_probe(struct hdac_device *hdev) * Turned off in the runtime_suspend during the first explicit * pm_runtime_suspend call. */ - ret = snd_hdac_display_power(hdev->bus, true); + ret = snd_hdac_display_power(hdev->bus, hdev->addr, true); if (ret < 0) { dev_err(&hdev->dev, "Cannot turn on display power on i915 err: %d\n", ret); return ret; } - ret = hdac_hdmi_parse_and_map_nid(hdev, &hdmi_dais, &num_dais); if (ret < 0) { dev_err(&hdev->dev, @@ -2196,7 +2195,7 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) snd_hdac_ext_bus_link_put(bus, hlink); - err = snd_hdac_display_power(bus, false); + err = snd_hdac_display_power(bus, hdev->addr, false); if (err < 0) dev_err(dev, "Cannot turn off display power on i915\n"); @@ -2224,7 +2223,7 @@ static int hdac_hdmi_runtime_resume(struct device *dev) snd_hdac_ext_bus_link_get(bus, hlink); - err = snd_hdac_display_power(bus, true); + err = snd_hdac_display_power(bus, hdev->addr, true); if (err < 0) { dev_err(dev, "Cannot turn on display power on i915\n"); return err; diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 7487f388e65d..64f8433ae921 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -334,7 +334,7 @@ static int skl_suspend(struct device *dev) } if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { - ret = snd_hdac_display_power(bus, false); + ret = snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false); if (ret < 0) dev_err(bus->dev, "Cannot turn OFF display power on i915\n"); @@ -353,7 +353,7 @@ static int skl_resume(struct device *dev) /* Turned OFF in HDMI codec driver after codec reconfiguration */ if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { - ret = snd_hdac_display_power(bus, true); + ret = snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, true); if (ret < 0) { dev_err(bus->dev, "Cannot turn on display power on i915\n"); @@ -783,7 +783,7 @@ static int skl_i915_init(struct hdac_bus *bus) if (err < 0) return err; - err = snd_hdac_display_power(bus, true); + err = snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, true); if (err < 0) dev_err(bus->dev, "Cannot turn on display power on i915\n"); @@ -838,7 +838,7 @@ static void skl_probe_work(struct work_struct *work) snd_hdac_ext_bus_link_put(bus, hlink); if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { - err = snd_hdac_display_power(bus, false); + err = snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false); if (err < 0) { dev_err(bus->dev, "Cannot turn off display power on i915\n"); skl_machine_device_unregister(skl); @@ -855,7 +855,7 @@ static void skl_probe_work(struct work_struct *work) out_err: if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) - err = snd_hdac_display_power(bus, false); + err = snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false); } /* -- cgit