/*case03:测试多个设备正常初始化和注册到dpm控制链表*/
s32 dpm_test_case03()
{
	s32 ret = 0;
	dev1.device_name = "dev1";
	dev1.complete = my_complete_ok;
	dev1.prepare   = my_prepare_ok;
	dev1.resume   = my_resume_ok;
	dev1.suspend = my_suspend_ok;
	dev2.device_name = "dev2";
	dev2.complete = my_complete_ok;
	dev2.prepare   = my_prepare_ok;
	dev2.resume   = my_resume_ok;
	dev2.suspend = my_suspend_ok;
	dev3.device_name = "dev3";
	dev3.complete = my_complete_ok;
	dev3.prepare   = my_prepare_ok;
	dev3.resume   = my_resume_ok;
	dev3.suspend = my_suspend_ok;
	dev4.device_name = "dev4";
	dev4.complete = my_complete_ok;
	dev4.prepare   = my_prepare_ok;
	dev4.resume   = my_resume_ok;
	dev4.suspend = my_suspend_ok;
	dev5.device_name = "dev5";
	dev5.complete = my_complete_ok;
	dev5.prepare   = my_prepare_ok;
	dev5.resume   = my_resume_ok;
	dev5.suspend = my_suspend_ok;
	ret = bsp_device_pm_add(&dev1);
	if(ret ==ERROR)
	{
		return ERROR;
	}
	ret = bsp_device_pm_add(&dev2);
	if(ret ==ERROR)
	{
		return ERROR;
	}
	ret = bsp_device_pm_add(&dev3);
	if(ret ==ERROR)
	{
		return ERROR;
	}
	ret = bsp_device_pm_add(&dev4);
	if(ret ==ERROR)
	{
		return ERROR;
	}
	ret = bsp_device_pm_add(&dev5);
	if(ret ==ERROR)
	{
		return ERROR;
	}
	return OK;
}
/*case8:给设备4赋上返回错误值的resume回调函数,
              测试观察resume是否会返回错误并打印相关错误log*/
s32 dpm_test_case08()
{
	s32 ret = 0;
	ret=bsp_device_pm_remove(&dev4);
	if(ret ==ERROR)
	{
		return ERROR;
	}
	dev4.resume = my_resume_error;
	dev4.complete = my_complete_ok;
	ret = bsp_device_pm_add(&dev4);
	 if(ret ==ERROR)
	 {
		 return ERROR;
	 }
	 
	 ret = bsp_dpm_suspend();
	 if(ret ==ERROR)
	 	return ERROR;
	 bsp_dpm_resume();	
	 /*DPM模块测试结束,清理工作*/
	 list_del_init(&dev1.entry);
	 list_del_init(&dev2.entry);
	 list_del_init(&dev3.entry);
	 list_del_init(&dev4.entry);
	 list_del_init(&dev5.entry);
	 return OK;
}
/*case06:给设备5赋上返回错误值的suspend函数,
              测试观察suspend到中途时是否会恢复已经suspend的设备*/
