aboutsummaryrefslogtreecommitdiffstats
path: root/arch/xtensa
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2011-10-28 18:28:19 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2012-01-06 15:11:14 -0500
commit7ec303a7247a46a7a88a4f890466fd12dbdd5dc6 (patch)
tree7fc9f7f177509b99caf43c4103fa3c40e1e50431 /arch/xtensa
parent2cd6975a4ff92a75e46240109d01c1daf4682e5d (diff)
xtensa/PCI: convert to pci_scan_root_bus() for correct root bus resources
Convert from pci_scan_bus() to pci_scan_root_bus() and remove root bus fixups. This fixes the problem of "early" and "header" quirks seeing incorrect root bus resources. This arch was unusual because it filled in bus->resource[0..3] in pcibios_init(), then overwrote them, applied io_space.offset and checked for unset resources in pcibios_fixup_bus(). I moved all of that to a new pci_controller_apertures() that we can use before scanning the root bus. CC: Chris Zankel <chris@zankel.net> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'arch/xtensa')
-rw-r--r--arch/xtensa/kernel/pci.c85
1 files changed, 42 insertions, 43 deletions
diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c
index 644b2d4b299d..61045c192e88 100644
--- a/arch/xtensa/kernel/pci.c
+++ b/arch/xtensa/kernel/pci.c
@@ -134,9 +134,46 @@ struct pci_controller * __init pcibios_alloc_controller(void)
134 return pci_ctrl; 134 return pci_ctrl;
135} 135}
136 136
137static void __init pci_controller_apertures(struct pci_controller *pci_ctrl,
138 struct list_head *resources)
139{
140 struct resource *res;
141 unsigned long io_offset;
142 int i;
143
144 io_offset = (unsigned long)pci_ctrl->io_space.base;
145 res = &pci_ctrl->io_resource;
146 if (!res->flags) {
147 if (io_offset)
148 printk (KERN_ERR "I/O resource not set for host"
149 " bridge %d\n", pci_ctrl->index);
150 res->start = 0;
151 res->end = IO_SPACE_LIMIT;
152 res->flags = IORESOURCE_IO;
153 }
154 res->start += io_offset;
155 res->end += io_offset;
156 pci_add_resource(resources, res);
157
158 for (i = 0; i < 3; i++) {
159 res = &pci_ctrl->mem_resources[i];
160 if (!res->flags) {
161 if (i > 0)
162 continue;
163 printk(KERN_ERR "Memory resource not set for "
164 "host bridge %d\n", pci_ctrl->index);
165 res->start = 0;
166 res->end = ~0U;
167 res->flags = IORESOURCE_MEM;
168 }
169 pci_add_resource(resources, res);
170 }
171}
172
137static int __init pcibios_init(void) 173static int __init pcibios_init(void)
138{ 174{
139 struct pci_controller *pci_ctrl; 175 struct pci_controller *pci_ctrl;
176 struct list_head resources;
140 struct pci_bus *bus; 177 struct pci_bus *bus;
141 int next_busno = 0, i; 178 int next_busno = 0, i;
142 179
@@ -145,19 +182,10 @@ static int __init pcibios_init(void)
145 /* Scan all of the recorded PCI controllers. */ 182 /* Scan all of the recorded PCI controllers. */
146 for (pci_ctrl = pci_ctrl_head; pci_ctrl; pci_ctrl = pci_ctrl->next) { 183 for (pci_ctrl = pci_ctrl_head; pci_ctrl; pci_ctrl = pci_ctrl->next) {
147 pci_ctrl->last_busno = 0xff; 184 pci_ctrl->last_busno = 0xff;
148 bus = pci_scan_bus(pci_ctrl->first_busno, pci_ctrl->ops, 185 INIT_LIST_HEAD(&resources);
149 pci_ctrl); 186 pci_controller_apertures(pci_ctrl, &resources);
150 if (pci_ctrl->io_resource.flags) { 187 bus = pci_scan_root_bus(NULL, pci_ctrl->first_busno,
151 unsigned long offs; 188 pci_ctrl->ops, pci_ctrl, &resources);
152
153 offs = (unsigned long)pci_ctrl->io_space.base;
154 pci_ctrl->io_resource.start += offs;
155 pci_ctrl->io_resource.end += offs;
156 bus->resource[0] = &pci_ctrl->io_resource;
157 }
158 for (i = 0; i < 3; ++i)
159 if (pci_ctrl->mem_resources[i].flags)
160 bus->resource[i+1] =&pci_ctrl->mem_resources[i];
161 pci_ctrl->bus = bus; 189 pci_ctrl->bus = bus;
162 pci_ctrl->last_busno = bus->subordinate; 190 pci_ctrl->last_busno = bus->subordinate;
163 if (next_busno <= pci_ctrl->last_busno) 191 if (next_busno <= pci_ctrl->last_busno)
@@ -178,36 +206,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
178 int i; 206 int i;
179 207
180 io_offset = (unsigned long)pci_ctrl->io_space.base; 208 io_offset = (unsigned long)pci_ctrl->io_space.base;
181 if (bus->parent == NULL) { 209 if (bus->parent) {
182 /* this is a host bridge - fill in its resources */
183 pci_ctrl->bus = bus;
184
185 bus->resource[0] = res = &pci_ctrl->io_resource;
186 if (!res->flags) {
187 if (io_offset)
188 printk (KERN_ERR "I/O resource not set for host"
189 " bridge %d\n", pci_ctrl->index);
190 res->start = 0;
191 res->end = IO_SPACE_LIMIT;
192 res->flags = IORESOURCE_IO;
193 }
194 res->start += io_offset;
195 res->end += io_offset;
196
197 for (i = 0; i < 3; i++) {
198 res = &pci_ctrl->mem_resources[i];
199 if (!res->flags) {
200 if (i > 0)
201 continue;
202 printk(KERN_ERR "Memory resource not set for "
203 "host bridge %d\n", pci_ctrl->index);
204 res->start = 0;
205 res->end = ~0U;
206 res->flags = IORESOURCE_MEM;
207 }
208 bus->resource[i+1] = res;
209 }
210 } else {
211 /* This is a subordinate bridge */ 210 /* This is a subordinate bridge */
212 pci_read_bridge_bases(bus); 211 pci_read_bridge_bases(bus);
213 212