1 /* 10G controller driver for Samsung SoCs
3 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
6 * Author: Siva Reddy Kallam <siva.kallam@samsung.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15 #include <linux/etherdevice.h>
17 #include <linux/module.h>
18 #include <linux/netdevice.h>
20 #include <linux/of_irq.h>
21 #include <linux/of_net.h>
22 #include <linux/phy.h>
23 #include <linux/platform_device.h>
24 #include <linux/sxgbe_platform.h>
26 #include "sxgbe_common.h"
27 #include "sxgbe_reg.h"
30 static int sxgbe_probe_config_dt(struct platform_device
*pdev
,
31 struct sxgbe_plat_data
*plat
,
34 struct device_node
*np
= pdev
->dev
.of_node
;
35 struct sxgbe_dma_cfg
*dma_cfg
;
40 *mac
= of_get_mac_address(np
);
41 plat
->interface
= of_get_phy_mode(np
);
43 plat
->bus_id
= of_alias_get_id(np
, "ethernet");
47 plat
->mdio_bus_data
= devm_kzalloc(&pdev
->dev
,
48 sizeof(*plat
->mdio_bus_data
),
51 dma_cfg
= devm_kzalloc(&pdev
->dev
, sizeof(*dma_cfg
), GFP_KERNEL
);
55 plat
->dma_cfg
= dma_cfg
;
56 of_property_read_u32(np
, "samsung,pbl", &dma_cfg
->pbl
);
57 if (of_property_read_u32(np
, "samsung,burst-map", &dma_cfg
->burst_map
) == 0)
58 dma_cfg
->fixed_burst
= true;
63 static int sxgbe_probe_config_dt(struct platform_device
*pdev
,
64 struct sxgbe_plat_data
*plat
,
69 #endif /* CONFIG_OF */
72 * sxgbe_platform_probe
73 * @pdev: platform device pointer
74 * Description: platform_device probe function. It allocates
75 * the necessary resources and invokes the main to init
76 * the net device, register the mdio bus etc.
78 static int sxgbe_platform_probe(struct platform_device
*pdev
)
83 struct device
*dev
= &pdev
->dev
;
85 struct sxgbe_priv_data
*priv
= NULL
;
86 struct sxgbe_plat_data
*plat_dat
= NULL
;
87 const char *mac
= NULL
;
88 struct net_device
*ndev
= platform_get_drvdata(pdev
);
89 struct device_node
*node
= dev
->of_node
;
91 /* Get memory resource */
92 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
93 addr
= devm_ioremap_resource(dev
, res
);
97 if (pdev
->dev
.of_node
) {
98 plat_dat
= devm_kzalloc(&pdev
->dev
,
99 sizeof(struct sxgbe_plat_data
),
104 ret
= sxgbe_probe_config_dt(pdev
, plat_dat
, &mac
);
106 pr_err("%s: main dt probe failed\n", __func__
);
111 priv
= sxgbe_drv_probe(&(pdev
->dev
), plat_dat
, addr
);
113 pr_err("%s: main driver probe failed\n", __func__
);
117 /* Get the SXGBE common INT information */
118 priv
->irq
= irq_of_parse_and_map(node
, 0);
119 if (priv
->irq
<= 0) {
120 dev_err(dev
, "sxgbe common irq parsing failed\n");
124 /* Get MAC address if available (DT) */
126 ether_addr_copy(priv
->dev
->dev_addr
, mac
);
128 /* Get the TX/RX IRQ numbers */
129 for (i
= 0, chan
= 1; i
< SXGBE_TX_QUEUES
; i
++) {
130 priv
->txq
[i
]->irq_no
= irq_of_parse_and_map(node
, chan
++);
131 if (priv
->txq
[i
]->irq_no
<= 0) {
132 dev_err(dev
, "sxgbe tx irq parsing failed\n");
133 goto err_tx_irq_unmap
;
137 for (i
= 0; i
< SXGBE_RX_QUEUES
; i
++) {
138 priv
->rxq
[i
]->irq_no
= irq_of_parse_and_map(node
, chan
++);
139 if (priv
->rxq
[i
]->irq_no
<= 0) {
140 dev_err(dev
, "sxgbe rx irq parsing failed\n");
141 goto err_rx_irq_unmap
;
145 priv
->lpi_irq
= irq_of_parse_and_map(node
, chan
);
146 if (priv
->lpi_irq
<= 0) {
147 dev_err(dev
, "sxgbe lpi irq parsing failed\n");
148 goto err_rx_irq_unmap
;
151 platform_set_drvdata(pdev
, priv
->dev
);
153 pr_debug("platform driver registration completed\n");
159 irq_dispose_mapping(priv
->rxq
[i
]->irq_no
);
163 irq_dispose_mapping(priv
->txq
[i
]->irq_no
);
164 irq_dispose_mapping(priv
->irq
);
166 sxgbe_drv_remove(ndev
);
172 * sxgbe_platform_remove
173 * @pdev: platform device pointer
174 * Description: this function calls the main to free the net resources
175 * and calls the platforms hook and release the resources (e.g. mem).
177 static int sxgbe_platform_remove(struct platform_device
*pdev
)
179 struct net_device
*ndev
= platform_get_drvdata(pdev
);
180 int ret
= sxgbe_drv_remove(ndev
);
186 static int sxgbe_platform_suspend(struct device
*dev
)
188 struct net_device
*ndev
= dev_get_drvdata(dev
);
190 return sxgbe_suspend(ndev
);
193 static int sxgbe_platform_resume(struct device
*dev
)
195 struct net_device
*ndev
= dev_get_drvdata(dev
);
197 return sxgbe_resume(ndev
);
200 static int sxgbe_platform_freeze(struct device
*dev
)
202 struct net_device
*ndev
= dev_get_drvdata(dev
);
204 return sxgbe_freeze(ndev
);
207 static int sxgbe_platform_restore(struct device
*dev
)
209 struct net_device
*ndev
= dev_get_drvdata(dev
);
211 return sxgbe_restore(ndev
);
214 static const struct dev_pm_ops sxgbe_platform_pm_ops
= {
215 .suspend
= sxgbe_platform_suspend
,
216 .resume
= sxgbe_platform_resume
,
217 .freeze
= sxgbe_platform_freeze
,
218 .thaw
= sxgbe_platform_restore
,
219 .restore
= sxgbe_platform_restore
,
222 static const struct dev_pm_ops sxgbe_platform_pm_ops
;
223 #endif /* CONFIG_PM */
225 static const struct of_device_id sxgbe_dt_ids
[] = {
226 { .compatible
= "samsung,sxgbe-v2.0a"},
229 MODULE_DEVICE_TABLE(of
, sxgbe_dt_ids
);
231 static struct platform_driver sxgbe_platform_driver
= {
232 .probe
= sxgbe_platform_probe
,
233 .remove
= sxgbe_platform_remove
,
235 .name
= SXGBE_RESOURCE_NAME
,
236 .pm
= &sxgbe_platform_pm_ops
,
237 .of_match_table
= of_match_ptr(sxgbe_dt_ids
),
241 int sxgbe_register_platform(void)
245 err
= platform_driver_register(&sxgbe_platform_driver
);
247 pr_err("failed to register the platform driver\n");
252 void sxgbe_unregister_platform(void)
254 platform_driver_unregister(&sxgbe_platform_driver
);