1 // SPDX-License-Identifier: GPL-2.0-only
2 /* 10G controller driver for Samsung SoCs
4 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
7 * Author: Siva Reddy Kallam <siva.kallam@samsung.com>
10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12 #include <linux/etherdevice.h>
14 #include <linux/module.h>
15 #include <linux/netdevice.h>
17 #include <linux/of_irq.h>
18 #include <linux/of_net.h>
19 #include <linux/phy.h>
20 #include <linux/platform_device.h>
21 #include <linux/sxgbe_platform.h>
23 #include "sxgbe_common.h"
24 #include "sxgbe_reg.h"
27 static int sxgbe_probe_config_dt(struct platform_device
*pdev
,
28 struct sxgbe_plat_data
*plat
,
31 struct device_node
*np
= pdev
->dev
.of_node
;
32 struct sxgbe_dma_cfg
*dma_cfg
;
38 *mac
= of_get_mac_address(np
);
39 err
= of_get_phy_mode(np
, &plat
->interface
);
40 if (err
&& err
!= -ENODEV
)
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
)
84 struct device
*dev
= &pdev
->dev
;
86 struct sxgbe_priv_data
*priv
= NULL
;
87 struct sxgbe_plat_data
*plat_dat
= NULL
;
88 const char *mac
= NULL
;
89 struct net_device
*ndev
= platform_get_drvdata(pdev
);
90 struct device_node
*node
= dev
->of_node
;
92 /* Get memory resource */
93 addr
= devm_platform_ioremap_resource(pdev
, 0);
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) */
125 if (!IS_ERR_OR_NULL(mac
))
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
);