s390/pci: deal with devices that have no support for MIO instructions
authorSebastian Ott <sebott@linux.ibm.com>
Thu, 27 Jun 2019 13:13:05 +0000 (15:13 +0200)
committerVasily Gorbik <gor@linux.ibm.com>
Thu, 4 Jul 2019 11:13:57 +0000 (13:13 +0200)
Unfortunately we have to handle a class of devices that don't support the
new MIO instructions. Adjust resource assignment and mapping accordingly.

Signed-off-by: Sebastian Ott <sebott@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
arch/s390/include/asm/pci.h
arch/s390/pci/pci.c

index 305befd..a2399ef 100644 (file)
@@ -194,6 +194,11 @@ int zpci_init_iommu(struct zpci_dev *zdev);
 void zpci_destroy_iommu(struct zpci_dev *zdev);
 
 #ifdef CONFIG_PCI
+static inline bool zpci_use_mio(struct zpci_dev *zdev)
+{
+       return static_branch_likely(&have_mio) && zdev->mio_capable;
+}
+
 /* Error handling and recovery */
 void zpci_event_error(void *);
 void zpci_event_availability(void *);
index 86ca7f8..b8a64cb 100644 (file)
@@ -421,12 +421,12 @@ static void zpci_map_resources(struct pci_dev *pdev)
                if (!len)
                        continue;
 
-               if (static_branch_likely(&have_mio))
+               if (zpci_use_mio(zdev))
                        pdev->resource[i].start =
                                (resource_size_t __force) zdev->bars[i].mio_wb;
                else
-                       pdev->resource[i].start =
-                               (resource_size_t __force) pci_iomap(pdev, i, 0);
+                       pdev->resource[i].start = (resource_size_t __force)
+                               pci_iomap_range_fh(pdev, i, 0, 0);
                pdev->resource[i].end = pdev->resource[i].start + len - 1;
        }
 
@@ -444,18 +444,19 @@ static void zpci_map_resources(struct pci_dev *pdev)
 
 static void zpci_unmap_resources(struct pci_dev *pdev)
 {
+       struct zpci_dev *zdev = to_zpci(pdev);
        resource_size_t len;
        int i;
 
-       if (static_branch_likely(&have_mio))
+       if (zpci_use_mio(zdev))
                return;
 
        for (i = 0; i < PCI_BAR_COUNT; i++) {
                len = pci_resource_len(pdev, i);
                if (!len)
                        continue;
-               pci_iounmap(pdev, (void __iomem __force *)
-                           pdev->resource[i].start);
+               pci_iounmap_fh(pdev, (void __iomem __force *)
+                              pdev->resource[i].start);
        }
 }
 
@@ -528,7 +529,7 @@ static int zpci_setup_bus_resources(struct zpci_dev *zdev,
                if (zdev->bars[i].val & 4)
                        flags |= IORESOURCE_MEM_64;
 
-               if (static_branch_likely(&have_mio))
+               if (zpci_use_mio(zdev))
                        addr = (unsigned long) zdev->bars[i].mio_wb;
                else
                        addr = ZPCI_ADDR(entry);