drivers/net/ethernet/ti/icssg/icss_iep.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/ti/icssg/icss_iep.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/ti/icssg/icss_iep.c
Extension
.c
Size
29579 bytes
Lines
1108
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (ret) {
			dev_info(iep->dev, "cap_cmp irq request failed: %x\n",
				 ret);
		} else {
			iep->cap_cmp_irq = irq;
			INIT_WORK(&iep->work, icss_iep_cap_cmp_work);
		}
	}

	iep_clk = devm_clk_get(dev, NULL);
	if (IS_ERR(iep_clk))
		return PTR_ERR(iep_clk);

	iep->refclk_freq = clk_get_rate(iep_clk);

	iep->def_inc = NSEC_PER_SEC / iep->refclk_freq;	/* ns per clock tick */
	if (iep->def_inc > IEP_MAX_DEF_INC) {
		dev_err(dev, "Failed to set def_inc %d.  IEP_clock is too slow to be supported\n",
			iep->def_inc);
		return -EINVAL;
	}

	iep->plat_data = device_get_match_data(dev);
	if (!iep->plat_data)
		return -EINVAL;

	iep->map = devm_regmap_init(dev, NULL, iep, iep->plat_data->config);
	if (IS_ERR(iep->map)) {
		dev_err(dev, "Failed to create regmap for IEP %ld\n",
			PTR_ERR(iep->map));
		return PTR_ERR(iep->map);
	}

	iep->ptp_info = icss_iep_ptp_info;
	mutex_init(&iep->ptp_clk_mutex);
	dev_set_drvdata(dev, iep);
	icss_iep_disable(iep);

	return 0;
}

static bool am654_icss_iep_valid_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case ICSS_IEP_GLOBAL_CFG_REG ... ICSS_IEP_SYNC_START_REG:
		return true;
	default:
		return false;
	}

	return false;
}

static int icss_iep_regmap_write(void *context, unsigned int reg,
				 unsigned int val)
{
	struct icss_iep *iep = context;

	writel(val, iep->base + iep->plat_data->reg_offs[reg]);

	return 0;
}

static int icss_iep_regmap_read(void *context, unsigned int reg,
				unsigned int *val)
{
	struct icss_iep *iep = context;

	*val = readl(iep->base + iep->plat_data->reg_offs[reg]);

	return 0;
}

static const struct regmap_config am654_icss_iep_regmap_config = {
	.name = "icss iep",
	.reg_stride = 1,
	.reg_write = icss_iep_regmap_write,
	.reg_read = icss_iep_regmap_read,
	.writeable_reg = am654_icss_iep_valid_reg,
	.readable_reg = am654_icss_iep_valid_reg,
	.fast_io = 1,
};

static const struct icss_iep_plat_data am654_icss_iep_plat_data = {
	.flags = ICSS_IEP_64BIT_COUNTER_SUPPORT |
		 ICSS_IEP_SLOW_COMPEN_REG_SUPPORT |
		 ICSS_IEP_SHADOW_MODE_SUPPORT,
	.reg_offs = {
		[ICSS_IEP_GLOBAL_CFG_REG] = 0x00,
		[ICSS_IEP_COMPEN_REG] = 0x08,

Annotation

Implementation Notes