aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-06-21 21:18:47 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-24 02:15:07 -0400
commite87dc35020bc555969810452f44bceaf8394eafa (patch)
treeb58f14d41f8e147f6ddc2d9657a88813fdb73bdf
parentaaf7cec2769942035985716452107fc5ba0b11f6 (diff)
[SPARC64]: Use in-kernel OBP device tree for PCI controller probing.
It can be pushed even further down, but this is a first step. Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/sparc64/kernel/pci.c53
-rw-r--r--arch/sparc64/kernel/pci_common.c15
-rw-r--r--arch/sparc64/kernel/pci_psycho.c108
-rw-r--r--arch/sparc64/kernel/pci_sabre.c192
-rw-r--r--arch/sparc64/kernel/pci_schizo.c173
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c144
-rw-r--r--include/asm-sparc64/pbm.h12
7 files changed, 312 insertions, 385 deletions
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 9472580a4319..a868c3792efb 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -22,6 +22,7 @@
22#include <asm/irq.h> 22#include <asm/irq.h>
23#include <asm/ebus.h> 23#include <asm/ebus.h>
24#include <asm/isa.h> 24#include <asm/isa.h>
25#include <asm/prom.h>
25 26
26unsigned long pci_memspace_mask = 0xffffffffUL; 27unsigned long pci_memspace_mask = 0xffffffffUL;
27 28
@@ -177,16 +178,16 @@ void pci_config_write32(u32 *addr, u32 val)
177} 178}
178 179
179/* Probe for all PCI controllers in the system. */ 180/* Probe for all PCI controllers in the system. */
180extern void sabre_init(int, char *); 181extern void sabre_init(struct device_node *, const char *);
181extern void psycho_init(int, char *); 182extern void psycho_init(struct device_node *, const char *);
182extern void schizo_init(int, char *); 183extern void schizo_init(struct device_node *, const char *);
183extern void schizo_plus_init(int, char *); 184extern void schizo_plus_init(struct device_node *, const char *);
184extern void tomatillo_init(int, char *); 185extern void tomatillo_init(struct device_node *, const char *);
185extern void sun4v_pci_init(int, char *); 186extern void sun4v_pci_init(struct device_node *, const char *);
186 187
187static struct { 188static struct {
188 char *model_name; 189 char *model_name;
189 void (*init)(int, char *); 190 void (*init)(struct device_node *, const char *);
190} pci_controller_table[] __initdata = { 191} pci_controller_table[] __initdata = {
191 { "SUNW,sabre", sabre_init }, 192 { "SUNW,sabre", sabre_init },
192 { "pci108e,a000", sabre_init }, 193 { "pci108e,a000", sabre_init },
@@ -204,7 +205,7 @@ static struct {
204#define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \ 205#define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \
205 sizeof(pci_controller_table[0])) 206 sizeof(pci_controller_table[0]))
206 207
207static int __init pci_controller_init(char *model_name, int namelen, int node) 208static int __init pci_controller_init(const char *model_name, int namelen, struct device_node *dp)
208{ 209{
209 int i; 210 int i;
210 211
@@ -212,18 +213,15 @@ static int __init pci_controller_init(char *model_name, int namelen, int node)
212 if (!strncmp(model_name, 213 if (!strncmp(model_name,
213 pci_controller_table[i].model_name, 214 pci_controller_table[i].model_name,
214 namelen)) { 215 namelen)) {
215 pci_controller_table[i].init(node, model_name); 216 pci_controller_table[i].init(dp, model_name);
216 return 1; 217 return 1;
217 } 218 }
218 } 219 }
219 printk("PCI: Warning unknown controller, model name [%s]\n",
220 model_name);
221 printk("PCI: Ignoring controller...\n");
222 220
223 return 0; 221 return 0;
224} 222}
225 223
226static int __init pci_is_controller(char *model_name, int namelen, int node) 224static int __init pci_is_controller(const char *model_name, int namelen, struct device_node *dp)
227{ 225{
228 int i; 226 int i;
229 227
@@ -237,36 +235,35 @@ static int __init pci_is_controller(char *model_name, int namelen, int node)
237 return 0; 235 return 0;
238} 236}
239 237
240static int __init pci_controller_scan(int (*handler)(char *, int, int)) 238static int __init pci_controller_scan(int (*handler)(const char *, int, struct device_node *))
241{ 239{
242 char namebuf[64]; 240 struct device_node *dp;
243 int node;
244 int count = 0; 241 int count = 0;
245 242
246 node = prom_getchild(prom_root_node); 243 for_each_node_by_name(dp, "pci") {
247 while ((node = prom_searchsiblings(node, "pci")) != 0) { 244 struct property *prop;
248 int len; 245 int len;
249 246
250 if ((len = prom_getproperty(node, "model", namebuf, sizeof(namebuf))) > 0 || 247 prop = of_find_property(dp, "model", &len);
251 (len = prom_getproperty(node, "compatible", namebuf, sizeof(namebuf))) > 0) { 248 if (!prop)
249 prop = of_find_property(dp, "compatible", &len);
250
251 if (prop) {
252 const char *model = prop->value;
252 int item_len = 0; 253 int item_len = 0;
253 254
254 /* Our value may be a multi-valued string in the 255 /* Our value may be a multi-valued string in the
255 * case of some compatible properties. For sanity, 256 * case of some compatible properties. For sanity,
256 * only try the first one. */ 257 * only try the first one.
257 258 */
258 while (namebuf[item_len] && len) { 259 while (model[item_len] && len) {
259 len--; 260 len--;
260 item_len++; 261 item_len++;
261 } 262 }
262 263
263 if (handler(namebuf, item_len, node)) 264 if (handler(model, item_len, dp))
264 count++; 265 count++;
265 } 266 }
266
267 node = prom_getsibling(node);
268 if (!node)
269 break;
270 } 267 }
271 268
272 return count; 269 return count;
diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c
index 33dedb1aacd4..fc71b28795a0 100644
--- a/arch/sparc64/kernel/pci_common.c
+++ b/arch/sparc64/kernel/pci_common.c
@@ -664,7 +664,7 @@ static unsigned int __init pci_intmap_match_to_root(struct pci_pbm_info *pbm,
664 } 664 }
665 pdev = pbus; 665 pdev = pbus;
666 666
667 if (cnode == pbm->prom_node) 667 if (cnode == pbm->prom_node->node)
668 break; 668 break;
669 } 669 }
670 670
@@ -680,7 +680,7 @@ static int __init pci_intmap_match(struct pci_dev *pdev, unsigned int *interrupt
680 int i, cnode, plen; 680 int i, cnode, plen;
681 681
682 cnode = pci_intmap_match_to_root(pbm, pdev, interrupt); 682 cnode = pci_intmap_match_to_root(pbm, pdev, interrupt);
683 if (cnode == pbm->prom_node) 683 if (cnode == pbm->prom_node->node)
684 goto success; 684 goto success;
685 685
686 plen = prom_getproperty(cnode, "reg", (char *) reg, sizeof(reg)); 686 plen = prom_getproperty(cnode, "reg", (char *) reg, sizeof(reg));
@@ -691,10 +691,10 @@ static int __init pci_intmap_match(struct pci_dev *pdev, unsigned int *interrupt
691 goto fail; 691 goto fail;
692 } 692 }
693 693
694 hi = reg[0].phys_hi & pbm->pbm_intmask.phys_hi; 694 hi = reg[0].phys_hi & pbm->pbm_intmask->phys_hi;
695 mid = reg[0].phys_mid & pbm->pbm_intmask.phys_mid; 695 mid = reg[0].phys_mid & pbm->pbm_intmask->phys_mid;
696 lo = reg[0].phys_lo & pbm->pbm_intmask.phys_lo; 696 lo = reg[0].phys_lo & pbm->pbm_intmask->phys_lo;
697 irq = *interrupt & pbm->pbm_intmask.interrupt; 697 irq = *interrupt & pbm->pbm_intmask->interrupt;
698 698
699 for (i = 0; i < pbm->num_pbm_intmap; i++) { 699 for (i = 0; i < pbm->num_pbm_intmap; i++) {
700 struct linux_prom_pci_intmap *intmap; 700 struct linux_prom_pci_intmap *intmap;
@@ -714,7 +714,8 @@ fail:
714 return 0; 714 return 0;
715 715
716success: 716success:
717 printk("PCI-IRQ: Routing bus[%2x] slot[%2x] to INO[%02x]\n", 717 printk("%s: Routing bus[%2x] slot[%2x] to INO[%02x]\n",
718 pbm->name,
718 pdev->bus->number, PCI_SLOT(pdev->devfn), 719 pdev->bus->number, PCI_SLOT(pdev->devfn),
719 *interrupt); 720 *interrupt);
720 return 1; 721 return 1;
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 24db22aa9728..40c2b6819983 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -17,6 +17,7 @@
17#include <asm/iommu.h> 17#include <asm/iommu.h>
18#include <asm/irq.h> 18#include <asm/irq.h>
19#include <asm/starfire.h> 19#include <asm/starfire.h>
20#include <asm/prom.h>
20 21
21#include "pci_impl.h" 22#include "pci_impl.h"
22#include "iommu_common.h" 23#include "iommu_common.h"
@@ -1103,7 +1104,7 @@ static void pbm_scan_bus(struct pci_controller_info *p,
1103 pci_fixup_host_bridge_self(pbm->pci_bus); 1104 pci_fixup_host_bridge_self(pbm->pci_bus);
1104 pbm->pci_bus->self->sysdata = cookie; 1105 pbm->pci_bus->self->sysdata = cookie;
1105 1106
1106 pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node); 1107 pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node->node);
1107 pci_record_assignments(pbm, pbm->pci_bus); 1108 pci_record_assignments(pbm, pbm->pci_bus);
1108 pci_assign_unassigned(pbm, pbm->pci_bus); 1109 pci_assign_unassigned(pbm, pbm->pci_bus);
1109 pci_fixup_irq(pbm, pbm->pci_bus); 1110 pci_fixup_irq(pbm, pbm->pci_bus);
@@ -1291,11 +1292,12 @@ static void psycho_pbm_strbuf_init(struct pci_controller_info *p,
1291#define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL 1292#define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL
1292 1293
1293static void psycho_pbm_init(struct pci_controller_info *p, 1294static void psycho_pbm_init(struct pci_controller_info *p,
1294 int prom_node, int is_pbm_a) 1295 struct device_node *dp, int is_pbm_a)
1295{ 1296{
1296 unsigned int busrange[2]; 1297 unsigned int *busrange;
1298 struct property *prop;
1297 struct pci_pbm_info *pbm; 1299 struct pci_pbm_info *pbm;
1298 int err; 1300 int len;
1299 1301
1300 if (is_pbm_a) { 1302 if (is_pbm_a) {
1301 pbm = &p->pbm_A; 1303 pbm = &p->pbm_A;
@@ -1310,10 +1312,14 @@ static void psycho_pbm_init(struct pci_controller_info *p,
1310 } 1312 }
1311 1313
1312 pbm->chip_type = PBM_CHIP_TYPE_PSYCHO; 1314 pbm->chip_type = PBM_CHIP_TYPE_PSYCHO;
1313 pbm->chip_version = 1315 pbm->chip_version = 0;
1314 prom_getintdefault(prom_node, "version#", 0); 1316 prop = of_find_property(dp, "version#", NULL);
1315 pbm->chip_revision = 1317 if (prop)
1316 prom_getintdefault(prom_node, "module-revision#", 0); 1318 pbm->chip_version = *(int *) prop->value;
1319 pbm->chip_revision = 0;
1320 prop = of_find_property(dp, "module-revision#", NULL);
1321 if (prop)
1322 pbm->chip_revision = *(int *) prop->value;
1317 1323
1318 pbm->io_space.end = pbm->io_space.start + PSYCHO_IOSPACE_SIZE; 1324 pbm->io_space.end = pbm->io_space.start + PSYCHO_IOSPACE_SIZE;
1319 pbm->io_space.flags = IORESOURCE_IO; 1325 pbm->io_space.flags = IORESOURCE_IO;
@@ -1322,45 +1328,36 @@ static void psycho_pbm_init(struct pci_controller_info *p,
1322 pbm_register_toplevel_resources(p, pbm); 1328 pbm_register_toplevel_resources(p, pbm);
1323 1329
1324 pbm->parent = p; 1330 pbm->parent = p;
1325 pbm->prom_node = prom_node; 1331 pbm->prom_node = dp;
1326 prom_getstring(prom_node, "name", 1332 pbm->name = dp->full_name;
1327 pbm->prom_name, 1333
1328 sizeof(pbm->prom_name)); 1334 printk("%s: PSYCHO PCI Bus Module ver[%x:%x]\n",
1329 1335 pbm->name,
1330 err = prom_getproperty(prom_node, "ranges", 1336 pbm->chip_version, pbm->chip_revision);
1331 (char *)pbm->pbm_ranges, 1337
1332 sizeof(pbm->pbm_ranges)); 1338 prop = of_find_property(dp, "ranges", &len);
1333 if (err != -1) 1339 if (prop) {
1340 pbm->pbm_ranges = prop->value;
1334 pbm->num_pbm_ranges = 1341 pbm->num_pbm_ranges =
1335 (err / sizeof(struct linux_prom_pci_ranges)); 1342 (len / sizeof(struct linux_prom_pci_ranges));
1336 else 1343 } else {
1337 pbm->num_pbm_ranges = 0; 1344 pbm->num_pbm_ranges = 0;
1345 }
1338 1346
1339 err = prom_getproperty(prom_node, "interrupt-map", 1347 prop = of_find_property(dp, "interrupt-map", &len);
1340 (char *)pbm->pbm_intmap, 1348 if (prop) {
1341 sizeof(pbm->pbm_intmap)); 1349 pbm->pbm_intmap = prop->value;
1342 if (err != -1) { 1350 pbm->num_pbm_intmap =
1343 pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap)); 1351 (len / sizeof(struct linux_prom_pci_intmap));
1344 err = prom_getproperty(prom_node, "interrupt-map-mask", 1352
1345 (char *)&pbm->pbm_intmask, 1353 prop = of_find_property(dp, "interrupt-map-mask", NULL);
1346 sizeof(pbm->pbm_intmask)); 1354 pbm->pbm_intmask = prop->value;
1347 if (err == -1) {
1348 prom_printf("PSYCHO-PBM: Fatal error, no "
1349 "interrupt-map-mask.\n");
1350 prom_halt();
1351 }
1352 } else { 1355 } else {
1353 pbm->num_pbm_intmap = 0; 1356 pbm->num_pbm_intmap = 0;
1354 memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask));
1355 } 1357 }
1356 1358
1357 err = prom_getproperty(prom_node, "bus-range", 1359 prop = of_find_property(dp, "bus-range", NULL);
1358 (char *)&busrange[0], 1360 busrange = prop->value;
1359 sizeof(busrange));
1360 if (err == 0 || err == -1) {
1361 prom_printf("PSYCHO-PBM: Fatal error, no bus-range.\n");
1362 prom_halt();
1363 }
1364 pbm->pci_first_busno = busrange[0]; 1361 pbm->pci_first_busno = busrange[0];
1365 pbm->pci_last_busno = busrange[1]; 1362 pbm->pci_last_busno = busrange[1];
1366 1363
@@ -1369,20 +1366,24 @@ static void psycho_pbm_init(struct pci_controller_info *p,
1369 1366
1370#define PSYCHO_CONFIGSPACE 0x001000000UL 1367#define PSYCHO_CONFIGSPACE 0x001000000UL
1371 1368
1372void psycho_init(int node, char *model_name) 1369void psycho_init(struct device_node *dp, char *model_name)
1373{ 1370{
1374 struct linux_prom64_registers pr_regs[3]; 1371 struct linux_prom64_registers *pr_regs;
1375 struct pci_controller_info *p; 1372 struct pci_controller_info *p;
1376 struct pci_iommu *iommu; 1373 struct pci_iommu *iommu;
1374 struct property *prop;
1377 u32 upa_portid; 1375 u32 upa_portid;
1378 int is_pbm_a, err; 1376 int is_pbm_a;
1379 1377
1380 upa_portid = prom_getintdefault(node, "upa-portid", 0xff); 1378 upa_portid = 0xff;
1379 prop = of_find_property(dp, "upa-portid", NULL);
1380 if (prop)
1381 upa_portid = *(u32 *) prop->value;
1381 1382
1382 for(p = pci_controller_root; p; p = p->next) { 1383 for(p = pci_controller_root; p; p = p->next) {
1383 if (p->pbm_A.portid == upa_portid) { 1384 if (p->pbm_A.portid == upa_portid) {
1384 is_pbm_a = (p->pbm_A.prom_node == 0); 1385 is_pbm_a = (p->pbm_A.prom_node == NULL);
1385 psycho_pbm_init(p, node, is_pbm_a); 1386 psycho_pbm_init(p, dp, is_pbm_a);
1386 return; 1387 return;
1387 } 1388 }
1388 } 1389 }
@@ -1412,23 +1413,14 @@ void psycho_init(int node, char *model_name)
1412 p->resource_adjust = psycho_resource_adjust; 1413 p->resource_adjust = psycho_resource_adjust;
1413 p->pci_ops = &psycho_ops; 1414 p->pci_ops = &psycho_ops;
1414 1415
1415 err = prom_getproperty(node, "reg", 1416 prop = of_find_property(dp, "reg", NULL);
1416 (char *)&pr_regs[0], 1417 pr_regs = prop->value;
1417 sizeof(pr_regs));
1418 if (err == 0 || err == -1) {
1419 prom_printf("PSYCHO: Fatal error, no reg property.\n");
1420 prom_halt();
1421 }
1422 1418
1423 p->pbm_A.controller_regs = pr_regs[2].phys_addr; 1419 p->pbm_A.controller_regs = pr_regs[2].phys_addr;
1424 p->pbm_B.controller_regs = pr_regs[2].phys_addr; 1420 p->pbm_B.controller_regs = pr_regs[2].phys_addr;
1425 printk("PCI: Found PSYCHO, control regs at %016lx\n",
1426 p->pbm_A.controller_regs);
1427 1421
1428 p->pbm_A.config_space = p->pbm_B.config_space = 1422 p->pbm_A.config_space = p->pbm_B.config_space =
1429 (pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE); 1423 (pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE);
1430 printk("PSYCHO: Shared PCI config space at %016lx\n",
1431 p->pbm_A.config_space);
1432 1424
1433 /* 1425 /*
1434 * Psycho's PCI MEM space is mapped to a 2GB aligned area, so 1426 * Psycho's PCI MEM space is mapped to a 2GB aligned area, so
@@ -1441,5 +1433,5 @@ void psycho_init(int node, char *model_name)
1441 psycho_iommu_init(p); 1433 psycho_iommu_init(p);
1442 1434
1443 is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000); 1435 is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000);
1444 psycho_pbm_init(p, node, is_pbm_a); 1436 psycho_pbm_init(p, dp, is_pbm_a);
1445} 1437}
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index b7d997b55f0a..91d1aa44efc1 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -19,6 +19,7 @@
19#include <asm/irq.h> 19#include <asm/irq.h>
20#include <asm/smp.h> 20#include <asm/smp.h>
21#include <asm/oplib.h> 21#include <asm/oplib.h>
22#include <asm/prom.h>
22 23
23#include "pci_impl.h" 24#include "pci_impl.h"
24#include "iommu_common.h" 25#include "iommu_common.h"
@@ -1160,7 +1161,7 @@ static void sabre_scan_bus(struct pci_controller_info *p)
1160 1161
1161 pbus->sysdata = pbm; 1162 pbus->sysdata = pbm;
1162 pbm->pci_bus = pbus; 1163 pbm->pci_bus = pbus;
1163 pci_fill_in_pbm_cookies(pbus, pbm, pbm->prom_node); 1164 pci_fill_in_pbm_cookies(pbus, pbm, pbm->prom_node->node);
1164 pci_record_assignments(pbm, pbus); 1165 pci_record_assignments(pbm, pbus);
1165 pci_assign_unassigned(pbm, pbus); 1166 pci_assign_unassigned(pbm, pbus);
1166 pci_fixup_irq(pbm, pbus); 1167 pci_fixup_irq(pbm, pbus);
@@ -1173,7 +1174,7 @@ static void sabre_scan_bus(struct pci_controller_info *p)
1173 pbm = &p->pbm_A; 1174 pbm = &p->pbm_A;
1174 sabre_bus->sysdata = pbm; 1175 sabre_bus->sysdata = pbm;
1175 pbm->pci_bus = sabre_bus; 1176 pbm->pci_bus = sabre_bus;
1176 pci_fill_in_pbm_cookies(sabre_bus, pbm, pbm->prom_node); 1177 pci_fill_in_pbm_cookies(sabre_bus, pbm, pbm->prom_node->node);
1177 pci_record_assignments(pbm, sabre_bus); 1178 pci_record_assignments(pbm, sabre_bus);
1178 pci_assign_unassigned(pbm, sabre_bus); 1179 pci_assign_unassigned(pbm, sabre_bus);
1179 pci_fixup_irq(pbm, sabre_bus); 1180 pci_fixup_irq(pbm, sabre_bus);
@@ -1306,34 +1307,36 @@ static void pbm_register_toplevel_resources(struct pci_controller_info *p,
1306 &pbm->mem_space); 1307 &pbm->mem_space);
1307} 1308}
1308 1309
1309static void sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dma_begin) 1310static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_begin)
1310{ 1311{
1311 struct pci_pbm_info *pbm; 1312 struct pci_pbm_info *pbm;
1312 char namebuf[128]; 1313 struct device_node *node;
1313 u32 busrange[2]; 1314 struct property *prop;
1314 int node, simbas_found; 1315 u32 *busrange;
1316 int len, simbas_found;
1315 1317
1316 simbas_found = 0; 1318 simbas_found = 0;
1317 node = prom_getchild(sabre_node); 1319 node = dp->child;
1318 while ((node = prom_searchsiblings(node, "pci")) != 0) { 1320 while (node != NULL) {
1319 int err; 1321 if (strcmp(node->name, "pci"))
1320
1321 err = prom_getproperty(node, "model", namebuf, sizeof(namebuf));
1322 if ((err <= 0) || strncmp(namebuf, "SUNW,simba", err))
1323 goto next_pci; 1322 goto next_pci;
1324 1323
1325 err = prom_getproperty(node, "bus-range", 1324 prop = of_find_property(node, "model", NULL);
1326 (char *)&busrange[0], sizeof(busrange)); 1325 if (!prop || strncmp(prop->value, "SUNW,simba", prop->length))
1327 if (err == 0 || err == -1) { 1326 goto next_pci;
1328 prom_printf("APB: Error, cannot get PCI bus-range.\n");
1329 prom_halt();
1330 }
1331 1327
1332 simbas_found++; 1328 simbas_found++;
1329
1330 prop = of_find_property(node, "bus-range", NULL);
1331 busrange = prop->value;
1333 if (busrange[0] == 1) 1332 if (busrange[0] == 1)
1334 pbm = &p->pbm_B; 1333 pbm = &p->pbm_B;
1335 else 1334 else
1336 pbm = &p->pbm_A; 1335 pbm = &p->pbm_A;
1336
1337 pbm->name = node->full_name;
1338 printk("%s: SABRE PCI Bus Module\n", pbm->name);
1339
1337 pbm->chip_type = PBM_CHIP_TYPE_SABRE; 1340 pbm->chip_type = PBM_CHIP_TYPE_SABRE;
1338 pbm->parent = p; 1341 pbm->parent = p;
1339 pbm->prom_node = node; 1342 pbm->prom_node = node;
@@ -1341,83 +1344,68 @@ static void sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dm
1341 pbm->pci_first_busno = busrange[0]; 1344 pbm->pci_first_busno = busrange[0];
1342 pbm->pci_last_busno = busrange[1]; 1345 pbm->pci_last_busno = busrange[1];
1343 1346
1344 prom_getstring(node, "name", pbm->prom_name, sizeof(pbm->prom_name)); 1347 prop = of_find_property(node, "ranges", &len);
1345 err = prom_getproperty(node, "ranges", 1348 if (prop) {
1346 (char *)pbm->pbm_ranges, 1349 pbm->pbm_ranges = prop->value;
1347 sizeof(pbm->pbm_ranges));
1348 if (err != -1)
1349 pbm->num_pbm_ranges = 1350 pbm->num_pbm_ranges =
1350 (err / sizeof(struct linux_prom_pci_ranges)); 1351 (len / sizeof(struct linux_prom_pci_ranges));
1351 else 1352 } else {
1352 pbm->num_pbm_ranges = 0; 1353 pbm->num_pbm_ranges = 0;
1354 }
1353 1355
1354 err = prom_getproperty(node, "interrupt-map", 1356 prop = of_find_property(node, "interrupt-map", &len);
1355 (char *)pbm->pbm_intmap, 1357 if (prop) {
1356 sizeof(pbm->pbm_intmap)); 1358 pbm->pbm_intmap = prop->value;
1357 if (err != -1) { 1359 pbm->num_pbm_intmap =
1358 pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap)); 1360 (len / sizeof(struct linux_prom_pci_intmap));
1359 err = prom_getproperty(node, "interrupt-map-mask", 1361
1360 (char *)&pbm->pbm_intmask, 1362 prop = of_find_property(node, "interrupt-map-mask",
1361 sizeof(pbm->pbm_intmask)); 1363 NULL);
1362 if (err == -1) { 1364 pbm->pbm_intmask = prop->value;
1363 prom_printf("APB: Fatal error, no interrupt-map-mask.\n");
1364 prom_halt();
1365 }
1366 } else { 1365 } else {
1367 pbm->num_pbm_intmap = 0; 1366 pbm->num_pbm_intmap = 0;
1368 memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask));
1369 } 1367 }
1370 1368
1371 pbm_register_toplevel_resources(p, pbm); 1369 pbm_register_toplevel_resources(p, pbm);
1372 1370
1373 next_pci: 1371 next_pci:
1374 node = prom_getsibling(node); 1372 node = node->sibling;
1375 if (!node)
1376 break;
1377 } 1373 }
1378 if (simbas_found == 0) { 1374 if (simbas_found == 0) {
1379 int err;
1380
1381 /* No APBs underneath, probably this is a hummingbird 1375 /* No APBs underneath, probably this is a hummingbird
1382 * system. 1376 * system.
1383 */ 1377 */
1384 pbm = &p->pbm_A; 1378 pbm = &p->pbm_A;
1385 pbm->parent = p; 1379 pbm->parent = p;
1386 pbm->prom_node = sabre_node; 1380 pbm->prom_node = dp;
1387 pbm->pci_first_busno = p->pci_first_busno; 1381 pbm->pci_first_busno = p->pci_first_busno;
1388 pbm->pci_last_busno = p->pci_last_busno; 1382 pbm->pci_last_busno = p->pci_last_busno;
1389 1383
1390 prom_getstring(sabre_node, "name", pbm->prom_name, sizeof(pbm->prom_name)); 1384 prop = of_find_property(dp, "ranges", &len);
1391 err = prom_getproperty(sabre_node, "ranges", 1385 if (prop) {
1392 (char *) pbm->pbm_ranges, 1386 pbm->pbm_ranges = prop->value;
1393 sizeof(pbm->pbm_ranges));
1394 if (err != -1)
1395 pbm->num_pbm_ranges = 1387 pbm->num_pbm_ranges =
1396 (err / sizeof(struct linux_prom_pci_ranges)); 1388 (len / sizeof(struct linux_prom_pci_ranges));
1397 else 1389 } else {
1398 pbm->num_pbm_ranges = 0; 1390 pbm->num_pbm_ranges = 0;
1391 }
1399 1392
1400 err = prom_getproperty(sabre_node, "interrupt-map", 1393 prop = of_find_property(dp, "interrupt-map", &len);
1401 (char *) pbm->pbm_intmap, 1394 if (prop) {
1402 sizeof(pbm->pbm_intmap)); 1395 pbm->pbm_intmap = prop->value;
1403 1396 pbm->num_pbm_intmap =
1404 if (err != -1) { 1397 (len / sizeof(struct linux_prom_pci_intmap));
1405 pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap)); 1398
1406 err = prom_getproperty(sabre_node, "interrupt-map-mask", 1399 prop = of_find_property(dp, "interrupt-map-mask",
1407 (char *)&pbm->pbm_intmask, 1400 NULL);
1408 sizeof(pbm->pbm_intmask)); 1401 pbm->pbm_intmask = prop->value;
1409 if (err == -1) {
1410 prom_printf("Hummingbird: Fatal error, no interrupt-map-mask.\n");
1411 prom_halt();
1412 }
1413 } else { 1402 } else {
1414 pbm->num_pbm_intmap = 0; 1403 pbm->num_pbm_intmap = 0;
1415 memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask));
1416 } 1404 }
1417 1405
1406 pbm->name = dp->full_name;
1407 printk("%s: SABRE PCI Bus Module\n", pbm->name);
1418 1408
1419 sprintf(pbm->name, "SABRE%d PBM%c", p->index,
1420 (pbm == &p->pbm_A ? 'A' : 'B'));
1421 pbm->io_space.name = pbm->mem_space.name = pbm->name; 1409 pbm->io_space.name = pbm->mem_space.name = pbm->name;
1422 1410
1423 /* Hack up top-level resources. */ 1411 /* Hack up top-level resources. */
@@ -1443,14 +1431,15 @@ static void sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dm
1443 } 1431 }
1444} 1432}
1445 1433
1446void sabre_init(int pnode, char *model_name) 1434void sabre_init(struct device_node *dp, char *model_name)
1447{ 1435{
1448 struct linux_prom64_registers pr_regs[2]; 1436 struct linux_prom64_registers *pr_regs;
1449 struct pci_controller_info *p; 1437 struct pci_controller_info *p;
1450 struct pci_iommu *iommu; 1438 struct pci_iommu *iommu;
1451 int tsbsize, err; 1439 struct property *prop;
1452 u32 busrange[2]; 1440 int tsbsize;
1453 u32 vdma[2]; 1441 u32 *busrange;
1442 u32 *vdma;
1454 u32 upa_portid, dma_mask; 1443 u32 upa_portid, dma_mask;
1455 u64 clear_irq; 1444 u64 clear_irq;
1456 1445
@@ -1458,13 +1447,15 @@ void sabre_init(int pnode, char *model_name)
1458 if (!strcmp(model_name, "pci108e,a001")) 1447 if (!strcmp(model_name, "pci108e,a001"))
1459 hummingbird_p = 1; 1448 hummingbird_p = 1;
1460 else if (!strcmp(model_name, "SUNW,sabre")) { 1449 else if (!strcmp(model_name, "SUNW,sabre")) {
1461 char compat[64]; 1450 prop = of_find_property(dp, "compatible", NULL);
1451 if (prop) {
1452 const char *compat = prop->value;
1462 1453
1463 if (prom_getproperty(pnode, "compatible", 1454 if (!strcmp(compat, "pci108e,a001"))
1464 compat, sizeof(compat)) > 0 && 1455 hummingbird_p = 1;
1465 !strcmp(compat, "pci108e,a001")) { 1456 }
1466 hummingbird_p = 1; 1457 if (!hummingbird_p) {
1467 } else { 1458 char compat[64];
1468 int cpu_node; 1459 int cpu_node;
1469 1460
1470 /* Of course, Sun has to encode things a thousand 1461 /* Of course, Sun has to encode things a thousand
@@ -1491,7 +1482,10 @@ void sabre_init(int pnode, char *model_name)
1491 } 1482 }
1492 p->pbm_A.iommu = p->pbm_B.iommu = iommu; 1483 p->pbm_A.iommu = p->pbm_B.iommu = iommu;
1493 1484
1494 upa_portid = prom_getintdefault(pnode, "upa-portid", 0xff); 1485 upa_portid = 0xff;
1486 prop = of_find_property(dp, "upa-portid", NULL);
1487 if (prop)
1488 upa_portid = *(u32 *) prop->value;
1495 1489
1496 p->next = pci_controller_root; 1490 p->next = pci_controller_root;
1497 pci_controller_root = p; 1491 pci_controller_root = p;
@@ -1509,13 +1503,9 @@ void sabre_init(int pnode, char *model_name)
1509 /* 1503 /*
1510 * Map in SABRE register set and report the presence of this SABRE. 1504 * Map in SABRE register set and report the presence of this SABRE.
1511 */ 1505 */
1512 err = prom_getproperty(pnode, "reg", 1506
1513 (char *)&pr_regs[0], sizeof(pr_regs)); 1507 prop = of_find_property(dp, "reg", NULL);
1514 if(err == 0 || err == -1) { 1508 pr_regs = prop->value;
1515 prom_printf("SABRE: Error, cannot get U2P registers "
1516 "from PROM.\n");
1517 prom_halt();
1518 }
1519 1509
1520 /* 1510 /*
1521 * First REG in property is base of entire SABRE register space. 1511 * First REG in property is base of entire SABRE register space.
@@ -1523,9 +1513,6 @@ void sabre_init(int pnode, char *model_name)
1523 p->pbm_A.controller_regs = pr_regs[0].phys_addr; 1513 p->pbm_A.controller_regs = pr_regs[0].phys_addr;
1524 p->pbm_B.controller_regs = pr_regs[0].phys_addr; 1514 p->pbm_B.controller_regs = pr_regs[0].phys_addr;
1525 1515
1526 printk("PCI: Found SABRE, main regs at %016lx\n",
1527 p->pbm_A.controller_regs);
1528
1529 /* Clear interrupts */ 1516 /* Clear interrupts */
1530 1517
1531 /* PCI first */ 1518 /* PCI first */
@@ -1544,16 +1531,9 @@ void sabre_init(int pnode, char *model_name)
1544 /* Now map in PCI config space for entire SABRE. */ 1531 /* Now map in PCI config space for entire SABRE. */
1545 p->pbm_A.config_space = p->pbm_B.config_space = 1532 p->pbm_A.config_space = p->pbm_B.config_space =
1546 (p->pbm_A.controller_regs + SABRE_CONFIGSPACE); 1533 (p->pbm_A.controller_regs + SABRE_CONFIGSPACE);
1547 printk("SABRE: Shared PCI config space at %016lx\n", 1534
1548 p->pbm_A.config_space); 1535 prop = of_find_property(dp, "virtual-dma", NULL);
1549 1536 vdma = prop->value;
1550 err = prom_getproperty(pnode, "virtual-dma",
1551 (char *)&vdma[0], sizeof(vdma));
1552 if(err == 0 || err == -1) {
1553 prom_printf("SABRE: Error, cannot get virtual-dma property "
1554 "from PROM.\n");
1555 prom_halt();
1556 }
1557 1537
1558 dma_mask = vdma[0]; 1538 dma_mask = vdma[0];
1559 switch(vdma[1]) { 1539 switch(vdma[1]) {
@@ -1577,21 +1557,13 @@ void sabre_init(int pnode, char *model_name)
1577 1557
1578 sabre_iommu_init(p, tsbsize, vdma[0], dma_mask); 1558 sabre_iommu_init(p, tsbsize, vdma[0], dma_mask);
1579 1559
1580 printk("SABRE: DVMA at %08x [%08x]\n", vdma[0], vdma[1]); 1560 prop = of_find_property(dp, "bus-range", NULL);
1581 1561 busrange = prop->value;
1582 err = prom_getproperty(pnode, "bus-range",
1583 (char *)&busrange[0], sizeof(busrange));
1584 if(err == 0 || err == -1) {
1585 prom_printf("SABRE: Error, cannot get PCI bus-range "
1586 " from PROM.\n");
1587 prom_halt();
1588 }
1589
1590 p->pci_first_busno = busrange[0]; 1562 p->pci_first_busno = busrange[0];
1591 p->pci_last_busno = busrange[1]; 1563 p->pci_last_busno = busrange[1];
1592 1564
1593 /* 1565 /*
1594 * Look for APB underneath. 1566 * Look for APB underneath.
1595 */ 1567 */
1596 sabre_pbm_init(p, pnode, vdma[0]); 1568 sabre_pbm_init(p, dp, vdma[0]);
1597} 1569}
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c
index cc662e915d32..d26820086843 100644
--- a/arch/sparc64/kernel/pci_schizo.c
+++ b/arch/sparc64/kernel/pci_schizo.c
@@ -16,6 +16,7 @@
16#include <asm/irq.h> 16#include <asm/irq.h>
17#include <asm/upa.h> 17#include <asm/upa.h>
18#include <asm/pstate.h> 18#include <asm/pstate.h>
19#include <asm/prom.h>
19 20
20#include "pci_impl.h" 21#include "pci_impl.h"
21#include "iommu_common.h" 22#include "iommu_common.h"
@@ -1437,7 +1438,7 @@ static void pbm_scan_bus(struct pci_controller_info *p,
1437 pci_fixup_host_bridge_self(pbm->pci_bus); 1438 pci_fixup_host_bridge_self(pbm->pci_bus);
1438 pbm->pci_bus->self->sysdata = cookie; 1439 pbm->pci_bus->self->sysdata = cookie;
1439 1440
1440 pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node); 1441 pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node->node);
1441 pci_record_assignments(pbm, pbm->pci_bus); 1442 pci_record_assignments(pbm, pbm->pci_bus);
1442 pci_assign_unassigned(pbm, pbm->pci_bus); 1443 pci_assign_unassigned(pbm, pbm->pci_bus);
1443 pci_fixup_irq(pbm, pbm->pci_bus); 1444 pci_fixup_irq(pbm, pbm->pci_bus);
@@ -1456,10 +1457,12 @@ static void __schizo_scan_bus(struct pci_controller_info *p,
1456 1457
1457 pbm_config_busmastering(&p->pbm_B); 1458 pbm_config_busmastering(&p->pbm_B);
1458 p->pbm_B.is_66mhz_capable = 1459 p->pbm_B.is_66mhz_capable =
1459 prom_getbool(p->pbm_B.prom_node, "66mhz-capable"); 1460 (of_find_property(p->pbm_B.prom_node, "66mhz-capable", NULL)
1461 != NULL);
1460 pbm_config_busmastering(&p->pbm_A); 1462 pbm_config_busmastering(&p->pbm_A);
1461 p->pbm_A.is_66mhz_capable = 1463 p->pbm_A.is_66mhz_capable =
1462 prom_getbool(p->pbm_A.prom_node, "66mhz-capable"); 1464 (of_find_property(p->pbm_A.prom_node, "66mhz-capable", NULL)
1465 != NULL);
1463 pbm_scan_bus(p, &p->pbm_B); 1466 pbm_scan_bus(p, &p->pbm_B);
1464 pbm_scan_bus(p, &p->pbm_A); 1467 pbm_scan_bus(p, &p->pbm_A);
1465 1468
@@ -1661,13 +1664,18 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
1661{ 1664{
1662 struct pci_iommu *iommu = pbm->iommu; 1665 struct pci_iommu *iommu = pbm->iommu;
1663 unsigned long i, tagbase, database; 1666 unsigned long i, tagbase, database;
1667 struct property *prop;
1664 u32 vdma[2], dma_mask; 1668 u32 vdma[2], dma_mask;
1665 u64 control; 1669 u64 control;
1666 int err, tsbsize; 1670 int tsbsize;
1667 1671
1668 err = prom_getproperty(pbm->prom_node, "virtual-dma", 1672 prop = of_find_property(pbm->prom_node, "virtual-dma", NULL);
1669 (char *)&vdma[0], sizeof(vdma)); 1673 if (prop) {
1670 if (err == 0 || err == -1) { 1674 u32 *val = prop->value;
1675
1676 vdma[0] = val[0];
1677 vdma[1] = val[1];
1678 } else {
1671 /* No property, use default values. */ 1679 /* No property, use default values. */
1672 vdma[0] = 0xc0000000; 1680 vdma[0] = 0xc0000000;
1673 vdma[1] = 0x40000000; 1681 vdma[1] = 0x40000000;
@@ -1778,6 +1786,7 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
1778 1786
1779static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) 1787static void schizo_pbm_hw_init(struct pci_pbm_info *pbm)
1780{ 1788{
1789 struct property *prop;
1781 u64 tmp; 1790 u64 tmp;
1782 1791
1783 schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, 5); 1792 schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, 5);
@@ -1791,7 +1800,8 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm)
1791 pbm->chip_version >= 0x2) 1800 pbm->chip_version >= 0x2)
1792 tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT; 1801 tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT;
1793 1802
1794 if (!prom_getbool(pbm->prom_node, "no-bus-parking")) 1803 prop = of_find_property(pbm->prom_node, "no-bus-parking", NULL);
1804 if (!prop)
1795 tmp |= SCHIZO_PCICTRL_PARK; 1805 tmp |= SCHIZO_PCICTRL_PARK;
1796 else 1806 else
1797 tmp &= ~SCHIZO_PCICTRL_PARK; 1807 tmp &= ~SCHIZO_PCICTRL_PARK;
@@ -1831,16 +1841,17 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm)
1831} 1841}
1832 1842
1833static void schizo_pbm_init(struct pci_controller_info *p, 1843static void schizo_pbm_init(struct pci_controller_info *p,
1834 int prom_node, u32 portid, 1844 struct device_node *dp, u32 portid,
1835 int chip_type) 1845 int chip_type)
1836{ 1846{
1837 struct linux_prom64_registers pr_regs[4]; 1847 struct linux_prom64_registers *regs;
1838 unsigned int busrange[2]; 1848 struct property *prop;
1849 unsigned int *busrange;
1839 struct pci_pbm_info *pbm; 1850 struct pci_pbm_info *pbm;
1840 const char *chipset_name; 1851 const char *chipset_name;
1841 u32 ino_bitmap[2]; 1852 u32 *ino_bitmap;
1842 int is_pbm_a; 1853 int is_pbm_a;
1843 int err; 1854 int len;
1844 1855
1845 switch (chip_type) { 1856 switch (chip_type) {
1846 case PBM_CHIP_TYPE_TOMATILLO: 1857 case PBM_CHIP_TYPE_TOMATILLO:
@@ -1868,16 +1879,10 @@ static void schizo_pbm_init(struct pci_controller_info *p,
1868 * 3) PBM PCI config space 1879 * 3) PBM PCI config space
1869 * 4) Ichip regs 1880 * 4) Ichip regs
1870 */ 1881 */
1871 err = prom_getproperty(prom_node, "reg", 1882 prop = of_find_property(dp, "reg", NULL);
1872 (char *)&pr_regs[0], 1883 regs = prop->value;
1873 sizeof(pr_regs));
1874 if (err == 0 || err == -1) {
1875 prom_printf("%s: Fatal error, no reg property.\n",
1876 chipset_name);
1877 prom_halt();
1878 }
1879 1884
1880 is_pbm_a = ((pr_regs[0].phys_addr & 0x00700000) == 0x00600000); 1885 is_pbm_a = ((regs[0].phys_addr & 0x00700000) == 0x00600000);
1881 1886
1882 if (is_pbm_a) 1887 if (is_pbm_a)
1883 pbm = &p->pbm_A; 1888 pbm = &p->pbm_A;
@@ -1886,92 +1891,62 @@ static void schizo_pbm_init(struct pci_controller_info *p,
1886 1891
1887 pbm->portid = portid; 1892 pbm->portid = portid;
1888 pbm->parent = p; 1893 pbm->parent = p;
1889 pbm->prom_node = prom_node; 1894 pbm->prom_node = dp;
1890 pbm->pci_first_slot = 1; 1895 pbm->pci_first_slot = 1;
1891 1896
1892 pbm->chip_type = chip_type; 1897 pbm->chip_type = chip_type;
1893 pbm->chip_version = 1898 pbm->chip_version = 0;
1894 prom_getintdefault(prom_node, "version#", 0); 1899 prop = of_find_property(dp, "version#", NULL);
1895 pbm->chip_revision = 1900 if (prop)
1896 prom_getintdefault(prom_node, "module-revision#", 0); 1901 pbm->chip_version = *(int *) prop->value;
1897 1902 pbm->chip_revision = 0;
1898 pbm->pbm_regs = pr_regs[0].phys_addr; 1903 prop = of_find_property(dp, "module-revision#", NULL);
1899 pbm->controller_regs = pr_regs[1].phys_addr - 0x10000UL; 1904 if (prop)
1905 pbm->chip_revision = *(int *) prop->value;
1906
1907 pbm->pbm_regs = regs[0].phys_addr;
1908 pbm->controller_regs = regs[1].phys_addr - 0x10000UL;
1900 1909
1901 if (chip_type == PBM_CHIP_TYPE_TOMATILLO) 1910 if (chip_type == PBM_CHIP_TYPE_TOMATILLO)
1902 pbm->sync_reg = pr_regs[3].phys_addr + 0x1a18UL; 1911 pbm->sync_reg = regs[3].phys_addr + 0x1a18UL;
1903 1912
1904 sprintf(pbm->name, 1913 pbm->name = dp->full_name;
1905 (chip_type == PBM_CHIP_TYPE_TOMATILLO ?
1906 "TOMATILLO%d PBM%c" :
1907 "SCHIZO%d PBM%c"),
1908 p->index,
1909 (pbm == &p->pbm_A ? 'A' : 'B'));
1910 1914
1911 printk("%s: ver[%x:%x], portid %x, " 1915 printk("%s: %s PCI Bus Module ver[%x:%x]\n",
1912 "cregs[%lx] pregs[%lx]\n",
1913 pbm->name, 1916 pbm->name,
1914 pbm->chip_version, pbm->chip_revision, 1917 (chip_type == PBM_CHIP_TYPE_TOMATILLO ?
1915 pbm->portid, 1918 "TOMATILLO" : "SCHIZO"),
1916 pbm->controller_regs, 1919 pbm->chip_version, pbm->chip_revision);
1917 pbm->pbm_regs);
1918 1920
1919 schizo_pbm_hw_init(pbm); 1921 schizo_pbm_hw_init(pbm);
1920 1922
1921 prom_getstring(prom_node, "name", 1923 prop = of_find_property(dp, "ranges", &len);
1922 pbm->prom_name, 1924 pbm->pbm_ranges = prop->value;
1923 sizeof(pbm->prom_name));
1924
1925 err = prom_getproperty(prom_node, "ranges",
1926 (char *) pbm->pbm_ranges,
1927 sizeof(pbm->pbm_ranges));
1928 if (err == 0 || err == -1) {
1929 prom_printf("%s: Fatal error, no ranges property.\n",
1930 pbm->name);
1931 prom_halt();
1932 }
1933
1934 pbm->num_pbm_ranges = 1925 pbm->num_pbm_ranges =
1935 (err / sizeof(struct linux_prom_pci_ranges)); 1926 (len / sizeof(struct linux_prom_pci_ranges));
1936 1927
1937 schizo_determine_mem_io_space(pbm); 1928 schizo_determine_mem_io_space(pbm);
1938 pbm_register_toplevel_resources(p, pbm); 1929 pbm_register_toplevel_resources(p, pbm);
1939 1930
1940 err = prom_getproperty(prom_node, "interrupt-map", 1931 prop = of_find_property(dp, "interrupt-map", &len);
1941 (char *)pbm->pbm_intmap, 1932 if (prop) {
1942 sizeof(pbm->pbm_intmap)); 1933 pbm->pbm_intmap = prop->value;
1943 if (err != -1) { 1934 pbm->num_pbm_intmap =
1944 pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap)); 1935 (len / sizeof(struct linux_prom_pci_intmap));
1945 err = prom_getproperty(prom_node, "interrupt-map-mask", 1936
1946 (char *)&pbm->pbm_intmask, 1937 prop = of_find_property(dp, "interrupt-map-mask", NULL);
1947 sizeof(pbm->pbm_intmask)); 1938 pbm->pbm_intmask = prop->value;
1948 if (err == -1) {
1949 prom_printf("%s: Fatal error, no "
1950 "interrupt-map-mask.\n", pbm->name);
1951 prom_halt();
1952 }
1953 } else { 1939 } else {
1954 pbm->num_pbm_intmap = 0; 1940 pbm->num_pbm_intmap = 0;
1955 memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask));
1956 } 1941 }
1957 1942
1958 err = prom_getproperty(prom_node, "ino-bitmap", 1943 prop = of_find_property(dp, "ino-bitmap", NULL);
1959 (char *) &ino_bitmap[0], 1944 ino_bitmap = prop->value;
1960 sizeof(ino_bitmap));
1961 if (err == 0 || err == -1) {
1962 prom_printf("%s: Fatal error, no ino-bitmap.\n", pbm->name);
1963 prom_halt();
1964 }
1965 pbm->ino_bitmap = (((u64)ino_bitmap[1] << 32UL) | 1945 pbm->ino_bitmap = (((u64)ino_bitmap[1] << 32UL) |
1966 ((u64)ino_bitmap[0] << 0UL)); 1946 ((u64)ino_bitmap[0] << 0UL));
1967 1947
1968 err = prom_getproperty(prom_node, "bus-range", 1948 prop = of_find_property(dp, "bus-range", NULL);
1969 (char *)&busrange[0], 1949 busrange = prop->value;
1970 sizeof(busrange));
1971 if (err == 0 || err == -1) {
1972 prom_printf("%s: Fatal error, no bus-range.\n", pbm->name);
1973 prom_halt();
1974 }
1975 pbm->pci_first_busno = busrange[0]; 1950 pbm->pci_first_busno = busrange[0];
1976 pbm->pci_last_busno = busrange[1]; 1951 pbm->pci_last_busno = busrange[1];
1977 1952
@@ -1989,16 +1964,20 @@ static inline int portid_compare(u32 x, u32 y, int chip_type)
1989 return (x == y); 1964 return (x == y);
1990} 1965}
1991 1966
1992static void __schizo_init(int node, char *model_name, int chip_type) 1967static void __schizo_init(struct device_node *dp, char *model_name, int chip_type)
1993{ 1968{
1994 struct pci_controller_info *p; 1969 struct pci_controller_info *p;
1995 struct pci_iommu *iommu; 1970 struct pci_iommu *iommu;
1971 struct property *prop;
1996 int is_pbm_a; 1972 int is_pbm_a;
1997 u32 portid; 1973 u32 portid;
1998 1974
1999 portid = prom_getintdefault(node, "portid", 0xff); 1975 portid = 0xff;
1976 prop = of_find_property(dp, "portid", NULL);
1977 if (prop)
1978 portid = *(u32 *) prop->value;
2000 1979
2001 for(p = pci_controller_root; p; p = p->next) { 1980 for (p = pci_controller_root; p; p = p->next) {
2002 struct pci_pbm_info *pbm; 1981 struct pci_pbm_info *pbm;
2003 1982
2004 if (p->pbm_A.prom_node && p->pbm_B.prom_node) 1983 if (p->pbm_A.prom_node && p->pbm_B.prom_node)
@@ -2009,8 +1988,8 @@ static void __schizo_init(int node, char *model_name, int chip_type)
2009 &p->pbm_B); 1988 &p->pbm_B);
2010 1989
2011 if (portid_compare(pbm->portid, portid, chip_type)) { 1990 if (portid_compare(pbm->portid, portid, chip_type)) {
2012 is_pbm_a = (p->pbm_A.prom_node == 0); 1991 is_pbm_a = (p->pbm_A.prom_node == NULL);
2013 schizo_pbm_init(p, node, portid, chip_type); 1992 schizo_pbm_init(p, dp, portid, chip_type);
2014 return; 1993 return;
2015 } 1994 }
2016 } 1995 }
@@ -2051,20 +2030,20 @@ static void __schizo_init(int node, char *model_name, int chip_type)
2051 /* Like PSYCHO we have a 2GB aligned area for memory space. */ 2030 /* Like PSYCHO we have a 2GB aligned area for memory space. */
2052 pci_memspace_mask = 0x7fffffffUL; 2031 pci_memspace_mask = 0x7fffffffUL;
2053 2032
2054 schizo_pbm_init(p, node, portid, chip_type); 2033 schizo_pbm_init(p, dp, portid, chip_type);
2055} 2034}
2056 2035
2057void schizo_init(int node, char *model_name) 2036void schizo_init(struct device_node *dp, char *model_name)
2058{ 2037{
2059 __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO); 2038 __schizo_init(dp, model_name, PBM_CHIP_TYPE_SCHIZO);
2060} 2039}
2061 2040
2062void schizo_plus_init(int node, char *model_name) 2041void schizo_plus_init(struct device_node *dp, char *model_name)
2063{ 2042{
2064 __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS); 2043 __schizo_init(dp, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS);
2065} 2044}
2066 2045
2067void tomatillo_init(int node, char *model_name) 2046void tomatillo_init(struct device_node *dp, char *model_name)
2068{ 2047{
2069 __schizo_init(node, model_name, PBM_CHIP_TYPE_TOMATILLO); 2048 __schizo_init(dp, model_name, PBM_CHIP_TYPE_TOMATILLO);
2070} 2049}
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index 5419480edf41..b63b2834133f 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -18,6 +18,7 @@
18#include <asm/pstate.h> 18#include <asm/pstate.h>
19#include <asm/oplib.h> 19#include <asm/oplib.h>
20#include <asm/hypervisor.h> 20#include <asm/hypervisor.h>
21#include <asm/prom.h>
21 22
22#include "pci_impl.h" 23#include "pci_impl.h"
23#include "iommu_common.h" 24#include "iommu_common.h"
@@ -646,35 +647,37 @@ static int pdev_htab_add(u32 devhandle, unsigned int bus, unsigned int device, u
646/* Recursively descend into the OBP device tree, rooted at toplevel_node, 647/* Recursively descend into the OBP device tree, rooted at toplevel_node,
647 * looking for a PCI device matching bus and devfn. 648 * looking for a PCI device matching bus and devfn.
648 */ 649 */
649static int obp_find(struct linux_prom_pci_registers *pregs, int toplevel_node, unsigned int bus, unsigned int devfn) 650static int obp_find(struct device_node *toplevel_node, unsigned int bus, unsigned int devfn)
650{ 651{
651 toplevel_node = prom_getchild(toplevel_node); 652 toplevel_node = toplevel_node->child;
652 653
653 while (toplevel_node != 0) { 654 while (toplevel_node != NULL) {
654 int ret = obp_find(pregs, toplevel_node, bus, devfn); 655 struct linux_prom_pci_registers *regs;
656 struct property *prop;
657 int ret;
655 658
659 ret = obp_find(toplevel_node, bus, devfn);
656 if (ret != 0) 660 if (ret != 0)
657 return ret; 661 return ret;
658 662
659 ret = prom_getproperty(toplevel_node, "reg", (char *) pregs, 663 prop = of_find_property(toplevel_node, "reg", NULL);
660 sizeof(*pregs) * PROMREG_MAX); 664 if (!prop)
661 if (ret == 0 || ret == -1)
662 goto next_sibling; 665 goto next_sibling;
663 666
664 if (((pregs[0].phys_hi >> 16) & 0xff) == bus && 667 regs = prop->value;
665 ((pregs[0].phys_hi >> 8) & 0xff) == devfn) 668 if (((regs->phys_hi >> 16) & 0xff) == bus &&
669 ((regs->phys_hi >> 8) & 0xff) == devfn)
666 break; 670 break;
667 671
668 next_sibling: 672 next_sibling:
669 toplevel_node = prom_getsibling(toplevel_node); 673 toplevel_node = toplevel_node->sibling;
670 } 674 }
671 675
672 return toplevel_node; 676 return toplevel_node != NULL;
673} 677}
674 678
675static int pdev_htab_populate(struct pci_pbm_info *pbm) 679static int pdev_htab_populate(struct pci_pbm_info *pbm)
676{ 680{
677 struct linux_prom_pci_registers pr[PROMREG_MAX];
678 u32 devhandle = pbm->devhandle; 681 u32 devhandle = pbm->devhandle;
679 unsigned int bus; 682 unsigned int bus;
680 683
@@ -685,7 +688,7 @@ static int pdev_htab_populate(struct pci_pbm_info *pbm)
685 unsigned int device = PCI_SLOT(devfn); 688 unsigned int device = PCI_SLOT(devfn);
686 unsigned int func = PCI_FUNC(devfn); 689 unsigned int func = PCI_FUNC(devfn);
687 690
688 if (obp_find(pr, pbm->prom_node, bus, devfn)) { 691 if (obp_find(pbm->prom_node, bus, devfn)) {
689 int err = pdev_htab_add(devhandle, bus, 692 int err = pdev_htab_add(devhandle, bus,
690 device, func); 693 device, func);
691 if (err) 694 if (err)
@@ -812,7 +815,7 @@ static void pbm_scan_bus(struct pci_controller_info *p,
812 pbm->pci_bus->self->sysdata = cookie; 815 pbm->pci_bus->self->sysdata = cookie;
813#endif 816#endif
814 pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, 817 pci_fill_in_pbm_cookies(pbm->pci_bus, pbm,
815 pbm->prom_node); 818 pbm->prom_node->node);
816 pci_record_assignments(pbm, pbm->pci_bus); 819 pci_record_assignments(pbm, pbm->pci_bus);
817 pci_assign_unassigned(pbm, pbm->pci_bus); 820 pci_assign_unassigned(pbm, pbm->pci_bus);
818 pci_fixup_irq(pbm, pbm->pci_bus); 821 pci_fixup_irq(pbm, pbm->pci_bus);
@@ -822,15 +825,18 @@ static void pbm_scan_bus(struct pci_controller_info *p,
822 825
823static void pci_sun4v_scan_bus(struct pci_controller_info *p) 826static void pci_sun4v_scan_bus(struct pci_controller_info *p)
824{ 827{
825 if (p->pbm_A.prom_node) { 828 struct property *prop;
826 p->pbm_A.is_66mhz_capable = 829 struct device_node *dp;
827 prom_getbool(p->pbm_A.prom_node, "66mhz-capable"); 830
831 if ((dp = p->pbm_A.prom_node) != NULL) {
832 prop = of_find_property(dp, "66mhz-capable", NULL);
833 p->pbm_A.is_66mhz_capable = (prop != NULL);
828 834
829 pbm_scan_bus(p, &p->pbm_A); 835 pbm_scan_bus(p, &p->pbm_A);
830 } 836 }
831 if (p->pbm_B.prom_node) { 837 if ((dp = p->pbm_B.prom_node) != NULL) {
832 p->pbm_B.is_66mhz_capable = 838 prop = of_find_property(dp, "66mhz-capable", NULL);
833 prom_getbool(p->pbm_B.prom_node, "66mhz-capable"); 839 p->pbm_B.is_66mhz_capable = (prop != NULL);
834 840
835 pbm_scan_bus(p, &p->pbm_B); 841 pbm_scan_bus(p, &p->pbm_B);
836 } 842 }
@@ -993,13 +999,18 @@ static unsigned long probe_existing_entries(struct pci_pbm_info *pbm,
993static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm) 999static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
994{ 1000{
995 struct pci_iommu *iommu = pbm->iommu; 1001 struct pci_iommu *iommu = pbm->iommu;
1002 struct property *prop;
996 unsigned long num_tsb_entries, sz; 1003 unsigned long num_tsb_entries, sz;
997 u32 vdma[2], dma_mask, dma_offset; 1004 u32 vdma[2], dma_mask, dma_offset;
998 int err, tsbsize; 1005 int tsbsize;
1006
1007 prop = of_find_property(pbm->prom_node, "virtual-dma", NULL);
1008 if (prop) {
1009 u32 *val = prop->value;
999 1010
1000 err = prom_getproperty(pbm->prom_node, "virtual-dma", 1011 vdma[0] = val[0];
1001 (char *)&vdma[0], sizeof(vdma)); 1012 vdma[1] = val[1];
1002 if (err == 0 || err == -1) { 1013 } else {
1003 /* No property, use default values. */ 1014 /* No property, use default values. */
1004 vdma[0] = 0x80000000; 1015 vdma[0] = 0x80000000;
1005 vdma[1] = 0x80000000; 1016 vdma[1] = 0x80000000;
@@ -1058,27 +1069,23 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
1058 1069
1059static void pci_sun4v_get_bus_range(struct pci_pbm_info *pbm) 1070static void pci_sun4v_get_bus_range(struct pci_pbm_info *pbm)
1060{ 1071{
1061 unsigned int busrange[2]; 1072 struct property *prop;
1062 int prom_node = pbm->prom_node; 1073 unsigned int *busrange;
1063 int err; 1074
1064 1075 prop = of_find_property(pbm->prom_node, "bus-range", NULL);
1065 err = prom_getproperty(prom_node, "bus-range", 1076
1066 (char *)&busrange[0], 1077 busrange = prop->value;
1067 sizeof(busrange));
1068 if (err == 0 || err == -1) {
1069 prom_printf("%s: Fatal error, no bus-range.\n", pbm->name);
1070 prom_halt();
1071 }
1072 1078
1073 pbm->pci_first_busno = busrange[0]; 1079 pbm->pci_first_busno = busrange[0];
1074 pbm->pci_last_busno = busrange[1]; 1080 pbm->pci_last_busno = busrange[1];
1075 1081
1076} 1082}
1077 1083
1078static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node, u32 devhandle) 1084static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 devhandle)
1079{ 1085{
1080 struct pci_pbm_info *pbm; 1086 struct pci_pbm_info *pbm;
1081 int err, i; 1087 struct property *prop;
1088 int len, i;
1082 1089
1083 if (devhandle & 0x40) 1090 if (devhandle & 0x40)
1084 pbm = &p->pbm_B; 1091 pbm = &p->pbm_B;
@@ -1086,32 +1093,19 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node, u32
1086 pbm = &p->pbm_A; 1093 pbm = &p->pbm_A;
1087 1094
1088 pbm->parent = p; 1095 pbm->parent = p;
1089 pbm->prom_node = prom_node; 1096 pbm->prom_node = dp;
1090 pbm->pci_first_slot = 1; 1097 pbm->pci_first_slot = 1;
1091 1098
1092 pbm->devhandle = devhandle; 1099 pbm->devhandle = devhandle;
1093 1100
1094 sprintf(pbm->name, "SUN4V-PCI%d PBM%c", 1101 pbm->name = dp->full_name;
1095 p->index, (pbm == &p->pbm_A ? 'A' : 'B'));
1096
1097 printk("%s: devhandle[%x] prom_node[%x:%x]\n",
1098 pbm->name, pbm->devhandle,
1099 pbm->prom_node, prom_getchild(pbm->prom_node));
1100 1102
1101 prom_getstring(prom_node, "name", 1103 printk("%s: SUN4V PCI Bus Module\n", pbm->name);
1102 pbm->prom_name, sizeof(pbm->prom_name));
1103
1104 err = prom_getproperty(prom_node, "ranges",
1105 (char *) pbm->pbm_ranges,
1106 sizeof(pbm->pbm_ranges));
1107 if (err == 0 || err == -1) {
1108 prom_printf("%s: Fatal error, no ranges property.\n",
1109 pbm->name);
1110 prom_halt();
1111 }
1112 1104
1105 prop = of_find_property(dp, "ranges", &len);
1106 pbm->pbm_ranges = prop->value;
1113 pbm->num_pbm_ranges = 1107 pbm->num_pbm_ranges =
1114 (err / sizeof(struct linux_prom_pci_ranges)); 1108 (len / sizeof(struct linux_prom_pci_ranges));
1115 1109
1116 /* Mask out the top 8 bits of the ranges, leaving the real 1110 /* Mask out the top 8 bits of the ranges, leaving the real
1117 * physical address. 1111 * physical address.
@@ -1122,24 +1116,13 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node, u32
1122 pci_sun4v_determine_mem_io_space(pbm); 1116 pci_sun4v_determine_mem_io_space(pbm);
1123 pbm_register_toplevel_resources(p, pbm); 1117 pbm_register_toplevel_resources(p, pbm);
1124 1118
1125 err = prom_getproperty(prom_node, "interrupt-map", 1119 prop = of_find_property(dp, "interrupt-map", &len);
1126 (char *)pbm->pbm_intmap, 1120 pbm->pbm_intmap = prop->value;
1127 sizeof(pbm->pbm_intmap)); 1121 pbm->num_pbm_intmap =
1128 if (err == 0 || err == -1) { 1122 (len / sizeof(struct linux_prom_pci_intmap));
1129 prom_printf("%s: Fatal error, no interrupt-map property.\n",
1130 pbm->name);
1131 prom_halt();
1132 }
1133 1123
1134 pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap)); 1124 prop = of_find_property(dp, "interrupt-map-mask", NULL);
1135 err = prom_getproperty(prom_node, "interrupt-map-mask", 1125 pbm->pbm_intmask = prop->value;
1136 (char *)&pbm->pbm_intmask,
1137 sizeof(pbm->pbm_intmask));
1138 if (err == 0 || err == -1) {
1139 prom_printf("%s: Fatal error, no interrupt-map-mask.\n",
1140 pbm->name);
1141 prom_halt();
1142 }
1143 1126
1144 pci_sun4v_get_bus_range(pbm); 1127 pci_sun4v_get_bus_range(pbm);
1145 pci_sun4v_iommu_init(pbm); 1128 pci_sun4v_iommu_init(pbm);
@@ -1147,16 +1130,19 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node, u32
1147 pdev_htab_populate(pbm); 1130 pdev_htab_populate(pbm);
1148} 1131}
1149 1132
1150void sun4v_pci_init(int node, char *model_name) 1133void sun4v_pci_init(struct device_node *dp, char *model_name)
1151{ 1134{
1152 struct pci_controller_info *p; 1135 struct pci_controller_info *p;
1153 struct pci_iommu *iommu; 1136 struct pci_iommu *iommu;
1154 struct linux_prom64_registers regs; 1137 struct property *prop;
1138 struct linux_prom64_registers *regs;
1155 u32 devhandle; 1139 u32 devhandle;
1156 int i; 1140 int i;
1157 1141
1158 prom_getproperty(node, "reg", (char *)&regs, sizeof(regs)); 1142 prop = of_find_property(dp, "reg", NULL);
1159 devhandle = (regs.phys_addr >> 32UL) & 0x0fffffff; 1143 regs = prop->value;
1144
1145 devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff;
1160 1146
1161 for (p = pci_controller_root; p; p = p->next) { 1147 for (p = pci_controller_root; p; p = p->next) {
1162 struct pci_pbm_info *pbm; 1148 struct pci_pbm_info *pbm;
@@ -1169,7 +1155,7 @@ void sun4v_pci_init(int node, char *model_name)
1169 &p->pbm_B); 1155 &p->pbm_B);
1170 1156
1171 if (pbm->devhandle == (devhandle ^ 0x40)) { 1157 if (pbm->devhandle == (devhandle ^ 0x40)) {
1172 pci_sun4v_pbm_init(p, node, devhandle); 1158 pci_sun4v_pbm_init(p, dp, devhandle);
1173 return; 1159 return;
1174 } 1160 }
1175 } 1161 }
@@ -1220,7 +1206,7 @@ void sun4v_pci_init(int node, char *model_name)
1220 */ 1206 */
1221 pci_memspace_mask = 0x7fffffffUL; 1207 pci_memspace_mask = 0x7fffffffUL;
1222 1208
1223 pci_sun4v_pbm_init(p, node, devhandle); 1209 pci_sun4v_pbm_init(p, dp, devhandle);
1224 return; 1210 return;
1225 1211
1226fatal_memory_error: 1212fatal_memory_error:
diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h
index 1396f110939a..142cc4028bb8 100644
--- a/include/asm-sparc64/pbm.h
+++ b/include/asm-sparc64/pbm.h
@@ -15,6 +15,7 @@
15#include <asm/io.h> 15#include <asm/io.h>
16#include <asm/page.h> 16#include <asm/page.h>
17#include <asm/oplib.h> 17#include <asm/oplib.h>
18#include <asm/prom.h>
18#include <asm/iommu.h> 19#include <asm/iommu.h>
19 20
20/* The abstraction used here is that there are PCI controllers, 21/* The abstraction used here is that there are PCI controllers,
@@ -153,16 +154,15 @@ struct pci_pbm_info {
153 int chip_revision; 154 int chip_revision;
154 155
155 /* Name used for top-level resources. */ 156 /* Name used for top-level resources. */
156 char name[64]; 157 char *name;
157 158
158 /* OBP specific information. */ 159 /* OBP specific information. */
159 int prom_node; 160 struct device_node *prom_node;
160 char prom_name[64]; 161 struct linux_prom_pci_ranges *pbm_ranges;
161 struct linux_prom_pci_ranges pbm_ranges[PROM_PCIRNG_MAX];
162 int num_pbm_ranges; 162 int num_pbm_ranges;
163 struct linux_prom_pci_intmap pbm_intmap[PROM_PCIIMAP_MAX]; 163 struct linux_prom_pci_intmap *pbm_intmap;
164 int num_pbm_intmap; 164 int num_pbm_intmap;
165 struct linux_prom_pci_intmask pbm_intmask; 165 struct linux_prom_pci_intmask *pbm_intmask;
166 u64 ino_bitmap; 166 u64 ino_bitmap;
167 167
168 /* PBM I/O and Memory space resources. */ 168 /* PBM I/O and Memory space resources. */