]> git.ipfire.org Git - thirdparty/kernel/linux.git/blobdiff - sound/pci/hda/hda_intel.c
Merge tag 'sound-4.17-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[thirdparty/kernel/linux.git] / sound / pci / hda / hda_intel.c
index fece779f62603efc151b56559044941227cbfac4..b0c8c79848a94fd9aae962207ed1c673e0d815ed 100644 (file)
@@ -987,7 +987,7 @@ static int param_set_xint(const char *val, const struct kernel_param *kp)
 #define azx_del_card_list(chip) /* NOP */
 #endif /* CONFIG_PM */
 
-#if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO)
+#ifdef CONFIG_PM_SLEEP
 /*
  * power management
  */
@@ -1068,9 +1068,7 @@ static int azx_resume(struct device *dev)
        trace_azx_resume(chip);
        return 0;
 }
-#endif /* CONFIG_PM_SLEEP || SUPPORT_VGA_SWITCHEROO */
 
-#ifdef CONFIG_PM_SLEEP
 /* put codec down to D3 at hibernation for Intel SKL+;
  * otherwise BIOS may still access the codec and screw up the driver
  */
@@ -1232,6 +1230,7 @@ static void azx_vs_set_state(struct pci_dev *pci,
        struct snd_card *card = pci_get_drvdata(pci);
        struct azx *chip = card->private_data;
        struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
+       struct hda_codec *codec;
        bool disabled;
 
        wait_for_completion(&hda->probe_wait);
@@ -1256,8 +1255,12 @@ static void azx_vs_set_state(struct pci_dev *pci,
                dev_info(chip->card->dev, "%s via vga_switcheroo\n",
                         disabled ? "Disabling" : "Enabling");
                if (disabled) {
-                       pm_runtime_put_sync_suspend(card->dev);
-                       azx_suspend(card->dev);
+                       list_for_each_codec(codec, &chip->bus) {
+                               pm_runtime_suspend(hda_codec_dev(codec));
+                               pm_runtime_disable(hda_codec_dev(codec));
+                       }
+                       pm_runtime_suspend(card->dev);
+                       pm_runtime_disable(card->dev);
                        /* when we get suspended by vga_switcheroo we end up in D3cold,
                         * however we have no ACPI handle, so pci/acpi can't put us there,
                         * put ourselves there */
@@ -1268,9 +1271,12 @@ static void azx_vs_set_state(struct pci_dev *pci,
                                         "Cannot lock devices!\n");
                } else {
                        snd_hda_unlock_devices(&chip->bus);
-                       pm_runtime_get_noresume(card->dev);
                        chip->disabled = false;
-                       azx_resume(card->dev);
+                       pm_runtime_enable(card->dev);
+                       list_for_each_codec(codec, &chip->bus) {
+                               pm_runtime_enable(hda_codec_dev(codec));
+                               pm_runtime_resume(hda_codec_dev(codec));
+                       }
                }
        }
 }
@@ -1300,6 +1306,7 @@ static void init_vga_switcheroo(struct azx *chip)
                dev_info(chip->card->dev,
                         "Handle vga_switcheroo audio client\n");
                hda->use_vga_switcheroo = 1;
+               chip->driver_caps |= AZX_DCAPS_PM_RUNTIME;
                pci_dev_put(p);
        }
 }
@@ -1325,9 +1332,6 @@ static int register_vga_switcheroo(struct azx *chip)
                return err;
        hda->vga_switcheroo_registered = 1;
 
-       /* register as an optimus hdmi audio power domain */
-       vga_switcheroo_init_domain_pm_optimus_hdmi_audio(chip->card->dev,
-                                                        &hda->hdmi_pm_domain);
        return 0;
 }
 #else
@@ -1356,10 +1360,8 @@ static int azx_free(struct azx *chip)
        if (use_vga_switcheroo(hda)) {
                if (chip->disabled && hda->probe_continued)
                        snd_hda_unlock_devices(&chip->bus);
-               if (hda->vga_switcheroo_registered) {
+               if (hda->vga_switcheroo_registered)
                        vga_switcheroo_unregister_client(chip->pci);
-                       vga_switcheroo_fini_domain_pm_ops(chip->card->dev);
-               }
        }
 
        if (bus->chip_init) {
@@ -2225,6 +2227,7 @@ static int azx_probe_continue(struct azx *chip)
        struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
        struct hdac_bus *bus = azx_bus(chip);
        struct pci_dev *pci = chip->pci;
+       struct hda_codec *codec;
        int dev = chip->dev_index;
        int val;
        int err;
@@ -2321,8 +2324,16 @@ static int azx_probe_continue(struct azx *chip)
                }
        }
 #endif /* CONFIG_PM */
+       /*
+        * The discrete GPU cannot power down unless the HDA controller runtime
+        * suspends, so activate runtime PM on codecs even if power_save == 0.
+        */
+       if (use_vga_switcheroo(hda))
+               list_for_each_codec(codec, &chip->bus)
+                       codec->auto_runtime_pm = 1;
+
        snd_hda_set_power_save(&chip->bus, val * 1000);
-       if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo)
+       if (azx_has_pm_runtime(chip))
                pm_runtime_put_autosuspend(&pci->dev);
 
 out_free: