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
)
30 struct device_node
*np
= pdev
->dev
.of_node
;
31 struct sxgbe_dma_cfg
*dma_cfg
;
37 err
= of_get_phy_mode(np
, &plat
->interface
);
38 if (err
&& err
!= -ENODEV
)
41 plat
->bus_id
= of_alias_get_id(np
, "ethernet");
45 plat
->mdio_bus_data
= devm_kzalloc(&pdev
->dev
,
46 sizeof(*plat
->mdio_bus_data
),
48 if (!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
)
68 #endif /* CONFIG_OF */
71 * sxgbe_platform_probe
72 * @pdev: platform device pointer
73 * Description: platform_device probe function. It allocates
74 * the necessary resources and invokes the main to init
75 * the net device, register the mdio bus etc.
77 static int sxgbe_platform_probe(struct platform_device
*pdev
)
81 struct device
*dev
= &pdev
->dev
;
83 struct sxgbe_priv_data
*priv
= NULL
;
84 struct sxgbe_plat_data
*plat_dat
= NULL
;
85 struct net_device
*ndev
= platform_get_drvdata(pdev
);
86 struct device_node
*node
= dev
->of_node
;
88 /* Get memory resource */
89 addr
= devm_platform_ioremap_resource(pdev
, 0);
93 if (pdev
->dev
.of_node
) {
94 plat_dat
= devm_kzalloc(&pdev
->dev
,
95 sizeof(struct sxgbe_plat_data
),
100 ret
= sxgbe_probe_config_dt(pdev
, plat_dat
);
102 pr_err("%s: main dt probe failed\n", __func__
);
107 priv
= sxgbe_drv_probe(&(pdev
->dev
), plat_dat
, addr
);
109 pr_err("%s: main driver probe failed\n", __func__
);
113 /* Get the SXGBE common INT information */
114 priv
->irq
= irq_of_parse_and_map(node
, 0);
115 if (priv
->irq
<= 0) {
116 dev_err(dev
, "sxgbe common irq parsing failed\n");
120 /* Get MAC address if available (DT) */
121 of_get_ethdev_address(node
, priv
->dev
);
123 /* Get the TX/RX IRQ numbers */
124 for (i
= 0, chan
= 1; i
< SXGBE_TX_QUEUES
; i
++) {
125 priv
->txq
[i
]->irq_no
= irq_of_parse_and_map(node
, chan
++);
126 if (priv
->txq
[i
]->irq_no
<= 0) {
127 dev_err(dev
, "sxgbe tx irq parsing failed\n");
128 goto err_tx_irq_unmap
;
132 for (i
= 0; i
< SXGBE_RX_QUEUES
; i
++) {
133 priv
->rxq
[i
]->irq_no
= irq_of_parse_and_map(node
, chan
++);
134 if (priv
->rxq
[i
]->irq_no
<= 0) {
135 dev_err(dev
, "sxgbe rx irq parsing failed\n");
136 goto err_rx_irq_unmap
;
140 priv
->lpi_irq
= irq_of_parse_and_map(node
, chan
);
141 if (priv
->lpi_irq
<= 0) {
142 dev_err(dev
, "sxgbe lpi irq parsing failed\n");
143 goto err_rx_irq_unmap
;
146 platform_set_drvdata(pdev
, priv
->dev
);
148 pr_debug("platform driver registration completed\n");
154 irq_dispose_mapping(priv
->rxq
[i
]->irq_no
);
158 irq_dispose_mapping(priv
->txq
[i
]->irq_no
);
159 irq_dispose_mapping(priv
->irq
);
161 sxgbe_drv_remove(ndev
);
167 * sxgbe_platform_remove
168 * @pdev: platform device pointer
169 * Description: this function calls the main to free the net resources
170 * and calls the platforms hook and release the resources (e.g. mem).
172 static void sxgbe_platform_remove(struct platform_device
*pdev
)
174 struct net_device
*ndev
= platform_get_drvdata(pdev
);
176 sxgbe_drv_remove(ndev
);
180 static int sxgbe_platform_suspend(struct device
*dev
)
182 struct net_device
*ndev
= dev_get_drvdata(dev
);
184 return sxgbe_suspend(ndev
);
187 static int sxgbe_platform_resume(struct device
*dev
)
189 struct net_device
*ndev
= dev_get_drvdata(dev
);
191 return sxgbe_resume(ndev
);
194 static int sxgbe_platform_freeze(struct device
*dev
)
196 struct net_device
*ndev
= dev_get_drvdata(dev
);
198 return sxgbe_freeze(ndev
);
201 static int sxgbe_platform_restore(struct device
*dev
)
203 struct net_device
*ndev
= dev_get_drvdata(dev
);
205 return sxgbe_restore(ndev
);
208 static const struct dev_pm_ops sxgbe_platform_pm_ops
= {
209 .suspend
= sxgbe_platform_suspend
,
210 .resume
= sxgbe_platform_resume
,
211 .freeze
= sxgbe_platform_freeze
,
212 .thaw
= sxgbe_platform_restore
,
213 .restore
= sxgbe_platform_restore
,
216 static const struct dev_pm_ops sxgbe_platform_pm_ops
;
217 #endif /* CONFIG_PM */
219 static const struct of_device_id sxgbe_dt_ids
[] = {
220 { .compatible
= "samsung,sxgbe-v2.0a"},
223 MODULE_DEVICE_TABLE(of
, sxgbe_dt_ids
);
225 static struct platform_driver sxgbe_platform_driver
= {
226 .probe
= sxgbe_platform_probe
,
227 .remove
= sxgbe_platform_remove
,
229 .name
= SXGBE_RESOURCE_NAME
,
230 .pm
= &sxgbe_platform_pm_ops
,
231 .of_match_table
= sxgbe_dt_ids
,
235 int sxgbe_register_platform(void)
239 err
= platform_driver_register(&sxgbe_platform_driver
);
241 pr_err("failed to register the platform driver\n");
246 void sxgbe_unregister_platform(void)
248 platform_driver_unregister(&sxgbe_platform_driver
);