1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /******************************************************************************
4 * (C)Copyright 1998,1999 SysKonnect,
5 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
7 * See the file "skfddi.c" for further information.
9 * The information in this file is provided "AS IS" without warranty.
11 ******************************************************************************/
22 static const char ID_sccs
[] = "@(#)smttimer.c 2.4 97/08/04 (C) SK " ;
25 static void timer_done(struct s_smc
*smc
, int restart
);
27 void smt_timer_init(struct s_smc
*smc
)
29 smc
->t
.st_queue
= NULL
;
30 smc
->t
.st_fast
.tm_active
= FALSE
;
31 smc
->t
.st_fast
.tm_next
= NULL
;
35 void smt_timer_stop(struct s_smc
*smc
, struct smt_timer
*timer
)
37 struct smt_timer
**prev
;
38 struct smt_timer
*tm
;
41 * remove timer from queue
43 timer
->tm_active
= FALSE
;
44 if (smc
->t
.st_queue
== timer
&& !timer
->tm_next
) {
47 for (prev
= &smc
->t
.st_queue
; (tm
= *prev
) ; prev
= &tm
->tm_next
) {
51 tm
->tm_next
->tm_delta
+= tm
->tm_delta
;
58 void smt_timer_start(struct s_smc
*smc
, struct smt_timer
*timer
, u_long time
,
61 struct smt_timer
**prev
;
62 struct smt_timer
*tm
;
65 time
/= 16 ; /* input is uS, clock ticks are 16uS */
68 smt_timer_stop(smc
,timer
) ;
70 timer
->tm_token
= token
;
71 timer
->tm_active
= TRUE
;
72 if (!smc
->t
.st_queue
) {
73 smc
->t
.st_queue
= timer
;
74 timer
->tm_next
= NULL
;
75 timer
->tm_delta
= time
;
85 * find position in queue
88 for (prev
= &smc
->t
.st_queue
; (tm
= *prev
) ; prev
= &tm
->tm_next
) {
89 if (delta
+ tm
->tm_delta
> time
) {
92 delta
+= tm
->tm_delta
;
97 timer
->tm_delta
= time
- delta
;
99 tm
->tm_delta
-= timer
->tm_delta
;
101 * start new with first
103 hwt_start(smc
,smc
->t
.st_queue
->tm_delta
) ;
106 void smt_force_irq(struct s_smc
*smc
)
108 smt_timer_start(smc
,&smc
->t
.st_fast
,32L, EV_TOKEN(EVENT_SMT
,SM_FAST
));
111 void smt_timer_done(struct s_smc
*smc
)
116 static void timer_done(struct s_smc
*smc
, int restart
)
119 struct smt_timer
*tm
;
120 struct smt_timer
*next
;
121 struct smt_timer
**last
;
124 delta
= hwt_read(smc
) ;
125 last
= &smc
->t
.st_queue
;
126 tm
= smc
->t
.st_queue
;
127 while (tm
&& !done
) {
128 if (delta
>= tm
->tm_delta
) {
129 tm
->tm_active
= FALSE
;
130 delta
-= tm
->tm_delta
;
131 last
= &tm
->tm_next
;
135 tm
->tm_delta
-= delta
;
141 next
= smc
->t
.st_queue
;
142 smc
->t
.st_queue
= tm
;
144 for ( tm
= next
; tm
; tm
= next
) {
146 timer_event(smc
,tm
->tm_token
) ;
149 if (restart
&& smc
->t
.st_queue
)
150 hwt_start(smc
,smc
->t
.st_queue
->tm_delta
) ;