diff options
author | Vitaly Wool <vitalywool@gmail.com> | 2008-01-10 09:10:05 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2008-01-11 12:05:41 -0500 |
commit | 1b1c5f0d96eb05cf6cd4702dabf4e003eded08c2 (patch) | |
tree | 5be9a68c8ef5b6cad1f4e8bc63f1ff446eef9455 /arch/mips | |
parent | 320167182dc3e351d2608cb7dccde12a47e3f51d (diff) |
[MIPS] pnx8xxx: move to clocksource
This patch converts PNX8XXX system timer to clocksource restoring PNX8550
support back to live.
Signed-off-by: Vitaly Wool <vitalywool@gmail.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/philips/pnx8550/common/time.c | 109 |
1 files changed, 72 insertions, 37 deletions
diff --git a/arch/mips/philips/pnx8550/common/time.c b/arch/mips/philips/pnx8550/common/time.c index e818fd0f1584..6d494e0de3d9 100644 --- a/arch/mips/philips/pnx8550/common/time.c +++ b/arch/mips/philips/pnx8550/common/time.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/kernel_stat.h> | 22 | #include <linux/kernel_stat.h> |
23 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/module.h> | ||
26 | 25 | ||
27 | #include <asm/bootinfo.h> | 26 | #include <asm/bootinfo.h> |
28 | #include <asm/cpu.h> | 27 | #include <asm/cpu.h> |
@@ -41,11 +40,60 @@ static cycle_t hpt_read(void) | |||
41 | return read_c0_count2(); | 40 | return read_c0_count2(); |
42 | } | 41 | } |
43 | 42 | ||
43 | static struct clocksource pnx_clocksource = { | ||
44 | .name = "pnx8xxx", | ||
45 | .rating = 200, | ||
46 | .read = hpt_read, | ||
47 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
48 | }; | ||
49 | |||
44 | static void timer_ack(void) | 50 | static void timer_ack(void) |
45 | { | 51 | { |
46 | write_c0_compare(cpj); | 52 | write_c0_compare(cpj); |
47 | } | 53 | } |
48 | 54 | ||
55 | static irqreturn_t pnx8xxx_timer_interrupt(int irq, void *dev_id) | ||
56 | { | ||
57 | struct clock_event_device *c = dev_id; | ||
58 | |||
59 | /* clear MATCH, signal the event */ | ||
60 | c->event_handler(c); | ||
61 | |||
62 | return IRQ_HANDLED; | ||
63 | } | ||
64 | |||
65 | static struct irqaction pnx8xxx_timer_irq = { | ||
66 | .handler = pnx8xxx_timer_interrupt, | ||
67 | .flags = IRQF_DISABLED | IRQF_PERCPU, | ||
68 | .name = "pnx8xxx_timer", | ||
69 | }; | ||
70 | |||
71 | static irqreturn_t monotonic_interrupt(int irq, void *dev_id) | ||
72 | { | ||
73 | /* Timer 2 clear interrupt */ | ||
74 | write_c0_compare2(-1); | ||
75 | return IRQ_HANDLED; | ||
76 | } | ||
77 | |||
78 | static struct irqaction monotonic_irqaction = { | ||
79 | .handler = monotonic_interrupt, | ||
80 | .flags = IRQF_DISABLED, | ||
81 | .name = "Monotonic timer", | ||
82 | }; | ||
83 | |||
84 | static int pnx8xxx_set_next_event(unsigned long delta, | ||
85 | struct clock_event_device *evt) | ||
86 | { | ||
87 | write_c0_compare(delta); | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static struct clock_event_device pnx8xxx_clockevent = { | ||
92 | .name = "pnx8xxx_clockevent", | ||
93 | .features = CLOCK_EVT_FEAT_ONESHOT, | ||
94 | .set_next_event = pnx8xxx_set_next_event, | ||
95 | }; | ||
96 | |||
49 | /* | 97 | /* |
50 | * plat_time_init() - it does the following things: | 98 | * plat_time_init() - it does the following things: |
51 | * | 99 | * |
@@ -58,11 +106,34 @@ static void timer_ack(void) | |||
58 | 106 | ||
59 | __init void plat_time_init(void) | 107 | __init void plat_time_init(void) |
60 | { | 108 | { |
109 | unsigned int configPR; | ||
61 | unsigned int n; | 110 | unsigned int n; |
62 | unsigned int m; | 111 | unsigned int m; |
63 | unsigned int p; | 112 | unsigned int p; |
64 | unsigned int pow2p; | 113 | unsigned int pow2p; |
65 | 114 | ||
115 | clockevents_register_device(&pnx8xxx_clockevent); | ||
116 | clocksource_register(&pnx_clocksource); | ||
117 | |||
118 | setup_irq(PNX8550_INT_TIMER1, &pnx8xxx_timer_irq); | ||
119 | setup_irq(PNX8550_INT_TIMER2, &monotonic_irqaction); | ||
120 | |||
121 | /* Timer 1 start */ | ||
122 | configPR = read_c0_config7(); | ||
123 | configPR &= ~0x00000008; | ||
124 | write_c0_config7(configPR); | ||
125 | |||
126 | /* Timer 2 start */ | ||
127 | configPR = read_c0_config7(); | ||
128 | configPR &= ~0x00000010; | ||
129 | write_c0_config7(configPR); | ||
130 | |||
131 | /* Timer 3 stop */ | ||
132 | configPR = read_c0_config7(); | ||
133 | configPR |= 0x00000020; | ||
134 | write_c0_config7(configPR); | ||
135 | |||
136 | |||
66 | /* PLL0 sets MIPS clock (PLL1 <=> TM1, PLL6 <=> TM2, PLL5 <=> mem) */ | 137 | /* PLL0 sets MIPS clock (PLL1 <=> TM1, PLL6 <=> TM2, PLL5 <=> mem) */ |
67 | /* (but only if CLK_MIPS_CTL select value [bits 3:1] is 1: FIXME) */ | 138 | /* (but only if CLK_MIPS_CTL select value [bits 3:1] is 1: FIXME) */ |
68 | 139 | ||
@@ -87,42 +158,6 @@ __init void plat_time_init(void) | |||
87 | write_c0_count2(0); | 158 | write_c0_count2(0); |
88 | write_c0_compare2(0xffffffff); | 159 | write_c0_compare2(0xffffffff); |
89 | 160 | ||
90 | clocksource_mips.read = hpt_read; | ||
91 | mips_timer_ack = timer_ack; | ||
92 | } | ||
93 | |||
94 | static irqreturn_t monotonic_interrupt(int irq, void *dev_id) | ||
95 | { | ||
96 | /* Timer 2 clear interrupt */ | ||
97 | write_c0_compare2(-1); | ||
98 | return IRQ_HANDLED; | ||
99 | } | 161 | } |
100 | 162 | ||
101 | static struct irqaction monotonic_irqaction = { | ||
102 | .handler = monotonic_interrupt, | ||
103 | .flags = IRQF_DISABLED, | ||
104 | .name = "Monotonic timer", | ||
105 | }; | ||
106 | 163 | ||
107 | void __init plat_timer_setup(struct irqaction *irq) | ||
108 | { | ||
109 | int configPR; | ||
110 | |||
111 | setup_irq(PNX8550_INT_TIMER1, irq); | ||
112 | setup_irq(PNX8550_INT_TIMER2, &monotonic_irqaction); | ||
113 | |||
114 | /* Timer 1 start */ | ||
115 | configPR = read_c0_config7(); | ||
116 | configPR &= ~0x00000008; | ||
117 | write_c0_config7(configPR); | ||
118 | |||
119 | /* Timer 2 start */ | ||
120 | configPR = read_c0_config7(); | ||
121 | configPR &= ~0x00000010; | ||
122 | write_c0_config7(configPR); | ||
123 | |||
124 | /* Timer 3 stop */ | ||
125 | configPR = read_c0_config7(); | ||
126 | configPR |= 0x00000020; | ||
127 | write_c0_config7(configPR); | ||
128 | } | ||