Merge branch 'topic/hda' into for-next
authorTakashi Iwai <tiwai@suse.de>
Wed, 29 Apr 2015 10:28:52 +0000 (12:28 +0200)
committerTakashi Iwai <tiwai@suse.de>
Wed, 29 Apr 2015 10:28:52 +0000 (12:28 +0200)
1  2 
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_controller.h
sound/pci/hda/hda_i915.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_hdmi.c

@@@ -781,15 -781,14 +781,15 @@@ struct hda_pcm *snd_hda_codec_pcm_new(s
        struct hda_pcm *pcm;
        va_list args;
  
 -      va_start(args, fmt);
        pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
        if (!pcm)
                return NULL;
  
        pcm->codec = codec;
        kref_init(&pcm->kref);
 +      va_start(args, fmt);
        pcm->name = kvasprintf(GFP_KERNEL, fmt, args);
 +      va_end(args);
        if (!pcm->name) {
                kfree(pcm);
                return NULL;
@@@ -858,6 -857,7 +858,7 @@@ void snd_hda_codec_register(struct hda_
                return;
        if (device_is_registered(hda_codec_dev(codec))) {
                snd_hda_register_beep_device(codec);
+               snd_hdac_link_power(&codec->core, true);
                pm_runtime_enable(hda_codec_dev(codec));
                /* it was powered up in snd_hda_codec_new(), now all done */
                snd_hda_power_down(codec);
@@@ -884,6 -884,7 +885,7 @@@ static int snd_hda_codec_dev_free(struc
        struct hda_codec *codec = device->device_data;
  
        codec->in_freeing = 1;
+       snd_hdac_link_power(&codec->core, false);
        snd_hdac_device_unregister(&codec->core);
        put_device(hda_codec_dev(codec));
        return 0;
@@@ -1991,16 -1992,6 +1993,16 @@@ static struct snd_kcontrol_new vmaster_
        .put = vmaster_mute_mode_put,
  };
  
 +/* meta hook to call each driver's vmaster hook */
 +static void vmaster_hook(void *private_data, int enabled)
 +{
 +      struct hda_vmaster_mute_hook *hook = private_data;
 +
 +      if (hook->mute_mode != HDA_VMUTE_FOLLOW_MASTER)
 +              enabled = hook->mute_mode;
 +      hook->hook(hook->codec, enabled);
 +}
 +
  /**
   * snd_hda_add_vmaster_hook - Add a vmaster hook for mute-LED
   * @codec: the HDA codec
@@@ -2019,9 -2010,9 +2021,9 @@@ int snd_hda_add_vmaster_hook(struct hda
  
        if (!hook->hook || !hook->sw_kctl)
                return 0;
 -      snd_ctl_add_vmaster_hook(hook->sw_kctl, hook->hook, codec);
        hook->codec = codec;
        hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
 +      snd_ctl_add_vmaster_hook(hook->sw_kctl, vmaster_hook, hook);
        if (!expose_enum_ctl)
                return 0;
        kctl = snd_ctl_new1(&vmaster_mute_mode, hook);
@@@ -2047,7 -2038,14 +2049,7 @@@ void snd_hda_sync_vmaster_hook(struct h
         */
        if (hook->codec->bus->shutdown)
                return;
 -      switch (hook->mute_mode) {
 -      case HDA_VMUTE_FOLLOW_MASTER:
 -              snd_ctl_sync_vmaster_hook(hook->sw_kctl);
 -              break;
 -      default:
 -              hook->hook(hook->codec, hook->mute_mode);
 -              break;
 -      }
 +      snd_ctl_sync_vmaster_hook(hook->sw_kctl);
  }
  EXPORT_SYMBOL_GPL(snd_hda_sync_vmaster_hook);
  
@@@ -2441,7 -2439,7 +2443,7 @@@ static void set_dig_out(struct hda_code
        if (!d)
                return;
        for (; *d; d++)
 -              snd_hdac_regmap_update(&codec->core, nid,
 +              snd_hdac_regmap_update(&codec->core, *d,
                                       AC_VERB_SET_DIGI_CONVERT_1, mask, val);
  }
  
@@@ -3106,6 -3104,7 +3108,7 @@@ static int hda_codec_runtime_suspend(st
        if (codec_has_clkstop(codec) && codec_has_epss(codec) &&
            (state & AC_PWRST_CLK_STOP_OK))
                snd_hdac_codec_link_down(&codec->core);
+       snd_hdac_link_power(&codec->core, false);
        return 0;
  }
  
@@@ -3113,6 -3112,7 +3116,7 @@@ static int hda_codec_runtime_resume(str
  {
        struct hda_codec *codec = dev_to_hda_codec(dev);
  
+       snd_hdac_link_power(&codec->core, true);
        snd_hdac_codec_link_up(&codec->core);
        hda_call_codec_resume(codec);
        pm_runtime_mark_last_busy(dev);
@@@ -89,6 -89,8 +89,8 @@@ struct hda_controller_ops 
                                 struct vm_area_struct *area);
        /* Check if current position is acceptable */
        int (*position_check)(struct azx *chip, struct azx_dev *azx_dev);
+       /* enable/disable the link power */
+       int (*link_power)(struct azx *chip, bool enable);
  };
  
  struct azx_pcm {
@@@ -185,7 -187,7 +187,7 @@@ struct azx 
        snd_hdac_chip_readb(azx_bus(chip), reg)
  
  #define azx_has_pm_runtime(chip) \
 -      (!AZX_DCAPS_PM_RUNTIME || ((chip)->driver_caps & AZX_DCAPS_PM_RUNTIME))
 +      ((chip)->driver_caps & AZX_DCAPS_PM_RUNTIME)
  
  /* PCM setup */
  static inline struct azx_dev *get_azx_dev(struct snd_pcm_substream *substream)
diff --combined sound/pci/hda/hda_i915.c
@@@ -42,10 -42,15 +42,15 @@@ int hda_display_power(struct hda_intel 
  
        dev_dbg(&hda->chip.pci->dev, "display power %s\n",
                enable ? "enable" : "disable");
-       if (enable)
-               acomp->ops->get_power(acomp->dev);
-       else
-               acomp->ops->put_power(acomp->dev);
+       if (enable) {
+               if (!hda->i915_power_refcount++)
+                       acomp->ops->get_power(acomp->dev);
+       } else {
+               WARN_ON(!hda->i915_power_refcount);
+               if (!--hda->i915_power_refcount)
+                       acomp->ops->put_power(acomp->dev);
+       }
  
        return 0;
  }
@@@ -55,12 -60,6 +60,12 @@@ void haswell_set_bclk(struct hda_intel 
        int cdclk_freq;
        unsigned int bclk_m, bclk_n;
        struct i915_audio_component *acomp = &hda->audio_component;
 +      struct pci_dev *pci = hda->chip.pci;
 +
 +      /* Only Haswell/Broadwell need set BCLK */
 +      if (pci->device != 0x0a0c && pci->device != 0x0c0c
 +         && pci->device != 0x0d0c && pci->device != 0x160c)
 +              return;
  
        if (!acomp->ops)
                return;
@@@ -189,6 -188,11 +194,11 @@@ out_err
  int hda_i915_exit(struct hda_intel *hda)
  {
        struct device *dev = &hda->chip.pci->dev;
+       struct i915_audio_component *acomp = &hda->audio_component;
+       WARN_ON(hda->i915_power_refcount);
+       if (hda->i915_power_refcount > 0 && acomp->ops)
+               acomp->ops->put_power(acomp->dev);
  
        component_master_del(dev, &hda_component_master_ops);
  
@@@ -297,9 -297,6 +297,9 @@@ enum 
         AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_POWERWELL |\
         AZX_DCAPS_SNOOP_TYPE(SCH))
  
 +#define AZX_DCAPS_INTEL_BAYTRAIL \
 +      (AZX_DCAPS_INTEL_PCH_NOPM | AZX_DCAPS_I915_POWERWELL)
 +
  #define AZX_DCAPS_INTEL_BRASWELL \
        (AZX_DCAPS_INTEL_PCH | AZX_DCAPS_I915_POWERWELL)
  
@@@ -543,6 -540,14 +543,14 @@@ static int azx_position_check(struct az
        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 -814,8 +817,8 @@@ static int azx_suspend(struct device *d
  
        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 -835,8 +838,8 @@@ static int azx_resume(struct device *de
        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 -879,8 +882,8 @@@ static int azx_runtime_suspend(struct d
        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 -905,8 +908,8 @@@ static int azx_runtime_resume(struct de
        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 -1127,8 +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);
@@@ -1561,11 -1571,11 +1574,11 @@@ static int azx_first_init(struct azx *c
        /* allow 64bit DMA address if supported by H/W */
        if (!(gcap & AZX_GCAP_64OK))
                dma_bits = 32;
 -      if (!pci_set_dma_mask(pci, DMA_BIT_MASK(dma_bits))) {
 -              pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(dma_bits));
 +      if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) {
 +              dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(dma_bits));
        } else {
 -              pci_set_dma_mask(pci, DMA_BIT_MASK(32));
 -              pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32));
 +              dma_set_mask(&pci->dev, DMA_BIT_MASK(32));
 +              dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32));
        }
  
        /* read number of streams from GCAP register instead of using
@@@ -1789,6 -1799,7 +1802,7 @@@ static const struct hda_controller_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 -1893,28 +1896,28 @@@ static int azx_probe_continue(struct az
        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
        }
                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);
@@@ -2023,7 -2050,7 +2053,7 @@@ static const struct pci_device_id azx_i
          .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },
        /* BayTrail */
        { PCI_DEVICE(0x8086, 0x0f04),
 -        .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
 +        .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BAYTRAIL },
        /* Braswell */
        { PCI_DEVICE(0x8086, 0x2284),
          .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BRASWELL },
@@@ -592,7 -592,7 +592,7 @@@ static int eld_proc_new(struct hdmi_spe
  static void eld_proc_free(struct hdmi_spec_per_pin *per_pin)
  {
        if (!per_pin->codec->bus->shutdown && per_pin->proc_entry) {
 -              snd_device_free(per_pin->codec->card, per_pin->proc_entry);
 +              snd_info_free_entry(per_pin->proc_entry);
                per_pin->proc_entry = NULL;
        }
  }
@@@ -2081,7 -2081,7 +2081,7 @@@ static int generic_hdmi_build_jack(stru
                strncat(hdmi_str, " Phantom",
                        sizeof(hdmi_str) - strlen(hdmi_str) - 1);
  
 -      return snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str, 0);
 +      return snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str);
  }
  
  static int generic_hdmi_build_controls(struct hda_codec *codec)
@@@ -2335,6 -2335,15 +2335,15 @@@ static int patch_generic_hdmi(struct hd
                intel_haswell_fixup_enable_dp12(codec);
        }
  
+       /* For Valleyview/Cherryview, only the display codec is in the display
+        * power well and can use link_power ops to request/release the power.
+        * For Haswell/Broadwell, the controller is also in the power well and
+        * can cover the codec power request, and so need not set this flag.
+        * For previous platforms, there is no such power well feature.
+        */
+       if (is_valleyview_plus(codec))
+               codec->core.link_power_control = 1;
        if (is_haswell_plus(codec) || is_valleyview_plus(codec))
                codec->depop_delay = 0;