Commit 882e57cb authored by Horatiu Vultur's avatar Horatiu Vultur Committed by Jakub Kicinski
Browse files

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: 7d272e63 ("net: phy: mscc: timestamping and PHC support")
Signed-off-by: default avatarHoratiu Vultur <horatiu.vultur@microchip.com>
Reviewed-by: default avatarVadim Fedorenko <vadim.fedorenko@linux.dev>
Reviewed-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20250825065543.2916334-1-horatiu.vultur@microchip.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent e81a7f65
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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;
+1 −3
Original line number Diff line number Diff line
@@ -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 */
+21 −13
Original line number Diff line number Diff line
@@ -1298,7 +1298,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;
@@ -1515,17 +1514,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)
@@ -1552,6 +1541,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;
@@ -1612,7 +1611,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)