aboutsummaryrefslogtreecommitdiff
path: root/arch/m68k/kernel/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68k/kernel/time.c')
-rw-r--r--arch/m68k/kernel/time.c129
1 files changed, 29 insertions, 100 deletions
diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
index 98e4b1adfa2..3857737e395 100644
--- a/arch/m68k/kernel/time.c
+++ b/arch/m68k/kernel/time.c
@@ -10,8 +10,8 @@
* "A Kernel Model for Precision Timekeeping" by Dave Mills
*/
-#include <linux/config.h> /* CONFIG_HEARTBEAT */
#include <linux/errno.h>
+#include <linux/export.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -19,32 +19,30 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/rtc.h>
+#include <linux/platform_device.h>
#include <asm/machdep.h>
#include <asm/io.h>
+#include <asm/irq_regs.h>
#include <linux/time.h>
#include <linux/timex.h>
#include <linux/profile.h>
-static inline int set_rtc_mmss(unsigned long nowtime)
-{
- if (mach_set_clock_mmss)
- return mach_set_clock_mmss (nowtime);
- return -1;
-}
+
+unsigned long (*mach_random_get_entropy)(void);
+EXPORT_SYMBOL_GPL(mach_random_get_entropy);
+
/*
* timer_interrupt() needs to keep up the real-time clock,
- * as well as call the "do_timer()" routine every clocktick
+ * as well as call the "xtime_update()" routine every clocktick
*/
-static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
+static irqreturn_t timer_interrupt(int irq, void *dummy)
{
- do_timer(regs);
-#ifndef CONFIG_SMP
- update_process_times(user_mode(regs));
-#endif
- profile_tick(CPU_PROFILING, regs);
+ xtime_update(1);
+ update_process_times(user_mode(get_irq_regs()));
+ profile_tick(CPU_PROFILING);
#ifdef CONFIG_HEARTBEAT
/* use power LED as a heartbeat instead -- much more useful
@@ -72,109 +70,40 @@ static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
return IRQ_HANDLED;
}
-void time_init(void)
+void read_persistent_clock(struct timespec *ts)
{
struct rtc_time time;
+ ts->tv_sec = 0;
+ ts->tv_nsec = 0;
if (mach_hwclk) {
mach_hwclk(0, &time);
if ((time.tm_year += 1900) < 1970)
time.tm_year += 100;
- xtime.tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday,
+ ts->tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday,
time.tm_hour, time.tm_min, time.tm_sec);
- xtime.tv_nsec = 0;
}
- wall_to_monotonic.tv_sec = -xtime.tv_sec;
-
- mach_sched_init(timer_interrupt);
}
-/*
- * This version of gettimeofday has near microsecond resolution.
- */
-void do_gettimeofday(struct timeval *tv)
-{
- unsigned long flags;
- extern unsigned long wall_jiffies;
- unsigned long seq;
- unsigned long usec, sec, lost;
- unsigned long max_ntp_tick = tick_usec - tickadj;
-
- do {
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
-
- usec = mach_gettimeoffset();
- lost = jiffies - wall_jiffies;
-
- /*
- * If time_adjust is negative then NTP is slowing the clock
- * so make sure not to go into next possible interval.
- * Better to lose some accuracy than have time go backwards..
- */
- if (unlikely(time_adjust < 0)) {
- usec = min(usec, max_ntp_tick);
-
- if (lost)
- usec += lost * max_ntp_tick;
- }
- else if (unlikely(lost))
- usec += lost * tick_usec;
-
- sec = xtime.tv_sec;
- usec += xtime.tv_nsec/1000;
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
-
- while (usec >= 1000000) {
- usec -= 1000000;
- sec++;
- }
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
+static int __init rtc_init(void)
+{
+ struct platform_device *pdev;
-EXPORT_SYMBOL(do_gettimeofday);
+ if (!mach_hwclk)
+ return -ENODEV;
-int do_settimeofday(struct timespec *tv)
-{
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
- extern unsigned long wall_jiffies;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irq(&xtime_lock);
- /* This is revolting. We need to set the xtime.tv_nsec
- * correctly. However, the value in this location is
- * is value at the last tick.
- * Discover what correction gettimeofday
- * would have done, and then undo it!
- */
- nsec -= 1000 * (mach_gettimeoffset() +
- (jiffies - wall_jiffies) * (1000000 / HZ));
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
- ntp_clear();
- write_sequnlock_irq(&xtime_lock);
- clock_was_set();
- return 0;
+ pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);
+ return PTR_ERR_OR_ZERO(pdev);
}
-EXPORT_SYMBOL(do_settimeofday);
+module_init(rtc_init);
-/*
- * Scheduler clock - returns current time in ns units.
- */
-unsigned long long sched_clock(void)
+#endif /* CONFIG_ARCH_USES_GETTIMEOFFSET */
+
+void __init time_init(void)
{
- return (unsigned long long)jiffies*(1000000000/HZ);
+ mach_sched_init(timer_interrupt);
}
-