Merge branch 'for-linus' into for-next
authorTakashi Iwai <tiwai@suse.de>
Thu, 7 Nov 2019 15:27:49 +0000 (16:27 +0100)
committerTakashi Iwai <tiwai@suse.de>
Thu, 7 Nov 2019 15:27:55 +0000 (16:27 +0100)
Merge 5.4-devel branch for applying the further ALSA timer fixes.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
1  2 
sound/core/timer.c
sound/pci/hda/patch_hdmi.c

diff --combined sound/core/timer.c
index 219249627cc3386dc016e1e3ca1ad1960018bab0,59ae21b0bb936c0757d58573b1bac3ed3defcb1a..013f0e69ff0f719fc1d090cd10a619a7bf47734a
@@@ -74,9 -74,6 +74,9 @@@ static LIST_HEAD(snd_timer_slave_list)
  /* lock for slave active lists */
  static DEFINE_SPINLOCK(slave_active_lock);
  
 +#define MAX_SLAVE_INSTANCES   1000
 +static int num_slaves;
 +
  static DEFINE_MUTEX(register_mutex);
  
  static int snd_timer_free(struct snd_timer *timer);
@@@ -229,7 -226,8 +229,8 @@@ static int snd_timer_check_master(struc
        return 0;
  }
  
- static int snd_timer_close_locked(struct snd_timer_instance *timeri);
+ static int snd_timer_close_locked(struct snd_timer_instance *timeri,
+                                 struct device **card_devp_to_put);
  
  /*
   * open a timer instance
@@@ -241,6 -239,7 +242,7 @@@ int snd_timer_open(struct snd_timer_ins
  {
        struct snd_timer *timer;
        struct snd_timer_instance *timeri = NULL;
+       struct device *card_dev_to_put = NULL;
        int err;
  
        mutex_lock(&register_mutex);
                        err = -EINVAL;
                        goto unlock;
                }
 +              if (num_slaves >= MAX_SLAVE_INSTANCES) {
 +                      err = -EBUSY;
 +                      goto unlock;
 +              }
                timeri = snd_timer_instance_new(owner, NULL);
                if (!timeri) {
                        err = -ENOMEM;
                timeri->slave_id = tid->device;
                timeri->flags |= SNDRV_TIMER_IFLG_SLAVE;
                list_add_tail(&timeri->open_list, &snd_timer_slave_list);
 +              num_slaves++;
                err = snd_timer_check_slave(timeri);
                if (err < 0) {
-                       snd_timer_close_locked(timeri);
+                       snd_timer_close_locked(timeri, &card_dev_to_put);
                        timeri = NULL;
                }
                goto unlock;
                goto unlock;
        }
        if (!list_empty(&timer->open_list_head)) {
-               timeri = list_entry(timer->open_list_head.next,
+               struct snd_timer_instance *t =
+                       list_entry(timer->open_list_head.next,
                                    struct snd_timer_instance, open_list);
-               if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
+               if (t->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
                        err = -EBUSY;
-                       timeri = NULL;
                        goto unlock;
                }
        }
                        timeri = NULL;
  
                        if (timer->card)
-                               put_device(&timer->card->card_dev);
+                               card_dev_to_put = &timer->card->card_dev;
                        module_put(timer->module);
                        goto unlock;
                }
        timer->num_instances++;
        err = snd_timer_check_master(timeri);
        if (err < 0) {
-               snd_timer_close_locked(timeri);
+               snd_timer_close_locked(timeri, &card_dev_to_put);
                timeri = NULL;
        }
  
   unlock:
        mutex_unlock(&register_mutex);
+       /* put_device() is called after unlock for avoiding deadlock */
+       if (card_dev_to_put)
+               put_device(card_dev_to_put);
        *ti = timeri;
        return err;
  }
@@@ -346,7 -343,8 +351,8 @@@ EXPORT_SYMBOL(snd_timer_open)
   * close a timer instance
   * call this with register_mutex down.
   */
- static int snd_timer_close_locked(struct snd_timer_instance *timeri)
+ static int snd_timer_close_locked(struct snd_timer_instance *timeri,
+                                 struct device **card_devp_to_put)
  {
        struct snd_timer *timer = timeri->timer;
        struct snd_timer_instance *slave, *tmp;
        }
  
        list_del(&timeri->open_list);
 +      if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
 +              num_slaves--;
  
        /* force to stop the timer */
        snd_timer_stop(timeri);
                        timer->hw.close(timer);
                /* release a card refcount for safe disconnection */
                if (timer->card)
-                       put_device(&timer->card->card_dev);
+                       *card_devp_to_put = &timer->card->card_dev;
                module_put(timer->module);
        }
  
   */
  int snd_timer_close(struct snd_timer_instance *timeri)
  {
+       struct device *card_dev_to_put = NULL;
        int err;
  
        if (snd_BUG_ON(!timeri))
                return -ENXIO;
  
        mutex_lock(&register_mutex);
-       err = snd_timer_close_locked(timeri);
+       err = snd_timer_close_locked(timeri, &card_dev_to_put);
        mutex_unlock(&register_mutex);
+       /* put_device() is called after unlock for avoiding deadlock */
+       if (card_dev_to_put)
+               put_device(card_dev_to_put);
        return err;
  }
  EXPORT_SYMBOL(snd_timer_close);
