s32 send_sync_msg_to_mcore(u32 reset_info, u32 *ack_val)
{
	s32 ret = 0;
	/*如果是modem处于复位状态,则调用AP侧IPC*/
	/*ap receive mabx 0,send mbx 13*/
	rproc_msg_t tx_buffer[2] ;
	rproc_msg_t ack_buffer[2] ;
	/*发送标志,用于LPM3上接收时解析*/
	tx_buffer[0] = (0<<24|9<<16|3<<8);
	tx_buffer[1] = reset_info;
	ret = RPROC_SYNC_SEND(HISI_RPROC_LPM3, tx_buffer, 2, SYNC_MSG, ack_buffer, 2);
	if (ret)
	{
		*ack_val = -1;
	}
	else
	{
		*ack_val = (u32)ack_buffer[1];
	}
	return ret;
}
static void iom3_recovery_work(struct work_struct *work)
{
	int rec_nest_count = 0;
	int rc;
	u32 ack_buffer;
	u32 tx_buffer;

	hwlog_err("%s enter\n", __func__);
	wake_lock(&iom3_rec_wl);

recovery_iom3:
	if(rec_nest_count++ > IOM3_REC_NEST_MAX){
		hwlog_err("unlucky recovery iom3 times exceed limit\n");
		atomic_set(&iom3_rec_state, IOM3_RECOVERY_FAILED);
		blocking_notifier_call_chain(&iom3_recovery_notifier_list, IOM3_RECOVERY_FAILED, NULL);
		atomic_set(&iom3_rec_state, IOM3_RECOVERY_IDLE);
		wake_unlock(&iom3_rec_wl);
		hwlog_err("%s exit\n", __func__);
		return;
	}

	//wait for iom3 enter WFI state
	show_iom3_stat();//only for IOM3 debug
	//rc = wait_for_iom3_wfi(100);
	//if(rc < 0 || 0 == rc) {//ioremap error || wait wfi timeout
	//	hwlog_err("RPROC wait for iom3 WFI failed %d, nest_count %d\n", rc, rec_nest_count);
	//	goto recovery_iom3;
	//}

	//reload iom3 system
	tx_buffer = RELOAD_IOM3_CMD;
	rc = RPROC_SYNC_SEND(HISI_RPROC_LPM3, &tx_buffer, 1, 1, &ack_buffer, 1);
	if (rc) {
		hwlog_err("RPROC reload iom3 failed %d, nest_count %d\n", rc, rec_nest_count);
		goto recovery_iom3;
	}

	show_iom3_stat();//only for IOM3 debug
	reset_i2c_0_controller();
	msleep(5);
	hw_power_reset_for_recovery_iom3();
	atomic_set(&iom3_rec_state, IOM3_RECOVERY_MINISYS);

	//startup iom3 system
	INIT_COMPLETION(iom3_rec_done);
	tx_buffer = STARTUP_IOM3_CMD;
	rc = RPROC_SYNC_SEND(HISI_RPROC_LPM3, &tx_buffer, 1, 1, &ack_buffer, 1);
	if (rc) {
		hwlog_err("RPROC start iom3 failed %d, nest_count %d\n", rc, rec_nest_count);
		goto recovery_iom3;
	}
	hwlog_err("RPROC restart iom3 success\n");
	show_iom3_stat();//only for IOM3 debug

	//dynamic loading
	if (!wait_for_completion_timeout(&iom3_rec_done, 5*HZ)) {
		hwlog_err("wait for iom3 system ready timeout\n");
		msleep(1000);
		goto recovery_iom3;
	}

	//repeat send cmd
	msleep(100);//wait iom3 finish handle config-data
	atomic_set(&iom3_rec_state, IOM3_RECOVERY_DOING);
	hwlog_err("%s doing\n", __func__);
	blocking_notifier_call_chain(&iom3_recovery_notifier_list, IOM3_RECOVERY_DOING, NULL);
	operations_when_recovery_iom3();
	atomic_set(&iom3_rec_state, IOM3_RECOVERY_IDLE);
	wake_unlock(&iom3_rec_wl);
	hwlog_err("%s finish recovery\n", __func__);
	blocking_notifier_call_chain(&iom3_recovery_notifier_list, IOM3_RECOVERY_IDLE, NULL);
	hwlog_err("%s exit\n", __func__);
	return;
}
int test_rproc_msg_send(unsigned int sync_id, 
		unsigned char rp_id,
		unsigned int msg_len,
		unsigned int msg_num, 
		struct test_rproc_cb *rproc_cb)
{
	int ret = 0;
	rproc_msg_t tx_buffer[8] = {0};
	rproc_msg_t ack_buffer[8] = {0};
	struct semaphore *complete_sema;
	unsigned int start_slice = 0;
	unsigned int end_slice = 0;
    unsigned int sync_task_cnt = 0;

