diff options
| -rw-r--r-- | arch/mips/pci/pci.c | 80 |
1 files changed, 53 insertions, 27 deletions
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index c7fe6ec621e6..a377e9d2d029 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c | |||
| @@ -34,6 +34,8 @@ static struct pci_controller *hose_head, **hose_tail = &hose_head; | |||
| 34 | unsigned long PCIBIOS_MIN_IO = 0x0000; | 34 | unsigned long PCIBIOS_MIN_IO = 0x0000; |
| 35 | unsigned long PCIBIOS_MIN_MEM = 0; | 35 | unsigned long PCIBIOS_MIN_MEM = 0; |
| 36 | 36 | ||
| 37 | static int pci_initialized; | ||
| 38 | |||
| 37 | /* | 39 | /* |
| 38 | * We need to avoid collisions with `mirrored' VGA ports | 40 | * We need to avoid collisions with `mirrored' VGA ports |
| 39 | * and other strange ISA hardware, so we always want the | 41 | * and other strange ISA hardware, so we always want the |
| @@ -74,6 +76,42 @@ pcibios_align_resource(void *data, struct resource *res, | |||
| 74 | res->start = start; | 76 | res->start = start; |
| 75 | } | 77 | } |
| 76 | 78 | ||
| 79 | static void __devinit pcibios_scanbus(struct pci_controller *hose) | ||
| 80 | { | ||
| 81 | static int next_busno; | ||
| 82 | static int need_domain_info; | ||
| 83 | struct pci_bus *bus; | ||
| 84 | |||
| 85 | if (!hose->iommu) | ||
| 86 | PCI_DMA_BUS_IS_PHYS = 1; | ||
| 87 | |||
| 88 | if (hose->get_busno && pci_probe_only) | ||
| 89 | next_busno = (*hose->get_busno)(); | ||
| 90 | |||
| 91 | bus = pci_scan_bus(next_busno, hose->pci_ops, hose); | ||
| 92 | hose->bus = bus; | ||
| 93 | |||
| 94 | need_domain_info = need_domain_info || hose->index; | ||
| 95 | hose->need_domain_info = need_domain_info; | ||
| 96 | if (bus) { | ||
| 97 | next_busno = bus->subordinate + 1; | ||
| 98 | /* Don't allow 8-bit bus number overflow inside the hose - | ||
| 99 | reserve some space for bridges. */ | ||
| 100 | if (next_busno > 224) { | ||
| 101 | next_busno = 0; | ||
| 102 | need_domain_info = 1; | ||
| 103 | } | ||
| 104 | |||
| 105 | if (!pci_probe_only) { | ||
| 106 | pci_bus_size_bridges(bus); | ||
| 107 | pci_bus_assign_resources(bus); | ||
| 108 | pci_enable_bridges(bus); | ||
| 109 | } | ||
| 110 | } | ||
| 111 | } | ||
| 112 | |||
| 113 | static DEFINE_MUTEX(pci_scan_mutex); | ||
| 114 | |||
| 77 | void __devinit register_pci_controller(struct pci_controller *hose) | 115 | void __devinit register_pci_controller(struct pci_controller *hose) |
| 78 | { | 116 | { |
| 79 | if (request_resource(&iomem_resource, hose->mem_resource) < 0) | 117 | if (request_resource(&iomem_resource, hose->mem_resource) < 0) |
| @@ -93,6 +131,17 @@ void __devinit register_pci_controller(struct pci_controller *hose) | |||
| 93 | printk(KERN_WARNING | 131 | printk(KERN_WARNING |
| 94 | "registering PCI controller with io_map_base unset\n"); | 132 | "registering PCI controller with io_map_base unset\n"); |
| 95 | } | 133 | } |
| 134 | |||
| 135 | /* | ||
| 136 | * Scan the bus if it is register after the PCI subsystem | ||
| 137 | * initialization. | ||
| 138 | */ | ||
| 139 | if (pci_initialized) { | ||
| 140 | mutex_lock(&pci_scan_mutex); | ||
| 141 | pcibios_scanbus(hose); | ||
| 142 | mutex_unlock(&pci_scan_mutex); | ||
| 143 | } | ||
| 144 | |||
| 96 | return; | 145 | return; |
| 97 | 146 | ||
| 98 | out: | 147 | out: |
| @@ -125,38 +174,15 @@ static u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp) | |||
| 125 | static int __init pcibios_init(void) | 174 | static int __init pcibios_init(void) |
| 126 | { | 175 | { |
| 127 | struct pci_controller *hose; | 176 | struct pci_controller *hose; |
| 128 | struct pci_bus *bus; | ||
| 129 | int next_busno; | ||
| 130 | int need_domain_info = 0; | ||
| 131 | 177 | ||
| 132 | /* Scan all of the recorded PCI controllers. */ | 178 | /* Scan all of the recorded PCI controllers. */ |
| 133 | for (next_busno = 0, hose = hose_head; hose; hose = hose->next) { | 179 | for (hose = hose_head; hose; hose = hose->next) |
| 134 | 180 | pcibios_scanbus(hose); | |
| 135 | if (!hose->iommu) | ||
| 136 | PCI_DMA_BUS_IS_PHYS = 1; | ||
| 137 | |||
| 138 | if (hose->get_busno && pci_probe_only) | ||
| 139 | next_busno = (*hose->get_busno)(); | ||
| 140 | |||
| 141 | bus = pci_scan_bus(next_busno, hose->pci_ops, hose); | ||
| 142 | hose->bus = bus; | ||
| 143 | need_domain_info = need_domain_info || hose->index; | ||
| 144 | hose->need_domain_info = need_domain_info; | ||
| 145 | if (bus) { | ||
| 146 | next_busno = bus->subordinate + 1; | ||
| 147 | /* Don't allow 8-bit bus number overflow inside the hose - | ||
| 148 | reserve some space for bridges. */ | ||
| 149 | if (next_busno > 224) { | ||
| 150 | next_busno = 0; | ||
| 151 | need_domain_info = 1; | ||
| 152 | } | ||
| 153 | } | ||
| 154 | } | ||
| 155 | 181 | ||
| 156 | if (!pci_probe_only) | ||
| 157 | pci_assign_unassigned_resources(); | ||
| 158 | pci_fixup_irqs(common_swizzle, pcibios_map_irq); | 182 | pci_fixup_irqs(common_swizzle, pcibios_map_irq); |
| 159 | 183 | ||
| 184 | pci_initialized = 1; | ||
| 185 | |||
| 160 | return 0; | 186 | return 0; |
| 161 | } | 187 | } |
| 162 | 188 | ||
