Source
195
195
writel_relaxed(tcmp, imxtm->base + V2_TCMP);
196
196
197
197
return evt < 0x7fffffff &&
198
198
(int)(tcmp - readl_relaxed(imxtm->base + V2_TCN)) < 0 ?
199
199
-ETIME : 0;
200
200
}
201
201
202
202
static int mxc_shutdown(struct clock_event_device *ced)
203
203
{
204
204
struct imx_timer *imxtm = to_imx_timer(ced);
205
-
unsigned long flags;
206
205
u32 tcn;
207
206
208
-
/*
209
-
* The timer interrupt generation is disabled at least
210
-
* for enough time to call mxc_set_next_event()
211
-
*/
212
-
local_irq_save(flags);
213
-
214
207
/* Disable interrupt in GPT module */
215
208
imxtm->gpt->gpt_irq_disable(imxtm);
216
209
217
210
tcn = readl_relaxed(imxtm->base + imxtm->gpt->reg_tcn);
218
211
/* Set event time into far-far future */
219
212
writel_relaxed(tcn - 3, imxtm->base + imxtm->gpt->reg_tcmp);
220
213
221
214
/* Clear pending interrupt */
222
215
imxtm->gpt->gpt_irq_acknowledge(imxtm);
223
216
224
217
#ifdef DEBUG
225
218
printk(KERN_INFO "%s: changing mode\n", __func__);
226
219
#endif /* DEBUG */
227
220
228
-
local_irq_restore(flags);
229
-
230
221
return 0;
231
222
}
232
223
233
224
static int mxc_set_oneshot(struct clock_event_device *ced)
234
225
{
235
226
struct imx_timer *imxtm = to_imx_timer(ced);
236
-
unsigned long flags;
237
-
238
-
/*
239
-
* The timer interrupt generation is disabled at least
240
-
* for enough time to call mxc_set_next_event()
241
-
*/
242
-
local_irq_save(flags);
243
227
244
228
/* Disable interrupt in GPT module */
245
229
imxtm->gpt->gpt_irq_disable(imxtm);
246
230
247
231
if (!clockevent_state_oneshot(ced)) {
248
232
u32 tcn = readl_relaxed(imxtm->base + imxtm->gpt->reg_tcn);
249
233
/* Set event time into far-far future */
250
234
writel_relaxed(tcn - 3, imxtm->base + imxtm->gpt->reg_tcmp);
251
235
252
236
/* Clear pending interrupt */
257
241
printk(KERN_INFO "%s: changing mode\n", __func__);
258
242
#endif /* DEBUG */
259
243
260
244
/*
261
245
* Do not put overhead of interrupt enable/disable into
262
246
* mxc_set_next_event(), the core has about 4 minutes
263
247
* to call mxc_set_next_event() or shutdown clock after
264
248
* mode switching
265
249
*/
266
250
imxtm->gpt->gpt_irq_enable(imxtm);
267
-
local_irq_restore(flags);
268
251
269
252
return 0;
270
253
}
271
254
272
255
/*
273
256
* IRQ handler for the timer
274
257
*/
275
258
static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
276
259
{
277
260
struct clock_event_device *ced = dev_id;