diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index b3eb8570cd7bf4a4073082fffdc9f3dbb71d9521..2c4892c853cf8d0c06e6be365f15baec1ca224ed 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -697,6 +697,23 @@ static snd_pcm_uframes_t fsl_dma_pointer(struct snd_pcm_substream *substream)
 	else
 		position = in_be32(&dma_channel->dar);
 
+	/*
+	 * When capture is started, the SSI immediately starts to fill its FIFO.
+	 * This means that the DMA controller is not started until the FIFO is
+	 * full.  However, ALSA calls this function before that happens, when
+	 * MR.DAR is still zero.  In this case, just return zero to indicate
+	 * that nothing has been received yet.
+	 */
+	if (!position)
+		return 0;
+
+	if ((position < dma_private->dma_buf_phys) ||
+	    (position > dma_private->dma_buf_end)) {
+		dev_err(substream->pcm->card->dev,
+			"dma pointer is out of range, halting stream\n");
+		return SNDRV_PCM_POS_XRUN;
+	}
+
 	frames = bytes_to_frames(runtime, position - dma_private->dma_buf_phys);
 
 	/*
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 169bca295b7831f263739042aa1ed3645d59c99a..72823a2b33d62f95694e8e880e4de1a4f1031f82 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -466,28 +466,12 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
 	case SNDRV_PCM_TRIGGER_START:
 		clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 			setbits32(&ssi->scr,
 				CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE);
-		} else {
-			long timeout = jiffies + 10;
-
+		else
 			setbits32(&ssi->scr,
 				CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE);
-
-			/* Wait until the SSI has filled its FIFO. Without this
-			 * delay, ALSA complains about overruns.  When the FIFO
-			 * is full, the DMA controller initiates its first
-			 * transfer.  Until then, however, the DMA's DAR
-			 * register is zero, which translates to an
-			 * out-of-bounds pointer.  This makes ALSA think an
-			 * overrun has occurred.
-			 */
-			while (!(in_be32(&ssi->sisr) & CCSR_SSI_SISR_RFF0) &&
-			       (jiffies < timeout));
-			if (!(in_be32(&ssi->sisr) & CCSR_SSI_SISR_RFF0))
-				return -EIO;
-		}
 		break;
 
 	case SNDRV_PCM_TRIGGER_STOP: