aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Kilroy <kilroyd@googlemail.com>2009-06-18 18:21:30 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-10 15:01:46 -0400
commit6415f7df10573bf1ec42644f42bef565127114a1 (patch)
tree6aa981f181010faca22989ffd70ef89b0d32ff07 /drivers
parentef96b5c9ed6ba4b45fd4cf45810c34978bb8d8bb (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.c33
-rw-r--r--drivers/net/wireless/orinoco/main.c61
-rw-r--r--drivers/net/wireless/orinoco/orinoco.h5
-rw-r--r--drivers/net/wireless/orinoco/orinoco_cs.c44
-rw-r--r--drivers/net/wireless/orinoco/orinoco_pci.h47
-rw-r--r--drivers/net/wireless/orinoco/spectrum_cs.c41
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
114static int 87static 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
213static void __orinoco_set_multicast_list(struct net_device *dev); 213static void __orinoco_set_multicast_list(struct net_device *dev);
214static int __orinoco_up(struct orinoco_private *priv);
215static 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
1517int __orinoco_up(struct orinoco_private *priv) 1519static 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}
1545EXPORT_SYMBOL(__orinoco_up);
1546 1547
1547int __orinoco_down(struct orinoco_private *priv) 1548static 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}
1577EXPORT_SYMBOL(__orinoco_down);
1578 1578
1579int orinoco_reinit_firmware(struct orinoco_private *priv) 1579static 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}
1595EXPORT_SYMBOL(orinoco_reinit_firmware);
1596 1595
1597int __orinoco_program_rids(struct net_device *dev) 1596int __orinoco_program_rids(struct net_device *dev)
1598{ 1597{
@@ -2389,6 +2388,56 @@ void free_orinocodev(struct orinoco_private *priv)
2389} 2388}
2390EXPORT_SYMBOL(free_orinocodev); 2389EXPORT_SYMBOL(free_orinocodev);
2391 2390
2391int 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
2416exit:
2417 spin_unlock_irqrestore(&priv->lock, flags);
2418
2419 return 0;
2420}
2421EXPORT_SYMBOL(orinoco_up);
2422
2423void 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}
2439EXPORT_SYMBOL(orinoco_down);
2440
2392static void orinoco_get_drvinfo(struct net_device *dev, 2441static 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);
199extern void orinoco_if_del(struct orinoco_private *priv); 199extern void orinoco_if_del(struct orinoco_private *priv);
200extern int __orinoco_up(struct orinoco_private *priv); 200extern int orinoco_up(struct orinoco_private *priv);
201extern int __orinoco_down(struct orinoco_private *priv); 201extern void orinoco_down(struct orinoco_private *priv);
202extern int orinoco_reinit_firmware(struct orinoco_private *priv);
203extern irqreturn_t orinoco_interrupt(int irq, void *dev_id); 202extern 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 {
22static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state) 22static 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
421spectrum_cs_suspend(struct pcmcia_device *link) 421spectrum_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
445spectrum_cs_resume(struct pcmcia_device *link) 433spectrum_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