Merge tag 'nfs-for-4.7-1' of git://git.linux-nfs.org/projects/anna/linux-nfs
[deliverable/linux.git] / sound / soc / intel / skylake / skl.c
index 3982f5536f2d82b55837c4358e0b2754ac95e2c4..06d8c263c68f93342931fbcfe447cd986408f2f3 100644 (file)
@@ -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 */
@@ -643,7 +671,7 @@ static int skl_probe(struct pci_dev *pci,
                err = skl_machine_device_register(skl,
                                  (void *)pci_id->driver_data);
                if (err < 0)
-                       goto out_free;
+                       goto out_nhlt_free;
 
                err = skl_init_dsp(skl);
                if (err < 0) {
@@ -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);
@@ -693,6 +727,8 @@ out_dsp_free:
        skl_free_dsp(skl);
 out_mach_free:
        skl_machine_device_unregister(skl);
+out_nhlt_free:
+       skl_nhlt_free(skl->nhlt);
 out_free:
        skl->init_failed = 1;
        skl_free(ebus);
@@ -743,6 +779,7 @@ static void skl_remove(struct pci_dev *pci)
        skl_free_dsp(skl);
        skl_machine_device_unregister(skl);
        skl_dmic_device_unregister(skl);
+       skl_nhlt_free(skl->nhlt);
        skl_free(ebus);
        dev_set_drvdata(&pci->dev, NULL);
 }
This page took 0.034193 seconds and 5 git commands to generate.