s32 bsp_ipc_spin_unlock (u32 u32SignalNum) { IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); writel(0,ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum)); ipc_debug.u32SemGiveTimes[u32SignalNum]++; return MDRV_OK; }
s32 bsp_ipc_spin_lock_timeout(u32 u32SignalNum, u32 TimeoutMs) { u32 u32HsCtrl = 0; u32 start_time = 0, end_time = 0, elapsed = 0; IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); start_time = bsp_get_slice_value(); elapsed = TimeoutMs * bsp_get_slice_freq() / 1000; /*lint !e647 */ /* coverity[no_escape] */ for(;;) { u32HsCtrl = readl(ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum)); if (0 == u32HsCtrl) { ipc_debug.u32SemTakeTimes[u32SignalNum]++; ipc_debug.u32SemId = u32SignalNum; break; } end_time = bsp_get_slice_value(); if(get_timer_slice_delta(start_time, end_time) > elapsed) { ipc_debug.u32SemCore = readl(ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_HS_STAT(ipc_ctrl.core_num, u32SignalNum)); return MDRV_ERROR; } } return MDRV_OK; }
/***************************************************************************** * 函 数 名 : ipc_sem_int_handler * * 功能描述 : 信号量释放中断处理函数 * * 输入参数 : 无 * 输出参数 : 无 * * 返 回 值 : 无 * * 修改记录 : 2013年1月9日 lixiaojie *****************************************************************************/ OSL_IRQ_FUNC(static irqreturn_t,ipc_sem_int_handler,irq,arg) { u32 u32IntStat = 0,u32HsCtrl=0,u32SNum=0, i = 32; u32IntStat = readl(ipc_ctrl.ipc_base[IPCM_NS]+BSP_IPC_SEM_INT_STAT(ipc_ctrl.core_num)); u32SNum = ffSLsb(u32IntStat); if( u32SNum != 0) { do { /*如果有信号量释放中断,清除该中断*/ writel((u32)1<<--u32SNum, ipc_ctrl.ipc_base[IPCM_NS]+BSP_IPC_SEM_INT_CLR(ipc_ctrl.core_num)); u32HsCtrl = readl(ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SNum)); if (0 == u32HsCtrl) { osl_sem_up(&(ipc_ctrl.sem_ipc_task[u32SNum])); } else { ipc_debug.u32SemTakeFailTimes[u32SNum]++; } u32IntStat = readl(ipc_ctrl.ipc_base[IPCM_NS]+BSP_IPC_SEM_INT_STAT(ipc_ctrl.core_num)); u32SNum = ffSLsb(u32IntStat); i--; }while((u32SNum != 0) && (i > 0)); } else { return IRQ_NONE; } return IRQ_HANDLED; }
s32 bsp_ipc_sem_give(u32 u32SignalNum) { IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); ipc_debug.u32SemGiveTimes[u32SignalNum]++; /*向信号量请求寄存器写0*/ writel(0,ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum)); return MDRV_OK; }
s32 bsp_ipc_sem_give(u32 u32SignalNum) { IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); ipc_debug.u32SemGiveTimes[u32SignalNum]++; /*向信号量请求寄存器写0*/ writel(0,(volatile void *)(ipc_ctrl.ipc_base + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum))); return OK; }
s32 bsp_ipc_spin_unlock (u32 u32SignalNum) { IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); if(ipc_modem_reset_flag) { return OK; } writel(0,ipc_ctrl.ipc_base + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum)); return OK; }
/*lint -restore +e550*/ void ipc_modem_reset(void) { u32 i = 0,ret = 0; for(i=0;i<32;i++) { ret = readl((const volatile void *)(ipc_ctrl.ipc_base + BSP_IPC_HS_STAT(ipc_ctrl.core_num,i))); if(ret == 0x9) writel(0,(volatile void *)(ipc_ctrl.ipc_base + BSP_IPC_HS_CTRL(IPC_CORE_CCORE, i))); } return ; }
s32 bsp_ipc_spin_trylock(u32 u32SignalNum) { u32 u32HsCtrl = 0; IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); u32HsCtrl = readl(ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum)); if (0 == u32HsCtrl) { ipc_debug.u32SemTakeTimes[u32SignalNum]++; ipc_debug.u32SemId = u32SignalNum; return MDRV_OK; } else return MDRV_ERROR; }
s32 bsp_ipc_sem_take(u32 u32SignalNum,s32 s32timeout) { u32 u32IntMask = 0,ret = 0; /*参数检查*/ IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); /*将申请的信号量对应的释放中断清零*/ writel((u32)1<<u32SignalNum, ipc_ctrl.ipc_base[IPCM_NS]+BSP_IPC_SEM_INT_CLR(ipc_ctrl.core_num)); ret = readl(ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum)); if(0 == ret) { mask_int(u32SignalNum); ipc_debug.u32SemTakeTimes[u32SignalNum]++; ipc_debug.u32SemId = u32SignalNum; return MDRV_OK; } else { if(false == ipc_ctrl.sem_exist[u32SignalNum]) { bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"need call ipc_sem_create to create this sem before call ipc_sem_take!\n"); return MDRV_ERROR; } if(0 != s32timeout) { /*使能信号量释放中断*/ u32IntMask = readl(ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_SEM_INT_MASK(ipc_ctrl.core_num)); u32IntMask = u32IntMask | ((u32)1 << u32SignalNum); writel(u32IntMask,ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_SEM_INT_MASK(ipc_ctrl.core_num)); if (MDRV_OK != osl_sem_downtimeout(&(ipc_ctrl.sem_ipc_task[u32SignalNum]), s32timeout)) { mask_int(u32SignalNum); bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"semTake timeout!\n"); ipc_debug.u32SemTakeFailTimes[u32SignalNum]++; return MDRV_ERROR; } else { /*lint !e525*/ mask_int(u32SignalNum); ipc_debug.u32SemTakeTimes[u32SignalNum]++; ipc_debug.u32SemId = u32SignalNum; return MDRV_OK; } } else { return MDRV_ERROR; } } }
static void ipc_free_sem_taked(u32 core_id) { u32 i = 0; u32 ret = 0; for(i = 0; i < 32; i++) { /*判断资源锁占用,如果占用,则释放*/ ret = readl((unsigned long)(ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_HS_STAT(core_id, i))); ret &= 0xf;/*取低4bit*/ if (ret == ((1 << 3) | core_id)) { writel(0, (unsigned long)(ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_HS_CTRL(core_id, i))); } } }
s32 bsp_ipc_spin_lock(u32 u32SignalNum) { u32 u32HsCtrl = 0; IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); for(;;) { u32HsCtrl = readl((const volatile void *)(ipc_ctrl.ipc_base + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum))); if (0 == u32HsCtrl) { ipc_debug.u32SemTakeTimes[u32SignalNum]++; ipc_debug.u32SemId = u32SignalNum; break; } } return OK; }
s32 bsp_ipc_spin_lock(u32 u32SignalNum) { u32 u32HsCtrl = 0; IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); if(ipc_modem_reset_flag) { return OK; } for(;;) { u32HsCtrl = readl(ipc_ctrl.ipc_base + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum)); if (0 == u32HsCtrl) { break; } } return OK; }
s32 bsp_ipc_spin_unlock (u32 u32SignalNum) { IPC_CHECK_PARA(u32SignalNum,IPC_SEM_BUTTOM); writel(0,(volatile void *)(ipc_ctrl.ipc_base + BSP_IPC_HS_CTRL(ipc_ctrl.core_num, u32SignalNum))); return OK; }