index 2d59688a121d5d1fc5bb3fb7a67de447f8384be7,3c720703ebb8338c4ad9eef13ec5d90de9600866..be8a977fc684e22fe69b6a5ac1a5bb5ec8f2797d
@@@ -145,6 -145,7 +145,7 @@@ struct hdmi_spec 
        struct snd_array pins; /* struct hdmi_spec_per_pin */
        struct hdmi_pcm pcm_rec[16];
        struct mutex pcm_lock;
+       struct mutex bind_lock; /* for audio component binding */
        /* pcm_bitmap means which pcms have been assigned to pins*/
        unsigned long pcm_bitmap;
        int pcm_used;   /* counter of pcm_rec[] */
@@@ -2072,24 -2073,15 +2073,24 @@@ static bool is_hdmi_pcm_attached(struc
  static int generic_hdmi_build_pcms(struct hda_codec *codec)
  {
        struct hdmi_spec *spec = codec->spec;
 -      int idx;
 +      int idx, pcm_num;
  
        /*
         * for non-mst mode, pcm number is the same as before
 -       * for DP MST mode, pcm number is (nid number + dev_num - 1)
 -       *  dev_num is the device entry number in a pin
 -       *
 +       * for DP MST mode without extra PCM, pcm number is same
 +       * for DP MST mode with extra PCMs, pcm number is
 +       *  (nid number + dev_num - 1)
 +       * dev_num is the device entry number in a pin
         */
 -      for (idx = 0; idx < spec->num_nids + spec->dev_num - 1; idx++) {
 +
 +      if (codec->mst_no_extra_pcms)
 +              pcm_num = spec->num_nids;
 +      else
 +              pcm_num = spec->num_nids + spec->dev_num - 1;
 +
 +      codec_dbg(codec, "hdmi: pcm_num set to %d\n", pcm_num);
 +
 +      for (idx = 0; idx < pcm_num; idx++) {
                struct hda_pcm *info;
                struct hda_pcm_stream *pstr;
  
@@@ -2267,7 -2259,7 +2268,7 @@@ static int generic_hdmi_init(struct hda
        struct hdmi_spec *spec = codec->spec;
        int pin_idx;
  
-       mutex_lock(&spec->pcm_lock);
+       mutex_lock(&spec->bind_lock);
        spec->use_jack_detect = !codec->jackpoll_interval;
        for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
                struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
                        snd_hda_jack_detect_enable_callback(codec, pin_nid,
                                                            jack_callback);
        }
-       mutex_unlock(&spec->pcm_lock);
+       mutex_unlock(&spec->bind_lock);
        return 0;
  }
  
@@@ -2391,6 -2383,7 +2392,7 @@@ static int alloc_generic_hdmi(struct hd
        spec->ops = generic_standard_hdmi_ops;
        spec->dev_num = 1;      /* initialize to 1 */
        mutex_init(&spec->pcm_lock);
+       mutex_init(&spec->bind_lock);
        snd_hdac_register_chmap_ops(&codec->core, &spec->chmap);
  
        spec->chmap.ops.get_chmap = hdmi_get_chmap;
@@@ -2460,7 -2453,7 +2462,7 @@@ static void generic_acomp_notifier_set(
        int i;
  
        spec = container_of(acomp->audio_ops, struct hdmi_spec, drm_audio_ops);
-       mutex_lock(&spec->pcm_lock);
+       mutex_lock(&spec->bind_lock);
        spec->use_acomp_notifier = use_acomp;
        spec->codec->relaxed_resume = use_acomp;
        /* reprogram each jack detection logic depending on the notifier */
                                              get_pin(spec, i)->pin_nid,
                                              use_acomp);
        }
-       mutex_unlock(&spec->pcm_lock);
+       mutex_unlock(&spec->bind_lock);
  }
  
  /* enable / disable the notifier via master bind / unbind */
@@@ -2858,6 -2851,18 +2860,18 @@@ static int patch_i915_icl_hdmi(struct h
        return intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map));
  }
  
+ static int patch_i915_tgl_hdmi(struct hda_codec *codec)
+ {
+       /*
+        * pin to port mapping table where the value indicate the pin number and
+        * the index indicate the port number with 1 base.
+        */
+       static const int map[] = {0x4, 0x6, 0x8, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
+       return intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map));
+ }
  /* Intel Baytrail and Braswell; with eld notifier */
  static int patch_i915_byt_hdmi(struct hda_codec *codec)
  {
@@@ -4160,6 -4165,7 +4174,7 @@@ HDA_CODEC_ENTRY(0x8086280b, "Kabylake H
  HDA_CODEC_ENTRY(0x8086280c, "Cannonlake HDMI",        patch_i915_glk_hdmi),
  HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI",        patch_i915_glk_hdmi),
  HDA_CODEC_ENTRY(0x8086280f, "Icelake HDMI",   patch_i915_icl_hdmi),
+ HDA_CODEC_ENTRY(0x80862812, "Tigerlake HDMI", patch_i915_tgl_hdmi),
  HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI",        patch_generic_hdmi),
  HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI",       patch_i915_byt_hdmi),
  HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI",  patch_i915_byt_hdmi),