summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@ti.com>2018-11-14 13:06:23 +0200
committerMark Brown <broonie@kernel.org>2018-11-23 14:05:30 +0000
commitffdcc3638c58d55a6fa68b6e5dfd4fb4109652eb (patch)
tree69e67089e55ddcaf468d995e6def17b514b6adbe
parent373a500e34aea97971c9d71e45edad458d3da98f (diff)
downloadlinux-stable-ffdcc3638c58d55a6fa68b6e5dfd4fb4109652eb.tar.gz
linux-stable-ffdcc3638c58d55a6fa68b6e5dfd4fb4109652eb.tar.bz2
linux-stable-ffdcc3638c58d55a6fa68b6e5dfd4fb4109652eb.zip
ASoC: omap-dmic: Add pm_qos handling to avoid overruns with CPU_IDLE
We need to block sleep states which would require longer time to leave than the time the DMA must react to the DMA request in order to keep the FIFO serviced without overrun. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Acked-by: Jarkko Nikula <jarkko.nikula@bitmer.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/omap/omap-dmic.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c
index fe966272bd0c..cba9645b6487 100644
--- a/sound/soc/omap/omap-dmic.c
+++ b/sound/soc/omap/omap-dmic.c
@@ -48,6 +48,8 @@ struct omap_dmic {
struct device *dev;
void __iomem *io_base;
struct clk *fclk;
+ struct pm_qos_request pm_qos_req;
+ int latency;
int fclk_freq;
int out_freq;
int clk_div;
@@ -124,6 +126,8 @@ static void omap_dmic_dai_shutdown(struct snd_pcm_substream *substream,
mutex_lock(&dmic->mutex);
+ pm_qos_remove_request(&dmic->pm_qos_req);
+
if (!dai->active)
dmic->active = 0;
@@ -228,6 +232,8 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream,
/* packet size is threshold * channels */
dma_data = snd_soc_dai_get_dma_data(dai, substream);
dma_data->maxburst = dmic->threshold * channels;
+ dmic->latency = (OMAP_DMIC_THRES_MAX - dmic->threshold) * USEC_PER_SEC /
+ params_rate(params);
return 0;
}
@@ -238,6 +244,9 @@ static int omap_dmic_dai_prepare(struct snd_pcm_substream *substream,
struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
u32 ctrl;
+ if (pm_qos_request_active(&dmic->pm_qos_req))
+ pm_qos_update_request(&dmic->pm_qos_req, dmic->latency);
+
/* Configure uplink threshold */
omap_dmic_write(dmic, OMAP_DMIC_FIFO_CTRL_REG, dmic->threshold);