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
),
50 if (!plat
->mdio_bus_data
)
53 dma_cfg
= devm_kzalloc(&pdev
->dev
, sizeof(*dma_cfg
), GFP_KERNEL
);
57 plat
->dma_cfg
= dma_cfg
;
58 of_property_read_u32(np
, "samsung,pbl", &dma_cfg
->pbl
);
59 if (of_property_read_u32(np
, "samsung,burst-map", &dma_cfg
->burst_map
) == 0)
60 dma_cfg
->fixed_burst
= true;
65 static int sxgbe_probe_config_dt(struct platform_device
*pdev
,
66 struct sxgbe_plat_data
*plat
,
71 #endif /* CONFIG_OF */
74 * sxgbe_platform_probe
75 * @pdev: platform device pointer
76 * Description: platform_device probe function. It allocates
77 * the necessary resources and invokes the main to init
78 * the net device, register the mdio bus etc.
80 static int sxgbe_platform_probe(struct platform_device
*pdev
)
85 struct device
*dev
= &pdev
->dev
;
87 struct sxgbe_priv_data
*priv
= NULL
;
88 struct sxgbe_plat_data
*plat_dat
= NULL
;
89 const char *mac
= NULL
;
90 struct net_device
*ndev
= platform_get_drvdata(pdev
);
91 struct device_node
*node
= dev
->of_node
;
93 /* Get memory resource */
94 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
95 addr
= devm_ioremap_resource(dev
, res
);
99 if (pdev
->dev
.of_node
) {
100 plat_dat
= devm_kzalloc(&pdev
->dev
,
101 sizeof(struct sxgbe_plat_data
),
106 ret
= sxgbe_probe_config_dt(pdev
, plat_dat
, &mac
);
108 pr_err("%s: main dt probe failed\n", __func__
);
113 priv
= sxgbe_drv_probe(&(pdev
->dev
), plat_dat
, addr
);
115 pr_err("%s: main driver probe failed\n", __func__
);
119 /* Get the SXGBE common INT information */
120 priv
->irq
= irq_of_parse_and_map(node
, 0);
121 if (priv
->irq
<= 0) {
122 dev_err(dev
, "sxgbe common irq parsing failed\n");
126 /* Get MAC address if available (DT) */
128 ether_addr_copy(priv
->dev
->dev_addr
, mac
);
130 /* Get the TX/RX IRQ numbers */
131 for (i
= 0, chan
= 1; i
< SXGBE_TX_QUEUES
; i
++) {
132 priv
->txq
[i
]->irq_no
= irq_of_parse_and_map(node
, chan
++);
133 if (priv
->txq
[i
]->irq_no
<= 0) {
134 dev_err(dev
, "sxgbe tx irq parsing failed\n");
135 goto err_tx_irq_unmap
;
139 for (i
= 0; i
< SXGBE_RX_QUEUES
; i
++) {
140 priv
->rxq
[i
]->irq_no
= irq_of_parse_and_map(node
, chan
++);
141 if (priv
->rxq
[i
]->irq_no
<= 0) {
142 dev_err(dev
, "sxgbe rx irq parsing failed\n");
143 goto err_rx_irq_unmap
;
147 priv
->lpi_irq
= irq_of_parse_and_map(node
, chan
);
148 if (priv
->lpi_irq
<= 0) {
149 dev_err(dev
, "sxgbe lpi irq parsing failed\n");
150 goto err_rx_irq_unmap
;
153 platform_set_drvdata(pdev
, priv
->dev
);
155 pr_debug("platform driver registration completed\n");
161 irq_dispose_mapping(priv
->rxq
[i
]->irq_no
);
165 irq_dispose_mapping(priv
->txq
[i
]->irq_no
);
166 irq_dispose_mapping(priv
->irq
);
168 sxgbe_drv_remove(ndev
);
174 * sxgbe_platform_remove
175 * @pdev: platform device pointer
176 * Description: this function calls the main to free the net resources
177 * and calls the platforms hook and release the resources (e.g. mem).
179 static int sxgbe_platform_remove(struct platform_device
*pdev
)
181 struct net_device
*ndev
= platform_get_drvdata(pdev
);
182 int ret
= sxgbe_drv_remove(ndev
);
188 static int sxgbe_platform_suspend(struct device
*dev
)
190 struct net_device
*ndev
= dev_get_drvdata(dev
);
192 return sxgbe_suspend(ndev
);
195 static int sxgbe_platform_resume(struct device
*dev
)
197 struct net_device
*ndev
= dev_get_drvdata(dev
);
199 return sxgbe_resume(ndev
);
202 static int sxgbe_platform_freeze(struct device
*dev
)
204 struct net_device
*ndev
= dev_get_drvdata(dev
);
206 return sxgbe_freeze(ndev
);
209 static int sxgbe_platform_restore(struct device
*dev
)
211 struct net_device
*ndev
= dev_get_drvdata(dev
);
213 return sxgbe_restore(ndev
);
216 static const struct dev_pm_ops sxgbe_platform_pm_ops
= {
217 .suspend
= sxgbe_platform_suspend
,
218 .resume
= sxgbe_platform_resume
,
219 .freeze
= sxgbe_platform_freeze
,
220 .thaw
= sxgbe_platform_restore
,
221 .restore
= sxgbe_platform_restore
,
224 static const struct dev_pm_ops sxgbe_platform_pm_ops
;
225 #endif /* CONFIG_PM */
227 static const struct of_device_id sxgbe_dt_ids
[] = {
228 { .compatible
= "samsung,sxgbe-v2.0a"},
231 MODULE_DEVICE_TABLE(of
, sxgbe_dt_ids
);
233 static struct platform_driver sxgbe_platform_driver
= {
234 .probe
= sxgbe_platform_probe
,
235 .remove
= sxgbe_platform_remove
,
237 .name
= SXGBE_RESOURCE_NAME
,
238 .pm
= &sxgbe_platform_pm_ops
,
239 .of_match_table
= of_match_ptr(sxgbe_dt_ids
),
243 int sxgbe_register_platform(void)
247 err
= platform_driver_register(&sxgbe_platform_driver
);
249 pr_err("failed to register the platform driver\n");
254 void sxgbe_unregister_platform(void)
256 platform_driver_unregister(&sxgbe_platform_driver
);