diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2005-12-13 02:01:21 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-01-08 22:53:55 -0500 |
commit | cc5d0189b9ba95260857a5018a1c2fef90008507 (patch) | |
tree | 1202c94b6b3cb81a96d0a0e54424cad10eef68bb /arch/powerpc/platforms | |
parent | 9cf84d7c97992dbe5360b241327341c07ce30fc9 (diff) |
[PATCH] powerpc: Remove device_node addrs/n_addr
The pre-parsed addrs/n_addrs fields in struct device_node are finally
gone. Remove the dodgy heuristics that did that parsing at boot and
remove the fields themselves since we now have a good replacement with
the new OF parsing code. This patch also fixes a bunch of drivers to use
the new code instead, so that at least pmac32, pseries, iseries and g5
defconfigs build.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r-- | arch/powerpc/platforms/powermac/feature.c | 75 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/nvram.c | 52 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/pci.c | 87 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/pic.c | 456 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/pmac.h | 6 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/setup.c | 3 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/time.c | 15 |
7 files changed, 381 insertions, 313 deletions
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); |