net: stmmac: ensure PTP time register reads are consistent
commit 80d4609008e6d696a279e39ae7458c916fcd44c1 upstream. Even if protected from preemption and interrupts, a small time window remains when the 2 register reads could return inconsistent values, each time the "seconds" register changes. This could lead to an about 1-second error in the reported time. Add logic to ensure the "seconds" and "nanoseconds" values are consistent. Fixes: 92ba6888510c ("stmmac: add the support for PTP hw clock driver") Signed-off-by: Yannick Vignon <yannick.vignon@nxp.com> Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Link: https://lore.kernel.org/r/20220203160025.750632-1-yannick.vignon@oss.nxp.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
41df2da2c1
commit
9ea0185361
@ -142,15 +142,20 @@ static int adjust_systime(void __iomem *ioaddr, u32 sec, u32 nsec,
|
||||
|
||||
static void get_systime(void __iomem *ioaddr, u64 *systime)
|
||||
{
|
||||
u64 ns;
|
||||
u64 ns, sec0, sec1;
|
||||
|
||||
/* Get the TSSS value */
|
||||
ns = readl(ioaddr + PTP_STNSR);
|
||||
/* Get the TSS and convert sec time value to nanosecond */
|
||||
ns += readl(ioaddr + PTP_STSR) * 1000000000ULL;
|
||||
/* Get the TSS value */
|
||||
sec1 = readl_relaxed(ioaddr + PTP_STSR);
|
||||
do {
|
||||
sec0 = sec1;
|
||||
/* Get the TSSS value */
|
||||
ns = readl_relaxed(ioaddr + PTP_STNSR);
|
||||
/* Get the TSS value */
|
||||
sec1 = readl_relaxed(ioaddr + PTP_STSR);
|
||||
} while (sec0 != sec1);
|
||||
|
||||
if (systime)
|
||||
*systime = ns;
|
||||
*systime = ns + (sec1 * 1000000000ULL);
|
||||
}
|
||||
|
||||
const struct stmmac_hwtimestamp stmmac_ptp = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user