Merge tag 'lsk-v4.4-16.06-android'
[firefly-linux-kernel-4.4.55.git] / drivers / pci / probe.c
index edb1984201e9702162321c50f33f76ba362bac5a..9757cf9037a2b0e9e917ac454b0f107e0e3b3b04 100644 (file)
@@ -319,6 +319,9 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
 {
        unsigned int pos, reg;
 
+       if (dev->non_compliant_bars)
+               return;
+
        for (pos = 0; pos < howmany; pos++) {
                struct resource *res = &dev->resource[pos];
                reg = PCI_BASE_ADDRESS_0 + (pos << 2);
@@ -1174,6 +1177,7 @@ void pci_msi_setup_pci_dev(struct pci_dev *dev)
 int pci_setup_device(struct pci_dev *dev)
 {
        u32 class;
+       u16 cmd;
        u8 hdr_type;
        int pos = 0;
        struct pci_bus_region region;
@@ -1219,6 +1223,16 @@ int pci_setup_device(struct pci_dev *dev)
        /* device class may be changed after fixup */
        class = dev->class >> 8;
 
+       if (dev->non_compliant_bars) {
+               pci_read_config_word(dev, PCI_COMMAND, &cmd);
+               if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
+                       dev_info(&dev->dev, "device has non-compliant BARs; disabling IO/MEM decoding\n");
+                       cmd &= ~PCI_COMMAND_IO;
+                       cmd &= ~PCI_COMMAND_MEMORY;
+                       pci_write_config_word(dev, PCI_COMMAND, cmd);
+               }
+       }
+
        switch (dev->hdr_type) {                    /* header type */
        case PCI_HEADER_TYPE_NORMAL:                /* standard header */
                if (class == PCI_CLASS_BRIDGE_PCI)