drivers/net/ethernet/renesas/ravb_ptp.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/renesas/ravb_ptp.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/renesas/ravb_ptp.c
Extension
.c
Size
8485 bytes
Lines
342
Domain
Driver Families
Bucket
drivers/net
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 (start_ns > U32_MAX) {
			netdev_warn(ndev,
				    "ptp: start value (nsec) is over limit. Maximum size of start is only 32 bits\n");
			return -ERANGE;
		}

		if (period_ns > U32_MAX) {
			netdev_warn(ndev,
				    "ptp: period value (nsec) is over limit. Maximum size of period is only 32 bits\n");
			return -ERANGE;
		}

		spin_lock_irqsave(&priv->lock, flags);

		perout = &priv->ptp.perout[req->index];
		perout->target = (u32)start_ns;
		perout->period = (u32)period_ns;
		error = ravb_ptp_update_compare(priv, (u32)start_ns);
		if (!error) {
			/* Unmask interrupt */
			if (!info->irq_en_dis)
				ravb_modify(ndev, GIC, GIC_PTME, GIC_PTME);
			else
				ravb_write(ndev, GIE_PTMS0, GIE);
		}
	} else	{
		spin_lock_irqsave(&priv->lock, flags);

		perout = &priv->ptp.perout[req->index];
		perout->period = 0;

		/* Mask interrupt */
		if (!info->irq_en_dis)
			ravb_modify(ndev, GIC, GIC_PTME, 0);
		else
			ravb_write(ndev, GID_PTMD0, GID);
	}
	spin_unlock_irqrestore(&priv->lock, flags);

	return error;
}

static int ravb_ptp_enable(struct ptp_clock_info *ptp,
			   struct ptp_clock_request *req, int on)
{
	switch (req->type) {
	case PTP_CLK_REQ_EXTTS:
		return ravb_ptp_extts(ptp, &req->extts, on);
	case PTP_CLK_REQ_PEROUT:
		return ravb_ptp_perout(ptp, &req->perout, on);
	default:
		return -EOPNOTSUPP;
	}
}

static const struct ptp_clock_info ravb_ptp_info = {
	.owner		= THIS_MODULE,
	.name		= "ravb clock",
	.max_adj	= 50000000,
	.n_ext_ts	= N_EXT_TS,
	.n_per_out	= N_PER_OUT,
	.supported_extts_flags = PTP_RISING_EDGE | PTP_FALLING_EDGE,
	.adjfine	= ravb_ptp_adjfine,
	.adjtime	= ravb_ptp_adjtime,
	.gettime64	= ravb_ptp_gettime64,
	.settime64	= ravb_ptp_settime64,
	.enable		= ravb_ptp_enable,
};

/* Caller must hold the lock */
void ravb_ptp_interrupt(struct net_device *ndev)
{
	struct ravb_private *priv = netdev_priv(ndev);
	u32 gis = ravb_read(ndev, GIS);

	gis &= ravb_read(ndev, GIC);
	if (gis & GIS_PTCF) {
		struct ptp_clock_event event;

		event.type = PTP_CLOCK_EXTTS;
		event.index = 0;
		event.timestamp = ravb_read(ndev, GCPT);
		ptp_clock_event(priv->ptp.clock, &event);
	}
	if (gis & GIS_PTMF) {
		struct ravb_ptp_perout *perout = priv->ptp.perout;

		if (perout->period) {
			perout->target += perout->period;
			ravb_ptp_update_compare(priv, perout->target);

Annotation

Implementation Notes