diff options
author | Francois Romieu <romieu@fr.zoreil.com> | 2006-10-10 17:33:27 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-12-02 00:11:55 -0500 |
commit | a189317fa0e9d425cd3a4c248b06f96d876cf7fd (patch) | |
tree | 63da17e7b0c80bed776d95b9408587b805c5f533 | |
parent | 3c3070d713d798f7f9e7ee3614e49b47655d14d8 (diff) |
[PATCH] forcedeth: power management support
Tobias Diedrich <ranma@tdiedrich.de> sayeth:
Vanilla forcedeth doesn't seem to support suspend and an ifdown/up-cycle is
needed to get it working again after suspend. Francois Romieu's "Awfully
experimental" patch is working just fine for me (with message signalled
interrupts disabled) and has survived quite a few suspend/resume cycles.
So I'd very much like to see (at least partial, with msi disabled)
suspend support for forcedeth in mainline.
(Addresses http://bugzilla.kernel.org/show_bug.cgi?id=6398)
Cc: Francois Romieu <romieu@fr.zoreil.com>
Cc; Jeff Garzik <jeff@garzik.org>
Cc: Manfred Spraul <manfred@colorfullife.com>
Cc: Ayaz Abdulla <aabdulla@nvidia.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/net/forcedeth.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index c5ed635bce36..87af5e497c51 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -4603,6 +4603,50 @@ static void __devexit nv_remove(struct pci_dev *pci_dev) | |||
4603 | pci_set_drvdata(pci_dev, NULL); | 4603 | pci_set_drvdata(pci_dev, NULL); |
4604 | } | 4604 | } |
4605 | 4605 | ||
4606 | #ifdef CONFIG_PM | ||
4607 | static int nv_suspend(struct pci_dev *pdev, pm_message_t state) | ||
4608 | { | ||
4609 | struct net_device *dev = pci_get_drvdata(pdev); | ||
4610 | struct fe_priv *np = netdev_priv(dev); | ||
4611 | |||
4612 | if (!netif_running(dev)) | ||
4613 | goto out; | ||
4614 | |||
4615 | netif_device_detach(dev); | ||
4616 | |||
4617 | // Gross. | ||
4618 | nv_close(dev); | ||
4619 | |||
4620 | pci_save_state(pdev); | ||
4621 | pci_enable_wake(pdev, pci_choose_state(pdev, state), np->wolenabled); | ||
4622 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
4623 | out: | ||
4624 | return 0; | ||
4625 | } | ||
4626 | |||
4627 | static int nv_resume(struct pci_dev *pdev) | ||
4628 | { | ||
4629 | struct net_device *dev = pci_get_drvdata(pdev); | ||
4630 | int rc = 0; | ||
4631 | |||
4632 | if (!netif_running(dev)) | ||
4633 | goto out; | ||
4634 | |||
4635 | netif_device_attach(dev); | ||
4636 | |||
4637 | pci_set_power_state(pdev, PCI_D0); | ||
4638 | pci_restore_state(pdev); | ||
4639 | pci_enable_wake(pdev, PCI_D0, 0); | ||
4640 | |||
4641 | rc = nv_open(dev); | ||
4642 | out: | ||
4643 | return rc; | ||
4644 | } | ||
4645 | #else | ||
4646 | #define nv_suspend NULL | ||
4647 | #define nv_resume NULL | ||
4648 | #endif /* CONFIG_PM */ | ||
4649 | |||
4606 | static struct pci_device_id pci_tbl[] = { | 4650 | static struct pci_device_id pci_tbl[] = { |
4607 | { /* nForce Ethernet Controller */ | 4651 | { /* nForce Ethernet Controller */ |
4608 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_1), | 4652 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_1), |
@@ -4704,9 +4748,10 @@ static struct pci_driver driver = { | |||
4704 | .id_table = pci_tbl, | 4748 | .id_table = pci_tbl, |
4705 | .probe = nv_probe, | 4749 | .probe = nv_probe, |
4706 | .remove = __devexit_p(nv_remove), | 4750 | .remove = __devexit_p(nv_remove), |
4751 | .suspend = nv_suspend, | ||
4752 | .resume = nv_resume, | ||
4707 | }; | 4753 | }; |
4708 | 4754 | ||
4709 | |||
4710 | static int __init init_nic(void) | 4755 | static int __init init_nic(void) |
4711 | { | 4756 | { |
4712 | printk(KERN_INFO "forcedeth.c: Reverse Engineered nForce ethernet driver. Version %s.\n", FORCEDETH_VERSION); | 4757 | printk(KERN_INFO "forcedeth.c: Reverse Engineered nForce ethernet driver. Version %s.\n", FORCEDETH_VERSION); |