diff options
Diffstat (limited to 'kernel/time/clockevents.c')
-rw-r--r-- | kernel/time/clockevents.c | 70 |
1 files changed, 68 insertions, 2 deletions
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index d7395fdfb9f3..e4c699dfa4e8 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/notifier.h> | 18 | #include <linux/notifier.h> |
19 | #include <linux/smp.h> | 19 | #include <linux/smp.h> |
20 | #include <linux/sysdev.h> | 20 | #include <linux/sysdev.h> |
21 | #include <linux/tick.h> | ||
22 | 21 | ||
23 | #include "tick-internal.h" | 22 | #include "tick-internal.h" |
24 | 23 | ||
@@ -183,7 +182,10 @@ void clockevents_register_device(struct clock_event_device *dev) | |||
183 | unsigned long flags; | 182 | unsigned long flags; |
184 | 183 | ||
185 | BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED); | 184 | BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED); |
186 | BUG_ON(!dev->cpumask); | 185 | if (!dev->cpumask) { |
186 | WARN_ON(num_possible_cpus() > 1); | ||
187 | dev->cpumask = cpumask_of(smp_processor_id()); | ||
188 | } | ||
187 | 189 | ||
188 | raw_spin_lock_irqsave(&clockevents_lock, flags); | 190 | raw_spin_lock_irqsave(&clockevents_lock, flags); |
189 | 191 | ||
@@ -195,6 +197,70 @@ void clockevents_register_device(struct clock_event_device *dev) | |||
195 | } | 197 | } |
196 | EXPORT_SYMBOL_GPL(clockevents_register_device); | 198 | EXPORT_SYMBOL_GPL(clockevents_register_device); |
197 | 199 | ||
200 | static void clockevents_config(struct clock_event_device *dev, | ||
201 | u32 freq) | ||
202 | { | ||
203 | u64 sec; | ||
204 | |||
205 | if (!(dev->features & CLOCK_EVT_FEAT_ONESHOT)) | ||
206 | return; | ||
207 | |||
208 | /* | ||
209 | * Calculate the maximum number of seconds we can sleep. Limit | ||
210 | * to 10 minutes for hardware which can program more than | ||
211 | * 32bit ticks so we still get reasonable conversion values. | ||
212 | */ | ||
213 | sec = dev->max_delta_ticks; | ||
214 | do_div(sec, freq); | ||
215 | if (!sec) | ||
216 | sec = 1; | ||
217 | else if (sec > 600 && dev->max_delta_ticks > UINT_MAX) | ||
218 | sec = 600; | ||
219 | |||
220 | clockevents_calc_mult_shift(dev, freq, sec); | ||
221 | dev->min_delta_ns = clockevent_delta2ns(dev->min_delta_ticks, dev); | ||
222 | dev->max_delta_ns = clockevent_delta2ns(dev->max_delta_ticks, dev); | ||
223 | } | ||
224 | |||
225 | /** | ||
226 | * clockevents_config_and_register - Configure and register a clock event device | ||
227 | * @dev: device to register | ||
228 | * @freq: The clock frequency | ||
229 | * @min_delta: The minimum clock ticks to program in oneshot mode | ||
230 | * @max_delta: The maximum clock ticks to program in oneshot mode | ||
231 | * | ||
232 | * min/max_delta can be 0 for devices which do not support oneshot mode. | ||
233 | */ | ||
234 | void clockevents_config_and_register(struct clock_event_device *dev, | ||
235 | u32 freq, unsigned long min_delta, | ||
236 | unsigned long max_delta) | ||
237 | { | ||
238 | dev->min_delta_ticks = min_delta; | ||
239 | dev->max_delta_ticks = max_delta; | ||
240 | clockevents_config(dev, freq); | ||
241 | clockevents_register_device(dev); | ||
242 | } | ||
243 | |||
244 | /** | ||
245 | * clockevents_update_freq - Update frequency and reprogram a clock event device. | ||
246 | * @dev: device to modify | ||
247 | * @freq: new device frequency | ||
248 | * | ||
249 | * Reconfigure and reprogram a clock event device in oneshot | ||
250 | * mode. Must be called on the cpu for which the device delivers per | ||
251 | * cpu timer events with interrupts disabled! Returns 0 on success, | ||
252 | * -ETIME when the event is in the past. | ||
253 | */ | ||
254 | int clockevents_update_freq(struct clock_event_device *dev, u32 freq) | ||
255 | { | ||
256 | clockevents_config(dev, freq); | ||
257 | |||
258 | if (dev->mode != CLOCK_EVT_MODE_ONESHOT) | ||
259 | return 0; | ||
260 | |||
261 | return clockevents_program_event(dev, dev->next_event, ktime_get()); | ||
262 | } | ||
263 | |||
198 | /* | 264 | /* |
199 | * Noop handler when we shut down an event device | 265 | * Noop handler when we shut down an event device |
200 | */ | 266 | */ |