struct snd_soc_dai *cpu_dai)
 {
        struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
+       int tx = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
+       int stream1 = tx ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
+       int stream2 = tx ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
+
+       if (mcbsp->latency[stream2])
+               pm_qos_update_request(&mcbsp->pm_qos_req,
+                                     mcbsp->latency[stream2]);
+       else if (mcbsp->latency[stream1])
+               pm_qos_remove_request(&mcbsp->pm_qos_req);
+
+       mcbsp->latency[stream1] = 0;
 
        if (!cpu_dai->active) {
                omap_mcbsp_free(mcbsp);
        }
 }
 
+static int omap_mcbsp_dai_prepare(struct snd_pcm_substream *substream,
+                                 struct snd_soc_dai *cpu_dai)
+{
+       struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
+       struct pm_qos_request *pm_qos_req = &mcbsp->pm_qos_req;
+       int tx = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
+       int stream1 = tx ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
+       int stream2 = tx ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
+       int latency = mcbsp->latency[stream2];
+
+       /* Prevent omap hardware from hitting off between FIFO fills */
+       if (!latency || mcbsp->latency[stream1] < latency)
+               latency = mcbsp->latency[stream1];
+
+       if (pm_qos_request_active(pm_qos_req))
+               pm_qos_update_request(pm_qos_req, latency);
+       else if (latency)
+               pm_qos_add_request(pm_qos_req, PM_QOS_CPU_DMA_LATENCY, latency);
+
+       return 0;
+}
+
 static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd,
                                  struct snd_soc_dai *cpu_dai)
 {
        int wlen, channels, wpf;
        int pkt_size = 0;
        unsigned int format, div, framesize, master;
+       unsigned int buffer_size = mcbsp->pdata->buffer_size;
 
        dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);
        channels = params_channels(params);
        default:
                return -EINVAL;
        }
-       if (mcbsp->pdata->buffer_size) {
+       if (buffer_size) {
+               int latency;
+
                if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
                        int period_words, max_thrsh;
                        int divider = 0;
                        /* Use packet mode for non mono streams */
                        pkt_size = channels;
                }
+
+               latency = ((((buffer_size - pkt_size) / channels) * 1000)
+                                / (params->rate_num / params->rate_den));
+
+               mcbsp->latency[substream->stream] = latency;
+
                omap_mcbsp_set_threshold(substream, pkt_size);
        }
 
 static const struct snd_soc_dai_ops mcbsp_dai_ops = {
        .startup        = omap_mcbsp_dai_startup,
        .shutdown       = omap_mcbsp_dai_shutdown,
+       .prepare        = omap_mcbsp_dai_prepare,
        .trigger        = omap_mcbsp_dai_trigger,
        .delay          = omap_mcbsp_dai_delay,
        .hw_params      = omap_mcbsp_dai_hw_params,
        if (mcbsp->pdata->ops && mcbsp->pdata->ops->free)
                mcbsp->pdata->ops->free(mcbsp->id);
 
+       if (pm_qos_request_active(&mcbsp->pm_qos_req))
+               pm_qos_remove_request(&mcbsp->pm_qos_req);
+
        omap_mcbsp_cleanup(mcbsp);
 
        clk_put(mcbsp->fclk);