aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci_sun4v.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_sun4v.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_sun4v.c')
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c47
1 files changed, 13 insertions, 34 deletions
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index 1491ba330583..0a101cb22320 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -677,29 +677,15 @@ static struct pci_ops pci_sun4v_ops = {
677}; 677};
678 678
679 679
680static void pbm_scan_bus(struct pci_controller_info *p, 680static void pci_sun4v_scan_bus(struct pci_pbm_info *pbm)
681 struct pci_pbm_info *pbm)
682{
683 pbm->pci_bus = pci_scan_one_pbm(pbm);
684}
685
686static void pci_sun4v_scan_bus(struct pci_controller_info *p)
687{ 681{
688 struct property *prop; 682 struct property *prop;
689 struct device_node *dp; 683 struct device_node *dp;
690 684
691 if ((dp = p->pbm_A.prom_node) != NULL) { 685 dp = pbm->prom_node;
692 prop = of_find_property(dp, "66mhz-capable", NULL); 686 prop = of_find_property(dp, "66mhz-capable", NULL);
693 p->pbm_A.is_66mhz_capable = (prop != NULL); 687 pbm->is_66mhz_capable = (prop != NULL);
694 688 pbm->pci_bus = pci_scan_one_pbm(pbm);
695 pbm_scan_bus(p, &p->pbm_A);
696 }
697 if ((dp = p->pbm_B.prom_node) != NULL) {
698 prop = of_find_property(dp, "66mhz-capable", NULL);
699 p->pbm_B.is_66mhz_capable = (prop != NULL);
700
701 pbm_scan_bus(p, &p->pbm_B);
702 }
703 689
704 /* XXX register error interrupt handlers XXX */ 690 /* XXX register error interrupt handlers XXX */
705} 691}
@@ -1246,6 +1232,11 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node
1246 else 1232 else
1247 pbm = &p->pbm_A; 1233 pbm = &p->pbm_A;
1248 1234
1235 pbm->next = pci_pbm_root;
1236 pci_pbm_root = pbm;
1237
1238 pbm->scan_bus = pci_sun4v_scan_bus;
1239
1249 pbm->parent = p; 1240 pbm->parent = p;
1250 pbm->prom_node = dp; 1241 pbm->prom_node = dp;
1251 1242
@@ -1265,6 +1256,7 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node
1265void sun4v_pci_init(struct device_node *dp, char *model_name) 1256void sun4v_pci_init(struct device_node *dp, char *model_name)
1266{ 1257{
1267 struct pci_controller_info *p; 1258 struct pci_controller_info *p;
1259 struct pci_pbm_info *pbm;
1268 struct iommu *iommu; 1260 struct iommu *iommu;
1269 struct property *prop; 1261 struct property *prop;
1270 struct linux_prom64_registers *regs; 1262 struct linux_prom64_registers *regs;
@@ -1276,18 +1268,9 @@ void sun4v_pci_init(struct device_node *dp, char *model_name)
1276 1268
1277 devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff; 1269 devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff;
1278 1270
1279 for (p = pci_controller_root; p; p = p->next) { 1271 for (pbm = pci_pbm_root; pbm; pbm = pbm->next) {
1280 struct pci_pbm_info *pbm;
1281
1282 if (p->pbm_A.prom_node && p->pbm_B.prom_node)
1283 continue;
1284
1285 pbm = (p->pbm_A.prom_node ?
1286 &p->pbm_A :
1287 &p->pbm_B);
1288
1289 if (pbm->devhandle == (devhandle ^ 0x40)) { 1272 if (pbm->devhandle == (devhandle ^ 0x40)) {
1290 pci_sun4v_pbm_init(p, dp, devhandle); 1273 pci_sun4v_pbm_init(pbm->parent, dp, devhandle);
1291 return; 1274 return;
1292 } 1275 }
1293 } 1276 }
@@ -1317,12 +1300,8 @@ void sun4v_pci_init(struct device_node *dp, char *model_name)
1317 1300
1318 p->pbm_B.iommu = iommu; 1301 p->pbm_B.iommu = iommu;
1319 1302
1320 p->next = pci_controller_root;
1321 pci_controller_root = p;
1322
1323 p->index = pci_num_controllers++; 1303 p->index = pci_num_controllers++;
1324 1304
1325 p->scan_bus = pci_sun4v_scan_bus;
1326#ifdef CONFIG_PCI_MSI 1305#ifdef CONFIG_PCI_MSI
1327 p->setup_msi_irq = pci_sun4v_setup_msi_irq; 1306 p->setup_msi_irq = pci_sun4v_setup_msi_irq;
1328 p->teardown_msi_irq = pci_sun4v_teardown_msi_irq; 1307 p->teardown_msi_irq = pci_sun4v_teardown_msi_irq;