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 | |
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>
31 files changed, 793 insertions, 1106 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); |
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index af7cb2bfd670..01f042f6f1c4 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c | |||
@@ -1083,23 +1083,33 @@ static int swim3_add_device(struct device_node *swim) | |||
1083 | { | 1083 | { |
1084 | struct device_node *mediabay; | 1084 | struct device_node *mediabay; |
1085 | struct floppy_state *fs = &floppy_states[floppy_count]; | 1085 | struct floppy_state *fs = &floppy_states[floppy_count]; |
1086 | struct resource res_reg, res_dma; | ||
1086 | 1087 | ||
1087 | if (swim->n_addrs < 2) | 1088 | if (of_address_to_resource(swim, 0, &res_reg) || |
1088 | { | 1089 | of_address_to_resource(swim, 1, &res_dma)) { |
1089 | printk(KERN_INFO "swim3: expecting 2 addrs (n_addrs:%d, n_intrs:%d)\n", | 1090 | printk(KERN_ERR "swim3: Can't get addresses\n"); |
1090 | swim->n_addrs, swim->n_intrs); | ||
1091 | return -EINVAL; | 1091 | return -EINVAL; |
1092 | } | 1092 | } |
1093 | 1093 | if (request_mem_region(res_reg.start, res_reg.end - res_reg.start + 1, | |
1094 | if (swim->n_intrs < 2) | 1094 | " (reg)") == NULL) { |
1095 | { | 1095 | printk(KERN_ERR "swim3: Can't request register space\n"); |
1096 | printk(KERN_INFO "swim3: expecting 2 intrs (n_addrs:%d, n_intrs:%d)\n", | 1096 | return -EINVAL; |
1097 | swim->n_addrs, swim->n_intrs); | 1097 | } |
1098 | if (request_mem_region(res_dma.start, res_dma.end - res_dma.start + 1, | ||
1099 | " (dma)") == NULL) { | ||
1100 | release_mem_region(res_reg.start, | ||
1101 | res_reg.end - res_reg.start + 1); | ||
1102 | printk(KERN_ERR "swim3: Can't request DMA space\n"); | ||
1098 | return -EINVAL; | 1103 | return -EINVAL; |
1099 | } | 1104 | } |
1100 | 1105 | ||
1101 | if (!request_OF_resource(swim, 0, NULL)) { | 1106 | if (swim->n_intrs < 2) { |
1102 | printk(KERN_INFO "swim3: can't request IO resource !\n"); | 1107 | printk(KERN_INFO "swim3: expecting 2 intrs (n_intrs:%d)\n", |
1108 | swim->n_intrs); | ||
1109 | release_mem_region(res_reg.start, | ||
1110 | res_reg.end - res_reg.start + 1); | ||
1111 | release_mem_region(res_dma.start, | ||
1112 | res_dma.end - res_dma.start + 1); | ||
1103 | return -EINVAL; | 1113 | return -EINVAL; |
1104 | } | 1114 | } |
1105 | 1115 | ||
@@ -1110,10 +1120,8 @@ static int swim3_add_device(struct device_node *swim) | |||
1110 | memset(fs, 0, sizeof(*fs)); | 1120 | memset(fs, 0, sizeof(*fs)); |
1111 | spin_lock_init(&fs->lock); | 1121 | spin_lock_init(&fs->lock); |
1112 | fs->state = idle; | 1122 | fs->state = idle; |
1113 | fs->swim3 = (struct swim3 __iomem *) | 1123 | fs->swim3 = (struct swim3 __iomem *)ioremap(res_reg.start, 0x200); |
1114 | ioremap(swim->addrs[0].address, 0x200); | 1124 | fs->dma = (struct dbdma_regs __iomem *)ioremap(res_dma.start, 0x200); |
1115 | fs->dma = (struct dbdma_regs __iomem *) | ||
1116 | ioremap(swim->addrs[1].address, 0x200); | ||
1117 | fs->swim3_intr = swim->intrs[0].line; | 1125 | fs->swim3_intr = swim->intrs[0].line; |
1118 | fs->dma_intr = swim->intrs[1].line; | 1126 | fs->dma_intr = swim->intrs[1].line; |
1119 | fs->cur_cyl = -1; | 1127 | fs->cur_cyl = -1; |
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 16b28357885b..a8d3bc0a9c5c 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c | |||
@@ -1271,7 +1271,7 @@ static int | |||
1271 | pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) | 1271 | pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) |
1272 | { | 1272 | { |
1273 | struct device_node *np = pmif->node; | 1273 | struct device_node *np = pmif->node; |
1274 | int *bidp, i; | 1274 | int *bidp; |
1275 | 1275 | ||
1276 | pmif->cable_80 = 0; | 1276 | pmif->cable_80 = 0; |
1277 | pmif->broken_dma = pmif->broken_dma_warn = 0; | 1277 | pmif->broken_dma = pmif->broken_dma_warn = 0; |
@@ -1430,7 +1430,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) | |||
1430 | pmif = &pmac_ide[i]; | 1430 | pmif = &pmac_ide[i]; |
1431 | hwif = &ide_hwifs[i]; | 1431 | hwif = &ide_hwifs[i]; |
1432 | 1432 | ||
1433 | if (mdev->ofdev.node->n_addrs == 0) { | 1433 | if (macio_resource_count(mdev) == 0) { |
1434 | printk(KERN_WARNING "ide%d: no address for %s\n", | 1434 | printk(KERN_WARNING "ide%d: no address for %s\n", |
1435 | i, mdev->ofdev.node->full_name); | 1435 | i, mdev->ofdev.node->full_name); |
1436 | return -ENXIO; | 1436 | return -ENXIO; |
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 0137ff239f13..2a545ceb523b 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c | |||
@@ -256,42 +256,42 @@ static int macio_resource_quirks(struct device_node *np, struct resource *res, | |||
256 | { | 256 | { |
257 | if (res->flags & IORESOURCE_MEM) { | 257 | if (res->flags & IORESOURCE_MEM) { |
258 | /* Grand Central has too large resource 0 on some machines */ | 258 | /* Grand Central has too large resource 0 on some machines */ |
259 | if (index == 0 && !strcmp(np->name, "gc")) { | 259 | if (index == 0 && !strcmp(np->name, "gc")) |
260 | np->addrs[0].size = 0x20000; | ||
261 | res->end = res->start + 0x1ffff; | 260 | res->end = res->start + 0x1ffff; |
262 | } | 261 | |
263 | /* Airport has bogus resource 2 */ | 262 | /* Airport has bogus resource 2 */ |
264 | if (index >= 2 && !strcmp(np->name, "radio")) | 263 | if (index >= 2 && !strcmp(np->name, "radio")) |
265 | return 1; | 264 | return 1; |
265 | |||
266 | #ifndef CONFIG_PPC64 | ||
266 | /* DBDMAs may have bogus sizes */ | 267 | /* DBDMAs may have bogus sizes */ |
267 | if ((res->start & 0x0001f000) == 0x00008000) { | 268 | if ((res->start & 0x0001f000) == 0x00008000) |
268 | np->addrs[index].size = 0x100; | ||
269 | res->end = res->start + 0xff; | 269 | res->end = res->start + 0xff; |
270 | } | 270 | #endif /* CONFIG_PPC64 */ |
271 | |||
271 | /* ESCC parent eats child resources. We could have added a | 272 | /* ESCC parent eats child resources. We could have added a |
272 | * level of hierarchy, but I don't really feel the need | 273 | * level of hierarchy, but I don't really feel the need |
273 | * for it | 274 | * for it |
274 | */ | 275 | */ |
275 | if (!strcmp(np->name, "escc")) | 276 | if (!strcmp(np->name, "escc")) |
276 | return 1; | 277 | return 1; |
278 | |||
277 | /* ESCC has bogus resources >= 3 */ | 279 | /* ESCC has bogus resources >= 3 */ |
278 | if (index >= 3 && !(strcmp(np->name, "ch-a") && | 280 | if (index >= 3 && !(strcmp(np->name, "ch-a") && |
279 | strcmp(np->name, "ch-b"))) | 281 | strcmp(np->name, "ch-b"))) |
280 | return 1; | 282 | return 1; |
283 | |||
281 | /* Media bay has too many resources, keep only first one */ | 284 | /* Media bay has too many resources, keep only first one */ |
282 | if (index > 0 && !strcmp(np->name, "media-bay")) | 285 | if (index > 0 && !strcmp(np->name, "media-bay")) |
283 | return 1; | 286 | return 1; |
287 | |||
284 | /* Some older IDE resources have bogus sizes */ | 288 | /* Some older IDE resources have bogus sizes */ |
285 | if (!(strcmp(np->name, "IDE") && strcmp(np->name, "ATA") && | 289 | if (!(strcmp(np->name, "IDE") && strcmp(np->name, "ATA") && |
286 | strcmp(np->type, "ide") && strcmp(np->type, "ata"))) { | 290 | strcmp(np->type, "ide") && strcmp(np->type, "ata"))) { |
287 | if (index == 0 && np->addrs[0].size > 0x1000) { | 291 | if (index == 0 && (res->end - res->start) > 0xfff) |
288 | np->addrs[0].size = 0x1000; | ||
289 | res->end = res->start + 0xfff; | 292 | res->end = res->start + 0xfff; |
290 | } | 293 | if (index == 1 && (res->end - res->start) > 0xff) |
291 | if (index == 1 && np->addrs[1].size > 0x100) { | ||
292 | np->addrs[1].size = 0x100; | ||
293 | res->end = res->start + 0xff; | 294 | res->end = res->start + 0xff; |
294 | } | ||
295 | } | 295 | } |
296 | } | 296 | } |
297 | return 0; | 297 | return 0; |
@@ -349,7 +349,7 @@ static void macio_setup_resources(struct macio_dev *dev, | |||
349 | /* Currently, we consider failure as harmless, this may | 349 | /* Currently, we consider failure as harmless, this may |
350 | * change in the future, once I've found all the device | 350 | * change in the future, once I've found all the device |
351 | * tree bugs in older machines & worked around them | 351 | * tree bugs in older machines & worked around them |
352 | l */ | 352 | */ |
353 | if (insert_resource(parent_res, res)) { | 353 | if (insert_resource(parent_res, res)) { |
354 | printk(KERN_WARNING "Can't request resource " | 354 | printk(KERN_WARNING "Can't request resource " |
355 | "%d for MacIO device %s\n", | 355 | "%d for MacIO device %s\n", |
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index b856bb67169c..8dbf2852bae0 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c | |||
@@ -647,6 +647,7 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_de | |||
647 | struct media_bay_info* bay; | 647 | struct media_bay_info* bay; |
648 | u32 __iomem *regbase; | 648 | u32 __iomem *regbase; |
649 | struct device_node *ofnode; | 649 | struct device_node *ofnode; |
650 | unsigned long base; | ||
650 | int i; | 651 | int i; |
651 | 652 | ||
652 | ofnode = mdev->ofdev.node; | 653 | ofnode = mdev->ofdev.node; |
@@ -656,10 +657,11 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_de | |||
656 | if (macio_request_resources(mdev, "media-bay")) | 657 | if (macio_request_resources(mdev, "media-bay")) |
657 | return -EBUSY; | 658 | return -EBUSY; |
658 | /* Media bay registers are located at the beginning of the | 659 | /* Media bay registers are located at the beginning of the |
659 | * mac-io chip, we get the parent address for now (hrm...) | 660 | * mac-io chip, for now, we trick and align down the first |
661 | * resource passed in | ||
660 | */ | 662 | */ |
661 | regbase = (u32 __iomem *) | 663 | base = macio_resource_start(mdev, 0) & 0xffff0000u; |
662 | ioremap(ofnode->parent->addrs[0].address, 0x100); | 664 | regbase = (u32 __iomem *)ioremap(base, 0x100); |
663 | if (regbase == NULL) { | 665 | if (regbase == NULL) { |
664 | macio_release_resources(mdev); | 666 | macio_release_resources(mdev); |
665 | return -ENOMEM; | 667 | return -ENOMEM; |
diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c index 18ff770ea668..2d9d79150403 100644 --- a/drivers/macintosh/via-cuda.c +++ b/drivers/macintosh/via-cuda.c | |||
@@ -193,10 +193,6 @@ static int __init via_cuda_start(void) | |||
193 | if (via == NULL) | 193 | if (via == NULL) |
194 | return -ENODEV; | 194 | return -ENODEV; |
195 | 195 | ||
196 | #ifdef CONFIG_PPC | ||
197 | request_OF_resource(vias, 0, NULL); | ||
198 | #endif | ||
199 | |||
200 | if (request_irq(CUDA_IRQ, cuda_interrupt, 0, "ADB", cuda_interrupt)) { | 196 | if (request_irq(CUDA_IRQ, cuda_interrupt, 0, "ADB", cuda_interrupt)) { |
201 | printk(KERN_ERR "cuda_init: can't get irq %d\n", CUDA_IRQ); | 197 | printk(KERN_ERR "cuda_init: can't get irq %d\n", CUDA_IRQ); |
202 | return -EAGAIN; | 198 | return -EAGAIN; |
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index d6dabee55f2f..79c7b44a94ee 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c | |||
@@ -298,7 +298,7 @@ static struct backlight_controller pmu_backlight_controller = { | |||
298 | 298 | ||
299 | int __init find_via_pmu(void) | 299 | int __init find_via_pmu(void) |
300 | { | 300 | { |
301 | phys_addr_t taddr; | 301 | u64 taddr; |
302 | u32 *reg; | 302 | u32 *reg; |
303 | 303 | ||
304 | if (via != 0) | 304 | if (via != 0) |
@@ -337,7 +337,7 @@ int __init find_via_pmu(void) | |||
337 | else if (device_is_compatible(vias->parent, "Keylargo") | 337 | else if (device_is_compatible(vias->parent, "Keylargo") |
338 | || device_is_compatible(vias->parent, "K2-Keylargo")) { | 338 | || device_is_compatible(vias->parent, "K2-Keylargo")) { |
339 | struct device_node *gpiop; | 339 | struct device_node *gpiop; |
340 | phys_addr_t gaddr = 0; | 340 | u64 gaddr = OF_BAD_ADDR; |
341 | 341 | ||
342 | pmu_kind = PMU_KEYLARGO_BASED; | 342 | pmu_kind = PMU_KEYLARGO_BASED; |
343 | pmu_has_adb = (find_type_devices("adb") != NULL); | 343 | pmu_has_adb = (find_type_devices("adb") != NULL); |
@@ -352,7 +352,7 @@ int __init find_via_pmu(void) | |||
352 | reg = (u32 *)get_property(gpiop, "reg", NULL); | 352 | reg = (u32 *)get_property(gpiop, "reg", NULL); |
353 | if (reg) | 353 | if (reg) |
354 | gaddr = of_translate_address(gpiop, reg); | 354 | gaddr = of_translate_address(gpiop, reg); |
355 | if (gaddr != 0) | 355 | if (gaddr != OF_BAD_ADDR) |
356 | gpio_reg = ioremap(gaddr, 0x10); | 356 | gpio_reg = ioremap(gaddr, 0x10); |
357 | } | 357 | } |
358 | if (gpio_reg == NULL) | 358 | if (gpio_reg == NULL) |
@@ -479,9 +479,6 @@ static int __init via_pmu_dev_init(void) | |||
479 | if (vias == NULL) | 479 | if (vias == NULL) |
480 | return -ENODEV; | 480 | return -ENODEV; |
481 | 481 | ||
482 | #ifndef CONFIG_PPC64 | ||
483 | request_OF_resource(vias, 0, NULL); | ||
484 | #endif | ||
485 | #ifdef CONFIG_PMAC_BACKLIGHT | 482 | #ifdef CONFIG_PMAC_BACKLIGHT |
486 | /* Enable backlight */ | 483 | /* Enable backlight */ |
487 | register_backlight_controller(&pmu_backlight_controller, NULL, "pmu"); | 484 | register_backlight_controller(&pmu_backlight_controller, NULL, "pmu"); |
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index 932dcf0366eb..311a4122bd70 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c | |||
@@ -432,11 +432,12 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat | |||
432 | struct Scsi_Host *host; | 432 | struct Scsi_Host *host; |
433 | void *dma_cmd_space; | 433 | void *dma_cmd_space; |
434 | unsigned char *clkprop; | 434 | unsigned char *clkprop; |
435 | int proplen; | 435 | int proplen, rc = -ENODEV; |
436 | 436 | ||
437 | if (macio_resource_count(mdev) != 2 || macio_irq_count(mdev) != 2) { | 437 | if (macio_resource_count(mdev) != 2 || macio_irq_count(mdev) != 2) { |
438 | printk(KERN_ERR "mac53c94: expected 2 addrs and intrs (got %d/%d)\n", | 438 | printk(KERN_ERR "mac53c94: expected 2 addrs and intrs" |
439 | node->n_addrs, node->n_intrs); | 439 | " (got %d/%d)\n", |
440 | macio_resource_count(mdev), macio_irq_count(mdev)); | ||
440 | return -ENODEV; | 441 | return -ENODEV; |
441 | } | 442 | } |
442 | 443 | ||
@@ -448,6 +449,7 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat | |||
448 | host = scsi_host_alloc(&mac53c94_template, sizeof(struct fsc_state)); | 449 | host = scsi_host_alloc(&mac53c94_template, sizeof(struct fsc_state)); |
449 | if (host == NULL) { | 450 | if (host == NULL) { |
450 | printk(KERN_ERR "mac53c94: couldn't register host"); | 451 | printk(KERN_ERR "mac53c94: couldn't register host"); |
452 | rc = -ENOMEM; | ||
451 | goto out_release; | 453 | goto out_release; |
452 | } | 454 | } |
453 | 455 | ||
@@ -486,6 +488,7 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat | |||
486 | if (dma_cmd_space == 0) { | 488 | if (dma_cmd_space == 0) { |
487 | printk(KERN_ERR "mac53c94: couldn't allocate dma " | 489 | printk(KERN_ERR "mac53c94: couldn't allocate dma " |
488 | "command space for %s\n", node->full_name); | 490 | "command space for %s\n", node->full_name); |
491 | rc = -ENOMEM; | ||
489 | goto out_free; | 492 | goto out_free; |
490 | } | 493 | } |
491 | state->dma_cmds = (struct dbdma_cmd *)DBDMA_ALIGN(dma_cmd_space); | 494 | state->dma_cmds = (struct dbdma_cmd *)DBDMA_ALIGN(dma_cmd_space); |
@@ -495,18 +498,21 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat | |||
495 | 498 | ||
496 | mac53c94_init(state); | 499 | mac53c94_init(state); |
497 | 500 | ||
498 | if (request_irq(state->intr, do_mac53c94_interrupt, 0, "53C94", state)) { | 501 | if (request_irq(state->intr, do_mac53c94_interrupt, 0, "53C94",state)) { |
499 | printk(KERN_ERR "mac53C94: can't get irq %d for %s\n", | 502 | printk(KERN_ERR "mac53C94: can't get irq %d for %s\n", |
500 | state->intr, node->full_name); | 503 | state->intr, node->full_name); |
501 | goto out_free_dma; | 504 | goto out_free_dma; |
502 | } | 505 | } |
503 | 506 | ||
504 | /* XXX FIXME: handle failure */ | 507 | rc = scsi_add_host(host, &mdev->ofdev.dev); |
505 | scsi_add_host(host, &mdev->ofdev.dev); | 508 | if (rc != 0) |
506 | scsi_scan_host(host); | 509 | goto out_release_irq; |
507 | 510 | ||
511 | scsi_scan_host(host); | ||
508 | return 0; | 512 | return 0; |
509 | 513 | ||
514 | out_release_irq: | ||
515 | free_irq(state->intr, state); | ||
510 | out_free_dma: | 516 | out_free_dma: |
511 | kfree(state->dma_cmd_space); | 517 | kfree(state->dma_cmd_space); |
512 | out_free: | 518 | out_free: |
@@ -518,7 +524,7 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat | |||
518 | out_release: | 524 | out_release: |
519 | macio_release_resources(mdev); | 525 | macio_release_resources(mdev); |
520 | 526 | ||
521 | return -ENODEV; | 527 | return rc; |
522 | } | 528 | } |
523 | 529 | ||
524 | static int mac53c94_remove(struct macio_dev *mdev) | 530 | static int mac53c94_remove(struct macio_dev *mdev) |
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c index bdccf73cf9fe..d6d2125f9044 100644 --- a/drivers/scsi/mesh.c +++ b/drivers/scsi/mesh.c | |||
@@ -1869,7 +1869,8 @@ static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match) | |||
1869 | 1869 | ||
1870 | if (macio_resource_count(mdev) != 2 || macio_irq_count(mdev) != 2) { | 1870 | if (macio_resource_count(mdev) != 2 || macio_irq_count(mdev) != 2) { |
1871 | printk(KERN_ERR "mesh: expected 2 addrs and 2 intrs" | 1871 | printk(KERN_ERR "mesh: expected 2 addrs and 2 intrs" |
1872 | " (got %d,%d)\n", mesh->n_addrs, mesh->n_intrs); | 1872 | " (got %d,%d)\n", macio_resource_count(mdev), |
1873 | macio_irq_count(mdev)); | ||
1873 | return -ENODEV; | 1874 | return -ENODEV; |
1874 | } | 1875 | } |
1875 | 1876 | ||
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 5ddd8ab1f108..ea24129eb6b9 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c | |||
@@ -1431,11 +1431,14 @@ static int __init pmz_init_port(struct uart_pmac_port *uap) | |||
1431 | char name[1]; | 1431 | char name[1]; |
1432 | } *slots; | 1432 | } *slots; |
1433 | int len; | 1433 | int len; |
1434 | struct resource r_ports, r_rxdma, r_txdma; | ||
1434 | 1435 | ||
1435 | /* | 1436 | /* |
1436 | * Request & map chip registers | 1437 | * Request & map chip registers |
1437 | */ | 1438 | */ |
1438 | uap->port.mapbase = np->addrs[0].address; | 1439 | if (of_address_to_resource(np, 0, &r_ports)) |
1440 | return -ENODEV; | ||
1441 | uap->port.mapbase = r_ports.start; | ||
1439 | uap->port.membase = ioremap(uap->port.mapbase, 0x1000); | 1442 | uap->port.membase = ioremap(uap->port.mapbase, 0x1000); |
1440 | 1443 | ||
1441 | uap->control_reg = uap->port.membase; | 1444 | uap->control_reg = uap->port.membase; |
@@ -1445,16 +1448,20 @@ static int __init pmz_init_port(struct uart_pmac_port *uap) | |||
1445 | * Request & map DBDMA registers | 1448 | * Request & map DBDMA registers |
1446 | */ | 1449 | */ |
1447 | #ifdef HAS_DBDMA | 1450 | #ifdef HAS_DBDMA |
1448 | if (np->n_addrs >= 3 && np->n_intrs >= 3) | 1451 | if (of_address_to_resource(np, 1, &r_txdma) == 0 && |
1452 | of_address_to_resource(np, 2, &r_rxdma) == 0) | ||
1449 | uap->flags |= PMACZILOG_FLAG_HAS_DMA; | 1453 | uap->flags |= PMACZILOG_FLAG_HAS_DMA; |
1454 | #else | ||
1455 | memset(&r_txdma, 0, sizeof(struct resource)); | ||
1456 | memset(&r_rxdma, 0, sizeof(struct resource)); | ||
1450 | #endif | 1457 | #endif |
1451 | if (ZS_HAS_DMA(uap)) { | 1458 | if (ZS_HAS_DMA(uap)) { |
1452 | uap->tx_dma_regs = ioremap(np->addrs[np->n_addrs - 2].address, 0x1000); | 1459 | uap->tx_dma_regs = ioremap(r_txdma.start, 0x100); |
1453 | if (uap->tx_dma_regs == NULL) { | 1460 | if (uap->tx_dma_regs == NULL) { |
1454 | uap->flags &= ~PMACZILOG_FLAG_HAS_DMA; | 1461 | uap->flags &= ~PMACZILOG_FLAG_HAS_DMA; |
1455 | goto no_dma; | 1462 | goto no_dma; |
1456 | } | 1463 | } |
1457 | uap->rx_dma_regs = ioremap(np->addrs[np->n_addrs - 1].address, 0x1000); | 1464 | uap->rx_dma_regs = ioremap(r_rxdma.start, 0x100); |
1458 | if (uap->rx_dma_regs == NULL) { | 1465 | if (uap->rx_dma_regs == NULL) { |
1459 | iounmap(uap->tx_dma_regs); | 1466 | iounmap(uap->tx_dma_regs); |
1460 | uap->tx_dma_regs = NULL; | 1467 | uap->tx_dma_regs = NULL; |
diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c index 403d17377f8d..03798e9c882d 100644 --- a/drivers/video/controlfb.c +++ b/drivers/video/controlfb.c | |||
@@ -133,12 +133,6 @@ static int controlfb_mmap(struct fb_info *info, struct file *file, | |||
133 | static int controlfb_set_par (struct fb_info *info); | 133 | static int controlfb_set_par (struct fb_info *info); |
134 | static int controlfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info); | 134 | static int controlfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info); |
135 | 135 | ||
136 | /* | ||
137 | * inititialization | ||
138 | */ | ||
139 | int control_init(void); | ||
140 | void control_setup(char *); | ||
141 | |||
142 | /******************** Prototypes for internal functions **********************/ | 136 | /******************** Prototypes for internal functions **********************/ |
143 | 137 | ||
144 | static void set_control_clock(unsigned char *params); | 138 | static void set_control_clock(unsigned char *params); |
@@ -550,9 +544,46 @@ static void control_set_hardware(struct fb_info_control *p, struct fb_par_contro | |||
550 | 544 | ||
551 | 545 | ||
552 | /* | 546 | /* |
553 | * Called from fbmem.c for probing & initializing | 547 | * Parse user speficied options (`video=controlfb:') |
554 | */ | 548 | */ |
555 | int __init control_init(void) | 549 | static void __init control_setup(char *options) |
550 | { | ||
551 | char *this_opt; | ||
552 | |||
553 | if (!options || !*options) | ||
554 | return; | ||
555 | |||
556 | while ((this_opt = strsep(&options, ",")) != NULL) { | ||
557 | if (!strncmp(this_opt, "vmode:", 6)) { | ||
558 | int vmode = simple_strtoul(this_opt+6, NULL, 0); | ||
559 | if (vmode > 0 && vmode <= VMODE_MAX && | ||
560 | control_mac_modes[vmode - 1].m[1] >= 0) | ||
561 | default_vmode = vmode; | ||
562 | } else if (!strncmp(this_opt, "cmode:", 6)) { | ||
563 | int depth = simple_strtoul(this_opt+6, NULL, 0); | ||
564 | switch (depth) { | ||
565 | case CMODE_8: | ||
566 | case CMODE_16: | ||
567 | case CMODE_32: | ||
568 | default_cmode = depth; | ||
569 | break; | ||
570 | case 8: | ||
571 | default_cmode = CMODE_8; | ||
572 | break; | ||
573 | case 15: | ||
574 | case 16: | ||
575 | default_cmode = CMODE_16; | ||
576 | break; | ||
577 | case 24: | ||
578 | case 32: | ||
579 | default_cmode = CMODE_32; | ||
580 | break; | ||
581 | } | ||
582 | } | ||
583 | } | ||
584 | } | ||
585 | |||
586 | static int __init control_init(void) | ||
556 | { | 587 | { |
557 | struct device_node *dp; | 588 | struct device_node *dp; |
558 | char *option = NULL; | 589 | char *option = NULL; |
@@ -651,15 +682,16 @@ static void __init find_vram_size(struct fb_info_control *p) | |||
651 | static int __init control_of_init(struct device_node *dp) | 682 | static int __init control_of_init(struct device_node *dp) |
652 | { | 683 | { |
653 | struct fb_info_control *p; | 684 | struct fb_info_control *p; |
654 | unsigned long addr; | 685 | struct resource fb_res, reg_res; |
655 | int i; | ||
656 | 686 | ||
657 | if (control_fb) { | 687 | if (control_fb) { |
658 | printk(KERN_ERR "controlfb: only one control is supported\n"); | 688 | printk(KERN_ERR "controlfb: only one control is supported\n"); |
659 | return -ENXIO; | 689 | return -ENXIO; |
660 | } | 690 | } |
661 | if(dp->n_addrs != 2) { | 691 | |
662 | printk(KERN_ERR "expecting 2 address for control (got %d)", dp->n_addrs); | 692 | if (of_pci_address_to_resource(dp, 2, &fb_res) || |
693 | of_pci_address_to_resource(dp, 1, ®_res)) { | ||
694 | printk(KERN_ERR "can't get 2 addresses for control\n"); | ||
663 | return -ENXIO; | 695 | return -ENXIO; |
664 | } | 696 | } |
665 | p = kmalloc(sizeof(*p), GFP_KERNEL); | 697 | p = kmalloc(sizeof(*p), GFP_KERNEL); |
@@ -669,18 +701,12 @@ static int __init control_of_init(struct device_node *dp) | |||
669 | memset(p, 0, sizeof(*p)); | 701 | memset(p, 0, sizeof(*p)); |
670 | 702 | ||
671 | /* Map in frame buffer and registers */ | 703 | /* Map in frame buffer and registers */ |
672 | for (i = 0; i < dp->n_addrs; ++i) { | 704 | p->fb_orig_base = fb_res.start; |
673 | addr = dp->addrs[i].address; | 705 | p->fb_orig_size = fb_res.end - fb_res.start + 1; |
674 | if (dp->addrs[i].size >= 0x800000) { | 706 | /* use the big-endian aperture (??) */ |
675 | p->fb_orig_base = addr; | 707 | p->frame_buffer_phys = fb_res.start + 0x800000; |
676 | p->fb_orig_size = dp->addrs[i].size; | 708 | p->control_regs_phys = reg_res.start; |
677 | /* use the big-endian aperture (??) */ | 709 | p->control_regs_size = reg_res.end - reg_res.start + 1; |
678 | p->frame_buffer_phys = addr + 0x800000; | ||
679 | } else { | ||
680 | p->control_regs_phys = addr; | ||
681 | p->control_regs_size = dp->addrs[i].size; | ||
682 | } | ||
683 | } | ||
684 | 710 | ||
685 | if (!p->fb_orig_base || | 711 | if (!p->fb_orig_base || |
686 | !request_mem_region(p->fb_orig_base,p->fb_orig_size,"controlfb")) { | 712 | !request_mem_region(p->fb_orig_base,p->fb_orig_size,"controlfb")) { |
@@ -1059,43 +1085,3 @@ static void control_cleanup(void) | |||
1059 | } | 1085 | } |
1060 | 1086 | ||
1061 | 1087 | ||
1062 | /* | ||
1063 | * Parse user speficied options (`video=controlfb:') | ||
1064 | */ | ||
1065 | void __init control_setup(char *options) | ||
1066 | { | ||
1067 | char *this_opt; | ||
1068 | |||
1069 | if (!options || !*options) | ||
1070 | return; | ||
1071 | |||
1072 | while ((this_opt = strsep(&options, ",")) != NULL) { | ||
1073 | if (!strncmp(this_opt, "vmode:", 6)) { | ||
1074 | int vmode = simple_strtoul(this_opt+6, NULL, 0); | ||
1075 | if (vmode > 0 && vmode <= VMODE_MAX && | ||
1076 | control_mac_modes[vmode - 1].m[1] >= 0) | ||
1077 | default_vmode = vmode; | ||
1078 | } else if (!strncmp(this_opt, "cmode:", 6)) { | ||
1079 | int depth = simple_strtoul(this_opt+6, NULL, 0); | ||
1080 | switch (depth) { | ||
1081 | case CMODE_8: | ||
1082 | case CMODE_16: | ||
1083 | case CMODE_32: | ||
1084 | default_cmode = depth; | ||
1085 | break; | ||
1086 | case 8: | ||
1087 | default_cmode = CMODE_8; | ||
1088 | break; | ||
1089 | case 15: | ||
1090 | case 16: | ||
1091 | default_cmode = CMODE_16; | ||
1092 | break; | ||
1093 | case 24: | ||
1094 | case 32: | ||
1095 | default_cmode = CMODE_32; | ||
1096 | break; | ||
1097 | } | ||
1098 | } | ||
1099 | } | ||
1100 | } | ||
1101 | |||
diff --git a/drivers/video/offb.c b/drivers/video/offb.c index 00d87f5bb7be..ad1434e3f227 100644 --- a/drivers/video/offb.c +++ b/drivers/video/offb.c | |||
@@ -223,6 +223,7 @@ static int offb_blank(int blank, struct fb_info *info) | |||
223 | int __init offb_init(void) | 223 | int __init offb_init(void) |
224 | { | 224 | { |
225 | struct device_node *dp = NULL, *boot_disp = NULL; | 225 | struct device_node *dp = NULL, *boot_disp = NULL; |
226 | |||
226 | #if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) | 227 | #if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) |
227 | struct device_node *macos_display = NULL; | 228 | struct device_node *macos_display = NULL; |
228 | #endif | 229 | #endif |
@@ -234,60 +235,54 @@ int __init offb_init(void) | |||
234 | if (boot_infos != 0) { | 235 | if (boot_infos != 0) { |
235 | unsigned long addr = | 236 | unsigned long addr = |
236 | (unsigned long) boot_infos->dispDeviceBase; | 237 | (unsigned long) boot_infos->dispDeviceBase; |
238 | u32 *addrp; | ||
239 | u64 daddr, dsize; | ||
240 | unsigned int flags; | ||
241 | |||
237 | /* find the device node corresponding to the macos display */ | 242 | /* find the device node corresponding to the macos display */ |
238 | while ((dp = of_find_node_by_type(dp, "display"))) { | 243 | while ((dp = of_find_node_by_type(dp, "display"))) { |
239 | int i; | 244 | int i; |
240 | /* | ||
241 | * Grrr... It looks like the MacOS ATI driver | ||
242 | * munges the assigned-addresses property (but | ||
243 | * the AAPL,address value is OK). | ||
244 | */ | ||
245 | if (strncmp(dp->name, "ATY,", 4) == 0 | ||
246 | && dp->n_addrs == 1) { | ||
247 | unsigned int *ap = | ||
248 | (unsigned int *) get_property(dp, | ||
249 | "AAPL,address", | ||
250 | NULL); | ||
251 | if (ap != NULL) { | ||
252 | dp->addrs[0].address = *ap; | ||
253 | dp->addrs[0].size = 0x01000000; | ||
254 | } | ||
255 | } | ||
256 | 245 | ||
257 | /* | 246 | /* |
258 | * The LTPro on the Lombard powerbook has no addresses | 247 | * Look for an AAPL,address property first. |
259 | * on the display nodes, they are on their parent. | ||
260 | */ | 248 | */ |
261 | if (dp->n_addrs == 0 | 249 | unsigned int na; |
262 | && device_is_compatible(dp, "ATY,264LTPro")) { | 250 | unsigned int *ap = |
263 | int na; | 251 | (unsigned int *)get_property(dp, "AAPL,address", |
264 | unsigned int *ap = (unsigned int *) | 252 | &na); |
265 | get_property(dp, "AAPL,address", &na); | 253 | if (ap != 0) { |
266 | if (ap != 0) | 254 | for (na /= sizeof(unsigned int); na > 0; |
267 | for (na /= sizeof(unsigned int); | 255 | --na, ++ap) |
268 | na > 0; --na, ++ap) | 256 | if (*ap <= addr && |
269 | if (*ap <= addr | 257 | addr < *ap + 0x1000000) { |
270 | && addr < | 258 | macos_display = dp; |
271 | *ap + 0x1000000) | 259 | goto foundit; |
272 | goto foundit; | 260 | } |
273 | } | 261 | } |
274 | 262 | ||
275 | /* | 263 | /* |
276 | * See if the display address is in one of the address | 264 | * See if the display address is in one of the address |
277 | * ranges for this display. | 265 | * ranges for this display. |
278 | */ | 266 | */ |
279 | for (i = 0; i < dp->n_addrs; ++i) { | 267 | i = 0; |
280 | if (dp->addrs[i].address <= addr | 268 | for (;;) { |
281 | && addr < | 269 | addrp = of_get_address(dp, i++, &dsize, &flags); |
282 | dp->addrs[i].address + | 270 | if (addrp == NULL) |
283 | dp->addrs[i].size) | ||
284 | break; | 271 | break; |
272 | if (!(flags & IORESOURCE_MEM)) | ||
273 | continue; | ||
274 | daddr = of_translate_address(dp, addrp); | ||
275 | if (daddr == OF_BAD_ADDR) | ||
276 | continue; | ||
277 | if (daddr <= addr && addr < (daddr + dsize)) { | ||
278 | macos_display = dp; | ||
279 | goto foundit; | ||
280 | } | ||
285 | } | 281 | } |
286 | if (i < dp->n_addrs) { | 282 | foundit: |
287 | foundit: | 283 | if (macos_display) { |
288 | printk(KERN_INFO "MacOS display is %s\n", | 284 | printk(KERN_INFO "MacOS display is %s\n", |
289 | dp->full_name); | 285 | dp->full_name); |
290 | macos_display = dp; | ||
291 | break; | 286 | break; |
292 | } | 287 | } |
293 | } | 288 | } |
@@ -326,8 +321,10 @@ static void __init offb_init_nodriver(struct device_node *dp) | |||
326 | int *pp, i; | 321 | int *pp, i; |
327 | unsigned int len; | 322 | unsigned int len; |
328 | int width = 640, height = 480, depth = 8, pitch; | 323 | int width = 640, height = 480, depth = 8, pitch; |
329 | unsigned int rsize, *up; | 324 | unsigned int flags, rsize, *up; |
330 | unsigned long address = 0; | 325 | u64 address = OF_BAD_ADDR; |
326 | u32 *addrp; | ||
327 | u64 asize; | ||
331 | 328 | ||
332 | if ((pp = (int *) get_property(dp, "depth", &len)) != NULL | 329 | if ((pp = (int *) get_property(dp, "depth", &len)) != NULL |
333 | && len == sizeof(int)) | 330 | && len == sizeof(int)) |
@@ -363,7 +360,7 @@ static void __init offb_init_nodriver(struct device_node *dp) | |||
363 | break; | 360 | break; |
364 | } | 361 | } |
365 | if (pdev) { | 362 | if (pdev) { |
366 | for (i = 0; i < 6 && address == 0; i++) { | 363 | for (i = 0; i < 6 && address == OF_BAD_ADDR; i++) { |
367 | if ((pci_resource_flags(pdev, i) & | 364 | if ((pci_resource_flags(pdev, i) & |
368 | IORESOURCE_MEM) && | 365 | IORESOURCE_MEM) && |
369 | (pci_resource_len(pdev, i) >= rsize)) | 366 | (pci_resource_len(pdev, i) >= rsize)) |
@@ -374,27 +371,33 @@ static void __init offb_init_nodriver(struct device_node *dp) | |||
374 | } | 371 | } |
375 | #endif /* CONFIG_PCI */ | 372 | #endif /* CONFIG_PCI */ |
376 | 373 | ||
377 | if (address == 0 && | 374 | /* This one is dodgy, we may drop it ... */ |
378 | (up = (unsigned *) get_property(dp, "address", &len)) != NULL && | 375 | if (address == OF_BAD_ADDR && |
379 | len == sizeof(unsigned)) | 376 | (up = (unsigned *) get_property(dp, "address", &len)) != NULL && |
380 | address = (u_long) * up; | 377 | len == sizeof(unsigned int)) |
381 | if (address == 0) { | 378 | address = (u64) * up; |
382 | for (i = 0; i < dp->n_addrs; ++i) | 379 | |
383 | if (dp->addrs[i].size >= | 380 | if (address == OF_BAD_ADDR) { |
384 | pitch * height * depth / 8) | 381 | for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags)) |
385 | break; | 382 | != NULL; i++) { |
386 | if (i >= dp->n_addrs) { | 383 | if (!(flags & IORESOURCE_MEM)) |
384 | continue; | ||
385 | if (asize >= pitch * height * depth / 8) | ||
386 | break; | ||
387 | } | ||
388 | if (addrp == NULL) { | ||
387 | printk(KERN_ERR | 389 | printk(KERN_ERR |
388 | "no framebuffer address found for %s\n", | 390 | "no framebuffer address found for %s\n", |
389 | dp->full_name); | 391 | dp->full_name); |
390 | return; | 392 | return; |
391 | } | 393 | } |
392 | 394 | address = of_translate_address(dp, addrp); | |
393 | address = (u_long) dp->addrs[i].address; | 395 | if (address == OF_BAD_ADDR) { |
394 | 396 | printk(KERN_ERR | |
395 | #ifdef CONFIG_PPC64 | 397 | "can't translate framebuffer address for %s\n", |
396 | address += ((struct pci_dn *)dp->data)->phb->pci_mem_offset; | 398 | dp->full_name); |
397 | #endif | 399 | return; |
400 | } | ||
398 | 401 | ||
399 | /* kludge for valkyrie */ | 402 | /* kludge for valkyrie */ |
400 | if (strcmp(dp->name, "valkyrie") == 0) | 403 | if (strcmp(dp->name, "valkyrie") == 0) |
@@ -459,7 +462,9 @@ static void __init offb_init_fb(const char *name, const char *full_name, | |||
459 | 462 | ||
460 | par->cmap_type = cmap_unknown; | 463 | par->cmap_type = cmap_unknown; |
461 | if (depth == 8) { | 464 | if (depth == 8) { |
462 | /* XXX kludge for ati */ | 465 | |
466 | /* Palette hacks disabled for now */ | ||
467 | #if 0 | ||
463 | if (dp && !strncmp(name, "ATY,Rage128", 11)) { | 468 | if (dp && !strncmp(name, "ATY,Rage128", 11)) { |
464 | unsigned long regbase = dp->addrs[2].address; | 469 | unsigned long regbase = dp->addrs[2].address; |
465 | par->cmap_adr = ioremap(regbase, 0x1FFF); | 470 | par->cmap_adr = ioremap(regbase, 0x1FFF); |
@@ -490,6 +495,7 @@ static void __init offb_init_fb(const char *name, const char *full_name, | |||
490 | par->cmap_adr = ioremap(regbase + 0x6000, 0x1000); | 495 | par->cmap_adr = ioremap(regbase + 0x6000, 0x1000); |
491 | par->cmap_type = cmap_gxt2000; | 496 | par->cmap_type = cmap_gxt2000; |
492 | } | 497 | } |
498 | #endif | ||
493 | fix->visual = par->cmap_adr ? FB_VISUAL_PSEUDOCOLOR | 499 | fix->visual = par->cmap_adr ? FB_VISUAL_PSEUDOCOLOR |
494 | : FB_VISUAL_STATIC_PSEUDOCOLOR; | 500 | : FB_VISUAL_STATIC_PSEUDOCOLOR; |
495 | } else | 501 | } else |
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index ba0af1b66bb6..335e37465559 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c | |||
@@ -69,6 +69,8 @@ struct fb_info_platinum { | |||
69 | unsigned long total_vram; | 69 | unsigned long total_vram; |
70 | int clktype; | 70 | int clktype; |
71 | int dactype; | 71 | int dactype; |
72 | |||
73 | struct resource rsrc_fb, rsrc_reg; | ||
72 | }; | 74 | }; |
73 | 75 | ||
74 | /* | 76 | /* |
@@ -97,9 +99,6 @@ static int platinum_var_to_par(struct fb_var_screeninfo *var, | |||
97 | * Interface used by the world | 99 | * Interface used by the world |
98 | */ | 100 | */ |
99 | 101 | ||
100 | int platinumfb_init(void); | ||
101 | int platinumfb_setup(char*); | ||
102 | |||
103 | static struct fb_ops platinumfb_ops = { | 102 | static struct fb_ops platinumfb_ops = { |
104 | .owner = THIS_MODULE, | 103 | .owner = THIS_MODULE, |
105 | .fb_check_var = platinumfb_check_var, | 104 | .fb_check_var = platinumfb_check_var, |
@@ -485,7 +484,7 @@ static int platinum_var_to_par(struct fb_var_screeninfo *var, | |||
485 | /* | 484 | /* |
486 | * Parse user speficied options (`video=platinumfb:') | 485 | * Parse user speficied options (`video=platinumfb:') |
487 | */ | 486 | */ |
488 | int __init platinumfb_setup(char *options) | 487 | static int __init platinumfb_setup(char *options) |
489 | { | 488 | { |
490 | char *this_opt; | 489 | char *this_opt; |
491 | 490 | ||
@@ -526,19 +525,15 @@ int __init platinumfb_setup(char *options) | |||
526 | #define invalidate_cache(addr) | 525 | #define invalidate_cache(addr) |
527 | #endif | 526 | #endif |
528 | 527 | ||
529 | static int __devinit platinumfb_probe(struct of_device* odev, const struct of_device_id *match) | 528 | static int __devinit platinumfb_probe(struct of_device* odev, |
529 | const struct of_device_id *match) | ||
530 | { | 530 | { |
531 | struct device_node *dp = odev->node; | 531 | struct device_node *dp = odev->node; |
532 | struct fb_info *info; | 532 | struct fb_info *info; |
533 | struct fb_info_platinum *pinfo; | 533 | struct fb_info_platinum *pinfo; |
534 | unsigned long addr, size; | ||
535 | volatile __u8 *fbuffer; | 534 | volatile __u8 *fbuffer; |
536 | int i, bank0, bank1, bank2, bank3, rc; | 535 | int bank0, bank1, bank2, bank3, rc; |
537 | 536 | ||
538 | if (dp->n_addrs != 2) { | ||
539 | printk(KERN_ERR "expecting 2 address for platinum (got %d)", dp->n_addrs); | ||
540 | return -ENXIO; | ||
541 | } | ||
542 | printk(KERN_INFO "platinumfb: Found Apple Platinum video hardware\n"); | 537 | printk(KERN_INFO "platinumfb: Found Apple Platinum video hardware\n"); |
543 | 538 | ||
544 | info = framebuffer_alloc(sizeof(*pinfo), &odev->dev); | 539 | info = framebuffer_alloc(sizeof(*pinfo), &odev->dev); |
@@ -546,26 +541,39 @@ static int __devinit platinumfb_probe(struct of_device* odev, const struct of_de | |||
546 | return -ENOMEM; | 541 | return -ENOMEM; |
547 | pinfo = info->par; | 542 | pinfo = info->par; |
548 | 543 | ||
549 | /* Map in frame buffer and registers */ | 544 | if (of_address_to_resource(dp, 0, &pinfo->rsrc_reg) || |
550 | for (i = 0; i < dp->n_addrs; ++i) { | 545 | of_address_to_resource(dp, 1, &pinfo->rsrc_fb)) { |
551 | addr = dp->addrs[i].address; | 546 | printk(KERN_ERR "platinumfb: Can't get resources\n"); |
552 | size = dp->addrs[i].size; | 547 | framebuffer_release(info); |
553 | /* Let's assume we can request either all or nothing */ | 548 | return -ENXIO; |
554 | if (!request_mem_region(addr, size, "platinumfb")) { | ||
555 | framebuffer_release(info); | ||
556 | return -ENXIO; | ||
557 | } | ||
558 | if (size >= 0x400000) { | ||
559 | /* frame buffer - map only 4MB */ | ||
560 | pinfo->frame_buffer_phys = addr; | ||
561 | pinfo->frame_buffer = __ioremap(addr, 0x400000, _PAGE_WRITETHRU); | ||
562 | pinfo->base_frame_buffer = pinfo->frame_buffer; | ||
563 | } else { | ||
564 | /* registers */ | ||
565 | pinfo->platinum_regs_phys = addr; | ||
566 | pinfo->platinum_regs = ioremap(addr, size); | ||
567 | } | ||
568 | } | 549 | } |
550 | if (!request_mem_region(pinfo->rsrc_reg.start, | ||
551 | pinfo->rsrc_reg.start - | ||
552 | pinfo->rsrc_reg.end + 1, | ||
553 | "platinumfb registers")) { | ||
554 | framebuffer_release(info); | ||
555 | return -ENXIO; | ||
556 | } | ||
557 | if (!request_mem_region(pinfo->rsrc_fb.start, | ||
558 | pinfo->rsrc_fb.start | ||
559 | - pinfo->rsrc_fb.end + 1, | ||
560 | "platinumfb framebuffer")) { | ||
561 | release_mem_region(pinfo->rsrc_reg.start, | ||
562 | pinfo->rsrc_reg.end - | ||
563 | pinfo->rsrc_reg.start + 1); | ||
564 | framebuffer_release(info); | ||
565 | return -ENXIO; | ||
566 | } | ||
567 | |||
568 | /* frame buffer - map only 4MB */ | ||
569 | pinfo->frame_buffer_phys = pinfo->rsrc_fb.start; | ||
570 | pinfo->frame_buffer = __ioremap(pinfo->rsrc_fb.start, 0x400000, | ||
571 | _PAGE_WRITETHRU); | ||
572 | pinfo->base_frame_buffer = pinfo->frame_buffer; | ||
573 | |||
574 | /* registers */ | ||
575 | pinfo->platinum_regs_phys = pinfo->rsrc_reg.start; | ||
576 | pinfo->platinum_regs = ioremap(pinfo->rsrc_reg.start, 0x1000); | ||
569 | 577 | ||
570 | pinfo->cmap_regs_phys = 0xf301b000; /* XXX not in prom? */ | 578 | pinfo->cmap_regs_phys = 0xf301b000; /* XXX not in prom? */ |
571 | request_mem_region(pinfo->cmap_regs_phys, 0x1000, "platinumfb cmap"); | 579 | request_mem_region(pinfo->cmap_regs_phys, 0x1000, "platinumfb cmap"); |
@@ -628,18 +636,16 @@ static int __devexit platinumfb_remove(struct of_device* odev) | |||
628 | { | 636 | { |
629 | struct fb_info *info = dev_get_drvdata(&odev->dev); | 637 | struct fb_info *info = dev_get_drvdata(&odev->dev); |
630 | struct fb_info_platinum *pinfo = info->par; | 638 | struct fb_info_platinum *pinfo = info->par; |
631 | struct device_node *dp = odev->node; | ||
632 | unsigned long addr, size; | ||
633 | int i; | ||
634 | 639 | ||
635 | unregister_framebuffer (info); | 640 | unregister_framebuffer (info); |
636 | 641 | ||
637 | /* Unmap frame buffer and registers */ | 642 | /* Unmap frame buffer and registers */ |
638 | for (i = 0; i < dp->n_addrs; ++i) { | 643 | release_mem_region(pinfo->rsrc_fb.start, |
639 | addr = dp->addrs[i].address; | 644 | pinfo->rsrc_fb.end - |
640 | size = dp->addrs[i].size; | 645 | pinfo->rsrc_fb.start + 1); |
641 | release_mem_region(addr, size); | 646 | release_mem_region(pinfo->rsrc_reg.start, |
642 | } | 647 | pinfo->rsrc_reg.end - |
648 | pinfo->rsrc_reg.start + 1); | ||
643 | iounmap(pinfo->frame_buffer); | 649 | iounmap(pinfo->frame_buffer); |
644 | iounmap(pinfo->platinum_regs); | 650 | iounmap(pinfo->platinum_regs); |
645 | release_mem_region(pinfo->cmap_regs_phys, 0x1000); | 651 | release_mem_region(pinfo->cmap_regs_phys, 0x1000); |
@@ -666,7 +672,7 @@ static struct of_platform_driver platinum_driver = | |||
666 | .remove = platinumfb_remove, | 672 | .remove = platinumfb_remove, |
667 | }; | 673 | }; |
668 | 674 | ||
669 | int __init platinumfb_init(void) | 675 | static int __init platinumfb_init(void) |
670 | { | 676 | { |
671 | #ifndef MODULE | 677 | #ifndef MODULE |
672 | char *option = NULL; | 678 | char *option = NULL; |
@@ -680,7 +686,7 @@ int __init platinumfb_init(void) | |||
680 | return 0; | 686 | return 0; |
681 | } | 687 | } |
682 | 688 | ||
683 | void __exit platinumfb_exit(void) | 689 | static void __exit platinumfb_exit(void) |
684 | { | 690 | { |
685 | of_unregister_driver(&platinum_driver); | 691 | of_unregister_driver(&platinum_driver); |
686 | } | 692 | } |
diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c index ce97ec8eae97..2bdeb4baa952 100644 --- a/drivers/video/valkyriefb.c +++ b/drivers/video/valkyriefb.c | |||
@@ -342,19 +342,19 @@ int __init valkyriefb_init(void) | |||
342 | #else /* ppc (!CONFIG_MAC) */ | 342 | #else /* ppc (!CONFIG_MAC) */ |
343 | { | 343 | { |
344 | struct device_node *dp; | 344 | struct device_node *dp; |
345 | struct resource r; | ||
345 | 346 | ||
346 | dp = find_devices("valkyrie"); | 347 | dp = of_find_node_by_name(NULL, "valkyrie"); |
347 | if (dp == 0) | 348 | if (dp == 0) |
348 | return 0; | 349 | return 0; |
349 | 350 | ||
350 | if (dp->n_addrs != 1) { | 351 | if (of_address_to_resource(dp, 0, &r)) { |
351 | printk(KERN_ERR "expecting 1 address for valkyrie (got %d)\n", | 352 | printk(KERN_ERR "can't find address for valkyrie\n"); |
352 | dp->n_addrs); | ||
353 | return 0; | 353 | return 0; |
354 | } | 354 | } |
355 | 355 | ||
356 | frame_buffer_phys = dp->addrs[0].address; | 356 | frame_buffer_phys = r.start; |
357 | cmap_regs_phys = dp->addrs[0].address+0x304000; | 357 | cmap_regs_phys = r.start + 0x304000; |
358 | flags = _PAGE_WRITETHRU; | 358 | flags = _PAGE_WRITETHRU; |
359 | } | 359 | } |
360 | #endif /* ppc (!CONFIG_MAC) */ | 360 | #endif /* ppc (!CONFIG_MAC) */ |
diff --git a/include/asm-powerpc/keylargo.h b/include/asm-powerpc/keylargo.h index a669a3f0f5a2..334d4c9356f3 100644 --- a/include/asm-powerpc/keylargo.h +++ b/include/asm-powerpc/keylargo.h | |||
@@ -232,10 +232,12 @@ | |||
232 | #define K2_FCR1_I2S0_RESET 0x00000800 | 232 | #define K2_FCR1_I2S0_RESET 0x00000800 |
233 | #define K2_FCR1_I2S0_CLK_ENABLE_BIT 0x00001000 | 233 | #define K2_FCR1_I2S0_CLK_ENABLE_BIT 0x00001000 |
234 | #define K2_FCR1_I2S0_ENABLE 0x00002000 | 234 | #define K2_FCR1_I2S0_ENABLE 0x00002000 |
235 | |||
236 | #define K2_FCR1_PCI1_CLK_ENABLE 0x00004000 | 235 | #define K2_FCR1_PCI1_CLK_ENABLE 0x00004000 |
237 | #define K2_FCR1_FW_CLK_ENABLE 0x00008000 | 236 | #define K2_FCR1_FW_CLK_ENABLE 0x00008000 |
238 | #define K2_FCR1_FW_RESET_N 0x00010000 | 237 | #define K2_FCR1_FW_RESET_N 0x00010000 |
238 | #define K2_FCR1_I2S1_CELL_ENABLE 0x00020000 | ||
239 | #define K2_FCR1_I2S1_CLK_ENABLE_BIT 0x00080000 | ||
240 | #define K2_FCR1_I2S1_ENABLE 0x00100000 | ||
239 | #define K2_FCR1_GMAC_CLK_ENABLE 0x00400000 | 241 | #define K2_FCR1_GMAC_CLK_ENABLE 0x00400000 |
240 | #define K2_FCR1_GMAC_POWER_DOWN 0x00800000 | 242 | #define K2_FCR1_GMAC_POWER_DOWN 0x00800000 |
241 | #define K2_FCR1_GMAC_RESET_N 0x01000000 | 243 | #define K2_FCR1_GMAC_RESET_N 0x01000000 |
@@ -246,3 +248,9 @@ | |||
246 | #define K2_FCR1_UATA_RESET_N 0x40000000 | 248 | #define K2_FCR1_UATA_RESET_N 0x40000000 |
247 | #define K2_FCR1_UATA_CHOOSE_CLK66 0x80000000 | 249 | #define K2_FCR1_UATA_CHOOSE_CLK66 0x80000000 |
248 | 250 | ||
251 | /* Shasta definitions */ | ||
252 | #define SH_FCR1_I2S2_CELL_ENABLE 0x00000010 | ||
253 | #define SH_FCR1_I2S2_CLK_ENABLE_BIT 0x00000040 | ||
254 | #define SH_FCR1_I2S2_ENABLE 0x00000080 | ||
255 | #define SH_FCR3_I2S2_CLK18_ENABLE 0x00008000 | ||
256 | |||
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h index 73d27bad55fa..329e9bf62260 100644 --- a/include/asm-powerpc/prom.h +++ b/include/asm-powerpc/prom.h | |||
@@ -65,49 +65,11 @@ struct boot_param_header | |||
65 | typedef u32 phandle; | 65 | typedef u32 phandle; |
66 | typedef u32 ihandle; | 66 | typedef u32 ihandle; |
67 | 67 | ||
68 | struct address_range { | ||
69 | unsigned long space; | ||
70 | unsigned long address; | ||
71 | unsigned long size; | ||
72 | }; | ||
73 | |||
74 | struct interrupt_info { | 68 | struct interrupt_info { |
75 | int line; | 69 | int line; |
76 | int sense; /* +ve/-ve logic, edge or level, etc. */ | 70 | int sense; /* +ve/-ve logic, edge or level, etc. */ |
77 | }; | 71 | }; |
78 | 72 | ||
79 | struct pci_address { | ||
80 | u32 a_hi; | ||
81 | u32 a_mid; | ||
82 | u32 a_lo; | ||
83 | }; | ||
84 | |||
85 | struct isa_address { | ||
86 | u32 a_hi; | ||
87 | u32 a_lo; | ||
88 | }; | ||
89 | |||
90 | struct isa_range { | ||
91 | struct isa_address isa_addr; | ||
92 | struct pci_address pci_addr; | ||
93 | unsigned int size; | ||
94 | }; | ||
95 | |||
96 | struct reg_property { | ||
97 | unsigned long address; | ||
98 | unsigned long size; | ||
99 | }; | ||
100 | |||
101 | struct reg_property32 { | ||
102 | unsigned int address; | ||
103 | unsigned int size; | ||
104 | }; | ||
105 | |||
106 | struct reg_property64 { | ||
107 | u64 address; | ||
108 | u64 size; | ||
109 | }; | ||
110 | |||
111 | struct property { | 73 | struct property { |
112 | char *name; | 74 | char *name; |
113 | int length; | 75 | int length; |
@@ -120,8 +82,6 @@ struct device_node { | |||
120 | char *type; | 82 | char *type; |
121 | phandle node; | 83 | phandle node; |
122 | phandle linux_phandle; | 84 | phandle linux_phandle; |
123 | int n_addrs; | ||
124 | struct address_range *addrs; | ||
125 | int n_intrs; | 85 | int n_intrs; |
126 | struct interrupt_info *intrs; | 86 | struct interrupt_info *intrs; |
127 | char *full_name; | 87 | char *full_name; |
diff --git a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c index cebd881b91ae..74f975676ccb 100644 --- a/sound/oss/dmasound/dmasound_awacs.c +++ b/sound/oss/dmasound/dmasound_awacs.c | |||
@@ -125,6 +125,7 @@ static int awacs_rate_index; | |||
125 | static int awacs_subframe; | 125 | static int awacs_subframe; |
126 | static struct device_node* awacs_node; | 126 | static struct device_node* awacs_node; |
127 | static struct device_node* i2s_node; | 127 | static struct device_node* i2s_node; |
128 | static struct resource awacs_rsrc[3]; | ||
128 | 129 | ||
129 | static char awacs_name[64]; | 130 | static char awacs_name[64]; |
130 | static int awacs_revision; | 131 | static int awacs_revision; |
@@ -667,9 +668,12 @@ static void PMacIrqCleanup(void) | |||
667 | iounmap(awacs_txdma); | 668 | iounmap(awacs_txdma); |
668 | iounmap(awacs_rxdma); | 669 | iounmap(awacs_rxdma); |
669 | 670 | ||
670 | release_OF_resource(awacs_node, 0); | 671 | release_mem_region(awacs_rsrc[0].start, |
671 | release_OF_resource(awacs_node, 1); | 672 | awacs_rsrc[0].end - awacs_rsrc[0].start + 1); |
672 | release_OF_resource(awacs_node, 2); | 673 | release_mem_region(awacs_rsrc[1].start, |
674 | awacs_rsrc[1].end - awacs_rsrc[1].start + 1); | ||
675 | release_mem_region(awacs_rsrc[2].start, | ||
676 | awacs_rsrc[2].end - awacs_rsrc[2].start + 1); | ||
673 | 677 | ||
674 | kfree(awacs_tx_cmd_space); | 678 | kfree(awacs_tx_cmd_space); |
675 | kfree(awacs_rx_cmd_space); | 679 | kfree(awacs_rx_cmd_space); |
@@ -2863,46 +2867,58 @@ printk("dmasound_pmac: couldn't find a Codec we can handle\n"); | |||
2863 | * other info if necessary (early AWACS we want to read chip ids) | 2867 | * other info if necessary (early AWACS we want to read chip ids) |
2864 | */ | 2868 | */ |
2865 | 2869 | ||
2866 | if (io->n_addrs < 3 || io->n_intrs < 3) { | 2870 | if (of_get_address(io, 2, NULL, NULL) == NULL || io->n_intrs < 3) { |
2867 | /* OK - maybe we need to use the 'awacs' node (on earlier | 2871 | /* OK - maybe we need to use the 'awacs' node (on earlier |
2868 | * machines). | 2872 | * machines). |
2869 | */ | 2873 | */ |
2870 | if (awacs_node) { | 2874 | if (awacs_node) { |
2871 | io = awacs_node ; | 2875 | io = awacs_node ; |
2872 | if (io->n_addrs < 3 || io->n_intrs < 3) { | 2876 | if (of_get_address(io, 2, NULL, NULL) == NULL || |
2873 | printk("dmasound_pmac: can't use %s" | 2877 | io->n_intrs < 3) { |
2874 | " (%d addrs, %d intrs)\n", | 2878 | printk("dmasound_pmac: can't use %s\n", |
2875 | io->full_name, io->n_addrs, io->n_intrs); | 2879 | io->full_name); |
2876 | return -ENODEV; | 2880 | return -ENODEV; |
2877 | } | 2881 | } |
2878 | } else { | 2882 | } else |
2879 | printk("dmasound_pmac: can't use %s (%d addrs, %d intrs)\n", | 2883 | printk("dmasound_pmac: can't use %s\n", io->full_name); |
2880 | io->full_name, io->n_addrs, io->n_intrs); | ||
2881 | } | ||
2882 | } | 2884 | } |
2883 | 2885 | ||
2884 | if (!request_OF_resource(io, 0, NULL)) { | 2886 | if (of_address_to_resource(io, 0, &awacs_rsrc[0]) || |
2887 | request_mem_region(awacs_rsrc[0].start, | ||
2888 | awacs_rsrc[0].end - awacs_rsrc[0].start + 1, | ||
2889 | " (IO)") == NULL) { | ||
2885 | printk(KERN_ERR "dmasound: can't request IO resource !\n"); | 2890 | printk(KERN_ERR "dmasound: can't request IO resource !\n"); |
2886 | return -ENODEV; | 2891 | return -ENODEV; |
2887 | } | 2892 | } |
2888 | if (!request_OF_resource(io, 1, " (tx dma)")) { | 2893 | if (of_address_to_resource(io, 1, &awacs_rsrc[1]) || |
2889 | release_OF_resource(io, 0); | 2894 | request_mem_region(awacs_rsrc[1].start, |
2890 | printk(KERN_ERR "dmasound: can't request TX DMA resource !\n"); | 2895 | awacs_rsrc[1].end - awacs_rsrc[1].start + 1, |
2896 | " (tx dma)") == NULL) { | ||
2897 | release_mem_region(awacs_rsrc[0].start, | ||
2898 | awacs_rsrc[0].end - awacs_rsrc[0].start + 1); | ||
2899 | printk(KERN_ERR "dmasound: can't request Tx DMA resource !\n"); | ||
2891 | return -ENODEV; | 2900 | return -ENODEV; |
2892 | } | 2901 | } |
2893 | 2902 | if (of_address_to_resource(io, 2, &awacs_rsrc[2]) || | |
2894 | if (!request_OF_resource(io, 2, " (rx dma)")) { | 2903 | request_mem_region(awacs_rsrc[2].start, |
2895 | release_OF_resource(io, 0); | 2904 | awacs_rsrc[2].end - awacs_rsrc[2].start + 1, |
2896 | release_OF_resource(io, 1); | 2905 | " (rx dma)") == NULL) { |
2897 | printk(KERN_ERR "dmasound: can't request RX DMA resource !\n"); | 2906 | release_mem_region(awacs_rsrc[0].start, |
2907 | awacs_rsrc[0].end - awacs_rsrc[0].start + 1); | ||
2908 | release_mem_region(awacs_rsrc[1].start, | ||
2909 | awacs_rsrc[1].end - awacs_rsrc[1].start + 1); | ||
2910 | printk(KERN_ERR "dmasound: can't request Rx DMA resource !\n"); | ||
2898 | return -ENODEV; | 2911 | return -ENODEV; |
2899 | } | 2912 | } |
2900 | 2913 | ||
2901 | awacs_beep_dev = input_allocate_device(); | 2914 | awacs_beep_dev = input_allocate_device(); |
2902 | if (!awacs_beep_dev) { | 2915 | if (!awacs_beep_dev) { |
2903 | release_OF_resource(io, 0); | 2916 | release_mem_region(awacs_rsrc[0].start, |
2904 | release_OF_resource(io, 1); | 2917 | awacs_rsrc[0].end - awacs_rsrc[0].start + 1); |
2905 | release_OF_resource(io, 2); | 2918 | release_mem_region(awacs_rsrc[1].start, |
2919 | awacs_rsrc[1].end - awacs_rsrc[1].start + 1); | ||
2920 | release_mem_region(awacs_rsrc[2].start, | ||
2921 | awacs_rsrc[2].end - awacs_rsrc[2].start + 1); | ||
2906 | printk(KERN_ERR "dmasound: can't allocate input device !\n"); | 2922 | printk(KERN_ERR "dmasound: can't allocate input device !\n"); |
2907 | return -ENOMEM; | 2923 | return -ENOMEM; |
2908 | } | 2924 | } |
@@ -2916,11 +2932,11 @@ printk("dmasound_pmac: couldn't find a Codec we can handle\n"); | |||
2916 | 2932 | ||
2917 | /* all OF versions I've seen use this value */ | 2933 | /* all OF versions I've seen use this value */ |
2918 | if (i2s_node) | 2934 | if (i2s_node) |
2919 | i2s = ioremap(io->addrs[0].address, 0x1000); | 2935 | i2s = ioremap(awacs_rsrc[0].start, 0x1000); |
2920 | else | 2936 | else |
2921 | awacs = ioremap(io->addrs[0].address, 0x1000); | 2937 | awacs = ioremap(awacs_rsrc[0].start, 0x1000); |
2922 | awacs_txdma = ioremap(io->addrs[1].address, 0x100); | 2938 | awacs_txdma = ioremap(awacs_rsrc[1].start, 0x100); |
2923 | awacs_rxdma = ioremap(io->addrs[2].address, 0x100); | 2939 | awacs_rxdma = ioremap(awacs_rsrc[2].start, 0x100); |
2924 | 2940 | ||
2925 | /* first of all make sure that the chip is powered up....*/ | 2941 | /* first of all make sure that the chip is powered up....*/ |
2926 | pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, io, 0, 1); | 2942 | pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, io, 0, 1); |
@@ -3083,9 +3099,10 @@ printk("dmasound_pmac: Awacs/Screamer Codec Mfct: %d Rev %d\n", mfg, rev); | |||
3083 | struct device_node* mio; | 3099 | struct device_node* mio; |
3084 | macio_base = NULL; | 3100 | macio_base = NULL; |
3085 | for (mio = io->parent; mio; mio = mio->parent) { | 3101 | for (mio = io->parent; mio; mio = mio->parent) { |
3086 | if (strcmp(mio->name, "mac-io") == 0 | 3102 | if (strcmp(mio->name, "mac-io") == 0) { |
3087 | && mio->n_addrs > 0) { | 3103 | struct resource r; |
3088 | macio_base = ioremap(mio->addrs[0].address, 0x40); | 3104 | if (of_address_to_resource(mio, 0, &r) == 0) |
3105 | macio_base = ioremap(r.start, 0x40); | ||
3089 | break; | 3106 | break; |
3090 | } | 3107 | } |
3091 | } | 3108 | } |
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index 9b2b00fdc1ae..a642e4cfcf45 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c | |||
@@ -803,21 +803,17 @@ static int snd_pmac_free(struct snd_pmac *chip) | |||
803 | iounmap(chip->playback.dma); | 803 | iounmap(chip->playback.dma); |
804 | if (chip->capture.dma) | 804 | if (chip->capture.dma) |
805 | iounmap(chip->capture.dma); | 805 | iounmap(chip->capture.dma); |
806 | #ifndef CONFIG_PPC64 | 806 | |
807 | if (chip->node) { | 807 | if (chip->node) { |
808 | int i; | 808 | int i; |
809 | |||
810 | for (i = 0; i < 3; i++) { | 809 | for (i = 0; i < 3; i++) { |
811 | if (chip->of_requested & (1 << i)) { | 810 | if (chip->requested & (1 << i)) |
812 | if (chip->is_k2) | 811 | release_mem_region(chip->rsrc[i].start, |
813 | release_OF_resource(chip->node->parent, | 812 | chip->rsrc[i].end - |
814 | i); | 813 | chip->rsrc[i].start + 1); |
815 | else | ||
816 | release_OF_resource(chip->node, i); | ||
817 | } | ||
818 | } | 814 | } |
819 | } | 815 | } |
820 | #endif /* CONFIG_PPC64 */ | 816 | |
821 | if (chip->pdev) | 817 | if (chip->pdev) |
822 | pci_dev_put(chip->pdev); | 818 | pci_dev_put(chip->pdev); |
823 | kfree(chip); | 819 | kfree(chip); |
@@ -991,6 +987,11 @@ static int __init snd_pmac_detect(struct snd_pmac *chip) | |||
991 | chip->can_byte_swap = 0; /* FIXME: check this */ | 987 | chip->can_byte_swap = 0; /* FIXME: check this */ |
992 | chip->control_mask = MASK_IEPC | 0x11;/* disable IEE */ | 988 | chip->control_mask = MASK_IEPC | 0x11;/* disable IEE */ |
993 | break; | 989 | break; |
990 | default: | ||
991 | printk(KERN_ERR "snd: Unknown layout ID 0x%x\n", | ||
992 | layout_id); | ||
993 | return -ENODEV; | ||
994 | |||
994 | } | 995 | } |
995 | } | 996 | } |
996 | prop = (unsigned int *)get_property(sound, "device-id", NULL); | 997 | prop = (unsigned int *)get_property(sound, "device-id", NULL); |
@@ -1175,46 +1176,69 @@ int __init snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return) | |||
1175 | } | 1176 | } |
1176 | 1177 | ||
1177 | np = chip->node; | 1178 | np = chip->node; |
1179 | chip->requested = 0; | ||
1178 | if (chip->is_k2) { | 1180 | if (chip->is_k2) { |
1179 | if (np->parent->n_addrs < 2 || np->n_intrs < 3) { | 1181 | static char *rnames[] = { |
1182 | "Sound Control", "Sound DMA" }; | ||
1183 | if (np->n_intrs < 3) { | ||
1180 | err = -ENODEV; | 1184 | err = -ENODEV; |
1181 | goto __error; | 1185 | goto __error; |
1182 | } | 1186 | } |
1183 | for (i = 0; i < 2; i++) { | 1187 | for (i = 0; i < 2; i ++) { |
1184 | #ifndef CONFIG_PPC64 | 1188 | if (of_address_to_resource(np->parent, i, |
1185 | static char *name[2] = { "- Control", "- DMA" }; | 1189 | &chip->rsrc[i])) { |
1186 | if (! request_OF_resource(np->parent, i, name[i])) { | 1190 | printk(KERN_ERR "snd: can't translate rsrc " |
1187 | snd_printk(KERN_ERR "pmac: can't request resource %d!\n", i); | 1191 | " %d (%s)\n", i, rnames[i]); |
1192 | err = -ENODEV; | ||
1193 | goto __error; | ||
1194 | } | ||
1195 | if (request_mem_region(chip->rsrc[i].start, | ||
1196 | chip->rsrc[i].end - | ||
1197 | chip->rsrc[i].start + 1, | ||
1198 | rnames[i]) == NULL) { | ||
1199 | printk(KERN_ERR "snd: can't request rsrc " | ||
1200 | " %d (%s: 0x%08lx:%08lx)\n", | ||
1201 | i, rnames[i], chip->rsrc[i].start, | ||
1202 | chip->rsrc[i].end); | ||
1188 | err = -ENODEV; | 1203 | err = -ENODEV; |
1189 | goto __error; | 1204 | goto __error; |
1190 | } | 1205 | } |
1191 | chip->of_requested |= (1 << i); | 1206 | chip->requested |= (1 << i); |
1192 | #endif /* CONFIG_PPC64 */ | ||
1193 | ctrl_addr = np->parent->addrs[0].address; | ||
1194 | txdma_addr = np->parent->addrs[1].address; | ||
1195 | rxdma_addr = txdma_addr + 0x100; | ||
1196 | } | 1207 | } |
1197 | 1208 | ctrl_addr = chip->rsrc[0].start; | |
1209 | txdma_addr = chip->rsrc[1].start; | ||
1210 | rxdma_addr = txdma_addr + 0x100; | ||
1198 | } else { | 1211 | } else { |
1199 | if (np->n_addrs < 3 || np->n_intrs < 3) { | 1212 | static char *rnames[] = { |
1213 | "Sound Control", "Sound Tx DMA", "Sound Rx DMA" }; | ||
1214 | if (np->n_intrs < 3) { | ||
1200 | err = -ENODEV; | 1215 | err = -ENODEV; |
1201 | goto __error; | 1216 | goto __error; |
1202 | } | 1217 | } |
1203 | 1218 | for (i = 0; i < 3; i ++) { | |
1204 | for (i = 0; i < 3; i++) { | 1219 | if (of_address_to_resource(np->parent, i, |
1205 | #ifndef CONFIG_PPC64 | 1220 | &chip->rsrc[i])) { |
1206 | static char *name[3] = { "- Control", "- Tx DMA", "- Rx DMA" }; | 1221 | printk(KERN_ERR "snd: can't translate rsrc " |
1207 | if (! request_OF_resource(np, i, name[i])) { | 1222 | " %d (%s)\n", i, rnames[i]); |
1208 | snd_printk(KERN_ERR "pmac: can't request resource %d!\n", i); | 1223 | err = -ENODEV; |
1224 | goto __error; | ||
1225 | } | ||
1226 | if (request_mem_region(chip->rsrc[i].start, | ||
1227 | chip->rsrc[i].end - | ||
1228 | chip->rsrc[i].start + 1, | ||
1229 | rnames[i]) == NULL) { | ||
1230 | printk(KERN_ERR "snd: can't request rsrc " | ||
1231 | " %d (%s: 0x%08lx:%08lx)\n", | ||
1232 | i, rnames[i], chip->rsrc[i].start, | ||
1233 | chip->rsrc[i].end); | ||
1209 | err = -ENODEV; | 1234 | err = -ENODEV; |
1210 | goto __error; | 1235 | goto __error; |
1211 | } | 1236 | } |
1212 | chip->of_requested |= (1 << i); | 1237 | chip->requested |= (1 << i); |
1213 | #endif /* CONFIG_PPC64 */ | ||
1214 | ctrl_addr = np->addrs[0].address; | ||
1215 | txdma_addr = np->addrs[1].address; | ||
1216 | rxdma_addr = np->addrs[2].address; | ||
1217 | } | 1238 | } |
1239 | ctrl_addr = chip->rsrc[0].start; | ||
1240 | txdma_addr = chip->rsrc[1].start; | ||
1241 | rxdma_addr = chip->rsrc[2].start; | ||
1218 | } | 1242 | } |
1219 | 1243 | ||
1220 | chip->awacs = ioremap(ctrl_addr, 0x1000); | 1244 | chip->awacs = ioremap(ctrl_addr, 0x1000); |
@@ -1266,9 +1290,11 @@ int __init snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return) | |||
1266 | } else if (chip->is_pbook_G3) { | 1290 | } else if (chip->is_pbook_G3) { |
1267 | struct device_node* mio; | 1291 | struct device_node* mio; |
1268 | for (mio = chip->node->parent; mio; mio = mio->parent) { | 1292 | for (mio = chip->node->parent; mio; mio = mio->parent) { |
1269 | if (strcmp(mio->name, "mac-io") == 0 | 1293 | if (strcmp(mio->name, "mac-io") == 0) { |
1270 | && mio->n_addrs > 0) { | 1294 | struct resource r; |
1271 | chip->macio_base = ioremap(mio->addrs[0].address, 0x40); | 1295 | if (of_address_to_resource(mio, 0, &r) == 0) |
1296 | chip->macio_base = | ||
1297 | ioremap(r.start, 0x40); | ||
1272 | break; | 1298 | break; |
1273 | } | 1299 | } |
1274 | } | 1300 | } |
diff --git a/sound/ppc/pmac.h b/sound/ppc/pmac.h index 086da7a18909..3a9bd4dbb9a6 100644 --- a/sound/ppc/pmac.h +++ b/sound/ppc/pmac.h | |||
@@ -113,7 +113,8 @@ struct snd_pmac { | |||
113 | unsigned int initialized : 1; | 113 | unsigned int initialized : 1; |
114 | unsigned int feature_is_set : 1; | 114 | unsigned int feature_is_set : 1; |
115 | 115 | ||
116 | unsigned int of_requested; | 116 | unsigned int requested; |
117 | struct resource rsrc[3]; | ||
117 | 118 | ||
118 | int num_freqs; | 119 | int num_freqs; |
119 | int *freq_table; | 120 | int *freq_table; |