	if (sync_id > 0x3) {
		printk(KERN_ERR "wrong sync id!\n");
		return -1;
	}

	if (msg_len > 8) {
		printk(KERN_ERR "illegal message length!\n");
		return -1;
	}

	if(rproc_cb) {
        down(&task_mutex_sema);
		rproc_cb->sync_task_cnt--;
        sync_task_cnt = rproc_cb->sync_task_cnt;
        up(&task_mutex_sema);
		if ((0 == sync_task_cnt) 
		&& (TEST_RPROC_NULL != rproc_cb->sync_sema)) {
			rproc_cb->start_slice = test_rproc_get_slice();
			up(rproc_cb->sync_sema);
		}

		/*进程同步*/
		if (TEST_RPROC_NULL != rproc_cb->sync_sema) {
			down(rproc_cb->sync_sema);
			up(rproc_cb->sync_sema);
		}
	}

	tx_buffer[0] = (OBJ_TEST << 16) | (CMD_TEST << 8)/*0x00120500*/;
	memcpy((void*)&tx_buffer[1], (void*)&data_buf[0], sizeof(tx_buffer) - sizeof(tx_buffer[0]));
	switch(sync_id)
	{
		case 0:/*同步发送同步消息*/
			while(msg_num--){
				ret = RPROC_SYNC_SEND(rp_id,tx_buffer, msg_len,SYNC_MSG,ack_buffer,msg_len);
				if (ret || (((OBJ_TEST << 16) | (CMD_TEST << 8)) != ack_buffer[0]) || (0x12345678 != ack_buffer[1])) {
					printk(KERN_ERR "rproc send error, ret %d, rp %d, sync %d, ack[0x%x][0x%x]!\r\n", 
							ret, rp_id, sync_id, ack_buffer[0], ack_buffer[1]);
					return -1;
				}
				if(rproc_cb)
					rproc_cb->msg_count++;
			}
			break;

		case 1:/*同步发送异步消息*/
			while(msg_num--){
				ret = RPROC_SYNC_SEND(rp_id ,tx_buffer, msg_len,ASYNC_MSG,NULL,0);
				if (ret) {
					printk(KERN_ERR "rproc send error, ret %d, rp %d, sync %d!\r\n", ret, rp_id, sync_id);
					return -1;
				}
				if(rproc_cb)
					rproc_cb->msg_count++;
			}
			break;

		case 2:/*异步发送同步消息*/
			while (msg_num--) {
				complete_sema = (struct semaphore*)kmalloc(sizeof(struct semaphore), GFP_KERNEL);
				sema_init(complete_sema, 0);
				ret = RPROC_ASYNC_SEND(rp_id,tx_buffer,msg_len,SYNC_MSG,rporc_async_callback,complete_sema);
				if (ret) {
					printk(KERN_ERR "rproc send error, ret %d, rp %d, sync %d!\r\n", ret, rp_id, sync_id);
					kfree(complete_sema);
					return -1;
				}
				start_slice = test_rproc_get_slice();
				if (0 != down_timeout(complete_sema, msecs_to_jiffies(1000)))
				{
					printk(KERN_ERR "msg_send timeout rp_id:%d rproc async send err!\r\n", rp_id);
					/*如果超时,不能释放内存*/
					/*kfree(complete_sema);*/
					return -1;
				}
				end_slice = test_rproc_get_slice();
				printk(KERN_INFO "async send sync msg spend %d slice!\r\n",
						test_rproc_slice_diff(start_slice, end_slice));
				kfree(complete_sema);
				if(rproc_cb)
					rproc_cb->msg_count++;
			}
			break;

		case 3:/*异步发送异步消息*/
			while (msg_num--) {
				ret = RPROC_ASYNC_SEND(rp_id,tx_buffer,msg_len,ASYNC_MSG,rporc_async_callback,NULL);
				if (ret) {
					printk(KERN_ERR "rproc send error, ret %d, rp %d, sync %d!\r\n", ret, rp_id, sync_id);
					return ret;
				}
				if(rproc_cb)
					rproc_cb->msg_count++;
			}
			break;

		default:
			printk(KERN_ERR "wrong sync ID!\n");
			return -1;
	}
	printk(KERN_INFO "rproc send ok, rp %d, sync %d!\n", rp_id, sync_id);

	return ret;
}