static struct hisi_mbox_task *mbox_debugfs_get_task(struct hisi_mbox *mbox, mbox_msg_t *msg, mbox_msg_len_t len, char *rp_name, struct mbox_task *context) { struct hisi_mbox_task *tx_task = NULL; mbox_msg_t *tx_buffer = NULL; tx_buffer = kmalloc(sizeof(mbox_msg_t) * len, GFP_KERNEL); if (!tx_buffer) return tx_task; memcpy(tx_buffer, msg, sizeof(mbox_msg_t) * len); context->tx_buffer = tx_buffer; tx_task = hisi_mbox_task_alloc(mbox, rp_name, tx_buffer, len, 1, mbox_debugfs_complete, context); if (!tx_task) kfree(tx_buffer); return tx_task; }
/* AP sends msgs to LPM3 for adc sampling&converting. */ static int adc_send_ipc_to_lpm3(int channel) { struct hisi_mbox_task *adc_tx_task; int loop = ADC_IPC_MAX_CNT; int ret = 0; if (channel > ADC_CHN_MAX) { pr_err("%s: invalid channel!\n", MODULE_NAME); ret = -EINVAL; goto err_adc_channel; } if (!hisi_adc_dev) { pr_err("%s: adc dev is not initialized yet!\n", MODULE_NAME); ret = -ENODEV; goto err_adc_dev; } if (hisi_adc_dev->tx_msg[ADC_IPC_CMD_TYPE] != ADC_IPC_DATA) hisi_adc_dev->tx_msg[ADC_IPC_CMD_TYPE] = ADC_IPC_DATA; hisi_adc_dev->info.channel = channel; hisi_adc_dev->tx_msg[ADC_IPC_CMD_CHANNEL] = channel; adc_tx_task = hisi_mbox_task_alloc(hisi_adc_dev->mbox, HISI_MAILBOX_RP_LPM3, hisi_adc_dev->tx_msg, ADC_IPC_CMD_LEN, 1, adc_complete_func, NULL); if (!adc_tx_task) { pr_err("%s: fail to alloc mbox task!\n", MODULE_NAME); ret = -ENOMEM; goto err_alloc_task; } do { ret = hisi_mbox_msg_send_async(hisi_adc_dev->mbox, adc_tx_task); loop--; } while (ret == -ENOMEM && loop > 0); if (ret) { pr_err("%s: fail to send mbox msg, ret = %d!\n", MODULE_NAME, ret); goto err_msg_async; } return ret; err_msg_async: hisi_mbox_task_free(&adc_tx_task); err_alloc_task: hisi_adc_dev->info.channel = ADC_RESULT_ERR; err_adc_dev: err_adc_channel: return ret; }
static int hisi_clkmbox_send_ipc(mbox_msg_t *msg, void *context, int autoack) { struct hisi_mbox_task *tx_task; int loop = MAX_SEND_IPC_TRY; mbox_msg_t *tx_msg; int ret, i; tx_msg = kzalloc(sizeof(mbox_msg_t) * LPM3_CMD_LEN, GFP_ATOMIC); if (!tx_msg) { pr_err("[%s] fail to alloc tx_msg!\n", __func__); ret = -ENOMEM; goto err; } /* construct cmd */ for (i = 0; i < LPM3_CMD_LEN; i++) { tx_msg[i] = msg[i]; pr_debug("[%s] tx_msg[i] = 0x%x\n", __func__, tx_msg[i]); } tx_task = hisi_mbox_task_alloc(mbox_clk->mbox, HISI_MAILBOX_RP_LPM3, tx_msg, LPM3_CMD_LEN, autoack, hisi_clkmbox_default_complete, context); if (!tx_task) { pr_err("[%s] fail to alloc mbox task!\n", __func__); ret = -ENOMEM; goto err_task; } /* try again if failing to send */ do { ret = hisi_mbox_msg_send_async(mbox_clk->mbox, tx_task); loop--; } while (ret == -ENOMEM && loop > 0); if (ret) { pr_err("[%s] fail to send mbox msg, ret = %d!\n", __func__, ret); goto err_snd_async; } return 0; err_snd_async: hisi_mbox_task_free(&tx_task); err_task: kfree(tx_msg); tx_msg = NULL; err: return ret; }
void boot_iom3(void) { struct hisi_mbox_task *tx_task = NULL; if (!(lpm3_mbox = hisi_mbox_get(HISI_MAILBOX_RP_LPM3, NULL))) { hwlog_err("failed to get mailbox in %s\n", __func__); return; } tx_task = hisi_mbox_task_alloc(lpm3_mbox, HISI_MAILBOX_RP_LPM3, &g_boot_iom3, 1, 1, inputhub_power_on_complete, NULL); if(!tx_task) { hwlog_err("failed to alloc task %s\n", __func__); return; } if (hisi_mbox_msg_send_async(lpm3_mbox,tx_task) != 0) { hwlog_err("hisi_mbox_msg_send_async error in %s\n", __func__); } }
int inputhub_mcu_send(const char *buf, unsigned long length) { struct hisi_mbox_task *tx_task = NULL; mbox_msg_t *tx_buffer = NULL; mbox_msg_len_t len=0; int i = 0; int ret = -1; if(NULL==mbox) inputhub_mcu_connect(); if(NULL==mbox) return ret; len = (length + sizeof(mbox_msg_t) - 1) / (sizeof(mbox_msg_t)); //todo:send 256 bytes max one time, and repeat until buf was sent. tx_buffer = (mbox_msg_t *)kmalloc(sizeof(mbox_msg_t)*len, GFP_KERNEL); if (!tx_buffer) return ret; memcpy(tx_buffer, buf, length); pr_debug("inputhub_mcu_send------------->length = %d, len = %d\n", (int)length, (int)len); for (i = 0; i < len; i++) pr_debug("tx_buffer[%d] = 0x%x\n", i, tx_buffer[i]); tx_task = hisi_mbox_task_alloc(mbox, HISI_MAILBOX_RP_IOM3, tx_buffer, len, 0, inputhub_mcu_send_complete, NULL); if (!tx_task) { kfree((void *)tx_buffer); return ret; } INIT_COMPLETION(send_complete); ret=hisi_mbox_msg_send_async(mbox,tx_task); if(ret) { hwlog_err("hisi_mbox_msg_send_async return %d.\n", ret); if (tx_task->tx_buffer) kfree((void *)tx_task->tx_buffer); tx_task->tx_buffer = NULL; hisi_mbox_task_free(&tx_task); return -1; } wait_for_completion(&send_complete); if ((-ETIMEOUT) == tx_task->tx_error) { hwlog_err("send failed timeout\n"); if(!dsm_client_ocuppy(shb_dclient)){ dsm_client_record(shb_dclient, "IOM3RSTSTAT: 0x%x\n", read_reg32(IOM3RSTSTAT_ADDR)); dsm_client_record(shb_dclient, "PERRSTSTAT4: 0x%x\n", read_reg32(PERRSTSTAT4_ADDR)); dsm_client_record(shb_dclient, "PERSTAT5: 0x%x\n", read_reg32(PERSTAT5_ADDR)); dsm_client_record(shb_dclient, "IOM3CLKEN: 0x%x\n", read_reg32(IOM3CLKEN_ADDR)); dsm_client_notify(shb_dclient, DSM_SHB_ERR_IPC_TIMEOUT); } ret = -1; }else{ hwlog_debug("send success\n"); ret = 0; } kfree((void *)tx_task->tx_buffer); tx_task->tx_buffer = NULL; hisi_mbox_task_free(&tx_task); return ret; }