aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m32r/kernel/time.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2009-11-03 01:10:07 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2009-11-03 01:10:07 -0500
commit7a53c7f56bbfc9b0ef892e68f5cfae3d902544d1 (patch)
tree19dec256fc80ad06d631ece78b9eb68a457ce66b /arch/m32r/kernel/time.c
parente57130698fe3dd2b7d617d90bbf86474473cb40c (diff)
parent012abeea669ea49636cf952d13298bb68654146a (diff)
Merge commit 'v2.6.32-rc5' into for-linus
Diffstat (limited to 'arch/m32r/kernel/time.c')
-rw-r--r--arch/m32r/kernel/time.c83
1 files changed, 12 insertions, 71 deletions
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c
index cada3ba4b990..e7fee0f198d5 100644
--- a/arch/m32r/kernel/time.c
+++ b/arch/m32r/kernel/time.c
@@ -33,6 +33,15 @@
33 33
34#include <asm/hw_irq.h> 34#include <asm/hw_irq.h>
35 35
36#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
37/* this needs a better home */
38DEFINE_SPINLOCK(rtc_lock);
39
40#ifdef CONFIG_RTC_DRV_CMOS_MODULE
41EXPORT_SYMBOL(rtc_lock);
42#endif
43#endif /* pc-style 'CMOS' RTC support */
44
36#ifdef CONFIG_SMP 45#ifdef CONFIG_SMP
37extern void smp_local_timer_interrupt(void); 46extern void smp_local_timer_interrupt(void);
38#endif 47#endif
@@ -48,7 +57,7 @@ extern void smp_local_timer_interrupt(void);
48 57
49static unsigned long latch; 58static unsigned long latch;
50 59
51static unsigned long do_gettimeoffset(void) 60u32 arch_gettimeoffset(void)
52{ 61{
53 unsigned long elapsed_time = 0; /* [us] */ 62 unsigned long elapsed_time = 0; /* [us] */
54 63
@@ -93,78 +102,9 @@ static unsigned long do_gettimeoffset(void)
93#error no chip configuration 102#error no chip configuration
94#endif 103#endif
95 104
96 return elapsed_time; 105 return elapsed_time * 1000;
97}
98
99/*
100 * This version of gettimeofday has near microsecond resolution.
101 */
102void do_gettimeofday(struct timeval *tv)
103{
104 unsigned long seq;
105 unsigned long usec, sec;
106 unsigned long max_ntp_tick = tick_usec - tickadj;
107
108 do {
109 seq = read_seqbegin(&xtime_lock);
110
111 usec = do_gettimeoffset();
112
113 /*
114 * If time_adjust is negative then NTP is slowing the clock
115 * so make sure not to go into next possible interval.
116 * Better to lose some accuracy than have time go backwards..
117 */
118 if (unlikely(time_adjust < 0))
119 usec = min(usec, max_ntp_tick);
120
121 sec = xtime.tv_sec;
122 usec += (xtime.tv_nsec / 1000);
123 } while (read_seqretry(&xtime_lock, seq));
124
125 while (usec >= 1000000) {
126 usec -= 1000000;
127 sec++;
128 }
129
130 tv->tv_sec = sec;
131 tv->tv_usec = usec;
132}
133
134EXPORT_SYMBOL(do_gettimeofday);
135
136int do_settimeofday(struct timespec *tv)
137{
138 time_t wtm_sec, sec = tv->tv_sec;
139 long wtm_nsec, nsec = tv->tv_nsec;
140
141 if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
142 return -EINVAL;
143
144 write_seqlock_irq(&xtime_lock);
145 /*
146 * This is revolting. We need to set "xtime" correctly. However, the
147 * value in this location is the value at the most recent update of
148 * wall time. Discover what correction gettimeofday() would have
149 * made, and then undo it!
150 */
151 nsec -= do_gettimeoffset() * NSEC_PER_USEC;
152
153 wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
154 wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
155
156 set_normalized_timespec(&xtime, sec, nsec);
157 set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
158
159 ntp_clear();
160 write_sequnlock_irq(&xtime_lock);
161 clock_was_set();
162
163 return 0;
164} 106}
165 107
166EXPORT_SYMBOL(do_settimeofday);
167
168/* 108/*
169 * In order to set the CMOS clock precisely, set_rtc_mmss has to be 109 * In order to set the CMOS clock precisely, set_rtc_mmss has to be
170 * called 500 ms after the second nowtime has started, because when 110 * called 500 ms after the second nowtime has started, because when
@@ -192,6 +132,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
192#ifndef CONFIG_SMP 132#ifndef CONFIG_SMP
193 profile_tick(CPU_PROFILING); 133 profile_tick(CPU_PROFILING);
194#endif 134#endif
135 /* XXX FIXME. Uh, the xtime_lock should be held here, no? */
195 do_timer(1); 136 do_timer(1);
196 137
197#ifndef CONFIG_SMP 138#ifndef CONFIG_SMP