diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2011-02-10 01:55:19 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-02-11 14:38:44 -0500 |
commit | dd68153def6b890a23288776cbd5bd2bad223a3f (patch) | |
tree | 43c4fe3ad2d9fc582c1fcbaad1c35ce75eef0588 | |
parent | 0303adeee3d6740cd78a71c0f40946b4886ceaa3 (diff) |
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>
-rw-r--r-- | drivers/net/atlx/atl1.c | 77 |
1 files changed, 31 insertions, 46 deletions
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 3b527687c28f..67f40b9c16ed 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c | |||
@@ -950,6 +950,7 @@ static int __devinit atl1_sw_init(struct atl1_adapter *adapter) | |||
950 | hw->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; | 950 | hw->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; |
951 | 951 | ||
952 | adapter->wol = 0; | 952 | adapter->wol = 0; |
953 | device_set_wakeup_enable(&adapter->pdev->dev, false); | ||
953 | adapter->rx_buffer_len = (hw->max_frame_size + 7) & ~7; | 954 | adapter->rx_buffer_len = (hw->max_frame_size + 7) & ~7; |
954 | adapter->ict = 50000; /* 100ms */ | 955 | adapter->ict = 50000; /* 100ms */ |
955 | adapter->link_speed = SPEED_0; /* hardware init */ | 956 | adapter->link_speed = SPEED_0; /* hardware init */ |
@@ -2735,15 +2736,15 @@ static int atl1_close(struct net_device *netdev) | |||
2735 | } | 2736 | } |
2736 | 2737 | ||
2737 | #ifdef CONFIG_PM | 2738 | #ifdef CONFIG_PM |
2738 | static int atl1_suspend(struct pci_dev *pdev, pm_message_t state) | 2739 | static int atl1_suspend(struct device *dev) |
2739 | { | 2740 | { |
2741 | struct pci_dev *pdev = to_pci_dev(dev); | ||
2740 | struct net_device *netdev = pci_get_drvdata(pdev); | 2742 | struct net_device *netdev = pci_get_drvdata(pdev); |
2741 | struct atl1_adapter *adapter = netdev_priv(netdev); | 2743 | struct atl1_adapter *adapter = netdev_priv(netdev); |
2742 | struct atl1_hw *hw = &adapter->hw; | 2744 | struct atl1_hw *hw = &adapter->hw; |
2743 | u32 ctrl = 0; | 2745 | u32 ctrl = 0; |
2744 | u32 wufc = adapter->wol; | 2746 | u32 wufc = adapter->wol; |
2745 | u32 val; | 2747 | u32 val; |
2746 | int retval; | ||
2747 | u16 speed; | 2748 | u16 speed; |
2748 | u16 duplex; | 2749 | u16 duplex; |
2749 | 2750 | ||
@@ -2751,17 +2752,15 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2751 | if (netif_running(netdev)) | 2752 | if (netif_running(netdev)) |
2752 | atl1_down(adapter); | 2753 | atl1_down(adapter); |
2753 | 2754 | ||
2754 | retval = pci_save_state(pdev); | ||
2755 | if (retval) | ||
2756 | return retval; | ||
2757 | |||
2758 | atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); | 2755 | atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); |
2759 | atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); | 2756 | atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); |
2760 | val = ctrl & BMSR_LSTATUS; | 2757 | val = ctrl & BMSR_LSTATUS; |
2761 | if (val) | 2758 | if (val) |
2762 | wufc &= ~ATLX_WUFC_LNKC; | 2759 | wufc &= ~ATLX_WUFC_LNKC; |
2760 | if (!wufc) | ||
2761 | goto disable_wol; | ||
2763 | 2762 | ||
2764 | if (val && wufc) { | 2763 | if (val) { |
2765 | val = atl1_get_speed_and_duplex(hw, &speed, &duplex); | 2764 | val = atl1_get_speed_and_duplex(hw, &speed, &duplex); |
2766 | if (val) { | 2765 | if (val) { |
2767 | if (netif_msg_ifdown(adapter)) | 2766 | if (netif_msg_ifdown(adapter)) |
@@ -2798,23 +2797,18 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2798 | ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; | 2797 | ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; |
2799 | iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC); | 2798 | iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC); |
2800 | ioread32(hw->hw_addr + REG_PCIE_PHYMISC); | 2799 | ioread32(hw->hw_addr + REG_PCIE_PHYMISC); |
2801 | 2800 | } else { | |
2802 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); | ||
2803 | goto exit; | ||
2804 | } | ||
2805 | |||
2806 | if (!val && wufc) { | ||
2807 | ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN); | 2801 | ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN); |
2808 | iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL); | 2802 | iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL); |
2809 | ioread32(hw->hw_addr + REG_WOL_CTRL); | 2803 | ioread32(hw->hw_addr + REG_WOL_CTRL); |
2810 | iowrite32(0, hw->hw_addr + REG_MAC_CTRL); | 2804 | iowrite32(0, hw->hw_addr + REG_MAC_CTRL); |
2811 | ioread32(hw->hw_addr + REG_MAC_CTRL); | 2805 | ioread32(hw->hw_addr + REG_MAC_CTRL); |
2812 | hw->phy_configured = false; | 2806 | hw->phy_configured = false; |
2813 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); | ||
2814 | goto exit; | ||
2815 | } | 2807 | } |
2816 | 2808 | ||
2817 | disable_wol: | 2809 | return 0; |
2810 | |||
2811 | disable_wol: | ||
2818 | iowrite32(0, hw->hw_addr + REG_WOL_CTRL); | 2812 | iowrite32(0, hw->hw_addr + REG_WOL_CTRL); |
2819 | ioread32(hw->hw_addr + REG_WOL_CTRL); | 2813 | ioread32(hw->hw_addr + REG_WOL_CTRL); |
2820 | ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC); | 2814 | ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC); |
@@ -2822,37 +2816,17 @@ disable_wol: | |||
2822 | iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC); | 2816 | iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC); |
2823 | ioread32(hw->hw_addr + REG_PCIE_PHYMISC); | 2817 | ioread32(hw->hw_addr + REG_PCIE_PHYMISC); |
2824 | hw->phy_configured = false; | 2818 | hw->phy_configured = false; |
2825 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); | ||
2826 | exit: | ||
2827 | if (netif_running(netdev)) | ||
2828 | pci_disable_msi(adapter->pdev); | ||
2829 | pci_disable_device(pdev); | ||
2830 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
2831 | 2819 | ||
2832 | return 0; | 2820 | return 0; |
2833 | } | 2821 | } |
2834 | 2822 | ||
2835 | static int atl1_resume(struct pci_dev *pdev) | 2823 | static int atl1_resume(struct device *dev) |
2836 | { | 2824 | { |
2825 | struct pci_dev *pdev = to_pci_dev(dev); | ||
2837 | struct net_device *netdev = pci_get_drvdata(pdev); | 2826 | struct net_device *netdev = pci_get_drvdata(pdev); |
2838 | struct atl1_adapter *adapter = netdev_priv(netdev); | 2827 | struct atl1_adapter *adapter = netdev_priv(netdev); |
2839 | u32 err; | ||
2840 | 2828 | ||
2841 | pci_set_power_state(pdev, PCI_D0); | ||
2842 | pci_restore_state(pdev); | ||
2843 | |||
2844 | err = pci_enable_device(pdev); | ||
2845 | if (err) { | ||
2846 | if (netif_msg_ifup(adapter)) | ||
2847 | dev_printk(KERN_DEBUG, &pdev->dev, | ||
2848 | "error enabling pci device\n"); | ||
2849 | return err; | ||
2850 | } | ||
2851 | |||
2852 | pci_set_master(pdev); | ||
2853 | iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL); | 2829 | iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL); |
2854 | pci_enable_wake(pdev, PCI_D3hot, 0); | ||
2855 | pci_enable_wake(pdev, PCI_D3cold, 0); | ||
2856 | 2830 | ||
2857 | atl1_reset_hw(&adapter->hw); | 2831 | atl1_reset_hw(&adapter->hw); |
2858 | 2832 | ||
@@ -2864,16 +2838,25 @@ static int atl1_resume(struct pci_dev *pdev) | |||
2864 | 2838 | ||
2865 | return 0; | 2839 | return 0; |
2866 | } | 2840 | } |
2841 | |||
2842 | static SIMPLE_DEV_PM_OPS(atl1_pm_ops, atl1_suspend, atl1_resume); | ||
2843 | #define ATL1_PM_OPS (&atl1_pm_ops) | ||
2844 | |||
2867 | #else | 2845 | #else |
2868 | #define atl1_suspend NULL | 2846 | |
2869 | #define atl1_resume NULL | 2847 | static int atl1_suspend(struct device *dev) { return 0; } |
2848 | |||
2849 | #define ATL1_PM_OPS NULL | ||
2870 | #endif | 2850 | #endif |
2871 | 2851 | ||
2872 | static void atl1_shutdown(struct pci_dev *pdev) | 2852 | static void atl1_shutdown(struct pci_dev *pdev) |
2873 | { | 2853 | { |
2874 | #ifdef CONFIG_PM | 2854 | struct net_device *netdev = pci_get_drvdata(pdev); |
2875 | atl1_suspend(pdev, PMSG_SUSPEND); | 2855 | struct atl1_adapter *adapter = netdev_priv(netdev); |
2876 | #endif | 2856 | |
2857 | atl1_suspend(&pdev->dev); | ||
2858 | pci_wake_from_d3(pdev, adapter->wol); | ||
2859 | pci_set_power_state(pdev, PCI_D3hot); | ||
2877 | } | 2860 | } |
2878 | 2861 | ||
2879 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2862 | #ifdef CONFIG_NET_POLL_CONTROLLER |
@@ -3117,9 +3100,8 @@ static struct pci_driver atl1_driver = { | |||
3117 | .id_table = atl1_pci_tbl, | 3100 | .id_table = atl1_pci_tbl, |
3118 | .probe = atl1_probe, | 3101 | .probe = atl1_probe, |
3119 | .remove = __devexit_p(atl1_remove), | 3102 | .remove = __devexit_p(atl1_remove), |
3120 | .suspend = atl1_suspend, | 3103 | .shutdown = atl1_shutdown, |
3121 | .resume = atl1_resume, | 3104 | .driver.pm = ATL1_PM_OPS, |
3122 | .shutdown = atl1_shutdown | ||
3123 | }; | 3105 | }; |
3124 | 3106 | ||
3125 | /* | 3107 | /* |
@@ -3409,6 +3391,9 @@ static int atl1_set_wol(struct net_device *netdev, | |||
3409 | adapter->wol = 0; | 3391 | adapter->wol = 0; |
3410 | if (wol->wolopts & WAKE_MAGIC) | 3392 | if (wol->wolopts & WAKE_MAGIC) |
3411 | adapter->wol |= ATLX_WUFC_MAG; | 3393 | adapter->wol |= ATLX_WUFC_MAG; |
3394 | |||
3395 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); | ||
3396 | |||
3412 | return 0; | 3397 | return 0; |
3413 | } | 3398 | } |
3414 | 3399 | ||