diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c index bd4b113401a8..48eb95973b7a 100644 --- a/sound/soc/codecs/hdac_hda.c +++ b/sound/soc/codecs/hdac_hda.c @@ -514,6 +514,9 @@ static int hdac_hda_codec_probe(struct snd_soc_component *component) snd_hdac_display_power(hdev->bus, HDA_CODEC_IDX_CONTROLLER, false); + /* The codec is in D0, the status is RPM_SUSPENDED after a previous unbind */ + pm_runtime_set_active(&hdev->dev); + /* match for forbid call in snd_hda_codec_device_new() */ pm_runtime_allow(&hdev->dev); @@ -554,6 +557,12 @@ static void hdac_hda_codec_remove(struct snd_soc_component *component) return; } + /* + * Resume the codec to have its link reference (dropped below) and + * codec_powered bit in the same state as after the probe. + */ + pm_runtime_get_sync(&hdev->dev); + /* prevent runtime PM callbacks while the link and the codec are torn down */ pm_runtime_disable(&hdev->dev); snd_hdac_ext_bus_link_put(hdev->bus, hlink); @@ -565,6 +574,9 @@ static void hdac_hda_codec_remove(struct snd_soc_component *component) /* Balances the disable above, cleanup_for_unbind keeps runtime PM disabled */ pm_runtime_enable(&hdev->dev); + pm_runtime_put_noidle(&hdev->dev); + /* The codec is cleaned up, system suspend must skip it from now on */ + pm_runtime_set_suspended(&hdev->dev); } static const struct snd_soc_dapm_route hdac_hda_dapm_routes[] = {