Skip to content

Commit

Permalink
Merge branch 'stmmac-dwmac-socfpga-cleanup'
Browse files Browse the repository at this point in the history
Joachim Eastwood says:

====================
stmmac: dwmac-socfpga refactor+cleanup

This patch aims to remove the init/exit callbacks from the dwmac-
socfpga driver and instead use standard PM callbacks. Doing this
will also allow us to cleanup the driver.

Eventually the init/exit callbacks will be deprecated and removed
from all drivers dwmac-* except for dwmac-generic. Drivers will be
refactored to use standard PM and remove callbacks.

This patch set should not change the behavior of the driver itself,
it only moves code around. The only exception to this is patch
number 4 which restores the resume callback behavior which was
changed in the "net: stmmac: socfpga: Remove re-registration of
reset controller" patch. I belive calling phy_resume() only
from the resume callback and not probe is the right thing to do.

Changes from v1:
 - Rebase on net-next

One heads-up here:
The first patch changes the prototype of a couple of
functions used in Alexandre's "add Ethernet glue logic for
stm32 chip" patch [1] and will cause build failures for
dwmac-stm32.c if not fixed up!
If Alexandre's patch set is applied first I will gladly
rebase my patch set to account for his driver as well.

[1] https://patchwork.ozlabs.org/patch/614405/
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed May 3, 2016
2 parents e03179f + 0f400a8 commit da7daf5
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 86 deletions.
106 changes: 54 additions & 52 deletions drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ struct socfpga_dwmac {
u32 reg_shift;
struct device *dev;
struct regmap *sys_mgr_base_addr;
struct reset_control *stmmac_rst;
void __iomem *splitter_base;
bool f2h_ptp_ref_clk;
};
Expand Down Expand Up @@ -135,7 +136,7 @@ static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *
return 0;
}

static int socfpga_dwmac_setup(struct socfpga_dwmac *dwmac)
static int socfpga_dwmac_set_phy_mode(struct socfpga_dwmac *dwmac)
{
struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr;
int phymode = dwmac->interface;
Expand Down Expand Up @@ -164,6 +165,10 @@ static int socfpga_dwmac_setup(struct socfpga_dwmac *dwmac)
if (dwmac->splitter_base)
val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;

/* Assert reset to the enet controller before changing the phy mode */
if (dwmac->stmmac_rst)
reset_control_assert(dwmac->stmmac_rst);

regmap_read(sys_mgr_base_addr, reg_offset, &ctrl);
ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << reg_shift);
ctrl |= val << reg_shift;
Expand All @@ -181,57 +186,13 @@ static int socfpga_dwmac_setup(struct socfpga_dwmac *dwmac)

regmap_write(sys_mgr_base_addr, reg_offset, ctrl);

return 0;
}

static int socfpga_dwmac_init(struct platform_device *pdev, void *priv)
{
struct socfpga_dwmac *dwmac = priv;
struct net_device *ndev = platform_get_drvdata(pdev);
struct stmmac_priv *stpriv = NULL;
int ret = 0;

if (!ndev)
return -EINVAL;

stpriv = netdev_priv(ndev);
if (!stpriv)
return -EINVAL;

/* Assert reset to the enet controller before changing the phy mode */
if (stpriv->stmmac_rst)
reset_control_assert(stpriv->stmmac_rst);

/* Setup the phy mode in the system manager registers according to
* devicetree configuration
*/
ret = socfpga_dwmac_setup(dwmac);

/* Deassert reset for the phy configuration to be sampled by
* the enet controller, and operation to start in requested mode
*/
if (stpriv->stmmac_rst)
reset_control_deassert(stpriv->stmmac_rst);

/* Before the enet controller is suspended, the phy is suspended.
* This causes the phy clock to be gated. The enet controller is
* resumed before the phy, so the clock is still gated "off" when
* the enet controller is resumed. This code makes sure the phy
* is "resumed" before reinitializing the enet controller since
* the enet controller depends on an active phy clock to complete
* a DMA reset. A DMA reset will "time out" if executed
* with no phy clock input on the Synopsys enet controller.
* Verified through Synopsys Case #8000711656.
*
* Note that the phy clock is also gated when the phy is isolated.
* Phy "suspend" and "isolate" controls are located in phy basic
* control register 0, and can be modified by the phy driver
* framework.
*/
if (stpriv->phydev)
phy_resume(stpriv->phydev);
if (dwmac->stmmac_rst)
reset_control_deassert(dwmac->stmmac_rst);

return ret;
return 0;
}

static int socfpga_dwmac_probe(struct platform_device *pdev)
Expand Down Expand Up @@ -261,16 +222,57 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
}

plat_dat->bsp_priv = dwmac;
plat_dat->init = socfpga_dwmac_init;
plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed;

ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
if (!ret)
ret = socfpga_dwmac_init(pdev, dwmac);
if (!ret) {
struct net_device *ndev = platform_get_drvdata(pdev);
struct stmmac_priv *stpriv = netdev_priv(ndev);

/* The socfpga driver needs to control the stmmac reset to
* set the phy mode. Create a copy of the core reset handel
* so it can be used by the driver later.
*/
dwmac->stmmac_rst = stpriv->stmmac_rst;

ret = socfpga_dwmac_set_phy_mode(dwmac);
}

return ret;
}

#ifdef CONFIG_PM_SLEEP
static int socfpga_dwmac_resume(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct stmmac_priv *priv = netdev_priv(ndev);

socfpga_dwmac_set_phy_mode(priv->plat->bsp_priv);

/* Before the enet controller is suspended, the phy is suspended.
* This causes the phy clock to be gated. The enet controller is
* resumed before the phy, so the clock is still gated "off" when
* the enet controller is resumed. This code makes sure the phy
* is "resumed" before reinitializing the enet controller since
* the enet controller depends on an active phy clock to complete
* a DMA reset. A DMA reset will "time out" if executed
* with no phy clock input on the Synopsys enet controller.
* Verified through Synopsys Case #8000711656.
*
* Note that the phy clock is also gated when the phy is isolated.
* Phy "suspend" and "isolate" controls are located in phy basic
* control register 0, and can be modified by the phy driver
* framework.
*/
if (priv->phydev)
phy_resume(priv->phydev);

return stmmac_resume(dev);
}
#endif /* CONFIG_PM_SLEEP */

SIMPLE_DEV_PM_OPS(socfpga_dwmac_pm_ops, stmmac_suspend, socfpga_dwmac_resume);

