diff options
Diffstat (limited to 'drivers/staging/mei/main.c')
-rw-r--r-- | drivers/staging/mei/main.c | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/drivers/staging/mei/main.c b/drivers/staging/mei/main.c index de8825fcd8ce..eb05c36f45d4 100644 --- a/drivers/staging/mei/main.c +++ b/drivers/staging/mei/main.c @@ -58,7 +58,7 @@ static struct cdev mei_cdev; static int mei_major; /* The device pointer */ /* Currently this driver works as long as there is only a single AMT device. */ -static struct pci_dev *mei_device; +struct pci_dev *mei_device; static struct class *mei_class; @@ -151,17 +151,26 @@ static int __devinit mei_probe(struct pci_dev *pdev, err = -ENOMEM; goto free_device; } - /* request and enable interrupt */ - err = request_threaded_irq(pdev->irq, + pci_enable_msi(pdev); + + /* request and enable interrupt */ + if (pci_dev_msi_enabled(pdev)) + err = request_threaded_irq(pdev->irq, + NULL, + mei_interrupt_thread_handler, + 0, mei_driver_name, dev); + else + err = request_threaded_irq(pdev->irq, mei_interrupt_quick_handler, mei_interrupt_thread_handler, IRQF_SHARED, mei_driver_name, dev); + if (err) { printk(KERN_ERR "mei: request_threaded_irq failure. irq = %d\n", pdev->irq); goto unmap_memory; } - INIT_DELAYED_WORK(&dev->wd_work, mei_wd_timer); + INIT_DELAYED_WORK(&dev->timer_work, mei_timer); if (mei_hw_init(dev)) { printk(KERN_ERR "mei: Init hw failure.\n"); err = -ENODEV; @@ -169,7 +178,7 @@ static int __devinit mei_probe(struct pci_dev *pdev, } mei_device = pdev; pci_set_drvdata(pdev, dev); - schedule_delayed_work(&dev->wd_work, HZ); + schedule_delayed_work(&dev->timer_work, HZ); mutex_unlock(&mei_mutex); @@ -183,6 +192,7 @@ release_irq: mei_disable_interrupts(dev); flush_scheduled_work(); free_irq(pdev->irq, dev); + pci_disable_msi(pdev); unmap_memory: pci_iounmap(pdev, dev->mem_addr); free_device: @@ -231,6 +241,10 @@ static void __devexit mei_remove(struct pci_dev *pdev) mei_disconnect_host_client(dev, &dev->wd_cl); } + /* Unregistering watchdog device */ + if (dev->wd_interface_reg) + watchdog_unregister_device(&amt_wd_dev); + /* remove entry if already in list */ dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n"); mei_remove_client_from_file_list(dev, dev->wd_cl.host_client_id); @@ -247,6 +261,7 @@ static void __devexit mei_remove(struct pci_dev *pdev) mei_disable_interrupts(dev); free_irq(pdev->irq, dev); + pci_disable_msi(pdev); pci_set_drvdata(pdev, NULL); if (dev->mem_addr) @@ -402,7 +417,7 @@ static int mei_open(struct inode *inode, struct file *file) err = -ENOMEM; cl = mei_cl_allocate(dev); if (!cl) - goto out; + goto out_unlock; err = -ENODEV; if (dev->mei_state != MEI_ENABLED) { @@ -1096,7 +1111,7 @@ static int mei_pci_suspend(struct device *device) mutex_unlock(&dev->device_lock); free_irq(pdev->irq, dev); - + pci_disable_msi(pdev); return err; } @@ -1111,11 +1126,20 @@ static int mei_pci_resume(struct device *device) if (!dev) return -ENODEV; - /* request and enable interrupt */ - err = request_threaded_irq(pdev->irq, + pci_enable_msi(pdev); + + /* request and enable interrupt */ + if (pci_dev_msi_enabled(pdev)) + err = request_threaded_irq(pdev->irq, + NULL, + mei_interrupt_thread_handler, + 0, mei_driver_name, dev); + else + err = request_threaded_irq(pdev->irq, mei_interrupt_quick_handler, mei_interrupt_thread_handler, IRQF_SHARED, mei_driver_name, dev); + if (err) { printk(KERN_ERR "mei: Request_irq failure. irq = %d\n", pdev->irq); @@ -1127,12 +1151,9 @@ static int mei_pci_resume(struct device *device) mei_reset(dev, 1); mutex_unlock(&dev->device_lock); - /* Start watchdog if stopped in suspend */ - if (dev->wd_timeout) { - mei_wd_start_setup(dev); - dev->wd_due_counter = 1; - schedule_delayed_work(&dev->wd_work, HZ); - } + /* Start timer if stopped in suspend */ + schedule_delayed_work(&dev->timer_work, HZ); + return err; } static SIMPLE_DEV_PM_OPS(mei_pm_ops, mei_pci_suspend, mei_pci_resume); |