mei: add mei_stop function to stop mei device
mei_stop calls mei_reset with disabling the interrupts. It will have the same effect as the open code it replaces in the mei_remove. The reset sequence on remove is required for the Lynx Point LP devices to clean the reset state. mei_stop is called from mei_pci_suspend and mei_remove functions Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
3d374d09f1
Коммит
7cb035d9e6
|
@ -183,6 +183,24 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
|
|||
mei_cl_all_write_clear(dev);
|
||||
}
|
||||
|
||||
void mei_stop(struct mei_device *dev)
|
||||
{
|
||||
dev_dbg(&dev->pdev->dev, "stopping the device.\n");
|
||||
|
||||
mutex_lock(&dev->device_lock);
|
||||
|
||||
cancel_delayed_work(&dev->timer_work);
|
||||
|
||||
mei_wd_stop(dev);
|
||||
|
||||
dev->dev_state = MEI_DEV_POWER_DOWN;
|
||||
mei_reset(dev, 0);
|
||||
|
||||
mutex_unlock(&dev->device_lock);
|
||||
|
||||
flush_scheduled_work();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -381,6 +381,7 @@ static inline unsigned long mei_secs_to_jiffies(unsigned long sec)
|
|||
void mei_device_init(struct mei_device *dev);
|
||||
void mei_reset(struct mei_device *dev, int interrupts);
|
||||
int mei_hw_init(struct mei_device *dev);
|
||||
void mei_stop(struct mei_device *dev);
|
||||
|
||||
/*
|
||||
* MEI interrupt functions prototype
|
||||
|
|
|
@ -247,44 +247,14 @@ static void mei_remove(struct pci_dev *pdev)
|
|||
|
||||
hw = to_me_hw(dev);
|
||||
|
||||
mutex_lock(&dev->device_lock);
|
||||
|
||||
cancel_delayed_work(&dev->timer_work);
|
||||
|
||||
mei_wd_stop(dev);
|
||||
dev_err(&pdev->dev, "stop\n");
|
||||
mei_stop(dev);
|
||||
|
||||
mei_pdev = NULL;
|
||||
|
||||
if (dev->iamthif_cl.state == MEI_FILE_CONNECTED) {
|
||||
dev->iamthif_cl.state = MEI_FILE_DISCONNECTING;
|
||||
mei_cl_disconnect(&dev->iamthif_cl);
|
||||
}
|
||||
if (dev->wd_cl.state == MEI_FILE_CONNECTED) {
|
||||
dev->wd_cl.state = MEI_FILE_DISCONNECTING;
|
||||
mei_cl_disconnect(&dev->wd_cl);
|
||||
}
|
||||
|
||||
/* Unregistering watchdog device */
|
||||
mei_watchdog_unregister(dev);
|
||||
|
||||
/* remove entry if already in list */
|
||||
dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n");
|
||||
|
||||
if (dev->open_handle_count > 0)
|
||||
dev->open_handle_count--;
|
||||
mei_cl_unlink(&dev->wd_cl);
|
||||
|
||||
if (dev->open_handle_count > 0)
|
||||
dev->open_handle_count--;
|
||||
mei_cl_unlink(&dev->iamthif_cl);
|
||||
|
||||
dev->iamthif_current_cb = NULL;
|
||||
dev->me_clients_num = 0;
|
||||
|
||||
mutex_unlock(&dev->device_lock);
|
||||
|
||||
flush_scheduled_work();
|
||||
|
||||
/* disable interrupts */
|
||||
mei_disable_interrupts(dev);
|
||||
|
||||
|
@ -308,28 +278,20 @@ static int mei_pci_suspend(struct device *device)
|
|||
{
|
||||
struct pci_dev *pdev = to_pci_dev(device);
|
||||
struct mei_device *dev = pci_get_drvdata(pdev);
|
||||
int err;
|
||||
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
mutex_lock(&dev->device_lock);
|
||||
|
||||
cancel_delayed_work(&dev->timer_work);
|
||||
dev_err(&pdev->dev, "suspend\n");
|
||||
|
||||
/* Stop watchdog if exists */
|
||||
err = mei_wd_stop(dev);
|
||||
/* Set new mei state */
|
||||
if (dev->dev_state == MEI_DEV_ENABLED ||
|
||||
dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) {
|
||||
dev->dev_state = MEI_DEV_POWER_DOWN;
|
||||
mei_reset(dev, 0);
|
||||
}
|
||||
mutex_unlock(&dev->device_lock);
|
||||
mei_stop(dev);
|
||||
|
||||
mei_disable_interrupts(dev);
|
||||
|
||||
free_irq(pdev->irq, dev);
|
||||
pci_disable_msi(pdev);
|
||||
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mei_pci_resume(struct device *device)
|
||||
|
|
Загрузка…
Ссылка в новой задаче