diff options
Diffstat (limited to 'drivers/net/ethernet/freescale/fec_ptp.c')
| -rw-r--r-- | drivers/net/ethernet/freescale/fec_ptp.c | 57 | 
1 files changed, 18 insertions, 39 deletions
| diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index 8dd5a2615a89..3dc3c0b626c2 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -365,19 +365,21 @@ static int fec_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)   */  static int fec_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)  { -	struct fec_enet_private *fep = +	struct fec_enet_private *adapter =  	    container_of(ptp, struct fec_enet_private, ptp_caps);  	u64 ns;  	unsigned long flags; -	spin_lock_irqsave(&fep->tmreg_lock, flags); +	mutex_lock(&adapter->ptp_clk_mutex);  	/* Check the ptp clock */ -	if (!fep->ptp_clk_on) { -		spin_unlock_irqrestore(&fep->tmreg_lock, flags); +	if (!adapter->ptp_clk_on) { +		mutex_unlock(&adapter->ptp_clk_mutex);  		return -EINVAL;  	} -	ns = timecounter_read(&fep->tc); -	spin_unlock_irqrestore(&fep->tmreg_lock, flags); +	spin_lock_irqsave(&adapter->tmreg_lock, flags); +	ns = timecounter_read(&adapter->tc); +	spin_unlock_irqrestore(&adapter->tmreg_lock, flags); +	mutex_unlock(&adapter->ptp_clk_mutex);  	*ts = ns_to_timespec64(ns); @@ -402,10 +404,10 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp,  	unsigned long flags;  	u32 counter; -	spin_lock_irqsave(&fep->tmreg_lock, flags); +	mutex_lock(&fep->ptp_clk_mutex);  	/* Check the ptp clock */  	if (!fep->ptp_clk_on) { -		spin_unlock_irqrestore(&fep->tmreg_lock, flags); +		mutex_unlock(&fep->ptp_clk_mutex);  		return -EINVAL;  	} @@ -415,9 +417,11 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp,  	 */  	counter = ns & fep->cc.mask; +	spin_lock_irqsave(&fep->tmreg_lock, flags);  	writel(counter, fep->hwp + FEC_ATIME);  	timecounter_init(&fep->tc, &fep->cc, ns);  	spin_unlock_irqrestore(&fep->tmreg_lock, flags); +	mutex_unlock(&fep->ptp_clk_mutex);  	return 0;  } @@ -514,11 +518,13 @@ static void fec_time_keep(struct work_struct *work)  	struct fec_enet_private *fep = container_of(dwork, struct fec_enet_private, time_keep);  	unsigned long flags; -	spin_lock_irqsave(&fep->tmreg_lock, flags); +	mutex_lock(&fep->ptp_clk_mutex);  	if (fep->ptp_clk_on) { +		spin_lock_irqsave(&fep->tmreg_lock, flags);  		timecounter_read(&fep->tc); +		spin_unlock_irqrestore(&fep->tmreg_lock, flags);  	} -	spin_unlock_irqrestore(&fep->tmreg_lock, flags); +	mutex_unlock(&fep->ptp_clk_mutex);  	schedule_delayed_work(&fep->time_keep, HZ);  } @@ -593,6 +599,8 @@ void fec_ptp_init(struct platform_device *pdev, int irq_idx)  	}  	fep->ptp_inc = NSEC_PER_SEC / fep->cycle_speed; +	spin_lock_init(&fep->tmreg_lock); +  	fec_ptp_start_cyclecounter(ndev);  	INIT_DELAYED_WORK(&fep->time_keep, fec_time_keep); @@ -625,36 +633,7 @@ void fec_ptp_stop(struct platform_device *pdev)  	struct net_device *ndev = platform_get_drvdata(pdev);  	struct fec_enet_private *fep = netdev_priv(ndev); -	if (fep->pps_enable) -		fec_ptp_enable_pps(fep, 0); -  	cancel_delayed_work_sync(&fep->time_keep);  	if (fep->ptp_clock)  		ptp_clock_unregister(fep->ptp_clock);  } - -void fec_ptp_save_state(struct fec_enet_private *fep) -{ -	u32 atime_inc_corr; - -	fec_ptp_gettime(&fep->ptp_caps, &fep->ptp_saved_state.ts_phc); -	fep->ptp_saved_state.ns_sys = ktime_get_ns(); - -	fep->ptp_saved_state.at_corr = readl(fep->hwp + FEC_ATIME_CORR); -	atime_inc_corr = readl(fep->hwp + FEC_ATIME_INC) & FEC_T_INC_CORR_MASK; -	fep->ptp_saved_state.at_inc_corr = (u8)(atime_inc_corr >> FEC_T_INC_CORR_OFFSET); -} - -int fec_ptp_restore_state(struct fec_enet_private *fep) -{ -	u32 atime_inc = readl(fep->hwp + FEC_ATIME_INC) & FEC_T_INC_MASK; -	u64 ns_sys; - -	writel(fep->ptp_saved_state.at_corr, fep->hwp + FEC_ATIME_CORR); -	atime_inc |= ((u32)fep->ptp_saved_state.at_inc_corr) << FEC_T_INC_CORR_OFFSET; -	writel(atime_inc, fep->hwp + FEC_ATIME_INC); - -	ns_sys = ktime_get_ns() - fep->ptp_saved_state.ns_sys; -	timespec64_add_ns(&fep->ptp_saved_state.ts_phc, ns_sys); -	return fec_ptp_settime(&fep->ptp_caps, &fep->ptp_saved_state.ts_phc); -} | 
