diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2011-10-28 18:25:45 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2012-01-06 15:10:51 -0500 |
commit | 166c6370754a0a92386e2ffb0eeb06e50ac8588d (patch) | |
tree | c9bbbf23a0508cd93d546ecbfdb9fcd423a1e461 | |
parent | a9d9f5276cb3fa08351e8837ab9398bfd8e69a2e (diff) |
PCI: add pci_create_root_bus() that accepts resource list
pci_create_bus() assigns ioport_resource and iomem_resource as the default
bus resources, i.e., the entire address space. Architectures fix these
later, typically in pcibios_fixup_bus() or after pci_scan_bus_parented()
returns, but code that runs in the interim sees incorrect resource
information.
This patch adds a new pci_create_root_bus() that sets the bus resources
correctly from a supplied list of resources.
I intend to remove pci_create_bus() after changing all callers.
Based on original patch by Deng-Cheng Zhu.
Reference: http://www.spinics.net/lists/mips/msg41654.html
Reference: https://lkml.org/lkml/2011/8/26/88
Signed-off-by: Deng-Cheng Zhu <dczhu@mips.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r-- | drivers/pci/probe.c | 25 | ||||
-rw-r--r-- | include/linux/pci.h | 3 |
2 files changed, 24 insertions, 4 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 2f0b14451d9d..89ecded0581b 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -1522,12 +1522,13 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) | |||
1522 | return max; | 1522 | return max; |
1523 | } | 1523 | } |
1524 | 1524 | ||
1525 | struct pci_bus * pci_create_bus(struct device *parent, | 1525 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, |
1526 | int bus, struct pci_ops *ops, void *sysdata) | 1526 | struct pci_ops *ops, void *sysdata, struct list_head *resources) |
1527 | { | 1527 | { |
1528 | int error, i; | 1528 | int error, i; |
1529 | struct pci_bus *b, *b2; | 1529 | struct pci_bus *b, *b2; |
1530 | struct device *dev; | 1530 | struct device *dev; |
1531 | struct pci_bus_resource *bus_res, *n; | ||
1531 | struct resource *res; | 1532 | struct resource *res; |
1532 | 1533 | ||
1533 | b = pci_alloc_bus(); | 1534 | b = pci_alloc_bus(); |
@@ -1578,8 +1579,10 @@ struct pci_bus * pci_create_bus(struct device *parent, | |||
1578 | pci_create_legacy_files(b); | 1579 | pci_create_legacy_files(b); |
1579 | 1580 | ||
1580 | b->number = b->secondary = bus; | 1581 | b->number = b->secondary = bus; |
1581 | b->resource[0] = &ioport_resource; | 1582 | |
1582 | b->resource[1] = &iomem_resource; | 1583 | /* Add initial resources to the bus */ |
1584 | list_for_each_entry_safe(bus_res, n, resources, list) | ||
1585 | list_move_tail(&bus_res->list, &b->resources); | ||
1583 | 1586 | ||
1584 | if (parent) | 1587 | if (parent) |
1585 | dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev)); | 1588 | dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev)); |
@@ -1605,6 +1608,20 @@ err_out: | |||
1605 | return NULL; | 1608 | return NULL; |
1606 | } | 1609 | } |
1607 | 1610 | ||
1611 | struct pci_bus *pci_create_bus(struct device *parent, | ||
1612 | int bus, struct pci_ops *ops, void *sysdata) | ||
1613 | { | ||
1614 | LIST_HEAD(resources); | ||
1615 | struct pci_bus *b; | ||
1616 | |||
1617 | pci_add_resource(&resources, &ioport_resource); | ||
1618 | pci_add_resource(&resources, &iomem_resource); | ||
1619 | b = pci_create_root_bus(parent, bus, ops, sysdata, &resources); | ||
1620 | if (!b) | ||
1621 | pci_free_resource_list(&resources); | ||
1622 | return b; | ||
1623 | } | ||
1624 | |||
1608 | struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, | 1625 | struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, |
1609 | int bus, struct pci_ops *ops, void *sysdata) | 1626 | int bus, struct pci_ops *ops, void *sysdata) |
1610 | { | 1627 | { |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 9daa79901122..eacb1e51e11b 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -670,6 +670,9 @@ static inline struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *o | |||
670 | pci_bus_add_devices(root_bus); | 670 | pci_bus_add_devices(root_bus); |
671 | return root_bus; | 671 | return root_bus; |
672 | } | 672 | } |
673 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | ||
674 | struct pci_ops *ops, void *sysdata, | ||
675 | struct list_head *resources); | ||
673 | struct pci_bus *pci_create_bus(struct device *parent, int bus, | 676 | struct pci_bus *pci_create_bus(struct device *parent, int bus, |
674 | struct pci_ops *ops, void *sysdata); | 677 | struct pci_ops *ops, void *sysdata); |
675 | struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, | 678 | struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, |