.. | .. |
---|
153 | 153 | * the Global Timer flag _after_ having incremented |
---|
154 | 154 | * the Comparator register value to a higher value. |
---|
155 | 155 | */ |
---|
156 | | - if (clockevent_state_oneshot(evt)) |
---|
| 156 | + if (clockevent_is_oob(evt) || clockevent_state_oneshot(evt)) |
---|
157 | 157 | gt_compare_set(ULONG_MAX, 0); |
---|
158 | 158 | |
---|
159 | 159 | writel_relaxed(GT_INT_STATUS_EVENT_FLAG, gt_base + GT_INT_STATUS); |
---|
160 | | - evt->event_handler(evt); |
---|
| 160 | + clockevents_handle_event(evt); |
---|
161 | 161 | |
---|
162 | 162 | return IRQ_HANDLED; |
---|
163 | 163 | } |
---|
.. | .. |
---|
168 | 168 | |
---|
169 | 169 | clk->name = "arm_global_timer"; |
---|
170 | 170 | clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | |
---|
171 | | - CLOCK_EVT_FEAT_PERCPU; |
---|
| 171 | + CLOCK_EVT_FEAT_PERCPU | CLOCK_EVT_FEAT_PIPELINE; |
---|
172 | 172 | clk->set_state_shutdown = gt_clockevent_shutdown; |
---|
173 | 173 | clk->set_state_periodic = gt_clockevent_set_periodic; |
---|
174 | 174 | clk->set_state_oneshot = gt_clockevent_shutdown; |
---|
.. | .. |
---|
192 | 192 | return 0; |
---|
193 | 193 | } |
---|
194 | 194 | |
---|
195 | | -static u64 gt_clocksource_read(struct clocksource *cs) |
---|
196 | | -{ |
---|
197 | | - return gt_counter_read(); |
---|
198 | | -} |
---|
199 | | - |
---|
200 | 195 | static void gt_resume(struct clocksource *cs) |
---|
201 | 196 | { |
---|
202 | 197 | unsigned long ctrl; |
---|
.. | .. |
---|
207 | 202 | writel(GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL); |
---|
208 | 203 | } |
---|
209 | 204 | |
---|
210 | | -static struct clocksource gt_clocksource = { |
---|
211 | | - .name = "arm_global_timer", |
---|
212 | | - .rating = 300, |
---|
213 | | - .read = gt_clocksource_read, |
---|
214 | | - .mask = CLOCKSOURCE_MASK(64), |
---|
215 | | - .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
---|
216 | | - .resume = gt_resume, |
---|
| 205 | +static struct clocksource_user_mmio gt_clocksource = { |
---|
| 206 | + .mmio.clksrc = { |
---|
| 207 | + .name = "arm_global_timer", |
---|
| 208 | + .rating = 300, |
---|
| 209 | + .read = clocksource_dual_mmio_readl_up, |
---|
| 210 | + .mask = CLOCKSOURCE_MASK(64), |
---|
| 211 | + .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
---|
| 212 | + .resume = gt_resume, |
---|
| 213 | + }, |
---|
217 | 214 | }; |
---|
218 | 215 | |
---|
219 | 216 | #ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK |
---|
.. | .. |
---|
240 | 237 | |
---|
241 | 238 | static int __init gt_clocksource_init(void) |
---|
242 | 239 | { |
---|
| 240 | + struct clocksource_mmio_regs mmr; |
---|
| 241 | + |
---|
243 | 242 | writel(0, gt_base + GT_CONTROL); |
---|
244 | 243 | writel(0, gt_base + GT_COUNTER0); |
---|
245 | 244 | writel(0, gt_base + GT_COUNTER1); |
---|
.. | .. |
---|
249 | 248 | #ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK |
---|
250 | 249 | sched_clock_register(gt_sched_clock_read, 64, gt_clk_rate); |
---|
251 | 250 | #endif |
---|
252 | | - return clocksource_register_hz(>_clocksource, gt_clk_rate); |
---|
| 251 | + mmr.reg_upper = gt_base + GT_COUNTER1; |
---|
| 252 | + mmr.reg_lower = gt_base + GT_COUNTER0; |
---|
| 253 | + mmr.bits_upper = 32; |
---|
| 254 | + mmr.bits_lower = 32; |
---|
| 255 | + mmr.revmap = NULL; |
---|
| 256 | + |
---|
| 257 | + return clocksource_user_mmio_init(>_clocksource, &mmr, gt_clk_rate); |
---|
253 | 258 | } |
---|
254 | 259 | |
---|
255 | 260 | static int __init global_timer_of_register(struct device_node *np) |
---|
.. | .. |
---|
299 | 304 | goto out_clk; |
---|
300 | 305 | } |
---|
301 | 306 | |
---|
302 | | - err = request_percpu_irq(gt_ppi, gt_clockevent_interrupt, |
---|
303 | | - "gt", gt_evt); |
---|
| 307 | + err = __request_percpu_irq(gt_ppi, gt_clockevent_interrupt, |
---|
| 308 | + IRQF_TIMER, "gt", gt_evt); |
---|
304 | 309 | if (err) { |
---|
305 | 310 | pr_warn("global-timer: can't register interrupt %d (%d)\n", |
---|
306 | 311 | gt_ppi, err); |
---|