s32 dpm_test_case06()
{
	s32 ret = 0;
	ret=bsp_device_pm_remove(&dev5);
	if(ret ==ERROR)
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_DPM,"remove error\n");
		return ERROR;
	}
	dev5.prepare= my_prepare_ok;
	dev5.suspend = my_suspend_error;
	ret = bsp_device_pm_add(&dev5);
	 if(ret ==ERROR)
	 {
	 	bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_DPM,"add error\n");
		 return ERROR;
	 }
	 ret = bsp_dpm_suspend();
	 if(ret ==ERROR)
	 {
		return OK;
	 }
	 else
	 	return ERROR;
}
/*软件配置TCXO1初始化状态*/
void bsp_tcxo1_init(void)
{
    unsigned int regvalue = 0;
	s32 ret = 0;

    /*TCXO1由软件控制*/
    regvalue = readl(HI_AP_SYSCTRL_BASE_ADDR_VIRT + 0x10);
    regvalue |= (unsigned int)0x1 << 8;
    writel(regvalue, HI_AP_SYSCTRL_BASE_ADDR_VIRT + 0x10);

    writel(0x5D, HI_AP_SYSCTRL_BASE_ADDR_VIRT + 0x18);

    /*TCXO1默认关闭*/
    regvalue = readl(HI_AP_SYSCTRL_BASE_ADDR_VIRT + 0x10);
    regvalue &= ~((unsigned int)0x1 << 7);
    writel(regvalue, HI_AP_SYSCTRL_BASE_ADDR_VIRT + 0x10);

    /*确认关闭完成*/
    while(!(readl(HI_AP_SYSCTRL_BASE_ADDR_VIRT + 0x1C) & (0x1 << 13))) {
        ;
    }
    ret = bsp_device_pm_add(&tcxo1_dpm);
    if(ret)
    {
        adp_dpm_printf("tcxo1 dpm callback function register fail!\n");
    }
    return;
}
void bsp_cross_mipi_init(void)
{
    int   ret     = 0;
    static struct cross_mipi_info g_tuner = {0};

    if (!g_tuner.is_inited) {
        ret = cross_mipi_read_nv(&g_tuner);
        if (ret) {
            cross_mipi_print_error("read nv fail ,ret: %d\n", ret);
            return ;
        }
        g_tuner.ctu_base  = (u32)bsp_bbp_part_addr_get(BBP_CTU);
        g_tuner.mem_base  = (u32)bsp_bbp_part_addr_get(BBP_CROSS_MIPI_MEM);
        g_tuner.ctrl_base = (u32)bsp_bbp_part_addr_get(BBP_CROSS_MIPI_CTRL);

       // CROSS_MIPI_USE_BBP_DMA
        g_tuner.dma_mipi.bbp_addr = g_tuner.mem_base  + CROSS_MIPI_MIPI_MEM_OFFSET;
        g_tuner.dma_mipi.soc_addr = (u32)g_tuner.mipi_mem;
        g_tuner.dma_mipi.chan     = CROSS_MIPI_BBP_DMA_CHN;
        g_tuner.dma_mipi.size     = 4 * g_tuner.mipi_mem_len;
        g_tuner.dma_mipi.type     = 0;

        g_tuner.dma_gpio.bbp_addr = g_tuner.mem_base  + CROSS_MIPI_GPIO_MEM_OFFSET;
        g_tuner.dma_gpio.soc_addr = (u32)g_tuner.gpio_mem;
        g_tuner.dma_gpio.chan      = CROSS_GPIO_BBP_DMA_CHN;
        g_tuner.dma_gpio.size      = 4 * g_tuner.ctrl_info.gpio_tuner_len;
        g_tuner.dma_gpio.type      = 0;

        g_tuner_dpm_device.platform_data = &g_tuner;
        ret = bsp_device_pm_add(&g_tuner_dpm_device);
        if (ret) {
            cross_mipi_print_error("fail to add cross_mipi dpm device!\r\n");
            return;
        }
    }

    if (g_tuner.ctrl_info.tuner_en) {
        writel(g_tuner.ctrl_info.tuner_en,             (u32)g_tuner.ctrl_base + CROSS_MIPI_EN_OFFSET);
        writel(g_tuner.ctrl_info.tuner_req_en,         (u32)g_tuner.ctrl_base + CROSS_MIPI_REQ_EN_OFFSET);
        writel((u32)!g_tuner.ctrl_info.gpio_cross_en,  (u32)g_tuner.ctrl_base + CROSS_GPIO_EN_OFFSET);

        writel(~g_tuner.ctrl_info.reg.tuner_mipi_mask, (u32)g_tuner.ctu_base  + CROSS_MIPI_MASK_OFFSET);
        writel(~g_tuner.ctrl_info.reg.gpio_mask,       (u32)g_tuner.ctu_base  + CROSS_MIPI_GPIO_MASK_OFFSET);
        writel(g_tuner.ctrl_info.tas_ind_en,           (u32)g_tuner.ctu_base + TUNER_TAS_IND_OFFSET);

       // CROSS_MIPI_USE_BBP_DMA
        bsp_bbp_dma_tran(&g_tuner.dma_gpio);
        bsp_bbp_dma_tran(&g_tuner.dma_mipi);
        if (!g_tuner.is_inited){
            bsp_bbp_dma_finish(&g_tuner.dma_gpio);
            bsp_bbp_dma_finish(&g_tuner.dma_mipi);
        }
    }

    if (!g_tuner.is_inited) {
        g_tuner.is_inited = 1;
        cross_mipi_print_error("cross mipi init ok!g_tuner addr :0x%x\n", (u32)&g_tuner);
    }
}
/*todo :改名字*/
int bsp_rffe_init(void)
{
    int ret = 0;
    int i   = 0;

    for(i = 0; i < SEM_NUM; i++){
        osl_sem_init(1, &rf_pwr_sem[i]);
    }

    /*供电初始化*/
    ret  = balong_rf_power_init();
    if(ret){
        rf_print_error("rf power init fail,ret = %d\n",ret);
    }

    udelay(200);

    /*MIPI配置初始化*/
    ret = balong_rf_config_by_mipi_init();
    if(ret){
        rf_print_error("rf power init fail,ret = %d\n",ret);
    }

    /*射频线控配置初始化*/
    ret = balong_rf_config_anten_init();
    if(ret){
        rf_print_error("rf ant(gpio) init fail,ret = %d\n",ret);
    }
#ifdef CONFIG_CCORE_PM

    /*注册dpm 回调*/
    if(bsp_rsracc_support())
    {
        ret = bsp_rsracc_register((rsr_acc_description *)&rf_rsracc_device,1);
    }
    else
    {
        ret = bsp_device_pm_add(&g_rf_dpm_device);
        if(ret){
            rf_print_error("rffe add dpm device fail,ret = %d\n",ret);
        }
    }
#endif

    rf_print_error("bsp rf init end,ret is %d\n",ret);
    return ret;
}
/*case01:测试添加一个并删除设备*/
s32 dpm_test_case01()
{
	s32 ret = 0;
	dev0.device_name = "dev0";
	dev0.complete   = my_complete_ok;
	dev0.prepare   = my_prepare_ok;
	dev0.resume   = my_resume_ok;
	dev0.suspend = my_suspend_ok;
	ret = bsp_device_pm_add(&dev0);
	if(OK != ret)
	{
		return ERROR;
	}
	ret = bsp_device_pm_remove(&dev0);
	if(OK != ret)
	{
		return ERROR;
	}
	return OK;
}
/*case5:给设备5赋上返回错误值的prepare函数,
              测试观察suspend到中途时是否会恢复已经suspend的设备*/
