]> Git Repo - linux.git/blob - drivers/net/fddi/skfp/smttimer.c
ASoC: simple-card: Use snd_soc_of_parse_aux_devs()
[linux.git] / drivers / net / fddi / skfp / smttimer.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /******************************************************************************
3  *
4  *      (C)Copyright 1998,1999 SysKonnect,
5  *      a business unit of Schneider & Koch & Co. Datensysteme GmbH.
6  *
7  *      See the file "skfddi.c" for further information.
8  *
9  *      The information in this file is provided "AS IS" without warranty.
10  *
11  ******************************************************************************/
12
13 /*
14         SMT timer
15 */
16
17 #include "h/types.h"
18 #include "h/fddi.h"
19 #include "h/smc.h"
20
21 #ifndef lint
22 static const char ID_sccs[] = "@(#)smttimer.c   2.4 97/08/04 (C) SK " ;
23 #endif
24
25 static void timer_done(struct s_smc *smc, int restart);
26
27 void smt_timer_init(struct s_smc *smc)
28 {
29         smc->t.st_queue = NULL;
30         smc->t.st_fast.tm_active = FALSE ;
31         smc->t.st_fast.tm_next = NULL;
32         hwt_init(smc) ;
33 }
34
35 void smt_timer_stop(struct s_smc *smc, struct smt_timer *timer)
36 {
37         struct smt_timer        **prev ;
38         struct smt_timer        *tm ;
39
40         /*
41          * remove timer from queue
42          */
43         timer->tm_active = FALSE ;
44         if (smc->t.st_queue == timer && !timer->tm_next) {
45                 hwt_stop(smc) ;
46         }
47         for (prev = &smc->t.st_queue ; (tm = *prev) ; prev = &tm->tm_next ) {
48                 if (tm == timer) {
49                         *prev = tm->tm_next ;
50                         if (tm->tm_next) {
51                                 tm->tm_next->tm_delta += tm->tm_delta ;
52                         }
53                         return ;
54                 }
55         }
56 }
57
58 void smt_timer_start(struct s_smc *smc, struct smt_timer *timer, u_long time,
59                      u_long token)
60 {
61         struct smt_timer        **prev ;
62         struct smt_timer        *tm ;
63         u_long                  delta = 0 ;
64
65         time /= 16 ;            /* input is uS, clock ticks are 16uS */
66         if (!time)
67                 time = 1 ;
68         smt_timer_stop(smc,timer) ;
69         timer->tm_smc = smc ;
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 ;
76                 hwt_start(smc,time) ;
77                 return ;
78         }
79         /*
80          * timer correction
81          */
82         timer_done(smc,0) ;
83
84         /*
85          * find position in queue
86          */
87         delta = 0 ;
88         for (prev = &smc->t.st_queue ; (tm = *prev) ; prev = &tm->tm_next ) {
89                 if (delta + tm->tm_delta > time) {
90                         break ;
91                 }
92                 delta += tm->tm_delta ;
93         }
94         /* insert in queue */
95         *prev = timer ;
96         timer->tm_next = tm ;
97         timer->tm_delta = time - delta ;
98         if (tm)
99                 tm->tm_delta -= timer->tm_delta ;
100         /*
101          * start new with first
102          */
103         hwt_start(smc,smc->t.st_queue->tm_delta) ;
104 }
105
106 void smt_force_irq(struct s_smc *smc)
107 {
108         smt_timer_start(smc,&smc->t.st_fast,32L, EV_TOKEN(EVENT_SMT,SM_FAST)); 
109 }
110
111 void smt_timer_done(struct s_smc *smc)
112 {
113         timer_done(smc,1) ;
114 }
115
116 static void timer_done(struct s_smc *smc, int restart)
117 {
118         u_long                  delta ;
119         struct smt_timer        *tm ;
120         struct smt_timer        *next ;
121         struct smt_timer        **last ;
122         int                     done = 0 ;
123
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 ;
132                         tm = tm->tm_next ;
133                 }
134                 else {
135                         tm->tm_delta -= delta ;
136                         delta = 0 ;
137                         done = 1 ;
138                 }
139         }
140         *last = NULL;
141         next = smc->t.st_queue ;
142         smc->t.st_queue = tm ;
143
144         for ( tm = next ; tm ; tm = next) {
145                 next = tm->tm_next ;
146                 timer_event(smc,tm->tm_token) ;
147         }
148
149         if (restart && smc->t.st_queue)
150                 hwt_start(smc,smc->t.st_queue->tm_delta) ;
151 }
152
This page took 0.040429 seconds and 4 git commands to generate.