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/module.h>
20 #include <linux/kernel.h>
21 #include <linux/printk.h>
22 #include <linux/timer.h>
23 #include <linux/delay.h>
24 #include <linux/slab.h>
25 #include <linux/sched.h>
26 #include <linux/rtc.h>
27 #include <linux/sched/clock.h>
28 #include <linux/version.h>
29 #include "hi_osal.h"
30
31 struct timer_list_info {
32 struct timer_list time_list;
33 unsigned long data;
34 };
35 typedef void (*timer_callback_fun)(struct timer_list *data);
36
osal_timer_get_private_data(void * data)37 unsigned long osal_timer_get_private_data(void *data)
38 {
39 struct timer_list_info *list_info = osal_container_of(data, struct timer_list_info, time_list);
40
41 return list_info->data;
42 }
43 EXPORT_SYMBOL(osal_timer_get_private_data);
44
osal_timer_init(osal_timer_t * timer)45 int osal_timer_init(osal_timer_t *timer)
46 {
47 struct timer_list_info *t = NULL;
48
49 if (timer == NULL) {
50 osal_trace("%s - parameter invalid!\n", __FUNCTION__);
51 return -1;
52 }
53
54 t = (struct timer_list_info *)kmalloc(sizeof(struct timer_list_info), GFP_KERNEL);
55 if (t == NULL) {
56 osal_trace("%s - kmalloc error!\n", __FUNCTION__);
57 return -1;
58 }
59
60 t->data = timer->data;
61 timer_setup(&t->time_list, (timer_callback_fun)timer->function, 0);
62 timer->timer = t;
63 return 0;
64 }
65 EXPORT_SYMBOL(osal_timer_init);
osal_set_timer(osal_timer_t * timer,unsigned long interval)66 int osal_set_timer(osal_timer_t *timer, unsigned long interval)
67 {
68 struct timer_list_info *list_info = NULL;
69 if ((timer == NULL) || (timer->timer == NULL) || (timer->function == NULL) || (interval == 0)) {
70 osal_trace("%s - parameter invalid!\n", __FUNCTION__);
71 return -1;
72 }
73 list_info = (struct timer_list_info *)timer->timer;
74 list_info->data = timer->data;
75 list_info->time_list.function = (timer_callback_fun)timer->function;
76 return mod_timer(&list_info->time_list, jiffies + msecs_to_jiffies(interval) - 1);
77 }
78 EXPORT_SYMBOL(osal_set_timer);
79
osal_del_timer(osal_timer_t * timer)80 int osal_del_timer(osal_timer_t *timer)
81 {
82 struct timer_list *t = NULL;
83 if ((timer == NULL) || (timer->timer == NULL) || (timer->function == NULL)) {
84 osal_trace("%s - parameter invalid!\n", __FUNCTION__);
85 return -1;
86 }
87 t = timer->timer;
88 return del_timer(t);
89 }
90 EXPORT_SYMBOL(osal_del_timer);
91
osal_timer_destroy(osal_timer_t * timer)92 int osal_timer_destroy(osal_timer_t *timer)
93 {
94 struct timer_list *t = timer->timer;
95 del_timer(t);
96 kfree(t);
97 timer->timer = NULL;
98 return 0;
99 }
100 EXPORT_SYMBOL(osal_timer_destroy);
101
osal_msleep(unsigned int msecs)102 unsigned long osal_msleep(unsigned int msecs)
103 {
104 return msleep_interruptible(msecs);
105 }
106 EXPORT_SYMBOL(osal_msleep);
107
osal_udelay(unsigned int usecs)108 void osal_udelay(unsigned int usecs)
109 {
110 udelay(usecs);
111 }
112 EXPORT_SYMBOL(osal_udelay);
113
osal_mdelay(unsigned int msecs)114 void osal_mdelay(unsigned int msecs)
115 {
116 mdelay(msecs);
117 }
118 EXPORT_SYMBOL(osal_mdelay);
119
osal_get_tickcount()120 unsigned int osal_get_tickcount()
121 {
122 return jiffies_to_msecs(jiffies);
123 }
124 EXPORT_SYMBOL(osal_get_tickcount);
125
osal_sched_clock()126 unsigned long long osal_sched_clock()
127 {
128 return sched_clock();
129 }
130 EXPORT_SYMBOL(osal_sched_clock);
131
osal_gettimeofday(osal_timeval_t * tv)132 void osal_gettimeofday(osal_timeval_t *tv)
133 {
134 #if LINUX_VERSION_CODE > KERNEL_VERSION(5,10,0)
135 struct timespec64 t;
136 if (tv == NULL) {
137 osal_trace("%s - parameter invalid!\n", __FUNCTION__);
138 return;
139 }
140 ktime_get_real_ts64(&t);
141
142 tv->tv_sec = t.tv_sec;
143 tv->tv_usec = t.tv_nsec;
144 #else
145 struct timeval t;
146 if (tv == NULL) {
147 osal_trace("%s - parameter invalid!\n", __FUNCTION__);
148 return;
149 }
150 do_gettimeofday(&t);
151
152 tv->tv_sec = t.tv_sec;
153 tv->tv_usec = t.tv_usec;
154 #endif
155 }
156 EXPORT_SYMBOL(osal_gettimeofday);
157
osal_rtc_time_to_tm(unsigned long time,osal_rtc_time_t * tm)158 void osal_rtc_time_to_tm(unsigned long time, osal_rtc_time_t *tm)
159 {
160 struct rtc_time _tm = {0};
161
162 #if LINUX_VERSION_CODE > KERNEL_VERSION(5,10,0)
163 rtc_time64_to_tm(time, &_tm);
164 #else
165 rtc_time_to_tm(time, &_tm);
166 #endif
167 tm->tm_sec = _tm.tm_sec;
168 tm->tm_min = _tm.tm_min;
169 tm->tm_hour = _tm.tm_hour;
170 tm->tm_mday = _tm.tm_mday;
171 tm->tm_mon = _tm.tm_mon;
172 tm->tm_year = _tm.tm_year;
173 tm->tm_wday = _tm.tm_wday;
174 tm->tm_yday = _tm.tm_yday;
175 tm->tm_isdst = _tm.tm_isdst;
176 }
177 EXPORT_SYMBOL(osal_rtc_time_to_tm);
178
osal_rtc_tm_to_time(osal_rtc_time_t * tm,unsigned long * time)179 void osal_rtc_tm_to_time(osal_rtc_time_t *tm, unsigned long *time)
180 {
181 struct rtc_time _tm;
182 _tm.tm_sec = tm->tm_sec;
183 _tm.tm_min = tm->tm_min;
184 _tm.tm_hour = tm->tm_hour;
185 _tm.tm_mday = tm->tm_mday;
186 _tm.tm_mon = tm->tm_mon;
187 _tm.tm_year = tm->tm_year;
188 _tm.tm_wday = tm->tm_wday;
189 _tm.tm_yday = tm->tm_yday;
190 _tm.tm_isdst = tm->tm_isdst;
191
192 #if LINUX_VERSION_CODE > KERNEL_VERSION(5,10,0)
193 *time = rtc_tm_to_time64(&_tm);
194 #else
195 rtc_tm_to_time(&_tm, time);
196 #endif
197 }
198 EXPORT_SYMBOL(osal_rtc_tm_to_time);
199
osal_getjiffies(unsigned long long * pjiffies)200 void osal_getjiffies(unsigned long long *pjiffies)
201 {
202 *pjiffies = jiffies;
203 }
204 EXPORT_SYMBOL(osal_getjiffies);
205
osal_rtc_valid_tm(struct osal_rtc_time * tm)206 int osal_rtc_valid_tm(struct osal_rtc_time *tm)
207 {
208 struct rtc_time _tm;
209 _tm.tm_sec = tm->tm_sec;
210 _tm.tm_min = tm->tm_min;
211 _tm.tm_hour = tm->tm_hour;
212 _tm.tm_mday = tm->tm_mday;
213 _tm.tm_mon = tm->tm_mon;
214 _tm.tm_year = tm->tm_year;
215 _tm.tm_wday = tm->tm_wday;
216 _tm.tm_yday = tm->tm_yday;
217 _tm.tm_isdst = tm->tm_isdst;
218
219 return rtc_valid_tm(&_tm);
220 }
221 EXPORT_SYMBOL(osal_rtc_valid_tm);
222