I have reduced the requirements for the -p option to accept
any type of device. With this it should be possible to use
ptp4l to syncronize any clock device that implements the kernel
POSIX clock interface.

Signed-off-by: Dimitrios Katsaros <patcherw...@gmail.com>
---
 clock.c    | 11 +++++++++--
 clockadj.c | 43 +++++++++++++++++++++++++------------------
 clockadj.h |  6 ++++++
 phc.c      |  6 +++---
 phc.h      |  2 +-
 ptp4l.c    |  2 +-
 6 files changed, 45 insertions(+), 25 deletions(-)

diff --git a/clock.c b/clock.c
index 56bc79b..b74e9e5 100644
--- a/clock.c
+++ b/clock.c
@@ -979,8 +979,7 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
                phc_index = -1;
        } else if (phc_device) {
                if (1 != sscanf(phc_device, "/dev/ptp%d", &phc_index)) {
-                       pr_err("bad ptp device string");
-                       return NULL;
+                       phc_index = -1;
                }
        } else if (iface->ts_info.valid) {
                phc_index = iface->ts_info.phc_index;
@@ -1053,6 +1052,14 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
                        return NULL;
                }
                clockadj_init(c->clkid);
+       } else if (phc_device) {
+               c->clkid = phc_open(phc_device);
+               if (c->clkid == CLOCK_INVALID) {
+                       pr_err("Failed to open %s: %m", phc);
+                       return NULL;
+               }
+               max_adj = clockadj_max_freq(c->clkid);
+               clockadj_init(c->clkid);
        } else {
                c->clkid = CLOCK_REALTIME;
                c->utc_timescale = 1;
diff --git a/clockadj.c b/clockadj.c
index 86c7b33..0485d8c 100644
--- a/clockadj.c
+++ b/clockadj.c
@@ -103,6 +103,30 @@ void clockadj_step(clockid_t clkid, int64_t step)
                pr_err("failed to step clock: %m");
 }
 
+int clockadj_max_freq(clockid_t clkid)
+{
+       int f = 0;
+       struct timex tx;
+
+       memset(&tx, 0, sizeof(tx));
+       if (clock_adjtime(clkid, &tx) < 0)
+               pr_err("failed to read out the clock maximum adjustment: %m");
+       else
+               f = tx.tolerance / 65.536;
+       if (!f)
+               f = 500000;
+
+       /* The kernel allows the tick length to be adjusted up to 10%. But use
+        * it only if the overall frequency of the clock can be adjusted
+        * continuously with the tick and freq fields (i.e. hz <= 1000).
+        */
+       if (clkid == CLOCK_REALTIME && (realtime_nominal_tick && 2 * f >=
+                                       1000 * realtime_hz))
+               f = realtime_nominal_tick / 10 * 1000 * realtime_hz;
+
+       return f;
+}
+
 void sysclk_set_leap(int leap)
 {
        clockid_t clkid = CLOCK_REALTIME;
@@ -142,24 +166,7 @@ void sysclk_set_tai_offset(int offset)
 
 int sysclk_max_freq(void)
 {
-       clockid_t clkid = CLOCK_REALTIME;
-       int f = 0;
-       struct timex tx;
-       memset(&tx, 0, sizeof(tx));
-       if (clock_adjtime(clkid, &tx) < 0)
-               pr_err("failed to read out the clock maximum adjustment: %m");
-       else
-               f = tx.tolerance / 65.536;
-       if (!f)
-               f = 500000;
-
-       /* The kernel allows the tick length to be adjusted up to 10%. But use
-          it only if the overall frequency of the clock can be adjusted
-          continuously with the tick and freq fields (i.e. hz <= 1000). */
-       if (realtime_nominal_tick && 2 * f >= 1000 * realtime_hz)
-               f = realtime_nominal_tick / 10 * 1000 * realtime_hz;
-
-       return f;
+       return clockadj_max_freq(CLOCK_REALTIME);
 }
 
 void sysclk_set_sync(void)
diff --git a/clockadj.h b/clockadj.h
index 492418e..4ea98c1 100644
--- a/clockadj.h
+++ b/clockadj.h
@@ -50,6 +50,12 @@ double clockadj_get_freq(clockid_t clkid);
  */
 void clockadj_step(clockid_t clkid, int64_t step);
 
+/**
+ * Read maximum frequency adjustment of the target clock.
+ * @return The maximum frequency adjustment in parts per billion (ppb).
+ */
+int clockadj_max_freq(clockid_t clkid);
+
 /**
  * Set the system clock to insert/delete leap second at midnight.
  * @param leap  +1 to insert leap second, -1 to delete leap second,
diff --git a/phc.c b/phc.c
index 40fa6a1..9993039 100644
--- a/phc.c
+++ b/phc.c
@@ -38,10 +38,10 @@
 
 static int phc_get_caps(clockid_t clkid, struct ptp_clock_caps *caps);
 
-clockid_t phc_open(char *phc)
+clockid_t phc_open(const char *phc)
 {
        clockid_t clkid;
-       struct ptp_clock_caps caps;
+       struct timespec ts;
        int fd = open(phc, O_RDWR);
 
        if (fd < 0)
@@ -49,7 +49,7 @@ clockid_t phc_open(char *phc)
 
        clkid = FD_TO_CLOCKID(fd);
        /* check if clkid is valid */
-       if (phc_get_caps(clkid, &caps)) {
+       if (clock_gettime(clkid, &ts)) {
                close(fd);
                return CLOCK_INVALID;
        }
diff --git a/phc.h b/phc.h
index 154e35e..c0c5996 100644
--- a/phc.h
+++ b/phc.h
@@ -28,7 +28,7 @@
  *
  * @return A valid clock ID on success, CLOCK_INVALID otherwise.
  */
-clockid_t phc_open(char *phc);
+clockid_t phc_open(const char *phc);
 
 /**
  * Closes a PTP hardware clock device.
diff --git a/ptp4l.c b/ptp4l.c
index 3a9f084..17db31f 100644
--- a/ptp4l.c
+++ b/ptp4l.c
@@ -56,7 +56,7 @@ static void usage(char *progname)
                " -f [file] read configuration from 'file'\n"
                " -i [dev]  interface device to use, for example 'eth0'\n"
                "           (may be specified multiple times)\n"
-               " -p [dev]  PTP hardware clock device to use, default auto\n"
+               " -p [dev]  Clock device to use, default auto\n"
                "           (ignored for SOFTWARE/LEGACY HW time stamping)\n"
                " -s        slave only mode (overrides configuration file)\n"
                " -t        transparent clock\n"
-- 
2.17.1



_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to