diff options
| -rw-r--r-- | sound/core/hrtimer.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c index 34c7d48f5061..7f4d744ae40a 100644 --- a/sound/core/hrtimer.c +++ b/sound/core/hrtimer.c | |||
| @@ -37,14 +37,22 @@ static unsigned int resolution; | |||
| 37 | struct snd_hrtimer { | 37 | struct snd_hrtimer { |
| 38 | struct snd_timer *timer; | 38 | struct snd_timer *timer; |
| 39 | struct hrtimer hrt; | 39 | struct hrtimer hrt; |
| 40 | atomic_t running; | ||
| 40 | }; | 41 | }; |
| 41 | 42 | ||
| 42 | static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) | 43 | static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) |
| 43 | { | 44 | { |
| 44 | struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt); | 45 | struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt); |
| 45 | struct snd_timer *t = stime->timer; | 46 | struct snd_timer *t = stime->timer; |
| 47 | |||
| 48 | if (!atomic_read(&stime->running)) | ||
| 49 | return HRTIMER_NORESTART; | ||
| 50 | |||
| 46 | hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution)); | 51 | hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution)); |
| 47 | snd_timer_interrupt(stime->timer, t->sticks); | 52 | snd_timer_interrupt(stime->timer, t->sticks); |
| 53 | |||
| 54 | if (!atomic_read(&stime->running)) | ||
| 55 | return HRTIMER_NORESTART; | ||
| 48 | return HRTIMER_RESTART; | 56 | return HRTIMER_RESTART; |
| 49 | } | 57 | } |
| 50 | 58 | ||
| @@ -58,6 +66,7 @@ static int snd_hrtimer_open(struct snd_timer *t) | |||
| 58 | hrtimer_init(&stime->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 66 | hrtimer_init(&stime->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
| 59 | stime->timer = t; | 67 | stime->timer = t; |
| 60 | stime->hrt.function = snd_hrtimer_callback; | 68 | stime->hrt.function = snd_hrtimer_callback; |
| 69 | atomic_set(&stime->running, 0); | ||
| 61 | t->private_data = stime; | 70 | t->private_data = stime; |
| 62 | return 0; | 71 | return 0; |
| 63 | } | 72 | } |
| @@ -78,16 +87,18 @@ static int snd_hrtimer_start(struct snd_timer *t) | |||
| 78 | { | 87 | { |
| 79 | struct snd_hrtimer *stime = t->private_data; | 88 | struct snd_hrtimer *stime = t->private_data; |
| 80 | 89 | ||
| 90 | atomic_set(&stime->running, 0); | ||
| 91 | hrtimer_cancel(&stime->hrt); | ||
| 81 | hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution), | 92 | hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution), |
| 82 | HRTIMER_MODE_REL); | 93 | HRTIMER_MODE_REL); |
| 94 | atomic_set(&stime->running, 1); | ||
| 83 | return 0; | 95 | return 0; |
| 84 | } | 96 | } |
| 85 | 97 | ||
| 86 | static int snd_hrtimer_stop(struct snd_timer *t) | 98 | static int snd_hrtimer_stop(struct snd_timer *t) |
| 87 | { | 99 | { |
| 88 | struct snd_hrtimer *stime = t->private_data; | 100 | struct snd_hrtimer *stime = t->private_data; |
| 89 | 101 | atomic_set(&stime->running, 0); | |
| 90 | hrtimer_cancel(&stime->hrt); | ||
| 91 | return 0; | 102 | return 0; |
| 92 | } | 103 | } |
| 93 | 104 | ||
