diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2005-12-13 02:01:21 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-01-08 22:53:55 -0500 |
commit | cc5d0189b9ba95260857a5018a1c2fef90008507 (patch) | |
tree | 1202c94b6b3cb81a96d0a0e54424cad10eef68bb /arch | |
parent | 9cf84d7c97992dbe5360b241327341c07ce30fc9 (diff) |
[PATCH] powerpc: Remove device_node addrs/n_addr
The pre-parsed addrs/n_addrs fields in struct device_node are finally
gone. Remove the dodgy heuristics that did that parsing at boot and
remove the fields themselves since we now have a good replacement with
the new OF parsing code. This patch also fixes a bunch of drivers to use
the new code instead, so that at least pmac32, pseries, iseries and g5
defconfigs build.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kernel/btext.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/pci_64.c | 24 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom.c | 424 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom_init.c | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/rtas_pci.c | 49 | ||||
-rw-r--r-- | arch/powerpc/mm/numa.c | 6 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/feature.c | 75 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/nvram.c | 52 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/pci.c | 87 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/pic.c | 456 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/pmac.h | 6 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/setup.c | 3 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/time.c | 15 |
13 files changed, 431 insertions, 771 deletions
diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c index 5de0d80ca2f2..6223d39177cb 100644 --- a/arch/powerpc/kernel/btext.c +++ b/arch/powerpc/kernel/btext.c | |||
@@ -211,8 +211,6 @@ int __init btext_find_display(int allow_nonstdout) | |||
211 | struct device_node *np = NULL; | 211 | struct device_node *np = NULL; |
212 | int rc = -ENODEV; | 212 | int rc = -ENODEV; |
213 | 213 | ||
214 | printk("trying to initialize btext ...\n"); | ||
215 | |||
216 | name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); | 214 | name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); |
217 | if (name != NULL) { | 215 | if (name != NULL) { |
218 | np = of_find_node_by_path(name); | 216 | np = of_find_node_by_path(name); |
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 4eb93fc1eef2..523f35087e81 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
@@ -896,6 +896,25 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node, | |||
896 | unsigned long phb_io_base_phys, | 896 | unsigned long phb_io_base_phys, |
897 | void __iomem * phb_io_base_virt) | 897 | void __iomem * phb_io_base_virt) |
898 | { | 898 | { |
899 | /* Remove these asap */ | ||
900 | |||
901 | struct pci_address { | ||
902 | u32 a_hi; | ||
903 | u32 a_mid; | ||
904 | u32 a_lo; | ||
905 | }; | ||
906 | |||
907 | struct isa_address { | ||
908 | u32 a_hi; | ||
909 | u32 a_lo; | ||
910 | }; | ||
911 | |||
912 | struct isa_range { | ||
913 | struct isa_address isa_addr; | ||
914 | struct pci_address pci_addr; | ||
915 | unsigned int size; | ||
916 | }; | ||
917 | |||
899 | struct isa_range *range; | 918 | struct isa_range *range; |
900 | unsigned long pci_addr; | 919 | unsigned long pci_addr; |
901 | unsigned int isa_addr; | 920 | unsigned int isa_addr; |
@@ -1330,8 +1349,9 @@ unsigned int pci_address_to_pio(phys_addr_t address) | |||
1330 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { | 1349 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { |
1331 | if (address >= hose->io_base_phys && | 1350 | if (address >= hose->io_base_phys && |
1332 | address < (hose->io_base_phys + hose->pci_io_size)) | 1351 | address < (hose->io_base_phys + hose->pci_io_size)) |
1333 | return (unsigned int)hose->io_base_virt + | 1352 | return (unsigned int) |
1334 | (address - hose->io_base_phys); | 1353 | ((unsigned long)hose->io_base_virt + |
1354 | (address - hose->io_base_phys)); | ||
1335 | } | 1355 | } |
1336 | return (unsigned int)-1; | 1356 | return (unsigned int)-1; |
1337 | } | 1357 | } |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 7e798d5b03b4..1b97e13657e5 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -57,21 +57,6 @@ | |||
57 | #define DBG(fmt...) | 57 | #define DBG(fmt...) |
58 | #endif | 58 | #endif |
59 | 59 | ||
60 | struct pci_reg_property { | ||
61 | struct pci_address addr; | ||
62 | u32 size_hi; | ||
63 | u32 size_lo; | ||
64 | }; | ||
65 | |||
66 | struct isa_reg_property { | ||
67 | u32 space; | ||
68 | u32 address; | ||
69 | u32 size; | ||
70 | }; | ||
71 | |||
72 | |||
73 | typedef int interpret_func(struct device_node *, unsigned long *, | ||
74 | int, int, int); | ||
75 | 60 | ||
76 | static int __initdata dt_root_addr_cells; | 61 | static int __initdata dt_root_addr_cells; |
77 | static int __initdata dt_root_size_cells; | 62 | static int __initdata dt_root_size_cells; |
@@ -410,237 +395,19 @@ static int __devinit finish_node_interrupts(struct device_node *np, | |||
410 | return 0; | 395 | return 0; |
411 | } | 396 | } |
412 | 397 | ||
413 | static int __devinit interpret_pci_props(struct device_node *np, | ||
414 | unsigned long *mem_start, | ||
415 | int naddrc, int nsizec, | ||
416 | int measure_only) | ||
417 | { | ||
418 | struct address_range *adr; | ||
419 | struct pci_reg_property *pci_addrs; | ||
420 | int i, l, n_addrs; | ||
421 | |||
422 | pci_addrs = (struct pci_reg_property *) | ||
423 | get_property(np, "assigned-addresses", &l); | ||
424 | if (!pci_addrs) | ||
425 | return 0; | ||
426 | |||
427 | n_addrs = l / sizeof(*pci_addrs); | ||
428 | |||
429 | adr = prom_alloc(n_addrs * sizeof(*adr), mem_start); | ||
430 | if (!adr) | ||
431 | return -ENOMEM; | ||
432 | |||
433 | if (measure_only) | ||
434 | return 0; | ||
435 | |||
436 | np->addrs = adr; | ||
437 | np->n_addrs = n_addrs; | ||
438 | |||
439 | for (i = 0; i < n_addrs; i++) { | ||
440 | adr[i].space = pci_addrs[i].addr.a_hi; | ||
441 | adr[i].address = pci_addrs[i].addr.a_lo | | ||
442 | ((u64)pci_addrs[i].addr.a_mid << 32); | ||
443 | adr[i].size = pci_addrs[i].size_lo; | ||
444 | } | ||
445 | |||
446 | return 0; | ||
447 | } | ||
448 | |||
449 | static int __init interpret_dbdma_props(struct device_node *np, | ||
450 | unsigned long *mem_start, | ||
451 | int naddrc, int nsizec, | ||
452 | int measure_only) | ||
453 | { | ||
454 | struct reg_property32 *rp; | ||
455 | struct address_range *adr; | ||
456 | unsigned long base_address; | ||
457 | int i, l; | ||
458 | struct device_node *db; | ||
459 | |||
460 | base_address = 0; | ||
461 | if (!measure_only) { | ||
462 | for (db = np->parent; db != NULL; db = db->parent) { | ||
463 | if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) { | ||
464 | base_address = db->addrs[0].address; | ||
465 | break; | ||
466 | } | ||
467 | } | ||
468 | } | ||
469 | |||
470 | rp = (struct reg_property32 *) get_property(np, "reg", &l); | ||
471 | if (rp != 0 && l >= sizeof(struct reg_property32)) { | ||
472 | i = 0; | ||
473 | adr = (struct address_range *) (*mem_start); | ||
474 | while ((l -= sizeof(struct reg_property32)) >= 0) { | ||
475 | if (!measure_only) { | ||
476 | adr[i].space = 2; | ||
477 | adr[i].address = rp[i].address + base_address; | ||
478 | adr[i].size = rp[i].size; | ||
479 | } | ||
480 | ++i; | ||
481 | } | ||
482 | np->addrs = adr; | ||
483 | np->n_addrs = i; | ||
484 | (*mem_start) += i * sizeof(struct address_range); | ||
485 | } | ||
486 | |||
487 | return 0; | ||
488 | } | ||
489 | |||
490 | static int __init interpret_macio_props(struct device_node *np, | ||
491 | unsigned long *mem_start, | ||
492 | int naddrc, int nsizec, | ||
493 | int measure_only) | ||
494 | { | ||
495 | struct reg_property32 *rp; | ||
496 | struct address_range *adr; | ||
497 | unsigned long base_address; | ||
498 | int i, l; | ||
499 | struct device_node *db; | ||
500 | |||
501 | base_address = 0; | ||
502 | if (!measure_only) { | ||
503 | for (db = np->parent; db != NULL; db = db->parent) { | ||
504 | if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) { | ||
505 | base_address = db->addrs[0].address; | ||
506 | break; | ||
507 | } | ||
508 | } | ||
509 | } | ||
510 | |||
511 | rp = (struct reg_property32 *) get_property(np, "reg", &l); | ||
512 | if (rp != 0 && l >= sizeof(struct reg_property32)) { | ||
513 | i = 0; | ||
514 | adr = (struct address_range *) (*mem_start); | ||
515 | while ((l -= sizeof(struct reg_property32)) >= 0) { | ||
516 | if (!measure_only) { | ||
517 | adr[i].space = 2; | ||
518 | adr[i].address = rp[i].address + base_address; | ||
519 | adr[i].size = rp[i].size; | ||
520 | } | ||
521 | ++i; | ||
522 | } | ||
523 | np->addrs = adr; | ||
524 | np->n_addrs = i; | ||
525 | (*mem_start) += i * sizeof(struct address_range); | ||
526 | } | ||
527 | |||
528 | return 0; | ||
529 | } | ||
530 | |||
531 | static int __init interpret_isa_props(struct device_node *np, | ||
532 | unsigned long *mem_start, | ||
533 | int naddrc, int nsizec, | ||
534 | int measure_only) | ||
535 | { | ||
536 | struct isa_reg_property *rp; | ||
537 | struct address_range *adr; | ||
538 | int i, l; | ||
539 | |||
540 | rp = (struct isa_reg_property *) get_property(np, "reg", &l); | ||
541 | if (rp != 0 && l >= sizeof(struct isa_reg_property)) { | ||
542 | i = 0; | ||
543 | adr = (struct address_range *) (*mem_start); | ||
544 | while ((l -= sizeof(struct isa_reg_property)) >= 0) { | ||
545 | if (!measure_only) { | ||
546 | adr[i].space = rp[i].space; | ||
547 | adr[i].address = rp[i].address; | ||
548 | adr[i].size = rp[i].size; | ||
549 | } | ||
550 | ++i; | ||
551 | } | ||
552 | np->addrs = adr; | ||
553 | np->n_addrs = i; | ||
554 | (*mem_start) += i * sizeof(struct address_range); | ||
555 | } | ||
556 | |||
557 | return 0; | ||
558 | } | ||
559 | |||
560 | static int __init interpret_root_props(struct device_node *np, | ||
561 | unsigned long *mem_start, | ||
562 | int naddrc, int nsizec, | ||
563 | int measure_only) | ||
564 | { | ||
565 | struct address_range *adr; | ||
566 | int i, l; | ||
567 | unsigned int *rp; | ||
568 | int rpsize = (naddrc + nsizec) * sizeof(unsigned int); | ||
569 | |||
570 | rp = (unsigned int *) get_property(np, "linux,usable-memory", &l); | ||
571 | if (rp == NULL) | ||
572 | rp = (unsigned int *) get_property(np, "reg", &l); | ||
573 | |||
574 | if (rp != 0 && l >= rpsize) { | ||
575 | i = 0; | ||
576 | adr = (struct address_range *) (*mem_start); | ||
577 | while ((l -= rpsize) >= 0) { | ||
578 | if (!measure_only) { | ||
579 | adr[i].space = 0; | ||
580 | adr[i].address = rp[naddrc - 1]; | ||
581 | adr[i].size = rp[naddrc + nsizec - 1]; | ||
582 | } | ||
583 | ++i; | ||
584 | rp += naddrc + nsizec; | ||
585 | } | ||
586 | np->addrs = adr; | ||
587 | np->n_addrs = i; | ||
588 | (*mem_start) += i * sizeof(struct address_range); | ||
589 | } | ||
590 | |||
591 | return 0; | ||
592 | } | ||
593 | |||
594 | static int __devinit finish_node(struct device_node *np, | 398 | static int __devinit finish_node(struct device_node *np, |
595 | unsigned long *mem_start, | 399 | unsigned long *mem_start, |
596 | interpret_func *ifunc, | ||
597 | int naddrc, int nsizec, | ||
598 | int measure_only) | 400 | int measure_only) |
599 | { | 401 | { |
600 | struct device_node *child; | 402 | struct device_node *child; |
601 | int *ip, rc = 0; | 403 | int rc = 0; |
602 | |||
603 | /* get the device addresses and interrupts */ | ||
604 | if (ifunc != NULL) | ||
605 | rc = ifunc(np, mem_start, naddrc, nsizec, measure_only); | ||
606 | if (rc) | ||
607 | goto out; | ||
608 | 404 | ||
609 | rc = finish_node_interrupts(np, mem_start, measure_only); | 405 | rc = finish_node_interrupts(np, mem_start, measure_only); |
610 | if (rc) | 406 | if (rc) |
611 | goto out; | 407 | goto out; |
612 | 408 | ||
613 | /* Look for #address-cells and #size-cells properties. */ | ||
614 | ip = (int *) get_property(np, "#address-cells", NULL); | ||
615 | if (ip != NULL) | ||
616 | naddrc = *ip; | ||
617 | ip = (int *) get_property(np, "#size-cells", NULL); | ||
618 | if (ip != NULL) | ||
619 | nsizec = *ip; | ||
620 | |||
621 | if (!strcmp(np->name, "device-tree") || np->parent == NULL) | ||
622 | ifunc = interpret_root_props; | ||
623 | else if (np->type == 0) | ||
624 | ifunc = NULL; | ||
625 | else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci")) | ||
626 | ifunc = interpret_pci_props; | ||
627 | else if (!strcmp(np->type, "dbdma")) | ||
628 | ifunc = interpret_dbdma_props; | ||
629 | else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props) | ||
630 | ifunc = interpret_macio_props; | ||
631 | else if (!strcmp(np->type, "isa")) | ||
632 | ifunc = interpret_isa_props; | ||
633 | else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3")) | ||
634 | ifunc = interpret_root_props; | ||
635 | else if (!((ifunc == interpret_dbdma_props | ||
636 | || ifunc == interpret_macio_props) | ||
637 | && (!strcmp(np->type, "escc") | ||
638 | || !strcmp(np->type, "media-bay")))) | ||
639 | ifunc = NULL; | ||
640 | |||
641 | for (child = np->child; child != NULL; child = child->sibling) { | 409 | for (child = np->child; child != NULL; child = child->sibling) { |
642 | rc = finish_node(child, mem_start, ifunc, | 410 | rc = finish_node(child, mem_start, measure_only); |
643 | naddrc, nsizec, measure_only); | ||
644 | if (rc) | 411 | if (rc) |
645 | goto out; | 412 | goto out; |
646 | } | 413 | } |
@@ -702,10 +469,10 @@ void __init finish_device_tree(void) | |||
702 | * reason and then remove those additional 16 bytes | 469 | * reason and then remove those additional 16 bytes |
703 | */ | 470 | */ |
704 | size = 16; | 471 | size = 16; |
705 | finish_node(allnodes, &size, NULL, 0, 0, 1); | 472 | finish_node(allnodes, &size, 1); |
706 | size -= 16; | 473 | size -= 16; |
707 | end = start = (unsigned long) __va(lmb_alloc(size, 128)); | 474 | end = start = (unsigned long) __va(lmb_alloc(size, 128)); |
708 | finish_node(allnodes, &end, NULL, 0, 0, 0); | 475 | finish_node(allnodes, &end, 0); |
709 | BUG_ON(end != start + size); | 476 | BUG_ON(end != start + size); |
710 | 477 | ||
711 | DBG(" <- finish_device_tree\n"); | 478 | DBG(" <- finish_device_tree\n"); |
@@ -1822,7 +1589,6 @@ static void of_node_release(struct kref *kref) | |||
1822 | prop = next; | 1589 | prop = next; |
1823 | } | 1590 | } |
1824 | kfree(node->intrs); | 1591 | kfree(node->intrs); |
1825 | kfree(node->addrs); | ||
1826 | kfree(node->full_name); | 1592 | kfree(node->full_name); |
1827 | kfree(node->data); | 1593 | kfree(node->data); |
1828 | kfree(node); | 1594 | kfree(node); |
@@ -1904,9 +1670,7 @@ void of_detach_node(const struct device_node *np) | |||
1904 | * This should probably be split up into smaller chunks. | 1670 | * This should probably be split up into smaller chunks. |
1905 | */ | 1671 | */ |
1906 | 1672 | ||
1907 | static int of_finish_dynamic_node(struct device_node *node, | 1673 | static int of_finish_dynamic_node(struct device_node *node) |
1908 | unsigned long *unused1, int unused2, | ||
1909 | int unused3, int unused4) | ||
1910 | { | 1674 | { |
1911 | struct device_node *parent = of_get_parent(node); | 1675 | struct device_node *parent = of_get_parent(node); |
1912 | int err = 0; | 1676 | int err = 0; |
@@ -1927,7 +1691,8 @@ static int of_finish_dynamic_node(struct device_node *node, | |||
1927 | return -ENODEV; | 1691 | return -ENODEV; |
1928 | 1692 | ||
1929 | /* fix up new node's linux_phandle field */ | 1693 | /* fix up new node's linux_phandle field */ |
1930 | if ((ibm_phandle = (unsigned int *)get_property(node, "ibm,phandle", NULL))) | 1694 | if ((ibm_phandle = (unsigned int *)get_property(node, |
1695 | "ibm,phandle", NULL))) | ||
1931 | node->linux_phandle = *ibm_phandle; | 1696 | node->linux_phandle = *ibm_phandle; |
1932 | 1697 | ||
1933 | out: | 1698 | out: |
@@ -1942,7 +1707,9 @@ static int prom_reconfig_notifier(struct notifier_block *nb, | |||
1942 | 1707 | ||
1943 | switch (action) { | 1708 | switch (action) { |
1944 | case PSERIES_RECONFIG_ADD: | 1709 | case PSERIES_RECONFIG_ADD: |
1945 | err = finish_node(node, NULL, of_finish_dynamic_node, 0, 0, 0); | 1710 | err = of_finish_dynamic_node(node); |
1711 | if (!err) | ||
1712 | finish_node(node, NULL, 0); | ||
1946 | if (err < 0) { | 1713 | if (err < 0) { |
1947 | printk(KERN_ERR "finish_node returned %d\n", err); | 1714 | printk(KERN_ERR "finish_node returned %d\n", err); |
1948 | err = NOTIFY_BAD; | 1715 | err = NOTIFY_BAD; |
@@ -2016,175 +1783,4 @@ int prom_add_property(struct device_node* np, struct property* prop) | |||
2016 | return 0; | 1783 | return 0; |
2017 | } | 1784 | } |
2018 | 1785 | ||
2019 | /* I quickly hacked that one, check against spec ! */ | ||
2020 | static inline unsigned long | ||
2021 | bus_space_to_resource_flags(unsigned int bus_space) | ||
2022 | { | ||
2023 | u8 space = (bus_space >> 24) & 0xf; | ||
2024 | if (space == 0) | ||
2025 | space = 0x02; | ||
2026 | if (space == 0x02) | ||
2027 | return IORESOURCE_MEM; | ||
2028 | else if (space == 0x01) | ||
2029 | return IORESOURCE_IO; | ||
2030 | else { | ||
2031 | printk(KERN_WARNING "prom.c: bus_space_to_resource_flags(), space: %x\n", | ||
2032 | bus_space); | ||
2033 | return 0; | ||
2034 | } | ||
2035 | } | ||
2036 | |||
2037 | #ifdef CONFIG_PCI | ||
2038 | static struct resource *find_parent_pci_resource(struct pci_dev* pdev, | ||
2039 | struct address_range *range) | ||
2040 | { | ||
2041 | unsigned long mask; | ||
2042 | int i; | ||
2043 | |||
2044 | /* Check this one */ | ||
2045 | mask = bus_space_to_resource_flags(range->space); | ||
2046 | for (i=0; i<DEVICE_COUNT_RESOURCE; i++) { | ||
2047 | if ((pdev->resource[i].flags & mask) == mask && | ||
2048 | pdev->resource[i].start <= range->address && | ||
2049 | pdev->resource[i].end > range->address) { | ||
2050 | if ((range->address + range->size - 1) > pdev->resource[i].end) { | ||
2051 | /* Add better message */ | ||
2052 | printk(KERN_WARNING "PCI/OF resource overlap !\n"); | ||
2053 | return NULL; | ||
2054 | } | ||
2055 | break; | ||
2056 | } | ||
2057 | } | ||
2058 | if (i == DEVICE_COUNT_RESOURCE) | ||
2059 | return NULL; | ||
2060 | return &pdev->resource[i]; | ||
2061 | } | ||
2062 | |||
2063 | /* | ||
2064 | * Request an OF device resource. Currently handles child of PCI devices, | ||
2065 | * or other nodes attached to the root node. Ultimately, put some | ||
2066 | * link to resources in the OF node. | ||
2067 | */ | ||
2068 | struct resource *request_OF_resource(struct device_node* node, int index, | ||
2069 | const char* name_postfix) | ||
2070 | { | ||
2071 | struct pci_dev* pcidev; | ||
2072 | u8 pci_bus, pci_devfn; | ||
2073 | unsigned long iomask; | ||
2074 | struct device_node* nd; | ||
2075 | struct resource* parent; | ||
2076 | struct resource *res = NULL; | ||
2077 | int nlen, plen; | ||
2078 | |||
2079 | if (index >= node->n_addrs) | ||
2080 | goto fail; | ||
2081 | |||
2082 | /* Sanity check on bus space */ | ||
2083 | iomask = bus_space_to_resource_flags(node->addrs[index].space); | ||
2084 | if (iomask & IORESOURCE_MEM) | ||
2085 | parent = &iomem_resource; | ||
2086 | else if (iomask & IORESOURCE_IO) | ||
2087 | parent = &ioport_resource; | ||
2088 | else | ||
2089 | goto fail; | ||
2090 | |||
2091 | /* Find a PCI parent if any */ | ||
2092 | nd = node; | ||
2093 | pcidev = NULL; | ||
2094 | while (nd) { | ||
2095 | if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn)) | ||
2096 | pcidev = pci_find_slot(pci_bus, pci_devfn); | ||
2097 | if (pcidev) break; | ||
2098 | nd = nd->parent; | ||
2099 | } | ||
2100 | if (pcidev) | ||
2101 | parent = find_parent_pci_resource(pcidev, &node->addrs[index]); | ||
2102 | if (!parent) { | ||
2103 | printk(KERN_WARNING "request_OF_resource(%s), parent not found\n", | ||
2104 | node->name); | ||
2105 | goto fail; | ||
2106 | } | ||
2107 | |||
2108 | res = __request_region(parent, node->addrs[index].address, | ||
2109 | node->addrs[index].size, NULL); | ||
2110 | if (!res) | ||
2111 | goto fail; | ||
2112 | nlen = strlen(node->name); | ||
2113 | plen = name_postfix ? strlen(name_postfix) : 0; | ||
2114 | res->name = (const char *)kmalloc(nlen+plen+1, GFP_KERNEL); | ||
2115 | if (res->name) { | ||
2116 | strcpy((char *)res->name, node->name); | ||
2117 | if (plen) | ||
2118 | strcpy((char *)res->name+nlen, name_postfix); | ||
2119 | } | ||
2120 | return res; | ||
2121 | fail: | ||
2122 | return NULL; | ||
2123 | } | ||
2124 | EXPORT_SYMBOL(request_OF_resource); | ||
2125 | |||
2126 | int release_OF_resource(struct device_node *node, int index) | ||
2127 | { | ||
2128 | struct pci_dev* pcidev; | ||
2129 | u8 pci_bus, pci_devfn; | ||
2130 | unsigned long iomask, start, end; | ||
2131 | struct device_node* nd; | ||
2132 | struct resource* parent; | ||
2133 | struct resource *res = NULL; | ||
2134 | |||
2135 | if (index >= node->n_addrs) | ||
2136 | return -EINVAL; | ||
2137 | |||
2138 | /* Sanity check on bus space */ | ||
2139 | iomask = bus_space_to_resource_flags(node->addrs[index].space); | ||
2140 | if (iomask & IORESOURCE_MEM) | ||
2141 | parent = &iomem_resource; | ||
2142 | else if (iomask & IORESOURCE_IO) | ||
2143 | parent = &ioport_resource; | ||
2144 | else | ||
2145 | return -EINVAL; | ||
2146 | |||
2147 | /* Find a PCI parent if any */ | ||
2148 | nd = node; | ||
2149 | pcidev = NULL; | ||
2150 | while(nd) { | ||
2151 | if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn)) | ||
2152 | pcidev = pci_find_slot(pci_bus, pci_devfn); | ||
2153 | if (pcidev) break; | ||
2154 | nd = nd->parent; | ||
2155 | } | ||
2156 | if (pcidev) | ||
2157 | parent = find_parent_pci_resource(pcidev, &node->addrs[index]); | ||
2158 | if (!parent) { | ||
2159 | printk(KERN_WARNING "release_OF_resource(%s), parent not found\n", | ||
2160 | node->name); | ||
2161 | return -ENODEV; | ||
2162 | } | ||
2163 | 1786 | ||
2164 | /* Find us in the parent and its childs */ | ||
2165 | res = parent->child; | ||
2166 | start = node->addrs[index].address; | ||
2167 | end = start + node->addrs[index].size - 1; | ||
2168 | while (res) { | ||
2169 | if (res->start == start && res->end == end && | ||
2170 | (res->flags & IORESOURCE_BUSY)) | ||
2171 | break; | ||
2172 | if (res->start <= start && res->end >= end) | ||
2173 | res = res->child; | ||
2174 | else | ||
2175 | res = res->sibling; | ||
2176 | } | ||
2177 | if (!res) | ||
2178 | return -ENODEV; | ||
2179 | |||
2180 | if (res->name) { | ||
2181 | kfree(res->name); | ||
2182 | res->name = NULL; | ||
2183 | } | ||
2184 | release_resource(res); | ||
2185 | kfree(res); | ||
2186 | |||
2187 | return 0; | ||
2188 | } | ||
2189 | EXPORT_SYMBOL(release_OF_resource); | ||
2190 | #endif /* CONFIG_PCI */ | ||
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 6007d51d119b..e381f2fc121c 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
@@ -558,7 +558,8 @@ unsigned long prom_memparse(const char *ptr, const char **retptr) | |||
558 | static void __init early_cmdline_parse(void) | 558 | static void __init early_cmdline_parse(void) |
559 | { | 559 | { |
560 | struct prom_t *_prom = &RELOC(prom); | 560 | struct prom_t *_prom = &RELOC(prom); |
561 | char *opt, *p; | 561 | const char *opt; |
562 | char *p; | ||
562 | int l = 0; | 563 | int l = 0; |
563 | 564 | ||
564 | RELOC(prom_cmd_line[0]) = 0; | 565 | RELOC(prom_cmd_line[0]) = 0; |
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 60dec2401c26..45b8109951fe 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c | |||
@@ -188,39 +188,19 @@ int is_python(struct device_node *dev) | |||
188 | return 0; | 188 | return 0; |
189 | } | 189 | } |
190 | 190 | ||
191 | static int get_phb_reg_prop(struct device_node *dev, | 191 | static void python_countermeasures(struct device_node *dev) |
192 | unsigned int addr_size_words, | ||
193 | struct reg_property64 *reg) | ||
194 | { | 192 | { |
195 | unsigned int *ui_ptr = NULL, len; | 193 | struct resource registers; |
196 | |||
197 | /* Found a PHB, now figure out where his registers are mapped. */ | ||
198 | ui_ptr = (unsigned int *)get_property(dev, "reg", &len); | ||
199 | if (ui_ptr == NULL) | ||
200 | return 1; | ||
201 | |||
202 | if (addr_size_words == 1) { | ||
203 | reg->address = ((struct reg_property32 *)ui_ptr)->address; | ||
204 | reg->size = ((struct reg_property32 *)ui_ptr)->size; | ||
205 | } else { | ||
206 | *reg = *((struct reg_property64 *)ui_ptr); | ||
207 | } | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static void python_countermeasures(struct device_node *dev, | ||
213 | unsigned int addr_size_words) | ||
214 | { | ||
215 | struct reg_property64 reg_struct; | ||
216 | void __iomem *chip_regs; | 194 | void __iomem *chip_regs; |
217 | volatile u32 val; | 195 | volatile u32 val; |
218 | 196 | ||
219 | if (get_phb_reg_prop(dev, addr_size_words, ®_struct)) | 197 | if (of_address_to_resource(dev, 0, ®isters)) { |
198 | printk(KERN_ERR "Can't get address for Python workarounds !\n"); | ||
220 | return; | 199 | return; |
200 | } | ||
221 | 201 | ||
222 | /* Python's register file is 1 MB in size. */ | 202 | /* Python's register file is 1 MB in size. */ |
223 | chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 0x100000); | 203 | chip_regs = ioremap(registers.start & ~(0xfffffUL), 0x100000); |
224 | 204 | ||
225 | /* | 205 | /* |
226 | * Firmware doesn't always clear this bit which is critical | 206 | * Firmware doesn't always clear this bit which is critical |
@@ -301,11 +281,10 @@ static int phb_set_bus_ranges(struct device_node *dev, | |||
301 | } | 281 | } |
302 | 282 | ||
303 | static int __devinit setup_phb(struct device_node *dev, | 283 | static int __devinit setup_phb(struct device_node *dev, |
304 | struct pci_controller *phb, | 284 | struct pci_controller *phb) |
305 | unsigned int addr_size_words) | ||
306 | { | 285 | { |
307 | if (is_python(dev)) | 286 | if (is_python(dev)) |
308 | python_countermeasures(dev, addr_size_words); | 287 | python_countermeasures(dev); |
309 | 288 | ||
310 | if (phb_set_bus_ranges(dev, phb)) | 289 | if (phb_set_bus_ranges(dev, phb)) |
311 | return 1; | 290 | return 1; |
@@ -320,8 +299,8 @@ unsigned long __init find_and_init_phbs(void) | |||
320 | { | 299 | { |
321 | struct device_node *node; | 300 | struct device_node *node; |
322 | struct pci_controller *phb; | 301 | struct pci_controller *phb; |
323 | unsigned int root_size_cells = 0; | ||
324 | unsigned int index; | 302 | unsigned int index; |
303 | unsigned int root_size_cells = 0; | ||
325 | unsigned int *opprop = NULL; | 304 | unsigned int *opprop = NULL; |
326 | struct device_node *root = of_find_node_by_path("/"); | 305 | struct device_node *root = of_find_node_by_path("/"); |
327 | 306 | ||
@@ -343,10 +322,11 @@ unsigned long __init find_and_init_phbs(void) | |||
343 | phb = pcibios_alloc_controller(node); | 322 | phb = pcibios_alloc_controller(node); |
344 | if (!phb) | 323 | if (!phb) |
345 | continue; | 324 | continue; |
346 | setup_phb(node, phb, root_size_cells); | 325 | setup_phb(node, phb); |
347 | pci_process_bridge_OF_ranges(phb, node, 0); | 326 | pci_process_bridge_OF_ranges(phb, node, 0); |
348 | pci_setup_phb_io(phb, index == 0); | 327 | pci_setup_phb_io(phb, index == 0); |
349 | #ifdef CONFIG_PPC_PSERIES | 328 | #ifdef CONFIG_PPC_PSERIES |
329 | /* XXX This code need serious fixing ... --BenH */ | ||
350 | if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) { | 330 | if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) { |
351 | int addr = root_size_cells * (index + 2) - 1; | 331 | int addr = root_size_cells * (index + 2) - 1; |
352 | mpic_assign_isu(pSeries_mpic, index, opprop[addr]); | 332 | mpic_assign_isu(pSeries_mpic, index, opprop[addr]); |
@@ -381,22 +361,17 @@ unsigned long __init find_and_init_phbs(void) | |||
381 | 361 | ||
382 | struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) | 362 | struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) |
383 | { | 363 | { |
384 | struct device_node *root = of_find_node_by_path("/"); | ||
385 | unsigned int root_size_cells = 0; | ||
386 | struct pci_controller *phb; | 364 | struct pci_controller *phb; |
387 | int primary; | 365 | int primary; |
388 | 366 | ||
389 | root_size_cells = prom_n_size_cells(root); | ||
390 | |||
391 | primary = list_empty(&hose_list); | 367 | primary = list_empty(&hose_list); |
392 | phb = pcibios_alloc_controller(dn); | 368 | phb = pcibios_alloc_controller(dn); |
393 | if (!phb) | 369 | if (!phb) |
394 | return NULL; | 370 | return NULL; |
395 | setup_phb(dn, phb, root_size_cells); | 371 | setup_phb(dn, phb); |
396 | pci_process_bridge_OF_ranges(phb, dn, primary); | 372 | pci_process_bridge_OF_ranges(phb, dn, primary); |
397 | 373 | ||
398 | pci_setup_phb_io_dynamic(phb, primary); | 374 | pci_setup_phb_io_dynamic(phb, primary); |
399 | of_node_put(root); | ||
400 | 375 | ||
401 | pci_devs_phb_init_dynamic(phb); | 376 | pci_devs_phb_init_dynamic(phb); |
402 | scan_phb(phb); | 377 | scan_phb(phb); |
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index fc519cd90f77..fc6f8ee9656f 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
@@ -432,7 +432,8 @@ static int __init parse_numa_properties(void) | |||
432 | if (!memcell_buf || len <= 0) | 432 | if (!memcell_buf || len <= 0) |
433 | continue; | 433 | continue; |
434 | 434 | ||
435 | ranges = memory->n_addrs; | 435 | /* ranges in cell */ |
436 | ranges = (len >> 2) / (n_mem_addr_cells + n_mem_size_cells); | ||
436 | new_range: | 437 | new_range: |
437 | /* these are order-sensitive, and modify the buffer pointer */ | 438 | /* these are order-sensitive, and modify the buffer pointer */ |
438 | start = read_n_cells(n_mem_addr_cells, &memcell_buf); | 439 | start = read_n_cells(n_mem_addr_cells, &memcell_buf); |
@@ -779,7 +780,8 @@ int hot_add_scn_to_nid(unsigned long scn_addr) | |||
779 | if (!memcell_buf || len <= 0) | 780 | if (!memcell_buf || len <= 0) |
780 | continue; | 781 | continue; |
781 | 782 | ||
782 | ranges = memory->n_addrs; /* ranges in cell */ | 783 | /* ranges in cell */ |
784 | ranges = (len >> 2) / (n_mem_addr_cells + n_mem_size_cells); | ||
783 | ha_new_range: | 785 | ha_new_range: |
784 | start = read_n_cells(n_mem_addr_cells, &memcell_buf); | 786 | start = read_n_cells(n_mem_addr_cells, &memcell_buf); |
785 | size = read_n_cells(n_mem_size_cells, &memcell_buf); | 787 | size = read_n_cells(n_mem_size_cells, &memcell_buf); |
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index b2928bbe9227..b1f896952b1b 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c | |||
@@ -1445,20 +1445,55 @@ static long g5_i2s_enable(struct device_node *node, long param, long value) | |||
1445 | /* Very crude implementation for now */ | 1445 | /* Very crude implementation for now */ |
1446 | struct macio_chip *macio = &macio_chips[0]; | 1446 | struct macio_chip *macio = &macio_chips[0]; |
1447 | unsigned long flags; | 1447 | unsigned long flags; |
1448 | 1448 | int cell; | |
1449 | if (value == 0) | 1449 | u32 fcrs[3][3] = { |
1450 | return 0; /* don't disable yet */ | 1450 | { 0, |
1451 | K2_FCR1_I2S0_CELL_ENABLE | | ||
1452 | K2_FCR1_I2S0_CLK_ENABLE_BIT | K2_FCR1_I2S0_ENABLE, | ||
1453 | KL3_I2S0_CLK18_ENABLE | ||
1454 | }, | ||
1455 | { KL0_SCC_A_INTF_ENABLE, | ||
1456 | K2_FCR1_I2S1_CELL_ENABLE | | ||
1457 | K2_FCR1_I2S1_CLK_ENABLE_BIT | K2_FCR1_I2S1_ENABLE, | ||
1458 | KL3_I2S1_CLK18_ENABLE | ||
1459 | }, | ||
1460 | { KL0_SCC_B_INTF_ENABLE, | ||
1461 | SH_FCR1_I2S2_CELL_ENABLE | | ||
1462 | SH_FCR1_I2S2_CLK_ENABLE_BIT | SH_FCR1_I2S2_ENABLE, | ||
1463 | SH_FCR3_I2S2_CLK18_ENABLE | ||
1464 | }, | ||
1465 | }; | ||
1466 | |||
1467 | if (macio->type != macio_keylargo2 /* && macio->type != macio_shasta*/) | ||
1468 | return -ENODEV; | ||
1469 | if (strncmp(node->name, "i2s-", 4)) | ||
1470 | return -ENODEV; | ||
1471 | cell = node->name[4] - 'a'; | ||
1472 | switch(cell) { | ||
1473 | case 0: | ||
1474 | case 1: | ||
1475 | break; | ||
1476 | #if 0 | ||
1477 | case 2: | ||
1478 | if (macio->type == macio_shasta) | ||
1479 | break; | ||
1480 | #endif | ||
1481 | default: | ||
1482 | return -ENODEV; | ||
1483 | } | ||
1451 | 1484 | ||
1452 | LOCK(flags); | 1485 | LOCK(flags); |
1453 | MACIO_BIS(KEYLARGO_FCR3, KL3_CLK45_ENABLE | KL3_CLK49_ENABLE | | 1486 | if (value) { |
1454 | KL3_I2S0_CLK18_ENABLE); | 1487 | MACIO_BIC(KEYLARGO_FCR0, fcrs[cell][0]); |
1455 | udelay(10); | 1488 | MACIO_BIS(KEYLARGO_FCR1, fcrs[cell][1]); |
1456 | MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_I2S0_CELL_ENABLE | | 1489 | MACIO_BIS(KEYLARGO_FCR3, fcrs[cell][2]); |
1457 | K2_FCR1_I2S0_CLK_ENABLE_BIT | K2_FCR1_I2S0_ENABLE); | 1490 | } else { |
1491 | MACIO_BIC(KEYLARGO_FCR3, fcrs[cell][2]); | ||
1492 | MACIO_BIC(KEYLARGO_FCR1, fcrs[cell][1]); | ||
1493 | MACIO_BIS(KEYLARGO_FCR0, fcrs[cell][0]); | ||
1494 | } | ||
1458 | udelay(10); | 1495 | udelay(10); |
1459 | MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_I2S0_RESET); | ||
1460 | UNLOCK(flags); | 1496 | UNLOCK(flags); |
1461 | udelay(10); | ||
1462 | 1497 | ||
1463 | return 0; | 1498 | return 0; |
1464 | } | 1499 | } |
@@ -2960,26 +2995,6 @@ pmac_feature_init(void) | |||
2960 | set_initial_features(); | 2995 | set_initial_features(); |
2961 | } | 2996 | } |
2962 | 2997 | ||
2963 | int __init pmac_feature_late_init(void) | ||
2964 | { | ||
2965 | #if 0 | ||
2966 | struct device_node *np; | ||
2967 | |||
2968 | /* Request some resources late */ | ||
2969 | if (uninorth_node) | ||
2970 | request_OF_resource(uninorth_node, 0, NULL); | ||
2971 | np = find_devices("hammerhead"); | ||
2972 | if (np) | ||
2973 | request_OF_resource(np, 0, NULL); | ||
2974 | np = find_devices("interrupt-controller"); | ||
2975 | if (np) | ||
2976 | request_OF_resource(np, 0, NULL); | ||
2977 | #endif | ||
2978 | return 0; | ||
2979 | } | ||
2980 | |||
2981 | device_initcall(pmac_feature_late_init); | ||
2982 | |||
2983 | #if 0 | 2998 | #if 0 |
2984 | static void dump_HT_speeds(char *name, u32 cfg, u32 frq) | 2999 | static void dump_HT_speeds(char *name, u32 cfg, u32 frq) |
2985 | { | 3000 | { |
diff --git a/arch/powerpc/platforms/powermac/nvram.c b/arch/powerpc/platforms/powermac/nvram.c index 59e0e51cf663..3ebd045a3350 100644 --- a/arch/powerpc/platforms/powermac/nvram.c +++ b/arch/powerpc/platforms/powermac/nvram.c | |||
@@ -514,7 +514,7 @@ static void core99_nvram_sync(void) | |||
514 | #endif | 514 | #endif |
515 | } | 515 | } |
516 | 516 | ||
517 | static int __init core99_nvram_setup(struct device_node *dp) | 517 | static int __init core99_nvram_setup(struct device_node *dp, unsigned long addr) |
518 | { | 518 | { |
519 | int i; | 519 | int i; |
520 | u32 gen_bank0, gen_bank1; | 520 | u32 gen_bank0, gen_bank1; |
@@ -528,7 +528,7 @@ static int __init core99_nvram_setup(struct device_node *dp) | |||
528 | printk(KERN_ERR "nvram: can't allocate ram image\n"); | 528 | printk(KERN_ERR "nvram: can't allocate ram image\n"); |
529 | return -ENOMEM; | 529 | return -ENOMEM; |
530 | } | 530 | } |
531 | nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2); | 531 | nvram_data = ioremap(addr, NVRAM_SIZE*2); |
532 | nvram_naddrs = 1; /* Make sure we get the correct case */ | 532 | nvram_naddrs = 1; /* Make sure we get the correct case */ |
533 | 533 | ||
534 | DBG("nvram: Checking bank 0...\n"); | 534 | DBG("nvram: Checking bank 0...\n"); |
@@ -570,34 +570,48 @@ static int __init core99_nvram_setup(struct device_node *dp) | |||
570 | int __init pmac_nvram_init(void) | 570 | int __init pmac_nvram_init(void) |
571 | { | 571 | { |
572 | struct device_node *dp; | 572 | struct device_node *dp; |
573 | struct resource r1, r2; | ||
574 | unsigned int s1 = 0, s2 = 0; | ||
573 | int err = 0; | 575 | int err = 0; |
574 | 576 | ||
575 | nvram_naddrs = 0; | 577 | nvram_naddrs = 0; |
576 | 578 | ||
577 | dp = find_devices("nvram"); | 579 | dp = of_find_node_by_name(NULL, "nvram"); |
578 | if (dp == NULL) { | 580 | if (dp == NULL) { |
579 | printk(KERN_ERR "Can't find NVRAM device\n"); | 581 | printk(KERN_ERR "Can't find NVRAM device\n"); |
580 | return -ENODEV; | 582 | return -ENODEV; |
581 | } | 583 | } |
582 | nvram_naddrs = dp->n_addrs; | 584 | |
585 | /* Try to obtain an address */ | ||
586 | if (of_address_to_resource(dp, 0, &r1) == 0) { | ||
587 | nvram_naddrs = 1; | ||
588 | s1 = (r1.end - r1.start) + 1; | ||
589 | if (of_address_to_resource(dp, 1, &r2) == 0) { | ||
590 | nvram_naddrs = 2; | ||
591 | s2 = (r2.end - r2.start) + 1; | ||
592 | } | ||
593 | } | ||
594 | |||
583 | is_core_99 = device_is_compatible(dp, "nvram,flash"); | 595 | is_core_99 = device_is_compatible(dp, "nvram,flash"); |
584 | if (is_core_99) | 596 | if (is_core_99) { |
585 | err = core99_nvram_setup(dp); | 597 | err = core99_nvram_setup(dp, r1.start); |
598 | goto bail; | ||
599 | } | ||
600 | |||
586 | #ifdef CONFIG_PPC32 | 601 | #ifdef CONFIG_PPC32 |
587 | else if (_machine == _MACH_chrp && nvram_naddrs == 1) { | 602 | if (_machine == _MACH_chrp && nvram_naddrs == 1) { |
588 | nvram_data = ioremap(dp->addrs[0].address + isa_mem_base, | 603 | nvram_data = ioremap(r1.start, s1); |
589 | dp->addrs[0].size); | ||
590 | nvram_mult = 1; | 604 | nvram_mult = 1; |
591 | ppc_md.nvram_read_val = direct_nvram_read_byte; | 605 | ppc_md.nvram_read_val = direct_nvram_read_byte; |
592 | ppc_md.nvram_write_val = direct_nvram_write_byte; | 606 | ppc_md.nvram_write_val = direct_nvram_write_byte; |
593 | } else if (nvram_naddrs == 1) { | 607 | } else if (nvram_naddrs == 1) { |
594 | nvram_data = ioremap(dp->addrs[0].address, dp->addrs[0].size); | 608 | nvram_data = ioremap(r1.start, s1); |
595 | nvram_mult = (dp->addrs[0].size + NVRAM_SIZE - 1) / NVRAM_SIZE; | 609 | nvram_mult = (s1 + NVRAM_SIZE - 1) / NVRAM_SIZE; |
596 | ppc_md.nvram_read_val = direct_nvram_read_byte; | 610 | ppc_md.nvram_read_val = direct_nvram_read_byte; |
597 | ppc_md.nvram_write_val = direct_nvram_write_byte; | 611 | ppc_md.nvram_write_val = direct_nvram_write_byte; |
598 | } else if (nvram_naddrs == 2) { | 612 | } else if (nvram_naddrs == 2) { |
599 | nvram_addr = ioremap(dp->addrs[0].address, dp->addrs[0].size); | 613 | nvram_addr = ioremap(r1.start, s1); |
600 | nvram_data = ioremap(dp->addrs[1].address, dp->addrs[1].size); | 614 | nvram_data = ioremap(r2.start, s2); |
601 | ppc_md.nvram_read_val = indirect_nvram_read_byte; | 615 | ppc_md.nvram_read_val = indirect_nvram_read_byte; |
602 | ppc_md.nvram_write_val = indirect_nvram_write_byte; | 616 | ppc_md.nvram_write_val = indirect_nvram_write_byte; |
603 | } else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) { | 617 | } else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) { |
@@ -606,13 +620,15 @@ int __init pmac_nvram_init(void) | |||
606 | ppc_md.nvram_read_val = pmu_nvram_read_byte; | 620 | ppc_md.nvram_read_val = pmu_nvram_read_byte; |
607 | ppc_md.nvram_write_val = pmu_nvram_write_byte; | 621 | ppc_md.nvram_write_val = pmu_nvram_write_byte; |
608 | #endif /* CONFIG_ADB_PMU */ | 622 | #endif /* CONFIG_ADB_PMU */ |
609 | } | 623 | } else { |
610 | #endif | ||
611 | else { | ||
612 | printk(KERN_ERR "Incompatible type of NVRAM\n"); | 624 | printk(KERN_ERR "Incompatible type of NVRAM\n"); |
613 | return -ENXIO; | 625 | err = -ENXIO; |
614 | } | 626 | } |
615 | lookup_partitions(); | 627 | #endif /* CONFIG_PPC32 */ |
628 | bail: | ||
629 | of_node_put(dp); | ||
630 | if (err == 0) | ||
631 | lookup_partitions(); | ||
616 | return err; | 632 | return err; |
617 | } | 633 | } |
618 | 634 | ||
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index e0b66f55a5f8..5aab261075de 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c | |||
@@ -285,15 +285,13 @@ static struct pci_ops chaos_pci_ops = | |||
285 | }; | 285 | }; |
286 | 286 | ||
287 | static void __init setup_chaos(struct pci_controller *hose, | 287 | static void __init setup_chaos(struct pci_controller *hose, |
288 | struct reg_property *addr) | 288 | struct resource *addr) |
289 | { | 289 | { |
290 | /* assume a `chaos' bridge */ | 290 | /* assume a `chaos' bridge */ |
291 | hose->ops = &chaos_pci_ops; | 291 | hose->ops = &chaos_pci_ops; |
292 | hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); | 292 | hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000); |
293 | hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); | 293 | hose->cfg_data = ioremap(addr->start + 0xc00000, 0x1000); |
294 | } | 294 | } |
295 | #else | ||
296 | #define setup_chaos(hose, addr) | ||
297 | #endif /* CONFIG_PPC32 */ | 295 | #endif /* CONFIG_PPC32 */ |
298 | 296 | ||
299 | #ifdef CONFIG_PPC64 | 297 | #ifdef CONFIG_PPC64 |
@@ -356,9 +354,11 @@ static unsigned long u3_ht_cfg_access(struct pci_controller* hose, | |||
356 | /* For now, we don't self probe U3 HT bridge */ | 354 | /* For now, we don't self probe U3 HT bridge */ |
357 | if (PCI_SLOT(devfn) == 0) | 355 | if (PCI_SLOT(devfn) == 0) |
358 | return 0; | 356 | return 0; |
359 | return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset); | 357 | return ((unsigned long)hose->cfg_data) + |
358 | U3_HT_CFA0(devfn, offset); | ||
360 | } else | 359 | } else |
361 | return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset); | 360 | return ((unsigned long)hose->cfg_data) + |
361 | U3_HT_CFA1(bus, devfn, offset); | ||
362 | } | 362 | } |
363 | 363 | ||
364 | static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, | 364 | static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, |
@@ -532,7 +532,8 @@ static void __init init_p2pbridge(void) | |||
532 | } | 532 | } |
533 | if (early_read_config_word(hose, bus, devfn, | 533 | if (early_read_config_word(hose, bus, devfn, |
534 | PCI_BRIDGE_CONTROL, &val) < 0) { | 534 | PCI_BRIDGE_CONTROL, &val) < 0) { |
535 | printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n"); | 535 | printk(KERN_ERR "init_p2pbridge: couldn't read bridge" |
536 | " control\n"); | ||
536 | return; | 537 | return; |
537 | } | 538 | } |
538 | val &= ~PCI_BRIDGE_CTL_MASTER_ABORT; | 539 | val &= ~PCI_BRIDGE_CTL_MASTER_ABORT; |
@@ -576,36 +577,38 @@ static void __init fixup_nec_usb2(void) | |||
576 | continue; | 577 | continue; |
577 | early_read_config_dword(hose, bus, devfn, 0xe4, &data); | 578 | early_read_config_dword(hose, bus, devfn, 0xe4, &data); |
578 | if (data & 1UL) { | 579 | if (data & 1UL) { |
579 | printk("Found NEC PD720100A USB2 chip with disabled EHCI, fixing up...\n"); | 580 | printk("Found NEC PD720100A USB2 chip with disabled" |
581 | " EHCI, fixing up...\n"); | ||
580 | data &= ~1UL; | 582 | data &= ~1UL; |
581 | early_write_config_dword(hose, bus, devfn, 0xe4, data); | 583 | early_write_config_dword(hose, bus, devfn, 0xe4, data); |
582 | early_write_config_byte(hose, bus, devfn | 2, PCI_INTERRUPT_LINE, | 584 | early_write_config_byte(hose, bus, |
585 | devfn | 2, PCI_INTERRUPT_LINE, | ||
583 | nec->intrs[0].line); | 586 | nec->intrs[0].line); |
584 | } | 587 | } |
585 | } | 588 | } |
586 | } | 589 | } |
587 | 590 | ||
588 | static void __init setup_bandit(struct pci_controller *hose, | 591 | static void __init setup_bandit(struct pci_controller *hose, |
589 | struct reg_property *addr) | 592 | struct resource *addr) |
590 | { | 593 | { |
591 | hose->ops = ¯isc_pci_ops; | 594 | hose->ops = ¯isc_pci_ops; |
592 | hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); | 595 | hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000); |
593 | hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); | 596 | hose->cfg_data = ioremap(addr->start + 0xc00000, 0x1000); |
594 | init_bandit(hose); | 597 | init_bandit(hose); |
595 | } | 598 | } |
596 | 599 | ||
597 | static int __init setup_uninorth(struct pci_controller *hose, | 600 | static int __init setup_uninorth(struct pci_controller *hose, |
598 | struct reg_property *addr) | 601 | struct resource *addr) |
599 | { | 602 | { |
600 | pci_assign_all_buses = 1; | 603 | pci_assign_all_buses = 1; |
601 | has_uninorth = 1; | 604 | has_uninorth = 1; |
602 | hose->ops = ¯isc_pci_ops; | 605 | hose->ops = ¯isc_pci_ops; |
603 | hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); | 606 | hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000); |
604 | hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); | 607 | hose->cfg_data = ioremap(addr->start + 0xc00000, 0x1000); |
605 | /* We "know" that the bridge at f2000000 has the PCI slots. */ | 608 | /* We "know" that the bridge at f2000000 has the PCI slots. */ |
606 | return addr->address == 0xf2000000; | 609 | return addr->start == 0xf2000000; |
607 | } | 610 | } |
608 | #endif | 611 | #endif /* CONFIG_PPC32 */ |
609 | 612 | ||
610 | #ifdef CONFIG_PPC64 | 613 | #ifdef CONFIG_PPC64 |
611 | static void __init setup_u3_agp(struct pci_controller* hose) | 614 | static void __init setup_u3_agp(struct pci_controller* hose) |
@@ -722,7 +725,7 @@ static void __init setup_u3_ht(struct pci_controller* hose) | |||
722 | hose->mem_resources[cur-1].end = res->start - 1; | 725 | hose->mem_resources[cur-1].end = res->start - 1; |
723 | } | 726 | } |
724 | } | 727 | } |
725 | #endif | 728 | #endif /* CONFIG_PPC64 */ |
726 | 729 | ||
727 | /* | 730 | /* |
728 | * We assume that if we have a G3 powermac, we have one bridge called | 731 | * We assume that if we have a G3 powermac, we have one bridge called |
@@ -733,24 +736,17 @@ static int __init add_bridge(struct device_node *dev) | |||
733 | { | 736 | { |
734 | int len; | 737 | int len; |
735 | struct pci_controller *hose; | 738 | struct pci_controller *hose; |
736 | #ifdef CONFIG_PPC32 | 739 | struct resource rsrc; |
737 | struct reg_property *addr; | ||
738 | #endif | ||
739 | char *disp_name; | 740 | char *disp_name; |
740 | int *bus_range; | 741 | int *bus_range; |
741 | int primary = 1; | 742 | int primary = 1, has_address = 0; |
742 | 743 | ||
743 | DBG("Adding PCI host bridge %s\n", dev->full_name); | 744 | DBG("Adding PCI host bridge %s\n", dev->full_name); |
744 | 745 | ||
745 | #ifdef CONFIG_PPC32 | 746 | /* Fetch host bridge registers address */ |
746 | /* XXX fix this */ | 747 | has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); |
747 | addr = (struct reg_property *) get_property(dev, "reg", &len); | 748 | |
748 | if (addr == NULL || len < sizeof(*addr)) { | 749 | /* Get bus range if any */ |
749 | printk(KERN_WARNING "Can't use %s: no address\n", | ||
750 | dev->full_name); | ||
751 | return -ENODEV; | ||
752 | } | ||
753 | #endif | ||
754 | bus_range = (int *) get_property(dev, "bus-range", &len); | 750 | bus_range = (int *) get_property(dev, "bus-range", &len); |
755 | if (bus_range == NULL || len < 2 * sizeof(int)) { | 751 | if (bus_range == NULL || len < 2 * sizeof(int)) { |
756 | printk(KERN_WARNING "Can't get bus-range for %s, assume" | 752 | printk(KERN_WARNING "Can't get bus-range for %s, assume" |
@@ -770,6 +766,8 @@ static int __init add_bridge(struct device_node *dev) | |||
770 | hose->last_busno = bus_range ? bus_range[1] : 0xff; | 766 | hose->last_busno = bus_range ? bus_range[1] : 0xff; |
771 | 767 | ||
772 | disp_name = NULL; | 768 | disp_name = NULL; |
769 | |||
770 | /* 64 bits only bridges */ | ||
773 | #ifdef CONFIG_PPC64 | 771 | #ifdef CONFIG_PPC64 |
774 | if (device_is_compatible(dev, "u3-agp")) { | 772 | if (device_is_compatible(dev, "u3-agp")) { |
775 | setup_u3_agp(hose); | 773 | setup_u3_agp(hose); |
@@ -782,25 +780,30 @@ static int __init add_bridge(struct device_node *dev) | |||
782 | } | 780 | } |
783 | printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n", | 781 | printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n", |
784 | disp_name, hose->first_busno, hose->last_busno); | 782 | disp_name, hose->first_busno, hose->last_busno); |
785 | #else | 783 | #endif /* CONFIG_PPC64 */ |
784 | |||
785 | /* 32 bits only bridges */ | ||
786 | #ifdef CONFIG_PPC32 | ||
786 | if (device_is_compatible(dev, "uni-north")) { | 787 | if (device_is_compatible(dev, "uni-north")) { |
787 | primary = setup_uninorth(hose, addr); | 788 | primary = setup_uninorth(hose, &rsrc); |
788 | disp_name = "UniNorth"; | 789 | disp_name = "UniNorth"; |
789 | } else if (strcmp(dev->name, "pci") == 0) { | 790 | } else if (strcmp(dev->name, "pci") == 0) { |
790 | /* XXX assume this is a mpc106 (grackle) */ | 791 | /* XXX assume this is a mpc106 (grackle) */ |
791 | setup_grackle(hose); | 792 | setup_grackle(hose); |
792 | disp_name = "Grackle (MPC106)"; | 793 | disp_name = "Grackle (MPC106)"; |
793 | } else if (strcmp(dev->name, "bandit") == 0) { | 794 | } else if (strcmp(dev->name, "bandit") == 0) { |
794 | setup_bandit(hose, addr); | 795 | setup_bandit(hose, &rsrc); |
795 | disp_name = "Bandit"; | 796 | disp_name = "Bandit"; |
796 | } else if (strcmp(dev->name, "chaos") == 0) { | 797 | } else if (strcmp(dev->name, "chaos") == 0) { |
797 | setup_chaos(hose, addr); | 798 | setup_chaos(hose, &rsrc); |
798 | disp_name = "Chaos"; | 799 | disp_name = "Chaos"; |
799 | primary = 0; | 800 | primary = 0; |
800 | } | 801 | } |
801 | printk(KERN_INFO "Found %s PCI host bridge at 0x%08lx. Firmware bus number: %d->%d\n", | 802 | printk(KERN_INFO "Found %s PCI host bridge at 0x%08lx. " |
802 | disp_name, addr->address, hose->first_busno, hose->last_busno); | 803 | "Firmware bus number: %d->%d\n", |
803 | #endif | 804 | disp_name, rsrc.start, hose->first_busno, hose->last_busno); |
805 | #endif /* CONFIG_PPC32 */ | ||
806 | |||
804 | DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", | 807 | DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", |
805 | hose, hose->cfg_addr, hose->cfg_data); | 808 | hose, hose->cfg_addr, hose->cfg_data); |
806 | 809 | ||
@@ -814,8 +817,7 @@ static int __init add_bridge(struct device_node *dev) | |||
814 | return 0; | 817 | return 0; |
815 | } | 818 | } |
816 | 819 | ||
817 | static void __init | 820 | static void __init pcibios_fixup_OF_interrupts(void) |
818 | pcibios_fixup_OF_interrupts(void) | ||
819 | { | 821 | { |
820 | struct pci_dev* dev = NULL; | 822 | struct pci_dev* dev = NULL; |
821 | 823 | ||
@@ -835,8 +837,7 @@ pcibios_fixup_OF_interrupts(void) | |||
835 | } | 837 | } |
836 | } | 838 | } |
837 | 839 | ||
838 | void __init | 840 | void __init pmac_pcibios_fixup(void) |
839 | pmac_pcibios_fixup(void) | ||
840 | { | 841 | { |
841 | /* Fixup interrupts according to OF tree */ | 842 | /* Fixup interrupts according to OF tree */ |
842 | pcibios_fixup_OF_interrupts(); | 843 | pcibios_fixup_OF_interrupts(); |
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index a36527c98133..dbb524a851aa 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c | |||
@@ -5,8 +5,8 @@ | |||
5 | * in a separate file | 5 | * in a separate file |
6 | * | 6 | * |
7 | * Copyright (C) 1997 Paul Mackerras (paulus@samba.org) | 7 | * Copyright (C) 1997 Paul Mackerras (paulus@samba.org) |
8 | * | 8 | * Copyright (C) 2005 Benjamin Herrenschmidt (benh@kernel.crashing.org) |
9 | * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org) | 9 | * IBM, Corp. |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
12 | * modify it under the terms of the GNU General Public License | 12 | * modify it under the terms of the GNU General Public License |
@@ -54,12 +54,7 @@ struct pmac_irq_hw { | |||
54 | }; | 54 | }; |
55 | 55 | ||
56 | /* Default addresses */ | 56 | /* Default addresses */ |
57 | static volatile struct pmac_irq_hw *pmac_irq_hw[4] = { | 57 | static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4]; |
58 | (struct pmac_irq_hw *) 0xf3000020, | ||
59 | (struct pmac_irq_hw *) 0xf3000010, | ||
60 | (struct pmac_irq_hw *) 0xf4000020, | ||
61 | (struct pmac_irq_hw *) 0xf4000010, | ||
62 | }; | ||
63 | 58 | ||
64 | #define GC_LEVEL_MASK 0x3ff00000 | 59 | #define GC_LEVEL_MASK 0x3ff00000 |
65 | #define OHARE_LEVEL_MASK 0x1ff00000 | 60 | #define OHARE_LEVEL_MASK 0x1ff00000 |
@@ -82,8 +77,7 @@ static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; | |||
82 | * since it can lose interrupts (see pmac_set_irq_mask). | 77 | * since it can lose interrupts (see pmac_set_irq_mask). |
83 | * -- Cort | 78 | * -- Cort |
84 | */ | 79 | */ |
85 | void | 80 | void __set_lost(unsigned long irq_nr, int nokick) |
86 | __set_lost(unsigned long irq_nr, int nokick) | ||
87 | { | 81 | { |
88 | if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) { | 82 | if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) { |
89 | atomic_inc(&ppc_n_lost_interrupts); | 83 | atomic_inc(&ppc_n_lost_interrupts); |
@@ -92,8 +86,7 @@ __set_lost(unsigned long irq_nr, int nokick) | |||
92 | } | 86 | } |
93 | } | 87 | } |
94 | 88 | ||
95 | static void | 89 | static void pmac_mask_and_ack_irq(unsigned int irq_nr) |
96 | pmac_mask_and_ack_irq(unsigned int irq_nr) | ||
97 | { | 90 | { |
98 | unsigned long bit = 1UL << (irq_nr & 0x1f); | 91 | unsigned long bit = 1UL << (irq_nr & 0x1f); |
99 | int i = irq_nr >> 5; | 92 | int i = irq_nr >> 5; |
@@ -224,8 +217,7 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs) | |||
224 | return IRQ_NONE; | 217 | return IRQ_NONE; |
225 | } | 218 | } |
226 | 219 | ||
227 | int | 220 | static int pmac_get_irq(struct pt_regs *regs) |
228 | pmac_get_irq(struct pt_regs *regs) | ||
229 | { | 221 | { |
230 | int irq; | 222 | int irq; |
231 | unsigned long bits = 0; | 223 | unsigned long bits = 0; |
@@ -256,34 +248,40 @@ pmac_get_irq(struct pt_regs *regs) | |||
256 | 248 | ||
257 | /* This routine will fix some missing interrupt values in the device tree | 249 | /* This routine will fix some missing interrupt values in the device tree |
258 | * on the gatwick mac-io controller used by some PowerBooks | 250 | * on the gatwick mac-io controller used by some PowerBooks |
251 | * | ||
252 | * Walking of OF nodes could use a bit more fixing up here, but it's not | ||
253 | * very important as this is all boot time code on static portions of the | ||
254 | * device-tree. | ||
255 | * | ||
256 | * However, the modifications done to "intrs" will have to be removed and | ||
257 | * replaced with proper updates of the "interrupts" properties or | ||
258 | * AAPL,interrupts, yet to be decided, once the dynamic parsing is there. | ||
259 | */ | 259 | */ |
260 | static void __init | 260 | static void __init pmac_fix_gatwick_interrupts(struct device_node *gw, |
261 | pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base) | 261 | int irq_base) |
262 | { | 262 | { |
263 | struct device_node *node; | 263 | struct device_node *node; |
264 | int count; | 264 | int count; |
265 | 265 | ||
266 | memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool)); | 266 | memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool)); |
267 | node = gw->child; | ||
268 | count = 0; | 267 | count = 0; |
269 | while(node) | 268 | for (node = NULL; (node = of_get_next_child(gw, node)) != NULL;) { |
270 | { | ||
271 | /* Fix SCC */ | 269 | /* Fix SCC */ |
272 | if (strcasecmp(node->name, "escc") == 0) | 270 | if ((strcasecmp(node->name, "escc") == 0) && node->child) { |
273 | if (node->child) { | 271 | if (node->child->n_intrs < 3) { |
274 | if (node->child->n_intrs < 3) { | 272 | node->child->intrs = &gatwick_int_pool[count]; |
275 | node->child->intrs = &gatwick_int_pool[count]; | 273 | count += 3; |
276 | count += 3; | ||
277 | } | ||
278 | node->child->n_intrs = 3; | ||
279 | node->child->intrs[0].line = 15+irq_base; | ||
280 | node->child->intrs[1].line = 4+irq_base; | ||
281 | node->child->intrs[2].line = 5+irq_base; | ||
282 | printk(KERN_INFO "irq: fixed SCC on second controller (%d,%d,%d)\n", | ||
283 | node->child->intrs[0].line, | ||
284 | node->child->intrs[1].line, | ||
285 | node->child->intrs[2].line); | ||
286 | } | 274 | } |
275 | node->child->n_intrs = 3; | ||
276 | node->child->intrs[0].line = 15+irq_base; | ||
277 | node->child->intrs[1].line = 4+irq_base; | ||
278 | node->child->intrs[2].line = 5+irq_base; | ||
279 | printk(KERN_INFO "irq: fixed SCC on gatwick" | ||
280 | " (%d,%d,%d)\n", | ||
281 | node->child->intrs[0].line, | ||
282 | node->child->intrs[1].line, | ||
283 | node->child->intrs[2].line); | ||
284 | } | ||
287 | /* Fix media-bay & left SWIM */ | 285 | /* Fix media-bay & left SWIM */ |
288 | if (strcasecmp(node->name, "media-bay") == 0) { | 286 | if (strcasecmp(node->name, "media-bay") == 0) { |
289 | struct device_node* ya_node; | 287 | struct device_node* ya_node; |
@@ -292,12 +290,11 @@ pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base) | |||
292 | node->intrs = &gatwick_int_pool[count++]; | 290 | node->intrs = &gatwick_int_pool[count++]; |
293 | node->n_intrs = 1; | 291 | node->n_intrs = 1; |
294 | node->intrs[0].line = 29+irq_base; | 292 | node->intrs[0].line = 29+irq_base; |
295 | printk(KERN_INFO "irq: fixed media-bay on second controller (%d)\n", | 293 | printk(KERN_INFO "irq: fixed media-bay on gatwick" |
296 | node->intrs[0].line); | 294 | " (%d)\n", node->intrs[0].line); |
297 | 295 | ||
298 | ya_node = node->child; | 296 | ya_node = node->child; |
299 | while(ya_node) | 297 | while(ya_node) { |
300 | { | ||
301 | if (strcasecmp(ya_node->name, "floppy") == 0) { | 298 | if (strcasecmp(ya_node->name, "floppy") == 0) { |
302 | if (ya_node->n_intrs < 2) { | 299 | if (ya_node->n_intrs < 2) { |
303 | ya_node->intrs = &gatwick_int_pool[count]; | 300 | ya_node->intrs = &gatwick_int_pool[count]; |
@@ -323,7 +320,6 @@ pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base) | |||
323 | ya_node = ya_node->sibling; | 320 | ya_node = ya_node->sibling; |
324 | } | 321 | } |
325 | } | 322 | } |
326 | node = node->sibling; | ||
327 | } | 323 | } |
328 | if (count > 10) { | 324 | if (count > 10) { |
329 | printk("WARNING !! Gatwick interrupt pool overflow\n"); | 325 | printk("WARNING !! Gatwick interrupt pool overflow\n"); |
@@ -338,45 +334,41 @@ pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base) | |||
338 | * controller. If we find this second ohare, set it up and fix the | 334 | * controller. If we find this second ohare, set it up and fix the |
339 | * interrupt value in the device tree for the ethernet chip. | 335 | * interrupt value in the device tree for the ethernet chip. |
340 | */ | 336 | */ |
341 | static int __init enable_second_ohare(void) | 337 | static void __init enable_second_ohare(struct device_node *np) |
342 | { | 338 | { |
343 | unsigned char bus, devfn; | 339 | unsigned char bus, devfn; |
344 | unsigned short cmd; | 340 | unsigned short cmd; |
345 | unsigned long addr; | ||
346 | struct device_node *irqctrler = find_devices("pci106b,7"); | ||
347 | struct device_node *ether; | 341 | struct device_node *ether; |
348 | 342 | ||
349 | if (irqctrler == NULL || irqctrler->n_addrs <= 0) | 343 | /* This code doesn't strictly belong here, it could be part of |
350 | return -1; | 344 | * either the PCI initialisation or the feature code. It's kept |
351 | addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40); | 345 | * here for historical reasons. |
352 | pmac_irq_hw[1] = (volatile struct pmac_irq_hw *)(addr + 0x20); | 346 | */ |
353 | max_irqs = 64; | 347 | if (pci_device_from_OF_node(np, &bus, &devfn) == 0) { |
354 | if (pci_device_from_OF_node(irqctrler, &bus, &devfn) == 0) { | 348 | struct pci_controller* hose = |
355 | struct pci_controller* hose = pci_find_hose_for_OF_device(irqctrler); | 349 | pci_find_hose_for_OF_device(np); |
356 | if (!hose) | 350 | if (!hose) { |
357 | printk(KERN_ERR "Can't find PCI hose for OHare2 !\n"); | 351 | printk(KERN_ERR "Can't find PCI hose for OHare2 !\n"); |
358 | else { | 352 | return; |
359 | early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd); | ||
360 | cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; | ||
361 | cmd &= ~PCI_COMMAND_IO; | ||
362 | early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd); | ||
363 | } | 353 | } |
354 | early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd); | ||
355 | cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; | ||
356 | cmd &= ~PCI_COMMAND_IO; | ||
357 | early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd); | ||
364 | } | 358 | } |
365 | 359 | ||
366 | /* Fix interrupt for the modem/ethernet combo controller. The number | 360 | /* Fix interrupt for the modem/ethernet combo controller. The number |
367 | in the device tree (27) is bogus (correct for the ethernet-only | 361 | * in the device tree (27) is bogus (correct for the ethernet-only |
368 | board but not the combo ethernet/modem board). | 362 | * board but not the combo ethernet/modem board). |
369 | The real interrupt is 28 on the second controller -> 28+32 = 60. | 363 | * The real interrupt is 28 on the second controller -> 28+32 = 60. |
370 | */ | 364 | */ |
371 | ether = find_devices("pci1011,14"); | 365 | ether = of_find_node_by_name(NULL, "pci1011,14"); |
372 | if (ether && ether->n_intrs > 0) { | 366 | if (ether && ether->n_intrs > 0) { |
373 | ether->intrs[0].line = 60; | 367 | ether->intrs[0].line = 60; |
374 | printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n", | 368 | printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n", |
375 | ether->intrs[0].line); | 369 | ether->intrs[0].line); |
376 | } | 370 | } |
377 | 371 | of_node_put(ether); | |
378 | /* Return the interrupt number of the cascade */ | ||
379 | return irqctrler->intrs[0].line; | ||
380 | } | 372 | } |
381 | 373 | ||
382 | #ifdef CONFIG_XMON | 374 | #ifdef CONFIG_XMON |
@@ -394,189 +386,233 @@ static struct irqaction gatwick_cascade_action = { | |||
394 | .mask = CPU_MASK_NONE, | 386 | .mask = CPU_MASK_NONE, |
395 | .name = "cascade", | 387 | .name = "cascade", |
396 | }; | 388 | }; |
397 | #endif /* CONFIG_PPC32 */ | ||
398 | 389 | ||
399 | static int pmac_u3_cascade(struct pt_regs *regs, void *data) | 390 | static void __init pmac_pic_probe_oldstyle(void) |
400 | { | 391 | { |
401 | return mpic_get_one_irq((struct mpic *)data, regs); | ||
402 | } | ||
403 | |||
404 | void __init pmac_pic_init(void) | ||
405 | { | ||
406 | struct device_node *irqctrler = NULL; | ||
407 | struct device_node *irqctrler2 = NULL; | ||
408 | struct device_node *np; | ||
409 | #ifdef CONFIG_PPC32 | ||
410 | int i; | 392 | int i; |
411 | unsigned long addr; | ||
412 | int irq_cascade = -1; | 393 | int irq_cascade = -1; |
413 | #endif | 394 | struct device_node *master = NULL; |
414 | struct mpic *mpic1, *mpic2; | 395 | struct device_node *slave = NULL; |
396 | u8 __iomem *addr; | ||
397 | struct resource r; | ||
415 | 398 | ||
416 | /* We first try to detect Apple's new Core99 chipset, since mac-io | 399 | /* Set our get_irq function */ |
417 | * is quite different on those machines and contains an IBM MPIC2. | 400 | ppc_md.get_irq = pmac_get_irq; |
418 | */ | ||
419 | np = find_type_devices("open-pic"); | ||
420 | while (np) { | ||
421 | if (np->parent && !strcmp(np->parent->name, "u3")) | ||
422 | irqctrler2 = np; | ||
423 | else | ||
424 | irqctrler = np; | ||
425 | np = np->next; | ||
426 | } | ||
427 | if (irqctrler != NULL && irqctrler->n_addrs > 0) { | ||
428 | unsigned char senses[128]; | ||
429 | |||
430 | printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n", | ||
431 | (unsigned int)irqctrler->addrs[0].address); | ||
432 | pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler, 0, 0); | ||
433 | |||
434 | prom_get_irq_senses(senses, 0, 128); | ||
435 | mpic1 = mpic_alloc(irqctrler->addrs[0].address, | ||
436 | MPIC_PRIMARY | MPIC_WANTS_RESET, | ||
437 | 0, 0, 128, 252, senses, 128, " OpenPIC "); | ||
438 | BUG_ON(mpic1 == NULL); | ||
439 | mpic_init(mpic1); | ||
440 | |||
441 | if (irqctrler2 != NULL && irqctrler2->n_intrs > 0 && | ||
442 | irqctrler2->n_addrs > 0) { | ||
443 | printk(KERN_INFO "Slave OpenPIC at 0x%08x hooked on IRQ %d\n", | ||
444 | (u32)irqctrler2->addrs[0].address, | ||
445 | irqctrler2->intrs[0].line); | ||
446 | |||
447 | pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0); | ||
448 | prom_get_irq_senses(senses, 128, 128 + 124); | ||
449 | |||
450 | /* We don't need to set MPIC_BROKEN_U3 here since we don't have | ||
451 | * hypertransport interrupts routed to it | ||
452 | */ | ||
453 | mpic2 = mpic_alloc(irqctrler2->addrs[0].address, | ||
454 | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET, | ||
455 | 0, 128, 124, 0, senses, 124, | ||
456 | " U3-MPIC "); | ||
457 | BUG_ON(mpic2 == NULL); | ||
458 | mpic_init(mpic2); | ||
459 | mpic_setup_cascade(irqctrler2->intrs[0].line, | ||
460 | pmac_u3_cascade, mpic2); | ||
461 | } | ||
462 | #if defined(CONFIG_XMON) && defined(CONFIG_PPC32) | ||
463 | { | ||
464 | struct device_node* pswitch; | ||
465 | int nmi_irq; | ||
466 | |||
467 | pswitch = find_devices("programmer-switch"); | ||
468 | if (pswitch && pswitch->n_intrs) { | ||
469 | nmi_irq = pswitch->intrs[0].line; | ||
470 | mpic_irq_set_priority(nmi_irq, 9); | ||
471 | setup_irq(nmi_irq, &xmon_action); | ||
472 | } | ||
473 | } | ||
474 | #endif /* defined(CONFIG_XMON) && defined(CONFIG_PPC32) */ | ||
475 | return; | ||
476 | } | ||
477 | irqctrler = NULL; | ||
478 | 401 | ||
479 | #ifdef CONFIG_PPC32 | 402 | /* |
480 | /* Get the level/edge settings, assume if it's not | 403 | * Find the interrupt controller type & node |
481 | * a Grand Central nor an OHare, then it's an Heathrow | ||
482 | * (or Paddington). | ||
483 | */ | 404 | */ |
484 | ppc_md.get_irq = pmac_get_irq; | 405 | |
485 | if (find_devices("gc")) | 406 | if ((master = of_find_node_by_name(NULL, "gc")) != NULL) { |
407 | max_irqs = max_real_irqs = 32; | ||
486 | level_mask[0] = GC_LEVEL_MASK; | 408 | level_mask[0] = GC_LEVEL_MASK; |
487 | else if (find_devices("ohare")) { | 409 | } else if ((master = of_find_node_by_name(NULL, "ohare")) != NULL) { |
410 | max_irqs = max_real_irqs = 32; | ||
488 | level_mask[0] = OHARE_LEVEL_MASK; | 411 | level_mask[0] = OHARE_LEVEL_MASK; |
412 | |||
489 | /* We might have a second cascaded ohare */ | 413 | /* We might have a second cascaded ohare */ |
490 | level_mask[1] = OHARE_LEVEL_MASK; | 414 | slave = of_find_node_by_name(NULL, "pci106b,7"); |
491 | } else { | 415 | if (slave) { |
416 | max_irqs = 64; | ||
417 | level_mask[1] = OHARE_LEVEL_MASK; | ||
418 | enable_second_ohare(slave); | ||
419 | } | ||
420 | } else if ((master = of_find_node_by_name(NULL, "mac-io")) != NULL) { | ||
421 | max_irqs = max_real_irqs = 64; | ||
492 | level_mask[0] = HEATHROW_LEVEL_MASK; | 422 | level_mask[0] = HEATHROW_LEVEL_MASK; |
493 | level_mask[1] = 0; | 423 | level_mask[1] = 0; |
424 | |||
494 | /* We might have a second cascaded heathrow */ | 425 | /* We might have a second cascaded heathrow */ |
495 | level_mask[2] = HEATHROW_LEVEL_MASK; | 426 | slave = of_find_node_by_name(master, "mac-io"); |
496 | level_mask[3] = 0; | 427 | |
497 | } | 428 | /* Check ordering of master & slave */ |
429 | if (device_is_compatible(master, "gatwick")) { | ||
430 | struct device_node *tmp; | ||
431 | BUG_ON(slave == NULL); | ||
432 | tmp = master; | ||
433 | master = slave; | ||
434 | slave = tmp; | ||
435 | } | ||
498 | 436 | ||
499 | /* | 437 | /* We found a slave */ |
500 | * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts, | 438 | if (slave) { |
501 | * 1998 G3 Series PowerBooks have 128, | ||
502 | * other powermacs have 32. | ||
503 | * The combo ethernet/modem card for the Powerstar powerbooks | ||
504 | * (2400/3400/3500, ohare based) has a second ohare chip | ||
505 | * effectively making a total of 64. | ||
506 | */ | ||
507 | max_irqs = max_real_irqs = 32; | ||
508 | irqctrler = find_devices("mac-io"); | ||
509 | if (irqctrler) | ||
510 | { | ||
511 | max_real_irqs = 64; | ||
512 | if (irqctrler->next) | ||
513 | max_irqs = 128; | 439 | max_irqs = 128; |
514 | else | 440 | level_mask[2] = HEATHROW_LEVEL_MASK; |
515 | max_irqs = 64; | 441 | level_mask[3] = 0; |
442 | pmac_fix_gatwick_interrupts(slave, max_real_irqs); | ||
443 | } | ||
516 | } | 444 | } |
445 | BUG_ON(master == NULL); | ||
446 | |||
447 | /* Set the handler for the main PIC */ | ||
517 | for ( i = 0; i < max_real_irqs ; i++ ) | 448 | for ( i = 0; i < max_real_irqs ; i++ ) |
518 | irq_desc[i].handler = &pmac_pic; | 449 | irq_desc[i].handler = &pmac_pic; |
519 | 450 | ||
520 | /* get addresses of first controller */ | 451 | /* Get addresses of first controller if we have a node for it */ |
521 | if (irqctrler) { | 452 | BUG_ON(of_address_to_resource(master, 0, &r)); |
522 | if (irqctrler->n_addrs > 0) { | ||
523 | addr = (unsigned long) | ||
524 | ioremap(irqctrler->addrs[0].address, 0x40); | ||
525 | for (i = 0; i < 2; ++i) | ||
526 | pmac_irq_hw[i] = (volatile struct pmac_irq_hw*) | ||
527 | (addr + (2 - i) * 0x10); | ||
528 | } | ||
529 | 453 | ||
530 | /* get addresses of second controller */ | 454 | /* Map interrupts of primary controller */ |
531 | irqctrler = irqctrler->next; | 455 | addr = (u8 __iomem *) ioremap(r.start, 0x40); |
532 | if (irqctrler && irqctrler->n_addrs > 0) { | 456 | i = 0; |
533 | addr = (unsigned long) | 457 | pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *) |
534 | ioremap(irqctrler->addrs[0].address, 0x40); | 458 | (addr + 0x20); |
535 | for (i = 2; i < 4; ++i) | 459 | if (max_real_irqs > 32) |
536 | pmac_irq_hw[i] = (volatile struct pmac_irq_hw*) | 460 | pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *) |
537 | (addr + (4 - i) * 0x10); | 461 | (addr + 0x10); |
538 | irq_cascade = irqctrler->intrs[0].line; | 462 | of_node_put(master); |
539 | if (device_is_compatible(irqctrler, "gatwick")) | 463 | |
540 | pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs); | 464 | printk(KERN_INFO "irq: Found primary Apple PIC %s for %d irqs\n", |
541 | } | 465 | master->full_name, max_real_irqs); |
542 | } else { | 466 | |
543 | /* older powermacs have a GC (grand central) or ohare at | 467 | /* Map interrupts of cascaded controller */ |
544 | f3000000, with interrupt control registers at f3000020. */ | 468 | if (slave && !of_address_to_resource(slave, 0, &r)) { |
545 | addr = (unsigned long) ioremap(0xf3000000, 0x40); | 469 | addr = (u8 __iomem *)ioremap(r.start, 0x40); |
546 | pmac_irq_hw[0] = (volatile struct pmac_irq_hw *) (addr + 0x20); | 470 | pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *) |
471 | (addr + 0x20); | ||
472 | if (max_irqs > 64) | ||
473 | pmac_irq_hw[i++] = | ||
474 | (volatile struct pmac_irq_hw __iomem *) | ||
475 | (addr + 0x10); | ||
476 | irq_cascade = slave->intrs[0].line; | ||
477 | |||
478 | printk(KERN_INFO "irq: Found slave Apple PIC %s for %d irqs" | ||
479 | " cascade: %d\n", slave->full_name, | ||
480 | max_irqs - max_real_irqs, irq_cascade); | ||
547 | } | 481 | } |
548 | 482 | of_node_put(slave); | |
549 | /* PowerBooks 3400 and 3500 can have a second controller in a second | ||
550 | ohare chip, on the combo ethernet/modem card */ | ||
551 | if (machine_is_compatible("AAPL,3400/2400") | ||
552 | || machine_is_compatible("AAPL,3500")) | ||
553 | irq_cascade = enable_second_ohare(); | ||
554 | 483 | ||
555 | /* disable all interrupts in all controllers */ | 484 | /* disable all interrupts in all controllers */ |
556 | for (i = 0; i * 32 < max_irqs; ++i) | 485 | for (i = 0; i * 32 < max_irqs; ++i) |
557 | out_le32(&pmac_irq_hw[i]->enable, 0); | 486 | out_le32(&pmac_irq_hw[i]->enable, 0); |
487 | |||
558 | /* mark level interrupts */ | 488 | /* mark level interrupts */ |
559 | for (i = 0; i < max_irqs; i++) | 489 | for (i = 0; i < max_irqs; i++) |
560 | if (level_mask[i >> 5] & (1UL << (i & 0x1f))) | 490 | if (level_mask[i >> 5] & (1UL << (i & 0x1f))) |
561 | irq_desc[i].status = IRQ_LEVEL; | 491 | irq_desc[i].status = IRQ_LEVEL; |
562 | 492 | ||
563 | /* get interrupt line of secondary interrupt controller */ | 493 | /* Setup handlers for secondary controller and hook cascade irq*/ |
564 | if (irq_cascade >= 0) { | 494 | if (slave) { |
565 | printk(KERN_INFO "irq: secondary controller on irq %d\n", | ||
566 | (int)irq_cascade); | ||
567 | for ( i = max_real_irqs ; i < max_irqs ; i++ ) | 495 | for ( i = max_real_irqs ; i < max_irqs ; i++ ) |
568 | irq_desc[i].handler = &gatwick_pic; | 496 | irq_desc[i].handler = &gatwick_pic; |
569 | setup_irq(irq_cascade, &gatwick_cascade_action); | 497 | setup_irq(irq_cascade, &gatwick_cascade_action); |
570 | } | 498 | } |
571 | printk("System has %d possible interrupts\n", max_irqs); | 499 | printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs); |
572 | if (max_irqs != max_real_irqs) | ||
573 | printk(KERN_DEBUG "%d interrupts on main controller\n", | ||
574 | max_real_irqs); | ||
575 | |||
576 | #ifdef CONFIG_XMON | 500 | #ifdef CONFIG_XMON |
577 | setup_irq(20, &xmon_action); | 501 | setup_irq(20, &xmon_action); |
578 | #endif /* CONFIG_XMON */ | 502 | #endif |
579 | #endif /* CONFIG_PPC32 */ | 503 | } |
504 | #endif /* CONFIG_PPC32 */ | ||
505 | |||
506 | static int pmac_u3_cascade(struct pt_regs *regs, void *data) | ||
507 | { | ||
508 | return mpic_get_one_irq((struct mpic *)data, regs); | ||
509 | } | ||
510 | |||
511 | static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic) | ||
512 | { | ||
513 | #if defined(CONFIG_XMON) && defined(CONFIG_PPC32) | ||
514 | struct device_node* pswitch; | ||
515 | int nmi_irq; | ||
516 | |||
517 | pswitch = of_find_node_by_name(NULL, "programmer-switch"); | ||
518 | if (pswitch && pswitch->n_intrs) { | ||
519 | nmi_irq = pswitch->intrs[0].line; | ||
520 | mpic_irq_set_priority(nmi_irq, 9); | ||
521 | setup_irq(nmi_irq, &xmon_action); | ||
522 | } | ||
523 | of_node_put(pswitch); | ||
524 | #endif /* defined(CONFIG_XMON) && defined(CONFIG_PPC32) */ | ||
525 | } | ||
526 | |||
527 | static int __init pmac_pic_probe_mpic(void) | ||
528 | { | ||
529 | struct mpic *mpic1, *mpic2; | ||
530 | struct device_node *np, *master = NULL, *slave = NULL; | ||
531 | unsigned char senses[128]; | ||
532 | struct resource r; | ||
533 | |||
534 | /* We can have up to 2 MPICs cascaded */ | ||
535 | for (np = NULL; (np = of_find_node_by_type(np, "open-pic")) | ||
536 | != NULL;) { | ||
537 | if (master == NULL && | ||
538 | get_property(np, "interrupt-parent", NULL) != NULL) | ||
539 | master = of_node_get(np); | ||
540 | else if (slave == NULL) | ||
541 | slave = of_node_get(np); | ||
542 | if (master && slave) | ||
543 | break; | ||
544 | } | ||
545 | |||
546 | /* Check for bogus setups */ | ||
547 | if (master == NULL && slave != NULL) { | ||
548 | master = slave; | ||
549 | slave = NULL; | ||
550 | } | ||
551 | |||
552 | /* Not found, default to good old pmac pic */ | ||
553 | if (master == NULL) | ||
554 | return -ENODEV; | ||
555 | |||
556 | /* Set master handler */ | ||
557 | ppc_md.get_irq = mpic_get_irq; | ||
558 | |||
559 | /* Setup master */ | ||
560 | BUG_ON(of_address_to_resource(master, 0, &r)); | ||
561 | pmac_call_feature(PMAC_FTR_ENABLE_MPIC, master, 0, 0); | ||
562 | prom_get_irq_senses(senses, 0, 128); | ||
563 | mpic1 = mpic_alloc(r.start, MPIC_PRIMARY | MPIC_WANTS_RESET, | ||
564 | 0, 0, 128, 252, senses, 128, " OpenPIC "); | ||
565 | BUG_ON(mpic1 == NULL); | ||
566 | mpic_init(mpic1); | ||
567 | |||
568 | /* Install NMI if any */ | ||
569 | pmac_pic_setup_mpic_nmi(mpic1); | ||
570 | |||
571 | of_node_put(master); | ||
572 | |||
573 | /* No slave, let's go out */ | ||
574 | if (slave == NULL || slave->n_intrs < 1) | ||
575 | return 0; | ||
576 | |||
577 | /* Setup slave, failures are non-fatal */ | ||
578 | if (of_address_to_resource(slave, 0, &r)) { | ||
579 | printk(KERN_ERR "Can't get address of MPIC %s\n", | ||
580 | slave->full_name); | ||
581 | return 0; | ||
582 | } | ||
583 | pmac_call_feature(PMAC_FTR_ENABLE_MPIC, slave, 0, 0); | ||
584 | prom_get_irq_senses(senses, 128, 128 + 124); | ||
585 | |||
586 | /* We don't need to set MPIC_BROKEN_U3 here since we don't have | ||
587 | * hypertransport interrupts routed to it, at least not on currently | ||
588 | * supported machines, that may change. | ||
589 | */ | ||
590 | mpic2 = mpic_alloc(r.start, MPIC_BIG_ENDIAN | MPIC_WANTS_RESET, | ||
591 | 0, 128, 124, 0, senses, 124, " U3-MPIC "); | ||
592 | if (mpic2 == NULL) { | ||
593 | printk(KERN_ERR "Can't create slave MPIC %s\n", | ||
594 | slave->full_name); | ||
595 | return 0; | ||
596 | } | ||
597 | mpic_init(mpic2); | ||
598 | mpic_setup_cascade(slave->intrs[0].line, pmac_u3_cascade, mpic2); | ||
599 | |||
600 | of_node_put(slave); | ||
601 | return 0; | ||
602 | } | ||
603 | |||
604 | |||
605 | void __init pmac_pic_init(void) | ||
606 | { | ||
607 | /* We first try to detect Apple's new Core99 chipset, since mac-io | ||
608 | * is quite different on those machines and contains an IBM MPIC2. | ||
609 | */ | ||
610 | if (pmac_pic_probe_mpic() == 0) | ||
611 | return; | ||
612 | |||
613 | #ifdef CONFIG_PPC32 | ||
614 | pmac_pic_probe_oldstyle(); | ||
615 | #endif | ||
580 | } | 616 | } |
581 | 617 | ||
582 | #if defined(CONFIG_PM) && defined(CONFIG_PPC32) | 618 | #if defined(CONFIG_PM) && defined(CONFIG_PPC32) |
diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h index 2ad25e13423e..21c7b0f8f329 100644 --- a/arch/powerpc/platforms/powermac/pmac.h +++ b/arch/powerpc/platforms/powermac/pmac.h | |||
@@ -42,10 +42,6 @@ extern void pmac_ide_init_hwif_ports(hw_regs_t *hw, | |||
42 | unsigned long data_port, unsigned long ctrl_port, int *irq); | 42 | unsigned long data_port, unsigned long ctrl_port, int *irq); |
43 | 43 | ||
44 | extern int pmac_nvram_init(void); | 44 | extern int pmac_nvram_init(void); |
45 | 45 | extern void pmac_pic_init(void); | |
46 | extern struct hw_interrupt_type pmac_pic; | ||
47 | |||
48 | void pmac_pic_init(void); | ||
49 | int pmac_get_irq(struct pt_regs *regs); | ||
50 | 46 | ||
51 | #endif /* __PMAC_H__ */ | 47 | #endif /* __PMAC_H__ */ |
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index c0638e47c298..18c5620f87fa 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c | |||
@@ -75,7 +75,6 @@ | |||
75 | #include <asm/iommu.h> | 75 | #include <asm/iommu.h> |
76 | #include <asm/smu.h> | 76 | #include <asm/smu.h> |
77 | #include <asm/pmc.h> | 77 | #include <asm/pmc.h> |
78 | #include <asm/mpic.h> | ||
79 | #include <asm/lmb.h> | 78 | #include <asm/lmb.h> |
80 | #include <asm/udbg.h> | 79 | #include <asm/udbg.h> |
81 | 80 | ||
@@ -751,7 +750,7 @@ struct machdep_calls __initdata pmac_md = { | |||
751 | .init_early = pmac_init_early, | 750 | .init_early = pmac_init_early, |
752 | .show_cpuinfo = pmac_show_cpuinfo, | 751 | .show_cpuinfo = pmac_show_cpuinfo, |
753 | .init_IRQ = pmac_pic_init, | 752 | .init_IRQ = pmac_pic_init, |
754 | .get_irq = mpic_get_irq, /* changed later */ | 753 | .get_irq = NULL, /* changed later */ |
755 | .pcibios_fixup = pmac_pcibios_fixup, | 754 | .pcibios_fixup = pmac_pcibios_fixup, |
756 | .restart = pmac_restart, | 755 | .restart = pmac_restart, |
757 | .power_off = pmac_power_off, | 756 | .power_off = pmac_power_off, |
diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c index feb0a94e7819..5d9afa1fa02d 100644 --- a/arch/powerpc/platforms/powermac/time.c +++ b/arch/powerpc/platforms/powermac/time.c | |||
@@ -258,15 +258,20 @@ int __init via_calibrate_decr(void) | |||
258 | volatile unsigned char __iomem *via; | 258 | volatile unsigned char __iomem *via; |
259 | int count = VIA_TIMER_FREQ_6 / 100; | 259 | int count = VIA_TIMER_FREQ_6 / 100; |
260 | unsigned int dstart, dend; | 260 | unsigned int dstart, dend; |
261 | struct resource rsrc; | ||
261 | 262 | ||
262 | vias = find_devices("via-cuda"); | 263 | vias = of_find_node_by_name(NULL, "via-cuda"); |
263 | if (vias == 0) | 264 | if (vias == 0) |
264 | vias = find_devices("via-pmu"); | 265 | vias = of_find_node_by_name(NULL, "via-pmu"); |
265 | if (vias == 0) | 266 | if (vias == 0) |
266 | vias = find_devices("via"); | 267 | vias = of_find_node_by_name(NULL, "via"); |
267 | if (vias == 0 || vias->n_addrs == 0) | 268 | if (vias == 0 || of_address_to_resource(vias, 0, &rsrc)) |
268 | return 0; | 269 | return 0; |
269 | via = ioremap(vias->addrs[0].address, vias->addrs[0].size); | 270 | via = ioremap(rsrc.start, rsrc.end - rsrc.start + 1); |
271 | if (via == NULL) { | ||
272 | printk(KERN_ERR "Failed to map VIA for timer calibration !\n"); | ||
273 | return 0; | ||
274 | } | ||
270 | 275 | ||
271 | /* set timer 1 for continuous interrupts */ | 276 | /* set timer 1 for continuous interrupts */ |
272 | out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT); | 277 | out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT); |