diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2006-08-28 19:19:35 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-08-29 17:18:30 -0400 |
commit | d38efdd65aaabd82374f386d0cc54de2ffc90af3 (patch) | |
tree | 99967ff37a6a491776d790f0e40fb15747ed7ef7 /drivers/net | |
parent | e981d47b9f0c322bacc8398c6c25fcd355a19415 (diff) |
[PATCH] skge: cleanup suspend/resume code
The code for suspend/resume needs several fixes. The hardware lock
should be setup in probe only, not in resume. Interrupts should be
disabled during suspend, etc.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/skge.c | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 1b752141a4f3..b8ebd9c7d40a 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -3106,7 +3106,6 @@ static int skge_reset(struct skge_hw *hw) | |||
3106 | else | 3106 | else |
3107 | hw->ram_size = t8 * 4096; | 3107 | hw->ram_size = t8 * 4096; |
3108 | 3108 | ||
3109 | spin_lock_init(&hw->hw_lock); | ||
3110 | hw->intr_mask = IS_HW_ERR | IS_EXT_REG | IS_PORT_1; | 3109 | hw->intr_mask = IS_HW_ERR | IS_EXT_REG | IS_PORT_1; |
3111 | if (hw->ports > 1) | 3110 | if (hw->ports > 1) |
3112 | hw->intr_mask |= IS_PORT_2; | 3111 | hw->intr_mask |= IS_PORT_2; |
@@ -3332,6 +3331,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, | |||
3332 | hw->pdev = pdev; | 3331 | hw->pdev = pdev; |
3333 | mutex_init(&hw->phy_mutex); | 3332 | mutex_init(&hw->phy_mutex); |
3334 | INIT_WORK(&hw->phy_work, skge_extirq, hw); | 3333 | INIT_WORK(&hw->phy_work, skge_extirq, hw); |
3334 | spin_lock_init(&hw->hw_lock); | ||
3335 | 3335 | ||
3336 | hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000); | 3336 | hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000); |
3337 | if (!hw->regs) { | 3337 | if (!hw->regs) { |
@@ -3449,26 +3449,25 @@ static int skge_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3449 | struct skge_hw *hw = pci_get_drvdata(pdev); | 3449 | struct skge_hw *hw = pci_get_drvdata(pdev); |
3450 | int i, wol = 0; | 3450 | int i, wol = 0; |
3451 | 3451 | ||
3452 | for (i = 0; i < 2; i++) { | 3452 | pci_save_state(pdev); |
3453 | for (i = 0; i < hw->ports; i++) { | ||
3453 | struct net_device *dev = hw->dev[i]; | 3454 | struct net_device *dev = hw->dev[i]; |
3454 | 3455 | ||
3455 | if (dev) { | 3456 | if (netif_running(dev)) { |
3456 | struct skge_port *skge = netdev_priv(dev); | 3457 | struct skge_port *skge = netdev_priv(dev); |
3457 | if (netif_running(dev)) { | 3458 | |
3458 | netif_carrier_off(dev); | 3459 | netif_carrier_off(dev); |
3459 | if (skge->wol) | 3460 | if (skge->wol) |
3460 | netif_stop_queue(dev); | 3461 | netif_stop_queue(dev); |
3461 | else | 3462 | else |
3462 | skge_down(dev); | 3463 | skge_down(dev); |
3463 | } | ||
3464 | netif_device_detach(dev); | ||
3465 | wol |= skge->wol; | 3464 | wol |= skge->wol; |
3466 | } | 3465 | } |
3466 | netif_device_detach(dev); | ||
3467 | } | 3467 | } |
3468 | 3468 | ||
3469 | pci_save_state(pdev); | 3469 | skge_write32(hw, B0_IMSK, 0); |
3470 | pci_enable_wake(pdev, pci_choose_state(pdev, state), wol); | 3470 | pci_enable_wake(pdev, pci_choose_state(pdev, state), wol); |
3471 | pci_disable_device(pdev); | ||
3472 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 3471 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); |
3473 | 3472 | ||
3474 | return 0; | 3473 | return 0; |
@@ -3477,23 +3476,33 @@ static int skge_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3477 | static int skge_resume(struct pci_dev *pdev) | 3476 | static int skge_resume(struct pci_dev *pdev) |
3478 | { | 3477 | { |
3479 | struct skge_hw *hw = pci_get_drvdata(pdev); | 3478 | struct skge_hw *hw = pci_get_drvdata(pdev); |
3480 | int i; | 3479 | int i, err; |
3481 | 3480 | ||
3482 | pci_set_power_state(pdev, PCI_D0); | 3481 | pci_set_power_state(pdev, PCI_D0); |
3483 | pci_restore_state(pdev); | 3482 | pci_restore_state(pdev); |
3484 | pci_enable_wake(pdev, PCI_D0, 0); | 3483 | pci_enable_wake(pdev, PCI_D0, 0); |
3485 | 3484 | ||
3486 | skge_reset(hw); | 3485 | err = skge_reset(hw); |
3486 | if (err) | ||
3487 | goto out; | ||
3487 | 3488 | ||
3488 | for (i = 0; i < 2; i++) { | 3489 | for (i = 0; i < hw->ports; i++) { |
3489 | struct net_device *dev = hw->dev[i]; | 3490 | struct net_device *dev = hw->dev[i]; |
3490 | if (dev) { | 3491 | |
3491 | netif_device_attach(dev); | 3492 | netif_device_attach(dev); |
3492 | if (netif_running(dev) && skge_up(dev)) | 3493 | if (netif_running(dev)) { |
3494 | err = skge_up(dev); | ||
3495 | |||
3496 | if (err) { | ||
3497 | printk(KERN_ERR PFX "%s: could not up: %d\n", | ||
3498 | dev->name, err); | ||
3493 | dev_close(dev); | 3499 | dev_close(dev); |
3500 | goto out; | ||
3501 | } | ||
3494 | } | 3502 | } |
3495 | } | 3503 | } |
3496 | return 0; | 3504 | out: |
3505 | return err; | ||
3497 | } | 3506 | } |
3498 | #endif | 3507 | #endif |
3499 | 3508 | ||