1b38dd98fSNobuhiro Iwamatsu // SPDX-License-Identifier: GPL-2.0
2b38dd98fSNobuhiro Iwamatsu /* Toshiba Visconti Ethernet Support
3b38dd98fSNobuhiro Iwamatsu *
4b38dd98fSNobuhiro Iwamatsu * (C) Copyright 2020 TOSHIBA CORPORATION
5b38dd98fSNobuhiro Iwamatsu * (C) Copyright 2020 Toshiba Electronic Devices & Storage Corporation
6b38dd98fSNobuhiro Iwamatsu */
7b38dd98fSNobuhiro Iwamatsu
8b38dd98fSNobuhiro Iwamatsu #include <linux/module.h>
93d40aed8SRob Herring #include <linux/of.h>
103d40aed8SRob Herring #include <linux/platform_device.h>
11b38dd98fSNobuhiro Iwamatsu #include <linux/of_net.h>
12b38dd98fSNobuhiro Iwamatsu #include <linux/stmmac.h>
13b38dd98fSNobuhiro Iwamatsu
14b38dd98fSNobuhiro Iwamatsu #include "stmmac_platform.h"
15b38dd98fSNobuhiro Iwamatsu #include "dwmac4.h"
16b38dd98fSNobuhiro Iwamatsu
17b38dd98fSNobuhiro Iwamatsu #define REG_ETHER_CONTROL 0x52D4
18b38dd98fSNobuhiro Iwamatsu #define ETHER_ETH_CONTROL_RESET BIT(17)
19b38dd98fSNobuhiro Iwamatsu
20b38dd98fSNobuhiro Iwamatsu #define REG_ETHER_CLOCK_SEL 0x52D0
21b38dd98fSNobuhiro Iwamatsu #define ETHER_CLK_SEL_TX_CLK_EN BIT(0)
22b38dd98fSNobuhiro Iwamatsu #define ETHER_CLK_SEL_RX_CLK_EN BIT(1)
23b38dd98fSNobuhiro Iwamatsu #define ETHER_CLK_SEL_RMII_CLK_EN BIT(2)
24b38dd98fSNobuhiro Iwamatsu #define ETHER_CLK_SEL_RMII_CLK_RST BIT(3)
25b38dd98fSNobuhiro Iwamatsu #define ETHER_CLK_SEL_DIV_SEL_2 BIT(4)
261ba1a4a9SYuji Ishikawa #define ETHER_CLK_SEL_DIV_SEL_20 0
27b38dd98fSNobuhiro Iwamatsu #define ETHER_CLK_SEL_FREQ_SEL_125M (BIT(9) | BIT(8))
28b38dd98fSNobuhiro Iwamatsu #define ETHER_CLK_SEL_FREQ_SEL_50M BIT(9)
29b38dd98fSNobuhiro Iwamatsu #define ETHER_CLK_SEL_FREQ_SEL_25M BIT(8)
30391e5975SNobuhiro Iwamatsu #define ETHER_CLK_SEL_FREQ_SEL_2P5M 0
311ba1a4a9SYuji Ishikawa #define ETHER_CLK_SEL_TX_CLK_EXT_SEL_IN 0
32b38dd98fSNobuhiro Iwamatsu #define ETHER_CLK_SEL_TX_CLK_EXT_SEL_TXC BIT(10)
33b38dd98fSNobuhiro Iwamatsu #define ETHER_CLK_SEL_TX_CLK_EXT_SEL_DIV BIT(11)
341ba1a4a9SYuji Ishikawa #define ETHER_CLK_SEL_RX_CLK_EXT_SEL_IN 0
35b38dd98fSNobuhiro Iwamatsu #define ETHER_CLK_SEL_RX_CLK_EXT_SEL_RXC BIT(12)
36b38dd98fSNobuhiro Iwamatsu #define ETHER_CLK_SEL_RX_CLK_EXT_SEL_DIV BIT(13)
371ba1a4a9SYuji Ishikawa #define ETHER_CLK_SEL_TX_CLK_O_TX_I 0
38b38dd98fSNobuhiro Iwamatsu #define ETHER_CLK_SEL_TX_CLK_O_RMII_I BIT(14)
39b38dd98fSNobuhiro Iwamatsu #define ETHER_CLK_SEL_TX_O_E_N_IN BIT(15)
401ba1a4a9SYuji Ishikawa #define ETHER_CLK_SEL_RMII_CLK_SEL_IN 0
41b38dd98fSNobuhiro Iwamatsu #define ETHER_CLK_SEL_RMII_CLK_SEL_RX_C BIT(16)
42b38dd98fSNobuhiro Iwamatsu
43b38dd98fSNobuhiro Iwamatsu #define ETHER_CLK_SEL_RX_TX_CLK_EN (ETHER_CLK_SEL_RX_CLK_EN | ETHER_CLK_SEL_TX_CLK_EN)
44b38dd98fSNobuhiro Iwamatsu
45b38dd98fSNobuhiro Iwamatsu #define ETHER_CONFIG_INTF_MII 0
46b38dd98fSNobuhiro Iwamatsu #define ETHER_CONFIG_INTF_RGMII BIT(0)
47b38dd98fSNobuhiro Iwamatsu #define ETHER_CONFIG_INTF_RMII BIT(2)
48b38dd98fSNobuhiro Iwamatsu
49b38dd98fSNobuhiro Iwamatsu struct visconti_eth {
50b38dd98fSNobuhiro Iwamatsu void __iomem *reg;
51b38dd98fSNobuhiro Iwamatsu u32 phy_intf_sel;
52b38dd98fSNobuhiro Iwamatsu struct clk *phy_ref_clk;
53928d6fe9SYuji Ishikawa struct device *dev;
54b38dd98fSNobuhiro Iwamatsu spinlock_t lock; /* lock to protect register update */
55b38dd98fSNobuhiro Iwamatsu };
56b38dd98fSNobuhiro Iwamatsu
visconti_eth_fix_mac_speed(void * priv,unsigned int speed,unsigned int mode)571fc04a0bSShenwei Wang static void visconti_eth_fix_mac_speed(void *priv, unsigned int speed, unsigned int mode)
58b38dd98fSNobuhiro Iwamatsu {
59b38dd98fSNobuhiro Iwamatsu struct visconti_eth *dwmac = priv;
60928d6fe9SYuji Ishikawa struct net_device *netdev = dev_get_drvdata(dwmac->dev);
61928d6fe9SYuji Ishikawa unsigned int val, clk_sel_val = 0;
62b38dd98fSNobuhiro Iwamatsu unsigned long flags;
63b38dd98fSNobuhiro Iwamatsu
64b38dd98fSNobuhiro Iwamatsu spin_lock_irqsave(&dwmac->lock, flags);
65b38dd98fSNobuhiro Iwamatsu
66b38dd98fSNobuhiro Iwamatsu /* adjust link */
67b38dd98fSNobuhiro Iwamatsu val = readl(dwmac->reg + MAC_CTRL_REG);
68b38dd98fSNobuhiro Iwamatsu val &= ~(GMAC_CONFIG_PS | GMAC_CONFIG_FES);
69b38dd98fSNobuhiro Iwamatsu
70b38dd98fSNobuhiro Iwamatsu switch (speed) {
71b38dd98fSNobuhiro Iwamatsu case SPEED_1000:
72b38dd98fSNobuhiro Iwamatsu if (dwmac->phy_intf_sel == ETHER_CONFIG_INTF_RGMII)
73b38dd98fSNobuhiro Iwamatsu clk_sel_val = ETHER_CLK_SEL_FREQ_SEL_125M;
74b38dd98fSNobuhiro Iwamatsu break;
75b38dd98fSNobuhiro Iwamatsu case SPEED_100:
76b38dd98fSNobuhiro Iwamatsu if (dwmac->phy_intf_sel == ETHER_CONFIG_INTF_RGMII)
77b38dd98fSNobuhiro Iwamatsu clk_sel_val = ETHER_CLK_SEL_FREQ_SEL_25M;
78b38dd98fSNobuhiro Iwamatsu if (dwmac->phy_intf_sel == ETHER_CONFIG_INTF_RMII)
79b38dd98fSNobuhiro Iwamatsu clk_sel_val = ETHER_CLK_SEL_DIV_SEL_2;
80b38dd98fSNobuhiro Iwamatsu val |= GMAC_CONFIG_PS | GMAC_CONFIG_FES;
81b38dd98fSNobuhiro Iwamatsu break;
82b38dd98fSNobuhiro Iwamatsu case SPEED_10:
83b38dd98fSNobuhiro Iwamatsu if (dwmac->phy_intf_sel == ETHER_CONFIG_INTF_RGMII)
84b38dd98fSNobuhiro Iwamatsu clk_sel_val = ETHER_CLK_SEL_FREQ_SEL_2P5M;
85b38dd98fSNobuhiro Iwamatsu if (dwmac->phy_intf_sel == ETHER_CONFIG_INTF_RMII)
86b38dd98fSNobuhiro Iwamatsu clk_sel_val = ETHER_CLK_SEL_DIV_SEL_20;
87b38dd98fSNobuhiro Iwamatsu val |= GMAC_CONFIG_PS;
88b38dd98fSNobuhiro Iwamatsu break;
89b38dd98fSNobuhiro Iwamatsu default:
90b38dd98fSNobuhiro Iwamatsu /* No bit control */
91928d6fe9SYuji Ishikawa netdev_err(netdev, "Unsupported speed request (%d)", speed);
92928d6fe9SYuji Ishikawa spin_unlock_irqrestore(&dwmac->lock, flags);
93928d6fe9SYuji Ishikawa return;
94b38dd98fSNobuhiro Iwamatsu }
95b38dd98fSNobuhiro Iwamatsu
96b38dd98fSNobuhiro Iwamatsu writel(val, dwmac->reg + MAC_CTRL_REG);
97b38dd98fSNobuhiro Iwamatsu
98b38dd98fSNobuhiro Iwamatsu /* Stop internal clock */
99b38dd98fSNobuhiro Iwamatsu val = readl(dwmac->reg + REG_ETHER_CLOCK_SEL);
100b38dd98fSNobuhiro Iwamatsu val &= ~(ETHER_CLK_SEL_RMII_CLK_EN | ETHER_CLK_SEL_RX_TX_CLK_EN);
101b38dd98fSNobuhiro Iwamatsu val |= ETHER_CLK_SEL_TX_O_E_N_IN;
102b38dd98fSNobuhiro Iwamatsu writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
103b38dd98fSNobuhiro Iwamatsu
1040959bc4bSYuji Ishikawa /* Set Clock-Mux, Start clock, Set TX_O direction */
105b38dd98fSNobuhiro Iwamatsu switch (dwmac->phy_intf_sel) {
106b38dd98fSNobuhiro Iwamatsu case ETHER_CONFIG_INTF_RGMII:
107b38dd98fSNobuhiro Iwamatsu val = clk_sel_val | ETHER_CLK_SEL_RX_CLK_EXT_SEL_RXC;
108b38dd98fSNobuhiro Iwamatsu writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
1090959bc4bSYuji Ishikawa
110b38dd98fSNobuhiro Iwamatsu val |= ETHER_CLK_SEL_RX_TX_CLK_EN;
111b38dd98fSNobuhiro Iwamatsu writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
112b38dd98fSNobuhiro Iwamatsu
113b38dd98fSNobuhiro Iwamatsu val &= ~ETHER_CLK_SEL_TX_O_E_N_IN;
114b38dd98fSNobuhiro Iwamatsu writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
1150959bc4bSYuji Ishikawa break;
1160959bc4bSYuji Ishikawa case ETHER_CONFIG_INTF_RMII:
1170959bc4bSYuji Ishikawa val = clk_sel_val | ETHER_CLK_SEL_RX_CLK_EXT_SEL_DIV |
1180959bc4bSYuji Ishikawa ETHER_CLK_SEL_TX_CLK_EXT_SEL_DIV | ETHER_CLK_SEL_TX_O_E_N_IN |
1190959bc4bSYuji Ishikawa ETHER_CLK_SEL_RMII_CLK_SEL_RX_C;
1200959bc4bSYuji Ishikawa writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
1210959bc4bSYuji Ishikawa
1220959bc4bSYuji Ishikawa val |= ETHER_CLK_SEL_RMII_CLK_RST;
1230959bc4bSYuji Ishikawa writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
1240959bc4bSYuji Ishikawa
1250959bc4bSYuji Ishikawa val |= ETHER_CLK_SEL_RMII_CLK_EN | ETHER_CLK_SEL_RX_TX_CLK_EN;
1260959bc4bSYuji Ishikawa writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
1270959bc4bSYuji Ishikawa break;
1280959bc4bSYuji Ishikawa case ETHER_CONFIG_INTF_MII:
1290959bc4bSYuji Ishikawa default:
1300959bc4bSYuji Ishikawa val = clk_sel_val | ETHER_CLK_SEL_RX_CLK_EXT_SEL_RXC |
1310959bc4bSYuji Ishikawa ETHER_CLK_SEL_TX_CLK_EXT_SEL_TXC | ETHER_CLK_SEL_TX_O_E_N_IN;
1320959bc4bSYuji Ishikawa writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
1330959bc4bSYuji Ishikawa
1340959bc4bSYuji Ishikawa val |= ETHER_CLK_SEL_RX_TX_CLK_EN;
1350959bc4bSYuji Ishikawa writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
1360959bc4bSYuji Ishikawa break;
1370959bc4bSYuji Ishikawa }
138b38dd98fSNobuhiro Iwamatsu
139b38dd98fSNobuhiro Iwamatsu spin_unlock_irqrestore(&dwmac->lock, flags);
140b38dd98fSNobuhiro Iwamatsu }
141b38dd98fSNobuhiro Iwamatsu
visconti_eth_init_hw(struct platform_device * pdev,struct plat_stmmacenet_data * plat_dat)142b38dd98fSNobuhiro Iwamatsu static int visconti_eth_init_hw(struct platform_device *pdev, struct plat_stmmacenet_data *plat_dat)
143b38dd98fSNobuhiro Iwamatsu {
144b38dd98fSNobuhiro Iwamatsu struct visconti_eth *dwmac = plat_dat->bsp_priv;
145b38dd98fSNobuhiro Iwamatsu unsigned int reg_val, clk_sel_val;
146b38dd98fSNobuhiro Iwamatsu
147b38dd98fSNobuhiro Iwamatsu switch (plat_dat->phy_interface) {
148b38dd98fSNobuhiro Iwamatsu case PHY_INTERFACE_MODE_RGMII:
149b38dd98fSNobuhiro Iwamatsu case PHY_INTERFACE_MODE_RGMII_ID:
150b38dd98fSNobuhiro Iwamatsu case PHY_INTERFACE_MODE_RGMII_RXID:
151b38dd98fSNobuhiro Iwamatsu case PHY_INTERFACE_MODE_RGMII_TXID:
152b38dd98fSNobuhiro Iwamatsu dwmac->phy_intf_sel = ETHER_CONFIG_INTF_RGMII;
153b38dd98fSNobuhiro Iwamatsu break;
154b38dd98fSNobuhiro Iwamatsu case PHY_INTERFACE_MODE_MII:
155b38dd98fSNobuhiro Iwamatsu dwmac->phy_intf_sel = ETHER_CONFIG_INTF_MII;
156b38dd98fSNobuhiro Iwamatsu break;
157b38dd98fSNobuhiro Iwamatsu case PHY_INTERFACE_MODE_RMII:
158b38dd98fSNobuhiro Iwamatsu dwmac->phy_intf_sel = ETHER_CONFIG_INTF_RMII;
159b38dd98fSNobuhiro Iwamatsu break;
160b38dd98fSNobuhiro Iwamatsu default:
161b38dd98fSNobuhiro Iwamatsu dev_err(&pdev->dev, "Unsupported phy-mode (%d)\n", plat_dat->phy_interface);
162b38dd98fSNobuhiro Iwamatsu return -EOPNOTSUPP;
163b38dd98fSNobuhiro Iwamatsu }
164b38dd98fSNobuhiro Iwamatsu
165b38dd98fSNobuhiro Iwamatsu reg_val = dwmac->phy_intf_sel;
166b38dd98fSNobuhiro Iwamatsu writel(reg_val, dwmac->reg + REG_ETHER_CONTROL);
167b38dd98fSNobuhiro Iwamatsu
168b38dd98fSNobuhiro Iwamatsu /* Enable TX/RX clock */
169b38dd98fSNobuhiro Iwamatsu clk_sel_val = ETHER_CLK_SEL_FREQ_SEL_125M;
170b38dd98fSNobuhiro Iwamatsu writel(clk_sel_val, dwmac->reg + REG_ETHER_CLOCK_SEL);
171b38dd98fSNobuhiro Iwamatsu
172b38dd98fSNobuhiro Iwamatsu writel((clk_sel_val | ETHER_CLK_SEL_RMII_CLK_EN | ETHER_CLK_SEL_RX_TX_CLK_EN),
173b38dd98fSNobuhiro Iwamatsu dwmac->reg + REG_ETHER_CLOCK_SEL);
174b38dd98fSNobuhiro Iwamatsu
175b38dd98fSNobuhiro Iwamatsu /* release internal-reset */
176b38dd98fSNobuhiro Iwamatsu reg_val |= ETHER_ETH_CONTROL_RESET;
177b38dd98fSNobuhiro Iwamatsu writel(reg_val, dwmac->reg + REG_ETHER_CONTROL);
178b38dd98fSNobuhiro Iwamatsu
179b38dd98fSNobuhiro Iwamatsu return 0;
180b38dd98fSNobuhiro Iwamatsu }
181b38dd98fSNobuhiro Iwamatsu
visconti_eth_clock_probe(struct platform_device * pdev,struct plat_stmmacenet_data * plat_dat)182b38dd98fSNobuhiro Iwamatsu static int visconti_eth_clock_probe(struct platform_device *pdev,
183b38dd98fSNobuhiro Iwamatsu struct plat_stmmacenet_data *plat_dat)
184b38dd98fSNobuhiro Iwamatsu {
185b38dd98fSNobuhiro Iwamatsu struct visconti_eth *dwmac = plat_dat->bsp_priv;
186b38dd98fSNobuhiro Iwamatsu int err;
187b38dd98fSNobuhiro Iwamatsu
188b38dd98fSNobuhiro Iwamatsu dwmac->phy_ref_clk = devm_clk_get(&pdev->dev, "phy_ref_clk");
189b20b54fbSCai Huoqing if (IS_ERR(dwmac->phy_ref_clk))
190b20b54fbSCai Huoqing return dev_err_probe(&pdev->dev, PTR_ERR(dwmac->phy_ref_clk),
191b20b54fbSCai Huoqing "phy_ref_clk clock not found.\n");
192b38dd98fSNobuhiro Iwamatsu
193b38dd98fSNobuhiro Iwamatsu err = clk_prepare_enable(dwmac->phy_ref_clk);
194b38dd98fSNobuhiro Iwamatsu if (err < 0) {
195b38dd98fSNobuhiro Iwamatsu dev_err(&pdev->dev, "failed to enable phy_ref clock: %d\n", err);
196b38dd98fSNobuhiro Iwamatsu return err;
197b38dd98fSNobuhiro Iwamatsu }
198b38dd98fSNobuhiro Iwamatsu
199b38dd98fSNobuhiro Iwamatsu return 0;
200b38dd98fSNobuhiro Iwamatsu }
201b38dd98fSNobuhiro Iwamatsu
visconti_eth_clock_remove(struct platform_device * pdev)202b9bc44feSUwe Kleine-König static void visconti_eth_clock_remove(struct platform_device *pdev)
203b38dd98fSNobuhiro Iwamatsu {
204b38dd98fSNobuhiro Iwamatsu struct visconti_eth *dwmac = get_stmmac_bsp_priv(&pdev->dev);
205b38dd98fSNobuhiro Iwamatsu struct net_device *ndev = platform_get_drvdata(pdev);
206b38dd98fSNobuhiro Iwamatsu struct stmmac_priv *priv = netdev_priv(ndev);
207b38dd98fSNobuhiro Iwamatsu
208b38dd98fSNobuhiro Iwamatsu clk_disable_unprepare(dwmac->phy_ref_clk);
209b38dd98fSNobuhiro Iwamatsu clk_disable_unprepare(priv->plat->stmmac_clk);
210b38dd98fSNobuhiro Iwamatsu }
211b38dd98fSNobuhiro Iwamatsu
visconti_eth_dwmac_probe(struct platform_device * pdev)212b38dd98fSNobuhiro Iwamatsu static int visconti_eth_dwmac_probe(struct platform_device *pdev)
213b38dd98fSNobuhiro Iwamatsu {
214b38dd98fSNobuhiro Iwamatsu struct plat_stmmacenet_data *plat_dat;
215b38dd98fSNobuhiro Iwamatsu struct stmmac_resources stmmac_res;
216b38dd98fSNobuhiro Iwamatsu struct visconti_eth *dwmac;
217b38dd98fSNobuhiro Iwamatsu int ret;
218b38dd98fSNobuhiro Iwamatsu
219b38dd98fSNobuhiro Iwamatsu ret = stmmac_get_platform_resources(pdev, &stmmac_res);
220b38dd98fSNobuhiro Iwamatsu if (ret)
221b38dd98fSNobuhiro Iwamatsu return ret;
222b38dd98fSNobuhiro Iwamatsu
223d54ebfe8SJisheng Zhang plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
224b38dd98fSNobuhiro Iwamatsu if (IS_ERR(plat_dat))
225b38dd98fSNobuhiro Iwamatsu return PTR_ERR(plat_dat);
226b38dd98fSNobuhiro Iwamatsu
227b38dd98fSNobuhiro Iwamatsu dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
228d54ebfe8SJisheng Zhang if (!dwmac)
229d54ebfe8SJisheng Zhang return -ENOMEM;
230b38dd98fSNobuhiro Iwamatsu
23117d7fd47SWei Yongjun spin_lock_init(&dwmac->lock);
232b38dd98fSNobuhiro Iwamatsu dwmac->reg = stmmac_res.addr;
233928d6fe9SYuji Ishikawa dwmac->dev = &pdev->dev;
234b38dd98fSNobuhiro Iwamatsu plat_dat->bsp_priv = dwmac;
235b38dd98fSNobuhiro Iwamatsu plat_dat->fix_mac_speed = visconti_eth_fix_mac_speed;
236b38dd98fSNobuhiro Iwamatsu
237b38dd98fSNobuhiro Iwamatsu ret = visconti_eth_clock_probe(pdev, plat_dat);
238b38dd98fSNobuhiro Iwamatsu if (ret)
239d54ebfe8SJisheng Zhang return ret;
240b38dd98fSNobuhiro Iwamatsu
241b38dd98fSNobuhiro Iwamatsu visconti_eth_init_hw(pdev, plat_dat);
242b38dd98fSNobuhiro Iwamatsu
243b38dd98fSNobuhiro Iwamatsu plat_dat->dma_cfg->aal = 1;
244b38dd98fSNobuhiro Iwamatsu
245b38dd98fSNobuhiro Iwamatsu ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
246b38dd98fSNobuhiro Iwamatsu if (ret)
247b38dd98fSNobuhiro Iwamatsu goto remove;
248b38dd98fSNobuhiro Iwamatsu
249b38dd98fSNobuhiro Iwamatsu return ret;
250b38dd98fSNobuhiro Iwamatsu
251b38dd98fSNobuhiro Iwamatsu remove:
252b38dd98fSNobuhiro Iwamatsu visconti_eth_clock_remove(pdev);
253b38dd98fSNobuhiro Iwamatsu
254b38dd98fSNobuhiro Iwamatsu return ret;
255b38dd98fSNobuhiro Iwamatsu }
256b38dd98fSNobuhiro Iwamatsu
visconti_eth_dwmac_remove(struct platform_device * pdev)257f4d05c41SUwe Kleine-König static void visconti_eth_dwmac_remove(struct platform_device *pdev)
258b38dd98fSNobuhiro Iwamatsu {
259*a39058e0SJisheng Zhang stmmac_pltfr_remove(pdev);
260b9bc44feSUwe Kleine-König visconti_eth_clock_remove(pdev);
261b38dd98fSNobuhiro Iwamatsu }
262b38dd98fSNobuhiro Iwamatsu
263b38dd98fSNobuhiro Iwamatsu static const struct of_device_id visconti_eth_dwmac_match[] = {
264b38dd98fSNobuhiro Iwamatsu { .compatible = "toshiba,visconti-dwmac" },
265b38dd98fSNobuhiro Iwamatsu { }
266b38dd98fSNobuhiro Iwamatsu };
267b38dd98fSNobuhiro Iwamatsu MODULE_DEVICE_TABLE(of, visconti_eth_dwmac_match);
268b38dd98fSNobuhiro Iwamatsu
269b38dd98fSNobuhiro Iwamatsu static struct platform_driver visconti_eth_dwmac_driver = {
270b38dd98fSNobuhiro Iwamatsu .probe = visconti_eth_dwmac_probe,
271f4d05c41SUwe Kleine-König .remove_new = visconti_eth_dwmac_remove,
272b38dd98fSNobuhiro Iwamatsu .driver = {
273b38dd98fSNobuhiro Iwamatsu .name = "visconti-eth-dwmac",
274b38dd98fSNobuhiro Iwamatsu .of_match_table = visconti_eth_dwmac_match,
275b38dd98fSNobuhiro Iwamatsu },
276b38dd98fSNobuhiro Iwamatsu };
277b38dd98fSNobuhiro Iwamatsu module_platform_driver(visconti_eth_dwmac_driver);
278b38dd98fSNobuhiro Iwamatsu
279b38dd98fSNobuhiro Iwamatsu MODULE_AUTHOR("Toshiba");
280b38dd98fSNobuhiro Iwamatsu MODULE_DESCRIPTION("Toshiba Visconti Ethernet DWMAC glue driver");
281b38dd98fSNobuhiro Iwamatsu MODULE_AUTHOR("Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp");
282b38dd98fSNobuhiro Iwamatsu MODULE_LICENSE("GPL v2");
283