Commit 56cf10db authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull sound fixes from Takashi Iwai:
 "There have been continuous flux but most of them are device-specific
  small fixes, while we see a few core fixes at this time (minor PCM fix
  for linked streams and a few ASoC core fixes for delayed work, etc)

  Core:
   - PCM: Fix use-after-free in linked stream drain

  ASoC:
   - core: Fixes for delayed works, empty DMI string handling and DT overlay
   - qcom: qdsp6: Fix ADSP stop/start crash via component removal ordering
   - tegra: Add support for Tegra238 audio graph card
   - amd: Fix missing error checks for clock acquisition
   - rt1011: Fix incorrect DAPM context retrieval helper

  HD-audio:
   - Add quirk for Gigabyte H610M, ASUS UM6702RC, HP 14s-dr5xxx, and
     ThinkPad X390

  USB-audio:
   - Scarlett2: Fix NULL dereference for malformed endpoint descriptors
   - Add quirk for SPACETOUCH"

* tag 'sound-7.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ASoC: amd: acp-mach-common: Add missing error check for clock acquisition
  ASoC: detect empty DMI strings
  ASoC: amd: acp3x-rt5682-max9836: Add missing error check for clock acquisition
  ALSA: usb-audio: Add iface reset and delay quirk for SPACETOUCH USB Audio
  ASoC: codecs: rt1011: Use component to get the dapm context in spk_mode_put
  ALSA: usb-audio: Check endpoint numbers at parsing Scarlett2 mixer interfaces
  ASoC: simple-card-utils: fix graph_util_is_ports0() for DT overlays
  ASoC: soc-core: flush delayed work before removing DAIs and widgets
  ASoC: soc-core: drop delayed_work_pending() check before flush
  ASoC: tegra: Add support for Tegra238 soundcard
  ALSA: hda/realtek: Add headset jack quirk for Thinkpad X390
  ALSA: hda/realtek: add HP Laptop 14s-dr5xxx mute LED quirk
  ALSA: hda/realtek: add quirk for ASUS UM6702RC
  ALSA: pcm: fix use-after-free on linked stream runtime in snd_pcm_drain()
  ALSA: hda/realtek: Add quirk for Gigabyte Technology to fix headphone
  firmware: cs_dsp: Fix fragmentation regression in firmware download
  ASoC: qcom: qdsp6: Fix q6apm remove ordering during ADSP stop and start
