aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/virtio/virtio_pci.c
diff options
context:
space:
mode:
authorAmit Shah <amit.shah@redhat.com>2011-12-22 06:28:26 -0500
committerRusty Russell <rusty@rustcorp.com.au>2012-01-12 00:14:44 -0500
commitf0fe6f11503fa9880867554350ac5d3092c47251 (patch)
tree0f95d79a528809e169a742afeafddd041d275181 /drivers/virtio/virtio_pci.c
parentd077536386595309060dda57e7b7474c501a589b (diff)
virtio: pci: add PM notification handlers for restore, freeze, thaw, poweroff
Handle thaw, restore and freeze notifications from the PM core. Expose these to individual virtio drivers that can quiesce and resume vq operations. For drivers not implementing the thaw() method, use the restore method instead. These functions also save device-specific data so that the device can be put in pre-suspend state after resume, and disable and enable the PCI device in the freeze and resume functions, respectively. Signed-off-by: Amit Shah <amit.shah@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/virtio/virtio_pci.c')
-rw-r--r--drivers/virtio/virtio_pci.c94
1 files changed, 92 insertions, 2 deletions
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index 7f9ac1af7cfd..635e1efb3792 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -55,6 +55,10 @@ struct virtio_pci_device
55 unsigned msix_vectors; 55 unsigned msix_vectors;
56 /* Vectors allocated, excluding per-vq vectors if any */ 56 /* Vectors allocated, excluding per-vq vectors if any */
57 unsigned msix_used_vectors; 57 unsigned msix_used_vectors;
58
59 /* Status saved during hibernate/restore */
60 u8 saved_status;
61
58 /* Whether we have vector per vq */ 62 /* Whether we have vector per vq */
59 bool per_vq_vectors; 63 bool per_vq_vectors;
60}; 64};
@@ -734,9 +738,95 @@ static int virtio_pci_resume(struct device *dev)
734 return 0; 738 return 0;
735} 739}
736 740
741static int virtio_pci_freeze(struct device *dev)
742{
743 struct pci_dev *pci_dev = to_pci_dev(dev);
744 struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
745 struct virtio_driver *drv;
746 int ret;
747
748 drv = container_of(vp_dev->vdev.dev.driver,
749 struct virtio_driver, driver);
750
751 ret = 0;
752 vp_dev->saved_status = vp_get_status(&vp_dev->vdev);
753 if (drv && drv->freeze)
754 ret = drv->freeze(&vp_dev->vdev);
755
756 if (!ret)
757 pci_disable_device(pci_dev);
758 return ret;
759}
760
761static int restore_common(struct device *dev)
762{
763 struct pci_dev *pci_dev = to_pci_dev(dev);
764 struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
765 int ret;
766
767 ret = pci_enable_device(pci_dev);
768 if (ret)
769 return ret;
770 pci_set_master(pci_dev);
771 vp_finalize_features(&vp_dev->vdev);
772
773 return ret;
774}
775
776static int virtio_pci_thaw(struct device *dev)
777{
778 struct pci_dev *pci_dev = to_pci_dev(dev);
779 struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
780 struct virtio_driver *drv;
781 int ret;
782
783 ret = restore_common(dev);
784 if (ret)
785 return ret;
786
787 drv = container_of(vp_dev->vdev.dev.driver,
788 struct virtio_driver, driver);
789
790 if (drv && drv->thaw)
791 ret = drv->thaw(&vp_dev->vdev);
792 else if (drv && drv->restore)
793 ret = drv->restore(&vp_dev->vdev);
794
795 /* Finally, tell the device we're all set */
796 if (!ret)
797 vp_set_status(&vp_dev->vdev, vp_dev->saved_status);
798
799 return ret;
800}
801
802static int virtio_pci_restore(struct device *dev)
803{
804 struct pci_dev *pci_dev = to_pci_dev(dev);
805 struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
806 struct virtio_driver *drv;
807 int ret;
808
809 drv = container_of(vp_dev->vdev.dev.driver,
810 struct virtio_driver, driver);
811
812 ret = restore_common(dev);
813 if (!ret && drv && drv->restore)
814 ret = drv->restore(&vp_dev->vdev);
815
816 /* Finally, tell the device we're all set */
817 if (!ret)
818 vp_set_status(&vp_dev->vdev, vp_dev->saved_status);
819
820 return ret;
821}
822
737static const struct dev_pm_ops virtio_pci_pm_ops = { 823static const struct dev_pm_ops virtio_pci_pm_ops = {
738 .suspend = virtio_pci_suspend, 824 .suspend = virtio_pci_suspend,
739 .resume = virtio_pci_resume, 825 .resume = virtio_pci_resume,
826 .freeze = virtio_pci_freeze,
827 .thaw = virtio_pci_thaw,
828 .restore = virtio_pci_restore,
829 .poweroff = virtio_pci_suspend,
740}; 830};
741#endif 831#endif
742 832