Example #1
0
static void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
		struct skl_ipc_header header)
{
	struct ipc_message *msg;
	u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK;
	u64 *ipc_header = (u64 *)(&header);
	struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc);
	unsigned long flags;

	spin_lock_irqsave(&ipc->dsp->spinlock, flags);
	msg = skl_ipc_reply_get_msg(ipc, *ipc_header);
	spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
	if (msg == NULL) {
		dev_dbg(ipc->dev, "ipc: rx list is empty\n");
		return;
	}

	/* first process the header */
	if (reply == IPC_GLB_REPLY_SUCCESS) {
		dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary);
		/* copy the rx data from the mailbox */
		sst_dsp_inbox_read(ipc->dsp, msg->rx_data, msg->rx_size);
		switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
		case IPC_GLB_LOAD_MULTIPLE_MODS:
		case IPC_GLB_LOAD_LIBRARY:
			skl->mod_load_complete = true;
			skl->mod_load_status = true;
			wake_up(&skl->mod_load_wait);
			break;

		default:
			break;

		}
	} else {
		msg->errno = skl_ipc_set_reply_error_code(reply);
		dev_err(ipc->dev, "ipc FW reply: reply=%d\n", reply);
		dev_err(ipc->dev, "FW Error Code: %u\n",
			ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
		switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
		case IPC_GLB_LOAD_MULTIPLE_MODS:
		case IPC_GLB_LOAD_LIBRARY:
			skl->mod_load_complete = true;
			skl->mod_load_status = false;
			wake_up(&skl->mod_load_wait);
			break;

		default:
			break;

		}
	}

	spin_lock_irqsave(&ipc->dsp->spinlock, flags);
	list_del(&msg->list);
	sst_ipc_tx_msg_reply_complete(ipc, msg);
	spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
}
Example #2
0
static void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
		struct skl_ipc_header header)
{
	struct ipc_message *msg;
	u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK;
	u64 *ipc_header = (u64 *)(&header);

	msg = skl_ipc_reply_get_msg(ipc, *ipc_header);
	if (msg == NULL) {
		dev_dbg(ipc->dev, "ipc: rx list is empty\n");
		return;
	}

	/* first process the header */
	switch (reply) {
	case IPC_GLB_REPLY_SUCCESS:
		dev_info(ipc->dev, "ipc FW reply %x: success\n", header.primary);
		break;

	case IPC_GLB_REPLY_OUT_OF_MEMORY:
		dev_err(ipc->dev, "ipc fw reply: %x: no memory\n", header.primary);
		msg->errno = -ENOMEM;
		break;

	case IPC_GLB_REPLY_BUSY:
		dev_err(ipc->dev, "ipc fw reply: %x: Busy\n", header.primary);
		msg->errno = -EBUSY;
		break;

	default:
		dev_err(ipc->dev, "Unknown ipc reply: 0x%x", reply);
		msg->errno = -EINVAL;
		break;
	}

	if (reply != IPC_GLB_REPLY_SUCCESS) {
		dev_err(ipc->dev, "ipc FW reply: reply=%d", reply);
		dev_err(ipc->dev, "FW Error Code: %u\n",
			ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
	}

	list_del(&msg->list);
	sst_ipc_tx_msg_reply_complete(ipc, msg);
}