diff options
author | Arnd Bergmann <arnd@arndb.de> | 2016-09-19 11:49:07 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2016-09-19 11:49:07 -0400 |
commit | 53570cbc189257d2e95c79e6baa9e12b0a3b3cdf (patch) | |
tree | 2f7a1a02ac46c6ecd9df793979c71456bbbbd04c /drivers/net | |
parent | bac6dd36e355d5b1f089ed507b6579938e4c07c1 (diff) | |
parent | dfdd7d4af6ebee027be7bf2636b2314937948da6 (diff) |
Merge tag 'amlogic-drivers-2' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic into next/late
Pull "Amlogic driver updates for v4.9, 2nd round" from Kevin Hilman:
- media: update IR support for newer SoCs
- firmware: add secure monitor driver
- net: new stmmac glue driver
- usb: udd DWC2 support for meson-gxbb
- clocks: expose more clock IDs for use by DT
- DT binding updates
* tag 'amlogic-drivers-2' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic: (21 commits)
clk: gxbb: expose i2c clocks
clk: gxbb: expose USB clocks
clk: gxbb: expose spifc clock
clk: gxbb: expose MPLL2 clock for use by DT
Documentation: dt-bindings: Add documentation for the Meson USB2 PHYs
usb: dwc2: add support for Meson8b and GXBB SoCs
net: stmmac: update the module description of the dwmac-meson driver
net: stmmac: add a glue driver for the Amlogic Meson 8b / GXBB DWMAC
stmmac: introduce get_stmmac_bsp_priv() helper
net: dt-bindings: Document the new Meson8b and GXBB DWMAC bindings
clk: meson-gxbb: Export PWM related clocks for DT
meson: clk: Add support for clock gates
gxbb: clk: Adjust MESON_GATE macro to be shared with meson8b
clk: meson: Copy meson8b CLKID defines to private header file
meson: clk: Rename register names according to Amlogic datasheet
meson: clk: Move register definitions to meson8b.h
clk: meson: Rename meson8b-clkc.c to reflect gxbb naming convention
nvmem: amlogic: Add Amlogic Meson EFUSE driver
firmware: Amlogic: Add secure monitor driver
media: rc: meson-ir: Add support for newer versions of the IR decoder
...
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/Kconfig | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 324 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h | 8 |
5 files changed, 338 insertions, 6 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index 8f06a6621ab1..54de17529c97 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig | |||
@@ -61,13 +61,13 @@ config DWMAC_LPC18XX | |||
61 | config DWMAC_MESON | 61 | config DWMAC_MESON |
62 | tristate "Amlogic Meson dwmac support" | 62 | tristate "Amlogic Meson dwmac support" |
63 | default ARCH_MESON | 63 | default ARCH_MESON |
64 | depends on OF && (ARCH_MESON || COMPILE_TEST) | 64 | depends on OF && COMMON_CLK && (ARCH_MESON || COMPILE_TEST) |
65 | help | 65 | help |
66 | Support for Ethernet controller on Amlogic Meson SoCs. | 66 | Support for Ethernet controller on Amlogic Meson SoCs. |
67 | 67 | ||
68 | This selects the Amlogic Meson SoC glue layer support for | 68 | This selects the Amlogic Meson SoC glue layer support for |
69 | the stmmac device driver. This driver is used for Meson6 and | 69 | the stmmac device driver. This driver is used for Meson6, |
70 | Meson8 SoCs. | 70 | Meson8, Meson8b and GXBB SoCs. |
71 | 71 | ||
72 | config DWMAC_ROCKCHIP | 72 | config DWMAC_ROCKCHIP |
73 | tristate "Rockchip dwmac support" | 73 | tristate "Rockchip dwmac support" |
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index 44b630cd1755..f77edb9c2fa9 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile | |||
@@ -9,7 +9,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ | |||
9 | obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o | 9 | obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o |
10 | obj-$(CONFIG_DWMAC_IPQ806X) += dwmac-ipq806x.o | 10 | obj-$(CONFIG_DWMAC_IPQ806X) += dwmac-ipq806x.o |
11 | obj-$(CONFIG_DWMAC_LPC18XX) += dwmac-lpc18xx.o | 11 | obj-$(CONFIG_DWMAC_LPC18XX) += dwmac-lpc18xx.o |
12 | obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o | 12 | obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o dwmac-meson8b.o |
13 | obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o | 13 | obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o |
14 | obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-altr-socfpga.o | 14 | obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-altr-socfpga.o |
15 | obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o | 15 | obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c index c1bac1912b37..309d99536a2c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Amlogic Meson DWMAC glue layer | 2 | * Amlogic Meson6 and Meson8 DWMAC glue layer |
3 | * | 3 | * |
4 | * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com> | 4 | * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com> |
5 | * | 5 | * |
@@ -96,5 +96,5 @@ static struct platform_driver meson6_dwmac_driver = { | |||
96 | module_platform_driver(meson6_dwmac_driver); | 96 | module_platform_driver(meson6_dwmac_driver); |
97 | 97 | ||
98 | MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>"); | 98 | MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>"); |
99 | MODULE_DESCRIPTION("Amlogic Meson DWMAC glue layer"); | 99 | MODULE_DESCRIPTION("Amlogic Meson6 and Meson8 DWMAC glue layer"); |
100 | MODULE_LICENSE("GPL v2"); | 100 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c new file mode 100644 index 000000000000..250e4ceafc8d --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | |||
@@ -0,0 +1,324 @@ | |||
1 | /* | ||
2 | * Amlogic Meson8b and GXBB DWMAC glue layer | ||
3 | * | ||
4 | * Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * You should have received a copy of the GNU General Public License | ||
11 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
12 | */ | ||
13 | |||
14 | #include <linux/clk.h> | ||
15 | #include <linux/clk-provider.h> | ||
16 | #include <linux/device.h> | ||
17 | #include <linux/ethtool.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/ioport.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/of_net.h> | ||
22 | #include <linux/mfd/syscon.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/stmmac.h> | ||
25 | |||
26 | #include "stmmac_platform.h" | ||
27 | |||
28 | #define PRG_ETH0 0x0 | ||
29 | |||
30 | #define PRG_ETH0_RGMII_MODE BIT(0) | ||
31 | |||
32 | /* mux to choose between fclk_div2 (bit unset) and mpll2 (bit set) */ | ||
33 | #define PRG_ETH0_CLK_M250_SEL_SHIFT 4 | ||
34 | #define PRG_ETH0_CLK_M250_SEL_MASK GENMASK(4, 4) | ||
35 | |||
36 | #define PRG_ETH0_TXDLY_SHIFT 5 | ||
37 | #define PRG_ETH0_TXDLY_MASK GENMASK(6, 5) | ||
38 | #define PRG_ETH0_TXDLY_OFF (0x0 << PRG_ETH0_TXDLY_SHIFT) | ||
39 | #define PRG_ETH0_TXDLY_QUARTER (0x1 << PRG_ETH0_TXDLY_SHIFT) | ||
40 | #define PRG_ETH0_TXDLY_HALF (0x2 << PRG_ETH0_TXDLY_SHIFT) | ||
41 | #define PRG_ETH0_TXDLY_THREE_QUARTERS (0x3 << PRG_ETH0_TXDLY_SHIFT) | ||
42 | |||
43 | /* divider for the result of m250_sel */ | ||
44 | #define PRG_ETH0_CLK_M250_DIV_SHIFT 7 | ||
45 | #define PRG_ETH0_CLK_M250_DIV_WIDTH 3 | ||
46 | |||
47 | /* divides the result of m25_sel by either 5 (bit unset) or 10 (bit set) */ | ||
48 | #define PRG_ETH0_CLK_M25_DIV_SHIFT 10 | ||
49 | #define PRG_ETH0_CLK_M25_DIV_WIDTH 1 | ||
50 | |||
51 | #define PRG_ETH0_INVERTED_RMII_CLK BIT(11) | ||
52 | #define PRG_ETH0_TX_AND_PHY_REF_CLK BIT(12) | ||
53 | |||
54 | #define MUX_CLK_NUM_PARENTS 2 | ||
55 | |||
56 | struct meson8b_dwmac { | ||
57 | struct platform_device *pdev; | ||
58 | |||
59 | void __iomem *regs; | ||
60 | |||
61 | phy_interface_t phy_mode; | ||
62 | |||
63 | struct clk_mux m250_mux; | ||
64 | struct clk *m250_mux_clk; | ||
65 | struct clk *m250_mux_parent[MUX_CLK_NUM_PARENTS]; | ||
66 | |||
67 | struct clk_divider m250_div; | ||
68 | struct clk *m250_div_clk; | ||
69 | |||
70 | struct clk_divider m25_div; | ||
71 | struct clk *m25_div_clk; | ||
72 | }; | ||
73 | |||
74 | static void meson8b_dwmac_mask_bits(struct meson8b_dwmac *dwmac, u32 reg, | ||
75 | u32 mask, u32 value) | ||
76 | { | ||
77 | u32 data; | ||
78 | |||
79 | data = readl(dwmac->regs + reg); | ||
80 | data &= ~mask; | ||
81 | data |= (value & mask); | ||
82 | |||
83 | writel(data, dwmac->regs + reg); | ||
84 | } | ||
85 | |||
86 | static int meson8b_init_clk(struct meson8b_dwmac *dwmac) | ||
87 | { | ||
88 | struct clk_init_data init; | ||
89 | int i, ret; | ||
90 | struct device *dev = &dwmac->pdev->dev; | ||
91 | char clk_name[32]; | ||
92 | const char *clk_div_parents[1]; | ||
93 | const char *mux_parent_names[MUX_CLK_NUM_PARENTS]; | ||
94 | static struct clk_div_table clk_25m_div_table[] = { | ||
95 | { .val = 0, .div = 5 }, | ||
96 | { .val = 1, .div = 10 }, | ||
97 | { /* sentinel */ }, | ||
98 | }; | ||
99 | |||
100 | /* get the mux parents from DT */ | ||
101 | for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) { | ||
102 | char name[16]; | ||
103 | |||
104 | snprintf(name, sizeof(name), "clkin%d", i); | ||
105 | dwmac->m250_mux_parent[i] = devm_clk_get(dev, name); | ||
106 | if (IS_ERR(dwmac->m250_mux_parent[i])) { | ||
107 | ret = PTR_ERR(dwmac->m250_mux_parent[i]); | ||
108 | if (ret != -EPROBE_DEFER) | ||
109 | dev_err(dev, "Missing clock %s\n", name); | ||
110 | return ret; | ||
111 | } | ||
112 | |||
113 | mux_parent_names[i] = | ||
114 | __clk_get_name(dwmac->m250_mux_parent[i]); | ||
115 | } | ||
116 | |||
117 | /* create the m250_mux */ | ||
118 | snprintf(clk_name, sizeof(clk_name), "%s#m250_sel", dev_name(dev)); | ||
119 | init.name = clk_name; | ||
120 | init.ops = &clk_mux_ops; | ||
121 | init.flags = 0; | ||
122 | init.parent_names = mux_parent_names; | ||
123 | init.num_parents = MUX_CLK_NUM_PARENTS; | ||
124 | |||
125 | dwmac->m250_mux.reg = dwmac->regs + PRG_ETH0; | ||
126 | dwmac->m250_mux.shift = PRG_ETH0_CLK_M250_SEL_SHIFT; | ||
127 | dwmac->m250_mux.mask = PRG_ETH0_CLK_M250_SEL_MASK; | ||
128 | dwmac->m250_mux.flags = 0; | ||
129 | dwmac->m250_mux.table = NULL; | ||
130 | dwmac->m250_mux.hw.init = &init; | ||
131 | |||
132 | dwmac->m250_mux_clk = devm_clk_register(dev, &dwmac->m250_mux.hw); | ||
133 | if (WARN_ON(IS_ERR(dwmac->m250_mux_clk))) | ||
134 | return PTR_ERR(dwmac->m250_mux_clk); | ||
135 | |||
136 | /* create the m250_div */ | ||
137 | snprintf(clk_name, sizeof(clk_name), "%s#m250_div", dev_name(dev)); | ||
138 | init.name = devm_kstrdup(dev, clk_name, GFP_KERNEL); | ||
139 | init.ops = &clk_divider_ops; | ||
140 | init.flags = CLK_SET_RATE_PARENT; | ||
141 | clk_div_parents[0] = __clk_get_name(dwmac->m250_mux_clk); | ||
142 | init.parent_names = clk_div_parents; | ||
143 | init.num_parents = ARRAY_SIZE(clk_div_parents); | ||
144 | |||
145 | dwmac->m250_div.reg = dwmac->regs + PRG_ETH0; | ||
146 | dwmac->m250_div.shift = PRG_ETH0_CLK_M250_DIV_SHIFT; | ||
147 | dwmac->m250_div.width = PRG_ETH0_CLK_M250_DIV_WIDTH; | ||
148 | dwmac->m250_div.hw.init = &init; | ||
149 | dwmac->m250_div.flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO; | ||
150 | |||
151 | dwmac->m250_div_clk = devm_clk_register(dev, &dwmac->m250_div.hw); | ||
152 | if (WARN_ON(IS_ERR(dwmac->m250_div_clk))) | ||
153 | return PTR_ERR(dwmac->m250_div_clk); | ||
154 | |||
155 | /* create the m25_div */ | ||
156 | snprintf(clk_name, sizeof(clk_name), "%s#m25_div", dev_name(dev)); | ||
157 | init.name = devm_kstrdup(dev, clk_name, GFP_KERNEL); | ||
158 | init.ops = &clk_divider_ops; | ||
159 | init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; | ||
160 | clk_div_parents[0] = __clk_get_name(dwmac->m250_div_clk); | ||
161 | init.parent_names = clk_div_parents; | ||
162 | init.num_parents = ARRAY_SIZE(clk_div_parents); | ||
163 | |||
164 | dwmac->m25_div.reg = dwmac->regs + PRG_ETH0; | ||
165 | dwmac->m25_div.shift = PRG_ETH0_CLK_M25_DIV_SHIFT; | ||
166 | dwmac->m25_div.width = PRG_ETH0_CLK_M25_DIV_WIDTH; | ||
167 | dwmac->m25_div.table = clk_25m_div_table; | ||
168 | dwmac->m25_div.hw.init = &init; | ||
169 | dwmac->m25_div.flags = CLK_DIVIDER_ALLOW_ZERO; | ||
170 | |||
171 | dwmac->m25_div_clk = devm_clk_register(dev, &dwmac->m25_div.hw); | ||
172 | if (WARN_ON(IS_ERR(dwmac->m25_div_clk))) | ||
173 | return PTR_ERR(dwmac->m25_div_clk); | ||
174 | |||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac) | ||
179 | { | ||
180 | int ret; | ||
181 | unsigned long clk_rate; | ||
182 | |||
183 | switch (dwmac->phy_mode) { | ||
184 | case PHY_INTERFACE_MODE_RGMII: | ||
185 | case PHY_INTERFACE_MODE_RGMII_ID: | ||
186 | case PHY_INTERFACE_MODE_RGMII_RXID: | ||
187 | case PHY_INTERFACE_MODE_RGMII_TXID: | ||
188 | /* Generate a 25MHz clock for the PHY */ | ||
189 | clk_rate = 25 * 1000 * 1000; | ||
190 | |||
191 | /* enable RGMII mode */ | ||
192 | meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE, | ||
193 | PRG_ETH0_RGMII_MODE); | ||
194 | |||
195 | /* only relevant for RMII mode -> disable in RGMII mode */ | ||
196 | meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, | ||
197 | PRG_ETH0_INVERTED_RMII_CLK, 0); | ||
198 | |||
199 | /* TX clock delay - all known boards use a 1/4 cycle delay */ | ||
200 | meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK, | ||
201 | PRG_ETH0_TXDLY_QUARTER); | ||
202 | break; | ||
203 | |||
204 | case PHY_INTERFACE_MODE_RMII: | ||
205 | /* Use the rate of the mux clock for the internal RMII PHY */ | ||
206 | clk_rate = clk_get_rate(dwmac->m250_mux_clk); | ||
207 | |||
208 | /* disable RGMII mode -> enables RMII mode */ | ||
209 | meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE, | ||
210 | 0); | ||
211 | |||
212 | /* invert internal clk_rmii_i to generate 25/2.5 tx_rx_clk */ | ||
213 | meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, | ||
214 | PRG_ETH0_INVERTED_RMII_CLK, | ||
215 | PRG_ETH0_INVERTED_RMII_CLK); | ||
216 | |||
217 | /* TX clock delay cannot be configured in RMII mode */ | ||
218 | meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK, | ||
219 | 0); | ||
220 | |||
221 | break; | ||
222 | |||
223 | default: | ||
224 | dev_err(&dwmac->pdev->dev, "unsupported phy-mode %s\n", | ||
225 | phy_modes(dwmac->phy_mode)); | ||
226 | return -EINVAL; | ||
227 | } | ||
228 | |||
229 | ret = clk_prepare_enable(dwmac->m25_div_clk); | ||
230 | if (ret) { | ||
231 | dev_err(&dwmac->pdev->dev, "failed to enable the PHY clock\n"); | ||
232 | return ret; | ||
233 | } | ||
234 | |||
235 | ret = clk_set_rate(dwmac->m25_div_clk, clk_rate); | ||
236 | if (ret) { | ||
237 | clk_disable_unprepare(dwmac->m25_div_clk); | ||
238 | |||
239 | dev_err(&dwmac->pdev->dev, "failed to set PHY clock\n"); | ||
240 | return ret; | ||
241 | } | ||
242 | |||
243 | /* enable TX_CLK and PHY_REF_CLK generator */ | ||
244 | meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TX_AND_PHY_REF_CLK, | ||
245 | PRG_ETH0_TX_AND_PHY_REF_CLK); | ||
246 | |||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | static int meson8b_dwmac_probe(struct platform_device *pdev) | ||
251 | { | ||
252 | struct plat_stmmacenet_data *plat_dat; | ||
253 | struct stmmac_resources stmmac_res; | ||
254 | struct resource *res; | ||
255 | struct meson8b_dwmac *dwmac; | ||
256 | int ret; | ||
257 | |||
258 | ret = stmmac_get_platform_resources(pdev, &stmmac_res); | ||
259 | if (ret) | ||
260 | return ret; | ||
261 | |||
262 | plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac); | ||
263 | if (IS_ERR(plat_dat)) | ||
264 | return PTR_ERR(plat_dat); | ||
265 | |||
266 | dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL); | ||
267 | if (!dwmac) | ||
268 | return -ENOMEM; | ||
269 | |||
270 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
271 | dwmac->regs = devm_ioremap_resource(&pdev->dev, res); | ||
272 | if (IS_ERR(dwmac->regs)) | ||
273 | return PTR_ERR(dwmac->regs); | ||
274 | |||
275 | dwmac->pdev = pdev; | ||
276 | dwmac->phy_mode = of_get_phy_mode(pdev->dev.of_node); | ||
277 | if (dwmac->phy_mode < 0) { | ||
278 | dev_err(&pdev->dev, "missing phy-mode property\n"); | ||
279 | return -EINVAL; | ||
280 | } | ||
281 | |||
282 | ret = meson8b_init_clk(dwmac); | ||
283 | if (ret) | ||
284 | return ret; | ||
285 | |||
286 | ret = meson8b_init_prg_eth(dwmac); | ||
287 | if (ret) | ||
288 | return ret; | ||
289 | |||
290 | plat_dat->bsp_priv = dwmac; | ||
291 | |||
292 | return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); | ||
293 | } | ||
294 | |||
295 | static int meson8b_dwmac_remove(struct platform_device *pdev) | ||
296 | { | ||
297 | struct meson8b_dwmac *dwmac = get_stmmac_bsp_priv(&pdev->dev); | ||
298 | |||
299 | clk_disable_unprepare(dwmac->m25_div_clk); | ||
300 | |||
301 | return stmmac_pltfr_remove(pdev); | ||
302 | } | ||
303 | |||
304 | static const struct of_device_id meson8b_dwmac_match[] = { | ||
305 | { .compatible = "amlogic,meson8b-dwmac" }, | ||
306 | { .compatible = "amlogic,meson-gxbb-dwmac" }, | ||
307 | { } | ||
308 | }; | ||
309 | MODULE_DEVICE_TABLE(of, meson8b_dwmac_match); | ||
310 | |||
311 | static struct platform_driver meson8b_dwmac_driver = { | ||
312 | .probe = meson8b_dwmac_probe, | ||
313 | .remove = meson8b_dwmac_remove, | ||
314 | .driver = { | ||
315 | .name = "meson8b-dwmac", | ||
316 | .pm = &stmmac_pltfr_pm_ops, | ||
317 | .of_match_table = meson8b_dwmac_match, | ||
318 | }, | ||
319 | }; | ||
320 | module_platform_driver(meson8b_dwmac_driver); | ||
321 | |||
322 | MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>"); | ||
323 | MODULE_DESCRIPTION("Amlogic Meson8b and GXBB DWMAC glue layer"); | ||
324 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h index ffeb8d9e2b2e..64e147f53a9c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h | |||
@@ -30,4 +30,12 @@ int stmmac_get_platform_resources(struct platform_device *pdev, | |||
30 | int stmmac_pltfr_remove(struct platform_device *pdev); | 30 | int stmmac_pltfr_remove(struct platform_device *pdev); |
31 | extern const struct dev_pm_ops stmmac_pltfr_pm_ops; | 31 | extern const struct dev_pm_ops stmmac_pltfr_pm_ops; |
32 | 32 | ||
33 | static inline void *get_stmmac_bsp_priv(struct device *dev) | ||
34 | { | ||
35 | struct net_device *ndev = dev_get_drvdata(dev); | ||
36 | struct stmmac_priv *priv = netdev_priv(ndev); | ||
37 | |||
38 | return priv->plat->bsp_priv; | ||
39 | } | ||
40 | |||
33 | #endif /* __STMMAC_PLATFORM_H__ */ | 41 | #endif /* __STMMAC_PLATFORM_H__ */ |