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; }