summaryrefslogtreecommitdiff
path: root/drivers/pci/setup-bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/setup-bus.c')
-rw-r--r--drivers/pci/setup-bus.c171
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, &region, 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, &region, 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, &region, 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, &region, 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: