drivers/hwtracing/coresight/coresight-tpda.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwtracing/coresight/coresight-tpda.c
Extension
.c
Size
15644 bytes
Lines
640
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 (csdev->pdata->in_conns[i]->filter_src_fwnode) {
			in = csdev->pdata->in_conns[i]->filter_src_dev;
			if (!in)
				continue;
		}

		if (coresight_device_is_tpdm(in)) {
			if (drvdata->dsb_esize || drvdata->cmb_esize)
				return -EEXIST;
			rc = tpdm_read_element_size(drvdata, in);
			if (rc)
				return rc;
		} else {
			/* Recurse down the path */
			rc = tpda_get_element_size(drvdata, in, -1);
			if (rc)
				return rc;
		}
	}

	return rc;
}

/* Settings pre enabling port control register */
static void tpda_enable_pre_port(struct tpda_drvdata *drvdata)
{
	u32 val = 0;

	val |= FIELD_PREP(TPDA_CR_ATID, drvdata->atid);
	if (drvdata->trig_async)
		val |= TPDA_CR_SRIE;

	if (drvdata->trig_flag_ts)
		val |= TPDA_CR_FLRIE;

	if (drvdata->trig_freq)
		val |= TPDA_CR_FRIE;

	if (drvdata->freq_ts)
		val |= TPDA_CR_FREQTS;

	if (drvdata->cmbchan_mode)
		val |= TPDA_CR_CMBCHANMODE;

	writel_relaxed(val, drvdata->base + TPDA_CR);

	/*
	 * If FLRIE bit is set, set the master and channel
	 * id as zero
	 */
	if (drvdata->trig_flag_ts)
		writel_relaxed(0x0, drvdata->base + TPDA_FPID_CR);

	/* Initialize with a value of 0 */
	val = 0;
	if (drvdata->syncr_mode)
		val |= TPDA_SYNCR_MODE_CTRL_MASK;

	if (drvdata->syncr_count > 0 &&
	    drvdata->syncr_count < TPDA_SYNCR_COUNT_MASK)
		val |= drvdata->syncr_count;
	else
		/* Program the count to its MAX value by default */
		val |= TPDA_SYNCR_COUNT_MASK;

	writel_relaxed(val, drvdata->base + TPDA_SYNCR);
}

static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
{
	u32 val;
	int rc;

	val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port));
	tpda_clear_element_size(drvdata->csdev);
	rc = tpda_get_element_size(drvdata, drvdata->csdev, port);
	if (!rc && (drvdata->dsb_esize || drvdata->cmb_esize)) {
		tpda_set_element_size(drvdata, &val);
		/* Enable the port */
		val |= TPDA_Pn_CR_ENA;
		writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
	} else if (rc == -EEXIST)
		dev_warn_once(&drvdata->csdev->dev,
			      "Detected multiple TPDMs on port %d", port);
	else
		dev_warn_once(&drvdata->csdev->dev,
			      "Didn't find TPDM element size");

	return rc;
}

Annotation

Implementation Notes