| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211 |
- #include <linux/uaccess.h>
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/device.h>
- #include <linux/fs.h>
- #include <linux/platform_device.h>
- #include <linux/cdev.h>
- #include <linux/io.h>
- #include <linux/slab.h>
- #include <linux/proc_fs.h> /* proc file use */
- #include <linux/spinlock.h>
- #include <linux/mm.h>
- #include <linux/sched.h>
- #include <linux/delay.h>
- #include <linux/ioctl.h>
- #include "inc/mt_typedefs.h"
- #include <mach/mt_clkmgr.h>
- #include <mt-plat/sync_write.h>
- #include "inc/camera_sysram_D1.h"
- #include "inc/camera_sysram_imp_D1.h"
- /* ----------------------------------------------------------------------------- */
- #define ISP_VALID_REG_RANGE 0x10000
- #define IMGSYS_BASE_ADDR 0x15000000
- static SYSRAM_STRUCT Sysram;
- /* ------------------------------------------------------------------------------ */
- static void SYSRAM_GetTime(MUINT64 *pUS64, MUINT32 *pSec, MUINT32 *pUSec)
- {
- ktime_t Time;
- MUINT64 TimeSec;
- Time = ktime_get();/* ns */
- TimeSec = Time.tv64;
- do_div(TimeSec, 1000);
- *pUS64 = TimeSec;
- *pUSec = do_div(TimeSec, 1000000);
- *pSec = (MUINT64)TimeSec;
- }
- /* ------------------------------------------------------------------------------ */
- static void SYSRAM_CheckClock(void)
- {
- /* LOG_MSG("AllocatedTbl(0x%08X), EnableClk(%d)", Sysram.AllocatedTbl, Sysram.EnableClk); */
- if (Sysram.AllocatedTbl) {
- if (!(Sysram.EnableClk)) {
- Sysram.EnableClk = true;
- /*
- LOG_MSG("AllocatedTbl(0x%08lX), EnableClk(%d)",
- Sysram.AllocatedTbl,
- Sysram.EnableClk);
- */
- }
- } else{
- if (Sysram.EnableClk) {
- Sysram.EnableClk = false;
- /*
- LOG_MSG("AllocatedTbl(0x%08lX), EnableClk(%d)",
- Sysram.AllocatedTbl,
- Sysram.EnableClk);
- */
- }
- }
- }
- /* ------------------------------------------------------------------------------ */
- static void SYSRAM_DumpResMgr(void)
- {
- unsigned int u4Idx = 0;
- LOG_MSG("TotalUserCount(%ld), AllocatedTbl(0x%lX)",
- Sysram.TotalUserCount,
- Sysram.AllocatedTbl);
- for (u4Idx = 0; u4Idx < SYSRAM_USER_AMOUNT; u4Idx++) {
- if (0 < Sysram.AllocatedSize[u4Idx]) {
- SYSRAM_USER_STRUCT * const pUserInfo = &Sysram.UserInfo[u4Idx];
- LOG_MSG("[id:%u][%s][size:0x%lX][pid:%d][tgid:%d][%s][%5lu.%06lu]",
- u4Idx,
- SysramUserName[u4Idx],
- Sysram.AllocatedSize[u4Idx],
- pUserInfo->pid,
- pUserInfo->tgid,
- pUserInfo->ProcName,
- pUserInfo->TimeS,
- pUserInfo->TimeUS);
- }
- }
- LOG_MSG("End");
- }
- /* ------------------------------------------------------------------------------ */
- static inline MBOOL SYSRAM_IsBadOwner(SYSRAM_USER_ENUM const User)
- {
- if (SYSRAM_USER_AMOUNT <= User || User < 0)
- return MTRUE;
- else
- return MFALSE;
- }
- /* ------------------------------------------------------------------------------ */
- static void SYSRAM_SetUserTaskInfo(SYSRAM_USER_ENUM const User)
- {
- if (!SYSRAM_IsBadOwner(User)) {
- SYSRAM_USER_STRUCT * const pUserInfo = &Sysram.UserInfo[User];
- pUserInfo->pid = current->pid;
- pUserInfo->tgid = current->tgid;
- memcpy(pUserInfo->ProcName, current->comm, sizeof(pUserInfo->ProcName));
- SYSRAM_GetTime(&(pUserInfo->Time64), &(pUserInfo->TimeS), &(pUserInfo->TimeUS));
- }
- }
- /* ------------------------------------------------------------------------------ */
- static void SYSRAM_ResetUserTaskInfo(SYSRAM_USER_ENUM const User)
- {
- if (!SYSRAM_IsBadOwner(User)) {
- SYSRAM_USER_STRUCT * const pUserInfo = &Sysram.UserInfo[User];
- memset(pUserInfo, 0, sizeof(*pUserInfo));
- }
- }
- /* ------------------------------------------------------------------------------ */
- static inline void SYSRAM_SpinLock(void)
- {
- spin_lock(&Sysram.SpinLock);
- }
- /* ------------------------------------------------------------------------------ */
- static inline void SYSRAM_SpinUnlock(void)
- {
- spin_unlock(&Sysram.SpinLock);
- }
- /* ------------------------------------------------------------------------------ */
- static inline MBOOL SYSRAM_UserIsLocked(SYSRAM_USER_ENUM const User)
- {
- if ((1 << User) & Sysram.AllocatedTbl)
- return MTRUE;
- else
- return MFALSE;
- }
- /* ------------------------------------------------------------------------------ */
- static inline MBOOL SYSRAM_UserIsUnlocked(SYSRAM_USER_ENUM const User)
- {
- if (SYSRAM_UserIsLocked(User) == 0)
- return MTRUE;
- else
- return MFALSE;
- }
- /* ------------------------------------------------------------------------------ */
- static void SYSRAM_LockUser(SYSRAM_USER_ENUM const User, MUINT32 const Size)
- {
- if (SYSRAM_UserIsLocked(User))
- return;
- Sysram.TotalUserCount++;
- Sysram.AllocatedTbl |= (1 << User);
- Sysram.AllocatedSize[User] = Size;
- SYSRAM_SetUserTaskInfo(User);
- /* Debug Log. */
- if ((1<<User) & SysramLogUserMask) {
- SYSRAM_USER_STRUCT * const pUserInfo = &Sysram.UserInfo[User];
- LOG_MSG("[%s][%lu bytes]OK, Time(%lu.%06lu)",
- SysramUserName[User],
- Sysram.AllocatedSize[User],
- pUserInfo->TimeS,
- pUserInfo->TimeUS);
- }
- }
- /* ------------------------------------------------------------------------------ */
- static void SYSRAM_UnlockUser(SYSRAM_USER_ENUM const User)
- {
- if (SYSRAM_UserIsUnlocked(User))
- return;
- /* Debug Log. */
- if ((1<<User) & SysramLogUserMask) {
- SYSRAM_USER_STRUCT * const pUserInfo = &Sysram.UserInfo[User];
- MUINT32 Sec, USec;
- MUINT64 Time64 = 0;
- SYSRAM_GetTime(&Time64, &Sec, &USec);
- LOG_MSG("[%s][%lu bytes]Time(%lu.%06lu - %lu.%06lu)(%lu.%06lu)",
- SysramUserName[User],
- Sysram.AllocatedSize[User],
- pUserInfo->TimeS,
- pUserInfo->TimeUS,
- Sec,
- USec,
- ((MUINT32)(Time64-pUserInfo->Time64))/1000,
- ((MUINT32)(Time64-pUserInfo->Time64))%1000);
- }
- if (Sysram.TotalUserCount > 0)
- Sysram.TotalUserCount--;
- Sysram.AllocatedTbl &= (~(1 << User));
- Sysram.AllocatedSize[User] = 0;
- SYSRAM_ResetUserTaskInfo(User);
- }
- /* ------------------------------------------------------------------------------ */
- static void SYSRAM_DumpLayout(void)
- {
- MUINT32 Index = 0;
- SYSRAM_MEM_NODE_STRUCT *pCurrNode = NULL;
- LOG_DMP("[SYSRAM_DumpLayout]\n");
- LOG_DMP("AllocatedTbl = 0x%08lX\n", Sysram.AllocatedTbl);
- LOG_DMP("=========================================\n");
- for (Index = 0; Index < SYSRAM_MEM_BANK_AMOUNT; Index++) {
- LOG_DMP("\n [Mem Pool %ld] (IndexTbl, UserCount)=(%lX, %ld)\n",
- Index,
- SysramMemPoolInfo[Index].IndexTbl,
- SysramMemPoolInfo[Index].UserCount);
- LOG_DMP("[Locked Time] [Owner Offset Size Index pCurrent pPrevious pNext] [pid tgid] [Proc Name / Owner Name]\n");
- pCurrNode = &SysramMemPoolInfo[Index].pMemNode[0];
- while (NULL != pCurrNode) {
- SYSRAM_USER_ENUM const User = pCurrNode->User;
- if (SYSRAM_IsBadOwner(User)) {
- LOG_DMP(
- "------------ -------- "
- " %2d\t0x%05lX 0x%05lX %ld %p %p\t%p\n",
- pCurrNode->User,
- pCurrNode->Offset,
- pCurrNode->Length,
- pCurrNode->Index,
- pCurrNode,
- pCurrNode->pPrev,
- pCurrNode->pNext);
- } else{
- SYSRAM_USER_STRUCT * const pUserInfo = &Sysram.UserInfo[User];
- LOG_DMP("%5lu.%06lu "
- " %2d\t0x%05lX 0x%05lX %ld %p %p\t%p "
- " %-4d %-4d \"%s\" / \"%s\"\n",
- pUserInfo->TimeS,
- pUserInfo->TimeUS,
- User,
- pCurrNode->Offset,
- pCurrNode->Length,
- pCurrNode->Index,
- pCurrNode,
- pCurrNode->pPrev,
- pCurrNode->pNext,
- pUserInfo->pid,
- pUserInfo->tgid,
- pUserInfo->ProcName,
- SysramUserName[User]);
- }
- pCurrNode = pCurrNode->pNext;
- };
- }
- LOG_DMP("\n");
- SYSRAM_DumpResMgr();
- }
- /* ------------------------------------------------------------------------------ */
- static SYSRAM_MEM_NODE_STRUCT *SYSRAM_AllocNode(SYSRAM_MEM_POOL_STRUCT * const pMemPoolInfo)
- {
- SYSRAM_MEM_NODE_STRUCT *pNode = NULL;
- MUINT32 Index = 0;
- for (Index = 0; Index < pMemPoolInfo->UserAmount; Index += 1) {
- if ((pMemPoolInfo->IndexTbl) & (1 << Index)) {
- pMemPoolInfo->IndexTbl &= (~(1 << Index));
- /* A free node is found. */
- pNode = &pMemPoolInfo->pMemNode[Index];
- pNode->User = SYSRAM_USER_NONE;
- pNode->Offset = 0;
- pNode->Length = 0;
- pNode->pPrev = NULL;
- pNode->pNext = NULL;
- pNode->Index = Index;
- break;
- }
- }
- /* Shouldn't happen. */
- if (!pNode)
- LOG_ERR("returns NULL - pMemPoolInfo->IndexTbl(%lX)", pMemPoolInfo->IndexTbl);
- return pNode;
- }
- /* ------------------------------------------------------------------------------ */
- static void SYSRAM_FreeNode(
- SYSRAM_MEM_POOL_STRUCT * const pMemPoolInfo,
- SYSRAM_MEM_NODE_STRUCT * const pNode)
- {
- pMemPoolInfo->IndexTbl |= (1<<pNode->Index);
- pNode->User = SYSRAM_USER_NONE;
- pNode->Offset = 0;
- pNode->Length = 0;
- pNode->pPrev = NULL;
- pNode->pNext = NULL;
- pNode->Index = 0;
- }
- /* ------------------------------------------------------------------------------ */
- static MBOOL SYSRAM_IsLegalSizeToAlloc(
- SYSRAM_MEM_BANK_ENUM const MemBankNo,
- SYSRAM_USER_ENUM const User,
- MUINT32 const Size)
- {
- MUINT32 MaxSize = 0;
- /* (1) Check the memory pool. */
- switch (MemBankNo) {
- case SYSRAM_MEM_BANK_BAD:
- case SYSRAM_MEM_BANK_AMOUNT:
- {
- /* Illegal Memory Pool: return "illegal" */
- /* Shouldn't happen. */
- goto EXIT;
- }
- default:
- break;
- }
- /* (2) */
- /* Here we use the dynamic memory pools. */
- MaxSize = SysramUserSize[User];
- EXIT:
- if (MaxSize < Size) {
- LOG_ERR("[User:%s]requested size(0x%lX) > max size(0x%lX)",
- SysramUserName[User],
- Size,
- MaxSize);
- SYSRAM_DumpLayout();
- return MFALSE;
- }
- return MTRUE;
- }
- /* ------------------------------------------------------------------------------ */
- /*
- Alignment should be 2^N, 4/8/2048 bytes alignment only
- First fit algorithm
- */
- static MUINT32 SYSRAM_AllocUserPhy(
- SYSRAM_USER_ENUM const User,
- MUINT32 const Size,
- MUINT32 const Alignment,
- SYSRAM_MEM_BANK_ENUM const MemBankNo
- )
- {
- SYSRAM_MEM_NODE_STRUCT *pSplitNode = NULL;
- SYSRAM_MEM_NODE_STRUCT *pCurrNode = NULL;
- MUINT32 AlingnedAddr = 0;
- MUINT32 ActualSize = 0;
- SYSRAM_MEM_POOL_STRUCT * const pMemPoolInfo = SYSRAM_GetMemPoolInfo(MemBankNo);
- if (!pMemPoolInfo)
- return 0;
- pCurrNode = &pMemPoolInfo->pMemNode[0];
- for (; pCurrNode && pCurrNode->Offset < pMemPoolInfo->Size; pCurrNode = pCurrNode->pNext) {
- if (SYSRAM_USER_NONE == pCurrNode->User) {
- /* Free space */
- AlingnedAddr = (pCurrNode->Offset + Alignment - 1)&(~(Alignment - 1));
- ActualSize = Size + AlingnedAddr - pCurrNode->Offset;
- if (ActualSize <= pCurrNode->Length) {
- /* Hit!! Split into 2 */
- /* pSplitNode pointers to the next available (free) node. */
- pSplitNode = SYSRAM_AllocNode(pMemPoolInfo);
- pSplitNode->Offset = pCurrNode->Offset + ActualSize;
- pSplitNode->Length = pCurrNode->Length - ActualSize;
- pSplitNode->pPrev = pCurrNode;
- pSplitNode->pNext = pCurrNode->pNext;
- pCurrNode->User = User;
- pCurrNode->Length = ActualSize;
- pCurrNode->pNext = pSplitNode;
- if (NULL != pSplitNode->pNext)
- pSplitNode->pNext->pPrev = pSplitNode;
- pMemPoolInfo->UserCount++;
- break;
- }
- /* Not hit */
- ActualSize = 0;
- }
- };
- return ActualSize ? (AlingnedAddr + pMemPoolInfo->Addr) : 0;
- }
- /* ------------------------------------------------------------------------------ */
- static MBOOL SYSRAM_FreeUserPhy(
- SYSRAM_USER_ENUM const User,
- SYSRAM_MEM_BANK_ENUM const MemBankNo)
- {
- MBOOL Ret = MFALSE;
- SYSRAM_MEM_NODE_STRUCT *pPrevOrNextNode = NULL;
- SYSRAM_MEM_NODE_STRUCT *pCurrNode = NULL;
- SYSRAM_MEM_NODE_STRUCT *pTempNode = NULL;
- SYSRAM_MEM_POOL_STRUCT * const pMemPoolInfo = SYSRAM_GetMemPoolInfo(MemBankNo);
- if (!pMemPoolInfo) {
- LOG_ERR("pMemPoolInfo==NULL, User(%d), MemBankNo(%d)", User, MemBankNo);
- return MFALSE;
- }
- pCurrNode = &pMemPoolInfo->pMemNode[0];
- for (; pCurrNode; pCurrNode = pCurrNode->pNext) {
- if (User == pCurrNode->User) {
- Ret = MTRUE; /* user is found. */
- if (pMemPoolInfo->UserCount > 0)
- pMemPoolInfo->UserCount--;
- pCurrNode->User = SYSRAM_USER_NONE;
- if (NULL != pCurrNode->pPrev) {
- pPrevOrNextNode = pCurrNode->pPrev;
- if (SYSRAM_USER_NONE == pPrevOrNextNode->User) {
- /* Merge previous: prev(o) + curr(x) */
- pTempNode = pCurrNode;
- pCurrNode = pPrevOrNextNode;
- pCurrNode->Length += pTempNode->Length;
- pCurrNode->pNext = pTempNode->pNext;
- if (NULL != pTempNode->pNext)
- pTempNode->pNext->pPrev = pCurrNode;
- SYSRAM_FreeNode(pMemPoolInfo, pTempNode);
- }
- }
- if (NULL != pCurrNode->pNext) {
- pPrevOrNextNode = pCurrNode->pNext;
- if (SYSRAM_USER_NONE == pPrevOrNextNode->User) {
- /* Merge next: curr(o) + next(x) */
- pTempNode = pPrevOrNextNode;
- pCurrNode->Length += pTempNode->Length;
- pCurrNode->pNext = pTempNode->pNext;
- if (NULL != pCurrNode->pNext)
- pCurrNode->pNext->pPrev = pCurrNode;
- SYSRAM_FreeNode(pMemPoolInfo, pTempNode);
- }
- }
- break;
- }
- }
- return Ret;
- }
- /* ------------------------------------------------------------------------------ */
- static MUINT32 SYSRAM_AllocUser(
- SYSRAM_USER_ENUM const User,
- MUINT32 Size,
- MUINT32 const Alignment)
- {
- MUINT32 Addr = 0;
- SYSRAM_MEM_BANK_ENUM const MemBankNo = SYSRAM_GetMemBankNo(User);
- if (SYSRAM_IsBadOwner(User)) {
- LOG_ERR("User(%d) out of range(%d)", User, SYSRAM_USER_AMOUNT);
- return 0;
- }
- if (!SYSRAM_IsLegalSizeToAlloc(MemBankNo, User, Size))
- return 0;
- switch (MemBankNo) {
- case SYSRAM_MEM_BANK_BAD:
- case SYSRAM_MEM_BANK_AMOUNT:
- {
- /* Do nothing. */
- break;
- }
- default:
- {
- Addr = SYSRAM_AllocUserPhy(
- User,
- Size,
- Alignment,
- MemBankNo);
- break;
- }
- }
- if (0 < Addr)
- SYSRAM_LockUser(User, Size);
- return Addr;
- }
- /* ------------------------------------------------------------------------------ */
- static void SYSRAM_FreeUser(SYSRAM_USER_ENUM const User)
- {
- SYSRAM_MEM_BANK_ENUM const MemBankNo = SYSRAM_GetMemBankNo(User);
- switch (MemBankNo) {
- case SYSRAM_MEM_BANK_BAD:
- case SYSRAM_MEM_BANK_AMOUNT:
- {
- /* Do nothing. */
- break;
- }
- default:
- {
- if (SYSRAM_FreeUserPhy(User, MemBankNo)) {
- SYSRAM_UnlockUser(User);
- } else{
- LOG_ERR("Cannot free User(%d)", User);
- SYSRAM_DumpLayout();
- }
- break;
- }
- }
- }
- /* ------------------------------------------------------------------------------ */
- static MUINT32 SYSRAM_MsToJiffies(MUINT32 TimeMs)
- {
- return (TimeMs*HZ + 512) >> 10;
- }
- /* ------------------------------------------------------------------------------ */
- static MUINT32 SYSRAM_TryAllocUser(
- SYSRAM_USER_ENUM const User,
- MUINT32 const Size,
- MUINT32 const Alignment)
- {
- MUINT32 Addr = 0;
- SYSRAM_SpinLock();
- if (SYSRAM_UserIsLocked(User)) {
- SYSRAM_SpinUnlock();
- LOG_ERR("[User:%s]has been already allocated!", SysramUserName[User]);
- return 0;
- }
- Addr = SYSRAM_AllocUser(User, Size, Alignment);
- if (Addr != 0)
- SYSRAM_CheckClock();
- SYSRAM_SpinUnlock();
- return Addr;
- }
- /* ------------------------------------------------------------------------------ */
- static MUINT32 SYSRAM_IOC_Alloc(
- SYSRAM_USER_ENUM const User,
- MUINT32 const Size,
- MUINT32 Alignment,
- MUINT32 const TimeoutMS)
- {
- MUINT32 Addr = 0;
- INT32 TimeOut = 0;
- if (SYSRAM_IsBadOwner(User)) {
- LOG_ERR("User(%d) out of range(%d)", User, SYSRAM_USER_AMOUNT);
- return 0;
- }
- if (0 == Size) {
- LOG_ERR("[User:%s]allocates 0 size!", SysramUserName[User]);
- return 0;
- }
- Addr = SYSRAM_TryAllocUser(User, Size, Alignment);
- if (0 != Addr /* success */
- || 0 == TimeoutMS /* failure without a timeout specified */)
- goto EXIT;
- TimeOut = wait_event_interruptible_timeout(
- Sysram.WaitQueueHead,
- 0 != (Addr = SYSRAM_TryAllocUser(User, Size, Alignment)),
- SYSRAM_MsToJiffies(TimeoutMS));
- if (0 == TimeOut && 0 == Addr)
- LOG_ERR("[User:%s]allocate timeout", SysramUserName[User]);
- EXIT:
- if (0 == Addr) { /* Failure */
- LOG_ERR("[User:%s]fails to allocate.Size(%lu), Alignment(%lu), TimeoutMS(%lu)",
- SysramUserName[User],
- Size,
- Alignment,
- TimeoutMS);
- SYSRAM_DumpLayout();
- } else{ /* Success */
- if ((1<<User) & SysramLogUserMask) {
- LOG_MSG("[User:%s]%lu bytes OK",
- SysramUserName[User],
- Size);
- }
- }
- return Addr;
- }
- /* ------------------------------------------------------------------------------ */
- static void SYSRAM_IOC_Free(SYSRAM_USER_ENUM User)
- {
- if (SYSRAM_IsBadOwner(User)) {
- LOG_ERR("User(%d) out of range(%d)", User, SYSRAM_USER_AMOUNT);
- return;
- }
- SYSRAM_SpinLock();
- SYSRAM_FreeUser(User);
- wake_up_interruptible(&Sysram.WaitQueueHead);
- SYSRAM_CheckClock();
- SYSRAM_SpinUnlock();
- if ((1<<User) & SysramLogUserMask)
- LOG_MSG("[User:%s]Done", SysramUserName[User]);
- }
- /* ------------------------------------------------------------------------------ */
- static int SYSRAM_Open(
- struct inode *pInode,
- struct file *pFile)
- {
- int Ret = 0;
- MUINT32 Sec = 0, USec = 0;
- MUINT64 Time64 = 0;
- SYSRAM_PROC_STRUCT *pProc;
- SYSRAM_GetTime(&Time64, &Sec, &USec);
- LOG_MSG("Cur:Name(%s), pid(%d), tgid(%d), Time(%ld.%06ld)",
- current->comm,
- current->pid,
- current->tgid,
- Sec,
- USec);
- SYSRAM_SpinLock();
- pFile->private_data = kmalloc(sizeof(SYSRAM_PROC_STRUCT) , GFP_ATOMIC);
- if (pFile->private_data == NULL) {
- Ret = -ENOMEM;
- } else{
- pProc = (SYSRAM_PROC_STRUCT *)(pFile->private_data);
- pProc->Pid = 0;
- pProc->Tgid = 0;
- strcpy(pProc->ProcName, SYSRAM_PROC_NAME);
- pProc->Table = 0;
- pProc->Time64 = Time64;
- pProc->TimeS = Sec;
- pProc->TimeUS = USec;
- }
- SYSRAM_SpinUnlock();
- if (Ret == (-ENOMEM)) {
- LOG_ERR("No enough memory");
- /*
- LOG_ERR("Cur:Name(%s), pid(%d), tgid(%d), Time(%ld.%06ld)",
- current->comm,
- current->pid,
- current->tgid,
- Sec,
- USec);
- */
- }
- return Ret;
- }
- /* ------------------------------------------------------------------------------ */
- static int SYSRAM_Release(
- struct inode *pInode,
- struct file *pFile)
- {
- MUINT32 Index = 0;
- MUINT32 Sec = 0, USec = 0;
- MUINT64 Time64 = 0;
- SYSRAM_PROC_STRUCT *pProc;
- SYSRAM_GetTime(&Time64, &Sec, &USec);
- LOG_MSG("Cur:Name(%s), pid(%d), tgid(%d), Time(%ld.%06ld)",
- current->comm,
- current->pid,
- current->tgid,
- Sec,
- USec);
- if (pFile->private_data != NULL) {
- pProc = (SYSRAM_PROC_STRUCT *)(pFile->private_data);
- if (pProc->Pid != 0 ||
- pProc->Tgid != 0 ||
- pProc->Table != 0) {
- /* */
- LOG_WRN("Proc:Name(%s), pid(%d), tgid(%d), Table(0x%08lX), Time(%ld.%06ld)",
- pProc->ProcName,
- pProc->Pid,
- pProc->Tgid,
- pProc->Table,
- pProc->TimeS,
- pProc->TimeUS);
- if (pProc->Table) {
- LOG_WRN("Force to release");
- /*
- LOG_WRN("Proc:Name(%s), pid(%d), tgid(%d), Table(0x%08lX), Time(%ld.%06ld)",
- pProc->ProcName,
- pProc->Pid,
- pProc->Tgid,
- pProc->Table,
- pProc->TimeS,
- pProc->TimeUS);
- */
- SYSRAM_DumpLayout();
- for (Index = 0; Index < SYSRAM_USER_AMOUNT; Index++) {
- if (pProc->Table & (1 << Index))
- SYSRAM_IOC_Free((SYSRAM_USER_ENUM)Index);
- }
- }
- }
- kfree(pFile->private_data);
- pFile->private_data = NULL;
- } else{
- LOG_WRN("private_data is NULL");
- /*
- LOG_WRN("Cur:Name(%s), pid(%d), tgid(%d), Time(%ld.%06ld)",
- current->comm,
- current->pid,
- current->tgid,
- Sec,
- USec);
- */
- }
- return 0;
- }
- /* ------------------------------------------------------------------------------ */
- static int SYSRAM_Flush(
- struct file *pFile,
- fl_owner_t Id)
- {
- MUINT32 Index = 0;
- MUINT32 Sec = 0, USec = 0;
- MUINT64 Time64 = 0;
- SYSRAM_PROC_STRUCT *pProc;
- SYSRAM_GetTime(&Time64, &Sec, &USec);
- LOG_MSG("Cur:Name(%s), pid(%d), tgid(%d), Time(%ld.%06ld)",
- current->comm,
- current->pid,
- current->tgid,
- Sec,
- USec);
- if (pFile->private_data != NULL) {
- pProc = (SYSRAM_PROC_STRUCT *)pFile->private_data;
- if (pProc->Pid != 0 ||
- pProc->Tgid != 0 ||
- pProc->Table != 0) {
- /* */
- LOG_WRN("Proc:Name(%s), pid(%d), tgid(%d), Table(0x%08lX), Time(%ld.%06ld)",
- pProc->ProcName,
- pProc->Pid,
- pProc->Tgid,
- pProc->Table,
- pProc->TimeS,
- pProc->TimeUS);
- if (pProc->Tgid == 0 && pProc->Table != 0) {
- LOG_ERR("No Tgid info");
- /*
- LOG_ERR("Cur:Name(%s), pid(%d), tgid(%d), Time(%ld.%06ld)",
- current->comm,
- current->pid,
- current->tgid,
- Sec,
- USec);
- LOG_ERR("Proc:Name(%s), pid(%d), tgid(%d), Table(0x%08lX), Time(%ld.%06ld)",
- pProc->ProcName,
- pProc->Pid,
- pProc->Tgid,
- pProc->Table,
- pProc->TimeS,
- pProc->TimeUS);
- */
- } else{
- if ((pProc->Tgid == current->tgid) ||
- ((pProc->Tgid != current->tgid) && (strcmp(current->comm, "binder") == 0))) {
- /* */
- if (pProc->Table) {
- LOG_WRN("Force to release");
- /*
- LOG_WRN("Cur:Name(%s), pid(%d), tgid(%d), Time(%ld.%06ld)",
- current->comm,
- current->pid,
- current->tgid,
- Sec,
- USec);
- */
- SYSRAM_DumpLayout();
- for (Index = 0; Index < SYSRAM_USER_AMOUNT; Index++) {
- if (pProc->Table & (1 << Index))
- SYSRAM_IOC_Free((SYSRAM_USER_ENUM)Index);
- }
- pProc->Table = 0;
- }
- }
- }
- }
- } else{
- LOG_WRN("private_data is NULL");
- /*
- LOG_WRN("Cur:Name(%s), pid(%d), tgid(%d), Time(%ld.%06ld)",
- current->comm,
- current->pid,
- current->tgid,
- Sec,
- USec);
- */
- }
- return 0;
- }
- /* ------------------------------------------------------------------------------ */
- static int SYSRAM_mmap(
- struct file *pFile,
- struct vm_area_struct *pVma)
- {
- long length = 0;
- MUINT32 pfn = 0x0;
- /* LOG_MSG(""); */
- pVma->vm_page_prot = pgprot_noncached(pVma->vm_page_prot);
- length = pVma->vm_end - pVma->vm_start;
- pfn = pVma->vm_pgoff<<PAGE_SHIFT;/* page from number, physical address of kernel memory */
- LOG_WRN("pVma->vm_pgoff(0x%lx), phy(0x%lx), pVmapVma->vm_start(0x%lx), pVma->vm_end(0x%lx), length(%lx)",
- pVma->vm_pgoff, pVma->vm_pgoff<<PAGE_SHIFT, pVma->vm_start, pVma->vm_end, length);
- if ((length > ISP_VALID_REG_RANGE) ||
- (pfn < IMGSYS_BASE_ADDR) ||
- (pfn > (IMGSYS_BASE_ADDR+ISP_VALID_REG_RANGE))) {
- LOG_ERR("mmap range error : vm_start(0x%lx), vm_end(0x%lx), length(%lx), pfn(%u)!",
- pVma->vm_start, pVma->vm_end, length, (unsigned int)pfn);
- return -EAGAIN;
- }
- if (remap_pfn_range(
- pVma,
- pVma->vm_start,
- pVma->vm_pgoff,
- pVma->vm_end - pVma->vm_start,
- pVma->vm_page_prot)) {
- /* */
- LOG_ERR("fail");
- return -EAGAIN;
- }
- return 0;
- }
- /* ------------------------------------------------------------------------------ */
- static long SYSRAM_Ioctl(
- struct file *pFile,
- unsigned int Cmd,
- unsigned long Param)
- {
- MINT32 Ret = 0;
- MUINT32 Sec = 0, USec = 0;
- MUINT64 Time64 = 0;
- SYSRAM_PROC_STRUCT *pProc = (SYSRAM_PROC_STRUCT *)pFile->private_data;
- SYSRAM_ALLOC_STRUCT Alloc;
- SYSRAM_USER_ENUM User;
- SYSRAM_GetTime(&Time64, &Sec, &USec);
- /*
- LOG_MSG("Cur:Name(%s), pid(%d), tgid(%d), Time(%ld.%06ld)",
- current->comm,
- current->pid,
- current->tgid,
- Sec,
- USec);
- */
- if (pFile->private_data == NULL) {
- LOG_WRN("private_data is NULL.");
- Ret = -EFAULT;
- goto EXIT;
- }
- switch (Cmd) {
- case SYSRAM_ALLOC:
- {
- if (copy_from_user(&Alloc, (void *)Param, sizeof(SYSRAM_ALLOC_STRUCT)) == 0) {
- Alloc.Addr = SYSRAM_IOC_Alloc(
- Alloc.User,
- Alloc.Size,
- Alloc.Alignment,
- Alloc.TimeoutMS);
- if (Alloc.Addr != 0) {
- SYSRAM_SpinLock();
- pProc->Table |= (1 << Alloc.User);
- if (pProc->Tgid == 0) {
- pProc->Pid = current->pid;
- pProc->Tgid = current->tgid;
- strcpy(pProc->ProcName, current->comm);
- SYSRAM_SpinUnlock();
- } else{
- SYSRAM_SpinUnlock();
- if (pProc->Tgid != current->tgid) {
- LOG_ERR("Tgid is inconsistent");
- Ret = -EFAULT;
- }
- }
- } else{
- Ret = -EFAULT;
- }
- if (copy_to_user((void *)Param, &Alloc, sizeof(SYSRAM_ALLOC_STRUCT))) {
- LOG_ERR("copy to user failed");
- Ret = -EFAULT;
- }
- } else{
- LOG_ERR("copy_from_user fail");
- Ret = -EFAULT;
- }
- break;
- }
- case SYSRAM_FREE:
- {
- if (copy_from_user(&User, (void *)Param, sizeof(SYSRAM_USER_ENUM)) == 0) {
- SYSRAM_SpinLock();
- if ((pProc->Table) & (1 << User)) {
- SYSRAM_SpinUnlock();
- SYSRAM_IOC_Free(User);
- SYSRAM_SpinLock();
- pProc->Table &= (~(1 << User));
- if (pProc->Table == 0) {
- pProc->Pid = 0;
- pProc->Tgid = 0;
- strcpy(pProc->ProcName, SYSRAM_PROC_NAME);
- }
- SYSRAM_SpinUnlock();
- } else{
- SYSRAM_SpinUnlock();
- LOG_WRN("Freeing unallocated buffer user(%d)", User);
- Ret = -EFAULT;
- }
- } else{
- LOG_ERR("copy_from_user fail");
- Ret = -EFAULT;
- }
- break;
- }
- case SYSRAM_DUMP:
- {
- SYSRAM_DumpLayout();
- break;
- }
- default:
- {
- LOG_WRN("No such command");
- Ret = -EINVAL;
- break;
- }
- }
- EXIT:
- if (Ret != 0) {
- LOG_ERR("Fail");
- LOG_ERR("Cur:Name(%s), pid(%d), tgid(%d), Time(%ld.%06ld)",
- current->comm,
- current->pid,
- current->tgid,
- Sec,
- USec);
- if (pFile->private_data != NULL) {
- LOG_ERR("Proc:Name(%s), pid(%d), tgid(%d), Table(0x%08lX), Time(%ld.%06ld)",
- pProc->ProcName,
- pProc->Pid,
- pProc->Tgid,
- pProc->Table,
- Sec,
- USec);
- }
- }
- return Ret;
- }
- /* ------------------------------------------------------------------------------ */
- static const struct file_operations SysramFileOper = {
- .owner = THIS_MODULE,
- .open = SYSRAM_Open,
- .release = SYSRAM_Release,
- .flush = SYSRAM_Flush,
- .unlocked_ioctl = SYSRAM_Ioctl,
- .mmap = SYSRAM_mmap,
- };
- /* ------------------------------------------------------------------------------ */
- static inline int SYSRAM_RegCharDrv(void)
- {
- LOG_MSG("E");
- if (alloc_chrdev_region(&Sysram.DevNo, 0, 1, SYSRAM_DEV_NAME)) {
- LOG_ERR("allocate device no failed");
- return -EAGAIN;
- }
- /* allocate driver */
- Sysram.pCharDrv = cdev_alloc();
- if (Sysram.pCharDrv == NULL) {
- unregister_chrdev_region(Sysram.DevNo, 1);
- LOG_ERR("allocate mem for kobject failed");
- return -ENOMEM;
- }
- /* Attatch file operation. */
- cdev_init(Sysram.pCharDrv, &SysramFileOper);
- Sysram.pCharDrv->owner = THIS_MODULE;
- /* Add to system */
- if (cdev_add(Sysram.pCharDrv, Sysram.DevNo, 1)) {
- LOG_ERR("Attatch file operation failed");
- unregister_chrdev_region(Sysram.DevNo, 1);
- return -EAGAIN;
- }
- LOG_MSG("X");
- return 0;
- }
- /* ------------------------------------------------------------------------------ */
- static inline void SYSRAM_UnregCharDrv(void)
- {
- LOG_MSG("E");
- /* Release char driver */
- cdev_del(Sysram.pCharDrv);
- unregister_chrdev_region(Sysram.DevNo, 1);
- LOG_MSG("X");
- }
- /* ------------------------------------------------------------------------------ */
- static int SYSRAM_Probe(struct platform_device *pDev)
- {
- MINT32 Ret = 0;
- MUINT32 Index = 0;
- struct device *sysram_device = NULL;
- LOG_MSG("E");
- /* register char driver */
- /* allocate major no */
- if (SYSRAM_RegCharDrv()) {
- LOG_ERR("register char failed");
- return -EAGAIN;
- }
- Sysram.pClass = class_create(THIS_MODULE, "SysramDrv");
- if (IS_ERR(Sysram.pClass)) {
- Ret = PTR_ERR(Sysram.pClass);
- LOG_ERR("Unable to create class, err(%ld)", Ret);
- return Ret;
- }
- sysram_device = device_create(
- Sysram.pClass,
- NULL,
- Sysram.DevNo,
- NULL,
- SYSRAM_DEV_NAME);
- /* Initialize variables */
- spin_lock_init(&Sysram.SpinLock);
- Sysram.TotalUserCount = 0;
- Sysram.AllocatedTbl = 0;
- memset(Sysram.AllocatedSize, 0, sizeof(Sysram.AllocatedSize));
- memset(Sysram.UserInfo, 0, sizeof(Sysram.UserInfo));
- init_waitqueue_head(&Sysram.WaitQueueHead);
- Sysram.EnableClk = MFALSE;
- for (Index = 0; Index < SYSRAM_MEM_BANK_AMOUNT; Index++) {
- SysramMemPoolInfo[Index].pMemNode[0].User = SYSRAM_USER_NONE;
- SysramMemPoolInfo[Index].pMemNode[0].Offset = 0;
- SysramMemPoolInfo[Index].pMemNode[0].Length = SysramMemPoolInfo[Index].Size;
- SysramMemPoolInfo[Index].pMemNode[0].Index = 0;
- SysramMemPoolInfo[Index].pMemNode[0].pNext = NULL;
- SysramMemPoolInfo[Index].pMemNode[0].pPrev = NULL;
- SysramMemPoolInfo[Index].IndexTbl = (~0x1);
- SysramMemPoolInfo[Index].UserCount = 0;
- }
- for (Index = 0; Index < SYSRAM_USER_AMOUNT; Index++)
- Sysram.AllocatedSize[Index] = 0;
- Sysram.DebugFlag = SYSRAM_DEBUG_DEFAULT;
- LOG_MSG("X");
- return Ret;
- }
- /* ------------------------------------------------------------------------------ */
- static int SYSRAM_Remove(struct platform_device *pDev)
- {
- LOG_MSG("E");
- /* unregister char driver. */
- SYSRAM_UnregCharDrv();
- device_destroy(Sysram.pClass, Sysram.DevNo);
- class_destroy(Sysram.pClass);
- LOG_MSG("X");
- return 0;
- }
- /* ------------------------------------------------------------------------------ */
- static int SYSRAM_Suspend(
- struct platform_device *pDev,
- pm_message_t Mesg)
- {
- LOG_MSG("");
- return 0;
- }
- /* ------------------------------------------------------------------------------ */
- static int SYSRAM_Resume(struct platform_device *pDev)
- {
- LOG_MSG("");
- return 0;
- }
- /* ------------------------------------------------------------------------------ */
- static struct platform_driver SysramPlatformDriver = {
- .probe = SYSRAM_Probe,
- .remove = SYSRAM_Remove,
- .suspend = SYSRAM_Suspend,
- .resume = SYSRAM_Resume,
- .driver = {
- .name = SYSRAM_DEV_NAME,
- .owner = THIS_MODULE,
- }
- };
- /* ------------------------------------------------------------------------------ */
- /*
- ssize_t (*read) (struct file *, char __user *, size_t, loff_t *)
- */
- static ssize_t SYSRAM_DumpLayoutToProc(
- struct file *pFile,
- char *pStart,
- size_t Off,
- loff_t *Count)
- {
- LOG_ERR("SYSRAM_DumpLayoutToProc: Not implement");
- return 0;
- }
- /* ------------------------------------------------------------------------------ */
- /*
- ssize_t (*read) (struct file *, char __user *, size_t, loff_t *)
- */
- static ssize_t SYSRAM_ReadFlag(
- struct file *pFile,
- char *pStart,
- size_t Off,
- loff_t *Count)
- {
- LOG_ERR("SYSRAM_ReadFlag: Not implement");
- return 0;
- }
- /* ------------------------------------------------------------------------------ */
- /*
- ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *)
- */
- static ssize_t SYSRAM_WriteFlag(
- struct file *pFile,
- const char *pBuffer,
- size_t Count,
- loff_t *pData)
- {
- LOG_ERR("SYSRAM_WriteFlag: Not implement");
- return 0;
- }
- /*******************************************************************************
- *
- ********************************************************************************/
- static const struct file_operations fsysram_proc_fops = {
- .read = SYSRAM_DumpLayoutToProc,
- .write = NULL,
- };
- static const struct file_operations fsysram_flag_proc_fops = {
- .read = SYSRAM_ReadFlag,
- .write = SYSRAM_WriteFlag,
- };
- /* ----------------------------------------------------------------------------- */
- static int __init SYSRAM_Init(void)
- {
- #if 0
- struct proc_dir_entry *pEntry;
- #endif
- LOG_MSG("E");
- if (platform_driver_register(&SysramPlatformDriver)) {
- LOG_ERR("failed to register sysram driver");
- return -ENODEV;
- }
- /* FIX-ME: linux-3.10 procfs API changed */
- #if 1
- proc_create("sysram", 0, NULL, &fsysram_proc_fops);
- proc_create("sysram_flag", 0, NULL, &fsysram_flag_proc_fops);
- #else
- pEntry = create_proc_entry("sysram", 0, NULL);
- if (pEntry) {
- pEntry->read_proc = SYSRAM_DumpLayoutToProc;
- pEntry->write_proc = NULL;
- } else{
- LOG_ERR("add /proc/sysram entry fail.");
- }
- pEntry = create_proc_entry("sysram_flag", 0, NULL);
- if (pEntry) {
- pEntry->read_proc = SYSRAM_ReadFlag;
- pEntry->write_proc = SYSRAM_WriteFlag;
- } else{
- LOG_ERR("add /proc/sysram_flag entry fail");
- }
- #endif
- LOG_MSG("X");
- return 0;
- }
- /* ------------------------------------------------------------------------------ */
- static void __exit SYSRAM_Exit(void)
- {
- LOG_MSG("E");
- platform_driver_unregister(&SysramPlatformDriver);
- LOG_MSG("X");
- }
- /* ------------------------------------------------------------------------------ */
- module_init(SYSRAM_Init);
- module_exit(SYSRAM_Exit);
- MODULE_DESCRIPTION("Camera sysram driver");
- MODULE_AUTHOR("Marx <marx.chiu@mediatek.com>");
- MODULE_LICENSE("GPL");
- /* ------------------------------------------------------------------------------ */
|