Commit | Line | Data |
---|---|---|
b884c872 PR |
1 | /* orinoco_pci.h |
2 | * | |
3 | * Common code for all Orinoco drivers for PCI devices, including | |
4 | * both native PCI and PCMCIA-to-PCI bridges. | |
5 | * | |
6 | * Copyright (C) 2005, Pavel Roskin. | |
7 | * See orinoco.c for license. | |
8 | */ | |
9 | ||
10 | #ifndef _ORINOCO_PCI_H | |
11 | #define _ORINOCO_PCI_H | |
12 | ||
13 | #include <linux/netdevice.h> | |
14 | ||
15 | /* Driver specific data */ | |
16 | struct orinoco_pci_card { | |
17 | void __iomem *bridge_io; | |
18 | void __iomem *attr_io; | |
19 | }; | |
20 | ||
95047dd6 | 21 | #ifdef CONFIG_PM |
b884c872 PR |
22 | static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state) |
23 | { | |
24 | struct net_device *dev = pci_get_drvdata(pdev); | |
25 | struct orinoco_private *priv = netdev_priv(dev); | |
26 | unsigned long flags; | |
27 | int err; | |
28 | ||
29 | err = orinoco_lock(priv, &flags); | |
30 | if (err) { | |
31 | printk(KERN_ERR "%s: cannot lock hardware for suspend\n", | |
32 | dev->name); | |
33 | return err; | |
34 | } | |
35 | ||
36 | err = __orinoco_down(dev); | |
37 | if (err) | |
38 | printk(KERN_WARNING "%s: error %d bringing interface down " | |
39 | "for suspend\n", dev->name, err); | |
40 | ||
41 | netif_device_detach(dev); | |
42 | ||
43 | priv->hw_unavailable++; | |
44 | ||
45 | orinoco_unlock(priv, &flags); | |
46 | ||
47 | free_irq(pdev->irq, dev); | |
48 | pci_save_state(pdev); | |
49 | pci_disable_device(pdev); | |
50 | pci_set_power_state(pdev, PCI_D3hot); | |
51 | ||
52 | return 0; | |
53 | } | |
54 | ||
55 | static int orinoco_pci_resume(struct pci_dev *pdev) | |
56 | { | |
57 | struct net_device *dev = pci_get_drvdata(pdev); | |
58 | struct orinoco_private *priv = netdev_priv(dev); | |
59 | unsigned long flags; | |
60 | int err; | |
61 | ||
62 | pci_set_power_state(pdev, 0); | |
02e0e5e9 JL |
63 | err = pci_enable_device(pdev); |
64 | if (err) { | |
65 | printk(KERN_ERR "%s: pci_enable_device failed on resume\n", | |
66 | dev->name); | |
67 | return err; | |
68 | } | |
b884c872 PR |
69 | pci_restore_state(pdev); |
70 | ||
1fb9df5d | 71 | err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED, |
b884c872 PR |
72 | dev->name, dev); |
73 | if (err) { | |
74 | printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n", | |
75 | dev->name); | |
76 | pci_disable_device(pdev); | |
77 | return -EBUSY; | |
78 | } | |
79 | ||
80 | err = orinoco_reinit_firmware(dev); | |
81 | if (err) { | |
82 | printk(KERN_ERR "%s: error %d re-initializing firmware " | |
83 | "on resume\n", dev->name, err); | |
84 | return err; | |
85 | } | |
86 | ||
87 | spin_lock_irqsave(&priv->lock, flags); | |
88 | ||
89 | netif_device_attach(dev); | |
90 | ||
91 | priv->hw_unavailable--; | |
92 | ||
93 | if (priv->open && (! priv->hw_unavailable)) { | |
94 | err = __orinoco_up(dev); | |
95 | if (err) | |
96 | printk(KERN_ERR "%s: Error %d restarting card on resume\n", | |
97 | dev->name, err); | |
98 | } | |
99 | ||
100 | spin_unlock_irqrestore(&priv->lock, flags); | |
101 | ||
102 | return 0; | |
103 | } | |
95047dd6 PR |
104 | #else |
105 | #define orinoco_pci_suspend NULL | |
106 | #define orinoco_pci_resume NULL | |
107 | #endif | |
b884c872 PR |
108 | |
109 | #endif /* _ORINOCO_PCI_H */ |