parents 73548503 9250673c
Loading
Loading
Loading
Loading
+18 −6
Original line number Diff line number Diff line
@@ -1610,11 +1610,17 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware,
			   region_name);

		if (reg) {
			/*
			 * Although we expect the underlying bus does not require
			 * physically-contiguous buffers, we pessimistically use
			 * a temporary buffer instead of trusting that the
			 * alignment of region->data is ok.
			 */
			region_len = le32_to_cpu(region->len);
			if (region_len > buf_len) {
				buf_len = round_up(region_len, PAGE_SIZE);
				kfree(buf);
				buf = kmalloc(buf_len, GFP_KERNEL | GFP_DMA);
				vfree(buf);
				buf = vmalloc(buf_len);
				if (!buf) {
					ret = -ENOMEM;
					goto out_fw;
@@ -1643,7 +1649,7 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware,

	ret = 0;
out_fw:
	kfree(buf);
	vfree(buf);

	if (ret == -EOVERFLOW)
		cs_dsp_err(dsp, "%s: file content overflows file data\n", file);
@@ -2331,11 +2337,17 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware
		}

		if (reg) {
			/*
			 * Although we expect the underlying bus does not require
			 * physically-contiguous buffers, we pessimistically use
			 * a temporary buffer instead of trusting that the
			 * alignment of blk->data is ok.
			 */
			region_len = le32_to_cpu(blk->len);
			if (region_len > buf_len) {
				buf_len = round_up(region_len, PAGE_SIZE);
				kfree(buf);
				buf = kmalloc(buf_len, GFP_KERNEL | GFP_DMA);
				vfree(buf);
				buf = vmalloc(buf_len);
				if (!buf) {
					ret = -ENOMEM;
					goto out_fw;
@@ -2366,7 +2378,7 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware

	ret = 0;
out_fw:
	kfree(buf);
	vfree(buf);

	if (ret == -EOVERFLOW)
		cs_dsp_err(dsp, "%s: file content overflows file data\n", file);
+16 −3
Original line number Diff line number Diff line
@@ -2144,6 +2144,10 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
	for (;;) {
		long tout;
		struct snd_pcm_runtime *to_check;
		unsigned int drain_rate;
		snd_pcm_uframes_t drain_bufsz;
		bool drain_no_period_wakeup;

		if (signal_pending(current)) {
			result = -ERESTARTSYS;
			break;
@@ -2163,16 +2167,25 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
		snd_pcm_group_unref(group, substream);
		if (!to_check)
			break; /* all drained */
		/*
		 * Cache the runtime fields needed after unlock.
		 * A concurrent close() on the linked stream may free
		 * its runtime via snd_pcm_detach_substream() once we
		 * release the stream lock below.
		 */
		drain_no_period_wakeup = to_check->no_period_wakeup;
		drain_rate = to_check->rate;
		drain_bufsz = to_check->buffer_size;
		init_waitqueue_entry(&wait, current);
		set_current_state(TASK_INTERRUPTIBLE);
		add_wait_queue(&to_check->sleep, &wait);
		snd_pcm_stream_unlock_irq(substream);
		if (runtime->no_period_wakeup)
		if (drain_no_period_wakeup)
			tout = MAX_SCHEDULE_TIMEOUT;
		else {
			tout = 100;
			if (runtime->rate) {
				long t = runtime->buffer_size * 1100 / runtime->rate;
			if (drain_rate) {
				long t = drain_bufsz * 1100 / drain_rate;
				tout = max(t, tout);
			}
			tout = msecs_to_jiffies(tout);
+3 −0
Original line number Diff line number Diff line
@@ -6940,6 +6940,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
	SND_PCI_QUIRK(0x103c, 0x89da, "HP Spectre x360 14t-ea100", ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX),
	SND_PCI_QUIRK(0x103c, 0x89e7, "HP Elite x2 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
	SND_PCI_QUIRK(0x103c, 0x8a0f, "HP Pavilion 14-ec1xxx", ALC287_FIXUP_HP_GPIO_LED),
	SND_PCI_QUIRK(0x103c, 0x8a1f, "HP Laptop 14s-dr5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
	SND_PCI_QUIRK(0x103c, 0x8a20, "HP Laptop 15s-fq5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
	SND_PCI_QUIRK(0x103c, 0x8a25, "HP Victus 16-d1xxx (MB 8A25)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
	SND_PCI_QUIRK(0x103c, 0x8a26, "HP Victus 16-d1xxx (MB 8A26)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
@@ -7273,6 +7274,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
	SND_PCI_QUIRK(0x1043, 0x1e93, "ASUS ExpertBook B9403CVAR", ALC294_FIXUP_ASUS_HPE),
	SND_PCI_QUIRK(0x1043, 0x1eb3, "ASUS Ally RCLA72", ALC287_FIXUP_TAS2781_I2C),
	SND_PCI_QUIRK(0x1043, 0x1ed3, "ASUS HN7306W", ALC287_FIXUP_CS35L41_I2C_2),
	HDA_CODEC_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC285_FIXUP_ASUS_I2C_SPEAKER2_TO_DAC1),
	SND_PCI_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC287_FIXUP_CS35L41_I2C_2),
	SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401),
	SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401),
@@ -7493,6 +7495,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
	SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
	SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
	SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
	SND_PCI_QUIRK(0x17aa, 0x2288, "Thinkpad X390", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK),
	SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
	SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
	SND_PCI_QUIRK(0x17aa, 0x22c1, "Thinkpad P1 Gen 3", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK),
+9 −0
Original line number Diff line number Diff line
@@ -313,6 +313,7 @@ enum {
	ALC897_FIXUP_HEADSET_MIC_PIN2,
	ALC897_FIXUP_UNIS_H3C_X500S,
	ALC897_FIXUP_HEADSET_MIC_PIN3,
	ALC897_FIXUP_H610M_HP_PIN,
};

static const struct hda_fixup alc662_fixups[] = {
@@ -766,6 +767,13 @@ static const struct hda_fixup alc662_fixups[] = {
			{ }
		},
	},
	[ALC897_FIXUP_H610M_HP_PIN] = {
		.type = HDA_FIXUP_PINS,
		.v.pins = (const struct hda_pintbl[]) {
			{ 0x19, 0x0321403f }, /* HP out */
			{ }
		},
	},
};

static const struct hda_quirk alc662_fixup_tbl[] = {
@@ -815,6 +823,7 @@ static const struct hda_quirk alc662_fixup_tbl[] = {
	SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
	SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
	SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
	SND_PCI_QUIRK(0x1458, 0xa194, "H610M H V2 DDR4", ALC897_FIXUP_H610M_HP_PIN),
	SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
	SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
	SND_PCI_QUIRK(0x17aa, 0x1057, "Lenovo P360", ALC897_FIXUP_HEADSET_MIC_PIN),
+14 −4
Original line number Diff line number Diff line
@@ -127,8 +127,13 @@ static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd)
	if (drvdata->hs_codec_id != RT5682)
		return -EINVAL;

	drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");
	drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");
	drvdata->wclk = devm_clk_get(component->dev, "rt5682-dai-wclk");
	if (IS_ERR(drvdata->wclk))
		return PTR_ERR(drvdata->wclk);

	drvdata->bclk = devm_clk_get(component->dev, "rt5682-dai-bclk");
	if (IS_ERR(drvdata->bclk))
		return PTR_ERR(drvdata->bclk);

	ret = snd_soc_dapm_new_controls(dapm, rt5682_widgets,
					ARRAY_SIZE(rt5682_widgets));
@@ -370,8 +375,13 @@ static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd)
		return -EINVAL;

	if (!drvdata->soc_mclk) {
		drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");
		drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");
		drvdata->wclk = devm_clk_get(component->dev, "rt5682-dai-wclk");
		if (IS_ERR(drvdata->wclk))
			return PTR_ERR(drvdata->wclk);

		drvdata->bclk = devm_clk_get(component->dev, "rt5682-dai-bclk");
		if (IS_ERR(drvdata->bclk))
			return PTR_ERR(drvdata->bclk);
	}

	ret = snd_soc_dapm_new_controls(dapm, rt5682s_widgets,
Loading