aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel/time.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-10-08 15:26:00 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-08 15:26:00 -0400
commitff3df54efacff4ecdcab32826e45798453eecf90 (patch)
tree9eef08a9092f88d6bf11fb039cb95546642eab39 /arch/parisc/kernel/time.c
parentc7111c1318ee8890f385813f232fdb32643e2653 (diff)
parentc7753f18711782738936f224aaa421468e87f6ed (diff)
Merge branch 'irq-fixes' of git://git.parisc-linux.org/git/linux-2.6
* 'irq-fixes' of git://git.parisc-linux.org/git/linux-2.6: [PARISC] More pt_regs removal [PARISC] pdc_init no longer exists [PARISC] Make firmware calls irqsafe-ish... [PA-RISC] Fix boot breakage [PARISC] Use set_irq_regs
Diffstat (limited to 'arch/parisc/kernel/time.c')
-rw-r--r--arch/parisc/kernel/time.c32
1 files changed, 16 insertions, 16 deletions
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index b44839203e69..bad7d1eb62b9 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -34,10 +34,6 @@
34 34
35static unsigned long clocktick __read_mostly; /* timer cycles per tick */ 35static unsigned long clocktick __read_mostly; /* timer cycles per tick */
36 36
37#ifdef CONFIG_SMP
38extern void smp_do_timer(struct pt_regs *regs);
39#endif
40
41/* 37/*
42 * We keep time on PA-RISC Linux by using the Interval Timer which is 38 * We keep time on PA-RISC Linux by using the Interval Timer which is
43 * a pair of registers; one is read-only and one is write-only; both 39 * a pair of registers; one is read-only and one is write-only; both
@@ -55,13 +51,14 @@ extern void smp_do_timer(struct pt_regs *regs);
55 * held off for an arbitrarily long period of time by interrupts being 51 * held off for an arbitrarily long period of time by interrupts being
56 * disabled, so we may miss one or more ticks. 52 * disabled, so we may miss one or more ticks.
57 */ 53 */
58irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) 54irqreturn_t timer_interrupt(int irq, void *dev_id)
59{ 55{
60 unsigned long now; 56 unsigned long now;
61 unsigned long next_tick; 57 unsigned long next_tick;
62 unsigned long cycles_elapsed, ticks_elapsed; 58 unsigned long cycles_elapsed, ticks_elapsed;
63 unsigned long cycles_remainder; 59 unsigned long cycles_remainder;
64 unsigned int cpu = smp_processor_id(); 60 unsigned int cpu = smp_processor_id();
61 struct cpuinfo_parisc *cpuinfo = &cpu_data[cpu];
65 62
66 /* gcc can optimize for "read-only" case with a local clocktick */ 63 /* gcc can optimize for "read-only" case with a local clocktick */
67 unsigned long cpt = clocktick; 64 unsigned long cpt = clocktick;
@@ -69,7 +66,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
69 profile_tick(CPU_PROFILING); 66 profile_tick(CPU_PROFILING);
70 67
71 /* Initialize next_tick to the expected tick time. */ 68 /* Initialize next_tick to the expected tick time. */
72 next_tick = cpu_data[cpu].it_value; 69 next_tick = cpuinfo->it_value;
73 70
74 /* Get current interval timer. 71 /* Get current interval timer.
75 * CR16 reads as 64 bits in CPU wide mode. 72 * CR16 reads as 64 bits in CPU wide mode.
@@ -120,7 +117,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
120 */ 117 */
121 next_tick = now + cycles_remainder; 118 next_tick = now + cycles_remainder;
122 119
123 cpu_data[cpu].it_value = next_tick; 120 cpuinfo->it_value = next_tick;
124 121
125 /* Skip one clocktick on purpose if we are likely to miss next_tick. 122 /* Skip one clocktick on purpose if we are likely to miss next_tick.
126 * We want to avoid the new next_tick being less than CR16. 123 * We want to avoid the new next_tick being less than CR16.
@@ -131,18 +128,19 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
131 next_tick += cpt; 128 next_tick += cpt;
132 129
133 /* Program the IT when to deliver the next interrupt. */ 130 /* Program the IT when to deliver the next interrupt. */
134 /* Only bottom 32-bits of next_tick are written to cr16. */ 131 /* Only bottom 32-bits of next_tick are written to cr16. */
135 mtctl(next_tick, 16); 132 mtctl(next_tick, 16);
136 133
137 134
138 /* Done mucking with unreliable delivery of interrupts. 135 /* Done mucking with unreliable delivery of interrupts.
139 * Go do system house keeping. 136 * Go do system house keeping.
140 */ 137 */
141#ifdef CONFIG_SMP 138
142 smp_do_timer(regs); 139 if (!--cpuinfo->prof_counter) {
143#else 140 cpuinfo->prof_counter = cpuinfo->prof_multiplier;
144 update_process_times(user_mode(regs)); 141 update_process_times(user_mode(get_irq_regs()));
145#endif 142 }
143
146 if (cpu == 0) { 144 if (cpu == 0) {
147 write_seqlock(&xtime_lock); 145 write_seqlock(&xtime_lock);
148 do_timer(ticks_elapsed); 146 do_timer(ticks_elapsed);
@@ -319,13 +317,15 @@ void __init time_init(void)
319 317
320 start_cpu_itimer(); /* get CPU 0 started */ 318 start_cpu_itimer(); /* get CPU 0 started */
321 319
322 if(pdc_tod_read(&tod_data) == 0) { 320 if (pdc_tod_read(&tod_data) == 0) {
323 write_seqlock_irq(&xtime_lock); 321 unsigned long flags;
322
323 write_seqlock_irqsave(&xtime_lock, flags);
324 xtime.tv_sec = tod_data.tod_sec; 324 xtime.tv_sec = tod_data.tod_sec;
325 xtime.tv_nsec = tod_data.tod_usec * 1000; 325 xtime.tv_nsec = tod_data.tod_usec * 1000;
326 set_normalized_timespec(&wall_to_monotonic, 326 set_normalized_timespec(&wall_to_monotonic,
327 -xtime.tv_sec, -xtime.tv_nsec); 327 -xtime.tv_sec, -xtime.tv_nsec);
328 write_sequnlock_irq(&xtime_lock); 328 write_sequnlock_irqrestore(&xtime_lock, flags);
329 } else { 329 } else {
330 printk(KERN_ERR "Error reading tod clock\n"); 330 printk(KERN_ERR "Error reading tod clock\n");
331 xtime.tv_sec = 0; 331 xtime.tv_sec = 0;