diff options
-rw-r--r-- | drivers/net/ethernet/sun/sungem.c | 76 |
1 files changed, 43 insertions, 33 deletions
diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c index 2d392a7b179a..0e9d2cf7979b 100644 --- a/drivers/net/ethernet/sun/sungem.c +++ b/drivers/net/ethernet/sun/sungem.c @@ -2139,20 +2139,6 @@ static int gem_do_start(struct net_device *dev) struct gem *gp = netdev_priv(dev); int rc; - /* Enable the cell */ - gem_get_cell(gp); - - /* Make sure PCI access and bus master are enabled */ - rc = pci_enable_device(gp->pdev); - if (rc) { - netdev_err(dev, "Failed to enable chip on PCI bus !\n"); - - /* Put cell and forget it for now, it will be considered as - * still asleep, a new sleep cycle may bring it back - */ - gem_put_cell(gp); - return -ENXIO; - } pci_set_master(gp->pdev); /* Init & setup chip hardware */ @@ -2230,13 +2216,6 @@ static void gem_do_stop(struct net_device *dev, int wol) /* Shut the PHY down eventually and setup WOL */ gem_stop_phy(gp, wol); - - /* Make sure bus master is disabled */ - pci_disable_device(gp->pdev); - - /* Cell not needed neither if no WOL */ - if (!wol) - gem_put_cell(gp); } static void gem_reset_task(struct work_struct *work) @@ -2288,26 +2267,53 @@ static void gem_reset_task(struct work_struct *work) static int gem_open(struct net_device *dev) { + struct gem *gp = netdev_priv(dev); + int rc; + /* We allow open while suspended, we just do nothing, * the chip will be initialized in resume() */ - if (netif_device_present(dev)) + if (netif_device_present(dev)) { + /* Enable the cell */ + gem_get_cell(gp); + + /* Make sure PCI access and bus master are enabled */ + rc = pci_enable_device(gp->pdev); + if (rc) { + netdev_err(dev, "Failed to enable chip on PCI bus !\n"); + + /* Put cell and forget it for now, it will be considered + *as still asleep, a new sleep cycle may bring it back + */ + gem_put_cell(gp); + return -ENXIO; + } return gem_do_start(dev); + } + return 0; } static int gem_close(struct net_device *dev) { - if (netif_device_present(dev)) + struct gem *gp = netdev_priv(dev); + + if (netif_device_present(dev)) { gem_do_stop(dev, 0); + /* Make sure bus master is disabled */ + pci_disable_device(gp->pdev); + + /* Cell not needed neither if no WOL */ + if (!gp->asleep_wol) + gem_put_cell(gp); + } return 0; } -#ifdef CONFIG_PM -static int gem_suspend(struct pci_dev *pdev, pm_message_t state) +static int __maybe_unused gem_suspend(struct device *dev_d) { - struct net_device *dev = pci_get_drvdata(pdev); + struct net_device *dev = dev_get_drvdata(dev_d); struct gem *gp = netdev_priv(dev); /* Lock the network stack first to avoid racing with open/close, @@ -2336,15 +2342,19 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state) gp->asleep_wol = !!gp->wake_on_lan; gem_do_stop(dev, gp->asleep_wol); + /* Cell not needed neither if no WOL */ + if (!gp->asleep_wol) + gem_put_cell(gp); + /* Unlock the network stack */ rtnl_unlock(); return 0; } -static int gem_resume(struct pci_dev *pdev) +static int __maybe_unused gem_resume(struct device *dev_d) { - struct net_device *dev = pci_get_drvdata(pdev); + struct net_device *dev = dev_get_drvdata(dev_d); struct gem *gp = netdev_priv(dev); /* See locking comment in gem_suspend */ @@ -2359,6 +2369,9 @@ static int gem_resume(struct pci_dev *pdev) return 0; } + /* Enable the cell */ + gem_get_cell(gp); + /* Restart chip. If that fails there isn't much we can do, we * leave things stopped. */ @@ -2375,7 +2388,6 @@ static int gem_resume(struct pci_dev *pdev) return 0; } -#endif /* CONFIG_PM */ static struct net_device_stats *gem_get_stats(struct net_device *dev) { @@ -3019,16 +3031,14 @@ err_disable_device: } +static SIMPLE_DEV_PM_OPS(gem_pm_ops, gem_suspend, gem_resume); static struct pci_driver gem_driver = { .name = GEM_MODULE_NAME, .id_table = gem_pci_tbl, .probe = gem_init_one, .remove = gem_remove_one, -#ifdef CONFIG_PM - .suspend = gem_suspend, - .resume = gem_resume, -#endif /* CONFIG_PM */ + .driver.pm = &gem_pm_ops, }; module_pci_driver(gem_driver); |