diff options
author | Takashi Iwai | 2018-02-28 08:46:00 +0100 |
---|---|---|
committer | Takashi Iwai | 2018-02-28 08:46:00 +0100 |
commit | c77a6edb6d4d35204673cad7389c317bfb17492e (patch) | |
tree | 81f571d7a1c951c58014d3981cc8250c911a256c | |
parent | 350144069abf351c743d766b2fba9cb9b7cd32a1 (diff) |
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>
-rw-r--r-- | sound/x86/intel_hdmi_audio.c | 27 |
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) |