From: Wei Fang <[email protected]> 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 <[email protected]> --- 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
