Skip to content

Commit

Permalink
mei: add mei_stop function to stop mei device
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Tomas Winkler authored and Greg Kroah-Hartman committed Mar 15, 2013
1 parent 3d374d0 commit 7cb035d
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 45 deletions.
18 changes: 18 additions & 0 deletions drivers/misc/mei/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}




1 change: 1 addition & 0 deletions drivers/misc/mei/mei_dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
52 changes: 7 additions & 45 deletions drivers/misc/mei/pci-me.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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)
Expand Down

0 comments on commit 7cb035d

Please sign in to comment.