コード例 #1
0
ファイル: skl-sst-ipc.c プロジェクト: asmalldev/linux
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);
}
コード例 #2
0
ファイル: skl-sst-ipc.c プロジェクト: DenisLug/mptcp
static int skl_ipc_process_notification(struct sst_generic_ipc *ipc,
		struct skl_ipc_header header)
{
	struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc);

	if (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
		switch (IPC_GLB_NOTIFY_TYPE(header.primary)) {

		case IPC_GLB_NOTIFY_UNDERRUN:
			dev_err(ipc->dev, "FW Underrun %x\n", header.primary);
			break;

		case IPC_GLB_NOTIFY_RESOURCE_EVENT:
			dev_err(ipc->dev, "MCPS Budget Violation: %x\n",
						header.primary);
			break;

		case IPC_GLB_NOTIFY_FW_READY:
			skl->boot_complete = true;
			wake_up(&skl->boot_wait);
			break;

		default:
			dev_err(ipc->dev, "ipc: Unhandled error msg=%x",
						header.primary);
			break;
		}
	}

	return 0;
}
コード例 #3
0
ファイル: skl-sst-ipc.c プロジェクト: asmalldev/linux
static int skl_ipc_process_notification(struct sst_generic_ipc *ipc,
		struct skl_ipc_header header)
{
	struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc);

	if (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
		switch (IPC_GLB_NOTIFY_TYPE(header.primary)) {

		case IPC_GLB_NOTIFY_UNDERRUN:
			dev_err(ipc->dev, "FW Underrun %x\n", header.primary);
			break;

		case IPC_GLB_NOTIFY_RESOURCE_EVENT:
			dev_err(ipc->dev, "MCPS Budget Violation: %x\n",
						header.primary);
			break;

		case IPC_GLB_NOTIFY_FW_READY:
			skl->boot_complete = true;
			wake_up(&skl->boot_wait);
			break;

		case IPC_GLB_NOTIFY_PHRASE_DETECTED:
			dev_dbg(ipc->dev, "***** Phrase Detected **********\n");

			/*
			 * Per HW recomendation, After phrase detection,
			 * clear the CGCTL.MISCBDCGE.
			 *
			 * This will be set back on stream closure
			 */
			skl->enable_miscbdcge(ipc->dev, false);
			skl->miscbdcg_disabled = true;
			break;

		default:
			dev_err(ipc->dev, "ipc: Unhandled error msg=%x\n",
						header.primary);
			break;
		}
	}

	return 0;
}