diff options
author | Pavel Roskin <proski@gnu.org> | 2006-04-07 04:10:55 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2006-04-24 16:15:52 -0400 |
commit | c6fb2e9abef894efc4870e4c1e3aa4365b830a11 (patch) | |
tree | ab262b6f480665fa6ea5b9bdc2a6d6383b0dc2f2 | |
parent | 3d529962217c3fec36f53f270a37e132b9763c65 (diff) | |
download | blackbird-op-linux-c6fb2e9abef894efc4870e4c1e3aa4365b830a11.tar.gz blackbird-op-linux-c6fb2e9abef894efc4870e4c1e3aa4365b830a11.zip |
[PATCH] orinoco: support PCI suspend/resume for Nortel, PLX and TMD adaptors
Copy PCI suspend/resume functions from orinoco_pci.c.
Signed-off-by: Pavel Roskin <proski@gnu.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/orinoco_nortel.c | 87 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco_plx.c | 79 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco_tmd.c | 79 |
3 files changed, 241 insertions, 4 deletions
diff --git a/drivers/net/wireless/orinoco_nortel.c b/drivers/net/wireless/orinoco_nortel.c index d1a670b35338..3fff013f6788 100644 --- a/drivers/net/wireless/orinoco_nortel.c +++ b/drivers/net/wireless/orinoco_nortel.c @@ -263,6 +263,83 @@ static void __devexit nortel_pci_remove_one(struct pci_dev *pdev) pci_disable_device(pdev); } +static int orinoco_nortel_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct orinoco_private *priv = netdev_priv(dev); + unsigned long flags; + int err; + + err = orinoco_lock(priv, &flags); + if (err) { + printk(KERN_ERR "%s: cannot lock hardware for suspend\n", + dev->name); + return err; + } + + err = __orinoco_down(dev); + if (err) + printk(KERN_WARNING "%s: error %d bringing interface down " + "for suspend\n", dev->name, err); + + netif_device_detach(dev); + + priv->hw_unavailable++; + + orinoco_unlock(priv, &flags); + + free_irq(pdev->irq, dev); + pci_save_state(pdev); + pci_disable_device(pdev); + pci_set_power_state(pdev, PCI_D3hot); + + return 0; +} + +static int orinoco_nortel_resume(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct orinoco_private *priv = netdev_priv(dev); + unsigned long flags; + int err; + + pci_set_power_state(pdev, 0); + pci_enable_device(pdev); + pci_restore_state(pdev); + + err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, + dev->name, dev); + if (err) { + printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n", + dev->name); + pci_disable_device(pdev); + return -EBUSY; + } + + err = orinoco_reinit_firmware(dev); + if (err) { + printk(KERN_ERR "%s: error %d re-initializing firmware " + "on resume\n", dev->name, err); + return err; + } + + spin_lock_irqsave(&priv->lock, flags); + + netif_device_attach(dev); + + priv->hw_unavailable--; + + if (priv->open && (! priv->hw_unavailable)) { + err = __orinoco_up(dev); + if (err) + printk(KERN_ERR "%s: Error %d restarting card on resume\n", + dev->name, err); + } + + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} static struct pci_device_id nortel_pci_id_table[] = { /* Nortel emobility PCI */ @@ -275,10 +352,12 @@ static struct pci_device_id nortel_pci_id_table[] = { MODULE_DEVICE_TABLE(pci, nortel_pci_id_table); static struct pci_driver nortel_pci_driver = { - .name = DRIVER_NAME, - .id_table = nortel_pci_id_table, - .probe = nortel_pci_init_one, - .remove = __devexit_p(nortel_pci_remove_one), + .name = DRIVER_NAME, + .id_table = nortel_pci_id_table, + .probe = nortel_pci_init_one, + .remove = __devexit_p(nortel_pci_remove_one), + .suspend = orinoco_nortel_suspend, + .resume = orinoco_nortel_resume, }; static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION diff --git a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c index 210e73776545..3fe7a2f37896 100644 --- a/drivers/net/wireless/orinoco_plx.c +++ b/drivers/net/wireless/orinoco_plx.c @@ -343,6 +343,83 @@ static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev) pci_disable_device(pdev); } +static int orinoco_plx_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct orinoco_private *priv = netdev_priv(dev); + unsigned long flags; + int err; + + err = orinoco_lock(priv, &flags); + if (err) { + printk(KERN_ERR "%s: cannot lock hardware for suspend\n", + dev->name); + return err; + } + + err = __orinoco_down(dev); + if (err) + printk(KERN_WARNING "%s: error %d bringing interface down " + "for suspend\n", dev->name, err); + + netif_device_detach(dev); + + priv->hw_unavailable++; + + orinoco_unlock(priv, &flags); + + free_irq(pdev->irq, dev); + pci_save_state(pdev); + pci_disable_device(pdev); + pci_set_power_state(pdev, PCI_D3hot); + + return 0; +} + +static int orinoco_plx_resume(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct orinoco_private *priv = netdev_priv(dev); + unsigned long flags; + int err; + + pci_set_power_state(pdev, 0); + pci_enable_device(pdev); + pci_restore_state(pdev); + + err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, + dev->name, dev); + if (err) { + printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n", + dev->name); + pci_disable_device(pdev); + return -EBUSY; + } + + err = orinoco_reinit_firmware(dev); + if (err) { + printk(KERN_ERR "%s: error %d re-initializing firmware " + "on resume\n", dev->name, err); + return err; + } + + spin_lock_irqsave(&priv->lock, flags); + + netif_device_attach(dev); + + priv->hw_unavailable--; + + if (priv->open && (! priv->hw_unavailable)) { + err = __orinoco_up(dev); + if (err) + printk(KERN_ERR "%s: Error %d restarting card on resume\n", + dev->name, err); + } + + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} static struct pci_device_id orinoco_plx_pci_id_table[] = { {0x111a, 0x1023, PCI_ANY_ID, PCI_ANY_ID,}, /* Siemens SpeedStream SS1023 */ @@ -369,6 +446,8 @@ static struct pci_driver orinoco_plx_driver = { .id_table = orinoco_plx_pci_id_table, .probe = orinoco_plx_init_one, .remove = __devexit_p(orinoco_plx_remove_one), + .suspend = orinoco_plx_suspend, + .resume = orinoco_plx_resume, }; static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION 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) pci_disable_device(pdev); } +static int orinoco_tmd_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct orinoco_private *priv = netdev_priv(dev); + unsigned long flags; + int err; + + err = orinoco_lock(priv, &flags); + if (err) { + printk(KERN_ERR "%s: cannot lock hardware for suspend\n", + dev->name); + return err; + } + + err = __orinoco_down(dev); + if (err) + printk(KERN_WARNING "%s: error %d bringing interface down " + "for suspend\n", dev->name, err); + + netif_device_detach(dev); + + priv->hw_unavailable++; + + orinoco_unlock(priv, &flags); + + free_irq(pdev->irq, dev); + pci_save_state(pdev); + pci_disable_device(pdev); + pci_set_power_state(pdev, PCI_D3hot); + + return 0; +} + +static int orinoco_tmd_resume(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct orinoco_private *priv = netdev_priv(dev); + unsigned long flags; + int err; + + pci_set_power_state(pdev, 0); + pci_enable_device(pdev); + pci_restore_state(pdev); + + err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, + dev->name, dev); + if (err) { + printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n", + dev->name); + pci_disable_device(pdev); + return -EBUSY; + } + + err = orinoco_reinit_firmware(dev); + if (err) { + printk(KERN_ERR "%s: error %d re-initializing firmware " + "on resume\n", dev->name, err); + return err; + } + + spin_lock_irqsave(&priv->lock, flags); + + netif_device_attach(dev); + + priv->hw_unavailable--; + + if (priv->open && (! priv->hw_unavailable)) { + err = __orinoco_up(dev); + if (err) + printk(KERN_ERR "%s: Error %d restarting card on resume\n", + dev->name, err); + } + + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} static struct pci_device_id orinoco_tmd_pci_id_table[] = { {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 = { .id_table = orinoco_tmd_pci_id_table, .probe = orinoco_tmd_init_one, .remove = __devexit_p(orinoco_tmd_remove_one), + .suspend = orinoco_tmd_suspend, + .resume = orinoco_tmd_resume, }; static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION |