diff options
Diffstat (limited to 'drivers/net/wireless/orinoco_tmd.c')
-rw-r--r-- | drivers/net/wireless/orinoco_tmd.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/net/wireless/orinoco_tmd.c b/drivers/net/wireless/orinoco_tmd.c index 5e68b7026186..b74807d4141f 100644 --- a/drivers/net/wireless/orinoco_tmd.c +++ b/drivers/net/wireless/orinoco_tmd.c | |||
@@ -215,6 +215,83 @@ static void __devexit orinoco_tmd_remove_one(struct pci_dev *pdev) | |||
215 | pci_disable_device(pdev); | 215 | pci_disable_device(pdev); |
216 | } | 216 | } |
217 | 217 | ||
218 | static int orinoco_tmd_suspend(struct pci_dev *pdev, pm_message_t state) | ||
219 | { | ||
220 | struct net_device *dev = pci_get_drvdata(pdev); | ||
221 | struct orinoco_private *priv = netdev_priv(dev); | ||
222 | unsigned long flags; | ||
223 | int err; | ||
224 | |||
225 | err = orinoco_lock(priv, &flags); | ||
226 | if (err) { | ||
227 | printk(KERN_ERR "%s: cannot lock hardware for suspend\n", | ||
228 | dev->name); | ||
229 | return err; | ||
230 | } | ||
231 | |||
232 | err = __orinoco_down(dev); | ||
233 | if (err) | ||
234 | printk(KERN_WARNING "%s: error %d bringing interface down " | ||
235 | "for suspend\n", dev->name, err); | ||
236 | |||
237 | netif_device_detach(dev); | ||
238 | |||
239 | priv->hw_unavailable++; | ||
240 | |||
241 | orinoco_unlock(priv, &flags); | ||
242 | |||
243 | free_irq(pdev->irq, dev); | ||
244 | pci_save_state(pdev); | ||
245 | pci_disable_device(pdev); | ||
246 | pci_set_power_state(pdev, PCI_D3hot); | ||
247 | |||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | static int orinoco_tmd_resume(struct pci_dev *pdev) | ||
252 | { | ||
253 | struct net_device *dev = pci_get_drvdata(pdev); | ||
254 | struct orinoco_private *priv = netdev_priv(dev); | ||
255 | unsigned long flags; | ||
256 | int err; | ||
257 | |||
258 | pci_set_power_state(pdev, 0); | ||
259 | pci_enable_device(pdev); | ||
260 | pci_restore_state(pdev); | ||
261 | |||
262 | err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, | ||
263 | dev->name, dev); | ||
264 | if (err) { | ||
265 | printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n", | ||
266 | dev->name); | ||
267 | pci_disable_device(pdev); | ||
268 | return -EBUSY; | ||
269 | } | ||
270 | |||
271 | err = orinoco_reinit_firmware(dev); | ||
272 | if (err) { | ||
273 | printk(KERN_ERR "%s: error %d re-initializing firmware " | ||
274 | "on resume\n", dev->name, err); | ||
275 | return err; | ||
276 | } | ||
277 | |||
278 | spin_lock_irqsave(&priv->lock, flags); | ||
279 | |||
280 | netif_device_attach(dev); | ||
281 | |||
282 | priv->hw_unavailable--; | ||
283 | |||
284 | if (priv->open && (! priv->hw_unavailable)) { | ||
285 | err = __orinoco_up(dev); | ||
286 | if (err) | ||
287 | printk(KERN_ERR "%s: Error %d restarting card on resume\n", | ||
288 | dev->name, err); | ||
289 | } | ||
290 | |||
291 | spin_unlock_irqrestore(&priv->lock, flags); | ||
292 | |||
293 | return 0; | ||
294 | } | ||
218 | 295 | ||
219 | static struct pci_device_id orinoco_tmd_pci_id_table[] = { | 296 | static struct pci_device_id orinoco_tmd_pci_id_table[] = { |
220 | {0x15e8, 0x0131, PCI_ANY_ID, PCI_ANY_ID,}, /* NDC and OEMs, e.g. pheecom */ | 297 | {0x15e8, 0x0131, PCI_ANY_ID, PCI_ANY_ID,}, /* NDC and OEMs, e.g. pheecom */ |
@@ -228,6 +305,8 @@ static struct pci_driver orinoco_tmd_driver = { | |||
228 | .id_table = orinoco_tmd_pci_id_table, | 305 | .id_table = orinoco_tmd_pci_id_table, |
229 | .probe = orinoco_tmd_init_one, | 306 | .probe = orinoco_tmd_init_one, |
230 | .remove = __devexit_p(orinoco_tmd_remove_one), | 307 | .remove = __devexit_p(orinoco_tmd_remove_one), |
308 | .suspend = orinoco_tmd_suspend, | ||
309 | .resume = orinoco_tmd_resume, | ||
231 | }; | 310 | }; |
232 | 311 | ||
233 | static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION | 312 | static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION |