crypto: caam - fix signals handling
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / pci / probe.c
index 70f10fa3c1b216ab88e04471c171d8404f107770..2d7cd0c080d3b03396a5d1cd4d19abedecf88646 100644 (file)
@@ -210,14 +210,17 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
                res->flags |= IORESOURCE_SIZEALIGN;
                if (res->flags & IORESOURCE_IO) {
                        l &= PCI_BASE_ADDRESS_IO_MASK;
+                       sz &= PCI_BASE_ADDRESS_IO_MASK;
                        mask = PCI_BASE_ADDRESS_IO_MASK & (u32) IO_SPACE_LIMIT;
                } else {
                        l &= PCI_BASE_ADDRESS_MEM_MASK;
+                       sz &= PCI_BASE_ADDRESS_MEM_MASK;
                        mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
                }
        } else {
                res->flags |= (l & IORESOURCE_ROM_ENABLE);
                l &= PCI_ROM_ADDRESS_MASK;
+               sz &= PCI_ROM_ADDRESS_MASK;
                mask = (u32)PCI_ROM_ADDRESS_MASK;
        }
 
@@ -289,6 +292,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);
@@ -978,6 +984,7 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev)
 int pci_setup_device(struct pci_dev *dev)
 {
        u32 class;
+       u16 cmd;
        u8 hdr_type;
        struct pci_slot *slot;
        int pos = 0;
@@ -1025,6 +1032,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)
@@ -1703,12 +1720,16 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
        bridge->dev.release = pci_release_bus_bridge_dev;
        dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
        error = pcibios_root_bridge_prepare(bridge);
-       if (error)
-               goto bridge_dev_reg_err;
+       if (error) {
+               kfree(bridge);
+               goto err_out;
+       }
 
        error = device_register(&bridge->dev);
-       if (error)
-               goto bridge_dev_reg_err;
+       if (error) {
+               put_device(&bridge->dev);
+               goto err_out;
+       }
        b->bridge = get_device(&bridge->dev);
        device_enable_async_suspend(b->bridge);
        pci_set_bus_of_node(b);
@@ -1764,8 +1785,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 class_dev_reg_err:
        put_device(&bridge->dev);
        device_unregister(&bridge->dev);
-bridge_dev_reg_err:
-       kfree(bridge);
 err_out:
        kfree(b);
        return NULL;