Commit 28585980 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'sound-5.4-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "A couple of regression fixes and a fix for mutex deadlock at
  hog-unplug, as well as other device-specific fixes:

   - A commit to avoid the spurious unsolicited interrupt on HD-audio
     bus caused a stall at shutdown, so it's reverted now.

   - The recent support of AMD/Nvidia audio component binding caused a
     mutex deadlock; fixed by splitting to another mutex

   - The device hot-unplug and the ALSA timer close combo may lead to
     another mutex deadlock; fixed by moving put_device() calls

   - Usual device-specific small quirks for HD- and USB-audio drivers

   - An old error check fix in FireWire driver"

* tag 'sound-5.4-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: timer: Fix mutex deadlock at releasing card
  ALSA: hda - Fix mutex deadlock in HDMI codec driver
  Revert "ALSA: hda: Flush interrupts on disabling"
  ALSA: bebob: Fix prototype of helper function to return negative value
  ALSA: hda/realtek - Fix 2 front mics of codec 0x623
  ALSA: hda/realtek - Add support for ALC623
  ALSA: usb-audio: Add DSD support for Gustard U16/X26 USB Interface
parents e472c64a a3933186
...@@ -226,7 +226,8 @@ static int snd_timer_check_master(struct snd_timer_instance *master) ...@@ -226,7 +226,8 @@ static int snd_timer_check_master(struct snd_timer_instance *master)
return 0; 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 * open a timer instance
...@@ -238,6 +239,7 @@ int snd_timer_open(struct snd_timer_instance **ti, ...@@ -238,6 +239,7 @@ int snd_timer_open(struct snd_timer_instance **ti,
{ {
struct snd_timer *timer; struct snd_timer *timer;
struct snd_timer_instance *timeri = NULL; struct snd_timer_instance *timeri = NULL;
struct device *card_dev_to_put = NULL;
int err; int err;
mutex_lock(&register_mutex); mutex_lock(&register_mutex);
...@@ -261,7 +263,7 @@ int snd_timer_open(struct snd_timer_instance **ti, ...@@ -261,7 +263,7 @@ int snd_timer_open(struct snd_timer_instance **ti,
list_add_tail(&timeri->open_list, &snd_timer_slave_list); list_add_tail(&timeri->open_list, &snd_timer_slave_list);
err = snd_timer_check_slave(timeri); err = snd_timer_check_slave(timeri);
if (err < 0) { if (err < 0) {
snd_timer_close_locked(timeri); snd_timer_close_locked(timeri, &card_dev_to_put);
timeri = NULL; timeri = NULL;
} }
goto unlock; goto unlock;
...@@ -313,7 +315,7 @@ int snd_timer_open(struct snd_timer_instance **ti, ...@@ -313,7 +315,7 @@ int snd_timer_open(struct snd_timer_instance **ti,
timeri = NULL; timeri = NULL;
if (timer->card) if (timer->card)
put_device(&timer->card->card_dev); card_dev_to_put = &timer->card->card_dev;
module_put(timer->module); module_put(timer->module);
goto unlock; goto unlock;
} }
...@@ -323,12 +325,15 @@ int snd_timer_open(struct snd_timer_instance **ti, ...@@ -323,12 +325,15 @@ int snd_timer_open(struct snd_timer_instance **ti,
timer->num_instances++; timer->num_instances++;
err = snd_timer_check_master(timeri); err = snd_timer_check_master(timeri);
if (err < 0) { if (err < 0) {
snd_timer_close_locked(timeri); snd_timer_close_locked(timeri, &card_dev_to_put);
timeri = NULL; timeri = NULL;
} }
unlock: unlock:
mutex_unlock(&register_mutex); 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; *ti = timeri;
return err; return err;
} }
...@@ -338,7 +343,8 @@ EXPORT_SYMBOL(snd_timer_open); ...@@ -338,7 +343,8 @@ EXPORT_SYMBOL(snd_timer_open);
* close a timer instance * close a timer instance
* call this with register_mutex down. * 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 *timer = timeri->timer;
struct snd_timer_instance *slave, *tmp; struct snd_timer_instance *slave, *tmp;
...@@ -395,7 +401,7 @@ static int snd_timer_close_locked(struct snd_timer_instance *timeri) ...@@ -395,7 +401,7 @@ static int snd_timer_close_locked(struct snd_timer_instance *timeri)
timer->hw.close(timer); timer->hw.close(timer);
/* release a card refcount for safe disconnection */ /* release a card refcount for safe disconnection */
if (timer->card) if (timer->card)
put_device(&timer->card->card_dev); *card_devp_to_put = &timer->card->card_dev;
module_put(timer->module); module_put(timer->module);
} }
...@@ -407,14 +413,18 @@ static int snd_timer_close_locked(struct snd_timer_instance *timeri) ...@@ -407,14 +413,18 @@ static int snd_timer_close_locked(struct snd_timer_instance *timeri)
*/ */
int snd_timer_close(struct snd_timer_instance *timeri) int snd_timer_close(struct snd_timer_instance *timeri)
{ {
struct device *card_dev_to_put = NULL;
int err; int err;
if (snd_BUG_ON(!timeri)) if (snd_BUG_ON(!timeri))
return -ENXIO; return -ENXIO;
mutex_lock(&register_mutex); mutex_lock(&register_mutex);
err = snd_timer_close_locked(timeri); err = snd_timer_close_locked(timeri, &card_dev_to_put);
mutex_unlock(&register_mutex); 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; return err;
} }
EXPORT_SYMBOL(snd_timer_close); EXPORT_SYMBOL(snd_timer_close);
......
...@@ -252,8 +252,7 @@ int snd_bebob_stream_get_clock_src(struct snd_bebob *bebob, ...@@ -252,8 +252,7 @@ int snd_bebob_stream_get_clock_src(struct snd_bebob *bebob,
return err; return err;
} }
static unsigned int static int map_data_channels(struct snd_bebob *bebob, struct amdtp_stream *s)
map_data_channels(struct snd_bebob *bebob, struct amdtp_stream *s)
{ {
unsigned int sec, sections, ch, channels; unsigned int sec, sections, ch, channels;
unsigned int pcm, midi, location; unsigned int pcm, midi, location;
......
...@@ -447,8 +447,6 @@ static void azx_int_disable(struct hdac_bus *bus) ...@@ -447,8 +447,6 @@ static void azx_int_disable(struct hdac_bus *bus)
list_for_each_entry(azx_dev, &bus->stream_list, list) list_for_each_entry(azx_dev, &bus->stream_list, list)
snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_INT_MASK, 0); snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_INT_MASK, 0);
synchronize_irq(bus->irq);
/* disable SIE for all streams */ /* disable SIE for all streams */
snd_hdac_chip_writeb(bus, INTCTL, 0); snd_hdac_chip_writeb(bus, INTCTL, 0);
......
...@@ -1348,9 +1348,9 @@ static int azx_free(struct azx *chip) ...@@ -1348,9 +1348,9 @@ static int azx_free(struct azx *chip)
} }
if (bus->chip_init) { if (bus->chip_init) {
azx_stop_chip(chip);
azx_clear_irq_pending(chip); azx_clear_irq_pending(chip);
azx_stop_all_streams(chip); azx_stop_all_streams(chip);
azx_stop_chip(chip);
} }
if (bus->irq >= 0) if (bus->irq >= 0)
......
...@@ -145,6 +145,7 @@ struct hdmi_spec { ...@@ -145,6 +145,7 @@ struct hdmi_spec {
struct snd_array pins; /* struct hdmi_spec_per_pin */ struct snd_array pins; /* struct hdmi_spec_per_pin */
struct hdmi_pcm pcm_rec[16]; struct hdmi_pcm pcm_rec[16];
struct mutex pcm_lock; struct mutex pcm_lock;
struct mutex bind_lock; /* for audio component binding */
/* pcm_bitmap means which pcms have been assigned to pins*/ /* pcm_bitmap means which pcms have been assigned to pins*/
unsigned long pcm_bitmap; unsigned long pcm_bitmap;
int pcm_used; /* counter of pcm_rec[] */ int pcm_used; /* counter of pcm_rec[] */
...@@ -2258,7 +2259,7 @@ static int generic_hdmi_init(struct hda_codec *codec) ...@@ -2258,7 +2259,7 @@ static int generic_hdmi_init(struct hda_codec *codec)
struct hdmi_spec *spec = codec->spec; struct hdmi_spec *spec = codec->spec;
int pin_idx; int pin_idx;
mutex_lock(&spec->pcm_lock); mutex_lock(&spec->bind_lock);
spec->use_jack_detect = !codec->jackpoll_interval; spec->use_jack_detect = !codec->jackpoll_interval;
for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
...@@ -2275,7 +2276,7 @@ static int generic_hdmi_init(struct hda_codec *codec) ...@@ -2275,7 +2276,7 @@ static int generic_hdmi_init(struct hda_codec *codec)
snd_hda_jack_detect_enable_callback(codec, pin_nid, snd_hda_jack_detect_enable_callback(codec, pin_nid,
jack_callback); jack_callback);
} }
mutex_unlock(&spec->pcm_lock); mutex_unlock(&spec->bind_lock);
return 0; return 0;
} }
...@@ -2382,6 +2383,7 @@ static int alloc_generic_hdmi(struct hda_codec *codec) ...@@ -2382,6 +2383,7 @@ static int alloc_generic_hdmi(struct hda_codec *codec)
spec->ops = generic_standard_hdmi_ops; spec->ops = generic_standard_hdmi_ops;
spec->dev_num = 1; /* initialize to 1 */ spec->dev_num = 1; /* initialize to 1 */
mutex_init(&spec->pcm_lock); mutex_init(&spec->pcm_lock);
mutex_init(&spec->bind_lock);
snd_hdac_register_chmap_ops(&codec->core, &spec->chmap); snd_hdac_register_chmap_ops(&codec->core, &spec->chmap);
spec->chmap.ops.get_chmap = hdmi_get_chmap; spec->chmap.ops.get_chmap = hdmi_get_chmap;
...@@ -2451,7 +2453,7 @@ static void generic_acomp_notifier_set(struct drm_audio_component *acomp, ...@@ -2451,7 +2453,7 @@ static void generic_acomp_notifier_set(struct drm_audio_component *acomp,
int i; int i;
spec = container_of(acomp->audio_ops, struct hdmi_spec, drm_audio_ops); 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->use_acomp_notifier = use_acomp;
spec->codec->relaxed_resume = use_acomp; spec->codec->relaxed_resume = use_acomp;
/* reprogram each jack detection logic depending on the notifier */ /* reprogram each jack detection logic depending on the notifier */
...@@ -2461,7 +2463,7 @@ static void generic_acomp_notifier_set(struct drm_audio_component *acomp, ...@@ -2461,7 +2463,7 @@ static void generic_acomp_notifier_set(struct drm_audio_component *acomp,
get_pin(spec, i)->pin_nid, get_pin(spec, i)->pin_nid,
use_acomp); use_acomp);
} }
mutex_unlock(&spec->pcm_lock); mutex_unlock(&spec->bind_lock);
} }
/* enable / disable the notifier via master bind / unbind */ /* enable / disable the notifier via master bind / unbind */
......
...@@ -409,6 +409,9 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) ...@@ -409,6 +409,9 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
case 0x10ec0672: case 0x10ec0672:
alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */ alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
break; break;
case 0x10ec0623:
alc_update_coef_idx(codec, 0x19, 1<<13, 0);
break;
case 0x10ec0668: case 0x10ec0668:
alc_update_coef_idx(codec, 0x7, 3<<13, 0); alc_update_coef_idx(codec, 0x7, 3<<13, 0);
break; break;
...@@ -2920,6 +2923,7 @@ enum { ...@@ -2920,6 +2923,7 @@ enum {
ALC269_TYPE_ALC225, ALC269_TYPE_ALC225,
ALC269_TYPE_ALC294, ALC269_TYPE_ALC294,
ALC269_TYPE_ALC300, ALC269_TYPE_ALC300,
ALC269_TYPE_ALC623,
ALC269_TYPE_ALC700, ALC269_TYPE_ALC700,
}; };
...@@ -2955,6 +2959,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) ...@@ -2955,6 +2959,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
case ALC269_TYPE_ALC225: case ALC269_TYPE_ALC225:
case ALC269_TYPE_ALC294: case ALC269_TYPE_ALC294:
case ALC269_TYPE_ALC300: case ALC269_TYPE_ALC300:
case ALC269_TYPE_ALC623:
case ALC269_TYPE_ALC700: case ALC269_TYPE_ALC700:
ssids = alc269_ssids; ssids = alc269_ssids;
break; break;
...@@ -7216,6 +7221,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -7216,6 +7221,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
SND_PCI_QUIRK(0x17aa, 0x3151, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x17aa, 0x3151, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI), SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
...@@ -8017,6 +8024,9 @@ static int patch_alc269(struct hda_codec *codec) ...@@ -8017,6 +8024,9 @@ static int patch_alc269(struct hda_codec *codec)
spec->codec_variant = ALC269_TYPE_ALC300; spec->codec_variant = ALC269_TYPE_ALC300;
spec->gen.mixer_nid = 0; /* no loopback on ALC300 */ spec->gen.mixer_nid = 0; /* no loopback on ALC300 */
break; break;
case 0x10ec0623:
spec->codec_variant = ALC269_TYPE_ALC623;
break;
case 0x10ec0700: case 0x10ec0700:
case 0x10ec0701: case 0x10ec0701:
case 0x10ec0703: case 0x10ec0703:
...@@ -9218,6 +9228,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = { ...@@ -9218,6 +9228,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269), HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269), HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0300, "ALC300", patch_alc269), HDA_CODEC_ENTRY(0x10ec0300, "ALC300", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0623, "ALC623", patch_alc269),
HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861), HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd), HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861), HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
......
...@@ -1657,6 +1657,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, ...@@ -1657,6 +1657,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
case 0x23ba: /* Playback Designs */ case 0x23ba: /* Playback Designs */
case 0x25ce: /* Mytek devices */ case 0x25ce: /* Mytek devices */
case 0x278b: /* Rotel? */ case 0x278b: /* Rotel? */
case 0x292b: /* Gustard/Ess based devices */
case 0x2ab6: /* T+A devices */ case 0x2ab6: /* T+A devices */
case 0x3842: /* EVGA */ case 0x3842: /* EVGA */
case 0xc502: /* HiBy devices */ case 0xc502: /* HiBy devices */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment