diff options
author | Paul Mackerras <paulus@samba.org> | 2005-10-10 08:58:41 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2005-10-10 08:58:41 -0400 |
commit | 3c3f42d63a11f2e22dbff6bb4d170f92dbd39316 (patch) | |
tree | 2619d63e6d49480b55de02044a75f8c843dbd811 /arch/powerpc | |
parent | e574d238ab907963ae6f97cb6bf12bb8fd48c376 (diff) |
powerpc: Start merging 64-bit support into powermac files
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/platforms/powermac/pci.c | 194 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/pic.c | 32 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/pmac.h | 25 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/setup.c | 20 |
4 files changed, 128 insertions, 143 deletions
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 40bcd3e55afb..afb147e6b89f 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c | |||
@@ -1,8 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Support for PCI bridges found on Power Macintoshes. | 2 | * Support for PCI bridges found on Power Macintoshes. |
3 | * At present the "bandit" and "chaos" bridges are supported. | ||
4 | * Fortunately you access configuration space in the same | ||
5 | * way with either bridge. | ||
6 | * | 3 | * |
7 | * Copyright (C) 2003 Benjamin Herrenschmuidt (benh@kernel.crashing.org) | 4 | * Copyright (C) 2003 Benjamin Herrenschmuidt (benh@kernel.crashing.org) |
8 | * Copyright (C) 1997 Paul Mackerras (paulus@samba.org) | 5 | * Copyright (C) 1997 Paul Mackerras (paulus@samba.org) |
@@ -26,6 +23,10 @@ | |||
26 | #include <asm/pci-bridge.h> | 23 | #include <asm/pci-bridge.h> |
27 | #include <asm/machdep.h> | 24 | #include <asm/machdep.h> |
28 | #include <asm/pmac_feature.h> | 25 | #include <asm/pmac_feature.h> |
26 | #ifdef CONFIG_PPC64 | ||
27 | #include <asm/iommu.h> | ||
28 | #include <asm/ppc-pci.h> | ||
29 | #endif | ||
29 | 30 | ||
30 | #undef DEBUG | 31 | #undef DEBUG |
31 | 32 | ||
@@ -160,9 +161,13 @@ static unsigned long macrisc_cfg_access(struct pci_controller* hose, | |||
160 | static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn, | 161 | static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn, |
161 | int offset, int len, u32 *val) | 162 | int offset, int len, u32 *val) |
162 | { | 163 | { |
163 | struct pci_controller *hose = bus->sysdata; | 164 | struct pci_controller *hose; |
164 | unsigned long addr; | 165 | unsigned long addr; |
165 | 166 | ||
167 | hose = pci_bus_to_host(bus); | ||
168 | if (hose == NULL) | ||
169 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
170 | |||
166 | addr = macrisc_cfg_access(hose, bus->number, devfn, offset); | 171 | addr = macrisc_cfg_access(hose, bus->number, devfn, offset); |
167 | if (!addr) | 172 | if (!addr) |
168 | return PCIBIOS_DEVICE_NOT_FOUND; | 173 | return PCIBIOS_DEVICE_NOT_FOUND; |
@@ -187,9 +192,13 @@ static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn, | |||
187 | static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn, | 192 | static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn, |
188 | int offset, int len, u32 val) | 193 | int offset, int len, u32 val) |
189 | { | 194 | { |
190 | struct pci_controller *hose = bus->sysdata; | 195 | struct pci_controller *hose; |
191 | unsigned long addr; | 196 | unsigned long addr; |
192 | 197 | ||
198 | hose = pci_bus_to_host(bus); | ||
199 | if (hose == NULL) | ||
200 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
201 | |||
193 | addr = macrisc_cfg_access(hose, bus->number, devfn, offset); | 202 | addr = macrisc_cfg_access(hose, bus->number, devfn, offset); |
194 | if (!addr) | 203 | if (!addr) |
195 | return PCIBIOS_DEVICE_NOT_FOUND; | 204 | return PCIBIOS_DEVICE_NOT_FOUND; |
@@ -221,7 +230,7 @@ static struct pci_ops macrisc_pci_ops = | |||
221 | }; | 230 | }; |
222 | 231 | ||
223 | /* | 232 | /* |
224 | * Verifiy that a specific (bus, dev_fn) exists on chaos | 233 | * Verify that a specific (bus, dev_fn) exists on chaos |
225 | */ | 234 | */ |
226 | static int | 235 | static int |
227 | chaos_validate_dev(struct pci_bus *bus, int devfn, int offset) | 236 | chaos_validate_dev(struct pci_bus *bus, int devfn, int offset) |
@@ -274,7 +283,6 @@ static struct pci_ops chaos_pci_ops = | |||
274 | }; | 283 | }; |
275 | 284 | ||
276 | #ifdef CONFIG_POWER4 | 285 | #ifdef CONFIG_POWER4 |
277 | |||
278 | /* | 286 | /* |
279 | * These versions of U3 HyperTransport config space access ops do not | 287 | * These versions of U3 HyperTransport config space access ops do not |
280 | * implement self-view of the HT host yet | 288 | * implement self-view of the HT host yet |
@@ -342,11 +350,11 @@ static unsigned long u3_ht_cfg_access(struct pci_controller* hose, | |||
342 | static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, | 350 | static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, |
343 | int offset, int len, u32 *val) | 351 | int offset, int len, u32 *val) |
344 | { | 352 | { |
345 | struct pci_controller *hose = bus->sysdata; | 353 | struct pci_controller *hose; |
346 | unsigned long addr; | 354 | unsigned long addr; |
347 | 355 | ||
348 | struct device_node *np = pci_busdev_to_OF_node(bus, devfn); | 356 | hose = pci_bus_to_host(bus); |
349 | if (np == NULL) | 357 | if (hose == NULL) |
350 | return PCIBIOS_DEVICE_NOT_FOUND; | 358 | return PCIBIOS_DEVICE_NOT_FOUND; |
351 | 359 | ||
352 | addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); | 360 | addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); |
@@ -357,19 +365,19 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, | |||
357 | case 0: | 365 | case 0: |
358 | break; | 366 | break; |
359 | case 1: | 367 | case 1: |
360 | switch (len) { | 368 | switch (len) { |
361 | case 1: | 369 | case 1: |
362 | *val = 0xff; break; | 370 | *val = 0xff; break; |
363 | case 2: | 371 | case 2: |
364 | *val = 0xffff; break; | 372 | *val = 0xffff; break; |
365 | default: | 373 | default: |
366 | *val = 0xfffffffful; break; | 374 | *val = 0xfffffffful; break; |
367 | } | 375 | } |
368 | return PCIBIOS_SUCCESSFUL; | 376 | return PCIBIOS_SUCCESSFUL; |
369 | default: | 377 | default: |
370 | return PCIBIOS_DEVICE_NOT_FOUND; | 378 | return PCIBIOS_DEVICE_NOT_FOUND; |
371 | } | 379 | } |
372 | 380 | ||
373 | /* | 381 | /* |
374 | * Note: the caller has already checked that offset is | 382 | * Note: the caller has already checked that offset is |
375 | * suitably aligned and that len is 1, 2 or 4. | 383 | * suitably aligned and that len is 1, 2 or 4. |
@@ -391,11 +399,11 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, | |||
391 | static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, | 399 | static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, |
392 | int offset, int len, u32 val) | 400 | int offset, int len, u32 val) |
393 | { | 401 | { |
394 | struct pci_controller *hose = bus->sysdata; | 402 | struct pci_controller *hose; |
395 | unsigned long addr; | 403 | unsigned long addr; |
396 | 404 | ||
397 | struct device_node *np = pci_busdev_to_OF_node(bus, devfn); | 405 | hose = pci_bus_to_host(bus); |
398 | if (np == NULL) | 406 | if (hose == NULL) |
399 | return PCIBIOS_DEVICE_NOT_FOUND; | 407 | return PCIBIOS_DEVICE_NOT_FOUND; |
400 | 408 | ||
401 | addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); | 409 | addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); |
@@ -437,15 +445,13 @@ static struct pci_ops u3_ht_pci_ops = | |||
437 | u3_ht_read_config, | 445 | u3_ht_read_config, |
438 | u3_ht_write_config | 446 | u3_ht_write_config |
439 | }; | 447 | }; |
440 | |||
441 | #endif /* CONFIG_POWER4 */ | 448 | #endif /* CONFIG_POWER4 */ |
442 | 449 | ||
443 | /* | 450 | /* |
444 | * For a bandit bridge, turn on cache coherency if necessary. | 451 | * For a bandit bridge, turn on cache coherency if necessary. |
445 | * N.B. we could clean this up using the hose ops directly. | 452 | * N.B. we could clean this up using the hose ops directly. |
446 | */ | 453 | */ |
447 | static void __init | 454 | static void __init init_bandit(struct pci_controller *bp) |
448 | init_bandit(struct pci_controller *bp) | ||
449 | { | 455 | { |
450 | unsigned int vendev, magic; | 456 | unsigned int vendev, magic; |
451 | int rev; | 457 | int rev; |
@@ -485,8 +491,7 @@ init_bandit(struct pci_controller *bp) | |||
485 | /* | 491 | /* |
486 | * Tweak the PCI-PCI bridge chip on the blue & white G3s. | 492 | * Tweak the PCI-PCI bridge chip on the blue & white G3s. |
487 | */ | 493 | */ |
488 | static void __init | 494 | static void __init init_p2pbridge(void) |
489 | init_p2pbridge(void) | ||
490 | { | 495 | { |
491 | struct device_node *p2pbridge; | 496 | struct device_node *p2pbridge; |
492 | struct pci_controller* hose; | 497 | struct pci_controller* hose; |
@@ -526,8 +531,7 @@ init_p2pbridge(void) | |||
526 | * EHCI part of it so it behaves like a pair of OHCI's. This fixup | 531 | * EHCI part of it so it behaves like a pair of OHCI's. This fixup |
527 | * code re-enables it ;) | 532 | * code re-enables it ;) |
528 | */ | 533 | */ |
529 | static void __init | 534 | static void __init fixup_nec_usb2(void) |
530 | fixup_nec_usb2(void) | ||
531 | { | 535 | { |
532 | struct device_node *nec; | 536 | struct device_node *nec; |
533 | 537 | ||
@@ -567,77 +571,6 @@ fixup_nec_usb2(void) | |||
567 | } | 571 | } |
568 | } | 572 | } |
569 | 573 | ||
570 | void __init | ||
571 | pmac_find_bridges(void) | ||
572 | { | ||
573 | struct device_node *np, *root; | ||
574 | struct device_node *ht = NULL; | ||
575 | |||
576 | root = of_find_node_by_path("/"); | ||
577 | if (root == NULL) { | ||
578 | printk(KERN_CRIT "pmac_find_bridges: can't find root of device tree\n"); | ||
579 | return; | ||
580 | } | ||
581 | for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) { | ||
582 | if (np->name == NULL) | ||
583 | continue; | ||
584 | if (strcmp(np->name, "bandit") == 0 | ||
585 | || strcmp(np->name, "chaos") == 0 | ||
586 | || strcmp(np->name, "pci") == 0) { | ||
587 | if (add_bridge(np) == 0) | ||
588 | of_node_get(np); | ||
589 | } | ||
590 | if (strcmp(np->name, "ht") == 0) { | ||
591 | of_node_get(np); | ||
592 | ht = np; | ||
593 | } | ||
594 | } | ||
595 | of_node_put(root); | ||
596 | |||
597 | /* Probe HT last as it relies on the agp resources to be already | ||
598 | * setup | ||
599 | */ | ||
600 | if (ht && add_bridge(ht) != 0) | ||
601 | of_node_put(ht); | ||
602 | |||
603 | init_p2pbridge(); | ||
604 | fixup_nec_usb2(); | ||
605 | |||
606 | /* We are still having some issues with the Xserve G4, enabling | ||
607 | * some offset between bus number and domains for now when we | ||
608 | * assign all busses should help for now | ||
609 | */ | ||
610 | if (pci_assign_all_busses) | ||
611 | pcibios_assign_bus_offset = 0x10; | ||
612 | |||
613 | #ifdef CONFIG_POWER4 | ||
614 | /* There is something wrong with DMA on U3/HT. I haven't figured out | ||
615 | * the details yet, but if I set the cache line size to 128 bytes like | ||
616 | * it should, I'm getting memory corruption caused by devices like | ||
617 | * sungem (even without the MWI bit set, but maybe sungem doesn't | ||
618 | * care). Right now, it appears that setting up a 64 bytes line size | ||
619 | * works properly, 64 bytes beeing the max transfer size of HT, I | ||
620 | * suppose this is related the way HT/PCI are hooked together. I still | ||
621 | * need to dive into more specs though to be really sure of what's | ||
622 | * going on. --BenH. | ||
623 | * | ||
624 | * Ok, apparently, it's just that HT can't do more than 64 bytes | ||
625 | * transactions. MWI seem to be meaningless there as well, it may | ||
626 | * be worth nop'ing out pci_set_mwi too though I haven't done that | ||
627 | * yet. | ||
628 | * | ||
629 | * Note that it's a bit different for whatever is in the AGP slot. | ||
630 | * For now, I don't care, but this can become a real issue, we | ||
631 | * should probably hook pci_set_mwi anyway to make sure it sets | ||
632 | * the real cache line size in there. | ||
633 | */ | ||
634 | if (machine_is_compatible("MacRISC4")) | ||
635 | pci_cache_line_size = 16; /* 64 bytes */ | ||
636 | |||
637 | pmac_check_ht_link(); | ||
638 | #endif /* CONFIG_POWER4 */ | ||
639 | } | ||
640 | |||
641 | #define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \ | 574 | #define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \ |
642 | | (((o) & ~3) << 24)) | 575 | | (((o) & ~3) << 24)) |
643 | 576 | ||
@@ -703,7 +636,6 @@ setup_chaos(struct pci_controller* hose, struct reg_property* addr) | |||
703 | } | 636 | } |
704 | 637 | ||
705 | #ifdef CONFIG_POWER4 | 638 | #ifdef CONFIG_POWER4 |
706 | |||
707 | static void __init setup_u3_agp(struct pci_controller* hose) | 639 | static void __init setup_u3_agp(struct pci_controller* hose) |
708 | { | 640 | { |
709 | /* On G5, we move AGP up to high bus number so we don't need | 641 | /* On G5, we move AGP up to high bus number so we don't need |
@@ -715,7 +647,7 @@ static void __init setup_u3_agp(struct pci_controller* hose) | |||
715 | * the reg address cell, we shall fix that by killing struct | 647 | * the reg address cell, we shall fix that by killing struct |
716 | * reg_property and using some accessor functions instead | 648 | * reg_property and using some accessor functions instead |
717 | */ | 649 | */ |
718 | hose->first_busno = 0xf0; | 650 | hose->first_busno = 0xf0; |
719 | hose->last_busno = 0xff; | 651 | hose->last_busno = 0xff; |
720 | has_uninorth = 1; | 652 | has_uninorth = 1; |
721 | hose->ops = ¯isc_pci_ops; | 653 | hose->ops = ¯isc_pci_ops; |
@@ -748,7 +680,7 @@ static void __init setup_u3_ht(struct pci_controller* hose) | |||
748 | */ | 680 | */ |
749 | hose->io_base_phys = 0xf4000000; | 681 | hose->io_base_phys = 0xf4000000; |
750 | hose->io_base_virt = ioremap(hose->io_base_phys, 0x00400000); | 682 | hose->io_base_virt = ioremap(hose->io_base_phys, 0x00400000); |
751 | isa_io_base = (unsigned long) hose->io_base_virt; | 683 | isa_io_base = pci_io_base = (unsigned long) hose->io_base_virt; |
752 | hose->io_resource.name = np->full_name; | 684 | hose->io_resource.name = np->full_name; |
753 | hose->io_resource.start = 0; | 685 | hose->io_resource.start = 0; |
754 | hose->io_resource.end = 0x003fffff; | 686 | hose->io_resource.end = 0x003fffff; |
@@ -794,13 +726,13 @@ static void __init setup_u3_ht(struct pci_controller* hose) | |||
794 | } | 726 | } |
795 | /* No, it's not the case, we need a hole */ | 727 | /* No, it's not the case, we need a hole */ |
796 | if (cur == 2) { | 728 | if (cur == 2) { |
797 | /* not enough resources to make a hole, we drop part of the range */ | 729 | /* not enough resources for a hole, we drop part of the range */ |
798 | printk(KERN_WARNING "Running out of resources for /ht host !\n"); | 730 | printk(KERN_WARNING "Running out of resources for /ht host !\n"); |
799 | hose->mem_resources[cur].end = res->start - 1; | 731 | hose->mem_resources[cur].end = res->start - 1; |
800 | continue; | 732 | continue; |
801 | } | 733 | } |
802 | cur++; | 734 | cur++; |
803 | DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n", | 735 | DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n", |
804 | cur-1, res->start - 1, cur, res->end + 1); | 736 | cur-1, res->start - 1, cur, res->end + 1); |
805 | hose->mem_resources[cur].name = np->full_name; | 737 | hose->mem_resources[cur].name = np->full_name; |
806 | hose->mem_resources[cur].flags = IORESOURCE_MEM; | 738 | hose->mem_resources[cur].flags = IORESOURCE_MEM; |
@@ -981,7 +913,7 @@ static int __init add_bridge(struct device_node *dev) | |||
981 | if (device_is_compatible(dev, "uni-north")) { | 913 | if (device_is_compatible(dev, "uni-north")) { |
982 | primary = setup_uninorth(hose, addr); | 914 | primary = setup_uninorth(hose, addr); |
983 | disp_name = "UniNorth"; | 915 | disp_name = "UniNorth"; |
984 | } else if (strcmp(dev->name, "pci") == 0) { | 916 | } else if (strcmp(dev->name, "pci") == 0) { |
985 | /* XXX assume this is a mpc106 (grackle) */ | 917 | /* XXX assume this is a mpc106 (grackle) */ |
986 | setup_grackle(hose); | 918 | setup_grackle(hose); |
987 | disp_name = "Grackle (MPC106)"; | 919 | disp_name = "Grackle (MPC106)"; |
@@ -993,7 +925,7 @@ static int __init add_bridge(struct device_node *dev) | |||
993 | disp_name = "Chaos"; | 925 | disp_name = "Chaos"; |
994 | primary = 0; | 926 | primary = 0; |
995 | } | 927 | } |
996 | printk(KERN_INFO "Found %s PCI host bridge at 0x%08x. Firmware bus number: %d->%d\n", | 928 | printk(KERN_INFO "Found %s PCI host bridge at 0x%08lx. Firmware bus number: %d->%d\n", |
997 | disp_name, addr->address, hose->first_busno, hose->last_busno); | 929 | disp_name, addr->address, hose->first_busno, hose->last_busno); |
998 | DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", | 930 | DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", |
999 | hose, hose->cfg_addr, hose->cfg_data); | 931 | hose, hose->cfg_addr, hose->cfg_data); |
@@ -1036,6 +968,50 @@ pmac_pcibios_fixup(void) | |||
1036 | pcibios_fixup_OF_interrupts(); | 968 | pcibios_fixup_OF_interrupts(); |
1037 | } | 969 | } |
1038 | 970 | ||
971 | void __init pmac_find_bridges(void) | ||
972 | { | ||
973 | struct device_node *np, *root; | ||
974 | struct device_node *ht = NULL; | ||
975 | |||
976 | root = of_find_node_by_path("/"); | ||
977 | if (root == NULL) { | ||
978 | printk(KERN_CRIT "pmac_find_bridges: can't find root of device tree\n"); | ||
979 | return; | ||
980 | } | ||
981 | for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) { | ||
982 | if (np->name == NULL) | ||
983 | continue; | ||
984 | if (strcmp(np->name, "bandit") == 0 | ||
985 | || strcmp(np->name, "chaos") == 0 | ||
986 | || strcmp(np->name, "pci") == 0) { | ||
987 | if (add_bridge(np) == 0) | ||
988 | of_node_get(np); | ||
989 | } | ||
990 | if (strcmp(np->name, "ht") == 0) { | ||
991 | of_node_get(np); | ||
992 | ht = np; | ||
993 | } | ||
994 | } | ||
995 | of_node_put(root); | ||
996 | |||
997 | /* Probe HT last as it relies on the agp resources to be already | ||
998 | * setup | ||
999 | */ | ||
1000 | if (ht && add_bridge(ht) != 0) | ||
1001 | of_node_put(ht); | ||
1002 | |||
1003 | init_p2pbridge(); | ||
1004 | fixup_nec_usb2(); | ||
1005 | |||
1006 | /* We are still having some issues with the Xserve G4, enabling | ||
1007 | * some offset between bus number and domains for now when we | ||
1008 | * assign all busses should help for now | ||
1009 | */ | ||
1010 | if (pci_assign_all_busses) | ||
1011 | pcibios_assign_bus_offset = 0x10; | ||
1012 | |||
1013 | } | ||
1014 | |||
1039 | int | 1015 | int |
1040 | pmac_pci_enable_device_hook(struct pci_dev *dev, int initial) | 1016 | pmac_pci_enable_device_hook(struct pci_dev *dev, int initial) |
1041 | { | 1017 | { |
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 7ddd5264cc6e..682fe8b6e025 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/sysdev.h> | 25 | #include <linux/sysdev.h> |
26 | #include <linux/adb.h> | 26 | #include <linux/adb.h> |
27 | #include <linux/pmu.h> | 27 | #include <linux/pmu.h> |
28 | #include <linux/module.h> | ||
28 | 29 | ||
29 | #include <asm/sections.h> | 30 | #include <asm/sections.h> |
30 | #include <asm/io.h> | 31 | #include <asm/io.h> |
@@ -32,12 +33,11 @@ | |||
32 | #include <asm/prom.h> | 33 | #include <asm/prom.h> |
33 | #include <asm/pci-bridge.h> | 34 | #include <asm/pci-bridge.h> |
34 | #include <asm/time.h> | 35 | #include <asm/time.h> |
35 | #include <asm/open_pic.h> | ||
36 | #include <asm/xmon.h> | 36 | #include <asm/xmon.h> |
37 | #include <asm/pmac_feature.h> | 37 | #include <asm/pmac_feature.h> |
38 | #include <asm/mpic.h> | 38 | #include <asm/mpic.h> |
39 | 39 | ||
40 | #include "pmac_pic.h" | 40 | #include "pmac.h" |
41 | 41 | ||
42 | /* | 42 | /* |
43 | * XXX this should be in xmon.h, but putting it there means xmon.h | 43 | * XXX this should be in xmon.h, but putting it there means xmon.h |
@@ -46,6 +46,7 @@ | |||
46 | */ | 46 | */ |
47 | extern irqreturn_t xmon_irq(int, void *, struct pt_regs *); | 47 | extern irqreturn_t xmon_irq(int, void *, struct pt_regs *); |
48 | 48 | ||
49 | #ifdef CONFIG_PPC32 | ||
49 | struct pmac_irq_hw { | 50 | struct pmac_irq_hw { |
50 | unsigned int event; | 51 | unsigned int event; |
51 | unsigned int enable; | 52 | unsigned int enable; |
@@ -71,6 +72,9 @@ static u32 level_mask[4]; | |||
71 | 72 | ||
72 | static DEFINE_SPINLOCK(pmac_pic_lock); | 73 | static DEFINE_SPINLOCK(pmac_pic_lock); |
73 | 74 | ||
75 | /* XXX here for now, should move to arch/powerpc/kernel/irq.c */ | ||
76 | int ppc_do_canonicalize_irqs; | ||
77 | EXPORT_SYMBOL(ppc_do_canonicalize_irqs); | ||
74 | 78 | ||
75 | #define GATWICK_IRQ_POOL_SIZE 10 | 79 | #define GATWICK_IRQ_POOL_SIZE 10 |
76 | static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; | 80 | static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; |
@@ -377,11 +381,6 @@ static int __init enable_second_ohare(void) | |||
377 | return irqctrler->intrs[0].line; | 381 | return irqctrler->intrs[0].line; |
378 | } | 382 | } |
379 | 383 | ||
380 | static int pmac_u3_cascade(struct pt_regs *regs, void *data) | ||
381 | { | ||
382 | return mpic_get_one_irq((struct mpic *)data, regs); | ||
383 | } | ||
384 | |||
385 | #ifdef CONFIG_XMON | 384 | #ifdef CONFIG_XMON |
386 | static struct irqaction xmon_action = { | 385 | static struct irqaction xmon_action = { |
387 | .handler = xmon_irq, | 386 | .handler = xmon_irq, |
@@ -397,15 +396,23 @@ static struct irqaction gatwick_cascade_action = { | |||
397 | .mask = CPU_MASK_NONE, | 396 | .mask = CPU_MASK_NONE, |
398 | .name = "cascade", | 397 | .name = "cascade", |
399 | }; | 398 | }; |
399 | #endif /* CONFIG_PPC32 */ | ||
400 | |||
401 | static int pmac_u3_cascade(struct pt_regs *regs, void *data) | ||
402 | { | ||
403 | return mpic_get_one_irq((struct mpic *)data, regs); | ||
404 | } | ||
400 | 405 | ||
401 | void __init pmac_pic_init(void) | 406 | void __init pmac_pic_init(void) |
402 | { | 407 | { |
403 | int i; | ||
404 | struct device_node *irqctrler = NULL; | 408 | struct device_node *irqctrler = NULL; |
405 | struct device_node *irqctrler2 = NULL; | 409 | struct device_node *irqctrler2 = NULL; |
406 | struct device_node *np; | 410 | struct device_node *np; |
411 | #ifdef CONFIG_PPC32 | ||
412 | int i; | ||
407 | unsigned long addr; | 413 | unsigned long addr; |
408 | int irq_cascade = -1; | 414 | int irq_cascade = -1; |
415 | #endif | ||
409 | struct mpic *mpic1, *mpic2; | 416 | struct mpic *mpic1, *mpic2; |
410 | 417 | ||
411 | /* We first try to detect Apple's new Core99 chipset, since mac-io | 418 | /* We first try to detect Apple's new Core99 chipset, since mac-io |
@@ -455,7 +462,7 @@ void __init pmac_pic_init(void) | |||
455 | mpic_setup_cascade(irqctrler2->intrs[0].line, | 462 | mpic_setup_cascade(irqctrler2->intrs[0].line, |
456 | pmac_u3_cascade, mpic2); | 463 | pmac_u3_cascade, mpic2); |
457 | } | 464 | } |
458 | #ifdef CONFIG_XMON | 465 | #if defined(CONFIG_XMON) && defined(CONFIG_PPC32) |
459 | { | 466 | { |
460 | struct device_node* pswitch; | 467 | struct device_node* pswitch; |
461 | int nmi_irq; | 468 | int nmi_irq; |
@@ -463,7 +470,7 @@ void __init pmac_pic_init(void) | |||
463 | pswitch = find_devices("programmer-switch"); | 470 | pswitch = find_devices("programmer-switch"); |
464 | if (pswitch && pswitch->n_intrs) { | 471 | if (pswitch && pswitch->n_intrs) { |
465 | nmi_irq = pswitch->intrs[0].line; | 472 | nmi_irq = pswitch->intrs[0].line; |
466 | openpic_init_nmi_irq(nmi_irq); | 473 | mpic_irq_set_priority(nmi_irq, 9); |
467 | setup_irq(nmi_irq, &xmon_action); | 474 | setup_irq(nmi_irq, &xmon_action); |
468 | } | 475 | } |
469 | } | 476 | } |
@@ -472,6 +479,7 @@ void __init pmac_pic_init(void) | |||
472 | } | 479 | } |
473 | irqctrler = NULL; | 480 | irqctrler = NULL; |
474 | 481 | ||
482 | #ifdef CONFIG_PPC32 | ||
475 | /* Get the level/edge settings, assume if it's not | 483 | /* Get the level/edge settings, assume if it's not |
476 | * a Grand Central nor an OHare, then it's an Heathrow | 484 | * a Grand Central nor an OHare, then it's an Heathrow |
477 | * (or Paddington). | 485 | * (or Paddington). |
@@ -570,6 +578,7 @@ void __init pmac_pic_init(void) | |||
570 | #ifdef CONFIG_XMON | 578 | #ifdef CONFIG_XMON |
571 | setup_irq(20, &xmon_action); | 579 | setup_irq(20, &xmon_action); |
572 | #endif /* CONFIG_XMON */ | 580 | #endif /* CONFIG_XMON */ |
581 | #endif /* CONFIG_PPC32 */ | ||
573 | } | 582 | } |
574 | 583 | ||
575 | #ifdef CONFIG_PM | 584 | #ifdef CONFIG_PM |
@@ -659,9 +668,10 @@ static struct sysdev_driver driver_pmacpic = { | |||
659 | 668 | ||
660 | static int __init init_pmacpic_sysfs(void) | 669 | static int __init init_pmacpic_sysfs(void) |
661 | { | 670 | { |
671 | #ifdef CONFIG_PPC32 | ||
662 | if (max_irqs == 0) | 672 | if (max_irqs == 0) |
663 | return -ENODEV; | 673 | return -ENODEV; |
664 | 674 | #endif | |
665 | printk(KERN_DEBUG "Registering pmac pic with sysfs...\n"); | 675 | printk(KERN_DEBUG "Registering pmac pic with sysfs...\n"); |
666 | sysdev_class_register(&pmacpic_sysclass); | 676 | sysdev_class_register(&pmacpic_sysclass); |
667 | sysdev_register(&device_pmacpic); | 677 | sysdev_register(&device_pmacpic); |
diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h index 40e1c5030f74..81f52512b046 100644 --- a/arch/powerpc/platforms/powermac/pmac.h +++ b/arch/powerpc/platforms/powermac/pmac.h | |||
@@ -3,19 +3,31 @@ | |||
3 | 3 | ||
4 | #include <linux/pci.h> | 4 | #include <linux/pci.h> |
5 | #include <linux/ide.h> | 5 | #include <linux/ide.h> |
6 | #include <linux/irq.h> | ||
6 | 7 | ||
7 | /* | 8 | /* |
8 | * Declaration for the various functions exported by the | 9 | * Declaration for the various functions exported by the |
9 | * pmac_* files. Mostly for use by pmac_setup | 10 | * pmac_* files. Mostly for use by pmac_setup |
10 | */ | 11 | */ |
11 | 12 | ||
12 | extern void pmac_get_boot_time(struct rtc_time *tm); | 13 | extern long pmac_time_init(void); |
13 | extern void pmac_get_rtc_time(struct rtc_time *tm); | 14 | extern unsigned long pmac_get_rtc_time(void); |
14 | extern int pmac_set_rtc_time(struct rtc_time *tm); | 15 | extern int pmac_set_rtc_time(unsigned long nowtime); |
15 | extern void pmac_read_rtc_time(void); | 16 | extern void pmac_read_rtc_time(void); |
16 | extern void pmac_calibrate_decr(void); | 17 | extern void pmac_calibrate_decr(void); |
17 | |||
18 | extern void pmac_pcibios_fixup(void); | 18 | extern void pmac_pcibios_fixup(void); |
19 | extern void pmac_find_bridges(void); | ||
20 | extern unsigned long pmac_ide_get_base(int index); | ||
21 | extern void pmac_ide_init_hwif_ports(hw_regs_t *hw, | ||
22 | unsigned long data_port, unsigned long ctrl_port, int *irq); | ||
23 | |||
24 | extern void pmac_nvram_update(void); | ||
25 | extern unsigned char pmac_nvram_read_byte(int addr); | ||
26 | extern void pmac_nvram_write_byte(int addr, unsigned char val); | ||
27 | extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial); | ||
28 | extern void pmac_pcibios_after_init(void); | ||
29 | extern int of_show_percpuinfo(struct seq_file *m, int i); | ||
30 | |||
19 | extern void pmac_pci_init(void); | 31 | extern void pmac_pci_init(void); |
20 | extern void pmac_setup_pci_dma(void); | 32 | extern void pmac_setup_pci_dma(void); |
21 | extern void pmac_check_ht_link(void); | 33 | extern void pmac_check_ht_link(void); |
@@ -28,4 +40,9 @@ extern void pmac_ide_init_hwif_ports(hw_regs_t *hw, | |||
28 | 40 | ||
29 | extern void pmac_nvram_init(void); | 41 | extern void pmac_nvram_init(void); |
30 | 42 | ||
43 | extern struct hw_interrupt_type pmac_pic; | ||
44 | |||
45 | void pmac_pic_init(void); | ||
46 | int pmac_get_irq(struct pt_regs *regs); | ||
47 | |||
31 | #endif /* __PMAC_H__ */ | 48 | #endif /* __PMAC_H__ */ |
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 1b12bf9956cb..9416fcaa6daa 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c | |||
@@ -73,28 +73,10 @@ | |||
73 | #include <asm/of_device.h> | 73 | #include <asm/of_device.h> |
74 | #include <asm/mmu_context.h> | 74 | #include <asm/mmu_context.h> |
75 | 75 | ||
76 | #include "pmac_pic.h" | 76 | #include "pmac.h" |
77 | 77 | ||
78 | #undef SHOW_GATWICK_IRQS | 78 | #undef SHOW_GATWICK_IRQS |
79 | 79 | ||
80 | extern long pmac_time_init(void); | ||
81 | extern unsigned long pmac_get_rtc_time(void); | ||
82 | extern int pmac_set_rtc_time(unsigned long nowtime); | ||
83 | extern void pmac_read_rtc_time(void); | ||
84 | extern void pmac_calibrate_decr(void); | ||
85 | extern void pmac_pcibios_fixup(void); | ||
86 | extern void pmac_find_bridges(void); | ||
87 | extern unsigned long pmac_ide_get_base(int index); | ||
88 | extern void pmac_ide_init_hwif_ports(hw_regs_t *hw, | ||
89 | unsigned long data_port, unsigned long ctrl_port, int *irq); | ||
90 | |||
91 | extern void pmac_nvram_update(void); | ||
92 | extern unsigned char pmac_nvram_read_byte(int addr); | ||
93 | extern void pmac_nvram_write_byte(int addr, unsigned char val); | ||
94 | extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial); | ||
95 | extern void pmac_pcibios_after_init(void); | ||
96 | extern int of_show_percpuinfo(struct seq_file *m, int i); | ||
97 | |||
98 | unsigned char drive_info; | 80 | unsigned char drive_info; |
99 | 81 | ||
100 | int ppc_override_l2cr = 0; | 82 | int ppc_override_l2cr = 0; |