aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time
diff options
context:
space:
mode:
authorJohn Stultz <john.stultz@linaro.org>2011-04-28 16:29:18 -0400
committerJohn Stultz <john.stultz@linaro.org>2011-04-28 16:39:18 -0400
commit7068b7a16270f1e85a8893d74b0f3c58d7826883 (patch)
tree114143f4724543c89d93e95bbb7d3f03f1abb5d6 /kernel/time
parent180bf812ceaf01eb8ac69b86f3be0bd57f697668 (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.c32
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 */
38static struct alarm_base { 37static 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 */
109static void alarmtimer_do_work(struct work_struct *work) 108static 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 */
157static 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);