s32 dpm_test_case05()
{
	s32 ret = 0;
	ret=bsp_device_pm_remove(&dev5);
	if(ret ==ERROR)
	{
		return ERROR;
	}
	dev5.prepare = my_prepare_error;
	ret = bsp_device_pm_add(&dev5);
	 if(ret ==ERROR)
	 {
		 return ERROR;
	 }
	 ret = bsp_dpm_suspend();
	 if(ret ==ERROR)
	 {
		return OK;
	 }
	 else
	 	return ERROR;
}
/*case7:给设备5赋上返回错误值的complete回调函数,
              测试观察resume是否会返回错误并打印相关错误log*/
s32 dpm_test_case07()
{
	s32 ret = 0;
	ret=bsp_device_pm_remove(&dev5);
	if(ret ==ERROR)
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_DPM,"remove error\n");
		return ERROR;
	}
	dev5.suspend = my_suspend_ok;
	dev5.complete = my_complete_error;
	ret = bsp_device_pm_add(&dev5);
	 if(ret ==ERROR)
	 {
	 	bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_DPM,"add error\n");
		 return ERROR;
	 }
	 
	 ret = bsp_dpm_suspend();
	 if(ret ==ERROR)
	 	return ERROR;
	 bsp_dpm_resume();
	 return OK;
}
void bsp_cross_mipi_init(void)
{
    u32 i = 0;
    int ret = 0;

    static NV_CROSS_MIPI_MEM cross_mipi_mem;
    static NV_CROSS_MIPI_CTRL cross_mipi_ctrl;

    if (!g_is_cross_mipi_inited) {
        (void)memset_s((void*)&cross_mipi_mem, sizeof(cross_mipi_mem), 0, sizeof(cross_mipi_mem));
        (void)memset_s((void*)&cross_mipi_ctrl, sizeof(cross_mipi_ctrl), 0, sizeof(cross_mipi_ctrl));

        ret = (int)bsp_nvm_read(NV_GU_RF_CROSS_MIPI_MEM_ID, (u8*)&cross_mipi_mem, sizeof(cross_mipi_mem));
        if (ret) {
            bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_CROSS_MIPI, "fail to read cross mipi nv, id: %d\n", NV_GU_RF_CROSS_MIPI_MEM_ID);
            return;
        }

        ret = (int)bsp_nvm_read(NV_GU_RF_CROSS_MIPI_CTRL_ID, (u8*)&cross_mipi_ctrl, sizeof(cross_mipi_ctrl));
        if (ret) {
            bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_CROSS_MIPI, "fail to read cross mipi nv, id: %d\n", NV_GU_RF_CROSS_MIPI_CTRL_ID);
            return;
        }

        g_cross_mipi_ctu_base_addr = (u32)bsp_bbp_part_addr_get(BBP_CTU);
        g_cross_mipi_mem_base_addr = (u32)bsp_bbp_part_addr_get(BBP_CROSS_MIPI_MEM);
        g_cross_mipi_ctrl_base_addr = (u32)bsp_bbp_part_addr_get(BBP_CROSS_MIPI_CTRL);

