summaryrefslogtreecommitdiffstats
path: root/sound/x86/intel_hdmi_audio.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2018-02-28 08:46:00 +0100
committerTakashi Iwai <tiwai@suse.de>2018-02-28 08:46:00 +0100
commitc77a6edb6d4d35204673cad7389c317bfb17492e (patch)
tree81f571d7a1c951c58014d3981cc8250c911a256c /sound/x86/intel_hdmi_audio.c
parentALSA: x86: Fix missing spinlock and mutex initializations (diff)
downloadlinux-c77a6edb6d4d35204673cad7389c317bfb17492e.tar.xz
linux-c77a6edb6d4d35204673cad7389c317bfb17492e.zip
ALSA: x86: Fix potential crash at error path
When LPE audio driver gets some error at probing, it may lead to a crash because of canceling the pending work in hdmi_lpe_audio_free(), since some of ports might be still not initialized. For assuring the proper free of each port, initialize all ports at the beginning of the probe. Fixes: b4eb0d522fcb ("ALSA: x86: Split snd_intelhad into card and PCM specific structures") Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/x86/intel_hdmi_audio.c')
-rw-r--r--sound/x86/intel_hdmi_audio.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c
index cec62f9b7085..4ed9d0c41843 100644
--- a/sound/x86/intel_hdmi_audio.c
+++ b/sound/x86/intel_hdmi_audio.c
@@ -1751,6 +1751,7 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev)
{
struct snd_card *card;
struct snd_intelhad_card *card_ctx;
+ struct snd_intelhad *ctx;
struct snd_pcm *pcm;
struct intel_hdmi_lpe_audio_pdata *pdata;
int irq;
@@ -1795,6 +1796,21 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, card_ctx);
+ card_ctx->num_pipes = pdata->num_pipes;
+ card_ctx->num_ports = single_port ? 1 : pdata->num_ports;
+
+ for_each_port(card_ctx, port) {
+ ctx = &card_ctx->pcm_ctx[port];
+ ctx->card_ctx = card_ctx;
+ ctx->dev = card_ctx->dev;
+ ctx->port = single_port ? -1 : port;
+ ctx->pipe = -1;
+
+ spin_lock_init(&ctx->had_spinlock);
+ mutex_init(&ctx->mutex);
+ INIT_WORK(&ctx->hdmi_audio_wq, had_audio_wq);
+ }
+
dev_dbg(&pdev->dev, "%s: mmio_start = 0x%x, mmio_end = 0x%x\n",
__func__, (unsigned int)res_mmio->start,
(unsigned int)res_mmio->end);
@@ -1827,18 +1843,9 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev)
card_ctx->num_ports = single_port ? 1 : pdata->num_ports;
for_each_port(card_ctx, port) {
- struct snd_intelhad *ctx = &card_ctx->pcm_ctx[port];
int i;
- ctx->card_ctx = card_ctx;
- ctx->dev = card_ctx->dev;
- ctx->port = single_port ? -1 : port;
- ctx->pipe = -1;
-
- spin_lock_init(&ctx->had_spinlock);
- mutex_init(&ctx->mutex);
- INIT_WORK(&ctx->hdmi_audio_wq, had_audio_wq);
-
+ ctx = &card_ctx->pcm_ctx[port];
ret = snd_pcm_new(card, INTEL_HAD, port, MAX_PB_STREAMS,
MAX_CAP_STREAMS, &pcm);
if (ret)