Commit dd68153d authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by David S. Miller

atl1: Do not use legacy PCI power management

The atl1 driver uses the legacy PCI power management, so it has to
do some PCI-specific things in its ->suspend() and ->resume()
callbacks, which isn't necessary and should better be done by the PCI
subsystem-level power management code.

Convert atl1 to the new PCI power management framework and make it
let the PCI subsystem take care of all the PCI-specific aspects of
device handling during system power transitions.
Tested-by: default avatarThomas Fjellstrom <thomas@fjellstrom.ca>
Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0303adee
...@@ -950,6 +950,7 @@ static int __devinit atl1_sw_init(struct atl1_adapter *adapter) ...@@ -950,6 +950,7 @@ static int __devinit atl1_sw_init(struct atl1_adapter *adapter)
hw->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; hw->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
adapter->wol = 0; adapter->wol = 0;
device_set_wakeup_enable(&adapter->pdev->dev, false);
adapter->rx_buffer_len = (hw->max_frame_size + 7) & ~7; adapter->rx_buffer_len = (hw->max_frame_size + 7) & ~7;
adapter->ict = 50000; /* 100ms */ adapter->ict = 50000; /* 100ms */
adapter->link_speed = SPEED_0; /* hardware init */ adapter->link_speed = SPEED_0; /* hardware init */
...@@ -2735,15 +2736,15 @@ static int atl1_close(struct net_device *netdev) ...@@ -2735,15 +2736,15 @@ static int atl1_close(struct net_device *netdev)
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int atl1_suspend(struct pci_dev *pdev, pm_message_t state) static int atl1_suspend(struct device *dev)
{ {
struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct atl1_adapter *adapter = netdev_priv(netdev); struct atl1_adapter *adapter = netdev_priv(netdev);
struct atl1_hw *hw = &adapter->hw; struct atl1_hw *hw = &adapter->hw;
u32 ctrl = 0; u32 ctrl = 0;
u32 wufc = adapter->wol; u32 wufc = adapter->wol;
u32 val; u32 val;
int retval;
u16 speed; u16 speed;
u16 duplex; u16 duplex;
...@@ -2751,17 +2752,15 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -2751,17 +2752,15 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
if (netif_running(netdev)) if (netif_running(netdev))
atl1_down(adapter); atl1_down(adapter);
retval = pci_save_state(pdev);
if (retval)
return retval;
atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
val = ctrl & BMSR_LSTATUS; val = ctrl & BMSR_LSTATUS;
if (val) if (val)
wufc &= ~ATLX_WUFC_LNKC; wufc &= ~ATLX_WUFC_LNKC;
if (!wufc)
goto disable_wol;
if (val && wufc) { if (val) {
val = atl1_get_speed_and_duplex(hw, &speed, &duplex); val = atl1_get_speed_and_duplex(hw, &speed, &duplex);
if (val) { if (val) {
if (netif_msg_ifdown(adapter)) if (netif_msg_ifdown(adapter))
...@@ -2798,23 +2797,18 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -2798,23 +2797,18 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC); iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC);
ioread32(hw->hw_addr + REG_PCIE_PHYMISC); ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
} else {
pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
goto exit;
}
if (!val && wufc) {
ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN); ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN);
iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL); iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
ioread32(hw->hw_addr + REG_WOL_CTRL); ioread32(hw->hw_addr + REG_WOL_CTRL);
iowrite32(0, hw->hw_addr + REG_MAC_CTRL); iowrite32(0, hw->hw_addr + REG_MAC_CTRL);
ioread32(hw->hw_addr + REG_MAC_CTRL); ioread32(hw->hw_addr + REG_MAC_CTRL);
hw->phy_configured = false; hw->phy_configured = false;
pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
goto exit;
} }
disable_wol: return 0;
disable_wol:
iowrite32(0, hw->hw_addr + REG_WOL_CTRL); iowrite32(0, hw->hw_addr + REG_WOL_CTRL);
ioread32(hw->hw_addr + REG_WOL_CTRL); ioread32(hw->hw_addr + REG_WOL_CTRL);
ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC); ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
...@@ -2822,37 +2816,17 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -2822,37 +2816,17 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC); iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC);
ioread32(hw->hw_addr + REG_PCIE_PHYMISC); ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
hw->phy_configured = false; hw->phy_configured = false;
pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
exit:
if (netif_running(netdev))
pci_disable_msi(adapter->pdev);
pci_disable_device(pdev);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
return 0; return 0;
} }
static int atl1_resume(struct pci_dev *pdev) static int atl1_resume(struct device *dev)
{ {
struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct atl1_adapter *adapter = netdev_priv(netdev); struct atl1_adapter *adapter = netdev_priv(netdev);
u32 err;
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
err = pci_enable_device(pdev);
if (err) {
if (netif_msg_ifup(adapter))
dev_printk(KERN_DEBUG, &pdev->dev,
"error enabling pci device\n");
return err;
}
pci_set_master(pdev);
iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL); iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL);
pci_enable_wake(pdev, PCI_D3hot, 0);
pci_enable_wake(pdev, PCI_D3cold, 0);
atl1_reset_hw(&adapter->hw); atl1_reset_hw(&adapter->hw);
...@@ -2864,16 +2838,25 @@ static int atl1_resume(struct pci_dev *pdev) ...@@ -2864,16 +2838,25 @@ static int atl1_resume(struct pci_dev *pdev)
return 0; return 0;
} }
static SIMPLE_DEV_PM_OPS(atl1_pm_ops, atl1_suspend, atl1_resume);
#define ATL1_PM_OPS (&atl1_pm_ops)
#else #else
#define atl1_suspend NULL
#define atl1_resume NULL static int atl1_suspend(struct device *dev) { return 0; }
#define ATL1_PM_OPS NULL
#endif #endif
static void atl1_shutdown(struct pci_dev *pdev) static void atl1_shutdown(struct pci_dev *pdev)
{ {
#ifdef CONFIG_PM struct net_device *netdev = pci_get_drvdata(pdev);
atl1_suspend(pdev, PMSG_SUSPEND); struct atl1_adapter *adapter = netdev_priv(netdev);
#endif
atl1_suspend(&pdev->dev);
pci_wake_from_d3(pdev, adapter->wol);
pci_set_power_state(pdev, PCI_D3hot);
} }
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER
...@@ -3117,9 +3100,8 @@ static struct pci_driver atl1_driver = { ...@@ -3117,9 +3100,8 @@ static struct pci_driver atl1_driver = {
.id_table = atl1_pci_tbl, .id_table = atl1_pci_tbl,
.probe = atl1_probe, .probe = atl1_probe,
.remove = __devexit_p(atl1_remove), .remove = __devexit_p(atl1_remove),
.suspend = atl1_suspend, .shutdown = atl1_shutdown,
.resume = atl1_resume, .driver.pm = ATL1_PM_OPS,
.shutdown = atl1_shutdown
}; };
/* /*
...@@ -3409,6 +3391,9 @@ static int atl1_set_wol(struct net_device *netdev, ...@@ -3409,6 +3391,9 @@ static int atl1_set_wol(struct net_device *netdev,
adapter->wol = 0; adapter->wol = 0;
if (wol->wolopts & WAKE_MAGIC) if (wol->wolopts & WAKE_MAGIC)
adapter->wol |= ATLX_WUFC_MAG; adapter->wol |= ATLX_WUFC_MAG;
device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
return 0; return 0;
} }
......
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