#ifdef CONFIG_CCORE_PM
        ret = bsp_device_pm_add(&g_cross_mipi_dpm_device);
        if (ret) {
            bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_CROSS_MIPI, "fail to add cross_mipi dpm device\r\n");
            return;
        }
#endif
    }

    if (cross_mipi_ctrl.tuner_en) {
        writel(cross_mipi_ctrl.tuner_en, g_cross_mipi_ctrl_base_addr + CROSS_MIPI_EN_OFFSET);
        writel(cross_mipi_ctrl.tuner_req_en, g_cross_mipi_ctrl_base_addr + CROSS_MIPI_REQ_EN_OFFSET);

        writel(~cross_mipi_ctrl.reg.tuner_mipi_mask, g_cross_mipi_ctu_base_addr + CROSS_MIPI_MASK_OFFSET);
        writel(~cross_mipi_ctrl.reg.gpio_primary_en, g_cross_mipi_ctu_base_addr + CROSS_MIPI_M0_LINE_P_MASK_OFFSET);
        writel(~cross_mipi_ctrl.reg.gpio_secondary_en, g_cross_mipi_ctu_base_addr + CROSS_MIPI_M0_LINE_S_MASK_OFFSET);
        writel(~cross_mipi_ctrl.reg.gpio_modem1_en, g_cross_mipi_ctu_base_addr + CROSS_MIPI_M1_LINE_MASK_OFFSET);

        for (i = 0; i < sizeof(cross_mipi_mem.gpio_buffer)/sizeof(cross_mipi_mem.gpio_buffer[0][0]); i++)
            writel(cross_mipi_mem.gpio_buffer[0][i], g_cross_mipi_mem_base_addr + CROSS_MIPI_GPIO_MEM_OFFSET + i*4);

        for (i = 0; i < sizeof(cross_mipi_mem.mipi_buffer)/sizeof(cross_mipi_mem.mipi_buffer[0][0]); i++)
            writel(cross_mipi_mem.mipi_buffer[0][i], g_cross_mipi_mem_base_addr + CROSS_MIPI_MIPI_MEM_OFFSET + i*4);
        writel(0x7,   g_cross_mipi_ctu_base_addr + CROSS_MIPI_FORCE_OUTPUT_OFFSET);
        writel(0x700, g_cross_mipi_ctu_base_addr + CROSS_MIPI_OUTPUT_VALUE_OFFSET);
        udelay(1);

        writel(0x0,   g_cross_mipi_ctu_base_addr + CROSS_MIPI_OUTPUT_VALUE_OFFSET);
        writel(0x0,   g_cross_mipi_ctu_base_addr + CROSS_MIPI_FORCE_OUTPUT_OFFSET);
    }

    if (!g_is_cross_mipi_inited) {
        g_is_cross_mipi_inited = 1;
        bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_CROSS_MIPI, "cross mipi init ok\n");
    }
}
void bsp_abb_init(void)
{
    int ret = 0;

    u32 abb_version = 0;
    u32 is_supported = 0;

    bsp_abb_deassert_reset();

    if (!g_abb_inited) {
        g_abb_base_addr = bsp_bbp_part_addr_get(BBP_ABB);

        ret = (int)bsp_nvm_read(NV_ID_DRV_NV_PWC_SWITCH, (u8*)&g_abb_pm_switch, sizeof(g_abb_pm_switch));
        if (ret) {
            (void)memset_s((void *)&g_abb_pm_switch, sizeof(g_abb_pm_switch), 0, sizeof(g_abb_pm_switch));
            bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_ABB, "ABB read nv fail, ret = %d\n", ret);
        }
    }

    if (!g_abb_base_addr) {
        bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_ABB, "fail to get abb base address\n");
        return;
    }

    (void)bsp_abb_read(ABB_VERSION_ADDR, &abb_version);

extern int bsp_abb_tv201_init(u32 abb_version, u32 *is_supported);
    ret |= bsp_abb_tv201_init(abb_version, &is_supported);

extern int bsp_abb_tv210_init(u32 abb_version, u32 *is_supported);
    ret |= bsp_abb_tv210_init(abb_version, &is_supported);

extern int bsp_abb_tv220_init(u32 abb_version, u32 *is_supported);
    ret |= bsp_abb_tv220_init(abb_version, &is_supported);

extern int bsp_abb_tv230_init(u32 abb_version, u32 *is_supported);
    ret |= bsp_abb_tv230_init(abb_version, &is_supported);

extern int bsp_abb_tv260_init(u32 abb_version, u32 *is_supported);
    ret |= bsp_abb_tv260_init(abb_version, &is_supported);

