diff options
author | Alan Tull <r80115@freescale.com> | 2012-02-17 15:15:35 -0600 |
---|---|---|
committer | Alan Tull <r80115@freescale.com> | 2012-02-17 15:46:45 -0600 |
commit | 5194bea9ddd70f8575da4c097fb7d5e8538c4ad1 (patch) | |
tree | 2e779a39f7087737b01e82bed9ba338657d3b151 /sound | |
parent | 6b063b2e6f2b5a258f2b3bcc92f81810af77a825 (diff) |
ENGR00174809 hdmi audio oops in hdmi_dma_mmap_copy
Runtime dma_area may be invalid after trigger stop command.
This will cause an oops in hdmi_dma_mmap_copy. To fix this,
disable mmap copying with trigger stop command and also check
the runtime->dma_area before doing hdmi_dma_mmap_copy.
Signed-off-by: Alan Tull <r80115@freescale.com>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/imx/imx-hdmi-dma.c | 11 |
1 files changed, 3 insertions, 8 deletions
diff --git a/sound/soc/imx/imx-hdmi-dma.c b/sound/soc/imx/imx-hdmi-dma.c index d0c4d52e9c56..eae530da490b 100644 --- a/sound/soc/imx/imx-hdmi-dma.c +++ b/sound/soc/imx/imx-hdmi-dma.c @@ -310,16 +310,11 @@ static irqreturn_t hdmi_dma_isr(int irq, void *dev_id) spin_lock_irqsave(&rtd->irq_lock, flags); - if (!rtd->tx_active) { - spin_unlock_irqrestore(&rtd->irq_lock, flags); - return IRQ_HANDLED; - } - hdmi_dma_irq_mute(1); status = hdmi_dma_get_irq_status(); hdmi_dma_clear_irq_status(status); - if (status & HDMI_IH_AHBDMAAUD_STAT0_DONE) { + if (runtime->dma_area && rtd->tx_active && (status & HDMI_IH_AHBDMAAUD_STAT0_DONE)) { rtd->offset += rtd->period_bytes; rtd->offset %= rtd->period_bytes * rtd->periods; @@ -605,12 +600,14 @@ static int hdmi_dma_trigger(struct snd_pcm_substream *substream, int cmd) } dumpregs(); hdmi_dma_irq_mask(0); + hdmi_dma_priv->tx_active = true; hdmi_dma_start(); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + hdmi_dma_priv->tx_active = false; hdmi_dma_stop(); hdmi_dma_irq_mask(1); break; @@ -662,7 +659,6 @@ static void hdmi_dma_irq_enable(struct imx_hdmi_dma_runtime_data *rtd) hdmi_irq_enable(hdmi_dma_priv->irq); hdmi_dma_irq_mute(0); hdmi_dma_irq_mask(0); - hdmi_dma_priv->tx_active = true; spin_unlock_irqrestore(&hdmi_dma_priv->irq_lock, flags); @@ -678,7 +674,6 @@ static void hdmi_dma_irq_disable(struct imx_hdmi_dma_runtime_data *rtd) hdmi_dma_irq_mute(1); hdmi_irq_disable(rtd->irq); hdmi_dma_clear_irq_status(0xff); - rtd->tx_active = false; spin_unlock_irqrestore(&rtd->irq_lock, flags); } |