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 ******************************************************************************/
21 static void timer_done(struct s_smc
*smc
, int restart
);
23 void smt_timer_init(struct s_smc
*smc
)
25 smc
->t
.st_queue
= NULL
;
26 smc
->t
.st_fast
.tm_active
= FALSE
;
27 smc
->t
.st_fast
.tm_next
= NULL
;
31 void smt_timer_stop(struct s_smc
*smc
, struct smt_timer
*timer
)
33 struct smt_timer
**prev
;
34 struct smt_timer
*tm
;
37 * remove timer from queue
39 timer
->tm_active
= FALSE
;
40 if (smc
->t
.st_queue
== timer
&& !timer
->tm_next
) {
43 for (prev
= &smc
->t
.st_queue
; (tm
= *prev
) ; prev
= &tm
->tm_next
) {
47 tm
->tm_next
->tm_delta
+= tm
->tm_delta
;
54 void smt_timer_start(struct s_smc
*smc
, struct smt_timer
*timer
, u_long time
,
57 struct smt_timer
**prev
;
58 struct smt_timer
*tm
;
61 time
/= 16 ; /* input is uS, clock ticks are 16uS */
64 smt_timer_stop(smc
,timer
) ;
66 timer
->tm_token
= token
;
67 timer
->tm_active
= TRUE
;
68 if (!smc
->t
.st_queue
) {
69 smc
->t
.st_queue
= timer
;
70 timer
->tm_next
= NULL
;
71 timer
->tm_delta
= time
;
81 * find position in queue
84 for (prev
= &smc
->t
.st_queue
; (tm
= *prev
) ; prev
= &tm
->tm_next
) {
85 if (delta
+ tm
->tm_delta
> time
) {
88 delta
+= tm
->tm_delta
;
93 timer
->tm_delta
= time
- delta
;
95 tm
->tm_delta
-= timer
->tm_delta
;
97 * start new with first
99 hwt_start(smc
,smc
->t
.st_queue
->tm_delta
) ;
102 void smt_force_irq(struct s_smc
*smc
)
104 smt_timer_start(smc
,&smc
->t
.st_fast
,32L, EV_TOKEN(EVENT_SMT
,SM_FAST
));
107 void smt_timer_done(struct s_smc
*smc
)
112 static void timer_done(struct s_smc
*smc
, int restart
)
115 struct smt_timer
*tm
;
116 struct smt_timer
*next
;
117 struct smt_timer
**last
;
120 delta
= hwt_read(smc
) ;
121 last
= &smc
->t
.st_queue
;
122 tm
= smc
->t
.st_queue
;
123 while (tm
&& !done
) {
124 if (delta
>= tm
->tm_delta
) {
125 tm
->tm_active
= FALSE
;
126 delta
-= tm
->tm_delta
;
127 last
= &tm
->tm_next
;
131 tm
->tm_delta
-= delta
;
137 next
= smc
->t
.st_queue
;
138 smc
->t
.st_queue
= tm
;
140 for ( tm
= next
; tm
; tm
= next
) {
142 timer_event(smc
,tm
->tm_token
) ;
145 if (restart
&& smc
->t
.st_queue
)
146 hwt_start(smc
,smc
->t
.st_queue
->tm_delta
) ;