diff options
Diffstat (limited to 'drivers/pci/setup-bus.c')
| -rw-r--r-- | drivers/pci/setup-bus.c | 171 |
1 files changed, 7 insertions, 164 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 3cc26fede31a..e680f75a5b5e 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -67,10 +67,9 @@ static void pci_dev_res_free_list(struct list_head *head) * @add_size: Additional size to be optionally added to the resource * @min_align: Minimum memory window alignment */ -static int pci_dev_res_add_to_list(struct list_head *head, struct pci_dev *dev, - struct resource *res, - resource_size_t add_size, - resource_size_t min_align) +int pci_dev_res_add_to_list(struct list_head *head, struct pci_dev *dev, + struct resource *res, resource_size_t add_size, + resource_size_t min_align) { struct pci_dev_resource *tmp; @@ -773,61 +772,6 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus, __assign_resources_sorted(&head, realloc_head, fail_head); } -void pci_setup_cardbus(struct pci_bus *bus) -{ - struct pci_dev *bridge = bus->self; - struct resource *res; - struct pci_bus_region region; - - pci_info(bridge, "CardBus bridge to %pR\n", - &bus->busn_res); - - res = bus->resource[0]; - pcibios_resource_to_bus(bridge->bus, ®ion, res); - if (resource_assigned(res) && res->flags & IORESOURCE_IO) { - /* - * The IO resource is allocated a range twice as large as it - * would normally need. This allows us to set both IO regs. - */ - pci_info(bridge, " bridge window %pR\n", res); - pci_write_config_dword(bridge, PCI_CB_IO_BASE_0, - region.start); - pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0, - region.end); - } - - res = bus->resource[1]; - pcibios_resource_to_bus(bridge->bus, ®ion, res); - if (resource_assigned(res) && res->flags & IORESOURCE_IO) { - pci_info(bridge, " bridge window %pR\n", res); - pci_write_config_dword(bridge, PCI_CB_IO_BASE_1, - region.start); - pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1, - region.end); - } - - res = bus->resource[2]; - pcibios_resource_to_bus(bridge->bus, ®ion, res); - if (resource_assigned(res) && res->flags & IORESOURCE_MEM) { - pci_info(bridge, " bridge window %pR\n", res); - pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0, - region.start); - pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0, - region.end); - } - - res = bus->resource[3]; - pcibios_resource_to_bus(bridge->bus, ®ion, res); - if (resource_assigned(res) && res->flags & IORESOURCE_MEM) { - pci_info(bridge, " bridge window %pR\n", res); - pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1, - region.start); - pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1, - region.end); - } -} -EXPORT_SYMBOL(pci_setup_cardbus); - /* * Initialize bridges with base/limit values we have collected. PCI-to-PCI * Bridge Architecture Specification rev. 1.1 (1998) requires that if there @@ -1424,108 +1368,6 @@ static void pbus_size_mem(struct pci_bus *bus, struct resource *b_res, } } -unsigned long pci_cardbus_resource_alignment(struct resource *res) -{ - if (res->flags & IORESOURCE_IO) - return pci_cardbus_io_size; - if (res->flags & IORESOURCE_MEM) - return pci_cardbus_mem_size; - return 0; -} - -static void pci_bus_size_cardbus(struct pci_bus *bus, - struct list_head *realloc_head) -{ - struct pci_dev *bridge = bus->self; - struct resource *b_res; - resource_size_t b_res_3_size = pci_cardbus_mem_size * 2; - u16 ctrl; - - b_res = &bridge->resource[PCI_CB_BRIDGE_IO_0_WINDOW]; - if (resource_assigned(b_res)) - goto handle_b_res_1; - /* - * Reserve some resources for CardBus. We reserve a fixed amount - * of bus space for CardBus bridges. - */ - resource_set_range(b_res, pci_cardbus_io_size, pci_cardbus_io_size); - b_res->flags |= IORESOURCE_IO | IORESOURCE_STARTALIGN; - if (realloc_head) { - b_res->end -= pci_cardbus_io_size; - pci_dev_res_add_to_list(realloc_head, bridge, b_res, - pci_cardbus_io_size, - pci_cardbus_io_size); - } - -handle_b_res_1: - b_res = &bridge->resource[PCI_CB_BRIDGE_IO_1_WINDOW]; - if (resource_assigned(b_res)) - goto handle_b_res_2; - resource_set_range(b_res, pci_cardbus_io_size, pci_cardbus_io_size); - b_res->flags |= IORESOURCE_IO | IORESOURCE_STARTALIGN; - if (realloc_head) { - b_res->end -= pci_cardbus_io_size; - pci_dev_res_add_to_list(realloc_head, bridge, b_res, - pci_cardbus_io_size, - pci_cardbus_io_size); - } - -handle_b_res_2: - /* MEM1 must not be pref MMIO */ - pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); - if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM1) { - ctrl &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM1; - pci_write_config_word(bridge, PCI_CB_BRIDGE_CONTROL, ctrl); - pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); - } - - /* Check whether prefetchable memory is supported by this bridge. */ - pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); - if (!(ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0)) { - ctrl |= PCI_CB_BRIDGE_CTL_PREFETCH_MEM0; - pci_write_config_word(bridge, PCI_CB_BRIDGE_CONTROL, ctrl); - pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); - } - - b_res = &bridge->resource[PCI_CB_BRIDGE_MEM_0_WINDOW]; - if (resource_assigned(b_res)) - goto handle_b_res_3; - /* - * If we have prefetchable memory support, allocate two regions. - * Otherwise, allocate one region of twice the size. - */ - if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) { - resource_set_range(b_res, pci_cardbus_mem_size, - pci_cardbus_mem_size); - b_res->flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | - IORESOURCE_STARTALIGN; - if (realloc_head) { - b_res->end -= pci_cardbus_mem_size; - pci_dev_res_add_to_list(realloc_head, bridge, b_res, - pci_cardbus_mem_size, - pci_cardbus_mem_size); - } - - /* Reduce that to half */ - b_res_3_size = pci_cardbus_mem_size; - } - -handle_b_res_3: - b_res = &bridge->resource[PCI_CB_BRIDGE_MEM_1_WINDOW]; - if (resource_assigned(b_res)) - goto handle_done; - resource_set_range(b_res, pci_cardbus_mem_size, b_res_3_size); - b_res->flags |= IORESOURCE_MEM | IORESOURCE_STARTALIGN; - if (realloc_head) { - b_res->end -= b_res_3_size; - pci_dev_res_add_to_list(realloc_head, bridge, b_res, - b_res_3_size, pci_cardbus_mem_size); - } - -handle_done: - ; -} - void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) { struct pci_dev *dev; @@ -1542,7 +1384,8 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) switch (dev->hdr_type) { case PCI_HEADER_TYPE_CARDBUS: - pci_bus_size_cardbus(b, realloc_head); + if (pci_bus_size_cardbus_bridge(b, realloc_head)) + continue; break; case PCI_HEADER_TYPE_BRIDGE: @@ -1666,7 +1509,7 @@ void __pci_bus_assign_resources(const struct pci_bus *bus, break; case PCI_HEADER_TYPE_CARDBUS: - pci_setup_cardbus(b); + pci_setup_cardbus_bridge(b); break; default: @@ -1771,7 +1614,7 @@ static void __pci_bridge_assign_resources(const struct pci_dev *bridge, break; case PCI_CLASS_BRIDGE_CARDBUS: - pci_setup_cardbus(b); + pci_setup_cardbus_bridge(b); break; default: |
