aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/orinoco_tmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/orinoco_tmd.c')
-rw-r--r--drivers/net/wireless/orinoco_tmd.c79
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
218static 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
251static 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
219static struct pci_device_id orinoco_tmd_pci_id_table[] = { 296static 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
233static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION 312static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION