Skip to content

Commit b1d198c

Browse files
committed
Merge tag 'sound-5.5-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai: "A few piled ASoC fixes and usual HD-audio and USB-audio fixups. Some of them are for ASoC core error-handling" * tag 'sound-5.5-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: hda: enable regmap internal locking ALSA: hda/realtek - Add quirk for the bass speaker on Lenovo Yoga X1 7th gen ALSA: hda/realtek - Set EAPD control to default for ALC222 ALSA: usb-audio: Apply the sample rate quirk for Bose Companion 5 ALSA: hda/realtek - Add new codec supported for ALCS1200A ASoC: Intel: boards: Fix compile-testing RT1011/RT5682 ASoC: SOF: imx8: Fix dsp_box offset ASoC: topology: Prevent use-after-free in snd_soc_get_pcm_runtime() ASoC: fsl_audmix: add missed pm_runtime_disable ASoC: stm32: spdifrx: fix input pin state management ASoC: stm32: spdifrx: fix race condition in irq handler ASoC: stm32: spdifrx: fix inconsistent lock state ASoC: core: Fix access to uninitialized list heads ASoC: soc-core: Set dpcm_playback / dpcm_capture ASoC: SOF: imx8: fix memory allocation failure check on priv->pd_dev ASoC: SOF: Intel: hda: hda-dai: fix oops on hda_link .hw_free ASoC: SOF: fix fault at driver unload after failed probe
2 parents 658e1af + 8e85def commit b1d198c

File tree

11 files changed

+67
-29
lines changed

11 files changed

+67
-29
lines changed

sound/hda/hdac_regmap.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,6 @@ static const struct regmap_config hda_regmap_cfg = {
363363
.reg_write = hda_reg_write,
364364
.use_single_read = true,
365365
.use_single_write = true,
366-
.disable_locking = true,
367366
};
368367

369368
/**

sound/pci/hda/patch_realtek.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
412412
case 0x10ec0672:
413413
alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
414414
break;
415+
case 0x10ec0222:
415416
case 0x10ec0623:
416417
alc_update_coef_idx(codec, 0x19, 1<<13, 0);
417418
break;
@@ -430,6 +431,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
430431
break;
431432
case 0x10ec0899:
432433
case 0x10ec0900:
434+
case 0x10ec0b00:
433435
case 0x10ec1168:
434436
case 0x10ec1220:
435437
alc_update_coef_idx(codec, 0x7, 1<<1, 0);
@@ -2526,6 +2528,7 @@ static int patch_alc882(struct hda_codec *codec)
25262528
case 0x10ec0882:
25272529
case 0x10ec0885:
25282530
case 0x10ec0900:
2531+
case 0x10ec0b00:
25292532
case 0x10ec1220:
25302533
break;
25312534
default:
@@ -7257,6 +7260,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
72577260
SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
72587261
SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
72597262
SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
7263+
SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Yoga 7th", ALC285_FIXUP_SPEAKER2_TO_DAC1),
72607264
SND_PCI_QUIRK(0x17aa, 0x2293, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_SPEAKER2_TO_DAC1),
72617265
SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
72627266
SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
@@ -9255,6 +9259,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
92559259
HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
92569260
HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
92579261
HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
9262+
HDA_CODEC_ENTRY(0x10ec0b00, "ALCS1200A", patch_alc882),
92589263
HDA_CODEC_ENTRY(0x10ec1168, "ALC1220", patch_alc882),
92599264
HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882),
92609265
{} /* terminator */

sound/soc/fsl/fsl_audmix.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,22 +505,29 @@ static int fsl_audmix_probe(struct platform_device *pdev)
505505
ARRAY_SIZE(fsl_audmix_dai));
506506
if (ret) {
507507
dev_err(dev, "failed to register ASoC DAI\n");
508-
return ret;
508+
goto err_disable_pm;
509509
}
510510

511511
priv->pdev = platform_device_register_data(dev, mdrv, 0, NULL, 0);
512512
if (IS_ERR(priv->pdev)) {
513513
ret = PTR_ERR(priv->pdev);
514514
dev_err(dev, "failed to register platform %s: %d\n", mdrv, ret);
515+
goto err_disable_pm;
515516
}
516517

