Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'sound-fix-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
"Here are last-minute fixes gathered before merge window close; a few
fixes are for the core while the rest majority are driver fixes.

- PCM locking annotation fixes and the possible self-lock fix

- ASoC DPCM regression fixes with multi-CPU DAI

- A fix for inconsistent resume from system-PM on USB-audio

- Improved runtime-PM handling with multiple USB interfaces

- Quirks for HD-audio and USB-audio

- Hardened firmware handling in max98390 codec

- A couple of fixes for meson"

* tag 'sound-fix-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (21 commits)
ASoC: rt5645: Add platform-data for Asus T101HA
ASoC: Intel: bytcr_rt5640: Add quirk for Toshiba Encore WT10-A tablet
ASoC: SOF: nocodec: conditionally set dpcm_capture/dpcm_playback flags
ASoC: Intel: boards: replace capture_only by dpcm_capture
ASoC: core: only convert non DPCM link to DPCM link
ASoC: soc-pcm: dpcm: fix playback/capture checks
ASoC: meson: add missing free_irq() in error path
ALSA: pcm: disallow linking stream to itself
ALSA: usb-audio: Manage auto-pm of all bundled interfaces
ALSA: hda/realtek - add a pintbl quirk for several Lenovo machines
ALSA: pcm: fix snd_pcm_link() lockdep splat
ALSA: usb-audio: Use the new macro for HP Dock rename quirks
ALSA: usb-audio: Add vendor, product and profile name for HP Thunderbolt Dock
ALSA: emu10k1: delete an unnecessary condition
dt-bindings: ASoc: Fix tdm-slot documentation spelling error
ASoC: meson: fix memory leak of links if allocation of ldata fails
ALSA: usb-audio: Fix inconsistent card PM state after resume
ASoC: max98390: Fix potential crash during param fw loading
ASoC: max98390: Fix incorrect printf qualifier
ASoC: fsl-asoc-card: Defer probe when fail to find codec device
...