extern int bsp_abb_tv300_init(u32 abb_version, u32 *is_supported);
    ret |= bsp_abb_tv300_init(abb_version, &is_supported);

extern int bsp_abb_tv310_init(u32 abb_version, u32 *is_supported);
    ret |= bsp_abb_tv310_init(abb_version, &is_supported);

    if (bsp_rsracc_support()) {
        ret |= bsp_rsracc_register(&g_abb_rsracc_device, 1);
    } else {
#ifdef CONFIG_CCORE_PM
        if (!g_abb_inited) {
            ret |= bsp_device_pm_add(&g_abb_dpm_device);
            if (ret) {
                bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_ABB, "fail to add abb dpm device\r\n");
                return;
            }
        }
#endif
    }

    if (ret) {
        bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_ABB, "ABB init fail\n");
        return;
    }

    if (!is_supported) {
        bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_ABB, "don't support this ABB version: 0x%x\n", abb_version);
        return;
    }

    if (!g_abb_inited) {
        g_abb_inited = 1;
        g_abb_ops.abb_om = (struct abb_om_info*)bsp_pm_dump_get(PM_OM_ABB, sizeof(struct abb_om_info));
        if (!g_abb_ops.abb_om)
            g_abb_ops.abb_om = &g_abb_om_info;

        (void)memset_s((void *)(g_abb_ops.abb_om), sizeof(struct abb_om_info), 0, sizeof(struct abb_om_info));

        bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_ABB, "ABB init ok, version: 0x%x\n", abb_version);
    }
}
/*****************************************************************************
 函 数 名  : bsp_dual_modem_init
 功能描述  : K3 modem uart相关初始化
 输入参数  : void
 输出参数  : -1:失败,0:成功
 返 回 值  : int
****************************************************************************/
int bsp_dual_modem_drv_init(void)
{
	int ret = ERROR;
	RECV_STR *recvStr = NULL;
#ifdef LPM3_VIA_GPIO
	struct dual_modem_icc_msg_str dm_msg = {0};
#endif

	recvStr = &g_dual_modem_ctrl.uart_port.circ_buf;

	if(DUAl_MODEM_ENABLE == g_dual_modem_ctrl.nv_flag
		&& DUAl_MODEM_DISABLE == g_dual_modem_ctrl.init_flag)
    {
		wake_lock(&g_dual_modem_ctrl.wakelock);
		memset_s((void*)&g_dual_modem_ctrl.uart_port.circ_buf, sizeof(g_dual_modem_ctrl.uart_port.circ_buf), 0, sizeof(g_dual_modem_ctrl.uart_port.circ_buf)); 
		osl_sem_init(0, &g_dual_modem_ctrl.wait_reply_mutex);
		osl_sem_init(0, &g_dual_modem_ctrl.recv_mutex);
    	osl_sem_mcreate(&g_dual_modem_ctrl.uart_port.send_mutex, OSL_SEM_Q_PRIORITY | OSL_SEM_DELETE_SAFE);
		spin_lock_init(&g_dual_modem_ctrl.lock);
			
		g_dual_modem_ctrl.uart_port.ops = &send_ops;
		
		if(OK != get_info_from_dts())
		{
			dm_print_err("get dts err %d\n",ret);
			goto init_fail;
		}
		writel(0x8000000 | g_dual_modem_ctrl.ap_uart.bit_shift, 
			   g_dual_modem_ctrl.ap_uart.crg_addr + g_dual_modem_ctrl.ap_uart.clk_uarth_clkdiv);
		writel(g_dual_modem_ctrl.ap_uart.bit_shift, 
			   g_dual_modem_ctrl.ap_uart.crg_addr + g_dual_modem_ctrl.ap_uart.clk_uart_peren);

		dual_modem_uart_channel_init(&g_dual_modem_ctrl.uart_port);

#ifdef CONFIG_CCORE_PM
	   if(bsp_device_pm_add(&dual_modem_device))
	   {
			dm_print_err("device add err\n");
			goto init_fail;
	   }
#endif
		if(OK != osl_task_init("utlrecv", DUAL_MODEM_TASK_PRO, DUAL_MODEM_TASK_STK,
		     (OSL_TASK_FUNC)dual_modem_uart_recv_task, (UART_PORT *)&g_dual_modem_ctrl.uart_port, &recvStr->recv_task_id))
    	{
			dm_print_err("utlrecv task err\n");
			goto init_fail;
    	}
		

		ret = request_irq(g_dual_modem_ctrl.uart_port.irq_num, 
			(irq_handler_t)dual_modem_uart_irq_handler, 0, "dual modem irq", &g_dual_modem_ctrl.uart_port);
		if(ret){
			dm_print_err("request irq err\n");
			goto init_fail;
		}

#ifdef LPM3_VIA_GPIO
		dm_msg.dual_modem_init_flag = UART_INIT_ENABLE;
		dm_msg.icc_msgs_flag = LPm3_UART5_IQR_DISABLE;

		/* 通知lpm3	*/
		bsp_icc_send((u32)ICC_CPU_MCU,(ICC_CHN_MCORE_CCORE << 16)|MCORE_CCORE_FUNC_UART,(u8 *)&dm_msg,sizeof(dm_msg));
#else
		bsp_gpio_direction_input(g_dual_modem_ctrl.wakeup_gpio);
		bsp_gpio_irq_unmask(g_dual_modem_ctrl.wakeup_gpio);
		ret = bsp_gpio_request_irq(g_dual_modem_ctrl.wakeup_gpio, (irq_handler_t)wakeup_gpio_int, IRQ_TYPE_EDGE_FALLING, "cpcp gpio");
		if(ret)
		{
			dm_print_err("gpio irq request err\n");
			goto init_fail;
		}
#endif
		g_dual_modem_ctrl.init_flag = DUAl_MODEM_ENABLE;
		wake_unlock(&g_dual_modem_ctrl.wakelock);
    }
    return OK;
init_fail:
	bsp_gpio_irq_mask(g_dual_modem_ctrl.wakeup_gpio);
	wake_unlock(&g_dual_modem_ctrl.wakelock);
	return ERROR;
}
void bsp_ipc_init(void)
{
	s32 ret = 0,i = 0;
    struct device_node *ptr_device_node = NULL;
	const char *compatible_name = "hisilicon,ipc_balong_mdm";
	char *ret_of_iomap = NULL;
	u32  irq_no_ipc_int = 0;
	u32  irq_no_ipc_sem = 0;
	
	ipc_ctrl.core_num = IPC_CORE_CCORE;
	for(i = 0;i< INTSRC_NUM;i++ )
	{
		ipc_ctrl.sem_exist[i] = false;
	}
	#ifdef CONFIG_CCORE_PM
	ret = bsp_device_pm_add(&ipc_dpm);
	if(ret)
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ipc init fail\n");
		return;
	}
	#endif

    /* 读取基地址并映射 */
	ptr_device_node = of_find_compatible_node(NULL, NULL, compatible_name);
	if (!ptr_device_node)  /* 找不到节点 */
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ccore ipc of_find_compatible_node fail\n");
		return;
	}

    ret_of_iomap = of_iomap(ptr_device_node, 0); 
	if (!ret_of_iomap)  /* 映射错误 */
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"of_iomap fail\n");
		return;
	}

