aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2010-12-25 07:56:23 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-31 14:14:28 -0500
commitc866b7eac073198cef03ea6bac2dc978635a9f5c (patch)
tree945266522a39ef06ea164157e78c0e32216eaaa4
parentf5260f02e7903bb10e45b1bf3500eab6425edf5c (diff)
tg3: Do not use legacy PCI power management
The tg3 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 sybsystem-level power management code. Convert tg3 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 on HP nx6325 with a NetXtreme BCM5788 adapter. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/tg3.c101
1 files changed, 43 insertions, 58 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 92fc29910c2d..6137869799a4 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -2551,39 +2551,35 @@ static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1)
2551 tw32(MAC_TX_BACKOFF_SEED, addr_high); 2551 tw32(MAC_TX_BACKOFF_SEED, addr_high);
2552} 2552}
2553 2553
2554static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) 2554static void tg3_enable_register_access(struct tg3 *tp)
2555{ 2555{
2556 u32 misc_host_ctrl; 2556 /*
2557 bool device_should_wake, do_low_power; 2557 * Make sure register accesses (indirect or otherwise) will function
2558 2558 * correctly.
2559 /* Make sure register accesses (indirect or otherwise)
2560 * will function correctly.
2561 */ 2559 */
2562 pci_write_config_dword(tp->pdev, 2560 pci_write_config_dword(tp->pdev,
2563 TG3PCI_MISC_HOST_CTRL, 2561 TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl);
2564 tp->misc_host_ctrl); 2562}
2565 2563
2566 switch (state) { 2564static int tg3_power_up(struct tg3 *tp)
2567 case PCI_D0: 2565{
2568 pci_enable_wake(tp->pdev, state, false); 2566 tg3_enable_register_access(tp);
2569 pci_set_power_state(tp->pdev, PCI_D0);
2570 2567
2571 /* Switch out of Vaux if it is a NIC */ 2568 pci_set_power_state(tp->pdev, PCI_D0);
2572 if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
2573 tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100);
2574 2569
2575 return 0; 2570 /* Switch out of Vaux if it is a NIC */
2571 if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
2572 tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100);
2576 2573
2577 case PCI_D1: 2574 return 0;
2578 case PCI_D2: 2575}
2579 case PCI_D3hot:
2580 break;
2581 2576
2582 default: 2577static int tg3_power_down_prepare(struct tg3 *tp)
2583 netdev_err(tp->dev, "Invalid power state (D%d) requested\n", 2578{
2584 state); 2579 u32 misc_host_ctrl;
2585 return -EINVAL; 2580 bool device_should_wake, do_low_power;
2586 } 2581
2582 tg3_enable_register_access(tp);
2587 2583
2588 /* Restore the CLKREQ setting. */ 2584 /* Restore the CLKREQ setting. */
2589 if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG) { 2585 if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG) {
@@ -2602,8 +2598,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
2602 tw32(TG3PCI_MISC_HOST_CTRL, 2598 tw32(TG3PCI_MISC_HOST_CTRL,
2603 misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT); 2599 misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT);
2604 2600
2605 device_should_wake = pci_pme_capable(tp->pdev, state) && 2601 device_should_wake = device_may_wakeup(&tp->pdev->dev) &&
2606 device_may_wakeup(&tp->pdev->dev) &&
2607 (tp->tg3_flags & TG3_FLAG_WOL_ENABLE); 2602 (tp->tg3_flags & TG3_FLAG_WOL_ENABLE);
2608 2603
2609 if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { 2604 if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
@@ -2823,13 +2818,15 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
2823 2818
2824 tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); 2819 tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
2825 2820
2826 if (device_should_wake) 2821 return 0;
2827 pci_enable_wake(tp->pdev, state, true); 2822}
2828 2823
2829 /* Finally, set the new power state. */ 2824static void tg3_power_down(struct tg3 *tp)
2830 pci_set_power_state(tp->pdev, state); 2825{
2826 tg3_power_down_prepare(tp);
2831 2827
2832 return 0; 2828 pci_wake_from_d3(tp->pdev, tp->tg3_flags & TG3_FLAG_WOL_ENABLE);
2829 pci_set_power_state(tp->pdev, PCI_D3hot);
2833} 2830}
2834 2831
2835static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8 *duplex) 2832static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8 *duplex)
@@ -9137,7 +9134,7 @@ static int tg3_open(struct net_device *dev)
9137 9134
9138 netif_carrier_off(tp->dev); 9135 netif_carrier_off(tp->dev);
9139 9136
9140 err = tg3_set_power_state(tp, PCI_D0); 9137 err = tg3_power_up(tp);
9141 if (err) 9138 if (err)
9142 return err; 9139 return err;
9143 9140
@@ -9302,7 +9299,7 @@ static int tg3_close(struct net_device *dev)
9302 9299
9303 tg3_free_consistent(tp); 9300 tg3_free_consistent(tp);
9304 9301
9305 tg3_set_power_state(tp, PCI_D3hot); 9302 tg3_power_down(tp);
9306 9303
9307 netif_carrier_off(tp->dev); 9304 netif_carrier_off(tp->dev);
9308 9305
@@ -11104,7 +11101,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
11104 struct tg3 *tp = netdev_priv(dev); 11101 struct tg3 *tp = netdev_priv(dev);
11105 11102
11106 if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) 11103 if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
11107 tg3_set_power_state(tp, PCI_D0); 11104 tg3_power_up(tp);
11108 11105
11109 memset(data, 0, sizeof(u64) * TG3_NUM_TEST); 11106 memset(data, 0, sizeof(u64) * TG3_NUM_TEST);
11110 11107
@@ -11172,7 +11169,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
11172 tg3_phy_start(tp); 11169 tg3_phy_start(tp);
11173 } 11170 }
11174 if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) 11171 if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
11175 tg3_set_power_state(tp, PCI_D3hot); 11172 tg3_power_down(tp);
11176 11173
11177} 11174}
11178 11175
@@ -13621,7 +13618,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
13621 (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) 13618 (tp->tg3_flags3 & TG3_FLG3_5717_PLUS))
13622 tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT; 13619 tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT;
13623 13620
13624 /* Set up tp->grc_local_ctrl before calling tg3_set_power_state(). 13621 /* Set up tp->grc_local_ctrl before calling tg_power_up().
13625 * GPIO1 driven high will bring 5700's external PHY out of reset. 13622 * GPIO1 driven high will bring 5700's external PHY out of reset.
13626 * It is also used as eeprom write protect on LOMs. 13623 * It is also used as eeprom write protect on LOMs.
13627 */ 13624 */
@@ -13652,7 +13649,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
13652 } 13649 }
13653 13650
13654 /* Force the chip into D0. */ 13651 /* Force the chip into D0. */
13655 err = tg3_set_power_state(tp, PCI_D0); 13652 err = tg3_power_up(tp);
13656 if (err) { 13653 if (err) {
13657 dev_err(&tp->pdev->dev, "Transition to D0 failed\n"); 13654 dev_err(&tp->pdev->dev, "Transition to D0 failed\n");
13658 return err; 13655 return err;
@@ -15055,19 +15052,13 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
15055 } 15052 }
15056} 15053}
15057 15054
15058static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) 15055static int tg3_suspend(struct device *device)
15059{ 15056{
15057 struct pci_dev *pdev = to_pci_dev(device);
15060 struct net_device *dev = pci_get_drvdata(pdev); 15058 struct net_device *dev = pci_get_drvdata(pdev);
15061 struct tg3 *tp = netdev_priv(dev); 15059 struct tg3 *tp = netdev_priv(dev);
15062 pci_power_t target_state;
15063 int err; 15060 int err;
15064 15061
15065 /* PCI register 4 needs to be saved whether netif_running() or not.
15066 * MSI address and data need to be saved if using MSI and
15067 * netif_running().
15068 */
15069 pci_save_state(pdev);
15070
15071 if (!netif_running(dev)) 15062 if (!netif_running(dev))
15072 return 0; 15063 return 0;
15073 15064
@@ -15088,9 +15079,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
15088 tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; 15079 tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
15089 tg3_full_unlock(tp); 15080 tg3_full_unlock(tp);
15090 15081
15091 target_state = pdev->pm_cap ? pci_target_state(pdev) : PCI_D3hot; 15082 err = tg3_power_down_prepare(tp);
15092
15093 err = tg3_set_power_state(tp, target_state);
15094 if (err) { 15083 if (err) {
15095 int err2; 15084 int err2;
15096 15085
@@ -15117,21 +15106,16 @@ out:
15117 return err; 15106 return err;
15118} 15107}
15119 15108
15120static int tg3_resume(struct pci_dev *pdev) 15109static int tg3_resume(struct device *device)
15121{ 15110{
15111 struct pci_dev *pdev = to_pci_dev(device);
15122 struct net_device *dev = pci_get_drvdata(pdev); 15112 struct net_device *dev = pci_get_drvdata(pdev);
15123 struct tg3 *tp = netdev_priv(dev); 15113 struct tg3 *tp = netdev_priv(dev);
15124 int err; 15114 int err;
15125 15115
15126 pci_restore_state(tp->pdev);
15127
15128 if (!netif_running(dev)) 15116 if (!netif_running(dev))
15129 return 0; 15117 return 0;
15130 15118
15131 err = tg3_set_power_state(tp, PCI_D0);
15132 if (err)
15133 return err;
15134
15135 netif_device_attach(dev); 15119 netif_device_attach(dev);
15136 15120
15137 tg3_full_lock(tp, 0); 15121 tg3_full_lock(tp, 0);
@@ -15155,13 +15139,14 @@ out:
15155 return err; 15139 return err;
15156} 15140}
15157 15141
15142static SIMPLE_DEV_PM_OPS(tg3_pm_ops, tg3_suspend, tg3_resume);
15143
15158static struct pci_driver tg3_driver = { 15144static struct pci_driver tg3_driver = {
15159 .name = DRV_MODULE_NAME, 15145 .name = DRV_MODULE_NAME,
15160 .id_table = tg3_pci_tbl, 15146 .id_table = tg3_pci_tbl,
15161 .probe = tg3_init_one, 15147 .probe = tg3_init_one,
15162 .remove = __devexit_p(tg3_remove_one), 15148 .remove = __devexit_p(tg3_remove_one),
15163 .suspend = tg3_suspend, 15149 .driver.pm = &tg3_pm_ops,
15164 .resume = tg3_resume
15165}; 15150};
15166 15151
15167static int __init tg3_init(void) 15152static int __init tg3_init(void)