source: GPL/branches/uniaud32-next/lib32/timer.c@ 660

Last change on this file since 660 was 629, checked in by Paul Smedley, 5 years ago

Update source to linux 5.10.4 level

File size: 8.4 KB
Line 
1/* $Id: timer.c,v 1.1.1.1 2003/07/02 13:57:04 eleph Exp $ */
2/*
3 * OS/2 implementation of Linux timer kernel functions
4 *
5 * (C) 2000-2002 InnoTek Systemberatung GmbH
6 * (C) 2000-2001 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
21 * USA.
22 *
23 */
24
25#include "linux.h"
26#include <linux/init.h>
27#include <linux/poll.h>
28#include <asm/uaccess.h>
29#include <asm/hardirq.h>
30#include <asm/io.h>
31#include <linux/time.h>
32#include <linux/math64.h>
33#include <linux/clocksource.h>
34
35#define LINUX
36#include <ossidc.h>
37#include <irqos2.h>
38#include <dbgos2.h>
39
40static long jiffiems = 1000/HZ;
41static long lasttime = 0;
42unsigned long volatile jiffies = 0;
43
44//******************************************************************************
45//Timer handler that is called on each timer tick (32 times/second)
46//******************************************************************************
47void ALSA_TIMER()
48{
49 long delta, newtime, remainder;
50
51 newtime = os2gettimemsec();
52 delta = newtime - lasttime;
53
54 jiffies += delta/jiffiems;
55 remainder = delta%jiffiems;
56
57 lasttime = newtime - remainder;
58}
59//******************************************************************************
60//timeout is in 'jiffies', linux talk for units of 1000/HZ ms
61//******************************************************************************
62signed long schedule_timeout(signed long timeout)
63{
64 dprintf2(("schedule_timeout %d jiffies %x", timeout, jiffies));
65 mdelay(timeout*jiffiems);
66 return 0;
67}
68//******************************************************************************
69//iodelay is in 500ns units
70void iodelay32(unsigned long);
71#pragma aux iodelay32 parm nomemory [ecx] modify nomemory exact [eax ecx];
72//******************************************************************************
73//microsecond delay
74//******************************************************************************
75void __udelay(unsigned long usecs)
76{
77 if(usecs == 0) {
78 DebugInt3();
79 usecs = 1;
80 }
81 iodelay32(usecs*2);
82}
83//******************************************************************************
84//millisecond delay
85//******************************************************************************
86void mdelay(unsigned long msecs)
87{
88 if(msecs == 0) {
89 DebugInt3();
90 msecs = 1;
91 }
92 iodelay32(msecs*2*1000);
93}
94//******************************************************************************
95//******************************************************************************
96void do_gettimeofday(struct timeval *tv)
97{
98#if 0
99 tv->tv_sec = 0; //os2gettimesec();
100 tv->tv_usec = os2gettimemsec() * 1000;
101#else /* r.ihle patch */
102 unsigned u = os2gettimemsec();
103 tv->tv_sec = u / 1000;
104 tv->tv_usec = (u % 1000) * 1000;
105#endif
106}
107//******************************************************************************
108//******************************************************************************
109void add_timer(struct timer_list * timer)
110{
111
112}
113//******************************************************************************
114//******************************************************************************
115int del_timer(struct timer_list * timer)
116{
117 return 0;
118}
119//******************************************************************************
120/*
121 * mod_timer is a more efficient way to update the expire field of an
122 * active timer (if the timer is inactive it will be activated)
123 * mod_timer(a,b) is equivalent to del_timer(a); a->expires = b; add_timer(a)
124 */
125void mod_timer(struct timer_list *timer, unsigned long expires)
126{
127
128}
129//******************************************************************************
130//******************************************************************************
131#include <linux/delay.h>
132void msleep(unsigned int msecs)
133{
134 unsigned long timeout = ((msecs) * HZ + 999) / 1000;
135
136 while (timeout) {
137 set_current_state(TASK_UNINTERRUPTIBLE);
138 timeout = schedule_timeout(timeout);
139 }
140}
141
142//******************************************************************************
143//******************************************************************************
144
145/**
146 * ns_to_timespec - Convert nanoseconds to timespec
147 * @nsec: the nanoseconds value to be converted
148 *
149 * Returns the timespec representation of the nsec parameter.
150 */
151struct timespec ns_to_timespec(const s64 nsec)
152{
153 struct timespec ts;
154 s32 rem;
155
156 if (!nsec) {
157 ts.tv_sec = 0;
158 ts.tv_nsec = 0;
159 return ts;
160 }
161
162 ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);
163 if (unlikely(rem < 0)) {
164 ts.tv_sec--;
165 rem += NSEC_PER_SEC;
166 }
167 ts.tv_nsec = rem;
168
169 return ts;
170}
171
172
173//******************************************************************************
174//******************************************************************************
175
176/**
177 * ns_to_timespec - Convert nanoseconds to timespec
178 * @nsec: the nanoseconds value to be converted
179 *
180 * Returns the timespec representation of the nsec parameter.
181 */
182struct timespec64 ns_to_timespec64(const s64 nsec)
183{
184 struct timespec64 ts;
185 s32 rem;
186
187 if (!nsec) {
188 ts.tv_sec = 0;
189 ts.tv_nsec = 0;
190 return ts;
191 }
192
193 ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);
194 if (unlikely(rem < 0)) {
195 ts.tv_sec--;
196 rem += NSEC_PER_SEC;
197 }
198 ts.tv_nsec = rem;
199
200 return ts;
201}
202//******************************************************************************
203//******************************************************************************
204
205void timecounter_init(struct timecounter *tc,
206 const struct cyclecounter *cc,
207 u64 start_tstamp)
208{
209 tc->cc = cc;
210 tc->cycle_last = cc->read(cc);
211 tc->nsec = start_tstamp;
212}
213
214/**
215 * timecounter_read_delta - get nanoseconds since last call of this function
216 * @tc: Pointer to time counter
217 *
218 * When the underlying cycle counter runs over, this will be handled
219 * correctly as long as it does not run over more than once between
220 * calls.
221 *
222 * The first call to this function for a new time counter initializes
223 * the time tracking and returns an undefined result.
224 */
225static u64 timecounter_read_delta(struct timecounter *tc)
226{
227 cycle_t cycle_now, cycle_delta;
228 u64 ns_offset;
229
230 /* read cycle counter: */
231 cycle_now = tc->cc->read(tc->cc);
232
233 /* calculate the delta since the last timecounter_read_delta(): */
234 cycle_delta = (cycle_now - tc->cycle_last) & tc->cc->mask;
235
236 /* convert to nanoseconds: */
237 ns_offset = cyclecounter_cyc2ns(tc->cc, cycle_delta);
238
239 /* update time stamp of timecounter_read_delta() call: */
240 tc->cycle_last = cycle_now;
241
242 return ns_offset;
243}
244
245u64 timecounter_read(struct timecounter *tc)
246{
247 u64 nsec;
248
249 /* increment time by nanoseconds since last call */
250 nsec = timecounter_read_delta(tc);
251 nsec += tc->nsec;
252 tc->nsec = nsec;
253
254 return nsec;
255}
256
257/**
258 * set_normalized_timespec - set timespec sec and nsec parts and normalize
259 *
260 * @ts: pointer to timespec variable to be set
261 * @sec: seconds to set
262 * @nsec: nanoseconds to set
263 *
264 * Set seconds and nanoseconds field of a timespec variable and
265 * normalize to the timespec storage format
266 *
267 * Note: The tv_nsec part is always in the range of
268 * 0 <= tv_nsec < NSEC_PER_SEC
269 * For negative values only the tv_sec field is negative !
270 */
271void set_normalized_timespec64(struct timespec64 *ts, time64_t sec, s64 nsec)
272{
273 while (nsec >= NSEC_PER_SEC) {
274 /*
275 * The following asm() prevents the compiler from
276 * optimising this loop into a modulo operation. See
277 * also __iter_div_u64_rem() in include/linux/time.h
278 */
279// asm("" : "+rm"(nsec));
280 nsec -= NSEC_PER_SEC;
281 ++sec;
282 }
283 while (nsec < 0) {
284// asm("" : "+rm"(nsec));
285 nsec += NSEC_PER_SEC;
286 --sec;
287 }
288 ts->tv_sec = sec;
289 ts->tv_nsec = nsec;
290}
Note: See TracBrowser for help on using the repository browser.