diff mbox series

[net-next] ptp: ocp: Add ptp_ocp_adjtime_coarse for large adjustments

Message ID 20220228203957.367371-1-jonathan.lemon@gmail.com (mailing list archive)
State Accepted
Commit 90f8f4c0e3cebd541deaa45cf0e470bb9810dd4f
Delegated to: Netdev Maintainers
Headers show
Series [net-next] ptp: ocp: Add ptp_ocp_adjtime_coarse for large adjustments | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Single patches do not need cover letters
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers success CCed 4 of 4 maintainers
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 49 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Jonathan Lemon Feb. 28, 2022, 8:39 p.m. UTC
In ("ptp: ocp: Have FPGA fold in ns adjustment for adjtime."), the
ns adjustment was written to the FPGA register, so the clock could
accurately perform adjustments.

However, the adjtime() call passes in a s64, while the clock adjustment
registers use a s32.  When trying to perform adjustments with a large
value (37 sec), things fail.

Examine the incoming delta, and if larger than 1 sec, use the original
(coarse) adjustment method.  If smaller than 1 sec, then allow the
FPGA to fold in the changes over a 1 second window.

Fixes: 6d59d4fa1789 ("ptp: ocp: Have FPGA fold in ns adjustment for adjtime.")
Signed-off-by: Jonathan Lemon <jonathan.lemon@gmail.com>
---
 drivers/ptp/ptp_ocp.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

Comments

Richard Cochran March 1, 2022, 12:51 p.m. UTC | #1
On Mon, Feb 28, 2022 at 12:39:57PM -0800, Jonathan Lemon wrote:
> In ("ptp: ocp: Have FPGA fold in ns adjustment for adjtime."), the
> ns adjustment was written to the FPGA register, so the clock could
> accurately perform adjustments.
> 
> However, the adjtime() call passes in a s64, while the clock adjustment
> registers use a s32.  When trying to perform adjustments with a large
> value (37 sec), things fail.
> 
> Examine the incoming delta, and if larger than 1 sec, use the original
> (coarse) adjustment method.  If smaller than 1 sec, then allow the
> FPGA to fold in the changes over a 1 second window.
> 
> Fixes: 6d59d4fa1789 ("ptp: ocp: Have FPGA fold in ns adjustment for adjtime.")
> Signed-off-by: Jonathan Lemon <jonathan.lemon@gmail.com>

Acked-by: Richard Cochran <richardcochran@gmail.com>
Jakub Kicinski March 2, 2022, 2:21 a.m. UTC | #2
On Mon, 28 Feb 2022 12:39:57 -0800 Jonathan Lemon wrote:
> In ("ptp: ocp: Have FPGA fold in ns adjustment for adjtime."), the
> ns adjustment was written to the FPGA register, so the clock could
> accurately perform adjustments.
> 
> However, the adjtime() call passes in a s64, while the clock adjustment
> registers use a s32.  When trying to perform adjustments with a large
> value (37 sec), things fail.
> 
> Examine the incoming delta, and if larger than 1 sec, use the original
> (coarse) adjustment method.  If smaller than 1 sec, then allow the
> FPGA to fold in the changes over a 1 second window.
> 
> Fixes: 6d59d4fa1789 ("ptp: ocp: Have FPGA fold in ns adjustment for adjtime.")
> Signed-off-by: Jonathan Lemon <jonathan.lemon@gmail.com>

This one's tagged for net-next - do you intend for it to go to net-next,
or is that a typo?
Jonathan Lemon March 2, 2022, 4:48 p.m. UTC | #3
On Tue, Mar 01, 2022 at 06:21:53PM -0800, Jakub Kicinski wrote:
> On Mon, 28 Feb 2022 12:39:57 -0800 Jonathan Lemon wrote:
> > In ("ptp: ocp: Have FPGA fold in ns adjustment for adjtime."), the
> > ns adjustment was written to the FPGA register, so the clock could
> > accurately perform adjustments.
> > 
> > However, the adjtime() call passes in a s64, while the clock adjustment
> > registers use a s32.  When trying to perform adjustments with a large
> > value (37 sec), things fail.
> > 
> > Examine the incoming delta, and if larger than 1 sec, use the original
> > (coarse) adjustment method.  If smaller than 1 sec, then allow the
> > FPGA to fold in the changes over a 1 second window.
> > 
> > Fixes: 6d59d4fa1789 ("ptp: ocp: Have FPGA fold in ns adjustment for adjtime.")
> > Signed-off-by: Jonathan Lemon <jonathan.lemon@gmail.com>
> 
> This one's tagged for net-next - do you intend for it to go to net-next,
> or is that a typo?

