diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2010-04-14 03:17:30 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-04-15 12:02:35 -0400 |
commit | 8392609969b3b37a4da5cff08161661f7a8c16af (patch) | |
tree | 5302e690e436ee6eb8fd6407db0aa8934d3f54fa /sound/soc | |
parent | 565a79f74af96ae90dfec411da14dc38d2cd56bc (diff) |
ASoC: imx-ssi: do not call hrtimer_disable in trigger function
Doing so causes a deadlock, so just signal the timer to stop
using an atomic variable.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/imx/imx-pcm-fiq.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c index 98ab33109527..ecec332121f2 100644 --- a/sound/soc/imx/imx-pcm-fiq.c +++ b/sound/soc/imx/imx-pcm-fiq.c | |||
@@ -41,6 +41,7 @@ struct imx_pcm_runtime_data { | |||
41 | struct hrtimer hrt; | 41 | struct hrtimer hrt; |
42 | int poll_time_ns; | 42 | int poll_time_ns; |
43 | struct snd_pcm_substream *substream; | 43 | struct snd_pcm_substream *substream; |
44 | atomic_t running; | ||
44 | }; | 45 | }; |
45 | 46 | ||
46 | static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) | 47 | static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) |
@@ -52,6 +53,9 @@ static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) | |||
52 | struct pt_regs regs; | 53 | struct pt_regs regs; |
53 | unsigned long delta; | 54 | unsigned long delta; |
54 | 55 | ||
56 | if (!atomic_read(&iprtd->running)) | ||
57 | return HRTIMER_NORESTART; | ||
58 | |||
55 | get_fiq_regs(®s); | 59 | get_fiq_regs(®s); |
56 | 60 | ||
57 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 61 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
@@ -129,6 +133,7 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
129 | case SNDRV_PCM_TRIGGER_START: | 133 | case SNDRV_PCM_TRIGGER_START: |
130 | case SNDRV_PCM_TRIGGER_RESUME: | 134 | case SNDRV_PCM_TRIGGER_RESUME: |
131 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 135 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
136 | atomic_set(&iprtd->running, 1); | ||
132 | hrtimer_start(&iprtd->hrt, ns_to_ktime(iprtd->poll_time_ns), | 137 | hrtimer_start(&iprtd->hrt, ns_to_ktime(iprtd->poll_time_ns), |
133 | HRTIMER_MODE_REL); | 138 | HRTIMER_MODE_REL); |
134 | if (++fiq_enable == 1) | 139 | if (++fiq_enable == 1) |
@@ -139,11 +144,11 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
139 | case SNDRV_PCM_TRIGGER_STOP: | 144 | case SNDRV_PCM_TRIGGER_STOP: |
140 | case SNDRV_PCM_TRIGGER_SUSPEND: | 145 | case SNDRV_PCM_TRIGGER_SUSPEND: |
141 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 146 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
142 | hrtimer_cancel(&iprtd->hrt); | 147 | atomic_set(&iprtd->running, 0); |
148 | |||
143 | if (--fiq_enable == 0) | 149 | if (--fiq_enable == 0) |
144 | disable_fiq(imx_pcm_fiq); | 150 | disable_fiq(imx_pcm_fiq); |
145 | 151 | ||
146 | |||
147 | break; | 152 | break; |
148 | default: | 153 | default: |
149 | return -EINVAL; | 154 | return -EINVAL; |
@@ -190,6 +195,7 @@ static int snd_imx_open(struct snd_pcm_substream *substream) | |||
190 | 195 | ||
191 | iprtd->substream = substream; | 196 | iprtd->substream = substream; |
192 | 197 | ||
198 | atomic_set(&iprtd->running, 0); | ||
193 | hrtimer_init(&iprtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 199 | hrtimer_init(&iprtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
194 | iprtd->hrt.function = snd_hrtimer_callback; | 200 | iprtd->hrt.function = snd_hrtimer_callback; |
195 | 201 | ||