Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

phy: mscc: Fix when PTP clock is register and unregister

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>

authored by

Horatiu Vultur and committed by
Jakub Kicinski
882e57cb e81a7f65

+26 -16
+4
drivers/net/phy/mscc/mscc.h
··· 481 481 void vsc85xx_link_change_notify(struct phy_device *phydev); 482 482 void vsc8584_config_ts_intr(struct phy_device *phydev); 483 483 int vsc8584_ptp_init(struct phy_device *phydev); 484 + void vsc8584_ptp_deinit(struct phy_device *phydev); 484 485 int vsc8584_ptp_probe_once(struct phy_device *phydev); 485 486 int vsc8584_ptp_probe(struct phy_device *phydev); 486 487 irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev); ··· 495 494 static inline int vsc8584_ptp_init(struct phy_device *phydev) 496 495 { 497 496 return 0; 497 + } 498 + static inline void vsc8584_ptp_deinit(struct phy_device *phydev) 499 + { 498 500 } 499 501 static inline int vsc8584_ptp_probe_once(struct phy_device *phydev) 500 502 {
+1 -3
drivers/net/phy/mscc/mscc_main.c
··· 2337 2337 2338 2338 static void vsc85xx_remove(struct phy_device *phydev) 2339 2339 { 2340 - struct vsc8531_private *priv = phydev->priv; 2341 - 2342 - skb_queue_purge(&priv->rx_skbs_list); 2340 + vsc8584_ptp_deinit(phydev); 2343 2341 } 2344 2342 2345 2343 /* Microsemi VSC85xx PHYs */
+21 -13
drivers/net/phy/mscc/mscc_ptp.c
··· 1298 1298 1299 1299 static int __vsc8584_init_ptp(struct phy_device *phydev) 1300 1300 { 1301 - struct vsc8531_private *vsc8531 = phydev->priv; 1302 1301 static const u32 ltc_seq_e[] = { 0, 400000, 0, 0, 0 }; 1303 1302 static const u8 ltc_seq_a[] = { 8, 6, 5, 4, 2 }; 1304 1303 u32 val; ··· 1514 1515 1515 1516 vsc85xx_ts_eth_cmp1_sig(phydev); 1516 1517 1517 - vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp; 1518 - vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp; 1519 - vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp; 1520 - vsc8531->mii_ts.ts_info = vsc85xx_ts_info; 1521 - phydev->mii_ts = &vsc8531->mii_ts; 1522 - 1523 - memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps)); 1524 - 1525 - vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps, 1526 - &phydev->mdio.dev); 1527 - return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock); 1518 + return 0; 1528 1519 } 1529 1520 1530 1521 void vsc8584_config_ts_intr(struct phy_device *phydev) ··· 1539 1550 } 1540 1551 1541 1552 return 0; 1553 + } 1554 + 1555 + void vsc8584_ptp_deinit(struct phy_device *phydev) 1556 + { 1557 + struct vsc8531_private *vsc8531 = phydev->priv; 1558 + 1559 + if (vsc8531->ptp->ptp_clock) { 1560 + ptp_clock_unregister(vsc8531->ptp->ptp_clock); 1561 + skb_queue_purge(&vsc8531->rx_skbs_list); 1562 + } 1542 1563 } 1543 1564 1544 1565 irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev) ··· 1611 1612 1612 1613 vsc8531->ptp->phydev = phydev; 1613 1614 1614 - return 0; 1615 + vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp; 1616 + vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp; 1617 + vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp; 1618 + vsc8531->mii_ts.ts_info = vsc85xx_ts_info; 1619 + phydev->mii_ts = &vsc8531->mii_ts; 1620 + 1621 + memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps)); 1622 + vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps, 1623 + &phydev->mdio.dev); 1624 + return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock); 1615 1625 } 1616 1626 1617 1627 int vsc8584_ptp_probe_once(struct phy_device *phydev)