I build and test net-next, so that was my target.
Jakub Kicinski March 2, 2022, 5:56 p.m. UTC | #4
On Wed, 2 Mar 2022 08:48:00 -0800 Jonathan Lemon wrote:
> > This one's tagged for net-next - do you intend for it to go to net-next,
> > or is that a typo?  
> 
> I build and test net-next, so that was my target.

You should develop fixes against the current tree, not -next trees.
patchwork-bot+netdevbpf@kernel.org March 2, 2022, 6 p.m. UTC | #5
Hello:

This patch was applied to netdev/net.git (master)
by Jakub Kicinski <kuba@kernel.org>:

On Mon, 28 Feb 2022 12:39:57 -0800 you wrote:
> In ("ptp: ocp: Have FPGA fold in ns adjustment for adjtime."), the
> ns adjustment was written to the FPGA register, so the clock could
> accurately perform adjustments.
> 
> However, the adjtime() call passes in a s64, while the clock adjustment
> registers use a s32.  When trying to perform adjustments with a large
> value (37 sec), things fail.
> 
> [...]

Here is the summary with links:
  - [net-next] ptp: ocp: Add ptp_ocp_adjtime_coarse for large adjustments
    https://git.kernel.org/netdev/net/c/90f8f4c0e3ce

You are awesome, thank you!
diff mbox series

Patch

diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
index 0f1b5a7d2a89..17ad5f0d13b2 100644
--- a/drivers/ptp/ptp_ocp.c
+++ b/drivers/ptp/ptp_ocp.c
@@ -607,7 +607,7 @@  ptp_ocp_settime(struct ptp_clock_info *ptp_info, const struct timespec64 *ts)
 }
 
 static void
-__ptp_ocp_adjtime_locked(struct ptp_ocp *bp, u64 adj_val)
+__ptp_ocp_adjtime_locked(struct ptp_ocp *bp, u32 adj_val)
 {
 	u32 select, ctrl;
 
@@ -615,7 +615,7 @@  __ptp_ocp_adjtime_locked(struct ptp_ocp *bp, u64 adj_val)
 	iowrite32(OCP_SELECT_CLK_REG, &bp->reg->select);
 
 	iowrite32(adj_val, &bp->reg->offset_ns);
-	iowrite32(adj_val & 0x7f, &bp->reg->offset_window_ns);
+	iowrite32(NSEC_PER_SEC, &bp->reg->offset_window_ns);
 
 	ctrl = OCP_CTRL_ADJUST_OFFSET | OCP_CTRL_ENABLE;
 	iowrite32(ctrl, &bp->reg->ctrl);
@@ -624,6 +624,22 @@  __ptp_ocp_adjtime_locked(struct ptp_ocp *bp, u64 adj_val)
 	iowrite32(select >> 16, &bp->reg->select);
 }
 
+static void
+ptp_ocp_adjtime_coarse(struct ptp_ocp *bp, u64 delta_ns)
+{
+	struct timespec64 ts;
+	unsigned long flags;
+	int err;
+
+	spin_lock_irqsave(&bp->lock, flags);
+	err = __ptp_ocp_gettime_locked(bp, &ts, NULL);
+	if (likely(!err)) {
+		timespec64_add_ns(&ts, delta_ns);
+		__ptp_ocp_settime_locked(bp, &ts);
+	}
+	spin_unlock_irqrestore(&bp->lock, flags);
+}
+
 static int
 ptp_ocp_adjtime(struct ptp_clock_info *ptp_info, s64 delta_ns)
 {
@@ -631,6 +647,11 @@  ptp_ocp_adjtime(struct ptp_clock_info *ptp_info, s64 delta_ns)
 	unsigned long flags;
 	u32 adj_ns, sign;
 
+	if (delta_ns > NSEC_PER_SEC || -delta_ns > NSEC_PER_SEC) {
+		ptp_ocp_adjtime_coarse(bp, delta_ns);
+		return 0;
+	}
+
 	sign = delta_ns < 0 ? BIT(31) : 0;
 	adj_ns = sign ? -delta_ns : delta_ns;