518+
return 0;
519+
520+
err_disable_pm:
521+
pm_runtime_disable(dev);
517522
return ret;
518523
}
519524

520525
static int fsl_audmix_remove(struct platform_device *pdev)
521526
{
522527
struct fsl_audmix *priv = dev_get_drvdata(&pdev->dev);
523528

529+
pm_runtime_disable(&pdev->dev);
530+
524531
if (priv->pdev)
525532
platform_device_unregister(priv->pdev);
526533

sound/soc/intel/boards/cml_rt1011_rt5682.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#include <linux/clk.h>
1212
#include <linux/dmi.h>
1313
#include <linux/slab.h>
14-
#include <asm/cpu_device_id.h>
1514
#include <linux/acpi.h>
1615
#include <sound/core.h>
1716
#include <sound/jack.h>

sound/soc/soc-core.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,12 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
479479
goto free_rtd;
480480

481481
rtd->dev = dev;
482+
INIT_LIST_HEAD(&rtd->list);
483+
INIT_LIST_HEAD(&rtd->component_list);
484+
INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients);
485+
INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].be_clients);
486+
INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].fe_clients);
487+
INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].fe_clients);
482488
dev_set_drvdata(dev, rtd);
483489
INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
484490

@@ -494,12 +500,6 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
494500
/*
495501
* rtd remaining settings
496502
*/
497-
INIT_LIST_HEAD(&rtd->component_list);
498-
INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients);
499-
INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].be_clients);
500-
INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].fe_clients);
501-
INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].fe_clients);
502-
503503
rtd->card = card;
504504
rtd->dai_link = dai_link;
505505
if (!rtd->dai_link->ops)
@@ -1871,6 +1871,8 @@ static void soc_check_tplg_fes(struct snd_soc_card *card)
18711871

18721872
/* convert non BE into BE */
18731873
dai_link->no_pcm = 1;
1874+
dai_link->dpcm_playback = 1;
1875+
dai_link->dpcm_capture = 1;
18741876

18751877
/* override any BE fixups */
18761878
dai_link->be_hw_params_fixup =

sound/soc/soc-topology.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -548,12 +548,12 @@ static void remove_link(struct snd_soc_component *comp,
548548
if (dobj->ops && dobj->ops->link_unload)
549549
dobj->ops->link_unload(comp, dobj);
550550

551+
list_del(&dobj->list);
552+
snd_soc_remove_dai_link(comp->card, link);
553+
551554
kfree(link->name);
552555
kfree(link->stream_name);
553556
kfree(link->cpus->dai_name);
554-
555-
list_del(&dobj->list);
556-
snd_soc_remove_dai_link(comp->card, link);
557557
kfree(link);
558558
}
559559

sound/soc/sof/imx/imx8.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ static int imx8_probe(struct snd_sof_dev *sdev)
209209

210210
priv->pd_dev = devm_kmalloc_array(&pdev->dev, priv->num_domains,
211211
sizeof(*priv->pd_dev), GFP_KERNEL);
212-
if (!priv)
212+
if (!priv->pd_dev)
213213
return -ENOMEM;
214214

215215
priv->link = devm_kmalloc_array(&pdev->dev, priv->num_domains,
@@ -304,6 +304,9 @@ static int imx8_probe(struct snd_sof_dev *sdev)
304304
}
305305
sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM;
306306

307+
/* set default mailbox offset for FW ready message */
308+
sdev->dsp_box.offset = MBOX_OFFSET;
309+
307310
return 0;
308311

309312
exit_pdev_unregister:

sound/soc/sof/intel/hda-dai.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream,
216216
link_dev = hda_link_stream_assign(bus, substream);
217217
if (!link_dev)
218218
return -EBUSY;
219+
220+
snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);
219221
}
220222

221223
stream_tag = hdac_stream(link_dev)->stream_tag;
@@ -228,8 +230,6 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream,
228230
if (ret < 0)
229231
return ret;
230232