#ifdef CONFIG_IPCM_USE_FPGA_VIC
    g_p532_asic_ipcm_virt_addr = (unsigned long)ret_of_iomap;

	/* 读取基地址并映射 */
	ptr_device_node = of_find_compatible_node(NULL, NULL, "hisilicon,ipc_balong_mdm_fpga");
	if (!ptr_device_node)  /* 找不到节点 */
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ccore ipc of_find_compatible_node fail\n");
		return;
	}

	ret_of_iomap = of_iomap(ptr_device_node, 0); 
	if (!ret_of_iomap)	/* 映射错误 */
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"of_iomap fail\n");
		return;
	}

#endif
	
	(void)memset_s((void*)(ipc_ctrl.ipc_int_table), sizeof(struct ipc_entry) * INTSRC_NUM, 
		                                   0x0, sizeof(struct ipc_entry) * INTSRC_NUM);
	ipc_ctrl.ipc_base[IPCM_NS] = (u32)ret_of_iomap; //HI_IPCM_REGBASE_ADDR_VIRT
	writel(0x0,ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_CPU_INT_MASK(ipc_ctrl.core_num));
	writel(0x0,ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_SEM_INT_MASK(ipc_ctrl.core_num));
	writel(0xffffffff,ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_CPU_INT_CLR(ipc_ctrl.core_num));/*清所有32个中断*/
	writel(0xffffffff,ipc_ctrl.ipc_base[IPCM_NS] + BSP_IPC_SEM_INT_CLR(ipc_ctrl.core_num));/*清所有32个中断*/
	ipc_free_sem_taked((u32)IPC_CORE_CCORE);
	ipc_free_sem_taked((u32)IPC_CORE_LDSP);
	spin_lock_init(&ipc_ctrl.lock);
