[PATCH net-next 1/7] ptp: netc: use ioread64_lo_hi/iowrite64_lo_hi for 64-bit register access

From: wei . fang

Date: Tue Jul 28 2026 - 06:42:59 EST


From: Wei Fang <wei.fang@xxxxxxx>

Replace the open-coded 64-bit register read/write sequences with
ioread64_lo_hi() and iowrite64_lo_hi() helpers. Introduce two new macros
netc_timer_rd64() and netc_timer_wr64() that wrap these helpers and use
them throughout the driver. This reduces boilerplate and makes the intent
of each operation clearer.

Signed-off-by: Wei Fang <wei.fang@xxxxxxx>
---
drivers/ptp/ptp_netc.c | 72 ++++++++++++------------------------------
1 file changed, 21 insertions(+), 51 deletions(-)

diff --git a/drivers/ptp/ptp_netc.c b/drivers/ptp/ptp_netc.c
index 94e952ee6990..78c6d235127d 100644
--- a/drivers/ptp/ptp_netc.c
+++ b/drivers/ptp/ptp_netc.c
@@ -127,6 +127,17 @@ struct netc_timer {

#define netc_timer_rd(p, o) netc_read((p)->base + (o))
#define netc_timer_wr(p, o, v) netc_write((p)->base + (o), v)
+
+/* The 64-bit timer registers consist of a low (L) and high (H) register pair.
+ * Hardware requires a strict access order: for writes, TMR_xxx_L must be
+ * written first, which latches the value into a shadow register; the write
+ * to TMR_xxx_H then atomically transfers both shadow registers into the live
+ * counter. For reads, TMR_xxx_L must be read first to capture a coherent
+ * snapshot. iowrite64_lo_hi() and ioread64_lo_hi() enforce this L-before-H
+ * ordering.
+ */
+#define netc_timer_rd64(p, o) ioread64_lo_hi((p)->base + (o))
+#define netc_timer_wr64(p, o, v) iowrite64_lo_hi(v, (p)->base + (o))
#define ptp_to_netc_timer(ptp) container_of((ptp), struct netc_timer, caps)

static const char *const timer_clk_src[] = {
@@ -136,66 +147,28 @@ static const char *const timer_clk_src[] = {

static void netc_timer_cnt_write(struct netc_timer *priv, u64 ns)
{
- u32 tmr_cnt_h = upper_32_bits(ns);
- u32 tmr_cnt_l = lower_32_bits(ns);
-
- /* Writes to the TMR_CNT_L register copies the written value
- * into the shadow TMR_CNT_L register. Writes to the TMR_CNT_H
- * register copies the values written into the shadow TMR_CNT_H
- * register. Contents of the shadow registers are copied into
- * the TMR_CNT_L and TMR_CNT_H registers following a write into
- * the TMR_CNT_H register. So the user must writes to TMR_CNT_L
- * register first. Other H/L registers should have the same
- * behavior.
- */
- netc_timer_wr(priv, NETC_TMR_CNT_L, tmr_cnt_l);
- netc_timer_wr(priv, NETC_TMR_CNT_H, tmr_cnt_h);
+ netc_timer_wr64(priv, NETC_TMR_CNT_L, ns);
}

static u64 netc_timer_offset_read(struct netc_timer *priv)
{
- u32 tmr_off_l, tmr_off_h;
- u64 offset;
-
- tmr_off_l = netc_timer_rd(priv, NETC_TMR_OFF_L);
- tmr_off_h = netc_timer_rd(priv, NETC_TMR_OFF_H);
- offset = (((u64)tmr_off_h) << 32) | tmr_off_l;
-
- return offset;
+ return netc_timer_rd64(priv, NETC_TMR_OFF_L);
}

static void netc_timer_offset_write(struct netc_timer *priv, u64 offset)
{
- u32 tmr_off_h = upper_32_bits(offset);
- u32 tmr_off_l = lower_32_bits(offset);
-
- netc_timer_wr(priv, NETC_TMR_OFF_L, tmr_off_l);
- netc_timer_wr(priv, NETC_TMR_OFF_H, tmr_off_h);
+ netc_timer_wr64(priv, NETC_TMR_OFF_L, offset);
}

static u64 netc_timer_cur_time_read(struct netc_timer *priv)
{
- u32 time_h, time_l;
- u64 ns;
-
- /* The user should read NETC_TMR_CUR_TIME_L first to
- * get correct current time.
- */
- time_l = netc_timer_rd(priv, NETC_TMR_CUR_TIME_L);
- time_h = netc_timer_rd(priv, NETC_TMR_CUR_TIME_H);
- ns = (u64)time_h << 32 | time_l;
-
- return ns;
+ return netc_timer_rd64(priv, NETC_TMR_CUR_TIME_L);
}

static void netc_timer_alarm_write(struct netc_timer *priv,
u64 alarm, int index)
{
- u32 alarm_h = upper_32_bits(alarm);
- u32 alarm_l = lower_32_bits(alarm);
-
- netc_timer_wr(priv, NETC_TMR_ALARM_L(index), alarm_l);
- netc_timer_wr(priv, NETC_TMR_ALARM_H(index), alarm_h);
+ netc_timer_wr64(priv, NETC_TMR_ALARM_L(index), alarm);
}

static u32 netc_timer_get_integral_period(struct netc_timer *priv)
@@ -497,22 +470,19 @@ static void netc_timer_handle_etts_event(struct netc_timer *priv, int index,
bool update_event)
{
struct ptp_clock_event event;
- u32 etts_l = 0, etts_h = 0;
+ u64 etts = 0;

- while (netc_timer_rd(priv, NETC_TMR_STAT) & TMR_STAT_ETS_VLD(index)) {
- etts_l = netc_timer_rd(priv, NETC_TMR_ETTS_L(index));
- etts_h = netc_timer_rd(priv, NETC_TMR_ETTS_H(index));
- }
+ while (netc_timer_rd(priv, NETC_TMR_STAT) & TMR_STAT_ETS_VLD(index))
+ etts = netc_timer_rd64(priv, NETC_TMR_ETTS_L(index));

/* Invalid time stamp */
- if (!etts_l && !etts_h)
+ if (!etts)
return;

if (update_event) {
event.type = PTP_CLOCK_EXTTS;
event.index = index;
- event.timestamp = (u64)etts_h << 32;
- event.timestamp |= etts_l;
+ event.timestamp = etts;
ptp_clock_event(priv->clock, &event);
}
}
--
2.34.1