Jiri Benc
2013-04-19 13:28:31 UTC
PPS output from a PHC has to be enabled by PTP_ENABLE_PPS ioctl. Call
the ioctl when both PHC device and PPS device are specified and PPS is
supported by the PHC.
Signed-off-by: Jiri Benc <***@redhat.com>
---
phc.c | 25 +++++++++++++++++++++----
phc.h | 10 ++++++++++
phc2sys.c | 17 +++++++++++++++--
3 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/phc.c b/phc.c
index de5eeb8..4b9347c 100644
--- a/phc.c
+++ b/phc.c
@@ -51,15 +51,23 @@ void phc_close(clockid_t clkid)
close(CLOCKID_TO_FD(clkid));
}
+static int phc_get_caps(clockid_t clkid, struct ptp_clock_caps *caps)
+{
+ int fd = CLOCKID_TO_FD(clkid), err;
+
+ err = ioctl(fd, PTP_CLOCK_GETCAPS, caps);
+ if (err)
+ perror("PTP_CLOCK_GETCAPS");
+ return err;
+}
+
int phc_max_adj(clockid_t clkid)
{
- int fd = CLOCKID_TO_FD(clkid), max;
+ int max;
struct ptp_clock_caps caps;
- if (ioctl(fd, PTP_CLOCK_GETCAPS, &caps)) {
- perror("PTP_CLOCK_GETCAPS");
+ if (phc_get_caps(clkid, &caps))
return 0;
- }
max = caps.max_adj;
@@ -68,3 +76,12 @@ int phc_max_adj(clockid_t clkid)
return max;
}
+
+int phc_has_pps(clockid_t clkid)
+{
+ struct ptp_clock_caps caps;
+
+ if (phc_get_caps(clkid, &caps))
+ return 0;
+ return caps.pps;
+}
diff --git a/phc.h b/phc.h
index 5eb775d..154e35e 100644
--- a/phc.h
+++ b/phc.h
@@ -46,4 +46,14 @@ void phc_close(clockid_t clkid);
*/
int phc_max_adj(clockid_t clkid);
+/**
+ * Checks whether the given PTP hardware clock device supports PPS output.
+ *
+ * @param clkid A clock ID obtained using phc_open().
+ *
+ * @return Zero if PPS output is not supported by the clock, non-zero
+ * otherwise.
+ */
+int phc_has_pps(clockid_t clkid);
+
#endif
diff --git a/phc2sys.c b/phc2sys.c
index 93495a4..7649c8a 100644
--- a/phc2sys.c
+++ b/phc2sys.c
@@ -206,6 +206,16 @@ static void update_clock(struct clock *clock,
}
}
+static void enable_pps_output(clockid_t src)
+{
+ int enable = 1;
+
+ if (!phc_has_pps(src))
+ return;
+ if (ioctl(CLOCKID_TO_FD(src), PTP_ENABLE_PPS, enable) < 0)
+ pr_warning("failed to enable PPS output");
+}
+
static int read_pps(int fd, int64_t *offset, uint64_t *ts)
{
struct pps_fdata pfd;
@@ -236,9 +246,12 @@ static int do_pps_loop(struct clock *clock, int fd,
clock->source_label = "pps";
- /* The sync offset can't be applied with PPS alone. */
- if (src == CLOCK_INVALID)
+ if (src == CLOCK_INVALID) {
+ /* The sync offset can't be applied with PPS alone. */
clock->sync_offset_direction = 0;
+ } else {
+ enable_pps_output(src);
+ }
while (1) {
if (!read_pps(fd, &pps_offset, &pps_ts)) {
the ioctl when both PHC device and PPS device are specified and PPS is
supported by the PHC.
Signed-off-by: Jiri Benc <***@redhat.com>
---
phc.c | 25 +++++++++++++++++++++----
phc.h | 10 ++++++++++
phc2sys.c | 17 +++++++++++++++--
3 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/phc.c b/phc.c
index de5eeb8..4b9347c 100644
--- a/phc.c
+++ b/phc.c
@@ -51,15 +51,23 @@ void phc_close(clockid_t clkid)
close(CLOCKID_TO_FD(clkid));
}
+static int phc_get_caps(clockid_t clkid, struct ptp_clock_caps *caps)
+{
+ int fd = CLOCKID_TO_FD(clkid), err;
+
+ err = ioctl(fd, PTP_CLOCK_GETCAPS, caps);
+ if (err)
+ perror("PTP_CLOCK_GETCAPS");
+ return err;
+}
+
int phc_max_adj(clockid_t clkid)
{
- int fd = CLOCKID_TO_FD(clkid), max;
+ int max;
struct ptp_clock_caps caps;
- if (ioctl(fd, PTP_CLOCK_GETCAPS, &caps)) {
- perror("PTP_CLOCK_GETCAPS");
+ if (phc_get_caps(clkid, &caps))
return 0;
- }
max = caps.max_adj;
@@ -68,3 +76,12 @@ int phc_max_adj(clockid_t clkid)
return max;
}
+
+int phc_has_pps(clockid_t clkid)
+{
+ struct ptp_clock_caps caps;
+
+ if (phc_get_caps(clkid, &caps))
+ return 0;
+ return caps.pps;
+}
diff --git a/phc.h b/phc.h
index 5eb775d..154e35e 100644
--- a/phc.h
+++ b/phc.h
@@ -46,4 +46,14 @@ void phc_close(clockid_t clkid);
*/
int phc_max_adj(clockid_t clkid);
+/**
+ * Checks whether the given PTP hardware clock device supports PPS output.
+ *
+ * @param clkid A clock ID obtained using phc_open().
+ *
+ * @return Zero if PPS output is not supported by the clock, non-zero
+ * otherwise.
+ */
+int phc_has_pps(clockid_t clkid);
+
#endif
diff --git a/phc2sys.c b/phc2sys.c
index 93495a4..7649c8a 100644
--- a/phc2sys.c
+++ b/phc2sys.c
@@ -206,6 +206,16 @@ static void update_clock(struct clock *clock,
}
}
+static void enable_pps_output(clockid_t src)
+{
+ int enable = 1;
+
+ if (!phc_has_pps(src))
+ return;
+ if (ioctl(CLOCKID_TO_FD(src), PTP_ENABLE_PPS, enable) < 0)
+ pr_warning("failed to enable PPS output");
+}
+
static int read_pps(int fd, int64_t *offset, uint64_t *ts)
{
struct pps_fdata pfd;
@@ -236,9 +246,12 @@ static int do_pps_loop(struct clock *clock, int fd,
clock->source_label = "pps";
- /* The sync offset can't be applied with PPS alone. */
- if (src == CLOCK_INVALID)
+ if (src == CLOCK_INVALID) {
+ /* The sync offset can't be applied with PPS alone. */
clock->sync_offset_direction = 0;
+ } else {
+ enable_pps_output(src);
+ }
while (1) {
if (!read_pps(fd, &pps_offset, &pps_ts)) {
--
1.7.6.5
1.7.6.5