diff options
Diffstat (limited to 'arch/cris')
-rw-r--r-- | arch/cris/Kconfig | 6 | ||||
-rw-r--r-- | arch/cris/kernel/time.c | 68 |
2 files changed, 8 insertions, 66 deletions
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 7adac388a771..059eac6abda1 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig | |||
@@ -20,6 +20,12 @@ config RWSEM_GENERIC_SPINLOCK | |||
20 | config RWSEM_XCHGADD_ALGORITHM | 20 | config RWSEM_XCHGADD_ALGORITHM |
21 | bool | 21 | bool |
22 | 22 | ||
23 | config GENERIC_TIME | ||
24 | def_bool y | ||
25 | |||
26 | config ARCH_USES_GETTIMEOFFSET | ||
27 | def_bool y | ||
28 | |||
23 | config GENERIC_IOMAP | 29 | config GENERIC_IOMAP |
24 | bool | 30 | bool |
25 | default y | 31 | default y |
diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c index 074fe7dea96b..a05dd31f3efb 100644 --- a/arch/cris/kernel/time.c +++ b/arch/cris/kernel/time.c | |||
@@ -42,75 +42,11 @@ unsigned long loops_per_usec; | |||
42 | extern unsigned long do_slow_gettimeoffset(void); | 42 | extern unsigned long do_slow_gettimeoffset(void); |
43 | static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset; | 43 | static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset; |
44 | 44 | ||
45 | /* | 45 | u32 arch_gettimeoffset(void) |
46 | * This version of gettimeofday has near microsecond resolution. | ||
47 | * | ||
48 | * Note: Division is quite slow on CRIS and do_gettimeofday is called | ||
49 | * rather often. Maybe we should do some kind of approximation here | ||
50 | * (a naive approximation would be to divide by 1024). | ||
51 | */ | ||
52 | void do_gettimeofday(struct timeval *tv) | ||
53 | { | ||
54 | unsigned long flags; | ||
55 | signed long usec, sec; | ||
56 | local_irq_save(flags); | ||
57 | usec = do_gettimeoffset(); | ||
58 | |||
59 | /* | ||
60 | * If time_adjust is negative then NTP is slowing the clock | ||
61 | * so make sure not to go into next possible interval. | ||
62 | * Better to lose some accuracy than have time go backwards.. | ||
63 | */ | ||
64 | if (unlikely(time_adjust < 0) && usec > tickadj) | ||
65 | usec = tickadj; | ||
66 | |||
67 | sec = xtime.tv_sec; | ||
68 | usec += xtime.tv_nsec / 1000; | ||
69 | local_irq_restore(flags); | ||
70 | |||
71 | while (usec >= 1000000) { | ||
72 | usec -= 1000000; | ||
73 | sec++; | ||
74 | } | ||
75 | |||
76 | tv->tv_sec = sec; | ||
77 | tv->tv_usec = usec; | ||
78 | } | ||
79 | |||
80 | EXPORT_SYMBOL(do_gettimeofday); | ||
81 | |||
82 | int do_settimeofday(struct timespec *tv) | ||
83 | { | 46 | { |
84 | time_t wtm_sec, sec = tv->tv_sec; | 47 | return do_gettimeoffset() * 1000; |
85 | long wtm_nsec, nsec = tv->tv_nsec; | ||
86 | |||
87 | if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) | ||
88 | return -EINVAL; | ||
89 | |||
90 | write_seqlock_irq(&xtime_lock); | ||
91 | /* | ||
92 | * This is revolting. We need to set "xtime" correctly. However, the | ||
93 | * value in this location is the value at the most recent update of | ||
94 | * wall time. Discover what correction gettimeofday() would have | ||
95 | * made, and then undo it! | ||
96 | */ | ||
97 | nsec -= do_gettimeoffset() * NSEC_PER_USEC; | ||
98 | |||
99 | wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); | ||
100 | wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); | ||
101 | |||
102 | set_normalized_timespec(&xtime, sec, nsec); | ||
103 | set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); | ||
104 | |||
105 | ntp_clear(); | ||
106 | write_sequnlock_irq(&xtime_lock); | ||
107 | clock_was_set(); | ||
108 | return 0; | ||
109 | } | 48 | } |
110 | 49 | ||
111 | EXPORT_SYMBOL(do_settimeofday); | ||
112 | |||
113 | |||
114 | /* | 50 | /* |
115 | * BUG: This routine does not handle hour overflow properly; it just | 51 | * BUG: This routine does not handle hour overflow properly; it just |
116 | * sets the minutes. Usually you'll only notice that after reboot! | 52 | * sets the minutes. Usually you'll only notice that after reboot! |