mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 08:33:17 +02:00
Merge branch 'net-stmmac-improbe-suspend-resume-architecture'
Russell King says: ==================== net: stmmac: improbe suspend/resume architecture This series improves the stmmac suspend/resume architecture by providing a couple of method hooks in struct plat_stmmacenet_data which are called by core code, and thus are available for any of the platform glue drivers, whether using a platform or PCI device. As these methods are called by core code, we can also provide a simple PM ops structure also in the core code for converted glue drivers to use. The remainder of the patches convert the various drivers. ==================== Link: https://patch.msgid.link/aJo7kvoub5voHOUQ@shell.armlinux.org.uk Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
0a529da8cf
|
|
@ -1231,6 +1231,37 @@ static int stmmac_config_multi_msi(struct pci_dev *pdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int intel_eth_pci_suspend(struct device *dev, void *bsp_priv)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
int ret;
|
||||
|
||||
ret = pci_save_state(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pci_wake_from_d3(pdev, true);
|
||||
pci_set_power_state(pdev, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intel_eth_pci_resume(struct device *dev, void *bsp_priv)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
int ret;
|
||||
|
||||
pci_restore_state(pdev);
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
|
||||
ret = pcim_enable_device(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_eth_pci_probe
|
||||
*
|
||||
|
|
@ -1292,6 +1323,9 @@ static int intel_eth_pci_probe(struct pci_dev *pdev,
|
|||
pci_set_master(pdev);
|
||||
|
||||
plat->bsp_priv = intel_priv;
|
||||
plat->suspend = intel_eth_pci_suspend;
|
||||
plat->resume = intel_eth_pci_resume;
|
||||
|
||||
intel_priv->mdio_adhoc_addr = INTEL_MGBE_ADHOC_ADDR;
|
||||
intel_priv->crossts_adj = 1;
|
||||
|
||||
|
|
@ -1355,44 +1389,6 @@ static void intel_eth_pci_remove(struct pci_dev *pdev)
|
|||
clk_unregister_fixed_rate(priv->plat->stmmac_clk);
|
||||
}
|
||||
|
||||
static int __maybe_unused intel_eth_pci_suspend(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
int ret;
|
||||
|
||||
ret = stmmac_suspend(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pci_save_state(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pci_wake_from_d3(pdev, true);
|
||||
pci_set_power_state(pdev, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused intel_eth_pci_resume(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
int ret;
|
||||
|
||||
pci_restore_state(pdev);
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
|
||||
ret = pcim_enable_device(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
return stmmac_resume(dev);
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(intel_eth_pm_ops, intel_eth_pci_suspend,
|
||||
intel_eth_pci_resume);
|
||||
|
||||
#define PCI_DEVICE_ID_INTEL_QUARK 0x0937
|
||||
#define PCI_DEVICE_ID_INTEL_EHL_RGMII1G 0x4b30
|
||||
#define PCI_DEVICE_ID_INTEL_EHL_SGMII1G 0x4b31
|
||||
|
|
@ -1442,7 +1438,7 @@ static struct pci_driver intel_eth_pci_driver = {
|
|||
.probe = intel_eth_pci_probe,
|
||||
.remove = intel_eth_pci_remove,
|
||||
.driver = {
|
||||
.pm = &intel_eth_pm_ops,
|
||||
.pm = &stmmac_simple_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -521,6 +521,37 @@ static int loongson_dwmac_fix_reset(void *priv, void __iomem *ioaddr)
|
|||
10000, 2000000);
|
||||
}
|
||||
|
||||
static int loongson_dwmac_suspend(struct device *dev, void *bsp_priv)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
int ret;
|
||||
|
||||
ret = pci_save_state(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pci_disable_device(pdev);
|
||||
pci_wake_from_d3(pdev, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int loongson_dwmac_resume(struct device *dev, void *bsp_priv)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
int ret;
|
||||
|
||||
pci_restore_state(pdev);
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
|
||||
ret = pci_enable_device(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
struct plat_stmmacenet_data *plat;
|
||||
|
|
@ -565,6 +596,8 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
|
|||
plat->bsp_priv = ld;
|
||||
plat->setup = loongson_dwmac_setup;
|
||||
plat->fix_soc_reset = loongson_dwmac_fix_reset;
|
||||
plat->suspend = loongson_dwmac_suspend;
|
||||
plat->resume = loongson_dwmac_resume;
|
||||
ld->dev = &pdev->dev;
|
||||
ld->loongson_id = readl(res.addr + GMAC_VERSION) & 0xff;
|
||||
|
||||
|
|
@ -621,44 +654,6 @@ static void loongson_dwmac_remove(struct pci_dev *pdev)
|
|||
pci_disable_device(pdev);
|
||||
}
|
||||
|
||||
static int __maybe_unused loongson_dwmac_suspend(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
int ret;
|
||||
|
||||
ret = stmmac_suspend(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pci_save_state(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pci_disable_device(pdev);
|
||||
pci_wake_from_d3(pdev, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused loongson_dwmac_resume(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
int ret;
|
||||
|
||||
pci_restore_state(pdev);
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
|
||||
ret = pci_enable_device(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
return stmmac_resume(dev);
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(loongson_dwmac_pm_ops, loongson_dwmac_suspend,
|
||||
loongson_dwmac_resume);
|
||||
|
||||
static const struct pci_device_id loongson_dwmac_id_table[] = {
|
||||
{ PCI_DEVICE_DATA(LOONGSON, GMAC1, &loongson_gmac_pci_info) },
|
||||
{ PCI_DEVICE_DATA(LOONGSON, GMAC2, &loongson_gmac_pci_info) },
|
||||
|
|
@ -673,7 +668,7 @@ static struct pci_driver loongson_dwmac_driver = {
|
|||
.probe = loongson_dwmac_probe,
|
||||
.remove = loongson_dwmac_remove,
|
||||
.driver = {
|
||||
.pm = &loongson_dwmac_pm_ops,
|
||||
.pm = &stmmac_simple_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -523,7 +523,7 @@ static int mediatek_dwmac_clk_init(struct mediatek_dwmac_plat_data *plat)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int mediatek_dwmac_init(struct platform_device *pdev, void *priv)
|
||||
static int mediatek_dwmac_init(struct device *dev, void *priv)
|
||||
{
|
||||
struct mediatek_dwmac_plat_data *plat = priv;
|
||||
const struct mediatek_dwmac_variant *variant = plat->variant;
|
||||
|
|
@ -532,7 +532,7 @@ static int mediatek_dwmac_init(struct platform_device *pdev, void *priv)
|
|||
if (variant->dwmac_set_phy_interface) {
|
||||
ret = variant->dwmac_set_phy_interface(plat);
|
||||
if (ret) {
|
||||
dev_err(plat->dev, "failed to set phy interface, err = %d\n", ret);
|
||||
dev_err(dev, "failed to set phy interface, err = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
@ -540,7 +540,7 @@ static int mediatek_dwmac_init(struct platform_device *pdev, void *priv)
|
|||
if (variant->dwmac_set_delay) {
|
||||
ret = variant->dwmac_set_delay(plat);
|
||||
if (ret) {
|
||||
dev_err(plat->dev, "failed to set delay value, err = %d\n", ret);
|
||||
dev_err(dev, "failed to set delay value, err = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
@ -589,7 +589,7 @@ static int mediatek_dwmac_common_data(struct platform_device *pdev,
|
|||
plat->maxmtu = ETH_DATA_LEN;
|
||||
plat->host_dma_width = priv_plat->variant->dma_bit_mask;
|
||||
plat->bsp_priv = priv_plat;
|
||||
plat->init = mediatek_dwmac_init;
|
||||
plat->resume = mediatek_dwmac_init;
|
||||
plat->clks_config = mediatek_dwmac_clks_config;
|
||||
|
||||
plat->safety_feat_cfg = devm_kzalloc(&pdev->dev,
|
||||
|
|
@ -654,7 +654,7 @@ static int mediatek_dwmac_probe(struct platform_device *pdev)
|
|||
return PTR_ERR(plat_dat);
|
||||
|
||||
mediatek_dwmac_common_data(pdev, plat_dat, priv_plat);
|
||||
mediatek_dwmac_init(pdev, priv_plat);
|
||||
mediatek_dwmac_init(&pdev->dev, priv_plat);
|
||||
|
||||
ret = mediatek_dwmac_clks_config(priv_plat, true);
|
||||
if (ret)
|
||||
|
|
|
|||
|
|
@ -71,7 +71,6 @@ struct rk_priv_data {
|
|||
phy_interface_t phy_iface;
|
||||
int id;
|
||||
struct regulator *regulator;
|
||||
bool suspended;
|
||||
const struct rk_gmac_ops *ops;
|
||||
|
||||
bool clk_enabled;
|
||||
|
|
@ -1706,6 +1705,28 @@ static int rk_set_clk_tx_rate(void *bsp_priv_, struct clk *clk_tx_i,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int rk_gmac_suspend(struct device *dev, void *bsp_priv_)
|
||||
{
|
||||
struct rk_priv_data *bsp_priv = bsp_priv_;
|
||||
|
||||
/* Keep the PHY up if we use Wake-on-Lan. */
|
||||
if (!device_may_wakeup(dev))
|
||||
rk_gmac_powerdown(bsp_priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk_gmac_resume(struct device *dev, void *bsp_priv_)
|
||||
{
|
||||
struct rk_priv_data *bsp_priv = bsp_priv_;
|
||||
|
||||
/* The PHY was up for Wake-on-Lan. */
|
||||
if (!device_may_wakeup(dev))
|
||||
rk_gmac_powerup(bsp_priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk_gmac_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct plat_stmmacenet_data *plat_dat;
|
||||
|
|
@ -1738,6 +1759,8 @@ static int rk_gmac_probe(struct platform_device *pdev)
|
|||
|
||||
plat_dat->get_interfaces = rk_get_interfaces;
|
||||
plat_dat->set_clk_tx_rate = rk_set_clk_tx_rate;
|
||||
plat_dat->suspend = rk_gmac_suspend;
|
||||
plat_dat->resume = rk_gmac_resume;
|
||||
|
||||
plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data);
|
||||
if (IS_ERR(plat_dat->bsp_priv))
|
||||
|
|
@ -1772,37 +1795,6 @@ static void rk_gmac_remove(struct platform_device *pdev)
|
|||
rk_gmac_powerdown(bsp_priv);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int rk_gmac_suspend(struct device *dev)
|
||||
{
|
||||
struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
|
||||
int ret = stmmac_suspend(dev);
|
||||
|
||||
/* Keep the PHY up if we use Wake-on-Lan. */
|
||||
if (!device_may_wakeup(dev)) {
|
||||
rk_gmac_powerdown(bsp_priv);
|
||||
bsp_priv->suspended = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rk_gmac_resume(struct device *dev)
|
||||
{
|
||||
struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
|
||||
|
||||
/* The PHY was up for Wake-on-Lan. */
|
||||
if (bsp_priv->suspended) {
|
||||
rk_gmac_powerup(bsp_priv);
|
||||
bsp_priv->suspended = false;
|
||||
}
|
||||
|
||||
return stmmac_resume(dev);
|
||||
}
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume);
|
||||
|
||||
static const struct of_device_id rk_gmac_dwmac_match[] = {
|
||||
{ .compatible = "rockchip,px30-gmac", .data = &px30_ops },
|
||||
{ .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops },
|
||||
|
|
@ -1828,7 +1820,7 @@ static struct platform_driver rk_gmac_dwmac_driver = {
|
|||
.remove = rk_gmac_remove,
|
||||
.driver = {
|
||||
.name = "rk_gmac-dwmac",
|
||||
.pm = &rk_gmac_pm_ops,
|
||||
.pm = &stmmac_simple_pm_ops,
|
||||
.of_match_table = rk_gmac_dwmac_match,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -498,6 +498,26 @@ static int stm32mp1_parse_data(struct stm32_dwmac *dwmac,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int stm32_dwmac_suspend(struct device *dev, void *bsp_priv)
|
||||
{
|
||||
struct stm32_dwmac *dwmac = bsp_priv;
|
||||
|
||||
stm32_dwmac_clk_disable(dwmac);
|
||||
|
||||
return dwmac->ops->suspend ? dwmac->ops->suspend(dwmac) : 0;
|
||||
}
|
||||
|
||||
static int stm32_dwmac_resume(struct device *dev, void *bsp_priv)
|
||||
{
|
||||
struct stmmac_priv *priv = netdev_priv(dev_get_drvdata(dev));
|
||||
struct stm32_dwmac *dwmac = bsp_priv;
|
||||
|
||||
if (dwmac->ops->resume)
|
||||
dwmac->ops->resume(dwmac);
|
||||
|
||||
return stm32_dwmac_init(priv->plat);
|
||||
}
|
||||
|
||||
static int stm32_dwmac_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct plat_stmmacenet_data *plat_dat;
|
||||
|
|
@ -535,6 +555,8 @@ static int stm32_dwmac_probe(struct platform_device *pdev)
|
|||
|
||||
plat_dat->flags |= STMMAC_FLAG_EN_TX_LPI_CLK_PHY_CAP;
|
||||
plat_dat->bsp_priv = dwmac;
|
||||
plat_dat->suspend = stm32_dwmac_suspend;
|
||||
plat_dat->resume = stm32_dwmac_resume;
|
||||
|
||||
ret = stm32_dwmac_init(plat_dat);
|
||||
if (ret)
|
||||
|
|
@ -600,50 +622,6 @@ static void stm32mp1_resume(struct stm32_dwmac *dwmac)
|
|||
clk_disable_unprepare(dwmac->clk_ethstp);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int stm32_dwmac_suspend(struct device *dev)
|
||||
{
|
||||
struct net_device *ndev = dev_get_drvdata(dev);
|
||||
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||
struct stm32_dwmac *dwmac = priv->plat->bsp_priv;
|
||||
|
||||
int ret;
|
||||
|
||||
ret = stmmac_suspend(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
stm32_dwmac_clk_disable(dwmac);
|
||||
|
||||
if (dwmac->ops->suspend)
|
||||
ret = dwmac->ops->suspend(dwmac);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int stm32_dwmac_resume(struct device *dev)
|
||||
{
|
||||
struct net_device *ndev = dev_get_drvdata(dev);
|
||||
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||
struct stm32_dwmac *dwmac = priv->plat->bsp_priv;
|
||||
int ret;
|
||||
|
||||
if (dwmac->ops->resume)
|
||||
dwmac->ops->resume(dwmac);
|
||||
|
||||
ret = stm32_dwmac_init(priv->plat);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = stmmac_resume(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_ops,
|
||||
stm32_dwmac_suspend, stm32_dwmac_resume);
|
||||
|
||||
static struct stm32_ops stm32mcu_dwmac_data = {
|
||||
.set_mode = stm32mcu_set_mode
|
||||
};
|
||||
|
|
@ -691,7 +669,7 @@ static struct platform_driver stm32_dwmac_driver = {
|
|||
.remove = stm32_dwmac_remove,
|
||||
.driver = {
|
||||
.name = "stm32-dwmac",
|
||||
.pm = &stm32_dwmac_pm_ops,
|
||||
.pm = &stmmac_simple_pm_ops,
|
||||
.of_match_table = stm32_dwmac_match,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -374,6 +374,8 @@ enum stmmac_state {
|
|||
STMMAC_SERVICE_SCHED,
|
||||
};
|
||||
|
||||
extern const struct dev_pm_ops stmmac_simple_pm_ops;
|
||||
|
||||
int stmmac_mdio_unregister(struct net_device *ndev);
|
||||
int stmmac_mdio_register(struct net_device *ndev);
|
||||
int stmmac_mdio_reset(struct mii_bus *mii);
|
||||
|
|
|
|||
|
|
@ -7879,6 +7879,9 @@ int stmmac_suspend(struct device *dev)
|
|||
if (stmmac_fpe_supported(priv))
|
||||
ethtool_mmsv_stop(&priv->fpe_cfg.mmsv);
|
||||
|
||||
if (priv->plat->suspend)
|
||||
return priv->plat->suspend(dev, priv->plat->bsp_priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(stmmac_suspend);
|
||||
|
|
@ -7931,6 +7934,12 @@ int stmmac_resume(struct device *dev)
|
|||
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||
int ret;
|
||||
|
||||
if (priv->plat->resume) {
|
||||
ret = priv->plat->resume(dev, priv->plat->bsp_priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!netif_running(ndev))
|
||||
return 0;
|
||||
|
||||
|
|
@ -8004,6 +8013,9 @@ int stmmac_resume(struct device *dev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(stmmac_resume);
|
||||
|
||||
EXPORT_GPL_SIMPLE_DEV_PM_OPS(stmmac_simple_pm_ops, stmmac_suspend,
|
||||
stmmac_resume);
|
||||
|
||||
#ifndef MODULE
|
||||
static int __init stmmac_cmdline_opt(char *str)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -138,6 +138,37 @@ static const struct stmmac_pci_info snps_gmac5_pci_info = {
|
|||
.setup = snps_gmac5_default_data,
|
||||
};
|
||||
|
||||
static int stmmac_pci_suspend(struct device *dev, void *bsp_priv)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
int ret;
|
||||
|
||||
ret = pci_save_state(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pci_disable_device(pdev);
|
||||
pci_wake_from_d3(pdev, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stmmac_pci_resume(struct device *dev, void *bsp_priv)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
int ret;
|
||||
|
||||
pci_restore_state(pdev);
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
|
||||
ret = pci_enable_device(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* stmmac_pci_probe
|
||||
*
|
||||
|
|
@ -217,6 +248,9 @@ static int stmmac_pci_probe(struct pci_dev *pdev,
|
|||
plat->safety_feat_cfg->prtyen = 1;
|
||||
plat->safety_feat_cfg->tmouten = 1;
|
||||
|
||||
plat->suspend = stmmac_pci_suspend;
|
||||
plat->resume = stmmac_pci_resume;
|
||||
|
||||
return stmmac_dvr_probe(&pdev->dev, plat, &res);
|
||||
}
|
||||
|
||||
|
|
@ -231,43 +265,6 @@ static void stmmac_pci_remove(struct pci_dev *pdev)
|
|||
stmmac_dvr_remove(&pdev->dev);
|
||||
}
|
||||
|
||||
static int __maybe_unused stmmac_pci_suspend(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
int ret;
|
||||
|
||||
ret = stmmac_suspend(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pci_save_state(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pci_disable_device(pdev);
|
||||
pci_wake_from_d3(pdev, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused stmmac_pci_resume(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
int ret;
|
||||
|
||||
pci_restore_state(pdev);
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
|
||||
ret = pci_enable_device(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
return stmmac_resume(dev);
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(stmmac_pm_ops, stmmac_pci_suspend, stmmac_pci_resume);
|
||||
|
||||
/* synthetic ID, no official vendor */
|
||||
#define PCI_VENDOR_ID_STMMAC 0x0700
|
||||
|
||||
|
|
@ -289,7 +286,7 @@ static struct pci_driver stmmac_pci_driver = {
|
|||
.probe = stmmac_pci_probe,
|
||||
.remove = stmmac_pci_remove,
|
||||
.driver = {
|
||||
.pm = &stmmac_pm_ops,
|
||||
.pm = &stmmac_simple_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -811,6 +811,22 @@ static void stmmac_pltfr_exit(struct platform_device *pdev,
|
|||
plat->exit(pdev, plat->bsp_priv);
|
||||
}
|
||||
|
||||
static int stmmac_plat_suspend(struct device *dev, void *bsp_priv)
|
||||
{
|
||||
struct stmmac_priv *priv = netdev_priv(dev_get_drvdata(dev));
|
||||
|
||||
stmmac_pltfr_exit(to_platform_device(dev), priv->plat);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stmmac_plat_resume(struct device *dev, void *bsp_priv)
|
||||
{
|
||||
struct stmmac_priv *priv = netdev_priv(dev_get_drvdata(dev));
|
||||
|
||||
return stmmac_pltfr_init(to_platform_device(dev), priv->plat);
|
||||
}
|
||||
|
||||
/**
|
||||
* stmmac_pltfr_probe
|
||||
* @pdev: platform device pointer
|
||||
|
|
@ -825,6 +841,11 @@ int stmmac_pltfr_probe(struct platform_device *pdev,
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (!plat->suspend && plat->exit)
|
||||
plat->suspend = stmmac_plat_suspend;
|
||||
if (!plat->resume && plat->init)
|
||||
plat->resume = stmmac_plat_resume;
|
||||
|
||||
ret = stmmac_pltfr_init(pdev, plat);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
@ -886,47 +907,6 @@ void stmmac_pltfr_remove(struct platform_device *pdev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
|
||||
|
||||
/**
|
||||
* stmmac_pltfr_suspend
|
||||
* @dev: device pointer
|
||||
* Description: this function is invoked when suspend the driver and it direcly
|
||||
* call the main suspend function and then, if required, on some platform, it
|
||||
* can call an exit helper.
|
||||
*/
|
||||
static int __maybe_unused stmmac_pltfr_suspend(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
struct net_device *ndev = dev_get_drvdata(dev);
|
||||
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
|
||||
ret = stmmac_suspend(dev);
|
||||
stmmac_pltfr_exit(pdev, priv->plat);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* stmmac_pltfr_resume
|
||||
* @dev: device pointer
|
||||
* Description: this function is invoked when resume the driver before calling
|
||||
* the main resume function, on some platforms, it can call own init helper
|
||||
* if required.
|
||||
*/
|
||||
static int __maybe_unused stmmac_pltfr_resume(struct device *dev)
|
||||
{
|
||||
struct net_device *ndev = dev_get_drvdata(dev);
|
||||
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
int ret;
|
||||
|
||||
ret = stmmac_pltfr_init(pdev, priv->plat);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return stmmac_resume(dev);
|
||||
}
|
||||
|
||||
static int __maybe_unused stmmac_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct net_device *ndev = dev_get_drvdata(dev);
|
||||
|
|
@ -994,7 +974,7 @@ static int __maybe_unused stmmac_pltfr_noirq_resume(struct device *dev)
|
|||
}
|
||||
|
||||
const struct dev_pm_ops stmmac_pltfr_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(stmmac_pltfr_suspend, stmmac_pltfr_resume)
|
||||
SET_SYSTEM_SLEEP_PM_OPS(stmmac_suspend, stmmac_resume)
|
||||
SET_RUNTIME_PM_OPS(stmmac_runtime_suspend, stmmac_runtime_resume, NULL)
|
||||
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(stmmac_pltfr_noirq_suspend, stmmac_pltfr_noirq_resume)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -248,6 +248,8 @@ struct plat_stmmacenet_data {
|
|||
void (*ptp_clk_freq_config)(struct stmmac_priv *priv);
|
||||
int (*init)(struct platform_device *pdev, void *priv);
|
||||
void (*exit)(struct platform_device *pdev, void *priv);
|
||||
int (*suspend)(struct device *dev, void *priv);
|
||||
int (*resume)(struct device *dev, void *priv);
|
||||
struct mac_device_info *(*setup)(void *priv);
|
||||
int (*clks_config)(void *priv, bool enabled);
|
||||
int (*crosststamp)(ktime_t *device, struct system_counterval_t *system,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user