drivers/hwtracing/coresight/coresight-tmc-etf.c

Source file repositories/reference/linux-study-clean/drivers/hwtracing/coresight/coresight-tmc-etf.c

File Facts

System
Linux kernel
Corpus path
drivers/hwtracing/coresight/coresight-tmc-etf.c
Extension
.c
Size
20066 bytes
Lines
811
Domain
Driver Families
Bucket
drivers/hwtracing
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 (coresight_get_mode(csdev) == CS_MODE_SYSFS) {
			ret = -EBUSY;
			break;
		}

		/* Get a handle on the pid of the process to monitor */
		pid = buf->pid;

		if (drvdata->pid != -1 && drvdata->pid != pid) {
			ret = -EBUSY;
			break;
		}

		ret = tmc_set_etf_buffer(csdev, handle);
		if (ret)
			break;

		/*
		 * No HW configuration is needed if the sink is already in
		 * use for this session.
		 */
		if (drvdata->pid == pid) {
			csdev->refcnt++;
			break;
		}

		ret  = tmc_etb_enable_hw(drvdata);
		if (!ret) {
			/* Associate with monitored process. */
			drvdata->pid = pid;
			coresight_set_mode(csdev, CS_MODE_PERF);
			csdev->refcnt++;
		}
	} while (0);
	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);

	return ret;
}

static int tmc_enable_etf_sink(struct coresight_device *csdev,
			       enum cs_mode mode,
			       struct coresight_path *path)
{
	int ret;

	switch (mode) {
	case CS_MODE_SYSFS:
		ret = tmc_enable_etf_sink_sysfs(csdev);
		break;
	case CS_MODE_PERF:
		ret = tmc_enable_etf_sink_perf(csdev, path);
		break;
	/* We shouldn't be here */
	default:
		ret = -EINVAL;
		break;
	}

	if (ret)
		return ret;

	dev_dbg(&csdev->dev, "TMC-ETB/ETF enabled\n");
	return 0;
}

static int tmc_disable_etf_sink(struct coresight_device *csdev)
{
	unsigned long flags;
	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);

	raw_spin_lock_irqsave(&drvdata->spinlock, flags);

	if (drvdata->reading) {
		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
		return -EBUSY;
	}

	csdev->refcnt--;
	if (csdev->refcnt) {
		raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
		return -EBUSY;
	}

	/* Complain if we (somehow) got out of sync */
	WARN_ON_ONCE(coresight_get_mode(csdev) == CS_MODE_DISABLED);
	tmc_etb_disable_hw(drvdata);
	/* Dissociate from monitored process. */
	drvdata->pid = -1;
	coresight_set_mode(csdev, CS_MODE_DISABLED);

Annotation

Implementation Notes