Commit 1c59bb6b authored by David S. Miller's avatar David S. Miller

Merge branch 'ethernet-dec-tulip-use-generic-power-management'

Vaibhav Gupta says:

====================
ethernet: dec: tulip: use generic power management

Linux Kernel Mentee: Remove Legacy Power Management.

The purpose of this patch series is to remove legacy power management
callbacks and invocation of PCI helper functions, from tulip ethernet drivers.

With legacy PM, drivers themselves are responsible for handling the device's
power states. And they do this with the help of PCI helper functions like
pci_enable/disable_device(), pci_set/restore_state(), pci_set_powr_state(), etc.
which is not recommended.

In generic PM, all the required tasks are handled by PCI core and drivers need
to perform device-specific operations only.

All patches are compile-tested only.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 39ea5d70 6c3cb945
...@@ -2105,11 +2105,10 @@ static void de_remove_one(struct pci_dev *pdev) ...@@ -2105,11 +2105,10 @@ static void de_remove_one(struct pci_dev *pdev)
free_netdev(dev); free_netdev(dev);
} }
#ifdef CONFIG_PM static int __maybe_unused de_suspend(struct device *dev_d)
static int de_suspend (struct pci_dev *pdev, pm_message_t state)
{ {
struct net_device *dev = pci_get_drvdata (pdev); struct pci_dev *pdev = to_pci_dev(dev_d);
struct net_device *dev = pci_get_drvdata(pdev);
struct de_private *de = netdev_priv(dev); struct de_private *de = netdev_priv(dev);
rtnl_lock(); rtnl_lock();
...@@ -2136,7 +2135,6 @@ static int de_suspend (struct pci_dev *pdev, pm_message_t state) ...@@ -2136,7 +2135,6 @@ static int de_suspend (struct pci_dev *pdev, pm_message_t state)
de_clean_rings(de); de_clean_rings(de);
de_adapter_sleep(de); de_adapter_sleep(de);
pci_disable_device(pdev);
} else { } else {
netif_device_detach(dev); netif_device_detach(dev);
} }
...@@ -2144,21 +2142,17 @@ static int de_suspend (struct pci_dev *pdev, pm_message_t state) ...@@ -2144,21 +2142,17 @@ static int de_suspend (struct pci_dev *pdev, pm_message_t state)
return 0; return 0;
} }
static int de_resume (struct pci_dev *pdev) static int __maybe_unused de_resume(struct device *dev_d)
{ {
struct net_device *dev = pci_get_drvdata (pdev); struct pci_dev *pdev = to_pci_dev(dev_d);
struct net_device *dev = pci_get_drvdata(pdev);
struct de_private *de = netdev_priv(dev); struct de_private *de = netdev_priv(dev);
int retval = 0;
rtnl_lock(); rtnl_lock();
if (netif_device_present(dev)) if (netif_device_present(dev))
goto out; goto out;
if (!netif_running(dev)) if (!netif_running(dev))
goto out_attach; goto out_attach;
if ((retval = pci_enable_device(pdev))) {
netdev_err(dev, "pci_enable_device failed in resume\n");
goto out;
}
pci_set_master(pdev); pci_set_master(pdev);
de_init_rings(de); de_init_rings(de);
de_init_hw(de); de_init_hw(de);
...@@ -2169,17 +2163,14 @@ static int de_resume (struct pci_dev *pdev) ...@@ -2169,17 +2163,14 @@ static int de_resume (struct pci_dev *pdev)
return 0; return 0;
} }
#endif /* CONFIG_PM */ static SIMPLE_DEV_PM_OPS(de_pm_ops, de_suspend, de_resume);
static struct pci_driver de_driver = { static struct pci_driver de_driver = {
.name = DRV_NAME, .name = DRV_NAME,
.id_table = de_pci_tbl, .id_table = de_pci_tbl,
.probe = de_init_one, .probe = de_init_one,
.remove = de_remove_one, .remove = de_remove_one,
#ifdef CONFIG_PM .driver.pm = &de_pm_ops,
.suspend = de_suspend,
.resume = de_resume,
#endif
}; };
static int __init de_init (void) static int __init de_init (void)
......
...@@ -2081,14 +2081,11 @@ static const struct pci_device_id dmfe_pci_tbl[] = { ...@@ -2081,14 +2081,11 @@ static const struct pci_device_id dmfe_pci_tbl[] = {
}; };
MODULE_DEVICE_TABLE(pci, dmfe_pci_tbl); MODULE_DEVICE_TABLE(pci, dmfe_pci_tbl);
static int __maybe_unused dmfe_suspend(struct device *dev_d)
#ifdef CONFIG_PM
static int dmfe_suspend(struct pci_dev *pci_dev, pm_message_t state)
{ {
struct net_device *dev = pci_get_drvdata(pci_dev); struct net_device *dev = dev_get_drvdata(dev_d);
struct dmfe_board_info *db = netdev_priv(dev); struct dmfe_board_info *db = netdev_priv(dev);
void __iomem *ioaddr = db->ioaddr; void __iomem *ioaddr = db->ioaddr;
u32 tmp;
/* Disable upper layer interface */ /* Disable upper layer interface */
netif_device_detach(dev); netif_device_detach(dev);
...@@ -2105,63 +2102,35 @@ static int dmfe_suspend(struct pci_dev *pci_dev, pm_message_t state) ...@@ -2105,63 +2102,35 @@ static int dmfe_suspend(struct pci_dev *pci_dev, pm_message_t state)
dmfe_free_rxbuffer(db); dmfe_free_rxbuffer(db);
/* Enable WOL */ /* Enable WOL */
pci_read_config_dword(pci_dev, 0x40, &tmp); device_wakeup_enable(dev_d);
tmp &= ~(DMFE_WOL_LINKCHANGE|DMFE_WOL_MAGICPACKET);
if (db->wol_mode & WAKE_PHY)
tmp |= DMFE_WOL_LINKCHANGE;
if (db->wol_mode & WAKE_MAGIC)
tmp |= DMFE_WOL_MAGICPACKET;
pci_write_config_dword(pci_dev, 0x40, tmp);
pci_enable_wake(pci_dev, PCI_D3hot, 1);
pci_enable_wake(pci_dev, PCI_D3cold, 1);
/* Power down device*/
pci_save_state(pci_dev);
pci_set_power_state(pci_dev, pci_choose_state (pci_dev, state));
return 0; return 0;
} }
static int dmfe_resume(struct pci_dev *pci_dev) static int __maybe_unused dmfe_resume(struct device *dev_d)
{ {
struct net_device *dev = pci_get_drvdata(pci_dev); struct net_device *dev = dev_get_drvdata(dev_d);
u32 tmp;
pci_set_power_state(pci_dev, PCI_D0);
pci_restore_state(pci_dev);
/* Re-initialize DM910X board */ /* Re-initialize DM910X board */
dmfe_init_dm910x(dev); dmfe_init_dm910x(dev);
/* Disable WOL */ /* Disable WOL */
pci_read_config_dword(pci_dev, 0x40, &tmp); device_wakeup_disable(dev_d);
tmp &= ~(DMFE_WOL_LINKCHANGE | DMFE_WOL_MAGICPACKET);
pci_write_config_dword(pci_dev, 0x40, tmp);
pci_enable_wake(pci_dev, PCI_D3hot, 0);
pci_enable_wake(pci_dev, PCI_D3cold, 0);
/* Restart upper layer interface */ /* Restart upper layer interface */
netif_device_attach(dev); netif_device_attach(dev);
return 0; return 0;
} }
#else
#define dmfe_suspend NULL static SIMPLE_DEV_PM_OPS(dmfe_pm_ops, dmfe_suspend, dmfe_resume);
#define dmfe_resume NULL
#endif
static struct pci_driver dmfe_driver = { static struct pci_driver dmfe_driver = {
.name = "dmfe", .name = "dmfe",
.id_table = dmfe_pci_tbl, .id_table = dmfe_pci_tbl,
.probe = dmfe_init_one, .probe = dmfe_init_one,
.remove = dmfe_remove_one, .remove = dmfe_remove_one,
.suspend = dmfe_suspend, .driver.pm = &dmfe_pm_ops,
.resume = dmfe_resume
}; };
MODULE_AUTHOR("Sten Wang, sten_wang@davicom.com.tw"); MODULE_AUTHOR("Sten Wang, sten_wang@davicom.com.tw");
......
...@@ -1803,13 +1803,9 @@ static void tulip_set_wolopts (struct pci_dev *pdev, u32 wolopts) ...@@ -1803,13 +1803,9 @@ static void tulip_set_wolopts (struct pci_dev *pdev, u32 wolopts)
} }
} }
#ifdef CONFIG_PM static int __maybe_unused tulip_suspend(struct device *dev_d)
static int tulip_suspend (struct pci_dev *pdev, pm_message_t state)
{ {
pci_power_t pstate; struct net_device *dev = dev_get_drvdata(dev_d);
struct net_device *dev = pci_get_drvdata(pdev);
struct tulip_private *tp = netdev_priv(dev); struct tulip_private *tp = netdev_priv(dev);
if (!dev) if (!dev)
...@@ -1825,45 +1821,27 @@ static int tulip_suspend (struct pci_dev *pdev, pm_message_t state) ...@@ -1825,45 +1821,27 @@ static int tulip_suspend (struct pci_dev *pdev, pm_message_t state)
free_irq(tp->pdev->irq, dev); free_irq(tp->pdev->irq, dev);
save_state: save_state:
pci_save_state(pdev); tulip_set_wolopts(to_pci_dev(dev_d), tp->wolinfo.wolopts);
pci_disable_device(pdev); device_set_wakeup_enable(dev_d, !!tp->wolinfo.wolopts);
pstate = pci_choose_state(pdev, state);
if (state.event == PM_EVENT_SUSPEND && pstate != PCI_D0) {
int rc;
tulip_set_wolopts(pdev, tp->wolinfo.wolopts);
rc = pci_enable_wake(pdev, pstate, tp->wolinfo.wolopts);
if (rc)
pr_err("pci_enable_wake failed (%d)\n", rc);
}
pci_set_power_state(pdev, pstate);
return 0; return 0;
} }
static int __maybe_unused tulip_resume(struct device *dev_d)
static int tulip_resume(struct pci_dev *pdev)
{ {
struct net_device *dev = pci_get_drvdata(pdev); struct pci_dev *pdev = to_pci_dev(dev_d);
struct net_device *dev = dev_get_drvdata(dev_d);
struct tulip_private *tp = netdev_priv(dev); struct tulip_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->base_addr; void __iomem *ioaddr = tp->base_addr;
int retval;
unsigned int tmp; unsigned int tmp;
int retval = 0;
if (!dev) if (!dev)
return -EINVAL; return -EINVAL;
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
if (!netif_running(dev)) if (!netif_running(dev))
return 0; return 0;
if ((retval = pci_enable_device(pdev))) {
pr_err("pci_enable_device failed in resume\n");
return retval;
}
retval = request_irq(pdev->irq, tulip_interrupt, IRQF_SHARED, retval = request_irq(pdev->irq, tulip_interrupt, IRQF_SHARED,
dev->name, dev); dev->name, dev);
if (retval) { if (retval) {
...@@ -1872,8 +1850,7 @@ static int tulip_resume(struct pci_dev *pdev) ...@@ -1872,8 +1850,7 @@ static int tulip_resume(struct pci_dev *pdev)
} }
if (tp->flags & COMET_PM) { if (tp->flags & COMET_PM) {
pci_enable_wake(pdev, PCI_D3hot, 0); device_set_wakeup_enable(dev_d, 0);
pci_enable_wake(pdev, PCI_D3cold, 0);
/* Clear the PMES flag */ /* Clear the PMES flag */
tmp = ioread32(ioaddr + CSR20); tmp = ioread32(ioaddr + CSR20);
...@@ -1891,9 +1868,6 @@ static int tulip_resume(struct pci_dev *pdev) ...@@ -1891,9 +1868,6 @@ static int tulip_resume(struct pci_dev *pdev)
return 0; return 0;
} }
#endif /* CONFIG_PM */
static void tulip_remove_one(struct pci_dev *pdev) static void tulip_remove_one(struct pci_dev *pdev)
{ {
struct net_device *dev = pci_get_drvdata (pdev); struct net_device *dev = pci_get_drvdata (pdev);
...@@ -1937,15 +1911,14 @@ static void poll_tulip (struct net_device *dev) ...@@ -1937,15 +1911,14 @@ static void poll_tulip (struct net_device *dev)
} }
#endif #endif
static SIMPLE_DEV_PM_OPS(tulip_pm_ops, tulip_suspend, tulip_resume);
static struct pci_driver tulip_driver = { static struct pci_driver tulip_driver = {
.name = DRV_NAME, .name = DRV_NAME,
.id_table = tulip_pci_tbl, .id_table = tulip_pci_tbl,
.probe = tulip_init_one, .probe = tulip_init_one,
.remove = tulip_remove_one, .remove = tulip_remove_one,
#ifdef CONFIG_PM .driver.pm = &tulip_pm_ops,
.suspend = tulip_suspend,
.resume = tulip_resume,
#endif /* CONFIG_PM */
}; };
......
...@@ -1163,65 +1163,41 @@ static void uli526x_dynamic_reset(struct net_device *dev) ...@@ -1163,65 +1163,41 @@ static void uli526x_dynamic_reset(struct net_device *dev)
netif_wake_queue(dev); netif_wake_queue(dev);
} }
#ifdef CONFIG_PM
/* /*
* Suspend the interface. * Suspend the interface.
*/ */
static int uli526x_suspend(struct pci_dev *pdev, pm_message_t state) static int __maybe_unused uli526x_suspend(struct device *dev_d)
{ {
struct net_device *dev = pci_get_drvdata(pdev); struct net_device *dev = dev_get_drvdata(dev_d);
pci_power_t power_state;
int err;
ULI526X_DBUG(0, "uli526x_suspend", 0); ULI526X_DBUG(0, "uli526x_suspend", 0);
pci_save_state(pdev);
if (!netif_running(dev)) if (!netif_running(dev))
return 0; return 0;
netif_device_detach(dev); netif_device_detach(dev);
uli526x_reset_prepare(dev); uli526x_reset_prepare(dev);
power_state = pci_choose_state(pdev, state); device_set_wakeup_enable(dev_d, 0);
pci_enable_wake(pdev, power_state, 0);
err = pci_set_power_state(pdev, power_state);
if (err) {
netif_device_attach(dev);
/* Re-initialize ULI526X board */
uli526x_init(dev);
/* Restart upper layer interface */
netif_wake_queue(dev);
}
return err; return 0;
} }
/* /*
* Resume the interface. * Resume the interface.
*/ */
static int uli526x_resume(struct pci_dev *pdev) static int __maybe_unused uli526x_resume(struct device *dev_d)
{ {
struct net_device *dev = pci_get_drvdata(pdev); struct net_device *dev = dev_get_drvdata(dev_d);
int err;
ULI526X_DBUG(0, "uli526x_resume", 0); ULI526X_DBUG(0, "uli526x_resume", 0);
pci_restore_state(pdev);
if (!netif_running(dev)) if (!netif_running(dev))
return 0; return 0;
err = pci_set_power_state(pdev, PCI_D0);
if (err) {
netdev_warn(dev, "Could not put device into D0\n");
return err;
}
netif_device_attach(dev); netif_device_attach(dev);
/* Re-initialize ULI526X board */ /* Re-initialize ULI526X board */
uli526x_init(dev); uli526x_init(dev);
...@@ -1231,14 +1207,6 @@ static int uli526x_resume(struct pci_dev *pdev) ...@@ -1231,14 +1207,6 @@ static int uli526x_resume(struct pci_dev *pdev)
return 0; return 0;
} }
#else /* !CONFIG_PM */
#define uli526x_suspend NULL
#define uli526x_resume NULL
#endif /* !CONFIG_PM */
/* /*
* free all allocated rx buffer * free all allocated rx buffer
*/ */
...@@ -1761,14 +1729,14 @@ static const struct pci_device_id uli526x_pci_tbl[] = { ...@@ -1761,14 +1729,14 @@ static const struct pci_device_id uli526x_pci_tbl[] = {
}; };
MODULE_DEVICE_TABLE(pci, uli526x_pci_tbl); MODULE_DEVICE_TABLE(pci, uli526x_pci_tbl);
static SIMPLE_DEV_PM_OPS(uli526x_pm_ops, uli526x_suspend, uli526x_resume);
static struct pci_driver uli526x_driver = { static struct pci_driver uli526x_driver = {
.name = "uli526x", .name = "uli526x",
.id_table = uli526x_pci_tbl, .id_table = uli526x_pci_tbl,
.probe = uli526x_init_one, .probe = uli526x_init_one,
.remove = uli526x_remove_one, .remove = uli526x_remove_one,
.suspend = uli526x_suspend, .driver.pm = &uli526x_pm_ops,
.resume = uli526x_resume,
}; };
MODULE_AUTHOR("Peer Chen, peer.chen@uli.com.tw"); MODULE_AUTHOR("Peer Chen, peer.chen@uli.com.tw");
......
...@@ -1530,8 +1530,6 @@ static void w840_remove1(struct pci_dev *pdev) ...@@ -1530,8 +1530,6 @@ static void w840_remove1(struct pci_dev *pdev)
} }
} }
#ifdef CONFIG_PM
/* /*
* suspend/resume synchronization: * suspend/resume synchronization:
* - open, close, do_ioctl: * - open, close, do_ioctl:
...@@ -1555,9 +1553,9 @@ static void w840_remove1(struct pci_dev *pdev) ...@@ -1555,9 +1553,9 @@ static void w840_remove1(struct pci_dev *pdev)
* Detach must occur under spin_unlock_irq(), interrupts from a detached * Detach must occur under spin_unlock_irq(), interrupts from a detached
* device would cause an irq storm. * device would cause an irq storm.
*/ */
static int w840_suspend (struct pci_dev *pdev, pm_message_t state) static int __maybe_unused w840_suspend(struct device *dev_d)
{ {
struct net_device *dev = pci_get_drvdata (pdev); struct net_device *dev = dev_get_drvdata(dev_d);
struct netdev_private *np = netdev_priv(dev); struct netdev_private *np = netdev_priv(dev);
void __iomem *ioaddr = np->base_addr; void __iomem *ioaddr = np->base_addr;
...@@ -1590,21 +1588,15 @@ static int w840_suspend (struct pci_dev *pdev, pm_message_t state) ...@@ -1590,21 +1588,15 @@ static int w840_suspend (struct pci_dev *pdev, pm_message_t state)
return 0; return 0;
} }
static int w840_resume (struct pci_dev *pdev) static int __maybe_unused w840_resume(struct device *dev_d)
{ {
struct net_device *dev = pci_get_drvdata (pdev); struct net_device *dev = dev_get_drvdata(dev_d);
struct netdev_private *np = netdev_priv(dev); struct netdev_private *np = netdev_priv(dev);
int retval = 0;
rtnl_lock(); rtnl_lock();
if (netif_device_present(dev)) if (netif_device_present(dev))
goto out; /* device not suspended */ goto out; /* device not suspended */
if (netif_running(dev)) { if (netif_running(dev)) {
if ((retval = pci_enable_device(pdev))) {
dev_err(&dev->dev,
"pci_enable_device failed in resume\n");
goto out;
}
spin_lock_irq(&np->lock); spin_lock_irq(&np->lock);
iowrite32(1, np->base_addr+PCIBusCfg); iowrite32(1, np->base_addr+PCIBusCfg);
ioread32(np->base_addr+PCIBusCfg); ioread32(np->base_addr+PCIBusCfg);
...@@ -1622,19 +1614,17 @@ static int w840_resume (struct pci_dev *pdev) ...@@ -1622,19 +1614,17 @@ static int w840_resume (struct pci_dev *pdev)
} }
out: out:
rtnl_unlock(); rtnl_unlock();
return retval; return 0;
} }
#endif
static SIMPLE_DEV_PM_OPS(w840_pm_ops, w840_suspend, w840_resume);
static struct pci_driver w840_driver = { static struct pci_driver w840_driver = {
.name = DRV_NAME, .name = DRV_NAME,
.id_table = w840_pci_tbl, .id_table = w840_pci_tbl,
.probe = w840_probe1, .probe = w840_probe1,
.remove = w840_remove1, .remove = w840_remove1,
#ifdef CONFIG_PM .driver.pm = &w840_pm_ops,
.suspend = w840_suspend,
.resume = w840_resume,
#endif
}; };
static int __init w840_init(void) static int __init w840_init(void)
......
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