Setting up repository
[linux-libre-firmware.git] / ath9k_htc / sboot / magpie_1_1 / sboot / cmnos / tasklet / src / cmnos_tasklet.c
1 /*
2  * Copyright (c) 2013 Qualcomm Atheros, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted (subject to the limitations in the
7  * disclaimer below) provided that the following conditions are met:
8  *
9  *  * Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  *  * Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the
15  *    distribution.
16  *
17  *  * Neither the name of Qualcomm Atheros nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific prior written permission.
20  *
21  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
22  * GRANTED BY THIS LICENSE.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
23  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
24  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
33  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 #include "sys_cfg.h"
36
37 #include "athos_api.h"
38 #include "tasklet_api.h"
39
40 ////////////////////////////////////////////
41
42 typedef struct _tasklet_context {
43     A_tasklet_t *schedule_tasks;
44 } tasklet_context;
45
46 static tasklet_context g_tasklet_ctx;
47
48 /* Initialize timer software.  Called once during initialization. */
49 LOCAL void
50 cmnos_tasklet_init(void)
51 {
52     //timer_list = NULL;
53     g_tasklet_ctx.schedule_tasks = NULL;
54 }
55
56 LOCAL void 
57 cmnos_tasklet_init_task(A_TASKLET_FUNC fn, void * arg, A_tasklet_t *tasklet)
58 {
59     tasklet->func = fn;
60     tasklet->arg  = arg;
61     tasklet->next = NULL;
62     tasklet->state = A_TASKLET_STATE_DISABLE;
63 }
64
65 LOCAL void 
66 cmnos_tasklet_schedule(A_tasklet_t *tasklet)
67 {
68     if ( tasklet->state == A_TASKLET_STATE_SCHEDULED ) {
69         return;
70     }
71     
72     tasklet->state = A_TASKLET_STATE_SCHEDULED;
73     if ( g_tasklet_ctx.schedule_tasks == NULL ) {
74         g_tasklet_ctx.schedule_tasks = tasklet;
75     } else {
76         tasklet->next = g_tasklet_ctx.schedule_tasks;
77         g_tasklet_ctx.schedule_tasks = tasklet;
78     }
79 }
80
81 LOCAL void 
82 cmnos_tasklet_disable(A_tasklet_t *tasklet)
83 {
84     A_tasklet_t *tmp;
85     A_tasklet_t *prev = NULL;
86     
87     if ( tasklet->state != A_TASKLET_STATE_SCHEDULED ) {
88         return;
89     }
90         
91     tmp = g_tasklet_ctx.schedule_tasks;
92     while ( tmp != NULL ) {
93         if ( tmp == tasklet ) {
94             if ( prev == NULL ) {
95                 g_tasklet_ctx.schedule_tasks = NULL;
96             } else {
97                 prev->next = tmp->next;    
98             }
99             
100             tasklet->state = A_TASKLET_STATE_DISABLE;
101             break;
102         } else {
103             prev = tmp;
104             tmp = tmp->next;
105         }
106     }
107 }
108
109 LOCAL void
110 cmnos_tasklet_run(void)
111 {
112     A_tasklet_t *tmp;
113     
114     tmp = g_tasklet_ctx.schedule_tasks;
115     while ( tmp != NULL ) {
116         g_tasklet_ctx.schedule_tasks = tmp->next;
117         tmp->next = NULL;
118         
119         tmp->state = A_TASKLET_STATE_RUNNING;
120         tmp->func(tmp->arg);
121         tmp->state = A_TASKLET_STATE_DISABLE;
122         
123         tmp = g_tasklet_ctx.schedule_tasks;
124     }  
125     
126     g_tasklet_ctx.schedule_tasks = NULL;
127 }
128
129 void
130 cmnos_tasklet_module_install(struct tasklet_api *tbl)
131 {
132     tbl->_tasklet_init         = cmnos_tasklet_init;
133     tbl->_tasklet_init_task    = cmnos_tasklet_init_task;
134     tbl->_tasklet_disable      = cmnos_tasklet_disable;
135     tbl->_tasklet_schedule     = cmnos_tasklet_schedule;
136     tbl->_tasklet_run          = cmnos_tasklet_run;
137 }
138
139 //#define CMNOS_TASKLET_UT
140 #ifdef CMNOS_TASKLET_UT
141
142 #include <adf_os_defer.h>
143
144 adf_os_bh_t bh;
145 adf_os_bh_t bh2;
146
147 void test_tasklet(void *arg)
148 {
149     adf_os_bh_t *tmpBH = (adf_os_bh_t *)arg;
150     
151     if ( tmpBH == &bh ) 
152         adf_os_print("Tasklet1 running...\n");
153     else if ( tmpBH == &bh2 ) 
154         adf_os_print("Tasklet2 running...\n");       
155 }
156
157 void 
158 cmnos_tasklet_test()
159 {
160     adf_os_init_bh(NULL, &bh, test_tasklet, &bh);
161     adf_os_init_bh(NULL, &bh2, test_tasklet, &bh2);
162         
163     adf_os_sched_bh(NULL, &bh);
164     adf_os_sched_bh(NULL, &bh2);    
165 }
166
167 #endif
168
169
170