aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/i8253.c
diff options
context:
space:
mode:
authorjohn stultz <johnstul@us.ibm.com>2006-06-26 03:25:12 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 12:58:21 -0400
commit5d0cf410e94b1f1ff852c3f210d22cc6c5a27ffa (patch)
treea30cd6d201295945f401fd1f2731493f68db9ee9 /arch/i386/kernel/i8253.c
parent61743fe445213b87fb55a389c8d073785323ca3e (diff)
[PATCH] Time: i386 Clocksource Drivers
Implement the time sources for i386 (acpi_pm, cyclone, hpet, pit, and tsc). With this patch, the conversion of the i386 arch to the generic timekeeping code should be complete. The patch should be fairly straight forward, only adding the new clocksources. [hirofumi@mail.parknet.co.jp: acpi_pm cleanup] Signed-off-by: John Stultz <johnstul@us.ibm.com> Signed-off-by: Adrian Bunk <bunk@stusta.de> Signed-off-by: Paul Mundt <lethal@linux-sh.org> Signed-off-by: John Stultz <johnstul@us.ibm.com> Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386/kernel/i8253.c')
-rw-r--r--arch/i386/kernel/i8253.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/arch/i386/kernel/i8253.c b/arch/i386/kernel/i8253.c
index 29cb2eb3436..a276bceade6 100644
--- a/arch/i386/kernel/i8253.c
+++ b/arch/i386/kernel/i8253.c
@@ -2,6 +2,7 @@
2 * i8253.c 8253/PIT functions 2 * i8253.c 8253/PIT functions
3 * 3 *
4 */ 4 */
5#include <linux/clocksource.h>
5#include <linux/spinlock.h> 6#include <linux/spinlock.h>
6#include <linux/jiffies.h> 7#include <linux/jiffies.h>
7#include <linux/sysdev.h> 8#include <linux/sysdev.h>
@@ -30,3 +31,55 @@ void setup_pit_timer(void)
30 outb(LATCH >> 8 , PIT_CH0); /* MSB */ 31 outb(LATCH >> 8 , PIT_CH0); /* MSB */
31 spin_unlock_irqrestore(&i8253_lock, flags); 32 spin_unlock_irqrestore(&i8253_lock, flags);
32} 33}
34
35/*
36 * Since the PIT overflows every tick, its not very useful
37 * to just read by itself. So use jiffies to emulate a free
38 * running counter:
39 */
40static cycle_t pit_read(void)
41{
42 unsigned long flags;
43 int count;
44 u64 jifs;
45
46 spin_lock_irqsave(&i8253_lock, flags);
47 outb_p(0x00, PIT_MODE); /* latch the count ASAP */
48 count = inb_p(PIT_CH0); /* read the latched count */
49 count |= inb_p(PIT_CH0) << 8;
50
51 /* VIA686a test code... reset the latch if count > max + 1 */
52 if (count > LATCH) {
53 outb_p(0x34, PIT_MODE);
54 outb_p(LATCH & 0xff, PIT_CH0);
55 outb(LATCH >> 8, PIT_CH0);
56 count = LATCH - 1;
57 }
58 spin_unlock_irqrestore(&i8253_lock, flags);
59
60 jifs = jiffies_64;
61
62 jifs -= INITIAL_JIFFIES;
63 count = (LATCH-1) - count;
64
65 return (cycle_t)(jifs * LATCH) + count;
66}
67
68static struct clocksource clocksource_pit = {
69 .name = "pit",
70 .rating = 110,
71 .read = pit_read,
72 .mask = (cycle_t)-1,
73 .mult = 0,
74 .shift = 20,
75};
76
77static int __init init_pit_clocksource(void)
78{
79 if (num_possible_cpus() > 4) /* PIT does not scale! */
80 return 0;
81
82 clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE, 20);
83 return register_clocksource(&clocksource_pit);
84}
85module_init(init_pit_clocksource);