Adapt the tg3 driver to use the reworked PCI PM and make it use the
exported PCI PM core functions instead of accessing the PCI PM registers
directly by itself.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
{
u32 misc_host_ctrl;
static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
{
u32 misc_host_ctrl;
- u16 power_control, power_caps;
- int pm = tp->pm_cap;
/* Make sure register accesses (indirect or otherwise)
* will function correctly.
/* Make sure register accesses (indirect or otherwise)
* will function correctly.
TG3PCI_MISC_HOST_CTRL,
tp->misc_host_ctrl);
TG3PCI_MISC_HOST_CTRL,
tp->misc_host_ctrl);
- pci_read_config_word(tp->pdev,
- pm + PCI_PM_CTRL,
- &power_control);
- power_control |= PCI_PM_CTRL_PME_STATUS;
- power_control &= ~(PCI_PM_CTRL_STATE_MASK);
switch (state) {
case PCI_D0:
switch (state) {
case PCI_D0:
- power_control |= 0;
- pci_write_config_word(tp->pdev,
- pm + PCI_PM_CTRL,
- power_control);
- udelay(100); /* Delay after power state change */
+ pci_enable_wake(tp->pdev, state, false);
+ pci_set_power_state(tp->pdev, PCI_D0);
/* Switch out of Vaux if it is a NIC */
if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
/* Switch out of Vaux if it is a NIC */
if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
- power_control |= 1;
- break;
-
- power_control |= 2;
- break;
-
- printk(KERN_WARNING PFX "%s: Invalid power state (%d) "
- "requested.\n",
- tp->dev->name, state);
+ printk(KERN_ERR PFX "%s: Invalid power state (D%d) requested\n",
+ tp->dev->name, state);
-
- power_control |= PCI_PM_CTRL_PME_ENABLE;
-
misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL);
tw32(TG3PCI_MISC_HOST_CTRL,
misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT);
misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL);
tw32(TG3PCI_MISC_HOST_CTRL,
misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT);
WOL_DRV_WOL |
WOL_SET_MAGIC_PKT);
WOL_DRV_WOL |
WOL_SET_MAGIC_PKT);
- pci_read_config_word(tp->pdev, pm + PCI_PM_PMC, &power_caps);
-
if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) {
u32 mac_mode;
if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) {
u32 mac_mode;
if (!(tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
tw32(MAC_LED_CTRL, tp->led_ctrl);
if (!(tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
tw32(MAC_LED_CTRL, tp->led_ctrl);
- if (((power_caps & PCI_PM_CAP_PME_D3cold) &&
- (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)))
+ if (pci_pme_capable(tp->pdev, state) &&
+ (tp->tg3_flags & TG3_FLAG_WOL_ENABLE))
mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE;
tw32_f(MAC_MODE, mac_mode);
mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE;
tw32_f(MAC_MODE, mac_mode);
tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
+ if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)
+ pci_enable_wake(tp->pdev, state, true);
+
/* Finally, set the new power state. */
/* Finally, set the new power state. */
- pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control);
- udelay(100); /* Delay after power state change */
+ pci_set_power_state(tp->pdev, state);
{
struct tg3 *tp = netdev_priv(dev);
{
struct tg3 *tp = netdev_priv(dev);
- if (tp->tg3_flags & TG3_FLAG_WOL_CAP)
+ if ((tp->tg3_flags & TG3_FLAG_WOL_CAP) &&
+ device_can_wakeup(&tp->pdev->dev))
wol->supported = WAKE_MAGIC;
else
wol->supported = 0;
wol->supported = WAKE_MAGIC;
else
wol->supported = 0;
static int tg3_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct tg3 *tp = netdev_priv(dev);
static int tg3_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct tg3 *tp = netdev_priv(dev);
+ struct device *dp = &tp->pdev->dev;
if (wol->wolopts & ~WAKE_MAGIC)
return -EINVAL;
if ((wol->wolopts & WAKE_MAGIC) &&
if (wol->wolopts & ~WAKE_MAGIC)
return -EINVAL;
if ((wol->wolopts & WAKE_MAGIC) &&
- !(tp->tg3_flags & TG3_FLAG_WOL_CAP))
+ !((tp->tg3_flags & TG3_FLAG_WOL_CAP) && device_can_wakeup(dp)))
return -EINVAL;
spin_lock_bh(&tp->lock);
return -EINVAL;
spin_lock_bh(&tp->lock);
- if (wol->wolopts & WAKE_MAGIC)
+ if (wol->wolopts & WAKE_MAGIC) {
tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
+ device_set_wakeup_enable(dp, true);
+ } else {
tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE;
tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE;
+ device_set_wakeup_enable(dp, false);
+ }
spin_unlock_bh(&tp->lock);
return 0;
spin_unlock_bh(&tp->lock);
return 0;
if (val & VCPU_CFGSHDW_ASPM_DBNC)
tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND;
if ((val & VCPU_CFGSHDW_WOL_ENABLE) &&
if (val & VCPU_CFGSHDW_ASPM_DBNC)
tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND;
if ((val & VCPU_CFGSHDW_WOL_ENABLE) &&
- (val & VCPU_CFGSHDW_WOL_MAGPKT))
+ (val & VCPU_CFGSHDW_WOL_MAGPKT) &&
+ device_may_wakeup(&tp->pdev->dev))
tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
return;
}
tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
return;
}
!(nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL))
tp->tg3_flags &= ~TG3_FLAG_WOL_CAP;
!(nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL))
tp->tg3_flags &= ~TG3_FLAG_WOL_CAP;
- if (tp->tg3_flags & TG3_FLAG_WOL_CAP &&
- nic_cfg & NIC_SRAM_DATA_CFG_WOL_ENABLE)
+ if ((tp->tg3_flags & TG3_FLAG_WOL_CAP) &&
+ (nic_cfg & NIC_SRAM_DATA_CFG_WOL_ENABLE) &&
+ device_may_wakeup(&tp->pdev->dev))
tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
if (cfg2 & (1 << 17))
tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
if (cfg2 & (1 << 17))
{
struct net_device *dev = pci_get_drvdata(pdev);
struct tg3 *tp = netdev_priv(dev);
{
struct net_device *dev = pci_get_drvdata(pdev);
struct tg3 *tp = netdev_priv(dev);
+ pci_power_t target_state;
int err;
/* PCI register 4 needs to be saved whether netif_running() or not.
int err;
/* PCI register 4 needs to be saved whether netif_running() or not.
tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
tg3_full_unlock(tp);
tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
tg3_full_unlock(tp);
- err = tg3_set_power_state(tp, pci_choose_state(pdev, state));
+ target_state = pdev->pm_cap ? pci_target_state(pdev) : PCI_D3hot;
+
+ err = tg3_set_power_state(tp, target_state);