1 #include <linux/uaccess.h>
2 #include <linux/module.h>
3 #include <linux/types.h>
4 #include <linux/device.h>
6 #include <linux/platform_device.h>
7 #include <linux/cdev.h>
9 #include <linux/proc_fs.h> //proc file use
10 #include <linux/slab.h> //kmalloc/kfree in kernel 3.10
11 #include <linux/spinlock.h>
13 #include <linux/sched.h>
14 #include <linux/delay.h>
15 #include <linux/ioctl.h>
16 #include <linux/xlog.h>
17 #include <mach/mt_reg_base.h>
18 #include <mach/mt_clkmgr.h>
19 #include <mach/sync_write.h>
20 #include <mach/camera_sysram.h>
21 #include <mach/mt_reg_base.h>
22 #include <mach/camera_sysram_imp.h>
24 #define ISP_VALID_REG_RANGE 0x10000
25 #define IMGSYS_BASE_ADDR 0x15000000
27 //-----------------------------------------------------------------------------
28 static SYSRAM_STRUCT Sysram
;
29 //------------------------------------------------------------------------------
30 static void SYSRAM_GetTime(MUINT64
* pUS64
, MUINT32
* pSec
, MUINT32
* pUSec
)
35 Time
= ktime_get();//ns
37 do_div( TimeSec
, 1000 );
40 *pUSec
= do_div( TimeSec
, 1000000);
41 *pSec
= (MUINT64
)TimeSec
;
43 //------------------------------------------------------------------------------
44 static void SYSRAM_CheckClock(void)
46 //LOG_MSG("AllocatedTbl(0x%08X),EnableClk(%d)",Sysram.AllocatedTbl,Sysram.EnableClk);
47 if(Sysram
.AllocatedTbl
)
49 if(!(Sysram
.EnableClk
))
51 Sysram
.EnableClk
= true;
53 LOG_MSG("AllocatedTbl(0x%08lX),EnableClk(%d)",
63 Sysram
.EnableClk
= false;
65 LOG_MSG("AllocatedTbl(0x%08lX),EnableClk(%d)",
72 //------------------------------------------------------------------------------
73 static void SYSRAM_DumpResMgr(void)
75 unsigned int u4Idx
= 0;
76 LOG_MSG("TotalUserCount(%ld),AllocatedTbl(0x%lX)",
77 Sysram
.TotalUserCount
,
80 for (u4Idx
= 0; u4Idx
< SYSRAM_USER_AMOUNT
; u4Idx
++)
82 if ( 0 < Sysram
.AllocatedSize
[u4Idx
] )
84 SYSRAM_USER_STRUCT
*const pUserInfo
= &Sysram
.UserInfo
[u4Idx
];
85 LOG_MSG("[id:%u][%s][size:0x%lX][pid:%d][tgid:%d][%s][%5lu.%06lu]",
87 SysramUserName
[u4Idx
],
88 Sysram
.AllocatedSize
[u4Idx
],
98 //------------------------------------------------------------------------------
99 static inline MBOOL
SYSRAM_IsBadOwner(SYSRAM_USER_ENUM
const User
)
101 if(SYSRAM_USER_AMOUNT
<= User
|| User
< 0)
110 //------------------------------------------------------------------------------
111 static void SYSRAM_SetUserTaskInfo(SYSRAM_USER_ENUM
const User
)
113 if(!SYSRAM_IsBadOwner(User
))
115 SYSRAM_USER_STRUCT
*const pUserInfo
= &Sysram
.UserInfo
[User
];
117 pUserInfo
->pid
= current
->pid
;
118 pUserInfo
->tgid
= current
->tgid
;
119 memcpy(pUserInfo
->ProcName
, current
->comm
, sizeof(pUserInfo
->ProcName
));
121 SYSRAM_GetTime(&(pUserInfo
->Time64
), &(pUserInfo
->TimeS
), &(pUserInfo
->TimeUS
));
124 //------------------------------------------------------------------------------
125 static void SYSRAM_ResetUserTaskInfo(SYSRAM_USER_ENUM
const User
)
127 if(!SYSRAM_IsBadOwner(User
))
129 SYSRAM_USER_STRUCT
*const pUserInfo
= &Sysram
.UserInfo
[User
];
130 memset(pUserInfo
, 0, sizeof(*pUserInfo
));
133 //------------------------------------------------------------------------------
134 static inline void SYSRAM_SpinLock(void)
136 spin_lock(&Sysram
.SpinLock
);
138 //------------------------------------------------------------------------------
139 static inline void SYSRAM_SpinUnlock(void)
141 spin_unlock(&Sysram
.SpinLock
);
143 //------------------------------------------------------------------------------
144 static inline MBOOL
SYSRAM_UserIsLocked(SYSRAM_USER_ENUM
const User
)
146 if((1 << User
) & Sysram
.AllocatedTbl
)
155 //------------------------------------------------------------------------------
156 static inline MBOOL
SYSRAM_UserIsUnlocked(SYSRAM_USER_ENUM
const User
)
158 if(SYSRAM_UserIsLocked(User
) == 0)
167 //------------------------------------------------------------------------------
168 static void SYSRAM_LockUser(SYSRAM_USER_ENUM
const User
, MUINT32
const Size
)
170 if(SYSRAM_UserIsLocked(User
))
175 Sysram
.TotalUserCount
++;
176 Sysram
.AllocatedTbl
|= (1 << User
);
177 Sysram
.AllocatedSize
[User
] = Size
;
178 SYSRAM_SetUserTaskInfo(User
);
180 if((1<<User
) & SysramLogUserMask
)
182 SYSRAM_USER_STRUCT
*const pUserInfo
= &Sysram
.UserInfo
[User
];
183 LOG_MSG("[%s][%lu bytes]OK,Time(%lu.%06lu)",
184 SysramUserName
[User
],
185 Sysram
.AllocatedSize
[User
],
190 //------------------------------------------------------------------------------
191 static void SYSRAM_UnlockUser(SYSRAM_USER_ENUM
const User
)
192 { if(SYSRAM_UserIsUnlocked(User
))
197 if((1<<User
) & SysramLogUserMask
)
199 SYSRAM_USER_STRUCT
*const pUserInfo
= &Sysram
.UserInfo
[User
];
202 SYSRAM_GetTime(&Time64
,&Sec
,&USec
);
204 LOG_MSG("[%s][%lu bytes]Time(%lu.%06lu - %lu.%06lu)(%lu.%06lu)",
205 SysramUserName
[User
],
206 Sysram
.AllocatedSize
[User
],
211 ((MUINT32
)(Time64
-pUserInfo
->Time64
))/1000,
212 ((MUINT32
)(Time64
-pUserInfo
->Time64
))%1000);
215 if(Sysram
.TotalUserCount
> 0)
217 Sysram
.TotalUserCount
--;
219 Sysram
.AllocatedTbl
&= (~(1 << User
));
220 Sysram
.AllocatedSize
[User
] = 0;
221 SYSRAM_ResetUserTaskInfo(User
);
223 //------------------------------------------------------------------------------
224 static void SYSRAM_DumpLayout(void)
227 SYSRAM_MEM_NODE_STRUCT
* pCurrNode
= NULL
;
229 LOG_DMP("[SYSRAM_DumpLayout]\n");
230 LOG_DMP("AllocatedTbl = 0x%08lX\n",Sysram
.AllocatedTbl
);
231 LOG_DMP("=========================================\n");
232 for (Index
= 0; Index
< SYSRAM_MEM_BANK_AMOUNT
; Index
++)
234 LOG_DMP("\n [Mem Pool %ld] (IndexTbl, UserCount)=(%lX, %ld)\n",
236 SysramMemPoolInfo
[Index
].IndexTbl
,
237 SysramMemPoolInfo
[Index
].UserCount
);
238 LOG_DMP("[Locked Time] [Owner Offset Size Index pCurrent pPrevious pNext] [pid tgid] [Proc Name / Owner Name]\n");
239 pCurrNode
= &SysramMemPoolInfo
[Index
].pMemNode
[0];
240 while(NULL
!= pCurrNode
)
242 SYSRAM_USER_ENUM
const User
= pCurrNode
->User
;
243 if(SYSRAM_IsBadOwner(User
))
246 "------------ --------"
247 " %2d\t0x%05lX 0x%05lX %ld %p %p\t%p\n",
258 SYSRAM_USER_STRUCT
*const pUserInfo
= &Sysram
.UserInfo
[User
];
260 " %2d\t0x%05lX 0x%05lX %ld %p %p\t%p"
261 " %-4d %-4d \"%s\" / \"%s\"\n",
274 SysramUserName
[User
]);
276 pCurrNode
= pCurrNode
->pNext
;
282 //------------------------------------------------------------------------------
283 static SYSRAM_MEM_NODE_STRUCT
* SYSRAM_AllocNode(SYSRAM_MEM_POOL_STRUCT
*const pMemPoolInfo
)
285 SYSRAM_MEM_NODE_STRUCT
* pNode
= NULL
;
288 for(Index
= 0; Index
< pMemPoolInfo
->UserAmount
; Index
+=1)
290 if((pMemPoolInfo
->IndexTbl
) & (1 << Index
))
292 pMemPoolInfo
->IndexTbl
&= (~(1 << Index
));
293 // A free node is found.
294 pNode
= &pMemPoolInfo
->pMemNode
[Index
];
295 pNode
->User
= SYSRAM_USER_NONE
;
300 pNode
->Index
= Index
;
307 LOG_ERR("returns NULL - pMemPoolInfo->IndexTbl(%lX)",pMemPoolInfo
->IndexTbl
);
311 //------------------------------------------------------------------------------
312 static void SYSRAM_FreeNode(
313 SYSRAM_MEM_POOL_STRUCT
*const pMemPoolInfo
,
314 SYSRAM_MEM_NODE_STRUCT
*const pNode
)
316 pMemPoolInfo
->IndexTbl
|= (1<<pNode
->Index
);
317 pNode
->User
= SYSRAM_USER_NONE
;
324 //------------------------------------------------------------------------------
325 static MBOOL
SYSRAM_IsLegalSizeToAlloc(
326 SYSRAM_MEM_BANK_ENUM
const MemBankNo
,
327 SYSRAM_USER_ENUM
const User
,
331 // (1) Check the memory pool.
334 case SYSRAM_MEM_BANK_BAD
:
335 case SYSRAM_MEM_BANK_AMOUNT
:
337 // Illegal Memory Pool: return "illegal"
347 // Here we use the dynamic memory pools.
348 MaxSize
= SysramUserSize
[User
];
353 LOG_ERR("[User:%s]requested size(0x%lX) > max size(0x%lX)",
354 SysramUserName
[User
],
362 //------------------------------------------------------------------------------
364 Alignment should be 2^N, 4/8/2048 bytes alignment only
367 static MUINT32
SYSRAM_AllocUserPhy(
368 SYSRAM_USER_ENUM
const User
,
370 MUINT32
const Alignment
,
371 SYSRAM_MEM_BANK_ENUM
const MemBankNo
374 SYSRAM_MEM_NODE_STRUCT
* pSplitNode
= NULL
;
375 SYSRAM_MEM_NODE_STRUCT
* pCurrNode
= NULL
;
376 MUINT32 AlingnedAddr
= 0;
377 MUINT32 ActualSize
= 0;
379 SYSRAM_MEM_POOL_STRUCT
*const pMemPoolInfo
= SYSRAM_GetMemPoolInfo(MemBankNo
);
385 pCurrNode
= &pMemPoolInfo
->pMemNode
[0];
386 for (; pCurrNode
&& pCurrNode
->Offset
< pMemPoolInfo
->Size
; pCurrNode
= pCurrNode
->pNext
)
388 if(SYSRAM_USER_NONE
== pCurrNode
->User
)
391 AlingnedAddr
= (pCurrNode
->Offset
+ Alignment
- 1)&(~(Alignment
- 1));
392 ActualSize
= Size
+ AlingnedAddr
- pCurrNode
->Offset
;
393 if (ActualSize
<= pCurrNode
->Length
)
395 // Hit!! Split into 2
396 // pSplitNode pointers to the next available (free) node.
397 pSplitNode
= SYSRAM_AllocNode(pMemPoolInfo
);
398 pSplitNode
->Offset
= pCurrNode
->Offset
+ ActualSize
;
399 pSplitNode
->Length
= pCurrNode
->Length
- ActualSize
;
400 pSplitNode
->pPrev
= pCurrNode
;
401 pSplitNode
->pNext
= pCurrNode
->pNext
;
403 pCurrNode
->User
= User
;
404 pCurrNode
->Length
= ActualSize
;
405 pCurrNode
->pNext
= pSplitNode
;
407 if(NULL
!= pSplitNode
->pNext
)
409 pSplitNode
->pNext
->pPrev
= pSplitNode
;
412 pMemPoolInfo
->UserCount
++;
420 return ActualSize
? (AlingnedAddr
+ pMemPoolInfo
->Addr
) : 0;
422 //------------------------------------------------------------------------------
423 static MBOOL
SYSRAM_FreeUserPhy(
424 SYSRAM_USER_ENUM
const User
,
425 SYSRAM_MEM_BANK_ENUM
const MemBankNo
)
428 SYSRAM_MEM_NODE_STRUCT
* pPrevOrNextNode
= NULL
;
429 SYSRAM_MEM_NODE_STRUCT
* pCurrNode
= NULL
;
430 SYSRAM_MEM_NODE_STRUCT
* pTempNode
= NULL
;
431 SYSRAM_MEM_POOL_STRUCT
*const pMemPoolInfo
= SYSRAM_GetMemPoolInfo(MemBankNo
);
435 LOG_ERR("pMemPoolInfo==NULL,User(%d),MemBankNo(%d)",User
,MemBankNo
);
439 pCurrNode
= &pMemPoolInfo
->pMemNode
[0];
440 for(; pCurrNode
; pCurrNode
= pCurrNode
->pNext
)
442 if(User
== pCurrNode
->User
)
444 Ret
= MTRUE
; // user is found.
445 if ( pMemPoolInfo
->UserCount
> 0 )
446 pMemPoolInfo
->UserCount
--;
448 pCurrNode
->User
= SYSRAM_USER_NONE
;
449 if(NULL
!= pCurrNode
->pPrev
)
451 pPrevOrNextNode
= pCurrNode
->pPrev
;
453 if(SYSRAM_USER_NONE
== pPrevOrNextNode
->User
)
455 //Merge previous: prev(o) + curr(x)
456 pTempNode
= pCurrNode
;
457 pCurrNode
= pPrevOrNextNode
;
458 pCurrNode
->Length
+= pTempNode
->Length
;
459 pCurrNode
->pNext
= pTempNode
->pNext
;
460 if(NULL
!= pTempNode
->pNext
)
462 pTempNode
->pNext
->pPrev
= pCurrNode
;
464 SYSRAM_FreeNode(pMemPoolInfo
, pTempNode
);
468 if(NULL
!= pCurrNode
->pNext
)
470 pPrevOrNextNode
= pCurrNode
->pNext
;
472 if(SYSRAM_USER_NONE
== pPrevOrNextNode
->User
)
474 //Merge next: curr(o) + next(x)
475 pTempNode
= pPrevOrNextNode
;
476 pCurrNode
->Length
+= pTempNode
->Length
;
477 pCurrNode
->pNext
= pTempNode
->pNext
;
478 if(NULL
!= pCurrNode
->pNext
)
480 pCurrNode
->pNext
->pPrev
= pCurrNode
;
482 SYSRAM_FreeNode(pMemPoolInfo
, pTempNode
);
491 //------------------------------------------------------------------------------
492 static MUINT32
SYSRAM_AllocUser(
493 SYSRAM_USER_ENUM
const User
,
495 MUINT32
const Alignment
)
498 SYSRAM_MEM_BANK_ENUM
const MemBankNo
= SYSRAM_GetMemBankNo(User
);
500 if(SYSRAM_IsBadOwner(User
))
502 LOG_ERR("User(%d) out of range(%d)",User
,SYSRAM_USER_AMOUNT
);
506 if(!SYSRAM_IsLegalSizeToAlloc(MemBankNo
, User
, Size
))
513 case SYSRAM_MEM_BANK_BAD
:
514 case SYSRAM_MEM_BANK_AMOUNT
:
521 Addr
= SYSRAM_AllocUserPhy(
532 SYSRAM_LockUser(User
,Size
);
537 //------------------------------------------------------------------------------
538 static void SYSRAM_FreeUser(SYSRAM_USER_ENUM
const User
)
540 SYSRAM_MEM_BANK_ENUM
const MemBankNo
= SYSRAM_GetMemBankNo(User
);
544 case SYSRAM_MEM_BANK_BAD
:
545 case SYSRAM_MEM_BANK_AMOUNT
:
552 if(SYSRAM_FreeUserPhy(User
, MemBankNo
))
554 SYSRAM_UnlockUser(User
);
558 LOG_ERR("Cannot free User(%d)",User
);
565 //------------------------------------------------------------------------------
566 static MUINT32
SYSRAM_MsToJiffies(MUINT32 TimeMs
)
568 return ((TimeMs
*HZ
+ 512) >> 10);
570 //------------------------------------------------------------------------------
571 static MUINT32
SYSRAM_TryAllocUser(
572 SYSRAM_USER_ENUM
const User
,
574 MUINT32
const Alignment
)
580 if(SYSRAM_UserIsLocked(User
))
583 LOG_ERR("[User:%s]has been already allocated!",SysramUserName
[User
]);
587 Addr
= SYSRAM_AllocUser(User
, Size
, Alignment
);
596 //------------------------------------------------------------------------------
597 static MUINT32
SYSRAM_IOC_Alloc(
598 SYSRAM_USER_ENUM
const User
,
601 MUINT32
const TimeoutMS
)
606 if(SYSRAM_IsBadOwner(User
))
608 LOG_ERR("User(%d) out of range(%d)",User
,SYSRAM_USER_AMOUNT
);
614 LOG_ERR("[User:%s]allocates 0 size!",SysramUserName
[User
]);
618 Addr
= SYSRAM_TryAllocUser(User
, Size
, Alignment
);
621 || 0 == TimeoutMS
//failure without a timeout specified
627 TimeOut
= wait_event_interruptible_timeout(
628 Sysram
.WaitQueueHead
,
629 0 != ( Addr
= SYSRAM_TryAllocUser(User
, Size
, Alignment
) ),
630 SYSRAM_MsToJiffies(TimeoutMS
));
632 if(0 == TimeOut
&& 0 == Addr
)
634 LOG_ERR("[User:%s]allocate timeout",SysramUserName
[User
]);
640 LOG_ERR("[User:%s]fails to allocate.Size(%lu),Alignment(%lu),TimeoutMS(%lu)",
641 SysramUserName
[User
],
649 if ( (1<<User
) & SysramLogUserMask
)
651 LOG_MSG("[User:%s]%lu bytes OK",
652 SysramUserName
[User
],
659 //------------------------------------------------------------------------------
660 static void SYSRAM_IOC_Free(SYSRAM_USER_ENUM User
)
662 if(SYSRAM_IsBadOwner(User
))
664 LOG_ERR("User(%d) out of range(%d)",User
,SYSRAM_USER_AMOUNT
);
669 SYSRAM_FreeUser(User
);
670 wake_up_interruptible(&Sysram
.WaitQueueHead
);
674 if((1<<User
) & SysramLogUserMask
)
676 LOG_MSG("[User:%s]Done",SysramUserName
[User
]);
679 //------------------------------------------------------------------------------
680 static int SYSRAM_Open(
681 struct inode
* pInode
,
685 MUINT32 Sec
= 0,USec
= 0;
687 SYSRAM_PROC_STRUCT
* pProc
;
689 SYSRAM_GetTime(&Time64
, &Sec
, &USec
);
691 LOG_MSG("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)",
700 pFile
->private_data
= kmalloc(sizeof(SYSRAM_PROC_STRUCT
) , GFP_ATOMIC
);
701 if(pFile
->private_data
== NULL
)
707 pProc
= (SYSRAM_PROC_STRUCT
*)(pFile
->private_data
);
710 strcpy(pProc
->ProcName
,SYSRAM_PROC_NAME
);
712 pProc
->Time64
= Time64
;
714 pProc
->TimeUS
= USec
;
721 LOG_ERR("No enough memory");
723 LOG_ERR("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)",
734 //------------------------------------------------------------------------------
735 static int SYSRAM_Release(
736 struct inode
* pInode
,
740 MUINT32 Sec
= 0,USec
= 0;
742 SYSRAM_PROC_STRUCT
* pProc
;
744 SYSRAM_GetTime(&Time64
, &Sec
, &USec
);
746 LOG_MSG("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)",
753 if(pFile
->private_data
!= NULL
)
755 pProc
= (SYSRAM_PROC_STRUCT
*)(pFile
->private_data
);
757 if( pProc
->Pid
!= 0 ||
762 LOG_WRN("Proc:Name(%s),pid(%d),tgid(%d),Table(0x%08lX),Time(%ld.%06ld)",
772 LOG_WRN("Force to release");
774 LOG_WRN("Proc:Name(%s),pid(%d),tgid(%d),Table(0x%08lX),Time(%ld.%06ld)",
784 for(Index
= 0 ; Index
< SYSRAM_USER_AMOUNT
; Index
++)
786 if(pProc
->Table
& (1 << Index
))
788 SYSRAM_IOC_Free((SYSRAM_USER_ENUM
)Index
);
794 kfree(pFile
->private_data
);
795 pFile
->private_data
= NULL
;
799 LOG_WRN("private_data is NULL");
801 LOG_WRN("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)",
812 //------------------------------------------------------------------------------
813 static int SYSRAM_Flush(
818 MUINT32 Sec
= 0,USec
= 0;
820 SYSRAM_PROC_STRUCT
* pProc
;
822 SYSRAM_GetTime(&Time64
, &Sec
, &USec
);
824 LOG_MSG("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)",
831 if(pFile
->private_data
!= NULL
)
833 pProc
= (SYSRAM_PROC_STRUCT
*)pFile
->private_data
;
835 if( pProc
->Pid
!= 0 ||
840 LOG_WRN("Proc:Name(%s),pid(%d),tgid(%d),Table(0x%08lX),Time(%ld.%06ld)",
848 if( pProc
->Tgid
== 0 &&
851 LOG_ERR("No Tgid info");
853 LOG_ERR("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)",
859 LOG_ERR("Proc:Name(%s),pid(%d),tgid(%d),Table(0x%08lX),Time(%ld.%06ld)",
869 if( (pProc
->Tgid
== current
->tgid
) ||
870 ((pProc
->Tgid
!= current
->tgid
) && (strcmp(current
->comm
, "binder") == 0)))
874 LOG_WRN("Force to release");
876 LOG_WRN("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)",
885 for(Index
= 0 ; Index
< SYSRAM_USER_AMOUNT
; Index
++)
887 if(pProc
->Table
& (1 << Index
))
889 SYSRAM_IOC_Free((SYSRAM_USER_ENUM
)Index
);
901 LOG_WRN("private_data is NULL");
903 LOG_WRN("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)",
914 //------------------------------------------------------------------------------
915 static int SYSRAM_mmap(
917 struct vm_area_struct
* pVma
)
922 pVma
->vm_page_prot
= pgprot_noncached(pVma
->vm_page_prot
);
923 length
=(long)(pVma
->vm_end
- pVma
->vm_start
);
924 pfn
=pVma
->vm_pgoff
<<PAGE_SHIFT
;//page from number, physical address of kernel memory
925 LOG_WRN("pVma->vm_pgoff(0x%x),phy(0x%x),pVmapVma->vm_start(0x%x),pVma->vm_end(0x%x),length(0x%x)",\
926 pVma
->vm_pgoff
,pVma
->vm_pgoff
<<PAGE_SHIFT
,pVma
->vm_start
,pVma
->vm_end
,length
);
927 if((length
>ISP_VALID_REG_RANGE
) || (pfn
<IMGSYS_BASE_ADDR
) || (pfn
>(IMGSYS_BASE_ADDR
+ISP_VALID_REG_RANGE
)))
929 LOG_ERR("mmap range error : vm_start(0x%x),vm_end(0x%x),length(0x%x),pfn(0x%x)!",pVma
->vm_start
,pVma
->vm_end
,length
,pfn
);
936 pVma
->vm_end
- pVma
->vm_start
,
944 //------------------------------------------------------------------------------
945 static long SYSRAM_Ioctl(
951 MUINT32 Sec
= 0,USec
= 0;
953 SYSRAM_PROC_STRUCT
* pProc
= (SYSRAM_PROC_STRUCT
*)pFile
->private_data
;
954 SYSRAM_ALLOC_STRUCT Alloc
;
955 SYSRAM_USER_ENUM User
;
957 SYSRAM_GetTime(&Time64
, &Sec
, &USec
);
959 LOG_MSG("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)",
966 if(pFile
->private_data
== NULL
)
968 LOG_WRN("private_data is NULL.");
977 if(copy_from_user(&Alloc
, (void*)Param
, sizeof(SYSRAM_ALLOC_STRUCT
)) == 0)
979 if(SYSRAM_IsBadOwner(Alloc
.User
))
981 LOG_ERR("User(%d) out of range(%d)",Alloc
.User
,SYSRAM_USER_AMOUNT
);
986 Alloc
.Addr
= SYSRAM_IOC_Alloc(
994 pProc
->Table
|= (1 << Alloc
.User
);
997 pProc
->Pid
= current
->pid
;
998 pProc
->Tgid
= current
->tgid
;
999 strcpy(pProc
->ProcName
,current
->comm
);
1000 SYSRAM_SpinUnlock();
1004 SYSRAM_SpinUnlock();
1005 if(pProc
->Tgid
!= current
->tgid
)
1007 LOG_ERR("Tgid is inconsistent");
1017 if(copy_to_user((void*)Param
, &Alloc
, sizeof(SYSRAM_ALLOC_STRUCT
)) )
1019 LOG_ERR("copy to user failed");
1025 LOG_ERR("copy_from_user fail");
1033 if(copy_from_user(&User
, (void*)Param
, sizeof(SYSRAM_USER_ENUM
)) == 0)
1035 if(SYSRAM_IsBadOwner(User
))
1037 LOG_ERR("User(%d) out of range(%d)",User
,SYSRAM_USER_AMOUNT
);
1043 if((pProc
->Table
) & (1 << User
))
1045 SYSRAM_SpinUnlock();
1046 SYSRAM_IOC_Free(User
);
1049 pProc
->Table
&= (~(1 << User
));
1050 if(pProc
->Table
== 0)
1054 strcpy(pProc
->ProcName
,SYSRAM_PROC_NAME
);
1056 SYSRAM_SpinUnlock();
1060 SYSRAM_SpinUnlock();
1061 LOG_WRN("Freeing unallocated buffer user(%d)",User
);
1067 LOG_ERR("copy_from_user fail");
1074 SYSRAM_DumpLayout();
1079 LOG_WRN("No such command");
1089 LOG_ERR("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)",
1095 if(pFile
->private_data
!= NULL
)
1097 LOG_ERR("Proc:Name(%s),pid(%d),tgid(%d),Table(0x%08lX),Time(%ld.%06ld)",
1109 //------------------------------------------------------------------------------
1110 static const struct file_operations SysramFileOper
=
1112 .owner
= THIS_MODULE
,
1113 .open
= SYSRAM_Open
,
1114 .release
= SYSRAM_Release
,
1115 .flush
= SYSRAM_Flush
,
1116 .unlocked_ioctl
= SYSRAM_Ioctl
,
1117 .mmap
= SYSRAM_mmap
,
1119 //------------------------------------------------------------------------------
1120 static inline int SYSRAM_RegCharDrv(void)
1123 if(alloc_chrdev_region(&Sysram
.DevNo
, 0, 1,SYSRAM_DEV_NAME
) )
1125 LOG_ERR("allocate device no failed");
1129 Sysram
.pCharDrv
= cdev_alloc();
1130 if(Sysram
.pCharDrv
== NULL
)
1132 unregister_chrdev_region(Sysram
.DevNo
, 1);
1133 LOG_ERR("allocate mem for kobject failed");
1136 //Attatch file operation.
1137 cdev_init(Sysram
.pCharDrv
, &SysramFileOper
);
1138 Sysram
.pCharDrv
->owner
= THIS_MODULE
;
1140 if(cdev_add(Sysram
.pCharDrv
, Sysram
.DevNo
, 1))
1142 LOG_ERR("Attatch file operation failed");
1143 unregister_chrdev_region(Sysram
.DevNo
, 1);
1149 //------------------------------------------------------------------------------
1150 static inline void SYSRAM_UnregCharDrv(void)
1153 //Release char driver
1154 cdev_del(Sysram
.pCharDrv
);
1155 unregister_chrdev_region(Sysram
.DevNo
, 1);
1158 //------------------------------------------------------------------------------
1159 static int SYSRAM_Probe(struct platform_device
*pDev
)
1163 struct device
* sysram_device
= NULL
;
1166 //register char driver
1168 if(SYSRAM_RegCharDrv())
1170 LOG_ERR("register char failed");
1174 Sysram
.pClass
= class_create(THIS_MODULE
, "SysramDrv");
1175 if(IS_ERR(Sysram
.pClass
))
1177 Ret
= PTR_ERR(Sysram
.pClass
);
1178 LOG_ERR("Unable to create class, err(%ld)", Ret
);
1181 sysram_device
= device_create(
1187 //Initialize variables
1188 spin_lock_init(&Sysram
.SpinLock
);
1189 Sysram
.TotalUserCount
= 0;
1190 Sysram
.AllocatedTbl
= 0;
1191 memset(Sysram
.AllocatedSize
, 0, sizeof(Sysram
.AllocatedSize
));
1192 memset(Sysram
.UserInfo
, 0, sizeof(Sysram
.UserInfo
));
1193 init_waitqueue_head(&Sysram
.WaitQueueHead
);
1194 Sysram
.EnableClk
= MFALSE
;
1196 for(Index
= 0; Index
< SYSRAM_MEM_BANK_AMOUNT
; Index
++)
1198 SysramMemPoolInfo
[Index
].pMemNode
[0].User
= SYSRAM_USER_NONE
;
1199 SysramMemPoolInfo
[Index
].pMemNode
[0].Offset
= 0;
1200 SysramMemPoolInfo
[Index
].pMemNode
[0].Length
= SysramMemPoolInfo
[Index
].Size
;
1201 SysramMemPoolInfo
[Index
].pMemNode
[0].Index
= 0;
1202 SysramMemPoolInfo
[Index
].pMemNode
[0].pNext
= NULL
;
1203 SysramMemPoolInfo
[Index
].pMemNode
[0].pPrev
= NULL
;
1204 SysramMemPoolInfo
[Index
].IndexTbl
= (~0x1);
1205 SysramMemPoolInfo
[Index
].UserCount
= 0;
1208 for(Index
= 0; Index
< SYSRAM_USER_AMOUNT
; Index
++)
1210 Sysram
.AllocatedSize
[Index
] = 0;
1212 Sysram
.DebugFlag
= SYSRAM_DEBUG_DEFAULT
;
1217 //------------------------------------------------------------------------------
1218 static int SYSRAM_Remove(struct platform_device
*pDev
)
1221 //unregister char driver.
1222 SYSRAM_UnregCharDrv();
1224 device_destroy(Sysram
.pClass
, Sysram
.DevNo
);
1225 class_destroy(Sysram
.pClass
);
1231 //------------------------------------------------------------------------------
1232 static int SYSRAM_Suspend(
1233 struct platform_device
* pDev
,
1239 //------------------------------------------------------------------------------
1240 static int SYSRAM_Resume(struct platform_device
*pDev
)
1245 //------------------------------------------------------------------------------
1246 static struct platform_driver SysramPlatformDriver
=
1248 .probe
= SYSRAM_Probe
,
1249 .remove
= SYSRAM_Remove
,
1250 .suspend
= SYSRAM_Suspend
,
1251 .resume
= SYSRAM_Resume
,
1254 .name
= SYSRAM_DEV_NAME
,
1255 .owner
= THIS_MODULE
,
1258 //------------------------------------------------------------------------------
1259 static int SYSRAM_DumpLayoutToProc(
1270 SYSRAM_MEM_NODE_STRUCT
* pCurrNode
= NULL
;
1272 p
+= sprintf(p
, "\n[SYSRAM_DumpLayoutToProc]\n");
1273 p
+= sprintf(p
, "AllocatedTbl = 0x%08lX\n",Sysram
.AllocatedTbl
);
1274 p
+= sprintf(p
, "=========================================\n" );
1275 for (Index
= 0; Index
< SYSRAM_MEM_BANK_AMOUNT
; Index
++)
1277 p
+= sprintf(p
, "\n [Mem Pool %ld] (IndexTbl, UserCount)=(%lX, %ld)\n",
1279 SysramMemPoolInfo
[Index
].IndexTbl
,
1280 SysramMemPoolInfo
[Index
].UserCount
);
1281 p
+= sprintf(p
, "[Locked Time] [Owner Offset Size Index pCurrent pPrevious pNext] [pid tgid] [Proc Name / Owner Name]\n");
1282 pCurrNode
= &SysramMemPoolInfo
[Index
].pMemNode
[0];
1283 while ( NULL
!= pCurrNode
)
1285 SYSRAM_USER_ENUM
const User
= pCurrNode
->User
;
1286 if ( SYSRAM_IsBadOwner(User
) )
1289 "------------ --------"
1290 " %2d\t0x%05lX 0x%05lX %ld %p %p\t%p\n",
1302 SYSRAM_USER_STRUCT
*const pUserInfo
= &Sysram
.UserInfo
[User
];
1305 " %2d\t0x%05lX 0x%05lX %ld %p %p\t%p"
1306 " %-4d %-4d \"%s\" / \"%s\"\n",
1318 pUserInfo
->ProcName
,
1319 SysramUserName
[User
]);
1321 pCurrNode
= pCurrNode
->pNext
;
1325 *ppStart
= pPage
+ Off
;
1336 return len
< Count
? len
: Count
;
1338 //------------------------------------------------------------------------------
1339 static int SYSRAM_ReadFlag(
1350 p
+= sprintf(p
, "\r\n[SYSRAM_ReadFlag]\r\n");
1351 p
+= sprintf(p
, "=========================================\r\n" );
1352 p
+= sprintf(p
, "Sysram.DebugFlag = 0x%08lX\r\n",Sysram
.DebugFlag
);
1354 *ppStart
= pPage
+ Off
;
1366 return len
< Count
? len
: Count
;
1368 //------------------------------------------------------------------------------
1369 static int SYSRAM_WriteFlag(
1371 const char* pBuffer
,
1372 unsigned long Count
,
1376 MUINT32 u4CopySize
= 0;
1377 MUINT32 u4SysramDbgFlag
= 0;
1379 u4CopySize
= (Count
< (sizeof(acBuf
) - 1)) ? Count
: (sizeof(acBuf
) - 1);
1380 if(copy_from_user(acBuf
, pBuffer
, u4CopySize
))
1384 acBuf
[u4CopySize
] = '\0';
1385 if(3 == sscanf(acBuf
, "%lx", &u4SysramDbgFlag
))
1387 Sysram
.DebugFlag
= u4SysramDbgFlag
;
1392 /*******************************************************************************
1394 ********************************************************************************/
1395 static const struct file_operations fsysram_proc_fops
= {
1396 .read
= SYSRAM_DumpLayoutToProc
,
1399 static const struct file_operations fsysram_flag_proc_fops
= {
1400 .read
= SYSRAM_ReadFlag
,
1401 .write
= SYSRAM_WriteFlag
,
1404 //-----------------------------------------------------------------------------
1405 static int __init
SYSRAM_Init(void)
1407 struct proc_dir_entry
*pEntry
;
1411 if(platform_driver_register(&SysramPlatformDriver
))
1413 LOG_ERR("failed to register sysram driver");
1417 //linux-3.10 procfs API changed
1419 proc_create("sysram",0,NULL
,&fsysram_proc_fops
);
1420 proc_create("sysram_flag",0,NULL
,&fsysram_flag_proc_fops
);
1422 pEntry
= create_proc_entry("sysram", 0, NULL
);
1425 pEntry
->read_proc
= SYSRAM_DumpLayoutToProc
;
1426 pEntry
->write_proc
= NULL
;
1430 LOG_ERR("add /proc/sysram entry fail.");
1433 pEntry
= create_proc_entry("sysram_flag", 0, NULL
);
1436 pEntry
->read_proc
= SYSRAM_ReadFlag
;
1437 pEntry
->write_proc
= SYSRAM_WriteFlag
;
1441 LOG_ERR("add /proc/sysram_flag entry fail");
1448 //------------------------------------------------------------------------------
1449 static void __exit
SYSRAM_Exit(void)
1452 platform_driver_unregister(&SysramPlatformDriver
);
1455 //------------------------------------------------------------------------------
1456 module_init(SYSRAM_Init
);
1457 module_exit(SYSRAM_Exit
);
1458 MODULE_DESCRIPTION("Camera sysram driver");
1459 MODULE_AUTHOR("Marx <marx.chiu@mediatek.com>");
1460 MODULE_LICENSE("GPL");
1461 //------------------------------------------------------------------------------