Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757541Ab0LTLzn (ORCPT ); Mon, 20 Dec 2010 06:55:43 -0500 Received: from gate.lvk.cs.msu.su ([158.250.17.1]:56981 "EHLO mail.lvk.cs.msu.su" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757484Ab0LTLzk (ORCPT ); Mon, 20 Dec 2010 06:55:40 -0500 X-Spam-ASN: From: Alexander Gordeev To: linux-kernel@vger.kernel.org Cc: "Nikita V\. Youshchenko" , linuxpps@ml.enneenne.com, Rodolfo Giometti , Andrew Morton , Alexander Gordeev , John Stultz , Thomas Gleixner , David Howells , "H\. Peter Anvin" , Magnus Damm , Jason Wessel Subject: [PATCHv7 13/16] pps: capture MONOTONIC_RAW timestamps as well Date: Mon, 20 Dec 2010 14:54:53 +0300 Message-Id: <9ab0bd7741741a3f400c5a260a779e492db8f482.1292844387.git.lasaine@lvk.cs.msu.su> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: References: X-AV-Checked: ClamAV using ClamSMTP Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3865 Lines: 126 MONOTONIC_RAW clock timestamps are ideally suited for frequency calculation and also fit well into the original NTP hardpps design. Now phase and frequency can be adjusted separately: the former based on REALTIME clock and the latter based on MONOTONIC_RAW clock. A new function getnstime_raw_and_real is added to timekeeping subsystem to capture both timestamps at the same time and atomically. Acked-by: John Stultz Signed-off-by: Alexander Gordeev --- include/linux/pps_kernel.h | 14 ++++++++++++++ include/linux/time.h | 2 ++ kernel/time/timekeeping.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 0 deletions(-) diff --git a/include/linux/pps_kernel.h b/include/linux/pps_kernel.h index 1aedf50..9404854 100644 --- a/include/linux/pps_kernel.h +++ b/include/linux/pps_kernel.h @@ -47,6 +47,9 @@ struct pps_source_info { }; struct pps_event_time { +#ifdef CONFIG_NTP_PPS + struct timespec ts_raw; +#endif /* CONFIG_NTP_PPS */ struct timespec ts_real; }; @@ -97,10 +100,21 @@ static inline void timespec_to_pps_ktime(struct pps_ktime *kt, kt->nsec = ts.tv_nsec; } +#ifdef CONFIG_NTP_PPS + +static inline void pps_get_ts(struct pps_event_time *ts) +{ + getnstime_raw_and_real(&ts->ts_raw, &ts->ts_real); +} + +#else /* CONFIG_NTP_PPS */ + static inline void pps_get_ts(struct pps_event_time *ts) { getnstimeofday(&ts->ts_real); } +#endif /* CONFIG_NTP_PPS */ + #endif /* LINUX_PPS_KERNEL_H */ diff --git a/include/linux/time.h b/include/linux/time.h index 9f15ac7..1e6d3b5 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -158,6 +158,8 @@ extern unsigned int alarm_setitimer(unsigned int seconds); extern int do_getitimer(int which, struct itimerval *value); extern void getnstimeofday(struct timespec *tv); extern void getrawmonotonic(struct timespec *ts); +extern void getnstime_raw_and_real(struct timespec *ts_raw, + struct timespec *ts_real); extern void getboottime(struct timespec *ts); extern void monotonic_to_bootbased(struct timespec *ts); diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 49010d8..5c4be30 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -284,6 +284,49 @@ void ktime_get_ts(struct timespec *ts) } EXPORT_SYMBOL_GPL(ktime_get_ts); +#ifdef CONFIG_NTP_PPS + +/** + * getnstime_raw_and_real - get day and raw monotonic time in timespec format + * @ts_raw: pointer to the timespec to be set to raw monotonic time + * @ts_real: pointer to the timespec to be set to the time of day + * + * This function reads both the time of day and raw monotonic time at the + * same time atomically and stores the resulting timestamps in timespec + * format. + */ +void getnstime_raw_and_real(struct timespec *ts_raw, struct timespec *ts_real) +{ + unsigned long seq; + s64 nsecs_raw, nsecs_real; + + WARN_ON_ONCE(timekeeping_suspended); + + do { + u32 arch_offset; + + seq = read_seqbegin(&xtime_lock); + + *ts_raw = raw_time; + *ts_real = xtime; + + nsecs_raw = timekeeping_get_ns_raw(); + nsecs_real = timekeeping_get_ns(); + + /* If arch requires, add in gettimeoffset() */ + arch_offset = arch_gettimeoffset(); + nsecs_raw += arch_offset; + nsecs_real += arch_offset; + + } while (read_seqretry(&xtime_lock, seq)); + + timespec_add_ns(ts_raw, nsecs_raw); + timespec_add_ns(ts_real, nsecs_real); +} +EXPORT_SYMBOL(getnstime_raw_and_real); + +#endif /* CONFIG_NTP_PPS */ + /** * do_gettimeofday - Returns the time of day in a timeval * @tv: pointer to the timeval to be set -- 1.7.2.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/