drivers/hwtracing/intel_th/msu.c

Source file repositories/reference/linux-study-clean/drivers/hwtracing/intel_th/msu.c

File Facts

System
Linux kernel
Corpus path
drivers/hwtracing/intel_th/msu.c
Extension
.c
Size
50317 bytes
Lines
2205
Domain
Driver Families
Bucket
drivers/hwtracing
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct file_operations intel_th_msc_fops = {
	.open		= intel_th_msc_open,
	.release	= intel_th_msc_release,
	.read		= intel_th_msc_read,
	.mmap		= intel_th_msc_mmap,
	.owner		= THIS_MODULE,
};

static void intel_th_msc_wait_empty(struct intel_th_device *thdev)
{
	struct msc *msc = dev_get_drvdata(&thdev->dev);
	unsigned long count;
	u32 reg;

	for (reg = 0, count = MSC_PLE_WAITLOOP_DEPTH;
	     count && !(reg & MSCSTS_PLE); count--) {
		reg = __raw_readl(msc->reg_base + REG_MSU_MSC0STS);
		cpu_relax();
	}

	if (!count)
		dev_dbg(msc_dev(msc), "timeout waiting for MSC0 PLE\n");
}

static int intel_th_msc_init(struct msc *msc)
{
	atomic_set(&msc->user_count, -1);

	msc->mode = msc->multi_is_broken ? MSC_MODE_SINGLE : MSC_MODE_MULTI;
	mutex_init(&msc->buf_mutex);
	INIT_LIST_HEAD(&msc->win_list);
	INIT_LIST_HEAD(&msc->iter_list);

	msc->burst_len =
		(ioread32(msc->reg_base + REG_MSU_MSC0CTL) & MSC_LEN) >>
		__ffs(MSC_LEN);

	return 0;
}

static int msc_win_switch(struct msc *msc)
{
	struct msc_window *first;

	if (list_empty(&msc->win_list))
		return -EINVAL;

	first = list_first_entry(&msc->win_list, struct msc_window, entry);

	if (msc_is_last_win(msc->cur_win))
		msc->cur_win = first;
	else
		msc->cur_win = list_next_entry(msc->cur_win, entry);

	msc->base = msc_win_base(msc->cur_win);
	msc->base_addr = msc_win_base_dma(msc->cur_win);

	intel_th_trace_switch(msc->thdev);

	return 0;
}

/**
 * intel_th_msc_window_unlock - put the window back in rotation
 * @dev:	MSC device to which this relates
 * @sgt:	buffer's sg_table for the window, does nothing if NULL
 */
void intel_th_msc_window_unlock(struct device *dev, struct sg_table *sgt)
{
	struct msc *msc = dev_get_drvdata(dev);
	struct msc_window *win;

	if (!sgt)
		return;

	win = msc_find_window(msc, sgt, false);
	if (!win)
		return;

	msc_win_set_lockout(win, WIN_LOCKED, WIN_READY);
	if (msc->switch_on_unlock == win) {
		msc->switch_on_unlock = NULL;
		msc_win_switch(msc);
	}
}
EXPORT_SYMBOL_GPL(intel_th_msc_window_unlock);

static void msc_work(struct work_struct *work)
{
	struct msc *msc = container_of(work, struct msc, work);

Annotation

Implementation Notes