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 | |
| 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>
| -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 | ||
