Commit b66ba8d5 authored by David S. Miller's avatar David S. Miller

Merge branch 'stmmac-probe-refactoring'

Joachim Eastwood says:

====================
stmmac: probe code refactoring and clean up part 1

This patch set refactor the code in stmmac_pci_probe and stmmac_pltfr_probe
and moves the common bits into stmmac_dvr_probe. Along the way some clean-
ups are applied to stmmac_pltfr_probe.

The code has been tested on the LPC18xx platform.

I am still working on more refactoring of the platform probe code, hence
part 1, but I need some more time on this.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 614919c3 def5cd3c
...@@ -34,6 +34,14 @@ ...@@ -34,6 +34,14 @@
#include <linux/ptp_clock_kernel.h> #include <linux/ptp_clock_kernel.h>
#include <linux/reset.h> #include <linux/reset.h>
struct stmmac_resources {
void __iomem *addr;
const char *mac;
int wol_irq;
int lpi_irq;
int irq;
};
struct stmmac_tx_info { struct stmmac_tx_info {
dma_addr_t buf; dma_addr_t buf;
bool map_as_page; bool map_as_page;
...@@ -129,9 +137,9 @@ void stmmac_ptp_unregister(struct stmmac_priv *priv); ...@@ -129,9 +137,9 @@ void stmmac_ptp_unregister(struct stmmac_priv *priv);
int stmmac_resume(struct net_device *ndev); int stmmac_resume(struct net_device *ndev);
int stmmac_suspend(struct net_device *ndev); int stmmac_suspend(struct net_device *ndev);
int stmmac_dvr_remove(struct net_device *ndev); int stmmac_dvr_remove(struct net_device *ndev);
struct stmmac_priv *stmmac_dvr_probe(struct device *device, int stmmac_dvr_probe(struct device *device,
struct plat_stmmacenet_data *plat_dat, struct plat_stmmacenet_data *plat_dat,
void __iomem *addr); struct stmmac_resources *res);
void stmmac_disable_eee_mode(struct stmmac_priv *priv); void stmmac_disable_eee_mode(struct stmmac_priv *priv);
bool stmmac_eee_init(struct stmmac_priv *priv); bool stmmac_eee_init(struct stmmac_priv *priv);
......
...@@ -2797,16 +2797,15 @@ static int stmmac_hw_init(struct stmmac_priv *priv) ...@@ -2797,16 +2797,15 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
* stmmac_dvr_probe * stmmac_dvr_probe
* @device: device pointer * @device: device pointer
* @plat_dat: platform data pointer * @plat_dat: platform data pointer
* @addr: iobase memory address * @res: stmmac resource pointer
* Description: this is the main probe function used to * Description: this is the main probe function used to
* call the alloc_etherdev, allocate the priv structure. * call the alloc_etherdev, allocate the priv structure.
* Return: * Return:
* on success the new private structure is returned, otherwise the error * returns 0 on success, otherwise errno.
* pointer.
*/ */
struct stmmac_priv *stmmac_dvr_probe(struct device *device, int stmmac_dvr_probe(struct device *device,
struct plat_stmmacenet_data *plat_dat, struct plat_stmmacenet_data *plat_dat,
void __iomem *addr) struct stmmac_resources *res)
{ {
int ret = 0; int ret = 0;
struct net_device *ndev = NULL; struct net_device *ndev = NULL;
...@@ -2814,7 +2813,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, ...@@ -2814,7 +2813,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
ndev = alloc_etherdev(sizeof(struct stmmac_priv)); ndev = alloc_etherdev(sizeof(struct stmmac_priv));
if (!ndev) if (!ndev)
return ERR_PTR(-ENOMEM); return -ENOMEM;
SET_NETDEV_DEV(ndev, device); SET_NETDEV_DEV(ndev, device);
...@@ -2825,8 +2824,17 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, ...@@ -2825,8 +2824,17 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
stmmac_set_ethtool_ops(ndev); stmmac_set_ethtool_ops(ndev);
priv->pause = pause; priv->pause = pause;
priv->plat = plat_dat; priv->plat = plat_dat;
priv->ioaddr = addr; priv->ioaddr = res->addr;
priv->dev->base_addr = (unsigned long)addr; priv->dev->base_addr = (unsigned long)res->addr;
priv->dev->irq = res->irq;
priv->wol_irq = res->wol_irq;
priv->lpi_irq = res->lpi_irq;
if (res->mac)
memcpy(priv->dev->dev_addr, res->mac, ETH_ALEN);
dev_set_drvdata(device, priv);
/* Verify driver arguments */ /* Verify driver arguments */
stmmac_verify_args(); stmmac_verify_args();
...@@ -2941,7 +2949,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, ...@@ -2941,7 +2949,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
} }
} }
return priv; return 0;
error_mdio_register: error_mdio_register:
unregister_netdev(ndev); unregister_netdev(ndev);
...@@ -2954,7 +2962,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, ...@@ -2954,7 +2962,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
error_clk_get: error_clk_get:
free_netdev(ndev); free_netdev(ndev);
return ERR_PTR(ret); return ret;
} }
EXPORT_SYMBOL_GPL(stmmac_dvr_probe); EXPORT_SYMBOL_GPL(stmmac_dvr_probe);
......
...@@ -163,7 +163,7 @@ static int stmmac_pci_probe(struct pci_dev *pdev, ...@@ -163,7 +163,7 @@ static int stmmac_pci_probe(struct pci_dev *pdev,
{ {
struct stmmac_pci_info *info = (struct stmmac_pci_info *)id->driver_data; struct stmmac_pci_info *info = (struct stmmac_pci_info *)id->driver_data;
struct plat_stmmacenet_data *plat; struct plat_stmmacenet_data *plat;
struct stmmac_priv *priv; struct stmmac_resources res;
int i; int i;
int ret; int ret;
...@@ -214,19 +214,12 @@ static int stmmac_pci_probe(struct pci_dev *pdev, ...@@ -214,19 +214,12 @@ static int stmmac_pci_probe(struct pci_dev *pdev,
pci_enable_msi(pdev); pci_enable_msi(pdev);
priv = stmmac_dvr_probe(&pdev->dev, plat, pcim_iomap_table(pdev)[i]); memset(&res, 0, sizeof(res));
if (IS_ERR(priv)) { res.addr = pcim_iomap_table(pdev)[i];
dev_err(&pdev->dev, "%s: main driver probe failed\n", __func__); res.wol_irq = pdev->irq;
return PTR_ERR(priv); res.irq = pdev->irq;
}
priv->dev->irq = pdev->irq;
priv->wol_irq = pdev->irq;
pci_set_drvdata(pdev, priv->dev);
dev_dbg(&pdev->dev, "STMMAC PCI driver registration completed\n"); return stmmac_dvr_probe(&pdev->dev, plat, &res);
return 0;
} }
/** /**
......
...@@ -112,13 +112,7 @@ static int stmmac_probe_config_dt(struct platform_device *pdev, ...@@ -112,13 +112,7 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
const struct of_device_id *device; const struct of_device_id *device;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
if (!np)
return -ENODEV;
device = of_match_device(dev->driver->of_match_table, dev); device = of_match_device(dev->driver->of_match_table, dev);
if (!device)
return -ENODEV;
if (device->data) { if (device->data) {
const struct stmmac_of_data *data = device->data; const struct stmmac_of_data *data = device->data;
plat->has_gmac = data->has_gmac; plat->has_gmac = data->has_gmac;
...@@ -252,25 +246,24 @@ static int stmmac_probe_config_dt(struct platform_device *pdev, ...@@ -252,25 +246,24 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
*/ */
int stmmac_pltfr_probe(struct platform_device *pdev) int stmmac_pltfr_probe(struct platform_device *pdev)
{ {
struct stmmac_resources stmmac_res;
int ret = 0; int ret = 0;
struct resource *res; struct resource *res;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
void __iomem *addr = NULL;
struct stmmac_priv *priv = NULL;
struct plat_stmmacenet_data *plat_dat = NULL; struct plat_stmmacenet_data *plat_dat = NULL;
const char *mac = NULL;
int irq, wol_irq, lpi_irq; memset(&stmmac_res, 0, sizeof(stmmac_res));
/* Get IRQ information early to have an ability to ask for deferred /* Get IRQ information early to have an ability to ask for deferred
* probe if needed before we went too far with resource allocation. * probe if needed before we went too far with resource allocation.
*/ */
irq = platform_get_irq_byname(pdev, "macirq"); stmmac_res.irq = platform_get_irq_byname(pdev, "macirq");
if (irq < 0) { if (stmmac_res.irq < 0) {
if (irq != -EPROBE_DEFER) { if (stmmac_res.irq != -EPROBE_DEFER) {
dev_err(dev, dev_err(dev,
"MAC IRQ configuration information not found\n"); "MAC IRQ configuration information not found\n");
} }
return irq; return stmmac_res.irq;
} }
/* On some platforms e.g. SPEAr the wake up irq differs from the mac irq /* On some platforms e.g. SPEAr the wake up irq differs from the mac irq
...@@ -280,21 +273,21 @@ int stmmac_pltfr_probe(struct platform_device *pdev) ...@@ -280,21 +273,21 @@ int stmmac_pltfr_probe(struct platform_device *pdev)
* In case the wake up interrupt is not passed from the platform * In case the wake up interrupt is not passed from the platform
* so the driver will continue to use the mac irq (ndev->irq) * so the driver will continue to use the mac irq (ndev->irq)
*/ */
wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq"); stmmac_res.wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq");
if (wol_irq < 0) { if (stmmac_res.wol_irq < 0) {
if (wol_irq == -EPROBE_DEFER) if (stmmac_res.wol_irq == -EPROBE_DEFER)
return -EPROBE_DEFER; return -EPROBE_DEFER;
wol_irq = irq; stmmac_res.wol_irq = stmmac_res.irq;
} }
lpi_irq = platform_get_irq_byname(pdev, "eth_lpi"); stmmac_res.lpi_irq = platform_get_irq_byname(pdev, "eth_lpi");
if (lpi_irq == -EPROBE_DEFER) if (stmmac_res.lpi_irq == -EPROBE_DEFER)
return -EPROBE_DEFER; return -EPROBE_DEFER;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
addr = devm_ioremap_resource(dev, res); stmmac_res.addr = devm_ioremap_resource(dev, res);
if (IS_ERR(addr)) if (IS_ERR(stmmac_res.addr))
return PTR_ERR(addr); return PTR_ERR(stmmac_res.addr);
plat_dat = dev_get_platdata(&pdev->dev); plat_dat = dev_get_platdata(&pdev->dev);
...@@ -314,7 +307,7 @@ int stmmac_pltfr_probe(struct platform_device *pdev) ...@@ -314,7 +307,7 @@ int stmmac_pltfr_probe(struct platform_device *pdev)
plat_dat->unicast_filter_entries = 1; plat_dat->unicast_filter_entries = 1;
if (pdev->dev.of_node) { if (pdev->dev.of_node) {
ret = stmmac_probe_config_dt(pdev, plat_dat, &mac); ret = stmmac_probe_config_dt(pdev, plat_dat, &stmmac_res.mac);
if (ret) { if (ret) {
pr_err("%s: main dt probe failed", __func__); pr_err("%s: main dt probe failed", __func__);
return ret; return ret;
...@@ -335,26 +328,7 @@ int stmmac_pltfr_probe(struct platform_device *pdev) ...@@ -335,26 +328,7 @@ int stmmac_pltfr_probe(struct platform_device *pdev)
return ret; return ret;
} }
priv = stmmac_dvr_probe(&(pdev->dev), plat_dat, addr); return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
if (IS_ERR(priv)) {
pr_err("%s: main driver probe failed", __func__);
return PTR_ERR(priv);
}
/* Copy IRQ values to priv structure which is now avaialble */
priv->dev->irq = irq;
priv->wol_irq = wol_irq;
priv->lpi_irq = lpi_irq;
/* Get MAC address if available (DT) */
if (mac)
memcpy(priv->dev->dev_addr, mac, ETH_ALEN);
platform_set_drvdata(pdev, priv->dev);
pr_debug("STMMAC platform driver registration completed");
return 0;
} }
EXPORT_SYMBOL_GPL(stmmac_pltfr_probe); EXPORT_SYMBOL_GPL(stmmac_pltfr_probe);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment