summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-12-20 22:06:34 +0100
committerJeff Garzik <jeff@garzik.org>2006-12-26 22:36:42 +0100
commit44ade178249fe53d055fd92113eaa271e06acddd (patch)
tree1b30df83af43394744ed51ce60f0eabdbd56500a /drivers
parentsky2: dual port NAPI problem (diff)
downloadlinux-44ade178249fe53d055fd92113eaa271e06acddd.tar.xz
linux-44ade178249fe53d055fd92113eaa271e06acddd.zip
sky2: power management/MSI workaround
MSI doesn't work properly on resume on many platforms because the BIOS goes and changes it back to INTx mode after the sky2 driver has restored in resume. It is really a bug in the base power management resume code, and this workaround is temporary until the change to PM code works it's way through the release process. The PM fix is non-trivial since it needs to change when non-boot CPU's are enabled. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/sky2.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 4fb3db99bcd1..93cb39388a1b 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -3638,6 +3638,29 @@ static int sky2_resume(struct pci_dev *pdev)
out:
return err;
}
+
+/* BIOS resume runs after device (it's a bug in PM)
+ * as a temporary workaround on suspend/resume leave MSI disabled
+ */
+static int sky2_suspend_late(struct pci_dev *pdev, pm_message_t state)
+{
+ struct sky2_hw *hw = pci_get_drvdata(pdev);
+
+ free_irq(pdev->irq, hw);
+ if (hw->msi) {
+ pci_disable_msi(pdev);
+ hw->msi = 0;
+ }
+ return 0;
+}
+
+static int sky2_resume_early(struct pci_dev *pdev)
+{
+ struct sky2_hw *hw = pci_get_drvdata(pdev);
+ struct net_device *dev = hw->dev[0];
+
+ return request_irq(pdev->irq, sky2_intr, IRQF_SHARED, dev->name, hw);
+}
#endif
static struct pci_driver sky2_driver = {
@@ -3648,6 +3671,8 @@ static struct pci_driver sky2_driver = {
#ifdef CONFIG_PM
.suspend = sky2_suspend,
.resume = sky2_resume,
+ .suspend_late = sky2_suspend_late,
+ .resume_early = sky2_resume_early,
#endif
};