diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2006-01-30 11:37:54 -0800 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-02-07 02:00:35 -0500 |
commit | 08c06d8a9063c81f6a21c9f275aa1ee49d4bf380 (patch) | |
tree | 342a3ee4bee534bdf3a836a85c08d8d853bd1255 /drivers/net/sky2.c | |
parent | d561514f616504c0962f22d51d165f7b6e1bae1b (diff) |
[PATCH] sky2: power management fix
Fix suspend/resume for sky2. The status ring was getting reallocated
and a bunch of other mistakes. Also, check return from power_state
on resume.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index f8b973a04b6..c236c598474 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -26,7 +26,6 @@ /* * TOTEST * - speed setting - * - suspend/resume */ #include <linux/config.h> @@ -198,7 +197,7 @@ static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_PMC, &power_control); - vaux = (sky2_read8(hw, B0_CTST) & Y2_VAUX_AVAIL) && + vaux = (sky2_read16(hw, B0_CTST) & Y2_VAUX_AVAIL) && (power_control & PCI_PM_CAP_PME_D3cold); pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_CTRL, &power_control); @@ -2141,14 +2140,12 @@ static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk) static int sky2_reset(struct sky2_hw *hw) { - u32 ctst; u16 status; u8 t8, pmd_type; int i; - ctst = sky2_read32(hw, B0_CTST); - sky2_write8(hw, B0_CTST, CS_RST_CLR); + hw->chip_id = sky2_read8(hw, B2_CHIP_ID); if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) { printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n", @@ -2156,12 +2153,6 @@ static int sky2_reset(struct sky2_hw *hw) return -EOPNOTSUPP; } - /* ring for status responses */ - hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES, - &hw->st_dma); - if (!hw->st_le) - return -ENOMEM; - /* disable ASF */ if (hw->chip_id <= CHIP_ID_YUKON_EC) { sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); @@ -3135,6 +3126,12 @@ static int __devinit sky2_probe(struct pci_dev *pdev, } hw->pm_cap = pm_cap; + /* ring for status responses */ + hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES, + &hw->st_dma); + if (!hw->st_le) + goto err_out_iounmap; + err = sky2_reset(hw); if (err) goto err_out_iounmap; @@ -3263,25 +3260,33 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) static int sky2_resume(struct pci_dev *pdev) { struct sky2_hw *hw = pci_get_drvdata(pdev); - int i; + int i, err; pci_restore_state(pdev); pci_enable_wake(pdev, PCI_D0, 0); - sky2_set_power_state(hw, PCI_D0); + err = sky2_set_power_state(hw, PCI_D0); + if (err) + goto out; - sky2_reset(hw); + err = sky2_reset(hw); + if (err) + goto out; for (i = 0; i < 2; i++) { struct net_device *dev = hw->dev[i]; - if (dev) { - if (netif_running(dev)) { - netif_device_attach(dev); - if (sky2_up(dev)) - dev_close(dev); + if (dev && netif_running(dev)) { + netif_device_attach(dev); + err = sky2_up(dev); + if (err) { + printk(KERN_ERR PFX "%s: could not up: %d\n", + dev->name, err); + dev_close(dev); + break; } } } - return 0; +out: + return err; } #endif |