Handle suspend and resume calls for virtio mmio devices from
PM core. Expose these notifications to virtio drivers that can quiesce and
resume vq operations. Update virtio pm ops to handle freeze& restore and
suspend & resume callbacks separately.
Signed-off-by: Anvesh Jain P <[email protected]>
Signed-off-by: Venkata Rao Kakani <[email protected]>
---
drivers/virtio/virtio.c | 112 +++++++++++++++++++++++++++++++++++
drivers/virtio/virtio_mmio.c | 50 +++++++++++++++-
include/linux/virtio.h | 12 ++++
3 files changed, 173 insertions(+), 1 deletion(-)
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 3893dc29eb26..c6f25a267600 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -551,6 +551,118 @@ int virtio_device_restore(struct virtio_device *dev)
return ret;
}
EXPORT_SYMBOL_GPL(virtio_device_restore);
+
+int virtio_device_suspend(struct virtio_device *dev)
+{
+ struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
+
+ virtio_config_disable(dev);
+
+ dev->failed = dev->config->get_status(dev) & VIRTIO_CONFIG_S_FAILED;
+
+ if (drv && drv->suspend)
+ return drv->suspend(dev);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(virtio_device_suspend);
+
+int virtio_device_resume(struct virtio_device *dev)
+{
+ struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
+ int ret;
+
+ if (drv && drv->resume) {
+ ret = drv->resume(dev);
+ if (ret)
+ goto err;
+
+ if (!(dev->config->get_status(dev) & VIRTIO_CONFIG_S_DRIVER_OK))
+ virtio_device_ready(dev);
+
+ virtio_config_enable(dev);
+ }
+
+ return 0;
+err:
+ virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(virtio_device_resume);
+
+int virtio_device_suspend_late(struct virtio_device *dev)
+{
+ struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
+
+ virtio_config_disable(dev);
+
+ dev->failed = dev->config->get_status(dev) & VIRTIO_CONFIG_S_FAILED;
+
+ if (drv && drv->suspend_late)
+ return drv->suspend_late(dev);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(virtio_device_suspend_late);
+
+int virtio_device_resume_early(struct virtio_device *dev)
+{
+ struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
+ int ret;
+
+ if (drv && drv->resume_early) {
+ ret = drv->resume_early(dev);
+ if (ret)
+ goto err;
+ if (!(dev->config->get_status(dev) & VIRTIO_CONFIG_S_DRIVER_OK))
+ virtio_device_ready(dev);
+
+ virtio_config_enable(dev);
+ }
+
+ return 0;
+err:
+ virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(virtio_device_resume_early);
+
+int virtio_device_suspend_noirq(struct virtio_device *dev)
+{
+ struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
+
+ virtio_config_disable(dev);
+
+ dev->failed = dev->config->get_status(dev) & VIRTIO_CONFIG_S_FAILED;
+
+ if (drv && drv->suspend_noirq)
+ return drv->suspend_noirq(dev);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(virtio_device_suspend_noirq);
+
+int virtio_device_resume_noirq(struct virtio_device *dev)
+{
+ struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
+ int ret;
+
+ if (drv && drv->resume_noirq) {
+ ret = drv->resume_noirq(dev);
+ if (ret)
+ goto err;
+ if (!(dev->config->get_status(dev) & VIRTIO_CONFIG_S_DRIVER_OK))
+ virtio_device_ready(dev);
+
+ virtio_config_enable(dev);
+ }
+
+ return 0;
+err:
+ virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(virtio_device_resume_noirq);
#endif
static int virtio_init(void)
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index a46a4a29e929..9385c7e65da9 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -596,9 +596,57 @@ static int virtio_mmio_restore(struct device *dev)
return virtio_device_restore(&vm_dev->vdev);
}
+static int virtio_mmio_suspend(struct device *dev)
+{
+ struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
+
+ return virtio_device_suspend(&vm_dev->vdev);
+}
+
+static int virtio_mmio_resume(struct device *dev)
+{
+ struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
+
+ return virtio_device_resume(&vm_dev->vdev);
+}
+
+static int virtio_mmio_suspend_late(struct device *dev)
+{
+ struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
+
+ return virtio_device_suspend_late(&vm_dev->vdev);
+}
+
+static int virtio_mmio_resume_early(struct device *dev)
+{
+ struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
+
+ return virtio_device_resume_early(&vm_dev->vdev);
+}
+
+static int virtio_mmio_suspend_noirq(struct device *dev)
+{
+ struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
+
+ return virtio_device_suspend_noirq(&vm_dev->vdev);
+}
+
+static int virtio_mmio_resume_noirq(struct device *dev)
+{
+ struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
+
+ return virtio_device_resume_noirq(&vm_dev->vdev);
+}
static const struct dev_pm_ops virtio_mmio_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(virtio_mmio_freeze, virtio_mmio_restore)
+ .freeze = virtio_mmio_freeze,
+ .restore = virtio_mmio_restore,
+ .suspend = virtio_mmio_suspend,
+ .resume = virtio_mmio_resume,
+ .suspend_late = virtio_mmio_suspend_late,
+ .resume_early = virtio_mmio_resume_early,
+ .suspend_noirq = virtio_mmio_suspend_noirq,
+ .resume_noirq = virtio_mmio_resume_noirq,
};
#endif
diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index de6041deee37..e88b321408e9 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -145,6 +145,12 @@ void virtio_config_changed(struct virtio_device *dev);
#ifdef CONFIG_PM_SLEEP
int virtio_device_freeze(struct virtio_device *dev);
int virtio_device_restore(struct virtio_device *dev);
+int virtio_device_suspend(struct virtio_device *dev);
+int virtio_device_resume(struct virtio_device *dev);
+int virtio_device_suspend_late(struct virtio_device *dev);
+int virtio_device_resume_early(struct virtio_device *dev);
+int virtio_device_suspend_noirq(struct virtio_device *dev);
+int virtio_device_resume_noirq(struct virtio_device *dev);
#endif
void virtio_reset_device(struct virtio_device *dev);
@@ -187,6 +193,12 @@ struct virtio_driver {
#ifdef CONFIG_PM
int (*freeze)(struct virtio_device *dev);
int (*restore)(struct virtio_device *dev);
+ int (*suspend)(struct virtio_device *dev);
+ int (*resume)(struct virtio_device *dev);
+ int (*suspend_late)(struct virtio_device *dev);
+ int (*resume_early)(struct virtio_device *dev);
+ int (*suspend_noirq)(struct virtio_device *dev);
+ int (*resume_noirq)(struct virtio_device *dev);
#endif
};
base-commit: 3f01e9fed8454dcd89727016c3e5b2fbb8f8e50c
--
2.17.1
On Fri, Jul 28, 2023 at 12:31:27PM +0530, Anvesh Jain P wrote:
> Handle suspend and resume calls for virtio mmio devices from
> PM core. Expose these notifications to virtio drivers that can quiesce and
> resume vq operations. Update virtio pm ops to handle freeze& restore and
> suspend & resume callbacks separately.
>
> Signed-off-by: Anvesh Jain P <[email protected]>
> Signed-off-by: Venkata Rao Kakani <[email protected]>
okey but what is the motivation? does this addition of 200 LOC
achieve something new? what is the issue fixed here?
> ---
> drivers/virtio/virtio.c | 112 +++++++++++++++++++++++++++++++++++
> drivers/virtio/virtio_mmio.c | 50 +++++++++++++++-
> include/linux/virtio.h | 12 ++++
> 3 files changed, 173 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
> index 3893dc29eb26..c6f25a267600 100644
> --- a/drivers/virtio/virtio.c
> +++ b/drivers/virtio/virtio.c
> @@ -551,6 +551,118 @@ int virtio_device_restore(struct virtio_device *dev)
> return ret;
> }
> EXPORT_SYMBOL_GPL(virtio_device_restore);
> +
> +int virtio_device_suspend(struct virtio_device *dev)
> +{
> + struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
> +
> + virtio_config_disable(dev);
> +
> + dev->failed = dev->config->get_status(dev) & VIRTIO_CONFIG_S_FAILED;
> +
> + if (drv && drv->suspend)
> + return drv->suspend(dev);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(virtio_device_suspend);
> +
> +int virtio_device_resume(struct virtio_device *dev)
> +{
> + struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
> + int ret;
> +
> + if (drv && drv->resume) {
> + ret = drv->resume(dev);
> + if (ret)
> + goto err;
> +
> + if (!(dev->config->get_status(dev) & VIRTIO_CONFIG_S_DRIVER_OK))
> + virtio_device_ready(dev);
> +
> + virtio_config_enable(dev);
> + }
> +
> + return 0;
> +err:
> + virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(virtio_device_resume);
> +
> +int virtio_device_suspend_late(struct virtio_device *dev)
> +{
> + struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
> +
> + virtio_config_disable(dev);
> +
> + dev->failed = dev->config->get_status(dev) & VIRTIO_CONFIG_S_FAILED;
> +
> + if (drv && drv->suspend_late)
> + return drv->suspend_late(dev);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(virtio_device_suspend_late);
> +
> +int virtio_device_resume_early(struct virtio_device *dev)
> +{
> + struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
> + int ret;
> +
> + if (drv && drv->resume_early) {
> + ret = drv->resume_early(dev);
> + if (ret)
> + goto err;
> + if (!(dev->config->get_status(dev) & VIRTIO_CONFIG_S_DRIVER_OK))
> + virtio_device_ready(dev);
> +
> + virtio_config_enable(dev);
> + }
> +
> + return 0;
> +err:
> + virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(virtio_device_resume_early);
> +
> +int virtio_device_suspend_noirq(struct virtio_device *dev)
> +{
> + struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
> +
> + virtio_config_disable(dev);
> +
> + dev->failed = dev->config->get_status(dev) & VIRTIO_CONFIG_S_FAILED;
> +
> + if (drv && drv->suspend_noirq)
> + return drv->suspend_noirq(dev);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(virtio_device_suspend_noirq);
> +
> +int virtio_device_resume_noirq(struct virtio_device *dev)
> +{
> + struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
> + int ret;
> +
> + if (drv && drv->resume_noirq) {
> + ret = drv->resume_noirq(dev);
> + if (ret)
> + goto err;
> + if (!(dev->config->get_status(dev) & VIRTIO_CONFIG_S_DRIVER_OK))
> + virtio_device_ready(dev);
> +
> + virtio_config_enable(dev);
> + }
> +
> + return 0;
> +err:
> + virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(virtio_device_resume_noirq);
> #endif
>
> static int virtio_init(void)
> diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
> index a46a4a29e929..9385c7e65da9 100644
> --- a/drivers/virtio/virtio_mmio.c
> +++ b/drivers/virtio/virtio_mmio.c
> @@ -596,9 +596,57 @@ static int virtio_mmio_restore(struct device *dev)
>
> return virtio_device_restore(&vm_dev->vdev);
> }
> +static int virtio_mmio_suspend(struct device *dev)
> +{
> + struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
> +
> + return virtio_device_suspend(&vm_dev->vdev);
> +}
> +
> +static int virtio_mmio_resume(struct device *dev)
> +{
> + struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
> +
> + return virtio_device_resume(&vm_dev->vdev);
> +}
> +
> +static int virtio_mmio_suspend_late(struct device *dev)
> +{
> + struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
> +
> + return virtio_device_suspend_late(&vm_dev->vdev);
> +}
> +
> +static int virtio_mmio_resume_early(struct device *dev)
> +{
> + struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
> +
> + return virtio_device_resume_early(&vm_dev->vdev);
> +}
> +
> +static int virtio_mmio_suspend_noirq(struct device *dev)
> +{
> + struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
> +
> + return virtio_device_suspend_noirq(&vm_dev->vdev);
> +}
> +
> +static int virtio_mmio_resume_noirq(struct device *dev)
> +{
> + struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
> +
> + return virtio_device_resume_noirq(&vm_dev->vdev);
> +}
>
> static const struct dev_pm_ops virtio_mmio_pm_ops = {
> - SET_SYSTEM_SLEEP_PM_OPS(virtio_mmio_freeze, virtio_mmio_restore)
> + .freeze = virtio_mmio_freeze,
> + .restore = virtio_mmio_restore,
> + .suspend = virtio_mmio_suspend,
> + .resume = virtio_mmio_resume,
> + .suspend_late = virtio_mmio_suspend_late,
> + .resume_early = virtio_mmio_resume_early,
> + .suspend_noirq = virtio_mmio_suspend_noirq,
> + .resume_noirq = virtio_mmio_resume_noirq,
> };
> #endif
>
> diff --git a/include/linux/virtio.h b/include/linux/virtio.h
> index de6041deee37..e88b321408e9 100644
> --- a/include/linux/virtio.h
> +++ b/include/linux/virtio.h
> @@ -145,6 +145,12 @@ void virtio_config_changed(struct virtio_device *dev);
> #ifdef CONFIG_PM_SLEEP
> int virtio_device_freeze(struct virtio_device *dev);
> int virtio_device_restore(struct virtio_device *dev);
> +int virtio_device_suspend(struct virtio_device *dev);
> +int virtio_device_resume(struct virtio_device *dev);
> +int virtio_device_suspend_late(struct virtio_device *dev);
> +int virtio_device_resume_early(struct virtio_device *dev);
> +int virtio_device_suspend_noirq(struct virtio_device *dev);
> +int virtio_device_resume_noirq(struct virtio_device *dev);
> #endif
> void virtio_reset_device(struct virtio_device *dev);
>
> @@ -187,6 +193,12 @@ struct virtio_driver {
> #ifdef CONFIG_PM
> int (*freeze)(struct virtio_device *dev);
> int (*restore)(struct virtio_device *dev);
> + int (*suspend)(struct virtio_device *dev);
> + int (*resume)(struct virtio_device *dev);
> + int (*suspend_late)(struct virtio_device *dev);
> + int (*resume_early)(struct virtio_device *dev);
> + int (*suspend_noirq)(struct virtio_device *dev);
> + int (*resume_noirq)(struct virtio_device *dev);
> #endif
> };
>
>
> base-commit: 3f01e9fed8454dcd89727016c3e5b2fbb8f8e50c
> --
> 2.17.1
On Fri, Aug 11, 2023 at 3:45 AM Michael S. Tsirkin <[email protected]> wrote:
>
> On Fri, Jul 28, 2023 at 12:31:27PM +0530, Anvesh Jain P wrote:
> > Handle suspend and resume calls for virtio mmio devices from
> > PM core. Expose these notifications to virtio drivers that can quiesce and
> > resume vq operations. Update virtio pm ops to handle freeze& restore and
> > suspend & resume callbacks separately.
> >
> > Signed-off-by: Anvesh Jain P <[email protected]>
> > Signed-off-by: Venkata Rao Kakani <[email protected]>
>
> okey but what is the motivation? does this addition of 200 LOC
> achieve something new? what is the issue fixed here?
+1
And I think we need an example that can use the new ops.
Thanks
>
>
> > ---
> > drivers/virtio/virtio.c | 112 +++++++++++++++++++++++++++++++++++
> > drivers/virtio/virtio_mmio.c | 50 +++++++++++++++-
> > include/linux/virtio.h | 12 ++++
> > 3 files changed, 173 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
> > index 3893dc29eb26..c6f25a267600 100644
> > --- a/drivers/virtio/virtio.c
> > +++ b/drivers/virtio/virtio.c
> > @@ -551,6 +551,118 @@ int virtio_device_restore(struct virtio_device *dev)
> > return ret;
> > }
> > EXPORT_SYMBOL_GPL(virtio_device_restore);
> > +
> > +int virtio_device_suspend(struct virtio_device *dev)
> > +{
> > + struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
> > +
> > + virtio_config_disable(dev);
> > +
> > + dev->failed = dev->config->get_status(dev) & VIRTIO_CONFIG_S_FAILED;
> > +
> > + if (drv && drv->suspend)
> > + return drv->suspend(dev);
> > +
> > + return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(virtio_device_suspend);
> > +
> > +int virtio_device_resume(struct virtio_device *dev)
> > +{
> > + struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
> > + int ret;
> > +
> > + if (drv && drv->resume) {
> > + ret = drv->resume(dev);
> > + if (ret)
> > + goto err;
> > +
> > + if (!(dev->config->get_status(dev) & VIRTIO_CONFIG_S_DRIVER_OK))
> > + virtio_device_ready(dev);
> > +
> > + virtio_config_enable(dev);
> > + }
> > +
> > + return 0;
> > +err:
> > + virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
> > + return ret;
> > +}
> > +EXPORT_SYMBOL_GPL(virtio_device_resume);
> > +
> > +int virtio_device_suspend_late(struct virtio_device *dev)
> > +{
> > + struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
> > +
> > + virtio_config_disable(dev);
> > +
> > + dev->failed = dev->config->get_status(dev) & VIRTIO_CONFIG_S_FAILED;
> > +
> > + if (drv && drv->suspend_late)
> > + return drv->suspend_late(dev);
> > +
> > + return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(virtio_device_suspend_late);
> > +
> > +int virtio_device_resume_early(struct virtio_device *dev)
> > +{
> > + struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
> > + int ret;
> > +
> > + if (drv && drv->resume_early) {
> > + ret = drv->resume_early(dev);
> > + if (ret)
> > + goto err;
> > + if (!(dev->config->get_status(dev) & VIRTIO_CONFIG_S_DRIVER_OK))
> > + virtio_device_ready(dev);
> > +
> > + virtio_config_enable(dev);
> > + }
> > +
> > + return 0;
> > +err:
> > + virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
> > + return ret;
> > +}
> > +EXPORT_SYMBOL_GPL(virtio_device_resume_early);
> > +
> > +int virtio_device_suspend_noirq(struct virtio_device *dev)
> > +{
> > + struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
> > +
> > + virtio_config_disable(dev);
> > +
> > + dev->failed = dev->config->get_status(dev) & VIRTIO_CONFIG_S_FAILED;
> > +
> > + if (drv && drv->suspend_noirq)
> > + return drv->suspend_noirq(dev);
> > +
> > + return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(virtio_device_suspend_noirq);
> > +
> > +int virtio_device_resume_noirq(struct virtio_device *dev)
> > +{
> > + struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
> > + int ret;
> > +
> > + if (drv && drv->resume_noirq) {
> > + ret = drv->resume_noirq(dev);
> > + if (ret)
> > + goto err;
> > + if (!(dev->config->get_status(dev) & VIRTIO_CONFIG_S_DRIVER_OK))
> > + virtio_device_ready(dev);
> > +
> > + virtio_config_enable(dev);
> > + }
> > +
> > + return 0;
> > +err:
> > + virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
> > + return ret;
> > +}
> > +EXPORT_SYMBOL_GPL(virtio_device_resume_noirq);
> > #endif
> >
> > static int virtio_init(void)
> > diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
> > index a46a4a29e929..9385c7e65da9 100644
> > --- a/drivers/virtio/virtio_mmio.c
> > +++ b/drivers/virtio/virtio_mmio.c
> > @@ -596,9 +596,57 @@ static int virtio_mmio_restore(struct device *dev)
> >
> > return virtio_device_restore(&vm_dev->vdev);
> > }
> > +static int virtio_mmio_suspend(struct device *dev)
> > +{
> > + struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
> > +
> > + return virtio_device_suspend(&vm_dev->vdev);
> > +}
> > +
> > +static int virtio_mmio_resume(struct device *dev)
> > +{
> > + struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
> > +
> > + return virtio_device_resume(&vm_dev->vdev);
> > +}
> > +
> > +static int virtio_mmio_suspend_late(struct device *dev)
> > +{
> > + struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
> > +
> > + return virtio_device_suspend_late(&vm_dev->vdev);
> > +}
> > +
> > +static int virtio_mmio_resume_early(struct device *dev)
> > +{
> > + struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
> > +
> > + return virtio_device_resume_early(&vm_dev->vdev);
> > +}
> > +
> > +static int virtio_mmio_suspend_noirq(struct device *dev)
> > +{
> > + struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
> > +
> > + return virtio_device_suspend_noirq(&vm_dev->vdev);
> > +}
> > +
> > +static int virtio_mmio_resume_noirq(struct device *dev)
> > +{
> > + struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
> > +
> > + return virtio_device_resume_noirq(&vm_dev->vdev);
> > +}
> >
> > static const struct dev_pm_ops virtio_mmio_pm_ops = {
> > - SET_SYSTEM_SLEEP_PM_OPS(virtio_mmio_freeze, virtio_mmio_restore)
> > + .freeze = virtio_mmio_freeze,
> > + .restore = virtio_mmio_restore,
> > + .suspend = virtio_mmio_suspend,
> > + .resume = virtio_mmio_resume,
> > + .suspend_late = virtio_mmio_suspend_late,
> > + .resume_early = virtio_mmio_resume_early,
> > + .suspend_noirq = virtio_mmio_suspend_noirq,
> > + .resume_noirq = virtio_mmio_resume_noirq,
> > };
> > #endif
> >
> > diff --git a/include/linux/virtio.h b/include/linux/virtio.h
> > index de6041deee37..e88b321408e9 100644
> > --- a/include/linux/virtio.h
> > +++ b/include/linux/virtio.h
> > @@ -145,6 +145,12 @@ void virtio_config_changed(struct virtio_device *dev);
> > #ifdef CONFIG_PM_SLEEP
> > int virtio_device_freeze(struct virtio_device *dev);
> > int virtio_device_restore(struct virtio_device *dev);
> > +int virtio_device_suspend(struct virtio_device *dev);
> > +int virtio_device_resume(struct virtio_device *dev);
> > +int virtio_device_suspend_late(struct virtio_device *dev);
> > +int virtio_device_resume_early(struct virtio_device *dev);
> > +int virtio_device_suspend_noirq(struct virtio_device *dev);
> > +int virtio_device_resume_noirq(struct virtio_device *dev);
> > #endif
> > void virtio_reset_device(struct virtio_device *dev);
> >
> > @@ -187,6 +193,12 @@ struct virtio_driver {
> > #ifdef CONFIG_PM
> > int (*freeze)(struct virtio_device *dev);
> > int (*restore)(struct virtio_device *dev);
> > + int (*suspend)(struct virtio_device *dev);
> > + int (*resume)(struct virtio_device *dev);
> > + int (*suspend_late)(struct virtio_device *dev);
> > + int (*resume_early)(struct virtio_device *dev);
> > + int (*suspend_noirq)(struct virtio_device *dev);
> > + int (*resume_noirq)(struct virtio_device *dev);
> > #endif
> > };
> >
> >
> > base-commit: 3f01e9fed8454dcd89727016c3e5b2fbb8f8e50c
> > --
> > 2.17.1
>