| .. | .. |
|---|
| 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 |
|---|