Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c
new file mode 100644
index 0000000..3c47072
--- /dev/null
+++ b/arch/m32r/kernel/time.c
@@ -0,0 +1,318 @@
+/*
+ *  linux/arch/m32r/kernel/time.c
+ *
+ *  Copyright (c) 2001, 2002  Hiroyuki Kondo, Hirokazu Takata,
+ *                            Hitoshi Yamamoto
+ *  Taken from i386 version.
+ *    Copyright (C) 1991, 1992, 1995  Linus Torvalds
+ *    Copyright (C) 1996, 1997, 1998  Ralf Baechle
+ *
+ *  This file contains the time handling details for PC-style clocks as
+ *  found in some MIPS systems.
+ *
+ *  Some code taken from sh version.
+ *    Copyright (C) 1999  Tetsuya Okada & Niibe Yutaka
+ *    Copyright (C) 2000  Philipp Rumpf <prumpf@tux.org>
+ */
+
+#undef  DEBUG_TIMER
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/profile.h>
+
+#include <asm/io.h>
+#include <asm/m32r.h>
+
+#include <asm/hw_irq.h>
+
+#ifdef CONFIG_SMP
+extern void send_IPI_allbutself(int, int);
+extern void smp_local_timer_interrupt(struct pt_regs *);
+#endif
+
+u64 jiffies_64 = INITIAL_JIFFIES;
+
+EXPORT_SYMBOL(jiffies_64);
+
+extern unsigned long wall_jiffies;
+#define TICK_SIZE	(tick_nsec / 1000)
+
+/*
+ * Change this if you have some constant time drift
+ */
+
+/* This is for machines which generate the exact clock. */
+#define USECS_PER_JIFFY (1000000/HZ)
+
+static unsigned long latch;
+
+static unsigned long do_gettimeoffset(void)
+{
+	unsigned long  elapsed_time = 0;  /* [us] */
+
+#if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \
+	|| defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \
+	|| defined(CONFIG_CHIP_OPSP)
+#ifndef CONFIG_SMP
+
+	unsigned long count;
+
+	/* timer count may underflow right here */
+	count = inl(M32R_MFT2CUT_PORTL);
+
+	if (inl(M32R_ICU_CR18_PORTL) & 0x00000100)	/* underflow check */
+		count = 0;
+
+	count = (latch - count) * TICK_SIZE;
+	elapsed_time = (count + latch / 2) / latch;
+	/* NOTE: LATCH is equal to the "interval" value (= reload count). */
+
+#else /* CONFIG_SMP */
+	unsigned long count;
+	static unsigned long p_jiffies = -1;
+	static unsigned long p_count = 0;
+
+	/* timer count may underflow right here */
+	count = inl(M32R_MFT2CUT_PORTL);
+
+	if (jiffies == p_jiffies && count > p_count)
+		count = 0;
+
+	p_jiffies = jiffies;
+	p_count = count;
+
+	count = (latch - count) * TICK_SIZE;
+	elapsed_time = (count + latch / 2) / latch;
+	/* NOTE: LATCH is equal to the "interval" value (= reload count). */
+#endif /* CONFIG_SMP */
+#elif defined(CONFIG_CHIP_M32310)
+#warning do_gettimeoffse not implemented
+#else
+#error no chip configuration
+#endif
+
+	return elapsed_time;
+}
+
+/*
+ * This version of gettimeofday has near microsecond resolution.
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+	unsigned long seq;
+	unsigned long usec, sec;
+	unsigned long max_ntp_tick = tick_usec - tickadj;
+
+	do {
+		unsigned long lost;
+
+		seq = read_seqbegin(&xtime_lock);
+
+		usec = do_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(&xtime_lock, seq));
+
+	while (usec >= 1000000) {
+		usec -= 1000000;
+		sec++;
+	}
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+EXPORT_SYMBOL(do_gettimeofday);
+
+int do_settimeofday(struct timespec *tv)
+{
+	time_t wtm_sec, sec = tv->tv_sec;
+ 	long wtm_nsec, nsec = tv->tv_nsec;
+
+	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
+		return -EINVAL;
+
+	write_seqlock_irq(&xtime_lock);
+	/*
+	 * This is revolting. We need to set "xtime" correctly. However, the
+	 * value in this location is the value at the most recent update of
+	 * wall time.  Discover what correction gettimeofday() would have
+	 * made, and then undo it!
+	 */
+	nsec -= do_gettimeoffset() * NSEC_PER_USEC;
+	nsec -= (jiffies - wall_jiffies) * TICK_NSEC;
+
+	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);
+
+	time_adjust = 0;		/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+	write_sequnlock_irq(&xtime_lock);
+	clock_was_set();
+
+	return 0;
+}
+
+EXPORT_SYMBOL(do_settimeofday);
+
+/*
+ * In order to set the CMOS clock precisely, set_rtc_mmss has to be
+ * called 500 ms after the second nowtime has started, because when
+ * nowtime is written into the registers of the CMOS clock, it will
+ * jump to the next second precisely 500 ms later. Check the Motorola
+ * MC146818A or Dallas DS12887 data sheet for details.
+ *
+ * BUG: This routine does not handle hour overflow properly; it just
+ *      sets the minutes. Usually you won't notice until after reboot!
+ */
+static inline int set_rtc_mmss(unsigned long nowtime)
+{
+	return 0;
+}
+
+/* last time the cmos clock got updated */
+static long last_rtc_update = 0;
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+static inline void
+do_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+#ifndef CONFIG_SMP
+	profile_tick(CPU_PROFILING, regs);
+#endif
+	do_timer(regs);
+
+#ifndef CONFIG_SMP
+	update_process_times(user_mode(regs));
+#endif
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	if ((time_status & STA_UNSYNC) == 0
+		&& xtime.tv_sec > last_rtc_update + 660
+		&& (xtime.tv_nsec / 1000) >= 500000 - ((unsigned)TICK_SIZE) / 2
+		&& (xtime.tv_nsec / 1000) <= 500000 + ((unsigned)TICK_SIZE) / 2)
+	{
+		if (set_rtc_mmss(xtime.tv_sec) == 0)
+			last_rtc_update = xtime.tv_sec;
+		else	/* do it again in 60 s */
+			last_rtc_update = xtime.tv_sec - 600;
+	}
+	/* As we return to user mode fire off the other CPU schedulers..
+	   this is basically because we don't yet share IRQ's around.
+	   This message is rigged to be safe on the 386 - basically it's
+	   a hack, so don't look closely for now.. */
+
+#ifdef CONFIG_SMP
+	smp_local_timer_interrupt(regs);
+#endif
+}
+
+irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	write_seqlock(&xtime_lock);
+	do_timer_interrupt(irq, NULL, regs);
+	write_sequnlock(&xtime_lock);
+
+	return IRQ_HANDLED;
+}
+
+struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE,
+			  "MFT2", NULL, NULL };
+
+void __init time_init(void)
+{
+	unsigned int epoch, year, mon, day, hour, min, sec;
+
+	sec = min = hour = day = mon = year = 0;
+	epoch = 0;
+
+	year = 23;
+	mon = 4;
+	day = 17;
+
+	/* Attempt to guess the epoch.  This is the same heuristic as in rtc.c
+	   so no stupid things will happen to timekeeping.  Who knows, maybe
+	   Ultrix also uses 1952 as epoch ...  */
+	if (year > 10 && year < 44)
+		epoch = 1980;
+	else if (year < 96)
+		epoch = 1952;
+	year += epoch;
+
+	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
+	xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
+	set_normalized_timespec(&wall_to_monotonic,
+		-xtime.tv_sec, -xtime.tv_nsec);
+
+#if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \
+	|| defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \
+	|| defined(CONFIG_CHIP_OPSP)
+
+	/* M32102 MFT setup */
+	setup_irq(M32R_IRQ_MFT2, &irq0);
+	{
+		unsigned long bus_clock;
+		unsigned short divide;
+
+		bus_clock = boot_cpu_data.bus_clock;
+		divide = boot_cpu_data.timer_divide;
+		latch = (bus_clock/divide + HZ / 2) / HZ;
+
+		printk("Timer start : latch = %ld\n", latch);
+
+		outl((M32R_MFTMOD_CC_MASK | M32R_MFTMOD_TCCR \
+			|M32R_MFTMOD_CSSEL011), M32R_MFT2MOD_PORTL);
+		outl(latch, M32R_MFT2RLD_PORTL);
+		outl(latch, M32R_MFT2CUT_PORTL);
+		outl(0, M32R_MFT2CMPRLD_PORTL);
+		outl((M32R_MFTCR_MFT2MSK|M32R_MFTCR_MFT2EN), M32R_MFTCR_PORTL);
+	}
+
+#elif defined(CONFIG_CHIP_M32310)
+#warning time_init not implemented
+#else
+#error no chip configuration
+#endif
+}
+
+/*
+ *  Scheduler clock - returns current time in nanosec units.
+ */
+unsigned long long sched_clock(void)
+{
+	return (unsigned long long)jiffies * (1000000000 / HZ);
+}