sound/soc/intel/catpt/ipc.c

Source file repositories/reference/linux-study-clean/sound/soc/intel/catpt/ipc.c

File Facts

System
Linux kernel
Corpus path
sound/soc/intel/catpt/ipc.c
Extension
.c
Size
7972 bytes
Lines
307
Domain
Driver Families
Bucket
sound/soc
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (catpt_readl_dram(cdev, COREDUMP) == CATPT_COREDUMP_REQUEST) {
			dev_dbg(cdev->dev, "releasing firmware from the coredump state\n");
			catpt_writel_dram(cdev, COREDUMP, CATPT_COREDUMP_RELEASE);
		}

		complete(&cdev->fw_ready);
		/* TODO: attempt recovery */
		break;

	case CATPT_GLB_STREAM_MESSAGE:
		switch (msg.stream_msg_type) {
		case CATPT_STRM_NOTIFICATION:
			catpt_dsp_notify_stream(cdev, msg);
			break;
		default:
			catpt_dsp_copy_rx(cdev, header);
			/* signal completion of delayed reply */
			complete(&ipc->busy_completion);
			break;
		}
		break;

	default:
		dev_warn(cdev->dev, "unknown response: %d received\n",
			 msg.global_msg_type);
		break;
	}
}

irqreturn_t catpt_dsp_irq_thread(int irq, void *dev_id)
{
	struct catpt_dev *cdev = dev_id;
	u32 ipcd;

	ipcd = catpt_readl_shim(cdev, IPCD);
	trace_catpt_ipc_notify(ipcd);

	/* ensure there is delayed reply or notification to process */
	if (!(ipcd & CATPT_IPCD_BUSY))
		return IRQ_NONE;

	catpt_dsp_process_response(cdev, ipcd);

	/* tell DSP processing is completed */
	catpt_updatel_shim(cdev, IPCD, CATPT_IPCD_BUSY | CATPT_IPCD_DONE,
			   CATPT_IPCD_DONE);
	/* unmask dsp BUSY interrupt */
	catpt_updatel_shim(cdev, IMC, CATPT_IMC_IPCDB, 0);

	return IRQ_HANDLED;
}

irqreturn_t catpt_dsp_irq_handler(int irq, void *dev_id)
{
	struct catpt_dev *cdev = dev_id;
	irqreturn_t ret = IRQ_NONE;
	u32 isc, ipcc;

	isc = catpt_readl_shim(cdev, ISC);
	trace_catpt_irq(isc);

	/* immediate reply */
	if (isc & CATPT_ISC_IPCCD) {
		/* mask host DONE interrupt */
		catpt_updatel_shim(cdev, IMC, CATPT_IMC_IPCCD, CATPT_IMC_IPCCD);

		ipcc = catpt_readl_shim(cdev, IPCC);
		trace_catpt_ipc_reply(ipcc);
		catpt_dsp_copy_rx(cdev, ipcc);
		complete(&cdev->ipc.done_completion);

		/* tell DSP processing is completed */
		catpt_updatel_shim(cdev, IPCC, CATPT_IPCC_DONE, 0);
		/* unmask host DONE interrupt */
		catpt_updatel_shim(cdev, IMC, CATPT_IMC_IPCCD, 0);
		ret = IRQ_HANDLED;
	}

	/* delayed reply or notification */
	if (isc & CATPT_ISC_IPCDB) {
		/* mask dsp BUSY interrupt */
		catpt_updatel_shim(cdev, IMC, CATPT_IMC_IPCDB, CATPT_IMC_IPCDB);
		ret = IRQ_WAKE_THREAD;
	}

	return ret;
}

Annotation

Implementation Notes