diff options
author | john stultz <johnstul@us.ibm.com> | 2009-09-21 20:04:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-22 10:17:43 -0400 |
commit | 95ad759c6b0f30ad9aa5efbdbcecb9597238c00f (patch) | |
tree | 596e961f86340694d205b652de02c90a16546b90 | |
parent | d5a6d1739526ed8c383db3dabc232bc15603439a (diff) |
m32r: convert to use arch_gettimeoffset()
Convert m32r to use GENERIC_TIME via the arch_getoffset() infrastructure,
reducing the amount of arch specific code we need to maintain.
I also noted that m32r doesn't seem to be taking the xtime write lock
before calling do_timer()! That looks like a pretty bad bug to me. If
folks agree, let me know and I can move the lock grab to the correct spot.
Signed-off-by: John Stultz <johnstul@us.ibm.com>
Cc: Hirokazu Takata <takata@linux-m32r.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/m32r/Kconfig | 6 | ||||
-rw-r--r-- | arch/m32r/kernel/time.c | 74 |
2 files changed, 9 insertions, 71 deletions
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index cabba332cc48..c41234f1b825 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig | |||
@@ -41,6 +41,12 @@ config HZ | |||
41 | int | 41 | int |
42 | default 100 | 42 | default 100 |
43 | 43 | ||
44 | config GENERIC_TIME | ||
45 | def_bool y | ||
46 | |||
47 | config ARCH_USES_GETTIMEOFFSET | ||
48 | def_bool y | ||
49 | |||
44 | source "init/Kconfig" | 50 | source "init/Kconfig" |
45 | 51 | ||
46 | source "kernel/Kconfig.freezer" | 52 | source "kernel/Kconfig.freezer" |
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c index cada3ba4b990..ba61c4c73202 100644 --- a/arch/m32r/kernel/time.c +++ b/arch/m32r/kernel/time.c | |||
@@ -48,7 +48,7 @@ extern void smp_local_timer_interrupt(void); | |||
48 | 48 | ||
49 | static unsigned long latch; | 49 | static unsigned long latch; |
50 | 50 | ||
51 | static unsigned long do_gettimeoffset(void) | 51 | u32 arch_gettimeoffset(void) |
52 | { | 52 | { |
53 | unsigned long elapsed_time = 0; /* [us] */ | 53 | unsigned long elapsed_time = 0; /* [us] */ |
54 | 54 | ||
@@ -93,79 +93,10 @@ static unsigned long do_gettimeoffset(void) | |||
93 | #error no chip configuration | 93 | #error no chip configuration |
94 | #endif | 94 | #endif |
95 | 95 | ||
96 | return elapsed_time; | 96 | return elapsed_time * 1000; |
97 | } | 97 | } |
98 | 98 | ||
99 | /* | 99 | /* |
100 | * This version of gettimeofday has near microsecond resolution. | ||
101 | */ | ||
102 | void 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 | |||
134 | EXPORT_SYMBOL(do_gettimeofday); | ||
135 | |||
136 | int 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 | } | ||
165 | |||
166 | EXPORT_SYMBOL(do_settimeofday); | ||
167 | |||
168 | /* | ||
169 | * In order to set the CMOS clock precisely, set_rtc_mmss has to be | 100 | * 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 | 101 | * called 500 ms after the second nowtime has started, because when |
171 | * nowtime is written into the registers of the CMOS clock, it will | 102 | * nowtime is written into the registers of the CMOS clock, it will |
@@ -192,6 +123,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) | |||
192 | #ifndef CONFIG_SMP | 123 | #ifndef CONFIG_SMP |
193 | profile_tick(CPU_PROFILING); | 124 | profile_tick(CPU_PROFILING); |
194 | #endif | 125 | #endif |
126 | /* XXX FIXME. Uh, the xtime_lock should be held here, no? */ | ||
195 | do_timer(1); | 127 | do_timer(1); |
196 | 128 | ||
197 | #ifndef CONFIG_SMP | 129 | #ifndef CONFIG_SMP |