OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [m68k/] [kernel/] [time.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1623 jcastillo
/*
2
 *  linux/arch/m68k/kernel/time.c
3
 *
4
 *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
5
 *
6
 * This file contains the m68k-specific time handling details.
7
 * Most of the stuff is located in the machine specific files.
8
 */
9
 
10
#include <linux/errno.h>
11
#include <linux/sched.h>
12
#include <linux/kernel.h>
13
#include <linux/param.h>
14
#include <linux/string.h>
15
#include <linux/mm.h>
16
 
17
#include <asm/machdep.h>
18
#include <asm/segment.h>
19
#include <asm/io.h>
20
 
21
#include <linux/timex.h>
22
 
23
 
24
static inline int set_rtc_mmss(unsigned long nowtime)
25
{
26
  if (mach_set_clock_mmss)
27
    return mach_set_clock_mmss (nowtime);
28
  return -1;
29
}
30
 
31
/*
32
 * timer_interrupt() needs to keep up the real-time clock,
33
 * as well as call the "do_timer()" routine every clocktick
34
 */
35
static void timer_interrupt(int irq, struct pt_regs * regs, void *dummy)
36
{
37
        /* last time the cmos clock got updated */
38
        static long last_rtc_update=0;
39
 
40
        do_timer(regs);
41
 
42
        /*
43
         * If we have an externally synchronized Linux clock, then update
44
         * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
45
         * called as close as possible to 500 ms before the new second starts.
46
         */
47
        if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
48
            xtime.tv_usec > 500000 - (tick >> 1) &&
49
            xtime.tv_usec < 500000 + (tick >> 1))
50
          if (set_rtc_mmss(xtime.tv_sec) == 0)
51
            last_rtc_update = xtime.tv_sec;
52
          else
53
            last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
54
}
55
 
56
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
57
 * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
58
 * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
59
 *
60
 * [For the Julian calendar (which was used in Russia before 1917,
61
 * Britain & colonies before 1752, anywhere else before 1582,
62
 * and is still in use by some communities) leave out the
63
 * -year/100+year/400 terms, and add 10.]
64
 *
65
 * This algorithm was first published by Gauss (I think).
66
 *
67
 * WARNING: this function will overflow on 2106-02-07 06:28:16 on
68
 * machines were long is 32-bit! (However, as time_t is signed, we
69
 * will already get problems at other places on 2038-01-19 03:14:08)
70
 */
71
static inline unsigned long mktime(unsigned int year, unsigned int mon,
72
        unsigned int day, unsigned int hour,
73
        unsigned int min, unsigned int sec)
74
{
75
        if (0 >= (int) (mon -= 2)) {     /* 1..12 -> 11,12,1..10 */
76
                mon += 12;      /* Puts Feb last since it has leap day */
77
                year -= 1;
78
        }
79
        return (((
80
            (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
81
              year*365 - 719499
82
            )*24 + hour /* now have hours */
83
           )*60 + min /* now have minutes */
84
          )*60 + sec; /* finally seconds */
85
}
86
 
87
void time_init(void)
88
{
89
        unsigned int year, mon, day, hour, min, sec;
90
 
91
        extern void arch_gettod(int *year, int *mon, int *day, int *hour,
92
                                int *min, int *sec);
93
 
94
        arch_gettod (&year, &mon, &day, &hour, &min, &sec);
95
 
96
        if ((year += 1900) < 1970)
97
                year += 100;
98
        xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
99
        xtime.tv_usec = 0;
100
 
101
        mach_sched_init(timer_interrupt);
102
}
103
 
104
/*
105
 * This version of gettimeofday has near microsecond resolution.
106
 */
107
void do_gettimeofday(struct timeval *tv)
108
{
109
        unsigned long flags;
110
 
111
        save_flags(flags);
112
        cli();
113
        *tv = xtime;
114
        tv->tv_usec += mach_gettimeoffset();
115
        if (tv->tv_usec >= 1000000) {
116
                tv->tv_usec -= 1000000;
117
                tv->tv_sec++;
118
        }
119
        restore_flags(flags);
120
}
121
 
122
void do_settimeofday(struct timeval *tv)
123
{
124
        cli();
125
        /* This is revolting. We need to set the xtime.tv_usec
126
         * correctly. However, the value in this location is
127
         * is value at the last tick.
128
         * Discover what correction gettimeofday
129
         * would have done, and then undo it!
130
         */
131
        tv->tv_usec -= mach_gettimeoffset();
132
 
133
        if (tv->tv_usec < 0) {
134
                tv->tv_usec += 1000000;
135
                tv->tv_sec--;
136
        }
137
 
138
        xtime = *tv;
139
        time_state = TIME_BAD;
140
        time_maxerror = MAXPHASE;
141
        time_esterror = MAXPHASE;
142
        sti();
143
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.