drivers/ptp/ptp_sysfs.c

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

File Facts

System
Linux kernel
Corpus path
drivers/ptp/ptp_sysfs.c
Extension
.c
Size
11467 bytes
Lines
482
Domain
Driver Families
Bucket
drivers/ptp
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

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * PTP 1588 clock support - sysfs interface.
 *
 * Copyright (C) 2010 OMICRON electronics GmbH
 * Copyright 2021 NXP
 */
#include <linux/capability.h>
#include <linux/slab.h>

#include "ptp_private.h"

static ssize_t clock_name_show(struct device *dev,
			       struct device_attribute *attr, char *page)
{
	struct ptp_clock *ptp = dev_get_drvdata(dev);
	return sysfs_emit(page, "%s\n", ptp->info->name);
}
static DEVICE_ATTR_RO(clock_name);

static ssize_t max_phase_adjustment_show(struct device *dev,
					 struct device_attribute *attr,
					 char *page)
{
	struct ptp_clock *ptp = dev_get_drvdata(dev);

	return sysfs_emit(page, "%d\n", ptp->info->getmaxphase(ptp->info));
}
static DEVICE_ATTR_RO(max_phase_adjustment);

#define PTP_SHOW_INT(name, var)						\
static ssize_t var##_show(struct device *dev,				\
			   struct device_attribute *attr, char *page)	\
{									\
	struct ptp_clock *ptp = dev_get_drvdata(dev);			\
	return sysfs_emit(page, "%d\n", ptp->info->var);	\
}									\
static DEVICE_ATTR(name, 0444, var##_show, NULL);

PTP_SHOW_INT(max_adjustment, max_adj);
PTP_SHOW_INT(n_alarms, n_alarm);
PTP_SHOW_INT(n_external_timestamps, n_ext_ts);
PTP_SHOW_INT(n_periodic_outputs, n_per_out);
PTP_SHOW_INT(n_programmable_pins, n_pins);
PTP_SHOW_INT(pps_available, pps);

static ssize_t extts_enable_store(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf, size_t count)
{
	struct ptp_clock *ptp = dev_get_drvdata(dev);
	struct ptp_clock_info *ops = ptp->info;
	struct ptp_clock_request req = { .type = PTP_CLK_REQ_EXTTS };
	int cnt, enable;
	int err = -EINVAL;

	cnt = sscanf(buf, "%u %d", &req.extts.index, &enable);
	if (cnt != 2)
		goto out;
	if (req.extts.index >= ops->n_ext_ts)
		goto out;

	err = ops->enable(ops, &req, enable ? 1 : 0);
	if (err)
		goto out;

	return count;
out:
	return err;
}
static DEVICE_ATTR(extts_enable, 0220, NULL, extts_enable_store);

static ssize_t extts_fifo_show(struct device *dev,
			       struct device_attribute *attr, char *page)
{
	struct ptp_clock *ptp = dev_get_drvdata(dev);
	struct timestamp_event_queue *queue;
	struct ptp_extts_event event;
	unsigned long flags;
	size_t qcnt;
	int cnt = 0;

	cnt = list_count_nodes(&ptp->tsevqs);
	if (cnt <= 0)
		goto out;

	/* The sysfs fifo will always draw from the fist queue */
	queue = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue,
				 qlist);

Annotation

Implementation Notes