import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / mach-mt8127 / camera_pipe_mgr.c
1 //-----------------------------------------------------------------------------
2 #include <linux/uaccess.h>
3 #include <linux/module.h>
4 #include <linux/types.h>
5 #include <linux/device.h>
6 #include <linux/cdev.h>
7 #include <linux/platform_device.h>
8 #include <linux/slab.h> //kmalloc/kfree in kernel 3.10
9 #include <linux/spinlock.h>
10 #include <linux/sched.h>
11 #include <linux/mm.h>
12 #include <linux/fs.h>
13 #include <linux/proc_fs.h>
14 #include <linux/xlog.h>
15 //#include <asm/io.h>
16 #include <mach/camera_pipe_mgr.h>
17 #include <mach/camera_pipe_mgr_imp.h>
18 //-----------------------------------------------------------------------------
19 static CAM_PIPE_MGR_STRUCT CamPipeMgr;
20 //------------------------------------------------------------------------------
21 static void CamPipeMgr_GetTime(MUINT32* pSec, MUINT32* pUSec)
22 {
23 ktime_t Time;
24 MUINT64 TimeSec;
25 //
26 Time = ktime_get();//ns
27 TimeSec = Time.tv64;
28 do_div( TimeSec, 1000 );
29 *pUSec = do_div( TimeSec, 1000000);
30 //
31 *pSec = (MUINT64)TimeSec;
32 }
33 //-----------------------------------------------------------------------------
34 static inline void CamPipeMgr_SpinLock(void)
35 {
36 //LOG_MSG("");
37 spin_lock(&(CamPipeMgr.SpinLock));
38 }
39 //-----------------------------------------------------------------------------
40 static inline void CamPipeMgr_SpinUnlock(void)
41 {
42 //LOG_MSG("");
43 spin_unlock(&(CamPipeMgr.SpinLock));
44 }
45 //-----------------------------------------------------------------------------
46 static unsigned long CamPipeMgr_MsToJiffies(MUINT32 Ms)
47 {
48 return ((Ms*HZ + 512) >> 10);
49 }
50 //-----------------------------------------------------------------------------
51 static void CamPipeMgr_DumpPipeInfo(void)
52 {
53 MUINT32 i;
54 //
55 LOG_MSG("E");
56 for(i=0;i<CAM_PIPE_MGR_PIPE_AMOUNT;i++)
57 {
58 if( CamPipeMgr.PipeInfo[i].Pid != 0 &&
59 CamPipeMgr.PipeInfo[i].Tgid != 0)
60 {
61 LOG_MSG("Pipe(%ld,%s),Proc:Name(%s),Pid(%d),Tgid(%d),Time(%ld.%06ld)",
62 i,
63 CamPipeMgr.PipeName[i],
64 CamPipeMgr.PipeInfo[i].ProcName,
65 CamPipeMgr.PipeInfo[i].Pid,
66 CamPipeMgr.PipeInfo[i].Tgid,
67 CamPipeMgr.PipeInfo[i].TimeS,
68 CamPipeMgr.PipeInfo[i].TimeUS);
69 }
70 }
71 LOG_MSG("X");
72 }
73 //----------------------------------------------------------------------------
74 static MUINT32 CamPipeMgr_GtePipeLockTable(
75 CAM_PIPE_MGR_SCEN_SW_ENUM ScenSw,
76 CAM_PIPE_MGR_SCEN_HW_ENUM ScenHw)
77 {
78 MUINT32 PipeLockTable = 0;
79 //
80 switch(ScenHw)
81 {
82 case CAM_PIPE_MGR_SCEN_HW_NONE:
83 {
84 if(ScenSw == CAM_PIPE_MGR_SCEN_SW_NONE)
85 {
86 PipeLockTable = CAM_PIPE_MGR_LOCK_TABLE_NONE;
87 }
88 break;
89 }
90 case CAM_PIPE_MGR_SCEN_HW_IC:
91 {
92 PipeLockTable = CAM_PIPE_MGR_LOCK_TABLE_IC;
93 break;
94 }
95 case CAM_PIPE_MGR_SCEN_HW_VR:
96 {
97 PipeLockTable = CAM_PIPE_MGR_LOCK_TABLE_VR;
98 break;
99 }
100 case CAM_PIPE_MGR_SCEN_HW_ZSD:
101 {
102 PipeLockTable = CAM_PIPE_MGR_LOCK_TABLE_ZSD;
103 break;
104 }
105 case CAM_PIPE_MGR_SCEN_HW_IP:
106 {
107 PipeLockTable = CAM_PIPE_MGR_LOCK_TABLE_IP;
108 break;
109 }
110 case CAM_PIPE_MGR_SCEN_HW_N3D:
111 {
112 PipeLockTable = CAM_PIPE_MGR_LOCK_TABLE_N3D;
113 break;
114 }
115 case CAM_PIPE_MGR_SCEN_HW_VSS:
116 {
117 PipeLockTable = CAM_PIPE_MGR_LOCK_TABLE_VSS;
118 break;
119 }
120 default:
121 {
122 LOG_ERR("Unknown ScenHw(%d)",ScenHw);
123 break;
124 }
125 }
126 //
127 switch(ScenSw)
128 {
129 case CAM_PIPE_MGR_SCEN_SW_CAM_PRV:
130 case CAM_PIPE_MGR_SCEN_SW_VIDEO_PRV:
131 {
132 if(ScenHw == CAM_PIPE_MGR_SCEN_HW_VSS)
133 {
134 //do nothing
135 }
136 break;
137 }
138 case CAM_PIPE_MGR_SCEN_SW_ZSD:
139 {
140 if(ScenHw == CAM_PIPE_MGR_SCEN_HW_ZSD)
141 {
142 //do nothing
143 }
144 break;
145 }
146 //
147 case CAM_PIPE_MGR_SCEN_SW_NONE:
148 case CAM_PIPE_MGR_SCEN_SW_CAM_IDLE:
149 case CAM_PIPE_MGR_SCEN_SW_CAM_CAP:
150 case CAM_PIPE_MGR_SCEN_SW_VIDEO_REC:
151 case CAM_PIPE_MGR_SCEN_SW_VIDEO_VSS:
152 case CAM_PIPE_MGR_SCEN_SW_N3D:
153 {
154 //Do nothing.
155 break;
156 }
157 default:
158 {
159 LOG_ERR("Unknown ScenSw(%d)",ScenSw);
160 break;
161 }
162 }
163 //
164 return PipeLockTable;
165 }
166 //----------------------------------------------------------------------------
167 static void CamPipeMgr_UpdatePipeLockTable(CAM_PIPE_MGR_SCEN_SW_ENUM ScenSw)
168 {
169 MUINT32 i;
170 //
171 for(i=0;i<CAM_PIPE_MGR_SCEN_HW_AMOUNT;i++)
172 {
173 CamPipeMgr.PipeLockTable[i] = CamPipeMgr_GtePipeLockTable(ScenSw,i);
174 }
175 }
176 //----------------------------------------------------------------------------
177 static void CamPipeMgr_StorePipeInfo(MUINT32 PipeMask)
178 {
179 MUINT32 i;
180 //
181 //LOG_MSG("PipeMask(0x%08X)",PipeMask);
182 //
183 CamPipeMgr.PipeMask |= PipeMask;
184 //
185 for(i=0;i<CAM_PIPE_MGR_PIPE_AMOUNT;i++)
186 {
187 if((1<<i) & PipeMask)
188 {
189 if( CamPipeMgr.PipeInfo[i].Pid == 0 &&
190 CamPipeMgr.PipeInfo[i].Tgid == 0)
191 {
192 CamPipeMgr.PipeInfo[i].Pid = current->pid;
193 CamPipeMgr.PipeInfo[i].Tgid = current->tgid;
194 strcpy(CamPipeMgr.PipeInfo[i].ProcName,current->comm);
195 CamPipeMgr_GetTime(&(CamPipeMgr.PipeInfo[i].TimeS), &(CamPipeMgr.PipeInfo[i].TimeUS));
196 }
197 else
198 {
199 LOG_ERR("PipeMask(0x%lX),Pipe(%ld,%s),Pid(%d),Tgid(%d),Time(%ld.%06ld)",
200 PipeMask,
201 i,
202 CamPipeMgr.PipeInfo[i].ProcName,
203 CamPipeMgr.PipeInfo[i].Pid,
204 CamPipeMgr.PipeInfo[i].Tgid,
205 CamPipeMgr.PipeInfo[i].TimeS,
206 CamPipeMgr.PipeInfo[i].TimeUS);
207 }
208 }
209 }
210 }
211 //-----------------------------------------------------------------------------
212 static void CamPipeMgr_RemovePipeInfo(MUINT32 PipeMask)
213 {
214 MUINT32 i;
215 //
216 //LOG_MSG("PipeMask(0x%08X)",PipeMask);
217 //
218 CamPipeMgr.PipeMask &= (~PipeMask);
219 //
220 for(i=0;i<CAM_PIPE_MGR_PIPE_AMOUNT;i++)
221 {
222 if((1<<i) & PipeMask)
223 {
224 if( CamPipeMgr.PipeInfo[i].Pid != 0 &&
225 CamPipeMgr.PipeInfo[i].Tgid != 0)
226 {
227 CamPipeMgr.PipeInfo[i].Pid = 0;
228 CamPipeMgr.PipeInfo[i].Tgid = 0;
229 strcpy(CamPipeMgr.PipeInfo[i].ProcName,CAM_PIPE_MGR_PROC_NAME);
230 }
231 else
232 {
233 LOG_WRN("PipeMask(0x%lX),Pipe(%ld,%s),Pid(%d),Tgid(%d),Time(%ld.%06ld)",
234 PipeMask,
235 i,
236 CamPipeMgr.PipeInfo[i].ProcName,
237 CamPipeMgr.PipeInfo[i].Pid,
238 CamPipeMgr.PipeInfo[i].Tgid,
239 CamPipeMgr.PipeInfo[i].TimeS,
240 CamPipeMgr.PipeInfo[i].TimeUS);
241 }
242 }
243 }
244 }
245 //-----------------------------------------------------------------------------
246 static CAM_PIPE_MGR_STATUS_ENUM CamPipeMgr_LockPipe(CAM_PIPE_MGR_LOCK_STRUCT* pLock)
247 {
248 MUINT32 Timeout;
249 CAM_PIPE_MGR_STATUS_ENUM Result = CAM_PIPE_MGR_STATUS_OK;
250 //
251 if((CamPipeMgr.PipeMask & pLock->PipeMask) == 0)
252 {
253 if((pLock->PipeMask & CamPipeMgr.PipeLockTable[CamPipeMgr.Mode.ScenHw]) != pLock->PipeMask)
254 {
255 Result = CAM_PIPE_MGR_STATUS_TIMEOUT;
256 }
257 else
258 {
259 CamPipeMgr_StorePipeInfo(pLock->PipeMask);
260 Result = CAM_PIPE_MGR_STATUS_OK;
261 }
262 }
263 else
264 {
265 CamPipeMgr_SpinUnlock();
266 if(pLock->Timeout > CAM_PIPE_MGR_TIMEOUT_MAX)
267 {
268 pLock->Timeout = CAM_PIPE_MGR_TIMEOUT_MAX;
269 }
270 Timeout = wait_event_interruptible_timeout(
271 CamPipeMgr.WaitQueueHead,
272 (CamPipeMgr.PipeMask & pLock->PipeMask) == 0,
273 CamPipeMgr_MsToJiffies(pLock->Timeout));
274 CamPipeMgr_SpinLock();
275 if((CamPipeMgr.PipeMask & pLock->PipeMask) == 0)
276 {
277 if((pLock->PipeMask & CamPipeMgr.PipeLockTable[CamPipeMgr.Mode.ScenHw]) != pLock->PipeMask)
278 {
279 Result = CAM_PIPE_MGR_STATUS_TIMEOUT;
280 }
281 else
282 {
283 CamPipeMgr_StorePipeInfo(pLock->PipeMask);
284 Result = CAM_PIPE_MGR_STATUS_OK;
285 }
286 }
287 else
288 if( Timeout == 0 &&
289 (CamPipeMgr.PipeMask & pLock->PipeMask) != 0)
290 {
291 Result = CAM_PIPE_MGR_STATUS_TIMEOUT;
292 }
293 else
294 {
295 Result = CAM_PIPE_MGR_STATUS_UNKNOW;
296 }
297 }
298 //
299 return Result;
300 }
301 //-----------------------------------------------------------------------------
302 static void CamPipeMgr_UnlockPipe(CAM_PIPE_MGR_UNLOCK_STRUCT* pUnlock)
303 {
304 CamPipeMgr_RemovePipeInfo(pUnlock->PipeMask);
305 wake_up_interruptible(&(CamPipeMgr.WaitQueueHead));
306 }
307 //-----------------------------------------------------------------------------
308 static int CamPipeMgr_Open(
309 struct inode* pInode,
310 struct file* pFile)
311 {
312 int Ret = 0;
313 MUINT32 Sec = 0,USec = 0;
314 CAM_PIPE_MGR_PROC_STRUCT* pProc;
315 //
316 CamPipeMgr_GetTime(&Sec, &USec);
317 //
318 LOG_MSG("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)",
319 current->comm,
320 current->pid,
321 current->tgid,
322 Sec,
323 USec);
324 //
325 CamPipeMgr_SpinLock();
326 //
327 pFile->private_data = NULL;
328 pFile->private_data = kmalloc(sizeof(CAM_PIPE_MGR_PROC_STRUCT),GFP_ATOMIC);
329 if(pFile->private_data == NULL)
330 {
331 Ret = -ENOMEM;
332 }
333 else
334 {
335 pProc = (CAM_PIPE_MGR_PROC_STRUCT*)pFile->private_data;
336 pProc->Pid = 0;
337 pProc->Tgid = 0;
338 strcpy(pProc->ProcName,CAM_PIPE_MGR_PROC_NAME);
339 pProc->PipeMask = 0;
340 pProc->TimeS = Sec;
341 pProc->TimeUS = USec;
342 }
343 //
344 CamPipeMgr_SpinUnlock();
345 //
346 if(Ret == (-ENOMEM))
347 {
348 LOG_ERR("No enough memory");
349 /*
350 LOG_ERR("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)",
351 current->comm,
352 current->pid,
353 current->tgid,
354 Sec,
355 USec);
356 */
357 }
358 //
359 //LOG_MSG("OK");
360 return Ret;
361 }
362 //-----------------------------------------------------------------------------
363 static int CamPipeMgr_Release(
364 struct inode* pInode,
365 struct file* pFile)
366 {
367 MUINT32 Sec = 0,USec = 0;
368 CAM_PIPE_MGR_PROC_STRUCT* pProc;
369 CAM_PIPE_MGR_UNLOCK_STRUCT Unlock;
370 //
371 CamPipeMgr_GetTime(&Sec, &USec);
372 //
373 LOG_MSG("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)",
374 current->comm,
375 current->pid,
376 current->tgid,
377 Sec,
378 USec);
379 //
380 if(pFile->private_data != NULL)
381 {
382 pProc = (CAM_PIPE_MGR_PROC_STRUCT*)pFile->private_data;
383 //
384 if( pProc->Pid != 0 ||
385 pProc->Tgid != 0 ||
386 pProc->PipeMask != 0)
387 {
388 //
389 LOG_WRN("Proc:Name(%s),Pid(%d),Tgid(%d),PipeMask(0x%lX),Time(%ld.%06ld)",
390 pProc->ProcName,
391 pProc->Pid,
392 pProc->Tgid,
393 pProc->PipeMask,
394 pProc->TimeS,
395 pProc->TimeUS);
396 //
397 if(pProc->PipeMask)
398 {
399 LOG_WRN("Force to unlock pipe");
400 /*
401 LOG_WRN("Proc:Name(%s),Pid(%d),Tgid(%d),PipeMask(0x%08lX),Time(%ld.%06ld)",
402 pProc->ProcName,
403 pProc->Pid,
404 pProc->Tgid,
405 pProc->PipeMask,
406 pProc->TimeS,
407 pProc->TimeUS);
408 */
409 CamPipeMgr_SpinLock();
410 Unlock.PipeMask = pProc->PipeMask;
411 CamPipeMgr_UnlockPipe(&Unlock);
412 CamPipeMgr_SpinUnlock();
413 }
414 }
415 //
416 kfree(pFile->private_data);
417 pFile->private_data = NULL;
418 }
419 else
420 {
421 LOG_WRN("private_data is NULL");
422 /*
423 LOG_WRN("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)",
424 current->comm,
425 current->pid,
426 current->tgid,
427 Sec,
428 USec);
429 */
430 }
431 //
432 //LOG_MSG("OK");
433 return 0;
434 }
435 //-----------------------------------------------------------------------------
436 static int CamPipeMgr_Flush(
437 struct file* pFile,
438 fl_owner_t Id)
439 {
440 MUINT32 Sec = 0,USec = 0;
441 CAM_PIPE_MGR_PROC_STRUCT* pProc;
442 CAM_PIPE_MGR_UNLOCK_STRUCT Unlock;
443 //
444 CamPipeMgr_GetTime(&Sec, &USec);
445 //
446 LOG_MSG("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)",
447 current->comm,
448 current->pid,
449 current->tgid,
450 Sec,
451 USec);
452 //
453 if(pFile->private_data != NULL)
454 {
455 pProc = (CAM_PIPE_MGR_PROC_STRUCT*)pFile->private_data;
456 //
457 if( pProc->Pid != 0 ||
458 pProc->Tgid != 0 ||
459 pProc->PipeMask != 0)
460 {
461 //
462 LOG_WRN("Proc:Name(%s),Pid(%d),Tgid(%d),PipeMask(0x%lX),Time(%ld.%06ld)",
463 pProc->ProcName,
464 pProc->Pid,
465 pProc->Tgid,
466 pProc->PipeMask,
467 pProc->TimeS,
468 pProc->TimeUS);
469 //
470 if( pProc->Tgid == 0 &&
471 pProc->PipeMask != 0)
472 {
473 LOG_ERR("No Tgid info");
474 /*
475 LOG_ERR("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)",
476 current->comm,
477 current->pid,
478 current->tgid,
479 Sec,
480 USec);
481 LOG_ERR("Proc:Name(%s),Pid(%d),Tgid(%d),PipeMask(0x%08lX),Time(%ld.%06ld)",
482 pProc->ProcName,
483 pProc->Pid,
484 pProc->Tgid,
485 pProc->PipeMask,
486 pProc->TimeS,
487 pProc->TimeUS);
488 */
489 }
490 else
491 if( (pProc->Tgid == current->tgid) ||
492 ((pProc->Tgid != current->tgid) && (strcmp(current->comm, "binder") == 0)))
493 {
494 if(pProc->PipeMask)
495 {
496 LOG_WRN("Force to unlock pipe");
497 /*
498 LOG_WRN("Proc:Name(%s),Pid(%d),Tgid(%d),PipeMask(0x%08lX),Time(%ld.%06ld)",
499 pProc->ProcName,
500 pProc->Pid,
501 pProc->Tgid,
502 pProc->PipeMask,
503 pProc->TimeS,
504 pProc->TimeUS);
505 */
506 CamPipeMgr_SpinLock();
507 Unlock.PipeMask = pProc->PipeMask;
508 CamPipeMgr_UnlockPipe(&Unlock);
509 pProc->PipeMask = 0;
510 CamPipeMgr_SpinUnlock();
511 }
512 }
513 }
514 }
515 else
516 {
517 LOG_WRN("private_data is NULL");
518 /*
519 LOG_WRN("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)",
520 current->comm,
521 current->pid,
522 current->tgid,
523 Sec,
524 USec);
525 */
526 }
527 //
528 //LOG_MSG("OK");
529 return 0;
530 }
531 //-----------------------------------------------------------------------------
532 static long CamPipeMgr_Ioctl(
533 struct file* pFile,
534 unsigned int Cmd,
535 unsigned long Param)
536 {
537 MINT32 Ret = 0;
538 MUINT32 Sec = 0,USec = 0;
539 pid_t Pid;
540 pid_t Tgid;
541 char ProcName[TASK_COMM_LEN];
542 CAM_PIPE_MGR_LOCK_STRUCT Lock;
543 CAM_PIPE_MGR_UNLOCK_STRUCT Unlock;
544 CAM_PIPE_MGR_MODE_STRUCT Mode;
545 CAM_PIPE_MGR_ENABLE_STRUCT Enable;
546 CAM_PIPE_MGR_DISABLE_STRUCT Disable;
547 CAM_PIPE_MGR_PROC_STRUCT* pProc = (CAM_PIPE_MGR_PROC_STRUCT*)pFile->private_data;
548 CAM_PIPE_MGR_STATUS_ENUM Status;
549 //
550 CamPipeMgr_GetTime(&Sec, &USec);
551 /*
552 LOG_MSG("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)",
553 current->comm,
554 current->pid,
555 current->tgid,
556 Sec,
557 USec);
558 */
559 if(pFile->private_data == NULL)
560 {
561 LOG_ERR("private_data is NULL");
562 Ret = -EFAULT;
563 goto EXIT;
564 }
565 //
566 switch(Cmd)
567 {
568 case CAM_PIPE_MGR_LOCK:
569 {
570 if(copy_from_user(&Lock, (void*)Param, sizeof(CAM_PIPE_MGR_LOCK_STRUCT)) == 0)
571 {
572 if((Lock.PipeMask & CamPipeMgr.PipeLockTable[CamPipeMgr.Mode.ScenHw]) != Lock.PipeMask)
573 {
574 LOG_ERR("LOCK:Sw(%d),Hw(%d),LPM(0x%lX),PLT(0x%lX) fail",
575 CamPipeMgr.Mode.ScenSw,
576 CamPipeMgr.Mode.ScenHw,
577 Lock.PipeMask,
578 CamPipeMgr.PipeLockTable[CamPipeMgr.Mode.ScenHw]);
579 Ret = -EFAULT;
580 }
581 else
582 {
583 CamPipeMgr_SpinLock();
584 Status = CamPipeMgr_LockPipe(&Lock);
585 if(Status == CAM_PIPE_MGR_STATUS_OK)
586 {
587 pProc->PipeMask |= Lock.PipeMask;
588 if(pProc->Tgid == 0)
589 {
590 pProc->Pid = current->pid;
591 pProc->Tgid = current->tgid;
592 strcpy(pProc->ProcName,current->comm);
593 CamPipeMgr_SpinUnlock();
594 if(CamPipeMgr.LogMask & Lock.PipeMask)
595 {
596 LOG_MSG("LOCK:Sw(%d),Hw(%d),LPM(0x%lX),PLT(0x%lX) OK",
597 CamPipeMgr.Mode.ScenSw,
598 CamPipeMgr.Mode.ScenHw,
599 Lock.PipeMask,
600 CamPipeMgr.PipeLockTable[CamPipeMgr.Mode.ScenHw]);
601 LOG_MSG("LOCK:Proc:Name(%s),Pid(%d),Tgid(%d),PipeMask(0x%lX)",
602 pProc->ProcName,
603 pProc->Pid,
604 pProc->Tgid,
605 pProc->PipeMask);
606 }
607 }
608 else
609 {
610 CamPipeMgr_SpinUnlock();
611 if(pProc->Tgid != current->tgid)
612 {
613 LOG_ERR("LOCK:Tgid is inconsistent");
614 Ret = -EFAULT;
615 }
616 }
617 }
618 else
619 {
620 CamPipeMgr_SpinUnlock();
621 if( (CamPipeMgr.LogMask & Lock.PipeMask) ||
622 (CamPipeMgr.Mode.ScenSw == CAM_PIPE_MGR_SCEN_SW_NONE))
623 {
624 LOG_ERR("LOCK:Sw(%d),Hw(%d),LPM(0x%lX),PLT(0x%lX) fail,Status(%d)",
625 CamPipeMgr.Mode.ScenSw,
626 CamPipeMgr.Mode.ScenHw,
627 Lock.PipeMask,
628 CamPipeMgr.PipeLockTable[CamPipeMgr.Mode.ScenHw],
629 Status);
630 }
631 Ret = -EFAULT;
632 }
633 }
634 }
635 else
636 {
637 LOG_ERR("LOCK:copy_from_user fail");
638 Ret = -EFAULT;
639 }
640 break;
641 }
642 //
643 case CAM_PIPE_MGR_UNLOCK:
644 {
645 if(copy_from_user(&Unlock, (void*)Param, sizeof(CAM_PIPE_MGR_UNLOCK_STRUCT)) == 0)
646 {
647 CamPipeMgr_SpinLock();
648 if(pProc->PipeMask & Unlock.PipeMask)
649 {
650 CamPipeMgr_UnlockPipe(&Unlock);
651 //Store info before clear.
652 Pid = pProc->Pid;
653 Tgid = pProc->Tgid;
654 strcpy(ProcName,pProc->ProcName);
655 //
656 pProc->PipeMask &= (~Unlock.PipeMask);
657 if(pProc->PipeMask == 0)
658 {
659 pProc->Pid = 0;
660 pProc->Tgid = 0;
661 strcpy(pProc->ProcName,CAM_PIPE_MGR_PROC_NAME);
662 }
663 CamPipeMgr_SpinUnlock();
664 if(CamPipeMgr.LogMask & Unlock.PipeMask)
665 {
666 LOG_MSG("UNLOCK:Sw(%d),Hw(%d),UPM(0x%lX),PLT(0x%lX) OK",
667 CamPipeMgr.Mode.ScenSw,
668 CamPipeMgr.Mode.ScenHw,
669 Unlock.PipeMask,
670 CamPipeMgr.PipeLockTable[CamPipeMgr.Mode.ScenHw]);
671 LOG_MSG("UNLOCK:Proc:Name(%s),Pid(%d),Tgid(%d),PipeMask(0x%lX)",
672 ProcName,
673 Pid,
674 Tgid,
675 pProc->PipeMask);
676 }
677 }
678 else
679 {
680 CamPipeMgr_SpinUnlock();
681 if( (CamPipeMgr.LogMask & Unlock.PipeMask) ||
682 (CamPipeMgr.Mode.ScenSw == CAM_PIPE_MGR_SCEN_SW_NONE))
683 {
684 LOG_ERR("UNLOCK:Sw(%d),Hw(%d),UPM(0x%lX),PLT(0x%lX) fail, it was not locked before",
685 CamPipeMgr.Mode.ScenSw,
686 CamPipeMgr.Mode.ScenHw,
687 Unlock.PipeMask,
688 CamPipeMgr.PipeLockTable[CamPipeMgr.Mode.ScenHw]);
689 }
690 Ret = -EFAULT;
691 }
692 }
693 else
694 {
695 LOG_ERR("UNLOCK:copy_from_user fail");
696 Ret = -EFAULT;
697 }
698 break;
699 }
700 //
701 case CAM_PIPE_MGR_DUMP:
702 {
703 CamPipeMgr_DumpPipeInfo();
704 break;
705 }
706 //
707 case CAM_PIPE_MGR_SET_MODE:
708 {
709 if(copy_from_user(&Mode, (void*)Param, sizeof(CAM_PIPE_MGR_MODE_STRUCT)) == 0)
710 {
711 if((Mode.ScenHw > CAM_PIPE_MGR_SCEN_HW_VSS) || (Mode.ScenHw<0))
712 {
713 LOG_ERR("ScenHw(%d) > max(%d)",Mode.ScenHw,CAM_PIPE_MGR_SCEN_HW_VSS);
714 Ret = -EFAULT;
715 goto EXIT;
716 }
717 if((Mode.ScenSw > CAM_PIPE_MGR_SCEN_SW_N3D) || (Mode.ScenSw<0))
718 {
719 LOG_ERR("ScenSw(%d) > max(%d)",Mode.ScenSw,CAM_PIPE_MGR_SCEN_SW_N3D);
720 Ret = -EFAULT;
721 goto EXIT;
722 }
723 if((Mode.Dev > CAM_PIPE_MGR_DEV_VT) || (Mode.Dev<0))
724 {
725 LOG_ERR("Dev(%d) > max(%d)",Mode.Dev,CAM_PIPE_MGR_DEV_VT);
726 Ret = -EFAULT;
727 goto EXIT;
728 }
729 //
730 LOG_MSG("SET_MODE:Sw(%d),Hw(%d)",Mode.ScenSw,Mode.ScenHw);
731 if((CamPipeMgr.PipeMask | CamPipeMgr.PipeLockTable[Mode.ScenHw]) ^ CamPipeMgr.PipeLockTable[Mode.ScenHw])
732 {
733 LOG_ERR("SET_MODE:PM(0x%lX),PLT(0x%lX), some pipe should be unlock",
734 CamPipeMgr.PipeMask,
735 CamPipeMgr.PipeLockTable[Mode.ScenHw]);
736 Ret = -EFAULT;
737 }
738 //
739 CamPipeMgr_SpinLock();
740 memcpy(
741 &(CamPipeMgr.Mode),
742 &Mode,
743 sizeof(CAM_PIPE_MGR_MODE_STRUCT));
744 CamPipeMgr_UpdatePipeLockTable(CamPipeMgr.Mode.ScenSw);
745 CamPipeMgr_SpinUnlock();
746 LOG_MSG("SET_MODE:done");
747
748 }
749 else
750 {
751 LOG_ERR("SET_MODE:copy_from_user fail");
752 Ret = -EFAULT;
753 }
754 break;
755 }
756 //
757 case CAM_PIPE_MGR_GET_MODE:
758 {
759 if((CamPipeMgr.Mode.ScenHw > CAM_PIPE_MGR_SCEN_HW_VSS) ||(CamPipeMgr.Mode.ScenHw <0))
760 {
761 LOG_ERR("ScenHw(%d) > max(%d)",CamPipeMgr.Mode.ScenHw,CAM_PIPE_MGR_SCEN_HW_VSS);
762 Ret = -EFAULT;
763 goto EXIT;
764 }
765 if((CamPipeMgr.Mode.ScenSw > CAM_PIPE_MGR_SCEN_SW_N3D) || (CamPipeMgr.Mode.ScenSw<0))
766 {
767 LOG_ERR("ScenSw(%d) > max(%d)",CamPipeMgr.Mode.ScenSw,CAM_PIPE_MGR_SCEN_SW_N3D);
768 Ret = -EFAULT;
769 goto EXIT;
770 }
771 if((CamPipeMgr.Mode.Dev > CAM_PIPE_MGR_DEV_VT) || (CamPipeMgr.Mode.Dev<0))
772 {
773 LOG_ERR("Dev(%d) > max(%d)",CamPipeMgr.Mode.Dev,CAM_PIPE_MGR_DEV_VT);
774 Ret = -EFAULT;
775 goto EXIT;
776 }
777 //
778 if(copy_to_user((void*)Param, &(CamPipeMgr.Mode), sizeof(CAM_PIPE_MGR_MODE_STRUCT)) == 0)
779 {
780 //do nothing.
781 }
782 else
783 {
784 LOG_ERR("GET_MODE:copy_to_user fail");
785 Ret = -EFAULT;
786 }
787 break;
788 }
789 //
790 case CAM_PIPE_MGR_ENABLE_PIPE:
791 {
792 if(copy_from_user(&Enable, (void*)Param, sizeof(CAM_PIPE_MGR_ENABLE_STRUCT)) == 0)
793 {
794 LOG_MSG("ENABLE_PIPE:Sw(%d),Hw(%d):EPM(0x%lX),PLT(0x%lX)",
795 CamPipeMgr.Mode.ScenSw,
796 CamPipeMgr.Mode.ScenHw,
797 Enable.PipeMask,
798 CamPipeMgr_GtePipeLockTable(CamPipeMgr.Mode.ScenSw,CamPipeMgr.Mode.ScenHw));
799 if((Enable.PipeMask & CamPipeMgr_GtePipeLockTable(CamPipeMgr.Mode.ScenSw,CamPipeMgr.Mode.ScenHw)) != Enable.PipeMask)
800 {
801 LOG_ERR("ENABLE_PIPE:Some pipe are not available");
802 Ret = -EFAULT;
803 }
804 else
805 {
806 CamPipeMgr_SpinLock();
807 CamPipeMgr.PipeLockTable[CamPipeMgr.Mode.ScenHw] |= Enable.PipeMask;
808 CamPipeMgr_SpinUnlock();
809 }
810 }
811 else
812 {
813 LOG_ERR("ENABLE_PIPE:copy_from_user fail");
814 Ret = -EFAULT;
815 }
816 break;
817 }
818 //
819 case CAM_PIPE_MGR_DISABLE_PIPE:
820 {
821 if(copy_from_user(&Disable, (void*)Param, sizeof(CAM_PIPE_MGR_DISABLE_STRUCT)) == 0)
822 {
823 LOG_MSG("DISABLE_PIPE:Sw(%d),Hw(%d):DPM(0x%lX),PLT(0x%lX)",
824 CamPipeMgr.Mode.ScenSw,
825 CamPipeMgr.Mode.ScenHw,
826 Disable.PipeMask,
827 CamPipeMgr_GtePipeLockTable(CamPipeMgr.Mode.ScenSw,CamPipeMgr.Mode.ScenHw));
828 if((Disable.PipeMask & CamPipeMgr_GtePipeLockTable(CamPipeMgr.Mode.ScenSw,CamPipeMgr.Mode.ScenHw)) != Disable.PipeMask)
829 {
830 LOG_ERR("DISABLE_PIPE:Some pipe are not available");
831 Ret = -EFAULT;
832 }
833 else
834 {
835 CamPipeMgr_SpinLock();
836 CamPipeMgr.PipeLockTable[CamPipeMgr.Mode.ScenHw] &= (~Disable.PipeMask);
837 CamPipeMgr_SpinUnlock();
838 }
839 }
840 else
841 {
842 LOG_ERR("DISABLE_PIPE:copy_from_user fail");
843 Ret = -EFAULT;
844 }
845 break;
846 }
847 //
848 default:
849 {
850 LOG_ERR("Unknown cmd");
851 Ret = -EFAULT;
852 break;
853 }
854 }
855 //
856 EXIT:
857 if(Ret != 0)
858 {
859 if( (CamPipeMgr.LogMask & Lock.PipeMask) ||
860 (CamPipeMgr.Mode.ScenSw == CAM_PIPE_MGR_SCEN_SW_NONE))
861 {
862 LOG_ERR("Fail");
863 LOG_ERR("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)",
864 current->comm,
865 current->pid,
866 current->tgid,
867 Sec,
868 USec);
869 if(pFile->private_data != NULL)
870 {
871 LOG_ERR("Proc:Name(%s),Pid(%d),Tgid(%d),PipeMask(0x%lX),Time(%ld.%06ld)",
872 pProc->ProcName,
873 pProc->Pid,
874 pProc->Tgid,
875 pProc->PipeMask,
876 Sec,
877 USec);
878 }
879 CamPipeMgr_DumpPipeInfo();
880 }
881 }
882 return Ret;
883 }
884 //-----------------------------------------------------------------------------
885 static const struct file_operations CamPipeMgr_FileOper =
886 {
887 .owner = THIS_MODULE,
888 .open = CamPipeMgr_Open,
889 .release = CamPipeMgr_Release,
890 .flush = CamPipeMgr_Flush,
891 .unlocked_ioctl = CamPipeMgr_Ioctl
892 };
893 //-----------------------------------------------------------------------------
894 static int CamPipeMgr_RegCharDev(void)
895 {
896 MINT32 Ret = 0;
897 //
898 LOG_MSG("E");
899 //
900 CamPipeMgr.DevNo = 0;
901 Ret = alloc_chrdev_region(
902 &(CamPipeMgr.DevNo),
903 CAM_PIPE_MGR_DEV_NO_MINOR,
904 CAM_PIPE_MGR_DEV_NUM,
905 CAM_PIPE_MGR_DEV_NAME);
906 if(Ret < 0)
907 {
908 LOG_ERR("alloc_chrdev_region fail:Ret(%ld)",Ret);
909 return Ret;
910 }
911 //Allocate memory for driver
912 CamPipeMgr.pCharDrv = cdev_alloc();
913 if(CamPipeMgr.pCharDrv == NULL)
914 {
915 unregister_chrdev_region(
916 CamPipeMgr.DevNo,
917 CAM_PIPE_MGR_DEV_NUM);
918 LOG_ERR("Allocate mem for kobject failed");
919 return -ENOMEM;
920 }
921 //Attatch file operation.
922 cdev_init(
923 CamPipeMgr.pCharDrv,
924 &CamPipeMgr_FileOper);
925 CamPipeMgr.pCharDrv->owner = THIS_MODULE;
926 //Add to system
927 if(cdev_add(CamPipeMgr.pCharDrv, CamPipeMgr.DevNo, CAM_PIPE_MGR_DEV_MINOR_NUM))
928 {
929 LOG_ERR("Attatch file operation failed");
930 unregister_chrdev_region(
931 CamPipeMgr.DevNo,
932 CAM_PIPE_MGR_DEV_NUM);
933 return -EAGAIN;
934 }
935 //
936 LOG_MSG("X");
937 return Ret;
938 }
939 //-----------------------------------------------------------------------------
940 static inline void CamPipeMgr_UnregCharDev(void)
941 {
942 LOG_MSG("E");
943 //Release char driver
944 cdev_del(CamPipeMgr.pCharDrv);
945 unregister_chrdev_region(
946 CamPipeMgr.DevNo,
947 CAM_PIPE_MGR_DEV_NUM);
948 //
949 LOG_MSG("X");
950 }
951 //-----------------------------------------------------------------------------
952 static int CamPipeMgr_Probe(struct platform_device *pDev)
953 {
954 MINT32 Ret = 0;
955 MUINT32 i;
956 struct device* pDevice = NULL;
957 //
958 LOG_MSG("E");
959 //
960 Ret = CamPipeMgr_RegCharDev();
961 if(Ret < 0)
962 {
963 LOG_ERR("RegCharDev fail:Ret(%ld)",Ret);
964 return Ret;
965 }
966
967 CamPipeMgr.pClass = class_create(
968 THIS_MODULE,
969 CAM_PIPE_MGR_DEV_NAME);
970 if(IS_ERR(CamPipeMgr.pClass))
971 {
972 Ret = PTR_ERR(CamPipeMgr.pClass);
973 LOG_ERR("class_create fail:Ret(%ld)",Ret);
974 return Ret;
975 }
976 pDevice = device_create(
977 CamPipeMgr.pClass,
978 NULL,
979 CamPipeMgr.DevNo,
980 NULL,
981 CAM_PIPE_MGR_DEV_NAME);
982 if(IS_ERR(pDevice))
983 {
984 LOG_ERR("device_create fail");
985 return (int)pDevice;
986 }
987 //Initial variable
988 spin_lock_init(&(CamPipeMgr.SpinLock));
989 init_waitqueue_head(&(CamPipeMgr.WaitQueueHead));
990 CamPipeMgr.Mode.ScenSw = CAM_PIPE_MGR_SCEN_SW_NONE;
991 CamPipeMgr.Mode.ScenHw = CAM_PIPE_MGR_SCEN_HW_NONE;
992 //
993 for(i=0;i<CAM_PIPE_MGR_PIPE_AMOUNT;i++)
994 {
995 CamPipeMgr.PipeInfo[i].Pid = 0;
996 CamPipeMgr.PipeInfo[i].Tgid = 0;
997 strcpy(CamPipeMgr.PipeInfo[i].ProcName,CAM_PIPE_MGR_PROC_NAME);
998 CamPipeMgr.PipeInfo[i].TimeS = 0;
999 CamPipeMgr.PipeInfo[i].TimeUS = 0;
1000 }
1001 //
1002 strcpy(
1003 CamPipeMgr.PipeName[CAM_PIPE_MGR_PIPE_CAM_IO],
1004 CAM_PIPE_MGR_PIPE_NAME_CAM_IO);
1005 strcpy(
1006 CamPipeMgr.PipeName[CAM_PIPE_MGR_PIPE_POST_PROC],
1007 CAM_PIPE_MGR_PIPE_NAME_POST_PROC);
1008 strcpy(
1009 CamPipeMgr.PipeName[CAM_PIPE_MGR_PIPE_XDP_CAM],
1010 CAM_PIPE_MGR_PIPE_NAME_XDP_CAM);
1011 //
1012 CamPipeMgr_UpdatePipeLockTable(CamPipeMgr.Mode.ScenSw);
1013 CamPipeMgr.LogMask = ( CAM_PIPE_MGR_PIPE_MASK_CAM_IO|
1014 CAM_PIPE_MGR_PIPE_MASK_POST_PROC|
1015 CAM_PIPE_MGR_PIPE_MASK_XDP_CAM);
1016 //
1017 LOG_MSG("X");
1018 return Ret;
1019 }
1020 //-----------------------------------------------------------------------------
1021 static int CamPipeMgr_Remove(struct platform_device *pdev)
1022 {
1023 LOG_MSG("E");
1024 //unregister char driver.
1025 CamPipeMgr_UnregCharDev();
1026 //
1027 device_destroy(
1028 CamPipeMgr.pClass,
1029 CamPipeMgr.DevNo);
1030 class_destroy(CamPipeMgr.pClass);
1031 //
1032 LOG_MSG("X");
1033 return 0;
1034 }
1035 //-----------------------------------------------------------------------------
1036 static int CamPipeMgr_Suspend(
1037 struct platform_device* pDev,
1038 pm_message_t Mesg)
1039 {
1040 LOG_MSG("");
1041 return 0;
1042 }
1043 //-----------------------------------------------------------------------------
1044 static int CamPipeMgr_Resume(struct platform_device *pDev)
1045 {
1046 LOG_MSG("");
1047 return 0;
1048 }
1049 //-----------------------------------------------------------------------------
1050 static struct platform_driver CamPipeMgr_PlatformDriver =
1051 {
1052 .probe = CamPipeMgr_Probe,
1053 .remove = CamPipeMgr_Remove,
1054 .suspend = CamPipeMgr_Suspend,
1055 .resume = CamPipeMgr_Resume,
1056 .driver =
1057 {
1058 .name = CAM_PIPE_MGR_DEV_NAME,
1059 .owner = THIS_MODULE,
1060 }
1061 };
1062 //-----------------------------------------------------------------------------
1063 static int __init CamPipeMgr_Init(void)
1064 {
1065 MINT32 Ret = 0;
1066 //
1067 LOG_MSG("E");
1068 //
1069 Ret = platform_driver_register(&CamPipeMgr_PlatformDriver);
1070 if(Ret < 0)
1071 {
1072 LOG_ERR("Failed to register driver:Ret(%ld)",Ret);
1073 return Ret;
1074 }
1075 //
1076 LOG_MSG("X");
1077 return Ret;
1078 }
1079 //-----------------------------------------------------------------------------
1080 static void __exit CamPipeMgr_Exit(void)
1081 {
1082 LOG_MSG("E");
1083 platform_driver_unregister(&CamPipeMgr_PlatformDriver);
1084 LOG_MSG("X");
1085 }
1086 //-----------------------------------------------------------------------------
1087 module_init(CamPipeMgr_Init);
1088 module_exit(CamPipeMgr_Exit);
1089 MODULE_DESCRIPTION("Camera Pipe Manager Driver");
1090 MODULE_AUTHOR("Marx <Marx.Chiu@Mediatek.com>");
1091 MODULE_LICENSE("GPL");
1092 //-----------------------------------------------------------------------------
1093