OSDN Git Service

Merge branches 'pci/aspm', 'pci/enumeration', 'pci/hotplug', 'pci/misc', 'pci/msi...
[uclinux-h8/linux.git] / drivers / pci / probe.c
index 6675a7a..cefd636 100644 (file)
@@ -254,8 +254,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
        }
 
        if (res->flags & IORESOURCE_MEM_64) {
-               if ((sizeof(dma_addr_t) < 8 || sizeof(resource_size_t) < 8) &&
-                   sz64 > 0x100000000ULL) {
+               if ((sizeof(pci_bus_addr_t) < 8 || sizeof(resource_size_t) < 8)
+                   && sz64 > 0x100000000ULL) {
                        res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
                        res->start = 0;
                        res->end = 0;
@@ -264,7 +264,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
                        goto out;
                }
 
-               if ((sizeof(dma_addr_t) < 8) && l) {
+               if ((sizeof(pci_bus_addr_t) < 8) && l) {
                        /* Above 32-bit boundary; try to reallocate */
                        res->flags |= IORESOURCE_UNSET;
                        res->start = 0;
@@ -399,7 +399,7 @@ static void pci_read_bridge_mmio_pref(struct pci_bus *child)
        struct pci_dev *dev = child->self;
        u16 mem_base_lo, mem_limit_lo;
        u64 base64, limit64;
-       dma_addr_t base, limit;
+       pci_bus_addr_t base, limit;
        struct pci_bus_region region;
        struct resource *res;
 
@@ -426,8 +426,8 @@ static void pci_read_bridge_mmio_pref(struct pci_bus *child)
                }
        }
 
-       base = (dma_addr_t) base64;
-       limit = (dma_addr_t) limit64;
+       base = (pci_bus_addr_t) base64;
+       limit = (pci_bus_addr_t) limit64;
 
        if (base != base64) {
                dev_err(&dev->dev, "can't handle bridge window above 4GB (bus address %#010llx)\n",
@@ -973,6 +973,8 @@ void set_pcie_port_type(struct pci_dev *pdev)
 {
        int pos;
        u16 reg16;
+       int type;
+       struct pci_dev *parent;
 
        pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
        if (!pos)
@@ -982,6 +984,22 @@ void set_pcie_port_type(struct pci_dev *pdev)
        pdev->pcie_flags_reg = reg16;
        pci_read_config_word(pdev, pos + PCI_EXP_DEVCAP, &reg16);
        pdev->pcie_mpss = reg16 & PCI_EXP_DEVCAP_PAYLOAD;
+
+       /*
+        * A Root Port is always the upstream end of a Link.  No PCIe
+        * component has two Links.  Two Links are connected by a Switch
+        * that has a Port on each Link and internal logic to connect the
+        * two Ports.
+        */
+       type = pci_pcie_type(pdev);
+       if (type == PCI_EXP_TYPE_ROOT_PORT)
+               pdev->has_secondary_link = 1;
+       else if (type == PCI_EXP_TYPE_UPSTREAM ||
+                type == PCI_EXP_TYPE_DOWNSTREAM) {
+               parent = pci_upstream_bridge(pdev);
+               if (!parent->has_secondary_link)
+                       pdev->has_secondary_link = 1;
+       }
 }
 
 void set_pcie_hotplug_bridge(struct pci_dev *pdev)
@@ -1085,6 +1103,22 @@ int pci_cfg_space_size(struct pci_dev *dev)
 
 #define LEGACY_IO_RESOURCE     (IORESOURCE_IO | IORESOURCE_PCI_FIXED)
 
+static void pci_msi_setup_pci_dev(struct pci_dev *dev)
+{
+       /*
+        * Disable the MSI hardware to avoid screaming interrupts
+        * during boot.  This is the power on reset default so
+        * usually this should be a noop.
+        */
+       dev->msi_cap = pci_find_capability(dev, PCI_CAP_ID_MSI);
+       if (dev->msi_cap)
+               pci_msi_set_enable(dev, 0);
+
+       dev->msix_cap = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+       if (dev->msix_cap)
+               pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0);
+}
+
 /**
  * pci_setup_device - fill in class and map information of a device
  * @dev: the device structure to fill
@@ -1140,6 +1174,8 @@ int pci_setup_device(struct pci_dev *dev)
        /* "Unknown power state" */
        dev->current_state = PCI_UNKNOWN;
 
+       pci_msi_setup_pci_dev(dev);
+
        /* Early fixups, before probing the BARs */
        pci_fixup_device(pci_fixup_early, dev);
        /* device class may be changed after fixup */
@@ -1611,7 +1647,7 @@ static int only_one_child(struct pci_bus *bus)
                return 0;
        if (pci_pcie_type(parent) == PCI_EXP_TYPE_ROOT_PORT)
                return 1;
-       if (pci_pcie_type(parent) == PCI_EXP_TYPE_DOWNSTREAM &&
+       if (parent->has_secondary_link &&
            !pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS))
                return 1;
        return 0;
@@ -2094,25 +2130,6 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
 }
 EXPORT_SYMBOL(pci_scan_root_bus);
 
-/* Deprecated; use pci_scan_root_bus() instead */
-struct pci_bus *pci_scan_bus_parented(struct device *parent,
-               int bus, struct pci_ops *ops, void *sysdata)
-{
-       LIST_HEAD(resources);
-       struct pci_bus *b;
-
-       pci_add_resource(&resources, &ioport_resource);
-       pci_add_resource(&resources, &iomem_resource);
-       pci_add_resource(&resources, &busn_resource);
-       b = pci_create_root_bus(parent, bus, ops, sysdata, &resources);
-       if (b)
-               pci_scan_child_bus(b);
-       else
-               pci_free_resource_list(&resources);
-       return b;
-}
-EXPORT_SYMBOL(pci_scan_bus_parented);
-
 struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
                                        void *sysdata)
 {