diff options
author | Finn Thain <fthain@telegraphics.com.au> | 2018-11-30 19:53:10 -0500 |
---|---|---|
committer | Geert Uytterhoeven <geert@linux-m68k.org> | 2019-03-25 05:22:24 -0400 |
commit | 3d744eee38f11cafb0fc332c3081ab1cd07a89f7 (patch) | |
tree | 718d166ff2157d246bb9e2919ed2d98691e34772 /arch/m68k | |
parent | 7529b90d051e4629884771ba2b1d3a87d2c6a9d7 (diff) |
m68k: mvme16x: Convert to clocksource API
Add a platform clocksource by adapting the existing arch_gettimeoffset
implementation.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Diffstat (limited to 'arch/m68k')
-rw-r--r-- | arch/m68k/mvme16x/config.c | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c index 3a3129e6f0bc..2c109ee2a1a5 100644 --- a/arch/m68k/mvme16x/config.c +++ b/arch/m68k/mvme16x/config.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
20 | #include <linux/seq_file.h> | 20 | #include <linux/seq_file.h> |
21 | #include <linux/tty.h> | 21 | #include <linux/tty.h> |
22 | #include <linux/clocksource.h> | ||
22 | #include <linux/console.h> | 23 | #include <linux/console.h> |
23 | #include <linux/linkage.h> | 24 | #include <linux/linkage.h> |
24 | #include <linux/init.h> | 25 | #include <linux/init.h> |
@@ -343,6 +344,21 @@ static irqreturn_t mvme16x_abort_int (int irq, void *dev_id) | |||
343 | return IRQ_HANDLED; | 344 | return IRQ_HANDLED; |
344 | } | 345 | } |
345 | 346 | ||
347 | static u64 mvme16x_read_clk(struct clocksource *cs); | ||
348 | |||
349 | static struct clocksource mvme16x_clk = { | ||
350 | .name = "pcc", | ||
351 | .rating = 250, | ||
352 | .read = mvme16x_read_clk, | ||
353 | .mask = CLOCKSOURCE_MASK(32), | ||
354 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
355 | }; | ||
356 | |||
357 | static u32 clk_total; | ||
358 | |||
359 | #define PCC_TIMER_CLOCK_FREQ 1000000 | ||
360 | #define PCC_TIMER_CYCLES (PCC_TIMER_CLOCK_FREQ / HZ) | ||
361 | |||
346 | static irqreturn_t mvme16x_timer_int (int irq, void *dev_id) | 362 | static irqreturn_t mvme16x_timer_int (int irq, void *dev_id) |
347 | { | 363 | { |
348 | irq_handler_t timer_routine = dev_id; | 364 | irq_handler_t timer_routine = dev_id; |
@@ -350,6 +366,7 @@ static irqreturn_t mvme16x_timer_int (int irq, void *dev_id) | |||
350 | 366 | ||
351 | local_irq_save(flags); | 367 | local_irq_save(flags); |
352 | *(volatile unsigned char *)0xfff4201b |= 8; | 368 | *(volatile unsigned char *)0xfff4201b |= 8; |
369 | clk_total += PCC_TIMER_CYCLES; | ||
353 | timer_routine(0, NULL); | 370 | timer_routine(0, NULL); |
354 | local_irq_restore(flags); | 371 | local_irq_restore(flags); |
355 | 372 | ||
@@ -363,13 +380,15 @@ void mvme16x_sched_init (irq_handler_t timer_routine) | |||
363 | 380 | ||
364 | /* Using PCCchip2 or MC2 chip tick timer 1 */ | 381 | /* Using PCCchip2 or MC2 chip tick timer 1 */ |
365 | *(volatile unsigned long *)0xfff42008 = 0; | 382 | *(volatile unsigned long *)0xfff42008 = 0; |
366 | *(volatile unsigned long *)0xfff42004 = 10000; /* 10ms */ | 383 | *(volatile unsigned long *)0xfff42004 = PCC_TIMER_CYCLES; |
367 | *(volatile unsigned char *)0xfff42017 |= 3; | 384 | *(volatile unsigned char *)0xfff42017 |= 3; |
368 | *(volatile unsigned char *)0xfff4201b = 0x16; | 385 | *(volatile unsigned char *)0xfff4201b = 0x16; |
369 | if (request_irq(MVME16x_IRQ_TIMER, mvme16x_timer_int, 0, "timer", | 386 | if (request_irq(MVME16x_IRQ_TIMER, mvme16x_timer_int, IRQF_TIMER, "timer", |
370 | timer_routine)) | 387 | timer_routine)) |
371 | panic ("Couldn't register timer int"); | 388 | panic ("Couldn't register timer int"); |
372 | 389 | ||
390 | clocksource_register_hz(&mvme16x_clk, PCC_TIMER_CLOCK_FREQ); | ||
391 | |||
373 | if (brdno == 0x0162 || brdno == 0x172) | 392 | if (brdno == 0x0162 || brdno == 0x172) |
374 | irq = MVME162_IRQ_ABORT; | 393 | irq = MVME162_IRQ_ABORT; |
375 | else | 394 | else |
@@ -379,11 +398,17 @@ void mvme16x_sched_init (irq_handler_t timer_routine) | |||
379 | panic ("Couldn't register abort int"); | 398 | panic ("Couldn't register abort int"); |
380 | } | 399 | } |
381 | 400 | ||
382 | 401 | static u64 mvme16x_read_clk(struct clocksource *cs) | |
383 | /* This is always executed with interrupts disabled. */ | ||
384 | u32 mvme16x_gettimeoffset(void) | ||
385 | { | 402 | { |
386 | return (*(volatile u32 *)0xfff42008) * 1000; | 403 | unsigned long flags; |
404 | u32 ticks; | ||
405 | |||
406 | local_irq_save(flags); | ||
407 | ticks = *(volatile u32 *)0xfff42008; | ||
408 | ticks += clk_total; | ||
409 | local_irq_restore(flags); | ||
410 | |||
411 | return ticks; | ||
387 | } | 412 | } |
388 | 413 | ||
389 | int bcd2int (unsigned char b) | 414 | int bcd2int (unsigned char b) |