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: Thomas Fjellstrom <thomas@fjellstrom.ca> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
0303adeee3
commit
dd68153def
@@ -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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#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)
|
|||||||
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)
|
|||||||
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 @@ disable_wol:
|
|||||||
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)
|
|||||||
|
|
||||||
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 = {
|
|||||||
.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,
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user