Commit 5f0c2ee1 authored by Loic Poulain's avatar Loic Poulain Committed by Greg Kroah-Hartman

bus: mhi: pci-generic: Fix hibernation

This patch fixes crash after resuming from hibernation. The issue
occurs when mhi stack is builtin and so part of the 'restore-kernel',
causing the device to be resumed from 'restored kernel' with a no
more valid context (memory mappings etc...) and leading to spurious
crashes.

This patch fixes the issue by implementing proper freeze/restore
callbacks.

Link: https://lore.kernel.org/r/1622571445-4505-1-git-send-email-loic.poulain@linaro.orgReported-by: default avatarShujun Wang <wsj20369@163.com>
Cc: stable <stable@vger.kernel.org>
Reviewed-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: default avatarLoic Poulain <loic.poulain@linaro.org>
Signed-off-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Link: https://lore.kernel.org/r/20210606153741.20725-4-manivannan.sadhasivam@linaro.orgSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 0b67808a
...@@ -935,9 +935,43 @@ static int __maybe_unused mhi_pci_resume(struct device *dev) ...@@ -935,9 +935,43 @@ static int __maybe_unused mhi_pci_resume(struct device *dev)
return ret; return ret;
} }
static int __maybe_unused mhi_pci_freeze(struct device *dev)
{
struct mhi_pci_device *mhi_pdev = dev_get_drvdata(dev);
struct mhi_controller *mhi_cntrl = &mhi_pdev->mhi_cntrl;
/* We want to stop all operations, hibernation does not guarantee that
* device will be in the same state as before freezing, especially if
* the intermediate restore kernel reinitializes MHI device with new
* context.
*/
if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) {
mhi_power_down(mhi_cntrl, false);
mhi_unprepare_after_power_down(mhi_cntrl);
}
return 0;
}
static int __maybe_unused mhi_pci_restore(struct device *dev)
{
struct mhi_pci_device *mhi_pdev = dev_get_drvdata(dev);
/* Reinitialize the device */
queue_work(system_long_wq, &mhi_pdev->recovery_work);
return 0;
}
static const struct dev_pm_ops mhi_pci_pm_ops = { static const struct dev_pm_ops mhi_pci_pm_ops = {
SET_RUNTIME_PM_OPS(mhi_pci_runtime_suspend, mhi_pci_runtime_resume, NULL) SET_RUNTIME_PM_OPS(mhi_pci_runtime_suspend, mhi_pci_runtime_resume, NULL)
SET_SYSTEM_SLEEP_PM_OPS(mhi_pci_suspend, mhi_pci_resume) #ifdef CONFIG_PM_SLEEP
.suspend = mhi_pci_suspend,
.resume = mhi_pci_resume,
.freeze = mhi_pci_freeze,
.thaw = mhi_pci_restore,
.restore = mhi_pci_restore,
#endif
}; };
static struct pci_driver mhi_pci_driver = { static struct pci_driver mhi_pci_driver = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment