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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [or32/] [kernel/] [time.c] - Blame information for rev 7

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7 xianfeng
/*
2
 *  linux/arch/or32/kernel/time.c
3
 *
4
 *  or32 version
5
 *
6
 *  Copied/hacked from:
7
 *
8
 *  linux/arch/m68knommu/kernel/time.c
9
 *
10
 *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
11
 *
12
 * This file contains the m68k-specific time handling details.
13
 * Most of the stuff is located in the machine specific files.
14
 */
15
 
16
#include <linux/kernel.h>
17
#include <linux/module.h>
18
#include <linux/errno.h>
19
#include <linux/init.h>
20
#include <linux/sched.h>
21
#include <linux/param.h>
22
#include <linux/string.h>
23
#include <linux/profile.h>
24
#include <linux/mm.h>
25
#include <linux/time.h>
26
#include <linux/timex.h>
27
#include <linux/interrupt.h>
28
 
29
#include <asm/machdep.h>
30
#include <asm/segment.h>
31
#include <asm/io.h>
32
#include <asm/or32-hf.h>
33
 
34
#define TICK_SIZE (tick_nsec / 1000)
35
 
36
extern unsigned long wall_jiffies;
37
 
38
 
39
static inline int set_rtc_mmss(unsigned long nowtime)
40
{
41
  if (mach_set_clock_mmss)
42
    return mach_set_clock_mmss (nowtime);
43
  return -1;
44
}
45
 
46
/* last time the RTC clock got updated */
47
static long last_rtc_update;
48
 
49
/*
50
 * timer_interrupt() needs to keep up the real-time clock,
51
 * as well as call the "do_timer()" routine every clocktick
52
 */
53
void do_timer_interrupt(struct pt_regs *regs)
54
{
55
       /* may need to kick the hardware timer */
56
       if (mach_tick)
57
         mach_tick();
58
 
59
       do_timer(1); /*RGD*/
60
 
61
#ifndef CONFIG_SMP
62
       update_process_times(user_mode(regs));
63
#endif
64
       /*profile_tick(CPU_PROFILING); RGD may be broken*/
65
 
66
       /*
67
        * If we have an externally synchronized Linux clock, then update
68
        * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
69
        * called as close as possible to 500 ms before the new second starts.
70
        */
71
#if 0 /*RGD*/
72
       if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
73
           (xtime.tv_nsec / 1000) > 500000 - ((unsigned)TICK_SIZE >> 1) &&
74
           (xtime.tv_nsec / 1000) < 500000 + ((unsigned)TICK_SIZE >> 1)) {
75
               if (set_rtc_mmss(xtime.tv_sec) == 0)
76
                       last_rtc_update = xtime.tv_sec;
77
               else
78
                       last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
79
       }
80
#endif /*RGD*/
81
 
82
       /*RGD from FRV*/
83
        /*
84
         * If we have an externally synchronized Linux clock, then update
85
         * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
86
         * called as close as possible to 500 ms before the new second starts.
87
         */
88
        if (ntp_synced() &&
89
            xtime.tv_sec > last_rtc_update + 660 &&
90
            (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
91
            (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2
92
            ) {
93
                if (set_rtc_mmss(xtime.tv_sec) == 0)
94
                        last_rtc_update = xtime.tv_sec;
95
                else
96
                        last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
97
        }
98
        /*RGD from FRV*/
99
}
100
 
101
 
102
/*
103
 * This get called at every clock tick...
104
 *
105
 */
106
irqreturn_t timer_interrupt(struct pt_regs * regs)
107
{
108
        check_stack(regs, __FILE__, __FUNCTION__, __LINE__);
109
 
110
        /*
111
         * Here we are in the timer irq handler. We just have irqs locally
112
         * disabled but we don't know if the timer_bh is running on the other
113
         * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
114
         * the irq version of write_lock because as just said we have irq
115
         * locally disabled. -arca
116
         */
117
        write_seqlock(&xtime_lock);
118
        do_timer_interrupt(regs);
119
        write_sequnlock(&xtime_lock);
120
 
121
        return IRQ_HANDLED;
122
}
123
 
124
/*
125
 * This version of gettimeofday has near microsecond resolution.
126
 *
127
 * Note: Division is quite slow on OR32 and do_gettimeofday is called
128
 *       rather often. Maybe we should do some kind of approximation here
129
 *       (a naive approximation would be to divide by 1024).
130
 */
131
void do_gettimeofday(struct timeval *tv)
132
{
133
        unsigned long flags;
134
        signed long usec, sec;
135
        local_irq_save(flags);
136
        local_irq_disable();
137
        usec = mach_gettimeoffset ? mach_gettimeoffset() : 0;
138
#if 0 /*RGD*/
139
        {
140
                unsigned long lost = jiffies - wall_jiffies;
141
                if (lost)
142
                  usec += lost * (1000000 / HZ);
143
        }
144
#endif /*RGD*/  
145
        /*
146
         * If time_adjust is negative then NTP is slowing the clock
147
         * so make sure not to go into next possible interval.
148
         * Better to lose some accuracy than have time go backwards..
149
         */
150
        if (unlikely(time_adjust < 0) && usec > tickadj)
151
          usec = tickadj;
152
 
153
        sec = xtime.tv_sec;
154
        usec += xtime.tv_nsec / 1000;
155
        local_irq_restore(flags);
156
 
157
        while (usec >= 1000000) {
158
                usec -= 1000000;
159
                sec++;
160
        }
161
 
162
        tv->tv_sec = sec;
163
        tv->tv_usec = usec;
164
}
165
 
166
EXPORT_SYMBOL(do_gettimeofday);
167
 
168
int do_settimeofday(struct timespec *tv)
169
{
170
        time_t wtm_sec, sec = tv->tv_sec;
171
        long wtm_nsec, nsec = tv->tv_nsec;
172
 
173
        if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
174
                return -EINVAL;
175
 
176
        write_seqlock_irq(&xtime_lock);
177
        /*
178
         * This is revolting. We need to set the xtime.tv_usec
179
         * correctly. However, the value in this location is
180
         * is value at the last tick.
181
         * Discover what correction gettimeofday
182
         * would have done, and then undo it!
183
         */
184
        if (mach_gettimeoffset)
185
                nsec -= (mach_gettimeoffset() * 1000);
186
 
187
        wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
188
        wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
189
 
190
        set_normalized_timespec(&xtime, sec, nsec);
191
        set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
192
 
193
        time_adjust = 0;         /* stop active adjtime() */
194
        time_status |= STA_UNSYNC;
195
        time_maxerror = NTP_PHASE_LIMIT;
196
        time_esterror = NTP_PHASE_LIMIT;
197
        write_sequnlock_irq(&xtime_lock);
198
        clock_was_set();
199
        return 0;
200
}
201
 
202
EXPORT_SYMBOL(do_settimeofday);
203
 
204
 
205
 
206
/*
207
 * Scheduler clock - returns current time in nanosec units.
208
 */
209
unsigned long long sched_clock(void)
210
{
211
        return (unsigned long long)jiffies * (1000000000 / HZ);
212
}
213
 
214
 
215
void __init time_init(void)
216
{
217
        unsigned int year, mon, day, hour, min, sec;
218
 
219
        extern void arch_gettod(int *year, int *mon, int *day, int *hour,
220
                                int *min, int *sec);
221
 
222
        arch_gettod (&year, &mon, &day, &hour, &min, &sec);
223
 
224
        if ((year += 1900) < 1970)
225
                year += 100;
226
        xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
227
        xtime.tv_nsec = 0;
228
 
229
 
230
        if (mach_sched_init)
231
                mach_sched_init();
232
}
233
 

powered by: WebSVN 2.1.0

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