Merge branch 'topic/hda' into for-next
[cascardo/linux.git] / sound / pci / hda / hda_intel.c
index c212f13..5aa5cfa 100644 (file)
@@ -543,6 +543,14 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
        return 0;
 }
 
+/* Enable/disable i915 display power for the link */
+static int azx_intel_link_power(struct azx *chip, bool enable)
+{
+       struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
+
+       return hda_display_power(hda, enable);
+}
+
 /*
  * Check whether the current DMA position is acceptable for updating
  * periods.  Returns non-zero if it's OK.
@@ -809,7 +817,8 @@ static int azx_suspend(struct device *dev)
 
        if (chip->msi)
                pci_disable_msi(chip->pci);
-       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
+       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL
+               && hda->need_i915_power)
                hda_display_power(hda, false);
        return 0;
 }
@@ -829,7 +838,8 @@ static int azx_resume(struct device *dev)
        if (chip->disabled || hda->init_failed)
                return 0;
 
-       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
+       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL
+               && hda->need_i915_power) {
                hda_display_power(hda, true);
                haswell_set_bclk(hda);
        }
@@ -872,7 +882,8 @@ static int azx_runtime_suspend(struct device *dev)
        azx_stop_chip(chip);
        azx_enter_link_reset(chip);
        azx_clear_irq_pending(chip);
-       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
+       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL
+               && hda->need_i915_power)
                hda_display_power(hda, false);
 
        return 0;
@@ -897,7 +908,8 @@ static int azx_runtime_resume(struct device *dev)
        if (!azx_has_pm_runtime(chip))
                return 0;
 
-       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
+       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL
+               && hda->need_i915_power) {
                hda_display_power(hda, true);
                haswell_set_bclk(hda);
        }
@@ -1118,7 +1130,8 @@ static int azx_free(struct azx *chip)
        release_firmware(chip->fw);
 #endif
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
-               hda_display_power(hda, false);
+               if (hda->need_i915_power)
+                       hda_display_power(hda, false);
                hda_i915_exit(hda);
        }
        kfree(hda);
@@ -1789,6 +1802,7 @@ static const struct hda_controller_ops pci_hda_ops = {
        .substream_free_pages = substream_free_pages,
        .pcm_mmap_prepare = pcm_mmap_prepare,
        .position_check = azx_position_check,
+       .link_power = azx_intel_link_power,
 };
 
 static int azx_probe(struct pci_dev *pci,
@@ -1882,17 +1896,28 @@ static int azx_probe_continue(struct azx *chip)
        int err;
 
        hda->probe_continued = 1;
-       /* Request power well for Haswell HDA controller and codec */
+
+       /* Request display power well for the HDA controller or codec. For
+        * Haswell/Broadwell, both the display HDA controller and codec need
+        * this power. For other platforms, like Baytrail/Braswell, only the
+        * display codec needs the power and it can be released after probe.
+        */
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
+               /* Baytral/Braswell controllers don't need this power */
+               if (pci->device != 0x0f04 && pci->device != 0x2284)
+                       hda->need_i915_power = 1;
+
+
 #ifdef CONFIG_SND_HDA_I915
                err = hda_i915_init(hda);
                if (err < 0)
-                       goto out_free;
+                       goto i915_power_fail;
+
                err = hda_display_power(hda, true);
                if (err < 0) {
                        dev_err(chip->card->dev,
                                "Cannot turn on display power on i915\n");
-                       goto out_free;
+                       goto i915_power_fail;
                }
 #endif
        }
@@ -1939,6 +1964,11 @@ static int azx_probe_continue(struct azx *chip)
                pm_runtime_put_noidle(&pci->dev);
 
 out_free:
+       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL
+               && !hda->need_i915_power)
+               hda_display_power(hda, false);
+
+i915_power_fail:
        if (err < 0)
                hda->init_failed = 1;
        complete_all(&hda->probe_wait);