1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 // Software and any modification/derivatives thereof.
18 // No right, ownership, or interest to MStar Software and any
19 // modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 // supplied together with third party`s software and the use of MStar
23 // Software may require additional licenses from third parties.
24 // Therefore, you hereby agree it is your sole responsibility to separately
25 // obtain any and all third party right and license necessary for your use of
26 // such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 // MStar`s confidential information and you agree to keep MStar`s
30 // confidential information in strictest confidence and not disclose to any
31 // third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 // kind. Any warranties are hereby expressly disclaimed by MStar, including
35 // without limitation, any warranties of merchantability, non-infringement of
36 // intellectual property rights, fitness for a particular purpose, error free
37 // and in conformity with any international standard. You agree to waive any
38 // claim against MStar for any loss, damage, cost or expense that you may
39 // incur related to your use of MStar Software.
40 // In no event shall MStar be liable for any direct, indirect, incidental or
41 // consequential damages, including without limitation, lost of profit or
42 // revenues, lost or damage of data, and unauthorized system use.
43 // You agree that this Section 4 shall still apply without being affected
44 // even if MStar Software has been modified by MStar in accordance with your
45 // request or instruction for your use, except otherwise agreed by both
46 // parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 // services in relation with MStar Software to you for your use of
50 // MStar Software in conjunction with your or your customer`s product
51 // ("Services").
52 // You understand and agree that, except otherwise agreed by both parties in
53 // writing, Services are provided on an "AS IS" basis and the warranty
54 // disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 // or otherwise:
58 // (a) conferring any license or right to use MStar name, trademark, service
59 // mark, symbol or any other identification;
60 // (b) obligating MStar or any of its affiliates to furnish any person,
61 // including without limitation, you and your customers, any assistance
62 // of any kind whatsoever, or any information; or
63 // (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 // of Taiwan, R.O.C., excluding its conflict of law rules.
67 // Any and all dispute arising out hereof or related hereto shall be finally
68 // settled by arbitration referred to the Chinese Arbitration Association,
69 // Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 // Rules of the Association by three (3) arbitrators appointed in accordance
71 // with the said Rules.
72 // The place of arbitration shall be in Taipei, Taiwan and the language shall
73 // be English.
74 // The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78
79 //=============================================================================
80 #include <MsCommon.h>
81
82 #include "include/drvConfig.h"
83 #include "include/drvCompiler.h"
84 #include "include/drvErrno.h"
85 #include "include/drvPorts.h"
86 #include "include/drvTimer.h"
87 #include "include/drvKernel.h"
88 #include "include/drvList.h"
89
90 U32 volatile jiffies;
91
92 //void SW_Timer_Tick(U32 u32Value);
93 void SW_Timer_Tick(U32 u32StTimer, U32 u32TimerID);
94
95 static struct list_head sw_timer_vec_head;
96
97 S32 g_Timer_ID;
98
99 #ifdef TIMER_NO_ALL_INT_DISABLE
100 #include "drvHUB.h"
101 extern struct s_ChipUsbHostDef *pCurrentChip;
disable_USB_interrupts(void)102 void disable_USB_interrupts(void)
103 {
104 U8 i;
105
106 for (i=0; i<pCurrentChip->nRootHub; i++)
107 MsOS_DisableInterrupt(pCurrentChip->reg[i].uhcIRQ);
108 }
109
enable_USB_interrupts(void)110 void enable_USB_interrupts(void)
111 {
112 U8 i;
113
114 for (i=0; i<pCurrentChip->nRootHub; i++)
115 MsOS_EnableInterrupt(pCurrentChip->reg[i].uhcIRQ);
116 }
117 #endif
118
119 S32 _s32MutexUTimer;
init_timers(void)120 void init_timers(void)
121 {
122 INIT_LIST_HEAD(&sw_timer_vec_head);
123 // Register software timer dispatch program
124 // Base 1 ms, interruptted every 1 ms
125
126 BOOL err;
127
128 g_Timer_ID = MsOS_CreateTimer((TimerCb) SW_Timer_Tick,100, 100, FALSE, "USB_TIMER");
129 //err = OS_DefineCyclicHandler(&g_Timer_ID, SW_Timer_Tick, (void*) 0, 100);
130 //USB_ASSERT((err == TRUE), "Define USB timer fail");
131
132 //err = OS_ActivateCyclicHandler(g_Timer_ID);
133 //
134 err=MsOS_StartTimer(g_Timer_ID);
135 USB_ASSERT((err == TRUE), "Activate USB timer fail");
136 //kdbg("Init Software Timer ok %s","\n");
137 printk("Init Software Timer ok \n");
138 _s32MutexUTimer = MsOS_CreateMutex(E_MSOS_FIFO, "UTimer_MUTEX", MSOS_PROCESS_SHARED);
139 }
140
remove_timers(void)141 void remove_timers(void)
142 {
143 MsOS_DeleteTimer(g_Timer_ID);
144 printk("Remove Software Timer ok \n");
145 MsOS_DeleteMutex(_s32MutexUTimer);
146 }
147
148 /*
149 * Timer ISR: It's responsible for dispatching tasks registered to software-timer
150 * task queue. It need to be implemented as Bottom-Half mechanism of Linux
151 * Timer and USB IRQ have the same priority and cannot be interrupted by each other
152 */
153 //void SW_Timer_Tick(U32 pData)
SW_Timer_Tick(U32 u32StTimer,U32 u32TimerID)154 void SW_Timer_Tick(U32 u32StTimer, U32 u32TimerID)
155 {
156 struct timer_list *timer;
157 struct list_head *tmp;
158
159 jiffies+=100;
160
161 if ( Timer_task_lock == 1 )
162 goto sw_done;
163
164 // Dispath task from task queue of software-timer here
165 if (!list_empty(&sw_timer_vec_head))
166 {
167 tmp = sw_timer_vec_head.next;
168 while (tmp != &sw_timer_vec_head)
169 {
170 timer = list_entry (tmp, struct timer_list, entry);
171 tmp = tmp->next;
172 //list_entry (tmp, struct timer_list, entry, struct list_head, timer);
173 // Check if time expired ?
174 timer->expires -= 100;
175 if ( timer->expires <= 0 )
176 {
177 void (*fn)(U32);
178 U32 data;
179 // If lock ==> don't dispatch task
180 /*
181 if ( Timer_task_lock == 1 )
182 {
183 timer->expires++;
184 continue;
185 }
186 */
187 fn = timer->function;
188 data = timer->data;
189 del_timer(timer);
190 // Call registered function
191 if ( (U32)fn )
192 {
193 lock_usb_core();
194 fn(data);
195 unlock_usb_core();
196 }
197 else
198 {
199 printk("ERROR: fun is NULL\n");
200 while(1);
201 }
202 //Current version only support dispatch one task each time
203 //break;
204 }
205 /*
206 if ( (U32)tmp->next == (U32)0x1 )
207 while(1);
208 if ( tmp->next == NULL )
209 while(1);*/
210 }
211 }
212 sw_done:
213 return;
214 // End of dispatching
215 }
216
217 #ifdef TIMER_NO_ALL_INT_DISABLE
timerSectionIn(void)218 void timerSectionIn(void)
219 {
220 MsOS_StopTimer(g_Timer_ID);
221 disable_USB_interrupts();
222 MsOS_ObtainMutex(_s32MutexUTimer, MSOS_WAIT_FOREVER);
223 }
timerSectionOut(void)224 void timerSectionOut(void)
225 {
226 enable_USB_interrupts();
227 MsOS_StartTimer(g_Timer_ID);
228 MsOS_ReleaseMutex(_s32MutexUTimer);
229 }
del_timer_body(struct timer_list * timer)230 int del_timer_body(struct timer_list *timer)
231 {
232 //MsOS_StopTimer(g_Timer_ID);
233 //disable_USB_interrupts();
234
235 if( timer->entry.next != NULL && timer->entry.prev != NULL )
236 {
237 USB_ASSERT(timer->entry.prev->next == &timer->entry, "timer->entry.prev->next error!!!!\n");
238 USB_ASSERT(timer->entry.next != 0, "timer->entry.next!!!!\n");
239 USB_ASSERT(timer->entry.next->prev == &timer->entry, "timer->entry.next->prev error!!!!\n");
240 USB_ASSERT(timer->entry.prev != 0, "timer->entry.prev error!!!!\n");
241 list_del_init(&timer->entry);
242 }
243
244 //enable_USB_interrupts();
245 //MsOS_StartTimer(g_Timer_ID);
246
247 //TIMER_TASK_LOCK = flags;
248 return 1;
249 }
del_timer(struct timer_list * timer)250 int del_timer(struct timer_list *timer)
251 {
252 //timerSectionIn();
253 del_timer_body(timer);
254 //timerSectionOut();
255 return 1;
256 }
del_timer_sync_body(struct timer_list * timer)257 int del_timer_sync_body(struct timer_list *timer)
258 {
259 //MsOS_StopTimer(g_Timer_ID);
260 //disable_USB_interrupts();
261
262 if( timer->entry.next != NULL && timer->entry.prev != NULL )
263 {
264 USB_ASSERT(timer->entry.prev->next == &timer->entry, "timer->entry.prev->next error!!!!\n");
265 USB_ASSERT(timer->entry.next != 0, "timer->entry.next!!!!\n");
266 USB_ASSERT(timer->entry.next->prev == &timer->entry, "timer->entry.next->prev error!!!!\n");
267 USB_ASSERT(timer->entry.prev != 0, "timer->entry.prev error!!!!\n");
268 list_del_init(&timer->entry);
269 }
270
271 //enable_USB_interrupts();
272 //MsOS_StartTimer(g_Timer_ID);
273
274 //TIMER_TASK_LOCK = flags;
275 return 1;
276 }
del_timer_sync(struct timer_list * timer)277 int del_timer_sync(struct timer_list *timer)
278 {
279 timerSectionIn();
280 del_timer_sync_body(timer);
281 timerSectionOut();
282 return 1;
283 }
add_timer_body(struct timer_list * timer)284 void add_timer_body(struct timer_list *timer)
285 {
286 //MsOS_StopTimer(g_Timer_ID);
287 //disable_USB_interrupts();
288
289 if ( (timer->tmout_step > 0) && (timer->tmout_value > timer->tmout_step) )
290 timer->expires = timer->tmout_step;
291 else
292 timer->expires = timer->tmout_value;
293
294 list_add_tail(&timer->entry, &sw_timer_vec_head);
295
296 //enable_USB_interrupts();
297 //MsOS_StartTimer(g_Timer_ID);
298
299 //TIMER_TASK_LOCK = flags;
300 }
add_timer(struct timer_list * timer)301 void add_timer(struct timer_list *timer)
302 {
303 timerSectionIn();
304 add_timer_body(timer);
305 timerSectionOut();
306 }
mod_timer_body(struct timer_list * timer,U32 expires,U32 steps)307 int mod_timer_body(struct timer_list *timer, U32 expires, U32 steps)
308 {
309 //U32 flags;
310 int ret = 0;
311
312 //MsOS_StopTimer(g_Timer_ID);
313 //disable_USB_interrupts();
314
315 timer->tmout_value = expires;
316 timer->tmout_step = steps;
317
318 //ret = del_timer(timer);
319 if( timer->entry.next != NULL && timer->entry.prev != NULL )
320 {
321 USB_ASSERT(timer->entry.prev->next == &timer->entry, "timer->entry.prev->next error!!!!\n");
322 USB_ASSERT(timer->entry.next != 0, "timer->entry.next!!!!\n");
323 USB_ASSERT(timer->entry.next->prev == &timer->entry, "timer->entry.next->prev error!!!!\n");
324 USB_ASSERT(timer->entry.prev != 0, "timer->entry.prev error!!!!\n");
325 list_del_init(&timer->entry);
326 }
327
328 //add_timer(timer);
329 if ( (timer->tmout_step > 0) && (timer->tmout_value > timer->tmout_step) )
330 timer->expires = timer->tmout_step;
331 else
332 timer->expires = timer->tmout_value;
333 list_add_tail(&timer->entry, &sw_timer_vec_head);
334
335 //enable_USB_interrupts();
336 //MsOS_StartTimer(g_Timer_ID);
337
338 return ret;
339 }
mod_timer(struct timer_list * timer,U32 expires,U32 steps)340 int mod_timer(struct timer_list *timer, U32 expires, U32 steps)
341 {
342 int ret = 0;
343 //timerSectionIn();
344 ret = mod_timer_body(timer, expires, steps);
345 //timerSectionOut();
346 return ret;
347 }
348 #else // Disable All Interrupts
349 /***
350 * del_timer - deactive a timer.
351 * @timer: the timer to be deactivated
352 *
353 * del_timer() deactivates a timer - this works on both active and inactive
354 * timers.
355 *
356 * The function returns whether it has deactivated a pending timer or not.
357 * (ie. del_timer() of an inactive timer returns 0, del_timer() of an
358 * active timer returns 1.)
359 */
del_timer(struct timer_list * timer)360 int del_timer(struct timer_list *timer)
361 {
362 //U32 flags;
363
364 //flags = TIMER_TASK_LOCK;
365 //lock_TmrTaskDispatch();
366 //save_and_disable_firqs(&flags);
367 //HAL_DISABLE_INTERRUPTS(flags);
368 //OS_DisableDispatch();yuwen
369 //MsOS_DisableInterrupt(E_IRQ_FIQ_ALL);
370 U32 u32OldIntr;
371 u32OldIntr = MsOS_DisableAllInterrupts();
372
373 if( timer->entry.next != NULL && timer->entry.prev != NULL )
374 {
375 USB_ASSERT(timer->entry.prev->next == &timer->entry, "timer->entry.prev->next error!!!!\n");
376 USB_ASSERT(timer->entry.next != 0, "timer->entry.next!!!!\n");
377 USB_ASSERT(timer->entry.next->prev == &timer->entry, "timer->entry.next->prev error!!!!\n");
378 USB_ASSERT(timer->entry.prev != 0, "timer->entry.prev error!!!!\n");
379 list_del_init(&timer->entry);
380 }
381
382 //restore_firqs(&flags);
383 //HAL_RESTORE_INTERRUPTS(flags);
384 //OS_EnableDispatch();yuwen
385 //MsOS_EnableInterrupt(E_IRQ_FIQ_ALL);
386 MsOS_RestoreAllInterrupts(u32OldIntr);
387
388 //TIMER_TASK_LOCK = flags;
389 return 1;
390 }
391
392 /***
393 * del_timer_sync - deactive a timer.
394 * @timer: the timer to be deactivated
395 *
396 * del_timer_sync() deactivates a timer - this works on both active and inactive
397 * timers.
398 *
399 * The function will protect synchronization problem before deactivating timer
400 */
del_timer_sync(struct timer_list * timer)401 int del_timer_sync(struct timer_list *timer)
402 {
403 //U32 flags;
404
405 //flags = TIMER_TASK_LOCK;
406 //lock_TmrTaskDispatch();
407 //save_and_disable_firqs(&flags);
408 //HAL_DISABLE_INTERRUPTS(flags);
409 //OS_DisableDispatch();
410 //MsOS_DisableInterrupt(E_IRQ_FIQ_ALL);
411 U32 u32OldIntr;
412 u32OldIntr = MsOS_DisableAllInterrupts();
413
414 if( timer->entry.next != NULL && timer->entry.prev != NULL )
415 {
416 USB_ASSERT(timer->entry.prev->next == &timer->entry, "timer->entry.prev->next error!!!!\n");
417 USB_ASSERT(timer->entry.next != 0, "timer->entry.next!!!!\n");
418 USB_ASSERT(timer->entry.next->prev == &timer->entry, "timer->entry.next->prev error!!!!\n");
419 USB_ASSERT(timer->entry.prev != 0, "timer->entry.prev error!!!!\n");
420 list_del_init(&timer->entry);
421 }
422
423 //restore_firqs(&flags);
424 //HAL_RESTORE_INTERRUPTS(flags);
425 //OS_EnableDispatch();
426 //MsOS_EnableInterrupt(E_IRQ_FIQ_ALL);
427 MsOS_RestoreAllInterrupts(u32OldIntr);
428
429 //TIMER_TASK_LOCK = flags;
430 return 1;
431 }
432
433 /***
434 * add_timer - start a timer
435 * @timer: the timer to be added
436 *
437 * The kernel will do a ->function(->data) callback from the
438 * timer interrupt at the ->expired point in the future. The
439 * current time is 'jiffies'.
440 *
441 * The timer's ->expired, ->function (and if the handler uses it, ->data)
442 * fields must be set prior calling this function.
443 *
444 * Timers with an ->expired field in the past will be executed in the next
445 * timer tick. It's illegal to add an already pending timer.
446 */
add_timer(struct timer_list * timer)447 void add_timer(struct timer_list *timer)
448 {
449 //U32 flags;
450
451 //flags = TIMER_TASK_LOCK;
452 //lock_TmrTaskDispatch();
453 //save_and_disable_firqs(&flags);
454 //HAL_DISABLE_INTERRUPTS(flags);
455 //OS_DisableDispatch();
456 //MsOS_DisableInterrupt(E_IRQ_FIQ_ALL);
457 U32 u32OldIntr;
458 u32OldIntr = MsOS_DisableAllInterrupts();
459
460 if ( (timer->tmout_step > 0) && (timer->tmout_value > timer->tmout_step) )
461 timer->expires = timer->tmout_step;
462 else
463 timer->expires = timer->tmout_value;
464
465 list_add_tail(&timer->entry, &sw_timer_vec_head);
466
467 //restore_firqs(&flags);
468 //HAL_RESTORE_INTERRUPTS(flags);
469 //OS_EnableDispatch();
470 //MsOS_EnableInterrupt(E_IRQ_FIQ_ALL);
471 MsOS_RestoreAllInterrupts(u32OldIntr);
472
473 //TIMER_TASK_LOCK = flags;
474 }
475
mod_timer(struct timer_list * timer,U32 expires,U32 steps)476 int mod_timer(struct timer_list *timer, U32 expires, U32 steps)
477 {
478 //U32 flags;
479 int ret = 0;
480
481 //save_and_disable_firqs(&flags);
482 //OS_DisableDispatch();
483 //MsOS_DisableInterrupt(E_IRQ_FIQ_ALL);
484 U32 u32OldIntr;
485 u32OldIntr = MsOS_DisableAllInterrupts();
486
487 timer->tmout_value = expires;
488 timer->tmout_step = steps;
489
490 //ret = del_timer(timer);
491 if( timer->entry.next != NULL && timer->entry.prev != NULL )
492 {
493 USB_ASSERT(timer->entry.prev->next == &timer->entry, "timer->entry.prev->next error!!!!\n");
494 USB_ASSERT(timer->entry.next != 0, "timer->entry.next!!!!\n");
495 USB_ASSERT(timer->entry.next->prev == &timer->entry, "timer->entry.next->prev error!!!!\n");
496 USB_ASSERT(timer->entry.prev != 0, "timer->entry.prev error!!!!\n");
497 list_del_init(&timer->entry);
498 }
499
500 //add_timer(timer);
501 if ( (timer->tmout_step > 0) && (timer->tmout_value > timer->tmout_step) )
502 timer->expires = timer->tmout_step;
503 else
504 timer->expires = timer->tmout_value;
505 list_add_tail(&timer->entry, &sw_timer_vec_head);
506
507 //restore_firqs(&flags);
508 //OS_EnableDispatch();
509 //MsOS_EnableInterrupt(E_IRQ_FIQ_ALL);
510 MsOS_RestoreAllInterrupts(u32OldIntr);
511
512 return ret;
513 }
514 #endif //#ifdef
515
516