diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index 4494db6a05f5aa70c9bb0d32d09d8ee553034760..15480234b20b9f148a9135ccad8b3b970c33cf96 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -533,7 +533,6 @@ static int skl_link_pcm_prepare(struct snd_pcm_substream *substream, if (!link) return -EINVAL; - snd_hdac_ext_bus_link_power_up(link); snd_hdac_ext_link_stream_reset(link_dev); snd_hdac_ext_link_stream_setup(link_dev, format_val); diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 83e985c0c0c9fe7369db75f92e0c70786d42b3e3..06d8c263c68f93342931fbcfe447cd986408f2f3 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -229,7 +229,12 @@ static int skl_suspend(struct device *dev) * running, we need to save the state for these and continue */ if (skl->supend_active) { + /* turn off the links and stop the CORB/RIRB DMA if it is On */ snd_hdac_ext_bus_link_power_down_all(ebus); + + if (ebus->cmd_dma_state) + snd_hdac_bus_stop_cmd_io(&ebus->bus); + enable_irq_wake(bus->irq); pci_save_state(pci); pci_disable_device(pci); @@ -255,6 +260,7 @@ static int skl_resume(struct device *dev) struct hdac_ext_bus *ebus = pci_get_drvdata(pci); struct skl *skl = ebus_to_skl(ebus); struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_ext_link *hlink = NULL; int ret; /* Turned OFF in HDMI codec driver after codec reconfiguration */ @@ -276,8 +282,29 @@ static int skl_resume(struct device *dev) ret = pci_enable_device(pci); snd_hdac_ext_bus_link_power_up_all(ebus); disable_irq_wake(bus->irq); + /* + * turn On the links which are On before active suspend + * and start the CORB/RIRB DMA if On before + * active suspend. + */ + list_for_each_entry(hlink, &ebus->hlink_list, list) { + if (hlink->ref_count) + snd_hdac_ext_bus_link_power_up(hlink); + } + + if (ebus->cmd_dma_state) + snd_hdac_bus_init_cmd_io(&ebus->bus); } else { ret = _skl_resume(ebus); + + /* turn off the links which are off before suspend */ + list_for_each_entry(hlink, &ebus->hlink_list, list) { + if (!hlink->ref_count) + snd_hdac_ext_bus_link_power_down(hlink); + } + + if (!ebus->cmd_dma_state) + snd_hdac_bus_stop_cmd_io(&ebus->bus); } return ret; @@ -613,6 +640,7 @@ static int skl_probe(struct pci_dev *pci, struct skl *skl; struct hdac_ext_bus *ebus = NULL; struct hdac_bus *bus = NULL; + struct hdac_ext_link *hlink = NULL; int err; /* we use ext core ops, so provide NULL for ops here */ @@ -679,6 +707,12 @@ static int skl_probe(struct pci_dev *pci, } } + /* + * we are done probling so decrement link counts + */ + list_for_each_entry(hlink, &ebus->hlink_list, list) + snd_hdac_ext_bus_link_put(ebus, hlink); + /*configure PM */ pm_runtime_put_noidle(bus->dev); pm_runtime_allow(bus->dev);