PCI: Make PCI_ROM_ADDRESS_MASK a 32-bit constant
[GitHub/exynos8895/android_kernel_samsung_universal8895.git] / drivers / pci / setup-res.c
index 604011e047d60b9db26e40e54769aeb7a957f53e..8b2f8b2a574e3dc1226aeaad3ea918a25ff6e527 100644 (file)
 #include <linux/slab.h>
 #include "pci.h"
 
-
-void pci_update_resource(struct pci_dev *dev, int resno)
+static void pci_std_update_resource(struct pci_dev *dev, int resno)
 {
        struct pci_bus_region region;
        bool disable;
        u16 cmd;
        u32 new, check, mask;
        int reg;
-       enum pci_bar_type type;
        struct resource *res = dev->resource + resno;
 
-       if (dev->is_virtfn) {
-               dev_warn(&dev->dev, "can't update VF BAR%d\n", resno);
+       /* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */
+       if (dev->is_virtfn)
                return;
-       }
 
        /*
         * Ignore resources for unimplemented BARs and unused resource slots
@@ -60,21 +57,34 @@ void pci_update_resource(struct pci_dev *dev, int resno)
                return;
 
        pcibios_resource_to_bus(dev->bus, &region, res);
+       new = region.start;
 
-       new = region.start | (res->flags & PCI_REGION_FLAG_MASK);
-       if (res->flags & IORESOURCE_IO)
+       if (res->flags & IORESOURCE_IO) {
                mask = (u32)PCI_BASE_ADDRESS_IO_MASK;
-       else
+               new |= res->flags & ~PCI_BASE_ADDRESS_IO_MASK;
+       } else if (resno == PCI_ROM_RESOURCE) {
+               mask = PCI_ROM_ADDRESS_MASK;
+       } else {
                mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
+               new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK;
+       }
 
-       reg = pci_resource_bar(dev, resno, &type);
-       if (!reg)
-               return;
-       if (type != pci_bar_unknown) {
+       if (resno < PCI_ROM_RESOURCE) {
+               reg = PCI_BASE_ADDRESS_0 + 4 * resno;
+       } else if (resno == PCI_ROM_RESOURCE) {
+
+               /*
+                * Apparently some Matrox devices have ROM BARs that read
+                * as zero when disabled, so don't update ROM BARs unless
+                * they're enabled.  See https://lkml.org/lkml/2005/8/30/138.
+                */
                if (!(res->flags & IORESOURCE_ROM_ENABLE))
                        return;
+
+               reg = dev->rom_base_reg;
                new |= PCI_ROM_ADDRESS_ENABLE;
-       }
+       } else
+               return;
 
        /*
         * We can't update a 64-bit BAR atomically, so when possible,
@@ -110,6 +120,16 @@ void pci_update_resource(struct pci_dev *dev, int resno)
                pci_write_config_word(dev, PCI_COMMAND, cmd);
 }
 
+void pci_update_resource(struct pci_dev *dev, int resno)
+{
+       if (resno <= PCI_ROM_RESOURCE)
+               pci_std_update_resource(dev, resno);
+#ifdef CONFIG_PCI_IOV
+       else if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END)
+               pci_iov_update_resource(dev, resno);
+#endif
+}
+
 int pci_claim_resource(struct pci_dev *dev, int resource)
 {
        struct resource *res = &dev->resource[resource];