diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-06-21 21:18:47 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-06-24 02:15:07 -0400 |
commit | e87dc35020bc555969810452f44bceaf8394eafa (patch) | |
tree | b58f14d41f8e147f6ddc2d9657a88813fdb73bdf | |
parent | aaf7cec2769942035985716452107fc5ba0b11f6 (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.c | 53 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_common.c | 15 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_psycho.c | 108 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_sabre.c | 192 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_schizo.c | 173 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_sun4v.c | 144 | ||||
-rw-r--r-- | include/asm-sparc64/pbm.h | 12 |
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 | ||
26 | unsigned long pci_memspace_mask = 0xffffffffUL; | 27 | unsigned 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. */ |
180 | extern void sabre_init(int, char *); | 181 | extern void sabre_init(struct device_node *, const char *); |
181 | extern void psycho_init(int, char *); | 182 | extern void psycho_init(struct device_node *, const char *); |
182 | extern void schizo_init(int, char *); | 183 | extern void schizo_init(struct device_node *, const char *); |
183 | extern void schizo_plus_init(int, char *); | 184 | extern void schizo_plus_init(struct device_node *, const char *); |
184 | extern void tomatillo_init(int, char *); | 185 | extern void tomatillo_init(struct device_node *, const char *); |
185 | extern void sun4v_pci_init(int, char *); | 186 | extern void sun4v_pci_init(struct device_node *, const char *); |
186 | 187 | ||
187 | static struct { | 188 | static 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 | ||
207 | static int __init pci_controller_init(char *model_name, int namelen, int node) | 208 | static 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 | ||
226 | static int __init pci_is_controller(char *model_name, int namelen, int node) | 224 | static 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 | ||
240 | static int __init pci_controller_scan(int (*handler)(char *, int, int)) | 238 | static 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 | ||
716 | success: | 716 | success: |
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 | ||
1293 | static void psycho_pbm_init(struct pci_controller_info *p, | 1294 | static 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 | ||
1372 | void psycho_init(int node, char *model_name) | 1369 | void 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 | ||
1309 | static void sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dma_begin) | 1310 | static 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 | ||
1446 | void sabre_init(int pnode, char *model_name) | 1434 | void 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 | ||
1779 | static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) | 1787 | static 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 | ||
1833 | static void schizo_pbm_init(struct pci_controller_info *p, | 1843 | static 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 | ||
1992 | static void __schizo_init(int node, char *model_name, int chip_type) | 1967 | static 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 | ||
2057 | void schizo_init(int node, char *model_name) | 2036 | void 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 | ||
2062 | void schizo_plus_init(int node, char *model_name) | 2041 | void 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 | ||
2067 | void tomatillo_init(int node, char *model_name) | 2046 | void 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 | */ |
649 | static int obp_find(struct linux_prom_pci_registers *pregs, int toplevel_node, unsigned int bus, unsigned int devfn) | 650 | static 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 | ||
675 | static int pdev_htab_populate(struct pci_pbm_info *pbm) | 679 | static 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 | ||
823 | static void pci_sun4v_scan_bus(struct pci_controller_info *p) | 826 | static 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, | |||
993 | static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm) | 999 | static 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 | ||
1059 | static void pci_sun4v_get_bus_range(struct pci_pbm_info *pbm) | 1070 | static 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 | ||
1078 | static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node, u32 devhandle) | 1084 | static 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 | ||
1150 | void sun4v_pci_init(int node, char *model_name) | 1133 | void 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 *)®s, 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 | ||
1226 | fatal_memory_error: | 1212 | fatal_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. */ |