#ifdef CONFIG_IPCM_USE_FPGA_VIC
	/* 获取中断号 */
	irq_no_ipc_int = irq_of_parse_and_map(ptr_device_node, 0);
	ret = bsp_vic_connect(irq_no_ipc_int, (vicfuncptr)ipc_int_handler, 0);
	ret |= bsp_vic_enable(irq_no_ipc_int);
	if (ret )
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ipc int handler error,init failed\n");
		return;
	}

	/* 获取中断号 */
	irq_no_ipc_sem = irq_of_parse_and_map(ptr_device_node, 1);
	ret = bsp_vic_connect(irq_no_ipc_sem, (vicfuncptr)ipc_sem_int_handler, 0);
	ret |= bsp_vic_enable(irq_no_ipc_sem);
	if (ret )
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ipc sem handler error,init failed\n");
		return;
	}

#else
    /* 获取中断号 */
	irq_no_ipc_int = irq_of_parse_and_map(ptr_device_node, 0);
	ret = request_irq(irq_no_ipc_int,(irq_handler_t) ipc_int_handler, 0, "ipc_irq",(void*)IPCM_NS);  //IPC_INT
	if (ret )
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ipc int handler error,init failed\n");
		return;
	}

    /* 获取中断号 */
	irq_no_ipc_sem = irq_of_parse_and_map(ptr_device_node, 1);
	ret = request_irq(irq_no_ipc_sem, (irq_handler_t) ipc_sem_int_handler, 0, "ipc_sem",(void*) NULL);  //IPC_SEM
	if (ret )
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ipc sem handler error,init failed\n");
		return;
	}
