]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
phy: mscc: Fix when PTP clock is register and unregister
authorHoratiu Vultur <horatiu.vultur@microchip.com>
Mon, 25 Aug 2025 06:55:43 +0000 (08:55 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 4 Sep 2025 13:31:48 +0000 (15:31 +0200)
[ Upstream commit 882e57cbc7204662f6c5672d5b04336c1d790b03 ]

It looks like that every time when the interface was set down and up the
driver was creating a new ptp clock. On top of this the function
ptp_clock_unregister was never called.
Therefore fix this by calling ptp_clock_register and initialize the
mii_ts struct inside the probe function and call ptp_clock_unregister when
driver is removed.

Fixes: 7d272e63e0979d ("net: phy: mscc: timestamping and PHC support")
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20250825065543.2916334-1-horatiu.vultur@microchip.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/phy/mscc/mscc.h
drivers/net/phy/mscc/mscc_main.c
drivers/net/phy/mscc/mscc_ptp.c

index 58c6d47fbe046dbfc6cd1e361c7ac1da34852f9b..2bfe314ef881c30510110cb2a1fb9846e46ae7b1 100644 (file)
@@ -481,6 +481,7 @@ static inline void vsc8584_config_macsec_intr(struct phy_device *phydev)
 void vsc85xx_link_change_notify(struct phy_device *phydev);
 void vsc8584_config_ts_intr(struct phy_device *phydev);
 int vsc8584_ptp_init(struct phy_device *phydev);
+void vsc8584_ptp_deinit(struct phy_device *phydev);
 int vsc8584_ptp_probe_once(struct phy_device *phydev);
 int vsc8584_ptp_probe(struct phy_device *phydev);
 irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev);
@@ -495,6 +496,9 @@ static inline int vsc8584_ptp_init(struct phy_device *phydev)
 {
        return 0;
 }
+static inline void vsc8584_ptp_deinit(struct phy_device *phydev)
+{
+}
 static inline int vsc8584_ptp_probe_once(struct phy_device *phydev)
 {
        return 0;
index 42cafa68c40098744a67723c151fecf5f1b0e6c1..19983b206405c6d5480d7e04e3fe976c3e0692a7 100644 (file)
@@ -2337,9 +2337,7 @@ static int vsc85xx_probe(struct phy_device *phydev)
 
 static void vsc85xx_remove(struct phy_device *phydev)
 {
-       struct vsc8531_private *priv = phydev->priv;
-
-       skb_queue_purge(&priv->rx_skbs_list);
+       vsc8584_ptp_deinit(phydev);
 }
 
 /* Microsemi VSC85xx PHYs */
index 80992827a3bdd1ce0ae1b603d5eda4f9c8f7a8ec..920f35f8f84e71d87de5ecceccbbf3819737ebaf 100644 (file)
@@ -1295,7 +1295,6 @@ static void vsc8584_set_input_clk_configured(struct phy_device *phydev)
 
 static int __vsc8584_init_ptp(struct phy_device *phydev)
 {
-       struct vsc8531_private *vsc8531 = phydev->priv;
        static const u32 ltc_seq_e[] = { 0, 400000, 0, 0, 0 };
        static const u8  ltc_seq_a[] = { 8, 6, 5, 4, 2 };
        u32 val;
@@ -1512,17 +1511,7 @@ static int __vsc8584_init_ptp(struct phy_device *phydev)
 
        vsc85xx_ts_eth_cmp1_sig(phydev);
 
-       vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
-       vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
-       vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
-       vsc8531->mii_ts.ts_info  = vsc85xx_ts_info;
-       phydev->mii_ts = &vsc8531->mii_ts;
-
-       memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
-
-       vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
-                                                    &phydev->mdio.dev);
-       return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
+       return 0;
 }
 
 void vsc8584_config_ts_intr(struct phy_device *phydev)
@@ -1549,6 +1538,16 @@ int vsc8584_ptp_init(struct phy_device *phydev)
        return 0;
 }
 
+void vsc8584_ptp_deinit(struct phy_device *phydev)
+{
+       struct vsc8531_private *vsc8531 = phydev->priv;
+
+       if (vsc8531->ptp->ptp_clock) {
+               ptp_clock_unregister(vsc8531->ptp->ptp_clock);
+               skb_queue_purge(&vsc8531->rx_skbs_list);
+       }
+}
+
 irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev)
 {
        struct vsc8531_private *priv = phydev->priv;
@@ -1609,7 +1608,16 @@ int vsc8584_ptp_probe(struct phy_device *phydev)
 
        vsc8531->ptp->phydev = phydev;
 
-       return 0;
+       vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
+       vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
+       vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
+       vsc8531->mii_ts.ts_info  = vsc85xx_ts_info;
+       phydev->mii_ts = &vsc8531->mii_ts;
+
+       memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
+       vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
+                                                    &phydev->mdio.dev);
+       return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
 }
 
 int vsc8584_ptp_probe_once(struct phy_device *phydev)