aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Vorontsov <avorontsov@ru.mvista.com>2009-09-30 23:11:11 -0400
committerDavid S. Miller <davem@davemloft.net>2009-09-30 23:11:11 -0400
commit7bfc4ab5620d8169d2effc0dbb644f207f75a9e3 (patch)
tree1403872368215e18d82a9d304f832e8d5df722bb
parenta55c0a0ed41533b3a7b32a6c8acdc1bb04a017b5 (diff)
3c59x: Rework suspend and resume
As noticed by Alan Stern, there is still one issue with the driver: we disable PCI IRQ on suspend, but other devices on the same IRQ line might still need the IRQ enabled to suspend properly. Nowadays, PCI core handles all power management work by itself, with one condition though: if we use dev_pm_ops. So, rework the driver to only quiesce 3c59x internal logic on suspend, while PCI core will manage PCI device power state with IRQs disabled. Suggested-by: Rafael J. Wysocki <rjw@sisk.pl> Suggested-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Acked-by: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/3c59x.c77
1 files changed, 38 insertions, 39 deletions
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index b9eeadf01b74..975e25b19ebe 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -805,52 +805,54 @@ static void poll_vortex(struct net_device *dev)
805 805
806#ifdef CONFIG_PM 806#ifdef CONFIG_PM
807 807
808static int vortex_suspend(struct pci_dev *pdev, pm_message_t state) 808static int vortex_suspend(struct device *dev)
809{ 809{
810 struct net_device *dev = pci_get_drvdata(pdev); 810 struct pci_dev *pdev = to_pci_dev(dev);
811 struct net_device *ndev = pci_get_drvdata(pdev);
812
813 if (!ndev || !netif_running(ndev))
814 return 0;
815
816 netif_device_detach(ndev);
817 vortex_down(ndev, 1);
811 818
812 if (dev && netdev_priv(dev)) {
813 if (netif_running(dev)) {
814 netif_device_detach(dev);
815 vortex_down(dev, 1);
816 disable_irq(dev->irq);
817 }
818 pci_save_state(pdev);
819 pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
820 pci_disable_device(pdev);
821 pci_set_power_state(pdev, pci_choose_state(pdev, state));
822 }
823 return 0; 819 return 0;
824} 820}
825 821
826static int vortex_resume(struct pci_dev *pdev) 822static int vortex_resume(struct device *dev)
827{ 823{
828 struct net_device *dev = pci_get_drvdata(pdev); 824 struct pci_dev *pdev = to_pci_dev(dev);
829 struct vortex_private *vp = netdev_priv(dev); 825 struct net_device *ndev = pci_get_drvdata(pdev);
830 int err; 826 int err;
831 827
832 if (dev && vp) { 828 if (!ndev || !netif_running(ndev))
833 pci_set_power_state(pdev, PCI_D0); 829 return 0;
834 pci_restore_state(pdev); 830
835 err = pci_enable_device(pdev); 831 err = vortex_up(ndev);
836 if (err) { 832 if (err)
837 pr_warning("%s: Could not enable device\n", 833 return err;
838 dev->name); 834
839 return err; 835 netif_device_attach(ndev);
840 } 836
841 pci_set_master(pdev);
842 if (netif_running(dev)) {
843 err = vortex_up(dev);
844 if (err)
845 return err;
846 enable_irq(dev->irq);
847 netif_device_attach(dev);
848 }
849 }
850 return 0; 837 return 0;
851} 838}
852 839
853#endif /* CONFIG_PM */ 840static struct dev_pm_ops vortex_pm_ops = {
841 .suspend = vortex_suspend,
842 .resume = vortex_resume,
843 .freeze = vortex_suspend,
844 .thaw = vortex_resume,
845 .poweroff = vortex_suspend,
846 .restore = vortex_resume,
847};
848
849#define VORTEX_PM_OPS (&vortex_pm_ops)
850
851#else /* !CONFIG_PM */
852
853#define VORTEX_PM_OPS NULL
854
855#endif /* !CONFIG_PM */
854 856
855#ifdef CONFIG_EISA 857#ifdef CONFIG_EISA
856static struct eisa_device_id vortex_eisa_ids[] = { 858static struct eisa_device_id vortex_eisa_ids[] = {
@@ -3199,10 +3201,7 @@ static struct pci_driver vortex_driver = {
3199 .probe = vortex_init_one, 3201 .probe = vortex_init_one,
3200 .remove = __devexit_p(vortex_remove_one), 3202 .remove = __devexit_p(vortex_remove_one),
3201 .id_table = vortex_pci_tbl, 3203 .id_table = vortex_pci_tbl,
3202#ifdef CONFIG_PM 3204 .driver.pm = VORTEX_PM_OPS,
3203 .suspend = vortex_suspend,
3204 .resume = vortex_resume,
3205#endif
3206}; 3205};
3207 3206
3208 3207