| 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ | 
|---|
| 2 | /* | 
|---|
| 3 | * PTP 1588 clock support | 
|---|
| 4 | * | 
|---|
| 5 | * Copyright (C) 2010 OMICRON electronics GmbH | 
|---|
| 6 | */ | 
|---|
| 7 |  | 
|---|
| 8 | #ifndef _PTP_CLOCK_KERNEL_H_ | 
|---|
| 9 | #define _PTP_CLOCK_KERNEL_H_ | 
|---|
| 10 |  | 
|---|
| 11 | #include <linux/device.h> | 
|---|
| 12 | #include <linux/pps_kernel.h> | 
|---|
| 13 | #include <linux/ptp_clock.h> | 
|---|
| 14 | #include <linux/timecounter.h> | 
|---|
| 15 | #include <linux/skbuff.h> | 
|---|
| 16 |  | 
|---|
| 17 | #define PTP_CLOCK_NAME_LEN	32 | 
|---|
| 18 | /** | 
|---|
| 19 | * struct ptp_clock_request - request PTP clock event | 
|---|
| 20 | * | 
|---|
| 21 | * @type:   The type of the request. | 
|---|
| 22 | *	    EXTTS:  Configure external trigger timestamping | 
|---|
| 23 | *	    PEROUT: Configure periodic output signal (e.g. PPS) | 
|---|
| 24 | *	    PPS:    trigger internal PPS event for input | 
|---|
| 25 | *	            into kernel PPS subsystem | 
|---|
| 26 | * @extts:  describes configuration for external trigger timestamping. | 
|---|
| 27 | *          This is only valid when event == PTP_CLK_REQ_EXTTS. | 
|---|
| 28 | * @perout: describes configuration for periodic output. | 
|---|
| 29 | *	    This is only valid when event == PTP_CLK_REQ_PEROUT. | 
|---|
| 30 | */ | 
|---|
| 31 |  | 
|---|
| 32 | struct ptp_clock_request { | 
|---|
| 33 | enum { | 
|---|
| 34 | PTP_CLK_REQ_EXTTS, | 
|---|
| 35 | PTP_CLK_REQ_PEROUT, | 
|---|
| 36 | PTP_CLK_REQ_PPS, | 
|---|
| 37 | } type; | 
|---|
| 38 | union { | 
|---|
| 39 | struct ptp_extts_request extts; | 
|---|
| 40 | struct ptp_perout_request perout; | 
|---|
| 41 | }; | 
|---|
| 42 | }; | 
|---|
| 43 |  | 
|---|
| 44 | struct system_device_crosststamp; | 
|---|
| 45 |  | 
|---|
| 46 | /** | 
|---|
| 47 | * struct ptp_system_timestamp - system time corresponding to a PHC timestamp | 
|---|
| 48 | * @pre_ts: system timestamp before capturing PHC | 
|---|
| 49 | * @post_ts: system timestamp after capturing PHC | 
|---|
| 50 | * @clockid: clock-base used for capturing the system timestamps | 
|---|
| 51 | */ | 
|---|
| 52 | struct ptp_system_timestamp { | 
|---|
| 53 | struct timespec64 pre_ts; | 
|---|
| 54 | struct timespec64 post_ts; | 
|---|
| 55 | clockid_t clockid; | 
|---|
| 56 | }; | 
|---|
| 57 |  | 
|---|
| 58 | /** | 
|---|
| 59 | * struct ptp_clock_info - describes a PTP hardware clock | 
|---|
| 60 | * | 
|---|
| 61 | * @owner:     The clock driver should set to THIS_MODULE. | 
|---|
| 62 | * @name:      A short "friendly name" to identify the clock and to | 
|---|
| 63 | *             help distinguish PHY based devices from MAC based ones. | 
|---|
| 64 | *             The string is not meant to be a unique id. | 
|---|
| 65 | * @max_adj:   The maximum possible frequency adjustment, in parts per billon. | 
|---|
| 66 | * @n_alarm:   The number of programmable alarms. | 
|---|
| 67 | * @n_ext_ts:  The number of external time stamp channels. | 
|---|
| 68 | * @n_per_out: The number of programmable periodic signals. | 
|---|
| 69 | * @n_pins:    The number of programmable pins. | 
|---|
| 70 | * @n_per_lp:  The number of channels that support loopback the periodic | 
|---|
| 71 | *             output signal. | 
|---|
| 72 | * @pps:       Indicates whether the clock supports a PPS callback. | 
|---|
| 73 | * | 
|---|
| 74 | * @supported_perout_flags:  The set of flags the driver supports for the | 
|---|
| 75 | *                           PTP_PEROUT_REQUEST ioctl. The PTP core will | 
|---|
| 76 | *                           reject a request with any flag not specified | 
|---|
| 77 | *                           here. | 
|---|
| 78 | * | 
|---|
| 79 | * @supported_extts_flags:  The set of flags the driver supports for the | 
|---|
| 80 | *                          PTP_EXTTS_REQUEST ioctl. The PTP core will use | 
|---|
| 81 | *                          this list to reject unsupported requests. | 
|---|
| 82 | *                          PTP_ENABLE_FEATURE is assumed and does not need to | 
|---|
| 83 | *                          be included. If PTP_STRICT_FLAGS is *not* set, | 
|---|
| 84 | *                          then both PTP_RISING_EDGE and PTP_FALLING_EDGE | 
|---|
| 85 | *                          will be assumed. Note that PTP_STRICT_FLAGS must | 
|---|
| 86 | *                          be set if the drivers wants to honor | 
|---|
| 87 | *                          PTP_EXTTS_REQUEST2 and any future flags. | 
|---|
| 88 | * | 
|---|
| 89 | * @pin_config: Array of length 'n_pins'. If the number of | 
|---|
| 90 | *              programmable pins is nonzero, then drivers must | 
|---|
| 91 | *              allocate and initialize this array. | 
|---|
| 92 | * | 
|---|
| 93 | * clock operations | 
|---|
| 94 | * | 
|---|
| 95 | * @adjfine:  Adjusts the frequency of the hardware clock. | 
|---|
| 96 | *            parameter scaled_ppm: Desired frequency offset from | 
|---|
| 97 | *            nominal frequency in parts per million, but with a | 
|---|
| 98 | *            16 bit binary fractional field. | 
|---|
| 99 | * | 
|---|
| 100 | * @adjphase:  Indicates that the PHC should use an internal servo | 
|---|
| 101 | *             algorithm to correct the provided phase offset. | 
|---|
| 102 | *             parameter delta: PHC servo phase adjustment target | 
|---|
| 103 | *                              in nanoseconds. | 
|---|
| 104 | * | 
|---|
| 105 | * @getmaxphase:  Advertises maximum offset that can be provided | 
|---|
| 106 | *                to the hardware clock's phase control functionality | 
|---|
| 107 | *                through adjphase. | 
|---|
| 108 | * | 
|---|
| 109 | * @adjtime:  Shifts the time of the hardware clock. | 
|---|
| 110 | *            parameter delta: Desired change in nanoseconds. | 
|---|
| 111 | * | 
|---|
| 112 | * @gettime64:  Reads the current time from the hardware clock. | 
|---|
| 113 | *              This method is deprecated.  New drivers should implement | 
|---|
| 114 | *              the @gettimex64 method instead. | 
|---|
| 115 | *              parameter ts: Holds the result. | 
|---|
| 116 | * | 
|---|
| 117 | * @gettimex64:  Reads the current time from the hardware clock and optionally | 
|---|
| 118 | *               also the system clock. | 
|---|
| 119 | *               parameter ts: Holds the PHC timestamp. | 
|---|
| 120 | *               parameter sts: If not NULL, it holds a pair of timestamps from | 
|---|
| 121 | *               the system clock. The first reading is made right before | 
|---|
| 122 | *               reading the lowest bits of the PHC timestamp and the second | 
|---|
| 123 | *               reading immediately follows that. | 
|---|
| 124 | * | 
|---|
| 125 | * @getcrosststamp:  Reads the current time from the hardware clock and | 
|---|
| 126 | *                   system clock simultaneously. | 
|---|
| 127 | *                   parameter cts: Contains timestamp (device,system) pair, | 
|---|
| 128 | *                   where system time is realtime and monotonic. | 
|---|
| 129 | * | 
|---|
| 130 | * @settime64:  Set the current time on the hardware clock. | 
|---|
| 131 | *              parameter ts: Time value to set. | 
|---|
| 132 | * | 
|---|
| 133 | * @getcycles64:  Reads the current free running cycle counter from the hardware | 
|---|
| 134 | *                clock. | 
|---|
| 135 | *                If @getcycles64 and @getcyclesx64 are not supported, then | 
|---|
| 136 | *                @gettime64 or @gettimex64 will be used as default | 
|---|
| 137 | *                implementation. | 
|---|
| 138 | *                parameter ts: Holds the result. | 
|---|
| 139 | * | 
|---|
| 140 | * @getcyclesx64:  Reads the current free running cycle counter from the | 
|---|
| 141 | *                 hardware clock and optionally also the system clock. | 
|---|
| 142 | *                 If @getcycles64 and @getcyclesx64 are not supported, then | 
|---|
| 143 | *                 @gettimex64 will be used as default implementation if | 
|---|
| 144 | *                 available. | 
|---|
| 145 | *                 parameter ts: Holds the PHC timestamp. | 
|---|
| 146 | *                 parameter sts: If not NULL, it holds a pair of timestamps | 
|---|
| 147 | *                 from the system clock. The first reading is made right before | 
|---|
| 148 | *                 reading the lowest bits of the PHC timestamp and the second | 
|---|
| 149 | *                 reading immediately follows that. | 
|---|
| 150 | * | 
|---|
| 151 | * @getcrosscycles:  Reads the current free running cycle counter from the | 
|---|
| 152 | *                   hardware clock and system clock simultaneously. | 
|---|
| 153 | *                   If @getcycles64 and @getcyclesx64 are not supported, then | 
|---|
| 154 | *                   @getcrosststamp will be used as default implementation if | 
|---|
| 155 | *                   available. | 
|---|
| 156 | *                   parameter cts: Contains timestamp (device,system) pair, | 
|---|
| 157 | *                   where system time is realtime and monotonic. | 
|---|
| 158 | * | 
|---|
| 159 | * @enable:   Request driver to enable or disable an ancillary feature. | 
|---|
| 160 | *            parameter request: Desired resource to enable or disable. | 
|---|
| 161 | *            parameter on: Caller passes one to enable or zero to disable. | 
|---|
| 162 | * | 
|---|
| 163 | * @verify:   Confirm that a pin can perform a given function. The PTP | 
|---|
| 164 | *            Hardware Clock subsystem maintains the 'pin_config' | 
|---|
| 165 | *            array on behalf of the drivers, but the PHC subsystem | 
|---|
| 166 | *            assumes that every pin can perform every function. This | 
|---|
| 167 | *            hook gives drivers a way of telling the core about | 
|---|
| 168 | *            limitations on specific pins. This function must return | 
|---|
| 169 | *            zero if the function can be assigned to this pin, and | 
|---|
| 170 | *            nonzero otherwise. | 
|---|
| 171 | *            parameter pin: index of the pin in question. | 
|---|
| 172 | *            parameter func: the desired function to use. | 
|---|
| 173 | *            parameter chan: the function channel index to use. | 
|---|
| 174 | * | 
|---|
| 175 | * @do_aux_work:  Request driver to perform auxiliary (periodic) operations | 
|---|
| 176 | *                Driver should return delay of the next auxiliary work | 
|---|
| 177 | *                scheduling time (>=0) or negative value in case further | 
|---|
| 178 | *                scheduling is not required. | 
|---|
| 179 | * | 
|---|
| 180 | * @perout_loopback: Request driver to enable or disable the periodic output | 
|---|
| 181 | *                   signal loopback. | 
|---|
| 182 | *                   parameter index: index of the periodic output signal channel. | 
|---|
| 183 | *                   parameter on: caller passes one to enable or zero to disable. | 
|---|
| 184 | * | 
|---|
| 185 | * Drivers should embed their ptp_clock_info within a private | 
|---|
| 186 | * structure, obtaining a reference to it using container_of(). | 
|---|
| 187 | * | 
|---|
| 188 | * The callbacks must all return zero on success, non-zero otherwise. | 
|---|
| 189 | */ | 
|---|
| 190 |  | 
|---|
| 191 | struct ptp_clock_info { | 
|---|
| 192 | struct module *owner; | 
|---|
| 193 | char name[PTP_CLOCK_NAME_LEN]; | 
|---|
| 194 | s32 max_adj; | 
|---|
| 195 | int n_alarm; | 
|---|
| 196 | int n_ext_ts; | 
|---|
| 197 | int n_per_out; | 
|---|
| 198 | int n_pins; | 
|---|
| 199 | int n_per_lp; | 
|---|
| 200 | int pps; | 
|---|
| 201 | unsigned int supported_perout_flags; | 
|---|
| 202 | unsigned int supported_extts_flags; | 
|---|
| 203 | struct ptp_pin_desc *pin_config; | 
|---|
| 204 | int (*adjfine)(struct ptp_clock_info *ptp, long scaled_ppm); | 
|---|
| 205 | int (*adjphase)(struct ptp_clock_info *ptp, s32 phase); | 
|---|
| 206 | s32 (*getmaxphase)(struct ptp_clock_info *ptp); | 
|---|
| 207 | int (*adjtime)(struct ptp_clock_info *ptp, s64 delta); | 
|---|
| 208 | int (*gettime64)(struct ptp_clock_info *ptp, struct timespec64 *ts); | 
|---|
| 209 | int (*gettimex64)(struct ptp_clock_info *ptp, struct timespec64 *ts, | 
|---|
| 210 | struct ptp_system_timestamp *sts); | 
|---|
| 211 | int (*getcrosststamp)(struct ptp_clock_info *ptp, | 
|---|
| 212 | struct system_device_crosststamp *cts); | 
|---|
| 213 | int (*settime64)(struct ptp_clock_info *p, const struct timespec64 *ts); | 
|---|
| 214 | int (*getcycles64)(struct ptp_clock_info *ptp, struct timespec64 *ts); | 
|---|
| 215 | int (*getcyclesx64)(struct ptp_clock_info *ptp, struct timespec64 *ts, | 
|---|
| 216 | struct ptp_system_timestamp *sts); | 
|---|
| 217 | int (*getcrosscycles)(struct ptp_clock_info *ptp, | 
|---|
| 218 | struct system_device_crosststamp *cts); | 
|---|
| 219 | int (*enable)(struct ptp_clock_info *ptp, | 
|---|
| 220 | struct ptp_clock_request *request, int on); | 
|---|
| 221 | int (*verify)(struct ptp_clock_info *ptp, unsigned int pin, | 
|---|
| 222 | enum ptp_pin_function func, unsigned int chan); | 
|---|
| 223 | long (*do_aux_work)(struct ptp_clock_info *ptp); | 
|---|
| 224 | int (*perout_loopback)(struct ptp_clock_info *ptp, unsigned int index, | 
|---|
| 225 | int on); | 
|---|
| 226 | }; | 
|---|
| 227 |  | 
|---|
| 228 | struct ptp_clock; | 
|---|
| 229 |  | 
|---|
| 230 | enum ptp_clock_events { | 
|---|
| 231 | PTP_CLOCK_ALARM, | 
|---|
| 232 | PTP_CLOCK_EXTTS, | 
|---|
| 233 | PTP_CLOCK_EXTOFF, | 
|---|
| 234 | PTP_CLOCK_PPS, | 
|---|
| 235 | PTP_CLOCK_PPSUSR, | 
|---|
| 236 | }; | 
|---|
| 237 |  | 
|---|
| 238 | /** | 
|---|
| 239 | * struct ptp_clock_event - decribes a PTP hardware clock event | 
|---|
| 240 | * | 
|---|
| 241 | * @type:  One of the ptp_clock_events enumeration values. | 
|---|
| 242 | * @index: Identifies the source of the event. | 
|---|
| 243 | * @timestamp: When the event occurred (%PTP_CLOCK_EXTTS only). | 
|---|
| 244 | * @offset:    When the event occurred (%PTP_CLOCK_EXTOFF only). | 
|---|
| 245 | * @pps_times: When the event occurred (%PTP_CLOCK_PPSUSR only). | 
|---|
| 246 | */ | 
|---|
| 247 |  | 
|---|
| 248 | struct ptp_clock_event { | 
|---|
| 249 | int type; | 
|---|
| 250 | int index; | 
|---|
| 251 | union { | 
|---|
| 252 | u64 timestamp; | 
|---|
| 253 | s64 offset; | 
|---|
| 254 | struct pps_event_time pps_times; | 
|---|
| 255 | }; | 
|---|
| 256 | }; | 
|---|
| 257 |  | 
|---|
| 258 | /** | 
|---|
| 259 | * scaled_ppm_to_ppb() - convert scaled ppm to ppb | 
|---|
| 260 | * | 
|---|
| 261 | * @ppm:    Parts per million, but with a 16 bit binary fractional field | 
|---|
| 262 | */ | 
|---|
| 263 | static inline long scaled_ppm_to_ppb(long ppm) | 
|---|
| 264 | { | 
|---|
| 265 | /* | 
|---|
| 266 | * The 'freq' field in the 'struct timex' is in parts per | 
|---|
| 267 | * million, but with a 16 bit binary fractional field. | 
|---|
| 268 | * | 
|---|
| 269 | * We want to calculate | 
|---|
| 270 | * | 
|---|
| 271 | *    ppb = scaled_ppm * 1000 / 2^16 | 
|---|
| 272 | * | 
|---|
| 273 | * which simplifies to | 
|---|
| 274 | * | 
|---|
| 275 | *    ppb = scaled_ppm * 125 / 2^13 | 
|---|
| 276 | */ | 
|---|
| 277 | s64 ppb = 1 + ppm; | 
|---|
| 278 |  | 
|---|
| 279 | ppb *= 125; | 
|---|
| 280 | ppb >>= 13; | 
|---|
| 281 | return (long)ppb; | 
|---|
| 282 | } | 
|---|
| 283 |  | 
|---|
| 284 | /** | 
|---|
| 285 | * diff_by_scaled_ppm - Calculate difference using scaled ppm | 
|---|
| 286 | * @base: the base increment value to adjust | 
|---|
| 287 | * @scaled_ppm: scaled parts per million to adjust by | 
|---|
| 288 | * @diff: on return, the absolute value of calculated diff | 
|---|
| 289 | * | 
|---|
| 290 | * Calculate the difference to adjust the base increment using scaled parts | 
|---|
| 291 | * per million. | 
|---|
| 292 | * | 
|---|
| 293 | * Use mul_u64_u64_div_u64 to perform the difference calculation in avoid | 
|---|
| 294 | * possible overflow. | 
|---|
| 295 | * | 
|---|
| 296 | * Returns: true if scaled_ppm is negative, false otherwise | 
|---|
| 297 | */ | 
|---|
| 298 | static inline bool diff_by_scaled_ppm(u64 base, long scaled_ppm, u64 *diff) | 
|---|
| 299 | { | 
|---|
| 300 | bool negative = false; | 
|---|
| 301 |  | 
|---|
| 302 | if (scaled_ppm < 0) { | 
|---|
| 303 | negative = true; | 
|---|
| 304 | scaled_ppm = -scaled_ppm; | 
|---|
| 305 | } | 
|---|
| 306 |  | 
|---|
| 307 | *diff = mul_u64_u64_div_u64(a: base, mul: (u64)scaled_ppm, div: 1000000ULL << 16); | 
|---|
| 308 |  | 
|---|
| 309 | return negative; | 
|---|
| 310 | } | 
|---|
| 311 |  | 
|---|
| 312 | /** | 
|---|
| 313 | * adjust_by_scaled_ppm - Adjust a base increment by scaled parts per million | 
|---|
| 314 | * @base: the base increment value to adjust | 
|---|
| 315 | * @scaled_ppm: scaled parts per million frequency adjustment | 
|---|
| 316 | * | 
|---|
| 317 | * Helper function which calculates a new increment value based on the | 
|---|
| 318 | * requested scaled parts per million adjustment. | 
|---|
| 319 | */ | 
|---|
| 320 | static inline u64 adjust_by_scaled_ppm(u64 base, long scaled_ppm) | 
|---|
| 321 | { | 
|---|
| 322 | u64 diff; | 
|---|
| 323 |  | 
|---|
| 324 | if (diff_by_scaled_ppm(base, scaled_ppm, diff: &diff)) | 
|---|
| 325 | return base - diff; | 
|---|
| 326 |  | 
|---|
| 327 | return base + diff; | 
|---|
| 328 | } | 
|---|
| 329 |  | 
|---|
| 330 | #if IS_ENABLED(CONFIG_PTP_1588_CLOCK) | 
|---|
| 331 |  | 
|---|
| 332 | /** | 
|---|
| 333 | * ptp_clock_register() - register a PTP hardware clock driver | 
|---|
| 334 | * | 
|---|
| 335 | * @info:   Structure describing the new clock. | 
|---|
| 336 | * @parent: Pointer to the parent device of the new clock. | 
|---|
| 337 | * | 
|---|
| 338 | * Returns: a valid pointer on success or PTR_ERR on failure.  If PHC | 
|---|
| 339 | * support is missing at the configuration level, this function | 
|---|
| 340 | * returns NULL, and drivers are expected to gracefully handle that | 
|---|
| 341 | * case separately. | 
|---|
| 342 | */ | 
|---|
| 343 |  | 
|---|
| 344 | extern struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, | 
|---|
| 345 | struct device *parent); | 
|---|
| 346 |  | 
|---|
| 347 | /** | 
|---|
| 348 | * ptp_clock_unregister() - unregister a PTP hardware clock driver | 
|---|
| 349 | * | 
|---|
| 350 | * @ptp:  The clock to remove from service. | 
|---|
| 351 | */ | 
|---|
| 352 |  | 
|---|
| 353 | extern int ptp_clock_unregister(struct ptp_clock *ptp); | 
|---|
| 354 |  | 
|---|
| 355 | /** | 
|---|
| 356 | * ptp_clock_event() - notify the PTP layer about an event | 
|---|
| 357 | * | 
|---|
| 358 | * @ptp:    The clock obtained from ptp_clock_register(). | 
|---|
| 359 | * @event:  Message structure describing the event. | 
|---|
| 360 | */ | 
|---|
| 361 |  | 
|---|
| 362 | extern void ptp_clock_event(struct ptp_clock *ptp, | 
|---|
| 363 | struct ptp_clock_event *event); | 
|---|
| 364 |  | 
|---|
| 365 | /** | 
|---|
| 366 | * ptp_clock_index() - obtain the device index of a PTP clock | 
|---|
| 367 | * | 
|---|
| 368 | * @ptp:    The clock obtained from ptp_clock_register(). | 
|---|
| 369 | */ | 
|---|
| 370 |  | 
|---|
| 371 | extern int ptp_clock_index(struct ptp_clock *ptp); | 
|---|
| 372 |  | 
|---|
| 373 | /** | 
|---|
| 374 | * ptp_clock_index_by_of_node() - obtain the device index of | 
|---|
| 375 | * a PTP clock based on the PTP device of_node | 
|---|
| 376 | * | 
|---|
| 377 | * @np:    The device of_node pointer of the PTP device. | 
|---|
| 378 | * Return: The PHC index on success or -1 on failure. | 
|---|
| 379 | */ | 
|---|
| 380 | int ptp_clock_index_by_of_node(struct device_node *np); | 
|---|
| 381 |  | 
|---|
| 382 | /** | 
|---|
| 383 | * ptp_clock_index_by_dev() - obtain the device index of | 
|---|
| 384 | * a PTP clock based on the PTP device. | 
|---|
| 385 | * | 
|---|
| 386 | * @parent:    The parent device (PTP device) pointer of the PTP clock. | 
|---|
| 387 | * Return: The PHC index on success or -1 on failure. | 
|---|
| 388 | */ | 
|---|
| 389 | int ptp_clock_index_by_dev(struct device *parent); | 
|---|
| 390 |  | 
|---|
| 391 | /** | 
|---|
| 392 | * ptp_find_pin() - obtain the pin index of a given auxiliary function | 
|---|
| 393 | * | 
|---|
| 394 | * The caller must hold ptp_clock::pincfg_mux.  Drivers do not have | 
|---|
| 395 | * access to that mutex as ptp_clock is an opaque type.  However, the | 
|---|
| 396 | * core code acquires the mutex before invoking the driver's | 
|---|
| 397 | * ptp_clock_info::enable() callback, and so drivers may call this | 
|---|
| 398 | * function from that context. | 
|---|
| 399 | * | 
|---|
| 400 | * @ptp:    The clock obtained from ptp_clock_register(). | 
|---|
| 401 | * @func:   One of the ptp_pin_function enumerated values. | 
|---|
| 402 | * @chan:   The particular functional channel to find. | 
|---|
| 403 | * Return:  Pin index in the range of zero to ptp_clock_caps.n_pins - 1, | 
|---|
| 404 | *          or -1 if the auxiliary function cannot be found. | 
|---|
| 405 | */ | 
|---|
| 406 |  | 
|---|
| 407 | int ptp_find_pin(struct ptp_clock *ptp, | 
|---|
| 408 | enum ptp_pin_function func, unsigned int chan); | 
|---|
| 409 |  | 
|---|
| 410 | /** | 
|---|
| 411 | * ptp_find_pin_unlocked() - wrapper for ptp_find_pin() | 
|---|
| 412 | * | 
|---|
| 413 | * This function acquires the ptp_clock::pincfg_mux mutex before | 
|---|
| 414 | * invoking ptp_find_pin().  Instead of using this function, drivers | 
|---|
| 415 | * should most likely call ptp_find_pin() directly from their | 
|---|
| 416 | * ptp_clock_info::enable() method. | 
|---|
| 417 | * | 
|---|
| 418 | * @ptp:    The clock obtained from ptp_clock_register(). | 
|---|
| 419 | * @func:   One of the ptp_pin_function enumerated values. | 
|---|
| 420 | * @chan:   The particular functional channel to find. | 
|---|
| 421 | * Return:  Pin index in the range of zero to ptp_clock_caps.n_pins - 1, | 
|---|
| 422 | *          or -1 if the auxiliary function cannot be found. | 
|---|
| 423 | */ | 
|---|
| 424 |  | 
|---|
| 425 | int ptp_find_pin_unlocked(struct ptp_clock *ptp, | 
|---|
| 426 | enum ptp_pin_function func, unsigned int chan); | 
|---|
| 427 |  | 
|---|
| 428 | /** | 
|---|
| 429 | * ptp_schedule_worker() - schedule ptp auxiliary work | 
|---|
| 430 | * | 
|---|
| 431 | * @ptp:    The clock obtained from ptp_clock_register(). | 
|---|
| 432 | * @delay:  number of jiffies to wait before queuing | 
|---|
| 433 | *          See kthread_queue_delayed_work() for more info. | 
|---|
| 434 | */ | 
|---|
| 435 |  | 
|---|
| 436 | int ptp_schedule_worker(struct ptp_clock *ptp, unsigned long delay); | 
|---|
| 437 |  | 
|---|
| 438 | /** | 
|---|
| 439 | * ptp_cancel_worker_sync() - cancel ptp auxiliary clock | 
|---|
| 440 | * | 
|---|
| 441 | * @ptp:     The clock obtained from ptp_clock_register(). | 
|---|
| 442 | */ | 
|---|
| 443 | void ptp_cancel_worker_sync(struct ptp_clock *ptp); | 
|---|
| 444 |  | 
|---|
| 445 | #else | 
|---|
| 446 | static inline struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, | 
|---|
| 447 | struct device *parent) | 
|---|
| 448 | { return NULL; } | 
|---|
| 449 | static inline int ptp_clock_unregister(struct ptp_clock *ptp) | 
|---|
| 450 | { return 0; } | 
|---|
| 451 | static inline void ptp_clock_event(struct ptp_clock *ptp, | 
|---|
| 452 | struct ptp_clock_event *event) | 
|---|
| 453 | { } | 
|---|
| 454 | static inline int ptp_clock_index(struct ptp_clock *ptp) | 
|---|
| 455 | { return -1; } | 
|---|
| 456 | static inline int ptp_clock_index_by_of_node(struct device_node *np) | 
|---|
| 457 | { return -1; } | 
|---|
| 458 | static inline int ptp_clock_index_by_dev(struct device *parent) | 
|---|
| 459 | { return -1; } | 
|---|
| 460 | static inline int ptp_find_pin(struct ptp_clock *ptp, | 
|---|
| 461 | enum ptp_pin_function func, unsigned int chan) | 
|---|
| 462 | { return -1; } | 
|---|
| 463 | static inline int ptp_find_pin_unlocked(struct ptp_clock *ptp, | 
|---|
| 464 | enum ptp_pin_function func, | 
|---|
| 465 | unsigned int chan) | 
|---|
| 466 | { return -1; } | 
|---|
| 467 | static inline int ptp_schedule_worker(struct ptp_clock *ptp, | 
|---|
| 468 | unsigned long delay) | 
|---|
| 469 | { return -EOPNOTSUPP; } | 
|---|
| 470 | static inline void ptp_cancel_worker_sync(struct ptp_clock *ptp) | 
|---|
| 471 | { } | 
|---|
| 472 | #endif | 
|---|
| 473 |  | 
|---|
| 474 | #if IS_BUILTIN(CONFIG_PTP_1588_CLOCK) | 
|---|
| 475 | /* | 
|---|
| 476 | * These are called by the network core, and don't work if PTP is in | 
|---|
| 477 | * a loadable module. | 
|---|
| 478 | */ | 
|---|
| 479 |  | 
|---|
| 480 | /** | 
|---|
| 481 | * ptp_get_vclocks_index() - get all vclocks index on pclock, and | 
|---|
| 482 | *                           caller is responsible to free memory | 
|---|
| 483 | *                           of vclock_index | 
|---|
| 484 | * | 
|---|
| 485 | * @pclock_index: phc index of ptp pclock. | 
|---|
| 486 | * @vclock_index: pointer to pointer of vclock index. | 
|---|
| 487 | * | 
|---|
| 488 | * return number of vclocks. | 
|---|
| 489 | */ | 
|---|
| 490 | int ptp_get_vclocks_index(int pclock_index, int **vclock_index); | 
|---|
| 491 |  | 
|---|
| 492 | /** | 
|---|
| 493 | * ptp_convert_timestamp() - convert timestamp to a ptp vclock time | 
|---|
| 494 | * | 
|---|
| 495 | * @hwtstamp:     timestamp | 
|---|
| 496 | * @vclock_index: phc index of ptp vclock. | 
|---|
| 497 | * | 
|---|
| 498 | * Returns: converted timestamp, or 0 on error. | 
|---|
| 499 | */ | 
|---|
| 500 | ktime_t ptp_convert_timestamp(const ktime_t *hwtstamp, int vclock_index); | 
|---|
| 501 | #else | 
|---|
| 502 | static inline int ptp_get_vclocks_index(int pclock_index, int **vclock_index) | 
|---|
| 503 | { return 0; } | 
|---|
| 504 | static inline ktime_t ptp_convert_timestamp(const ktime_t *hwtstamp, | 
|---|
| 505 | int vclock_index) | 
|---|
| 506 | { return 0; } | 
|---|
| 507 |  | 
|---|
| 508 | #endif | 
|---|
| 509 |  | 
|---|
| 510 | static inline void ptp_read_system_prets(struct ptp_system_timestamp *sts) | 
|---|
| 511 | { | 
|---|
| 512 | if (sts) | 
|---|
| 513 | ktime_get_clock_ts64(id: sts->clockid, ts: &sts->pre_ts); | 
|---|
| 514 | } | 
|---|
| 515 |  | 
|---|
| 516 | static inline void ptp_read_system_postts(struct ptp_system_timestamp *sts) | 
|---|
| 517 | { | 
|---|
| 518 | if (sts) | 
|---|
| 519 | ktime_get_clock_ts64(id: sts->clockid, ts: &sts->post_ts); | 
|---|
| 520 | } | 
|---|
| 521 |  | 
|---|
| 522 | #endif | 
|---|
| 523 |  | 
|---|