static int __init reset_sub_mgr_init_hifi(void) { struct task_struct *pHifiTask = NULL; int iret = BSP_RESET_OK; /*默认HIFI使能*/ reset_set_cpu_status(0, RESET_CPU_HIFI_STATUS_OFF); /*创建需要的信号量*/ printk(KERN_INFO "%s: enter\n", __FUNCTION__); hisi_io_memset(&g_reset_assistant_hifi, 0, sizeof(g_reset_assistant_hifi)); sema_init(&(g_reset_assistant_hifi.sem_wait_hifireset), SEM_EMPTY); sema_init(&(g_reset_assistant_hifi.sem_wait_mcu_msg_hifireset), SEM_EMPTY); /*创建hifi复位处理线程*/ pHifiTask = kthread_run(hifireset_task, NULL, "hifireset_task"); printk(KERN_INFO "%s: create hifireset_task, return %p\n", __FUNCTION__, pHifiTask); ccorereset_enable_wdt_irq(); /*注册HIFI复位回调函数*//*hifi复位,底软不注册*/ hifireset_regcbfunc("CODEC", drv_hifireset_cbfun, 0, BSP_DRV_CBFUN_PRIOLEVEL); iret = ipc_msg_req_callback(OBJ_HIFI, CMD_NOTIFY, mailbox_recfun_mcu_hifireset); printk(KERN_INFO"RESET LOG: LEAVE reset_sub_mgr_init0! iret = %d\n", iret); return BSP_RESET_OK; }
void queue_init(struct queue *q, char *name, unsigned int len) { hisi_io_memset(q->name, 0, QUEUE_NAME_LEN); if (name){ strncpy(q->name, name, QUEUE_NAME_LEN); q->name[QUEUE_NAME_LEN - 1] = 0; } spin_lock_init(&q->lock); q->max = len; q->head = 0; q->tail = 0; q->in = 0; q->out = 0; hisi_io_memset(q->data, 0, len); return; }
void queue_destory(struct queue *q) { hisi_io_memset(q->data, 0, q->max); q->max = 0; q->head = 0; q->tail = 0; q->in = 0; q->out = 0; return; }
/***************************************************************************** 函 数 名 : drv_hifi_read_image 功能描述 : 读取Hifi镜像 输入参数 : void 输出参数 : img_head hifi镜像头信息 img_buf hifi镜像信息 返 回 值 : int 成功返回 0,失败返回 -1 调用函数 : 被调函数 : 修改历史 : 1.日 期 : 2012年8月29日 作 者 : 刘慈红 lKF71598 修改内容 : 新生成函数 *****************************************************************************/ int drv_hifi_read_image(void *img_head, void **img_buf) { struct drv_hifi_image_head *head = NULL; int ret = 0; char **buff = NULL; unsigned int size = sizeof(struct drv_hifi_image_head); head = (struct drv_hifi_image_head *)img_head; buff = (char **)img_buf; /* read hifi image head from EMMC */ ret = drv_read_bin((const char*)HIFI_IMAGE_NAME, 0, size, (char *)head); printk(KERN_INFO"RESET LOADHIFI: after drv_read_bin ret = %d.\n", ret); /* the size of hifi image */ size = head->image_size; printk(KERN_INFO "%s: drv_read_bin size is %x \n",__FUNCTION__,size); *buff = vmalloc(size); if (NULL == *buff) { printk(KERN_INFO"drv_hifi_read_image: Fail to malloc %d bytes in load hifi bin function\n", size); return BSP_RESET_ERROR; } printk(KERN_INFO"RESET RESET: read hifi bin to virt addr 0x%p, size = %d\n", (void*)(*buff), size); hisi_io_memset((void*)*buff, 0, size); /* read hifi image head from EMMC */ ret = drv_read_bin((const char*)HIFI_IMAGE_NAME, 0, size, *buff); if (ret < 0) { printk(KERN_INFO"RESET LOADHIFI: drv_hifi_read_image:Read image %s error.\n", HIFI_IMAGE_NAME); return BSP_RESET_ERROR; } /*dma_free_coherent(NULL, sizeof(struct drv_hifi_image_head),*buff,phy_img_buf);*/ return 0; }
/***************************************************************************** 函 数 名 : reset_no_ok_savelog 功能描述 : 在调用回调函数时如果回调函数返回失败,则记录下模块名字,返回值 输入参数 : char *pname,组件注册回调函数时注册的名字; int iresult,回调函数的返回值。 ereset_module emodule, 复位的模块,ccore or hifi 输出参数 : 无 返 回 值 : int 0, 成功,非0,失败 *****************************************************************************/ int reset_no_ok_savelog(char *pname, int iresult, DRV_RESET_CB_MOMENT_E eparam, ereset_module emodule) { #ifdef PRINK_TO_FILE /*如果实现了printk打印信息生成文件功能,则不需要该函数功能*/ return BSP_RESET_OK; #else int ilen = 0; char *psavelog = NULL; char *ptime = (MDRV_RESET_CB_BEFORE == eparam?"before":"after"); if (NULL == pname) { printk(KERN_ERR "[%s ]name is NULL, in savelog fun\n", __FUNCTION__); return BSP_RESET_ERROR; } psavelog = (char*)kmalloc(BSP_RESET_LOG_INFO_ITEM_LEN, GFP_KERNEL); if (NULL == psavelog) { printk(KERN_ERR "%s: fail to malloc, in savelog fun\n", __FUNCTION__); return BSP_RESET_ERROR; } hisi_io_memset((void*)psavelog, 0, BSP_RESET_LOG_INFO_ITEM_LEN); switch (emodule) { case BSP_RESET_MODULE_CCORE: sprintf(psavelog, "%s ccore reset, %s fail, return %d\n",ptime, pname, iresult); break; case BSP_RESET_MODULE_HIFI: sprintf(psavelog, "%s hifi reset, %s fail, return %d\n",ptime, pname, iresult); break; default: sprintf(psavelog, "valid module, %s fail, return %d\n",pname, iresult); printk(KERN_ERR "%s: module id %d invalid!!, in savelog fun\n", __FUNCTION__, emodule); break; } reset_for_savelog(psavelog); kfree(psavelog); psavelog = NULL; return BSP_RESET_OK; #endif /* PRINK_TO_FILE */ }
/***************************************************************************** 函 数 名 : reset_do_regcbfunc 功能描述 : 用于其它组件注册回调函数,处理Modem复位前后相关数据。 输入参数 : sreset_mgr_LLI *plink,管理链表,注意,允许为空. const char *pname, 组件注册的名字 pdrv_reset_cbfun cbfun, 组件注册的回调函数 int userdata,组件的私有数据 Int Priolevel, 回调函数调用优先级 0-49,其中0-9 保留。 输出参数 : 无 返 回 值 : int *****************************************************************************/ sreset_mgr_LLI * reset_do_regcbfunc(sreset_mgr_LLI *plink, const char *pname, pdrv_reset_cbfun pcbfun, int userdata, int priolevel) { sreset_mgr_LLI *phead = plink; sreset_mgr_LLI *pmgr_unit = NULL; /*判断入参是否合法,不合法返回错误*/ if (NULL == pname || NULL == pcbfun || (priolevel < RESET_CBFUNC_PRIO_LEVEL_LOWT || priolevel > RESET_CBFUNC_PRIO_LEVEL_HIGH)) { printk(KERN_ERR "%s: fail in ccore reset regcb,fail, name 0x%p, cbfun 0x%p, prio %d\n", __FUNCTION__, \ (void*)pname, (void*)pcbfun, priolevel); return NULL; } /*分配空间*/ pmgr_unit = (sreset_mgr_LLI*)kmalloc(sizeof(sreset_mgr_LLI), GFP_KERNEL); if (NULL != pmgr_unit) { hisi_io_memset((void*)pmgr_unit, 0, (sizeof(sreset_mgr_LLI))); /*赋值*/ strncpy(pmgr_unit->cbfuninfo.name, pname, DRV_RESET_MODULE_NAME_LEN); pmgr_unit->cbfuninfo.priolevel = priolevel; pmgr_unit->cbfuninfo.userdata = userdata; pmgr_unit->cbfuninfo.cbfun = pcbfun; } /*第一次调用该函数,链表为空*/ if (NULL == phead) { phead = pmgr_unit; } else { /*根据优先级插入链表*/ phead = reset_link_insert(phead, pmgr_unit); } return phead; }
/***************************************************************************** * 函 数 名 : IPF_Init * * 功能描述 : IPF初始化 内部使用,不作为接口函数 * * 输入参数 : void * 输出参数 : 无 * 返 回 值 : IPF_SUCCESS 初始化成功 * IPF_ERROR 初始化失败 * * 修改记录 :2011年1月21日 鲁婷 创建 * 1.修改日期 : 2012年11月29日 * 修改作者 : z00212992 * 修改记录 : 增加ADQ初始化 *****************************************************************************/ int IPF_Init(void) { int s32Ret = 0; /* IPF内存配置越界检查 */ if(IPF_MEM_USED_SIZE > IPF_AXI_MEM_SIZE) { IPF_PRINT_ERROR("memory overstep the boundary\n"); return IPF_ERROR; } hisi_io_memset((BSP_VOID*)&g_stIpfCtx, 0x0, sizeof(IPF_CONTEXT_S)); IPF_ULBD_MEM_ADDR = HISI_VA_ADDRESS(IPF_AXI_MEM_ADDR); if (0 == (IPF_REGBASE_ADR = (unsigned long)ioremap(REG_BASE_IPF,REG_IPF_IOSIZE))){ BUG_ON(1); return IPF_ERROR; } /* 为上行BD、RD描述符分配一段连续的物理地址 */ g_stIpfUl.pstIpfBDQ = (IPF_BD_DESC_S*)IPF_ULBD_MEM_ADDR; g_stIpfUl.pstIpfRDQ = (IPF_RD_DESC_S*)IPF_ULRD_MEM_ADDR; /* 为上行AD描述符分配一段连续内存(首地址8字节对齐)*/ g_stIpfUl.pstIpfADQ0 = (IPF_AD_DESC_S*)IPF_ULAD0_MEM_ADDR; g_stIpfUl.pstIpfADQ1 = (IPF_AD_DESC_S*)IPF_ULAD1_MEM_ADDR; /* 为下行BD、RD描述符分配一段连续的物理地址 */ g_stIpfDl.pstIpfBDQ = (IPF_BD_DESC_S*)IPF_DLBD_MEM_ADDR; g_stIpfDl.pstIpfRDQ = (IPF_RD_DESC_S*)IPF_DLRD_MEM_ADDR; /* 为下行AD描述符分配一段连续内存(首地址8字节对齐)*/ g_stIpfDl.pstIpfADQ0 = (IPF_AD_DESC_S*)IPF_DLAD0_MEM_ADDR; g_stIpfDl.pstIpfADQ1 = (IPF_AD_DESC_S*)IPF_DLAD1_MEM_ADDR; /* 为下行CD描述符分配一段连续的物理地址 */ g_stIpfDl.pstIpfCDQ = (IPF_CD_DESC_S*)IPF_DLCD_MEM_ADDR; /* 记录IPF上行空闲BD个数 */ g_stIpfUl.pu32IdleBd = (unsigned int*)IPF_ULBD_IDLENUM_ADDR; #ifdef __BSP_IPF_DEBUG__ /* 记录IPF debug信息 */ g_stIPFDebugInfo = (IPF_DEBUG_INFO_S*)IPF_DEBUG_INFO_ADDR; /* 记录IPF 下行CDdebug信息 */ g_stIpfDl.pstIpfDebugCDQ = (IPF_CD_DESC_S*)IPF_DEBUG_DLCD_ADDR; #endif /* 记录IPF 下行CD读写指针 */ g_stIpfDl.u32IpfCdRptr = (unsigned int*)IPF_DLCD_PTR_ADDR; g_stIpfDl.u32IpfCdWptr = (unsigned int*)(IPF_DLCD_PTR_ADDR+4); /* 挂接IPF中断 */ IPF_Int_Connect(); /* 注册IPF设备 */ s32Ret = platform_device_register(&ipf_pfdev); if(s32Ret) { IPF_PRINT_ERROR("ipf device register fail\n"); return s32Ret; } /* 注册IPF驱动 */ s32Ret = platform_driver_register(&ipf_pfdrv); if(s32Ret) { platform_device_unregister(&ipf_pfdev); IPF_PRINT_ERROR("ipf driver register fail\n"); return s32Ret; } ipf_peri_ctrl_base = (unsigned long)HISI_VA_ADDRESS(SOC_PERI_SCTRL_BASE_ADDR); if (!ipf_peri_ctrl_base) { IPF_PRINT_ERROR("unable to ioremap ipf peri ctrl\n"); } /* 打开IPF hclk时钟、axi总线时钟 */ IPF_REG_WRITE(SOC_PERI_SCTRL_SC_PERIPH_CLKEN2_ADDR(ipf_peri_ctrl_base), \ (0x1 << SOC_PERI_SCTRL_SC_PERIPH_CLKEN2_periph_clken2_ipf_acpu_START)); /* 等待另外一个core ipf初始化同步完成 */ s32Ret = BSP_SYNC_Wait(SYNC_MODULE_IPF, 5000); if(s32Ret != BSP_OK) { IPF_PRINT_ERROR("BSP_SYNC_Wait timeout\n"); return IPF_ERROR; } /* IPF初始化完成 */ g_stIpfCtx.isInit = BSP_TRUE; IPF_PRINT_ERROR("success\n"); return IPF_SUCCESS; }