231-
snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);
232-
233233
link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name);
234234
if (!link)
235235
return -EINVAL;
@@ -361,6 +361,13 @@ static int hda_link_hw_free(struct snd_pcm_substream *substream,
361361
bus = hstream->bus;
362362
rtd = snd_pcm_substream_chip(substream);
363363
link_dev = snd_soc_dai_get_dma_data(dai, substream);
364+
365+
if (!link_dev) {
366+
dev_dbg(dai->dev,
367+
"%s: link_dev is not assigned\n", __func__);
368+
return -EINVAL;
369+
}
370+
364371
hda_stream = hstream_to_sof_hda_stream(link_dev);
365372

366373
/* free the link DMA channel in the FW */

sound/soc/sof/ipc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,9 @@ void snd_sof_ipc_free(struct snd_sof_dev *sdev)
826826
{
827827
struct snd_sof_ipc *ipc = sdev->ipc;
828828

829+
if (!ipc)
830+
return;
831+
829832
/* disable sending of ipc's */
830833
mutex_lock(&ipc->tx_mutex);
831834
ipc->disable_ipc_tx = true;

sound/soc/stm/stm32_spdifrx.c

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
#include <linux/delay.h>
1313
#include <linux/module.h>
1414
#include <linux/of_platform.h>
15-
#include <linux/pinctrl/consumer.h>
1615
#include <linux/regmap.h>
1716
#include <linux/reset.h>
1817

@@ -220,6 +219,7 @@
220219
* @slave_config: dma slave channel runtime config pointer
221220
* @phys_addr: SPDIFRX registers physical base address
222221
* @lock: synchronization enabling lock
222+
* @irq_lock: prevent race condition with IRQ on stream state
223223
* @cs: channel status buffer
224224
* @ub: user data buffer
225225
* @irq: SPDIFRX interrupt line
@@ -240,6 +240,7 @@ struct stm32_spdifrx_data {
240240
struct dma_slave_config slave_config;
241241
dma_addr_t phys_addr;
242242
spinlock_t lock; /* Sync enabling lock */
243+
spinlock_t irq_lock; /* Prevent race condition on stream state */
243244
unsigned char cs[SPDIFRX_CS_BYTES_NB];
244245
unsigned char ub[SPDIFRX_UB_BYTES_NB];
245246
int irq;
@@ -320,14 +321,15 @@ static void stm32_spdifrx_dma_ctrl_stop(struct stm32_spdifrx_data *spdifrx)
320321
static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx)
321322
{
322323
int cr, cr_mask, imr, ret;
324+
unsigned long flags;
323325

324326
/* Enable IRQs */
325327
imr = SPDIFRX_IMR_IFEIE | SPDIFRX_IMR_SYNCDIE | SPDIFRX_IMR_PERRIE;
326328
ret = regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_IMR, imr, imr);
327329
if (ret)
328330
return ret;
329331

330-
spin_lock(&spdifrx->lock);
332+
spin_lock_irqsave(&spdifrx->lock, flags);
331333

332334
spdifrx->refcount++;
333335

@@ -362,19 +364,20 @@ static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx)
362364
"Failed to start synchronization\n");
363365
}
364366

365-
spin_unlock(&spdifrx->lock);
367+
spin_unlock_irqrestore(&spdifrx->lock, flags);
366368

367369
return ret;
368370
}
369371

370372
static void stm32_spdifrx_stop(struct stm32_spdifrx_data *spdifrx)
371373
{
372374
int cr, cr_mask, reg;
375+
unsigned long flags;
373376

374-
spin_lock(&spdifrx->lock);
377+
spin_lock_irqsave(&spdifrx->lock, flags);
375378

376379
if (--spdifrx->refcount) {
377-
spin_unlock(&spdifrx->lock);
380+
spin_unlock_irqrestore(&spdifrx->lock, flags);
378381
return;
379382
}
380383

@@ -393,7 +396,7 @@ static void stm32_spdifrx_stop(struct stm32_spdifrx_data *spdifrx)
393396
regmap_read(spdifrx->regmap, STM32_SPDIFRX_DR, &reg);
394397
regmap_read(spdifrx->regmap, STM32_SPDIFRX_CSR, &reg);
395398

396-
spin_unlock(&spdifrx->lock);
399+
spin_unlock_irqrestore(&spdifrx->lock, flags);
397400
}
398401

