1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Marvell 88E6xxx Switch PTP support
5 * Copyright (c) 2008 Marvell Semiconductor
7 * Copyright (c) 2017 National Instruments
8 * Erik Hons <erik.hons@ni.com>
9 * Brandon Streiff <brandon.streiff@ni.com>
10 * Dane Wagner <dane.wagner@ni.com>
19 #define MV88E6XXX_MAX_ADJ_PPB 1000000
21 struct mv88e6xxx_cc_coeffs
{
29 * Raw timestamps are in units of 10-ns clock periods.
31 * clkadj = scaled_ppm * 10*2^28 / (10^6 * 2^16)
33 * clkadj = scaled_ppm * 2^7 / 5^5
35 #define MV88E6XXX_CC_10NS_SHIFT 28
36 static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_10ns_coeffs
= {
37 .cc_shift
= MV88E6XXX_CC_10NS_SHIFT
,
38 .cc_mult
= 10 << MV88E6XXX_CC_10NS_SHIFT
,
39 .cc_mult_num
= 1 << 7,
40 .cc_mult_dem
= 3125ULL,
43 /* Other families except MV88E6393X in internal clock mode:
44 * Raw timestamps are in units of 8-ns clock periods.
46 * clkadj = scaled_ppm * 8*2^28 / (10^6 * 2^16)
48 * clkadj = scaled_ppm * 2^9 / 5^6
50 #define MV88E6XXX_CC_8NS_SHIFT 28
51 static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_8ns_coeffs
= {
52 .cc_shift
= MV88E6XXX_CC_8NS_SHIFT
,
53 .cc_mult
= 8 << MV88E6XXX_CC_8NS_SHIFT
,
54 .cc_mult_num
= 1 << 9,
55 .cc_mult_dem
= 15625ULL
58 /* Family MV88E6393X using internal clock:
59 * Raw timestamps are in units of 4-ns clock periods.
61 * clkadj = scaled_ppm * 4*2^28 / (10^6 * 2^16)
63 * clkadj = scaled_ppm * 2^8 / 5^6
65 #define MV88E6XXX_CC_4NS_SHIFT 28
66 static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_4ns_coeffs
= {
67 .cc_shift
= MV88E6XXX_CC_4NS_SHIFT
,
68 .cc_mult
= 4 << MV88E6XXX_CC_4NS_SHIFT
,
69 .cc_mult_num
= 1 << 8,
70 .cc_mult_dem
= 15625ULL
73 #define TAI_EVENT_WORK_INTERVAL msecs_to_jiffies(100)
75 #define cc_to_chip(cc) container_of(cc, struct mv88e6xxx_chip, tstamp_cc)
76 #define dw_overflow_to_chip(dw) container_of(dw, struct mv88e6xxx_chip, \
78 #define dw_tai_event_to_chip(dw) container_of(dw, struct mv88e6xxx_chip, \
81 static int mv88e6xxx_tai_read(struct mv88e6xxx_chip
*chip
, int addr
,
84 if (!chip
->info
->ops
->avb_ops
->tai_read
)
87 return chip
->info
->ops
->avb_ops
->tai_read(chip
, addr
, data
, len
);
90 static int mv88e6xxx_tai_write(struct mv88e6xxx_chip
*chip
, int addr
, u16 data
)
92 if (!chip
->info
->ops
->avb_ops
->tai_write
)
95 return chip
->info
->ops
->avb_ops
->tai_write(chip
, addr
, data
);
98 /* TODO: places where this are called should be using pinctrl */
99 static int mv88e6352_set_gpio_func(struct mv88e6xxx_chip
*chip
, int pin
,
104 if (!chip
->info
->ops
->gpio_ops
)
107 err
= chip
->info
->ops
->gpio_ops
->set_dir(chip
, pin
, input
);
111 return chip
->info
->ops
->gpio_ops
->set_pctl(chip
, pin
, func
);
114 static const struct mv88e6xxx_cc_coeffs
*
115 mv88e6xxx_cc_coeff_get(struct mv88e6xxx_chip
*chip
)
120 err
= mv88e6xxx_tai_read(chip
, MV88E6XXX_TAI_CLOCK_PERIOD
, &period_ps
, 1);
122 dev_err(chip
->dev
, "failed to read cycle counter period: %d\n",
129 return &mv88e6xxx_cc_4ns_coeffs
;
131 return &mv88e6xxx_cc_8ns_coeffs
;
133 return &mv88e6xxx_cc_10ns_coeffs
;
135 dev_err(chip
->dev
, "unexpected cycle counter period of %u ps\n",
137 return ERR_PTR(-ENODEV
);
141 static u64
mv88e6352_ptp_clock_read(const struct cyclecounter
*cc
)
143 struct mv88e6xxx_chip
*chip
= cc_to_chip(cc
);
147 err
= mv88e6xxx_tai_read(chip
, MV88E6XXX_TAI_TIME_LO
, phc_time
,
148 ARRAY_SIZE(phc_time
));
152 return ((u32
)phc_time
[1] << 16) | phc_time
[0];
155 static u64
mv88e6165_ptp_clock_read(const struct cyclecounter
*cc
)
157 struct mv88e6xxx_chip
*chip
= cc_to_chip(cc
);
161 err
= mv88e6xxx_tai_read(chip
, MV88E6XXX_PTP_GC_TIME_LO
, phc_time
,
162 ARRAY_SIZE(phc_time
));
166 return ((u32
)phc_time
[1] << 16) | phc_time
[0];
169 /* mv88e6352_config_eventcap - configure TAI event capture
170 * @event: PTP_CLOCK_PPS (internal) or PTP_CLOCK_EXTTS (external)
171 * @rising: zero for falling-edge trigger, else rising-edge trigger
173 * This will also reset the capture sequence counter.
175 static int mv88e6352_config_eventcap(struct mv88e6xxx_chip
*chip
, int event
,
182 chip
->evcap_config
= MV88E6XXX_TAI_CFG_CAP_OVERWRITE
|
183 MV88E6XXX_TAI_CFG_CAP_CTR_START
;
185 chip
->evcap_config
|= MV88E6XXX_TAI_CFG_EVREQ_FALLING
;
187 global_config
= (chip
->evcap_config
| chip
->trig_config
);
188 err
= mv88e6xxx_tai_write(chip
, MV88E6XXX_TAI_CFG
, global_config
);
192 if (event
== PTP_CLOCK_PPS
) {
193 cap_config
= MV88E6XXX_TAI_EVENT_STATUS_CAP_TRIG
;
194 } else if (event
== PTP_CLOCK_EXTTS
) {
195 /* if STATUS_CAP_TRIG is unset we capture PTP_EVREQ events */
201 /* Write the capture config; this also clears the capture counter */
202 err
= mv88e6xxx_tai_write(chip
, MV88E6XXX_TAI_EVENT_STATUS
,
208 static void mv88e6352_tai_event_work(struct work_struct
*ugly
)
210 struct delayed_work
*dw
= to_delayed_work(ugly
);
211 struct mv88e6xxx_chip
*chip
= dw_tai_event_to_chip(dw
);
212 struct ptp_clock_event ev
;
217 mv88e6xxx_reg_lock(chip
);
218 err
= mv88e6xxx_tai_read(chip
, MV88E6XXX_TAI_EVENT_STATUS
,
219 status
, ARRAY_SIZE(status
));
220 mv88e6xxx_reg_unlock(chip
);
223 dev_err(chip
->dev
, "failed to read TAI status register\n");
226 if (status
[0] & MV88E6XXX_TAI_EVENT_STATUS_ERROR
) {
227 dev_warn(chip
->dev
, "missed event capture\n");
230 if (!(status
[0] & MV88E6XXX_TAI_EVENT_STATUS_VALID
))
233 raw_ts
= ((u32
)status
[2] << 16) | status
[1];
235 /* Clear the valid bit so the next timestamp can come in */
236 status
[0] &= ~MV88E6XXX_TAI_EVENT_STATUS_VALID
;
237 mv88e6xxx_reg_lock(chip
);
238 err
= mv88e6xxx_tai_write(chip
, MV88E6XXX_TAI_EVENT_STATUS
, status
[0]);
239 mv88e6xxx_reg_unlock(chip
);
241 dev_err(chip
->dev
, "failed to write TAI status register\n");
245 /* This is an external timestamp */
246 ev
.type
= PTP_CLOCK_EXTTS
;
248 /* We only have one timestamping channel. */
250 mv88e6xxx_reg_lock(chip
);
251 ev
.timestamp
= timecounter_cyc2time(&chip
->tstamp_tc
, raw_ts
);
252 mv88e6xxx_reg_unlock(chip
);
254 ptp_clock_event(chip
->ptp_clock
, &ev
);
256 schedule_delayed_work(&chip
->tai_event_work
, TAI_EVENT_WORK_INTERVAL
);
259 static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info
*ptp
, long scaled_ppm
)
261 struct mv88e6xxx_chip
*chip
= ptp_to_chip(ptp
);
266 if (scaled_ppm
< 0) {
268 scaled_ppm
= -scaled_ppm
;
271 mult
= chip
->cc_coeffs
->cc_mult
;
272 adj
= chip
->cc_coeffs
->cc_mult_num
;
274 diff
= div_u64(adj
, chip
->cc_coeffs
->cc_mult_dem
);
276 mv88e6xxx_reg_lock(chip
);
278 timecounter_read(&chip
->tstamp_tc
);
279 chip
->tstamp_cc
.mult
= neg_adj
? mult
- diff
: mult
+ diff
;
281 mv88e6xxx_reg_unlock(chip
);
286 static int mv88e6xxx_ptp_adjtime(struct ptp_clock_info
*ptp
, s64 delta
)
288 struct mv88e6xxx_chip
*chip
= ptp_to_chip(ptp
);
290 mv88e6xxx_reg_lock(chip
);
291 timecounter_adjtime(&chip
->tstamp_tc
, delta
);
292 mv88e6xxx_reg_unlock(chip
);
297 static int mv88e6xxx_ptp_gettime(struct ptp_clock_info
*ptp
,
298 struct timespec64
*ts
)
300 struct mv88e6xxx_chip
*chip
= ptp_to_chip(ptp
);
303 mv88e6xxx_reg_lock(chip
);
304 ns
= timecounter_read(&chip
->tstamp_tc
);
305 mv88e6xxx_reg_unlock(chip
);
307 *ts
= ns_to_timespec64(ns
);
312 static int mv88e6xxx_ptp_settime(struct ptp_clock_info
*ptp
,
313 const struct timespec64
*ts
)
315 struct mv88e6xxx_chip
*chip
= ptp_to_chip(ptp
);
318 ns
= timespec64_to_ns(ts
);
320 mv88e6xxx_reg_lock(chip
);
321 timecounter_init(&chip
->tstamp_tc
, &chip
->tstamp_cc
, ns
);
322 mv88e6xxx_reg_unlock(chip
);
327 static int mv88e6352_ptp_enable_extts(struct mv88e6xxx_chip
*chip
,
328 struct ptp_clock_request
*rq
, int on
)
330 int rising
= (rq
->extts
.flags
& PTP_RISING_EDGE
);
335 /* Reject requests with unsupported flags */
336 if (rq
->extts
.flags
& ~(PTP_ENABLE_FEATURE
|
342 /* Reject requests to enable time stamping on both edges. */
343 if ((rq
->extts
.flags
& PTP_STRICT_FLAGS
) &&
344 (rq
->extts
.flags
& PTP_ENABLE_FEATURE
) &&
345 (rq
->extts
.flags
& PTP_EXTTS_EDGES
) == PTP_EXTTS_EDGES
)
348 pin
= ptp_find_pin(chip
->ptp_clock
, PTP_PF_EXTTS
, rq
->extts
.index
);
353 mv88e6xxx_reg_lock(chip
);
356 func
= MV88E6352_G2_SCRATCH_GPIO_PCTL_EVREQ
;
358 err
= mv88e6352_set_gpio_func(chip
, pin
, func
, true);
362 schedule_delayed_work(&chip
->tai_event_work
,
363 TAI_EVENT_WORK_INTERVAL
);
365 err
= mv88e6352_config_eventcap(chip
, PTP_CLOCK_EXTTS
, rising
);
367 func
= MV88E6352_G2_SCRATCH_GPIO_PCTL_GPIO
;
369 err
= mv88e6352_set_gpio_func(chip
, pin
, func
, true);
371 cancel_delayed_work_sync(&chip
->tai_event_work
);
375 mv88e6xxx_reg_unlock(chip
);
380 static int mv88e6352_ptp_enable(struct ptp_clock_info
*ptp
,
381 struct ptp_clock_request
*rq
, int on
)
383 struct mv88e6xxx_chip
*chip
= ptp_to_chip(ptp
);
386 case PTP_CLK_REQ_EXTTS
:
387 return mv88e6352_ptp_enable_extts(chip
, rq
, on
);
393 static int mv88e6352_ptp_verify(struct ptp_clock_info
*ptp
, unsigned int pin
,
394 enum ptp_pin_function func
, unsigned int chan
)
407 const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops
= {
408 .clock_read
= mv88e6165_ptp_clock_read
,
409 .global_enable
= mv88e6165_global_enable
,
410 .global_disable
= mv88e6165_global_disable
,
411 .arr0_sts_reg
= MV88E6165_PORT_PTP_ARR0_STS
,
412 .arr1_sts_reg
= MV88E6165_PORT_PTP_ARR1_STS
,
413 .dep_sts_reg
= MV88E6165_PORT_PTP_DEP_STS
,
414 .rx_filters
= (1 << HWTSTAMP_FILTER_NONE
) |
415 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT
) |
416 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC
) |
417 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ
) |
418 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT
) |
419 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC
) |
420 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ
),
423 const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops
= {
424 .clock_read
= mv88e6352_ptp_clock_read
,
425 .ptp_enable
= mv88e6352_ptp_enable
,
426 .ptp_verify
= mv88e6352_ptp_verify
,
427 .event_work
= mv88e6352_tai_event_work
,
428 .port_enable
= mv88e6352_hwtstamp_port_enable
,
429 .port_disable
= mv88e6352_hwtstamp_port_disable
,
431 .arr0_sts_reg
= MV88E6XXX_PORT_PTP_ARR0_STS
,
432 .arr1_sts_reg
= MV88E6XXX_PORT_PTP_ARR1_STS
,
433 .dep_sts_reg
= MV88E6XXX_PORT_PTP_DEP_STS
,
434 .rx_filters
= (1 << HWTSTAMP_FILTER_NONE
) |
435 (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT
) |
436 (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC
) |
437 (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ
) |
438 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT
) |
439 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC
) |
440 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ
) |
441 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT
) |
442 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC
) |
443 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ
),
446 const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops
= {
447 .clock_read
= mv88e6352_ptp_clock_read
,
448 .ptp_enable
= mv88e6352_ptp_enable
,
449 .ptp_verify
= mv88e6352_ptp_verify
,
450 .event_work
= mv88e6352_tai_event_work
,
451 .port_enable
= mv88e6352_hwtstamp_port_enable
,
452 .port_disable
= mv88e6352_hwtstamp_port_disable
,
454 .arr0_sts_reg
= MV88E6XXX_PORT_PTP_ARR0_STS
,
455 .arr1_sts_reg
= MV88E6XXX_PORT_PTP_ARR1_STS
,
456 .dep_sts_reg
= MV88E6XXX_PORT_PTP_DEP_STS
,
457 .rx_filters
= (1 << HWTSTAMP_FILTER_NONE
) |
458 (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT
) |
459 (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC
) |
460 (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ
) |
461 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT
) |
462 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC
) |
463 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ
) |
464 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT
) |
465 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC
) |
466 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ
),
469 const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops
= {
470 .clock_read
= mv88e6352_ptp_clock_read
,
471 .ptp_enable
= mv88e6352_ptp_enable
,
472 .ptp_verify
= mv88e6352_ptp_verify
,
473 .event_work
= mv88e6352_tai_event_work
,
474 .port_enable
= mv88e6352_hwtstamp_port_enable
,
475 .port_disable
= mv88e6352_hwtstamp_port_disable
,
476 .set_ptp_cpu_port
= mv88e6390_g1_set_ptp_cpu_port
,
478 .arr0_sts_reg
= MV88E6XXX_PORT_PTP_ARR0_STS
,
479 .arr1_sts_reg
= MV88E6XXX_PORT_PTP_ARR1_STS
,
480 .dep_sts_reg
= MV88E6XXX_PORT_PTP_DEP_STS
,
481 .rx_filters
= (1 << HWTSTAMP_FILTER_NONE
) |
482 (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT
) |
483 (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC
) |
484 (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ
) |
485 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT
) |
486 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC
) |
487 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ
) |
488 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT
) |
489 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC
) |
490 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ
),
493 static u64
mv88e6xxx_ptp_clock_read(const struct cyclecounter
*cc
)
495 struct mv88e6xxx_chip
*chip
= cc_to_chip(cc
);
497 if (chip
->info
->ops
->ptp_ops
->clock_read
)
498 return chip
->info
->ops
->ptp_ops
->clock_read(cc
);
503 /* With a 250MHz input clock, the 32-bit timestamp counter overflows in ~17.2
504 * seconds; this task forces periodic reads so that we don't miss any.
506 #define MV88E6XXX_TAI_OVERFLOW_PERIOD (HZ * 8)
507 static void mv88e6xxx_ptp_overflow_check(struct work_struct
*work
)
509 struct delayed_work
*dw
= to_delayed_work(work
);
510 struct mv88e6xxx_chip
*chip
= dw_overflow_to_chip(dw
);
511 struct timespec64 ts
;
513 mv88e6xxx_ptp_gettime(&chip
->ptp_clock_info
, &ts
);
515 schedule_delayed_work(&chip
->overflow_work
,
516 MV88E6XXX_TAI_OVERFLOW_PERIOD
);
519 int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip
*chip
)
521 const struct mv88e6xxx_ptp_ops
*ptp_ops
= chip
->info
->ops
->ptp_ops
;
524 /* Set up the cycle counter */
525 chip
->cc_coeffs
= mv88e6xxx_cc_coeff_get(chip
);
526 if (IS_ERR(chip
->cc_coeffs
))
527 return PTR_ERR(chip
->cc_coeffs
);
529 memset(&chip
->tstamp_cc
, 0, sizeof(chip
->tstamp_cc
));
530 chip
->tstamp_cc
.read
= mv88e6xxx_ptp_clock_read
;
531 chip
->tstamp_cc
.mask
= CYCLECOUNTER_MASK(32);
532 chip
->tstamp_cc
.mult
= chip
->cc_coeffs
->cc_mult
;
533 chip
->tstamp_cc
.shift
= chip
->cc_coeffs
->cc_shift
;
535 timecounter_init(&chip
->tstamp_tc
, &chip
->tstamp_cc
,
536 ktime_to_ns(ktime_get_real()));
538 INIT_DELAYED_WORK(&chip
->overflow_work
, mv88e6xxx_ptp_overflow_check
);
539 if (ptp_ops
->event_work
)
540 INIT_DELAYED_WORK(&chip
->tai_event_work
, ptp_ops
->event_work
);
542 chip
->ptp_clock_info
.owner
= THIS_MODULE
;
543 snprintf(chip
->ptp_clock_info
.name
, sizeof(chip
->ptp_clock_info
.name
),
544 "%s", dev_name(chip
->dev
));
546 chip
->ptp_clock_info
.n_ext_ts
= ptp_ops
->n_ext_ts
;
547 chip
->ptp_clock_info
.n_per_out
= 0;
548 chip
->ptp_clock_info
.n_pins
= mv88e6xxx_num_gpio(chip
);
549 chip
->ptp_clock_info
.pps
= 0;
551 for (i
= 0; i
< chip
->ptp_clock_info
.n_pins
; ++i
) {
552 struct ptp_pin_desc
*ppd
= &chip
->pin_config
[i
];
554 snprintf(ppd
->name
, sizeof(ppd
->name
), "mv88e6xxx_gpio%d", i
);
556 ppd
->func
= PTP_PF_NONE
;
558 chip
->ptp_clock_info
.pin_config
= chip
->pin_config
;
560 chip
->ptp_clock_info
.max_adj
= MV88E6XXX_MAX_ADJ_PPB
;
561 chip
->ptp_clock_info
.adjfine
= mv88e6xxx_ptp_adjfine
;
562 chip
->ptp_clock_info
.adjtime
= mv88e6xxx_ptp_adjtime
;
563 chip
->ptp_clock_info
.gettime64
= mv88e6xxx_ptp_gettime
;
564 chip
->ptp_clock_info
.settime64
= mv88e6xxx_ptp_settime
;
565 chip
->ptp_clock_info
.enable
= ptp_ops
->ptp_enable
;
566 chip
->ptp_clock_info
.verify
= ptp_ops
->ptp_verify
;
567 chip
->ptp_clock_info
.do_aux_work
= mv88e6xxx_hwtstamp_work
;
569 if (ptp_ops
->set_ptp_cpu_port
) {
574 dsa_switch_for_each_user_port(dp
, chip
->ds
) {
575 upstream
= dsa_upstream_port(chip
->ds
, dp
->index
);
579 err
= ptp_ops
->set_ptp_cpu_port(chip
, upstream
);
581 dev_err(chip
->dev
, "Failed to set PTP CPU destination port!\n");
586 chip
->ptp_clock
= ptp_clock_register(&chip
->ptp_clock_info
, chip
->dev
);
587 if (IS_ERR(chip
->ptp_clock
))
588 return PTR_ERR(chip
->ptp_clock
);
590 schedule_delayed_work(&chip
->overflow_work
,
591 MV88E6XXX_TAI_OVERFLOW_PERIOD
);
596 void mv88e6xxx_ptp_free(struct mv88e6xxx_chip
*chip
)
598 if (chip
->ptp_clock
) {
599 cancel_delayed_work_sync(&chip
->overflow_work
);
600 if (chip
->info
->ops
->ptp_ops
->event_work
)
601 cancel_delayed_work_sync(&chip
->tai_event_work
);
603 ptp_clock_unregister(chip
->ptp_clock
);
604 chip
->ptp_clock
= NULL
;