drivers/ptp/ptp_clock.c

Source file repositories/reference/linux-study-clean/drivers/ptp/ptp_clock.c

File Facts

System
Linux kernel
Corpus path
drivers/ptp/ptp_clock.c
Extension
.c
Size
17312 bytes
Lines
712
Domain
Driver Families
Bucket
drivers/ptp
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 ptp_n_perout_loopback_fops = {
	.owner	= THIS_MODULE,
	.open	= simple_open,
	.read	= ptp_n_perout_loopback_read,
};

static ssize_t ptp_perout_loopback_write(struct file *filep,
					 const char __user *buffer,
					 size_t count, loff_t *ppos)
{
	struct ptp_clock *ptp = filep->private_data;
	struct ptp_clock_info *ops = ptp->info;
	unsigned int index, enable;
	int len, cnt, err;
	char buf[32] = {};

	if (*ppos || !count)
		return -EINVAL;

	if (count >= sizeof(buf))
		return -ENOSPC;

	len = simple_write_to_buffer(buf, sizeof(buf) - 1,
				     ppos, buffer, count);
	if (len < 0)
		return len;

	buf[len] = '\0';
	cnt = sscanf(buf, "%u %u", &index, &enable);
	if (cnt != 2)
		return -EINVAL;

	if (index >= ops->n_per_lp)
		return -EINVAL;

	if (enable != 0 && enable != 1)
		return -EINVAL;

	err = ops->perout_loopback(ops, index, enable);
	if (err)
		return err;

	return count;
}

static const struct file_operations ptp_perout_loopback_ops = {
	.owner   = THIS_MODULE,
	.open    = simple_open,
	.write	 = ptp_perout_loopback_write,
};

/* public interface */

struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
				     struct device *parent)
{
	struct ptp_clock *ptp;
	struct timestamp_event_queue *queue = NULL;
	int err, index, major = MAJOR(ptp_devt);
	char debugfsname[16];
	size_t size;

	if (WARN_ON_ONCE(info->n_alarm > PTP_MAX_ALARMS ||
			 (!info->gettimex64 && !info->gettime64) ||
			 !info->settime64))
		return ERR_PTR(-EINVAL);

	/* Initialize a clock structure. */
	ptp = kzalloc_obj(struct ptp_clock);
	if (!ptp) {
		err = -ENOMEM;
		goto no_memory;
	}

	err = xa_alloc(&ptp_clocks_map, &index, ptp, xa_limit_31b,
		       GFP_KERNEL);
	if (err)
		goto no_slot;

	ptp->clock.ops = ptp_clock_ops;
	ptp->info = info;
	ptp->devid = MKDEV(major, index);
	ptp->index = index;
	INIT_LIST_HEAD(&ptp->tsevqs);
	queue = kzalloc_obj(*queue);
	if (!queue) {
		err = -ENOMEM;
		goto no_memory_queue;
	}
	list_add_tail(&queue->qlist, &ptp->tsevqs);

Annotation

Implementation Notes