Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7cb035d9 authored by Tomas Winkler's avatar Tomas Winkler Committed by Greg Kroah-Hartman
Browse files

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: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3d374d09
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
@@ -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
+7 −45
Original line number Diff line number Diff line
@@ -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)