xref: /openbmc/linux/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c (revision fac59652993f075d57860769c99045b3ca18780d)
14fa9c49fSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
292ba6888SRayagond Kokatanur /*******************************************************************************
392ba6888SRayagond Kokatanur   PTP 1588 clock using the STMMAC.
492ba6888SRayagond Kokatanur 
592ba6888SRayagond Kokatanur   Copyright (C) 2013  Vayavya Labs Pvt Ltd
692ba6888SRayagond Kokatanur 
792ba6888SRayagond Kokatanur 
892ba6888SRayagond Kokatanur   Author: Rayagond Kokatanur <rayagond@vayavyalabs.com>
992ba6888SRayagond Kokatanur *******************************************************************************/
1092ba6888SRayagond Kokatanur #include "stmmac.h"
1192ba6888SRayagond Kokatanur #include "stmmac_ptp.h"
12341f67e4STan Tee Min #include "dwmac4.h"
1392ba6888SRayagond Kokatanur 
1492ba6888SRayagond Kokatanur /**
1592ba6888SRayagond Kokatanur  * stmmac_adjust_freq
1692ba6888SRayagond Kokatanur  *
1792ba6888SRayagond Kokatanur  * @ptp: pointer to ptp_clock_info structure
182d96099fSJacob Keller  * @scaled_ppm: desired period change in scaled parts per million
1992ba6888SRayagond Kokatanur  *
2092ba6888SRayagond Kokatanur  * Description: this function will adjust the frequency of hardware clock.
212d96099fSJacob Keller  *
222d96099fSJacob Keller  * Scaled parts per million is ppm with a 16-bit binary fractional field.
2392ba6888SRayagond Kokatanur  */
stmmac_adjust_freq(struct ptp_clock_info * ptp,long scaled_ppm)242d96099fSJacob Keller static int stmmac_adjust_freq(struct ptp_clock_info *ptp, long scaled_ppm)
2592ba6888SRayagond Kokatanur {
2692ba6888SRayagond Kokatanur 	struct stmmac_priv *priv =
2792ba6888SRayagond Kokatanur 	    container_of(ptp, struct stmmac_priv, ptp_clock_ops);
2892ba6888SRayagond Kokatanur 	unsigned long flags;
292d96099fSJacob Keller 	u32 addend;
3092ba6888SRayagond Kokatanur 
312d96099fSJacob Keller 	addend = adjust_by_scaled_ppm(priv->default_addend, scaled_ppm);
3292ba6888SRayagond Kokatanur 
33642436a1SYannick Vignon 	write_lock_irqsave(&priv->ptp_lock, flags);
34cc4c9001SJose Abreu 	stmmac_config_addend(priv, priv->ptpaddr, addend);
35642436a1SYannick Vignon 	write_unlock_irqrestore(&priv->ptp_lock, flags);
3692ba6888SRayagond Kokatanur 
3792ba6888SRayagond Kokatanur 	return 0;
3892ba6888SRayagond Kokatanur }
3992ba6888SRayagond Kokatanur 
4092ba6888SRayagond Kokatanur /**
4192ba6888SRayagond Kokatanur  * stmmac_adjust_time
4292ba6888SRayagond Kokatanur  *
4392ba6888SRayagond Kokatanur  * @ptp: pointer to ptp_clock_info structure
4492ba6888SRayagond Kokatanur  * @delta: desired change in nanoseconds
4592ba6888SRayagond Kokatanur  *
4692ba6888SRayagond Kokatanur  * Description: this function will shift/adjust the hardware clock time.
4792ba6888SRayagond Kokatanur  */
stmmac_adjust_time(struct ptp_clock_info * ptp,s64 delta)4892ba6888SRayagond Kokatanur static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta)
4992ba6888SRayagond Kokatanur {
5092ba6888SRayagond Kokatanur 	struct stmmac_priv *priv =
5192ba6888SRayagond Kokatanur 	    container_of(ptp, struct stmmac_priv, ptp_clock_ops);
5292ba6888SRayagond Kokatanur 	unsigned long flags;
5392ba6888SRayagond Kokatanur 	u32 sec, nsec;
5492ba6888SRayagond Kokatanur 	u32 quotient, reminder;
5592ba6888SRayagond Kokatanur 	int neg_adj = 0;
56e9e37200SXiaoliang Yang 	bool xmac, est_rst = false;
57e9e37200SXiaoliang Yang 	int ret;
584bb7aff9SJose Abreu 
594bb7aff9SJose Abreu 	xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
6092ba6888SRayagond Kokatanur 
6192ba6888SRayagond Kokatanur 	if (delta < 0) {
6292ba6888SRayagond Kokatanur 		neg_adj = 1;
6392ba6888SRayagond Kokatanur 		delta = -delta;
6492ba6888SRayagond Kokatanur 	}
6592ba6888SRayagond Kokatanur 
6692ba6888SRayagond Kokatanur 	quotient = div_u64_rem(delta, 1000000000ULL, &reminder);
6792ba6888SRayagond Kokatanur 	sec = quotient;
6892ba6888SRayagond Kokatanur 	nsec = reminder;
6992ba6888SRayagond Kokatanur 
70e9e37200SXiaoliang Yang 	/* If EST is enabled, disabled it before adjust ptp time. */
71e9e37200SXiaoliang Yang 	if (priv->plat->est && priv->plat->est->enable) {
72e9e37200SXiaoliang Yang 		est_rst = true;
73*b538fefeSXiaolei Wang 		mutex_lock(&priv->est_lock);
74e9e37200SXiaoliang Yang 		priv->plat->est->enable = false;
75e9e37200SXiaoliang Yang 		stmmac_est_configure(priv, priv->ioaddr, priv->plat->est,
76e9e37200SXiaoliang Yang 				     priv->plat->clk_ptp_rate);
77*b538fefeSXiaolei Wang 		mutex_unlock(&priv->est_lock);
78e9e37200SXiaoliang Yang 	}
79e9e37200SXiaoliang Yang 
80642436a1SYannick Vignon 	write_lock_irqsave(&priv->ptp_lock, flags);
814bb7aff9SJose Abreu 	stmmac_adjust_systime(priv, priv->ptpaddr, sec, nsec, neg_adj, xmac);
82642436a1SYannick Vignon 	write_unlock_irqrestore(&priv->ptp_lock, flags);
8392ba6888SRayagond Kokatanur 
84e9e37200SXiaoliang Yang 	/* Caculate new basetime and re-configured EST after PTP time adjust. */
85e9e37200SXiaoliang Yang 	if (est_rst) {
86e9e37200SXiaoliang Yang 		struct timespec64 current_time, time;
87e9e37200SXiaoliang Yang 		ktime_t current_time_ns, basetime;
88e9e37200SXiaoliang Yang 		u64 cycle_time;
89e9e37200SXiaoliang Yang 
90*b538fefeSXiaolei Wang 		mutex_lock(&priv->est_lock);
91e9e37200SXiaoliang Yang 		priv->ptp_clock_ops.gettime64(&priv->ptp_clock_ops, &current_time);
92e9e37200SXiaoliang Yang 		current_time_ns = timespec64_to_ktime(current_time);
93e9e37200SXiaoliang Yang 		time.tv_nsec = priv->plat->est->btr_reserve[0];
94e9e37200SXiaoliang Yang 		time.tv_sec = priv->plat->est->btr_reserve[1];
95e9e37200SXiaoliang Yang 		basetime = timespec64_to_ktime(time);
96eccffcf4SXiaoliang Yang 		cycle_time = (u64)priv->plat->est->ctr[1] * NSEC_PER_SEC +
97e9e37200SXiaoliang Yang 			     priv->plat->est->ctr[0];
98e9e37200SXiaoliang Yang 		time = stmmac_calc_tas_basetime(basetime,
99e9e37200SXiaoliang Yang 						current_time_ns,
100e9e37200SXiaoliang Yang 						cycle_time);
101e9e37200SXiaoliang Yang 
102e9e37200SXiaoliang Yang 		priv->plat->est->btr[0] = (u32)time.tv_nsec;
103e9e37200SXiaoliang Yang 		priv->plat->est->btr[1] = (u32)time.tv_sec;
104e9e37200SXiaoliang Yang 		priv->plat->est->enable = true;
105e9e37200SXiaoliang Yang 		ret = stmmac_est_configure(priv, priv->ioaddr, priv->plat->est,
106e9e37200SXiaoliang Yang 					   priv->plat->clk_ptp_rate);
107*b538fefeSXiaolei Wang 		mutex_unlock(&priv->est_lock);
108e9e37200SXiaoliang Yang 		if (ret)
109e9e37200SXiaoliang Yang 			netdev_err(priv->dev, "failed to configure EST\n");
110e9e37200SXiaoliang Yang 	}
111e9e37200SXiaoliang Yang 
11292ba6888SRayagond Kokatanur 	return 0;
11392ba6888SRayagond Kokatanur }
11492ba6888SRayagond Kokatanur 
11592ba6888SRayagond Kokatanur /**
11692ba6888SRayagond Kokatanur  * stmmac_get_time
11792ba6888SRayagond Kokatanur  *
11892ba6888SRayagond Kokatanur  * @ptp: pointer to ptp_clock_info structure
11992ba6888SRayagond Kokatanur  * @ts: pointer to hold time/result
12092ba6888SRayagond Kokatanur  *
12192ba6888SRayagond Kokatanur  * Description: this function will read the current time from the
12292ba6888SRayagond Kokatanur  * hardware clock and store it in @ts.
12392ba6888SRayagond Kokatanur  */
stmmac_get_time(struct ptp_clock_info * ptp,struct timespec64 * ts)1243f6c4654SRichard Cochran static int stmmac_get_time(struct ptp_clock_info *ptp, struct timespec64 *ts)
12592ba6888SRayagond Kokatanur {
12692ba6888SRayagond Kokatanur 	struct stmmac_priv *priv =
12792ba6888SRayagond Kokatanur 	    container_of(ptp, struct stmmac_priv, ptp_clock_ops);
12892ba6888SRayagond Kokatanur 	unsigned long flags;
1291f5d861fSNathan Chancellor 	u64 ns = 0;
13092ba6888SRayagond Kokatanur 
131642436a1SYannick Vignon 	read_lock_irqsave(&priv->ptp_lock, flags);
132cc4c9001SJose Abreu 	stmmac_get_systime(priv, priv->ptpaddr, &ns);
133642436a1SYannick Vignon 	read_unlock_irqrestore(&priv->ptp_lock, flags);
13492ba6888SRayagond Kokatanur 
135e7ea55beSRichard Cochran 	*ts = ns_to_timespec64(ns);
13692ba6888SRayagond Kokatanur 
13792ba6888SRayagond Kokatanur 	return 0;
13892ba6888SRayagond Kokatanur }
13992ba6888SRayagond Kokatanur 
14092ba6888SRayagond Kokatanur /**
14192ba6888SRayagond Kokatanur  * stmmac_set_time
14292ba6888SRayagond Kokatanur  *
14392ba6888SRayagond Kokatanur  * @ptp: pointer to ptp_clock_info structure
14492ba6888SRayagond Kokatanur  * @ts: time value to set
14592ba6888SRayagond Kokatanur  *
14692ba6888SRayagond Kokatanur  * Description: this function will set the current time on the
14792ba6888SRayagond Kokatanur  * hardware clock.
14892ba6888SRayagond Kokatanur  */
stmmac_set_time(struct ptp_clock_info * ptp,const struct timespec64 * ts)14992ba6888SRayagond Kokatanur static int stmmac_set_time(struct ptp_clock_info *ptp,
1503f6c4654SRichard Cochran 			   const struct timespec64 *ts)
15192ba6888SRayagond Kokatanur {
15292ba6888SRayagond Kokatanur 	struct stmmac_priv *priv =
15392ba6888SRayagond Kokatanur 	    container_of(ptp, struct stmmac_priv, ptp_clock_ops);
15492ba6888SRayagond Kokatanur 	unsigned long flags;
15592ba6888SRayagond Kokatanur 
156642436a1SYannick Vignon 	write_lock_irqsave(&priv->ptp_lock, flags);
157cc4c9001SJose Abreu 	stmmac_init_systime(priv, priv->ptpaddr, ts->tv_sec, ts->tv_nsec);
158642436a1SYannick Vignon 	write_unlock_irqrestore(&priv->ptp_lock, flags);
15992ba6888SRayagond Kokatanur 
16092ba6888SRayagond Kokatanur 	return 0;
16192ba6888SRayagond Kokatanur }
16292ba6888SRayagond Kokatanur 
stmmac_enable(struct ptp_clock_info * ptp,struct ptp_clock_request * rq,int on)16392ba6888SRayagond Kokatanur static int stmmac_enable(struct ptp_clock_info *ptp,
16492ba6888SRayagond Kokatanur 			 struct ptp_clock_request *rq, int on)
16592ba6888SRayagond Kokatanur {
1669a8a02c9SJose Abreu 	struct stmmac_priv *priv =
1679a8a02c9SJose Abreu 	    container_of(ptp, struct stmmac_priv, ptp_clock_ops);
168f4da5652STan Tee Min 	void __iomem *ptpaddr = priv->ptpaddr;
1699a8a02c9SJose Abreu 	struct stmmac_pps_cfg *cfg;
1709a8a02c9SJose Abreu 	int ret = -EOPNOTSUPP;
1719a8a02c9SJose Abreu 	unsigned long flags;
17276c16d3eSWong Vee Khee 	u32 acr_value;
1739a8a02c9SJose Abreu 
1749a8a02c9SJose Abreu 	switch (rq->type) {
1759a8a02c9SJose Abreu 	case PTP_CLK_REQ_PEROUT:
1767f9048f1SJacob Keller 		/* Reject requests with unsupported flags */
1777f9048f1SJacob Keller 		if (rq->perout.flags)
1787f9048f1SJacob Keller 			return -EOPNOTSUPP;
1797f9048f1SJacob Keller 
1809a8a02c9SJose Abreu 		cfg = &priv->pps[rq->perout.index];
1819a8a02c9SJose Abreu 
1829a8a02c9SJose Abreu 		cfg->start.tv_sec = rq->perout.start.sec;
1839a8a02c9SJose Abreu 		cfg->start.tv_nsec = rq->perout.start.nsec;
1849a8a02c9SJose Abreu 		cfg->period.tv_sec = rq->perout.period.sec;
1859a8a02c9SJose Abreu 		cfg->period.tv_nsec = rq->perout.period.nsec;
1869a8a02c9SJose Abreu 
187642436a1SYannick Vignon 		write_lock_irqsave(&priv->ptp_lock, flags);
1889a8a02c9SJose Abreu 		ret = stmmac_flex_pps_config(priv, priv->ioaddr,
1899a8a02c9SJose Abreu 					     rq->perout.index, cfg, on,
1909a8a02c9SJose Abreu 					     priv->sub_second_inc,
1919a8a02c9SJose Abreu 					     priv->systime_flags);
192642436a1SYannick Vignon 		write_unlock_irqrestore(&priv->ptp_lock, flags);
1939a8a02c9SJose Abreu 		break;
194f4da5652STan Tee Min 	case PTP_CLK_REQ_EXTTS:
195aa5513f5SBartosz Golaszewski 		if (on)
196aa5513f5SBartosz Golaszewski 			priv->plat->flags |= STMMAC_FLAG_EXT_SNAPSHOT_EN;
197aa5513f5SBartosz Golaszewski 		else
198aa5513f5SBartosz Golaszewski 			priv->plat->flags &= ~STMMAC_FLAG_EXT_SNAPSHOT_EN;
199f4da5652STan Tee Min 		mutex_lock(&priv->aux_ts_lock);
200f4da5652STan Tee Min 		acr_value = readl(ptpaddr + PTP_ACR);
201f4da5652STan Tee Min 		acr_value &= ~PTP_ACR_MASK;
202f4da5652STan Tee Min 		if (on) {
203f4da5652STan Tee Min 			/* Enable External snapshot trigger */
204f4da5652STan Tee Min 			acr_value |= priv->plat->ext_snapshot_num;
205f4da5652STan Tee Min 			acr_value |= PTP_ACR_ATSFC;
206f4da5652STan Tee Min 			netdev_dbg(priv->dev, "Auxiliary Snapshot %d enabled.\n",
207f4da5652STan Tee Min 				   priv->plat->ext_snapshot_num >>
208f4da5652STan Tee Min 				   PTP_ACR_ATSEN_SHIFT);
209f4da5652STan Tee Min 		} else {
210f4da5652STan Tee Min 			netdev_dbg(priv->dev, "Auxiliary Snapshot %d disabled.\n",
211f4da5652STan Tee Min 				   priv->plat->ext_snapshot_num >>
212f4da5652STan Tee Min 				   PTP_ACR_ATSEN_SHIFT);
213f4da5652STan Tee Min 		}
214f4da5652STan Tee Min 		writel(acr_value, ptpaddr + PTP_ACR);
215f4da5652STan Tee Min 		mutex_unlock(&priv->aux_ts_lock);
216ae9dcb91SNoor Azura Ahmad Tarmizi 		/* wait for auxts fifo clear to finish */
217ae9dcb91SNoor Azura Ahmad Tarmizi 		ret = readl_poll_timeout(ptpaddr + PTP_ACR, acr_value,
218ae9dcb91SNoor Azura Ahmad Tarmizi 					 !(acr_value & PTP_ACR_ATSFC),
219ae9dcb91SNoor Azura Ahmad Tarmizi 					 10, 10000);
220f4da5652STan Tee Min 		break;
221f4da5652STan Tee Min 
2229a8a02c9SJose Abreu 	default:
2239a8a02c9SJose Abreu 		break;
2249a8a02c9SJose Abreu 	}
2259a8a02c9SJose Abreu 
2269a8a02c9SJose Abreu 	return ret;
22792ba6888SRayagond Kokatanur }
22892ba6888SRayagond Kokatanur 
229341f67e4STan Tee Min /**
230341f67e4STan Tee Min  * stmmac_get_syncdevicetime
231341f67e4STan Tee Min  * @device: current device time
232341f67e4STan Tee Min  * @system: system counter value read synchronously with device time
233341f67e4STan Tee Min  * @ctx: context provided by timekeeping code
234341f67e4STan Tee Min  * Description: Read device and system clock simultaneously and return the
235341f67e4STan Tee Min  * corrected clock values in ns.
236341f67e4STan Tee Min  **/
stmmac_get_syncdevicetime(ktime_t * device,struct system_counterval_t * system,void * ctx)237341f67e4STan Tee Min static int stmmac_get_syncdevicetime(ktime_t *device,
238341f67e4STan Tee Min 				     struct system_counterval_t *system,
239341f67e4STan Tee Min 				     void *ctx)
240341f67e4STan Tee Min {
241341f67e4STan Tee Min 	struct stmmac_priv *priv = (struct stmmac_priv *)ctx;
242341f67e4STan Tee Min 
243341f67e4STan Tee Min 	if (priv->plat->crosststamp)
244341f67e4STan Tee Min 		return priv->plat->crosststamp(device, system, ctx);
245341f67e4STan Tee Min 	else
246341f67e4STan Tee Min 		return -EOPNOTSUPP;
247341f67e4STan Tee Min }
248341f67e4STan Tee Min 
stmmac_getcrosststamp(struct ptp_clock_info * ptp,struct system_device_crosststamp * xtstamp)249341f67e4STan Tee Min static int stmmac_getcrosststamp(struct ptp_clock_info *ptp,
250341f67e4STan Tee Min 				 struct system_device_crosststamp *xtstamp)
251341f67e4STan Tee Min {
252341f67e4STan Tee Min 	struct stmmac_priv *priv =
253341f67e4STan Tee Min 		container_of(ptp, struct stmmac_priv, ptp_clock_ops);
254341f67e4STan Tee Min 
255341f67e4STan Tee Min 	return get_device_system_crosststamp(stmmac_get_syncdevicetime,
256341f67e4STan Tee Min 					     priv, NULL, xtstamp);
257341f67e4STan Tee Min }
258341f67e4STan Tee Min 
25992ba6888SRayagond Kokatanur /* structure describing a PTP hardware clock */
2609a8a02c9SJose Abreu static struct ptp_clock_info stmmac_ptp_clock_ops = {
26192ba6888SRayagond Kokatanur 	.owner = THIS_MODULE,
2625da202c8SAntonio Borneo 	.name = "stmmac ptp",
26392ba6888SRayagond Kokatanur 	.max_adj = 62500000,
26492ba6888SRayagond Kokatanur 	.n_alarm = 0,
265f4da5652STan Tee Min 	.n_ext_ts = 0, /* will be overwritten in stmmac_ptp_register */
2669a8a02c9SJose Abreu 	.n_per_out = 0, /* will be overwritten in stmmac_ptp_register */
2674986b4f0SRichard Cochran 	.n_pins = 0,
26892ba6888SRayagond Kokatanur 	.pps = 0,
2692d96099fSJacob Keller 	.adjfine = stmmac_adjust_freq,
27092ba6888SRayagond Kokatanur 	.adjtime = stmmac_adjust_time,
2713f6c4654SRichard Cochran 	.gettime64 = stmmac_get_time,
2723f6c4654SRichard Cochran 	.settime64 = stmmac_set_time,
27392ba6888SRayagond Kokatanur 	.enable = stmmac_enable,
274341f67e4STan Tee Min 	.getcrosststamp = stmmac_getcrosststamp,
27592ba6888SRayagond Kokatanur };
27692ba6888SRayagond Kokatanur 
27792ba6888SRayagond Kokatanur /**
27892ba6888SRayagond Kokatanur  * stmmac_ptp_register
27932ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
28092ba6888SRayagond Kokatanur  * Description: this function will register the ptp clock driver
28192ba6888SRayagond Kokatanur  * to kernel. It also does some house keeping work.
28292ba6888SRayagond Kokatanur  */
stmmac_ptp_register(struct stmmac_priv * priv)283c30a70d3SGiuseppe CAVALLARO void stmmac_ptp_register(struct stmmac_priv *priv)
28492ba6888SRayagond Kokatanur {
2859a8a02c9SJose Abreu 	int i;
2869a8a02c9SJose Abreu 
2879a8a02c9SJose Abreu 	for (i = 0; i < priv->dma_cap.pps_out_num; i++) {
2889a8a02c9SJose Abreu 		if (i >= STMMAC_PPS_MAX)
2899a8a02c9SJose Abreu 			break;
2909a8a02c9SJose Abreu 		priv->pps[i].available = true;
2919a8a02c9SJose Abreu 	}
2929a8a02c9SJose Abreu 
293190f73abSVoon Weifeng 	if (priv->plat->ptp_max_adj)
294190f73abSVoon Weifeng 		stmmac_ptp_clock_ops.max_adj = priv->plat->ptp_max_adj;
295190f73abSVoon Weifeng 
296c6d5f193SKurt Kanzenbach 	/* Calculate the clock domain crossing (CDC) error if necessary */
297c6d5f193SKurt Kanzenbach 	priv->plat->cdc_error_adj = 0;
298c6d5f193SKurt Kanzenbach 	if (priv->plat->has_gmac4 && priv->plat->clk_ptp_rate)
299c6d5f193SKurt Kanzenbach 		priv->plat->cdc_error_adj = (2 * NSEC_PER_SEC) / priv->plat->clk_ptp_rate;
300c6d5f193SKurt Kanzenbach 
3019a8a02c9SJose Abreu 	stmmac_ptp_clock_ops.n_per_out = priv->dma_cap.pps_out_num;
302f4da5652STan Tee Min 	stmmac_ptp_clock_ops.n_ext_ts = priv->dma_cap.aux_snapshot_n;
3039a8a02c9SJose Abreu 
304642436a1SYannick Vignon 	rwlock_init(&priv->ptp_lock);
305f4da5652STan Tee Min 	mutex_init(&priv->aux_ts_lock);
30692ba6888SRayagond Kokatanur 	priv->ptp_clock_ops = stmmac_ptp_clock_ops;
30792ba6888SRayagond Kokatanur 
30892ba6888SRayagond Kokatanur 	priv->ptp_clock = ptp_clock_register(&priv->ptp_clock_ops,
30992ba6888SRayagond Kokatanur 					     priv->device);
31092ba6888SRayagond Kokatanur 	if (IS_ERR(priv->ptp_clock)) {
311c30a70d3SGiuseppe CAVALLARO 		netdev_err(priv->dev, "ptp_clock_register failed\n");
31292ba6888SRayagond Kokatanur 		priv->ptp_clock = NULL;
313c30a70d3SGiuseppe CAVALLARO 	} else if (priv->ptp_clock)
314c30a70d3SGiuseppe CAVALLARO 		netdev_info(priv->dev, "registered PTP clock\n");
31592ba6888SRayagond Kokatanur }
31692ba6888SRayagond Kokatanur 
31792ba6888SRayagond Kokatanur /**
31892ba6888SRayagond Kokatanur  * stmmac_ptp_unregister
31932ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
32092ba6888SRayagond Kokatanur  * Description: this function will remove/unregister the ptp clock driver
32192ba6888SRayagond Kokatanur  * from the kernel.
32292ba6888SRayagond Kokatanur  */
stmmac_ptp_unregister(struct stmmac_priv * priv)32392ba6888SRayagond Kokatanur void stmmac_ptp_unregister(struct stmmac_priv *priv)
32492ba6888SRayagond Kokatanur {
32592ba6888SRayagond Kokatanur 	if (priv->ptp_clock) {
32692ba6888SRayagond Kokatanur 		ptp_clock_unregister(priv->ptp_clock);
327f95f4045SGiuseppe CAVALLARO 		priv->ptp_clock = NULL;
32892ba6888SRayagond Kokatanur 		pr_debug("Removed PTP HW clock successfully on %s\n",
32992ba6888SRayagond Kokatanur 			 priv->dev->name);
33092ba6888SRayagond Kokatanur 	}
331f4da5652STan Tee Min 
332f4da5652STan Tee Min 	mutex_destroy(&priv->aux_ts_lock);
33392ba6888SRayagond Kokatanur }
334