diff options
author | Rayagond Kokatanur <rayagond@vayavyalabs.com> | 2013-03-26 00:43:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-03-26 12:53:37 -0400 |
commit | 92ba6888510c6700ee78273cfcd2b4092a2a71b2 (patch) | |
tree | b50e62680d6d472c24c8d08fb7827ab5d7e1848b | |
parent | 891434b18ec0a21cfa4788695165b74e8d4c0474 (diff) |
stmmac: add the support for PTP hw clock driver
This patch implements PHC (ptp hardware clock) driver for stmmac
driver to support 1588 PTP.
V2: added support for FINE method, reduced loop delay and review spinlock.
Signed-off-by: Rayagond Kokatanur <rayagond@vayavyalabs.com>
Hacked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/Kconfig | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/common.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac.h | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c | 40 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 34 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c | 215 |
8 files changed, 294 insertions, 10 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index f0720d0d5771..f695a50bac47 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig | |||
@@ -5,6 +5,7 @@ config STMMAC_ETH | |||
5 | select MII | 5 | select MII |
6 | select PHYLIB | 6 | select PHYLIB |
7 | select CRC32 | 7 | select CRC32 |
8 | select PTP_1588_CLOCK | ||
8 | ---help--- | 9 | ---help--- |
9 | This is the driver for the Ethernet IPs are built around a | 10 | This is the driver for the Ethernet IPs are built around a |
10 | Synopsys IP Core and only tested on the STMicroelectronics | 11 | Synopsys IP Core and only tested on the STMicroelectronics |
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index 1aca0e6881bd..356a9dd32be7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile | |||
@@ -4,4 +4,4 @@ stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o | |||
4 | stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ | 4 | stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ |
5 | chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ | 5 | chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ |
6 | dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ | 6 | dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ |
7 | mmc_core.o stmmac_hwtstamp.o $(stmmac-y) | 7 | mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o $(stmmac-y) |
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 6fa975c55234..ad7e20a9875d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h | |||
@@ -411,6 +411,9 @@ struct stmmac_hwtimestamp { | |||
411 | void (*config_sub_second_increment) (void __iomem *ioaddr); | 411 | void (*config_sub_second_increment) (void __iomem *ioaddr); |
412 | int (*init_systime) (void __iomem *ioaddr, u32 sec, u32 nsec); | 412 | int (*init_systime) (void __iomem *ioaddr, u32 sec, u32 nsec); |
413 | int (*config_addend)(void __iomem *ioaddr, u32 addend); | 413 | int (*config_addend)(void __iomem *ioaddr, u32 addend); |
414 | int (*adjust_systime)(void __iomem *ioaddr, u32 sec, u32 nsec, | ||
415 | int add_sub); | ||
416 | u64 (*get_systime)(void __iomem *ioaddr); | ||
414 | }; | 417 | }; |
415 | 418 | ||
416 | struct mac_link { | 419 | struct mac_link { |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index a21d1b9c9094..52002e7c59ae 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/phy.h> | 31 | #include <linux/phy.h> |
32 | #include <linux/pci.h> | 32 | #include <linux/pci.h> |
33 | #include "common.h" | 33 | #include "common.h" |
34 | #include <linux/ptp_clock_kernel.h> | ||
34 | 35 | ||
35 | struct stmmac_priv { | 36 | struct stmmac_priv { |
36 | /* Frequently used values are kept adjacent for cache effect */ | 37 | /* Frequently used values are kept adjacent for cache effect */ |
@@ -103,6 +104,9 @@ struct stmmac_priv { | |||
103 | int hwts_rx_en; | 104 | int hwts_rx_en; |
104 | unsigned int default_addend; | 105 | unsigned int default_addend; |
105 | u32 adv_ts; | 106 | u32 adv_ts; |
107 | struct ptp_clock *ptp_clock; | ||
108 | struct ptp_clock_info ptp_clock_ops; | ||
109 | spinlock_t ptp_lock; | ||
106 | }; | 110 | }; |
107 | 111 | ||
108 | extern int phyaddr; | 112 | extern int phyaddr; |
@@ -113,6 +117,8 @@ extern void stmmac_set_ethtool_ops(struct net_device *netdev); | |||
113 | extern const struct stmmac_desc_ops enh_desc_ops; | 117 | extern const struct stmmac_desc_ops enh_desc_ops; |
114 | extern const struct stmmac_desc_ops ndesc_ops; | 118 | extern const struct stmmac_desc_ops ndesc_ops; |
115 | extern const struct stmmac_hwtimestamp stmmac_ptp; | 119 | extern const struct stmmac_hwtimestamp stmmac_ptp; |
120 | extern int stmmac_ptp_register(struct stmmac_priv *priv); | ||
121 | extern void stmmac_ptp_unregister(struct stmmac_priv *priv); | ||
116 | int stmmac_freeze(struct net_device *ndev); | 122 | int stmmac_freeze(struct net_device *ndev); |
117 | int stmmac_restore(struct net_device *ndev); | 123 | int stmmac_restore(struct net_device *ndev); |
118 | int stmmac_resume(struct net_device *ndev); | 124 | int stmmac_resume(struct net_device *ndev); |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index 5b340c23fd6b..c5f9cb85c8ef 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | |||
@@ -737,6 +737,9 @@ static int stmmac_get_ts_info(struct net_device *dev, | |||
737 | SOF_TIMESTAMPING_RX_HARDWARE | | 737 | SOF_TIMESTAMPING_RX_HARDWARE | |
738 | SOF_TIMESTAMPING_RAW_HARDWARE; | 738 | SOF_TIMESTAMPING_RAW_HARDWARE; |
739 | 739 | ||
740 | if (priv->ptp_clock) | ||
741 | info->phc_index = ptp_clock_index(priv->ptp_clock); | ||
742 | |||
740 | info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON); | 743 | info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON); |
741 | 744 | ||
742 | info->rx_filters = ((1 << HWTSTAMP_FILTER_NONE) | | 745 | info->rx_filters = ((1 << HWTSTAMP_FILTER_NONE) | |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c index 380baeb016a9..def7e75e1d57 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c | |||
@@ -100,9 +100,49 @@ static int stmmac_config_addend(void __iomem *ioaddr, u32 addend) | |||
100 | return 0; | 100 | return 0; |
101 | } | 101 | } |
102 | 102 | ||
103 | static int stmmac_adjust_systime(void __iomem *ioaddr, u32 sec, u32 nsec, | ||
104 | int add_sub) | ||
105 | { | ||
106 | u32 value; | ||
107 | int limit; | ||
108 | |||
109 | writel(sec, ioaddr + PTP_STSUR); | ||
110 | writel(((add_sub << PTP_STNSUR_ADDSUB_SHIFT) | nsec), | ||
111 | ioaddr + PTP_STNSUR); | ||
112 | /* issue command to initialize the system time value */ | ||
113 | value = readl(ioaddr + PTP_TCR); | ||
114 | value |= PTP_TCR_TSUPDT; | ||
115 | writel(value, ioaddr + PTP_TCR); | ||
116 | |||
117 | /* wait for present system time adjust/update to complete */ | ||
118 | limit = 10; | ||
119 | while (limit--) { | ||
120 | if (!(readl(ioaddr + PTP_TCR) & PTP_TCR_TSUPDT)) | ||
121 | break; | ||
122 | mdelay(10); | ||
123 | } | ||
124 | if (limit < 0) | ||
125 | return -EBUSY; | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | static u64 stmmac_get_systime(void __iomem *ioaddr) | ||
131 | { | ||
132 | u64 ns; | ||
133 | |||
134 | ns = readl(ioaddr + PTP_STNSR); | ||
135 | /* convert sec time value to nanosecond */ | ||
136 | ns += readl(ioaddr + PTP_STSR) * 1000000000ULL; | ||
137 | |||
138 | return ns; | ||
139 | } | ||
140 | |||
103 | const struct stmmac_hwtimestamp stmmac_ptp = { | 141 | const struct stmmac_hwtimestamp stmmac_ptp = { |
104 | .config_hw_tstamping = stmmac_config_hw_tstamping, | 142 | .config_hw_tstamping = stmmac_config_hw_tstamping, |
105 | .init_systime = stmmac_init_systime, | 143 | .init_systime = stmmac_init_systime, |
106 | .config_sub_second_increment = stmmac_config_sub_second_increment, | 144 | .config_sub_second_increment = stmmac_config_sub_second_increment, |
107 | .config_addend = stmmac_config_addend, | 145 | .config_addend = stmmac_config_addend, |
146 | .adjust_systime = stmmac_adjust_systime, | ||
147 | .get_systime = stmmac_get_systime, | ||
108 | }; | 148 | }; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 6906772069e3..6b26d31c268f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
@@ -618,20 +618,32 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
618 | sizeof(struct hwtstamp_config)) ? -EFAULT : 0; | 618 | sizeof(struct hwtstamp_config)) ? -EFAULT : 0; |
619 | } | 619 | } |
620 | 620 | ||
621 | static void stmmac_init_ptp(struct stmmac_priv *priv) | 621 | static int stmmac_init_ptp(struct stmmac_priv *priv) |
622 | { | 622 | { |
623 | if (priv->dma_cap.time_stamp) { | 623 | if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) |
624 | pr_debug("IEEE 1588-2002 Time Stamp supported\n"); | 624 | return -EOPNOTSUPP; |
625 | priv->adv_ts = 0; | 625 | |
626 | } | 626 | if (netif_msg_hw(priv)) { |
627 | if (priv->dma_cap.atime_stamp && priv->extend_desc) { | 627 | if (priv->dma_cap.time_stamp) { |
628 | pr_debug("IEEE 1588-2008 Advanced Time Stamp supported\n"); | 628 | pr_debug("IEEE 1588-2002 Time Stamp supported\n"); |
629 | priv->adv_ts = 1; | 629 | priv->adv_ts = 0; |
630 | } | ||
631 | if (priv->dma_cap.atime_stamp && priv->extend_desc) { | ||
632 | pr_debug("IEEE 1588-2008 Advanced Time Stamp supported\n"); | ||
633 | priv->adv_ts = 1; | ||
634 | } | ||
630 | } | 635 | } |
631 | 636 | ||
632 | priv->hw->ptp = &stmmac_ptp; | 637 | priv->hw->ptp = &stmmac_ptp; |
633 | priv->hwts_tx_en = 0; | 638 | priv->hwts_tx_en = 0; |
634 | priv->hwts_rx_en = 0; | 639 | priv->hwts_rx_en = 0; |
640 | |||
641 | return stmmac_ptp_register(priv); | ||
642 | } | ||
643 | |||
644 | static void stmmac_release_ptp(struct stmmac_priv *priv) | ||
645 | { | ||
646 | stmmac_ptp_unregister(priv); | ||
635 | } | 647 | } |
636 | 648 | ||
637 | /** | 649 | /** |
@@ -1567,7 +1579,9 @@ static int stmmac_open(struct net_device *dev) | |||
1567 | 1579 | ||
1568 | stmmac_mmc_setup(priv); | 1580 | stmmac_mmc_setup(priv); |
1569 | 1581 | ||
1570 | stmmac_init_ptp(priv); | 1582 | ret = stmmac_init_ptp(priv); |
1583 | if (ret) | ||
1584 | pr_warn("%s: failed PTP initialisation\n", __func__); | ||
1571 | 1585 | ||
1572 | #ifdef CONFIG_STMMAC_DEBUG_FS | 1586 | #ifdef CONFIG_STMMAC_DEBUG_FS |
1573 | ret = stmmac_init_fs(dev); | 1587 | ret = stmmac_init_fs(dev); |
@@ -1677,6 +1691,8 @@ static int stmmac_release(struct net_device *dev) | |||
1677 | #endif | 1691 | #endif |
1678 | clk_disable_unprepare(priv->stmmac_clk); | 1692 | clk_disable_unprepare(priv->stmmac_clk); |
1679 | 1693 | ||
1694 | stmmac_release_ptp(priv); | ||
1695 | |||
1680 | return 0; | 1696 | return 0; |
1681 | } | 1697 | } |
1682 | 1698 | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c new file mode 100644 index 000000000000..93d4beff92c7 --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c | |||
@@ -0,0 +1,215 @@ | |||
1 | /******************************************************************************* | ||
2 | PTP 1588 clock using the STMMAC. | ||
3 | |||
4 | Copyright (C) 2013 Vayavya Labs Pvt Ltd | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify it | ||
7 | under the terms and conditions of the GNU General Public License, | ||
8 | version 2, as published by the Free Software Foundation. | ||
9 | |||
10 | This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License along with | ||
16 | this program; if not, write to the Free Software Foundation, Inc., | ||
17 | 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | |||
19 | The full GNU General Public License is included in this distribution in | ||
20 | the file called "COPYING". | ||
21 | |||
22 | Author: Rayagond Kokatanur <rayagond@vayavyalabs.com> | ||
23 | *******************************************************************************/ | ||
24 | #include "stmmac.h" | ||
25 | #include "stmmac_ptp.h" | ||
26 | |||
27 | /** | ||
28 | * stmmac_adjust_freq | ||
29 | * | ||
30 | * @ptp: pointer to ptp_clock_info structure | ||
31 | * @ppb: desired period change in parts ber billion | ||
32 | * | ||
33 | * Description: this function will adjust the frequency of hardware clock. | ||
34 | */ | ||
35 | static int stmmac_adjust_freq(struct ptp_clock_info *ptp, s32 ppb) | ||
36 | { | ||
37 | struct stmmac_priv *priv = | ||
38 | container_of(ptp, struct stmmac_priv, ptp_clock_ops); | ||
39 | unsigned long flags; | ||
40 | u32 diff, addend; | ||
41 | int neg_adj = 0; | ||
42 | u64 adj; | ||
43 | |||
44 | if (ppb < 0) { | ||
45 | neg_adj = 1; | ||
46 | ppb = -ppb; | ||
47 | } | ||
48 | |||
49 | addend = priv->default_addend; | ||
50 | adj = addend; | ||
51 | adj *= ppb; | ||
52 | diff = div_u64(adj, 1000000000ULL); | ||
53 | addend = neg_adj ? (addend - diff) : (addend + diff); | ||
54 | |||
55 | spin_lock_irqsave(&priv->ptp_lock, flags); | ||
56 | |||
57 | priv->hw->ptp->config_addend(priv->ioaddr, addend); | ||
58 | |||
59 | spin_unlock_irqrestore(&priv->lock, flags); | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | /** | ||
65 | * stmmac_adjust_time | ||
66 | * | ||
67 | * @ptp: pointer to ptp_clock_info structure | ||
68 | * @delta: desired change in nanoseconds | ||
69 | * | ||
70 | * Description: this function will shift/adjust the hardware clock time. | ||
71 | */ | ||
72 | static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta) | ||
73 | { | ||
74 | struct stmmac_priv *priv = | ||
75 | container_of(ptp, struct stmmac_priv, ptp_clock_ops); | ||
76 | unsigned long flags; | ||
77 | u32 sec, nsec; | ||
78 | u32 quotient, reminder; | ||
79 | int neg_adj = 0; | ||
80 | |||
81 | if (delta < 0) { | ||
82 | neg_adj = 1; | ||
83 | delta = -delta; | ||
84 | } | ||
85 | |||
86 | quotient = div_u64_rem(delta, 1000000000ULL, &reminder); | ||
87 | sec = quotient; | ||
88 | nsec = reminder; | ||
89 | |||
90 | spin_lock_irqsave(&priv->ptp_lock, flags); | ||
91 | |||
92 | priv->hw->ptp->adjust_systime(priv->ioaddr, sec, nsec, neg_adj); | ||
93 | |||
94 | spin_unlock_irqrestore(&priv->lock, flags); | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | /** | ||
100 | * stmmac_get_time | ||
101 | * | ||
102 | * @ptp: pointer to ptp_clock_info structure | ||
103 | * @ts: pointer to hold time/result | ||
104 | * | ||
105 | * Description: this function will read the current time from the | ||
106 | * hardware clock and store it in @ts. | ||
107 | */ | ||
108 | static int stmmac_get_time(struct ptp_clock_info *ptp, struct timespec *ts) | ||
109 | { | ||
110 | struct stmmac_priv *priv = | ||
111 | container_of(ptp, struct stmmac_priv, ptp_clock_ops); | ||
112 | unsigned long flags; | ||
113 | u64 ns; | ||
114 | u32 reminder; | ||
115 | |||
116 | spin_lock_irqsave(&priv->ptp_lock, flags); | ||
117 | |||
118 | ns = priv->hw->ptp->get_systime(priv->ioaddr); | ||
119 | |||
120 | spin_unlock_irqrestore(&priv->ptp_lock, flags); | ||
121 | |||
122 | ts->tv_sec = div_u64_rem(ns, 1000000000ULL, &reminder); | ||
123 | ts->tv_nsec = reminder; | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | /** | ||
129 | * stmmac_set_time | ||
130 | * | ||
131 | * @ptp: pointer to ptp_clock_info structure | ||
132 | * @ts: time value to set | ||
133 | * | ||
134 | * Description: this function will set the current time on the | ||
135 | * hardware clock. | ||
136 | */ | ||
137 | static int stmmac_set_time(struct ptp_clock_info *ptp, | ||
138 | const struct timespec *ts) | ||
139 | { | ||
140 | struct stmmac_priv *priv = | ||
141 | container_of(ptp, struct stmmac_priv, ptp_clock_ops); | ||
142 | unsigned long flags; | ||
143 | |||
144 | spin_lock_irqsave(&priv->ptp_lock, flags); | ||
145 | |||
146 | priv->hw->ptp->init_systime(priv->ioaddr, ts->tv_sec, ts->tv_nsec); | ||
147 | |||
148 | spin_unlock_irqrestore(&priv->ptp_lock, flags); | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int stmmac_enable(struct ptp_clock_info *ptp, | ||
154 | struct ptp_clock_request *rq, int on) | ||
155 | { | ||
156 | return -EOPNOTSUPP; | ||
157 | } | ||
158 | |||
159 | /* structure describing a PTP hardware clock */ | ||
160 | static struct ptp_clock_info stmmac_ptp_clock_ops = { | ||
161 | .owner = THIS_MODULE, | ||
162 | .name = "stmmac_ptp_clock", | ||
163 | .max_adj = 62500000, | ||
164 | .n_alarm = 0, | ||
165 | .n_ext_ts = 0, | ||
166 | .n_per_out = 0, | ||
167 | .pps = 0, | ||
168 | .adjfreq = stmmac_adjust_freq, | ||
169 | .adjtime = stmmac_adjust_time, | ||
170 | .gettime = stmmac_get_time, | ||
171 | .settime = stmmac_set_time, | ||
172 | .enable = stmmac_enable, | ||
173 | }; | ||
174 | |||
175 | /** | ||
176 | * stmmac_ptp_register | ||
177 | * | ||
178 | * @ndev: net device pointer | ||
179 | * | ||
180 | * Description: this function will register the ptp clock driver | ||
181 | * to kernel. It also does some house keeping work. | ||
182 | */ | ||
183 | int stmmac_ptp_register(struct stmmac_priv *priv) | ||
184 | { | ||
185 | spin_lock_init(&priv->ptp_lock); | ||
186 | priv->ptp_clock_ops = stmmac_ptp_clock_ops; | ||
187 | |||
188 | priv->ptp_clock = ptp_clock_register(&priv->ptp_clock_ops, | ||
189 | priv->device); | ||
190 | if (IS_ERR(priv->ptp_clock)) { | ||
191 | priv->ptp_clock = NULL; | ||
192 | pr_err("ptp_clock_register() failed on %s\n", priv->dev->name); | ||
193 | } else | ||
194 | pr_debug("Added PTP HW clock successfully on %s\n", | ||
195 | priv->dev->name); | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | /** | ||
201 | * stmmac_ptp_unregister | ||
202 | * | ||
203 | * @ndev: net device pointer | ||
204 | * | ||
205 | * Description: this function will remove/unregister the ptp clock driver | ||
206 | * from the kernel. | ||
207 | */ | ||
208 | void stmmac_ptp_unregister(struct stmmac_priv *priv) | ||
209 | { | ||
210 | if (priv->ptp_clock) { | ||
211 | ptp_clock_unregister(priv->ptp_clock); | ||
212 | pr_debug("Removed PTP HW clock successfully on %s\n", | ||
213 | priv->dev->name); | ||
214 | } | ||
215 | } | ||