sound fixes for 5.4-rc6
A copule of regression fixes and a fix for mutex deadlock at hog-unplug, as well as other device-specific fixes: - A commit for avoiding 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 -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAl26CfIOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE8rlRAAytCk4/fyNpxEk0IV7cfqMWKuqwtUiQlR7BNt dGW0arnTDVfIonwYH2M83iDS7LgNOu1kw4ids3ofif8BLvmcaBr60pWkzWz3PITN e4+eY4JEVmkXHjVcZxwarzDOpo3XPI7PAM07fbE76IkrPFasFvUXBARF8RQqRQy2 JmrJF99ylOM/YATT6faw6qFiDa+ZMU8HYfa+Rj+GPKQAgQupEBIgyvt35nxAupHM rPn3IwXaYq6TQTPeZB8dH0GJzEHKLwozfQoqRzO6Zjwlg7dVhyUYOYDW2ID4I0ci KMs9RRRx3Ai7Id1nECJw6adwIlqviNzQntlpzvvQT7SAGGQebNeVET+1+7GLPEM/ ZvGi2nmIZpNU5nHde+4XLuRfFjJawzyNjA9ud7S3XnXJbO6m9Lgmx34EQ86KLd9g zr4aJL6343NSICoco4FHqfQ+YmWxV3Jc2Dsz2zrS20Xw/rokei1ngpL/+N9EVE6T qCOwP6TzsafsRsuqV2fPx+dswYnUQfiFxfer6eRRx+B74d274qepPAJTgnPbknQt xaC4CwYRKe1HMSsUwgKQV0XSduwXI5fAc7n7gikYYxbabAseycz3xHxS6csqbRaq Kjom6F7BI43cQSHXlfLNEnMHtnkE+x9cx1ymO0BJzVojtNCL/Syx3JpNBUFJXP9/ 8Rn1qfA= =Qt/i -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
2858598006
|
@ -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,
|
||||||
{
|
{
|
||||||
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(®ister_mutex);
|
mutex_lock(®ister_mutex);
|
||||||
|
@ -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,
|
||||||
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,
|
||||||
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(®ister_mutex);
|
mutex_unlock(®ister_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);
|
||||||
* 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)
|
||||||
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)
|
||||||
*/
|
*/
|
||||||
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(®ister_mutex);
|
mutex_lock(®ister_mutex);
|
||||||
err = snd_timer_close_locked(timeri);
|
err = snd_timer_close_locked(timeri, &card_dev_to_put);
|
||||||
mutex_unlock(®ister_mutex);
|
mutex_unlock(®ister_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 @@ end:
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
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 {
|
||||||
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)
|
||||||
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[] = {
|
||||||
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)
|
||||||
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[] = {
|
||||||
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,
|
||||||
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 */
|
||||||
|
|
Loading…
Reference in New Issue