path: root/sys/sys/clock.h
diff options
authorIan Lepore <ian@FreeBSD.org>2017-07-12 02:53:54 +0000
committerIan Lepore <ian@FreeBSD.org>2017-07-12 02:53:54 +0000
commita8d7b9d3bbcad38e9c99a3ef65da4f0ead955a42 (patch)
tree2729ca4bf9cbb146d38198783309e4d1152e6abc /sys/sys/clock.h
parentb524a31593fba5f2b49b220461450bab47459b18 (diff)
Support multiple realtime clocks, and remove locking/sleeping restrictions
on clock drivers. This tracks multiple concurrent realtime clock drivers in a list sorted by clock resolution. When system time changes (and periodically) the clock_settime() methods of all registered clocks are invoked. To initialize system time, each driver is tried in turn from best to worst resolution, until one succesfully returns a valid time. The code no longer holds a mutex while calling the clock_settime() and clock_gettime() methods of the registered clocks. This allows clock drivers to do whatever kind of locking or sleeping is necessary (this is especially important for i2c clock chips since i2c drivers often need to sleep). A new clock_register_flags() function allows the clock driver to pass flags. The flags currently defined help support drivers that use their own techniques to avoid roundoff errors (prevents the 4/5 rounding done by the subr_rtc code). A driver which may need to wait for resources (such as bus ownership) may pass a flag to indicate that it will obtain system time for itself after waiting for resources; this is merely an optimization to avoid the common code retrieving a timespec that will never get used. Relnotes: yes Differential Revision: https://reviews.freebsd.org/D11484
Notes: svn path=/head/; revision=320902
Diffstat (limited to 'sys/sys/clock.h')
1 files changed, 28 insertions, 2 deletions
diff --git a/sys/sys/clock.h b/sys/sys/clock.h
index f1809dbb9527..696ff55eee14 100644
--- a/sys/sys/clock.h
+++ b/sys/sys/clock.h
@@ -54,7 +54,6 @@
extern int tz_minuteswest;
extern int tz_dsttime;
-extern struct mtx resettodr_lock;
int utc_offset(void);
@@ -76,7 +75,34 @@ struct clocktime {
int clock_ct_to_ts(struct clocktime *, struct timespec *);
void clock_ts_to_ct(struct timespec *, struct clocktime *);
-void clock_register(device_t, long);
+ * Time-of-day clock register/unregister functions, and associated flags. These
+ * functions can sleep. Upon return from unregister, the clock's methods are
+ * not running and will not be called again.
+ *
+ * Flags:
+ *
+ * Do not pass a timespec to clock_settime(), the driver obtains its own time
+ * and applies its own adjustments (this flag implies CLOCKF_SETTIME_NO_ADJ).
+ *
+ * Do not apply utc offset and resolution/accuracy adjustments to the value
+ * passed to clock_settime(), the driver applies them itself.
+ *
+ * Do not apply utc offset and resolution/accuracy adjustments to the value
+ * returned from clock_gettime(), the driver has already applied them.
+ */
+#define CLOCKF_SETTIME_NO_TS 0x00000001
+#define CLOCKF_SETTIME_NO_ADJ 0x00000002
+#define CLOCKF_GETTIME_NO_ADJ 0x00000004
+void clock_register(device_t _clockdev, long _resolution_us);
+void clock_register_flags(device_t _clockdev, long _resolution_us, int _flags);
+void clock_unregister(device_t _clockdev);
* BCD to decimal and decimal to BCD.