Skip to content

Commit 56cf10d

Browse files
committed
Merge tag 'sound-7.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
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
2 parents 7354850 + 9250673 commit 56cf10d

15 files changed

Lines changed: 102 additions & 23 deletions

File tree

drivers/firmware/cirrus/cs_dsp.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1610,11 +1610,17 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware,
16101610
region_name);
16111611

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

16441650
ret = 0;
16451651
out_fw:
1646-
kfree(buf);
1652+
vfree(buf);
16471653

16481654
if (ret == -EOVERFLOW)
16491655
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
23312337
}
23322338

23332339
if (reg) {
2340+
/*
2341+
* Although we expect the underlying bus does not require
2342+
* physically-contiguous buffers, we pessimistically use
2343+
* a temporary buffer instead of trusting that the
2344+
* alignment of blk->data is ok.
2345+
*/
23342346
region_len = le32_to_cpu(blk->len);
23352347
if (region_len > buf_len) {
23362348
buf_len = round_up(region_len, PAGE_SIZE);
2337-
kfree(buf);
2338-
buf = kmalloc(buf_len, GFP_KERNEL | GFP_DMA);
2349+
vfree(buf);
2350+
buf = vmalloc(buf_len);
23392351
if (!buf) {
23402352
ret = -ENOMEM;
23412353
goto out_fw;
@@ -2366,7 +2378,7 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware
23662378

23672379
ret = 0;
23682380
out_fw:
2369-
kfree(buf);
2381+
vfree(buf);
23702382

23712383
if (ret == -EOVERFLOW)
23722384
cs_dsp_err(dsp, "%s: file content overflows file data\n", file);

sound/core/pcm_native.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2144,6 +2144,10 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
21442144
for (;;) {
21452145
long tout;
21462146
struct snd_pcm_runtime *to_check;
2147+
unsigned int drain_rate;
2148+
snd_pcm_uframes_t drain_bufsz;
2149+
bool drain_no_period_wakeup;
2150+
21472151
if (signal_pending(current)) {
21482152
result = -ERESTARTSYS;
21492153
break;
@@ -2163,16 +2167,25 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
21632167
snd_pcm_group_unref(group, substream);
21642168
if (!to_check)
21652169
break; /* all drained */
2170+
/*
2171+
* Cache the runtime fields needed after unlock.
2172+
* A concurrent close() on the linked stream may free
2173+
* its runtime via snd_pcm_detach_substream() once we
2174+
* release the stream lock below.
2175+
*/
2176+
drain_no_period_wakeup = to_check->no_period_wakeup;
2177+
drain_rate = to_check->rate;
2178+
drain_bufsz = to_check->buffer_size;
21662179
init_waitqueue_entry(&wait, current);
21672180
set_current_state(TASK_INTERRUPTIBLE);
21682181
add_wait_queue(&to_check->sleep, &wait);
21692182
snd_pcm_stream_unlock_irq(substream);
2170-
if (runtime->no_period_wakeup)
2183+
if (drain_no_period_wakeup)
21712184
tout = MAX_SCHEDULE_TIMEOUT;
21722185
else {
21732186
tout = 100;
2174-
if (runtime->rate) {
2175-
long t = runtime->buffer_size * 1100 / runtime->rate;
2187+
if (drain_rate) {
2188+
long t = drain_bufsz * 1100 / drain_rate;
21762189
tout = max(t, tout);
21772190
}
21782191
tout = msecs_to_jiffies(tout);

sound/hda/codecs/realtek/alc269.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6940,6 +6940,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
69406940
SND_PCI_QUIRK(0x103c, 0x89da, "HP Spectre x360 14t-ea100", ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX),
69416941
SND_PCI_QUIRK(0x103c, 0x89e7, "HP Elite x2 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
69426942
SND_PCI_QUIRK(0x103c, 0x8a0f, "HP Pavilion 14-ec1xxx", ALC287_FIXUP_HP_GPIO_LED),
6943+
SND_PCI_QUIRK(0x103c, 0x8a1f, "HP Laptop 14s-dr5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
69436944
SND_PCI_QUIRK(0x103c, 0x8a20, "HP Laptop 15s-fq5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
69446945
SND_PCI_QUIRK(0x103c, 0x8a25, "HP Victus 16-d1xxx (MB 8A25)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
69456946
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[] = {
72737274
SND_PCI_QUIRK(0x1043, 0x1e93, "ASUS ExpertBook B9403CVAR", ALC294_FIXUP_ASUS_HPE),
72747275
SND_PCI_QUIRK(0x1043, 0x1eb3, "ASUS Ally RCLA72", ALC287_FIXUP_TAS2781_I2C),
72757276
SND_PCI_QUIRK(0x1043, 0x1ed3, "ASUS HN7306W", ALC287_FIXUP_CS35L41_I2C_2),
7277+
HDA_CODEC_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC285_FIXUP_ASUS_I2C_SPEAKER2_TO_DAC1),
72767278
SND_PCI_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC287_FIXUP_CS35L41_I2C_2),
72777279
SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401),
72787280
SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401),
@@ -7493,6 +7495,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
74937495
SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
74947496
SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
74957497
SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
7498+
SND_PCI_QUIRK(0x17aa, 0x2288, "Thinkpad X390", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK),
74967499
SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
74977500
SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
74987501
SND_PCI_QUIRK(0x17aa, 0x22c1, "Thinkpad P1 Gen 3", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK),

sound/hda/codecs/realtek/alc662.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ enum {
313313
ALC897_FIXUP_HEADSET_MIC_PIN2,
314314
ALC897_FIXUP_UNIS_H3C_X500S,
315315
ALC897_FIXUP_HEADSET_MIC_PIN3,
316+
ALC897_FIXUP_H610M_HP_PIN,
316317
};
317318

318319
static const struct hda_fixup alc662_fixups[] = {
@@ -766,6 +767,13 @@ static const struct hda_fixup alc662_fixups[] = {
766767
{ }
767768
},
768769
},
770+
[ALC897_FIXUP_H610M_HP_PIN] = {
771+
.type = HDA_FIXUP_PINS,
772+
.v.pins = (const struct hda_pintbl[]) {
773+
{ 0x19, 0x0321403f }, /* HP out */
774+
{ }
775+
},
776+
},
769777
};
770778

771779
static const struct hda_quirk alc662_fixup_tbl[] = {
@@ -815,6 +823,7 @@ static const struct hda_quirk alc662_fixup_tbl[] = {
815823
SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
816824
SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
817825
SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
826+
SND_PCI_QUIRK(0x1458, 0xa194, "H610M H V2 DDR4", ALC897_FIXUP_H610M_HP_PIN),
818827
SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
819828
SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
820829
SND_PCI_QUIRK(0x17aa, 0x1057, "Lenovo P360", ALC897_FIXUP_HEADSET_MIC_PIN),

sound/soc/amd/acp/acp-mach-common.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,13 @@ static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd)
127127
if (drvdata->hs_codec_id != RT5682)
128128
return -EINVAL;
129129

130-
drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");
131-
drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");
130+
drvdata->wclk = devm_clk_get(component->dev, "rt5682-dai-wclk");
131+
if (IS_ERR(drvdata->wclk))
132+
return PTR_ERR(drvdata->wclk);
133+
134+
drvdata->bclk = devm_clk_get(component->dev, "rt5682-dai-bclk");
135+
if (IS_ERR(drvdata->bclk))
136+
return PTR_ERR(drvdata->bclk);
132137

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

372377
if (!drvdata->soc_mclk) {
373-
drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");
374-
drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");
378+
drvdata->wclk = devm_clk_get(component->dev, "rt5682-dai-wclk");
379+
if (IS_ERR(drvdata->wclk))
380+
return PTR_ERR(drvdata->wclk);
381+
382+
drvdata->bclk = devm_clk_get(component->dev, "rt5682-dai-bclk");
383+
if (IS_ERR(drvdata->bclk))
384+
return PTR_ERR(drvdata->bclk);
375385
}
376386

377387
ret = snd_soc_dapm_new_controls(dapm, rt5682s_widgets,

sound/soc/amd/acp3x-rt5682-max9836.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,13 @@ static int acp3x_5682_init(struct snd_soc_pcm_runtime *rtd)
9494
return ret;
9595
}
9696

97-
rt5682_dai_wclk = clk_get(component->dev, "rt5682-dai-wclk");
98-
rt5682_dai_bclk = clk_get(component->dev, "rt5682-dai-bclk");
97+
rt5682_dai_wclk = devm_clk_get(component->dev, "rt5682-dai-wclk");
98+
if (IS_ERR(rt5682_dai_wclk))
99+
return PTR_ERR(rt5682_dai_wclk);
100+
101+
rt5682_dai_bclk = devm_clk_get(component->dev, "rt5682-dai-bclk");
102+
if (IS_ERR(rt5682_dai_bclk))
103+
return PTR_ERR(rt5682_dai_bclk);
99104

100105
ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
101106
SND_JACK_HEADSET |

sound/soc/codecs/rt1011.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1047,7 +1047,7 @@ static int rt1011_recv_spk_mode_put(struct snd_kcontrol *kcontrol,
10471047
struct snd_ctl_elem_value *ucontrol)
10481048
{
10491049
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
1050-
struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol);
1050+
struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
10511051
struct rt1011_priv *rt1011 =
10521052
snd_soc_component_get_drvdata(component);
10531053

sound/soc/generic/simple-card-utils.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,11 +1038,15 @@ int graph_util_is_ports0(struct device_node *np)
10381038
else
10391039
port = np;
10401040

1041-
struct device_node *ports __free(device_node) = of_get_parent(port);
1042-
struct device_node *top __free(device_node) = of_get_parent(ports);
1043-
struct device_node *ports0 __free(device_node) = of_get_child_by_name(top, "ports");
1041+
struct device_node *ports __free(device_node) = of_get_parent(port);
1042+
const char *at = strchr(kbasename(ports->full_name), '@');
10441043

1045-
return ports0 == ports;
1044+
/*
1045+
* Since child iteration order may differ
1046+
* between a base DT and DT overlays,
1047+
* string match "ports" or "ports@0" in the node name instead.
1048+
*/
1049+
return !at || !strcmp(at, "@0");
10461050
}
10471051
EXPORT_SYMBOL_GPL(graph_util_is_ports0);
10481052

sound/soc/qcom/qdsp6/q6apm-dai.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,7 @@ static const struct snd_soc_component_driver q6apm_fe_dai_component = {
838838
.ack = q6apm_dai_ack,
839839
.compress_ops = &q6apm_dai_compress_ops,
840840
.use_dai_pcm_id = true,
841+
.remove_order = SND_SOC_COMP_ORDER_EARLY,
841842
};
842843

843844
static int q6apm_dai_probe(struct platform_device *pdev)

sound/soc/qcom/qdsp6/q6apm-lpass-dais.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ static const struct snd_soc_component_driver q6apm_lpass_dai_component = {
278278
.of_xlate_dai_name = q6dsp_audio_ports_of_xlate_dai_name,
279279
.be_pcm_base = AUDIOREACH_BE_PCM_BASE,
280280
.use_dai_pcm_id = true,
281+
.remove_order = SND_SOC_COMP_ORDER_FIRST,
281282
};
282283

283284
static int q6apm_lpass_dai_dev_probe(struct platform_device *pdev)

0 commit comments

Comments
 (0)