s390/pci: implement hibernation hooks
authorSebastian Ott <sebott@linux.vnet.ibm.com>
Wed, 25 Sep 2013 10:27:43 +0000 (12:27 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Thu, 24 Oct 2013 15:16:57 +0000 (17:16 +0200)
Implement architecture-specific functionality when a PCI device is
doing a hibernate transition.

Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/pci/pci.c

index f17a8343e3609d7d644b1d5896fd49bf4fca9e88..206186c44ade4a9ddfa621bd37d6bf48d7ef9385 100644 (file)
@@ -708,6 +708,47 @@ void pcibios_disable_device(struct pci_dev *pdev)
        zdev->pdev = NULL;
 }
 
+#ifdef CONFIG_HIBERNATE_CALLBACKS
+static int zpci_restore(struct device *dev)
+{
+       struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
+       int ret = 0;
+
+       if (zdev->state != ZPCI_FN_STATE_ONLINE)
+               goto out;
+
+       ret = clp_enable_fh(zdev, ZPCI_NR_DMA_SPACES);
+       if (ret)
+               goto out;
+
+       zpci_map_resources(zdev);
+       zpci_register_ioat(zdev, 0, zdev->start_dma + PAGE_OFFSET,
+                          zdev->start_dma + zdev->iommu_size - 1,
+                          (u64) zdev->dma_table);
+
+out:
+       return ret;
+}
+
+static int zpci_freeze(struct device *dev)
+{
+       struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
+
+       if (zdev->state != ZPCI_FN_STATE_ONLINE)
+               return 0;
+
+       zpci_unregister_ioat(zdev, 0);
+       return clp_disable_fh(zdev);
+}
+
+struct dev_pm_ops pcibios_pm_ops = {
+       .thaw_noirq = zpci_restore,
+       .freeze_noirq = zpci_freeze,
+       .restore_noirq = zpci_restore,
+       .poweroff_noirq = zpci_freeze,
+};
+#endif /* CONFIG_HIBERNATE_CALLBACKS */
+
 static int zpci_scan_bus(struct zpci_dev *zdev)
 {
        struct resource *res;