• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 
19 #include "hi_osal.h"
20 #include <linux/module.h>
21 #include <linux/kernel.h>
22 #include <linux/printk.h>
23 #include <linux/wait.h>
24 #include <linux/sched.h>
25 #include <linux/sched/signal.h>
26 #include <linux/slab.h>
27 
osal_msecs_to_jiffies(const unsigned int m)28 unsigned long osal_msecs_to_jiffies(const unsigned int m)
29 {
30     return msecs_to_jiffies(m);
31 }
32 EXPORT_SYMBOL(osal_msecs_to_jiffies);
33 
osal_wait_init(osal_wait_t * wait)34 int osal_wait_init(osal_wait_t *wait)
35 {
36     wait_queue_head_t *wq = NULL;
37     if (wait == NULL) {
38         osal_trace("%s - parameter invalid!\n", __FUNCTION__);
39         return -1;
40     }
41     wq = (wait_queue_head_t *)kmalloc(sizeof(wait_queue_head_t), GFP_ATOMIC);
42     if (wq == NULL) {
43         osal_trace("%s - kmalloc error!\n", __FUNCTION__);
44         return -1;
45     }
46     init_waitqueue_head(wq);
47     wait->wait = wq;
48     return 0;
49 }
50 EXPORT_SYMBOL(osal_wait_init);
osal_wait_interruptible(osal_wait_t * wait,osal_wait_cond_func_t func,const void * param)51 int osal_wait_interruptible(osal_wait_t *wait, osal_wait_cond_func_t func, const void *param)
52 {
53     wait_queue_head_t *wq = NULL;
54     DEFINE_WAIT(__wait);
55     long ret = 0;
56     int condition = 0;
57 
58     if (wait == NULL) {
59         osal_trace("%s - parameter invalid!\n", __FUNCTION__);
60         return -1;
61     }
62 
63     wq = (wait_queue_head_t *)(wait->wait);
64     if (wq == NULL) {
65         osal_trace("%s - wait->wait is NULL!\n", __FUNCTION__);
66         return -1;
67     }
68     prepare_to_wait(wq, &__wait, TASK_INTERRUPTIBLE);
69     /* if wakeup the queue before prepare_to_wait, the func will return true. And will not go to schedule */
70     if (func != NULL) {
71         condition = func(param);
72     }
73 
74     if (!condition) {
75         if (!signal_pending(current)) {
76             schedule();
77         }
78         if (signal_pending(current)) {
79             ret = -ERESTARTSYS;
80         }
81     }
82 
83     finish_wait(wq, &__wait);
84     return ret;
85 }
86 EXPORT_SYMBOL(osal_wait_interruptible);
87 
osal_wait_uninterruptible(osal_wait_t * wait,osal_wait_cond_func_t func,const void * param)88 int osal_wait_uninterruptible(osal_wait_t *wait, osal_wait_cond_func_t func, const void *param)
89 {
90     wait_queue_head_t *wq = NULL;
91     DEFINE_WAIT(__wait);
92     long ret = 0;
93     int condition = 0;
94 
95     if (wait == NULL) {
96         osal_trace("%s - parameter invalid!\n", __FUNCTION__);
97         return -1;
98     }
99 
100     wq = (wait_queue_head_t *)(wait->wait);
101     if (wq == NULL) {
102         osal_trace("%s - wait->wait is NULL!\n", __FUNCTION__);
103         return -1;
104     }
105     prepare_to_wait(wq, &__wait, TASK_UNINTERRUPTIBLE);
106     /* if wakeup the queue before prepare_to_wait, the func will return true. And will not go to schedule */
107     if (func != NULL) {
108         condition = func(param);
109     }
110 
111     if (!condition) {
112         schedule();
113     }
114 
115     finish_wait(wq, &__wait);
116     return ret;
117 }
118 EXPORT_SYMBOL(osal_wait_uninterruptible);
119 
osal_wait_timeout_interruptible(osal_wait_t * wait,osal_wait_cond_func_t func,const void * param,unsigned long ms)120 int osal_wait_timeout_interruptible(osal_wait_t *wait, osal_wait_cond_func_t func, const void *param,
121     unsigned long ms)
122 {
123     wait_queue_head_t *wq = NULL;
124     DEFINE_WAIT(__wait);
125     long ret = ms;
126     int condition = 0;
127 
128     if (wait == NULL) {
129         osal_trace("%s - parameter invalid!\n", __FUNCTION__);
130         return -1;
131     }
132 
133     wq = (wait_queue_head_t *)(wait->wait);
134     if (wq == NULL) {
135         osal_trace("%s - wait->wait is NULL!\n", __FUNCTION__);
136         return -1;
137     }
138     prepare_to_wait(wq, &__wait, TASK_INTERRUPTIBLE);
139     /* if wakeup the queue before prepare_to_wait, the func will return true. And will not go to schedule */
140     if (func != NULL) {
141         condition = func(param);
142     }
143 
144     if (!condition) {
145         if (!signal_pending(current)) {
146             ret = schedule_timeout(msecs_to_jiffies(ret));
147             ret = jiffies_to_msecs(ret);
148         }
149         if (signal_pending(current)) {
150             ret = -ERESTARTSYS;
151         }
152     }
153 
154     finish_wait(wq, &__wait);
155 
156     return ret;
157 }
158 
159 EXPORT_SYMBOL(osal_wait_timeout_interruptible);
160 
osal_wait_timeout_uninterruptible(osal_wait_t * wait,osal_wait_cond_func_t func,const void * param,unsigned long ms)161 int osal_wait_timeout_uninterruptible(osal_wait_t *wait, osal_wait_cond_func_t func,
162                                       const void *param, unsigned long ms)
163 {
164     wait_queue_head_t *wq = NULL;
165     DEFINE_WAIT(__wait);
166     long ret = ms;
167     int condition = 0;
168 
169     if (wait == NULL) {
170         osal_trace("%s - parameter invalid!\n", __FUNCTION__);
171         return -1;
172     }
173 
174     wq = (wait_queue_head_t *)(wait->wait);
175     if (wq == NULL) {
176         osal_trace("%s - wait->wait is NULL!\n", __FUNCTION__);
177         return -1;
178     }
179     prepare_to_wait(wq, &__wait, TASK_UNINTERRUPTIBLE);
180     /* if wakeup the queue before prepare_to_wait, the func will return true. And will not go to schedule */
181     if (func != NULL) {
182         condition = func(param);
183     }
184 
185     if (!condition) {
186         ret = schedule_timeout(msecs_to_jiffies(ret));
187         ret = jiffies_to_msecs(ret);
188     }
189 
190     finish_wait(wq, &__wait);
191 
192     return ret;
193 }
194 EXPORT_SYMBOL(osal_wait_timeout_uninterruptible);
195 
osal_wakeup(osal_wait_t * wait)196 void osal_wakeup(osal_wait_t *wait)
197 {
198     wait_queue_head_t *wq = NULL;
199 
200     wq = (wait_queue_head_t *)(wait->wait);
201     if (wq == NULL) {
202         osal_trace("%s - wait->wait is NULL!\n", __FUNCTION__);
203         return;
204     }
205     wake_up_all(wq);
206 }
207 EXPORT_SYMBOL(osal_wakeup);
osal_wait_destroy(osal_wait_t * wait)208 void osal_wait_destroy(osal_wait_t *wait)
209 {
210     wait_queue_head_t *wq = NULL;
211 
212     wq = (wait_queue_head_t *)(wait->wait);
213     if (wq == NULL) {
214         osal_trace("%s - wait->wait is NULL!\n", __FUNCTION__);
215         return;
216     }
217     kfree(wq);
218     wait->wait = NULL;
219 }
220 EXPORT_SYMBOL(osal_wait_destroy);
221