.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
---|
1 | 2 | /* |
---|
2 | 3 | * PTP 1588 clock support |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2010 OMICRON electronics GmbH |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify |
---|
7 | | - * it under the terms of the GNU General Public License as published by |
---|
8 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
9 | | - * (at your option) any later version. |
---|
10 | | - * |
---|
11 | | - * This program is distributed in the hope that it will be useful, |
---|
12 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
14 | | - * GNU General Public License for more details. |
---|
15 | | - * |
---|
16 | | - * You should have received a copy of the GNU General Public License |
---|
17 | | - * along with this program; if not, write to the Free Software |
---|
18 | | - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
---|
19 | 6 | */ |
---|
20 | 7 | |
---|
21 | 8 | #ifndef _PTP_CLOCK_KERNEL_H_ |
---|
.. | .. |
---|
39 | 26 | }; |
---|
40 | 27 | |
---|
41 | 28 | struct system_device_crosststamp; |
---|
| 29 | + |
---|
42 | 30 | /** |
---|
43 | | - * struct ptp_clock_info - decribes a PTP hardware clock |
---|
| 31 | + * struct ptp_system_timestamp - system time corresponding to a PHC timestamp |
---|
| 32 | + */ |
---|
| 33 | +struct ptp_system_timestamp { |
---|
| 34 | + struct timespec64 pre_ts; |
---|
| 35 | + struct timespec64 post_ts; |
---|
| 36 | +}; |
---|
| 37 | + |
---|
| 38 | +/** |
---|
| 39 | + * struct ptp_clock_info - describes a PTP hardware clock |
---|
44 | 40 | * |
---|
45 | 41 | * @owner: The clock driver should set to THIS_MODULE. |
---|
46 | 42 | * @name: A short "friendly name" to identify the clock and to |
---|
.. | .. |
---|
69 | 65 | * parameter delta: Desired frequency offset from nominal frequency |
---|
70 | 66 | * in parts per billion |
---|
71 | 67 | * |
---|
| 68 | + * @adjphase: Adjusts the phase offset of the hardware clock. |
---|
| 69 | + * parameter delta: Desired change in nanoseconds. |
---|
| 70 | + * |
---|
72 | 71 | * @adjtime: Shifts the time of the hardware clock. |
---|
73 | 72 | * parameter delta: Desired change in nanoseconds. |
---|
74 | 73 | * |
---|
75 | 74 | * @gettime64: Reads the current time from the hardware clock. |
---|
| 75 | + * This method is deprecated. New drivers should implement |
---|
| 76 | + * the @gettimex64 method instead. |
---|
76 | 77 | * parameter ts: Holds the result. |
---|
| 78 | + * |
---|
| 79 | + * @gettimex64: Reads the current time from the hardware clock and optionally |
---|
| 80 | + * also the system clock. |
---|
| 81 | + * parameter ts: Holds the PHC timestamp. |
---|
| 82 | + * parameter sts: If not NULL, it holds a pair of timestamps from |
---|
| 83 | + * the system clock. The first reading is made right before |
---|
| 84 | + * reading the lowest bits of the PHC timestamp and the second |
---|
| 85 | + * reading immediately follows that. |
---|
77 | 86 | * |
---|
78 | 87 | * @getcrosststamp: Reads the current time from the hardware clock and |
---|
79 | 88 | * system clock simultaneously. |
---|
.. | .. |
---|
99 | 108 | * parameter func: the desired function to use. |
---|
100 | 109 | * parameter chan: the function channel index to use. |
---|
101 | 110 | * |
---|
102 | | - * @do_work: Request driver to perform auxiliary (periodic) operations |
---|
103 | | - * Driver should return delay of the next auxiliary work scheduling |
---|
104 | | - * time (>=0) or negative value in case further scheduling |
---|
105 | | - * is not required. |
---|
| 111 | + * @do_aux_work: Request driver to perform auxiliary (periodic) operations |
---|
| 112 | + * Driver should return delay of the next auxiliary work |
---|
| 113 | + * scheduling time (>=0) or negative value in case further |
---|
| 114 | + * scheduling is not required. |
---|
106 | 115 | * |
---|
107 | 116 | * Drivers should embed their ptp_clock_info within a private |
---|
108 | 117 | * structure, obtaining a reference to it using container_of(). |
---|
.. | .. |
---|
122 | 131 | struct ptp_pin_desc *pin_config; |
---|
123 | 132 | int (*adjfine)(struct ptp_clock_info *ptp, long scaled_ppm); |
---|
124 | 133 | int (*adjfreq)(struct ptp_clock_info *ptp, s32 delta); |
---|
| 134 | + int (*adjphase)(struct ptp_clock_info *ptp, s32 phase); |
---|
125 | 135 | int (*adjtime)(struct ptp_clock_info *ptp, s64 delta); |
---|
126 | 136 | int (*gettime64)(struct ptp_clock_info *ptp, struct timespec64 *ts); |
---|
| 137 | + int (*gettimex64)(struct ptp_clock_info *ptp, struct timespec64 *ts, |
---|
| 138 | + struct ptp_system_timestamp *sts); |
---|
127 | 139 | int (*getcrosststamp)(struct ptp_clock_info *ptp, |
---|
128 | 140 | struct system_device_crosststamp *cts); |
---|
129 | 141 | int (*settime64)(struct ptp_clock_info *p, const struct timespec64 *ts); |
---|
.. | .. |
---|
215 | 227 | /** |
---|
216 | 228 | * ptp_find_pin() - obtain the pin index of a given auxiliary function |
---|
217 | 229 | * |
---|
| 230 | + * The caller must hold ptp_clock::pincfg_mux. Drivers do not have |
---|
| 231 | + * access to that mutex as ptp_clock is an opaque type. However, the |
---|
| 232 | + * core code acquires the mutex before invoking the driver's |
---|
| 233 | + * ptp_clock_info::enable() callback, and so drivers may call this |
---|
| 234 | + * function from that context. |
---|
| 235 | + * |
---|
218 | 236 | * @ptp: The clock obtained from ptp_clock_register(). |
---|
219 | 237 | * @func: One of the ptp_pin_function enumerated values. |
---|
220 | 238 | * @chan: The particular functional channel to find. |
---|
.. | .. |
---|
226 | 244 | enum ptp_pin_function func, unsigned int chan); |
---|
227 | 245 | |
---|
228 | 246 | /** |
---|
| 247 | + * ptp_find_pin_unlocked() - wrapper for ptp_find_pin() |
---|
| 248 | + * |
---|
| 249 | + * This function acquires the ptp_clock::pincfg_mux mutex before |
---|
| 250 | + * invoking ptp_find_pin(). Instead of using this function, drivers |
---|
| 251 | + * should most likely call ptp_find_pin() directly from their |
---|
| 252 | + * ptp_clock_info::enable() method. |
---|
| 253 | + * |
---|
| 254 | + */ |
---|
| 255 | + |
---|
| 256 | +int ptp_find_pin_unlocked(struct ptp_clock *ptp, |
---|
| 257 | + enum ptp_pin_function func, unsigned int chan); |
---|
| 258 | + |
---|
| 259 | +/** |
---|
229 | 260 | * ptp_schedule_worker() - schedule ptp auxiliary work |
---|
230 | 261 | * |
---|
231 | 262 | * @ptp: The clock obtained from ptp_clock_register(). |
---|
.. | .. |
---|
234 | 265 | */ |
---|
235 | 266 | |
---|
236 | 267 | int ptp_schedule_worker(struct ptp_clock *ptp, unsigned long delay); |
---|
| 268 | + |
---|
| 269 | +/** |
---|
| 270 | + * ptp_cancel_worker_sync() - cancel ptp auxiliary clock |
---|
| 271 | + * |
---|
| 272 | + * @ptp: The clock obtained from ptp_clock_register(). |
---|
| 273 | + */ |
---|
| 274 | +void ptp_cancel_worker_sync(struct ptp_clock *ptp); |
---|
237 | 275 | |
---|
238 | 276 | #else |
---|
239 | 277 | static inline struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, |
---|
.. | .. |
---|
252 | 290 | static inline int ptp_schedule_worker(struct ptp_clock *ptp, |
---|
253 | 291 | unsigned long delay) |
---|
254 | 292 | { return -EOPNOTSUPP; } |
---|
| 293 | +static inline void ptp_cancel_worker_sync(struct ptp_clock *ptp) |
---|
| 294 | +{ } |
---|
255 | 295 | |
---|
256 | 296 | #endif |
---|
257 | 297 | |
---|
| 298 | +static inline void ptp_read_system_prets(struct ptp_system_timestamp *sts) |
---|
| 299 | +{ |
---|
| 300 | + if (sts) |
---|
| 301 | + ktime_get_real_ts64(&sts->pre_ts); |
---|
| 302 | +} |
---|
| 303 | + |
---|
| 304 | +static inline void ptp_read_system_postts(struct ptp_system_timestamp *sts) |
---|
| 305 | +{ |
---|
| 306 | + if (sts) |
---|
| 307 | + ktime_get_real_ts64(&sts->post_ts); |
---|
| 308 | +} |
---|
| 309 | + |
---|
258 | 310 | #endif |
---|