diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2006-01-30 14:37:54 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-02-07 02:00:35 -0500 |
commit | 08c06d8a9063c81f6a21c9f275aa1ee49d4bf380 (patch) | |
tree | 342a3ee4bee534bdf3a836a85c08d8d853bd1255 /drivers/net | |
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')
-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 f8b973a04b65..c236c5984743 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -26,7 +26,6 @@ | |||
26 | /* | 26 | /* |
27 | * TOTEST | 27 | * TOTEST |
28 | * - speed setting | 28 | * - speed setting |
29 | * - suspend/resume | ||
30 | */ | 29 | */ |
31 | 30 | ||
32 | #include <linux/config.h> | 31 | #include <linux/config.h> |
@@ -198,7 +197,7 @@ static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
198 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | 197 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
199 | 198 | ||
200 | pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_PMC, &power_control); | 199 | pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_PMC, &power_control); |
201 | vaux = (sky2_read8(hw, B0_CTST) & Y2_VAUX_AVAIL) && | 200 | vaux = (sky2_read16(hw, B0_CTST) & Y2_VAUX_AVAIL) && |
202 | (power_control & PCI_PM_CAP_PME_D3cold); | 201 | (power_control & PCI_PM_CAP_PME_D3cold); |
203 | 202 | ||
204 | pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_CTRL, &power_control); | 203 | 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) | |||
2141 | 2140 | ||
2142 | static int sky2_reset(struct sky2_hw *hw) | 2141 | static int sky2_reset(struct sky2_hw *hw) |
2143 | { | 2142 | { |
2144 | u32 ctst; | ||
2145 | u16 status; | 2143 | u16 status; |
2146 | u8 t8, pmd_type; | 2144 | u8 t8, pmd_type; |
2147 | int i; | 2145 | int i; |
2148 | 2146 | ||
2149 | ctst = sky2_read32(hw, B0_CTST); | ||
2150 | |||
2151 | sky2_write8(hw, B0_CTST, CS_RST_CLR); | 2147 | sky2_write8(hw, B0_CTST, CS_RST_CLR); |
2148 | |||
2152 | hw->chip_id = sky2_read8(hw, B2_CHIP_ID); | 2149 | hw->chip_id = sky2_read8(hw, B2_CHIP_ID); |
2153 | if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) { | 2150 | if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) { |
2154 | printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n", | 2151 | printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n", |
@@ -2156,12 +2153,6 @@ static int sky2_reset(struct sky2_hw *hw) | |||
2156 | return -EOPNOTSUPP; | 2153 | return -EOPNOTSUPP; |
2157 | } | 2154 | } |
2158 | 2155 | ||
2159 | /* ring for status responses */ | ||
2160 | hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES, | ||
2161 | &hw->st_dma); | ||
2162 | if (!hw->st_le) | ||
2163 | return -ENOMEM; | ||
2164 | |||
2165 | /* disable ASF */ | 2156 | /* disable ASF */ |
2166 | if (hw->chip_id <= CHIP_ID_YUKON_EC) { | 2157 | if (hw->chip_id <= CHIP_ID_YUKON_EC) { |
2167 | sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); | 2158 | sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); |
@@ -3135,6 +3126,12 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
3135 | } | 3126 | } |
3136 | hw->pm_cap = pm_cap; | 3127 | hw->pm_cap = pm_cap; |
3137 | 3128 | ||
3129 | /* ring for status responses */ | ||
3130 | hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES, | ||
3131 | &hw->st_dma); | ||
3132 | if (!hw->st_le) | ||
3133 | goto err_out_iounmap; | ||
3134 | |||
3138 | err = sky2_reset(hw); | 3135 | err = sky2_reset(hw); |
3139 | if (err) | 3136 | if (err) |
3140 | goto err_out_iounmap; | 3137 | goto err_out_iounmap; |
@@ -3263,25 +3260,33 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3263 | static int sky2_resume(struct pci_dev *pdev) | 3260 | static int sky2_resume(struct pci_dev *pdev) |
3264 | { | 3261 | { |
3265 | struct sky2_hw *hw = pci_get_drvdata(pdev); | 3262 | struct sky2_hw *hw = pci_get_drvdata(pdev); |
3266 | int i; | 3263 | int i, err; |
3267 | 3264 | ||
3268 | pci_restore_state(pdev); | 3265 | pci_restore_state(pdev); |
3269 | pci_enable_wake(pdev, PCI_D0, 0); | 3266 | pci_enable_wake(pdev, PCI_D0, 0); |
3270 | sky2_set_power_state(hw, PCI_D0); | 3267 | err = sky2_set_power_state(hw, PCI_D0); |
3268 | if (err) | ||
3269 | goto out; | ||
3271 | 3270 | ||
3272 | sky2_reset(hw); | 3271 | err = sky2_reset(hw); |
3272 | if (err) | ||
3273 | goto out; | ||
3273 | 3274 | ||
3274 | for (i = 0; i < 2; i++) { | 3275 | for (i = 0; i < 2; i++) { |
3275 | struct net_device *dev = hw->dev[i]; | 3276 | struct net_device *dev = hw->dev[i]; |
3276 | if (dev) { | 3277 | if (dev && netif_running(dev)) { |
3277 | if (netif_running(dev)) { | 3278 | netif_device_attach(dev); |
3278 | netif_device_attach(dev); | 3279 | err = sky2_up(dev); |
3279 | if (sky2_up(dev)) | 3280 | if (err) { |
3280 | dev_close(dev); | 3281 | printk(KERN_ERR PFX "%s: could not up: %d\n", |
3282 | dev->name, err); | ||
3283 | dev_close(dev); | ||
3284 | break; | ||
3281 | } | 3285 | } |
3282 | } | 3286 | } |
3283 | } | 3287 | } |
3284 | return 0; | 3288 | out: |
3289 | return err; | ||
3285 | } | 3290 | } |
3286 | #endif | 3291 | #endif |
3287 | 3292 | ||