diff options
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 36 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.h | 3 |
2 files changed, 25 insertions, 14 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index c71dcacea807..ec4e6b829ee2 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1227,6 +1227,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); @@ -1251,8 +1252,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 */ @@ -1263,9 +1268,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)); + } } } } @@ -1295,6 +1303,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); } } @@ -1320,9 +1329,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 @@ -1351,10 +1357,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) { @@ -2197,6 +2201,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 err; @@ -2278,8 +2283,17 @@ static int azx_probe_continue(struct azx *chip) chip->running = 1; azx_add_card_list(chip); + + /* + * 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, power_save * 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: diff --git a/sound/pci/hda/hda_intel.h b/sound/pci/hda/hda_intel.h index ff0c4d617bc1..e3a3d318d2e5 100644 --- a/sound/pci/hda/hda_intel.h +++ b/sound/pci/hda/hda_intel.h @@ -40,9 +40,6 @@ struct hda_intel { unsigned int vga_switcheroo_registered:1; unsigned int init_failed:1; /* delayed init failed */ - /* secondary power domain for hdmi audio under vga device */ - struct dev_pm_domain hdmi_pm_domain; - bool need_i915_power:1; /* the hda controller needs i915 power */ }; |