diff options
author | John Stultz <john.stultz@linaro.org> | 2011-04-28 16:29:18 -0400 |
---|---|---|
committer | John Stultz <john.stultz@linaro.org> | 2011-04-28 16:39:18 -0400 |
commit | 7068b7a16270f1e85a8893d74b0f3c58d7826883 (patch) | |
tree | 114143f4724543c89d93e95bbb7d3f03f1abb5d6 /kernel/time | |
parent | 180bf812ceaf01eb8ac69b86f3be0bd57f697668 (diff) |
timers: Remove delayed irqwork from alarmtimers implementation
Thomas asked about the delayed irq work in the alarmtimers code,
and I realized that it was a legacy from when the alarmtimer base
lock was a mutex (due to concerns that we'd be interacting with
the RTC device, which is protected by mutexes).
Since the alarmtimer base is now protected by a spinlock, we can
simply execute alarmtimer functions directly from the hrtimer
callback. Should any future alarmtimer functions sleep, they can
simply manage scheduling any delayed work themselves.
CC: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Diffstat (limited to 'kernel/time')
-rw-r--r-- | kernel/time/alarmtimer.c | 32 |
1 files changed, 9 insertions, 23 deletions
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index bed98004ae1a..491e37b8de1f 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c | |||
@@ -33,7 +33,6 @@ | |||
33 | * @timer: hrtimer used to schedule events while running | 33 | * @timer: hrtimer used to schedule events while running |
34 | * @gettime: Function to read the time correlating to the base | 34 | * @gettime: Function to read the time correlating to the base |
35 | * @base_clockid: clockid for the base | 35 | * @base_clockid: clockid for the base |
36 | * @irqwork Delayed work structure for expiring timers | ||
37 | */ | 36 | */ |
38 | static struct alarm_base { | 37 | static struct alarm_base { |
39 | spinlock_t lock; | 38 | spinlock_t lock; |
@@ -41,7 +40,6 @@ static struct alarm_base { | |||
41 | struct hrtimer timer; | 40 | struct hrtimer timer; |
42 | ktime_t (*gettime)(void); | 41 | ktime_t (*gettime)(void); |
43 | clockid_t base_clockid; | 42 | clockid_t base_clockid; |
44 | struct work_struct irqwork; | ||
45 | } alarm_bases[ALARM_NUMTYPE]; | 43 | } alarm_bases[ALARM_NUMTYPE]; |
46 | 44 | ||
47 | /* rtc timer and device for setting alarm wakeups at suspend */ | 45 | /* rtc timer and device for setting alarm wakeups at suspend */ |
@@ -97,22 +95,23 @@ static void alarmtimer_remove(struct alarm_base *base, struct alarm *alarm) | |||
97 | } | 95 | } |
98 | } | 96 | } |
99 | 97 | ||
98 | |||
100 | /** | 99 | /** |
101 | * alarmtimer_do_work - Handles alarm being fired. | 100 | * alarmtimer_fired - Handles alarm hrtimer being fired. |
102 | * @work: pointer to workqueue being run | 101 | * @timer: pointer to hrtimer being run |
103 | * | 102 | * |
104 | * When a alarm timer fires, this runs through the timerqueue to | 103 | * When a alarm timer fires, this runs through the timerqueue to |
105 | * see which alarms expired, and runs those. If there are more alarm | 104 | * see which alarms expired, and runs those. If there are more alarm |
106 | * timers queued for the future, we set the hrtimer to fire when | 105 | * timers queued for the future, we set the hrtimer to fire when |
107 | * when the next future alarm timer expires. | 106 | * when the next future alarm timer expires. |
108 | */ | 107 | */ |
109 | static void alarmtimer_do_work(struct work_struct *work) | 108 | static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer) |
110 | { | 109 | { |
111 | struct alarm_base *base = container_of(work, struct alarm_base, | 110 | struct alarm_base *base = container_of(timer, struct alarm_base, timer); |
112 | irqwork); | ||
113 | struct timerqueue_node *next; | 111 | struct timerqueue_node *next; |
114 | unsigned long flags; | 112 | unsigned long flags; |
115 | ktime_t now; | 113 | ktime_t now; |
114 | int ret = HRTIMER_NORESTART; | ||
116 | 115 | ||
117 | spin_lock_irqsave(&base->lock, flags); | 116 | spin_lock_irqsave(&base->lock, flags); |
118 | now = base->gettime(); | 117 | now = base->gettime(); |
@@ -140,25 +139,13 @@ static void alarmtimer_do_work(struct work_struct *work) | |||
140 | } | 139 | } |
141 | 140 | ||
142 | if (next) { | 141 | if (next) { |
143 | hrtimer_start(&base->timer, next->expires, | 142 | hrtimer_set_expires(&base->timer, next->expires); |
144 | HRTIMER_MODE_ABS); | 143 | ret = HRTIMER_RESTART; |
145 | } | 144 | } |
146 | spin_unlock_irqrestore(&base->lock, flags); | 145 | spin_unlock_irqrestore(&base->lock, flags); |
147 | } | ||
148 | 146 | ||
147 | return ret; | ||
149 | 148 | ||
150 | /** | ||
151 | * alarmtimer_fired - Handles alarm hrtimer being fired. | ||
152 | * @timer: pointer to hrtimer being run | ||
153 | * | ||
154 | * When a timer fires, this schedules the do_work function to | ||
155 | * be run. | ||
156 | */ | ||
157 | static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer) | ||
158 | { | ||
159 | struct alarm_base *base = container_of(timer, struct alarm_base, timer); | ||
160 | schedule_work(&base->irqwork); | ||
161 | return HRTIMER_NORESTART; | ||
162 | } | 149 | } |
163 | 150 | ||
164 | 151 | ||
@@ -636,7 +623,6 @@ static int __init alarmtimer_init(void) | |||
636 | alarm_bases[i].base_clockid, | 623 | alarm_bases[i].base_clockid, |
637 | HRTIMER_MODE_ABS); | 624 | HRTIMER_MODE_ABS); |
638 | alarm_bases[i].timer.function = alarmtimer_fired; | 625 | alarm_bases[i].timer.function = alarmtimer_fired; |
639 | INIT_WORK(&alarm_bases[i].irqwork, alarmtimer_do_work); | ||
640 | } | 626 | } |
641 | error = platform_driver_register(&alarmtimer_driver); | 627 | error = platform_driver_register(&alarmtimer_driver); |
642 | platform_device_register_simple("alarmtimer", -1, NULL, 0); | 628 | platform_device_register_simple("alarmtimer", -1, NULL, 0); |