Commit 9e682679 authored by baujc's avatar baujc Committed by Adam Wujek

wr_clocksource: Fix bug with WR clock adjustment(ns)

The previous fix didn't solved completelly this issue: Negative nano WR
time adjustement generate a big jump of the monotonic clock used in
PPSI.
The current fix solves this issue.
parent 816db7dd
...@@ -119,7 +119,9 @@ DEFINE_SPINLOCK(wrcs_lock); ...@@ -119,7 +119,9 @@ DEFINE_SPINLOCK(wrcs_lock);
static cycle_t wrcs_read(struct clocksource *cs) static cycle_t wrcs_read(struct clocksource *cs)
{ {
static uint32_t offset, last, this; static uint32_t offset, last, this, adjustOffset;
static char cntWasNeg;
int32_t ticksCounter;
unsigned long flags; unsigned long flags;
wrcs_do_stats(); wrcs_do_stats();
...@@ -133,15 +135,25 @@ static cycle_t wrcs_read(struct clocksource *cs) ...@@ -133,15 +135,25 @@ static cycle_t wrcs_read(struct clocksource *cs)
*/ */
spin_lock_irqsave(&wrcs_lock, flags); spin_lock_irqsave(&wrcs_lock, flags);
this = readl(&wrcs_ppsg->CNTR_NSEC); ticksCounter = readl(&wrcs_ppsg->CNTR_NSEC);
if ( this > NSEC_PER_SEC ) { if ( (ticksCounter & 0x8000000)!=0 ) {
/* it means that the value is negative and an adjustment is in progress */ // Negative value
this=0; /* We freeze then the time */ ticksCounter|= 0xF0000000;
if ( ! cntWasNeg ) {
/* Jump from positive to negative counter value */
adjustOffset+=-ticksCounter;
adjustOffset%=WRCS_FREQUENCY;
cntWasNeg=1;
}
} else { } else {
if (this < last) /* the counter is positive */
offset += WRCS_FREQUENCY; cntWasNeg=0;
last = this;
} }
this=(ticksCounter+adjustOffset)%WRCS_FREQUENCY;
if ( this < last) {
offset += WRCS_FREQUENCY;
}
last = this;
spin_unlock_irqrestore(&wrcs_lock, flags); spin_unlock_irqrestore(&wrcs_lock, flags);
return offset + this; return offset + this;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment