summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Tull <r80115@freescale.com>2012-02-17 15:15:35 -0600
committerAlan Tull <r80115@freescale.com>2012-02-17 16:02:06 -0600
commit7ce46fbfcda2b6b5d5f3005c3d8dd639e625f292 (patch)
tree884054171c15d0131b775e17883f4b8410923e86
parent8374a2fad38f2ab478a051d9e0b90651cb0999bf (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>
-rw-r--r--sound/soc/imx/imx-hdmi-dma.c11
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);
}