+220 -56
+2 -2
Documentation/devicetree/bindings/sound/tdm-slot.txt
··· 14 14 dai-tdm-slot-tx-mask = <0 1>; 15 15 dai-tdm-slot-rx-mask = <1 0>; 16 16 17 - And for each spcified driver, there could be one .of_xlate_tdm_slot_mask() 18 - to specify a explicit mapping of the channels and the slots. If it's absent 17 + And for each specified driver, there could be one .of_xlate_tdm_slot_mask() 18 + to specify an explicit mapping of the channels and the slots. If it's absent 19 19 the default snd_soc_of_xlate_tdm_slot_mask() will be used to generating the 20 20 tx and rx masks. 21 21
+18 -2
sound/core/pcm_native.c
··· 138 138 } 139 139 EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq); 140 140 141 + static void snd_pcm_stream_lock_nested(struct snd_pcm_substream *substream) 142 + { 143 + struct snd_pcm_group *group = &substream->self_group; 144 + 145 + if (substream->pcm->nonatomic) 146 + mutex_lock_nested(&group->mutex, SINGLE_DEPTH_NESTING); 147 + else 148 + spin_lock_nested(&group->lock, SINGLE_DEPTH_NESTING); 149 + } 150 + 141 151 /** 142 152 * snd_pcm_stream_unlock_irq - Unlock the PCM stream 143 153 * @substream: PCM substream ··· 2176 2166 } 2177 2167 pcm_file = f.file->private_data; 2178 2168 substream1 = pcm_file->substream; 2169 + 2170 + if (substream == substream1) { 2171 + res = -EINVAL; 2172 + goto _badf; 2173 + } 2174 + 2179 2175 group = kzalloc(sizeof(*group), GFP_KERNEL); 2180 2176 if (!group) { 2181 2177 res = -ENOMEM; ··· 2210 2194 snd_pcm_stream_unlock_irq(substream); 2211 2195 2212 2196 snd_pcm_group_lock_irq(target_group, nonatomic); 2213 - snd_pcm_stream_lock(substream1); 2197 + snd_pcm_stream_lock_nested(substream1); 2214 2198 snd_pcm_group_assign(substream1, target_group); 2215 2199 refcount_inc(&target_group->refs); 2216 2200 snd_pcm_stream_unlock(substream1); ··· 2226 2210 2227 2211 static void relink_to_local(struct snd_pcm_substream *substream) 2228 2212 { 2229 - snd_pcm_stream_lock(substream); 2213 + snd_pcm_stream_lock_nested(substream); 2230 2214 snd_pcm_group_assign(substream, &substream->self_group); 2231 2215 snd_pcm_stream_unlock(substream); 2232 2216 }
+1 -1
sound/pci/emu10k1/emu10k1x.c
··· 1040 1040 if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3) 1041 1041 continue; 1042 1042 1043 - if (reg < 0x49 && val <= 0xffffffff && channel_id <= 2) 1043 + if (reg < 0x49 && channel_id <= 2) 1044 1044 snd_emu10k1x_ptr_write(emu, reg, channel_id, val); 1045 1045 } 1046 1046 }
+6
sound/pci/hda/patch_realtek.c
··· 8161 8161 ALC225_STANDARD_PINS, 8162 8162 {0x12, 0xb7a60130}, 8163 8163 {0x17, 0x90170110}), 8164 + SND_HDA_PIN_QUIRK(0x10ec0623, 0x17aa, "Lenovo", ALC283_FIXUP_HEADSET_MIC, 8165 + {0x14, 0x01014010}, 8166 + {0x17, 0x90170120}, 8167 + {0x18, 0x02a11030}, 8168 + {0x19, 0x02a1103f}, 8169 + {0x21, 0x0221101f}), 8164 8170 {} 8165 8171 }; 8166 8172
+21 -5
sound/soc/codecs/max98390.c
··· 754 754 static int max98390_dsm_init(struct snd_soc_component *component) 755 755 { 756 756 int ret; 757 + int param_size, param_start_addr; 757 758 char filename[128]; 758 759 const char *vendor, *product; 759 760 struct max98390_priv *max98390 = ··· 779 778 } 780 779 781 780 dev_dbg(component->dev, 782 - "max98390: param fw size %ld\n", 781 + "max98390: param fw size %zd\n", 783 782 fw->size); 783 + if (fw->size < MAX98390_DSM_PARAM_MIN_SIZE) { 784 + dev_err(component->dev, 785 + "param fw is invalid.\n"); 786 + goto err_alloc; 787 + } 784 788 dsm_param = (char *)fw->data; 789 + param_start_addr = (dsm_param[0] & 0xff) | (dsm_param[1] & 0xff) << 8; 790 + param_size = (dsm_param[2] & 0xff) | (dsm_param[3] & 0xff) << 8; 791 + if (param_size > MAX98390_DSM_PARAM_MAX_SIZE || 792 + param_start_addr < DSM_STBASS_HPF_B0_BYTE0 || 793 + fw->size < param_size + MAX98390_DSM_PAYLOAD_OFFSET) { 794 + dev_err(component->dev, 795 + "param fw is invalid.\n"); 796 + goto err_alloc; 797 + } 798 + regmap_write(max98390->regmap, MAX98390_R203A_AMP_EN, 0x80); 785 799 dsm_param += MAX98390_DSM_PAYLOAD_OFFSET; 786 - regmap_bulk_write(max98390->regmap, DSM_EQ_BQ1_B0_BYTE0, 787 - dsm_param, 788 - fw->size - MAX98390_DSM_PAYLOAD_OFFSET); 789 - release_firmware(fw); 800 + regmap_bulk_write(max98390->regmap, param_start_addr, 801 + dsm_param, param_size); 790 802 regmap_write(max98390->regmap, MAX98390_R23E1_DSP_GLOBAL_EN, 0x01); 791 803 804 + err_alloc: 805 + release_firmware(fw); 792 806 err: 793 807 return ret; 794 808 }
+2 -1
sound/soc/codecs/max98390.h
··· 650 650 651 651 /* DSM register offset */ 652 652 #define MAX98390_DSM_PAYLOAD_OFFSET 16 653 - #define MAX98390_DSM_PAYLOAD_OFFSET_2 495 653 + #define MAX98390_DSM_PARAM_MAX_SIZE 770 654 + #define MAX98390_DSM_PARAM_MIN_SIZE 670 654 655 655 656 struct max98390_priv { 656 657 struct regmap *regmap;
+2 -2
sound/soc/codecs/rl6231.c
··· 80 80 for (i = 0; i < ARRAY_SIZE(div); i++) { 81 81 if ((div[i] % 3) == 0) 82 82 continue; 83 - /* find divider that gives DMIC frequency below 3.072MHz */ 84 - if (3072000 * div[i] >= rate) 83 + /* find divider that gives DMIC frequency below 1.536MHz */ 84 + if (1536000 * div[i] >= rate) 85 85 return i; 86 86 } 87 87
+14
sound/soc/codecs/rt5645.c
··· 3625 3625 .inv_jd1_1 = true, 3626 3626 }; 3627 3627 3628 + static const struct rt5645_platform_data asus_t101ha_platform_data = { 3629 + .dmic1_data_pin = RT5645_DMIC_DATA_IN2N, 3630 + .dmic2_data_pin = RT5645_DMIC2_DISABLE, 3631 + .jd_mode = 3, 3632 + }; 3633 + 3628 3634 static const struct rt5645_platform_data lenovo_ideapad_miix_310_pdata = { 3629 3635 .jd_mode = 3, 3630 3636 .in2_diff = true, ··· 3713 3707 DMI_MATCH(DMI_PRODUCT_NAME, "T100HAN"), 3714 3708 }, 3715 3709 .driver_data = (void *)&asus_t100ha_platform_data, 3710 + }, 3711 + { 3712 + .ident = "ASUS T101HA", 3713 + .matches = { 3714 + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 3715 + DMI_MATCH(DMI_PRODUCT_NAME, "T101HA"), 3716 + }, 3717 + .driver_data = (void *)&asus_t101ha_platform_data, 3716 3718 }, 3717 3719 { 3718 3720 .ident = "MINIX Z83-4",
+1 -1
sound/soc/fsl/fsl-asoc-card.c
··· 581 581 582 582 if (!fsl_asoc_card_is_ac97(priv) && !codec_dev) { 583 583 dev_err(&pdev->dev, "failed to find codec device\n"); 584 - ret = -EINVAL; 584 + ret = -EPROBE_DEFER; 585 585 goto asrc_fail; 586 586 } 587 587
+12
sound/soc/intel/boards/bytcr_rt5640.c
··· 754 754 BYT_RT5640_JD_NOT_INV | 755 755 BYT_RT5640_MCLK_EN), 756 756 }, 757 + { /* Toshiba Encore WT10-A */ 758 + .matches = { 759 + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), 760 + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TOSHIBA WT10-A-103"), 761 + }, 762 + .driver_data = (void *)(BYT_RT5640_DMIC1_MAP | 763 + BYT_RT5640_JD_SRC_JD1_IN4P | 764 + BYT_RT5640_OVCD_TH_2000UA | 765 + BYT_RT5640_OVCD_SF_0P75 | 766 + BYT_RT5640_SSP0_AIF2 | 767 + BYT_RT5640_MCLK_EN), 768 + }, 757 769 { /* Catch-all for generic Insyde tablets, must be last */ 758 770 .matches = { 759 771 DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
+1 -1
sound/soc/intel/boards/glk_rt5682_max98357a.c
··· 407 407 .name = "Glk Audio Echo Reference cap", 408 408 .stream_name = "Echoreference Capture", 409 409 .init = NULL, 410 - .capture_only = 1, 410 + .dpcm_capture = 1, 411 411 .nonatomic = 1, 412 412 .dynamic = 1, 413 413 SND_SOC_DAILINK_REG(echoref, dummy, platform),
+2 -2
sound/soc/intel/boards/kbl_da7219_max98927.c
··· 692 692 .name = "Kbl Audio Echo Reference cap", 693 693 .stream_name = "Echoreference Capture", 694 694 .init = NULL, 695 - .capture_only = 1, 695 + .dpcm_capture = 1, 696 696 .nonatomic = 1, 697 697 SND_SOC_DAILINK_REG(echoref, dummy, platform), 698 698 }, ··· 858 858 .name = "Kbl Audio Echo Reference cap", 859 859 .stream_name = "Echoreference Capture", 860 860 .init = NULL, 861 - .capture_only = 1, 861 + .dpcm_capture = 1, 862 862 .nonatomic = 1, 863 863 SND_SOC_DAILINK_REG(echoref, dummy, platform), 864 864 },
+1 -1
sound/soc/intel/boards/kbl_rt5663_max98927.c
··· 672 672 .name = "Kbl Audio Echo Reference cap", 673 673 .stream_name = "Echoreference Capture", 674 674 .init = NULL, 675 - .capture_only = 1, 675 + .dpcm_capture = 1, 676 676 .nonatomic = 1, 677 677 SND_SOC_DAILINK_REG(echoref, dummy, platform), 678 678 },
+1 -1
sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
··· 566 566 .name = "Kbl Audio Echo Reference cap", 567 567 .stream_name = "Echoreference Capture", 568 568 .init = NULL, 569 - .capture_only = 1, 569 + .dpcm_capture = 1, 570 570 .nonatomic = 1, 571 571 SND_SOC_DAILINK_REG(echoref, dummy, platform), 572 572 },
+8 -2
sound/soc/meson/axg-fifo.c
··· 249 249 /* Enable pclk to access registers and clock the fifo ip */ 250 250 ret = clk_prepare_enable(fifo->pclk); 251 251 if (ret) 252 - return ret; 252 + goto free_irq; 253 253 254 254 /* Setup status2 so it reports the memory pointer */ 255 255 regmap_update_bits(fifo->map, FIFO_CTRL1, ··· 269 269 /* Take memory arbitror out of reset */ 270 270 ret = reset_control_deassert(fifo->arb); 271 271 if (ret) 272 - clk_disable_unprepare(fifo->pclk); 272 + goto free_clk; 273 273 274 + return 0; 275 + 276 + free_clk: 277 + clk_disable_unprepare(fifo->pclk); 278 + free_irq: 279 + free_irq(fifo->irq, ss); 274 280 return ret; 275 281 } 276 282 EXPORT_SYMBOL_GPL(axg_fifo_pcm_open);
+12 -5
sound/soc/meson/meson-card-utils.c
··· 49 49 links = krealloc(priv->card.dai_link, 50 50 num_links * sizeof(*priv->card.dai_link), 51 51 GFP_KERNEL | __GFP_ZERO); 52 + if (!links) 53 + goto err_links; 54 + 52 55 ldata = krealloc(priv->link_data, 53 56 num_links * sizeof(*priv->link_data), 54 57 GFP_KERNEL | __GFP_ZERO); 55 - 56 - if (!links || !ldata) { 57 - dev_err(priv->card.dev, "failed to allocate links\n"); 58 - return -ENOMEM; 59 - } 58 + if (!ldata) 59 + goto err_ldata; 60 60 61 61 priv->card.dai_link = links; 62 62 priv->link_data = ldata; 63 63 priv->card.num_links = num_links; 64 64 return 0; 65 + 66 + err_ldata: 67 + kfree(links); 68 + err_links: 69 + dev_err(priv->card.dev, "failed to allocate links\n"); 70 + return -ENOMEM; 71 + 65 72 } 66 73 EXPORT_SYMBOL_GPL(meson_card_reallocate_links); 67 74
+19 -3
sound/soc/soc-core.c
··· 1648 1648 dai_link->platforms->name = component->name; 1649 1649 1650 1650 /* convert non BE into BE */ 1651 - dai_link->no_pcm = 1; 1652 - dai_link->dpcm_playback = 1; 1653 - dai_link->dpcm_capture = 1; 1651 + if (!dai_link->no_pcm) { 1652 + dai_link->no_pcm = 1; 1653 + 1654 + if (dai_link->dpcm_playback) 1655 + dev_warn(card->dev, 1656 + "invalid configuration, dailink %s has flags no_pcm=0 and dpcm_playback=1\n", 1657 + dai_link->name); 1658 + if (dai_link->dpcm_capture) 1659 + dev_warn(card->dev, 1660 + "invalid configuration, dailink %s has flags no_pcm=0 and dpcm_capture=1\n", 1661 + dai_link->name); 1662 + 1663 + /* convert normal link into DPCM one */ 1664 + if (!(dai_link->dpcm_playback || 1665 + dai_link->dpcm_capture)) { 1666 + dai_link->dpcm_playback = !dai_link->capture_only; 1667 + dai_link->dpcm_capture = !dai_link->playback_only; 1668 + } 1669 + } 1654 1670 1655 1671 /* 1656 1672 * override any BE fixups
+35 -11
sound/soc/soc-pcm.c
··· 2789 2789 struct snd_pcm *pcm; 2790 2790 char new_name[64]; 2791 2791 int ret = 0, playback = 0, capture = 0; 2792 + int stream; 2792 2793 int i; 2793 2794 2794 - if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) { 2795 - cpu_dai = asoc_rtd_to_cpu(rtd, 0); 2796 - if (rtd->num_cpus > 1) { 2797 - dev_err(rtd->dev, 2798 - "DPCM doesn't support Multi CPU yet\n"); 2799 - return -EINVAL; 2800 - } 2795 + if (rtd->dai_link->dynamic && rtd->num_cpus > 1) { 2796 + dev_err(rtd->dev, 2797 + "DPCM doesn't support Multi CPU for Front-Ends yet\n"); 2798 + return -EINVAL; 2799 + } 2801 2800 2802 - playback = rtd->dai_link->dpcm_playback && 2803 - snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK); 2804 - capture = rtd->dai_link->dpcm_capture && 2805 - snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE); 2801 + if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) { 2802 + if (rtd->dai_link->dpcm_playback) { 2803 + stream = SNDRV_PCM_STREAM_PLAYBACK; 2804 + 2805 + for_each_rtd_cpu_dais(rtd, i, cpu_dai) 2806 + if (!snd_soc_dai_stream_valid(cpu_dai, 2807 + stream)) { 2808 + dev_err(rtd->card->dev, 2809 + "CPU DAI %s for rtd %s does not support playback\n", 2810 + cpu_dai->name, 2811 + rtd->dai_link->stream_name); 2812 + return -EINVAL; 2813 + } 2814 + playback = 1; 2815 + } 2816 + if (rtd->dai_link->dpcm_capture) { 2817 + stream = SNDRV_PCM_STREAM_CAPTURE; 2818 + 2819 + for_each_rtd_cpu_dais(rtd, i, cpu_dai) 2820 + if (!snd_soc_dai_stream_valid(cpu_dai, 2821 + stream)) { 2822 + dev_err(rtd->card->dev, 2823 + "CPU DAI %s for rtd %s does not support capture\n", 2824 + cpu_dai->name, 2825 + rtd->dai_link->stream_name); 2826 + return -EINVAL; 2827 + } 2828 + capture = 1; 2829 + } 2806 2830 } else { 2807 2831 /* Adapt stream for codec2codec links */ 2808 2832 int cpu_capture = rtd->dai_link->params ?
+4 -2
sound/soc/sof/nocodec.c
··· 52 52 links[i].platforms->name = dev_name(dev); 53 53 links[i].codecs->dai_name = "snd-soc-dummy-dai"; 54 54 links[i].codecs->name = "snd-soc-dummy"; 55 - links[i].dpcm_playback = 1; 56 - links[i].dpcm_capture = 1; 55 + if (ops->drv[i].playback.channels_min) 56 + links[i].dpcm_playback = 1; 57 + if (ops->drv[i].capture.channels_min) 58 + links[i].dpcm_capture = 1; 57 59 } 58 60 59 61 card->dai_link = links;
+42 -12
sound/usb/card.c
··· 634 634 id, &chip); 635 635 if (err < 0) 636 636 goto __error; 637 - chip->pm_intf = intf; 638 637 break; 639 638 } else if (vid[i] != -1 || pid[i] != -1) { 640 639 dev_info(&dev->dev, ··· 650 651 goto __error; 651 652 } 652 653 } 654 + 655 + if (chip->num_interfaces >= MAX_CARD_INTERFACES) { 656 + dev_info(&dev->dev, "Too many interfaces assigned to the single USB-audio card\n"); 657 + err = -EINVAL; 658 + goto __error; 659 + } 660 + 653 661 dev_set_drvdata(&dev->dev, chip); 654 662 655 663 /* ··· 709 703 } 710 704 711 705 usb_chip[chip->index] = chip; 706 + chip->intf[chip->num_interfaces] = intf; 712 707 chip->num_interfaces++; 713 708 usb_set_intfdata(intf, chip); 714 709 atomic_dec(&chip->active); ··· 825 818 826 819 int snd_usb_autoresume(struct snd_usb_audio *chip) 827 820 { 821 + int i, err; 822 + 828 823 if (atomic_read(&chip->shutdown)) 829 824 return -EIO; 830 - if (atomic_inc_return(&chip->active) == 1) 831 - return usb_autopm_get_interface(chip->pm_intf); 825 + if (atomic_inc_return(&chip->active) != 1) 826 + return 0; 827 + 828 + for (i = 0; i < chip->num_interfaces; i++) { 829 + err = usb_autopm_get_interface(chip->intf[i]); 830 + if (err < 0) { 831 + /* rollback */ 832 + while (--i >= 0) 833 + usb_autopm_put_interface(chip->intf[i]); 834 + atomic_dec(&chip->active); 835 + return err; 836 + } 837 + } 832 838 return 0; 833 839 } 834 840 835 841 void snd_usb_autosuspend(struct snd_usb_audio *chip) 836 842 { 843 + int i; 844 + 837 845 if (atomic_read(&chip->shutdown)) 838 846 return; 839 - if (atomic_dec_and_test(&chip->active)) 840 - usb_autopm_put_interface(chip->pm_intf); 847 + if (!atomic_dec_and_test(&chip->active)) 848 + return; 849 + 850 + for (i = 0; i < chip->num_interfaces; i++) 851 + usb_autopm_put_interface(chip->intf[i]); 841 852 } 842 853 843 854 static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) ··· 868 843 if (chip == (void *)-1L) 869 844 return 0; 870 845 871 - chip->autosuspended = !!PMSG_IS_AUTO(message); 872 - if (!chip->autosuspended) 873 - snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot); 874 846 if (!chip->num_suspended_intf++) { 875 847 list_for_each_entry(as, &chip->pcm_list, list) { 876 848 snd_usb_pcm_suspend(as); ··· 878 856 snd_usbmidi_suspend(p); 879 857 list_for_each_entry(mixer, &chip->mixer_list, list) 880 858 snd_usb_mixer_suspend(mixer); 859 + } 860 + 861 + if (!PMSG_IS_AUTO(message) && !chip->system_suspend) { 862 + snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot); 863 + chip->system_suspend = chip->num_suspended_intf; 881 864 } 882 865 883 866 return 0; ··· 898 871 899 872 if (chip == (void *)-1L) 900 873 return 0; 901 - if (--chip->num_suspended_intf) 902 - return 0; 903 874 904 875 atomic_inc(&chip->active); /* avoid autopm */ 876 + if (chip->num_suspended_intf > 1) 877 + goto out; 905 878 906 879 list_for_each_entry(as, &chip->pcm_list, list) { 907 880 err = snd_usb_pcm_resume(as); ··· 923 896 snd_usbmidi_resume(p); 924 897 } 925 898 926 - if (!chip->autosuspended) 899 + out: 900 + if (chip->num_suspended_intf == chip->system_suspend) { 927 901 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0); 928 - chip->autosuspended = 0; 902 + chip->system_suspend = 0; 903 + } 904 + chip->num_suspended_intf--; 929 905 930 906 err_out: 931 907 atomic_dec(&chip->active); /* allow autopm after this point */
+12
sound/usb/quirks-table.h
··· 40 40 .ifnum = QUIRK_NO_INTERFACE \ 41 41 } 42 42 43 + /* HP Thunderbolt Dock Audio Headset */ 44 + { 45 + USB_DEVICE(0x03f0, 0x0269), 46 + QUIRK_DEVICE_PROFILE("HP", "Thunderbolt Dock Audio Headset", 47 + "HP-Thunderbolt-Dock-Audio-Headset"), 48 + }, 49 + /* HP Thunderbolt Dock Audio Module */ 50 + { 51 + USB_DEVICE(0x03f0, 0x0567), 52 + QUIRK_DEVICE_PROFILE("HP", "Thunderbolt Dock Audio Module", 53 + "HP-Thunderbolt-Dock-Audio-Module"), 54 + }, 43 55 /* FTDI devices */ 44 56 { 45 57 USB_DEVICE(0x0403, 0xb8d8),
+4 -2
sound/usb/usbaudio.h
··· 19 19 struct media_device; 20 20 struct media_intf_devnode; 21 21 22 + #define MAX_CARD_INTERFACES 16 23 + 22 24 struct snd_usb_audio { 23 25 int index; 24 26 struct usb_device *dev; 25 27 struct snd_card *card; 26 - struct usb_interface *pm_intf; 28 + struct usb_interface *intf[MAX_CARD_INTERFACES]; 27 29 u32 usb_id; 28 30 struct mutex mutex; 29 - unsigned int autosuspended:1; 31 + unsigned int system_suspend; 30 32 atomic_t active; 31 33 atomic_t shutdown; 32 34 atomic_t usage_count;