#endif
	
	#ifdef ENABLE_TEST_CODE
	ret = bsp_ipc_test_init();
	if (ret )
	{
		bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"bsp_ipc_test_init failed\n");
		return;
	}
	#endif
	bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"ccore ipc_ns init success\n");
	bsp_ipc_s_init();
	return;
}
s32 bsp_i2c_initial(void)
{
	s32 ret=0;

	/*initial variable*/
#ifdef HI_I2C_REGBASE_ADDR
	spin_lock_init(&p531_i2c.lock);
	p531_i2c.regs=HI_I2C_REGBASE_ADDR;
	p531_i2c.master_name="p531_i2c";
	p531_i2c.slave_num=0;

	p531_i2c.clk=clk_get(NULL,"i2c0_clk");/*default p531 use I2C0,if change ensure sync code*/
    if(ret = bsp_i2c_clk_enable(&p531_i2c))/*close clk should enable it firstly,ensure with xujingcui*/
	{
		i2c_print_error("i2c_dpm_device add error\n");
		return ERROR;
	}
	/* set high high level cycle*/
	balong_i2c_scl_high(&p531_i2c);
	/* set high low level cycle */
	balong_i2c_scl_low(&p531_i2c);


	bsp_i2c_clk_disable(&p531_i2c);
#endif

#ifdef HI_I2C1_REGBASE_ADDR
	/*i2c0 initial*/
	spin_lock_init(&v7r2_i2c0.lock);
	v7r2_i2c0.regs=HI_I2C0_REGBASE_ADDR;
	v7r2_i2c0.master_name="v7r2_i2c0";
	v7r2_i2c0.slave_num=0;

	v7r2_i2c0.clk=clk_get(NULL,"i2c0_clk");
	ret = bsp_i2c_clk_enable(&v7r2_i2c0);
	if(ret)/*close clk should enable it firstly,ensure with xujingcui*/
	{
		i2c_print_error("i2c_dpm_device add error\n");
		return ERROR;
	}

	/* set high high level cycle*/
	balong_i2c_scl_high(&v7r2_i2c0);
	/* set high low level cycle */
	balong_i2c_scl_low(&v7r2_i2c0);
	bsp_i2c_clk_disable(&v7r2_i2c0);

	/*i2c1 initial*/
	spin_lock_init(&v7r2_i2c1.lock);
	v7r2_i2c1.regs=HI_I2C1_REGBASE_ADDR;
	v7r2_i2c1.master_name="v7r2_i2c1";
	v7r2_i2c1.slave_num=0;

	v7r2_i2c1.clk=clk_get(NULL,"i2c1_clk");
	ret = bsp_i2c_clk_enable(&v7r2_i2c1);
    if(ret)/*close clk should enable it firstly,ensure with xujingcui*/
	{
		i2c_print_error("i2c_dpm_device add error\n");
		return ERROR;
	}
	/* set high high level cycle*/
	balong_i2c_scl_high(&v7r2_i2c1);
	/* set high low level cycle */
	balong_i2c_scl_low(&v7r2_i2c1);
	/*close clk*/
	bsp_i2c_clk_disable(&v7r2_i2c1);
#endif

#ifdef CONFIG_CCORE_PM
	ret = bsp_device_pm_add(&i2c_dpm_device);
	if(OK!= ret)
	{
		i2c_print_error("i2c_dpm_device add error\n");
		return ERROR;
	}
#endif

	return 0;
}
void  cpufreq_init(void)
{
	/*lint --e{516}*/
	u32 i = 0;
	u32 retValue = 0;
	ST_PWC_SWITCH_STRU cpufreq_control_nv = {0} ;
    retValue = bsp_nvm_read(NV_ID_DRV_NV_DFS_SWITCH,(u8*)&g_stDfsSwitch,sizeof(ST_PWC_DFS_STRU));
    if (NV_OK != retValue)
    {
    	cpufreq_err("read nv failed use default value\n");
		g_stDfsSwitch.CcpuDownLimit = 60;
		g_stDfsSwitch.CcpuDownNum = 3;
		g_stDfsSwitch.CcpuUpLimit = 85;
		g_stDfsSwitch.CcpuUpNum = 1;
		g_stDfsSwitch.DFSTimerLen = 400;
		g_stDfsSwitch.Strategy = 0;/*使用4s检测一次的策略*/
		g_stDfsSwitch.DFSDdrUpLimit = 85;
		g_stDfsSwitch.DFSDdrDownLimit = 60;
		g_stDfsSwitch.DFSDdrprofile = 5;
		g_stDfsSwitch.reserved = 0;
    }
	retValue = bsp_nvm_read(NV_ID_DRV_NV_PWC_SWITCH,(u8*)&cpufreq_control_nv,sizeof(ST_PWC_SWITCH_STRU));
	if (NV_OK == retValue)
	{
		g_cpufreq_lock_status_flag = cpufreq_control_nv.dfs;
	}
	else
	{
		cpufreq_err("read nv failed %d\n", retValue);
	}

    memset(&g_stDfsCpuConfigInfo, 0, sizeof(g_stDfsCpuConfigInfo));
    memset(&g_stDfsCpuControl, 0, sizeof(g_stDfsCpuControl));
	g_stDfsCpuControl.enCurProfile = BALONG_FREQ_MAX;

	register_icc_for_cpufreq();
	cpufreq_table_init();
#ifdef CONFIG_CCORE_PM
    if (bsp_device_pm_add(&g_cpufreq_dpm_device))
    {
		cpufreq_err("register dpm failed,check it\n");
    }
#endif
    /*bit1 使用MS级调频策略*/
    if (g_stDfsSwitch.Strategy & 0x1)
    {
		  g_sem_calccpu_flag = semBCreate(SEM_Q_PRIORITY, SEM_FULL); /*lint !e64 */
		  if (NULL == g_sem_calccpu_flag)
		  {
		      cpufreq_err("Create g_sem_k3get_volt Failed %d\n", g_sem_calccpu_flag);
		  }
	}

    g_stDfsCpuConfigInfo.ulDFSFunEnableFlag = DFS_TRUE;
    g_stDfsCpuConfigInfo.usProfileDownTime = g_stDfsSwitch.CcpuDownNum;
    g_stDfsCpuConfigInfo.usProfileUpTime = g_stDfsSwitch.CcpuUpNum;
    g_stDfsCpuConfigInfo.ulProfileNum = DC_RESV;
    g_stDfsCpuConfigInfo.ulTimerLen = g_stDfsSwitch.DFSTimerLen;
    g_test_in_interr_times = g_stDfsSwitch.DFSTimerLen;

    for (i = 0; i < g_stDfsCpuConfigInfo.ulProfileNum; i++)
    {
        g_stDfsCpuConfigInfo.astThresHold[i].usProfileUpLimit   = g_stDfsSwitch.CcpuUpLimit;
        g_stDfsCpuConfigInfo.astThresHold[i].usProfileDownLimit = g_stDfsSwitch.CcpuDownLimit;
    }
    INIT_LIST_HEAD(&(g_v9_qos_list.entry));
    /*添加DDR调频请求*/
    (void)PWRCTRL_DfsQosRequest(DFS_QOS_ID_DDR_MINFREQ, BALONG_DDRFREQUENCY_MIN, &g_ddr_request_id);
    
    taskSpawn("dfs_task", 1, 0, 4096, (FUNCPTR)pwrctrl_dfs_mgrmsg_task, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);/*lint !e64 !e119 */
	g_cpufreq_start_time = bsp_get_slice_value();
	cpufreq_err("cpufreq init ok\n");
    return;
}