• 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 <linux/workqueue.h>
20 #include <linux/slab.h>
21 #include <linux/module.h>
22 #include "hi_osal.h"
23 
24 OSAL_LIST_HEAD(wq_list);
25 struct wq_node {
26     struct osal_work_struct *osal_work;
27     struct work_struct *work;
28     struct osal_list_head node;
29 };
30 
osal_find_work(struct work_struct * work)31 static struct osal_work_struct *osal_find_work(struct work_struct *work)
32 {
33     struct osal_list_head *this = NULL;
34     if (osal_list_empty(&wq_list)) {
35         osal_trace("find work failed! wq_list is empty!\n");
36         return NULL;
37     }
38     osal_list_for_each(this, &wq_list) {
39         struct wq_node *ws = osal_list_entry(this, struct wq_node, node);
40         if (ws->work == work) {
41             return ws->osal_work;
42         }
43     }
44     osal_trace("find work failed!\n");
45     return NULL;
46 }
47 
osal_del_work(struct work_struct * work)48 static int osal_del_work(struct work_struct *work)
49 {
50     struct osal_list_head *this = NULL;
51     struct osal_list_head *next = NULL;
52     if (osal_list_empty(&wq_list)) {
53         osal_trace("find work failed! wq_list is empty!\n");
54         return -1;
55     }
56     osal_list_for_each_safe(this, next, &wq_list) {
57         struct wq_node *ws = osal_list_entry(this, struct wq_node, node);
58         if (ws->work == work) {
59             osal_list_del(this);
60             kfree(ws);
61             ws = NULL;
62             return 0;
63         }
64     }
65     osal_trace("del work failed!\n");
66     return -1;
67 }
68 
osal_work_func(struct work_struct * work)69 static void osal_work_func(struct work_struct *work)
70 {
71     struct osal_work_struct *ow = osal_find_work(work);
72     if ((ow != NULL) && (ow->func != NULL)) {
73         ow->func(ow);
74     }
75 }
76 
osal_init_work(struct osal_work_struct * work,osal_work_func_t func)77 int osal_init_work(struct osal_work_struct *work, osal_work_func_t func)
78 {
79     struct work_struct *w = NULL;
80     struct wq_node *w_node = NULL;
81     w = kmalloc(sizeof(struct work_struct), GFP_ATOMIC);
82     if (w == NULL) {
83         osal_trace("osal_init_work kmalloc failed!\n");
84         return -1;
85     }
86 
87     w_node = kmalloc(sizeof(struct wq_node), GFP_ATOMIC);
88     if (w_node == NULL) {
89         osal_trace("osal_init_work kmalloc failed!\n");
90         kfree(w);
91         w = NULL;
92         return -1;
93     }
94     INIT_WORK(w, osal_work_func);
95     work->work = w;
96     work->func = func;
97     w_node->osal_work = work;
98     w_node->work = w;
99     osal_list_add(&(w_node->node), &wq_list);
100     return 0;
101 }
102 EXPORT_SYMBOL(osal_init_work);
103 
osal_schedule_work(struct osal_work_struct * work)104 int osal_schedule_work(struct osal_work_struct *work)
105 {
106     if ((work != NULL) && (work->work != NULL)) {
107         return (int)schedule_work(work->work);
108     } else {
109         return (int)false;
110     }
111 }
112 EXPORT_SYMBOL(osal_schedule_work);
113 
osal_destroy_work(struct osal_work_struct * work)114 void osal_destroy_work(struct osal_work_struct *work)
115 {
116     if ((work != NULL) && (work->work != NULL)) {
117         osal_del_work(work->work);
118         kfree((struct work_struct *)work->work);
119         work->work = NULL;
120     }
121 }
122 EXPORT_SYMBOL(osal_destroy_work);
123