On Tue, Jun 15, 2021 at 05:45:08PM +0800, Yangbo Lu wrote:
diff --git a/drivers/ptp/Makefile b/drivers/ptp/Makefile index 8673d1743faa..3c6a905760e2 100644 --- a/drivers/ptp/Makefile +++ b/drivers/ptp/Makefile @@ -3,7 +3,7 @@ # Makefile for PTP 1588 clock support. # -ptp-y := ptp_clock.o ptp_chardev.o ptp_sysfs.o +ptp-y := ptp_clock.o ptp_vclock.o ptp_chardev.o ptp_sysfs.o
Nit: Please place ptp_vclock.o at the end of the list.
ptp_kvm-$(CONFIG_X86) := ptp_kvm_x86.o ptp_kvm_common.o ptp_kvm-$(CONFIG_HAVE_ARM_SMCCC) := ptp_kvm_arm.o ptp_kvm_common.o obj-$(CONFIG_PTP_1588_CLOCK) += ptp.o
diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h index 6b97155148f1..3f388d63904c 100644 --- a/drivers/ptp/ptp_private.h +++ b/drivers/ptp/ptp_private.h @@ -48,6 +48,20 @@ struct ptp_clock { struct kthread_delayed_work aux_work; }; +#define info_to_vclock(d) container_of((d), struct ptp_vclock, info) +#define cc_to_vclock(d) container_of((d), struct ptp_vclock, cc) +#define dw_to_vclock(d) container_of((d), struct ptp_vclock, refresh_work)
+struct ptp_vclock {
- struct ptp_clock *pclock;
- struct ptp_clock_info info;
- struct ptp_clock *clock;
- struct cyclecounter cc;
- struct timecounter tc;
- spinlock_t lock; /* protects tc/cc */
- struct delayed_work refresh_work;
Can we please have a kthread worker here instead of work?
Experience shows that plain work can be delayed for a long, long time on busy systems.
+};
/*
- The function queue_cnt() is safe for readers to call without
- holding q->lock. Readers use this function to verify that the queue
@@ -89,4 +103,6 @@ extern const struct attribute_group *ptp_groups[]; int ptp_populate_pin_groups(struct ptp_clock *ptp); void ptp_cleanup_pin_groups(struct ptp_clock *ptp); +struct ptp_vclock *ptp_vclock_register(struct ptp_clock *pclock); +void ptp_vclock_unregister(struct ptp_vclock *vclock); #endif
diff --git a/drivers/ptp/ptp_vclock.c b/drivers/ptp/ptp_vclock.c new file mode 100644 index 000000000000..b8f500677314 --- /dev/null +++ b/drivers/ptp/ptp_vclock.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/*
- PTP virtual clock driver
- Copyright 2021 NXP
- */
+#include <linux/slab.h> +#include "ptp_private.h"
+#define PTP_VCLOCK_CC_MULT (1 << 31) +#define PTP_VCLOCK_CC_SHIFT 31
These two are okay, but ...
+#define PTP_VCLOCK_CC_MULT_NUM (1 << 9) +#define PTP_VCLOCK_CC_MULT_DEM 15625ULL
the similarity of naming is confusing for these two. They are only used in the .adjfine method. How about this?
PTP_VCLOCK_FADJ_NUMERATOR, or even PTP_VCLOCK_FADJ_SHIFT (see below) PTP_VCLOCK_FADJ_DENOMINATOR
+#define PTP_VCLOCK_CC_REFRESH_INTERVAL (HZ * 2)
Consider dropping CC from the name. PTP_VCLOCK_REFRESH_INTERVAL sounds good to me.
+static int ptp_vclock_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) +{
- struct ptp_vclock *vclock = info_to_vclock(ptp);
- unsigned long flags;
- s64 adj;
- adj = (s64)scaled_ppm * PTP_VCLOCK_CC_MULT_NUM;
Rather than
scaled_ppm * (1 << 9)
I suggest
scaled_ppm << 9
instead. I suppose a good compiler would replace the multiplication with a bit shift, but it never hurts to spell it out.
- adj = div_s64(adj, PTP_VCLOCK_CC_MULT_DEM);
- spin_lock_irqsave(&vclock->lock, flags);
- timecounter_read(&vclock->tc);
- vclock->cc.mult = PTP_VCLOCK_CC_MULT + adj;
- spin_unlock_irqrestore(&vclock->lock, flags);
- return 0;
+}
Thanks, Richard