399402
static int stm32_spdifrx_dma_ctrl_register(struct device *dev,
@@ -480,8 +483,6 @@ static int stm32_spdifrx_get_ctrl_data(struct stm32_spdifrx_data *spdifrx)
480483
memset(spdifrx->cs, 0, SPDIFRX_CS_BYTES_NB);
481484
memset(spdifrx->ub, 0, SPDIFRX_UB_BYTES_NB);
482485

483-
pinctrl_pm_select_default_state(&spdifrx->pdev->dev);
484-
485486
ret = stm32_spdifrx_dma_ctrl_start(spdifrx);
486487
if (ret < 0)
487488
return ret;
@@ -513,7 +514,6 @@ static int stm32_spdifrx_get_ctrl_data(struct stm32_spdifrx_data *spdifrx)
513514

514515
end:
515516
clk_disable_unprepare(spdifrx->kclk);
516-
pinctrl_pm_select_sleep_state(&spdifrx->pdev->dev);
517517

518518
return ret;
519519
}
@@ -665,7 +665,6 @@ static const struct regmap_config stm32_h7_spdifrx_regmap_conf = {
665665
static irqreturn_t stm32_spdifrx_isr(int irq, void *devid)
666666
{
667667
struct stm32_spdifrx_data *spdifrx = (struct stm32_spdifrx_data *)devid;
668-
struct snd_pcm_substream *substream = spdifrx->substream;
669668
struct platform_device *pdev = spdifrx->pdev;
670669
unsigned int cr, mask, sr, imr;
671670
unsigned int flags, sync_state;
@@ -745,14 +744,19 @@ static irqreturn_t stm32_spdifrx_isr(int irq, void *devid)
745744
return IRQ_HANDLED;
746745
}
747746

748-
if (substream)
749-
snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
747+
spin_lock(&spdifrx->irq_lock);
748+
if (spdifrx->substream)
749+
snd_pcm_stop(spdifrx->substream,
750+
SNDRV_PCM_STATE_DISCONNECTED);
751+
spin_unlock(&spdifrx->irq_lock);
750752

751753
return IRQ_HANDLED;
752754
}
753755

754-
if (err_xrun && substream)
755-
snd_pcm_stop_xrun(substream);
756+
spin_lock(&spdifrx->irq_lock);
757+
if (err_xrun && spdifrx->substream)
758+
snd_pcm_stop_xrun(spdifrx->substream);
759+
spin_unlock(&spdifrx->irq_lock);
756760

757761
return IRQ_HANDLED;
758762
}
@@ -761,9 +765,12 @@ static int stm32_spdifrx_startup(struct snd_pcm_substream *substream,
761765
struct snd_soc_dai *cpu_dai)
762766
{
763767
struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai);
768+
unsigned long flags;
764769
int ret;
765770

771+
spin_lock_irqsave(&spdifrx->irq_lock, flags);
766772
spdifrx->substream = substream;
773+
spin_unlock_irqrestore(&spdifrx->irq_lock, flags);
767774

768775
ret = clk_prepare_enable(spdifrx->kclk);
769776
if (ret)
@@ -839,8 +846,12 @@ static void stm32_spdifrx_shutdown(struct snd_pcm_substream *substream,
839846
struct snd_soc_dai *cpu_dai)
840847
{
841848
struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai);
849+
unsigned long flags;
842850

851+
spin_lock_irqsave(&spdifrx->irq_lock, flags);
843852
spdifrx->substream = NULL;
853+
spin_unlock_irqrestore(&spdifrx->irq_lock, flags);
854+
844855
clk_disable_unprepare(spdifrx->kclk);
845856
}
846857

@@ -944,6 +955,7 @@ static int stm32_spdifrx_probe(struct platform_device *pdev)
944955
spdifrx->pdev = pdev;
945956
init_completion(&spdifrx->cs_completion);
946957
spin_lock_init(&spdifrx->lock);
958+
spin_lock_init(&spdifrx->irq_lock);
947959

948960
platform_set_drvdata(pdev, spdifrx);
949961

0 commit comments

Comments
 (0)