File Index
Files and directories
Sign in
FILE

ptp_clock.c

File preview with syntax highlighting.

linux-6.19.14/drivers/ptp/ptp_clock.c C
  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#include <linux/device.h>
  8#include <linux/err.h>
  9#include <linux/init.h>
 10#include <linux/kernel.h>
 11#include <linux/module.h>
 12#include <linux/posix-clock.h>
 13#include <linux/pps_kernel.h>
 14#include <linux/property.h>
 15#include <linux/slab.h>
 16#include <linux/syscalls.h>
 17#include <linux/uaccess.h>
 18#include <linux/debugfs.h>
 19#include <linux/xarray.h>
 20#include <uapi/linux/sched/types.h>
 21
 22#include "ptp_private.h"
 23
 24#define PTP_MAX_ALARMS 4
 25#define PTP_PPS_DEFAULTS (PPS_CAPTUREASSERT | PPS_OFFSETASSERT)
 26#define PTP_PPS_EVENT PPS_CAPTUREASSERT
 27#define PTP_PPS_MODE (PTP_PPS_DEFAULTS | PPS_CANWAIT | PPS_TSFMT_TSPEC)
 28
 29const struct class ptp_class = {
 30	.name = "ptp",
 31	.dev_groups = ptp_groups
 32};
 33
 34/* private globals */
 35
 36static dev_t ptp_devt;
 37
 38static DEFINE_XARRAY_ALLOC(ptp_clocks_map);
 39
 40/* time stamp event queue operations */
 41
 42static inline int queue_free(struct timestamp_event_queue *q)
 43{
 44	return PTP_MAX_TIMESTAMPS - queue_cnt(q) - 1;
 45}
 46
 47static void enqueue_external_timestamp(struct timestamp_event_queue *queue,
 48				       struct ptp_clock_event *src)
 49{
 50	struct ptp_extts_event *dst;
 51	struct timespec64 offset_ts;
 52	unsigned long flags;
 53	s64 seconds;
 54	u32 remainder;
 55
 56	if (src->type == PTP_CLOCK_EXTTS) {
 57		seconds = div_u64_rem(src->timestamp, 1000000000, &remainder);
 58	} else if (src->type == PTP_CLOCK_EXTOFF) {
 59		offset_ts = ns_to_timespec64(src->offset);
 60		seconds = offset_ts.tv_sec;
 61		remainder = offset_ts.tv_nsec;
 62	} else {
 63		WARN(1, "%s: unknown type %d\n", __func__, src->type);
 64		return;
 65	}
 66
 67	spin_lock_irqsave(&queue->lock, flags);
 68
 69	dst = &queue->buf[queue->tail];
 70	dst->index = src->index;
 71	dst->flags = PTP_EXTTS_EVENT_VALID;
 72	dst->t.sec = seconds;
 73	dst->t.nsec = remainder;
 74	if (src->type == PTP_CLOCK_EXTOFF)
 75		dst->flags |= PTP_EXT_OFFSET;
 76
 77	/* Both WRITE_ONCE() are paired with READ_ONCE() in queue_cnt() */
 78	if (!queue_free(queue))
 79		WRITE_ONCE(queue->head, (queue->head + 1) % PTP_MAX_TIMESTAMPS);
 80
 81	WRITE_ONCE(queue->tail, (queue->tail + 1) % PTP_MAX_TIMESTAMPS);
 82
 83	spin_unlock_irqrestore(&queue->lock, flags);
 84}
 85
 86/* posix clock implementation */
 87
 88static int ptp_clock_getres(struct posix_clock *pc, struct timespec64 *tp)
 89{
 90	tp->tv_sec = 0;
 91	tp->tv_nsec = 1;
 92	return 0;
 93}
 94
 95static int ptp_clock_settime(struct posix_clock *pc, const struct timespec64 *tp)
 96{
 97	struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
 98
 99	if (ptp_clock_freerun(ptp)) {
100		pr_err_ratelimited("ptp: physical clock is free running\n");
101		return -EBUSY;
102	}
103
104	if (!timespec64_valid_settod(tp))
105		return -EINVAL;
106
107	return  ptp->info->settime64(ptp->info, tp);
108}
109
110static int ptp_clock_gettime(struct posix_clock *pc, struct timespec64 *tp)
111{
112	struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
113	int err;
114
115	if (ptp->info->gettimex64)
116		err = ptp->info->gettimex64(ptp->info, tp, NULL);
117	else
118		err = ptp->info->gettime64(ptp->info, tp);
119	return err;
120}
121
122static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx)
123{
124	struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
125	struct ptp_clock_info *ops;
126	int err = -EOPNOTSUPP;
127
128	if (tx->modes & (ADJ_SETOFFSET | ADJ_FREQUENCY | ADJ_OFFSET) &&
129	    ptp_clock_freerun(ptp)) {
130		pr_err("ptp: physical clock is free running\n");
131		return -EBUSY;
132	}
133
134	ops = ptp->info;
135
136	if (tx->modes & ADJ_SETOFFSET) {
137		struct timespec64 ts, ts2;
138		ktime_t kt;
139		s64 delta;
140
141		ts.tv_sec  = tx->time.tv_sec;
142		ts.tv_nsec = tx->time.tv_usec;
143
144		if (!(tx->modes & ADJ_NANO))
145			ts.tv_nsec *= 1000;
146
147		if ((unsigned long) ts.tv_nsec >= NSEC_PER_SEC)
148			return -EINVAL;
149
150		/* Make sure the offset is valid */
151		err = ptp_clock_gettime(pc, &ts2);
152		if (err)
153			return err;
154		ts2 = timespec64_add(ts2, ts);
155		if (!timespec64_valid_settod(&ts2))
156			return -EINVAL;
157
158		kt = timespec64_to_ktime(ts);
159		delta = ktime_to_ns(kt);
160		err = ops->adjtime(ops, delta);
161	} else if (tx->modes & ADJ_FREQUENCY) {
162		long ppb = scaled_ppm_to_ppb(tx->freq);
163		if (ppb > ops->max_adj || ppb < -ops->max_adj)
164			return -ERANGE;
165		err = ops->adjfine(ops, tx->freq);
166		if (!err)
167			ptp->dialed_frequency = tx->freq;
168	} else if (tx->modes & ADJ_OFFSET) {
169		if (ops->adjphase) {
170			s32 max_phase_adj = ops->getmaxphase(ops);
171			s32 offset = tx->offset;
172
173			if (!(tx->modes & ADJ_NANO))
174				offset *= NSEC_PER_USEC;
175
176			if (offset > max_phase_adj || offset < -max_phase_adj)
177				return -ERANGE;
178
179			err = ops->adjphase(ops, offset);
180		}
181	} else if (tx->modes == 0) {
182		tx->freq = ptp->dialed_frequency;
183		err = 0;
184	}
185
186	return err;
187}
188
189static struct posix_clock_operations ptp_clock_ops = {
190	.owner		= THIS_MODULE,
191	.clock_adjtime	= ptp_clock_adjtime,
192	.clock_gettime	= ptp_clock_gettime,
193	.clock_getres	= ptp_clock_getres,
194	.clock_settime	= ptp_clock_settime,
195	.ioctl		= ptp_ioctl,
196	.open		= ptp_open,
197	.release	= ptp_release,
198	.poll		= ptp_poll,
199	.read		= ptp_read,
200};
201
202static void ptp_clock_release(struct device *dev)
203{
204	struct ptp_clock *ptp = container_of(dev, struct ptp_clock, dev);
205	struct timestamp_event_queue *tsevq;
206	unsigned long flags;
207
208	ptp_cleanup_pin_groups(ptp);
209	kfree(ptp->vclock_index);
210	mutex_destroy(&ptp->pincfg_mux);
211	mutex_destroy(&ptp->n_vclocks_mux);
212	/* Delete first entry */
213	spin_lock_irqsave(&ptp->tsevqs_lock, flags);
214	tsevq = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue,
215				 qlist);
216	list_del(&tsevq->qlist);
217	spin_unlock_irqrestore(&ptp->tsevqs_lock, flags);
218	bitmap_free(tsevq->mask);
219	kfree(tsevq);
220	debugfs_remove(ptp->debugfs_root);
221	xa_erase(&ptp_clocks_map, ptp->index);
222	kfree(ptp);
223}
224
225static int ptp_getcycles64(struct ptp_clock_info *info, struct timespec64 *ts)
226{
227	if (info->getcyclesx64)
228		return info->getcyclesx64(info, ts, NULL);
229	else
230		return info->gettime64(info, ts);
231}
232
233static int ptp_enable(struct ptp_clock_info *ptp, struct ptp_clock_request *request, int on)
234{
235	return -EOPNOTSUPP;
236}
237
238static void ptp_aux_kworker(struct kthread_work *work)
239{
240	struct ptp_clock *ptp = container_of(work, struct ptp_clock,
241					     aux_work.work);
242	struct ptp_clock_info *info = ptp->info;
243	long delay;
244
245	delay = info->do_aux_work(info);
246
247	if (delay >= 0)
248		kthread_queue_delayed_work(ptp->kworker, &ptp->aux_work, delay);
249}
250
251static ssize_t ptp_n_perout_loopback_read(struct file *filep,
252					  char __user *buffer,
253					  size_t count, loff_t *pos)
254{
255	struct ptp_clock *ptp = filep->private_data;
256	char buf[12] = {};
257
258	snprintf(buf, sizeof(buf), "%d\n", ptp->info->n_per_lp);
259
260	return simple_read_from_buffer(buffer, count, pos, buf, strlen(buf));
261}
262
263static const struct file_operations ptp_n_perout_loopback_fops = {
264	.owner	= THIS_MODULE,
265	.open	= simple_open,
266	.read	= ptp_n_perout_loopback_read,
267};
268
269static ssize_t ptp_perout_loopback_write(struct file *filep,
270					 const char __user *buffer,
271					 size_t count, loff_t *ppos)
272{
273	struct ptp_clock *ptp = filep->private_data;
274	struct ptp_clock_info *ops = ptp->info;
275	unsigned int index, enable;
276	int len, cnt, err;
277	char buf[32] = {};
278
279	if (*ppos || !count)
280		return -EINVAL;
281
282	if (count >= sizeof(buf))
283		return -ENOSPC;
284
285	len = simple_write_to_buffer(buf, sizeof(buf) - 1,
286				     ppos, buffer, count);
287	if (len < 0)
288		return len;
289
290	buf[len] = '\0';
291	cnt = sscanf(buf, "%u %u", &index, &enable);
292	if (cnt != 2)
293		return -EINVAL;
294
295	if (index >= ops->n_per_lp)
296		return -EINVAL;
297
298	if (enable != 0 && enable != 1)
299		return -EINVAL;
300
301	err = ops->perout_loopback(ops, index, enable);
302	if (err)
303		return err;
304
305	return count;
306}
307
308static const struct file_operations ptp_perout_loopback_ops = {
309	.owner   = THIS_MODULE,
310	.open    = simple_open,
311	.write	 = ptp_perout_loopback_write,
312};
313
314/* public interface */
315
316struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
317				     struct device *parent)
318{
319	struct ptp_clock *ptp;
320	struct timestamp_event_queue *queue = NULL;
321	int err, index, major = MAJOR(ptp_devt);
322	char debugfsname[16];
323	size_t size;
324
325	if (WARN_ON_ONCE(info->n_alarm > PTP_MAX_ALARMS ||
326			 (!info->gettimex64 && !info->gettime64) ||
327			 !info->settime64))
328		return ERR_PTR(-EINVAL);
329
330	/* Initialize a clock structure. */
331	ptp = kzalloc(sizeof(struct ptp_clock), GFP_KERNEL);
332	if (!ptp) {
333		err = -ENOMEM;
334		goto no_memory;
335	}
336
337	err = xa_alloc(&ptp_clocks_map, &index, ptp, xa_limit_31b,
338		       GFP_KERNEL);
339	if (err)
340		goto no_slot;
341
342	ptp->clock.ops = ptp_clock_ops;
343	ptp->info = info;
344	ptp->devid = MKDEV(major, index);
345	ptp->index = index;
346	INIT_LIST_HEAD(&ptp->tsevqs);
347	queue = kzalloc(sizeof(*queue), GFP_KERNEL);
348	if (!queue) {
349		err = -ENOMEM;
350		goto no_memory_queue;
351	}
352	list_add_tail(&queue->qlist, &ptp->tsevqs);
353	spin_lock_init(&ptp->tsevqs_lock);
354	queue->mask = bitmap_alloc(PTP_MAX_CHANNELS, GFP_KERNEL);
355	if (!queue->mask) {
356		err = -ENOMEM;
357		goto no_memory_bitmap;
358	}
359	bitmap_set(queue->mask, 0, PTP_MAX_CHANNELS);
360	spin_lock_init(&queue->lock);
361	mutex_init(&ptp->pincfg_mux);
362	mutex_init(&ptp->n_vclocks_mux);
363	init_waitqueue_head(&ptp->tsev_wq);
364
365	if (ptp->info->getcycles64 || ptp->info->getcyclesx64) {
366		ptp->has_cycles = true;
367		if (!ptp->info->getcycles64 && ptp->info->getcyclesx64)
368			ptp->info->getcycles64 = ptp_getcycles64;
369	} else {
370		/* Free running cycle counter not supported, use time. */
371		ptp->info->getcycles64 = ptp_getcycles64;
372
373		if (ptp->info->gettimex64)
374			ptp->info->getcyclesx64 = ptp->info->gettimex64;
375
376		if (ptp->info->getcrosststamp)
377			ptp->info->getcrosscycles = ptp->info->getcrosststamp;
378	}
379
380	if (!ptp->info->enable)
381		ptp->info->enable = ptp_enable;
382
383	if (ptp->info->do_aux_work) {
384		kthread_init_delayed_work(&ptp->aux_work, ptp_aux_kworker);
385		ptp->kworker = kthread_run_worker(0, "ptp%d", ptp->index);
386		if (IS_ERR(ptp->kworker)) {
387			err = PTR_ERR(ptp->kworker);
388			pr_err("failed to create ptp aux_worker %d\n", err);
389			goto kworker_err;
390		}
391	}
392
393	/* PTP virtual clock is being registered under physical clock */
394	if (parent && parent->class && parent->class->name &&
395	    strcmp(parent->class->name, "ptp") == 0)
396		ptp->is_virtual_clock = true;
397
398	if (!ptp->is_virtual_clock) {
399		ptp->max_vclocks = PTP_DEFAULT_MAX_VCLOCKS;
400
401		size = sizeof(int) * ptp->max_vclocks;
402		ptp->vclock_index = kzalloc(size, GFP_KERNEL);
403		if (!ptp->vclock_index) {
404			err = -ENOMEM;
405			goto no_mem_for_vclocks;
406		}
407	}
408
409	err = ptp_populate_pin_groups(ptp);
410	if (err)
411		goto no_pin_groups;
412
413	/* Register a new PPS source. */
414	if (info->pps) {
415		struct pps_source_info pps;
416		memset(&pps, 0, sizeof(pps));
417		snprintf(pps.name, PPS_MAX_NAME_LEN, "ptp%d", index);
418		pps.mode = PTP_PPS_MODE;
419		pps.owner = info->owner;
420		ptp->pps_source = pps_register_source(&pps, PTP_PPS_DEFAULTS);
421		if (IS_ERR(ptp->pps_source)) {
422			err = PTR_ERR(ptp->pps_source);
423			pr_err("failed to register pps source\n");
424			goto no_pps;
425		}
426		ptp->pps_source->lookup_cookie = ptp;
427	}
428
429	/* Initialize a new device of our class in our clock structure. */
430	device_initialize(&ptp->dev);
431	ptp->dev.devt = ptp->devid;
432	ptp->dev.class = &ptp_class;
433	ptp->dev.parent = parent;
434	ptp->dev.groups = ptp->pin_attr_groups;
435	ptp->dev.release = ptp_clock_release;
436	dev_set_drvdata(&ptp->dev, ptp);
437	dev_set_name(&ptp->dev, "ptp%d", ptp->index);
438
439	/* Create a posix clock and link it to the device. */
440	err = posix_clock_register(&ptp->clock, &ptp->dev);
441	if (err) {
442		if (ptp->pps_source)
443			pps_unregister_source(ptp->pps_source);
444
445		if (ptp->kworker)
446			kthread_destroy_worker(ptp->kworker);
447
448		put_device(&ptp->dev);
449
450		pr_err("failed to create posix clock\n");
451		return ERR_PTR(err);
452	}
453
454	/* Debugfs initialization */
455	snprintf(debugfsname, sizeof(debugfsname), "ptp%d", ptp->index);
456	ptp->debugfs_root = debugfs_create_dir(debugfsname, NULL);
457	if (info->n_per_lp > 0 && info->perout_loopback) {
458		debugfs_create_file("n_perout_loopback", 0400, ptp->debugfs_root,
459				    ptp, &ptp_n_perout_loopback_fops);
460		debugfs_create_file("perout_loopback", 0200, ptp->debugfs_root,
461				    ptp, &ptp_perout_loopback_ops);
462	}
463
464	return ptp;
465
466no_pps:
467	ptp_cleanup_pin_groups(ptp);
468no_pin_groups:
469	kfree(ptp->vclock_index);
470no_mem_for_vclocks:
471	if (ptp->kworker)
472		kthread_destroy_worker(ptp->kworker);
473kworker_err:
474	mutex_destroy(&ptp->pincfg_mux);
475	mutex_destroy(&ptp->n_vclocks_mux);
476	bitmap_free(queue->mask);
477no_memory_bitmap:
478	list_del(&queue->qlist);
479	kfree(queue);
480no_memory_queue:
481	xa_erase(&ptp_clocks_map, index);
482no_slot:
483	kfree(ptp);
484no_memory:
485	return ERR_PTR(err);
486}
487EXPORT_SYMBOL(ptp_clock_register);
488
489static int unregister_vclock(struct device *dev, void *data)
490{
491	struct ptp_clock *ptp = dev_get_drvdata(dev);
492
493	ptp_vclock_unregister(info_to_vclock(ptp->info));
494	return 0;
495}
496
497int ptp_clock_unregister(struct ptp_clock *ptp)
498{
499	if (ptp_vclock_in_use(ptp)) {
500		device_for_each_child(&ptp->dev, NULL, unregister_vclock);
501	}
502
503	/* Get the device to stop posix_clock_unregister() doing the last put
504	 * and freeing the structure(s)
505	 */
506	get_device(&ptp->dev);
507
508	/* Wake up any userspace waiting for an event. */
509	ptp->defunct = 1;
510	wake_up_interruptible(&ptp->tsev_wq);
511
512	/* Tear down the POSIX clock, which removes the user interface. */
513	posix_clock_unregister(&ptp->clock);
514
515	/* Disable all sources of event generation. */
516	ptp_disable_all_events(ptp);
517
518	if (ptp->kworker) {
519		kthread_cancel_delayed_work_sync(&ptp->aux_work);
520		kthread_destroy_worker(ptp->kworker);
521	}
522
523	/* Release the clock's resources. */
524	if (ptp->pps_source)
525		pps_unregister_source(ptp->pps_source);
526
527	/* The final put, normally here, will invoke ptp_clock_release(). */
528	put_device(&ptp->dev);
529
530	return 0;
531}
532EXPORT_SYMBOL(ptp_clock_unregister);
533
534void ptp_clock_event(struct ptp_clock *ptp, struct ptp_clock_event *event)
535{
536	struct timestamp_event_queue *tsevq;
537	struct pps_event_time evt;
538	unsigned long flags;
539
540	switch (event->type) {
541
542	case PTP_CLOCK_ALARM:
543		break;
544
545	case PTP_CLOCK_EXTTS:
546	case PTP_CLOCK_EXTOFF:
547		/* Enqueue timestamp on selected queues */
548		spin_lock_irqsave(&ptp->tsevqs_lock, flags);
549		list_for_each_entry(tsevq, &ptp->tsevqs, qlist) {
550			if (test_bit((unsigned int)event->index, tsevq->mask))
551				enqueue_external_timestamp(tsevq, event);
552		}
553		spin_unlock_irqrestore(&ptp->tsevqs_lock, flags);
554		wake_up_interruptible(&ptp->tsev_wq);
555		break;
556
557	case PTP_CLOCK_PPS:
558		pps_get_ts(&evt);
559		pps_event(ptp->pps_source, &evt, PTP_PPS_EVENT, NULL);
560		break;
561
562	case PTP_CLOCK_PPSUSR:
563		pps_event(ptp->pps_source, &event->pps_times,
564			  PTP_PPS_EVENT, NULL);
565		break;
566	}
567}
568EXPORT_SYMBOL(ptp_clock_event);
569
570int ptp_clock_index(struct ptp_clock *ptp)
571{
572	return ptp->index;
573}
574EXPORT_SYMBOL(ptp_clock_index);
575
576static int ptp_clock_of_node_match(struct device *dev, const void *data)
577{
578	const struct device_node *parent_np = data;
579
580	return (dev->parent && dev_of_node(dev->parent) == parent_np);
581}
582
583int ptp_clock_index_by_of_node(struct device_node *np)
584{
585	struct ptp_clock *ptp;
586	struct device *dev;
587	int phc_index;
588
589	dev = class_find_device(&ptp_class, NULL, np,
590				ptp_clock_of_node_match);
591	if (!dev)
592		return -1;
593
594	ptp = dev_get_drvdata(dev);
595	phc_index = ptp_clock_index(ptp);
596	put_device(dev);
597
598	return phc_index;
599}
600EXPORT_SYMBOL_GPL(ptp_clock_index_by_of_node);
601
602static int ptp_clock_dev_match(struct device *dev, const void *data)
603{
604	const struct device *parent = data;
605
606	return dev->parent == parent;
607}
608
609int ptp_clock_index_by_dev(struct device *parent)
610{
611	struct ptp_clock *ptp;
612	struct device *dev;
613	int phc_index;
614
615	dev = class_find_device(&ptp_class, NULL, parent,
616				ptp_clock_dev_match);
617	if (!dev)
618		return -1;
619
620	ptp = dev_get_drvdata(dev);
621	phc_index = ptp_clock_index(ptp);
622	put_device(dev);
623
624	return phc_index;
625}
626EXPORT_SYMBOL_GPL(ptp_clock_index_by_dev);
627
628int ptp_find_pin(struct ptp_clock *ptp,
629		 enum ptp_pin_function func, unsigned int chan)
630{
631	struct ptp_pin_desc *pin = NULL;
632	int i;
633
634	for (i = 0; i < ptp->info->n_pins; i++) {
635		if (ptp->info->pin_config[i].func == func &&
636		    ptp->info->pin_config[i].chan == chan) {
637			pin = &ptp->info->pin_config[i];
638			break;
639		}
640	}
641
642	return pin ? i : -1;
643}
644EXPORT_SYMBOL(ptp_find_pin);
645
646int ptp_find_pin_unlocked(struct ptp_clock *ptp,
647			  enum ptp_pin_function func, unsigned int chan)
648{
649	int result;
650
651	mutex_lock(&ptp->pincfg_mux);
652
653	result = ptp_find_pin(ptp, func, chan);
654
655	mutex_unlock(&ptp->pincfg_mux);
656
657	return result;
658}
659EXPORT_SYMBOL(ptp_find_pin_unlocked);
660
661int ptp_schedule_worker(struct ptp_clock *ptp, unsigned long delay)
662{
663	return kthread_mod_delayed_work(ptp->kworker, &ptp->aux_work, delay);
664}
665EXPORT_SYMBOL(ptp_schedule_worker);
666
667void ptp_cancel_worker_sync(struct ptp_clock *ptp)
668{
669	kthread_cancel_delayed_work_sync(&ptp->aux_work);
670}
671EXPORT_SYMBOL(ptp_cancel_worker_sync);
672
673/* module operations */
674
675static void __exit ptp_exit(void)
676{
677	class_unregister(&ptp_class);
678	unregister_chrdev_region(ptp_devt, MINORMASK + 1);
679	xa_destroy(&ptp_clocks_map);
680}
681
682static int __init ptp_init(void)
683{
684	int err;
685
686	err = class_register(&ptp_class);
687	if (err) {
688		pr_err("ptp: failed to allocate class\n");
689		return err;
690	}
691
692	err = alloc_chrdev_region(&ptp_devt, 0, MINORMASK + 1, "ptp");
693	if (err < 0) {
694		pr_err("ptp: failed to allocate device region\n");
695		goto no_region;
696	}
697
698	pr_info("PTP clock support registered\n");
699	return 0;
700
701no_region:
702	class_unregister(&ptp_class);
703	return err;
704}
705
706subsys_initcall(ptp_init);
707module_exit(ptp_exit);
708
709MODULE_AUTHOR("Richard Cochran <richardcochran@gmail.com>");
710MODULE_DESCRIPTION("PTP clocks support");
711MODULE_LICENSE("GPL");
~/ Read-only file preview.