diff options
author | David Kilroy <kilroyd@googlemail.com> | 2009-06-18 18:21:30 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-07-10 15:01:46 -0400 |
commit | 6415f7df10573bf1ec42644f42bef565127114a1 (patch) | |
tree | 6aa981f181010faca22989ffd70ef89b0d32ff07 /drivers | |
parent | ef96b5c9ed6ba4b45fd4cf45810c34978bb8d8bb (diff) |
orinoco: Handle suspend/restore in core driver
Each device does almost exactly the same things on suspend and resume
when upping and downing the interface. So move this logic into a common
routine.
Signed-off-by: David Kilroy <kilroyd@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/orinoco/airport.c | 33 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/main.c | 61 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/orinoco.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/orinoco_cs.c | 44 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/orinoco_pci.h | 47 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/spectrum_cs.c | 41 |
6 files changed, 70 insertions, 161 deletions
diff --git a/drivers/net/wireless/orinoco/airport.c b/drivers/net/wireless/orinoco/airport.c index 70f1331512bd..c60df2c1aca3 100644 --- a/drivers/net/wireless/orinoco/airport.c +++ b/drivers/net/wireless/orinoco/airport.c | |||
@@ -50,15 +50,7 @@ airport_suspend(struct macio_dev *mdev, pm_message_t state) | |||
50 | return 0; | 50 | return 0; |
51 | } | 51 | } |
52 | 52 | ||
53 | err = __orinoco_down(priv); | 53 | orinoco_down(priv); |
54 | if (err) | ||
55 | printk(KERN_WARNING "%s: PBOOK_SLEEP_NOW: Error %d downing interface\n", | ||
56 | dev->name, err); | ||
57 | |||
58 | netif_device_detach(dev); | ||
59 | |||
60 | priv->hw_unavailable++; | ||
61 | |||
62 | orinoco_unlock(priv, &flags); | 54 | orinoco_unlock(priv, &flags); |
63 | 55 | ||
64 | disable_irq(card->irq); | 56 | disable_irq(card->irq); |
@@ -85,30 +77,11 @@ airport_resume(struct macio_dev *mdev) | |||
85 | 77 | ||
86 | enable_irq(card->irq); | 78 | enable_irq(card->irq); |
87 | 79 | ||
88 | err = orinoco_reinit_firmware(priv); | ||
89 | if (err) { | ||
90 | printk(KERN_ERR "%s: Error %d re-initializing firmware on PBOOK_WAKE\n", | ||
91 | dev->name, err); | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | spin_lock_irqsave(&priv->lock, flags); | 80 | spin_lock_irqsave(&priv->lock, flags); |
96 | 81 | err = orinoco_up(priv); | |
97 | netif_device_attach(dev); | ||
98 | |||
99 | priv->hw_unavailable--; | ||
100 | |||
101 | if (priv->open && (!priv->hw_unavailable)) { | ||
102 | err = __orinoco_up(priv); | ||
103 | if (err) | ||
104 | printk(KERN_ERR "%s: Error %d restarting card on PBOOK_WAKE\n", | ||
105 | dev->name, err); | ||
106 | } | ||
107 | |||
108 | |||
109 | spin_unlock_irqrestore(&priv->lock, flags); | 82 | spin_unlock_irqrestore(&priv->lock, flags); |
110 | 83 | ||
111 | return 0; | 84 | return err; |
112 | } | 85 | } |
113 | 86 | ||
114 | static int | 87 | static int |
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index 361cf09d6b70..0727b41a397e 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c | |||
@@ -211,6 +211,8 @@ struct orinoco_rx_data { | |||
211 | /********************************************************************/ | 211 | /********************************************************************/ |
212 | 212 | ||
213 | static void __orinoco_set_multicast_list(struct net_device *dev); | 213 | static void __orinoco_set_multicast_list(struct net_device *dev); |
214 | static int __orinoco_up(struct orinoco_private *priv); | ||
215 | static int __orinoco_down(struct orinoco_private *priv); | ||
214 | 216 | ||
215 | /********************************************************************/ | 217 | /********************************************************************/ |
216 | /* Internal helper functions */ | 218 | /* Internal helper functions */ |
@@ -1514,7 +1516,7 @@ static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw) | |||
1514 | /* Internal hardware control routines */ | 1516 | /* Internal hardware control routines */ |
1515 | /********************************************************************/ | 1517 | /********************************************************************/ |
1516 | 1518 | ||
1517 | int __orinoco_up(struct orinoco_private *priv) | 1519 | static int __orinoco_up(struct orinoco_private *priv) |
1518 | { | 1520 | { |
1519 | struct net_device *dev = priv->ndev; | 1521 | struct net_device *dev = priv->ndev; |
1520 | struct hermes *hw = &priv->hw; | 1522 | struct hermes *hw = &priv->hw; |
@@ -1542,9 +1544,8 @@ int __orinoco_up(struct orinoco_private *priv) | |||
1542 | 1544 | ||
1543 | return 0; | 1545 | return 0; |
1544 | } | 1546 | } |
1545 | EXPORT_SYMBOL(__orinoco_up); | ||
1546 | 1547 | ||
1547 | int __orinoco_down(struct orinoco_private *priv) | 1548 | static int __orinoco_down(struct orinoco_private *priv) |
1548 | { | 1549 | { |
1549 | struct net_device *dev = priv->ndev; | 1550 | struct net_device *dev = priv->ndev; |
1550 | struct hermes *hw = &priv->hw; | 1551 | struct hermes *hw = &priv->hw; |
@@ -1574,9 +1575,8 @@ int __orinoco_down(struct orinoco_private *priv) | |||
1574 | 1575 | ||
1575 | return 0; | 1576 | return 0; |
1576 | } | 1577 | } |
1577 | EXPORT_SYMBOL(__orinoco_down); | ||
1578 | 1578 | ||
1579 | int orinoco_reinit_firmware(struct orinoco_private *priv) | 1579 | static int orinoco_reinit_firmware(struct orinoco_private *priv) |
1580 | { | 1580 | { |
1581 | struct hermes *hw = &priv->hw; | 1581 | struct hermes *hw = &priv->hw; |
1582 | int err; | 1582 | int err; |
@@ -1592,7 +1592,6 @@ int orinoco_reinit_firmware(struct orinoco_private *priv) | |||
1592 | 1592 | ||
1593 | return err; | 1593 | return err; |
1594 | } | 1594 | } |
1595 | EXPORT_SYMBOL(orinoco_reinit_firmware); | ||
1596 | 1595 | ||
1597 | int __orinoco_program_rids(struct net_device *dev) | 1596 | int __orinoco_program_rids(struct net_device *dev) |
1598 | { | 1597 | { |
@@ -2389,6 +2388,56 @@ void free_orinocodev(struct orinoco_private *priv) | |||
2389 | } | 2388 | } |
2390 | EXPORT_SYMBOL(free_orinocodev); | 2389 | EXPORT_SYMBOL(free_orinocodev); |
2391 | 2390 | ||
2391 | int orinoco_up(struct orinoco_private *priv) | ||
2392 | { | ||
2393 | struct net_device *dev = priv->ndev; | ||
2394 | unsigned long flags; | ||
2395 | int err; | ||
2396 | |||
2397 | spin_lock_irqsave(&priv->lock, flags); | ||
2398 | |||
2399 | err = orinoco_reinit_firmware(priv); | ||
2400 | if (err) { | ||
2401 | printk(KERN_ERR "%s: Error %d re-initializing firmware\n", | ||
2402 | dev->name, err); | ||
2403 | goto exit; | ||
2404 | } | ||
2405 | |||
2406 | netif_device_attach(dev); | ||
2407 | priv->hw_unavailable--; | ||
2408 | |||
2409 | if (priv->open && !priv->hw_unavailable) { | ||
2410 | err = __orinoco_up(priv); | ||
2411 | if (err) | ||
2412 | printk(KERN_ERR "%s: Error %d restarting card\n", | ||
2413 | dev->name, err); | ||
2414 | } | ||
2415 | |||
2416 | exit: | ||
2417 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2418 | |||
2419 | return 0; | ||
2420 | } | ||
2421 | EXPORT_SYMBOL(orinoco_up); | ||
2422 | |||
2423 | void orinoco_down(struct orinoco_private *priv) | ||
2424 | { | ||
2425 | struct net_device *dev = priv->ndev; | ||
2426 | unsigned long flags; | ||
2427 | int err; | ||
2428 | |||
2429 | spin_lock_irqsave(&priv->lock, flags); | ||
2430 | err = __orinoco_down(priv); | ||
2431 | if (err) | ||
2432 | printk(KERN_WARNING "%s: Error %d downing interface\n", | ||
2433 | dev->name, err); | ||
2434 | |||
2435 | netif_device_detach(dev); | ||
2436 | priv->hw_unavailable++; | ||
2437 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2438 | } | ||
2439 | EXPORT_SYMBOL(orinoco_down); | ||
2440 | |||
2392 | static void orinoco_get_drvinfo(struct net_device *dev, | 2441 | static void orinoco_get_drvinfo(struct net_device *dev, |
2393 | struct ethtool_drvinfo *info) | 2442 | struct ethtool_drvinfo *info) |
2394 | { | 2443 | { |
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h index 45aa616eb664..4ee85f8f6bc7 100644 --- a/drivers/net/wireless/orinoco/orinoco.h +++ b/drivers/net/wireless/orinoco/orinoco.h | |||
@@ -197,9 +197,8 @@ extern int orinoco_if_add(struct orinoco_private *priv, | |||
197 | unsigned long base_addr, | 197 | unsigned long base_addr, |
198 | unsigned int irq); | 198 | unsigned int irq); |
199 | extern void orinoco_if_del(struct orinoco_private *priv); | 199 | extern void orinoco_if_del(struct orinoco_private *priv); |
200 | extern int __orinoco_up(struct orinoco_private *priv); | 200 | extern int orinoco_up(struct orinoco_private *priv); |
201 | extern int __orinoco_down(struct orinoco_private *priv); | 201 | extern void orinoco_down(struct orinoco_private *priv); |
202 | extern int orinoco_reinit_firmware(struct orinoco_private *priv); | ||
203 | extern irqreturn_t orinoco_interrupt(int irq, void *dev_id); | 202 | extern irqreturn_t orinoco_interrupt(int irq, void *dev_id); |
204 | 203 | ||
205 | /********************************************************************/ | 204 | /********************************************************************/ |
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index 4c29d3689251..38c1c9d2abb8 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c | |||
@@ -349,26 +349,12 @@ static int orinoco_cs_suspend(struct pcmcia_device *link) | |||
349 | { | 349 | { |
350 | struct orinoco_private *priv = link->priv; | 350 | struct orinoco_private *priv = link->priv; |
351 | struct orinoco_pccard *card = priv->card; | 351 | struct orinoco_pccard *card = priv->card; |
352 | struct net_device *dev = priv->ndev; | ||
353 | int err = 0; | ||
354 | unsigned long flags; | ||
355 | 352 | ||
356 | /* This is probably racy, but I can't think of | 353 | /* This is probably racy, but I can't think of |
357 | a better way, short of rewriting the PCMCIA | 354 | a better way, short of rewriting the PCMCIA |
358 | layer to not suck :-( */ | 355 | layer to not suck :-( */ |
359 | if (!test_bit(0, &card->hard_reset_in_progress)) { | 356 | if (!test_bit(0, &card->hard_reset_in_progress)) |
360 | spin_lock_irqsave(&priv->lock, flags); | 357 | orinoco_down(priv); |
361 | |||
362 | err = __orinoco_down(priv); | ||
363 | if (err) | ||
364 | printk(KERN_WARNING "%s: Error %d downing interface\n", | ||
365 | dev->name, err); | ||
366 | |||
367 | netif_device_detach(dev); | ||
368 | priv->hw_unavailable++; | ||
369 | |||
370 | spin_unlock_irqrestore(&priv->lock, flags); | ||
371 | } | ||
372 | 358 | ||
373 | return 0; | 359 | return 0; |
374 | } | 360 | } |
@@ -377,32 +363,10 @@ static int orinoco_cs_resume(struct pcmcia_device *link) | |||
377 | { | 363 | { |
378 | struct orinoco_private *priv = link->priv; | 364 | struct orinoco_private *priv = link->priv; |
379 | struct orinoco_pccard *card = priv->card; | 365 | struct orinoco_pccard *card = priv->card; |
380 | struct net_device *dev = priv->ndev; | ||
381 | int err = 0; | 366 | int err = 0; |
382 | unsigned long flags; | ||
383 | 367 | ||
384 | if (!test_bit(0, &card->hard_reset_in_progress)) { | 368 | if (!test_bit(0, &card->hard_reset_in_progress)) |
385 | err = orinoco_reinit_firmware(priv); | 369 | err = orinoco_up(priv); |
386 | if (err) { | ||
387 | printk(KERN_ERR "%s: Error %d re-initializing firmware\n", | ||
388 | dev->name, err); | ||
389 | return -EIO; | ||
390 | } | ||
391 | |||
392 | spin_lock_irqsave(&priv->lock, flags); | ||
393 | |||
394 | netif_device_attach(dev); | ||
395 | priv->hw_unavailable--; | ||
396 | |||
397 | if (priv->open && !priv->hw_unavailable) { | ||
398 | err = __orinoco_up(priv); | ||
399 | if (err) | ||
400 | printk(KERN_ERR "%s: Error %d restarting card\n", | ||
401 | dev->name, err); | ||
402 | } | ||
403 | |||
404 | spin_unlock_irqrestore(&priv->lock, flags); | ||
405 | } | ||
406 | 370 | ||
407 | return err; | 371 | return err; |
408 | } | 372 | } |
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.h b/drivers/net/wireless/orinoco/orinoco_pci.h index 22aa630027e0..ea7231af40a8 100644 --- a/drivers/net/wireless/orinoco/orinoco_pci.h +++ b/drivers/net/wireless/orinoco/orinoco_pci.h | |||
@@ -22,28 +22,8 @@ struct orinoco_pci_card { | |||
22 | static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state) | 22 | static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state) |
23 | { | 23 | { |
24 | struct orinoco_private *priv = pci_get_drvdata(pdev); | 24 | struct orinoco_private *priv = pci_get_drvdata(pdev); |
25 | struct net_device *dev = priv->ndev; | ||
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(priv); | ||
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 | 25 | ||
26 | orinoco_down(priv); | ||
47 | free_irq(pdev->irq, priv); | 27 | free_irq(pdev->irq, priv); |
48 | pci_save_state(pdev); | 28 | pci_save_state(pdev); |
49 | pci_disable_device(pdev); | 29 | pci_disable_device(pdev); |
@@ -56,7 +36,6 @@ static int orinoco_pci_resume(struct pci_dev *pdev) | |||
56 | { | 36 | { |
57 | struct orinoco_private *priv = pci_get_drvdata(pdev); | 37 | struct orinoco_private *priv = pci_get_drvdata(pdev); |
58 | struct net_device *dev = priv->ndev; | 38 | struct net_device *dev = priv->ndev; |
59 | unsigned long flags; | ||
60 | int err; | 39 | int err; |
61 | 40 | ||
62 | pci_set_power_state(pdev, 0); | 41 | pci_set_power_state(pdev, 0); |
@@ -77,29 +56,9 @@ static int orinoco_pci_resume(struct pci_dev *pdev) | |||
77 | return -EBUSY; | 56 | return -EBUSY; |
78 | } | 57 | } |
79 | 58 | ||
80 | err = orinoco_reinit_firmware(priv); | 59 | err = orinoco_up(priv); |
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 | 60 | ||
91 | priv->hw_unavailable--; | 61 | return err; |
92 | |||
93 | if (priv->open && (!priv->hw_unavailable)) { | ||
94 | err = __orinoco_up(priv); | ||
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 | } | 62 | } |
104 | #else | 63 | #else |
105 | #define orinoco_pci_suspend NULL | 64 | #define orinoco_pci_suspend NULL |
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c index 7b4a7e428355..c361310b885d 100644 --- a/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/drivers/net/wireless/orinoco/spectrum_cs.c | |||
@@ -421,22 +421,10 @@ static int | |||
421 | spectrum_cs_suspend(struct pcmcia_device *link) | 421 | spectrum_cs_suspend(struct pcmcia_device *link) |
422 | { | 422 | { |
423 | struct orinoco_private *priv = link->priv; | 423 | struct orinoco_private *priv = link->priv; |
424 | struct net_device *dev = priv->ndev; | ||
425 | unsigned long flags; | ||
426 | int err = 0; | 424 | int err = 0; |
427 | 425 | ||
428 | /* Mark the device as stopped, to block IO until later */ | 426 | /* Mark the device as stopped, to block IO until later */ |
429 | spin_lock_irqsave(&priv->lock, flags); | 427 | orinoco_down(priv); |
430 | |||
431 | err = __orinoco_down(priv); | ||
432 | if (err) | ||
433 | printk(KERN_WARNING "%s: Error %d downing interface\n", | ||
434 | dev->name, err); | ||
435 | |||
436 | netif_device_detach(dev); | ||
437 | priv->hw_unavailable++; | ||
438 | |||
439 | spin_unlock_irqrestore(&priv->lock, flags); | ||
440 | 428 | ||
441 | return err; | 429 | return err; |
442 | } | 430 | } |
@@ -445,32 +433,9 @@ static int | |||
445 | spectrum_cs_resume(struct pcmcia_device *link) | 433 | spectrum_cs_resume(struct pcmcia_device *link) |
446 | { | 434 | { |
447 | struct orinoco_private *priv = link->priv; | 435 | struct orinoco_private *priv = link->priv; |
448 | struct net_device *dev = priv->ndev; | 436 | int err = orinoco_up(priv); |
449 | unsigned long flags; | ||
450 | int err; | ||
451 | |||
452 | err = orinoco_reinit_firmware(priv); | ||
453 | if (err) { | ||
454 | printk(KERN_ERR "%s: Error %d re-initializing firmware\n", | ||
455 | dev->name, err); | ||
456 | return -EIO; | ||
457 | } | ||
458 | 437 | ||
459 | spin_lock_irqsave(&priv->lock, flags); | 438 | return err; |
460 | |||
461 | netif_device_attach(dev); | ||
462 | priv->hw_unavailable--; | ||
463 | |||
464 | if (priv->open && !priv->hw_unavailable) { | ||
465 | err = __orinoco_up(priv); | ||
466 | if (err) | ||
467 | printk(KERN_ERR "%s: Error %d restarting card\n", | ||
468 | dev->name, err); | ||
469 | } | ||
470 | |||
471 | spin_unlock_irqrestore(&priv->lock, flags); | ||
472 | |||
473 | return 0; | ||
474 | } | 439 | } |
475 | 440 | ||
476 | 441 | ||