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

Last change on this file since 715 was 675, checked in by Paul Smedley, 4 years ago

More code cleanups from AlexT from #os2russian

File size: 8.6 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
40#pragma pack(1)
41#include "infoseg.h"
42#pragma pack()
43extern PVOID KernSISData;
44#define KernSISData ((struct InfoSegGDT *)&KernSISData)
45
46static long jiffiems = 1000/HZ;
47static long lasttime = 0;
48unsigned long volatile jiffies = 0;
49
50//******************************************************************************
51//Timer handler that is called on each timer tick (32 times/second)
52//******************************************************************************
53void ALSA_TIMER()
54{
55 long delta, newtime, remainder;
56
57 newtime = KernSISData->SIS_MsCount;
58 delta = newtime - lasttime;
59
60 jiffies += delta/jiffiems;
61 remainder = delta%jiffiems;
62
63 lasttime = newtime - remainder;
64}
65//******************************************************************************
66//timeout is in 'jiffies', linux talk for units of 1000/HZ ms
67//******************************************************************************
68signed long schedule_timeout(signed long timeout)
69{
70 dprintf2(("schedule_timeout %d jiffies %x", timeout, jiffies));
71 mdelay(timeout*jiffiems);
72 return 0;
73}
74//******************************************************************************
75//iodelay is in 500ns units
76void iodelay32(unsigned long);
77#pragma aux iodelay32 parm nomemory [ecx] modify nomemory exact [eax ecx];
78//******************************************************************************
79//microsecond delay
80//******************************************************************************
81void __udelay(unsigned long usecs)
82{
83 if(usecs == 0) {
84 DebugInt3();
85 usecs = 1;
86 }
87 iodelay32(usecs*2);
88}
89//******************************************************************************
90//millisecond delay
91//******************************************************************************
92void mdelay(unsigned long msecs)
93{
94 if(msecs == 0) {
95 DebugInt3();
96 msecs = 1;
97 }
98 iodelay32(msecs*2*1000);
99}
100//******************************************************************************
101//******************************************************************************
102void do_gettimeofday(struct timeval *tv)
103{
104#if 0
105 tv->tv_sec = 0; //KernSISData->SIS_BigTime;
106 tv->tv_usec = KernSISData->SIS_MsCount * 1000;
107#else /* r.ihle patch */
108 unsigned u = KernSISData->SIS_MsCount;
109 tv->tv_sec = u / 1000;
110 tv->tv_usec = (u % 1000) * 1000;
111#endif
112}
113//******************************************************************************
114//******************************************************************************
115void add_timer(struct timer_list * timer)
116{
117
118}
119//******************************************************************************
120//******************************************************************************
121int del_timer(struct timer_list * timer)
122{
123 return 0;
124}
125//******************************************************************************
126/*
127 * mod_timer is a more efficient way to update the expire field of an
128 * active timer (if the timer is inactive it will be activated)
129 * mod_timer(a,b) is equivalent to del_timer(a); a->expires = b; add_timer(a)
130 */
131void mod_timer(struct timer_list *timer, unsigned long expires)
132{
133
134}
135//******************************************************************************
136//******************************************************************************
137#include <linux/delay.h>
138void msleep(unsigned int msecs)
139{
140 unsigned long timeout = ((msecs) * HZ + 999) / 1000;
141
142 while (timeout) {
143 set_current_state(TASK_UNINTERRUPTIBLE);
144 timeout = schedule_timeout(timeout);
145 }
146}
147
148//******************************************************************************
149//******************************************************************************
150
151/**
152 * ns_to_timespec - Convert nanoseconds to timespec
153 * @nsec: the nanoseconds value to be converted
154 *
155 * Returns the timespec representation of the nsec parameter.
156 */
157struct timespec ns_to_timespec(const s64 nsec)
158{
159 struct timespec ts;
160 s32 rem;
161
162 if (!nsec) {
163 ts.tv_sec = 0;
164 ts.tv_nsec = 0;
165 return ts;
166 }
167
168 ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);
169 if (unlikely(rem < 0)) {
170 ts.tv_sec--;
171 rem += NSEC_PER_SEC;
172 }
173 ts.tv_nsec = rem;
174
175 return ts;
176}
177
178
179//******************************************************************************
180//******************************************************************************
181
182/**
183 * ns_to_timespec - Convert nanoseconds to timespec
184 * @nsec: the nanoseconds value to be converted
185 *
186 * Returns the timespec representation of the nsec parameter.
187 */
188struct timespec64 ns_to_timespec64(const s64 nsec)
189{
190 struct timespec64 ts;
191 s32 rem;
192
193 if (!nsec) {
194 ts.tv_sec = 0;
195 ts.tv_nsec = 0;
196 return ts;
197 }
198
199 ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);
200 if (unlikely(rem < 0)) {
201 ts.tv_sec--;
202 rem += NSEC_PER_SEC;
203 }
204 ts.tv_nsec = rem;
205
206 return ts;
207}
208//******************************************************************************
209//******************************************************************************
210
211void timecounter_init(struct timecounter *tc,
212 const struct cyclecounter *cc,
213 u64 start_tstamp)
214{
215 tc->cc = cc;
216 tc->cycle_last = cc->read(cc);
217 tc->nsec = start_tstamp;
218}
219
220/**
221 * timecounter_read_delta - get nanoseconds since last call of this function
222 * @tc: Pointer to time counter
223 *
224 * When the underlying cycle counter runs over, this will be handled
225 * correctly as long as it does not run over more than once between
226 * calls.
227 *
228 * The first call to this function for a new time counter initializes
229 * the time tracking and returns an undefined result.
230 */
231static u64 timecounter_read_delta(struct timecounter *tc)
232{
233 cycle_t cycle_now, cycle_delta;
234 u64 ns_offset;
235
236 /* read cycle counter: */
237 cycle_now = tc->cc->read(tc->cc);
238
239 /* calculate the delta since the last timecounter_read_delta(): */
240 cycle_delta = (cycle_now - tc->cycle_last) & tc->cc->mask;
241
242 /* convert to nanoseconds: */
243 ns_offset = cyclecounter_cyc2ns(tc->cc, cycle_delta);
244
245 /* update time stamp of timecounter_read_delta() call: */
246 tc->cycle_last = cycle_now;
247
248 return ns_offset;
249}
250
251u64 timecounter_read(struct timecounter *tc)
252{
253 u64 nsec;
254
255 /* increment time by nanoseconds since last call */
256 nsec = timecounter_read_delta(tc);
257 nsec += tc->nsec;
258 tc->nsec = nsec;
259
260 return nsec;
261}
262
263/**
264 * set_normalized_timespec - set timespec sec and nsec parts and normalize
265 *
266 * @ts: pointer to timespec variable to be set
267 * @sec: seconds to set
268 * @nsec: nanoseconds to set
269 *
270 * Set seconds and nanoseconds field of a timespec variable and
271 * normalize to the timespec storage format
272 *
273 * Note: The tv_nsec part is always in the range of
274 * 0 <= tv_nsec < NSEC_PER_SEC
275 * For negative values only the tv_sec field is negative !
276 */
277void set_normalized_timespec64(struct timespec64 *ts, time64_t sec, s64 nsec)
278{
279 while (nsec >= NSEC_PER_SEC) {
280 /*
281 * The following asm() prevents the compiler from
282 * optimising this loop into a modulo operation. See
283 * also __iter_div_u64_rem() in include/linux/time.h
284 */
285// asm("" : "+rm"(nsec));
286 nsec -= NSEC_PER_SEC;
287 ++sec;
288 }
289 while (nsec < 0) {
290// asm("" : "+rm"(nsec));
291 nsec += NSEC_PER_SEC;
292 --sec;
293 }
294 ts->tv_sec = sec;
295 ts->tv_nsec = nsec;
296}
Note: See TracBrowser for help on using the repository browser.