aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci_fire.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-05-08 02:06:27 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-05-08 19:41:24 -0400
commit34768bc8329194b14e42ee408a84edfa40059046 (patch)
tree3fff53138966f3a58e796a71c19a3b75de86fbf7 /arch/sparc64/kernel/pci_fire.c
parent5a4a3e592d0d66653297049373caa7ac5b4febe0 (diff)
[SPARC64] PCI: Use root list of pbm's instead of pci_controller_info's
The idea is to move more and more things into the pbm, with the eventual goal of eliminating the pci_controller_info entirely as there really isn't any need for it. This stage of the transformations requires some reworking of the PCI error interrupt handling. It might be tricky to get rid of the pci_controller_info parenting for a few reasons: 1) When we get an uncorrectable or correctable error we want to interrogate the IOMMU and streaming cache of both PBMs for error status. These errors come from the UPA front-end which is shared between the two PBM PCI bus segments. Historically speaking this is why I choose the datastructure hierarchy of pci_controller_info-->pci_pbm_info 2) The probing does a portid/devhandle match to look for the 'other' pbm, but this is entirely an artifact and can be eliminated trivially. What we could do to solve #1 is to have a "buddy" pointer from one pbm to another. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/pci_fire.c')
-rw-r--r--arch/sparc64/kernel/pci_fire.c39
1 files changed, 10 insertions, 29 deletions
diff --git a/arch/sparc64/kernel/pci_fire.c b/arch/sparc64/kernel/pci_fire.c
index 79ee5be948eb..f55c08ae0aa0 100644
--- a/arch/sparc64/kernel/pci_fire.c
+++ b/arch/sparc64/kernel/pci_fire.c
@@ -160,21 +160,9 @@ static struct pci_ops pci_fire_ops = {
160 .write = fire_write_pci_cfg, 160 .write = fire_write_pci_cfg,
161}; 161};
162 162
163static void pbm_scan_bus(struct pci_controller_info *p, 163static void pci_fire_scan_bus(struct pci_pbm_info *pbm)
164 struct pci_pbm_info *pbm)
165{ 164{
166 pbm->pci_bus = pci_scan_one_pbm(pbm); 165 pbm->pci_bus = pci_scan_one_pbm(pbm);
167}
168
169static void pci_fire_scan_bus(struct pci_controller_info *p)
170{
171 struct device_node *dp;
172
173 if ((dp = p->pbm_A.prom_node) != NULL)
174 pbm_scan_bus(p, &p->pbm_A);
175
176 if ((dp = p->pbm_B.prom_node) != NULL)
177 pbm_scan_bus(p, &p->pbm_B);
178 166
179 /* XXX register error interrupt handlers XXX */ 167 /* XXX register error interrupt handlers XXX */
180} 168}
@@ -313,7 +301,7 @@ static void pci_fire_hw_init(struct pci_pbm_info *pbm)
313} 301}
314 302
315static void pci_fire_pbm_init(struct pci_controller_info *p, 303static void pci_fire_pbm_init(struct pci_controller_info *p,
316 struct device_node *dp, u32 portid) 304 struct device_node *dp, u32 portid)
317{ 305{
318 const struct linux_prom64_registers *regs; 306 const struct linux_prom64_registers *regs;
319 struct pci_pbm_info *pbm; 307 struct pci_pbm_info *pbm;
@@ -323,6 +311,11 @@ static void pci_fire_pbm_init(struct pci_controller_info *p,
323 else 311 else
324 pbm = &p->pbm_B; 312 pbm = &p->pbm_B;
325 313
314 pbm->next = pci_pbm_root;
315 pci_pbm_root = pbm;
316
317 pbm->scan_bus = pci_fire_scan_bus;
318
326 pbm->portid = portid; 319 pbm->portid = portid;
327 pbm->parent = p; 320 pbm->parent = p;
328 pbm->prom_node = dp; 321 pbm->prom_node = dp;
@@ -354,19 +347,11 @@ void fire_pci_init(struct device_node *dp, const char *model_name)
354 struct pci_controller_info *p; 347 struct pci_controller_info *p;
355 u32 portid = of_getintprop_default(dp, "portid", 0xff); 348 u32 portid = of_getintprop_default(dp, "portid", 0xff);
356 struct iommu *iommu; 349 struct iommu *iommu;
350 struct pci_pbm_info *pbm;
357 351
358 for (p = pci_controller_root; p; p = p->next) { 352 for (pbm = pci_pbm_root; pbm; pbm = pbm->next) {
359 struct pci_pbm_info *pbm;
360
361 if (p->pbm_A.prom_node && p->pbm_B.prom_node)
362 continue;
363
364 pbm = (p->pbm_A.prom_node ?
365 &p->pbm_A :
366 &p->pbm_B);
367
368 if (portid_compare(pbm->portid, portid)) { 353 if (portid_compare(pbm->portid, portid)) {
369 pci_fire_pbm_init(p, dp, portid); 354 pci_fire_pbm_init(pbm->parent, dp, portid);
370 return; 355 return;
371 } 356 }
372 } 357 }
@@ -387,12 +372,8 @@ void fire_pci_init(struct device_node *dp, const char *model_name)
387 372
388 p->pbm_B.iommu = iommu; 373 p->pbm_B.iommu = iommu;
389 374
390 p->next = pci_controller_root;
391 pci_controller_root = p;
392
393 p->index = pci_num_controllers++; 375 p->index = pci_num_controllers++;
394 376
395 p->scan_bus = pci_fire_scan_bus;
396 /* XXX MSI support XXX */ 377 /* XXX MSI support XXX */
397 p->pci_ops = &pci_fire_ops; 378 p->pci_ops = &pci_fire_ops;
398 379