diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2012-02-23 22:19:00 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2012-02-23 22:19:00 -0500 |
commit | 0efd5aab41e18a1175f72641696cfda154ba6c87 (patch) | |
tree | 2480b5ade8937d18104c5ecc1423ca1eac1b154e /drivers/pci/probe.c | |
parent | 5a21d70dbd33d20713fb735ad9381711b0ae2c9b (diff) |
PCI: add struct pci_host_bridge_window with CPU/bus address offset
Some PCI host bridges apply an address offset, so bus addresses on PCI are
different from CPU addresses. This patch adds a way for architectures to
tell the PCI core about this offset. For example:
LIST_HEAD(resources);
pci_add_resource_offset(&resources, host->io_space, host->io_offset);
pci_add_resource_offset(&resources, host->mem_space, host->mem_offset);
pci_scan_root_bus(parent, bus, ops, sysdata, &resources);
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r-- | drivers/pci/probe.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 3a30023a123c..3f07cb6bae32 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -1562,12 +1562,15 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) | |||
1562 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | 1562 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, |
1563 | struct pci_ops *ops, void *sysdata, struct list_head *resources) | 1563 | struct pci_ops *ops, void *sysdata, struct list_head *resources) |
1564 | { | 1564 | { |
1565 | int error, i; | 1565 | int error; |
1566 | struct pci_host_bridge *bridge; | 1566 | struct pci_host_bridge *bridge; |
1567 | struct pci_bus *b, *b2; | 1567 | struct pci_bus *b, *b2; |
1568 | struct device *dev; | 1568 | struct device *dev; |
1569 | struct pci_bus_resource *bus_res, *n; | 1569 | struct pci_host_bridge_window *window, *n; |
1570 | struct resource *res; | 1570 | struct resource *res; |
1571 | resource_size_t offset; | ||
1572 | char bus_addr[64]; | ||
1573 | char *fmt; | ||
1571 | 1574 | ||
1572 | bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); | 1575 | bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); |
1573 | if (!bridge) | 1576 | if (!bridge) |
@@ -1617,19 +1620,30 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
1617 | b->number = b->secondary = bus; | 1620 | b->number = b->secondary = bus; |
1618 | 1621 | ||
1619 | bridge->bus = b; | 1622 | bridge->bus = b; |
1620 | 1623 | INIT_LIST_HEAD(&bridge->windows); | |
1621 | /* Add initial resources to the bus */ | ||
1622 | list_for_each_entry_safe(bus_res, n, resources, list) | ||
1623 | list_move_tail(&bus_res->list, &b->resources); | ||
1624 | 1624 | ||
1625 | if (parent) | 1625 | if (parent) |
1626 | dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev)); | 1626 | dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev)); |
1627 | else | 1627 | else |
1628 | printk(KERN_INFO "PCI host bridge to bus %s\n", dev_name(&b->dev)); | 1628 | printk(KERN_INFO "PCI host bridge to bus %s\n", dev_name(&b->dev)); |
1629 | 1629 | ||
1630 | pci_bus_for_each_resource(b, res, i) { | 1630 | /* Add initial resources to the bus */ |
1631 | if (res) | 1631 | list_for_each_entry_safe(window, n, resources, list) { |
1632 | dev_info(&b->dev, "root bus resource %pR\n", res); | 1632 | list_move_tail(&window->list, &bridge->windows); |
1633 | res = window->res; | ||
1634 | offset = window->offset; | ||
1635 | pci_bus_add_resource(b, res, 0); | ||
1636 | if (offset) { | ||
1637 | if (resource_type(res) == IORESOURCE_IO) | ||
1638 | fmt = " (bus address [%#06llx-%#06llx])"; | ||
1639 | else | ||
1640 | fmt = " (bus address [%#010llx-%#010llx])"; | ||
1641 | snprintf(bus_addr, sizeof(bus_addr), fmt, | ||
1642 | (unsigned long long) (res->start - offset), | ||
1643 | (unsigned long long) (res->end - offset)); | ||
1644 | } else | ||
1645 | bus_addr[0] = '\0'; | ||
1646 | dev_info(&b->dev, "root bus resource %pR%s\n", res, bus_addr); | ||
1633 | } | 1647 | } |
1634 | 1648 | ||
1635 | down_write(&pci_bus_sem); | 1649 | down_write(&pci_bus_sem); |