diff options
-rw-r--r-- | include/linux/clockchips.h | 9 | ||||
-rw-r--r-- | kernel/time/clockevents.c | 44 |
2 files changed, 53 insertions, 0 deletions
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h index 9466eebc8e19..80acc79e0dc5 100644 --- a/include/linux/clockchips.h +++ b/include/linux/clockchips.h | |||
@@ -69,6 +69,8 @@ enum clock_event_nofitiers { | |||
69 | * @retries: number of forced programming retries | 69 | * @retries: number of forced programming retries |
70 | * @set_mode: set mode function | 70 | * @set_mode: set mode function |
71 | * @broadcast: function to broadcast events | 71 | * @broadcast: function to broadcast events |
72 | * @min_delta_ticks: minimum delta value in ticks stored for reconfiguration | ||
73 | * @max_delta_ticks: maximum delta value in ticks stored for reconfiguration | ||
72 | * @name: ptr to clock event name | 74 | * @name: ptr to clock event name |
73 | * @rating: variable to rate clock event devices | 75 | * @rating: variable to rate clock event devices |
74 | * @irq: IRQ number (only for non CPU local devices) | 76 | * @irq: IRQ number (only for non CPU local devices) |
@@ -91,6 +93,9 @@ struct clock_event_device { | |||
91 | void (*broadcast)(const struct cpumask *mask); | 93 | void (*broadcast)(const struct cpumask *mask); |
92 | void (*set_mode)(enum clock_event_mode mode, | 94 | void (*set_mode)(enum clock_event_mode mode, |
93 | struct clock_event_device *); | 95 | struct clock_event_device *); |
96 | unsigned long min_delta_ticks; | ||
97 | unsigned long max_delta_ticks; | ||
98 | |||
94 | const char *name; | 99 | const char *name; |
95 | int rating; | 100 | int rating; |
96 | int irq; | 101 | int irq; |
@@ -123,6 +128,10 @@ extern u64 clockevent_delta2ns(unsigned long latch, | |||
123 | struct clock_event_device *evt); | 128 | struct clock_event_device *evt); |
124 | extern void clockevents_register_device(struct clock_event_device *dev); | 129 | extern void clockevents_register_device(struct clock_event_device *dev); |
125 | 130 | ||
131 | extern void clockevents_config_and_register(struct clock_event_device *dev, | ||
132 | u32 freq, unsigned long min_delta, | ||
133 | unsigned long max_delta); | ||
134 | |||
126 | extern void clockevents_exchange_device(struct clock_event_device *old, | 135 | extern void clockevents_exchange_device(struct clock_event_device *old, |
127 | struct clock_event_device *new); | 136 | struct clock_event_device *new); |
128 | extern void clockevents_set_mode(struct clock_event_device *dev, | 137 | extern void clockevents_set_mode(struct clock_event_device *dev, |
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 0d74b9ba90c8..c69e88c94446 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c | |||
@@ -194,6 +194,50 @@ void clockevents_register_device(struct clock_event_device *dev) | |||
194 | } | 194 | } |
195 | EXPORT_SYMBOL_GPL(clockevents_register_device); | 195 | EXPORT_SYMBOL_GPL(clockevents_register_device); |
196 | 196 | ||
197 | static void clockevents_config(struct clock_event_device *dev, | ||
198 | u32 freq) | ||
199 | { | ||
200 | unsigned long sec; | ||
201 | |||
202 | if (!(dev->features & CLOCK_EVT_FEAT_ONESHOT)) | ||
203 | return; | ||
204 | |||
205 | /* | ||
206 | * Calculate the maximum number of seconds we can sleep. Limit | ||
207 | * to 10 minutes for hardware which can program more than | ||
208 | * 32bit ticks so we still get reasonable conversion values. | ||
209 | */ | ||
210 | sec = dev->max_delta_ticks; | ||
211 | do_div(sec, freq); | ||
212 | if (!sec) | ||
213 | sec = 1; | ||
214 | else if (sec > 600 && dev->max_delta_ticks > UINT_MAX) | ||
215 | sec = 600; | ||
216 | |||
217 | clockevents_calc_mult_shift(dev, freq, sec); | ||
218 | dev->min_delta_ns = clockevent_delta2ns(dev->min_delta_ticks, dev); | ||
219 | dev->max_delta_ns = clockevent_delta2ns(dev->max_delta_ticks, dev); | ||
220 | } | ||
221 | |||
222 | /** | ||
223 | * clockevents_config_and_register - Configure and register a clock event device | ||
224 | * @dev: device to register | ||
225 | * @freq: The clock frequency | ||
226 | * @min_delta: The minimum clock ticks to program in oneshot mode | ||
227 | * @max_delta: The maximum clock ticks to program in oneshot mode | ||
228 | * | ||
229 | * min/max_delta can be 0 for devices which do not support oneshot mode. | ||
230 | */ | ||
231 | void clockevents_config_and_register(struct clock_event_device *dev, | ||
232 | u32 freq, unsigned long min_delta, | ||
233 | unsigned long max_delta) | ||
234 | { | ||
235 | dev->min_delta_ticks = min_delta; | ||
236 | dev->max_delta_ticks = max_delta; | ||
237 | clockevents_config(dev, freq); | ||
238 | clockevents_register_device(dev); | ||
239 | } | ||
240 | |||
197 | /* | 241 | /* |
198 | * Noop handler when we shut down an event device | 242 | * Noop handler when we shut down an event device |
199 | */ | 243 | */ |