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. */ |