static const struct of_device_id socfpga_dwmac_match[] = {
{ .compatible = "altr,socfpga-stmmac" },
{ }
Expand All @@ -282,7 +284,7 @@ static struct platform_driver socfpga_dwmac_driver = {
.remove = stmmac_pltfr_remove,
.driver = {
.name = "socfpga-dwmac",
.pm = &stmmac_pltfr_pm_ops,
.pm = &socfpga_dwmac_pm_ops,
.of_match_table = socfpga_dwmac_match,
},
};
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/ethernet/stmicro/stmmac/stmmac.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,9 @@ void stmmac_set_ethtool_ops(struct net_device *netdev);

int stmmac_ptp_register(struct stmmac_priv *priv);
void stmmac_ptp_unregister(struct stmmac_priv *priv);
int stmmac_resume(struct net_device *ndev);
int stmmac_suspend(struct net_device *ndev);
int stmmac_dvr_remove(struct net_device *ndev);
int stmmac_resume(struct device *dev);
int stmmac_suspend(struct device *dev);
int stmmac_dvr_remove(struct device *dev);
int stmmac_dvr_probe(struct device *device,
struct plat_stmmacenet_data *plat_dat,
struct stmmac_resources *res);
Expand Down
15 changes: 9 additions & 6 deletions drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3350,12 +3350,13 @@ EXPORT_SYMBOL_GPL(stmmac_dvr_probe);

/**
* stmmac_dvr_remove
* @ndev: net device pointer
* @dev: device pointer
* Description: this function resets the TX/RX processes, disables the MAC RX/TX
* changes the link status, releases the DMA descriptor rings.
*/
int stmmac_dvr_remove(struct net_device *ndev)
int stmmac_dvr_remove(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct stmmac_priv *priv = netdev_priv(ndev);

pr_info("%s:\n\tremoving driver", __func__);
Expand All @@ -3381,13 +3382,14 @@ EXPORT_SYMBOL_GPL(stmmac_dvr_remove);

/**
* stmmac_suspend - suspend callback
* @ndev: net device pointer
* @dev: device pointer
* Description: this is the function to suspend the device and it is called
* by the platform driver to stop the network queue, release the resources,
* program the PMT register (for WoL), clean and release driver resources.
*/
int stmmac_suspend(struct net_device *ndev)
int stmmac_suspend(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct stmmac_priv *priv = netdev_priv(ndev);
unsigned long flags;

Expand Down Expand Up @@ -3430,12 +3432,13 @@ EXPORT_SYMBOL_GPL(stmmac_suspend);

/**
* stmmac_resume - resume callback
* @ndev: net device pointer
* @dev: device pointer
* Description: when resume this function is invoked to setup the DMA and CORE
* in a usable state.
*/
int stmmac_resume(struct net_device *ndev)
int stmmac_resume(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct stmmac_priv *priv = netdev_priv(ndev);
unsigned long flags;

Expand Down
24 changes: 2 additions & 22 deletions drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,30 +231,10 @@ static int stmmac_pci_probe(struct pci_dev *pdev,
*/
static void stmmac_pci_remove(struct pci_dev *pdev)
{
struct net_device *ndev = pci_get_drvdata(pdev);

stmmac_dvr_remove(ndev);
}

#ifdef CONFIG_PM_SLEEP
static int stmmac_pci_suspend(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *ndev = pci_get_drvdata(pdev);

return stmmac_suspend(ndev);
}

static int stmmac_pci_resume(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *ndev = pci_get_drvdata(pdev);

return stmmac_resume(ndev);
stmmac_dvr_remove(&pdev->dev);
}
#endif

static SIMPLE_DEV_PM_OPS(stmmac_pm_ops, stmmac_pci_suspend, stmmac_pci_resume);
static SIMPLE_DEV_PM_OPS(stmmac_pm_ops, stmmac_suspend, stmmac_resume);

#define STMMAC_VENDOR_ID 0x700
#define STMMAC_QUARK_ID 0x0937
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ int stmmac_pltfr_remove(struct platform_device *pdev)
{
struct net_device *ndev = platform_get_drvdata(pdev);
struct stmmac_priv *priv = netdev_priv(ndev);
int ret = stmmac_dvr_remove(ndev);
int ret = stmmac_dvr_remove(&pdev->dev);

if (priv->plat->exit)
priv->plat->exit(pdev, priv->plat->bsp_priv);
Expand All @@ -410,7 +410,7 @@ static int stmmac_pltfr_suspend(struct device *dev)
struct stmmac_priv *priv = netdev_priv(ndev);
struct platform_device *pdev = to_platform_device(dev);

ret = stmmac_suspend(ndev);
ret = stmmac_suspend(dev);
if (priv->plat->exit)
priv->plat->exit(pdev, priv->plat->bsp_priv);

Expand All @@ -433,7 +433,7 @@ static int stmmac_pltfr_resume(struct device *dev)
if (priv->plat->init)
priv->plat->init(pdev, priv->plat->bsp_priv);

return stmmac_resume(ndev);
return stmmac_resume(dev);
}
#endif /* CONFIG_PM_SLEEP */

Expand Down

0 comments on commit da7daf5

Please sign in to comment.