File Index
Files and directories
Sign in
FILE

ptp.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/dsa/mv88e6xxx/ptp.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Marvell 88E6xxx Switch PTP support
  4 *
  5 * Copyright (c) 2008 Marvell Semiconductor
  6 *
  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>
 11 */
 12
 13#include "chip.h"
 14#include "global1.h"
 15#include "global2.h"
 16#include "hwtstamp.h"
 17#include "ptp.h"
 18
 19#define MV88E6XXX_MAX_ADJ_PPB	1000000
 20
 21struct mv88e6xxx_cc_coeffs {
 22	u32 cc_shift;
 23	u32 cc_mult;
 24	u32 cc_mult_num;
 25	u32 cc_mult_dem;
 26};
 27
 28/* Family MV88E6250:
 29 * Raw timestamps are in units of 10-ns clock periods.
 30 *
 31 * clkadj = scaled_ppm * 10*2^28 / (10^6 * 2^16)
 32 * simplifies to
 33 * clkadj = scaled_ppm * 2^7 / 5^5
 34 */
 35#define MV88E6XXX_CC_10NS_SHIFT 28
 36static 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,
 41};
 42
 43/* Other families except MV88E6393X in internal clock mode:
 44 * Raw timestamps are in units of 8-ns clock periods.
 45 *
 46 * clkadj = scaled_ppm * 8*2^28 / (10^6 * 2^16)
 47 * simplifies to
 48 * clkadj = scaled_ppm * 2^9 / 5^6
 49 */
 50#define MV88E6XXX_CC_8NS_SHIFT 28
 51static 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
 56};
 57
 58/* Family MV88E6393X using internal clock:
 59 * Raw timestamps are in units of 4-ns clock periods.
 60 *
 61 * clkadj = scaled_ppm * 4*2^28 / (10^6 * 2^16)
 62 * simplifies to
 63 * clkadj = scaled_ppm * 2^8 / 5^6
 64 */
 65#define MV88E6XXX_CC_4NS_SHIFT 28
 66static 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
 71};
 72
 73#define TAI_EVENT_WORK_INTERVAL msecs_to_jiffies(100)
 74
 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, \
 77					     overflow_work)
 78#define dw_tai_event_to_chip(dw) container_of(dw, struct mv88e6xxx_chip, \
 79					      tai_event_work)
 80
 81static int mv88e6xxx_tai_read(struct mv88e6xxx_chip *chip, int addr,
 82			      u16 *data, int len)
 83{
 84	if (!chip->info->ops->avb_ops->tai_read)
 85		return -EOPNOTSUPP;
 86
 87	return chip->info->ops->avb_ops->tai_read(chip, addr, data, len);
 88}
 89
 90static int mv88e6xxx_tai_write(struct mv88e6xxx_chip *chip, int addr, u16 data)
 91{
 92	if (!chip->info->ops->avb_ops->tai_write)
 93		return -EOPNOTSUPP;
 94
 95	return chip->info->ops->avb_ops->tai_write(chip, addr, data);
 96}
 97
 98/* TODO: places where this are called should be using pinctrl */
 99static int mv88e6352_set_gpio_func(struct mv88e6xxx_chip *chip, int pin,
100				   int func, int input)
101{
102	int err;
103
104	if (!chip->info->ops->gpio_ops)
105		return -EOPNOTSUPP;
106
107	err = chip->info->ops->gpio_ops->set_dir(chip, pin, input);
108	if (err)
109		return err;
110
111	return chip->info->ops->gpio_ops->set_pctl(chip, pin, func);
112}
113
114static const struct mv88e6xxx_cc_coeffs *
115mv88e6xxx_cc_coeff_get(struct mv88e6xxx_chip *chip)
116{
117	u16 period_ps;
118	int err;
119
120	err = mv88e6xxx_tai_read(chip, MV88E6XXX_TAI_CLOCK_PERIOD, &period_ps, 1);
121	if (err) {
122		dev_err(chip->dev, "failed to read cycle counter period: %d\n",
123			err);
124		return ERR_PTR(err);
125	}
126
127	switch (period_ps) {
128	case 4000:
129		return &mv88e6xxx_cc_4ns_coeffs;
130	case 8000:
131		return &mv88e6xxx_cc_8ns_coeffs;
132	case 10000:
133		return &mv88e6xxx_cc_10ns_coeffs;
134	default:
135		dev_err(chip->dev, "unexpected cycle counter period of %u ps\n",
136			period_ps);
137		return ERR_PTR(-ENODEV);
138	}
139}
140
141static u64 mv88e6352_ptp_clock_read(struct cyclecounter *cc)
142{
143	struct mv88e6xxx_chip *chip = cc_to_chip(cc);
144	u16 phc_time[2];
145	int err;
146
147	err = mv88e6xxx_tai_read(chip, MV88E6352_TAI_TIME_LO, phc_time,
148				 ARRAY_SIZE(phc_time));
149	if (err)
150		return 0;
151	else
152		return ((u32)phc_time[1] << 16) | phc_time[0];
153}
154
155static u64 mv88e6165_ptp_clock_read(struct cyclecounter *cc)
156{
157	struct mv88e6xxx_chip *chip = cc_to_chip(cc);
158	u16 phc_time[2];
159	int err;
160
161	err = mv88e6xxx_tai_read(chip, MV88E6165_PTP_GC_TIME_LO, phc_time,
162				 ARRAY_SIZE(phc_time));
163	if (err)
164		return 0;
165	else
166		return ((u32)phc_time[1] << 16) | phc_time[0];
167}
168
169/* mv88e6352_config_eventcap - configure TAI event capture
170 * @rising: zero for falling-edge trigger, else rising-edge trigger
171 *
172 * This will also reset the capture sequence counter.
173 */
174static int mv88e6352_config_eventcap(struct mv88e6xxx_chip *chip, int rising)
175{
176	u16 evcap_config;
177	int err;
178
179	evcap_config = MV88E6352_TAI_CFG_CAP_OVERWRITE |
180		       MV88E6352_TAI_CFG_CAP_CTR_START;
181	if (!rising)
182		evcap_config |= MV88E6352_TAI_CFG_EVREQ_FALLING;
183
184	err = mv88e6xxx_tai_write(chip, MV88E6352_TAI_CFG, evcap_config);
185	if (err)
186		return err;
187
188	/* Write the capture config; this also clears the capture counter */
189	return mv88e6xxx_tai_write(chip, MV88E6352_TAI_EVENT_STATUS, 0);
190}
191
192static void mv88e6352_tai_event_work(struct work_struct *ugly)
193{
194	struct delayed_work *dw = to_delayed_work(ugly);
195	struct mv88e6xxx_chip *chip = dw_tai_event_to_chip(dw);
196	struct ptp_clock_event ev;
197	u16 status[4];
198	u32 raw_ts;
199	int err;
200
201	mv88e6xxx_reg_lock(chip);
202	err = mv88e6xxx_tai_read(chip, MV88E6352_TAI_EVENT_STATUS,
203				 status, ARRAY_SIZE(status));
204	mv88e6xxx_reg_unlock(chip);
205
206	if (err) {
207		dev_err(chip->dev, "failed to read TAI status register\n");
208		return;
209	}
210	if (status[0] & MV88E6352_TAI_EVENT_STATUS_ERROR) {
211		dev_warn(chip->dev, "missed event capture\n");
212		return;
213	}
214	if (!(status[0] & MV88E6352_TAI_EVENT_STATUS_VALID))
215		goto out;
216
217	raw_ts = ((u32)status[2] << 16) | status[1];
218
219	/* Clear the valid bit so the next timestamp can come in */
220	status[0] &= ~MV88E6352_TAI_EVENT_STATUS_VALID;
221	mv88e6xxx_reg_lock(chip);
222	err = mv88e6xxx_tai_write(chip, MV88E6352_TAI_EVENT_STATUS, status[0]);
223	mv88e6xxx_reg_unlock(chip);
224	if (err) {
225		dev_err(chip->dev, "failed to write TAI status register\n");
226		return;
227	}
228
229	/* This is an external timestamp */
230	ev.type = PTP_CLOCK_EXTTS;
231
232	/* We only have one timestamping channel. */
233	ev.index = 0;
234	mv88e6xxx_reg_lock(chip);
235	ev.timestamp = timecounter_cyc2time(&chip->tstamp_tc, raw_ts);
236	mv88e6xxx_reg_unlock(chip);
237
238	ptp_clock_event(chip->ptp_clock, &ev);
239out:
240	schedule_delayed_work(&chip->tai_event_work, TAI_EVENT_WORK_INTERVAL);
241}
242
243static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
244{
245	struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
246	int neg_adj = 0;
247	u32 diff, mult;
248	u64 adj;
249
250	if (scaled_ppm < 0) {
251		neg_adj = 1;
252		scaled_ppm = -scaled_ppm;
253	}
254
255	mult = chip->cc_coeffs->cc_mult;
256	adj = chip->cc_coeffs->cc_mult_num;
257	adj *= scaled_ppm;
258	diff = div_u64(adj, chip->cc_coeffs->cc_mult_dem);
259
260	mv88e6xxx_reg_lock(chip);
261
262	timecounter_read(&chip->tstamp_tc);
263	chip->tstamp_cc.mult = neg_adj ? mult - diff : mult + diff;
264
265	mv88e6xxx_reg_unlock(chip);
266
267	return 0;
268}
269
270static int mv88e6xxx_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
271{
272	struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
273
274	mv88e6xxx_reg_lock(chip);
275	timecounter_adjtime(&chip->tstamp_tc, delta);
276	mv88e6xxx_reg_unlock(chip);
277
278	return 0;
279}
280
281static int mv88e6xxx_ptp_gettime(struct ptp_clock_info *ptp,
282				 struct timespec64 *ts)
283{
284	struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
285	u64 ns;
286
287	mv88e6xxx_reg_lock(chip);
288	ns = timecounter_read(&chip->tstamp_tc);
289	mv88e6xxx_reg_unlock(chip);
290
291	*ts = ns_to_timespec64(ns);
292
293	return 0;
294}
295
296static int mv88e6xxx_ptp_settime(struct ptp_clock_info *ptp,
297				 const struct timespec64 *ts)
298{
299	struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
300	u64 ns;
301
302	ns = timespec64_to_ns(ts);
303
304	mv88e6xxx_reg_lock(chip);
305	timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc, ns);
306	mv88e6xxx_reg_unlock(chip);
307
308	return 0;
309}
310
311static int mv88e6352_ptp_enable_extts(struct mv88e6xxx_chip *chip,
312				      struct ptp_clock_request *rq, int on)
313{
314	int rising = (rq->extts.flags & PTP_RISING_EDGE);
315	int func;
316	int pin;
317	int err;
318
319	/* Reject requests to enable time stamping on both edges. */
320	if ((rq->extts.flags & PTP_STRICT_FLAGS) &&
321	    (rq->extts.flags & PTP_ENABLE_FEATURE) &&
322	    (rq->extts.flags & PTP_EXTTS_EDGES) == PTP_EXTTS_EDGES)
323		return -EOPNOTSUPP;
324
325	pin = ptp_find_pin(chip->ptp_clock, PTP_PF_EXTTS, rq->extts.index);
326
327	if (pin < 0)
328		return -EBUSY;
329
330	mv88e6xxx_reg_lock(chip);
331
332	if (on) {
333		func = MV88E6352_G2_SCRATCH_GPIO_PCTL_EVREQ;
334
335		err = mv88e6352_set_gpio_func(chip, pin, func, true);
336		if (err)
337			goto out;
338
339		schedule_delayed_work(&chip->tai_event_work,
340				      TAI_EVENT_WORK_INTERVAL);
341
342		err = mv88e6352_config_eventcap(chip, rising);
343	} else {
344		func = MV88E6352_G2_SCRATCH_GPIO_PCTL_GPIO;
345
346		err = mv88e6352_set_gpio_func(chip, pin, func, true);
347
348		cancel_delayed_work_sync(&chip->tai_event_work);
349	}
350
351out:
352	mv88e6xxx_reg_unlock(chip);
353
354	return err;
355}
356
357static int mv88e6352_ptp_enable(struct ptp_clock_info *ptp,
358				struct ptp_clock_request *rq, int on)
359{
360	struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
361
362	switch (rq->type) {
363	case PTP_CLK_REQ_EXTTS:
364		return mv88e6352_ptp_enable_extts(chip, rq, on);
365	default:
366		return -EOPNOTSUPP;
367	}
368}
369
370static int mv88e6352_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin,
371				enum ptp_pin_function func, unsigned int chan)
372{
373	switch (func) {
374	case PTP_PF_NONE:
375	case PTP_PF_EXTTS:
376		break;
377	case PTP_PF_PEROUT:
378	case PTP_PF_PHYSYNC:
379		return -EOPNOTSUPP;
380	}
381	return 0;
382}
383
384const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = {
385	.clock_read = mv88e6165_ptp_clock_read,
386	.global_enable = mv88e6165_global_enable,
387	.global_disable = mv88e6165_global_disable,
388	.arr0_sts_reg = MV88E6165_PORT_PTP_ARR0_STS,
389	.arr1_sts_reg = MV88E6165_PORT_PTP_ARR1_STS,
390	.dep_sts_reg = MV88E6165_PORT_PTP_DEP_STS,
391	.rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
392		(1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
393		(1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
394		(1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
395		(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
396		(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
397		(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
398};
399
400const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {
401	.clock_read = mv88e6352_ptp_clock_read,
402	.ptp_enable = mv88e6352_ptp_enable,
403	.ptp_verify = mv88e6352_ptp_verify,
404	.event_work = mv88e6352_tai_event_work,
405	.port_enable = mv88e6352_hwtstamp_port_enable,
406	.port_disable = mv88e6352_hwtstamp_port_disable,
407	.n_ext_ts = 1,
408	.arr0_sts_reg = MV88E6XXX_PORT_PTP_ARR0_STS,
409	.arr1_sts_reg = MV88E6XXX_PORT_PTP_ARR1_STS,
410	.dep_sts_reg = MV88E6XXX_PORT_PTP_DEP_STS,
411	.rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
412		(1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
413		(1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
414		(1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
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),
421};
422
423const struct mv88e6xxx_ptp_ops mv88e6390_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,
430	.set_ptp_cpu_port = mv88e6390_g1_set_ptp_cpu_port,
431	.n_ext_ts = 1,
432	.arr0_sts_reg = MV88E6XXX_PORT_PTP_ARR0_STS,
433	.arr1_sts_reg = MV88E6XXX_PORT_PTP_ARR1_STS,
434	.dep_sts_reg = MV88E6XXX_PORT_PTP_DEP_STS,
435	.rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
436		(1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
437		(1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
438		(1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
439		(1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
440		(1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
441		(1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
442		(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
443		(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
444		(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
445};
446
447static u64 mv88e6xxx_ptp_clock_read(struct cyclecounter *cc)
448{
449	struct mv88e6xxx_chip *chip = cc_to_chip(cc);
450
451	if (chip->info->ops->ptp_ops->clock_read)
452		return chip->info->ops->ptp_ops->clock_read(cc);
453
454	return 0;
455}
456
457/* With a 250MHz input clock, the 32-bit timestamp counter overflows in ~17.2
458 * seconds; this task forces periodic reads so that we don't miss any.
459 */
460#define MV88E6XXX_TAI_OVERFLOW_PERIOD (HZ * 8)
461static void mv88e6xxx_ptp_overflow_check(struct work_struct *work)
462{
463	struct delayed_work *dw = to_delayed_work(work);
464	struct mv88e6xxx_chip *chip = dw_overflow_to_chip(dw);
465	struct timespec64 ts;
466
467	mv88e6xxx_ptp_gettime(&chip->ptp_clock_info, &ts);
468
469	schedule_delayed_work(&chip->overflow_work,
470			      MV88E6XXX_TAI_OVERFLOW_PERIOD);
471}
472
473int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
474{
475	const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
476	int i;
477
478	/* Set up the cycle counter */
479	chip->cc_coeffs = mv88e6xxx_cc_coeff_get(chip);
480	if (IS_ERR(chip->cc_coeffs))
481		return PTR_ERR(chip->cc_coeffs);
482
483	memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc));
484	chip->tstamp_cc.read	= mv88e6xxx_ptp_clock_read;
485	chip->tstamp_cc.mask	= CYCLECOUNTER_MASK(32);
486	chip->tstamp_cc.mult	= chip->cc_coeffs->cc_mult;
487	chip->tstamp_cc.shift	= chip->cc_coeffs->cc_shift;
488
489	timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc,
490			 ktime_to_ns(ktime_get_real()));
491
492	INIT_DELAYED_WORK(&chip->overflow_work, mv88e6xxx_ptp_overflow_check);
493	if (ptp_ops->event_work)
494		INIT_DELAYED_WORK(&chip->tai_event_work, ptp_ops->event_work);
495
496	chip->ptp_clock_info.owner = THIS_MODULE;
497	snprintf(chip->ptp_clock_info.name, sizeof(chip->ptp_clock_info.name),
498		 "%s", dev_name(chip->dev));
499
500	chip->ptp_clock_info.n_ext_ts	= ptp_ops->n_ext_ts;
501	chip->ptp_clock_info.n_per_out	= 0;
502	chip->ptp_clock_info.n_pins	= mv88e6xxx_num_gpio(chip);
503	chip->ptp_clock_info.pps	= 0;
504
505	for (i = 0; i < chip->ptp_clock_info.n_pins; ++i) {
506		struct ptp_pin_desc *ppd = &chip->pin_config[i];
507
508		snprintf(ppd->name, sizeof(ppd->name), "mv88e6xxx_gpio%d", i);
509		ppd->index = i;
510		ppd->func = PTP_PF_NONE;
511	}
512	chip->ptp_clock_info.pin_config = chip->pin_config;
513
514	chip->ptp_clock_info.max_adj    = MV88E6XXX_MAX_ADJ_PPB;
515	chip->ptp_clock_info.adjfine	= mv88e6xxx_ptp_adjfine;
516	chip->ptp_clock_info.adjtime	= mv88e6xxx_ptp_adjtime;
517	chip->ptp_clock_info.gettime64	= mv88e6xxx_ptp_gettime;
518	chip->ptp_clock_info.settime64	= mv88e6xxx_ptp_settime;
519	chip->ptp_clock_info.enable	= ptp_ops->ptp_enable;
520	chip->ptp_clock_info.verify	= ptp_ops->ptp_verify;
521	chip->ptp_clock_info.do_aux_work = mv88e6xxx_hwtstamp_work;
522
523	chip->ptp_clock_info.supported_extts_flags = PTP_RISING_EDGE |
524						     PTP_FALLING_EDGE |
525						     PTP_STRICT_FLAGS;
526
527	if (ptp_ops->set_ptp_cpu_port) {
528		struct dsa_port *dp;
529		int upstream = 0;
530		int err;
531
532		dsa_switch_for_each_user_port(dp, chip->ds) {
533			upstream = dsa_upstream_port(chip->ds, dp->index);
534			break;
535		}
536
537		err = ptp_ops->set_ptp_cpu_port(chip, upstream);
538		if (err) {
539			dev_err(chip->dev, "Failed to set PTP CPU destination port!\n");
540			return err;
541		}
542	}
543
544	chip->ptp_clock = ptp_clock_register(&chip->ptp_clock_info, chip->dev);
545	if (IS_ERR(chip->ptp_clock))
546		return PTR_ERR(chip->ptp_clock);
547
548	schedule_delayed_work(&chip->overflow_work,
549			      MV88E6XXX_TAI_OVERFLOW_PERIOD);
550
551	return 0;
552}
553
554/* This must never be called holding the register lock */
555void mv88e6xxx_ptp_free(struct mv88e6xxx_chip *chip)
556{
557	if (chip->ptp_clock) {
558		cancel_delayed_work_sync(&chip->overflow_work);
559		if (chip->info->ops->ptp_ops->event_work)
560			cancel_delayed_work_sync(&chip->tai_event_work);
561
562		ptp_clock_unregister(chip->ptp_clock);
563		chip->ptp_clock = NULL;
564	}
565}
~/ Read-only file preview.