diff options
Diffstat (limited to 'arch')
350 files changed, 11731 insertions, 15543 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 50b9afa8ae6d..5959e36c3b4c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -180,6 +180,7 @@ config ARCH_OMAP | |||
| 180 | config ARCH_VERSATILE | 180 | config ARCH_VERSATILE |
| 181 | bool "Versatile" | 181 | bool "Versatile" |
| 182 | select ARM_AMBA | 182 | select ARM_AMBA |
| 183 | select ARM_VIC | ||
| 183 | select ICST307 | 184 | select ICST307 |
| 184 | help | 185 | help |
| 185 | This enables support for ARM Ltd Versatile board. | 186 | This enables support for ARM Ltd Versatile board. |
| @@ -400,6 +401,38 @@ config NO_IDLE_HZ | |||
| 400 | Currently at least OMAP, PXA2xx and SA11x0 platforms are known | 401 | Currently at least OMAP, PXA2xx and SA11x0 platforms are known |
| 401 | to have accurate timekeeping with dynamic tick. | 402 | to have accurate timekeeping with dynamic tick. |
| 402 | 403 | ||
| 404 | config AEABI | ||
| 405 | bool "Use the ARM EABI to compile the kernel" | ||
| 406 | help | ||
| 407 | This option allows for the kernel to be compiled using the latest | ||
| 408 | ARM ABI (aka EABI). This is only useful if you are using a user | ||
| 409 | space environment that is also compiled with EABI. | ||
| 410 | |||
| 411 | Since there are major incompatibilities between the legacy ABI and | ||
| 412 | EABI, especially with regard to structure member alignment, this | ||
| 413 | option also changes the kernel syscall calling convention to | ||
| 414 | disambiguate both ABIs and allow for backward compatibility support | ||
| 415 | (selected with CONFIG_OABI_COMPAT). | ||
| 416 | |||
| 417 | To use this you need GCC version 4.0.0 or later. | ||
| 418 | |||
| 419 | config OABI_COMPAT | ||
| 420 | bool "Allow old ABI binaries to run with this kernel" | ||
| 421 | depends on AEABI | ||
| 422 | default y | ||
| 423 | help | ||
| 424 | This option preserves the old syscall interface along with the | ||
| 425 | new (ARM EABI) one. It also provides a compatibility layer to | ||
| 426 | intercept syscalls that have structure arguments which layout | ||
| 427 | in memory differs between the legacy ABI and the new ARM EABI | ||
| 428 | (only for non "thumb" binaries). This option adds a tiny | ||
| 429 | overhead to all syscalls and produces a slightly larger kernel. | ||
| 430 | If you know you'll be using only pure EABI user space then you | ||
| 431 | can say N here. If this option is not selected and you attempt | ||
| 432 | to execute a legacy ABI binary then the result will be | ||
| 433 | UNPREDICTABLE (in fact it can be predicted that it won't work | ||
| 434 | at all). If in doubt say Y. | ||
| 435 | |||
| 403 | config ARCH_DISCONTIGMEM_ENABLE | 436 | config ARCH_DISCONTIGMEM_ENABLE |
| 404 | bool | 437 | bool |
| 405 | default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) | 438 | default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) |
| @@ -586,6 +619,7 @@ comment "At least one emulation must be selected" | |||
| 586 | 619 | ||
| 587 | config FPE_NWFPE | 620 | config FPE_NWFPE |
| 588 | bool "NWFPE math emulation" | 621 | bool "NWFPE math emulation" |
| 622 | depends on !AEABI || OABI_COMPAT | ||
| 589 | ---help--- | 623 | ---help--- |
| 590 | Say Y to include the NWFPE floating point emulator in the kernel. | 624 | Say Y to include the NWFPE floating point emulator in the kernel. |
| 591 | This is necessary to run most binaries. Linux does not currently | 625 | This is necessary to run most binaries. Linux does not currently |
| @@ -609,7 +643,7 @@ config FPE_NWFPE_XP | |||
| 609 | 643 | ||
| 610 | config FPE_FASTFPE | 644 | config FPE_FASTFPE |
| 611 | bool "FastFPE math emulation (EXPERIMENTAL)" | 645 | bool "FastFPE math emulation (EXPERIMENTAL)" |
| 612 | depends on !CPU_32v3 && EXPERIMENTAL | 646 | depends on (!AEABI || OABI_COMPAT) && !CPU_32v3 && EXPERIMENTAL |
| 613 | ---help--- | 647 | ---help--- |
| 614 | Say Y here to include the FAST floating point emulator in the kernel. | 648 | Say Y here to include the FAST floating point emulator in the kernel. |
| 615 | This is an experimental much faster emulator which now also has full | 649 | This is an experimental much faster emulator which now also has full |
| @@ -641,6 +675,7 @@ source "fs/Kconfig.binfmt" | |||
| 641 | 675 | ||
| 642 | config ARTHUR | 676 | config ARTHUR |
| 643 | tristate "RISC OS personality" | 677 | tristate "RISC OS personality" |
| 678 | depends on !AEABI | ||
| 644 | help | 679 | help |
| 645 | Say Y here to include the kernel code necessary if you want to run | 680 | Say Y here to include the kernel code necessary if you want to run |
| 646 | Acorn RISC OS/Arthur binaries under Linux. This code is still very | 681 | Acorn RISC OS/Arthur binaries under Linux. This code is still very |
| @@ -729,6 +764,8 @@ source "drivers/char/Kconfig" | |||
| 729 | 764 | ||
| 730 | source "drivers/i2c/Kconfig" | 765 | source "drivers/i2c/Kconfig" |
| 731 | 766 | ||
| 767 | source "drivers/spi/Kconfig" | ||
| 768 | |||
| 732 | source "drivers/hwmon/Kconfig" | 769 | source "drivers/hwmon/Kconfig" |
| 733 | 770 | ||
| 734 | #source "drivers/l3/Kconfig" | 771 | #source "drivers/l3/Kconfig" |
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 1fa2a1011584..fbfc14a56b96 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
| @@ -56,8 +56,13 @@ tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100 | |||
| 56 | tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale | 56 | tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale |
| 57 | tune-$(CONFIG_CPU_V6) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm) | 57 | tune-$(CONFIG_CPU_V6) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm) |
| 58 | 58 | ||
| 59 | # Need -Uarm for gcc < 3.x | 59 | ifeq ($(CONFIG_AEABI),y) |
| 60 | CFLAGS_ABI :=-mabi=aapcs -mno-thumb-interwork | ||
| 61 | else | ||
| 60 | CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,) | 62 | CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,) |
| 63 | endif | ||
| 64 | |||
| 65 | # Need -Uarm for gcc < 3.x | ||
| 61 | CFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm | 66 | CFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm |
| 62 | AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float | 67 | AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float |
| 63 | 68 | ||
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index d7509c7a3c5e..5e34ca6d38b6 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig | |||
| @@ -1,7 +1,10 @@ | |||
| 1 | config ICST525 | 1 | config ARM_GIC |
| 2 | bool | 2 | bool |
| 3 | 3 | ||
| 4 | config ARM_GIC | 4 | config ARM_VIC |
| 5 | bool | ||
| 6 | |||
| 7 | config ICST525 | ||
| 5 | bool | 8 | bool |
| 6 | 9 | ||
| 7 | config ICST307 | 10 | config ICST307 |
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index ec8d17c96906..c81a2ff6b5be 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | obj-y += rtctime.o | 5 | obj-y += rtctime.o |
| 6 | obj-$(CONFIG_ARM_GIC) += gic.o | 6 | obj-$(CONFIG_ARM_GIC) += gic.o |
| 7 | obj-$(CONFIG_ARM_VIC) += vic.o | ||
| 7 | obj-$(CONFIG_ICST525) += icst525.o | 8 | obj-$(CONFIG_ICST525) += icst525.o |
| 8 | obj-$(CONFIG_ICST307) += icst307.o | 9 | obj-$(CONFIG_ICST307) += icst307.o |
| 9 | obj-$(CONFIG_SA1111) += sa1111.o | 10 | obj-$(CONFIG_SA1111) += sa1111.o |
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 1b7eaab02b9e..159ad7ed7a40 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c | |||
| @@ -1103,14 +1103,14 @@ static int locomo_bus_remove(struct device *dev) | |||
| 1103 | struct bus_type locomo_bus_type = { | 1103 | struct bus_type locomo_bus_type = { |
| 1104 | .name = "locomo-bus", | 1104 | .name = "locomo-bus", |
| 1105 | .match = locomo_match, | 1105 | .match = locomo_match, |
| 1106 | .probe = locomo_bus_probe, | ||
| 1107 | .remove = locomo_bus_remove, | ||
| 1106 | .suspend = locomo_bus_suspend, | 1108 | .suspend = locomo_bus_suspend, |
| 1107 | .resume = locomo_bus_resume, | 1109 | .resume = locomo_bus_resume, |
| 1108 | }; | 1110 | }; |
| 1109 | 1111 | ||
| 1110 | int locomo_driver_register(struct locomo_driver *driver) | 1112 | int locomo_driver_register(struct locomo_driver *driver) |
| 1111 | { | 1113 | { |
| 1112 | driver->drv.probe = locomo_bus_probe; | ||
| 1113 | driver->drv.remove = locomo_bus_remove; | ||
| 1114 | driver->drv.bus = &locomo_bus_type; | 1114 | driver->drv.bus = &locomo_bus_type; |
| 1115 | return driver_register(&driver->drv); | 1115 | return driver_register(&driver->drv); |
| 1116 | } | 1116 | } |
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index d0d6e6d2d649..1475089f9b42 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c | |||
| @@ -1247,14 +1247,14 @@ static int sa1111_bus_remove(struct device *dev) | |||
| 1247 | struct bus_type sa1111_bus_type = { | 1247 | struct bus_type sa1111_bus_type = { |
| 1248 | .name = "sa1111-rab", | 1248 | .name = "sa1111-rab", |
| 1249 | .match = sa1111_match, | 1249 | .match = sa1111_match, |
| 1250 | .probe = sa1111_bus_probe, | ||
| 1251 | .remove = sa1111_bus_remove, | ||
| 1250 | .suspend = sa1111_bus_suspend, | 1252 | .suspend = sa1111_bus_suspend, |
| 1251 | .resume = sa1111_bus_resume, | 1253 | .resume = sa1111_bus_resume, |
| 1252 | }; | 1254 | }; |
| 1253 | 1255 | ||
| 1254 | int sa1111_driver_register(struct sa1111_driver *driver) | 1256 | int sa1111_driver_register(struct sa1111_driver *driver) |
| 1255 | { | 1257 | { |
| 1256 | driver->drv.probe = sa1111_bus_probe; | ||
| 1257 | driver->drv.remove = sa1111_bus_remove; | ||
| 1258 | driver->drv.bus = &sa1111_bus_type; | 1258 | driver->drv.bus = &sa1111_bus_type; |
| 1259 | return driver_register(&driver->drv); | 1259 | return driver_register(&driver->drv); |
| 1260 | } | 1260 | } |
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c new file mode 100644 index 000000000000..a45ed1687a59 --- /dev/null +++ b/arch/arm/common/vic.c | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/common/vic.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 1999 - 2003 ARM Limited | ||
| 5 | * Copyright (C) 2000 Deep Blue Solutions Ltd | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | ||
| 21 | #include <linux/init.h> | ||
| 22 | #include <linux/list.h> | ||
| 23 | |||
| 24 | #include <asm/io.h> | ||
| 25 | #include <asm/irq.h> | ||
| 26 | #include <asm/mach/irq.h> | ||
| 27 | #include <asm/hardware/vic.h> | ||
| 28 | |||
| 29 | static void __iomem *vic_base; | ||
| 30 | |||
| 31 | static void vic_mask_irq(unsigned int irq) | ||
| 32 | { | ||
| 33 | irq -= IRQ_VIC_START; | ||
| 34 | writel(1 << irq, vic_base + VIC_INT_ENABLE_CLEAR); | ||
| 35 | } | ||
| 36 | |||
| 37 | static void vic_unmask_irq(unsigned int irq) | ||
| 38 | { | ||
| 39 | irq -= IRQ_VIC_START; | ||
| 40 | writel(1 << irq, vic_base + VIC_INT_ENABLE); | ||
| 41 | } | ||
| 42 | |||
| 43 | static struct irqchip vic_chip = { | ||
| 44 | .ack = vic_mask_irq, | ||
| 45 | .mask = vic_mask_irq, | ||
| 46 | .unmask = vic_unmask_irq, | ||
| 47 | }; | ||
| 48 | |||
| 49 | void __init vic_init(void __iomem *base, u32 vic_sources) | ||
| 50 | { | ||
| 51 | unsigned int i; | ||
| 52 | |||
| 53 | vic_base = base; | ||
| 54 | |||
| 55 | /* Disable all interrupts initially. */ | ||
| 56 | |||
| 57 | writel(0, vic_base + VIC_INT_SELECT); | ||
| 58 | writel(0, vic_base + VIC_INT_ENABLE); | ||
| 59 | writel(~0, vic_base + VIC_INT_ENABLE_CLEAR); | ||
| 60 | writel(0, vic_base + VIC_IRQ_STATUS); | ||
| 61 | writel(0, vic_base + VIC_ITCR); | ||
| 62 | writel(~0, vic_base + VIC_INT_SOFT_CLEAR); | ||
| 63 | |||
| 64 | /* | ||
| 65 | * Make sure we clear all existing interrupts | ||
| 66 | */ | ||
| 67 | writel(0, vic_base + VIC_VECT_ADDR); | ||
| 68 | for (i = 0; i < 19; i++) { | ||
| 69 | unsigned int value; | ||
| 70 | |||
| 71 | value = readl(vic_base + VIC_VECT_ADDR); | ||
| 72 | writel(value, vic_base + VIC_VECT_ADDR); | ||
| 73 | } | ||
| 74 | |||
| 75 | for (i = 0; i < 16; i++) { | ||
| 76 | void __iomem *reg = vic_base + VIC_VECT_CNTL0 + (i * 4); | ||
| 77 | writel(VIC_VECT_CNTL_ENABLE | i, reg); | ||
| 78 | } | ||
| 79 | |||
| 80 | writel(32, vic_base + VIC_DEF_VECT_ADDR); | ||
| 81 | |||
| 82 | for (i = 0; i < 32; i++) { | ||
| 83 | unsigned int irq = IRQ_VIC_START + i; | ||
| 84 | |||
| 85 | set_irq_chip(irq, &vic_chip); | ||
| 86 | |||
| 87 | if (vic_sources & (1 << i)) { | ||
| 88 | set_irq_handler(irq, do_level_IRQ); | ||
| 89 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
| 90 | } | ||
| 91 | } | ||
| 92 | } | ||
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index de94b0f3ee2a..2ce0e3a27a45 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
| @@ -20,6 +20,7 @@ obj-$(CONFIG_ARTHUR) += arthur.o | |||
| 20 | obj-$(CONFIG_ISA_DMA) += dma-isa.o | 20 | obj-$(CONFIG_ISA_DMA) += dma-isa.o |
| 21 | obj-$(CONFIG_PCI) += bios32.o | 21 | obj-$(CONFIG_PCI) += bios32.o |
| 22 | obj-$(CONFIG_SMP) += smp.o | 22 | obj-$(CONFIG_SMP) += smp.o |
| 23 | obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o | ||
| 23 | 24 | ||
| 24 | obj-$(CONFIG_IWMMXT) += iwmmxt.o | 25 | obj-$(CONFIG_IWMMXT) += iwmmxt.o |
| 25 | AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt | 26 | AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt |
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 9997098009a9..1574941ebfe1 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c | |||
| @@ -35,6 +35,16 @@ extern void __udivsi3(void); | |||
| 35 | extern void __umodsi3(void); | 35 | extern void __umodsi3(void); |
| 36 | extern void __do_div64(void); | 36 | extern void __do_div64(void); |
| 37 | 37 | ||
| 38 | extern void __aeabi_idiv(void); | ||
| 39 | extern void __aeabi_idivmod(void); | ||
| 40 | extern void __aeabi_lasr(void); | ||
| 41 | extern void __aeabi_llsl(void); | ||
| 42 | extern void __aeabi_llsr(void); | ||
| 43 | extern void __aeabi_lmul(void); | ||
| 44 | extern void __aeabi_uidiv(void); | ||
| 45 | extern void __aeabi_uidivmod(void); | ||
| 46 | extern void __aeabi_ulcmp(void); | ||
| 47 | |||
| 38 | extern void fpundefinstr(void); | 48 | extern void fpundefinstr(void); |
| 39 | extern void fp_enter(void); | 49 | extern void fp_enter(void); |
| 40 | 50 | ||
| @@ -141,6 +151,18 @@ EXPORT_SYMBOL(__udivsi3); | |||
| 141 | EXPORT_SYMBOL(__umodsi3); | 151 | EXPORT_SYMBOL(__umodsi3); |
| 142 | EXPORT_SYMBOL(__do_div64); | 152 | EXPORT_SYMBOL(__do_div64); |
| 143 | 153 | ||
| 154 | #ifdef CONFIG_AEABI | ||
| 155 | EXPORT_SYMBOL(__aeabi_idiv); | ||
| 156 | EXPORT_SYMBOL(__aeabi_idivmod); | ||
| 157 | EXPORT_SYMBOL(__aeabi_lasr); | ||
| 158 | EXPORT_SYMBOL(__aeabi_llsl); | ||
| 159 | EXPORT_SYMBOL(__aeabi_llsr); | ||
| 160 | EXPORT_SYMBOL(__aeabi_lmul); | ||
| 161 | EXPORT_SYMBOL(__aeabi_uidiv); | ||
| 162 | EXPORT_SYMBOL(__aeabi_uidivmod); | ||
| 163 | EXPORT_SYMBOL(__aeabi_ulcmp); | ||
| 164 | #endif | ||
| 165 | |||
| 144 | /* bitops */ | 166 | /* bitops */ |
| 145 | EXPORT_SYMBOL(_set_bit_le); | 167 | EXPORT_SYMBOL(_set_bit_le); |
| 146 | EXPORT_SYMBOL(_test_and_set_bit_le); | 168 | EXPORT_SYMBOL(_test_and_set_bit_le); |
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 55076a75e5bf..75e6f9a94713 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | #define NR_syscalls 328 | 13 | #define NR_syscalls 328 |
| 14 | #else | 14 | #else |
| 15 | 15 | ||
| 16 | __syscall_start: | 16 | 100: |
| 17 | /* 0 */ .long sys_restart_syscall | 17 | /* 0 */ .long sys_restart_syscall |
| 18 | .long sys_exit | 18 | .long sys_exit |
| 19 | .long sys_fork_wrapper | 19 | .long sys_fork_wrapper |
| @@ -27,7 +27,7 @@ __syscall_start: | |||
| 27 | /* 10 */ .long sys_unlink | 27 | /* 10 */ .long sys_unlink |
| 28 | .long sys_execve_wrapper | 28 | .long sys_execve_wrapper |
| 29 | .long sys_chdir | 29 | .long sys_chdir |
| 30 | .long sys_time /* used by libc4 */ | 30 | .long OBSOLETE(sys_time) /* used by libc4 */ |
| 31 | .long sys_mknod | 31 | .long sys_mknod |
| 32 | /* 15 */ .long sys_chmod | 32 | /* 15 */ .long sys_chmod |
| 33 | .long sys_lchown16 | 33 | .long sys_lchown16 |
| @@ -36,15 +36,15 @@ __syscall_start: | |||
| 36 | .long sys_lseek | 36 | .long sys_lseek |
| 37 | /* 20 */ .long sys_getpid | 37 | /* 20 */ .long sys_getpid |
| 38 | .long sys_mount | 38 | .long sys_mount |
| 39 | .long sys_oldumount /* used by libc4 */ | 39 | .long OBSOLETE(sys_oldumount) /* used by libc4 */ |
| 40 | .long sys_setuid16 | 40 | .long sys_setuid16 |
| 41 | .long sys_getuid16 | 41 | .long sys_getuid16 |
| 42 | /* 25 */ .long sys_stime | 42 | /* 25 */ .long OBSOLETE(sys_stime) |
| 43 | .long sys_ptrace | 43 | .long sys_ptrace |
| 44 | .long sys_alarm /* used by libc4 */ | 44 | .long OBSOLETE(sys_alarm) /* used by libc4 */ |
| 45 | .long sys_ni_syscall /* was sys_fstat */ | 45 | .long sys_ni_syscall /* was sys_fstat */ |
| 46 | .long sys_pause | 46 | .long sys_pause |
| 47 | /* 30 */ .long sys_utime /* used by libc4 */ | 47 | /* 30 */ .long OBSOLETE(sys_utime) /* used by libc4 */ |
| 48 | .long sys_ni_syscall /* was sys_stty */ | 48 | .long sys_ni_syscall /* was sys_stty */ |
| 49 | .long sys_ni_syscall /* was sys_getty */ | 49 | .long sys_ni_syscall /* was sys_getty */ |
| 50 | .long sys_access | 50 | .long sys_access |
| @@ -90,21 +90,21 @@ __syscall_start: | |||
| 90 | .long sys_sigpending | 90 | .long sys_sigpending |
| 91 | .long sys_sethostname | 91 | .long sys_sethostname |
| 92 | /* 75 */ .long sys_setrlimit | 92 | /* 75 */ .long sys_setrlimit |
| 93 | .long sys_old_getrlimit /* used by libc4 */ | 93 | .long OBSOLETE(sys_old_getrlimit) /* used by libc4 */ |
| 94 | .long sys_getrusage | 94 | .long sys_getrusage |
| 95 | .long sys_gettimeofday | 95 | .long sys_gettimeofday |
| 96 | .long sys_settimeofday | 96 | .long sys_settimeofday |
| 97 | /* 80 */ .long sys_getgroups16 | 97 | /* 80 */ .long sys_getgroups16 |
| 98 | .long sys_setgroups16 | 98 | .long sys_setgroups16 |
| 99 | .long old_select /* used by libc4 */ | 99 | .long OBSOLETE(old_select) /* used by libc4 */ |
| 100 | .long sys_symlink | 100 | .long sys_symlink |
| 101 | .long sys_ni_syscall /* was sys_lstat */ | 101 | .long sys_ni_syscall /* was sys_lstat */ |
| 102 | /* 85 */ .long sys_readlink | 102 | /* 85 */ .long sys_readlink |
| 103 | .long sys_uselib | 103 | .long sys_uselib |
| 104 | .long sys_swapon | 104 | .long sys_swapon |
| 105 | .long sys_reboot | 105 | .long sys_reboot |
| 106 | .long old_readdir /* used by libc4 */ | 106 | .long OBSOLETE(old_readdir) /* used by libc4 */ |
| 107 | /* 90 */ .long old_mmap /* used by libc4 */ | 107 | /* 90 */ .long OBSOLETE(old_mmap) /* used by libc4 */ |
| 108 | .long sys_munmap | 108 | .long sys_munmap |
| 109 | .long sys_truncate | 109 | .long sys_truncate |
| 110 | .long sys_ftruncate | 110 | .long sys_ftruncate |
| @@ -116,7 +116,7 @@ __syscall_start: | |||
| 116 | .long sys_statfs | 116 | .long sys_statfs |
| 117 | /* 100 */ .long sys_fstatfs | 117 | /* 100 */ .long sys_fstatfs |
| 118 | .long sys_ni_syscall | 118 | .long sys_ni_syscall |
| 119 | .long sys_socketcall | 119 | .long OBSOLETE(sys_socketcall) |
| 120 | .long sys_syslog | 120 | .long sys_syslog |
| 121 | .long sys_setitimer | 121 | .long sys_setitimer |
| 122 | /* 105 */ .long sys_getitimer | 122 | /* 105 */ .long sys_getitimer |
| @@ -127,11 +127,11 @@ __syscall_start: | |||
| 127 | /* 110 */ .long sys_ni_syscall /* was sys_iopl */ | 127 | /* 110 */ .long sys_ni_syscall /* was sys_iopl */ |
| 128 | .long sys_vhangup | 128 | .long sys_vhangup |
| 129 | .long sys_ni_syscall | 129 | .long sys_ni_syscall |
| 130 | .long sys_syscall /* call a syscall */ | 130 | .long OBSOLETE(sys_syscall) /* call a syscall */ |
| 131 | .long sys_wait4 | 131 | .long sys_wait4 |
| 132 | /* 115 */ .long sys_swapoff | 132 | /* 115 */ .long sys_swapoff |
| 133 | .long sys_sysinfo | 133 | .long sys_sysinfo |
| 134 | .long sys_ipc | 134 | .long OBSOLETE(ABI(sys_ipc, sys_oabi_ipc)) |
| 135 | .long sys_fsync | 135 | .long sys_fsync |
| 136 | .long sys_sigreturn_wrapper | 136 | .long sys_sigreturn_wrapper |
| 137 | /* 120 */ .long sys_clone_wrapper | 137 | /* 120 */ .long sys_clone_wrapper |
| @@ -194,8 +194,8 @@ __syscall_start: | |||
| 194 | .long sys_rt_sigtimedwait | 194 | .long sys_rt_sigtimedwait |
| 195 | .long sys_rt_sigqueueinfo | 195 | .long sys_rt_sigqueueinfo |
| 196 | .long sys_rt_sigsuspend_wrapper | 196 | .long sys_rt_sigsuspend_wrapper |
| 197 | /* 180 */ .long sys_pread64 | 197 | /* 180 */ .long ABI(sys_pread64, sys_oabi_pread64) |
| 198 | .long sys_pwrite64 | 198 | .long ABI(sys_pwrite64, sys_oabi_pwrite64) |
| 199 | .long sys_chown16 | 199 | .long sys_chown16 |
| 200 | .long sys_getcwd | 200 | .long sys_getcwd |
| 201 | .long sys_capget | 201 | .long sys_capget |
| @@ -207,11 +207,11 @@ __syscall_start: | |||
| 207 | /* 190 */ .long sys_vfork_wrapper | 207 | /* 190 */ .long sys_vfork_wrapper |
| 208 | .long sys_getrlimit | 208 | .long sys_getrlimit |
| 209 | .long sys_mmap2 | 209 | .long sys_mmap2 |
| 210 | .long sys_truncate64 | 210 | .long ABI(sys_truncate64, sys_oabi_truncate64) |
| 211 | .long sys_ftruncate64 | 211 | .long ABI(sys_ftruncate64, sys_oabi_ftruncate64) |
| 212 | /* 195 */ .long sys_stat64 | 212 | /* 195 */ .long ABI(sys_stat64, sys_oabi_stat64) |
| 213 | .long sys_lstat64 | 213 | .long ABI(sys_lstat64, sys_oabi_lstat64) |
| 214 | .long sys_fstat64 | 214 | .long ABI(sys_fstat64, sys_oabi_fstat64) |
| 215 | .long sys_lchown | 215 | .long sys_lchown |
| 216 | .long sys_getuid | 216 | .long sys_getuid |
| 217 | /* 200 */ .long sys_getgid | 217 | /* 200 */ .long sys_getgid |
| @@ -235,11 +235,11 @@ __syscall_start: | |||
| 235 | .long sys_pivot_root | 235 | .long sys_pivot_root |
| 236 | .long sys_mincore | 236 | .long sys_mincore |
| 237 | /* 220 */ .long sys_madvise | 237 | /* 220 */ .long sys_madvise |
| 238 | .long sys_fcntl64 | 238 | .long ABI(sys_fcntl64, sys_oabi_fcntl64) |
| 239 | .long sys_ni_syscall /* TUX */ | 239 | .long sys_ni_syscall /* TUX */ |
| 240 | .long sys_ni_syscall | 240 | .long sys_ni_syscall |
| 241 | .long sys_gettid | 241 | .long sys_gettid |
| 242 | /* 225 */ .long sys_readahead | 242 | /* 225 */ .long ABI(sys_readahead, sys_oabi_readahead) |
| 243 | .long sys_setxattr | 243 | .long sys_setxattr |
| 244 | .long sys_lsetxattr | 244 | .long sys_lsetxattr |
| 245 | .long sys_fsetxattr | 245 | .long sys_fsetxattr |
| @@ -265,8 +265,8 @@ __syscall_start: | |||
| 265 | .long sys_exit_group | 265 | .long sys_exit_group |
| 266 | .long sys_lookup_dcookie | 266 | .long sys_lookup_dcookie |
| 267 | /* 250 */ .long sys_epoll_create | 267 | /* 250 */ .long sys_epoll_create |
| 268 | .long sys_epoll_ctl | 268 | .long ABI(sys_epoll_ctl, sys_oabi_epoll_ctl) |
| 269 | .long sys_epoll_wait | 269 | .long ABI(sys_epoll_wait, sys_oabi_epoll_wait) |
| 270 | .long sys_remap_file_pages | 270 | .long sys_remap_file_pages |
| 271 | .long sys_ni_syscall /* sys_set_thread_area */ | 271 | .long sys_ni_syscall /* sys_set_thread_area */ |
| 272 | /* 255 */ .long sys_ni_syscall /* sys_get_thread_area */ | 272 | /* 255 */ .long sys_ni_syscall /* sys_get_thread_area */ |
| @@ -280,8 +280,8 @@ __syscall_start: | |||
| 280 | .long sys_clock_gettime | 280 | .long sys_clock_gettime |
| 281 | .long sys_clock_getres | 281 | .long sys_clock_getres |
| 282 | /* 265 */ .long sys_clock_nanosleep | 282 | /* 265 */ .long sys_clock_nanosleep |
| 283 | .long sys_statfs64 | 283 | .long sys_statfs64_wrapper |
| 284 | .long sys_fstatfs64 | 284 | .long sys_fstatfs64_wrapper |
| 285 | .long sys_tgkill | 285 | .long sys_tgkill |
| 286 | .long sys_utimes | 286 | .long sys_utimes |
| 287 | /* 270 */ .long sys_arm_fadvise64_64 | 287 | /* 270 */ .long sys_arm_fadvise64_64 |
| @@ -312,7 +312,7 @@ __syscall_start: | |||
| 312 | /* 295 */ .long sys_getsockopt | 312 | /* 295 */ .long sys_getsockopt |
| 313 | .long sys_sendmsg | 313 | .long sys_sendmsg |
| 314 | .long sys_recvmsg | 314 | .long sys_recvmsg |
| 315 | .long sys_semop | 315 | .long ABI(sys_semop, sys_oabi_semop) |
| 316 | .long sys_semget | 316 | .long sys_semget |
| 317 | /* 300 */ .long sys_semctl | 317 | /* 300 */ .long sys_semctl |
| 318 | .long sys_msgsnd | 318 | .long sys_msgsnd |
| @@ -326,7 +326,7 @@ __syscall_start: | |||
| 326 | .long sys_add_key | 326 | .long sys_add_key |
| 327 | /* 310 */ .long sys_request_key | 327 | /* 310 */ .long sys_request_key |
| 328 | .long sys_keyctl | 328 | .long sys_keyctl |
| 329 | .long sys_semtimedop | 329 | .long ABI(sys_semtimedop, sys_oabi_semtimedop) |
| 330 | /* vserver */ .long sys_ni_syscall | 330 | /* vserver */ .long sys_ni_syscall |
| 331 | .long sys_ioprio_set | 331 | .long sys_ioprio_set |
| 332 | /* 315 */ .long sys_ioprio_get | 332 | /* 315 */ .long sys_ioprio_get |
| @@ -336,9 +336,8 @@ __syscall_start: | |||
| 336 | .long sys_mbind | 336 | .long sys_mbind |
| 337 | /* 320 */ .long sys_get_mempolicy | 337 | /* 320 */ .long sys_get_mempolicy |
| 338 | .long sys_set_mempolicy | 338 | .long sys_set_mempolicy |
| 339 | __syscall_end: | ||
| 340 | 339 | ||
| 341 | .rept NR_syscalls - (__syscall_end - __syscall_start) / 4 | 340 | .rept NR_syscalls - (. - 100b) / 4 |
| 342 | .long sys_ni_syscall | 341 | .long sys_ni_syscall |
| 343 | .endr | 342 | .endr |
| 344 | #endif | 343 | #endif |
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index 96fd91926c9b..74ea29c3205e 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c | |||
| @@ -1147,9 +1147,11 @@ static void ecard_drv_shutdown(struct device *dev) | |||
| 1147 | struct ecard_driver *drv = ECARD_DRV(dev->driver); | 1147 | struct ecard_driver *drv = ECARD_DRV(dev->driver); |
| 1148 | struct ecard_request req; | 1148 | struct ecard_request req; |
| 1149 | 1149 | ||
| 1150 | if (drv->shutdown) | 1150 | if (dev->driver) { |
| 1151 | drv->shutdown(ec); | 1151 | if (drv->shutdown) |
| 1152 | ecard_release(ec); | 1152 | drv->shutdown(ec); |
| 1153 | ecard_release(ec); | ||
| 1154 | } | ||
| 1153 | 1155 | ||
| 1154 | /* | 1156 | /* |
| 1155 | * If this card has a loader, call the reset handler. | 1157 | * If this card has a loader, call the reset handler. |
| @@ -1164,9 +1166,6 @@ static void ecard_drv_shutdown(struct device *dev) | |||
| 1164 | int ecard_register_driver(struct ecard_driver *drv) | 1166 | int ecard_register_driver(struct ecard_driver *drv) |
| 1165 | { | 1167 | { |
| 1166 | drv->drv.bus = &ecard_bus_type; | 1168 | drv->drv.bus = &ecard_bus_type; |
| 1167 | drv->drv.probe = ecard_drv_probe; | ||
| 1168 | drv->drv.remove = ecard_drv_remove; | ||
| 1169 | drv->drv.shutdown = ecard_drv_shutdown; | ||
| 1170 | 1169 | ||
| 1171 | return driver_register(&drv->drv); | 1170 | return driver_register(&drv->drv); |
| 1172 | } | 1171 | } |
| @@ -1195,6 +1194,9 @@ struct bus_type ecard_bus_type = { | |||
| 1195 | .name = "ecard", | 1194 | .name = "ecard", |
| 1196 | .dev_attrs = ecard_dev_attrs, | 1195 | .dev_attrs = ecard_dev_attrs, |
| 1197 | .match = ecard_match, | 1196 | .match = ecard_match, |
| 1197 | .probe = ecard_drv_probe, | ||
| 1198 | .remove = ecard_drv_remove, | ||
| 1199 | .shutdown = ecard_drv_shutdown, | ||
| 1198 | }; | 1200 | }; |
| 1199 | 1201 | ||
| 1200 | static int ecard_bus_init(void) | 1202 | static int ecard_bus_init(void) |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index a52baedf6262..874e6bb79405 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * Copyright (C) 1996,1997,1998 Russell King. | 4 | * Copyright (C) 1996,1997,1998 Russell King. |
| 5 | * ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk) | 5 | * ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk) |
| 6 | * nommu support by Hyok S. Choi (hyok.choi@samsung.com) | ||
| 6 | * | 7 | * |
| 7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
| @@ -104,14 +105,24 @@ common_invalid: | |||
| 104 | /* | 105 | /* |
| 105 | * SVC mode handlers | 106 | * SVC mode handlers |
| 106 | */ | 107 | */ |
| 108 | |||
| 109 | #if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) | ||
| 110 | #define SPFIX(code...) code | ||
| 111 | #else | ||
| 112 | #define SPFIX(code...) | ||
| 113 | #endif | ||
| 114 | |||
| 107 | .macro svc_entry | 115 | .macro svc_entry |
| 108 | sub sp, sp, #S_FRAME_SIZE | 116 | sub sp, sp, #S_FRAME_SIZE |
| 117 | SPFIX( tst sp, #4 ) | ||
| 118 | SPFIX( bicne sp, sp, #4 ) | ||
| 109 | stmib sp, {r1 - r12} | 119 | stmib sp, {r1 - r12} |
| 110 | 120 | ||
| 111 | ldmia r0, {r1 - r3} | 121 | ldmia r0, {r1 - r3} |
| 112 | add r5, sp, #S_SP @ here for interlock avoidance | 122 | add r5, sp, #S_SP @ here for interlock avoidance |
| 113 | mov r4, #-1 @ "" "" "" "" | 123 | mov r4, #-1 @ "" "" "" "" |
| 114 | add r0, sp, #S_FRAME_SIZE @ "" "" "" "" | 124 | add r0, sp, #S_FRAME_SIZE @ "" "" "" "" |
| 125 | SPFIX( addne r0, r0, #4 ) | ||
| 115 | str r1, [sp] @ save the "real" r0 copied | 126 | str r1, [sp] @ save the "real" r0 copied |
| 116 | @ from the exception stack | 127 | @ from the exception stack |
| 117 | 128 | ||
| @@ -302,7 +313,14 @@ __pabt_svc: | |||
| 302 | 313 | ||
| 303 | /* | 314 | /* |
| 304 | * User mode handlers | 315 | * User mode handlers |
| 316 | * | ||
| 317 | * EABI note: sp_svc is always 64-bit aligned here, so should S_FRAME_SIZE | ||
| 305 | */ | 318 | */ |
| 319 | |||
| 320 | #if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) && (S_FRAME_SIZE & 7) | ||
| 321 | #error "sizeof(struct pt_regs) must be a multiple of 8" | ||
| 322 | #endif | ||
| 323 | |||
| 306 | .macro usr_entry | 324 | .macro usr_entry |
| 307 | sub sp, sp, #S_FRAME_SIZE | 325 | sub sp, sp, #S_FRAME_SIZE |
| 308 | stmib sp, {r1 - r12} | 326 | stmib sp, {r1 - r12} |
| @@ -538,7 +556,11 @@ ENTRY(__switch_to) | |||
| 538 | add ip, r1, #TI_CPU_SAVE | 556 | add ip, r1, #TI_CPU_SAVE |
| 539 | ldr r3, [r2, #TI_TP_VALUE] | 557 | ldr r3, [r2, #TI_TP_VALUE] |
| 540 | stmia ip!, {r4 - sl, fp, sp, lr} @ Store most regs on stack | 558 | stmia ip!, {r4 - sl, fp, sp, lr} @ Store most regs on stack |
| 559 | #ifndef CONFIG_MMU | ||
| 560 | add r2, r2, #TI_CPU_DOMAIN | ||
| 561 | #else | ||
| 541 | ldr r6, [r2, #TI_CPU_DOMAIN]! | 562 | ldr r6, [r2, #TI_CPU_DOMAIN]! |
| 563 | #endif | ||
| 542 | #if __LINUX_ARM_ARCH__ >= 6 | 564 | #if __LINUX_ARM_ARCH__ >= 6 |
| 543 | #ifdef CONFIG_CPU_MPCORE | 565 | #ifdef CONFIG_CPU_MPCORE |
| 544 | clrex | 566 | clrex |
| @@ -556,7 +578,9 @@ ENTRY(__switch_to) | |||
| 556 | mov r4, #0xffff0fff | 578 | mov r4, #0xffff0fff |
| 557 | str r3, [r4, #-15] @ TLS val at 0xffff0ff0 | 579 | str r3, [r4, #-15] @ TLS val at 0xffff0ff0 |
| 558 | #endif | 580 | #endif |
| 581 | #ifdef CONFIG_MMU | ||
| 559 | mcr p15, 0, r6, c3, c0, 0 @ Set domain register | 582 | mcr p15, 0, r6, c3, c0, 0 @ Set domain register |
| 583 | #endif | ||
| 560 | #ifdef CONFIG_VFP | 584 | #ifdef CONFIG_VFP |
| 561 | @ Always disable VFP so we can lazily save/restore the old | 585 | @ Always disable VFP so we can lazily save/restore the old |
| 562 | @ state. This occurs in the context of the previous thread. | 586 | @ state. This occurs in the context of the previous thread. |
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index e2b42997ad33..2b92ce85f97f 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
| @@ -98,20 +98,14 @@ ENTRY(ret_from_fork) | |||
| 98 | run on an ARM7 and we can save a couple of instructions. | 98 | run on an ARM7 and we can save a couple of instructions. |
| 99 | --pb */ | 99 | --pb */ |
| 100 | #ifdef CONFIG_CPU_ARM710 | 100 | #ifdef CONFIG_CPU_ARM710 |
| 101 | .macro arm710_bug_check, instr, temp | 101 | #define A710(code...) code |
| 102 | and \temp, \instr, #0x0f000000 @ check for SWI | 102 | .Larm710bug: |
| 103 | teq \temp, #0x0f000000 | ||
| 104 | bne .Larm700bug | ||
| 105 | .endm | ||
| 106 | |||
| 107 | .Larm700bug: | ||
| 108 | ldmia sp, {r0 - lr}^ @ Get calling r0 - lr | 103 | ldmia sp, {r0 - lr}^ @ Get calling r0 - lr |
| 109 | mov r0, r0 | 104 | mov r0, r0 |
| 110 | add sp, sp, #S_FRAME_SIZE | 105 | add sp, sp, #S_FRAME_SIZE |
| 111 | subs pc, lr, #4 | 106 | subs pc, lr, #4 |
| 112 | #else | 107 | #else |
| 113 | .macro arm710_bug_check, instr, temp | 108 | #define A710(code...) |
| 114 | .endm | ||
| 115 | #endif | 109 | #endif |
| 116 | 110 | ||
| 117 | .align 5 | 111 | .align 5 |
| @@ -129,14 +123,50 @@ ENTRY(vector_swi) | |||
| 129 | /* | 123 | /* |
| 130 | * Get the system call number. | 124 | * Get the system call number. |
| 131 | */ | 125 | */ |
| 126 | |||
| 127 | #if defined(CONFIG_OABI_COMPAT) | ||
| 128 | |||
| 129 | /* | ||
| 130 | * If we have CONFIG_OABI_COMPAT then we need to look at the swi | ||
| 131 | * value to determine if it is an EABI or an old ABI call. | ||
| 132 | */ | ||
| 132 | #ifdef CONFIG_ARM_THUMB | 133 | #ifdef CONFIG_ARM_THUMB |
| 134 | tst r8, #PSR_T_BIT | ||
| 135 | movne r10, #0 @ no thumb OABI emulation | ||
| 136 | ldreq r10, [lr, #-4] @ get SWI instruction | ||
| 137 | #else | ||
| 138 | ldr r10, [lr, #-4] @ get SWI instruction | ||
| 139 | A710( and ip, r10, #0x0f000000 @ check for SWI ) | ||
| 140 | A710( teq ip, #0x0f000000 ) | ||
| 141 | A710( bne .Larm710bug ) | ||
| 142 | #endif | ||
| 143 | |||
| 144 | #elif defined(CONFIG_AEABI) | ||
| 145 | |||
| 146 | /* | ||
| 147 | * Pure EABI user space always put syscall number into scno (r7). | ||
| 148 | */ | ||
| 149 | A710( ldr ip, [lr, #-4] @ get SWI instruction ) | ||
| 150 | A710( and ip, ip, #0x0f000000 @ check for SWI ) | ||
| 151 | A710( teq ip, #0x0f000000 ) | ||
| 152 | A710( bne .Larm710bug ) | ||
| 153 | |||
| 154 | #elif defined(CONFIG_ARM_THUMB) | ||
| 155 | |||
| 156 | /* Legacy ABI only, possibly thumb mode. */ | ||
| 133 | tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs | 157 | tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs |
| 134 | addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in | 158 | addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in |
| 135 | ldreq scno, [lr, #-4] | 159 | ldreq scno, [lr, #-4] |
| 160 | |||
| 136 | #else | 161 | #else |
| 162 | |||
| 163 | /* Legacy ABI only. */ | ||
| 137 | ldr scno, [lr, #-4] @ get SWI instruction | 164 | ldr scno, [lr, #-4] @ get SWI instruction |
| 165 | A710( and ip, scno, #0x0f000000 @ check for SWI ) | ||
| 166 | A710( teq ip, #0x0f000000 ) | ||
| 167 | A710( bne .Larm710bug ) | ||
| 168 | |||
| 138 | #endif | 169 | #endif |
| 139 | arm710_bug_check scno, ip | ||
| 140 | 170 | ||
| 141 | #ifdef CONFIG_ALIGNMENT_TRAP | 171 | #ifdef CONFIG_ALIGNMENT_TRAP |
| 142 | ldr ip, __cr_alignment | 172 | ldr ip, __cr_alignment |
| @@ -145,18 +175,31 @@ ENTRY(vector_swi) | |||
| 145 | #endif | 175 | #endif |
| 146 | enable_irq | 176 | enable_irq |
| 147 | 177 | ||
| 148 | stmdb sp!, {r4, r5} @ push fifth and sixth args | ||
| 149 | |||
| 150 | get_thread_info tsk | 178 | get_thread_info tsk |
| 179 | adr tbl, sys_call_table @ load syscall table pointer | ||
| 151 | ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing | 180 | ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing |
| 181 | |||
| 182 | #if defined(CONFIG_OABI_COMPAT) | ||
| 183 | /* | ||
| 184 | * If the swi argument is zero, this is an EABI call and we do nothing. | ||
| 185 | * | ||
| 186 | * If this is an old ABI call, get the syscall number into scno and | ||
| 187 | * get the old ABI syscall table address. | ||
| 188 | */ | ||
| 189 | bics r10, r10, #0xff000000 | ||
| 190 | eorne scno, r10, #__NR_OABI_SYSCALL_BASE | ||
| 191 | ldrne tbl, =sys_oabi_call_table | ||
| 192 | #elif !defined(CONFIG_AEABI) | ||
| 152 | bic scno, scno, #0xff000000 @ mask off SWI op-code | 193 | bic scno, scno, #0xff000000 @ mask off SWI op-code |
| 153 | eor scno, scno, #__NR_SYSCALL_BASE @ check OS number | 194 | eor scno, scno, #__NR_SYSCALL_BASE @ check OS number |
| 154 | adr tbl, sys_call_table @ load syscall table pointer | 195 | #endif |
| 196 | |||
| 197 | stmdb sp!, {r4, r5} @ push fifth and sixth args | ||
| 155 | tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? | 198 | tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? |
| 156 | bne __sys_trace | 199 | bne __sys_trace |
| 157 | 200 | ||
| 158 | adr lr, ret_fast_syscall @ return address | ||
| 159 | cmp scno, #NR_syscalls @ check upper syscall limit | 201 | cmp scno, #NR_syscalls @ check upper syscall limit |
| 202 | adr lr, ret_fast_syscall @ return address | ||
| 160 | ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine | 203 | ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine |
| 161 | 204 | ||
| 162 | add r1, sp, #S_OFF | 205 | add r1, sp, #S_OFF |
| @@ -171,11 +214,13 @@ ENTRY(vector_swi) | |||
| 171 | * context switches, and waiting for our parent to respond. | 214 | * context switches, and waiting for our parent to respond. |
| 172 | */ | 215 | */ |
| 173 | __sys_trace: | 216 | __sys_trace: |
| 217 | mov r2, scno | ||
| 174 | add r1, sp, #S_OFF | 218 | add r1, sp, #S_OFF |
| 175 | mov r0, #0 @ trace entry [IP = 0] | 219 | mov r0, #0 @ trace entry [IP = 0] |
| 176 | bl syscall_trace | 220 | bl syscall_trace |
| 177 | 221 | ||
| 178 | adr lr, __sys_trace_return @ return address | 222 | adr lr, __sys_trace_return @ return address |
| 223 | mov scno, r0 @ syscall number (possibly new) | ||
| 179 | add r1, sp, #S_R0 + S_OFF @ pointer to regs | 224 | add r1, sp, #S_R0 + S_OFF @ pointer to regs |
| 180 | cmp scno, #NR_syscalls @ check upper syscall limit | 225 | cmp scno, #NR_syscalls @ check upper syscall limit |
| 181 | ldmccia r1, {r0 - r3} @ have to reload r0 - r3 | 226 | ldmccia r1, {r0 - r3} @ have to reload r0 - r3 |
| @@ -184,6 +229,7 @@ __sys_trace: | |||
| 184 | 229 | ||
| 185 | __sys_trace_return: | 230 | __sys_trace_return: |
| 186 | str r0, [sp, #S_R0 + S_OFF]! @ save returned r0 | 231 | str r0, [sp, #S_R0 + S_OFF]! @ save returned r0 |
| 232 | mov r2, scno | ||
| 187 | mov r1, sp | 233 | mov r1, sp |
| 188 | mov r0, #1 @ trace exit [IP = 1] | 234 | mov r0, #1 @ trace exit [IP = 1] |
| 189 | bl syscall_trace | 235 | bl syscall_trace |
| @@ -195,10 +241,24 @@ __sys_trace_return: | |||
| 195 | __cr_alignment: | 241 | __cr_alignment: |
| 196 | .word cr_alignment | 242 | .word cr_alignment |
| 197 | #endif | 243 | #endif |
| 244 | .ltorg | ||
| 245 | |||
| 246 | /* | ||
| 247 | * This is the syscall table declaration for native ABI syscalls. | ||
| 248 | * With EABI a couple syscalls are obsolete and defined as sys_ni_syscall. | ||
| 249 | */ | ||
| 250 | #define ABI(native, compat) native | ||
| 251 | #ifdef CONFIG_AEABI | ||
| 252 | #define OBSOLETE(syscall) sys_ni_syscall | ||
| 253 | #else | ||
| 254 | #define OBSOLETE(syscall) syscall | ||
| 255 | #endif | ||
| 198 | 256 | ||
| 199 | .type sys_call_table, #object | 257 | .type sys_call_table, #object |
| 200 | ENTRY(sys_call_table) | 258 | ENTRY(sys_call_table) |
| 201 | #include "calls.S" | 259 | #include "calls.S" |
| 260 | #undef ABI | ||
| 261 | #undef OBSOLETE | ||
| 202 | 262 | ||
| 203 | /*============================================================================ | 263 | /*============================================================================ |
| 204 | * Special system call wrappers | 264 | * Special system call wrappers |
| @@ -207,7 +267,7 @@ ENTRY(sys_call_table) | |||
| 207 | @ r8 = syscall table | 267 | @ r8 = syscall table |
| 208 | .type sys_syscall, #function | 268 | .type sys_syscall, #function |
| 209 | sys_syscall: | 269 | sys_syscall: |
| 210 | eor scno, r0, #__NR_SYSCALL_BASE | 270 | eor scno, r0, #__NR_OABI_SYSCALL_BASE |
| 211 | cmp scno, #__NR_syscall - __NR_SYSCALL_BASE | 271 | cmp scno, #__NR_syscall - __NR_SYSCALL_BASE |
| 212 | cmpne scno, #NR_syscalls @ check range | 272 | cmpne scno, #NR_syscalls @ check range |
| 213 | stmloia sp, {r5, r6} @ shuffle args | 273 | stmloia sp, {r5, r6} @ shuffle args |
| @@ -255,6 +315,16 @@ sys_sigaltstack_wrapper: | |||
| 255 | ldr r2, [sp, #S_OFF + S_SP] | 315 | ldr r2, [sp, #S_OFF + S_SP] |
| 256 | b do_sigaltstack | 316 | b do_sigaltstack |
| 257 | 317 | ||
| 318 | sys_statfs64_wrapper: | ||
| 319 | teq r1, #88 | ||
| 320 | moveq r1, #84 | ||
| 321 | b sys_statfs64 | ||
| 322 | |||
| 323 | sys_fstatfs64_wrapper: | ||
| 324 | teq r1, #88 | ||
| 325 | moveq r1, #84 | ||
| 326 | b sys_fstatfs64 | ||
| 327 | |||
| 258 | /* | 328 | /* |
| 259 | * Note: off_4k (r5) is always units of 4K. If we can't do the requested | 329 | * Note: off_4k (r5) is always units of 4K. If we can't do the requested |
| 260 | * offset, we return EINVAL. | 330 | * offset, we return EINVAL. |
| @@ -271,3 +341,49 @@ sys_mmap2: | |||
| 271 | str r5, [sp, #4] | 341 | str r5, [sp, #4] |
| 272 | b do_mmap2 | 342 | b do_mmap2 |
| 273 | #endif | 343 | #endif |
| 344 | |||
| 345 | #ifdef CONFIG_OABI_COMPAT | ||
| 346 | |||
| 347 | /* | ||
| 348 | * These are syscalls with argument register differences | ||
| 349 | */ | ||
| 350 | |||
| 351 | sys_oabi_pread64: | ||
| 352 | stmia sp, {r3, r4} | ||
| 353 | b sys_pread64 | ||
| 354 | |||
| 355 | sys_oabi_pwrite64: | ||
| 356 | stmia sp, {r3, r4} | ||
| 357 | b sys_pwrite64 | ||
| 358 | |||
| 359 | sys_oabi_truncate64: | ||
| 360 | mov r3, r2 | ||
| 361 | mov r2, r1 | ||
| 362 | b sys_truncate64 | ||
| 363 | |||
| 364 | sys_oabi_ftruncate64: | ||
| 365 | mov r3, r2 | ||
| 366 | mov r2, r1 | ||
| 367 | b sys_ftruncate64 | ||
| 368 | |||
| 369 | sys_oabi_readahead: | ||
| 370 | str r3, [sp] | ||
| 371 | mov r3, r2 | ||
| 372 | mov r2, r1 | ||
| 373 | b sys_readahead | ||
| 374 | |||
| 375 | /* | ||
| 376 | * Let's declare a second syscall table for old ABI binaries | ||
| 377 | * using the compatibility syscall entries. | ||
| 378 | */ | ||
| 379 | #define ABI(native, compat) compat | ||
| 380 | #define OBSOLETE(syscall) syscall | ||
| 381 | |||
| 382 | .type sys_oabi_call_table, #object | ||
| 383 | ENTRY(sys_oabi_call_table) | ||
| 384 | #include "calls.S" | ||
| 385 | #undef ABI | ||
| 386 | #undef OBSOLETE | ||
| 387 | |||
| 388 | #endif | ||
| 389 | |||
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index 648cfff93138..55c99cdab7d6 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | @ | 19 | @ |
| 20 | @ Most of the stack format comes from struct pt_regs, but with | 20 | @ Most of the stack format comes from struct pt_regs, but with |
| 21 | @ the addition of 8 bytes for storing syscall args 5 and 6. | 21 | @ the addition of 8 bytes for storing syscall args 5 and 6. |
| 22 | @ This _must_ remain a multiple of 8 for EABI. | ||
| 22 | @ | 23 | @ |
| 23 | #define S_OFF 8 | 24 | #define S_OFF 8 |
| 24 | 25 | ||
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 1e985f2cd70f..1aca1775b28f 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S | |||
| @@ -251,12 +251,11 @@ __turn_mmu_on: | |||
| 251 | * r10 = procinfo | 251 | * r10 = procinfo |
| 252 | * | 252 | * |
| 253 | * Returns: | 253 | * Returns: |
| 254 | * r0, r3, r5, r6, r7 corrupted | 254 | * r0, r3, r6, r7 corrupted |
| 255 | * r4 = physical page table address | 255 | * r4 = physical page table address |
| 256 | */ | 256 | */ |
| 257 | .type __create_page_tables, %function | 257 | .type __create_page_tables, %function |
| 258 | __create_page_tables: | 258 | __create_page_tables: |
| 259 | ldr r5, [r8, #MACHINFO_PHYSRAM] @ physram | ||
| 260 | pgtbl r4 @ page table address | 259 | pgtbl r4 @ page table address |
| 261 | 260 | ||
| 262 | /* | 261 | /* |
| @@ -303,7 +302,7 @@ __create_page_tables: | |||
| 303 | * Then map first 1MB of ram in case it contains our boot params. | 302 | * Then map first 1MB of ram in case it contains our boot params. |
| 304 | */ | 303 | */ |
| 305 | add r0, r4, #PAGE_OFFSET >> 18 | 304 | add r0, r4, #PAGE_OFFSET >> 18 |
| 306 | orr r6, r5, r7 | 305 | orr r6, r7, #PHYS_OFFSET |
| 307 | str r6, [r0] | 306 | str r6, [r0] |
| 308 | 307 | ||
| 309 | #ifdef CONFIG_XIP_KERNEL | 308 | #ifdef CONFIG_XIP_KERNEL |
| @@ -311,7 +310,7 @@ __create_page_tables: | |||
| 311 | * Map some ram to cover our .data and .bss areas. | 310 | * Map some ram to cover our .data and .bss areas. |
| 312 | * Mapping 3MB should be plenty. | 311 | * Mapping 3MB should be plenty. |
| 313 | */ | 312 | */ |
| 314 | sub r3, r4, r5 | 313 | sub r3, r4, #PHYS_OFFSET |
| 315 | mov r3, r3, lsr #20 | 314 | mov r3, r3, lsr #20 |
| 316 | add r0, r0, r3, lsl #2 | 315 | add r0, r0, r3, lsl #2 |
| 317 | add r6, r6, r3, lsl #20 | 316 | add r6, r6, r3, lsl #20 |
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index e591f72bcdeb..7b6256bb590e 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
| @@ -766,6 +766,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
| 766 | (unsigned long __user *) data); | 766 | (unsigned long __user *) data); |
| 767 | break; | 767 | break; |
| 768 | 768 | ||
| 769 | case PTRACE_SET_SYSCALL: | ||
| 770 | ret = 0; | ||
| 771 | child->ptrace_message = data; | ||
| 772 | break; | ||
| 773 | |||
| 769 | default: | 774 | default: |
| 770 | ret = ptrace_request(child, request, addr, data); | 775 | ret = ptrace_request(child, request, addr, data); |
| 771 | break; | 776 | break; |
| @@ -774,14 +779,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
| 774 | return ret; | 779 | return ret; |
| 775 | } | 780 | } |
| 776 | 781 | ||
| 777 | asmlinkage void syscall_trace(int why, struct pt_regs *regs) | 782 | asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) |
| 778 | { | 783 | { |
| 779 | unsigned long ip; | 784 | unsigned long ip; |
| 780 | 785 | ||
| 781 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | 786 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
| 782 | return; | 787 | return scno; |
| 783 | if (!(current->ptrace & PT_PTRACED)) | 788 | if (!(current->ptrace & PT_PTRACED)) |
| 784 | return; | 789 | return scno; |
| 785 | 790 | ||
| 786 | /* | 791 | /* |
| 787 | * Save IP. IP is used to denote syscall entry/exit: | 792 | * Save IP. IP is used to denote syscall entry/exit: |
| @@ -790,6 +795,8 @@ asmlinkage void syscall_trace(int why, struct pt_regs *regs) | |||
| 790 | ip = regs->ARM_ip; | 795 | ip = regs->ARM_ip; |
| 791 | regs->ARM_ip = why; | 796 | regs->ARM_ip = why; |
| 792 | 797 | ||
| 798 | current->ptrace_message = scno; | ||
| 799 | |||
| 793 | /* the 0x80 provides a way for the tracing parent to distinguish | 800 | /* the 0x80 provides a way for the tracing parent to distinguish |
| 794 | between a syscall stop and SIGTRAP delivery */ | 801 | between a syscall stop and SIGTRAP delivery */ |
| 795 | ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) | 802 | ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) |
| @@ -804,4 +811,6 @@ asmlinkage void syscall_trace(int why, struct pt_regs *regs) | |||
| 804 | current->exit_code = 0; | 811 | current->exit_code = 0; |
| 805 | } | 812 | } |
| 806 | regs->ARM_ip = ip; | 813 | regs->ARM_ip = ip; |
| 814 | |||
| 815 | return current->ptrace_message; | ||
| 807 | } | 816 | } |
diff --git a/arch/arm/kernel/semaphore.c b/arch/arm/kernel/semaphore.c index 4c31f2923055..981fe5c6ccbe 100644 --- a/arch/arm/kernel/semaphore.c +++ b/arch/arm/kernel/semaphore.c | |||
| @@ -177,41 +177,42 @@ int __down_trylock(struct semaphore * sem) | |||
| 177 | * ip contains the semaphore pointer on entry. Save the C-clobbered | 177 | * ip contains the semaphore pointer on entry. Save the C-clobbered |
| 178 | * registers (r0 to r3 and lr), but not ip, as we use it as a return | 178 | * registers (r0 to r3 and lr), but not ip, as we use it as a return |
| 179 | * value in some cases.. | 179 | * value in some cases.. |
| 180 | * To remain AAPCS compliant (64-bit stack align) we save r4 as well. | ||
| 180 | */ | 181 | */ |
| 181 | asm(" .section .sched.text,\"ax\",%progbits \n\ | 182 | asm(" .section .sched.text,\"ax\",%progbits \n\ |
| 182 | .align 5 \n\ | 183 | .align 5 \n\ |
| 183 | .globl __down_failed \n\ | 184 | .globl __down_failed \n\ |
| 184 | __down_failed: \n\ | 185 | __down_failed: \n\ |
| 185 | stmfd sp!, {r0 - r3, lr} \n\ | 186 | stmfd sp!, {r0 - r4, lr} \n\ |
| 186 | mov r0, ip \n\ | 187 | mov r0, ip \n\ |
| 187 | bl __down \n\ | 188 | bl __down \n\ |
| 188 | ldmfd sp!, {r0 - r3, pc} \n\ | 189 | ldmfd sp!, {r0 - r4, pc} \n\ |
| 189 | \n\ | 190 | \n\ |
| 190 | .align 5 \n\ | 191 | .align 5 \n\ |
| 191 | .globl __down_interruptible_failed \n\ | 192 | .globl __down_interruptible_failed \n\ |
| 192 | __down_interruptible_failed: \n\ | 193 | __down_interruptible_failed: \n\ |
| 193 | stmfd sp!, {r0 - r3, lr} \n\ | 194 | stmfd sp!, {r0 - r4, lr} \n\ |
| 194 | mov r0, ip \n\ | 195 | mov r0, ip \n\ |
| 195 | bl __down_interruptible \n\ | 196 | bl __down_interruptible \n\ |
| 196 | mov ip, r0 \n\ | 197 | mov ip, r0 \n\ |
| 197 | ldmfd sp!, {r0 - r3, pc} \n\ | 198 | ldmfd sp!, {r0 - r4, pc} \n\ |
| 198 | \n\ | 199 | \n\ |
| 199 | .align 5 \n\ | 200 | .align 5 \n\ |
| 200 | .globl __down_trylock_failed \n\ | 201 | .globl __down_trylock_failed \n\ |
| 201 | __down_trylock_failed: \n\ | 202 | __down_trylock_failed: \n\ |
| 202 | stmfd sp!, {r0 - r3, lr} \n\ | 203 | stmfd sp!, {r0 - r4, lr} \n\ |
| 203 | mov r0, ip \n\ | 204 | mov r0, ip \n\ |
| 204 | bl __down_trylock \n\ | 205 | bl __down_trylock \n\ |
| 205 | mov ip, r0 \n\ | 206 | mov ip, r0 \n\ |
| 206 | ldmfd sp!, {r0 - r3, pc} \n\ | 207 | ldmfd sp!, {r0 - r4, pc} \n\ |
| 207 | \n\ | 208 | \n\ |
| 208 | .align 5 \n\ | 209 | .align 5 \n\ |
| 209 | .globl __up_wakeup \n\ | 210 | .globl __up_wakeup \n\ |
| 210 | __up_wakeup: \n\ | 211 | __up_wakeup: \n\ |
| 211 | stmfd sp!, {r0 - r3, lr} \n\ | 212 | stmfd sp!, {r0 - r4, lr} \n\ |
| 212 | mov r0, ip \n\ | 213 | mov r0, ip \n\ |
| 213 | bl __up \n\ | 214 | bl __up \n\ |
| 214 | ldmfd sp!, {r0 - r3, pc} \n\ | 215 | ldmfd sp!, {r0 - r4, pc} \n\ |
| 215 | "); | 216 | "); |
| 216 | 217 | ||
| 217 | EXPORT_SYMBOL(__down_failed); | 218 | EXPORT_SYMBOL(__down_failed); |
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index ea569ba482b1..a491de2d9024 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c | |||
| @@ -147,6 +147,7 @@ asmlinkage int old_select(struct sel_arg_struct __user *arg) | |||
| 147 | return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp); | 147 | return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp); |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | #if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT) | ||
| 150 | /* | 151 | /* |
| 151 | * sys_ipc() is the de-multiplexer for the SysV IPC calls.. | 152 | * sys_ipc() is the de-multiplexer for the SysV IPC calls.. |
| 152 | * | 153 | * |
| @@ -226,6 +227,7 @@ asmlinkage int sys_ipc(uint call, int first, int second, int third, | |||
| 226 | return -ENOSYS; | 227 | return -ENOSYS; |
| 227 | } | 228 | } |
| 228 | } | 229 | } |
| 230 | #endif | ||
| 229 | 231 | ||
| 230 | /* Fork a new task - this creates a new program thread. | 232 | /* Fork a new task - this creates a new program thread. |
| 231 | * This is called indirectly via a small wrapper | 233 | * This is called indirectly via a small wrapper |
diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c new file mode 100644 index 000000000000..eafa8e5284af --- /dev/null +++ b/arch/arm/kernel/sys_oabi-compat.c | |||
| @@ -0,0 +1,339 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/kernel/sys_oabi-compat.c | ||
| 3 | * | ||
| 4 | * Compatibility wrappers for syscalls that are used from | ||
| 5 | * old ABI user space binaries with an EABI kernel. | ||
| 6 | * | ||
| 7 | * Author: Nicolas Pitre | ||
| 8 | * Created: Oct 7, 2005 | ||
| 9 | * Copyright: MontaVista Software, Inc. | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License version 2 as | ||
| 13 | * published by the Free Software Foundation. | ||
| 14 | */ | ||
| 15 | |||
| 16 | /* | ||
| 17 | * The legacy ABI and the new ARM EABI have different rules making some | ||
| 18 | * syscalls incompatible especially with structure arguments. | ||
| 19 | * Most notably, Eabi says 64-bit members should be 64-bit aligned instead of | ||
| 20 | * simply word aligned. EABI also pads structures to the size of the largest | ||
| 21 | * member it contains instead of the invariant 32-bit. | ||
| 22 | * | ||
| 23 | * The following syscalls are affected: | ||
| 24 | * | ||
| 25 | * sys_stat64: | ||
| 26 | * sys_lstat64: | ||
| 27 | * sys_fstat64: | ||
| 28 | * | ||
| 29 | * struct stat64 has different sizes and some members are shifted | ||
| 30 | * Compatibility wrappers are needed for them and provided below. | ||
| 31 | * | ||
| 32 | * sys_fcntl64: | ||
| 33 | * | ||
| 34 | * struct flock64 has different sizes and some members are shifted | ||
| 35 | * A compatibility wrapper is needed and provided below. | ||
| 36 | * | ||
| 37 | * sys_statfs64: | ||
| 38 | * sys_fstatfs64: | ||
| 39 | * | ||
| 40 | * struct statfs64 has extra padding with EABI growing its size from | ||
| 41 | * 84 to 88. This struct is now __attribute__((packed,aligned(4))) | ||
| 42 | * with a small assembly wrapper to force the sz argument to 84 if it is 88 | ||
| 43 | * to avoid copying the extra padding over user space unexpecting it. | ||
| 44 | * | ||
| 45 | * sys_newuname: | ||
| 46 | * | ||
| 47 | * struct new_utsname has no padding with EABI. No problem there. | ||
| 48 | * | ||
| 49 | * sys_epoll_ctl: | ||
| 50 | * sys_epoll_wait: | ||
| 51 | * | ||
| 52 | * struct epoll_event has its second member shifted also affecting the | ||
| 53 | * structure size. Compatibility wrappers are needed and provided below. | ||
| 54 | * | ||
| 55 | * sys_ipc: | ||
| 56 | * sys_semop: | ||
| 57 | * sys_semtimedop: | ||
| 58 | * | ||
| 59 | * struct sembuf loses its padding with EABI. Since arrays of them are | ||
| 60 | * used they have to be copyed to remove the padding. Compatibility wrappers | ||
| 61 | * provided below. | ||
| 62 | */ | ||
| 63 | |||
| 64 | #include <linux/syscalls.h> | ||
| 65 | #include <linux/errno.h> | ||
| 66 | #include <linux/fs.h> | ||
| 67 | #include <linux/fcntl.h> | ||
| 68 | #include <linux/eventpoll.h> | ||
| 69 | #include <linux/sem.h> | ||
| 70 | #include <asm/ipc.h> | ||
| 71 | #include <asm/uaccess.h> | ||
| 72 | |||
| 73 | struct oldabi_stat64 { | ||
| 74 | unsigned long long st_dev; | ||
| 75 | unsigned int __pad1; | ||
| 76 | unsigned long __st_ino; | ||
| 77 | unsigned int st_mode; | ||
| 78 | unsigned int st_nlink; | ||
| 79 | |||
| 80 | unsigned long st_uid; | ||
| 81 | unsigned long st_gid; | ||
| 82 | |||
| 83 | unsigned long long st_rdev; | ||
| 84 | unsigned int __pad2; | ||
| 85 | |||
| 86 | long long st_size; | ||
| 87 | unsigned long st_blksize; | ||
| 88 | unsigned long long st_blocks; | ||
| 89 | |||
| 90 | unsigned long st_atime; | ||
| 91 | unsigned long st_atime_nsec; | ||
| 92 | |||
| 93 | unsigned long st_mtime; | ||
| 94 | unsigned long st_mtime_nsec; | ||
| 95 | |||
| 96 | unsigned long st_ctime; | ||
| 97 | unsigned long st_ctime_nsec; | ||
| 98 | |||
| 99 | unsigned long long st_ino; | ||
| 100 | } __attribute__ ((packed,aligned(4))); | ||
| 101 | |||
| 102 | static long cp_oldabi_stat64(struct kstat *stat, | ||
| 103 | struct oldabi_stat64 __user *statbuf) | ||
| 104 | { | ||
| 105 | struct oldabi_stat64 tmp; | ||
| 106 | |||
| 107 | tmp.st_dev = huge_encode_dev(stat->dev); | ||
| 108 | tmp.__pad1 = 0; | ||
| 109 | tmp.__st_ino = stat->ino; | ||
| 110 | tmp.st_mode = stat->mode; | ||
| 111 | tmp.st_nlink = stat->nlink; | ||
| 112 | tmp.st_uid = stat->uid; | ||
| 113 | tmp.st_gid = stat->gid; | ||
| 114 | tmp.st_rdev = huge_encode_dev(stat->rdev); | ||
| 115 | tmp.st_size = stat->size; | ||
| 116 | tmp.st_blocks = stat->blocks; | ||
| 117 | tmp.__pad2 = 0; | ||
| 118 | tmp.st_blksize = stat->blksize; | ||
| 119 | tmp.st_atime = stat->atime.tv_sec; | ||
| 120 | tmp.st_atime_nsec = stat->atime.tv_nsec; | ||
| 121 | tmp.st_mtime = stat->mtime.tv_sec; | ||
| 122 | tmp.st_mtime_nsec = stat->mtime.tv_nsec; | ||
| 123 | tmp.st_ctime = stat->ctime.tv_sec; | ||
| 124 | tmp.st_ctime_nsec = stat->ctime.tv_nsec; | ||
| 125 | tmp.st_ino = stat->ino; | ||
| 126 | return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; | ||
| 127 | } | ||
| 128 | |||
| 129 | asmlinkage long sys_oabi_stat64(char __user * filename, | ||
| 130 | struct oldabi_stat64 __user * statbuf) | ||
| 131 | { | ||
| 132 | struct kstat stat; | ||
| 133 | int error = vfs_stat(filename, &stat); | ||
| 134 | if (!error) | ||
| 135 | error = cp_oldabi_stat64(&stat, statbuf); | ||
| 136 | return error; | ||
| 137 | } | ||
| 138 | |||
| 139 | asmlinkage long sys_oabi_lstat64(char __user * filename, | ||
| 140 | struct oldabi_stat64 __user * statbuf) | ||
| 141 | { | ||
| 142 | struct kstat stat; | ||
| 143 | int error = vfs_lstat(filename, &stat); | ||
| 144 | if (!error) | ||
| 145 | error = cp_oldabi_stat64(&stat, statbuf); | ||
| 146 | return error; | ||
| 147 | } | ||
| 148 | |||
| 149 | asmlinkage long sys_oabi_fstat64(unsigned long fd, | ||
| 150 | struct oldabi_stat64 __user * statbuf) | ||
| 151 | { | ||
| 152 | struct kstat stat; | ||
| 153 | int error = vfs_fstat(fd, &stat); | ||
| 154 | if (!error) | ||
| 155 | error = cp_oldabi_stat64(&stat, statbuf); | ||
| 156 | return error; | ||
| 157 | } | ||
| 158 | |||
| 159 | struct oabi_flock64 { | ||
| 160 | short l_type; | ||
| 161 | short l_whence; | ||
| 162 | loff_t l_start; | ||
| 163 | loff_t l_len; | ||
| 164 | pid_t l_pid; | ||
| 165 | } __attribute__ ((packed,aligned(4))); | ||
| 166 | |||
| 167 | asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd, | ||
| 168 | unsigned long arg) | ||
| 169 | { | ||
| 170 | struct oabi_flock64 user; | ||
| 171 | struct flock64 kernel; | ||
| 172 | mm_segment_t fs = USER_DS; /* initialized to kill a warning */ | ||
| 173 | unsigned long local_arg = arg; | ||
| 174 | int ret; | ||
| 175 | |||
| 176 | switch (cmd) { | ||
| 177 | case F_GETLK64: | ||
| 178 | case F_SETLK64: | ||
| 179 | case F_SETLKW64: | ||
| 180 | if (copy_from_user(&user, (struct oabi_flock64 __user *)arg, | ||
| 181 | sizeof(user))) | ||
| 182 | return -EFAULT; | ||
| 183 | kernel.l_type = user.l_type; | ||
| 184 | kernel.l_whence = user.l_whence; | ||
| 185 | kernel.l_start = user.l_start; | ||
| 186 | kernel.l_len = user.l_len; | ||
| 187 | kernel.l_pid = user.l_pid; | ||
| 188 | local_arg = (unsigned long)&kernel; | ||
| 189 | fs = get_fs(); | ||
| 190 | set_fs(KERNEL_DS); | ||
| 191 | } | ||
| 192 | |||
| 193 | ret = sys_fcntl64(fd, cmd, local_arg); | ||
| 194 | |||
| 195 | switch (cmd) { | ||
| 196 | case F_GETLK64: | ||
| 197 | if (!ret) { | ||
| 198 | user.l_type = kernel.l_type; | ||
| 199 | user.l_whence = kernel.l_whence; | ||
| 200 | user.l_start = kernel.l_start; | ||
| 201 | user.l_len = kernel.l_len; | ||
| 202 | user.l_pid = kernel.l_pid; | ||
| 203 | if (copy_to_user((struct oabi_flock64 __user *)arg, | ||
| 204 | &user, sizeof(user))) | ||
| 205 | ret = -EFAULT; | ||
| 206 | } | ||
| 207 | case F_SETLK64: | ||
| 208 | case F_SETLKW64: | ||
| 209 | set_fs(fs); | ||
| 210 | } | ||
| 211 | |||
| 212 | return ret; | ||
| 213 | } | ||
| 214 | |||
| 215 | struct oabi_epoll_event { | ||
| 216 | __u32 events; | ||
| 217 | __u64 data; | ||
| 218 | } __attribute__ ((packed,aligned(4))); | ||
| 219 | |||
| 220 | asmlinkage long sys_oabi_epoll_ctl(int epfd, int op, int fd, | ||
| 221 | struct oabi_epoll_event __user *event) | ||
| 222 | { | ||
| 223 | struct oabi_epoll_event user; | ||
| 224 | struct epoll_event kernel; | ||
| 225 | mm_segment_t fs; | ||
| 226 | long ret; | ||
| 227 | |||
| 228 | if (op == EPOLL_CTL_DEL) | ||
| 229 | return sys_epoll_ctl(epfd, op, fd, NULL); | ||
| 230 | if (copy_from_user(&user, event, sizeof(user))) | ||
| 231 | return -EFAULT; | ||
| 232 | kernel.events = user.events; | ||
| 233 | kernel.data = user.data; | ||
| 234 | fs = get_fs(); | ||
| 235 | set_fs(KERNEL_DS); | ||
| 236 | ret = sys_epoll_ctl(epfd, op, fd, &kernel); | ||
| 237 | set_fs(fs); | ||
| 238 | return ret; | ||
| 239 | } | ||
| 240 | |||
| 241 | asmlinkage long sys_oabi_epoll_wait(int epfd, | ||
| 242 | struct oabi_epoll_event __user *events, | ||
| 243 | int maxevents, int timeout) | ||
| 244 | { | ||
| 245 | struct epoll_event *kbuf; | ||
| 246 | mm_segment_t fs; | ||
| 247 | long ret, err, i; | ||
| 248 | |||
| 249 | if (maxevents <= 0 || maxevents > (INT_MAX/sizeof(struct epoll_event))) | ||
| 250 | return -EINVAL; | ||
| 251 | kbuf = kmalloc(sizeof(*kbuf) * maxevents, GFP_KERNEL); | ||
| 252 | if (!kbuf) | ||
| 253 | return -ENOMEM; | ||
| 254 | fs = get_fs(); | ||
| 255 | set_fs(KERNEL_DS); | ||
| 256 | ret = sys_epoll_wait(epfd, kbuf, maxevents, timeout); | ||
| 257 | set_fs(fs); | ||
| 258 | err = 0; | ||
| 259 | for (i = 0; i < ret; i++) { | ||
| 260 | __put_user_error(kbuf[i].events, &events->events, err); | ||
| 261 | __put_user_error(kbuf[i].data, &events->data, err); | ||
| 262 | events++; | ||
| 263 | } | ||
| 264 | kfree(kbuf); | ||
| 265 | return err ? -EFAULT : ret; | ||
| 266 | } | ||
| 267 | |||
| 268 | struct oabi_sembuf { | ||
| 269 | unsigned short sem_num; | ||
| 270 | short sem_op; | ||
| 271 | short sem_flg; | ||
| 272 | unsigned short __pad; | ||
| 273 | }; | ||
| 274 | |||
| 275 | asmlinkage long sys_oabi_semtimedop(int semid, | ||
| 276 | struct oabi_sembuf __user *tsops, | ||
| 277 | unsigned nsops, | ||
| 278 | const struct timespec __user *timeout) | ||
| 279 | { | ||
| 280 | struct sembuf *sops; | ||
| 281 | struct timespec local_timeout; | ||
| 282 | long err; | ||
| 283 | int i; | ||
| 284 | |||
| 285 | if (nsops < 1) | ||
| 286 | return -EINVAL; | ||
| 287 | sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL); | ||
| 288 | if (!sops) | ||
| 289 | return -ENOMEM; | ||
| 290 | err = 0; | ||
| 291 | for (i = 0; i < nsops; i++) { | ||
| 292 | __get_user_error(sops[i].sem_num, &tsops->sem_num, err); | ||
| 293 | __get_user_error(sops[i].sem_op, &tsops->sem_op, err); | ||
| 294 | __get_user_error(sops[i].sem_flg, &tsops->sem_flg, err); | ||
| 295 | tsops++; | ||
| 296 | } | ||
| 297 | if (timeout) { | ||
| 298 | /* copy this as well before changing domain protection */ | ||
| 299 | err |= copy_from_user(&local_timeout, timeout, sizeof(*timeout)); | ||
| 300 | timeout = &local_timeout; | ||
| 301 | } | ||
| 302 | if (err) { | ||
| 303 | err = -EFAULT; | ||
| 304 | } else { | ||
| 305 | mm_segment_t fs = get_fs(); | ||
| 306 | set_fs(KERNEL_DS); | ||
| 307 | err = sys_semtimedop(semid, sops, nsops, timeout); | ||
| 308 | set_fs(fs); | ||
| 309 | } | ||
| 310 | kfree(sops); | ||
| 311 | return err; | ||
| 312 | } | ||
| 313 | |||
| 314 | asmlinkage long sys_oabi_semop(int semid, struct oabi_sembuf __user *tsops, | ||
| 315 | unsigned nsops) | ||
| 316 | { | ||
| 317 | return sys_oabi_semtimedop(semid, tsops, nsops, NULL); | ||
| 318 | } | ||
| 319 | |||
| 320 | extern asmlinkage int sys_ipc(uint call, int first, int second, int third, | ||
| 321 | void __user *ptr, long fifth); | ||
| 322 | |||
| 323 | asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third, | ||
| 324 | void __user *ptr, long fifth) | ||
| 325 | { | ||
| 326 | switch (call & 0xffff) { | ||
| 327 | case SEMOP: | ||
| 328 | return sys_oabi_semtimedop(first, | ||
| 329 | (struct oabi_sembuf __user *)ptr, | ||
| 330 | second, NULL); | ||
| 331 | case SEMTIMEDOP: | ||
| 332 | return sys_oabi_semtimedop(first, | ||
| 333 | (struct oabi_sembuf __user *)ptr, | ||
| 334 | second, | ||
| 335 | (const struct timespec __user *)fifth); | ||
| 336 | default: | ||
| 337 | return sys_ipc(call, first, second, third, ptr, fifth); | ||
| 338 | } | ||
| 339 | } | ||
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 93cfd3ffcc72..10235b01582e 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
| @@ -404,7 +404,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) | |||
| 404 | struct thread_info *thread = current_thread_info(); | 404 | struct thread_info *thread = current_thread_info(); |
| 405 | siginfo_t info; | 405 | siginfo_t info; |
| 406 | 406 | ||
| 407 | if ((no >> 16) != 0x9f) | 407 | if ((no >> 16) != (__ARM_NR_BASE>> 16)) |
| 408 | return bad_syscall(no, regs); | 408 | return bad_syscall(no, regs); |
| 409 | 409 | ||
| 410 | switch (no & 0xffff) { | 410 | switch (no & 0xffff) { |
diff --git a/arch/arm/lib/ashldi3.S b/arch/arm/lib/ashldi3.S index 561e20717b30..55e57a1c2e6d 100644 --- a/arch/arm/lib/ashldi3.S +++ b/arch/arm/lib/ashldi3.S | |||
| @@ -37,6 +37,7 @@ Boston, MA 02110-1301, USA. */ | |||
| 37 | #endif | 37 | #endif |
| 38 | 38 | ||
| 39 | ENTRY(__ashldi3) | 39 | ENTRY(__ashldi3) |
| 40 | ENTRY(__aeabi_llsl) | ||
| 40 | 41 | ||
| 41 | subs r3, r2, #32 | 42 | subs r3, r2, #32 |
| 42 | rsb ip, r2, #32 | 43 | rsb ip, r2, #32 |
diff --git a/arch/arm/lib/ashrdi3.S b/arch/arm/lib/ashrdi3.S index 86fb2a90c301..0b31398f89b2 100644 --- a/arch/arm/lib/ashrdi3.S +++ b/arch/arm/lib/ashrdi3.S | |||
| @@ -37,6 +37,7 @@ Boston, MA 02110-1301, USA. */ | |||
| 37 | #endif | 37 | #endif |
| 38 | 38 | ||
| 39 | ENTRY(__ashrdi3) | 39 | ENTRY(__ashrdi3) |
| 40 | ENTRY(__aeabi_lasr) | ||
| 40 | 41 | ||
| 41 | subs r3, r2, #32 | 42 | subs r3, r2, #32 |
| 42 | rsb ip, r2, #32 | 43 | rsb ip, r2, #32 |
diff --git a/arch/arm/lib/lib1funcs.S b/arch/arm/lib/lib1funcs.S index 59026029d017..4e492f4b3f0e 100644 --- a/arch/arm/lib/lib1funcs.S +++ b/arch/arm/lib/lib1funcs.S | |||
| @@ -206,6 +206,7 @@ Boston, MA 02111-1307, USA. */ | |||
| 206 | 206 | ||
| 207 | 207 | ||
| 208 | ENTRY(__udivsi3) | 208 | ENTRY(__udivsi3) |
| 209 | ENTRY(__aeabi_uidiv) | ||
| 209 | 210 | ||
| 210 | subs r2, r1, #1 | 211 | subs r2, r1, #1 |
| 211 | moveq pc, lr | 212 | moveq pc, lr |
| @@ -246,6 +247,7 @@ ENTRY(__umodsi3) | |||
| 246 | 247 | ||
| 247 | 248 | ||
| 248 | ENTRY(__divsi3) | 249 | ENTRY(__divsi3) |
| 250 | ENTRY(__aeabi_idiv) | ||
| 249 | 251 | ||
| 250 | cmp r1, #0 | 252 | cmp r1, #0 |
| 251 | eor ip, r0, r1 @ save the sign of the result. | 253 | eor ip, r0, r1 @ save the sign of the result. |
| @@ -303,12 +305,33 @@ ENTRY(__modsi3) | |||
| 303 | rsbmi r0, r0, #0 | 305 | rsbmi r0, r0, #0 |
| 304 | mov pc, lr | 306 | mov pc, lr |
| 305 | 307 | ||
| 308 | #ifdef CONFIG_AEABI | ||
| 309 | |||
| 310 | ENTRY(__aeabi_uidivmod) | ||
| 311 | |||
| 312 | stmfd sp!, {r0, r1, ip, lr} | ||
| 313 | bl __aeabi_uidiv | ||
| 314 | ldmfd sp!, {r1, r2, ip, lr} | ||
| 315 | mul r3, r0, r2 | ||
| 316 | sub r1, r1, r3 | ||
| 317 | mov pc, lr | ||
| 318 | |||
| 319 | ENTRY(__aeabi_idivmod) | ||
| 320 | |||
| 321 | stmfd sp!, {r0, r1, ip, lr} | ||
| 322 | bl __aeabi_idiv | ||
| 323 | ldmfd sp!, {r1, r2, ip, lr} | ||
| 324 | mul r3, r0, r2 | ||
| 325 | sub r1, r1, r3 | ||
| 326 | mov pc, lr | ||
| 327 | |||
| 328 | #endif | ||
| 306 | 329 | ||
| 307 | Ldiv0: | 330 | Ldiv0: |
| 308 | 331 | ||
| 309 | str lr, [sp, #-4]! | 332 | str lr, [sp, #-8]! |
| 310 | bl __div0 | 333 | bl __div0 |
| 311 | mov r0, #0 @ About as wrong as it could be. | 334 | mov r0, #0 @ About as wrong as it could be. |
| 312 | ldr pc, [sp], #4 | 335 | ldr pc, [sp], #8 |
| 313 | 336 | ||
| 314 | 337 | ||
diff --git a/arch/arm/lib/lshrdi3.S b/arch/arm/lib/lshrdi3.S index 46c2ed19ec95..a86dbdd59cc4 100644 --- a/arch/arm/lib/lshrdi3.S +++ b/arch/arm/lib/lshrdi3.S | |||
| @@ -37,6 +37,7 @@ Boston, MA 02110-1301, USA. */ | |||
| 37 | #endif | 37 | #endif |
| 38 | 38 | ||
| 39 | ENTRY(__lshrdi3) | 39 | ENTRY(__lshrdi3) |
| 40 | ENTRY(__aeabi_llsr) | ||
| 40 | 41 | ||
| 41 | subs r3, r2, #32 | 42 | subs r3, r2, #32 |
| 42 | rsb ip, r2, #32 | 43 | rsb ip, r2, #32 |
diff --git a/arch/arm/lib/muldi3.S b/arch/arm/lib/muldi3.S index c7fbdf005319..72d594184b8a 100644 --- a/arch/arm/lib/muldi3.S +++ b/arch/arm/lib/muldi3.S | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #endif | 25 | #endif |
| 26 | 26 | ||
| 27 | ENTRY(__muldi3) | 27 | ENTRY(__muldi3) |
| 28 | ENTRY(__aeabi_lmul) | ||
| 28 | 29 | ||
| 29 | mul xh, yl, xh | 30 | mul xh, yl, xh |
| 30 | mla xh, xl, yh, xh | 31 | mla xh, xl, yh, xh |
diff --git a/arch/arm/lib/ucmpdi2.S b/arch/arm/lib/ucmpdi2.S index 112630f93e5d..d847a62834cb 100644 --- a/arch/arm/lib/ucmpdi2.S +++ b/arch/arm/lib/ucmpdi2.S | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/config.h> | ||
| 13 | #include <linux/linkage.h> | 14 | #include <linux/linkage.h> |
| 14 | 15 | ||
| 15 | #ifdef __ARMEB__ | 16 | #ifdef __ARMEB__ |
| @@ -33,3 +34,16 @@ ENTRY(__ucmpdi2) | |||
| 33 | movhi r0, #2 | 34 | movhi r0, #2 |
| 34 | mov pc, lr | 35 | mov pc, lr |
| 35 | 36 | ||
| 37 | #ifdef CONFIG_AEABI | ||
| 38 | |||
| 39 | ENTRY(__aeabi_ulcmp) | ||
| 40 | |||
| 41 | cmp xh, yh | ||
| 42 | cmpeq xl, yl | ||
| 43 | movlo r0, #-1 | ||
| 44 | moveq r0, #0 | ||
| 45 | movhi r0, #1 | ||
| 46 | mov pc, lr | ||
| 47 | |||
| 48 | #endif | ||
| 49 | |||
diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c index f5ef69702296..dc5fa8e5ebef 100644 --- a/arch/arm/mach-aaec2000/aaed2000.c +++ b/arch/arm/mach-aaec2000/aaed2000.c | |||
| @@ -90,7 +90,6 @@ static void __init aaed2000_map_io(void) | |||
| 90 | 90 | ||
| 91 | MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform") | 91 | MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform") |
| 92 | /* Maintainer: Nicolas Bellido Y Ortega */ | 92 | /* Maintainer: Nicolas Bellido Y Ortega */ |
| 93 | .phys_ram = 0xf0000000, | ||
| 94 | .phys_io = PIO_BASE, | 93 | .phys_io = PIO_BASE, |
| 95 | .io_pg_offst = ((VIO_BASE) >> 18) & 0xfffc, | 94 | .io_pg_offst = ((VIO_BASE) >> 18) & 0xfffc, |
| 96 | .map_io = aaed2000_map_io, | 95 | .map_io = aaed2000_map_io, |
diff --git a/arch/arm/mach-at91rm9200/board-csb337.c b/arch/arm/mach-at91rm9200/board-csb337.c index 4aec834ee47f..54022e58d50d 100644 --- a/arch/arm/mach-at91rm9200/board-csb337.c +++ b/arch/arm/mach-at91rm9200/board-csb337.c | |||
| @@ -132,7 +132,6 @@ static void __init csb337_board_init(void) | |||
| 132 | 132 | ||
| 133 | MACHINE_START(CSB337, "Cogent CSB337") | 133 | MACHINE_START(CSB337, "Cogent CSB337") |
| 134 | /* Maintainer: Bill Gatliff */ | 134 | /* Maintainer: Bill Gatliff */ |
| 135 | .phys_ram = AT91_SDRAM_BASE, | ||
| 136 | .phys_io = AT91_BASE_SYS, | 135 | .phys_io = AT91_BASE_SYS, |
| 137 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | 136 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, |
| 138 | .boot_params = AT91_SDRAM_BASE + 0x100, | 137 | .boot_params = AT91_SDRAM_BASE + 0x100, |
diff --git a/arch/arm/mach-at91rm9200/board-csb637.c b/arch/arm/mach-at91rm9200/board-csb637.c index 23e4cc21481a..8195f9d919ea 100644 --- a/arch/arm/mach-at91rm9200/board-csb637.c +++ b/arch/arm/mach-at91rm9200/board-csb637.c | |||
| @@ -105,7 +105,6 @@ static void __init csb637_board_init(void) | |||
| 105 | 105 | ||
| 106 | MACHINE_START(CSB637, "Cogent CSB637") | 106 | MACHINE_START(CSB637, "Cogent CSB637") |
| 107 | /* Maintainer: Bill Gatliff */ | 107 | /* Maintainer: Bill Gatliff */ |
| 108 | .phys_ram = AT91_SDRAM_BASE, | ||
| 109 | .phys_io = AT91_BASE_SYS, | 108 | .phys_io = AT91_BASE_SYS, |
| 110 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | 109 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, |
| 111 | .boot_params = AT91_SDRAM_BASE + 0x100, | 110 | .boot_params = AT91_SDRAM_BASE + 0x100, |
diff --git a/arch/arm/mach-at91rm9200/board-dk.c b/arch/arm/mach-at91rm9200/board-dk.c index 8c747a31b95a..8a783368366e 100644 --- a/arch/arm/mach-at91rm9200/board-dk.c +++ b/arch/arm/mach-at91rm9200/board-dk.c | |||
| @@ -127,7 +127,6 @@ static void __init dk_board_init(void) | |||
| 127 | 127 | ||
| 128 | MACHINE_START(AT91RM9200DK, "Atmel AT91RM9200-DK") | 128 | MACHINE_START(AT91RM9200DK, "Atmel AT91RM9200-DK") |
| 129 | /* Maintainer: SAN People/Atmel */ | 129 | /* Maintainer: SAN People/Atmel */ |
| 130 | .phys_ram = AT91_SDRAM_BASE, | ||
| 131 | .phys_io = AT91_BASE_SYS, | 130 | .phys_io = AT91_BASE_SYS, |
| 132 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | 131 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, |
| 133 | .boot_params = AT91_SDRAM_BASE + 0x100, | 132 | .boot_params = AT91_SDRAM_BASE + 0x100, |
diff --git a/arch/arm/mach-at91rm9200/board-ek.c b/arch/arm/mach-at91rm9200/board-ek.c index d140645711be..fd0752eba897 100644 --- a/arch/arm/mach-at91rm9200/board-ek.c +++ b/arch/arm/mach-at91rm9200/board-ek.c | |||
| @@ -120,7 +120,6 @@ static void __init ek_board_init(void) | |||
| 120 | 120 | ||
| 121 | MACHINE_START(AT91RM9200EK, "Atmel AT91RM9200-EK") | 121 | MACHINE_START(AT91RM9200EK, "Atmel AT91RM9200-EK") |
| 122 | /* Maintainer: SAN People/Atmel */ | 122 | /* Maintainer: SAN People/Atmel */ |
| 123 | .phys_ram = AT91_SDRAM_BASE, | ||
| 124 | .phys_io = AT91_BASE_SYS, | 123 | .phys_io = AT91_BASE_SYS, |
| 125 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | 124 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, |
| 126 | .boot_params = AT91_SDRAM_BASE + 0x100, | 125 | .boot_params = AT91_SDRAM_BASE + 0x100, |
diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c index 43b9423d1440..c13ca6c56baa 100644 --- a/arch/arm/mach-clps711x/autcpu12.c +++ b/arch/arm/mach-clps711x/autcpu12.c | |||
| @@ -64,7 +64,6 @@ void __init autcpu12_map_io(void) | |||
| 64 | 64 | ||
| 65 | MACHINE_START(AUTCPU12, "autronix autcpu12") | 65 | MACHINE_START(AUTCPU12, "autronix autcpu12") |
| 66 | /* Maintainer: Thomas Gleixner */ | 66 | /* Maintainer: Thomas Gleixner */ |
| 67 | .phys_ram = 0xc0000000, | ||
| 68 | .phys_io = 0x80000000, | 67 | .phys_io = 0x80000000, |
| 69 | .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, | 68 | .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, |
| 70 | .boot_params = 0xc0020000, | 69 | .boot_params = 0xc0020000, |
diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c index cba7be5a06c3..831df007f6c7 100644 --- a/arch/arm/mach-clps711x/cdb89712.c +++ b/arch/arm/mach-clps711x/cdb89712.c | |||
| @@ -55,7 +55,6 @@ static void __init cdb89712_map_io(void) | |||
| 55 | 55 | ||
| 56 | MACHINE_START(CDB89712, "Cirrus-CDB89712") | 56 | MACHINE_START(CDB89712, "Cirrus-CDB89712") |
| 57 | /* Maintainer: Ray Lehtiniemi */ | 57 | /* Maintainer: Ray Lehtiniemi */ |
| 58 | .phys_ram = 0xc0000000, | ||
| 59 | .phys_io = 0x80000000, | 58 | .phys_io = 0x80000000, |
| 60 | .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, | 59 | .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, |
| 61 | .boot_params = 0xc0000100, | 60 | .boot_params = 0xc0000100, |
diff --git a/arch/arm/mach-clps711x/ceiva.c b/arch/arm/mach-clps711x/ceiva.c index 35d51a759b59..e2b2c5ac8a83 100644 --- a/arch/arm/mach-clps711x/ceiva.c +++ b/arch/arm/mach-clps711x/ceiva.c | |||
| @@ -56,7 +56,6 @@ static void __init ceiva_map_io(void) | |||
| 56 | 56 | ||
| 57 | MACHINE_START(CEIVA, "CEIVA/Polaroid Photo MAX Digital Picture Frame") | 57 | MACHINE_START(CEIVA, "CEIVA/Polaroid Photo MAX Digital Picture Frame") |
| 58 | /* Maintainer: Rob Scott */ | 58 | /* Maintainer: Rob Scott */ |
| 59 | .phys_ram = 0xc0000000, | ||
| 60 | .phys_io = 0x80000000, | 59 | .phys_io = 0x80000000, |
| 61 | .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, | 60 | .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, |
| 62 | .boot_params = 0xc0000100, | 61 | .boot_params = 0xc0000100, |
diff --git a/arch/arm/mach-clps711x/clep7312.c b/arch/arm/mach-clps711x/clep7312.c index c83f3fd68fcd..09fb57e45213 100644 --- a/arch/arm/mach-clps711x/clep7312.c +++ b/arch/arm/mach-clps711x/clep7312.c | |||
| @@ -38,7 +38,6 @@ fixup_clep7312(struct machine_desc *desc, struct tag *tags, | |||
| 38 | 38 | ||
| 39 | MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312") | 39 | MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312") |
| 40 | /* Maintainer: Nobody */ | 40 | /* Maintainer: Nobody */ |
| 41 | .phys_ram = 0xc0000000, | ||
| 42 | .phys_io = 0x80000000, | 41 | .phys_io = 0x80000000, |
| 43 | .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, | 42 | .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, |
| 44 | .boot_params = 0xc0000100, | 43 | .boot_params = 0xc0000100, |
diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c index 255c98b63e15..dc81cc68595d 100644 --- a/arch/arm/mach-clps711x/edb7211-arch.c +++ b/arch/arm/mach-clps711x/edb7211-arch.c | |||
| @@ -52,7 +52,6 @@ fixup_edb7211(struct machine_desc *desc, struct tag *tags, | |||
| 52 | 52 | ||
| 53 | MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)") | 53 | MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)") |
| 54 | /* Maintainer: Jon McClintock */ | 54 | /* Maintainer: Jon McClintock */ |
| 55 | .phys_ram = 0xc0000000, | ||
| 56 | .phys_io = 0x80000000, | 55 | .phys_io = 0x80000000, |
| 57 | .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, | 56 | .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, |
| 58 | .boot_params = 0xc0020100, /* 0xc0000000 - 0xc001ffff can be video RAM */ | 57 | .boot_params = 0xc0020100, /* 0xc0000000 - 0xc001ffff can be video RAM */ |
diff --git a/arch/arm/mach-clps711x/fortunet.c b/arch/arm/mach-clps711x/fortunet.c index 3d88da0c287b..ff26a85aa4ba 100644 --- a/arch/arm/mach-clps711x/fortunet.c +++ b/arch/arm/mach-clps711x/fortunet.c | |||
| @@ -78,7 +78,6 @@ fortunet_fixup(struct machine_desc *desc, struct tag *tags, | |||
| 78 | 78 | ||
| 79 | MACHINE_START(FORTUNET, "ARM-FortuNet") | 79 | MACHINE_START(FORTUNET, "ARM-FortuNet") |
| 80 | /* Maintainer: FortuNet Inc. */ | 80 | /* Maintainer: FortuNet Inc. */ |
| 81 | .phys_ram = 0xc0000000, | ||
| 82 | .phys_io = 0x80000000, | 81 | .phys_io = 0x80000000, |
| 83 | .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc, | 82 | .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc, |
| 84 | .boot_params = 0x00000000, | 83 | .boot_params = 0x00000000, |
diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c index a1acb945fb51..9ba45f4d5a7e 100644 --- a/arch/arm/mach-clps711x/p720t.c +++ b/arch/arm/mach-clps711x/p720t.c | |||
| @@ -90,7 +90,6 @@ static void __init p720t_map_io(void) | |||
| 90 | 90 | ||
| 91 | MACHINE_START(P720T, "ARM-Prospector720T") | 91 | MACHINE_START(P720T, "ARM-Prospector720T") |
| 92 | /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ | 92 | /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ |
| 93 | .phys_ram = 0xc0000000, | ||
| 94 | .phys_io = 0x80000000, | 93 | .phys_io = 0x80000000, |
| 95 | .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, | 94 | .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, |
| 96 | .boot_params = 0xc0000100, | 95 | .boot_params = 0xc0000100, |
diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c index d869af0023f8..5b12cab0e691 100644 --- a/arch/arm/mach-clps7500/core.c +++ b/arch/arm/mach-clps7500/core.c | |||
| @@ -384,7 +384,6 @@ static void __init clps7500_init(void) | |||
| 384 | 384 | ||
| 385 | MACHINE_START(CLPS7500, "CL-PS7500") | 385 | MACHINE_START(CLPS7500, "CL-PS7500") |
| 386 | /* Maintainer: Philip Blundell */ | 386 | /* Maintainer: Philip Blundell */ |
| 387 | .phys_ram = 0x10000000, | ||
| 388 | .phys_io = 0x03000000, | 387 | .phys_io = 0x03000000, |
| 389 | .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, | 388 | .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, |
| 390 | .map_io = clps7500_map_io, | 389 | .map_io = clps7500_map_io, |
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c index ed4614983adb..6d620d8268cc 100644 --- a/arch/arm/mach-ebsa110/core.c +++ b/arch/arm/mach-ebsa110/core.c | |||
| @@ -284,7 +284,6 @@ arch_initcall(ebsa110_init); | |||
| 284 | 284 | ||
| 285 | MACHINE_START(EBSA110, "EBSA110") | 285 | MACHINE_START(EBSA110, "EBSA110") |
| 286 | /* Maintainer: Russell King */ | 286 | /* Maintainer: Russell King */ |
| 287 | .phys_ram = 0x00000000, | ||
| 288 | .phys_io = 0xe0000000, | 287 | .phys_io = 0xe0000000, |
| 289 | .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, | 288 | .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, |
| 290 | .boot_params = 0x00000400, | 289 | .boot_params = 0x00000400, |
diff --git a/arch/arm/mach-footbridge/cats-hw.c b/arch/arm/mach-footbridge/cats-hw.c index 49b898af0032..5b64d5c5b967 100644 --- a/arch/arm/mach-footbridge/cats-hw.c +++ b/arch/arm/mach-footbridge/cats-hw.c | |||
| @@ -85,7 +85,6 @@ fixup_cats(struct machine_desc *desc, struct tag *tags, | |||
| 85 | 85 | ||
| 86 | MACHINE_START(CATS, "Chalice-CATS") | 86 | MACHINE_START(CATS, "Chalice-CATS") |
| 87 | /* Maintainer: Philip Blundell */ | 87 | /* Maintainer: Philip Blundell */ |
| 88 | .phys_ram = 0x00000000, | ||
| 89 | .phys_io = DC21285_ARMCSR_BASE, | 88 | .phys_io = DC21285_ARMCSR_BASE, |
| 90 | .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, | 89 | .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, |
| 91 | .boot_params = 0x00000100, | 90 | .boot_params = 0x00000100, |
diff --git a/arch/arm/mach-footbridge/co285.c b/arch/arm/mach-footbridge/co285.c index 548a79081688..4545576ad8d9 100644 --- a/arch/arm/mach-footbridge/co285.c +++ b/arch/arm/mach-footbridge/co285.c | |||
| @@ -29,7 +29,6 @@ fixup_coebsa285(struct machine_desc *desc, struct tag *tags, | |||
| 29 | 29 | ||
| 30 | MACHINE_START(CO285, "co-EBSA285") | 30 | MACHINE_START(CO285, "co-EBSA285") |
| 31 | /* Maintainer: Mark van Doesburg */ | 31 | /* Maintainer: Mark van Doesburg */ |
| 32 | .phys_ram = 0x00000000, | ||
| 33 | .phys_io = DC21285_ARMCSR_BASE, | 32 | .phys_io = DC21285_ARMCSR_BASE, |
| 34 | .io_pg_offst = ((0x7cf00000) >> 18) & 0xfffc, | 33 | .io_pg_offst = ((0x7cf00000) >> 18) & 0xfffc, |
| 35 | .fixup = fixup_coebsa285, | 34 | .fixup = fixup_coebsa285, |
diff --git a/arch/arm/mach-footbridge/ebsa285.c b/arch/arm/mach-footbridge/ebsa285.c index 1c37605268d5..b1d3bf20a41e 100644 --- a/arch/arm/mach-footbridge/ebsa285.c +++ b/arch/arm/mach-footbridge/ebsa285.c | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | 14 | ||
| 15 | MACHINE_START(EBSA285, "EBSA285") | 15 | MACHINE_START(EBSA285, "EBSA285") |
| 16 | /* Maintainer: Russell King */ | 16 | /* Maintainer: Russell King */ |
| 17 | .phys_ram = 0x00000000, | ||
| 18 | .phys_io = DC21285_ARMCSR_BASE, | 17 | .phys_io = DC21285_ARMCSR_BASE, |
| 19 | .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, | 18 | .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, |
| 20 | .boot_params = 0x00000100, | 19 | .boot_params = 0x00000100, |
diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c index 9e563de465b5..229bf0585e40 100644 --- a/arch/arm/mach-footbridge/netwinder-hw.c +++ b/arch/arm/mach-footbridge/netwinder-hw.c | |||
| @@ -649,7 +649,6 @@ fixup_netwinder(struct machine_desc *desc, struct tag *tags, | |||
| 649 | 649 | ||
| 650 | MACHINE_START(NETWINDER, "Rebel-NetWinder") | 650 | MACHINE_START(NETWINDER, "Rebel-NetWinder") |
| 651 | /* Maintainer: Russell King/Rebel.com */ | 651 | /* Maintainer: Russell King/Rebel.com */ |
| 652 | .phys_ram = 0x00000000, | ||
| 653 | .phys_io = DC21285_ARMCSR_BASE, | 652 | .phys_io = DC21285_ARMCSR_BASE, |
| 654 | .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, | 653 | .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, |
| 655 | .boot_params = 0x00000100, | 654 | .boot_params = 0x00000100, |
diff --git a/arch/arm/mach-footbridge/personal.c b/arch/arm/mach-footbridge/personal.c index 0146b8bb59da..c4f843fc099d 100644 --- a/arch/arm/mach-footbridge/personal.c +++ b/arch/arm/mach-footbridge/personal.c | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | 14 | ||
| 15 | MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer") | 15 | MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer") |
| 16 | /* Maintainer: Jamey Hicks / George France */ | 16 | /* Maintainer: Jamey Hicks / George France */ |
| 17 | .phys_ram = 0x00000000, | ||
| 18 | .phys_io = DC21285_ARMCSR_BASE, | 17 | .phys_io = DC21285_ARMCSR_BASE, |
| 19 | .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, | 18 | .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, |
| 20 | .boot_params = 0x00000100, | 19 | .boot_params = 0x00000100, |
diff --git a/arch/arm/mach-h720x/h7201-eval.c b/arch/arm/mach-h720x/h7201-eval.c index fa59e9e2a5c8..193f968edac3 100644 --- a/arch/arm/mach-h720x/h7201-eval.c +++ b/arch/arm/mach-h720x/h7201-eval.c | |||
| @@ -31,7 +31,6 @@ | |||
| 31 | 31 | ||
| 32 | MACHINE_START(H7201, "Hynix GMS30C7201") | 32 | MACHINE_START(H7201, "Hynix GMS30C7201") |
| 33 | /* Maintainer: Robert Schwebel, Pengutronix */ | 33 | /* Maintainer: Robert Schwebel, Pengutronix */ |
| 34 | .phys_ram = 0x40000000, | ||
| 35 | .phys_io = 0x80000000, | 34 | .phys_io = 0x80000000, |
| 36 | .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc, | 35 | .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc, |
| 37 | .boot_params = 0xc0001000, | 36 | .boot_params = 0xc0001000, |
diff --git a/arch/arm/mach-h720x/h7202-eval.c b/arch/arm/mach-h720x/h7202-eval.c index d75c8221d2a5..36266896979c 100644 --- a/arch/arm/mach-h720x/h7202-eval.c +++ b/arch/arm/mach-h720x/h7202-eval.c | |||
| @@ -72,7 +72,6 @@ static void __init init_eval_h7202(void) | |||
| 72 | 72 | ||
| 73 | MACHINE_START(H7202, "Hynix HMS30C7202") | 73 | MACHINE_START(H7202, "Hynix HMS30C7202") |
| 74 | /* Maintainer: Robert Schwebel, Pengutronix */ | 74 | /* Maintainer: Robert Schwebel, Pengutronix */ |
| 75 | .phys_ram = 0x40000000, | ||
| 76 | .phys_io = 0x80000000, | 75 | .phys_io = 0x80000000, |
| 77 | .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc, | 76 | .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc, |
| 78 | .boot_params = 0x40000100, | 77 | .boot_params = 0x40000100, |
diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c index c9e0cd8ed016..dc31e3fd6c57 100644 --- a/arch/arm/mach-imx/mx1ads.c +++ b/arch/arm/mach-imx/mx1ads.c | |||
| @@ -69,7 +69,6 @@ mx1ads_map_io(void) | |||
| 69 | 69 | ||
| 70 | MACHINE_START(MX1ADS, "Motorola MX1ADS") | 70 | MACHINE_START(MX1ADS, "Motorola MX1ADS") |
| 71 | /* Maintainer: Sascha Hauer, Pengutronix */ | 71 | /* Maintainer: Sascha Hauer, Pengutronix */ |
| 72 | .phys_ram = 0x08000000, | ||
| 73 | .phys_io = 0x00200000, | 72 | .phys_io = 0x00200000, |
| 74 | .io_pg_offst = ((0xe0200000) >> 18) & 0xfffc, | 73 | .io_pg_offst = ((0xe0200000) >> 18) & 0xfffc, |
| 75 | .boot_params = 0x08000100, | 74 | .boot_params = 0x08000100, |
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 3afedeb56a6e..d8d3c2a5a97e 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c | |||
| @@ -347,7 +347,6 @@ static struct sys_timer ap_timer = { | |||
| 347 | 347 | ||
| 348 | MACHINE_START(INTEGRATOR, "ARM-Integrator") | 348 | MACHINE_START(INTEGRATOR, "ARM-Integrator") |
| 349 | /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ | 349 | /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ |
| 350 | .phys_ram = 0x00000000, | ||
| 351 | .phys_io = 0x16000000, | 350 | .phys_io = 0x16000000, |
| 352 | .io_pg_offst = ((0xf1600000) >> 18) & 0xfffc, | 351 | .io_pg_offst = ((0xf1600000) >> 18) & 0xfffc, |
| 353 | .boot_params = 0x00000100, | 352 | .boot_params = 0x00000100, |
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 16cf2482a3e9..31820170f306 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c | |||
| @@ -578,7 +578,6 @@ static struct sys_timer cp_timer = { | |||
| 578 | 578 | ||
| 579 | MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") | 579 | MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") |
| 580 | /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ | 580 | /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ |
| 581 | .phys_ram = 0x00000000, | ||
| 582 | .phys_io = 0x16000000, | 581 | .phys_io = 0x16000000, |
| 583 | .io_pg_offst = ((0xf1600000) >> 18) & 0xfffc, | 582 | .io_pg_offst = ((0xf1600000) >> 18) & 0xfffc, |
| 584 | .boot_params = 0x00000100, | 583 | .boot_params = 0x00000100, |
diff --git a/arch/arm/mach-integrator/lm.c b/arch/arm/mach-integrator/lm.c index 5b41e3a724e1..622cdc4212dd 100644 --- a/arch/arm/mach-integrator/lm.c +++ b/arch/arm/mach-integrator/lm.c | |||
| @@ -22,20 +22,6 @@ static int lm_match(struct device *dev, struct device_driver *drv) | |||
| 22 | return 1; | 22 | return 1; |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | static struct bus_type lm_bustype = { | ||
| 26 | .name = "logicmodule", | ||
| 27 | .match = lm_match, | ||
| 28 | // .suspend = lm_suspend, | ||
| 29 | // .resume = lm_resume, | ||
| 30 | }; | ||
| 31 | |||
| 32 | static int __init lm_init(void) | ||
| 33 | { | ||
| 34 | return bus_register(&lm_bustype); | ||
| 35 | } | ||
| 36 | |||
| 37 | postcore_initcall(lm_init); | ||
| 38 | |||
| 39 | static int lm_bus_probe(struct device *dev) | 25 | static int lm_bus_probe(struct device *dev) |
| 40 | { | 26 | { |
| 41 | struct lm_device *lmdev = to_lm_device(dev); | 27 | struct lm_device *lmdev = to_lm_device(dev); |
| @@ -49,16 +35,30 @@ static int lm_bus_remove(struct device *dev) | |||
| 49 | struct lm_device *lmdev = to_lm_device(dev); | 35 | struct lm_device *lmdev = to_lm_device(dev); |
| 50 | struct lm_driver *lmdrv = to_lm_driver(dev->driver); | 36 | struct lm_driver *lmdrv = to_lm_driver(dev->driver); |
| 51 | 37 | ||
| 52 | lmdrv->remove(lmdev); | 38 | if (lmdrv->remove) |
| 39 | lmdrv->remove(lmdev); | ||
| 53 | return 0; | 40 | return 0; |
| 54 | } | 41 | } |
| 55 | 42 | ||
| 43 | static struct bus_type lm_bustype = { | ||
| 44 | .name = "logicmodule", | ||
| 45 | .match = lm_match, | ||
| 46 | .probe = lm_bus_probe, | ||
| 47 | .remove = lm_bus_remove, | ||
| 48 | // .suspend = lm_bus_suspend, | ||
| 49 | // .resume = lm_bus_resume, | ||
| 50 | }; | ||
| 51 | |||
| 52 | static int __init lm_init(void) | ||
| 53 | { | ||
| 54 | return bus_register(&lm_bustype); | ||
| 55 | } | ||
| 56 | |||
| 57 | postcore_initcall(lm_init); | ||
| 58 | |||
| 56 | int lm_driver_register(struct lm_driver *drv) | 59 | int lm_driver_register(struct lm_driver *drv) |
| 57 | { | 60 | { |
| 58 | drv->drv.bus = &lm_bustype; | 61 | drv->drv.bus = &lm_bustype; |
| 59 | drv->drv.probe = lm_bus_probe; | ||
| 60 | drv->drv.remove = lm_bus_remove; | ||
| 61 | |||
| 62 | return driver_register(&drv->drv); | 62 | return driver_register(&drv->drv); |
| 63 | } | 63 | } |
| 64 | 64 | ||
diff --git a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c index 80770233b8d4..e4f4c52d93d4 100644 --- a/arch/arm/mach-iop3xx/iop321-setup.c +++ b/arch/arm/mach-iop3xx/iop321-setup.c | |||
| @@ -151,7 +151,6 @@ extern void iop321_init_time(void); | |||
| 151 | #if defined(CONFIG_ARCH_IQ80321) | 151 | #if defined(CONFIG_ARCH_IQ80321) |
| 152 | MACHINE_START(IQ80321, "Intel IQ80321") | 152 | MACHINE_START(IQ80321, "Intel IQ80321") |
| 153 | /* Maintainer: Intel Corporation */ | 153 | /* Maintainer: Intel Corporation */ |
| 154 | .phys_ram = PHYS_OFFSET, | ||
| 155 | .phys_io = IQ80321_UART, | 154 | .phys_io = IQ80321_UART, |
| 156 | .io_pg_offst = ((IQ80321_UART) >> 18) & 0xfffc, | 155 | .io_pg_offst = ((IQ80321_UART) >> 18) & 0xfffc, |
| 157 | .map_io = iq80321_map_io, | 156 | .map_io = iq80321_map_io, |
| @@ -163,7 +162,6 @@ MACHINE_END | |||
| 163 | #elif defined(CONFIG_ARCH_IQ31244) | 162 | #elif defined(CONFIG_ARCH_IQ31244) |
| 164 | MACHINE_START(IQ31244, "Intel IQ31244") | 163 | MACHINE_START(IQ31244, "Intel IQ31244") |
| 165 | /* Maintainer: Intel Corp. */ | 164 | /* Maintainer: Intel Corp. */ |
| 166 | .phys_ram = PHYS_OFFSET, | ||
| 167 | .phys_io = IQ31244_UART, | 165 | .phys_io = IQ31244_UART, |
| 168 | .io_pg_offst = ((IQ31244_UART) >> 18) & 0xfffc, | 166 | .io_pg_offst = ((IQ31244_UART) >> 18) & 0xfffc, |
| 169 | .map_io = iq31244_map_io, | 167 | .map_io = iq31244_map_io, |
diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c index e6ea1cba6a17..63585485123e 100644 --- a/arch/arm/mach-iop3xx/iop331-setup.c +++ b/arch/arm/mach-iop3xx/iop331-setup.c | |||
| @@ -195,7 +195,6 @@ extern void iq80332_map_io(void); | |||
| 195 | #if defined(CONFIG_ARCH_IQ80331) | 195 | #if defined(CONFIG_ARCH_IQ80331) |
| 196 | MACHINE_START(IQ80331, "Intel IQ80331") | 196 | MACHINE_START(IQ80331, "Intel IQ80331") |
| 197 | /* Maintainer: Intel Corp. */ | 197 | /* Maintainer: Intel Corp. */ |
| 198 | .phys_ram = PHYS_OFFSET, | ||
| 199 | .phys_io = 0xfefff000, | 198 | .phys_io = 0xfefff000, |
| 200 | .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical | 199 | .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical |
| 201 | .map_io = iq80331_map_io, | 200 | .map_io = iq80331_map_io, |
| @@ -208,7 +207,6 @@ MACHINE_END | |||
| 208 | #elif defined(CONFIG_MACH_IQ80332) | 207 | #elif defined(CONFIG_MACH_IQ80332) |
| 209 | MACHINE_START(IQ80332, "Intel IQ80332") | 208 | MACHINE_START(IQ80332, "Intel IQ80332") |
| 210 | /* Maintainer: Intel Corp. */ | 209 | /* Maintainer: Intel Corp. */ |
| 211 | .phys_ram = PHYS_OFFSET, | ||
| 212 | .phys_io = 0xfefff000, | 210 | .phys_io = 0xfefff000, |
| 213 | .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical | 211 | .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical |
| 214 | .map_io = iq80332_map_io, | 212 | .map_io = iq80332_map_io, |
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c index 6851abaf5524..cfd5bef3190b 100644 --- a/arch/arm/mach-ixp2000/core.c +++ b/arch/arm/mach-ixp2000/core.c | |||
| @@ -106,6 +106,16 @@ static struct map_desc ixp2000_io_desc[] __initdata = { | |||
| 106 | .length = IXP2000_MSF_SIZE, | 106 | .length = IXP2000_MSF_SIZE, |
| 107 | .type = MT_IXP2000_DEVICE, | 107 | .type = MT_IXP2000_DEVICE, |
| 108 | }, { | 108 | }, { |
| 109 | .virtual = IXP2000_SCRATCH_RING_VIRT_BASE, | ||
| 110 | .pfn = __phys_to_pfn(IXP2000_SCRATCH_RING_PHYS_BASE), | ||
| 111 | .length = IXP2000_SCRATCH_RING_SIZE, | ||
| 112 | .type = MT_IXP2000_DEVICE, | ||
| 113 | }, { | ||
| 114 | .virtual = IXP2000_SRAM0_VIRT_BASE, | ||
| 115 | .pfn = __phys_to_pfn(IXP2000_SRAM0_PHYS_BASE), | ||
| 116 | .length = IXP2000_SRAM0_SIZE, | ||
| 117 | .type = MT_IXP2000_DEVICE, | ||
| 118 | }, { | ||
| 109 | .virtual = IXP2000_PCI_IO_VIRT_BASE, | 119 | .virtual = IXP2000_PCI_IO_VIRT_BASE, |
| 110 | .pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE), | 120 | .pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE), |
| 111 | .length = IXP2000_PCI_IO_SIZE, | 121 | .length = IXP2000_PCI_IO_SIZE, |
diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c index 61f6006241bd..9e5a13bb39d0 100644 --- a/arch/arm/mach-ixp2000/enp2611.c +++ b/arch/arm/mach-ixp2000/enp2611.c | |||
| @@ -254,7 +254,6 @@ static void __init enp2611_init_machine(void) | |||
| 254 | 254 | ||
| 255 | MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board") | 255 | MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board") |
| 256 | /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ | 256 | /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ |
| 257 | .phys_ram = 0x00000000, | ||
| 258 | .phys_io = IXP2000_UART_PHYS_BASE, | 257 | .phys_io = IXP2000_UART_PHYS_BASE, |
| 259 | .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, | 258 | .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, |
| 260 | .boot_params = 0x00000100, | 259 | .boot_params = 0x00000100, |
diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c index fd280a93637e..7c782403042a 100644 --- a/arch/arm/mach-ixp2000/ixdp2400.c +++ b/arch/arm/mach-ixp2000/ixdp2400.c | |||
| @@ -169,7 +169,6 @@ void ixdp2400_init_irq(void) | |||
| 169 | 169 | ||
| 170 | MACHINE_START(IXDP2400, "Intel IXDP2400 Development Platform") | 170 | MACHINE_START(IXDP2400, "Intel IXDP2400 Development Platform") |
| 171 | /* Maintainer: MontaVista Software, Inc. */ | 171 | /* Maintainer: MontaVista Software, Inc. */ |
| 172 | .phys_ram = 0x00000000, | ||
| 173 | .phys_io = IXP2000_UART_PHYS_BASE, | 172 | .phys_io = IXP2000_UART_PHYS_BASE, |
| 174 | .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, | 173 | .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, |
| 175 | .boot_params = 0x00000100, | 174 | .boot_params = 0x00000100, |
diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c index f9073aa28615..076e3f8acc96 100644 --- a/arch/arm/mach-ixp2000/ixdp2800.c +++ b/arch/arm/mach-ixp2000/ixdp2800.c | |||
| @@ -285,7 +285,6 @@ void ixdp2800_init_irq(void) | |||
| 285 | 285 | ||
| 286 | MACHINE_START(IXDP2800, "Intel IXDP2800 Development Platform") | 286 | MACHINE_START(IXDP2800, "Intel IXDP2800 Development Platform") |
| 287 | /* Maintainer: MontaVista Software, Inc. */ | 287 | /* Maintainer: MontaVista Software, Inc. */ |
| 288 | .phys_ram = 0x00000000, | ||
| 289 | .phys_io = IXP2000_UART_PHYS_BASE, | 288 | .phys_io = IXP2000_UART_PHYS_BASE, |
| 290 | .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, | 289 | .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, |
| 291 | .boot_params = 0x00000100, | 290 | .boot_params = 0x00000100, |
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c index e6a882f35da2..10f06606d460 100644 --- a/arch/arm/mach-ixp2000/ixdp2x01.c +++ b/arch/arm/mach-ixp2000/ixdp2x01.c | |||
| @@ -376,7 +376,6 @@ static void __init ixdp2x01_init_machine(void) | |||
| 376 | #ifdef CONFIG_ARCH_IXDP2401 | 376 | #ifdef CONFIG_ARCH_IXDP2401 |
| 377 | MACHINE_START(IXDP2401, "Intel IXDP2401 Development Platform") | 377 | MACHINE_START(IXDP2401, "Intel IXDP2401 Development Platform") |
| 378 | /* Maintainer: MontaVista Software, Inc. */ | 378 | /* Maintainer: MontaVista Software, Inc. */ |
| 379 | .phys_ram = 0x00000000, | ||
| 380 | .phys_io = IXP2000_UART_PHYS_BASE, | 379 | .phys_io = IXP2000_UART_PHYS_BASE, |
| 381 | .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, | 380 | .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, |
| 382 | .boot_params = 0x00000100, | 381 | .boot_params = 0x00000100, |
| @@ -390,7 +389,6 @@ MACHINE_END | |||
| 390 | #ifdef CONFIG_ARCH_IXDP2801 | 389 | #ifdef CONFIG_ARCH_IXDP2801 |
| 391 | MACHINE_START(IXDP2801, "Intel IXDP2801 Development Platform") | 390 | MACHINE_START(IXDP2801, "Intel IXDP2801 Development Platform") |
| 392 | /* Maintainer: MontaVista Software, Inc. */ | 391 | /* Maintainer: MontaVista Software, Inc. */ |
| 393 | .phys_ram = 0x00000000, | ||
| 394 | .phys_io = IXP2000_UART_PHYS_BASE, | 392 | .phys_io = IXP2000_UART_PHYS_BASE, |
| 395 | .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, | 393 | .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, |
| 396 | .boot_params = 0x00000100, | 394 | .boot_params = 0x00000100, |
diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c index 679594a73981..13f8a7ac3ba9 100644 --- a/arch/arm/mach-ixp4xx/coyote-setup.c +++ b/arch/arm/mach-ixp4xx/coyote-setup.c | |||
| @@ -101,7 +101,6 @@ static void __init coyote_init(void) | |||
| 101 | #ifdef CONFIG_ARCH_ADI_COYOTE | 101 | #ifdef CONFIG_ARCH_ADI_COYOTE |
| 102 | MACHINE_START(ADI_COYOTE, "ADI Engineering Coyote") | 102 | MACHINE_START(ADI_COYOTE, "ADI Engineering Coyote") |
| 103 | /* Maintainer: MontaVista Software, Inc. */ | 103 | /* Maintainer: MontaVista Software, Inc. */ |
| 104 | .phys_ram = PHYS_OFFSET, | ||
| 105 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, | 104 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, |
| 106 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, | 105 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, |
| 107 | .map_io = ixp4xx_map_io, | 106 | .map_io = ixp4xx_map_io, |
| @@ -119,7 +118,6 @@ MACHINE_END | |||
| 119 | #ifdef CONFIG_MACH_IXDPG425 | 118 | #ifdef CONFIG_MACH_IXDPG425 |
| 120 | MACHINE_START(IXDPG425, "Intel IXDPG425") | 119 | MACHINE_START(IXDPG425, "Intel IXDPG425") |
| 121 | /* Maintainer: MontaVista Software, Inc. */ | 120 | /* Maintainer: MontaVista Software, Inc. */ |
| 122 | .phys_ram = PHYS_OFFSET, | ||
| 123 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, | 121 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, |
| 124 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, | 122 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, |
| 125 | .map_io = ixp4xx_map_io, | 123 | .map_io = ixp4xx_map_io, |
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c index 038670489970..654e2eed81fb 100644 --- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c +++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c | |||
| @@ -142,7 +142,6 @@ static void __init gtwx5715_init(void) | |||
| 142 | 142 | ||
| 143 | MACHINE_START(GTWX5715, "Gemtek GTWX5715 (Linksys WRV54G)") | 143 | MACHINE_START(GTWX5715, "Gemtek GTWX5715 (Linksys WRV54G)") |
| 144 | /* Maintainer: George Joseph */ | 144 | /* Maintainer: George Joseph */ |
| 145 | .phys_ram = PHYS_OFFSET, | ||
| 146 | .phys_io = IXP4XX_UART2_BASE_PHYS, | 145 | .phys_io = IXP4XX_UART2_BASE_PHYS, |
| 147 | .io_pg_offst = ((IXP4XX_UART2_BASE_VIRT) >> 18) & 0xfffc, | 146 | .io_pg_offst = ((IXP4XX_UART2_BASE_VIRT) >> 18) & 0xfffc, |
| 148 | .map_io = ixp4xx_map_io, | 147 | .map_io = ixp4xx_map_io, |
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index c2e105c89c95..da72383ee301 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c | |||
| @@ -121,7 +121,6 @@ static void __init ixdp425_init(void) | |||
| 121 | #ifdef CONFIG_ARCH_IXDP425 | 121 | #ifdef CONFIG_ARCH_IXDP425 |
| 122 | MACHINE_START(IXDP425, "Intel IXDP425 Development Platform") | 122 | MACHINE_START(IXDP425, "Intel IXDP425 Development Platform") |
| 123 | /* Maintainer: MontaVista Software, Inc. */ | 123 | /* Maintainer: MontaVista Software, Inc. */ |
| 124 | .phys_ram = PHYS_OFFSET, | ||
| 125 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, | 124 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, |
| 126 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, | 125 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, |
| 127 | .map_io = ixp4xx_map_io, | 126 | .map_io = ixp4xx_map_io, |
| @@ -135,7 +134,6 @@ MACHINE_END | |||
| 135 | #ifdef CONFIG_MACH_IXDP465 | 134 | #ifdef CONFIG_MACH_IXDP465 |
| 136 | MACHINE_START(IXDP465, "Intel IXDP465 Development Platform") | 135 | MACHINE_START(IXDP465, "Intel IXDP465 Development Platform") |
| 137 | /* Maintainer: MontaVista Software, Inc. */ | 136 | /* Maintainer: MontaVista Software, Inc. */ |
| 138 | .phys_ram = PHYS_OFFSET, | ||
| 139 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, | 137 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, |
| 140 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, | 138 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, |
| 141 | .map_io = ixp4xx_map_io, | 139 | .map_io = ixp4xx_map_io, |
| @@ -149,7 +147,6 @@ MACHINE_END | |||
| 149 | #ifdef CONFIG_ARCH_PRPMC1100 | 147 | #ifdef CONFIG_ARCH_PRPMC1100 |
| 150 | MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform") | 148 | MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform") |
| 151 | /* Maintainer: MontaVista Software, Inc. */ | 149 | /* Maintainer: MontaVista Software, Inc. */ |
| 152 | .phys_ram = PHYS_OFFSET, | ||
| 153 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, | 150 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, |
| 154 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, | 151 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, |
| 155 | .map_io = ixp4xx_map_io, | 152 | .map_io = ixp4xx_map_io, |
| @@ -169,7 +166,6 @@ MACHINE_END | |||
| 169 | #ifdef CONFIG_ARCH_AVILA | 166 | #ifdef CONFIG_ARCH_AVILA |
| 170 | MACHINE_START(AVILA, "Gateworks Avila Network Platform") | 167 | MACHINE_START(AVILA, "Gateworks Avila Network Platform") |
| 171 | /* Maintainer: Deepak Saxena <dsaxena@plexity.net> */ | 168 | /* Maintainer: Deepak Saxena <dsaxena@plexity.net> */ |
| 172 | .phys_ram = PHYS_OFFSET, | ||
| 173 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, | 169 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, |
| 174 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, | 170 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, |
| 175 | .map_io = ixp4xx_map_io, | 171 | .map_io = ixp4xx_map_io, |
diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c index 49998a8bd4e8..856d56f3b2ae 100644 --- a/arch/arm/mach-ixp4xx/nas100d-setup.c +++ b/arch/arm/mach-ixp4xx/nas100d-setup.c | |||
| @@ -124,7 +124,6 @@ static void __init nas100d_init(void) | |||
| 124 | 124 | ||
| 125 | MACHINE_START(NAS100D, "Iomega NAS 100d") | 125 | MACHINE_START(NAS100D, "Iomega NAS 100d") |
| 126 | /* Maintainer: www.nslu2-linux.org */ | 126 | /* Maintainer: www.nslu2-linux.org */ |
| 127 | .phys_ram = PHYS_OFFSET, | ||
| 128 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, | 127 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, |
| 129 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC, | 128 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC, |
| 130 | .boot_params = 0x00000100, | 129 | .boot_params = 0x00000100, |
diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c index 289e94cb65c2..da9340a53434 100644 --- a/arch/arm/mach-ixp4xx/nslu2-setup.c +++ b/arch/arm/mach-ixp4xx/nslu2-setup.c | |||
| @@ -123,7 +123,6 @@ static void __init nslu2_init(void) | |||
| 123 | 123 | ||
| 124 | MACHINE_START(NSLU2, "Linksys NSLU2") | 124 | MACHINE_START(NSLU2, "Linksys NSLU2") |
| 125 | /* Maintainer: www.nslu2-linux.org */ | 125 | /* Maintainer: www.nslu2-linux.org */ |
| 126 | .phys_ram = PHYS_OFFSET, | ||
| 127 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, | 126 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, |
| 128 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC, | 127 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC, |
| 129 | .boot_params = 0x00000100, | 128 | .boot_params = 0x00000100, |
diff --git a/arch/arm/mach-l7200/core.c b/arch/arm/mach-l7200/core.c index 03ed742ae2be..ac626436e96f 100644 --- a/arch/arm/mach-l7200/core.c +++ b/arch/arm/mach-l7200/core.c | |||
| @@ -91,7 +91,6 @@ static void __init l7200_map_io(void) | |||
| 91 | 91 | ||
| 92 | MACHINE_START(L7200, "LinkUp Systems L7200") | 92 | MACHINE_START(L7200, "LinkUp Systems L7200") |
| 93 | /* Maintainer: Steve Hill / Scott McConnell */ | 93 | /* Maintainer: Steve Hill / Scott McConnell */ |
| 94 | .phys_ram = 0xf0000000, | ||
| 95 | .phys_io = 0x80040000, | 94 | .phys_io = 0x80040000, |
| 96 | .io_pg_offst = ((0xd0000000) >> 18) & 0xfffc, | 95 | .io_pg_offst = ((0xd0000000) >> 18) & 0xfffc, |
| 97 | .map_io = l7200_map_io, | 96 | .map_io = l7200_map_io, |
diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c index 19f2fa2244c4..2cccc27c62e4 100644 --- a/arch/arm/mach-lh7a40x/arch-kev7a400.c +++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c | |||
| @@ -112,7 +112,6 @@ void __init lh7a40x_init_board_irq (void) | |||
| 112 | 112 | ||
| 113 | MACHINE_START (KEV7A400, "Sharp KEV7a400") | 113 | MACHINE_START (KEV7A400, "Sharp KEV7a400") |
| 114 | /* Maintainer: Marc Singer */ | 114 | /* Maintainer: Marc Singer */ |
| 115 | .phys_ram = 0xc0000000, | ||
| 116 | .phys_io = 0x80000000, | 115 | .phys_io = 0x80000000, |
| 117 | .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, | 116 | .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, |
| 118 | .boot_params = 0xc0000100, | 117 | .boot_params = 0xc0000100, |
diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c index 4eb962fdb3a8..12e23277c5ea 100644 --- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c +++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c | |||
| @@ -317,7 +317,6 @@ lpd7a400_map_io(void) | |||
| 317 | 317 | ||
| 318 | MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10") | 318 | MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10") |
| 319 | /* Maintainer: Marc Singer */ | 319 | /* Maintainer: Marc Singer */ |
| 320 | .phys_ram = 0xc0000000, | ||
| 321 | .phys_io = 0x80000000, | 320 | .phys_io = 0x80000000, |
| 322 | .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, | 321 | .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, |
| 323 | .boot_params = 0xc0000100, | 322 | .boot_params = 0xc0000100, |
| @@ -333,7 +332,6 @@ MACHINE_END | |||
| 333 | 332 | ||
| 334 | MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10") | 333 | MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10") |
| 335 | /* Maintainer: Marc Singer */ | 334 | /* Maintainer: Marc Singer */ |
| 336 | .phys_ram = 0xc0000000, | ||
| 337 | .phys_io = 0x80000000, | 335 | .phys_io = 0x80000000, |
| 338 | .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, | 336 | .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, |
| 339 | .boot_params = 0xc0000100, | 337 | .boot_params = 0xc0000100, |
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c index 4b292e93fbe2..bdc20b51b076 100644 --- a/arch/arm/mach-omap1/board-generic.c +++ b/arch/arm/mach-omap1/board-generic.c | |||
| @@ -109,7 +109,6 @@ static void __init omap_generic_map_io(void) | |||
| 109 | 109 | ||
| 110 | MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710") | 110 | MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710") |
| 111 | /* Maintainer: Tony Lindgren <tony@atomide.com> */ | 111 | /* Maintainer: Tony Lindgren <tony@atomide.com> */ |
| 112 | .phys_ram = 0x10000000, | ||
| 113 | .phys_io = 0xfff00000, | 112 | .phys_io = 0xfff00000, |
| 114 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, | 113 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, |
| 115 | .boot_params = 0x10000100, | 114 | .boot_params = 0x10000100, |
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index a07e2c9307fa..9533c36a92df 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c | |||
| @@ -199,7 +199,6 @@ static void __init h2_map_io(void) | |||
| 199 | 199 | ||
| 200 | MACHINE_START(OMAP_H2, "TI-H2") | 200 | MACHINE_START(OMAP_H2, "TI-H2") |
| 201 | /* Maintainer: Imre Deak <imre.deak@nokia.com> */ | 201 | /* Maintainer: Imre Deak <imre.deak@nokia.com> */ |
| 202 | .phys_ram = 0x10000000, | ||
| 203 | .phys_io = 0xfff00000, | 202 | .phys_io = 0xfff00000, |
| 204 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, | 203 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, |
| 205 | .boot_params = 0x10000100, | 204 | .boot_params = 0x10000100, |
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index 668e278433c2..d665efc1c344 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c | |||
| @@ -215,7 +215,6 @@ static void __init h3_map_io(void) | |||
| 215 | 215 | ||
| 216 | MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board") | 216 | MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board") |
| 217 | /* Maintainer: Texas Instruments, Inc. */ | 217 | /* Maintainer: Texas Instruments, Inc. */ |
| 218 | .phys_ram = 0x10000000, | ||
| 219 | .phys_io = 0xfff00000, | 218 | .phys_io = 0xfff00000, |
| 220 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, | 219 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, |
| 221 | .boot_params = 0x10000100, | 220 | .boot_params = 0x10000100, |
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index 95f1ff36cdcb..652f37c7f906 100644 --- a/arch/arm/mach-omap1/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c | |||
| @@ -303,7 +303,6 @@ static void __init innovator_map_io(void) | |||
| 303 | 303 | ||
| 304 | MACHINE_START(OMAP_INNOVATOR, "TI-Innovator") | 304 | MACHINE_START(OMAP_INNOVATOR, "TI-Innovator") |
| 305 | /* Maintainer: MontaVista Software, Inc. */ | 305 | /* Maintainer: MontaVista Software, Inc. */ |
| 306 | .phys_ram = 0x10000000, | ||
| 307 | .phys_io = 0xfff00000, | 306 | .phys_io = 0xfff00000, |
| 308 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, | 307 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, |
| 309 | .boot_params = 0x10000100, | 308 | .boot_params = 0x10000100, |
diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c index 0448fa7de8a4..58f783930d45 100644 --- a/arch/arm/mach-omap1/board-netstar.c +++ b/arch/arm/mach-omap1/board-netstar.c | |||
| @@ -149,7 +149,6 @@ postcore_initcall(netstar_late_init); | |||
| 149 | 149 | ||
| 150 | MACHINE_START(NETSTAR, "NetStar OMAP5910") | 150 | MACHINE_START(NETSTAR, "NetStar OMAP5910") |
| 151 | /* Maintainer: Ladislav Michl <michl@2n.cz> */ | 151 | /* Maintainer: Ladislav Michl <michl@2n.cz> */ |
| 152 | .phys_ram = 0x10000000, | ||
| 153 | .phys_io = 0xfff00000, | 152 | .phys_io = 0xfff00000, |
| 154 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, | 153 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, |
| 155 | .boot_params = 0x10000100, | 154 | .boot_params = 0x10000100, |
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index e990e1bc1669..e5d126e8f276 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c | |||
| @@ -274,7 +274,6 @@ static void __init osk_map_io(void) | |||
| 274 | 274 | ||
| 275 | MACHINE_START(OMAP_OSK, "TI-OSK") | 275 | MACHINE_START(OMAP_OSK, "TI-OSK") |
| 276 | /* Maintainer: Dirk Behme <dirk.behme@de.bosch.com> */ | 276 | /* Maintainer: Dirk Behme <dirk.behme@de.bosch.com> */ |
| 277 | .phys_ram = 0x10000000, | ||
| 278 | .phys_io = 0xfff00000, | 277 | .phys_io = 0xfff00000, |
| 279 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, | 278 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, |
| 280 | .boot_params = 0x10000100, | 279 | .boot_params = 0x10000100, |
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index 5c975eb5c34b..67fada207622 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c | |||
| @@ -76,7 +76,6 @@ static void __init omap_generic_map_io(void) | |||
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E") | 78 | MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E") |
| 79 | .phys_ram = 0x10000000, | ||
| 80 | .phys_io = 0xfff00000, | 79 | .phys_io = 0xfff00000, |
| 81 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, | 80 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, |
| 82 | .boot_params = 0x10000100, | 81 | .boot_params = 0x10000100, |
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c index 92ff5dc07351..88708a0c52a2 100644 --- a/arch/arm/mach-omap1/board-perseus2.c +++ b/arch/arm/mach-omap1/board-perseus2.c | |||
| @@ -199,7 +199,6 @@ static void __init omap_perseus2_map_io(void) | |||
| 199 | 199 | ||
| 200 | MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2") | 200 | MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2") |
| 201 | /* Maintainer: Kevin Hilman <kjh@hilman.org> */ | 201 | /* Maintainer: Kevin Hilman <kjh@hilman.org> */ |
| 202 | .phys_ram = 0x10000000, | ||
| 203 | .phys_io = 0xfff00000, | 202 | .phys_io = 0xfff00000, |
| 204 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, | 203 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, |
| 205 | .boot_params = 0x10000100, | 204 | .boot_params = 0x10000100, |
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index 6f9a6220e78a..959b4b847c87 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c | |||
| @@ -281,7 +281,6 @@ EXPORT_SYMBOL(voiceblue_wdt_ping); | |||
| 281 | 281 | ||
| 282 | MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910") | 282 | MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910") |
| 283 | /* Maintainer: Ladislav Michl <michl@2n.cz> */ | 283 | /* Maintainer: Ladislav Michl <michl@2n.cz> */ |
| 284 | .phys_ram = 0x10000000, | ||
| 285 | .phys_io = 0xfff00000, | 284 | .phys_io = 0xfff00000, |
| 286 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, | 285 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, |
| 287 | .boot_params = 0x10000100, | 286 | .boot_params = 0x10000100, |
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index c602e7a3d93e..b937123e5c65 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c | |||
| @@ -69,7 +69,6 @@ static void __init omap_generic_map_io(void) | |||
| 69 | 69 | ||
| 70 | MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx") | 70 | MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx") |
| 71 | /* Maintainer: Paul Mundt <paul.mundt@nokia.com> */ | 71 | /* Maintainer: Paul Mundt <paul.mundt@nokia.com> */ |
| 72 | .phys_ram = 0x80000000, | ||
| 73 | .phys_io = 0x48000000, | 72 | .phys_io = 0x48000000, |
| 74 | .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, | 73 | .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, |
| 75 | .boot_params = 0x80000100, | 74 | .boot_params = 0x80000100, |
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index f2554469a76a..c3c35d40378a 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c | |||
| @@ -186,7 +186,6 @@ static void __init omap_h4_map_io(void) | |||
| 186 | 186 | ||
| 187 | MACHINE_START(OMAP_H4, "OMAP2420 H4 board") | 187 | MACHINE_START(OMAP_H4, "OMAP2420 H4 board") |
| 188 | /* Maintainer: Paul Mundt <paul.mundt@nokia.com> */ | 188 | /* Maintainer: Paul Mundt <paul.mundt@nokia.com> */ |
| 189 | .phys_ram = 0x80000000, | ||
| 190 | .phys_io = 0x48000000, | 189 | .phys_io = 0x48000000, |
| 191 | .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, | 190 | .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, |
| 192 | .boot_params = 0x80000100, | 191 | .boot_params = 0x80000100, |
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 5a7b873f29b3..7ffd2de8f2f3 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c | |||
| @@ -342,7 +342,6 @@ static void __init fixup_corgi(struct machine_desc *desc, | |||
| 342 | 342 | ||
| 343 | #ifdef CONFIG_MACH_CORGI | 343 | #ifdef CONFIG_MACH_CORGI |
| 344 | MACHINE_START(CORGI, "SHARP Corgi") | 344 | MACHINE_START(CORGI, "SHARP Corgi") |
| 345 | .phys_ram = 0xa0000000, | ||
| 346 | .phys_io = 0x40000000, | 345 | .phys_io = 0x40000000, |
| 347 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | 346 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, |
| 348 | .fixup = fixup_corgi, | 347 | .fixup = fixup_corgi, |
| @@ -355,7 +354,6 @@ MACHINE_END | |||
| 355 | 354 | ||
| 356 | #ifdef CONFIG_MACH_SHEPHERD | 355 | #ifdef CONFIG_MACH_SHEPHERD |
| 357 | MACHINE_START(SHEPHERD, "SHARP Shepherd") | 356 | MACHINE_START(SHEPHERD, "SHARP Shepherd") |
| 358 | .phys_ram = 0xa0000000, | ||
| 359 | .phys_io = 0x40000000, | 357 | .phys_io = 0x40000000, |
| 360 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | 358 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, |
| 361 | .fixup = fixup_corgi, | 359 | .fixup = fixup_corgi, |
| @@ -368,7 +366,6 @@ MACHINE_END | |||
| 368 | 366 | ||
| 369 | #ifdef CONFIG_MACH_HUSKY | 367 | #ifdef CONFIG_MACH_HUSKY |
| 370 | MACHINE_START(HUSKY, "SHARP Husky") | 368 | MACHINE_START(HUSKY, "SHARP Husky") |
| 371 | .phys_ram = 0xa0000000, | ||
| 372 | .phys_io = 0x40000000, | 369 | .phys_io = 0x40000000, |
| 373 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | 370 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, |
| 374 | .fixup = fixup_corgi, | 371 | .fixup = fixup_corgi, |
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c index 7de159e2ab42..347b9dea24c6 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c | |||
| @@ -183,7 +183,6 @@ static void __init idp_map_io(void) | |||
| 183 | 183 | ||
| 184 | MACHINE_START(PXA_IDP, "Vibren PXA255 IDP") | 184 | MACHINE_START(PXA_IDP, "Vibren PXA255 IDP") |
| 185 | /* Maintainer: Vibren Technologies */ | 185 | /* Maintainer: Vibren Technologies */ |
| 186 | .phys_ram = 0xa0000000, | ||
| 187 | .phys_io = 0x40000000, | 186 | .phys_io = 0x40000000, |
| 188 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | 187 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, |
| 189 | .map_io = idp_map_io, | 188 | .map_io = idp_map_io, |
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index b464bc88ff93..3e26d7ce5bb2 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c | |||
| @@ -437,7 +437,6 @@ static void __init lubbock_map_io(void) | |||
| 437 | 437 | ||
| 438 | MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)") | 438 | MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)") |
| 439 | /* Maintainer: MontaVista Software Inc. */ | 439 | /* Maintainer: MontaVista Software Inc. */ |
| 440 | .phys_ram = 0xa0000000, | ||
| 441 | .phys_io = 0x40000000, | 440 | .phys_io = 0x40000000, |
| 442 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | 441 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, |
| 443 | .map_io = lubbock_map_io, | 442 | .map_io = lubbock_map_io, |
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 8da9d3efe9a0..d5bda60209ec 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c | |||
| @@ -489,7 +489,6 @@ static void __init mainstone_map_io(void) | |||
| 489 | 489 | ||
| 490 | MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") | 490 | MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") |
| 491 | /* Maintainer: MontaVista Software Inc. */ | 491 | /* Maintainer: MontaVista Software Inc. */ |
| 492 | .phys_ram = 0xa0000000, | ||
| 493 | .phys_io = 0x40000000, | 492 | .phys_io = 0x40000000, |
| 494 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | 493 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, |
| 495 | .map_io = mainstone_map_io, | 494 | .map_io = mainstone_map_io, |
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 663c95005985..911e6ff5a9bd 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c | |||
| @@ -311,7 +311,6 @@ static void __init fixup_poodle(struct machine_desc *desc, | |||
| 311 | } | 311 | } |
| 312 | 312 | ||
| 313 | MACHINE_START(POODLE, "SHARP Poodle") | 313 | MACHINE_START(POODLE, "SHARP Poodle") |
| 314 | .phys_ram = 0xa0000000, | ||
| 315 | .phys_io = 0x40000000, | 314 | .phys_io = 0x40000000, |
| 316 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | 315 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, |
| 317 | .fixup = fixup_poodle, | 316 | .fixup = fixup_poodle, |
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index a9eacc06555f..c094d99ebf56 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c | |||
| @@ -497,7 +497,6 @@ static void __init fixup_spitz(struct machine_desc *desc, | |||
| 497 | 497 | ||
| 498 | #ifdef CONFIG_MACH_SPITZ | 498 | #ifdef CONFIG_MACH_SPITZ |
| 499 | MACHINE_START(SPITZ, "SHARP Spitz") | 499 | MACHINE_START(SPITZ, "SHARP Spitz") |
| 500 | .phys_ram = 0xa0000000, | ||
| 501 | .phys_io = 0x40000000, | 500 | .phys_io = 0x40000000, |
| 502 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | 501 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, |
| 503 | .fixup = fixup_spitz, | 502 | .fixup = fixup_spitz, |
| @@ -510,7 +509,6 @@ MACHINE_END | |||
| 510 | 509 | ||
| 511 | #ifdef CONFIG_MACH_BORZOI | 510 | #ifdef CONFIG_MACH_BORZOI |
| 512 | MACHINE_START(BORZOI, "SHARP Borzoi") | 511 | MACHINE_START(BORZOI, "SHARP Borzoi") |
| 513 | .phys_ram = 0xa0000000, | ||
| 514 | .phys_io = 0x40000000, | 512 | .phys_io = 0x40000000, |
| 515 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | 513 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, |
| 516 | .fixup = fixup_spitz, | 514 | .fixup = fixup_spitz, |
| @@ -523,7 +521,6 @@ MACHINE_END | |||
| 523 | 521 | ||
| 524 | #ifdef CONFIG_MACH_AKITA | 522 | #ifdef CONFIG_MACH_AKITA |
| 525 | MACHINE_START(AKITA, "SHARP Akita") | 523 | MACHINE_START(AKITA, "SHARP Akita") |
| 526 | .phys_ram = 0xa0000000, | ||
| 527 | .phys_io = 0x40000000, | 524 | .phys_io = 0x40000000, |
| 528 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | 525 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, |
| 529 | .fixup = fixup_spitz, | 526 | .fixup = fixup_spitz, |
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index e4f92efc616e..d168286ed470 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c | |||
| @@ -295,7 +295,6 @@ static void __init fixup_tosa(struct machine_desc *desc, | |||
| 295 | } | 295 | } |
| 296 | 296 | ||
| 297 | MACHINE_START(TOSA, "SHARP Tosa") | 297 | MACHINE_START(TOSA, "SHARP Tosa") |
| 298 | .phys_ram = 0xa0000000, | ||
| 299 | .phys_io = 0x40000000, | 298 | .phys_io = 0x40000000, |
| 300 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | 299 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, |
| 301 | .fixup = fixup_tosa, | 300 | .fixup = fixup_tosa, |
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig index 129976866d47..17f5f4439fe7 100644 --- a/arch/arm/mach-realview/Kconfig +++ b/arch/arm/mach-realview/Kconfig | |||
| @@ -3,7 +3,6 @@ menu "RealView platform type" | |||
| 3 | 3 | ||
| 4 | config MACH_REALVIEW_EB | 4 | config MACH_REALVIEW_EB |
| 5 | bool "Support RealView/EB platform" | 5 | bool "Support RealView/EB platform" |
| 6 | default n | ||
| 7 | select ARM_GIC | 6 | select ARM_GIC |
| 8 | help | 7 | help |
| 9 | Include support for the ARM(R) RealView Emulation Baseboard platform. | 8 | Include support for the ARM(R) RealView Emulation Baseboard platform. |
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 112f7592aca9..d4a586e38d5b 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c | |||
| @@ -166,7 +166,6 @@ static void __init realview_eb_init(void) | |||
| 166 | 166 | ||
| 167 | MACHINE_START(REALVIEW_EB, "ARM-RealView EB") | 167 | MACHINE_START(REALVIEW_EB, "ARM-RealView EB") |
| 168 | /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ | 168 | /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ |
| 169 | .phys_ram = 0x00000000, | ||
| 170 | .phys_io = REALVIEW_UART0_BASE, | 169 | .phys_io = REALVIEW_UART0_BASE, |
| 171 | .io_pg_offst = (IO_ADDRESS(REALVIEW_UART0_BASE) >> 18) & 0xfffc, | 170 | .io_pg_offst = (IO_ADDRESS(REALVIEW_UART0_BASE) >> 18) & 0xfffc, |
| 172 | .boot_params = 0x00000100, | 171 | .boot_params = 0x00000100, |
diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c index 5c4ac1c008a6..208a2b5dba1b 100644 --- a/arch/arm/mach-rpc/riscpc.c +++ b/arch/arm/mach-rpc/riscpc.c | |||
| @@ -177,7 +177,6 @@ extern struct sys_timer ioc_timer; | |||
| 177 | 177 | ||
| 178 | MACHINE_START(RISCPC, "Acorn-RiscPC") | 178 | MACHINE_START(RISCPC, "Acorn-RiscPC") |
| 179 | /* Maintainer: Russell King */ | 179 | /* Maintainer: Russell King */ |
| 180 | .phys_ram = 0x10000000, | ||
| 181 | .phys_io = 0x03000000, | 180 | .phys_io = 0x03000000, |
| 182 | .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, | 181 | .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, |
| 183 | .boot_params = 0x10000100, | 182 | .boot_params = 0x10000100, |
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c index 0f81fc0c2f7f..3e327b8e46be 100644 --- a/arch/arm/mach-s3c2410/mach-anubis.c +++ b/arch/arm/mach-s3c2410/mach-anubis.c | |||
| @@ -294,7 +294,6 @@ static void __init anubis_map_io(void) | |||
| 294 | 294 | ||
| 295 | MACHINE_START(ANUBIS, "Simtec-Anubis") | 295 | MACHINE_START(ANUBIS, "Simtec-Anubis") |
| 296 | /* Maintainer: Ben Dooks <ben@simtec.co.uk> */ | 296 | /* Maintainer: Ben Dooks <ben@simtec.co.uk> */ |
| 297 | .phys_ram = S3C2410_SDRAM_PA, | ||
| 298 | .phys_io = S3C2410_PA_UART, | 297 | .phys_io = S3C2410_PA_UART, |
| 299 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, | 298 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, |
| 300 | .boot_params = S3C2410_SDRAM_PA + 0x100, | 299 | .boot_params = S3C2410_SDRAM_PA + 0x100, |
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index 4d962717fdf7..995bb8add331 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c | |||
| @@ -527,7 +527,6 @@ static void __init bast_init(void) | |||
| 527 | 527 | ||
| 528 | MACHINE_START(BAST, "Simtec-BAST") | 528 | MACHINE_START(BAST, "Simtec-BAST") |
| 529 | /* Maintainer: Ben Dooks <ben@simtec.co.uk> */ | 529 | /* Maintainer: Ben Dooks <ben@simtec.co.uk> */ |
| 530 | .phys_ram = S3C2410_SDRAM_PA, | ||
| 531 | .phys_io = S3C2410_PA_UART, | 530 | .phys_io = S3C2410_PA_UART, |
| 532 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, | 531 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, |
| 533 | .boot_params = S3C2410_SDRAM_PA + 0x100, | 532 | .boot_params = S3C2410_SDRAM_PA + 0x100, |
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index 0aa8760598f7..1c316f14ed94 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c | |||
| @@ -171,7 +171,6 @@ static void __init h1940_init(void) | |||
| 171 | 171 | ||
| 172 | MACHINE_START(H1940, "IPAQ-H1940") | 172 | MACHINE_START(H1940, "IPAQ-H1940") |
| 173 | /* Maintainer: Ben Dooks <ben@fluff.org> */ | 173 | /* Maintainer: Ben Dooks <ben@fluff.org> */ |
| 174 | .phys_ram = S3C2410_SDRAM_PA, | ||
| 175 | .phys_io = S3C2410_PA_UART, | 174 | .phys_io = S3C2410_PA_UART, |
| 176 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, | 175 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, |
| 177 | .boot_params = S3C2410_SDRAM_PA + 0x100, | 176 | .boot_params = S3C2410_SDRAM_PA + 0x100, |
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 378d640ab00b..116ac3169966 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c | |||
| @@ -128,7 +128,6 @@ MACHINE_START(N30, "Acer-N30") | |||
| 128 | /* Maintainer: Christer Weinigel <christer@weinigel.se>, | 128 | /* Maintainer: Christer Weinigel <christer@weinigel.se>, |
| 129 | Ben Dooks <ben-linux@fluff.org> | 129 | Ben Dooks <ben-linux@fluff.org> |
| 130 | */ | 130 | */ |
| 131 | .phys_ram = S3C2410_SDRAM_PA, | ||
| 132 | .phys_io = S3C2410_PA_UART, | 131 | .phys_io = S3C2410_PA_UART, |
| 133 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, | 132 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, |
| 134 | .boot_params = S3C2410_SDRAM_PA + 0x100, | 133 | .boot_params = S3C2410_SDRAM_PA + 0x100, |
diff --git a/arch/arm/mach-s3c2410/mach-nexcoder.c b/arch/arm/mach-s3c2410/mach-nexcoder.c index 42b0eeff2e0f..07d09509a626 100644 --- a/arch/arm/mach-s3c2410/mach-nexcoder.c +++ b/arch/arm/mach-s3c2410/mach-nexcoder.c | |||
| @@ -148,7 +148,6 @@ static void __init nexcoder_map_io(void) | |||
| 148 | 148 | ||
| 149 | MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440") | 149 | MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440") |
| 150 | /* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */ | 150 | /* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */ |
| 151 | .phys_ram = S3C2410_SDRAM_PA, | ||
| 152 | .phys_io = S3C2410_PA_UART, | 151 | .phys_io = S3C2410_PA_UART, |
| 153 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, | 152 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, |
| 154 | .boot_params = S3C2410_SDRAM_PA + 0x100, | 153 | .boot_params = S3C2410_SDRAM_PA + 0x100, |
diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c index a2eb9ed48fcd..b39daedf93ca 100644 --- a/arch/arm/mach-s3c2410/mach-otom.c +++ b/arch/arm/mach-s3c2410/mach-otom.c | |||
| @@ -116,7 +116,6 @@ static void __init otom11_map_io(void) | |||
| 116 | 116 | ||
| 117 | MACHINE_START(OTOM, "Nex Vision - Otom 1.1") | 117 | MACHINE_START(OTOM, "Nex Vision - Otom 1.1") |
| 118 | /* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */ | 118 | /* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */ |
| 119 | .phys_ram = S3C2410_SDRAM_PA, | ||
| 120 | .phys_io = S3C2410_PA_UART, | 119 | .phys_io = S3C2410_PA_UART, |
| 121 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, | 120 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, |
| 122 | .boot_params = S3C2410_SDRAM_PA + 0x100, | 121 | .boot_params = S3C2410_SDRAM_PA + 0x100, |
diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c index f8d86d1e16b6..0260ed5ab946 100644 --- a/arch/arm/mach-s3c2410/mach-rx3715.c +++ b/arch/arm/mach-s3c2410/mach-rx3715.c | |||
| @@ -205,7 +205,6 @@ static void __init rx3715_init_machine(void) | |||
| 205 | 205 | ||
| 206 | MACHINE_START(RX3715, "IPAQ-RX3715") | 206 | MACHINE_START(RX3715, "IPAQ-RX3715") |
| 207 | /* Maintainer: Ben Dooks <ben@fluff.org> */ | 207 | /* Maintainer: Ben Dooks <ben@fluff.org> */ |
| 208 | .phys_ram = S3C2410_SDRAM_PA, | ||
| 209 | .phys_io = S3C2410_PA_UART, | 208 | .phys_io = S3C2410_PA_UART, |
| 210 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, | 209 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, |
| 211 | .boot_params = S3C2410_SDRAM_PA + 0x100, | 210 | .boot_params = S3C2410_SDRAM_PA + 0x100, |
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c index 2c91965ee1c8..1e76e1fdfcea 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2410.c +++ b/arch/arm/mach-s3c2410/mach-smdk2410.c | |||
| @@ -115,7 +115,6 @@ static void __init smdk2410_init_irq(void) | |||
| 115 | MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch | 115 | MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch |
| 116 | * to SMDK2410 */ | 116 | * to SMDK2410 */ |
| 117 | /* Maintainer: Jonas Dietsche */ | 117 | /* Maintainer: Jonas Dietsche */ |
| 118 | .phys_ram = S3C2410_SDRAM_PA, | ||
| 119 | .phys_io = S3C2410_PA_UART, | 118 | .phys_io = S3C2410_PA_UART, |
| 120 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, | 119 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, |
| 121 | .boot_params = S3C2410_SDRAM_PA + 0x100, | 120 | .boot_params = S3C2410_SDRAM_PA + 0x100, |
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c index 4e31118533e6..f4315721c3b8 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2440.c +++ b/arch/arm/mach-s3c2410/mach-smdk2440.c | |||
| @@ -216,7 +216,6 @@ static void __init smdk2440_machine_init(void) | |||
| 216 | 216 | ||
| 217 | MACHINE_START(S3C2440, "SMDK2440") | 217 | MACHINE_START(S3C2440, "SMDK2440") |
| 218 | /* Maintainer: Ben Dooks <ben@fluff.org> */ | 218 | /* Maintainer: Ben Dooks <ben@fluff.org> */ |
| 219 | .phys_ram = S3C2410_SDRAM_PA, | ||
| 220 | .phys_io = S3C2410_PA_UART, | 219 | .phys_io = S3C2410_PA_UART, |
| 221 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, | 220 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, |
| 222 | .boot_params = S3C2410_SDRAM_PA + 0x100, | 221 | .boot_params = S3C2410_SDRAM_PA + 0x100, |
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c index ae7e099bf6c8..785fc9cdcf7c 100644 --- a/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/arch/arm/mach-s3c2410/mach-vr1000.c | |||
| @@ -395,7 +395,6 @@ static void __init vr1000_map_io(void) | |||
| 395 | 395 | ||
| 396 | MACHINE_START(VR1000, "Thorcom-VR1000") | 396 | MACHINE_START(VR1000, "Thorcom-VR1000") |
| 397 | /* Maintainer: Ben Dooks <ben@simtec.co.uk> */ | 397 | /* Maintainer: Ben Dooks <ben@simtec.co.uk> */ |
| 398 | .phys_ram = S3C2410_SDRAM_PA, | ||
| 399 | .phys_io = S3C2410_PA_UART, | 398 | .phys_io = S3C2410_PA_UART, |
| 400 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, | 399 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, |
| 401 | .boot_params = S3C2410_SDRAM_PA + 0x100, | 400 | .boot_params = S3C2410_SDRAM_PA + 0x100, |
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c index a66ac61233a2..a599bb0d4ab8 100644 --- a/arch/arm/mach-sa1100/assabet.c +++ b/arch/arm/mach-sa1100/assabet.c | |||
| @@ -447,7 +447,6 @@ static void __init assabet_map_io(void) | |||
| 447 | 447 | ||
| 448 | 448 | ||
| 449 | MACHINE_START(ASSABET, "Intel-Assabet") | 449 | MACHINE_START(ASSABET, "Intel-Assabet") |
| 450 | .phys_ram = 0xc0000000, | ||
| 451 | .phys_io = 0x80000000, | 450 | .phys_io = 0x80000000, |
| 452 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, | 451 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, |
| 453 | .boot_params = 0xc0000100, | 452 | .boot_params = 0xc0000100, |
diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c index edccd5eb06be..f60b7a66dfa0 100644 --- a/arch/arm/mach-sa1100/badge4.c +++ b/arch/arm/mach-sa1100/badge4.c | |||
| @@ -297,7 +297,6 @@ static void __init badge4_map_io(void) | |||
| 297 | } | 297 | } |
| 298 | 298 | ||
| 299 | MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4") | 299 | MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4") |
| 300 | .phys_ram = 0xc0000000, | ||
| 301 | .phys_io = 0x80000000, | 300 | .phys_io = 0x80000000, |
| 302 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, | 301 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, |
| 303 | .boot_params = 0xc0000100, | 302 | .boot_params = 0xc0000100, |
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c index 508593722bc7..8269a9ef9afe 100644 --- a/arch/arm/mach-sa1100/cerf.c +++ b/arch/arm/mach-sa1100/cerf.c | |||
| @@ -135,7 +135,6 @@ static void __init cerf_init(void) | |||
| 135 | 135 | ||
| 136 | MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube") | 136 | MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube") |
| 137 | /* Maintainer: support@intrinsyc.com */ | 137 | /* Maintainer: support@intrinsyc.com */ |
| 138 | .phys_ram = 0xc0000000, | ||
| 139 | .phys_io = 0x80000000, | 138 | .phys_io = 0x80000000, |
| 140 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, | 139 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, |
| 141 | .map_io = cerf_map_io, | 140 | .map_io = cerf_map_io, |
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index 522abc036d3a..6888816a1935 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c | |||
| @@ -191,7 +191,6 @@ static void __init collie_map_io(void) | |||
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | MACHINE_START(COLLIE, "Sharp-Collie") | 193 | MACHINE_START(COLLIE, "Sharp-Collie") |
| 194 | .phys_ram = 0xc0000000, | ||
| 195 | .phys_io = 0x80000000, | 194 | .phys_io = 0x80000000, |
| 196 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, | 195 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, |
| 197 | .map_io = collie_map_io, | 196 | .map_io = collie_map_io, |
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c index e8352b7f74b0..b04d92271020 100644 --- a/arch/arm/mach-sa1100/h3600.c +++ b/arch/arm/mach-sa1100/h3600.c | |||
| @@ -392,7 +392,6 @@ static void __init h3100_map_io(void) | |||
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | MACHINE_START(H3100, "Compaq iPAQ H3100") | 394 | MACHINE_START(H3100, "Compaq iPAQ H3100") |
| 395 | .phys_ram = 0xc0000000, | ||
| 396 | .phys_io = 0x80000000, | 395 | .phys_io = 0x80000000, |
| 397 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, | 396 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, |
| 398 | .boot_params = 0xc0000100, | 397 | .boot_params = 0xc0000100, |
| @@ -510,7 +509,6 @@ static void __init h3600_map_io(void) | |||
| 510 | } | 509 | } |
| 511 | 510 | ||
| 512 | MACHINE_START(H3600, "Compaq iPAQ H3600") | 511 | MACHINE_START(H3600, "Compaq iPAQ H3600") |
| 513 | .phys_ram = 0xc0000000, | ||
| 514 | .phys_io = 0x80000000, | 512 | .phys_io = 0x80000000, |
| 515 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, | 513 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, |
| 516 | .boot_params = 0xc0000100, | 514 | .boot_params = 0xc0000100, |
| @@ -897,7 +895,6 @@ static void __init h3800_map_io(void) | |||
| 897 | } | 895 | } |
| 898 | 896 | ||
| 899 | MACHINE_START(H3800, "Compaq iPAQ H3800") | 897 | MACHINE_START(H3800, "Compaq iPAQ H3800") |
| 900 | .phys_ram = 0xc0000000, | ||
| 901 | .phys_io = 0x80000000, | 898 | .phys_io = 0x80000000, |
| 902 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, | 899 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, |
| 903 | .boot_params = 0xc0000100, | 900 | .boot_params = 0xc0000100, |
diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c index c922e043c424..046b213efd5b 100644 --- a/arch/arm/mach-sa1100/hackkit.c +++ b/arch/arm/mach-sa1100/hackkit.c | |||
| @@ -195,7 +195,6 @@ static void __init hackkit_init(void) | |||
| 195 | */ | 195 | */ |
| 196 | 196 | ||
| 197 | MACHINE_START(HACKKIT, "HackKit Cpu Board") | 197 | MACHINE_START(HACKKIT, "HackKit Cpu Board") |
| 198 | .phys_ram = 0xc0000000, | ||
| 199 | .phys_io = 0x80000000, | 198 | .phys_io = 0x80000000, |
| 200 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, | 199 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, |
| 201 | .boot_params = 0xc0000100, | 200 | .boot_params = 0xc0000100, |
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c index 2f671cc3cb99..17f5a43acdb7 100644 --- a/arch/arm/mach-sa1100/jornada720.c +++ b/arch/arm/mach-sa1100/jornada720.c | |||
| @@ -173,7 +173,6 @@ static void __init jornada720_mach_init(void) | |||
| 173 | 173 | ||
| 174 | MACHINE_START(JORNADA720, "HP Jornada 720") | 174 | MACHINE_START(JORNADA720, "HP Jornada 720") |
| 175 | /* Maintainer: Michael Gernoth <michael@gernoth.net> */ | 175 | /* Maintainer: Michael Gernoth <michael@gernoth.net> */ |
| 176 | .phys_ram = 0xc0000000, | ||
| 177 | .phys_io = 0x80000000, | 176 | .phys_io = 0x80000000, |
| 178 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, | 177 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, |
| 179 | .boot_params = 0xc0000100, | 178 | .boot_params = 0xc0000100, |
diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c index 8c9e3dd52942..07d3a696ae7f 100644 --- a/arch/arm/mach-sa1100/lart.c +++ b/arch/arm/mach-sa1100/lart.c | |||
| @@ -60,7 +60,6 @@ static void __init lart_map_io(void) | |||
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | MACHINE_START(LART, "LART") | 62 | MACHINE_START(LART, "LART") |
| 63 | .phys_ram = 0xc0000000, | ||
| 64 | .phys_io = 0x80000000, | 63 | .phys_io = 0x80000000, |
| 65 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, | 64 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, |
| 66 | .boot_params = 0xc0000100, | 65 | .boot_params = 0xc0000100, |
diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c index 58c18f9e9b7b..0709ebab531c 100644 --- a/arch/arm/mach-sa1100/pleb.c +++ b/arch/arm/mach-sa1100/pleb.c | |||
| @@ -146,7 +146,6 @@ static void __init pleb_map_io(void) | |||
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | MACHINE_START(PLEB, "PLEB") | 148 | MACHINE_START(PLEB, "PLEB") |
| 149 | .phys_ram = 0xc0000000, | ||
| 150 | .phys_io = 0x80000000, | 149 | .phys_io = 0x80000000, |
| 151 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, | 150 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, |
| 152 | .map_io = pleb_map_io, | 151 | .map_io = pleb_map_io, |
diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c index 7482288278d9..5aafe0b56992 100644 --- a/arch/arm/mach-sa1100/shannon.c +++ b/arch/arm/mach-sa1100/shannon.c | |||
| @@ -83,7 +83,6 @@ static void __init shannon_map_io(void) | |||
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)") | 85 | MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)") |
| 86 | .phys_ram = 0xc0000000, | ||
| 87 | .phys_io = 0x80000000, | 86 | .phys_io = 0x80000000, |
| 88 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, | 87 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, |
| 89 | .boot_params = 0xc0000100, | 88 | .boot_params = 0xc0000100, |
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c index 439ddc9b06d6..d2c23b2c34d1 100644 --- a/arch/arm/mach-sa1100/simpad.c +++ b/arch/arm/mach-sa1100/simpad.c | |||
| @@ -229,7 +229,6 @@ arch_initcall(simpad_init); | |||
| 229 | 229 | ||
| 230 | MACHINE_START(SIMPAD, "Simpad") | 230 | MACHINE_START(SIMPAD, "Simpad") |
| 231 | /* Maintainer: Holger Freyther */ | 231 | /* Maintainer: Holger Freyther */ |
| 232 | .phys_ram = 0xc0000000, | ||
| 233 | .phys_io = 0x80000000, | 232 | .phys_io = 0x80000000, |
| 234 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, | 233 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, |
| 235 | .boot_params = 0xc0000100, | 234 | .boot_params = 0xc0000100, |
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c index 2d428b6dbb58..877600e212dd 100644 --- a/arch/arm/mach-shark/core.c +++ b/arch/arm/mach-shark/core.c | |||
| @@ -111,7 +111,6 @@ static struct sys_timer shark_timer = { | |||
| 111 | 111 | ||
| 112 | MACHINE_START(SHARK, "Shark") | 112 | MACHINE_START(SHARK, "Shark") |
| 113 | /* Maintainer: Alexander Schulz */ | 113 | /* Maintainer: Alexander Schulz */ |
| 114 | .phys_ram = 0x08000000, | ||
| 115 | .phys_io = 0x40000000, | 114 | .phys_io = 0x40000000, |
| 116 | .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, | 115 | .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, |
| 117 | .boot_params = 0x08003000, | 116 | .boot_params = 0x08003000, |
diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig index 8d787f4c78e6..95096afd5271 100644 --- a/arch/arm/mach-versatile/Kconfig +++ b/arch/arm/mach-versatile/Kconfig | |||
| @@ -9,7 +9,6 @@ config ARCH_VERSATILE_PB | |||
| 9 | 9 | ||
| 10 | config MACH_VERSATILE_AB | 10 | config MACH_VERSATILE_AB |
| 11 | bool "Support Versatile/AB platform" | 11 | bool "Support Versatile/AB platform" |
| 12 | default n | ||
| 13 | help | 12 | help |
| 14 | Include support for the ARM(R) Versatile/AP platform. | 13 | Include support for the ARM(R) Versatile/AP platform. |
| 15 | 14 | ||
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 90023745b23a..9ebbe808b41d 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <asm/leds.h> | 35 | #include <asm/leds.h> |
| 36 | #include <asm/hardware/arm_timer.h> | 36 | #include <asm/hardware/arm_timer.h> |
| 37 | #include <asm/hardware/icst307.h> | 37 | #include <asm/hardware/icst307.h> |
| 38 | #include <asm/hardware/vic.h> | ||
| 38 | 39 | ||
| 39 | #include <asm/mach/arch.h> | 40 | #include <asm/mach/arch.h> |
| 40 | #include <asm/mach/flash.h> | 41 | #include <asm/mach/flash.h> |
| @@ -56,24 +57,6 @@ | |||
| 56 | #define VA_VIC_BASE __io_address(VERSATILE_VIC_BASE) | 57 | #define VA_VIC_BASE __io_address(VERSATILE_VIC_BASE) |
| 57 | #define VA_SIC_BASE __io_address(VERSATILE_SIC_BASE) | 58 | #define VA_SIC_BASE __io_address(VERSATILE_SIC_BASE) |
| 58 | 59 | ||
| 59 | static void vic_mask_irq(unsigned int irq) | ||
| 60 | { | ||
| 61 | irq -= IRQ_VIC_START; | ||
| 62 | writel(1 << irq, VA_VIC_BASE + VIC_IRQ_ENABLE_CLEAR); | ||
| 63 | } | ||
| 64 | |||
| 65 | static void vic_unmask_irq(unsigned int irq) | ||
| 66 | { | ||
| 67 | irq -= IRQ_VIC_START; | ||
| 68 | writel(1 << irq, VA_VIC_BASE + VIC_IRQ_ENABLE); | ||
| 69 | } | ||
| 70 | |||
| 71 | static struct irqchip vic_chip = { | ||
| 72 | .ack = vic_mask_irq, | ||
| 73 | .mask = vic_mask_irq, | ||
| 74 | .unmask = vic_unmask_irq, | ||
| 75 | }; | ||
| 76 | |||
| 77 | static void sic_mask_irq(unsigned int irq) | 60 | static void sic_mask_irq(unsigned int irq) |
| 78 | { | 61 | { |
| 79 | irq -= IRQ_SIC_START; | 62 | irq -= IRQ_SIC_START; |
| @@ -127,43 +110,12 @@ sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) | |||
| 127 | 110 | ||
| 128 | void __init versatile_init_irq(void) | 111 | void __init versatile_init_irq(void) |
| 129 | { | 112 | { |
| 130 | unsigned int i, value; | 113 | unsigned int i; |
| 131 | |||
| 132 | /* Disable all interrupts initially. */ | ||
| 133 | 114 | ||
| 134 | writel(0, VA_VIC_BASE + VIC_INT_SELECT); | 115 | vic_init(VA_VIC_BASE, ~(1 << 31)); |
| 135 | writel(0, VA_VIC_BASE + VIC_IRQ_ENABLE); | ||
| 136 | writel(~0, VA_VIC_BASE + VIC_IRQ_ENABLE_CLEAR); | ||
| 137 | writel(0, VA_VIC_BASE + VIC_IRQ_STATUS); | ||
| 138 | writel(0, VA_VIC_BASE + VIC_ITCR); | ||
| 139 | writel(~0, VA_VIC_BASE + VIC_IRQ_SOFT_CLEAR); | ||
| 140 | |||
| 141 | /* | ||
| 142 | * Make sure we clear all existing interrupts | ||
| 143 | */ | ||
| 144 | writel(0, VA_VIC_BASE + VIC_VECT_ADDR); | ||
| 145 | for (i = 0; i < 19; i++) { | ||
| 146 | value = readl(VA_VIC_BASE + VIC_VECT_ADDR); | ||
| 147 | writel(value, VA_VIC_BASE + VIC_VECT_ADDR); | ||
| 148 | } | ||
| 149 | |||
| 150 | for (i = 0; i < 16; i++) { | ||
| 151 | value = readl(VA_VIC_BASE + VIC_VECT_CNTL0 + (i * 4)); | ||
| 152 | writel(value | VICVectCntl_Enable | i, VA_VIC_BASE + VIC_VECT_CNTL0 + (i * 4)); | ||
| 153 | } | ||
| 154 | |||
| 155 | writel(32, VA_VIC_BASE + VIC_DEF_VECT_ADDR); | ||
| 156 | |||
| 157 | for (i = IRQ_VIC_START; i <= IRQ_VIC_END; i++) { | ||
| 158 | if (i != IRQ_VICSOURCE31) { | ||
| 159 | set_irq_chip(i, &vic_chip); | ||
| 160 | set_irq_handler(i, do_level_IRQ); | ||
| 161 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); | ||
| 162 | } | ||
| 163 | } | ||
| 164 | 116 | ||
| 165 | set_irq_handler(IRQ_VICSOURCE31, sic_handle_irq); | 117 | set_irq_handler(IRQ_VICSOURCE31, sic_handle_irq); |
| 166 | vic_unmask_irq(IRQ_VICSOURCE31); | 118 | enable_irq(IRQ_VICSOURCE31); |
| 167 | 119 | ||
| 168 | /* Do second interrupt controller */ | 120 | /* Do second interrupt controller */ |
| 169 | writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); | 121 | writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); |
| @@ -877,7 +829,7 @@ static unsigned long versatile_gettimeoffset(void) | |||
| 877 | ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; | 829 | ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; |
| 878 | do { | 830 | do { |
| 879 | ticks1 = ticks2; | 831 | ticks1 = ticks2; |
| 880 | status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS); | 832 | status = __raw_readl(VA_IC_BASE + VIC_RAW_STATUS); |
| 881 | ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; | 833 | ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; |
| 882 | } while (ticks2 > ticks1); | 834 | } while (ticks2 > ticks1); |
| 883 | 835 | ||
diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c index e74c8a2fbb95..1eb596782078 100644 --- a/arch/arm/mach-versatile/versatile_ab.c +++ b/arch/arm/mach-versatile/versatile_ab.c | |||
| @@ -36,7 +36,6 @@ | |||
| 36 | 36 | ||
| 37 | MACHINE_START(VERSATILE_AB, "ARM-Versatile AB") | 37 | MACHINE_START(VERSATILE_AB, "ARM-Versatile AB") |
| 38 | /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ | 38 | /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ |
| 39 | .phys_ram = 0x00000000, | ||
| 40 | .phys_io = 0x101f1000, | 39 | .phys_io = 0x101f1000, |
| 41 | .io_pg_offst = ((0xf11f1000) >> 18) & 0xfffc, | 40 | .io_pg_offst = ((0xf11f1000) >> 18) & 0xfffc, |
| 42 | .boot_params = 0x00000100, | 41 | .boot_params = 0x00000100, |
diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c index 22d5ca07f75d..f17ab4fb548a 100644 --- a/arch/arm/mach-versatile/versatile_pb.c +++ b/arch/arm/mach-versatile/versatile_pb.c | |||
| @@ -100,7 +100,6 @@ arch_initcall(versatile_pb_init); | |||
| 100 | 100 | ||
| 101 | MACHINE_START(VERSATILE_PB, "ARM-Versatile PB") | 101 | MACHINE_START(VERSATILE_PB, "ARM-Versatile PB") |
| 102 | /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ | 102 | /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ |
| 103 | .phys_ram = 0x00000000, | ||
| 104 | .phys_io = 0x101f1000, | 103 | .phys_io = 0x101f1000, |
| 105 | .io_pg_offst = ((0xf11f1000) >> 18) & 0xfffc, | 104 | .io_pg_offst = ((0xf11f1000) >> 18) & 0xfffc, |
| 106 | .boot_params = 0x00000100, | 105 | .boot_params = 0x00000100, |
diff --git a/arch/arm/nwfpe/fpa11.h b/arch/arm/nwfpe/fpa11.h index da4c616b6c49..28cd79a451d3 100644 --- a/arch/arm/nwfpe/fpa11.h +++ b/arch/arm/nwfpe/fpa11.h | |||
| @@ -62,7 +62,7 @@ typedef union tagFPREG { | |||
| 62 | #else | 62 | #else |
| 63 | u32 padding[3]; | 63 | u32 padding[3]; |
| 64 | #endif | 64 | #endif |
| 65 | } FPREG; | 65 | } __attribute__ ((packed,aligned(4))) FPREG; |
| 66 | 66 | ||
| 67 | /* | 67 | /* |
| 68 | * FPA11 device model. | 68 | * FPA11 device model. |
| @@ -89,7 +89,7 @@ typedef struct tagFPA11 { | |||
| 89 | so we can use it to detect whether this | 89 | so we can use it to detect whether this |
| 90 | instance of the emulator needs to be | 90 | instance of the emulator needs to be |
| 91 | initialised. */ | 91 | initialised. */ |
| 92 | } FPA11; | 92 | } __attribute__ ((packed,aligned(4))) FPA11; |
| 93 | 93 | ||
| 94 | extern int8 SetRoundingMode(const unsigned int); | 94 | extern int8 SetRoundingMode(const unsigned int); |
| 95 | extern int8 SetRoundingPrecision(const unsigned int); | 95 | extern int8 SetRoundingPrecision(const unsigned int); |
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index 9693e9b4ffd1..0887bb2a2551 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig | |||
| @@ -22,7 +22,6 @@ comment "OMAP Feature Selections" | |||
| 22 | config OMAP_RESET_CLOCKS | 22 | config OMAP_RESET_CLOCKS |
| 23 | bool "Reset unused clocks during boot" | 23 | bool "Reset unused clocks during boot" |
| 24 | depends on ARCH_OMAP | 24 | depends on ARCH_OMAP |
| 25 | default n | ||
| 26 | help | 25 | help |
| 27 | Say Y if you want to reset unused clocks during boot. | 26 | Say Y if you want to reset unused clocks during boot. |
| 28 | This option saves power, but assumes all drivers are | 27 | This option saves power, but assumes all drivers are |
| @@ -44,7 +43,6 @@ config OMAP_MUX | |||
| 44 | config OMAP_MUX_DEBUG | 43 | config OMAP_MUX_DEBUG |
| 45 | bool "Multiplexing debug output" | 44 | bool "Multiplexing debug output" |
| 46 | depends on OMAP_MUX | 45 | depends on OMAP_MUX |
| 47 | default n | ||
| 48 | help | 46 | help |
| 49 | Makes the multiplexing functions print out a lot of debug info. | 47 | Makes the multiplexing functions print out a lot of debug info. |
| 50 | This is useful if you want to find out the correct values of the | 48 | This is useful if you want to find out the correct values of the |
| @@ -93,7 +91,6 @@ config OMAP_32K_TIMER_HZ | |||
| 93 | 91 | ||
| 94 | config OMAP_DM_TIMER | 92 | config OMAP_DM_TIMER |
| 95 | bool "Use dual-mode timer" | 93 | bool "Use dual-mode timer" |
| 96 | default n | ||
| 97 | depends on ARCH_OMAP16XX | 94 | depends on ARCH_OMAP16XX |
| 98 | help | 95 | help |
| 99 | Select this option if you want to use OMAP Dual-Mode timers. | 96 | Select this option if you want to use OMAP Dual-Mode timers. |
diff --git a/arch/arm26/kernel/irq.c b/arch/arm26/kernel/irq.c index f3cc1036e5bc..0934e6fba606 100644 --- a/arch/arm26/kernel/irq.c +++ b/arch/arm26/kernel/irq.c | |||
| @@ -141,7 +141,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
| 141 | if (i < NR_IRQS) { | 141 | if (i < NR_IRQS) { |
| 142 | action = irq_desc[i].action; | 142 | action = irq_desc[i].action; |
| 143 | if (!action) | 143 | if (!action) |
| 144 | continue; | 144 | goto out; |
| 145 | seq_printf(p, "%3d: %10u ", i, kstat_irqs(i)); | 145 | seq_printf(p, "%3d: %10u ", i, kstat_irqs(i)); |
| 146 | seq_printf(p, " %s", action->name); | 146 | seq_printf(p, " %s", action->name); |
| 147 | for (action = action->next; action; action = action->next) { | 147 | for (action = action->next; action; action = action->next) { |
| @@ -152,6 +152,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
| 152 | show_fiq_list(p, v); | 152 | show_fiq_list(p, v); |
| 153 | seq_printf(p, "Err: %10lu\n", irq_err_count); | 153 | seq_printf(p, "Err: %10lu\n", irq_err_count); |
| 154 | } | 154 | } |
| 155 | out: | ||
| 155 | return 0; | 156 | return 0; |
| 156 | } | 157 | } |
| 157 | 158 | ||
diff --git a/arch/arm26/kernel/ptrace.c b/arch/arm26/kernel/ptrace.c index 3c3371d4683e..282e24d79328 100644 --- a/arch/arm26/kernel/ptrace.c +++ b/arch/arm26/kernel/ptrace.c | |||
| @@ -527,7 +527,7 @@ static int ptrace_getfpregs(struct task_struct *tsk, void *ufp) | |||
| 527 | static int ptrace_setfpregs(struct task_struct *tsk, void *ufp) | 527 | static int ptrace_setfpregs(struct task_struct *tsk, void *ufp) |
| 528 | { | 528 | { |
| 529 | set_stopped_child_used_math(tsk); | 529 | set_stopped_child_used_math(tsk); |
| 530 | return copy_from_user(&task_threas_info(tsk)->fpstate, ufp, | 530 | return copy_from_user(&task_thread_info(tsk)->fpstate, ufp, |
| 531 | sizeof(struct user_fp)) ? -EFAULT : 0; | 531 | sizeof(struct user_fp)) ? -EFAULT : 0; |
| 532 | } | 532 | } |
| 533 | 533 | ||
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index d5d0df7f04fc..cbde675bc95c 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
| @@ -702,6 +702,15 @@ config PHYSICAL_START | |||
| 702 | 702 | ||
| 703 | Don't change this unless you know what you are doing. | 703 | Don't change this unless you know what you are doing. |
| 704 | 704 | ||
| 705 | config HOTPLUG_CPU | ||
| 706 | bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" | ||
| 707 | depends on SMP && HOTPLUG && EXPERIMENTAL | ||
| 708 | ---help--- | ||
| 709 | Say Y here to experiment with turning CPUs off and on. CPUs | ||
| 710 | can be controlled through /sys/devices/system/cpu. | ||
| 711 | |||
| 712 | Say N. | ||
| 713 | |||
| 705 | endmenu | 714 | endmenu |
| 706 | 715 | ||
| 707 | 716 | ||
| @@ -988,15 +997,6 @@ config SCx200 | |||
| 988 | This support is also available as a module. If compiled as a | 997 | This support is also available as a module. If compiled as a |
| 989 | module, it will be called scx200. | 998 | module, it will be called scx200. |
| 990 | 999 | ||
| 991 | config HOTPLUG_CPU | ||
| 992 | bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" | ||
| 993 | depends on SMP && HOTPLUG && EXPERIMENTAL | ||
| 994 | ---help--- | ||
| 995 | Say Y here to experiment with turning CPUs off and on. CPUs | ||
| 996 | can be controlled through /sys/devices/system/cpu. | ||
| 997 | |||
| 998 | Say N. | ||
| 999 | |||
| 1000 | source "drivers/pcmcia/Kconfig" | 1000 | source "drivers/pcmcia/Kconfig" |
| 1001 | 1001 | ||
| 1002 | source "drivers/pci/hotplug/Kconfig" | 1002 | source "drivers/pci/hotplug/Kconfig" |
diff --git a/arch/i386/Makefile b/arch/i386/Makefile index d3c0409d201c..36bef6543ac1 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile | |||
| @@ -37,14 +37,11 @@ CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2) | |||
| 37 | # CPU-specific tuning. Anything which can be shared with UML should go here. | 37 | # CPU-specific tuning. Anything which can be shared with UML should go here. |
| 38 | include $(srctree)/arch/i386/Makefile.cpu | 38 | include $(srctree)/arch/i386/Makefile.cpu |
| 39 | 39 | ||
| 40 | # -mregparm=3 works ok on gcc-3.0 and later | 40 | cflags-$(CONFIG_REGPARM) += -mregparm=3 |
| 41 | # | ||
| 42 | cflags-$(CONFIG_REGPARM) += $(shell if [ $(call cc-version) -ge 0300 ] ; then \ | ||
| 43 | echo "-mregparm=3"; fi ;) | ||
| 44 | 41 | ||
| 45 | # Disable unit-at-a-time mode, it makes gcc use a lot more stack | 42 | # Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use |
| 46 | # due to the lack of sharing of stacklots. | 43 | # a lot more stack due to the lack of sharing of stacklots: |
| 47 | CFLAGS += $(call cc-option,-fno-unit-at-a-time) | 44 | CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;) |
| 48 | 45 | ||
| 49 | CFLAGS += $(cflags-y) | 46 | CFLAGS += $(cflags-y) |
| 50 | 47 | ||
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 0fbbd4c1072e..e11a09207ec8 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c | |||
| @@ -980,7 +980,7 @@ static int powernowk8_verify(struct cpufreq_policy *pol) | |||
| 980 | } | 980 | } |
| 981 | 981 | ||
| 982 | /* per CPU init entry point to the driver */ | 982 | /* per CPU init entry point to the driver */ |
| 983 | static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) | 983 | static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) |
| 984 | { | 984 | { |
| 985 | struct powernow_k8_data *data; | 985 | struct powernow_k8_data *data; |
| 986 | cpumask_t oldmask = CPU_MASK_ALL; | 986 | cpumask_t oldmask = CPU_MASK_ALL; |
| @@ -1141,7 +1141,7 @@ static struct cpufreq_driver cpufreq_amd64_driver = { | |||
| 1141 | }; | 1141 | }; |
| 1142 | 1142 | ||
| 1143 | /* driver entry point for init */ | 1143 | /* driver entry point for init */ |
| 1144 | static int __init powernowk8_init(void) | 1144 | static int __cpuinit powernowk8_init(void) |
| 1145 | { | 1145 | { |
| 1146 | unsigned int i, supported_cpus = 0; | 1146 | unsigned int i, supported_cpus = 0; |
| 1147 | 1147 | ||
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index b9f0030a2ebb..0aaebf3e1cfa 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
| @@ -112,33 +112,38 @@ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) | |||
| 112 | p < (void *)tinfo + THREAD_SIZE - 3; | 112 | p < (void *)tinfo + THREAD_SIZE - 3; |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | static void print_addr_and_symbol(unsigned long addr, char *log_lvl) | ||
| 116 | { | ||
| 117 | printk(log_lvl); | ||
| 118 | printk(" [<%08lx>] ", addr); | ||
| 119 | print_symbol("%s", addr); | ||
| 120 | printk("\n"); | ||
| 121 | } | ||
| 122 | |||
| 115 | static inline unsigned long print_context_stack(struct thread_info *tinfo, | 123 | static inline unsigned long print_context_stack(struct thread_info *tinfo, |
| 116 | unsigned long *stack, unsigned long ebp) | 124 | unsigned long *stack, unsigned long ebp, |
| 125 | char *log_lvl) | ||
| 117 | { | 126 | { |
| 118 | unsigned long addr; | 127 | unsigned long addr; |
| 119 | 128 | ||
| 120 | #ifdef CONFIG_FRAME_POINTER | 129 | #ifdef CONFIG_FRAME_POINTER |
| 121 | while (valid_stack_ptr(tinfo, (void *)ebp)) { | 130 | while (valid_stack_ptr(tinfo, (void *)ebp)) { |
| 122 | addr = *(unsigned long *)(ebp + 4); | 131 | addr = *(unsigned long *)(ebp + 4); |
| 123 | printk(KERN_EMERG " [<%08lx>] ", addr); | 132 | print_addr_and_symbol(addr, log_lvl); |
| 124 | print_symbol("%s", addr); | ||
| 125 | printk("\n"); | ||
| 126 | ebp = *(unsigned long *)ebp; | 133 | ebp = *(unsigned long *)ebp; |
| 127 | } | 134 | } |
| 128 | #else | 135 | #else |
| 129 | while (valid_stack_ptr(tinfo, stack)) { | 136 | while (valid_stack_ptr(tinfo, stack)) { |
| 130 | addr = *stack++; | 137 | addr = *stack++; |
| 131 | if (__kernel_text_address(addr)) { | 138 | if (__kernel_text_address(addr)) |
| 132 | printk(KERN_EMERG " [<%08lx>]", addr); | 139 | print_addr_and_symbol(addr, log_lvl); |
| 133 | print_symbol(" %s", addr); | ||
| 134 | printk("\n"); | ||
| 135 | } | ||
| 136 | } | 140 | } |
| 137 | #endif | 141 | #endif |
| 138 | return ebp; | 142 | return ebp; |
| 139 | } | 143 | } |
| 140 | 144 | ||
| 141 | void show_trace(struct task_struct *task, unsigned long * stack) | 145 | static void show_trace_log_lvl(struct task_struct *task, |
| 146 | unsigned long *stack, char *log_lvl) | ||
| 142 | { | 147 | { |
| 143 | unsigned long ebp; | 148 | unsigned long ebp; |
| 144 | 149 | ||
| @@ -157,7 +162,7 @@ void show_trace(struct task_struct *task, unsigned long * stack) | |||
| 157 | struct thread_info *context; | 162 | struct thread_info *context; |
| 158 | context = (struct thread_info *) | 163 | context = (struct thread_info *) |
| 159 | ((unsigned long)stack & (~(THREAD_SIZE - 1))); | 164 | ((unsigned long)stack & (~(THREAD_SIZE - 1))); |
| 160 | ebp = print_context_stack(context, stack, ebp); | 165 | ebp = print_context_stack(context, stack, ebp, log_lvl); |
| 161 | stack = (unsigned long*)context->previous_esp; | 166 | stack = (unsigned long*)context->previous_esp; |
| 162 | if (!stack) | 167 | if (!stack) |
| 163 | break; | 168 | break; |
| @@ -165,7 +170,13 @@ void show_trace(struct task_struct *task, unsigned long * stack) | |||
| 165 | } | 170 | } |
| 166 | } | 171 | } |
| 167 | 172 | ||
| 168 | void show_stack(struct task_struct *task, unsigned long *esp) | 173 | void show_trace(struct task_struct *task, unsigned long * stack) |
| 174 | { | ||
| 175 | show_trace_log_lvl(task, stack, ""); | ||
| 176 | } | ||
| 177 | |||
| 178 | static void show_stack_log_lvl(struct task_struct *task, unsigned long *esp, | ||
| 179 | char *log_lvl) | ||
| 169 | { | 180 | { |
| 170 | unsigned long *stack; | 181 | unsigned long *stack; |
| 171 | int i; | 182 | int i; |
| @@ -178,16 +189,26 @@ void show_stack(struct task_struct *task, unsigned long *esp) | |||
| 178 | } | 189 | } |
| 179 | 190 | ||
| 180 | stack = esp; | 191 | stack = esp; |
| 181 | printk(KERN_EMERG); | 192 | printk(log_lvl); |
| 182 | for(i = 0; i < kstack_depth_to_print; i++) { | 193 | for(i = 0; i < kstack_depth_to_print; i++) { |
| 183 | if (kstack_end(stack)) | 194 | if (kstack_end(stack)) |
| 184 | break; | 195 | break; |
| 185 | if (i && ((i % 8) == 0)) | 196 | if (i && ((i % 8) == 0)) { |
| 186 | printk("\n" KERN_EMERG " "); | 197 | printk("\n"); |
| 198 | printk(log_lvl); | ||
| 199 | printk(" "); | ||
| 200 | } | ||
| 187 | printk("%08lx ", *stack++); | 201 | printk("%08lx ", *stack++); |
| 188 | } | 202 | } |
| 189 | printk("\n" KERN_EMERG "Call Trace:\n"); | 203 | printk("\n"); |
| 190 | show_trace(task, esp); | 204 | printk(log_lvl); |
| 205 | printk("Call Trace:\n"); | ||
| 206 | show_trace_log_lvl(task, esp, log_lvl); | ||
| 207 | } | ||
| 208 | |||
| 209 | void show_stack(struct task_struct *task, unsigned long *esp) | ||
| 210 | { | ||
| 211 | show_stack_log_lvl(task, esp, ""); | ||
| 191 | } | 212 | } |
| 192 | 213 | ||
| 193 | /* | 214 | /* |
| @@ -238,7 +259,7 @@ void show_registers(struct pt_regs *regs) | |||
| 238 | u8 __user *eip; | 259 | u8 __user *eip; |
| 239 | 260 | ||
| 240 | printk("\n" KERN_EMERG "Stack: "); | 261 | printk("\n" KERN_EMERG "Stack: "); |
| 241 | show_stack(NULL, (unsigned long*)esp); | 262 | show_stack_log_lvl(NULL, (unsigned long *)esp, KERN_EMERG); |
| 242 | 263 | ||
| 243 | printk(KERN_EMERG "Code: "); | 264 | printk(KERN_EMERG "Code: "); |
| 244 | 265 | ||
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c index 0c90ae54ddfa..f51c894a7da5 100644 --- a/arch/i386/kernel/vm86.c +++ b/arch/i386/kernel/vm86.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * Copyright (C) 1994 Linus Torvalds | 4 | * Copyright (C) 1994 Linus Torvalds |
| 5 | * | 5 | * |
| 6 | * 29 dec 2001 - Fixed oopses caused by unchecked access to the vm86 | 6 | * 29 dec 2001 - Fixed oopses caused by unchecked access to the vm86 |
| 7 | * stack - Manfred Spraul <manfreds@colorfullife.com> | 7 | * stack - Manfred Spraul <manfred@colorfullife.com> |
| 8 | * | 8 | * |
| 9 | * 22 mar 2002 - Manfred detected the stackfaults, but didn't handle | 9 | * 22 mar 2002 - Manfred detected the stackfaults, but didn't handle |
| 10 | * them correctly. Now the emulation will be in a | 10 | * them correctly. Now the emulation will be in a |
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 7df494b51a5b..2700f01994ba 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c | |||
| @@ -268,7 +268,7 @@ static void __init permanent_kmaps_init(pgd_t *pgd_base) | |||
| 268 | pkmap_page_table = pte; | 268 | pkmap_page_table = pte; |
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | static void __devinit free_new_highpage(struct page *page) | 271 | static void __meminit free_new_highpage(struct page *page) |
| 272 | { | 272 | { |
| 273 | set_page_count(page, 1); | 273 | set_page_count(page, 1); |
| 274 | __free_page(page); | 274 | __free_page(page); |
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c index 65f67070db64..83c3645ccc43 100644 --- a/arch/i386/pci/fixup.c +++ b/arch/i386/pci/fixup.c | |||
| @@ -449,3 +449,19 @@ static void __devinit pci_post_fixup_toshiba_ohci1394(struct pci_dev *dev) | |||
| 449 | } | 449 | } |
| 450 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_TI, 0x8032, | 450 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_TI, 0x8032, |
| 451 | pci_post_fixup_toshiba_ohci1394); | 451 | pci_post_fixup_toshiba_ohci1394); |
| 452 | |||
| 453 | |||
| 454 | /* | ||
| 455 | * Prevent the BIOS trapping accesses to the Cyrix CS5530A video device | ||
| 456 | * configuration space. | ||
| 457 | */ | ||
| 458 | static void __devinit pci_early_fixup_cyrix_5530(struct pci_dev *dev) | ||
| 459 | { | ||
| 460 | u8 r; | ||
| 461 | /* clear 'F4 Video Configuration Trap' bit */ | ||
| 462 | pci_read_config_byte(dev, 0x42, &r); | ||
| 463 | r &= 0xfd; | ||
| 464 | pci_write_config_byte(dev, 0x42, r); | ||
| 465 | } | ||
| 466 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, | ||
| 467 | pci_early_fixup_cyrix_5530); | ||
diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig index 80f8663bc6d9..1d07d8072ec2 100644 --- a/arch/ia64/configs/gensparse_defconfig +++ b/arch/ia64/configs/gensparse_defconfig | |||
| @@ -701,6 +701,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y | |||
| 701 | CONFIG_SERIAL_SGI_L1_CONSOLE=y | 701 | CONFIG_SERIAL_SGI_L1_CONSOLE=y |
| 702 | # CONFIG_SERIAL_JSM is not set | 702 | # CONFIG_SERIAL_JSM is not set |
| 703 | CONFIG_SERIAL_SGI_IOC4=y | 703 | CONFIG_SERIAL_SGI_IOC4=y |
| 704 | CONFIG_SERIAL_SGI_IOC3=y | ||
| 704 | CONFIG_UNIX98_PTYS=y | 705 | CONFIG_UNIX98_PTYS=y |
| 705 | CONFIG_LEGACY_PTYS=y | 706 | CONFIG_LEGACY_PTYS=y |
| 706 | CONFIG_LEGACY_PTY_COUNT=256 | 707 | CONFIG_LEGACY_PTY_COUNT=256 |
| @@ -1046,6 +1047,7 @@ CONFIG_INFINIBAND_IPOIB=m | |||
| 1046 | # SN Devices | 1047 | # SN Devices |
| 1047 | # | 1048 | # |
| 1048 | CONFIG_SGI_IOC4=y | 1049 | CONFIG_SGI_IOC4=y |
| 1050 | CONFIG_SGI_IOC3=y | ||
| 1049 | 1051 | ||
| 1050 | # | 1052 | # |
| 1051 | # File systems | 1053 | # File systems |
diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig index ff8bb3770c9d..3cb503b659e6 100644 --- a/arch/ia64/configs/sn2_defconfig +++ b/arch/ia64/configs/sn2_defconfig | |||
| @@ -659,6 +659,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y | |||
| 659 | CONFIG_SERIAL_SGI_L1_CONSOLE=y | 659 | CONFIG_SERIAL_SGI_L1_CONSOLE=y |
| 660 | # CONFIG_SERIAL_JSM is not set | 660 | # CONFIG_SERIAL_JSM is not set |
| 661 | CONFIG_SERIAL_SGI_IOC4=y | 661 | CONFIG_SERIAL_SGI_IOC4=y |
| 662 | CONFIG_SERIAL_SGI_IOC3=y | ||
| 662 | CONFIG_UNIX98_PTYS=y | 663 | CONFIG_UNIX98_PTYS=y |
| 663 | CONFIG_LEGACY_PTYS=y | 664 | CONFIG_LEGACY_PTYS=y |
| 664 | CONFIG_LEGACY_PTY_COUNT=256 | 665 | CONFIG_LEGACY_PTY_COUNT=256 |
| @@ -899,6 +900,7 @@ CONFIG_INFINIBAND_SRP=m | |||
| 899 | # SN Devices | 900 | # SN Devices |
| 900 | # | 901 | # |
| 901 | CONFIG_SGI_IOC4=y | 902 | CONFIG_SGI_IOC4=y |
| 903 | CONFIG_SGI_IOC3=y | ||
| 902 | 904 | ||
| 903 | # | 905 | # |
| 904 | # File systems | 906 | # File systems |
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index a346e1833bf2..626cdc83668b 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c | |||
| @@ -108,7 +108,6 @@ static struct async_struct *IRQ_ports[NR_IRQS]; | |||
| 108 | static struct console *console; | 108 | static struct console *console; |
| 109 | 109 | ||
| 110 | static unsigned char *tmp_buf; | 110 | static unsigned char *tmp_buf; |
| 111 | static DECLARE_MUTEX(tmp_buf_sem); | ||
| 112 | 111 | ||
| 113 | extern struct console *console_drivers; /* from kernel/printk.c */ | 112 | extern struct console *console_drivers; /* from kernel/printk.c */ |
| 114 | 113 | ||
| @@ -167,15 +166,9 @@ static void receive_chars(struct tty_struct *tty, struct pt_regs *regs) | |||
| 167 | } | 166 | } |
| 168 | } | 167 | } |
| 169 | seen_esc = 0; | 168 | seen_esc = 0; |
| 170 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) break; | ||
| 171 | 169 | ||
| 172 | *tty->flip.char_buf_ptr = ch; | 170 | if (tty_insert_flip_char(tty, ch, TTY_NORMAL) == 0) |
| 173 | 171 | break; | |
| 174 | *tty->flip.flag_buf_ptr = 0; | ||
| 175 | |||
| 176 | tty->flip.flag_buf_ptr++; | ||
| 177 | tty->flip.char_buf_ptr++; | ||
| 178 | tty->flip.count++; | ||
| 179 | } | 172 | } |
| 180 | tty_flip_buffer_push(tty); | 173 | tty_flip_buffer_push(tty); |
| 181 | } | 174 | } |
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index 2ddbac6f4999..ce423910ca97 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S | |||
| @@ -903,5 +903,6 @@ fsyscall_table: | |||
| 903 | data8 0 | 903 | data8 0 |
| 904 | data8 0 | 904 | data8 0 |
| 905 | data8 0 | 905 | data8 0 |
| 906 | data8 0 // 1280 | ||
| 906 | 907 | ||
| 907 | .org fsyscall_table + 8*NR_syscalls // guard against failures to increase NR_syscalls | 908 | .org fsyscall_table + 8*NR_syscalls // guard against failures to increase NR_syscalls |
diff --git a/arch/ia64/kernel/jprobes.S b/arch/ia64/kernel/jprobes.S index 2323377e3695..5cd6226f44f2 100644 --- a/arch/ia64/kernel/jprobes.S +++ b/arch/ia64/kernel/jprobes.S | |||
| @@ -60,3 +60,30 @@ END(jprobe_break) | |||
| 60 | GLOBAL_ENTRY(jprobe_inst_return) | 60 | GLOBAL_ENTRY(jprobe_inst_return) |
| 61 | br.call.sptk.many b0=jprobe_break | 61 | br.call.sptk.many b0=jprobe_break |
| 62 | END(jprobe_inst_return) | 62 | END(jprobe_inst_return) |
| 63 | |||
| 64 | GLOBAL_ENTRY(invalidate_stacked_regs) | ||
| 65 | movl r16=invalidate_restore_cfm | ||
| 66 | ;; | ||
| 67 | mov b6=r16 | ||
| 68 | ;; | ||
| 69 | br.ret.sptk.many b6 | ||
| 70 | ;; | ||
| 71 | invalidate_restore_cfm: | ||
| 72 | mov r16=ar.rsc | ||
| 73 | ;; | ||
| 74 | mov ar.rsc=r0 | ||
| 75 | ;; | ||
| 76 | loadrs | ||
| 77 | ;; | ||
| 78 | mov ar.rsc=r16 | ||
| 79 | ;; | ||
| 80 | br.cond.sptk.many rp | ||
| 81 | END(invalidate_stacked_regs) | ||
| 82 | |||
| 83 | GLOBAL_ENTRY(flush_register_stack) | ||
| 84 | // flush dirty regs to backing store (must be first in insn group) | ||
| 85 | flushrs | ||
| 86 | ;; | ||
| 87 | br.ret.sptk.many rp | ||
| 88 | END(flush_register_stack) | ||
| 89 | |||
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 346fedf9ea47..50ae8c7d453d 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c | |||
| @@ -766,11 +766,56 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | |||
| 766 | return ret; | 766 | return ret; |
| 767 | } | 767 | } |
| 768 | 768 | ||
| 769 | struct param_bsp_cfm { | ||
| 770 | unsigned long ip; | ||
| 771 | unsigned long *bsp; | ||
| 772 | unsigned long cfm; | ||
| 773 | }; | ||
| 774 | |||
| 775 | static void ia64_get_bsp_cfm(struct unw_frame_info *info, void *arg) | ||
| 776 | { | ||
| 777 | unsigned long ip; | ||
| 778 | struct param_bsp_cfm *lp = arg; | ||
| 779 | |||
| 780 | do { | ||
| 781 | unw_get_ip(info, &ip); | ||
| 782 | if (ip == 0) | ||
| 783 | break; | ||
| 784 | if (ip == lp->ip) { | ||
| 785 | unw_get_bsp(info, (unsigned long*)&lp->bsp); | ||
| 786 | unw_get_cfm(info, (unsigned long*)&lp->cfm); | ||
| 787 | return; | ||
| 788 | } | ||
| 789 | } while (unw_unwind(info) >= 0); | ||
| 790 | lp->bsp = 0; | ||
| 791 | lp->cfm = 0; | ||
| 792 | return; | ||
| 793 | } | ||
| 794 | |||
| 769 | int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | 795 | int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) |
| 770 | { | 796 | { |
| 771 | struct jprobe *jp = container_of(p, struct jprobe, kp); | 797 | struct jprobe *jp = container_of(p, struct jprobe, kp); |
| 772 | unsigned long addr = ((struct fnptr *)(jp->entry))->ip; | 798 | unsigned long addr = ((struct fnptr *)(jp->entry))->ip; |
| 773 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 799 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
| 800 | struct param_bsp_cfm pa; | ||
| 801 | int bytes; | ||
| 802 | |||
| 803 | /* | ||
| 804 | * Callee owns the argument space and could overwrite it, eg | ||
| 805 | * tail call optimization. So to be absolutely safe | ||
| 806 | * we save the argument space before transfering the control | ||
| 807 | * to instrumented jprobe function which runs in | ||
| 808 | * the process context | ||
| 809 | */ | ||
| 810 | pa.ip = regs->cr_iip; | ||
| 811 | unw_init_running(ia64_get_bsp_cfm, &pa); | ||
| 812 | bytes = (char *)ia64_rse_skip_regs(pa.bsp, pa.cfm & 0x3f) | ||
| 813 | - (char *)pa.bsp; | ||
| 814 | memcpy( kcb->jprobes_saved_stacked_regs, | ||
| 815 | pa.bsp, | ||
| 816 | bytes ); | ||
| 817 | kcb->bsp = pa.bsp; | ||
| 818 | kcb->cfm = pa.cfm; | ||
| 774 | 819 | ||
| 775 | /* save architectural state */ | 820 | /* save architectural state */ |
| 776 | kcb->jprobe_saved_regs = *regs; | 821 | kcb->jprobe_saved_regs = *regs; |
| @@ -792,8 +837,20 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | |||
| 792 | int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | 837 | int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) |
| 793 | { | 838 | { |
| 794 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 839 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
| 840 | int bytes; | ||
| 795 | 841 | ||
| 842 | /* restoring architectural state */ | ||
| 796 | *regs = kcb->jprobe_saved_regs; | 843 | *regs = kcb->jprobe_saved_regs; |
| 844 | |||
| 845 | /* restoring the original argument space */ | ||
| 846 | flush_register_stack(); | ||
| 847 | bytes = (char *)ia64_rse_skip_regs(kcb->bsp, kcb->cfm & 0x3f) | ||
| 848 | - (char *)kcb->bsp; | ||
| 849 | memcpy( kcb->bsp, | ||
| 850 | kcb->jprobes_saved_stacked_regs, | ||
| 851 | bytes ); | ||
| 852 | invalidate_stacked_regs(); | ||
| 853 | |||
| 797 | preempt_enable_no_resched(); | 854 | preempt_enable_no_resched(); |
| 798 | return 1; | 855 | return 1; |
| 799 | } | 856 | } |
diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S index db32fc1d3935..403a80a58c13 100644 --- a/arch/ia64/kernel/mca_asm.S +++ b/arch/ia64/kernel/mca_asm.S | |||
| @@ -847,7 +847,7 @@ ia64_state_restore: | |||
| 847 | ;; | 847 | ;; |
| 848 | mov cr.iim=temp3 | 848 | mov cr.iim=temp3 |
| 849 | mov cr.iha=temp4 | 849 | mov cr.iha=temp4 |
| 850 | dep r22=0,r22,62,2 // pal_min_state, physical, uncached | 850 | dep r22=0,r22,62,1 // pal_min_state, physical, uncached |
| 851 | mov IA64_KR(CURRENT)=r21 | 851 | mov IA64_KR(CURRENT)=r21 |
| 852 | ld8 r8=[temp1] // os_status | 852 | ld8 r8=[temp1] // os_status |
| 853 | ld8 r10=[temp2] // context | 853 | ld8 r10=[temp2] // context |
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index bd87cb6b7a81..2ea4b39efffa 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
| @@ -628,9 +628,11 @@ static int pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, | |||
| 628 | 628 | ||
| 629 | #include "perfmon_itanium.h" | 629 | #include "perfmon_itanium.h" |
| 630 | #include "perfmon_mckinley.h" | 630 | #include "perfmon_mckinley.h" |
| 631 | #include "perfmon_montecito.h" | ||
| 631 | #include "perfmon_generic.h" | 632 | #include "perfmon_generic.h" |
| 632 | 633 | ||
| 633 | static pmu_config_t *pmu_confs[]={ | 634 | static pmu_config_t *pmu_confs[]={ |
| 635 | &pmu_conf_mont, | ||
| 634 | &pmu_conf_mck, | 636 | &pmu_conf_mck, |
| 635 | &pmu_conf_ita, | 637 | &pmu_conf_ita, |
| 636 | &pmu_conf_gen, /* must be last */ | 638 | &pmu_conf_gen, /* must be last */ |
diff --git a/arch/ia64/kernel/perfmon_montecito.h b/arch/ia64/kernel/perfmon_montecito.h new file mode 100644 index 000000000000..cd06ac6a686c --- /dev/null +++ b/arch/ia64/kernel/perfmon_montecito.h | |||
| @@ -0,0 +1,269 @@ | |||
| 1 | /* | ||
| 2 | * This file contains the Montecito PMU register description tables | ||
| 3 | * and pmc checker used by perfmon.c. | ||
| 4 | * | ||
| 5 | * Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P. | ||
| 6 | * Contributed by Stephane Eranian <eranian@hpl.hp.com> | ||
| 7 | */ | ||
| 8 | static int pfm_mont_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs); | ||
| 9 | |||
| 10 | #define RDEP_MONT_ETB (RDEP(38)|RDEP(39)|RDEP(48)|RDEP(49)|RDEP(50)|RDEP(51)|RDEP(52)|RDEP(53)|RDEP(54)|\ | ||
| 11 | RDEP(55)|RDEP(56)|RDEP(57)|RDEP(58)|RDEP(59)|RDEP(60)|RDEP(61)|RDEP(62)|RDEP(63)) | ||
| 12 | #define RDEP_MONT_DEAR (RDEP(32)|RDEP(33)|RDEP(36)) | ||
| 13 | #define RDEP_MONT_IEAR (RDEP(34)|RDEP(35)) | ||
| 14 | |||
| 15 | static pfm_reg_desc_t pfm_mont_pmc_desc[PMU_MAX_PMCS]={ | ||
| 16 | /* pmc0 */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
| 17 | /* pmc1 */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
| 18 | /* pmc2 */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
| 19 | /* pmc3 */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
| 20 | /* pmc4 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(4),0, 0, 0}, {0,0, 0, 0}}, | ||
| 21 | /* pmc5 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(5),0, 0, 0}, {0,0, 0, 0}}, | ||
| 22 | /* pmc6 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(6),0, 0, 0}, {0,0, 0, 0}}, | ||
| 23 | /* pmc7 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(7),0, 0, 0}, {0,0, 0, 0}}, | ||
| 24 | /* pmc8 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(8),0, 0, 0}, {0,0, 0, 0}}, | ||
| 25 | /* pmc9 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(9),0, 0, 0}, {0,0, 0, 0}}, | ||
| 26 | /* pmc10 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(10),0, 0, 0}, {0,0, 0, 0}}, | ||
| 27 | /* pmc11 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(11),0, 0, 0}, {0,0, 0, 0}}, | ||
| 28 | /* pmc12 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(12),0, 0, 0}, {0,0, 0, 0}}, | ||
| 29 | /* pmc13 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(13),0, 0, 0}, {0,0, 0, 0}}, | ||
| 30 | /* pmc14 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(14),0, 0, 0}, {0,0, 0, 0}}, | ||
| 31 | /* pmc15 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(15),0, 0, 0}, {0,0, 0, 0}}, | ||
| 32 | /* pmc16 */ { PFM_REG_NOTIMPL, }, | ||
| 33 | /* pmc17 */ { PFM_REG_NOTIMPL, }, | ||
| 34 | /* pmc18 */ { PFM_REG_NOTIMPL, }, | ||
| 35 | /* pmc19 */ { PFM_REG_NOTIMPL, }, | ||
| 36 | /* pmc20 */ { PFM_REG_NOTIMPL, }, | ||
| 37 | /* pmc21 */ { PFM_REG_NOTIMPL, }, | ||
| 38 | /* pmc22 */ { PFM_REG_NOTIMPL, }, | ||
| 39 | /* pmc23 */ { PFM_REG_NOTIMPL, }, | ||
| 40 | /* pmc24 */ { PFM_REG_NOTIMPL, }, | ||
| 41 | /* pmc25 */ { PFM_REG_NOTIMPL, }, | ||
| 42 | /* pmc26 */ { PFM_REG_NOTIMPL, }, | ||
| 43 | /* pmc27 */ { PFM_REG_NOTIMPL, }, | ||
| 44 | /* pmc28 */ { PFM_REG_NOTIMPL, }, | ||
| 45 | /* pmc29 */ { PFM_REG_NOTIMPL, }, | ||
| 46 | /* pmc30 */ { PFM_REG_NOTIMPL, }, | ||
| 47 | /* pmc31 */ { PFM_REG_NOTIMPL, }, | ||
| 48 | /* pmc32 */ { PFM_REG_CONFIG, 0, 0x30f01ffffffffff, 0x30f01ffffffffff, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
| 49 | /* pmc33 */ { PFM_REG_CONFIG, 0, 0x0, 0x1ffffffffff, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
| 50 | /* pmc34 */ { PFM_REG_CONFIG, 0, 0xf01ffffffffff, 0xf01ffffffffff, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
| 51 | /* pmc35 */ { PFM_REG_CONFIG, 0, 0x0, 0x1ffffffffff, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
| 52 | /* pmc36 */ { PFM_REG_CONFIG, 0, 0xfffffff0, 0xf, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
| 53 | /* pmc37 */ { PFM_REG_MONITOR, 4, 0x0, 0x3fff, NULL, pfm_mont_pmc_check, {RDEP_MONT_IEAR, 0, 0, 0}, {0, 0, 0, 0}}, | ||
| 54 | /* pmc38 */ { PFM_REG_CONFIG, 0, 0xdb6, 0x2492, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
| 55 | /* pmc39 */ { PFM_REG_MONITOR, 6, 0x0, 0xffcf, NULL, pfm_mont_pmc_check, {RDEP_MONT_ETB,0, 0, 0}, {0,0, 0, 0}}, | ||
| 56 | /* pmc40 */ { PFM_REG_MONITOR, 6, 0x2000000, 0xf01cf, NULL, pfm_mont_pmc_check, {RDEP_MONT_DEAR,0, 0, 0}, {0,0, 0, 0}}, | ||
| 57 | /* pmc41 */ { PFM_REG_CONFIG, 0, 0x00002078fefefefe, 0x1e00018181818, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, | ||
| 58 | /* pmc42 */ { PFM_REG_MONITOR, 6, 0x0, 0x7ff4f, NULL, pfm_mont_pmc_check, {RDEP_MONT_ETB,0, 0, 0}, {0,0, 0, 0}}, | ||
| 59 | { PFM_REG_END , 0, 0x0, -1, NULL, NULL, {0,}, {0,}}, /* end marker */ | ||
| 60 | }; | ||
| 61 | |||
| 62 | static pfm_reg_desc_t pfm_mont_pmd_desc[PMU_MAX_PMDS]={ | ||
| 63 | /* pmd0 */ { PFM_REG_NOTIMPL, }, | ||
| 64 | /* pmd1 */ { PFM_REG_NOTIMPL, }, | ||
| 65 | /* pmd2 */ { PFM_REG_NOTIMPL, }, | ||
| 66 | /* pmd3 */ { PFM_REG_NOTIMPL, }, | ||
| 67 | /* pmd4 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(4),0, 0, 0}}, | ||
| 68 | /* pmd5 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(5),0, 0, 0}}, | ||
| 69 | /* pmd6 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(6),0, 0, 0}}, | ||
| 70 | /* pmd7 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(7),0, 0, 0}}, | ||
| 71 | /* pmd8 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(8),0, 0, 0}}, | ||
| 72 | /* pmd9 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(9),0, 0, 0}}, | ||
| 73 | /* pmd10 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(10),0, 0, 0}}, | ||
| 74 | /* pmd11 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(11),0, 0, 0}}, | ||
| 75 | /* pmd12 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(12),0, 0, 0}}, | ||
| 76 | /* pmd13 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(13),0, 0, 0}}, | ||
| 77 | /* pmd14 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(14),0, 0, 0}}, | ||
| 78 | /* pmd15 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(15),0, 0, 0}}, | ||
| 79 | /* pmd16 */ { PFM_REG_NOTIMPL, }, | ||
| 80 | /* pmd17 */ { PFM_REG_NOTIMPL, }, | ||
| 81 | /* pmd18 */ { PFM_REG_NOTIMPL, }, | ||
| 82 | /* pmd19 */ { PFM_REG_NOTIMPL, }, | ||
| 83 | /* pmd20 */ { PFM_REG_NOTIMPL, }, | ||
| 84 | /* pmd21 */ { PFM_REG_NOTIMPL, }, | ||
| 85 | /* pmd22 */ { PFM_REG_NOTIMPL, }, | ||
| 86 | /* pmd23 */ { PFM_REG_NOTIMPL, }, | ||
| 87 | /* pmd24 */ { PFM_REG_NOTIMPL, }, | ||
| 88 | /* pmd25 */ { PFM_REG_NOTIMPL, }, | ||
| 89 | /* pmd26 */ { PFM_REG_NOTIMPL, }, | ||
| 90 | /* pmd27 */ { PFM_REG_NOTIMPL, }, | ||
| 91 | /* pmd28 */ { PFM_REG_NOTIMPL, }, | ||
| 92 | /* pmd29 */ { PFM_REG_NOTIMPL, }, | ||
| 93 | /* pmd30 */ { PFM_REG_NOTIMPL, }, | ||
| 94 | /* pmd31 */ { PFM_REG_NOTIMPL, }, | ||
| 95 | /* pmd32 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(33)|RDEP(36),0, 0, 0}, {RDEP(40),0, 0, 0}}, | ||
| 96 | /* pmd33 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(32)|RDEP(36),0, 0, 0}, {RDEP(40),0, 0, 0}}, | ||
| 97 | /* pmd34 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(35),0, 0, 0}, {RDEP(37),0, 0, 0}}, | ||
| 98 | /* pmd35 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(34),0, 0, 0}, {RDEP(37),0, 0, 0}}, | ||
| 99 | /* pmd36 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(32)|RDEP(33),0, 0, 0}, {RDEP(40),0, 0, 0}}, | ||
| 100 | /* pmd37 */ { PFM_REG_NOTIMPL, }, | ||
| 101 | /* pmd38 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
| 102 | /* pmd39 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
| 103 | /* pmd40 */ { PFM_REG_NOTIMPL, }, | ||
| 104 | /* pmd41 */ { PFM_REG_NOTIMPL, }, | ||
| 105 | /* pmd42 */ { PFM_REG_NOTIMPL, }, | ||
| 106 | /* pmd43 */ { PFM_REG_NOTIMPL, }, | ||
| 107 | /* pmd44 */ { PFM_REG_NOTIMPL, }, | ||
| 108 | /* pmd45 */ { PFM_REG_NOTIMPL, }, | ||
| 109 | /* pmd46 */ { PFM_REG_NOTIMPL, }, | ||
| 110 | /* pmd47 */ { PFM_REG_NOTIMPL, }, | ||
| 111 | /* pmd48 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
| 112 | /* pmd49 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
| 113 | /* pmd50 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
| 114 | /* pmd51 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
| 115 | /* pmd52 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
| 116 | /* pmd53 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
| 117 | /* pmd54 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
| 118 | /* pmd55 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
| 119 | /* pmd56 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
| 120 | /* pmd57 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
| 121 | /* pmd58 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
| 122 | /* pmd59 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
| 123 | /* pmd60 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
| 124 | /* pmd61 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
| 125 | /* pmd62 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
| 126 | /* pmd63 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, | ||
| 127 | { PFM_REG_END , 0, 0x0, -1, NULL, NULL, {0,}, {0,}}, /* end marker */ | ||
| 128 | }; | ||
| 129 | |||
| 130 | /* | ||
| 131 | * PMC reserved fields must have their power-up values preserved | ||
| 132 | */ | ||
| 133 | static int | ||
| 134 | pfm_mont_reserved(unsigned int cnum, unsigned long *val, struct pt_regs *regs) | ||
| 135 | { | ||
| 136 | unsigned long tmp1, tmp2, ival = *val; | ||
| 137 | |||
| 138 | /* remove reserved areas from user value */ | ||
| 139 | tmp1 = ival & PMC_RSVD_MASK(cnum); | ||
| 140 | |||
| 141 | /* get reserved fields values */ | ||
| 142 | tmp2 = PMC_DFL_VAL(cnum) & ~PMC_RSVD_MASK(cnum); | ||
| 143 | |||
| 144 | *val = tmp1 | tmp2; | ||
| 145 | |||
| 146 | DPRINT(("pmc[%d]=0x%lx, mask=0x%lx, reset=0x%lx, val=0x%lx\n", | ||
| 147 | cnum, ival, PMC_RSVD_MASK(cnum), PMC_DFL_VAL(cnum), *val)); | ||
| 148 | return 0; | ||
| 149 | } | ||
| 150 | |||
| 151 | /* | ||
| 152 | * task can be NULL if the context is unloaded | ||
| 153 | */ | ||
| 154 | static int | ||
| 155 | pfm_mont_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs) | ||
| 156 | { | ||
| 157 | int ret = 0; | ||
| 158 | unsigned long val32 = 0, val38 = 0, val41 = 0; | ||
| 159 | unsigned long tmpval; | ||
| 160 | int check_case1 = 0; | ||
| 161 | int is_loaded; | ||
| 162 | |||
| 163 | /* first preserve the reserved fields */ | ||
| 164 | pfm_mont_reserved(cnum, val, regs); | ||
| 165 | |||
| 166 | tmpval = *val; | ||
| 167 | |||
| 168 | /* sanity check */ | ||
| 169 | if (ctx == NULL) return -EINVAL; | ||
| 170 | |||
| 171 | is_loaded = ctx->ctx_state == PFM_CTX_LOADED || ctx->ctx_state == PFM_CTX_MASKED; | ||
| 172 | |||
| 173 | /* | ||
| 174 | * we must clear the debug registers if pmc41 has a value which enable | ||
| 175 | * memory pipeline event constraints. In this case we need to clear the | ||
| 176 | * the debug registers if they have not yet been accessed. This is required | ||
| 177 | * to avoid picking stale state. | ||
| 178 | * PMC41 is "active" if: | ||
| 179 | * one of the pmc41.cfg_dtagXX field is different from 0x3 | ||
| 180 | * AND | ||
| 181 | * at the corresponding pmc41.en_dbrpXX is set. | ||
| 182 | * AND | ||
| 183 | * ctx_fl_using_dbreg == 0 (i.e., dbr not yet used) | ||
| 184 | */ | ||
| 185 | DPRINT(("cnum=%u val=0x%lx, using_dbreg=%d loaded=%d\n", cnum, tmpval, ctx->ctx_fl_using_dbreg, is_loaded)); | ||
| 186 | |||
| 187 | if (cnum == 41 && is_loaded | ||
| 188 | && (tmpval & 0x1e00000000000) && (tmpval & 0x18181818UL) != 0x18181818UL && ctx->ctx_fl_using_dbreg == 0) { | ||
| 189 | |||
| 190 | DPRINT(("pmc[%d]=0x%lx has active pmc41 settings, clearing dbr\n", cnum, tmpval)); | ||
| 191 | |||
| 192 | /* don't mix debug with perfmon */ | ||
| 193 | if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL; | ||
| 194 | |||
| 195 | /* | ||
| 196 | * a count of 0 will mark the debug registers if: | ||
| 197 | * AND | ||
| 198 | */ | ||
| 199 | ret = pfm_write_ibr_dbr(PFM_DATA_RR, ctx, NULL, 0, regs); | ||
| 200 | if (ret) return ret; | ||
| 201 | } | ||
| 202 | /* | ||
| 203 | * we must clear the (instruction) debug registers if: | ||
| 204 | * pmc38.ig_ibrpX is 0 (enabled) | ||
| 205 | * AND | ||
| 206 | * ctx_fl_using_dbreg == 0 (i.e., dbr not yet used) | ||
| 207 | */ | ||
| 208 | if (cnum == 38 && is_loaded && ((tmpval & 0x492UL) != 0x492UL) && ctx->ctx_fl_using_dbreg == 0) { | ||
| 209 | |||
| 210 | DPRINT(("pmc38=0x%lx has active pmc38 settings, clearing ibr\n", tmpval)); | ||
| 211 | |||
| 212 | /* don't mix debug with perfmon */ | ||
| 213 | if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL; | ||
| 214 | |||
| 215 | /* | ||
| 216 | * a count of 0 will mark the debug registers as in use and also | ||
| 217 | * ensure that they are properly cleared. | ||
| 218 | */ | ||
| 219 | ret = pfm_write_ibr_dbr(PFM_CODE_RR, ctx, NULL, 0, regs); | ||
| 220 | if (ret) return ret; | ||
| 221 | |||
| 222 | } | ||
| 223 | switch(cnum) { | ||
| 224 | case 32: val32 = *val; | ||
| 225 | val38 = ctx->ctx_pmcs[38]; | ||
| 226 | val41 = ctx->ctx_pmcs[41]; | ||
| 227 | check_case1 = 1; | ||
| 228 | break; | ||
| 229 | case 38: val38 = *val; | ||
| 230 | val32 = ctx->ctx_pmcs[32]; | ||
| 231 | val41 = ctx->ctx_pmcs[41]; | ||
| 232 | check_case1 = 1; | ||
| 233 | break; | ||
| 234 | case 41: val41 = *val; | ||
| 235 | val32 = ctx->ctx_pmcs[32]; | ||
| 236 | val38 = ctx->ctx_pmcs[38]; | ||
| 237 | check_case1 = 1; | ||
| 238 | break; | ||
| 239 | } | ||
| 240 | /* check illegal configuration which can produce inconsistencies in tagging | ||
| 241 | * i-side events in L1D and L2 caches | ||
| 242 | */ | ||
| 243 | if (check_case1) { | ||
| 244 | ret = (((val41 >> 45) & 0xf) == 0 && ((val32>>57) & 0x1) == 0) | ||
| 245 | && ((((val38>>1) & 0x3) == 0x2 || ((val38>>1) & 0x3) == 0) | ||
| 246 | || (((val38>>4) & 0x3) == 0x2 || ((val38>>4) & 0x3) == 0)); | ||
| 247 | if (ret) { | ||
| 248 | DPRINT(("invalid config pmc38=0x%lx pmc41=0x%lx pmc32=0x%lx\n", val38, val41, val32)); | ||
| 249 | return -EINVAL; | ||
| 250 | } | ||
| 251 | } | ||
| 252 | *val = tmpval; | ||
| 253 | return 0; | ||
| 254 | } | ||
| 255 | |||
| 256 | /* | ||
| 257 | * impl_pmcs, impl_pmds are computed at runtime to minimize errors! | ||
| 258 | */ | ||
| 259 | static pmu_config_t pmu_conf_mont={ | ||
| 260 | .pmu_name = "Montecito", | ||
| 261 | .pmu_family = 0x20, | ||
| 262 | .flags = PFM_PMU_IRQ_RESEND, | ||
| 263 | .ovfl_val = (1UL << 47) - 1, | ||
| 264 | .pmd_desc = pfm_mont_pmd_desc, | ||
| 265 | .pmc_desc = pfm_mont_pmc_desc, | ||
| 266 | .num_ibrs = 8, | ||
| 267 | .num_dbrs = 8, | ||
| 268 | .use_rr_dbregs = 1 /* debug register are use for range retrictions */ | ||
| 269 | }; | ||
diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c index a87a162a3086..9d5a823479a3 100644 --- a/arch/ia64/kernel/salinfo.c +++ b/arch/ia64/kernel/salinfo.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * Creates entries in /proc/sal for various system features. | 4 | * Creates entries in /proc/sal for various system features. |
| 5 | * | 5 | * |
| 6 | * Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved. | 6 | * Copyright (c) 2003, 2006 Silicon Graphics, Inc. All rights reserved. |
| 7 | * Copyright (c) 2003 Hewlett-Packard Co | 7 | * Copyright (c) 2003 Hewlett-Packard Co |
| 8 | * Bjorn Helgaas <bjorn.helgaas@hp.com> | 8 | * Bjorn Helgaas <bjorn.helgaas@hp.com> |
| 9 | * | 9 | * |
| @@ -27,9 +27,17 @@ | |||
| 27 | * mca.c may not pass a buffer, a NULL buffer just indicates that a new | 27 | * mca.c may not pass a buffer, a NULL buffer just indicates that a new |
| 28 | * record is available in SAL. | 28 | * record is available in SAL. |
| 29 | * Replace some NR_CPUS by cpus_online, for hotplug cpu. | 29 | * Replace some NR_CPUS by cpus_online, for hotplug cpu. |
| 30 | * | ||
| 31 | * Jan 5 2006 kaos@sgi.com | ||
| 32 | * Handle hotplug cpus coming online. | ||
| 33 | * Handle hotplug cpus going offline while they still have outstanding records. | ||
| 34 | * Use the cpu_* macros consistently. | ||
| 35 | * Replace the counting semaphore with a mutex and a test if the cpumask is non-empty. | ||
| 36 | * Modify the locking to make the test for "work to do" an atomic operation. | ||
| 30 | */ | 37 | */ |
| 31 | 38 | ||
| 32 | #include <linux/capability.h> | 39 | #include <linux/capability.h> |
| 40 | #include <linux/cpu.h> | ||
| 33 | #include <linux/types.h> | 41 | #include <linux/types.h> |
| 34 | #include <linux/proc_fs.h> | 42 | #include <linux/proc_fs.h> |
| 35 | #include <linux/module.h> | 43 | #include <linux/module.h> |
| @@ -132,8 +140,8 @@ enum salinfo_state { | |||
| 132 | }; | 140 | }; |
| 133 | 141 | ||
| 134 | struct salinfo_data { | 142 | struct salinfo_data { |
| 135 | volatile cpumask_t cpu_event; /* which cpus have outstanding events */ | 143 | cpumask_t cpu_event; /* which cpus have outstanding events */ |
| 136 | struct semaphore sem; /* count of cpus with outstanding events (bits set in cpu_event) */ | 144 | struct semaphore mutex; |
| 137 | u8 *log_buffer; | 145 | u8 *log_buffer; |
| 138 | u64 log_size; | 146 | u64 log_size; |
| 139 | u8 *oemdata; /* decoded oem data */ | 147 | u8 *oemdata; /* decoded oem data */ |
| @@ -174,6 +182,21 @@ struct salinfo_platform_oemdata_parms { | |||
| 174 | int ret; | 182 | int ret; |
| 175 | }; | 183 | }; |
| 176 | 184 | ||
| 185 | /* Kick the mutex that tells user space that there is work to do. Instead of | ||
| 186 | * trying to track the state of the mutex across multiple cpus, in user | ||
| 187 | * context, interrupt context, non-maskable interrupt context and hotplug cpu, | ||
| 188 | * it is far easier just to grab the mutex if it is free then release it. | ||
| 189 | * | ||
| 190 | * This routine must be called with data_saved_lock held, to make the down/up | ||
| 191 | * operation atomic. | ||
| 192 | */ | ||
| 193 | static void | ||
| 194 | salinfo_work_to_do(struct salinfo_data *data) | ||
| 195 | { | ||
| 196 | down_trylock(&data->mutex); | ||
| 197 | up(&data->mutex); | ||
| 198 | } | ||
| 199 | |||
| 177 | static void | 200 | static void |
| 178 | salinfo_platform_oemdata_cpu(void *context) | 201 | salinfo_platform_oemdata_cpu(void *context) |
| 179 | { | 202 | { |
| @@ -212,9 +235,9 @@ salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe) | |||
| 212 | 235 | ||
| 213 | BUG_ON(type >= ARRAY_SIZE(salinfo_log_name)); | 236 | BUG_ON(type >= ARRAY_SIZE(salinfo_log_name)); |
| 214 | 237 | ||
| 238 | if (irqsafe) | ||
| 239 | spin_lock_irqsave(&data_saved_lock, flags); | ||
| 215 | if (buffer) { | 240 | if (buffer) { |
| 216 | if (irqsafe) | ||
| 217 | spin_lock_irqsave(&data_saved_lock, flags); | ||
| 218 | for (i = 0, data_saved = data->data_saved; i < saved_size; ++i, ++data_saved) { | 241 | for (i = 0, data_saved = data->data_saved; i < saved_size; ++i, ++data_saved) { |
| 219 | if (!data_saved->buffer) | 242 | if (!data_saved->buffer) |
| 220 | break; | 243 | break; |
| @@ -232,13 +255,11 @@ salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe) | |||
| 232 | data_saved->size = size; | 255 | data_saved->size = size; |
| 233 | data_saved->buffer = buffer; | 256 | data_saved->buffer = buffer; |
| 234 | } | 257 | } |
| 235 | if (irqsafe) | ||
| 236 | spin_unlock_irqrestore(&data_saved_lock, flags); | ||
| 237 | } | 258 | } |
| 238 | 259 | cpu_set(smp_processor_id(), data->cpu_event); | |
| 239 | if (!test_and_set_bit(smp_processor_id(), &data->cpu_event)) { | 260 | if (irqsafe) { |
| 240 | if (irqsafe) | 261 | salinfo_work_to_do(data); |
| 241 | up(&data->sem); | 262 | spin_unlock_irqrestore(&data_saved_lock, flags); |
| 242 | } | 263 | } |
| 243 | } | 264 | } |
| 244 | 265 | ||
| @@ -249,20 +270,17 @@ static struct timer_list salinfo_timer; | |||
| 249 | static void | 270 | static void |
| 250 | salinfo_timeout_check(struct salinfo_data *data) | 271 | salinfo_timeout_check(struct salinfo_data *data) |
| 251 | { | 272 | { |
| 252 | int i; | 273 | unsigned long flags; |
| 253 | if (!data->open) | 274 | if (!data->open) |
| 254 | return; | 275 | return; |
| 255 | for_each_online_cpu(i) { | 276 | if (!cpus_empty(data->cpu_event)) { |
| 256 | if (test_bit(i, &data->cpu_event)) { | 277 | spin_lock_irqsave(&data_saved_lock, flags); |
| 257 | /* double up() is not a problem, user space will see no | 278 | salinfo_work_to_do(data); |
| 258 | * records for the additional "events". | 279 | spin_unlock_irqrestore(&data_saved_lock, flags); |
| 259 | */ | ||
| 260 | up(&data->sem); | ||
| 261 | } | ||
| 262 | } | 280 | } |
| 263 | } | 281 | } |
| 264 | 282 | ||
| 265 | static void | 283 | static void |
| 266 | salinfo_timeout (unsigned long arg) | 284 | salinfo_timeout (unsigned long arg) |
| 267 | { | 285 | { |
| 268 | salinfo_timeout_check(salinfo_data + SAL_INFO_TYPE_MCA); | 286 | salinfo_timeout_check(salinfo_data + SAL_INFO_TYPE_MCA); |
| @@ -290,16 +308,20 @@ salinfo_event_read(struct file *file, char __user *buffer, size_t count, loff_t | |||
| 290 | int i, n, cpu = -1; | 308 | int i, n, cpu = -1; |
| 291 | 309 | ||
| 292 | retry: | 310 | retry: |
| 293 | if (down_trylock(&data->sem)) { | 311 | if (cpus_empty(data->cpu_event) && down_trylock(&data->mutex)) { |
| 294 | if (file->f_flags & O_NONBLOCK) | 312 | if (file->f_flags & O_NONBLOCK) |
| 295 | return -EAGAIN; | 313 | return -EAGAIN; |
| 296 | if (down_interruptible(&data->sem)) | 314 | if (down_interruptible(&data->mutex)) |
| 297 | return -EINTR; | 315 | return -EINTR; |
| 298 | } | 316 | } |
| 299 | 317 | ||
| 300 | n = data->cpu_check; | 318 | n = data->cpu_check; |
| 301 | for (i = 0; i < NR_CPUS; i++) { | 319 | for (i = 0; i < NR_CPUS; i++) { |
| 302 | if (test_bit(n, &data->cpu_event) && cpu_online(n)) { | 320 | if (cpu_isset(n, data->cpu_event)) { |
| 321 | if (!cpu_online(n)) { | ||
| 322 | cpu_clear(n, data->cpu_event); | ||
| 323 | continue; | ||
| 324 | } | ||
| 303 | cpu = n; | 325 | cpu = n; |
| 304 | break; | 326 | break; |
| 305 | } | 327 | } |
| @@ -310,9 +332,6 @@ retry: | |||
| 310 | if (cpu == -1) | 332 | if (cpu == -1) |
| 311 | goto retry; | 333 | goto retry; |
| 312 | 334 | ||
| 313 | /* events are sticky until the user says "clear" */ | ||
| 314 | up(&data->sem); | ||
| 315 | |||
| 316 | /* for next read, start checking at next CPU */ | 335 | /* for next read, start checking at next CPU */ |
| 317 | data->cpu_check = cpu; | 336 | data->cpu_check = cpu; |
| 318 | if (++data->cpu_check == NR_CPUS) | 337 | if (++data->cpu_check == NR_CPUS) |
| @@ -381,10 +400,8 @@ salinfo_log_release(struct inode *inode, struct file *file) | |||
| 381 | static void | 400 | static void |
| 382 | call_on_cpu(int cpu, void (*fn)(void *), void *arg) | 401 | call_on_cpu(int cpu, void (*fn)(void *), void *arg) |
| 383 | { | 402 | { |
| 384 | cpumask_t save_cpus_allowed, new_cpus_allowed; | 403 | cpumask_t save_cpus_allowed = current->cpus_allowed; |
| 385 | memcpy(&save_cpus_allowed, ¤t->cpus_allowed, sizeof(save_cpus_allowed)); | 404 | cpumask_t new_cpus_allowed = cpumask_of_cpu(cpu); |
| 386 | memset(&new_cpus_allowed, 0, sizeof(new_cpus_allowed)); | ||
| 387 | set_bit(cpu, &new_cpus_allowed); | ||
| 388 | set_cpus_allowed(current, new_cpus_allowed); | 405 | set_cpus_allowed(current, new_cpus_allowed); |
| 389 | (*fn)(arg); | 406 | (*fn)(arg); |
| 390 | set_cpus_allowed(current, save_cpus_allowed); | 407 | set_cpus_allowed(current, save_cpus_allowed); |
| @@ -433,10 +450,10 @@ retry: | |||
| 433 | if (!data->saved_num) | 450 | if (!data->saved_num) |
| 434 | call_on_cpu(cpu, salinfo_log_read_cpu, data); | 451 | call_on_cpu(cpu, salinfo_log_read_cpu, data); |
| 435 | if (!data->log_size) { | 452 | if (!data->log_size) { |
| 436 | data->state = STATE_NO_DATA; | 453 | data->state = STATE_NO_DATA; |
| 437 | clear_bit(cpu, &data->cpu_event); | 454 | cpu_clear(cpu, data->cpu_event); |
| 438 | } else { | 455 | } else { |
| 439 | data->state = STATE_LOG_RECORD; | 456 | data->state = STATE_LOG_RECORD; |
| 440 | } | 457 | } |
| 441 | } | 458 | } |
| 442 | 459 | ||
| @@ -473,27 +490,31 @@ static int | |||
| 473 | salinfo_log_clear(struct salinfo_data *data, int cpu) | 490 | salinfo_log_clear(struct salinfo_data *data, int cpu) |
| 474 | { | 491 | { |
| 475 | sal_log_record_header_t *rh; | 492 | sal_log_record_header_t *rh; |
| 493 | unsigned long flags; | ||
| 494 | spin_lock_irqsave(&data_saved_lock, flags); | ||
| 476 | data->state = STATE_NO_DATA; | 495 | data->state = STATE_NO_DATA; |
| 477 | if (!test_bit(cpu, &data->cpu_event)) | 496 | if (!cpu_isset(cpu, data->cpu_event)) { |
| 497 | spin_unlock_irqrestore(&data_saved_lock, flags); | ||
| 478 | return 0; | 498 | return 0; |
| 479 | down(&data->sem); | 499 | } |
| 480 | clear_bit(cpu, &data->cpu_event); | 500 | cpu_clear(cpu, data->cpu_event); |
| 481 | if (data->saved_num) { | 501 | if (data->saved_num) { |
| 482 | unsigned long flags; | 502 | shift1_data_saved(data, data->saved_num - 1); |
| 483 | spin_lock_irqsave(&data_saved_lock, flags); | ||
| 484 | shift1_data_saved(data, data->saved_num - 1 ); | ||
| 485 | data->saved_num = 0; | 503 | data->saved_num = 0; |
| 486 | spin_unlock_irqrestore(&data_saved_lock, flags); | ||
| 487 | } | 504 | } |
| 505 | spin_unlock_irqrestore(&data_saved_lock, flags); | ||
| 488 | rh = (sal_log_record_header_t *)(data->log_buffer); | 506 | rh = (sal_log_record_header_t *)(data->log_buffer); |
| 489 | /* Corrected errors have already been cleared from SAL */ | 507 | /* Corrected errors have already been cleared from SAL */ |
| 490 | if (rh->severity != sal_log_severity_corrected) | 508 | if (rh->severity != sal_log_severity_corrected) |
| 491 | call_on_cpu(cpu, salinfo_log_clear_cpu, data); | 509 | call_on_cpu(cpu, salinfo_log_clear_cpu, data); |
| 492 | /* clearing a record may make a new record visible */ | 510 | /* clearing a record may make a new record visible */ |
| 493 | salinfo_log_new_read(cpu, data); | 511 | salinfo_log_new_read(cpu, data); |
| 494 | if (data->state == STATE_LOG_RECORD && | 512 | if (data->state == STATE_LOG_RECORD) { |
| 495 | !test_and_set_bit(cpu, &data->cpu_event)) | 513 | spin_lock_irqsave(&data_saved_lock, flags); |
| 496 | up(&data->sem); | 514 | cpu_set(cpu, data->cpu_event); |
| 515 | salinfo_work_to_do(data); | ||
| 516 | spin_unlock_irqrestore(&data_saved_lock, flags); | ||
| 517 | } | ||
| 497 | return 0; | 518 | return 0; |
| 498 | } | 519 | } |
| 499 | 520 | ||
| @@ -550,6 +571,53 @@ static struct file_operations salinfo_data_fops = { | |||
| 550 | .write = salinfo_log_write, | 571 | .write = salinfo_log_write, |
| 551 | }; | 572 | }; |
| 552 | 573 | ||
| 574 | #ifdef CONFIG_HOTPLUG_CPU | ||
| 575 | static int __devinit | ||
| 576 | salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) | ||
| 577 | { | ||
| 578 | unsigned int i, cpu = (unsigned long)hcpu; | ||
| 579 | unsigned long flags; | ||
| 580 | struct salinfo_data *data; | ||
| 581 | switch (action) { | ||
| 582 | case CPU_ONLINE: | ||
| 583 | spin_lock_irqsave(&data_saved_lock, flags); | ||
| 584 | for (i = 0, data = salinfo_data; | ||
| 585 | i < ARRAY_SIZE(salinfo_data); | ||
| 586 | ++i, ++data) { | ||
| 587 | cpu_set(cpu, data->cpu_event); | ||
| 588 | salinfo_work_to_do(data); | ||
| 589 | } | ||
| 590 | spin_unlock_irqrestore(&data_saved_lock, flags); | ||
| 591 | break; | ||
| 592 | case CPU_DEAD: | ||
| 593 | spin_lock_irqsave(&data_saved_lock, flags); | ||
| 594 | for (i = 0, data = salinfo_data; | ||
| 595 | i < ARRAY_SIZE(salinfo_data); | ||
| 596 | ++i, ++data) { | ||
| 597 | struct salinfo_data_saved *data_saved; | ||
| 598 | int j; | ||
| 599 | for (j = ARRAY_SIZE(data->data_saved) - 1, data_saved = data->data_saved + j; | ||
| 600 | j >= 0; | ||
| 601 | --j, --data_saved) { | ||
| 602 | if (data_saved->buffer && data_saved->cpu == cpu) { | ||
| 603 | shift1_data_saved(data, j); | ||
| 604 | } | ||
| 605 | } | ||
| 606 | cpu_clear(cpu, data->cpu_event); | ||
| 607 | } | ||
| 608 | spin_unlock_irqrestore(&data_saved_lock, flags); | ||
| 609 | break; | ||
| 610 | } | ||
| 611 | return NOTIFY_OK; | ||
| 612 | } | ||
| 613 | |||
| 614 | static struct notifier_block salinfo_cpu_notifier = | ||
| 615 | { | ||
| 616 | .notifier_call = salinfo_cpu_callback, | ||
| 617 | .priority = 0, | ||
| 618 | }; | ||
| 619 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
| 620 | |||
| 553 | static int __init | 621 | static int __init |
| 554 | salinfo_init(void) | 622 | salinfo_init(void) |
| 555 | { | 623 | { |
| @@ -557,7 +625,7 @@ salinfo_init(void) | |||
| 557 | struct proc_dir_entry **sdir = salinfo_proc_entries; /* keeps track of every entry */ | 625 | struct proc_dir_entry **sdir = salinfo_proc_entries; /* keeps track of every entry */ |
| 558 | struct proc_dir_entry *dir, *entry; | 626 | struct proc_dir_entry *dir, *entry; |
| 559 | struct salinfo_data *data; | 627 | struct salinfo_data *data; |
| 560 | int i, j, online; | 628 | int i, j; |
| 561 | 629 | ||
| 562 | salinfo_dir = proc_mkdir("sal", NULL); | 630 | salinfo_dir = proc_mkdir("sal", NULL); |
| 563 | if (!salinfo_dir) | 631 | if (!salinfo_dir) |
| @@ -572,7 +640,7 @@ salinfo_init(void) | |||
| 572 | for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) { | 640 | for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) { |
| 573 | data = salinfo_data + i; | 641 | data = salinfo_data + i; |
| 574 | data->type = i; | 642 | data->type = i; |
| 575 | sema_init(&data->sem, 0); | 643 | init_MUTEX(&data->mutex); |
| 576 | dir = proc_mkdir(salinfo_log_name[i], salinfo_dir); | 644 | dir = proc_mkdir(salinfo_log_name[i], salinfo_dir); |
| 577 | if (!dir) | 645 | if (!dir) |
| 578 | continue; | 646 | continue; |
| @@ -592,12 +660,8 @@ salinfo_init(void) | |||
| 592 | *sdir++ = entry; | 660 | *sdir++ = entry; |
| 593 | 661 | ||
| 594 | /* we missed any events before now */ | 662 | /* we missed any events before now */ |
| 595 | online = 0; | 663 | for_each_online_cpu(j) |
| 596 | for_each_online_cpu(j) { | 664 | cpu_set(j, data->cpu_event); |
| 597 | set_bit(j, &data->cpu_event); | ||
| 598 | ++online; | ||
| 599 | } | ||
| 600 | sema_init(&data->sem, online); | ||
| 601 | 665 | ||
| 602 | *sdir++ = dir; | 666 | *sdir++ = dir; |
| 603 | } | 667 | } |
| @@ -609,6 +673,10 @@ salinfo_init(void) | |||
| 609 | salinfo_timer.function = &salinfo_timeout; | 673 | salinfo_timer.function = &salinfo_timeout; |
| 610 | add_timer(&salinfo_timer); | 674 | add_timer(&salinfo_timer); |
| 611 | 675 | ||
| 676 | #ifdef CONFIG_HOTPLUG_CPU | ||
| 677 | register_cpu_notifier(&salinfo_cpu_notifier); | ||
| 678 | #endif | ||
| 679 | |||
| 612 | return 0; | 680 | return 0; |
| 613 | } | 681 | } |
| 614 | 682 | ||
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index d3e0ecb56d62..55391901b013 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c | |||
| @@ -530,12 +530,15 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, | |||
| 530 | if (fsys_mode(current, ®s)) { | 530 | if (fsys_mode(current, ®s)) { |
| 531 | extern char __kernel_syscall_via_break[]; | 531 | extern char __kernel_syscall_via_break[]; |
| 532 | /* | 532 | /* |
| 533 | * Got a trap in fsys-mode: Taken Branch Trap and Single Step trap | 533 | * Got a trap in fsys-mode: Taken Branch Trap |
| 534 | * need special handling; Debug trap is not supposed to happen. | 534 | * and Single Step trap need special handling; |
| 535 | * Debug trap is ignored (we disable it here | ||
| 536 | * and re-enable it in the lower-privilege trap). | ||
| 535 | */ | 537 | */ |
| 536 | if (unlikely(vector == 29)) { | 538 | if (unlikely(vector == 29)) { |
| 537 | die("Got debug trap in fsys-mode---not supposed to happen!", | 539 | set_thread_flag(TIF_DB_DISABLED); |
| 538 | ®s, 0); | 540 | ia64_psr(®s)->db = 0; |
| 541 | ia64_psr(®s)->lp = 1; | ||
| 539 | return; | 542 | return; |
| 540 | } | 543 | } |
| 541 | /* re-do the system call via break 0x100000: */ | 544 | /* re-do the system call via break 0x100000: */ |
| @@ -589,10 +592,19 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, | |||
| 589 | case 34: | 592 | case 34: |
| 590 | if (isr & 0x2) { | 593 | if (isr & 0x2) { |
| 591 | /* Lower-Privilege Transfer Trap */ | 594 | /* Lower-Privilege Transfer Trap */ |
| 595 | |||
| 596 | /* If we disabled debug traps during an fsyscall, | ||
| 597 | * re-enable them here. | ||
| 598 | */ | ||
| 599 | if (test_thread_flag(TIF_DB_DISABLED)) { | ||
| 600 | clear_thread_flag(TIF_DB_DISABLED); | ||
| 601 | ia64_psr(®s)->db = 1; | ||
| 602 | } | ||
| 603 | |||
| 592 | /* | 604 | /* |
| 593 | * Just clear PSR.lp and then return immediately: all the | 605 | * Just clear PSR.lp and then return immediately: |
| 594 | * interesting work (e.g., signal delivery is done in the kernel | 606 | * all the interesting work (e.g., signal delivery) |
| 595 | * exit path). | 607 | * is done in the kernel exit path. |
| 596 | */ | 608 | */ |
| 597 | ia64_psr(®s)->lp = 0; | 609 | ia64_psr(®s)->lp = 0; |
| 598 | return; | 610 | return; |
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index e3215ba64ffd..b38b6d213c15 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c | |||
| @@ -635,3 +635,39 @@ mem_init (void) | |||
| 635 | ia32_mem_init(); | 635 | ia32_mem_init(); |
| 636 | #endif | 636 | #endif |
| 637 | } | 637 | } |
| 638 | |||
| 639 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
| 640 | void online_page(struct page *page) | ||
| 641 | { | ||
| 642 | ClearPageReserved(page); | ||
| 643 | set_page_count(page, 1); | ||
| 644 | __free_page(page); | ||
| 645 | totalram_pages++; | ||
| 646 | num_physpages++; | ||
| 647 | } | ||
| 648 | |||
| 649 | int add_memory(u64 start, u64 size) | ||
| 650 | { | ||
| 651 | pg_data_t *pgdat; | ||
| 652 | struct zone *zone; | ||
| 653 | unsigned long start_pfn = start >> PAGE_SHIFT; | ||
| 654 | unsigned long nr_pages = size >> PAGE_SHIFT; | ||
| 655 | int ret; | ||
| 656 | |||
| 657 | pgdat = NODE_DATA(0); | ||
| 658 | |||
| 659 | zone = pgdat->node_zones + ZONE_NORMAL; | ||
| 660 | ret = __add_pages(zone, start_pfn, nr_pages); | ||
| 661 | |||
| 662 | if (ret) | ||
| 663 | printk("%s: Problem encountered in __add_pages() as ret=%d\n", | ||
| 664 | __FUNCTION__, ret); | ||
| 665 | |||
| 666 | return ret; | ||
| 667 | } | ||
| 668 | |||
| 669 | int remove_memory(u64 start, u64 size) | ||
| 670 | { | ||
| 671 | return -EINVAL; | ||
| 672 | } | ||
| 673 | #endif | ||
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index 41105d454423..6a4eec9113e8 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c | |||
| @@ -90,7 +90,7 @@ ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start, | |||
| 90 | { | 90 | { |
| 91 | static DEFINE_SPINLOCK(ptcg_lock); | 91 | static DEFINE_SPINLOCK(ptcg_lock); |
| 92 | 92 | ||
| 93 | if (mm != current->active_mm) { | 93 | if (mm != current->active_mm || !current->mm) { |
| 94 | flush_tlb_all(); | 94 | flush_tlb_all(); |
| 95 | return; | 95 | return; |
| 96 | } | 96 | } |
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 30dbc98bf0b3..d27ecdcb6fca 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
| @@ -454,14 +454,13 @@ static int __devinit is_valid_resource(struct pci_dev *dev, int idx) | |||
| 454 | return 0; | 454 | return 0; |
| 455 | } | 455 | } |
| 456 | 456 | ||
| 457 | static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) | 457 | static void __devinit |
| 458 | pcibios_fixup_resources(struct pci_dev *dev, int start, int limit) | ||
| 458 | { | 459 | { |
| 459 | struct pci_bus_region region; | 460 | struct pci_bus_region region; |
| 460 | int i; | 461 | int i; |
| 461 | int limit = (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) ? \ | ||
| 462 | PCI_BRIDGE_RESOURCES : PCI_NUM_RESOURCES; | ||
| 463 | 462 | ||
| 464 | for (i = 0; i < limit; i++) { | 463 | for (i = start; i < limit; i++) { |
| 465 | if (!dev->resource[i].flags) | 464 | if (!dev->resource[i].flags) |
| 466 | continue; | 465 | continue; |
| 467 | region.start = dev->resource[i].start; | 466 | region.start = dev->resource[i].start; |
| @@ -472,6 +471,16 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) | |||
| 472 | } | 471 | } |
| 473 | } | 472 | } |
| 474 | 473 | ||
| 474 | static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) | ||
| 475 | { | ||
| 476 | pcibios_fixup_resources(dev, 0, PCI_BRIDGE_RESOURCES); | ||
| 477 | } | ||
| 478 | |||
| 479 | static void __devinit pcibios_fixup_bridge_resources(struct pci_dev *dev) | ||
| 480 | { | ||
| 481 | pcibios_fixup_resources(dev, PCI_BRIDGE_RESOURCES, PCI_NUM_RESOURCES); | ||
| 482 | } | ||
| 483 | |||
| 475 | /* | 484 | /* |
| 476 | * Called after each bus is probed, but before its children are examined. | 485 | * Called after each bus is probed, but before its children are examined. |
| 477 | */ | 486 | */ |
| @@ -482,7 +491,7 @@ pcibios_fixup_bus (struct pci_bus *b) | |||
| 482 | 491 | ||
| 483 | if (b->self) { | 492 | if (b->self) { |
| 484 | pci_read_bridge_bases(b); | 493 | pci_read_bridge_bases(b); |
| 485 | pcibios_fixup_device_resources(b->self); | 494 | pcibios_fixup_bridge_resources(b->self); |
| 486 | } | 495 | } |
| 487 | list_for_each_entry(dev, &b->devices, bus_list) | 496 | list_for_each_entry(dev, &b->devices, bus_list) |
| 488 | pcibios_fixup_device_resources(dev); | 497 | pcibios_fixup_device_resources(dev); |
diff --git a/arch/ia64/sn/include/xtalk/hubdev.h b/arch/ia64/sn/include/xtalk/hubdev.h index 71c2b271b4c6..7c88e9a58516 100644 --- a/arch/ia64/sn/include/xtalk/hubdev.h +++ b/arch/ia64/sn/include/xtalk/hubdev.h | |||
| @@ -26,29 +26,37 @@ | |||
| 26 | #define IIO_NUM_ITTES 7 | 26 | #define IIO_NUM_ITTES 7 |
| 27 | #define HUB_NUM_BIG_WINDOW (IIO_NUM_ITTES - 1) | 27 | #define HUB_NUM_BIG_WINDOW (IIO_NUM_ITTES - 1) |
| 28 | 28 | ||
| 29 | struct sn_flush_device_list { | 29 | /* This struct is shared between the PROM and the kernel. |
| 30 | * Changes to this struct will require corresponding changes to the kernel. | ||
| 31 | */ | ||
| 32 | struct sn_flush_device_common { | ||
| 30 | int sfdl_bus; | 33 | int sfdl_bus; |
| 31 | int sfdl_slot; | 34 | int sfdl_slot; |
| 32 | int sfdl_pin; | 35 | int sfdl_pin; |
| 33 | struct bar_list { | 36 | struct common_bar_list { |
| 34 | unsigned long start; | 37 | unsigned long start; |
| 35 | unsigned long end; | 38 | unsigned long end; |
| 36 | } sfdl_bar_list[6]; | 39 | } sfdl_bar_list[6]; |
| 37 | unsigned long sfdl_force_int_addr; | 40 | unsigned long sfdl_force_int_addr; |
| 38 | unsigned long sfdl_flush_value; | 41 | unsigned long sfdl_flush_value; |
| 39 | volatile unsigned long *sfdl_flush_addr; | 42 | volatile unsigned long *sfdl_flush_addr; |
| 40 | uint32_t sfdl_persistent_busnum; | 43 | u32 sfdl_persistent_busnum; |
| 41 | uint32_t sfdl_persistent_segment; | 44 | u32 sfdl_persistent_segment; |
| 42 | struct pcibus_info *sfdl_pcibus_info; | 45 | struct pcibus_info *sfdl_pcibus_info; |
| 46 | }; | ||
| 47 | |||
| 48 | /* This struct is kernel only and is not used by the PROM */ | ||
| 49 | struct sn_flush_device_kernel { | ||
| 43 | spinlock_t sfdl_flush_lock; | 50 | spinlock_t sfdl_flush_lock; |
| 51 | struct sn_flush_device_common *common; | ||
| 44 | }; | 52 | }; |
| 45 | 53 | ||
| 46 | /* | 54 | /* |
| 47 | * **widget_p - Used as an array[wid_num][device] of sn_flush_device_list. | 55 | * **widget_p - Used as an array[wid_num][device] of sn_flush_device_kernel. |
| 48 | */ | 56 | */ |
| 49 | struct sn_flush_nasid_entry { | 57 | struct sn_flush_nasid_entry { |
| 50 | struct sn_flush_device_list **widget_p; /* Used as a array of wid_num */ | 58 | struct sn_flush_device_kernel **widget_p; // Used as an array of wid_num |
| 51 | uint64_t iio_itte[8]; | 59 | u64 iio_itte[8]; |
| 52 | }; | 60 | }; |
| 53 | 61 | ||
| 54 | struct hubdev_info { | 62 | struct hubdev_info { |
| @@ -62,8 +70,8 @@ struct hubdev_info { | |||
| 62 | 70 | ||
| 63 | void *hdi_nodepda; | 71 | void *hdi_nodepda; |
| 64 | void *hdi_node_vertex; | 72 | void *hdi_node_vertex; |
| 65 | uint32_t max_segment_number; | 73 | u32 max_segment_number; |
| 66 | uint32_t max_pcibus_number; | 74 | u32 max_pcibus_number; |
| 67 | }; | 75 | }; |
| 68 | 76 | ||
| 69 | extern void hubdev_init_node(nodepda_t *, cnodeid_t); | 77 | extern void hubdev_init_node(nodepda_t *, cnodeid_t); |
diff --git a/arch/ia64/sn/include/xtalk/xbow.h b/arch/ia64/sn/include/xtalk/xbow.h index ec56b3432f17..90f37a4133d0 100644 --- a/arch/ia64/sn/include/xtalk/xbow.h +++ b/arch/ia64/sn/include/xtalk/xbow.h | |||
| @@ -3,7 +3,8 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 1992-1997,2000-2004 Silicon Graphics, Inc. All Rights Reserved. | 6 | * Copyright (C) 1992-1997,2000-2006 Silicon Graphics, Inc. All Rights |
| 7 | * Reserved. | ||
| 7 | */ | 8 | */ |
| 8 | #ifndef _ASM_IA64_SN_XTALK_XBOW_H | 9 | #ifndef _ASM_IA64_SN_XTALK_XBOW_H |
| 9 | #define _ASM_IA64_SN_XTALK_XBOW_H | 10 | #define _ASM_IA64_SN_XTALK_XBOW_H |
| @@ -21,94 +22,94 @@ | |||
| 21 | 22 | ||
| 22 | /* Register set for each xbow link */ | 23 | /* Register set for each xbow link */ |
| 23 | typedef volatile struct xb_linkregs_s { | 24 | typedef volatile struct xb_linkregs_s { |
| 24 | /* | 25 | /* |
| 25 | * we access these through synergy unswizzled space, so the address | 26 | * we access these through synergy unswizzled space, so the address |
| 26 | * gets twiddled (i.e. references to 0x4 actually go to 0x0 and vv.) | 27 | * gets twiddled (i.e. references to 0x4 actually go to 0x0 and vv.) |
| 27 | * That's why we put the register first and filler second. | 28 | * That's why we put the register first and filler second. |
| 28 | */ | 29 | */ |
| 29 | uint32_t link_ibf; | 30 | u32 link_ibf; |
| 30 | uint32_t filler0; /* filler for proper alignment */ | 31 | u32 filler0; /* filler for proper alignment */ |
| 31 | uint32_t link_control; | 32 | u32 link_control; |
| 32 | uint32_t filler1; | 33 | u32 filler1; |
| 33 | uint32_t link_status; | 34 | u32 link_status; |
| 34 | uint32_t filler2; | 35 | u32 filler2; |
| 35 | uint32_t link_arb_upper; | 36 | u32 link_arb_upper; |
| 36 | uint32_t filler3; | 37 | u32 filler3; |
| 37 | uint32_t link_arb_lower; | 38 | u32 link_arb_lower; |
| 38 | uint32_t filler4; | 39 | u32 filler4; |
| 39 | uint32_t link_status_clr; | 40 | u32 link_status_clr; |
| 40 | uint32_t filler5; | 41 | u32 filler5; |
| 41 | uint32_t link_reset; | 42 | u32 link_reset; |
| 42 | uint32_t filler6; | 43 | u32 filler6; |
| 43 | uint32_t link_aux_status; | 44 | u32 link_aux_status; |
| 44 | uint32_t filler7; | 45 | u32 filler7; |
| 45 | } xb_linkregs_t; | 46 | } xb_linkregs_t; |
| 46 | 47 | ||
| 47 | typedef volatile struct xbow_s { | 48 | typedef volatile struct xbow_s { |
| 48 | /* standard widget configuration 0x000000-0x000057 */ | 49 | /* standard widget configuration 0x000000-0x000057 */ |
| 49 | struct widget_cfg xb_widget; /* 0x000000 */ | 50 | struct widget_cfg xb_widget; /* 0x000000 */ |
| 50 | 51 | ||
| 51 | /* helper fieldnames for accessing bridge widget */ | 52 | /* helper fieldnames for accessing bridge widget */ |
| 52 | 53 | ||
| 53 | #define xb_wid_id xb_widget.w_id | 54 | #define xb_wid_id xb_widget.w_id |
| 54 | #define xb_wid_stat xb_widget.w_status | 55 | #define xb_wid_stat xb_widget.w_status |
| 55 | #define xb_wid_err_upper xb_widget.w_err_upper_addr | 56 | #define xb_wid_err_upper xb_widget.w_err_upper_addr |
| 56 | #define xb_wid_err_lower xb_widget.w_err_lower_addr | 57 | #define xb_wid_err_lower xb_widget.w_err_lower_addr |
| 57 | #define xb_wid_control xb_widget.w_control | 58 | #define xb_wid_control xb_widget.w_control |
| 58 | #define xb_wid_req_timeout xb_widget.w_req_timeout | 59 | #define xb_wid_req_timeout xb_widget.w_req_timeout |
| 59 | #define xb_wid_int_upper xb_widget.w_intdest_upper_addr | 60 | #define xb_wid_int_upper xb_widget.w_intdest_upper_addr |
| 60 | #define xb_wid_int_lower xb_widget.w_intdest_lower_addr | 61 | #define xb_wid_int_lower xb_widget.w_intdest_lower_addr |
| 61 | #define xb_wid_err_cmdword xb_widget.w_err_cmd_word | 62 | #define xb_wid_err_cmdword xb_widget.w_err_cmd_word |
| 62 | #define xb_wid_llp xb_widget.w_llp_cfg | 63 | #define xb_wid_llp xb_widget.w_llp_cfg |
| 63 | #define xb_wid_stat_clr xb_widget.w_tflush | 64 | #define xb_wid_stat_clr xb_widget.w_tflush |
| 64 | 65 | ||
| 65 | /* | 66 | /* |
| 66 | * we access these through synergy unswizzled space, so the address | 67 | * we access these through synergy unswizzled space, so the address |
| 67 | * gets twiddled (i.e. references to 0x4 actually go to 0x0 and vv.) | 68 | * gets twiddled (i.e. references to 0x4 actually go to 0x0 and vv.) |
| 68 | * That's why we put the register first and filler second. | 69 | * That's why we put the register first and filler second. |
| 69 | */ | 70 | */ |
| 70 | /* xbow-specific widget configuration 0x000058-0x0000FF */ | 71 | /* xbow-specific widget configuration 0x000058-0x0000FF */ |
| 71 | uint32_t xb_wid_arb_reload; /* 0x00005C */ | 72 | u32 xb_wid_arb_reload; /* 0x00005C */ |
| 72 | uint32_t _pad_000058; | 73 | u32 _pad_000058; |
| 73 | uint32_t xb_perf_ctr_a; /* 0x000064 */ | 74 | u32 xb_perf_ctr_a; /* 0x000064 */ |
| 74 | uint32_t _pad_000060; | 75 | u32 _pad_000060; |
| 75 | uint32_t xb_perf_ctr_b; /* 0x00006c */ | 76 | u32 xb_perf_ctr_b; /* 0x00006c */ |
| 76 | uint32_t _pad_000068; | 77 | u32 _pad_000068; |
| 77 | uint32_t xb_nic; /* 0x000074 */ | 78 | u32 xb_nic; /* 0x000074 */ |
| 78 | uint32_t _pad_000070; | 79 | u32 _pad_000070; |
| 79 | 80 | ||
| 80 | /* Xbridge only */ | 81 | /* Xbridge only */ |
| 81 | uint32_t xb_w0_rst_fnc; /* 0x00007C */ | 82 | u32 xb_w0_rst_fnc; /* 0x00007C */ |
| 82 | uint32_t _pad_000078; | 83 | u32 _pad_000078; |
| 83 | uint32_t xb_l8_rst_fnc; /* 0x000084 */ | 84 | u32 xb_l8_rst_fnc; /* 0x000084 */ |
| 84 | uint32_t _pad_000080; | 85 | u32 _pad_000080; |
| 85 | uint32_t xb_l9_rst_fnc; /* 0x00008c */ | 86 | u32 xb_l9_rst_fnc; /* 0x00008c */ |
| 86 | uint32_t _pad_000088; | 87 | u32 _pad_000088; |
| 87 | uint32_t xb_la_rst_fnc; /* 0x000094 */ | 88 | u32 xb_la_rst_fnc; /* 0x000094 */ |
| 88 | uint32_t _pad_000090; | 89 | u32 _pad_000090; |
| 89 | uint32_t xb_lb_rst_fnc; /* 0x00009c */ | 90 | u32 xb_lb_rst_fnc; /* 0x00009c */ |
| 90 | uint32_t _pad_000098; | 91 | u32 _pad_000098; |
| 91 | uint32_t xb_lc_rst_fnc; /* 0x0000a4 */ | 92 | u32 xb_lc_rst_fnc; /* 0x0000a4 */ |
| 92 | uint32_t _pad_0000a0; | 93 | u32 _pad_0000a0; |
| 93 | uint32_t xb_ld_rst_fnc; /* 0x0000ac */ | 94 | u32 xb_ld_rst_fnc; /* 0x0000ac */ |
| 94 | uint32_t _pad_0000a8; | 95 | u32 _pad_0000a8; |
| 95 | uint32_t xb_le_rst_fnc; /* 0x0000b4 */ | 96 | u32 xb_le_rst_fnc; /* 0x0000b4 */ |
| 96 | uint32_t _pad_0000b0; | 97 | u32 _pad_0000b0; |
| 97 | uint32_t xb_lf_rst_fnc; /* 0x0000bc */ | 98 | u32 xb_lf_rst_fnc; /* 0x0000bc */ |
| 98 | uint32_t _pad_0000b8; | 99 | u32 _pad_0000b8; |
| 99 | uint32_t xb_lock; /* 0x0000c4 */ | 100 | u32 xb_lock; /* 0x0000c4 */ |
| 100 | uint32_t _pad_0000c0; | 101 | u32 _pad_0000c0; |
| 101 | uint32_t xb_lock_clr; /* 0x0000cc */ | 102 | u32 xb_lock_clr; /* 0x0000cc */ |
| 102 | uint32_t _pad_0000c8; | 103 | u32 _pad_0000c8; |
| 103 | /* end of Xbridge only */ | 104 | /* end of Xbridge only */ |
| 104 | uint32_t _pad_0000d0[12]; | 105 | u32 _pad_0000d0[12]; |
| 105 | 106 | ||
| 106 | /* Link Specific Registers, port 8..15 0x000100-0x000300 */ | 107 | /* Link Specific Registers, port 8..15 0x000100-0x000300 */ |
| 107 | xb_linkregs_t xb_link_raw[MAX_XBOW_PORTS]; | 108 | xb_linkregs_t xb_link_raw[MAX_XBOW_PORTS]; |
| 108 | #define xb_link(p) xb_link_raw[(p) & (MAX_XBOW_PORTS - 1)] | ||
| 109 | |||
| 110 | } xbow_t; | 109 | } xbow_t; |
| 111 | 110 | ||
| 111 | #define xb_link(p) xb_link_raw[(p) & (MAX_XBOW_PORTS - 1)] | ||
| 112 | |||
| 112 | #define XB_FLAGS_EXISTS 0x1 /* device exists */ | 113 | #define XB_FLAGS_EXISTS 0x1 /* device exists */ |
| 113 | #define XB_FLAGS_MASTER 0x2 | 114 | #define XB_FLAGS_MASTER 0x2 |
| 114 | #define XB_FLAGS_SLAVE 0x0 | 115 | #define XB_FLAGS_SLAVE 0x0 |
| @@ -160,7 +161,7 @@ typedef volatile struct xbow_s { | |||
| 160 | /* End of Xbridge only */ | 161 | /* End of Xbridge only */ |
| 161 | 162 | ||
| 162 | /* used only in ide, but defined here within the reserved portion */ | 163 | /* used only in ide, but defined here within the reserved portion */ |
| 163 | /* of the widget0 address space (before 0xf4) */ | 164 | /* of the widget0 address space (before 0xf4) */ |
| 164 | #define XBOW_WID_UNDEF 0xe4 | 165 | #define XBOW_WID_UNDEF 0xe4 |
| 165 | 166 | ||
| 166 | /* xbow link register set base, legal value for x is 0x8..0xf */ | 167 | /* xbow link register set base, legal value for x is 0x8..0xf */ |
| @@ -179,29 +180,37 @@ typedef volatile struct xbow_s { | |||
| 179 | 180 | ||
| 180 | /* link_control(x) */ | 181 | /* link_control(x) */ |
| 181 | #define XB_CTRL_LINKALIVE_IE 0x80000000 /* link comes alive */ | 182 | #define XB_CTRL_LINKALIVE_IE 0x80000000 /* link comes alive */ |
| 182 | /* reserved: 0x40000000 */ | 183 | /* reserved: 0x40000000 */ |
| 183 | #define XB_CTRL_PERF_CTR_MODE_MSK 0x30000000 /* perf counter mode */ | 184 | #define XB_CTRL_PERF_CTR_MODE_MSK 0x30000000 /* perf counter mode */ |
| 184 | #define XB_CTRL_IBUF_LEVEL_MSK 0x0e000000 /* input packet buffer level */ | 185 | #define XB_CTRL_IBUF_LEVEL_MSK 0x0e000000 /* input packet buffer |
| 185 | #define XB_CTRL_8BIT_MODE 0x01000000 /* force link into 8 bit mode */ | 186 | level */ |
| 186 | #define XB_CTRL_BAD_LLP_PKT 0x00800000 /* force bad LLP packet */ | 187 | #define XB_CTRL_8BIT_MODE 0x01000000 /* force link into 8 |
| 187 | #define XB_CTRL_WIDGET_CR_MSK 0x007c0000 /* LLP widget credit mask */ | 188 | bit mode */ |
| 188 | #define XB_CTRL_WIDGET_CR_SHFT 18 /* LLP widget credit shift */ | 189 | #define XB_CTRL_BAD_LLP_PKT 0x00800000 /* force bad LLP |
| 189 | #define XB_CTRL_ILLEGAL_DST_IE 0x00020000 /* illegal destination */ | 190 | packet */ |
| 190 | #define XB_CTRL_OALLOC_IBUF_IE 0x00010000 /* overallocated input buffer */ | 191 | #define XB_CTRL_WIDGET_CR_MSK 0x007c0000 /* LLP widget credit |
| 191 | /* reserved: 0x0000fe00 */ | 192 | mask */ |
| 193 | #define XB_CTRL_WIDGET_CR_SHFT 18 /* LLP widget credit | ||
| 194 | shift */ | ||
| 195 | #define XB_CTRL_ILLEGAL_DST_IE 0x00020000 /* illegal destination | ||
| 196 | */ | ||
| 197 | #define XB_CTRL_OALLOC_IBUF_IE 0x00010000 /* overallocated input | ||
| 198 | buffer */ | ||
| 199 | /* reserved: 0x0000fe00 */ | ||
| 192 | #define XB_CTRL_BNDWDTH_ALLOC_IE 0x00000100 /* bandwidth alloc */ | 200 | #define XB_CTRL_BNDWDTH_ALLOC_IE 0x00000100 /* bandwidth alloc */ |
| 193 | #define XB_CTRL_RCV_CNT_OFLOW_IE 0x00000080 /* rcv retry overflow */ | 201 | #define XB_CTRL_RCV_CNT_OFLOW_IE 0x00000080 /* rcv retry overflow */ |
| 194 | #define XB_CTRL_XMT_CNT_OFLOW_IE 0x00000040 /* xmt retry overflow */ | 202 | #define XB_CTRL_XMT_CNT_OFLOW_IE 0x00000040 /* xmt retry overflow */ |
| 195 | #define XB_CTRL_XMT_MAX_RTRY_IE 0x00000020 /* max transmit retry */ | 203 | #define XB_CTRL_XMT_MAX_RTRY_IE 0x00000020 /* max transmit retry */ |
| 196 | #define XB_CTRL_RCV_IE 0x00000010 /* receive */ | 204 | #define XB_CTRL_RCV_IE 0x00000010 /* receive */ |
| 197 | #define XB_CTRL_XMT_RTRY_IE 0x00000008 /* transmit retry */ | 205 | #define XB_CTRL_XMT_RTRY_IE 0x00000008 /* transmit retry */ |
| 198 | /* reserved: 0x00000004 */ | 206 | /* reserved: 0x00000004 */ |
| 199 | #define XB_CTRL_MAXREQ_TOUT_IE 0x00000002 /* maximum request timeout */ | 207 | #define XB_CTRL_MAXREQ_TOUT_IE 0x00000002 /* maximum request |
| 208 | timeout */ | ||
| 200 | #define XB_CTRL_SRC_TOUT_IE 0x00000001 /* source timeout */ | 209 | #define XB_CTRL_SRC_TOUT_IE 0x00000001 /* source timeout */ |
| 201 | 210 | ||
| 202 | /* link_status(x) */ | 211 | /* link_status(x) */ |
| 203 | #define XB_STAT_LINKALIVE XB_CTRL_LINKALIVE_IE | 212 | #define XB_STAT_LINKALIVE XB_CTRL_LINKALIVE_IE |
| 204 | /* reserved: 0x7ff80000 */ | 213 | /* reserved: 0x7ff80000 */ |
| 205 | #define XB_STAT_MULTI_ERR 0x00040000 /* multi error */ | 214 | #define XB_STAT_MULTI_ERR 0x00040000 /* multi error */ |
| 206 | #define XB_STAT_ILLEGAL_DST_ERR XB_CTRL_ILLEGAL_DST_IE | 215 | #define XB_STAT_ILLEGAL_DST_ERR XB_CTRL_ILLEGAL_DST_IE |
| 207 | #define XB_STAT_OALLOC_IBUF_ERR XB_CTRL_OALLOC_IBUF_IE | 216 | #define XB_STAT_OALLOC_IBUF_ERR XB_CTRL_OALLOC_IBUF_IE |
| @@ -211,7 +220,7 @@ typedef volatile struct xbow_s { | |||
| 211 | #define XB_STAT_XMT_MAX_RTRY_ERR XB_CTRL_XMT_MAX_RTRY_IE | 220 | #define XB_STAT_XMT_MAX_RTRY_ERR XB_CTRL_XMT_MAX_RTRY_IE |
| 212 | #define XB_STAT_RCV_ERR XB_CTRL_RCV_IE | 221 | #define XB_STAT_RCV_ERR XB_CTRL_RCV_IE |
| 213 | #define XB_STAT_XMT_RTRY_ERR XB_CTRL_XMT_RTRY_IE | 222 | #define XB_STAT_XMT_RTRY_ERR XB_CTRL_XMT_RTRY_IE |
| 214 | /* reserved: 0x00000004 */ | 223 | /* reserved: 0x00000004 */ |
| 215 | #define XB_STAT_MAXREQ_TOUT_ERR XB_CTRL_MAXREQ_TOUT_IE | 224 | #define XB_STAT_MAXREQ_TOUT_ERR XB_CTRL_MAXREQ_TOUT_IE |
| 216 | #define XB_STAT_SRC_TOUT_ERR XB_CTRL_SRC_TOUT_IE | 225 | #define XB_STAT_SRC_TOUT_ERR XB_CTRL_SRC_TOUT_IE |
| 217 | 226 | ||
| @@ -222,7 +231,7 @@ typedef volatile struct xbow_s { | |||
| 222 | #define XB_AUX_LINKFAIL_RST_BAD 0x00000040 | 231 | #define XB_AUX_LINKFAIL_RST_BAD 0x00000040 |
| 223 | #define XB_AUX_STAT_PRESENT 0x00000020 | 232 | #define XB_AUX_STAT_PRESENT 0x00000020 |
| 224 | #define XB_AUX_STAT_PORT_WIDTH 0x00000010 | 233 | #define XB_AUX_STAT_PORT_WIDTH 0x00000010 |
| 225 | /* reserved: 0x0000000f */ | 234 | /* reserved: 0x0000000f */ |
| 226 | 235 | ||
| 227 | /* | 236 | /* |
| 228 | * link_arb_upper/link_arb_lower(x), (reg) should be the link_arb_upper | 237 | * link_arb_upper/link_arb_lower(x), (reg) should be the link_arb_upper |
| @@ -238,7 +247,8 @@ typedef volatile struct xbow_s { | |||
| 238 | /* XBOW_WID_STAT */ | 247 | /* XBOW_WID_STAT */ |
| 239 | #define XB_WID_STAT_LINK_INTR_SHFT (24) | 248 | #define XB_WID_STAT_LINK_INTR_SHFT (24) |
| 240 | #define XB_WID_STAT_LINK_INTR_MASK (0xFF << XB_WID_STAT_LINK_INTR_SHFT) | 249 | #define XB_WID_STAT_LINK_INTR_MASK (0xFF << XB_WID_STAT_LINK_INTR_SHFT) |
| 241 | #define XB_WID_STAT_LINK_INTR(x) (0x1 << (((x)&7) + XB_WID_STAT_LINK_INTR_SHFT)) | 250 | #define XB_WID_STAT_LINK_INTR(x) \ |
| 251 | (0x1 << (((x)&7) + XB_WID_STAT_LINK_INTR_SHFT)) | ||
| 242 | #define XB_WID_STAT_WIDGET0_INTR 0x00800000 | 252 | #define XB_WID_STAT_WIDGET0_INTR 0x00800000 |
| 243 | #define XB_WID_STAT_SRCID_MASK 0x000003c0 /* Xbridge only */ | 253 | #define XB_WID_STAT_SRCID_MASK 0x000003c0 /* Xbridge only */ |
| 244 | #define XB_WID_STAT_REG_ACC_ERR 0x00000020 | 254 | #define XB_WID_STAT_REG_ACC_ERR 0x00000020 |
| @@ -264,7 +274,7 @@ typedef volatile struct xbow_s { | |||
| 264 | #define XXBOW_WIDGET_PART_NUM 0xd000 /* Xbridge */ | 274 | #define XXBOW_WIDGET_PART_NUM 0xd000 /* Xbridge */ |
| 265 | #define XBOW_WIDGET_MFGR_NUM 0x0 | 275 | #define XBOW_WIDGET_MFGR_NUM 0x0 |
| 266 | #define XXBOW_WIDGET_MFGR_NUM 0x0 | 276 | #define XXBOW_WIDGET_MFGR_NUM 0x0 |
| 267 | #define PXBOW_WIDGET_PART_NUM 0xd100 /* PIC */ | 277 | #define PXBOW_WIDGET_PART_NUM 0xd100 /* PIC */ |
| 268 | 278 | ||
| 269 | #define XBOW_REV_1_0 0x1 /* xbow rev 1.0 is "1" */ | 279 | #define XBOW_REV_1_0 0x1 /* xbow rev 1.0 is "1" */ |
| 270 | #define XBOW_REV_1_1 0x2 /* xbow rev 1.1 is "2" */ | 280 | #define XBOW_REV_1_1 0x2 /* xbow rev 1.1 is "2" */ |
| @@ -279,13 +289,13 @@ typedef volatile struct xbow_s { | |||
| 279 | #define XBOW_WID_ARB_RELOAD_INT 0x3f /* GBR reload interval */ | 289 | #define XBOW_WID_ARB_RELOAD_INT 0x3f /* GBR reload interval */ |
| 280 | 290 | ||
| 281 | #define IS_XBRIDGE_XBOW(wid) \ | 291 | #define IS_XBRIDGE_XBOW(wid) \ |
| 282 | (XWIDGET_PART_NUM(wid) == XXBOW_WIDGET_PART_NUM && \ | 292 | (XWIDGET_PART_NUM(wid) == XXBOW_WIDGET_PART_NUM && \ |
| 283 | XWIDGET_MFG_NUM(wid) == XXBOW_WIDGET_MFGR_NUM) | 293 | XWIDGET_MFG_NUM(wid) == XXBOW_WIDGET_MFGR_NUM) |
| 284 | 294 | ||
| 285 | #define IS_PIC_XBOW(wid) \ | 295 | #define IS_PIC_XBOW(wid) \ |
| 286 | (XWIDGET_PART_NUM(wid) == PXBOW_WIDGET_PART_NUM && \ | 296 | (XWIDGET_PART_NUM(wid) == PXBOW_WIDGET_PART_NUM && \ |
| 287 | XWIDGET_MFG_NUM(wid) == XXBOW_WIDGET_MFGR_NUM) | 297 | XWIDGET_MFG_NUM(wid) == XXBOW_WIDGET_MFGR_NUM) |
| 288 | 298 | ||
| 289 | #define XBOW_WAR_ENABLED(pv, widid) ((1 << XWIDGET_REV_NUM(widid)) & pv) | 299 | #define XBOW_WAR_ENABLED(pv, widid) ((1 << XWIDGET_REV_NUM(widid)) & pv) |
| 290 | 300 | ||
| 291 | #endif /* _ASM_IA64_SN_XTALK_XBOW_H */ | 301 | #endif /* _ASM_IA64_SN_XTALK_XBOW_H */ |
diff --git a/arch/ia64/sn/include/xtalk/xwidgetdev.h b/arch/ia64/sn/include/xtalk/xwidgetdev.h index c5f4bc5cc033..2800eda0fd68 100644 --- a/arch/ia64/sn/include/xtalk/xwidgetdev.h +++ b/arch/ia64/sn/include/xtalk/xwidgetdev.h | |||
| @@ -25,28 +25,28 @@ | |||
| 25 | 25 | ||
| 26 | /* widget configuration registers */ | 26 | /* widget configuration registers */ |
| 27 | struct widget_cfg{ | 27 | struct widget_cfg{ |
| 28 | uint32_t w_id; /* 0x04 */ | 28 | u32 w_id; /* 0x04 */ |
| 29 | uint32_t w_pad_0; /* 0x00 */ | 29 | u32 w_pad_0; /* 0x00 */ |
| 30 | uint32_t w_status; /* 0x0c */ | 30 | u32 w_status; /* 0x0c */ |
| 31 | uint32_t w_pad_1; /* 0x08 */ | 31 | u32 w_pad_1; /* 0x08 */ |
| 32 | uint32_t w_err_upper_addr; /* 0x14 */ | 32 | u32 w_err_upper_addr; /* 0x14 */ |
| 33 | uint32_t w_pad_2; /* 0x10 */ | 33 | u32 w_pad_2; /* 0x10 */ |
| 34 | uint32_t w_err_lower_addr; /* 0x1c */ | 34 | u32 w_err_lower_addr; /* 0x1c */ |
| 35 | uint32_t w_pad_3; /* 0x18 */ | 35 | u32 w_pad_3; /* 0x18 */ |
| 36 | uint32_t w_control; /* 0x24 */ | 36 | u32 w_control; /* 0x24 */ |
| 37 | uint32_t w_pad_4; /* 0x20 */ | 37 | u32 w_pad_4; /* 0x20 */ |
| 38 | uint32_t w_req_timeout; /* 0x2c */ | 38 | u32 w_req_timeout; /* 0x2c */ |
| 39 | uint32_t w_pad_5; /* 0x28 */ | 39 | u32 w_pad_5; /* 0x28 */ |
| 40 | uint32_t w_intdest_upper_addr; /* 0x34 */ | 40 | u32 w_intdest_upper_addr; /* 0x34 */ |
| 41 | uint32_t w_pad_6; /* 0x30 */ | 41 | u32 w_pad_6; /* 0x30 */ |
| 42 | uint32_t w_intdest_lower_addr; /* 0x3c */ | 42 | u32 w_intdest_lower_addr; /* 0x3c */ |
| 43 | uint32_t w_pad_7; /* 0x38 */ | 43 | u32 w_pad_7; /* 0x38 */ |
| 44 | uint32_t w_err_cmd_word; /* 0x44 */ | 44 | u32 w_err_cmd_word; /* 0x44 */ |
| 45 | uint32_t w_pad_8; /* 0x40 */ | 45 | u32 w_pad_8; /* 0x40 */ |
| 46 | uint32_t w_llp_cfg; /* 0x4c */ | 46 | u32 w_llp_cfg; /* 0x4c */ |
| 47 | uint32_t w_pad_9; /* 0x48 */ | 47 | u32 w_pad_9; /* 0x48 */ |
| 48 | uint32_t w_tflush; /* 0x54 */ | 48 | u32 w_tflush; /* 0x54 */ |
| 49 | uint32_t w_pad_10; /* 0x50 */ | 49 | u32 w_pad_10; /* 0x50 */ |
| 50 | }; | 50 | }; |
| 51 | 51 | ||
| 52 | /* | 52 | /* |
| @@ -63,7 +63,7 @@ struct xwidget_info{ | |||
| 63 | struct xwidget_hwid xwi_hwid; /* Widget Identification */ | 63 | struct xwidget_hwid xwi_hwid; /* Widget Identification */ |
| 64 | char xwi_masterxid; /* Hub's Widget Port Number */ | 64 | char xwi_masterxid; /* Hub's Widget Port Number */ |
| 65 | void *xwi_hubinfo; /* Hub's provider private info */ | 65 | void *xwi_hubinfo; /* Hub's provider private info */ |
| 66 | uint64_t *xwi_hub_provider; /* prom provider functions */ | 66 | u64 *xwi_hub_provider; /* prom provider functions */ |
| 67 | void *xwi_vertex; | 67 | void *xwi_vertex; |
| 68 | }; | 68 | }; |
| 69 | 69 | ||
diff --git a/arch/ia64/sn/kernel/bte_error.c b/arch/ia64/sn/kernel/bte_error.c index fcbc748ae433..f1ec1370b3e3 100644 --- a/arch/ia64/sn/kernel/bte_error.c +++ b/arch/ia64/sn/kernel/bte_error.c | |||
| @@ -33,7 +33,7 @@ void bte_error_handler(unsigned long); | |||
| 33 | * Wait until all BTE related CRBs are completed | 33 | * Wait until all BTE related CRBs are completed |
| 34 | * and then reset the interfaces. | 34 | * and then reset the interfaces. |
| 35 | */ | 35 | */ |
| 36 | void shub1_bte_error_handler(unsigned long _nodepda) | 36 | int shub1_bte_error_handler(unsigned long _nodepda) |
| 37 | { | 37 | { |
| 38 | struct nodepda_s *err_nodepda = (struct nodepda_s *)_nodepda; | 38 | struct nodepda_s *err_nodepda = (struct nodepda_s *)_nodepda; |
| 39 | struct timer_list *recovery_timer = &err_nodepda->bte_recovery_timer; | 39 | struct timer_list *recovery_timer = &err_nodepda->bte_recovery_timer; |
| @@ -53,7 +53,7 @@ void shub1_bte_error_handler(unsigned long _nodepda) | |||
| 53 | (err_nodepda->bte_if[1].bh_error == BTE_SUCCESS)) { | 53 | (err_nodepda->bte_if[1].bh_error == BTE_SUCCESS)) { |
| 54 | BTE_PRINTK(("eh:%p:%d Nothing to do.\n", err_nodepda, | 54 | BTE_PRINTK(("eh:%p:%d Nothing to do.\n", err_nodepda, |
| 55 | smp_processor_id())); | 55 | smp_processor_id())); |
| 56 | return; | 56 | return 1; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | /* Determine information about our hub */ | 59 | /* Determine information about our hub */ |
| @@ -81,7 +81,7 @@ void shub1_bte_error_handler(unsigned long _nodepda) | |||
| 81 | mod_timer(recovery_timer, HZ * 5); | 81 | mod_timer(recovery_timer, HZ * 5); |
| 82 | BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda, | 82 | BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda, |
| 83 | smp_processor_id())); | 83 | smp_processor_id())); |
| 84 | return; | 84 | return 1; |
| 85 | } | 85 | } |
| 86 | if (icmr.ii_icmr_fld_s.i_crb_vld != 0) { | 86 | if (icmr.ii_icmr_fld_s.i_crb_vld != 0) { |
| 87 | 87 | ||
| @@ -99,7 +99,7 @@ void shub1_bte_error_handler(unsigned long _nodepda) | |||
| 99 | BTE_PRINTK(("eh:%p:%d Valid %d, Giving up\n", | 99 | BTE_PRINTK(("eh:%p:%d Valid %d, Giving up\n", |
| 100 | err_nodepda, smp_processor_id(), | 100 | err_nodepda, smp_processor_id(), |
| 101 | i)); | 101 | i)); |
| 102 | return; | 102 | return 1; |
| 103 | } | 103 | } |
| 104 | } | 104 | } |
| 105 | } | 105 | } |
| @@ -124,6 +124,42 @@ void shub1_bte_error_handler(unsigned long _nodepda) | |||
| 124 | REMOTE_HUB_S(nasid, IIO_IBCR, ibcr.ii_ibcr_regval); | 124 | REMOTE_HUB_S(nasid, IIO_IBCR, ibcr.ii_ibcr_regval); |
| 125 | 125 | ||
| 126 | del_timer(recovery_timer); | 126 | del_timer(recovery_timer); |
| 127 | return 0; | ||
| 128 | } | ||
| 129 | |||
| 130 | /* | ||
| 131 | * Wait until all BTE related CRBs are completed | ||
| 132 | * and then reset the interfaces. | ||
| 133 | */ | ||
| 134 | int shub2_bte_error_handler(unsigned long _nodepda) | ||
| 135 | { | ||
| 136 | struct nodepda_s *err_nodepda = (struct nodepda_s *)_nodepda; | ||
| 137 | struct timer_list *recovery_timer = &err_nodepda->bte_recovery_timer; | ||
| 138 | struct bteinfo_s *bte; | ||
| 139 | nasid_t nasid; | ||
| 140 | u64 status; | ||
| 141 | int i; | ||
| 142 | |||
| 143 | nasid = cnodeid_to_nasid(err_nodepda->bte_if[0].bte_cnode); | ||
| 144 | |||
| 145 | /* | ||
| 146 | * Verify that all the BTEs are complete | ||
| 147 | */ | ||
| 148 | for (i = 0; i < BTES_PER_NODE; i++) { | ||
| 149 | bte = &err_nodepda->bte_if[i]; | ||
| 150 | status = BTE_LNSTAT_LOAD(bte); | ||
| 151 | if ((status & IBLS_ERROR) || !(status & IBLS_BUSY)) | ||
| 152 | continue; | ||
| 153 | mod_timer(recovery_timer, HZ * 5); | ||
| 154 | BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda, | ||
| 155 | smp_processor_id())); | ||
| 156 | return 1; | ||
| 157 | } | ||
| 158 | if (ia64_sn_bte_recovery(nasid)) | ||
| 159 | panic("bte_error_handler(): Fatal BTE Error"); | ||
| 160 | |||
| 161 | del_timer(recovery_timer); | ||
| 162 | return 0; | ||
| 127 | } | 163 | } |
| 128 | 164 | ||
| 129 | /* | 165 | /* |
| @@ -135,7 +171,6 @@ void bte_error_handler(unsigned long _nodepda) | |||
| 135 | struct nodepda_s *err_nodepda = (struct nodepda_s *)_nodepda; | 171 | struct nodepda_s *err_nodepda = (struct nodepda_s *)_nodepda; |
| 136 | spinlock_t *recovery_lock = &err_nodepda->bte_recovery_lock; | 172 | spinlock_t *recovery_lock = &err_nodepda->bte_recovery_lock; |
| 137 | int i; | 173 | int i; |
| 138 | nasid_t nasid; | ||
| 139 | unsigned long irq_flags; | 174 | unsigned long irq_flags; |
| 140 | volatile u64 *notify; | 175 | volatile u64 *notify; |
| 141 | bte_result_t bh_error; | 176 | bte_result_t bh_error; |
| @@ -160,12 +195,15 @@ void bte_error_handler(unsigned long _nodepda) | |||
| 160 | } | 195 | } |
| 161 | 196 | ||
| 162 | if (is_shub1()) { | 197 | if (is_shub1()) { |
| 163 | shub1_bte_error_handler(_nodepda); | 198 | if (shub1_bte_error_handler(_nodepda)) { |
| 199 | spin_unlock_irqrestore(recovery_lock, irq_flags); | ||
| 200 | return; | ||
| 201 | } | ||
| 164 | } else { | 202 | } else { |
| 165 | nasid = cnodeid_to_nasid(err_nodepda->bte_if[0].bte_cnode); | 203 | if (shub2_bte_error_handler(_nodepda)) { |
| 166 | 204 | spin_unlock_irqrestore(recovery_lock, irq_flags); | |
| 167 | if (ia64_sn_bte_recovery(nasid)) | 205 | return; |
| 168 | panic("bte_error_handler(): Fatal BTE Error"); | 206 | } |
| 169 | } | 207 | } |
| 170 | 208 | ||
| 171 | for (i = 0; i < BTES_PER_NODE; i++) { | 209 | for (i = 0; i < BTES_PER_NODE; i++) { |
diff --git a/arch/ia64/sn/kernel/huberror.c b/arch/ia64/sn/kernel/huberror.c index 5c5eb01c50f0..56ab6bae00ee 100644 --- a/arch/ia64/sn/kernel/huberror.c +++ b/arch/ia64/sn/kernel/huberror.c | |||
| @@ -32,13 +32,14 @@ static irqreturn_t hub_eint_handler(int irq, void *arg, struct pt_regs *ep) | |||
| 32 | ret_stuff.v0 = 0; | 32 | ret_stuff.v0 = 0; |
| 33 | hubdev_info = (struct hubdev_info *)arg; | 33 | hubdev_info = (struct hubdev_info *)arg; |
| 34 | nasid = hubdev_info->hdi_nasid; | 34 | nasid = hubdev_info->hdi_nasid; |
| 35 | SAL_CALL_NOLOCK(ret_stuff, SN_SAL_HUB_ERROR_INTERRUPT, | 35 | |
| 36 | if (is_shub1()) { | ||
| 37 | SAL_CALL_NOLOCK(ret_stuff, SN_SAL_HUB_ERROR_INTERRUPT, | ||
| 36 | (u64) nasid, 0, 0, 0, 0, 0, 0); | 38 | (u64) nasid, 0, 0, 0, 0, 0, 0); |
| 37 | 39 | ||
| 38 | if ((int)ret_stuff.v0) | 40 | if ((int)ret_stuff.v0) |
| 39 | panic("hubii_eint_handler(): Fatal TIO Error"); | 41 | panic("hubii_eint_handler(): Fatal TIO Error"); |
| 40 | 42 | ||
| 41 | if (is_shub1()) { | ||
| 42 | if (!(nasid & 1)) /* Not a TIO, handle CRB errors */ | 43 | if (!(nasid & 1)) /* Not a TIO, handle CRB errors */ |
| 43 | (void)hubiio_crb_error_handler(hubdev_info); | 44 | (void)hubiio_crb_error_handler(hubdev_info); |
| 44 | } else | 45 | } else |
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 318087e35b66..233d55115d33 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c | |||
| @@ -76,11 +76,12 @@ static struct sn_pcibus_provider sn_pci_default_provider = { | |||
| 76 | }; | 76 | }; |
| 77 | 77 | ||
| 78 | /* | 78 | /* |
| 79 | * Retrieve the DMA Flush List given nasid. This list is needed | 79 | * Retrieve the DMA Flush List given nasid, widget, and device. |
| 80 | * to implement the WAR - Flush DMA data on PIO Reads. | 80 | * This list is needed to implement the WAR - Flush DMA data on PIO Reads. |
| 81 | */ | 81 | */ |
| 82 | static inline uint64_t | 82 | static inline u64 |
| 83 | sal_get_widget_dmaflush_list(u64 nasid, u64 widget_num, u64 address) | 83 | sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num, |
| 84 | u64 address) | ||
| 84 | { | 85 | { |
| 85 | 86 | ||
| 86 | struct ia64_sal_retval ret_stuff; | 87 | struct ia64_sal_retval ret_stuff; |
| @@ -88,17 +89,17 @@ sal_get_widget_dmaflush_list(u64 nasid, u64 widget_num, u64 address) | |||
| 88 | ret_stuff.v0 = 0; | 89 | ret_stuff.v0 = 0; |
| 89 | 90 | ||
| 90 | SAL_CALL_NOLOCK(ret_stuff, | 91 | SAL_CALL_NOLOCK(ret_stuff, |
| 91 | (u64) SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST, | 92 | (u64) SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST, |
| 92 | (u64) nasid, (u64) widget_num, (u64) address, 0, 0, 0, | 93 | (u64) nasid, (u64) widget_num, |
| 93 | 0); | 94 | (u64) device_num, (u64) address, 0, 0, 0); |
| 94 | return ret_stuff.v0; | 95 | return ret_stuff.status; |
| 95 | 96 | ||
| 96 | } | 97 | } |
| 97 | 98 | ||
| 98 | /* | 99 | /* |
| 99 | * Retrieve the hub device info structure for the given nasid. | 100 | * Retrieve the hub device info structure for the given nasid. |
| 100 | */ | 101 | */ |
| 101 | static inline uint64_t sal_get_hubdev_info(u64 handle, u64 address) | 102 | static inline u64 sal_get_hubdev_info(u64 handle, u64 address) |
| 102 | { | 103 | { |
| 103 | 104 | ||
| 104 | struct ia64_sal_retval ret_stuff; | 105 | struct ia64_sal_retval ret_stuff; |
| @@ -114,7 +115,7 @@ static inline uint64_t sal_get_hubdev_info(u64 handle, u64 address) | |||
| 114 | /* | 115 | /* |
| 115 | * Retrieve the pci bus information given the bus number. | 116 | * Retrieve the pci bus information given the bus number. |
| 116 | */ | 117 | */ |
| 117 | static inline uint64_t sal_get_pcibus_info(u64 segment, u64 busnum, u64 address) | 118 | static inline u64 sal_get_pcibus_info(u64 segment, u64 busnum, u64 address) |
| 118 | { | 119 | { |
| 119 | 120 | ||
| 120 | struct ia64_sal_retval ret_stuff; | 121 | struct ia64_sal_retval ret_stuff; |
| @@ -130,9 +131,9 @@ static inline uint64_t sal_get_pcibus_info(u64 segment, u64 busnum, u64 address) | |||
| 130 | /* | 131 | /* |
| 131 | * Retrieve the pci device information given the bus and device|function number. | 132 | * Retrieve the pci device information given the bus and device|function number. |
| 132 | */ | 133 | */ |
| 133 | static inline uint64_t | 134 | static inline u64 |
| 134 | sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev, | 135 | sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev, |
| 135 | u64 sn_irq_info) | 136 | u64 sn_irq_info) |
| 136 | { | 137 | { |
| 137 | struct ia64_sal_retval ret_stuff; | 138 | struct ia64_sal_retval ret_stuff; |
| 138 | ret_stuff.status = 0; | 139 | ret_stuff.status = 0; |
| @@ -140,7 +141,7 @@ sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev, | |||
| 140 | 141 | ||
| 141 | SAL_CALL_NOLOCK(ret_stuff, | 142 | SAL_CALL_NOLOCK(ret_stuff, |
| 142 | (u64) SN_SAL_IOIF_GET_PCIDEV_INFO, | 143 | (u64) SN_SAL_IOIF_GET_PCIDEV_INFO, |
| 143 | (u64) segment, (u64) bus_number, (u64) devfn, | 144 | (u64) segment, (u64) bus_number, (u64) devfn, |
| 144 | (u64) pci_dev, | 145 | (u64) pci_dev, |
| 145 | sn_irq_info, 0, 0); | 146 | sn_irq_info, 0, 0); |
| 146 | return ret_stuff.v0; | 147 | return ret_stuff.v0; |
| @@ -170,12 +171,12 @@ sn_pcidev_info_get(struct pci_dev *dev) | |||
| 170 | */ | 171 | */ |
| 171 | static void sn_fixup_ionodes(void) | 172 | static void sn_fixup_ionodes(void) |
| 172 | { | 173 | { |
| 173 | 174 | struct sn_flush_device_kernel *sn_flush_device_kernel; | |
| 174 | struct sn_flush_device_list *sn_flush_device_list; | 175 | struct sn_flush_device_kernel *dev_entry; |
| 175 | struct hubdev_info *hubdev; | 176 | struct hubdev_info *hubdev; |
| 176 | uint64_t status; | 177 | u64 status; |
| 177 | uint64_t nasid; | 178 | u64 nasid; |
| 178 | int i, widget; | 179 | int i, widget, device; |
| 179 | 180 | ||
| 180 | /* | 181 | /* |
| 181 | * Get SGI Specific HUB chipset information. | 182 | * Get SGI Specific HUB chipset information. |
| @@ -186,7 +187,7 @@ static void sn_fixup_ionodes(void) | |||
| 186 | nasid = cnodeid_to_nasid(i); | 187 | nasid = cnodeid_to_nasid(i); |
| 187 | hubdev->max_segment_number = 0xffffffff; | 188 | hubdev->max_segment_number = 0xffffffff; |
| 188 | hubdev->max_pcibus_number = 0xff; | 189 | hubdev->max_pcibus_number = 0xff; |
| 189 | status = sal_get_hubdev_info(nasid, (uint64_t) __pa(hubdev)); | 190 | status = sal_get_hubdev_info(nasid, (u64) __pa(hubdev)); |
| 190 | if (status) | 191 | if (status) |
| 191 | continue; | 192 | continue; |
| 192 | 193 | ||
| @@ -213,38 +214,49 @@ static void sn_fixup_ionodes(void) | |||
| 213 | 214 | ||
| 214 | hubdev->hdi_flush_nasid_list.widget_p = | 215 | hubdev->hdi_flush_nasid_list.widget_p = |
| 215 | kmalloc((HUB_WIDGET_ID_MAX + 1) * | 216 | kmalloc((HUB_WIDGET_ID_MAX + 1) * |
| 216 | sizeof(struct sn_flush_device_list *), GFP_KERNEL); | 217 | sizeof(struct sn_flush_device_kernel *), |
| 217 | 218 | GFP_KERNEL); | |
| 218 | memset(hubdev->hdi_flush_nasid_list.widget_p, 0x0, | 219 | memset(hubdev->hdi_flush_nasid_list.widget_p, 0x0, |
| 219 | (HUB_WIDGET_ID_MAX + 1) * | 220 | (HUB_WIDGET_ID_MAX + 1) * |
| 220 | sizeof(struct sn_flush_device_list *)); | 221 | sizeof(struct sn_flush_device_kernel *)); |
| 221 | 222 | ||
| 222 | for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) { | 223 | for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) { |
| 223 | sn_flush_device_list = kmalloc(DEV_PER_WIDGET * | 224 | sn_flush_device_kernel = kmalloc(DEV_PER_WIDGET * |
| 224 | sizeof(struct | 225 | sizeof(struct |
| 225 | sn_flush_device_list), | 226 | sn_flush_device_kernel), |
| 226 | GFP_KERNEL); | 227 | GFP_KERNEL); |
| 227 | memset(sn_flush_device_list, 0x0, | 228 | if (!sn_flush_device_kernel) |
| 229 | BUG(); | ||
| 230 | memset(sn_flush_device_kernel, 0x0, | ||
| 228 | DEV_PER_WIDGET * | 231 | DEV_PER_WIDGET * |
| 229 | sizeof(struct sn_flush_device_list)); | 232 | sizeof(struct sn_flush_device_kernel)); |
| 230 | 233 | ||
| 231 | status = | 234 | dev_entry = sn_flush_device_kernel; |
| 232 | sal_get_widget_dmaflush_list(nasid, widget, | 235 | for (device = 0; device < DEV_PER_WIDGET; |
| 233 | (uint64_t) | 236 | device++,dev_entry++) { |
| 234 | __pa | 237 | dev_entry->common = kmalloc(sizeof(struct |
| 235 | (sn_flush_device_list)); | 238 | sn_flush_device_common), |
| 236 | if (status) { | 239 | GFP_KERNEL); |
| 237 | kfree(sn_flush_device_list); | 240 | if (!dev_entry->common) |
| 238 | continue; | 241 | BUG(); |
| 242 | memset(dev_entry->common, 0x0, sizeof(struct | ||
| 243 | sn_flush_device_common)); | ||
| 244 | |||
| 245 | status = sal_get_device_dmaflush_list(nasid, | ||
| 246 | widget, | ||
| 247 | device, | ||
| 248 | (u64)(dev_entry->common)); | ||
| 249 | if (status) | ||
| 250 | BUG(); | ||
| 251 | |||
| 252 | spin_lock_init(&dev_entry->sfdl_flush_lock); | ||
| 239 | } | 253 | } |
| 240 | 254 | ||
| 241 | spin_lock_init(&sn_flush_device_list->sfdl_flush_lock); | 255 | if (sn_flush_device_kernel) |
| 242 | hubdev->hdi_flush_nasid_list.widget_p[widget] = | 256 | hubdev->hdi_flush_nasid_list.widget_p[widget] = |
| 243 | sn_flush_device_list; | 257 | sn_flush_device_kernel; |
| 244 | } | 258 | } |
| 245 | |||
| 246 | } | 259 | } |
| 247 | |||
| 248 | } | 260 | } |
| 249 | 261 | ||
| 250 | /* | 262 | /* |
| @@ -256,7 +268,7 @@ static void sn_fixup_ionodes(void) | |||
| 256 | */ | 268 | */ |
| 257 | static void | 269 | static void |
| 258 | sn_pci_window_fixup(struct pci_dev *dev, unsigned int count, | 270 | sn_pci_window_fixup(struct pci_dev *dev, unsigned int count, |
| 259 | int64_t * pci_addrs) | 271 | s64 * pci_addrs) |
| 260 | { | 272 | { |
| 261 | struct pci_controller *controller = PCI_CONTROLLER(dev->bus); | 273 | struct pci_controller *controller = PCI_CONTROLLER(dev->bus); |
| 262 | unsigned int i; | 274 | unsigned int i; |
| @@ -316,7 +328,7 @@ void sn_pci_fixup_slot(struct pci_dev *dev) | |||
| 316 | struct pci_bus *host_pci_bus; | 328 | struct pci_bus *host_pci_bus; |
| 317 | struct pci_dev *host_pci_dev; | 329 | struct pci_dev *host_pci_dev; |
| 318 | struct pcidev_info *pcidev_info; | 330 | struct pcidev_info *pcidev_info; |
| 319 | int64_t pci_addrs[PCI_ROM_RESOURCE + 1]; | 331 | s64 pci_addrs[PCI_ROM_RESOURCE + 1]; |
| 320 | struct sn_irq_info *sn_irq_info; | 332 | struct sn_irq_info *sn_irq_info; |
| 321 | unsigned long size; | 333 | unsigned long size; |
| 322 | unsigned int bus_no, devfn; | 334 | unsigned int bus_no, devfn; |
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index 01d18b7b5bb3..ec37084bdc17 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c | |||
| @@ -28,7 +28,7 @@ extern int sn_ioif_inited; | |||
| 28 | static struct list_head **sn_irq_lh; | 28 | static struct list_head **sn_irq_lh; |
| 29 | static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */ | 29 | static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */ |
| 30 | 30 | ||
| 31 | static inline uint64_t sn_intr_alloc(nasid_t local_nasid, int local_widget, | 31 | static inline u64 sn_intr_alloc(nasid_t local_nasid, int local_widget, |
| 32 | u64 sn_irq_info, | 32 | u64 sn_irq_info, |
| 33 | int req_irq, nasid_t req_nasid, | 33 | int req_irq, nasid_t req_nasid, |
| 34 | int req_slice) | 34 | int req_slice) |
| @@ -123,7 +123,7 @@ static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) | |||
| 123 | 123 | ||
| 124 | list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe, | 124 | list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe, |
| 125 | sn_irq_lh[irq], list) { | 125 | sn_irq_lh[irq], list) { |
| 126 | uint64_t bridge; | 126 | u64 bridge; |
| 127 | int local_widget, status; | 127 | int local_widget, status; |
| 128 | nasid_t local_nasid; | 128 | nasid_t local_nasid; |
| 129 | struct sn_irq_info *new_irq_info; | 129 | struct sn_irq_info *new_irq_info; |
| @@ -134,7 +134,7 @@ static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) | |||
| 134 | break; | 134 | break; |
| 135 | memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info)); | 135 | memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info)); |
| 136 | 136 | ||
| 137 | bridge = (uint64_t) new_irq_info->irq_bridge; | 137 | bridge = (u64) new_irq_info->irq_bridge; |
| 138 | if (!bridge) { | 138 | if (!bridge) { |
| 139 | kfree(new_irq_info); | 139 | kfree(new_irq_info); |
| 140 | break; /* irq is not a device interrupt */ | 140 | break; /* irq is not a device interrupt */ |
| @@ -349,10 +349,10 @@ static void force_interrupt(int irq) | |||
| 349 | */ | 349 | */ |
| 350 | static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info) | 350 | static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info) |
| 351 | { | 351 | { |
| 352 | uint64_t regval; | 352 | u64 regval; |
| 353 | int irr_reg_num; | 353 | int irr_reg_num; |
| 354 | int irr_bit; | 354 | int irr_bit; |
| 355 | uint64_t irr_reg; | 355 | u64 irr_reg; |
| 356 | struct pcidev_info *pcidev_info; | 356 | struct pcidev_info *pcidev_info; |
| 357 | struct pcibus_info *pcibus_info; | 357 | struct pcibus_info *pcibus_info; |
| 358 | 358 | ||
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index 493fb3f38dc3..d263d3e8fbb9 100644 --- a/arch/ia64/sn/kernel/tiocx.c +++ b/arch/ia64/sn/kernel/tiocx.c | |||
| @@ -77,12 +77,6 @@ static void tiocx_bus_release(struct device *dev) | |||
| 77 | kfree(to_cx_dev(dev)); | 77 | kfree(to_cx_dev(dev)); |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | struct bus_type tiocx_bus_type = { | ||
| 81 | .name = "tiocx", | ||
| 82 | .match = tiocx_match, | ||
| 83 | .uevent = tiocx_uevent, | ||
| 84 | }; | ||
| 85 | |||
| 86 | /** | 80 | /** |
| 87 | * cx_device_match - Find cx_device in the id table. | 81 | * cx_device_match - Find cx_device in the id table. |
| 88 | * @ids: id table from driver | 82 | * @ids: id table from driver |
| @@ -149,6 +143,14 @@ static int cx_driver_remove(struct device *dev) | |||
| 149 | return 0; | 143 | return 0; |
| 150 | } | 144 | } |
| 151 | 145 | ||
| 146 | struct bus_type tiocx_bus_type = { | ||
| 147 | .name = "tiocx", | ||
| 148 | .match = tiocx_match, | ||
| 149 | .uevent = tiocx_uevent, | ||
| 150 | .probe = cx_device_probe, | ||
| 151 | .remove = cx_driver_remove, | ||
| 152 | }; | ||
| 153 | |||
| 152 | /** | 154 | /** |
| 153 | * cx_driver_register - Register the driver. | 155 | * cx_driver_register - Register the driver. |
| 154 | * @cx_driver: driver table (cx_drv struct) from driver | 156 | * @cx_driver: driver table (cx_drv struct) from driver |
| @@ -162,8 +164,6 @@ int cx_driver_register(struct cx_drv *cx_driver) | |||
| 162 | { | 164 | { |
| 163 | cx_driver->driver.name = cx_driver->name; | 165 | cx_driver->driver.name = cx_driver->name; |
| 164 | cx_driver->driver.bus = &tiocx_bus_type; | 166 | cx_driver->driver.bus = &tiocx_bus_type; |
| 165 | cx_driver->driver.probe = cx_device_probe; | ||
| 166 | cx_driver->driver.remove = cx_driver_remove; | ||
| 167 | 167 | ||
| 168 | return driver_register(&cx_driver->driver); | 168 | return driver_register(&cx_driver->driver); |
| 169 | } | 169 | } |
| @@ -245,7 +245,7 @@ static int cx_device_reload(struct cx_dev *cx_dev) | |||
| 245 | cx_dev->bt); | 245 | cx_dev->bt); |
| 246 | } | 246 | } |
| 247 | 247 | ||
| 248 | static inline uint64_t tiocx_intr_alloc(nasid_t nasid, int widget, | 248 | static inline u64 tiocx_intr_alloc(nasid_t nasid, int widget, |
| 249 | u64 sn_irq_info, | 249 | u64 sn_irq_info, |
| 250 | int req_irq, nasid_t req_nasid, | 250 | int req_irq, nasid_t req_nasid, |
| 251 | int req_slice) | 251 | int req_slice) |
| @@ -302,7 +302,7 @@ struct sn_irq_info *tiocx_irq_alloc(nasid_t nasid, int widget, int irq, | |||
| 302 | 302 | ||
| 303 | void tiocx_irq_free(struct sn_irq_info *sn_irq_info) | 303 | void tiocx_irq_free(struct sn_irq_info *sn_irq_info) |
| 304 | { | 304 | { |
| 305 | uint64_t bridge = (uint64_t) sn_irq_info->irq_bridge; | 305 | u64 bridge = (u64) sn_irq_info->irq_bridge; |
| 306 | nasid_t nasid = NASID_GET(bridge); | 306 | nasid_t nasid = NASID_GET(bridge); |
| 307 | int widget; | 307 | int widget; |
| 308 | 308 | ||
| @@ -313,12 +313,12 @@ void tiocx_irq_free(struct sn_irq_info *sn_irq_info) | |||
| 313 | } | 313 | } |
| 314 | } | 314 | } |
| 315 | 315 | ||
| 316 | uint64_t tiocx_dma_addr(uint64_t addr) | 316 | u64 tiocx_dma_addr(u64 addr) |
| 317 | { | 317 | { |
| 318 | return PHYS_TO_TIODMA(addr); | 318 | return PHYS_TO_TIODMA(addr); |
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | uint64_t tiocx_swin_base(int nasid) | 321 | u64 tiocx_swin_base(int nasid) |
| 322 | { | 322 | { |
| 323 | return TIO_SWIN_BASE(nasid, TIOCX_CORELET); | 323 | return TIO_SWIN_BASE(nasid, TIOCX_CORELET); |
| 324 | } | 324 | } |
| @@ -335,8 +335,8 @@ EXPORT_SYMBOL(tiocx_swin_base); | |||
| 335 | 335 | ||
| 336 | static void tio_conveyor_set(nasid_t nasid, int enable_flag) | 336 | static void tio_conveyor_set(nasid_t nasid, int enable_flag) |
| 337 | { | 337 | { |
| 338 | uint64_t ice_frz; | 338 | u64 ice_frz; |
| 339 | uint64_t disable_cb = (1ull << 61); | 339 | u64 disable_cb = (1ull << 61); |
| 340 | 340 | ||
| 341 | if (!(nasid & 1)) | 341 | if (!(nasid & 1)) |
| 342 | return; | 342 | return; |
| @@ -388,7 +388,7 @@ static int is_fpga_tio(int nasid, int *bt) | |||
| 388 | 388 | ||
| 389 | static int bitstream_loaded(nasid_t nasid) | 389 | static int bitstream_loaded(nasid_t nasid) |
| 390 | { | 390 | { |
| 391 | uint64_t cx_credits; | 391 | u64 cx_credits; |
| 392 | 392 | ||
| 393 | cx_credits = REMOTE_HUB_L(nasid, TIO_ICE_PMI_TX_DYN_CREDIT_STAT_CB3); | 393 | cx_credits = REMOTE_HUB_L(nasid, TIO_ICE_PMI_TX_DYN_CREDIT_STAT_CB3); |
| 394 | cx_credits &= TIO_ICE_PMI_TX_DYN_CREDIT_STAT_CB3_CREDIT_CNT_MASK; | 394 | cx_credits &= TIO_ICE_PMI_TX_DYN_CREDIT_STAT_CB3_CREDIT_CNT_MASK; |
| @@ -404,14 +404,14 @@ static int tiocx_reload(struct cx_dev *cx_dev) | |||
| 404 | nasid_t nasid = cx_dev->cx_id.nasid; | 404 | nasid_t nasid = cx_dev->cx_id.nasid; |
| 405 | 405 | ||
| 406 | if (bitstream_loaded(nasid)) { | 406 | if (bitstream_loaded(nasid)) { |
| 407 | uint64_t cx_id; | 407 | u64 cx_id; |
| 408 | int rv; | 408 | int rv; |
| 409 | 409 | ||
| 410 | rv = ia64_sn_sysctl_tio_clock_reset(nasid); | 410 | rv = ia64_sn_sysctl_tio_clock_reset(nasid); |
| 411 | if (rv) { | 411 | if (rv) { |
| 412 | printk(KERN_ALERT "CX port JTAG reset failed.\n"); | 412 | printk(KERN_ALERT "CX port JTAG reset failed.\n"); |
| 413 | } else { | 413 | } else { |
| 414 | cx_id = *(volatile uint64_t *) | 414 | cx_id = *(volatile u64 *) |
| 415 | (TIO_SWIN_BASE(nasid, TIOCX_CORELET) + | 415 | (TIO_SWIN_BASE(nasid, TIOCX_CORELET) + |
| 416 | WIDGET_ID); | 416 | WIDGET_ID); |
| 417 | part_num = XWIDGET_PART_NUM(cx_id); | 417 | part_num = XWIDGET_PART_NUM(cx_id); |
diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h deleted file mode 100644 index 5483a9f227d4..000000000000 --- a/arch/ia64/sn/kernel/xpc.h +++ /dev/null | |||
| @@ -1,1273 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 3 | * License. See the file "COPYING" in the main directory of this archive | ||
| 4 | * for more details. | ||
| 5 | * | ||
| 6 | * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. | ||
| 7 | */ | ||
| 8 | |||
| 9 | |||
| 10 | /* | ||
| 11 | * Cross Partition Communication (XPC) structures and macros. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #ifndef _IA64_SN_KERNEL_XPC_H | ||
| 15 | #define _IA64_SN_KERNEL_XPC_H | ||
| 16 | |||
| 17 | |||
| 18 | #include <linux/config.h> | ||
| 19 | #include <linux/interrupt.h> | ||
| 20 | #include <linux/sysctl.h> | ||
| 21 | #include <linux/device.h> | ||
| 22 | #include <asm/pgtable.h> | ||
| 23 | #include <asm/processor.h> | ||
| 24 | #include <asm/sn/bte.h> | ||
| 25 | #include <asm/sn/clksupport.h> | ||
| 26 | #include <asm/sn/addrs.h> | ||
| 27 | #include <asm/sn/mspec.h> | ||
| 28 | #include <asm/sn/shub_mmr.h> | ||
| 29 | #include <asm/sn/xp.h> | ||
| 30 | |||
| 31 | |||
| 32 | /* | ||
| 33 | * XPC Version numbers consist of a major and minor number. XPC can always | ||
| 34 | * talk to versions with same major #, and never talk to versions with a | ||
| 35 | * different major #. | ||
| 36 | */ | ||
| 37 | #define _XPC_VERSION(_maj, _min) (((_maj) << 4) | ((_min) & 0xf)) | ||
| 38 | #define XPC_VERSION_MAJOR(_v) ((_v) >> 4) | ||
| 39 | #define XPC_VERSION_MINOR(_v) ((_v) & 0xf) | ||
| 40 | |||
| 41 | |||
| 42 | /* | ||
| 43 | * The next macros define word or bit representations for given | ||
| 44 | * C-brick nasid in either the SAL provided bit array representing | ||
| 45 | * nasids in the partition/machine or the AMO_t array used for | ||
| 46 | * inter-partition initiation communications. | ||
| 47 | * | ||
| 48 | * For SN2 machines, C-Bricks are alway even numbered NASIDs. As | ||
| 49 | * such, some space will be saved by insisting that nasid information | ||
| 50 | * passed from SAL always be packed for C-Bricks and the | ||
| 51 | * cross-partition interrupts use the same packing scheme. | ||
| 52 | */ | ||
| 53 | #define XPC_NASID_W_INDEX(_n) (((_n) / 64) / 2) | ||
| 54 | #define XPC_NASID_B_INDEX(_n) (((_n) / 2) & (64 - 1)) | ||
| 55 | #define XPC_NASID_IN_ARRAY(_n, _p) ((_p)[XPC_NASID_W_INDEX(_n)] & \ | ||
| 56 | (1UL << XPC_NASID_B_INDEX(_n))) | ||
| 57 | #define XPC_NASID_FROM_W_B(_w, _b) (((_w) * 64 + (_b)) * 2) | ||
| 58 | |||
| 59 | #define XPC_HB_DEFAULT_INTERVAL 5 /* incr HB every x secs */ | ||
| 60 | #define XPC_HB_CHECK_DEFAULT_INTERVAL 20 /* check HB every x secs */ | ||
| 61 | |||
| 62 | /* define the process name of HB checker and the CPU it is pinned to */ | ||
| 63 | #define XPC_HB_CHECK_THREAD_NAME "xpc_hb" | ||
| 64 | #define XPC_HB_CHECK_CPU 0 | ||
| 65 | |||
| 66 | /* define the process name of the discovery thread */ | ||
| 67 | #define XPC_DISCOVERY_THREAD_NAME "xpc_discovery" | ||
| 68 | |||
| 69 | |||
| 70 | /* | ||
| 71 | * the reserved page | ||
| 72 | * | ||
| 73 | * SAL reserves one page of memory per partition for XPC. Though a full page | ||
| 74 | * in length (16384 bytes), its starting address is not page aligned, but it | ||
| 75 | * is cacheline aligned. The reserved page consists of the following: | ||
| 76 | * | ||
| 77 | * reserved page header | ||
| 78 | * | ||
| 79 | * The first cacheline of the reserved page contains the header | ||
| 80 | * (struct xpc_rsvd_page). Before SAL initialization has completed, | ||
| 81 | * SAL has set up the following fields of the reserved page header: | ||
| 82 | * SAL_signature, SAL_version, partid, and nasids_size. The other | ||
| 83 | * fields are set up by XPC. (xpc_rsvd_page points to the local | ||
| 84 | * partition's reserved page.) | ||
| 85 | * | ||
| 86 | * part_nasids mask | ||
| 87 | * mach_nasids mask | ||
| 88 | * | ||
| 89 | * SAL also sets up two bitmaps (or masks), one that reflects the actual | ||
| 90 | * nasids in this partition (part_nasids), and the other that reflects | ||
| 91 | * the actual nasids in the entire machine (mach_nasids). We're only | ||
| 92 | * interested in the even numbered nasids (which contain the processors | ||
| 93 | * and/or memory), so we only need half as many bits to represent the | ||
| 94 | * nasids. The part_nasids mask is located starting at the first cacheline | ||
| 95 | * following the reserved page header. The mach_nasids mask follows right | ||
| 96 | * after the part_nasids mask. The size in bytes of each mask is reflected | ||
| 97 | * by the reserved page header field 'nasids_size'. (Local partition's | ||
| 98 | * mask pointers are xpc_part_nasids and xpc_mach_nasids.) | ||
| 99 | * | ||
| 100 | * vars | ||
| 101 | * vars part | ||
| 102 | * | ||
| 103 | * Immediately following the mach_nasids mask are the XPC variables | ||
| 104 | * required by other partitions. First are those that are generic to all | ||
| 105 | * partitions (vars), followed on the next available cacheline by those | ||
| 106 | * which are partition specific (vars part). These are setup by XPC. | ||
| 107 | * (Local partition's vars pointers are xpc_vars and xpc_vars_part.) | ||
| 108 | * | ||
| 109 | * Note: Until vars_pa is set, the partition XPC code has not been initialized. | ||
| 110 | */ | ||
| 111 | struct xpc_rsvd_page { | ||
| 112 | u64 SAL_signature; /* SAL: unique signature */ | ||
| 113 | u64 SAL_version; /* SAL: version */ | ||
| 114 | u8 partid; /* SAL: partition ID */ | ||
| 115 | u8 version; | ||
| 116 | u8 pad1[6]; /* align to next u64 in cacheline */ | ||
| 117 | volatile u64 vars_pa; | ||
| 118 | struct timespec stamp; /* time when reserved page was setup by XPC */ | ||
| 119 | u64 pad2[9]; /* align to last u64 in cacheline */ | ||
| 120 | u64 nasids_size; /* SAL: size of each nasid mask in bytes */ | ||
| 121 | }; | ||
| 122 | |||
| 123 | #define XPC_RP_VERSION _XPC_VERSION(1,1) /* version 1.1 of the reserved page */ | ||
| 124 | |||
| 125 | #define XPC_SUPPORTS_RP_STAMP(_version) \ | ||
| 126 | (_version >= _XPC_VERSION(1,1)) | ||
| 127 | |||
| 128 | /* | ||
| 129 | * compare stamps - the return value is: | ||
| 130 | * | ||
| 131 | * < 0, if stamp1 < stamp2 | ||
| 132 | * = 0, if stamp1 == stamp2 | ||
| 133 | * > 0, if stamp1 > stamp2 | ||
| 134 | */ | ||
| 135 | static inline int | ||
| 136 | xpc_compare_stamps(struct timespec *stamp1, struct timespec *stamp2) | ||
| 137 | { | ||
| 138 | int ret; | ||
| 139 | |||
| 140 | |||
| 141 | if ((ret = stamp1->tv_sec - stamp2->tv_sec) == 0) { | ||
| 142 | ret = stamp1->tv_nsec - stamp2->tv_nsec; | ||
| 143 | } | ||
| 144 | return ret; | ||
| 145 | } | ||
| 146 | |||
| 147 | |||
| 148 | /* | ||
| 149 | * Define the structures by which XPC variables can be exported to other | ||
| 150 | * partitions. (There are two: struct xpc_vars and struct xpc_vars_part) | ||
| 151 | */ | ||
| 152 | |||
| 153 | /* | ||
| 154 | * The following structure describes the partition generic variables | ||
| 155 | * needed by other partitions in order to properly initialize. | ||
| 156 | * | ||
| 157 | * struct xpc_vars version number also applies to struct xpc_vars_part. | ||
| 158 | * Changes to either structure and/or related functionality should be | ||
| 159 | * reflected by incrementing either the major or minor version numbers | ||
| 160 | * of struct xpc_vars. | ||
| 161 | */ | ||
| 162 | struct xpc_vars { | ||
| 163 | u8 version; | ||
| 164 | u64 heartbeat; | ||
| 165 | u64 heartbeating_to_mask; | ||
| 166 | u64 heartbeat_offline; /* if 0, heartbeat should be changing */ | ||
| 167 | int act_nasid; | ||
| 168 | int act_phys_cpuid; | ||
| 169 | u64 vars_part_pa; | ||
| 170 | u64 amos_page_pa; /* paddr of page of AMOs from MSPEC driver */ | ||
| 171 | AMO_t *amos_page; /* vaddr of page of AMOs from MSPEC driver */ | ||
| 172 | }; | ||
| 173 | |||
| 174 | #define XPC_V_VERSION _XPC_VERSION(3,1) /* version 3.1 of the cross vars */ | ||
| 175 | |||
| 176 | #define XPC_SUPPORTS_DISENGAGE_REQUEST(_version) \ | ||
| 177 | (_version >= _XPC_VERSION(3,1)) | ||
| 178 | |||
| 179 | |||
| 180 | static inline int | ||
| 181 | xpc_hb_allowed(partid_t partid, struct xpc_vars *vars) | ||
| 182 | { | ||
| 183 | return ((vars->heartbeating_to_mask & (1UL << partid)) != 0); | ||
| 184 | } | ||
| 185 | |||
| 186 | static inline void | ||
| 187 | xpc_allow_hb(partid_t partid, struct xpc_vars *vars) | ||
| 188 | { | ||
| 189 | u64 old_mask, new_mask; | ||
| 190 | |||
| 191 | do { | ||
| 192 | old_mask = vars->heartbeating_to_mask; | ||
| 193 | new_mask = (old_mask | (1UL << partid)); | ||
| 194 | } while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) != | ||
| 195 | old_mask); | ||
| 196 | } | ||
| 197 | |||
| 198 | static inline void | ||
| 199 | xpc_disallow_hb(partid_t partid, struct xpc_vars *vars) | ||
| 200 | { | ||
| 201 | u64 old_mask, new_mask; | ||
| 202 | |||
| 203 | do { | ||
| 204 | old_mask = vars->heartbeating_to_mask; | ||
| 205 | new_mask = (old_mask & ~(1UL << partid)); | ||
| 206 | } while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) != | ||
| 207 | old_mask); | ||
| 208 | } | ||
| 209 | |||
| 210 | |||
| 211 | /* | ||
| 212 | * The AMOs page consists of a number of AMO variables which are divided into | ||
| 213 | * four groups, The first two groups are used to identify an IRQ's sender. | ||
| 214 | * These two groups consist of 64 and 128 AMO variables respectively. The last | ||
| 215 | * two groups, consisting of just one AMO variable each, are used to identify | ||
| 216 | * the remote partitions that are currently engaged (from the viewpoint of | ||
| 217 | * the XPC running on the remote partition). | ||
| 218 | */ | ||
| 219 | #define XPC_NOTIFY_IRQ_AMOS 0 | ||
| 220 | #define XPC_ACTIVATE_IRQ_AMOS (XPC_NOTIFY_IRQ_AMOS + XP_MAX_PARTITIONS) | ||
| 221 | #define XPC_ENGAGED_PARTITIONS_AMO (XPC_ACTIVATE_IRQ_AMOS + XP_NASID_MASK_WORDS) | ||
| 222 | #define XPC_DISENGAGE_REQUEST_AMO (XPC_ENGAGED_PARTITIONS_AMO + 1) | ||
| 223 | |||
| 224 | |||
| 225 | /* | ||
| 226 | * The following structure describes the per partition specific variables. | ||
| 227 | * | ||
| 228 | * An array of these structures, one per partition, will be defined. As a | ||
| 229 | * partition becomes active XPC will copy the array entry corresponding to | ||
| 230 | * itself from that partition. It is desirable that the size of this | ||
| 231 | * structure evenly divide into a cacheline, such that none of the entries | ||
| 232 | * in this array crosses a cacheline boundary. As it is now, each entry | ||
| 233 | * occupies half a cacheline. | ||
| 234 | */ | ||
| 235 | struct xpc_vars_part { | ||
| 236 | volatile u64 magic; | ||
| 237 | |||
| 238 | u64 openclose_args_pa; /* physical address of open and close args */ | ||
| 239 | u64 GPs_pa; /* physical address of Get/Put values */ | ||
| 240 | |||
| 241 | u64 IPI_amo_pa; /* physical address of IPI AMO_t structure */ | ||
| 242 | int IPI_nasid; /* nasid of where to send IPIs */ | ||
| 243 | int IPI_phys_cpuid; /* physical CPU ID of where to send IPIs */ | ||
| 244 | |||
| 245 | u8 nchannels; /* #of defined channels supported */ | ||
| 246 | |||
| 247 | u8 reserved[23]; /* pad to a full 64 bytes */ | ||
| 248 | }; | ||
| 249 | |||
| 250 | /* | ||
| 251 | * The vars_part MAGIC numbers play a part in the first contact protocol. | ||
| 252 | * | ||
| 253 | * MAGIC1 indicates that the per partition specific variables for a remote | ||
| 254 | * partition have been initialized by this partition. | ||
| 255 | * | ||
| 256 | * MAGIC2 indicates that this partition has pulled the remote partititions | ||
| 257 | * per partition variables that pertain to this partition. | ||
| 258 | */ | ||
| 259 | #define XPC_VP_MAGIC1 0x0053524156435058L /* 'XPCVARS\0'L (little endian) */ | ||
| 260 | #define XPC_VP_MAGIC2 0x0073726176435058L /* 'XPCvars\0'L (little endian) */ | ||
| 261 | |||
| 262 | |||
| 263 | /* the reserved page sizes and offsets */ | ||
| 264 | |||
| 265 | #define XPC_RP_HEADER_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page)) | ||
| 266 | #define XPC_RP_VARS_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_vars)) | ||
| 267 | |||
| 268 | #define XPC_RP_PART_NASIDS(_rp) (u64 *) ((u8 *) _rp + XPC_RP_HEADER_SIZE) | ||
| 269 | #define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + xp_nasid_mask_words) | ||
| 270 | #define XPC_RP_VARS(_rp) ((struct xpc_vars *) XPC_RP_MACH_NASIDS(_rp) + xp_nasid_mask_words) | ||
| 271 | #define XPC_RP_VARS_PART(_rp) (struct xpc_vars_part *) ((u8 *) XPC_RP_VARS(rp) + XPC_RP_VARS_SIZE) | ||
| 272 | |||
| 273 | |||
| 274 | /* | ||
| 275 | * Functions registered by add_timer() or called by kernel_thread() only | ||
| 276 | * allow for a single 64-bit argument. The following macros can be used to | ||
| 277 | * pack and unpack two (32-bit, 16-bit or 8-bit) arguments into or out from | ||
| 278 | * the passed argument. | ||
| 279 | */ | ||
| 280 | #define XPC_PACK_ARGS(_arg1, _arg2) \ | ||
| 281 | ((((u64) _arg1) & 0xffffffff) | \ | ||
| 282 | ((((u64) _arg2) & 0xffffffff) << 32)) | ||
| 283 | |||
| 284 | #define XPC_UNPACK_ARG1(_args) (((u64) _args) & 0xffffffff) | ||
| 285 | #define XPC_UNPACK_ARG2(_args) ((((u64) _args) >> 32) & 0xffffffff) | ||
| 286 | |||
| 287 | |||
| 288 | |||
| 289 | /* | ||
| 290 | * Define a Get/Put value pair (pointers) used with a message queue. | ||
| 291 | */ | ||
| 292 | struct xpc_gp { | ||
| 293 | volatile s64 get; /* Get value */ | ||
| 294 | volatile s64 put; /* Put value */ | ||
| 295 | }; | ||
| 296 | |||
| 297 | #define XPC_GP_SIZE \ | ||
| 298 | L1_CACHE_ALIGN(sizeof(struct xpc_gp) * XPC_NCHANNELS) | ||
| 299 | |||
| 300 | |||
| 301 | |||
| 302 | /* | ||
| 303 | * Define a structure that contains arguments associated with opening and | ||
| 304 | * closing a channel. | ||
| 305 | */ | ||
| 306 | struct xpc_openclose_args { | ||
| 307 | u16 reason; /* reason why channel is closing */ | ||
| 308 | u16 msg_size; /* sizeof each message entry */ | ||
| 309 | u16 remote_nentries; /* #of message entries in remote msg queue */ | ||
| 310 | u16 local_nentries; /* #of message entries in local msg queue */ | ||
| 311 | u64 local_msgqueue_pa; /* physical address of local message queue */ | ||
| 312 | }; | ||
| 313 | |||
| 314 | #define XPC_OPENCLOSE_ARGS_SIZE \ | ||
| 315 | L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * XPC_NCHANNELS) | ||
| 316 | |||
| 317 | |||
| 318 | |||
| 319 | /* struct xpc_msg flags */ | ||
| 320 | |||
| 321 | #define XPC_M_DONE 0x01 /* msg has been received/consumed */ | ||
| 322 | #define XPC_M_READY 0x02 /* msg is ready to be sent */ | ||
| 323 | #define XPC_M_INTERRUPT 0x04 /* send interrupt when msg consumed */ | ||
| 324 | |||
| 325 | |||
| 326 | #define XPC_MSG_ADDRESS(_payload) \ | ||
| 327 | ((struct xpc_msg *)((u8 *)(_payload) - XPC_MSG_PAYLOAD_OFFSET)) | ||
| 328 | |||
| 329 | |||
| 330 | |||
| 331 | /* | ||
| 332 | * Defines notify entry. | ||
| 333 | * | ||
| 334 | * This is used to notify a message's sender that their message was received | ||
| 335 | * and consumed by the intended recipient. | ||
| 336 | */ | ||
| 337 | struct xpc_notify { | ||
| 338 | struct semaphore sema; /* notify semaphore */ | ||
| 339 | volatile u8 type; /* type of notification */ | ||
| 340 | |||
| 341 | /* the following two fields are only used if type == XPC_N_CALL */ | ||
| 342 | xpc_notify_func func; /* user's notify function */ | ||
| 343 | void *key; /* pointer to user's key */ | ||
| 344 | }; | ||
| 345 | |||
| 346 | /* struct xpc_notify type of notification */ | ||
| 347 | |||
| 348 | #define XPC_N_CALL 0x01 /* notify function provided by user */ | ||
| 349 | |||
| 350 | |||
| 351 | |||
| 352 | /* | ||
| 353 | * Define the structure that manages all the stuff required by a channel. In | ||
| 354 | * particular, they are used to manage the messages sent across the channel. | ||
| 355 | * | ||
| 356 | * This structure is private to a partition, and is NOT shared across the | ||
| 357 | * partition boundary. | ||
| 358 | * | ||
| 359 | * There is an array of these structures for each remote partition. It is | ||
| 360 | * allocated at the time a partition becomes active. The array contains one | ||
| 361 | * of these structures for each potential channel connection to that partition. | ||
| 362 | * | ||
| 363 | * Each of these structures manages two message queues (circular buffers). | ||
| 364 | * They are allocated at the time a channel connection is made. One of | ||
| 365 | * these message queues (local_msgqueue) holds the locally created messages | ||
| 366 | * that are destined for the remote partition. The other of these message | ||
| 367 | * queues (remote_msgqueue) is a locally cached copy of the remote partition's | ||
| 368 | * own local_msgqueue. | ||
| 369 | * | ||
| 370 | * The following is a description of the Get/Put pointers used to manage these | ||
| 371 | * two message queues. Consider the local_msgqueue to be on one partition | ||
| 372 | * and the remote_msgqueue to be its cached copy on another partition. A | ||
| 373 | * description of what each of the lettered areas contains is included. | ||
| 374 | * | ||
| 375 | * | ||
| 376 | * local_msgqueue remote_msgqueue | ||
| 377 | * | ||
| 378 | * |/////////| |/////////| | ||
| 379 | * w_remote_GP.get --> +---------+ |/////////| | ||
| 380 | * | F | |/////////| | ||
| 381 | * remote_GP.get --> +---------+ +---------+ <-- local_GP->get | ||
| 382 | * | | | | | ||
| 383 | * | | | E | | ||
| 384 | * | | | | | ||
| 385 | * | | +---------+ <-- w_local_GP.get | ||
| 386 | * | B | |/////////| | ||
| 387 | * | | |////D////| | ||
| 388 | * | | |/////////| | ||
| 389 | * | | +---------+ <-- w_remote_GP.put | ||
| 390 | * | | |////C////| | ||
| 391 | * local_GP->put --> +---------+ +---------+ <-- remote_GP.put | ||
| 392 | * | | |/////////| | ||
| 393 | * | A | |/////////| | ||
| 394 | * | | |/////////| | ||
| 395 | * w_local_GP.put --> +---------+ |/////////| | ||
| 396 | * |/////////| |/////////| | ||
| 397 | * | ||
| 398 | * | ||
| 399 | * ( remote_GP.[get|put] are cached copies of the remote | ||
| 400 | * partition's local_GP->[get|put], and thus their values can | ||
| 401 | * lag behind their counterparts on the remote partition. ) | ||
| 402 | * | ||
| 403 | * | ||
| 404 | * A - Messages that have been allocated, but have not yet been sent to the | ||
| 405 | * remote partition. | ||
| 406 | * | ||
| 407 | * B - Messages that have been sent, but have not yet been acknowledged by the | ||
| 408 | * remote partition as having been received. | ||
| 409 | * | ||
| 410 | * C - Area that needs to be prepared for the copying of sent messages, by | ||
| 411 | * the clearing of the message flags of any previously received messages. | ||
| 412 | * | ||
| 413 | * D - Area into which sent messages are to be copied from the remote | ||
| 414 | * partition's local_msgqueue and then delivered to their intended | ||
| 415 | * recipients. [ To allow for a multi-message copy, another pointer | ||
| 416 | * (next_msg_to_pull) has been added to keep track of the next message | ||
| 417 | * number needing to be copied (pulled). It chases after w_remote_GP.put. | ||
| 418 | * Any messages lying between w_local_GP.get and next_msg_to_pull have | ||
| 419 | * been copied and are ready to be delivered. ] | ||
| 420 | * | ||
| 421 | * E - Messages that have been copied and delivered, but have not yet been | ||
| 422 | * acknowledged by the recipient as having been received. | ||
| 423 | * | ||
| 424 | * F - Messages that have been acknowledged, but XPC has not yet notified the | ||
| 425 | * sender that the message was received by its intended recipient. | ||
| 426 | * This is also an area that needs to be prepared for the allocating of | ||
| 427 | * new messages, by the clearing of the message flags of the acknowledged | ||
| 428 | * messages. | ||
| 429 | */ | ||
| 430 | struct xpc_channel { | ||
| 431 | partid_t partid; /* ID of remote partition connected */ | ||
| 432 | spinlock_t lock; /* lock for updating this structure */ | ||
| 433 | u32 flags; /* general flags */ | ||
| 434 | |||
| 435 | enum xpc_retval reason; /* reason why channel is disconnect'g */ | ||
| 436 | int reason_line; /* line# disconnect initiated from */ | ||
| 437 | |||
| 438 | u16 number; /* channel # */ | ||
| 439 | |||
| 440 | u16 msg_size; /* sizeof each msg entry */ | ||
| 441 | u16 local_nentries; /* #of msg entries in local msg queue */ | ||
| 442 | u16 remote_nentries; /* #of msg entries in remote msg queue*/ | ||
| 443 | |||
| 444 | void *local_msgqueue_base; /* base address of kmalloc'd space */ | ||
| 445 | struct xpc_msg *local_msgqueue; /* local message queue */ | ||
| 446 | void *remote_msgqueue_base; /* base address of kmalloc'd space */ | ||
| 447 | struct xpc_msg *remote_msgqueue;/* cached copy of remote partition's */ | ||
| 448 | /* local message queue */ | ||
| 449 | u64 remote_msgqueue_pa; /* phys addr of remote partition's */ | ||
| 450 | /* local message queue */ | ||
| 451 | |||
| 452 | atomic_t references; /* #of external references to queues */ | ||
| 453 | |||
| 454 | atomic_t n_on_msg_allocate_wq; /* #on msg allocation wait queue */ | ||
| 455 | wait_queue_head_t msg_allocate_wq; /* msg allocation wait queue */ | ||
| 456 | |||
| 457 | u8 delayed_IPI_flags; /* IPI flags received, but delayed */ | ||
| 458 | /* action until channel disconnected */ | ||
| 459 | |||
| 460 | /* queue of msg senders who want to be notified when msg received */ | ||
| 461 | |||
| 462 | atomic_t n_to_notify; /* #of msg senders to notify */ | ||
| 463 | struct xpc_notify *notify_queue;/* notify queue for messages sent */ | ||
| 464 | |||
| 465 | xpc_channel_func func; /* user's channel function */ | ||
| 466 | void *key; /* pointer to user's key */ | ||
| 467 | |||
| 468 | struct semaphore msg_to_pull_sema; /* next msg to pull serialization */ | ||
| 469 | struct semaphore wdisconnect_sema; /* wait for channel disconnect */ | ||
| 470 | |||
| 471 | struct xpc_openclose_args *local_openclose_args; /* args passed on */ | ||
| 472 | /* opening or closing of channel */ | ||
| 473 | |||
| 474 | /* various flavors of local and remote Get/Put values */ | ||
| 475 | |||
| 476 | struct xpc_gp *local_GP; /* local Get/Put values */ | ||
| 477 | struct xpc_gp remote_GP; /* remote Get/Put values */ | ||
| 478 | struct xpc_gp w_local_GP; /* working local Get/Put values */ | ||
| 479 | struct xpc_gp w_remote_GP; /* working remote Get/Put values */ | ||
| 480 | s64 next_msg_to_pull; /* Put value of next msg to pull */ | ||
| 481 | |||
| 482 | /* kthread management related fields */ | ||
| 483 | |||
| 484 | // >>> rethink having kthreads_assigned_limit and kthreads_idle_limit; perhaps | ||
| 485 | // >>> allow the assigned limit be unbounded and let the idle limit be dynamic | ||
| 486 | // >>> dependent on activity over the last interval of time | ||
| 487 | atomic_t kthreads_assigned; /* #of kthreads assigned to channel */ | ||
| 488 | u32 kthreads_assigned_limit; /* limit on #of kthreads assigned */ | ||
| 489 | atomic_t kthreads_idle; /* #of kthreads idle waiting for work */ | ||
| 490 | u32 kthreads_idle_limit; /* limit on #of kthreads idle */ | ||
| 491 | atomic_t kthreads_active; /* #of kthreads actively working */ | ||
| 492 | // >>> following field is temporary | ||
| 493 | u32 kthreads_created; /* total #of kthreads created */ | ||
| 494 | |||
| 495 | wait_queue_head_t idle_wq; /* idle kthread wait queue */ | ||
| 496 | |||
| 497 | } ____cacheline_aligned; | ||
| 498 | |||
| 499 | |||
| 500 | /* struct xpc_channel flags */ | ||
| 501 | |||
| 502 | #define XPC_C_WASCONNECTED 0x00000001 /* channel was connected */ | ||
| 503 | |||
| 504 | #define XPC_C_ROPENREPLY 0x00000002 /* remote open channel reply */ | ||
| 505 | #define XPC_C_OPENREPLY 0x00000004 /* local open channel reply */ | ||
| 506 | #define XPC_C_ROPENREQUEST 0x00000008 /* remote open channel request */ | ||
| 507 | #define XPC_C_OPENREQUEST 0x00000010 /* local open channel request */ | ||
| 508 | |||
| 509 | #define XPC_C_SETUP 0x00000020 /* channel's msgqueues are alloc'd */ | ||
| 510 | #define XPC_C_CONNECTCALLOUT 0x00000040 /* channel connected callout made */ | ||
| 511 | #define XPC_C_CONNECTED 0x00000080 /* local channel is connected */ | ||
| 512 | #define XPC_C_CONNECTING 0x00000100 /* channel is being connected */ | ||
| 513 | |||
| 514 | #define XPC_C_RCLOSEREPLY 0x00000200 /* remote close channel reply */ | ||
| 515 | #define XPC_C_CLOSEREPLY 0x00000400 /* local close channel reply */ | ||
| 516 | #define XPC_C_RCLOSEREQUEST 0x00000800 /* remote close channel request */ | ||
| 517 | #define XPC_C_CLOSEREQUEST 0x00001000 /* local close channel request */ | ||
| 518 | |||
| 519 | #define XPC_C_DISCONNECTED 0x00002000 /* channel is disconnected */ | ||
| 520 | #define XPC_C_DISCONNECTING 0x00004000 /* channel is being disconnected */ | ||
| 521 | #define XPC_C_DISCONNECTCALLOUT 0x00008000 /* chan disconnected callout made */ | ||
| 522 | #define XPC_C_WDISCONNECT 0x00010000 /* waiting for channel disconnect */ | ||
| 523 | |||
| 524 | |||
| 525 | |||
| 526 | /* | ||
| 527 | * Manages channels on a partition basis. There is one of these structures | ||
| 528 | * for each partition (a partition will never utilize the structure that | ||
| 529 | * represents itself). | ||
| 530 | */ | ||
| 531 | struct xpc_partition { | ||
| 532 | |||
| 533 | /* XPC HB infrastructure */ | ||
| 534 | |||
| 535 | u8 remote_rp_version; /* version# of partition's rsvd pg */ | ||
| 536 | struct timespec remote_rp_stamp;/* time when rsvd pg was initialized */ | ||
| 537 | u64 remote_rp_pa; /* phys addr of partition's rsvd pg */ | ||
| 538 | u64 remote_vars_pa; /* phys addr of partition's vars */ | ||
| 539 | u64 remote_vars_part_pa; /* phys addr of partition's vars part */ | ||
| 540 | u64 last_heartbeat; /* HB at last read */ | ||
| 541 | u64 remote_amos_page_pa; /* phys addr of partition's amos page */ | ||
| 542 | int remote_act_nasid; /* active part's act/deact nasid */ | ||
| 543 | int remote_act_phys_cpuid; /* active part's act/deact phys cpuid */ | ||
| 544 | u32 act_IRQ_rcvd; /* IRQs since activation */ | ||
| 545 | spinlock_t act_lock; /* protect updating of act_state */ | ||
| 546 | u8 act_state; /* from XPC HB viewpoint */ | ||
| 547 | u8 remote_vars_version; /* version# of partition's vars */ | ||
| 548 | enum xpc_retval reason; /* reason partition is deactivating */ | ||
| 549 | int reason_line; /* line# deactivation initiated from */ | ||
| 550 | int reactivate_nasid; /* nasid in partition to reactivate */ | ||
| 551 | |||
| 552 | unsigned long disengage_request_timeout; /* timeout in jiffies */ | ||
| 553 | struct timer_list disengage_request_timer; | ||
| 554 | |||
| 555 | |||
| 556 | /* XPC infrastructure referencing and teardown control */ | ||
| 557 | |||
| 558 | volatile u8 setup_state; /* infrastructure setup state */ | ||
| 559 | wait_queue_head_t teardown_wq; /* kthread waiting to teardown infra */ | ||
| 560 | atomic_t references; /* #of references to infrastructure */ | ||
| 561 | |||
| 562 | |||
| 563 | /* | ||
| 564 | * NONE OF THE PRECEDING FIELDS OF THIS STRUCTURE WILL BE CLEARED WHEN | ||
| 565 | * XPC SETS UP THE NECESSARY INFRASTRUCTURE TO SUPPORT CROSS PARTITION | ||
| 566 | * COMMUNICATION. ALL OF THE FOLLOWING FIELDS WILL BE CLEARED. (THE | ||
| 567 | * 'nchannels' FIELD MUST BE THE FIRST OF THE FIELDS TO BE CLEARED.) | ||
| 568 | */ | ||
| 569 | |||
| 570 | |||
| 571 | u8 nchannels; /* #of defined channels supported */ | ||
| 572 | atomic_t nchannels_active; /* #of channels that are not DISCONNECTED */ | ||
| 573 | atomic_t nchannels_engaged;/* #of channels engaged with remote part */ | ||
| 574 | struct xpc_channel *channels;/* array of channel structures */ | ||
| 575 | |||
| 576 | void *local_GPs_base; /* base address of kmalloc'd space */ | ||
| 577 | struct xpc_gp *local_GPs; /* local Get/Put values */ | ||
| 578 | void *remote_GPs_base; /* base address of kmalloc'd space */ | ||
| 579 | struct xpc_gp *remote_GPs;/* copy of remote partition's local Get/Put */ | ||
| 580 | /* values */ | ||
| 581 | u64 remote_GPs_pa; /* phys address of remote partition's local */ | ||
| 582 | /* Get/Put values */ | ||
| 583 | |||
| 584 | |||
| 585 | /* fields used to pass args when opening or closing a channel */ | ||
| 586 | |||
| 587 | void *local_openclose_args_base; /* base address of kmalloc'd space */ | ||
| 588 | struct xpc_openclose_args *local_openclose_args; /* local's args */ | ||
| 589 | void *remote_openclose_args_base; /* base address of kmalloc'd space */ | ||
| 590 | struct xpc_openclose_args *remote_openclose_args; /* copy of remote's */ | ||
| 591 | /* args */ | ||
| 592 | u64 remote_openclose_args_pa; /* phys addr of remote's args */ | ||
| 593 | |||
| 594 | |||
| 595 | /* IPI sending, receiving and handling related fields */ | ||
| 596 | |||
| 597 | int remote_IPI_nasid; /* nasid of where to send IPIs */ | ||
| 598 | int remote_IPI_phys_cpuid; /* phys CPU ID of where to send IPIs */ | ||
| 599 | AMO_t *remote_IPI_amo_va; /* address of remote IPI AMO_t structure */ | ||
| 600 | |||
| 601 | AMO_t *local_IPI_amo_va; /* address of IPI AMO_t structure */ | ||
| 602 | u64 local_IPI_amo; /* IPI amo flags yet to be handled */ | ||
| 603 | char IPI_owner[8]; /* IPI owner's name */ | ||
| 604 | struct timer_list dropped_IPI_timer; /* dropped IPI timer */ | ||
| 605 | |||
| 606 | spinlock_t IPI_lock; /* IPI handler lock */ | ||
| 607 | |||
| 608 | |||
| 609 | /* channel manager related fields */ | ||
| 610 | |||
| 611 | atomic_t channel_mgr_requests; /* #of requests to activate chan mgr */ | ||
| 612 | wait_queue_head_t channel_mgr_wq; /* channel mgr's wait queue */ | ||
| 613 | |||
| 614 | } ____cacheline_aligned; | ||
| 615 | |||
| 616 | |||
| 617 | /* struct xpc_partition act_state values (for XPC HB) */ | ||
| 618 | |||
| 619 | #define XPC_P_INACTIVE 0x00 /* partition is not active */ | ||
| 620 | #define XPC_P_ACTIVATION_REQ 0x01 /* created thread to activate */ | ||
| 621 | #define XPC_P_ACTIVATING 0x02 /* activation thread started */ | ||
| 622 | #define XPC_P_ACTIVE 0x03 /* xpc_partition_up() was called */ | ||
| 623 | #define XPC_P_DEACTIVATING 0x04 /* partition deactivation initiated */ | ||
| 624 | |||
| 625 | |||
| 626 | #define XPC_DEACTIVATE_PARTITION(_p, _reason) \ | ||
| 627 | xpc_deactivate_partition(__LINE__, (_p), (_reason)) | ||
| 628 | |||
| 629 | |||
| 630 | /* struct xpc_partition setup_state values */ | ||
| 631 | |||
| 632 | #define XPC_P_UNSET 0x00 /* infrastructure was never setup */ | ||
| 633 | #define XPC_P_SETUP 0x01 /* infrastructure is setup */ | ||
| 634 | #define XPC_P_WTEARDOWN 0x02 /* waiting to teardown infrastructure */ | ||
| 635 | #define XPC_P_TORNDOWN 0x03 /* infrastructure is torndown */ | ||
| 636 | |||
| 637 | |||
| 638 | |||
| 639 | /* | ||
| 640 | * struct xpc_partition IPI_timer #of seconds to wait before checking for | ||
| 641 | * dropped IPIs. These occur whenever an IPI amo write doesn't complete until | ||
| 642 | * after the IPI was received. | ||
| 643 | */ | ||
| 644 | #define XPC_P_DROPPED_IPI_WAIT (0.25 * HZ) | ||
| 645 | |||
| 646 | |||
| 647 | /* number of seconds to wait for other partitions to disengage */ | ||
| 648 | #define XPC_DISENGAGE_REQUEST_DEFAULT_TIMELIMIT 90 | ||
| 649 | |||
| 650 | /* interval in seconds to print 'waiting disengagement' messages */ | ||
| 651 | #define XPC_DISENGAGE_PRINTMSG_INTERVAL 10 | ||
| 652 | |||
| 653 | |||
| 654 | #define XPC_PARTID(_p) ((partid_t) ((_p) - &xpc_partitions[0])) | ||
| 655 | |||
| 656 | |||
| 657 | |||
| 658 | /* found in xp_main.c */ | ||
| 659 | extern struct xpc_registration xpc_registrations[]; | ||
| 660 | |||
| 661 | |||
| 662 | /* found in xpc_main.c */ | ||
| 663 | extern struct device *xpc_part; | ||
| 664 | extern struct device *xpc_chan; | ||
| 665 | extern int xpc_disengage_request_timelimit; | ||
| 666 | extern irqreturn_t xpc_notify_IRQ_handler(int, void *, struct pt_regs *); | ||
| 667 | extern void xpc_dropped_IPI_check(struct xpc_partition *); | ||
| 668 | extern void xpc_activate_partition(struct xpc_partition *); | ||
| 669 | extern void xpc_activate_kthreads(struct xpc_channel *, int); | ||
| 670 | extern void xpc_create_kthreads(struct xpc_channel *, int); | ||
| 671 | extern void xpc_disconnect_wait(int); | ||
| 672 | |||
| 673 | |||
| 674 | /* found in xpc_partition.c */ | ||
| 675 | extern int xpc_exiting; | ||
| 676 | extern struct xpc_vars *xpc_vars; | ||
| 677 | extern struct xpc_rsvd_page *xpc_rsvd_page; | ||
| 678 | extern struct xpc_vars_part *xpc_vars_part; | ||
| 679 | extern struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1]; | ||
| 680 | extern char xpc_remote_copy_buffer[]; | ||
| 681 | extern struct xpc_rsvd_page *xpc_rsvd_page_init(void); | ||
| 682 | extern void xpc_allow_IPI_ops(void); | ||
| 683 | extern void xpc_restrict_IPI_ops(void); | ||
| 684 | extern int xpc_identify_act_IRQ_sender(void); | ||
| 685 | extern int xpc_partition_disengaged(struct xpc_partition *); | ||
| 686 | extern enum xpc_retval xpc_mark_partition_active(struct xpc_partition *); | ||
| 687 | extern void xpc_mark_partition_inactive(struct xpc_partition *); | ||
| 688 | extern void xpc_discovery(void); | ||
| 689 | extern void xpc_check_remote_hb(void); | ||
| 690 | extern void xpc_deactivate_partition(const int, struct xpc_partition *, | ||
| 691 | enum xpc_retval); | ||
| 692 | extern enum xpc_retval xpc_initiate_partid_to_nasids(partid_t, void *); | ||
| 693 | |||
| 694 | |||
| 695 | /* found in xpc_channel.c */ | ||
| 696 | extern void xpc_initiate_connect(int); | ||
| 697 | extern void xpc_initiate_disconnect(int); | ||
| 698 | extern enum xpc_retval xpc_initiate_allocate(partid_t, int, u32, void **); | ||
| 699 | extern enum xpc_retval xpc_initiate_send(partid_t, int, void *); | ||
| 700 | extern enum xpc_retval xpc_initiate_send_notify(partid_t, int, void *, | ||
| 701 | xpc_notify_func, void *); | ||
| 702 | extern void xpc_initiate_received(partid_t, int, void *); | ||
| 703 | extern enum xpc_retval xpc_setup_infrastructure(struct xpc_partition *); | ||
| 704 | extern enum xpc_retval xpc_pull_remote_vars_part(struct xpc_partition *); | ||
| 705 | extern void xpc_process_channel_activity(struct xpc_partition *); | ||
| 706 | extern void xpc_connected_callout(struct xpc_channel *); | ||
| 707 | extern void xpc_deliver_msg(struct xpc_channel *); | ||
| 708 | extern void xpc_disconnect_channel(const int, struct xpc_channel *, | ||
| 709 | enum xpc_retval, unsigned long *); | ||
| 710 | extern void xpc_disconnecting_callout(struct xpc_channel *); | ||
| 711 | extern void xpc_partition_going_down(struct xpc_partition *, enum xpc_retval); | ||
| 712 | extern void xpc_teardown_infrastructure(struct xpc_partition *); | ||
| 713 | |||
| 714 | |||
| 715 | |||
| 716 | static inline void | ||
| 717 | xpc_wakeup_channel_mgr(struct xpc_partition *part) | ||
| 718 | { | ||
| 719 | if (atomic_inc_return(&part->channel_mgr_requests) == 1) { | ||
| 720 | wake_up(&part->channel_mgr_wq); | ||
| 721 | } | ||
| 722 | } | ||
| 723 | |||
| 724 | |||
| 725 | |||
| 726 | /* | ||
| 727 | * These next two inlines are used to keep us from tearing down a channel's | ||
| 728 | * msg queues while a thread may be referencing them. | ||
| 729 | */ | ||
| 730 | static inline void | ||
| 731 | xpc_msgqueue_ref(struct xpc_channel *ch) | ||
| 732 | { | ||
| 733 | atomic_inc(&ch->references); | ||
| 734 | } | ||
| 735 | |||
| 736 | static inline void | ||
| 737 | xpc_msgqueue_deref(struct xpc_channel *ch) | ||
| 738 | { | ||
| 739 | s32 refs = atomic_dec_return(&ch->references); | ||
| 740 | |||
| 741 | DBUG_ON(refs < 0); | ||
| 742 | if (refs == 0) { | ||
| 743 | xpc_wakeup_channel_mgr(&xpc_partitions[ch->partid]); | ||
| 744 | } | ||
| 745 | } | ||
| 746 | |||
| 747 | |||
| 748 | |||
| 749 | #define XPC_DISCONNECT_CHANNEL(_ch, _reason, _irqflgs) \ | ||
| 750 | xpc_disconnect_channel(__LINE__, _ch, _reason, _irqflgs) | ||
| 751 | |||
| 752 | |||
| 753 | /* | ||
| 754 | * These two inlines are used to keep us from tearing down a partition's | ||
| 755 | * setup infrastructure while a thread may be referencing it. | ||
| 756 | */ | ||
| 757 | static inline void | ||
| 758 | xpc_part_deref(struct xpc_partition *part) | ||
| 759 | { | ||
| 760 | s32 refs = atomic_dec_return(&part->references); | ||
| 761 | |||
| 762 | |||
| 763 | DBUG_ON(refs < 0); | ||
| 764 | if (refs == 0 && part->setup_state == XPC_P_WTEARDOWN) { | ||
| 765 | wake_up(&part->teardown_wq); | ||
| 766 | } | ||
| 767 | } | ||
| 768 | |||
| 769 | static inline int | ||
| 770 | xpc_part_ref(struct xpc_partition *part) | ||
| 771 | { | ||
| 772 | int setup; | ||
| 773 | |||
| 774 | |||
| 775 | atomic_inc(&part->references); | ||
| 776 | setup = (part->setup_state == XPC_P_SETUP); | ||
| 777 | if (!setup) { | ||
| 778 | xpc_part_deref(part); | ||
| 779 | } | ||
| 780 | return setup; | ||
| 781 | } | ||
| 782 | |||
| 783 | |||
| 784 | |||
| 785 | /* | ||
| 786 | * The following macro is to be used for the setting of the reason and | ||
| 787 | * reason_line fields in both the struct xpc_channel and struct xpc_partition | ||
| 788 | * structures. | ||
| 789 | */ | ||
| 790 | #define XPC_SET_REASON(_p, _reason, _line) \ | ||
| 791 | { \ | ||
| 792 | (_p)->reason = _reason; \ | ||
| 793 | (_p)->reason_line = _line; \ | ||
| 794 | } | ||
| 795 | |||
| 796 | |||
| 797 | |||
| 798 | /* | ||
| 799 | * This next set of inlines are used to keep track of when a partition is | ||
| 800 | * potentially engaged in accessing memory belonging to another partition. | ||
| 801 | */ | ||
| 802 | |||
| 803 | static inline void | ||
| 804 | xpc_mark_partition_engaged(struct xpc_partition *part) | ||
| 805 | { | ||
| 806 | unsigned long irq_flags; | ||
| 807 | AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa + | ||
| 808 | (XPC_ENGAGED_PARTITIONS_AMO * sizeof(AMO_t))); | ||
| 809 | |||
| 810 | |||
| 811 | local_irq_save(irq_flags); | ||
| 812 | |||
| 813 | /* set bit corresponding to our partid in remote partition's AMO */ | ||
| 814 | FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR, | ||
| 815 | (1UL << sn_partition_id)); | ||
| 816 | /* | ||
| 817 | * We must always use the nofault function regardless of whether we | ||
| 818 | * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we | ||
| 819 | * didn't, we'd never know that the other partition is down and would | ||
| 820 | * keep sending IPIs and AMOs to it until the heartbeat times out. | ||
| 821 | */ | ||
| 822 | (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo-> | ||
| 823 | variable), xp_nofault_PIOR_target)); | ||
| 824 | |||
| 825 | local_irq_restore(irq_flags); | ||
| 826 | } | ||
| 827 | |||
| 828 | static inline void | ||
| 829 | xpc_mark_partition_disengaged(struct xpc_partition *part) | ||
| 830 | { | ||
| 831 | unsigned long irq_flags; | ||
| 832 | AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa + | ||
| 833 | (XPC_ENGAGED_PARTITIONS_AMO * sizeof(AMO_t))); | ||
| 834 | |||
| 835 | |||
| 836 | local_irq_save(irq_flags); | ||
| 837 | |||
| 838 | /* clear bit corresponding to our partid in remote partition's AMO */ | ||
| 839 | FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND, | ||
| 840 | ~(1UL << sn_partition_id)); | ||
| 841 | /* | ||
| 842 | * We must always use the nofault function regardless of whether we | ||
| 843 | * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we | ||
| 844 | * didn't, we'd never know that the other partition is down and would | ||
| 845 | * keep sending IPIs and AMOs to it until the heartbeat times out. | ||
| 846 | */ | ||
| 847 | (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo-> | ||
| 848 | variable), xp_nofault_PIOR_target)); | ||
| 849 | |||
| 850 | local_irq_restore(irq_flags); | ||
| 851 | } | ||
| 852 | |||
| 853 | static inline void | ||
| 854 | xpc_request_partition_disengage(struct xpc_partition *part) | ||
| 855 | { | ||
| 856 | unsigned long irq_flags; | ||
| 857 | AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa + | ||
| 858 | (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t))); | ||
| 859 | |||
| 860 | |||
| 861 | local_irq_save(irq_flags); | ||
| 862 | |||
| 863 | /* set bit corresponding to our partid in remote partition's AMO */ | ||
| 864 | FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR, | ||
| 865 | (1UL << sn_partition_id)); | ||
| 866 | /* | ||
| 867 | * We must always use the nofault function regardless of whether we | ||
| 868 | * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we | ||
| 869 | * didn't, we'd never know that the other partition is down and would | ||
| 870 | * keep sending IPIs and AMOs to it until the heartbeat times out. | ||
| 871 | */ | ||
| 872 | (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo-> | ||
| 873 | variable), xp_nofault_PIOR_target)); | ||
| 874 | |||
| 875 | local_irq_restore(irq_flags); | ||
| 876 | } | ||
| 877 | |||
| 878 | static inline void | ||
| 879 | xpc_cancel_partition_disengage_request(struct xpc_partition *part) | ||
| 880 | { | ||
| 881 | unsigned long irq_flags; | ||
| 882 | AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa + | ||
| 883 | (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t))); | ||
| 884 | |||
| 885 | |||
| 886 | local_irq_save(irq_flags); | ||
| 887 | |||
| 888 | /* clear bit corresponding to our partid in remote partition's AMO */ | ||
| 889 | FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND, | ||
| 890 | ~(1UL << sn_partition_id)); | ||
| 891 | /* | ||
| 892 | * We must always use the nofault function regardless of whether we | ||
| 893 | * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we | ||
| 894 | * didn't, we'd never know that the other partition is down and would | ||
| 895 | * keep sending IPIs and AMOs to it until the heartbeat times out. | ||
| 896 | */ | ||
| 897 | (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo-> | ||
| 898 | variable), xp_nofault_PIOR_target)); | ||
| 899 | |||
| 900 | local_irq_restore(irq_flags); | ||
| 901 | } | ||
| 902 | |||
| 903 | static inline u64 | ||
| 904 | xpc_partition_engaged(u64 partid_mask) | ||
| 905 | { | ||
| 906 | AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO; | ||
| 907 | |||
| 908 | |||
| 909 | /* return our partition's AMO variable ANDed with partid_mask */ | ||
| 910 | return (FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_LOAD) & | ||
| 911 | partid_mask); | ||
| 912 | } | ||
| 913 | |||
| 914 | static inline u64 | ||
| 915 | xpc_partition_disengage_requested(u64 partid_mask) | ||
| 916 | { | ||
| 917 | AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO; | ||
| 918 | |||
| 919 | |||
| 920 | /* return our partition's AMO variable ANDed with partid_mask */ | ||
| 921 | return (FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_LOAD) & | ||
| 922 | partid_mask); | ||
| 923 | } | ||
| 924 | |||
| 925 | static inline void | ||
| 926 | xpc_clear_partition_engaged(u64 partid_mask) | ||
| 927 | { | ||
| 928 | AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO; | ||
| 929 | |||
| 930 | |||
| 931 | /* clear bit(s) based on partid_mask in our partition's AMO */ | ||
| 932 | FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND, | ||
| 933 | ~partid_mask); | ||
| 934 | } | ||
| 935 | |||
| 936 | static inline void | ||
| 937 | xpc_clear_partition_disengage_request(u64 partid_mask) | ||
| 938 | { | ||
| 939 | AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO; | ||
| 940 | |||
| 941 | |||
| 942 | /* clear bit(s) based on partid_mask in our partition's AMO */ | ||
| 943 | FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND, | ||
| 944 | ~partid_mask); | ||
| 945 | } | ||
| 946 | |||
| 947 | |||
| 948 | |||
| 949 | /* | ||
| 950 | * The following set of macros and inlines are used for the sending and | ||
| 951 | * receiving of IPIs (also known as IRQs). There are two flavors of IPIs, | ||
| 952 | * one that is associated with partition activity (SGI_XPC_ACTIVATE) and | ||
| 953 | * the other that is associated with channel activity (SGI_XPC_NOTIFY). | ||
| 954 | */ | ||
| 955 | |||
| 956 | static inline u64 | ||
| 957 | xpc_IPI_receive(AMO_t *amo) | ||
| 958 | { | ||
| 959 | return FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_CLEAR); | ||
| 960 | } | ||
| 961 | |||
| 962 | |||
| 963 | static inline enum xpc_retval | ||
| 964 | xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector) | ||
| 965 | { | ||
| 966 | int ret = 0; | ||
| 967 | unsigned long irq_flags; | ||
| 968 | |||
| 969 | |||
| 970 | local_irq_save(irq_flags); | ||
| 971 | |||
| 972 | FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR, flag); | ||
| 973 | sn_send_IPI_phys(nasid, phys_cpuid, vector, 0); | ||
| 974 | |||
| 975 | /* | ||
| 976 | * We must always use the nofault function regardless of whether we | ||
| 977 | * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we | ||
| 978 | * didn't, we'd never know that the other partition is down and would | ||
| 979 | * keep sending IPIs and AMOs to it until the heartbeat times out. | ||
| 980 | */ | ||
| 981 | ret = xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo->variable), | ||
| 982 | xp_nofault_PIOR_target)); | ||
| 983 | |||
| 984 | local_irq_restore(irq_flags); | ||
| 985 | |||
| 986 | return ((ret == 0) ? xpcSuccess : xpcPioReadError); | ||
| 987 | } | ||
| 988 | |||
| 989 | |||
| 990 | /* | ||
| 991 | * IPIs associated with SGI_XPC_ACTIVATE IRQ. | ||
| 992 | */ | ||
| 993 | |||
| 994 | /* | ||
| 995 | * Flag the appropriate AMO variable and send an IPI to the specified node. | ||
| 996 | */ | ||
| 997 | static inline void | ||
| 998 | xpc_activate_IRQ_send(u64 amos_page_pa, int from_nasid, int to_nasid, | ||
| 999 | int to_phys_cpuid) | ||
| 1000 | { | ||
| 1001 | int w_index = XPC_NASID_W_INDEX(from_nasid); | ||
| 1002 | int b_index = XPC_NASID_B_INDEX(from_nasid); | ||
| 1003 | AMO_t *amos = (AMO_t *) __va(amos_page_pa + | ||
| 1004 | (XPC_ACTIVATE_IRQ_AMOS * sizeof(AMO_t))); | ||
| 1005 | |||
| 1006 | |||
| 1007 | (void) xpc_IPI_send(&amos[w_index], (1UL << b_index), to_nasid, | ||
| 1008 | to_phys_cpuid, SGI_XPC_ACTIVATE); | ||
| 1009 | } | ||
| 1010 | |||
| 1011 | static inline void | ||
| 1012 | xpc_IPI_send_activate(struct xpc_vars *vars) | ||
| 1013 | { | ||
| 1014 | xpc_activate_IRQ_send(vars->amos_page_pa, cnodeid_to_nasid(0), | ||
| 1015 | vars->act_nasid, vars->act_phys_cpuid); | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | static inline void | ||
| 1019 | xpc_IPI_send_activated(struct xpc_partition *part) | ||
| 1020 | { | ||
| 1021 | xpc_activate_IRQ_send(part->remote_amos_page_pa, cnodeid_to_nasid(0), | ||
| 1022 | part->remote_act_nasid, part->remote_act_phys_cpuid); | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | static inline void | ||
| 1026 | xpc_IPI_send_reactivate(struct xpc_partition *part) | ||
| 1027 | { | ||
| 1028 | xpc_activate_IRQ_send(xpc_vars->amos_page_pa, part->reactivate_nasid, | ||
| 1029 | xpc_vars->act_nasid, xpc_vars->act_phys_cpuid); | ||
| 1030 | } | ||
| 1031 | |||
| 1032 | static inline void | ||
| 1033 | xpc_IPI_send_disengage(struct xpc_partition *part) | ||
| 1034 | { | ||
| 1035 | xpc_activate_IRQ_send(part->remote_amos_page_pa, cnodeid_to_nasid(0), | ||
| 1036 | part->remote_act_nasid, part->remote_act_phys_cpuid); | ||
| 1037 | } | ||
| 1038 | |||
| 1039 | |||
| 1040 | /* | ||
| 1041 | * IPIs associated with SGI_XPC_NOTIFY IRQ. | ||
| 1042 | */ | ||
| 1043 | |||
| 1044 | /* | ||
| 1045 | * Send an IPI to the remote partition that is associated with the | ||
| 1046 | * specified channel. | ||
| 1047 | */ | ||
| 1048 | #define XPC_NOTIFY_IRQ_SEND(_ch, _ipi_f, _irq_f) \ | ||
| 1049 | xpc_notify_IRQ_send(_ch, _ipi_f, #_ipi_f, _irq_f) | ||
| 1050 | |||
| 1051 | static inline void | ||
| 1052 | xpc_notify_IRQ_send(struct xpc_channel *ch, u8 ipi_flag, char *ipi_flag_string, | ||
| 1053 | unsigned long *irq_flags) | ||
| 1054 | { | ||
| 1055 | struct xpc_partition *part = &xpc_partitions[ch->partid]; | ||
| 1056 | enum xpc_retval ret; | ||
| 1057 | |||
| 1058 | |||
| 1059 | if (likely(part->act_state != XPC_P_DEACTIVATING)) { | ||
| 1060 | ret = xpc_IPI_send(part->remote_IPI_amo_va, | ||
| 1061 | (u64) ipi_flag << (ch->number * 8), | ||
| 1062 | part->remote_IPI_nasid, | ||
| 1063 | part->remote_IPI_phys_cpuid, | ||
| 1064 | SGI_XPC_NOTIFY); | ||
| 1065 | dev_dbg(xpc_chan, "%s sent to partid=%d, channel=%d, ret=%d\n", | ||
| 1066 | ipi_flag_string, ch->partid, ch->number, ret); | ||
| 1067 | if (unlikely(ret != xpcSuccess)) { | ||
| 1068 | if (irq_flags != NULL) { | ||
| 1069 | spin_unlock_irqrestore(&ch->lock, *irq_flags); | ||
| 1070 | } | ||
| 1071 | XPC_DEACTIVATE_PARTITION(part, ret); | ||
| 1072 | if (irq_flags != NULL) { | ||
| 1073 | spin_lock_irqsave(&ch->lock, *irq_flags); | ||
| 1074 | } | ||
| 1075 | } | ||
| 1076 | } | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | |||
| 1080 | /* | ||
| 1081 | * Make it look like the remote partition, which is associated with the | ||
| 1082 | * specified channel, sent us an IPI. This faked IPI will be handled | ||
| 1083 | * by xpc_dropped_IPI_check(). | ||
| 1084 | */ | ||
| 1085 | #define XPC_NOTIFY_IRQ_SEND_LOCAL(_ch, _ipi_f) \ | ||
| 1086 | xpc_notify_IRQ_send_local(_ch, _ipi_f, #_ipi_f) | ||
| 1087 | |||
| 1088 | static inline void | ||
| 1089 | xpc_notify_IRQ_send_local(struct xpc_channel *ch, u8 ipi_flag, | ||
| 1090 | char *ipi_flag_string) | ||
| 1091 | { | ||
| 1092 | struct xpc_partition *part = &xpc_partitions[ch->partid]; | ||
| 1093 | |||
| 1094 | |||
| 1095 | FETCHOP_STORE_OP(TO_AMO((u64) &part->local_IPI_amo_va->variable), | ||
| 1096 | FETCHOP_OR, ((u64) ipi_flag << (ch->number * 8))); | ||
| 1097 | dev_dbg(xpc_chan, "%s sent local from partid=%d, channel=%d\n", | ||
| 1098 | ipi_flag_string, ch->partid, ch->number); | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | |||
| 1102 | /* | ||
| 1103 | * The sending and receiving of IPIs includes the setting of an AMO variable | ||
| 1104 | * to indicate the reason the IPI was sent. The 64-bit variable is divided | ||
| 1105 | * up into eight bytes, ordered from right to left. Byte zero pertains to | ||
| 1106 | * channel 0, byte one to channel 1, and so on. Each byte is described by | ||
| 1107 | * the following IPI flags. | ||
| 1108 | */ | ||
| 1109 | |||
| 1110 | #define XPC_IPI_CLOSEREQUEST 0x01 | ||
| 1111 | #define XPC_IPI_CLOSEREPLY 0x02 | ||
| 1112 | #define XPC_IPI_OPENREQUEST 0x04 | ||
| 1113 | #define XPC_IPI_OPENREPLY 0x08 | ||
| 1114 | #define XPC_IPI_MSGREQUEST 0x10 | ||
| 1115 | |||
| 1116 | |||
| 1117 | /* given an AMO variable and a channel#, get its associated IPI flags */ | ||
| 1118 | #define XPC_GET_IPI_FLAGS(_amo, _c) ((u8) (((_amo) >> ((_c) * 8)) & 0xff)) | ||
| 1119 | #define XPC_SET_IPI_FLAGS(_amo, _c, _f) (_amo) |= ((u64) (_f) << ((_c) * 8)) | ||
| 1120 | |||
| 1121 | #define XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(_amo) ((_amo) & 0x0f0f0f0f0f0f0f0f) | ||
| 1122 | #define XPC_ANY_MSG_IPI_FLAGS_SET(_amo) ((_amo) & 0x1010101010101010) | ||
| 1123 | |||
| 1124 | |||
| 1125 | static inline void | ||
| 1126 | xpc_IPI_send_closerequest(struct xpc_channel *ch, unsigned long *irq_flags) | ||
| 1127 | { | ||
| 1128 | struct xpc_openclose_args *args = ch->local_openclose_args; | ||
| 1129 | |||
| 1130 | |||
| 1131 | args->reason = ch->reason; | ||
| 1132 | |||
| 1133 | XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_CLOSEREQUEST, irq_flags); | ||
| 1134 | } | ||
| 1135 | |||
| 1136 | static inline void | ||
| 1137 | xpc_IPI_send_closereply(struct xpc_channel *ch, unsigned long *irq_flags) | ||
| 1138 | { | ||
| 1139 | XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_CLOSEREPLY, irq_flags); | ||
| 1140 | } | ||
| 1141 | |||
| 1142 | static inline void | ||
| 1143 | xpc_IPI_send_openrequest(struct xpc_channel *ch, unsigned long *irq_flags) | ||
| 1144 | { | ||
| 1145 | struct xpc_openclose_args *args = ch->local_openclose_args; | ||
| 1146 | |||
| 1147 | |||
| 1148 | args->msg_size = ch->msg_size; | ||
| 1149 | args->local_nentries = ch->local_nentries; | ||
| 1150 | |||
| 1151 | XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_OPENREQUEST, irq_flags); | ||
| 1152 | } | ||
| 1153 | |||
| 1154 | static inline void | ||
| 1155 | xpc_IPI_send_openreply(struct xpc_channel *ch, unsigned long *irq_flags) | ||
| 1156 | { | ||
| 1157 | struct xpc_openclose_args *args = ch->local_openclose_args; | ||
| 1158 | |||
| 1159 | |||
| 1160 | args->remote_nentries = ch->remote_nentries; | ||
| 1161 | args->local_nentries = ch->local_nentries; | ||
| 1162 | args->local_msgqueue_pa = __pa(ch->local_msgqueue); | ||
| 1163 | |||
| 1164 | XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_OPENREPLY, irq_flags); | ||
| 1165 | } | ||
| 1166 | |||
| 1167 | static inline void | ||
| 1168 | xpc_IPI_send_msgrequest(struct xpc_channel *ch) | ||
| 1169 | { | ||
| 1170 | XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_MSGREQUEST, NULL); | ||
| 1171 | } | ||
| 1172 | |||
| 1173 | static inline void | ||
| 1174 | xpc_IPI_send_local_msgrequest(struct xpc_channel *ch) | ||
| 1175 | { | ||
| 1176 | XPC_NOTIFY_IRQ_SEND_LOCAL(ch, XPC_IPI_MSGREQUEST); | ||
| 1177 | } | ||
| 1178 | |||
| 1179 | |||
| 1180 | /* | ||
| 1181 | * Memory for XPC's AMO variables is allocated by the MSPEC driver. These | ||
| 1182 | * pages are located in the lowest granule. The lowest granule uses 4k pages | ||
| 1183 | * for cached references and an alternate TLB handler to never provide a | ||
| 1184 | * cacheable mapping for the entire region. This will prevent speculative | ||
| 1185 | * reading of cached copies of our lines from being issued which will cause | ||
| 1186 | * a PI FSB Protocol error to be generated by the SHUB. For XPC, we need 64 | ||
| 1187 | * AMO variables (based on XP_MAX_PARTITIONS) for message notification and an | ||
| 1188 | * additional 128 AMO variables (based on XP_NASID_MASK_WORDS) for partition | ||
| 1189 | * activation and 2 AMO variables for partition deactivation. | ||
| 1190 | */ | ||
| 1191 | static inline AMO_t * | ||
| 1192 | xpc_IPI_init(int index) | ||
| 1193 | { | ||
| 1194 | AMO_t *amo = xpc_vars->amos_page + index; | ||
| 1195 | |||
| 1196 | |||
| 1197 | (void) xpc_IPI_receive(amo); /* clear AMO variable */ | ||
| 1198 | return amo; | ||
| 1199 | } | ||
| 1200 | |||
| 1201 | |||
| 1202 | |||
| 1203 | static inline enum xpc_retval | ||
| 1204 | xpc_map_bte_errors(bte_result_t error) | ||
| 1205 | { | ||
| 1206 | switch (error) { | ||
| 1207 | case BTE_SUCCESS: return xpcSuccess; | ||
| 1208 | case BTEFAIL_DIR: return xpcBteDirectoryError; | ||
| 1209 | case BTEFAIL_POISON: return xpcBtePoisonError; | ||
| 1210 | case BTEFAIL_WERR: return xpcBteWriteError; | ||
| 1211 | case BTEFAIL_ACCESS: return xpcBteAccessError; | ||
| 1212 | case BTEFAIL_PWERR: return xpcBtePWriteError; | ||
| 1213 | case BTEFAIL_PRERR: return xpcBtePReadError; | ||
| 1214 | case BTEFAIL_TOUT: return xpcBteTimeOutError; | ||
| 1215 | case BTEFAIL_XTERR: return xpcBteXtalkError; | ||
| 1216 | case BTEFAIL_NOTAVAIL: return xpcBteNotAvailable; | ||
| 1217 | default: return xpcBteUnmappedError; | ||
| 1218 | } | ||
| 1219 | } | ||
| 1220 | |||
| 1221 | |||
| 1222 | |||
| 1223 | static inline void * | ||
| 1224 | xpc_kmalloc_cacheline_aligned(size_t size, gfp_t flags, void **base) | ||
| 1225 | { | ||
| 1226 | /* see if kmalloc will give us cachline aligned memory by default */ | ||
| 1227 | *base = kmalloc(size, flags); | ||
| 1228 | if (*base == NULL) { | ||
| 1229 | return NULL; | ||
| 1230 | } | ||
| 1231 | if ((u64) *base == L1_CACHE_ALIGN((u64) *base)) { | ||
| 1232 | return *base; | ||
| 1233 | } | ||
| 1234 | kfree(*base); | ||
| 1235 | |||
| 1236 | /* nope, we'll have to do it ourselves */ | ||
| 1237 | *base = kmalloc(size + L1_CACHE_BYTES, flags); | ||
| 1238 | if (*base == NULL) { | ||
| 1239 | return NULL; | ||
| 1240 | } | ||
| 1241 | return (void *) L1_CACHE_ALIGN((u64) *base); | ||
| 1242 | } | ||
| 1243 | |||
| 1244 | |||
| 1245 | /* | ||
| 1246 | * Check to see if there is any channel activity to/from the specified | ||
| 1247 | * partition. | ||
| 1248 | */ | ||
| 1249 | static inline void | ||
| 1250 | xpc_check_for_channel_activity(struct xpc_partition *part) | ||
| 1251 | { | ||
| 1252 | u64 IPI_amo; | ||
| 1253 | unsigned long irq_flags; | ||
| 1254 | |||
| 1255 | |||
| 1256 | IPI_amo = xpc_IPI_receive(part->local_IPI_amo_va); | ||
| 1257 | if (IPI_amo == 0) { | ||
| 1258 | return; | ||
| 1259 | } | ||
| 1260 | |||
| 1261 | spin_lock_irqsave(&part->IPI_lock, irq_flags); | ||
| 1262 | part->local_IPI_amo |= IPI_amo; | ||
| 1263 | spin_unlock_irqrestore(&part->IPI_lock, irq_flags); | ||
| 1264 | |||
| 1265 | dev_dbg(xpc_chan, "received IPI from partid=%d, IPI_amo=0x%lx\n", | ||
| 1266 | XPC_PARTID(part), IPI_amo); | ||
| 1267 | |||
| 1268 | xpc_wakeup_channel_mgr(part); | ||
| 1269 | } | ||
| 1270 | |||
| 1271 | |||
| 1272 | #endif /* _IA64_SN_KERNEL_XPC_H */ | ||
| 1273 | |||
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c index abf4fc2a87bb..0c0a68902409 100644 --- a/arch/ia64/sn/kernel/xpc_channel.c +++ b/arch/ia64/sn/kernel/xpc_channel.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. | 6 | * Copyright (c) 2004-2006 Silicon Graphics, Inc. All Rights Reserved. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | 9 | ||
| @@ -24,7 +24,7 @@ | |||
| 24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
| 25 | #include <asm/sn/bte.h> | 25 | #include <asm/sn/bte.h> |
| 26 | #include <asm/sn/sn_sal.h> | 26 | #include <asm/sn/sn_sal.h> |
| 27 | #include "xpc.h" | 27 | #include <asm/sn/xpc.h> |
| 28 | 28 | ||
| 29 | 29 | ||
| 30 | /* | 30 | /* |
| @@ -779,6 +779,12 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) | |||
| 779 | 779 | ||
| 780 | /* both sides are disconnected now */ | 780 | /* both sides are disconnected now */ |
| 781 | 781 | ||
| 782 | if (ch->flags & XPC_C_CONNECTCALLOUT) { | ||
| 783 | spin_unlock_irqrestore(&ch->lock, *irq_flags); | ||
| 784 | xpc_disconnect_callout(ch, xpcDisconnected); | ||
| 785 | spin_lock_irqsave(&ch->lock, *irq_flags); | ||
| 786 | } | ||
| 787 | |||
| 782 | /* it's now safe to free the channel's message queues */ | 788 | /* it's now safe to free the channel's message queues */ |
| 783 | xpc_free_msgqueues(ch); | 789 | xpc_free_msgqueues(ch); |
| 784 | 790 | ||
| @@ -1645,7 +1651,7 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch, | |||
| 1645 | 1651 | ||
| 1646 | 1652 | ||
| 1647 | void | 1653 | void |
| 1648 | xpc_disconnecting_callout(struct xpc_channel *ch) | 1654 | xpc_disconnect_callout(struct xpc_channel *ch, enum xpc_retval reason) |
| 1649 | { | 1655 | { |
| 1650 | /* | 1656 | /* |
| 1651 | * Let the channel's registerer know that the channel is being | 1657 | * Let the channel's registerer know that the channel is being |
| @@ -1654,15 +1660,13 @@ xpc_disconnecting_callout(struct xpc_channel *ch) | |||
| 1654 | */ | 1660 | */ |
| 1655 | 1661 | ||
| 1656 | if (ch->func != NULL) { | 1662 | if (ch->func != NULL) { |
| 1657 | dev_dbg(xpc_chan, "ch->func() called, reason=xpcDisconnecting," | 1663 | dev_dbg(xpc_chan, "ch->func() called, reason=%d, partid=%d, " |
| 1658 | " partid=%d, channel=%d\n", ch->partid, ch->number); | 1664 | "channel=%d\n", reason, ch->partid, ch->number); |
| 1659 | 1665 | ||
| 1660 | ch->func(xpcDisconnecting, ch->partid, ch->number, NULL, | 1666 | ch->func(reason, ch->partid, ch->number, NULL, ch->key); |
| 1661 | ch->key); | ||
| 1662 | 1667 | ||
| 1663 | dev_dbg(xpc_chan, "ch->func() returned, reason=" | 1668 | dev_dbg(xpc_chan, "ch->func() returned, reason=%d, partid=%d, " |
| 1664 | "xpcDisconnecting, partid=%d, channel=%d\n", | 1669 | "channel=%d\n", reason, ch->partid, ch->number); |
| 1665 | ch->partid, ch->number); | ||
| 1666 | } | 1670 | } |
| 1667 | } | 1671 | } |
| 1668 | 1672 | ||
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c index b617236524c6..8930586e0eb4 100644 --- a/arch/ia64/sn/kernel/xpc_main.c +++ b/arch/ia64/sn/kernel/xpc_main.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. | 6 | * Copyright (c) 2004-2006 Silicon Graphics, Inc. All Rights Reserved. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | 9 | ||
| @@ -59,7 +59,7 @@ | |||
| 59 | #include <asm/sn/sn_sal.h> | 59 | #include <asm/sn/sn_sal.h> |
| 60 | #include <asm/kdebug.h> | 60 | #include <asm/kdebug.h> |
| 61 | #include <asm/uaccess.h> | 61 | #include <asm/uaccess.h> |
| 62 | #include "xpc.h" | 62 | #include <asm/sn/xpc.h> |
| 63 | 63 | ||
| 64 | 64 | ||
| 65 | /* define two XPC debug device structures to be used with dev_dbg() et al */ | 65 | /* define two XPC debug device structures to be used with dev_dbg() et al */ |
| @@ -82,6 +82,9 @@ struct device *xpc_part = &xpc_part_dbg_subname; | |||
| 82 | struct device *xpc_chan = &xpc_chan_dbg_subname; | 82 | struct device *xpc_chan = &xpc_chan_dbg_subname; |
| 83 | 83 | ||
| 84 | 84 | ||
| 85 | static int xpc_kdebug_ignore; | ||
| 86 | |||
| 87 | |||
| 85 | /* systune related variables for /proc/sys directories */ | 88 | /* systune related variables for /proc/sys directories */ |
| 86 | 89 | ||
| 87 | static int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL; | 90 | static int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL; |
| @@ -162,6 +165,8 @@ static ctl_table xpc_sys_dir[] = { | |||
| 162 | }; | 165 | }; |
| 163 | static struct ctl_table_header *xpc_sysctl; | 166 | static struct ctl_table_header *xpc_sysctl; |
| 164 | 167 | ||
| 168 | /* non-zero if any remote partition disengage request was timed out */ | ||
| 169 | int xpc_disengage_request_timedout; | ||
| 165 | 170 | ||
| 166 | /* #of IRQs received */ | 171 | /* #of IRQs received */ |
| 167 | static atomic_t xpc_act_IRQ_rcvd; | 172 | static atomic_t xpc_act_IRQ_rcvd; |
| @@ -773,7 +778,7 @@ xpc_daemonize_kthread(void *args) | |||
| 773 | ch->flags |= XPC_C_DISCONNECTCALLOUT; | 778 | ch->flags |= XPC_C_DISCONNECTCALLOUT; |
| 774 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 779 | spin_unlock_irqrestore(&ch->lock, irq_flags); |
| 775 | 780 | ||
| 776 | xpc_disconnecting_callout(ch); | 781 | xpc_disconnect_callout(ch, xpcDisconnecting); |
| 777 | } else { | 782 | } else { |
| 778 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 783 | spin_unlock_irqrestore(&ch->lock, irq_flags); |
| 779 | } | 784 | } |
| @@ -921,9 +926,9 @@ static void | |||
| 921 | xpc_do_exit(enum xpc_retval reason) | 926 | xpc_do_exit(enum xpc_retval reason) |
| 922 | { | 927 | { |
| 923 | partid_t partid; | 928 | partid_t partid; |
| 924 | int active_part_count; | 929 | int active_part_count, printed_waiting_msg = 0; |
| 925 | struct xpc_partition *part; | 930 | struct xpc_partition *part; |
| 926 | unsigned long printmsg_time; | 931 | unsigned long printmsg_time, disengage_request_timeout = 0; |
| 927 | 932 | ||
| 928 | 933 | ||
| 929 | /* a 'rmmod XPC' and a 'reboot' cannot both end up here together */ | 934 | /* a 'rmmod XPC' and a 'reboot' cannot both end up here together */ |
| @@ -953,7 +958,8 @@ xpc_do_exit(enum xpc_retval reason) | |||
| 953 | 958 | ||
| 954 | /* wait for all partitions to become inactive */ | 959 | /* wait for all partitions to become inactive */ |
| 955 | 960 | ||
| 956 | printmsg_time = jiffies; | 961 | printmsg_time = jiffies + (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ); |
| 962 | xpc_disengage_request_timedout = 0; | ||
| 957 | 963 | ||
| 958 | do { | 964 | do { |
| 959 | active_part_count = 0; | 965 | active_part_count = 0; |
| @@ -969,20 +975,39 @@ xpc_do_exit(enum xpc_retval reason) | |||
| 969 | active_part_count++; | 975 | active_part_count++; |
| 970 | 976 | ||
| 971 | XPC_DEACTIVATE_PARTITION(part, reason); | 977 | XPC_DEACTIVATE_PARTITION(part, reason); |
| 972 | } | ||
| 973 | 978 | ||
| 974 | if (active_part_count == 0) { | 979 | if (part->disengage_request_timeout > |
| 975 | break; | 980 | disengage_request_timeout) { |
| 981 | disengage_request_timeout = | ||
| 982 | part->disengage_request_timeout; | ||
| 983 | } | ||
| 976 | } | 984 | } |
| 977 | 985 | ||
| 978 | if (jiffies >= printmsg_time) { | 986 | if (xpc_partition_engaged(-1UL)) { |
| 979 | dev_info(xpc_part, "waiting for partitions to " | 987 | if (time_after(jiffies, printmsg_time)) { |
| 980 | "deactivate/disengage, active count=%d, remote " | 988 | dev_info(xpc_part, "waiting for remote " |
| 981 | "engaged=0x%lx\n", active_part_count, | 989 | "partitions to disengage, timeout in " |
| 982 | xpc_partition_engaged(1UL << partid)); | 990 | "%ld seconds\n", |
| 983 | 991 | (disengage_request_timeout - jiffies) | |
| 984 | printmsg_time = jiffies + | 992 | / HZ); |
| 993 | printmsg_time = jiffies + | ||
| 985 | (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ); | 994 | (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ); |
| 995 | printed_waiting_msg = 1; | ||
| 996 | } | ||
| 997 | |||
| 998 | } else if (active_part_count > 0) { | ||
| 999 | if (printed_waiting_msg) { | ||
| 1000 | dev_info(xpc_part, "waiting for local partition" | ||
| 1001 | " to disengage\n"); | ||
| 1002 | printed_waiting_msg = 0; | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | } else { | ||
| 1006 | if (!xpc_disengage_request_timedout) { | ||
| 1007 | dev_info(xpc_part, "all partitions have " | ||
| 1008 | "disengaged\n"); | ||
| 1009 | } | ||
| 1010 | break; | ||
| 986 | } | 1011 | } |
| 987 | 1012 | ||
| 988 | /* sleep for a 1/3 of a second or so */ | 1013 | /* sleep for a 1/3 of a second or so */ |
| @@ -1000,11 +1025,13 @@ xpc_do_exit(enum xpc_retval reason) | |||
| 1000 | del_timer_sync(&xpc_hb_timer); | 1025 | del_timer_sync(&xpc_hb_timer); |
| 1001 | DBUG_ON(xpc_vars->heartbeating_to_mask != 0); | 1026 | DBUG_ON(xpc_vars->heartbeating_to_mask != 0); |
| 1002 | 1027 | ||
| 1003 | /* take ourselves off of the reboot_notifier_list */ | 1028 | if (reason == xpcUnloading) { |
| 1004 | (void) unregister_reboot_notifier(&xpc_reboot_notifier); | 1029 | /* take ourselves off of the reboot_notifier_list */ |
| 1030 | (void) unregister_reboot_notifier(&xpc_reboot_notifier); | ||
| 1005 | 1031 | ||
| 1006 | /* take ourselves off of the die_notifier list */ | 1032 | /* take ourselves off of the die_notifier list */ |
| 1007 | (void) unregister_die_notifier(&xpc_die_notifier); | 1033 | (void) unregister_die_notifier(&xpc_die_notifier); |
| 1034 | } | ||
| 1008 | 1035 | ||
| 1009 | /* close down protections for IPI operations */ | 1036 | /* close down protections for IPI operations */ |
| 1010 | xpc_restrict_IPI_ops(); | 1037 | xpc_restrict_IPI_ops(); |
| @@ -1020,7 +1047,35 @@ xpc_do_exit(enum xpc_retval reason) | |||
| 1020 | 1047 | ||
| 1021 | 1048 | ||
| 1022 | /* | 1049 | /* |
| 1023 | * Called when the system is about to be either restarted or halted. | 1050 | * This function is called when the system is being rebooted. |
| 1051 | */ | ||
| 1052 | static int | ||
| 1053 | xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused) | ||
| 1054 | { | ||
| 1055 | enum xpc_retval reason; | ||
| 1056 | |||
| 1057 | |||
| 1058 | switch (event) { | ||
| 1059 | case SYS_RESTART: | ||
| 1060 | reason = xpcSystemReboot; | ||
| 1061 | break; | ||
| 1062 | case SYS_HALT: | ||
| 1063 | reason = xpcSystemHalt; | ||
| 1064 | break; | ||
| 1065 | case SYS_POWER_OFF: | ||
| 1066 | reason = xpcSystemPoweroff; | ||
| 1067 | break; | ||
| 1068 | default: | ||
| 1069 | reason = xpcSystemGoingDown; | ||
| 1070 | } | ||
| 1071 | |||
| 1072 | xpc_do_exit(reason); | ||
| 1073 | return NOTIFY_DONE; | ||
| 1074 | } | ||
| 1075 | |||
| 1076 | |||
| 1077 | /* | ||
| 1078 | * Notify other partitions to disengage from all references to our memory. | ||
| 1024 | */ | 1079 | */ |
| 1025 | static void | 1080 | static void |
| 1026 | xpc_die_disengage(void) | 1081 | xpc_die_disengage(void) |
| @@ -1028,7 +1083,7 @@ xpc_die_disengage(void) | |||
| 1028 | struct xpc_partition *part; | 1083 | struct xpc_partition *part; |
| 1029 | partid_t partid; | 1084 | partid_t partid; |
| 1030 | unsigned long engaged; | 1085 | unsigned long engaged; |
| 1031 | long time, print_time, disengage_request_timeout; | 1086 | long time, printmsg_time, disengage_request_timeout; |
| 1032 | 1087 | ||
| 1033 | 1088 | ||
| 1034 | /* keep xpc_hb_checker thread from doing anything (just in case) */ | 1089 | /* keep xpc_hb_checker thread from doing anything (just in case) */ |
| @@ -1055,57 +1110,53 @@ xpc_die_disengage(void) | |||
| 1055 | } | 1110 | } |
| 1056 | } | 1111 | } |
| 1057 | 1112 | ||
| 1058 | print_time = rtc_time(); | 1113 | time = rtc_time(); |
| 1059 | disengage_request_timeout = print_time + | 1114 | printmsg_time = time + |
| 1115 | (XPC_DISENGAGE_PRINTMSG_INTERVAL * sn_rtc_cycles_per_second); | ||
| 1116 | disengage_request_timeout = time + | ||
| 1060 | (xpc_disengage_request_timelimit * sn_rtc_cycles_per_second); | 1117 | (xpc_disengage_request_timelimit * sn_rtc_cycles_per_second); |
| 1061 | 1118 | ||
| 1062 | /* wait for all other partitions to disengage from us */ | 1119 | /* wait for all other partitions to disengage from us */ |
| 1063 | 1120 | ||
| 1064 | while ((engaged = xpc_partition_engaged(-1UL)) && | 1121 | while (1) { |
| 1065 | (time = rtc_time()) < disengage_request_timeout) { | 1122 | engaged = xpc_partition_engaged(-1UL); |
| 1123 | if (!engaged) { | ||
| 1124 | dev_info(xpc_part, "all partitions have disengaged\n"); | ||
| 1125 | break; | ||
| 1126 | } | ||
| 1066 | 1127 | ||
| 1067 | if (time >= print_time) { | 1128 | time = rtc_time(); |
| 1129 | if (time >= disengage_request_timeout) { | ||
| 1130 | for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { | ||
| 1131 | if (engaged & (1UL << partid)) { | ||
| 1132 | dev_info(xpc_part, "disengage from " | ||
| 1133 | "remote partition %d timed " | ||
| 1134 | "out\n", partid); | ||
| 1135 | } | ||
| 1136 | } | ||
| 1137 | break; | ||
| 1138 | } | ||
| 1139 | |||
| 1140 | if (time >= printmsg_time) { | ||
| 1068 | dev_info(xpc_part, "waiting for remote partitions to " | 1141 | dev_info(xpc_part, "waiting for remote partitions to " |
| 1069 | "disengage, engaged=0x%lx\n", engaged); | 1142 | "disengage, timeout in %ld seconds\n", |
| 1070 | print_time = time + (XPC_DISENGAGE_PRINTMSG_INTERVAL * | 1143 | (disengage_request_timeout - time) / |
| 1144 | sn_rtc_cycles_per_second); | ||
| 1145 | printmsg_time = time + | ||
| 1146 | (XPC_DISENGAGE_PRINTMSG_INTERVAL * | ||
| 1071 | sn_rtc_cycles_per_second); | 1147 | sn_rtc_cycles_per_second); |
| 1072 | } | 1148 | } |
| 1073 | } | 1149 | } |
| 1074 | dev_info(xpc_part, "finished waiting for remote partitions to " | ||
| 1075 | "disengage, engaged=0x%lx\n", engaged); | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | |||
| 1079 | /* | ||
| 1080 | * This function is called when the system is being rebooted. | ||
| 1081 | */ | ||
| 1082 | static int | ||
| 1083 | xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused) | ||
| 1084 | { | ||
| 1085 | enum xpc_retval reason; | ||
| 1086 | |||
| 1087 | |||
| 1088 | switch (event) { | ||
| 1089 | case SYS_RESTART: | ||
| 1090 | reason = xpcSystemReboot; | ||
| 1091 | break; | ||
| 1092 | case SYS_HALT: | ||
| 1093 | reason = xpcSystemHalt; | ||
| 1094 | break; | ||
| 1095 | case SYS_POWER_OFF: | ||
| 1096 | reason = xpcSystemPoweroff; | ||
| 1097 | break; | ||
| 1098 | default: | ||
| 1099 | reason = xpcSystemGoingDown; | ||
| 1100 | } | ||
| 1101 | |||
| 1102 | xpc_do_exit(reason); | ||
| 1103 | return NOTIFY_DONE; | ||
| 1104 | } | 1150 | } |
| 1105 | 1151 | ||
| 1106 | 1152 | ||
| 1107 | /* | 1153 | /* |
| 1108 | * This function is called when the system is being rebooted. | 1154 | * This function is called when the system is being restarted or halted due |
| 1155 | * to some sort of system failure. If this is the case we need to notify the | ||
| 1156 | * other partitions to disengage from all references to our memory. | ||
| 1157 | * This function can also be called when our heartbeater could be offlined | ||
| 1158 | * for a time. In this case we need to notify other partitions to not worry | ||
| 1159 | * about the lack of a heartbeat. | ||
| 1109 | */ | 1160 | */ |
| 1110 | static int | 1161 | static int |
| 1111 | xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused) | 1162 | xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused) |
| @@ -1115,11 +1166,25 @@ xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused) | |||
| 1115 | case DIE_MACHINE_HALT: | 1166 | case DIE_MACHINE_HALT: |
| 1116 | xpc_die_disengage(); | 1167 | xpc_die_disengage(); |
| 1117 | break; | 1168 | break; |
| 1169 | |||
| 1170 | case DIE_KDEBUG_ENTER: | ||
| 1171 | /* Should lack of heartbeat be ignored by other partitions? */ | ||
| 1172 | if (!xpc_kdebug_ignore) { | ||
| 1173 | break; | ||
| 1174 | } | ||
| 1175 | /* fall through */ | ||
| 1118 | case DIE_MCA_MONARCH_ENTER: | 1176 | case DIE_MCA_MONARCH_ENTER: |
| 1119 | case DIE_INIT_MONARCH_ENTER: | 1177 | case DIE_INIT_MONARCH_ENTER: |
| 1120 | xpc_vars->heartbeat++; | 1178 | xpc_vars->heartbeat++; |
| 1121 | xpc_vars->heartbeat_offline = 1; | 1179 | xpc_vars->heartbeat_offline = 1; |
| 1122 | break; | 1180 | break; |
| 1181 | |||
| 1182 | case DIE_KDEBUG_LEAVE: | ||
| 1183 | /* Is lack of heartbeat being ignored by other partitions? */ | ||
| 1184 | if (!xpc_kdebug_ignore) { | ||
| 1185 | break; | ||
| 1186 | } | ||
| 1187 | /* fall through */ | ||
| 1123 | case DIE_MCA_MONARCH_LEAVE: | 1188 | case DIE_MCA_MONARCH_LEAVE: |
| 1124 | case DIE_INIT_MONARCH_LEAVE: | 1189 | case DIE_INIT_MONARCH_LEAVE: |
| 1125 | xpc_vars->heartbeat++; | 1190 | xpc_vars->heartbeat++; |
| @@ -1344,3 +1409,7 @@ module_param(xpc_disengage_request_timelimit, int, 0); | |||
| 1344 | MODULE_PARM_DESC(xpc_disengage_request_timelimit, "Number of seconds to wait " | 1409 | MODULE_PARM_DESC(xpc_disengage_request_timelimit, "Number of seconds to wait " |
| 1345 | "for disengage request to complete."); | 1410 | "for disengage request to complete."); |
| 1346 | 1411 | ||
| 1412 | module_param(xpc_kdebug_ignore, int, 0); | ||
| 1413 | MODULE_PARM_DESC(xpc_kdebug_ignore, "Should lack of heartbeat be ignored by " | ||
| 1414 | "other partitions when dropping into kdebug."); | ||
| 1415 | |||
diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c index cdd6431853a1..88a730e6cfdb 100644 --- a/arch/ia64/sn/kernel/xpc_partition.c +++ b/arch/ia64/sn/kernel/xpc_partition.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. | 6 | * Copyright (c) 2004-2006 Silicon Graphics, Inc. All Rights Reserved. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | 9 | ||
| @@ -28,7 +28,7 @@ | |||
| 28 | #include <asm/sn/sn_sal.h> | 28 | #include <asm/sn/sn_sal.h> |
| 29 | #include <asm/sn/nodepda.h> | 29 | #include <asm/sn/nodepda.h> |
| 30 | #include <asm/sn/addrs.h> | 30 | #include <asm/sn/addrs.h> |
| 31 | #include "xpc.h" | 31 | #include <asm/sn/xpc.h> |
| 32 | 32 | ||
| 33 | 33 | ||
| 34 | /* XPC is exiting flag */ | 34 | /* XPC is exiting flag */ |
| @@ -771,7 +771,8 @@ xpc_identify_act_IRQ_req(int nasid) | |||
| 771 | } | 771 | } |
| 772 | } | 772 | } |
| 773 | 773 | ||
| 774 | if (!xpc_partition_disengaged(part)) { | 774 | if (part->disengage_request_timeout > 0 && |
| 775 | !xpc_partition_disengaged(part)) { | ||
| 775 | /* still waiting on other side to disengage from us */ | 776 | /* still waiting on other side to disengage from us */ |
| 776 | return; | 777 | return; |
| 777 | } | 778 | } |
| @@ -873,6 +874,9 @@ xpc_partition_disengaged(struct xpc_partition *part) | |||
| 873 | * request in a timely fashion, so assume it's dead. | 874 | * request in a timely fashion, so assume it's dead. |
| 874 | */ | 875 | */ |
| 875 | 876 | ||
| 877 | dev_info(xpc_part, "disengage from remote partition %d " | ||
| 878 | "timed out\n", partid); | ||
| 879 | xpc_disengage_request_timedout = 1; | ||
| 876 | xpc_clear_partition_engaged(1UL << partid); | 880 | xpc_clear_partition_engaged(1UL << partid); |
| 877 | disengaged = 1; | 881 | disengaged = 1; |
| 878 | } | 882 | } |
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_ate.c b/arch/ia64/sn/pci/pcibr/pcibr_ate.c index d1647b863e61..aa3fa5152a32 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_ate.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_ate.c | |||
| @@ -18,10 +18,10 @@ int pcibr_invalidate_ate = 0; /* by default don't invalidate ATE on free */ | |||
| 18 | * mark_ate: Mark the ate as either free or inuse. | 18 | * mark_ate: Mark the ate as either free or inuse. |
| 19 | */ | 19 | */ |
| 20 | static void mark_ate(struct ate_resource *ate_resource, int start, int number, | 20 | static void mark_ate(struct ate_resource *ate_resource, int start, int number, |
| 21 | uint64_t value) | 21 | u64 value) |
| 22 | { | 22 | { |
| 23 | 23 | ||
| 24 | uint64_t *ate = ate_resource->ate; | 24 | u64 *ate = ate_resource->ate; |
| 25 | int index; | 25 | int index; |
| 26 | int length = 0; | 26 | int length = 0; |
| 27 | 27 | ||
| @@ -38,7 +38,7 @@ static int find_free_ate(struct ate_resource *ate_resource, int start, | |||
| 38 | int count) | 38 | int count) |
| 39 | { | 39 | { |
| 40 | 40 | ||
| 41 | uint64_t *ate = ate_resource->ate; | 41 | u64 *ate = ate_resource->ate; |
| 42 | int index; | 42 | int index; |
| 43 | int start_free; | 43 | int start_free; |
| 44 | 44 | ||
| @@ -119,7 +119,7 @@ static inline int alloc_ate_resource(struct ate_resource *ate_resource, | |||
| 119 | int pcibr_ate_alloc(struct pcibus_info *pcibus_info, int count) | 119 | int pcibr_ate_alloc(struct pcibus_info *pcibus_info, int count) |
| 120 | { | 120 | { |
| 121 | int status = 0; | 121 | int status = 0; |
| 122 | uint64_t flag; | 122 | u64 flag; |
| 123 | 123 | ||
| 124 | flag = pcibr_lock(pcibus_info); | 124 | flag = pcibr_lock(pcibus_info); |
| 125 | status = alloc_ate_resource(&pcibus_info->pbi_int_ate_resource, count); | 125 | status = alloc_ate_resource(&pcibus_info->pbi_int_ate_resource, count); |
| @@ -139,7 +139,7 @@ int pcibr_ate_alloc(struct pcibus_info *pcibus_info, int count) | |||
| 139 | * Setup an Address Translation Entry as specified. Use either the Bridge | 139 | * Setup an Address Translation Entry as specified. Use either the Bridge |
| 140 | * internal maps or the external map RAM, as appropriate. | 140 | * internal maps or the external map RAM, as appropriate. |
| 141 | */ | 141 | */ |
| 142 | static inline uint64_t *pcibr_ate_addr(struct pcibus_info *pcibus_info, | 142 | static inline u64 *pcibr_ate_addr(struct pcibus_info *pcibus_info, |
| 143 | int ate_index) | 143 | int ate_index) |
| 144 | { | 144 | { |
| 145 | if (ate_index < pcibus_info->pbi_int_ate_size) { | 145 | if (ate_index < pcibus_info->pbi_int_ate_size) { |
| @@ -153,7 +153,7 @@ static inline uint64_t *pcibr_ate_addr(struct pcibus_info *pcibus_info, | |||
| 153 | */ | 153 | */ |
| 154 | void inline | 154 | void inline |
| 155 | ate_write(struct pcibus_info *pcibus_info, int ate_index, int count, | 155 | ate_write(struct pcibus_info *pcibus_info, int ate_index, int count, |
| 156 | volatile uint64_t ate) | 156 | volatile u64 ate) |
| 157 | { | 157 | { |
| 158 | while (count-- > 0) { | 158 | while (count-- > 0) { |
| 159 | if (ate_index < pcibus_info->pbi_int_ate_size) { | 159 | if (ate_index < pcibus_info->pbi_int_ate_size) { |
| @@ -171,9 +171,9 @@ ate_write(struct pcibus_info *pcibus_info, int ate_index, int count, | |||
| 171 | void pcibr_ate_free(struct pcibus_info *pcibus_info, int index) | 171 | void pcibr_ate_free(struct pcibus_info *pcibus_info, int index) |
| 172 | { | 172 | { |
| 173 | 173 | ||
| 174 | volatile uint64_t ate; | 174 | volatile u64 ate; |
| 175 | int count; | 175 | int count; |
| 176 | uint64_t flags; | 176 | u64 flags; |
| 177 | 177 | ||
| 178 | if (pcibr_invalidate_ate) { | 178 | if (pcibr_invalidate_ate) { |
| 179 | /* For debugging purposes, clear the valid bit in the ATE */ | 179 | /* For debugging purposes, clear the valid bit in the ATE */ |
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c index 34093476e965..54ce5b7ceed2 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c | |||
| @@ -41,21 +41,21 @@ extern int sn_ioif_inited; | |||
| 41 | 41 | ||
| 42 | static dma_addr_t | 42 | static dma_addr_t |
| 43 | pcibr_dmamap_ate32(struct pcidev_info *info, | 43 | pcibr_dmamap_ate32(struct pcidev_info *info, |
| 44 | uint64_t paddr, size_t req_size, uint64_t flags) | 44 | u64 paddr, size_t req_size, u64 flags) |
| 45 | { | 45 | { |
| 46 | 46 | ||
| 47 | struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; | 47 | struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; |
| 48 | struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info-> | 48 | struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info-> |
| 49 | pdi_pcibus_info; | 49 | pdi_pcibus_info; |
| 50 | uint8_t internal_device = (PCI_SLOT(pcidev_info->pdi_host_pcidev_info-> | 50 | u8 internal_device = (PCI_SLOT(pcidev_info->pdi_host_pcidev_info-> |
| 51 | pdi_linux_pcidev->devfn)) - 1; | 51 | pdi_linux_pcidev->devfn)) - 1; |
| 52 | int ate_count; | 52 | int ate_count; |
| 53 | int ate_index; | 53 | int ate_index; |
| 54 | uint64_t ate_flags = flags | PCI32_ATE_V; | 54 | u64 ate_flags = flags | PCI32_ATE_V; |
| 55 | uint64_t ate; | 55 | u64 ate; |
| 56 | uint64_t pci_addr; | 56 | u64 pci_addr; |
| 57 | uint64_t xio_addr; | 57 | u64 xio_addr; |
| 58 | uint64_t offset; | 58 | u64 offset; |
| 59 | 59 | ||
| 60 | /* PIC in PCI-X mode does not supports 32bit PageMap mode */ | 60 | /* PIC in PCI-X mode does not supports 32bit PageMap mode */ |
| 61 | if (IS_PIC_SOFT(pcibus_info) && IS_PCIX(pcibus_info)) { | 61 | if (IS_PIC_SOFT(pcibus_info) && IS_PCIX(pcibus_info)) { |
| @@ -109,12 +109,12 @@ pcibr_dmamap_ate32(struct pcidev_info *info, | |||
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | static dma_addr_t | 111 | static dma_addr_t |
| 112 | pcibr_dmatrans_direct64(struct pcidev_info * info, uint64_t paddr, | 112 | pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr, |
| 113 | uint64_t dma_attributes) | 113 | u64 dma_attributes) |
| 114 | { | 114 | { |
| 115 | struct pcibus_info *pcibus_info = (struct pcibus_info *) | 115 | struct pcibus_info *pcibus_info = (struct pcibus_info *) |
| 116 | ((info->pdi_host_pcidev_info)->pdi_pcibus_info); | 116 | ((info->pdi_host_pcidev_info)->pdi_pcibus_info); |
| 117 | uint64_t pci_addr; | 117 | u64 pci_addr; |
| 118 | 118 | ||
| 119 | /* Translate to Crosstalk View of Physical Address */ | 119 | /* Translate to Crosstalk View of Physical Address */ |
| 120 | pci_addr = (IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : | 120 | pci_addr = (IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : |
| @@ -127,7 +127,7 @@ pcibr_dmatrans_direct64(struct pcidev_info * info, uint64_t paddr, | |||
| 127 | /* Handle Bridge Chipset differences */ | 127 | /* Handle Bridge Chipset differences */ |
| 128 | if (IS_PIC_SOFT(pcibus_info)) { | 128 | if (IS_PIC_SOFT(pcibus_info)) { |
| 129 | pci_addr |= | 129 | pci_addr |= |
| 130 | ((uint64_t) pcibus_info-> | 130 | ((u64) pcibus_info-> |
| 131 | pbi_hub_xid << PIC_PCI64_ATTR_TARG_SHFT); | 131 | pbi_hub_xid << PIC_PCI64_ATTR_TARG_SHFT); |
| 132 | } else | 132 | } else |
| 133 | pci_addr |= TIOCP_PCI64_CMDTYPE_MEM; | 133 | pci_addr |= TIOCP_PCI64_CMDTYPE_MEM; |
| @@ -142,17 +142,17 @@ pcibr_dmatrans_direct64(struct pcidev_info * info, uint64_t paddr, | |||
| 142 | 142 | ||
| 143 | static dma_addr_t | 143 | static dma_addr_t |
| 144 | pcibr_dmatrans_direct32(struct pcidev_info * info, | 144 | pcibr_dmatrans_direct32(struct pcidev_info * info, |
| 145 | uint64_t paddr, size_t req_size, uint64_t flags) | 145 | u64 paddr, size_t req_size, u64 flags) |
| 146 | { | 146 | { |
| 147 | 147 | ||
| 148 | struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; | 148 | struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; |
| 149 | struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info-> | 149 | struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info-> |
| 150 | pdi_pcibus_info; | 150 | pdi_pcibus_info; |
| 151 | uint64_t xio_addr; | 151 | u64 xio_addr; |
| 152 | 152 | ||
| 153 | uint64_t xio_base; | 153 | u64 xio_base; |
| 154 | uint64_t offset; | 154 | u64 offset; |
| 155 | uint64_t endoff; | 155 | u64 endoff; |
| 156 | 156 | ||
| 157 | if (IS_PCIX(pcibus_info)) { | 157 | if (IS_PCIX(pcibus_info)) { |
| 158 | return 0; | 158 | return 0; |
| @@ -209,16 +209,18 @@ pcibr_dma_unmap(struct pci_dev *hwdev, dma_addr_t dma_handle, int direction) | |||
| 209 | * unlike the PIC Device(x) Write Request Buffer Flush register. | 209 | * unlike the PIC Device(x) Write Request Buffer Flush register. |
| 210 | */ | 210 | */ |
| 211 | 211 | ||
| 212 | void sn_dma_flush(uint64_t addr) | 212 | void sn_dma_flush(u64 addr) |
| 213 | { | 213 | { |
| 214 | nasid_t nasid; | 214 | nasid_t nasid; |
| 215 | int is_tio; | 215 | int is_tio; |
| 216 | int wid_num; | 216 | int wid_num; |
| 217 | int i, j; | 217 | int i, j; |
| 218 | uint64_t flags; | 218 | u64 flags; |
| 219 | uint64_t itte; | 219 | u64 itte; |
| 220 | struct hubdev_info *hubinfo; | 220 | struct hubdev_info *hubinfo; |
| 221 | volatile struct sn_flush_device_list *p; | 221 | volatile struct sn_flush_device_kernel *p; |
| 222 | volatile struct sn_flush_device_common *common; | ||
| 223 | |||
| 222 | struct sn_flush_nasid_entry *flush_nasid_list; | 224 | struct sn_flush_nasid_entry *flush_nasid_list; |
| 223 | 225 | ||
| 224 | if (!sn_ioif_inited) | 226 | if (!sn_ioif_inited) |
| @@ -268,17 +270,17 @@ void sn_dma_flush(uint64_t addr) | |||
| 268 | p = &flush_nasid_list->widget_p[wid_num][0]; | 270 | p = &flush_nasid_list->widget_p[wid_num][0]; |
| 269 | 271 | ||
| 270 | /* find a matching BAR */ | 272 | /* find a matching BAR */ |
| 271 | for (i = 0; i < DEV_PER_WIDGET; i++) { | 273 | for (i = 0; i < DEV_PER_WIDGET; i++,p++) { |
| 274 | common = p->common; | ||
| 272 | for (j = 0; j < PCI_ROM_RESOURCE; j++) { | 275 | for (j = 0; j < PCI_ROM_RESOURCE; j++) { |
| 273 | if (p->sfdl_bar_list[j].start == 0) | 276 | if (common->sfdl_bar_list[j].start == 0) |
| 274 | break; | 277 | break; |
| 275 | if (addr >= p->sfdl_bar_list[j].start | 278 | if (addr >= common->sfdl_bar_list[j].start |
| 276 | && addr <= p->sfdl_bar_list[j].end) | 279 | && addr <= common->sfdl_bar_list[j].end) |
| 277 | break; | 280 | break; |
| 278 | } | 281 | } |
| 279 | if (j < PCI_ROM_RESOURCE && p->sfdl_bar_list[j].start != 0) | 282 | if (j < PCI_ROM_RESOURCE && common->sfdl_bar_list[j].start != 0) |
| 280 | break; | 283 | break; |
| 281 | p++; | ||
| 282 | } | 284 | } |
| 283 | 285 | ||
| 284 | /* if no matching BAR, return without doing anything. */ | 286 | /* if no matching BAR, return without doing anything. */ |
| @@ -297,31 +299,31 @@ void sn_dma_flush(uint64_t addr) | |||
| 297 | * If CE ever needs the sn_dma_flush mechanism, we will have | 299 | * If CE ever needs the sn_dma_flush mechanism, we will have |
| 298 | * to account for that here and in tioce_bus_fixup(). | 300 | * to account for that here and in tioce_bus_fixup(). |
| 299 | */ | 301 | */ |
| 300 | uint32_t tio_id = HUB_L(TIO_IOSPACE_ADDR(nasid, TIO_NODE_ID)); | 302 | u32 tio_id = HUB_L(TIO_IOSPACE_ADDR(nasid, TIO_NODE_ID)); |
| 301 | uint32_t revnum = XWIDGET_PART_REV_NUM(tio_id); | 303 | u32 revnum = XWIDGET_PART_REV_NUM(tio_id); |
| 302 | 304 | ||
| 303 | /* TIOCP BRINGUP WAR (PV907516): Don't write buffer flush reg */ | 305 | /* TIOCP BRINGUP WAR (PV907516): Don't write buffer flush reg */ |
| 304 | if ((1 << XWIDGET_PART_REV_NUM_REV(revnum)) & PV907516) { | 306 | if ((1 << XWIDGET_PART_REV_NUM_REV(revnum)) & PV907516) { |
| 305 | return; | 307 | return; |
| 306 | } else { | 308 | } else { |
| 307 | pcireg_wrb_flush_get(p->sfdl_pcibus_info, | 309 | pcireg_wrb_flush_get(common->sfdl_pcibus_info, |
| 308 | (p->sfdl_slot - 1)); | 310 | (common->sfdl_slot - 1)); |
| 309 | } | 311 | } |
| 310 | } else { | 312 | } else { |
| 311 | spin_lock_irqsave(&((struct sn_flush_device_list *)p)-> | 313 | spin_lock_irqsave((spinlock_t *)&p->sfdl_flush_lock, |
| 312 | sfdl_flush_lock, flags); | 314 | flags); |
| 313 | 315 | *common->sfdl_flush_addr = 0; | |
| 314 | *p->sfdl_flush_addr = 0; | ||
| 315 | 316 | ||
| 316 | /* force an interrupt. */ | 317 | /* force an interrupt. */ |
| 317 | *(volatile uint32_t *)(p->sfdl_force_int_addr) = 1; | 318 | *(volatile u32 *)(common->sfdl_force_int_addr) = 1; |
| 318 | 319 | ||
| 319 | /* wait for the interrupt to come back. */ | 320 | /* wait for the interrupt to come back. */ |
| 320 | while (*(p->sfdl_flush_addr) != 0x10f) | 321 | while (*(common->sfdl_flush_addr) != 0x10f) |
| 321 | cpu_relax(); | 322 | cpu_relax(); |
| 322 | 323 | ||
| 323 | /* okay, everything is synched up. */ | 324 | /* okay, everything is synched up. */ |
| 324 | spin_unlock_irqrestore((spinlock_t *)&p->sfdl_flush_lock, flags); | 325 | spin_unlock_irqrestore((spinlock_t *)&p->sfdl_flush_lock, |
| 326 | flags); | ||
| 325 | } | 327 | } |
| 326 | return; | 328 | return; |
| 327 | } | 329 | } |
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c index 1f500c81002c..77a1262751d3 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c | |||
| @@ -23,7 +23,7 @@ int | |||
| 23 | sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp) | 23 | sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp) |
| 24 | { | 24 | { |
| 25 | struct ia64_sal_retval ret_stuff; | 25 | struct ia64_sal_retval ret_stuff; |
| 26 | uint64_t busnum; | 26 | u64 busnum; |
| 27 | 27 | ||
| 28 | ret_stuff.status = 0; | 28 | ret_stuff.status = 0; |
| 29 | ret_stuff.v0 = 0; | 29 | ret_stuff.v0 = 0; |
| @@ -40,7 +40,7 @@ sal_pcibr_slot_disable(struct pcibus_info *soft, int device, int action, | |||
| 40 | void *resp) | 40 | void *resp) |
| 41 | { | 41 | { |
| 42 | struct ia64_sal_retval ret_stuff; | 42 | struct ia64_sal_retval ret_stuff; |
| 43 | uint64_t busnum; | 43 | u64 busnum; |
| 44 | 44 | ||
| 45 | ret_stuff.status = 0; | 45 | ret_stuff.status = 0; |
| 46 | ret_stuff.v0 = 0; | 46 | ret_stuff.v0 = 0; |
| @@ -56,7 +56,7 @@ sal_pcibr_slot_disable(struct pcibus_info *soft, int device, int action, | |||
| 56 | static int sal_pcibr_error_interrupt(struct pcibus_info *soft) | 56 | static int sal_pcibr_error_interrupt(struct pcibus_info *soft) |
| 57 | { | 57 | { |
| 58 | struct ia64_sal_retval ret_stuff; | 58 | struct ia64_sal_retval ret_stuff; |
| 59 | uint64_t busnum; | 59 | u64 busnum; |
| 60 | int segment; | 60 | int segment; |
| 61 | ret_stuff.status = 0; | 61 | ret_stuff.status = 0; |
| 62 | ret_stuff.v0 = 0; | 62 | ret_stuff.v0 = 0; |
| @@ -92,7 +92,8 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont | |||
| 92 | cnodeid_t near_cnode; | 92 | cnodeid_t near_cnode; |
| 93 | struct hubdev_info *hubdev_info; | 93 | struct hubdev_info *hubdev_info; |
| 94 | struct pcibus_info *soft; | 94 | struct pcibus_info *soft; |
| 95 | struct sn_flush_device_list *sn_flush_device_list; | 95 | struct sn_flush_device_kernel *sn_flush_device_kernel; |
| 96 | struct sn_flush_device_common *common; | ||
| 96 | 97 | ||
| 97 | if (! IS_PCI_BRIDGE_ASIC(prom_bussoft->bs_asic_type)) { | 98 | if (! IS_PCI_BRIDGE_ASIC(prom_bussoft->bs_asic_type)) { |
| 98 | return NULL; | 99 | return NULL; |
| @@ -137,20 +138,19 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont | |||
| 137 | hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); | 138 | hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); |
| 138 | 139 | ||
| 139 | if (hubdev_info->hdi_flush_nasid_list.widget_p) { | 140 | if (hubdev_info->hdi_flush_nasid_list.widget_p) { |
| 140 | sn_flush_device_list = hubdev_info->hdi_flush_nasid_list. | 141 | sn_flush_device_kernel = hubdev_info->hdi_flush_nasid_list. |
| 141 | widget_p[(int)soft->pbi_buscommon.bs_xid]; | 142 | widget_p[(int)soft->pbi_buscommon.bs_xid]; |
| 142 | if (sn_flush_device_list) { | 143 | if (sn_flush_device_kernel) { |
| 143 | for (j = 0; j < DEV_PER_WIDGET; | 144 | for (j = 0; j < DEV_PER_WIDGET; |
| 144 | j++, sn_flush_device_list++) { | 145 | j++, sn_flush_device_kernel++) { |
| 145 | if (sn_flush_device_list->sfdl_slot == -1) | 146 | common = sn_flush_device_kernel->common; |
| 147 | if (common->sfdl_slot == -1) | ||
| 146 | continue; | 148 | continue; |
| 147 | if ((sn_flush_device_list-> | 149 | if ((common->sfdl_persistent_segment == |
| 148 | sfdl_persistent_segment == | ||
| 149 | soft->pbi_buscommon.bs_persist_segment) && | 150 | soft->pbi_buscommon.bs_persist_segment) && |
| 150 | (sn_flush_device_list-> | 151 | (common->sfdl_persistent_busnum == |
| 151 | sfdl_persistent_busnum == | ||
| 152 | soft->pbi_buscommon.bs_persist_busnum)) | 152 | soft->pbi_buscommon.bs_persist_busnum)) |
| 153 | sn_flush_device_list->sfdl_pcibus_info = | 153 | common->sfdl_pcibus_info = |
| 154 | soft; | 154 | soft; |
| 155 | } | 155 | } |
| 156 | } | 156 | } |
| @@ -159,9 +159,9 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont | |||
| 159 | /* Setup the PMU ATE map */ | 159 | /* Setup the PMU ATE map */ |
| 160 | soft->pbi_int_ate_resource.lowest_free_index = 0; | 160 | soft->pbi_int_ate_resource.lowest_free_index = 0; |
| 161 | soft->pbi_int_ate_resource.ate = | 161 | soft->pbi_int_ate_resource.ate = |
| 162 | kmalloc(soft->pbi_int_ate_size * sizeof(uint64_t), GFP_KERNEL); | 162 | kmalloc(soft->pbi_int_ate_size * sizeof(u64), GFP_KERNEL); |
| 163 | memset(soft->pbi_int_ate_resource.ate, 0, | 163 | memset(soft->pbi_int_ate_resource.ate, 0, |
| 164 | (soft->pbi_int_ate_size * sizeof(uint64_t))); | 164 | (soft->pbi_int_ate_size * sizeof(u64))); |
| 165 | 165 | ||
| 166 | if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) { | 166 | if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) { |
| 167 | /* TIO PCI Bridge: find nearest node with CPUs */ | 167 | /* TIO PCI Bridge: find nearest node with CPUs */ |
| @@ -203,7 +203,7 @@ void pcibr_target_interrupt(struct sn_irq_info *sn_irq_info) | |||
| 203 | struct pcidev_info *pcidev_info; | 203 | struct pcidev_info *pcidev_info; |
| 204 | struct pcibus_info *pcibus_info; | 204 | struct pcibus_info *pcibus_info; |
| 205 | int bit = sn_irq_info->irq_int_bit; | 205 | int bit = sn_irq_info->irq_int_bit; |
| 206 | uint64_t xtalk_addr = sn_irq_info->irq_xtalkaddr; | 206 | u64 xtalk_addr = sn_irq_info->irq_xtalkaddr; |
| 207 | 207 | ||
| 208 | pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; | 208 | pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; |
| 209 | if (pcidev_info) { | 209 | if (pcidev_info) { |
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_reg.c b/arch/ia64/sn/pci/pcibr/pcibr_reg.c index 79fdb91d7259..8b8bbd51d433 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_reg.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_reg.c | |||
| @@ -23,7 +23,7 @@ union br_ptr { | |||
| 23 | /* | 23 | /* |
| 24 | * Control Register Access -- Read/Write 0000_0020 | 24 | * Control Register Access -- Read/Write 0000_0020 |
| 25 | */ | 25 | */ |
| 26 | void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits) | 26 | void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, u64 bits) |
| 27 | { | 27 | { |
| 28 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 28 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
| 29 | 29 | ||
| @@ -43,7 +43,7 @@ void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits) | |||
| 43 | } | 43 | } |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | void pcireg_control_bit_set(struct pcibus_info *pcibus_info, uint64_t bits) | 46 | void pcireg_control_bit_set(struct pcibus_info *pcibus_info, u64 bits) |
| 47 | { | 47 | { |
| 48 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 48 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
| 49 | 49 | ||
| @@ -66,10 +66,10 @@ void pcireg_control_bit_set(struct pcibus_info *pcibus_info, uint64_t bits) | |||
| 66 | /* | 66 | /* |
| 67 | * PCI/PCIX Target Flush Register Access -- Read Only 0000_0050 | 67 | * PCI/PCIX Target Flush Register Access -- Read Only 0000_0050 |
| 68 | */ | 68 | */ |
| 69 | uint64_t pcireg_tflush_get(struct pcibus_info *pcibus_info) | 69 | u64 pcireg_tflush_get(struct pcibus_info *pcibus_info) |
| 70 | { | 70 | { |
| 71 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 71 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
| 72 | uint64_t ret = 0; | 72 | u64 ret = 0; |
| 73 | 73 | ||
| 74 | if (pcibus_info) { | 74 | if (pcibus_info) { |
| 75 | switch (pcibus_info->pbi_bridge_type) { | 75 | switch (pcibus_info->pbi_bridge_type) { |
| @@ -96,10 +96,10 @@ uint64_t pcireg_tflush_get(struct pcibus_info *pcibus_info) | |||
| 96 | /* | 96 | /* |
| 97 | * Interrupt Status Register Access -- Read Only 0000_0100 | 97 | * Interrupt Status Register Access -- Read Only 0000_0100 |
| 98 | */ | 98 | */ |
| 99 | uint64_t pcireg_intr_status_get(struct pcibus_info * pcibus_info) | 99 | u64 pcireg_intr_status_get(struct pcibus_info * pcibus_info) |
| 100 | { | 100 | { |
| 101 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 101 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
| 102 | uint64_t ret = 0; | 102 | u64 ret = 0; |
| 103 | 103 | ||
| 104 | if (pcibus_info) { | 104 | if (pcibus_info) { |
| 105 | switch (pcibus_info->pbi_bridge_type) { | 105 | switch (pcibus_info->pbi_bridge_type) { |
| @@ -121,7 +121,7 @@ uint64_t pcireg_intr_status_get(struct pcibus_info * pcibus_info) | |||
| 121 | /* | 121 | /* |
| 122 | * Interrupt Enable Register Access -- Read/Write 0000_0108 | 122 | * Interrupt Enable Register Access -- Read/Write 0000_0108 |
| 123 | */ | 123 | */ |
| 124 | void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits) | 124 | void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, u64 bits) |
| 125 | { | 125 | { |
| 126 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 126 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
| 127 | 127 | ||
| @@ -141,7 +141,7 @@ void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits) | |||
| 141 | } | 141 | } |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, uint64_t bits) | 144 | void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, u64 bits) |
| 145 | { | 145 | { |
| 146 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 146 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
| 147 | 147 | ||
| @@ -165,7 +165,7 @@ void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, uint64_t bits) | |||
| 165 | * Intr Host Address Register (int_addr) -- Read/Write 0000_0130 - 0000_0168 | 165 | * Intr Host Address Register (int_addr) -- Read/Write 0000_0130 - 0000_0168 |
| 166 | */ | 166 | */ |
| 167 | void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n, | 167 | void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n, |
| 168 | uint64_t addr) | 168 | u64 addr) |
| 169 | { | 169 | { |
| 170 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 170 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
| 171 | 171 | ||
| @@ -217,10 +217,10 @@ void pcireg_force_intr_set(struct pcibus_info *pcibus_info, int int_n) | |||
| 217 | /* | 217 | /* |
| 218 | * Device(x) Write Buffer Flush Reg Access -- Read Only 0000_0240 - 0000_0258 | 218 | * Device(x) Write Buffer Flush Reg Access -- Read Only 0000_0240 - 0000_0258 |
| 219 | */ | 219 | */ |
| 220 | uint64_t pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device) | 220 | u64 pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device) |
| 221 | { | 221 | { |
| 222 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 222 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
| 223 | uint64_t ret = 0; | 223 | u64 ret = 0; |
| 224 | 224 | ||
| 225 | if (pcibus_info) { | 225 | if (pcibus_info) { |
| 226 | switch (pcibus_info->pbi_bridge_type) { | 226 | switch (pcibus_info->pbi_bridge_type) { |
| @@ -242,7 +242,7 @@ uint64_t pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device) | |||
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index, | 244 | void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index, |
| 245 | uint64_t val) | 245 | u64 val) |
| 246 | { | 246 | { |
| 247 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 247 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
| 248 | 248 | ||
| @@ -262,10 +262,10 @@ void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index, | |||
| 262 | } | 262 | } |
| 263 | } | 263 | } |
| 264 | 264 | ||
| 265 | uint64_t __iomem *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index) | 265 | u64 __iomem *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index) |
| 266 | { | 266 | { |
| 267 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; | 267 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
| 268 | uint64_t __iomem *ret = NULL; | 268 | u64 __iomem *ret = NULL; |
| 269 | 269 | ||
| 270 | if (pcibus_info) { | 270 | if (pcibus_info) { |
| 271 | switch (pcibus_info->pbi_bridge_type) { | 271 | switch (pcibus_info->pbi_bridge_type) { |
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index 27aa1842dacc..7571a4025529 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | #include <asm/sn/pcibus_provider_defs.h> | 16 | #include <asm/sn/pcibus_provider_defs.h> |
| 17 | #include <asm/sn/tioca_provider.h> | 17 | #include <asm/sn/tioca_provider.h> |
| 18 | 18 | ||
| 19 | uint32_t tioca_gart_found; | 19 | u32 tioca_gart_found; |
| 20 | EXPORT_SYMBOL(tioca_gart_found); /* used by agp-sgi */ | 20 | EXPORT_SYMBOL(tioca_gart_found); /* used by agp-sgi */ |
| 21 | 21 | ||
| 22 | LIST_HEAD(tioca_list); | 22 | LIST_HEAD(tioca_list); |
| @@ -34,8 +34,8 @@ static int tioca_gart_init(struct tioca_kernel *); | |||
| 34 | static int | 34 | static int |
| 35 | tioca_gart_init(struct tioca_kernel *tioca_kern) | 35 | tioca_gart_init(struct tioca_kernel *tioca_kern) |
| 36 | { | 36 | { |
| 37 | uint64_t ap_reg; | 37 | u64 ap_reg; |
| 38 | uint64_t offset; | 38 | u64 offset; |
| 39 | struct page *tmp; | 39 | struct page *tmp; |
| 40 | struct tioca_common *tioca_common; | 40 | struct tioca_common *tioca_common; |
| 41 | struct tioca __iomem *ca_base; | 41 | struct tioca __iomem *ca_base; |
| @@ -214,7 +214,7 @@ void | |||
| 214 | tioca_fastwrite_enable(struct tioca_kernel *tioca_kern) | 214 | tioca_fastwrite_enable(struct tioca_kernel *tioca_kern) |
| 215 | { | 215 | { |
| 216 | int cap_ptr; | 216 | int cap_ptr; |
| 217 | uint32_t reg; | 217 | u32 reg; |
| 218 | struct tioca __iomem *tioca_base; | 218 | struct tioca __iomem *tioca_base; |
| 219 | struct pci_dev *pdev; | 219 | struct pci_dev *pdev; |
| 220 | struct tioca_common *common; | 220 | struct tioca_common *common; |
| @@ -276,7 +276,7 @@ EXPORT_SYMBOL(tioca_fastwrite_enable); /* used by agp-sgi */ | |||
| 276 | * We will always use 0x1 | 276 | * We will always use 0x1 |
| 277 | * 55:55 - Swap bytes Currently unused | 277 | * 55:55 - Swap bytes Currently unused |
| 278 | */ | 278 | */ |
| 279 | static uint64_t | 279 | static u64 |
| 280 | tioca_dma_d64(unsigned long paddr) | 280 | tioca_dma_d64(unsigned long paddr) |
| 281 | { | 281 | { |
| 282 | dma_addr_t bus_addr; | 282 | dma_addr_t bus_addr; |
| @@ -318,15 +318,15 @@ tioca_dma_d64(unsigned long paddr) | |||
| 318 | * and so a given CA can only directly target nodes in the range | 318 | * and so a given CA can only directly target nodes in the range |
| 319 | * xxx - xxx+255. | 319 | * xxx - xxx+255. |
| 320 | */ | 320 | */ |
| 321 | static uint64_t | 321 | static u64 |
| 322 | tioca_dma_d48(struct pci_dev *pdev, uint64_t paddr) | 322 | tioca_dma_d48(struct pci_dev *pdev, u64 paddr) |
| 323 | { | 323 | { |
| 324 | struct tioca_common *tioca_common; | 324 | struct tioca_common *tioca_common; |
| 325 | struct tioca __iomem *ca_base; | 325 | struct tioca __iomem *ca_base; |
| 326 | uint64_t ct_addr; | 326 | u64 ct_addr; |
| 327 | dma_addr_t bus_addr; | 327 | dma_addr_t bus_addr; |
| 328 | uint32_t node_upper; | 328 | u32 node_upper; |
| 329 | uint64_t agp_dma_extn; | 329 | u64 agp_dma_extn; |
| 330 | struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev); | 330 | struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev); |
| 331 | 331 | ||
| 332 | tioca_common = (struct tioca_common *)pcidev_info->pdi_pcibus_info; | 332 | tioca_common = (struct tioca_common *)pcidev_info->pdi_pcibus_info; |
| @@ -367,10 +367,10 @@ tioca_dma_d48(struct pci_dev *pdev, uint64_t paddr) | |||
| 367 | * dma_addr_t is guarenteed to be contiguous in CA bus space. | 367 | * dma_addr_t is guarenteed to be contiguous in CA bus space. |
| 368 | */ | 368 | */ |
| 369 | static dma_addr_t | 369 | static dma_addr_t |
| 370 | tioca_dma_mapped(struct pci_dev *pdev, uint64_t paddr, size_t req_size) | 370 | tioca_dma_mapped(struct pci_dev *pdev, u64 paddr, size_t req_size) |
| 371 | { | 371 | { |
| 372 | int i, ps, ps_shift, entry, entries, mapsize, last_entry; | 372 | int i, ps, ps_shift, entry, entries, mapsize, last_entry; |
| 373 | uint64_t xio_addr, end_xio_addr; | 373 | u64 xio_addr, end_xio_addr; |
| 374 | struct tioca_common *tioca_common; | 374 | struct tioca_common *tioca_common; |
| 375 | struct tioca_kernel *tioca_kern; | 375 | struct tioca_kernel *tioca_kern; |
| 376 | dma_addr_t bus_addr = 0; | 376 | dma_addr_t bus_addr = 0; |
| @@ -514,10 +514,10 @@ tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) | |||
| 514 | * The mapping mode used is based on the devices dma_mask. As a last resort | 514 | * The mapping mode used is based on the devices dma_mask. As a last resort |
| 515 | * use the GART mapped mode. | 515 | * use the GART mapped mode. |
| 516 | */ | 516 | */ |
| 517 | static uint64_t | 517 | static u64 |
| 518 | tioca_dma_map(struct pci_dev *pdev, uint64_t paddr, size_t byte_count) | 518 | tioca_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count) |
| 519 | { | 519 | { |
| 520 | uint64_t mapaddr; | 520 | u64 mapaddr; |
| 521 | 521 | ||
| 522 | /* | 522 | /* |
| 523 | * If card is 64 or 48 bit addresable, use a direct mapping. 32 | 523 | * If card is 64 or 48 bit addresable, use a direct mapping. 32 |
| @@ -554,8 +554,8 @@ tioca_error_intr_handler(int irq, void *arg, struct pt_regs *pt) | |||
| 554 | { | 554 | { |
| 555 | struct tioca_common *soft = arg; | 555 | struct tioca_common *soft = arg; |
| 556 | struct ia64_sal_retval ret_stuff; | 556 | struct ia64_sal_retval ret_stuff; |
| 557 | uint64_t segment; | 557 | u64 segment; |
| 558 | uint64_t busnum; | 558 | u64 busnum; |
| 559 | ret_stuff.status = 0; | 559 | ret_stuff.status = 0; |
| 560 | ret_stuff.v0 = 0; | 560 | ret_stuff.v0 = 0; |
| 561 | 561 | ||
| @@ -620,7 +620,7 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont | |||
| 620 | INIT_LIST_HEAD(&tioca_kern->ca_dmamaps); | 620 | INIT_LIST_HEAD(&tioca_kern->ca_dmamaps); |
| 621 | tioca_kern->ca_closest_node = | 621 | tioca_kern->ca_closest_node = |
| 622 | nasid_to_cnodeid(tioca_common->ca_closest_nasid); | 622 | nasid_to_cnodeid(tioca_common->ca_closest_nasid); |
| 623 | tioca_common->ca_kernel_private = (uint64_t) tioca_kern; | 623 | tioca_common->ca_kernel_private = (u64) tioca_kern; |
| 624 | 624 | ||
| 625 | bus = pci_find_bus(tioca_common->ca_common.bs_persist_segment, | 625 | bus = pci_find_bus(tioca_common->ca_common.bs_persist_segment, |
| 626 | tioca_common->ca_common.bs_persist_busnum); | 626 | tioca_common->ca_common.bs_persist_busnum); |
diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c index dda196c9e324..e52831ed93eb 100644 --- a/arch/ia64/sn/pci/tioce_provider.c +++ b/arch/ia64/sn/pci/tioce_provider.c | |||
| @@ -81,10 +81,10 @@ | |||
| 81 | * 61 - 0 since this is not an MSI transaction | 81 | * 61 - 0 since this is not an MSI transaction |
| 82 | * 60:54 - reserved, MBZ | 82 | * 60:54 - reserved, MBZ |
| 83 | */ | 83 | */ |
| 84 | static uint64_t | 84 | static u64 |
| 85 | tioce_dma_d64(unsigned long ct_addr) | 85 | tioce_dma_d64(unsigned long ct_addr) |
| 86 | { | 86 | { |
| 87 | uint64_t bus_addr; | 87 | u64 bus_addr; |
| 88 | 88 | ||
| 89 | bus_addr = ct_addr | (1UL << 63); | 89 | bus_addr = ct_addr | (1UL << 63); |
| 90 | 90 | ||
| @@ -141,9 +141,9 @@ pcidev_to_tioce(struct pci_dev *pdev, struct tioce **base, | |||
| 141 | * length, and if enough resources exist, fill in the ATE's and construct a | 141 | * length, and if enough resources exist, fill in the ATE's and construct a |
| 142 | * tioce_dmamap struct to track the mapping. | 142 | * tioce_dmamap struct to track the mapping. |
| 143 | */ | 143 | */ |
| 144 | static uint64_t | 144 | static u64 |
| 145 | tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, | 145 | tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, |
| 146 | uint64_t ct_addr, int len) | 146 | u64 ct_addr, int len) |
| 147 | { | 147 | { |
| 148 | int i; | 148 | int i; |
| 149 | int j; | 149 | int j; |
| @@ -152,11 +152,11 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, | |||
| 152 | int entries; | 152 | int entries; |
| 153 | int nates; | 153 | int nates; |
| 154 | int pagesize; | 154 | int pagesize; |
| 155 | uint64_t *ate_shadow; | 155 | u64 *ate_shadow; |
| 156 | uint64_t *ate_reg; | 156 | u64 *ate_reg; |
| 157 | uint64_t addr; | 157 | u64 addr; |
| 158 | struct tioce *ce_mmr; | 158 | struct tioce *ce_mmr; |
| 159 | uint64_t bus_base; | 159 | u64 bus_base; |
| 160 | struct tioce_dmamap *map; | 160 | struct tioce_dmamap *map; |
| 161 | 161 | ||
| 162 | ce_mmr = (struct tioce *)ce_kern->ce_common->ce_pcibus.bs_base; | 162 | ce_mmr = (struct tioce *)ce_kern->ce_common->ce_pcibus.bs_base; |
| @@ -224,7 +224,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, | |||
| 224 | 224 | ||
| 225 | addr = ct_addr; | 225 | addr = ct_addr; |
| 226 | for (j = 0; j < nates; j++) { | 226 | for (j = 0; j < nates; j++) { |
| 227 | uint64_t ate; | 227 | u64 ate; |
| 228 | 228 | ||
| 229 | ate = ATE_MAKE(addr, pagesize); | 229 | ate = ATE_MAKE(addr, pagesize); |
| 230 | ate_shadow[i + j] = ate; | 230 | ate_shadow[i + j] = ate; |
| @@ -252,15 +252,15 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, | |||
| 252 | * | 252 | * |
| 253 | * Map @paddr into 32-bit bus space of the CE associated with @pcidev_info. | 253 | * Map @paddr into 32-bit bus space of the CE associated with @pcidev_info. |
| 254 | */ | 254 | */ |
| 255 | static uint64_t | 255 | static u64 |
| 256 | tioce_dma_d32(struct pci_dev *pdev, uint64_t ct_addr) | 256 | tioce_dma_d32(struct pci_dev *pdev, u64 ct_addr) |
| 257 | { | 257 | { |
| 258 | int dma_ok; | 258 | int dma_ok; |
| 259 | int port; | 259 | int port; |
| 260 | struct tioce *ce_mmr; | 260 | struct tioce *ce_mmr; |
| 261 | struct tioce_kernel *ce_kern; | 261 | struct tioce_kernel *ce_kern; |
| 262 | uint64_t ct_upper; | 262 | u64 ct_upper; |
| 263 | uint64_t ct_lower; | 263 | u64 ct_lower; |
| 264 | dma_addr_t bus_addr; | 264 | dma_addr_t bus_addr; |
| 265 | 265 | ||
| 266 | ct_upper = ct_addr & ~0x3fffffffUL; | 266 | ct_upper = ct_addr & ~0x3fffffffUL; |
| @@ -269,7 +269,7 @@ tioce_dma_d32(struct pci_dev *pdev, uint64_t ct_addr) | |||
| 269 | pcidev_to_tioce(pdev, &ce_mmr, &ce_kern, &port); | 269 | pcidev_to_tioce(pdev, &ce_mmr, &ce_kern, &port); |
| 270 | 270 | ||
| 271 | if (ce_kern->ce_port[port].dirmap_refcnt == 0) { | 271 | if (ce_kern->ce_port[port].dirmap_refcnt == 0) { |
| 272 | uint64_t tmp; | 272 | u64 tmp; |
| 273 | 273 | ||
| 274 | ce_kern->ce_port[port].dirmap_shadow = ct_upper; | 274 | ce_kern->ce_port[port].dirmap_shadow = ct_upper; |
| 275 | writeq(ct_upper, &ce_mmr->ce_ure_dir_map[port]); | 275 | writeq(ct_upper, &ce_mmr->ce_ure_dir_map[port]); |
| @@ -295,10 +295,10 @@ tioce_dma_d32(struct pci_dev *pdev, uint64_t ct_addr) | |||
| 295 | * Given a TIOCE bus address, set the appropriate bit to indicate barrier | 295 | * Given a TIOCE bus address, set the appropriate bit to indicate barrier |
| 296 | * attributes. | 296 | * attributes. |
| 297 | */ | 297 | */ |
| 298 | static uint64_t | 298 | static u64 |
| 299 | tioce_dma_barrier(uint64_t bus_addr, int on) | 299 | tioce_dma_barrier(u64 bus_addr, int on) |
| 300 | { | 300 | { |
| 301 | uint64_t barrier_bit; | 301 | u64 barrier_bit; |
| 302 | 302 | ||
| 303 | /* barrier not supported in M40/M40S mode */ | 303 | /* barrier not supported in M40/M40S mode */ |
| 304 | if (TIOCE_M40_ADDR(bus_addr) || TIOCE_M40S_ADDR(bus_addr)) | 304 | if (TIOCE_M40_ADDR(bus_addr) || TIOCE_M40S_ADDR(bus_addr)) |
| @@ -351,7 +351,7 @@ tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) | |||
| 351 | 351 | ||
| 352 | list_for_each_entry(map, &ce_kern->ce_dmamap_list, | 352 | list_for_each_entry(map, &ce_kern->ce_dmamap_list, |
| 353 | ce_dmamap_list) { | 353 | ce_dmamap_list) { |
| 354 | uint64_t last; | 354 | u64 last; |
| 355 | 355 | ||
| 356 | last = map->pci_start + map->nbytes - 1; | 356 | last = map->pci_start + map->nbytes - 1; |
| 357 | if (bus_addr >= map->pci_start && bus_addr <= last) | 357 | if (bus_addr >= map->pci_start && bus_addr <= last) |
| @@ -385,17 +385,17 @@ tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) | |||
| 385 | * This is the main wrapper for mapping host physical pages to CE PCI space. | 385 | * This is the main wrapper for mapping host physical pages to CE PCI space. |
| 386 | * The mapping mode used is based on the device's dma_mask. | 386 | * The mapping mode used is based on the device's dma_mask. |
| 387 | */ | 387 | */ |
| 388 | static uint64_t | 388 | static u64 |
| 389 | tioce_do_dma_map(struct pci_dev *pdev, uint64_t paddr, size_t byte_count, | 389 | tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, |
| 390 | int barrier) | 390 | int barrier) |
| 391 | { | 391 | { |
| 392 | unsigned long flags; | 392 | unsigned long flags; |
| 393 | uint64_t ct_addr; | 393 | u64 ct_addr; |
| 394 | uint64_t mapaddr = 0; | 394 | u64 mapaddr = 0; |
| 395 | struct tioce_kernel *ce_kern; | 395 | struct tioce_kernel *ce_kern; |
| 396 | struct tioce_dmamap *map; | 396 | struct tioce_dmamap *map; |
| 397 | int port; | 397 | int port; |
| 398 | uint64_t dma_mask; | 398 | u64 dma_mask; |
| 399 | 399 | ||
| 400 | dma_mask = (barrier) ? pdev->dev.coherent_dma_mask : pdev->dma_mask; | 400 | dma_mask = (barrier) ? pdev->dev.coherent_dma_mask : pdev->dma_mask; |
| 401 | 401 | ||
| @@ -425,7 +425,7 @@ tioce_do_dma_map(struct pci_dev *pdev, uint64_t paddr, size_t byte_count, | |||
| 425 | * address bits than this device can support. | 425 | * address bits than this device can support. |
| 426 | */ | 426 | */ |
| 427 | list_for_each_entry(map, &ce_kern->ce_dmamap_list, ce_dmamap_list) { | 427 | list_for_each_entry(map, &ce_kern->ce_dmamap_list, ce_dmamap_list) { |
| 428 | uint64_t last; | 428 | u64 last; |
| 429 | 429 | ||
| 430 | last = map->ct_start + map->nbytes - 1; | 430 | last = map->ct_start + map->nbytes - 1; |
| 431 | if (ct_addr >= map->ct_start && | 431 | if (ct_addr >= map->ct_start && |
| @@ -501,8 +501,8 @@ dma_map_done: | |||
| 501 | * Simply call tioce_do_dma_map() to create a map with the barrier bit clear | 501 | * Simply call tioce_do_dma_map() to create a map with the barrier bit clear |
| 502 | * in the address. | 502 | * in the address. |
| 503 | */ | 503 | */ |
| 504 | static uint64_t | 504 | static u64 |
| 505 | tioce_dma(struct pci_dev *pdev, uint64_t paddr, size_t byte_count) | 505 | tioce_dma(struct pci_dev *pdev, u64 paddr, size_t byte_count) |
| 506 | { | 506 | { |
| 507 | return tioce_do_dma_map(pdev, paddr, byte_count, 0); | 507 | return tioce_do_dma_map(pdev, paddr, byte_count, 0); |
| 508 | } | 508 | } |
| @@ -515,8 +515,8 @@ tioce_dma(struct pci_dev *pdev, uint64_t paddr, size_t byte_count) | |||
| 515 | * | 515 | * |
| 516 | * Simply call tioce_do_dma_map() to create a map with the barrier bit set | 516 | * Simply call tioce_do_dma_map() to create a map with the barrier bit set |
| 517 | * in the address. | 517 | * in the address. |
| 518 | */ static uint64_t | 518 | */ static u64 |
| 519 | tioce_dma_consistent(struct pci_dev *pdev, uint64_t paddr, size_t byte_count) | 519 | tioce_dma_consistent(struct pci_dev *pdev, u64 paddr, size_t byte_count) |
| 520 | { | 520 | { |
| 521 | return tioce_do_dma_map(pdev, paddr, byte_count, 1); | 521 | return tioce_do_dma_map(pdev, paddr, byte_count, 1); |
| 522 | } | 522 | } |
| @@ -551,7 +551,7 @@ tioce_error_intr_handler(int irq, void *arg, struct pt_regs *pt) | |||
| 551 | tioce_kern_init(struct tioce_common *tioce_common) | 551 | tioce_kern_init(struct tioce_common *tioce_common) |
| 552 | { | 552 | { |
| 553 | int i; | 553 | int i; |
| 554 | uint32_t tmp; | 554 | u32 tmp; |
| 555 | struct tioce *tioce_mmr; | 555 | struct tioce *tioce_mmr; |
| 556 | struct tioce_kernel *tioce_kern; | 556 | struct tioce_kernel *tioce_kern; |
| 557 | 557 | ||
| @@ -563,7 +563,7 @@ tioce_kern_init(struct tioce_common *tioce_common) | |||
| 563 | tioce_kern->ce_common = tioce_common; | 563 | tioce_kern->ce_common = tioce_common; |
| 564 | spin_lock_init(&tioce_kern->ce_lock); | 564 | spin_lock_init(&tioce_kern->ce_lock); |
| 565 | INIT_LIST_HEAD(&tioce_kern->ce_dmamap_list); | 565 | INIT_LIST_HEAD(&tioce_kern->ce_dmamap_list); |
| 566 | tioce_common->ce_kernel_private = (uint64_t) tioce_kern; | 566 | tioce_common->ce_kernel_private = (u64) tioce_kern; |
| 567 | 567 | ||
| 568 | /* | 568 | /* |
| 569 | * Determine the secondary bus number of the port2 logical PPB. | 569 | * Determine the secondary bus number of the port2 logical PPB. |
| @@ -575,7 +575,7 @@ tioce_kern_init(struct tioce_common *tioce_common) | |||
| 575 | raw_pci_ops->read(tioce_common->ce_pcibus.bs_persist_segment, | 575 | raw_pci_ops->read(tioce_common->ce_pcibus.bs_persist_segment, |
| 576 | tioce_common->ce_pcibus.bs_persist_busnum, | 576 | tioce_common->ce_pcibus.bs_persist_busnum, |
| 577 | PCI_DEVFN(2, 0), PCI_SECONDARY_BUS, 1, &tmp); | 577 | PCI_DEVFN(2, 0), PCI_SECONDARY_BUS, 1, &tmp); |
| 578 | tioce_kern->ce_port1_secondary = (uint8_t) tmp; | 578 | tioce_kern->ce_port1_secondary = (u8) tmp; |
| 579 | 579 | ||
| 580 | /* | 580 | /* |
| 581 | * Set PMU pagesize to the largest size available, and zero out | 581 | * Set PMU pagesize to the largest size available, and zero out |
| @@ -615,7 +615,7 @@ tioce_force_interrupt(struct sn_irq_info *sn_irq_info) | |||
| 615 | struct pcidev_info *pcidev_info; | 615 | struct pcidev_info *pcidev_info; |
| 616 | struct tioce_common *ce_common; | 616 | struct tioce_common *ce_common; |
| 617 | struct tioce *ce_mmr; | 617 | struct tioce *ce_mmr; |
| 618 | uint64_t force_int_val; | 618 | u64 force_int_val; |
| 619 | 619 | ||
| 620 | if (!sn_irq_info->irq_bridge) | 620 | if (!sn_irq_info->irq_bridge) |
| 621 | return; | 621 | return; |
| @@ -687,7 +687,7 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info) | |||
| 687 | struct tioce_common *ce_common; | 687 | struct tioce_common *ce_common; |
| 688 | struct tioce *ce_mmr; | 688 | struct tioce *ce_mmr; |
| 689 | int bit; | 689 | int bit; |
| 690 | uint64_t vector; | 690 | u64 vector; |
| 691 | 691 | ||
| 692 | pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; | 692 | pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; |
| 693 | if (!pcidev_info) | 693 | if (!pcidev_info) |
| @@ -699,7 +699,7 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info) | |||
| 699 | bit = sn_irq_info->irq_int_bit; | 699 | bit = sn_irq_info->irq_int_bit; |
| 700 | 700 | ||
| 701 | __sn_setq_relaxed(&ce_mmr->ce_adm_int_mask, (1UL << bit)); | 701 | __sn_setq_relaxed(&ce_mmr->ce_adm_int_mask, (1UL << bit)); |
| 702 | vector = (uint64_t)sn_irq_info->irq_irq << INTR_VECTOR_SHFT; | 702 | vector = (u64)sn_irq_info->irq_irq << INTR_VECTOR_SHFT; |
| 703 | vector |= sn_irq_info->irq_xtalkaddr; | 703 | vector |= sn_irq_info->irq_xtalkaddr; |
| 704 | writeq(vector, &ce_mmr->ce_adm_int_dest[bit]); | 704 | writeq(vector, &ce_mmr->ce_adm_int_dest[bit]); |
| 705 | __sn_clrq_relaxed(&ce_mmr->ce_adm_int_mask, (1UL << bit)); | 705 | __sn_clrq_relaxed(&ce_mmr->ce_adm_int_mask, (1UL << bit)); |
diff --git a/arch/mips/kernel/reset.c b/arch/mips/kernel/reset.c index ae2ba67b7ef6..5e37df3111ad 100644 --- a/arch/mips/kernel/reset.c +++ b/arch/mips/kernel/reset.c | |||
| @@ -12,6 +12,9 @@ | |||
| 12 | #include <linux/reboot.h> | 12 | #include <linux/reboot.h> |
| 13 | #include <asm/reboot.h> | 13 | #include <asm/reboot.h> |
| 14 | 14 | ||
| 15 | void (*pm_power_off)(void); | ||
| 16 | EXPORT_SYMBOL(pm_power_off); | ||
| 17 | |||
| 15 | /* | 18 | /* |
| 16 | * Urgs ... Too many MIPS machines to handle this in a generic way. | 19 | * Urgs ... Too many MIPS machines to handle this in a generic way. |
| 17 | * So handle all using function pointers to machine specific | 20 | * So handle all using function pointers to machine specific |
| @@ -33,6 +36,9 @@ void machine_halt(void) | |||
| 33 | 36 | ||
| 34 | void machine_power_off(void) | 37 | void machine_power_off(void) |
| 35 | { | 38 | { |
| 39 | if (pm_power_off) | ||
| 40 | pm_power_off(); | ||
| 41 | |||
| 36 | _machine_power_off(); | 42 | _machine_power_off(); |
| 37 | } | 43 | } |
| 38 | 44 | ||
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c index 1eaa0d37f677..2d804e2d16d1 100644 --- a/arch/parisc/kernel/drivers.c +++ b/arch/parisc/kernel/drivers.c | |||
| @@ -173,8 +173,6 @@ int register_parisc_driver(struct parisc_driver *driver) | |||
| 173 | WARN_ON(driver->drv.probe != NULL); | 173 | WARN_ON(driver->drv.probe != NULL); |
| 174 | WARN_ON(driver->drv.remove != NULL); | 174 | WARN_ON(driver->drv.remove != NULL); |
| 175 | 175 | ||
| 176 | driver->drv.probe = parisc_driver_probe; | ||
| 177 | driver->drv.remove = parisc_driver_remove; | ||
| 178 | driver->drv.name = driver->name; | 176 | driver->drv.name = driver->name; |
| 179 | 177 | ||
| 180 | return driver_register(&driver->drv); | 178 | return driver_register(&driver->drv); |
| @@ -575,6 +573,8 @@ struct bus_type parisc_bus_type = { | |||
| 575 | .name = "parisc", | 573 | .name = "parisc", |
| 576 | .match = parisc_generic_match, | 574 | .match = parisc_generic_match, |
| 577 | .dev_attrs = parisc_device_attrs, | 575 | .dev_attrs = parisc_device_attrs, |
| 576 | .probe = parisc_driver_probe, | ||
| 577 | .remove = parisc_driver_remove, | ||
| 578 | }; | 578 | }; |
| 579 | 579 | ||
| 580 | /** | 580 | /** |
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 01feed0e2a15..df338c5cc910 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
| @@ -78,17 +78,6 @@ config PPC_UDBG_16550 | |||
| 78 | bool | 78 | bool |
| 79 | default n | 79 | default n |
| 80 | 80 | ||
| 81 | config CRASH_DUMP | ||
| 82 | bool "kernel crash dumps (EXPERIMENTAL)" | ||
| 83 | depends on PPC_MULTIPLATFORM | ||
| 84 | depends on EXPERIMENTAL | ||
| 85 | help | ||
| 86 | Build a kernel suitable for use as a kdump capture kernel. | ||
| 87 | The kernel will be linked at a different address than normal, and | ||
| 88 | so can only be used for Kdump. | ||
| 89 | |||
| 90 | Don't change this unless you know what you are doing. | ||
| 91 | |||
| 92 | config GENERIC_TBSYNC | 81 | config GENERIC_TBSYNC |
| 93 | bool | 82 | bool |
| 94 | default y if PPC32 && SMP | 83 | default y if PPC32 && SMP |
| @@ -584,6 +573,16 @@ config KEXEC | |||
| 584 | support. As of this writing the exact hardware interface is | 573 | support. As of this writing the exact hardware interface is |
| 585 | strongly in flux, so no good recommendation can be made. | 574 | strongly in flux, so no good recommendation can be made. |
| 586 | 575 | ||
| 576 | config CRASH_DUMP | ||
| 577 | bool "kernel crash dumps (EXPERIMENTAL)" | ||
| 578 | depends on PPC_MULTIPLATFORM && PPC64 && EXPERIMENTAL | ||
| 579 | help | ||
| 580 | Build a kernel suitable for use as a kdump capture kernel. | ||
| 581 | The kernel will be linked at a different address than normal, and | ||
| 582 | so can only be used for Kdump. | ||
| 583 | |||
| 584 | Don't change this unless you know what you are doing. | ||
| 585 | |||
| 587 | config EMBEDDEDBOOT | 586 | config EMBEDDEDBOOT |
| 588 | bool | 587 | bool |
| 589 | depends on 8xx || 8260 | 588 | depends on 8xx || 8260 |
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index d3654a264ef7..44dd82b791d1 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
| @@ -139,17 +139,14 @@ drivers-$(CONFIG_CPM2) += arch/ppc/8260_io/ | |||
| 139 | 139 | ||
| 140 | drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ | 140 | drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ |
| 141 | 141 | ||
| 142 | defaultimage-$(CONFIG_PPC32) := zImage | 142 | # Default to zImage, override when needed |
| 143 | defaultimage-y := zImage | ||
| 143 | defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux | 144 | defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux |
| 144 | defaultimage-$(CONFIG_PPC_PSERIES) := zImage | ||
| 145 | KBUILD_IMAGE := $(defaultimage-y) | 145 | KBUILD_IMAGE := $(defaultimage-y) |
| 146 | all: $(KBUILD_IMAGE) | 146 | all: $(KBUILD_IMAGE) |
| 147 | 147 | ||
| 148 | CPPFLAGS_vmlinux.lds := -Upowerpc | 148 | CPPFLAGS_vmlinux.lds := -Upowerpc |
| 149 | 149 | ||
| 150 | # All the instructions talk about "make bzImage". | ||
| 151 | bzImage: zImage | ||
| 152 | |||
| 153 | BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm uImage | 150 | BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm uImage |
| 154 | 151 | ||
| 155 | .PHONY: $(BOOT_TARGETS) | 152 | .PHONY: $(BOOT_TARGETS) |
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index b53d677f6742..840ae595a617 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile | |||
| @@ -25,8 +25,9 @@ HOSTCC := gcc | |||
| 25 | BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem \ | 25 | BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem \ |
| 26 | $(shell $(CROSS32CC) -print-file-name=include) -fPIC | 26 | $(shell $(CROSS32CC) -print-file-name=include) -fPIC |
| 27 | BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc | 27 | BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc |
| 28 | BOOTLFLAGS := -T $(srctree)/$(src)/zImage.lds | ||
| 29 | OBJCOPYFLAGS := contents,alloc,load,readonly,data | 28 | OBJCOPYFLAGS := contents,alloc,load,readonly,data |
| 29 | OBJCOPY_COFF_ARGS := -O aixcoff-rs6000 --set-start 0x500000 | ||
| 30 | OBJCOPY_MIB_ARGS := -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment | ||
| 30 | 31 | ||
| 31 | zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c | 32 | zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c |
| 32 | zlibheader := infblock.h infcodes.h inffast.h inftrees.h infutil.h | 33 | zlibheader := infblock.h infcodes.h inffast.h inftrees.h infutil.h |
| @@ -35,7 +36,7 @@ zliblinuxheader := zlib.h zconf.h zutil.h | |||
| 35 | $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) | 36 | $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) |
| 36 | #$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h) | 37 | #$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h) |
| 37 | 38 | ||
| 38 | src-boot := string.S prom.c main.c div64.S crt0.S | 39 | src-boot := crt0.S string.S prom.c stdio.c main.c div64.S |
| 39 | src-boot += $(zlib) | 40 | src-boot += $(zlib) |
| 40 | src-boot := $(addprefix $(obj)/, $(src-boot)) | 41 | src-boot := $(addprefix $(obj)/, $(src-boot)) |
| 41 | obj-boot := $(addsuffix .o, $(basename $(src-boot))) | 42 | obj-boot := $(addsuffix .o, $(basename $(src-boot))) |
| @@ -70,7 +71,7 @@ quiet_cmd_bootas = BOOTAS $@ | |||
| 70 | cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< | 71 | cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< |
| 71 | 72 | ||
| 72 | quiet_cmd_bootld = BOOTLD $@ | 73 | quiet_cmd_bootld = BOOTLD $@ |
| 73 | cmd_bootld = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(2) | 74 | cmd_bootld = $(CROSS32LD) -T $(srctree)/$(src)/$(3) -o $@ $(2) |
| 74 | 75 | ||
| 75 | $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c | 76 | $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c |
| 76 | $(call if_changed_dep,bootcc) | 77 | $(call if_changed_dep,bootcc) |
| @@ -87,12 +88,14 @@ obj-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.o, $(section))) | |||
| 87 | src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section))) | 88 | src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section))) |
| 88 | gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) | 89 | gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) |
| 89 | 90 | ||
| 90 | hostprogs-y := addnote addRamDisk | 91 | hostprogs-y := addnote addRamDisk hack-coff |
| 91 | targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd \ | 92 | |
| 92 | $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ | 93 | targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd \ |
| 93 | $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ | 94 | zImage.coff zImage.initrd.coff miboot.image miboot.initrd.image \ |
| 94 | $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \ | 95 | $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ |
| 95 | vmlinux.initrd | 96 | $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ |
| 97 | $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \ | ||
| 98 | vmlinux.initrd dummy.o | ||
| 96 | extra-y := initrd.o | 99 | extra-y := initrd.o |
| 97 | 100 | ||
| 98 | quiet_cmd_ramdisk = RAMDISK $@ | 101 | quiet_cmd_ramdisk = RAMDISK $@ |
| @@ -114,6 +117,14 @@ quiet_cmd_addsection = ADDSEC $@ | |||
| 114 | quiet_cmd_addnote = ADDNOTE $@ | 117 | quiet_cmd_addnote = ADDNOTE $@ |
| 115 | cmd_addnote = $(obj)/addnote $@ | 118 | cmd_addnote = $(obj)/addnote $@ |
| 116 | 119 | ||
| 120 | quiet_cmd_gen-miboot = GEN $@ | ||
| 121 | cmd_gen-miboot = $(OBJCOPY) $(OBJCOPY_MIB_ARGS) \ | ||
| 122 | --add-section=$1=$(word 2, $^) $< $@ | ||
| 123 | |||
| 124 | quiet_cmd_gencoff = COFF $@ | ||
| 125 | cmd_gencoff = $(OBJCOPY) $(OBJCOPY_COFF_ARGS) $@ && \ | ||
| 126 | $(obj)/hack-coff $@ | ||
| 127 | |||
| 117 | $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % | 128 | $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % |
| 118 | $(call if_changed,gzip) | 129 | $(call if_changed,gzip) |
| 119 | 130 | ||
| @@ -127,22 +138,47 @@ $(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c | |||
| 127 | $(call if_changed_dep,bootcc) | 138 | $(call if_changed_dep,bootcc) |
| 128 | $(call cmd,addsection) | 139 | $(call cmd,addsection) |
| 129 | 140 | ||
| 130 | $(obj)/zImage.vmode: obj-boot += $(call obj-sec, $(required)) | 141 | $(obj)/zImage.vmode $(obj)/zImage.coff: obj-boot += $(call obj-sec, $(required)) |
| 131 | $(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) $(srctree)/$(src)/zImage.lds | 142 | $(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) $(srctree)/$(src)/zImage.lds |
| 132 | $(call cmd,bootld,$(obj-boot)) | 143 | $(call cmd,bootld,$(obj-boot),zImage.lds) |
| 133 | 144 | ||
| 134 | $(obj)/zImage.initrd.vmode: obj-boot += $(call obj-sec, $(required) $(initrd)) | 145 | $(obj)/zImage.initrd.vmode $(obj)/zImage.initrd.coff: obj-boot += $(call obj-sec, $(required) $(initrd)) |
| 135 | $(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(srctree)/$(src)/zImage.lds | 146 | $(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(srctree)/$(src)/zImage.lds |
| 136 | $(call cmd,bootld,$(obj-boot)) | 147 | $(call cmd,bootld,$(obj-boot),zImage.lds) |
| 148 | |||
| 149 | # For 32-bit powermacs, build the COFF and miboot images | ||
| 150 | # as well as the ELF images. | ||
| 151 | coffimage-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/zImage.coff | ||
| 152 | coffrdimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/zImage.initrd.coff | ||
| 153 | mibootimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/miboot.image | ||
| 154 | mibrdimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/miboot.initrd.image | ||
| 137 | 155 | ||
| 138 | $(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote | 156 | $(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote $(coffimage-y-y) \ |
| 157 | $(mibootimg-y-y) | ||
| 139 | @cp -f $< $@ | 158 | @cp -f $< $@ |
| 140 | $(call if_changed,addnote) | 159 | $(call if_changed,addnote) |
| 141 | 160 | ||
| 142 | $(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote | 161 | $(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote \ |
| 162 | $(coffrdimg-y-y) $(mibrdimg-y-y) | ||
| 143 | @cp -f $< $@ | 163 | @cp -f $< $@ |
| 144 | $(call if_changed,addnote) | 164 | $(call if_changed,addnote) |
| 145 | 165 | ||
| 166 | $(obj)/zImage.coff: $(call obj-sec, $(required)) $(obj-boot) \ | ||
| 167 | $(srctree)/$(src)/zImage.coff.lds $(obj)/hack-coff | ||
| 168 | $(call cmd,bootld,$(obj-boot),zImage.coff.lds) | ||
| 169 | $(call cmd,gencoff) | ||
| 170 | |||
| 171 | $(obj)/zImage.initrd.coff: $(call obj-sec, $(required) $(initrd)) $(obj-boot) \ | ||
| 172 | $(srctree)/$(src)/zImage.coff.lds $(obj)/hack-coff | ||
| 173 | $(call cmd,bootld,$(obj-boot),zImage.coff.lds) | ||
| 174 | $(call cmd,gencoff) | ||
| 175 | |||
| 176 | $(obj)/miboot.image: $(obj)/dummy.o $(obj)/vmlinux.gz | ||
| 177 | $(call cmd,gen-miboot,image) | ||
| 178 | |||
| 179 | $(obj)/miboot.initrd.image: $(obj)/miboot.image $(images)/ramdisk.image.gz | ||
| 180 | $(call cmd,gen-miboot,initrd) | ||
| 181 | |||
| 146 | #----------------------------------------------------------- | 182 | #----------------------------------------------------------- |
| 147 | # build u-boot images | 183 | # build u-boot images |
| 148 | #----------------------------------------------------------- | 184 | #----------------------------------------------------------- |
diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S index d2f2ace56cd3..e0192c26037b 100644 --- a/arch/powerpc/boot/crt0.S +++ b/arch/powerpc/boot/crt0.S | |||
| @@ -12,17 +12,23 @@ | |||
| 12 | #include "ppc_asm.h" | 12 | #include "ppc_asm.h" |
| 13 | 13 | ||
| 14 | .text | 14 | .text |
| 15 | /* a procedure descriptor used when booting this as a COFF file */ | ||
| 16 | _zimage_start_opd: | ||
| 17 | .long _zimage_start, 0, 0, 0 | ||
| 18 | |||
| 15 | .globl _zimage_start | 19 | .globl _zimage_start |
| 16 | _zimage_start: | 20 | _zimage_start: |
| 21 | /* Work out the offset between the address we were linked at | ||
| 22 | and the address where we're running. */ | ||
| 17 | bl 1f | 23 | bl 1f |
| 18 | 24 | 1: mflr r0 | |
| 19 | 1: | ||
| 20 | mflr r0 | ||
| 21 | lis r9,1b@ha | 25 | lis r9,1b@ha |
| 22 | addi r9,r9,1b@l | 26 | addi r9,r9,1b@l |
| 23 | subf. r0,r9,r0 | 27 | subf. r0,r9,r0 |
| 24 | beq 3f | 28 | beq 3f /* if running at same address as linked */ |
| 25 | 29 | ||
| 30 | /* The .got2 section contains a list of addresses, so add | ||
| 31 | the address offset onto each entry. */ | ||
| 26 | lis r9,__got2_start@ha | 32 | lis r9,__got2_start@ha |
| 27 | addi r9,r9,__got2_start@l | 33 | addi r9,r9,__got2_start@l |
| 28 | lis r8,__got2_end@ha | 34 | lis r8,__got2_end@ha |
| @@ -32,15 +38,14 @@ _zimage_start: | |||
| 32 | srwi. r8,r8,2 | 38 | srwi. r8,r8,2 |
| 33 | mtctr r8 | 39 | mtctr r8 |
| 34 | add r9,r0,r9 | 40 | add r9,r0,r9 |
| 35 | 2: | 41 | 2: lwz r8,0(r9) |
| 36 | lwz r8,0(r9) | ||
| 37 | add r8,r8,r0 | 42 | add r8,r8,r0 |
| 38 | stw r8,0(r9) | 43 | stw r8,0(r9) |
| 39 | addi r9,r9,4 | 44 | addi r9,r9,4 |
| 40 | bdnz 2b | 45 | bdnz 2b |
| 41 | 46 | ||
| 42 | 3: | 47 | /* Do a cache flush for our text, in case OF didn't */ |
| 43 | lis r9,_start@h | 48 | 3: lis r9,_start@h |
| 44 | add r9,r0,r9 | 49 | add r9,r0,r9 |
| 45 | lis r8,_etext@ha | 50 | lis r8,_etext@ha |
| 46 | addi r8,r8,_etext@l | 51 | addi r8,r8,_etext@l |
diff --git a/arch/powerpc/boot/dummy.c b/arch/powerpc/boot/dummy.c new file mode 100644 index 000000000000..31dbf45bf99c --- /dev/null +++ b/arch/powerpc/boot/dummy.c | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | int main(void) | ||
| 2 | { | ||
| 3 | return 0; | ||
| 4 | } | ||
diff --git a/arch/powerpc/boot/hack-coff.c b/arch/powerpc/boot/hack-coff.c new file mode 100644 index 000000000000..5e5a6573a1ef --- /dev/null +++ b/arch/powerpc/boot/hack-coff.c | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | /* | ||
| 2 | * hack-coff.c - hack the header of an xcoff file to fill in | ||
| 3 | * a few fields needed by the Open Firmware xcoff loader on | ||
| 4 | * Power Macs but not initialized by objcopy. | ||
| 5 | * | ||
| 6 | * Copyright (C) Paul Mackerras 1997. | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or | ||
| 9 | * modify it under the terms of the GNU General Public License | ||
| 10 | * as published by the Free Software Foundation; either version | ||
| 11 | * 2 of the License, or (at your option) any later version. | ||
| 12 | */ | ||
| 13 | #include <stdio.h> | ||
| 14 | #include <stdlib.h> | ||
| 15 | #include <unistd.h> | ||
| 16 | #include <fcntl.h> | ||
| 17 | #include <string.h> | ||
| 18 | #include "rs6000.h" | ||
| 19 | |||
| 20 | #define AOUT_MAGIC 0x010b | ||
| 21 | |||
| 22 | #define get_16be(x) ((((unsigned char *)(x))[0] << 8) \ | ||
| 23 | + ((unsigned char *)(x))[1]) | ||
| 24 | #define put_16be(x, v) (((unsigned char *)(x))[0] = (v) >> 8, \ | ||
| 25 | ((unsigned char *)(x))[1] = (v) & 0xff) | ||
| 26 | #define get_32be(x) ((((unsigned char *)(x))[0] << 24) \ | ||
| 27 | + (((unsigned char *)(x))[1] << 16) \ | ||
| 28 | + (((unsigned char *)(x))[2] << 8) \ | ||
| 29 | + ((unsigned char *)(x))[3]) | ||
| 30 | |||
| 31 | int | ||
| 32 | main(int ac, char **av) | ||
| 33 | { | ||
| 34 | int fd; | ||
| 35 | int i, nsect; | ||
| 36 | int aoutsz; | ||
| 37 | struct external_filehdr fhdr; | ||
| 38 | AOUTHDR aout; | ||
| 39 | struct external_scnhdr shdr; | ||
| 40 | |||
| 41 | if (ac != 2) { | ||
| 42 | fprintf(stderr, "Usage: hack-coff coff-file\n"); | ||
| 43 | exit(1); | ||
| 44 | } | ||
| 45 | if ((fd = open(av[1], 2)) == -1) { | ||
| 46 | perror(av[2]); | ||
| 47 | exit(1); | ||
| 48 | } | ||
| 49 | if (read(fd, &fhdr, sizeof(fhdr)) != sizeof(fhdr)) | ||
| 50 | goto readerr; | ||
| 51 | i = get_16be(fhdr.f_magic); | ||
| 52 | if (i != U802TOCMAGIC && i != U802WRMAGIC && i != U802ROMAGIC) { | ||
| 53 | fprintf(stderr, "%s: not an xcoff file\n", av[1]); | ||
| 54 | exit(1); | ||
| 55 | } | ||
| 56 | aoutsz = get_16be(fhdr.f_opthdr); | ||
| 57 | if (read(fd, &aout, aoutsz) != aoutsz) | ||
| 58 | goto readerr; | ||
| 59 | nsect = get_16be(fhdr.f_nscns); | ||
| 60 | for (i = 0; i < nsect; ++i) { | ||
| 61 | if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr)) | ||
| 62 | goto readerr; | ||
| 63 | if (strcmp(shdr.s_name, ".text") == 0) { | ||
| 64 | put_16be(aout.o_snentry, i+1); | ||
| 65 | put_16be(aout.o_sntext, i+1); | ||
| 66 | } else if (strcmp(shdr.s_name, ".data") == 0) { | ||
| 67 | put_16be(aout.o_sndata, i+1); | ||
| 68 | } else if (strcmp(shdr.s_name, ".bss") == 0) { | ||
| 69 | put_16be(aout.o_snbss, i+1); | ||
| 70 | } | ||
| 71 | } | ||
| 72 | put_16be(aout.magic, AOUT_MAGIC); | ||
| 73 | if (lseek(fd, (long) sizeof(struct external_filehdr), 0) == -1 | ||
| 74 | || write(fd, &aout, aoutsz) != aoutsz) { | ||
| 75 | fprintf(stderr, "%s: write error\n", av[1]); | ||
| 76 | exit(1); | ||
| 77 | } | ||
| 78 | close(fd); | ||
| 79 | exit(0); | ||
| 80 | |||
| 81 | readerr: | ||
| 82 | fprintf(stderr, "%s: read error or file too short\n", av[1]); | ||
| 83 | exit(1); | ||
| 84 | } | ||
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c index 64ec93116fa6..55ec59867250 100644 --- a/arch/powerpc/boot/main.c +++ b/arch/powerpc/boot/main.c | |||
| @@ -21,8 +21,8 @@ extern void flush_cache(void *, unsigned long); | |||
| 21 | 21 | ||
| 22 | 22 | ||
| 23 | /* Value picked to match that used by yaboot */ | 23 | /* Value picked to match that used by yaboot */ |
| 24 | #define PROG_START 0x01400000 | 24 | #define PROG_START 0x01400000 /* only used on 64-bit systems */ |
| 25 | #define RAM_END (512<<20) // Fixme: use OF */ | 25 | #define RAM_END (512<<20) /* Fixme: use OF */ |
| 26 | #define ONE_MB 0x100000 | 26 | #define ONE_MB 0x100000 |
| 27 | 27 | ||
| 28 | extern char _start[]; | 28 | extern char _start[]; |
| @@ -160,6 +160,17 @@ static int is_elf64(void *hdr) | |||
| 160 | elfoffset = (unsigned long)elf64ph->p_offset; | 160 | elfoffset = (unsigned long)elf64ph->p_offset; |
| 161 | vmlinux.size = (unsigned long)elf64ph->p_filesz + elfoffset; | 161 | vmlinux.size = (unsigned long)elf64ph->p_filesz + elfoffset; |
| 162 | vmlinux.memsize = (unsigned long)elf64ph->p_memsz + elfoffset; | 162 | vmlinux.memsize = (unsigned long)elf64ph->p_memsz + elfoffset; |
| 163 | |||
| 164 | #if defined(PROG_START) | ||
| 165 | /* | ||
| 166 | * Maintain a "magic" minimum address. This keeps some older | ||
| 167 | * firmware platforms running. | ||
| 168 | */ | ||
| 169 | |||
| 170 | if (claim_base < PROG_START) | ||
| 171 | claim_base = PROG_START; | ||
| 172 | #endif | ||
| 173 | |||
| 163 | return 1; | 174 | return 1; |
| 164 | } | 175 | } |
| 165 | 176 | ||
| @@ -206,12 +217,18 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) | |||
| 206 | exit(); | 217 | exit(); |
| 207 | if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) | 218 | if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) |
| 208 | exit(); | 219 | exit(); |
| 209 | stderr = stdout; | ||
| 210 | if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) | ||
| 211 | exit(); | ||
| 212 | 220 | ||
| 213 | printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp); | 221 | printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp); |
| 214 | 222 | ||
| 223 | /* | ||
| 224 | * The first available claim_base must be above the end of the | ||
| 225 | * the loaded kernel wrapper file (_start to _end includes the | ||
| 226 | * initrd image if it is present) and rounded up to a nice | ||
| 227 | * 1 MB boundary for good measure. | ||
| 228 | */ | ||
| 229 | |||
| 230 | claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB); | ||
| 231 | |||
| 215 | vmlinuz.addr = (unsigned long)_vmlinux_start; | 232 | vmlinuz.addr = (unsigned long)_vmlinux_start; |
| 216 | vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start); | 233 | vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start); |
| 217 | 234 | ||
| @@ -228,25 +245,6 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) | |||
| 228 | exit(); | 245 | exit(); |
| 229 | } | 246 | } |
| 230 | 247 | ||
| 231 | /* | ||
| 232 | * The first available claim_base must be above the end of the | ||
| 233 | * the loaded kernel wrapper file (_start to _end includes the | ||
| 234 | * initrd image if it is present) and rounded up to a nice | ||
| 235 | * 1 MB boundary for good measure. | ||
| 236 | */ | ||
| 237 | |||
| 238 | claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB); | ||
| 239 | |||
| 240 | #if defined(PROG_START) | ||
| 241 | /* | ||
| 242 | * Maintain a "magic" minimum address. This keeps some older | ||
| 243 | * firmware platforms running. | ||
| 244 | */ | ||
| 245 | |||
| 246 | if (claim_base < PROG_START) | ||
| 247 | claim_base = PROG_START; | ||
| 248 | #endif | ||
| 249 | |||
| 250 | /* We need to claim the memsize plus the file offset since gzip | 248 | /* We need to claim the memsize plus the file offset since gzip |
| 251 | * will expand the header (file offset), then the kernel, then | 249 | * will expand the header (file offset), then the kernel, then |
| 252 | * possible rubbish we don't care about. But the kernel bss must | 250 | * possible rubbish we don't care about. But the kernel bss must |
diff --git a/arch/powerpc/boot/prom.c b/arch/powerpc/boot/prom.c index 4bea2f4dcb06..fa0057736f6b 100644 --- a/arch/powerpc/boot/prom.c +++ b/arch/powerpc/boot/prom.c | |||
| @@ -13,487 +13,153 @@ | |||
| 13 | #include "prom.h" | 13 | #include "prom.h" |
| 14 | 14 | ||
| 15 | int (*prom)(void *); | 15 | int (*prom)(void *); |
| 16 | phandle chosen_handle; | ||
| 17 | ihandle stdout; | ||
| 16 | 18 | ||
| 17 | void *chosen_handle; | 19 | int call_prom(const char *service, int nargs, int nret, ...) |
| 18 | |||
| 19 | void *stdin; | ||
| 20 | void *stdout; | ||
| 21 | void *stderr; | ||
| 22 | |||
| 23 | |||
| 24 | int | ||
| 25 | write(void *handle, void *ptr, int nb) | ||
| 26 | { | ||
| 27 | struct prom_args { | ||
| 28 | char *service; | ||
| 29 | int nargs; | ||
| 30 | int nret; | ||
| 31 | void *ihandle; | ||
| 32 | void *addr; | ||
| 33 | int len; | ||
| 34 | int actual; | ||
| 35 | } args; | ||
| 36 | |||
| 37 | args.service = "write"; | ||
| 38 | args.nargs = 3; | ||
| 39 | args.nret = 1; | ||
| 40 | args.ihandle = handle; | ||
| 41 | args.addr = ptr; | ||
| 42 | args.len = nb; | ||
| 43 | args.actual = -1; | ||
| 44 | (*prom)(&args); | ||
| 45 | return args.actual; | ||
| 46 | } | ||
| 47 | |||
| 48 | int | ||
| 49 | read(void *handle, void *ptr, int nb) | ||
| 50 | { | 20 | { |
| 21 | int i; | ||
| 51 | struct prom_args { | 22 | struct prom_args { |
| 52 | char *service; | 23 | const char *service; |
| 53 | int nargs; | 24 | int nargs; |
| 54 | int nret; | 25 | int nret; |
| 55 | void *ihandle; | 26 | unsigned int args[12]; |
| 56 | void *addr; | ||
| 57 | int len; | ||
| 58 | int actual; | ||
| 59 | } args; | ||
| 60 | |||
| 61 | args.service = "read"; | ||
| 62 | args.nargs = 3; | ||
| 63 | args.nret = 1; | ||
| 64 | args.ihandle = handle; | ||
| 65 | args.addr = ptr; | ||
| 66 | args.len = nb; | ||
| 67 | args.actual = -1; | ||
| 68 | (*prom)(&args); | ||
| 69 | return args.actual; | ||
| 70 | } | ||
| 71 | |||
| 72 | void | ||
| 73 | exit() | ||
| 74 | { | ||
| 75 | struct prom_args { | ||
| 76 | char *service; | ||
| 77 | } args; | ||
| 78 | |||
| 79 | for (;;) { | ||
| 80 | args.service = "exit"; | ||
| 81 | (*prom)(&args); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | void | ||
| 86 | pause(void) | ||
| 87 | { | ||
| 88 | struct prom_args { | ||
| 89 | char *service; | ||
| 90 | } args; | 27 | } args; |
| 28 | va_list list; | ||
| 91 | 29 | ||
| 92 | args.service = "enter"; | 30 | args.service = service; |
| 93 | (*prom)(&args); | 31 | args.nargs = nargs; |
| 94 | } | 32 | args.nret = nret; |
| 95 | 33 | ||
| 96 | void * | 34 | va_start(list, nret); |
| 97 | finddevice(const char *name) | 35 | for (i = 0; i < nargs; i++) |
| 98 | { | 36 | args.args[i] = va_arg(list, unsigned int); |
| 99 | struct prom_args { | 37 | va_end(list); |
| 100 | char *service; | ||
| 101 | int nargs; | ||
| 102 | int nret; | ||
| 103 | const char *devspec; | ||
| 104 | void *phandle; | ||
| 105 | } args; | ||
| 106 | 38 | ||
| 107 | args.service = "finddevice"; | 39 | for (i = 0; i < nret; i++) |
| 108 | args.nargs = 1; | 40 | args.args[nargs+i] = 0; |
| 109 | args.nret = 1; | ||
| 110 | args.devspec = name; | ||
| 111 | args.phandle = (void *) -1; | ||
| 112 | (*prom)(&args); | ||
| 113 | return args.phandle; | ||
| 114 | } | ||
| 115 | 41 | ||
| 116 | void * | 42 | if (prom(&args) < 0) |
| 117 | claim(unsigned long virt, unsigned long size, unsigned long align) | 43 | return -1; |
| 118 | { | ||
| 119 | struct prom_args { | ||
| 120 | char *service; | ||
| 121 | int nargs; | ||
| 122 | int nret; | ||
| 123 | unsigned int virt; | ||
| 124 | unsigned int size; | ||
| 125 | unsigned int align; | ||
| 126 | void *ret; | ||
| 127 | } args; | ||
| 128 | 44 | ||
| 129 | args.service = "claim"; | 45 | return (nret > 0)? args.args[nargs]: 0; |
| 130 | args.nargs = 3; | ||
| 131 | args.nret = 1; | ||
| 132 | args.virt = virt; | ||
| 133 | args.size = size; | ||
| 134 | args.align = align; | ||
| 135 | (*prom)(&args); | ||
| 136 | return args.ret; | ||
| 137 | } | 46 | } |
| 138 | 47 | ||
| 139 | int | 48 | int call_prom_ret(const char *service, int nargs, int nret, |
| 140 | getprop(void *phandle, const char *name, void *buf, int buflen) | 49 | unsigned int *rets, ...) |
| 141 | { | 50 | { |
| 51 | int i; | ||
| 142 | struct prom_args { | 52 | struct prom_args { |
| 143 | char *service; | 53 | const char *service; |
| 144 | int nargs; | 54 | int nargs; |
| 145 | int nret; | 55 | int nret; |
| 146 | void *phandle; | 56 | unsigned int args[12]; |
| 147 | const char *name; | ||
| 148 | void *buf; | ||
| 149 | int buflen; | ||
| 150 | int size; | ||
| 151 | } args; | 57 | } args; |
| 58 | va_list list; | ||
| 152 | 59 | ||
| 153 | args.service = "getprop"; | 60 | args.service = service; |
| 154 | args.nargs = 4; | 61 | args.nargs = nargs; |
| 155 | args.nret = 1; | 62 | args.nret = nret; |
| 156 | args.phandle = phandle; | ||
| 157 | args.name = name; | ||
| 158 | args.buf = buf; | ||
| 159 | args.buflen = buflen; | ||
| 160 | args.size = -1; | ||
| 161 | (*prom)(&args); | ||
| 162 | return args.size; | ||
| 163 | } | ||
| 164 | 63 | ||
| 165 | int | 64 | va_start(list, rets); |
| 166 | putc(int c, void *f) | 65 | for (i = 0; i < nargs; i++) |
| 167 | { | 66 | args.args[i] = va_arg(list, unsigned int); |
| 168 | char ch = c; | 67 | va_end(list); |
| 169 | 68 | ||
| 170 | if (c == '\n') | 69 | for (i = 0; i < nret; i++) |
| 171 | putc('\r', f); | 70 | args.args[nargs+i] = 0; |
| 172 | return write(f, &ch, 1) == 1? c: -1; | ||
| 173 | } | ||
| 174 | 71 | ||
| 175 | int | 72 | if (prom(&args) < 0) |
| 176 | putchar(int c) | 73 | return -1; |
| 177 | { | ||
| 178 | return putc(c, stdout); | ||
| 179 | } | ||
| 180 | 74 | ||
| 181 | int | 75 | if (rets != (void *) 0) |
| 182 | fputs(char *str, void *f) | 76 | for (i = 1; i < nret; ++i) |
| 183 | { | 77 | rets[i-1] = args.args[nargs+i]; |
| 184 | int n = strlen(str); | ||
| 185 | 78 | ||
| 186 | return write(f, str, n) == n? 0: -1; | 79 | return (nret > 0)? args.args[nargs]: 0; |
| 187 | } | 80 | } |
| 188 | 81 | ||
| 189 | size_t strnlen(const char * s, size_t count) | 82 | int write(void *handle, void *ptr, int nb) |
| 190 | { | 83 | { |
| 191 | const char *sc; | 84 | return call_prom("write", 3, 1, handle, ptr, nb); |
| 192 | |||
| 193 | for (sc = s; count-- && *sc != '\0'; ++sc) | ||
| 194 | /* nothing */; | ||
| 195 | return sc - s; | ||
| 196 | } | 85 | } |
| 197 | 86 | ||
| 198 | extern unsigned int __div64_32(unsigned long long *dividend, | 87 | /* |
| 199 | unsigned int divisor); | 88 | * Older OF's require that when claiming a specific range of addresses, |
| 200 | 89 | * we claim the physical space in the /memory node and the virtual | |
| 201 | /* The unnecessary pointer compare is there | 90 | * space in the chosen mmu node, and then do a map operation to |
| 202 | * to check for type safety (n must be 64bit) | 91 | * map virtual to physical. |
| 203 | */ | 92 | */ |
| 204 | # define do_div(n,base) ({ \ | 93 | static int need_map = -1; |
| 205 | unsigned int __base = (base); \ | 94 | static ihandle chosen_mmu; |
| 206 | unsigned int __rem; \ | 95 | static phandle memory; |
| 207 | (void)(((typeof((n)) *)0) == ((unsigned long long *)0)); \ | ||
| 208 | if (((n) >> 32) == 0) { \ | ||
| 209 | __rem = (unsigned int)(n) % __base; \ | ||
| 210 | (n) = (unsigned int)(n) / __base; \ | ||
| 211 | } else \ | ||
| 212 | __rem = __div64_32(&(n), __base); \ | ||
| 213 | __rem; \ | ||
| 214 | }) | ||
| 215 | 96 | ||
| 216 | static int skip_atoi(const char **s) | 97 | /* returns true if s2 is a prefix of s1 */ |
| 98 | static int string_match(const char *s1, const char *s2) | ||
| 217 | { | 99 | { |
| 218 | int i, c; | 100 | for (; *s2; ++s2) |
| 219 | 101 | if (*s1++ != *s2) | |
| 220 | for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s) | 102 | return 0; |
| 221 | i = i*10 + c - '0'; | 103 | return 1; |
| 222 | return i; | ||
| 223 | } | 104 | } |
| 224 | 105 | ||
| 225 | #define ZEROPAD 1 /* pad with zero */ | 106 | static int check_of_version(void) |
| 226 | #define SIGN 2 /* unsigned/signed long */ | ||
| 227 | #define PLUS 4 /* show plus */ | ||
| 228 | #define SPACE 8 /* space if plus */ | ||
| 229 | #define LEFT 16 /* left justified */ | ||
| 230 | #define SPECIAL 32 /* 0x */ | ||
| 231 | #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ | ||
| 232 | |||
| 233 | static char * number(char * str, unsigned long long num, int base, int size, int precision, int type) | ||
| 234 | { | 107 | { |
| 235 | char c,sign,tmp[66]; | 108 | phandle oprom, chosen; |
| 236 | const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; | 109 | char version[64]; |
| 237 | int i; | ||
| 238 | 110 | ||
| 239 | if (type & LARGE) | 111 | oprom = finddevice("/openprom"); |
| 240 | digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | 112 | if (oprom == (phandle) -1) |
| 241 | if (type & LEFT) | ||
| 242 | type &= ~ZEROPAD; | ||
| 243 | if (base < 2 || base > 36) | ||
| 244 | return 0; | 113 | return 0; |
| 245 | c = (type & ZEROPAD) ? '0' : ' '; | 114 | if (getprop(oprom, "model", version, sizeof(version)) <= 0) |
| 246 | sign = 0; | 115 | return 0; |
| 247 | if (type & SIGN) { | 116 | version[sizeof(version)-1] = 0; |
| 248 | if ((signed long long)num < 0) { | 117 | printf("OF version = '%s'\r\n", version); |
| 249 | sign = '-'; | 118 | if (!string_match(version, "Open Firmware, 1.") |
| 250 | num = - (signed long long)num; | 119 | && !string_match(version, "FirmWorks,3.")) |
| 251 | size--; | 120 | return 0; |
| 252 | } else if (type & PLUS) { | 121 | chosen = finddevice("/chosen"); |
| 253 | sign = '+'; | 122 | if (chosen == (phandle) -1) { |
| 254 | size--; | 123 | chosen = finddevice("/chosen@0"); |
| 255 | } else if (type & SPACE) { | 124 | if (chosen == (phandle) -1) { |
| 256 | sign = ' '; | 125 | printf("no chosen\n"); |
| 257 | size--; | 126 | return 0; |
| 258 | } | 127 | } |
| 259 | } | 128 | } |
| 260 | if (type & SPECIAL) { | 129 | if (getprop(chosen, "mmu", &chosen_mmu, sizeof(chosen_mmu)) <= 0) { |
| 261 | if (base == 16) | 130 | printf("no mmu\n"); |
| 262 | size -= 2; | 131 | return 0; |
| 263 | else if (base == 8) | ||
| 264 | size--; | ||
| 265 | } | ||
| 266 | i = 0; | ||
| 267 | if (num == 0) | ||
| 268 | tmp[i++]='0'; | ||
| 269 | else while (num != 0) { | ||
| 270 | tmp[i++] = digits[do_div(num, base)]; | ||
| 271 | } | 132 | } |
| 272 | if (i > precision) | 133 | memory = (ihandle) call_prom("open", 1, 1, "/memory"); |
| 273 | precision = i; | 134 | if (memory == (ihandle) -1) { |
| 274 | size -= precision; | 135 | memory = (ihandle) call_prom("open", 1, 1, "/memory@0"); |
| 275 | if (!(type&(ZEROPAD+LEFT))) | 136 | if (memory == (ihandle) -1) { |
| 276 | while(size-->0) | 137 | printf("no memory node\n"); |
| 277 | *str++ = ' '; | 138 | return 0; |
| 278 | if (sign) | ||
| 279 | *str++ = sign; | ||
| 280 | if (type & SPECIAL) { | ||
| 281 | if (base==8) | ||
| 282 | *str++ = '0'; | ||
| 283 | else if (base==16) { | ||
| 284 | *str++ = '0'; | ||
| 285 | *str++ = digits[33]; | ||
| 286 | } | 139 | } |
| 287 | } | 140 | } |
| 288 | if (!(type & LEFT)) | 141 | printf("old OF detected\r\n"); |
| 289 | while (size-- > 0) | 142 | return 1; |
| 290 | *str++ = c; | ||
| 291 | while (i < precision--) | ||
| 292 | *str++ = '0'; | ||
| 293 | while (i-- > 0) | ||
| 294 | *str++ = tmp[i]; | ||
| 295 | while (size-- > 0) | ||
| 296 | *str++ = ' '; | ||
| 297 | return str; | ||
| 298 | } | 143 | } |
| 299 | 144 | ||
| 300 | int vsprintf(char *buf, const char *fmt, va_list args) | 145 | void *claim(unsigned long virt, unsigned long size, unsigned long align) |
| 301 | { | 146 | { |
| 302 | int len; | 147 | int ret; |
| 303 | unsigned long long num; | 148 | unsigned int result; |
| 304 | int i, base; | ||
| 305 | char * str; | ||
| 306 | const char *s; | ||
| 307 | |||
| 308 | int flags; /* flags to number() */ | ||
| 309 | |||
| 310 | int field_width; /* width of output field */ | ||
| 311 | int precision; /* min. # of digits for integers; max | ||
| 312 | number of chars for from string */ | ||
| 313 | int qualifier; /* 'h', 'l', or 'L' for integer fields */ | ||
| 314 | /* 'z' support added 23/7/1999 S.H. */ | ||
| 315 | /* 'z' changed to 'Z' --davidm 1/25/99 */ | ||
| 316 | 149 | ||
| 150 | if (need_map < 0) | ||
| 151 | need_map = check_of_version(); | ||
| 152 | if (align || !need_map) | ||
| 153 | return (void *) call_prom("claim", 3, 1, virt, size, align); | ||
| 317 | 154 | ||
| 318 | for (str=buf ; *fmt ; ++fmt) { | 155 | ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory, |
| 319 | if (*fmt != '%') { | 156 | align, size, virt); |
| 320 | *str++ = *fmt; | 157 | if (ret != 0 || result == -1) |
| 321 | continue; | 158 | return (void *) -1; |
| 322 | } | 159 | ret = call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu, |
| 323 | 160 | align, size, virt); | |
| 324 | /* process flags */ | 161 | /* 0x12 == coherent + read/write */ |
| 325 | flags = 0; | 162 | ret = call_prom("call-method", 6, 1, "map", chosen_mmu, |
| 326 | repeat: | 163 | 0x12, size, virt, virt); |
| 327 | ++fmt; /* this also skips first '%' */ | 164 | return (void *) virt; |
| 328 | switch (*fmt) { | ||
| 329 | case '-': flags |= LEFT; goto repeat; | ||
| 330 | case '+': flags |= PLUS; goto repeat; | ||
| 331 | case ' ': flags |= SPACE; goto repeat; | ||
| 332 | case '#': flags |= SPECIAL; goto repeat; | ||
| 333 | case '0': flags |= ZEROPAD; goto repeat; | ||
| 334 | } | ||
| 335 | |||
| 336 | /* get field width */ | ||
| 337 | field_width = -1; | ||
| 338 | if ('0' <= *fmt && *fmt <= '9') | ||
| 339 | field_width = skip_atoi(&fmt); | ||
| 340 | else if (*fmt == '*') { | ||
| 341 | ++fmt; | ||
| 342 | /* it's the next argument */ | ||
| 343 | field_width = va_arg(args, int); | ||
| 344 | if (field_width < 0) { | ||
| 345 | field_width = -field_width; | ||
| 346 | flags |= LEFT; | ||
| 347 | } | ||
| 348 | } | ||
| 349 | |||
| 350 | /* get the precision */ | ||
| 351 | precision = -1; | ||
| 352 | if (*fmt == '.') { | ||
| 353 | ++fmt; | ||
| 354 | if ('0' <= *fmt && *fmt <= '9') | ||
| 355 | precision = skip_atoi(&fmt); | ||
| 356 | else if (*fmt == '*') { | ||
| 357 | ++fmt; | ||
| 358 | /* it's the next argument */ | ||
| 359 | precision = va_arg(args, int); | ||
| 360 | } | ||
| 361 | if (precision < 0) | ||
| 362 | precision = 0; | ||
| 363 | } | ||
| 364 | |||
| 365 | /* get the conversion qualifier */ | ||
| 366 | qualifier = -1; | ||
| 367 | if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') { | ||
| 368 | qualifier = *fmt; | ||
| 369 | ++fmt; | ||
| 370 | } | ||
| 371 | |||
| 372 | /* default base */ | ||
| 373 | base = 10; | ||
| 374 | |||
| 375 | switch (*fmt) { | ||
| 376 | case 'c': | ||
| 377 | if (!(flags & LEFT)) | ||
| 378 | while (--field_width > 0) | ||
| 379 | *str++ = ' '; | ||
| 380 | *str++ = (unsigned char) va_arg(args, int); | ||
| 381 | while (--field_width > 0) | ||
| 382 | *str++ = ' '; | ||
| 383 | continue; | ||
| 384 | |||
| 385 | case 's': | ||
| 386 | s = va_arg(args, char *); | ||
| 387 | if (!s) | ||
| 388 | s = "<NULL>"; | ||
| 389 | |||
| 390 | len = strnlen(s, precision); | ||
| 391 | |||
| 392 | if (!(flags & LEFT)) | ||
| 393 | while (len < field_width--) | ||
| 394 | *str++ = ' '; | ||
| 395 | for (i = 0; i < len; ++i) | ||
| 396 | *str++ = *s++; | ||
| 397 | while (len < field_width--) | ||
| 398 | *str++ = ' '; | ||
| 399 | continue; | ||
| 400 | |||
| 401 | case 'p': | ||
| 402 | if (field_width == -1) { | ||
| 403 | field_width = 2*sizeof(void *); | ||
| 404 | flags |= ZEROPAD; | ||
| 405 | } | ||
| 406 | str = number(str, | ||
| 407 | (unsigned long) va_arg(args, void *), 16, | ||
| 408 | field_width, precision, flags); | ||
| 409 | continue; | ||
| 410 | |||
| 411 | |||
| 412 | case 'n': | ||
| 413 | if (qualifier == 'l') { | ||
| 414 | long * ip = va_arg(args, long *); | ||
| 415 | *ip = (str - buf); | ||
| 416 | } else if (qualifier == 'Z') { | ||
| 417 | size_t * ip = va_arg(args, size_t *); | ||
| 418 | *ip = (str - buf); | ||
| 419 | } else { | ||
| 420 | int * ip = va_arg(args, int *); | ||
| 421 | *ip = (str - buf); | ||
| 422 | } | ||
| 423 | continue; | ||
| 424 | |||
| 425 | case '%': | ||
| 426 | *str++ = '%'; | ||
| 427 | continue; | ||
| 428 | |||
| 429 | /* integer number formats - set up the flags and "break" */ | ||
| 430 | case 'o': | ||
| 431 | base = 8; | ||
| 432 | break; | ||
| 433 | |||
| 434 | case 'X': | ||
| 435 | flags |= LARGE; | ||
| 436 | case 'x': | ||
| 437 | base = 16; | ||
| 438 | break; | ||
| 439 | |||
| 440 | case 'd': | ||
| 441 | case 'i': | ||
| 442 | flags |= SIGN; | ||
| 443 | case 'u': | ||
| 444 | break; | ||
| 445 | |||
| 446 | default: | ||
| 447 | *str++ = '%'; | ||
| 448 | if (*fmt) | ||
| 449 | *str++ = *fmt; | ||
| 450 | else | ||
| 451 | --fmt; | ||
| 452 | continue; | ||
| 453 | } | ||
| 454 | if (qualifier == 'l') { | ||
| 455 | num = va_arg(args, unsigned long); | ||
| 456 | if (flags & SIGN) | ||
| 457 | num = (signed long) num; | ||
| 458 | } else if (qualifier == 'Z') { | ||
| 459 | num = va_arg(args, size_t); | ||
| 460 | } else if (qualifier == 'h') { | ||
| 461 | num = (unsigned short) va_arg(args, int); | ||
| 462 | if (flags & SIGN) | ||
| 463 | num = (signed short) num; | ||
| 464 | } else { | ||
| 465 | num = va_arg(args, unsigned int); | ||
| 466 | if (flags & SIGN) | ||
| 467 | num = (signed int) num; | ||
| 468 | } | ||
| 469 | str = number(str, num, base, field_width, precision, flags); | ||
| 470 | } | ||
| 471 | *str = '\0'; | ||
| 472 | return str-buf; | ||
| 473 | } | ||
| 474 | |||
| 475 | int sprintf(char * buf, const char *fmt, ...) | ||
| 476 | { | ||
| 477 | va_list args; | ||
| 478 | int i; | ||
| 479 | |||
| 480 | va_start(args, fmt); | ||
| 481 | i=vsprintf(buf,fmt,args); | ||
| 482 | va_end(args); | ||
| 483 | return i; | ||
| 484 | } | ||
| 485 | |||
| 486 | static char sprint_buf[1024]; | ||
| 487 | |||
| 488 | int | ||
| 489 | printf(const char *fmt, ...) | ||
| 490 | { | ||
| 491 | va_list args; | ||
| 492 | int n; | ||
| 493 | |||
| 494 | va_start(args, fmt); | ||
| 495 | n = vsprintf(sprint_buf, fmt, args); | ||
| 496 | va_end(args); | ||
| 497 | write(stdout, sprint_buf, n); | ||
| 498 | return n; | ||
| 499 | } | 165 | } |
diff --git a/arch/powerpc/boot/prom.h b/arch/powerpc/boot/prom.h index 96ab5aec740c..3e2ddd4a5a81 100644 --- a/arch/powerpc/boot/prom.h +++ b/arch/powerpc/boot/prom.h | |||
| @@ -1,18 +1,34 @@ | |||
| 1 | #ifndef _PPC_BOOT_PROM_H_ | 1 | #ifndef _PPC_BOOT_PROM_H_ |
| 2 | #define _PPC_BOOT_PROM_H_ | 2 | #define _PPC_BOOT_PROM_H_ |
| 3 | 3 | ||
| 4 | typedef void *phandle; | ||
| 5 | typedef void *ihandle; | ||
| 6 | |||
| 4 | extern int (*prom) (void *); | 7 | extern int (*prom) (void *); |
| 5 | extern void *chosen_handle; | 8 | extern phandle chosen_handle; |
| 9 | extern ihandle stdout; | ||
| 6 | 10 | ||
| 7 | extern void *stdin; | 11 | int call_prom(const char *service, int nargs, int nret, ...); |
| 8 | extern void *stdout; | 12 | int call_prom_ret(const char *service, int nargs, int nret, |
| 9 | extern void *stderr; | 13 | unsigned int *rets, ...); |
| 10 | 14 | ||
| 11 | extern int write(void *handle, void *ptr, int nb); | 15 | extern int write(void *handle, void *ptr, int nb); |
| 12 | extern int read(void *handle, void *ptr, int nb); | 16 | extern void *claim(unsigned long virt, unsigned long size, unsigned long aln); |
| 13 | extern void exit(void); | 17 | |
| 14 | extern void pause(void); | 18 | static inline void exit(void) |
| 15 | extern void *finddevice(const char *); | 19 | { |
| 16 | extern void *claim(unsigned long virt, unsigned long size, unsigned long align); | 20 | call_prom("exit", 0, 0); |
| 17 | extern int getprop(void *phandle, const char *name, void *buf, int buflen); | 21 | } |
| 22 | |||
| 23 | static inline phandle finddevice(const char *name) | ||
| 24 | { | ||
| 25 | return (phandle) call_prom("finddevice", 1, 1, name); | ||
| 26 | } | ||
| 27 | |||
| 28 | static inline int getprop(void *phandle, const char *name, | ||
| 29 | void *buf, int buflen) | ||
| 30 | { | ||
| 31 | return call_prom("getprop", 4, 1, phandle, name, buf, buflen); | ||
| 32 | } | ||
| 33 | |||
| 18 | #endif /* _PPC_BOOT_PROM_H_ */ | 34 | #endif /* _PPC_BOOT_PROM_H_ */ |
diff --git a/arch/powerpc/boot/rs6000.h b/arch/powerpc/boot/rs6000.h new file mode 100644 index 000000000000..433f45084e41 --- /dev/null +++ b/arch/powerpc/boot/rs6000.h | |||
| @@ -0,0 +1,243 @@ | |||
| 1 | /* IBM RS/6000 "XCOFF" file definitions for BFD. | ||
| 2 | Copyright (C) 1990, 1991 Free Software Foundation, Inc. | ||
| 3 | FIXME: Can someone provide a transliteration of this name into ASCII? | ||
| 4 | Using the following chars caused a compiler warning on HIUX (so I replaced | ||
| 5 | them with octal escapes), and isn't useful without an understanding of what | ||
| 6 | character set it is. | ||
| 7 | Written by Mimi Ph\373\364ng-Th\345o V\365 of IBM | ||
| 8 | and John Gilmore of Cygnus Support. */ | ||
| 9 | |||
| 10 | /********************** FILE HEADER **********************/ | ||
| 11 | |||
| 12 | struct external_filehdr { | ||
| 13 | char f_magic[2]; /* magic number */ | ||
| 14 | char f_nscns[2]; /* number of sections */ | ||
| 15 | char f_timdat[4]; /* time & date stamp */ | ||
| 16 | char f_symptr[4]; /* file pointer to symtab */ | ||
| 17 | char f_nsyms[4]; /* number of symtab entries */ | ||
| 18 | char f_opthdr[2]; /* sizeof(optional hdr) */ | ||
| 19 | char f_flags[2]; /* flags */ | ||
| 20 | }; | ||
| 21 | |||
| 22 | /* IBM RS/6000 */ | ||
| 23 | #define U802WRMAGIC 0730 /* writeable text segments **chh** */ | ||
| 24 | #define U802ROMAGIC 0735 /* readonly sharable text segments */ | ||
| 25 | #define U802TOCMAGIC 0737 /* readonly text segments and TOC */ | ||
| 26 | |||
| 27 | #define BADMAG(x) \ | ||
| 28 | ((x).f_magic != U802ROMAGIC && (x).f_magic != U802WRMAGIC && \ | ||
| 29 | (x).f_magic != U802TOCMAGIC) | ||
| 30 | |||
| 31 | #define FILHDR struct external_filehdr | ||
| 32 | #define FILHSZ 20 | ||
| 33 | |||
| 34 | |||
| 35 | /********************** AOUT "OPTIONAL HEADER" **********************/ | ||
| 36 | |||
| 37 | |||
| 38 | typedef struct | ||
| 39 | { | ||
| 40 | unsigned char magic[2]; /* type of file */ | ||
| 41 | unsigned char vstamp[2]; /* version stamp */ | ||
| 42 | unsigned char tsize[4]; /* text size in bytes, padded to FW bdry */ | ||
| 43 | unsigned char dsize[4]; /* initialized data " " */ | ||
| 44 | unsigned char bsize[4]; /* uninitialized data " " */ | ||
| 45 | unsigned char entry[4]; /* entry pt. */ | ||
| 46 | unsigned char text_start[4]; /* base of text used for this file */ | ||
| 47 | unsigned char data_start[4]; /* base of data used for this file */ | ||
| 48 | unsigned char o_toc[4]; /* address of TOC */ | ||
| 49 | unsigned char o_snentry[2]; /* section number of entry point */ | ||
| 50 | unsigned char o_sntext[2]; /* section number of .text section */ | ||
| 51 | unsigned char o_sndata[2]; /* section number of .data section */ | ||
| 52 | unsigned char o_sntoc[2]; /* section number of TOC */ | ||
| 53 | unsigned char o_snloader[2]; /* section number of .loader section */ | ||
| 54 | unsigned char o_snbss[2]; /* section number of .bss section */ | ||
| 55 | unsigned char o_algntext[2]; /* .text alignment */ | ||
| 56 | unsigned char o_algndata[2]; /* .data alignment */ | ||
| 57 | unsigned char o_modtype[2]; /* module type (??) */ | ||
| 58 | unsigned char o_cputype[2]; /* cpu type */ | ||
| 59 | unsigned char o_maxstack[4]; /* max stack size (??) */ | ||
| 60 | unsigned char o_maxdata[4]; /* max data size (??) */ | ||
| 61 | unsigned char o_resv2[12]; /* reserved */ | ||
| 62 | } | ||
| 63 | AOUTHDR; | ||
| 64 | |||
| 65 | #define AOUTSZ 72 | ||
| 66 | #define SMALL_AOUTSZ (28) | ||
| 67 | #define AOUTHDRSZ 72 | ||
| 68 | |||
| 69 | #define RS6K_AOUTHDR_OMAGIC 0x0107 /* old: text & data writeable */ | ||
| 70 | #define RS6K_AOUTHDR_NMAGIC 0x0108 /* new: text r/o, data r/w */ | ||
| 71 | #define RS6K_AOUTHDR_ZMAGIC 0x010B /* paged: text r/o, both page-aligned */ | ||
| 72 | |||
| 73 | |||
| 74 | /********************** SECTION HEADER **********************/ | ||
| 75 | |||
| 76 | |||
| 77 | struct external_scnhdr { | ||
| 78 | char s_name[8]; /* section name */ | ||
| 79 | char s_paddr[4]; /* physical address, aliased s_nlib */ | ||
| 80 | char s_vaddr[4]; /* virtual address */ | ||
| 81 | char s_size[4]; /* section size */ | ||
| 82 | char s_scnptr[4]; /* file ptr to raw data for section */ | ||
| 83 | char s_relptr[4]; /* file ptr to relocation */ | ||
| 84 | char s_lnnoptr[4]; /* file ptr to line numbers */ | ||
| 85 | char s_nreloc[2]; /* number of relocation entries */ | ||
| 86 | char s_nlnno[2]; /* number of line number entries*/ | ||
| 87 | char s_flags[4]; /* flags */ | ||
| 88 | }; | ||
| 89 | |||
| 90 | /* | ||
| 91 | * names of "special" sections | ||
| 92 | */ | ||
| 93 | #define _TEXT ".text" | ||
| 94 | #define _DATA ".data" | ||
| 95 | #define _BSS ".bss" | ||
| 96 | #define _PAD ".pad" | ||
| 97 | #define _LOADER ".loader" | ||
| 98 | |||
| 99 | #define SCNHDR struct external_scnhdr | ||
| 100 | #define SCNHSZ 40 | ||
| 101 | |||
| 102 | /* XCOFF uses a special .loader section with type STYP_LOADER. */ | ||
| 103 | #define STYP_LOADER 0x1000 | ||
| 104 | |||
| 105 | /* XCOFF uses a special .debug section with type STYP_DEBUG. */ | ||
| 106 | #define STYP_DEBUG 0x2000 | ||
| 107 | |||
| 108 | /* XCOFF handles line number or relocation overflow by creating | ||
| 109 | another section header with STYP_OVRFLO set. */ | ||
| 110 | #define STYP_OVRFLO 0x8000 | ||
| 111 | |||
| 112 | /********************** LINE NUMBERS **********************/ | ||
| 113 | |||
| 114 | /* 1 line number entry for every "breakpointable" source line in a section. | ||
| 115 | * Line numbers are grouped on a per function basis; first entry in a function | ||
| 116 | * grouping will have l_lnno = 0 and in place of physical address will be the | ||
| 117 | * symbol table index of the function name. | ||
| 118 | */ | ||
| 119 | struct external_lineno { | ||
| 120 | union { | ||
| 121 | char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ | ||
| 122 | char l_paddr[4]; /* (physical) address of line number */ | ||
| 123 | } l_addr; | ||
| 124 | char l_lnno[2]; /* line number */ | ||
| 125 | }; | ||
| 126 | |||
| 127 | |||
| 128 | #define LINENO struct external_lineno | ||
| 129 | #define LINESZ 6 | ||
| 130 | |||
| 131 | |||
| 132 | /********************** SYMBOLS **********************/ | ||
| 133 | |||
| 134 | #define E_SYMNMLEN 8 /* # characters in a symbol name */ | ||
| 135 | #define E_FILNMLEN 14 /* # characters in a file name */ | ||
| 136 | #define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ | ||
| 137 | |||
| 138 | struct external_syment | ||
| 139 | { | ||
| 140 | union { | ||
| 141 | char e_name[E_SYMNMLEN]; | ||
| 142 | struct { | ||
| 143 | char e_zeroes[4]; | ||
| 144 | char e_offset[4]; | ||
| 145 | } e; | ||
| 146 | } e; | ||
| 147 | char e_value[4]; | ||
| 148 | char e_scnum[2]; | ||
| 149 | char e_type[2]; | ||
| 150 | char e_sclass[1]; | ||
| 151 | char e_numaux[1]; | ||
| 152 | }; | ||
| 153 | |||
| 154 | |||
| 155 | |||
| 156 | #define N_BTMASK (017) | ||
| 157 | #define N_TMASK (060) | ||
| 158 | #define N_BTSHFT (4) | ||
| 159 | #define N_TSHIFT (2) | ||
| 160 | |||
| 161 | |||
| 162 | union external_auxent { | ||
| 163 | struct { | ||
| 164 | char x_tagndx[4]; /* str, un, or enum tag indx */ | ||
| 165 | union { | ||
| 166 | struct { | ||
| 167 | char x_lnno[2]; /* declaration line number */ | ||
| 168 | char x_size[2]; /* str/union/array size */ | ||
| 169 | } x_lnsz; | ||
| 170 | char x_fsize[4]; /* size of function */ | ||
| 171 | } x_misc; | ||
| 172 | union { | ||
| 173 | struct { /* if ISFCN, tag, or .bb */ | ||
| 174 | char x_lnnoptr[4]; /* ptr to fcn line # */ | ||
| 175 | char x_endndx[4]; /* entry ndx past block end */ | ||
| 176 | } x_fcn; | ||
| 177 | struct { /* if ISARY, up to 4 dimen. */ | ||
| 178 | char x_dimen[E_DIMNUM][2]; | ||
| 179 | } x_ary; | ||
| 180 | } x_fcnary; | ||
| 181 | char x_tvndx[2]; /* tv index */ | ||
| 182 | } x_sym; | ||
| 183 | |||
| 184 | union { | ||
| 185 | char x_fname[E_FILNMLEN]; | ||
| 186 | struct { | ||
| 187 | char x_zeroes[4]; | ||
| 188 | char x_offset[4]; | ||
| 189 | } x_n; | ||
| 190 | } x_file; | ||
| 191 | |||
| 192 | struct { | ||
| 193 | char x_scnlen[4]; /* section length */ | ||
| 194 | char x_nreloc[2]; /* # relocation entries */ | ||
| 195 | char x_nlinno[2]; /* # line numbers */ | ||
| 196 | } x_scn; | ||
| 197 | |||
| 198 | struct { | ||
| 199 | char x_tvfill[4]; /* tv fill value */ | ||
| 200 | char x_tvlen[2]; /* length of .tv */ | ||
| 201 | char x_tvran[2][2]; /* tv range */ | ||
| 202 | } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ | ||
| 203 | |||
| 204 | struct { | ||
| 205 | unsigned char x_scnlen[4]; | ||
| 206 | unsigned char x_parmhash[4]; | ||
| 207 | unsigned char x_snhash[2]; | ||
| 208 | unsigned char x_smtyp[1]; | ||
| 209 | unsigned char x_smclas[1]; | ||
| 210 | unsigned char x_stab[4]; | ||
| 211 | unsigned char x_snstab[2]; | ||
| 212 | } x_csect; | ||
| 213 | |||
| 214 | }; | ||
| 215 | |||
| 216 | #define SYMENT struct external_syment | ||
| 217 | #define SYMESZ 18 | ||
| 218 | #define AUXENT union external_auxent | ||
| 219 | #define AUXESZ 18 | ||
| 220 | #define DBXMASK 0x80 /* for dbx storage mask */ | ||
| 221 | #define SYMNAME_IN_DEBUG(symptr) ((symptr)->n_sclass & DBXMASK) | ||
| 222 | |||
| 223 | |||
| 224 | |||
| 225 | /********************** RELOCATION DIRECTIVES **********************/ | ||
| 226 | |||
| 227 | |||
| 228 | struct external_reloc { | ||
| 229 | char r_vaddr[4]; | ||
| 230 | char r_symndx[4]; | ||
| 231 | char r_size[1]; | ||
| 232 | char r_type[1]; | ||
| 233 | }; | ||
| 234 | |||
| 235 | |||
| 236 | #define RELOC struct external_reloc | ||
| 237 | #define RELSZ 10 | ||
| 238 | |||
| 239 | #define DEFAULT_DATA_SECTION_ALIGNMENT 4 | ||
| 240 | #define DEFAULT_BSS_SECTION_ALIGNMENT 4 | ||
| 241 | #define DEFAULT_TEXT_SECTION_ALIGNMENT 4 | ||
| 242 | /* For new sections we havn't heard of before */ | ||
| 243 | #define DEFAULT_SECTION_ALIGNMENT 4 | ||
diff --git a/arch/powerpc/boot/stdio.c b/arch/powerpc/boot/stdio.c new file mode 100644 index 000000000000..b5aa522f8b77 --- /dev/null +++ b/arch/powerpc/boot/stdio.c | |||
| @@ -0,0 +1,325 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) Paul Mackerras 1997. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU General Public License | ||
| 6 | * as published by the Free Software Foundation; either version | ||
| 7 | * 2 of the License, or (at your option) any later version. | ||
| 8 | */ | ||
| 9 | #include <stdarg.h> | ||
| 10 | #include <stddef.h> | ||
| 11 | #include "string.h" | ||
| 12 | #include "stdio.h" | ||
| 13 | #include "prom.h" | ||
| 14 | |||
| 15 | size_t strnlen(const char * s, size_t count) | ||
| 16 | { | ||
| 17 | const char *sc; | ||
| 18 | |||
| 19 | for (sc = s; count-- && *sc != '\0'; ++sc) | ||
| 20 | /* nothing */; | ||
| 21 | return sc - s; | ||
| 22 | } | ||
| 23 | |||
| 24 | extern unsigned int __div64_32(unsigned long long *dividend, | ||
| 25 | unsigned int divisor); | ||
| 26 | |||
| 27 | /* The unnecessary pointer compare is there | ||
| 28 | * to check for type safety (n must be 64bit) | ||
| 29 | */ | ||
| 30 | # define do_div(n,base) ({ \ | ||
| 31 | unsigned int __base = (base); \ | ||
| 32 | unsigned int __rem; \ | ||
| 33 | (void)(((typeof((n)) *)0) == ((unsigned long long *)0)); \ | ||
| 34 | if (((n) >> 32) == 0) { \ | ||
| 35 | __rem = (unsigned int)(n) % __base; \ | ||
| 36 | (n) = (unsigned int)(n) / __base; \ | ||
| 37 | } else \ | ||
| 38 | __rem = __div64_32(&(n), __base); \ | ||
| 39 | __rem; \ | ||
| 40 | }) | ||
| 41 | |||
| 42 | static int skip_atoi(const char **s) | ||
| 43 | { | ||
| 44 | int i, c; | ||
| 45 | |||
| 46 | for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s) | ||
| 47 | i = i*10 + c - '0'; | ||
| 48 | return i; | ||
| 49 | } | ||
| 50 | |||
| 51 | #define ZEROPAD 1 /* pad with zero */ | ||
| 52 | #define SIGN 2 /* unsigned/signed long */ | ||
| 53 | #define PLUS 4 /* show plus */ | ||
| 54 | #define SPACE 8 /* space if plus */ | ||
| 55 | #define LEFT 16 /* left justified */ | ||
| 56 | #define SPECIAL 32 /* 0x */ | ||
| 57 | #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ | ||
| 58 | |||
| 59 | static char * number(char * str, unsigned long long num, int base, int size, int precision, int type) | ||
| 60 | { | ||
| 61 | char c,sign,tmp[66]; | ||
| 62 | const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; | ||
| 63 | int i; | ||
| 64 | |||
| 65 | if (type & LARGE) | ||
| 66 | digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | ||
| 67 | if (type & LEFT) | ||
| 68 | type &= ~ZEROPAD; | ||
| 69 | if (base < 2 || base > 36) | ||
| 70 | return 0; | ||
| 71 | c = (type & ZEROPAD) ? '0' : ' '; | ||
| 72 | sign = 0; | ||
| 73 | if (type & SIGN) { | ||
| 74 | if ((signed long long)num < 0) { | ||
| 75 | sign = '-'; | ||
| 76 | num = - (signed long long)num; | ||
| 77 | size--; | ||
| 78 | } else if (type & PLUS) { | ||
| 79 | sign = '+'; | ||
| 80 | size--; | ||
| 81 | } else if (type & SPACE) { | ||
| 82 | sign = ' '; | ||
| 83 | size--; | ||
| 84 | } | ||
| 85 | } | ||
| 86 | if (type & SPECIAL) { | ||
| 87 | if (base == 16) | ||
| 88 | size -= 2; | ||
| 89 | else if (base == 8) | ||
| 90 | size--; | ||
| 91 | } | ||
| 92 | i = 0; | ||
| 93 | if (num == 0) | ||
| 94 | tmp[i++]='0'; | ||
| 95 | else while (num != 0) { | ||
| 96 | tmp[i++] = digits[do_div(num, base)]; | ||
| 97 | } | ||
| 98 | if (i > precision) | ||
| 99 | precision = i; | ||
| 100 | size -= precision; | ||
| 101 | if (!(type&(ZEROPAD+LEFT))) | ||
| 102 | while(size-->0) | ||
| 103 | *str++ = ' '; | ||
| 104 | if (sign) | ||
| 105 | *str++ = sign; | ||
| 106 | if (type & SPECIAL) { | ||
| 107 | if (base==8) | ||
| 108 | *str++ = '0'; | ||
| 109 | else if (base==16) { | ||
| 110 | *str++ = '0'; | ||
| 111 | *str++ = digits[33]; | ||
| 112 | } | ||
| 113 | } | ||
| 114 | if (!(type & LEFT)) | ||
| 115 | while (size-- > 0) | ||
| 116 | *str++ = c; | ||
| 117 | while (i < precision--) | ||
| 118 | *str++ = '0'; | ||
| 119 | while (i-- > 0) | ||
| 120 | *str++ = tmp[i]; | ||
| 121 | while (size-- > 0) | ||
| 122 | *str++ = ' '; | ||
| 123 | return str; | ||
| 124 | } | ||
| 125 | |||
| 126 | int vsprintf(char *buf, const char *fmt, va_list args) | ||
| 127 | { | ||
| 128 | int len; | ||
| 129 | unsigned long long num; | ||
| 130 | int i, base; | ||
| 131 | char * str; | ||
| 132 | const char *s; | ||
| 133 | |||
| 134 | int flags; /* flags to number() */ | ||
| 135 | |||
| 136 | int field_width; /* width of output field */ | ||
| 137 | int precision; /* min. # of digits for integers; max | ||
| 138 | number of chars for from string */ | ||
| 139 | int qualifier; /* 'h', 'l', or 'L' for integer fields */ | ||
| 140 | /* 'z' support added 23/7/1999 S.H. */ | ||
| 141 | /* 'z' changed to 'Z' --davidm 1/25/99 */ | ||
| 142 | |||
| 143 | |||
| 144 | for (str=buf ; *fmt ; ++fmt) { | ||
| 145 | if (*fmt != '%') { | ||
| 146 | *str++ = *fmt; | ||
| 147 | continue; | ||
| 148 | } | ||
| 149 | |||
| 150 | /* process flags */ | ||
| 151 | flags = 0; | ||
| 152 | repeat: | ||
| 153 | ++fmt; /* this also skips first '%' */ | ||
| 154 | switch (*fmt) { | ||
| 155 | case '-': flags |= LEFT; goto repeat; | ||
| 156 | case '+': flags |= PLUS; goto repeat; | ||
| 157 | case ' ': flags |= SPACE; goto repeat; | ||
| 158 | case '#': flags |= SPECIAL; goto repeat; | ||
| 159 | case '0': flags |= ZEROPAD; goto repeat; | ||
| 160 | } | ||
| 161 | |||
| 162 | /* get field width */ | ||
| 163 | field_width = -1; | ||
| 164 | if ('0' <= *fmt && *fmt <= '9') | ||
| 165 | field_width = skip_atoi(&fmt); | ||
| 166 | else if (*fmt == '*') { | ||
| 167 | ++fmt; | ||
| 168 | /* it's the next argument */ | ||
| 169 | field_width = va_arg(args, int); | ||
| 170 | if (field_width < 0) { | ||
| 171 | field_width = -field_width; | ||
| 172 | flags |= LEFT; | ||
| 173 | } | ||
| 174 | } | ||
| 175 | |||
| 176 | /* get the precision */ | ||
| 177 | precision = -1; | ||
| 178 | if (*fmt == '.') { | ||
| 179 | ++fmt; | ||
| 180 | if ('0' <= *fmt && *fmt <= '9') | ||
| 181 | precision = skip_atoi(&fmt); | ||
| 182 | else if (*fmt == '*') { | ||
| 183 | ++fmt; | ||
| 184 | /* it's the next argument */ | ||
| 185 | precision = va_arg(args, int); | ||
| 186 | } | ||
| 187 | if (precision < 0) | ||
| 188 | precision = 0; | ||
| 189 | } | ||
| 190 | |||
| 191 | /* get the conversion qualifier */ | ||
| 192 | qualifier = -1; | ||
| 193 | if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') { | ||
| 194 | qualifier = *fmt; | ||
| 195 | ++fmt; | ||
| 196 | } | ||
| 197 | |||
| 198 | /* default base */ | ||
| 199 | base = 10; | ||
| 200 | |||
| 201 | switch (*fmt) { | ||
| 202 | case 'c': | ||
| 203 | if (!(flags & LEFT)) | ||
| 204 | while (--field_width > 0) | ||
| 205 | *str++ = ' '; | ||
| 206 | *str++ = (unsigned char) va_arg(args, int); | ||
| 207 | while (--field_width > 0) | ||
| 208 | *str++ = ' '; | ||
| 209 | continue; | ||
| 210 | |||
| 211 | case 's': | ||
| 212 | s = va_arg(args, char *); | ||
| 213 | if (!s) | ||
| 214 | s = "<NULL>"; | ||
| 215 | |||
| 216 | len = strnlen(s, precision); | ||
| 217 | |||
| 218 | if (!(flags & LEFT)) | ||
| 219 | while (len < field_width--) | ||
| 220 | *str++ = ' '; | ||
| 221 | for (i = 0; i < len; ++i) | ||
| 222 | *str++ = *s++; | ||
| 223 | while (len < field_width--) | ||
| 224 | *str++ = ' '; | ||
| 225 | continue; | ||
| 226 | |||
| 227 | case 'p': | ||
| 228 | if (field_width == -1) { | ||
| 229 | field_width = 2*sizeof(void *); | ||
| 230 | flags |= ZEROPAD; | ||
| 231 | } | ||
| 232 | str = number(str, | ||
| 233 | (unsigned long) va_arg(args, void *), 16, | ||
| 234 | field_width, precision, flags); | ||
| 235 | continue; | ||
| 236 | |||
| 237 | |||
| 238 | case 'n': | ||
| 239 | if (qualifier == 'l') { | ||
| 240 | long * ip = va_arg(args, long *); | ||
| 241 | *ip = (str - buf); | ||
| 242 | } else if (qualifier == 'Z') { | ||
| 243 | size_t * ip = va_arg(args, size_t *); | ||
| 244 | *ip = (str - buf); | ||
| 245 | } else { | ||
| 246 | int * ip = va_arg(args, int *); | ||
| 247 | *ip = (str - buf); | ||
| 248 | } | ||
| 249 | continue; | ||
| 250 | |||
| 251 | case '%': | ||
| 252 | *str++ = '%'; | ||
| 253 | continue; | ||
| 254 | |||
| 255 | /* integer number formats - set up the flags and "break" */ | ||
| 256 | case 'o': | ||
| 257 | base = 8; | ||
| 258 | break; | ||
| 259 | |||
| 260 | case 'X': | ||
| 261 | flags |= LARGE; | ||
| 262 | case 'x': | ||
| 263 | base = 16; | ||
| 264 | break; | ||
| 265 | |||
| 266 | case 'd': | ||
| 267 | case 'i': | ||
| 268 | flags |= SIGN; | ||
| 269 | case 'u': | ||
| 270 | break; | ||
| 271 | |||
| 272 | default: | ||
| 273 | *str++ = '%'; | ||
| 274 | if (*fmt) | ||
| 275 | *str++ = *fmt; | ||
| 276 | else | ||
| 277 | --fmt; | ||
| 278 | continue; | ||
| 279 | } | ||
| 280 | if (qualifier == 'l') { | ||
| 281 | num = va_arg(args, unsigned long); | ||
| 282 | if (flags & SIGN) | ||
| 283 | num = (signed long) num; | ||
| 284 | } else if (qualifier == 'Z') { | ||
| 285 | num = va_arg(args, size_t); | ||
| 286 | } else if (qualifier == 'h') { | ||
| 287 | num = (unsigned short) va_arg(args, int); | ||
| 288 | if (flags & SIGN) | ||
| 289 | num = (signed short) num; | ||
| 290 | } else { | ||
| 291 | num = va_arg(args, unsigned int); | ||
| 292 | if (flags & SIGN) | ||
| 293 | num = (signed int) num; | ||
| 294 | } | ||
| 295 | str = number(str, num, base, field_width, precision, flags); | ||
| 296 | } | ||
| 297 | *str = '\0'; | ||
| 298 | return str-buf; | ||
| 299 | } | ||
| 300 | |||
| 301 | int sprintf(char * buf, const char *fmt, ...) | ||
| 302 | { | ||
| 303 | va_list args; | ||
| 304 | int i; | ||
| 305 | |||
| 306 | va_start(args, fmt); | ||
| 307 | i=vsprintf(buf,fmt,args); | ||
| 308 | va_end(args); | ||
| 309 | return i; | ||
| 310 | } | ||
| 311 | |||
| 312 | static char sprint_buf[1024]; | ||
| 313 | |||
| 314 | int | ||
| 315 | printf(const char *fmt, ...) | ||
| 316 | { | ||
| 317 | va_list args; | ||
| 318 | int n; | ||
| 319 | |||
| 320 | va_start(args, fmt); | ||
| 321 | n = vsprintf(sprint_buf, fmt, args); | ||
| 322 | va_end(args); | ||
| 323 | write(stdout, sprint_buf, n); | ||
| 324 | return n; | ||
| 325 | } | ||
diff --git a/arch/powerpc/boot/stdio.h b/arch/powerpc/boot/stdio.h index 24bd3a8dee94..eb9e16c87aef 100644 --- a/arch/powerpc/boot/stdio.h +++ b/arch/powerpc/boot/stdio.h | |||
| @@ -7,10 +7,4 @@ extern int sprintf(char *buf, const char *fmt, ...); | |||
| 7 | 7 | ||
| 8 | extern int vsprintf(char *buf, const char *fmt, va_list args); | 8 | extern int vsprintf(char *buf, const char *fmt, va_list args); |
| 9 | 9 | ||
| 10 | extern int putc(int c, void *f); | ||
| 11 | extern int putchar(int c); | ||
| 12 | extern int getchar(void); | ||
| 13 | |||
| 14 | extern int fputs(char *str, void *f); | ||
| 15 | |||
| 16 | #endif /* _PPC_BOOT_STDIO_H_ */ | 10 | #endif /* _PPC_BOOT_STDIO_H_ */ |
diff --git a/arch/powerpc/boot/string.S b/arch/powerpc/boot/string.S index b1eeaed7db17..ac3d43b6a324 100644 --- a/arch/powerpc/boot/string.S +++ b/arch/powerpc/boot/string.S | |||
| @@ -107,10 +107,12 @@ memcpy: | |||
| 107 | rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */ | 107 | rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */ |
| 108 | addi r6,r3,-4 | 108 | addi r6,r3,-4 |
| 109 | addi r4,r4,-4 | 109 | addi r4,r4,-4 |
| 110 | beq 2f /* if less than 8 bytes to do */ | 110 | beq 3f /* if less than 8 bytes to do */ |
| 111 | andi. r0,r6,3 /* get dest word aligned */ | 111 | andi. r0,r6,3 /* get dest word aligned */ |
| 112 | mtctr r7 | 112 | mtctr r7 |
| 113 | bne 5f | 113 | bne 5f |
| 114 | andi. r0,r4,3 /* check src word aligned too */ | ||
| 115 | bne 3f | ||
| 114 | 1: lwz r7,4(r4) | 116 | 1: lwz r7,4(r4) |
| 115 | lwzu r8,8(r4) | 117 | lwzu r8,8(r4) |
| 116 | stw r7,4(r6) | 118 | stw r7,4(r6) |
| @@ -132,6 +134,11 @@ memcpy: | |||
| 132 | bdnz 4b | 134 | bdnz 4b |
| 133 | blr | 135 | blr |
| 134 | 5: subfic r0,r0,4 | 136 | 5: subfic r0,r0,4 |
| 137 | cmpw cr1,r0,r5 | ||
| 138 | add r7,r0,r4 | ||
| 139 | andi. r7,r7,3 /* will source be word-aligned too? */ | ||
| 140 | ble cr1,3b | ||
| 141 | bne 3b /* do byte-by-byte if not */ | ||
| 135 | mtctr r0 | 142 | mtctr r0 |
| 136 | 6: lbz r7,4(r4) | 143 | 6: lbz r7,4(r4) |
| 137 | addi r4,r4,1 | 144 | addi r4,r4,1 |
| @@ -149,10 +156,12 @@ backwards_memcpy: | |||
| 149 | rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */ | 156 | rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */ |
| 150 | add r6,r3,r5 | 157 | add r6,r3,r5 |
| 151 | add r4,r4,r5 | 158 | add r4,r4,r5 |
| 152 | beq 2f | 159 | beq 3f |
| 153 | andi. r0,r6,3 | 160 | andi. r0,r6,3 |
| 154 | mtctr r7 | 161 | mtctr r7 |
| 155 | bne 5f | 162 | bne 5f |
| 163 | andi. r0,r4,3 | ||
| 164 | bne 3f | ||
| 156 | 1: lwz r7,-4(r4) | 165 | 1: lwz r7,-4(r4) |
| 157 | lwzu r8,-8(r4) | 166 | lwzu r8,-8(r4) |
| 158 | stw r7,-4(r6) | 167 | stw r7,-4(r6) |
| @@ -171,7 +180,12 @@ backwards_memcpy: | |||
| 171 | stbu r0,-1(r6) | 180 | stbu r0,-1(r6) |
| 172 | bdnz 4b | 181 | bdnz 4b |
| 173 | blr | 182 | blr |
| 174 | 5: mtctr r0 | 183 | 5: cmpw cr1,r0,r5 |
| 184 | subf r7,r0,r4 | ||
| 185 | andi. r7,r7,3 | ||
| 186 | ble cr1,3b | ||
| 187 | bne 3b | ||
| 188 | mtctr r0 | ||
| 175 | 6: lbzu r7,-1(r4) | 189 | 6: lbzu r7,-1(r4) |
| 176 | stbu r7,-1(r6) | 190 | stbu r7,-1(r6) |
| 177 | bdnz 6b | 191 | bdnz 6b |
diff --git a/arch/powerpc/boot/zImage.coff.lds b/arch/powerpc/boot/zImage.coff.lds new file mode 100644 index 000000000000..6016251a1a2c --- /dev/null +++ b/arch/powerpc/boot/zImage.coff.lds | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | OUTPUT_ARCH(powerpc:common) | ||
| 2 | ENTRY(_start) | ||
| 3 | SECTIONS | ||
| 4 | { | ||
| 5 | . = (5*1024*1024); | ||
| 6 | _start = .; | ||
| 7 | .text : | ||
| 8 | { | ||
| 9 | *(.text) | ||
| 10 | *(.fixup) | ||
| 11 | } | ||
| 12 | _etext = .; | ||
| 13 | . = ALIGN(4096); | ||
| 14 | .data : | ||
| 15 | { | ||
| 16 | *(.rodata*) | ||
| 17 | *(.data*) | ||
| 18 | *(.sdata*) | ||
| 19 | __got2_start = .; | ||
| 20 | *(.got2) | ||
| 21 | __got2_end = .; | ||
| 22 | |||
| 23 | _vmlinux_start = .; | ||
| 24 | *(.kernel:vmlinux.strip) | ||
| 25 | _vmlinux_end = .; | ||
| 26 | |||
| 27 | _initrd_start = .; | ||
| 28 | *(.kernel:initrd) | ||
| 29 | _initrd_end = .; | ||
| 30 | } | ||
| 31 | |||
| 32 | . = ALIGN(4096); | ||
| 33 | _edata = .; | ||
| 34 | __bss_start = .; | ||
| 35 | .bss : | ||
| 36 | { | ||
| 37 | *(.sbss) | ||
| 38 | *(.bss) | ||
| 39 | } | ||
| 40 | _end = . ; | ||
| 41 | |||
| 42 | /DISCARD/ : | ||
| 43 | { | ||
| 44 | *(.comment) | ||
| 45 | } | ||
| 46 | } | ||
diff --git a/arch/powerpc/configs/mpc834x_sys_defconfig b/arch/powerpc/configs/mpc834x_sys_defconfig new file mode 100644 index 000000000000..3bff761965c2 --- /dev/null +++ b/arch/powerpc/configs/mpc834x_sys_defconfig | |||
| @@ -0,0 +1,911 @@ | |||
| 1 | # | ||
| 2 | # Automatically generated make config: don't edit | ||
| 3 | # Linux kernel version: 2.6.15-g461d4edf-dirty | ||
| 4 | # Fri Jan 13 11:01:47 2006 | ||
| 5 | # | ||
| 6 | # CONFIG_PPC64 is not set | ||
| 7 | CONFIG_PPC32=y | ||
| 8 | CONFIG_PPC_MERGE=y | ||
| 9 | CONFIG_MMU=y | ||
| 10 | CONFIG_GENERIC_HARDIRQS=y | ||
| 11 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | ||
| 12 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
| 13 | CONFIG_PPC=y | ||
| 14 | CONFIG_EARLY_PRINTK=y | ||
| 15 | CONFIG_GENERIC_NVRAM=y | ||
| 16 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y | ||
| 17 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y | ||
| 18 | CONFIG_PPC_OF=y | ||
| 19 | CONFIG_PPC_UDBG_16550=y | ||
| 20 | # CONFIG_GENERIC_TBSYNC is not set | ||
| 21 | CONFIG_DEFAULT_UIMAGE=y | ||
| 22 | |||
| 23 | # | ||
| 24 | # Processor support | ||
| 25 | # | ||
| 26 | # CONFIG_CLASSIC32 is not set | ||
| 27 | # CONFIG_PPC_52xx is not set | ||
| 28 | # CONFIG_PPC_82xx is not set | ||
| 29 | CONFIG_PPC_83xx=y | ||
| 30 | # CONFIG_40x is not set | ||
| 31 | # CONFIG_44x is not set | ||
| 32 | # CONFIG_8xx is not set | ||
| 33 | # CONFIG_E200 is not set | ||
| 34 | # CONFIG_E500 is not set | ||
| 35 | CONFIG_6xx=y | ||
| 36 | CONFIG_83xx=y | ||
| 37 | CONFIG_PPC_FPU=y | ||
| 38 | CONFIG_PPC_STD_MMU=y | ||
| 39 | CONFIG_PPC_STD_MMU_32=y | ||
| 40 | # CONFIG_SMP is not set | ||
| 41 | |||
| 42 | # | ||
| 43 | # Code maturity level options | ||
| 44 | # | ||
| 45 | CONFIG_EXPERIMENTAL=y | ||
| 46 | CONFIG_CLEAN_COMPILE=y | ||
| 47 | CONFIG_BROKEN_ON_SMP=y | ||
| 48 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
| 49 | |||
| 50 | # | ||
| 51 | # General setup | ||
| 52 | # | ||
| 53 | CONFIG_LOCALVERSION="" | ||
| 54 | CONFIG_LOCALVERSION_AUTO=y | ||
| 55 | CONFIG_SWAP=y | ||
| 56 | CONFIG_SYSVIPC=y | ||
| 57 | # CONFIG_POSIX_MQUEUE is not set | ||
| 58 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
| 59 | CONFIG_SYSCTL=y | ||
| 60 | # CONFIG_AUDIT is not set | ||
| 61 | # CONFIG_IKCONFIG is not set | ||
| 62 | CONFIG_INITRAMFS_SOURCE="" | ||
| 63 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
| 64 | CONFIG_EMBEDDED=y | ||
| 65 | # CONFIG_KALLSYMS is not set | ||
| 66 | CONFIG_HOTPLUG=y | ||
| 67 | CONFIG_PRINTK=y | ||
| 68 | CONFIG_BUG=y | ||
| 69 | CONFIG_ELF_CORE=y | ||
| 70 | CONFIG_BASE_FULL=y | ||
| 71 | CONFIG_FUTEX=y | ||
| 72 | # CONFIG_EPOLL is not set | ||
| 73 | CONFIG_SHMEM=y | ||
| 74 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
| 75 | CONFIG_CC_ALIGN_LABELS=0 | ||
| 76 | CONFIG_CC_ALIGN_LOOPS=0 | ||
| 77 | CONFIG_CC_ALIGN_JUMPS=0 | ||
| 78 | CONFIG_SLAB=y | ||
| 79 | # CONFIG_TINY_SHMEM is not set | ||
| 80 | CONFIG_BASE_SMALL=0 | ||
| 81 | # CONFIG_SLOB is not set | ||
| 82 | |||
| 83 | # | ||
| 84 | # Loadable module support | ||
| 85 | # | ||
| 86 | CONFIG_MODULES=y | ||
| 87 | CONFIG_MODULE_UNLOAD=y | ||
| 88 | # CONFIG_MODULE_FORCE_UNLOAD is not set | ||
| 89 | CONFIG_OBSOLETE_MODPARM=y | ||
| 90 | # CONFIG_MODVERSIONS is not set | ||
| 91 | # CONFIG_MODULE_SRCVERSION_ALL is not set | ||
| 92 | # CONFIG_KMOD is not set | ||
| 93 | |||
| 94 | # | ||
| 95 | # Block layer | ||
| 96 | # | ||
| 97 | # CONFIG_LBD is not set | ||
| 98 | |||
| 99 | # | ||
| 100 | # IO Schedulers | ||
| 101 | # | ||
| 102 | CONFIG_IOSCHED_NOOP=y | ||
| 103 | CONFIG_IOSCHED_AS=y | ||
| 104 | CONFIG_IOSCHED_DEADLINE=y | ||
| 105 | CONFIG_IOSCHED_CFQ=y | ||
| 106 | CONFIG_DEFAULT_AS=y | ||
| 107 | # CONFIG_DEFAULT_DEADLINE is not set | ||
| 108 | # CONFIG_DEFAULT_CFQ is not set | ||
| 109 | # CONFIG_DEFAULT_NOOP is not set | ||
| 110 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
| 111 | CONFIG_PPC_GEN550=y | ||
| 112 | # CONFIG_WANT_EARLY_SERIAL is not set | ||
| 113 | |||
| 114 | # | ||
| 115 | # Platform support | ||
| 116 | # | ||
| 117 | CONFIG_MPC834x_SYS=y | ||
| 118 | CONFIG_MPC834x=y | ||
| 119 | |||
| 120 | # | ||
| 121 | # Kernel options | ||
| 122 | # | ||
| 123 | # CONFIG_HIGHMEM is not set | ||
| 124 | # CONFIG_HZ_100 is not set | ||
| 125 | CONFIG_HZ_250=y | ||
| 126 | # CONFIG_HZ_1000 is not set | ||
| 127 | CONFIG_HZ=250 | ||
| 128 | CONFIG_PREEMPT_NONE=y | ||
| 129 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
| 130 | # CONFIG_PREEMPT is not set | ||
| 131 | CONFIG_BINFMT_ELF=y | ||
| 132 | # CONFIG_BINFMT_MISC is not set | ||
| 133 | CONFIG_ARCH_FLATMEM_ENABLE=y | ||
| 134 | CONFIG_SELECT_MEMORY_MODEL=y | ||
| 135 | CONFIG_FLATMEM_MANUAL=y | ||
| 136 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
| 137 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
| 138 | CONFIG_FLATMEM=y | ||
| 139 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
| 140 | # CONFIG_SPARSEMEM_STATIC is not set | ||
| 141 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
| 142 | CONFIG_PROC_DEVICETREE=y | ||
| 143 | # CONFIG_CMDLINE_BOOL is not set | ||
| 144 | # CONFIG_PM is not set | ||
| 145 | # CONFIG_SOFTWARE_SUSPEND is not set | ||
| 146 | CONFIG_SECCOMP=y | ||
| 147 | CONFIG_ISA_DMA_API=y | ||
| 148 | |||
| 149 | # | ||
| 150 | # Bus options | ||
| 151 | # | ||
| 152 | CONFIG_GENERIC_ISA_DMA=y | ||
| 153 | # CONFIG_PPC_I8259 is not set | ||
| 154 | CONFIG_PPC_INDIRECT_PCI=y | ||
| 155 | CONFIG_FSL_SOC=y | ||
| 156 | CONFIG_PCI=y | ||
| 157 | CONFIG_PCI_DOMAINS=y | ||
| 158 | # CONFIG_PCI_LEGACY_PROC is not set | ||
| 159 | |||
| 160 | # | ||
| 161 | # PCCARD (PCMCIA/CardBus) support | ||
| 162 | # | ||
| 163 | # CONFIG_PCCARD is not set | ||
| 164 | |||
| 165 | # | ||
| 166 | # PCI Hotplug Support | ||
| 167 | # | ||
| 168 | # CONFIG_HOTPLUG_PCI is not set | ||
| 169 | |||
| 170 | # | ||
| 171 | # Advanced setup | ||
| 172 | # | ||
| 173 | # CONFIG_ADVANCED_OPTIONS is not set | ||
| 174 | |||
| 175 | # | ||
| 176 | # Default settings for advanced configuration options are used | ||
| 177 | # | ||
| 178 | CONFIG_HIGHMEM_START=0xfe000000 | ||
| 179 | CONFIG_LOWMEM_SIZE=0x30000000 | ||
| 180 | CONFIG_KERNEL_START=0xc0000000 | ||
| 181 | CONFIG_TASK_SIZE=0x80000000 | ||
| 182 | CONFIG_BOOT_LOAD=0x00800000 | ||
| 183 | |||
| 184 | # | ||
| 185 | # Networking | ||
| 186 | # | ||
| 187 | CONFIG_NET=y | ||
| 188 | |||
| 189 | # | ||
| 190 | # Networking options | ||
| 191 | # | ||
| 192 | CONFIG_PACKET=y | ||
| 193 | # CONFIG_PACKET_MMAP is not set | ||
| 194 | CONFIG_UNIX=y | ||
| 195 | # CONFIG_NET_KEY is not set | ||
| 196 | CONFIG_INET=y | ||
| 197 | CONFIG_IP_MULTICAST=y | ||
| 198 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
| 199 | CONFIG_IP_FIB_HASH=y | ||
| 200 | CONFIG_IP_PNP=y | ||
| 201 | CONFIG_IP_PNP_DHCP=y | ||
| 202 | CONFIG_IP_PNP_BOOTP=y | ||
| 203 | # CONFIG_IP_PNP_RARP is not set | ||
| 204 | # CONFIG_NET_IPIP is not set | ||
| 205 | # CONFIG_NET_IPGRE is not set | ||
| 206 | # CONFIG_IP_MROUTE is not set | ||
| 207 | # CONFIG_ARPD is not set | ||
| 208 | CONFIG_SYN_COOKIES=y | ||
| 209 | # CONFIG_INET_AH is not set | ||
| 210 | # CONFIG_INET_ESP is not set | ||
| 211 | # CONFIG_INET_IPCOMP is not set | ||
| 212 | # CONFIG_INET_TUNNEL is not set | ||
| 213 | CONFIG_INET_DIAG=y | ||
| 214 | CONFIG_INET_TCP_DIAG=y | ||
| 215 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
| 216 | CONFIG_TCP_CONG_BIC=y | ||
| 217 | # CONFIG_IPV6 is not set | ||
| 218 | # CONFIG_NETFILTER is not set | ||
| 219 | |||
| 220 | # | ||
| 221 | # DCCP Configuration (EXPERIMENTAL) | ||
| 222 | # | ||
| 223 | # CONFIG_IP_DCCP is not set | ||
| 224 | |||
| 225 | # | ||
| 226 | # SCTP Configuration (EXPERIMENTAL) | ||
| 227 | # | ||
| 228 | # CONFIG_IP_SCTP is not set | ||
| 229 | # CONFIG_ATM is not set | ||
| 230 | # CONFIG_BRIDGE is not set | ||
| 231 | # CONFIG_VLAN_8021Q is not set | ||
| 232 | # CONFIG_DECNET is not set | ||
| 233 | # CONFIG_LLC2 is not set | ||
| 234 | # CONFIG_IPX is not set | ||
| 235 | # CONFIG_ATALK is not set | ||
| 236 | # CONFIG_X25 is not set | ||
| 237 | # CONFIG_LAPB is not set | ||
| 238 | # CONFIG_NET_DIVERT is not set | ||
| 239 | # CONFIG_ECONET is not set | ||
| 240 | # CONFIG_WAN_ROUTER is not set | ||
| 241 | |||
| 242 | # | ||
| 243 | # QoS and/or fair queueing | ||
| 244 | # | ||
| 245 | # CONFIG_NET_SCHED is not set | ||
| 246 | |||
| 247 | # | ||
| 248 | # Network testing | ||
| 249 | # | ||
| 250 | # CONFIG_NET_PKTGEN is not set | ||
| 251 | # CONFIG_HAMRADIO is not set | ||
| 252 | # CONFIG_IRDA is not set | ||
| 253 | # CONFIG_BT is not set | ||
| 254 | # CONFIG_IEEE80211 is not set | ||
| 255 | |||
| 256 | # | ||
| 257 | # Device Drivers | ||
| 258 | # | ||
| 259 | |||
| 260 | # | ||
| 261 | # Generic Driver Options | ||
| 262 | # | ||
| 263 | CONFIG_STANDALONE=y | ||
| 264 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
| 265 | # CONFIG_FW_LOADER is not set | ||
| 266 | |||
| 267 | # | ||
| 268 | # Connector - unified userspace <-> kernelspace linker | ||
| 269 | # | ||
| 270 | # CONFIG_CONNECTOR is not set | ||
| 271 | |||
| 272 | # | ||
| 273 | # Memory Technology Devices (MTD) | ||
| 274 | # | ||
| 275 | # CONFIG_MTD is not set | ||
| 276 | |||
| 277 | # | ||
| 278 | # Parallel port support | ||
| 279 | # | ||
| 280 | # CONFIG_PARPORT is not set | ||
| 281 | |||
| 282 | # | ||
| 283 | # Plug and Play support | ||
| 284 | # | ||
| 285 | |||
| 286 | # | ||
| 287 | # Block devices | ||
| 288 | # | ||
| 289 | # CONFIG_BLK_DEV_FD is not set | ||
| 290 | # CONFIG_BLK_CPQ_DA is not set | ||
| 291 | # CONFIG_BLK_CPQ_CISS_DA is not set | ||
| 292 | # CONFIG_BLK_DEV_DAC960 is not set | ||
| 293 | # CONFIG_BLK_DEV_UMEM is not set | ||
| 294 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
| 295 | CONFIG_BLK_DEV_LOOP=y | ||
| 296 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | ||
| 297 | # CONFIG_BLK_DEV_NBD is not set | ||
| 298 | # CONFIG_BLK_DEV_SX8 is not set | ||
| 299 | CONFIG_BLK_DEV_RAM=y | ||
| 300 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
| 301 | CONFIG_BLK_DEV_RAM_SIZE=32768 | ||
| 302 | CONFIG_BLK_DEV_INITRD=y | ||
| 303 | # CONFIG_CDROM_PKTCDVD is not set | ||
| 304 | # CONFIG_ATA_OVER_ETH is not set | ||
| 305 | |||
| 306 | # | ||
| 307 | # ATA/ATAPI/MFM/RLL support | ||
| 308 | # | ||
| 309 | # CONFIG_IDE is not set | ||
| 310 | |||
| 311 | # | ||
| 312 | # SCSI device support | ||
| 313 | # | ||
| 314 | # CONFIG_RAID_ATTRS is not set | ||
| 315 | # CONFIG_SCSI is not set | ||
| 316 | |||
| 317 | # | ||
| 318 | # Multi-device support (RAID and LVM) | ||
| 319 | # | ||
| 320 | # CONFIG_MD is not set | ||
| 321 | |||
| 322 | # | ||
| 323 | # Fusion MPT device support | ||
| 324 | # | ||
| 325 | # CONFIG_FUSION is not set | ||
| 326 | |||
| 327 | # | ||
| 328 | # IEEE 1394 (FireWire) support | ||
| 329 | # | ||
| 330 | # CONFIG_IEEE1394 is not set | ||
| 331 | |||
| 332 | # | ||
| 333 | # I2O device support | ||
| 334 | # | ||
| 335 | # CONFIG_I2O is not set | ||
| 336 | |||
| 337 | # | ||
| 338 | # Macintosh device drivers | ||
| 339 | # | ||
| 340 | # CONFIG_WINDFARM is not set | ||
| 341 | |||
| 342 | # | ||
| 343 | # Network device support | ||
| 344 | # | ||
| 345 | CONFIG_NETDEVICES=y | ||
| 346 | # CONFIG_DUMMY is not set | ||
| 347 | # CONFIG_BONDING is not set | ||
| 348 | # CONFIG_EQUALIZER is not set | ||
| 349 | # CONFIG_TUN is not set | ||
| 350 | |||
| 351 | # | ||
| 352 | # ARCnet devices | ||
| 353 | # | ||
| 354 | # CONFIG_ARCNET is not set | ||
| 355 | |||
| 356 | # | ||
| 357 | # PHY device support | ||
| 358 | # | ||
| 359 | CONFIG_PHYLIB=y | ||
| 360 | |||
| 361 | # | ||
| 362 | # MII PHY device drivers | ||
| 363 | # | ||
| 364 | CONFIG_MARVELL_PHY=y | ||
| 365 | # CONFIG_DAVICOM_PHY is not set | ||
| 366 | # CONFIG_QSEMI_PHY is not set | ||
| 367 | # CONFIG_LXT_PHY is not set | ||
| 368 | # CONFIG_CICADA_PHY is not set | ||
| 369 | |||
| 370 | # | ||
| 371 | # Ethernet (10 or 100Mbit) | ||
| 372 | # | ||
| 373 | CONFIG_NET_ETHERNET=y | ||
| 374 | CONFIG_MII=y | ||
| 375 | # CONFIG_HAPPYMEAL is not set | ||
| 376 | # CONFIG_SUNGEM is not set | ||
| 377 | # CONFIG_CASSINI is not set | ||
| 378 | # CONFIG_NET_VENDOR_3COM is not set | ||
| 379 | |||
| 380 | # | ||
| 381 | # Tulip family network device support | ||
| 382 | # | ||
| 383 | # CONFIG_NET_TULIP is not set | ||
| 384 | # CONFIG_HP100 is not set | ||
| 385 | CONFIG_NET_PCI=y | ||
| 386 | # CONFIG_PCNET32 is not set | ||
| 387 | # CONFIG_AMD8111_ETH is not set | ||
| 388 | # CONFIG_ADAPTEC_STARFIRE is not set | ||
| 389 | # CONFIG_B44 is not set | ||
| 390 | # CONFIG_FORCEDETH is not set | ||
| 391 | # CONFIG_DGRS is not set | ||
| 392 | # CONFIG_EEPRO100 is not set | ||
| 393 | CONFIG_E100=y | ||
| 394 | # CONFIG_FEALNX is not set | ||
| 395 | # CONFIG_NATSEMI is not set | ||
| 396 | # CONFIG_NE2K_PCI is not set | ||
| 397 | # CONFIG_8139CP is not set | ||
| 398 | # CONFIG_8139TOO is not set | ||
| 399 | # CONFIG_SIS900 is not set | ||
| 400 | # CONFIG_EPIC100 is not set | ||
| 401 | # CONFIG_SUNDANCE is not set | ||
| 402 | # CONFIG_TLAN is not set | ||
| 403 | # CONFIG_VIA_RHINE is not set | ||
| 404 | |||
| 405 | # | ||
| 406 | # Ethernet (1000 Mbit) | ||
| 407 | # | ||
| 408 | # CONFIG_ACENIC is not set | ||
| 409 | # CONFIG_DL2K is not set | ||
| 410 | # CONFIG_E1000 is not set | ||
| 411 | # CONFIG_NS83820 is not set | ||
| 412 | # CONFIG_HAMACHI is not set | ||
| 413 | # CONFIG_YELLOWFIN is not set | ||
| 414 | # CONFIG_R8169 is not set | ||
| 415 | # CONFIG_SIS190 is not set | ||
| 416 | # CONFIG_SKGE is not set | ||
| 417 | # CONFIG_SKY2 is not set | ||
| 418 | # CONFIG_SK98LIN is not set | ||
| 419 | # CONFIG_VIA_VELOCITY is not set | ||
| 420 | # CONFIG_TIGON3 is not set | ||
| 421 | # CONFIG_BNX2 is not set | ||
| 422 | CONFIG_GIANFAR=y | ||
| 423 | # CONFIG_GFAR_NAPI is not set | ||
| 424 | |||
| 425 | # | ||
| 426 | # Ethernet (10000 Mbit) | ||
| 427 | # | ||
| 428 | # CONFIG_CHELSIO_T1 is not set | ||
| 429 | # CONFIG_IXGB is not set | ||
| 430 | # CONFIG_S2IO is not set | ||
| 431 | |||
| 432 | # | ||
| 433 | # Token Ring devices | ||
| 434 | # | ||
| 435 | # CONFIG_TR is not set | ||
| 436 | |||
| 437 | # | ||
| 438 | # Wireless LAN (non-hamradio) | ||
| 439 | # | ||
| 440 | # CONFIG_NET_RADIO is not set | ||
| 441 | |||
| 442 | # | ||
| 443 | # Wan interfaces | ||
| 444 | # | ||
| 445 | # CONFIG_WAN is not set | ||
| 446 | # CONFIG_FDDI is not set | ||
| 447 | # CONFIG_HIPPI is not set | ||
| 448 | # CONFIG_PPP is not set | ||
| 449 | # CONFIG_SLIP is not set | ||
| 450 | # CONFIG_SHAPER is not set | ||
| 451 | # CONFIG_NETCONSOLE is not set | ||
| 452 | # CONFIG_NETPOLL is not set | ||
| 453 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
| 454 | |||
| 455 | # | ||
| 456 | # ISDN subsystem | ||
| 457 | # | ||
| 458 | # CONFIG_ISDN is not set | ||
| 459 | |||
| 460 | # | ||
| 461 | # Telephony Support | ||
| 462 | # | ||
| 463 | # CONFIG_PHONE is not set | ||
| 464 | |||
| 465 | # | ||
| 466 | # Input device support | ||
| 467 | # | ||
| 468 | CONFIG_INPUT=y | ||
| 469 | |||
| 470 | # | ||
| 471 | # Userland interfaces | ||
| 472 | # | ||
| 473 | # CONFIG_INPUT_MOUSEDEV is not set | ||
| 474 | # CONFIG_INPUT_JOYDEV is not set | ||
| 475 | # CONFIG_INPUT_TSDEV is not set | ||
| 476 | # CONFIG_INPUT_EVDEV is not set | ||
| 477 | # CONFIG_INPUT_EVBUG is not set | ||
| 478 | |||
| 479 | # | ||
| 480 | # Input Device Drivers | ||
| 481 | # | ||
| 482 | # CONFIG_INPUT_KEYBOARD is not set | ||
| 483 | # CONFIG_INPUT_MOUSE is not set | ||
| 484 | # CONFIG_INPUT_JOYSTICK is not set | ||
| 485 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
| 486 | # CONFIG_INPUT_MISC is not set | ||
| 487 | |||
| 488 | # | ||
| 489 | # Hardware I/O ports | ||
| 490 | # | ||
| 491 | # CONFIG_SERIO is not set | ||
| 492 | # CONFIG_GAMEPORT is not set | ||
| 493 | |||
| 494 | # | ||
| 495 | # Character devices | ||
| 496 | # | ||
| 497 | # CONFIG_VT is not set | ||
| 498 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
| 499 | |||
| 500 | # | ||
| 501 | # Serial drivers | ||
| 502 | # | ||
| 503 | CONFIG_SERIAL_8250=y | ||
| 504 | CONFIG_SERIAL_8250_CONSOLE=y | ||
| 505 | CONFIG_SERIAL_8250_NR_UARTS=4 | ||
| 506 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | ||
| 507 | # CONFIG_SERIAL_8250_EXTENDED is not set | ||
| 508 | |||
| 509 | # | ||
| 510 | # Non-8250 serial port support | ||
| 511 | # | ||
| 512 | CONFIG_SERIAL_CORE=y | ||
| 513 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
| 514 | CONFIG_UNIX98_PTYS=y | ||
| 515 | CONFIG_LEGACY_PTYS=y | ||
| 516 | CONFIG_LEGACY_PTY_COUNT=256 | ||
| 517 | |||
| 518 | # | ||
| 519 | # IPMI | ||
| 520 | # | ||
| 521 | # CONFIG_IPMI_HANDLER is not set | ||
| 522 | |||
| 523 | # | ||
| 524 | # Watchdog Cards | ||
| 525 | # | ||
| 526 | CONFIG_WATCHDOG=y | ||
| 527 | # CONFIG_WATCHDOG_NOWAYOUT is not set | ||
| 528 | |||
| 529 | # | ||
| 530 | # Watchdog Device Drivers | ||
| 531 | # | ||
| 532 | # CONFIG_SOFT_WATCHDOG is not set | ||
| 533 | CONFIG_83xx_WDT=y | ||
| 534 | |||
| 535 | # | ||
| 536 | # PCI-based Watchdog Cards | ||
| 537 | # | ||
| 538 | # CONFIG_PCIPCWATCHDOG is not set | ||
| 539 | # CONFIG_WDTPCI is not set | ||
| 540 | # CONFIG_NVRAM is not set | ||
| 541 | CONFIG_GEN_RTC=y | ||
| 542 | # CONFIG_GEN_RTC_X is not set | ||
| 543 | # CONFIG_DTLK is not set | ||
| 544 | # CONFIG_R3964 is not set | ||
| 545 | # CONFIG_APPLICOM is not set | ||
| 546 | |||
| 547 | # | ||
| 548 | # Ftape, the floppy tape device driver | ||
| 549 | # | ||
| 550 | # CONFIG_AGP is not set | ||
| 551 | # CONFIG_DRM is not set | ||
| 552 | # CONFIG_RAW_DRIVER is not set | ||
| 553 | |||
| 554 | # | ||
| 555 | # TPM devices | ||
| 556 | # | ||
| 557 | # CONFIG_TCG_TPM is not set | ||
| 558 | # CONFIG_TELCLOCK is not set | ||
| 559 | |||
| 560 | # | ||
| 561 | # I2C support | ||
| 562 | # | ||
| 563 | CONFIG_I2C=y | ||
| 564 | CONFIG_I2C_CHARDEV=y | ||
| 565 | |||
| 566 | # | ||
| 567 | # I2C Algorithms | ||
| 568 | # | ||
| 569 | # CONFIG_I2C_ALGOBIT is not set | ||
| 570 | # CONFIG_I2C_ALGOPCF is not set | ||
| 571 | # CONFIG_I2C_ALGOPCA is not set | ||
| 572 | |||
| 573 | # | ||
| 574 | # I2C Hardware Bus support | ||
| 575 | # | ||
| 576 | # CONFIG_I2C_ALI1535 is not set | ||
| 577 | # CONFIG_I2C_ALI1563 is not set | ||
| 578 | # CONFIG_I2C_ALI15X3 is not set | ||
| 579 | # CONFIG_I2C_AMD756 is not set | ||
| 580 | # CONFIG_I2C_AMD8111 is not set | ||
| 581 | # CONFIG_I2C_I801 is not set | ||
| 582 | # CONFIG_I2C_I810 is not set | ||
| 583 | # CONFIG_I2C_PIIX4 is not set | ||
| 584 | CONFIG_I2C_MPC=y | ||
| 585 | # CONFIG_I2C_NFORCE2 is not set | ||
| 586 | # CONFIG_I2C_PARPORT_LIGHT is not set | ||
| 587 | # CONFIG_I2C_PROSAVAGE is not set | ||
| 588 | # CONFIG_I2C_SAVAGE4 is not set | ||
| 589 | # CONFIG_SCx200_ACB is not set | ||
| 590 | # CONFIG_I2C_SIS5595 is not set | ||
| 591 | # CONFIG_I2C_SIS630 is not set | ||
| 592 | # CONFIG_I2C_SIS96X is not set | ||
| 593 | # CONFIG_I2C_STUB is not set | ||
| 594 | # CONFIG_I2C_VIA is not set | ||
| 595 | # CONFIG_I2C_VIAPRO is not set | ||
| 596 | # CONFIG_I2C_VOODOO3 is not set | ||
| 597 | # CONFIG_I2C_PCA_ISA is not set | ||
| 598 | |||
| 599 | # | ||
| 600 | # Miscellaneous I2C Chip support | ||
| 601 | # | ||
| 602 | # CONFIG_SENSORS_DS1337 is not set | ||
| 603 | # CONFIG_SENSORS_DS1374 is not set | ||
| 604 | # CONFIG_SENSORS_EEPROM is not set | ||
| 605 | # CONFIG_SENSORS_PCF8574 is not set | ||
| 606 | # CONFIG_SENSORS_PCA9539 is not set | ||
| 607 | # CONFIG_SENSORS_PCF8591 is not set | ||
| 608 | # CONFIG_SENSORS_RTC8564 is not set | ||
| 609 | # CONFIG_SENSORS_M41T00 is not set | ||
| 610 | # CONFIG_SENSORS_MAX6875 is not set | ||
| 611 | # CONFIG_RTC_X1205_I2C is not set | ||
| 612 | # CONFIG_I2C_DEBUG_CORE is not set | ||
| 613 | # CONFIG_I2C_DEBUG_ALGO is not set | ||
| 614 | # CONFIG_I2C_DEBUG_BUS is not set | ||
| 615 | # CONFIG_I2C_DEBUG_CHIP is not set | ||
| 616 | |||
| 617 | # | ||
| 618 | # Dallas's 1-wire bus | ||
| 619 | # | ||
| 620 | # CONFIG_W1 is not set | ||
| 621 | |||
| 622 | # | ||
| 623 | # Hardware Monitoring support | ||
| 624 | # | ||
| 625 | CONFIG_HWMON=y | ||
| 626 | # CONFIG_HWMON_VID is not set | ||
| 627 | # CONFIG_SENSORS_ADM1021 is not set | ||
| 628 | # CONFIG_SENSORS_ADM1025 is not set | ||
| 629 | # CONFIG_SENSORS_ADM1026 is not set | ||
| 630 | # CONFIG_SENSORS_ADM1031 is not set | ||
| 631 | # CONFIG_SENSORS_ADM9240 is not set | ||
| 632 | # CONFIG_SENSORS_ASB100 is not set | ||
| 633 | # CONFIG_SENSORS_ATXP1 is not set | ||
| 634 | # CONFIG_SENSORS_DS1621 is not set | ||
| 635 | # CONFIG_SENSORS_FSCHER is not set | ||
| 636 | # CONFIG_SENSORS_FSCPOS is not set | ||
| 637 | # CONFIG_SENSORS_GL518SM is not set | ||
| 638 | # CONFIG_SENSORS_GL520SM is not set | ||
| 639 | # CONFIG_SENSORS_IT87 is not set | ||
| 640 | # CONFIG_SENSORS_LM63 is not set | ||
| 641 | # CONFIG_SENSORS_LM75 is not set | ||
| 642 | # CONFIG_SENSORS_LM77 is not set | ||
| 643 | # CONFIG_SENSORS_LM78 is not set | ||
| 644 | # CONFIG_SENSORS_LM80 is not set | ||
| 645 | # CONFIG_SENSORS_LM83 is not set | ||
| 646 | # CONFIG_SENSORS_LM85 is not set | ||
| 647 | # CONFIG_SENSORS_LM87 is not set | ||
| 648 | # CONFIG_SENSORS_LM90 is not set | ||
| 649 | # CONFIG_SENSORS_LM92 is not set | ||
| 650 | # CONFIG_SENSORS_MAX1619 is not set | ||
| 651 | # CONFIG_SENSORS_PC87360 is not set | ||
| 652 | # CONFIG_SENSORS_SIS5595 is not set | ||
| 653 | # CONFIG_SENSORS_SMSC47M1 is not set | ||
| 654 | # CONFIG_SENSORS_SMSC47B397 is not set | ||
| 655 | # CONFIG_SENSORS_VIA686A is not set | ||
| 656 | # CONFIG_SENSORS_VT8231 is not set | ||
| 657 | # CONFIG_SENSORS_W83781D is not set | ||
| 658 | # CONFIG_SENSORS_W83792D is not set | ||
| 659 | # CONFIG_SENSORS_W83L785TS is not set | ||
| 660 | # CONFIG_SENSORS_W83627HF is not set | ||
| 661 | # CONFIG_SENSORS_W83627EHF is not set | ||
| 662 | # CONFIG_HWMON_DEBUG_CHIP is not set | ||
| 663 | |||
| 664 | # | ||
| 665 | # Misc devices | ||
| 666 | # | ||
| 667 | |||
| 668 | # | ||
| 669 | # Multimedia Capabilities Port drivers | ||
| 670 | # | ||
| 671 | |||
| 672 | # | ||
| 673 | # Multimedia devices | ||
| 674 | # | ||
| 675 | # CONFIG_VIDEO_DEV is not set | ||
| 676 | |||
| 677 | # | ||
| 678 | # Digital Video Broadcasting Devices | ||
| 679 | # | ||
| 680 | # CONFIG_DVB is not set | ||
| 681 | |||
| 682 | # | ||
| 683 | # Graphics support | ||
| 684 | # | ||
| 685 | # CONFIG_FB is not set | ||
| 686 | |||
| 687 | # | ||
| 688 | # Sound | ||
| 689 | # | ||
| 690 | # CONFIG_SOUND is not set | ||
| 691 | |||
| 692 | # | ||
| 693 | # USB support | ||
| 694 | # | ||
| 695 | CONFIG_USB_ARCH_HAS_HCD=y | ||
| 696 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
| 697 | # CONFIG_USB is not set | ||
| 698 | |||
| 699 | # | ||
| 700 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' | ||
| 701 | # | ||
| 702 | |||
| 703 | # | ||
| 704 | # USB Gadget Support | ||
| 705 | # | ||
| 706 | # CONFIG_USB_GADGET is not set | ||
| 707 | |||
| 708 | # | ||
| 709 | # MMC/SD Card support | ||
| 710 | # | ||
| 711 | # CONFIG_MMC is not set | ||
| 712 | |||
| 713 | # | ||
| 714 | # InfiniBand support | ||
| 715 | # | ||
| 716 | # CONFIG_INFINIBAND is not set | ||
| 717 | |||
| 718 | # | ||
| 719 | # SN Devices | ||
| 720 | # | ||
| 721 | |||
| 722 | # | ||
| 723 | # File systems | ||
| 724 | # | ||
| 725 | CONFIG_EXT2_FS=y | ||
| 726 | # CONFIG_EXT2_FS_XATTR is not set | ||
| 727 | # CONFIG_EXT2_FS_XIP is not set | ||
| 728 | CONFIG_EXT3_FS=y | ||
| 729 | CONFIG_EXT3_FS_XATTR=y | ||
| 730 | # CONFIG_EXT3_FS_POSIX_ACL is not set | ||
| 731 | # CONFIG_EXT3_FS_SECURITY is not set | ||
| 732 | CONFIG_JBD=y | ||
| 733 | # CONFIG_JBD_DEBUG is not set | ||
| 734 | CONFIG_FS_MBCACHE=y | ||
| 735 | # CONFIG_REISERFS_FS is not set | ||
| 736 | # CONFIG_JFS_FS is not set | ||
| 737 | # CONFIG_FS_POSIX_ACL is not set | ||
| 738 | # CONFIG_XFS_FS is not set | ||
| 739 | # CONFIG_OCFS2_FS is not set | ||
| 740 | # CONFIG_MINIX_FS is not set | ||
| 741 | # CONFIG_ROMFS_FS is not set | ||
| 742 | CONFIG_INOTIFY=y | ||
| 743 | # CONFIG_QUOTA is not set | ||
| 744 | CONFIG_DNOTIFY=y | ||
| 745 | # CONFIG_AUTOFS_FS is not set | ||
| 746 | # CONFIG_AUTOFS4_FS is not set | ||
| 747 | # CONFIG_FUSE_FS is not set | ||
| 748 | |||
| 749 | # | ||
| 750 | # CD-ROM/DVD Filesystems | ||
| 751 | # | ||
| 752 | # CONFIG_ISO9660_FS is not set | ||
| 753 | # CONFIG_UDF_FS is not set | ||
| 754 | |||
| 755 | # | ||
| 756 | # DOS/FAT/NT Filesystems | ||
| 757 | # | ||
| 758 | # CONFIG_MSDOS_FS is not set | ||
| 759 | # CONFIG_VFAT_FS is not set | ||
| 760 | # CONFIG_NTFS_FS is not set | ||
| 761 | |||
| 762 | # | ||
| 763 | # Pseudo filesystems | ||
| 764 | # | ||
| 765 | CONFIG_PROC_FS=y | ||
| 766 | CONFIG_PROC_KCORE=y | ||
| 767 | CONFIG_SYSFS=y | ||
| 768 | CONFIG_TMPFS=y | ||
| 769 | # CONFIG_HUGETLB_PAGE is not set | ||
| 770 | CONFIG_RAMFS=y | ||
| 771 | # CONFIG_RELAYFS_FS is not set | ||
| 772 | # CONFIG_CONFIGFS_FS is not set | ||
| 773 | |||
| 774 | # | ||
| 775 | # Miscellaneous filesystems | ||
| 776 | # | ||
| 777 | # CONFIG_ADFS_FS is not set | ||
| 778 | # CONFIG_AFFS_FS is not set | ||
| 779 | # CONFIG_HFS_FS is not set | ||
| 780 | # CONFIG_HFSPLUS_FS is not set | ||
| 781 | # CONFIG_BEFS_FS is not set | ||
| 782 | # CONFIG_BFS_FS is not set | ||
| 783 | # CONFIG_EFS_FS is not set | ||
| 784 | # CONFIG_CRAMFS is not set | ||
| 785 | # CONFIG_VXFS_FS is not set | ||
| 786 | # CONFIG_HPFS_FS is not set | ||
| 787 | # CONFIG_QNX4FS_FS is not set | ||
| 788 | # CONFIG_SYSV_FS is not set | ||
| 789 | # CONFIG_UFS_FS is not set | ||
| 790 | |||
| 791 | # | ||
| 792 | # Network File Systems | ||
| 793 | # | ||
| 794 | CONFIG_NFS_FS=y | ||
| 795 | CONFIG_NFS_V3=y | ||
| 796 | # CONFIG_NFS_V3_ACL is not set | ||
| 797 | CONFIG_NFS_V4=y | ||
| 798 | # CONFIG_NFS_DIRECTIO is not set | ||
| 799 | # CONFIG_NFSD is not set | ||
| 800 | CONFIG_ROOT_NFS=y | ||
| 801 | CONFIG_LOCKD=y | ||
| 802 | CONFIG_LOCKD_V4=y | ||
| 803 | CONFIG_NFS_COMMON=y | ||
| 804 | CONFIG_SUNRPC=y | ||
| 805 | CONFIG_SUNRPC_GSS=y | ||
| 806 | CONFIG_RPCSEC_GSS_KRB5=y | ||
| 807 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | ||
| 808 | # CONFIG_SMB_FS is not set | ||
| 809 | # CONFIG_CIFS is not set | ||
| 810 | # CONFIG_NCP_FS is not set | ||
| 811 | # CONFIG_CODA_FS is not set | ||
| 812 | # CONFIG_AFS_FS is not set | ||
| 813 | # CONFIG_9P_FS is not set | ||
| 814 | |||
| 815 | # | ||
| 816 | # Partition Types | ||
| 817 | # | ||
| 818 | CONFIG_PARTITION_ADVANCED=y | ||
| 819 | # CONFIG_ACORN_PARTITION is not set | ||
| 820 | # CONFIG_OSF_PARTITION is not set | ||
| 821 | # CONFIG_AMIGA_PARTITION is not set | ||
| 822 | # CONFIG_ATARI_PARTITION is not set | ||
| 823 | # CONFIG_MAC_PARTITION is not set | ||
| 824 | # CONFIG_MSDOS_PARTITION is not set | ||
| 825 | # CONFIG_LDM_PARTITION is not set | ||
| 826 | # CONFIG_SGI_PARTITION is not set | ||
| 827 | # CONFIG_ULTRIX_PARTITION is not set | ||
| 828 | # CONFIG_SUN_PARTITION is not set | ||
| 829 | # CONFIG_EFI_PARTITION is not set | ||
| 830 | |||
| 831 | # | ||
| 832 | # Native Language Support | ||
| 833 | # | ||
| 834 | # CONFIG_NLS is not set | ||
| 835 | |||
| 836 | # | ||
| 837 | # Library routines | ||
| 838 | # | ||
| 839 | # CONFIG_CRC_CCITT is not set | ||
| 840 | # CONFIG_CRC16 is not set | ||
| 841 | CONFIG_CRC32=y | ||
| 842 | # CONFIG_LIBCRC32C is not set | ||
| 843 | |||
| 844 | # | ||
| 845 | # Instrumentation Support | ||
| 846 | # | ||
| 847 | # CONFIG_PROFILING is not set | ||
| 848 | |||
| 849 | # | ||
| 850 | # Kernel hacking | ||
| 851 | # | ||
| 852 | # CONFIG_PRINTK_TIME is not set | ||
| 853 | # CONFIG_MAGIC_SYSRQ is not set | ||
| 854 | # CONFIG_DEBUG_KERNEL is not set | ||
| 855 | CONFIG_LOG_BUF_SHIFT=14 | ||
| 856 | # CONFIG_BOOTX_TEXT is not set | ||
| 857 | # CONFIG_SERIAL_TEXT_DEBUG is not set | ||
| 858 | # CONFIG_PPC_EARLY_DEBUG_LPAR is not set | ||
| 859 | # CONFIG_PPC_EARLY_DEBUG_G5 is not set | ||
| 860 | # CONFIG_PPC_EARLY_DEBUG_RTAS is not set | ||
| 861 | # CONFIG_PPC_EARLY_DEBUG_MAPLE is not set | ||
| 862 | # CONFIG_PPC_EARLY_DEBUG_ISERIES is not set | ||
| 863 | |||
| 864 | # | ||
| 865 | # Security options | ||
| 866 | # | ||
| 867 | # CONFIG_KEYS is not set | ||
| 868 | # CONFIG_SECURITY is not set | ||
| 869 | |||
| 870 | # | ||
| 871 | # Cryptographic options | ||
| 872 | # | ||
| 873 | CONFIG_CRYPTO=y | ||
| 874 | # CONFIG_CRYPTO_HMAC is not set | ||
| 875 | # CONFIG_CRYPTO_NULL is not set | ||
| 876 | # CONFIG_CRYPTO_MD4 is not set | ||
| 877 | CONFIG_CRYPTO_MD5=y | ||
| 878 | # CONFIG_CRYPTO_SHA1 is not set | ||
| 879 | # CONFIG_CRYPTO_SHA256 is not set | ||
| 880 | # CONFIG_CRYPTO_SHA512 is not set | ||
| 881 | # CONFIG_CRYPTO_WP512 is not set | ||
| 882 | # CONFIG_CRYPTO_TGR192 is not set | ||
| 883 | CONFIG_CRYPTO_DES=y | ||
| 884 | # CONFIG_CRYPTO_BLOWFISH is not set | ||
| 885 | # CONFIG_CRYPTO_TWOFISH is not set | ||
| 886 | # CONFIG_CRYPTO_SERPENT is not set | ||
| 887 | # CONFIG_CRYPTO_AES is not set | ||
| 888 | # CONFIG_CRYPTO_CAST5 is not set | ||
| 889 | # CONFIG_CRYPTO_CAST6 is not set | ||
| 890 | # CONFIG_CRYPTO_TEA is not set | ||
| 891 | # CONFIG_CRYPTO_ARC4 is not set | ||
| 892 | # CONFIG_CRYPTO_KHAZAD is not set | ||
| 893 | # CONFIG_CRYPTO_ANUBIS is not set | ||
| 894 | # CONFIG_CRYPTO_DEFLATE is not set | ||
| 895 | # CONFIG_CRYPTO_MICHAEL_MIC is not set | ||
| 896 | # CONFIG_CRYPTO_CRC32C is not set | ||
| 897 | # CONFIG_CRYPTO_TEST is not set | ||
| 898 | |||
| 899 | # | ||
| 900 | # Hardware crypto devices | ||
| 901 | # | ||
| 902 | |||
| 903 | # | ||
| 904 | # SEC2.x Options | ||
| 905 | # | ||
| 906 | CONFIG_MPC8349E_SEC2x=y | ||
| 907 | |||
| 908 | # | ||
| 909 | # SEC2.x Test Options | ||
| 910 | # | ||
| 911 | CONFIG_MPC8349E_SEC2xTEST=y | ||
diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig index 398203bd98eb..2ace57d1e333 100644 --- a/arch/powerpc/configs/pmac32_defconfig +++ b/arch/powerpc/configs/pmac32_defconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | # | 1 | # |
| 2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
| 3 | # Linux kernel version: 2.6.15-rc5 | 3 | # Linux kernel version: 2.6.15 |
| 4 | # Tue Dec 13 17:24:05 2005 | 4 | # Sat Jan 14 16:26:08 2006 |
| 5 | # | 5 | # |
| 6 | # CONFIG_PPC64 is not set | 6 | # CONFIG_PPC64 is not set |
| 7 | CONFIG_PPC32=y | 7 | CONFIG_PPC32=y |
| @@ -15,11 +15,15 @@ CONFIG_EARLY_PRINTK=y | |||
| 15 | CONFIG_GENERIC_NVRAM=y | 15 | CONFIG_GENERIC_NVRAM=y |
| 16 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y | 16 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y |
| 17 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y | 17 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y |
| 18 | CONFIG_PPC_OF=y | ||
| 19 | # CONFIG_PPC_UDBG_16550 is not set | ||
| 20 | # CONFIG_CRASH_DUMP is not set | ||
| 21 | # CONFIG_GENERIC_TBSYNC is not set | ||
| 18 | 22 | ||
| 19 | # | 23 | # |
| 20 | # Processor support | 24 | # Processor support |
| 21 | # | 25 | # |
| 22 | CONFIG_6xx=y | 26 | CONFIG_CLASSIC32=y |
| 23 | # CONFIG_PPC_52xx is not set | 27 | # CONFIG_PPC_52xx is not set |
| 24 | # CONFIG_PPC_82xx is not set | 28 | # CONFIG_PPC_82xx is not set |
| 25 | # CONFIG_PPC_83xx is not set | 29 | # CONFIG_PPC_83xx is not set |
| @@ -28,6 +32,7 @@ CONFIG_6xx=y | |||
| 28 | # CONFIG_8xx is not set | 32 | # CONFIG_8xx is not set |
| 29 | # CONFIG_E200 is not set | 33 | # CONFIG_E200 is not set |
| 30 | # CONFIG_E500 is not set | 34 | # CONFIG_E500 is not set |
| 35 | CONFIG_6xx=y | ||
| 31 | CONFIG_PPC_FPU=y | 36 | CONFIG_PPC_FPU=y |
| 32 | CONFIG_ALTIVEC=y | 37 | CONFIG_ALTIVEC=y |
| 33 | CONFIG_PPC_STD_MMU=y | 38 | CONFIG_PPC_STD_MMU=y |
| @@ -53,17 +58,18 @@ CONFIG_POSIX_MQUEUE=y | |||
| 53 | # CONFIG_BSD_PROCESS_ACCT is not set | 58 | # CONFIG_BSD_PROCESS_ACCT is not set |
| 54 | CONFIG_SYSCTL=y | 59 | CONFIG_SYSCTL=y |
| 55 | # CONFIG_AUDIT is not set | 60 | # CONFIG_AUDIT is not set |
| 56 | CONFIG_HOTPLUG=y | ||
| 57 | CONFIG_KOBJECT_UEVENT=y | ||
| 58 | CONFIG_IKCONFIG=y | 61 | CONFIG_IKCONFIG=y |
| 59 | CONFIG_IKCONFIG_PROC=y | 62 | CONFIG_IKCONFIG_PROC=y |
| 60 | CONFIG_INITRAMFS_SOURCE="" | 63 | CONFIG_INITRAMFS_SOURCE="" |
| 64 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
| 61 | # CONFIG_EMBEDDED is not set | 65 | # CONFIG_EMBEDDED is not set |
| 62 | CONFIG_KALLSYMS=y | 66 | CONFIG_KALLSYMS=y |
| 63 | # CONFIG_KALLSYMS_ALL is not set | 67 | # CONFIG_KALLSYMS_ALL is not set |
| 64 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 68 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
| 69 | CONFIG_HOTPLUG=y | ||
| 65 | CONFIG_PRINTK=y | 70 | CONFIG_PRINTK=y |
| 66 | CONFIG_BUG=y | 71 | CONFIG_BUG=y |
| 72 | CONFIG_ELF_CORE=y | ||
| 67 | CONFIG_BASE_FULL=y | 73 | CONFIG_BASE_FULL=y |
| 68 | CONFIG_FUTEX=y | 74 | CONFIG_FUTEX=y |
| 69 | CONFIG_EPOLL=y | 75 | CONFIG_EPOLL=y |
| @@ -72,8 +78,10 @@ CONFIG_CC_ALIGN_FUNCTIONS=0 | |||
| 72 | CONFIG_CC_ALIGN_LABELS=0 | 78 | CONFIG_CC_ALIGN_LABELS=0 |
| 73 | CONFIG_CC_ALIGN_LOOPS=0 | 79 | CONFIG_CC_ALIGN_LOOPS=0 |
| 74 | CONFIG_CC_ALIGN_JUMPS=0 | 80 | CONFIG_CC_ALIGN_JUMPS=0 |
| 81 | CONFIG_SLAB=y | ||
| 75 | # CONFIG_TINY_SHMEM is not set | 82 | # CONFIG_TINY_SHMEM is not set |
| 76 | CONFIG_BASE_SMALL=0 | 83 | CONFIG_BASE_SMALL=0 |
| 84 | # CONFIG_SLOB is not set | ||
| 77 | 85 | ||
| 78 | # | 86 | # |
| 79 | # Loadable module support | 87 | # Loadable module support |
| @@ -113,13 +121,10 @@ CONFIG_PPC_MULTIPLATFORM=y | |||
| 113 | # CONFIG_APUS is not set | 121 | # CONFIG_APUS is not set |
| 114 | # CONFIG_PPC_CHRP is not set | 122 | # CONFIG_PPC_CHRP is not set |
| 115 | CONFIG_PPC_PMAC=y | 123 | CONFIG_PPC_PMAC=y |
| 116 | CONFIG_PPC_OF=y | ||
| 117 | CONFIG_MPIC=y | 124 | CONFIG_MPIC=y |
| 118 | # CONFIG_PPC_RTAS is not set | 125 | # CONFIG_PPC_RTAS is not set |
| 119 | # CONFIG_MMIO_NVRAM is not set | 126 | # CONFIG_MMIO_NVRAM is not set |
| 120 | # CONFIG_CRASH_DUMP is not set | ||
| 121 | CONFIG_PPC_MPC106=y | 127 | CONFIG_PPC_MPC106=y |
| 122 | # CONFIG_GENERIC_TBSYNC is not set | ||
| 123 | CONFIG_CPU_FREQ=y | 128 | CONFIG_CPU_FREQ=y |
| 124 | CONFIG_CPU_FREQ_TABLE=y | 129 | CONFIG_CPU_FREQ_TABLE=y |
| 125 | # CONFIG_CPU_FREQ_DEBUG is not set | 130 | # CONFIG_CPU_FREQ_DEBUG is not set |
| @@ -195,6 +200,11 @@ CONFIG_CARDBUS=y | |||
| 195 | # PC-card bridges | 200 | # PC-card bridges |
| 196 | # | 201 | # |
| 197 | CONFIG_YENTA=m | 202 | CONFIG_YENTA=m |
| 203 | CONFIG_YENTA_O2=y | ||
| 204 | CONFIG_YENTA_RICOH=y | ||
| 205 | CONFIG_YENTA_TI=y | ||
| 206 | CONFIG_YENTA_ENE_TUNE=y | ||
| 207 | CONFIG_YENTA_TOSHIBA=y | ||
| 198 | # CONFIG_PD6729 is not set | 208 | # CONFIG_PD6729 is not set |
| 199 | # CONFIG_I82092 is not set | 209 | # CONFIG_I82092 is not set |
| 200 | CONFIG_PCCARD_NONSTATIC=m | 210 | CONFIG_PCCARD_NONSTATIC=m |
| @@ -464,7 +474,7 @@ CONFIG_IEEE80211_CRYPT_TKIP=m | |||
| 464 | # | 474 | # |
| 465 | # CONFIG_STANDALONE is not set | 475 | # CONFIG_STANDALONE is not set |
| 466 | CONFIG_PREVENT_FIRMWARE_BUILD=y | 476 | CONFIG_PREVENT_FIRMWARE_BUILD=y |
| 467 | CONFIG_FW_LOADER=m | 477 | CONFIG_FW_LOADER=y |
| 468 | # CONFIG_DEBUG_DRIVER is not set | 478 | # CONFIG_DEBUG_DRIVER is not set |
| 469 | 479 | ||
| 470 | # | 480 | # |
| @@ -491,7 +501,7 @@ CONFIG_PROC_EVENTS=y | |||
| 491 | # Block devices | 501 | # Block devices |
| 492 | # | 502 | # |
| 493 | # CONFIG_BLK_DEV_FD is not set | 503 | # CONFIG_BLK_DEV_FD is not set |
| 494 | CONFIG_MAC_FLOPPY=y | 504 | CONFIG_MAC_FLOPPY=m |
| 495 | # CONFIG_BLK_CPQ_DA is not set | 505 | # CONFIG_BLK_CPQ_DA is not set |
| 496 | # CONFIG_BLK_CPQ_CISS_DA is not set | 506 | # CONFIG_BLK_CPQ_CISS_DA is not set |
| 497 | # CONFIG_BLK_DEV_DAC960 is not set | 507 | # CONFIG_BLK_DEV_DAC960 is not set |
| @@ -603,7 +613,7 @@ CONFIG_SCSI_CONSTANTS=y | |||
| 603 | # SCSI Transport Attributes | 613 | # SCSI Transport Attributes |
| 604 | # | 614 | # |
| 605 | CONFIG_SCSI_SPI_ATTRS=y | 615 | CONFIG_SCSI_SPI_ATTRS=y |
| 606 | # CONFIG_SCSI_FC_ATTRS is not set | 616 | CONFIG_SCSI_FC_ATTRS=y |
| 607 | # CONFIG_SCSI_ISCSI_ATTRS is not set | 617 | # CONFIG_SCSI_ISCSI_ATTRS is not set |
| 608 | # CONFIG_SCSI_SAS_ATTRS is not set | 618 | # CONFIG_SCSI_SAS_ATTRS is not set |
| 609 | 619 | ||
| @@ -645,12 +655,7 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 | |||
| 645 | # CONFIG_SCSI_QLOGIC_FC is not set | 655 | # CONFIG_SCSI_QLOGIC_FC is not set |
| 646 | # CONFIG_SCSI_QLOGIC_1280 is not set | 656 | # CONFIG_SCSI_QLOGIC_1280 is not set |
| 647 | CONFIG_SCSI_QLA2XXX=y | 657 | CONFIG_SCSI_QLA2XXX=y |
| 648 | # CONFIG_SCSI_QLA21XX is not set | 658 | # CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE is not set |
| 649 | # CONFIG_SCSI_QLA22XX is not set | ||
| 650 | # CONFIG_SCSI_QLA2300 is not set | ||
| 651 | # CONFIG_SCSI_QLA2322 is not set | ||
| 652 | # CONFIG_SCSI_QLA6312 is not set | ||
| 653 | # CONFIG_SCSI_QLA24XX is not set | ||
| 654 | # CONFIG_SCSI_LPFC is not set | 659 | # CONFIG_SCSI_LPFC is not set |
| 655 | # CONFIG_SCSI_DC395x is not set | 660 | # CONFIG_SCSI_DC395x is not set |
| 656 | # CONFIG_SCSI_DC390T is not set | 661 | # CONFIG_SCSI_DC390T is not set |
| @@ -658,7 +663,7 @@ CONFIG_SCSI_QLA2XXX=y | |||
| 658 | # CONFIG_SCSI_DEBUG is not set | 663 | # CONFIG_SCSI_DEBUG is not set |
| 659 | CONFIG_SCSI_MESH=y | 664 | CONFIG_SCSI_MESH=y |
| 660 | CONFIG_SCSI_MESH_SYNC_RATE=5 | 665 | CONFIG_SCSI_MESH_SYNC_RATE=5 |
| 661 | CONFIG_SCSI_MESH_RESET_DELAY_MS=1000 | 666 | CONFIG_SCSI_MESH_RESET_DELAY_MS=4000 |
| 662 | CONFIG_SCSI_MAC53C94=y | 667 | CONFIG_SCSI_MAC53C94=y |
| 663 | 668 | ||
| 664 | # | 669 | # |
| @@ -727,7 +732,6 @@ CONFIG_IEEE1394_SBP2=m | |||
| 727 | CONFIG_IEEE1394_ETH1394=m | 732 | CONFIG_IEEE1394_ETH1394=m |
| 728 | CONFIG_IEEE1394_DV1394=m | 733 | CONFIG_IEEE1394_DV1394=m |
| 729 | CONFIG_IEEE1394_RAWIO=m | 734 | CONFIG_IEEE1394_RAWIO=m |
| 730 | # CONFIG_IEEE1394_CMP is not set | ||
| 731 | 735 | ||
| 732 | # | 736 | # |
| 733 | # I2O device support | 737 | # I2O device support |
| @@ -740,7 +744,7 @@ CONFIG_IEEE1394_RAWIO=m | |||
| 740 | CONFIG_ADB=y | 744 | CONFIG_ADB=y |
| 741 | CONFIG_ADB_CUDA=y | 745 | CONFIG_ADB_CUDA=y |
| 742 | CONFIG_ADB_PMU=y | 746 | CONFIG_ADB_PMU=y |
| 743 | CONFIG_PMAC_APM_EMU=y | 747 | CONFIG_PMAC_APM_EMU=m |
| 744 | CONFIG_PMAC_MEDIABAY=y | 748 | CONFIG_PMAC_MEDIABAY=y |
| 745 | CONFIG_PMAC_BACKLIGHT=y | 749 | CONFIG_PMAC_BACKLIGHT=y |
| 746 | CONFIG_INPUT_ADBHID=y | 750 | CONFIG_INPUT_ADBHID=y |
| @@ -819,6 +823,7 @@ CONFIG_PCNET32=y | |||
| 819 | # CONFIG_R8169 is not set | 823 | # CONFIG_R8169 is not set |
| 820 | # CONFIG_SIS190 is not set | 824 | # CONFIG_SIS190 is not set |
| 821 | # CONFIG_SKGE is not set | 825 | # CONFIG_SKGE is not set |
| 826 | # CONFIG_SKY2 is not set | ||
| 822 | # CONFIG_SK98LIN is not set | 827 | # CONFIG_SK98LIN is not set |
| 823 | # CONFIG_VIA_VELOCITY is not set | 828 | # CONFIG_VIA_VELOCITY is not set |
| 824 | # CONFIG_TIGON3 is not set | 829 | # CONFIG_TIGON3 is not set |
| @@ -978,14 +983,14 @@ CONFIG_HW_CONSOLE=y | |||
| 978 | CONFIG_SERIAL_8250=m | 983 | CONFIG_SERIAL_8250=m |
| 979 | # CONFIG_SERIAL_8250_CS is not set | 984 | # CONFIG_SERIAL_8250_CS is not set |
| 980 | CONFIG_SERIAL_8250_NR_UARTS=4 | 985 | CONFIG_SERIAL_8250_NR_UARTS=4 |
| 986 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | ||
| 981 | # CONFIG_SERIAL_8250_EXTENDED is not set | 987 | # CONFIG_SERIAL_8250_EXTENDED is not set |
| 982 | 988 | ||
| 983 | # | 989 | # |
| 984 | # Non-8250 serial port support | 990 | # Non-8250 serial port support |
| 985 | # | 991 | # |
| 986 | CONFIG_SERIAL_CORE=m | 992 | CONFIG_SERIAL_CORE=m |
| 987 | # CONFIG_SERIAL_PMACZILOG is not set | 993 | CONFIG_SERIAL_PMACZILOG=m |
| 988 | # CONFIG_SERIAL_JSM is not set | ||
| 989 | CONFIG_UNIX98_PTYS=y | 994 | CONFIG_UNIX98_PTYS=y |
| 990 | CONFIG_LEGACY_PTYS=y | 995 | CONFIG_LEGACY_PTYS=y |
| 991 | CONFIG_LEGACY_PTY_COUNT=256 | 996 | CONFIG_LEGACY_PTY_COUNT=256 |
| @@ -1058,7 +1063,7 @@ CONFIG_I2C_ALGOBIT=y | |||
| 1058 | # CONFIG_I2C_I801 is not set | 1063 | # CONFIG_I2C_I801 is not set |
| 1059 | # CONFIG_I2C_I810 is not set | 1064 | # CONFIG_I2C_I810 is not set |
| 1060 | # CONFIG_I2C_PIIX4 is not set | 1065 | # CONFIG_I2C_PIIX4 is not set |
| 1061 | CONFIG_I2C_KEYWEST=m | 1066 | CONFIG_I2C_POWERMAC=y |
| 1062 | # CONFIG_I2C_MPC is not set | 1067 | # CONFIG_I2C_MPC is not set |
| 1063 | # CONFIG_I2C_NFORCE2 is not set | 1068 | # CONFIG_I2C_NFORCE2 is not set |
| 1064 | # CONFIG_I2C_PARPORT_LIGHT is not set | 1069 | # CONFIG_I2C_PARPORT_LIGHT is not set |
| @@ -1160,7 +1165,6 @@ CONFIG_FB_ATY128=y | |||
| 1160 | CONFIG_FB_ATY=y | 1165 | CONFIG_FB_ATY=y |
| 1161 | CONFIG_FB_ATY_CT=y | 1166 | CONFIG_FB_ATY_CT=y |
| 1162 | # CONFIG_FB_ATY_GENERIC_LCD is not set | 1167 | # CONFIG_FB_ATY_GENERIC_LCD is not set |
| 1163 | # CONFIG_FB_ATY_XL_INIT is not set | ||
| 1164 | CONFIG_FB_ATY_GX=y | 1168 | CONFIG_FB_ATY_GX=y |
| 1165 | # CONFIG_FB_SAVAGE is not set | 1169 | # CONFIG_FB_SAVAGE is not set |
| 1166 | # CONFIG_FB_SIS is not set | 1170 | # CONFIG_FB_SIS is not set |
| @@ -1169,7 +1173,6 @@ CONFIG_FB_ATY_GX=y | |||
| 1169 | CONFIG_FB_3DFX=y | 1173 | CONFIG_FB_3DFX=y |
| 1170 | # CONFIG_FB_3DFX_ACCEL is not set | 1174 | # CONFIG_FB_3DFX_ACCEL is not set |
| 1171 | # CONFIG_FB_VOODOO1 is not set | 1175 | # CONFIG_FB_VOODOO1 is not set |
| 1172 | # CONFIG_FB_CYBLA is not set | ||
| 1173 | # CONFIG_FB_TRIDENT is not set | 1176 | # CONFIG_FB_TRIDENT is not set |
| 1174 | # CONFIG_FB_VIRTUAL is not set | 1177 | # CONFIG_FB_VIRTUAL is not set |
| 1175 | 1178 | ||
| @@ -1214,9 +1217,10 @@ CONFIG_SND_OSSEMUL=y | |||
| 1214 | CONFIG_SND_MIXER_OSS=m | 1217 | CONFIG_SND_MIXER_OSS=m |
| 1215 | CONFIG_SND_PCM_OSS=m | 1218 | CONFIG_SND_PCM_OSS=m |
| 1216 | CONFIG_SND_SEQUENCER_OSS=y | 1219 | CONFIG_SND_SEQUENCER_OSS=y |
| 1220 | # CONFIG_SND_DYNAMIC_MINORS is not set | ||
| 1221 | CONFIG_SND_SUPPORT_OLD_API=y | ||
| 1217 | # CONFIG_SND_VERBOSE_PRINTK is not set | 1222 | # CONFIG_SND_VERBOSE_PRINTK is not set |
| 1218 | # CONFIG_SND_DEBUG is not set | 1223 | # CONFIG_SND_DEBUG is not set |
| 1219 | CONFIG_SND_GENERIC_DRIVER=y | ||
| 1220 | 1224 | ||
| 1221 | # | 1225 | # |
| 1222 | # Generic devices | 1226 | # Generic devices |
| @@ -1230,6 +1234,8 @@ CONFIG_SND_DUMMY=m | |||
| 1230 | # | 1234 | # |
| 1231 | # PCI devices | 1235 | # PCI devices |
| 1232 | # | 1236 | # |
| 1237 | # CONFIG_SND_AD1889 is not set | ||
| 1238 | # CONFIG_SND_ALS4000 is not set | ||
| 1233 | # CONFIG_SND_ALI5451 is not set | 1239 | # CONFIG_SND_ALI5451 is not set |
| 1234 | # CONFIG_SND_ATIIXP is not set | 1240 | # CONFIG_SND_ATIIXP is not set |
| 1235 | # CONFIG_SND_ATIIXP_MODEM is not set | 1241 | # CONFIG_SND_ATIIXP_MODEM is not set |
| @@ -1238,45 +1244,44 @@ CONFIG_SND_DUMMY=m | |||
| 1238 | # CONFIG_SND_AU8830 is not set | 1244 | # CONFIG_SND_AU8830 is not set |
| 1239 | # CONFIG_SND_AZT3328 is not set | 1245 | # CONFIG_SND_AZT3328 is not set |
| 1240 | # CONFIG_SND_BT87X is not set | 1246 | # CONFIG_SND_BT87X is not set |
| 1241 | # CONFIG_SND_CS46XX is not set | 1247 | # CONFIG_SND_CA0106 is not set |
| 1248 | # CONFIG_SND_CMIPCI is not set | ||
| 1242 | # CONFIG_SND_CS4281 is not set | 1249 | # CONFIG_SND_CS4281 is not set |
| 1250 | # CONFIG_SND_CS46XX is not set | ||
| 1243 | # CONFIG_SND_EMU10K1 is not set | 1251 | # CONFIG_SND_EMU10K1 is not set |
| 1244 | # CONFIG_SND_EMU10K1X is not set | 1252 | # CONFIG_SND_EMU10K1X is not set |
| 1245 | # CONFIG_SND_CA0106 is not set | ||
| 1246 | # CONFIG_SND_KORG1212 is not set | ||
| 1247 | # CONFIG_SND_MIXART is not set | ||
| 1248 | # CONFIG_SND_NM256 is not set | ||
| 1249 | # CONFIG_SND_RME32 is not set | ||
| 1250 | # CONFIG_SND_RME96 is not set | ||
| 1251 | # CONFIG_SND_RME9652 is not set | ||
| 1252 | # CONFIG_SND_HDSP is not set | ||
| 1253 | # CONFIG_SND_HDSPM is not set | ||
| 1254 | # CONFIG_SND_TRIDENT is not set | ||
| 1255 | # CONFIG_SND_YMFPCI is not set | ||
| 1256 | # CONFIG_SND_AD1889 is not set | ||
| 1257 | # CONFIG_SND_ALS4000 is not set | ||
| 1258 | # CONFIG_SND_CMIPCI is not set | ||
| 1259 | # CONFIG_SND_ENS1370 is not set | 1253 | # CONFIG_SND_ENS1370 is not set |
| 1260 | # CONFIG_SND_ENS1371 is not set | 1254 | # CONFIG_SND_ENS1371 is not set |
| 1261 | # CONFIG_SND_ES1938 is not set | 1255 | # CONFIG_SND_ES1938 is not set |
| 1262 | # CONFIG_SND_ES1968 is not set | 1256 | # CONFIG_SND_ES1968 is not set |
| 1263 | # CONFIG_SND_MAESTRO3 is not set | ||
| 1264 | # CONFIG_SND_FM801 is not set | 1257 | # CONFIG_SND_FM801 is not set |
| 1258 | # CONFIG_SND_HDA_INTEL is not set | ||
| 1259 | # CONFIG_SND_HDSP is not set | ||
| 1260 | # CONFIG_SND_HDSPM is not set | ||
| 1265 | # CONFIG_SND_ICE1712 is not set | 1261 | # CONFIG_SND_ICE1712 is not set |
| 1266 | # CONFIG_SND_ICE1724 is not set | 1262 | # CONFIG_SND_ICE1724 is not set |
| 1267 | # CONFIG_SND_INTEL8X0 is not set | 1263 | # CONFIG_SND_INTEL8X0 is not set |
| 1268 | # CONFIG_SND_INTEL8X0M is not set | 1264 | # CONFIG_SND_INTEL8X0M is not set |
| 1265 | # CONFIG_SND_KORG1212 is not set | ||
| 1266 | # CONFIG_SND_MAESTRO3 is not set | ||
| 1267 | # CONFIG_SND_MIXART is not set | ||
| 1268 | # CONFIG_SND_NM256 is not set | ||
| 1269 | # CONFIG_SND_PCXHR is not set | ||
| 1270 | # CONFIG_SND_RME32 is not set | ||
| 1271 | # CONFIG_SND_RME96 is not set | ||
| 1272 | # CONFIG_SND_RME9652 is not set | ||
| 1269 | # CONFIG_SND_SONICVIBES is not set | 1273 | # CONFIG_SND_SONICVIBES is not set |
| 1274 | # CONFIG_SND_TRIDENT is not set | ||
| 1270 | # CONFIG_SND_VIA82XX is not set | 1275 | # CONFIG_SND_VIA82XX is not set |
| 1271 | # CONFIG_SND_VIA82XX_MODEM is not set | 1276 | # CONFIG_SND_VIA82XX_MODEM is not set |
| 1272 | # CONFIG_SND_VX222 is not set | 1277 | # CONFIG_SND_VX222 is not set |
| 1273 | # CONFIG_SND_HDA_INTEL is not set | 1278 | # CONFIG_SND_YMFPCI is not set |
| 1274 | 1279 | ||
| 1275 | # | 1280 | # |
| 1276 | # ALSA PowerMac devices | 1281 | # ALSA PowerMac devices |
| 1277 | # | 1282 | # |
| 1278 | CONFIG_SND_POWERMAC=m | 1283 | CONFIG_SND_POWERMAC=m |
| 1279 | # CONFIG_SND_POWERMAC_AUTO_DRC is not set | 1284 | CONFIG_SND_POWERMAC_AUTO_DRC=y |
| 1280 | 1285 | ||
| 1281 | # | 1286 | # |
| 1282 | # USB devices | 1287 | # USB devices |
| @@ -1336,6 +1341,7 @@ CONFIG_USB_PRINTER=m | |||
| 1336 | # may also be needed; see USB_STORAGE Help for more information | 1341 | # may also be needed; see USB_STORAGE Help for more information |
| 1337 | # | 1342 | # |
| 1338 | # CONFIG_USB_STORAGE is not set | 1343 | # CONFIG_USB_STORAGE is not set |
| 1344 | # CONFIG_USB_LIBUSUAL is not set | ||
| 1339 | 1345 | ||
| 1340 | # | 1346 | # |
| 1341 | # USB Input Devices | 1347 | # USB Input Devices |
| @@ -1355,6 +1361,7 @@ CONFIG_USB_HIDINPUT=y | |||
| 1355 | # CONFIG_USB_YEALINK is not set | 1361 | # CONFIG_USB_YEALINK is not set |
| 1356 | # CONFIG_USB_XPAD is not set | 1362 | # CONFIG_USB_XPAD is not set |
| 1357 | # CONFIG_USB_ATI_REMOTE is not set | 1363 | # CONFIG_USB_ATI_REMOTE is not set |
| 1364 | # CONFIG_USB_ATI_REMOTE2 is not set | ||
| 1358 | # CONFIG_USB_KEYSPAN_REMOTE is not set | 1365 | # CONFIG_USB_KEYSPAN_REMOTE is not set |
| 1359 | CONFIG_USB_APPLETOUCH=y | 1366 | CONFIG_USB_APPLETOUCH=y |
| 1360 | 1367 | ||
| @@ -1501,6 +1508,7 @@ CONFIG_FS_MBCACHE=y | |||
| 1501 | # CONFIG_JFS_FS is not set | 1508 | # CONFIG_JFS_FS is not set |
| 1502 | # CONFIG_FS_POSIX_ACL is not set | 1509 | # CONFIG_FS_POSIX_ACL is not set |
| 1503 | # CONFIG_XFS_FS is not set | 1510 | # CONFIG_XFS_FS is not set |
| 1511 | # CONFIG_OCFS2_FS is not set | ||
| 1504 | # CONFIG_MINIX_FS is not set | 1512 | # CONFIG_MINIX_FS is not set |
| 1505 | # CONFIG_ROMFS_FS is not set | 1513 | # CONFIG_ROMFS_FS is not set |
| 1506 | CONFIG_INOTIFY=y | 1514 | CONFIG_INOTIFY=y |
| @@ -1540,6 +1548,7 @@ CONFIG_TMPFS=y | |||
| 1540 | # CONFIG_HUGETLB_PAGE is not set | 1548 | # CONFIG_HUGETLB_PAGE is not set |
| 1541 | CONFIG_RAMFS=y | 1549 | CONFIG_RAMFS=y |
| 1542 | CONFIG_RELAYFS_FS=m | 1550 | CONFIG_RELAYFS_FS=m |
| 1551 | # CONFIG_CONFIGFS_FS is not set | ||
| 1543 | 1552 | ||
| 1544 | # | 1553 | # |
| 1545 | # Miscellaneous filesystems | 1554 | # Miscellaneous filesystems |
| @@ -1670,12 +1679,13 @@ CONFIG_OPROFILE=y | |||
| 1670 | # Kernel hacking | 1679 | # Kernel hacking |
| 1671 | # | 1680 | # |
| 1672 | # CONFIG_PRINTK_TIME is not set | 1681 | # CONFIG_PRINTK_TIME is not set |
| 1673 | CONFIG_DEBUG_KERNEL=y | ||
| 1674 | # CONFIG_MAGIC_SYSRQ is not set | 1682 | # CONFIG_MAGIC_SYSRQ is not set |
| 1683 | CONFIG_DEBUG_KERNEL=y | ||
| 1675 | CONFIG_LOG_BUF_SHIFT=14 | 1684 | CONFIG_LOG_BUF_SHIFT=14 |
| 1676 | CONFIG_DETECT_SOFTLOCKUP=y | 1685 | CONFIG_DETECT_SOFTLOCKUP=y |
| 1677 | # CONFIG_SCHEDSTATS is not set | 1686 | # CONFIG_SCHEDSTATS is not set |
| 1678 | # CONFIG_DEBUG_SLAB is not set | 1687 | # CONFIG_DEBUG_SLAB is not set |
| 1688 | # CONFIG_DEBUG_MUTEXES is not set | ||
| 1679 | # CONFIG_DEBUG_SPINLOCK is not set | 1689 | # CONFIG_DEBUG_SPINLOCK is not set |
| 1680 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 1690 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set |
| 1681 | # CONFIG_DEBUG_KOBJECT is not set | 1691 | # CONFIG_DEBUG_KOBJECT is not set |
| @@ -1688,6 +1698,11 @@ CONFIG_XMON=y | |||
| 1688 | CONFIG_XMON_DEFAULT=y | 1698 | CONFIG_XMON_DEFAULT=y |
| 1689 | # CONFIG_BDI_SWITCH is not set | 1699 | # CONFIG_BDI_SWITCH is not set |
| 1690 | CONFIG_BOOTX_TEXT=y | 1700 | CONFIG_BOOTX_TEXT=y |
| 1701 | # CONFIG_PPC_EARLY_DEBUG_LPAR is not set | ||
| 1702 | # CONFIG_PPC_EARLY_DEBUG_G5 is not set | ||
| 1703 | # CONFIG_PPC_EARLY_DEBUG_RTAS is not set | ||
| 1704 | # CONFIG_PPC_EARLY_DEBUG_MAPLE is not set | ||
| 1705 | # CONFIG_PPC_EARLY_DEBUG_ISERIES is not set | ||
| 1691 | 1706 | ||
| 1692 | # | 1707 | # |
| 1693 | # Security options | 1708 | # Security options |
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index a94699d8dc52..c287980b7e65 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
| @@ -60,7 +60,8 @@ obj-$(CONFIG_MODULES) += $(module-y) | |||
| 60 | 60 | ||
| 61 | pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci_iommu.o \ | 61 | pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci_iommu.o \ |
| 62 | pci_direct_iommu.o iomap.o | 62 | pci_direct_iommu.o iomap.o |
| 63 | obj-$(CONFIG_PCI) += $(pci64-y) | 63 | pci32-$(CONFIG_PPC32) := pci_32.o |
| 64 | obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y) | ||
| 64 | kexec-$(CONFIG_PPC64) := machine_kexec_64.o crash.o | 65 | kexec-$(CONFIG_PPC64) := machine_kexec_64.o crash.o |
| 65 | kexec-$(CONFIG_PPC32) := machine_kexec_32.o | 66 | kexec-$(CONFIG_PPC32) := machine_kexec_32.o |
| 66 | obj-$(CONFIG_KEXEC) += machine_kexec.o $(kexec-y) | 67 | obj-$(CONFIG_KEXEC) += machine_kexec.o $(kexec-y) |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 56399c5c931a..840aad43a98b 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
| @@ -135,7 +135,7 @@ int main(void) | |||
| 135 | DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc)); | 135 | DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc)); |
| 136 | DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb)); | 136 | DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb)); |
| 137 | DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp)); | 137 | DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp)); |
| 138 | DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca)); | 138 | DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr)); |
| 139 | DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); | 139 | DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); |
| 140 | 140 | ||
| 141 | DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0)); | 141 | DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0)); |
diff --git a/arch/powerpc/kernel/cpu_setup_power4.S b/arch/powerpc/kernel/cpu_setup_power4.S index cca942fe6115..b61d86e7ceb6 100644 --- a/arch/powerpc/kernel/cpu_setup_power4.S +++ b/arch/powerpc/kernel/cpu_setup_power4.S | |||
| @@ -130,7 +130,7 @@ _GLOBAL(__save_cpu_setup) | |||
| 130 | mfcr r7 | 130 | mfcr r7 |
| 131 | 131 | ||
| 132 | /* Get storage ptr */ | 132 | /* Get storage ptr */ |
| 133 | LOADADDR(r5,cpu_state_storage) | 133 | LOAD_REG_IMMEDIATE(r5,cpu_state_storage) |
| 134 | 134 | ||
| 135 | /* We only deal with 970 for now */ | 135 | /* We only deal with 970 for now */ |
| 136 | mfspr r0,SPRN_PVR | 136 | mfspr r0,SPRN_PVR |
| @@ -164,7 +164,7 @@ _GLOBAL(__restore_cpu_setup) | |||
| 164 | /* Get storage ptr (FIXME when using anton reloc as we | 164 | /* Get storage ptr (FIXME when using anton reloc as we |
| 165 | * are running with translation disabled here | 165 | * are running with translation disabled here |
| 166 | */ | 166 | */ |
| 167 | LOADADDR(r5,cpu_state_storage) | 167 | LOAD_REG_IMMEDIATE(r5,cpu_state_storage) |
| 168 | 168 | ||
| 169 | /* We only deal with 970 for now */ | 169 | /* We only deal with 970 for now */ |
| 170 | mfspr r0,SPRN_PVR | 170 | mfspr r0,SPRN_PVR |
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 43c74a6b07b1..10696456a4c6 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
| @@ -55,7 +55,8 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); | |||
| 55 | #define COMMON_USER_POWER4 (COMMON_USER_PPC64 | PPC_FEATURE_POWER4) | 55 | #define COMMON_USER_POWER4 (COMMON_USER_PPC64 | PPC_FEATURE_POWER4) |
| 56 | #define COMMON_USER_POWER5 (COMMON_USER_PPC64 | PPC_FEATURE_POWER5) | 56 | #define COMMON_USER_POWER5 (COMMON_USER_PPC64 | PPC_FEATURE_POWER5) |
| 57 | #define COMMON_USER_POWER5_PLUS (COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS) | 57 | #define COMMON_USER_POWER5_PLUS (COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS) |
| 58 | 58 | #define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \ | |
| 59 | PPC_FEATURE_BOOKE) | ||
| 59 | 60 | ||
| 60 | /* We only set the spe features if the kernel was compiled with | 61 | /* We only set the spe features if the kernel was compiled with |
| 61 | * spe support | 62 | * spe support |
| @@ -79,7 +80,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 79 | .num_pmcs = 8, | 80 | .num_pmcs = 8, |
| 80 | .cpu_setup = __setup_cpu_power3, | 81 | .cpu_setup = __setup_cpu_power3, |
| 81 | .oprofile_cpu_type = "ppc64/power3", | 82 | .oprofile_cpu_type = "ppc64/power3", |
| 82 | .oprofile_type = RS64, | 83 | .oprofile_type = PPC_OPROFILE_RS64, |
| 84 | .platform = "power3", | ||
| 83 | }, | 85 | }, |
| 84 | { /* Power3+ */ | 86 | { /* Power3+ */ |
| 85 | .pvr_mask = 0xffff0000, | 87 | .pvr_mask = 0xffff0000, |
| @@ -92,7 +94,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 92 | .num_pmcs = 8, | 94 | .num_pmcs = 8, |
| 93 | .cpu_setup = __setup_cpu_power3, | 95 | .cpu_setup = __setup_cpu_power3, |
| 94 | .oprofile_cpu_type = "ppc64/power3", | 96 | .oprofile_cpu_type = "ppc64/power3", |
| 95 | .oprofile_type = RS64, | 97 | .oprofile_type = PPC_OPROFILE_RS64, |
| 98 | .platform = "power3", | ||
| 96 | }, | 99 | }, |
| 97 | { /* Northstar */ | 100 | { /* Northstar */ |
| 98 | .pvr_mask = 0xffff0000, | 101 | .pvr_mask = 0xffff0000, |
| @@ -105,7 +108,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 105 | .num_pmcs = 8, | 108 | .num_pmcs = 8, |
| 106 | .cpu_setup = __setup_cpu_power3, | 109 | .cpu_setup = __setup_cpu_power3, |
| 107 | .oprofile_cpu_type = "ppc64/rs64", | 110 | .oprofile_cpu_type = "ppc64/rs64", |
| 108 | .oprofile_type = RS64, | 111 | .oprofile_type = PPC_OPROFILE_RS64, |
| 112 | .platform = "rs64", | ||
| 109 | }, | 113 | }, |
| 110 | { /* Pulsar */ | 114 | { /* Pulsar */ |
| 111 | .pvr_mask = 0xffff0000, | 115 | .pvr_mask = 0xffff0000, |
| @@ -118,7 +122,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 118 | .num_pmcs = 8, | 122 | .num_pmcs = 8, |
| 119 | .cpu_setup = __setup_cpu_power3, | 123 | .cpu_setup = __setup_cpu_power3, |
| 120 | .oprofile_cpu_type = "ppc64/rs64", | 124 | .oprofile_cpu_type = "ppc64/rs64", |
| 121 | .oprofile_type = RS64, | 125 | .oprofile_type = PPC_OPROFILE_RS64, |
| 126 | .platform = "rs64", | ||
| 122 | }, | 127 | }, |
| 123 | { /* I-star */ | 128 | { /* I-star */ |
| 124 | .pvr_mask = 0xffff0000, | 129 | .pvr_mask = 0xffff0000, |
| @@ -131,7 +136,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 131 | .num_pmcs = 8, | 136 | .num_pmcs = 8, |
| 132 | .cpu_setup = __setup_cpu_power3, | 137 | .cpu_setup = __setup_cpu_power3, |
| 133 | .oprofile_cpu_type = "ppc64/rs64", | 138 | .oprofile_cpu_type = "ppc64/rs64", |
| 134 | .oprofile_type = RS64, | 139 | .oprofile_type = PPC_OPROFILE_RS64, |
| 140 | .platform = "rs64", | ||
| 135 | }, | 141 | }, |
| 136 | { /* S-star */ | 142 | { /* S-star */ |
| 137 | .pvr_mask = 0xffff0000, | 143 | .pvr_mask = 0xffff0000, |
| @@ -144,7 +150,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 144 | .num_pmcs = 8, | 150 | .num_pmcs = 8, |
| 145 | .cpu_setup = __setup_cpu_power3, | 151 | .cpu_setup = __setup_cpu_power3, |
| 146 | .oprofile_cpu_type = "ppc64/rs64", | 152 | .oprofile_cpu_type = "ppc64/rs64", |
| 147 | .oprofile_type = RS64, | 153 | .oprofile_type = PPC_OPROFILE_RS64, |
| 154 | .platform = "rs64", | ||
| 148 | }, | 155 | }, |
| 149 | { /* Power4 */ | 156 | { /* Power4 */ |
| 150 | .pvr_mask = 0xffff0000, | 157 | .pvr_mask = 0xffff0000, |
| @@ -157,7 +164,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 157 | .num_pmcs = 8, | 164 | .num_pmcs = 8, |
| 158 | .cpu_setup = __setup_cpu_power4, | 165 | .cpu_setup = __setup_cpu_power4, |
| 159 | .oprofile_cpu_type = "ppc64/power4", | 166 | .oprofile_cpu_type = "ppc64/power4", |
| 160 | .oprofile_type = POWER4, | 167 | .oprofile_type = PPC_OPROFILE_POWER4, |
| 168 | .platform = "power4", | ||
| 161 | }, | 169 | }, |
| 162 | { /* Power4+ */ | 170 | { /* Power4+ */ |
| 163 | .pvr_mask = 0xffff0000, | 171 | .pvr_mask = 0xffff0000, |
| @@ -170,7 +178,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 170 | .num_pmcs = 8, | 178 | .num_pmcs = 8, |
| 171 | .cpu_setup = __setup_cpu_power4, | 179 | .cpu_setup = __setup_cpu_power4, |
| 172 | .oprofile_cpu_type = "ppc64/power4", | 180 | .oprofile_cpu_type = "ppc64/power4", |
| 173 | .oprofile_type = POWER4, | 181 | .oprofile_type = PPC_OPROFILE_POWER4, |
| 182 | .platform = "power4", | ||
| 174 | }, | 183 | }, |
| 175 | { /* PPC970 */ | 184 | { /* PPC970 */ |
| 176 | .pvr_mask = 0xffff0000, | 185 | .pvr_mask = 0xffff0000, |
| @@ -184,7 +193,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 184 | .num_pmcs = 8, | 193 | .num_pmcs = 8, |
| 185 | .cpu_setup = __setup_cpu_ppc970, | 194 | .cpu_setup = __setup_cpu_ppc970, |
| 186 | .oprofile_cpu_type = "ppc64/970", | 195 | .oprofile_cpu_type = "ppc64/970", |
| 187 | .oprofile_type = POWER4, | 196 | .oprofile_type = PPC_OPROFILE_POWER4, |
| 197 | .platform = "ppc970", | ||
| 188 | }, | 198 | }, |
| 189 | #endif /* CONFIG_PPC64 */ | 199 | #endif /* CONFIG_PPC64 */ |
| 190 | #if defined(CONFIG_PPC64) || defined(CONFIG_POWER4) | 200 | #if defined(CONFIG_PPC64) || defined(CONFIG_POWER4) |
| @@ -204,7 +214,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 204 | .num_pmcs = 8, | 214 | .num_pmcs = 8, |
| 205 | .cpu_setup = __setup_cpu_ppc970, | 215 | .cpu_setup = __setup_cpu_ppc970, |
| 206 | .oprofile_cpu_type = "ppc64/970", | 216 | .oprofile_cpu_type = "ppc64/970", |
| 207 | .oprofile_type = POWER4, | 217 | .oprofile_type = PPC_OPROFILE_POWER4, |
| 218 | .platform = "ppc970", | ||
| 208 | }, | 219 | }, |
| 209 | #endif /* defined(CONFIG_PPC64) || defined(CONFIG_POWER4) */ | 220 | #endif /* defined(CONFIG_PPC64) || defined(CONFIG_POWER4) */ |
| 210 | #ifdef CONFIG_PPC64 | 221 | #ifdef CONFIG_PPC64 |
| @@ -219,7 +230,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 219 | .dcache_bsize = 128, | 230 | .dcache_bsize = 128, |
| 220 | .cpu_setup = __setup_cpu_ppc970, | 231 | .cpu_setup = __setup_cpu_ppc970, |
| 221 | .oprofile_cpu_type = "ppc64/970", | 232 | .oprofile_cpu_type = "ppc64/970", |
| 222 | .oprofile_type = POWER4, | 233 | .oprofile_type = PPC_OPROFILE_POWER4, |
| 234 | .platform = "ppc970", | ||
| 223 | }, | 235 | }, |
| 224 | { /* Power5 GR */ | 236 | { /* Power5 GR */ |
| 225 | .pvr_mask = 0xffff0000, | 237 | .pvr_mask = 0xffff0000, |
| @@ -232,7 +244,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 232 | .num_pmcs = 6, | 244 | .num_pmcs = 6, |
| 233 | .cpu_setup = __setup_cpu_power4, | 245 | .cpu_setup = __setup_cpu_power4, |
| 234 | .oprofile_cpu_type = "ppc64/power5", | 246 | .oprofile_cpu_type = "ppc64/power5", |
| 235 | .oprofile_type = POWER4, | 247 | .oprofile_type = PPC_OPROFILE_POWER4, |
| 248 | .platform = "power5", | ||
| 236 | }, | 249 | }, |
| 237 | { /* Power5 GS */ | 250 | { /* Power5 GS */ |
| 238 | .pvr_mask = 0xffff0000, | 251 | .pvr_mask = 0xffff0000, |
| @@ -245,7 +258,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 245 | .num_pmcs = 6, | 258 | .num_pmcs = 6, |
| 246 | .cpu_setup = __setup_cpu_power4, | 259 | .cpu_setup = __setup_cpu_power4, |
| 247 | .oprofile_cpu_type = "ppc64/power5+", | 260 | .oprofile_cpu_type = "ppc64/power5+", |
| 248 | .oprofile_type = POWER4, | 261 | .oprofile_type = PPC_OPROFILE_POWER4, |
| 262 | .platform = "power5+", | ||
| 249 | }, | 263 | }, |
| 250 | { /* Cell Broadband Engine */ | 264 | { /* Cell Broadband Engine */ |
| 251 | .pvr_mask = 0xffff0000, | 265 | .pvr_mask = 0xffff0000, |
| @@ -257,6 +271,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 257 | .icache_bsize = 128, | 271 | .icache_bsize = 128, |
| 258 | .dcache_bsize = 128, | 272 | .dcache_bsize = 128, |
| 259 | .cpu_setup = __setup_cpu_be, | 273 | .cpu_setup = __setup_cpu_be, |
| 274 | .platform = "ppc-cell-be", | ||
| 260 | }, | 275 | }, |
| 261 | { /* default match */ | 276 | { /* default match */ |
| 262 | .pvr_mask = 0x00000000, | 277 | .pvr_mask = 0x00000000, |
| @@ -268,6 +283,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 268 | .dcache_bsize = 128, | 283 | .dcache_bsize = 128, |
| 269 | .num_pmcs = 6, | 284 | .num_pmcs = 6, |
| 270 | .cpu_setup = __setup_cpu_power4, | 285 | .cpu_setup = __setup_cpu_power4, |
| 286 | .platform = "power4", | ||
| 271 | } | 287 | } |
| 272 | #endif /* CONFIG_PPC64 */ | 288 | #endif /* CONFIG_PPC64 */ |
| 273 | #ifdef CONFIG_PPC32 | 289 | #ifdef CONFIG_PPC32 |
| @@ -281,6 +297,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 281 | PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB, | 297 | PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB, |
| 282 | .icache_bsize = 32, | 298 | .icache_bsize = 32, |
| 283 | .dcache_bsize = 32, | 299 | .dcache_bsize = 32, |
| 300 | .platform = "ppc601", | ||
| 284 | }, | 301 | }, |
| 285 | { /* 603 */ | 302 | { /* 603 */ |
| 286 | .pvr_mask = 0xffff0000, | 303 | .pvr_mask = 0xffff0000, |
| @@ -290,7 +307,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 290 | .cpu_user_features = COMMON_USER, | 307 | .cpu_user_features = COMMON_USER, |
| 291 | .icache_bsize = 32, | 308 | .icache_bsize = 32, |
| 292 | .dcache_bsize = 32, | 309 | .dcache_bsize = 32, |
| 293 | .cpu_setup = __setup_cpu_603 | 310 | .cpu_setup = __setup_cpu_603, |
| 311 | .platform = "ppc603", | ||
| 294 | }, | 312 | }, |
| 295 | { /* 603e */ | 313 | { /* 603e */ |
| 296 | .pvr_mask = 0xffff0000, | 314 | .pvr_mask = 0xffff0000, |
| @@ -300,7 +318,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 300 | .cpu_user_features = COMMON_USER, | 318 | .cpu_user_features = COMMON_USER, |
| 301 | .icache_bsize = 32, | 319 | .icache_bsize = 32, |
| 302 | .dcache_bsize = 32, | 320 | .dcache_bsize = 32, |
| 303 | .cpu_setup = __setup_cpu_603 | 321 | .cpu_setup = __setup_cpu_603, |
| 322 | .platform = "ppc603", | ||
| 304 | }, | 323 | }, |
| 305 | { /* 603ev */ | 324 | { /* 603ev */ |
| 306 | .pvr_mask = 0xffff0000, | 325 | .pvr_mask = 0xffff0000, |
| @@ -310,7 +329,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 310 | .cpu_user_features = COMMON_USER, | 329 | .cpu_user_features = COMMON_USER, |
| 311 | .icache_bsize = 32, | 330 | .icache_bsize = 32, |
| 312 | .dcache_bsize = 32, | 331 | .dcache_bsize = 32, |
| 313 | .cpu_setup = __setup_cpu_603 | 332 | .cpu_setup = __setup_cpu_603, |
| 333 | .platform = "ppc603", | ||
| 314 | }, | 334 | }, |
| 315 | { /* 604 */ | 335 | { /* 604 */ |
| 316 | .pvr_mask = 0xffff0000, | 336 | .pvr_mask = 0xffff0000, |
| @@ -321,7 +341,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 321 | .icache_bsize = 32, | 341 | .icache_bsize = 32, |
| 322 | .dcache_bsize = 32, | 342 | .dcache_bsize = 32, |
| 323 | .num_pmcs = 2, | 343 | .num_pmcs = 2, |
| 324 | .cpu_setup = __setup_cpu_604 | 344 | .cpu_setup = __setup_cpu_604, |
| 345 | .platform = "ppc604", | ||
| 325 | }, | 346 | }, |
| 326 | { /* 604e */ | 347 | { /* 604e */ |
| 327 | .pvr_mask = 0xfffff000, | 348 | .pvr_mask = 0xfffff000, |
| @@ -332,7 +353,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 332 | .icache_bsize = 32, | 353 | .icache_bsize = 32, |
| 333 | .dcache_bsize = 32, | 354 | .dcache_bsize = 32, |
| 334 | .num_pmcs = 4, | 355 | .num_pmcs = 4, |
| 335 | .cpu_setup = __setup_cpu_604 | 356 | .cpu_setup = __setup_cpu_604, |
| 357 | .platform = "ppc604", | ||
| 336 | }, | 358 | }, |
| 337 | { /* 604r */ | 359 | { /* 604r */ |
| 338 | .pvr_mask = 0xffff0000, | 360 | .pvr_mask = 0xffff0000, |
| @@ -343,7 +365,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 343 | .icache_bsize = 32, | 365 | .icache_bsize = 32, |
| 344 | .dcache_bsize = 32, | 366 | .dcache_bsize = 32, |
| 345 | .num_pmcs = 4, | 367 | .num_pmcs = 4, |
| 346 | .cpu_setup = __setup_cpu_604 | 368 | .cpu_setup = __setup_cpu_604, |
| 369 | .platform = "ppc604", | ||
| 347 | }, | 370 | }, |
| 348 | { /* 604ev */ | 371 | { /* 604ev */ |
| 349 | .pvr_mask = 0xffff0000, | 372 | .pvr_mask = 0xffff0000, |
| @@ -354,7 +377,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 354 | .icache_bsize = 32, | 377 | .icache_bsize = 32, |
| 355 | .dcache_bsize = 32, | 378 | .dcache_bsize = 32, |
| 356 | .num_pmcs = 4, | 379 | .num_pmcs = 4, |
| 357 | .cpu_setup = __setup_cpu_604 | 380 | .cpu_setup = __setup_cpu_604, |
| 381 | .platform = "ppc604", | ||
| 358 | }, | 382 | }, |
| 359 | { /* 740/750 (0x4202, don't support TAU ?) */ | 383 | { /* 740/750 (0x4202, don't support TAU ?) */ |
| 360 | .pvr_mask = 0xffffffff, | 384 | .pvr_mask = 0xffffffff, |
| @@ -365,7 +389,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 365 | .icache_bsize = 32, | 389 | .icache_bsize = 32, |
| 366 | .dcache_bsize = 32, | 390 | .dcache_bsize = 32, |
| 367 | .num_pmcs = 4, | 391 | .num_pmcs = 4, |
| 368 | .cpu_setup = __setup_cpu_750 | 392 | .cpu_setup = __setup_cpu_750, |
| 393 | .platform = "ppc750", | ||
| 369 | }, | 394 | }, |
| 370 | { /* 750CX (80100 and 8010x?) */ | 395 | { /* 750CX (80100 and 8010x?) */ |
| 371 | .pvr_mask = 0xfffffff0, | 396 | .pvr_mask = 0xfffffff0, |
| @@ -376,7 +401,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 376 | .icache_bsize = 32, | 401 | .icache_bsize = 32, |
| 377 | .dcache_bsize = 32, | 402 | .dcache_bsize = 32, |
| 378 | .num_pmcs = 4, | 403 | .num_pmcs = 4, |
| 379 | .cpu_setup = __setup_cpu_750cx | 404 | .cpu_setup = __setup_cpu_750cx, |
| 405 | .platform = "ppc750", | ||
| 380 | }, | 406 | }, |
| 381 | { /* 750CX (82201 and 82202) */ | 407 | { /* 750CX (82201 and 82202) */ |
| 382 | .pvr_mask = 0xfffffff0, | 408 | .pvr_mask = 0xfffffff0, |
| @@ -387,7 +413,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 387 | .icache_bsize = 32, | 413 | .icache_bsize = 32, |
| 388 | .dcache_bsize = 32, | 414 | .dcache_bsize = 32, |
| 389 | .num_pmcs = 4, | 415 | .num_pmcs = 4, |
| 390 | .cpu_setup = __setup_cpu_750cx | 416 | .cpu_setup = __setup_cpu_750cx, |
| 417 | .platform = "ppc750", | ||
| 391 | }, | 418 | }, |
| 392 | { /* 750CXe (82214) */ | 419 | { /* 750CXe (82214) */ |
| 393 | .pvr_mask = 0xfffffff0, | 420 | .pvr_mask = 0xfffffff0, |
| @@ -398,7 +425,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 398 | .icache_bsize = 32, | 425 | .icache_bsize = 32, |
| 399 | .dcache_bsize = 32, | 426 | .dcache_bsize = 32, |
| 400 | .num_pmcs = 4, | 427 | .num_pmcs = 4, |
| 401 | .cpu_setup = __setup_cpu_750cx | 428 | .cpu_setup = __setup_cpu_750cx, |
| 429 | .platform = "ppc750", | ||
| 402 | }, | 430 | }, |
| 403 | { /* 750CXe "Gekko" (83214) */ | 431 | { /* 750CXe "Gekko" (83214) */ |
| 404 | .pvr_mask = 0xffffffff, | 432 | .pvr_mask = 0xffffffff, |
| @@ -409,7 +437,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 409 | .icache_bsize = 32, | 437 | .icache_bsize = 32, |
| 410 | .dcache_bsize = 32, | 438 | .dcache_bsize = 32, |
| 411 | .num_pmcs = 4, | 439 | .num_pmcs = 4, |
| 412 | .cpu_setup = __setup_cpu_750cx | 440 | .cpu_setup = __setup_cpu_750cx, |
| 441 | .platform = "ppc750", | ||
| 413 | }, | 442 | }, |
| 414 | { /* 745/755 */ | 443 | { /* 745/755 */ |
| 415 | .pvr_mask = 0xfffff000, | 444 | .pvr_mask = 0xfffff000, |
| @@ -420,7 +449,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 420 | .icache_bsize = 32, | 449 | .icache_bsize = 32, |
| 421 | .dcache_bsize = 32, | 450 | .dcache_bsize = 32, |
| 422 | .num_pmcs = 4, | 451 | .num_pmcs = 4, |
| 423 | .cpu_setup = __setup_cpu_750 | 452 | .cpu_setup = __setup_cpu_750, |
| 453 | .platform = "ppc750", | ||
| 424 | }, | 454 | }, |
| 425 | { /* 750FX rev 1.x */ | 455 | { /* 750FX rev 1.x */ |
| 426 | .pvr_mask = 0xffffff00, | 456 | .pvr_mask = 0xffffff00, |
| @@ -431,7 +461,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 431 | .icache_bsize = 32, | 461 | .icache_bsize = 32, |
| 432 | .dcache_bsize = 32, | 462 | .dcache_bsize = 32, |
| 433 | .num_pmcs = 4, | 463 | .num_pmcs = 4, |
| 434 | .cpu_setup = __setup_cpu_750 | 464 | .cpu_setup = __setup_cpu_750, |
| 465 | .platform = "ppc750", | ||
| 435 | }, | 466 | }, |
| 436 | { /* 750FX rev 2.0 must disable HID0[DPM] */ | 467 | { /* 750FX rev 2.0 must disable HID0[DPM] */ |
| 437 | .pvr_mask = 0xffffffff, | 468 | .pvr_mask = 0xffffffff, |
| @@ -442,7 +473,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 442 | .icache_bsize = 32, | 473 | .icache_bsize = 32, |
| 443 | .dcache_bsize = 32, | 474 | .dcache_bsize = 32, |
| 444 | .num_pmcs = 4, | 475 | .num_pmcs = 4, |
| 445 | .cpu_setup = __setup_cpu_750 | 476 | .cpu_setup = __setup_cpu_750, |
| 477 | .platform = "ppc750", | ||
| 446 | }, | 478 | }, |
| 447 | { /* 750FX (All revs except 2.0) */ | 479 | { /* 750FX (All revs except 2.0) */ |
| 448 | .pvr_mask = 0xffff0000, | 480 | .pvr_mask = 0xffff0000, |
| @@ -453,7 +485,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 453 | .icache_bsize = 32, | 485 | .icache_bsize = 32, |
| 454 | .dcache_bsize = 32, | 486 | .dcache_bsize = 32, |
| 455 | .num_pmcs = 4, | 487 | .num_pmcs = 4, |
| 456 | .cpu_setup = __setup_cpu_750fx | 488 | .cpu_setup = __setup_cpu_750fx, |
| 489 | .platform = "ppc750", | ||
| 457 | }, | 490 | }, |
| 458 | { /* 750GX */ | 491 | { /* 750GX */ |
| 459 | .pvr_mask = 0xffff0000, | 492 | .pvr_mask = 0xffff0000, |
| @@ -464,7 +497,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 464 | .icache_bsize = 32, | 497 | .icache_bsize = 32, |
| 465 | .dcache_bsize = 32, | 498 | .dcache_bsize = 32, |
| 466 | .num_pmcs = 4, | 499 | .num_pmcs = 4, |
| 467 | .cpu_setup = __setup_cpu_750fx | 500 | .cpu_setup = __setup_cpu_750fx, |
| 501 | .platform = "ppc750", | ||
| 468 | }, | 502 | }, |
| 469 | { /* 740/750 (L2CR bit need fixup for 740) */ | 503 | { /* 740/750 (L2CR bit need fixup for 740) */ |
| 470 | .pvr_mask = 0xffff0000, | 504 | .pvr_mask = 0xffff0000, |
| @@ -475,7 +509,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 475 | .icache_bsize = 32, | 509 | .icache_bsize = 32, |
| 476 | .dcache_bsize = 32, | 510 | .dcache_bsize = 32, |
| 477 | .num_pmcs = 4, | 511 | .num_pmcs = 4, |
| 478 | .cpu_setup = __setup_cpu_750 | 512 | .cpu_setup = __setup_cpu_750, |
| 513 | .platform = "ppc750", | ||
| 479 | }, | 514 | }, |
| 480 | { /* 7400 rev 1.1 ? (no TAU) */ | 515 | { /* 7400 rev 1.1 ? (no TAU) */ |
| 481 | .pvr_mask = 0xffffffff, | 516 | .pvr_mask = 0xffffffff, |
| @@ -486,7 +521,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 486 | .icache_bsize = 32, | 521 | .icache_bsize = 32, |
| 487 | .dcache_bsize = 32, | 522 | .dcache_bsize = 32, |
| 488 | .num_pmcs = 4, | 523 | .num_pmcs = 4, |
| 489 | .cpu_setup = __setup_cpu_7400 | 524 | .cpu_setup = __setup_cpu_7400, |
| 525 | .platform = "ppc7400", | ||
| 490 | }, | 526 | }, |
| 491 | { /* 7400 */ | 527 | { /* 7400 */ |
| 492 | .pvr_mask = 0xffff0000, | 528 | .pvr_mask = 0xffff0000, |
| @@ -497,7 +533,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 497 | .icache_bsize = 32, | 533 | .icache_bsize = 32, |
| 498 | .dcache_bsize = 32, | 534 | .dcache_bsize = 32, |
| 499 | .num_pmcs = 4, | 535 | .num_pmcs = 4, |
| 500 | .cpu_setup = __setup_cpu_7400 | 536 | .cpu_setup = __setup_cpu_7400, |
| 537 | .platform = "ppc7400", | ||
| 501 | }, | 538 | }, |
| 502 | { /* 7410 */ | 539 | { /* 7410 */ |
| 503 | .pvr_mask = 0xffff0000, | 540 | .pvr_mask = 0xffff0000, |
| @@ -508,7 +545,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 508 | .icache_bsize = 32, | 545 | .icache_bsize = 32, |
| 509 | .dcache_bsize = 32, | 546 | .dcache_bsize = 32, |
| 510 | .num_pmcs = 4, | 547 | .num_pmcs = 4, |
| 511 | .cpu_setup = __setup_cpu_7410 | 548 | .cpu_setup = __setup_cpu_7410, |
| 549 | .platform = "ppc7400", | ||
| 512 | }, | 550 | }, |
| 513 | { /* 7450 2.0 - no doze/nap */ | 551 | { /* 7450 2.0 - no doze/nap */ |
| 514 | .pvr_mask = 0xffffffff, | 552 | .pvr_mask = 0xffffffff, |
| @@ -521,7 +559,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 521 | .num_pmcs = 6, | 559 | .num_pmcs = 6, |
| 522 | .cpu_setup = __setup_cpu_745x, | 560 | .cpu_setup = __setup_cpu_745x, |
| 523 | .oprofile_cpu_type = "ppc/7450", | 561 | .oprofile_cpu_type = "ppc/7450", |
| 524 | .oprofile_type = G4, | 562 | .oprofile_type = PPC_OPROFILE_G4, |
| 563 | .platform = "ppc7450", | ||
| 525 | }, | 564 | }, |
| 526 | { /* 7450 2.1 */ | 565 | { /* 7450 2.1 */ |
| 527 | .pvr_mask = 0xffffffff, | 566 | .pvr_mask = 0xffffffff, |
| @@ -534,7 +573,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 534 | .num_pmcs = 6, | 573 | .num_pmcs = 6, |
| 535 | .cpu_setup = __setup_cpu_745x, | 574 | .cpu_setup = __setup_cpu_745x, |
| 536 | .oprofile_cpu_type = "ppc/7450", | 575 | .oprofile_cpu_type = "ppc/7450", |
| 537 | .oprofile_type = G4, | 576 | .oprofile_type = PPC_OPROFILE_G4, |
| 577 | .platform = "ppc7450", | ||
| 538 | }, | 578 | }, |
| 539 | { /* 7450 2.3 and newer */ | 579 | { /* 7450 2.3 and newer */ |
| 540 | .pvr_mask = 0xffff0000, | 580 | .pvr_mask = 0xffff0000, |
| @@ -547,7 +587,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 547 | .num_pmcs = 6, | 587 | .num_pmcs = 6, |
| 548 | .cpu_setup = __setup_cpu_745x, | 588 | .cpu_setup = __setup_cpu_745x, |
| 549 | .oprofile_cpu_type = "ppc/7450", | 589 | .oprofile_cpu_type = "ppc/7450", |
| 550 | .oprofile_type = G4, | 590 | .oprofile_type = PPC_OPROFILE_G4, |
| 591 | .platform = "ppc7450", | ||
| 551 | }, | 592 | }, |
| 552 | { /* 7455 rev 1.x */ | 593 | { /* 7455 rev 1.x */ |
| 553 | .pvr_mask = 0xffffff00, | 594 | .pvr_mask = 0xffffff00, |
| @@ -560,7 +601,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 560 | .num_pmcs = 6, | 601 | .num_pmcs = 6, |
| 561 | .cpu_setup = __setup_cpu_745x, | 602 | .cpu_setup = __setup_cpu_745x, |
| 562 | .oprofile_cpu_type = "ppc/7450", | 603 | .oprofile_cpu_type = "ppc/7450", |
| 563 | .oprofile_type = G4, | 604 | .oprofile_type = PPC_OPROFILE_G4, |
| 605 | .platform = "ppc7450", | ||
| 564 | }, | 606 | }, |
| 565 | { /* 7455 rev 2.0 */ | 607 | { /* 7455 rev 2.0 */ |
| 566 | .pvr_mask = 0xffffffff, | 608 | .pvr_mask = 0xffffffff, |
| @@ -573,7 +615,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 573 | .num_pmcs = 6, | 615 | .num_pmcs = 6, |
| 574 | .cpu_setup = __setup_cpu_745x, | 616 | .cpu_setup = __setup_cpu_745x, |
| 575 | .oprofile_cpu_type = "ppc/7450", | 617 | .oprofile_cpu_type = "ppc/7450", |
| 576 | .oprofile_type = G4, | 618 | .oprofile_type = PPC_OPROFILE_G4, |
| 619 | .platform = "ppc7450", | ||
| 577 | }, | 620 | }, |
| 578 | { /* 7455 others */ | 621 | { /* 7455 others */ |
| 579 | .pvr_mask = 0xffff0000, | 622 | .pvr_mask = 0xffff0000, |
| @@ -586,7 +629,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 586 | .num_pmcs = 6, | 629 | .num_pmcs = 6, |
| 587 | .cpu_setup = __setup_cpu_745x, | 630 | .cpu_setup = __setup_cpu_745x, |
| 588 | .oprofile_cpu_type = "ppc/7450", | 631 | .oprofile_cpu_type = "ppc/7450", |
| 589 | .oprofile_type = G4, | 632 | .oprofile_type = PPC_OPROFILE_G4, |
| 633 | .platform = "ppc7450", | ||
| 590 | }, | 634 | }, |
| 591 | { /* 7447/7457 Rev 1.0 */ | 635 | { /* 7447/7457 Rev 1.0 */ |
| 592 | .pvr_mask = 0xffffffff, | 636 | .pvr_mask = 0xffffffff, |
| @@ -599,7 +643,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 599 | .num_pmcs = 6, | 643 | .num_pmcs = 6, |
| 600 | .cpu_setup = __setup_cpu_745x, | 644 | .cpu_setup = __setup_cpu_745x, |
| 601 | .oprofile_cpu_type = "ppc/7450", | 645 | .oprofile_cpu_type = "ppc/7450", |
| 602 | .oprofile_type = G4, | 646 | .oprofile_type = PPC_OPROFILE_G4, |
| 647 | .platform = "ppc7450", | ||
| 603 | }, | 648 | }, |
| 604 | { /* 7447/7457 Rev 1.1 */ | 649 | { /* 7447/7457 Rev 1.1 */ |
| 605 | .pvr_mask = 0xffffffff, | 650 | .pvr_mask = 0xffffffff, |
| @@ -612,7 +657,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 612 | .num_pmcs = 6, | 657 | .num_pmcs = 6, |
| 613 | .cpu_setup = __setup_cpu_745x, | 658 | .cpu_setup = __setup_cpu_745x, |
| 614 | .oprofile_cpu_type = "ppc/7450", | 659 | .oprofile_cpu_type = "ppc/7450", |
| 615 | .oprofile_type = G4, | 660 | .oprofile_type = PPC_OPROFILE_G4, |
| 661 | .platform = "ppc7450", | ||
| 616 | }, | 662 | }, |
| 617 | { /* 7447/7457 Rev 1.2 and later */ | 663 | { /* 7447/7457 Rev 1.2 and later */ |
| 618 | .pvr_mask = 0xffff0000, | 664 | .pvr_mask = 0xffff0000, |
| @@ -625,7 +671,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 625 | .num_pmcs = 6, | 671 | .num_pmcs = 6, |
| 626 | .cpu_setup = __setup_cpu_745x, | 672 | .cpu_setup = __setup_cpu_745x, |
| 627 | .oprofile_cpu_type = "ppc/7450", | 673 | .oprofile_cpu_type = "ppc/7450", |
| 628 | .oprofile_type = G4, | 674 | .oprofile_type = PPC_OPROFILE_G4, |
| 675 | .platform = "ppc7450", | ||
| 629 | }, | 676 | }, |
| 630 | { /* 7447A */ | 677 | { /* 7447A */ |
| 631 | .pvr_mask = 0xffff0000, | 678 | .pvr_mask = 0xffff0000, |
| @@ -638,7 +685,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 638 | .num_pmcs = 6, | 685 | .num_pmcs = 6, |
| 639 | .cpu_setup = __setup_cpu_745x, | 686 | .cpu_setup = __setup_cpu_745x, |
| 640 | .oprofile_cpu_type = "ppc/7450", | 687 | .oprofile_cpu_type = "ppc/7450", |
| 641 | .oprofile_type = G4, | 688 | .oprofile_type = PPC_OPROFILE_G4, |
| 689 | .platform = "ppc7450", | ||
| 642 | }, | 690 | }, |
| 643 | { /* 7448 */ | 691 | { /* 7448 */ |
| 644 | .pvr_mask = 0xffff0000, | 692 | .pvr_mask = 0xffff0000, |
| @@ -651,7 +699,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 651 | .num_pmcs = 6, | 699 | .num_pmcs = 6, |
| 652 | .cpu_setup = __setup_cpu_745x, | 700 | .cpu_setup = __setup_cpu_745x, |
| 653 | .oprofile_cpu_type = "ppc/7450", | 701 | .oprofile_cpu_type = "ppc/7450", |
| 654 | .oprofile_type = G4, | 702 | .oprofile_type = PPC_OPROFILE_G4, |
| 703 | .platform = "ppc7450", | ||
| 655 | }, | 704 | }, |
| 656 | { /* 82xx (8240, 8245, 8260 are all 603e cores) */ | 705 | { /* 82xx (8240, 8245, 8260 are all 603e cores) */ |
| 657 | .pvr_mask = 0x7fff0000, | 706 | .pvr_mask = 0x7fff0000, |
| @@ -661,7 +710,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 661 | .cpu_user_features = COMMON_USER, | 710 | .cpu_user_features = COMMON_USER, |
| 662 | .icache_bsize = 32, | 711 | .icache_bsize = 32, |
| 663 | .dcache_bsize = 32, | 712 | .dcache_bsize = 32, |
| 664 | .cpu_setup = __setup_cpu_603 | 713 | .cpu_setup = __setup_cpu_603, |
| 714 | .platform = "ppc603", | ||
| 665 | }, | 715 | }, |
| 666 | { /* All G2_LE (603e core, plus some) have the same pvr */ | 716 | { /* All G2_LE (603e core, plus some) have the same pvr */ |
| 667 | .pvr_mask = 0x7fff0000, | 717 | .pvr_mask = 0x7fff0000, |
| @@ -671,7 +721,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 671 | .cpu_user_features = COMMON_USER, | 721 | .cpu_user_features = COMMON_USER, |
| 672 | .icache_bsize = 32, | 722 | .icache_bsize = 32, |
| 673 | .dcache_bsize = 32, | 723 | .dcache_bsize = 32, |
| 674 | .cpu_setup = __setup_cpu_603 | 724 | .cpu_setup = __setup_cpu_603, |
| 725 | .platform = "ppc603", | ||
| 675 | }, | 726 | }, |
| 676 | { /* e300 (a 603e core, plus some) on 83xx */ | 727 | { /* e300 (a 603e core, plus some) on 83xx */ |
| 677 | .pvr_mask = 0x7fff0000, | 728 | .pvr_mask = 0x7fff0000, |
| @@ -681,7 +732,8 @@ struct cpu_spec cpu_specs[] = { | |||
| 681 | .cpu_user_features = COMMON_USER, | 732 | .cpu_user_features = COMMON_USER, |
| 682 | .icache_bsize = 32, | 733 | .icache_bsize = 32, |
| 683 | .dcache_bsize = 32, | 734 | .dcache_bsize = 32, |
| 684 | .cpu_setup = __setup_cpu_603 | 735 | .cpu_setup = __setup_cpu_603, |
| 736 | .platform = "ppc603", | ||
| 685 | }, | 737 | }, |
| 686 | { /* default match, we assume split I/D cache & TB (non-601)... */ | 738 | { /* default match, we assume split I/D cache & TB (non-601)... */ |
| 687 | .pvr_mask = 0x00000000, | 739 | .pvr_mask = 0x00000000, |
| @@ -691,6 +743,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 691 | .cpu_user_features = COMMON_USER, | 743 | .cpu_user_features = COMMON_USER, |
| 692 | .icache_bsize = 32, | 744 | .icache_bsize = 32, |
| 693 | .dcache_bsize = 32, | 745 | .dcache_bsize = 32, |
| 746 | .platform = "ppc603", | ||
| 694 | }, | 747 | }, |
| 695 | #endif /* CLASSIC_PPC */ | 748 | #endif /* CLASSIC_PPC */ |
| 696 | #ifdef CONFIG_8xx | 749 | #ifdef CONFIG_8xx |
| @@ -704,6 +757,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 704 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, | 757 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, |
| 705 | .icache_bsize = 16, | 758 | .icache_bsize = 16, |
| 706 | .dcache_bsize = 16, | 759 | .dcache_bsize = 16, |
| 760 | .platform = "ppc823", | ||
| 707 | }, | 761 | }, |
| 708 | #endif /* CONFIG_8xx */ | 762 | #endif /* CONFIG_8xx */ |
| 709 | #ifdef CONFIG_40x | 763 | #ifdef CONFIG_40x |
| @@ -715,6 +769,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 715 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, | 769 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, |
| 716 | .icache_bsize = 16, | 770 | .icache_bsize = 16, |
| 717 | .dcache_bsize = 16, | 771 | .dcache_bsize = 16, |
| 772 | .platform = "ppc403", | ||
| 718 | }, | 773 | }, |
| 719 | { /* 403GCX */ | 774 | { /* 403GCX */ |
| 720 | .pvr_mask = 0xffffff00, | 775 | .pvr_mask = 0xffffff00, |
| @@ -725,6 +780,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 725 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB, | 780 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB, |
| 726 | .icache_bsize = 16, | 781 | .icache_bsize = 16, |
| 727 | .dcache_bsize = 16, | 782 | .dcache_bsize = 16, |
| 783 | .platform = "ppc403", | ||
| 728 | }, | 784 | }, |
| 729 | { /* 403G ?? */ | 785 | { /* 403G ?? */ |
| 730 | .pvr_mask = 0xffff0000, | 786 | .pvr_mask = 0xffff0000, |
| @@ -734,6 +790,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 734 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, | 790 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, |
| 735 | .icache_bsize = 16, | 791 | .icache_bsize = 16, |
| 736 | .dcache_bsize = 16, | 792 | .dcache_bsize = 16, |
| 793 | .platform = "ppc403", | ||
| 737 | }, | 794 | }, |
| 738 | { /* 405GP */ | 795 | { /* 405GP */ |
| 739 | .pvr_mask = 0xffff0000, | 796 | .pvr_mask = 0xffff0000, |
| @@ -744,6 +801,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 744 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 801 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
| 745 | .icache_bsize = 32, | 802 | .icache_bsize = 32, |
| 746 | .dcache_bsize = 32, | 803 | .dcache_bsize = 32, |
| 804 | .platform = "ppc405", | ||
| 747 | }, | 805 | }, |
| 748 | { /* STB 03xxx */ | 806 | { /* STB 03xxx */ |
| 749 | .pvr_mask = 0xffff0000, | 807 | .pvr_mask = 0xffff0000, |
| @@ -754,6 +812,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 754 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 812 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
| 755 | .icache_bsize = 32, | 813 | .icache_bsize = 32, |
| 756 | .dcache_bsize = 32, | 814 | .dcache_bsize = 32, |
| 815 | .platform = "ppc405", | ||
| 757 | }, | 816 | }, |
| 758 | { /* STB 04xxx */ | 817 | { /* STB 04xxx */ |
| 759 | .pvr_mask = 0xffff0000, | 818 | .pvr_mask = 0xffff0000, |
| @@ -764,6 +823,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 764 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 823 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
| 765 | .icache_bsize = 32, | 824 | .icache_bsize = 32, |
| 766 | .dcache_bsize = 32, | 825 | .dcache_bsize = 32, |
| 826 | .platform = "ppc405", | ||
| 767 | }, | 827 | }, |
| 768 | { /* NP405L */ | 828 | { /* NP405L */ |
| 769 | .pvr_mask = 0xffff0000, | 829 | .pvr_mask = 0xffff0000, |
| @@ -774,6 +834,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 774 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 834 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
| 775 | .icache_bsize = 32, | 835 | .icache_bsize = 32, |
| 776 | .dcache_bsize = 32, | 836 | .dcache_bsize = 32, |
| 837 | .platform = "ppc405", | ||
| 777 | }, | 838 | }, |
| 778 | { /* NP4GS3 */ | 839 | { /* NP4GS3 */ |
| 779 | .pvr_mask = 0xffff0000, | 840 | .pvr_mask = 0xffff0000, |
| @@ -784,6 +845,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 784 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 845 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
| 785 | .icache_bsize = 32, | 846 | .icache_bsize = 32, |
| 786 | .dcache_bsize = 32, | 847 | .dcache_bsize = 32, |
| 848 | .platform = "ppc405", | ||
| 787 | }, | 849 | }, |
| 788 | { /* NP405H */ | 850 | { /* NP405H */ |
| 789 | .pvr_mask = 0xffff0000, | 851 | .pvr_mask = 0xffff0000, |
| @@ -794,6 +856,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 794 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 856 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
| 795 | .icache_bsize = 32, | 857 | .icache_bsize = 32, |
| 796 | .dcache_bsize = 32, | 858 | .dcache_bsize = 32, |
| 859 | .platform = "ppc405", | ||
| 797 | }, | 860 | }, |
| 798 | { /* 405GPr */ | 861 | { /* 405GPr */ |
| 799 | .pvr_mask = 0xffff0000, | 862 | .pvr_mask = 0xffff0000, |
| @@ -804,6 +867,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 804 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 867 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
| 805 | .icache_bsize = 32, | 868 | .icache_bsize = 32, |
| 806 | .dcache_bsize = 32, | 869 | .dcache_bsize = 32, |
| 870 | .platform = "ppc405", | ||
| 807 | }, | 871 | }, |
| 808 | { /* STBx25xx */ | 872 | { /* STBx25xx */ |
| 809 | .pvr_mask = 0xffff0000, | 873 | .pvr_mask = 0xffff0000, |
| @@ -814,6 +878,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 814 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 878 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
| 815 | .icache_bsize = 32, | 879 | .icache_bsize = 32, |
| 816 | .dcache_bsize = 32, | 880 | .dcache_bsize = 32, |
| 881 | .platform = "ppc405", | ||
| 817 | }, | 882 | }, |
| 818 | { /* 405LP */ | 883 | { /* 405LP */ |
| 819 | .pvr_mask = 0xffff0000, | 884 | .pvr_mask = 0xffff0000, |
| @@ -823,6 +888,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 823 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, | 888 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, |
| 824 | .icache_bsize = 32, | 889 | .icache_bsize = 32, |
| 825 | .dcache_bsize = 32, | 890 | .dcache_bsize = 32, |
| 891 | .platform = "ppc405", | ||
| 826 | }, | 892 | }, |
| 827 | { /* Xilinx Virtex-II Pro */ | 893 | { /* Xilinx Virtex-II Pro */ |
| 828 | .pvr_mask = 0xffff0000, | 894 | .pvr_mask = 0xffff0000, |
| @@ -833,6 +899,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 833 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 899 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
| 834 | .icache_bsize = 32, | 900 | .icache_bsize = 32, |
| 835 | .dcache_bsize = 32, | 901 | .dcache_bsize = 32, |
| 902 | .platform = "ppc405", | ||
| 836 | }, | 903 | }, |
| 837 | { /* 405EP */ | 904 | { /* 405EP */ |
| 838 | .pvr_mask = 0xffff0000, | 905 | .pvr_mask = 0xffff0000, |
| @@ -843,6 +910,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 843 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 910 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
| 844 | .icache_bsize = 32, | 911 | .icache_bsize = 32, |
| 845 | .dcache_bsize = 32, | 912 | .dcache_bsize = 32, |
| 913 | .platform = "ppc405", | ||
| 846 | }, | 914 | }, |
| 847 | 915 | ||
| 848 | #endif /* CONFIG_40x */ | 916 | #endif /* CONFIG_40x */ |
| @@ -852,81 +920,90 @@ struct cpu_spec cpu_specs[] = { | |||
| 852 | .pvr_value = 0x40000850, | 920 | .pvr_value = 0x40000850, |
| 853 | .cpu_name = "440EP Rev. A", | 921 | .cpu_name = "440EP Rev. A", |
| 854 | .cpu_features = CPU_FTRS_44X, | 922 | .cpu_features = CPU_FTRS_44X, |
| 855 | .cpu_user_features = COMMON_USER, /* 440EP has an FPU */ | 923 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, |
| 856 | .icache_bsize = 32, | 924 | .icache_bsize = 32, |
| 857 | .dcache_bsize = 32, | 925 | .dcache_bsize = 32, |
| 926 | .platform = "ppc440", | ||
| 858 | }, | 927 | }, |
| 859 | { | 928 | { |
| 860 | .pvr_mask = 0xf0000fff, | 929 | .pvr_mask = 0xf0000fff, |
| 861 | .pvr_value = 0x400008d3, | 930 | .pvr_value = 0x400008d3, |
| 862 | .cpu_name = "440EP Rev. B", | 931 | .cpu_name = "440EP Rev. B", |
| 863 | .cpu_features = CPU_FTRS_44X, | 932 | .cpu_features = CPU_FTRS_44X, |
| 864 | .cpu_user_features = COMMON_USER, /* 440EP has an FPU */ | 933 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, |
| 865 | .icache_bsize = 32, | 934 | .icache_bsize = 32, |
| 866 | .dcache_bsize = 32, | 935 | .dcache_bsize = 32, |
| 936 | .platform = "ppc440", | ||
| 867 | }, | 937 | }, |
| 868 | { /* 440GP Rev. B */ | 938 | { /* 440GP Rev. B */ |
| 869 | .pvr_mask = 0xf0000fff, | 939 | .pvr_mask = 0xf0000fff, |
| 870 | .pvr_value = 0x40000440, | 940 | .pvr_value = 0x40000440, |
| 871 | .cpu_name = "440GP Rev. B", | 941 | .cpu_name = "440GP Rev. B", |
| 872 | .cpu_features = CPU_FTRS_44X, | 942 | .cpu_features = CPU_FTRS_44X, |
| 873 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, | 943 | .cpu_user_features = COMMON_USER_BOOKE, |
| 874 | .icache_bsize = 32, | 944 | .icache_bsize = 32, |
| 875 | .dcache_bsize = 32, | 945 | .dcache_bsize = 32, |
| 946 | .platform = "ppc440gp", | ||
| 876 | }, | 947 | }, |
| 877 | { /* 440GP Rev. C */ | 948 | { /* 440GP Rev. C */ |
| 878 | .pvr_mask = 0xf0000fff, | 949 | .pvr_mask = 0xf0000fff, |
| 879 | .pvr_value = 0x40000481, | 950 | .pvr_value = 0x40000481, |
| 880 | .cpu_name = "440GP Rev. C", | 951 | .cpu_name = "440GP Rev. C", |
| 881 | .cpu_features = CPU_FTRS_44X, | 952 | .cpu_features = CPU_FTRS_44X, |
| 882 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, | 953 | .cpu_user_features = COMMON_USER_BOOKE, |
| 883 | .icache_bsize = 32, | 954 | .icache_bsize = 32, |
| 884 | .dcache_bsize = 32, | 955 | .dcache_bsize = 32, |
| 956 | .platform = "ppc440gp", | ||
| 885 | }, | 957 | }, |
| 886 | { /* 440GX Rev. A */ | 958 | { /* 440GX Rev. A */ |
| 887 | .pvr_mask = 0xf0000fff, | 959 | .pvr_mask = 0xf0000fff, |
| 888 | .pvr_value = 0x50000850, | 960 | .pvr_value = 0x50000850, |
| 889 | .cpu_name = "440GX Rev. A", | 961 | .cpu_name = "440GX Rev. A", |
| 890 | .cpu_features = CPU_FTRS_44X, | 962 | .cpu_features = CPU_FTRS_44X, |
| 891 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, | 963 | .cpu_user_features = COMMON_USER_BOOKE, |
| 892 | .icache_bsize = 32, | 964 | .icache_bsize = 32, |
| 893 | .dcache_bsize = 32, | 965 | .dcache_bsize = 32, |
| 966 | .platform = "ppc440", | ||
| 894 | }, | 967 | }, |
| 895 | { /* 440GX Rev. B */ | 968 | { /* 440GX Rev. B */ |
| 896 | .pvr_mask = 0xf0000fff, | 969 | .pvr_mask = 0xf0000fff, |
| 897 | .pvr_value = 0x50000851, | 970 | .pvr_value = 0x50000851, |
| 898 | .cpu_name = "440GX Rev. B", | 971 | .cpu_name = "440GX Rev. B", |
| 899 | .cpu_features = CPU_FTRS_44X, | 972 | .cpu_features = CPU_FTRS_44X, |
| 900 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, | 973 | .cpu_user_features = COMMON_USER_BOOKE, |
| 901 | .icache_bsize = 32, | 974 | .icache_bsize = 32, |
| 902 | .dcache_bsize = 32, | 975 | .dcache_bsize = 32, |
| 976 | .platform = "ppc440", | ||
| 903 | }, | 977 | }, |
| 904 | { /* 440GX Rev. C */ | 978 | { /* 440GX Rev. C */ |
| 905 | .pvr_mask = 0xf0000fff, | 979 | .pvr_mask = 0xf0000fff, |
| 906 | .pvr_value = 0x50000892, | 980 | .pvr_value = 0x50000892, |
| 907 | .cpu_name = "440GX Rev. C", | 981 | .cpu_name = "440GX Rev. C", |
| 908 | .cpu_features = CPU_FTRS_44X, | 982 | .cpu_features = CPU_FTRS_44X, |
| 909 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, | 983 | .cpu_user_features = COMMON_USER_BOOKE, |
| 910 | .icache_bsize = 32, | 984 | .icache_bsize = 32, |
| 911 | .dcache_bsize = 32, | 985 | .dcache_bsize = 32, |
| 986 | .platform = "ppc440", | ||
| 912 | }, | 987 | }, |
| 913 | { /* 440GX Rev. F */ | 988 | { /* 440GX Rev. F */ |
| 914 | .pvr_mask = 0xf0000fff, | 989 | .pvr_mask = 0xf0000fff, |
| 915 | .pvr_value = 0x50000894, | 990 | .pvr_value = 0x50000894, |
| 916 | .cpu_name = "440GX Rev. F", | 991 | .cpu_name = "440GX Rev. F", |
| 917 | .cpu_features = CPU_FTRS_44X, | 992 | .cpu_features = CPU_FTRS_44X, |
| 918 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, | 993 | .cpu_user_features = COMMON_USER_BOOKE, |
| 919 | .icache_bsize = 32, | 994 | .icache_bsize = 32, |
| 920 | .dcache_bsize = 32, | 995 | .dcache_bsize = 32, |
| 996 | .platform = "ppc440", | ||
| 921 | }, | 997 | }, |
| 922 | { /* 440SP Rev. A */ | 998 | { /* 440SP Rev. A */ |
| 923 | .pvr_mask = 0xff000fff, | 999 | .pvr_mask = 0xff000fff, |
| 924 | .pvr_value = 0x53000891, | 1000 | .pvr_value = 0x53000891, |
| 925 | .cpu_name = "440SP Rev. A", | 1001 | .cpu_name = "440SP Rev. A", |
| 926 | .cpu_features = CPU_FTRS_44X, | 1002 | .cpu_features = CPU_FTRS_44X, |
| 927 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, | 1003 | .cpu_user_features = COMMON_USER_BOOKE, |
| 928 | .icache_bsize = 32, | 1004 | .icache_bsize = 32, |
| 929 | .dcache_bsize = 32, | 1005 | .dcache_bsize = 32, |
| 1006 | .platform = "ppc440", | ||
| 930 | }, | 1007 | }, |
| 931 | { /* 440SPe Rev. A */ | 1008 | { /* 440SPe Rev. A */ |
| 932 | .pvr_mask = 0xff000fff, | 1009 | .pvr_mask = 0xff000fff, |
| @@ -934,9 +1011,10 @@ struct cpu_spec cpu_specs[] = { | |||
| 934 | .cpu_name = "440SPe Rev. A", | 1011 | .cpu_name = "440SPe Rev. A", |
| 935 | .cpu_features = CPU_FTR_SPLIT_ID_CACHE | | 1012 | .cpu_features = CPU_FTR_SPLIT_ID_CACHE | |
| 936 | CPU_FTR_USE_TB, | 1013 | CPU_FTR_USE_TB, |
| 937 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, | 1014 | .cpu_user_features = COMMON_USER_BOOKE, |
| 938 | .icache_bsize = 32, | 1015 | .icache_bsize = 32, |
| 939 | .dcache_bsize = 32, | 1016 | .dcache_bsize = 32, |
| 1017 | .platform = "ppc440", | ||
| 940 | }, | 1018 | }, |
| 941 | #endif /* CONFIG_44x */ | 1019 | #endif /* CONFIG_44x */ |
| 942 | #ifdef CONFIG_FSL_BOOKE | 1020 | #ifdef CONFIG_FSL_BOOKE |
| @@ -946,10 +1024,11 @@ struct cpu_spec cpu_specs[] = { | |||
| 946 | .cpu_name = "e200z5", | 1024 | .cpu_name = "e200z5", |
| 947 | /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ | 1025 | /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ |
| 948 | .cpu_features = CPU_FTRS_E200, | 1026 | .cpu_features = CPU_FTRS_E200, |
| 949 | .cpu_user_features = PPC_FEATURE_32 | | 1027 | .cpu_user_features = COMMON_USER_BOOKE | |
| 950 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_EFP_SINGLE | | 1028 | PPC_FEATURE_HAS_EFP_SINGLE | |
| 951 | PPC_FEATURE_UNIFIED_CACHE, | 1029 | PPC_FEATURE_UNIFIED_CACHE, |
| 952 | .dcache_bsize = 32, | 1030 | .dcache_bsize = 32, |
| 1031 | .platform = "ppc5554", | ||
| 953 | }, | 1032 | }, |
| 954 | { /* e200z6 */ | 1033 | { /* e200z6 */ |
| 955 | .pvr_mask = 0xfff00000, | 1034 | .pvr_mask = 0xfff00000, |
| @@ -957,11 +1036,12 @@ struct cpu_spec cpu_specs[] = { | |||
| 957 | .cpu_name = "e200z6", | 1036 | .cpu_name = "e200z6", |
| 958 | /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ | 1037 | /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ |
| 959 | .cpu_features = CPU_FTRS_E200, | 1038 | .cpu_features = CPU_FTRS_E200, |
| 960 | .cpu_user_features = PPC_FEATURE_32 | | 1039 | .cpu_user_features = COMMON_USER_BOOKE | |
| 961 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP | | 1040 | PPC_FEATURE_SPE_COMP | |
| 962 | PPC_FEATURE_HAS_EFP_SINGLE | | 1041 | PPC_FEATURE_HAS_EFP_SINGLE | |
| 963 | PPC_FEATURE_UNIFIED_CACHE, | 1042 | PPC_FEATURE_UNIFIED_CACHE, |
| 964 | .dcache_bsize = 32, | 1043 | .dcache_bsize = 32, |
| 1044 | .platform = "ppc5554", | ||
| 965 | }, | 1045 | }, |
| 966 | { /* e500 */ | 1046 | { /* e500 */ |
| 967 | .pvr_mask = 0xffff0000, | 1047 | .pvr_mask = 0xffff0000, |
| @@ -969,14 +1049,15 @@ struct cpu_spec cpu_specs[] = { | |||
| 969 | .cpu_name = "e500", | 1049 | .cpu_name = "e500", |
| 970 | /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ | 1050 | /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ |
| 971 | .cpu_features = CPU_FTRS_E500, | 1051 | .cpu_features = CPU_FTRS_E500, |
| 972 | .cpu_user_features = PPC_FEATURE_32 | | 1052 | .cpu_user_features = COMMON_USER_BOOKE | |
| 973 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP | | 1053 | PPC_FEATURE_SPE_COMP | |
| 974 | PPC_FEATURE_HAS_EFP_SINGLE, | 1054 | PPC_FEATURE_HAS_EFP_SINGLE, |
| 975 | .icache_bsize = 32, | 1055 | .icache_bsize = 32, |
| 976 | .dcache_bsize = 32, | 1056 | .dcache_bsize = 32, |
| 977 | .num_pmcs = 4, | 1057 | .num_pmcs = 4, |
| 978 | .oprofile_cpu_type = "ppc/e500", | 1058 | .oprofile_cpu_type = "ppc/e500", |
| 979 | .oprofile_type = BOOKE, | 1059 | .oprofile_type = PPC_OPROFILE_BOOKE, |
| 1060 | .platform = "ppc8540", | ||
| 980 | }, | 1061 | }, |
| 981 | { /* e500v2 */ | 1062 | { /* e500v2 */ |
| 982 | .pvr_mask = 0xffff0000, | 1063 | .pvr_mask = 0xffff0000, |
| @@ -984,14 +1065,16 @@ struct cpu_spec cpu_specs[] = { | |||
| 984 | .cpu_name = "e500v2", | 1065 | .cpu_name = "e500v2", |
| 985 | /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ | 1066 | /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ |
| 986 | .cpu_features = CPU_FTRS_E500_2, | 1067 | .cpu_features = CPU_FTRS_E500_2, |
| 987 | .cpu_user_features = PPC_FEATURE_32 | | 1068 | .cpu_user_features = COMMON_USER_BOOKE | |
| 988 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP | | 1069 | PPC_FEATURE_SPE_COMP | |
| 989 | PPC_FEATURE_HAS_EFP_SINGLE | PPC_FEATURE_HAS_EFP_DOUBLE, | 1070 | PPC_FEATURE_HAS_EFP_SINGLE | |
| 1071 | PPC_FEATURE_HAS_EFP_DOUBLE, | ||
| 990 | .icache_bsize = 32, | 1072 | .icache_bsize = 32, |
| 991 | .dcache_bsize = 32, | 1073 | .dcache_bsize = 32, |
| 992 | .num_pmcs = 4, | 1074 | .num_pmcs = 4, |
| 993 | .oprofile_cpu_type = "ppc/e500", | 1075 | .oprofile_cpu_type = "ppc/e500", |
| 994 | .oprofile_type = BOOKE, | 1076 | .oprofile_type = PPC_OPROFILE_BOOKE, |
| 1077 | .platform = "ppc8548", | ||
| 995 | }, | 1078 | }, |
| 996 | #endif | 1079 | #endif |
| 997 | #if !CLASSIC_PPC | 1080 | #if !CLASSIC_PPC |
| @@ -1003,6 +1086,7 @@ struct cpu_spec cpu_specs[] = { | |||
| 1003 | .cpu_user_features = PPC_FEATURE_32, | 1086 | .cpu_user_features = PPC_FEATURE_32, |
| 1004 | .icache_bsize = 32, | 1087 | .icache_bsize = 32, |
| 1005 | .dcache_bsize = 32, | 1088 | .dcache_bsize = 32, |
| 1089 | .platform = "powerpc", | ||
| 1006 | } | 1090 | } |
| 1007 | #endif /* !CLASSIC_PPC */ | 1091 | #endif /* !CLASSIC_PPC */ |
| 1008 | #endif /* CONFIG_PPC32 */ | 1092 | #endif /* CONFIG_PPC32 */ |
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 5f248e3fdf82..8c21d378f5d2 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c | |||
| @@ -84,7 +84,10 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu) | |||
| 84 | * squirrelled away. ELF notes happen to provide | 84 | * squirrelled away. ELF notes happen to provide |
| 85 | * all of that that no need to invent something new. | 85 | * all of that that no need to invent something new. |
| 86 | */ | 86 | */ |
| 87 | buf = &crash_notes[cpu][0]; | 87 | buf = (u32*)per_cpu_ptr(crash_notes, cpu); |
| 88 | if (!buf) | ||
| 89 | return; | ||
| 90 | |||
| 88 | memset(&prstatus, 0, sizeof(prstatus)); | 91 | memset(&prstatus, 0, sizeof(prstatus)); |
| 89 | prstatus.pr_pid = current->pid; | 92 | prstatus.pr_pid = current->pid; |
| 90 | elf_core_copy_regs(&prstatus.pr_reg, regs); | 93 | elf_core_copy_regs(&prstatus.pr_reg, regs); |
| @@ -93,76 +96,6 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu) | |||
| 93 | final_note(buf); | 96 | final_note(buf); |
| 94 | } | 97 | } |
| 95 | 98 | ||
| 96 | /* FIXME Merge this with xmon_save_regs ?? */ | ||
| 97 | static inline void crash_get_current_regs(struct pt_regs *regs) | ||
| 98 | { | ||
| 99 | unsigned long tmp1, tmp2; | ||
| 100 | |||
| 101 | __asm__ __volatile__ ( | ||
| 102 | "std 0,0(%2)\n" | ||
| 103 | "std 1,8(%2)\n" | ||
| 104 | "std 2,16(%2)\n" | ||
| 105 | "std 3,24(%2)\n" | ||
| 106 | "std 4,32(%2)\n" | ||
| 107 | "std 5,40(%2)\n" | ||
| 108 | "std 6,48(%2)\n" | ||
| 109 | "std 7,56(%2)\n" | ||
| 110 | "std 8,64(%2)\n" | ||
| 111 | "std 9,72(%2)\n" | ||
| 112 | "std 10,80(%2)\n" | ||
| 113 | "std 11,88(%2)\n" | ||
| 114 | "std 12,96(%2)\n" | ||
| 115 | "std 13,104(%2)\n" | ||
| 116 | "std 14,112(%2)\n" | ||
| 117 | "std 15,120(%2)\n" | ||
| 118 | "std 16,128(%2)\n" | ||
| 119 | "std 17,136(%2)\n" | ||
| 120 | "std 18,144(%2)\n" | ||
| 121 | "std 19,152(%2)\n" | ||
| 122 | "std 20,160(%2)\n" | ||
| 123 | "std 21,168(%2)\n" | ||
| 124 | "std 22,176(%2)\n" | ||
| 125 | "std 23,184(%2)\n" | ||
| 126 | "std 24,192(%2)\n" | ||
| 127 | "std 25,200(%2)\n" | ||
| 128 | "std 26,208(%2)\n" | ||
| 129 | "std 27,216(%2)\n" | ||
| 130 | "std 28,224(%2)\n" | ||
| 131 | "std 29,232(%2)\n" | ||
| 132 | "std 30,240(%2)\n" | ||
| 133 | "std 31,248(%2)\n" | ||
| 134 | "mfmsr %0\n" | ||
| 135 | "std %0, 264(%2)\n" | ||
| 136 | "mfctr %0\n" | ||
| 137 | "std %0, 280(%2)\n" | ||
| 138 | "mflr %0\n" | ||
| 139 | "std %0, 288(%2)\n" | ||
| 140 | "bl 1f\n" | ||
| 141 | "1: mflr %1\n" | ||
| 142 | "std %1, 256(%2)\n" | ||
| 143 | "mtlr %0\n" | ||
| 144 | "mfxer %0\n" | ||
| 145 | "std %0, 296(%2)\n" | ||
| 146 | : "=&r" (tmp1), "=&r" (tmp2) | ||
| 147 | : "b" (regs)); | ||
| 148 | } | ||
| 149 | |||
| 150 | /* We may have saved_regs from where the error came from | ||
| 151 | * or it is NULL if via a direct panic(). | ||
| 152 | */ | ||
| 153 | static void crash_save_self(struct pt_regs *saved_regs) | ||
| 154 | { | ||
| 155 | struct pt_regs regs; | ||
| 156 | int cpu; | ||
| 157 | |||
| 158 | cpu = smp_processor_id(); | ||
| 159 | if (saved_regs) | ||
| 160 | memcpy(®s, saved_regs, sizeof(regs)); | ||
| 161 | else | ||
| 162 | crash_get_current_regs(®s); | ||
| 163 | crash_save_this_cpu(®s, cpu); | ||
| 164 | } | ||
| 165 | |||
| 166 | #ifdef CONFIG_SMP | 99 | #ifdef CONFIG_SMP |
| 167 | static atomic_t waiting_for_crash_ipi; | 100 | static atomic_t waiting_for_crash_ipi; |
| 168 | 101 | ||
| @@ -260,5 +193,5 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
| 260 | */ | 193 | */ |
| 261 | crashing_cpu = smp_processor_id(); | 194 | crashing_cpu = smp_processor_id(); |
| 262 | crash_kexec_prepare_cpus(); | 195 | crash_kexec_prepare_cpus(); |
| 263 | crash_save_self(regs); | 196 | crash_save_this_cpu(regs, crashing_cpu); |
| 264 | } | 197 | } |
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 036b71d2adfc..d8da2a35c0a4 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S | |||
| @@ -988,7 +988,7 @@ _GLOBAL(enter_rtas) | |||
| 988 | stwu r1,-INT_FRAME_SIZE(r1) | 988 | stwu r1,-INT_FRAME_SIZE(r1) |
| 989 | mflr r0 | 989 | mflr r0 |
| 990 | stw r0,INT_FRAME_SIZE+4(r1) | 990 | stw r0,INT_FRAME_SIZE+4(r1) |
| 991 | LOADADDR(r4, rtas) | 991 | LOAD_REG_ADDR(r4, rtas) |
| 992 | lis r6,1f@ha /* physical return address for rtas */ | 992 | lis r6,1f@ha /* physical return address for rtas */ |
| 993 | addi r6,r6,1f@l | 993 | addi r6,r6,1f@l |
| 994 | tophys(r6,r6) | 994 | tophys(r6,r6) |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index aacebb33e98a..542036318866 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
| @@ -511,7 +511,8 @@ restore: | |||
| 511 | cmpdi 0,r5,0 | 511 | cmpdi 0,r5,0 |
| 512 | beq 4f | 512 | beq 4f |
| 513 | /* Check for pending interrupts (iSeries) */ | 513 | /* Check for pending interrupts (iSeries) */ |
| 514 | ld r3,PACALPPACA+LPPACAANYINT(r13) | 514 | ld r3,PACALPPACAPTR(r13) |
| 515 | ld r3,LPPACAANYINT(r3) | ||
| 515 | cmpdi r3,0 | 516 | cmpdi r3,0 |
| 516 | beq+ 4f /* skip do_IRQ if no interrupts */ | 517 | beq+ 4f /* skip do_IRQ if no interrupts */ |
| 517 | 518 | ||
| @@ -689,9 +690,8 @@ _GLOBAL(enter_rtas) | |||
| 689 | std r6,PACASAVEDMSR(r13) | 690 | std r6,PACASAVEDMSR(r13) |
| 690 | 691 | ||
| 691 | /* Setup our real return addr */ | 692 | /* Setup our real return addr */ |
| 692 | SET_REG_TO_LABEL(r4,.rtas_return_loc) | 693 | LOAD_REG_ADDR(r4,.rtas_return_loc) |
| 693 | SET_REG_TO_CONST(r9,PAGE_OFFSET) | 694 | clrldi r4,r4,2 /* convert to realmode address */ |
| 694 | sub r4,r4,r9 | ||
| 695 | mtlr r4 | 695 | mtlr r4 |
| 696 | 696 | ||
| 697 | li r0,0 | 697 | li r0,0 |
| @@ -706,7 +706,7 @@ _GLOBAL(enter_rtas) | |||
| 706 | sync /* disable interrupts so SRR0/1 */ | 706 | sync /* disable interrupts so SRR0/1 */ |
| 707 | mtmsrd r0 /* don't get trashed */ | 707 | mtmsrd r0 /* don't get trashed */ |
| 708 | 708 | ||
| 709 | SET_REG_TO_LABEL(r4,rtas) | 709 | LOAD_REG_ADDR(r4, rtas) |
| 710 | ld r5,RTASENTRY(r4) /* get the rtas->entry value */ | 710 | ld r5,RTASENTRY(r4) /* get the rtas->entry value */ |
| 711 | ld r4,RTASBASE(r4) /* get the rtas->base value */ | 711 | ld r4,RTASBASE(r4) /* get the rtas->base value */ |
| 712 | 712 | ||
| @@ -718,8 +718,7 @@ _GLOBAL(enter_rtas) | |||
| 718 | _STATIC(rtas_return_loc) | 718 | _STATIC(rtas_return_loc) |
| 719 | /* relocation is off at this point */ | 719 | /* relocation is off at this point */ |
| 720 | mfspr r4,SPRN_SPRG3 /* Get PACA */ | 720 | mfspr r4,SPRN_SPRG3 /* Get PACA */ |
| 721 | SET_REG_TO_CONST(r5, PAGE_OFFSET) | 721 | clrldi r4,r4,2 /* convert to realmode address */ |
| 722 | sub r4,r4,r5 /* RELOC the PACA base pointer */ | ||
| 723 | 722 | ||
| 724 | mfmsr r6 | 723 | mfmsr r6 |
| 725 | li r0,MSR_RI | 724 | li r0,MSR_RI |
| @@ -728,7 +727,7 @@ _STATIC(rtas_return_loc) | |||
| 728 | mtmsrd r6 | 727 | mtmsrd r6 |
| 729 | 728 | ||
| 730 | ld r1,PACAR1(r4) /* Restore our SP */ | 729 | ld r1,PACAR1(r4) /* Restore our SP */ |
| 731 | LOADADDR(r3,.rtas_restore_regs) | 730 | LOAD_REG_IMMEDIATE(r3,.rtas_restore_regs) |
| 732 | ld r4,PACASAVEDMSR(r4) /* Restore our MSR */ | 731 | ld r4,PACASAVEDMSR(r4) /* Restore our MSR */ |
| 733 | 732 | ||
| 734 | mtspr SPRN_SRR0,r3 | 733 | mtspr SPRN_SRR0,r3 |
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index b780b42c95fc..e4362dfa37fb 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S | |||
| @@ -39,9 +39,9 @@ _GLOBAL(load_up_fpu) | |||
| 39 | * to another. Instead we call giveup_fpu in switch_to. | 39 | * to another. Instead we call giveup_fpu in switch_to. |
| 40 | */ | 40 | */ |
| 41 | #ifndef CONFIG_SMP | 41 | #ifndef CONFIG_SMP |
| 42 | LOADBASE(r3, last_task_used_math) | 42 | LOAD_REG_ADDRBASE(r3, last_task_used_math) |
| 43 | toreal(r3) | 43 | toreal(r3) |
| 44 | PPC_LL r4,OFF(last_task_used_math)(r3) | 44 | PPC_LL r4,ADDROFF(last_task_used_math)(r3) |
| 45 | PPC_LCMPI 0,r4,0 | 45 | PPC_LCMPI 0,r4,0 |
| 46 | beq 1f | 46 | beq 1f |
| 47 | toreal(r4) | 47 | toreal(r4) |
| @@ -77,7 +77,7 @@ _GLOBAL(load_up_fpu) | |||
| 77 | #ifndef CONFIG_SMP | 77 | #ifndef CONFIG_SMP |
| 78 | subi r4,r5,THREAD | 78 | subi r4,r5,THREAD |
| 79 | fromreal(r4) | 79 | fromreal(r4) |
| 80 | PPC_STL r4,OFF(last_task_used_math)(r3) | 80 | PPC_STL r4,ADDROFF(last_task_used_math)(r3) |
| 81 | #endif /* CONFIG_SMP */ | 81 | #endif /* CONFIG_SMP */ |
| 82 | /* restore registers and return */ | 82 | /* restore registers and return */ |
| 83 | /* we haven't used ctr or xer or lr */ | 83 | /* we haven't used ctr or xer or lr */ |
| @@ -113,8 +113,8 @@ _GLOBAL(giveup_fpu) | |||
| 113 | 1: | 113 | 1: |
| 114 | #ifndef CONFIG_SMP | 114 | #ifndef CONFIG_SMP |
| 115 | li r5,0 | 115 | li r5,0 |
| 116 | LOADBASE(r4,last_task_used_math) | 116 | LOAD_REG_ADDRBASE(r4,last_task_used_math) |
| 117 | PPC_STL r5,OFF(last_task_used_math)(r4) | 117 | PPC_STL r5,ADDROFF(last_task_used_math)(r4) |
| 118 | #endif /* CONFIG_SMP */ | 118 | #endif /* CONFIG_SMP */ |
| 119 | blr | 119 | blr |
| 120 | 120 | ||
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 1c066d125375..308268466342 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
| @@ -154,12 +154,12 @@ _GLOBAL(__secondary_hold) | |||
| 154 | bne 100b | 154 | bne 100b |
| 155 | 155 | ||
| 156 | #ifdef CONFIG_HMT | 156 | #ifdef CONFIG_HMT |
| 157 | LOADADDR(r4, .hmt_init) | 157 | SET_REG_IMMEDIATE(r4, .hmt_init) |
| 158 | mtctr r4 | 158 | mtctr r4 |
| 159 | bctr | 159 | bctr |
| 160 | #else | 160 | #else |
| 161 | #ifdef CONFIG_SMP | 161 | #ifdef CONFIG_SMP |
| 162 | LOADADDR(r4, .pSeries_secondary_smp_init) | 162 | LOAD_REG_IMMEDIATE(r4, .pSeries_secondary_smp_init) |
| 163 | mtctr r4 | 163 | mtctr r4 |
| 164 | mr r3,r24 | 164 | mr r3,r24 |
| 165 | bctr | 165 | bctr |
| @@ -205,9 +205,10 @@ exception_marker: | |||
| 205 | #define EX_LR 72 | 205 | #define EX_LR 72 |
| 206 | 206 | ||
| 207 | /* | 207 | /* |
| 208 | * We're short on space and time in the exception prolog, so we can't use | 208 | * We're short on space and time in the exception prolog, so we can't |
| 209 | * the normal LOADADDR macro. Normally we just need the low halfword of the | 209 | * use the normal SET_REG_IMMEDIATE macro. Normally we just need the |
| 210 | * address, but for Kdump we need the whole low word. | 210 | * low halfword of the address, but for Kdump we need the whole low |
| 211 | * word. | ||
| 211 | */ | 212 | */ |
| 212 | #ifdef CONFIG_CRASH_DUMP | 213 | #ifdef CONFIG_CRASH_DUMP |
| 213 | #define LOAD_HANDLER(reg, label) \ | 214 | #define LOAD_HANDLER(reg, label) \ |
| @@ -254,8 +255,9 @@ exception_marker: | |||
| 254 | 255 | ||
| 255 | #define EXCEPTION_PROLOG_ISERIES_2 \ | 256 | #define EXCEPTION_PROLOG_ISERIES_2 \ |
| 256 | mfmsr r10; \ | 257 | mfmsr r10; \ |
| 257 | ld r11,PACALPPACA+LPPACASRR0(r13); \ | 258 | ld r12,PACALPPACAPTR(r13); \ |
| 258 | ld r12,PACALPPACA+LPPACASRR1(r13); \ | 259 | ld r11,LPPACASRR0(r12); \ |
| 260 | ld r12,LPPACASRR1(r12); \ | ||
| 259 | ori r10,r10,MSR_RI; \ | 261 | ori r10,r10,MSR_RI; \ |
| 260 | mtmsrd r10,1 | 262 | mtmsrd r10,1 |
| 261 | 263 | ||
| @@ -634,7 +636,8 @@ data_access_slb_iSeries: | |||
| 634 | std r12,PACA_EXSLB+EX_R12(r13) | 636 | std r12,PACA_EXSLB+EX_R12(r13) |
| 635 | mfspr r10,SPRN_SPRG1 | 637 | mfspr r10,SPRN_SPRG1 |
| 636 | std r10,PACA_EXSLB+EX_R13(r13) | 638 | std r10,PACA_EXSLB+EX_R13(r13) |
| 637 | ld r12,PACALPPACA+LPPACASRR1(r13); | 639 | ld r12,PACALPPACAPTR(r13) |
| 640 | ld r12,LPPACASRR1(r12) | ||
| 638 | b .slb_miss_realmode | 641 | b .slb_miss_realmode |
| 639 | 642 | ||
| 640 | STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN) | 643 | STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN) |
| @@ -644,7 +647,8 @@ instruction_access_slb_iSeries: | |||
| 644 | mtspr SPRN_SPRG1,r13 /* save r13 */ | 647 | mtspr SPRN_SPRG1,r13 /* save r13 */ |
| 645 | mfspr r13,SPRN_SPRG3 /* get paca address into r13 */ | 648 | mfspr r13,SPRN_SPRG3 /* get paca address into r13 */ |
| 646 | std r3,PACA_EXSLB+EX_R3(r13) | 649 | std r3,PACA_EXSLB+EX_R3(r13) |
| 647 | ld r3,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */ | 650 | ld r3,PACALPPACAPTR(r13) |
| 651 | ld r3,LPPACASRR0(r3) /* get SRR0 value */ | ||
| 648 | std r9,PACA_EXSLB+EX_R9(r13) | 652 | std r9,PACA_EXSLB+EX_R9(r13) |
| 649 | mfcr r9 | 653 | mfcr r9 |
| 650 | #ifdef __DISABLED__ | 654 | #ifdef __DISABLED__ |
| @@ -656,7 +660,8 @@ instruction_access_slb_iSeries: | |||
| 656 | std r12,PACA_EXSLB+EX_R12(r13) | 660 | std r12,PACA_EXSLB+EX_R12(r13) |
| 657 | mfspr r10,SPRN_SPRG1 | 661 | mfspr r10,SPRN_SPRG1 |
| 658 | std r10,PACA_EXSLB+EX_R13(r13) | 662 | std r10,PACA_EXSLB+EX_R13(r13) |
| 659 | ld r12,PACALPPACA+LPPACASRR1(r13); | 663 | ld r12,PACALPPACAPTR(r13) |
| 664 | ld r12,LPPACASRR1(r12) | ||
| 660 | b .slb_miss_realmode | 665 | b .slb_miss_realmode |
| 661 | 666 | ||
| 662 | #ifdef __DISABLED__ | 667 | #ifdef __DISABLED__ |
| @@ -713,7 +718,7 @@ system_reset_iSeries: | |||
| 713 | lbz r23,PACAPROCSTART(r13) /* Test if this processor | 718 | lbz r23,PACAPROCSTART(r13) /* Test if this processor |
| 714 | * should start */ | 719 | * should start */ |
| 715 | sync | 720 | sync |
| 716 | LOADADDR(r3,current_set) | 721 | LOAD_REG_IMMEDIATE(r3,current_set) |
| 717 | sldi r28,r24,3 /* get current_set[cpu#] */ | 722 | sldi r28,r24,3 /* get current_set[cpu#] */ |
| 718 | ldx r3,r3,r28 | 723 | ldx r3,r3,r28 |
| 719 | addi r1,r3,THREAD_SIZE | 724 | addi r1,r3,THREAD_SIZE |
| @@ -745,17 +750,19 @@ iSeries_secondary_smp_loop: | |||
| 745 | .globl decrementer_iSeries_masked | 750 | .globl decrementer_iSeries_masked |
| 746 | decrementer_iSeries_masked: | 751 | decrementer_iSeries_masked: |
| 747 | li r11,1 | 752 | li r11,1 |
| 748 | stb r11,PACALPPACA+LPPACADECRINT(r13) | 753 | ld r12,PACALPPACAPTR(r13) |
| 749 | LOADBASE(r12,tb_ticks_per_jiffy) | 754 | stb r11,LPPACADECRINT(r12) |
| 750 | lwz r12,OFF(tb_ticks_per_jiffy)(r12) | 755 | LOAD_REG_ADDRBASE(r12,tb_ticks_per_jiffy) |
| 756 | lwz r12,ADDROFF(tb_ticks_per_jiffy)(r12) | ||
| 751 | mtspr SPRN_DEC,r12 | 757 | mtspr SPRN_DEC,r12 |
| 752 | /* fall through */ | 758 | /* fall through */ |
| 753 | 759 | ||
| 754 | .globl hardware_interrupt_iSeries_masked | 760 | .globl hardware_interrupt_iSeries_masked |
| 755 | hardware_interrupt_iSeries_masked: | 761 | hardware_interrupt_iSeries_masked: |
| 756 | mtcrf 0x80,r9 /* Restore regs */ | 762 | mtcrf 0x80,r9 /* Restore regs */ |
| 757 | ld r11,PACALPPACA+LPPACASRR0(r13) | 763 | ld r12,PACALPPACAPTR(r13) |
| 758 | ld r12,PACALPPACA+LPPACASRR1(r13) | 764 | ld r11,LPPACASRR0(r12) |
| 765 | ld r12,LPPACASRR1(r12) | ||
| 759 | mtspr SPRN_SRR0,r11 | 766 | mtspr SPRN_SRR0,r11 |
| 760 | mtspr SPRN_SRR1,r12 | 767 | mtspr SPRN_SRR1,r12 |
| 761 | ld r9,PACA_EXGEN+EX_R9(r13) | 768 | ld r9,PACA_EXGEN+EX_R9(r13) |
| @@ -994,7 +1001,8 @@ _GLOBAL(slb_miss_realmode) | |||
| 994 | ld r3,PACA_EXSLB+EX_R3(r13) | 1001 | ld r3,PACA_EXSLB+EX_R3(r13) |
| 995 | lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */ | 1002 | lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */ |
| 996 | #ifdef CONFIG_PPC_ISERIES | 1003 | #ifdef CONFIG_PPC_ISERIES |
| 997 | ld r11,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */ | 1004 | ld r11,PACALPPACAPTR(r13) |
| 1005 | ld r11,LPPACASRR0(r11) /* get SRR0 value */ | ||
| 998 | #endif /* CONFIG_PPC_ISERIES */ | 1006 | #endif /* CONFIG_PPC_ISERIES */ |
| 999 | 1007 | ||
| 1000 | mtlr r10 | 1008 | mtlr r10 |
| @@ -1412,7 +1420,7 @@ _GLOBAL(pSeries_secondary_smp_init) | |||
| 1412 | * physical cpu id in r24, we need to search the pacas to find | 1420 | * physical cpu id in r24, we need to search the pacas to find |
| 1413 | * which logical id maps to our physical one. | 1421 | * which logical id maps to our physical one. |
| 1414 | */ | 1422 | */ |
| 1415 | LOADADDR(r13, paca) /* Get base vaddr of paca array */ | 1423 | LOAD_REG_IMMEDIATE(r13, paca) /* Get base vaddr of paca array */ |
| 1416 | li r5,0 /* logical cpu id */ | 1424 | li r5,0 /* logical cpu id */ |
| 1417 | 1: lhz r6,PACAHWCPUID(r13) /* Load HW procid from paca */ | 1425 | 1: lhz r6,PACAHWCPUID(r13) /* Load HW procid from paca */ |
| 1418 | cmpw r6,r24 /* Compare to our id */ | 1426 | cmpw r6,r24 /* Compare to our id */ |
| @@ -1446,8 +1454,8 @@ _GLOBAL(pSeries_secondary_smp_init) | |||
| 1446 | #ifdef CONFIG_PPC_ISERIES | 1454 | #ifdef CONFIG_PPC_ISERIES |
| 1447 | _STATIC(__start_initialization_iSeries) | 1455 | _STATIC(__start_initialization_iSeries) |
| 1448 | /* Clear out the BSS */ | 1456 | /* Clear out the BSS */ |
| 1449 | LOADADDR(r11,__bss_stop) | 1457 | LOAD_REG_IMMEDIATE(r11,__bss_stop) |
| 1450 | LOADADDR(r8,__bss_start) | 1458 | LOAD_REG_IMMEDIATE(r8,__bss_start) |
| 1451 | sub r11,r11,r8 /* bss size */ | 1459 | sub r11,r11,r8 /* bss size */ |
| 1452 | addi r11,r11,7 /* round up to an even double word */ | 1460 | addi r11,r11,7 /* round up to an even double word */ |
| 1453 | rldicl. r11,r11,61,3 /* shift right by 3 */ | 1461 | rldicl. r11,r11,61,3 /* shift right by 3 */ |
| @@ -1458,17 +1466,17 @@ _STATIC(__start_initialization_iSeries) | |||
| 1458 | 3: stdu r0,8(r8) | 1466 | 3: stdu r0,8(r8) |
| 1459 | bdnz 3b | 1467 | bdnz 3b |
| 1460 | 4: | 1468 | 4: |
| 1461 | LOADADDR(r1,init_thread_union) | 1469 | LOAD_REG_IMMEDIATE(r1,init_thread_union) |
| 1462 | addi r1,r1,THREAD_SIZE | 1470 | addi r1,r1,THREAD_SIZE |
| 1463 | li r0,0 | 1471 | li r0,0 |
| 1464 | stdu r0,-STACK_FRAME_OVERHEAD(r1) | 1472 | stdu r0,-STACK_FRAME_OVERHEAD(r1) |
| 1465 | 1473 | ||
| 1466 | LOADADDR(r3,cpu_specs) | 1474 | LOAD_REG_IMMEDIATE(r3,cpu_specs) |
| 1467 | LOADADDR(r4,cur_cpu_spec) | 1475 | LOAD_REG_IMMEDIATE(r4,cur_cpu_spec) |
| 1468 | li r5,0 | 1476 | li r5,0 |
| 1469 | bl .identify_cpu | 1477 | bl .identify_cpu |
| 1470 | 1478 | ||
| 1471 | LOADADDR(r2,__toc_start) | 1479 | LOAD_REG_IMMEDIATE(r2,__toc_start) |
| 1472 | addi r2,r2,0x4000 | 1480 | addi r2,r2,0x4000 |
| 1473 | addi r2,r2,0x4000 | 1481 | addi r2,r2,0x4000 |
| 1474 | 1482 | ||
| @@ -1528,7 +1536,7 @@ _GLOBAL(__start_initialization_multiplatform) | |||
| 1528 | li r24,0 | 1536 | li r24,0 |
| 1529 | 1537 | ||
| 1530 | /* Switch off MMU if not already */ | 1538 | /* Switch off MMU if not already */ |
| 1531 | LOADADDR(r4, .__after_prom_start - KERNELBASE) | 1539 | LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE) |
| 1532 | add r4,r4,r30 | 1540 | add r4,r4,r30 |
| 1533 | bl .__mmu_off | 1541 | bl .__mmu_off |
| 1534 | b .__after_prom_start | 1542 | b .__after_prom_start |
| @@ -1548,7 +1556,7 @@ _STATIC(__boot_from_prom) | |||
| 1548 | /* put a relocation offset into r3 */ | 1556 | /* put a relocation offset into r3 */ |
| 1549 | bl .reloc_offset | 1557 | bl .reloc_offset |
| 1550 | 1558 | ||
| 1551 | LOADADDR(r2,__toc_start) | 1559 | LOAD_REG_IMMEDIATE(r2,__toc_start) |
| 1552 | addi r2,r2,0x4000 | 1560 | addi r2,r2,0x4000 |
| 1553 | addi r2,r2,0x4000 | 1561 | addi r2,r2,0x4000 |
| 1554 | 1562 | ||
| @@ -1588,9 +1596,9 @@ _STATIC(__after_prom_start) | |||
| 1588 | */ | 1596 | */ |
| 1589 | bl .reloc_offset | 1597 | bl .reloc_offset |
| 1590 | mr r26,r3 | 1598 | mr r26,r3 |
| 1591 | SET_REG_TO_CONST(r27,KERNELBASE) | 1599 | LOAD_REG_IMMEDIATE(r27, KERNELBASE) |
| 1592 | 1600 | ||
| 1593 | LOADADDR(r3, PHYSICAL_START) /* target addr */ | 1601 | LOAD_REG_IMMEDIATE(r3, PHYSICAL_START) /* target addr */ |
| 1594 | 1602 | ||
| 1595 | // XXX FIXME: Use phys returned by OF (r30) | 1603 | // XXX FIXME: Use phys returned by OF (r30) |
| 1596 | add r4,r27,r26 /* source addr */ | 1604 | add r4,r27,r26 /* source addr */ |
| @@ -1598,7 +1606,7 @@ _STATIC(__after_prom_start) | |||
| 1598 | /* i.e. where we are running */ | 1606 | /* i.e. where we are running */ |
| 1599 | /* the source addr */ | 1607 | /* the source addr */ |
| 1600 | 1608 | ||
| 1601 | LOADADDR(r5,copy_to_here) /* # bytes of memory to copy */ | 1609 | LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */ |
| 1602 | sub r5,r5,r27 | 1610 | sub r5,r5,r27 |
| 1603 | 1611 | ||
| 1604 | li r6,0x100 /* Start offset, the first 0x100 */ | 1612 | li r6,0x100 /* Start offset, the first 0x100 */ |
| @@ -1608,11 +1616,11 @@ _STATIC(__after_prom_start) | |||
| 1608 | /* this includes the code being */ | 1616 | /* this includes the code being */ |
| 1609 | /* executed here. */ | 1617 | /* executed here. */ |
| 1610 | 1618 | ||
| 1611 | LOADADDR(r0, 4f) /* Jump to the copy of this code */ | 1619 | LOAD_REG_IMMEDIATE(r0, 4f) /* Jump to the copy of this code */ |
| 1612 | mtctr r0 /* that we just made/relocated */ | 1620 | mtctr r0 /* that we just made/relocated */ |
| 1613 | bctr | 1621 | bctr |
| 1614 | 1622 | ||
| 1615 | 4: LOADADDR(r5,klimit) | 1623 | 4: LOAD_REG_IMMEDIATE(r5,klimit) |
| 1616 | add r5,r5,r26 | 1624 | add r5,r5,r26 |
| 1617 | ld r5,0(r5) /* get the value of klimit */ | 1625 | ld r5,0(r5) /* get the value of klimit */ |
| 1618 | sub r5,r5,r27 | 1626 | sub r5,r5,r27 |
| @@ -1694,7 +1702,7 @@ _GLOBAL(pmac_secondary_start) | |||
| 1694 | mtmsrd r3 /* RI on */ | 1702 | mtmsrd r3 /* RI on */ |
| 1695 | 1703 | ||
| 1696 | /* Set up a paca value for this processor. */ | 1704 | /* Set up a paca value for this processor. */ |
| 1697 | LOADADDR(r4, paca) /* Get base vaddr of paca array */ | 1705 | LOAD_REG_IMMEDIATE(r4, paca) /* Get base vaddr of paca array */ |
| 1698 | mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */ | 1706 | mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */ |
| 1699 | add r13,r13,r4 /* for this processor. */ | 1707 | add r13,r13,r4 /* for this processor. */ |
| 1700 | mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */ | 1708 | mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */ |
| @@ -1731,7 +1739,7 @@ _GLOBAL(__secondary_start) | |||
| 1731 | bl .early_setup_secondary | 1739 | bl .early_setup_secondary |
| 1732 | 1740 | ||
| 1733 | /* Initialize the kernel stack. Just a repeat for iSeries. */ | 1741 | /* Initialize the kernel stack. Just a repeat for iSeries. */ |
| 1734 | LOADADDR(r3,current_set) | 1742 | LOAD_REG_ADDR(r3, current_set) |
| 1735 | sldi r28,r24,3 /* get current_set[cpu#] */ | 1743 | sldi r28,r24,3 /* get current_set[cpu#] */ |
| 1736 | ldx r1,r3,r28 | 1744 | ldx r1,r3,r28 |
| 1737 | addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD | 1745 | addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD |
| @@ -1742,8 +1750,8 @@ _GLOBAL(__secondary_start) | |||
| 1742 | mtlr r7 | 1750 | mtlr r7 |
| 1743 | 1751 | ||
| 1744 | /* enable MMU and jump to start_secondary */ | 1752 | /* enable MMU and jump to start_secondary */ |
| 1745 | LOADADDR(r3,.start_secondary_prolog) | 1753 | LOAD_REG_ADDR(r3, .start_secondary_prolog) |
| 1746 | SET_REG_TO_CONST(r4, MSR_KERNEL) | 1754 | LOAD_REG_IMMEDIATE(r4, MSR_KERNEL) |
| 1747 | #ifdef DO_SOFT_DISABLE | 1755 | #ifdef DO_SOFT_DISABLE |
| 1748 | ori r4,r4,MSR_EE | 1756 | ori r4,r4,MSR_EE |
| 1749 | #endif | 1757 | #endif |
| @@ -1792,8 +1800,8 @@ _STATIC(start_here_multiplatform) | |||
| 1792 | * be detached from the kernel completely. Besides, we need | 1800 | * be detached from the kernel completely. Besides, we need |
| 1793 | * to clear it now for kexec-style entry. | 1801 | * to clear it now for kexec-style entry. |
| 1794 | */ | 1802 | */ |
| 1795 | LOADADDR(r11,__bss_stop) | 1803 | LOAD_REG_IMMEDIATE(r11,__bss_stop) |
| 1796 | LOADADDR(r8,__bss_start) | 1804 | LOAD_REG_IMMEDIATE(r8,__bss_start) |
| 1797 | sub r11,r11,r8 /* bss size */ | 1805 | sub r11,r11,r8 /* bss size */ |
| 1798 | addi r11,r11,7 /* round up to an even double word */ | 1806 | addi r11,r11,7 /* round up to an even double word */ |
| 1799 | rldicl. r11,r11,61,3 /* shift right by 3 */ | 1807 | rldicl. r11,r11,61,3 /* shift right by 3 */ |
| @@ -1831,7 +1839,7 @@ _STATIC(start_here_multiplatform) | |||
| 1831 | /* up the htab. This is done because we have relocated the */ | 1839 | /* up the htab. This is done because we have relocated the */ |
| 1832 | /* kernel but are still running in real mode. */ | 1840 | /* kernel but are still running in real mode. */ |
| 1833 | 1841 | ||
| 1834 | LOADADDR(r3,init_thread_union) | 1842 | LOAD_REG_IMMEDIATE(r3,init_thread_union) |
| 1835 | add r3,r3,r26 | 1843 | add r3,r3,r26 |
| 1836 | 1844 | ||
| 1837 | /* set up a stack pointer (physical address) */ | 1845 | /* set up a stack pointer (physical address) */ |
| @@ -1840,14 +1848,14 @@ _STATIC(start_here_multiplatform) | |||
| 1840 | stdu r0,-STACK_FRAME_OVERHEAD(r1) | 1848 | stdu r0,-STACK_FRAME_OVERHEAD(r1) |
| 1841 | 1849 | ||
| 1842 | /* set up the TOC (physical address) */ | 1850 | /* set up the TOC (physical address) */ |
| 1843 | LOADADDR(r2,__toc_start) | 1851 | LOAD_REG_IMMEDIATE(r2,__toc_start) |
| 1844 | addi r2,r2,0x4000 | 1852 | addi r2,r2,0x4000 |
| 1845 | addi r2,r2,0x4000 | 1853 | addi r2,r2,0x4000 |
| 1846 | add r2,r2,r26 | 1854 | add r2,r2,r26 |
| 1847 | 1855 | ||
| 1848 | LOADADDR(r3,cpu_specs) | 1856 | LOAD_REG_IMMEDIATE(r3, cpu_specs) |
| 1849 | add r3,r3,r26 | 1857 | add r3,r3,r26 |
| 1850 | LOADADDR(r4,cur_cpu_spec) | 1858 | LOAD_REG_IMMEDIATE(r4,cur_cpu_spec) |
| 1851 | add r4,r4,r26 | 1859 | add r4,r4,r26 |
| 1852 | mr r5,r26 | 1860 | mr r5,r26 |
| 1853 | bl .identify_cpu | 1861 | bl .identify_cpu |
| @@ -1863,11 +1871,11 @@ _STATIC(start_here_multiplatform) | |||
| 1863 | * nowhere it can be initialized differently before we reach this | 1871 | * nowhere it can be initialized differently before we reach this |
| 1864 | * code | 1872 | * code |
| 1865 | */ | 1873 | */ |
| 1866 | LOADADDR(r27, boot_cpuid) | 1874 | LOAD_REG_IMMEDIATE(r27, boot_cpuid) |
| 1867 | add r27,r27,r26 | 1875 | add r27,r27,r26 |
| 1868 | lwz r27,0(r27) | 1876 | lwz r27,0(r27) |
| 1869 | 1877 | ||
| 1870 | LOADADDR(r24, paca) /* Get base vaddr of paca array */ | 1878 | LOAD_REG_IMMEDIATE(r24, paca) /* Get base vaddr of paca array */ |
| 1871 | mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */ | 1879 | mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */ |
| 1872 | add r13,r13,r24 /* for this processor. */ | 1880 | add r13,r13,r24 /* for this processor. */ |
| 1873 | add r13,r13,r26 /* convert to physical addr */ | 1881 | add r13,r13,r26 /* convert to physical addr */ |
| @@ -1880,8 +1888,8 @@ _STATIC(start_here_multiplatform) | |||
| 1880 | mr r3,r31 | 1888 | mr r3,r31 |
| 1881 | bl .early_setup | 1889 | bl .early_setup |
| 1882 | 1890 | ||
| 1883 | LOADADDR(r3,.start_here_common) | 1891 | LOAD_REG_IMMEDIATE(r3, .start_here_common) |
| 1884 | SET_REG_TO_CONST(r4, MSR_KERNEL) | 1892 | LOAD_REG_IMMEDIATE(r4, MSR_KERNEL) |
| 1885 | mtspr SPRN_SRR0,r3 | 1893 | mtspr SPRN_SRR0,r3 |
| 1886 | mtspr SPRN_SRR1,r4 | 1894 | mtspr SPRN_SRR1,r4 |
| 1887 | rfid | 1895 | rfid |
| @@ -1895,7 +1903,7 @@ _STATIC(start_here_common) | |||
| 1895 | /* The following code sets up the SP and TOC now that we are */ | 1903 | /* The following code sets up the SP and TOC now that we are */ |
| 1896 | /* running with translation enabled. */ | 1904 | /* running with translation enabled. */ |
| 1897 | 1905 | ||
| 1898 | LOADADDR(r3,init_thread_union) | 1906 | LOAD_REG_IMMEDIATE(r3,init_thread_union) |
| 1899 | 1907 | ||
| 1900 | /* set up the stack */ | 1908 | /* set up the stack */ |
| 1901 | addi r1,r3,THREAD_SIZE | 1909 | addi r1,r3,THREAD_SIZE |
| @@ -1908,16 +1916,16 @@ _STATIC(start_here_common) | |||
| 1908 | li r3,0 | 1916 | li r3,0 |
| 1909 | bl .do_cpu_ftr_fixups | 1917 | bl .do_cpu_ftr_fixups |
| 1910 | 1918 | ||
| 1911 | LOADADDR(r26, boot_cpuid) | 1919 | LOAD_REG_IMMEDIATE(r26, boot_cpuid) |
| 1912 | lwz r26,0(r26) | 1920 | lwz r26,0(r26) |
| 1913 | 1921 | ||
| 1914 | LOADADDR(r24, paca) /* Get base vaddr of paca array */ | 1922 | LOAD_REG_IMMEDIATE(r24, paca) /* Get base vaddr of paca array */ |
| 1915 | mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */ | 1923 | mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */ |
| 1916 | add r13,r13,r24 /* for this processor. */ | 1924 | add r13,r13,r24 /* for this processor. */ |
| 1917 | mtspr SPRN_SPRG3,r13 | 1925 | mtspr SPRN_SPRG3,r13 |
| 1918 | 1926 | ||
| 1919 | /* ptr to current */ | 1927 | /* ptr to current */ |
| 1920 | LOADADDR(r4,init_task) | 1928 | LOAD_REG_IMMEDIATE(r4, init_task) |
| 1921 | std r4,PACACURRENT(r13) | 1929 | std r4,PACACURRENT(r13) |
| 1922 | 1930 | ||
| 1923 | /* Load the TOC */ | 1931 | /* Load the TOC */ |
| @@ -1940,7 +1948,7 @@ _STATIC(start_here_common) | |||
| 1940 | 1948 | ||
| 1941 | _GLOBAL(hmt_init) | 1949 | _GLOBAL(hmt_init) |
| 1942 | #ifdef CONFIG_HMT | 1950 | #ifdef CONFIG_HMT |
| 1943 | LOADADDR(r5, hmt_thread_data) | 1951 | LOAD_REG_IMMEDIATE(r5, hmt_thread_data) |
| 1944 | mfspr r7,SPRN_PVR | 1952 | mfspr r7,SPRN_PVR |
| 1945 | srwi r7,r7,16 | 1953 | srwi r7,r7,16 |
| 1946 | cmpwi r7,0x34 /* Pulsar */ | 1954 | cmpwi r7,0x34 /* Pulsar */ |
| @@ -1961,7 +1969,7 @@ _GLOBAL(hmt_init) | |||
| 1961 | b 101f | 1969 | b 101f |
| 1962 | 1970 | ||
| 1963 | __hmt_secondary_hold: | 1971 | __hmt_secondary_hold: |
| 1964 | LOADADDR(r5, hmt_thread_data) | 1972 | LOAD_REG_IMMEDIATE(r5, hmt_thread_data) |
| 1965 | clrldi r5,r5,4 | 1973 | clrldi r5,r5,4 |
| 1966 | li r7,0 | 1974 | li r7,0 |
| 1967 | mfspr r6,SPRN_PIR | 1975 | mfspr r6,SPRN_PIR |
| @@ -1989,7 +1997,7 @@ __hmt_secondary_hold: | |||
| 1989 | 1997 | ||
| 1990 | #ifdef CONFIG_HMT | 1998 | #ifdef CONFIG_HMT |
| 1991 | _GLOBAL(hmt_start_secondary) | 1999 | _GLOBAL(hmt_start_secondary) |
| 1992 | LOADADDR(r4,__hmt_secondary_hold) | 2000 | LOAD_REG_IMMEDIATE(r4,__hmt_secondary_hold) |
| 1993 | clrldi r4,r4,4 | 2001 | clrldi r4,r4,4 |
| 1994 | mtspr SPRN_NIADORM, r4 | 2002 | mtspr SPRN_NIADORM, r4 |
| 1995 | mfspr r4, SPRN_MSRDORM | 2003 | mfspr r4, SPRN_MSRDORM |
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S index 1494e2f177f7..c16b4afab582 100644 --- a/arch/powerpc/kernel/idle_power4.S +++ b/arch/powerpc/kernel/idle_power4.S | |||
| @@ -38,14 +38,14 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP) | |||
| 38 | /* We must dynamically check for the NAP feature as it | 38 | /* We must dynamically check for the NAP feature as it |
| 39 | * can be cleared by CPU init after the fixups are done | 39 | * can be cleared by CPU init after the fixups are done |
| 40 | */ | 40 | */ |
| 41 | LOADBASE(r3,cur_cpu_spec) | 41 | LOAD_REG_ADDRBASE(r3,cur_cpu_spec) |
| 42 | ld r4,OFF(cur_cpu_spec)(r3) | 42 | ld r4,ADDROFF(cur_cpu_spec)(r3) |
| 43 | ld r4,CPU_SPEC_FEATURES(r4) | 43 | ld r4,CPU_SPEC_FEATURES(r4) |
| 44 | andi. r0,r4,CPU_FTR_CAN_NAP | 44 | andi. r0,r4,CPU_FTR_CAN_NAP |
| 45 | beqlr | 45 | beqlr |
| 46 | /* Now check if user or arch enabled NAP mode */ | 46 | /* Now check if user or arch enabled NAP mode */ |
| 47 | LOADBASE(r3,powersave_nap) | 47 | LOAD_REG_ADDRBASE(r3,powersave_nap) |
| 48 | lwz r4,OFF(powersave_nap)(r3) | 48 | lwz r4,ADDROFF(powersave_nap)(r3) |
| 49 | cmpwi 0,r4,0 | 49 | cmpwi 0,r4,0 |
| 50 | beqlr | 50 | beqlr |
| 51 | 51 | ||
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 5651032d8706..d1fffce86df9 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
| @@ -238,14 +238,10 @@ void do_IRQ(struct pt_regs *regs) | |||
| 238 | irq_exit(); | 238 | irq_exit(); |
| 239 | 239 | ||
| 240 | #ifdef CONFIG_PPC_ISERIES | 240 | #ifdef CONFIG_PPC_ISERIES |
| 241 | { | 241 | if (get_lppaca()->int_dword.fields.decr_int) { |
| 242 | struct paca_struct *lpaca = get_paca(); | 242 | get_lppaca()->int_dword.fields.decr_int = 0; |
| 243 | 243 | /* Signal a fake decrementer interrupt */ | |
| 244 | if (lpaca->lppaca.int_dword.fields.decr_int) { | 244 | timer_interrupt(regs); |
| 245 | lpaca->lppaca.int_dword.fields.decr_int = 0; | ||
| 246 | /* Signal a fake decrementer interrupt */ | ||
| 247 | timer_interrupt(regs); | ||
| 248 | } | ||
| 249 | } | 245 | } |
| 250 | #endif | 246 | #endif |
| 251 | } | 247 | } |
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index 9dda16ccde78..1ae96a8ed7e2 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c | |||
| @@ -55,15 +55,13 @@ static unsigned long get_purr(void) | |||
| 55 | { | 55 | { |
| 56 | unsigned long sum_purr = 0; | 56 | unsigned long sum_purr = 0; |
| 57 | int cpu; | 57 | int cpu; |
| 58 | struct paca_struct *lpaca; | ||
| 59 | 58 | ||
| 60 | for_each_cpu(cpu) { | 59 | for_each_cpu(cpu) { |
| 61 | lpaca = paca + cpu; | 60 | sum_purr += lppaca[cpu].emulated_time_base; |
| 62 | sum_purr += lpaca->lppaca.emulated_time_base; | ||
| 63 | 61 | ||
| 64 | #ifdef PURR_DEBUG | 62 | #ifdef PURR_DEBUG |
| 65 | printk(KERN_INFO "get_purr for cpu (%d) has value (%ld) \n", | 63 | printk(KERN_INFO "get_purr for cpu (%d) has value (%ld) \n", |
| 66 | cpu, lpaca->lppaca.emulated_time_base); | 64 | cpu, lppaca[cpu].emulated_time_base); |
| 67 | #endif | 65 | #endif |
| 68 | } | 66 | } |
| 69 | return sum_purr; | 67 | return sum_purr; |
| @@ -79,12 +77,11 @@ static int lparcfg_data(struct seq_file *m, void *v) | |||
| 79 | unsigned long pool_id, lp_index; | 77 | unsigned long pool_id, lp_index; |
| 80 | int shared, entitled_capacity, max_entitled_capacity; | 78 | int shared, entitled_capacity, max_entitled_capacity; |
| 81 | int processors, max_processors; | 79 | int processors, max_processors; |
| 82 | struct paca_struct *lpaca = get_paca(); | ||
| 83 | unsigned long purr = get_purr(); | 80 | unsigned long purr = get_purr(); |
| 84 | 81 | ||
| 85 | seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); | 82 | seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); |
| 86 | 83 | ||
| 87 | shared = (int)(lpaca->lppaca_ptr->shared_proc); | 84 | shared = (int)(get_lppaca()->shared_proc); |
| 88 | seq_printf(m, "serial_number=%c%c%c%c%c%c%c\n", | 85 | seq_printf(m, "serial_number=%c%c%c%c%c%c%c\n", |
| 89 | e2a(xItExtVpdPanel.mfgID[2]), | 86 | e2a(xItExtVpdPanel.mfgID[2]), |
| 90 | e2a(xItExtVpdPanel.mfgID[3]), | 87 | e2a(xItExtVpdPanel.mfgID[3]), |
| @@ -402,7 +399,7 @@ static int lparcfg_data(struct seq_file *m, void *v) | |||
| 402 | (h_resource >> 0 * 8) & 0xffff); | 399 | (h_resource >> 0 * 8) & 0xffff); |
| 403 | 400 | ||
| 404 | /* pool related entries are apropriate for shared configs */ | 401 | /* pool related entries are apropriate for shared configs */ |
| 405 | if (paca[0].lppaca.shared_proc) { | 402 | if (lppaca[0].shared_proc) { |
| 406 | 403 | ||
| 407 | h_pic(&pool_idle_time, &pool_procs); | 404 | h_pic(&pool_idle_time, &pool_procs); |
| 408 | 405 | ||
| @@ -451,7 +448,7 @@ static int lparcfg_data(struct seq_file *m, void *v) | |||
| 451 | seq_printf(m, "partition_potential_processors=%d\n", | 448 | seq_printf(m, "partition_potential_processors=%d\n", |
| 452 | partition_potential_processors); | 449 | partition_potential_processors); |
| 453 | 450 | ||
| 454 | seq_printf(m, "shared_processor_mode=%d\n", paca[0].lppaca.shared_proc); | 451 | seq_printf(m, "shared_processor_mode=%d\n", lppaca[0].shared_proc); |
| 455 | 452 | ||
| 456 | return 0; | 453 | return 0; |
| 457 | } | 454 | } |
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 01d0d97a16e1..be982023409e 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
| @@ -68,7 +68,7 @@ _GLOBAL(reloc_offset) | |||
| 68 | mflr r0 | 68 | mflr r0 |
| 69 | bl 1f | 69 | bl 1f |
| 70 | 1: mflr r3 | 70 | 1: mflr r3 |
| 71 | LOADADDR(r4,1b) | 71 | LOAD_REG_IMMEDIATE(r4,1b) |
| 72 | subf r3,r4,r3 | 72 | subf r3,r4,r3 |
| 73 | mtlr r0 | 73 | mtlr r0 |
| 74 | blr | 74 | blr |
| @@ -80,7 +80,7 @@ _GLOBAL(add_reloc_offset) | |||
| 80 | mflr r0 | 80 | mflr r0 |
| 81 | bl 1f | 81 | bl 1f |
| 82 | 1: mflr r5 | 82 | 1: mflr r5 |
| 83 | LOADADDR(r4,1b) | 83 | LOAD_REG_IMMEDIATE(r4,1b) |
| 84 | subf r5,r4,r5 | 84 | subf r5,r4,r5 |
| 85 | add r3,r3,r5 | 85 | add r3,r3,r5 |
| 86 | mtlr r0 | 86 | mtlr r0 |
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index ae48a002f81a..2778cce058e2 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S | |||
| @@ -39,7 +39,7 @@ _GLOBAL(reloc_offset) | |||
| 39 | mflr r0 | 39 | mflr r0 |
| 40 | bl 1f | 40 | bl 1f |
| 41 | 1: mflr r3 | 41 | 1: mflr r3 |
| 42 | LOADADDR(r4,1b) | 42 | LOAD_REG_IMMEDIATE(r4,1b) |
| 43 | subf r3,r4,r3 | 43 | subf r3,r4,r3 |
| 44 | mtlr r0 | 44 | mtlr r0 |
| 45 | blr | 45 | blr |
| @@ -51,7 +51,7 @@ _GLOBAL(add_reloc_offset) | |||
| 51 | mflr r0 | 51 | mflr r0 |
| 52 | bl 1f | 52 | bl 1f |
| 53 | 1: mflr r5 | 53 | 1: mflr r5 |
| 54 | LOADADDR(r4,1b) | 54 | LOAD_REG_IMMEDIATE(r4,1b) |
| 55 | subf r5,r4,r5 | 55 | subf r5,r4,r5 |
| 56 | add r3,r3,r5 | 56 | add r3,r3,r5 |
| 57 | mtlr r0 | 57 | mtlr r0 |
| @@ -498,15 +498,15 @@ _GLOBAL(identify_cpu) | |||
| 498 | */ | 498 | */ |
| 499 | _GLOBAL(do_cpu_ftr_fixups) | 499 | _GLOBAL(do_cpu_ftr_fixups) |
| 500 | /* Get CPU 0 features */ | 500 | /* Get CPU 0 features */ |
| 501 | LOADADDR(r6,cur_cpu_spec) | 501 | LOAD_REG_IMMEDIATE(r6,cur_cpu_spec) |
| 502 | sub r6,r6,r3 | 502 | sub r6,r6,r3 |
| 503 | ld r4,0(r6) | 503 | ld r4,0(r6) |
| 504 | sub r4,r4,r3 | 504 | sub r4,r4,r3 |
| 505 | ld r4,CPU_SPEC_FEATURES(r4) | 505 | ld r4,CPU_SPEC_FEATURES(r4) |
| 506 | /* Get the fixup table */ | 506 | /* Get the fixup table */ |
| 507 | LOADADDR(r6,__start___ftr_fixup) | 507 | LOAD_REG_IMMEDIATE(r6,__start___ftr_fixup) |
| 508 | sub r6,r6,r3 | 508 | sub r6,r6,r3 |
| 509 | LOADADDR(r7,__stop___ftr_fixup) | 509 | LOAD_REG_IMMEDIATE(r7,__stop___ftr_fixup) |
| 510 | sub r7,r7,r3 | 510 | sub r7,r7,r3 |
| 511 | /* Do the fixup */ | 511 | /* Do the fixup */ |
| 512 | 1: cmpld r6,r7 | 512 | 1: cmpld r6,r7 |
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index 7065e40e2f42..22d83d4d1af5 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c | |||
| @@ -132,6 +132,8 @@ static int of_device_resume(struct device * dev) | |||
| 132 | struct bus_type of_platform_bus_type = { | 132 | struct bus_type of_platform_bus_type = { |
| 133 | .name = "of_platform", | 133 | .name = "of_platform", |
| 134 | .match = of_platform_bus_match, | 134 | .match = of_platform_bus_match, |
| 135 | .probe = of_device_probe, | ||
| 136 | .remove = of_device_remove, | ||
| 135 | .suspend = of_device_suspend, | 137 | .suspend = of_device_suspend, |
| 136 | .resume = of_device_resume, | 138 | .resume = of_device_resume, |
| 137 | }; | 139 | }; |
| @@ -150,8 +152,6 @@ int of_register_driver(struct of_platform_driver *drv) | |||
| 150 | /* initialize common driver fields */ | 152 | /* initialize common driver fields */ |
| 151 | drv->driver.name = drv->name; | 153 | drv->driver.name = drv->name; |
| 152 | drv->driver.bus = &of_platform_bus_type; | 154 | drv->driver.bus = &of_platform_bus_type; |
| 153 | drv->driver.probe = of_device_probe; | ||
| 154 | drv->driver.remove = of_device_remove; | ||
| 155 | 155 | ||
| 156 | /* register with core */ | 156 | /* register with core */ |
| 157 | count = driver_register(&drv->driver); | 157 | count = driver_register(&drv->driver); |
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 999bdd816769..5d1b708086bd 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c | |||
| @@ -25,6 +25,28 @@ | |||
| 25 | * field correctly */ | 25 | * field correctly */ |
| 26 | extern unsigned long __toc_start; | 26 | extern unsigned long __toc_start; |
| 27 | 27 | ||
| 28 | /* | ||
| 29 | * iSeries structure which the hypervisor knows about - this structure | ||
| 30 | * should not cross a page boundary. The vpa_init/register_vpa call | ||
| 31 | * is now known to fail if the lppaca structure crosses a page | ||
| 32 | * boundary. The lppaca is also used on POWER5 pSeries boxes. The | ||
| 33 | * lppaca is 640 bytes long, and cannot readily change since the | ||
| 34 | * hypervisor knows its layout, so a 1kB alignment will suffice to | ||
| 35 | * ensure that it doesn't cross a page boundary. | ||
| 36 | */ | ||
| 37 | struct lppaca lppaca[] = { | ||
| 38 | [0 ... (NR_CPUS-1)] = { | ||
| 39 | .desc = 0xd397d781, /* "LpPa" */ | ||
| 40 | .size = sizeof(struct lppaca), | ||
| 41 | .dyn_proc_status = 2, | ||
| 42 | .decr_val = 0x00ff0000, | ||
| 43 | .fpregs_in_use = 1, | ||
| 44 | .end_of_quantum = 0xfffffffffffffffful, | ||
| 45 | .slb_count = 64, | ||
| 46 | .vmxregs_in_use = 0, | ||
| 47 | }, | ||
| 48 | }; | ||
| 49 | |||
| 28 | /* The Paca is an array with one entry per processor. Each contains an | 50 | /* The Paca is an array with one entry per processor. Each contains an |
| 29 | * lppaca, which contains the information shared between the | 51 | * lppaca, which contains the information shared between the |
| 30 | * hypervisor and Linux. | 52 | * hypervisor and Linux. |
| @@ -35,27 +57,17 @@ extern unsigned long __toc_start; | |||
| 35 | * processor (not thread). | 57 | * processor (not thread). |
| 36 | */ | 58 | */ |
| 37 | #define PACA_INIT_COMMON(number, start, asrr, asrv) \ | 59 | #define PACA_INIT_COMMON(number, start, asrr, asrv) \ |
| 60 | .lppaca_ptr = &lppaca[number], \ | ||
| 38 | .lock_token = 0x8000, \ | 61 | .lock_token = 0x8000, \ |
| 39 | .paca_index = (number), /* Paca Index */ \ | 62 | .paca_index = (number), /* Paca Index */ \ |
| 40 | .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \ | 63 | .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \ |
| 41 | .stab_real = (asrr), /* Real pointer to segment table */ \ | 64 | .stab_real = (asrr), /* Real pointer to segment table */ \ |
| 42 | .stab_addr = (asrv), /* Virt pointer to segment table */ \ | 65 | .stab_addr = (asrv), /* Virt pointer to segment table */ \ |
| 43 | .cpu_start = (start), /* Processor start */ \ | 66 | .cpu_start = (start), /* Processor start */ \ |
| 44 | .hw_cpu_id = 0xffff, \ | 67 | .hw_cpu_id = 0xffff, |
| 45 | .lppaca = { \ | ||
| 46 | .desc = 0xd397d781, /* "LpPa" */ \ | ||
| 47 | .size = sizeof(struct lppaca), \ | ||
| 48 | .dyn_proc_status = 2, \ | ||
| 49 | .decr_val = 0x00ff0000, \ | ||
| 50 | .fpregs_in_use = 1, \ | ||
| 51 | .end_of_quantum = 0xfffffffffffffffful, \ | ||
| 52 | .slb_count = 64, \ | ||
| 53 | .vmxregs_in_use = 0, \ | ||
| 54 | }, \ | ||
| 55 | 68 | ||
| 56 | #ifdef CONFIG_PPC_ISERIES | 69 | #ifdef CONFIG_PPC_ISERIES |
| 57 | #define PACA_INIT_ISERIES(number) \ | 70 | #define PACA_INIT_ISERIES(number) \ |
| 58 | .lppaca_ptr = &paca[number].lppaca, \ | ||
| 59 | .reg_save_ptr = &iseries_reg_save[number], | 71 | .reg_save_ptr = &iseries_reg_save[number], |
| 60 | 72 | ||
| 61 | #define PACA_INIT(number) \ | 73 | #define PACA_INIT(number) \ |
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c new file mode 100644 index 000000000000..704c846b2b0f --- /dev/null +++ b/arch/powerpc/kernel/pci_32.c | |||
| @@ -0,0 +1,1897 @@ | |||
| 1 | /* | ||
| 2 | * Common pmac/prep/chrp pci routines. -- Cort | ||
| 3 | */ | ||
| 4 | |||
| 5 | #include <linux/config.h> | ||
| 6 | #include <linux/kernel.h> | ||
| 7 | #include <linux/pci.h> | ||
| 8 | #include <linux/delay.h> | ||
| 9 | #include <linux/string.h> | ||
| 10 | #include <linux/init.h> | ||
| 11 | #include <linux/capability.h> | ||
| 12 | #include <linux/sched.h> | ||
| 13 | #include <linux/errno.h> | ||
| 14 | #include <linux/bootmem.h> | ||
| 15 | |||
| 16 | #include <asm/processor.h> | ||
| 17 | #include <asm/io.h> | ||
| 18 | #include <asm/prom.h> | ||
| 19 | #include <asm/sections.h> | ||
| 20 | #include <asm/pci-bridge.h> | ||
| 21 | #include <asm/byteorder.h> | ||
| 22 | #include <asm/irq.h> | ||
| 23 | #include <asm/uaccess.h> | ||
| 24 | #include <asm/machdep.h> | ||
| 25 | |||
| 26 | #undef DEBUG | ||
| 27 | |||
| 28 | #ifdef DEBUG | ||
| 29 | #define DBG(x...) printk(x) | ||
| 30 | #else | ||
| 31 | #define DBG(x...) | ||
| 32 | #endif | ||
| 33 | |||
| 34 | unsigned long isa_io_base = 0; | ||
| 35 | unsigned long isa_mem_base = 0; | ||
| 36 | unsigned long pci_dram_offset = 0; | ||
| 37 | int pcibios_assign_bus_offset = 1; | ||
| 38 | |||
| 39 | void pcibios_make_OF_bus_map(void); | ||
| 40 | |||
| 41 | static int pci_relocate_bridge_resource(struct pci_bus *bus, int i); | ||
| 42 | static int probe_resource(struct pci_bus *parent, struct resource *pr, | ||
| 43 | struct resource *res, struct resource **conflict); | ||
| 44 | static void update_bridge_base(struct pci_bus *bus, int i); | ||
| 45 | static void pcibios_fixup_resources(struct pci_dev* dev); | ||
| 46 | static void fixup_broken_pcnet32(struct pci_dev* dev); | ||
| 47 | static int reparent_resources(struct resource *parent, struct resource *res); | ||
| 48 | static void fixup_cpc710_pci64(struct pci_dev* dev); | ||
| 49 | #ifdef CONFIG_PPC_OF | ||
| 50 | static u8* pci_to_OF_bus_map; | ||
| 51 | #endif | ||
| 52 | |||
| 53 | /* By default, we don't re-assign bus numbers. We do this only on | ||
| 54 | * some pmacs | ||
| 55 | */ | ||
| 56 | int pci_assign_all_buses; | ||
| 57 | |||
| 58 | struct pci_controller* hose_head; | ||
| 59 | struct pci_controller** hose_tail = &hose_head; | ||
| 60 | |||
| 61 | static int pci_bus_count; | ||
| 62 | |||
| 63 | static void | ||
| 64 | fixup_broken_pcnet32(struct pci_dev* dev) | ||
| 65 | { | ||
| 66 | if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) { | ||
| 67 | dev->vendor = PCI_VENDOR_ID_AMD; | ||
| 68 | pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD); | ||
| 69 | } | ||
| 70 | } | ||
| 71 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32); | ||
| 72 | |||
| 73 | static void | ||
| 74 | fixup_cpc710_pci64(struct pci_dev* dev) | ||
| 75 | { | ||
| 76 | /* Hide the PCI64 BARs from the kernel as their content doesn't | ||
| 77 | * fit well in the resource management | ||
| 78 | */ | ||
| 79 | dev->resource[0].start = dev->resource[0].end = 0; | ||
| 80 | dev->resource[0].flags = 0; | ||
| 81 | dev->resource[1].start = dev->resource[1].end = 0; | ||
| 82 | dev->resource[1].flags = 0; | ||
| 83 | } | ||
| 84 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CPC710_PCI64, fixup_cpc710_pci64); | ||
| 85 | |||
| 86 | static void | ||
| 87 | pcibios_fixup_resources(struct pci_dev *dev) | ||
| 88 | { | ||
| 89 | struct pci_controller* hose = (struct pci_controller *)dev->sysdata; | ||
| 90 | int i; | ||
| 91 | unsigned long offset; | ||
| 92 | |||
| 93 | if (!hose) { | ||
| 94 | printk(KERN_ERR "No hose for PCI dev %s!\n", pci_name(dev)); | ||
| 95 | return; | ||
| 96 | } | ||
| 97 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | ||
| 98 | struct resource *res = dev->resource + i; | ||
| 99 | if (!res->flags) | ||
| 100 | continue; | ||
| 101 | if (res->end == 0xffffffff) { | ||
| 102 | DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n", | ||
| 103 | pci_name(dev), i, res->start, res->end); | ||
| 104 | res->end -= res->start; | ||
| 105 | res->start = 0; | ||
| 106 | res->flags |= IORESOURCE_UNSET; | ||
| 107 | continue; | ||
| 108 | } | ||
| 109 | offset = 0; | ||
| 110 | if (res->flags & IORESOURCE_MEM) { | ||
| 111 | offset = hose->pci_mem_offset; | ||
| 112 | } else if (res->flags & IORESOURCE_IO) { | ||
| 113 | offset = (unsigned long) hose->io_base_virt | ||
| 114 | - isa_io_base; | ||
| 115 | } | ||
| 116 | if (offset != 0) { | ||
| 117 | res->start += offset; | ||
| 118 | res->end += offset; | ||
| 119 | #ifdef DEBUG | ||
| 120 | printk("Fixup res %d (%lx) of dev %s: %lx -> %lx\n", | ||
| 121 | i, res->flags, pci_name(dev), | ||
| 122 | res->start - offset, res->start); | ||
| 123 | #endif | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | /* Call machine specific resource fixup */ | ||
| 128 | if (ppc_md.pcibios_fixup_resources) | ||
| 129 | ppc_md.pcibios_fixup_resources(dev); | ||
| 130 | } | ||
| 131 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources); | ||
| 132 | |||
| 133 | void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
| 134 | struct resource *res) | ||
| 135 | { | ||
| 136 | unsigned long offset = 0; | ||
| 137 | struct pci_controller *hose = dev->sysdata; | ||
| 138 | |||
| 139 | if (hose && res->flags & IORESOURCE_IO) | ||
| 140 | offset = (unsigned long)hose->io_base_virt - isa_io_base; | ||
| 141 | else if (hose && res->flags & IORESOURCE_MEM) | ||
| 142 | offset = hose->pci_mem_offset; | ||
| 143 | region->start = res->start - offset; | ||
| 144 | region->end = res->end - offset; | ||
| 145 | } | ||
| 146 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
| 147 | |||
| 148 | void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
| 149 | struct pci_bus_region *region) | ||
| 150 | { | ||
| 151 | unsigned long offset = 0; | ||
| 152 | struct pci_controller *hose = dev->sysdata; | ||
| 153 | |||
| 154 | if (hose && res->flags & IORESOURCE_IO) | ||
| 155 | offset = (unsigned long)hose->io_base_virt - isa_io_base; | ||
| 156 | else if (hose && res->flags & IORESOURCE_MEM) | ||
| 157 | offset = hose->pci_mem_offset; | ||
| 158 | res->start = region->start + offset; | ||
| 159 | res->end = region->end + offset; | ||
| 160 | } | ||
| 161 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
| 162 | |||
| 163 | /* | ||
| 164 | * We need to avoid collisions with `mirrored' VGA ports | ||
| 165 | * and other strange ISA hardware, so we always want the | ||
| 166 | * addresses to be allocated in the 0x000-0x0ff region | ||
| 167 | * modulo 0x400. | ||
| 168 | * | ||
| 169 | * Why? Because some silly external IO cards only decode | ||
| 170 | * the low 10 bits of the IO address. The 0x00-0xff region | ||
| 171 | * is reserved for motherboard devices that decode all 16 | ||
| 172 | * bits, so it's ok to allocate at, say, 0x2800-0x28ff, | ||
| 173 | * but we want to try to avoid allocating at 0x2900-0x2bff | ||
| 174 | * which might have be mirrored at 0x0100-0x03ff.. | ||
| 175 | */ | ||
| 176 | void pcibios_align_resource(void *data, struct resource *res, unsigned long size, | ||
| 177 | unsigned long align) | ||
| 178 | { | ||
| 179 | struct pci_dev *dev = data; | ||
| 180 | |||
| 181 | if (res->flags & IORESOURCE_IO) { | ||
| 182 | unsigned long start = res->start; | ||
| 183 | |||
| 184 | if (size > 0x100) { | ||
| 185 | printk(KERN_ERR "PCI: I/O Region %s/%d too large" | ||
| 186 | " (%ld bytes)\n", pci_name(dev), | ||
| 187 | dev->resource - res, size); | ||
| 188 | } | ||
| 189 | |||
| 190 | if (start & 0x300) { | ||
| 191 | start = (start + 0x3ff) & ~0x3ff; | ||
| 192 | res->start = start; | ||
| 193 | } | ||
| 194 | } | ||
| 195 | } | ||
| 196 | EXPORT_SYMBOL(pcibios_align_resource); | ||
| 197 | |||
| 198 | /* | ||
| 199 | * Handle resources of PCI devices. If the world were perfect, we could | ||
| 200 | * just allocate all the resource regions and do nothing more. It isn't. | ||
| 201 | * On the other hand, we cannot just re-allocate all devices, as it would | ||
| 202 | * require us to know lots of host bridge internals. So we attempt to | ||
| 203 | * keep as much of the original configuration as possible, but tweak it | ||
| 204 | * when it's found to be wrong. | ||
| 205 | * | ||
| 206 | * Known BIOS problems we have to work around: | ||
| 207 | * - I/O or memory regions not configured | ||
| 208 | * - regions configured, but not enabled in the command register | ||
| 209 | * - bogus I/O addresses above 64K used | ||
| 210 | * - expansion ROMs left enabled (this may sound harmless, but given | ||
| 211 | * the fact the PCI specs explicitly allow address decoders to be | ||
| 212 | * shared between expansion ROMs and other resource regions, it's | ||
| 213 | * at least dangerous) | ||
| 214 | * | ||
| 215 | * Our solution: | ||
| 216 | * (1) Allocate resources for all buses behind PCI-to-PCI bridges. | ||
| 217 | * This gives us fixed barriers on where we can allocate. | ||
| 218 | * (2) Allocate resources for all enabled devices. If there is | ||
| 219 | * a collision, just mark the resource as unallocated. Also | ||
| 220 | * disable expansion ROMs during this step. | ||
| 221 | * (3) Try to allocate resources for disabled devices. If the | ||
| 222 | * resources were assigned correctly, everything goes well, | ||
| 223 | * if they weren't, they won't disturb allocation of other | ||
| 224 | * resources. | ||
| 225 | * (4) Assign new addresses to resources which were either | ||
| 226 | * not configured at all or misconfigured. If explicitly | ||
| 227 | * requested by the user, configure expansion ROM address | ||
| 228 | * as well. | ||
| 229 | */ | ||
| 230 | |||
| 231 | static void __init | ||
| 232 | pcibios_allocate_bus_resources(struct list_head *bus_list) | ||
| 233 | { | ||
| 234 | struct pci_bus *bus; | ||
| 235 | int i; | ||
| 236 | struct resource *res, *pr; | ||
| 237 | |||
| 238 | /* Depth-First Search on bus tree */ | ||
| 239 | list_for_each_entry(bus, bus_list, node) { | ||
| 240 | for (i = 0; i < 4; ++i) { | ||
| 241 | if ((res = bus->resource[i]) == NULL || !res->flags | ||
| 242 | || res->start > res->end) | ||
| 243 | continue; | ||
| 244 | if (bus->parent == NULL) | ||
| 245 | pr = (res->flags & IORESOURCE_IO)? | ||
| 246 | &ioport_resource: &iomem_resource; | ||
| 247 | else { | ||
| 248 | pr = pci_find_parent_resource(bus->self, res); | ||
| 249 | if (pr == res) { | ||
| 250 | /* this happens when the generic PCI | ||
| 251 | * code (wrongly) decides that this | ||
| 252 | * bridge is transparent -- paulus | ||
| 253 | */ | ||
| 254 | continue; | ||
| 255 | } | ||
| 256 | } | ||
| 257 | |||
| 258 | DBG("PCI: bridge rsrc %lx..%lx (%lx), parent %p\n", | ||
| 259 | res->start, res->end, res->flags, pr); | ||
| 260 | if (pr) { | ||
| 261 | if (request_resource(pr, res) == 0) | ||
| 262 | continue; | ||
| 263 | /* | ||
| 264 | * Must be a conflict with an existing entry. | ||
| 265 | * Move that entry (or entries) under the | ||
| 266 | * bridge resource and try again. | ||
| 267 | */ | ||
| 268 | if (reparent_resources(pr, res) == 0) | ||
| 269 | continue; | ||
| 270 | } | ||
| 271 | printk(KERN_ERR "PCI: Cannot allocate resource region " | ||
| 272 | "%d of PCI bridge %d\n", i, bus->number); | ||
| 273 | if (pci_relocate_bridge_resource(bus, i)) | ||
| 274 | bus->resource[i] = NULL; | ||
| 275 | } | ||
| 276 | pcibios_allocate_bus_resources(&bus->children); | ||
| 277 | } | ||
| 278 | } | ||
| 279 | |||
| 280 | /* | ||
| 281 | * Reparent resource children of pr that conflict with res | ||
| 282 | * under res, and make res replace those children. | ||
| 283 | */ | ||
| 284 | static int __init | ||
| 285 | reparent_resources(struct resource *parent, struct resource *res) | ||
| 286 | { | ||
| 287 | struct resource *p, **pp; | ||
| 288 | struct resource **firstpp = NULL; | ||
| 289 | |||
| 290 | for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) { | ||
| 291 | if (p->end < res->start) | ||
| 292 | continue; | ||
| 293 | if (res->end < p->start) | ||
| 294 | break; | ||
| 295 | if (p->start < res->start || p->end > res->end) | ||
| 296 | return -1; /* not completely contained */ | ||
| 297 | if (firstpp == NULL) | ||
| 298 | firstpp = pp; | ||
| 299 | } | ||
| 300 | if (firstpp == NULL) | ||
| 301 | return -1; /* didn't find any conflicting entries? */ | ||
| 302 | res->parent = parent; | ||
| 303 | res->child = *firstpp; | ||
| 304 | res->sibling = *pp; | ||
| 305 | *firstpp = res; | ||
| 306 | *pp = NULL; | ||
| 307 | for (p = res->child; p != NULL; p = p->sibling) { | ||
| 308 | p->parent = res; | ||
| 309 | DBG(KERN_INFO "PCI: reparented %s [%lx..%lx] under %s\n", | ||
| 310 | p->name, p->start, p->end, res->name); | ||
| 311 | } | ||
| 312 | return 0; | ||
| 313 | } | ||
| 314 | |||
| 315 | /* | ||
| 316 | * A bridge has been allocated a range which is outside the range | ||
| 317 | * of its parent bridge, so it needs to be moved. | ||
| 318 | */ | ||
| 319 | static int __init | ||
| 320 | pci_relocate_bridge_resource(struct pci_bus *bus, int i) | ||
| 321 | { | ||
| 322 | struct resource *res, *pr, *conflict; | ||
| 323 | unsigned long try, size; | ||
| 324 | int j; | ||
| 325 | struct pci_bus *parent = bus->parent; | ||
| 326 | |||
| 327 | if (parent == NULL) { | ||
| 328 | /* shouldn't ever happen */ | ||
| 329 | printk(KERN_ERR "PCI: can't move host bridge resource\n"); | ||
| 330 | return -1; | ||
| 331 | } | ||
| 332 | res = bus->resource[i]; | ||
| 333 | if (res == NULL) | ||
| 334 | return -1; | ||
| 335 | pr = NULL; | ||
| 336 | for (j = 0; j < 4; j++) { | ||
| 337 | struct resource *r = parent->resource[j]; | ||
| 338 | if (!r) | ||
| 339 | continue; | ||
| 340 | if ((res->flags ^ r->flags) & (IORESOURCE_IO | IORESOURCE_MEM)) | ||
| 341 | continue; | ||
| 342 | if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH)) { | ||
| 343 | pr = r; | ||
| 344 | break; | ||
| 345 | } | ||
| 346 | if (res->flags & IORESOURCE_PREFETCH) | ||
| 347 | pr = r; | ||
| 348 | } | ||
| 349 | if (pr == NULL) | ||
| 350 | return -1; | ||
| 351 | size = res->end - res->start; | ||
| 352 | if (pr->start > pr->end || size > pr->end - pr->start) | ||
| 353 | return -1; | ||
| 354 | try = pr->end; | ||
| 355 | for (;;) { | ||
| 356 | res->start = try - size; | ||
| 357 | res->end = try; | ||
| 358 | if (probe_resource(bus->parent, pr, res, &conflict) == 0) | ||
| 359 | break; | ||
| 360 | if (conflict->start <= pr->start + size) | ||
| 361 | return -1; | ||
| 362 | try = conflict->start - 1; | ||
| 363 | } | ||
| 364 | if (request_resource(pr, res)) { | ||
| 365 | DBG(KERN_ERR "PCI: huh? couldn't move to %lx..%lx\n", | ||
| 366 | res->start, res->end); | ||
| 367 | return -1; /* "can't happen" */ | ||
| 368 | } | ||
| 369 | update_bridge_base(bus, i); | ||
| 370 | printk(KERN_INFO "PCI: bridge %d resource %d moved to %lx..%lx\n", | ||
| 371 | bus->number, i, res->start, res->end); | ||
| 372 | return 0; | ||
| 373 | } | ||
| 374 | |||
| 375 | static int __init | ||
| 376 | probe_resource(struct pci_bus *parent, struct resource *pr, | ||
| 377 | struct resource *res, struct resource **conflict) | ||
| 378 | { | ||
| 379 | struct pci_bus *bus; | ||
| 380 | struct pci_dev *dev; | ||
| 381 | struct resource *r; | ||
| 382 | int i; | ||
| 383 | |||
| 384 | for (r = pr->child; r != NULL; r = r->sibling) { | ||
| 385 | if (r->end >= res->start && res->end >= r->start) { | ||
| 386 | *conflict = r; | ||
| 387 | return 1; | ||
| 388 | } | ||
| 389 | } | ||
| 390 | list_for_each_entry(bus, &parent->children, node) { | ||
| 391 | for (i = 0; i < 4; ++i) { | ||
| 392 | if ((r = bus->resource[i]) == NULL) | ||
| 393 | continue; | ||
| 394 | if (!r->flags || r->start > r->end || r == res) | ||
| 395 | continue; | ||
| 396 | if (pci_find_parent_resource(bus->self, r) != pr) | ||
| 397 | continue; | ||
| 398 | if (r->end >= res->start && res->end >= r->start) { | ||
| 399 | *conflict = r; | ||
| 400 | return 1; | ||
| 401 | } | ||
| 402 | } | ||
| 403 | } | ||
| 404 | list_for_each_entry(dev, &parent->devices, bus_list) { | ||
| 405 | for (i = 0; i < 6; ++i) { | ||
| 406 | r = &dev->resource[i]; | ||
| 407 | if (!r->flags || (r->flags & IORESOURCE_UNSET)) | ||
| 408 | continue; | ||
| 409 | if (pci_find_parent_resource(dev, r) != pr) | ||
| 410 | continue; | ||
| 411 | if (r->end >= res->start && res->end >= r->start) { | ||
| 412 | *conflict = r; | ||
| 413 | return 1; | ||
| 414 | } | ||
| 415 | } | ||
| 416 | } | ||
| 417 | return 0; | ||
| 418 | } | ||
| 419 | |||
| 420 | static void __init | ||
| 421 | update_bridge_base(struct pci_bus *bus, int i) | ||
| 422 | { | ||
| 423 | struct resource *res = bus->resource[i]; | ||
| 424 | u8 io_base_lo, io_limit_lo; | ||
| 425 | u16 mem_base, mem_limit; | ||
| 426 | u16 cmd; | ||
| 427 | unsigned long start, end, off; | ||
| 428 | struct pci_dev *dev = bus->self; | ||
| 429 | struct pci_controller *hose = dev->sysdata; | ||
| 430 | |||
| 431 | if (!hose) { | ||
| 432 | printk("update_bridge_base: no hose?\n"); | ||
| 433 | return; | ||
| 434 | } | ||
| 435 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
| 436 | pci_write_config_word(dev, PCI_COMMAND, | ||
| 437 | cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)); | ||
| 438 | if (res->flags & IORESOURCE_IO) { | ||
| 439 | off = (unsigned long) hose->io_base_virt - isa_io_base; | ||
| 440 | start = res->start - off; | ||
| 441 | end = res->end - off; | ||
| 442 | io_base_lo = (start >> 8) & PCI_IO_RANGE_MASK; | ||
| 443 | io_limit_lo = (end >> 8) & PCI_IO_RANGE_MASK; | ||
| 444 | if (end > 0xffff) { | ||
| 445 | pci_write_config_word(dev, PCI_IO_BASE_UPPER16, | ||
| 446 | start >> 16); | ||
| 447 | pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16, | ||
| 448 | end >> 16); | ||
| 449 | io_base_lo |= PCI_IO_RANGE_TYPE_32; | ||
| 450 | } else | ||
| 451 | io_base_lo |= PCI_IO_RANGE_TYPE_16; | ||
| 452 | pci_write_config_byte(dev, PCI_IO_BASE, io_base_lo); | ||
| 453 | pci_write_config_byte(dev, PCI_IO_LIMIT, io_limit_lo); | ||
| 454 | |||
| 455 | } else if ((res->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH)) | ||
| 456 | == IORESOURCE_MEM) { | ||
| 457 | off = hose->pci_mem_offset; | ||
| 458 | mem_base = ((res->start - off) >> 16) & PCI_MEMORY_RANGE_MASK; | ||
| 459 | mem_limit = ((res->end - off) >> 16) & PCI_MEMORY_RANGE_MASK; | ||
| 460 | pci_write_config_word(dev, PCI_MEMORY_BASE, mem_base); | ||
| 461 | pci_write_config_word(dev, PCI_MEMORY_LIMIT, mem_limit); | ||
| 462 | |||
| 463 | } else if ((res->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH)) | ||
| 464 | == (IORESOURCE_MEM | IORESOURCE_PREFETCH)) { | ||
| 465 | off = hose->pci_mem_offset; | ||
| 466 | mem_base = ((res->start - off) >> 16) & PCI_PREF_RANGE_MASK; | ||
| 467 | mem_limit = ((res->end - off) >> 16) & PCI_PREF_RANGE_MASK; | ||
| 468 | pci_write_config_word(dev, PCI_PREF_MEMORY_BASE, mem_base); | ||
| 469 | pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT, mem_limit); | ||
| 470 | |||
| 471 | } else { | ||
| 472 | DBG(KERN_ERR "PCI: ugh, bridge %s res %d has flags=%lx\n", | ||
| 473 | pci_name(dev), i, res->flags); | ||
| 474 | } | ||
| 475 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
| 476 | } | ||
| 477 | |||
| 478 | static inline void alloc_resource(struct pci_dev *dev, int idx) | ||
| 479 | { | ||
| 480 | struct resource *pr, *r = &dev->resource[idx]; | ||
| 481 | |||
| 482 | DBG("PCI:%s: Resource %d: %08lx-%08lx (f=%lx)\n", | ||
| 483 | pci_name(dev), idx, r->start, r->end, r->flags); | ||
| 484 | pr = pci_find_parent_resource(dev, r); | ||
| 485 | if (!pr || request_resource(pr, r) < 0) { | ||
| 486 | printk(KERN_ERR "PCI: Cannot allocate resource region %d" | ||
| 487 | " of device %s\n", idx, pci_name(dev)); | ||
| 488 | if (pr) | ||
| 489 | DBG("PCI: parent is %p: %08lx-%08lx (f=%lx)\n", | ||
| 490 | pr, pr->start, pr->end, pr->flags); | ||
| 491 | /* We'll assign a new address later */ | ||
| 492 | r->flags |= IORESOURCE_UNSET; | ||
| 493 | r->end -= r->start; | ||
| 494 | r->start = 0; | ||
| 495 | } | ||
| 496 | } | ||
| 497 | |||
| 498 | static void __init | ||
| 499 | pcibios_allocate_resources(int pass) | ||
| 500 | { | ||
| 501 | struct pci_dev *dev = NULL; | ||
| 502 | int idx, disabled; | ||
| 503 | u16 command; | ||
| 504 | struct resource *r; | ||
| 505 | |||
| 506 | for_each_pci_dev(dev) { | ||
| 507 | pci_read_config_word(dev, PCI_COMMAND, &command); | ||
| 508 | for (idx = 0; idx < 6; idx++) { | ||
| 509 | r = &dev->resource[idx]; | ||
| 510 | if (r->parent) /* Already allocated */ | ||
| 511 | continue; | ||
| 512 | if (!r->flags || (r->flags & IORESOURCE_UNSET)) | ||
| 513 | continue; /* Not assigned at all */ | ||
| 514 | if (r->flags & IORESOURCE_IO) | ||
| 515 | disabled = !(command & PCI_COMMAND_IO); | ||
| 516 | else | ||
| 517 | disabled = !(command & PCI_COMMAND_MEMORY); | ||
| 518 | if (pass == disabled) | ||
| 519 | alloc_resource(dev, idx); | ||
| 520 | } | ||
| 521 | if (pass) | ||
| 522 | continue; | ||
| 523 | r = &dev->resource[PCI_ROM_RESOURCE]; | ||
| 524 | if (r->flags & IORESOURCE_ROM_ENABLE) { | ||
| 525 | /* Turn the ROM off, leave the resource region, but keep it unregistered. */ | ||
| 526 | u32 reg; | ||
| 527 | DBG("PCI: Switching off ROM of %s\n", pci_name(dev)); | ||
| 528 | r->flags &= ~IORESOURCE_ROM_ENABLE; | ||
| 529 | pci_read_config_dword(dev, dev->rom_base_reg, ®); | ||
| 530 | pci_write_config_dword(dev, dev->rom_base_reg, | ||
| 531 | reg & ~PCI_ROM_ADDRESS_ENABLE); | ||
| 532 | } | ||
| 533 | } | ||
| 534 | } | ||
| 535 | |||
| 536 | static void __init | ||
| 537 | pcibios_assign_resources(void) | ||
| 538 | { | ||
| 539 | struct pci_dev *dev = NULL; | ||
| 540 | int idx; | ||
| 541 | struct resource *r; | ||
| 542 | |||
| 543 | for_each_pci_dev(dev) { | ||
| 544 | int class = dev->class >> 8; | ||
| 545 | |||
| 546 | /* Don't touch classless devices and host bridges */ | ||
| 547 | if (!class || class == PCI_CLASS_BRIDGE_HOST) | ||
| 548 | continue; | ||
| 549 | |||
| 550 | for (idx = 0; idx < 6; idx++) { | ||
| 551 | r = &dev->resource[idx]; | ||
| 552 | |||
| 553 | /* | ||
| 554 | * We shall assign a new address to this resource, | ||
| 555 | * either because the BIOS (sic) forgot to do so | ||
| 556 | * or because we have decided the old address was | ||
| 557 | * unusable for some reason. | ||
| 558 | */ | ||
| 559 | if ((r->flags & IORESOURCE_UNSET) && r->end && | ||
| 560 | (!ppc_md.pcibios_enable_device_hook || | ||
| 561 | !ppc_md.pcibios_enable_device_hook(dev, 1))) { | ||
| 562 | r->flags &= ~IORESOURCE_UNSET; | ||
| 563 | pci_assign_resource(dev, idx); | ||
| 564 | } | ||
| 565 | } | ||
| 566 | |||
| 567 | #if 0 /* don't assign ROMs */ | ||
| 568 | r = &dev->resource[PCI_ROM_RESOURCE]; | ||
| 569 | r->end -= r->start; | ||
| 570 | r->start = 0; | ||
| 571 | if (r->end) | ||
| 572 | pci_assign_resource(dev, PCI_ROM_RESOURCE); | ||
| 573 | #endif | ||
| 574 | } | ||
| 575 | } | ||
| 576 | |||
| 577 | |||
| 578 | int | ||
| 579 | pcibios_enable_resources(struct pci_dev *dev, int mask) | ||
| 580 | { | ||
| 581 | u16 cmd, old_cmd; | ||
| 582 | int idx; | ||
| 583 | struct resource *r; | ||
| 584 | |||
| 585 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
| 586 | old_cmd = cmd; | ||
| 587 | for (idx=0; idx<6; idx++) { | ||
| 588 | /* Only set up the requested stuff */ | ||
| 589 | if (!(mask & (1<<idx))) | ||
| 590 | continue; | ||
| 591 | |||
| 592 | r = &dev->resource[idx]; | ||
| 593 | if (r->flags & IORESOURCE_UNSET) { | ||
| 594 | printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev)); | ||
| 595 | return -EINVAL; | ||
| 596 | } | ||
| 597 | if (r->flags & IORESOURCE_IO) | ||
| 598 | cmd |= PCI_COMMAND_IO; | ||
| 599 | if (r->flags & IORESOURCE_MEM) | ||
| 600 | cmd |= PCI_COMMAND_MEMORY; | ||
| 601 | } | ||
| 602 | if (dev->resource[PCI_ROM_RESOURCE].start) | ||
| 603 | cmd |= PCI_COMMAND_MEMORY; | ||
| 604 | if (cmd != old_cmd) { | ||
| 605 | printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); | ||
| 606 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
| 607 | } | ||
| 608 | return 0; | ||
| 609 | } | ||
| 610 | |||
| 611 | static int next_controller_index; | ||
| 612 | |||
| 613 | struct pci_controller * __init | ||
| 614 | pcibios_alloc_controller(void) | ||
| 615 | { | ||
| 616 | struct pci_controller *hose; | ||
| 617 | |||
| 618 | hose = (struct pci_controller *)alloc_bootmem(sizeof(*hose)); | ||
| 619 | memset(hose, 0, sizeof(struct pci_controller)); | ||
| 620 | |||
| 621 | *hose_tail = hose; | ||
| 622 | hose_tail = &hose->next; | ||
| 623 | |||
| 624 | hose->index = next_controller_index++; | ||
| 625 | |||
| 626 | return hose; | ||
| 627 | } | ||
| 628 | |||
| 629 | #ifdef CONFIG_PPC_OF | ||
| 630 | /* | ||
| 631 | * Functions below are used on OpenFirmware machines. | ||
| 632 | */ | ||
| 633 | static void | ||
| 634 | make_one_node_map(struct device_node* node, u8 pci_bus) | ||
| 635 | { | ||
| 636 | int *bus_range; | ||
| 637 | int len; | ||
| 638 | |||
| 639 | if (pci_bus >= pci_bus_count) | ||
| 640 | return; | ||
| 641 | bus_range = (int *) get_property(node, "bus-range", &len); | ||
| 642 | if (bus_range == NULL || len < 2 * sizeof(int)) { | ||
| 643 | printk(KERN_WARNING "Can't get bus-range for %s, " | ||
| 644 | "assuming it starts at 0\n", node->full_name); | ||
| 645 | pci_to_OF_bus_map[pci_bus] = 0; | ||
| 646 | } else | ||
| 647 | pci_to_OF_bus_map[pci_bus] = bus_range[0]; | ||
| 648 | |||
| 649 | for (node=node->child; node != 0;node = node->sibling) { | ||
| 650 | struct pci_dev* dev; | ||
| 651 | unsigned int *class_code, *reg; | ||
| 652 | |||
| 653 | class_code = (unsigned int *) get_property(node, "class-code", NULL); | ||
| 654 | if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && | ||
| 655 | (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) | ||
| 656 | continue; | ||
| 657 | reg = (unsigned int *)get_property(node, "reg", NULL); | ||
| 658 | if (!reg) | ||
| 659 | continue; | ||
| 660 | dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff)); | ||
| 661 | if (!dev || !dev->subordinate) | ||
| 662 | continue; | ||
| 663 | make_one_node_map(node, dev->subordinate->number); | ||
| 664 | } | ||
| 665 | } | ||
| 666 | |||
| 667 | void | ||
| 668 | pcibios_make_OF_bus_map(void) | ||
| 669 | { | ||
| 670 | int i; | ||
| 671 | struct pci_controller* hose; | ||
| 672 | u8* of_prop_map; | ||
| 673 | |||
| 674 | pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL); | ||
| 675 | if (!pci_to_OF_bus_map) { | ||
| 676 | printk(KERN_ERR "Can't allocate OF bus map !\n"); | ||
| 677 | return; | ||
| 678 | } | ||
| 679 | |||
| 680 | /* We fill the bus map with invalid values, that helps | ||
| 681 | * debugging. | ||
| 682 | */ | ||
| 683 | for (i=0; i<pci_bus_count; i++) | ||
| 684 | pci_to_OF_bus_map[i] = 0xff; | ||
| 685 | |||
| 686 | /* For each hose, we begin searching bridges */ | ||
| 687 | for(hose=hose_head; hose; hose=hose->next) { | ||
| 688 | struct device_node* node; | ||
| 689 | node = (struct device_node *)hose->arch_data; | ||
| 690 | if (!node) | ||
| 691 | continue; | ||
| 692 | make_one_node_map(node, hose->first_busno); | ||
| 693 | } | ||
| 694 | of_prop_map = get_property(find_path_device("/"), "pci-OF-bus-map", NULL); | ||
| 695 | if (of_prop_map) | ||
| 696 | memcpy(of_prop_map, pci_to_OF_bus_map, pci_bus_count); | ||
| 697 | #ifdef DEBUG | ||
| 698 | printk("PCI->OF bus map:\n"); | ||
| 699 | for (i=0; i<pci_bus_count; i++) { | ||
| 700 | if (pci_to_OF_bus_map[i] == 0xff) | ||
| 701 | continue; | ||
| 702 | printk("%d -> %d\n", i, pci_to_OF_bus_map[i]); | ||
| 703 | } | ||
| 704 | #endif | ||
| 705 | } | ||
| 706 | |||
| 707 | typedef int (*pci_OF_scan_iterator)(struct device_node* node, void* data); | ||
| 708 | |||
| 709 | static struct device_node* | ||
| 710 | scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* data) | ||
| 711 | { | ||
| 712 | struct device_node* sub_node; | ||
| 713 | |||
| 714 | for (; node != 0;node = node->sibling) { | ||
| 715 | unsigned int *class_code; | ||
| 716 | |||
| 717 | if (filter(node, data)) | ||
| 718 | return node; | ||
| 719 | |||
| 720 | /* For PCI<->PCI bridges or CardBus bridges, we go down | ||
| 721 | * Note: some OFs create a parent node "multifunc-device" as | ||
| 722 | * a fake root for all functions of a multi-function device, | ||
| 723 | * we go down them as well. | ||
| 724 | */ | ||
| 725 | class_code = (unsigned int *) get_property(node, "class-code", NULL); | ||
| 726 | if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && | ||
| 727 | (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) && | ||
| 728 | strcmp(node->name, "multifunc-device")) | ||
| 729 | continue; | ||
| 730 | sub_node = scan_OF_pci_childs(node->child, filter, data); | ||
| 731 | if (sub_node) | ||
| 732 | return sub_node; | ||
| 733 | } | ||
| 734 | return NULL; | ||
| 735 | } | ||
| 736 | |||
| 737 | static int | ||
| 738 | scan_OF_pci_childs_iterator(struct device_node* node, void* data) | ||
| 739 | { | ||
| 740 | unsigned int *reg; | ||
| 741 | u8* fdata = (u8*)data; | ||
| 742 | |||
| 743 | reg = (unsigned int *) get_property(node, "reg", NULL); | ||
| 744 | if (reg && ((reg[0] >> 8) & 0xff) == fdata[1] | ||
| 745 | && ((reg[0] >> 16) & 0xff) == fdata[0]) | ||
| 746 | return 1; | ||
| 747 | return 0; | ||
| 748 | } | ||
| 749 | |||
| 750 | static struct device_node* | ||
| 751 | scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn) | ||
| 752 | { | ||
| 753 | u8 filter_data[2] = {bus, dev_fn}; | ||
| 754 | |||
| 755 | return scan_OF_pci_childs(node, scan_OF_pci_childs_iterator, filter_data); | ||
| 756 | } | ||
| 757 | |||
| 758 | /* | ||
| 759 | * Scans the OF tree for a device node matching a PCI device | ||
| 760 | */ | ||
| 761 | struct device_node * | ||
| 762 | pci_busdev_to_OF_node(struct pci_bus *bus, int devfn) | ||
| 763 | { | ||
| 764 | struct pci_controller *hose; | ||
| 765 | struct device_node *node; | ||
| 766 | int busnr; | ||
| 767 | |||
| 768 | if (!have_of) | ||
| 769 | return NULL; | ||
| 770 | |||
| 771 | /* Lookup the hose */ | ||
| 772 | busnr = bus->number; | ||
| 773 | hose = pci_bus_to_hose(busnr); | ||
| 774 | if (!hose) | ||
| 775 | return NULL; | ||
| 776 | |||
| 777 | /* Check it has an OF node associated */ | ||
| 778 | node = (struct device_node *) hose->arch_data; | ||
| 779 | if (!node) | ||
| 780 | return NULL; | ||
| 781 | |||
| 782 | /* Fixup bus number according to what OF think it is. */ | ||
| 783 | #ifdef CONFIG_PPC_PMAC | ||
| 784 | /* The G5 need a special case here. Basically, we don't remap all | ||
| 785 | * busses on it so we don't create the pci-OF-map. However, we do | ||
| 786 | * remap the AGP bus and so have to deal with it. A future better | ||
| 787 | * fix has to be done by making the remapping per-host and always | ||
| 788 | * filling the pci_to_OF map. --BenH | ||
| 789 | */ | ||
| 790 | if (_machine == _MACH_Pmac && busnr >= 0xf0) | ||
| 791 | busnr -= 0xf0; | ||
| 792 | else | ||
| 793 | #endif | ||
| 794 | if (pci_to_OF_bus_map) | ||
| 795 | busnr = pci_to_OF_bus_map[busnr]; | ||
| 796 | if (busnr == 0xff) | ||
| 797 | return NULL; | ||
| 798 | |||
| 799 | /* Now, lookup childs of the hose */ | ||
| 800 | return scan_OF_childs_for_device(node->child, busnr, devfn); | ||
| 801 | } | ||
| 802 | EXPORT_SYMBOL(pci_busdev_to_OF_node); | ||
| 803 | |||
| 804 | struct device_node* | ||
| 805 | pci_device_to_OF_node(struct pci_dev *dev) | ||
| 806 | { | ||
| 807 | return pci_busdev_to_OF_node(dev->bus, dev->devfn); | ||
| 808 | } | ||
| 809 | EXPORT_SYMBOL(pci_device_to_OF_node); | ||
| 810 | |||
| 811 | /* This routine is meant to be used early during boot, when the | ||
| 812 | * PCI bus numbers have not yet been assigned, and you need to | ||
| 813 | * issue PCI config cycles to an OF device. | ||
| 814 | * It could also be used to "fix" RTAS config cycles if you want | ||
| 815 | * to set pci_assign_all_buses to 1 and still use RTAS for PCI | ||
| 816 | * config cycles. | ||
| 817 | */ | ||
| 818 | struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node) | ||
| 819 | { | ||
| 820 | if (!have_of) | ||
| 821 | return NULL; | ||
| 822 | while(node) { | ||
| 823 | struct pci_controller* hose; | ||
| 824 | for (hose=hose_head;hose;hose=hose->next) | ||
| 825 | if (hose->arch_data == node) | ||
| 826 | return hose; | ||
| 827 | node=node->parent; | ||
| 828 | } | ||
| 829 | return NULL; | ||
| 830 | } | ||
| 831 | |||
| 832 | static int | ||
| 833 | find_OF_pci_device_filter(struct device_node* node, void* data) | ||
| 834 | { | ||
| 835 | return ((void *)node == data); | ||
| 836 | } | ||
| 837 | |||
| 838 | /* | ||
| 839 | * Returns the PCI device matching a given OF node | ||
| 840 | */ | ||
| 841 | int | ||
| 842 | pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn) | ||
| 843 | { | ||
| 844 | unsigned int *reg; | ||
| 845 | struct pci_controller* hose; | ||
| 846 | struct pci_dev* dev = NULL; | ||
| 847 | |||
| 848 | if (!have_of) | ||
| 849 | return -ENODEV; | ||
| 850 | /* Make sure it's really a PCI device */ | ||
| 851 | hose = pci_find_hose_for_OF_device(node); | ||
| 852 | if (!hose || !hose->arch_data) | ||
| 853 | return -ENODEV; | ||
| 854 | if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child, | ||
| 855 | find_OF_pci_device_filter, (void *)node)) | ||
| 856 | return -ENODEV; | ||
| 857 | reg = (unsigned int *) get_property(node, "reg", NULL); | ||
| 858 | if (!reg) | ||
| 859 | return -ENODEV; | ||
| 860 | *bus = (reg[0] >> 16) & 0xff; | ||
| 861 | *devfn = ((reg[0] >> 8) & 0xff); | ||
| 862 | |||
| 863 | /* Ok, here we need some tweak. If we have already renumbered | ||
| 864 | * all busses, we can't rely on the OF bus number any more. | ||
| 865 | * the pci_to_OF_bus_map is not enough as several PCI busses | ||
| 866 | * may match the same OF bus number. | ||
| 867 | */ | ||
| 868 | if (!pci_to_OF_bus_map) | ||
| 869 | return 0; | ||
| 870 | |||
| 871 | for_each_pci_dev(dev) | ||
| 872 | if (pci_to_OF_bus_map[dev->bus->number] == *bus && | ||
| 873 | dev->devfn == *devfn) { | ||
| 874 | *bus = dev->bus->number; | ||
| 875 | pci_dev_put(dev); | ||
| 876 | return 0; | ||
| 877 | } | ||
| 878 | |||
| 879 | return -ENODEV; | ||
| 880 | } | ||
| 881 | EXPORT_SYMBOL(pci_device_from_OF_node); | ||
| 882 | |||
| 883 | void __init | ||
| 884 | pci_process_bridge_OF_ranges(struct pci_controller *hose, | ||
| 885 | struct device_node *dev, int primary) | ||
| 886 | { | ||
| 887 | static unsigned int static_lc_ranges[256] __initdata; | ||
| 888 | unsigned int *dt_ranges, *lc_ranges, *ranges, *prev; | ||
| 889 | unsigned int size; | ||
| 890 | int rlen = 0, orig_rlen; | ||
| 891 | int memno = 0; | ||
| 892 | struct resource *res; | ||
| 893 | int np, na = prom_n_addr_cells(dev); | ||
| 894 | np = na + 5; | ||
| 895 | |||
| 896 | /* First we try to merge ranges to fix a problem with some pmacs | ||
| 897 | * that can have more than 3 ranges, fortunately using contiguous | ||
| 898 | * addresses -- BenH | ||
| 899 | */ | ||
| 900 | dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen); | ||
| 901 | if (!dt_ranges) | ||
| 902 | return; | ||
| 903 | /* Sanity check, though hopefully that never happens */ | ||
| 904 | if (rlen > sizeof(static_lc_ranges)) { | ||
| 905 | printk(KERN_WARNING "OF ranges property too large !\n"); | ||
| 906 | rlen = sizeof(static_lc_ranges); | ||
| 907 | } | ||
| 908 | lc_ranges = static_lc_ranges; | ||
| 909 | memcpy(lc_ranges, dt_ranges, rlen); | ||
| 910 | orig_rlen = rlen; | ||
| 911 | |||
| 912 | /* Let's work on a copy of the "ranges" property instead of damaging | ||
| 913 | * the device-tree image in memory | ||
| 914 | */ | ||
| 915 | ranges = lc_ranges; | ||
| 916 | prev = NULL; | ||
| 917 | while ((rlen -= np * sizeof(unsigned int)) >= 0) { | ||
| 918 | if (prev) { | ||
| 919 | if (prev[0] == ranges[0] && prev[1] == ranges[1] && | ||
| 920 | (prev[2] + prev[na+4]) == ranges[2] && | ||
| 921 | (prev[na+2] + prev[na+4]) == ranges[na+2]) { | ||
| 922 | prev[na+4] += ranges[na+4]; | ||
| 923 | ranges[0] = 0; | ||
| 924 | ranges += np; | ||
| 925 | continue; | ||
| 926 | } | ||
| 927 | } | ||
| 928 | prev = ranges; | ||
| 929 | ranges += np; | ||
| 930 | } | ||
| 931 | |||
| 932 | /* | ||
| 933 | * The ranges property is laid out as an array of elements, | ||
| 934 | * each of which comprises: | ||
| 935 | * cells 0 - 2: a PCI address | ||
| 936 | * cells 3 or 3+4: a CPU physical address | ||
| 937 | * (size depending on dev->n_addr_cells) | ||
| 938 | * cells 4+5 or 5+6: the size of the range | ||
| 939 | */ | ||
| 940 | ranges = lc_ranges; | ||
| 941 | rlen = orig_rlen; | ||
| 942 | while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) { | ||
| 943 | res = NULL; | ||
| 944 | size = ranges[na+4]; | ||
| 945 | switch ((ranges[0] >> 24) & 0x3) { | ||
| 946 | case 1: /* I/O space */ | ||
| 947 | if (ranges[2] != 0) | ||
| 948 | break; | ||
| 949 | hose->io_base_phys = ranges[na+2]; | ||
| 950 | /* limit I/O space to 16MB */ | ||
| 951 | if (size > 0x01000000) | ||
| 952 | size = 0x01000000; | ||
| 953 | hose->io_base_virt = ioremap(ranges[na+2], size); | ||
| 954 | if (primary) | ||
| 955 | isa_io_base = (unsigned long) hose->io_base_virt; | ||
| 956 | res = &hose->io_resource; | ||
| 957 | res->flags = IORESOURCE_IO; | ||
| 958 | res->start = ranges[2]; | ||
| 959 | DBG("PCI: IO 0x%lx -> 0x%lx\n", | ||
| 960 | res->start, res->start + size - 1); | ||
| 961 | break; | ||
| 962 | case 2: /* memory space */ | ||
| 963 | memno = 0; | ||
| 964 | if (ranges[1] == 0 && ranges[2] == 0 | ||
| 965 | && ranges[na+4] <= (16 << 20)) { | ||
| 966 | /* 1st 16MB, i.e. ISA memory area */ | ||
| 967 | if (primary) | ||
| 968 | isa_mem_base = ranges[na+2]; | ||
| 969 | memno = 1; | ||
| 970 | } | ||
| 971 | while (memno < 3 && hose->mem_resources[memno].flags) | ||
| 972 | ++memno; | ||
| 973 | if (memno == 0) | ||
| 974 | hose->pci_mem_offset = ranges[na+2] - ranges[2]; | ||
| 975 | if (memno < 3) { | ||
| 976 | res = &hose->mem_resources[memno]; | ||
| 977 | res->flags = IORESOURCE_MEM; | ||
| 978 | if(ranges[0] & 0x40000000) | ||
| 979 | res->flags |= IORESOURCE_PREFETCH; | ||
| 980 | res->start = ranges[na+2]; | ||
| 981 | DBG("PCI: MEM[%d] 0x%lx -> 0x%lx\n", memno, | ||
| 982 | res->start, res->start + size - 1); | ||
| 983 | } | ||
| 984 | break; | ||
| 985 | } | ||
| 986 | if (res != NULL) { | ||
| 987 | res->name = dev->full_name; | ||
| 988 | res->end = res->start + size - 1; | ||
| 989 | res->parent = NULL; | ||
| 990 | res->sibling = NULL; | ||
| 991 | res->child = NULL; | ||
| 992 | } | ||
| 993 | ranges += np; | ||
| 994 | } | ||
| 995 | } | ||
| 996 | |||
| 997 | /* We create the "pci-OF-bus-map" property now so it appears in the | ||
| 998 | * /proc device tree | ||
| 999 | */ | ||
| 1000 | void __init | ||
| 1001 | pci_create_OF_bus_map(void) | ||
| 1002 | { | ||
| 1003 | struct property* of_prop; | ||
| 1004 | |||
| 1005 | of_prop = (struct property*) alloc_bootmem(sizeof(struct property) + 256); | ||
| 1006 | if (of_prop && find_path_device("/")) { | ||
| 1007 | memset(of_prop, -1, sizeof(struct property) + 256); | ||
| 1008 | of_prop->name = "pci-OF-bus-map"; | ||
| 1009 | of_prop->length = 256; | ||
| 1010 | of_prop->value = (unsigned char *)&of_prop[1]; | ||
| 1011 | prom_add_property(find_path_device("/"), of_prop); | ||
| 1012 | } | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 1016 | { | ||
| 1017 | struct pci_dev *pdev; | ||
| 1018 | struct device_node *np; | ||
| 1019 | |||
| 1020 | pdev = to_pci_dev (dev); | ||
| 1021 | np = pci_device_to_OF_node(pdev); | ||
| 1022 | if (np == NULL || np->full_name == NULL) | ||
| 1023 | return 0; | ||
| 1024 | return sprintf(buf, "%s", np->full_name); | ||
| 1025 | } | ||
| 1026 | static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL); | ||
| 1027 | |||
| 1028 | #else /* CONFIG_PPC_OF */ | ||
| 1029 | void pcibios_make_OF_bus_map(void) | ||
| 1030 | { | ||
| 1031 | } | ||
| 1032 | #endif /* CONFIG_PPC_OF */ | ||
| 1033 | |||
| 1034 | /* Add sysfs properties */ | ||
| 1035 | void pcibios_add_platform_entries(struct pci_dev *pdev) | ||
| 1036 | { | ||
| 1037 | #ifdef CONFIG_PPC_OF | ||
| 1038 | device_create_file(&pdev->dev, &dev_attr_devspec); | ||
| 1039 | #endif /* CONFIG_PPC_OF */ | ||
| 1040 | } | ||
| 1041 | |||
| 1042 | |||
| 1043 | #ifdef CONFIG_PPC_PMAC | ||
| 1044 | /* | ||
| 1045 | * This set of routines checks for PCI<->PCI bridges that have closed | ||
| 1046 | * IO resources and have child devices. It tries to re-open an IO | ||
| 1047 | * window on them. | ||
| 1048 | * | ||
| 1049 | * This is a _temporary_ fix to workaround a problem with Apple's OF | ||
| 1050 | * closing IO windows on P2P bridges when the OF drivers of cards | ||
| 1051 | * below this bridge don't claim any IO range (typically ATI or | ||
| 1052 | * Adaptec). | ||
| 1053 | * | ||
| 1054 | * A more complete fix would be to use drivers/pci/setup-bus.c, which | ||
| 1055 | * involves a working pcibios_fixup_pbus_ranges(), some more care about | ||
| 1056 | * ordering when creating the host bus resources, and maybe a few more | ||
| 1057 | * minor tweaks | ||
| 1058 | */ | ||
| 1059 | |||
| 1060 | /* Initialize bridges with base/limit values we have collected */ | ||
| 1061 | static void __init | ||
| 1062 | do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga) | ||
| 1063 | { | ||
| 1064 | struct pci_dev *bridge = bus->self; | ||
| 1065 | struct pci_controller* hose = (struct pci_controller *)bridge->sysdata; | ||
| 1066 | u32 l; | ||
| 1067 | u16 w; | ||
| 1068 | struct resource res; | ||
| 1069 | |||
| 1070 | if (bus->resource[0] == NULL) | ||
| 1071 | return; | ||
| 1072 | res = *(bus->resource[0]); | ||
| 1073 | |||
| 1074 | DBG("Remapping Bus %d, bridge: %s\n", bus->number, pci_name(bridge)); | ||
| 1075 | res.start -= ((unsigned long) hose->io_base_virt - isa_io_base); | ||
| 1076 | res.end -= ((unsigned long) hose->io_base_virt - isa_io_base); | ||
| 1077 | DBG(" IO window: %08lx-%08lx\n", res.start, res.end); | ||
| 1078 | |||
| 1079 | /* Set up the top and bottom of the PCI I/O segment for this bus. */ | ||
| 1080 | pci_read_config_dword(bridge, PCI_IO_BASE, &l); | ||
| 1081 | l &= 0xffff000f; | ||
| 1082 | l |= (res.start >> 8) & 0x00f0; | ||
| 1083 | l |= res.end & 0xf000; | ||
| 1084 | pci_write_config_dword(bridge, PCI_IO_BASE, l); | ||
| 1085 | |||
| 1086 | if ((l & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) { | ||
| 1087 | l = (res.start >> 16) | (res.end & 0xffff0000); | ||
| 1088 | pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, l); | ||
| 1089 | } | ||
| 1090 | |||
| 1091 | pci_read_config_word(bridge, PCI_COMMAND, &w); | ||
| 1092 | w |= PCI_COMMAND_IO; | ||
| 1093 | pci_write_config_word(bridge, PCI_COMMAND, w); | ||
| 1094 | |||
| 1095 | #if 0 /* Enabling this causes XFree 4.2.0 to hang during PCI probe */ | ||
| 1096 | if (enable_vga) { | ||
| 1097 | pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &w); | ||
| 1098 | w |= PCI_BRIDGE_CTL_VGA; | ||
| 1099 | pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, w); | ||
| 1100 | } | ||
| 1101 | #endif | ||
| 1102 | } | ||
| 1103 | |||
| 1104 | /* This function is pretty basic and actually quite broken for the | ||
| 1105 | * general case, it's enough for us right now though. It's supposed | ||
| 1106 | * to tell us if we need to open an IO range at all or not and what | ||
| 1107 | * size. | ||
| 1108 | */ | ||
| 1109 | static int __init | ||
| 1110 | check_for_io_childs(struct pci_bus *bus, struct resource* res, int *found_vga) | ||
| 1111 | { | ||
| 1112 | struct pci_dev *dev; | ||
| 1113 | int i; | ||
| 1114 | int rc = 0; | ||
| 1115 | |||
| 1116 | #define push_end(res, size) do { unsigned long __sz = (size) ; \ | ||
| 1117 | res->end = ((res->end + __sz) / (__sz + 1)) * (__sz + 1) + __sz; \ | ||
| 1118 | } while (0) | ||
| 1119 | |||
| 1120 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
| 1121 | u16 class = dev->class >> 8; | ||
| 1122 | |||
| 1123 | if (class == PCI_CLASS_DISPLAY_VGA || | ||
| 1124 | class == PCI_CLASS_NOT_DEFINED_VGA) | ||
| 1125 | *found_vga = 1; | ||
| 1126 | if (class >> 8 == PCI_BASE_CLASS_BRIDGE && dev->subordinate) | ||
| 1127 | rc |= check_for_io_childs(dev->subordinate, res, found_vga); | ||
| 1128 | if (class == PCI_CLASS_BRIDGE_CARDBUS) | ||
| 1129 | push_end(res, 0xfff); | ||
| 1130 | |||
| 1131 | for (i=0; i<PCI_NUM_RESOURCES; i++) { | ||
| 1132 | struct resource *r; | ||
| 1133 | unsigned long r_size; | ||
| 1134 | |||
| 1135 | if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI | ||
| 1136 | && i >= PCI_BRIDGE_RESOURCES) | ||
| 1137 | continue; | ||
| 1138 | r = &dev->resource[i]; | ||
| 1139 | r_size = r->end - r->start; | ||
| 1140 | if (r_size < 0xfff) | ||
| 1141 | r_size = 0xfff; | ||
| 1142 | if (r->flags & IORESOURCE_IO && (r_size) != 0) { | ||
| 1143 | rc = 1; | ||
| 1144 | push_end(res, r_size); | ||
| 1145 | } | ||
| 1146 | } | ||
| 1147 | } | ||
| 1148 | |||
| 1149 | return rc; | ||
| 1150 | } | ||
| 1151 | |||
| 1152 | /* Here we scan all P2P bridges of a given level that have a closed | ||
| 1153 | * IO window. Note that the test for the presence of a VGA card should | ||
| 1154 | * be improved to take into account already configured P2P bridges, | ||
| 1155 | * currently, we don't see them and might end up configuring 2 bridges | ||
| 1156 | * with VGA pass through enabled | ||
| 1157 | */ | ||
| 1158 | static void __init | ||
| 1159 | do_fixup_p2p_level(struct pci_bus *bus) | ||
| 1160 | { | ||
| 1161 | struct pci_bus *b; | ||
| 1162 | int i, parent_io; | ||
| 1163 | int has_vga = 0; | ||
| 1164 | |||
| 1165 | for (parent_io=0; parent_io<4; parent_io++) | ||
| 1166 | if (bus->resource[parent_io] | ||
| 1167 | && bus->resource[parent_io]->flags & IORESOURCE_IO) | ||
| 1168 | break; | ||
| 1169 | if (parent_io >= 4) | ||
| 1170 | return; | ||
| 1171 | |||
| 1172 | list_for_each_entry(b, &bus->children, node) { | ||
| 1173 | struct pci_dev *d = b->self; | ||
| 1174 | struct pci_controller* hose = (struct pci_controller *)d->sysdata; | ||
| 1175 | struct resource *res = b->resource[0]; | ||
| 1176 | struct resource tmp_res; | ||
| 1177 | unsigned long max; | ||
| 1178 | int found_vga = 0; | ||
| 1179 | |||
| 1180 | memset(&tmp_res, 0, sizeof(tmp_res)); | ||
| 1181 | tmp_res.start = bus->resource[parent_io]->start; | ||
| 1182 | |||
| 1183 | /* We don't let low addresses go through that closed P2P bridge, well, | ||
| 1184 | * that may not be necessary but I feel safer that way | ||
| 1185 | */ | ||
| 1186 | if (tmp_res.start == 0) | ||
| 1187 | tmp_res.start = 0x1000; | ||
| 1188 | |||
| 1189 | if (!list_empty(&b->devices) && res && res->flags == 0 && | ||
| 1190 | res != bus->resource[parent_io] && | ||
| 1191 | (d->class >> 8) == PCI_CLASS_BRIDGE_PCI && | ||
| 1192 | check_for_io_childs(b, &tmp_res, &found_vga)) { | ||
| 1193 | u8 io_base_lo; | ||
| 1194 | |||
| 1195 | printk(KERN_INFO "Fixing up IO bus %s\n", b->name); | ||
| 1196 | |||
| 1197 | if (found_vga) { | ||
| 1198 | if (has_vga) { | ||
| 1199 | printk(KERN_WARNING "Skipping VGA, already active" | ||
| 1200 | " on bus segment\n"); | ||
| 1201 | found_vga = 0; | ||
| 1202 | } else | ||
| 1203 | has_vga = 1; | ||
| 1204 | } | ||
| 1205 | pci_read_config_byte(d, PCI_IO_BASE, &io_base_lo); | ||
| 1206 | |||
| 1207 | if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) | ||
| 1208 | max = ((unsigned long) hose->io_base_virt | ||
| 1209 | - isa_io_base) + 0xffffffff; | ||
| 1210 | else | ||
| 1211 | max = ((unsigned long) hose->io_base_virt | ||
| 1212 | - isa_io_base) + 0xffff; | ||
| 1213 | |||
| 1214 | *res = tmp_res; | ||
| 1215 | res->flags = IORESOURCE_IO; | ||
| 1216 | res->name = b->name; | ||
| 1217 | |||
| 1218 | /* Find a resource in the parent where we can allocate */ | ||
| 1219 | for (i = 0 ; i < 4; i++) { | ||
| 1220 | struct resource *r = bus->resource[i]; | ||
| 1221 | if (!r) | ||
| 1222 | continue; | ||
| 1223 | if ((r->flags & IORESOURCE_IO) == 0) | ||
| 1224 | continue; | ||
| 1225 | DBG("Trying to allocate from %08lx, size %08lx from parent" | ||
| 1226 | " res %d: %08lx -> %08lx\n", | ||
| 1227 | res->start, res->end, i, r->start, r->end); | ||
| 1228 | |||
| 1229 | if (allocate_resource(r, res, res->end + 1, res->start, max, | ||
| 1230 | res->end + 1, NULL, NULL) < 0) { | ||
| 1231 | DBG("Failed !\n"); | ||
| 1232 | continue; | ||
| 1233 | } | ||
| 1234 | do_update_p2p_io_resource(b, found_vga); | ||
| 1235 | break; | ||
| 1236 | } | ||
| 1237 | } | ||
| 1238 | do_fixup_p2p_level(b); | ||
| 1239 | } | ||
| 1240 | } | ||
| 1241 | |||
| 1242 | static void | ||
| 1243 | pcibios_fixup_p2p_bridges(void) | ||
| 1244 | { | ||
| 1245 | struct pci_bus *b; | ||
| 1246 | |||
| 1247 | list_for_each_entry(b, &pci_root_buses, node) | ||
| 1248 | do_fixup_p2p_level(b); | ||
| 1249 | } | ||
| 1250 | |||
| 1251 | #endif /* CONFIG_PPC_PMAC */ | ||
| 1252 | |||
| 1253 | static int __init | ||
| 1254 | pcibios_init(void) | ||
| 1255 | { | ||
| 1256 | struct pci_controller *hose; | ||
| 1257 | struct pci_bus *bus; | ||
| 1258 | int next_busno; | ||
| 1259 | |||
| 1260 | printk(KERN_INFO "PCI: Probing PCI hardware\n"); | ||
| 1261 | |||
| 1262 | /* Scan all of the recorded PCI controllers. */ | ||
| 1263 | for (next_busno = 0, hose = hose_head; hose; hose = hose->next) { | ||
| 1264 | if (pci_assign_all_buses) | ||
| 1265 | hose->first_busno = next_busno; | ||
| 1266 | hose->last_busno = 0xff; | ||
| 1267 | bus = pci_scan_bus(hose->first_busno, hose->ops, hose); | ||
| 1268 | hose->last_busno = bus->subordinate; | ||
| 1269 | if (pci_assign_all_buses || next_busno <= hose->last_busno) | ||
| 1270 | next_busno = hose->last_busno + pcibios_assign_bus_offset; | ||
| 1271 | } | ||
| 1272 | pci_bus_count = next_busno; | ||
| 1273 | |||
| 1274 | /* OpenFirmware based machines need a map of OF bus | ||
| 1275 | * numbers vs. kernel bus numbers since we may have to | ||
| 1276 | * remap them. | ||
| 1277 | */ | ||
| 1278 | if (pci_assign_all_buses && have_of) | ||
| 1279 | pcibios_make_OF_bus_map(); | ||
| 1280 | |||
| 1281 | /* Do machine dependent PCI interrupt routing */ | ||
| 1282 | if (ppc_md.pci_swizzle && ppc_md.pci_map_irq) | ||
| 1283 | pci_fixup_irqs(ppc_md.pci_swizzle, ppc_md.pci_map_irq); | ||
| 1284 | |||
| 1285 | /* Call machine dependent fixup */ | ||
| 1286 | if (ppc_md.pcibios_fixup) | ||
| 1287 | ppc_md.pcibios_fixup(); | ||
| 1288 | |||
| 1289 | /* Allocate and assign resources */ | ||
| 1290 | pcibios_allocate_bus_resources(&pci_root_buses); | ||
| 1291 | pcibios_allocate_resources(0); | ||
| 1292 | pcibios_allocate_resources(1); | ||
| 1293 | #ifdef CONFIG_PPC_PMAC | ||
| 1294 | pcibios_fixup_p2p_bridges(); | ||
| 1295 | #endif /* CONFIG_PPC_PMAC */ | ||
| 1296 | pcibios_assign_resources(); | ||
| 1297 | |||
| 1298 | /* Call machine dependent post-init code */ | ||
| 1299 | if (ppc_md.pcibios_after_init) | ||
| 1300 | ppc_md.pcibios_after_init(); | ||
| 1301 | |||
| 1302 | return 0; | ||
| 1303 | } | ||
| 1304 | |||
| 1305 | subsys_initcall(pcibios_init); | ||
| 1306 | |||
| 1307 | unsigned char __init | ||
| 1308 | common_swizzle(struct pci_dev *dev, unsigned char *pinp) | ||
| 1309 | { | ||
| 1310 | struct pci_controller *hose = dev->sysdata; | ||
| 1311 | |||
| 1312 | if (dev->bus->number != hose->first_busno) { | ||
| 1313 | u8 pin = *pinp; | ||
| 1314 | do { | ||
| 1315 | pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)); | ||
| 1316 | /* Move up the chain of bridges. */ | ||
| 1317 | dev = dev->bus->self; | ||
| 1318 | } while (dev->bus->self); | ||
| 1319 | *pinp = pin; | ||
| 1320 | |||
| 1321 | /* The slot is the idsel of the last bridge. */ | ||
| 1322 | } | ||
| 1323 | return PCI_SLOT(dev->devfn); | ||
| 1324 | } | ||
| 1325 | |||
| 1326 | unsigned long resource_fixup(struct pci_dev * dev, struct resource * res, | ||
| 1327 | unsigned long start, unsigned long size) | ||
| 1328 | { | ||
| 1329 | return start; | ||
| 1330 | } | ||
| 1331 | |||
| 1332 | void __init pcibios_fixup_bus(struct pci_bus *bus) | ||
| 1333 | { | ||
| 1334 | struct pci_controller *hose = (struct pci_controller *) bus->sysdata; | ||
| 1335 | unsigned long io_offset; | ||
| 1336 | struct resource *res; | ||
| 1337 | int i; | ||
| 1338 | |||
| 1339 | io_offset = (unsigned long)hose->io_base_virt - isa_io_base; | ||
| 1340 | if (bus->parent == NULL) { | ||
| 1341 | /* This is a host bridge - fill in its resources */ | ||
| 1342 | hose->bus = bus; | ||
| 1343 | |||
| 1344 | bus->resource[0] = res = &hose->io_resource; | ||
| 1345 | if (!res->flags) { | ||
| 1346 | if (io_offset) | ||
| 1347 | printk(KERN_ERR "I/O resource not set for host" | ||
| 1348 | " bridge %d\n", hose->index); | ||
| 1349 | res->start = 0; | ||
| 1350 | res->end = IO_SPACE_LIMIT; | ||
| 1351 | res->flags = IORESOURCE_IO; | ||
| 1352 | } | ||
| 1353 | res->start += io_offset; | ||
| 1354 | res->end += io_offset; | ||
| 1355 | |||
| 1356 | for (i = 0; i < 3; ++i) { | ||
| 1357 | res = &hose->mem_resources[i]; | ||
| 1358 | if (!res->flags) { | ||
| 1359 | if (i > 0) | ||
| 1360 | continue; | ||
| 1361 | printk(KERN_ERR "Memory resource not set for " | ||
| 1362 | "host bridge %d\n", hose->index); | ||
| 1363 | res->start = hose->pci_mem_offset; | ||
| 1364 | res->end = ~0U; | ||
| 1365 | res->flags = IORESOURCE_MEM; | ||
| 1366 | } | ||
| 1367 | bus->resource[i+1] = res; | ||
| 1368 | } | ||
| 1369 | } else { | ||
| 1370 | /* This is a subordinate bridge */ | ||
| 1371 | pci_read_bridge_bases(bus); | ||
| 1372 | |||
| 1373 | for (i = 0; i < 4; ++i) { | ||
| 1374 | if ((res = bus->resource[i]) == NULL) | ||
| 1375 | continue; | ||
| 1376 | if (!res->flags) | ||
| 1377 | continue; | ||
| 1378 | if (io_offset && (res->flags & IORESOURCE_IO)) { | ||
| 1379 | res->start += io_offset; | ||
| 1380 | res->end += io_offset; | ||
| 1381 | } else if (hose->pci_mem_offset | ||
| 1382 | && (res->flags & IORESOURCE_MEM)) { | ||
| 1383 | res->start += hose->pci_mem_offset; | ||
| 1384 | res->end += hose->pci_mem_offset; | ||
| 1385 | } | ||
| 1386 | } | ||
| 1387 | } | ||
| 1388 | |||
| 1389 | if (ppc_md.pcibios_fixup_bus) | ||
| 1390 | ppc_md.pcibios_fixup_bus(bus); | ||
| 1391 | } | ||
| 1392 | |||
| 1393 | char __init *pcibios_setup(char *str) | ||
| 1394 | { | ||
| 1395 | return str; | ||
| 1396 | } | ||
| 1397 | |||
| 1398 | /* the next one is stolen from the alpha port... */ | ||
| 1399 | void __init | ||
| 1400 | pcibios_update_irq(struct pci_dev *dev, int irq) | ||
| 1401 | { | ||
| 1402 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); | ||
| 1403 | /* XXX FIXME - update OF device tree node interrupt property */ | ||
| 1404 | } | ||
| 1405 | |||
| 1406 | int pcibios_enable_device(struct pci_dev *dev, int mask) | ||
| 1407 | { | ||
| 1408 | u16 cmd, old_cmd; | ||
| 1409 | int idx; | ||
| 1410 | struct resource *r; | ||
| 1411 | |||
| 1412 | if (ppc_md.pcibios_enable_device_hook) | ||
| 1413 | if (ppc_md.pcibios_enable_device_hook(dev, 0)) | ||
| 1414 | return -EINVAL; | ||
| 1415 | |||
| 1416 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
| 1417 | old_cmd = cmd; | ||
| 1418 | for (idx=0; idx<6; idx++) { | ||
| 1419 | r = &dev->resource[idx]; | ||
| 1420 | if (r->flags & IORESOURCE_UNSET) { | ||
| 1421 | printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev)); | ||
| 1422 | return -EINVAL; | ||
| 1423 | } | ||
| 1424 | if (r->flags & IORESOURCE_IO) | ||
| 1425 | cmd |= PCI_COMMAND_IO; | ||
| 1426 | if (r->flags & IORESOURCE_MEM) | ||
| 1427 | cmd |= PCI_COMMAND_MEMORY; | ||
| 1428 | } | ||
| 1429 | if (cmd != old_cmd) { | ||
| 1430 | printk("PCI: Enabling device %s (%04x -> %04x)\n", | ||
| 1431 | pci_name(dev), old_cmd, cmd); | ||
| 1432 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
| 1433 | } | ||
| 1434 | return 0; | ||
| 1435 | } | ||
| 1436 | |||
| 1437 | struct pci_controller* | ||
| 1438 | pci_bus_to_hose(int bus) | ||
| 1439 | { | ||
| 1440 | struct pci_controller* hose = hose_head; | ||
| 1441 | |||
| 1442 | for (; hose; hose = hose->next) | ||
| 1443 | if (bus >= hose->first_busno && bus <= hose->last_busno) | ||
| 1444 | return hose; | ||
| 1445 | return NULL; | ||
| 1446 | } | ||
| 1447 | |||
| 1448 | void __iomem * | ||
| 1449 | pci_bus_io_base(unsigned int bus) | ||
| 1450 | { | ||
| 1451 | struct pci_controller *hose; | ||
| 1452 | |||
| 1453 | hose = pci_bus_to_hose(bus); | ||
| 1454 | if (!hose) | ||
| 1455 | return NULL; | ||
| 1456 | return hose->io_base_virt; | ||
| 1457 | } | ||
| 1458 | |||
| 1459 | unsigned long | ||
| 1460 | pci_bus_io_base_phys(unsigned int bus) | ||
| 1461 | { | ||
| 1462 | struct pci_controller *hose; | ||
| 1463 | |||
| 1464 | hose = pci_bus_to_hose(bus); | ||
| 1465 | if (!hose) | ||
| 1466 | return 0; | ||
| 1467 | return hose->io_base_phys; | ||
| 1468 | } | ||
| 1469 | |||
| 1470 | unsigned long | ||
| 1471 | pci_bus_mem_base_phys(unsigned int bus) | ||
| 1472 | { | ||
| 1473 | struct pci_controller *hose; | ||
| 1474 | |||
| 1475 | hose = pci_bus_to_hose(bus); | ||
| 1476 | if (!hose) | ||
| 1477 | return 0; | ||
| 1478 | return hose->pci_mem_offset; | ||
| 1479 | } | ||
| 1480 | |||
| 1481 | unsigned long | ||
| 1482 | pci_resource_to_bus(struct pci_dev *pdev, struct resource *res) | ||
| 1483 | { | ||
| 1484 | /* Hack alert again ! See comments in chrp_pci.c | ||
| 1485 | */ | ||
| 1486 | struct pci_controller* hose = | ||
| 1487 | (struct pci_controller *)pdev->sysdata; | ||
| 1488 | if (hose && res->flags & IORESOURCE_MEM) | ||
| 1489 | return res->start - hose->pci_mem_offset; | ||
| 1490 | /* We may want to do something with IOs here... */ | ||
| 1491 | return res->start; | ||
| 1492 | } | ||
| 1493 | |||
| 1494 | |||
| 1495 | static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, | ||
| 1496 | unsigned long *offset, | ||
| 1497 | enum pci_mmap_state mmap_state) | ||
| 1498 | { | ||
| 1499 | struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); | ||
| 1500 | unsigned long io_offset = 0; | ||
| 1501 | int i, res_bit; | ||
| 1502 | |||
| 1503 | if (hose == 0) | ||
| 1504 | return NULL; /* should never happen */ | ||
| 1505 | |||
| 1506 | /* If memory, add on the PCI bridge address offset */ | ||
| 1507 | if (mmap_state == pci_mmap_mem) { | ||
| 1508 | *offset += hose->pci_mem_offset; | ||
| 1509 | res_bit = IORESOURCE_MEM; | ||
| 1510 | } else { | ||
| 1511 | io_offset = hose->io_base_virt - ___IO_BASE; | ||
| 1512 | *offset += io_offset; | ||
| 1513 | res_bit = IORESOURCE_IO; | ||
| 1514 | } | ||
| 1515 | |||
| 1516 | /* | ||
| 1517 | * Check that the offset requested corresponds to one of the | ||
| 1518 | * resources of the device. | ||
| 1519 | */ | ||
| 1520 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
| 1521 | struct resource *rp = &dev->resource[i]; | ||
| 1522 | int flags = rp->flags; | ||
| 1523 | |||
| 1524 | /* treat ROM as memory (should be already) */ | ||
| 1525 | if (i == PCI_ROM_RESOURCE) | ||
| 1526 | flags |= IORESOURCE_MEM; | ||
| 1527 | |||
| 1528 | /* Active and same type? */ | ||
| 1529 | if ((flags & res_bit) == 0) | ||
| 1530 | continue; | ||
| 1531 | |||
| 1532 | /* In the range of this resource? */ | ||
| 1533 | if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end) | ||
| 1534 | continue; | ||
| 1535 | |||
| 1536 | /* found it! construct the final physical address */ | ||
| 1537 | if (mmap_state == pci_mmap_io) | ||
| 1538 | *offset += hose->io_base_phys - io_offset; | ||
| 1539 | return rp; | ||
| 1540 | } | ||
| 1541 | |||
| 1542 | return NULL; | ||
| 1543 | } | ||
| 1544 | |||
| 1545 | /* | ||
| 1546 | * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci | ||
| 1547 | * device mapping. | ||
| 1548 | */ | ||
| 1549 | static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, | ||
| 1550 | pgprot_t protection, | ||
| 1551 | enum pci_mmap_state mmap_state, | ||
| 1552 | int write_combine) | ||
| 1553 | { | ||
| 1554 | unsigned long prot = pgprot_val(protection); | ||
| 1555 | |||
| 1556 | /* Write combine is always 0 on non-memory space mappings. On | ||
| 1557 | * memory space, if the user didn't pass 1, we check for a | ||
| 1558 | * "prefetchable" resource. This is a bit hackish, but we use | ||
| 1559 | * this to workaround the inability of /sysfs to provide a write | ||
| 1560 | * combine bit | ||
| 1561 | */ | ||
| 1562 | if (mmap_state != pci_mmap_mem) | ||
| 1563 | write_combine = 0; | ||
| 1564 | else if (write_combine == 0) { | ||
| 1565 | if (rp->flags & IORESOURCE_PREFETCH) | ||
| 1566 | write_combine = 1; | ||
| 1567 | } | ||
| 1568 | |||
| 1569 | /* XXX would be nice to have a way to ask for write-through */ | ||
| 1570 | prot |= _PAGE_NO_CACHE; | ||
| 1571 | if (write_combine) | ||
| 1572 | prot &= ~_PAGE_GUARDED; | ||
| 1573 | else | ||
| 1574 | prot |= _PAGE_GUARDED; | ||
| 1575 | |||
| 1576 | printk("PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start, | ||
| 1577 | prot); | ||
| 1578 | |||
| 1579 | return __pgprot(prot); | ||
| 1580 | } | ||
| 1581 | |||
| 1582 | /* | ||
| 1583 | * This one is used by /dev/mem and fbdev who have no clue about the | ||
| 1584 | * PCI device, it tries to find the PCI device first and calls the | ||
| 1585 | * above routine | ||
| 1586 | */ | ||
| 1587 | pgprot_t pci_phys_mem_access_prot(struct file *file, | ||
| 1588 | unsigned long pfn, | ||
| 1589 | unsigned long size, | ||
| 1590 | pgprot_t protection) | ||
| 1591 | { | ||
| 1592 | struct pci_dev *pdev = NULL; | ||
| 1593 | struct resource *found = NULL; | ||
| 1594 | unsigned long prot = pgprot_val(protection); | ||
| 1595 | unsigned long offset = pfn << PAGE_SHIFT; | ||
| 1596 | int i; | ||
| 1597 | |||
| 1598 | if (page_is_ram(pfn)) | ||
| 1599 | return prot; | ||
| 1600 | |||
| 1601 | prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; | ||
| 1602 | |||
| 1603 | for_each_pci_dev(pdev) { | ||
| 1604 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
| 1605 | struct resource *rp = &pdev->resource[i]; | ||
| 1606 | int flags = rp->flags; | ||
| 1607 | |||
| 1608 | /* Active and same type? */ | ||
| 1609 | if ((flags & IORESOURCE_MEM) == 0) | ||
| 1610 | continue; | ||
| 1611 | /* In the range of this resource? */ | ||
| 1612 | if (offset < (rp->start & PAGE_MASK) || | ||
| 1613 | offset > rp->end) | ||
| 1614 | continue; | ||
| 1615 | found = rp; | ||
| 1616 | break; | ||
| 1617 | } | ||
| 1618 | if (found) | ||
| 1619 | break; | ||
| 1620 | } | ||
| 1621 | if (found) { | ||
| 1622 | if (found->flags & IORESOURCE_PREFETCH) | ||
| 1623 | prot &= ~_PAGE_GUARDED; | ||
| 1624 | pci_dev_put(pdev); | ||
| 1625 | } | ||
| 1626 | |||
| 1627 | DBG("non-PCI map for %lx, prot: %lx\n", offset, prot); | ||
| 1628 | |||
| 1629 | return __pgprot(prot); | ||
| 1630 | } | ||
| 1631 | |||
| 1632 | |||
| 1633 | /* | ||
| 1634 | * Perform the actual remap of the pages for a PCI device mapping, as | ||
| 1635 | * appropriate for this architecture. The region in the process to map | ||
| 1636 | * is described by vm_start and vm_end members of VMA, the base physical | ||
| 1637 | * address is found in vm_pgoff. | ||
| 1638 | * The pci device structure is provided so that architectures may make mapping | ||
| 1639 | * decisions on a per-device or per-bus basis. | ||
| 1640 | * | ||
| 1641 | * Returns a negative error code on failure, zero on success. | ||
| 1642 | */ | ||
| 1643 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | ||
| 1644 | enum pci_mmap_state mmap_state, | ||
| 1645 | int write_combine) | ||
| 1646 | { | ||
| 1647 | unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; | ||
| 1648 | struct resource *rp; | ||
| 1649 | int ret; | ||
| 1650 | |||
| 1651 | rp = __pci_mmap_make_offset(dev, &offset, mmap_state); | ||
| 1652 | if (rp == NULL) | ||
| 1653 | return -EINVAL; | ||
| 1654 | |||
| 1655 | vma->vm_pgoff = offset >> PAGE_SHIFT; | ||
| 1656 | vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO; | ||
| 1657 | vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp, | ||
| 1658 | vma->vm_page_prot, | ||
| 1659 | mmap_state, write_combine); | ||
| 1660 | |||
| 1661 | ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, | ||
| 1662 | vma->vm_end - vma->vm_start, vma->vm_page_prot); | ||
| 1663 | |||
| 1664 | return ret; | ||
| 1665 | } | ||
| 1666 | |||
| 1667 | /* Obsolete functions. Should be removed once the symbios driver | ||
| 1668 | * is fixed | ||
| 1669 | */ | ||
| 1670 | unsigned long | ||
| 1671 | phys_to_bus(unsigned long pa) | ||
| 1672 | { | ||
| 1673 | struct pci_controller *hose; | ||
| 1674 | int i; | ||
| 1675 | |||
| 1676 | for (hose = hose_head; hose; hose = hose->next) { | ||
| 1677 | for (i = 0; i < 3; ++i) { | ||
| 1678 | if (pa >= hose->mem_resources[i].start | ||
| 1679 | && pa <= hose->mem_resources[i].end) { | ||
| 1680 | /* | ||
| 1681 | * XXX the hose->pci_mem_offset really | ||
| 1682 | * only applies to mem_resources[0]. | ||
| 1683 | * We need a way to store an offset for | ||
| 1684 | * the others. -- paulus | ||
| 1685 | */ | ||
| 1686 | if (i == 0) | ||
| 1687 | pa -= hose->pci_mem_offset; | ||
| 1688 | return pa; | ||
| 1689 | } | ||
| 1690 | } | ||
| 1691 | } | ||
| 1692 | /* hmmm, didn't find it */ | ||
| 1693 | return 0; | ||
| 1694 | } | ||
| 1695 | |||
| 1696 | unsigned long | ||
| 1697 | pci_phys_to_bus(unsigned long pa, int busnr) | ||
| 1698 | { | ||
| 1699 | struct pci_controller* hose = pci_bus_to_hose(busnr); | ||
| 1700 | if (!hose) | ||
| 1701 | return pa; | ||
| 1702 | return pa - hose->pci_mem_offset; | ||
| 1703 | } | ||
| 1704 | |||
| 1705 | unsigned long | ||
| 1706 | pci_bus_to_phys(unsigned int ba, int busnr) | ||
| 1707 | { | ||
| 1708 | struct pci_controller* hose = pci_bus_to_hose(busnr); | ||
| 1709 | if (!hose) | ||
| 1710 | return ba; | ||
| 1711 | return ba + hose->pci_mem_offset; | ||
| 1712 | } | ||
| 1713 | |||
| 1714 | /* Provide information on locations of various I/O regions in physical | ||
| 1715 | * memory. Do this on a per-card basis so that we choose the right | ||
| 1716 | * root bridge. | ||
| 1717 | * Note that the returned IO or memory base is a physical address | ||
| 1718 | */ | ||
| 1719 | |||
| 1720 | long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) | ||
| 1721 | { | ||
| 1722 | struct pci_controller* hose; | ||
| 1723 | long result = -EOPNOTSUPP; | ||
| 1724 | |||
| 1725 | /* Argh ! Please forgive me for that hack, but that's the | ||
| 1726 | * simplest way to get existing XFree to not lockup on some | ||
| 1727 | * G5 machines... So when something asks for bus 0 io base | ||
| 1728 | * (bus 0 is HT root), we return the AGP one instead. | ||
| 1729 | */ | ||
| 1730 | #ifdef CONFIG_PPC_PMAC | ||
| 1731 | if (_machine == _MACH_Pmac && machine_is_compatible("MacRISC4")) | ||
| 1732 | if (bus == 0) | ||
| 1733 | bus = 0xf0; | ||
| 1734 | #endif /* CONFIG_PPC_PMAC */ | ||
| 1735 | |||
| 1736 | hose = pci_bus_to_hose(bus); | ||
| 1737 | if (!hose) | ||
| 1738 | return -ENODEV; | ||
| 1739 | |||
| 1740 | switch (which) { | ||
| 1741 | case IOBASE_BRIDGE_NUMBER: | ||
| 1742 | return (long)hose->first_busno; | ||
| 1743 | case IOBASE_MEMORY: | ||
| 1744 | return (long)hose->pci_mem_offset; | ||
| 1745 | case IOBASE_IO: | ||
| 1746 | return (long)hose->io_base_phys; | ||
| 1747 | case IOBASE_ISA_IO: | ||
| 1748 | return (long)isa_io_base; | ||
| 1749 | case IOBASE_ISA_MEM: | ||
| 1750 | return (long)isa_mem_base; | ||
| 1751 | } | ||
| 1752 | |||
| 1753 | return result; | ||
| 1754 | } | ||
| 1755 | |||
| 1756 | void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
| 1757 | const struct resource *rsrc, | ||
| 1758 | u64 *start, u64 *end) | ||
| 1759 | { | ||
| 1760 | struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); | ||
| 1761 | unsigned long offset = 0; | ||
| 1762 | |||
| 1763 | if (hose == NULL) | ||
| 1764 | return; | ||
| 1765 | |||
| 1766 | if (rsrc->flags & IORESOURCE_IO) | ||
| 1767 | offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys; | ||
| 1768 | |||
| 1769 | *start = rsrc->start + offset; | ||
| 1770 | *end = rsrc->end + offset; | ||
| 1771 | } | ||
| 1772 | |||
| 1773 | void __init | ||
| 1774 | pci_init_resource(struct resource *res, unsigned long start, unsigned long end, | ||
| 1775 | int flags, char *name) | ||
| 1776 | { | ||
| 1777 | res->start = start; | ||
| 1778 | res->end = end; | ||
| 1779 | res->flags = flags; | ||
| 1780 | res->name = name; | ||
| 1781 | res->parent = NULL; | ||
| 1782 | res->sibling = NULL; | ||
| 1783 | res->child = NULL; | ||
| 1784 | } | ||
| 1785 | |||
| 1786 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max) | ||
| 1787 | { | ||
| 1788 | unsigned long start = pci_resource_start(dev, bar); | ||
| 1789 | unsigned long len = pci_resource_len(dev, bar); | ||
| 1790 | unsigned long flags = pci_resource_flags(dev, bar); | ||
| 1791 | |||
| 1792 | if (!len) | ||
| 1793 | return NULL; | ||
| 1794 | if (max && len > max) | ||
| 1795 | len = max; | ||
| 1796 | if (flags & IORESOURCE_IO) | ||
| 1797 | return ioport_map(start, len); | ||
| 1798 | if (flags & IORESOURCE_MEM) | ||
| 1799 | /* Not checking IORESOURCE_CACHEABLE because PPC does | ||
| 1800 | * not currently distinguish between ioremap and | ||
| 1801 | * ioremap_nocache. | ||
| 1802 | */ | ||
| 1803 | return ioremap(start, len); | ||
| 1804 | /* What? */ | ||
| 1805 | return NULL; | ||
| 1806 | } | ||
| 1807 | |||
| 1808 | void pci_iounmap(struct pci_dev *dev, void __iomem *addr) | ||
| 1809 | { | ||
| 1810 | /* Nothing to do */ | ||
| 1811 | } | ||
| 1812 | EXPORT_SYMBOL(pci_iomap); | ||
| 1813 | EXPORT_SYMBOL(pci_iounmap); | ||
| 1814 | |||
| 1815 | unsigned long pci_address_to_pio(phys_addr_t address) | ||
| 1816 | { | ||
| 1817 | struct pci_controller* hose = hose_head; | ||
| 1818 | |||
| 1819 | for (; hose; hose = hose->next) { | ||
| 1820 | unsigned int size = hose->io_resource.end - | ||
| 1821 | hose->io_resource.start + 1; | ||
| 1822 | if (address >= hose->io_base_phys && | ||
| 1823 | address < (hose->io_base_phys + size)) { | ||
| 1824 | unsigned long base = | ||
| 1825 | (unsigned long)hose->io_base_virt - _IO_BASE; | ||
| 1826 | return base + (address - hose->io_base_phys); | ||
| 1827 | } | ||
| 1828 | } | ||
| 1829 | return (unsigned int)-1; | ||
| 1830 | } | ||
| 1831 | EXPORT_SYMBOL(pci_address_to_pio); | ||
| 1832 | |||
| 1833 | /* | ||
| 1834 | * Null PCI config access functions, for the case when we can't | ||
| 1835 | * find a hose. | ||
| 1836 | */ | ||
| 1837 | #define NULL_PCI_OP(rw, size, type) \ | ||
| 1838 | static int \ | ||
| 1839 | null_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \ | ||
| 1840 | { \ | ||
| 1841 | return PCIBIOS_DEVICE_NOT_FOUND; \ | ||
| 1842 | } | ||
| 1843 | |||
| 1844 | static int | ||
| 1845 | null_read_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
| 1846 | int len, u32 *val) | ||
| 1847 | { | ||
| 1848 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 1849 | } | ||
| 1850 | |||
| 1851 | static int | ||
| 1852 | null_write_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
| 1853 | int len, u32 val) | ||
| 1854 | { | ||
| 1855 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 1856 | } | ||
| 1857 | |||
| 1858 | static struct pci_ops null_pci_ops = | ||
| 1859 | { | ||
| 1860 | null_read_config, | ||
| 1861 | null_write_config | ||
| 1862 | }; | ||
| 1863 | |||
| 1864 | /* | ||
| 1865 | * These functions are used early on before PCI scanning is done | ||
| 1866 | * and all of the pci_dev and pci_bus structures have been created. | ||
| 1867 | */ | ||
| 1868 | static struct pci_bus * | ||
| 1869 | fake_pci_bus(struct pci_controller *hose, int busnr) | ||
| 1870 | { | ||
| 1871 | static struct pci_bus bus; | ||
| 1872 | |||
| 1873 | if (hose == 0) { | ||
| 1874 | hose = pci_bus_to_hose(busnr); | ||
| 1875 | if (hose == 0) | ||
| 1876 | printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr); | ||
| 1877 | } | ||
| 1878 | bus.number = busnr; | ||
| 1879 | bus.sysdata = hose; | ||
| 1880 | bus.ops = hose? hose->ops: &null_pci_ops; | ||
| 1881 | return &bus; | ||
| 1882 | } | ||
| 1883 | |||
| 1884 | #define EARLY_PCI_OP(rw, size, type) \ | ||
| 1885 | int early_##rw##_config_##size(struct pci_controller *hose, int bus, \ | ||
| 1886 | int devfn, int offset, type value) \ | ||
| 1887 | { \ | ||
| 1888 | return pci_bus_##rw##_config_##size(fake_pci_bus(hose, bus), \ | ||
| 1889 | devfn, offset, value); \ | ||
| 1890 | } | ||
| 1891 | |||
| 1892 | EARLY_PCI_OP(read, byte, u8 *) | ||
| 1893 | EARLY_PCI_OP(read, word, u16 *) | ||
| 1894 | EARLY_PCI_OP(read, dword, u32 *) | ||
| 1895 | EARLY_PCI_OP(write, byte, u8) | ||
| 1896 | EARLY_PCI_OP(write, word, u16) | ||
| 1897 | EARLY_PCI_OP(write, dword, u32) | ||
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 16d9a904f3cb..d9a459c144d8 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
| @@ -230,8 +230,7 @@ EXPORT_SYMBOL(__down_interruptible); | |||
| 230 | EXPORT_SYMBOL(cpm_install_handler); | 230 | EXPORT_SYMBOL(cpm_install_handler); |
| 231 | EXPORT_SYMBOL(cpm_free_handler); | 231 | EXPORT_SYMBOL(cpm_free_handler); |
| 232 | #endif /* CONFIG_8xx */ | 232 | #endif /* CONFIG_8xx */ |
| 233 | #if defined(CONFIG_8xx) || defined(CONFIG_40x) || defined(CONFIG_85xx) ||\ | 233 | #if defined(CONFIG_8xx) || defined(CONFIG_40x) |
| 234 | defined(CONFIG_83xx) | ||
| 235 | EXPORT_SYMBOL(__res); | 234 | EXPORT_SYMBOL(__res); |
| 236 | #endif | 235 | #endif |
| 237 | 236 | ||
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 02e2115323e4..d50c8df0183e 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
| @@ -1627,6 +1627,11 @@ static void of_node_release(struct kref *kref) | |||
| 1627 | kfree(prop->value); | 1627 | kfree(prop->value); |
| 1628 | kfree(prop); | 1628 | kfree(prop); |
| 1629 | prop = next; | 1629 | prop = next; |
| 1630 | |||
| 1631 | if (!prop) { | ||
| 1632 | prop = node->deadprops; | ||
| 1633 | node->deadprops = NULL; | ||
| 1634 | } | ||
| 1630 | } | 1635 | } |
| 1631 | kfree(node->intrs); | 1636 | kfree(node->intrs); |
| 1632 | kfree(node->full_name); | 1637 | kfree(node->full_name); |
| @@ -1774,22 +1779,32 @@ static int __init prom_reconfig_setup(void) | |||
| 1774 | __initcall(prom_reconfig_setup); | 1779 | __initcall(prom_reconfig_setup); |
| 1775 | #endif | 1780 | #endif |
| 1776 | 1781 | ||
| 1777 | /* | 1782 | struct property *of_find_property(struct device_node *np, const char *name, |
| 1778 | * Find a property with a given name for a given node | 1783 | int *lenp) |
| 1779 | * and return the value. | ||
| 1780 | */ | ||
| 1781 | unsigned char *get_property(struct device_node *np, const char *name, | ||
| 1782 | int *lenp) | ||
| 1783 | { | 1784 | { |
| 1784 | struct property *pp; | 1785 | struct property *pp; |
| 1785 | 1786 | ||
| 1787 | read_lock(&devtree_lock); | ||
| 1786 | for (pp = np->properties; pp != 0; pp = pp->next) | 1788 | for (pp = np->properties; pp != 0; pp = pp->next) |
| 1787 | if (strcmp(pp->name, name) == 0) { | 1789 | if (strcmp(pp->name, name) == 0) { |
| 1788 | if (lenp != 0) | 1790 | if (lenp != 0) |
| 1789 | *lenp = pp->length; | 1791 | *lenp = pp->length; |
| 1790 | return pp->value; | 1792 | break; |
| 1791 | } | 1793 | } |
| 1792 | return NULL; | 1794 | read_unlock(&devtree_lock); |
| 1795 | |||
| 1796 | return pp; | ||
| 1797 | } | ||
| 1798 | |||
| 1799 | /* | ||
| 1800 | * Find a property with a given name for a given node | ||
| 1801 | * and return the value. | ||
| 1802 | */ | ||
| 1803 | unsigned char *get_property(struct device_node *np, const char *name, | ||
| 1804 | int *lenp) | ||
| 1805 | { | ||
| 1806 | struct property *pp = of_find_property(np,name,lenp); | ||
| 1807 | return pp ? pp->value : NULL; | ||
| 1793 | } | 1808 | } |
| 1794 | EXPORT_SYMBOL(get_property); | 1809 | EXPORT_SYMBOL(get_property); |
| 1795 | 1810 | ||
| @@ -1823,4 +1838,82 @@ int prom_add_property(struct device_node* np, struct property* prop) | |||
| 1823 | return 0; | 1838 | return 0; |
| 1824 | } | 1839 | } |
| 1825 | 1840 | ||
| 1841 | /* | ||
| 1842 | * Remove a property from a node. Note that we don't actually | ||
| 1843 | * remove it, since we have given out who-knows-how-many pointers | ||
| 1844 | * to the data using get-property. Instead we just move the property | ||
| 1845 | * to the "dead properties" list, so it won't be found any more. | ||
| 1846 | */ | ||
| 1847 | int prom_remove_property(struct device_node *np, struct property *prop) | ||
| 1848 | { | ||
| 1849 | struct property **next; | ||
| 1850 | int found = 0; | ||
| 1826 | 1851 | ||
| 1852 | write_lock(&devtree_lock); | ||
| 1853 | next = &np->properties; | ||
| 1854 | while (*next) { | ||
| 1855 | if (*next == prop) { | ||
| 1856 | /* found the node */ | ||
| 1857 | *next = prop->next; | ||
| 1858 | prop->next = np->deadprops; | ||
| 1859 | np->deadprops = prop; | ||
| 1860 | found = 1; | ||
| 1861 | break; | ||
| 1862 | } | ||
| 1863 | next = &(*next)->next; | ||
| 1864 | } | ||
| 1865 | write_unlock(&devtree_lock); | ||
| 1866 | |||
| 1867 | if (!found) | ||
| 1868 | return -ENODEV; | ||
| 1869 | |||
| 1870 | #ifdef CONFIG_PROC_DEVICETREE | ||
| 1871 | /* try to remove the proc node as well */ | ||
| 1872 | if (np->pde) | ||
| 1873 | proc_device_tree_remove_prop(np->pde, prop); | ||
| 1874 | #endif /* CONFIG_PROC_DEVICETREE */ | ||
| 1875 | |||
| 1876 | return 0; | ||
| 1877 | } | ||
| 1878 | |||
| 1879 | /* | ||
| 1880 | * Update a property in a node. Note that we don't actually | ||
| 1881 | * remove it, since we have given out who-knows-how-many pointers | ||
| 1882 | * to the data using get-property. Instead we just move the property | ||
| 1883 | * to the "dead properties" list, and add the new property to the | ||
| 1884 | * property list | ||
| 1885 | */ | ||
| 1886 | int prom_update_property(struct device_node *np, | ||
| 1887 | struct property *newprop, | ||
| 1888 | struct property *oldprop) | ||
| 1889 | { | ||
| 1890 | struct property **next; | ||
| 1891 | int found = 0; | ||
| 1892 | |||
| 1893 | write_lock(&devtree_lock); | ||
| 1894 | next = &np->properties; | ||
| 1895 | while (*next) { | ||
| 1896 | if (*next == oldprop) { | ||
| 1897 | /* found the node */ | ||
| 1898 | newprop->next = oldprop->next; | ||
| 1899 | *next = newprop; | ||
| 1900 | oldprop->next = np->deadprops; | ||
| 1901 | np->deadprops = oldprop; | ||
| 1902 | found = 1; | ||
| 1903 | break; | ||
| 1904 | } | ||
| 1905 | next = &(*next)->next; | ||
| 1906 | } | ||
| 1907 | write_unlock(&devtree_lock); | ||
| 1908 | |||
| 1909 | if (!found) | ||
| 1910 | return -ENODEV; | ||
| 1911 | |||
| 1912 | #ifdef CONFIG_PROC_DEVICETREE | ||
| 1913 | /* try to add to proc as well if it was initialized */ | ||
| 1914 | if (np->pde) | ||
| 1915 | proc_device_tree_update_prop(np->pde, newprop, oldprop); | ||
| 1916 | #endif /* CONFIG_PROC_DEVICETREE */ | ||
| 1917 | |||
| 1918 | return 0; | ||
| 1919 | } | ||
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index d963a12ec640..7881ec96ef11 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
| @@ -605,7 +605,8 @@ static void __init early_cmdline_parse(void) | |||
| 605 | opt = strstr(RELOC(prom_cmd_line), RELOC("crashkernel=")); | 605 | opt = strstr(RELOC(prom_cmd_line), RELOC("crashkernel=")); |
| 606 | if (opt) { | 606 | if (opt) { |
| 607 | opt += 12; | 607 | opt += 12; |
| 608 | RELOC(prom_crashk_size) = prom_memparse(opt, &opt); | 608 | RELOC(prom_crashk_size) = |
| 609 | prom_memparse(opt, (const char **)&opt); | ||
| 609 | 610 | ||
| 610 | if (ALIGN(RELOC(prom_crashk_size), 0x1000000) != | 611 | if (ALIGN(RELOC(prom_crashk_size), 0x1000000) != |
| 611 | RELOC(prom_crashk_size)) { | 612 | RELOC(prom_crashk_size)) { |
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index 309ae1d5fa77..a8099c806150 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c | |||
| @@ -113,7 +113,8 @@ static unsigned int of_bus_default_get_flags(u32 *addr) | |||
| 113 | 113 | ||
| 114 | static int of_bus_pci_match(struct device_node *np) | 114 | static int of_bus_pci_match(struct device_node *np) |
| 115 | { | 115 | { |
| 116 | return !strcmp(np->type, "pci"); | 116 | /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */ |
| 117 | return !strcmp(np->type, "pci") || !strcmp(np->type, "vci"); | ||
| 117 | } | 118 | } |
| 118 | 119 | ||
| 119 | static void of_bus_pci_count_cells(struct device_node *np, | 120 | static void of_bus_pci_count_cells(struct device_node *np, |
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 4b9cfe4637b1..7fe4a5c944c9 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
| @@ -36,6 +36,11 @@ struct rtas_t rtas = { | |||
| 36 | .lock = SPIN_LOCK_UNLOCKED | 36 | .lock = SPIN_LOCK_UNLOCKED |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | struct rtas_suspend_me_data { | ||
| 40 | long waiting; | ||
| 41 | struct rtas_args *args; | ||
| 42 | }; | ||
| 43 | |||
| 39 | EXPORT_SYMBOL(rtas); | 44 | EXPORT_SYMBOL(rtas); |
| 40 | 45 | ||
| 41 | DEFINE_SPINLOCK(rtas_data_buf_lock); | 46 | DEFINE_SPINLOCK(rtas_data_buf_lock); |
| @@ -556,6 +561,80 @@ void rtas_os_term(char *str) | |||
| 556 | } while (status == RTAS_BUSY); | 561 | } while (status == RTAS_BUSY); |
| 557 | } | 562 | } |
| 558 | 563 | ||
| 564 | static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE; | ||
| 565 | #ifdef CONFIG_PPC_PSERIES | ||
| 566 | static void rtas_percpu_suspend_me(void *info) | ||
| 567 | { | ||
| 568 | long rc; | ||
| 569 | long flags; | ||
| 570 | struct rtas_suspend_me_data *data = | ||
| 571 | (struct rtas_suspend_me_data *)info; | ||
| 572 | |||
| 573 | /* | ||
| 574 | * We use "waiting" to indicate our state. As long | ||
| 575 | * as it is >0, we are still trying to all join up. | ||
| 576 | * If it goes to 0, we have successfully joined up and | ||
| 577 | * one thread got H_Continue. If any error happens, | ||
| 578 | * we set it to <0. | ||
| 579 | */ | ||
| 580 | local_irq_save(flags); | ||
| 581 | do { | ||
| 582 | rc = plpar_hcall_norets(H_JOIN); | ||
| 583 | smp_rmb(); | ||
| 584 | } while (rc == H_Success && data->waiting > 0); | ||
| 585 | if (rc == H_Success) | ||
| 586 | goto out; | ||
| 587 | |||
| 588 | if (rc == H_Continue) { | ||
| 589 | data->waiting = 0; | ||
| 590 | rtas_call(ibm_suspend_me_token, 0, 1, | ||
| 591 | data->args->args); | ||
| 592 | } else { | ||
| 593 | data->waiting = -EBUSY; | ||
| 594 | printk(KERN_ERR "Error on H_Join hypervisor call\n"); | ||
| 595 | } | ||
| 596 | |||
| 597 | out: | ||
| 598 | /* before we restore interrupts, make sure we don't | ||
| 599 | * generate a spurious soft lockup errors | ||
| 600 | */ | ||
| 601 | touch_softlockup_watchdog(); | ||
| 602 | local_irq_restore(flags); | ||
| 603 | return; | ||
| 604 | } | ||
| 605 | |||
| 606 | static int rtas_ibm_suspend_me(struct rtas_args *args) | ||
| 607 | { | ||
| 608 | int i; | ||
| 609 | |||
| 610 | struct rtas_suspend_me_data data; | ||
| 611 | |||
| 612 | data.waiting = 1; | ||
| 613 | data.args = args; | ||
| 614 | |||
| 615 | /* Call function on all CPUs. One of us will make the | ||
| 616 | * rtas call | ||
| 617 | */ | ||
| 618 | if (on_each_cpu(rtas_percpu_suspend_me, &data, 1, 0)) | ||
| 619 | data.waiting = -EINVAL; | ||
| 620 | |||
| 621 | if (data.waiting != 0) | ||
| 622 | printk(KERN_ERR "Error doing global join\n"); | ||
| 623 | |||
| 624 | /* Prod each CPU. This won't hurt, and will wake | ||
| 625 | * anyone we successfully put to sleep with H_Join | ||
| 626 | */ | ||
| 627 | for_each_cpu(i) | ||
| 628 | plpar_hcall_norets(H_PROD, i); | ||
| 629 | |||
| 630 | return data.waiting; | ||
| 631 | } | ||
| 632 | #else /* CONFIG_PPC_PSERIES */ | ||
| 633 | static int rtas_ibm_suspend_me(struct rtas_args *args) | ||
| 634 | { | ||
| 635 | return -ENOSYS; | ||
| 636 | } | ||
| 637 | #endif | ||
| 559 | 638 | ||
| 560 | asmlinkage int ppc_rtas(struct rtas_args __user *uargs) | 639 | asmlinkage int ppc_rtas(struct rtas_args __user *uargs) |
| 561 | { | 640 | { |
| @@ -563,6 +642,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) | |||
| 563 | unsigned long flags; | 642 | unsigned long flags; |
| 564 | char *buff_copy, *errbuf = NULL; | 643 | char *buff_copy, *errbuf = NULL; |
| 565 | int nargs; | 644 | int nargs; |
| 645 | int rc; | ||
| 566 | 646 | ||
| 567 | if (!capable(CAP_SYS_ADMIN)) | 647 | if (!capable(CAP_SYS_ADMIN)) |
| 568 | return -EPERM; | 648 | return -EPERM; |
| @@ -581,6 +661,17 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) | |||
| 581 | nargs * sizeof(rtas_arg_t)) != 0) | 661 | nargs * sizeof(rtas_arg_t)) != 0) |
| 582 | return -EFAULT; | 662 | return -EFAULT; |
| 583 | 663 | ||
| 664 | if (args.token == RTAS_UNKNOWN_SERVICE) | ||
| 665 | return -EINVAL; | ||
| 666 | |||
| 667 | /* Need to handle ibm,suspend_me call specially */ | ||
| 668 | if (args.token == ibm_suspend_me_token) { | ||
| 669 | rc = rtas_ibm_suspend_me(&args); | ||
| 670 | if (rc) | ||
| 671 | return rc; | ||
| 672 | goto copy_return; | ||
| 673 | } | ||
| 674 | |||
| 584 | buff_copy = get_errorlog_buffer(); | 675 | buff_copy = get_errorlog_buffer(); |
| 585 | 676 | ||
| 586 | spin_lock_irqsave(&rtas.lock, flags); | 677 | spin_lock_irqsave(&rtas.lock, flags); |
| @@ -604,6 +695,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) | |||
| 604 | kfree(buff_copy); | 695 | kfree(buff_copy); |
| 605 | } | 696 | } |
| 606 | 697 | ||
| 698 | copy_return: | ||
| 607 | /* Copy out args. */ | 699 | /* Copy out args. */ |
| 608 | if (copy_to_user(uargs->args + nargs, | 700 | if (copy_to_user(uargs->args + nargs, |
| 609 | args.args + nargs, | 701 | args.args + nargs, |
| @@ -675,8 +767,10 @@ void __init rtas_initialize(void) | |||
| 675 | * the stop-self token if any | 767 | * the stop-self token if any |
| 676 | */ | 768 | */ |
| 677 | #ifdef CONFIG_PPC64 | 769 | #ifdef CONFIG_PPC64 |
| 678 | if (_machine == PLATFORM_PSERIES_LPAR) | 770 | if (_machine == PLATFORM_PSERIES_LPAR) { |
| 679 | rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX); | 771 | rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX); |
| 772 | ibm_suspend_me_token = rtas_token("ibm,suspend-me"); | ||
| 773 | } | ||
| 680 | #endif | 774 | #endif |
| 681 | rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region); | 775 | rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region); |
| 682 | 776 | ||
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index d5c52fae023a..be12041c0fc5 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c | |||
| @@ -100,7 +100,8 @@ void machine_shutdown(void) | |||
| 100 | void machine_restart(char *cmd) | 100 | void machine_restart(char *cmd) |
| 101 | { | 101 | { |
| 102 | machine_shutdown(); | 102 | machine_shutdown(); |
| 103 | ppc_md.restart(cmd); | 103 | if (ppc_md.restart) |
| 104 | ppc_md.restart(cmd); | ||
| 104 | #ifdef CONFIG_SMP | 105 | #ifdef CONFIG_SMP |
| 105 | smp_send_stop(); | 106 | smp_send_stop(); |
| 106 | #endif | 107 | #endif |
| @@ -112,7 +113,8 @@ void machine_restart(char *cmd) | |||
| 112 | void machine_power_off(void) | 113 | void machine_power_off(void) |
| 113 | { | 114 | { |
| 114 | machine_shutdown(); | 115 | machine_shutdown(); |
| 115 | ppc_md.power_off(); | 116 | if (ppc_md.power_off) |
| 117 | ppc_md.power_off(); | ||
| 116 | #ifdef CONFIG_SMP | 118 | #ifdef CONFIG_SMP |
| 117 | smp_send_stop(); | 119 | smp_send_stop(); |
| 118 | #endif | 120 | #endif |
| @@ -129,7 +131,8 @@ EXPORT_SYMBOL_GPL(pm_power_off); | |||
| 129 | void machine_halt(void) | 131 | void machine_halt(void) |
| 130 | { | 132 | { |
| 131 | machine_shutdown(); | 133 | machine_shutdown(); |
| 132 | ppc_md.halt(); | 134 | if (ppc_md.halt) |
| 135 | ppc_md.halt(); | ||
| 133 | #ifdef CONFIG_SMP | 136 | #ifdef CONFIG_SMP |
| 134 | smp_send_stop(); | 137 | smp_send_stop(); |
| 135 | #endif | 138 | #endif |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 56f50e91bddb..c4a294d657b9 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
| @@ -431,7 +431,7 @@ void timer_interrupt(struct pt_regs * regs) | |||
| 431 | profile_tick(CPU_PROFILING, regs); | 431 | profile_tick(CPU_PROFILING, regs); |
| 432 | 432 | ||
| 433 | #ifdef CONFIG_PPC_ISERIES | 433 | #ifdef CONFIG_PPC_ISERIES |
| 434 | get_paca()->lppaca.int_dword.fields.decr_int = 0; | 434 | get_lppaca()->int_dword.fields.decr_int = 0; |
| 435 | #endif | 435 | #endif |
| 436 | 436 | ||
| 437 | while ((ticks = tb_ticks_since(per_cpu(last_jiffy, cpu))) | 437 | while ((ticks = tb_ticks_since(per_cpu(last_jiffy, cpu))) |
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 13c41495fe06..13c655ba2841 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
| @@ -76,7 +76,7 @@ static void vio_bus_shutdown(struct device *dev) | |||
| 76 | struct vio_dev *viodev = to_vio_dev(dev); | 76 | struct vio_dev *viodev = to_vio_dev(dev); |
| 77 | struct vio_driver *viodrv = to_vio_driver(dev->driver); | 77 | struct vio_driver *viodrv = to_vio_driver(dev->driver); |
| 78 | 78 | ||
| 79 | if (viodrv->shutdown) | 79 | if (dev->driver && viodrv->shutdown) |
| 80 | viodrv->shutdown(viodev); | 80 | viodrv->shutdown(viodev); |
| 81 | } | 81 | } |
| 82 | 82 | ||
| @@ -91,9 +91,6 @@ int vio_register_driver(struct vio_driver *viodrv) | |||
| 91 | 91 | ||
| 92 | /* fill in 'struct driver' fields */ | 92 | /* fill in 'struct driver' fields */ |
| 93 | viodrv->driver.bus = &vio_bus_type; | 93 | viodrv->driver.bus = &vio_bus_type; |
| 94 | viodrv->driver.probe = vio_bus_probe; | ||
| 95 | viodrv->driver.remove = vio_bus_remove; | ||
| 96 | viodrv->driver.shutdown = vio_bus_shutdown; | ||
| 97 | 94 | ||
| 98 | return driver_register(&viodrv->driver); | 95 | return driver_register(&viodrv->driver); |
| 99 | } | 96 | } |
| @@ -295,4 +292,7 @@ struct bus_type vio_bus_type = { | |||
| 295 | .name = "vio", | 292 | .name = "vio", |
| 296 | .uevent = vio_hotplug, | 293 | .uevent = vio_hotplug, |
| 297 | .match = vio_bus_match, | 294 | .match = vio_bus_match, |
| 295 | .probe = vio_bus_probe, | ||
| 296 | .remove = vio_bus_remove, | ||
| 297 | .shutdown = vio_bus_shutdown, | ||
| 298 | }; | 298 | }; |
diff --git a/arch/powerpc/lib/locks.c b/arch/powerpc/lib/locks.c index 35bd03c41dd1..8362fa272ca5 100644 --- a/arch/powerpc/lib/locks.c +++ b/arch/powerpc/lib/locks.c | |||
| @@ -28,15 +28,13 @@ | |||
| 28 | void __spin_yield(raw_spinlock_t *lock) | 28 | void __spin_yield(raw_spinlock_t *lock) |
| 29 | { | 29 | { |
| 30 | unsigned int lock_value, holder_cpu, yield_count; | 30 | unsigned int lock_value, holder_cpu, yield_count; |
| 31 | struct paca_struct *holder_paca; | ||
| 32 | 31 | ||
| 33 | lock_value = lock->slock; | 32 | lock_value = lock->slock; |
| 34 | if (lock_value == 0) | 33 | if (lock_value == 0) |
| 35 | return; | 34 | return; |
| 36 | holder_cpu = lock_value & 0xffff; | 35 | holder_cpu = lock_value & 0xffff; |
| 37 | BUG_ON(holder_cpu >= NR_CPUS); | 36 | BUG_ON(holder_cpu >= NR_CPUS); |
| 38 | holder_paca = &paca[holder_cpu]; | 37 | yield_count = lppaca[holder_cpu].yield_count; |
| 39 | yield_count = holder_paca->lppaca.yield_count; | ||
| 40 | if ((yield_count & 1) == 0) | 38 | if ((yield_count & 1) == 0) |
| 41 | return; /* virtual cpu is currently running */ | 39 | return; /* virtual cpu is currently running */ |
| 42 | rmb(); | 40 | rmb(); |
| @@ -60,15 +58,13 @@ void __rw_yield(raw_rwlock_t *rw) | |||
| 60 | { | 58 | { |
| 61 | int lock_value; | 59 | int lock_value; |
| 62 | unsigned int holder_cpu, yield_count; | 60 | unsigned int holder_cpu, yield_count; |
| 63 | struct paca_struct *holder_paca; | ||
| 64 | 61 | ||
| 65 | lock_value = rw->lock; | 62 | lock_value = rw->lock; |
| 66 | if (lock_value >= 0) | 63 | if (lock_value >= 0) |
| 67 | return; /* no write lock at present */ | 64 | return; /* no write lock at present */ |
| 68 | holder_cpu = lock_value & 0xffff; | 65 | holder_cpu = lock_value & 0xffff; |
| 69 | BUG_ON(holder_cpu >= NR_CPUS); | 66 | BUG_ON(holder_cpu >= NR_CPUS); |
| 70 | holder_paca = &paca[holder_cpu]; | 67 | yield_count = lppaca[holder_cpu].yield_count; |
| 71 | yield_count = holder_paca->lppaca.yield_count; | ||
| 72 | if ((yield_count & 1) == 0) | 68 | if ((yield_count & 1) == 0) |
| 73 | return; /* virtual cpu is currently running */ | 69 | return; /* virtual cpu is currently running */ |
| 74 | rmb(); | 70 | rmb(); |
diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c index 71615eb70b2b..cc2535be3a73 100644 --- a/arch/powerpc/oprofile/common.c +++ b/arch/powerpc/oprofile/common.c | |||
| @@ -140,19 +140,19 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
| 140 | 140 | ||
| 141 | switch (cur_cpu_spec->oprofile_type) { | 141 | switch (cur_cpu_spec->oprofile_type) { |
| 142 | #ifdef CONFIG_PPC64 | 142 | #ifdef CONFIG_PPC64 |
| 143 | case RS64: | 143 | case PPC_OPROFILE_RS64: |
| 144 | model = &op_model_rs64; | 144 | model = &op_model_rs64; |
| 145 | break; | 145 | break; |
| 146 | case POWER4: | 146 | case PPC_OPROFILE_POWER4: |
| 147 | model = &op_model_power4; | 147 | model = &op_model_power4; |
| 148 | break; | 148 | break; |
| 149 | #else | 149 | #else |
| 150 | case G4: | 150 | case PPC_OPROFILE_G4: |
| 151 | model = &op_model_7450; | 151 | model = &op_model_7450; |
| 152 | break; | 152 | break; |
| 153 | #endif | 153 | #endif |
| 154 | #ifdef CONFIG_FSL_BOOKE | 154 | #ifdef CONFIG_FSL_BOOKE |
| 155 | case BOOKE: | 155 | case PPC_OPROFILE_BOOKE: |
| 156 | model = &op_model_fsl_booke; | 156 | model = &op_model_fsl_booke; |
| 157 | break; | 157 | break; |
| 158 | #endif | 158 | #endif |
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig index b20812d460e6..7675e675dce1 100644 --- a/arch/powerpc/platforms/83xx/Kconfig +++ b/arch/powerpc/platforms/83xx/Kconfig | |||
| @@ -7,6 +7,7 @@ choice | |||
| 7 | 7 | ||
| 8 | config MPC834x_SYS | 8 | config MPC834x_SYS |
| 9 | bool "Freescale MPC834x SYS" | 9 | bool "Freescale MPC834x SYS" |
| 10 | select DEFAULT_UIMAGE | ||
| 10 | help | 11 | help |
| 11 | This option enables support for the MPC 834x SYS evaluation board. | 12 | This option enables support for the MPC 834x SYS evaluation board. |
| 12 | 13 | ||
diff --git a/arch/powerpc/platforms/83xx/mpc834x_sys.c b/arch/powerpc/platforms/83xx/mpc834x_sys.c new file mode 100644 index 000000000000..2098dd05a773 --- /dev/null +++ b/arch/powerpc/platforms/83xx/mpc834x_sys.c | |||
| @@ -0,0 +1,243 @@ | |||
| 1 | /* | ||
| 2 | * arch/powerpc/platforms/83xx/mpc834x_sys.c | ||
| 3 | * | ||
| 4 | * MPC834x SYS board specific routines | ||
| 5 | * | ||
| 6 | * Maintainer: Kumar Gala <galak@kernel.crashing.org> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/config.h> | ||
| 15 | #include <linux/stddef.h> | ||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/init.h> | ||
| 18 | #include <linux/errno.h> | ||
| 19 | #include <linux/reboot.h> | ||
| 20 | #include <linux/pci.h> | ||
| 21 | #include <linux/kdev_t.h> | ||
| 22 | #include <linux/major.h> | ||
| 23 | #include <linux/console.h> | ||
| 24 | #include <linux/delay.h> | ||
| 25 | #include <linux/seq_file.h> | ||
| 26 | #include <linux/root_dev.h> | ||
| 27 | #include <linux/module.h> | ||
| 28 | #include <linux/fsl_devices.h> | ||
| 29 | |||
| 30 | #include <asm/system.h> | ||
| 31 | #include <asm/pgtable.h> | ||
| 32 | #include <asm/page.h> | ||
| 33 | #include <asm/atomic.h> | ||
| 34 | #include <asm/time.h> | ||
| 35 | #include <asm/io.h> | ||
| 36 | #include <asm/machdep.h> | ||
| 37 | #include <asm/ipic.h> | ||
| 38 | #include <asm/bootinfo.h> | ||
| 39 | #include <asm/pci-bridge.h> | ||
| 40 | #include <asm/mpc83xx.h> | ||
| 41 | #include <asm/irq.h> | ||
| 42 | #include <mm/mmu_decl.h> | ||
| 43 | #include <asm/prom.h> | ||
| 44 | #include <asm/udbg.h> | ||
| 45 | #include <sysdev/fsl_soc.h> | ||
| 46 | |||
| 47 | #include "mpc83xx.h" | ||
| 48 | |||
| 49 | #ifndef CONFIG_PCI | ||
| 50 | unsigned long isa_io_base = 0; | ||
| 51 | unsigned long isa_mem_base = 0; | ||
| 52 | #endif | ||
| 53 | |||
| 54 | #ifdef CONFIG_PCI | ||
| 55 | extern int mpc83xx_pci2_busno; | ||
| 56 | |||
| 57 | static int | ||
| 58 | mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | ||
| 59 | { | ||
| 60 | static char pci_irq_table[][4] = | ||
| 61 | /* | ||
| 62 | * PCI IDSEL/INTPIN->INTLINE | ||
| 63 | * A B C D | ||
| 64 | */ | ||
| 65 | { | ||
| 66 | {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x11 */ | ||
| 67 | {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x12 */ | ||
| 68 | {PIRQD, PIRQA, PIRQB, PIRQC}, /* idsel 0x13 */ | ||
| 69 | {0, 0, 0, 0}, | ||
| 70 | {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x15 */ | ||
| 71 | {PIRQD, PIRQA, PIRQB, PIRQC}, /* idsel 0x16 */ | ||
| 72 | {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x17 */ | ||
| 73 | {PIRQB, PIRQC, PIRQD, PIRQA}, /* idsel 0x18 */ | ||
| 74 | {0, 0, 0, 0}, /* idsel 0x19 */ | ||
| 75 | {0, 0, 0, 0}, /* idsel 0x20 */ | ||
| 76 | }; | ||
| 77 | |||
| 78 | const long min_idsel = 0x11, max_idsel = 0x20, irqs_per_slot = 4; | ||
| 79 | return PCI_IRQ_TABLE_LOOKUP; | ||
| 80 | } | ||
| 81 | |||
| 82 | static int | ||
| 83 | mpc83xx_exclude_device(u_char bus, u_char devfn) | ||
| 84 | { | ||
| 85 | if (bus == 0 && PCI_SLOT(devfn) == 0) | ||
| 86 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 87 | if (mpc83xx_pci2_busno) | ||
| 88 | if (bus == (mpc83xx_pci2_busno) && PCI_SLOT(devfn) == 0) | ||
| 89 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 90 | return PCIBIOS_SUCCESSFUL; | ||
| 91 | } | ||
| 92 | #endif /* CONFIG_PCI */ | ||
| 93 | |||
| 94 | /* ************************************************************************ | ||
| 95 | * | ||
| 96 | * Setup the architecture | ||
| 97 | * | ||
| 98 | */ | ||
| 99 | static void __init | ||
| 100 | mpc834x_sys_setup_arch(void) | ||
| 101 | { | ||
| 102 | struct device_node *np; | ||
| 103 | |||
| 104 | if (ppc_md.progress) | ||
| 105 | ppc_md.progress("mpc834x_sys_setup_arch()", 0); | ||
| 106 | |||
| 107 | np = of_find_node_by_type(NULL, "cpu"); | ||
| 108 | if (np != 0) { | ||
| 109 | unsigned int *fp = (int *) get_property(np, "clock-frequency", NULL); | ||
| 110 | if (fp != 0) | ||
| 111 | loops_per_jiffy = *fp / HZ; | ||
| 112 | else | ||
| 113 | loops_per_jiffy = 50000000 / HZ; | ||
| 114 | of_node_put(np); | ||
| 115 | } | ||
| 116 | |||
| 117 | #ifdef CONFIG_PCI | ||
| 118 | for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) | ||
| 119 | add_bridge(np); | ||
| 120 | |||
| 121 | ppc_md.pci_swizzle = common_swizzle; | ||
| 122 | ppc_md.pci_map_irq = mpc83xx_map_irq; | ||
| 123 | ppc_md.pci_exclude_device = mpc83xx_exclude_device; | ||
| 124 | #endif | ||
| 125 | |||
| 126 | #ifdef CONFIG_ROOT_NFS | ||
| 127 | ROOT_DEV = Root_NFS; | ||
| 128 | #else | ||
| 129 | ROOT_DEV = Root_HDA1; | ||
| 130 | #endif | ||
| 131 | } | ||
| 132 | |||
| 133 | void __init | ||
| 134 | mpc834x_sys_init_IRQ(void) | ||
| 135 | { | ||
| 136 | u8 senses[8] = { | ||
| 137 | 0, /* EXT 0 */ | ||
| 138 | IRQ_SENSE_LEVEL, /* EXT 1 */ | ||
| 139 | IRQ_SENSE_LEVEL, /* EXT 2 */ | ||
| 140 | 0, /* EXT 3 */ | ||
| 141 | #ifdef CONFIG_PCI | ||
| 142 | IRQ_SENSE_LEVEL, /* EXT 4 */ | ||
| 143 | IRQ_SENSE_LEVEL, /* EXT 5 */ | ||
| 144 | IRQ_SENSE_LEVEL, /* EXT 6 */ | ||
| 145 | IRQ_SENSE_LEVEL, /* EXT 7 */ | ||
| 146 | #else | ||
| 147 | 0, /* EXT 4 */ | ||
| 148 | 0, /* EXT 5 */ | ||
| 149 | 0, /* EXT 6 */ | ||
| 150 | 0, /* EXT 7 */ | ||
| 151 | #endif | ||
| 152 | }; | ||
| 153 | |||
| 154 | ipic_init(get_immrbase() + 0x00700, 0, 0, senses, 8); | ||
| 155 | |||
| 156 | /* Initialize the default interrupt mapping priorities, | ||
| 157 | * in case the boot rom changed something on us. | ||
| 158 | */ | ||
| 159 | ipic_set_default_priority(); | ||
| 160 | } | ||
| 161 | |||
| 162 | #if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374) | ||
| 163 | extern ulong ds1374_get_rtc_time(void); | ||
| 164 | extern int ds1374_set_rtc_time(ulong); | ||
| 165 | |||
| 166 | static int __init | ||
| 167 | mpc834x_rtc_hookup(void) | ||
| 168 | { | ||
| 169 | struct timespec tv; | ||
| 170 | |||
| 171 | ppc_md.get_rtc_time = ds1374_get_rtc_time; | ||
| 172 | ppc_md.set_rtc_time = ds1374_set_rtc_time; | ||
| 173 | |||
| 174 | tv.tv_nsec = 0; | ||
| 175 | tv.tv_sec = (ppc_md.get_rtc_time)(); | ||
| 176 | do_settimeofday(&tv); | ||
| 177 | |||
| 178 | return 0; | ||
| 179 | } | ||
| 180 | late_initcall(mpc834x_rtc_hookup); | ||
| 181 | #endif | ||
| 182 | |||
| 183 | static void | ||
| 184 | mpc83xx_restart(char *cmd) | ||
| 185 | { | ||
| 186 | #define RST_OFFSET 0x00000900 | ||
| 187 | #define RST_PROT_REG 0x00000018 | ||
| 188 | #define RST_CTRL_REG 0x0000001c | ||
| 189 | __be32 __iomem *reg; | ||
| 190 | |||
| 191 | // map reset register space | ||
| 192 | reg = ioremap(get_immrbase() + 0x900, 0xff); | ||
| 193 | |||
| 194 | local_irq_disable(); | ||
| 195 | |||
| 196 | /* enable software reset "RSTE" */ | ||
| 197 | out_be32(reg + (RST_PROT_REG >> 2), 0x52535445); | ||
| 198 | |||
| 199 | /* set software hard reset */ | ||
| 200 | out_be32(reg + (RST_CTRL_REG >> 2), 0x52535445); | ||
| 201 | for(;;); | ||
| 202 | } | ||
| 203 | |||
| 204 | static long __init | ||
| 205 | mpc83xx_time_init(void) | ||
| 206 | { | ||
| 207 | #define SPCR_OFFSET 0x00000110 | ||
| 208 | #define SPCR_TBEN 0x00400000 | ||
| 209 | __be32 __iomem *spcr = ioremap(get_immrbase() + SPCR_OFFSET, 4); | ||
| 210 | __be32 tmp; | ||
| 211 | |||
| 212 | tmp = in_be32(spcr); | ||
| 213 | out_be32(spcr, tmp|SPCR_TBEN); | ||
| 214 | |||
| 215 | iounmap(spcr); | ||
| 216 | |||
| 217 | return 0; | ||
| 218 | } | ||
| 219 | void __init | ||
| 220 | platform_init(void) | ||
| 221 | { | ||
| 222 | /* setup the PowerPC module struct */ | ||
| 223 | ppc_md.setup_arch = mpc834x_sys_setup_arch; | ||
| 224 | |||
| 225 | ppc_md.init_IRQ = mpc834x_sys_init_IRQ; | ||
| 226 | ppc_md.get_irq = ipic_get_irq; | ||
| 227 | |||
| 228 | ppc_md.restart = mpc83xx_restart; | ||
| 229 | |||
| 230 | ppc_md.time_init = mpc83xx_time_init; | ||
| 231 | ppc_md.set_rtc_time = NULL; | ||
| 232 | ppc_md.get_rtc_time = NULL; | ||
| 233 | ppc_md.calibrate_decr = generic_calibrate_decr; | ||
| 234 | |||
| 235 | ppc_md.progress = udbg_progress; | ||
| 236 | |||
| 237 | if (ppc_md.progress) | ||
| 238 | ppc_md.progress("mpc834x_sys_init(): exit", 0); | ||
| 239 | |||
| 240 | return; | ||
| 241 | } | ||
| 242 | |||
| 243 | |||
diff --git a/arch/powerpc/platforms/83xx/mpc834x_sys.h b/arch/powerpc/platforms/83xx/mpc834x_sys.h new file mode 100644 index 000000000000..e4ca39f6a862 --- /dev/null +++ b/arch/powerpc/platforms/83xx/mpc834x_sys.h | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | /* | ||
| 2 | * arch/powerppc/platforms/83xx/mpc834x_sys.h | ||
| 3 | * | ||
| 4 | * MPC834X SYS common board definitions | ||
| 5 | * | ||
| 6 | * Maintainer: Kumar Gala <galak@kernel.crashing.org> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | |||
| 15 | #ifndef __MACH_MPC83XX_SYS_H__ | ||
| 16 | #define __MACH_MPC83XX_SYS_H__ | ||
| 17 | |||
| 18 | #define PIRQA MPC83xx_IRQ_EXT4 | ||
| 19 | #define PIRQB MPC83xx_IRQ_EXT5 | ||
| 20 | #define PIRQC MPC83xx_IRQ_EXT6 | ||
| 21 | #define PIRQD MPC83xx_IRQ_EXT7 | ||
| 22 | |||
| 23 | #endif /* __MACH_MPC83XX_SYS_H__ */ | ||
diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h new file mode 100644 index 000000000000..ce9e66abef24 --- /dev/null +++ b/arch/powerpc/platforms/83xx/mpc83xx.h | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | #ifndef __MPC83XX_H__ | ||
| 2 | #define __MPC83XX_H__ | ||
| 3 | |||
| 4 | #include <linux/init.h> | ||
| 5 | #include <linux/device.h> | ||
| 6 | |||
| 7 | /* | ||
| 8 | * Declaration for the various functions exported by the | ||
| 9 | * mpc83xx_* files. Mostly for use by mpc83xx_setup | ||
| 10 | */ | ||
| 11 | |||
| 12 | extern int add_bridge(struct device_node *dev); | ||
| 13 | |||
| 14 | #endif /* __MPC83XX_H__ */ | ||
diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c new file mode 100644 index 000000000000..469cdacc5bd4 --- /dev/null +++ b/arch/powerpc/platforms/83xx/pci.c | |||
| @@ -0,0 +1,99 @@ | |||
| 1 | /* | ||
| 2 | * FSL SoC setup code | ||
| 3 | * | ||
| 4 | * Maintained by Kumar Gala (see MAINTAINERS for contact information) | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License as published by the | ||
| 8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 9 | * option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/config.h> | ||
| 13 | #include <linux/stddef.h> | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/errno.h> | ||
| 17 | #include <linux/pci.h> | ||
| 18 | #include <linux/delay.h> | ||
| 19 | #include <linux/irq.h> | ||
| 20 | #include <linux/module.h> | ||
| 21 | |||
| 22 | #include <asm/system.h> | ||
| 23 | #include <asm/atomic.h> | ||
| 24 | #include <asm/io.h> | ||
| 25 | #include <asm/pci-bridge.h> | ||
| 26 | #include <asm/prom.h> | ||
| 27 | #include <sysdev/fsl_soc.h> | ||
| 28 | |||
| 29 | #undef DEBUG | ||
| 30 | |||
| 31 | #ifdef DEBUG | ||
| 32 | #define DBG(x...) printk(x) | ||
| 33 | #else | ||
| 34 | #define DBG(x...) | ||
| 35 | #endif | ||
| 36 | |||
| 37 | int mpc83xx_pci2_busno; | ||
| 38 | |||
| 39 | #ifdef CONFIG_PCI | ||
| 40 | int __init add_bridge(struct device_node *dev) | ||
| 41 | { | ||
| 42 | int len; | ||
| 43 | struct pci_controller *hose; | ||
| 44 | struct resource rsrc; | ||
| 45 | int *bus_range; | ||
| 46 | int primary = 1, has_address = 0; | ||
| 47 | phys_addr_t immr = get_immrbase(); | ||
| 48 | |||
| 49 | DBG("Adding PCI host bridge %s\n", dev->full_name); | ||
| 50 | |||
| 51 | /* Fetch host bridge registers address */ | ||
| 52 | has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); | ||
| 53 | |||
| 54 | /* Get bus range if any */ | ||
| 55 | bus_range = (int *) get_property(dev, "bus-range", &len); | ||
| 56 | if (bus_range == NULL || len < 2 * sizeof(int)) { | ||
| 57 | printk(KERN_WARNING "Can't get bus-range for %s, assume" | ||
| 58 | " bus 0\n", dev->full_name); | ||
| 59 | } | ||
| 60 | |||
| 61 | hose = pcibios_alloc_controller(); | ||
| 62 | if (!hose) | ||
| 63 | return -ENOMEM; | ||
| 64 | hose->arch_data = dev; | ||
| 65 | hose->set_cfg_type = 1; | ||
| 66 | |||
| 67 | hose->first_busno = bus_range ? bus_range[0] : 0; | ||
| 68 | hose->last_busno = bus_range ? bus_range[1] : 0xff; | ||
| 69 | |||
| 70 | /* MPC83xx supports up to two host controllers one at 0x8500 from immrbar | ||
| 71 | * the other at 0x8600, we consider the 0x8500 the primary controller | ||
| 72 | */ | ||
| 73 | /* PCI 1 */ | ||
| 74 | if ((rsrc.start & 0xfffff) == 0x8500) { | ||
| 75 | setup_indirect_pci(hose, immr + 0x8300, immr + 0x8304); | ||
| 76 | } | ||
| 77 | /* PCI 2*/ | ||
| 78 | if ((rsrc.start & 0xfffff) == 0x8600) { | ||
| 79 | setup_indirect_pci(hose, immr + 0x8380, immr + 0x8384); | ||
| 80 | primary = 0; | ||
| 81 | hose->bus_offset = hose->first_busno; | ||
| 82 | mpc83xx_pci2_busno = hose->first_busno; | ||
| 83 | } | ||
| 84 | |||
| 85 | printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%08lx. " | ||
| 86 | "Firmware bus number: %d->%d\n", | ||
| 87 | rsrc.start, hose->first_busno, hose->last_busno); | ||
| 88 | |||
| 89 | DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", | ||
| 90 | hose, hose->cfg_addr, hose->cfg_data); | ||
| 91 | |||
| 92 | /* Interpret the "ranges" property */ | ||
| 93 | /* This also maps the I/O region and sets isa_io/mem_base */ | ||
| 94 | pci_process_bridge_OF_ranges(hose, dev, primary); | ||
| 95 | |||
| 96 | return 0; | ||
| 97 | } | ||
| 98 | |||
| 99 | #endif | ||
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c index 82c429d487f3..00c52f27ef4f 100644 --- a/arch/powerpc/platforms/chrp/pci.c +++ b/arch/powerpc/platforms/chrp/pci.c | |||
| @@ -135,12 +135,13 @@ int __init | |||
| 135 | hydra_init(void) | 135 | hydra_init(void) |
| 136 | { | 136 | { |
| 137 | struct device_node *np; | 137 | struct device_node *np; |
| 138 | struct resource r; | ||
| 138 | 139 | ||
| 139 | np = find_devices("mac-io"); | 140 | np = find_devices("mac-io"); |
| 140 | if (np == NULL || np->n_addrs == 0) | 141 | if (np == NULL || of_address_to_resource(np, 0, &r)) |
| 141 | return 0; | 142 | return 0; |
| 142 | Hydra = ioremap(np->addrs[0].address, np->addrs[0].size); | 143 | Hydra = ioremap(r.start, r.end-r.start); |
| 143 | printk("Hydra Mac I/O at %lx\n", np->addrs[0].address); | 144 | printk("Hydra Mac I/O at %lx\n", r.start); |
| 144 | printk("Hydra Feature_Control was %x", | 145 | printk("Hydra Feature_Control was %x", |
| 145 | in_le32(&Hydra->Feature_Control)); | 146 | in_le32(&Hydra->Feature_Control)); |
| 146 | out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN | | 147 | out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN | |
| @@ -177,18 +178,24 @@ setup_python(struct pci_controller *hose, struct device_node *dev) | |||
| 177 | { | 178 | { |
| 178 | u32 __iomem *reg; | 179 | u32 __iomem *reg; |
| 179 | u32 val; | 180 | u32 val; |
| 180 | unsigned long addr = dev->addrs[0].address; | 181 | struct resource r; |
| 181 | 182 | ||
| 182 | setup_indirect_pci(hose, addr + 0xf8000, addr + 0xf8010); | 183 | if (of_address_to_resource(dev, 0, &r)) { |
| 184 | printk(KERN_ERR "No address for Python PCI controller\n"); | ||
| 185 | return; | ||
| 186 | } | ||
| 183 | 187 | ||
| 184 | /* Clear the magic go-slow bit */ | 188 | /* Clear the magic go-slow bit */ |
| 185 | reg = ioremap(dev->addrs[0].address + 0xf6000, 0x40); | 189 | reg = ioremap(r.start + 0xf6000, 0x40); |
| 190 | BUG_ON(!reg); | ||
| 186 | val = in_be32(®[12]); | 191 | val = in_be32(®[12]); |
| 187 | if (val & PRG_CL_RESET_VALID) { | 192 | if (val & PRG_CL_RESET_VALID) { |
| 188 | out_be32(®[12], val & ~PRG_CL_RESET_VALID); | 193 | out_be32(®[12], val & ~PRG_CL_RESET_VALID); |
| 189 | in_be32(®[12]); | 194 | in_be32(®[12]); |
| 190 | } | 195 | } |
| 191 | iounmap(reg); | 196 | iounmap(reg); |
| 197 | |||
| 198 | setup_indirect_pci(hose, r.start + 0xf8000, r.start + 0xf8010); | ||
| 192 | } | 199 | } |
| 193 | 200 | ||
| 194 | /* Marvell Discovery II based Pegasos 2 */ | 201 | /* Marvell Discovery II based Pegasos 2 */ |
| @@ -218,7 +225,7 @@ chrp_find_bridges(void) | |||
| 218 | char *model, *machine; | 225 | char *model, *machine; |
| 219 | int is_longtrail = 0, is_mot = 0, is_pegasos = 0; | 226 | int is_longtrail = 0, is_mot = 0, is_pegasos = 0; |
| 220 | struct device_node *root = find_path_device("/"); | 227 | struct device_node *root = find_path_device("/"); |
| 221 | 228 | struct resource r; | |
| 222 | /* | 229 | /* |
| 223 | * The PCI host bridge nodes on some machines don't have | 230 | * The PCI host bridge nodes on some machines don't have |
| 224 | * properties to adequately identify them, so we have to | 231 | * properties to adequately identify them, so we have to |
| @@ -238,7 +245,7 @@ chrp_find_bridges(void) | |||
| 238 | continue; | 245 | continue; |
| 239 | ++index; | 246 | ++index; |
| 240 | /* The GG2 bridge on the LongTrail doesn't have an address */ | 247 | /* The GG2 bridge on the LongTrail doesn't have an address */ |
| 241 | if (dev->n_addrs < 1 && !is_longtrail) { | 248 | if (of_address_to_resource(dev, 0, &r) && !is_longtrail) { |
| 242 | printk(KERN_WARNING "Can't use %s: no address\n", | 249 | printk(KERN_WARNING "Can't use %s: no address\n", |
| 243 | dev->full_name); | 250 | dev->full_name); |
| 244 | continue; | 251 | continue; |
| @@ -255,8 +262,8 @@ chrp_find_bridges(void) | |||
| 255 | printk(KERN_INFO "PCI buses %d..%d", | 262 | printk(KERN_INFO "PCI buses %d..%d", |
| 256 | bus_range[0], bus_range[1]); | 263 | bus_range[0], bus_range[1]); |
| 257 | printk(" controlled by %s", dev->type); | 264 | printk(" controlled by %s", dev->type); |
| 258 | if (dev->n_addrs > 0) | 265 | if (!is_longtrail) |
| 259 | printk(" at %lx", dev->addrs[0].address); | 266 | printk(" at %lx", r.start); |
| 260 | printk("\n"); | 267 | printk("\n"); |
| 261 | 268 | ||
| 262 | hose = pcibios_alloc_controller(); | 269 | hose = pcibios_alloc_controller(); |
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 4ec8ba737e7d..2dc87aa5962f 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c | |||
| @@ -352,9 +352,10 @@ static void __init chrp_find_openpic(void) | |||
| 352 | opaddr = opprop[na-1]; /* assume 32-bit */ | 352 | opaddr = opprop[na-1]; /* assume 32-bit */ |
| 353 | oplen /= na * sizeof(unsigned int); | 353 | oplen /= na * sizeof(unsigned int); |
| 354 | } else { | 354 | } else { |
| 355 | if (np->n_addrs == 0) | 355 | struct resource r; |
| 356 | if (of_address_to_resource(np, 0, &r)) | ||
| 356 | return; | 357 | return; |
| 357 | opaddr = np->addrs[0].address; | 358 | opaddr = r.start; |
| 358 | oplen = 0; | 359 | oplen = 0; |
| 359 | } | 360 | } |
| 360 | 361 | ||
| @@ -377,7 +378,7 @@ static void __init chrp_find_openpic(void) | |||
| 377 | */ | 378 | */ |
| 378 | if (oplen < len) { | 379 | if (oplen < len) { |
| 379 | printk(KERN_ERR "Insufficient addresses for distributed" | 380 | printk(KERN_ERR "Insufficient addresses for distributed" |
| 380 | " OpenPIC (%d < %d)\n", np->n_addrs, len); | 381 | " OpenPIC (%d < %d)\n", oplen, len); |
| 381 | len = oplen; | 382 | len = oplen; |
| 382 | } | 383 | } |
| 383 | 384 | ||
diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c index 737ee5d9f0aa..36a0f97bb7b1 100644 --- a/arch/powerpc/platforms/chrp/time.c +++ b/arch/powerpc/platforms/chrp/time.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/mc146818rtc.h> | 21 | #include <linux/mc146818rtc.h> |
| 22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
| 23 | #include <linux/bcd.h> | 23 | #include <linux/bcd.h> |
| 24 | #include <linux/ioport.h> | ||
| 24 | 25 | ||
| 25 | #include <asm/io.h> | 26 | #include <asm/io.h> |
| 26 | #include <asm/nvram.h> | 27 | #include <asm/nvram.h> |
| @@ -37,14 +38,16 @@ static int nvram_data = NVRAM_DATA; | |||
| 37 | long __init chrp_time_init(void) | 38 | long __init chrp_time_init(void) |
| 38 | { | 39 | { |
| 39 | struct device_node *rtcs; | 40 | struct device_node *rtcs; |
| 41 | struct resource r; | ||
| 40 | int base; | 42 | int base; |
| 41 | 43 | ||
| 42 | rtcs = find_compatible_devices("rtc", "pnpPNP,b00"); | 44 | rtcs = find_compatible_devices("rtc", "pnpPNP,b00"); |
| 43 | if (rtcs == NULL) | 45 | if (rtcs == NULL) |
| 44 | rtcs = find_compatible_devices("rtc", "ds1385-rtc"); | 46 | rtcs = find_compatible_devices("rtc", "ds1385-rtc"); |
| 45 | if (rtcs == NULL || rtcs->addrs == NULL) | 47 | if (rtcs == NULL || of_address_to_resource(rtcs, 0, &r)) |
| 46 | return 0; | 48 | return 0; |
| 47 | base = rtcs->addrs[0].address; | 49 | |
| 50 | base = r.start; | ||
| 48 | nvram_as1 = 0; | 51 | nvram_as1 = 0; |
| 49 | nvram_as0 = base; | 52 | nvram_as0 = base; |
| 50 | nvram_data = base + 1; | 53 | nvram_data = base + 1; |
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c index 83442ea77476..be3fbfc24e6c 100644 --- a/arch/powerpc/platforms/iseries/irq.c +++ b/arch/powerpc/platforms/iseries/irq.c | |||
| @@ -334,14 +334,12 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus, | |||
| 334 | */ | 334 | */ |
| 335 | int iSeries_get_irq(struct pt_regs *regs) | 335 | int iSeries_get_irq(struct pt_regs *regs) |
| 336 | { | 336 | { |
| 337 | struct paca_struct *lpaca; | ||
| 338 | /* -2 means ignore this interrupt */ | 337 | /* -2 means ignore this interrupt */ |
| 339 | int irq = -2; | 338 | int irq = -2; |
| 340 | 339 | ||
| 341 | lpaca = get_paca(); | ||
| 342 | #ifdef CONFIG_SMP | 340 | #ifdef CONFIG_SMP |
| 343 | if (lpaca->lppaca.int_dword.fields.ipi_cnt) { | 341 | if (get_lppaca()->int_dword.fields.ipi_cnt) { |
| 344 | lpaca->lppaca.int_dword.fields.ipi_cnt = 0; | 342 | get_lppaca()->int_dword.fields.ipi_cnt = 0; |
| 345 | iSeries_smp_message_recv(regs); | 343 | iSeries_smp_message_recv(regs); |
| 346 | } | 344 | } |
| 347 | #endif /* CONFIG_SMP */ | 345 | #endif /* CONFIG_SMP */ |
diff --git a/arch/powerpc/platforms/iseries/misc.S b/arch/powerpc/platforms/iseries/misc.S index dfe7aa1ba098..7641fc7e550a 100644 --- a/arch/powerpc/platforms/iseries/misc.S +++ b/arch/powerpc/platforms/iseries/misc.S | |||
| @@ -44,7 +44,8 @@ _GLOBAL(local_irq_restore) | |||
| 44 | /* Check pending interrupts */ | 44 | /* Check pending interrupts */ |
| 45 | /* A decrementer, IPI or PMC interrupt may have occurred | 45 | /* A decrementer, IPI or PMC interrupt may have occurred |
| 46 | * while we were in the hypervisor (which enables) */ | 46 | * while we were in the hypervisor (which enables) */ |
| 47 | ld r4,PACALPPACA+LPPACAANYINT(r13) | 47 | ld r4,PACALPPACAPTR(r13) |
| 48 | ld r4,LPPACAANYINT(r4) | ||
| 48 | cmpdi r4,0 | 49 | cmpdi r4,0 |
| 49 | beqlr | 50 | beqlr |
| 50 | 51 | ||
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index c6bbe5c25107..3f8790146b00 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c | |||
| @@ -538,7 +538,7 @@ static unsigned long __init build_iSeries_Memory_Map(void) | |||
| 538 | */ | 538 | */ |
| 539 | static void __init iSeries_setup_arch(void) | 539 | static void __init iSeries_setup_arch(void) |
| 540 | { | 540 | { |
| 541 | if (get_paca()->lppaca.shared_proc) { | 541 | if (get_lppaca()->shared_proc) { |
| 542 | ppc_md.idle_loop = iseries_shared_idle; | 542 | ppc_md.idle_loop = iseries_shared_idle; |
| 543 | printk(KERN_INFO "Using shared processor idle loop\n"); | 543 | printk(KERN_INFO "Using shared processor idle loop\n"); |
| 544 | } else { | 544 | } else { |
| @@ -647,7 +647,7 @@ static void yield_shared_processor(void) | |||
| 647 | * The decrementer stops during the yield. Force a fake decrementer | 647 | * The decrementer stops during the yield. Force a fake decrementer |
| 648 | * here and let the timer_interrupt code sort out the actual time. | 648 | * here and let the timer_interrupt code sort out the actual time. |
| 649 | */ | 649 | */ |
| 650 | get_paca()->lppaca.int_dword.fields.decr_int = 1; | 650 | get_lppaca()->int_dword.fields.decr_int = 1; |
| 651 | process_iSeries_events(); | 651 | process_iSeries_events(); |
| 652 | } | 652 | } |
| 653 | 653 | ||
| @@ -883,7 +883,7 @@ void dt_cpus(struct iseries_flat_dt *dt) | |||
| 883 | pft_size[1] = __ilog2(HvCallHpt_getHptPages() * HW_PAGE_SIZE); | 883 | pft_size[1] = __ilog2(HvCallHpt_getHptPages() * HW_PAGE_SIZE); |
| 884 | 884 | ||
| 885 | for (i = 0; i < NR_CPUS; i++) { | 885 | for (i = 0; i < NR_CPUS; i++) { |
| 886 | if (paca[i].lppaca.dyn_proc_status >= 2) | 886 | if (lppaca[i].dyn_proc_status >= 2) |
| 887 | continue; | 887 | continue; |
| 888 | 888 | ||
| 889 | snprintf(p, 32 - (p - buf), "@%d", i); | 889 | snprintf(p, 32 - (p - buf), "@%d", i); |
| @@ -891,7 +891,7 @@ void dt_cpus(struct iseries_flat_dt *dt) | |||
| 891 | 891 | ||
| 892 | dt_prop_str(dt, "device_type", "cpu"); | 892 | dt_prop_str(dt, "device_type", "cpu"); |
| 893 | 893 | ||
| 894 | index = paca[i].lppaca.dyn_hv_phys_proc_index; | 894 | index = lppaca[i].dyn_hv_phys_proc_index; |
| 895 | d = &xIoHriProcessorVpd[index]; | 895 | d = &xIoHriProcessorVpd[index]; |
| 896 | 896 | ||
| 897 | dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024); | 897 | dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024); |
diff --git a/arch/powerpc/platforms/iseries/smp.c b/arch/powerpc/platforms/iseries/smp.c index fcb094ec6aec..6f9d407a709f 100644 --- a/arch/powerpc/platforms/iseries/smp.c +++ b/arch/powerpc/platforms/iseries/smp.c | |||
| @@ -91,7 +91,7 @@ static void smp_iSeries_kick_cpu(int nr) | |||
| 91 | BUG_ON((nr < 0) || (nr >= NR_CPUS)); | 91 | BUG_ON((nr < 0) || (nr >= NR_CPUS)); |
| 92 | 92 | ||
| 93 | /* Verify that our partition has a processor nr */ | 93 | /* Verify that our partition has a processor nr */ |
| 94 | if (paca[nr].lppaca.dyn_proc_status >= 2) | 94 | if (lppaca[nr].dyn_proc_status >= 2) |
| 95 | return; | 95 | return; |
| 96 | 96 | ||
| 97 | /* The processor is currently spinning, waiting | 97 | /* The processor is currently spinning, waiting |
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index f40451da037c..7d4099a34f92 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c | |||
| @@ -316,7 +316,6 @@ static int __init add_bridge(struct device_node *dev) | |||
| 316 | char* disp_name; | 316 | char* disp_name; |
| 317 | int *bus_range; | 317 | int *bus_range; |
| 318 | int primary = 1; | 318 | int primary = 1; |
| 319 | struct property *of_prop; | ||
| 320 | 319 | ||
| 321 | DBG("Adding PCI host bridge %s\n", dev->full_name); | 320 | DBG("Adding PCI host bridge %s\n", dev->full_name); |
| 322 | 321 | ||
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c index a1cb4d236720..ec5c1e10c407 100644 --- a/arch/powerpc/platforms/maple/setup.c +++ b/arch/powerpc/platforms/maple/setup.c | |||
| @@ -71,38 +71,60 @@ | |||
| 71 | #define DBG(fmt...) | 71 | #define DBG(fmt...) |
| 72 | #endif | 72 | #endif |
| 73 | 73 | ||
| 74 | static unsigned long maple_find_nvram_base(void) | ||
| 75 | { | ||
| 76 | struct device_node *rtcs; | ||
| 77 | unsigned long result = 0; | ||
| 78 | |||
| 79 | /* find NVRAM device */ | ||
| 80 | rtcs = of_find_compatible_node(NULL, "nvram", "AMD8111"); | ||
| 81 | if (rtcs) { | ||
| 82 | struct resource r; | ||
| 83 | if (of_address_to_resource(rtcs, 0, &r)) { | ||
| 84 | printk(KERN_EMERG "Maple: Unable to translate NVRAM" | ||
| 85 | " address\n"); | ||
| 86 | goto bail; | ||
| 87 | } | ||
| 88 | if (!(r.flags & IORESOURCE_IO)) { | ||
| 89 | printk(KERN_EMERG "Maple: NVRAM address isn't PIO!\n"); | ||
| 90 | goto bail; | ||
| 91 | } | ||
| 92 | result = r.start; | ||
| 93 | } else | ||
| 94 | printk(KERN_EMERG "Maple: Unable to find NVRAM\n"); | ||
| 95 | bail: | ||
| 96 | of_node_put(rtcs); | ||
| 97 | return result; | ||
| 98 | } | ||
| 99 | |||
| 74 | static void maple_restart(char *cmd) | 100 | static void maple_restart(char *cmd) |
| 75 | { | 101 | { |
| 76 | unsigned int maple_nvram_base; | 102 | unsigned int maple_nvram_base; |
| 77 | unsigned int maple_nvram_offset; | 103 | unsigned int maple_nvram_offset; |
| 78 | unsigned int maple_nvram_command; | 104 | unsigned int maple_nvram_command; |
| 79 | struct device_node *rtcs; | 105 | struct device_node *sp; |
| 80 | 106 | ||
| 81 | /* find NVRAM device */ | 107 | maple_nvram_base = maple_find_nvram_base(); |
| 82 | rtcs = find_compatible_devices("nvram", "AMD8111"); | 108 | if (maple_nvram_base == 0) |
| 83 | if (rtcs && rtcs->addrs) { | 109 | goto fail; |
| 84 | maple_nvram_base = rtcs->addrs[0].address; | ||
| 85 | } else { | ||
| 86 | printk(KERN_EMERG "Maple: Unable to find NVRAM\n"); | ||
| 87 | printk(KERN_EMERG "Maple: Manual Restart Required\n"); | ||
| 88 | return; | ||
| 89 | } | ||
| 90 | 110 | ||
| 91 | /* find service processor device */ | 111 | /* find service processor device */ |
| 92 | rtcs = find_devices("service-processor"); | 112 | sp = of_find_node_by_name(NULL, "service-processor"); |
| 93 | if (!rtcs) { | 113 | if (!sp) { |
| 94 | printk(KERN_EMERG "Maple: Unable to find Service Processor\n"); | 114 | printk(KERN_EMERG "Maple: Unable to find Service Processor\n"); |
| 95 | printk(KERN_EMERG "Maple: Manual Restart Required\n"); | 115 | goto fail; |
| 96 | return; | ||
| 97 | } | 116 | } |
| 98 | maple_nvram_offset = *(unsigned int*) get_property(rtcs, | 117 | maple_nvram_offset = *(unsigned int*) get_property(sp, |
| 99 | "restart-addr", NULL); | 118 | "restart-addr", NULL); |
| 100 | maple_nvram_command = *(unsigned int*) get_property(rtcs, | 119 | maple_nvram_command = *(unsigned int*) get_property(sp, |
| 101 | "restart-value", NULL); | 120 | "restart-value", NULL); |
| 121 | of_node_put(sp); | ||
| 102 | 122 | ||
| 103 | /* send command */ | 123 | /* send command */ |
| 104 | outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset); | 124 | outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset); |
| 105 | for (;;) ; | 125 | for (;;) ; |
| 126 | fail: | ||
| 127 | printk(KERN_EMERG "Maple: Manual Restart Required\n"); | ||
| 106 | } | 128 | } |
| 107 | 129 | ||
| 108 | static void maple_power_off(void) | 130 | static void maple_power_off(void) |
| @@ -110,33 +132,29 @@ static void maple_power_off(void) | |||
| 110 | unsigned int maple_nvram_base; | 132 | unsigned int maple_nvram_base; |
| 111 | unsigned int maple_nvram_offset; | 133 | unsigned int maple_nvram_offset; |
| 112 | unsigned int maple_nvram_command; | 134 | unsigned int maple_nvram_command; |
| 113 | struct device_node *rtcs; | 135 | struct device_node *sp; |
| 114 | 136 | ||
| 115 | /* find NVRAM device */ | 137 | maple_nvram_base = maple_find_nvram_base(); |
| 116 | rtcs = find_compatible_devices("nvram", "AMD8111"); | 138 | if (maple_nvram_base == 0) |
| 117 | if (rtcs && rtcs->addrs) { | 139 | goto fail; |
| 118 | maple_nvram_base = rtcs->addrs[0].address; | ||
| 119 | } else { | ||
| 120 | printk(KERN_EMERG "Maple: Unable to find NVRAM\n"); | ||
| 121 | printk(KERN_EMERG "Maple: Manual Power-Down Required\n"); | ||
| 122 | return; | ||
| 123 | } | ||
| 124 | 140 | ||
| 125 | /* find service processor device */ | 141 | /* find service processor device */ |
| 126 | rtcs = find_devices("service-processor"); | 142 | sp = of_find_node_by_name(NULL, "service-processor"); |
| 127 | if (!rtcs) { | 143 | if (!sp) { |
| 128 | printk(KERN_EMERG "Maple: Unable to find Service Processor\n"); | 144 | printk(KERN_EMERG "Maple: Unable to find Service Processor\n"); |
| 129 | printk(KERN_EMERG "Maple: Manual Power-Down Required\n"); | 145 | goto fail; |
| 130 | return; | ||
| 131 | } | 146 | } |
| 132 | maple_nvram_offset = *(unsigned int*) get_property(rtcs, | 147 | maple_nvram_offset = *(unsigned int*) get_property(sp, |
| 133 | "power-off-addr", NULL); | 148 | "power-off-addr", NULL); |
| 134 | maple_nvram_command = *(unsigned int*) get_property(rtcs, | 149 | maple_nvram_command = *(unsigned int*) get_property(sp, |
| 135 | "power-off-value", NULL); | 150 | "power-off-value", NULL); |
| 151 | of_node_put(sp); | ||
| 136 | 152 | ||
| 137 | /* send command */ | 153 | /* send command */ |
| 138 | outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset); | 154 | outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset); |
| 139 | for (;;) ; | 155 | for (;;) ; |
| 156 | fail: | ||
| 157 | printk(KERN_EMERG "Maple: Manual Power-Down Required\n"); | ||
| 140 | } | 158 | } |
| 141 | 159 | ||
| 142 | static void maple_halt(void) | 160 | static void maple_halt(void) |
| @@ -179,9 +197,6 @@ void __init maple_setup_arch(void) | |||
| 179 | */ | 197 | */ |
| 180 | static void __init maple_init_early(void) | 198 | static void __init maple_init_early(void) |
| 181 | { | 199 | { |
| 182 | unsigned int default_speed; | ||
| 183 | u64 physport; | ||
| 184 | |||
| 185 | DBG(" -> maple_init_early\n"); | 200 | DBG(" -> maple_init_early\n"); |
| 186 | 201 | ||
| 187 | /* Initialize hash table, from now on, we can take hash faults | 202 | /* Initialize hash table, from now on, we can take hash faults |
diff --git a/arch/powerpc/platforms/maple/time.c b/arch/powerpc/platforms/maple/time.c index 15846cc938ac..50bc4eb85353 100644 --- a/arch/powerpc/platforms/maple/time.c +++ b/arch/powerpc/platforms/maple/time.c | |||
| @@ -168,11 +168,24 @@ unsigned long __init maple_get_boot_time(void) | |||
| 168 | struct rtc_time tm; | 168 | struct rtc_time tm; |
| 169 | struct device_node *rtcs; | 169 | struct device_node *rtcs; |
| 170 | 170 | ||
| 171 | rtcs = find_compatible_devices("rtc", "pnpPNP,b00"); | 171 | rtcs = of_find_compatible_node(NULL, "rtc", "pnpPNP,b00"); |
| 172 | if (rtcs && rtcs->addrs) { | 172 | if (rtcs) { |
| 173 | maple_rtc_addr = rtcs->addrs[0].address; | 173 | struct resource r; |
| 174 | printk(KERN_INFO "Maple: Found RTC at 0x%x\n", maple_rtc_addr); | 174 | if (of_address_to_resource(rtcs, 0, &r)) { |
| 175 | } else { | 175 | printk(KERN_EMERG "Maple: Unable to translate RTC" |
| 176 | " address\n"); | ||
| 177 | goto bail; | ||
| 178 | } | ||
| 179 | if (!(r.flags & IORESOURCE_IO)) { | ||
| 180 | printk(KERN_EMERG "Maple: RTC address isn't PIO!\n"); | ||
| 181 | goto bail; | ||
| 182 | } | ||
| 183 | maple_rtc_addr = r.start; | ||
| 184 | printk(KERN_INFO "Maple: Found RTC at IO 0x%x\n", | ||
| 185 | maple_rtc_addr); | ||
| 186 | } | ||
| 187 | bail: | ||
| 188 | if (maple_rtc_addr == 0) { | ||
| 176 | maple_rtc_addr = RTC_PORT(0); /* legacy address */ | 189 | maple_rtc_addr = RTC_PORT(0); /* legacy address */ |
| 177 | printk(KERN_INFO "Maple: No device node for RTC, assuming " | 190 | printk(KERN_INFO "Maple: No device node for RTC, assuming " |
| 178 | "legacy address (0x%x)\n", maple_rtc_addr); | 191 | "legacy address (0x%x)\n", maple_rtc_addr); |
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 1fe445ab78a6..8952528d31ac 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c | |||
| @@ -254,11 +254,11 @@ out: | |||
| 254 | void vpa_init(int cpu) | 254 | void vpa_init(int cpu) |
| 255 | { | 255 | { |
| 256 | int hwcpu = get_hard_smp_processor_id(cpu); | 256 | int hwcpu = get_hard_smp_processor_id(cpu); |
| 257 | unsigned long vpa = __pa(&paca[cpu].lppaca); | 257 | unsigned long vpa = __pa(&lppaca[cpu]); |
| 258 | long ret; | 258 | long ret; |
| 259 | 259 | ||
| 260 | if (cpu_has_feature(CPU_FTR_ALTIVEC)) | 260 | if (cpu_has_feature(CPU_FTR_ALTIVEC)) |
| 261 | paca[cpu].lppaca.vmxregs_in_use = 1; | 261 | lppaca[cpu].vmxregs_in_use = 1; |
| 262 | 262 | ||
| 263 | ret = register_vpa(hwcpu, vpa); | 263 | ret = register_vpa(hwcpu, vpa); |
| 264 | 264 | ||
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index d8864164dbe8..86cfa6ecdcf3 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c | |||
| @@ -350,6 +350,100 @@ static int do_remove_node(char *buf) | |||
| 350 | return rv; | 350 | return rv; |
| 351 | } | 351 | } |
| 352 | 352 | ||
| 353 | static char *parse_node(char *buf, size_t bufsize, struct device_node **npp) | ||
| 354 | { | ||
| 355 | char *handle_str; | ||
| 356 | phandle handle; | ||
| 357 | *npp = NULL; | ||
| 358 | |||
| 359 | handle_str = buf; | ||
| 360 | |||
| 361 | buf = strchr(buf, ' '); | ||
| 362 | if (!buf) | ||
| 363 | return NULL; | ||
| 364 | *buf = '\0'; | ||
| 365 | buf++; | ||
| 366 | |||
| 367 | handle = simple_strtoul(handle_str, NULL, 10); | ||
| 368 | |||
| 369 | *npp = of_find_node_by_phandle(handle); | ||
| 370 | return buf; | ||
| 371 | } | ||
| 372 | |||
| 373 | static int do_add_property(char *buf, size_t bufsize) | ||
| 374 | { | ||
| 375 | struct property *prop = NULL; | ||
| 376 | struct device_node *np; | ||
| 377 | unsigned char *value; | ||
| 378 | char *name, *end; | ||
| 379 | int length; | ||
| 380 | end = buf + bufsize; | ||
| 381 | buf = parse_node(buf, bufsize, &np); | ||
| 382 | |||
| 383 | if (!np) | ||
| 384 | return -ENODEV; | ||
| 385 | |||
| 386 | if (parse_next_property(buf, end, &name, &length, &value) == NULL) | ||
| 387 | return -EINVAL; | ||
| 388 | |||
| 389 | prop = new_property(name, length, value, NULL); | ||
| 390 | if (!prop) | ||
| 391 | return -ENOMEM; | ||
| 392 | |||
| 393 | prom_add_property(np, prop); | ||
| 394 | |||
| 395 | return 0; | ||
| 396 | } | ||
| 397 | |||
| 398 | static int do_remove_property(char *buf, size_t bufsize) | ||
| 399 | { | ||
| 400 | struct device_node *np; | ||
| 401 | char *tmp; | ||
| 402 | struct property *prop; | ||
| 403 | buf = parse_node(buf, bufsize, &np); | ||
| 404 | |||
| 405 | if (!np) | ||
| 406 | return -ENODEV; | ||
| 407 | |||
| 408 | tmp = strchr(buf,' '); | ||
| 409 | if (tmp) | ||
| 410 | *tmp = '\0'; | ||
| 411 | |||
| 412 | if (strlen(buf) == 0) | ||
| 413 | return -EINVAL; | ||
| 414 | |||
| 415 | prop = of_find_property(np, buf, NULL); | ||
| 416 | |||
| 417 | return prom_remove_property(np, prop); | ||
| 418 | } | ||
| 419 | |||
| 420 | static int do_update_property(char *buf, size_t bufsize) | ||
| 421 | { | ||
| 422 | struct device_node *np; | ||
| 423 | unsigned char *value; | ||
| 424 | char *name, *end; | ||
| 425 | int length; | ||
| 426 | struct property *newprop, *oldprop; | ||
| 427 | buf = parse_node(buf, bufsize, &np); | ||
| 428 | end = buf + bufsize; | ||
| 429 | |||
| 430 | if (!np) | ||
| 431 | return -ENODEV; | ||
| 432 | |||
| 433 | if (parse_next_property(buf, end, &name, &length, &value) == NULL) | ||
| 434 | return -EINVAL; | ||
| 435 | |||
| 436 | newprop = new_property(name, length, value, NULL); | ||
| 437 | if (!newprop) | ||
| 438 | return -ENOMEM; | ||
| 439 | |||
| 440 | oldprop = of_find_property(np, name,NULL); | ||
| 441 | if (!oldprop) | ||
| 442 | return -ENODEV; | ||
| 443 | |||
| 444 | return prom_update_property(np, newprop, oldprop); | ||
| 445 | } | ||
| 446 | |||
| 353 | /** | 447 | /** |
| 354 | * ofdt_write - perform operations on the Open Firmware device tree | 448 | * ofdt_write - perform operations on the Open Firmware device tree |
| 355 | * | 449 | * |
| @@ -392,6 +486,12 @@ static ssize_t ofdt_write(struct file *file, const char __user *buf, size_t coun | |||
| 392 | rv = do_add_node(tmp, count - (tmp - kbuf)); | 486 | rv = do_add_node(tmp, count - (tmp - kbuf)); |
| 393 | else if (!strcmp(kbuf, "remove_node")) | 487 | else if (!strcmp(kbuf, "remove_node")) |
| 394 | rv = do_remove_node(tmp); | 488 | rv = do_remove_node(tmp); |
| 489 | else if (!strcmp(kbuf, "add_property")) | ||
| 490 | rv = do_add_property(tmp, count - (tmp - kbuf)); | ||
| 491 | else if (!strcmp(kbuf, "remove_property")) | ||
| 492 | rv = do_remove_property(tmp, count - (tmp - kbuf)); | ||
| 493 | else if (!strcmp(kbuf, "update_property")) | ||
| 494 | rv = do_update_property(tmp, count - (tmp - kbuf)); | ||
| 395 | else | 495 | else |
| 396 | rv = -EINVAL; | 496 | rv = -EINVAL; |
| 397 | out: | 497 | out: |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 68b7f086d63d..da6cebaf72cd 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
| @@ -190,7 +190,7 @@ static void pseries_lpar_enable_pmcs(void) | |||
| 190 | 190 | ||
| 191 | /* instruct hypervisor to maintain PMCs */ | 191 | /* instruct hypervisor to maintain PMCs */ |
| 192 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) | 192 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) |
| 193 | get_paca()->lppaca.pmcregs_in_use = 1; | 193 | get_lppaca()->pmcregs_in_use = 1; |
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | static void __init pSeries_setup_arch(void) | 196 | static void __init pSeries_setup_arch(void) |
| @@ -234,7 +234,7 @@ static void __init pSeries_setup_arch(void) | |||
| 234 | /* Choose an idle loop */ | 234 | /* Choose an idle loop */ |
| 235 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) { | 235 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) { |
| 236 | vpa_init(boot_cpuid); | 236 | vpa_init(boot_cpuid); |
| 237 | if (get_paca()->lppaca.shared_proc) { | 237 | if (get_lppaca()->shared_proc) { |
| 238 | printk(KERN_INFO "Using shared processor idle loop\n"); | 238 | printk(KERN_INFO "Using shared processor idle loop\n"); |
| 239 | ppc_md.idle_loop = pseries_shared_idle; | 239 | ppc_md.idle_loop = pseries_shared_idle; |
| 240 | } else { | 240 | } else { |
| @@ -444,10 +444,10 @@ DECLARE_PER_CPU(unsigned long, smt_snooze_delay); | |||
| 444 | 444 | ||
| 445 | static inline void dedicated_idle_sleep(unsigned int cpu) | 445 | static inline void dedicated_idle_sleep(unsigned int cpu) |
| 446 | { | 446 | { |
| 447 | struct paca_struct *ppaca = &paca[cpu ^ 1]; | 447 | struct lppaca *plppaca = &lppaca[cpu ^ 1]; |
| 448 | 448 | ||
| 449 | /* Only sleep if the other thread is not idle */ | 449 | /* Only sleep if the other thread is not idle */ |
| 450 | if (!(ppaca->lppaca.idle)) { | 450 | if (!(plppaca->idle)) { |
| 451 | local_irq_disable(); | 451 | local_irq_disable(); |
| 452 | 452 | ||
| 453 | /* | 453 | /* |
| @@ -480,7 +480,6 @@ static inline void dedicated_idle_sleep(unsigned int cpu) | |||
| 480 | 480 | ||
| 481 | static void pseries_dedicated_idle(void) | 481 | static void pseries_dedicated_idle(void) |
| 482 | { | 482 | { |
| 483 | struct paca_struct *lpaca = get_paca(); | ||
| 484 | unsigned int cpu = smp_processor_id(); | 483 | unsigned int cpu = smp_processor_id(); |
| 485 | unsigned long start_snooze; | 484 | unsigned long start_snooze; |
| 486 | unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay); | 485 | unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay); |
| @@ -491,7 +490,7 @@ static void pseries_dedicated_idle(void) | |||
| 491 | * Indicate to the HV that we are idle. Now would be | 490 | * Indicate to the HV that we are idle. Now would be |
| 492 | * a good time to find other work to dispatch. | 491 | * a good time to find other work to dispatch. |
| 493 | */ | 492 | */ |
| 494 | lpaca->lppaca.idle = 1; | 493 | get_lppaca()->idle = 1; |
| 495 | 494 | ||
| 496 | if (!need_resched()) { | 495 | if (!need_resched()) { |
| 497 | start_snooze = get_tb() + | 496 | start_snooze = get_tb() + |
| @@ -518,7 +517,7 @@ static void pseries_dedicated_idle(void) | |||
| 518 | HMT_medium(); | 517 | HMT_medium(); |
| 519 | } | 518 | } |
| 520 | 519 | ||
| 521 | lpaca->lppaca.idle = 0; | 520 | get_lppaca()->idle = 0; |
| 522 | ppc64_runlatch_on(); | 521 | ppc64_runlatch_on(); |
| 523 | 522 | ||
| 524 | preempt_enable_no_resched(); | 523 | preempt_enable_no_resched(); |
| @@ -532,7 +531,6 @@ static void pseries_dedicated_idle(void) | |||
| 532 | 531 | ||
| 533 | static void pseries_shared_idle(void) | 532 | static void pseries_shared_idle(void) |
| 534 | { | 533 | { |
| 535 | struct paca_struct *lpaca = get_paca(); | ||
| 536 | unsigned int cpu = smp_processor_id(); | 534 | unsigned int cpu = smp_processor_id(); |
| 537 | 535 | ||
| 538 | while (1) { | 536 | while (1) { |
| @@ -540,7 +538,7 @@ static void pseries_shared_idle(void) | |||
| 540 | * Indicate to the HV that we are idle. Now would be | 538 | * Indicate to the HV that we are idle. Now would be |
| 541 | * a good time to find other work to dispatch. | 539 | * a good time to find other work to dispatch. |
| 542 | */ | 540 | */ |
| 543 | lpaca->lppaca.idle = 1; | 541 | get_lppaca()->idle = 1; |
| 544 | 542 | ||
| 545 | while (!need_resched() && !cpu_is_offline(cpu)) { | 543 | while (!need_resched() && !cpu_is_offline(cpu)) { |
| 546 | local_irq_disable(); | 544 | local_irq_disable(); |
| @@ -564,7 +562,7 @@ static void pseries_shared_idle(void) | |||
| 564 | HMT_medium(); | 562 | HMT_medium(); |
| 565 | } | 563 | } |
| 566 | 564 | ||
| 567 | lpaca->lppaca.idle = 0; | 565 | get_lppaca()->idle = 0; |
| 568 | ppc64_runlatch_on(); | 566 | ppc64_runlatch_on(); |
| 569 | 567 | ||
| 570 | preempt_enable_no_resched(); | 568 | preempt_enable_no_resched(); |
| @@ -588,7 +586,7 @@ static void pseries_kexec_cpu_down(int crash_shutdown, int secondary) | |||
| 588 | { | 586 | { |
| 589 | /* Don't risk a hypervisor call if we're crashing */ | 587 | /* Don't risk a hypervisor call if we're crashing */ |
| 590 | if (!crash_shutdown) { | 588 | if (!crash_shutdown) { |
| 591 | unsigned long vpa = __pa(&get_paca()->lppaca); | 589 | unsigned long vpa = __pa(get_lppaca()); |
| 592 | 590 | ||
| 593 | if (unregister_vpa(hard_smp_processor_id(), vpa)) { | 591 | if (unregister_vpa(hard_smp_processor_id(), vpa)) { |
| 594 | printk("VPA deregistration of cpu %u (hw_cpu_id %d) " | 592 | printk("VPA deregistration of cpu %u (hw_cpu_id %d) " |
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 0ae841347a09..4c2b356774ea 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile | |||
| @@ -7,3 +7,4 @@ obj-$(CONFIG_40x) += dcr.o | |||
| 7 | obj-$(CONFIG_U3_DART) += dart_iommu.o | 7 | obj-$(CONFIG_U3_DART) += dart_iommu.o |
| 8 | obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o | 8 | obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o |
| 9 | obj-$(CONFIG_PPC_83xx) += ipic.o | 9 | obj-$(CONFIG_PPC_83xx) += ipic.o |
| 10 | obj-$(CONFIG_FSL_SOC) += fsl_soc.o | ||
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c new file mode 100644 index 000000000000..064c9de47732 --- /dev/null +++ b/arch/powerpc/sysdev/fsl_soc.c | |||
| @@ -0,0 +1,317 @@ | |||
| 1 | /* | ||
| 2 | * FSL SoC setup code | ||
| 3 | * | ||
| 4 | * Maintained by Kumar Gala (see MAINTAINERS for contact information) | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License as published by the | ||
| 8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 9 | * option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/config.h> | ||
| 13 | #include <linux/stddef.h> | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/errno.h> | ||
| 17 | #include <linux/major.h> | ||
| 18 | #include <linux/delay.h> | ||
| 19 | #include <linux/irq.h> | ||
| 20 | #include <linux/module.h> | ||
| 21 | #include <linux/device.h> | ||
| 22 | #include <linux/platform_device.h> | ||
| 23 | #include <linux/fsl_devices.h> | ||
| 24 | |||
| 25 | #include <asm/system.h> | ||
| 26 | #include <asm/atomic.h> | ||
| 27 | #include <asm/io.h> | ||
| 28 | #include <asm/irq.h> | ||
| 29 | #include <asm/prom.h> | ||
| 30 | #include <sysdev/fsl_soc.h> | ||
| 31 | #include <mm/mmu_decl.h> | ||
| 32 | |||
| 33 | static phys_addr_t immrbase = -1; | ||
| 34 | |||
| 35 | phys_addr_t get_immrbase(void) | ||
| 36 | { | ||
| 37 | struct device_node *soc; | ||
| 38 | |||
| 39 | if (immrbase != -1) | ||
| 40 | return immrbase; | ||
| 41 | |||
| 42 | soc = of_find_node_by_type(NULL, "soc"); | ||
| 43 | if (soc != 0) { | ||
| 44 | unsigned int size; | ||
| 45 | void *prop = get_property(soc, "reg", &size); | ||
| 46 | immrbase = of_translate_address(soc, prop); | ||
| 47 | of_node_put(soc); | ||
| 48 | }; | ||
| 49 | |||
| 50 | return immrbase; | ||
| 51 | } | ||
| 52 | EXPORT_SYMBOL(get_immrbase); | ||
| 53 | |||
| 54 | static const char * gfar_tx_intr = "tx"; | ||
| 55 | static const char * gfar_rx_intr = "rx"; | ||
| 56 | static const char * gfar_err_intr = "error"; | ||
| 57 | |||
| 58 | static int __init gfar_of_init(void) | ||
| 59 | { | ||
| 60 | struct device_node *np; | ||
| 61 | unsigned int i; | ||
| 62 | struct platform_device *mdio_dev, *gfar_dev; | ||
| 63 | struct resource res; | ||
| 64 | int ret; | ||
| 65 | |||
| 66 | for (np = NULL, i = 0; (np = of_find_compatible_node(np, "mdio", "gianfar")) != NULL; i++) { | ||
| 67 | int k; | ||
| 68 | struct device_node *child = NULL; | ||
| 69 | struct gianfar_mdio_data mdio_data; | ||
| 70 | |||
| 71 | memset(&res, 0, sizeof(res)); | ||
| 72 | memset(&mdio_data, 0, sizeof(mdio_data)); | ||
| 73 | |||
| 74 | ret = of_address_to_resource(np, 0, &res); | ||
| 75 | if (ret) | ||
| 76 | goto mdio_err; | ||
| 77 | |||
| 78 | mdio_dev = platform_device_register_simple("fsl-gianfar_mdio", res.start, &res, 1); | ||
| 79 | if (IS_ERR(mdio_dev)) { | ||
| 80 | ret = PTR_ERR(mdio_dev); | ||
| 81 | goto mdio_err; | ||
| 82 | } | ||
| 83 | |||
| 84 | for (k = 0; k < 32; k++) | ||
| 85 | mdio_data.irq[k] = -1; | ||
| 86 | |||
| 87 | while ((child = of_get_next_child(np, child)) != NULL) { | ||
| 88 | if (child->n_intrs) { | ||
| 89 | u32 *id = (u32 *) get_property(child, "reg", NULL); | ||
| 90 | mdio_data.irq[*id] = child->intrs[0].line; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | ret = platform_device_add_data(mdio_dev, &mdio_data, sizeof(struct gianfar_mdio_data)); | ||
| 95 | if (ret) | ||
| 96 | goto mdio_unreg; | ||
| 97 | } | ||
| 98 | |||
| 99 | for (np = NULL, i = 0; (np = of_find_compatible_node(np, "network", "gianfar")) != NULL; i++) { | ||
| 100 | struct resource r[4]; | ||
| 101 | struct device_node *phy, *mdio; | ||
| 102 | struct gianfar_platform_data gfar_data; | ||
| 103 | unsigned int *id; | ||
| 104 | char *model; | ||
| 105 | void *mac_addr; | ||
| 106 | phandle *ph; | ||
| 107 | |||
| 108 | memset(r, 0, sizeof(r)); | ||
| 109 | memset(&gfar_data, 0, sizeof(gfar_data)); | ||
| 110 | |||
| 111 | ret = of_address_to_resource(np, 0, &r[0]); | ||
| 112 | if (ret) | ||
| 113 | goto gfar_err; | ||
| 114 | |||
| 115 | r[1].start = np->intrs[0].line; | ||
| 116 | r[1].end = np->intrs[0].line; | ||
| 117 | r[1].flags = IORESOURCE_IRQ; | ||
| 118 | |||
| 119 | model = get_property(np, "model", NULL); | ||
| 120 | |||
| 121 | /* If we aren't the FEC we have multiple interrupts */ | ||
| 122 | if (model && strcasecmp(model, "FEC")) { | ||
| 123 | r[1].name = gfar_tx_intr; | ||
| 124 | |||
| 125 | r[2].name = gfar_rx_intr; | ||
| 126 | r[2].start = np->intrs[1].line; | ||
| 127 | r[2].end = np->intrs[1].line; | ||
| 128 | r[2].flags = IORESOURCE_IRQ; | ||
| 129 | |||
| 130 | r[3].name = gfar_err_intr; | ||
| 131 | r[3].start = np->intrs[2].line; | ||
| 132 | r[3].end = np->intrs[2].line; | ||
| 133 | r[3].flags = IORESOURCE_IRQ; | ||
| 134 | } | ||
| 135 | |||
| 136 | gfar_dev = platform_device_register_simple("fsl-gianfar", i, &r[0], np->n_intrs + 1); | ||
| 137 | |||
| 138 | if (IS_ERR(gfar_dev)) { | ||
| 139 | ret = PTR_ERR(gfar_dev); | ||
| 140 | goto gfar_err; | ||
| 141 | } | ||
| 142 | |||
| 143 | mac_addr = get_property(np, "address", NULL); | ||
| 144 | memcpy(gfar_data.mac_addr, mac_addr, 6); | ||
| 145 | |||
| 146 | if (model && !strcasecmp(model, "TSEC")) | ||
| 147 | gfar_data.device_flags = | ||
| 148 | FSL_GIANFAR_DEV_HAS_GIGABIT | | ||
| 149 | FSL_GIANFAR_DEV_HAS_COALESCE | | ||
| 150 | FSL_GIANFAR_DEV_HAS_RMON | | ||
| 151 | FSL_GIANFAR_DEV_HAS_MULTI_INTR; | ||
| 152 | if (model && !strcasecmp(model, "eTSEC")) | ||
| 153 | gfar_data.device_flags = | ||
| 154 | FSL_GIANFAR_DEV_HAS_GIGABIT | | ||
| 155 | FSL_GIANFAR_DEV_HAS_COALESCE | | ||
| 156 | FSL_GIANFAR_DEV_HAS_RMON | | ||
| 157 | FSL_GIANFAR_DEV_HAS_MULTI_INTR | | ||
| 158 | FSL_GIANFAR_DEV_HAS_CSUM | | ||
| 159 | FSL_GIANFAR_DEV_HAS_VLAN | | ||
| 160 | FSL_GIANFAR_DEV_HAS_EXTENDED_HASH; | ||
| 161 | |||
| 162 | ph = (phandle *) get_property(np, "phy-handle", NULL); | ||
| 163 | phy = of_find_node_by_phandle(*ph); | ||
| 164 | |||
| 165 | if (phy == NULL) { | ||
| 166 | ret = -ENODEV; | ||
| 167 | goto gfar_unreg; | ||
| 168 | } | ||
| 169 | |||
| 170 | mdio = of_get_parent(phy); | ||
| 171 | |||
| 172 | id = (u32 *) get_property(phy, "reg", NULL); | ||
| 173 | ret = of_address_to_resource(mdio, 0, &res); | ||
| 174 | if (ret) { | ||
| 175 | of_node_put(phy); | ||
| 176 | of_node_put(mdio); | ||
| 177 | goto gfar_unreg; | ||
| 178 | } | ||
| 179 | |||
| 180 | gfar_data.phy_id = *id; | ||
| 181 | gfar_data.bus_id = res.start; | ||
| 182 | |||
| 183 | of_node_put(phy); | ||
| 184 | of_node_put(mdio); | ||
| 185 | |||
| 186 | ret = platform_device_add_data(gfar_dev, &gfar_data, sizeof(struct gianfar_platform_data)); | ||
| 187 | if (ret) | ||
| 188 | goto gfar_unreg; | ||
| 189 | } | ||
| 190 | |||
| 191 | return 0; | ||
| 192 | |||
| 193 | mdio_unreg: | ||
| 194 | platform_device_unregister(mdio_dev); | ||
| 195 | mdio_err: | ||
| 196 | return ret; | ||
| 197 | |||
| 198 | gfar_unreg: | ||
| 199 | platform_device_unregister(gfar_dev); | ||
| 200 | gfar_err: | ||
| 201 | return ret; | ||
| 202 | } | ||
| 203 | arch_initcall(gfar_of_init); | ||
| 204 | |||
| 205 | static int __init fsl_i2c_of_init(void) | ||
| 206 | { | ||
| 207 | struct device_node *np; | ||
| 208 | unsigned int i; | ||
| 209 | struct platform_device *i2c_dev; | ||
| 210 | int ret; | ||
| 211 | |||
| 212 | for (np = NULL, i = 0; (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL; i++) { | ||
| 213 | struct resource r[2]; | ||
| 214 | struct fsl_i2c_platform_data i2c_data; | ||
| 215 | unsigned char * flags = NULL; | ||
| 216 | |||
| 217 | memset(&r, 0, sizeof(r)); | ||
| 218 | memset(&i2c_data, 0, sizeof(i2c_data)); | ||
| 219 | |||
| 220 | ret = of_address_to_resource(np, 0, &r[0]); | ||
| 221 | if (ret) | ||
| 222 | goto i2c_err; | ||
| 223 | |||
| 224 | r[1].start = np->intrs[0].line; | ||
| 225 | r[1].end = np->intrs[0].line; | ||
| 226 | r[1].flags = IORESOURCE_IRQ; | ||
| 227 | |||
| 228 | i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2); | ||
| 229 | if (IS_ERR(i2c_dev)) { | ||
| 230 | ret = PTR_ERR(i2c_dev); | ||
| 231 | goto i2c_err; | ||
| 232 | } | ||
| 233 | |||
| 234 | i2c_data.device_flags = 0; | ||
| 235 | flags = get_property(np, "dfsrr", NULL); | ||
| 236 | if (flags) | ||
| 237 | i2c_data.device_flags |= FSL_I2C_DEV_SEPARATE_DFSRR; | ||
| 238 | |||
| 239 | flags = get_property(np, "fsl5200-clocking", NULL); | ||
| 240 | if (flags) | ||
| 241 | i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200; | ||
| 242 | |||
| 243 | ret = platform_device_add_data(i2c_dev, &i2c_data, sizeof(struct fsl_i2c_platform_data)); | ||
| 244 | if (ret) | ||
| 245 | goto i2c_unreg; | ||
| 246 | } | ||
| 247 | |||
| 248 | return 0; | ||
| 249 | |||
| 250 | i2c_unreg: | ||
| 251 | platform_device_unregister(i2c_dev); | ||
| 252 | i2c_err: | ||
| 253 | return ret; | ||
| 254 | } | ||
| 255 | arch_initcall(fsl_i2c_of_init); | ||
| 256 | |||
| 257 | #ifdef CONFIG_PPC_83xx | ||
| 258 | static int __init mpc83xx_wdt_init(void) | ||
| 259 | { | ||
| 260 | struct resource r; | ||
| 261 | struct device_node *soc, *np; | ||
| 262 | struct platform_device *dev; | ||
| 263 | unsigned int *freq; | ||
| 264 | int ret; | ||
| 265 | |||
| 266 | np = of_find_compatible_node(NULL, "watchdog", "mpc83xx_wdt"); | ||
| 267 | |||
| 268 | if (!np) { | ||
| 269 | ret = -ENODEV; | ||
| 270 | goto mpc83xx_wdt_nodev; | ||
| 271 | } | ||
| 272 | |||
| 273 | soc = of_find_node_by_type(NULL, "soc"); | ||
| 274 | |||
| 275 | if (!soc) { | ||
| 276 | ret = -ENODEV; | ||
| 277 | goto mpc83xx_wdt_nosoc; | ||
| 278 | } | ||
| 279 | |||
| 280 | freq = (unsigned int *)get_property(soc, "bus-frequency", NULL); | ||
| 281 | if (!freq) { | ||
| 282 | ret = -ENODEV; | ||
| 283 | goto mpc83xx_wdt_err; | ||
| 284 | } | ||
| 285 | |||
| 286 | memset(&r, 0, sizeof(r)); | ||
| 287 | |||
| 288 | ret = of_address_to_resource(np, 0, &r); | ||
| 289 | if (ret) | ||
| 290 | goto mpc83xx_wdt_err; | ||
| 291 | |||
| 292 | dev = platform_device_register_simple("mpc83xx_wdt", 0, &r, 1); | ||
| 293 | if (IS_ERR(dev)) { | ||
| 294 | ret = PTR_ERR(dev); | ||
| 295 | goto mpc83xx_wdt_err; | ||
| 296 | } | ||
| 297 | |||
| 298 | ret = platform_device_add_data(dev, freq, sizeof(int)); | ||
| 299 | if (ret) | ||
| 300 | goto mpc83xx_wdt_unreg; | ||
| 301 | |||
| 302 | of_node_put(soc); | ||
| 303 | of_node_put(np); | ||
| 304 | |||
| 305 | return 0; | ||
| 306 | |||
| 307 | mpc83xx_wdt_unreg: | ||
| 308 | platform_device_unregister(dev); | ||
| 309 | mpc83xx_wdt_err: | ||
| 310 | of_node_put(soc); | ||
| 311 | mpc83xx_wdt_nosoc: | ||
| 312 | of_node_put(np); | ||
| 313 | mpc83xx_wdt_nodev: | ||
| 314 | return ret; | ||
| 315 | } | ||
| 316 | arch_initcall(mpc83xx_wdt_init); | ||
| 317 | #endif | ||
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h new file mode 100644 index 000000000000..c433d3f39edd --- /dev/null +++ b/arch/powerpc/sysdev/fsl_soc.h | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | #ifndef __PPC_FSL_SOC_H | ||
| 2 | #define __PPC_FSL_SOC_H | ||
| 3 | #ifdef __KERNEL__ | ||
| 4 | |||
| 5 | extern phys_addr_t get_immrbase(void); | ||
| 6 | |||
| 7 | #endif | ||
| 8 | #endif | ||
diff --git a/arch/ppc/4xx_io/serial_sicc.c b/arch/ppc/4xx_io/serial_sicc.c index ebc4db8fcc63..8ace2a1f3b48 100644 --- a/arch/ppc/4xx_io/serial_sicc.c +++ b/arch/ppc/4xx_io/serial_sicc.c | |||
| @@ -215,7 +215,6 @@ static struct tty_driver *siccnormal_driver; | |||
| 215 | * memory if large numbers of serial ports are open. | 215 | * memory if large numbers of serial ports are open. |
| 216 | */ | 216 | */ |
| 217 | static u_char *tmp_buf; | 217 | static u_char *tmp_buf; |
| 218 | static DECLARE_MUTEX(tmp_buf_sem); | ||
| 219 | 218 | ||
| 220 | #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) | 219 | #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) |
| 221 | 220 | ||
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index d65810108bc3..11899f06bf06 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig | |||
| @@ -58,11 +58,11 @@ config 6xx | |||
| 58 | help | 58 | help |
| 59 | There are four types of PowerPC chips supported. The more common | 59 | There are four types of PowerPC chips supported. The more common |
| 60 | types (601, 603, 604, 740, 750, 7400), the Motorola embedded | 60 | types (601, 603, 604, 740, 750, 7400), the Motorola embedded |
| 61 | versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the IBM embedded | 61 | versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the IBM |
| 62 | versions (403 and 405) and the high end 64 bit Power processors | 62 | embedded versions (403 and 405) and the POWER3 processor. |
| 63 | (POWER 3, POWER4, and IBM 970 also known as G5) | 63 | (For support for more recent 64-bit processors, set ARCH=powerpc.) |
| 64 | Unless you are building a kernel for one of the embedded processor | 64 | Unless you are building a kernel for one of the embedded processor |
| 65 | systems, 64 bit IBM RS/6000 or an Apple G5, choose 6xx. | 65 | systems or a POWER3-based IBM RS/6000, choose 6xx. |
| 66 | Note that the kernel runs in 32-bit mode even on 64-bit chips. | 66 | Note that the kernel runs in 32-bit mode even on 64-bit chips. |
| 67 | Also note that because the 52xx, 82xx, & 83xx family has a 603e core, | 67 | Also note that because the 52xx, 82xx, & 83xx family has a 603e core, |
| 68 | specific support for that chipset is asked later on. | 68 | specific support for that chipset is asked later on. |
| @@ -77,10 +77,6 @@ config POWER3 | |||
| 77 | select PPC_FPU | 77 | select PPC_FPU |
| 78 | bool "POWER3" | 78 | bool "POWER3" |
| 79 | 79 | ||
| 80 | config POWER4 | ||
| 81 | select PPC_FPU | ||
| 82 | bool "POWER4 and 970 (G5)" | ||
| 83 | |||
| 84 | config 8xx | 80 | config 8xx |
| 85 | bool "8xx" | 81 | bool "8xx" |
| 86 | 82 | ||
| @@ -123,7 +119,7 @@ config PHYS_64BIT | |||
| 123 | 119 | ||
| 124 | config ALTIVEC | 120 | config ALTIVEC |
| 125 | bool "AltiVec Support" | 121 | bool "AltiVec Support" |
| 126 | depends on 6xx || POWER4 | 122 | depends on 6xx |
| 127 | depends on !8260 && !83xx | 123 | depends on !8260 && !83xx |
| 128 | ---help--- | 124 | ---help--- |
| 129 | This option enables kernel support for the Altivec extensions to the | 125 | This option enables kernel support for the Altivec extensions to the |
| @@ -235,18 +231,9 @@ config KEXEC | |||
| 235 | 231 | ||
| 236 | source "drivers/cpufreq/Kconfig" | 232 | source "drivers/cpufreq/Kconfig" |
| 237 | 233 | ||
| 238 | config CPU_FREQ_PMAC | ||
| 239 | bool "Support for Apple PowerBooks" | ||
| 240 | depends on CPU_FREQ && ADB_PMU | ||
| 241 | select CPU_FREQ_TABLE | ||
| 242 | help | ||
| 243 | This adds support for frequency switching on Apple PowerBooks, | ||
| 244 | this currently includes some models of iBook & Titanium | ||
| 245 | PowerBook. | ||
| 246 | |||
| 247 | config PPC601_SYNC_FIX | 234 | config PPC601_SYNC_FIX |
| 248 | bool "Workarounds for PPC601 bugs" | 235 | bool "Workarounds for PPC601 bugs" |
| 249 | depends on 6xx && (PPC_PREP || PPC_PMAC) | 236 | depends on 6xx && PPC_PREP |
| 250 | help | 237 | help |
| 251 | Some versions of the PPC601 (the first PowerPC chip) have bugs which | 238 | Some versions of the PPC601 (the first PowerPC chip) have bugs which |
| 252 | mean that extra synchronization instructions are required near | 239 | mean that extra synchronization instructions are required near |
| @@ -258,26 +245,17 @@ config PPC601_SYNC_FIX | |||
| 258 | 245 | ||
| 259 | If in doubt, say Y here. | 246 | If in doubt, say Y here. |
| 260 | 247 | ||
| 261 | config HOTPLUG_CPU | ||
| 262 | bool "Support for enabling/disabling CPUs" | ||
| 263 | depends on SMP && HOTPLUG && EXPERIMENTAL && PPC_PMAC | ||
| 264 | ---help--- | ||
| 265 | Say Y here to be able to disable and re-enable individual | ||
| 266 | CPUs at runtime on SMP machines. | ||
| 267 | |||
| 268 | Say N if you are unsure. | ||
| 269 | |||
| 270 | source arch/ppc/platforms/4xx/Kconfig | 248 | source arch/ppc/platforms/4xx/Kconfig |
| 271 | source arch/ppc/platforms/85xx/Kconfig | 249 | source arch/ppc/platforms/85xx/Kconfig |
| 272 | 250 | ||
| 273 | config PPC64BRIDGE | 251 | config PPC64BRIDGE |
| 274 | bool | 252 | bool |
| 275 | depends on POWER3 || POWER4 | 253 | depends on POWER3 |
| 276 | default y | 254 | default y |
| 277 | 255 | ||
| 278 | config PPC_STD_MMU | 256 | config PPC_STD_MMU |
| 279 | bool | 257 | bool |
| 280 | depends on 6xx || POWER3 || POWER4 | 258 | depends on 6xx || POWER3 |
| 281 | default y | 259 | default y |
| 282 | 260 | ||
| 283 | config NOT_COHERENT_CACHE | 261 | config NOT_COHERENT_CACHE |
| @@ -505,7 +483,7 @@ endchoice | |||
| 505 | 483 | ||
| 506 | choice | 484 | choice |
| 507 | prompt "Machine Type" | 485 | prompt "Machine Type" |
| 508 | depends on 6xx || POWER3 || POWER4 | 486 | depends on 6xx || POWER3 |
| 509 | default PPC_MULTIPLATFORM | 487 | default PPC_MULTIPLATFORM |
| 510 | ---help--- | 488 | ---help--- |
| 511 | Linux currently supports several different kinds of PowerPC-based | 489 | Linux currently supports several different kinds of PowerPC-based |
| @@ -516,11 +494,15 @@ choice | |||
| 516 | Platform) machines (including all of the recent IBM RS/6000 and | 494 | Platform) machines (including all of the recent IBM RS/6000 and |
| 517 | pSeries machines), and several embedded PowerPC systems containing | 495 | pSeries machines), and several embedded PowerPC systems containing |
| 518 | 4xx, 6xx, 7xx, 8xx, 74xx, and 82xx processors. Currently, the | 496 | 4xx, 6xx, 7xx, 8xx, 74xx, and 82xx processors. Currently, the |
| 519 | default option is to build a kernel which works on the first three. | 497 | default option is to build a kernel which works on PReP and CHRP. |
| 520 | 498 | ||
| 521 | Select CHRP/PowerMac/PReP if configuring for an IBM RS/6000 or | 499 | Note that support for Apple machines is now only available with |
| 522 | pSeries machine, a Power Macintosh (including iMacs, iBooks and | 500 | ARCH=powerpc, and has been removed from this menu. If you wish |
| 523 | Powerbooks), or a PReP machine. | 501 | to build a kernel for an Apple machine, exit this configuration |
| 502 | process and re-run it with ARCH=powerpc. | ||
| 503 | |||
| 504 | Select CHRP/PReP if configuring for an IBM RS/6000 or | ||
| 505 | pSeries machine, or a PReP machine. | ||
| 524 | 506 | ||
| 525 | Select Gemini if configuring for a Synergy Microsystems' Gemini | 507 | Select Gemini if configuring for a Synergy Microsystems' Gemini |
| 526 | series Single Board Computer. More information is available at: | 508 | series Single Board Computer. More information is available at: |
| @@ -530,7 +512,7 @@ choice | |||
| 530 | available at: <http://linux-apus.sourceforge.net/>. | 512 | available at: <http://linux-apus.sourceforge.net/>. |
| 531 | 513 | ||
| 532 | config PPC_MULTIPLATFORM | 514 | config PPC_MULTIPLATFORM |
| 533 | bool "CHRP/PowerMac/PReP" | 515 | bool "CHRP/PReP" |
| 534 | 516 | ||
| 535 | config APUS | 517 | config APUS |
| 536 | bool "Amiga-APUS" | 518 | bool "Amiga-APUS" |
| @@ -768,25 +750,14 @@ config CPM2 | |||
| 768 | on it (826x, 827x, 8560). | 750 | on it (826x, 827x, 8560). |
| 769 | 751 | ||
| 770 | config PPC_CHRP | 752 | config PPC_CHRP |
| 771 | bool | 753 | bool "Support for CHRP (Common Hardware Reference Platform) machines" |
| 772 | depends on PPC_MULTIPLATFORM | 754 | depends on PPC_MULTIPLATFORM |
| 773 | select PPC_I8259 | 755 | select PPC_I8259 |
| 774 | select PPC_INDIRECT_PCI | 756 | select PPC_INDIRECT_PCI |
| 775 | default y | 757 | default y |
| 776 | 758 | ||
| 777 | config PPC_PMAC | ||
| 778 | bool | ||
| 779 | depends on PPC_MULTIPLATFORM | ||
| 780 | select PPC_INDIRECT_PCI | ||
| 781 | default y | ||
| 782 | |||
| 783 | config PPC_PMAC64 | ||
| 784 | bool | ||
| 785 | depends on PPC_PMAC && POWER4 | ||
| 786 | default y | ||
| 787 | |||
| 788 | config PPC_PREP | 759 | config PPC_PREP |
| 789 | bool | 760 | bool "Support for PReP (PowerPC Reference Platform) machines" |
| 790 | depends on PPC_MULTIPLATFORM | 761 | depends on PPC_MULTIPLATFORM |
| 791 | select PPC_I8259 | 762 | select PPC_I8259 |
| 792 | select PPC_INDIRECT_PCI | 763 | select PPC_INDIRECT_PCI |
| @@ -794,7 +765,7 @@ config PPC_PREP | |||
| 794 | 765 | ||
| 795 | config PPC_OF | 766 | config PPC_OF |
| 796 | bool | 767 | bool |
| 797 | depends on PPC_PMAC || PPC_CHRP | 768 | depends on PPC_CHRP |
| 798 | default y | 769 | default y |
| 799 | 770 | ||
| 800 | config PPC_GEN550 | 771 | config PPC_GEN550 |
| @@ -1166,7 +1137,7 @@ config ISA | |||
| 1166 | 1137 | ||
| 1167 | config GENERIC_ISA_DMA | 1138 | config GENERIC_ISA_DMA |
| 1168 | bool | 1139 | bool |
| 1169 | depends on POWER3 || POWER4 || 6xx && !CPM2 | 1140 | depends on POWER3 || 6xx && !CPM2 |
| 1170 | default y | 1141 | default y |
| 1171 | 1142 | ||
| 1172 | config PPC_I8259 | 1143 | config PPC_I8259 |
diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile index 995f89bb049c..efd8ce515d5f 100644 --- a/arch/ppc/boot/Makefile +++ b/arch/ppc/boot/Makefile | |||
| @@ -18,7 +18,7 @@ BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd | |||
| 18 | bootdir-y := simple | 18 | bootdir-y := simple |
| 19 | bootdir-$(CONFIG_PPC_OF) += openfirmware | 19 | bootdir-$(CONFIG_PPC_OF) += openfirmware |
| 20 | subdir-y := lib common images | 20 | subdir-y := lib common images |
| 21 | subdir-$(CONFIG_PPC_OF) += of1275 | 21 | subdir-$(CONFIG_PPC_MULTIPLATFORM) += of1275 |
| 22 | 22 | ||
| 23 | # for cleaning | 23 | # for cleaning |
| 24 | subdir- += simple openfirmware | 24 | subdir- += simple openfirmware |
diff --git a/arch/ppc/boot/openfirmware/Makefile b/arch/ppc/boot/openfirmware/Makefile index 83a6433459ce..2a411ec2e650 100644 --- a/arch/ppc/boot/openfirmware/Makefile +++ b/arch/ppc/boot/openfirmware/Makefile | |||
| @@ -21,26 +21,16 @@ bootlib := $(boot)/lib | |||
| 21 | of1275 := $(boot)/of1275 | 21 | of1275 := $(boot)/of1275 |
| 22 | images := $(boot)/images | 22 | images := $(boot)/images |
| 23 | 23 | ||
| 24 | OBJCOPY_ARGS := -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment | ||
| 25 | COFF_LD_ARGS := -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00500000 \ | ||
| 26 | -Bstatic | ||
| 27 | CHRP_LD_ARGS := -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00800000 | 24 | CHRP_LD_ARGS := -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00800000 |
| 28 | NEWWORLD_LD_ARGS:= -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x01000000 | ||
| 29 | 25 | ||
| 30 | COMMONOBJS := start.o misc.o common.o | 26 | COMMONOBJS := start.o misc.o common.o |
| 31 | COFFOBJS := coffcrt0.o $(COMMONOBJS) coffmain.o | ||
| 32 | CHRPOBJS := crt0.o $(COMMONOBJS) chrpmain.o | 27 | CHRPOBJS := crt0.o $(COMMONOBJS) chrpmain.o |
| 33 | NEWWORLDOBJS := crt0.o $(COMMONOBJS) newworldmain.o | ||
| 34 | 28 | ||
| 35 | targets := $(COFFOBJS) $(CHRPOBJS) $(NEWWORLDOBJS) dummy.o | 29 | targets := $(CHRPOBJS) dummy.o |
| 36 | COFFOBJS := $(addprefix $(obj)/, $(COFFOBJS)) | ||
| 37 | CHRPOBJS := $(addprefix $(obj)/, $(CHRPOBJS)) | 30 | CHRPOBJS := $(addprefix $(obj)/, $(CHRPOBJS)) |
| 38 | NEWWORLDOBJS := $(addprefix $(obj)/, $(NEWWORLDOBJS)) | ||
| 39 | 31 | ||
| 40 | LIBS := lib/lib.a $(bootlib)/lib.a $(of1275)/lib.a $(common)/lib.a | 32 | LIBS := lib/lib.a $(bootlib)/lib.a $(of1275)/lib.a $(common)/lib.a |
| 41 | 33 | ||
| 42 | HACKCOFF := $(utils)/hack-coff | ||
| 43 | |||
| 44 | ifdef CONFIG_SMP | 34 | ifdef CONFIG_SMP |
| 45 | END := .smp | 35 | END := .smp |
| 46 | endif | 36 | endif |
| @@ -72,56 +62,11 @@ targets += image.initrd.o | |||
| 72 | $(obj)/image.initrd.o: $(obj)/image.o $(images)/ramdisk.image.gz FORCE | 62 | $(obj)/image.initrd.o: $(obj)/image.o $(images)/ramdisk.image.gz FORCE |
| 73 | $(call if_changed,genimage-initrd) | 63 | $(call if_changed,genimage-initrd) |
| 74 | 64 | ||
| 75 | # Create the note section for New-World PowerMacs. | ||
| 76 | quiet_cmd_mknote = MKNOTE $@ | ||
| 77 | cmd_mknote = $(utils)/mknote > $@ | ||
| 78 | targets += note | ||
| 79 | $(obj)/note: $(utils)/mknote FORCE | ||
| 80 | $(call if_changed,mknote) | ||
| 81 | |||
| 82 | 65 | ||
| 83 | $(obj)/coffcrt0.o: EXTRA_AFLAGS := -DXCOFF | 66 | targets += crt0.o |
| 84 | targets += coffcrt0.o crt0.o | 67 | $(obj)/crt0.o: $(common)/crt0.S FORCE |
| 85 | $(obj)/coffcrt0.o $(obj)/crt0.o: $(common)/crt0.S FORCE | ||
| 86 | $(call if_changed_dep,as_o_S) | 68 | $(call if_changed_dep,as_o_S) |
| 87 | 69 | ||
| 88 | quiet_cmd_gencoffb = COFF $@ | ||
| 89 | cmd_gencoffb = $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) $< $(LIBS) && \ | ||
| 90 | $(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec) | ||
| 91 | targets += coffboot | ||
| 92 | $(obj)/coffboot: $(obj)/image.o $(COFFOBJS) $(LIBS) $(srctree)/$(boot)/ld.script FORCE | ||
| 93 | $(call if_changed,gencoffb) | ||
| 94 | targets += coffboot.initrd | ||
| 95 | $(obj)/coffboot.initrd: $(obj)/image.initrd.o $(COFFOBJS) $(LIBS) \ | ||
| 96 | $(srctree)/$(boot)/ld.script FORCE | ||
| 97 | $(call if_changed,gencoffb) | ||
| 98 | |||
| 99 | |||
| 100 | quiet_cmd_gen-coff = COFF $@ | ||
| 101 | cmd_gen-coff = $(OBJCOPY) $(OBJCOPY_ARGS) $< $@ && \ | ||
| 102 | $(HACKCOFF) $@ && \ | ||
| 103 | ln -sf $(notdir $@) $(images)/zImage$(initrd).pmac | ||
| 104 | |||
| 105 | $(images)/vmlinux.coff: $(obj)/coffboot | ||
| 106 | $(call cmd,gen-coff) | ||
| 107 | |||
| 108 | $(images)/vmlinux.initrd.coff: $(obj)/coffboot.initrd | ||
| 109 | $(call cmd,gen-coff) | ||
| 110 | |||
| 111 | quiet_cmd_gen-elf-pmac = ELF $@ | ||
| 112 | cmd_gen-elf-pmac = $(LD) $(NEWWORLD_LD_ARGS) -o $@ \ | ||
| 113 | $(NEWWORLDOBJS) $(LIBS) $< && \ | ||
| 114 | $(OBJCOPY) $@ $@ --add-section=.note=$(obj)/note \ | ||
| 115 | -R .comment $(del-ramdisk-sec) | ||
| 116 | |||
| 117 | $(images)/vmlinux.elf-pmac: $(obj)/image.o $(NEWWORLDOBJS) $(LIBS) \ | ||
| 118 | $(obj)/note $(srctree)/$(boot)/ld.script | ||
| 119 | $(call cmd,gen-elf-pmac) | ||
| 120 | $(images)/vmlinux.initrd.elf-pmac: $(obj)/image.initrd.o $(NEWWORLDOBJS) \ | ||
| 121 | $(LIBS) $(obj)/note \ | ||
| 122 | $(srctree)/$(boot)/ld.script | ||
| 123 | $(call cmd,gen-elf-pmac) | ||
| 124 | |||
| 125 | quiet_cmd_gen-chrp = CHRP $@ | 70 | quiet_cmd_gen-chrp = CHRP $@ |
| 126 | cmd_gen-chrp = $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) $< $(LIBS) && \ | 71 | cmd_gen-chrp = $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) $< $(LIBS) && \ |
| 127 | $(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec) | 72 | $(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec) |
| @@ -139,46 +84,23 @@ $(images)/zImage.chrp-rs6k $(images)/zImage.initrd.chrp-rs6k: \ | |||
| 139 | %-rs6k: % | 84 | %-rs6k: % |
| 140 | $(call cmd,addnote) | 85 | $(call cmd,addnote) |
| 141 | 86 | ||
| 142 | quiet_cmd_gen-miboot = GEN $@ | ||
| 143 | cmd_gen-miboot = $(OBJCOPY) $(OBJCOPY_ARGS) \ | ||
| 144 | --add-section=$1=$(word 2, $^) $< $@ | ||
| 145 | $(images)/miboot.image: $(obj)/dummy.o $(images)/vmlinux.gz | ||
| 146 | $(call cmd,gen-miboot,image) | ||
| 147 | |||
| 148 | $(images)/miboot.initrd.image: $(images)/miboot.image $(images)/ramdisk.image.gz | ||
| 149 | $(call cmd,gen-miboot,initrd) | ||
| 150 | |||
| 151 | # The targets used on the make command-line | 87 | # The targets used on the make command-line |
| 152 | 88 | ||
| 153 | .PHONY: zImage zImage.initrd | 89 | .PHONY: zImage zImage.initrd |
| 154 | zImage: $(images)/vmlinux.coff \ | 90 | zImage: $(images)/zImage.chrp \ |
| 155 | $(images)/vmlinux.elf-pmac \ | 91 | $(images)/zImage.chrp-rs6k |
| 156 | $(images)/zImage.chrp \ | ||
| 157 | $(images)/zImage.chrp-rs6k \ | ||
| 158 | $(images)/miboot.image | ||
| 159 | @echo ' kernel: $@ is ready ($<)' | 92 | @echo ' kernel: $@ is ready ($<)' |
| 160 | zImage.initrd: $(images)/vmlinux.initrd.coff \ | 93 | zImage.initrd: $(images)/zImage.initrd.chrp \ |
| 161 | $(images)/vmlinux.initrd.elf-pmac \ | 94 | $(images)/zImage.initrd.chrp-rs6k |
| 162 | $(images)/zImage.initrd.chrp \ | ||
| 163 | $(images)/zImage.initrd.chrp-rs6k \ | ||
| 164 | $(images)/miboot.initrd.image | ||
| 165 | @echo ' kernel: $@ is ready ($<)' | 95 | @echo ' kernel: $@ is ready ($<)' |
| 166 | 96 | ||
| 167 | TFTPIMAGE := /tftpboot/zImage | 97 | TFTPIMAGE := /tftpboot/zImage |
| 168 | 98 | ||
| 169 | .PHONY: znetboot znetboot.initrd | 99 | .PHONY: znetboot znetboot.initrd |
| 170 | znetboot: $(images)/vmlinux.coff \ | 100 | znetboot: $(images)/zImage.chrp |
| 171 | $(images)/vmlinux.elf-pmac \ | ||
| 172 | $(images)/zImage.chrp | ||
| 173 | cp $(images)/vmlinux.coff $(TFTPIMAGE).pmac$(END) | ||
| 174 | cp $(images)/vmlinux.elf-pmac $(TFTPIMAGE).pmac$(END).elf | ||
| 175 | cp $(images)/zImage.chrp $(TFTPIMAGE).chrp$(END) | 101 | cp $(images)/zImage.chrp $(TFTPIMAGE).chrp$(END) |
| 176 | @echo ' kernel: $@ is ready ($<)' | 102 | @echo ' kernel: $@ is ready ($<)' |
| 177 | znetboot.initrd:$(images)/vmlinux.initrd.coff \ | 103 | znetboot.initrd:$(images)/zImage.initrd.chrp |
| 178 | $(images)/vmlinux.initrd.elf-pmac \ | ||
| 179 | $(images)/zImage.initrd.chrp | ||
| 180 | cp $(images)/vmlinux.initrd.coff $(TFTPIMAGE).pmac$(END) | ||
| 181 | cp $(images)/vmlinux.initrd.elf-pmac $(TFTPIMAGE).pmac$(END).elf | ||
| 182 | cp $(images)/zImage.initrd.chrp $(TFTPIMAGE).chrp$(END) | 104 | cp $(images)/zImage.initrd.chrp $(TFTPIMAGE).chrp$(END) |
| 183 | @echo ' kernel: $@ is ready ($<)' | 105 | @echo ' kernel: $@ is ready ($<)' |
| 184 | 106 | ||
diff --git a/arch/ppc/boot/openfirmware/coffmain.c b/arch/ppc/boot/openfirmware/coffmain.c deleted file mode 100644 index 2da8855e2be0..000000000000 --- a/arch/ppc/boot/openfirmware/coffmain.c +++ /dev/null | |||
| @@ -1,101 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) Paul Mackerras 1997. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU General Public License | ||
| 6 | * as published by the Free Software Foundation; either version | ||
| 7 | * 2 of the License, or (at your option) any later version. | ||
| 8 | */ | ||
| 9 | #include <linux/string.h> | ||
| 10 | #include <asm/processor.h> | ||
| 11 | #include <asm/page.h> | ||
| 12 | |||
| 13 | #include "nonstdio.h" | ||
| 14 | #include "of1275.h" | ||
| 15 | |||
| 16 | /* Passed from the linker */ | ||
| 17 | extern char __image_begin, __image_end; | ||
| 18 | extern char __ramdisk_begin[], __ramdisk_end; | ||
| 19 | extern char _start, _end; | ||
| 20 | |||
| 21 | extern char image_data[], initrd_data[]; | ||
| 22 | extern int initrd_len, image_len; | ||
| 23 | extern unsigned int heap_max; | ||
| 24 | extern void flush_cache(void *start, unsigned int len); | ||
| 25 | extern void gunzip(void *, int, unsigned char *, int *); | ||
| 26 | extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach, | ||
| 27 | unsigned int progend); | ||
| 28 | extern void setup_bats(unsigned long start); | ||
| 29 | |||
| 30 | char *avail_ram; | ||
| 31 | char *begin_avail, *end_avail; | ||
| 32 | char *avail_high; | ||
| 33 | |||
| 34 | #define SCRATCH_SIZE (128 << 10) | ||
| 35 | |||
| 36 | static char heap[SCRATCH_SIZE]; | ||
| 37 | |||
| 38 | static unsigned long ram_start = 0; | ||
| 39 | static unsigned long ram_end = 0x1000000; | ||
| 40 | |||
| 41 | static unsigned long prog_start = 0x800000; | ||
| 42 | static unsigned long prog_size = 0x700000; | ||
| 43 | |||
| 44 | typedef void (*kernel_start_t)(int, int, void *); | ||
| 45 | |||
| 46 | void boot(int a1, int a2, void *prom) | ||
| 47 | { | ||
| 48 | unsigned sa, len; | ||
| 49 | void *dst; | ||
| 50 | unsigned char *im; | ||
| 51 | unsigned initrd_start, initrd_size; | ||
| 52 | |||
| 53 | printf("coffboot starting: loaded at 0x%p\n", &_start); | ||
| 54 | setup_bats(ram_start); | ||
| 55 | |||
| 56 | initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin); | ||
| 57 | if (initrd_size) { | ||
| 58 | initrd_start = (ram_end - initrd_size) & ~0xFFF; | ||
| 59 | a1 = initrd_start; | ||
| 60 | a2 = initrd_size; | ||
| 61 | claim(initrd_start, ram_end - initrd_start, 0); | ||
| 62 | printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r", | ||
| 63 | initrd_start, (char *)(&__ramdisk_begin), initrd_size); | ||
| 64 | memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size); | ||
| 65 | prog_size = initrd_start - prog_start; | ||
| 66 | } else | ||
| 67 | a2 = 0xdeadbeef; | ||
| 68 | |||
| 69 | im = (char *)(&__image_begin); | ||
| 70 | len = (char *)(&__image_end) - (char *)(&__image_begin); | ||
| 71 | /* claim 4MB starting at PROG_START */ | ||
| 72 | claim(prog_start, prog_size, 0); | ||
| 73 | map(prog_start, prog_start, prog_size); | ||
| 74 | dst = (void *) prog_start; | ||
| 75 | if (im[0] == 0x1f && im[1] == 0x8b) { | ||
| 76 | /* set up scratch space */ | ||
| 77 | begin_avail = avail_high = avail_ram = heap; | ||
| 78 | end_avail = heap + sizeof(heap); | ||
| 79 | printf("heap at 0x%p\n", avail_ram); | ||
| 80 | printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len); | ||
| 81 | gunzip(dst, prog_size, im, &len); | ||
| 82 | printf("done %u bytes\n", len); | ||
| 83 | printf("%u bytes of heap consumed, max in use %u\n", | ||
| 84 | avail_high - begin_avail, heap_max); | ||
| 85 | } else { | ||
| 86 | memmove(dst, im, len); | ||
| 87 | } | ||
| 88 | |||
| 89 | flush_cache(dst, len); | ||
| 90 | make_bi_recs(((unsigned long) dst + len), "coffboot", _MACH_Pmac, | ||
| 91 | (prog_start + prog_size)); | ||
| 92 | |||
| 93 | sa = (unsigned long)prog_start; | ||
| 94 | printf("start address = 0x%x\n", sa); | ||
| 95 | |||
| 96 | (*(kernel_start_t)sa)(a1, a2, prom); | ||
| 97 | |||
| 98 | printf("returned?\n"); | ||
| 99 | |||
| 100 | pause(); | ||
| 101 | } | ||
diff --git a/arch/ppc/boot/openfirmware/newworldmain.c b/arch/ppc/boot/openfirmware/newworldmain.c deleted file mode 100644 index fa8a8f9313f9..000000000000 --- a/arch/ppc/boot/openfirmware/newworldmain.c +++ /dev/null | |||
| @@ -1,94 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) Paul Mackerras 1997. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU General Public License | ||
| 6 | * as published by the Free Software Foundation; either version | ||
| 7 | * 2 of the License, or (at your option) any later version. | ||
| 8 | */ | ||
| 9 | #include <linux/string.h> | ||
| 10 | #include "nonstdio.h" | ||
| 11 | #include "of1275.h" | ||
| 12 | #include <asm/processor.h> | ||
| 13 | #include <asm/page.h> | ||
| 14 | |||
| 15 | /* Passed from the linker */ | ||
| 16 | extern char __image_begin, __image_end; | ||
| 17 | extern char __ramdisk_begin[], __ramdisk_end; | ||
| 18 | extern char _start, _end; | ||
| 19 | |||
| 20 | extern unsigned int heap_max; | ||
| 21 | extern void flush_cache(void *start, unsigned int len); | ||
| 22 | extern void gunzip(void *, int, unsigned char *, int *); | ||
| 23 | extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach, | ||
| 24 | unsigned int progend); | ||
| 25 | |||
| 26 | char *avail_ram; | ||
| 27 | char *begin_avail, *end_avail; | ||
| 28 | char *avail_high; | ||
| 29 | |||
| 30 | |||
| 31 | #define RAM_END (16 << 20) | ||
| 32 | |||
| 33 | #define PROG_START 0x00010000 | ||
| 34 | #define PROG_SIZE 0x007f0000 | ||
| 35 | |||
| 36 | #define SCRATCH_SIZE (128 << 10) | ||
| 37 | |||
| 38 | typedef void (*kernel_start_t)(int, int, void *); | ||
| 39 | |||
| 40 | void boot(int a1, int a2, void *prom) | ||
| 41 | { | ||
| 42 | unsigned sa, len; | ||
| 43 | void *dst; | ||
| 44 | unsigned char *im; | ||
| 45 | unsigned initrd_start, initrd_size; | ||
| 46 | |||
| 47 | printf("chrpboot starting: loaded at 0x%p\n", &_start); | ||
| 48 | |||
| 49 | initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin); | ||
| 50 | if (initrd_size) { | ||
| 51 | initrd_start = (RAM_END - initrd_size) & ~0xFFF; | ||
| 52 | a1 = initrd_start; | ||
| 53 | a2 = initrd_size; | ||
| 54 | claim(initrd_start, RAM_END - initrd_start, 0); | ||
| 55 | printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r", | ||
| 56 | initrd_start, (char *)(&__ramdisk_begin), initrd_size); | ||
| 57 | memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size); | ||
| 58 | } else | ||
| 59 | a2 = 0xdeadbeef; | ||
| 60 | |||
| 61 | im = (char *)(&__image_begin); | ||
| 62 | len = (char *)(&__image_end) - (char *)(&__image_begin); | ||
| 63 | /* claim 3MB starting at PROG_START */ | ||
| 64 | claim(PROG_START, PROG_SIZE, 0); | ||
| 65 | dst = (void *) PROG_START; | ||
| 66 | if (im[0] == 0x1f && im[1] == 0x8b) { | ||
| 67 | /* claim some memory for scratch space */ | ||
| 68 | avail_ram = (char *) claim(0, SCRATCH_SIZE, 0x10); | ||
| 69 | begin_avail = avail_high = avail_ram; | ||
| 70 | end_avail = avail_ram + SCRATCH_SIZE; | ||
| 71 | printf("heap at 0x%p\n", avail_ram); | ||
| 72 | printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len); | ||
| 73 | gunzip(dst, PROG_SIZE, im, &len); | ||
| 74 | printf("done %u bytes\n", len); | ||
| 75 | printf("%u bytes of heap consumed, max in use %u\n", | ||
| 76 | avail_high - begin_avail, heap_max); | ||
| 77 | release(begin_avail, SCRATCH_SIZE); | ||
| 78 | } else { | ||
| 79 | memmove(dst, im, len); | ||
| 80 | } | ||
| 81 | |||
| 82 | flush_cache(dst, len); | ||
| 83 | make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_Pmac, | ||
| 84 | (PROG_START + PROG_SIZE)); | ||
| 85 | |||
| 86 | sa = (unsigned long)PROG_START; | ||
| 87 | printf("start address = 0x%x\n", sa); | ||
| 88 | |||
| 89 | (*(kernel_start_t)sa)(a1, a2, prom); | ||
| 90 | |||
| 91 | printf("returned?\n"); | ||
| 92 | |||
| 93 | pause(); | ||
| 94 | } | ||
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index ca0201300868..e399bbb969a4 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile | |||
| @@ -9,7 +9,6 @@ extra-$(CONFIG_44x) := head_44x.o | |||
| 9 | extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o | 9 | extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o |
| 10 | extra-$(CONFIG_8xx) := head_8xx.o | 10 | extra-$(CONFIG_8xx) := head_8xx.o |
| 11 | extra-$(CONFIG_6xx) += idle_6xx.o | 11 | extra-$(CONFIG_6xx) += idle_6xx.o |
| 12 | extra-$(CONFIG_POWER4) += idle_power4.o | ||
| 13 | extra-y += vmlinux.lds | 12 | extra-y += vmlinux.lds |
| 14 | 13 | ||
| 15 | obj-y := entry.o traps.o idle.o time.o misc.o \ | 14 | obj-y := entry.o traps.o idle.o time.o misc.o \ |
| @@ -17,7 +16,6 @@ obj-y := entry.o traps.o idle.o time.o misc.o \ | |||
| 17 | ppc_htab.o | 16 | ppc_htab.o |
| 18 | obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o | 17 | obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o |
| 19 | obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o | 18 | obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o |
| 20 | obj-$(CONFIG_POWER4) += cpu_setup_power4.o | ||
| 21 | obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o | 19 | obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o |
| 22 | obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o | 20 | obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o |
| 23 | obj-$(CONFIG_PCI) += pci.o | 21 | obj-$(CONFIG_PCI) += pci.o |
| @@ -42,7 +40,6 @@ obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o | |||
| 42 | obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o | 40 | obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o |
| 43 | obj-$(CONFIG_MODULES) += module.o | 41 | obj-$(CONFIG_MODULES) += module.o |
| 44 | obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o | 42 | obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o |
| 45 | obj-$(CONFIG_PCI) += pci.o | ||
| 46 | obj-$(CONFIG_KGDB) += ppc-stub.o | 43 | obj-$(CONFIG_KGDB) += ppc-stub.o |
| 47 | obj-$(CONFIG_TAU) += temp.o | 44 | obj-$(CONFIG_TAU) += temp.o |
| 48 | ifndef CONFIG_E200 | 45 | ifndef CONFIG_E200 |
diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S index de0978742221..3e6ca7f5843f 100644 --- a/arch/ppc/kernel/head_8xx.S +++ b/arch/ppc/kernel/head_8xx.S | |||
| @@ -375,6 +375,8 @@ DataStoreTLBMiss: | |||
| 375 | lis r11, swapper_pg_dir@h | 375 | lis r11, swapper_pg_dir@h |
| 376 | ori r11, r11, swapper_pg_dir@l | 376 | ori r11, r11, swapper_pg_dir@l |
| 377 | rlwimi r10, r11, 0, 2, 19 | 377 | rlwimi r10, r11, 0, 2, 19 |
| 378 | stw r12, 16(r0) | ||
| 379 | b LoadLargeDTLB | ||
| 378 | 3: | 380 | 3: |
| 379 | lwz r11, 0(r10) /* Get the level 1 entry */ | 381 | lwz r11, 0(r10) /* Get the level 1 entry */ |
| 380 | rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ | 382 | rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ |
| @@ -430,6 +432,81 @@ DataStoreTLBMiss: | |||
| 430 | InstructionTLBError: | 432 | InstructionTLBError: |
| 431 | b InstructionAccess | 433 | b InstructionAccess |
| 432 | 434 | ||
| 435 | LoadLargeDTLB: | ||
| 436 | li r12, 0 | ||
| 437 | lwz r11, 0(r10) /* Get the level 1 entry */ | ||
| 438 | rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ | ||
| 439 | beq 3f /* If zero, don't try to find a pte */ | ||
| 440 | |||
| 441 | /* We have a pte table, so load fetch the pte from the table. | ||
| 442 | */ | ||
| 443 | ori r11, r11, 1 /* Set valid bit in physical L2 page */ | ||
| 444 | DO_8xx_CPU6(0x3b80, r3) | ||
| 445 | mtspr SPRN_MD_TWC, r11 /* Load pte table base address */ | ||
| 446 | mfspr r10, SPRN_MD_TWC /* ....and get the pte address */ | ||
| 447 | lwz r10, 0(r10) /* Get the pte */ | ||
| 448 | |||
| 449 | /* Insert the Guarded flag into the TWC from the Linux PTE. | ||
| 450 | * It is bit 27 of both the Linux PTE and the TWC (at least | ||
| 451 | * I got that right :-). It will be better when we can put | ||
| 452 | * this into the Linux pgd/pmd and load it in the operation | ||
| 453 | * above. | ||
| 454 | */ | ||
| 455 | rlwimi r11, r10, 0, 27, 27 | ||
| 456 | |||
| 457 | rlwimi r12, r10, 0, 0, 9 /* extract phys. addr */ | ||
| 458 | mfspr r3, SPRN_MD_EPN | ||
| 459 | rlwinm r3, r3, 0, 0, 9 /* extract virtual address */ | ||
| 460 | tophys(r3, r3) | ||
| 461 | cmpw r3, r12 /* only use 8M page if it is a direct | ||
| 462 | kernel mapping */ | ||
| 463 | bne 1f | ||
| 464 | ori r11, r11, MD_PS8MEG | ||
| 465 | li r12, 1 | ||
| 466 | b 2f | ||
| 467 | 1: | ||
| 468 | li r12, 0 /* can't use 8MB TLB, so zero r12. */ | ||
| 469 | 2: | ||
| 470 | DO_8xx_CPU6(0x3b80, r3) | ||
| 471 | mtspr SPRN_MD_TWC, r11 | ||
| 472 | |||
| 473 | /* The Linux PTE won't go exactly into the MMU TLB. | ||
| 474 | * Software indicator bits 21, 22 and 28 must be clear. | ||
| 475 | * Software indicator bits 24, 25, 26, and 27 must be | ||
| 476 | * set. All other Linux PTE bits control the behavior | ||
| 477 | * of the MMU. | ||
| 478 | */ | ||
| 479 | 3: li r11, 0x00f0 | ||
| 480 | rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */ | ||
| 481 | cmpwi r12, 1 | ||
| 482 | bne 4f | ||
| 483 | ori r10, r10, 0x8 | ||
| 484 | |||
| 485 | mfspr r12, SPRN_MD_EPN | ||
| 486 | lis r3, 0xff80 /* 10-19 must be clear for 8MB TLB */ | ||
| 487 | ori r3, r3, 0x0fff | ||
| 488 | and r12, r3, r12 | ||
| 489 | DO_8xx_CPU6(0x3780, r3) | ||
| 490 | mtspr SPRN_MD_EPN, r12 | ||
| 491 | |||
| 492 | lis r3, 0xff80 /* 10-19 must be clear for 8MB TLB */ | ||
| 493 | ori r3, r3, 0x0fff | ||
| 494 | and r10, r3, r10 | ||
| 495 | 4: | ||
| 496 | DO_8xx_CPU6(0x3d80, r3) | ||
| 497 | mtspr SPRN_MD_RPN, r10 /* Update TLB entry */ | ||
| 498 | |||
| 499 | mfspr r10, SPRN_M_TW /* Restore registers */ | ||
| 500 | lwz r11, 0(r0) | ||
| 501 | mtcr r11 | ||
| 502 | lwz r11, 4(r0) | ||
| 503 | |||
| 504 | lwz r12, 16(r0) | ||
| 505 | #ifdef CONFIG_8xx_CPU6 | ||
| 506 | lwz r3, 8(r0) | ||
| 507 | #endif | ||
| 508 | rfi | ||
| 509 | |||
| 433 | /* This is the data TLB error on the MPC8xx. This could be due to | 510 | /* This is the data TLB error on the MPC8xx. This could be due to |
| 434 | * many reasons, including a dirty update to a pte. We can catch that | 511 | * many reasons, including a dirty update to a pte. We can catch that |
| 435 | * one here, but anything else is an error. First, we track down the | 512 | * one here, but anything else is an error. First, we track down the |
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index fb5658bba285..c3427eed8345 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S | |||
| @@ -204,78 +204,6 @@ _GLOBAL(call_setup_cpu) | |||
| 204 | mtctr r5 | 204 | mtctr r5 |
| 205 | bctr | 205 | bctr |
| 206 | 206 | ||
| 207 | #if defined(CONFIG_CPU_FREQ_PMAC) && defined(CONFIG_6xx) | ||
| 208 | |||
| 209 | /* This gets called by via-pmu.c to switch the PLL selection | ||
| 210 | * on 750fx CPU. This function should really be moved to some | ||
| 211 | * other place (as most of the cpufreq code in via-pmu | ||
| 212 | */ | ||
| 213 | _GLOBAL(low_choose_750fx_pll) | ||
| 214 | /* Clear MSR:EE */ | ||
| 215 | mfmsr r7 | ||
| 216 | rlwinm r0,r7,0,17,15 | ||
| 217 | mtmsr r0 | ||
| 218 | |||
| 219 | /* If switching to PLL1, disable HID0:BTIC */ | ||
| 220 | cmplwi cr0,r3,0 | ||
| 221 | beq 1f | ||
| 222 | mfspr r5,SPRN_HID0 | ||
| 223 | rlwinm r5,r5,0,27,25 | ||
| 224 | sync | ||
| 225 | mtspr SPRN_HID0,r5 | ||
| 226 | isync | ||
| 227 | sync | ||
| 228 | |||
| 229 | 1: | ||
| 230 | /* Calc new HID1 value */ | ||
| 231 | mfspr r4,SPRN_HID1 /* Build a HID1:PS bit from parameter */ | ||
| 232 | rlwinm r5,r3,16,15,15 /* Clear out HID1:PS from value read */ | ||
| 233 | rlwinm r4,r4,0,16,14 /* Could have I used rlwimi here ? */ | ||
| 234 | or r4,r4,r5 | ||
| 235 | mtspr SPRN_HID1,r4 | ||
| 236 | |||
| 237 | /* Store new HID1 image */ | ||
| 238 | rlwinm r6,r1,0,0,18 | ||
| 239 | lwz r6,TI_CPU(r6) | ||
| 240 | slwi r6,r6,2 | ||
| 241 | addis r6,r6,nap_save_hid1@ha | ||
| 242 | stw r4,nap_save_hid1@l(r6) | ||
| 243 | |||
| 244 | /* If switching to PLL0, enable HID0:BTIC */ | ||
| 245 | cmplwi cr0,r3,0 | ||
| 246 | bne 1f | ||
| 247 | mfspr r5,SPRN_HID0 | ||
| 248 | ori r5,r5,HID0_BTIC | ||
| 249 | sync | ||
| 250 | mtspr SPRN_HID0,r5 | ||
| 251 | isync | ||
| 252 | sync | ||
| 253 | |||
| 254 | 1: | ||
| 255 | /* Return */ | ||
| 256 | mtmsr r7 | ||
| 257 | blr | ||
| 258 | |||
| 259 | _GLOBAL(low_choose_7447a_dfs) | ||
| 260 | /* Clear MSR:EE */ | ||
| 261 | mfmsr r7 | ||
| 262 | rlwinm r0,r7,0,17,15 | ||
| 263 | mtmsr r0 | ||
| 264 | |||
| 265 | /* Calc new HID1 value */ | ||
| 266 | mfspr r4,SPRN_HID1 | ||
| 267 | insrwi r4,r3,1,9 /* insert parameter into bit 9 */ | ||
| 268 | sync | ||
| 269 | mtspr SPRN_HID1,r4 | ||
| 270 | sync | ||
| 271 | isync | ||
| 272 | |||
| 273 | /* Return */ | ||
| 274 | mtmsr r7 | ||
| 275 | blr | ||
| 276 | |||
| 277 | #endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_6xx */ | ||
| 278 | |||
| 279 | /* | 207 | /* |
| 280 | * complement mask on the msr then "or" some values on. | 208 | * complement mask on the msr then "or" some values on. |
| 281 | * _nmask_and_or_msr(nmask, value_to_or) | 209 | * _nmask_and_or_msr(nmask, value_to_or) |
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 704c846b2b0f..04d04c5bfdd0 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Common pmac/prep/chrp pci routines. -- Cort | 2 | * Common prep/chrp pci routines. -- Cort |
| 3 | */ | 3 | */ |
| 4 | 4 | ||
| 5 | #include <linux/config.h> | 5 | #include <linux/config.h> |
| @@ -50,8 +50,7 @@ static void fixup_cpc710_pci64(struct pci_dev* dev); | |||
| 50 | static u8* pci_to_OF_bus_map; | 50 | static u8* pci_to_OF_bus_map; |
| 51 | #endif | 51 | #endif |
| 52 | 52 | ||
| 53 | /* By default, we don't re-assign bus numbers. We do this only on | 53 | /* By default, we don't re-assign bus numbers. |
| 54 | * some pmacs | ||
| 55 | */ | 54 | */ |
| 56 | int pci_assign_all_buses; | 55 | int pci_assign_all_buses; |
| 57 | 56 | ||
| @@ -780,17 +779,6 @@ pci_busdev_to_OF_node(struct pci_bus *bus, int devfn) | |||
| 780 | return NULL; | 779 | return NULL; |
| 781 | 780 | ||
| 782 | /* Fixup bus number according to what OF think it is. */ | 781 | /* Fixup bus number according to what OF think it is. */ |
| 783 | #ifdef CONFIG_PPC_PMAC | ||
| 784 | /* The G5 need a special case here. Basically, we don't remap all | ||
| 785 | * busses on it so we don't create the pci-OF-map. However, we do | ||
| 786 | * remap the AGP bus and so have to deal with it. A future better | ||
| 787 | * fix has to be done by making the remapping per-host and always | ||
| 788 | * filling the pci_to_OF map. --BenH | ||
| 789 | */ | ||
| 790 | if (_machine == _MACH_Pmac && busnr >= 0xf0) | ||
| 791 | busnr -= 0xf0; | ||
| 792 | else | ||
| 793 | #endif | ||
| 794 | if (pci_to_OF_bus_map) | 782 | if (pci_to_OF_bus_map) |
| 795 | busnr = pci_to_OF_bus_map[busnr]; | 783 | busnr = pci_to_OF_bus_map[busnr]; |
| 796 | if (busnr == 0xff) | 784 | if (busnr == 0xff) |
| @@ -1040,216 +1028,6 @@ void pcibios_add_platform_entries(struct pci_dev *pdev) | |||
| 1040 | } | 1028 | } |
| 1041 | 1029 | ||
| 1042 | 1030 | ||
| 1043 | #ifdef CONFIG_PPC_PMAC | ||
| 1044 | /* | ||
| 1045 | * This set of routines checks for PCI<->PCI bridges that have closed | ||
| 1046 | * IO resources and have child devices. It tries to re-open an IO | ||
| 1047 | * window on them. | ||
| 1048 | * | ||
| 1049 | * This is a _temporary_ fix to workaround a problem with Apple's OF | ||
| 1050 | * closing IO windows on P2P bridges when the OF drivers of cards | ||
| 1051 | * below this bridge don't claim any IO range (typically ATI or | ||
| 1052 | * Adaptec). | ||
| 1053 | * | ||
| 1054 | * A more complete fix would be to use drivers/pci/setup-bus.c, which | ||
| 1055 | * involves a working pcibios_fixup_pbus_ranges(), some more care about | ||
| 1056 | * ordering when creating the host bus resources, and maybe a few more | ||
| 1057 | * minor tweaks | ||
| 1058 | */ | ||
| 1059 | |||
| 1060 | /* Initialize bridges with base/limit values we have collected */ | ||
| 1061 | static void __init | ||
| 1062 | do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga) | ||
| 1063 | { | ||
| 1064 | struct pci_dev *bridge = bus->self; | ||
| 1065 | struct pci_controller* hose = (struct pci_controller *)bridge->sysdata; | ||
| 1066 | u32 l; | ||
| 1067 | u16 w; | ||
| 1068 | struct resource res; | ||
| 1069 | |||
| 1070 | if (bus->resource[0] == NULL) | ||
| 1071 | return; | ||
| 1072 | res = *(bus->resource[0]); | ||
| 1073 | |||
| 1074 | DBG("Remapping Bus %d, bridge: %s\n", bus->number, pci_name(bridge)); | ||
| 1075 | res.start -= ((unsigned long) hose->io_base_virt - isa_io_base); | ||
| 1076 | res.end -= ((unsigned long) hose->io_base_virt - isa_io_base); | ||
| 1077 | DBG(" IO window: %08lx-%08lx\n", res.start, res.end); | ||
| 1078 | |||
| 1079 | /* Set up the top and bottom of the PCI I/O segment for this bus. */ | ||
| 1080 | pci_read_config_dword(bridge, PCI_IO_BASE, &l); | ||
| 1081 | l &= 0xffff000f; | ||
| 1082 | l |= (res.start >> 8) & 0x00f0; | ||
| 1083 | l |= res.end & 0xf000; | ||
| 1084 | pci_write_config_dword(bridge, PCI_IO_BASE, l); | ||
| 1085 | |||
| 1086 | if ((l & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) { | ||
| 1087 | l = (res.start >> 16) | (res.end & 0xffff0000); | ||
| 1088 | pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, l); | ||
| 1089 | } | ||
| 1090 | |||
| 1091 | pci_read_config_word(bridge, PCI_COMMAND, &w); | ||
| 1092 | w |= PCI_COMMAND_IO; | ||
| 1093 | pci_write_config_word(bridge, PCI_COMMAND, w); | ||
| 1094 | |||
| 1095 | #if 0 /* Enabling this causes XFree 4.2.0 to hang during PCI probe */ | ||
| 1096 | if (enable_vga) { | ||
| 1097 | pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &w); | ||
| 1098 | w |= PCI_BRIDGE_CTL_VGA; | ||
| 1099 | pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, w); | ||
| 1100 | } | ||
| 1101 | #endif | ||
| 1102 | } | ||
| 1103 | |||
| 1104 | /* This function is pretty basic and actually quite broken for the | ||
| 1105 | * general case, it's enough for us right now though. It's supposed | ||
| 1106 | * to tell us if we need to open an IO range at all or not and what | ||
| 1107 | * size. | ||
| 1108 | */ | ||
| 1109 | static int __init | ||
| 1110 | check_for_io_childs(struct pci_bus *bus, struct resource* res, int *found_vga) | ||
| 1111 | { | ||
| 1112 | struct pci_dev *dev; | ||
| 1113 | int i; | ||
| 1114 | int rc = 0; | ||
| 1115 | |||
| 1116 | #define push_end(res, size) do { unsigned long __sz = (size) ; \ | ||
| 1117 | res->end = ((res->end + __sz) / (__sz + 1)) * (__sz + 1) + __sz; \ | ||
| 1118 | } while (0) | ||
| 1119 | |||
| 1120 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
| 1121 | u16 class = dev->class >> 8; | ||
| 1122 | |||
| 1123 | if (class == PCI_CLASS_DISPLAY_VGA || | ||
| 1124 | class == PCI_CLASS_NOT_DEFINED_VGA) | ||
| 1125 | *found_vga = 1; | ||
| 1126 | if (class >> 8 == PCI_BASE_CLASS_BRIDGE && dev->subordinate) | ||
| 1127 | rc |= check_for_io_childs(dev->subordinate, res, found_vga); | ||
| 1128 | if (class == PCI_CLASS_BRIDGE_CARDBUS) | ||
| 1129 | push_end(res, 0xfff); | ||
| 1130 | |||
| 1131 | for (i=0; i<PCI_NUM_RESOURCES; i++) { | ||
| 1132 | struct resource *r; | ||
| 1133 | unsigned long r_size; | ||
| 1134 | |||
| 1135 | if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI | ||
| 1136 | && i >= PCI_BRIDGE_RESOURCES) | ||
| 1137 | continue; | ||
| 1138 | r = &dev->resource[i]; | ||
| 1139 | r_size = r->end - r->start; | ||
| 1140 | if (r_size < 0xfff) | ||
| 1141 | r_size = 0xfff; | ||
| 1142 | if (r->flags & IORESOURCE_IO && (r_size) != 0) { | ||
| 1143 | rc = 1; | ||
| 1144 | push_end(res, r_size); | ||
| 1145 | } | ||
| 1146 | } | ||
| 1147 | } | ||
| 1148 | |||
| 1149 | return rc; | ||
| 1150 | } | ||
| 1151 | |||
| 1152 | /* Here we scan all P2P bridges of a given level that have a closed | ||
| 1153 | * IO window. Note that the test for the presence of a VGA card should | ||
| 1154 | * be improved to take into account already configured P2P bridges, | ||
| 1155 | * currently, we don't see them and might end up configuring 2 bridges | ||
| 1156 | * with VGA pass through enabled | ||
| 1157 | */ | ||
| 1158 | static void __init | ||
| 1159 | do_fixup_p2p_level(struct pci_bus *bus) | ||
| 1160 | { | ||
| 1161 | struct pci_bus *b; | ||
| 1162 | int i, parent_io; | ||
| 1163 | int has_vga = 0; | ||
| 1164 | |||
| 1165 | for (parent_io=0; parent_io<4; parent_io++) | ||
| 1166 | if (bus->resource[parent_io] | ||
| 1167 | && bus->resource[parent_io]->flags & IORESOURCE_IO) | ||
| 1168 | break; | ||
| 1169 | if (parent_io >= 4) | ||
| 1170 | return; | ||
| 1171 | |||
| 1172 | list_for_each_entry(b, &bus->children, node) { | ||
| 1173 | struct pci_dev *d = b->self; | ||
| 1174 | struct pci_controller* hose = (struct pci_controller *)d->sysdata; | ||
| 1175 | struct resource *res = b->resource[0]; | ||
| 1176 | struct resource tmp_res; | ||
| 1177 | unsigned long max; | ||
| 1178 | int found_vga = 0; | ||
| 1179 | |||
| 1180 | memset(&tmp_res, 0, sizeof(tmp_res)); | ||
| 1181 | tmp_res.start = bus->resource[parent_io]->start; | ||
| 1182 | |||
| 1183 | /* We don't let low addresses go through that closed P2P bridge, well, | ||
| 1184 | * that may not be necessary but I feel safer that way | ||
| 1185 | */ | ||
| 1186 | if (tmp_res.start == 0) | ||
| 1187 | tmp_res.start = 0x1000; | ||
| 1188 | |||
| 1189 | if (!list_empty(&b->devices) && res && res->flags == 0 && | ||
| 1190 | res != bus->resource[parent_io] && | ||
| 1191 | (d->class >> 8) == PCI_CLASS_BRIDGE_PCI && | ||
| 1192 | check_for_io_childs(b, &tmp_res, &found_vga)) { | ||
| 1193 | u8 io_base_lo; | ||
| 1194 | |||
| 1195 | printk(KERN_INFO "Fixing up IO bus %s\n", b->name); | ||
| 1196 | |||
| 1197 | if (found_vga) { | ||
| 1198 | if (has_vga) { | ||
| 1199 | printk(KERN_WARNING "Skipping VGA, already active" | ||
| 1200 | " on bus segment\n"); | ||
| 1201 | found_vga = 0; | ||
| 1202 | } else | ||
| 1203 | has_vga = 1; | ||
| 1204 | } | ||
| 1205 | pci_read_config_byte(d, PCI_IO_BASE, &io_base_lo); | ||
| 1206 | |||
| 1207 | if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) | ||
| 1208 | max = ((unsigned long) hose->io_base_virt | ||
| 1209 | - isa_io_base) + 0xffffffff; | ||
| 1210 | else | ||
| 1211 | max = ((unsigned long) hose->io_base_virt | ||
| 1212 | - isa_io_base) + 0xffff; | ||
| 1213 | |||
| 1214 | *res = tmp_res; | ||
| 1215 | res->flags = IORESOURCE_IO; | ||
| 1216 | res->name = b->name; | ||
| 1217 | |||
| 1218 | /* Find a resource in the parent where we can allocate */ | ||
| 1219 | for (i = 0 ; i < 4; i++) { | ||
| 1220 | struct resource *r = bus->resource[i]; | ||
| 1221 | if (!r) | ||
| 1222 | continue; | ||
| 1223 | if ((r->flags & IORESOURCE_IO) == 0) | ||
| 1224 | continue; | ||
| 1225 | DBG("Trying to allocate from %08lx, size %08lx from parent" | ||
| 1226 | " res %d: %08lx -> %08lx\n", | ||
| 1227 | res->start, res->end, i, r->start, r->end); | ||
| 1228 | |||
| 1229 | if (allocate_resource(r, res, res->end + 1, res->start, max, | ||
| 1230 | res->end + 1, NULL, NULL) < 0) { | ||
| 1231 | DBG("Failed !\n"); | ||
| 1232 | continue; | ||
| 1233 | } | ||
| 1234 | do_update_p2p_io_resource(b, found_vga); | ||
| 1235 | break; | ||
| 1236 | } | ||
| 1237 | } | ||
| 1238 | do_fixup_p2p_level(b); | ||
| 1239 | } | ||
| 1240 | } | ||
| 1241 | |||
| 1242 | static void | ||
| 1243 | pcibios_fixup_p2p_bridges(void) | ||
| 1244 | { | ||
| 1245 | struct pci_bus *b; | ||
| 1246 | |||
| 1247 | list_for_each_entry(b, &pci_root_buses, node) | ||
| 1248 | do_fixup_p2p_level(b); | ||
| 1249 | } | ||
| 1250 | |||
| 1251 | #endif /* CONFIG_PPC_PMAC */ | ||
| 1252 | |||
| 1253 | static int __init | 1031 | static int __init |
| 1254 | pcibios_init(void) | 1032 | pcibios_init(void) |
| 1255 | { | 1033 | { |
| @@ -1290,9 +1068,6 @@ pcibios_init(void) | |||
| 1290 | pcibios_allocate_bus_resources(&pci_root_buses); | 1068 | pcibios_allocate_bus_resources(&pci_root_buses); |
| 1291 | pcibios_allocate_resources(0); | 1069 | pcibios_allocate_resources(0); |
| 1292 | pcibios_allocate_resources(1); | 1070 | pcibios_allocate_resources(1); |
| 1293 | #ifdef CONFIG_PPC_PMAC | ||
| 1294 | pcibios_fixup_p2p_bridges(); | ||
| 1295 | #endif /* CONFIG_PPC_PMAC */ | ||
| 1296 | pcibios_assign_resources(); | 1071 | pcibios_assign_resources(); |
| 1297 | 1072 | ||
| 1298 | /* Call machine dependent post-init code */ | 1073 | /* Call machine dependent post-init code */ |
| @@ -1722,17 +1497,6 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) | |||
| 1722 | struct pci_controller* hose; | 1497 | struct pci_controller* hose; |
| 1723 | long result = -EOPNOTSUPP; | 1498 | long result = -EOPNOTSUPP; |
| 1724 | 1499 | ||
| 1725 | /* Argh ! Please forgive me for that hack, but that's the | ||
| 1726 | * simplest way to get existing XFree to not lockup on some | ||
| 1727 | * G5 machines... So when something asks for bus 0 io base | ||
| 1728 | * (bus 0 is HT root), we return the AGP one instead. | ||
| 1729 | */ | ||
| 1730 | #ifdef CONFIG_PPC_PMAC | ||
| 1731 | if (_machine == _MACH_Pmac && machine_is_compatible("MacRISC4")) | ||
| 1732 | if (bus == 0) | ||
| 1733 | bus = 0xf0; | ||
| 1734 | #endif /* CONFIG_PPC_PMAC */ | ||
| 1735 | |||
| 1736 | hose = pci_bus_to_hose(bus); | 1500 | hose = pci_bus_to_hose(bus); |
| 1737 | if (!hose) | 1501 | if (!hose) |
| 1738 | return -ENODEV; | 1502 | return -ENODEV; |
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 95075f99a6d4..3a6e4bcb3c53 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c | |||
| @@ -34,7 +34,6 @@ | |||
| 34 | #include <asm/system.h> | 34 | #include <asm/system.h> |
| 35 | #include <asm/pci-bridge.h> | 35 | #include <asm/pci-bridge.h> |
| 36 | #include <asm/irq.h> | 36 | #include <asm/irq.h> |
| 37 | #include <asm/pmac_feature.h> | ||
| 38 | #include <asm/dma.h> | 37 | #include <asm/dma.h> |
| 39 | #include <asm/machdep.h> | 38 | #include <asm/machdep.h> |
| 40 | #include <asm/hw_irq.h> | 39 | #include <asm/hw_irq.h> |
| @@ -58,7 +57,6 @@ extern void machine_check_exception(struct pt_regs *regs); | |||
| 58 | extern void alignment_exception(struct pt_regs *regs); | 57 | extern void alignment_exception(struct pt_regs *regs); |
| 59 | extern void program_check_exception(struct pt_regs *regs); | 58 | extern void program_check_exception(struct pt_regs *regs); |
| 60 | extern void single_step_exception(struct pt_regs *regs); | 59 | extern void single_step_exception(struct pt_regs *regs); |
| 61 | extern int pmac_newworld; | ||
| 62 | extern int sys_sigreturn(struct pt_regs *regs); | 60 | extern int sys_sigreturn(struct pt_regs *regs); |
| 63 | 61 | ||
| 64 | long long __ashrdi3(long long, int); | 62 | long long __ashrdi3(long long, int); |
| @@ -213,10 +211,6 @@ EXPORT_SYMBOL(adb_try_handler_change); | |||
| 213 | EXPORT_SYMBOL(cuda_request); | 211 | EXPORT_SYMBOL(cuda_request); |
| 214 | EXPORT_SYMBOL(cuda_poll); | 212 | EXPORT_SYMBOL(cuda_poll); |
| 215 | #endif /* CONFIG_ADB_CUDA */ | 213 | #endif /* CONFIG_ADB_CUDA */ |
| 216 | #ifdef CONFIG_PPC_PMAC | ||
| 217 | EXPORT_SYMBOL(sys_ctrler); | ||
| 218 | EXPORT_SYMBOL(pmac_newworld); | ||
| 219 | #endif | ||
| 220 | #ifdef CONFIG_PPC_OF | 214 | #ifdef CONFIG_PPC_OF |
| 221 | EXPORT_SYMBOL(find_devices); | 215 | EXPORT_SYMBOL(find_devices); |
| 222 | EXPORT_SYMBOL(find_type_devices); | 216 | EXPORT_SYMBOL(find_type_devices); |
| @@ -241,9 +235,6 @@ EXPORT_SYMBOL(of_node_put); | |||
| 241 | #if defined(CONFIG_BOOTX_TEXT) | 235 | #if defined(CONFIG_BOOTX_TEXT) |
| 242 | EXPORT_SYMBOL(btext_update_display); | 236 | EXPORT_SYMBOL(btext_update_display); |
| 243 | #endif | 237 | #endif |
| 244 | #if defined(CONFIG_SCSI) && defined(CONFIG_PPC_PMAC) | ||
| 245 | EXPORT_SYMBOL(note_scsi_host); | ||
| 246 | #endif | ||
| 247 | #ifdef CONFIG_VT | 238 | #ifdef CONFIG_VT |
| 248 | EXPORT_SYMBOL(kd_mksound); | 239 | EXPORT_SYMBOL(kd_mksound); |
| 249 | #endif | 240 | #endif |
| @@ -270,7 +261,6 @@ EXPORT_SYMBOL(__delay); | |||
| 270 | EXPORT_SYMBOL(timer_interrupt); | 261 | EXPORT_SYMBOL(timer_interrupt); |
| 271 | EXPORT_SYMBOL(irq_desc); | 262 | EXPORT_SYMBOL(irq_desc); |
| 272 | EXPORT_SYMBOL(tb_ticks_per_jiffy); | 263 | EXPORT_SYMBOL(tb_ticks_per_jiffy); |
| 273 | EXPORT_SYMBOL(get_wchan); | ||
| 274 | EXPORT_SYMBOL(console_drivers); | 264 | EXPORT_SYMBOL(console_drivers); |
| 275 | #ifdef CONFIG_XMON | 265 | #ifdef CONFIG_XMON |
| 276 | EXPORT_SYMBOL(xmon); | 266 | EXPORT_SYMBOL(xmon); |
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index e707c6f6e61b..c08ab432e958 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Common prep/pmac/chrp boot and setup code. | 2 | * Common prep/chrp boot and setup code. |
| 3 | */ | 3 | */ |
| 4 | 4 | ||
| 5 | #include <linux/config.h> | 5 | #include <linux/config.h> |
| @@ -35,7 +35,6 @@ | |||
| 35 | #include <asm/machdep.h> | 35 | #include <asm/machdep.h> |
| 36 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
| 37 | #include <asm/system.h> | 37 | #include <asm/system.h> |
| 38 | #include <asm/pmac_feature.h> | ||
| 39 | #include <asm/sections.h> | 38 | #include <asm/sections.h> |
| 40 | #include <asm/nvram.h> | 39 | #include <asm/nvram.h> |
| 41 | #include <asm/xmon.h> | 40 | #include <asm/xmon.h> |
| @@ -55,7 +54,6 @@ | |||
| 55 | 54 | ||
| 56 | extern void platform_init(unsigned long r3, unsigned long r4, | 55 | extern void platform_init(unsigned long r3, unsigned long r4, |
| 57 | unsigned long r5, unsigned long r6, unsigned long r7); | 56 | unsigned long r5, unsigned long r6, unsigned long r7); |
| 58 | extern void bootx_init(unsigned long r4, unsigned long phys); | ||
| 59 | extern void identify_cpu(unsigned long offset, unsigned long cpu); | 57 | extern void identify_cpu(unsigned long offset, unsigned long cpu); |
| 60 | extern void do_cpu_ftr_fixups(unsigned long offset); | 58 | extern void do_cpu_ftr_fixups(unsigned long offset); |
| 61 | extern void reloc_got2(unsigned long offset); | 59 | extern void reloc_got2(unsigned long offset); |
| @@ -80,8 +78,6 @@ EXPORT_SYMBOL(_machine); | |||
| 80 | 78 | ||
| 81 | extern void prep_init(unsigned long r3, unsigned long r4, | 79 | extern void prep_init(unsigned long r3, unsigned long r4, |
| 82 | unsigned long r5, unsigned long r6, unsigned long r7); | 80 | unsigned long r5, unsigned long r6, unsigned long r7); |
| 83 | extern void pmac_init(unsigned long r3, unsigned long r4, | ||
| 84 | unsigned long r5, unsigned long r6, unsigned long r7); | ||
| 85 | extern void chrp_init(unsigned long r3, unsigned long r4, | 81 | extern void chrp_init(unsigned long r3, unsigned long r4, |
| 86 | unsigned long r5, unsigned long r6, unsigned long r7); | 82 | unsigned long r5, unsigned long r6, unsigned long r7); |
| 87 | 83 | ||
| @@ -324,20 +320,15 @@ early_init(int r3, int r4, int r5) | |||
| 324 | identify_cpu(offset, 0); | 320 | identify_cpu(offset, 0); |
| 325 | do_cpu_ftr_fixups(offset); | 321 | do_cpu_ftr_fixups(offset); |
| 326 | 322 | ||
| 327 | #if defined(CONFIG_PPC_MULTIPLATFORM) | 323 | #if defined(CONFIG_PPC_OF) |
| 328 | reloc_got2(offset); | 324 | reloc_got2(offset); |
| 329 | 325 | ||
| 330 | /* If we came here from BootX, clear the screen, | ||
| 331 | * set up some pointers and return. */ | ||
| 332 | if ((r3 == 0x426f6f58) && (r5 == 0)) | ||
| 333 | bootx_init(r4, phys); | ||
| 334 | |||
| 335 | /* | 326 | /* |
| 336 | * don't do anything on prep | 327 | * don't do anything on prep |
| 337 | * for now, don't use bootinfo because it breaks yaboot 0.5 | 328 | * for now, don't use bootinfo because it breaks yaboot 0.5 |
| 338 | * and assume that if we didn't find a magic number, we have OF | 329 | * and assume that if we didn't find a magic number, we have OF |
| 339 | */ | 330 | */ |
| 340 | else if (*(unsigned long *)(0) != 0xdeadc0de) | 331 | if (*(unsigned long *)(0) != 0xdeadc0de) |
| 341 | phys = prom_init(r3, r4, (prom_entry)r5); | 332 | phys = prom_init(r3, r4, (prom_entry)r5); |
| 342 | 333 | ||
| 343 | reloc_got2(-offset); | 334 | reloc_got2(-offset); |
| @@ -424,6 +415,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
| 424 | } | 415 | } |
| 425 | #endif | 416 | #endif |
| 426 | 417 | ||
| 418 | #ifdef CONFIG_PPC_OF | ||
| 427 | have_of = 1; | 419 | have_of = 1; |
| 428 | 420 | ||
| 429 | /* prom_init has already been called from __start */ | 421 | /* prom_init has already been called from __start */ |
| @@ -495,19 +487,17 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
| 495 | #endif /* CONFIG_ADB */ | 487 | #endif /* CONFIG_ADB */ |
| 496 | 488 | ||
| 497 | switch (_machine) { | 489 | switch (_machine) { |
| 498 | #ifdef CONFIG_PPC_PMAC | ||
| 499 | case _MACH_Pmac: | ||
| 500 | pmac_init(r3, r4, r5, r6, r7); | ||
| 501 | break; | ||
| 502 | #endif | ||
| 503 | #ifdef CONFIG_PPC_CHRP | 490 | #ifdef CONFIG_PPC_CHRP |
| 504 | case _MACH_chrp: | 491 | case _MACH_chrp: |
| 505 | chrp_init(r3, r4, r5, r6, r7); | 492 | chrp_init(r3, r4, r5, r6, r7); |
| 506 | break; | 493 | break; |
| 507 | #endif | 494 | #endif |
| 508 | } | 495 | } |
| 496 | #endif /* CONFIG_PPC_OF */ | ||
| 509 | } | 497 | } |
| 498 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | ||
| 510 | 499 | ||
| 500 | #ifdef CONFIG_PPC_OF | ||
| 511 | #ifdef CONFIG_SERIAL_CORE_CONSOLE | 501 | #ifdef CONFIG_SERIAL_CORE_CONSOLE |
| 512 | extern char *of_stdout_device; | 502 | extern char *of_stdout_device; |
| 513 | 503 | ||
| @@ -564,7 +554,7 @@ static int __init set_preferred_console(void) | |||
| 564 | } | 554 | } |
| 565 | console_initcall(set_preferred_console); | 555 | console_initcall(set_preferred_console); |
| 566 | #endif /* CONFIG_SERIAL_CORE_CONSOLE */ | 556 | #endif /* CONFIG_SERIAL_CORE_CONSOLE */ |
| 567 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | 557 | #endif /* CONFIG_PPC_OF */ |
| 568 | 558 | ||
| 569 | struct bi_record *find_bootinfo(void) | 559 | struct bi_record *find_bootinfo(void) |
| 570 | { | 560 | { |
| @@ -747,14 +737,6 @@ void __init setup_arch(char **cmdline_p) | |||
| 747 | if (ppc_md.init_early) | 737 | if (ppc_md.init_early) |
| 748 | ppc_md.init_early(); | 738 | ppc_md.init_early(); |
| 749 | 739 | ||
| 750 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
| 751 | /* This could be called "early setup arch", it must be done | ||
| 752 | * now because xmon need it | ||
| 753 | */ | ||
| 754 | if (_machine == _MACH_Pmac) | ||
| 755 | pmac_feature_init(); /* New cool way */ | ||
| 756 | #endif | ||
| 757 | |||
| 758 | #ifdef CONFIG_XMON | 740 | #ifdef CONFIG_XMON |
| 759 | xmon_init(1); | 741 | xmon_init(1); |
| 760 | if (strstr(cmd_line, "xmon")) | 742 | if (strstr(cmd_line, "xmon")) |
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 9dbc4d28fa28..6d0a1838d94c 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c | |||
| @@ -38,9 +38,6 @@ | |||
| 38 | #include <asm/io.h> | 38 | #include <asm/io.h> |
| 39 | #include <asm/reg.h> | 39 | #include <asm/reg.h> |
| 40 | #include <asm/xmon.h> | 40 | #include <asm/xmon.h> |
| 41 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
| 42 | #include <asm/backlight.h> | ||
| 43 | #endif | ||
| 44 | #include <asm/pmc.h> | 41 | #include <asm/pmc.h> |
| 45 | 42 | ||
| 46 | #ifdef CONFIG_XMON | 43 | #ifdef CONFIG_XMON |
| @@ -85,12 +82,6 @@ int die(const char * str, struct pt_regs * fp, long err) | |||
| 85 | int nl = 0; | 82 | int nl = 0; |
| 86 | console_verbose(); | 83 | console_verbose(); |
| 87 | spin_lock_irq(&die_lock); | 84 | spin_lock_irq(&die_lock); |
| 88 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
| 89 | if (_machine == _MACH_Pmac) { | ||
| 90 | set_backlight_enable(1); | ||
| 91 | set_backlight_level(BACKLIGHT_MAX); | ||
| 92 | } | ||
| 93 | #endif | ||
| 94 | printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); | 85 | printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); |
| 95 | #ifdef CONFIG_PREEMPT | 86 | #ifdef CONFIG_PREEMPT |
| 96 | printk("PREEMPT "); | 87 | printk("PREEMPT "); |
| @@ -159,7 +150,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) | |||
| 159 | */ | 150 | */ |
| 160 | static inline int check_io_access(struct pt_regs *regs) | 151 | static inline int check_io_access(struct pt_regs *regs) |
| 161 | { | 152 | { |
| 162 | #if defined CONFIG_PPC_PMAC || defined CONFIG_8xx | 153 | #if defined CONFIG_8xx |
| 163 | unsigned long msr = regs->msr; | 154 | unsigned long msr = regs->msr; |
| 164 | const struct exception_table_entry *entry; | 155 | const struct exception_table_entry *entry; |
| 165 | unsigned int *nip = (unsigned int *)regs->nip; | 156 | unsigned int *nip = (unsigned int *)regs->nip; |
| @@ -196,7 +187,7 @@ static inline int check_io_access(struct pt_regs *regs) | |||
| 196 | return 1; | 187 | return 1; |
| 197 | } | 188 | } |
| 198 | } | 189 | } |
| 199 | #endif /* CONFIG_PPC_PMAC */ | 190 | #endif /* CONFIG_8xx */ |
| 200 | return 0; | 191 | return 0; |
| 201 | } | 192 | } |
| 202 | 193 | ||
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index 45f0782059f1..134db5c04203 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c | |||
| @@ -67,10 +67,6 @@ unsigned long ppc_memoffset = PAGE_OFFSET; | |||
| 67 | int mem_init_done; | 67 | int mem_init_done; |
| 68 | int init_bootmem_done; | 68 | int init_bootmem_done; |
| 69 | int boot_mapsize; | 69 | int boot_mapsize; |
| 70 | #ifdef CONFIG_PPC_PMAC | ||
| 71 | unsigned long agp_special_page; | ||
| 72 | EXPORT_SYMBOL(agp_special_page); | ||
| 73 | #endif | ||
| 74 | 70 | ||
| 75 | extern char _end[]; | 71 | extern char _end[]; |
| 76 | extern char etext[], _stext[]; | 72 | extern char etext[], _stext[]; |
| @@ -424,10 +420,6 @@ void __init mem_init(void) | |||
| 424 | addr += PAGE_SIZE) | 420 | addr += PAGE_SIZE) |
| 425 | SetPageReserved(virt_to_page(addr)); | 421 | SetPageReserved(virt_to_page(addr)); |
| 426 | #endif | 422 | #endif |
| 427 | #ifdef CONFIG_PPC_PMAC | ||
| 428 | if (agp_special_page) | ||
| 429 | SetPageReserved(virt_to_page(agp_special_page)); | ||
| 430 | #endif | ||
| 431 | for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory; | 423 | for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory; |
| 432 | addr += PAGE_SIZE) { | 424 | addr += PAGE_SIZE) { |
| 433 | if (!PageReserved(virt_to_page(addr))) | 425 | if (!PageReserved(virt_to_page(addr))) |
| @@ -463,11 +455,6 @@ void __init mem_init(void) | |||
| 463 | initpages<< (PAGE_SHIFT-10), | 455 | initpages<< (PAGE_SHIFT-10), |
| 464 | (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); | 456 | (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); |
| 465 | 457 | ||
| 466 | #ifdef CONFIG_PPC_PMAC | ||
| 467 | if (agp_special_page) | ||
| 468 | printk(KERN_INFO "AGP special page: 0x%08lx\n", agp_special_page); | ||
| 469 | #endif | ||
| 470 | |||
| 471 | mem_init_done = 1; | 458 | mem_init_done = 1; |
| 472 | } | 459 | } |
| 473 | 460 | ||
| @@ -512,22 +499,6 @@ set_phys_avail(unsigned long total_memory) | |||
| 512 | if (rtas_data) | 499 | if (rtas_data) |
| 513 | mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1); | 500 | mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1); |
| 514 | #endif | 501 | #endif |
| 515 | #ifdef CONFIG_PPC_PMAC | ||
| 516 | /* Because of some uninorth weirdness, we need a page of | ||
| 517 | * memory as high as possible (it must be outside of the | ||
| 518 | * bus address seen as the AGP aperture). It will be used | ||
| 519 | * by the r128 DRM driver | ||
| 520 | * | ||
| 521 | * FIXME: We need to make sure that page doesn't overlap any of the\ | ||
| 522 | * above. This could be done by improving mem_pieces_find to be able | ||
| 523 | * to do a backward search from the end of the list. | ||
| 524 | */ | ||
| 525 | if (_machine == _MACH_Pmac && find_devices("uni-north-agp")) { | ||
| 526 | agp_special_page = (total_memory - PAGE_SIZE); | ||
| 527 | mem_pieces_remove(&phys_avail, agp_special_page, PAGE_SIZE, 0); | ||
| 528 | agp_special_page = (unsigned long)__va(agp_special_page); | ||
| 529 | } | ||
| 530 | #endif /* CONFIG_PPC_PMAC */ | ||
| 531 | } | 502 | } |
| 532 | 503 | ||
| 533 | /* Mark some memory as reserved by removing it from phys_avail. */ | 504 | /* Mark some memory as reserved by removing it from phys_avail. */ |
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c index 04bdc39bf47b..012e1e652c03 100644 --- a/arch/ppc/platforms/83xx/mpc834x_sys.c +++ b/arch/ppc/platforms/83xx/mpc834x_sys.c | |||
| @@ -51,9 +51,6 @@ | |||
| 51 | 51 | ||
| 52 | #include <syslib/ppc83xx_setup.h> | 52 | #include <syslib/ppc83xx_setup.h> |
| 53 | 53 | ||
| 54 | static const char *GFAR_PHY_0 = "phy0:0"; | ||
| 55 | static const char *GFAR_PHY_1 = "phy0:1"; | ||
| 56 | |||
| 57 | #ifndef CONFIG_PCI | 54 | #ifndef CONFIG_PCI |
| 58 | unsigned long isa_io_base = 0; | 55 | unsigned long isa_io_base = 0; |
| 59 | unsigned long isa_mem_base = 0; | 56 | unsigned long isa_mem_base = 0; |
| @@ -129,20 +126,21 @@ mpc834x_sys_setup_arch(void) | |||
| 129 | mdata->irq[1] = MPC83xx_IRQ_EXT2; | 126 | mdata->irq[1] = MPC83xx_IRQ_EXT2; |
| 130 | mdata->irq[2] = -1; | 127 | mdata->irq[2] = -1; |
| 131 | mdata->irq[31] = -1; | 128 | mdata->irq[31] = -1; |
| 132 | mdata->paddr += binfo->bi_immr_base; | ||
| 133 | 129 | ||
| 134 | /* setup the board related information for the enet controllers */ | 130 | /* setup the board related information for the enet controllers */ |
| 135 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC1); | 131 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC1); |
| 136 | if (pdata) { | 132 | if (pdata) { |
| 137 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 133 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
| 138 | pdata->bus_id = GFAR_PHY_0; | 134 | pdata->bus_id = 0; |
| 135 | pdata->phy_id = 0; | ||
| 139 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | 136 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); |
| 140 | } | 137 | } |
| 141 | 138 | ||
| 142 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC2); | 139 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC2); |
| 143 | if (pdata) { | 140 | if (pdata) { |
| 144 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 141 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
| 145 | pdata->bus_id = GFAR_PHY_1; | 142 | pdata->bus_id = 0; |
| 143 | pdata->phy_id = 1; | ||
| 146 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | 144 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); |
| 147 | } | 145 | } |
| 148 | 146 | ||
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c index c5cde97c6ef0..2eceb1e6f4eb 100644 --- a/arch/ppc/platforms/85xx/mpc8540_ads.c +++ b/arch/ppc/platforms/85xx/mpc8540_ads.c | |||
| @@ -52,10 +52,6 @@ | |||
| 52 | 52 | ||
| 53 | #include <syslib/ppc85xx_setup.h> | 53 | #include <syslib/ppc85xx_setup.h> |
| 54 | 54 | ||
| 55 | static const char *GFAR_PHY_0 = "phy0:0"; | ||
| 56 | static const char *GFAR_PHY_1 = "phy0:1"; | ||
| 57 | static const char *GFAR_PHY_3 = "phy0:3"; | ||
| 58 | |||
| 59 | /* ************************************************************************ | 55 | /* ************************************************************************ |
| 60 | * | 56 | * |
| 61 | * Setup the architecture | 57 | * Setup the architecture |
| @@ -102,27 +98,29 @@ mpc8540ads_setup_arch(void) | |||
| 102 | mdata->irq[2] = -1; | 98 | mdata->irq[2] = -1; |
| 103 | mdata->irq[3] = MPC85xx_IRQ_EXT5; | 99 | mdata->irq[3] = MPC85xx_IRQ_EXT5; |
| 104 | mdata->irq[31] = -1; | 100 | mdata->irq[31] = -1; |
| 105 | mdata->paddr += binfo->bi_immr_base; | ||
| 106 | 101 | ||
| 107 | /* setup the board related information for the enet controllers */ | 102 | /* setup the board related information for the enet controllers */ |
| 108 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); | 103 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); |
| 109 | if (pdata) { | 104 | if (pdata) { |
| 110 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 105 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
| 111 | pdata->bus_id = GFAR_PHY_0; | 106 | pdata->bus_id = 0; |
| 107 | pdata->phy_id = 0; | ||
| 112 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | 108 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); |
| 113 | } | 109 | } |
| 114 | 110 | ||
| 115 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); | 111 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); |
| 116 | if (pdata) { | 112 | if (pdata) { |
| 117 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 113 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
| 118 | pdata->bus_id = GFAR_PHY_1; | 114 | pdata->bus_id = 0; |
| 115 | pdata->phy_id = 1; | ||
| 119 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | 116 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); |
| 120 | } | 117 | } |
| 121 | 118 | ||
| 122 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC); | 119 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC); |
| 123 | if (pdata) { | 120 | if (pdata) { |
| 124 | pdata->board_flags = 0; | 121 | pdata->board_flags = 0; |
| 125 | pdata->bus_id = GFAR_PHY_3; | 122 | pdata->bus_id = 0; |
| 123 | pdata->phy_id = 3; | ||
| 126 | memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6); | 124 | memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6); |
| 127 | } | 125 | } |
| 128 | 126 | ||
diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.c b/arch/ppc/platforms/85xx/mpc8560_ads.c index 8e39a5517092..442c7ff195d3 100644 --- a/arch/ppc/platforms/85xx/mpc8560_ads.c +++ b/arch/ppc/platforms/85xx/mpc8560_ads.c | |||
| @@ -56,10 +56,6 @@ | |||
| 56 | #include <syslib/ppc85xx_setup.h> | 56 | #include <syslib/ppc85xx_setup.h> |
| 57 | 57 | ||
| 58 | 58 | ||
| 59 | static const char *GFAR_PHY_0 = "phy0:0"; | ||
| 60 | static const char *GFAR_PHY_1 = "phy0:1"; | ||
| 61 | static const char *GFAR_PHY_3 = "phy0:3"; | ||
| 62 | |||
| 63 | /* ************************************************************************ | 59 | /* ************************************************************************ |
| 64 | * | 60 | * |
| 65 | * Setup the architecture | 61 | * Setup the architecture |
| @@ -99,20 +95,21 @@ mpc8560ads_setup_arch(void) | |||
| 99 | mdata->irq[2] = -1; | 95 | mdata->irq[2] = -1; |
| 100 | mdata->irq[3] = MPC85xx_IRQ_EXT5; | 96 | mdata->irq[3] = MPC85xx_IRQ_EXT5; |
| 101 | mdata->irq[31] = -1; | 97 | mdata->irq[31] = -1; |
| 102 | mdata->paddr += binfo->bi_immr_base; | ||
| 103 | 98 | ||
| 104 | /* setup the board related information for the enet controllers */ | 99 | /* setup the board related information for the enet controllers */ |
| 105 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); | 100 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); |
| 106 | if (pdata) { | 101 | if (pdata) { |
| 107 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 102 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
| 108 | pdata->bus_id = GFAR_PHY_0; | 103 | pdata->bus_id = 0; |
| 104 | pdata->phy_id = 0; | ||
| 109 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | 105 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); |
| 110 | } | 106 | } |
| 111 | 107 | ||
| 112 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); | 108 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); |
| 113 | if (pdata) { | 109 | if (pdata) { |
| 114 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 110 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
| 115 | pdata->bus_id = GFAR_PHY_1; | 111 | pdata->bus_id = 0; |
| 112 | pdata->phy_id = 1; | ||
| 116 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | 113 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); |
| 117 | } | 114 | } |
| 118 | 115 | ||
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c index 2959e3c4083d..b332ebae6bd3 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c +++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c | |||
| @@ -395,9 +395,6 @@ mpc85xx_cds_pcibios_fixup(void) | |||
| 395 | 395 | ||
| 396 | TODC_ALLOC(); | 396 | TODC_ALLOC(); |
| 397 | 397 | ||
| 398 | static const char *GFAR_PHY_0 = "phy0:0"; | ||
| 399 | static const char *GFAR_PHY_1 = "phy0:1"; | ||
| 400 | |||
| 401 | /* ************************************************************************ | 398 | /* ************************************************************************ |
| 402 | * | 399 | * |
| 403 | * Setup the architecture | 400 | * Setup the architecture |
| @@ -461,34 +458,37 @@ mpc85xx_cds_setup_arch(void) | |||
| 461 | mdata->irq[2] = -1; | 458 | mdata->irq[2] = -1; |
| 462 | mdata->irq[3] = -1; | 459 | mdata->irq[3] = -1; |
| 463 | mdata->irq[31] = -1; | 460 | mdata->irq[31] = -1; |
| 464 | mdata->paddr += binfo->bi_immr_base; | ||
| 465 | 461 | ||
| 466 | /* setup the board related information for the enet controllers */ | 462 | /* setup the board related information for the enet controllers */ |
| 467 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); | 463 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); |
| 468 | if (pdata) { | 464 | if (pdata) { |
| 469 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 465 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
| 470 | pdata->bus_id = GFAR_PHY_0; | 466 | pdata->bus_id = 0; |
| 467 | pdata->phy_id = 0; | ||
| 471 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | 468 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); |
| 472 | } | 469 | } |
| 473 | 470 | ||
| 474 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); | 471 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); |
| 475 | if (pdata) { | 472 | if (pdata) { |
| 476 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 473 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
| 477 | pdata->bus_id = GFAR_PHY_1; | 474 | pdata->bus_id = 0; |
| 475 | pdata->phy_id = 1; | ||
| 478 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | 476 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); |
| 479 | } | 477 | } |
| 480 | 478 | ||
| 481 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC1); | 479 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC1); |
| 482 | if (pdata) { | 480 | if (pdata) { |
| 483 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 481 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
| 484 | pdata->bus_id = GFAR_PHY_0; | 482 | pdata->bus_id = 0; |
| 483 | pdata->phy_id = 0; | ||
| 485 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | 484 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); |
| 486 | } | 485 | } |
| 487 | 486 | ||
| 488 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC2); | 487 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC2); |
| 489 | if (pdata) { | 488 | if (pdata) { |
| 490 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 489 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
| 491 | pdata->bus_id = GFAR_PHY_1; | 490 | pdata->bus_id = 0; |
| 491 | pdata->phy_id = 1; | ||
| 492 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | 492 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); |
| 493 | } | 493 | } |
| 494 | 494 | ||
diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c index 45a5b81b4ed1..e777ba824aa9 100644 --- a/arch/ppc/platforms/85xx/sbc8560.c +++ b/arch/ppc/platforms/85xx/sbc8560.c | |||
| @@ -91,9 +91,6 @@ sbc8560_early_serial_map(void) | |||
| 91 | } | 91 | } |
| 92 | #endif | 92 | #endif |
| 93 | 93 | ||
| 94 | static const char *GFAR_PHY_25 = "phy0:25"; | ||
| 95 | static const char *GFAR_PHY_26 = "phy0:26"; | ||
| 96 | |||
| 97 | /* ************************************************************************ | 94 | /* ************************************************************************ |
| 98 | * | 95 | * |
| 99 | * Setup the architecture | 96 | * Setup the architecture |
| @@ -136,20 +133,21 @@ sbc8560_setup_arch(void) | |||
| 136 | mdata->irq[25] = MPC85xx_IRQ_EXT6; | 133 | mdata->irq[25] = MPC85xx_IRQ_EXT6; |
| 137 | mdata->irq[26] = MPC85xx_IRQ_EXT7; | 134 | mdata->irq[26] = MPC85xx_IRQ_EXT7; |
| 138 | mdata->irq[31] = -1; | 135 | mdata->irq[31] = -1; |
| 139 | mdata->paddr += binfo->bi_immr_base; | ||
| 140 | 136 | ||
| 141 | /* setup the board related information for the enet controllers */ | 137 | /* setup the board related information for the enet controllers */ |
| 142 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); | 138 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); |
| 143 | if (pdata) { | 139 | if (pdata) { |
| 144 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 140 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
| 145 | pdata->bus_id = GFAR_PHY_25; | 141 | pdata->bus_id = 0; |
| 142 | pdata->phy_id = 25; | ||
| 146 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | 143 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); |
| 147 | } | 144 | } |
| 148 | 145 | ||
| 149 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); | 146 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); |
| 150 | if (pdata) { | 147 | if (pdata) { |
| 151 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 148 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
| 152 | pdata->bus_id = GFAR_PHY_26; | 149 | pdata->bus_id = 0; |
| 150 | pdata->phy_id = 26; | ||
| 153 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | 151 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); |
| 154 | } | 152 | } |
| 155 | 153 | ||
diff --git a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c index 15ce9d070634..061bb7cf2d9a 100644 --- a/arch/ppc/platforms/85xx/stx_gp3.c +++ b/arch/ppc/platforms/85xx/stx_gp3.c | |||
| @@ -93,9 +93,6 @@ static u8 gp3_openpic_initsenses[] __initdata = { | |||
| 93 | 0x0, /* External 11: */ | 93 | 0x0, /* External 11: */ |
| 94 | }; | 94 | }; |
| 95 | 95 | ||
| 96 | static const char *GFAR_PHY_2 = "phy0:2"; | ||
| 97 | static const char *GFAR_PHY_4 = "phy0:4"; | ||
| 98 | |||
| 99 | /* | 96 | /* |
| 100 | * Setup the architecture | 97 | * Setup the architecture |
| 101 | */ | 98 | */ |
| @@ -130,20 +127,21 @@ gp3_setup_arch(void) | |||
| 130 | mdata->irq[2] = MPC85xx_IRQ_EXT5; | 127 | mdata->irq[2] = MPC85xx_IRQ_EXT5; |
| 131 | mdata->irq[4] = MPC85xx_IRQ_EXT5; | 128 | mdata->irq[4] = MPC85xx_IRQ_EXT5; |
| 132 | mdata->irq[31] = -1; | 129 | mdata->irq[31] = -1; |
| 133 | mdata->paddr += binfo->bi_immr_base; | ||
| 134 | 130 | ||
| 135 | /* setup the board related information for the enet controllers */ | 131 | /* setup the board related information for the enet controllers */ |
| 136 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); | 132 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); |
| 137 | if (pdata) { | 133 | if (pdata) { |
| 138 | /* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */ | 134 | /* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */ |
| 139 | pdata->bus_id = GFAR_PHY_2; | 135 | pdata->bus_id = 0; |
| 136 | pdata->phy_id = 2; | ||
| 140 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | 137 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); |
| 141 | } | 138 | } |
| 142 | 139 | ||
| 143 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); | 140 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); |
| 144 | if (pdata) { | 141 | if (pdata) { |
| 145 | /* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */ | 142 | /* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */ |
| 146 | pdata->bus_id = GFAR_PHY_4; | 143 | pdata->bus_id = 0; |
| 144 | pdata->phy_id = 4; | ||
| 147 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | 145 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); |
| 148 | } | 146 | } |
| 149 | 147 | ||
diff --git a/arch/ppc/platforms/85xx/tqm85xx.c b/arch/ppc/platforms/85xx/tqm85xx.c index c6dfd8f0f9df..b436f4d0a3fa 100644 --- a/arch/ppc/platforms/85xx/tqm85xx.c +++ b/arch/ppc/platforms/85xx/tqm85xx.c | |||
| @@ -91,12 +91,6 @@ static u_char tqm85xx_openpic_initsenses[] __initdata = { | |||
| 91 | 0x0, /* External 11: */ | 91 | 0x0, /* External 11: */ |
| 92 | }; | 92 | }; |
| 93 | 93 | ||
| 94 | static const char *GFAR_PHY_0 = "phy0:2"; | ||
| 95 | static const char *GFAR_PHY_1 = "phy0:1"; | ||
| 96 | #ifdef CONFIG_MPC8540 | ||
| 97 | static const char *GFAR_PHY_3 = "phy0:3"; | ||
| 98 | #endif | ||
| 99 | |||
| 100 | /* ************************************************************************ | 94 | /* ************************************************************************ |
| 101 | * | 95 | * |
| 102 | * Setup the architecture | 96 | * Setup the architecture |
| @@ -149,20 +143,21 @@ tqm85xx_setup_arch(void) | |||
| 149 | mdata->irq[2] = -1; | 143 | mdata->irq[2] = -1; |
| 150 | mdata->irq[3] = MPC85xx_IRQ_EXT8; | 144 | mdata->irq[3] = MPC85xx_IRQ_EXT8; |
| 151 | mdata->irq[31] = -1; | 145 | mdata->irq[31] = -1; |
| 152 | mdata->paddr += binfo->bi_immr_base; | ||
| 153 | 146 | ||
| 154 | /* setup the board related information for the enet controllers */ | 147 | /* setup the board related information for the enet controllers */ |
| 155 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); | 148 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); |
| 156 | if (pdata) { | 149 | if (pdata) { |
| 157 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 150 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
| 158 | pdata->bus_id = GFAR_PHY_0; | 151 | pdata->bus_id = 0; |
| 152 | pdata->phy_id = 2; | ||
| 159 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | 153 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); |
| 160 | } | 154 | } |
| 161 | 155 | ||
| 162 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); | 156 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); |
| 163 | if (pdata) { | 157 | if (pdata) { |
| 164 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 158 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
| 165 | pdata->bus_id = GFAR_PHY_1; | 159 | pdata->bus_id = 0; |
| 160 | pdata->phy_id = 1; | ||
| 166 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | 161 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); |
| 167 | } | 162 | } |
| 168 | 163 | ||
| @@ -170,7 +165,8 @@ tqm85xx_setup_arch(void) | |||
| 170 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC); | 165 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC); |
| 171 | if (pdata) { | 166 | if (pdata) { |
| 172 | pdata->board_flags = 0; | 167 | pdata->board_flags = 0; |
| 173 | pdata->bus_id = GFAR_PHY_3; | 168 | pdata->bus_id = 0; |
| 169 | pdata->phy_id = 3; | ||
| 174 | memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6); | 170 | memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6); |
| 175 | } | 171 | } |
| 176 | #endif | 172 | #endif |
diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile index 7c5cdabf6f3c..51430e294b32 100644 --- a/arch/ppc/platforms/Makefile +++ b/arch/ppc/platforms/Makefile | |||
| @@ -3,26 +3,18 @@ | |||
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | # Extra CFLAGS so we don't have to do relative includes | 5 | # Extra CFLAGS so we don't have to do relative includes |
| 6 | CFLAGS_pmac_setup.o += -Iarch/$(ARCH)/mm | 6 | CFLAGS_chrp_setup.o += -Iarch/$(ARCH)/mm |
| 7 | 7 | ||
| 8 | obj-$(CONFIG_APUS) += apus_setup.o | 8 | obj-$(CONFIG_APUS) += apus_setup.o |
| 9 | ifeq ($(CONFIG_APUS),y) | 9 | ifeq ($(CONFIG_APUS),y) |
| 10 | obj-$(CONFIG_PCI) += apus_pci.o | 10 | obj-$(CONFIG_PCI) += apus_pci.o |
| 11 | endif | 11 | endif |
| 12 | obj-$(CONFIG_PPC_PMAC) += pmac_pic.o pmac_setup.o pmac_time.o \ | ||
| 13 | pmac_feature.o pmac_pci.o pmac_sleep.o \ | ||
| 14 | pmac_low_i2c.o pmac_cache.o | ||
| 15 | obj-$(CONFIG_PPC_CHRP) += chrp_setup.o chrp_time.o chrp_pci.o \ | 12 | obj-$(CONFIG_PPC_CHRP) += chrp_setup.o chrp_time.o chrp_pci.o \ |
| 16 | chrp_pegasos_eth.o | 13 | chrp_pegasos_eth.o |
| 17 | ifeq ($(CONFIG_PPC_CHRP),y) | 14 | ifeq ($(CONFIG_PPC_CHRP),y) |
| 18 | obj-$(CONFIG_NVRAM) += chrp_nvram.o | 15 | obj-$(CONFIG_NVRAM) += chrp_nvram.o |
| 19 | endif | 16 | endif |
| 20 | obj-$(CONFIG_PPC_PREP) += prep_pci.o prep_setup.o | 17 | obj-$(CONFIG_PPC_PREP) += prep_pci.o prep_setup.o |
| 21 | ifeq ($(CONFIG_PPC_PMAC),y) | ||
| 22 | obj-$(CONFIG_NVRAM) += pmac_nvram.o | ||
| 23 | obj-$(CONFIG_CPU_FREQ_PMAC) += pmac_cpufreq.o | ||
| 24 | endif | ||
| 25 | obj-$(CONFIG_PMAC_BACKLIGHT) += pmac_backlight.o | ||
| 26 | obj-$(CONFIG_PREP_RESIDUAL) += residual.o | 18 | obj-$(CONFIG_PREP_RESIDUAL) += residual.o |
| 27 | obj-$(CONFIG_PQ2ADS) += pq2ads.o | 19 | obj-$(CONFIG_PQ2ADS) += pq2ads.o |
| 28 | obj-$(CONFIG_TQM8260) += tqm8260_setup.o | 20 | obj-$(CONFIG_TQM8260) += tqm8260_setup.o |
| @@ -47,6 +39,5 @@ obj-$(CONFIG_LITE5200) += lite5200.o | |||
| 47 | obj-$(CONFIG_EV64360) += ev64360.o | 39 | obj-$(CONFIG_EV64360) += ev64360.o |
| 48 | 40 | ||
| 49 | ifeq ($(CONFIG_SMP),y) | 41 | ifeq ($(CONFIG_SMP),y) |
| 50 | obj-$(CONFIG_PPC_PMAC) += pmac_smp.o | ||
| 51 | obj-$(CONFIG_PPC_CHRP) += chrp_smp.o | 42 | obj-$(CONFIG_PPC_CHRP) += chrp_smp.o |
| 52 | endif | 43 | endif |
diff --git a/arch/ppc/platforms/chrp_pci.c b/arch/ppc/platforms/chrp_pci.c index bd047aac01b1..c7fe6182bb77 100644 --- a/arch/ppc/platforms/chrp_pci.c +++ b/arch/ppc/platforms/chrp_pci.c | |||
| @@ -275,7 +275,7 @@ chrp_find_bridges(void) | |||
| 275 | setup_python(hose, dev); | 275 | setup_python(hose, dev); |
| 276 | } else if (is_mot | 276 | } else if (is_mot |
| 277 | || strncmp(model, "Motorola, Grackle", 17) == 0) { | 277 | || strncmp(model, "Motorola, Grackle", 17) == 0) { |
| 278 | setup_grackle(hose); | 278 | setup_indirect_pci(hose, 0xfec00000, 0xfee00000); |
| 279 | } else if (is_longtrail) { | 279 | } else if (is_longtrail) { |
| 280 | void __iomem *p = ioremap(GG2_PCI_CONFIG_BASE, 0x80000); | 280 | void __iomem *p = ioremap(GG2_PCI_CONFIG_BASE, 0x80000); |
| 281 | hose->ops = &gg2_pci_ops; | 281 | hose->ops = &gg2_pci_ops; |
diff --git a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c index 056ac2a7b5c1..48996b787378 100644 --- a/arch/ppc/platforms/chrp_setup.c +++ b/arch/ppc/platforms/chrp_setup.c | |||
| @@ -53,6 +53,7 @@ | |||
| 53 | #include <asm/i8259.h> | 53 | #include <asm/i8259.h> |
| 54 | #include <asm/open_pic.h> | 54 | #include <asm/open_pic.h> |
| 55 | #include <asm/xmon.h> | 55 | #include <asm/xmon.h> |
| 56 | #include "mem_pieces.h" | ||
| 56 | 57 | ||
| 57 | unsigned long chrp_get_rtc_time(void); | 58 | unsigned long chrp_get_rtc_time(void); |
| 58 | int chrp_set_rtc_time(unsigned long nowtime); | 59 | int chrp_set_rtc_time(unsigned long nowtime); |
| @@ -65,7 +66,6 @@ void rtas_display_progress(char *, unsigned short); | |||
| 65 | void rtas_indicator_progress(char *, unsigned short); | 66 | void rtas_indicator_progress(char *, unsigned short); |
| 66 | void btext_progress(char *, unsigned short); | 67 | void btext_progress(char *, unsigned short); |
| 67 | 68 | ||
| 68 | extern unsigned long pmac_find_end_of_memory(void); | ||
| 69 | extern int of_show_percpuinfo(struct seq_file *, int); | 69 | extern int of_show_percpuinfo(struct seq_file *, int); |
| 70 | 70 | ||
| 71 | int _chrp_type; | 71 | int _chrp_type; |
| @@ -467,6 +467,75 @@ chrp_init2(void) | |||
| 467 | ppc_md.progress(" Have fun! ", 0x7777); | 467 | ppc_md.progress(" Have fun! ", 0x7777); |
| 468 | } | 468 | } |
| 469 | 469 | ||
| 470 | static struct device_node *memory_node; | ||
| 471 | |||
| 472 | static int __init get_mem_prop(char *name, struct mem_pieces *mp) | ||
| 473 | { | ||
| 474 | struct reg_property *rp; | ||
| 475 | int i, s; | ||
| 476 | unsigned int *ip; | ||
| 477 | int nac = prom_n_addr_cells(memory_node); | ||
| 478 | int nsc = prom_n_size_cells(memory_node); | ||
| 479 | |||
| 480 | ip = (unsigned int *) get_property(memory_node, name, &s); | ||
| 481 | if (ip == NULL) { | ||
| 482 | printk(KERN_ERR "error: couldn't get %s property on /memory\n", | ||
| 483 | name); | ||
| 484 | return 0; | ||
| 485 | } | ||
| 486 | s /= (nsc + nac) * 4; | ||
| 487 | rp = mp->regions; | ||
| 488 | for (i = 0; i < s; ++i, ip += nac+nsc) { | ||
| 489 | if (nac >= 2 && ip[nac-2] != 0) | ||
| 490 | continue; | ||
| 491 | rp->address = ip[nac-1]; | ||
| 492 | if (nsc >= 2 && ip[nac+nsc-2] != 0) | ||
| 493 | rp->size = ~0U; | ||
| 494 | else | ||
| 495 | rp->size = ip[nac+nsc-1]; | ||
| 496 | ++rp; | ||
| 497 | } | ||
| 498 | mp->n_regions = rp - mp->regions; | ||
| 499 | |||
| 500 | /* Make sure the pieces are sorted. */ | ||
| 501 | mem_pieces_sort(mp); | ||
| 502 | mem_pieces_coalesce(mp); | ||
| 503 | return 1; | ||
| 504 | } | ||
| 505 | |||
| 506 | static unsigned long __init chrp_find_end_of_memory(void) | ||
| 507 | { | ||
| 508 | unsigned long a, total; | ||
| 509 | struct mem_pieces phys_mem; | ||
| 510 | |||
| 511 | /* | ||
| 512 | * Find out where physical memory is, and check that it | ||
| 513 | * starts at 0 and is contiguous. It seems that RAM is | ||
| 514 | * always physically contiguous on Power Macintoshes. | ||
| 515 | * | ||
| 516 | * Supporting discontiguous physical memory isn't hard, | ||
| 517 | * it just makes the virtual <-> physical mapping functions | ||
| 518 | * more complicated (or else you end up wasting space | ||
| 519 | * in mem_map). | ||
| 520 | */ | ||
| 521 | memory_node = find_devices("memory"); | ||
| 522 | if (memory_node == NULL || !get_mem_prop("reg", &phys_mem) | ||
| 523 | || phys_mem.n_regions == 0) | ||
| 524 | panic("No RAM??"); | ||
| 525 | a = phys_mem.regions[0].address; | ||
| 526 | if (a != 0) | ||
| 527 | panic("RAM doesn't start at physical address 0"); | ||
| 528 | total = phys_mem.regions[0].size; | ||
| 529 | |||
| 530 | if (phys_mem.n_regions > 1) { | ||
| 531 | printk("RAM starting at 0x%x is not contiguous\n", | ||
| 532 | phys_mem.regions[1].address); | ||
| 533 | printk("Using RAM from 0 to 0x%lx\n", total-1); | ||
| 534 | } | ||
| 535 | |||
| 536 | return total; | ||
| 537 | } | ||
| 538 | |||
| 470 | void __init | 539 | void __init |
| 471 | chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, | 540 | chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, |
| 472 | unsigned long r6, unsigned long r7) | 541 | unsigned long r6, unsigned long r7) |
| @@ -525,7 +594,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
| 525 | ppc_md.get_rtc_time = chrp_get_rtc_time; | 594 | ppc_md.get_rtc_time = chrp_get_rtc_time; |
| 526 | ppc_md.calibrate_decr = chrp_calibrate_decr; | 595 | ppc_md.calibrate_decr = chrp_calibrate_decr; |
| 527 | 596 | ||
| 528 | ppc_md.find_end_of_memory = pmac_find_end_of_memory; | 597 | ppc_md.find_end_of_memory = chrp_find_end_of_memory; |
| 529 | 598 | ||
| 530 | if (rtas_data) { | 599 | if (rtas_data) { |
| 531 | struct device_node *rtas; | 600 | struct device_node *rtas; |
diff --git a/arch/ppc/platforms/chrp_time.c b/arch/ppc/platforms/chrp_time.c index 29d074c305f0..57753a55b580 100644 --- a/arch/ppc/platforms/chrp_time.c +++ b/arch/ppc/platforms/chrp_time.c | |||
| @@ -163,13 +163,75 @@ unsigned long chrp_get_rtc_time(void) | |||
| 163 | return mktime(year, mon, day, hour, min, sec); | 163 | return mktime(year, mon, day, hour, min, sec); |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | /* | ||
| 167 | * Calibrate the decrementer frequency with the VIA timer 1. | ||
| 168 | */ | ||
| 169 | #define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */ | ||
| 170 | |||
| 171 | /* VIA registers */ | ||
| 172 | #define RS 0x200 /* skip between registers */ | ||
| 173 | #define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */ | ||
| 174 | #define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */ | ||
| 175 | #define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */ | ||
| 176 | #define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */ | ||
| 177 | #define ACR (11*RS) /* Auxiliary control register */ | ||
| 178 | #define IFR (13*RS) /* Interrupt flag register */ | ||
| 179 | |||
| 180 | /* Bits in ACR */ | ||
| 181 | #define T1MODE 0xc0 /* Timer 1 mode */ | ||
| 182 | #define T1MODE_CONT 0x40 /* continuous interrupts */ | ||
| 183 | |||
| 184 | /* Bits in IFR and IER */ | ||
| 185 | #define T1_INT 0x40 /* Timer 1 interrupt */ | ||
| 186 | |||
| 187 | static int __init chrp_via_calibrate_decr(void) | ||
| 188 | { | ||
| 189 | struct device_node *vias; | ||
| 190 | volatile unsigned char __iomem *via; | ||
| 191 | int count = VIA_TIMER_FREQ_6 / 100; | ||
| 192 | unsigned int dstart, dend; | ||
| 193 | |||
| 194 | vias = find_devices("via-cuda"); | ||
| 195 | if (vias == 0) | ||
| 196 | vias = find_devices("via"); | ||
| 197 | if (vias == 0 || vias->n_addrs == 0) | ||
| 198 | return 0; | ||
| 199 | via = ioremap(vias->addrs[0].address, vias->addrs[0].size); | ||
| 200 | |||
| 201 | /* set timer 1 for continuous interrupts */ | ||
| 202 | out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT); | ||
| 203 | /* set the counter to a small value */ | ||
| 204 | out_8(&via[T1CH], 2); | ||
| 205 | /* set the latch to `count' */ | ||
| 206 | out_8(&via[T1LL], count); | ||
| 207 | out_8(&via[T1LH], count >> 8); | ||
| 208 | /* wait until it hits 0 */ | ||
| 209 | while ((in_8(&via[IFR]) & T1_INT) == 0) | ||
| 210 | ; | ||
| 211 | dstart = get_dec(); | ||
| 212 | /* clear the interrupt & wait until it hits 0 again */ | ||
| 213 | in_8(&via[T1CL]); | ||
| 214 | while ((in_8(&via[IFR]) & T1_INT) == 0) | ||
| 215 | ; | ||
| 216 | dend = get_dec(); | ||
| 217 | |||
| 218 | tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100); | ||
| 219 | tb_to_us = mulhwu_scale_factor(dstart - dend, 60000); | ||
| 220 | |||
| 221 | printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n", | ||
| 222 | tb_ticks_per_jiffy, dstart - dend); | ||
| 223 | |||
| 224 | iounmap(via); | ||
| 225 | |||
| 226 | return 1; | ||
| 227 | } | ||
| 166 | 228 | ||
| 167 | void __init chrp_calibrate_decr(void) | 229 | void __init chrp_calibrate_decr(void) |
| 168 | { | 230 | { |
| 169 | struct device_node *cpu; | 231 | struct device_node *cpu; |
| 170 | unsigned int freq, *fp; | 232 | unsigned int freq, *fp; |
| 171 | 233 | ||
| 172 | if (via_calibrate_decr()) | 234 | if (chrp_via_calibrate_decr()) |
| 173 | return; | 235 | return; |
| 174 | 236 | ||
| 175 | /* | 237 | /* |
diff --git a/arch/ppc/platforms/pmac_backlight.c b/arch/ppc/platforms/pmac_backlight.c deleted file mode 100644 index 8be2f7d071f0..000000000000 --- a/arch/ppc/platforms/pmac_backlight.c +++ /dev/null | |||
| @@ -1,202 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Miscellaneous procedures for dealing with the PowerMac hardware. | ||
| 3 | * Contains support for the backlight. | ||
| 4 | * | ||
| 5 | * Copyright (C) 2000 Benjamin Herrenschmidt | ||
| 6 | * | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/config.h> | ||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/stddef.h> | ||
| 13 | #include <linux/reboot.h> | ||
| 14 | #include <linux/nvram.h> | ||
| 15 | #include <linux/console.h> | ||
| 16 | #include <asm/sections.h> | ||
| 17 | #include <asm/ptrace.h> | ||
| 18 | #include <asm/io.h> | ||
| 19 | #include <asm/pgtable.h> | ||
| 20 | #include <asm/system.h> | ||
| 21 | #include <asm/prom.h> | ||
| 22 | #include <asm/machdep.h> | ||
| 23 | #include <asm/nvram.h> | ||
| 24 | #include <asm/backlight.h> | ||
| 25 | |||
| 26 | #include <linux/adb.h> | ||
| 27 | #include <linux/pmu.h> | ||
| 28 | |||
| 29 | static struct backlight_controller *backlighter; | ||
| 30 | static void* backlighter_data; | ||
| 31 | static int backlight_autosave; | ||
| 32 | static int backlight_level = BACKLIGHT_MAX; | ||
| 33 | static int backlight_enabled = 1; | ||
| 34 | static int backlight_req_level = -1; | ||
| 35 | static int backlight_req_enable = -1; | ||
| 36 | |||
| 37 | static void backlight_callback(void *); | ||
| 38 | static DECLARE_WORK(backlight_work, backlight_callback, NULL); | ||
| 39 | |||
| 40 | void register_backlight_controller(struct backlight_controller *ctrler, | ||
| 41 | void *data, char *type) | ||
| 42 | { | ||
| 43 | struct device_node* bk_node; | ||
| 44 | char *prop; | ||
| 45 | int valid = 0; | ||
| 46 | |||
| 47 | /* There's already a matching controller, bail out */ | ||
| 48 | if (backlighter != NULL) | ||
| 49 | return; | ||
| 50 | |||
| 51 | bk_node = find_devices("backlight"); | ||
| 52 | |||
| 53 | #ifdef CONFIG_ADB_PMU | ||
| 54 | /* Special case for the old PowerBook since I can't test on it */ | ||
| 55 | backlight_autosave = machine_is_compatible("AAPL,3400/2400") | ||
| 56 | || machine_is_compatible("AAPL,3500"); | ||
| 57 | if ((backlight_autosave | ||
| 58 | || machine_is_compatible("AAPL,PowerBook1998") | ||
| 59 | || machine_is_compatible("PowerBook1,1")) | ||
| 60 | && !strcmp(type, "pmu")) | ||
| 61 | valid = 1; | ||
| 62 | #endif | ||
| 63 | if (bk_node) { | ||
| 64 | prop = get_property(bk_node, "backlight-control", NULL); | ||
| 65 | if (prop && !strncmp(prop, type, strlen(type))) | ||
| 66 | valid = 1; | ||
| 67 | } | ||
| 68 | if (!valid) | ||
| 69 | return; | ||
| 70 | backlighter = ctrler; | ||
| 71 | backlighter_data = data; | ||
| 72 | |||
| 73 | if (bk_node && !backlight_autosave) | ||
| 74 | prop = get_property(bk_node, "bklt", NULL); | ||
| 75 | else | ||
| 76 | prop = NULL; | ||
| 77 | if (prop) { | ||
| 78 | backlight_level = ((*prop)+1) >> 1; | ||
| 79 | if (backlight_level > BACKLIGHT_MAX) | ||
| 80 | backlight_level = BACKLIGHT_MAX; | ||
| 81 | } | ||
| 82 | |||
| 83 | #ifdef CONFIG_ADB_PMU | ||
| 84 | if (backlight_autosave) { | ||
| 85 | struct adb_request req; | ||
| 86 | pmu_request(&req, NULL, 2, 0xd9, 0); | ||
| 87 | while (!req.complete) | ||
| 88 | pmu_poll(); | ||
| 89 | backlight_level = req.reply[0] >> 4; | ||
| 90 | } | ||
| 91 | #endif | ||
| 92 | acquire_console_sem(); | ||
| 93 | if (!backlighter->set_enable(1, backlight_level, data)) | ||
| 94 | backlight_enabled = 1; | ||
| 95 | release_console_sem(); | ||
| 96 | |||
| 97 | printk(KERN_INFO "Registered \"%s\" backlight controller," | ||
| 98 | "level: %d/15\n", type, backlight_level); | ||
| 99 | } | ||
| 100 | EXPORT_SYMBOL(register_backlight_controller); | ||
| 101 | |||
| 102 | void unregister_backlight_controller(struct backlight_controller | ||
| 103 | *ctrler, void *data) | ||
| 104 | { | ||
| 105 | /* We keep the current backlight level (for now) */ | ||
| 106 | if (ctrler == backlighter && data == backlighter_data) | ||
| 107 | backlighter = NULL; | ||
| 108 | } | ||
| 109 | EXPORT_SYMBOL(unregister_backlight_controller); | ||
| 110 | |||
| 111 | static int __set_backlight_enable(int enable) | ||
| 112 | { | ||
| 113 | int rc; | ||
| 114 | |||
| 115 | if (!backlighter) | ||
| 116 | return -ENODEV; | ||
| 117 | acquire_console_sem(); | ||
| 118 | rc = backlighter->set_enable(enable, backlight_level, | ||
| 119 | backlighter_data); | ||
| 120 | if (!rc) | ||
| 121 | backlight_enabled = enable; | ||
| 122 | release_console_sem(); | ||
| 123 | return rc; | ||
| 124 | } | ||
| 125 | int set_backlight_enable(int enable) | ||
| 126 | { | ||
| 127 | if (!backlighter) | ||
| 128 | return -ENODEV; | ||
| 129 | backlight_req_enable = enable; | ||
| 130 | schedule_work(&backlight_work); | ||
| 131 | return 0; | ||
| 132 | } | ||
| 133 | |||
| 134 | EXPORT_SYMBOL(set_backlight_enable); | ||
| 135 | |||
| 136 | int get_backlight_enable(void) | ||
| 137 | { | ||
| 138 | if (!backlighter) | ||
| 139 | return -ENODEV; | ||
| 140 | return backlight_enabled; | ||
| 141 | } | ||
| 142 | EXPORT_SYMBOL(get_backlight_enable); | ||
| 143 | |||
| 144 | static int __set_backlight_level(int level) | ||
| 145 | { | ||
| 146 | int rc = 0; | ||
| 147 | |||
| 148 | if (!backlighter) | ||
| 149 | return -ENODEV; | ||
| 150 | if (level < BACKLIGHT_MIN) | ||
| 151 | level = BACKLIGHT_OFF; | ||
| 152 | if (level > BACKLIGHT_MAX) | ||
| 153 | level = BACKLIGHT_MAX; | ||
| 154 | acquire_console_sem(); | ||
| 155 | if (backlight_enabled) | ||
| 156 | rc = backlighter->set_level(level, backlighter_data); | ||
| 157 | if (!rc) | ||
| 158 | backlight_level = level; | ||
| 159 | release_console_sem(); | ||
| 160 | if (!rc && !backlight_autosave) { | ||
| 161 | level <<=1; | ||
| 162 | if (level & 0x10) | ||
| 163 | level |= 0x01; | ||
| 164 | // -- todo: save to property "bklt" | ||
| 165 | } | ||
| 166 | return rc; | ||
| 167 | } | ||
| 168 | int set_backlight_level(int level) | ||
| 169 | { | ||
| 170 | if (!backlighter) | ||
| 171 | return -ENODEV; | ||
| 172 | backlight_req_level = level; | ||
| 173 | schedule_work(&backlight_work); | ||
| 174 | return 0; | ||
| 175 | } | ||
| 176 | |||
| 177 | EXPORT_SYMBOL(set_backlight_level); | ||
| 178 | |||
| 179 | int get_backlight_level(void) | ||
| 180 | { | ||
| 181 | if (!backlighter) | ||
| 182 | return -ENODEV; | ||
| 183 | return backlight_level; | ||
| 184 | } | ||
| 185 | EXPORT_SYMBOL(get_backlight_level); | ||
| 186 | |||
| 187 | static void backlight_callback(void *dummy) | ||
| 188 | { | ||
| 189 | int level, enable; | ||
| 190 | |||
| 191 | do { | ||
| 192 | level = backlight_req_level; | ||
| 193 | enable = backlight_req_enable; | ||
| 194 | mb(); | ||
| 195 | |||
| 196 | if (level >= 0) | ||
| 197 | __set_backlight_level(level); | ||
| 198 | if (enable >= 0) | ||
| 199 | __set_backlight_enable(enable); | ||
| 200 | } while(cmpxchg(&backlight_req_level, level, -1) != level || | ||
| 201 | cmpxchg(&backlight_req_enable, enable, -1) != enable); | ||
| 202 | } | ||
diff --git a/arch/ppc/platforms/pmac_cache.S b/arch/ppc/platforms/pmac_cache.S deleted file mode 100644 index fb977de6b704..000000000000 --- a/arch/ppc/platforms/pmac_cache.S +++ /dev/null | |||
| @@ -1,359 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * This file contains low-level cache management functions | ||
| 3 | * used for sleep and CPU speed changes on Apple machines. | ||
| 4 | * (In fact the only thing that is Apple-specific is that we assume | ||
| 5 | * that we can read from ROM at physical address 0xfff00000.) | ||
| 6 | * | ||
| 7 | * Copyright (C) 2004 Paul Mackerras (paulus@samba.org) and | ||
| 8 | * Benjamin Herrenschmidt (benh@kernel.crashing.org) | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or | ||
| 11 | * modify it under the terms of the GNU General Public License | ||
| 12 | * as published by the Free Software Foundation; either version | ||
| 13 | * 2 of the License, or (at your option) any later version. | ||
| 14 | * | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/config.h> | ||
| 18 | #include <asm/processor.h> | ||
| 19 | #include <asm/ppc_asm.h> | ||
| 20 | #include <asm/cputable.h> | ||
| 21 | |||
| 22 | /* | ||
| 23 | * Flush and disable all data caches (dL1, L2, L3). This is used | ||
| 24 | * when going to sleep, when doing a PMU based cpufreq transition, | ||
| 25 | * or when "offlining" a CPU on SMP machines. This code is over | ||
| 26 | * paranoid, but I've had enough issues with various CPU revs and | ||
| 27 | * bugs that I decided it was worth beeing over cautious | ||
| 28 | */ | ||
| 29 | |||
| 30 | _GLOBAL(flush_disable_caches) | ||
| 31 | #ifndef CONFIG_6xx | ||
| 32 | blr | ||
| 33 | #else | ||
| 34 | BEGIN_FTR_SECTION | ||
| 35 | b flush_disable_745x | ||
| 36 | END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450) | ||
| 37 | BEGIN_FTR_SECTION | ||
| 38 | b flush_disable_75x | ||
| 39 | END_FTR_SECTION_IFSET(CPU_FTR_L2CR) | ||
| 40 | b __flush_disable_L1 | ||
| 41 | |||
| 42 | /* This is the code for G3 and 74[01]0 */ | ||
| 43 | flush_disable_75x: | ||
| 44 | mflr r10 | ||
| 45 | |||
| 46 | /* Turn off EE and DR in MSR */ | ||
| 47 | mfmsr r11 | ||
| 48 | rlwinm r0,r11,0,~MSR_EE | ||
| 49 | rlwinm r0,r0,0,~MSR_DR | ||
| 50 | sync | ||
| 51 | mtmsr r0 | ||
| 52 | isync | ||
| 53 | |||
| 54 | /* Stop DST streams */ | ||
| 55 | BEGIN_FTR_SECTION | ||
| 56 | DSSALL | ||
| 57 | sync | ||
| 58 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | ||
| 59 | |||
| 60 | /* Stop DPM */ | ||
| 61 | mfspr r8,SPRN_HID0 /* Save SPRN_HID0 in r8 */ | ||
| 62 | rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */ | ||
| 63 | sync | ||
| 64 | mtspr SPRN_HID0,r4 /* Disable DPM */ | ||
| 65 | sync | ||
| 66 | |||
| 67 | /* Disp-flush L1. We have a weird problem here that I never | ||
| 68 | * totally figured out. On 750FX, using the ROM for the flush | ||
| 69 | * results in a non-working flush. We use that workaround for | ||
| 70 | * now until I finally understand what's going on. --BenH | ||
| 71 | */ | ||
| 72 | |||
| 73 | /* ROM base by default */ | ||
| 74 | lis r4,0xfff0 | ||
| 75 | mfpvr r3 | ||
| 76 | srwi r3,r3,16 | ||
| 77 | cmplwi cr0,r3,0x7000 | ||
| 78 | bne+ 1f | ||
| 79 | /* RAM base on 750FX */ | ||
| 80 | li r4,0 | ||
| 81 | 1: li r4,0x4000 | ||
| 82 | mtctr r4 | ||
| 83 | 1: lwz r0,0(r4) | ||
| 84 | addi r4,r4,32 | ||
| 85 | bdnz 1b | ||
| 86 | sync | ||
| 87 | isync | ||
| 88 | |||
| 89 | /* Disable / invalidate / enable L1 data */ | ||
| 90 | mfspr r3,SPRN_HID0 | ||
| 91 | rlwinm r3,r3,0,~(HID0_DCE | HID0_ICE) | ||
| 92 | mtspr SPRN_HID0,r3 | ||
| 93 | sync | ||
| 94 | isync | ||
| 95 | ori r3,r3,(HID0_DCE|HID0_DCI|HID0_ICE|HID0_ICFI) | ||
| 96 | sync | ||
| 97 | isync | ||
| 98 | mtspr SPRN_HID0,r3 | ||
| 99 | xori r3,r3,(HID0_DCI|HID0_ICFI) | ||
| 100 | mtspr SPRN_HID0,r3 | ||
| 101 | sync | ||
| 102 | |||
| 103 | /* Get the current enable bit of the L2CR into r4 */ | ||
| 104 | mfspr r5,SPRN_L2CR | ||
| 105 | /* Set to data-only (pre-745x bit) */ | ||
| 106 | oris r3,r5,L2CR_L2DO@h | ||
| 107 | b 2f | ||
| 108 | /* When disabling L2, code must be in L1 */ | ||
| 109 | .balign 32 | ||
| 110 | 1: mtspr SPRN_L2CR,r3 | ||
| 111 | 3: sync | ||
| 112 | isync | ||
| 113 | b 1f | ||
| 114 | 2: b 3f | ||
| 115 | 3: sync | ||
| 116 | isync | ||
| 117 | b 1b | ||
| 118 | 1: /* disp-flush L2. The interesting thing here is that the L2 can be | ||
| 119 | * up to 2Mb ... so using the ROM, we'll end up wrapping back to memory | ||
| 120 | * but that is probbaly fine. We disp-flush over 4Mb to be safe | ||
| 121 | */ | ||
| 122 | lis r4,2 | ||
| 123 | mtctr r4 | ||
| 124 | lis r4,0xfff0 | ||
| 125 | 1: lwz r0,0(r4) | ||
| 126 | addi r4,r4,32 | ||
| 127 | bdnz 1b | ||
| 128 | sync | ||
| 129 | isync | ||
| 130 | lis r4,2 | ||
| 131 | mtctr r4 | ||
| 132 | lis r4,0xfff0 | ||
| 133 | 1: dcbf 0,r4 | ||
| 134 | addi r4,r4,32 | ||
| 135 | bdnz 1b | ||
| 136 | sync | ||
| 137 | isync | ||
| 138 | |||
| 139 | /* now disable L2 */ | ||
| 140 | rlwinm r5,r5,0,~L2CR_L2E | ||
| 141 | b 2f | ||
| 142 | /* When disabling L2, code must be in L1 */ | ||
| 143 | .balign 32 | ||
| 144 | 1: mtspr SPRN_L2CR,r5 | ||
| 145 | 3: sync | ||
| 146 | isync | ||
| 147 | b 1f | ||
| 148 | 2: b 3f | ||
| 149 | 3: sync | ||
| 150 | isync | ||
| 151 | b 1b | ||
| 152 | 1: sync | ||
| 153 | isync | ||
| 154 | /* Invalidate L2. This is pre-745x, we clear the L2I bit ourselves */ | ||
| 155 | oris r4,r5,L2CR_L2I@h | ||
| 156 | mtspr SPRN_L2CR,r4 | ||
| 157 | sync | ||
| 158 | isync | ||
| 159 | |||
| 160 | /* Wait for the invalidation to complete */ | ||
| 161 | 1: mfspr r3,SPRN_L2CR | ||
| 162 | rlwinm. r0,r3,0,31,31 | ||
| 163 | bne 1b | ||
| 164 | |||
| 165 | /* Clear L2I */ | ||
| 166 | xoris r4,r4,L2CR_L2I@h | ||
| 167 | sync | ||
| 168 | mtspr SPRN_L2CR,r4 | ||
| 169 | sync | ||
| 170 | |||
| 171 | /* now disable the L1 data cache */ | ||
| 172 | mfspr r0,SPRN_HID0 | ||
| 173 | rlwinm r0,r0,0,~(HID0_DCE|HID0_ICE) | ||
| 174 | mtspr SPRN_HID0,r0 | ||
| 175 | sync | ||
| 176 | isync | ||
| 177 | |||
| 178 | /* Restore HID0[DPM] to whatever it was before */ | ||
| 179 | sync | ||
| 180 | mfspr r0,SPRN_HID0 | ||
| 181 | rlwimi r0,r8,0,11,11 /* Turn back HID0[DPM] */ | ||
| 182 | mtspr SPRN_HID0,r0 | ||
| 183 | sync | ||
| 184 | |||
| 185 | /* restore DR and EE */ | ||
| 186 | sync | ||
| 187 | mtmsr r11 | ||
| 188 | isync | ||
| 189 | |||
| 190 | mtlr r10 | ||
| 191 | blr | ||
| 192 | |||
| 193 | /* This code is for 745x processors */ | ||
| 194 | flush_disable_745x: | ||
| 195 | /* Turn off EE and DR in MSR */ | ||
| 196 | mfmsr r11 | ||
| 197 | rlwinm r0,r11,0,~MSR_EE | ||
| 198 | rlwinm r0,r0,0,~MSR_DR | ||
| 199 | sync | ||
| 200 | mtmsr r0 | ||
| 201 | isync | ||
| 202 | |||
| 203 | /* Stop prefetch streams */ | ||
| 204 | DSSALL | ||
| 205 | sync | ||
| 206 | |||
| 207 | /* Disable L2 prefetching */ | ||
| 208 | mfspr r0,SPRN_MSSCR0 | ||
| 209 | rlwinm r0,r0,0,0,29 | ||
| 210 | mtspr SPRN_MSSCR0,r0 | ||
| 211 | sync | ||
| 212 | isync | ||
| 213 | lis r4,0 | ||
| 214 | dcbf 0,r4 | ||
| 215 | dcbf 0,r4 | ||
| 216 | dcbf 0,r4 | ||
| 217 | dcbf 0,r4 | ||
| 218 | dcbf 0,r4 | ||
| 219 | dcbf 0,r4 | ||
| 220 | dcbf 0,r4 | ||
| 221 | dcbf 0,r4 | ||
| 222 | |||
| 223 | /* Due to a bug with the HW flush on some CPU revs, we occasionally | ||
| 224 | * experience data corruption. I'm adding a displacement flush along | ||
| 225 | * with a dcbf loop over a few Mb to "help". The problem isn't totally | ||
| 226 | * fixed by this in theory, but at least, in practice, I couldn't reproduce | ||
| 227 | * it even with a big hammer... | ||
| 228 | */ | ||
| 229 | |||
| 230 | lis r4,0x0002 | ||
| 231 | mtctr r4 | ||
| 232 | li r4,0 | ||
| 233 | 1: | ||
| 234 | lwz r0,0(r4) | ||
| 235 | addi r4,r4,32 /* Go to start of next cache line */ | ||
| 236 | bdnz 1b | ||
| 237 | isync | ||
| 238 | |||
| 239 | /* Now, flush the first 4MB of memory */ | ||
| 240 | lis r4,0x0002 | ||
| 241 | mtctr r4 | ||
| 242 | li r4,0 | ||
| 243 | sync | ||
| 244 | 1: | ||
| 245 | dcbf 0,r4 | ||
| 246 | addi r4,r4,32 /* Go to start of next cache line */ | ||
| 247 | bdnz 1b | ||
| 248 | |||
| 249 | /* Flush and disable the L1 data cache */ | ||
| 250 | mfspr r6,SPRN_LDSTCR | ||
| 251 | lis r3,0xfff0 /* read from ROM for displacement flush */ | ||
| 252 | li r4,0xfe /* start with only way 0 unlocked */ | ||
| 253 | li r5,128 /* 128 lines in each way */ | ||
| 254 | 1: mtctr r5 | ||
| 255 | rlwimi r6,r4,0,24,31 | ||
| 256 | mtspr SPRN_LDSTCR,r6 | ||
| 257 | sync | ||
| 258 | isync | ||
| 259 | 2: lwz r0,0(r3) /* touch each cache line */ | ||
| 260 | addi r3,r3,32 | ||
| 261 | bdnz 2b | ||
| 262 | rlwinm r4,r4,1,24,30 /* move on to the next way */ | ||
| 263 | ori r4,r4,1 | ||
| 264 | cmpwi r4,0xff /* all done? */ | ||
| 265 | bne 1b | ||
| 266 | /* now unlock the L1 data cache */ | ||
| 267 | li r4,0 | ||
| 268 | rlwimi r6,r4,0,24,31 | ||
| 269 | sync | ||
| 270 | mtspr SPRN_LDSTCR,r6 | ||
| 271 | sync | ||
| 272 | isync | ||
| 273 | |||
| 274 | /* Flush the L2 cache using the hardware assist */ | ||
| 275 | mfspr r3,SPRN_L2CR | ||
| 276 | cmpwi r3,0 /* check if it is enabled first */ | ||
| 277 | bge 4f | ||
| 278 | oris r0,r3,(L2CR_L2IO_745x|L2CR_L2DO_745x)@h | ||
| 279 | b 2f | ||
| 280 | /* When disabling/locking L2, code must be in L1 */ | ||
| 281 | .balign 32 | ||
| 282 | 1: mtspr SPRN_L2CR,r0 /* lock the L2 cache */ | ||
| 283 | 3: sync | ||
| 284 | isync | ||
| 285 | b 1f | ||
| 286 | 2: b 3f | ||
| 287 | 3: sync | ||
| 288 | isync | ||
| 289 | b 1b | ||
| 290 | 1: sync | ||
| 291 | isync | ||
| 292 | ori r0,r3,L2CR_L2HWF_745x | ||
| 293 | sync | ||
| 294 | mtspr SPRN_L2CR,r0 /* set the hardware flush bit */ | ||
| 295 | 3: mfspr r0,SPRN_L2CR /* wait for it to go to 0 */ | ||
| 296 | andi. r0,r0,L2CR_L2HWF_745x | ||
| 297 | bne 3b | ||
| 298 | sync | ||
| 299 | rlwinm r3,r3,0,~L2CR_L2E | ||
| 300 | b 2f | ||
| 301 | /* When disabling L2, code must be in L1 */ | ||
| 302 | .balign 32 | ||
| 303 | 1: mtspr SPRN_L2CR,r3 /* disable the L2 cache */ | ||
| 304 | 3: sync | ||
| 305 | isync | ||
| 306 | b 1f | ||
| 307 | 2: b 3f | ||
| 308 | 3: sync | ||
| 309 | isync | ||
| 310 | b 1b | ||
| 311 | 1: sync | ||
| 312 | isync | ||
| 313 | oris r4,r3,L2CR_L2I@h | ||
| 314 | mtspr SPRN_L2CR,r4 | ||
| 315 | sync | ||
| 316 | isync | ||
| 317 | 1: mfspr r4,SPRN_L2CR | ||
| 318 | andis. r0,r4,L2CR_L2I@h | ||
| 319 | bne 1b | ||
| 320 | sync | ||
| 321 | |||
| 322 | BEGIN_FTR_SECTION | ||
| 323 | /* Flush the L3 cache using the hardware assist */ | ||
| 324 | 4: mfspr r3,SPRN_L3CR | ||
| 325 | cmpwi r3,0 /* check if it is enabled */ | ||
| 326 | bge 6f | ||
| 327 | oris r0,r3,L3CR_L3IO@h | ||
| 328 | ori r0,r0,L3CR_L3DO | ||
| 329 | sync | ||
| 330 | mtspr SPRN_L3CR,r0 /* lock the L3 cache */ | ||
| 331 | sync | ||
| 332 | isync | ||
| 333 | ori r0,r0,L3CR_L3HWF | ||
| 334 | sync | ||
| 335 | mtspr SPRN_L3CR,r0 /* set the hardware flush bit */ | ||
| 336 | 5: mfspr r0,SPRN_L3CR /* wait for it to go to zero */ | ||
| 337 | andi. r0,r0,L3CR_L3HWF | ||
| 338 | bne 5b | ||
| 339 | rlwinm r3,r3,0,~L3CR_L3E | ||
| 340 | sync | ||
| 341 | mtspr SPRN_L3CR,r3 /* disable the L3 cache */ | ||
| 342 | sync | ||
| 343 | ori r4,r3,L3CR_L3I | ||
| 344 | mtspr SPRN_L3CR,r4 | ||
| 345 | 1: mfspr r4,SPRN_L3CR | ||
| 346 | andi. r0,r4,L3CR_L3I | ||
| 347 | bne 1b | ||
| 348 | sync | ||
| 349 | END_FTR_SECTION_IFSET(CPU_FTR_L3CR) | ||
| 350 | |||
| 351 | 6: mfspr r0,SPRN_HID0 /* now disable the L1 data cache */ | ||
| 352 | rlwinm r0,r0,0,~HID0_DCE | ||
| 353 | mtspr SPRN_HID0,r0 | ||
| 354 | sync | ||
| 355 | isync | ||
| 356 | mtmsr r11 /* restore DR and EE */ | ||
| 357 | isync | ||
| 358 | blr | ||
| 359 | #endif /* CONFIG_6xx */ | ||
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c deleted file mode 100644 index fba7e4d7c0bf..000000000000 --- a/arch/ppc/platforms/pmac_cpufreq.c +++ /dev/null | |||
| @@ -1,735 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * arch/ppc/platforms/pmac_cpufreq.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org> | ||
| 5 | * Copyright (C) 2004 John Steele Scott <toojays@toojays.net> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * TODO: Need a big cleanup here. Basically, we need to have different | ||
| 12 | * cpufreq_driver structures for the different type of HW instead of the | ||
| 13 | * current mess. We also need to better deal with the detection of the | ||
| 14 | * type of machine. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/config.h> | ||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/types.h> | ||
| 21 | #include <linux/errno.h> | ||
| 22 | #include <linux/kernel.h> | ||
| 23 | #include <linux/delay.h> | ||
| 24 | #include <linux/sched.h> | ||
| 25 | #include <linux/adb.h> | ||
| 26 | #include <linux/pmu.h> | ||
| 27 | #include <linux/slab.h> | ||
| 28 | #include <linux/cpufreq.h> | ||
| 29 | #include <linux/init.h> | ||
| 30 | #include <linux/sysdev.h> | ||
| 31 | #include <linux/i2c.h> | ||
| 32 | #include <linux/hardirq.h> | ||
| 33 | #include <asm/prom.h> | ||
| 34 | #include <asm/machdep.h> | ||
| 35 | #include <asm/irq.h> | ||
| 36 | #include <asm/pmac_feature.h> | ||
| 37 | #include <asm/mmu_context.h> | ||
| 38 | #include <asm/sections.h> | ||
| 39 | #include <asm/cputable.h> | ||
| 40 | #include <asm/time.h> | ||
| 41 | #include <asm/system.h> | ||
| 42 | #include <asm/open_pic.h> | ||
| 43 | #include <asm/keylargo.h> | ||
| 44 | |||
| 45 | /* WARNING !!! This will cause calibrate_delay() to be called, | ||
| 46 | * but this is an __init function ! So you MUST go edit | ||
| 47 | * init/main.c to make it non-init before enabling DEBUG_FREQ | ||
| 48 | */ | ||
| 49 | #undef DEBUG_FREQ | ||
| 50 | |||
| 51 | /* | ||
| 52 | * There is a problem with the core cpufreq code on SMP kernels, | ||
| 53 | * it won't recalculate the Bogomips properly | ||
| 54 | */ | ||
| 55 | #ifdef CONFIG_SMP | ||
| 56 | #warning "WARNING, CPUFREQ not recommended on SMP kernels" | ||
| 57 | #endif | ||
| 58 | |||
| 59 | extern void low_choose_7447a_dfs(int dfs); | ||
| 60 | extern void low_choose_750fx_pll(int pll); | ||
| 61 | extern void low_sleep_handler(void); | ||
| 62 | |||
| 63 | /* | ||
| 64 | * Currently, PowerMac cpufreq supports only high & low frequencies | ||
| 65 | * that are set by the firmware | ||
| 66 | */ | ||
| 67 | static unsigned int low_freq; | ||
| 68 | static unsigned int hi_freq; | ||
| 69 | static unsigned int cur_freq; | ||
| 70 | static unsigned int sleep_freq; | ||
| 71 | |||
| 72 | /* | ||
| 73 | * Different models uses different mecanisms to switch the frequency | ||
| 74 | */ | ||
| 75 | static int (*set_speed_proc)(int low_speed); | ||
| 76 | static unsigned int (*get_speed_proc)(void); | ||
| 77 | |||
| 78 | /* | ||
| 79 | * Some definitions used by the various speedprocs | ||
| 80 | */ | ||
| 81 | static u32 voltage_gpio; | ||
| 82 | static u32 frequency_gpio; | ||
| 83 | static u32 slew_done_gpio; | ||
| 84 | static int no_schedule; | ||
| 85 | static int has_cpu_l2lve; | ||
| 86 | static int is_pmu_based; | ||
| 87 | |||
| 88 | /* There are only two frequency states for each processor. Values | ||
| 89 | * are in kHz for the time being. | ||
| 90 | */ | ||
| 91 | #define CPUFREQ_HIGH 0 | ||
| 92 | #define CPUFREQ_LOW 1 | ||
| 93 | |||
| 94 | static struct cpufreq_frequency_table pmac_cpu_freqs[] = { | ||
| 95 | {CPUFREQ_HIGH, 0}, | ||
| 96 | {CPUFREQ_LOW, 0}, | ||
| 97 | {0, CPUFREQ_TABLE_END}, | ||
| 98 | }; | ||
| 99 | |||
| 100 | static struct freq_attr* pmac_cpu_freqs_attr[] = { | ||
| 101 | &cpufreq_freq_attr_scaling_available_freqs, | ||
| 102 | NULL, | ||
| 103 | }; | ||
| 104 | |||
| 105 | static inline void local_delay(unsigned long ms) | ||
| 106 | { | ||
| 107 | if (no_schedule) | ||
| 108 | mdelay(ms); | ||
| 109 | else | ||
| 110 | msleep(ms); | ||
| 111 | } | ||
| 112 | |||
| 113 | static inline void wakeup_decrementer(void) | ||
| 114 | { | ||
| 115 | set_dec(tb_ticks_per_jiffy); | ||
| 116 | /* No currently-supported powerbook has a 601, | ||
| 117 | * so use get_tbl, not native | ||
| 118 | */ | ||
| 119 | last_jiffy_stamp(0) = tb_last_stamp = get_tbl(); | ||
| 120 | } | ||
| 121 | |||
| 122 | #ifdef DEBUG_FREQ | ||
| 123 | static inline void debug_calc_bogomips(void) | ||
| 124 | { | ||
| 125 | /* This will cause a recalc of bogomips and display the | ||
| 126 | * result. We backup/restore the value to avoid affecting the | ||
| 127 | * core cpufreq framework's own calculation. | ||
| 128 | */ | ||
| 129 | extern void calibrate_delay(void); | ||
| 130 | |||
| 131 | unsigned long save_lpj = loops_per_jiffy; | ||
| 132 | calibrate_delay(); | ||
| 133 | loops_per_jiffy = save_lpj; | ||
| 134 | } | ||
| 135 | #endif /* DEBUG_FREQ */ | ||
| 136 | |||
| 137 | /* Switch CPU speed under 750FX CPU control | ||
| 138 | */ | ||
| 139 | static int cpu_750fx_cpu_speed(int low_speed) | ||
| 140 | { | ||
| 141 | u32 hid2; | ||
| 142 | |||
| 143 | if (low_speed == 0) { | ||
| 144 | /* ramping up, set voltage first */ | ||
| 145 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05); | ||
| 146 | /* Make sure we sleep for at least 1ms */ | ||
| 147 | local_delay(10); | ||
| 148 | |||
| 149 | /* tweak L2 for high voltage */ | ||
| 150 | if (has_cpu_l2lve) { | ||
| 151 | hid2 = mfspr(SPRN_HID2); | ||
| 152 | hid2 &= ~0x2000; | ||
| 153 | mtspr(SPRN_HID2, hid2); | ||
| 154 | } | ||
| 155 | } | ||
| 156 | #ifdef CONFIG_6xx | ||
| 157 | low_choose_750fx_pll(low_speed); | ||
| 158 | #endif | ||
| 159 | if (low_speed == 1) { | ||
| 160 | /* tweak L2 for low voltage */ | ||
| 161 | if (has_cpu_l2lve) { | ||
| 162 | hid2 = mfspr(SPRN_HID2); | ||
| 163 | hid2 |= 0x2000; | ||
| 164 | mtspr(SPRN_HID2, hid2); | ||
| 165 | } | ||
| 166 | |||
| 167 | /* ramping down, set voltage last */ | ||
| 168 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04); | ||
| 169 | local_delay(10); | ||
| 170 | } | ||
| 171 | |||
| 172 | return 0; | ||
| 173 | } | ||
| 174 | |||
| 175 | static unsigned int cpu_750fx_get_cpu_speed(void) | ||
| 176 | { | ||
| 177 | if (mfspr(SPRN_HID1) & HID1_PS) | ||
| 178 | return low_freq; | ||
| 179 | else | ||
| 180 | return hi_freq; | ||
| 181 | } | ||
| 182 | |||
| 183 | /* Switch CPU speed using DFS */ | ||
| 184 | static int dfs_set_cpu_speed(int low_speed) | ||
| 185 | { | ||
| 186 | if (low_speed == 0) { | ||
| 187 | /* ramping up, set voltage first */ | ||
| 188 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05); | ||
| 189 | /* Make sure we sleep for at least 1ms */ | ||
| 190 | local_delay(1); | ||
| 191 | } | ||
| 192 | |||
| 193 | /* set frequency */ | ||
| 194 | #ifdef CONFIG_6xx | ||
| 195 | low_choose_7447a_dfs(low_speed); | ||
| 196 | #endif | ||
| 197 | udelay(100); | ||
| 198 | |||
| 199 | if (low_speed == 1) { | ||
| 200 | /* ramping down, set voltage last */ | ||
| 201 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04); | ||
| 202 | local_delay(1); | ||
| 203 | } | ||
| 204 | |||
| 205 | return 0; | ||
| 206 | } | ||
| 207 | |||
| 208 | static unsigned int dfs_get_cpu_speed(void) | ||
| 209 | { | ||
| 210 | if (mfspr(SPRN_HID1) & HID1_DFS) | ||
| 211 | return low_freq; | ||
| 212 | else | ||
| 213 | return hi_freq; | ||
| 214 | } | ||
| 215 | |||
| 216 | |||
| 217 | /* Switch CPU speed using slewing GPIOs | ||
| 218 | */ | ||
| 219 | static int gpios_set_cpu_speed(int low_speed) | ||
| 220 | { | ||
| 221 | int gpio, timeout = 0; | ||
| 222 | |||
| 223 | /* If ramping up, set voltage first */ | ||
| 224 | if (low_speed == 0) { | ||
| 225 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05); | ||
| 226 | /* Delay is way too big but it's ok, we schedule */ | ||
| 227 | local_delay(10); | ||
| 228 | } | ||
| 229 | |||
| 230 | /* Set frequency */ | ||
| 231 | gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0); | ||
| 232 | if (low_speed == ((gpio & 0x01) == 0)) | ||
| 233 | goto skip; | ||
| 234 | |||
| 235 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio, | ||
| 236 | low_speed ? 0x04 : 0x05); | ||
| 237 | udelay(200); | ||
| 238 | do { | ||
| 239 | if (++timeout > 100) | ||
| 240 | break; | ||
| 241 | local_delay(1); | ||
| 242 | gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, slew_done_gpio, 0); | ||
| 243 | } while((gpio & 0x02) == 0); | ||
| 244 | skip: | ||
| 245 | /* If ramping down, set voltage last */ | ||
| 246 | if (low_speed == 1) { | ||
| 247 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04); | ||
| 248 | /* Delay is way too big but it's ok, we schedule */ | ||
| 249 | local_delay(10); | ||
| 250 | } | ||
| 251 | |||
| 252 | #ifdef DEBUG_FREQ | ||
| 253 | debug_calc_bogomips(); | ||
| 254 | #endif | ||
| 255 | |||
| 256 | return 0; | ||
| 257 | } | ||
| 258 | |||
| 259 | /* Switch CPU speed under PMU control | ||
| 260 | */ | ||
| 261 | static int pmu_set_cpu_speed(int low_speed) | ||
| 262 | { | ||
| 263 | struct adb_request req; | ||
| 264 | unsigned long save_l2cr; | ||
| 265 | unsigned long save_l3cr; | ||
| 266 | unsigned int pic_prio; | ||
| 267 | unsigned long flags; | ||
| 268 | |||
| 269 | preempt_disable(); | ||
| 270 | |||
| 271 | #ifdef DEBUG_FREQ | ||
| 272 | printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); | ||
| 273 | #endif | ||
| 274 | pmu_suspend(); | ||
| 275 | |||
| 276 | /* Disable all interrupt sources on openpic */ | ||
| 277 | pic_prio = openpic_get_priority(); | ||
| 278 | openpic_set_priority(0xf); | ||
| 279 | |||
| 280 | /* Make sure the decrementer won't interrupt us */ | ||
| 281 | asm volatile("mtdec %0" : : "r" (0x7fffffff)); | ||
| 282 | /* Make sure any pending DEC interrupt occuring while we did | ||
| 283 | * the above didn't re-enable the DEC */ | ||
| 284 | mb(); | ||
| 285 | asm volatile("mtdec %0" : : "r" (0x7fffffff)); | ||
| 286 | |||
| 287 | /* We can now disable MSR_EE */ | ||
| 288 | local_irq_save(flags); | ||
| 289 | |||
| 290 | /* Giveup the FPU & vec */ | ||
| 291 | enable_kernel_fp(); | ||
| 292 | |||
| 293 | #ifdef CONFIG_ALTIVEC | ||
| 294 | if (cpu_has_feature(CPU_FTR_ALTIVEC)) | ||
| 295 | enable_kernel_altivec(); | ||
| 296 | #endif /* CONFIG_ALTIVEC */ | ||
| 297 | |||
| 298 | /* Save & disable L2 and L3 caches */ | ||
| 299 | save_l3cr = _get_L3CR(); /* (returns -1 if not available) */ | ||
| 300 | save_l2cr = _get_L2CR(); /* (returns -1 if not available) */ | ||
| 301 | |||
| 302 | /* Send the new speed command. My assumption is that this command | ||
| 303 | * will cause PLL_CFG[0..3] to be changed next time CPU goes to sleep | ||
| 304 | */ | ||
| 305 | pmu_request(&req, NULL, 6, PMU_CPU_SPEED, 'W', 'O', 'O', 'F', low_speed); | ||
| 306 | while (!req.complete) | ||
| 307 | pmu_poll(); | ||
| 308 | |||
| 309 | /* Prepare the northbridge for the speed transition */ | ||
| 310 | pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,1); | ||
| 311 | |||
| 312 | /* Call low level code to backup CPU state and recover from | ||
| 313 | * hardware reset | ||
| 314 | */ | ||
| 315 | low_sleep_handler(); | ||
| 316 | |||
| 317 | /* Restore the northbridge */ | ||
| 318 | pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,0); | ||
| 319 | |||
| 320 | /* Restore L2 cache */ | ||
| 321 | if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0) | ||
| 322 | _set_L2CR(save_l2cr); | ||
| 323 | /* Restore L3 cache */ | ||
| 324 | if (save_l3cr != 0xffffffff && (save_l3cr & L3CR_L3E) != 0) | ||
| 325 | _set_L3CR(save_l3cr); | ||
| 326 | |||
| 327 | /* Restore userland MMU context */ | ||
| 328 | set_context(current->active_mm->context, current->active_mm->pgd); | ||
| 329 | |||
| 330 | #ifdef DEBUG_FREQ | ||
| 331 | printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1)); | ||
| 332 | #endif | ||
| 333 | |||
| 334 | /* Restore low level PMU operations */ | ||
| 335 | pmu_unlock(); | ||
| 336 | |||
| 337 | /* Restore decrementer */ | ||
| 338 | wakeup_decrementer(); | ||
| 339 | |||
| 340 | /* Restore interrupts */ | ||
| 341 | openpic_set_priority(pic_prio); | ||
| 342 | |||
| 343 | /* Let interrupts flow again ... */ | ||
| 344 | local_irq_restore(flags); | ||
| 345 | |||
| 346 | #ifdef DEBUG_FREQ | ||
| 347 | debug_calc_bogomips(); | ||
| 348 | #endif | ||
| 349 | |||
| 350 | pmu_resume(); | ||
| 351 | |||
| 352 | preempt_enable(); | ||
| 353 | |||
| 354 | return 0; | ||
| 355 | } | ||
| 356 | |||
| 357 | static int do_set_cpu_speed(int speed_mode, int notify) | ||
| 358 | { | ||
| 359 | struct cpufreq_freqs freqs; | ||
| 360 | unsigned long l3cr; | ||
| 361 | static unsigned long prev_l3cr; | ||
| 362 | |||
| 363 | freqs.old = cur_freq; | ||
| 364 | freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq; | ||
| 365 | freqs.cpu = smp_processor_id(); | ||
| 366 | |||
| 367 | if (freqs.old == freqs.new) | ||
| 368 | return 0; | ||
| 369 | |||
| 370 | if (notify) | ||
| 371 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
| 372 | if (speed_mode == CPUFREQ_LOW && | ||
| 373 | cpu_has_feature(CPU_FTR_L3CR)) { | ||
| 374 | l3cr = _get_L3CR(); | ||
| 375 | if (l3cr & L3CR_L3E) { | ||
| 376 | prev_l3cr = l3cr; | ||
| 377 | _set_L3CR(0); | ||
| 378 | } | ||
| 379 | } | ||
| 380 | set_speed_proc(speed_mode == CPUFREQ_LOW); | ||
| 381 | if (speed_mode == CPUFREQ_HIGH && | ||
| 382 | cpu_has_feature(CPU_FTR_L3CR)) { | ||
| 383 | l3cr = _get_L3CR(); | ||
| 384 | if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr) | ||
| 385 | _set_L3CR(prev_l3cr); | ||
| 386 | } | ||
| 387 | if (notify) | ||
| 388 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
| 389 | cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq; | ||
| 390 | |||
| 391 | return 0; | ||
| 392 | } | ||
| 393 | |||
| 394 | static unsigned int pmac_cpufreq_get_speed(unsigned int cpu) | ||
| 395 | { | ||
| 396 | return cur_freq; | ||
| 397 | } | ||
| 398 | |||
| 399 | static int pmac_cpufreq_verify(struct cpufreq_policy *policy) | ||
| 400 | { | ||
| 401 | return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs); | ||
| 402 | } | ||
| 403 | |||
| 404 | static int pmac_cpufreq_target( struct cpufreq_policy *policy, | ||
| 405 | unsigned int target_freq, | ||
| 406 | unsigned int relation) | ||
| 407 | { | ||
| 408 | unsigned int newstate = 0; | ||
| 409 | |||
| 410 | if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs, | ||
| 411 | target_freq, relation, &newstate)) | ||
| 412 | return -EINVAL; | ||
| 413 | |||
| 414 | return do_set_cpu_speed(newstate, 1); | ||
| 415 | } | ||
| 416 | |||
| 417 | unsigned int pmac_get_one_cpufreq(int i) | ||
| 418 | { | ||
| 419 | /* Supports only one CPU for now */ | ||
| 420 | return (i == 0) ? cur_freq : 0; | ||
| 421 | } | ||
| 422 | |||
| 423 | static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy) | ||
| 424 | { | ||
| 425 | if (policy->cpu != 0) | ||
| 426 | return -ENODEV; | ||
| 427 | |||
| 428 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | ||
| 429 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | ||
| 430 | policy->cur = cur_freq; | ||
| 431 | |||
| 432 | cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu); | ||
| 433 | return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs); | ||
| 434 | } | ||
| 435 | |||
| 436 | static u32 read_gpio(struct device_node *np) | ||
| 437 | { | ||
| 438 | u32 *reg = (u32 *)get_property(np, "reg", NULL); | ||
| 439 | u32 offset; | ||
| 440 | |||
| 441 | if (reg == NULL) | ||
| 442 | return 0; | ||
| 443 | /* That works for all keylargos but shall be fixed properly | ||
| 444 | * some day... The problem is that it seems we can't rely | ||
| 445 | * on the "reg" property of the GPIO nodes, they are either | ||
| 446 | * relative to the base of KeyLargo or to the base of the | ||
| 447 | * GPIO space, and the device-tree doesn't help. | ||
| 448 | */ | ||
| 449 | offset = *reg; | ||
| 450 | if (offset < KEYLARGO_GPIO_LEVELS0) | ||
| 451 | offset += KEYLARGO_GPIO_LEVELS0; | ||
| 452 | return offset; | ||
| 453 | } | ||
| 454 | |||
| 455 | static int pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg) | ||
| 456 | { | ||
| 457 | /* Ok, this could be made a bit smarter, but let's be robust for now. We | ||
| 458 | * always force a speed change to high speed before sleep, to make sure | ||
| 459 | * we have appropriate voltage and/or bus speed for the wakeup process, | ||
| 460 | * and to make sure our loops_per_jiffies are "good enough", that is will | ||
| 461 | * not cause too short delays if we sleep in low speed and wake in high | ||
| 462 | * speed.. | ||
| 463 | */ | ||
| 464 | no_schedule = 1; | ||
| 465 | sleep_freq = cur_freq; | ||
| 466 | if (cur_freq == low_freq && !is_pmu_based) | ||
| 467 | do_set_cpu_speed(CPUFREQ_HIGH, 0); | ||
| 468 | return 0; | ||
| 469 | } | ||
| 470 | |||
| 471 | static int pmac_cpufreq_resume(struct cpufreq_policy *policy) | ||
| 472 | { | ||
| 473 | /* If we resume, first check if we have a get() function */ | ||
| 474 | if (get_speed_proc) | ||
| 475 | cur_freq = get_speed_proc(); | ||
| 476 | else | ||
| 477 | cur_freq = 0; | ||
| 478 | |||
| 479 | /* We don't, hrm... we don't really know our speed here, best | ||
| 480 | * is that we force a switch to whatever it was, which is | ||
| 481 | * probably high speed due to our suspend() routine | ||
| 482 | */ | ||
| 483 | do_set_cpu_speed(sleep_freq == low_freq ? | ||
| 484 | CPUFREQ_LOW : CPUFREQ_HIGH, 0); | ||
| 485 | |||
| 486 | no_schedule = 0; | ||
| 487 | return 0; | ||
| 488 | } | ||
| 489 | |||
| 490 | static struct cpufreq_driver pmac_cpufreq_driver = { | ||
| 491 | .verify = pmac_cpufreq_verify, | ||
| 492 | .target = pmac_cpufreq_target, | ||
| 493 | .get = pmac_cpufreq_get_speed, | ||
| 494 | .init = pmac_cpufreq_cpu_init, | ||
| 495 | .suspend = pmac_cpufreq_suspend, | ||
| 496 | .resume = pmac_cpufreq_resume, | ||
| 497 | .flags = CPUFREQ_PM_NO_WARN, | ||
| 498 | .attr = pmac_cpu_freqs_attr, | ||
| 499 | .name = "powermac", | ||
| 500 | .owner = THIS_MODULE, | ||
| 501 | }; | ||
| 502 | |||
| 503 | |||
| 504 | static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode) | ||
| 505 | { | ||
| 506 | struct device_node *volt_gpio_np = of_find_node_by_name(NULL, | ||
| 507 | "voltage-gpio"); | ||
| 508 | struct device_node *freq_gpio_np = of_find_node_by_name(NULL, | ||
| 509 | "frequency-gpio"); | ||
| 510 | struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL, | ||
| 511 | "slewing-done"); | ||
| 512 | u32 *value; | ||
| 513 | |||
| 514 | /* | ||
| 515 | * Check to see if it's GPIO driven or PMU only | ||
| 516 | * | ||
| 517 | * The way we extract the GPIO address is slightly hackish, but it | ||
| 518 | * works well enough for now. We need to abstract the whole GPIO | ||
| 519 | * stuff sooner or later anyway | ||
| 520 | */ | ||
| 521 | |||
| 522 | if (volt_gpio_np) | ||
| 523 | voltage_gpio = read_gpio(volt_gpio_np); | ||
| 524 | if (freq_gpio_np) | ||
| 525 | frequency_gpio = read_gpio(freq_gpio_np); | ||
| 526 | if (slew_done_gpio_np) | ||
| 527 | slew_done_gpio = read_gpio(slew_done_gpio_np); | ||
| 528 | |||
| 529 | /* If we use the frequency GPIOs, calculate the min/max speeds based | ||
| 530 | * on the bus frequencies | ||
| 531 | */ | ||
| 532 | if (frequency_gpio && slew_done_gpio) { | ||
| 533 | int lenp, rc; | ||
| 534 | u32 *freqs, *ratio; | ||
| 535 | |||
| 536 | freqs = (u32 *)get_property(cpunode, "bus-frequencies", &lenp); | ||
| 537 | lenp /= sizeof(u32); | ||
| 538 | if (freqs == NULL || lenp != 2) { | ||
| 539 | printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n"); | ||
| 540 | return 1; | ||
| 541 | } | ||
| 542 | ratio = (u32 *)get_property(cpunode, "processor-to-bus-ratio*2", NULL); | ||
| 543 | if (ratio == NULL) { | ||
| 544 | printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n"); | ||
| 545 | return 1; | ||
| 546 | } | ||
| 547 | |||
| 548 | /* Get the min/max bus frequencies */ | ||
| 549 | low_freq = min(freqs[0], freqs[1]); | ||
| 550 | hi_freq = max(freqs[0], freqs[1]); | ||
| 551 | |||
| 552 | /* Grrrr.. It _seems_ that the device-tree is lying on the low bus | ||
| 553 | * frequency, it claims it to be around 84Mhz on some models while | ||
| 554 | * it appears to be approx. 101Mhz on all. Let's hack around here... | ||
| 555 | * fortunately, we don't need to be too precise | ||
| 556 | */ | ||
| 557 | if (low_freq < 98000000) | ||
| 558 | low_freq = 101000000; | ||
| 559 | |||
| 560 | /* Convert those to CPU core clocks */ | ||
| 561 | low_freq = (low_freq * (*ratio)) / 2000; | ||
| 562 | hi_freq = (hi_freq * (*ratio)) / 2000; | ||
| 563 | |||
| 564 | /* Now we get the frequencies, we read the GPIO to see what is out current | ||
| 565 | * speed | ||
| 566 | */ | ||
| 567 | rc = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0); | ||
| 568 | cur_freq = (rc & 0x01) ? hi_freq : low_freq; | ||
| 569 | |||
| 570 | set_speed_proc = gpios_set_cpu_speed; | ||
| 571 | return 1; | ||
| 572 | } | ||
| 573 | |||
| 574 | /* If we use the PMU, look for the min & max frequencies in the | ||
| 575 | * device-tree | ||
| 576 | */ | ||
| 577 | value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL); | ||
| 578 | if (!value) | ||
| 579 | return 1; | ||
| 580 | low_freq = (*value) / 1000; | ||
| 581 | /* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree | ||
| 582 | * here */ | ||
| 583 | if (low_freq < 100000) | ||
| 584 | low_freq *= 10; | ||
| 585 | |||
| 586 | value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL); | ||
| 587 | if (!value) | ||
| 588 | return 1; | ||
| 589 | hi_freq = (*value) / 1000; | ||
| 590 | set_speed_proc = pmu_set_cpu_speed; | ||
| 591 | is_pmu_based = 1; | ||
| 592 | |||
| 593 | return 0; | ||
| 594 | } | ||
| 595 | |||
| 596 | static int pmac_cpufreq_init_7447A(struct device_node *cpunode) | ||
| 597 | { | ||
| 598 | struct device_node *volt_gpio_np; | ||
| 599 | |||
| 600 | if (get_property(cpunode, "dynamic-power-step", NULL) == NULL) | ||
| 601 | return 1; | ||
| 602 | |||
| 603 | volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select"); | ||
| 604 | if (volt_gpio_np) | ||
| 605 | voltage_gpio = read_gpio(volt_gpio_np); | ||
| 606 | if (!voltage_gpio){ | ||
| 607 | printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n"); | ||
| 608 | return 1; | ||
| 609 | } | ||
| 610 | |||
| 611 | /* OF only reports the high frequency */ | ||
| 612 | hi_freq = cur_freq; | ||
| 613 | low_freq = cur_freq/2; | ||
| 614 | |||
| 615 | /* Read actual frequency from CPU */ | ||
| 616 | cur_freq = dfs_get_cpu_speed(); | ||
| 617 | set_speed_proc = dfs_set_cpu_speed; | ||
| 618 | get_speed_proc = dfs_get_cpu_speed; | ||
| 619 | |||
| 620 | return 0; | ||
| 621 | } | ||
| 622 | |||
| 623 | static int pmac_cpufreq_init_750FX(struct device_node *cpunode) | ||
| 624 | { | ||
| 625 | struct device_node *volt_gpio_np; | ||
| 626 | u32 pvr, *value; | ||
| 627 | |||
| 628 | if (get_property(cpunode, "dynamic-power-step", NULL) == NULL) | ||
| 629 | return 1; | ||
| 630 | |||
| 631 | hi_freq = cur_freq; | ||
| 632 | value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL); | ||
| 633 | if (!value) | ||
| 634 | return 1; | ||
| 635 | low_freq = (*value) / 1000; | ||
| 636 | |||
| 637 | volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select"); | ||
| 638 | if (volt_gpio_np) | ||
| 639 | voltage_gpio = read_gpio(volt_gpio_np); | ||
| 640 | |||
| 641 | pvr = mfspr(SPRN_PVR); | ||
| 642 | has_cpu_l2lve = !((pvr & 0xf00) == 0x100); | ||
| 643 | |||
| 644 | set_speed_proc = cpu_750fx_cpu_speed; | ||
| 645 | get_speed_proc = cpu_750fx_get_cpu_speed; | ||
| 646 | cur_freq = cpu_750fx_get_cpu_speed(); | ||
| 647 | |||
| 648 | return 0; | ||
| 649 | } | ||
| 650 | |||
| 651 | /* Currently, we support the following machines: | ||
| 652 | * | ||
| 653 | * - Titanium PowerBook 1Ghz (PMU based, 667Mhz & 1Ghz) | ||
| 654 | * - Titanium PowerBook 800 (PMU based, 667Mhz & 800Mhz) | ||
| 655 | * - Titanium PowerBook 400 (PMU based, 300Mhz & 400Mhz) | ||
| 656 | * - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz) | ||
| 657 | * - iBook2 500/600 (PMU based, 400Mhz & 500/600Mhz) | ||
| 658 | * - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage) | ||
| 659 | * - Recent MacRISC3 laptops | ||
| 660 | * - All new machines with 7447A CPUs | ||
| 661 | */ | ||
| 662 | static int __init pmac_cpufreq_setup(void) | ||
| 663 | { | ||
| 664 | struct device_node *cpunode; | ||
| 665 | u32 *value; | ||
| 666 | |||
| 667 | if (strstr(cmd_line, "nocpufreq")) | ||
| 668 | return 0; | ||
| 669 | |||
| 670 | /* Assume only one CPU */ | ||
| 671 | cpunode = find_type_devices("cpu"); | ||
| 672 | if (!cpunode) | ||
| 673 | goto out; | ||
| 674 | |||
| 675 | /* Get current cpu clock freq */ | ||
| 676 | value = (u32 *)get_property(cpunode, "clock-frequency", NULL); | ||
| 677 | if (!value) | ||
| 678 | goto out; | ||
| 679 | cur_freq = (*value) / 1000; | ||
| 680 | |||
| 681 | /* Check for 7447A based MacRISC3 */ | ||
| 682 | if (machine_is_compatible("MacRISC3") && | ||
| 683 | get_property(cpunode, "dynamic-power-step", NULL) && | ||
| 684 | PVR_VER(mfspr(SPRN_PVR)) == 0x8003) { | ||
| 685 | pmac_cpufreq_init_7447A(cpunode); | ||
| 686 | /* Check for other MacRISC3 machines */ | ||
| 687 | } else if (machine_is_compatible("PowerBook3,4") || | ||
| 688 | machine_is_compatible("PowerBook3,5") || | ||
| 689 | machine_is_compatible("MacRISC3")) { | ||
| 690 | pmac_cpufreq_init_MacRISC3(cpunode); | ||
| 691 | /* Else check for iBook2 500/600 */ | ||
| 692 | } else if (machine_is_compatible("PowerBook4,1")) { | ||
| 693 | hi_freq = cur_freq; | ||
| 694 | low_freq = 400000; | ||
| 695 | set_speed_proc = pmu_set_cpu_speed; | ||
| 696 | is_pmu_based = 1; | ||
| 697 | } | ||
| 698 | /* Else check for TiPb 550 */ | ||
| 699 | else if (machine_is_compatible("PowerBook3,3") && cur_freq == 550000) { | ||
| 700 | hi_freq = cur_freq; | ||
| 701 | low_freq = 500000; | ||
| 702 | set_speed_proc = pmu_set_cpu_speed; | ||
| 703 | is_pmu_based = 1; | ||
| 704 | } | ||
| 705 | /* Else check for TiPb 400 & 500 */ | ||
| 706 | else if (machine_is_compatible("PowerBook3,2")) { | ||
| 707 | /* We only know about the 400 MHz and the 500Mhz model | ||
| 708 | * they both have 300 MHz as low frequency | ||
| 709 | */ | ||
| 710 | if (cur_freq < 350000 || cur_freq > 550000) | ||
| 711 | goto out; | ||
| 712 | hi_freq = cur_freq; | ||
| 713 | low_freq = 300000; | ||
| 714 | set_speed_proc = pmu_set_cpu_speed; | ||
| 715 | is_pmu_based = 1; | ||
| 716 | } | ||
| 717 | /* Else check for 750FX */ | ||
| 718 | else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000) | ||
| 719 | pmac_cpufreq_init_750FX(cpunode); | ||
| 720 | out: | ||
| 721 | if (set_speed_proc == NULL) | ||
| 722 | return -ENODEV; | ||
| 723 | |||
| 724 | pmac_cpu_freqs[CPUFREQ_LOW].frequency = low_freq; | ||
| 725 | pmac_cpu_freqs[CPUFREQ_HIGH].frequency = hi_freq; | ||
| 726 | |||
| 727 | printk(KERN_INFO "Registering PowerMac CPU frequency driver\n"); | ||
| 728 | printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz\n", | ||
| 729 | low_freq/1000, hi_freq/1000, cur_freq/1000); | ||
| 730 | |||
| 731 | return cpufreq_register_driver(&pmac_cpufreq_driver); | ||
| 732 | } | ||
| 733 | |||
| 734 | module_init(pmac_cpufreq_setup); | ||
| 735 | |||
diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c deleted file mode 100644 index 6b7b3a150631..000000000000 --- a/arch/ppc/platforms/pmac_feature.c +++ /dev/null | |||
| @@ -1,3023 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * arch/ppc/platforms/pmac_feature.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 1996-2001 Paul Mackerras (paulus@cs.anu.edu.au) | ||
| 5 | * Ben. Herrenschmidt (benh@kernel.crashing.org) | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * as published by the Free Software Foundation; either version | ||
| 10 | * 2 of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | * TODO: | ||
| 13 | * | ||
| 14 | * - Replace mdelay with some schedule loop if possible | ||
| 15 | * - Shorten some obfuscated delays on some routines (like modem | ||
| 16 | * power) | ||
| 17 | * - Refcount some clocks (see darwin) | ||
| 18 | * - Split split split... | ||
| 19 | * | ||
| 20 | */ | ||
| 21 | #include <linux/config.h> | ||
| 22 | #include <linux/types.h> | ||
| 23 | #include <linux/init.h> | ||
| 24 | #include <linux/delay.h> | ||
| 25 | #include <linux/kernel.h> | ||
| 26 | #include <linux/sched.h> | ||
| 27 | #include <linux/spinlock.h> | ||
| 28 | #include <linux/adb.h> | ||
| 29 | #include <linux/pmu.h> | ||
| 30 | #include <linux/ioport.h> | ||
| 31 | #include <linux/pci.h> | ||
| 32 | #include <asm/sections.h> | ||
| 33 | #include <asm/errno.h> | ||
| 34 | #include <asm/ohare.h> | ||
| 35 | #include <asm/heathrow.h> | ||
| 36 | #include <asm/keylargo.h> | ||
| 37 | #include <asm/uninorth.h> | ||
| 38 | #include <asm/io.h> | ||
| 39 | #include <asm/prom.h> | ||
| 40 | #include <asm/machdep.h> | ||
| 41 | #include <asm/pmac_feature.h> | ||
| 42 | #include <asm/dbdma.h> | ||
| 43 | #include <asm/pci-bridge.h> | ||
| 44 | #include <asm/pmac_low_i2c.h> | ||
| 45 | |||
| 46 | #undef DEBUG_FEATURE | ||
| 47 | |||
| 48 | #ifdef DEBUG_FEATURE | ||
| 49 | #define DBG(fmt,...) printk(KERN_DEBUG fmt) | ||
| 50 | #else | ||
| 51 | #define DBG(fmt,...) | ||
| 52 | #endif | ||
| 53 | |||
| 54 | #ifdef CONFIG_6xx | ||
| 55 | extern int powersave_lowspeed; | ||
| 56 | #endif | ||
| 57 | |||
| 58 | extern int powersave_nap; | ||
| 59 | extern struct device_node *k2_skiplist[2]; | ||
| 60 | |||
| 61 | |||
| 62 | /* | ||
| 63 | * We use a single global lock to protect accesses. Each driver has | ||
| 64 | * to take care of its own locking | ||
| 65 | */ | ||
| 66 | static DEFINE_SPINLOCK(feature_lock); | ||
| 67 | |||
| 68 | #define LOCK(flags) spin_lock_irqsave(&feature_lock, flags); | ||
| 69 | #define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags); | ||
| 70 | |||
| 71 | |||
| 72 | /* | ||
| 73 | * Instance of some macio stuffs | ||
| 74 | */ | ||
| 75 | struct macio_chip macio_chips[MAX_MACIO_CHIPS]; | ||
| 76 | |||
| 77 | struct macio_chip* macio_find(struct device_node* child, int type) | ||
| 78 | { | ||
| 79 | while(child) { | ||
| 80 | int i; | ||
| 81 | |||
| 82 | for (i=0; i < MAX_MACIO_CHIPS && macio_chips[i].of_node; i++) | ||
| 83 | if (child == macio_chips[i].of_node && | ||
| 84 | (!type || macio_chips[i].type == type)) | ||
| 85 | return &macio_chips[i]; | ||
| 86 | child = child->parent; | ||
| 87 | } | ||
| 88 | return NULL; | ||
| 89 | } | ||
| 90 | EXPORT_SYMBOL_GPL(macio_find); | ||
| 91 | |||
| 92 | static const char* macio_names[] = | ||
| 93 | { | ||
| 94 | "Unknown", | ||
| 95 | "Grand Central", | ||
| 96 | "OHare", | ||
| 97 | "OHareII", | ||
| 98 | "Heathrow", | ||
| 99 | "Gatwick", | ||
| 100 | "Paddington", | ||
| 101 | "Keylargo", | ||
| 102 | "Pangea", | ||
| 103 | "Intrepid", | ||
| 104 | "K2" | ||
| 105 | }; | ||
| 106 | |||
| 107 | |||
| 108 | |||
| 109 | /* | ||
| 110 | * Uninorth reg. access. Note that Uni-N regs are big endian | ||
| 111 | */ | ||
| 112 | |||
| 113 | #define UN_REG(r) (uninorth_base + ((r) >> 2)) | ||
| 114 | #define UN_IN(r) (in_be32(UN_REG(r))) | ||
| 115 | #define UN_OUT(r,v) (out_be32(UN_REG(r), (v))) | ||
| 116 | #define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v))) | ||
| 117 | #define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v))) | ||
| 118 | |||
| 119 | static struct device_node* uninorth_node; | ||
| 120 | static u32 __iomem * uninorth_base; | ||
| 121 | static u32 uninorth_rev; | ||
| 122 | static int uninorth_u3; | ||
| 123 | static void __iomem *u3_ht; | ||
| 124 | |||
| 125 | /* | ||
| 126 | * For each motherboard family, we have a table of functions pointers | ||
| 127 | * that handle the various features. | ||
| 128 | */ | ||
| 129 | |||
| 130 | typedef long (*feature_call)(struct device_node* node, long param, long value); | ||
| 131 | |||
| 132 | struct feature_table_entry { | ||
| 133 | unsigned int selector; | ||
| 134 | feature_call function; | ||
| 135 | }; | ||
| 136 | |||
| 137 | struct pmac_mb_def | ||
| 138 | { | ||
| 139 | const char* model_string; | ||
| 140 | const char* model_name; | ||
| 141 | int model_id; | ||
| 142 | struct feature_table_entry* features; | ||
| 143 | unsigned long board_flags; | ||
| 144 | }; | ||
| 145 | static struct pmac_mb_def pmac_mb; | ||
| 146 | |||
| 147 | /* | ||
| 148 | * Here are the chip specific feature functions | ||
| 149 | */ | ||
| 150 | |||
| 151 | static inline int | ||
| 152 | simple_feature_tweak(struct device_node* node, int type, int reg, u32 mask, int value) | ||
| 153 | { | ||
| 154 | struct macio_chip* macio; | ||
| 155 | unsigned long flags; | ||
| 156 | |||
| 157 | macio = macio_find(node, type); | ||
| 158 | if (!macio) | ||
| 159 | return -ENODEV; | ||
| 160 | LOCK(flags); | ||
| 161 | if (value) | ||
| 162 | MACIO_BIS(reg, mask); | ||
| 163 | else | ||
| 164 | MACIO_BIC(reg, mask); | ||
| 165 | (void)MACIO_IN32(reg); | ||
| 166 | UNLOCK(flags); | ||
| 167 | |||
| 168 | return 0; | ||
| 169 | } | ||
| 170 | |||
| 171 | #ifndef CONFIG_POWER4 | ||
| 172 | |||
| 173 | static long | ||
| 174 | ohare_htw_scc_enable(struct device_node* node, long param, long value) | ||
| 175 | { | ||
| 176 | struct macio_chip* macio; | ||
| 177 | unsigned long chan_mask; | ||
| 178 | unsigned long fcr; | ||
| 179 | unsigned long flags; | ||
| 180 | int htw, trans; | ||
| 181 | unsigned long rmask; | ||
| 182 | |||
| 183 | macio = macio_find(node, 0); | ||
| 184 | if (!macio) | ||
| 185 | return -ENODEV; | ||
| 186 | if (!strcmp(node->name, "ch-a")) | ||
| 187 | chan_mask = MACIO_FLAG_SCCA_ON; | ||
| 188 | else if (!strcmp(node->name, "ch-b")) | ||
| 189 | chan_mask = MACIO_FLAG_SCCB_ON; | ||
| 190 | else | ||
| 191 | return -ENODEV; | ||
| 192 | |||
| 193 | htw = (macio->type == macio_heathrow || macio->type == macio_paddington | ||
| 194 | || macio->type == macio_gatwick); | ||
| 195 | /* On these machines, the HRW_SCC_TRANS_EN_N bit mustn't be touched */ | ||
| 196 | trans = (pmac_mb.model_id != PMAC_TYPE_YOSEMITE && | ||
| 197 | pmac_mb.model_id != PMAC_TYPE_YIKES); | ||
| 198 | if (value) { | ||
| 199 | #ifdef CONFIG_ADB_PMU | ||
| 200 | if ((param & 0xfff) == PMAC_SCC_IRDA) | ||
| 201 | pmu_enable_irled(1); | ||
| 202 | #endif /* CONFIG_ADB_PMU */ | ||
| 203 | LOCK(flags); | ||
| 204 | fcr = MACIO_IN32(OHARE_FCR); | ||
| 205 | /* Check if scc cell need enabling */ | ||
| 206 | if (!(fcr & OH_SCC_ENABLE)) { | ||
| 207 | fcr |= OH_SCC_ENABLE; | ||
| 208 | if (htw) { | ||
| 209 | /* Side effect: this will also power up the | ||
| 210 | * modem, but it's too messy to figure out on which | ||
| 211 | * ports this controls the tranceiver and on which | ||
| 212 | * it controls the modem | ||
| 213 | */ | ||
| 214 | if (trans) | ||
| 215 | fcr &= ~HRW_SCC_TRANS_EN_N; | ||
| 216 | MACIO_OUT32(OHARE_FCR, fcr); | ||
| 217 | fcr |= (rmask = HRW_RESET_SCC); | ||
| 218 | MACIO_OUT32(OHARE_FCR, fcr); | ||
| 219 | } else { | ||
| 220 | fcr |= (rmask = OH_SCC_RESET); | ||
| 221 | MACIO_OUT32(OHARE_FCR, fcr); | ||
| 222 | } | ||
| 223 | UNLOCK(flags); | ||
| 224 | (void)MACIO_IN32(OHARE_FCR); | ||
| 225 | mdelay(15); | ||
| 226 | LOCK(flags); | ||
| 227 | fcr &= ~rmask; | ||
| 228 | MACIO_OUT32(OHARE_FCR, fcr); | ||
| 229 | } | ||
| 230 | if (chan_mask & MACIO_FLAG_SCCA_ON) | ||
| 231 | fcr |= OH_SCCA_IO; | ||
| 232 | if (chan_mask & MACIO_FLAG_SCCB_ON) | ||
| 233 | fcr |= OH_SCCB_IO; | ||
| 234 | MACIO_OUT32(OHARE_FCR, fcr); | ||
| 235 | macio->flags |= chan_mask; | ||
| 236 | UNLOCK(flags); | ||
| 237 | if (param & PMAC_SCC_FLAG_XMON) | ||
| 238 | macio->flags |= MACIO_FLAG_SCC_LOCKED; | ||
| 239 | } else { | ||
| 240 | if (macio->flags & MACIO_FLAG_SCC_LOCKED) | ||
| 241 | return -EPERM; | ||
| 242 | LOCK(flags); | ||
| 243 | fcr = MACIO_IN32(OHARE_FCR); | ||
| 244 | if (chan_mask & MACIO_FLAG_SCCA_ON) | ||
| 245 | fcr &= ~OH_SCCA_IO; | ||
| 246 | if (chan_mask & MACIO_FLAG_SCCB_ON) | ||
| 247 | fcr &= ~OH_SCCB_IO; | ||
| 248 | MACIO_OUT32(OHARE_FCR, fcr); | ||
| 249 | if ((fcr & (OH_SCCA_IO | OH_SCCB_IO)) == 0) { | ||
| 250 | fcr &= ~OH_SCC_ENABLE; | ||
| 251 | if (htw && trans) | ||
| 252 | fcr |= HRW_SCC_TRANS_EN_N; | ||
| 253 | MACIO_OUT32(OHARE_FCR, fcr); | ||
| 254 | } | ||
| 255 | macio->flags &= ~(chan_mask); | ||
| 256 | UNLOCK(flags); | ||
| 257 | mdelay(10); | ||
| 258 | #ifdef CONFIG_ADB_PMU | ||
| 259 | if ((param & 0xfff) == PMAC_SCC_IRDA) | ||
| 260 | pmu_enable_irled(0); | ||
| 261 | #endif /* CONFIG_ADB_PMU */ | ||
| 262 | } | ||
| 263 | return 0; | ||
| 264 | } | ||
| 265 | |||
| 266 | static long | ||
| 267 | ohare_floppy_enable(struct device_node* node, long param, long value) | ||
| 268 | { | ||
| 269 | return simple_feature_tweak(node, macio_ohare, | ||
| 270 | OHARE_FCR, OH_FLOPPY_ENABLE, value); | ||
| 271 | } | ||
| 272 | |||
| 273 | static long | ||
| 274 | ohare_mesh_enable(struct device_node* node, long param, long value) | ||
| 275 | { | ||
| 276 | return simple_feature_tweak(node, macio_ohare, | ||
| 277 | OHARE_FCR, OH_MESH_ENABLE, value); | ||
| 278 | } | ||
| 279 | |||
| 280 | static long | ||
| 281 | ohare_ide_enable(struct device_node* node, long param, long value) | ||
| 282 | { | ||
| 283 | switch(param) { | ||
| 284 | case 0: | ||
| 285 | /* For some reason, setting the bit in set_initial_features() | ||
| 286 | * doesn't stick. I'm still investigating... --BenH. | ||
| 287 | */ | ||
| 288 | if (value) | ||
| 289 | simple_feature_tweak(node, macio_ohare, | ||
| 290 | OHARE_FCR, OH_IOBUS_ENABLE, 1); | ||
| 291 | return simple_feature_tweak(node, macio_ohare, | ||
| 292 | OHARE_FCR, OH_IDE0_ENABLE, value); | ||
| 293 | case 1: | ||
| 294 | return simple_feature_tweak(node, macio_ohare, | ||
| 295 | OHARE_FCR, OH_BAY_IDE_ENABLE, value); | ||
| 296 | default: | ||
| 297 | return -ENODEV; | ||
| 298 | } | ||
| 299 | } | ||
| 300 | |||
| 301 | static long | ||
| 302 | ohare_ide_reset(struct device_node* node, long param, long value) | ||
| 303 | { | ||
| 304 | switch(param) { | ||
| 305 | case 0: | ||
| 306 | return simple_feature_tweak(node, macio_ohare, | ||
| 307 | OHARE_FCR, OH_IDE0_RESET_N, !value); | ||
| 308 | case 1: | ||
| 309 | return simple_feature_tweak(node, macio_ohare, | ||
| 310 | OHARE_FCR, OH_IDE1_RESET_N, !value); | ||
| 311 | default: | ||
| 312 | return -ENODEV; | ||
| 313 | } | ||
| 314 | } | ||
| 315 | |||
| 316 | static long | ||
| 317 | ohare_sleep_state(struct device_node* node, long param, long value) | ||
| 318 | { | ||
| 319 | struct macio_chip* macio = &macio_chips[0]; | ||
| 320 | |||
| 321 | if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0) | ||
| 322 | return -EPERM; | ||
| 323 | if (value == 1) { | ||
| 324 | MACIO_BIC(OHARE_FCR, OH_IOBUS_ENABLE); | ||
| 325 | } else if (value == 0) { | ||
| 326 | MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE); | ||
| 327 | } | ||
| 328 | |||
| 329 | return 0; | ||
| 330 | } | ||
| 331 | |||
| 332 | static long | ||
| 333 | heathrow_modem_enable(struct device_node* node, long param, long value) | ||
| 334 | { | ||
| 335 | struct macio_chip* macio; | ||
| 336 | u8 gpio; | ||
| 337 | unsigned long flags; | ||
| 338 | |||
| 339 | macio = macio_find(node, macio_unknown); | ||
| 340 | if (!macio) | ||
| 341 | return -ENODEV; | ||
| 342 | gpio = MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1; | ||
| 343 | if (!value) { | ||
| 344 | LOCK(flags); | ||
| 345 | MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio); | ||
| 346 | UNLOCK(flags); | ||
| 347 | (void)MACIO_IN8(HRW_GPIO_MODEM_RESET); | ||
| 348 | mdelay(250); | ||
| 349 | } | ||
| 350 | if (pmac_mb.model_id != PMAC_TYPE_YOSEMITE && | ||
| 351 | pmac_mb.model_id != PMAC_TYPE_YIKES) { | ||
| 352 | LOCK(flags); | ||
| 353 | if (value) | ||
| 354 | MACIO_BIC(HEATHROW_FCR, HRW_SCC_TRANS_EN_N); | ||
| 355 | else | ||
| 356 | MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N); | ||
| 357 | UNLOCK(flags); | ||
| 358 | (void)MACIO_IN32(HEATHROW_FCR); | ||
| 359 | mdelay(250); | ||
| 360 | } | ||
| 361 | if (value) { | ||
| 362 | LOCK(flags); | ||
| 363 | MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1); | ||
| 364 | (void)MACIO_IN8(HRW_GPIO_MODEM_RESET); | ||
| 365 | UNLOCK(flags); mdelay(250); LOCK(flags); | ||
| 366 | MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio); | ||
| 367 | (void)MACIO_IN8(HRW_GPIO_MODEM_RESET); | ||
| 368 | UNLOCK(flags); mdelay(250); LOCK(flags); | ||
| 369 | MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1); | ||
| 370 | (void)MACIO_IN8(HRW_GPIO_MODEM_RESET); | ||
| 371 | UNLOCK(flags); mdelay(250); | ||
| 372 | } | ||
| 373 | return 0; | ||
| 374 | } | ||
| 375 | |||
| 376 | static long | ||
| 377 | heathrow_floppy_enable(struct device_node* node, long param, long value) | ||
| 378 | { | ||
| 379 | return simple_feature_tweak(node, macio_unknown, | ||
| 380 | HEATHROW_FCR, | ||
| 381 | HRW_SWIM_ENABLE|HRW_BAY_FLOPPY_ENABLE, | ||
| 382 | value); | ||
| 383 | } | ||
| 384 | |||
| 385 | static long | ||
| 386 | heathrow_mesh_enable(struct device_node* node, long param, long value) | ||
| 387 | { | ||
| 388 | struct macio_chip* macio; | ||
| 389 | unsigned long flags; | ||
| 390 | |||
| 391 | macio = macio_find(node, macio_unknown); | ||
| 392 | if (!macio) | ||
| 393 | return -ENODEV; | ||
| 394 | LOCK(flags); | ||
| 395 | /* Set clear mesh cell enable */ | ||
| 396 | if (value) | ||
| 397 | MACIO_BIS(HEATHROW_FCR, HRW_MESH_ENABLE); | ||
| 398 | else | ||
| 399 | MACIO_BIC(HEATHROW_FCR, HRW_MESH_ENABLE); | ||
| 400 | (void)MACIO_IN32(HEATHROW_FCR); | ||
| 401 | udelay(10); | ||
| 402 | /* Set/Clear termination power */ | ||
| 403 | if (value) | ||
| 404 | MACIO_BIC(HEATHROW_MBCR, 0x04000000); | ||
| 405 | else | ||
| 406 | MACIO_BIS(HEATHROW_MBCR, 0x04000000); | ||
| 407 | (void)MACIO_IN32(HEATHROW_MBCR); | ||
| 408 | udelay(10); | ||
| 409 | UNLOCK(flags); | ||
| 410 | |||
| 411 | return 0; | ||
| 412 | } | ||
| 413 | |||
| 414 | static long | ||
| 415 | heathrow_ide_enable(struct device_node* node, long param, long value) | ||
| 416 | { | ||
| 417 | switch(param) { | ||
| 418 | case 0: | ||
| 419 | return simple_feature_tweak(node, macio_unknown, | ||
| 420 | HEATHROW_FCR, HRW_IDE0_ENABLE, value); | ||
| 421 | case 1: | ||
| 422 | return simple_feature_tweak(node, macio_unknown, | ||
| 423 | HEATHROW_FCR, HRW_BAY_IDE_ENABLE, value); | ||
| 424 | default: | ||
| 425 | return -ENODEV; | ||
| 426 | } | ||
| 427 | } | ||
| 428 | |||
| 429 | static long | ||
| 430 | heathrow_ide_reset(struct device_node* node, long param, long value) | ||
| 431 | { | ||
| 432 | switch(param) { | ||
| 433 | case 0: | ||
| 434 | return simple_feature_tweak(node, macio_unknown, | ||
| 435 | HEATHROW_FCR, HRW_IDE0_RESET_N, !value); | ||
| 436 | case 1: | ||
| 437 | return simple_feature_tweak(node, macio_unknown, | ||
| 438 | HEATHROW_FCR, HRW_IDE1_RESET_N, !value); | ||
| 439 | default: | ||
| 440 | return -ENODEV; | ||
| 441 | } | ||
| 442 | } | ||
| 443 | |||
| 444 | static long | ||
| 445 | heathrow_bmac_enable(struct device_node* node, long param, long value) | ||
| 446 | { | ||
| 447 | struct macio_chip* macio; | ||
| 448 | unsigned long flags; | ||
| 449 | |||
| 450 | macio = macio_find(node, 0); | ||
| 451 | if (!macio) | ||
| 452 | return -ENODEV; | ||
| 453 | if (value) { | ||
| 454 | LOCK(flags); | ||
| 455 | MACIO_BIS(HEATHROW_FCR, HRW_BMAC_IO_ENABLE); | ||
| 456 | MACIO_BIS(HEATHROW_FCR, HRW_BMAC_RESET); | ||
| 457 | UNLOCK(flags); | ||
| 458 | (void)MACIO_IN32(HEATHROW_FCR); | ||
| 459 | mdelay(10); | ||
| 460 | LOCK(flags); | ||
| 461 | MACIO_BIC(HEATHROW_FCR, HRW_BMAC_RESET); | ||
| 462 | UNLOCK(flags); | ||
| 463 | (void)MACIO_IN32(HEATHROW_FCR); | ||
| 464 | mdelay(10); | ||
| 465 | } else { | ||
| 466 | LOCK(flags); | ||
| 467 | MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE); | ||
| 468 | UNLOCK(flags); | ||
| 469 | } | ||
| 470 | return 0; | ||
| 471 | } | ||
| 472 | |||
| 473 | static long | ||
| 474 | heathrow_sound_enable(struct device_node* node, long param, long value) | ||
| 475 | { | ||
| 476 | struct macio_chip* macio; | ||
| 477 | unsigned long flags; | ||
| 478 | |||
| 479 | /* B&W G3 and Yikes don't support that properly (the | ||
| 480 | * sound appear to never come back after beeing shut down). | ||
| 481 | */ | ||
| 482 | if (pmac_mb.model_id == PMAC_TYPE_YOSEMITE || | ||
| 483 | pmac_mb.model_id == PMAC_TYPE_YIKES) | ||
| 484 | return 0; | ||
| 485 | |||
| 486 | macio = macio_find(node, 0); | ||
| 487 | if (!macio) | ||
| 488 | return -ENODEV; | ||
| 489 | if (value) { | ||
| 490 | LOCK(flags); | ||
| 491 | MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE); | ||
| 492 | MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N); | ||
| 493 | UNLOCK(flags); | ||
| 494 | (void)MACIO_IN32(HEATHROW_FCR); | ||
| 495 | } else { | ||
| 496 | LOCK(flags); | ||
| 497 | MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N); | ||
| 498 | MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE); | ||
| 499 | UNLOCK(flags); | ||
| 500 | } | ||
| 501 | return 0; | ||
| 502 | } | ||
| 503 | |||
| 504 | static u32 save_fcr[6]; | ||
| 505 | static u32 save_mbcr; | ||
| 506 | static u32 save_gpio_levels[2]; | ||
| 507 | static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT]; | ||
| 508 | static u8 save_gpio_normal[KEYLARGO_GPIO_CNT]; | ||
| 509 | static u32 save_unin_clock_ctl; | ||
| 510 | static struct dbdma_regs save_dbdma[13]; | ||
| 511 | static struct dbdma_regs save_alt_dbdma[13]; | ||
| 512 | |||
| 513 | static void | ||
| 514 | dbdma_save(struct macio_chip* macio, struct dbdma_regs* save) | ||
| 515 | { | ||
| 516 | int i; | ||
| 517 | |||
| 518 | /* Save state & config of DBDMA channels */ | ||
| 519 | for (i=0; i<13; i++) { | ||
| 520 | volatile struct dbdma_regs __iomem * chan = (void __iomem *) | ||
| 521 | (macio->base + ((0x8000+i*0x100)>>2)); | ||
| 522 | save[i].cmdptr_hi = in_le32(&chan->cmdptr_hi); | ||
| 523 | save[i].cmdptr = in_le32(&chan->cmdptr); | ||
| 524 | save[i].intr_sel = in_le32(&chan->intr_sel); | ||
| 525 | save[i].br_sel = in_le32(&chan->br_sel); | ||
| 526 | save[i].wait_sel = in_le32(&chan->wait_sel); | ||
| 527 | } | ||
| 528 | } | ||
| 529 | |||
| 530 | static void | ||
| 531 | dbdma_restore(struct macio_chip* macio, struct dbdma_regs* save) | ||
| 532 | { | ||
| 533 | int i; | ||
| 534 | |||
| 535 | /* Save state & config of DBDMA channels */ | ||
| 536 | for (i=0; i<13; i++) { | ||
| 537 | volatile struct dbdma_regs __iomem * chan = (void __iomem *) | ||
| 538 | (macio->base + ((0x8000+i*0x100)>>2)); | ||
| 539 | out_le32(&chan->control, (ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN)<<16); | ||
| 540 | while (in_le32(&chan->status) & ACTIVE) | ||
| 541 | mb(); | ||
| 542 | out_le32(&chan->cmdptr_hi, save[i].cmdptr_hi); | ||
| 543 | out_le32(&chan->cmdptr, save[i].cmdptr); | ||
| 544 | out_le32(&chan->intr_sel, save[i].intr_sel); | ||
| 545 | out_le32(&chan->br_sel, save[i].br_sel); | ||
| 546 | out_le32(&chan->wait_sel, save[i].wait_sel); | ||
| 547 | } | ||
| 548 | } | ||
| 549 | |||
| 550 | static void | ||
| 551 | heathrow_sleep(struct macio_chip* macio, int secondary) | ||
| 552 | { | ||
| 553 | if (secondary) { | ||
| 554 | dbdma_save(macio, save_alt_dbdma); | ||
| 555 | save_fcr[2] = MACIO_IN32(0x38); | ||
| 556 | save_fcr[3] = MACIO_IN32(0x3c); | ||
| 557 | } else { | ||
| 558 | dbdma_save(macio, save_dbdma); | ||
| 559 | save_fcr[0] = MACIO_IN32(0x38); | ||
| 560 | save_fcr[1] = MACIO_IN32(0x3c); | ||
| 561 | save_mbcr = MACIO_IN32(0x34); | ||
| 562 | /* Make sure sound is shut down */ | ||
| 563 | MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N); | ||
| 564 | MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE); | ||
| 565 | /* This seems to be necessary as well or the fan | ||
| 566 | * keeps coming up and battery drains fast */ | ||
| 567 | MACIO_BIC(HEATHROW_FCR, HRW_IOBUS_ENABLE); | ||
| 568 | MACIO_BIC(HEATHROW_FCR, HRW_IDE0_RESET_N); | ||
| 569 | /* Make sure eth is down even if module or sleep | ||
| 570 | * won't work properly */ | ||
| 571 | MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE | HRW_BMAC_RESET); | ||
| 572 | } | ||
| 573 | /* Make sure modem is shut down */ | ||
| 574 | MACIO_OUT8(HRW_GPIO_MODEM_RESET, | ||
| 575 | MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1); | ||
| 576 | MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N); | ||
| 577 | MACIO_BIC(HEATHROW_FCR, OH_SCCA_IO|OH_SCCB_IO|HRW_SCC_ENABLE); | ||
| 578 | |||
| 579 | /* Let things settle */ | ||
| 580 | (void)MACIO_IN32(HEATHROW_FCR); | ||
| 581 | } | ||
| 582 | |||
| 583 | static void | ||
| 584 | heathrow_wakeup(struct macio_chip* macio, int secondary) | ||
| 585 | { | ||
| 586 | if (secondary) { | ||
| 587 | MACIO_OUT32(0x38, save_fcr[2]); | ||
| 588 | (void)MACIO_IN32(0x38); | ||
| 589 | mdelay(1); | ||
| 590 | MACIO_OUT32(0x3c, save_fcr[3]); | ||
| 591 | (void)MACIO_IN32(0x38); | ||
| 592 | mdelay(10); | ||
| 593 | dbdma_restore(macio, save_alt_dbdma); | ||
| 594 | } else { | ||
| 595 | MACIO_OUT32(0x38, save_fcr[0] | HRW_IOBUS_ENABLE); | ||
| 596 | (void)MACIO_IN32(0x38); | ||
| 597 | mdelay(1); | ||
| 598 | MACIO_OUT32(0x3c, save_fcr[1]); | ||
| 599 | (void)MACIO_IN32(0x38); | ||
| 600 | mdelay(1); | ||
| 601 | MACIO_OUT32(0x34, save_mbcr); | ||
| 602 | (void)MACIO_IN32(0x38); | ||
| 603 | mdelay(10); | ||
| 604 | dbdma_restore(macio, save_dbdma); | ||
| 605 | } | ||
| 606 | } | ||
| 607 | |||
| 608 | static long | ||
| 609 | heathrow_sleep_state(struct device_node* node, long param, long value) | ||
| 610 | { | ||
| 611 | if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0) | ||
| 612 | return -EPERM; | ||
| 613 | if (value == 1) { | ||
| 614 | if (macio_chips[1].type == macio_gatwick) | ||
| 615 | heathrow_sleep(&macio_chips[0], 1); | ||
| 616 | heathrow_sleep(&macio_chips[0], 0); | ||
| 617 | } else if (value == 0) { | ||
| 618 | heathrow_wakeup(&macio_chips[0], 0); | ||
| 619 | if (macio_chips[1].type == macio_gatwick) | ||
| 620 | heathrow_wakeup(&macio_chips[0], 1); | ||
| 621 | } | ||
| 622 | return 0; | ||
| 623 | } | ||
| 624 | |||
| 625 | static long | ||
| 626 | core99_scc_enable(struct device_node* node, long param, long value) | ||
| 627 | { | ||
| 628 | struct macio_chip* macio; | ||
| 629 | unsigned long flags; | ||
| 630 | unsigned long chan_mask; | ||
| 631 | u32 fcr; | ||
| 632 | |||
| 633 | macio = macio_find(node, 0); | ||
| 634 | if (!macio) | ||
| 635 | return -ENODEV; | ||
| 636 | if (!strcmp(node->name, "ch-a")) | ||
| 637 | chan_mask = MACIO_FLAG_SCCA_ON; | ||
| 638 | else if (!strcmp(node->name, "ch-b")) | ||
| 639 | chan_mask = MACIO_FLAG_SCCB_ON; | ||
| 640 | else | ||
| 641 | return -ENODEV; | ||
| 642 | |||
| 643 | if (value) { | ||
| 644 | int need_reset_scc = 0; | ||
| 645 | int need_reset_irda = 0; | ||
| 646 | |||
| 647 | LOCK(flags); | ||
| 648 | fcr = MACIO_IN32(KEYLARGO_FCR0); | ||
| 649 | /* Check if scc cell need enabling */ | ||
| 650 | if (!(fcr & KL0_SCC_CELL_ENABLE)) { | ||
| 651 | fcr |= KL0_SCC_CELL_ENABLE; | ||
| 652 | need_reset_scc = 1; | ||
| 653 | } | ||
| 654 | if (chan_mask & MACIO_FLAG_SCCA_ON) { | ||
| 655 | fcr |= KL0_SCCA_ENABLE; | ||
| 656 | /* Don't enable line drivers for I2S modem */ | ||
| 657 | if ((param & 0xfff) == PMAC_SCC_I2S1) | ||
| 658 | fcr &= ~KL0_SCC_A_INTF_ENABLE; | ||
| 659 | else | ||
| 660 | fcr |= KL0_SCC_A_INTF_ENABLE; | ||
| 661 | } | ||
| 662 | if (chan_mask & MACIO_FLAG_SCCB_ON) { | ||
| 663 | fcr |= KL0_SCCB_ENABLE; | ||
| 664 | /* Perform irda specific inits */ | ||
| 665 | if ((param & 0xfff) == PMAC_SCC_IRDA) { | ||
| 666 | fcr &= ~KL0_SCC_B_INTF_ENABLE; | ||
| 667 | fcr |= KL0_IRDA_ENABLE; | ||
| 668 | fcr |= KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE; | ||
| 669 | fcr |= KL0_IRDA_SOURCE1_SEL; | ||
| 670 | fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0); | ||
| 671 | fcr &= ~(KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND); | ||
| 672 | need_reset_irda = 1; | ||
| 673 | } else | ||
| 674 | fcr |= KL0_SCC_B_INTF_ENABLE; | ||
| 675 | } | ||
| 676 | MACIO_OUT32(KEYLARGO_FCR0, fcr); | ||
| 677 | macio->flags |= chan_mask; | ||
| 678 | if (need_reset_scc) { | ||
| 679 | MACIO_BIS(KEYLARGO_FCR0, KL0_SCC_RESET); | ||
| 680 | (void)MACIO_IN32(KEYLARGO_FCR0); | ||
| 681 | UNLOCK(flags); | ||
| 682 | mdelay(15); | ||
| 683 | LOCK(flags); | ||
| 684 | MACIO_BIC(KEYLARGO_FCR0, KL0_SCC_RESET); | ||
| 685 | } | ||
| 686 | if (need_reset_irda) { | ||
| 687 | MACIO_BIS(KEYLARGO_FCR0, KL0_IRDA_RESET); | ||
| 688 | (void)MACIO_IN32(KEYLARGO_FCR0); | ||
| 689 | UNLOCK(flags); | ||
| 690 | mdelay(15); | ||
| 691 | LOCK(flags); | ||
| 692 | MACIO_BIC(KEYLARGO_FCR0, KL0_IRDA_RESET); | ||
| 693 | } | ||
| 694 | UNLOCK(flags); | ||
| 695 | if (param & PMAC_SCC_FLAG_XMON) | ||
| 696 | macio->flags |= MACIO_FLAG_SCC_LOCKED; | ||
| 697 | } else { | ||
| 698 | if (macio->flags & MACIO_FLAG_SCC_LOCKED) | ||
| 699 | return -EPERM; | ||
| 700 | LOCK(flags); | ||
| 701 | fcr = MACIO_IN32(KEYLARGO_FCR0); | ||
| 702 | if (chan_mask & MACIO_FLAG_SCCA_ON) | ||
| 703 | fcr &= ~KL0_SCCA_ENABLE; | ||
| 704 | if (chan_mask & MACIO_FLAG_SCCB_ON) { | ||
| 705 | fcr &= ~KL0_SCCB_ENABLE; | ||
| 706 | /* Perform irda specific clears */ | ||
| 707 | if ((param & 0xfff) == PMAC_SCC_IRDA) { | ||
| 708 | fcr &= ~KL0_IRDA_ENABLE; | ||
| 709 | fcr &= ~(KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE); | ||
| 710 | fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0); | ||
| 711 | fcr &= ~(KL0_IRDA_SOURCE1_SEL|KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND); | ||
| 712 | } | ||
| 713 | } | ||
| 714 | MACIO_OUT32(KEYLARGO_FCR0, fcr); | ||
| 715 | if ((fcr & (KL0_SCCA_ENABLE | KL0_SCCB_ENABLE)) == 0) { | ||
| 716 | fcr &= ~KL0_SCC_CELL_ENABLE; | ||
| 717 | MACIO_OUT32(KEYLARGO_FCR0, fcr); | ||
| 718 | } | ||
| 719 | macio->flags &= ~(chan_mask); | ||
| 720 | UNLOCK(flags); | ||
| 721 | mdelay(10); | ||
| 722 | } | ||
| 723 | return 0; | ||
| 724 | } | ||
| 725 | |||
| 726 | static long | ||
| 727 | core99_modem_enable(struct device_node* node, long param, long value) | ||
| 728 | { | ||
| 729 | struct macio_chip* macio; | ||
| 730 | u8 gpio; | ||
| 731 | unsigned long flags; | ||
| 732 | |||
| 733 | /* Hack for internal USB modem */ | ||
| 734 | if (node == NULL) { | ||
| 735 | if (macio_chips[0].type != macio_keylargo) | ||
| 736 | return -ENODEV; | ||
| 737 | node = macio_chips[0].of_node; | ||
| 738 | } | ||
| 739 | macio = macio_find(node, 0); | ||
| 740 | if (!macio) | ||
| 741 | return -ENODEV; | ||
| 742 | gpio = MACIO_IN8(KL_GPIO_MODEM_RESET); | ||
| 743 | gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE; | ||
| 744 | gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA; | ||
| 745 | |||
| 746 | if (!value) { | ||
| 747 | LOCK(flags); | ||
| 748 | MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); | ||
| 749 | UNLOCK(flags); | ||
| 750 | (void)MACIO_IN8(KL_GPIO_MODEM_RESET); | ||
| 751 | mdelay(250); | ||
| 752 | } | ||
| 753 | LOCK(flags); | ||
| 754 | if (value) { | ||
| 755 | MACIO_BIC(KEYLARGO_FCR2, KL2_ALT_DATA_OUT); | ||
| 756 | UNLOCK(flags); | ||
| 757 | (void)MACIO_IN32(KEYLARGO_FCR2); | ||
| 758 | mdelay(250); | ||
| 759 | } else { | ||
| 760 | MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT); | ||
| 761 | UNLOCK(flags); | ||
| 762 | } | ||
| 763 | if (value) { | ||
| 764 | LOCK(flags); | ||
| 765 | MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA); | ||
| 766 | (void)MACIO_IN8(KL_GPIO_MODEM_RESET); | ||
| 767 | UNLOCK(flags); mdelay(250); LOCK(flags); | ||
| 768 | MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); | ||
| 769 | (void)MACIO_IN8(KL_GPIO_MODEM_RESET); | ||
| 770 | UNLOCK(flags); mdelay(250); LOCK(flags); | ||
| 771 | MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA); | ||
| 772 | (void)MACIO_IN8(KL_GPIO_MODEM_RESET); | ||
| 773 | UNLOCK(flags); mdelay(250); | ||
| 774 | } | ||
| 775 | return 0; | ||
| 776 | } | ||
| 777 | |||
| 778 | static long | ||
| 779 | pangea_modem_enable(struct device_node* node, long param, long value) | ||
| 780 | { | ||
| 781 | struct macio_chip* macio; | ||
| 782 | u8 gpio; | ||
| 783 | unsigned long flags; | ||
| 784 | |||
| 785 | /* Hack for internal USB modem */ | ||
| 786 | if (node == NULL) { | ||
| 787 | if (macio_chips[0].type != macio_pangea && | ||
| 788 | macio_chips[0].type != macio_intrepid) | ||
| 789 | return -ENODEV; | ||
| 790 | node = macio_chips[0].of_node; | ||
| 791 | } | ||
| 792 | macio = macio_find(node, 0); | ||
| 793 | if (!macio) | ||
| 794 | return -ENODEV; | ||
| 795 | gpio = MACIO_IN8(KL_GPIO_MODEM_RESET); | ||
| 796 | gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE; | ||
| 797 | gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA; | ||
| 798 | |||
| 799 | if (!value) { | ||
| 800 | LOCK(flags); | ||
| 801 | MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); | ||
| 802 | UNLOCK(flags); | ||
| 803 | (void)MACIO_IN8(KL_GPIO_MODEM_RESET); | ||
| 804 | mdelay(250); | ||
| 805 | } | ||
| 806 | LOCK(flags); | ||
| 807 | if (value) { | ||
| 808 | MACIO_OUT8(KL_GPIO_MODEM_POWER, | ||
| 809 | KEYLARGO_GPIO_OUTPUT_ENABLE); | ||
| 810 | UNLOCK(flags); | ||
| 811 | (void)MACIO_IN32(KEYLARGO_FCR2); | ||
| 812 | mdelay(250); | ||
| 813 | } else { | ||
| 814 | MACIO_OUT8(KL_GPIO_MODEM_POWER, | ||
| 815 | KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA); | ||
| 816 | UNLOCK(flags); | ||
| 817 | } | ||
| 818 | if (value) { | ||
| 819 | LOCK(flags); | ||
| 820 | MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA); | ||
| 821 | (void)MACIO_IN8(KL_GPIO_MODEM_RESET); | ||
| 822 | UNLOCK(flags); mdelay(250); LOCK(flags); | ||
| 823 | MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); | ||
| 824 | (void)MACIO_IN8(KL_GPIO_MODEM_RESET); | ||
| 825 | UNLOCK(flags); mdelay(250); LOCK(flags); | ||
| 826 | MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA); | ||
| 827 | (void)MACIO_IN8(KL_GPIO_MODEM_RESET); | ||
| 828 | UNLOCK(flags); mdelay(250); | ||
| 829 | } | ||
| 830 | return 0; | ||
| 831 | } | ||
| 832 | |||
| 833 | static long | ||
| 834 | core99_ata100_enable(struct device_node* node, long value) | ||
| 835 | { | ||
| 836 | unsigned long flags; | ||
| 837 | struct pci_dev *pdev = NULL; | ||
| 838 | u8 pbus, pid; | ||
| 839 | |||
| 840 | if (uninorth_rev < 0x24) | ||
| 841 | return -ENODEV; | ||
| 842 | |||
| 843 | LOCK(flags); | ||
| 844 | if (value) | ||
| 845 | UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100); | ||
| 846 | else | ||
| 847 | UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100); | ||
| 848 | (void)UN_IN(UNI_N_CLOCK_CNTL); | ||
| 849 | UNLOCK(flags); | ||
| 850 | udelay(20); | ||
| 851 | |||
| 852 | if (value) { | ||
| 853 | if (pci_device_from_OF_node(node, &pbus, &pid) == 0) | ||
| 854 | pdev = pci_find_slot(pbus, pid); | ||
| 855 | if (pdev == NULL) | ||
| 856 | return 0; | ||
| 857 | pci_enable_device(pdev); | ||
| 858 | pci_set_master(pdev); | ||
| 859 | } | ||
| 860 | return 0; | ||
| 861 | } | ||
| 862 | |||
| 863 | static long | ||
| 864 | core99_ide_enable(struct device_node* node, long param, long value) | ||
| 865 | { | ||
| 866 | /* Bus ID 0 to 2 are KeyLargo based IDE, busID 3 is U2 | ||
| 867 | * based ata-100 | ||
| 868 | */ | ||
| 869 | switch(param) { | ||
| 870 | case 0: | ||
| 871 | return simple_feature_tweak(node, macio_unknown, | ||
| 872 | KEYLARGO_FCR1, KL1_EIDE0_ENABLE, value); | ||
| 873 | case 1: | ||
| 874 | return simple_feature_tweak(node, macio_unknown, | ||
| 875 | KEYLARGO_FCR1, KL1_EIDE1_ENABLE, value); | ||
| 876 | case 2: | ||
| 877 | return simple_feature_tweak(node, macio_unknown, | ||
| 878 | KEYLARGO_FCR1, KL1_UIDE_ENABLE, value); | ||
| 879 | case 3: | ||
| 880 | return core99_ata100_enable(node, value); | ||
| 881 | default: | ||
| 882 | return -ENODEV; | ||
| 883 | } | ||
| 884 | } | ||
| 885 | |||
| 886 | static long | ||
| 887 | core99_ide_reset(struct device_node* node, long param, long value) | ||
| 888 | { | ||
| 889 | switch(param) { | ||
| 890 | case 0: | ||
| 891 | return simple_feature_tweak(node, macio_unknown, | ||
| 892 | KEYLARGO_FCR1, KL1_EIDE0_RESET_N, !value); | ||
| 893 | case 1: | ||
| 894 | return simple_feature_tweak(node, macio_unknown, | ||
| 895 | KEYLARGO_FCR1, KL1_EIDE1_RESET_N, !value); | ||
| 896 | case 2: | ||
| 897 | return simple_feature_tweak(node, macio_unknown, | ||
| 898 | KEYLARGO_FCR1, KL1_UIDE_RESET_N, !value); | ||
| 899 | default: | ||
| 900 | return -ENODEV; | ||
| 901 | } | ||
| 902 | } | ||
| 903 | |||
| 904 | static long | ||
| 905 | core99_gmac_enable(struct device_node* node, long param, long value) | ||
| 906 | { | ||
| 907 | unsigned long flags; | ||
| 908 | |||
| 909 | LOCK(flags); | ||
| 910 | if (value) | ||
| 911 | UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC); | ||
| 912 | else | ||
| 913 | UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC); | ||
| 914 | (void)UN_IN(UNI_N_CLOCK_CNTL); | ||
| 915 | UNLOCK(flags); | ||
| 916 | udelay(20); | ||
| 917 | |||
| 918 | return 0; | ||
| 919 | } | ||
| 920 | |||
| 921 | static long | ||
| 922 | core99_gmac_phy_reset(struct device_node* node, long param, long value) | ||
| 923 | { | ||
| 924 | unsigned long flags; | ||
| 925 | struct macio_chip* macio; | ||
| 926 | |||
| 927 | macio = &macio_chips[0]; | ||
| 928 | if (macio->type != macio_keylargo && macio->type != macio_pangea && | ||
| 929 | macio->type != macio_intrepid) | ||
| 930 | return -ENODEV; | ||
| 931 | |||
| 932 | LOCK(flags); | ||
| 933 | MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE); | ||
| 934 | (void)MACIO_IN8(KL_GPIO_ETH_PHY_RESET); | ||
| 935 | UNLOCK(flags); | ||
| 936 | mdelay(10); | ||
| 937 | LOCK(flags); | ||
| 938 | MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, /*KEYLARGO_GPIO_OUTPUT_ENABLE | */ | ||
| 939 | KEYLARGO_GPIO_OUTOUT_DATA); | ||
| 940 | UNLOCK(flags); | ||
| 941 | mdelay(10); | ||
| 942 | |||
| 943 | return 0; | ||
| 944 | } | ||
| 945 | |||
| 946 | static long | ||
| 947 | core99_sound_chip_enable(struct device_node* node, long param, long value) | ||
| 948 | { | ||
| 949 | struct macio_chip* macio; | ||
| 950 | unsigned long flags; | ||
| 951 | |||
| 952 | macio = macio_find(node, 0); | ||
| 953 | if (!macio) | ||
| 954 | return -ENODEV; | ||
| 955 | |||
| 956 | /* Do a better probe code, screamer G4 desktops & | ||
| 957 | * iMacs can do that too, add a recalibrate in | ||
| 958 | * the driver as well | ||
| 959 | */ | ||
| 960 | if (pmac_mb.model_id == PMAC_TYPE_PISMO || | ||
| 961 | pmac_mb.model_id == PMAC_TYPE_TITANIUM) { | ||
| 962 | LOCK(flags); | ||
| 963 | if (value) | ||
| 964 | MACIO_OUT8(KL_GPIO_SOUND_POWER, | ||
| 965 | KEYLARGO_GPIO_OUTPUT_ENABLE | | ||
| 966 | KEYLARGO_GPIO_OUTOUT_DATA); | ||
| 967 | else | ||
| 968 | MACIO_OUT8(KL_GPIO_SOUND_POWER, | ||
| 969 | KEYLARGO_GPIO_OUTPUT_ENABLE); | ||
| 970 | (void)MACIO_IN8(KL_GPIO_SOUND_POWER); | ||
| 971 | UNLOCK(flags); | ||
| 972 | } | ||
| 973 | return 0; | ||
| 974 | } | ||
| 975 | |||
| 976 | static long | ||
| 977 | core99_airport_enable(struct device_node* node, long param, long value) | ||
| 978 | { | ||
| 979 | struct macio_chip* macio; | ||
| 980 | unsigned long flags; | ||
| 981 | int state; | ||
| 982 | |||
| 983 | macio = macio_find(node, 0); | ||
| 984 | if (!macio) | ||
| 985 | return -ENODEV; | ||
| 986 | |||
| 987 | /* Hint: we allow passing of macio itself for the sake of the | ||
| 988 | * sleep code | ||
| 989 | */ | ||
| 990 | if (node != macio->of_node && | ||
| 991 | (!node->parent || node->parent != macio->of_node)) | ||
| 992 | return -ENODEV; | ||
| 993 | state = (macio->flags & MACIO_FLAG_AIRPORT_ON) != 0; | ||
| 994 | if (value == state) | ||
| 995 | return 0; | ||
| 996 | if (value) { | ||
| 997 | /* This code is a reproduction of OF enable-cardslot | ||
| 998 | * and init-wireless methods, slightly hacked until | ||
| 999 | * I got it working. | ||
| 1000 | */ | ||
| 1001 | LOCK(flags); | ||
| 1002 | MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 5); | ||
| 1003 | (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf); | ||
| 1004 | UNLOCK(flags); | ||
| 1005 | mdelay(10); | ||
| 1006 | LOCK(flags); | ||
| 1007 | MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 4); | ||
| 1008 | (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf); | ||
| 1009 | UNLOCK(flags); | ||
| 1010 | |||
| 1011 | mdelay(10); | ||
| 1012 | |||
| 1013 | LOCK(flags); | ||
| 1014 | MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16); | ||
| 1015 | (void)MACIO_IN32(KEYLARGO_FCR2); | ||
| 1016 | udelay(10); | ||
| 1017 | MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xb, 0); | ||
| 1018 | (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xb); | ||
| 1019 | udelay(10); | ||
| 1020 | MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xa, 0x28); | ||
| 1021 | (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xa); | ||
| 1022 | udelay(10); | ||
| 1023 | MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xd, 0x28); | ||
| 1024 | (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xd); | ||
| 1025 | udelay(10); | ||
| 1026 | MACIO_OUT8(KEYLARGO_GPIO_0+0xd, 0x28); | ||
| 1027 | (void)MACIO_IN8(KEYLARGO_GPIO_0+0xd); | ||
| 1028 | udelay(10); | ||
| 1029 | MACIO_OUT8(KEYLARGO_GPIO_0+0xe, 0x28); | ||
| 1030 | (void)MACIO_IN8(KEYLARGO_GPIO_0+0xe); | ||
| 1031 | UNLOCK(flags); | ||
| 1032 | udelay(10); | ||
| 1033 | MACIO_OUT32(0x1c000, 0); | ||
| 1034 | mdelay(1); | ||
| 1035 | MACIO_OUT8(0x1a3e0, 0x41); | ||
| 1036 | (void)MACIO_IN8(0x1a3e0); | ||
| 1037 | udelay(10); | ||
| 1038 | LOCK(flags); | ||
| 1039 | MACIO_BIS(KEYLARGO_FCR2, KL2_CARDSEL_16); | ||
| 1040 | (void)MACIO_IN32(KEYLARGO_FCR2); | ||
| 1041 | UNLOCK(flags); | ||
| 1042 | mdelay(100); | ||
| 1043 | |||
| 1044 | macio->flags |= MACIO_FLAG_AIRPORT_ON; | ||
| 1045 | } else { | ||
| 1046 | LOCK(flags); | ||
| 1047 | MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16); | ||
| 1048 | (void)MACIO_IN32(KEYLARGO_FCR2); | ||
| 1049 | MACIO_OUT8(KL_GPIO_AIRPORT_0, 0); | ||
| 1050 | MACIO_OUT8(KL_GPIO_AIRPORT_1, 0); | ||
| 1051 | MACIO_OUT8(KL_GPIO_AIRPORT_2, 0); | ||
| 1052 | MACIO_OUT8(KL_GPIO_AIRPORT_3, 0); | ||
| 1053 | MACIO_OUT8(KL_GPIO_AIRPORT_4, 0); | ||
| 1054 | (void)MACIO_IN8(KL_GPIO_AIRPORT_4); | ||
| 1055 | UNLOCK(flags); | ||
| 1056 | |||
| 1057 | macio->flags &= ~MACIO_FLAG_AIRPORT_ON; | ||
| 1058 | } | ||
| 1059 | return 0; | ||
| 1060 | } | ||
| 1061 | |||
| 1062 | #ifdef CONFIG_SMP | ||
| 1063 | static long | ||
| 1064 | core99_reset_cpu(struct device_node* node, long param, long value) | ||
| 1065 | { | ||
| 1066 | unsigned int reset_io = 0; | ||
| 1067 | unsigned long flags; | ||
| 1068 | struct macio_chip* macio; | ||
| 1069 | struct device_node* np; | ||
| 1070 | const int dflt_reset_lines[] = { KL_GPIO_RESET_CPU0, | ||
| 1071 | KL_GPIO_RESET_CPU1, | ||
| 1072 | KL_GPIO_RESET_CPU2, | ||
| 1073 | KL_GPIO_RESET_CPU3 }; | ||
| 1074 | |||
| 1075 | macio = &macio_chips[0]; | ||
| 1076 | if (macio->type != macio_keylargo) | ||
| 1077 | return -ENODEV; | ||
| 1078 | |||
| 1079 | np = find_path_device("/cpus"); | ||
| 1080 | if (np == NULL) | ||
| 1081 | return -ENODEV; | ||
| 1082 | for (np = np->child; np != NULL; np = np->sibling) { | ||
| 1083 | u32* num = (u32 *)get_property(np, "reg", NULL); | ||
| 1084 | u32* rst = (u32 *)get_property(np, "soft-reset", NULL); | ||
| 1085 | if (num == NULL || rst == NULL) | ||
| 1086 | continue; | ||
| 1087 | if (param == *num) { | ||
| 1088 | reset_io = *rst; | ||
| 1089 | break; | ||
| 1090 | } | ||
| 1091 | } | ||
| 1092 | if (np == NULL || reset_io == 0) | ||
| 1093 | reset_io = dflt_reset_lines[param]; | ||
| 1094 | |||
| 1095 | LOCK(flags); | ||
| 1096 | MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE); | ||
| 1097 | (void)MACIO_IN8(reset_io); | ||
| 1098 | udelay(1); | ||
| 1099 | MACIO_OUT8(reset_io, 0); | ||
| 1100 | (void)MACIO_IN8(reset_io); | ||
| 1101 | UNLOCK(flags); | ||
| 1102 | |||
| 1103 | return 0; | ||
| 1104 | } | ||
| 1105 | #endif /* CONFIG_SMP */ | ||
| 1106 | |||
| 1107 | static long | ||
| 1108 | core99_usb_enable(struct device_node* node, long param, long value) | ||
| 1109 | { | ||
| 1110 | struct macio_chip* macio; | ||
| 1111 | unsigned long flags; | ||
| 1112 | char* prop; | ||
| 1113 | int number; | ||
| 1114 | u32 reg; | ||
| 1115 | |||
| 1116 | macio = &macio_chips[0]; | ||
| 1117 | if (macio->type != macio_keylargo && macio->type != macio_pangea && | ||
| 1118 | macio->type != macio_intrepid) | ||
| 1119 | return -ENODEV; | ||
| 1120 | |||
| 1121 | prop = (char *)get_property(node, "AAPL,clock-id", NULL); | ||
| 1122 | if (!prop) | ||
| 1123 | return -ENODEV; | ||
| 1124 | if (strncmp(prop, "usb0u048", 8) == 0) | ||
| 1125 | number = 0; | ||
| 1126 | else if (strncmp(prop, "usb1u148", 8) == 0) | ||
| 1127 | number = 2; | ||
| 1128 | else if (strncmp(prop, "usb2u248", 8) == 0) | ||
| 1129 | number = 4; | ||
| 1130 | else | ||
| 1131 | return -ENODEV; | ||
| 1132 | |||
| 1133 | /* Sorry for the brute-force locking, but this is only used during | ||
| 1134 | * sleep and the timing seem to be critical | ||
| 1135 | */ | ||
| 1136 | LOCK(flags); | ||
| 1137 | if (value) { | ||
| 1138 | /* Turn ON */ | ||
| 1139 | if (number == 0) { | ||
| 1140 | MACIO_BIC(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1)); | ||
| 1141 | (void)MACIO_IN32(KEYLARGO_FCR0); | ||
| 1142 | UNLOCK(flags); | ||
| 1143 | mdelay(1); | ||
| 1144 | LOCK(flags); | ||
| 1145 | MACIO_BIS(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE); | ||
| 1146 | } else if (number == 2) { | ||
| 1147 | MACIO_BIC(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1)); | ||
| 1148 | UNLOCK(flags); | ||
| 1149 | (void)MACIO_IN32(KEYLARGO_FCR0); | ||
| 1150 | mdelay(1); | ||
| 1151 | LOCK(flags); | ||
| 1152 | MACIO_BIS(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE); | ||
| 1153 | } else if (number == 4) { | ||
| 1154 | MACIO_BIC(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1)); | ||
| 1155 | UNLOCK(flags); | ||
| 1156 | (void)MACIO_IN32(KEYLARGO_FCR1); | ||
| 1157 | mdelay(1); | ||
| 1158 | LOCK(flags); | ||
| 1159 | MACIO_BIS(KEYLARGO_FCR1, KL1_USB2_CELL_ENABLE); | ||
| 1160 | } | ||
| 1161 | if (number < 4) { | ||
| 1162 | reg = MACIO_IN32(KEYLARGO_FCR4); | ||
| 1163 | reg &= ~(KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) | | ||
| 1164 | KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number)); | ||
| 1165 | reg &= ~(KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) | | ||
| 1166 | KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1)); | ||
| 1167 | MACIO_OUT32(KEYLARGO_FCR4, reg); | ||
| 1168 | (void)MACIO_IN32(KEYLARGO_FCR4); | ||
| 1169 | udelay(10); | ||
| 1170 | } else { | ||
| 1171 | reg = MACIO_IN32(KEYLARGO_FCR3); | ||
| 1172 | reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) | | ||
| 1173 | KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0)); | ||
| 1174 | reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) | | ||
| 1175 | KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1)); | ||
| 1176 | MACIO_OUT32(KEYLARGO_FCR3, reg); | ||
| 1177 | (void)MACIO_IN32(KEYLARGO_FCR3); | ||
| 1178 | udelay(10); | ||
| 1179 | } | ||
| 1180 | if (macio->type == macio_intrepid) { | ||
| 1181 | /* wait for clock stopped bits to clear */ | ||
| 1182 | u32 test0 = 0, test1 = 0; | ||
| 1183 | u32 status0, status1; | ||
| 1184 | int timeout = 1000; | ||
| 1185 | |||
| 1186 | UNLOCK(flags); | ||
| 1187 | switch (number) { | ||
| 1188 | case 0: | ||
| 1189 | test0 = UNI_N_CLOCK_STOPPED_USB0; | ||
| 1190 | test1 = UNI_N_CLOCK_STOPPED_USB0PCI; | ||
| 1191 | break; | ||
| 1192 | case 2: | ||
| 1193 | test0 = UNI_N_CLOCK_STOPPED_USB1; | ||
| 1194 | test1 = UNI_N_CLOCK_STOPPED_USB1PCI; | ||
| 1195 | break; | ||
| 1196 | case 4: | ||
| 1197 | test0 = UNI_N_CLOCK_STOPPED_USB2; | ||
| 1198 | test1 = UNI_N_CLOCK_STOPPED_USB2PCI; | ||
| 1199 | break; | ||
| 1200 | } | ||
| 1201 | do { | ||
| 1202 | if (--timeout <= 0) { | ||
| 1203 | printk(KERN_ERR "core99_usb_enable: " | ||
| 1204 | "Timeout waiting for clocks\n"); | ||
| 1205 | break; | ||
| 1206 | } | ||
| 1207 | mdelay(1); | ||
| 1208 | status0 = UN_IN(UNI_N_CLOCK_STOP_STATUS0); | ||
| 1209 | status1 = UN_IN(UNI_N_CLOCK_STOP_STATUS1); | ||
| 1210 | } while ((status0 & test0) | (status1 & test1)); | ||
| 1211 | LOCK(flags); | ||
| 1212 | } | ||
| 1213 | } else { | ||
| 1214 | /* Turn OFF */ | ||
| 1215 | if (number < 4) { | ||
| 1216 | reg = MACIO_IN32(KEYLARGO_FCR4); | ||
| 1217 | reg |= KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) | | ||
| 1218 | KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number); | ||
| 1219 | reg |= KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) | | ||
| 1220 | KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1); | ||
| 1221 | MACIO_OUT32(KEYLARGO_FCR4, reg); | ||
| 1222 | (void)MACIO_IN32(KEYLARGO_FCR4); | ||
| 1223 | udelay(1); | ||
| 1224 | } else { | ||
| 1225 | reg = MACIO_IN32(KEYLARGO_FCR3); | ||
| 1226 | reg |= KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) | | ||
| 1227 | KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0); | ||
| 1228 | reg |= KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) | | ||
| 1229 | KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1); | ||
| 1230 | MACIO_OUT32(KEYLARGO_FCR3, reg); | ||
| 1231 | (void)MACIO_IN32(KEYLARGO_FCR3); | ||
| 1232 | udelay(1); | ||
| 1233 | } | ||
| 1234 | if (number == 0) { | ||
| 1235 | if (macio->type != macio_intrepid) | ||
| 1236 | MACIO_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE); | ||
| 1237 | (void)MACIO_IN32(KEYLARGO_FCR0); | ||
| 1238 | udelay(1); | ||
| 1239 | MACIO_BIS(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1)); | ||
| 1240 | (void)MACIO_IN32(KEYLARGO_FCR0); | ||
| 1241 | } else if (number == 2) { | ||
| 1242 | if (macio->type != macio_intrepid) | ||
| 1243 | MACIO_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE); | ||
| 1244 | (void)MACIO_IN32(KEYLARGO_FCR0); | ||
| 1245 | udelay(1); | ||
| 1246 | MACIO_BIS(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1)); | ||
| 1247 | (void)MACIO_IN32(KEYLARGO_FCR0); | ||
| 1248 | } else if (number == 4) { | ||
| 1249 | udelay(1); | ||
| 1250 | MACIO_BIS(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1)); | ||
| 1251 | (void)MACIO_IN32(KEYLARGO_FCR1); | ||
| 1252 | } | ||
| 1253 | udelay(1); | ||
| 1254 | } | ||
| 1255 | UNLOCK(flags); | ||
| 1256 | |||
| 1257 | return 0; | ||
| 1258 | } | ||
| 1259 | |||
| 1260 | static long | ||
| 1261 | core99_firewire_enable(struct device_node* node, long param, long value) | ||
| 1262 | { | ||
| 1263 | unsigned long flags; | ||
| 1264 | struct macio_chip* macio; | ||
| 1265 | |||
| 1266 | macio = &macio_chips[0]; | ||
| 1267 | if (macio->type != macio_keylargo && macio->type != macio_pangea && | ||
| 1268 | macio->type != macio_intrepid) | ||
| 1269 | return -ENODEV; | ||
| 1270 | if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED)) | ||
| 1271 | return -ENODEV; | ||
| 1272 | |||
| 1273 | LOCK(flags); | ||
| 1274 | if (value) { | ||
| 1275 | UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW); | ||
| 1276 | (void)UN_IN(UNI_N_CLOCK_CNTL); | ||
| 1277 | } else { | ||
| 1278 | UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW); | ||
| 1279 | (void)UN_IN(UNI_N_CLOCK_CNTL); | ||
| 1280 | } | ||
| 1281 | UNLOCK(flags); | ||
| 1282 | mdelay(1); | ||
| 1283 | |||
| 1284 | return 0; | ||
| 1285 | } | ||
| 1286 | |||
| 1287 | static long | ||
| 1288 | core99_firewire_cable_power(struct device_node* node, long param, long value) | ||
| 1289 | { | ||
| 1290 | unsigned long flags; | ||
| 1291 | struct macio_chip* macio; | ||
| 1292 | |||
| 1293 | /* Trick: we allow NULL node */ | ||
| 1294 | if ((pmac_mb.board_flags & PMAC_MB_HAS_FW_POWER) == 0) | ||
| 1295 | return -ENODEV; | ||
| 1296 | macio = &macio_chips[0]; | ||
| 1297 | if (macio->type != macio_keylargo && macio->type != macio_pangea && | ||
| 1298 | macio->type != macio_intrepid) | ||
| 1299 | return -ENODEV; | ||
| 1300 | if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED)) | ||
| 1301 | return -ENODEV; | ||
| 1302 | |||
| 1303 | LOCK(flags); | ||
| 1304 | if (value) { | ||
| 1305 | MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 0); | ||
| 1306 | MACIO_IN8(KL_GPIO_FW_CABLE_POWER); | ||
| 1307 | udelay(10); | ||
| 1308 | } else { | ||
| 1309 | MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 4); | ||
| 1310 | MACIO_IN8(KL_GPIO_FW_CABLE_POWER); udelay(10); | ||
| 1311 | } | ||
| 1312 | UNLOCK(flags); | ||
| 1313 | mdelay(1); | ||
| 1314 | |||
| 1315 | return 0; | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | static long | ||
| 1319 | intrepid_aack_delay_enable(struct device_node* node, long param, long value) | ||
| 1320 | { | ||
| 1321 | unsigned long flags; | ||
| 1322 | |||
| 1323 | if (uninorth_rev < 0xd2) | ||
| 1324 | return -ENODEV; | ||
| 1325 | |||
| 1326 | LOCK(flags); | ||
| 1327 | if (param) | ||
| 1328 | UN_BIS(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE); | ||
| 1329 | else | ||
| 1330 | UN_BIC(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE); | ||
| 1331 | UNLOCK(flags); | ||
| 1332 | |||
| 1333 | return 0; | ||
| 1334 | } | ||
| 1335 | |||
| 1336 | |||
| 1337 | #endif /* CONFIG_POWER4 */ | ||
| 1338 | |||
| 1339 | static long | ||
| 1340 | core99_read_gpio(struct device_node* node, long param, long value) | ||
| 1341 | { | ||
| 1342 | struct macio_chip* macio = &macio_chips[0]; | ||
| 1343 | |||
| 1344 | return MACIO_IN8(param); | ||
| 1345 | } | ||
| 1346 | |||
| 1347 | |||
| 1348 | static long | ||
| 1349 | core99_write_gpio(struct device_node* node, long param, long value) | ||
| 1350 | { | ||
| 1351 | struct macio_chip* macio = &macio_chips[0]; | ||
| 1352 | |||
| 1353 | MACIO_OUT8(param, (u8)(value & 0xff)); | ||
| 1354 | return 0; | ||
| 1355 | } | ||
| 1356 | |||
| 1357 | #ifdef CONFIG_POWER4 | ||
| 1358 | |||
| 1359 | static long | ||
| 1360 | g5_gmac_enable(struct device_node* node, long param, long value) | ||
| 1361 | { | ||
| 1362 | struct macio_chip* macio = &macio_chips[0]; | ||
| 1363 | unsigned long flags; | ||
| 1364 | u8 pbus, pid; | ||
| 1365 | |||
| 1366 | LOCK(flags); | ||
| 1367 | if (value) { | ||
| 1368 | MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE); | ||
| 1369 | mb(); | ||
| 1370 | k2_skiplist[0] = NULL; | ||
| 1371 | } else { | ||
| 1372 | k2_skiplist[0] = node; | ||
| 1373 | mb(); | ||
| 1374 | MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE); | ||
| 1375 | } | ||
| 1376 | |||
| 1377 | UNLOCK(flags); | ||
| 1378 | mdelay(1); | ||
| 1379 | |||
| 1380 | return 0; | ||
| 1381 | } | ||
| 1382 | |||
| 1383 | static long | ||
| 1384 | g5_fw_enable(struct device_node* node, long param, long value) | ||
| 1385 | { | ||
| 1386 | struct macio_chip* macio = &macio_chips[0]; | ||
| 1387 | unsigned long flags; | ||
| 1388 | |||
| 1389 | LOCK(flags); | ||
| 1390 | if (value) { | ||
| 1391 | MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE); | ||
| 1392 | mb(); | ||
| 1393 | k2_skiplist[1] = NULL; | ||
| 1394 | } else { | ||
| 1395 | k2_skiplist[1] = node; | ||
| 1396 | mb(); | ||
| 1397 | MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE); | ||
| 1398 | } | ||
| 1399 | |||
| 1400 | UNLOCK(flags); | ||
| 1401 | mdelay(1); | ||
| 1402 | |||
| 1403 | return 0; | ||
| 1404 | } | ||
| 1405 | |||
| 1406 | static long | ||
| 1407 | g5_mpic_enable(struct device_node* node, long param, long value) | ||
| 1408 | { | ||
| 1409 | unsigned long flags; | ||
| 1410 | |||
| 1411 | if (node->parent == NULL || strcmp(node->parent->name, "u3")) | ||
| 1412 | return 0; | ||
| 1413 | |||
| 1414 | LOCK(flags); | ||
| 1415 | UN_BIS(U3_TOGGLE_REG, U3_MPIC_RESET | U3_MPIC_OUTPUT_ENABLE); | ||
| 1416 | UNLOCK(flags); | ||
| 1417 | |||
| 1418 | return 0; | ||
| 1419 | } | ||
| 1420 | |||
| 1421 | #ifdef CONFIG_SMP | ||
| 1422 | static long | ||
| 1423 | g5_reset_cpu(struct device_node* node, long param, long value) | ||
| 1424 | { | ||
| 1425 | unsigned int reset_io = 0; | ||
| 1426 | unsigned long flags; | ||
| 1427 | struct macio_chip* macio; | ||
| 1428 | struct device_node* np; | ||
| 1429 | |||
| 1430 | macio = &macio_chips[0]; | ||
| 1431 | if (macio->type != macio_keylargo2) | ||
| 1432 | return -ENODEV; | ||
| 1433 | |||
| 1434 | np = find_path_device("/cpus"); | ||
| 1435 | if (np == NULL) | ||
| 1436 | return -ENODEV; | ||
| 1437 | for (np = np->child; np != NULL; np = np->sibling) { | ||
| 1438 | u32* num = (u32 *)get_property(np, "reg", NULL); | ||
| 1439 | u32* rst = (u32 *)get_property(np, "soft-reset", NULL); | ||
| 1440 | if (num == NULL || rst == NULL) | ||
| 1441 | continue; | ||
| 1442 | if (param == *num) { | ||
| 1443 | reset_io = *rst; | ||
| 1444 | break; | ||
| 1445 | } | ||
| 1446 | } | ||
| 1447 | if (np == NULL || reset_io == 0) | ||
| 1448 | return -ENODEV; | ||
| 1449 | |||
| 1450 | LOCK(flags); | ||
| 1451 | MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE); | ||
| 1452 | (void)MACIO_IN8(reset_io); | ||
| 1453 | udelay(1); | ||
| 1454 | MACIO_OUT8(reset_io, 0); | ||
| 1455 | (void)MACIO_IN8(reset_io); | ||
| 1456 | UNLOCK(flags); | ||
| 1457 | |||
| 1458 | return 0; | ||
| 1459 | } | ||
| 1460 | #endif /* CONFIG_SMP */ | ||
| 1461 | |||
| 1462 | /* | ||
| 1463 | * This can be called from pmac_smp so isn't static | ||
| 1464 | * | ||
| 1465 | * This takes the second CPU off the bus on dual CPU machines | ||
| 1466 | * running UP | ||
| 1467 | */ | ||
| 1468 | void g5_phy_disable_cpu1(void) | ||
| 1469 | { | ||
| 1470 | UN_OUT(U3_API_PHY_CONFIG_1, 0); | ||
| 1471 | } | ||
| 1472 | |||
| 1473 | #endif /* CONFIG_POWER4 */ | ||
| 1474 | |||
| 1475 | #ifndef CONFIG_POWER4 | ||
| 1476 | |||
| 1477 | static void | ||
| 1478 | keylargo_shutdown(struct macio_chip* macio, int sleep_mode) | ||
| 1479 | { | ||
| 1480 | u32 temp; | ||
| 1481 | |||
| 1482 | if (sleep_mode) { | ||
| 1483 | mdelay(1); | ||
| 1484 | MACIO_BIS(KEYLARGO_FCR0, KL0_USB_REF_SUSPEND); | ||
| 1485 | (void)MACIO_IN32(KEYLARGO_FCR0); | ||
| 1486 | mdelay(1); | ||
| 1487 | } | ||
| 1488 | |||
| 1489 | MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE | | ||
| 1490 | KL0_SCC_CELL_ENABLE | | ||
| 1491 | KL0_IRDA_ENABLE | KL0_IRDA_CLK32_ENABLE | | ||
| 1492 | KL0_IRDA_CLK19_ENABLE); | ||
| 1493 | |||
| 1494 | MACIO_BIC(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK); | ||
| 1495 | MACIO_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_IDE_ENABLE); | ||
| 1496 | |||
| 1497 | MACIO_BIC(KEYLARGO_FCR1, | ||
| 1498 | KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT | | ||
| 1499 | KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE | | ||
| 1500 | KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT | | ||
| 1501 | KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE | | ||
| 1502 | KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE | | ||
| 1503 | KL1_EIDE0_ENABLE | KL1_EIDE0_RESET_N | | ||
| 1504 | KL1_EIDE1_ENABLE | KL1_EIDE1_RESET_N | | ||
| 1505 | KL1_UIDE_ENABLE); | ||
| 1506 | |||
| 1507 | MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT); | ||
| 1508 | MACIO_BIC(KEYLARGO_FCR2, KL2_IOBUS_ENABLE); | ||
| 1509 | |||
| 1510 | temp = MACIO_IN32(KEYLARGO_FCR3); | ||
| 1511 | if (macio->rev >= 2) { | ||
| 1512 | temp |= KL3_SHUTDOWN_PLL2X; | ||
| 1513 | if (sleep_mode) | ||
| 1514 | temp |= KL3_SHUTDOWN_PLL_TOTAL; | ||
| 1515 | } | ||
| 1516 | |||
| 1517 | temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 | | ||
| 1518 | KL3_SHUTDOWN_PLLKW35; | ||
| 1519 | if (sleep_mode) | ||
| 1520 | temp |= KL3_SHUTDOWN_PLLKW12; | ||
| 1521 | temp &= ~(KL3_CLK66_ENABLE | KL3_CLK49_ENABLE | KL3_CLK45_ENABLE | ||
| 1522 | | KL3_CLK31_ENABLE | KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE); | ||
| 1523 | if (sleep_mode) | ||
| 1524 | temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE); | ||
| 1525 | MACIO_OUT32(KEYLARGO_FCR3, temp); | ||
| 1526 | |||
| 1527 | /* Flush posted writes & wait a bit */ | ||
| 1528 | (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1); | ||
| 1529 | } | ||
| 1530 | |||
| 1531 | static void | ||
| 1532 | pangea_shutdown(struct macio_chip* macio, int sleep_mode) | ||
| 1533 | { | ||
| 1534 | u32 temp; | ||
| 1535 | |||
| 1536 | MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE | | ||
| 1537 | KL0_SCC_CELL_ENABLE | | ||
| 1538 | KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE); | ||
| 1539 | |||
| 1540 | MACIO_BIC(KEYLARGO_FCR1, | ||
| 1541 | KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT | | ||
| 1542 | KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE | | ||
| 1543 | KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT | | ||
| 1544 | KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE | | ||
| 1545 | KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE | | ||
| 1546 | KL1_UIDE_ENABLE); | ||
| 1547 | if (pmac_mb.board_flags & PMAC_MB_MOBILE) | ||
| 1548 | MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N); | ||
| 1549 | |||
| 1550 | MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT); | ||
| 1551 | |||
| 1552 | temp = MACIO_IN32(KEYLARGO_FCR3); | ||
| 1553 | temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 | | ||
| 1554 | KL3_SHUTDOWN_PLLKW35; | ||
| 1555 | temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE | KL3_CLK31_ENABLE | ||
| 1556 | | KL3_I2S0_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE); | ||
| 1557 | if (sleep_mode) | ||
| 1558 | temp &= ~(KL3_VIA_CLK16_ENABLE | KL3_TIMER_CLK18_ENABLE); | ||
| 1559 | MACIO_OUT32(KEYLARGO_FCR3, temp); | ||
| 1560 | |||
| 1561 | /* Flush posted writes & wait a bit */ | ||
| 1562 | (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1); | ||
| 1563 | } | ||
| 1564 | |||
| 1565 | static void | ||
| 1566 | intrepid_shutdown(struct macio_chip* macio, int sleep_mode) | ||
| 1567 | { | ||
| 1568 | u32 temp; | ||
| 1569 | |||
| 1570 | MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE | | ||
| 1571 | KL0_SCC_CELL_ENABLE); | ||
| 1572 | |||
| 1573 | MACIO_BIC(KEYLARGO_FCR1, | ||
| 1574 | /*KL1_USB2_CELL_ENABLE |*/ | ||
| 1575 | KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT | | ||
| 1576 | KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE | | ||
| 1577 | KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE); | ||
| 1578 | if (pmac_mb.board_flags & PMAC_MB_MOBILE) | ||
| 1579 | MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N); | ||
| 1580 | |||
| 1581 | temp = MACIO_IN32(KEYLARGO_FCR3); | ||
| 1582 | temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE | | ||
| 1583 | KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE); | ||
| 1584 | if (sleep_mode) | ||
| 1585 | temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_IT_VIA_CLK32_ENABLE); | ||
| 1586 | MACIO_OUT32(KEYLARGO_FCR3, temp); | ||
| 1587 | |||
| 1588 | /* Flush posted writes & wait a bit */ | ||
| 1589 | (void)MACIO_IN32(KEYLARGO_FCR0); | ||
| 1590 | mdelay(10); | ||
| 1591 | } | ||
| 1592 | |||
| 1593 | |||
| 1594 | void pmac_tweak_clock_spreading(int enable) | ||
| 1595 | { | ||
| 1596 | struct macio_chip* macio = &macio_chips[0]; | ||
| 1597 | |||
| 1598 | /* Hack for doing clock spreading on some machines PowerBooks and | ||
| 1599 | * iBooks. This implements the "platform-do-clockspreading" OF | ||
| 1600 | * property as decoded manually on various models. For safety, we also | ||
| 1601 | * check the product ID in the device-tree in cases we'll whack the i2c | ||
| 1602 | * chip to make reasonably sure we won't set wrong values in there | ||
| 1603 | * | ||
| 1604 | * Of course, ultimately, we have to implement a real parser for | ||
| 1605 | * the platform-do-* stuff... | ||
| 1606 | */ | ||
| 1607 | |||
| 1608 | if (macio->type == macio_intrepid) { | ||
| 1609 | struct device_node *clock = | ||
| 1610 | of_find_node_by_path("/uni-n@f8000000/hw-clock"); | ||
| 1611 | if (clock && get_property(clock, "platform-do-clockspreading", | ||
| 1612 | NULL)) { | ||
| 1613 | printk(KERN_INFO "%sabling clock spreading on Intrepid" | ||
| 1614 | " ASIC\n", enable ? "En" : "Dis"); | ||
| 1615 | if (enable) | ||
| 1616 | UN_OUT(UNI_N_CLOCK_SPREADING, 2); | ||
| 1617 | else | ||
| 1618 | UN_OUT(UNI_N_CLOCK_SPREADING, 0); | ||
| 1619 | mdelay(40); | ||
| 1620 | } | ||
| 1621 | of_node_put(clock); | ||
| 1622 | } | ||
| 1623 | |||
| 1624 | while (machine_is_compatible("PowerBook5,2") || | ||
| 1625 | machine_is_compatible("PowerBook5,3") || | ||
| 1626 | machine_is_compatible("PowerBook6,2") || | ||
| 1627 | machine_is_compatible("PowerBook6,3")) { | ||
| 1628 | struct device_node *ui2c = of_find_node_by_type(NULL, "i2c"); | ||
| 1629 | struct device_node *dt = of_find_node_by_name(NULL, "device-tree"); | ||
| 1630 | u8 buffer[9]; | ||
| 1631 | u32 *productID; | ||
| 1632 | int i, rc, changed = 0; | ||
| 1633 | |||
| 1634 | if (dt == NULL) | ||
| 1635 | break; | ||
| 1636 | productID = (u32 *)get_property(dt, "pid#", NULL); | ||
| 1637 | if (productID == NULL) | ||
| 1638 | break; | ||
| 1639 | while(ui2c) { | ||
| 1640 | struct device_node *p = of_get_parent(ui2c); | ||
| 1641 | if (p && !strcmp(p->name, "uni-n")) | ||
| 1642 | break; | ||
| 1643 | ui2c = of_find_node_by_type(ui2c, "i2c"); | ||
| 1644 | } | ||
| 1645 | if (ui2c == NULL) | ||
| 1646 | break; | ||
| 1647 | DBG("Trying to bump clock speed for PID: %08x...\n", *productID); | ||
| 1648 | rc = pmac_low_i2c_open(ui2c, 1); | ||
| 1649 | if (rc != 0) | ||
| 1650 | break; | ||
| 1651 | pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined); | ||
| 1652 | rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9); | ||
| 1653 | DBG("read result: %d,", rc); | ||
| 1654 | if (rc != 0) { | ||
| 1655 | pmac_low_i2c_close(ui2c); | ||
| 1656 | break; | ||
| 1657 | } | ||
| 1658 | for (i=0; i<9; i++) | ||
| 1659 | DBG(" %02x", buffer[i]); | ||
| 1660 | DBG("\n"); | ||
| 1661 | |||
| 1662 | switch(*productID) { | ||
| 1663 | case 0x1182: /* AlBook 12" rev 2 */ | ||
| 1664 | case 0x1183: /* iBook G4 12" */ | ||
| 1665 | buffer[0] = (buffer[0] & 0x8f) | 0x70; | ||
| 1666 | buffer[2] = (buffer[2] & 0x7f) | 0x00; | ||
| 1667 | buffer[5] = (buffer[5] & 0x80) | 0x31; | ||
| 1668 | buffer[6] = (buffer[6] & 0x40) | 0xb0; | ||
| 1669 | buffer[7] = (buffer[7] & 0x00) | (enable ? 0xc0 : 0xba); | ||
| 1670 | buffer[8] = (buffer[8] & 0x00) | 0x30; | ||
| 1671 | changed = 1; | ||
| 1672 | break; | ||
| 1673 | case 0x3142: /* AlBook 15" (ATI M10) */ | ||
| 1674 | case 0x3143: /* AlBook 17" (ATI M10) */ | ||
| 1675 | buffer[0] = (buffer[0] & 0xaf) | 0x50; | ||
| 1676 | buffer[2] = (buffer[2] & 0x7f) | 0x00; | ||
| 1677 | buffer[5] = (buffer[5] & 0x80) | 0x31; | ||
| 1678 | buffer[6] = (buffer[6] & 0x40) | 0xb0; | ||
| 1679 | buffer[7] = (buffer[7] & 0x00) | (enable ? 0xd0 : 0xc0); | ||
| 1680 | buffer[8] = (buffer[8] & 0x00) | 0x30; | ||
| 1681 | changed = 1; | ||
| 1682 | break; | ||
| 1683 | default: | ||
| 1684 | DBG("i2c-hwclock: Machine model not handled\n"); | ||
| 1685 | break; | ||
| 1686 | } | ||
| 1687 | if (!changed) { | ||
| 1688 | pmac_low_i2c_close(ui2c); | ||
| 1689 | break; | ||
| 1690 | } | ||
| 1691 | printk(KERN_INFO "%sabling clock spreading on i2c clock chip\n", | ||
| 1692 | enable ? "En" : "Dis"); | ||
| 1693 | pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub); | ||
| 1694 | rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9); | ||
| 1695 | DBG("write result: %d,", rc); | ||
| 1696 | pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined); | ||
| 1697 | rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9); | ||
| 1698 | DBG("read result: %d,", rc); | ||
| 1699 | if (rc != 0) { | ||
| 1700 | pmac_low_i2c_close(ui2c); | ||
| 1701 | break; | ||
| 1702 | } | ||
| 1703 | for (i=0; i<9; i++) | ||
| 1704 | DBG(" %02x", buffer[i]); | ||
| 1705 | pmac_low_i2c_close(ui2c); | ||
| 1706 | break; | ||
| 1707 | } | ||
| 1708 | } | ||
| 1709 | |||
| 1710 | |||
| 1711 | static int | ||
| 1712 | core99_sleep(void) | ||
| 1713 | { | ||
| 1714 | struct macio_chip* macio; | ||
| 1715 | int i; | ||
| 1716 | |||
| 1717 | macio = &macio_chips[0]; | ||
| 1718 | if (macio->type != macio_keylargo && macio->type != macio_pangea && | ||
| 1719 | macio->type != macio_intrepid) | ||
| 1720 | return -ENODEV; | ||
| 1721 | |||
| 1722 | /* We power off the wireless slot in case it was not done | ||
| 1723 | * by the driver. We don't power it on automatically however | ||
| 1724 | */ | ||
| 1725 | if (macio->flags & MACIO_FLAG_AIRPORT_ON) | ||
| 1726 | core99_airport_enable(macio->of_node, 0, 0); | ||
| 1727 | |||
| 1728 | /* We power off the FW cable. Should be done by the driver... */ | ||
| 1729 | if (macio->flags & MACIO_FLAG_FW_SUPPORTED) { | ||
| 1730 | core99_firewire_enable(NULL, 0, 0); | ||
| 1731 | core99_firewire_cable_power(NULL, 0, 0); | ||
| 1732 | } | ||
| 1733 | |||
| 1734 | /* We make sure int. modem is off (in case driver lost it) */ | ||
| 1735 | if (macio->type == macio_keylargo) | ||
| 1736 | core99_modem_enable(macio->of_node, 0, 0); | ||
| 1737 | else | ||
| 1738 | pangea_modem_enable(macio->of_node, 0, 0); | ||
| 1739 | |||
| 1740 | /* We make sure the sound is off as well */ | ||
| 1741 | core99_sound_chip_enable(macio->of_node, 0, 0); | ||
| 1742 | |||
| 1743 | /* | ||
| 1744 | * Save various bits of KeyLargo | ||
| 1745 | */ | ||
| 1746 | |||
| 1747 | /* Save the state of the various GPIOs */ | ||
| 1748 | save_gpio_levels[0] = MACIO_IN32(KEYLARGO_GPIO_LEVELS0); | ||
| 1749 | save_gpio_levels[1] = MACIO_IN32(KEYLARGO_GPIO_LEVELS1); | ||
| 1750 | for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++) | ||
| 1751 | save_gpio_extint[i] = MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+i); | ||
| 1752 | for (i=0; i<KEYLARGO_GPIO_CNT; i++) | ||
| 1753 | save_gpio_normal[i] = MACIO_IN8(KEYLARGO_GPIO_0+i); | ||
| 1754 | |||
| 1755 | /* Save the FCRs */ | ||
| 1756 | if (macio->type == macio_keylargo) | ||
| 1757 | save_mbcr = MACIO_IN32(KEYLARGO_MBCR); | ||
| 1758 | save_fcr[0] = MACIO_IN32(KEYLARGO_FCR0); | ||
| 1759 | save_fcr[1] = MACIO_IN32(KEYLARGO_FCR1); | ||
| 1760 | save_fcr[2] = MACIO_IN32(KEYLARGO_FCR2); | ||
| 1761 | save_fcr[3] = MACIO_IN32(KEYLARGO_FCR3); | ||
| 1762 | save_fcr[4] = MACIO_IN32(KEYLARGO_FCR4); | ||
| 1763 | if (macio->type == macio_pangea || macio->type == macio_intrepid) | ||
| 1764 | save_fcr[5] = MACIO_IN32(KEYLARGO_FCR5); | ||
| 1765 | |||
| 1766 | /* Save state & config of DBDMA channels */ | ||
| 1767 | dbdma_save(macio, save_dbdma); | ||
| 1768 | |||
| 1769 | /* | ||
| 1770 | * Turn off as much as we can | ||
| 1771 | */ | ||
| 1772 | if (macio->type == macio_pangea) | ||
| 1773 | pangea_shutdown(macio, 1); | ||
| 1774 | else if (macio->type == macio_intrepid) | ||
| 1775 | intrepid_shutdown(macio, 1); | ||
| 1776 | else if (macio->type == macio_keylargo) | ||
| 1777 | keylargo_shutdown(macio, 1); | ||
| 1778 | |||
| 1779 | /* | ||
| 1780 | * Put the host bridge to sleep | ||
| 1781 | */ | ||
| 1782 | |||
| 1783 | save_unin_clock_ctl = UN_IN(UNI_N_CLOCK_CNTL); | ||
| 1784 | /* Note: do not switch GMAC off, driver does it when necessary, WOL must keep it | ||
| 1785 | * enabled ! | ||
| 1786 | */ | ||
| 1787 | UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl & | ||
| 1788 | ~(/*UNI_N_CLOCK_CNTL_GMAC|*/UNI_N_CLOCK_CNTL_FW/*|UNI_N_CLOCK_CNTL_PCI*/)); | ||
| 1789 | udelay(100); | ||
| 1790 | UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING); | ||
| 1791 | UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_SLEEP); | ||
| 1792 | mdelay(10); | ||
| 1793 | |||
| 1794 | /* | ||
| 1795 | * FIXME: A bit of black magic with OpenPIC (don't ask me why) | ||
| 1796 | */ | ||
| 1797 | if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) { | ||
| 1798 | MACIO_BIS(0x506e0, 0x00400000); | ||
| 1799 | MACIO_BIS(0x506e0, 0x80000000); | ||
| 1800 | } | ||
| 1801 | return 0; | ||
| 1802 | } | ||
| 1803 | |||
| 1804 | static int | ||
| 1805 | core99_wake_up(void) | ||
| 1806 | { | ||
| 1807 | struct macio_chip* macio; | ||
| 1808 | int i; | ||
| 1809 | |||
| 1810 | macio = &macio_chips[0]; | ||
| 1811 | if (macio->type != macio_keylargo && macio->type != macio_pangea && | ||
| 1812 | macio->type != macio_intrepid) | ||
| 1813 | return -ENODEV; | ||
| 1814 | |||
| 1815 | /* | ||
| 1816 | * Wakeup the host bridge | ||
| 1817 | */ | ||
| 1818 | UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL); | ||
| 1819 | udelay(10); | ||
| 1820 | UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING); | ||
| 1821 | udelay(10); | ||
| 1822 | |||
| 1823 | /* | ||
| 1824 | * Restore KeyLargo | ||
| 1825 | */ | ||
| 1826 | |||
| 1827 | if (macio->type == macio_keylargo) { | ||
| 1828 | MACIO_OUT32(KEYLARGO_MBCR, save_mbcr); | ||
| 1829 | (void)MACIO_IN32(KEYLARGO_MBCR); udelay(10); | ||
| 1830 | } | ||
| 1831 | MACIO_OUT32(KEYLARGO_FCR0, save_fcr[0]); | ||
| 1832 | (void)MACIO_IN32(KEYLARGO_FCR0); udelay(10); | ||
| 1833 | MACIO_OUT32(KEYLARGO_FCR1, save_fcr[1]); | ||
| 1834 | (void)MACIO_IN32(KEYLARGO_FCR1); udelay(10); | ||
| 1835 | MACIO_OUT32(KEYLARGO_FCR2, save_fcr[2]); | ||
| 1836 | (void)MACIO_IN32(KEYLARGO_FCR2); udelay(10); | ||
| 1837 | MACIO_OUT32(KEYLARGO_FCR3, save_fcr[3]); | ||
| 1838 | (void)MACIO_IN32(KEYLARGO_FCR3); udelay(10); | ||
| 1839 | MACIO_OUT32(KEYLARGO_FCR4, save_fcr[4]); | ||
| 1840 | (void)MACIO_IN32(KEYLARGO_FCR4); udelay(10); | ||
| 1841 | if (macio->type == macio_pangea || macio->type == macio_intrepid) { | ||
| 1842 | MACIO_OUT32(KEYLARGO_FCR5, save_fcr[5]); | ||
| 1843 | (void)MACIO_IN32(KEYLARGO_FCR5); udelay(10); | ||
| 1844 | } | ||
| 1845 | |||
| 1846 | dbdma_restore(macio, save_dbdma); | ||
| 1847 | |||
| 1848 | MACIO_OUT32(KEYLARGO_GPIO_LEVELS0, save_gpio_levels[0]); | ||
| 1849 | MACIO_OUT32(KEYLARGO_GPIO_LEVELS1, save_gpio_levels[1]); | ||
| 1850 | for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++) | ||
| 1851 | MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+i, save_gpio_extint[i]); | ||
| 1852 | for (i=0; i<KEYLARGO_GPIO_CNT; i++) | ||
| 1853 | MACIO_OUT8(KEYLARGO_GPIO_0+i, save_gpio_normal[i]); | ||
| 1854 | |||
| 1855 | /* FIXME more black magic with OpenPIC ... */ | ||
| 1856 | if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) { | ||
| 1857 | MACIO_BIC(0x506e0, 0x00400000); | ||
| 1858 | MACIO_BIC(0x506e0, 0x80000000); | ||
| 1859 | } | ||
| 1860 | |||
| 1861 | UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl); | ||
| 1862 | udelay(100); | ||
| 1863 | |||
| 1864 | return 0; | ||
| 1865 | } | ||
| 1866 | |||
| 1867 | static long | ||
| 1868 | core99_sleep_state(struct device_node* node, long param, long value) | ||
| 1869 | { | ||
| 1870 | /* Param == 1 means to enter the "fake sleep" mode that is | ||
| 1871 | * used for CPU speed switch | ||
| 1872 | */ | ||
| 1873 | if (param == 1) { | ||
| 1874 | if (value == 1) { | ||
| 1875 | UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING); | ||
| 1876 | UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_IDLE2); | ||
| 1877 | } else { | ||
| 1878 | UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL); | ||
| 1879 | udelay(10); | ||
| 1880 | UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING); | ||
| 1881 | udelay(10); | ||
| 1882 | } | ||
| 1883 | return 0; | ||
| 1884 | } | ||
| 1885 | if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0) | ||
| 1886 | return -EPERM; | ||
| 1887 | |||
| 1888 | if (value == 1) | ||
| 1889 | return core99_sleep(); | ||
| 1890 | else if (value == 0) | ||
| 1891 | return core99_wake_up(); | ||
| 1892 | return 0; | ||
| 1893 | } | ||
| 1894 | |||
| 1895 | #endif /* CONFIG_POWER4 */ | ||
| 1896 | |||
| 1897 | static long | ||
| 1898 | generic_dev_can_wake(struct device_node* node, long param, long value) | ||
| 1899 | { | ||
| 1900 | /* Todo: eventually check we are really dealing with on-board | ||
| 1901 | * video device ... | ||
| 1902 | */ | ||
| 1903 | |||
| 1904 | if (pmac_mb.board_flags & PMAC_MB_MAY_SLEEP) | ||
| 1905 | pmac_mb.board_flags |= PMAC_MB_CAN_SLEEP; | ||
| 1906 | return 0; | ||
| 1907 | } | ||
| 1908 | |||
| 1909 | static long | ||
| 1910 | generic_get_mb_info(struct device_node* node, long param, long value) | ||
| 1911 | { | ||
| 1912 | switch(param) { | ||
| 1913 | case PMAC_MB_INFO_MODEL: | ||
| 1914 | return pmac_mb.model_id; | ||
| 1915 | case PMAC_MB_INFO_FLAGS: | ||
| 1916 | return pmac_mb.board_flags; | ||
| 1917 | case PMAC_MB_INFO_NAME: | ||
| 1918 | /* hack hack hack... but should work */ | ||
| 1919 | *((const char **)value) = pmac_mb.model_name; | ||
| 1920 | return 0; | ||
| 1921 | } | ||
| 1922 | return -EINVAL; | ||
| 1923 | } | ||
| 1924 | |||
| 1925 | |||
| 1926 | /* | ||
| 1927 | * Table definitions | ||
| 1928 | */ | ||
| 1929 | |||
| 1930 | /* Used on any machine | ||
| 1931 | */ | ||
| 1932 | static struct feature_table_entry any_features[] = { | ||
| 1933 | { PMAC_FTR_GET_MB_INFO, generic_get_mb_info }, | ||
| 1934 | { PMAC_FTR_DEVICE_CAN_WAKE, generic_dev_can_wake }, | ||
| 1935 | { 0, NULL } | ||
| 1936 | }; | ||
| 1937 | |||
| 1938 | #ifndef CONFIG_POWER4 | ||
| 1939 | |||
| 1940 | /* OHare based motherboards. Currently, we only use these on the | ||
| 1941 | * 2400,3400 and 3500 series powerbooks. Some older desktops seem | ||
| 1942 | * to have issues with turning on/off those asic cells | ||
| 1943 | */ | ||
| 1944 | static struct feature_table_entry ohare_features[] = { | ||
| 1945 | { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable }, | ||
| 1946 | { PMAC_FTR_SWIM3_ENABLE, ohare_floppy_enable }, | ||
| 1947 | { PMAC_FTR_MESH_ENABLE, ohare_mesh_enable }, | ||
| 1948 | { PMAC_FTR_IDE_ENABLE, ohare_ide_enable}, | ||
| 1949 | { PMAC_FTR_IDE_RESET, ohare_ide_reset}, | ||
| 1950 | { PMAC_FTR_SLEEP_STATE, ohare_sleep_state }, | ||
| 1951 | { 0, NULL } | ||
| 1952 | }; | ||
| 1953 | |||
| 1954 | /* Heathrow desktop machines (Beige G3). | ||
| 1955 | * Separated as some features couldn't be properly tested | ||
| 1956 | * and the serial port control bits appear to confuse it. | ||
| 1957 | */ | ||
| 1958 | static struct feature_table_entry heathrow_desktop_features[] = { | ||
| 1959 | { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable }, | ||
| 1960 | { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable }, | ||
| 1961 | { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable }, | ||
| 1962 | { PMAC_FTR_IDE_RESET, heathrow_ide_reset }, | ||
| 1963 | { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable }, | ||
| 1964 | { 0, NULL } | ||
| 1965 | }; | ||
| 1966 | |||
| 1967 | /* Heathrow based laptop, that is the Wallstreet and mainstreet | ||
| 1968 | * powerbooks. | ||
| 1969 | */ | ||
| 1970 | static struct feature_table_entry heathrow_laptop_features[] = { | ||
| 1971 | { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable }, | ||
| 1972 | { PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable }, | ||
| 1973 | { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable }, | ||
| 1974 | { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable }, | ||
| 1975 | { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable }, | ||
| 1976 | { PMAC_FTR_IDE_RESET, heathrow_ide_reset }, | ||
| 1977 | { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable }, | ||
| 1978 | { PMAC_FTR_SOUND_CHIP_ENABLE, heathrow_sound_enable }, | ||
| 1979 | { PMAC_FTR_SLEEP_STATE, heathrow_sleep_state }, | ||
| 1980 | { 0, NULL } | ||
| 1981 | }; | ||
| 1982 | |||
| 1983 | /* Paddington based machines | ||
| 1984 | * The lombard (101) powerbook, first iMac models, B&W G3 and Yikes G4. | ||
| 1985 | */ | ||
| 1986 | static struct feature_table_entry paddington_features[] = { | ||
| 1987 | { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable }, | ||
| 1988 | { PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable }, | ||
| 1989 | { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable }, | ||
| 1990 | { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable }, | ||
| 1991 | { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable }, | ||
| 1992 | { PMAC_FTR_IDE_RESET, heathrow_ide_reset }, | ||
| 1993 | { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable }, | ||
| 1994 | { PMAC_FTR_SOUND_CHIP_ENABLE, heathrow_sound_enable }, | ||
| 1995 | { PMAC_FTR_SLEEP_STATE, heathrow_sleep_state }, | ||
| 1996 | { 0, NULL } | ||
| 1997 | }; | ||
| 1998 | |||
| 1999 | /* Core99 & MacRISC 2 machines (all machines released since the | ||
| 2000 | * iBook (included), that is all AGP machines, except pangea | ||
| 2001 | * chipset. The pangea chipset is the "combo" UniNorth/KeyLargo | ||
| 2002 | * used on iBook2 & iMac "flow power". | ||
| 2003 | */ | ||
| 2004 | static struct feature_table_entry core99_features[] = { | ||
| 2005 | { PMAC_FTR_SCC_ENABLE, core99_scc_enable }, | ||
| 2006 | { PMAC_FTR_MODEM_ENABLE, core99_modem_enable }, | ||
| 2007 | { PMAC_FTR_IDE_ENABLE, core99_ide_enable }, | ||
| 2008 | { PMAC_FTR_IDE_RESET, core99_ide_reset }, | ||
| 2009 | { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable }, | ||
| 2010 | { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset }, | ||
| 2011 | { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable }, | ||
| 2012 | { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable }, | ||
| 2013 | { PMAC_FTR_USB_ENABLE, core99_usb_enable }, | ||
| 2014 | { PMAC_FTR_1394_ENABLE, core99_firewire_enable }, | ||
| 2015 | { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power }, | ||
| 2016 | { PMAC_FTR_SLEEP_STATE, core99_sleep_state }, | ||
| 2017 | #ifdef CONFIG_SMP | ||
| 2018 | { PMAC_FTR_RESET_CPU, core99_reset_cpu }, | ||
| 2019 | #endif /* CONFIG_SMP */ | ||
| 2020 | { PMAC_FTR_READ_GPIO, core99_read_gpio }, | ||
| 2021 | { PMAC_FTR_WRITE_GPIO, core99_write_gpio }, | ||
| 2022 | { 0, NULL } | ||
| 2023 | }; | ||
| 2024 | |||
| 2025 | /* RackMac | ||
| 2026 | */ | ||
| 2027 | static struct feature_table_entry rackmac_features[] = { | ||
| 2028 | { PMAC_FTR_SCC_ENABLE, core99_scc_enable }, | ||
| 2029 | { PMAC_FTR_IDE_ENABLE, core99_ide_enable }, | ||
| 2030 | { PMAC_FTR_IDE_RESET, core99_ide_reset }, | ||
| 2031 | { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable }, | ||
| 2032 | { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset }, | ||
| 2033 | { PMAC_FTR_USB_ENABLE, core99_usb_enable }, | ||
| 2034 | { PMAC_FTR_1394_ENABLE, core99_firewire_enable }, | ||
| 2035 | { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power }, | ||
| 2036 | { PMAC_FTR_SLEEP_STATE, core99_sleep_state }, | ||
| 2037 | #ifdef CONFIG_SMP | ||
| 2038 | { PMAC_FTR_RESET_CPU, core99_reset_cpu }, | ||
| 2039 | #endif /* CONFIG_SMP */ | ||
| 2040 | { PMAC_FTR_READ_GPIO, core99_read_gpio }, | ||
| 2041 | { PMAC_FTR_WRITE_GPIO, core99_write_gpio }, | ||
| 2042 | { 0, NULL } | ||
| 2043 | }; | ||
| 2044 | |||
| 2045 | /* Pangea features | ||
| 2046 | */ | ||
| 2047 | static struct feature_table_entry pangea_features[] = { | ||
| 2048 | { PMAC_FTR_SCC_ENABLE, core99_scc_enable }, | ||
| 2049 | { PMAC_FTR_MODEM_ENABLE, pangea_modem_enable }, | ||
| 2050 | { PMAC_FTR_IDE_ENABLE, core99_ide_enable }, | ||
| 2051 | { PMAC_FTR_IDE_RESET, core99_ide_reset }, | ||
| 2052 | { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable }, | ||
| 2053 | { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset }, | ||
| 2054 | { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable }, | ||
| 2055 | { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable }, | ||
| 2056 | { PMAC_FTR_USB_ENABLE, core99_usb_enable }, | ||
| 2057 | { PMAC_FTR_1394_ENABLE, core99_firewire_enable }, | ||
| 2058 | { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power }, | ||
| 2059 | { PMAC_FTR_SLEEP_STATE, core99_sleep_state }, | ||
| 2060 | { PMAC_FTR_READ_GPIO, core99_read_gpio }, | ||
| 2061 | { PMAC_FTR_WRITE_GPIO, core99_write_gpio }, | ||
| 2062 | { 0, NULL } | ||
| 2063 | }; | ||
| 2064 | |||
| 2065 | /* Intrepid features | ||
| 2066 | */ | ||
| 2067 | static struct feature_table_entry intrepid_features[] = { | ||
| 2068 | { PMAC_FTR_SCC_ENABLE, core99_scc_enable }, | ||
| 2069 | { PMAC_FTR_MODEM_ENABLE, pangea_modem_enable }, | ||
| 2070 | { PMAC_FTR_IDE_ENABLE, core99_ide_enable }, | ||
| 2071 | { PMAC_FTR_IDE_RESET, core99_ide_reset }, | ||
| 2072 | { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable }, | ||
| 2073 | { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset }, | ||
| 2074 | { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable }, | ||
| 2075 | { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable }, | ||
| 2076 | { PMAC_FTR_USB_ENABLE, core99_usb_enable }, | ||
| 2077 | { PMAC_FTR_1394_ENABLE, core99_firewire_enable }, | ||
| 2078 | { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power }, | ||
| 2079 | { PMAC_FTR_SLEEP_STATE, core99_sleep_state }, | ||
| 2080 | { PMAC_FTR_READ_GPIO, core99_read_gpio }, | ||
| 2081 | { PMAC_FTR_WRITE_GPIO, core99_write_gpio }, | ||
| 2082 | { PMAC_FTR_AACK_DELAY_ENABLE, intrepid_aack_delay_enable }, | ||
| 2083 | { 0, NULL } | ||
| 2084 | }; | ||
| 2085 | |||
| 2086 | #else /* CONFIG_POWER4 */ | ||
| 2087 | |||
| 2088 | /* G5 features | ||
| 2089 | */ | ||
| 2090 | static struct feature_table_entry g5_features[] = { | ||
| 2091 | { PMAC_FTR_GMAC_ENABLE, g5_gmac_enable }, | ||
| 2092 | { PMAC_FTR_1394_ENABLE, g5_fw_enable }, | ||
| 2093 | { PMAC_FTR_ENABLE_MPIC, g5_mpic_enable }, | ||
| 2094 | #ifdef CONFIG_SMP | ||
| 2095 | { PMAC_FTR_RESET_CPU, g5_reset_cpu }, | ||
| 2096 | #endif /* CONFIG_SMP */ | ||
| 2097 | { PMAC_FTR_READ_GPIO, core99_read_gpio }, | ||
| 2098 | { PMAC_FTR_WRITE_GPIO, core99_write_gpio }, | ||
| 2099 | { 0, NULL } | ||
| 2100 | }; | ||
| 2101 | |||
| 2102 | #endif /* CONFIG_POWER4 */ | ||
| 2103 | |||
| 2104 | static struct pmac_mb_def pmac_mb_defs[] = { | ||
| 2105 | #ifndef CONFIG_POWER4 | ||
| 2106 | /* | ||
| 2107 | * Desktops | ||
| 2108 | */ | ||
| 2109 | |||
| 2110 | { "AAPL,8500", "PowerMac 8500/8600", | ||
| 2111 | PMAC_TYPE_PSURGE, NULL, | ||
| 2112 | 0 | ||
| 2113 | }, | ||
| 2114 | { "AAPL,9500", "PowerMac 9500/9600", | ||
| 2115 | PMAC_TYPE_PSURGE, NULL, | ||
| 2116 | 0 | ||
| 2117 | }, | ||
| 2118 | { "AAPL,7200", "PowerMac 7200", | ||
| 2119 | PMAC_TYPE_PSURGE, NULL, | ||
| 2120 | 0 | ||
| 2121 | }, | ||
| 2122 | { "AAPL,7300", "PowerMac 7200/7300", | ||
| 2123 | PMAC_TYPE_PSURGE, NULL, | ||
| 2124 | 0 | ||
| 2125 | }, | ||
| 2126 | { "AAPL,7500", "PowerMac 7500", | ||
| 2127 | PMAC_TYPE_PSURGE, NULL, | ||
| 2128 | 0 | ||
| 2129 | }, | ||
| 2130 | { "AAPL,ShinerESB", "Apple Network Server", | ||
| 2131 | PMAC_TYPE_ANS, NULL, | ||
| 2132 | 0 | ||
| 2133 | }, | ||
| 2134 | { "AAPL,e407", "Alchemy", | ||
| 2135 | PMAC_TYPE_ALCHEMY, NULL, | ||
| 2136 | 0 | ||
| 2137 | }, | ||
| 2138 | { "AAPL,e411", "Gazelle", | ||
| 2139 | PMAC_TYPE_GAZELLE, NULL, | ||
| 2140 | 0 | ||
| 2141 | }, | ||
| 2142 | { "AAPL,Gossamer", "PowerMac G3 (Gossamer)", | ||
| 2143 | PMAC_TYPE_GOSSAMER, heathrow_desktop_features, | ||
| 2144 | 0 | ||
| 2145 | }, | ||
| 2146 | { "AAPL,PowerMac G3", "PowerMac G3 (Silk)", | ||
| 2147 | PMAC_TYPE_SILK, heathrow_desktop_features, | ||
| 2148 | 0 | ||
| 2149 | }, | ||
| 2150 | { "PowerMac1,1", "Blue&White G3", | ||
| 2151 | PMAC_TYPE_YOSEMITE, paddington_features, | ||
| 2152 | 0 | ||
| 2153 | }, | ||
| 2154 | { "PowerMac1,2", "PowerMac G4 PCI Graphics", | ||
| 2155 | PMAC_TYPE_YIKES, paddington_features, | ||
| 2156 | 0 | ||
| 2157 | }, | ||
| 2158 | { "PowerMac2,1", "iMac FireWire", | ||
| 2159 | PMAC_TYPE_FW_IMAC, core99_features, | ||
| 2160 | PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99 | ||
| 2161 | }, | ||
| 2162 | { "PowerMac2,2", "iMac FireWire", | ||
| 2163 | PMAC_TYPE_FW_IMAC, core99_features, | ||
| 2164 | PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99 | ||
| 2165 | }, | ||
| 2166 | { "PowerMac3,1", "PowerMac G4 AGP Graphics", | ||
| 2167 | PMAC_TYPE_SAWTOOTH, core99_features, | ||
| 2168 | PMAC_MB_OLD_CORE99 | ||
| 2169 | }, | ||
| 2170 | { "PowerMac3,2", "PowerMac G4 AGP Graphics", | ||
| 2171 | PMAC_TYPE_SAWTOOTH, core99_features, | ||
| 2172 | PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99 | ||
| 2173 | }, | ||
| 2174 | { "PowerMac3,3", "PowerMac G4 AGP Graphics", | ||
| 2175 | PMAC_TYPE_SAWTOOTH, core99_features, | ||
| 2176 | PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99 | ||
| 2177 | }, | ||
| 2178 | { "PowerMac3,4", "PowerMac G4 Silver", | ||
| 2179 | PMAC_TYPE_QUICKSILVER, core99_features, | ||
| 2180 | PMAC_MB_MAY_SLEEP | ||
| 2181 | }, | ||
| 2182 | { "PowerMac3,5", "PowerMac G4 Silver", | ||
| 2183 | PMAC_TYPE_QUICKSILVER, core99_features, | ||
| 2184 | PMAC_MB_MAY_SLEEP | ||
| 2185 | }, | ||
| 2186 | { "PowerMac3,6", "PowerMac G4 Windtunnel", | ||
| 2187 | PMAC_TYPE_WINDTUNNEL, core99_features, | ||
| 2188 | PMAC_MB_MAY_SLEEP, | ||
| 2189 | }, | ||
| 2190 | { "PowerMac4,1", "iMac \"Flower Power\"", | ||
| 2191 | PMAC_TYPE_PANGEA_IMAC, pangea_features, | ||
| 2192 | PMAC_MB_MAY_SLEEP | ||
| 2193 | }, | ||
| 2194 | { "PowerMac4,2", "Flat panel iMac", | ||
| 2195 | PMAC_TYPE_FLAT_PANEL_IMAC, pangea_features, | ||
| 2196 | PMAC_MB_CAN_SLEEP | ||
| 2197 | }, | ||
| 2198 | { "PowerMac4,4", "eMac", | ||
| 2199 | PMAC_TYPE_EMAC, core99_features, | ||
| 2200 | PMAC_MB_MAY_SLEEP | ||
| 2201 | }, | ||
| 2202 | { "PowerMac5,1", "PowerMac G4 Cube", | ||
| 2203 | PMAC_TYPE_CUBE, core99_features, | ||
| 2204 | PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99 | ||
| 2205 | }, | ||
| 2206 | { "PowerMac6,1", "Flat panel iMac", | ||
| 2207 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2208 | PMAC_MB_MAY_SLEEP, | ||
| 2209 | }, | ||
| 2210 | { "PowerMac6,3", "Flat panel iMac", | ||
| 2211 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2212 | PMAC_MB_MAY_SLEEP, | ||
| 2213 | }, | ||
| 2214 | { "PowerMac6,4", "eMac", | ||
| 2215 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2216 | PMAC_MB_MAY_SLEEP, | ||
| 2217 | }, | ||
| 2218 | { "PowerMac10,1", "Mac mini", | ||
| 2219 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2220 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER, | ||
| 2221 | }, | ||
| 2222 | { "iMac,1", "iMac (first generation)", | ||
| 2223 | PMAC_TYPE_ORIG_IMAC, paddington_features, | ||
| 2224 | 0 | ||
| 2225 | }, | ||
| 2226 | |||
| 2227 | /* | ||
| 2228 | * Xserve's | ||
| 2229 | */ | ||
| 2230 | |||
| 2231 | { "RackMac1,1", "XServe", | ||
| 2232 | PMAC_TYPE_RACKMAC, rackmac_features, | ||
| 2233 | 0, | ||
| 2234 | }, | ||
| 2235 | { "RackMac1,2", "XServe rev. 2", | ||
| 2236 | PMAC_TYPE_RACKMAC, rackmac_features, | ||
| 2237 | 0, | ||
| 2238 | }, | ||
| 2239 | |||
| 2240 | /* | ||
| 2241 | * Laptops | ||
| 2242 | */ | ||
| 2243 | |||
| 2244 | { "AAPL,3400/2400", "PowerBook 3400", | ||
| 2245 | PMAC_TYPE_HOOPER, ohare_features, | ||
| 2246 | PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE | ||
| 2247 | }, | ||
| 2248 | { "AAPL,3500", "PowerBook 3500", | ||
| 2249 | PMAC_TYPE_KANGA, ohare_features, | ||
| 2250 | PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE | ||
| 2251 | }, | ||
| 2252 | { "AAPL,PowerBook1998", "PowerBook Wallstreet", | ||
| 2253 | PMAC_TYPE_WALLSTREET, heathrow_laptop_features, | ||
| 2254 | PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE | ||
| 2255 | }, | ||
| 2256 | { "PowerBook1,1", "PowerBook 101 (Lombard)", | ||
| 2257 | PMAC_TYPE_101_PBOOK, paddington_features, | ||
| 2258 | PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE | ||
| 2259 | }, | ||
| 2260 | { "PowerBook2,1", "iBook (first generation)", | ||
| 2261 | PMAC_TYPE_ORIG_IBOOK, core99_features, | ||
| 2262 | PMAC_MB_CAN_SLEEP | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE | ||
| 2263 | }, | ||
| 2264 | { "PowerBook2,2", "iBook FireWire", | ||
| 2265 | PMAC_TYPE_FW_IBOOK, core99_features, | ||
| 2266 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | | ||
| 2267 | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE | ||
| 2268 | }, | ||
| 2269 | { "PowerBook3,1", "PowerBook Pismo", | ||
| 2270 | PMAC_TYPE_PISMO, core99_features, | ||
| 2271 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | | ||
| 2272 | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE | ||
| 2273 | }, | ||
| 2274 | { "PowerBook3,2", "PowerBook Titanium", | ||
| 2275 | PMAC_TYPE_TITANIUM, core99_features, | ||
| 2276 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE | ||
| 2277 | }, | ||
| 2278 | { "PowerBook3,3", "PowerBook Titanium II", | ||
| 2279 | PMAC_TYPE_TITANIUM2, core99_features, | ||
| 2280 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE | ||
| 2281 | }, | ||
| 2282 | { "PowerBook3,4", "PowerBook Titanium III", | ||
| 2283 | PMAC_TYPE_TITANIUM3, core99_features, | ||
| 2284 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE | ||
| 2285 | }, | ||
| 2286 | { "PowerBook3,5", "PowerBook Titanium IV", | ||
| 2287 | PMAC_TYPE_TITANIUM4, core99_features, | ||
| 2288 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE | ||
| 2289 | }, | ||
| 2290 | { "PowerBook4,1", "iBook 2", | ||
| 2291 | PMAC_TYPE_IBOOK2, pangea_features, | ||
| 2292 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE | ||
| 2293 | }, | ||
| 2294 | { "PowerBook4,2", "iBook 2", | ||
| 2295 | PMAC_TYPE_IBOOK2, pangea_features, | ||
| 2296 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE | ||
| 2297 | }, | ||
| 2298 | { "PowerBook4,3", "iBook 2 rev. 2", | ||
| 2299 | PMAC_TYPE_IBOOK2, pangea_features, | ||
| 2300 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE | ||
| 2301 | }, | ||
| 2302 | { "PowerBook5,1", "PowerBook G4 17\"", | ||
| 2303 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2304 | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | ||
| 2305 | }, | ||
| 2306 | { "PowerBook5,2", "PowerBook G4 15\"", | ||
| 2307 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2308 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | ||
| 2309 | }, | ||
| 2310 | { "PowerBook5,3", "PowerBook G4 17\"", | ||
| 2311 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2312 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | ||
| 2313 | }, | ||
| 2314 | { "PowerBook5,4", "PowerBook G4 15\"", | ||
| 2315 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2316 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | ||
| 2317 | }, | ||
| 2318 | { "PowerBook5,5", "PowerBook G4 17\"", | ||
| 2319 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2320 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | ||
| 2321 | }, | ||
| 2322 | { "PowerBook5,6", "PowerBook G4 15\"", | ||
| 2323 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2324 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | ||
| 2325 | }, | ||
| 2326 | { "PowerBook5,7", "PowerBook G4 17\"", | ||
| 2327 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2328 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | ||
| 2329 | }, | ||
| 2330 | { "PowerBook5,8", "PowerBook G4 15\"", | ||
| 2331 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2332 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | ||
| 2333 | }, | ||
| 2334 | { "PowerBook5,9", "PowerBook G4 17\"", | ||
| 2335 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2336 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | ||
| 2337 | }, | ||
| 2338 | { "PowerBook6,1", "PowerBook G4 12\"", | ||
| 2339 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2340 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | ||
| 2341 | }, | ||
| 2342 | { "PowerBook6,2", "PowerBook G4", | ||
| 2343 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2344 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | ||
| 2345 | }, | ||
| 2346 | { "PowerBook6,3", "iBook G4", | ||
| 2347 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2348 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | ||
| 2349 | }, | ||
| 2350 | { "PowerBook6,4", "PowerBook G4 12\"", | ||
| 2351 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2352 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | ||
| 2353 | }, | ||
| 2354 | { "PowerBook6,5", "iBook G4", | ||
| 2355 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2356 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | ||
| 2357 | }, | ||
| 2358 | { "PowerBook6,7", "iBook G4", | ||
| 2359 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2360 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | ||
| 2361 | }, | ||
| 2362 | { "PowerBook6,8", "PowerBook G4 12\"", | ||
| 2363 | PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features, | ||
| 2364 | PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE, | ||
| 2365 | }, | ||
| 2366 | #else /* CONFIG_POWER4 */ | ||
| 2367 | { "PowerMac7,2", "PowerMac G5", | ||
| 2368 | PMAC_TYPE_POWERMAC_G5, g5_features, | ||
| 2369 | 0, | ||
| 2370 | }, | ||
| 2371 | #endif /* CONFIG_POWER4 */ | ||
| 2372 | }; | ||
| 2373 | |||
| 2374 | /* | ||
| 2375 | * The toplevel feature_call callback | ||
| 2376 | */ | ||
| 2377 | long | ||
| 2378 | pmac_do_feature_call(unsigned int selector, ...) | ||
| 2379 | { | ||
| 2380 | struct device_node* node; | ||
| 2381 | long param, value; | ||
| 2382 | int i; | ||
| 2383 | feature_call func = NULL; | ||
| 2384 | va_list args; | ||
| 2385 | |||
| 2386 | if (pmac_mb.features) | ||
| 2387 | for (i=0; pmac_mb.features[i].function; i++) | ||
| 2388 | if (pmac_mb.features[i].selector == selector) { | ||
| 2389 | func = pmac_mb.features[i].function; | ||
| 2390 | break; | ||
| 2391 | } | ||
| 2392 | if (!func) | ||
| 2393 | for (i=0; any_features[i].function; i++) | ||
| 2394 | if (any_features[i].selector == selector) { | ||
| 2395 | func = any_features[i].function; | ||
| 2396 | break; | ||
| 2397 | } | ||
| 2398 | if (!func) | ||
| 2399 | return -ENODEV; | ||
| 2400 | |||
| 2401 | va_start(args, selector); | ||
| 2402 | node = (struct device_node*)va_arg(args, void*); | ||
| 2403 | param = va_arg(args, long); | ||
| 2404 | value = va_arg(args, long); | ||
| 2405 | va_end(args); | ||
| 2406 | |||
| 2407 | return func(node, param, value); | ||
| 2408 | } | ||
| 2409 | |||
| 2410 | static int __init | ||
| 2411 | probe_motherboard(void) | ||
| 2412 | { | ||
| 2413 | int i; | ||
| 2414 | struct macio_chip* macio = &macio_chips[0]; | ||
| 2415 | const char* model = NULL; | ||
| 2416 | struct device_node *dt; | ||
| 2417 | |||
| 2418 | /* Lookup known motherboard type in device-tree. First try an | ||
| 2419 | * exact match on the "model" property, then try a "compatible" | ||
| 2420 | * match is none is found. | ||
| 2421 | */ | ||
| 2422 | dt = find_devices("device-tree"); | ||
| 2423 | if (dt != NULL) | ||
| 2424 | model = (const char *) get_property(dt, "model", NULL); | ||
| 2425 | for(i=0; model && i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) { | ||
| 2426 | if (strcmp(model, pmac_mb_defs[i].model_string) == 0) { | ||
| 2427 | pmac_mb = pmac_mb_defs[i]; | ||
| 2428 | goto found; | ||
| 2429 | } | ||
| 2430 | } | ||
| 2431 | for(i=0; i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) { | ||
| 2432 | if (machine_is_compatible(pmac_mb_defs[i].model_string)) { | ||
| 2433 | pmac_mb = pmac_mb_defs[i]; | ||
| 2434 | goto found; | ||
| 2435 | } | ||
| 2436 | } | ||
| 2437 | |||
| 2438 | /* Fallback to selection depending on mac-io chip type */ | ||
| 2439 | switch(macio->type) { | ||
| 2440 | #ifndef CONFIG_POWER4 | ||
| 2441 | case macio_grand_central: | ||
| 2442 | pmac_mb.model_id = PMAC_TYPE_PSURGE; | ||
| 2443 | pmac_mb.model_name = "Unknown PowerSurge"; | ||
| 2444 | break; | ||
| 2445 | case macio_ohare: | ||
| 2446 | pmac_mb.model_id = PMAC_TYPE_UNKNOWN_OHARE; | ||
| 2447 | pmac_mb.model_name = "Unknown OHare-based"; | ||
| 2448 | break; | ||
| 2449 | case macio_heathrow: | ||
| 2450 | pmac_mb.model_id = PMAC_TYPE_UNKNOWN_HEATHROW; | ||
| 2451 | pmac_mb.model_name = "Unknown Heathrow-based"; | ||
| 2452 | pmac_mb.features = heathrow_desktop_features; | ||
| 2453 | break; | ||
| 2454 | case macio_paddington: | ||
| 2455 | pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PADDINGTON; | ||
| 2456 | pmac_mb.model_name = "Unknown Paddington-based"; | ||
| 2457 | pmac_mb.features = paddington_features; | ||
| 2458 | break; | ||
| 2459 | case macio_keylargo: | ||
| 2460 | pmac_mb.model_id = PMAC_TYPE_UNKNOWN_CORE99; | ||
| 2461 | pmac_mb.model_name = "Unknown Keylargo-based"; | ||
| 2462 | pmac_mb.features = core99_features; | ||
| 2463 | break; | ||
| 2464 | case macio_pangea: | ||
| 2465 | pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PANGEA; | ||
| 2466 | pmac_mb.model_name = "Unknown Pangea-based"; | ||
| 2467 | pmac_mb.features = pangea_features; | ||
| 2468 | break; | ||
| 2469 | case macio_intrepid: | ||
| 2470 | pmac_mb.model_id = PMAC_TYPE_UNKNOWN_INTREPID; | ||
| 2471 | pmac_mb.model_name = "Unknown Intrepid-based"; | ||
| 2472 | pmac_mb.features = intrepid_features; | ||
| 2473 | break; | ||
| 2474 | #else /* CONFIG_POWER4 */ | ||
| 2475 | case macio_keylargo2: | ||
| 2476 | pmac_mb.model_id = PMAC_TYPE_UNKNOWN_K2; | ||
| 2477 | pmac_mb.model_name = "Unknown G5"; | ||
| 2478 | pmac_mb.features = g5_features; | ||
| 2479 | break; | ||
| 2480 | #endif /* CONFIG_POWER4 */ | ||
| 2481 | default: | ||
| 2482 | return -ENODEV; | ||
| 2483 | } | ||
| 2484 | found: | ||
| 2485 | #ifndef CONFIG_POWER4 | ||
| 2486 | /* Fixup Hooper vs. Comet */ | ||
| 2487 | if (pmac_mb.model_id == PMAC_TYPE_HOOPER) { | ||
| 2488 | u32 __iomem * mach_id_ptr = ioremap(0xf3000034, 4); | ||
| 2489 | if (!mach_id_ptr) | ||
| 2490 | return -ENODEV; | ||
| 2491 | /* Here, I used to disable the media-bay on comet. It | ||
| 2492 | * appears this is wrong, the floppy connector is actually | ||
| 2493 | * a kind of media-bay and works with the current driver. | ||
| 2494 | */ | ||
| 2495 | if (__raw_readl(mach_id_ptr) & 0x20000000UL) | ||
| 2496 | pmac_mb.model_id = PMAC_TYPE_COMET; | ||
| 2497 | iounmap(mach_id_ptr); | ||
| 2498 | } | ||
| 2499 | #endif /* CONFIG_POWER4 */ | ||
| 2500 | |||
| 2501 | #ifdef CONFIG_6xx | ||
| 2502 | /* Set default value of powersave_nap on machines that support it. | ||
| 2503 | * It appears that uninorth rev 3 has a problem with it, we don't | ||
| 2504 | * enable it on those. In theory, the flush-on-lock property is | ||
| 2505 | * supposed to be set when not supported, but I'm not very confident | ||
| 2506 | * that all Apple OF revs did it properly, I do it the paranoid way. | ||
| 2507 | */ | ||
| 2508 | while (uninorth_base && uninorth_rev > 3) { | ||
| 2509 | struct device_node* np = find_path_device("/cpus"); | ||
| 2510 | if (!np || !np->child) { | ||
| 2511 | printk(KERN_WARNING "Can't find CPU(s) in device tree !\n"); | ||
| 2512 | break; | ||
| 2513 | } | ||
| 2514 | np = np->child; | ||
| 2515 | /* Nap mode not supported on SMP */ | ||
| 2516 | if (np->sibling) | ||
| 2517 | break; | ||
| 2518 | /* Nap mode not supported if flush-on-lock property is present */ | ||
| 2519 | if (get_property(np, "flush-on-lock", NULL)) | ||
| 2520 | break; | ||
| 2521 | powersave_nap = 1; | ||
| 2522 | printk(KERN_INFO "Processor NAP mode on idle enabled.\n"); | ||
| 2523 | break; | ||
| 2524 | } | ||
| 2525 | |||
| 2526 | /* On CPUs that support it (750FX), lowspeed by default during | ||
| 2527 | * NAP mode | ||
| 2528 | */ | ||
| 2529 | powersave_lowspeed = 1; | ||
| 2530 | #endif /* CONFIG_6xx */ | ||
| 2531 | #ifdef CONFIG_POWER4 | ||
| 2532 | powersave_nap = 1; | ||
| 2533 | #endif | ||
| 2534 | /* Check for "mobile" machine */ | ||
| 2535 | if (model && (strncmp(model, "PowerBook", 9) == 0 | ||
| 2536 | || strncmp(model, "iBook", 5) == 0)) | ||
| 2537 | pmac_mb.board_flags |= PMAC_MB_MOBILE; | ||
| 2538 | |||
| 2539 | |||
| 2540 | printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name); | ||
| 2541 | return 0; | ||
| 2542 | } | ||
| 2543 | |||
| 2544 | /* Initialize the Core99 UniNorth host bridge and memory controller | ||
| 2545 | */ | ||
| 2546 | static void __init | ||
| 2547 | probe_uninorth(void) | ||
| 2548 | { | ||
| 2549 | unsigned long actrl; | ||
| 2550 | |||
| 2551 | /* Locate core99 Uni-N */ | ||
| 2552 | uninorth_node = of_find_node_by_name(NULL, "uni-n"); | ||
| 2553 | /* Locate G5 u3 */ | ||
| 2554 | if (uninorth_node == NULL) { | ||
| 2555 | uninorth_node = of_find_node_by_name(NULL, "u3"); | ||
| 2556 | uninorth_u3 = 1; | ||
| 2557 | } | ||
| 2558 | if (uninorth_node && uninorth_node->n_addrs > 0) { | ||
| 2559 | unsigned long address = uninorth_node->addrs[0].address; | ||
| 2560 | uninorth_base = ioremap(address, 0x40000); | ||
| 2561 | uninorth_rev = in_be32(UN_REG(UNI_N_VERSION)); | ||
| 2562 | if (uninorth_u3) | ||
| 2563 | u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000); | ||
| 2564 | } else | ||
| 2565 | uninorth_node = NULL; | ||
| 2566 | |||
| 2567 | if (!uninorth_node) | ||
| 2568 | return; | ||
| 2569 | |||
| 2570 | printk(KERN_INFO "Found %s memory controller & host bridge, revision: %d\n", | ||
| 2571 | uninorth_u3 ? "U3" : "UniNorth", uninorth_rev); | ||
| 2572 | printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base); | ||
| 2573 | |||
| 2574 | /* Set the arbitrer QAck delay according to what Apple does | ||
| 2575 | */ | ||
| 2576 | if (uninorth_rev < 0x11) { | ||
| 2577 | actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK; | ||
| 2578 | actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 : | ||
| 2579 | UNI_N_ARB_CTRL_QACK_DELAY) << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT; | ||
| 2580 | UN_OUT(UNI_N_ARB_CTRL, actrl); | ||
| 2581 | } | ||
| 2582 | |||
| 2583 | /* Some more magic as done by them in recent MacOS X on UniNorth | ||
| 2584 | * revs 1.5 to 2.O and Pangea. Seem to toggle the UniN Maxbus/PCI | ||
| 2585 | * memory timeout | ||
| 2586 | */ | ||
| 2587 | if ((uninorth_rev >= 0x11 && uninorth_rev <= 0x24) || uninorth_rev == 0xc0) | ||
| 2588 | UN_OUT(0x2160, UN_IN(0x2160) & 0x00ffffff); | ||
| 2589 | } | ||
| 2590 | |||
| 2591 | static void __init | ||
| 2592 | probe_one_macio(const char* name, const char* compat, int type) | ||
| 2593 | { | ||
| 2594 | struct device_node* node; | ||
| 2595 | int i; | ||
| 2596 | volatile u32 __iomem * base; | ||
| 2597 | u32* revp; | ||
| 2598 | |||
| 2599 | node = find_devices(name); | ||
| 2600 | if (!node || !node->n_addrs) | ||
| 2601 | return; | ||
| 2602 | if (compat) | ||
| 2603 | do { | ||
| 2604 | if (device_is_compatible(node, compat)) | ||
| 2605 | break; | ||
| 2606 | node = node->next; | ||
| 2607 | } while (node); | ||
| 2608 | if (!node) | ||
| 2609 | return; | ||
| 2610 | for(i=0; i<MAX_MACIO_CHIPS; i++) { | ||
| 2611 | if (!macio_chips[i].of_node) | ||
| 2612 | break; | ||
| 2613 | if (macio_chips[i].of_node == node) | ||
| 2614 | return; | ||
| 2615 | } | ||
| 2616 | if (i >= MAX_MACIO_CHIPS) { | ||
| 2617 | printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n"); | ||
| 2618 | printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name); | ||
| 2619 | return; | ||
| 2620 | } | ||
| 2621 | base = ioremap(node->addrs[0].address, node->addrs[0].size); | ||
| 2622 | if (!base) { | ||
| 2623 | printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n"); | ||
| 2624 | return; | ||
| 2625 | } | ||
| 2626 | if (type == macio_keylargo) { | ||
| 2627 | u32* did = (u32 *)get_property(node, "device-id", NULL); | ||
| 2628 | if (*did == 0x00000025) | ||
| 2629 | type = macio_pangea; | ||
| 2630 | if (*did == 0x0000003e) | ||
| 2631 | type = macio_intrepid; | ||
| 2632 | } | ||
| 2633 | macio_chips[i].of_node = node; | ||
| 2634 | macio_chips[i].type = type; | ||
| 2635 | macio_chips[i].base = base; | ||
| 2636 | macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON; | ||
| 2637 | macio_chips[i].name = macio_names[type]; | ||
| 2638 | revp = (u32 *)get_property(node, "revision-id", NULL); | ||
| 2639 | if (revp) | ||
| 2640 | macio_chips[i].rev = *revp; | ||
| 2641 | printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n", | ||
| 2642 | macio_names[type], macio_chips[i].rev, macio_chips[i].base); | ||
| 2643 | } | ||
| 2644 | |||
| 2645 | static int __init | ||
| 2646 | probe_macios(void) | ||
| 2647 | { | ||
| 2648 | /* Warning, ordering is important */ | ||
| 2649 | probe_one_macio("gc", NULL, macio_grand_central); | ||
| 2650 | probe_one_macio("ohare", NULL, macio_ohare); | ||
| 2651 | probe_one_macio("pci106b,7", NULL, macio_ohareII); | ||
| 2652 | probe_one_macio("mac-io", "keylargo", macio_keylargo); | ||
| 2653 | probe_one_macio("mac-io", "paddington", macio_paddington); | ||
| 2654 | probe_one_macio("mac-io", "gatwick", macio_gatwick); | ||
| 2655 | probe_one_macio("mac-io", "heathrow", macio_heathrow); | ||
| 2656 | probe_one_macio("mac-io", "K2-Keylargo", macio_keylargo2); | ||
| 2657 | |||
| 2658 | /* Make sure the "main" macio chip appear first */ | ||
| 2659 | if (macio_chips[0].type == macio_gatwick | ||
| 2660 | && macio_chips[1].type == macio_heathrow) { | ||
| 2661 | struct macio_chip temp = macio_chips[0]; | ||
| 2662 | macio_chips[0] = macio_chips[1]; | ||
| 2663 | macio_chips[1] = temp; | ||
| 2664 | } | ||
| 2665 | if (macio_chips[0].type == macio_ohareII | ||
| 2666 | && macio_chips[1].type == macio_ohare) { | ||
| 2667 | struct macio_chip temp = macio_chips[0]; | ||
| 2668 | macio_chips[0] = macio_chips[1]; | ||
| 2669 | macio_chips[1] = temp; | ||
| 2670 | } | ||
| 2671 | macio_chips[0].lbus.index = 0; | ||
| 2672 | macio_chips[1].lbus.index = 1; | ||
| 2673 | |||
| 2674 | return (macio_chips[0].of_node == NULL) ? -ENODEV : 0; | ||
| 2675 | } | ||
| 2676 | |||
| 2677 | static void __init | ||
| 2678 | initial_serial_shutdown(struct device_node* np) | ||
| 2679 | { | ||
| 2680 | int len; | ||
| 2681 | struct slot_names_prop { | ||
| 2682 | int count; | ||
| 2683 | char name[1]; | ||
| 2684 | } *slots; | ||
| 2685 | char *conn; | ||
| 2686 | int port_type = PMAC_SCC_ASYNC; | ||
| 2687 | int modem = 0; | ||
| 2688 | |||
| 2689 | slots = (struct slot_names_prop *)get_property(np, "slot-names", &len); | ||
| 2690 | conn = get_property(np, "AAPL,connector", &len); | ||
| 2691 | if (conn && (strcmp(conn, "infrared") == 0)) | ||
| 2692 | port_type = PMAC_SCC_IRDA; | ||
| 2693 | else if (device_is_compatible(np, "cobalt")) | ||
| 2694 | modem = 1; | ||
| 2695 | else if (slots && slots->count > 0) { | ||
| 2696 | if (strcmp(slots->name, "IrDA") == 0) | ||
| 2697 | port_type = PMAC_SCC_IRDA; | ||
| 2698 | else if (strcmp(slots->name, "Modem") == 0) | ||
| 2699 | modem = 1; | ||
| 2700 | } | ||
| 2701 | if (modem) | ||
| 2702 | pmac_call_feature(PMAC_FTR_MODEM_ENABLE, np, 0, 0); | ||
| 2703 | pmac_call_feature(PMAC_FTR_SCC_ENABLE, np, port_type, 0); | ||
| 2704 | } | ||
| 2705 | |||
| 2706 | static void __init | ||
| 2707 | set_initial_features(void) | ||
| 2708 | { | ||
| 2709 | struct device_node* np; | ||
| 2710 | |||
| 2711 | /* That hack appears to be necessary for some StarMax motherboards | ||
| 2712 | * but I'm not too sure it was audited for side-effects on other | ||
| 2713 | * ohare based machines... | ||
| 2714 | * Since I still have difficulties figuring the right way to | ||
| 2715 | * differenciate them all and since that hack was there for a long | ||
| 2716 | * time, I'll keep it around | ||
| 2717 | */ | ||
| 2718 | if (macio_chips[0].type == macio_ohare && !find_devices("via-pmu")) { | ||
| 2719 | struct macio_chip* macio = &macio_chips[0]; | ||
| 2720 | MACIO_OUT32(OHARE_FCR, STARMAX_FEATURES); | ||
| 2721 | } else if (macio_chips[0].type == macio_ohare) { | ||
| 2722 | struct macio_chip* macio = &macio_chips[0]; | ||
| 2723 | MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE); | ||
| 2724 | } else if (macio_chips[1].type == macio_ohare) { | ||
| 2725 | struct macio_chip* macio = &macio_chips[1]; | ||
| 2726 | MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE); | ||
| 2727 | } | ||
| 2728 | |||
| 2729 | #ifdef CONFIG_POWER4 | ||
| 2730 | if (macio_chips[0].type == macio_keylargo2) { | ||
| 2731 | #ifndef CONFIG_SMP | ||
| 2732 | /* On SMP machines running UP, we have the second CPU eating | ||
| 2733 | * bus cycles. We need to take it off the bus. This is done | ||
| 2734 | * from pmac_smp for SMP kernels running on one CPU | ||
| 2735 | */ | ||
| 2736 | np = of_find_node_by_type(NULL, "cpu"); | ||
| 2737 | if (np != NULL) | ||
| 2738 | np = of_find_node_by_type(np, "cpu"); | ||
| 2739 | if (np != NULL) { | ||
| 2740 | g5_phy_disable_cpu1(); | ||
| 2741 | of_node_put(np); | ||
| 2742 | } | ||
| 2743 | #endif /* CONFIG_SMP */ | ||
| 2744 | /* Enable GMAC for now for PCI probing. It will be disabled | ||
| 2745 | * later on after PCI probe | ||
| 2746 | */ | ||
| 2747 | np = of_find_node_by_name(NULL, "ethernet"); | ||
| 2748 | while(np) { | ||
| 2749 | if (device_is_compatible(np, "K2-GMAC")) | ||
| 2750 | g5_gmac_enable(np, 0, 1); | ||
| 2751 | np = of_find_node_by_name(np, "ethernet"); | ||
| 2752 | } | ||
| 2753 | |||
| 2754 | /* Enable FW before PCI probe. Will be disabled later on | ||
| 2755 | * Note: We should have a batter way to check that we are | ||
| 2756 | * dealing with uninorth internal cell and not a PCI cell | ||
| 2757 | * on the external PCI. The code below works though. | ||
| 2758 | */ | ||
| 2759 | np = of_find_node_by_name(NULL, "firewire"); | ||
| 2760 | while(np) { | ||
| 2761 | if (device_is_compatible(np, "pci106b,5811")) { | ||
| 2762 | macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED; | ||
| 2763 | g5_fw_enable(np, 0, 1); | ||
| 2764 | } | ||
| 2765 | np = of_find_node_by_name(np, "firewire"); | ||
| 2766 | } | ||
| 2767 | } | ||
| 2768 | #else /* CONFIG_POWER4 */ | ||
| 2769 | |||
| 2770 | if (macio_chips[0].type == macio_keylargo || | ||
| 2771 | macio_chips[0].type == macio_pangea || | ||
| 2772 | macio_chips[0].type == macio_intrepid) { | ||
| 2773 | /* Enable GMAC for now for PCI probing. It will be disabled | ||
| 2774 | * later on after PCI probe | ||
| 2775 | */ | ||
| 2776 | np = of_find_node_by_name(NULL, "ethernet"); | ||
| 2777 | while(np) { | ||
| 2778 | if (np->parent | ||
| 2779 | && device_is_compatible(np->parent, "uni-north") | ||
| 2780 | && device_is_compatible(np, "gmac")) | ||
| 2781 | core99_gmac_enable(np, 0, 1); | ||
| 2782 | np = of_find_node_by_name(np, "ethernet"); | ||
| 2783 | } | ||
| 2784 | |||
| 2785 | /* Enable FW before PCI probe. Will be disabled later on | ||
| 2786 | * Note: We should have a batter way to check that we are | ||
| 2787 | * dealing with uninorth internal cell and not a PCI cell | ||
| 2788 | * on the external PCI. The code below works though. | ||
| 2789 | */ | ||
| 2790 | np = of_find_node_by_name(NULL, "firewire"); | ||
| 2791 | while(np) { | ||
| 2792 | if (np->parent | ||
| 2793 | && device_is_compatible(np->parent, "uni-north") | ||
| 2794 | && (device_is_compatible(np, "pci106b,18") || | ||
| 2795 | device_is_compatible(np, "pci106b,30") || | ||
| 2796 | device_is_compatible(np, "pci11c1,5811"))) { | ||
| 2797 | macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED; | ||
| 2798 | core99_firewire_enable(np, 0, 1); | ||
| 2799 | } | ||
| 2800 | np = of_find_node_by_name(np, "firewire"); | ||
| 2801 | } | ||
| 2802 | |||
| 2803 | /* Enable ATA-100 before PCI probe. */ | ||
| 2804 | np = of_find_node_by_name(NULL, "ata-6"); | ||
| 2805 | while(np) { | ||
| 2806 | if (np->parent | ||
| 2807 | && device_is_compatible(np->parent, "uni-north") | ||
| 2808 | && device_is_compatible(np, "kauai-ata")) { | ||
| 2809 | core99_ata100_enable(np, 1); | ||
| 2810 | } | ||
| 2811 | np = of_find_node_by_name(np, "ata-6"); | ||
| 2812 | } | ||
| 2813 | |||
| 2814 | /* Switch airport off */ | ||
| 2815 | np = find_devices("radio"); | ||
| 2816 | while(np) { | ||
| 2817 | if (np && np->parent == macio_chips[0].of_node) { | ||
| 2818 | macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON; | ||
| 2819 | core99_airport_enable(np, 0, 0); | ||
| 2820 | } | ||
| 2821 | np = np->next; | ||
| 2822 | } | ||
| 2823 | } | ||
| 2824 | |||
| 2825 | /* On all machines that support sound PM, switch sound off */ | ||
| 2826 | if (macio_chips[0].of_node) | ||
| 2827 | pmac_do_feature_call(PMAC_FTR_SOUND_CHIP_ENABLE, | ||
| 2828 | macio_chips[0].of_node, 0, 0); | ||
| 2829 | |||
| 2830 | /* While on some desktop G3s, we turn it back on */ | ||
| 2831 | if (macio_chips[0].of_node && macio_chips[0].type == macio_heathrow | ||
| 2832 | && (pmac_mb.model_id == PMAC_TYPE_GOSSAMER || | ||
| 2833 | pmac_mb.model_id == PMAC_TYPE_SILK)) { | ||
| 2834 | struct macio_chip* macio = &macio_chips[0]; | ||
| 2835 | MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE); | ||
| 2836 | MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N); | ||
| 2837 | } | ||
| 2838 | |||
| 2839 | /* Some machine models need the clock chip to be properly setup for | ||
| 2840 | * clock spreading now. This should be a platform function but we | ||
| 2841 | * don't do these at the moment | ||
| 2842 | */ | ||
| 2843 | pmac_tweak_clock_spreading(1); | ||
| 2844 | |||
| 2845 | #endif /* CONFIG_POWER4 */ | ||
| 2846 | |||
| 2847 | /* On all machines, switch modem & serial ports off */ | ||
| 2848 | np = find_devices("ch-a"); | ||
| 2849 | while(np) { | ||
| 2850 | initial_serial_shutdown(np); | ||
| 2851 | np = np->next; | ||
| 2852 | } | ||
| 2853 | np = find_devices("ch-b"); | ||
| 2854 | while(np) { | ||
| 2855 | initial_serial_shutdown(np); | ||
| 2856 | np = np->next; | ||
| 2857 | } | ||
| 2858 | } | ||
| 2859 | |||
| 2860 | void __init | ||
| 2861 | pmac_feature_init(void) | ||
| 2862 | { | ||
| 2863 | /* Detect the UniNorth memory controller */ | ||
| 2864 | probe_uninorth(); | ||
| 2865 | |||
| 2866 | /* Probe mac-io controllers */ | ||
| 2867 | if (probe_macios()) { | ||
| 2868 | printk(KERN_WARNING "No mac-io chip found\n"); | ||
| 2869 | return; | ||
| 2870 | } | ||
| 2871 | |||
| 2872 | /* Setup low-level i2c stuffs */ | ||
| 2873 | pmac_init_low_i2c(); | ||
| 2874 | |||
| 2875 | /* Probe machine type */ | ||
| 2876 | if (probe_motherboard()) | ||
| 2877 | printk(KERN_WARNING "Unknown PowerMac !\n"); | ||
| 2878 | |||
| 2879 | /* Set some initial features (turn off some chips that will | ||
| 2880 | * be later turned on) | ||
| 2881 | */ | ||
| 2882 | set_initial_features(); | ||
| 2883 | } | ||
| 2884 | |||
| 2885 | int __init | ||
| 2886 | pmac_feature_late_init(void) | ||
| 2887 | { | ||
| 2888 | struct device_node* np; | ||
| 2889 | |||
| 2890 | /* Request some resources late */ | ||
| 2891 | if (uninorth_node) | ||
| 2892 | request_OF_resource(uninorth_node, 0, NULL); | ||
| 2893 | np = find_devices("hammerhead"); | ||
| 2894 | if (np) | ||
| 2895 | request_OF_resource(np, 0, NULL); | ||
| 2896 | np = find_devices("interrupt-controller"); | ||
| 2897 | if (np) | ||
| 2898 | request_OF_resource(np, 0, NULL); | ||
| 2899 | return 0; | ||
| 2900 | } | ||
| 2901 | |||
| 2902 | device_initcall(pmac_feature_late_init); | ||
| 2903 | |||
| 2904 | #ifdef CONFIG_POWER4 | ||
| 2905 | |||
| 2906 | static void dump_HT_speeds(char *name, u32 cfg, u32 frq) | ||
| 2907 | { | ||
| 2908 | int freqs[16] = { 200,300,400,500,600,800,1000,0,0,0,0,0,0,0,0,0 }; | ||
| 2909 | int bits[8] = { 8,16,0,32,2,4,0,0 }; | ||
| 2910 | int freq = (frq >> 8) & 0xf; | ||
| 2911 | |||
| 2912 | if (freqs[freq] == 0) | ||
| 2913 | printk("%s: Unknown HT link frequency %x\n", name, freq); | ||
| 2914 | else | ||
| 2915 | printk("%s: %d MHz on main link, (%d in / %d out) bits width\n", | ||
| 2916 | name, freqs[freq], | ||
| 2917 | bits[(cfg >> 28) & 0x7], bits[(cfg >> 24) & 0x7]); | ||
| 2918 | } | ||
| 2919 | |||
| 2920 | void __init pmac_check_ht_link(void) | ||
| 2921 | { | ||
| 2922 | u32 ufreq, freq, ucfg, cfg; | ||
| 2923 | struct device_node *pcix_node; | ||
| 2924 | u8 px_bus, px_devfn; | ||
| 2925 | struct pci_controller *px_hose; | ||
| 2926 | |||
| 2927 | (void)in_be32(u3_ht + U3_HT_LINK_COMMAND); | ||
| 2928 | ucfg = cfg = in_be32(u3_ht + U3_HT_LINK_CONFIG); | ||
| 2929 | ufreq = freq = in_be32(u3_ht + U3_HT_LINK_FREQ); | ||
| 2930 | dump_HT_speeds("U3 HyperTransport", cfg, freq); | ||
| 2931 | |||
| 2932 | pcix_node = of_find_compatible_node(NULL, "pci", "pci-x"); | ||
| 2933 | if (pcix_node == NULL) { | ||
| 2934 | printk("No PCI-X bridge found\n"); | ||
| 2935 | return; | ||
| 2936 | } | ||
| 2937 | if (pci_device_from_OF_node(pcix_node, &px_bus, &px_devfn) != 0) { | ||
| 2938 | printk("PCI-X bridge found but not matched to pci\n"); | ||
| 2939 | return; | ||
| 2940 | } | ||
| 2941 | px_hose = pci_find_hose_for_OF_device(pcix_node); | ||
| 2942 | if (px_hose == NULL) { | ||
| 2943 | printk("PCI-X bridge found but not matched to host\n"); | ||
| 2944 | return; | ||
| 2945 | } | ||
| 2946 | early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg); | ||
| 2947 | early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq); | ||
| 2948 | dump_HT_speeds("PCI-X HT Uplink", cfg, freq); | ||
| 2949 | early_read_config_dword(px_hose, px_bus, px_devfn, 0xc8, &cfg); | ||
| 2950 | early_read_config_dword(px_hose, px_bus, px_devfn, 0xd0, &freq); | ||
| 2951 | dump_HT_speeds("PCI-X HT Downlink", cfg, freq); | ||
| 2952 | } | ||
| 2953 | |||
| 2954 | #endif /* CONFIG_POWER4 */ | ||
| 2955 | |||
| 2956 | /* | ||
| 2957 | * Early video resume hook | ||
| 2958 | */ | ||
| 2959 | |||
| 2960 | static void (*pmac_early_vresume_proc)(void *data); | ||
| 2961 | static void *pmac_early_vresume_data; | ||
| 2962 | |||
| 2963 | void pmac_set_early_video_resume(void (*proc)(void *data), void *data) | ||
| 2964 | { | ||
| 2965 | if (_machine != _MACH_Pmac) | ||
| 2966 | return; | ||
| 2967 | preempt_disable(); | ||
| 2968 | pmac_early_vresume_proc = proc; | ||
| 2969 | pmac_early_vresume_data = data; | ||
| 2970 | preempt_enable(); | ||
| 2971 | } | ||
| 2972 | EXPORT_SYMBOL(pmac_set_early_video_resume); | ||
| 2973 | |||
| 2974 | void pmac_call_early_video_resume(void) | ||
| 2975 | { | ||
| 2976 | if (pmac_early_vresume_proc) | ||
| 2977 | pmac_early_vresume_proc(pmac_early_vresume_data); | ||
| 2978 | } | ||
| 2979 | |||
| 2980 | /* | ||
| 2981 | * AGP related suspend/resume code | ||
| 2982 | */ | ||
| 2983 | |||
| 2984 | static struct pci_dev *pmac_agp_bridge; | ||
| 2985 | static int (*pmac_agp_suspend)(struct pci_dev *bridge); | ||
| 2986 | static int (*pmac_agp_resume)(struct pci_dev *bridge); | ||
| 2987 | |||
| 2988 | void pmac_register_agp_pm(struct pci_dev *bridge, | ||
| 2989 | int (*suspend)(struct pci_dev *bridge), | ||
| 2990 | int (*resume)(struct pci_dev *bridge)) | ||
| 2991 | { | ||
| 2992 | if (suspend || resume) { | ||
| 2993 | pmac_agp_bridge = bridge; | ||
| 2994 | pmac_agp_suspend = suspend; | ||
| 2995 | pmac_agp_resume = resume; | ||
| 2996 | return; | ||
| 2997 | } | ||
| 2998 | if (bridge != pmac_agp_bridge) | ||
| 2999 | return; | ||
| 3000 | pmac_agp_suspend = pmac_agp_resume = NULL; | ||
| 3001 | return; | ||
| 3002 | } | ||
| 3003 | EXPORT_SYMBOL(pmac_register_agp_pm); | ||
| 3004 | |||
| 3005 | void pmac_suspend_agp_for_card(struct pci_dev *dev) | ||
| 3006 | { | ||
| 3007 | if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL) | ||
| 3008 | return; | ||
| 3009 | if (pmac_agp_bridge->bus != dev->bus) | ||
| 3010 | return; | ||
| 3011 | pmac_agp_suspend(pmac_agp_bridge); | ||
| 3012 | } | ||
| 3013 | EXPORT_SYMBOL(pmac_suspend_agp_for_card); | ||
| 3014 | |||
| 3015 | void pmac_resume_agp_for_card(struct pci_dev *dev) | ||
| 3016 | { | ||
| 3017 | if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL) | ||
| 3018 | return; | ||
| 3019 | if (pmac_agp_bridge->bus != dev->bus) | ||
| 3020 | return; | ||
| 3021 | pmac_agp_resume(pmac_agp_bridge); | ||
| 3022 | } | ||
| 3023 | EXPORT_SYMBOL(pmac_resume_agp_for_card); | ||
diff --git a/arch/ppc/platforms/pmac_low_i2c.c b/arch/ppc/platforms/pmac_low_i2c.c deleted file mode 100644 index 08583fce1692..000000000000 --- a/arch/ppc/platforms/pmac_low_i2c.c +++ /dev/null | |||
| @@ -1,511 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * arch/ppc/platforms/pmac_low_i2c.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2003 Ben. Herrenschmidt (benh@kernel.crashing.org) | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the License, or (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This file contains some low-level i2c access routines that | ||
| 12 | * need to be used by various bits of the PowerMac platform code | ||
| 13 | * at times where the real asynchronous & interrupt driven driver | ||
| 14 | * cannot be used. The API borrows some semantics from the darwin | ||
| 15 | * driver in order to ease the implementation of the platform | ||
| 16 | * properties parser | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/config.h> | ||
| 20 | #include <linux/types.h> | ||
| 21 | #include <linux/delay.h> | ||
| 22 | #include <linux/sched.h> | ||
| 23 | #include <linux/init.h> | ||
| 24 | #include <linux/module.h> | ||
| 25 | #include <linux/adb.h> | ||
| 26 | #include <linux/pmu.h> | ||
| 27 | #include <asm/keylargo.h> | ||
| 28 | #include <asm/uninorth.h> | ||
| 29 | #include <asm/io.h> | ||
| 30 | #include <asm/prom.h> | ||
| 31 | #include <asm/machdep.h> | ||
| 32 | #include <asm/pmac_low_i2c.h> | ||
| 33 | |||
| 34 | #define MAX_LOW_I2C_HOST 4 | ||
| 35 | |||
| 36 | #if 1 | ||
| 37 | #define DBG(x...) do {\ | ||
| 38 | printk(KERN_DEBUG "KW:" x); \ | ||
| 39 | } while(0) | ||
| 40 | #else | ||
| 41 | #define DBGG(x...) | ||
| 42 | #endif | ||
| 43 | |||
| 44 | struct low_i2c_host; | ||
| 45 | |||
| 46 | typedef int (*low_i2c_func_t)(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len); | ||
| 47 | |||
| 48 | struct low_i2c_host | ||
| 49 | { | ||
| 50 | struct device_node *np; /* OF device node */ | ||
| 51 | struct semaphore mutex; /* Access mutex for use by i2c-keywest */ | ||
| 52 | low_i2c_func_t func; /* Access function */ | ||
| 53 | int is_open : 1; /* Poor man's access control */ | ||
| 54 | int mode; /* Current mode */ | ||
| 55 | int channel; /* Current channel */ | ||
| 56 | int num_channels; /* Number of channels */ | ||
| 57 | void __iomem * base; /* For keywest-i2c, base address */ | ||
| 58 | int bsteps; /* And register stepping */ | ||
| 59 | int speed; /* And speed */ | ||
| 60 | }; | ||
| 61 | |||
| 62 | static struct low_i2c_host low_i2c_hosts[MAX_LOW_I2C_HOST]; | ||
| 63 | |||
| 64 | /* No locking is necessary on allocation, we are running way before | ||
| 65 | * anything can race with us | ||
| 66 | */ | ||
| 67 | static struct low_i2c_host *find_low_i2c_host(struct device_node *np) | ||
| 68 | { | ||
| 69 | int i; | ||
| 70 | |||
| 71 | for (i = 0; i < MAX_LOW_I2C_HOST; i++) | ||
| 72 | if (low_i2c_hosts[i].np == np) | ||
| 73 | return &low_i2c_hosts[i]; | ||
| 74 | return NULL; | ||
| 75 | } | ||
| 76 | |||
| 77 | /* | ||
| 78 | * | ||
| 79 | * i2c-keywest implementation (UniNorth, U2, U3, Keylargo's) | ||
| 80 | * | ||
| 81 | */ | ||
| 82 | |||
| 83 | /* | ||
| 84 | * Keywest i2c definitions borrowed from drivers/i2c/i2c-keywest.h, | ||
| 85 | * should be moved somewhere in include/asm-ppc/ | ||
| 86 | */ | ||
| 87 | /* Register indices */ | ||
| 88 | typedef enum { | ||
| 89 | reg_mode = 0, | ||
| 90 | reg_control, | ||
| 91 | reg_status, | ||
| 92 | reg_isr, | ||
| 93 | reg_ier, | ||
| 94 | reg_addr, | ||
| 95 | reg_subaddr, | ||
| 96 | reg_data | ||
| 97 | } reg_t; | ||
| 98 | |||
| 99 | |||
| 100 | /* Mode register */ | ||
| 101 | #define KW_I2C_MODE_100KHZ 0x00 | ||
| 102 | #define KW_I2C_MODE_50KHZ 0x01 | ||
| 103 | #define KW_I2C_MODE_25KHZ 0x02 | ||
| 104 | #define KW_I2C_MODE_DUMB 0x00 | ||
| 105 | #define KW_I2C_MODE_STANDARD 0x04 | ||
| 106 | #define KW_I2C_MODE_STANDARDSUB 0x08 | ||
| 107 | #define KW_I2C_MODE_COMBINED 0x0C | ||
| 108 | #define KW_I2C_MODE_MODE_MASK 0x0C | ||
| 109 | #define KW_I2C_MODE_CHAN_MASK 0xF0 | ||
| 110 | |||
| 111 | /* Control register */ | ||
| 112 | #define KW_I2C_CTL_AAK 0x01 | ||
| 113 | #define KW_I2C_CTL_XADDR 0x02 | ||
| 114 | #define KW_I2C_CTL_STOP 0x04 | ||
| 115 | #define KW_I2C_CTL_START 0x08 | ||
| 116 | |||
| 117 | /* Status register */ | ||
| 118 | #define KW_I2C_STAT_BUSY 0x01 | ||
| 119 | #define KW_I2C_STAT_LAST_AAK 0x02 | ||
| 120 | #define KW_I2C_STAT_LAST_RW 0x04 | ||
| 121 | #define KW_I2C_STAT_SDA 0x08 | ||
| 122 | #define KW_I2C_STAT_SCL 0x10 | ||
| 123 | |||
| 124 | /* IER & ISR registers */ | ||
| 125 | #define KW_I2C_IRQ_DATA 0x01 | ||
| 126 | #define KW_I2C_IRQ_ADDR 0x02 | ||
| 127 | #define KW_I2C_IRQ_STOP 0x04 | ||
| 128 | #define KW_I2C_IRQ_START 0x08 | ||
| 129 | #define KW_I2C_IRQ_MASK 0x0F | ||
| 130 | |||
| 131 | /* State machine states */ | ||
| 132 | enum { | ||
| 133 | state_idle, | ||
| 134 | state_addr, | ||
| 135 | state_read, | ||
| 136 | state_write, | ||
| 137 | state_stop, | ||
| 138 | state_dead | ||
| 139 | }; | ||
| 140 | |||
| 141 | #define WRONG_STATE(name) do {\ | ||
| 142 | printk(KERN_DEBUG "KW: wrong state. Got %s, state: %s (isr: %02x)\n", \ | ||
| 143 | name, __kw_state_names[state], isr); \ | ||
| 144 | } while(0) | ||
| 145 | |||
| 146 | static const char *__kw_state_names[] = { | ||
| 147 | "state_idle", | ||
| 148 | "state_addr", | ||
| 149 | "state_read", | ||
| 150 | "state_write", | ||
| 151 | "state_stop", | ||
| 152 | "state_dead" | ||
| 153 | }; | ||
| 154 | |||
| 155 | static inline u8 __kw_read_reg(struct low_i2c_host *host, reg_t reg) | ||
| 156 | { | ||
| 157 | return in_8(host->base + (((unsigned)reg) << host->bsteps)); | ||
| 158 | } | ||
| 159 | |||
| 160 | static inline void __kw_write_reg(struct low_i2c_host *host, reg_t reg, u8 val) | ||
| 161 | { | ||
| 162 | out_8(host->base + (((unsigned)reg) << host->bsteps), val); | ||
| 163 | (void)__kw_read_reg(host, reg_subaddr); | ||
| 164 | } | ||
| 165 | |||
| 166 | #define kw_write_reg(reg, val) __kw_write_reg(host, reg, val) | ||
| 167 | #define kw_read_reg(reg) __kw_read_reg(host, reg) | ||
| 168 | |||
| 169 | |||
| 170 | /* Don't schedule, the g5 fan controller is too | ||
| 171 | * timing sensitive | ||
| 172 | */ | ||
| 173 | static u8 kw_wait_interrupt(struct low_i2c_host* host) | ||
| 174 | { | ||
| 175 | int i; | ||
| 176 | u8 isr; | ||
| 177 | |||
| 178 | for (i = 0; i < 200000; i++) { | ||
| 179 | isr = kw_read_reg(reg_isr) & KW_I2C_IRQ_MASK; | ||
| 180 | if (isr != 0) | ||
| 181 | return isr; | ||
| 182 | udelay(1); | ||
| 183 | } | ||
| 184 | return isr; | ||
| 185 | } | ||
| 186 | |||
| 187 | static int kw_handle_interrupt(struct low_i2c_host *host, int state, int rw, int *rc, u8 **data, int *len, u8 isr) | ||
| 188 | { | ||
| 189 | u8 ack; | ||
| 190 | |||
| 191 | if (isr == 0) { | ||
| 192 | if (state != state_stop) { | ||
| 193 | DBG("KW: Timeout !\n"); | ||
| 194 | *rc = -EIO; | ||
| 195 | goto stop; | ||
| 196 | } | ||
| 197 | if (state == state_stop) { | ||
| 198 | ack = kw_read_reg(reg_status); | ||
| 199 | if (!(ack & KW_I2C_STAT_BUSY)) { | ||
| 200 | state = state_idle; | ||
| 201 | kw_write_reg(reg_ier, 0x00); | ||
| 202 | } | ||
| 203 | } | ||
| 204 | return state; | ||
| 205 | } | ||
| 206 | |||
| 207 | if (isr & KW_I2C_IRQ_ADDR) { | ||
| 208 | ack = kw_read_reg(reg_status); | ||
| 209 | if (state != state_addr) { | ||
| 210 | kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR); | ||
| 211 | WRONG_STATE("KW_I2C_IRQ_ADDR"); | ||
| 212 | *rc = -EIO; | ||
| 213 | goto stop; | ||
| 214 | } | ||
| 215 | if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { | ||
| 216 | *rc = -ENODEV; | ||
| 217 | DBG("KW: NAK on address\n"); | ||
| 218 | return state_stop; | ||
| 219 | } else { | ||
| 220 | if (rw) { | ||
| 221 | state = state_read; | ||
| 222 | if (*len > 1) | ||
| 223 | kw_write_reg(reg_control, KW_I2C_CTL_AAK); | ||
| 224 | } else { | ||
| 225 | state = state_write; | ||
| 226 | kw_write_reg(reg_data, **data); | ||
| 227 | (*data)++; (*len)--; | ||
| 228 | } | ||
| 229 | } | ||
| 230 | kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR); | ||
| 231 | } | ||
| 232 | |||
| 233 | if (isr & KW_I2C_IRQ_DATA) { | ||
| 234 | if (state == state_read) { | ||
| 235 | **data = kw_read_reg(reg_data); | ||
| 236 | (*data)++; (*len)--; | ||
| 237 | kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); | ||
| 238 | if ((*len) == 0) | ||
| 239 | state = state_stop; | ||
| 240 | else if ((*len) == 1) | ||
| 241 | kw_write_reg(reg_control, 0); | ||
| 242 | } else if (state == state_write) { | ||
| 243 | ack = kw_read_reg(reg_status); | ||
| 244 | if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { | ||
| 245 | DBG("KW: nack on data write\n"); | ||
| 246 | *rc = -EIO; | ||
| 247 | goto stop; | ||
| 248 | } else if (*len) { | ||
| 249 | kw_write_reg(reg_data, **data); | ||
| 250 | (*data)++; (*len)--; | ||
| 251 | } else { | ||
| 252 | kw_write_reg(reg_control, KW_I2C_CTL_STOP); | ||
| 253 | state = state_stop; | ||
| 254 | *rc = 0; | ||
| 255 | } | ||
| 256 | kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); | ||
| 257 | } else { | ||
| 258 | kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); | ||
| 259 | WRONG_STATE("KW_I2C_IRQ_DATA"); | ||
| 260 | if (state != state_stop) { | ||
| 261 | *rc = -EIO; | ||
| 262 | goto stop; | ||
| 263 | } | ||
| 264 | } | ||
| 265 | } | ||
| 266 | |||
| 267 | if (isr & KW_I2C_IRQ_STOP) { | ||
| 268 | kw_write_reg(reg_isr, KW_I2C_IRQ_STOP); | ||
| 269 | if (state != state_stop) { | ||
| 270 | WRONG_STATE("KW_I2C_IRQ_STOP"); | ||
| 271 | *rc = -EIO; | ||
| 272 | } | ||
| 273 | return state_idle; | ||
| 274 | } | ||
| 275 | |||
| 276 | if (isr & KW_I2C_IRQ_START) | ||
| 277 | kw_write_reg(reg_isr, KW_I2C_IRQ_START); | ||
| 278 | |||
| 279 | return state; | ||
| 280 | |||
| 281 | stop: | ||
| 282 | kw_write_reg(reg_control, KW_I2C_CTL_STOP); | ||
| 283 | return state_stop; | ||
| 284 | } | ||
| 285 | |||
| 286 | static int keywest_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 subaddr, u8 *data, int len) | ||
| 287 | { | ||
| 288 | u8 mode_reg = host->speed; | ||
| 289 | int state = state_addr; | ||
| 290 | int rc = 0; | ||
| 291 | |||
| 292 | /* Setup mode & subaddress if any */ | ||
| 293 | switch(host->mode) { | ||
| 294 | case pmac_low_i2c_mode_dumb: | ||
| 295 | printk(KERN_ERR "low_i2c: Dumb mode not supported !\n"); | ||
| 296 | return -EINVAL; | ||
| 297 | case pmac_low_i2c_mode_std: | ||
| 298 | mode_reg |= KW_I2C_MODE_STANDARD; | ||
| 299 | break; | ||
| 300 | case pmac_low_i2c_mode_stdsub: | ||
| 301 | mode_reg |= KW_I2C_MODE_STANDARDSUB; | ||
| 302 | kw_write_reg(reg_subaddr, subaddr); | ||
| 303 | break; | ||
| 304 | case pmac_low_i2c_mode_combined: | ||
| 305 | mode_reg |= KW_I2C_MODE_COMBINED; | ||
| 306 | kw_write_reg(reg_subaddr, subaddr); | ||
| 307 | break; | ||
| 308 | } | ||
| 309 | |||
| 310 | /* Setup channel & clear pending irqs */ | ||
| 311 | kw_write_reg(reg_isr, kw_read_reg(reg_isr)); | ||
| 312 | kw_write_reg(reg_mode, mode_reg | (host->channel << 4)); | ||
| 313 | kw_write_reg(reg_status, 0); | ||
| 314 | |||
| 315 | /* Set up address and r/w bit */ | ||
| 316 | kw_write_reg(reg_addr, addr); | ||
| 317 | |||
| 318 | /* Start sending address & disable interrupt*/ | ||
| 319 | kw_write_reg(reg_ier, 0 /*KW_I2C_IRQ_MASK*/); | ||
| 320 | kw_write_reg(reg_control, KW_I2C_CTL_XADDR); | ||
| 321 | |||
| 322 | /* State machine, to turn into an interrupt handler */ | ||
| 323 | while(state != state_idle) { | ||
| 324 | u8 isr = kw_wait_interrupt(host); | ||
| 325 | state = kw_handle_interrupt(host, state, addr & 1, &rc, &data, &len, isr); | ||
| 326 | } | ||
| 327 | |||
| 328 | return rc; | ||
| 329 | } | ||
| 330 | |||
| 331 | static void keywest_low_i2c_add(struct device_node *np) | ||
| 332 | { | ||
| 333 | struct low_i2c_host *host = find_low_i2c_host(NULL); | ||
| 334 | unsigned long *psteps, *prate, steps, aoffset = 0; | ||
| 335 | struct device_node *parent; | ||
| 336 | |||
| 337 | if (host == NULL) { | ||
| 338 | printk(KERN_ERR "low_i2c: Can't allocate host for %s\n", | ||
| 339 | np->full_name); | ||
| 340 | return; | ||
| 341 | } | ||
| 342 | memset(host, 0, sizeof(*host)); | ||
| 343 | |||
| 344 | init_MUTEX(&host->mutex); | ||
| 345 | host->np = of_node_get(np); | ||
| 346 | psteps = (unsigned long *)get_property(np, "AAPL,address-step", NULL); | ||
| 347 | steps = psteps ? (*psteps) : 0x10; | ||
| 348 | for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++) | ||
| 349 | steps >>= 1; | ||
| 350 | parent = of_get_parent(np); | ||
| 351 | host->num_channels = 1; | ||
| 352 | if (parent && parent->name[0] == 'u') { | ||
| 353 | host->num_channels = 2; | ||
| 354 | aoffset = 3; | ||
| 355 | } | ||
| 356 | /* Select interface rate */ | ||
| 357 | host->speed = KW_I2C_MODE_100KHZ; | ||
| 358 | prate = (unsigned long *)get_property(np, "AAPL,i2c-rate", NULL); | ||
| 359 | if (prate) switch(*prate) { | ||
| 360 | case 100: | ||
| 361 | host->speed = KW_I2C_MODE_100KHZ; | ||
| 362 | break; | ||
| 363 | case 50: | ||
| 364 | host->speed = KW_I2C_MODE_50KHZ; | ||
| 365 | break; | ||
| 366 | case 25: | ||
| 367 | host->speed = KW_I2C_MODE_25KHZ; | ||
| 368 | break; | ||
| 369 | } | ||
| 370 | host->mode = pmac_low_i2c_mode_std; | ||
| 371 | host->base = ioremap(np->addrs[0].address + aoffset, | ||
| 372 | np->addrs[0].size); | ||
| 373 | host->func = keywest_low_i2c_func; | ||
| 374 | } | ||
| 375 | |||
| 376 | /* | ||
| 377 | * | ||
| 378 | * PMU implementation | ||
| 379 | * | ||
| 380 | */ | ||
| 381 | |||
| 382 | |||
| 383 | #ifdef CONFIG_ADB_PMU | ||
| 384 | |||
| 385 | static int pmu_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len) | ||
| 386 | { | ||
| 387 | // TODO | ||
| 388 | return -ENODEV; | ||
| 389 | } | ||
| 390 | |||
| 391 | static void pmu_low_i2c_add(struct device_node *np) | ||
| 392 | { | ||
| 393 | struct low_i2c_host *host = find_low_i2c_host(NULL); | ||
| 394 | |||
| 395 | if (host == NULL) { | ||
| 396 | printk(KERN_ERR "low_i2c: Can't allocate host for %s\n", | ||
| 397 | np->full_name); | ||
| 398 | return; | ||
| 399 | } | ||
| 400 | memset(host, 0, sizeof(*host)); | ||
| 401 | |||
| 402 | init_MUTEX(&host->mutex); | ||
| 403 | host->np = of_node_get(np); | ||
| 404 | host->num_channels = 3; | ||
| 405 | host->mode = pmac_low_i2c_mode_std; | ||
| 406 | host->func = pmu_low_i2c_func; | ||
| 407 | } | ||
| 408 | |||
| 409 | #endif /* CONFIG_ADB_PMU */ | ||
| 410 | |||
| 411 | void __init pmac_init_low_i2c(void) | ||
| 412 | { | ||
| 413 | struct device_node *np; | ||
| 414 | |||
| 415 | /* Probe keywest-i2c busses */ | ||
| 416 | np = of_find_compatible_node(NULL, "i2c", "keywest-i2c"); | ||
| 417 | while(np) { | ||
| 418 | keywest_low_i2c_add(np); | ||
| 419 | np = of_find_compatible_node(np, "i2c", "keywest-i2c"); | ||
| 420 | } | ||
| 421 | |||
| 422 | #ifdef CONFIG_ADB_PMU | ||
| 423 | /* Probe PMU busses */ | ||
| 424 | np = of_find_node_by_name(NULL, "via-pmu"); | ||
| 425 | if (np) | ||
| 426 | pmu_low_i2c_add(np); | ||
| 427 | #endif /* CONFIG_ADB_PMU */ | ||
| 428 | |||
| 429 | /* TODO: Add CUDA support as well */ | ||
| 430 | } | ||
| 431 | |||
| 432 | int pmac_low_i2c_lock(struct device_node *np) | ||
| 433 | { | ||
| 434 | struct low_i2c_host *host = find_low_i2c_host(np); | ||
| 435 | |||
| 436 | if (!host) | ||
| 437 | return -ENODEV; | ||
| 438 | down(&host->mutex); | ||
| 439 | return 0; | ||
| 440 | } | ||
| 441 | EXPORT_SYMBOL(pmac_low_i2c_lock); | ||
| 442 | |||
| 443 | int pmac_low_i2c_unlock(struct device_node *np) | ||
| 444 | { | ||
| 445 | struct low_i2c_host *host = find_low_i2c_host(np); | ||
| 446 | |||
| 447 | if (!host) | ||
| 448 | return -ENODEV; | ||
| 449 | up(&host->mutex); | ||
| 450 | return 0; | ||
| 451 | } | ||
| 452 | EXPORT_SYMBOL(pmac_low_i2c_unlock); | ||
| 453 | |||
| 454 | |||
| 455 | int pmac_low_i2c_open(struct device_node *np, int channel) | ||
| 456 | { | ||
| 457 | struct low_i2c_host *host = find_low_i2c_host(np); | ||
| 458 | |||
| 459 | if (!host) | ||
| 460 | return -ENODEV; | ||
| 461 | |||
| 462 | if (channel >= host->num_channels) | ||
| 463 | return -EINVAL; | ||
| 464 | |||
| 465 | down(&host->mutex); | ||
| 466 | host->is_open = 1; | ||
| 467 | host->channel = channel; | ||
| 468 | |||
| 469 | return 0; | ||
| 470 | } | ||
| 471 | EXPORT_SYMBOL(pmac_low_i2c_open); | ||
| 472 | |||
| 473 | int pmac_low_i2c_close(struct device_node *np) | ||
| 474 | { | ||
| 475 | struct low_i2c_host *host = find_low_i2c_host(np); | ||
| 476 | |||
| 477 | if (!host) | ||
| 478 | return -ENODEV; | ||
| 479 | |||
| 480 | host->is_open = 0; | ||
| 481 | up(&host->mutex); | ||
| 482 | |||
| 483 | return 0; | ||
| 484 | } | ||
| 485 | EXPORT_SYMBOL(pmac_low_i2c_close); | ||
| 486 | |||
| 487 | int pmac_low_i2c_setmode(struct device_node *np, int mode) | ||
| 488 | { | ||
| 489 | struct low_i2c_host *host = find_low_i2c_host(np); | ||
| 490 | |||
| 491 | if (!host) | ||
| 492 | return -ENODEV; | ||
| 493 | WARN_ON(!host->is_open); | ||
| 494 | host->mode = mode; | ||
| 495 | |||
| 496 | return 0; | ||
| 497 | } | ||
| 498 | EXPORT_SYMBOL(pmac_low_i2c_setmode); | ||
| 499 | |||
| 500 | int pmac_low_i2c_xfer(struct device_node *np, u8 addrdir, u8 subaddr, u8 *data, int len) | ||
| 501 | { | ||
| 502 | struct low_i2c_host *host = find_low_i2c_host(np); | ||
| 503 | |||
| 504 | if (!host) | ||
| 505 | return -ENODEV; | ||
| 506 | WARN_ON(!host->is_open); | ||
| 507 | |||
| 508 | return host->func(host, addrdir, subaddr, data, len); | ||
| 509 | } | ||
| 510 | EXPORT_SYMBOL(pmac_low_i2c_xfer); | ||
| 511 | |||
diff --git a/arch/ppc/platforms/pmac_nvram.c b/arch/ppc/platforms/pmac_nvram.c deleted file mode 100644 index 8c9b008c7226..000000000000 --- a/arch/ppc/platforms/pmac_nvram.c +++ /dev/null | |||
| @@ -1,584 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * arch/ppc/platforms/pmac_nvram.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2002 Benjamin Herrenschmidt (benh@kernel.crashing.org) | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the License, or (at your option) any later version. | ||
| 10 | * | ||
| 11 | * Todo: - add support for the OF persistent properties | ||
| 12 | */ | ||
| 13 | #include <linux/config.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/stddef.h> | ||
| 17 | #include <linux/string.h> | ||
| 18 | #include <linux/nvram.h> | ||
| 19 | #include <linux/init.h> | ||
| 20 | #include <linux/slab.h> | ||
| 21 | #include <linux/delay.h> | ||
| 22 | #include <linux/errno.h> | ||
| 23 | #include <linux/adb.h> | ||
| 24 | #include <linux/pmu.h> | ||
| 25 | #include <linux/bootmem.h> | ||
| 26 | #include <linux/completion.h> | ||
| 27 | #include <linux/spinlock.h> | ||
| 28 | #include <asm/sections.h> | ||
| 29 | #include <asm/io.h> | ||
| 30 | #include <asm/system.h> | ||
| 31 | #include <asm/prom.h> | ||
| 32 | #include <asm/machdep.h> | ||
| 33 | #include <asm/nvram.h> | ||
| 34 | |||
| 35 | #define DEBUG | ||
| 36 | |||
| 37 | #ifdef DEBUG | ||
| 38 | #define DBG(x...) printk(x) | ||
| 39 | #else | ||
| 40 | #define DBG(x...) | ||
| 41 | #endif | ||
| 42 | |||
| 43 | #define NVRAM_SIZE 0x2000 /* 8kB of non-volatile RAM */ | ||
| 44 | |||
| 45 | #define CORE99_SIGNATURE 0x5a | ||
| 46 | #define CORE99_ADLER_START 0x14 | ||
| 47 | |||
| 48 | /* On Core99, nvram is either a sharp, a micron or an AMD flash */ | ||
| 49 | #define SM_FLASH_STATUS_DONE 0x80 | ||
| 50 | #define SM_FLASH_STATUS_ERR 0x38 | ||
| 51 | #define SM_FLASH_CMD_ERASE_CONFIRM 0xd0 | ||
| 52 | #define SM_FLASH_CMD_ERASE_SETUP 0x20 | ||
| 53 | #define SM_FLASH_CMD_RESET 0xff | ||
| 54 | #define SM_FLASH_CMD_WRITE_SETUP 0x40 | ||
| 55 | #define SM_FLASH_CMD_CLEAR_STATUS 0x50 | ||
| 56 | #define SM_FLASH_CMD_READ_STATUS 0x70 | ||
| 57 | |||
| 58 | /* CHRP NVRAM header */ | ||
| 59 | struct chrp_header { | ||
| 60 | u8 signature; | ||
| 61 | u8 cksum; | ||
| 62 | u16 len; | ||
| 63 | char name[12]; | ||
| 64 | u8 data[0]; | ||
| 65 | }; | ||
| 66 | |||
| 67 | struct core99_header { | ||
| 68 | struct chrp_header hdr; | ||
| 69 | u32 adler; | ||
| 70 | u32 generation; | ||
| 71 | u32 reserved[2]; | ||
| 72 | }; | ||
| 73 | |||
| 74 | /* | ||
| 75 | * Read and write the non-volatile RAM on PowerMacs and CHRP machines. | ||
| 76 | */ | ||
| 77 | static int nvram_naddrs; | ||
| 78 | static volatile unsigned char *nvram_addr; | ||
| 79 | static volatile unsigned char *nvram_data; | ||
| 80 | static int nvram_mult, is_core_99; | ||
| 81 | static int core99_bank = 0; | ||
| 82 | static int nvram_partitions[3]; | ||
| 83 | static DEFINE_SPINLOCK(nv_lock); | ||
| 84 | |||
| 85 | extern int pmac_newworld; | ||
| 86 | extern int system_running; | ||
| 87 | |||
| 88 | static int (*core99_write_bank)(int bank, u8* datas); | ||
| 89 | static int (*core99_erase_bank)(int bank); | ||
| 90 | |||
| 91 | static char *nvram_image; | ||
| 92 | |||
| 93 | |||
| 94 | static unsigned char core99_nvram_read_byte(int addr) | ||
| 95 | { | ||
| 96 | if (nvram_image == NULL) | ||
| 97 | return 0xff; | ||
| 98 | return nvram_image[addr]; | ||
| 99 | } | ||
| 100 | |||
| 101 | static void core99_nvram_write_byte(int addr, unsigned char val) | ||
| 102 | { | ||
| 103 | if (nvram_image == NULL) | ||
| 104 | return; | ||
| 105 | nvram_image[addr] = val; | ||
| 106 | } | ||
| 107 | |||
| 108 | |||
| 109 | static unsigned char direct_nvram_read_byte(int addr) | ||
| 110 | { | ||
| 111 | return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]); | ||
| 112 | } | ||
| 113 | |||
| 114 | static void direct_nvram_write_byte(int addr, unsigned char val) | ||
| 115 | { | ||
| 116 | out_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult], val); | ||
| 117 | } | ||
| 118 | |||
| 119 | |||
| 120 | static unsigned char indirect_nvram_read_byte(int addr) | ||
| 121 | { | ||
| 122 | unsigned char val; | ||
| 123 | unsigned long flags; | ||
| 124 | |||
| 125 | spin_lock_irqsave(&nv_lock, flags); | ||
| 126 | out_8(nvram_addr, addr >> 5); | ||
| 127 | val = in_8(&nvram_data[(addr & 0x1f) << 4]); | ||
| 128 | spin_unlock_irqrestore(&nv_lock, flags); | ||
| 129 | |||
| 130 | return val; | ||
| 131 | } | ||
| 132 | |||
| 133 | static void indirect_nvram_write_byte(int addr, unsigned char val) | ||
| 134 | { | ||
| 135 | unsigned long flags; | ||
| 136 | |||
| 137 | spin_lock_irqsave(&nv_lock, flags); | ||
| 138 | out_8(nvram_addr, addr >> 5); | ||
| 139 | out_8(&nvram_data[(addr & 0x1f) << 4], val); | ||
| 140 | spin_unlock_irqrestore(&nv_lock, flags); | ||
| 141 | } | ||
| 142 | |||
| 143 | |||
| 144 | #ifdef CONFIG_ADB_PMU | ||
| 145 | |||
| 146 | static void pmu_nvram_complete(struct adb_request *req) | ||
| 147 | { | ||
| 148 | if (req->arg) | ||
| 149 | complete((struct completion *)req->arg); | ||
| 150 | } | ||
| 151 | |||
| 152 | static unsigned char pmu_nvram_read_byte(int addr) | ||
| 153 | { | ||
| 154 | struct adb_request req; | ||
| 155 | DECLARE_COMPLETION(req_complete); | ||
| 156 | |||
| 157 | req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL; | ||
| 158 | if (pmu_request(&req, pmu_nvram_complete, 3, PMU_READ_NVRAM, | ||
| 159 | (addr >> 8) & 0xff, addr & 0xff)) | ||
| 160 | return 0xff; | ||
| 161 | if (system_state == SYSTEM_RUNNING) | ||
| 162 | wait_for_completion(&req_complete); | ||
| 163 | while (!req.complete) | ||
| 164 | pmu_poll(); | ||
| 165 | return req.reply[0]; | ||
| 166 | } | ||
| 167 | |||
| 168 | static void pmu_nvram_write_byte(int addr, unsigned char val) | ||
| 169 | { | ||
| 170 | struct adb_request req; | ||
| 171 | DECLARE_COMPLETION(req_complete); | ||
| 172 | |||
| 173 | req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL; | ||
| 174 | if (pmu_request(&req, pmu_nvram_complete, 4, PMU_WRITE_NVRAM, | ||
| 175 | (addr >> 8) & 0xff, addr & 0xff, val)) | ||
| 176 | return; | ||
| 177 | if (system_state == SYSTEM_RUNNING) | ||
| 178 | wait_for_completion(&req_complete); | ||
| 179 | while (!req.complete) | ||
| 180 | pmu_poll(); | ||
| 181 | } | ||
| 182 | |||
| 183 | #endif /* CONFIG_ADB_PMU */ | ||
| 184 | |||
| 185 | |||
| 186 | static u8 chrp_checksum(struct chrp_header* hdr) | ||
| 187 | { | ||
| 188 | u8 *ptr; | ||
| 189 | u16 sum = hdr->signature; | ||
| 190 | for (ptr = (u8 *)&hdr->len; ptr < hdr->data; ptr++) | ||
| 191 | sum += *ptr; | ||
| 192 | while (sum > 0xFF) | ||
| 193 | sum = (sum & 0xFF) + (sum>>8); | ||
| 194 | return sum; | ||
| 195 | } | ||
| 196 | |||
| 197 | static u32 core99_calc_adler(u8 *buffer) | ||
| 198 | { | ||
| 199 | int cnt; | ||
| 200 | u32 low, high; | ||
| 201 | |||
| 202 | buffer += CORE99_ADLER_START; | ||
| 203 | low = 1; | ||
| 204 | high = 0; | ||
| 205 | for (cnt=0; cnt<(NVRAM_SIZE-CORE99_ADLER_START); cnt++) { | ||
| 206 | if ((cnt % 5000) == 0) { | ||
| 207 | high %= 65521UL; | ||
| 208 | high %= 65521UL; | ||
| 209 | } | ||
| 210 | low += buffer[cnt]; | ||
| 211 | high += low; | ||
| 212 | } | ||
| 213 | low %= 65521UL; | ||
| 214 | high %= 65521UL; | ||
| 215 | |||
| 216 | return (high << 16) | low; | ||
| 217 | } | ||
| 218 | |||
| 219 | static u32 core99_check(u8* datas) | ||
| 220 | { | ||
| 221 | struct core99_header* hdr99 = (struct core99_header*)datas; | ||
| 222 | |||
| 223 | if (hdr99->hdr.signature != CORE99_SIGNATURE) { | ||
| 224 | DBG("Invalid signature\n"); | ||
| 225 | return 0; | ||
| 226 | } | ||
| 227 | if (hdr99->hdr.cksum != chrp_checksum(&hdr99->hdr)) { | ||
| 228 | DBG("Invalid checksum\n"); | ||
| 229 | return 0; | ||
| 230 | } | ||
| 231 | if (hdr99->adler != core99_calc_adler(datas)) { | ||
| 232 | DBG("Invalid adler\n"); | ||
| 233 | return 0; | ||
| 234 | } | ||
| 235 | return hdr99->generation; | ||
| 236 | } | ||
| 237 | |||
| 238 | static int sm_erase_bank(int bank) | ||
| 239 | { | ||
| 240 | int stat, i; | ||
| 241 | unsigned long timeout; | ||
| 242 | |||
| 243 | u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; | ||
| 244 | |||
| 245 | DBG("nvram: Sharp/Micron Erasing bank %d...\n", bank); | ||
| 246 | |||
| 247 | out_8(base, SM_FLASH_CMD_ERASE_SETUP); | ||
| 248 | out_8(base, SM_FLASH_CMD_ERASE_CONFIRM); | ||
| 249 | timeout = 0; | ||
| 250 | do { | ||
| 251 | if (++timeout > 1000000) { | ||
| 252 | printk(KERN_ERR "nvram: Sharp/Miron flash erase timeout !\n"); | ||
| 253 | break; | ||
| 254 | } | ||
| 255 | out_8(base, SM_FLASH_CMD_READ_STATUS); | ||
| 256 | stat = in_8(base); | ||
| 257 | } while (!(stat & SM_FLASH_STATUS_DONE)); | ||
| 258 | |||
| 259 | out_8(base, SM_FLASH_CMD_CLEAR_STATUS); | ||
| 260 | out_8(base, SM_FLASH_CMD_RESET); | ||
| 261 | |||
| 262 | for (i=0; i<NVRAM_SIZE; i++) | ||
| 263 | if (base[i] != 0xff) { | ||
| 264 | printk(KERN_ERR "nvram: Sharp/Micron flash erase failed !\n"); | ||
| 265 | return -ENXIO; | ||
| 266 | } | ||
| 267 | return 0; | ||
| 268 | } | ||
| 269 | |||
| 270 | static int sm_write_bank(int bank, u8* datas) | ||
| 271 | { | ||
| 272 | int i, stat = 0; | ||
| 273 | unsigned long timeout; | ||
| 274 | |||
| 275 | u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; | ||
| 276 | |||
| 277 | DBG("nvram: Sharp/Micron Writing bank %d...\n", bank); | ||
| 278 | |||
| 279 | for (i=0; i<NVRAM_SIZE; i++) { | ||
| 280 | out_8(base+i, SM_FLASH_CMD_WRITE_SETUP); | ||
| 281 | udelay(1); | ||
| 282 | out_8(base+i, datas[i]); | ||
| 283 | timeout = 0; | ||
| 284 | do { | ||
| 285 | if (++timeout > 1000000) { | ||
| 286 | printk(KERN_ERR "nvram: Sharp/Micron flash write timeout !\n"); | ||
| 287 | break; | ||
| 288 | } | ||
| 289 | out_8(base, SM_FLASH_CMD_READ_STATUS); | ||
| 290 | stat = in_8(base); | ||
| 291 | } while (!(stat & SM_FLASH_STATUS_DONE)); | ||
| 292 | if (!(stat & SM_FLASH_STATUS_DONE)) | ||
| 293 | break; | ||
| 294 | } | ||
| 295 | out_8(base, SM_FLASH_CMD_CLEAR_STATUS); | ||
| 296 | out_8(base, SM_FLASH_CMD_RESET); | ||
| 297 | for (i=0; i<NVRAM_SIZE; i++) | ||
| 298 | if (base[i] != datas[i]) { | ||
| 299 | printk(KERN_ERR "nvram: Sharp/Micron flash write failed !\n"); | ||
| 300 | return -ENXIO; | ||
| 301 | } | ||
| 302 | return 0; | ||
| 303 | } | ||
| 304 | |||
| 305 | static int amd_erase_bank(int bank) | ||
| 306 | { | ||
| 307 | int i, stat = 0; | ||
| 308 | unsigned long timeout; | ||
| 309 | |||
| 310 | u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; | ||
| 311 | |||
| 312 | DBG("nvram: AMD Erasing bank %d...\n", bank); | ||
| 313 | |||
| 314 | /* Unlock 1 */ | ||
| 315 | out_8(base+0x555, 0xaa); | ||
| 316 | udelay(1); | ||
| 317 | /* Unlock 2 */ | ||
| 318 | out_8(base+0x2aa, 0x55); | ||
| 319 | udelay(1); | ||
| 320 | |||
| 321 | /* Sector-Erase */ | ||
| 322 | out_8(base+0x555, 0x80); | ||
| 323 | udelay(1); | ||
| 324 | out_8(base+0x555, 0xaa); | ||
| 325 | udelay(1); | ||
| 326 | out_8(base+0x2aa, 0x55); | ||
| 327 | udelay(1); | ||
| 328 | out_8(base, 0x30); | ||
| 329 | udelay(1); | ||
| 330 | |||
| 331 | timeout = 0; | ||
| 332 | do { | ||
| 333 | if (++timeout > 1000000) { | ||
| 334 | printk(KERN_ERR "nvram: AMD flash erase timeout !\n"); | ||
| 335 | break; | ||
| 336 | } | ||
| 337 | stat = in_8(base) ^ in_8(base); | ||
| 338 | } while (stat != 0); | ||
| 339 | |||
| 340 | /* Reset */ | ||
| 341 | out_8(base, 0xf0); | ||
| 342 | udelay(1); | ||
| 343 | |||
| 344 | for (i=0; i<NVRAM_SIZE; i++) | ||
| 345 | if (base[i] != 0xff) { | ||
| 346 | printk(KERN_ERR "nvram: AMD flash erase failed !\n"); | ||
| 347 | return -ENXIO; | ||
| 348 | } | ||
| 349 | return 0; | ||
| 350 | } | ||
| 351 | |||
| 352 | static int amd_write_bank(int bank, u8* datas) | ||
| 353 | { | ||
| 354 | int i, stat = 0; | ||
| 355 | unsigned long timeout; | ||
| 356 | |||
| 357 | u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; | ||
| 358 | |||
| 359 | DBG("nvram: AMD Writing bank %d...\n", bank); | ||
| 360 | |||
| 361 | for (i=0; i<NVRAM_SIZE; i++) { | ||
| 362 | /* Unlock 1 */ | ||
| 363 | out_8(base+0x555, 0xaa); | ||
| 364 | udelay(1); | ||
| 365 | /* Unlock 2 */ | ||
| 366 | out_8(base+0x2aa, 0x55); | ||
| 367 | udelay(1); | ||
| 368 | |||
| 369 | /* Write single word */ | ||
| 370 | out_8(base+0x555, 0xa0); | ||
| 371 | udelay(1); | ||
| 372 | out_8(base+i, datas[i]); | ||
| 373 | |||
| 374 | timeout = 0; | ||
| 375 | do { | ||
| 376 | if (++timeout > 1000000) { | ||
| 377 | printk(KERN_ERR "nvram: AMD flash write timeout !\n"); | ||
| 378 | break; | ||
| 379 | } | ||
| 380 | stat = in_8(base) ^ in_8(base); | ||
| 381 | } while (stat != 0); | ||
| 382 | if (stat != 0) | ||
| 383 | break; | ||
| 384 | } | ||
| 385 | |||
| 386 | /* Reset */ | ||
| 387 | out_8(base, 0xf0); | ||
| 388 | udelay(1); | ||
| 389 | |||
| 390 | for (i=0; i<NVRAM_SIZE; i++) | ||
| 391 | if (base[i] != datas[i]) { | ||
| 392 | printk(KERN_ERR "nvram: AMD flash write failed !\n"); | ||
| 393 | return -ENXIO; | ||
| 394 | } | ||
| 395 | return 0; | ||
| 396 | } | ||
| 397 | |||
| 398 | static void __init lookup_partitions(void) | ||
| 399 | { | ||
| 400 | u8 buffer[17]; | ||
| 401 | int i, offset; | ||
| 402 | struct chrp_header* hdr; | ||
| 403 | |||
| 404 | if (pmac_newworld) { | ||
| 405 | nvram_partitions[pmac_nvram_OF] = -1; | ||
| 406 | nvram_partitions[pmac_nvram_XPRAM] = -1; | ||
| 407 | nvram_partitions[pmac_nvram_NR] = -1; | ||
| 408 | hdr = (struct chrp_header *)buffer; | ||
| 409 | |||
| 410 | offset = 0; | ||
| 411 | buffer[16] = 0; | ||
| 412 | do { | ||
| 413 | for (i=0;i<16;i++) | ||
| 414 | buffer[i] = nvram_read_byte(offset+i); | ||
| 415 | if (!strcmp(hdr->name, "common")) | ||
| 416 | nvram_partitions[pmac_nvram_OF] = offset + 0x10; | ||
| 417 | if (!strcmp(hdr->name, "APL,MacOS75")) { | ||
| 418 | nvram_partitions[pmac_nvram_XPRAM] = offset + 0x10; | ||
| 419 | nvram_partitions[pmac_nvram_NR] = offset + 0x110; | ||
| 420 | } | ||
| 421 | offset += (hdr->len * 0x10); | ||
| 422 | } while(offset < NVRAM_SIZE); | ||
| 423 | } else { | ||
| 424 | nvram_partitions[pmac_nvram_OF] = 0x1800; | ||
| 425 | nvram_partitions[pmac_nvram_XPRAM] = 0x1300; | ||
| 426 | nvram_partitions[pmac_nvram_NR] = 0x1400; | ||
| 427 | } | ||
| 428 | DBG("nvram: OF partition at 0x%x\n", nvram_partitions[pmac_nvram_OF]); | ||
| 429 | DBG("nvram: XP partition at 0x%x\n", nvram_partitions[pmac_nvram_XPRAM]); | ||
| 430 | DBG("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]); | ||
| 431 | } | ||
| 432 | |||
| 433 | static void core99_nvram_sync(void) | ||
| 434 | { | ||
| 435 | struct core99_header* hdr99; | ||
| 436 | unsigned long flags; | ||
| 437 | |||
| 438 | if (!is_core_99 || !nvram_data || !nvram_image) | ||
| 439 | return; | ||
| 440 | |||
| 441 | spin_lock_irqsave(&nv_lock, flags); | ||
| 442 | if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE, | ||
| 443 | NVRAM_SIZE)) | ||
| 444 | goto bail; | ||
| 445 | |||
| 446 | DBG("Updating nvram...\n"); | ||
| 447 | |||
| 448 | hdr99 = (struct core99_header*)nvram_image; | ||
| 449 | hdr99->generation++; | ||
| 450 | hdr99->hdr.signature = CORE99_SIGNATURE; | ||
| 451 | hdr99->hdr.cksum = chrp_checksum(&hdr99->hdr); | ||
| 452 | hdr99->adler = core99_calc_adler(nvram_image); | ||
| 453 | core99_bank = core99_bank ? 0 : 1; | ||
| 454 | if (core99_erase_bank) | ||
| 455 | if (core99_erase_bank(core99_bank)) { | ||
| 456 | printk("nvram: Error erasing bank %d\n", core99_bank); | ||
| 457 | goto bail; | ||
| 458 | } | ||
| 459 | if (core99_write_bank) | ||
| 460 | if (core99_write_bank(core99_bank, nvram_image)) | ||
| 461 | printk("nvram: Error writing bank %d\n", core99_bank); | ||
| 462 | bail: | ||
| 463 | spin_unlock_irqrestore(&nv_lock, flags); | ||
| 464 | |||
| 465 | #ifdef DEBUG | ||
| 466 | mdelay(2000); | ||
| 467 | #endif | ||
| 468 | } | ||
| 469 | |||
| 470 | void __init pmac_nvram_init(void) | ||
| 471 | { | ||
| 472 | struct device_node *dp; | ||
| 473 | |||
| 474 | nvram_naddrs = 0; | ||
| 475 | |||
| 476 | dp = find_devices("nvram"); | ||
| 477 | if (dp == NULL) { | ||
| 478 | printk(KERN_ERR "Can't find NVRAM device\n"); | ||
| 479 | return; | ||
| 480 | } | ||
| 481 | nvram_naddrs = dp->n_addrs; | ||
| 482 | is_core_99 = device_is_compatible(dp, "nvram,flash"); | ||
| 483 | if (is_core_99) { | ||
| 484 | int i; | ||
| 485 | u32 gen_bank0, gen_bank1; | ||
| 486 | |||
| 487 | if (nvram_naddrs < 1) { | ||
| 488 | printk(KERN_ERR "nvram: no address\n"); | ||
| 489 | return; | ||
| 490 | } | ||
| 491 | nvram_image = alloc_bootmem(NVRAM_SIZE); | ||
| 492 | if (nvram_image == NULL) { | ||
| 493 | printk(KERN_ERR "nvram: can't allocate ram image\n"); | ||
| 494 | return; | ||
| 495 | } | ||
| 496 | nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2); | ||
| 497 | nvram_naddrs = 1; /* Make sure we get the correct case */ | ||
| 498 | |||
| 499 | DBG("nvram: Checking bank 0...\n"); | ||
| 500 | |||
| 501 | gen_bank0 = core99_check((u8 *)nvram_data); | ||
| 502 | gen_bank1 = core99_check((u8 *)nvram_data + NVRAM_SIZE); | ||
| 503 | core99_bank = (gen_bank0 < gen_bank1) ? 1 : 0; | ||
| 504 | |||
| 505 | DBG("nvram: gen0=%d, gen1=%d\n", gen_bank0, gen_bank1); | ||
| 506 | DBG("nvram: Active bank is: %d\n", core99_bank); | ||
| 507 | |||
| 508 | for (i=0; i<NVRAM_SIZE; i++) | ||
| 509 | nvram_image[i] = nvram_data[i + core99_bank*NVRAM_SIZE]; | ||
| 510 | |||
| 511 | ppc_md.nvram_read_val = core99_nvram_read_byte; | ||
| 512 | ppc_md.nvram_write_val = core99_nvram_write_byte; | ||
| 513 | ppc_md.nvram_sync = core99_nvram_sync; | ||
| 514 | /* | ||
| 515 | * Maybe we could be smarter here though making an exclusive list | ||
| 516 | * of known flash chips is a bit nasty as older OF didn't provide us | ||
| 517 | * with a useful "compatible" entry. A solution would be to really | ||
| 518 | * identify the chip using flash id commands and base ourselves on | ||
| 519 | * a list of known chips IDs | ||
| 520 | */ | ||
| 521 | if (device_is_compatible(dp, "amd-0137")) { | ||
| 522 | core99_erase_bank = amd_erase_bank; | ||
| 523 | core99_write_bank = amd_write_bank; | ||
| 524 | } else { | ||
| 525 | core99_erase_bank = sm_erase_bank; | ||
| 526 | core99_write_bank = sm_write_bank; | ||
| 527 | } | ||
| 528 | } else if (_machine == _MACH_chrp && nvram_naddrs == 1) { | ||
| 529 | nvram_data = ioremap(dp->addrs[0].address + isa_mem_base, | ||
| 530 | dp->addrs[0].size); | ||
| 531 | nvram_mult = 1; | ||
| 532 | ppc_md.nvram_read_val = direct_nvram_read_byte; | ||
| 533 | ppc_md.nvram_write_val = direct_nvram_write_byte; | ||
| 534 | } else if (nvram_naddrs == 1) { | ||
| 535 | nvram_data = ioremap(dp->addrs[0].address, dp->addrs[0].size); | ||
| 536 | nvram_mult = (dp->addrs[0].size + NVRAM_SIZE - 1) / NVRAM_SIZE; | ||
| 537 | ppc_md.nvram_read_val = direct_nvram_read_byte; | ||
| 538 | ppc_md.nvram_write_val = direct_nvram_write_byte; | ||
| 539 | } else if (nvram_naddrs == 2) { | ||
| 540 | nvram_addr = ioremap(dp->addrs[0].address, dp->addrs[0].size); | ||
| 541 | nvram_data = ioremap(dp->addrs[1].address, dp->addrs[1].size); | ||
| 542 | ppc_md.nvram_read_val = indirect_nvram_read_byte; | ||
| 543 | ppc_md.nvram_write_val = indirect_nvram_write_byte; | ||
| 544 | } else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) { | ||
| 545 | #ifdef CONFIG_ADB_PMU | ||
| 546 | nvram_naddrs = -1; | ||
| 547 | ppc_md.nvram_read_val = pmu_nvram_read_byte; | ||
| 548 | ppc_md.nvram_write_val = pmu_nvram_write_byte; | ||
| 549 | #endif /* CONFIG_ADB_PMU */ | ||
| 550 | } else { | ||
| 551 | printk(KERN_ERR "Don't know how to access NVRAM with %d addresses\n", | ||
| 552 | nvram_naddrs); | ||
| 553 | } | ||
| 554 | lookup_partitions(); | ||
| 555 | } | ||
| 556 | |||
| 557 | int pmac_get_partition(int partition) | ||
| 558 | { | ||
| 559 | return nvram_partitions[partition]; | ||
| 560 | } | ||
| 561 | |||
| 562 | u8 pmac_xpram_read(int xpaddr) | ||
| 563 | { | ||
| 564 | int offset = nvram_partitions[pmac_nvram_XPRAM]; | ||
| 565 | |||
| 566 | if (offset < 0) | ||
| 567 | return 0xff; | ||
| 568 | |||
| 569 | return ppc_md.nvram_read_val(xpaddr + offset); | ||
| 570 | } | ||
| 571 | |||
| 572 | void pmac_xpram_write(int xpaddr, u8 data) | ||
| 573 | { | ||
| 574 | int offset = nvram_partitions[pmac_nvram_XPRAM]; | ||
| 575 | |||
| 576 | if (offset < 0) | ||
| 577 | return; | ||
| 578 | |||
| 579 | ppc_md.nvram_write_val(xpaddr + offset, data); | ||
| 580 | } | ||
| 581 | |||
| 582 | EXPORT_SYMBOL(pmac_get_partition); | ||
| 583 | EXPORT_SYMBOL(pmac_xpram_read); | ||
| 584 | EXPORT_SYMBOL(pmac_xpram_write); | ||
diff --git a/arch/ppc/platforms/pmac_pci.c b/arch/ppc/platforms/pmac_pci.c deleted file mode 100644 index 786295b6ddd0..000000000000 --- a/arch/ppc/platforms/pmac_pci.c +++ /dev/null | |||
| @@ -1,1124 +0,0 @@ | |||
| 1 | /* | ||
| 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 | * | ||
| 7 | * Copyright (C) 1997 Paul Mackerras (paulus@cs.anu.edu.au) | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or | ||
| 10 | * modify it under the terms of the GNU General Public License | ||
| 11 | * as published by the Free Software Foundation; either version | ||
| 12 | * 2 of the License, or (at your option) any later version. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/pci.h> | ||
| 17 | #include <linux/delay.h> | ||
| 18 | #include <linux/string.h> | ||
| 19 | #include <linux/init.h> | ||
| 20 | |||
| 21 | #include <asm/sections.h> | ||
| 22 | #include <asm/io.h> | ||
| 23 | #include <asm/prom.h> | ||
| 24 | #include <asm/pci-bridge.h> | ||
| 25 | #include <asm/machdep.h> | ||
| 26 | #include <asm/pmac_feature.h> | ||
| 27 | |||
| 28 | #undef DEBUG | ||
| 29 | |||
| 30 | #ifdef DEBUG | ||
| 31 | #ifdef CONFIG_XMON | ||
| 32 | extern void xmon_printf(const char *fmt, ...); | ||
| 33 | #define DBG(x...) xmon_printf(x) | ||
| 34 | #else | ||
| 35 | #define DBG(x...) printk(x) | ||
| 36 | #endif | ||
| 37 | #else | ||
| 38 | #define DBG(x...) | ||
| 39 | #endif | ||
| 40 | |||
| 41 | static int add_bridge(struct device_node *dev); | ||
| 42 | extern void pmac_check_ht_link(void); | ||
| 43 | |||
| 44 | /* XXX Could be per-controller, but I don't think we risk anything by | ||
| 45 | * assuming we won't have both UniNorth and Bandit */ | ||
| 46 | static int has_uninorth; | ||
| 47 | #ifdef CONFIG_POWER4 | ||
| 48 | static struct pci_controller *u3_agp; | ||
| 49 | #endif /* CONFIG_POWER4 */ | ||
| 50 | |||
| 51 | extern u8 pci_cache_line_size; | ||
| 52 | extern int pcibios_assign_bus_offset; | ||
| 53 | |||
| 54 | struct device_node *k2_skiplist[2]; | ||
| 55 | |||
| 56 | /* | ||
| 57 | * Magic constants for enabling cache coherency in the bandit/PSX bridge. | ||
| 58 | */ | ||
| 59 | #define BANDIT_DEVID_2 8 | ||
| 60 | #define BANDIT_REVID 3 | ||
| 61 | |||
| 62 | #define BANDIT_DEVNUM 11 | ||
| 63 | #define BANDIT_MAGIC 0x50 | ||
| 64 | #define BANDIT_COHERENT 0x40 | ||
| 65 | |||
| 66 | static int __init | ||
| 67 | fixup_one_level_bus_range(struct device_node *node, int higher) | ||
| 68 | { | ||
| 69 | for (; node != 0;node = node->sibling) { | ||
| 70 | int * bus_range; | ||
| 71 | unsigned int *class_code; | ||
| 72 | int len; | ||
| 73 | |||
| 74 | /* For PCI<->PCI bridges or CardBus bridges, we go down */ | ||
| 75 | class_code = (unsigned int *) get_property(node, "class-code", NULL); | ||
| 76 | if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && | ||
| 77 | (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) | ||
| 78 | continue; | ||
| 79 | bus_range = (int *) get_property(node, "bus-range", &len); | ||
| 80 | if (bus_range != NULL && len > 2 * sizeof(int)) { | ||
| 81 | if (bus_range[1] > higher) | ||
| 82 | higher = bus_range[1]; | ||
| 83 | } | ||
| 84 | higher = fixup_one_level_bus_range(node->child, higher); | ||
| 85 | } | ||
| 86 | return higher; | ||
| 87 | } | ||
| 88 | |||
| 89 | /* This routine fixes the "bus-range" property of all bridges in the | ||
| 90 | * system since they tend to have their "last" member wrong on macs | ||
| 91 | * | ||
| 92 | * Note that the bus numbers manipulated here are OF bus numbers, they | ||
| 93 | * are not Linux bus numbers. | ||
| 94 | */ | ||
| 95 | static void __init | ||
| 96 | fixup_bus_range(struct device_node *bridge) | ||
| 97 | { | ||
| 98 | int * bus_range; | ||
| 99 | int len; | ||
| 100 | |||
| 101 | /* Lookup the "bus-range" property for the hose */ | ||
| 102 | bus_range = (int *) get_property(bridge, "bus-range", &len); | ||
| 103 | if (bus_range == NULL || len < 2 * sizeof(int)) { | ||
| 104 | printk(KERN_WARNING "Can't get bus-range for %s\n", | ||
| 105 | bridge->full_name); | ||
| 106 | return; | ||
| 107 | } | ||
| 108 | bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]); | ||
| 109 | } | ||
| 110 | |||
| 111 | /* | ||
| 112 | * Apple MacRISC (U3, UniNorth, Bandit, Chaos) PCI controllers. | ||
| 113 | * | ||
| 114 | * The "Bandit" version is present in all early PCI PowerMacs, | ||
| 115 | * and up to the first ones using Grackle. Some machines may | ||
| 116 | * have 2 bandit controllers (2 PCI busses). | ||
| 117 | * | ||
| 118 | * "Chaos" is used in some "Bandit"-type machines as a bridge | ||
| 119 | * for the separate display bus. It is accessed the same | ||
| 120 | * way as bandit, but cannot be probed for devices. It therefore | ||
| 121 | * has its own config access functions. | ||
| 122 | * | ||
| 123 | * The "UniNorth" version is present in all Core99 machines | ||
| 124 | * (iBook, G4, new IMacs, and all the recent Apple machines). | ||
| 125 | * It contains 3 controllers in one ASIC. | ||
| 126 | * | ||
| 127 | * The U3 is the bridge used on G5 machines. It contains an | ||
| 128 | * AGP bus which is dealt with the old UniNorth access routines | ||
| 129 | * and a HyperTransport bus which uses its own set of access | ||
| 130 | * functions. | ||
| 131 | */ | ||
| 132 | |||
| 133 | #define MACRISC_CFA0(devfn, off) \ | ||
| 134 | ((1 << (unsigned long)PCI_SLOT(dev_fn)) \ | ||
| 135 | | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \ | ||
| 136 | | (((unsigned long)(off)) & 0xFCUL)) | ||
| 137 | |||
| 138 | #define MACRISC_CFA1(bus, devfn, off) \ | ||
| 139 | ((((unsigned long)(bus)) << 16) \ | ||
| 140 | |(((unsigned long)(devfn)) << 8) \ | ||
| 141 | |(((unsigned long)(off)) & 0xFCUL) \ | ||
| 142 | |1UL) | ||
| 143 | |||
| 144 | static void volatile __iomem * | ||
| 145 | macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset) | ||
| 146 | { | ||
| 147 | unsigned int caddr; | ||
| 148 | |||
| 149 | if (bus == hose->first_busno) { | ||
| 150 | if (dev_fn < (11 << 3)) | ||
| 151 | return NULL; | ||
| 152 | caddr = MACRISC_CFA0(dev_fn, offset); | ||
| 153 | } else | ||
| 154 | caddr = MACRISC_CFA1(bus, dev_fn, offset); | ||
| 155 | |||
| 156 | /* Uninorth will return garbage if we don't read back the value ! */ | ||
| 157 | do { | ||
| 158 | out_le32(hose->cfg_addr, caddr); | ||
| 159 | } while (in_le32(hose->cfg_addr) != caddr); | ||
| 160 | |||
| 161 | offset &= has_uninorth ? 0x07 : 0x03; | ||
| 162 | return hose->cfg_data + offset; | ||
| 163 | } | ||
| 164 | |||
| 165 | static int | ||
| 166 | macrisc_read_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
| 167 | int len, u32 *val) | ||
| 168 | { | ||
| 169 | struct pci_controller *hose = bus->sysdata; | ||
| 170 | void volatile __iomem *addr; | ||
| 171 | |||
| 172 | addr = macrisc_cfg_access(hose, bus->number, devfn, offset); | ||
| 173 | if (!addr) | ||
| 174 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 175 | /* | ||
| 176 | * Note: the caller has already checked that offset is | ||
| 177 | * suitably aligned and that len is 1, 2 or 4. | ||
| 178 | */ | ||
| 179 | switch (len) { | ||
| 180 | case 1: | ||
| 181 | *val = in_8(addr); | ||
| 182 | break; | ||
| 183 | case 2: | ||
| 184 | *val = in_le16(addr); | ||
| 185 | break; | ||
| 186 | default: | ||
| 187 | *val = in_le32(addr); | ||
| 188 | break; | ||
| 189 | } | ||
| 190 | return PCIBIOS_SUCCESSFUL; | ||
| 191 | } | ||
| 192 | |||
| 193 | static int | ||
| 194 | macrisc_write_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
| 195 | int len, u32 val) | ||
| 196 | { | ||
| 197 | struct pci_controller *hose = bus->sysdata; | ||
| 198 | void volatile __iomem *addr; | ||
| 199 | |||
| 200 | addr = macrisc_cfg_access(hose, bus->number, devfn, offset); | ||
| 201 | if (!addr) | ||
| 202 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 203 | /* | ||
| 204 | * Note: the caller has already checked that offset is | ||
| 205 | * suitably aligned and that len is 1, 2 or 4. | ||
| 206 | */ | ||
| 207 | switch (len) { | ||
| 208 | case 1: | ||
| 209 | out_8(addr, val); | ||
| 210 | (void) in_8(addr); | ||
| 211 | break; | ||
| 212 | case 2: | ||
| 213 | out_le16(addr, val); | ||
| 214 | (void) in_le16(addr); | ||
| 215 | break; | ||
| 216 | default: | ||
| 217 | out_le32(addr, val); | ||
| 218 | (void) in_le32(addr); | ||
| 219 | break; | ||
| 220 | } | ||
| 221 | return PCIBIOS_SUCCESSFUL; | ||
| 222 | } | ||
| 223 | |||
| 224 | static struct pci_ops macrisc_pci_ops = | ||
| 225 | { | ||
| 226 | macrisc_read_config, | ||
| 227 | macrisc_write_config | ||
| 228 | }; | ||
| 229 | |||
| 230 | /* | ||
| 231 | * Verifiy that a specific (bus, dev_fn) exists on chaos | ||
| 232 | */ | ||
| 233 | static int | ||
| 234 | chaos_validate_dev(struct pci_bus *bus, int devfn, int offset) | ||
| 235 | { | ||
| 236 | struct device_node *np; | ||
| 237 | u32 *vendor, *device; | ||
| 238 | |||
| 239 | np = pci_busdev_to_OF_node(bus, devfn); | ||
| 240 | if (np == NULL) | ||
| 241 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 242 | |||
| 243 | vendor = (u32 *)get_property(np, "vendor-id", NULL); | ||
| 244 | device = (u32 *)get_property(np, "device-id", NULL); | ||
| 245 | if (vendor == NULL || device == NULL) | ||
| 246 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 247 | |||
| 248 | if ((*vendor == 0x106b) && (*device == 3) && (offset >= 0x10) | ||
| 249 | && (offset != 0x14) && (offset != 0x18) && (offset <= 0x24)) | ||
| 250 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
| 251 | |||
| 252 | return PCIBIOS_SUCCESSFUL; | ||
| 253 | } | ||
| 254 | |||
| 255 | static int | ||
| 256 | chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
| 257 | int len, u32 *val) | ||
| 258 | { | ||
| 259 | int result = chaos_validate_dev(bus, devfn, offset); | ||
| 260 | if (result == PCIBIOS_BAD_REGISTER_NUMBER) | ||
| 261 | *val = ~0U; | ||
| 262 | if (result != PCIBIOS_SUCCESSFUL) | ||
| 263 | return result; | ||
| 264 | return macrisc_read_config(bus, devfn, offset, len, val); | ||
| 265 | } | ||
| 266 | |||
| 267 | static int | ||
| 268 | chaos_write_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
| 269 | int len, u32 val) | ||
| 270 | { | ||
| 271 | int result = chaos_validate_dev(bus, devfn, offset); | ||
| 272 | if (result != PCIBIOS_SUCCESSFUL) | ||
| 273 | return result; | ||
| 274 | return macrisc_write_config(bus, devfn, offset, len, val); | ||
| 275 | } | ||
| 276 | |||
| 277 | static struct pci_ops chaos_pci_ops = | ||
| 278 | { | ||
| 279 | chaos_read_config, | ||
| 280 | chaos_write_config | ||
| 281 | }; | ||
| 282 | |||
| 283 | #ifdef CONFIG_POWER4 | ||
| 284 | |||
| 285 | /* | ||
| 286 | * These versions of U3 HyperTransport config space access ops do not | ||
| 287 | * implement self-view of the HT host yet | ||
| 288 | */ | ||
| 289 | |||
| 290 | #define U3_HT_CFA0(devfn, off) \ | ||
| 291 | ((((unsigned long)devfn) << 8) | offset) | ||
| 292 | #define U3_HT_CFA1(bus, devfn, off) \ | ||
| 293 | (U3_HT_CFA0(devfn, off) \ | ||
| 294 | + (((unsigned long)bus) << 16) \ | ||
| 295 | + 0x01000000UL) | ||
| 296 | |||
| 297 | static void volatile __iomem * | ||
| 298 | u3_ht_cfg_access(struct pci_controller* hose, u8 bus, u8 devfn, u8 offset) | ||
| 299 | { | ||
| 300 | if (bus == hose->first_busno) { | ||
| 301 | /* For now, we don't self probe U3 HT bridge */ | ||
| 302 | if (PCI_FUNC(devfn) != 0 || PCI_SLOT(devfn) > 7 || | ||
| 303 | PCI_SLOT(devfn) < 1) | ||
| 304 | return 0; | ||
| 305 | return hose->cfg_data + U3_HT_CFA0(devfn, offset); | ||
| 306 | } else | ||
| 307 | return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset); | ||
| 308 | } | ||
| 309 | |||
| 310 | static int | ||
| 311 | u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
| 312 | int len, u32 *val) | ||
| 313 | { | ||
| 314 | struct pci_controller *hose = bus->sysdata; | ||
| 315 | void volatile __iomem *addr; | ||
| 316 | int i; | ||
| 317 | |||
| 318 | struct device_node *np = pci_busdev_to_OF_node(bus, devfn); | ||
| 319 | if (np == NULL) | ||
| 320 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 321 | |||
| 322 | /* | ||
| 323 | * When a device in K2 is powered down, we die on config | ||
| 324 | * cycle accesses. Fix that here. | ||
| 325 | */ | ||
| 326 | for (i=0; i<2; i++) | ||
| 327 | if (k2_skiplist[i] == np) { | ||
| 328 | switch (len) { | ||
| 329 | case 1: | ||
| 330 | *val = 0xff; break; | ||
| 331 | case 2: | ||
| 332 | *val = 0xffff; break; | ||
| 333 | default: | ||
| 334 | *val = 0xfffffffful; break; | ||
| 335 | } | ||
| 336 | return PCIBIOS_SUCCESSFUL; | ||
| 337 | } | ||
| 338 | |||
| 339 | addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); | ||
| 340 | if (!addr) | ||
| 341 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 342 | /* | ||
| 343 | * Note: the caller has already checked that offset is | ||
| 344 | * suitably aligned and that len is 1, 2 or 4. | ||
| 345 | */ | ||
| 346 | switch (len) { | ||
| 347 | case 1: | ||
| 348 | *val = in_8(addr); | ||
| 349 | break; | ||
| 350 | case 2: | ||
| 351 | *val = in_le16(addr); | ||
| 352 | break; | ||
| 353 | default: | ||
| 354 | *val = in_le32(addr); | ||
| 355 | break; | ||
| 356 | } | ||
| 357 | return PCIBIOS_SUCCESSFUL; | ||
| 358 | } | ||
| 359 | |||
| 360 | static int | ||
| 361 | u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
| 362 | int len, u32 val) | ||
| 363 | { | ||
| 364 | struct pci_controller *hose = bus->sysdata; | ||
| 365 | void volatile __iomem *addr; | ||
| 366 | int i; | ||
| 367 | |||
| 368 | struct device_node *np = pci_busdev_to_OF_node(bus, devfn); | ||
| 369 | if (np == NULL) | ||
| 370 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 371 | /* | ||
| 372 | * When a device in K2 is powered down, we die on config | ||
| 373 | * cycle accesses. Fix that here. | ||
| 374 | */ | ||
| 375 | for (i=0; i<2; i++) | ||
| 376 | if (k2_skiplist[i] == np) | ||
| 377 | return PCIBIOS_SUCCESSFUL; | ||
| 378 | |||
| 379 | addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); | ||
| 380 | if (!addr) | ||
| 381 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 382 | /* | ||
| 383 | * Note: the caller has already checked that offset is | ||
| 384 | * suitably aligned and that len is 1, 2 or 4. | ||
| 385 | */ | ||
| 386 | switch (len) { | ||
| 387 | case 1: | ||
| 388 | out_8(addr, val); | ||
| 389 | (void) in_8(addr); | ||
| 390 | break; | ||
| 391 | case 2: | ||
| 392 | out_le16(addr, val); | ||
| 393 | (void) in_le16(addr); | ||
| 394 | break; | ||
| 395 | default: | ||
| 396 | out_le32(addr, val); | ||
| 397 | (void) in_le32(addr); | ||
| 398 | break; | ||
| 399 | } | ||
| 400 | return PCIBIOS_SUCCESSFUL; | ||
| 401 | } | ||
| 402 | |||
| 403 | static struct pci_ops u3_ht_pci_ops = | ||
| 404 | { | ||
| 405 | u3_ht_read_config, | ||
| 406 | u3_ht_write_config | ||
| 407 | }; | ||
| 408 | |||
| 409 | #endif /* CONFIG_POWER4 */ | ||
| 410 | |||
| 411 | /* | ||
| 412 | * For a bandit bridge, turn on cache coherency if necessary. | ||
| 413 | * N.B. we could clean this up using the hose ops directly. | ||
| 414 | */ | ||
| 415 | static void __init | ||
| 416 | init_bandit(struct pci_controller *bp) | ||
| 417 | { | ||
| 418 | unsigned int vendev, magic; | ||
| 419 | int rev; | ||
| 420 | |||
| 421 | /* read the word at offset 0 in config space for device 11 */ | ||
| 422 | out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + PCI_VENDOR_ID); | ||
| 423 | udelay(2); | ||
| 424 | vendev = in_le32(bp->cfg_data); | ||
| 425 | if (vendev == (PCI_DEVICE_ID_APPLE_BANDIT << 16) + | ||
| 426 | PCI_VENDOR_ID_APPLE) { | ||
| 427 | /* read the revision id */ | ||
| 428 | out_le32(bp->cfg_addr, | ||
| 429 | (1UL << BANDIT_DEVNUM) + PCI_REVISION_ID); | ||
| 430 | udelay(2); | ||
| 431 | rev = in_8(bp->cfg_data); | ||
| 432 | if (rev != BANDIT_REVID) | ||
| 433 | printk(KERN_WARNING | ||
| 434 | "Unknown revision %d for bandit\n", rev); | ||
| 435 | } else if (vendev != (BANDIT_DEVID_2 << 16) + PCI_VENDOR_ID_APPLE) { | ||
| 436 | printk(KERN_WARNING "bandit isn't? (%x)\n", vendev); | ||
| 437 | return; | ||
| 438 | } | ||
| 439 | |||
| 440 | /* read the word at offset 0x50 */ | ||
| 441 | out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + BANDIT_MAGIC); | ||
| 442 | udelay(2); | ||
| 443 | magic = in_le32(bp->cfg_data); | ||
| 444 | if ((magic & BANDIT_COHERENT) != 0) | ||
| 445 | return; | ||
| 446 | magic |= BANDIT_COHERENT; | ||
| 447 | udelay(2); | ||
| 448 | out_le32(bp->cfg_data, magic); | ||
| 449 | printk(KERN_INFO "Cache coherency enabled for bandit/PSX\n"); | ||
| 450 | } | ||
| 451 | |||
| 452 | |||
| 453 | /* | ||
| 454 | * Tweak the PCI-PCI bridge chip on the blue & white G3s. | ||
| 455 | */ | ||
| 456 | static void __init | ||
| 457 | init_p2pbridge(void) | ||
| 458 | { | ||
| 459 | struct device_node *p2pbridge; | ||
| 460 | struct pci_controller* hose; | ||
| 461 | u8 bus, devfn; | ||
| 462 | u16 val; | ||
| 463 | |||
| 464 | /* XXX it would be better here to identify the specific | ||
| 465 | PCI-PCI bridge chip we have. */ | ||
| 466 | if ((p2pbridge = find_devices("pci-bridge")) == 0 | ||
| 467 | || p2pbridge->parent == NULL | ||
| 468 | || strcmp(p2pbridge->parent->name, "pci") != 0) | ||
| 469 | return; | ||
| 470 | if (pci_device_from_OF_node(p2pbridge, &bus, &devfn) < 0) { | ||
| 471 | DBG("Can't find PCI infos for PCI<->PCI bridge\n"); | ||
| 472 | return; | ||
| 473 | } | ||
| 474 | /* Warning: At this point, we have not yet renumbered all busses. | ||
| 475 | * So we must use OF walking to find out hose | ||
| 476 | */ | ||
| 477 | hose = pci_find_hose_for_OF_device(p2pbridge); | ||
| 478 | if (!hose) { | ||
| 479 | DBG("Can't find hose for PCI<->PCI bridge\n"); | ||
| 480 | return; | ||
| 481 | } | ||
| 482 | if (early_read_config_word(hose, bus, devfn, | ||
| 483 | PCI_BRIDGE_CONTROL, &val) < 0) { | ||
| 484 | printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n"); | ||
| 485 | return; | ||
| 486 | } | ||
| 487 | val &= ~PCI_BRIDGE_CTL_MASTER_ABORT; | ||
| 488 | early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val); | ||
| 489 | } | ||
| 490 | |||
| 491 | /* | ||
| 492 | * Some Apple desktop machines have a NEC PD720100A USB2 controller | ||
| 493 | * on the motherboard. Open Firmware, on these, will disable the | ||
| 494 | * EHCI part of it so it behaves like a pair of OHCI's. This fixup | ||
| 495 | * code re-enables it ;) | ||
| 496 | */ | ||
| 497 | static void __init | ||
| 498 | fixup_nec_usb2(void) | ||
| 499 | { | ||
| 500 | struct device_node *nec; | ||
| 501 | |||
| 502 | for (nec = NULL; (nec = of_find_node_by_name(nec, "usb")) != NULL;) { | ||
| 503 | struct pci_controller *hose; | ||
| 504 | u32 data, *prop; | ||
| 505 | u8 bus, devfn; | ||
| 506 | |||
| 507 | prop = (u32 *)get_property(nec, "vendor-id", NULL); | ||
| 508 | if (prop == NULL) | ||
| 509 | continue; | ||
| 510 | if (0x1033 != *prop) | ||
| 511 | continue; | ||
| 512 | prop = (u32 *)get_property(nec, "device-id", NULL); | ||
| 513 | if (prop == NULL) | ||
| 514 | continue; | ||
| 515 | if (0x0035 != *prop) | ||
| 516 | continue; | ||
| 517 | prop = (u32 *)get_property(nec, "reg", NULL); | ||
| 518 | if (prop == NULL) | ||
| 519 | continue; | ||
| 520 | devfn = (prop[0] >> 8) & 0xff; | ||
| 521 | bus = (prop[0] >> 16) & 0xff; | ||
| 522 | if (PCI_FUNC(devfn) != 0) | ||
| 523 | continue; | ||
| 524 | hose = pci_find_hose_for_OF_device(nec); | ||
| 525 | if (!hose) | ||
| 526 | continue; | ||
| 527 | early_read_config_dword(hose, bus, devfn, 0xe4, &data); | ||
| 528 | if (data & 1UL) { | ||
| 529 | printk("Found NEC PD720100A USB2 chip with disabled EHCI, fixing up...\n"); | ||
| 530 | data &= ~1UL; | ||
| 531 | early_write_config_dword(hose, bus, devfn, 0xe4, data); | ||
| 532 | early_write_config_byte(hose, bus, devfn | 2, PCI_INTERRUPT_LINE, | ||
| 533 | nec->intrs[0].line); | ||
| 534 | } | ||
| 535 | } | ||
| 536 | } | ||
| 537 | |||
| 538 | void __init | ||
| 539 | pmac_find_bridges(void) | ||
| 540 | { | ||
| 541 | struct device_node *np, *root; | ||
| 542 | struct device_node *ht = NULL; | ||
| 543 | |||
| 544 | root = of_find_node_by_path("/"); | ||
| 545 | if (root == NULL) { | ||
| 546 | printk(KERN_CRIT "pmac_find_bridges: can't find root of device tree\n"); | ||
| 547 | return; | ||
| 548 | } | ||
| 549 | for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) { | ||
| 550 | if (np->name == NULL) | ||
| 551 | continue; | ||
| 552 | if (strcmp(np->name, "bandit") == 0 | ||
| 553 | || strcmp(np->name, "chaos") == 0 | ||
| 554 | || strcmp(np->name, "pci") == 0) { | ||
| 555 | if (add_bridge(np) == 0) | ||
| 556 | of_node_get(np); | ||
| 557 | } | ||
| 558 | if (strcmp(np->name, "ht") == 0) { | ||
| 559 | of_node_get(np); | ||
| 560 | ht = np; | ||
| 561 | } | ||
| 562 | } | ||
| 563 | of_node_put(root); | ||
| 564 | |||
| 565 | /* Probe HT last as it relies on the agp resources to be already | ||
| 566 | * setup | ||
| 567 | */ | ||
| 568 | if (ht && add_bridge(ht) != 0) | ||
| 569 | of_node_put(ht); | ||
| 570 | |||
| 571 | init_p2pbridge(); | ||
| 572 | fixup_nec_usb2(); | ||
| 573 | |||
| 574 | /* We are still having some issues with the Xserve G4, enabling | ||
| 575 | * some offset between bus number and domains for now when we | ||
| 576 | * assign all busses should help for now | ||
| 577 | */ | ||
| 578 | if (pci_assign_all_buses) | ||
| 579 | pcibios_assign_bus_offset = 0x10; | ||
| 580 | |||
| 581 | #ifdef CONFIG_POWER4 | ||
| 582 | /* There is something wrong with DMA on U3/HT. I haven't figured out | ||
| 583 | * the details yet, but if I set the cache line size to 128 bytes like | ||
| 584 | * it should, I'm getting memory corruption caused by devices like | ||
| 585 | * sungem (even without the MWI bit set, but maybe sungem doesn't | ||
| 586 | * care). Right now, it appears that setting up a 64 bytes line size | ||
| 587 | * works properly, 64 bytes beeing the max transfer size of HT, I | ||
| 588 | * suppose this is related the way HT/PCI are hooked together. I still | ||
| 589 | * need to dive into more specs though to be really sure of what's | ||
| 590 | * going on. --BenH. | ||
| 591 | * | ||
| 592 | * Ok, apparently, it's just that HT can't do more than 64 bytes | ||
| 593 | * transactions. MWI seem to be meaningless there as well, it may | ||
| 594 | * be worth nop'ing out pci_set_mwi too though I haven't done that | ||
| 595 | * yet. | ||
| 596 | * | ||
| 597 | * Note that it's a bit different for whatever is in the AGP slot. | ||
| 598 | * For now, I don't care, but this can become a real issue, we | ||
| 599 | * should probably hook pci_set_mwi anyway to make sure it sets | ||
| 600 | * the real cache line size in there. | ||
| 601 | */ | ||
| 602 | if (machine_is_compatible("MacRISC4")) | ||
| 603 | pci_cache_line_size = 16; /* 64 bytes */ | ||
| 604 | |||
| 605 | pmac_check_ht_link(); | ||
| 606 | #endif /* CONFIG_POWER4 */ | ||
| 607 | } | ||
| 608 | |||
| 609 | #define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \ | ||
| 610 | | (((o) & ~3) << 24)) | ||
| 611 | |||
| 612 | #define GRACKLE_PICR1_STG 0x00000040 | ||
| 613 | #define GRACKLE_PICR1_LOOPSNOOP 0x00000010 | ||
| 614 | |||
| 615 | /* N.B. this is called before bridges is initialized, so we can't | ||
| 616 | use grackle_pcibios_{read,write}_config_dword. */ | ||
| 617 | static inline void grackle_set_stg(struct pci_controller* bp, int enable) | ||
| 618 | { | ||
| 619 | unsigned int val; | ||
| 620 | |||
| 621 | out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); | ||
| 622 | val = in_le32(bp->cfg_data); | ||
| 623 | val = enable? (val | GRACKLE_PICR1_STG) : | ||
| 624 | (val & ~GRACKLE_PICR1_STG); | ||
| 625 | out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); | ||
| 626 | out_le32(bp->cfg_data, val); | ||
| 627 | (void)in_le32(bp->cfg_data); | ||
| 628 | } | ||
| 629 | |||
| 630 | static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable) | ||
| 631 | { | ||
| 632 | unsigned int val; | ||
| 633 | |||
| 634 | out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); | ||
| 635 | val = in_le32(bp->cfg_data); | ||
| 636 | val = enable? (val | GRACKLE_PICR1_LOOPSNOOP) : | ||
| 637 | (val & ~GRACKLE_PICR1_LOOPSNOOP); | ||
| 638 | out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); | ||
| 639 | out_le32(bp->cfg_data, val); | ||
| 640 | (void)in_le32(bp->cfg_data); | ||
| 641 | } | ||
| 642 | |||
| 643 | static int __init | ||
| 644 | setup_uninorth(struct pci_controller* hose, struct reg_property* addr) | ||
| 645 | { | ||
| 646 | pci_assign_all_buses = 1; | ||
| 647 | has_uninorth = 1; | ||
| 648 | hose->ops = ¯isc_pci_ops; | ||
| 649 | hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); | ||
| 650 | hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); | ||
| 651 | /* We "know" that the bridge at f2000000 has the PCI slots. */ | ||
| 652 | return addr->address == 0xf2000000; | ||
| 653 | } | ||
| 654 | |||
| 655 | static void __init | ||
| 656 | setup_bandit(struct pci_controller* hose, struct reg_property* addr) | ||
| 657 | { | ||
| 658 | hose->ops = ¯isc_pci_ops; | ||
| 659 | hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); | ||
| 660 | hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); | ||
| 661 | init_bandit(hose); | ||
| 662 | } | ||
| 663 | |||
| 664 | static void __init | ||
| 665 | setup_chaos(struct pci_controller* hose, struct reg_property* addr) | ||
| 666 | { | ||
| 667 | /* assume a `chaos' bridge */ | ||
| 668 | hose->ops = &chaos_pci_ops; | ||
| 669 | hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); | ||
| 670 | hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); | ||
| 671 | } | ||
| 672 | |||
| 673 | #ifdef CONFIG_POWER4 | ||
| 674 | |||
| 675 | static void __init | ||
| 676 | setup_u3_agp(struct pci_controller* hose, struct reg_property* addr) | ||
| 677 | { | ||
| 678 | /* On G5, we move AGP up to high bus number so we don't need | ||
| 679 | * to reassign bus numbers for HT. If we ever have P2P bridges | ||
| 680 | * on AGP, we'll have to move pci_assign_all_buses to the | ||
| 681 | * pci_controller structure so we enable it for AGP and not for | ||
| 682 | * HT childs. | ||
| 683 | * We hard code the address because of the different size of | ||
| 684 | * the reg address cell, we shall fix that by killing struct | ||
| 685 | * reg_property and using some accessor functions instead | ||
| 686 | */ | ||
| 687 | hose->first_busno = 0xf0; | ||
| 688 | hose->last_busno = 0xff; | ||
| 689 | has_uninorth = 1; | ||
| 690 | hose->ops = ¯isc_pci_ops; | ||
| 691 | hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000); | ||
| 692 | hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000); | ||
| 693 | |||
| 694 | u3_agp = hose; | ||
| 695 | } | ||
| 696 | |||
| 697 | static void __init | ||
| 698 | setup_u3_ht(struct pci_controller* hose, struct reg_property *addr) | ||
| 699 | { | ||
| 700 | struct device_node *np = (struct device_node *)hose->arch_data; | ||
| 701 | int i, cur; | ||
| 702 | |||
| 703 | hose->ops = &u3_ht_pci_ops; | ||
| 704 | |||
| 705 | /* We hard code the address because of the different size of | ||
| 706 | * the reg address cell, we shall fix that by killing struct | ||
| 707 | * reg_property and using some accessor functions instead | ||
| 708 | */ | ||
| 709 | hose->cfg_data = ioremap(0xf2000000, 0x02000000); | ||
| 710 | |||
| 711 | /* | ||
| 712 | * /ht node doesn't expose a "ranges" property, so we "remove" regions that | ||
| 713 | * have been allocated to AGP. So far, this version of the code doesn't assign | ||
| 714 | * any of the 0xfxxxxxxx "fine" memory regions to /ht. | ||
| 715 | * We need to fix that sooner or later by either parsing all child "ranges" | ||
| 716 | * properties or figuring out the U3 address space decoding logic and | ||
| 717 | * then read its configuration register (if any). | ||
| 718 | */ | ||
| 719 | hose->io_base_phys = 0xf4000000; | ||
| 720 | hose->io_base_virt = ioremap(hose->io_base_phys, 0x00400000); | ||
| 721 | isa_io_base = (unsigned long) hose->io_base_virt; | ||
| 722 | hose->io_resource.name = np->full_name; | ||
| 723 | hose->io_resource.start = 0; | ||
| 724 | hose->io_resource.end = 0x003fffff; | ||
| 725 | hose->io_resource.flags = IORESOURCE_IO; | ||
| 726 | hose->pci_mem_offset = 0; | ||
| 727 | hose->first_busno = 0; | ||
| 728 | hose->last_busno = 0xef; | ||
| 729 | hose->mem_resources[0].name = np->full_name; | ||
| 730 | hose->mem_resources[0].start = 0x80000000; | ||
| 731 | hose->mem_resources[0].end = 0xefffffff; | ||
| 732 | hose->mem_resources[0].flags = IORESOURCE_MEM; | ||
| 733 | |||
| 734 | if (u3_agp == NULL) { | ||
| 735 | DBG("U3 has no AGP, using full resource range\n"); | ||
| 736 | return; | ||
| 737 | } | ||
| 738 | |||
| 739 | /* We "remove" the AGP resources from the resources allocated to HT, that | ||
| 740 | * is we create "holes". However, that code does assumptions that so far | ||
| 741 | * happen to be true (cross fingers...), typically that resources in the | ||
| 742 | * AGP node are properly ordered | ||
| 743 | */ | ||
| 744 | cur = 0; | ||
| 745 | for (i=0; i<3; i++) { | ||
| 746 | struct resource *res = &u3_agp->mem_resources[i]; | ||
| 747 | if (res->flags != IORESOURCE_MEM) | ||
| 748 | continue; | ||
| 749 | /* We don't care about "fine" resources */ | ||
| 750 | if (res->start >= 0xf0000000) | ||
| 751 | continue; | ||
| 752 | /* Check if it's just a matter of "shrinking" us in one direction */ | ||
| 753 | if (hose->mem_resources[cur].start == res->start) { | ||
| 754 | DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n", | ||
| 755 | cur, hose->mem_resources[cur].start, res->end + 1); | ||
| 756 | hose->mem_resources[cur].start = res->end + 1; | ||
| 757 | continue; | ||
| 758 | } | ||
| 759 | if (hose->mem_resources[cur].end == res->end) { | ||
| 760 | DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n", | ||
| 761 | cur, hose->mem_resources[cur].end, res->start - 1); | ||
| 762 | hose->mem_resources[cur].end = res->start - 1; | ||
| 763 | continue; | ||
| 764 | } | ||
| 765 | /* No, it's not the case, we need a hole */ | ||
| 766 | if (cur == 2) { | ||
| 767 | /* not enough resources to make a hole, we drop part of the range */ | ||
| 768 | printk(KERN_WARNING "Running out of resources for /ht host !\n"); | ||
| 769 | hose->mem_resources[cur].end = res->start - 1; | ||
| 770 | continue; | ||
| 771 | } | ||
| 772 | cur++; | ||
| 773 | DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n", | ||
| 774 | cur-1, res->start - 1, cur, res->end + 1); | ||
| 775 | hose->mem_resources[cur].name = np->full_name; | ||
| 776 | hose->mem_resources[cur].flags = IORESOURCE_MEM; | ||
| 777 | hose->mem_resources[cur].start = res->end + 1; | ||
| 778 | hose->mem_resources[cur].end = hose->mem_resources[cur-1].end; | ||
| 779 | hose->mem_resources[cur-1].end = res->start - 1; | ||
| 780 | } | ||
| 781 | } | ||
| 782 | |||
| 783 | #endif /* CONFIG_POWER4 */ | ||
| 784 | |||
| 785 | void __init | ||
| 786 | setup_grackle(struct pci_controller *hose) | ||
| 787 | { | ||
| 788 | setup_indirect_pci(hose, 0xfec00000, 0xfee00000); | ||
| 789 | if (machine_is_compatible("AAPL,PowerBook1998")) | ||
| 790 | grackle_set_loop_snoop(hose, 1); | ||
| 791 | #if 0 /* Disabled for now, HW problems ??? */ | ||
| 792 | grackle_set_stg(hose, 1); | ||
| 793 | #endif | ||
| 794 | } | ||
| 795 | |||
| 796 | /* | ||
| 797 | * We assume that if we have a G3 powermac, we have one bridge called | ||
| 798 | * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise, | ||
| 799 | * if we have one or more bandit or chaos bridges, we don't have a MPC106. | ||
| 800 | */ | ||
| 801 | static int __init | ||
| 802 | add_bridge(struct device_node *dev) | ||
| 803 | { | ||
| 804 | int len; | ||
| 805 | struct pci_controller *hose; | ||
| 806 | struct reg_property *addr; | ||
| 807 | char* disp_name; | ||
| 808 | int *bus_range; | ||
| 809 | int primary = 1; | ||
| 810 | |||
| 811 | DBG("Adding PCI host bridge %s\n", dev->full_name); | ||
| 812 | |||
| 813 | addr = (struct reg_property *) get_property(dev, "reg", &len); | ||
| 814 | if (addr == NULL || len < sizeof(*addr)) { | ||
| 815 | printk(KERN_WARNING "Can't use %s: no address\n", | ||
| 816 | dev->full_name); | ||
| 817 | return -ENODEV; | ||
| 818 | } | ||
| 819 | bus_range = (int *) get_property(dev, "bus-range", &len); | ||
| 820 | if (bus_range == NULL || len < 2 * sizeof(int)) { | ||
| 821 | printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", | ||
| 822 | dev->full_name); | ||
| 823 | } | ||
| 824 | |||
| 825 | hose = pcibios_alloc_controller(); | ||
| 826 | if (!hose) | ||
| 827 | return -ENOMEM; | ||
| 828 | hose->arch_data = dev; | ||
| 829 | hose->first_busno = bus_range ? bus_range[0] : 0; | ||
| 830 | hose->last_busno = bus_range ? bus_range[1] : 0xff; | ||
| 831 | |||
| 832 | disp_name = NULL; | ||
| 833 | #ifdef CONFIG_POWER4 | ||
| 834 | if (device_is_compatible(dev, "u3-agp")) { | ||
| 835 | setup_u3_agp(hose, addr); | ||
| 836 | disp_name = "U3-AGP"; | ||
| 837 | primary = 0; | ||
| 838 | } else if (device_is_compatible(dev, "u3-ht")) { | ||
| 839 | setup_u3_ht(hose, addr); | ||
| 840 | disp_name = "U3-HT"; | ||
| 841 | primary = 1; | ||
| 842 | } else | ||
| 843 | #endif /* CONFIG_POWER4 */ | ||
| 844 | if (device_is_compatible(dev, "uni-north")) { | ||
| 845 | primary = setup_uninorth(hose, addr); | ||
| 846 | disp_name = "UniNorth"; | ||
| 847 | } else if (strcmp(dev->name, "pci") == 0) { | ||
| 848 | /* XXX assume this is a mpc106 (grackle) */ | ||
| 849 | setup_grackle(hose); | ||
| 850 | disp_name = "Grackle (MPC106)"; | ||
| 851 | } else if (strcmp(dev->name, "bandit") == 0) { | ||
| 852 | setup_bandit(hose, addr); | ||
| 853 | disp_name = "Bandit"; | ||
| 854 | } else if (strcmp(dev->name, "chaos") == 0) { | ||
| 855 | setup_chaos(hose, addr); | ||
| 856 | disp_name = "Chaos"; | ||
| 857 | primary = 0; | ||
| 858 | } | ||
| 859 | printk(KERN_INFO "Found %s PCI host bridge at 0x%08x. Firmware bus number: %d->%d\n", | ||
| 860 | disp_name, addr->address, hose->first_busno, hose->last_busno); | ||
| 861 | DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", | ||
| 862 | hose, hose->cfg_addr, hose->cfg_data); | ||
| 863 | |||
| 864 | /* Interpret the "ranges" property */ | ||
| 865 | /* This also maps the I/O region and sets isa_io/mem_base */ | ||
| 866 | pci_process_bridge_OF_ranges(hose, dev, primary); | ||
| 867 | |||
| 868 | /* Fixup "bus-range" OF property */ | ||
| 869 | fixup_bus_range(dev); | ||
| 870 | |||
| 871 | return 0; | ||
| 872 | } | ||
| 873 | |||
| 874 | static void __init | ||
| 875 | pcibios_fixup_OF_interrupts(void) | ||
| 876 | { | ||
| 877 | struct pci_dev* dev = NULL; | ||
| 878 | |||
| 879 | /* | ||
| 880 | * Open Firmware often doesn't initialize the | ||
| 881 | * PCI_INTERRUPT_LINE config register properly, so we | ||
| 882 | * should find the device node and apply the interrupt | ||
| 883 | * obtained from the OF device-tree | ||
| 884 | */ | ||
| 885 | for_each_pci_dev(dev) { | ||
| 886 | struct device_node *node; | ||
| 887 | node = pci_device_to_OF_node(dev); | ||
| 888 | /* this is the node, see if it has interrupts */ | ||
| 889 | if (node && node->n_intrs > 0) | ||
| 890 | dev->irq = node->intrs[0].line; | ||
| 891 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); | ||
| 892 | } | ||
| 893 | } | ||
| 894 | |||
| 895 | void __init | ||
| 896 | pmac_pcibios_fixup(void) | ||
| 897 | { | ||
| 898 | /* Fixup interrupts according to OF tree */ | ||
| 899 | pcibios_fixup_OF_interrupts(); | ||
| 900 | } | ||
| 901 | |||
| 902 | int | ||
| 903 | pmac_pci_enable_device_hook(struct pci_dev *dev, int initial) | ||
| 904 | { | ||
| 905 | struct device_node* node; | ||
| 906 | int updatecfg = 0; | ||
| 907 | int uninorth_child; | ||
| 908 | |||
| 909 | node = pci_device_to_OF_node(dev); | ||
| 910 | |||
| 911 | /* We don't want to enable USB controllers absent from the OF tree | ||
| 912 | * (iBook second controller) | ||
| 913 | */ | ||
| 914 | if (dev->vendor == PCI_VENDOR_ID_APPLE | ||
| 915 | && (dev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10)) | ||
| 916 | && !node) { | ||
| 917 | printk(KERN_INFO "Apple USB OHCI %s disabled by firmware\n", | ||
| 918 | pci_name(dev)); | ||
| 919 | return -EINVAL; | ||
| 920 | } | ||
| 921 | |||
| 922 | if (!node) | ||
| 923 | return 0; | ||
| 924 | |||
| 925 | uninorth_child = node->parent && | ||
| 926 | device_is_compatible(node->parent, "uni-north"); | ||
| 927 | |||
| 928 | /* Firewire & GMAC were disabled after PCI probe, the driver is | ||
| 929 | * claiming them, we must re-enable them now. | ||
| 930 | */ | ||
| 931 | if (uninorth_child && !strcmp(node->name, "firewire") && | ||
| 932 | (device_is_compatible(node, "pci106b,18") || | ||
| 933 | device_is_compatible(node, "pci106b,30") || | ||
| 934 | device_is_compatible(node, "pci11c1,5811"))) { | ||
| 935 | pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, node, 0, 1); | ||
| 936 | pmac_call_feature(PMAC_FTR_1394_ENABLE, node, 0, 1); | ||
| 937 | updatecfg = 1; | ||
| 938 | } | ||
| 939 | if (uninorth_child && !strcmp(node->name, "ethernet") && | ||
| 940 | device_is_compatible(node, "gmac")) { | ||
| 941 | pmac_call_feature(PMAC_FTR_GMAC_ENABLE, node, 0, 1); | ||
| 942 | updatecfg = 1; | ||
| 943 | } | ||
| 944 | |||
| 945 | if (updatecfg) { | ||
| 946 | u16 cmd; | ||
| 947 | |||
| 948 | /* | ||
| 949 | * Make sure PCI is correctly configured | ||
| 950 | * | ||
| 951 | * We use old pci_bios versions of the function since, by | ||
| 952 | * default, gmac is not powered up, and so will be absent | ||
| 953 | * from the kernel initial PCI lookup. | ||
| 954 | * | ||
| 955 | * Should be replaced by 2.4 new PCI mechanisms and really | ||
| 956 | * register the device. | ||
| 957 | */ | ||
| 958 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
| 959 | cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE; | ||
| 960 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
| 961 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16); | ||
| 962 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, pci_cache_line_size); | ||
| 963 | } | ||
| 964 | |||
| 965 | return 0; | ||
| 966 | } | ||
| 967 | |||
| 968 | /* We power down some devices after they have been probed. They'll | ||
| 969 | * be powered back on later on | ||
| 970 | */ | ||
| 971 | void __init | ||
| 972 | pmac_pcibios_after_init(void) | ||
| 973 | { | ||
| 974 | struct device_node* nd; | ||
| 975 | |||
| 976 | #ifdef CONFIG_BLK_DEV_IDE | ||
| 977 | struct pci_dev *dev = NULL; | ||
| 978 | |||
| 979 | /* OF fails to initialize IDE controllers on macs | ||
| 980 | * (and maybe other machines) | ||
| 981 | * | ||
| 982 | * Ideally, this should be moved to the IDE layer, but we need | ||
| 983 | * to check specifically with Andre Hedrick how to do it cleanly | ||
| 984 | * since the common IDE code seem to care about the fact that the | ||
| 985 | * BIOS may have disabled a controller. | ||
| 986 | * | ||
| 987 | * -- BenH | ||
| 988 | */ | ||
| 989 | for_each_pci_dev(dev) { | ||
| 990 | if ((dev->class >> 16) == PCI_BASE_CLASS_STORAGE) | ||
| 991 | pci_enable_device(dev); | ||
| 992 | } | ||
| 993 | #endif /* CONFIG_BLK_DEV_IDE */ | ||
| 994 | |||
| 995 | nd = find_devices("firewire"); | ||
| 996 | while (nd) { | ||
| 997 | if (nd->parent && (device_is_compatible(nd, "pci106b,18") || | ||
| 998 | device_is_compatible(nd, "pci106b,30") || | ||
| 999 | device_is_compatible(nd, "pci11c1,5811")) | ||
| 1000 | && device_is_compatible(nd->parent, "uni-north")) { | ||
| 1001 | pmac_call_feature(PMAC_FTR_1394_ENABLE, nd, 0, 0); | ||
| 1002 | pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0); | ||
| 1003 | } | ||
| 1004 | nd = nd->next; | ||
| 1005 | } | ||
| 1006 | nd = find_devices("ethernet"); | ||
| 1007 | while (nd) { | ||
| 1008 | if (nd->parent && device_is_compatible(nd, "gmac") | ||
| 1009 | && device_is_compatible(nd->parent, "uni-north")) | ||
| 1010 | pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0); | ||
| 1011 | nd = nd->next; | ||
| 1012 | } | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | void pmac_pci_fixup_cardbus(struct pci_dev* dev) | ||
| 1016 | { | ||
| 1017 | if (_machine != _MACH_Pmac) | ||
| 1018 | return; | ||
| 1019 | /* | ||
| 1020 | * Fix the interrupt routing on the various cardbus bridges | ||
| 1021 | * used on powerbooks | ||
| 1022 | */ | ||
| 1023 | if (dev->vendor != PCI_VENDOR_ID_TI) | ||
| 1024 | return; | ||
| 1025 | if (dev->device == PCI_DEVICE_ID_TI_1130 || | ||
| 1026 | dev->device == PCI_DEVICE_ID_TI_1131) { | ||
| 1027 | u8 val; | ||
| 1028 | /* Enable PCI interrupt */ | ||
| 1029 | if (pci_read_config_byte(dev, 0x91, &val) == 0) | ||
| 1030 | pci_write_config_byte(dev, 0x91, val | 0x30); | ||
| 1031 | /* Disable ISA interrupt mode */ | ||
| 1032 | if (pci_read_config_byte(dev, 0x92, &val) == 0) | ||
| 1033 | pci_write_config_byte(dev, 0x92, val & ~0x06); | ||
| 1034 | } | ||
| 1035 | if (dev->device == PCI_DEVICE_ID_TI_1210 || | ||
| 1036 | dev->device == PCI_DEVICE_ID_TI_1211 || | ||
| 1037 | dev->device == PCI_DEVICE_ID_TI_1410 || | ||
| 1038 | dev->device == PCI_DEVICE_ID_TI_1510) { | ||
| 1039 | u8 val; | ||
| 1040 | /* 0x8c == TI122X_IRQMUX, 2 says to route the INTA | ||
| 1041 | signal out the MFUNC0 pin */ | ||
| 1042 | if (pci_read_config_byte(dev, 0x8c, &val) == 0) | ||
| 1043 | pci_write_config_byte(dev, 0x8c, (val & ~0x0f) | 2); | ||
| 1044 | /* Disable ISA interrupt mode */ | ||
| 1045 | if (pci_read_config_byte(dev, 0x92, &val) == 0) | ||
| 1046 | pci_write_config_byte(dev, 0x92, val & ~0x06); | ||
| 1047 | } | ||
| 1048 | } | ||
| 1049 | |||
| 1050 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TI, PCI_ANY_ID, pmac_pci_fixup_cardbus); | ||
| 1051 | |||
| 1052 | void pmac_pci_fixup_pciata(struct pci_dev* dev) | ||
| 1053 | { | ||
| 1054 | u8 progif = 0; | ||
| 1055 | |||
| 1056 | /* | ||
| 1057 | * On PowerMacs, we try to switch any PCI ATA controller to | ||
| 1058 | * fully native mode | ||
| 1059 | */ | ||
| 1060 | if (_machine != _MACH_Pmac) | ||
| 1061 | return; | ||
| 1062 | /* Some controllers don't have the class IDE */ | ||
| 1063 | if (dev->vendor == PCI_VENDOR_ID_PROMISE) | ||
| 1064 | switch(dev->device) { | ||
| 1065 | case PCI_DEVICE_ID_PROMISE_20246: | ||
| 1066 | case PCI_DEVICE_ID_PROMISE_20262: | ||
| 1067 | case PCI_DEVICE_ID_PROMISE_20263: | ||
| 1068 | case PCI_DEVICE_ID_PROMISE_20265: | ||
| 1069 | case PCI_DEVICE_ID_PROMISE_20267: | ||
| 1070 | case PCI_DEVICE_ID_PROMISE_20268: | ||
| 1071 | case PCI_DEVICE_ID_PROMISE_20269: | ||
| 1072 | case PCI_DEVICE_ID_PROMISE_20270: | ||
| 1073 | case PCI_DEVICE_ID_PROMISE_20271: | ||
| 1074 | case PCI_DEVICE_ID_PROMISE_20275: | ||
| 1075 | case PCI_DEVICE_ID_PROMISE_20276: | ||
| 1076 | case PCI_DEVICE_ID_PROMISE_20277: | ||
| 1077 | goto good; | ||
| 1078 | } | ||
| 1079 | /* Others, check PCI class */ | ||
| 1080 | if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) | ||
| 1081 | return; | ||
| 1082 | good: | ||
| 1083 | pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); | ||
| 1084 | if ((progif & 5) != 5) { | ||
| 1085 | printk(KERN_INFO "Forcing PCI IDE into native mode: %s\n", pci_name(dev)); | ||
| 1086 | (void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5); | ||
| 1087 | if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) || | ||
| 1088 | (progif & 5) != 5) | ||
| 1089 | printk(KERN_ERR "Rewrite of PROGIF failed !\n"); | ||
| 1090 | } | ||
| 1091 | } | ||
| 1092 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata); | ||
| 1093 | |||
| 1094 | |||
| 1095 | /* | ||
| 1096 | * Disable second function on K2-SATA, it's broken | ||
| 1097 | * and disable IO BARs on first one | ||
| 1098 | */ | ||
| 1099 | void pmac_pci_fixup_k2_sata(struct pci_dev* dev) | ||
| 1100 | { | ||
| 1101 | int i; | ||
| 1102 | u16 cmd; | ||
| 1103 | |||
| 1104 | if (PCI_FUNC(dev->devfn) > 0) { | ||
| 1105 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
| 1106 | cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY); | ||
| 1107 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
| 1108 | for (i = 0; i < 6; i++) { | ||
| 1109 | dev->resource[i].start = dev->resource[i].end = 0; | ||
| 1110 | dev->resource[i].flags = 0; | ||
| 1111 | pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0); | ||
| 1112 | } | ||
| 1113 | } else { | ||
| 1114 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
| 1115 | cmd &= ~PCI_COMMAND_IO; | ||
| 1116 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
| 1117 | for (i = 0; i < 5; i++) { | ||
| 1118 | dev->resource[i].start = dev->resource[i].end = 0; | ||
| 1119 | dev->resource[i].flags = 0; | ||
| 1120 | pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0); | ||
| 1121 | } | ||
| 1122 | } | ||
| 1123 | } | ||
| 1124 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, pmac_pci_fixup_k2_sata); | ||
diff --git a/arch/ppc/platforms/pmac_pic.c b/arch/ppc/platforms/pmac_pic.c deleted file mode 100644 index 4742bf609357..000000000000 --- a/arch/ppc/platforms/pmac_pic.c +++ /dev/null | |||
| @@ -1,693 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Support for the interrupt controllers found on Power Macintosh, | ||
| 3 | * currently Apple's "Grand Central" interrupt controller in all | ||
| 4 | * it's incarnations. OpenPIC support used on newer machines is | ||
| 5 | * in a separate file | ||
| 6 | * | ||
| 7 | * Copyright (C) 1997 Paul Mackerras (paulus@cs.anu.edu.au) | ||
| 8 | * | ||
| 9 | * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org) | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or | ||
| 12 | * modify it under the terms of the GNU General Public License | ||
| 13 | * as published by the Free Software Foundation; either version | ||
| 14 | * 2 of the License, or (at your option) any later version. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/config.h> | ||
| 19 | #include <linux/stddef.h> | ||
| 20 | #include <linux/init.h> | ||
| 21 | #include <linux/sched.h> | ||
| 22 | #include <linux/signal.h> | ||
| 23 | #include <linux/pci.h> | ||
| 24 | #include <linux/interrupt.h> | ||
| 25 | #include <linux/sysdev.h> | ||
| 26 | #include <linux/adb.h> | ||
| 27 | #include <linux/pmu.h> | ||
| 28 | |||
| 29 | #include <asm/sections.h> | ||
| 30 | #include <asm/io.h> | ||
| 31 | #include <asm/smp.h> | ||
| 32 | #include <asm/prom.h> | ||
| 33 | #include <asm/pci-bridge.h> | ||
| 34 | #include <asm/time.h> | ||
| 35 | #include <asm/open_pic.h> | ||
| 36 | #include <asm/xmon.h> | ||
| 37 | #include <asm/pmac_feature.h> | ||
| 38 | #include <asm/machdep.h> | ||
| 39 | |||
| 40 | #include "pmac_pic.h" | ||
| 41 | |||
| 42 | /* | ||
| 43 | * XXX this should be in xmon.h, but putting it there means xmon.h | ||
| 44 | * has to include <linux/interrupt.h> (to get irqreturn_t), which | ||
| 45 | * causes all sorts of problems. -- paulus | ||
| 46 | */ | ||
| 47 | extern irqreturn_t xmon_irq(int, void *, struct pt_regs *); | ||
| 48 | |||
| 49 | struct pmac_irq_hw { | ||
| 50 | unsigned int event; | ||
| 51 | unsigned int enable; | ||
| 52 | unsigned int ack; | ||
| 53 | unsigned int level; | ||
| 54 | }; | ||
| 55 | |||
| 56 | /* Default addresses */ | ||
| 57 | static volatile struct pmac_irq_hw *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 | |||
| 64 | #define GC_LEVEL_MASK 0x3ff00000 | ||
| 65 | #define OHARE_LEVEL_MASK 0x1ff00000 | ||
| 66 | #define HEATHROW_LEVEL_MASK 0x1ff00000 | ||
| 67 | |||
| 68 | static int max_irqs; | ||
| 69 | static int max_real_irqs; | ||
| 70 | static u32 level_mask[4]; | ||
| 71 | |||
| 72 | static DEFINE_SPINLOCK(pmac_pic_lock); | ||
| 73 | |||
| 74 | |||
| 75 | #define GATWICK_IRQ_POOL_SIZE 10 | ||
| 76 | static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; | ||
| 77 | |||
| 78 | #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) | ||
| 79 | static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; | ||
| 80 | |||
| 81 | /* | ||
| 82 | * Mark an irq as "lost". This is only used on the pmac | ||
| 83 | * since it can lose interrupts (see pmac_set_irq_mask). | ||
| 84 | * -- Cort | ||
| 85 | */ | ||
| 86 | void | ||
| 87 | __set_lost(unsigned long irq_nr, int nokick) | ||
| 88 | { | ||
| 89 | if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) { | ||
| 90 | atomic_inc(&ppc_n_lost_interrupts); | ||
| 91 | if (!nokick) | ||
| 92 | set_dec(1); | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | static void | ||
| 97 | pmac_mask_and_ack_irq(unsigned int irq_nr) | ||
| 98 | { | ||
| 99 | unsigned long bit = 1UL << (irq_nr & 0x1f); | ||
| 100 | int i = irq_nr >> 5; | ||
| 101 | unsigned long flags; | ||
| 102 | |||
| 103 | if ((unsigned)irq_nr >= max_irqs) | ||
| 104 | return; | ||
| 105 | |||
| 106 | clear_bit(irq_nr, ppc_cached_irq_mask); | ||
| 107 | if (test_and_clear_bit(irq_nr, ppc_lost_interrupts)) | ||
| 108 | atomic_dec(&ppc_n_lost_interrupts); | ||
| 109 | spin_lock_irqsave(&pmac_pic_lock, flags); | ||
| 110 | out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]); | ||
| 111 | out_le32(&pmac_irq_hw[i]->ack, bit); | ||
| 112 | do { | ||
| 113 | /* make sure ack gets to controller before we enable | ||
| 114 | interrupts */ | ||
| 115 | mb(); | ||
| 116 | } while((in_le32(&pmac_irq_hw[i]->enable) & bit) | ||
| 117 | != (ppc_cached_irq_mask[i] & bit)); | ||
| 118 | spin_unlock_irqrestore(&pmac_pic_lock, flags); | ||
| 119 | } | ||
| 120 | |||
| 121 | static void pmac_set_irq_mask(unsigned int irq_nr, int nokicklost) | ||
| 122 | { | ||
| 123 | unsigned long bit = 1UL << (irq_nr & 0x1f); | ||
| 124 | int i = irq_nr >> 5; | ||
| 125 | unsigned long flags; | ||
| 126 | |||
| 127 | if ((unsigned)irq_nr >= max_irqs) | ||
| 128 | return; | ||
| 129 | |||
| 130 | spin_lock_irqsave(&pmac_pic_lock, flags); | ||
| 131 | /* enable unmasked interrupts */ | ||
| 132 | out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]); | ||
| 133 | |||
| 134 | do { | ||
| 135 | /* make sure mask gets to controller before we | ||
| 136 | return to user */ | ||
| 137 | mb(); | ||
| 138 | } while((in_le32(&pmac_irq_hw[i]->enable) & bit) | ||
| 139 | != (ppc_cached_irq_mask[i] & bit)); | ||
| 140 | |||
| 141 | /* | ||
| 142 | * Unfortunately, setting the bit in the enable register | ||
| 143 | * when the device interrupt is already on *doesn't* set | ||
| 144 | * the bit in the flag register or request another interrupt. | ||
| 145 | */ | ||
| 146 | if (bit & ppc_cached_irq_mask[i] & in_le32(&pmac_irq_hw[i]->level)) | ||
| 147 | __set_lost((ulong)irq_nr, nokicklost); | ||
| 148 | spin_unlock_irqrestore(&pmac_pic_lock, flags); | ||
| 149 | } | ||
| 150 | |||
| 151 | /* When an irq gets requested for the first client, if it's an | ||
| 152 | * edge interrupt, we clear any previous one on the controller | ||
| 153 | */ | ||
| 154 | static unsigned int pmac_startup_irq(unsigned int irq_nr) | ||
| 155 | { | ||
| 156 | unsigned long bit = 1UL << (irq_nr & 0x1f); | ||
| 157 | int i = irq_nr >> 5; | ||
| 158 | |||
| 159 | if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0) | ||
| 160 | out_le32(&pmac_irq_hw[i]->ack, bit); | ||
| 161 | set_bit(irq_nr, ppc_cached_irq_mask); | ||
| 162 | pmac_set_irq_mask(irq_nr, 0); | ||
| 163 | |||
| 164 | return 0; | ||
| 165 | } | ||
| 166 | |||
| 167 | static void pmac_mask_irq(unsigned int irq_nr) | ||
| 168 | { | ||
| 169 | clear_bit(irq_nr, ppc_cached_irq_mask); | ||
| 170 | pmac_set_irq_mask(irq_nr, 0); | ||
| 171 | mb(); | ||
| 172 | } | ||
| 173 | |||
| 174 | static void pmac_unmask_irq(unsigned int irq_nr) | ||
| 175 | { | ||
| 176 | set_bit(irq_nr, ppc_cached_irq_mask); | ||
| 177 | pmac_set_irq_mask(irq_nr, 0); | ||
| 178 | } | ||
| 179 | |||
| 180 | static void pmac_end_irq(unsigned int irq_nr) | ||
| 181 | { | ||
| 182 | if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS)) | ||
| 183 | && irq_desc[irq_nr].action) { | ||
| 184 | set_bit(irq_nr, ppc_cached_irq_mask); | ||
| 185 | pmac_set_irq_mask(irq_nr, 1); | ||
| 186 | } | ||
| 187 | } | ||
| 188 | |||
| 189 | |||
| 190 | struct hw_interrupt_type pmac_pic = { | ||
| 191 | .typename = " PMAC-PIC ", | ||
| 192 | .startup = pmac_startup_irq, | ||
| 193 | .enable = pmac_unmask_irq, | ||
| 194 | .disable = pmac_mask_irq, | ||
| 195 | .ack = pmac_mask_and_ack_irq, | ||
| 196 | .end = pmac_end_irq, | ||
| 197 | }; | ||
| 198 | |||
| 199 | struct hw_interrupt_type gatwick_pic = { | ||
| 200 | .typename = " GATWICK ", | ||
| 201 | .startup = pmac_startup_irq, | ||
| 202 | .enable = pmac_unmask_irq, | ||
| 203 | .disable = pmac_mask_irq, | ||
| 204 | .ack = pmac_mask_and_ack_irq, | ||
| 205 | .end = pmac_end_irq, | ||
| 206 | }; | ||
| 207 | |||
| 208 | static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs) | ||
| 209 | { | ||
| 210 | int irq, bits; | ||
| 211 | |||
| 212 | for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) { | ||
| 213 | int i = irq >> 5; | ||
| 214 | bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; | ||
| 215 | /* We must read level interrupts from the level register */ | ||
| 216 | bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]); | ||
| 217 | bits &= ppc_cached_irq_mask[i]; | ||
| 218 | if (bits == 0) | ||
| 219 | continue; | ||
| 220 | irq += __ilog2(bits); | ||
| 221 | __do_IRQ(irq, regs); | ||
| 222 | return IRQ_HANDLED; | ||
| 223 | } | ||
| 224 | printk("gatwick irq not from gatwick pic\n"); | ||
| 225 | return IRQ_NONE; | ||
| 226 | } | ||
| 227 | |||
| 228 | int | ||
| 229 | pmac_get_irq(struct pt_regs *regs) | ||
| 230 | { | ||
| 231 | int irq; | ||
| 232 | unsigned long bits = 0; | ||
| 233 | |||
| 234 | #ifdef CONFIG_SMP | ||
| 235 | void psurge_smp_message_recv(struct pt_regs *); | ||
| 236 | |||
| 237 | /* IPI's are a hack on the powersurge -- Cort */ | ||
| 238 | if ( smp_processor_id() != 0 ) { | ||
| 239 | psurge_smp_message_recv(regs); | ||
| 240 | return -2; /* ignore, already handled */ | ||
| 241 | } | ||
| 242 | #endif /* CONFIG_SMP */ | ||
| 243 | for (irq = max_real_irqs; (irq -= 32) >= 0; ) { | ||
| 244 | int i = irq >> 5; | ||
| 245 | bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; | ||
| 246 | /* We must read level interrupts from the level register */ | ||
| 247 | bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]); | ||
| 248 | bits &= ppc_cached_irq_mask[i]; | ||
| 249 | if (bits == 0) | ||
| 250 | continue; | ||
| 251 | irq += __ilog2(bits); | ||
| 252 | break; | ||
| 253 | } | ||
| 254 | |||
| 255 | return irq; | ||
| 256 | } | ||
| 257 | |||
| 258 | /* This routine will fix some missing interrupt values in the device tree | ||
| 259 | * on the gatwick mac-io controller used by some PowerBooks | ||
| 260 | */ | ||
| 261 | static void __init | ||
| 262 | pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base) | ||
| 263 | { | ||
| 264 | struct device_node *node; | ||
| 265 | int count; | ||
| 266 | |||
| 267 | memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool)); | ||
| 268 | node = gw->child; | ||
| 269 | count = 0; | ||
| 270 | while(node) | ||
| 271 | { | ||
| 272 | /* Fix SCC */ | ||
| 273 | if (strcasecmp(node->name, "escc") == 0) | ||
| 274 | if (node->child) { | ||
| 275 | if (node->child->n_intrs < 3) { | ||
| 276 | node->child->intrs = &gatwick_int_pool[count]; | ||
| 277 | count += 3; | ||
| 278 | } | ||
| 279 | node->child->n_intrs = 3; | ||
| 280 | node->child->intrs[0].line = 15+irq_base; | ||
| 281 | node->child->intrs[1].line = 4+irq_base; | ||
| 282 | node->child->intrs[2].line = 5+irq_base; | ||
| 283 | printk(KERN_INFO "irq: fixed SCC on second controller (%d,%d,%d)\n", | ||
| 284 | node->child->intrs[0].line, | ||
| 285 | node->child->intrs[1].line, | ||
| 286 | node->child->intrs[2].line); | ||
| 287 | } | ||
| 288 | /* Fix media-bay & left SWIM */ | ||
| 289 | if (strcasecmp(node->name, "media-bay") == 0) { | ||
| 290 | struct device_node* ya_node; | ||
| 291 | |||
| 292 | if (node->n_intrs == 0) | ||
| 293 | node->intrs = &gatwick_int_pool[count++]; | ||
| 294 | node->n_intrs = 1; | ||
| 295 | node->intrs[0].line = 29+irq_base; | ||
| 296 | printk(KERN_INFO "irq: fixed media-bay on second controller (%d)\n", | ||
| 297 | node->intrs[0].line); | ||
| 298 | |||
| 299 | ya_node = node->child; | ||
| 300 | while(ya_node) | ||
| 301 | { | ||
| 302 | if (strcasecmp(ya_node->name, "floppy") == 0) { | ||
| 303 | if (ya_node->n_intrs < 2) { | ||
| 304 | ya_node->intrs = &gatwick_int_pool[count]; | ||
| 305 | count += 2; | ||
| 306 | } | ||
| 307 | ya_node->n_intrs = 2; | ||
| 308 | ya_node->intrs[0].line = 19+irq_base; | ||
| 309 | ya_node->intrs[1].line = 1+irq_base; | ||
| 310 | printk(KERN_INFO "irq: fixed floppy on second controller (%d,%d)\n", | ||
| 311 | ya_node->intrs[0].line, ya_node->intrs[1].line); | ||
| 312 | } | ||
| 313 | if (strcasecmp(ya_node->name, "ata4") == 0) { | ||
| 314 | if (ya_node->n_intrs < 2) { | ||
| 315 | ya_node->intrs = &gatwick_int_pool[count]; | ||
| 316 | count += 2; | ||
| 317 | } | ||
| 318 | ya_node->n_intrs = 2; | ||
| 319 | ya_node->intrs[0].line = 14+irq_base; | ||
| 320 | ya_node->intrs[1].line = 3+irq_base; | ||
| 321 | printk(KERN_INFO "irq: fixed ide on second controller (%d,%d)\n", | ||
| 322 | ya_node->intrs[0].line, ya_node->intrs[1].line); | ||
| 323 | } | ||
| 324 | ya_node = ya_node->sibling; | ||
| 325 | } | ||
| 326 | } | ||
| 327 | node = node->sibling; | ||
| 328 | } | ||
| 329 | if (count > 10) { | ||
| 330 | printk("WARNING !! Gatwick interrupt pool overflow\n"); | ||
| 331 | printk(" GATWICK_IRQ_POOL_SIZE = %d\n", GATWICK_IRQ_POOL_SIZE); | ||
| 332 | printk(" requested = %d\n", count); | ||
| 333 | } | ||
| 334 | } | ||
| 335 | |||
| 336 | /* | ||
| 337 | * The PowerBook 3400/2400/3500 can have a combo ethernet/modem | ||
| 338 | * card which includes an ohare chip that acts as a second interrupt | ||
| 339 | * controller. If we find this second ohare, set it up and fix the | ||
| 340 | * interrupt value in the device tree for the ethernet chip. | ||
| 341 | */ | ||
| 342 | static int __init enable_second_ohare(void) | ||
| 343 | { | ||
| 344 | unsigned char bus, devfn; | ||
| 345 | unsigned short cmd; | ||
| 346 | unsigned long addr; | ||
| 347 | struct device_node *irqctrler = find_devices("pci106b,7"); | ||
| 348 | struct device_node *ether; | ||
| 349 | |||
| 350 | if (irqctrler == NULL || irqctrler->n_addrs <= 0) | ||
| 351 | return -1; | ||
| 352 | addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40); | ||
| 353 | pmac_irq_hw[1] = (volatile struct pmac_irq_hw *)(addr + 0x20); | ||
| 354 | max_irqs = 64; | ||
| 355 | if (pci_device_from_OF_node(irqctrler, &bus, &devfn) == 0) { | ||
| 356 | struct pci_controller* hose = pci_find_hose_for_OF_device(irqctrler); | ||
| 357 | if (!hose) | ||
| 358 | printk(KERN_ERR "Can't find PCI hose for OHare2 !\n"); | ||
| 359 | else { | ||
| 360 | early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd); | ||
| 361 | cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; | ||
| 362 | cmd &= ~PCI_COMMAND_IO; | ||
| 363 | early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd); | ||
| 364 | } | ||
| 365 | } | ||
| 366 | |||
| 367 | /* Fix interrupt for the modem/ethernet combo controller. The number | ||
| 368 | in the device tree (27) is bogus (correct for the ethernet-only | ||
| 369 | board but not the combo ethernet/modem board). | ||
| 370 | The real interrupt is 28 on the second controller -> 28+32 = 60. | ||
| 371 | */ | ||
| 372 | ether = find_devices("pci1011,14"); | ||
| 373 | if (ether && ether->n_intrs > 0) { | ||
| 374 | ether->intrs[0].line = 60; | ||
| 375 | printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n", | ||
| 376 | ether->intrs[0].line); | ||
| 377 | } | ||
| 378 | |||
| 379 | /* Return the interrupt number of the cascade */ | ||
| 380 | return irqctrler->intrs[0].line; | ||
| 381 | } | ||
| 382 | |||
| 383 | #ifdef CONFIG_POWER4 | ||
| 384 | static irqreturn_t k2u3_action(int cpl, void *dev_id, struct pt_regs *regs) | ||
| 385 | { | ||
| 386 | int irq; | ||
| 387 | |||
| 388 | irq = openpic2_get_irq(regs); | ||
| 389 | if (irq != -1) | ||
| 390 | __do_IRQ(irq, regs); | ||
| 391 | return IRQ_HANDLED; | ||
| 392 | } | ||
| 393 | |||
| 394 | static struct irqaction k2u3_cascade_action = { | ||
| 395 | .handler = k2u3_action, | ||
| 396 | .flags = 0, | ||
| 397 | .mask = CPU_MASK_NONE, | ||
| 398 | .name = "U3->K2 Cascade", | ||
| 399 | }; | ||
| 400 | #endif /* CONFIG_POWER4 */ | ||
| 401 | |||
| 402 | #ifdef CONFIG_XMON | ||
| 403 | static struct irqaction xmon_action = { | ||
| 404 | .handler = xmon_irq, | ||
| 405 | .flags = 0, | ||
| 406 | .mask = CPU_MASK_NONE, | ||
| 407 | .name = "NMI - XMON" | ||
| 408 | }; | ||
| 409 | #endif | ||
| 410 | |||
| 411 | static struct irqaction gatwick_cascade_action = { | ||
| 412 | .handler = gatwick_action, | ||
| 413 | .flags = SA_INTERRUPT, | ||
| 414 | .mask = CPU_MASK_NONE, | ||
| 415 | .name = "cascade", | ||
| 416 | }; | ||
| 417 | |||
| 418 | void __init pmac_pic_init(void) | ||
| 419 | { | ||
| 420 | int i; | ||
| 421 | struct device_node *irqctrler = NULL; | ||
| 422 | struct device_node *irqctrler2 = NULL; | ||
| 423 | struct device_node *np; | ||
| 424 | unsigned long addr; | ||
| 425 | int irq_cascade = -1; | ||
| 426 | |||
| 427 | /* We first try to detect Apple's new Core99 chipset, since mac-io | ||
| 428 | * is quite different on those machines and contains an IBM MPIC2. | ||
| 429 | */ | ||
| 430 | np = find_type_devices("open-pic"); | ||
| 431 | while(np) { | ||
| 432 | if (np->parent && !strcmp(np->parent->name, "u3")) | ||
| 433 | irqctrler2 = np; | ||
| 434 | else | ||
| 435 | irqctrler = np; | ||
| 436 | np = np->next; | ||
| 437 | } | ||
| 438 | if (irqctrler != NULL) | ||
| 439 | { | ||
| 440 | if (irqctrler->n_addrs > 0) | ||
| 441 | { | ||
| 442 | unsigned char senses[128]; | ||
| 443 | |||
| 444 | printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n", | ||
| 445 | irqctrler->addrs[0].address); | ||
| 446 | |||
| 447 | prom_get_irq_senses(senses, 0, 128); | ||
| 448 | OpenPIC_InitSenses = senses; | ||
| 449 | OpenPIC_NumInitSenses = 128; | ||
| 450 | ppc_md.get_irq = openpic_get_irq; | ||
| 451 | pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler, 0, 0); | ||
| 452 | OpenPIC_Addr = ioremap(irqctrler->addrs[0].address, | ||
| 453 | irqctrler->addrs[0].size); | ||
| 454 | openpic_init(0); | ||
| 455 | |||
| 456 | #ifdef CONFIG_POWER4 | ||
| 457 | if (irqctrler2 != NULL && irqctrler2->n_intrs > 0 && | ||
| 458 | irqctrler2->n_addrs > 0) { | ||
| 459 | printk(KERN_INFO "Slave OpenPIC at 0x%08x hooked on IRQ %d\n", | ||
| 460 | irqctrler2->addrs[0].address, | ||
| 461 | irqctrler2->intrs[0].line); | ||
| 462 | pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0); | ||
| 463 | OpenPIC2_Addr = ioremap(irqctrler2->addrs[0].address, | ||
| 464 | irqctrler2->addrs[0].size); | ||
| 465 | prom_get_irq_senses(senses, PMAC_OPENPIC2_OFFSET, | ||
| 466 | PMAC_OPENPIC2_OFFSET+128); | ||
| 467 | OpenPIC_InitSenses = senses; | ||
| 468 | OpenPIC_NumInitSenses = 128; | ||
| 469 | openpic2_init(PMAC_OPENPIC2_OFFSET); | ||
| 470 | |||
| 471 | if (setup_irq(irqctrler2->intrs[0].line, | ||
| 472 | &k2u3_cascade_action)) | ||
| 473 | printk("Unable to get OpenPIC IRQ for cascade\n"); | ||
| 474 | } | ||
| 475 | #endif /* CONFIG_POWER4 */ | ||
| 476 | |||
| 477 | #ifdef CONFIG_XMON | ||
| 478 | { | ||
| 479 | struct device_node* pswitch; | ||
| 480 | int nmi_irq; | ||
| 481 | |||
| 482 | pswitch = find_devices("programmer-switch"); | ||
| 483 | if (pswitch && pswitch->n_intrs) { | ||
| 484 | nmi_irq = pswitch->intrs[0].line; | ||
| 485 | openpic_init_nmi_irq(nmi_irq); | ||
| 486 | setup_irq(nmi_irq, &xmon_action); | ||
| 487 | } | ||
| 488 | } | ||
| 489 | #endif /* CONFIG_XMON */ | ||
| 490 | return; | ||
| 491 | } | ||
| 492 | irqctrler = NULL; | ||
| 493 | } | ||
| 494 | |||
| 495 | /* Get the level/edge settings, assume if it's not | ||
| 496 | * a Grand Central nor an OHare, then it's an Heathrow | ||
| 497 | * (or Paddington). | ||
| 498 | */ | ||
| 499 | if (find_devices("gc")) | ||
| 500 | level_mask[0] = GC_LEVEL_MASK; | ||
| 501 | else if (find_devices("ohare")) { | ||
| 502 | level_mask[0] = OHARE_LEVEL_MASK; | ||
| 503 | /* We might have a second cascaded ohare */ | ||
| 504 | level_mask[1] = OHARE_LEVEL_MASK; | ||
| 505 | } else { | ||
| 506 | level_mask[0] = HEATHROW_LEVEL_MASK; | ||
| 507 | level_mask[1] = 0; | ||
| 508 | /* We might have a second cascaded heathrow */ | ||
| 509 | level_mask[2] = HEATHROW_LEVEL_MASK; | ||
| 510 | level_mask[3] = 0; | ||
| 511 | } | ||
| 512 | |||
| 513 | /* | ||
| 514 | * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts, | ||
| 515 | * 1998 G3 Series PowerBooks have 128, | ||
| 516 | * other powermacs have 32. | ||
| 517 | * The combo ethernet/modem card for the Powerstar powerbooks | ||
| 518 | * (2400/3400/3500, ohare based) has a second ohare chip | ||
| 519 | * effectively making a total of 64. | ||
| 520 | */ | ||
| 521 | max_irqs = max_real_irqs = 32; | ||
| 522 | irqctrler = find_devices("mac-io"); | ||
| 523 | if (irqctrler) | ||
| 524 | { | ||
| 525 | max_real_irqs = 64; | ||
| 526 | if (irqctrler->next) | ||
| 527 | max_irqs = 128; | ||
| 528 | else | ||
| 529 | max_irqs = 64; | ||
| 530 | } | ||
| 531 | for ( i = 0; i < max_real_irqs ; i++ ) | ||
| 532 | irq_desc[i].handler = &pmac_pic; | ||
| 533 | |||
| 534 | /* get addresses of first controller */ | ||
| 535 | if (irqctrler) { | ||
| 536 | if (irqctrler->n_addrs > 0) { | ||
| 537 | addr = (unsigned long) | ||
| 538 | ioremap(irqctrler->addrs[0].address, 0x40); | ||
| 539 | for (i = 0; i < 2; ++i) | ||
| 540 | pmac_irq_hw[i] = (volatile struct pmac_irq_hw*) | ||
| 541 | (addr + (2 - i) * 0x10); | ||
| 542 | } | ||
| 543 | |||
| 544 | /* get addresses of second controller */ | ||
| 545 | irqctrler = irqctrler->next; | ||
| 546 | if (irqctrler && irqctrler->n_addrs > 0) { | ||
| 547 | addr = (unsigned long) | ||
| 548 | ioremap(irqctrler->addrs[0].address, 0x40); | ||
| 549 | for (i = 2; i < 4; ++i) | ||
| 550 | pmac_irq_hw[i] = (volatile struct pmac_irq_hw*) | ||
| 551 | (addr + (4 - i) * 0x10); | ||
| 552 | irq_cascade = irqctrler->intrs[0].line; | ||
| 553 | if (device_is_compatible(irqctrler, "gatwick")) | ||
| 554 | pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs); | ||
| 555 | } | ||
| 556 | } else { | ||
| 557 | /* older powermacs have a GC (grand central) or ohare at | ||
| 558 | f3000000, with interrupt control registers at f3000020. */ | ||
| 559 | addr = (unsigned long) ioremap(0xf3000000, 0x40); | ||
| 560 | pmac_irq_hw[0] = (volatile struct pmac_irq_hw *) (addr + 0x20); | ||
| 561 | } | ||
| 562 | |||
| 563 | /* PowerBooks 3400 and 3500 can have a second controller in a second | ||
| 564 | ohare chip, on the combo ethernet/modem card */ | ||
| 565 | if (machine_is_compatible("AAPL,3400/2400") | ||
| 566 | || machine_is_compatible("AAPL,3500")) | ||
| 567 | irq_cascade = enable_second_ohare(); | ||
| 568 | |||
| 569 | /* disable all interrupts in all controllers */ | ||
| 570 | for (i = 0; i * 32 < max_irqs; ++i) | ||
| 571 | out_le32(&pmac_irq_hw[i]->enable, 0); | ||
| 572 | /* mark level interrupts */ | ||
| 573 | for (i = 0; i < max_irqs; i++) | ||
| 574 | if (level_mask[i >> 5] & (1UL << (i & 0x1f))) | ||
| 575 | irq_desc[i].status = IRQ_LEVEL; | ||
| 576 | |||
| 577 | /* get interrupt line of secondary interrupt controller */ | ||
| 578 | if (irq_cascade >= 0) { | ||
| 579 | printk(KERN_INFO "irq: secondary controller on irq %d\n", | ||
| 580 | (int)irq_cascade); | ||
| 581 | for ( i = max_real_irqs ; i < max_irqs ; i++ ) | ||
| 582 | irq_desc[i].handler = &gatwick_pic; | ||
| 583 | setup_irq(irq_cascade, &gatwick_cascade_action); | ||
| 584 | } | ||
| 585 | printk("System has %d possible interrupts\n", max_irqs); | ||
| 586 | if (max_irqs != max_real_irqs) | ||
| 587 | printk(KERN_DEBUG "%d interrupts on main controller\n", | ||
| 588 | max_real_irqs); | ||
| 589 | |||
| 590 | #ifdef CONFIG_XMON | ||
| 591 | setup_irq(20, &xmon_action); | ||
| 592 | #endif /* CONFIG_XMON */ | ||
| 593 | } | ||
| 594 | |||
| 595 | #ifdef CONFIG_PM | ||
| 596 | /* | ||
| 597 | * These procedures are used in implementing sleep on the powerbooks. | ||
| 598 | * sleep_save_intrs() saves the states of all interrupt enables | ||
| 599 | * and disables all interrupts except for the nominated one. | ||
| 600 | * sleep_restore_intrs() restores the states of all interrupt enables. | ||
| 601 | */ | ||
| 602 | unsigned long sleep_save_mask[2]; | ||
| 603 | |||
| 604 | /* This used to be passed by the PMU driver but that link got | ||
| 605 | * broken with the new driver model. We use this tweak for now... | ||
| 606 | */ | ||
| 607 | static int pmacpic_find_viaint(void) | ||
| 608 | { | ||
| 609 | int viaint = -1; | ||
| 610 | |||
| 611 | #ifdef CONFIG_ADB_PMU | ||
| 612 | struct device_node *np; | ||
| 613 | |||
| 614 | if (pmu_get_model() != PMU_OHARE_BASED) | ||
| 615 | goto not_found; | ||
| 616 | np = of_find_node_by_name(NULL, "via-pmu"); | ||
| 617 | if (np == NULL) | ||
| 618 | goto not_found; | ||
| 619 | viaint = np->intrs[0].line; | ||
| 620 | #endif /* CONFIG_ADB_PMU */ | ||
| 621 | |||
| 622 | not_found: | ||
| 623 | return viaint; | ||
| 624 | } | ||
| 625 | |||
| 626 | static int pmacpic_suspend(struct sys_device *sysdev, pm_message_t state) | ||
| 627 | { | ||
| 628 | int viaint = pmacpic_find_viaint(); | ||
| 629 | |||
| 630 | sleep_save_mask[0] = ppc_cached_irq_mask[0]; | ||
| 631 | sleep_save_mask[1] = ppc_cached_irq_mask[1]; | ||
| 632 | ppc_cached_irq_mask[0] = 0; | ||
| 633 | ppc_cached_irq_mask[1] = 0; | ||
| 634 | if (viaint > 0) | ||
| 635 | set_bit(viaint, ppc_cached_irq_mask); | ||
| 636 | out_le32(&pmac_irq_hw[0]->enable, ppc_cached_irq_mask[0]); | ||
| 637 | if (max_real_irqs > 32) | ||
| 638 | out_le32(&pmac_irq_hw[1]->enable, ppc_cached_irq_mask[1]); | ||
| 639 | (void)in_le32(&pmac_irq_hw[0]->event); | ||
| 640 | /* make sure mask gets to controller before we return to caller */ | ||
| 641 | mb(); | ||
| 642 | (void)in_le32(&pmac_irq_hw[0]->enable); | ||
| 643 | |||
| 644 | return 0; | ||
| 645 | } | ||
| 646 | |||
| 647 | static int pmacpic_resume(struct sys_device *sysdev) | ||
| 648 | { | ||
| 649 | int i; | ||
| 650 | |||
| 651 | out_le32(&pmac_irq_hw[0]->enable, 0); | ||
| 652 | if (max_real_irqs > 32) | ||
| 653 | out_le32(&pmac_irq_hw[1]->enable, 0); | ||
| 654 | mb(); | ||
| 655 | for (i = 0; i < max_real_irqs; ++i) | ||
| 656 | if (test_bit(i, sleep_save_mask)) | ||
| 657 | pmac_unmask_irq(i); | ||
| 658 | |||
| 659 | return 0; | ||
| 660 | } | ||
| 661 | |||
| 662 | #endif /* CONFIG_PM */ | ||
| 663 | |||
| 664 | static struct sysdev_class pmacpic_sysclass = { | ||
| 665 | set_kset_name("pmac_pic"), | ||
| 666 | }; | ||
| 667 | |||
| 668 | static struct sys_device device_pmacpic = { | ||
| 669 | .id = 0, | ||
| 670 | .cls = &pmacpic_sysclass, | ||
| 671 | }; | ||
| 672 | |||
| 673 | static struct sysdev_driver driver_pmacpic = { | ||
| 674 | #ifdef CONFIG_PM | ||
| 675 | .suspend = &pmacpic_suspend, | ||
| 676 | .resume = &pmacpic_resume, | ||
| 677 | #endif /* CONFIG_PM */ | ||
| 678 | }; | ||
| 679 | |||
| 680 | static int __init init_pmacpic_sysfs(void) | ||
| 681 | { | ||
| 682 | if (max_irqs == 0) | ||
| 683 | return -ENODEV; | ||
| 684 | |||
| 685 | printk(KERN_DEBUG "Registering pmac pic with sysfs...\n"); | ||
| 686 | sysdev_class_register(&pmacpic_sysclass); | ||
| 687 | sysdev_register(&device_pmacpic); | ||
| 688 | sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic); | ||
| 689 | return 0; | ||
| 690 | } | ||
| 691 | |||
| 692 | subsys_initcall(init_pmacpic_sysfs); | ||
| 693 | |||
diff --git a/arch/ppc/platforms/pmac_pic.h b/arch/ppc/platforms/pmac_pic.h deleted file mode 100644 index 664103dfeef9..000000000000 --- a/arch/ppc/platforms/pmac_pic.h +++ /dev/null | |||
| @@ -1,11 +0,0 @@ | |||
| 1 | #ifndef __PPC_PLATFORMS_PMAC_PIC_H | ||
| 2 | #define __PPC_PLATFORMS_PMAC_PIC_H | ||
| 3 | |||
| 4 | #include <linux/irq.h> | ||
| 5 | |||
| 6 | extern struct hw_interrupt_type pmac_pic; | ||
| 7 | |||
| 8 | void pmac_pic_init(void); | ||
| 9 | int pmac_get_irq(struct pt_regs *regs); | ||
| 10 | |||
| 11 | #endif /* __PPC_PLATFORMS_PMAC_PIC_H */ | ||
diff --git a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c deleted file mode 100644 index 55d2beffe560..000000000000 --- a/arch/ppc/platforms/pmac_setup.c +++ /dev/null | |||
| @@ -1,745 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * arch/ppc/platforms/setup.c | ||
| 3 | * | ||
| 4 | * PowerPC version | ||
| 5 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) | ||
| 6 | * | ||
| 7 | * Adapted for Power Macintosh by Paul Mackerras | ||
| 8 | * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) | ||
| 9 | * | ||
| 10 | * Derived from "arch/alpha/kernel/setup.c" | ||
| 11 | * Copyright (C) 1995 Linus Torvalds | ||
| 12 | * | ||
| 13 | * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org) | ||
| 14 | * | ||
| 15 | * This program is free software; you can redistribute it and/or | ||
| 16 | * modify it under the terms of the GNU General Public License | ||
| 17 | * as published by the Free Software Foundation; either version | ||
| 18 | * 2 of the License, or (at your option) any later version. | ||
| 19 | * | ||
| 20 | */ | ||
| 21 | |||
| 22 | /* | ||
| 23 | * bootup setup stuff.. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include <linux/config.h> | ||
| 27 | #include <linux/init.h> | ||
| 28 | #include <linux/errno.h> | ||
| 29 | #include <linux/sched.h> | ||
| 30 | #include <linux/kernel.h> | ||
| 31 | #include <linux/mm.h> | ||
| 32 | #include <linux/stddef.h> | ||
| 33 | #include <linux/unistd.h> | ||
| 34 | #include <linux/ptrace.h> | ||
| 35 | #include <linux/slab.h> | ||
| 36 | #include <linux/user.h> | ||
| 37 | #include <linux/a.out.h> | ||
| 38 | #include <linux/tty.h> | ||
| 39 | #include <linux/string.h> | ||
| 40 | #include <linux/delay.h> | ||
| 41 | #include <linux/ioport.h> | ||
| 42 | #include <linux/major.h> | ||
| 43 | #include <linux/initrd.h> | ||
| 44 | #include <linux/vt_kern.h> | ||
| 45 | #include <linux/console.h> | ||
| 46 | #include <linux/ide.h> | ||
| 47 | #include <linux/pci.h> | ||
| 48 | #include <linux/adb.h> | ||
| 49 | #include <linux/cuda.h> | ||
| 50 | #include <linux/pmu.h> | ||
| 51 | #include <linux/seq_file.h> | ||
| 52 | #include <linux/root_dev.h> | ||
| 53 | #include <linux/bitops.h> | ||
| 54 | #include <linux/suspend.h> | ||
| 55 | |||
| 56 | #include <asm/reg.h> | ||
| 57 | #include <asm/sections.h> | ||
| 58 | #include <asm/prom.h> | ||
| 59 | #include <asm/system.h> | ||
| 60 | #include <asm/pgtable.h> | ||
| 61 | #include <asm/io.h> | ||
| 62 | #include <asm/pci-bridge.h> | ||
| 63 | #include <asm/ohare.h> | ||
| 64 | #include <asm/mediabay.h> | ||
| 65 | #include <asm/machdep.h> | ||
| 66 | #include <asm/dma.h> | ||
| 67 | #include <asm/bootx.h> | ||
| 68 | #include <asm/cputable.h> | ||
| 69 | #include <asm/btext.h> | ||
| 70 | #include <asm/pmac_feature.h> | ||
| 71 | #include <asm/time.h> | ||
| 72 | #include <asm/of_device.h> | ||
| 73 | #include <asm/mmu_context.h> | ||
| 74 | |||
| 75 | #include "pmac_pic.h" | ||
| 76 | #include "mem_pieces.h" | ||
| 77 | |||
| 78 | #undef SHOW_GATWICK_IRQS | ||
| 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 | struct device_node *memory_node; | ||
| 99 | |||
| 100 | unsigned char drive_info; | ||
| 101 | |||
| 102 | int ppc_override_l2cr = 0; | ||
| 103 | int ppc_override_l2cr_value; | ||
| 104 | int has_l2cache = 0; | ||
| 105 | |||
| 106 | static int current_root_goodness = -1; | ||
| 107 | |||
| 108 | extern int pmac_newworld; | ||
| 109 | |||
| 110 | #define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */ | ||
| 111 | |||
| 112 | extern void zs_kgdb_hook(int tty_num); | ||
| 113 | static void ohare_init(void); | ||
| 114 | #ifdef CONFIG_BOOTX_TEXT | ||
| 115 | static void pmac_progress(char *s, unsigned short hex); | ||
| 116 | #endif | ||
| 117 | |||
| 118 | sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN; | ||
| 119 | |||
| 120 | #ifdef CONFIG_SMP | ||
| 121 | extern struct smp_ops_t psurge_smp_ops; | ||
| 122 | extern struct smp_ops_t core99_smp_ops; | ||
| 123 | #endif /* CONFIG_SMP */ | ||
| 124 | |||
| 125 | static int | ||
| 126 | pmac_show_cpuinfo(struct seq_file *m) | ||
| 127 | { | ||
| 128 | struct device_node *np; | ||
| 129 | char *pp; | ||
| 130 | int plen; | ||
| 131 | int mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, | ||
| 132 | NULL, PMAC_MB_INFO_MODEL, 0); | ||
| 133 | unsigned int mbflags = (unsigned int)pmac_call_feature(PMAC_FTR_GET_MB_INFO, | ||
| 134 | NULL, PMAC_MB_INFO_FLAGS, 0); | ||
| 135 | char* mbname; | ||
| 136 | |||
| 137 | if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, (int)&mbname) != 0) | ||
| 138 | mbname = "Unknown"; | ||
| 139 | |||
| 140 | /* find motherboard type */ | ||
| 141 | seq_printf(m, "machine\t\t: "); | ||
| 142 | np = find_devices("device-tree"); | ||
| 143 | if (np != NULL) { | ||
| 144 | pp = (char *) get_property(np, "model", NULL); | ||
| 145 | if (pp != NULL) | ||
| 146 | seq_printf(m, "%s\n", pp); | ||
| 147 | else | ||
| 148 | seq_printf(m, "PowerMac\n"); | ||
| 149 | pp = (char *) get_property(np, "compatible", &plen); | ||
| 150 | if (pp != NULL) { | ||
| 151 | seq_printf(m, "motherboard\t:"); | ||
| 152 | while (plen > 0) { | ||
| 153 | int l = strlen(pp) + 1; | ||
| 154 | seq_printf(m, " %s", pp); | ||
| 155 | plen -= l; | ||
| 156 | pp += l; | ||
| 157 | } | ||
| 158 | seq_printf(m, "\n"); | ||
| 159 | } | ||
| 160 | } else | ||
| 161 | seq_printf(m, "PowerMac\n"); | ||
| 162 | |||
| 163 | /* print parsed model */ | ||
| 164 | seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname); | ||
| 165 | seq_printf(m, "pmac flags\t: %08x\n", mbflags); | ||
| 166 | |||
| 167 | /* find l2 cache info */ | ||
| 168 | np = find_devices("l2-cache"); | ||
| 169 | if (np == 0) | ||
| 170 | np = find_type_devices("cache"); | ||
| 171 | if (np != 0) { | ||
| 172 | unsigned int *ic = (unsigned int *) | ||
| 173 | get_property(np, "i-cache-size", NULL); | ||
| 174 | unsigned int *dc = (unsigned int *) | ||
| 175 | get_property(np, "d-cache-size", NULL); | ||
| 176 | seq_printf(m, "L2 cache\t:"); | ||
| 177 | has_l2cache = 1; | ||
| 178 | if (get_property(np, "cache-unified", NULL) != 0 && dc) { | ||
| 179 | seq_printf(m, " %dK unified", *dc / 1024); | ||
| 180 | } else { | ||
| 181 | if (ic) | ||
| 182 | seq_printf(m, " %dK instruction", *ic / 1024); | ||
| 183 | if (dc) | ||
| 184 | seq_printf(m, "%s %dK data", | ||
| 185 | (ic? " +": ""), *dc / 1024); | ||
| 186 | } | ||
| 187 | pp = get_property(np, "ram-type", NULL); | ||
| 188 | if (pp) | ||
| 189 | seq_printf(m, " %s", pp); | ||
| 190 | seq_printf(m, "\n"); | ||
| 191 | } | ||
| 192 | |||
| 193 | /* find ram info */ | ||
| 194 | np = find_devices("memory"); | ||
| 195 | if (np != 0) { | ||
| 196 | int n; | ||
| 197 | struct reg_property *reg = (struct reg_property *) | ||
| 198 | get_property(np, "reg", &n); | ||
| 199 | |||
| 200 | if (reg != 0) { | ||
| 201 | unsigned long total = 0; | ||
| 202 | |||
| 203 | for (n /= sizeof(struct reg_property); n > 0; --n) | ||
| 204 | total += (reg++)->size; | ||
| 205 | seq_printf(m, "memory\t\t: %luMB\n", total >> 20); | ||
| 206 | } | ||
| 207 | } | ||
| 208 | |||
| 209 | /* Checks "l2cr-value" property in the registry */ | ||
| 210 | np = find_devices("cpus"); | ||
| 211 | if (np == 0) | ||
| 212 | np = find_type_devices("cpu"); | ||
| 213 | if (np != 0) { | ||
| 214 | unsigned int *l2cr = (unsigned int *) | ||
| 215 | get_property(np, "l2cr-value", NULL); | ||
| 216 | if (l2cr != 0) { | ||
| 217 | seq_printf(m, "l2cr override\t: 0x%x\n", *l2cr); | ||
| 218 | } | ||
| 219 | } | ||
| 220 | |||
| 221 | /* Indicate newworld/oldworld */ | ||
| 222 | seq_printf(m, "pmac-generation\t: %s\n", | ||
| 223 | pmac_newworld ? "NewWorld" : "OldWorld"); | ||
| 224 | |||
| 225 | |||
| 226 | return 0; | ||
| 227 | } | ||
| 228 | |||
| 229 | static int | ||
| 230 | pmac_show_percpuinfo(struct seq_file *m, int i) | ||
| 231 | { | ||
| 232 | #ifdef CONFIG_CPU_FREQ_PMAC | ||
| 233 | extern unsigned int pmac_get_one_cpufreq(int i); | ||
| 234 | unsigned int freq = pmac_get_one_cpufreq(i); | ||
| 235 | if (freq != 0) { | ||
| 236 | seq_printf(m, "clock\t\t: %dMHz\n", freq/1000); | ||
| 237 | return 0; | ||
| 238 | } | ||
| 239 | #endif /* CONFIG_CPU_FREQ_PMAC */ | ||
| 240 | return of_show_percpuinfo(m, i); | ||
| 241 | } | ||
| 242 | |||
| 243 | static volatile u32 *sysctrl_regs; | ||
| 244 | |||
| 245 | void __init | ||
| 246 | pmac_setup_arch(void) | ||
| 247 | { | ||
| 248 | struct device_node *cpu; | ||
| 249 | int *fp; | ||
| 250 | unsigned long pvr; | ||
| 251 | |||
| 252 | pvr = PVR_VER(mfspr(SPRN_PVR)); | ||
| 253 | |||
| 254 | /* Set loops_per_jiffy to a half-way reasonable value, | ||
| 255 | for use until calibrate_delay gets called. */ | ||
| 256 | cpu = find_type_devices("cpu"); | ||
| 257 | if (cpu != 0) { | ||
| 258 | fp = (int *) get_property(cpu, "clock-frequency", NULL); | ||
| 259 | if (fp != 0) { | ||
| 260 | if (pvr == 4 || pvr >= 8) | ||
| 261 | /* 604, G3, G4 etc. */ | ||
| 262 | loops_per_jiffy = *fp / HZ; | ||
| 263 | else | ||
| 264 | /* 601, 603, etc. */ | ||
| 265 | loops_per_jiffy = *fp / (2*HZ); | ||
| 266 | } else | ||
| 267 | loops_per_jiffy = 50000000 / HZ; | ||
| 268 | } | ||
| 269 | |||
| 270 | /* this area has the CPU identification register | ||
| 271 | and some registers used by smp boards */ | ||
| 272 | sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000); | ||
| 273 | ohare_init(); | ||
| 274 | |||
| 275 | /* Lookup PCI hosts */ | ||
| 276 | pmac_find_bridges(); | ||
| 277 | |||
| 278 | /* Checks "l2cr-value" property in the registry */ | ||
| 279 | if (cpu_has_feature(CPU_FTR_L2CR)) { | ||
| 280 | struct device_node *np = find_devices("cpus"); | ||
| 281 | if (np == 0) | ||
| 282 | np = find_type_devices("cpu"); | ||
| 283 | if (np != 0) { | ||
| 284 | unsigned int *l2cr = (unsigned int *) | ||
| 285 | get_property(np, "l2cr-value", NULL); | ||
| 286 | if (l2cr != 0) { | ||
| 287 | ppc_override_l2cr = 1; | ||
| 288 | ppc_override_l2cr_value = *l2cr; | ||
| 289 | _set_L2CR(0); | ||
| 290 | _set_L2CR(ppc_override_l2cr_value); | ||
| 291 | } | ||
| 292 | } | ||
| 293 | } | ||
| 294 | |||
| 295 | if (ppc_override_l2cr) | ||
| 296 | printk(KERN_INFO "L2CR overriden (0x%x), backside cache is %s\n", | ||
| 297 | ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000) | ||
| 298 | ? "enabled" : "disabled"); | ||
| 299 | |||
| 300 | #ifdef CONFIG_KGDB | ||
| 301 | zs_kgdb_hook(0); | ||
| 302 | #endif | ||
| 303 | |||
| 304 | #ifdef CONFIG_ADB_CUDA | ||
| 305 | find_via_cuda(); | ||
| 306 | #else | ||
| 307 | if (find_devices("via-cuda")) { | ||
| 308 | printk("WARNING ! Your machine is Cuda based but your kernel\n"); | ||
| 309 | printk(" wasn't compiled with CONFIG_ADB_CUDA option !\n"); | ||
| 310 | } | ||
| 311 | #endif | ||
| 312 | #ifdef CONFIG_ADB_PMU | ||
| 313 | find_via_pmu(); | ||
| 314 | #else | ||
| 315 | if (find_devices("via-pmu")) { | ||
| 316 | printk("WARNING ! Your machine is PMU based but your kernel\n"); | ||
| 317 | printk(" wasn't compiled with CONFIG_ADB_PMU option !\n"); | ||
| 318 | } | ||
| 319 | #endif | ||
| 320 | #ifdef CONFIG_NVRAM | ||
| 321 | pmac_nvram_init(); | ||
| 322 | #endif | ||
| 323 | #ifdef CONFIG_BLK_DEV_INITRD | ||
| 324 | if (initrd_start) | ||
| 325 | ROOT_DEV = Root_RAM0; | ||
| 326 | else | ||
| 327 | #endif | ||
| 328 | ROOT_DEV = DEFAULT_ROOT_DEVICE; | ||
| 329 | |||
| 330 | #ifdef CONFIG_SMP | ||
| 331 | /* Check for Core99 */ | ||
| 332 | if (find_devices("uni-n") || find_devices("u3")) | ||
| 333 | smp_ops = &core99_smp_ops; | ||
| 334 | else | ||
| 335 | smp_ops = &psurge_smp_ops; | ||
| 336 | #endif /* CONFIG_SMP */ | ||
| 337 | |||
| 338 | pci_create_OF_bus_map(); | ||
| 339 | } | ||
| 340 | |||
| 341 | static void __init ohare_init(void) | ||
| 342 | { | ||
| 343 | /* | ||
| 344 | * Turn on the L2 cache. | ||
| 345 | * We assume that we have a PSX memory controller iff | ||
| 346 | * we have an ohare I/O controller. | ||
| 347 | */ | ||
| 348 | if (find_devices("ohare") != NULL) { | ||
| 349 | if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) { | ||
| 350 | if (sysctrl_regs[4] & 0x10) | ||
| 351 | sysctrl_regs[4] |= 0x04000020; | ||
| 352 | else | ||
| 353 | sysctrl_regs[4] |= 0x04000000; | ||
| 354 | if(has_l2cache) | ||
| 355 | printk(KERN_INFO "Level 2 cache enabled\n"); | ||
| 356 | } | ||
| 357 | } | ||
| 358 | } | ||
| 359 | |||
| 360 | extern char *bootpath; | ||
| 361 | extern char *bootdevice; | ||
| 362 | void *boot_host; | ||
| 363 | int boot_target; | ||
| 364 | int boot_part; | ||
| 365 | extern dev_t boot_dev; | ||
| 366 | |||
| 367 | #ifdef CONFIG_SCSI | ||
| 368 | void __init | ||
| 369 | note_scsi_host(struct device_node *node, void *host) | ||
| 370 | { | ||
| 371 | int l; | ||
| 372 | char *p; | ||
| 373 | |||
| 374 | l = strlen(node->full_name); | ||
| 375 | if (bootpath != NULL && bootdevice != NULL | ||
| 376 | && strncmp(node->full_name, bootdevice, l) == 0 | ||
| 377 | && (bootdevice[l] == '/' || bootdevice[l] == 0)) { | ||
| 378 | boot_host = host; | ||
| 379 | /* | ||
| 380 | * There's a bug in OF 1.0.5. (Why am I not surprised.) | ||
| 381 | * If you pass a path like scsi/sd@1:0 to canon, it returns | ||
| 382 | * something like /bandit@F2000000/gc@10/53c94@10000/sd@0,0 | ||
| 383 | * That is, the scsi target number doesn't get preserved. | ||
| 384 | * So we pick the target number out of bootpath and use that. | ||
| 385 | */ | ||
| 386 | p = strstr(bootpath, "/sd@"); | ||
| 387 | if (p != NULL) { | ||
| 388 | p += 4; | ||
| 389 | boot_target = simple_strtoul(p, NULL, 10); | ||
| 390 | p = strchr(p, ':'); | ||
| 391 | if (p != NULL) | ||
| 392 | boot_part = simple_strtoul(p + 1, NULL, 10); | ||
| 393 | } | ||
| 394 | } | ||
| 395 | } | ||
| 396 | #endif | ||
| 397 | |||
| 398 | #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) | ||
| 399 | static dev_t __init | ||
| 400 | find_ide_boot(void) | ||
| 401 | { | ||
| 402 | char *p; | ||
| 403 | int n; | ||
| 404 | dev_t __init pmac_find_ide_boot(char *bootdevice, int n); | ||
| 405 | |||
| 406 | if (bootdevice == NULL) | ||
| 407 | return 0; | ||
| 408 | p = strrchr(bootdevice, '/'); | ||
| 409 | if (p == NULL) | ||
| 410 | return 0; | ||
| 411 | n = p - bootdevice; | ||
| 412 | |||
| 413 | return pmac_find_ide_boot(bootdevice, n); | ||
| 414 | } | ||
| 415 | #endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */ | ||
| 416 | |||
| 417 | static void __init | ||
| 418 | find_boot_device(void) | ||
| 419 | { | ||
| 420 | #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) | ||
| 421 | boot_dev = find_ide_boot(); | ||
| 422 | #endif | ||
| 423 | } | ||
| 424 | |||
| 425 | static int initializing = 1; | ||
| 426 | /* TODO: Merge the suspend-to-ram with the common code !!! | ||
| 427 | * currently, this is a stub implementation for suspend-to-disk | ||
| 428 | * only | ||
| 429 | */ | ||
| 430 | |||
| 431 | #ifdef CONFIG_SOFTWARE_SUSPEND | ||
| 432 | |||
| 433 | static int pmac_pm_prepare(suspend_state_t state) | ||
| 434 | { | ||
| 435 | printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); | ||
| 436 | |||
| 437 | return 0; | ||
| 438 | } | ||
| 439 | |||
| 440 | static int pmac_pm_enter(suspend_state_t state) | ||
| 441 | { | ||
| 442 | printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); | ||
| 443 | |||
| 444 | /* Giveup the lazy FPU & vec so we don't have to back them | ||
| 445 | * up from the low level code | ||
| 446 | */ | ||
| 447 | enable_kernel_fp(); | ||
| 448 | |||
| 449 | #ifdef CONFIG_ALTIVEC | ||
| 450 | if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC) | ||
| 451 | enable_kernel_altivec(); | ||
| 452 | #endif /* CONFIG_ALTIVEC */ | ||
| 453 | |||
| 454 | return 0; | ||
| 455 | } | ||
| 456 | |||
| 457 | static int pmac_pm_finish(suspend_state_t state) | ||
| 458 | { | ||
| 459 | printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); | ||
| 460 | |||
| 461 | /* Restore userland MMU context */ | ||
| 462 | set_context(current->active_mm->context, current->active_mm->pgd); | ||
| 463 | |||
| 464 | return 0; | ||
| 465 | } | ||
| 466 | |||
| 467 | static struct pm_ops pmac_pm_ops = { | ||
| 468 | .pm_disk_mode = PM_DISK_SHUTDOWN, | ||
| 469 | .prepare = pmac_pm_prepare, | ||
| 470 | .enter = pmac_pm_enter, | ||
| 471 | .finish = pmac_pm_finish, | ||
| 472 | }; | ||
| 473 | |||
| 474 | #endif /* CONFIG_SOFTWARE_SUSPEND */ | ||
| 475 | |||
| 476 | static int pmac_late_init(void) | ||
| 477 | { | ||
| 478 | initializing = 0; | ||
| 479 | #ifdef CONFIG_SOFTWARE_SUSPEND | ||
| 480 | pm_set_ops(&pmac_pm_ops); | ||
| 481 | #endif /* CONFIG_SOFTWARE_SUSPEND */ | ||
| 482 | return 0; | ||
| 483 | } | ||
| 484 | |||
| 485 | late_initcall(pmac_late_init); | ||
| 486 | |||
| 487 | /* can't be __init - can be called whenever a disk is first accessed */ | ||
| 488 | void | ||
| 489 | note_bootable_part(dev_t dev, int part, int goodness) | ||
| 490 | { | ||
| 491 | static int found_boot = 0; | ||
| 492 | char *p; | ||
| 493 | |||
| 494 | if (!initializing) | ||
| 495 | return; | ||
| 496 | if ((goodness <= current_root_goodness) && | ||
| 497 | ROOT_DEV != DEFAULT_ROOT_DEVICE) | ||
| 498 | return; | ||
| 499 | p = strstr(saved_command_line, "root="); | ||
| 500 | if (p != NULL && (p == saved_command_line || p[-1] == ' ')) | ||
| 501 | return; | ||
| 502 | |||
| 503 | if (!found_boot) { | ||
| 504 | find_boot_device(); | ||
| 505 | found_boot = 1; | ||
| 506 | } | ||
| 507 | if (!boot_dev || dev == boot_dev) { | ||
| 508 | ROOT_DEV = dev + part; | ||
| 509 | boot_dev = 0; | ||
| 510 | current_root_goodness = goodness; | ||
| 511 | } | ||
| 512 | } | ||
| 513 | |||
| 514 | static void | ||
| 515 | pmac_restart(char *cmd) | ||
| 516 | { | ||
| 517 | #ifdef CONFIG_ADB_CUDA | ||
| 518 | struct adb_request req; | ||
| 519 | #endif /* CONFIG_ADB_CUDA */ | ||
| 520 | |||
| 521 | switch (sys_ctrler) { | ||
| 522 | #ifdef CONFIG_ADB_CUDA | ||
| 523 | case SYS_CTRLER_CUDA: | ||
| 524 | cuda_request(&req, NULL, 2, CUDA_PACKET, | ||
| 525 | CUDA_RESET_SYSTEM); | ||
| 526 | for (;;) | ||
| 527 | cuda_poll(); | ||
| 528 | break; | ||
| 529 | #endif /* CONFIG_ADB_CUDA */ | ||
| 530 | #ifdef CONFIG_ADB_PMU | ||
| 531 | case SYS_CTRLER_PMU: | ||
| 532 | pmu_restart(); | ||
| 533 | break; | ||
| 534 | #endif /* CONFIG_ADB_PMU */ | ||
| 535 | default: ; | ||
| 536 | } | ||
| 537 | } | ||
| 538 | |||
| 539 | static void | ||
| 540 | pmac_power_off(void) | ||
| 541 | { | ||
| 542 | #ifdef CONFIG_ADB_CUDA | ||
| 543 | struct adb_request req; | ||
| 544 | #endif /* CONFIG_ADB_CUDA */ | ||
| 545 | |||
| 546 | switch (sys_ctrler) { | ||
| 547 | #ifdef CONFIG_ADB_CUDA | ||
| 548 | case SYS_CTRLER_CUDA: | ||
| 549 | cuda_request(&req, NULL, 2, CUDA_PACKET, | ||
| 550 | CUDA_POWERDOWN); | ||
| 551 | for (;;) | ||
| 552 | cuda_poll(); | ||
| 553 | break; | ||
| 554 | #endif /* CONFIG_ADB_CUDA */ | ||
| 555 | #ifdef CONFIG_ADB_PMU | ||
| 556 | case SYS_CTRLER_PMU: | ||
| 557 | pmu_shutdown(); | ||
| 558 | break; | ||
| 559 | #endif /* CONFIG_ADB_PMU */ | ||
| 560 | default: ; | ||
| 561 | } | ||
| 562 | } | ||
| 563 | |||
| 564 | static void | ||
| 565 | pmac_halt(void) | ||
| 566 | { | ||
| 567 | pmac_power_off(); | ||
| 568 | } | ||
| 569 | |||
| 570 | /* | ||
| 571 | * Read in a property describing some pieces of memory. | ||
| 572 | */ | ||
| 573 | |||
| 574 | static int __init | ||
| 575 | get_mem_prop(char *name, struct mem_pieces *mp) | ||
| 576 | { | ||
| 577 | struct reg_property *rp; | ||
| 578 | int i, s; | ||
| 579 | unsigned int *ip; | ||
| 580 | int nac = prom_n_addr_cells(memory_node); | ||
| 581 | int nsc = prom_n_size_cells(memory_node); | ||
| 582 | |||
| 583 | ip = (unsigned int *) get_property(memory_node, name, &s); | ||
| 584 | if (ip == NULL) { | ||
| 585 | printk(KERN_ERR "error: couldn't get %s property on /memory\n", | ||
| 586 | name); | ||
| 587 | return 0; | ||
| 588 | } | ||
| 589 | s /= (nsc + nac) * 4; | ||
| 590 | rp = mp->regions; | ||
| 591 | for (i = 0; i < s; ++i, ip += nac+nsc) { | ||
| 592 | if (nac >= 2 && ip[nac-2] != 0) | ||
| 593 | continue; | ||
| 594 | rp->address = ip[nac-1]; | ||
| 595 | if (nsc >= 2 && ip[nac+nsc-2] != 0) | ||
| 596 | rp->size = ~0U; | ||
| 597 | else | ||
| 598 | rp->size = ip[nac+nsc-1]; | ||
| 599 | ++rp; | ||
| 600 | } | ||
| 601 | mp->n_regions = rp - mp->regions; | ||
| 602 | |||
| 603 | /* Make sure the pieces are sorted. */ | ||
| 604 | mem_pieces_sort(mp); | ||
| 605 | mem_pieces_coalesce(mp); | ||
| 606 | return 1; | ||
| 607 | } | ||
| 608 | |||
| 609 | /* | ||
| 610 | * On systems with Open Firmware, collect information about | ||
| 611 | * physical RAM and which pieces are already in use. | ||
| 612 | * At this point, we have (at least) the first 8MB mapped with a BAT. | ||
| 613 | * Our text, data, bss use something over 1MB, starting at 0. | ||
| 614 | * Open Firmware may be using 1MB at the 4MB point. | ||
| 615 | */ | ||
| 616 | unsigned long __init | ||
| 617 | pmac_find_end_of_memory(void) | ||
| 618 | { | ||
| 619 | unsigned long a, total; | ||
| 620 | struct mem_pieces phys_mem; | ||
| 621 | |||
| 622 | /* | ||
| 623 | * Find out where physical memory is, and check that it | ||
| 624 | * starts at 0 and is contiguous. It seems that RAM is | ||
| 625 | * always physically contiguous on Power Macintoshes. | ||
| 626 | * | ||
| 627 | * Supporting discontiguous physical memory isn't hard, | ||
| 628 | * it just makes the virtual <-> physical mapping functions | ||
| 629 | * more complicated (or else you end up wasting space | ||
| 630 | * in mem_map). | ||
| 631 | */ | ||
| 632 | memory_node = find_devices("memory"); | ||
| 633 | if (memory_node == NULL || !get_mem_prop("reg", &phys_mem) | ||
| 634 | || phys_mem.n_regions == 0) | ||
| 635 | panic("No RAM??"); | ||
| 636 | a = phys_mem.regions[0].address; | ||
| 637 | if (a != 0) | ||
| 638 | panic("RAM doesn't start at physical address 0"); | ||
| 639 | total = phys_mem.regions[0].size; | ||
| 640 | |||
| 641 | if (phys_mem.n_regions > 1) { | ||
| 642 | printk("RAM starting at 0x%x is not contiguous\n", | ||
| 643 | phys_mem.regions[1].address); | ||
| 644 | printk("Using RAM from 0 to 0x%lx\n", total-1); | ||
| 645 | } | ||
| 646 | |||
| 647 | return total; | ||
| 648 | } | ||
| 649 | |||
| 650 | void __init | ||
| 651 | pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, | ||
| 652 | unsigned long r6, unsigned long r7) | ||
| 653 | { | ||
| 654 | /* isa_io_base gets set in pmac_find_bridges */ | ||
| 655 | isa_mem_base = PMAC_ISA_MEM_BASE; | ||
| 656 | pci_dram_offset = PMAC_PCI_DRAM_OFFSET; | ||
| 657 | ISA_DMA_THRESHOLD = ~0L; | ||
| 658 | DMA_MODE_READ = 1; | ||
| 659 | DMA_MODE_WRITE = 2; | ||
| 660 | |||
| 661 | ppc_md.setup_arch = pmac_setup_arch; | ||
| 662 | ppc_md.show_cpuinfo = pmac_show_cpuinfo; | ||
| 663 | ppc_md.show_percpuinfo = pmac_show_percpuinfo; | ||
| 664 | ppc_md.init_IRQ = pmac_pic_init; | ||
| 665 | ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */ | ||
| 666 | |||
| 667 | ppc_md.pcibios_fixup = pmac_pcibios_fixup; | ||
| 668 | ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook; | ||
| 669 | ppc_md.pcibios_after_init = pmac_pcibios_after_init; | ||
| 670 | ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; | ||
| 671 | |||
| 672 | ppc_md.restart = pmac_restart; | ||
| 673 | ppc_md.power_off = pmac_power_off; | ||
| 674 | ppc_md.halt = pmac_halt; | ||
| 675 | |||
| 676 | ppc_md.time_init = pmac_time_init; | ||
| 677 | ppc_md.set_rtc_time = pmac_set_rtc_time; | ||
| 678 | ppc_md.get_rtc_time = pmac_get_rtc_time; | ||
| 679 | ppc_md.calibrate_decr = pmac_calibrate_decr; | ||
| 680 | |||
| 681 | ppc_md.find_end_of_memory = pmac_find_end_of_memory; | ||
| 682 | |||
| 683 | ppc_md.feature_call = pmac_do_feature_call; | ||
| 684 | |||
| 685 | #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) | ||
| 686 | #ifdef CONFIG_BLK_DEV_IDE_PMAC | ||
| 687 | ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports; | ||
| 688 | ppc_ide_md.default_io_base = pmac_ide_get_base; | ||
| 689 | #endif /* CONFIG_BLK_DEV_IDE_PMAC */ | ||
| 690 | #endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */ | ||
| 691 | |||
| 692 | #ifdef CONFIG_BOOTX_TEXT | ||
| 693 | ppc_md.progress = pmac_progress; | ||
| 694 | #endif /* CONFIG_BOOTX_TEXT */ | ||
| 695 | |||
| 696 | if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0); | ||
| 697 | |||
| 698 | } | ||
| 699 | |||
| 700 | #ifdef CONFIG_BOOTX_TEXT | ||
| 701 | static void __init | ||
| 702 | pmac_progress(char *s, unsigned short hex) | ||
| 703 | { | ||
| 704 | if (boot_text_mapped) { | ||
| 705 | btext_drawstring(s); | ||
| 706 | btext_drawchar('\n'); | ||
| 707 | } | ||
| 708 | } | ||
| 709 | #endif /* CONFIG_BOOTX_TEXT */ | ||
| 710 | |||
| 711 | static int __init | ||
| 712 | pmac_declare_of_platform_devices(void) | ||
| 713 | { | ||
| 714 | struct device_node *np; | ||
| 715 | |||
| 716 | np = find_devices("uni-n"); | ||
| 717 | if (np) { | ||
| 718 | for (np = np->child; np != NULL; np = np->sibling) | ||
| 719 | if (strncmp(np->name, "i2c", 3) == 0) { | ||
| 720 | of_platform_device_create(np, "uni-n-i2c", | ||
| 721 | NULL); | ||
| 722 | break; | ||
| 723 | } | ||
| 724 | } | ||
| 725 | np = find_devices("u3"); | ||
| 726 | if (np) { | ||
| 727 | for (np = np->child; np != NULL; np = np->sibling) | ||
| 728 | if (strncmp(np->name, "i2c", 3) == 0) { | ||
| 729 | of_platform_device_create(np, "u3-i2c", | ||
| 730 | NULL); | ||
| 731 | break; | ||
| 732 | } | ||
| 733 | } | ||
| 734 | |||
| 735 | np = find_devices("valkyrie"); | ||
| 736 | if (np) | ||
| 737 | of_platform_device_create(np, "valkyrie", NULL); | ||
| 738 | np = find_devices("platinum"); | ||
| 739 | if (np) | ||
| 740 | of_platform_device_create(np, "platinum", NULL); | ||
| 741 | |||
| 742 | return 0; | ||
| 743 | } | ||
| 744 | |||
| 745 | device_initcall(pmac_declare_of_platform_devices); | ||
diff --git a/arch/ppc/platforms/pmac_sleep.S b/arch/ppc/platforms/pmac_sleep.S deleted file mode 100644 index 22b113d19b24..000000000000 --- a/arch/ppc/platforms/pmac_sleep.S +++ /dev/null | |||
| @@ -1,396 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * This file contains sleep low-level functions for PowerBook G3. | ||
| 3 | * Copyright (C) 1999 Benjamin Herrenschmidt (benh@kernel.crashing.org) | ||
| 4 | * and Paul Mackerras (paulus@samba.org). | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the License, or (at your option) any later version. | ||
| 10 | * | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/config.h> | ||
| 14 | #include <asm/processor.h> | ||
| 15 | #include <asm/page.h> | ||
| 16 | #include <asm/ppc_asm.h> | ||
| 17 | #include <asm/cputable.h> | ||
| 18 | #include <asm/cache.h> | ||
| 19 | #include <asm/thread_info.h> | ||
| 20 | #include <asm/asm-offsets.h> | ||
| 21 | |||
| 22 | #define MAGIC 0x4c617273 /* 'Lars' */ | ||
| 23 | |||
| 24 | /* | ||
| 25 | * Structure for storing CPU registers on the stack. | ||
| 26 | */ | ||
| 27 | #define SL_SP 0 | ||
| 28 | #define SL_PC 4 | ||
| 29 | #define SL_MSR 8 | ||
| 30 | #define SL_SDR1 0xc | ||
| 31 | #define SL_SPRG0 0x10 /* 4 sprg's */ | ||
| 32 | #define SL_DBAT0 0x20 | ||
| 33 | #define SL_IBAT0 0x28 | ||
| 34 | #define SL_DBAT1 0x30 | ||
| 35 | #define SL_IBAT1 0x38 | ||
| 36 | #define SL_DBAT2 0x40 | ||
| 37 | #define SL_IBAT2 0x48 | ||
| 38 | #define SL_DBAT3 0x50 | ||
| 39 | #define SL_IBAT3 0x58 | ||
| 40 | #define SL_TB 0x60 | ||
| 41 | #define SL_R2 0x68 | ||
| 42 | #define SL_CR 0x6c | ||
| 43 | #define SL_R12 0x70 /* r12 to r31 */ | ||
| 44 | #define SL_SIZE (SL_R12 + 80) | ||
| 45 | |||
| 46 | .section .text | ||
| 47 | .align 5 | ||
| 48 | |||
| 49 | #if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC) | ||
| 50 | |||
| 51 | /* This gets called by via-pmu.c late during the sleep process. | ||
| 52 | * The PMU was already send the sleep command and will shut us down | ||
| 53 | * soon. We need to save all that is needed and setup the wakeup | ||
| 54 | * vector that will be called by the ROM on wakeup | ||
| 55 | */ | ||
| 56 | _GLOBAL(low_sleep_handler) | ||
| 57 | #ifndef CONFIG_6xx | ||
| 58 | blr | ||
| 59 | #else | ||
| 60 | mflr r0 | ||
| 61 | stw r0,4(r1) | ||
| 62 | stwu r1,-SL_SIZE(r1) | ||
| 63 | mfcr r0 | ||
| 64 | stw r0,SL_CR(r1) | ||
| 65 | stw r2,SL_R2(r1) | ||
| 66 | stmw r12,SL_R12(r1) | ||
| 67 | |||
| 68 | /* Save MSR & SDR1 */ | ||
| 69 | mfmsr r4 | ||
| 70 | stw r4,SL_MSR(r1) | ||
| 71 | mfsdr1 r4 | ||
| 72 | stw r4,SL_SDR1(r1) | ||
| 73 | |||
| 74 | /* Get a stable timebase and save it */ | ||
| 75 | 1: mftbu r4 | ||
| 76 | stw r4,SL_TB(r1) | ||
| 77 | mftb r5 | ||
| 78 | stw r5,SL_TB+4(r1) | ||
| 79 | mftbu r3 | ||
| 80 | cmpw r3,r4 | ||
| 81 | bne 1b | ||
| 82 | |||
| 83 | /* Save SPRGs */ | ||
| 84 | mfsprg r4,0 | ||
| 85 | stw r4,SL_SPRG0(r1) | ||
| 86 | mfsprg r4,1 | ||
| 87 | stw r4,SL_SPRG0+4(r1) | ||
| 88 | mfsprg r4,2 | ||
| 89 | stw r4,SL_SPRG0+8(r1) | ||
| 90 | mfsprg r4,3 | ||
| 91 | stw r4,SL_SPRG0+12(r1) | ||
| 92 | |||
| 93 | /* Save BATs */ | ||
| 94 | mfdbatu r4,0 | ||
| 95 | stw r4,SL_DBAT0(r1) | ||
| 96 | mfdbatl r4,0 | ||
| 97 | stw r4,SL_DBAT0+4(r1) | ||
| 98 | mfdbatu r4,1 | ||
| 99 | stw r4,SL_DBAT1(r1) | ||
| 100 | mfdbatl r4,1 | ||
| 101 | stw r4,SL_DBAT1+4(r1) | ||
| 102 | mfdbatu r4,2 | ||
| 103 | stw r4,SL_DBAT2(r1) | ||
| 104 | mfdbatl r4,2 | ||
| 105 | stw r4,SL_DBAT2+4(r1) | ||
| 106 | mfdbatu r4,3 | ||
| 107 | stw r4,SL_DBAT3(r1) | ||
| 108 | mfdbatl r4,3 | ||
| 109 | stw r4,SL_DBAT3+4(r1) | ||
| 110 | mfibatu r4,0 | ||
| 111 | stw r4,SL_IBAT0(r1) | ||
| 112 | mfibatl r4,0 | ||
| 113 | stw r4,SL_IBAT0+4(r1) | ||
| 114 | mfibatu r4,1 | ||
| 115 | stw r4,SL_IBAT1(r1) | ||
| 116 | mfibatl r4,1 | ||
| 117 | stw r4,SL_IBAT1+4(r1) | ||
| 118 | mfibatu r4,2 | ||
| 119 | stw r4,SL_IBAT2(r1) | ||
| 120 | mfibatl r4,2 | ||
| 121 | stw r4,SL_IBAT2+4(r1) | ||
| 122 | mfibatu r4,3 | ||
| 123 | stw r4,SL_IBAT3(r1) | ||
| 124 | mfibatl r4,3 | ||
| 125 | stw r4,SL_IBAT3+4(r1) | ||
| 126 | |||
| 127 | /* Backup various CPU config stuffs */ | ||
| 128 | bl __save_cpu_setup | ||
| 129 | |||
| 130 | /* The ROM can wake us up via 2 different vectors: | ||
| 131 | * - On wallstreet & lombard, we must write a magic | ||
| 132 | * value 'Lars' at address 4 and a pointer to a | ||
| 133 | * memory location containing the PC to resume from | ||
| 134 | * at address 0. | ||
| 135 | * - On Core99, we must store the wakeup vector at | ||
| 136 | * address 0x80 and eventually it's parameters | ||
| 137 | * at address 0x84. I've have some trouble with those | ||
| 138 | * parameters however and I no longer use them. | ||
| 139 | */ | ||
| 140 | lis r5,grackle_wake_up@ha | ||
| 141 | addi r5,r5,grackle_wake_up@l | ||
| 142 | tophys(r5,r5) | ||
| 143 | stw r5,SL_PC(r1) | ||
| 144 | lis r4,KERNELBASE@h | ||
| 145 | tophys(r5,r1) | ||
| 146 | addi r5,r5,SL_PC | ||
| 147 | lis r6,MAGIC@ha | ||
| 148 | addi r6,r6,MAGIC@l | ||
| 149 | stw r5,0(r4) | ||
| 150 | stw r6,4(r4) | ||
| 151 | /* Setup stuffs at 0x80-0x84 for Core99 */ | ||
| 152 | lis r3,core99_wake_up@ha | ||
| 153 | addi r3,r3,core99_wake_up@l | ||
| 154 | tophys(r3,r3) | ||
| 155 | stw r3,0x80(r4) | ||
| 156 | stw r5,0x84(r4) | ||
| 157 | /* Store a pointer to our backup storage into | ||
| 158 | * a kernel global | ||
| 159 | */ | ||
| 160 | lis r3,sleep_storage@ha | ||
| 161 | addi r3,r3,sleep_storage@l | ||
| 162 | stw r5,0(r3) | ||
| 163 | |||
| 164 | .globl low_cpu_die | ||
| 165 | low_cpu_die: | ||
| 166 | /* Flush & disable all caches */ | ||
| 167 | bl flush_disable_caches | ||
| 168 | |||
| 169 | /* Turn off data relocation. */ | ||
| 170 | mfmsr r3 /* Save MSR in r7 */ | ||
| 171 | rlwinm r3,r3,0,28,26 /* Turn off DR bit */ | ||
| 172 | sync | ||
| 173 | mtmsr r3 | ||
| 174 | isync | ||
| 175 | |||
| 176 | BEGIN_FTR_SECTION | ||
| 177 | /* Flush any pending L2 data prefetches to work around HW bug */ | ||
| 178 | sync | ||
| 179 | lis r3,0xfff0 | ||
| 180 | lwz r0,0(r3) /* perform cache-inhibited load to ROM */ | ||
| 181 | sync /* (caches are disabled at this point) */ | ||
| 182 | END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450) | ||
| 183 | |||
| 184 | /* | ||
| 185 | * Set the HID0 and MSR for sleep. | ||
| 186 | */ | ||
| 187 | mfspr r2,SPRN_HID0 | ||
| 188 | rlwinm r2,r2,0,10,7 /* clear doze, nap */ | ||
| 189 | oris r2,r2,HID0_SLEEP@h | ||
| 190 | sync | ||
| 191 | isync | ||
| 192 | mtspr SPRN_HID0,r2 | ||
| 193 | sync | ||
| 194 | |||
| 195 | /* This loop puts us back to sleep in case we have a spurrious | ||
| 196 | * wakeup so that the host bridge properly stays asleep. The | ||
| 197 | * CPU will be turned off, either after a known time (about 1 | ||
| 198 | * second) on wallstreet & lombard, or as soon as the CPU enters | ||
| 199 | * SLEEP mode on core99 | ||
| 200 | */ | ||
| 201 | mfmsr r2 | ||
| 202 | oris r2,r2,MSR_POW@h | ||
| 203 | 1: sync | ||
| 204 | mtmsr r2 | ||
| 205 | isync | ||
| 206 | b 1b | ||
| 207 | |||
| 208 | /* | ||
| 209 | * Here is the resume code. | ||
| 210 | */ | ||
| 211 | |||
| 212 | |||
| 213 | /* | ||
| 214 | * Core99 machines resume here | ||
| 215 | * r4 has the physical address of SL_PC(sp) (unused) | ||
| 216 | */ | ||
| 217 | _GLOBAL(core99_wake_up) | ||
| 218 | /* Make sure HID0 no longer contains any sleep bit and that data cache | ||
| 219 | * is disabled | ||
| 220 | */ | ||
| 221 | mfspr r3,SPRN_HID0 | ||
| 222 | rlwinm r3,r3,0,11,7 /* clear SLEEP, NAP, DOZE bits */ | ||
| 223 | rlwinm 3,r3,0,18,15 /* clear DCE, ICE */ | ||
| 224 | mtspr SPRN_HID0,r3 | ||
| 225 | sync | ||
| 226 | isync | ||
| 227 | |||
| 228 | /* sanitize MSR */ | ||
| 229 | mfmsr r3 | ||
| 230 | ori r3,r3,MSR_EE|MSR_IP | ||
| 231 | xori r3,r3,MSR_EE|MSR_IP | ||
| 232 | sync | ||
| 233 | isync | ||
| 234 | mtmsr r3 | ||
| 235 | sync | ||
| 236 | isync | ||
| 237 | |||
| 238 | /* Recover sleep storage */ | ||
| 239 | lis r3,sleep_storage@ha | ||
| 240 | addi r3,r3,sleep_storage@l | ||
| 241 | tophys(r3,r3) | ||
| 242 | lwz r1,0(r3) | ||
| 243 | |||
| 244 | /* Pass thru to older resume code ... */ | ||
| 245 | /* | ||
| 246 | * Here is the resume code for older machines. | ||
| 247 | * r1 has the physical address of SL_PC(sp). | ||
| 248 | */ | ||
| 249 | |||
| 250 | grackle_wake_up: | ||
| 251 | |||
| 252 | /* Restore the kernel's segment registers before | ||
| 253 | * we do any r1 memory access as we are not sure they | ||
| 254 | * are in a sane state above the first 256Mb region | ||
| 255 | */ | ||
| 256 | li r0,16 /* load up segment register values */ | ||
| 257 | mtctr r0 /* for context 0 */ | ||
| 258 | lis r3,0x2000 /* Ku = 1, VSID = 0 */ | ||
| 259 | li r4,0 | ||
| 260 | 3: mtsrin r3,r4 | ||
| 261 | addi r3,r3,0x111 /* increment VSID */ | ||
| 262 | addis r4,r4,0x1000 /* address of next segment */ | ||
| 263 | bdnz 3b | ||
| 264 | sync | ||
| 265 | isync | ||
| 266 | |||
| 267 | subi r1,r1,SL_PC | ||
| 268 | |||
| 269 | /* Restore various CPU config stuffs */ | ||
| 270 | bl __restore_cpu_setup | ||
| 271 | |||
| 272 | /* Make sure all FPRs have been initialized */ | ||
| 273 | bl reloc_offset | ||
| 274 | bl __init_fpu_registers | ||
| 275 | |||
| 276 | /* Invalidate & enable L1 cache, we don't care about | ||
| 277 | * whatever the ROM may have tried to write to memory | ||
| 278 | */ | ||
| 279 | bl __inval_enable_L1 | ||
| 280 | |||
| 281 | /* Restore the BATs, and SDR1. Then we can turn on the MMU. */ | ||
| 282 | lwz r4,SL_SDR1(r1) | ||
| 283 | mtsdr1 r4 | ||
| 284 | lwz r4,SL_SPRG0(r1) | ||
| 285 | mtsprg 0,r4 | ||
| 286 | lwz r4,SL_SPRG0+4(r1) | ||
| 287 | mtsprg 1,r4 | ||
| 288 | lwz r4,SL_SPRG0+8(r1) | ||
| 289 | mtsprg 2,r4 | ||
| 290 | lwz r4,SL_SPRG0+12(r1) | ||
| 291 | mtsprg 3,r4 | ||
| 292 | |||
| 293 | lwz r4,SL_DBAT0(r1) | ||
| 294 | mtdbatu 0,r4 | ||
| 295 | lwz r4,SL_DBAT0+4(r1) | ||
| 296 | mtdbatl 0,r4 | ||
| 297 | lwz r4,SL_DBAT1(r1) | ||
| 298 | mtdbatu 1,r4 | ||
| 299 | lwz r4,SL_DBAT1+4(r1) | ||
| 300 | mtdbatl 1,r4 | ||
| 301 | lwz r4,SL_DBAT2(r1) | ||
| 302 | mtdbatu 2,r4 | ||
| 303 | lwz r4,SL_DBAT2+4(r1) | ||
| 304 | mtdbatl 2,r4 | ||
| 305 | lwz r4,SL_DBAT3(r1) | ||
| 306 | mtdbatu 3,r4 | ||
| 307 | lwz r4,SL_DBAT3+4(r1) | ||
| 308 | mtdbatl 3,r4 | ||
| 309 | lwz r4,SL_IBAT0(r1) | ||
| 310 | mtibatu 0,r4 | ||
| 311 | lwz r4,SL_IBAT0+4(r1) | ||
| 312 | mtibatl 0,r4 | ||
| 313 | lwz r4,SL_IBAT1(r1) | ||
| 314 | mtibatu 1,r4 | ||
| 315 | lwz r4,SL_IBAT1+4(r1) | ||
| 316 | mtibatl 1,r4 | ||
| 317 | lwz r4,SL_IBAT2(r1) | ||
| 318 | mtibatu 2,r4 | ||
| 319 | lwz r4,SL_IBAT2+4(r1) | ||
| 320 | mtibatl 2,r4 | ||
| 321 | lwz r4,SL_IBAT3(r1) | ||
| 322 | mtibatu 3,r4 | ||
| 323 | lwz r4,SL_IBAT3+4(r1) | ||
| 324 | mtibatl 3,r4 | ||
| 325 | |||
| 326 | BEGIN_FTR_SECTION | ||
| 327 | li r4,0 | ||
| 328 | mtspr SPRN_DBAT4U,r4 | ||
| 329 | mtspr SPRN_DBAT4L,r4 | ||
| 330 | mtspr SPRN_DBAT5U,r4 | ||
| 331 | mtspr SPRN_DBAT5L,r4 | ||
| 332 | mtspr SPRN_DBAT6U,r4 | ||
| 333 | mtspr SPRN_DBAT6L,r4 | ||
| 334 | mtspr SPRN_DBAT7U,r4 | ||
| 335 | mtspr SPRN_DBAT7L,r4 | ||
| 336 | mtspr SPRN_IBAT4U,r4 | ||
| 337 | mtspr SPRN_IBAT4L,r4 | ||
| 338 | mtspr SPRN_IBAT5U,r4 | ||
| 339 | mtspr SPRN_IBAT5L,r4 | ||
| 340 | mtspr SPRN_IBAT6U,r4 | ||
| 341 | mtspr SPRN_IBAT6L,r4 | ||
| 342 | mtspr SPRN_IBAT7U,r4 | ||
| 343 | mtspr SPRN_IBAT7L,r4 | ||
| 344 | END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS) | ||
| 345 | |||
| 346 | /* Flush all TLBs */ | ||
| 347 | lis r4,0x1000 | ||
| 348 | 1: addic. r4,r4,-0x1000 | ||
| 349 | tlbie r4 | ||
| 350 | blt 1b | ||
| 351 | sync | ||
| 352 | |||
| 353 | /* restore the MSR and turn on the MMU */ | ||
| 354 | lwz r3,SL_MSR(r1) | ||
| 355 | bl turn_on_mmu | ||
| 356 | |||
| 357 | /* get back the stack pointer */ | ||
| 358 | tovirt(r1,r1) | ||
| 359 | |||
| 360 | /* Restore TB */ | ||
| 361 | li r3,0 | ||
| 362 | mttbl r3 | ||
| 363 | lwz r3,SL_TB(r1) | ||
| 364 | lwz r4,SL_TB+4(r1) | ||
| 365 | mttbu r3 | ||
| 366 | mttbl r4 | ||
| 367 | |||
| 368 | /* Restore the callee-saved registers and return */ | ||
| 369 | lwz r0,SL_CR(r1) | ||
| 370 | mtcr r0 | ||
| 371 | lwz r2,SL_R2(r1) | ||
| 372 | lmw r12,SL_R12(r1) | ||
| 373 | addi r1,r1,SL_SIZE | ||
| 374 | lwz r0,4(r1) | ||
| 375 | mtlr r0 | ||
| 376 | blr | ||
| 377 | |||
| 378 | turn_on_mmu: | ||
| 379 | mflr r4 | ||
| 380 | tovirt(r4,r4) | ||
| 381 | mtsrr0 r4 | ||
| 382 | mtsrr1 r3 | ||
| 383 | sync | ||
| 384 | isync | ||
| 385 | rfi | ||
| 386 | |||
| 387 | #endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */ | ||
| 388 | |||
| 389 | .section .data | ||
| 390 | .balign L1_CACHE_BYTES | ||
| 391 | sleep_storage: | ||
| 392 | .long 0 | ||
| 393 | .balign L1_CACHE_BYTES, 0 | ||
| 394 | |||
| 395 | #endif /* CONFIG_6xx */ | ||
| 396 | .section .text | ||
diff --git a/arch/ppc/platforms/pmac_smp.c b/arch/ppc/platforms/pmac_smp.c deleted file mode 100644 index 26ff26238f03..000000000000 --- a/arch/ppc/platforms/pmac_smp.c +++ /dev/null | |||
| @@ -1,692 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * SMP support for power macintosh. | ||
| 3 | * | ||
| 4 | * We support both the old "powersurge" SMP architecture | ||
| 5 | * and the current Core99 (G4 PowerMac) machines. | ||
| 6 | * | ||
| 7 | * Note that we don't support the very first rev. of | ||
| 8 | * Apple/DayStar 2 CPUs board, the one with the funky | ||
| 9 | * watchdog. Hopefully, none of these should be there except | ||
| 10 | * maybe internally to Apple. I should probably still add some | ||
| 11 | * code to detect this card though and disable SMP. --BenH. | ||
| 12 | * | ||
| 13 | * Support Macintosh G4 SMP by Troy Benjegerdes (hozer@drgw.net) | ||
| 14 | * and Ben Herrenschmidt <benh@kernel.crashing.org>. | ||
| 15 | * | ||
| 16 | * Support for DayStar quad CPU cards | ||
| 17 | * Copyright (C) XLR8, Inc. 1994-2000 | ||
| 18 | * | ||
| 19 | * This program is free software; you can redistribute it and/or | ||
| 20 | * modify it under the terms of the GNU General Public License | ||
| 21 | * as published by the Free Software Foundation; either version | ||
| 22 | * 2 of the License, or (at your option) any later version. | ||
| 23 | */ | ||
| 24 | #include <linux/config.h> | ||
| 25 | #include <linux/kernel.h> | ||
| 26 | #include <linux/sched.h> | ||
| 27 | #include <linux/smp.h> | ||
| 28 | #include <linux/smp_lock.h> | ||
| 29 | #include <linux/interrupt.h> | ||
| 30 | #include <linux/kernel_stat.h> | ||
| 31 | #include <linux/delay.h> | ||
| 32 | #include <linux/init.h> | ||
| 33 | #include <linux/spinlock.h> | ||
| 34 | #include <linux/errno.h> | ||
| 35 | #include <linux/hardirq.h> | ||
| 36 | #include <linux/cpu.h> | ||
| 37 | |||
| 38 | #include <asm/ptrace.h> | ||
| 39 | #include <asm/atomic.h> | ||
| 40 | #include <asm/irq.h> | ||
| 41 | #include <asm/page.h> | ||
| 42 | #include <asm/pgtable.h> | ||
| 43 | #include <asm/sections.h> | ||
| 44 | #include <asm/io.h> | ||
| 45 | #include <asm/prom.h> | ||
| 46 | #include <asm/smp.h> | ||
| 47 | #include <asm/residual.h> | ||
| 48 | #include <asm/machdep.h> | ||
| 49 | #include <asm/pmac_feature.h> | ||
| 50 | #include <asm/time.h> | ||
| 51 | #include <asm/open_pic.h> | ||
| 52 | #include <asm/cacheflush.h> | ||
| 53 | #include <asm/keylargo.h> | ||
| 54 | |||
| 55 | /* | ||
| 56 | * Powersurge (old powermac SMP) support. | ||
| 57 | */ | ||
| 58 | |||
| 59 | extern void __secondary_start_pmac_0(void); | ||
| 60 | |||
| 61 | /* Addresses for powersurge registers */ | ||
| 62 | #define HAMMERHEAD_BASE 0xf8000000 | ||
| 63 | #define HHEAD_CONFIG 0x90 | ||
| 64 | #define HHEAD_SEC_INTR 0xc0 | ||
| 65 | |||
| 66 | /* register for interrupting the primary processor on the powersurge */ | ||
| 67 | /* N.B. this is actually the ethernet ROM! */ | ||
| 68 | #define PSURGE_PRI_INTR 0xf3019000 | ||
| 69 | |||
| 70 | /* register for storing the start address for the secondary processor */ | ||
| 71 | /* N.B. this is the PCI config space address register for the 1st bridge */ | ||
| 72 | #define PSURGE_START 0xf2800000 | ||
| 73 | |||
| 74 | /* Daystar/XLR8 4-CPU card */ | ||
| 75 | #define PSURGE_QUAD_REG_ADDR 0xf8800000 | ||
| 76 | |||
| 77 | #define PSURGE_QUAD_IRQ_SET 0 | ||
| 78 | #define PSURGE_QUAD_IRQ_CLR 1 | ||
| 79 | #define PSURGE_QUAD_IRQ_PRIMARY 2 | ||
| 80 | #define PSURGE_QUAD_CKSTOP_CTL 3 | ||
| 81 | #define PSURGE_QUAD_PRIMARY_ARB 4 | ||
| 82 | #define PSURGE_QUAD_BOARD_ID 6 | ||
| 83 | #define PSURGE_QUAD_WHICH_CPU 7 | ||
| 84 | #define PSURGE_QUAD_CKSTOP_RDBK 8 | ||
| 85 | #define PSURGE_QUAD_RESET_CTL 11 | ||
| 86 | |||
| 87 | #define PSURGE_QUAD_OUT(r, v) (out_8(quad_base + ((r) << 4) + 4, (v))) | ||
| 88 | #define PSURGE_QUAD_IN(r) (in_8(quad_base + ((r) << 4) + 4) & 0x0f) | ||
| 89 | #define PSURGE_QUAD_BIS(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) | (v))) | ||
| 90 | #define PSURGE_QUAD_BIC(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) & ~(v))) | ||
| 91 | |||
| 92 | /* virtual addresses for the above */ | ||
| 93 | static volatile u8 __iomem *hhead_base; | ||
| 94 | static volatile u8 __iomem *quad_base; | ||
| 95 | static volatile u32 __iomem *psurge_pri_intr; | ||
| 96 | static volatile u8 __iomem *psurge_sec_intr; | ||
| 97 | static volatile u32 __iomem *psurge_start; | ||
| 98 | |||
| 99 | /* values for psurge_type */ | ||
| 100 | #define PSURGE_NONE -1 | ||
| 101 | #define PSURGE_DUAL 0 | ||
| 102 | #define PSURGE_QUAD_OKEE 1 | ||
| 103 | #define PSURGE_QUAD_COTTON 2 | ||
| 104 | #define PSURGE_QUAD_ICEGRASS 3 | ||
| 105 | |||
| 106 | /* what sort of powersurge board we have */ | ||
| 107 | static int psurge_type = PSURGE_NONE; | ||
| 108 | |||
| 109 | /* L2 and L3 cache settings to pass from CPU0 to CPU1 */ | ||
| 110 | volatile static long int core99_l2_cache; | ||
| 111 | volatile static long int core99_l3_cache; | ||
| 112 | |||
| 113 | /* Timebase freeze GPIO */ | ||
| 114 | static unsigned int core99_tb_gpio; | ||
| 115 | |||
| 116 | /* Sync flag for HW tb sync */ | ||
| 117 | static volatile int sec_tb_reset = 0; | ||
| 118 | static unsigned int pri_tb_hi, pri_tb_lo; | ||
| 119 | static unsigned int pri_tb_stamp; | ||
| 120 | |||
| 121 | static void __devinit core99_init_caches(int cpu) | ||
| 122 | { | ||
| 123 | if (!cpu_has_feature(CPU_FTR_L2CR)) | ||
| 124 | return; | ||
| 125 | |||
| 126 | if (cpu == 0) { | ||
| 127 | core99_l2_cache = _get_L2CR(); | ||
| 128 | printk("CPU0: L2CR is %lx\n", core99_l2_cache); | ||
| 129 | } else { | ||
| 130 | printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR()); | ||
| 131 | _set_L2CR(0); | ||
| 132 | _set_L2CR(core99_l2_cache); | ||
| 133 | printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache); | ||
| 134 | } | ||
| 135 | |||
| 136 | if (!cpu_has_feature(CPU_FTR_L3CR)) | ||
| 137 | return; | ||
| 138 | |||
| 139 | if (cpu == 0){ | ||
| 140 | core99_l3_cache = _get_L3CR(); | ||
| 141 | printk("CPU0: L3CR is %lx\n", core99_l3_cache); | ||
| 142 | } else { | ||
| 143 | printk("CPU%d: L3CR was %lx\n", cpu, _get_L3CR()); | ||
| 144 | _set_L3CR(0); | ||
| 145 | _set_L3CR(core99_l3_cache); | ||
| 146 | printk("CPU%d: L3CR set to %lx\n", cpu, core99_l3_cache); | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 150 | /* | ||
| 151 | * Set and clear IPIs for powersurge. | ||
| 152 | */ | ||
| 153 | static inline void psurge_set_ipi(int cpu) | ||
| 154 | { | ||
| 155 | if (psurge_type == PSURGE_NONE) | ||
| 156 | return; | ||
| 157 | if (cpu == 0) | ||
| 158 | in_be32(psurge_pri_intr); | ||
| 159 | else if (psurge_type == PSURGE_DUAL) | ||
| 160 | out_8(psurge_sec_intr, 0); | ||
| 161 | else | ||
| 162 | PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_SET, 1 << cpu); | ||
| 163 | } | ||
| 164 | |||
| 165 | static inline void psurge_clr_ipi(int cpu) | ||
| 166 | { | ||
| 167 | if (cpu > 0) { | ||
| 168 | switch(psurge_type) { | ||
| 169 | case PSURGE_DUAL: | ||
| 170 | out_8(psurge_sec_intr, ~0); | ||
| 171 | case PSURGE_NONE: | ||
| 172 | break; | ||
| 173 | default: | ||
| 174 | PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, 1 << cpu); | ||
| 175 | } | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | /* | ||
| 180 | * On powersurge (old SMP powermac architecture) we don't have | ||
| 181 | * separate IPIs for separate messages like openpic does. Instead | ||
| 182 | * we have a bitmap for each processor, where a 1 bit means that | ||
| 183 | * the corresponding message is pending for that processor. | ||
| 184 | * Ideally each cpu's entry would be in a different cache line. | ||
| 185 | * -- paulus. | ||
| 186 | */ | ||
| 187 | static unsigned long psurge_smp_message[NR_CPUS]; | ||
| 188 | |||
| 189 | void psurge_smp_message_recv(struct pt_regs *regs) | ||
| 190 | { | ||
| 191 | int cpu = smp_processor_id(); | ||
| 192 | int msg; | ||
| 193 | |||
| 194 | /* clear interrupt */ | ||
| 195 | psurge_clr_ipi(cpu); | ||
| 196 | |||
| 197 | if (num_online_cpus() < 2) | ||
| 198 | return; | ||
| 199 | |||
| 200 | /* make sure there is a message there */ | ||
| 201 | for (msg = 0; msg < 4; msg++) | ||
| 202 | if (test_and_clear_bit(msg, &psurge_smp_message[cpu])) | ||
| 203 | smp_message_recv(msg, regs); | ||
| 204 | } | ||
| 205 | |||
| 206 | irqreturn_t psurge_primary_intr(int irq, void *d, struct pt_regs *regs) | ||
| 207 | { | ||
| 208 | psurge_smp_message_recv(regs); | ||
| 209 | return IRQ_HANDLED; | ||
| 210 | } | ||
| 211 | |||
| 212 | static void smp_psurge_message_pass(int target, int msg) | ||
| 213 | { | ||
| 214 | int i; | ||
| 215 | |||
| 216 | if (num_online_cpus() < 2) | ||
| 217 | return; | ||
| 218 | |||
| 219 | for (i = 0; i < NR_CPUS; i++) { | ||
| 220 | if (!cpu_online(i)) | ||
| 221 | continue; | ||
| 222 | if (target == MSG_ALL | ||
| 223 | || (target == MSG_ALL_BUT_SELF && i != smp_processor_id()) | ||
| 224 | || target == i) { | ||
| 225 | set_bit(msg, &psurge_smp_message[i]); | ||
| 226 | psurge_set_ipi(i); | ||
| 227 | } | ||
| 228 | } | ||
| 229 | } | ||
| 230 | |||
| 231 | /* | ||
| 232 | * Determine a quad card presence. We read the board ID register, we | ||
| 233 | * force the data bus to change to something else, and we read it again. | ||
| 234 | * It it's stable, then the register probably exist (ugh !) | ||
| 235 | */ | ||
| 236 | static int __init psurge_quad_probe(void) | ||
| 237 | { | ||
| 238 | int type; | ||
| 239 | unsigned int i; | ||
| 240 | |||
| 241 | type = PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID); | ||
| 242 | if (type < PSURGE_QUAD_OKEE || type > PSURGE_QUAD_ICEGRASS | ||
| 243 | || type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID)) | ||
| 244 | return PSURGE_DUAL; | ||
| 245 | |||
| 246 | /* looks OK, try a slightly more rigorous test */ | ||
| 247 | /* bogus is not necessarily cacheline-aligned, | ||
| 248 | though I don't suppose that really matters. -- paulus */ | ||
| 249 | for (i = 0; i < 100; i++) { | ||
| 250 | volatile u32 bogus[8]; | ||
| 251 | bogus[(0+i)%8] = 0x00000000; | ||
| 252 | bogus[(1+i)%8] = 0x55555555; | ||
| 253 | bogus[(2+i)%8] = 0xFFFFFFFF; | ||
| 254 | bogus[(3+i)%8] = 0xAAAAAAAA; | ||
| 255 | bogus[(4+i)%8] = 0x33333333; | ||
| 256 | bogus[(5+i)%8] = 0xCCCCCCCC; | ||
| 257 | bogus[(6+i)%8] = 0xCCCCCCCC; | ||
| 258 | bogus[(7+i)%8] = 0x33333333; | ||
| 259 | wmb(); | ||
| 260 | asm volatile("dcbf 0,%0" : : "r" (bogus) : "memory"); | ||
| 261 | mb(); | ||
| 262 | if (type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID)) | ||
| 263 | return PSURGE_DUAL; | ||
| 264 | } | ||
| 265 | return type; | ||
| 266 | } | ||
| 267 | |||
| 268 | static void __init psurge_quad_init(void) | ||
| 269 | { | ||
| 270 | int procbits; | ||
| 271 | |||
| 272 | if (ppc_md.progress) ppc_md.progress("psurge_quad_init", 0x351); | ||
| 273 | procbits = ~PSURGE_QUAD_IN(PSURGE_QUAD_WHICH_CPU); | ||
| 274 | if (psurge_type == PSURGE_QUAD_ICEGRASS) | ||
| 275 | PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits); | ||
| 276 | else | ||
| 277 | PSURGE_QUAD_BIC(PSURGE_QUAD_CKSTOP_CTL, procbits); | ||
| 278 | mdelay(33); | ||
| 279 | out_8(psurge_sec_intr, ~0); | ||
| 280 | PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, procbits); | ||
| 281 | PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits); | ||
| 282 | if (psurge_type != PSURGE_QUAD_ICEGRASS) | ||
| 283 | PSURGE_QUAD_BIS(PSURGE_QUAD_CKSTOP_CTL, procbits); | ||
| 284 | PSURGE_QUAD_BIC(PSURGE_QUAD_PRIMARY_ARB, procbits); | ||
| 285 | mdelay(33); | ||
| 286 | PSURGE_QUAD_BIC(PSURGE_QUAD_RESET_CTL, procbits); | ||
| 287 | mdelay(33); | ||
| 288 | PSURGE_QUAD_BIS(PSURGE_QUAD_PRIMARY_ARB, procbits); | ||
| 289 | mdelay(33); | ||
| 290 | } | ||
| 291 | |||
| 292 | static int __init smp_psurge_probe(void) | ||
| 293 | { | ||
| 294 | int i, ncpus; | ||
| 295 | |||
| 296 | /* We don't do SMP on the PPC601 -- paulus */ | ||
| 297 | if (PVR_VER(mfspr(SPRN_PVR)) == 1) | ||
| 298 | return 1; | ||
| 299 | |||
| 300 | /* | ||
| 301 | * The powersurge cpu board can be used in the generation | ||
| 302 | * of powermacs that have a socket for an upgradeable cpu card, | ||
| 303 | * including the 7500, 8500, 9500, 9600. | ||
| 304 | * The device tree doesn't tell you if you have 2 cpus because | ||
| 305 | * OF doesn't know anything about the 2nd processor. | ||
| 306 | * Instead we look for magic bits in magic registers, | ||
| 307 | * in the hammerhead memory controller in the case of the | ||
| 308 | * dual-cpu powersurge board. -- paulus. | ||
| 309 | */ | ||
| 310 | if (find_devices("hammerhead") == NULL) | ||
| 311 | return 1; | ||
| 312 | |||
| 313 | hhead_base = ioremap(HAMMERHEAD_BASE, 0x800); | ||
| 314 | quad_base = ioremap(PSURGE_QUAD_REG_ADDR, 1024); | ||
| 315 | psurge_sec_intr = hhead_base + HHEAD_SEC_INTR; | ||
| 316 | |||
| 317 | psurge_type = psurge_quad_probe(); | ||
| 318 | if (psurge_type != PSURGE_DUAL) { | ||
| 319 | psurge_quad_init(); | ||
| 320 | /* All released cards using this HW design have 4 CPUs */ | ||
| 321 | ncpus = 4; | ||
| 322 | } else { | ||
| 323 | iounmap(quad_base); | ||
| 324 | if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) { | ||
| 325 | /* not a dual-cpu card */ | ||
| 326 | iounmap(hhead_base); | ||
| 327 | psurge_type = PSURGE_NONE; | ||
| 328 | return 1; | ||
| 329 | } | ||
| 330 | ncpus = 2; | ||
| 331 | } | ||
| 332 | |||
| 333 | psurge_start = ioremap(PSURGE_START, 4); | ||
| 334 | psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); | ||
| 335 | |||
| 336 | /* this is not actually strictly necessary -- paulus. */ | ||
| 337 | for (i = 1; i < ncpus; ++i) | ||
| 338 | smp_hw_index[i] = i; | ||
| 339 | |||
| 340 | if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352); | ||
| 341 | |||
| 342 | return ncpus; | ||
| 343 | } | ||
| 344 | |||
| 345 | static void __init smp_psurge_kick_cpu(int nr) | ||
| 346 | { | ||
| 347 | unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8; | ||
| 348 | unsigned long a; | ||
| 349 | |||
| 350 | /* may need to flush here if secondary bats aren't setup */ | ||
| 351 | for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32) | ||
| 352 | asm volatile("dcbf 0,%0" : : "r" (a) : "memory"); | ||
| 353 | asm volatile("sync"); | ||
| 354 | |||
| 355 | if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353); | ||
| 356 | |||
| 357 | out_be32(psurge_start, start); | ||
| 358 | mb(); | ||
| 359 | |||
| 360 | psurge_set_ipi(nr); | ||
| 361 | udelay(10); | ||
| 362 | psurge_clr_ipi(nr); | ||
| 363 | |||
| 364 | if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354); | ||
| 365 | } | ||
| 366 | |||
| 367 | /* | ||
| 368 | * With the dual-cpu powersurge board, the decrementers and timebases | ||
| 369 | * of both cpus are frozen after the secondary cpu is started up, | ||
| 370 | * until we give the secondary cpu another interrupt. This routine | ||
| 371 | * uses this to get the timebases synchronized. | ||
| 372 | * -- paulus. | ||
| 373 | */ | ||
| 374 | static void __init psurge_dual_sync_tb(int cpu_nr) | ||
| 375 | { | ||
| 376 | int t; | ||
| 377 | |||
| 378 | set_dec(tb_ticks_per_jiffy); | ||
| 379 | set_tb(0, 0); | ||
| 380 | last_jiffy_stamp(cpu_nr) = 0; | ||
| 381 | |||
| 382 | if (cpu_nr > 0) { | ||
| 383 | mb(); | ||
| 384 | sec_tb_reset = 1; | ||
| 385 | return; | ||
| 386 | } | ||
| 387 | |||
| 388 | /* wait for the secondary to have reset its TB before proceeding */ | ||
| 389 | for (t = 10000000; t > 0 && !sec_tb_reset; --t) | ||
| 390 | ; | ||
| 391 | |||
| 392 | /* now interrupt the secondary, starting both TBs */ | ||
| 393 | psurge_set_ipi(1); | ||
| 394 | |||
| 395 | smp_tb_synchronized = 1; | ||
| 396 | } | ||
| 397 | |||
| 398 | static struct irqaction psurge_irqaction = { | ||
| 399 | .handler = psurge_primary_intr, | ||
| 400 | .flags = SA_INTERRUPT, | ||
| 401 | .mask = CPU_MASK_NONE, | ||
| 402 | .name = "primary IPI", | ||
| 403 | }; | ||
| 404 | |||
| 405 | static void __init smp_psurge_setup_cpu(int cpu_nr) | ||
| 406 | { | ||
| 407 | |||
| 408 | if (cpu_nr == 0) { | ||
| 409 | /* If we failed to start the second CPU, we should still | ||
| 410 | * send it an IPI to start the timebase & DEC or we might | ||
| 411 | * have them stuck. | ||
| 412 | */ | ||
| 413 | if (num_online_cpus() < 2) { | ||
| 414 | if (psurge_type == PSURGE_DUAL) | ||
| 415 | psurge_set_ipi(1); | ||
| 416 | return; | ||
| 417 | } | ||
| 418 | /* reset the entry point so if we get another intr we won't | ||
| 419 | * try to startup again */ | ||
| 420 | out_be32(psurge_start, 0x100); | ||
| 421 | if (setup_irq(30, &psurge_irqaction)) | ||
| 422 | printk(KERN_ERR "Couldn't get primary IPI interrupt"); | ||
| 423 | } | ||
| 424 | |||
| 425 | if (psurge_type == PSURGE_DUAL) | ||
| 426 | psurge_dual_sync_tb(cpu_nr); | ||
| 427 | } | ||
| 428 | |||
| 429 | void __init smp_psurge_take_timebase(void) | ||
| 430 | { | ||
| 431 | /* Dummy implementation */ | ||
| 432 | } | ||
| 433 | |||
| 434 | void __init smp_psurge_give_timebase(void) | ||
| 435 | { | ||
| 436 | /* Dummy implementation */ | ||
| 437 | } | ||
| 438 | |||
| 439 | static int __init smp_core99_probe(void) | ||
| 440 | { | ||
| 441 | #ifdef CONFIG_6xx | ||
| 442 | extern int powersave_nap; | ||
| 443 | #endif | ||
| 444 | struct device_node *cpus, *firstcpu; | ||
| 445 | int i, ncpus = 0, boot_cpu = -1; | ||
| 446 | u32 *tbprop = NULL; | ||
| 447 | |||
| 448 | if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345); | ||
| 449 | cpus = firstcpu = find_type_devices("cpu"); | ||
| 450 | while(cpus != NULL) { | ||
| 451 | u32 *regprop = (u32 *)get_property(cpus, "reg", NULL); | ||
| 452 | char *stateprop = (char *)get_property(cpus, "state", NULL); | ||
| 453 | if (regprop != NULL && stateprop != NULL && | ||
| 454 | !strncmp(stateprop, "running", 7)) | ||
| 455 | boot_cpu = *regprop; | ||
| 456 | ++ncpus; | ||
| 457 | cpus = cpus->next; | ||
| 458 | } | ||
| 459 | if (boot_cpu == -1) | ||
| 460 | printk(KERN_WARNING "Couldn't detect boot CPU !\n"); | ||
| 461 | if (boot_cpu != 0) | ||
| 462 | printk(KERN_WARNING "Boot CPU is %d, unsupported setup !\n", boot_cpu); | ||
| 463 | |||
| 464 | if (machine_is_compatible("MacRISC4")) { | ||
| 465 | extern struct smp_ops_t core99_smp_ops; | ||
| 466 | |||
| 467 | core99_smp_ops.take_timebase = smp_generic_take_timebase; | ||
| 468 | core99_smp_ops.give_timebase = smp_generic_give_timebase; | ||
| 469 | } else { | ||
| 470 | if (firstcpu != NULL) | ||
| 471 | tbprop = (u32 *)get_property(firstcpu, "timebase-enable", NULL); | ||
| 472 | if (tbprop) | ||
| 473 | core99_tb_gpio = *tbprop; | ||
| 474 | else | ||
| 475 | core99_tb_gpio = KL_GPIO_TB_ENABLE; | ||
| 476 | } | ||
| 477 | |||
| 478 | if (ncpus > 1) { | ||
| 479 | openpic_request_IPIs(); | ||
| 480 | for (i = 1; i < ncpus; ++i) | ||
| 481 | smp_hw_index[i] = i; | ||
| 482 | #ifdef CONFIG_6xx | ||
| 483 | powersave_nap = 0; | ||
| 484 | #endif | ||
| 485 | core99_init_caches(0); | ||
| 486 | } | ||
| 487 | |||
| 488 | return ncpus; | ||
| 489 | } | ||
| 490 | |||
| 491 | static void __devinit smp_core99_kick_cpu(int nr) | ||
| 492 | { | ||
| 493 | unsigned long save_vector, new_vector; | ||
| 494 | unsigned long flags; | ||
| 495 | |||
| 496 | volatile unsigned long *vector | ||
| 497 | = ((volatile unsigned long *)(KERNELBASE+0x100)); | ||
| 498 | if (nr < 0 || nr > 3) | ||
| 499 | return; | ||
| 500 | if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346); | ||
| 501 | |||
| 502 | local_irq_save(flags); | ||
| 503 | local_irq_disable(); | ||
| 504 | |||
| 505 | /* Save reset vector */ | ||
| 506 | save_vector = *vector; | ||
| 507 | |||
| 508 | /* Setup fake reset vector that does | ||
| 509 | * b __secondary_start_pmac_0 + nr*8 - KERNELBASE | ||
| 510 | */ | ||
| 511 | new_vector = (unsigned long) __secondary_start_pmac_0 + nr * 8; | ||
| 512 | *vector = 0x48000002 + new_vector - KERNELBASE; | ||
| 513 | |||
| 514 | /* flush data cache and inval instruction cache */ | ||
| 515 | flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); | ||
| 516 | |||
| 517 | /* Put some life in our friend */ | ||
| 518 | pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0); | ||
| 519 | |||
| 520 | /* FIXME: We wait a bit for the CPU to take the exception, I should | ||
| 521 | * instead wait for the entry code to set something for me. Well, | ||
| 522 | * ideally, all that crap will be done in prom.c and the CPU left | ||
| 523 | * in a RAM-based wait loop like CHRP. | ||
| 524 | */ | ||
| 525 | mdelay(1); | ||
| 526 | |||
| 527 | /* Restore our exception vector */ | ||
| 528 | *vector = save_vector; | ||
| 529 | flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); | ||
| 530 | |||
| 531 | local_irq_restore(flags); | ||
| 532 | if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347); | ||
| 533 | } | ||
| 534 | |||
| 535 | static void __devinit smp_core99_setup_cpu(int cpu_nr) | ||
| 536 | { | ||
| 537 | /* Setup L2/L3 */ | ||
| 538 | if (cpu_nr != 0) | ||
| 539 | core99_init_caches(cpu_nr); | ||
| 540 | |||
| 541 | /* Setup openpic */ | ||
| 542 | do_openpic_setup_cpu(); | ||
| 543 | |||
| 544 | if (cpu_nr == 0) { | ||
| 545 | #ifdef CONFIG_POWER4 | ||
| 546 | extern void g5_phy_disable_cpu1(void); | ||
| 547 | |||
| 548 | /* If we didn't start the second CPU, we must take | ||
| 549 | * it off the bus | ||
| 550 | */ | ||
| 551 | if (machine_is_compatible("MacRISC4") && | ||
| 552 | num_online_cpus() < 2) | ||
| 553 | g5_phy_disable_cpu1(); | ||
| 554 | #endif /* CONFIG_POWER4 */ | ||
| 555 | if (ppc_md.progress) ppc_md.progress("core99_setup_cpu 0 done", 0x349); | ||
| 556 | } | ||
| 557 | } | ||
| 558 | |||
| 559 | /* not __init, called in sleep/wakeup code */ | ||
| 560 | void smp_core99_take_timebase(void) | ||
| 561 | { | ||
| 562 | unsigned long flags; | ||
| 563 | |||
| 564 | /* tell the primary we're here */ | ||
| 565 | sec_tb_reset = 1; | ||
| 566 | mb(); | ||
| 567 | |||
| 568 | /* wait for the primary to set pri_tb_hi/lo */ | ||
| 569 | while (sec_tb_reset < 2) | ||
| 570 | mb(); | ||
| 571 | |||
| 572 | /* set our stuff the same as the primary */ | ||
| 573 | local_irq_save(flags); | ||
| 574 | set_dec(1); | ||
| 575 | set_tb(pri_tb_hi, pri_tb_lo); | ||
| 576 | last_jiffy_stamp(smp_processor_id()) = pri_tb_stamp; | ||
| 577 | mb(); | ||
| 578 | |||
| 579 | /* tell the primary we're done */ | ||
| 580 | sec_tb_reset = 0; | ||
| 581 | mb(); | ||
| 582 | local_irq_restore(flags); | ||
| 583 | } | ||
| 584 | |||
| 585 | /* not __init, called in sleep/wakeup code */ | ||
| 586 | void smp_core99_give_timebase(void) | ||
| 587 | { | ||
| 588 | unsigned long flags; | ||
| 589 | unsigned int t; | ||
| 590 | |||
| 591 | /* wait for the secondary to be in take_timebase */ | ||
| 592 | for (t = 100000; t > 0 && !sec_tb_reset; --t) | ||
| 593 | udelay(10); | ||
| 594 | if (!sec_tb_reset) { | ||
| 595 | printk(KERN_WARNING "Timeout waiting sync on second CPU\n"); | ||
| 596 | return; | ||
| 597 | } | ||
| 598 | |||
| 599 | /* freeze the timebase and read it */ | ||
| 600 | /* disable interrupts so the timebase is disabled for the | ||
| 601 | shortest possible time */ | ||
| 602 | local_irq_save(flags); | ||
| 603 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4); | ||
| 604 | pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0); | ||
| 605 | mb(); | ||
| 606 | pri_tb_hi = get_tbu(); | ||
| 607 | pri_tb_lo = get_tbl(); | ||
| 608 | pri_tb_stamp = last_jiffy_stamp(smp_processor_id()); | ||
| 609 | mb(); | ||
| 610 | |||
| 611 | /* tell the secondary we're ready */ | ||
| 612 | sec_tb_reset = 2; | ||
| 613 | mb(); | ||
| 614 | |||
| 615 | /* wait for the secondary to have taken it */ | ||
| 616 | for (t = 100000; t > 0 && sec_tb_reset; --t) | ||
| 617 | udelay(10); | ||
| 618 | if (sec_tb_reset) | ||
| 619 | printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n"); | ||
| 620 | else | ||
| 621 | smp_tb_synchronized = 1; | ||
| 622 | |||
| 623 | /* Now, restart the timebase by leaving the GPIO to an open collector */ | ||
| 624 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0); | ||
| 625 | pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0); | ||
| 626 | local_irq_restore(flags); | ||
| 627 | } | ||
| 628 | |||
| 629 | |||
| 630 | /* PowerSurge-style Macs */ | ||
| 631 | struct smp_ops_t psurge_smp_ops = { | ||
| 632 | .message_pass = smp_psurge_message_pass, | ||
| 633 | .probe = smp_psurge_probe, | ||
| 634 | .kick_cpu = smp_psurge_kick_cpu, | ||
| 635 | .setup_cpu = smp_psurge_setup_cpu, | ||
| 636 | .give_timebase = smp_psurge_give_timebase, | ||
| 637 | .take_timebase = smp_psurge_take_timebase, | ||
| 638 | }; | ||
| 639 | |||
| 640 | /* Core99 Macs (dual G4s) */ | ||
| 641 | struct smp_ops_t core99_smp_ops = { | ||
| 642 | .message_pass = smp_openpic_message_pass, | ||
| 643 | .probe = smp_core99_probe, | ||
| 644 | .kick_cpu = smp_core99_kick_cpu, | ||
| 645 | .setup_cpu = smp_core99_setup_cpu, | ||
| 646 | .give_timebase = smp_core99_give_timebase, | ||
| 647 | .take_timebase = smp_core99_take_timebase, | ||
| 648 | }; | ||
| 649 | |||
| 650 | #ifdef CONFIG_HOTPLUG_CPU | ||
| 651 | |||
| 652 | int __cpu_disable(void) | ||
| 653 | { | ||
| 654 | cpu_clear(smp_processor_id(), cpu_online_map); | ||
| 655 | |||
| 656 | /* XXX reset cpu affinity here */ | ||
| 657 | openpic_set_priority(0xf); | ||
| 658 | asm volatile("mtdec %0" : : "r" (0x7fffffff)); | ||
| 659 | mb(); | ||
| 660 | udelay(20); | ||
| 661 | asm volatile("mtdec %0" : : "r" (0x7fffffff)); | ||
| 662 | return 0; | ||
| 663 | } | ||
| 664 | |||
| 665 | extern void low_cpu_die(void) __attribute__((noreturn)); /* in pmac_sleep.S */ | ||
| 666 | static int cpu_dead[NR_CPUS]; | ||
| 667 | |||
| 668 | void cpu_die(void) | ||
| 669 | { | ||
| 670 | local_irq_disable(); | ||
| 671 | cpu_dead[smp_processor_id()] = 1; | ||
| 672 | mb(); | ||
| 673 | low_cpu_die(); | ||
| 674 | } | ||
| 675 | |||
| 676 | void __cpu_die(unsigned int cpu) | ||
| 677 | { | ||
| 678 | int timeout; | ||
| 679 | |||
| 680 | timeout = 1000; | ||
| 681 | while (!cpu_dead[cpu]) { | ||
| 682 | if (--timeout == 0) { | ||
| 683 | printk("CPU %u refused to die!\n", cpu); | ||
| 684 | break; | ||
| 685 | } | ||
| 686 | msleep(1); | ||
| 687 | } | ||
| 688 | cpu_callin_map[cpu] = 0; | ||
| 689 | cpu_dead[cpu] = 0; | ||
| 690 | } | ||
| 691 | |||
| 692 | #endif | ||
diff --git a/arch/ppc/platforms/pmac_time.c b/arch/ppc/platforms/pmac_time.c deleted file mode 100644 index edb9fcc64790..000000000000 --- a/arch/ppc/platforms/pmac_time.c +++ /dev/null | |||
| @@ -1,291 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Support for periodic interrupts (100 per second) and for getting | ||
| 3 | * the current time from the RTC on Power Macintoshes. | ||
| 4 | * | ||
| 5 | * We use the decrementer register for our periodic interrupts. | ||
| 6 | * | ||
| 7 | * Paul Mackerras August 1996. | ||
| 8 | * Copyright (C) 1996 Paul Mackerras. | ||
| 9 | */ | ||
| 10 | #include <linux/config.h> | ||
| 11 | #include <linux/errno.h> | ||
| 12 | #include <linux/sched.h> | ||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/param.h> | ||
| 15 | #include <linux/string.h> | ||
| 16 | #include <linux/mm.h> | ||
| 17 | #include <linux/init.h> | ||
| 18 | #include <linux/time.h> | ||
| 19 | #include <linux/adb.h> | ||
| 20 | #include <linux/cuda.h> | ||
| 21 | #include <linux/pmu.h> | ||
| 22 | #include <linux/hardirq.h> | ||
| 23 | |||
| 24 | #include <asm/sections.h> | ||
| 25 | #include <asm/prom.h> | ||
| 26 | #include <asm/system.h> | ||
| 27 | #include <asm/io.h> | ||
| 28 | #include <asm/pgtable.h> | ||
| 29 | #include <asm/machdep.h> | ||
| 30 | #include <asm/time.h> | ||
| 31 | #include <asm/nvram.h> | ||
| 32 | |||
| 33 | /* Apparently the RTC stores seconds since 1 Jan 1904 */ | ||
| 34 | #define RTC_OFFSET 2082844800 | ||
| 35 | |||
| 36 | /* | ||
| 37 | * Calibrate the decrementer frequency with the VIA timer 1. | ||
| 38 | */ | ||
| 39 | #define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */ | ||
| 40 | |||
| 41 | /* VIA registers */ | ||
| 42 | #define RS 0x200 /* skip between registers */ | ||
| 43 | #define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */ | ||
| 44 | #define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */ | ||
| 45 | #define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */ | ||
| 46 | #define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */ | ||
| 47 | #define ACR (11*RS) /* Auxiliary control register */ | ||
| 48 | #define IFR (13*RS) /* Interrupt flag register */ | ||
| 49 | |||
| 50 | /* Bits in ACR */ | ||
| 51 | #define T1MODE 0xc0 /* Timer 1 mode */ | ||
| 52 | #define T1MODE_CONT 0x40 /* continuous interrupts */ | ||
| 53 | |||
| 54 | /* Bits in IFR and IER */ | ||
| 55 | #define T1_INT 0x40 /* Timer 1 interrupt */ | ||
| 56 | |||
| 57 | extern struct timezone sys_tz; | ||
| 58 | |||
| 59 | long __init | ||
| 60 | pmac_time_init(void) | ||
| 61 | { | ||
| 62 | #ifdef CONFIG_NVRAM | ||
| 63 | s32 delta = 0; | ||
| 64 | int dst; | ||
| 65 | |||
| 66 | delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16; | ||
| 67 | delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8; | ||
| 68 | delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb); | ||
| 69 | if (delta & 0x00800000UL) | ||
| 70 | delta |= 0xFF000000UL; | ||
| 71 | dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0); | ||
| 72 | printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60, | ||
| 73 | dst ? "on" : "off"); | ||
| 74 | return delta; | ||
| 75 | #else | ||
| 76 | return 0; | ||
| 77 | #endif | ||
| 78 | } | ||
| 79 | |||
| 80 | unsigned long | ||
| 81 | pmac_get_rtc_time(void) | ||
| 82 | { | ||
| 83 | #if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU) | ||
| 84 | struct adb_request req; | ||
| 85 | unsigned long now; | ||
| 86 | #endif | ||
| 87 | |||
| 88 | /* Get the time from the RTC */ | ||
| 89 | switch (sys_ctrler) { | ||
| 90 | #ifdef CONFIG_ADB_CUDA | ||
| 91 | case SYS_CTRLER_CUDA: | ||
| 92 | if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0) | ||
| 93 | return 0; | ||
| 94 | while (!req.complete) | ||
| 95 | cuda_poll(); | ||
| 96 | if (req.reply_len != 7) | ||
| 97 | printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n", | ||
| 98 | req.reply_len); | ||
| 99 | now = (req.reply[3] << 24) + (req.reply[4] << 16) | ||
| 100 | + (req.reply[5] << 8) + req.reply[6]; | ||
| 101 | return now - RTC_OFFSET; | ||
| 102 | #endif /* CONFIG_ADB_CUDA */ | ||
| 103 | #ifdef CONFIG_ADB_PMU | ||
| 104 | case SYS_CTRLER_PMU: | ||
| 105 | if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0) | ||
| 106 | return 0; | ||
| 107 | while (!req.complete) | ||
| 108 | pmu_poll(); | ||
| 109 | if (req.reply_len != 4) | ||
| 110 | printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n", | ||
| 111 | req.reply_len); | ||
| 112 | now = (req.reply[0] << 24) + (req.reply[1] << 16) | ||
| 113 | + (req.reply[2] << 8) + req.reply[3]; | ||
| 114 | return now - RTC_OFFSET; | ||
| 115 | #endif /* CONFIG_ADB_PMU */ | ||
| 116 | default: ; | ||
| 117 | } | ||
| 118 | return 0; | ||
| 119 | } | ||
| 120 | |||
| 121 | int | ||
| 122 | pmac_set_rtc_time(unsigned long nowtime) | ||
| 123 | { | ||
| 124 | #if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU) | ||
| 125 | struct adb_request req; | ||
| 126 | #endif | ||
| 127 | |||
| 128 | nowtime += RTC_OFFSET; | ||
| 129 | |||
| 130 | switch (sys_ctrler) { | ||
| 131 | #ifdef CONFIG_ADB_CUDA | ||
| 132 | case SYS_CTRLER_CUDA: | ||
| 133 | if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME, | ||
| 134 | nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0) | ||
| 135 | return 0; | ||
| 136 | while (!req.complete) | ||
| 137 | cuda_poll(); | ||
| 138 | if ((req.reply_len != 3) && (req.reply_len != 7)) | ||
| 139 | printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n", | ||
| 140 | req.reply_len); | ||
| 141 | return 1; | ||
| 142 | #endif /* CONFIG_ADB_CUDA */ | ||
| 143 | #ifdef CONFIG_ADB_PMU | ||
| 144 | case SYS_CTRLER_PMU: | ||
| 145 | if (pmu_request(&req, NULL, 5, PMU_SET_RTC, | ||
| 146 | nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0) | ||
| 147 | return 0; | ||
| 148 | while (!req.complete) | ||
| 149 | pmu_poll(); | ||
| 150 | if (req.reply_len != 0) | ||
| 151 | printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n", | ||
| 152 | req.reply_len); | ||
| 153 | return 1; | ||
| 154 | #endif /* CONFIG_ADB_PMU */ | ||
| 155 | default: | ||
| 156 | return 0; | ||
| 157 | } | ||
| 158 | } | ||
| 159 | |||
| 160 | /* | ||
| 161 | * Calibrate the decrementer register using VIA timer 1. | ||
| 162 | * This is used both on powermacs and CHRP machines. | ||
| 163 | */ | ||
| 164 | int __init | ||
| 165 | via_calibrate_decr(void) | ||
| 166 | { | ||
| 167 | struct device_node *vias; | ||
| 168 | volatile unsigned char __iomem *via; | ||
| 169 | int count = VIA_TIMER_FREQ_6 / 100; | ||
| 170 | unsigned int dstart, dend; | ||
| 171 | |||
| 172 | vias = find_devices("via-cuda"); | ||
| 173 | if (vias == 0) | ||
| 174 | vias = find_devices("via-pmu"); | ||
| 175 | if (vias == 0) | ||
| 176 | vias = find_devices("via"); | ||
| 177 | if (vias == 0 || vias->n_addrs == 0) | ||
| 178 | return 0; | ||
| 179 | via = ioremap(vias->addrs[0].address, vias->addrs[0].size); | ||
| 180 | |||
| 181 | /* set timer 1 for continuous interrupts */ | ||
| 182 | out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT); | ||
| 183 | /* set the counter to a small value */ | ||
| 184 | out_8(&via[T1CH], 2); | ||
| 185 | /* set the latch to `count' */ | ||
| 186 | out_8(&via[T1LL], count); | ||
| 187 | out_8(&via[T1LH], count >> 8); | ||
| 188 | /* wait until it hits 0 */ | ||
| 189 | while ((in_8(&via[IFR]) & T1_INT) == 0) | ||
| 190 | ; | ||
| 191 | dstart = get_dec(); | ||
| 192 | /* clear the interrupt & wait until it hits 0 again */ | ||
| 193 | in_8(&via[T1CL]); | ||
| 194 | while ((in_8(&via[IFR]) & T1_INT) == 0) | ||
| 195 | ; | ||
| 196 | dend = get_dec(); | ||
| 197 | |||
| 198 | tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100); | ||
| 199 | tb_to_us = mulhwu_scale_factor(dstart - dend, 60000); | ||
| 200 | |||
| 201 | printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n", | ||
| 202 | tb_ticks_per_jiffy, dstart - dend); | ||
| 203 | |||
| 204 | iounmap(via); | ||
| 205 | |||
| 206 | return 1; | ||
| 207 | } | ||
| 208 | |||
| 209 | #ifdef CONFIG_PM | ||
| 210 | /* | ||
| 211 | * Reset the time after a sleep. | ||
| 212 | */ | ||
| 213 | static int | ||
| 214 | time_sleep_notify(struct pmu_sleep_notifier *self, int when) | ||
| 215 | { | ||
| 216 | static unsigned long time_diff; | ||
| 217 | unsigned long flags; | ||
| 218 | unsigned long seq; | ||
| 219 | |||
| 220 | switch (when) { | ||
| 221 | case PBOOK_SLEEP_NOW: | ||
| 222 | do { | ||
| 223 | seq = read_seqbegin_irqsave(&xtime_lock, flags); | ||
| 224 | time_diff = xtime.tv_sec - pmac_get_rtc_time(); | ||
| 225 | } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); | ||
| 226 | break; | ||
| 227 | case PBOOK_WAKE: | ||
| 228 | write_seqlock_irqsave(&xtime_lock, flags); | ||
| 229 | xtime.tv_sec = pmac_get_rtc_time() + time_diff; | ||
| 230 | xtime.tv_nsec = 0; | ||
| 231 | last_rtc_update = xtime.tv_sec; | ||
| 232 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
| 233 | break; | ||
| 234 | } | ||
| 235 | return PBOOK_SLEEP_OK; | ||
| 236 | } | ||
| 237 | |||
| 238 | static struct pmu_sleep_notifier time_sleep_notifier = { | ||
| 239 | time_sleep_notify, SLEEP_LEVEL_MISC, | ||
| 240 | }; | ||
| 241 | #endif /* CONFIG_PM */ | ||
| 242 | |||
| 243 | /* | ||
| 244 | * Query the OF and get the decr frequency. | ||
| 245 | * This was taken from the pmac time_init() when merging the prep/pmac | ||
| 246 | * time functions. | ||
| 247 | */ | ||
| 248 | void __init | ||
| 249 | pmac_calibrate_decr(void) | ||
| 250 | { | ||
| 251 | struct device_node *cpu; | ||
| 252 | unsigned int freq, *fp; | ||
| 253 | |||
| 254 | #ifdef CONFIG_PM | ||
| 255 | pmu_register_sleep_notifier(&time_sleep_notifier); | ||
| 256 | #endif /* CONFIG_PM */ | ||
| 257 | |||
| 258 | /* We assume MacRISC2 machines have correct device-tree | ||
| 259 | * calibration. That's better since the VIA itself seems | ||
| 260 | * to be slightly off. --BenH | ||
| 261 | */ | ||
| 262 | if (!machine_is_compatible("MacRISC2") && | ||
| 263 | !machine_is_compatible("MacRISC3") && | ||
| 264 | !machine_is_compatible("MacRISC4")) | ||
| 265 | if (via_calibrate_decr()) | ||
| 266 | return; | ||
| 267 | |||
| 268 | /* Special case: QuickSilver G4s seem to have a badly calibrated | ||
| 269 | * timebase-frequency in OF, VIA is much better on these. We should | ||
| 270 | * probably implement calibration based on the KL timer on these | ||
| 271 | * machines anyway... -BenH | ||
| 272 | */ | ||
| 273 | if (machine_is_compatible("PowerMac3,5")) | ||
| 274 | if (via_calibrate_decr()) | ||
| 275 | return; | ||
| 276 | /* | ||
| 277 | * The cpu node should have a timebase-frequency property | ||
| 278 | * to tell us the rate at which the decrementer counts. | ||
| 279 | */ | ||
| 280 | cpu = find_type_devices("cpu"); | ||
| 281 | if (cpu == 0) | ||
| 282 | panic("can't find cpu node in time_init"); | ||
| 283 | fp = (unsigned int *) get_property(cpu, "timebase-frequency", NULL); | ||
| 284 | if (fp == 0) | ||
| 285 | panic("can't get cpu timebase frequency"); | ||
| 286 | freq = *fp; | ||
| 287 | printk("time_init: decrementer frequency = %u.%.6u MHz\n", | ||
| 288 | freq/1000000, freq%1000000); | ||
| 289 | tb_ticks_per_jiffy = freq / HZ; | ||
| 290 | tb_to_us = mulhwu_scale_factor(freq, 1000000); | ||
| 291 | } | ||
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile index 84ef03018d0e..159dcd92a6d1 100644 --- a/arch/ppc/syslib/Makefile +++ b/arch/ppc/syslib/Makefile | |||
| @@ -39,8 +39,6 @@ obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \ | |||
| 39 | ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o | 39 | ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o |
| 40 | obj-$(CONFIG_PCI_QSPAN) += qspan_pci.o | 40 | obj-$(CONFIG_PCI_QSPAN) += qspan_pci.o |
| 41 | obj-$(CONFIG_PPC_OF) += prom_init.o prom.o | 41 | obj-$(CONFIG_PPC_OF) += prom_init.o prom.o |
| 42 | obj-$(CONFIG_PPC_PMAC) += open_pic.o | ||
| 43 | obj-$(CONFIG_POWER4) += open_pic2.o | ||
| 44 | obj-$(CONFIG_PPC_CHRP) += open_pic.o | 42 | obj-$(CONFIG_PPC_CHRP) += open_pic.o |
| 45 | obj-$(CONFIG_PPC_PREP) += open_pic.o todc_time.o | 43 | obj-$(CONFIG_PPC_PREP) += open_pic.o todc_time.o |
| 46 | obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o | 44 | obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o |
diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/mpc83xx_devices.c index 847df4409982..f9b95de70e23 100644 --- a/arch/ppc/syslib/mpc83xx_devices.c +++ b/arch/ppc/syslib/mpc83xx_devices.c | |||
| @@ -28,7 +28,6 @@ | |||
| 28 | */ | 28 | */ |
| 29 | 29 | ||
| 30 | struct gianfar_mdio_data mpc83xx_mdio_pdata = { | 30 | struct gianfar_mdio_data mpc83xx_mdio_pdata = { |
| 31 | .paddr = 0x24520, | ||
| 32 | }; | 31 | }; |
| 33 | 32 | ||
| 34 | static struct gianfar_platform_data mpc83xx_tsec1_pdata = { | 33 | static struct gianfar_platform_data mpc83xx_tsec1_pdata = { |
| @@ -226,7 +225,14 @@ struct platform_device ppc_sys_platform_devices[] = { | |||
| 226 | .name = "fsl-gianfar_mdio", | 225 | .name = "fsl-gianfar_mdio", |
| 227 | .id = 0, | 226 | .id = 0, |
| 228 | .dev.platform_data = &mpc83xx_mdio_pdata, | 227 | .dev.platform_data = &mpc83xx_mdio_pdata, |
| 229 | .num_resources = 0, | 228 | .num_resources = 1, |
| 229 | .resource = (struct resource[]) { | ||
| 230 | { | ||
| 231 | .start = 0x24520, | ||
| 232 | .end = 0x2453f, | ||
| 233 | .flags = IORESOURCE_MEM, | ||
| 234 | }, | ||
| 235 | }, | ||
| 230 | }, | 236 | }, |
| 231 | }; | 237 | }; |
| 232 | 238 | ||
diff --git a/arch/ppc/syslib/mpc85xx_devices.c b/arch/ppc/syslib/mpc85xx_devices.c index 69949d255658..00e9b6ff2f6e 100644 --- a/arch/ppc/syslib/mpc85xx_devices.c +++ b/arch/ppc/syslib/mpc85xx_devices.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | * what CCSRBAR is, will get fixed up by mach_mpc85xx_fixup | 26 | * what CCSRBAR is, will get fixed up by mach_mpc85xx_fixup |
| 27 | */ | 27 | */ |
| 28 | struct gianfar_mdio_data mpc85xx_mdio_pdata = { | 28 | struct gianfar_mdio_data mpc85xx_mdio_pdata = { |
| 29 | .paddr = MPC85xx_MIIM_OFFSET, | ||
| 30 | }; | 29 | }; |
| 31 | 30 | ||
| 32 | static struct gianfar_platform_data mpc85xx_tsec1_pdata = { | 31 | static struct gianfar_platform_data mpc85xx_tsec1_pdata = { |
| @@ -720,7 +719,14 @@ struct platform_device ppc_sys_platform_devices[] = { | |||
| 720 | .name = "fsl-gianfar_mdio", | 719 | .name = "fsl-gianfar_mdio", |
| 721 | .id = 0, | 720 | .id = 0, |
| 722 | .dev.platform_data = &mpc85xx_mdio_pdata, | 721 | .dev.platform_data = &mpc85xx_mdio_pdata, |
| 723 | .num_resources = 0, | 722 | .num_resources = 1, |
| 723 | .resource = (struct resource[]) { | ||
| 724 | { | ||
| 725 | .start = 0x24520, | ||
| 726 | .end = 0x2453f, | ||
| 727 | .flags = IORESOURCE_MEM, | ||
| 728 | }, | ||
| 729 | }, | ||
| 724 | }, | 730 | }, |
| 725 | }; | 731 | }; |
| 726 | 732 | ||
diff --git a/arch/ppc/syslib/ocp.c b/arch/ppc/syslib/ocp.c index 9ccce438bd7a..ab34b1d6072f 100644 --- a/arch/ppc/syslib/ocp.c +++ b/arch/ppc/syslib/ocp.c | |||
| @@ -189,6 +189,8 @@ ocp_device_resume(struct device *dev) | |||
| 189 | struct bus_type ocp_bus_type = { | 189 | struct bus_type ocp_bus_type = { |
| 190 | .name = "ocp", | 190 | .name = "ocp", |
| 191 | .match = ocp_device_match, | 191 | .match = ocp_device_match, |
| 192 | .probe = ocp_driver_probe, | ||
| 193 | .remove = ocp_driver_remove, | ||
| 192 | .suspend = ocp_device_suspend, | 194 | .suspend = ocp_device_suspend, |
| 193 | .resume = ocp_device_resume, | 195 | .resume = ocp_device_resume, |
| 194 | }; | 196 | }; |
| @@ -210,8 +212,6 @@ ocp_register_driver(struct ocp_driver *drv) | |||
| 210 | /* initialize common driver fields */ | 212 | /* initialize common driver fields */ |
| 211 | drv->driver.name = drv->name; | 213 | drv->driver.name = drv->name; |
| 212 | drv->driver.bus = &ocp_bus_type; | 214 | drv->driver.bus = &ocp_bus_type; |
| 213 | drv->driver.probe = ocp_device_probe; | ||
| 214 | drv->driver.remove = ocp_device_remove; | ||
| 215 | 215 | ||
| 216 | /* register with core */ | 216 | /* register with core */ |
| 217 | return driver_register(&drv->driver); | 217 | return driver_register(&drv->driver); |
diff --git a/arch/ppc/syslib/prom.c b/arch/ppc/syslib/prom.c index af4deace49e0..482f837fd373 100644 --- a/arch/ppc/syslib/prom.c +++ b/arch/ppc/syslib/prom.c | |||
| @@ -70,8 +70,6 @@ int use_of_interrupt_tree; | |||
| 70 | struct device_node *dflt_interrupt_controller; | 70 | struct device_node *dflt_interrupt_controller; |
| 71 | int num_interrupt_controllers; | 71 | int num_interrupt_controllers; |
| 72 | 72 | ||
| 73 | int pmac_newworld; | ||
| 74 | |||
| 75 | extern unsigned int rtas_entry; /* physical pointer */ | 73 | extern unsigned int rtas_entry; /* physical pointer */ |
| 76 | 74 | ||
| 77 | extern struct device_node *allnodes; | 75 | extern struct device_node *allnodes; |
| @@ -123,22 +121,13 @@ finish_device_tree(void) | |||
| 123 | unsigned long mem = (unsigned long) klimit; | 121 | unsigned long mem = (unsigned long) klimit; |
| 124 | struct device_node *np; | 122 | struct device_node *np; |
| 125 | 123 | ||
| 126 | /* All newworld pmac machines and CHRPs now use the interrupt tree */ | 124 | /* All CHRPs now use the interrupt tree */ |
| 127 | for (np = allnodes; np != NULL; np = np->allnext) { | 125 | for (np = allnodes; np != NULL; np = np->allnext) { |
| 128 | if (get_property(np, "interrupt-parent", NULL)) { | 126 | if (get_property(np, "interrupt-parent", NULL)) { |
| 129 | use_of_interrupt_tree = 1; | 127 | use_of_interrupt_tree = 1; |
| 130 | break; | 128 | break; |
| 131 | } | 129 | } |
| 132 | } | 130 | } |
| 133 | if (_machine == _MACH_Pmac && use_of_interrupt_tree) | ||
| 134 | pmac_newworld = 1; | ||
| 135 | |||
| 136 | #ifdef CONFIG_BOOTX_TEXT | ||
| 137 | if (boot_infos && pmac_newworld) { | ||
| 138 | prom_print("WARNING ! BootX/miBoot booting is not supported on this machine\n"); | ||
| 139 | prom_print(" You should use an Open Firmware bootloader\n"); | ||
| 140 | } | ||
| 141 | #endif /* CONFIG_BOOTX_TEXT */ | ||
| 142 | 131 | ||
| 143 | if (use_of_interrupt_tree) { | 132 | if (use_of_interrupt_tree) { |
| 144 | /* | 133 | /* |
| @@ -434,16 +423,10 @@ finish_node_interrupts(struct device_node *np, unsigned long mem_start) | |||
| 434 | * those machines, we want to offset interrupts from the | 423 | * those machines, we want to offset interrupts from the |
| 435 | * second openpic by 128 -- BenH | 424 | * second openpic by 128 -- BenH |
| 436 | */ | 425 | */ |
| 437 | if (_machine != _MACH_Pmac && num_interrupt_controllers > 1 | 426 | if (num_interrupt_controllers > 1 |
| 438 | && ic != NULL | 427 | && ic != NULL |
| 439 | && get_property(ic, "interrupt-parent", NULL) == NULL) | 428 | && get_property(ic, "interrupt-parent", NULL) == NULL) |
| 440 | offset = 16; | 429 | offset = 16; |
| 441 | else if (_machine == _MACH_Pmac && num_interrupt_controllers > 1 | ||
| 442 | && ic != NULL && ic->parent != NULL) { | ||
| 443 | char *name = get_property(ic->parent, "name", NULL); | ||
| 444 | if (name && !strcmp(name, "u3")) | ||
| 445 | offset = 128; | ||
| 446 | } | ||
| 447 | 430 | ||
| 448 | np->intrs[i].line = irq[0] + offset; | 431 | np->intrs[i].line = irq[0] + offset; |
| 449 | if (n > 1) | 432 | if (n > 1) |
diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c index c80177f8ec04..4344cbe9b5c5 100644 --- a/arch/ppc/xmon/start.c +++ b/arch/ppc/xmon/start.c | |||
| @@ -18,7 +18,6 @@ | |||
| 18 | #include <asm/bootx.h> | 18 | #include <asm/bootx.h> |
| 19 | #include <asm/machdep.h> | 19 | #include <asm/machdep.h> |
| 20 | #include <asm/errno.h> | 20 | #include <asm/errno.h> |
| 21 | #include <asm/pmac_feature.h> | ||
| 22 | #include <asm/processor.h> | 21 | #include <asm/processor.h> |
| 23 | #include <asm/delay.h> | 22 | #include <asm/delay.h> |
| 24 | #include <asm/btext.h> | 23 | #include <asm/btext.h> |
| @@ -27,11 +26,9 @@ static volatile unsigned char *sccc, *sccd; | |||
| 27 | unsigned int TXRDY, RXRDY, DLAB; | 26 | unsigned int TXRDY, RXRDY, DLAB; |
| 28 | static int xmon_expect(const char *str, unsigned int timeout); | 27 | static int xmon_expect(const char *str, unsigned int timeout); |
| 29 | 28 | ||
| 30 | static int use_serial; | ||
| 31 | static int use_screen; | 29 | static int use_screen; |
| 32 | static int via_modem; | 30 | static int via_modem; |
| 33 | static int xmon_use_sccb; | 31 | static int xmon_use_sccb; |
| 34 | static struct device_node *channel_node; | ||
| 35 | 32 | ||
| 36 | #define TB_SPEED 25000000 | 33 | #define TB_SPEED 25000000 |
| 37 | 34 | ||
| @@ -112,96 +109,21 @@ xmon_map_scc(void) | |||
| 112 | #ifdef CONFIG_PPC_MULTIPLATFORM | 109 | #ifdef CONFIG_PPC_MULTIPLATFORM |
| 113 | volatile unsigned char *base; | 110 | volatile unsigned char *base; |
| 114 | 111 | ||
| 115 | if (_machine == _MACH_Pmac) { | ||
| 116 | struct device_node *np; | ||
| 117 | unsigned long addr; | ||
| 118 | #ifdef CONFIG_BOOTX_TEXT | ||
| 119 | if (!use_screen && !use_serial | ||
| 120 | && !machine_is_compatible("iMac")) { | ||
| 121 | /* see if there is a keyboard in the device tree | ||
| 122 | with a parent of type "adb" */ | ||
| 123 | for (np = find_devices("keyboard"); np; np = np->next) | ||
| 124 | if (np->parent && np->parent->type | ||
| 125 | && strcmp(np->parent->type, "adb") == 0) | ||
| 126 | break; | ||
| 127 | |||
| 128 | /* needs to be hacked if xmon_printk is to be used | ||
| 129 | from within find_via_pmu() */ | ||
| 130 | #ifdef CONFIG_ADB_PMU | ||
| 131 | if (np != NULL && boot_text_mapped && find_via_pmu()) | ||
| 132 | use_screen = 1; | ||
| 133 | #endif | ||
| 134 | #ifdef CONFIG_ADB_CUDA | ||
| 135 | if (np != NULL && boot_text_mapped && find_via_cuda()) | ||
| 136 | use_screen = 1; | ||
| 137 | #endif | ||
| 138 | } | ||
| 139 | if (!use_screen && (np = find_devices("escc")) != NULL) { | ||
| 140 | /* | ||
| 141 | * look for the device node for the serial port | ||
| 142 | * we're using and see if it says it has a modem | ||
| 143 | */ | ||
| 144 | char *name = xmon_use_sccb? "ch-b": "ch-a"; | ||
| 145 | char *slots; | ||
| 146 | int l; | ||
| 147 | |||
| 148 | np = np->child; | ||
| 149 | while (np != NULL && strcmp(np->name, name) != 0) | ||
| 150 | np = np->sibling; | ||
| 151 | if (np != NULL) { | ||
| 152 | /* XXX should parse this properly */ | ||
| 153 | channel_node = np; | ||
| 154 | slots = get_property(np, "slot-names", &l); | ||
| 155 | if (slots != NULL && l >= 10 | ||
| 156 | && strcmp(slots+4, "Modem") == 0) | ||
| 157 | via_modem = 1; | ||
| 158 | } | ||
| 159 | } | ||
| 160 | btext_drawstring("xmon uses "); | ||
| 161 | if (use_screen) | ||
| 162 | btext_drawstring("screen and keyboard\n"); | ||
| 163 | else { | ||
| 164 | if (via_modem) | ||
| 165 | btext_drawstring("modem on "); | ||
| 166 | btext_drawstring(xmon_use_sccb? "printer": "modem"); | ||
| 167 | btext_drawstring(" port\n"); | ||
| 168 | } | ||
| 169 | |||
| 170 | #endif /* CONFIG_BOOTX_TEXT */ | ||
| 171 | |||
| 172 | #ifdef CHRP_ESCC | ||
| 173 | addr = 0xc1013020; | ||
| 174 | #else | ||
| 175 | addr = 0xf3013020; | ||
| 176 | #endif | ||
| 177 | TXRDY = 4; | ||
| 178 | RXRDY = 1; | ||
| 179 | |||
| 180 | np = find_devices("mac-io"); | ||
| 181 | if (np && np->n_addrs) | ||
| 182 | addr = np->addrs[0].address + 0x13020; | ||
| 183 | base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE); | ||
| 184 | sccc = base + (addr & ~PAGE_MASK); | ||
| 185 | sccd = sccc + 0x10; | ||
| 186 | |||
| 187 | } | ||
| 188 | #ifdef CONFIG_PPC_CHRP | 112 | #ifdef CONFIG_PPC_CHRP |
| 189 | else { | 113 | base = (volatile unsigned char *) isa_io_base; |
| 190 | base = (volatile unsigned char *) isa_io_base; | 114 | if (_machine == _MACH_chrp) |
| 191 | if (_machine == _MACH_chrp) | 115 | base = (volatile unsigned char *) |
| 192 | base = (volatile unsigned char *) | 116 | ioremap(chrp_find_phys_io_base(), 0x1000); |
| 193 | ioremap(chrp_find_phys_io_base(), 0x1000); | 117 | |
| 194 | 118 | sccc = base + 0x3fd; | |
| 195 | sccc = base + 0x3fd; | 119 | sccd = base + 0x3f8; |
| 196 | sccd = base + 0x3f8; | 120 | if (xmon_use_sccb) { |
| 197 | if (xmon_use_sccb) { | 121 | sccc -= 0x100; |
| 198 | sccc -= 0x100; | 122 | sccd -= 0x100; |
| 199 | sccd -= 0x100; | ||
| 200 | } | ||
| 201 | TXRDY = 0x20; | ||
| 202 | RXRDY = 1; | ||
| 203 | DLAB = 0x80; | ||
| 204 | } | 123 | } |
| 124 | TXRDY = 0x20; | ||
| 125 | RXRDY = 1; | ||
| 126 | DLAB = 0x80; | ||
| 205 | #endif /* CONFIG_PPC_CHRP */ | 127 | #endif /* CONFIG_PPC_CHRP */ |
| 206 | #elif defined(CONFIG_GEMINI) | 128 | #elif defined(CONFIG_GEMINI) |
| 207 | /* should already be mapped by the kernel boot */ | 129 | /* should already be mapped by the kernel boot */ |
| @@ -385,16 +307,6 @@ xmon_read_poll(void) | |||
| 385 | return *sccd; | 307 | return *sccd; |
| 386 | } | 308 | } |
| 387 | 309 | ||
| 388 | static unsigned char scc_inittab[] = { | ||
| 389 | 13, 0, /* set baud rate divisor */ | ||
| 390 | 12, 1, | ||
| 391 | 14, 1, /* baud rate gen enable, src=rtxc */ | ||
| 392 | 11, 0x50, /* clocks = br gen */ | ||
| 393 | 5, 0xea, /* tx 8 bits, assert DTR & RTS */ | ||
| 394 | 4, 0x46, /* x16 clock, 1 stop */ | ||
| 395 | 3, 0xc1, /* rx enable, 8 bits */ | ||
| 396 | }; | ||
| 397 | |||
| 398 | void | 310 | void |
| 399 | xmon_init_scc(void) | 311 | xmon_init_scc(void) |
| 400 | { | 312 | { |
| @@ -407,43 +319,6 @@ xmon_init_scc(void) | |||
| 407 | sccd[3] = 3; eieio(); /* LCR = 8N1 */ | 319 | sccd[3] = 3; eieio(); /* LCR = 8N1 */ |
| 408 | sccd[1] = 0; eieio(); /* IER = 0 */ | 320 | sccd[1] = 0; eieio(); /* IER = 0 */ |
| 409 | } | 321 | } |
| 410 | else if ( _machine == _MACH_Pmac ) | ||
| 411 | { | ||
| 412 | int i, x; | ||
| 413 | |||
| 414 | if (channel_node != 0) | ||
| 415 | pmac_call_feature( | ||
| 416 | PMAC_FTR_SCC_ENABLE, | ||
| 417 | channel_node, | ||
| 418 | PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1); | ||
| 419 | printk(KERN_INFO "Serial port locked ON by debugger !\n"); | ||
| 420 | if (via_modem && channel_node != 0) { | ||
| 421 | unsigned int t0; | ||
| 422 | |||
| 423 | pmac_call_feature( | ||
| 424 | PMAC_FTR_MODEM_ENABLE, | ||
| 425 | channel_node, 0, 1); | ||
| 426 | printk(KERN_INFO "Modem powered up by debugger !\n"); | ||
| 427 | t0 = readtb(); | ||
| 428 | while (readtb() - t0 < 3*TB_SPEED) | ||
| 429 | eieio(); | ||
| 430 | } | ||
| 431 | /* use the B channel if requested */ | ||
| 432 | if (xmon_use_sccb) { | ||
| 433 | sccc = (volatile unsigned char *) | ||
| 434 | ((unsigned long)sccc & ~0x20); | ||
| 435 | sccd = sccc + 0x10; | ||
| 436 | } | ||
| 437 | for (i = 20000; i != 0; --i) { | ||
| 438 | x = *sccc; eieio(); | ||
| 439 | } | ||
| 440 | *sccc = 9; eieio(); /* reset A or B side */ | ||
| 441 | *sccc = ((unsigned long)sccc & 0x20)? 0x80: 0x40; eieio(); | ||
| 442 | for (i = 0; i < sizeof(scc_inittab); ++i) { | ||
| 443 | *sccc = scc_inittab[i]; | ||
| 444 | eieio(); | ||
| 445 | } | ||
| 446 | } | ||
| 447 | scc_initialized = 1; | 322 | scc_initialized = 1; |
| 448 | if (via_modem) { | 323 | if (via_modem) { |
| 449 | for (;;) { | 324 | for (;;) { |
| @@ -632,19 +507,9 @@ xmon_fgets(char *str, int nb, void *f) | |||
| 632 | void | 507 | void |
| 633 | xmon_enter(void) | 508 | xmon_enter(void) |
| 634 | { | 509 | { |
| 635 | #ifdef CONFIG_ADB_PMU | ||
| 636 | if (_machine == _MACH_Pmac) { | ||
| 637 | pmu_suspend(); | ||
| 638 | } | ||
| 639 | #endif | ||
| 640 | } | 510 | } |
| 641 | 511 | ||
| 642 | void | 512 | void |
| 643 | xmon_leave(void) | 513 | xmon_leave(void) |
| 644 | { | 514 | { |
| 645 | #ifdef CONFIG_ADB_PMU | ||
| 646 | if (_machine == _MACH_Pmac) { | ||
| 647 | pmu_resume(); | ||
| 648 | } | ||
| 649 | #endif | ||
| 650 | } | 515 | } |
diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c index 9075a7538e26..bdaf6597b4c2 100644 --- a/arch/ppc/xmon/xmon.c +++ b/arch/ppc/xmon/xmon.c | |||
| @@ -16,9 +16,6 @@ | |||
| 16 | #include <asm/bootx.h> | 16 | #include <asm/bootx.h> |
| 17 | #include <asm/machdep.h> | 17 | #include <asm/machdep.h> |
| 18 | #include <asm/xmon.h> | 18 | #include <asm/xmon.h> |
| 19 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
| 20 | #include <asm/backlight.h> | ||
| 21 | #endif | ||
| 22 | #include "nonstdio.h" | 19 | #include "nonstdio.h" |
| 23 | #include "privinst.h" | 20 | #include "privinst.h" |
| 24 | 21 | ||
| @@ -260,16 +257,6 @@ int xmon(struct pt_regs *excp) | |||
| 260 | */ | 257 | */ |
| 261 | #endif /* CONFIG_SMP */ | 258 | #endif /* CONFIG_SMP */ |
| 262 | remove_bpts(); | 259 | remove_bpts(); |
| 263 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
| 264 | if( setjmp(bus_error_jmp) == 0 ) { | ||
| 265 | debugger_fault_handler = handle_fault; | ||
| 266 | sync(); | ||
| 267 | set_backlight_enable(1); | ||
| 268 | set_backlight_level(BACKLIGHT_MAX); | ||
| 269 | sync(); | ||
| 270 | } | ||
| 271 | debugger_fault_handler = NULL; | ||
| 272 | #endif /* CONFIG_PMAC_BACKLIGHT */ | ||
| 273 | cmd = cmds(excp); | 260 | cmd = cmds(excp); |
| 274 | if (cmd == 's') { | 261 | if (cmd == 's') { |
| 275 | xmon_trace[smp_processor_id()] = SSTEP; | 262 | xmon_trace[smp_processor_id()] = SSTEP; |
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index 7a1033d8e00f..c5ca2dc5d428 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c | |||
| @@ -114,80 +114,108 @@ static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out, | |||
| 114 | const u8 *in, unsigned int nbytes) | 114 | const u8 *in, unsigned int nbytes) |
| 115 | { | 115 | { |
| 116 | struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); | 116 | struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); |
| 117 | int ret; | ||
| 118 | |||
| 119 | /* only use complete blocks */ | ||
| 120 | nbytes &= ~(AES_BLOCK_SIZE - 1); | ||
| 117 | 121 | ||
| 118 | switch (sctx->key_len) { | 122 | switch (sctx->key_len) { |
| 119 | case 16: | 123 | case 16: |
| 120 | crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in, nbytes); | 124 | ret = crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in, nbytes); |
| 125 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 121 | break; | 126 | break; |
| 122 | case 24: | 127 | case 24: |
| 123 | crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in, nbytes); | 128 | ret = crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in, nbytes); |
| 129 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 124 | break; | 130 | break; |
| 125 | case 32: | 131 | case 32: |
| 126 | crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in, nbytes); | 132 | ret = crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in, nbytes); |
| 133 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 127 | break; | 134 | break; |
| 128 | } | 135 | } |
| 129 | return nbytes & ~(AES_BLOCK_SIZE - 1); | 136 | return nbytes; |
| 130 | } | 137 | } |
| 131 | 138 | ||
| 132 | static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out, | 139 | static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out, |
| 133 | const u8 *in, unsigned int nbytes) | 140 | const u8 *in, unsigned int nbytes) |
| 134 | { | 141 | { |
| 135 | struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); | 142 | struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); |
| 143 | int ret; | ||
| 144 | |||
| 145 | /* only use complete blocks */ | ||
| 146 | nbytes &= ~(AES_BLOCK_SIZE - 1); | ||
| 136 | 147 | ||
| 137 | switch (sctx->key_len) { | 148 | switch (sctx->key_len) { |
| 138 | case 16: | 149 | case 16: |
| 139 | crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, nbytes); | 150 | ret = crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, nbytes); |
| 151 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 140 | break; | 152 | break; |
| 141 | case 24: | 153 | case 24: |
| 142 | crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, nbytes); | 154 | ret = crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, nbytes); |
| 155 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 143 | break; | 156 | break; |
| 144 | case 32: | 157 | case 32: |
| 145 | crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, nbytes); | 158 | ret = crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, nbytes); |
| 159 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 146 | break; | 160 | break; |
| 147 | } | 161 | } |
| 148 | return nbytes & ~(AES_BLOCK_SIZE - 1); | 162 | return nbytes; |
| 149 | } | 163 | } |
| 150 | 164 | ||
| 151 | static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out, | 165 | static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out, |
| 152 | const u8 *in, unsigned int nbytes) | 166 | const u8 *in, unsigned int nbytes) |
| 153 | { | 167 | { |
| 154 | struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); | 168 | struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); |
| 169 | int ret; | ||
| 170 | |||
| 171 | /* only use complete blocks */ | ||
| 172 | nbytes &= ~(AES_BLOCK_SIZE - 1); | ||
| 155 | 173 | ||
| 156 | memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE); | 174 | memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE); |
| 157 | switch (sctx->key_len) { | 175 | switch (sctx->key_len) { |
| 158 | case 16: | 176 | case 16: |
| 159 | crypt_s390_kmc(KMC_AES_128_ENCRYPT, &sctx->iv, out, in, nbytes); | 177 | ret = crypt_s390_kmc(KMC_AES_128_ENCRYPT, &sctx->iv, out, in, nbytes); |
| 178 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 160 | break; | 179 | break; |
| 161 | case 24: | 180 | case 24: |
| 162 | crypt_s390_kmc(KMC_AES_192_ENCRYPT, &sctx->iv, out, in, nbytes); | 181 | ret = crypt_s390_kmc(KMC_AES_192_ENCRYPT, &sctx->iv, out, in, nbytes); |
| 182 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 163 | break; | 183 | break; |
| 164 | case 32: | 184 | case 32: |
| 165 | crypt_s390_kmc(KMC_AES_256_ENCRYPT, &sctx->iv, out, in, nbytes); | 185 | ret = crypt_s390_kmc(KMC_AES_256_ENCRYPT, &sctx->iv, out, in, nbytes); |
| 186 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 166 | break; | 187 | break; |
| 167 | } | 188 | } |
| 168 | memcpy(desc->info, &sctx->iv, AES_BLOCK_SIZE); | 189 | memcpy(desc->info, &sctx->iv, AES_BLOCK_SIZE); |
| 169 | 190 | ||
| 170 | return nbytes & ~(AES_BLOCK_SIZE - 1); | 191 | return nbytes; |
| 171 | } | 192 | } |
| 172 | 193 | ||
| 173 | static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out, | 194 | static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out, |
| 174 | const u8 *in, unsigned int nbytes) | 195 | const u8 *in, unsigned int nbytes) |
| 175 | { | 196 | { |
| 176 | struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); | 197 | struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); |
| 198 | int ret; | ||
| 199 | |||
| 200 | /* only use complete blocks */ | ||
| 201 | nbytes &= ~(AES_BLOCK_SIZE - 1); | ||
| 177 | 202 | ||
| 178 | memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE); | 203 | memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE); |
| 179 | switch (sctx->key_len) { | 204 | switch (sctx->key_len) { |
| 180 | case 16: | 205 | case 16: |
| 181 | crypt_s390_kmc(KMC_AES_128_DECRYPT, &sctx->iv, out, in, nbytes); | 206 | ret = crypt_s390_kmc(KMC_AES_128_DECRYPT, &sctx->iv, out, in, nbytes); |
| 207 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 182 | break; | 208 | break; |
| 183 | case 24: | 209 | case 24: |
| 184 | crypt_s390_kmc(KMC_AES_192_DECRYPT, &sctx->iv, out, in, nbytes); | 210 | ret = crypt_s390_kmc(KMC_AES_192_DECRYPT, &sctx->iv, out, in, nbytes); |
| 211 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 185 | break; | 212 | break; |
| 186 | case 32: | 213 | case 32: |
| 187 | crypt_s390_kmc(KMC_AES_256_DECRYPT, &sctx->iv, out, in, nbytes); | 214 | ret = crypt_s390_kmc(KMC_AES_256_DECRYPT, &sctx->iv, out, in, nbytes); |
| 215 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 188 | break; | 216 | break; |
| 189 | } | 217 | } |
| 190 | return nbytes & ~(AES_BLOCK_SIZE - 1); | 218 | return nbytes; |
| 191 | } | 219 | } |
| 192 | 220 | ||
| 193 | 221 | ||
diff --git a/arch/s390/crypto/des_s390.c b/arch/s390/crypto/des_s390.c index a38bb2a3eef6..e3c37aa0a199 100644 --- a/arch/s390/crypto/des_s390.c +++ b/arch/s390/crypto/des_s390.c | |||
| @@ -15,10 +15,8 @@ | |||
| 15 | */ | 15 | */ |
| 16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
| 17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
| 18 | #include <linux/mm.h> | ||
| 19 | #include <linux/errno.h> | ||
| 20 | #include <asm/scatterlist.h> | ||
| 21 | #include <linux/crypto.h> | 18 | #include <linux/crypto.h> |
| 19 | |||
| 22 | #include "crypt_s390.h" | 20 | #include "crypt_s390.h" |
| 23 | #include "crypto_des.h" | 21 | #include "crypto_des.h" |
| 24 | 22 | ||
| @@ -46,38 +44,92 @@ struct crypt_s390_des3_192_ctx { | |||
| 46 | u8 key[DES3_192_KEY_SIZE]; | 44 | u8 key[DES3_192_KEY_SIZE]; |
| 47 | }; | 45 | }; |
| 48 | 46 | ||
| 49 | static int | 47 | static int des_setkey(void *ctx, const u8 *key, unsigned int keylen, |
| 50 | des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) | 48 | u32 *flags) |
| 51 | { | 49 | { |
| 52 | struct crypt_s390_des_ctx *dctx; | 50 | struct crypt_s390_des_ctx *dctx = ctx; |
| 53 | int ret; | 51 | int ret; |
| 54 | 52 | ||
| 55 | dctx = ctx; | 53 | /* test if key is valid (not a weak key) */ |
| 56 | //test if key is valid (not a weak key) | ||
| 57 | ret = crypto_des_check_key(key, keylen, flags); | 54 | ret = crypto_des_check_key(key, keylen, flags); |
| 58 | if (ret == 0){ | 55 | if (ret == 0) |
| 59 | memcpy(dctx->key, key, keylen); | 56 | memcpy(dctx->key, key, keylen); |
| 60 | } | ||
| 61 | return ret; | 57 | return ret; |
| 62 | } | 58 | } |
| 63 | 59 | ||
| 60 | static void des_encrypt(void *ctx, u8 *out, const u8 *in) | ||
| 61 | { | ||
| 62 | struct crypt_s390_des_ctx *dctx = ctx; | ||
| 63 | |||
| 64 | crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, out, in, DES_BLOCK_SIZE); | ||
| 65 | } | ||
| 66 | |||
| 67 | static void des_decrypt(void *ctx, u8 *out, const u8 *in) | ||
| 68 | { | ||
| 69 | struct crypt_s390_des_ctx *dctx = ctx; | ||
| 70 | |||
| 71 | crypt_s390_km(KM_DEA_DECRYPT, dctx->key, out, in, DES_BLOCK_SIZE); | ||
| 72 | } | ||
| 73 | |||
| 74 | static unsigned int des_encrypt_ecb(const struct cipher_desc *desc, u8 *out, | ||
| 75 | const u8 *in, unsigned int nbytes) | ||
| 76 | { | ||
| 77 | struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm); | ||
| 78 | int ret; | ||
| 79 | |||
| 80 | /* only use complete blocks */ | ||
| 81 | nbytes &= ~(DES_BLOCK_SIZE - 1); | ||
| 82 | ret = crypt_s390_km(KM_DEA_ENCRYPT, sctx->key, out, in, nbytes); | ||
| 83 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 84 | |||
| 85 | return nbytes; | ||
| 86 | } | ||
| 64 | 87 | ||
| 65 | static void | 88 | static unsigned int des_decrypt_ecb(const struct cipher_desc *desc, u8 *out, |
| 66 | des_encrypt(void *ctx, u8 *dst, const u8 *src) | 89 | const u8 *in, unsigned int nbytes) |
| 67 | { | 90 | { |
| 68 | struct crypt_s390_des_ctx *dctx; | 91 | struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm); |
| 92 | int ret; | ||
| 93 | |||
| 94 | /* only use complete blocks */ | ||
| 95 | nbytes &= ~(DES_BLOCK_SIZE - 1); | ||
| 96 | ret = crypt_s390_km(KM_DEA_DECRYPT, sctx->key, out, in, nbytes); | ||
| 97 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 69 | 98 | ||
| 70 | dctx = ctx; | 99 | return nbytes; |
| 71 | crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, dst, src, DES_BLOCK_SIZE); | ||
| 72 | } | 100 | } |
| 73 | 101 | ||
| 74 | static void | 102 | static unsigned int des_encrypt_cbc(const struct cipher_desc *desc, u8 *out, |
| 75 | des_decrypt(void *ctx, u8 *dst, const u8 *src) | 103 | const u8 *in, unsigned int nbytes) |
| 76 | { | 104 | { |
| 77 | struct crypt_s390_des_ctx *dctx; | 105 | struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm); |
| 106 | int ret; | ||
| 78 | 107 | ||
| 79 | dctx = ctx; | 108 | /* only use complete blocks */ |
| 80 | crypt_s390_km(KM_DEA_DECRYPT, dctx->key, dst, src, DES_BLOCK_SIZE); | 109 | nbytes &= ~(DES_BLOCK_SIZE - 1); |
| 110 | |||
| 111 | memcpy(sctx->iv, desc->info, DES_BLOCK_SIZE); | ||
| 112 | ret = crypt_s390_kmc(KMC_DEA_ENCRYPT, &sctx->iv, out, in, nbytes); | ||
| 113 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 114 | |||
| 115 | memcpy(desc->info, sctx->iv, DES_BLOCK_SIZE); | ||
| 116 | return nbytes; | ||
| 117 | } | ||
| 118 | |||
| 119 | static unsigned int des_decrypt_cbc(const struct cipher_desc *desc, u8 *out, | ||
| 120 | const u8 *in, unsigned int nbytes) | ||
| 121 | { | ||
| 122 | struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm); | ||
| 123 | int ret; | ||
| 124 | |||
| 125 | /* only use complete blocks */ | ||
| 126 | nbytes &= ~(DES_BLOCK_SIZE - 1); | ||
| 127 | |||
| 128 | memcpy(&sctx->iv, desc->info, DES_BLOCK_SIZE); | ||
| 129 | ret = crypt_s390_kmc(KMC_DEA_DECRYPT, &sctx->iv, out, in, nbytes); | ||
| 130 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 131 | |||
| 132 | return nbytes; | ||
| 81 | } | 133 | } |
| 82 | 134 | ||
| 83 | static struct crypto_alg des_alg = { | 135 | static struct crypto_alg des_alg = { |
| @@ -87,12 +139,19 @@ static struct crypto_alg des_alg = { | |||
| 87 | .cra_ctxsize = sizeof(struct crypt_s390_des_ctx), | 139 | .cra_ctxsize = sizeof(struct crypt_s390_des_ctx), |
| 88 | .cra_module = THIS_MODULE, | 140 | .cra_module = THIS_MODULE, |
| 89 | .cra_list = LIST_HEAD_INIT(des_alg.cra_list), | 141 | .cra_list = LIST_HEAD_INIT(des_alg.cra_list), |
| 90 | .cra_u = { .cipher = { | 142 | .cra_u = { |
| 91 | .cia_min_keysize = DES_KEY_SIZE, | 143 | .cipher = { |
| 92 | .cia_max_keysize = DES_KEY_SIZE, | 144 | .cia_min_keysize = DES_KEY_SIZE, |
| 93 | .cia_setkey = des_setkey, | 145 | .cia_max_keysize = DES_KEY_SIZE, |
| 94 | .cia_encrypt = des_encrypt, | 146 | .cia_setkey = des_setkey, |
| 95 | .cia_decrypt = des_decrypt } } | 147 | .cia_encrypt = des_encrypt, |
| 148 | .cia_decrypt = des_decrypt, | ||
| 149 | .cia_encrypt_ecb = des_encrypt_ecb, | ||
| 150 | .cia_decrypt_ecb = des_decrypt_ecb, | ||
| 151 | .cia_encrypt_cbc = des_encrypt_cbc, | ||
| 152 | .cia_decrypt_cbc = des_decrypt_cbc, | ||
| 153 | } | ||
| 154 | } | ||
| 96 | }; | 155 | }; |
| 97 | 156 | ||
| 98 | /* | 157 | /* |
| @@ -107,20 +166,18 @@ static struct crypto_alg des_alg = { | |||
| 107 | * Implementers MUST reject keys that exhibit this property. | 166 | * Implementers MUST reject keys that exhibit this property. |
| 108 | * | 167 | * |
| 109 | */ | 168 | */ |
| 110 | static int | 169 | static int des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen, |
| 111 | des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) | 170 | u32 *flags) |
| 112 | { | 171 | { |
| 113 | int i, ret; | 172 | int i, ret; |
| 114 | struct crypt_s390_des3_128_ctx *dctx; | 173 | struct crypt_s390_des3_128_ctx *dctx = ctx; |
| 115 | const u8* temp_key = key; | 174 | const u8* temp_key = key; |
| 116 | 175 | ||
| 117 | dctx = ctx; | ||
| 118 | if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) { | 176 | if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) { |
| 119 | |||
| 120 | *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; | 177 | *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; |
| 121 | return -EINVAL; | 178 | return -EINVAL; |
| 122 | } | 179 | } |
| 123 | for (i = 0; i < 2; i++, temp_key += DES_KEY_SIZE) { | 180 | for (i = 0; i < 2; i++, temp_key += DES_KEY_SIZE) { |
| 124 | ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags); | 181 | ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags); |
| 125 | if (ret < 0) | 182 | if (ret < 0) |
| 126 | return ret; | 183 | return ret; |
| @@ -129,24 +186,85 @@ des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) | |||
| 129 | return 0; | 186 | return 0; |
| 130 | } | 187 | } |
| 131 | 188 | ||
| 132 | static void | 189 | static void des3_128_encrypt(void *ctx, u8 *dst, const u8 *src) |
| 133 | des3_128_encrypt(void *ctx, u8 *dst, const u8 *src) | ||
| 134 | { | 190 | { |
| 135 | struct crypt_s390_des3_128_ctx *dctx; | 191 | struct crypt_s390_des3_128_ctx *dctx = ctx; |
| 136 | 192 | ||
| 137 | dctx = ctx; | ||
| 138 | crypt_s390_km(KM_TDEA_128_ENCRYPT, dctx->key, dst, (void*)src, | 193 | crypt_s390_km(KM_TDEA_128_ENCRYPT, dctx->key, dst, (void*)src, |
| 139 | DES3_128_BLOCK_SIZE); | 194 | DES3_128_BLOCK_SIZE); |
| 140 | } | 195 | } |
| 141 | 196 | ||
| 142 | static void | 197 | static void des3_128_decrypt(void *ctx, u8 *dst, const u8 *src) |
| 143 | des3_128_decrypt(void *ctx, u8 *dst, const u8 *src) | ||
| 144 | { | 198 | { |
| 145 | struct crypt_s390_des3_128_ctx *dctx; | 199 | struct crypt_s390_des3_128_ctx *dctx = ctx; |
| 146 | 200 | ||
| 147 | dctx = ctx; | ||
| 148 | crypt_s390_km(KM_TDEA_128_DECRYPT, dctx->key, dst, (void*)src, | 201 | crypt_s390_km(KM_TDEA_128_DECRYPT, dctx->key, dst, (void*)src, |
| 149 | DES3_128_BLOCK_SIZE); | 202 | DES3_128_BLOCK_SIZE); |
| 203 | } | ||
| 204 | |||
| 205 | static unsigned int des3_128_encrypt_ecb(const struct cipher_desc *desc, | ||
| 206 | u8 *out, const u8 *in, | ||
| 207 | unsigned int nbytes) | ||
| 208 | { | ||
| 209 | struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm); | ||
| 210 | int ret; | ||
| 211 | |||
| 212 | /* only use complete blocks */ | ||
| 213 | nbytes &= ~(DES3_128_BLOCK_SIZE - 1); | ||
| 214 | ret = crypt_s390_km(KM_TDEA_128_ENCRYPT, sctx->key, out, in, nbytes); | ||
| 215 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 216 | |||
| 217 | return nbytes; | ||
| 218 | } | ||
| 219 | |||
| 220 | static unsigned int des3_128_decrypt_ecb(const struct cipher_desc *desc, | ||
| 221 | u8 *out, const u8 *in, | ||
| 222 | unsigned int nbytes) | ||
| 223 | { | ||
| 224 | struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm); | ||
| 225 | int ret; | ||
| 226 | |||
| 227 | /* only use complete blocks */ | ||
| 228 | nbytes &= ~(DES3_128_BLOCK_SIZE - 1); | ||
| 229 | ret = crypt_s390_km(KM_TDEA_128_DECRYPT, sctx->key, out, in, nbytes); | ||
| 230 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 231 | |||
| 232 | return nbytes; | ||
| 233 | } | ||
| 234 | |||
| 235 | static unsigned int des3_128_encrypt_cbc(const struct cipher_desc *desc, | ||
| 236 | u8 *out, const u8 *in, | ||
| 237 | unsigned int nbytes) | ||
| 238 | { | ||
| 239 | struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm); | ||
| 240 | int ret; | ||
| 241 | |||
| 242 | /* only use complete blocks */ | ||
| 243 | nbytes &= ~(DES3_128_BLOCK_SIZE - 1); | ||
| 244 | |||
| 245 | memcpy(sctx->iv, desc->info, DES3_128_BLOCK_SIZE); | ||
| 246 | ret = crypt_s390_kmc(KMC_TDEA_128_ENCRYPT, &sctx->iv, out, in, nbytes); | ||
| 247 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 248 | |||
| 249 | memcpy(desc->info, sctx->iv, DES3_128_BLOCK_SIZE); | ||
| 250 | return nbytes; | ||
| 251 | } | ||
| 252 | |||
| 253 | static unsigned int des3_128_decrypt_cbc(const struct cipher_desc *desc, | ||
| 254 | u8 *out, const u8 *in, | ||
| 255 | unsigned int nbytes) | ||
| 256 | { | ||
| 257 | struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm); | ||
| 258 | int ret; | ||
| 259 | |||
| 260 | /* only use complete blocks */ | ||
| 261 | nbytes &= ~(DES3_128_BLOCK_SIZE - 1); | ||
| 262 | |||
| 263 | memcpy(&sctx->iv, desc->info, DES3_128_BLOCK_SIZE); | ||
| 264 | ret = crypt_s390_kmc(KMC_TDEA_128_DECRYPT, &sctx->iv, out, in, nbytes); | ||
| 265 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 266 | |||
| 267 | return nbytes; | ||
| 150 | } | 268 | } |
| 151 | 269 | ||
| 152 | static struct crypto_alg des3_128_alg = { | 270 | static struct crypto_alg des3_128_alg = { |
| @@ -156,12 +274,19 @@ static struct crypto_alg des3_128_alg = { | |||
| 156 | .cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx), | 274 | .cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx), |
| 157 | .cra_module = THIS_MODULE, | 275 | .cra_module = THIS_MODULE, |
| 158 | .cra_list = LIST_HEAD_INIT(des3_128_alg.cra_list), | 276 | .cra_list = LIST_HEAD_INIT(des3_128_alg.cra_list), |
| 159 | .cra_u = { .cipher = { | 277 | .cra_u = { |
| 160 | .cia_min_keysize = DES3_128_KEY_SIZE, | 278 | .cipher = { |
| 161 | .cia_max_keysize = DES3_128_KEY_SIZE, | 279 | .cia_min_keysize = DES3_128_KEY_SIZE, |
| 162 | .cia_setkey = des3_128_setkey, | 280 | .cia_max_keysize = DES3_128_KEY_SIZE, |
| 163 | .cia_encrypt = des3_128_encrypt, | 281 | .cia_setkey = des3_128_setkey, |
| 164 | .cia_decrypt = des3_128_decrypt } } | 282 | .cia_encrypt = des3_128_encrypt, |
| 283 | .cia_decrypt = des3_128_decrypt, | ||
| 284 | .cia_encrypt_ecb = des3_128_encrypt_ecb, | ||
| 285 | .cia_decrypt_ecb = des3_128_decrypt_ecb, | ||
| 286 | .cia_encrypt_cbc = des3_128_encrypt_cbc, | ||
| 287 | .cia_decrypt_cbc = des3_128_decrypt_cbc, | ||
| 288 | } | ||
| 289 | } | ||
| 165 | }; | 290 | }; |
| 166 | 291 | ||
| 167 | /* | 292 | /* |
| @@ -177,50 +302,108 @@ static struct crypto_alg des3_128_alg = { | |||
| 177 | * property. | 302 | * property. |
| 178 | * | 303 | * |
| 179 | */ | 304 | */ |
| 180 | static int | 305 | static int des3_192_setkey(void *ctx, const u8 *key, unsigned int keylen, |
| 181 | des3_192_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) | 306 | u32 *flags) |
| 182 | { | 307 | { |
| 183 | int i, ret; | 308 | int i, ret; |
| 184 | struct crypt_s390_des3_192_ctx *dctx; | 309 | struct crypt_s390_des3_192_ctx *dctx = ctx; |
| 185 | const u8* temp_key; | 310 | const u8* temp_key = key; |
| 186 | 311 | ||
| 187 | dctx = ctx; | ||
| 188 | temp_key = key; | ||
| 189 | if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && | 312 | if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && |
| 190 | memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2], | 313 | memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2], |
| 191 | DES_KEY_SIZE))) { | 314 | DES_KEY_SIZE))) { |
| 192 | 315 | ||
| 193 | *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; | 316 | *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; |
| 194 | return -EINVAL; | 317 | return -EINVAL; |
| 195 | } | 318 | } |
| 196 | for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) { | 319 | for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) { |
| 197 | ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags); | 320 | ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags); |
| 198 | if (ret < 0){ | 321 | if (ret < 0) |
| 199 | return ret; | 322 | return ret; |
| 200 | } | ||
| 201 | } | 323 | } |
| 202 | memcpy(dctx->key, key, keylen); | 324 | memcpy(dctx->key, key, keylen); |
| 203 | return 0; | 325 | return 0; |
| 204 | } | 326 | } |
| 205 | 327 | ||
| 206 | static void | 328 | static void des3_192_encrypt(void *ctx, u8 *dst, const u8 *src) |
| 207 | des3_192_encrypt(void *ctx, u8 *dst, const u8 *src) | ||
| 208 | { | 329 | { |
| 209 | struct crypt_s390_des3_192_ctx *dctx; | 330 | struct crypt_s390_des3_192_ctx *dctx = ctx; |
| 210 | 331 | ||
| 211 | dctx = ctx; | ||
| 212 | crypt_s390_km(KM_TDEA_192_ENCRYPT, dctx->key, dst, (void*)src, | 332 | crypt_s390_km(KM_TDEA_192_ENCRYPT, dctx->key, dst, (void*)src, |
| 213 | DES3_192_BLOCK_SIZE); | 333 | DES3_192_BLOCK_SIZE); |
| 214 | } | 334 | } |
| 215 | 335 | ||
| 216 | static void | 336 | static void des3_192_decrypt(void *ctx, u8 *dst, const u8 *src) |
| 217 | des3_192_decrypt(void *ctx, u8 *dst, const u8 *src) | ||
| 218 | { | 337 | { |
| 219 | struct crypt_s390_des3_192_ctx *dctx; | 338 | struct crypt_s390_des3_192_ctx *dctx = ctx; |
| 220 | 339 | ||
| 221 | dctx = ctx; | ||
| 222 | crypt_s390_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src, | 340 | crypt_s390_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src, |
| 223 | DES3_192_BLOCK_SIZE); | 341 | DES3_192_BLOCK_SIZE); |
| 342 | } | ||
| 343 | |||
| 344 | static unsigned int des3_192_encrypt_ecb(const struct cipher_desc *desc, | ||
| 345 | u8 *out, const u8 *in, | ||
| 346 | unsigned int nbytes) | ||
| 347 | { | ||
| 348 | struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm); | ||
| 349 | int ret; | ||
| 350 | |||
| 351 | /* only use complete blocks */ | ||
| 352 | nbytes &= ~(DES3_192_BLOCK_SIZE - 1); | ||
| 353 | ret = crypt_s390_km(KM_TDEA_192_ENCRYPT, sctx->key, out, in, nbytes); | ||
| 354 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 355 | |||
| 356 | return nbytes; | ||
| 357 | } | ||
| 358 | |||
| 359 | static unsigned int des3_192_decrypt_ecb(const struct cipher_desc *desc, | ||
| 360 | u8 *out, const u8 *in, | ||
| 361 | unsigned int nbytes) | ||
| 362 | { | ||
| 363 | struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm); | ||
| 364 | int ret; | ||
| 365 | |||
| 366 | /* only use complete blocks */ | ||
| 367 | nbytes &= ~(DES3_192_BLOCK_SIZE - 1); | ||
| 368 | ret = crypt_s390_km(KM_TDEA_192_DECRYPT, sctx->key, out, in, nbytes); | ||
| 369 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 370 | |||
| 371 | return nbytes; | ||
| 372 | } | ||
| 373 | |||
| 374 | static unsigned int des3_192_encrypt_cbc(const struct cipher_desc *desc, | ||
| 375 | u8 *out, const u8 *in, | ||
| 376 | unsigned int nbytes) | ||
| 377 | { | ||
| 378 | struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm); | ||
| 379 | int ret; | ||
| 380 | |||
| 381 | /* only use complete blocks */ | ||
| 382 | nbytes &= ~(DES3_192_BLOCK_SIZE - 1); | ||
| 383 | |||
| 384 | memcpy(sctx->iv, desc->info, DES3_192_BLOCK_SIZE); | ||
| 385 | ret = crypt_s390_kmc(KMC_TDEA_192_ENCRYPT, &sctx->iv, out, in, nbytes); | ||
| 386 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 387 | |||
| 388 | memcpy(desc->info, sctx->iv, DES3_192_BLOCK_SIZE); | ||
| 389 | return nbytes; | ||
| 390 | } | ||
| 391 | |||
| 392 | static unsigned int des3_192_decrypt_cbc(const struct cipher_desc *desc, | ||
| 393 | u8 *out, const u8 *in, | ||
| 394 | unsigned int nbytes) | ||
| 395 | { | ||
| 396 | struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm); | ||
| 397 | int ret; | ||
| 398 | |||
| 399 | /* only use complete blocks */ | ||
| 400 | nbytes &= ~(DES3_192_BLOCK_SIZE - 1); | ||
| 401 | |||
| 402 | memcpy(&sctx->iv, desc->info, DES3_192_BLOCK_SIZE); | ||
| 403 | ret = crypt_s390_kmc(KMC_TDEA_192_DECRYPT, &sctx->iv, out, in, nbytes); | ||
| 404 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
| 405 | |||
| 406 | return nbytes; | ||
| 224 | } | 407 | } |
| 225 | 408 | ||
| 226 | static struct crypto_alg des3_192_alg = { | 409 | static struct crypto_alg des3_192_alg = { |
| @@ -230,44 +413,43 @@ static struct crypto_alg des3_192_alg = { | |||
| 230 | .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx), | 413 | .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx), |
| 231 | .cra_module = THIS_MODULE, | 414 | .cra_module = THIS_MODULE, |
| 232 | .cra_list = LIST_HEAD_INIT(des3_192_alg.cra_list), | 415 | .cra_list = LIST_HEAD_INIT(des3_192_alg.cra_list), |
| 233 | .cra_u = { .cipher = { | 416 | .cra_u = { |
| 234 | .cia_min_keysize = DES3_192_KEY_SIZE, | 417 | .cipher = { |
| 235 | .cia_max_keysize = DES3_192_KEY_SIZE, | 418 | .cia_min_keysize = DES3_192_KEY_SIZE, |
| 236 | .cia_setkey = des3_192_setkey, | 419 | .cia_max_keysize = DES3_192_KEY_SIZE, |
| 237 | .cia_encrypt = des3_192_encrypt, | 420 | .cia_setkey = des3_192_setkey, |
| 238 | .cia_decrypt = des3_192_decrypt } } | 421 | .cia_encrypt = des3_192_encrypt, |
| 422 | .cia_decrypt = des3_192_decrypt, | ||
| 423 | .cia_encrypt_ecb = des3_192_encrypt_ecb, | ||
| 424 | .cia_decrypt_ecb = des3_192_decrypt_ecb, | ||
| 425 | .cia_encrypt_cbc = des3_192_encrypt_cbc, | ||
| 426 | .cia_decrypt_cbc = des3_192_decrypt_cbc, | ||
| 427 | } | ||
| 428 | } | ||
| 239 | }; | 429 | }; |
| 240 | 430 | ||
| 241 | 431 | static int init(void) | |
| 242 | |||
| 243 | static int | ||
| 244 | init(void) | ||
| 245 | { | 432 | { |
| 246 | int ret; | 433 | int ret = 0; |
| 247 | 434 | ||
| 248 | if (!crypt_s390_func_available(KM_DEA_ENCRYPT) || | 435 | if (!crypt_s390_func_available(KM_DEA_ENCRYPT) || |
| 249 | !crypt_s390_func_available(KM_TDEA_128_ENCRYPT) || | 436 | !crypt_s390_func_available(KM_TDEA_128_ENCRYPT) || |
| 250 | !crypt_s390_func_available(KM_TDEA_192_ENCRYPT)){ | 437 | !crypt_s390_func_available(KM_TDEA_192_ENCRYPT)) |
| 251 | return -ENOSYS; | 438 | return -ENOSYS; |
| 252 | } | ||
| 253 | 439 | ||
| 254 | ret = 0; | 440 | ret |= (crypto_register_alg(&des_alg) == 0) ? 0:1; |
| 255 | ret |= (crypto_register_alg(&des_alg) == 0)? 0:1; | 441 | ret |= (crypto_register_alg(&des3_128_alg) == 0) ? 0:2; |
| 256 | ret |= (crypto_register_alg(&des3_128_alg) == 0)? 0:2; | 442 | ret |= (crypto_register_alg(&des3_192_alg) == 0) ? 0:4; |
| 257 | ret |= (crypto_register_alg(&des3_192_alg) == 0)? 0:4; | 443 | if (ret) { |
| 258 | if (ret){ | ||
| 259 | crypto_unregister_alg(&des3_192_alg); | 444 | crypto_unregister_alg(&des3_192_alg); |
| 260 | crypto_unregister_alg(&des3_128_alg); | 445 | crypto_unregister_alg(&des3_128_alg); |
| 261 | crypto_unregister_alg(&des_alg); | 446 | crypto_unregister_alg(&des_alg); |
| 262 | return -EEXIST; | 447 | return -EEXIST; |
| 263 | } | 448 | } |
| 264 | |||
| 265 | printk(KERN_INFO "crypt_s390: des_s390 loaded.\n"); | ||
| 266 | return 0; | 449 | return 0; |
| 267 | } | 450 | } |
| 268 | 451 | ||
| 269 | static void __exit | 452 | static void __exit fini(void) |
| 270 | fini(void) | ||
| 271 | { | 453 | { |
| 272 | crypto_unregister_alg(&des3_192_alg); | 454 | crypto_unregister_alg(&des3_192_alg); |
| 273 | crypto_unregister_alg(&des3_128_alg); | 455 | crypto_unregister_alg(&des3_128_alg); |
diff --git a/arch/s390/crypto/sha256_s390.c b/arch/s390/crypto/sha256_s390.c index b75bdbd476c7..1ec5e92b3454 100644 --- a/arch/s390/crypto/sha256_s390.c +++ b/arch/s390/crypto/sha256_s390.c | |||
| @@ -51,6 +51,7 @@ static void sha256_update(void *ctx, const u8 *data, unsigned int len) | |||
| 51 | { | 51 | { |
| 52 | struct s390_sha256_ctx *sctx = ctx; | 52 | struct s390_sha256_ctx *sctx = ctx; |
| 53 | unsigned int index; | 53 | unsigned int index; |
| 54 | int ret; | ||
| 54 | 55 | ||
| 55 | /* how much is already in the buffer? */ | 56 | /* how much is already in the buffer? */ |
| 56 | index = sctx->count / 8 & 0x3f; | 57 | index = sctx->count / 8 & 0x3f; |
| @@ -58,15 +59,29 @@ static void sha256_update(void *ctx, const u8 *data, unsigned int len) | |||
| 58 | /* update message bit length */ | 59 | /* update message bit length */ |
| 59 | sctx->count += len * 8; | 60 | sctx->count += len * 8; |
| 60 | 61 | ||
| 61 | /* process one block */ | 62 | if ((index + len) < SHA256_BLOCK_SIZE) |
| 62 | if ((index + len) >= SHA256_BLOCK_SIZE) { | 63 | goto store; |
| 64 | |||
| 65 | /* process one stored block */ | ||
| 66 | if (index) { | ||
| 63 | memcpy(sctx->buf + index, data, SHA256_BLOCK_SIZE - index); | 67 | memcpy(sctx->buf + index, data, SHA256_BLOCK_SIZE - index); |
| 64 | crypt_s390_kimd(KIMD_SHA_256, sctx->state, sctx->buf, | 68 | ret = crypt_s390_kimd(KIMD_SHA_256, sctx->state, sctx->buf, |
| 65 | SHA256_BLOCK_SIZE); | 69 | SHA256_BLOCK_SIZE); |
| 70 | BUG_ON(ret != SHA256_BLOCK_SIZE); | ||
| 66 | data += SHA256_BLOCK_SIZE - index; | 71 | data += SHA256_BLOCK_SIZE - index; |
| 67 | len -= SHA256_BLOCK_SIZE - index; | 72 | len -= SHA256_BLOCK_SIZE - index; |
| 68 | } | 73 | } |
| 69 | 74 | ||
| 75 | /* process as many blocks as possible */ | ||
| 76 | if (len >= SHA256_BLOCK_SIZE) { | ||
| 77 | ret = crypt_s390_kimd(KIMD_SHA_256, sctx->state, data, | ||
| 78 | len & ~(SHA256_BLOCK_SIZE - 1)); | ||
| 79 | BUG_ON(ret != (len & ~(SHA256_BLOCK_SIZE - 1))); | ||
| 80 | data += ret; | ||
| 81 | len -= ret; | ||
| 82 | } | ||
| 83 | |||
| 84 | store: | ||
| 70 | /* anything left? */ | 85 | /* anything left? */ |
| 71 | if (len) | 86 | if (len) |
| 72 | memcpy(sctx->buf + index , data, len); | 87 | memcpy(sctx->buf + index , data, len); |
| @@ -119,9 +134,9 @@ static struct crypto_alg alg = { | |||
| 119 | .cra_list = LIST_HEAD_INIT(alg.cra_list), | 134 | .cra_list = LIST_HEAD_INIT(alg.cra_list), |
| 120 | .cra_u = { .digest = { | 135 | .cra_u = { .digest = { |
| 121 | .dia_digestsize = SHA256_DIGEST_SIZE, | 136 | .dia_digestsize = SHA256_DIGEST_SIZE, |
| 122 | .dia_init = sha256_init, | 137 | .dia_init = sha256_init, |
| 123 | .dia_update = sha256_update, | 138 | .dia_update = sha256_update, |
| 124 | .dia_final = sha256_final } } | 139 | .dia_final = sha256_final } } |
| 125 | }; | 140 | }; |
| 126 | 141 | ||
| 127 | static int init(void) | 142 | static int init(void) |
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 2ff90a1a1056..008c74526fd3 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
| @@ -58,10 +58,18 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); | |||
| 58 | */ | 58 | */ |
| 59 | unsigned long thread_saved_pc(struct task_struct *tsk) | 59 | unsigned long thread_saved_pc(struct task_struct *tsk) |
| 60 | { | 60 | { |
| 61 | struct stack_frame *sf; | 61 | struct stack_frame *sf, *low, *high; |
| 62 | 62 | ||
| 63 | sf = (struct stack_frame *) tsk->thread.ksp; | 63 | if (!tsk || !task_stack_page(tsk)) |
| 64 | sf = (struct stack_frame *) sf->back_chain; | 64 | return 0; |
| 65 | low = task_stack_page(tsk); | ||
| 66 | high = (struct stack_frame *) task_pt_regs(tsk); | ||
| 67 | sf = (struct stack_frame *) (tsk->thread.ksp & PSW_ADDR_INSN); | ||
| 68 | if (sf <= low || sf > high) | ||
| 69 | return 0; | ||
| 70 | sf = (struct stack_frame *) (sf->back_chain & PSW_ADDR_INSN); | ||
| 71 | if (sf <= low || sf > high) | ||
| 72 | return 0; | ||
| 65 | return sf->gprs[8]; | 73 | return sf->gprs[8]; |
| 66 | } | 74 | } |
| 67 | 75 | ||
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index b03847d100d9..de8784267473 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
| @@ -268,7 +268,7 @@ static void do_machine_restart_nonsmp(char * __unused) | |||
| 268 | reipl_diag(); | 268 | reipl_diag(); |
| 269 | 269 | ||
| 270 | if (MACHINE_IS_VM) | 270 | if (MACHINE_IS_VM) |
| 271 | cpcmd ("IPL", NULL, 0); | 271 | cpcmd ("IPL", NULL, 0, NULL); |
| 272 | else | 272 | else |
| 273 | reipl (0x10000 | S390_lowcore.ipl_device); | 273 | reipl (0x10000 | S390_lowcore.ipl_device); |
| 274 | } | 274 | } |
| @@ -276,14 +276,14 @@ static void do_machine_restart_nonsmp(char * __unused) | |||
| 276 | static void do_machine_halt_nonsmp(void) | 276 | static void do_machine_halt_nonsmp(void) |
| 277 | { | 277 | { |
| 278 | if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) | 278 | if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) |
| 279 | cpcmd(vmhalt_cmd, NULL, 0); | 279 | cpcmd(vmhalt_cmd, NULL, 0, NULL); |
| 280 | signal_processor(smp_processor_id(), sigp_stop_and_store_status); | 280 | signal_processor(smp_processor_id(), sigp_stop_and_store_status); |
| 281 | } | 281 | } |
| 282 | 282 | ||
| 283 | static void do_machine_power_off_nonsmp(void) | 283 | static void do_machine_power_off_nonsmp(void) |
| 284 | { | 284 | { |
| 285 | if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0) | 285 | if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0) |
| 286 | cpcmd(vmpoff_cmd, NULL, 0); | 286 | cpcmd(vmpoff_cmd, NULL, 0, NULL); |
| 287 | signal_processor(smp_processor_id(), sigp_stop_and_store_status); | 287 | signal_processor(smp_processor_id(), sigp_stop_and_store_status); |
| 288 | } | 288 | } |
| 289 | 289 | ||
| @@ -315,6 +315,11 @@ void machine_power_off(void) | |||
| 315 | _machine_power_off(); | 315 | _machine_power_off(); |
| 316 | } | 316 | } |
| 317 | 317 | ||
| 318 | /* | ||
| 319 | * Dummy power off function. | ||
| 320 | */ | ||
| 321 | void (*pm_power_off)(void) = machine_power_off; | ||
| 322 | |||
| 318 | static void __init | 323 | static void __init |
| 319 | add_memory_hole(unsigned long start, unsigned long end) | 324 | add_memory_hole(unsigned long start, unsigned long end) |
| 320 | { | 325 | { |
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index b0d8ca8e5eeb..7c0fe152a111 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
| @@ -214,7 +214,7 @@ void account_ticks(struct pt_regs *regs) | |||
| 214 | #endif | 214 | #endif |
| 215 | 215 | ||
| 216 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 216 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
| 217 | account_user_vtime(current); | 217 | account_tick_vtime(current); |
| 218 | #else | 218 | #else |
| 219 | while (ticks--) | 219 | while (ticks--) |
| 220 | update_process_times(user_mode(regs)); | 220 | update_process_times(user_mode(regs)); |
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 22a895ecb7a4..dfe6f0856617 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c | |||
| @@ -32,7 +32,7 @@ DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer); | |||
| 32 | * Update process times based on virtual cpu times stored by entry.S | 32 | * Update process times based on virtual cpu times stored by entry.S |
| 33 | * to the lowcore fields user_timer, system_timer & steal_clock. | 33 | * to the lowcore fields user_timer, system_timer & steal_clock. |
| 34 | */ | 34 | */ |
| 35 | void account_user_vtime(struct task_struct *tsk) | 35 | void account_tick_vtime(struct task_struct *tsk) |
| 36 | { | 36 | { |
| 37 | cputime_t cputime; | 37 | cputime_t cputime; |
| 38 | __u64 timer, clock; | 38 | __u64 timer, clock; |
| @@ -76,6 +76,31 @@ void account_user_vtime(struct task_struct *tsk) | |||
| 76 | * Update process times based on virtual cpu times stored by entry.S | 76 | * Update process times based on virtual cpu times stored by entry.S |
| 77 | * to the lowcore fields user_timer, system_timer & steal_clock. | 77 | * to the lowcore fields user_timer, system_timer & steal_clock. |
| 78 | */ | 78 | */ |
| 79 | void account_vtime(struct task_struct *tsk) | ||
| 80 | { | ||
| 81 | cputime_t cputime; | ||
| 82 | __u64 timer; | ||
| 83 | |||
| 84 | timer = S390_lowcore.last_update_timer; | ||
| 85 | asm volatile (" STPT %0" /* Store current cpu timer value */ | ||
| 86 | : "=m" (S390_lowcore.last_update_timer) ); | ||
| 87 | S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer; | ||
| 88 | |||
| 89 | cputime = S390_lowcore.user_timer >> 12; | ||
| 90 | S390_lowcore.user_timer -= cputime << 12; | ||
| 91 | S390_lowcore.steal_clock -= cputime << 12; | ||
| 92 | account_user_time(tsk, cputime); | ||
| 93 | |||
| 94 | cputime = S390_lowcore.system_timer >> 12; | ||
| 95 | S390_lowcore.system_timer -= cputime << 12; | ||
| 96 | S390_lowcore.steal_clock -= cputime << 12; | ||
| 97 | account_system_time(tsk, 0, cputime); | ||
| 98 | } | ||
| 99 | |||
| 100 | /* | ||
| 101 | * Update process times based on virtual cpu times stored by entry.S | ||
| 102 | * to the lowcore fields user_timer, system_timer & steal_clock. | ||
| 103 | */ | ||
| 79 | void account_system_vtime(struct task_struct *tsk) | 104 | void account_system_vtime(struct task_struct *tsk) |
| 80 | { | 105 | { |
| 81 | cputime_t cputime; | 106 | cputime_t cputime; |
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile index d9b97b3c597f..f20b51ff1d86 100644 --- a/arch/s390/lib/Makefile +++ b/arch/s390/lib/Makefile | |||
| @@ -4,5 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | EXTRA_AFLAGS := -traditional | 5 | EXTRA_AFLAGS := -traditional |
| 6 | 6 | ||
| 7 | lib-y += delay.o string.o spinlock.o | 7 | lib-y += delay.o string.o |
| 8 | lib-y += $(if $(CONFIG_64BIT),uaccess64.o,uaccess.o) | 8 | lib-y += $(if $(CONFIG_64BIT),uaccess64.o,uaccess.o) |
| 9 | lib-$(CONFIG_SMP) += spinlock.o \ No newline at end of file | ||
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index 68d79c502081..60f80a4eed4e 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <asm/io.h> | 14 | #include <asm/io.h> |
| 15 | 15 | ||
| 16 | atomic_t spin_retry_counter; | ||
| 17 | int spin_retry = 1000; | 16 | int spin_retry = 1000; |
| 18 | 17 | ||
| 19 | /** | 18 | /** |
| @@ -45,7 +44,6 @@ _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc) | |||
| 45 | _diag44(); | 44 | _diag44(); |
| 46 | count = spin_retry; | 45 | count = spin_retry; |
| 47 | } | 46 | } |
| 48 | atomic_inc(&spin_retry_counter); | ||
| 49 | if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0) | 47 | if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0) |
| 50 | return; | 48 | return; |
| 51 | } | 49 | } |
| @@ -58,7 +56,6 @@ _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc) | |||
| 58 | int count = spin_retry; | 56 | int count = spin_retry; |
| 59 | 57 | ||
| 60 | while (count-- > 0) { | 58 | while (count-- > 0) { |
| 61 | atomic_inc(&spin_retry_counter); | ||
| 62 | if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0) | 59 | if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0) |
| 63 | return 1; | 60 | return 1; |
| 64 | } | 61 | } |
| @@ -77,7 +74,6 @@ _raw_read_lock_wait(raw_rwlock_t *rw) | |||
| 77 | _diag44(); | 74 | _diag44(); |
| 78 | count = spin_retry; | 75 | count = spin_retry; |
| 79 | } | 76 | } |
| 80 | atomic_inc(&spin_retry_counter); | ||
| 81 | old = rw->lock & 0x7fffffffU; | 77 | old = rw->lock & 0x7fffffffU; |
| 82 | if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old) | 78 | if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old) |
| 83 | return; | 79 | return; |
| @@ -92,7 +88,6 @@ _raw_read_trylock_retry(raw_rwlock_t *rw) | |||
| 92 | int count = spin_retry; | 88 | int count = spin_retry; |
| 93 | 89 | ||
| 94 | while (count-- > 0) { | 90 | while (count-- > 0) { |
| 95 | atomic_inc(&spin_retry_counter); | ||
| 96 | old = rw->lock & 0x7fffffffU; | 91 | old = rw->lock & 0x7fffffffU; |
| 97 | if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old) | 92 | if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old) |
| 98 | return 1; | 93 | return 1; |
| @@ -111,7 +106,6 @@ _raw_write_lock_wait(raw_rwlock_t *rw) | |||
| 111 | _diag44(); | 106 | _diag44(); |
| 112 | count = spin_retry; | 107 | count = spin_retry; |
| 113 | } | 108 | } |
| 114 | atomic_inc(&spin_retry_counter); | ||
| 115 | if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0) | 109 | if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0) |
| 116 | return; | 110 | return; |
| 117 | } | 111 | } |
| @@ -124,7 +118,6 @@ _raw_write_trylock_retry(raw_rwlock_t *rw) | |||
| 124 | int count = spin_retry; | 118 | int count = spin_retry; |
| 125 | 119 | ||
| 126 | while (count-- > 0) { | 120 | while (count-- > 0) { |
| 127 | atomic_inc(&spin_retry_counter); | ||
| 128 | if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0) | 121 | if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0) |
| 129 | return 1; | 122 | return 1; |
| 130 | } | 123 | } |
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 8cf6d437a630..01bc7d589afe 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
| @@ -33,9 +33,11 @@ config GENERIC_CALIBRATE_DELAY | |||
| 33 | bool | 33 | bool |
| 34 | default y | 34 | default y |
| 35 | 35 | ||
| 36 | config GENERIC_IOMAP | ||
| 37 | bool | ||
| 38 | |||
| 36 | config ARCH_MAY_HAVE_PC_FDC | 39 | config ARCH_MAY_HAVE_PC_FDC |
| 37 | bool | 40 | bool |
| 38 | default y | ||
| 39 | 41 | ||
| 40 | source "init/Kconfig" | 42 | source "init/Kconfig" |
| 41 | 43 | ||
| @@ -53,24 +55,28 @@ config SH_SOLUTION_ENGINE | |||
| 53 | 55 | ||
| 54 | config SH_7751_SOLUTION_ENGINE | 56 | config SH_7751_SOLUTION_ENGINE |
| 55 | bool "SolutionEngine7751" | 57 | bool "SolutionEngine7751" |
| 58 | select CPU_SUBTYPE_SH7751 | ||
| 56 | help | 59 | help |
| 57 | Select 7751 SolutionEngine if configuring for a Hitachi SH7751 | 60 | Select 7751 SolutionEngine if configuring for a Hitachi SH7751 |
| 58 | evaluation board. | 61 | evaluation board. |
| 59 | 62 | ||
| 60 | config SH_7300_SOLUTION_ENGINE | 63 | config SH_7300_SOLUTION_ENGINE |
| 61 | bool "SolutionEngine7300" | 64 | bool "SolutionEngine7300" |
| 65 | select CPU_SUBTYPE_SH7300 | ||
| 62 | help | 66 | help |
| 63 | Select 7300 SolutionEngine if configuring for a Hitachi SH7300(SH-Mobile V) | 67 | Select 7300 SolutionEngine if configuring for a Hitachi SH7300(SH-Mobile V) |
| 64 | evaluation board. | 68 | evaluation board. |
| 65 | 69 | ||
| 66 | config SH_73180_SOLUTION_ENGINE | 70 | config SH_73180_SOLUTION_ENGINE |
| 67 | bool "SolutionEngine73180" | 71 | bool "SolutionEngine73180" |
| 72 | select CPU_SUBTYPE_SH73180 | ||
| 68 | help | 73 | help |
| 69 | Select 73180 SolutionEngine if configuring for a Hitachi SH73180(SH-Mobile 3) | 74 | Select 73180 SolutionEngine if configuring for a Hitachi SH73180(SH-Mobile 3) |
| 70 | evaluation board. | 75 | evaluation board. |
| 71 | 76 | ||
| 72 | config SH_7751_SYSTEMH | 77 | config SH_7751_SYSTEMH |
| 73 | bool "SystemH7751R" | 78 | bool "SystemH7751R" |
| 79 | select CPU_SUBTYPE_SH7751R | ||
| 74 | help | 80 | help |
| 75 | Select SystemH if you are configuring for a Renesas SystemH | 81 | Select SystemH if you are configuring for a Renesas SystemH |
| 76 | 7751R evaluation board. | 82 | 7751R evaluation board. |
| @@ -81,27 +87,13 @@ config SH_STB1_HARP | |||
| 81 | config SH_STB1_OVERDRIVE | 87 | config SH_STB1_OVERDRIVE |
| 82 | bool "STB1_Overdrive" | 88 | bool "STB1_Overdrive" |
| 83 | 89 | ||
| 84 | config SH_HP620 | 90 | config SH_HP6XX |
| 85 | bool "HP620" | 91 | bool "HP6XX" |
| 86 | help | 92 | help |
| 87 | Select HP620 if configuring for a HP jornada HP620. | 93 | Select HP6XX if configuring for a HP jornada HP6xx. |
| 88 | More information (hardware only) at | 94 | More information (hardware only) at |
| 89 | <http://www.hp.com/jornada/>. | 95 | <http://www.hp.com/jornada/>. |
| 90 | 96 | ||
| 91 | config SH_HP680 | ||
| 92 | bool "HP680" | ||
| 93 | help | ||
| 94 | Select HP680 if configuring for a HP Jornada HP680. | ||
| 95 | More information (hardware only) at | ||
| 96 | <http://www.hp.com/jornada/products/680/>. | ||
| 97 | |||
| 98 | config SH_HP690 | ||
| 99 | bool "HP690" | ||
| 100 | help | ||
| 101 | Select HP690 if configuring for a HP Jornada HP690. | ||
| 102 | More information (hardware only) | ||
| 103 | at <http://www.hp.com/jornada/products/680/>. | ||
| 104 | |||
| 105 | config SH_CQREEK | 97 | config SH_CQREEK |
| 106 | bool "CqREEK" | 98 | bool "CqREEK" |
| 107 | help | 99 | help |
| @@ -123,11 +115,13 @@ config SH_EC3104 | |||
| 123 | 115 | ||
| 124 | config SH_SATURN | 116 | config SH_SATURN |
| 125 | bool "Saturn" | 117 | bool "Saturn" |
| 118 | select CPU_SUBTYPE_SH7604 | ||
| 126 | help | 119 | help |
| 127 | Select Saturn if configuring for a SEGA Saturn. | 120 | Select Saturn if configuring for a SEGA Saturn. |
| 128 | 121 | ||
| 129 | config SH_DREAMCAST | 122 | config SH_DREAMCAST |
| 130 | bool "Dreamcast" | 123 | bool "Dreamcast" |
| 124 | select CPU_SUBTYPE_SH7091 | ||
| 131 | help | 125 | help |
| 132 | Select Dreamcast if configuring for a SEGA Dreamcast. | 126 | Select Dreamcast if configuring for a SEGA Dreamcast. |
| 133 | More information at | 127 | More information at |
| @@ -142,6 +136,7 @@ config SH_BIGSUR | |||
| 142 | 136 | ||
| 143 | config SH_SH2000 | 137 | config SH_SH2000 |
| 144 | bool "SH2000" | 138 | bool "SH2000" |
| 139 | select CPU_SUBTYPE_SH7709 | ||
| 145 | help | 140 | help |
| 146 | SH-2000 is a single-board computer based around SH7709A chip | 141 | SH-2000 is a single-board computer based around SH7709A chip |
| 147 | intended for embedded applications. | 142 | intended for embedded applications. |
| @@ -153,20 +148,22 @@ config SH_ADX | |||
| 153 | bool "ADX" | 148 | bool "ADX" |
| 154 | 149 | ||
| 155 | config SH_MPC1211 | 150 | config SH_MPC1211 |
| 156 | bool "MPC1211" | 151 | bool "Interface MPC1211" |
| 152 | help | ||
| 153 | CTP/PCI-SH02 is a CPU module computer that is produced | ||
| 154 | by Interface Corporation. | ||
| 155 | More information at <http://www.interface.co.jp> | ||
| 157 | 156 | ||
| 158 | config SH_SH03 | 157 | config SH_SH03 |
| 159 | bool "SH03" | 158 | bool "Interface CTP/PCI-SH03" |
| 160 | help | 159 | help |
| 161 | CTP/PCI-SH03 is a CPU module computer that produced | 160 | CTP/PCI-SH03 is a CPU module computer that is produced |
| 162 | by Interface Corporation. | 161 | by Interface Corporation. |
| 163 | It is compact and excellent in durability. | ||
| 164 | It will play an active part in your factory or laboratory | ||
| 165 | as a FA computer. | ||
| 166 | More information at <http://www.interface.co.jp> | 162 | More information at <http://www.interface.co.jp> |
| 167 | 163 | ||
| 168 | config SH_SECUREEDGE5410 | 164 | config SH_SECUREEDGE5410 |
| 169 | bool "SecureEdge5410" | 165 | bool "SecureEdge5410" |
| 166 | select CPU_SUBTYPE_SH7751R | ||
| 170 | help | 167 | help |
| 171 | Select SecureEdge5410 if configuring for a SnapGear SH board. | 168 | Select SecureEdge5410 if configuring for a SnapGear SH board. |
| 172 | This includes both the OEM SecureEdge products as well as the | 169 | This includes both the OEM SecureEdge products as well as the |
| @@ -174,25 +171,49 @@ config SH_SECUREEDGE5410 | |||
| 174 | 171 | ||
| 175 | config SH_HS7751RVOIP | 172 | config SH_HS7751RVOIP |
| 176 | bool "HS7751RVOIP" | 173 | bool "HS7751RVOIP" |
| 174 | select CPU_SUBTYPE_SH7751R | ||
| 177 | help | 175 | help |
| 178 | Select HS7751RVOIP if configuring for a Renesas Technology | 176 | Select HS7751RVOIP if configuring for a Renesas Technology |
| 179 | Sales VoIP board. | 177 | Sales VoIP board. |
| 180 | 178 | ||
| 181 | config SH_RTS7751R2D | 179 | config SH_RTS7751R2D |
| 182 | bool "RTS7751R2D" | 180 | bool "RTS7751R2D" |
| 181 | select CPU_SUBTYPE_SH7751R | ||
| 183 | help | 182 | help |
| 184 | Select RTS7751R2D if configuring for a Renesas Technology | 183 | Select RTS7751R2D if configuring for a Renesas Technology |
| 185 | Sales SH-Graphics board. | 184 | Sales SH-Graphics board. |
| 186 | 185 | ||
| 186 | config SH_R7780RP | ||
| 187 | bool "R7780RP-1" | ||
| 188 | select CPU_SUBTYPE_SH7780 | ||
| 189 | help | ||
| 190 | Select R7780RP-1 if configuring for a Renesas Solutions | ||
| 191 | HIGHLANDER board. | ||
| 192 | |||
| 187 | config SH_EDOSK7705 | 193 | config SH_EDOSK7705 |
| 188 | bool "EDOSK7705" | 194 | bool "EDOSK7705" |
| 195 | select CPU_SUBTYPE_SH7705 | ||
| 189 | 196 | ||
| 190 | config SH_SH4202_MICRODEV | 197 | config SH_SH4202_MICRODEV |
| 191 | bool "SH4-202 MicroDev" | 198 | bool "SH4-202 MicroDev" |
| 199 | select CPU_SUBTYPE_SH4_202 | ||
| 192 | help | 200 | help |
| 193 | Select SH4-202 MicroDev if configuring for a SuperH MicroDev board | 201 | Select SH4-202 MicroDev if configuring for a SuperH MicroDev board |
| 194 | with an SH4-202 CPU. | 202 | with an SH4-202 CPU. |
| 195 | 203 | ||
| 204 | config SH_LANDISK | ||
| 205 | bool "LANDISK" | ||
| 206 | select CPU_SUBTYPE_SH7751R | ||
| 207 | help | ||
| 208 | I-O DATA DEVICE, INC. "LANDISK Series" support. | ||
| 209 | |||
| 210 | config SH_TITAN | ||
| 211 | bool "TITAN" | ||
| 212 | select CPU_SUBTYPE_SH7751R | ||
| 213 | help | ||
| 214 | Select Titan if you are configuring for a Nimble Microsystems | ||
| 215 | NetEngine NP51R. | ||
| 216 | |||
| 196 | config SH_UNKNOWN | 217 | config SH_UNKNOWN |
| 197 | bool "BareCPU" | 218 | bool "BareCPU" |
| 198 | help | 219 | help |
| @@ -207,168 +228,27 @@ config SH_UNKNOWN | |||
| 207 | 228 | ||
| 208 | endchoice | 229 | endchoice |
| 209 | 230 | ||
| 210 | choice | 231 | source "arch/sh/mm/Kconfig" |
| 211 | prompt "Processor family" | ||
| 212 | default CPU_SH4 | ||
| 213 | help | ||
| 214 | This option determines the CPU family to compile for. Supported | ||
| 215 | targets are SH-2, SH-3, and SH-4. These options are independent of | ||
| 216 | CPU functionality. As such, SH-DSP users will still want to select | ||
| 217 | their respective processor family in addition to the DSP support | ||
| 218 | option. | ||
| 219 | |||
| 220 | config CPU_SH2 | ||
| 221 | bool "SH-2" | ||
| 222 | select SH_WRITETHROUGH | ||
| 223 | |||
| 224 | config CPU_SH3 | ||
| 225 | bool "SH-3" | ||
| 226 | |||
| 227 | config CPU_SH4 | ||
| 228 | bool "SH-4" | ||
| 229 | |||
| 230 | endchoice | ||
| 231 | |||
| 232 | choice | ||
| 233 | prompt "Processor subtype" | ||
| 234 | |||
| 235 | config CPU_SUBTYPE_SH7604 | ||
| 236 | bool "SH7604" | ||
| 237 | depends on CPU_SH2 | ||
| 238 | help | ||
| 239 | Select SH7604 if you have SH7604 | ||
| 240 | |||
| 241 | config CPU_SUBTYPE_SH7300 | ||
| 242 | bool "SH7300" | ||
| 243 | depends on CPU_SH3 | ||
| 244 | |||
| 245 | config CPU_SUBTYPE_SH7705 | ||
| 246 | bool "SH7705" | ||
| 247 | depends on CPU_SH3 | ||
| 248 | |||
| 249 | config CPU_SUBTYPE_SH7707 | ||
| 250 | bool "SH7707" | ||
| 251 | depends on CPU_SH3 | ||
| 252 | help | ||
| 253 | Select SH7707 if you have a 60 Mhz SH-3 HD6417707 CPU. | ||
| 254 | |||
| 255 | config CPU_SUBTYPE_SH7708 | ||
| 256 | bool "SH7708" | ||
| 257 | depends on CPU_SH3 | ||
| 258 | help | ||
| 259 | Select SH7708 if you have a 60 Mhz SH-3 HD6417708S or | ||
| 260 | if you have a 100 Mhz SH-3 HD6417708R CPU. | ||
| 261 | |||
| 262 | config CPU_SUBTYPE_SH7709 | ||
| 263 | bool "SH7709" | ||
| 264 | depends on CPU_SH3 | ||
| 265 | help | ||
| 266 | Select SH7709 if you have a 80 Mhz SH-3 HD6417709 CPU. | ||
| 267 | |||
| 268 | config CPU_SUBTYPE_SH7750 | ||
| 269 | bool "SH7750" | ||
| 270 | depends on CPU_SH4 | ||
| 271 | help | ||
| 272 | Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU. | ||
| 273 | |||
| 274 | config CPU_SUBTYPE_SH7751 | ||
| 275 | bool "SH7751/SH7751R" | ||
| 276 | depends on CPU_SH4 | ||
| 277 | help | ||
| 278 | Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU, | ||
| 279 | or if you have a HD6417751R CPU. | ||
| 280 | |||
| 281 | config CPU_SUBTYPE_SH7760 | ||
| 282 | bool "SH7760" | ||
| 283 | depends on CPU_SH4 | ||
| 284 | |||
| 285 | config CPU_SUBTYPE_SH73180 | ||
| 286 | bool "SH73180" | ||
| 287 | depends on CPU_SH4 | ||
| 288 | |||
| 289 | config CPU_SUBTYPE_ST40STB1 | ||
| 290 | bool "ST40STB1 / ST40RA" | ||
| 291 | depends on CPU_SH4 | ||
| 292 | help | ||
| 293 | Select ST40STB1 if you have a ST40RA CPU. | ||
| 294 | This was previously called the ST40STB1, hence the option name. | ||
| 295 | |||
| 296 | config CPU_SUBTYPE_ST40GX1 | ||
| 297 | bool "ST40GX1" | ||
| 298 | depends on CPU_SH4 | ||
| 299 | help | ||
| 300 | Select ST40GX1 if you have a ST40GX1 CPU. | ||
| 301 | |||
| 302 | config CPU_SUBTYPE_SH4_202 | ||
| 303 | bool "SH4-202" | ||
| 304 | depends on CPU_SH4 | ||
| 305 | |||
| 306 | endchoice | ||
| 307 | |||
| 308 | config SH7705_CACHE_32KB | ||
| 309 | bool "Enable 32KB cache size for SH7705" | ||
| 310 | depends on CPU_SUBTYPE_SH7705 | ||
| 311 | default y | ||
| 312 | |||
| 313 | config MMU | ||
| 314 | bool "Support for memory management hardware" | ||
| 315 | depends on !CPU_SH2 | ||
| 316 | default y | ||
| 317 | help | ||
| 318 | Early SH processors (such as the SH7604) lack an MMU. In order to | ||
| 319 | boot on these systems, this option must not be set. | ||
| 320 | |||
| 321 | On other systems (such as the SH-3 and 4) where an MMU exists, | ||
| 322 | turning this off will boot the kernel on these machines with the | ||
| 323 | MMU implicitly switched off. | ||
| 324 | |||
| 325 | choice | ||
| 326 | prompt "HugeTLB page size" | ||
| 327 | depends on HUGETLB_PAGE && CPU_SH4 && MMU | ||
| 328 | default HUGETLB_PAGE_SIZE_64K | ||
| 329 | |||
| 330 | config HUGETLB_PAGE_SIZE_64K | ||
| 331 | bool "64K" | ||
| 332 | |||
| 333 | config HUGETLB_PAGE_SIZE_1MB | ||
| 334 | bool "1MB" | ||
| 335 | |||
| 336 | endchoice | ||
| 337 | |||
| 338 | config CMDLINE_BOOL | ||
| 339 | bool "Default bootloader kernel arguments" | ||
| 340 | |||
| 341 | config CMDLINE | ||
| 342 | string "Initial kernel command string" | ||
| 343 | depends on CMDLINE_BOOL | ||
| 344 | default "console=ttySC1,115200" | ||
| 345 | 232 | ||
| 346 | # Platform-specific memory start and size definitions | ||
| 347 | config MEMORY_START | 233 | config MEMORY_START |
| 348 | hex "Physical memory start address" if !MEMORY_SET || MEMORY_OVERRIDE | 234 | hex "Physical memory start address" |
| 349 | default "0x08000000" if !MEMORY_SET || MEMORY_OVERRIDE || !MEMORY_OVERRIDE && SH_ADX || SH_MPC1211 || SH_SH03 || SH_SECUREEDGE5410 || SH_SH4202_MICRODEV | 235 | default "0x08000000" |
| 350 | default "0x0c000000" if !MEMORY_OVERRIDE && (SH_DREAMCAST || SH_HP600 || SH_BIGSUR || SH_SH2000 || SH_73180_SOLUTION_ENGINE || SH_7300_SOLUTION_ENGINE || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || SH_HS7751RVOIP || SH_RTS7751R2D || SH_EDOSK7705) | ||
| 351 | ---help--- | 236 | ---help--- |
| 352 | Computers built with Hitachi SuperH processors always | 237 | Computers built with Hitachi SuperH processors always |
| 353 | map the ROM starting at address zero. But the processor | 238 | map the ROM starting at address zero. But the processor |
| 354 | does not specify the range that RAM takes. | 239 | does not specify the range that RAM takes. |
| 355 | 240 | ||
| 356 | The physical memory (RAM) start address will be automatically | 241 | The physical memory (RAM) start address will be automatically |
| 357 | set to 08000000, unless you selected one of the following | 242 | set to 08000000. Other platforms, such as the Solution Engine |
| 358 | processor types: SolutionEngine, Overdrive, HP620, HP680, HP690, | 243 | boards typically map RAM at 0C000000. |
| 359 | in which case the start address will be set to 0c000000. | ||
| 360 | 244 | ||
| 361 | Tweak this only when porting to a new machine which is not already | 245 | Tweak this only when porting to a new machine which does not |
| 362 | known by the config system. Changing it from the known correct | 246 | already have a defconfig. Changing it from the known correct |
| 363 | value on any of the known systems will only lead to disaster. | 247 | value on any of the known systems will only lead to disaster. |
| 364 | 248 | ||
| 365 | config MEMORY_SIZE | 249 | config MEMORY_SIZE |
| 366 | hex "Physical memory size" if !MEMORY_SET || MEMORY_OVERRIDE | 250 | hex "Physical memory size" |
| 367 | default "0x00400000" if !MEMORY_SET || MEMORY_OVERRIDE || !MEMORY_OVERRIDE && SH_ADX || !MEMORY_OVERRIDE && (SH_HP600 || SH_BIGSUR || SH_SH2000) | 251 | default "0x00400000" |
| 368 | default "0x01000000" if !MEMORY_OVERRIDE && SH_DREAMCAST || SH_SECUREEDGE5410 || SH_EDOSK7705 | ||
| 369 | default "0x02000000" if !MEMORY_OVERRIDE && (SH_73180_SOLUTION_ENGINE || SH_SOLUTION_ENGINE) | ||
| 370 | default "0x04000000" if !MEMORY_OVERRIDE && (SH_7300_SOLUTION_ENGINE || SH_7751_SOLUTION_ENGINE || SH_HS7751RVOIP || SH_RTS7751R2D || SH_SH4202_MICRODEV) | ||
| 371 | default "0x08000000" if SH_MPC1211 || SH_SH03 | ||
| 372 | help | 252 | help |
| 373 | This sets the default memory size assumed by your SH kernel. It can | 253 | This sets the default memory size assumed by your SH kernel. It can |
| 374 | be overridden as normal by the 'mem=' argument on the kernel command | 254 | be overridden as normal by the 'mem=' argument on the kernel command |
| @@ -376,21 +256,6 @@ config MEMORY_SIZE | |||
| 376 | as 0x00400000 which was the default value before this became | 256 | as 0x00400000 which was the default value before this became |
| 377 | configurable. | 257 | configurable. |
| 378 | 258 | ||
| 379 | config MEMORY_SET | ||
| 380 | bool | ||
| 381 | depends on !MEMORY_OVERRIDE && (SH_MPC1211 || SH_SH03 || SH_ADX || SH_DREAMCAST || SH_HP600 || SH_BIGSUR || SH_SH2000 || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || SH_SECUREEDGE5410 || SH_HS7751RVOIP || SH_RTS7751R2D || SH_SH4202_MICRODEV || SH_EDOSK7705) | ||
| 382 | default y | ||
| 383 | help | ||
| 384 | This is an option about which you will never be asked a question. | ||
| 385 | Therefore, I conclude that you do not exist - go away. | ||
| 386 | |||
| 387 | There is a grue here. | ||
| 388 | |||
| 389 | # If none of the above have set memory start/size, ask the user. | ||
| 390 | config MEMORY_OVERRIDE | ||
| 391 | bool "Override default load address and memory size" | ||
| 392 | |||
| 393 | # XXX: break these out into the board-specific configs below | ||
| 394 | config CF_ENABLER | 259 | config CF_ENABLER |
| 395 | bool "Compact Flash Enabler support" | 260 | bool "Compact Flash Enabler support" |
| 396 | depends on SH_ADX || SH_SOLUTION_ENGINE || SH_UNKNOWN || SH_CAT68701 || SH_SH03 | 261 | depends on SH_ADX || SH_SOLUTION_ENGINE || SH_UNKNOWN || SH_CAT68701 || SH_SH03 |
| @@ -434,10 +299,21 @@ config CF_BASE_ADDR | |||
| 434 | default "0xb8000000" if CF_AREA6 | 299 | default "0xb8000000" if CF_AREA6 |
| 435 | default "0xb4000000" if CF_AREA5 | 300 | default "0xb4000000" if CF_AREA5 |
| 436 | 301 | ||
| 302 | menu "Processor features" | ||
| 303 | |||
| 304 | config CPU_LITTLE_ENDIAN | ||
| 305 | bool "Little Endian" | ||
| 306 | help | ||
| 307 | Some SuperH machines can be configured for either little or big | ||
| 308 | endian byte order. These modes require different kernels. Say Y if | ||
| 309 | your machine is little endian, N if it's a big endian machine. | ||
| 310 | |||
| 437 | # The SH7750 RTC module is disabled in the Dreamcast | 311 | # The SH7750 RTC module is disabled in the Dreamcast |
| 438 | config SH_RTC | 312 | config SH_RTC |
| 439 | bool | 313 | bool |
| 440 | depends on !SH_DREAMCAST && !SH_SATURN && !SH_7300_SOLUTION_ENGINE && !SH_73180_SOLUTION_ENGINE | 314 | depends on !SH_DREAMCAST && !SH_SATURN && !SH_7300_SOLUTION_ENGINE && \ |
| 315 | !SH_73180_SOLUTION_ENGINE && !SH_LANDISK && \ | ||
| 316 | !SH_R7780RP | ||
| 441 | default y | 317 | default y |
| 442 | help | 318 | help |
| 443 | Selecting this option will allow the Linux kernel to emulate | 319 | Selecting this option will allow the Linux kernel to emulate |
| @@ -476,104 +352,131 @@ config SH_ADC | |||
| 476 | 352 | ||
| 477 | If unsure, say N. | 353 | If unsure, say N. |
| 478 | 354 | ||
| 479 | config SH_HP600 | 355 | config SH_STORE_QUEUES |
| 356 | bool "Support for Store Queues" | ||
| 357 | depends on CPU_SH4 | ||
| 358 | help | ||
| 359 | Selecting this option will enable an in-kernel API for manipulating | ||
| 360 | the store queues integrated in the SH-4 processors. | ||
| 361 | |||
| 362 | config CPU_HAS_INTEVT | ||
| 480 | bool | 363 | bool |
| 481 | depends on SH_HP620 || SH_HP680 || SH_HP690 | ||
| 482 | default y | ||
| 483 | 364 | ||
| 484 | config CPU_SUBTYPE_ST40 | 365 | config CPU_HAS_PINT_IRQ |
| 485 | bool | 366 | bool |
| 486 | depends on CPU_SUBTYPE_ST40STB1 || CPU_SUBTYPE_ST40GX1 | ||
| 487 | default y | ||
| 488 | 367 | ||
| 489 | source "mm/Kconfig" | 368 | config CPU_HAS_INTC2_IRQ |
| 369 | bool | ||
| 490 | 370 | ||
| 491 | config ZERO_PAGE_OFFSET | 371 | config CPU_HAS_SR_RB |
| 492 | hex "Zero page offset" | 372 | bool "CPU has SR.RB" |
| 493 | default "0x00001000" if !(SH_MPC1211 || SH_SH03) | 373 | depends on CPU_SH3 || CPU_SH4 |
| 494 | default "0x00004000" if SH_MPC1211 || SH_SH03 | 374 | default y |
| 495 | help | 375 | help |
| 496 | This sets the default offset of zero page. | 376 | This will enable the use of SR.RB register bank usage. Processors |
| 377 | that are lacking this bit must have another method in place for | ||
| 378 | accomplishing what is taken care of by the banked registers. | ||
| 497 | 379 | ||
| 498 | # XXX: needs to lose subtype for system type | 380 | See <file:Documentation/sh/register-banks.txt> for further |
| 499 | config ST40_LMI_MEMORY | 381 | information on SR.RB and register banking in the kernel in general. |
| 500 | bool "Memory on LMI" | ||
| 501 | depends on CPU_SUBTYPE_ST40STB1 | ||
| 502 | 382 | ||
| 503 | config MEMORY_START | 383 | endmenu |
| 504 | hex | ||
| 505 | depends on CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY | ||
| 506 | default "0x08000000" | ||
| 507 | 384 | ||
| 508 | config MEMORY_SIZE | 385 | menu "Timer support" |
| 509 | hex | ||
| 510 | depends on CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY | ||
| 511 | default "0x00400000" | ||
| 512 | 386 | ||
| 513 | config MEMORY_SET | 387 | config SH_TMU |
| 514 | bool | 388 | bool "TMU timer support" |
| 515 | depends on CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY | ||
| 516 | default y | 389 | default y |
| 517 | |||
| 518 | config BOOT_LINK_OFFSET | ||
| 519 | hex "Link address offset for booting" | ||
| 520 | default "0x00800000" | ||
| 521 | help | 390 | help |
| 522 | This option allows you to set the link address offset of the zImage. | 391 | This enables the use of the TMU as the system timer. |
| 523 | This can be useful if you are on a board which has a small amount of | ||
| 524 | memory. | ||
| 525 | 392 | ||
| 526 | config CPU_LITTLE_ENDIAN | 393 | endmenu |
| 527 | bool "Little Endian" | ||
| 528 | help | ||
| 529 | Some SuperH machines can be configured for either little or big | ||
| 530 | endian byte order. These modes require different kernels. Say Y if | ||
| 531 | your machine is little endian, N if it's a big endian machine. | ||
| 532 | 394 | ||
| 533 | config PREEMPT | 395 | source "arch/sh/boards/renesas/hs7751rvoip/Kconfig" |
| 534 | bool "Preemptible Kernel (EXPERIMENTAL)" | ||
| 535 | depends on EXPERIMENTAL | ||
| 536 | 396 | ||
| 537 | config UBC_WAKEUP | 397 | source "arch/sh/boards/renesas/rts7751r2d/Kconfig" |
| 538 | bool "Wakeup UBC on startup" | 398 | |
| 399 | config SH_PCLK_FREQ_BOOL | ||
| 400 | bool "Set default pclk frequency" | ||
| 401 | default y if !SH_RTC | ||
| 402 | default n | ||
| 403 | |||
| 404 | config SH_PCLK_FREQ | ||
| 405 | int "Peripheral clock frequency (in Hz)" | ||
| 406 | depends on SH_PCLK_FREQ_BOOL | ||
| 407 | default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780 | ||
| 408 | default "60000000" if CPU_SUBTYPE_SH7751 | ||
| 409 | default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || CPU_SUBTYPE_SH7760 | ||
| 410 | default "27000000" if CPU_SUBTYPE_SH73180 | ||
| 411 | default "66000000" if CPU_SUBTYPE_SH4_202 | ||
| 539 | help | 412 | help |
| 540 | Selecting this option will wakeup the User Break Controller (UBC) on | 413 | This option is used to specify the peripheral clock frequency. |
| 541 | startup. Although the UBC is left in an awake state when the processor | 414 | This is necessary for determining the reference clock value on |
| 542 | comes up, some boot loaders misbehave by putting the UBC to sleep in a | 415 | platforms lacking an RTC. |
| 543 | power saving state, which causes issues with things like ptrace(). | ||
| 544 | 416 | ||
| 545 | If unsure, say N. | 417 | menu "CPU Frequency scaling" |
| 418 | |||
| 419 | source "drivers/cpufreq/Kconfig" | ||
| 546 | 420 | ||
| 547 | config SH_WRITETHROUGH | 421 | config SH_CPU_FREQ |
| 548 | bool "Use write-through caching" | 422 | tristate "SuperH CPU Frequency driver" |
| 549 | default y if CPU_SH2 | 423 | depends on CPU_FREQ |
| 424 | select CPU_FREQ_TABLE | ||
| 550 | help | 425 | help |
| 551 | Selecting this option will configure the caches in write-through | 426 | This adds the cpufreq driver for SuperH. At present, only |
| 552 | mode, as opposed to the default write-back configuration. | 427 | the SH-4 is supported. |
| 553 | 428 | ||
| 554 | Since there's sill some aliasing issues on SH-4, this option will | 429 | For details, take a look at <file:Documentation/cpu-freq>. |
| 555 | unfortunately still require the majority of flushing functions to | ||
| 556 | be implemented to deal with aliasing. | ||
| 557 | 430 | ||
| 558 | If unsure, say N. | 431 | If unsure, say N. |
| 559 | 432 | ||
| 560 | config SH_OCRAM | 433 | endmenu |
| 561 | bool "Operand Cache RAM (OCRAM) support" | 434 | |
| 435 | source "arch/sh/drivers/dma/Kconfig" | ||
| 436 | |||
| 437 | source "arch/sh/cchips/Kconfig" | ||
| 438 | |||
| 439 | config HEARTBEAT | ||
| 440 | bool "Heartbeat LED" | ||
| 441 | depends on SH_MPC1211 || SH_SH03 || SH_CAT68701 || \ | ||
| 442 | SH_STB1_HARP || SH_STB1_OVERDRIVE || SH_BIGSUR || \ | ||
| 443 | SH_7751_SOLUTION_ENGINE || SH_7300_SOLUTION_ENGINE || \ | ||
| 444 | SH_73180_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || \ | ||
| 445 | SH_RTS7751R2D || SH_SH4202_MICRODEV || SH_LANDISK | ||
| 562 | help | 446 | help |
| 563 | Selecting this option will automatically tear down the number of | 447 | Use the power-on LED on your machine as a load meter. The exact |
| 564 | sets in the dcache by half, which in turn exposes a memory range. | 448 | behavior is platform-dependent, but normally the flash frequency is |
| 449 | a hyperbolic function of the 5-minute load average. | ||
| 565 | 450 | ||
| 566 | The addresses for the OC RAM base will vary according to the | 451 | endmenu |
| 567 | processor version. Consult vendor documentation for specifics. | ||
| 568 | 452 | ||
| 569 | If unsure, say N. | 453 | config ISA_DMA_API |
| 454 | bool | ||
| 455 | depends on MPC1211 | ||
| 456 | default y | ||
| 570 | 457 | ||
| 571 | config SH_STORE_QUEUES | 458 | menu "Kernel features" |
| 572 | bool "Support for Store Queues" | 459 | |
| 573 | depends on CPU_SH4 | 460 | config KEXEC |
| 461 | bool "kexec system call (EXPERIMENTAL)" | ||
| 462 | depends on EXPERIMENTAL | ||
| 574 | help | 463 | help |
| 575 | Selecting this option will enable an in-kernel API for manipulating | 464 | kexec is a system call that implements the ability to shutdown your |
| 576 | the store queues integrated in the SH-4 processors. | 465 | current kernel, and to start another kernel. It is like a reboot |
| 466 | but it is indepedent of the system firmware. And like a reboot | ||
| 467 | you can start any kernel with it, not just Linux. | ||
| 468 | |||
| 469 | The name comes from the similiarity to the exec system call. | ||
| 470 | |||
| 471 | It is an ongoing process to be certain the hardware in a machine | ||
| 472 | is properly shutdown, so do not be surprised if this code does not | ||
| 473 | initially work for you. It may help to enable device hotplugging | ||
| 474 | support. As of this writing the exact hardware interface is | ||
| 475 | strongly in flux, so no good recommendation can be made. | ||
| 476 | |||
| 477 | config PREEMPT | ||
| 478 | bool "Preemptible Kernel (EXPERIMENTAL)" | ||
| 479 | depends on EXPERIMENTAL | ||
| 577 | 480 | ||
| 578 | config SMP | 481 | config SMP |
| 579 | bool "Symmetric multi-processing support" | 482 | bool "Symmetric multi-processing support" |
| @@ -610,87 +513,58 @@ config NR_CPUS | |||
| 610 | This is purely to save memory - each supported CPU adds | 513 | This is purely to save memory - each supported CPU adds |
| 611 | approximately eight kilobytes to the kernel image. | 514 | approximately eight kilobytes to the kernel image. |
| 612 | 515 | ||
| 613 | config HS7751RVOIP_CODEC | 516 | config CPU_HAS_SR_RB |
| 614 | bool "Support VoIP Codec section" | 517 | bool "CPU has SR.RB" |
| 615 | depends on SH_HS7751RVOIP | 518 | depends on CPU_SH3 || CPU_SH4 |
| 616 | help | ||
| 617 | Selecting this option will support CODEC section. | ||
| 618 | |||
| 619 | config RTS7751R2D_REV11 | ||
| 620 | bool "RTS7751R2D Rev. 1.1 board support" | ||
| 621 | depends on SH_RTS7751R2D | ||
| 622 | help | ||
| 623 | Selecting this option will support version rev. 1.1. | ||
| 624 | |||
| 625 | config SH_PCLK_CALC | ||
| 626 | bool | ||
| 627 | default n if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH73180 | ||
| 628 | default y | 519 | default y |
| 629 | help | 520 | help |
| 630 | This option will cause the PCLK value to be probed at run-time. It | 521 | This will enable the use of SR.RB register bank usage. Processors |
| 631 | will display a notification if the probed value has greater than a | 522 | that are lacking this bit must have another method in place for |
| 632 | 1% variance of the hardcoded CONFIG_SH_PCLK_FREQ. | 523 | accomplishing what is taken care of by the banked registers. |
| 633 | 524 | ||
| 634 | config SH_PCLK_FREQ | 525 | See <file:Documentation/sh/register-banks.txt> for further |
| 635 | int "Peripheral clock frequency (in Hz)" | 526 | information on SR.RB and register banking in the kernel in general. |
| 636 | default "50000000" if CPU_SUBTYPE_SH7750 | ||
| 637 | default "60000000" if CPU_SUBTYPE_SH7751 | ||
| 638 | default "33333333" if CPU_SUBTYPE_SH7300 | ||
| 639 | default "27000000" if CPU_SUBTYPE_SH73180 | ||
| 640 | default "66000000" if CPU_SUBTYPE_SH4_202 | ||
| 641 | default "1193182" | ||
| 642 | help | ||
| 643 | This option is used to specify the peripheral clock frequency. This | ||
| 644 | option must be set for each processor in order for the kernel to | ||
| 645 | function reliably. If no sane default exists, we use a default from | ||
| 646 | the legacy i8254. Any discrepancies will be reported on boot time | ||
| 647 | with an auto-probed frequency which should be considered the proper | ||
| 648 | value for your hardware. | ||
| 649 | 527 | ||
| 650 | menu "CPU Frequency scaling" | 528 | endmenu |
| 651 | 529 | ||
| 652 | source "drivers/cpufreq/Kconfig" | 530 | menu "Boot options" |
| 653 | 531 | ||
| 654 | config SH_CPU_FREQ | 532 | config ZERO_PAGE_OFFSET |
| 655 | tristate "SuperH CPU Frequency driver" | 533 | hex "Zero page offset" |
| 656 | depends on CPU_FREQ | 534 | default "0x00004000" if SH_MPC1211 || SH_SH03 |
| 657 | select CPU_FREQ_TABLE | 535 | default "0x00001000" |
| 658 | help | 536 | help |
| 659 | This adds the cpufreq driver for SuperH. At present, only | 537 | This sets the default offset of zero page. |
| 660 | the SH-4 is supported. | ||
| 661 | |||
| 662 | For details, take a look at <file:Documentation/cpu-freq>. | ||
| 663 | |||
| 664 | If unsure, say N. | ||
| 665 | 538 | ||
| 666 | endmenu | 539 | config BOOT_LINK_OFFSET |
| 540 | hex "Link address offset for booting" | ||
| 541 | default "0x00800000" | ||
| 542 | help | ||
| 543 | This option allows you to set the link address offset of the zImage. | ||
| 544 | This can be useful if you are on a board which has a small amount of | ||
| 545 | memory. | ||
| 667 | 546 | ||
| 668 | source "arch/sh/drivers/dma/Kconfig" | 547 | config UBC_WAKEUP |
| 548 | bool "Wakeup UBC on startup" | ||
| 549 | help | ||
| 550 | Selecting this option will wakeup the User Break Controller (UBC) on | ||
| 551 | startup. Although the UBC is left in an awake state when the processor | ||
| 552 | comes up, some boot loaders misbehave by putting the UBC to sleep in a | ||
| 553 | power saving state, which causes issues with things like ptrace(). | ||
| 669 | 554 | ||
| 670 | source "arch/sh/cchips/Kconfig" | 555 | If unsure, say N. |
| 671 | 556 | ||
| 672 | config HEARTBEAT | 557 | config CMDLINE_BOOL |
| 673 | bool "Heartbeat LED" | 558 | bool "Default bootloader kernel arguments" |
| 674 | depends on SH_MPC1211 || SH_SH03 || SH_CAT68701 || SH_STB1_HARP || SH_STB1_OVERDRIVE || SH_BIGSUR || SH_7751_SOLUTION_ENGINE || SH_7300_SOLUTION_ENGINE || SH_73180_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || SH_RTS7751R2D || SH_SH4202_MICRODEV | ||
| 675 | help | ||
| 676 | Use the power-on LED on your machine as a load meter. The exact | ||
| 677 | behavior is platform-dependent, but normally the flash frequency is | ||
| 678 | a hyperbolic function of the 5-minute load average. | ||
| 679 | 559 | ||
| 680 | config RTC_9701JE | 560 | config CMDLINE |
| 681 | tristate "EPSON RTC-9701JE support" | 561 | string "Initial kernel command string" |
| 682 | depends on SH_RTS7751R2D | 562 | depends on CMDLINE_BOOL |
| 683 | help | 563 | default "console=ttySC1,115200" |
| 684 | Selecting this option will support EPSON RTC-9701JE. | ||
| 685 | 564 | ||
| 686 | endmenu | 565 | endmenu |
| 687 | 566 | ||
| 688 | config ISA_DMA_API | 567 | menu "Bus options" |
| 689 | bool | ||
| 690 | depends on MPC1211 | ||
| 691 | default y | ||
| 692 | |||
| 693 | menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)" | ||
| 694 | 568 | ||
| 695 | # Even on SuperH devices which don't have an ISA bus, | 569 | # Even on SuperH devices which don't have an ISA bus, |
| 696 | # this variable helps the PCMCIA modules handle | 570 | # this variable helps the PCMCIA modules handle |
| @@ -701,7 +575,7 @@ menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)" | |||
| 701 | # PCMCIA outright. -- PFM. | 575 | # PCMCIA outright. -- PFM. |
| 702 | config ISA | 576 | config ISA |
| 703 | bool | 577 | bool |
| 704 | default y if PCMCIA || SMC91X | 578 | default y if PCMCIA |
| 705 | help | 579 | help |
| 706 | Find out whether you have ISA slots on your motherboard. ISA is the | 580 | Find out whether you have ISA slots on your motherboard. ISA is the |
| 707 | name of a bus system, i.e. the way the CPU talks to the other stuff | 581 | name of a bus system, i.e. the way the CPU talks to the other stuff |
| @@ -735,10 +609,9 @@ config MCA | |||
| 735 | config SBUS | 609 | config SBUS |
| 736 | bool | 610 | bool |
| 737 | 611 | ||
| 738 | config MAPLE | 612 | config SUPERHYWAY |
| 739 | tristate "Maple Bus support" | 613 | tristate "SuperHyway Bus support" |
| 740 | depends on SH_DREAMCAST | 614 | depends on CPU_SUBTYPE_SH4_202 |
| 741 | default y | ||
| 742 | 615 | ||
| 743 | source "arch/sh/drivers/pci/Kconfig" | 616 | source "arch/sh/drivers/pci/Kconfig" |
| 744 | 617 | ||
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 3fab181da364..8fb31ab2c02c 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug | |||
| @@ -17,7 +17,7 @@ config SH_STANDARD_BIOS | |||
| 17 | 17 | ||
| 18 | config EARLY_SCIF_CONSOLE | 18 | config EARLY_SCIF_CONSOLE |
| 19 | bool "Use early SCIF console" | 19 | bool "Use early SCIF console" |
| 20 | depends on CPU_SH4 | 20 | depends on CPU_SH4 || CPU_SH2A && !SH_STANDARD_BIOS |
| 21 | 21 | ||
| 22 | config EARLY_PRINTK | 22 | config EARLY_PRINTK |
| 23 | bool "Early printk support" | 23 | bool "Early printk support" |
diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 67192d6b00d8..08c9515c4806 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile | |||
| @@ -17,10 +17,30 @@ | |||
| 17 | cflags-y := -mb | 17 | cflags-y := -mb |
| 18 | cflags-$(CONFIG_CPU_LITTLE_ENDIAN) := -ml | 18 | cflags-$(CONFIG_CPU_LITTLE_ENDIAN) := -ml |
| 19 | 19 | ||
| 20 | isa-y := any | ||
| 21 | isa-$(CONFIG_CPU_SH2) := sh2 | ||
| 22 | isa-$(CONFIG_CPU_SH3) := sh3 | ||
| 23 | isa-$(CONFIG_CPU_SH4) := sh4 | ||
| 24 | isa-$(CONFIG_CPU_SH4A) := sh4a | ||
| 25 | isa-$(CONFIG_CPU_SH2A) := sh2a | ||
| 26 | |||
| 27 | isa-$(CONFIG_SH_DSP) := $(isa-y)-dsp | ||
| 28 | |||
| 29 | ifndef CONFIG_MMU | ||
| 30 | isa-y := $(isa-y)-nommu | ||
| 31 | endif | ||
| 32 | |||
| 33 | ifndef CONFIG_SH_FPU | ||
| 34 | isa-y := $(isa-y)-nofpu | ||
| 35 | endif | ||
| 36 | |||
| 37 | cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) | ||
| 38 | |||
| 20 | cflags-$(CONFIG_CPU_SH2) += -m2 | 39 | cflags-$(CONFIG_CPU_SH2) += -m2 |
| 21 | cflags-$(CONFIG_CPU_SH3) += -m3 | 40 | cflags-$(CONFIG_CPU_SH3) += -m3 |
| 22 | cflags-$(CONFIG_CPU_SH4) += -m4 \ | 41 | cflags-$(CONFIG_CPU_SH4) += -m4 \ |
| 23 | $(call cc-option,-mno-implicit-fp,-m4-nofpu) | 42 | $(call cc-option,-mno-implicit-fp,-m4-nofpu) |
| 43 | cflags-$(CONFIG_CPU_SH4A) += $(call cc-option,-m4a-nofpu,) | ||
| 24 | 44 | ||
| 25 | cflags-$(CONFIG_SH_DSP) += -Wa,-dsp | 45 | cflags-$(CONFIG_SH_DSP) += -Wa,-dsp |
| 26 | cflags-$(CONFIG_SH_KGDB) += -g | 46 | cflags-$(CONFIG_SH_KGDB) += -g |
| @@ -67,9 +87,7 @@ machdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se/7300 | |||
| 67 | machdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se/73180 | 87 | machdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se/73180 |
| 68 | machdir-$(CONFIG_SH_STB1_HARP) := harp | 88 | machdir-$(CONFIG_SH_STB1_HARP) := harp |
| 69 | machdir-$(CONFIG_SH_STB1_OVERDRIVE) := overdrive | 89 | machdir-$(CONFIG_SH_STB1_OVERDRIVE) := overdrive |
| 70 | machdir-$(CONFIG_SH_HP620) := hp6xx/hp620 | 90 | machdir-$(CONFIG_SH_HP6XX) := hp6xx |
| 71 | machdir-$(CONFIG_SH_HP680) := hp6xx/hp680 | ||
| 72 | machdir-$(CONFIG_SH_HP690) := hp6xx/hp690 | ||
| 73 | machdir-$(CONFIG_SH_CQREEK) := cqreek | 91 | machdir-$(CONFIG_SH_CQREEK) := cqreek |
| 74 | machdir-$(CONFIG_SH_DMIDA) := dmida | 92 | machdir-$(CONFIG_SH_DMIDA) := dmida |
| 75 | machdir-$(CONFIG_SH_EC3104) := ec3104 | 93 | machdir-$(CONFIG_SH_EC3104) := ec3104 |
| @@ -119,31 +137,39 @@ boot := arch/sh/boot | |||
| 119 | 137 | ||
| 120 | CPPFLAGS_vmlinux.lds := -traditional | 138 | CPPFLAGS_vmlinux.lds := -traditional |
| 121 | 139 | ||
| 140 | ifneq ($(KBUILD_SRC),) | ||
| 141 | incdir-prefix := $(srctree)/include/asm-sh/ | ||
| 142 | else | ||
| 143 | incdir-prefix := | ||
| 144 | endif | ||
| 145 | |||
| 122 | # Update machine arch and proc symlinks if something which affects | 146 | # Update machine arch and proc symlinks if something which affects |
| 123 | # them changed. We use .arch and .mach to indicate when they were | 147 | # them changed. We use .arch and .mach to indicate when they were |
| 124 | # updated last, otherwise make uses the target directory mtime. | 148 | # updated last, otherwise make uses the target directory mtime. |
| 125 | 149 | ||
| 126 | include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/MARKER | 150 | include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/MARKER |
| 127 | @echo ' SYMLINK include/asm-sh/cpu -> include/asm-sh/$(cpuincdir-y)' | 151 | @echo ' SYMLINK include/asm-sh/cpu -> include/asm-sh/$(cpuincdir-y)' |
| 128 | ifneq ($(KBUILD_SRC),) | 152 | $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi |
| 129 | $(Q)mkdir -p include/asm-sh | 153 | $(Q)ln -fsn $(incdir-prefix)$(cpuincdir-y) include/asm-sh/cpu |
| 130 | $(Q)ln -fsn $(srctree)/include/asm-sh/$(cpuincdir-y) include/asm-sh/cpu | ||
| 131 | else | ||
| 132 | $(Q)ln -fsn $(cpuincdir-y) include/asm-sh/cpu | ||
| 133 | endif | ||
| 134 | @touch $@ | 154 | @touch $@ |
| 135 | 155 | ||
| 156 | # Most boards have their own mach directories. For the ones that | ||
| 157 | # don't, just reference the parent directory so the semantics are | ||
| 158 | # kept roughly the same. | ||
| 159 | |||
| 136 | include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/MARKER | 160 | include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/MARKER |
| 137 | @echo ' SYMLINK include/asm-sh/mach -> include/asm-sh/$(incdir-y)' | 161 | @echo -n ' SYMLINK include/asm-sh/mach -> ' |
| 138 | ifneq ($(KBUILD_SRC),) | 162 | $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi |
| 139 | $(Q)mkdir -p include/asm-sh | 163 | $(Q)if [ -d $(incdir-prefix)$(incdir-y) ]; then \ |
| 140 | $(Q)ln -fsn $(srctree)/include/asm-sh/$(incdir-y) include/asm-sh/mach | 164 | echo -e 'include/asm-sh/$(incdir-y)'; \ |
| 141 | else | 165 | ln -fsn $(incdir-prefix)$(incdir-y) \ |
| 142 | $(Q)ln -fsn $(incdir-y) include/asm-sh/mach | 166 | include/asm-sh/mach; \ |
| 143 | endif | 167 | else \ |
| 168 | echo -e 'include/asm-sh'; \ | ||
| 169 | ln -fsn $(incdir-prefix) include/asm-sh/mach; \ | ||
| 170 | fi | ||
| 144 | @touch $@ | 171 | @touch $@ |
| 145 | 172 | ||
| 146 | |||
| 147 | archprepare: maketools include/asm-sh/.cpu include/asm-sh/.mach | 173 | archprepare: maketools include/asm-sh/.cpu include/asm-sh/.mach |
| 148 | 174 | ||
| 149 | .PHONY: maketools FORCE | 175 | .PHONY: maketools FORCE |
diff --git a/arch/sh/boards/hp6xx/Makefile b/arch/sh/boards/hp6xx/Makefile new file mode 100644 index 000000000000..927fe0aa5dfa --- /dev/null +++ b/arch/sh/boards/hp6xx/Makefile | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | # | ||
| 2 | # Makefile for the HP6xx specific parts of the kernel | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-y := mach.o setup.o | ||
| 6 | |||
diff --git a/arch/sh/boards/hp6xx/hp620/Makefile b/arch/sh/boards/hp6xx/hp620/Makefile deleted file mode 100644 index 20691dbce347..000000000000 --- a/arch/sh/boards/hp6xx/hp620/Makefile +++ /dev/null | |||
| @@ -1,6 +0,0 @@ | |||
| 1 | # | ||
| 2 | # Makefile for the HP620 specific parts of the kernel | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-y := mach.o setup.o | ||
| 6 | |||
diff --git a/arch/sh/boards/hp6xx/hp620/mach.c b/arch/sh/boards/hp6xx/hp620/mach.c deleted file mode 100644 index 0392d82b4a7b..000000000000 --- a/arch/sh/boards/hp6xx/hp620/mach.c +++ /dev/null | |||
| @@ -1,52 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/sh/boards/hp6xx/hp620/mach.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) | ||
| 5 | * | ||
| 6 | * May be copied or modified under the terms of the GNU General Public | ||
| 7 | * License. See linux/COPYING for more information. | ||
| 8 | * | ||
| 9 | * Machine vector for the HP620 | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/init.h> | ||
| 13 | |||
| 14 | #include <asm/machvec.h> | ||
| 15 | #include <asm/rtc.h> | ||
| 16 | #include <asm/machvec_init.h> | ||
| 17 | |||
| 18 | #include <asm/io.h> | ||
| 19 | #include <asm/hd64461/hd64461.h> | ||
| 20 | #include <asm/irq.h> | ||
| 21 | |||
| 22 | /* | ||
| 23 | * The Machine Vector | ||
| 24 | */ | ||
| 25 | |||
| 26 | struct sh_machine_vector mv_hp620 __initmv = { | ||
| 27 | .mv_nr_irqs = HD64461_IRQBASE+HD64461_IRQ_NUM, | ||
| 28 | |||
| 29 | .mv_inb = hd64461_inb, | ||
| 30 | .mv_inw = hd64461_inw, | ||
| 31 | .mv_inl = hd64461_inl, | ||
| 32 | .mv_outb = hd64461_outb, | ||
| 33 | .mv_outw = hd64461_outw, | ||
| 34 | .mv_outl = hd64461_outl, | ||
| 35 | |||
| 36 | .mv_inb_p = hd64461_inb_p, | ||
| 37 | .mv_inw_p = hd64461_inw, | ||
| 38 | .mv_inl_p = hd64461_inl, | ||
| 39 | .mv_outb_p = hd64461_outb_p, | ||
| 40 | .mv_outw_p = hd64461_outw, | ||
| 41 | .mv_outl_p = hd64461_outl, | ||
| 42 | |||
| 43 | .mv_insb = hd64461_insb, | ||
| 44 | .mv_insw = hd64461_insw, | ||
| 45 | .mv_insl = hd64461_insl, | ||
| 46 | .mv_outsb = hd64461_outsb, | ||
| 47 | .mv_outsw = hd64461_outsw, | ||
| 48 | .mv_outsl = hd64461_outsl, | ||
| 49 | |||
| 50 | .mv_irq_demux = hd64461_irq_demux, | ||
| 51 | }; | ||
| 52 | ALIAS_MV(hp620) | ||
diff --git a/arch/sh/boards/hp6xx/hp620/setup.c b/arch/sh/boards/hp6xx/hp620/setup.c deleted file mode 100644 index 045fc5da7274..000000000000 --- a/arch/sh/boards/hp6xx/hp620/setup.c +++ /dev/null | |||
| @@ -1,45 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/sh/boards/hp6xx/hp620/setup.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2002 Andriy Skulysh, 2005 Kristoffer Ericson | ||
| 5 | * | ||
| 6 | * May be copied or modified under the terms of the GNU General Public | ||
| 7 | * License. See Linux/COPYING for more information. | ||
| 8 | * | ||
| 9 | * Setup code for an HP620. | ||
| 10 | * Due to similiarity with hp680/hp690 same inits are done (for now) | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/config.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <asm/hd64461/hd64461.h> | ||
| 16 | #include <asm/io.h> | ||
| 17 | #include <asm/hp6xx/hp6xx.h> | ||
| 18 | #include <asm/cpu/dac.h> | ||
| 19 | |||
| 20 | const char *get_system_type(void) | ||
| 21 | { | ||
| 22 | return "HP620"; | ||
| 23 | } | ||
| 24 | |||
| 25 | int __init platform_setup(void) | ||
| 26 | { | ||
| 27 | u16 v; | ||
| 28 | |||
| 29 | v = inw(HD64461_STBCR); | ||
| 30 | v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST | | ||
| 31 | HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST | | ||
| 32 | HD64461_STBCR_SAFEST | HD64461_STBCR_SPC0ST | | ||
| 33 | HD64461_STBCR_SMIAST | HD64461_STBCR_SAFECKE_OST | | ||
| 34 | HD64461_STBCR_SAFECKE_IST; | ||
| 35 | outw(v, HD64461_STBCR); | ||
| 36 | |||
| 37 | v = inw(HD64461_GPADR); | ||
| 38 | v |= HD64461_GPADR_SPEAKER | HD64461_GPADR_PCMCIA0; | ||
| 39 | outw(v, HD64461_GPADR); | ||
| 40 | |||
| 41 | sh_dac_disable(DAC_SPEAKER_VOLUME); | ||
| 42 | |||
| 43 | return 0; | ||
| 44 | } | ||
| 45 | |||
diff --git a/arch/sh/boards/hp6xx/hp680/Makefile b/arch/sh/boards/hp6xx/hp680/Makefile deleted file mode 100644 index 0beef11d9b11..000000000000 --- a/arch/sh/boards/hp6xx/hp680/Makefile +++ /dev/null | |||
| @@ -1,6 +0,0 @@ | |||
| 1 | # | ||
| 2 | # Makefile for the HP680 specific parts of the kernel | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-y := mach.o setup.o | ||
| 6 | |||
diff --git a/arch/sh/boards/hp6xx/hp690/Makefile b/arch/sh/boards/hp6xx/hp690/Makefile deleted file mode 100644 index fbbe95e75f83..000000000000 --- a/arch/sh/boards/hp6xx/hp690/Makefile +++ /dev/null | |||
| @@ -1,6 +0,0 @@ | |||
| 1 | # | ||
| 2 | # Makefile for the HP690 specific parts of the kernel | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-y := mach.o | ||
| 6 | |||
diff --git a/arch/sh/boards/hp6xx/hp690/mach.c b/arch/sh/boards/hp6xx/hp690/mach.c deleted file mode 100644 index 2a4c68783cd6..000000000000 --- a/arch/sh/boards/hp6xx/hp690/mach.c +++ /dev/null | |||
| @@ -1,48 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/sh/boards/hp6xx/hp690/mach.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) | ||
| 5 | * | ||
| 6 | * May be copied or modified under the terms of the GNU General Public | ||
| 7 | * License. See linux/COPYING for more information. | ||
| 8 | * | ||
| 9 | * Machine vector for the HP690 | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/init.h> | ||
| 13 | |||
| 14 | #include <asm/machvec.h> | ||
| 15 | #include <asm/rtc.h> | ||
| 16 | #include <asm/machvec_init.h> | ||
| 17 | |||
| 18 | #include <asm/io.h> | ||
| 19 | #include <asm/hd64461/hd64461.h> | ||
| 20 | #include <asm/irq.h> | ||
| 21 | |||
| 22 | struct sh_machine_vector mv_hp690 __initmv = { | ||
| 23 | .mv_nr_irqs = HD64461_IRQBASE+HD64461_IRQ_NUM, | ||
| 24 | |||
| 25 | .mv_inb = hd64461_inb, | ||
| 26 | .mv_inw = hd64461_inw, | ||
| 27 | .mv_inl = hd64461_inl, | ||
| 28 | .mv_outb = hd64461_outb, | ||
| 29 | .mv_outw = hd64461_outw, | ||
| 30 | .mv_outl = hd64461_outl, | ||
| 31 | |||
| 32 | .mv_inb_p = hd64461_inb_p, | ||
| 33 | .mv_inw_p = hd64461_inw, | ||
| 34 | .mv_inl_p = hd64461_inl, | ||
| 35 | .mv_outb_p = hd64461_outb_p, | ||
| 36 | .mv_outw_p = hd64461_outw, | ||
| 37 | .mv_outl_p = hd64461_outl, | ||
| 38 | |||
| 39 | .mv_insb = hd64461_insb, | ||
| 40 | .mv_insw = hd64461_insw, | ||
| 41 | .mv_insl = hd64461_insl, | ||
| 42 | .mv_outsb = hd64461_outsb, | ||
| 43 | .mv_outsw = hd64461_outsw, | ||
| 44 | .mv_outsl = hd64461_outsl, | ||
| 45 | |||
| 46 | .mv_irq_demux = hd64461_irq_demux, | ||
| 47 | }; | ||
| 48 | ALIAS_MV(hp690) | ||
diff --git a/arch/sh/boards/hp6xx/hp680/mach.c b/arch/sh/boards/hp6xx/mach.c index d73486136045..08dbba910f74 100644 --- a/arch/sh/boards/hp6xx/hp680/mach.c +++ b/arch/sh/boards/hp6xx/mach.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/arch/sh/boards/hp6xx/hp680/mach.c | 2 | * linux/arch/sh/boards/hp6xx/mach.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) | 4 | * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) |
| 5 | * | 5 | * |
| @@ -8,19 +8,12 @@ | |||
| 8 | * | 8 | * |
| 9 | * Machine vector for the HP680 | 9 | * Machine vector for the HP680 |
| 10 | */ | 10 | */ |
| 11 | |||
| 12 | #include <linux/init.h> | ||
| 13 | |||
| 14 | #include <asm/machvec.h> | 11 | #include <asm/machvec.h> |
| 15 | #include <asm/rtc.h> | 12 | #include <asm/hd64461.h> |
| 16 | #include <asm/machvec_init.h> | ||
| 17 | |||
| 18 | #include <asm/io.h> | 13 | #include <asm/io.h> |
| 19 | #include <asm/hd64461/hd64461.h> | ||
| 20 | #include <asm/hp6xx/io.h> | ||
| 21 | #include <asm/irq.h> | 14 | #include <asm/irq.h> |
| 22 | 15 | ||
| 23 | struct sh_machine_vector mv_hp680 __initmv = { | 16 | struct sh_machine_vector mv_hp6xx __initmv = { |
| 24 | .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM, | 17 | .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM, |
| 25 | 18 | ||
| 26 | .mv_inb = hd64461_inb, | 19 | .mv_inb = hd64461_inb, |
| @@ -50,4 +43,4 @@ struct sh_machine_vector mv_hp680 __initmv = { | |||
| 50 | .mv_irq_demux = hd64461_irq_demux, | 43 | .mv_irq_demux = hd64461_irq_demux, |
| 51 | }; | 44 | }; |
| 52 | 45 | ||
| 53 | ALIAS_MV(hp680) | 46 | ALIAS_MV(hp6xx) |
diff --git a/arch/sh/boards/hp6xx/hp680/setup.c b/arch/sh/boards/hp6xx/setup.c index 4170190f2644..6d94a8e2e67a 100644 --- a/arch/sh/boards/hp6xx/hp680/setup.c +++ b/arch/sh/boards/hp6xx/setup.c | |||
| @@ -11,18 +11,19 @@ | |||
| 11 | 11 | ||
| 12 | #include <linux/config.h> | 12 | #include <linux/config.h> |
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <asm/hd64461/hd64461.h> | ||
| 15 | #include <asm/io.h> | 14 | #include <asm/io.h> |
| 15 | #include <asm/hd64461.h> | ||
| 16 | #include <asm/hp6xx/hp6xx.h> | 16 | #include <asm/hp6xx/hp6xx.h> |
| 17 | #include <asm/cpu/dac.h> | 17 | #include <asm/cpu/dac.h> |
| 18 | 18 | ||
| 19 | const char *get_system_type(void) | 19 | const char *get_system_type(void) |
| 20 | { | 20 | { |
| 21 | return "HP680"; | 21 | return "HP6xx"; |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | int __init platform_setup(void) | 24 | int __init platform_setup(void) |
| 25 | { | 25 | { |
| 26 | u8 v8; | ||
| 26 | u16 v; | 27 | u16 v; |
| 27 | v = inw(HD64461_STBCR); | 28 | v = inw(HD64461_STBCR); |
| 28 | v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST | | 29 | v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST | |
| @@ -30,12 +31,25 @@ int __init platform_setup(void) | |||
| 30 | HD64461_STBCR_SAFEST | HD64461_STBCR_SPC0ST | | 31 | HD64461_STBCR_SAFEST | HD64461_STBCR_SPC0ST | |
| 31 | HD64461_STBCR_SMIAST | HD64461_STBCR_SAFECKE_OST | | 32 | HD64461_STBCR_SMIAST | HD64461_STBCR_SAFECKE_OST | |
| 32 | HD64461_STBCR_SAFECKE_IST; | 33 | HD64461_STBCR_SAFECKE_IST; |
| 34 | #ifndef CONFIG_HD64461_ENABLER | ||
| 35 | v |= HD64461_STBCR_SPC1ST; | ||
| 36 | #endif | ||
| 33 | outw(v, HD64461_STBCR); | 37 | outw(v, HD64461_STBCR); |
| 34 | v = inw(HD64461_GPADR); | 38 | v = inw(HD64461_GPADR); |
| 35 | v |= HD64461_GPADR_SPEAKER | HD64461_GPADR_PCMCIA0; | 39 | v |= HD64461_GPADR_SPEAKER | HD64461_GPADR_PCMCIA0; |
| 36 | outw(v, HD64461_GPADR); | 40 | outw(v, HD64461_GPADR); |
| 37 | 41 | ||
| 42 | outw(HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, HD64461_PCC0GCR); | ||
| 43 | |||
| 44 | #ifndef CONFIG_HD64461_ENABLER | ||
| 45 | outw(HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, HD64461_PCC1GCR); | ||
| 46 | #endif | ||
| 47 | |||
| 48 | sh_dac_output(0, DAC_SPEAKER_VOLUME); | ||
| 38 | sh_dac_disable(DAC_SPEAKER_VOLUME); | 49 | sh_dac_disable(DAC_SPEAKER_VOLUME); |
| 50 | v8 = ctrl_inb(DACR); | ||
| 51 | v8 &= ~DACR_DAE; | ||
| 52 | ctrl_outb(v8,DACR); | ||
| 39 | 53 | ||
| 40 | return 0; | 54 | return 0; |
| 41 | } | 55 | } |
diff --git a/arch/sh/boards/overdrive/Makefile b/arch/sh/boards/overdrive/Makefile index 1762b59e9279..245f03baf762 100644 --- a/arch/sh/boards/overdrive/Makefile +++ b/arch/sh/boards/overdrive/Makefile | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | # Makefile for the STMicroelectronics Overdrive specific parts of the kernel | 2 | # Makefile for the STMicroelectronics Overdrive specific parts of the kernel |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-y := mach.o setup.o io.o irq.o led.o time.o | 5 | obj-y := mach.o setup.o io.o irq.o led.o |
| 6 | 6 | ||
| 7 | obj-$(CONFIG_PCI) += fpga.o galileo.o pcidma.o | 7 | obj-$(CONFIG_PCI) += fpga.o galileo.o pcidma.o |
| 8 | 8 | ||
diff --git a/arch/sh/boards/overdrive/setup.c b/arch/sh/boards/overdrive/setup.c index a36ce0284ed3..94f6165d33b8 100644 --- a/arch/sh/boards/overdrive/setup.c +++ b/arch/sh/boards/overdrive/setup.c | |||
| @@ -17,8 +17,6 @@ | |||
| 17 | #include <asm/overdrive/overdrive.h> | 17 | #include <asm/overdrive/overdrive.h> |
| 18 | #include <asm/overdrive/fpga.h> | 18 | #include <asm/overdrive/fpga.h> |
| 19 | 19 | ||
| 20 | extern void od_time_init(void); | ||
| 21 | |||
| 22 | const char *get_system_type(void) | 20 | const char *get_system_type(void) |
| 23 | { | 21 | { |
| 24 | return "SH7750 Overdrive"; | 22 | return "SH7750 Overdrive"; |
| @@ -31,11 +29,9 @@ int __init platform_setup(void) | |||
| 31 | { | 29 | { |
| 32 | #ifdef CONFIG_PCI | 30 | #ifdef CONFIG_PCI |
| 33 | init_overdrive_fpga(); | 31 | init_overdrive_fpga(); |
| 34 | galileo_init(); | 32 | galileo_init(); |
| 35 | #endif | 33 | #endif |
| 36 | 34 | ||
| 37 | board_time_init = od_time_init; | ||
| 38 | |||
| 39 | /* Enable RS232 receive buffers */ | 35 | /* Enable RS232 receive buffers */ |
| 40 | writel(0x1e, OVERDRIVE_CTRL); | 36 | writel(0x1e, OVERDRIVE_CTRL); |
| 41 | } | 37 | } |
diff --git a/arch/sh/boards/overdrive/time.c b/arch/sh/boards/overdrive/time.c deleted file mode 100644 index 68533690e097..000000000000 --- a/arch/sh/boards/overdrive/time.c +++ /dev/null | |||
| @@ -1,119 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * arch/sh/boards/overdrive/time.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) | ||
| 5 | * Copyright (C) 2002 Paul Mundt (lethal@chaoticdreams.org) | ||
| 6 | * | ||
| 7 | * May be copied or modified under the terms of the GNU General Public | ||
| 8 | * License. See linux/COPYING for more information. | ||
| 9 | * | ||
| 10 | * STMicroelectronics Overdrive Support. | ||
| 11 | */ | ||
| 12 | |||
| 13 | void od_time_init(void) | ||
| 14 | { | ||
| 15 | struct frqcr_data { | ||
| 16 | unsigned short frqcr; | ||
| 17 | struct { | ||
| 18 | unsigned char multiplier; | ||
| 19 | unsigned char divisor; | ||
| 20 | } factor[3]; | ||
| 21 | }; | ||
| 22 | |||
| 23 | static struct frqcr_data st40_frqcr_table[] = { | ||
| 24 | { 0x000, {{1,1}, {1,1}, {1,2}}}, | ||
| 25 | { 0x002, {{1,1}, {1,1}, {1,4}}}, | ||
| 26 | { 0x004, {{1,1}, {1,1}, {1,8}}}, | ||
| 27 | { 0x008, {{1,1}, {1,2}, {1,2}}}, | ||
| 28 | { 0x00A, {{1,1}, {1,2}, {1,4}}}, | ||
| 29 | { 0x00C, {{1,1}, {1,2}, {1,8}}}, | ||
| 30 | { 0x011, {{1,1}, {2,3}, {1,6}}}, | ||
| 31 | { 0x013, {{1,1}, {2,3}, {1,3}}}, | ||
| 32 | { 0x01A, {{1,1}, {1,2}, {1,4}}}, | ||
| 33 | { 0x01C, {{1,1}, {1,2}, {1,8}}}, | ||
| 34 | { 0x023, {{1,1}, {2,3}, {1,3}}}, | ||
| 35 | { 0x02C, {{1,1}, {1,2}, {1,8}}}, | ||
| 36 | { 0x048, {{1,2}, {1,2}, {1,4}}}, | ||
| 37 | { 0x04A, {{1,2}, {1,2}, {1,6}}}, | ||
| 38 | { 0x04C, {{1,2}, {1,2}, {1,8}}}, | ||
| 39 | { 0x05A, {{1,2}, {1,3}, {1,6}}}, | ||
| 40 | { 0x05C, {{1,2}, {1,3}, {1,6}}}, | ||
| 41 | { 0x063, {{1,2}, {1,4}, {1,4}}}, | ||
| 42 | { 0x06C, {{1,2}, {1,4}, {1,8}}}, | ||
| 43 | { 0x091, {{1,3}, {1,3}, {1,6}}}, | ||
| 44 | { 0x093, {{1,3}, {1,3}, {1,6}}}, | ||
| 45 | { 0x0A3, {{1,3}, {1,6}, {1,6}}}, | ||
| 46 | { 0x0DA, {{1,4}, {1,4}, {1,8}}}, | ||
| 47 | { 0x0DC, {{1,4}, {1,4}, {1,8}}}, | ||
| 48 | { 0x0EC, {{1,4}, {1,8}, {1,8}}}, | ||
| 49 | { 0x123, {{1,4}, {1,4}, {1,8}}}, | ||
| 50 | { 0x16C, {{1,4}, {1,8}, {1,8}}}, | ||
| 51 | }; | ||
| 52 | |||
| 53 | struct memclk_data { | ||
| 54 | unsigned char multiplier; | ||
| 55 | unsigned char divisor; | ||
| 56 | }; | ||
| 57 | static struct memclk_data st40_memclk_table[8] = { | ||
| 58 | {1,1}, // 000 | ||
| 59 | {1,2}, // 001 | ||
| 60 | {1,3}, // 010 | ||
| 61 | {2,3}, // 011 | ||
| 62 | {1,4}, // 100 | ||
| 63 | {1,6}, // 101 | ||
| 64 | {1,8}, // 110 | ||
| 65 | {1,8} // 111 | ||
| 66 | }; | ||
| 67 | |||
| 68 | unsigned long pvr; | ||
| 69 | |||
| 70 | /* | ||
| 71 | * This should probably be moved into the SH3 probing code, and then | ||
| 72 | * use the processor structure to determine which CPU we are running | ||
| 73 | * on. | ||
| 74 | */ | ||
| 75 | pvr = ctrl_inl(CCN_PVR); | ||
| 76 | printk("PVR %08x\n", pvr); | ||
| 77 | |||
| 78 | if (((pvr >> CCN_PVR_CHIP_SHIFT) & CCN_PVR_CHIP_MASK) == CCN_PVR_CHIP_ST40STB1) { | ||
| 79 | /* | ||
| 80 | * Unfortunatly the STB1 FRQCR values are different from the | ||
| 81 | * 7750 ones. | ||
| 82 | */ | ||
| 83 | struct frqcr_data *d; | ||
| 84 | int a; | ||
| 85 | unsigned long memclkcr; | ||
| 86 | struct memclk_data *e; | ||
| 87 | |||
| 88 | for (a=0; a<ARRAY_SIZE(st40_frqcr_table); a++) { | ||
| 89 | d = &st40_frqcr_table[a]; | ||
| 90 | if (d->frqcr == (frqcr & 0x1ff)) | ||
| 91 | break; | ||
| 92 | } | ||
| 93 | if (a == ARRAY_SIZE(st40_frqcr_table)) { | ||
| 94 | d = st40_frqcr_table; | ||
| 95 | printk("ERROR: Unrecognised FRQCR value, using default multipliers\n"); | ||
| 96 | } | ||
| 97 | |||
| 98 | memclkcr = ctrl_inl(CLOCKGEN_MEMCLKCR); | ||
| 99 | e = &st40_memclk_table[memclkcr & MEMCLKCR_RATIO_MASK]; | ||
| 100 | |||
| 101 | printk("Clock multipliers: CPU: %d/%d Bus: %d/%d Mem: %d/%d Periph: %d/%d\n", | ||
| 102 | d->factor[0].multiplier, d->factor[0].divisor, | ||
| 103 | d->factor[1].multiplier, d->factor[1].divisor, | ||
| 104 | e->multiplier, e->divisor, | ||
| 105 | d->factor[2].multiplier, d->factor[2].divisor); | ||
| 106 | |||
| 107 | current_cpu_data.master_clock = current_cpu_data.module_clock * | ||
| 108 | d->factor[2].divisor / | ||
| 109 | d->factor[2].multiplier; | ||
| 110 | current_cpu_data.bus_clock = current_cpu_data.master_clock * | ||
| 111 | d->factor[1].multiplier / | ||
| 112 | d->factor[1].divisor; | ||
| 113 | current_cpu_data.memory_clock = current_cpu_data.master_clock * | ||
| 114 | e->multiplier / e->divisor; | ||
| 115 | current_cpu_data.cpu_clock = current_cpu_data.master_clock * | ||
| 116 | d->factor[0].multiplier / | ||
| 117 | d->factor[0].divisor; | ||
| 118 | } | ||
| 119 | |||
diff --git a/arch/sh/configs/hp680_defconfig b/arch/sh/configs/hp6xx_defconfig index c85d3655b53c..b36f102cec81 100644 --- a/arch/sh/configs/hp680_defconfig +++ b/arch/sh/configs/hp6xx_defconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | # | 1 | # |
| 2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
| 3 | # Linux kernel version: 2.6.11-sh | 3 | # Linux kernel version: 2.6.15-sh |
| 4 | # Wed Mar 2 15:09:41 2005 | 4 | # Wed Jan 4 15:32:56 2006 |
| 5 | # | 5 | # |
| 6 | CONFIG_SUPERH=y | 6 | CONFIG_SUPERH=y |
| 7 | CONFIG_UID16=y | 7 | CONFIG_UID16=y |
| @@ -17,31 +17,36 @@ CONFIG_EXPERIMENTAL=y | |||
| 17 | # CONFIG_CLEAN_COMPILE is not set | 17 | # CONFIG_CLEAN_COMPILE is not set |
| 18 | CONFIG_BROKEN=y | 18 | CONFIG_BROKEN=y |
| 19 | CONFIG_BROKEN_ON_SMP=y | 19 | CONFIG_BROKEN_ON_SMP=y |
| 20 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
| 20 | 21 | ||
| 21 | # | 22 | # |
| 22 | # General setup | 23 | # General setup |
| 23 | # | 24 | # |
| 24 | CONFIG_LOCALVERSION="" | 25 | CONFIG_LOCALVERSION="" |
| 26 | CONFIG_LOCALVERSION_AUTO=y | ||
| 25 | CONFIG_SWAP=y | 27 | CONFIG_SWAP=y |
| 26 | # CONFIG_SYSVIPC is not set | 28 | # CONFIG_SYSVIPC is not set |
| 27 | # CONFIG_BSD_PROCESS_ACCT is not set | 29 | # CONFIG_BSD_PROCESS_ACCT is not set |
| 28 | # CONFIG_SYSCTL is not set | 30 | # CONFIG_SYSCTL is not set |
| 29 | # CONFIG_AUDIT is not set | 31 | CONFIG_HOTPLUG=y |
| 30 | CONFIG_LOG_BUF_SHIFT=14 | ||
| 31 | # CONFIG_HOTPLUG is not set | ||
| 32 | # CONFIG_IKCONFIG is not set | 32 | # CONFIG_IKCONFIG is not set |
| 33 | CONFIG_INITRAMFS_SOURCE="" | ||
| 34 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
| 33 | # CONFIG_EMBEDDED is not set | 35 | # CONFIG_EMBEDDED is not set |
| 34 | CONFIG_KALLSYMS=y | 36 | CONFIG_KALLSYMS=y |
| 35 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
| 38 | CONFIG_PRINTK=y | ||
| 39 | CONFIG_BUG=y | ||
| 40 | CONFIG_BASE_FULL=y | ||
| 36 | CONFIG_FUTEX=y | 41 | CONFIG_FUTEX=y |
| 37 | CONFIG_EPOLL=y | 42 | CONFIG_EPOLL=y |
| 38 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
| 39 | CONFIG_SHMEM=y | 43 | CONFIG_SHMEM=y |
| 40 | CONFIG_CC_ALIGN_FUNCTIONS=0 | 44 | CONFIG_CC_ALIGN_FUNCTIONS=0 |
| 41 | CONFIG_CC_ALIGN_LABELS=0 | 45 | CONFIG_CC_ALIGN_LABELS=0 |
| 42 | CONFIG_CC_ALIGN_LOOPS=0 | 46 | CONFIG_CC_ALIGN_LOOPS=0 |
| 43 | CONFIG_CC_ALIGN_JUMPS=0 | 47 | CONFIG_CC_ALIGN_JUMPS=0 |
| 44 | # CONFIG_TINY_SHMEM is not set | 48 | # CONFIG_TINY_SHMEM is not set |
| 49 | CONFIG_BASE_SMALL=0 | ||
| 45 | 50 | ||
| 46 | # | 51 | # |
| 47 | # Loadable module support | 52 | # Loadable module support |
| @@ -49,6 +54,24 @@ CONFIG_CC_ALIGN_JUMPS=0 | |||
| 49 | # CONFIG_MODULES is not set | 54 | # CONFIG_MODULES is not set |
| 50 | 55 | ||
| 51 | # | 56 | # |
| 57 | # Block layer | ||
| 58 | # | ||
| 59 | # CONFIG_LBD is not set | ||
| 60 | |||
| 61 | # | ||
| 62 | # IO Schedulers | ||
| 63 | # | ||
| 64 | CONFIG_IOSCHED_NOOP=y | ||
| 65 | CONFIG_IOSCHED_AS=y | ||
| 66 | CONFIG_IOSCHED_DEADLINE=y | ||
| 67 | CONFIG_IOSCHED_CFQ=y | ||
| 68 | CONFIG_DEFAULT_AS=y | ||
| 69 | # CONFIG_DEFAULT_DEADLINE is not set | ||
| 70 | # CONFIG_DEFAULT_CFQ is not set | ||
| 71 | # CONFIG_DEFAULT_NOOP is not set | ||
| 72 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
| 73 | |||
| 74 | # | ||
| 52 | # System type | 75 | # System type |
| 53 | # | 76 | # |
| 54 | # CONFIG_SH_SOLUTION_ENGINE is not set | 77 | # CONFIG_SH_SOLUTION_ENGINE is not set |
| @@ -58,9 +81,7 @@ CONFIG_CC_ALIGN_JUMPS=0 | |||
| 58 | # CONFIG_SH_7751_SYSTEMH is not set | 81 | # CONFIG_SH_7751_SYSTEMH is not set |
| 59 | # CONFIG_SH_STB1_HARP is not set | 82 | # CONFIG_SH_STB1_HARP is not set |
| 60 | # CONFIG_SH_STB1_OVERDRIVE is not set | 83 | # CONFIG_SH_STB1_OVERDRIVE is not set |
| 61 | # CONFIG_SH_HP620 is not set | 84 | CONFIG_SH_HP6XX=y |
| 62 | CONFIG_SH_HP680=y | ||
| 63 | # CONFIG_SH_HP690 is not set | ||
| 64 | # CONFIG_SH_CQREEK is not set | 85 | # CONFIG_SH_CQREEK is not set |
| 65 | # CONFIG_SH_DMIDA is not set | 86 | # CONFIG_SH_DMIDA is not set |
| 66 | # CONFIG_SH_EC3104 is not set | 87 | # CONFIG_SH_EC3104 is not set |
| @@ -77,43 +98,90 @@ CONFIG_SH_HP680=y | |||
| 77 | # CONFIG_SH_RTS7751R2D is not set | 98 | # CONFIG_SH_RTS7751R2D is not set |
| 78 | # CONFIG_SH_EDOSK7705 is not set | 99 | # CONFIG_SH_EDOSK7705 is not set |
| 79 | # CONFIG_SH_SH4202_MICRODEV is not set | 100 | # CONFIG_SH_SH4202_MICRODEV is not set |
| 101 | # CONFIG_SH_LANDISK is not set | ||
| 102 | # CONFIG_SH_TITAN is not set | ||
| 80 | # CONFIG_SH_UNKNOWN is not set | 103 | # CONFIG_SH_UNKNOWN is not set |
| 81 | # CONFIG_CPU_SH2 is not set | 104 | |
| 105 | # | ||
| 106 | # Processor selection | ||
| 107 | # | ||
| 82 | CONFIG_CPU_SH3=y | 108 | CONFIG_CPU_SH3=y |
| 83 | # CONFIG_CPU_SH4 is not set | 109 | |
| 110 | # | ||
| 111 | # SH-2 Processor Support | ||
| 112 | # | ||
| 84 | # CONFIG_CPU_SUBTYPE_SH7604 is not set | 113 | # CONFIG_CPU_SUBTYPE_SH7604 is not set |
| 114 | |||
| 115 | # | ||
| 116 | # SH-3 Processor Support | ||
| 117 | # | ||
| 85 | # CONFIG_CPU_SUBTYPE_SH7300 is not set | 118 | # CONFIG_CPU_SUBTYPE_SH7300 is not set |
| 86 | # CONFIG_CPU_SUBTYPE_SH7705 is not set | 119 | # CONFIG_CPU_SUBTYPE_SH7705 is not set |
| 87 | # CONFIG_CPU_SUBTYPE_SH7707 is not set | 120 | # CONFIG_CPU_SUBTYPE_SH7707 is not set |
| 88 | # CONFIG_CPU_SUBTYPE_SH7708 is not set | 121 | # CONFIG_CPU_SUBTYPE_SH7708 is not set |
| 89 | CONFIG_CPU_SUBTYPE_SH7709=y | 122 | CONFIG_CPU_SUBTYPE_SH7709=y |
| 123 | |||
| 124 | # | ||
| 125 | # SH-4 Processor Support | ||
| 126 | # | ||
| 90 | # CONFIG_CPU_SUBTYPE_SH7750 is not set | 127 | # CONFIG_CPU_SUBTYPE_SH7750 is not set |
| 128 | # CONFIG_CPU_SUBTYPE_SH7091 is not set | ||
| 129 | # CONFIG_CPU_SUBTYPE_SH7750R is not set | ||
| 130 | # CONFIG_CPU_SUBTYPE_SH7750S is not set | ||
| 91 | # CONFIG_CPU_SUBTYPE_SH7751 is not set | 131 | # CONFIG_CPU_SUBTYPE_SH7751 is not set |
| 132 | # CONFIG_CPU_SUBTYPE_SH7751R is not set | ||
| 92 | # CONFIG_CPU_SUBTYPE_SH7760 is not set | 133 | # CONFIG_CPU_SUBTYPE_SH7760 is not set |
| 93 | # CONFIG_CPU_SUBTYPE_SH73180 is not set | 134 | # CONFIG_CPU_SUBTYPE_SH4_202 is not set |
| 135 | |||
| 136 | # | ||
| 137 | # ST40 Processor Support | ||
| 138 | # | ||
| 94 | # CONFIG_CPU_SUBTYPE_ST40STB1 is not set | 139 | # CONFIG_CPU_SUBTYPE_ST40STB1 is not set |
| 95 | # CONFIG_CPU_SUBTYPE_ST40GX1 is not set | 140 | # CONFIG_CPU_SUBTYPE_ST40GX1 is not set |
| 96 | # CONFIG_CPU_SUBTYPE_SH4_202 is not set | 141 | |
| 142 | # | ||
| 143 | # SH-4A Processor Support | ||
| 144 | # | ||
| 145 | # CONFIG_CPU_SUBTYPE_SH73180 is not set | ||
| 146 | # CONFIG_CPU_SUBTYPE_SH7770 is not set | ||
| 147 | # CONFIG_CPU_SUBTYPE_SH7780 is not set | ||
| 148 | |||
| 149 | # | ||
| 150 | # Memory management options | ||
| 151 | # | ||
| 97 | CONFIG_MMU=y | 152 | CONFIG_MMU=y |
| 98 | # CONFIG_CMDLINE_BOOL is not set | 153 | CONFIG_SELECT_MEMORY_MODEL=y |
| 154 | CONFIG_FLATMEM_MANUAL=y | ||
| 155 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
| 156 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
| 157 | CONFIG_FLATMEM=y | ||
| 158 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
| 159 | # CONFIG_SPARSEMEM_STATIC is not set | ||
| 160 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
| 161 | |||
| 162 | # | ||
| 163 | # Cache configuration | ||
| 164 | # | ||
| 165 | # CONFIG_SH_DIRECT_MAPPED is not set | ||
| 166 | # CONFIG_SH_WRITETHROUGH is not set | ||
| 167 | # CONFIG_SH_OCRAM is not set | ||
| 99 | CONFIG_MEMORY_START=0x0c000000 | 168 | CONFIG_MEMORY_START=0x0c000000 |
| 100 | CONFIG_MEMORY_SIZE=0x00400000 | 169 | CONFIG_MEMORY_SIZE=0x00400000 |
| 101 | CONFIG_MEMORY_SET=y | 170 | |
| 102 | # CONFIG_MEMORY_OVERRIDE is not set | 171 | # |
| 172 | # Processor features | ||
| 173 | # | ||
| 174 | CONFIG_CPU_LITTLE_ENDIAN=y | ||
| 103 | CONFIG_SH_RTC=y | 175 | CONFIG_SH_RTC=y |
| 104 | # CONFIG_SH_DSP is not set | 176 | # CONFIG_SH_DSP is not set |
| 105 | CONFIG_SH_ADC=y | 177 | CONFIG_SH_ADC=y |
| 106 | CONFIG_SH_HP600=y | 178 | |
| 107 | CONFIG_ZERO_PAGE_OFFSET=0x00001000 | 179 | # |
| 108 | CONFIG_BOOT_LINK_OFFSET=0x00800000 | 180 | # Timer support |
| 109 | CONFIG_CPU_LITTLE_ENDIAN=y | 181 | # |
| 110 | # CONFIG_PREEMPT is not set | 182 | CONFIG_SH_TMU=y |
| 111 | # CONFIG_UBC_WAKEUP is not set | 183 | CONFIG_SH_PCLK_FREQ_BOOL=y |
| 112 | # CONFIG_SH_WRITETHROUGH is not set | 184 | CONFIG_SH_PCLK_FREQ=22110000 |
| 113 | # CONFIG_SH_OCRAM is not set | ||
| 114 | # CONFIG_SMP is not set | ||
| 115 | CONFIG_SH_PCLK_CALC=y | ||
| 116 | CONFIG_SH_PCLK_FREQ=1193182 | ||
| 117 | 185 | ||
| 118 | # | 186 | # |
| 119 | # CPU Frequency scaling | 187 | # CPU Frequency scaling |
| @@ -123,7 +191,10 @@ CONFIG_SH_PCLK_FREQ=1193182 | |||
| 123 | # | 191 | # |
| 124 | # DMA support | 192 | # DMA support |
| 125 | # | 193 | # |
| 126 | # CONFIG_SH_DMA is not set | 194 | CONFIG_SH_DMA=y |
| 195 | CONFIG_NR_ONCHIP_DMA_CHANNELS=4 | ||
| 196 | # CONFIG_NR_DMA_CHANNELS_BOOL is not set | ||
| 197 | # CONFIG_DMA_PAGE_OPS is not set | ||
| 127 | 198 | ||
| 128 | # | 199 | # |
| 129 | # Companion Chips | 200 | # Companion Chips |
| @@ -132,21 +203,47 @@ CONFIG_HD6446X_SERIES=y | |||
| 132 | CONFIG_HD64461=y | 203 | CONFIG_HD64461=y |
| 133 | # CONFIG_HD64465 is not set | 204 | # CONFIG_HD64465 is not set |
| 134 | CONFIG_HD64461_IRQ=36 | 205 | CONFIG_HD64461_IRQ=36 |
| 135 | # CONFIG_HD64461_ENABLER is not set | 206 | CONFIG_HD64461_IOBASE=0xb0000000 |
| 207 | CONFIG_HD64461_ENABLER=y | ||
| 208 | |||
| 209 | # | ||
| 210 | # Kernel features | ||
| 211 | # | ||
| 212 | # CONFIG_KEXEC is not set | ||
| 213 | # CONFIG_PREEMPT is not set | ||
| 214 | # CONFIG_SMP is not set | ||
| 136 | 215 | ||
| 137 | # | 216 | # |
| 138 | # Bus options (PCI, PCMCIA, EISA, MCA, ISA) | 217 | # Boot options |
| 139 | # | 218 | # |
| 219 | CONFIG_ZERO_PAGE_OFFSET=0x00001000 | ||
| 220 | CONFIG_BOOT_LINK_OFFSET=0x00800000 | ||
| 221 | # CONFIG_UBC_WAKEUP is not set | ||
| 222 | # CONFIG_CMDLINE_BOOL is not set | ||
| 223 | |||
| 224 | # | ||
| 225 | # Bus options | ||
| 226 | # | ||
| 227 | CONFIG_ISA=y | ||
| 140 | # CONFIG_PCI is not set | 228 | # CONFIG_PCI is not set |
| 141 | 229 | ||
| 142 | # | 230 | # |
| 143 | # PCCARD (PCMCIA/CardBus) support | 231 | # PCCARD (PCMCIA/CardBus) support |
| 144 | # | 232 | # |
| 145 | # CONFIG_PCCARD is not set | 233 | CONFIG_PCCARD=y |
| 234 | # CONFIG_PCMCIA_DEBUG is not set | ||
| 235 | CONFIG_PCMCIA=y | ||
| 236 | CONFIG_PCMCIA_LOAD_CIS=y | ||
| 237 | CONFIG_PCMCIA_IOCTL=y | ||
| 146 | 238 | ||
| 147 | # | 239 | # |
| 148 | # PC-card bridges | 240 | # PC-card bridges |
| 149 | # | 241 | # |
| 242 | # CONFIG_I82365 is not set | ||
| 243 | # CONFIG_TCIC is not set | ||
| 244 | CONFIG_HD64461_PCMCIA=y | ||
| 245 | CONFIG_HD64461_PCMCIA_SOCKETS=1 | ||
| 246 | CONFIG_PCMCIA_PROBE=y | ||
| 150 | 247 | ||
| 151 | # | 248 | # |
| 152 | # PCI Hotplug Support | 249 | # PCI Hotplug Support |
| @@ -160,9 +257,9 @@ CONFIG_BINFMT_ELF=y | |||
| 160 | # CONFIG_BINFMT_MISC is not set | 257 | # CONFIG_BINFMT_MISC is not set |
| 161 | 258 | ||
| 162 | # | 259 | # |
| 163 | # SH initrd options | 260 | # Networking |
| 164 | # | 261 | # |
| 165 | # CONFIG_EMBEDDED_RAMDISK is not set | 262 | # CONFIG_NET is not set |
| 166 | 263 | ||
| 167 | # | 264 | # |
| 168 | # Device Drivers | 265 | # Device Drivers |
| @@ -173,7 +270,11 @@ CONFIG_BINFMT_ELF=y | |||
| 173 | # | 270 | # |
| 174 | # CONFIG_STANDALONE is not set | 271 | # CONFIG_STANDALONE is not set |
| 175 | CONFIG_PREVENT_FIRMWARE_BUILD=y | 272 | CONFIG_PREVENT_FIRMWARE_BUILD=y |
| 176 | # CONFIG_FW_LOADER is not set | 273 | CONFIG_FW_LOADER=y |
| 274 | |||
| 275 | # | ||
| 276 | # Connector - unified userspace <-> kernelspace linker | ||
| 277 | # | ||
| 177 | 278 | ||
| 178 | # | 279 | # |
| 179 | # Memory Technology Devices (MTD) | 280 | # Memory Technology Devices (MTD) |
| @@ -188,30 +289,20 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y | |||
| 188 | # | 289 | # |
| 189 | # Plug and Play support | 290 | # Plug and Play support |
| 190 | # | 291 | # |
| 292 | # CONFIG_PNP is not set | ||
| 191 | 293 | ||
| 192 | # | 294 | # |
| 193 | # Block devices | 295 | # Block devices |
| 194 | # | 296 | # |
| 195 | # CONFIG_BLK_DEV_FD is not set | ||
| 196 | # CONFIG_BLK_DEV_COW_COMMON is not set | 297 | # CONFIG_BLK_DEV_COW_COMMON is not set |
| 197 | # CONFIG_BLK_DEV_LOOP is not set | 298 | # CONFIG_BLK_DEV_LOOP is not set |
| 198 | CONFIG_BLK_DEV_RAM=y | 299 | CONFIG_BLK_DEV_RAM=y |
| 199 | CONFIG_BLK_DEV_RAM_COUNT=16 | 300 | CONFIG_BLK_DEV_RAM_COUNT=16 |
| 200 | CONFIG_BLK_DEV_RAM_SIZE=4096 | 301 | CONFIG_BLK_DEV_RAM_SIZE=4096 |
| 201 | CONFIG_BLK_DEV_INITRD=y | 302 | CONFIG_BLK_DEV_INITRD=y |
| 202 | CONFIG_INITRAMFS_SOURCE="" | ||
| 203 | # CONFIG_LBD is not set | ||
| 204 | # CONFIG_CDROM_PKTCDVD is not set | 303 | # CONFIG_CDROM_PKTCDVD is not set |
| 205 | 304 | ||
| 206 | # | 305 | # |
| 207 | # IO Schedulers | ||
| 208 | # | ||
| 209 | CONFIG_IOSCHED_NOOP=y | ||
| 210 | CONFIG_IOSCHED_AS=y | ||
| 211 | CONFIG_IOSCHED_DEADLINE=y | ||
| 212 | CONFIG_IOSCHED_CFQ=y | ||
| 213 | |||
| 214 | # | ||
| 215 | # ATA/ATAPI/MFM/RLL support | 306 | # ATA/ATAPI/MFM/RLL support |
| 216 | # | 307 | # |
| 217 | CONFIG_IDE=y | 308 | CONFIG_IDE=y |
| @@ -224,6 +315,7 @@ CONFIG_BLK_DEV_IDE=y | |||
| 224 | # CONFIG_BLK_DEV_IDE_SATA is not set | 315 | # CONFIG_BLK_DEV_IDE_SATA is not set |
| 225 | CONFIG_BLK_DEV_IDEDISK=y | 316 | CONFIG_BLK_DEV_IDEDISK=y |
| 226 | # CONFIG_IDEDISK_MULTI_MODE is not set | 317 | # CONFIG_IDEDISK_MULTI_MODE is not set |
| 318 | # CONFIG_BLK_DEV_IDECS is not set | ||
| 227 | # CONFIG_BLK_DEV_IDECD is not set | 319 | # CONFIG_BLK_DEV_IDECD is not set |
| 228 | # CONFIG_BLK_DEV_IDETAPE is not set | 320 | # CONFIG_BLK_DEV_IDETAPE is not set |
| 229 | # CONFIG_BLK_DEV_IDEFLOPPY is not set | 321 | # CONFIG_BLK_DEV_IDEFLOPPY is not set |
| @@ -235,6 +327,7 @@ CONFIG_BLK_DEV_IDEDISK=y | |||
| 235 | CONFIG_IDE_GENERIC=y | 327 | CONFIG_IDE_GENERIC=y |
| 236 | CONFIG_IDE_SH=y | 328 | CONFIG_IDE_SH=y |
| 237 | # CONFIG_IDE_ARM is not set | 329 | # CONFIG_IDE_ARM is not set |
| 330 | # CONFIG_IDE_CHIPSETS is not set | ||
| 238 | # CONFIG_BLK_DEV_IDEDMA is not set | 331 | # CONFIG_BLK_DEV_IDEDMA is not set |
| 239 | # CONFIG_IDEDMA_AUTO is not set | 332 | # CONFIG_IDEDMA_AUTO is not set |
| 240 | # CONFIG_BLK_DEV_HD is not set | 333 | # CONFIG_BLK_DEV_HD is not set |
| @@ -242,9 +335,15 @@ CONFIG_IDE_SH=y | |||
| 242 | # | 335 | # |
| 243 | # SCSI device support | 336 | # SCSI device support |
| 244 | # | 337 | # |
| 338 | # CONFIG_RAID_ATTRS is not set | ||
| 245 | # CONFIG_SCSI is not set | 339 | # CONFIG_SCSI is not set |
| 246 | 340 | ||
| 247 | # | 341 | # |
| 342 | # Old CD-ROM drivers (not SCSI, not IDE) | ||
| 343 | # | ||
| 344 | # CONFIG_CD_NO_IDESCSI is not set | ||
| 345 | |||
| 346 | # | ||
| 248 | # Multi-device support (RAID and LVM) | 347 | # Multi-device support (RAID and LVM) |
| 249 | # | 348 | # |
| 250 | # CONFIG_MD is not set | 349 | # CONFIG_MD is not set |
| @@ -252,6 +351,7 @@ CONFIG_IDE_SH=y | |||
| 252 | # | 351 | # |
| 253 | # Fusion MPT device support | 352 | # Fusion MPT device support |
| 254 | # | 353 | # |
| 354 | # CONFIG_FUSION is not set | ||
| 255 | 355 | ||
| 256 | # | 356 | # |
| 257 | # IEEE 1394 (FireWire) support | 357 | # IEEE 1394 (FireWire) support |
| @@ -263,9 +363,8 @@ CONFIG_IDE_SH=y | |||
| 263 | # | 363 | # |
| 264 | 364 | ||
| 265 | # | 365 | # |
| 266 | # Networking support | 366 | # Network device support |
| 267 | # | 367 | # |
| 268 | # CONFIG_NET is not set | ||
| 269 | # CONFIG_NETPOLL is not set | 368 | # CONFIG_NETPOLL is not set |
| 270 | # CONFIG_NET_POLL_CONTROLLER is not set | 369 | # CONFIG_NET_POLL_CONTROLLER is not set |
| 271 | 370 | ||
| @@ -296,17 +395,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
| 296 | # CONFIG_INPUT_EVBUG is not set | 395 | # CONFIG_INPUT_EVBUG is not set |
| 297 | 396 | ||
| 298 | # | 397 | # |
| 299 | # Input I/O drivers | ||
| 300 | # | ||
| 301 | # CONFIG_GAMEPORT is not set | ||
| 302 | CONFIG_SOUND_GAMEPORT=y | ||
| 303 | CONFIG_SERIO=y | ||
| 304 | # CONFIG_SERIO_I8042 is not set | ||
| 305 | # CONFIG_SERIO_SERPORT is not set | ||
| 306 | # CONFIG_SERIO_CT82C710 is not set | ||
| 307 | # CONFIG_SERIO_RAW is not set | ||
| 308 | |||
| 309 | # | ||
| 310 | # Input Device Drivers | 398 | # Input Device Drivers |
| 311 | # | 399 | # |
| 312 | # CONFIG_INPUT_KEYBOARD is not set | 400 | # CONFIG_INPUT_KEYBOARD is not set |
| @@ -316,6 +404,15 @@ CONFIG_SERIO=y | |||
| 316 | # CONFIG_INPUT_MISC is not set | 404 | # CONFIG_INPUT_MISC is not set |
| 317 | 405 | ||
| 318 | # | 406 | # |
| 407 | # Hardware I/O ports | ||
| 408 | # | ||
| 409 | CONFIG_SERIO=y | ||
| 410 | # CONFIG_SERIO_I8042 is not set | ||
| 411 | # CONFIG_SERIO_SERPORT is not set | ||
| 412 | # CONFIG_SERIO_RAW is not set | ||
| 413 | # CONFIG_GAMEPORT is not set | ||
| 414 | |||
| 415 | # | ||
| 319 | # Character devices | 416 | # Character devices |
| 320 | # | 417 | # |
| 321 | CONFIG_VT=y | 418 | CONFIG_VT=y |
| @@ -353,10 +450,22 @@ CONFIG_LEGACY_PTY_COUNT=256 | |||
| 353 | # | 450 | # |
| 354 | # Ftape, the floppy tape device driver | 451 | # Ftape, the floppy tape device driver |
| 355 | # | 452 | # |
| 356 | # CONFIG_DRM is not set | 453 | |
| 454 | # | ||
| 455 | # PCMCIA character devices | ||
| 456 | # | ||
| 457 | # CONFIG_SYNCLINK_CS is not set | ||
| 458 | # CONFIG_CARDMAN_4000 is not set | ||
| 459 | # CONFIG_CARDMAN_4040 is not set | ||
| 357 | # CONFIG_RAW_DRIVER is not set | 460 | # CONFIG_RAW_DRIVER is not set |
| 358 | 461 | ||
| 359 | # | 462 | # |
| 463 | # TPM devices | ||
| 464 | # | ||
| 465 | # CONFIG_TCG_TPM is not set | ||
| 466 | # CONFIG_TELCLOCK is not set | ||
| 467 | |||
| 468 | # | ||
| 360 | # I2C support | 469 | # I2C support |
| 361 | # | 470 | # |
| 362 | # CONFIG_I2C is not set | 471 | # CONFIG_I2C is not set |
| @@ -367,10 +476,21 @@ CONFIG_LEGACY_PTY_COUNT=256 | |||
| 367 | # CONFIG_W1 is not set | 476 | # CONFIG_W1 is not set |
| 368 | 477 | ||
| 369 | # | 478 | # |
| 479 | # Hardware Monitoring support | ||
| 480 | # | ||
| 481 | CONFIG_HWMON=y | ||
| 482 | # CONFIG_HWMON_VID is not set | ||
| 483 | # CONFIG_HWMON_DEBUG_CHIP is not set | ||
| 484 | |||
| 485 | # | ||
| 370 | # Misc devices | 486 | # Misc devices |
| 371 | # | 487 | # |
| 372 | 488 | ||
| 373 | # | 489 | # |
| 490 | # Multimedia Capabilities Port drivers | ||
| 491 | # | ||
| 492 | |||
| 493 | # | ||
| 374 | # Multimedia devices | 494 | # Multimedia devices |
| 375 | # | 495 | # |
| 376 | # CONFIG_VIDEO_DEV is not set | 496 | # CONFIG_VIDEO_DEV is not set |
| @@ -383,27 +503,35 @@ CONFIG_LEGACY_PTY_COUNT=256 | |||
| 383 | # Graphics support | 503 | # Graphics support |
| 384 | # | 504 | # |
| 385 | CONFIG_FB=y | 505 | CONFIG_FB=y |
| 506 | CONFIG_FB_CFB_FILLRECT=y | ||
| 507 | CONFIG_FB_CFB_COPYAREA=y | ||
| 508 | CONFIG_FB_CFB_IMAGEBLIT=y | ||
| 509 | # CONFIG_FB_MACMODES is not set | ||
| 386 | # CONFIG_FB_MODE_HELPERS is not set | 510 | # CONFIG_FB_MODE_HELPERS is not set |
| 387 | # CONFIG_FB_TILEBLITTING is not set | 511 | # CONFIG_FB_TILEBLITTING is not set |
| 388 | # CONFIG_FB_EPSON1355 is not set | 512 | # CONFIG_FB_EPSON1355 is not set |
| 513 | # CONFIG_FB_S1D13XXX is not set | ||
| 389 | CONFIG_FB_HIT=y | 514 | CONFIG_FB_HIT=y |
| 390 | # CONFIG_FB_VIRTUAL is not set | 515 | # CONFIG_FB_VIRTUAL is not set |
| 391 | 516 | ||
| 392 | # | 517 | # |
| 393 | # Console display driver support | 518 | # Console display driver support |
| 394 | # | 519 | # |
| 395 | # CONFIG_VGA_CONSOLE is not set | 520 | # CONFIG_MDA_CONSOLE is not set |
| 396 | CONFIG_DUMMY_CONSOLE=y | 521 | CONFIG_DUMMY_CONSOLE=y |
| 397 | CONFIG_FRAMEBUFFER_CONSOLE=y | 522 | CONFIG_FRAMEBUFFER_CONSOLE=y |
| 523 | # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set | ||
| 398 | CONFIG_FONTS=y | 524 | CONFIG_FONTS=y |
| 399 | # CONFIG_FONT_8x8 is not set | 525 | # CONFIG_FONT_8x8 is not set |
| 400 | # CONFIG_FONT_8x16 is not set | 526 | # CONFIG_FONT_8x16 is not set |
| 401 | # CONFIG_FONT_6x11 is not set | 527 | # CONFIG_FONT_6x11 is not set |
| 528 | # CONFIG_FONT_7x14 is not set | ||
| 402 | CONFIG_FONT_PEARL_8x8=y | 529 | CONFIG_FONT_PEARL_8x8=y |
| 403 | # CONFIG_FONT_ACORN_8x8 is not set | 530 | # CONFIG_FONT_ACORN_8x8 is not set |
| 404 | # CONFIG_FONT_MINI_4x6 is not set | 531 | # CONFIG_FONT_MINI_4x6 is not set |
| 405 | # CONFIG_FONT_SUN8x16 is not set | 532 | # CONFIG_FONT_SUN8x16 is not set |
| 406 | # CONFIG_FONT_SUN12x22 is not set | 533 | # CONFIG_FONT_SUN12x22 is not set |
| 534 | # CONFIG_FONT_10x18 is not set | ||
| 407 | 535 | ||
| 408 | # | 536 | # |
| 409 | # Logo configuration | 537 | # Logo configuration |
| @@ -414,7 +542,22 @@ CONFIG_FONT_PEARL_8x8=y | |||
| 414 | # | 542 | # |
| 415 | # Sound | 543 | # Sound |
| 416 | # | 544 | # |
| 417 | # CONFIG_SOUND is not set | 545 | CONFIG_SOUND=y |
| 546 | |||
| 547 | # | ||
| 548 | # Advanced Linux Sound Architecture | ||
| 549 | # | ||
| 550 | # CONFIG_SND is not set | ||
| 551 | |||
| 552 | # | ||
| 553 | # Open Sound System | ||
| 554 | # | ||
| 555 | CONFIG_SOUND_PRIME=y | ||
| 556 | # CONFIG_OBSOLETE_OSS_DRIVER is not set | ||
| 557 | # CONFIG_SOUND_MSNDCLAS is not set | ||
| 558 | # CONFIG_SOUND_MSNDPIN is not set | ||
| 559 | CONFIG_SOUND_SH_DAC_AUDIO=y | ||
| 560 | CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL=1 | ||
| 418 | 561 | ||
| 419 | # | 562 | # |
| 420 | # USB support | 563 | # USB support |
| @@ -423,7 +566,7 @@ CONFIG_FONT_PEARL_8x8=y | |||
| 423 | # CONFIG_USB_ARCH_HAS_OHCI is not set | 566 | # CONFIG_USB_ARCH_HAS_OHCI is not set |
| 424 | 567 | ||
| 425 | # | 568 | # |
| 426 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information | 569 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' |
| 427 | # | 570 | # |
| 428 | 571 | ||
| 429 | # | 572 | # |
| @@ -442,25 +585,29 @@ CONFIG_FONT_PEARL_8x8=y | |||
| 442 | # CONFIG_INFINIBAND is not set | 585 | # CONFIG_INFINIBAND is not set |
| 443 | 586 | ||
| 444 | # | 587 | # |
| 588 | # SN Devices | ||
| 589 | # | ||
| 590 | |||
| 591 | # | ||
| 445 | # File systems | 592 | # File systems |
| 446 | # | 593 | # |
| 447 | CONFIG_EXT2_FS=y | 594 | CONFIG_EXT2_FS=y |
| 448 | # CONFIG_EXT2_FS_XATTR is not set | 595 | # CONFIG_EXT2_FS_XATTR is not set |
| 596 | # CONFIG_EXT2_FS_XIP is not set | ||
| 449 | # CONFIG_EXT3_FS is not set | 597 | # CONFIG_EXT3_FS is not set |
| 450 | # CONFIG_JBD is not set | 598 | # CONFIG_JBD is not set |
| 451 | # CONFIG_REISERFS_FS is not set | 599 | # CONFIG_REISERFS_FS is not set |
| 452 | # CONFIG_JFS_FS is not set | 600 | # CONFIG_JFS_FS is not set |
| 453 | 601 | # CONFIG_FS_POSIX_ACL is not set | |
| 454 | # | ||
| 455 | # XFS support | ||
| 456 | # | ||
| 457 | # CONFIG_XFS_FS is not set | 602 | # CONFIG_XFS_FS is not set |
| 458 | # CONFIG_MINIX_FS is not set | 603 | # CONFIG_MINIX_FS is not set |
| 459 | # CONFIG_ROMFS_FS is not set | 604 | # CONFIG_ROMFS_FS is not set |
| 605 | CONFIG_INOTIFY=y | ||
| 460 | # CONFIG_QUOTA is not set | 606 | # CONFIG_QUOTA is not set |
| 461 | CONFIG_DNOTIFY=y | 607 | CONFIG_DNOTIFY=y |
| 462 | # CONFIG_AUTOFS_FS is not set | 608 | # CONFIG_AUTOFS_FS is not set |
| 463 | # CONFIG_AUTOFS4_FS is not set | 609 | # CONFIG_AUTOFS4_FS is not set |
| 610 | # CONFIG_FUSE_FS is not set | ||
| 464 | 611 | ||
| 465 | # | 612 | # |
| 466 | # CD-ROM/DVD Filesystems | 613 | # CD-ROM/DVD Filesystems |
| @@ -471,8 +618,11 @@ CONFIG_DNOTIFY=y | |||
| 471 | # | 618 | # |
| 472 | # DOS/FAT/NT Filesystems | 619 | # DOS/FAT/NT Filesystems |
| 473 | # | 620 | # |
| 621 | CONFIG_FAT_FS=y | ||
| 474 | # CONFIG_MSDOS_FS is not set | 622 | # CONFIG_MSDOS_FS is not set |
| 475 | # CONFIG_VFAT_FS is not set | 623 | CONFIG_VFAT_FS=y |
| 624 | CONFIG_FAT_DEFAULT_CODEPAGE=437 | ||
| 625 | CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" | ||
| 476 | # CONFIG_NTFS_FS is not set | 626 | # CONFIG_NTFS_FS is not set |
| 477 | 627 | ||
| 478 | # | 628 | # |
| @@ -481,14 +631,11 @@ CONFIG_DNOTIFY=y | |||
| 481 | CONFIG_PROC_FS=y | 631 | CONFIG_PROC_FS=y |
| 482 | CONFIG_PROC_KCORE=y | 632 | CONFIG_PROC_KCORE=y |
| 483 | CONFIG_SYSFS=y | 633 | CONFIG_SYSFS=y |
| 484 | CONFIG_DEVFS_FS=y | ||
| 485 | CONFIG_DEVFS_MOUNT=y | ||
| 486 | # CONFIG_DEVFS_DEBUG is not set | ||
| 487 | # CONFIG_DEVPTS_FS_XATTR is not set | ||
| 488 | # CONFIG_TMPFS is not set | 634 | # CONFIG_TMPFS is not set |
| 489 | # CONFIG_HUGETLBFS is not set | 635 | # CONFIG_HUGETLBFS is not set |
| 490 | # CONFIG_HUGETLB_PAGE is not set | 636 | # CONFIG_HUGETLB_PAGE is not set |
| 491 | CONFIG_RAMFS=y | 637 | CONFIG_RAMFS=y |
| 638 | # CONFIG_RELAYFS_FS is not set | ||
| 492 | 639 | ||
| 493 | # | 640 | # |
| 494 | # Miscellaneous filesystems | 641 | # Miscellaneous filesystems |
| @@ -516,7 +663,46 @@ CONFIG_MSDOS_PARTITION=y | |||
| 516 | # | 663 | # |
| 517 | # Native Language Support | 664 | # Native Language Support |
| 518 | # | 665 | # |
| 519 | # CONFIG_NLS is not set | 666 | CONFIG_NLS=y |
| 667 | CONFIG_NLS_DEFAULT="iso8859-1" | ||
| 668 | # CONFIG_NLS_CODEPAGE_437 is not set | ||
| 669 | # CONFIG_NLS_CODEPAGE_737 is not set | ||
| 670 | # CONFIG_NLS_CODEPAGE_775 is not set | ||
| 671 | # CONFIG_NLS_CODEPAGE_850 is not set | ||
| 672 | # CONFIG_NLS_CODEPAGE_852 is not set | ||
| 673 | # CONFIG_NLS_CODEPAGE_855 is not set | ||
| 674 | # CONFIG_NLS_CODEPAGE_857 is not set | ||
| 675 | # CONFIG_NLS_CODEPAGE_860 is not set | ||
| 676 | # CONFIG_NLS_CODEPAGE_861 is not set | ||
| 677 | # CONFIG_NLS_CODEPAGE_862 is not set | ||
| 678 | # CONFIG_NLS_CODEPAGE_863 is not set | ||
| 679 | # CONFIG_NLS_CODEPAGE_864 is not set | ||
| 680 | # CONFIG_NLS_CODEPAGE_865 is not set | ||
| 681 | # CONFIG_NLS_CODEPAGE_866 is not set | ||
| 682 | # CONFIG_NLS_CODEPAGE_869 is not set | ||
| 683 | # CONFIG_NLS_CODEPAGE_936 is not set | ||
| 684 | # CONFIG_NLS_CODEPAGE_950 is not set | ||
| 685 | # CONFIG_NLS_CODEPAGE_932 is not set | ||
| 686 | # CONFIG_NLS_CODEPAGE_949 is not set | ||
| 687 | # CONFIG_NLS_CODEPAGE_874 is not set | ||
| 688 | # CONFIG_NLS_ISO8859_8 is not set | ||
| 689 | # CONFIG_NLS_CODEPAGE_1250 is not set | ||
| 690 | # CONFIG_NLS_CODEPAGE_1251 is not set | ||
| 691 | # CONFIG_NLS_ASCII is not set | ||
| 692 | # CONFIG_NLS_ISO8859_1 is not set | ||
| 693 | # CONFIG_NLS_ISO8859_2 is not set | ||
| 694 | # CONFIG_NLS_ISO8859_3 is not set | ||
| 695 | # CONFIG_NLS_ISO8859_4 is not set | ||
| 696 | # CONFIG_NLS_ISO8859_5 is not set | ||
| 697 | # CONFIG_NLS_ISO8859_6 is not set | ||
| 698 | # CONFIG_NLS_ISO8859_7 is not set | ||
| 699 | # CONFIG_NLS_ISO8859_9 is not set | ||
| 700 | # CONFIG_NLS_ISO8859_13 is not set | ||
| 701 | # CONFIG_NLS_ISO8859_14 is not set | ||
| 702 | # CONFIG_NLS_ISO8859_15 is not set | ||
| 703 | # CONFIG_NLS_KOI8_R is not set | ||
| 704 | # CONFIG_NLS_KOI8_U is not set | ||
| 705 | # CONFIG_NLS_UTF8 is not set | ||
| 520 | 706 | ||
| 521 | # | 707 | # |
| 522 | # Profiling support | 708 | # Profiling support |
| @@ -526,7 +712,9 @@ CONFIG_MSDOS_PARTITION=y | |||
| 526 | # | 712 | # |
| 527 | # Kernel hacking | 713 | # Kernel hacking |
| 528 | # | 714 | # |
| 715 | # CONFIG_PRINTK_TIME is not set | ||
| 529 | # CONFIG_DEBUG_KERNEL is not set | 716 | # CONFIG_DEBUG_KERNEL is not set |
| 717 | CONFIG_LOG_BUF_SHIFT=14 | ||
| 530 | # CONFIG_FRAME_POINTER is not set | 718 | # CONFIG_FRAME_POINTER is not set |
| 531 | # CONFIG_SH_STANDARD_BIOS is not set | 719 | # CONFIG_SH_STANDARD_BIOS is not set |
| 532 | # CONFIG_KGDB is not set | 720 | # CONFIG_KGDB is not set |
| @@ -550,5 +738,6 @@ CONFIG_MSDOS_PARTITION=y | |||
| 550 | # Library routines | 738 | # Library routines |
| 551 | # | 739 | # |
| 552 | # CONFIG_CRC_CCITT is not set | 740 | # CONFIG_CRC_CCITT is not set |
| 741 | # CONFIG_CRC16 is not set | ||
| 553 | CONFIG_CRC32=y | 742 | CONFIG_CRC32=y |
| 554 | # CONFIG_LIBCRC32C is not set | 743 | # CONFIG_LIBCRC32C is not set |
diff --git a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c index 96e3036ec2bb..47c3e837599b 100644 --- a/arch/sh/drivers/dma/dma-api.c +++ b/arch/sh/drivers/dma/dma-api.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * SuperH-specific DMA management API | 4 | * SuperH-specific DMA management API |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2003, 2004 Paul Mundt | 6 | * Copyright (C) 2003, 2004, 2005 Paul Mundt |
| 7 | * | 7 | * |
| 8 | * This file is subject to the terms and conditions of the GNU General Public | 8 | * This file is subject to the terms and conditions of the GNU General Public |
| 9 | * License. See the file "COPYING" in the main directory of this archive | 9 | * License. See the file "COPYING" in the main directory of this archive |
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/spinlock.h> | 15 | #include <linux/spinlock.h> |
| 16 | #include <linux/proc_fs.h> | 16 | #include <linux/proc_fs.h> |
| 17 | #include <linux/list.h> | 17 | #include <linux/list.h> |
| 18 | #include <linux/platform_device.h> | ||
| 18 | #include <asm/dma.h> | 19 | #include <asm/dma.h> |
| 19 | 20 | ||
| 20 | DEFINE_SPINLOCK(dma_spin_lock); | 21 | DEFINE_SPINLOCK(dma_spin_lock); |
| @@ -55,16 +56,14 @@ static LIST_HEAD(registered_dmac_list); | |||
| 55 | 56 | ||
| 56 | struct dma_info *get_dma_info(unsigned int chan) | 57 | struct dma_info *get_dma_info(unsigned int chan) |
| 57 | { | 58 | { |
| 58 | struct list_head *pos, *tmp; | 59 | struct dma_info *info; |
| 59 | unsigned int total = 0; | 60 | unsigned int total = 0; |
| 60 | 61 | ||
| 61 | /* | 62 | /* |
| 62 | * Look for each DMAC's range to determine who the owner of | 63 | * Look for each DMAC's range to determine who the owner of |
| 63 | * the channel is. | 64 | * the channel is. |
| 64 | */ | 65 | */ |
| 65 | list_for_each_safe(pos, tmp, ®istered_dmac_list) { | 66 | list_for_each_entry(info, ®istered_dmac_list, list) { |
| 66 | struct dma_info *info = list_entry(pos, struct dma_info, list); | ||
| 67 | |||
| 68 | total += info->nr_channels; | 67 | total += info->nr_channels; |
| 69 | if (chan > total) | 68 | if (chan > total) |
| 70 | continue; | 69 | continue; |
| @@ -75,6 +74,20 @@ struct dma_info *get_dma_info(unsigned int chan) | |||
| 75 | return NULL; | 74 | return NULL; |
| 76 | } | 75 | } |
| 77 | 76 | ||
| 77 | static unsigned int get_nr_channels(void) | ||
| 78 | { | ||
| 79 | struct dma_info *info; | ||
| 80 | unsigned int nr = 0; | ||
| 81 | |||
| 82 | if (unlikely(list_empty(®istered_dmac_list))) | ||
| 83 | return nr; | ||
| 84 | |||
| 85 | list_for_each_entry(info, ®istered_dmac_list, list) | ||
| 86 | nr += info->nr_channels; | ||
| 87 | |||
| 88 | return nr; | ||
| 89 | } | ||
| 90 | |||
| 78 | struct dma_channel *get_dma_channel(unsigned int chan) | 91 | struct dma_channel *get_dma_channel(unsigned int chan) |
| 79 | { | 92 | { |
| 80 | struct dma_info *info = get_dma_info(chan); | 93 | struct dma_info *info = get_dma_info(chan); |
| @@ -173,7 +186,7 @@ int dma_xfer(unsigned int chan, unsigned long from, | |||
| 173 | static int dma_read_proc(char *buf, char **start, off_t off, | 186 | static int dma_read_proc(char *buf, char **start, off_t off, |
| 174 | int len, int *eof, void *data) | 187 | int len, int *eof, void *data) |
| 175 | { | 188 | { |
| 176 | struct list_head *pos, *tmp; | 189 | struct dma_info *info; |
| 177 | char *p = buf; | 190 | char *p = buf; |
| 178 | 191 | ||
| 179 | if (list_empty(®istered_dmac_list)) | 192 | if (list_empty(®istered_dmac_list)) |
| @@ -182,8 +195,7 @@ static int dma_read_proc(char *buf, char **start, off_t off, | |||
| 182 | /* | 195 | /* |
| 183 | * Iterate over each registered DMAC | 196 | * Iterate over each registered DMAC |
| 184 | */ | 197 | */ |
| 185 | list_for_each_safe(pos, tmp, ®istered_dmac_list) { | 198 | list_for_each_entry(info, ®istered_dmac_list, list) { |
| 186 | struct dma_info *info = list_entry(pos, struct dma_info, list); | ||
| 187 | int i; | 199 | int i; |
| 188 | 200 | ||
| 189 | /* | 201 | /* |
| @@ -205,9 +217,9 @@ static int dma_read_proc(char *buf, char **start, off_t off, | |||
| 205 | #endif | 217 | #endif |
| 206 | 218 | ||
| 207 | 219 | ||
| 208 | int __init register_dmac(struct dma_info *info) | 220 | int register_dmac(struct dma_info *info) |
| 209 | { | 221 | { |
| 210 | int i; | 222 | unsigned int total_channels, i; |
| 211 | 223 | ||
| 212 | INIT_LIST_HEAD(&info->list); | 224 | INIT_LIST_HEAD(&info->list); |
| 213 | 225 | ||
| @@ -217,6 +229,11 @@ int __init register_dmac(struct dma_info *info) | |||
| 217 | 229 | ||
| 218 | BUG_ON((info->flags & DMAC_CHANNELS_CONFIGURED) && !info->channels); | 230 | BUG_ON((info->flags & DMAC_CHANNELS_CONFIGURED) && !info->channels); |
| 219 | 231 | ||
| 232 | info->pdev = platform_device_register_simple((char *)info->name, -1, | ||
| 233 | NULL, 0); | ||
| 234 | if (IS_ERR(info->pdev)) | ||
| 235 | return PTR_ERR(info->pdev); | ||
| 236 | |||
| 220 | /* | 237 | /* |
| 221 | * Don't touch pre-configured channels | 238 | * Don't touch pre-configured channels |
| 222 | */ | 239 | */ |
| @@ -232,10 +249,12 @@ int __init register_dmac(struct dma_info *info) | |||
| 232 | memset(info->channels, 0, size); | 249 | memset(info->channels, 0, size); |
| 233 | } | 250 | } |
| 234 | 251 | ||
| 252 | total_channels = get_nr_channels(); | ||
| 235 | for (i = 0; i < info->nr_channels; i++) { | 253 | for (i = 0; i < info->nr_channels; i++) { |
| 236 | struct dma_channel *chan = info->channels + i; | 254 | struct dma_channel *chan = info->channels + i; |
| 237 | 255 | ||
| 238 | chan->chan = i; | 256 | chan->chan = i; |
| 257 | chan->vchan = i + total_channels; | ||
| 239 | 258 | ||
| 240 | memcpy(chan->dev_id, "Unused", 7); | 259 | memcpy(chan->dev_id, "Unused", 7); |
| 241 | 260 | ||
| @@ -245,9 +264,7 @@ int __init register_dmac(struct dma_info *info) | |||
| 245 | init_MUTEX(&chan->sem); | 264 | init_MUTEX(&chan->sem); |
| 246 | init_waitqueue_head(&chan->wait_queue); | 265 | init_waitqueue_head(&chan->wait_queue); |
| 247 | 266 | ||
| 248 | #ifdef CONFIG_SYSFS | 267 | dma_create_sysfs_files(chan, info); |
| 249 | dma_create_sysfs_files(chan); | ||
| 250 | #endif | ||
| 251 | } | 268 | } |
| 252 | 269 | ||
| 253 | list_add(&info->list, ®istered_dmac_list); | 270 | list_add(&info->list, ®istered_dmac_list); |
| @@ -255,12 +272,18 @@ int __init register_dmac(struct dma_info *info) | |||
| 255 | return 0; | 272 | return 0; |
| 256 | } | 273 | } |
| 257 | 274 | ||
| 258 | void __exit unregister_dmac(struct dma_info *info) | 275 | void unregister_dmac(struct dma_info *info) |
| 259 | { | 276 | { |
| 277 | unsigned int i; | ||
| 278 | |||
| 279 | for (i = 0; i < info->nr_channels; i++) | ||
| 280 | dma_remove_sysfs_files(info->channels + i, info); | ||
| 281 | |||
| 260 | if (!(info->flags & DMAC_CHANNELS_CONFIGURED)) | 282 | if (!(info->flags & DMAC_CHANNELS_CONFIGURED)) |
| 261 | kfree(info->channels); | 283 | kfree(info->channels); |
| 262 | 284 | ||
| 263 | list_del(&info->list); | 285 | list_del(&info->list); |
| 286 | platform_device_unregister(info->pdev); | ||
| 264 | } | 287 | } |
| 265 | 288 | ||
| 266 | static int __init dma_api_init(void) | 289 | static int __init dma_api_init(void) |
diff --git a/arch/sh/drivers/dma/dma-g2.c b/arch/sh/drivers/dma/dma-g2.c index 231e3f6fb28f..5afab6f56ec3 100644 --- a/arch/sh/drivers/dma/dma-g2.c +++ b/arch/sh/drivers/dma/dma-g2.c | |||
| @@ -140,7 +140,7 @@ static struct dma_ops g2_dma_ops = { | |||
| 140 | }; | 140 | }; |
| 141 | 141 | ||
| 142 | static struct dma_info g2_dma_info = { | 142 | static struct dma_info g2_dma_info = { |
| 143 | .name = "G2 DMA", | 143 | .name = "g2_dmac", |
| 144 | .nr_channels = 4, | 144 | .nr_channels = 4, |
| 145 | .ops = &g2_dma_ops, | 145 | .ops = &g2_dma_ops, |
| 146 | .flags = DMAC_CHANNELS_TEI_CAPABLE, | 146 | .flags = DMAC_CHANNELS_TEI_CAPABLE, |
| @@ -160,6 +160,7 @@ static int __init g2_dma_init(void) | |||
| 160 | static void __exit g2_dma_exit(void) | 160 | static void __exit g2_dma_exit(void) |
| 161 | { | 161 | { |
| 162 | free_irq(HW_EVENT_G2_DMA, 0); | 162 | free_irq(HW_EVENT_G2_DMA, 0); |
| 163 | unregister_dmac(&g2_dma_info); | ||
| 163 | } | 164 | } |
| 164 | 165 | ||
| 165 | subsys_initcall(g2_dma_init); | 166 | subsys_initcall(g2_dma_init); |
diff --git a/arch/sh/drivers/dma/dma-isa.c b/arch/sh/drivers/dma/dma-isa.c index 1c9bc45b8bcb..05a74ffdb68d 100644 --- a/arch/sh/drivers/dma/dma-isa.c +++ b/arch/sh/drivers/dma/dma-isa.c | |||
| @@ -25,14 +25,14 @@ | |||
| 25 | * such, this code is meant for only the simplest of tasks (and shouldn't be | 25 | * such, this code is meant for only the simplest of tasks (and shouldn't be |
| 26 | * used in any new drivers at all). | 26 | * used in any new drivers at all). |
| 27 | * | 27 | * |
| 28 | * It should also be noted that various functions here are labelled as | 28 | * NOTE: ops->xfer() is the preferred way of doing things. However, there |
| 29 | * being deprecated. This is due to the fact that the ops->xfer() method is | 29 | * are some users of the ISA DMA API that exist in common code that we |
| 30 | * the preferred way of doing things (as well as just grabbing the spinlock | 30 | * don't necessarily want to go out of our way to break, so we still |
| 31 | * directly). As such, any users of this interface will be warned rather | 31 | * allow for some compatability at that level. Any new code is strongly |
| 32 | * loudly. | 32 | * advised to run far away from the ISA DMA API and use the SH DMA API |
| 33 | * directly. | ||
| 33 | */ | 34 | */ |
| 34 | 35 | unsigned long claim_dma_lock(void) | |
| 35 | unsigned long __deprecated claim_dma_lock(void) | ||
| 36 | { | 36 | { |
| 37 | unsigned long flags; | 37 | unsigned long flags; |
| 38 | 38 | ||
| @@ -42,19 +42,19 @@ unsigned long __deprecated claim_dma_lock(void) | |||
| 42 | } | 42 | } |
| 43 | EXPORT_SYMBOL(claim_dma_lock); | 43 | EXPORT_SYMBOL(claim_dma_lock); |
| 44 | 44 | ||
| 45 | void __deprecated release_dma_lock(unsigned long flags) | 45 | void release_dma_lock(unsigned long flags) |
| 46 | { | 46 | { |
| 47 | spin_unlock_irqrestore(&dma_spin_lock, flags); | 47 | spin_unlock_irqrestore(&dma_spin_lock, flags); |
| 48 | } | 48 | } |
| 49 | EXPORT_SYMBOL(release_dma_lock); | 49 | EXPORT_SYMBOL(release_dma_lock); |
| 50 | 50 | ||
| 51 | void __deprecated disable_dma(unsigned int chan) | 51 | void disable_dma(unsigned int chan) |
| 52 | { | 52 | { |
| 53 | /* Nothing */ | 53 | /* Nothing */ |
| 54 | } | 54 | } |
| 55 | EXPORT_SYMBOL(disable_dma); | 55 | EXPORT_SYMBOL(disable_dma); |
| 56 | 56 | ||
| 57 | void __deprecated enable_dma(unsigned int chan) | 57 | void enable_dma(unsigned int chan) |
| 58 | { | 58 | { |
| 59 | struct dma_info *info = get_dma_info(chan); | 59 | struct dma_info *info = get_dma_info(chan); |
| 60 | struct dma_channel *channel = &info->channels[chan]; | 60 | struct dma_channel *channel = &info->channels[chan]; |
diff --git a/arch/sh/drivers/dma/dma-pvr2.c b/arch/sh/drivers/dma/dma-pvr2.c index 2e1d58f2d1b9..df604975ccc8 100644 --- a/arch/sh/drivers/dma/dma-pvr2.c +++ b/arch/sh/drivers/dma/dma-pvr2.c | |||
| @@ -80,7 +80,7 @@ static struct dma_ops pvr2_dma_ops = { | |||
| 80 | }; | 80 | }; |
| 81 | 81 | ||
| 82 | static struct dma_info pvr2_dma_info = { | 82 | static struct dma_info pvr2_dma_info = { |
| 83 | .name = "PowerVR 2 DMA", | 83 | .name = "pvr2_dmac", |
| 84 | .nr_channels = 1, | 84 | .nr_channels = 1, |
| 85 | .ops = &pvr2_dma_ops, | 85 | .ops = &pvr2_dma_ops, |
| 86 | .flags = DMAC_CHANNELS_TEI_CAPABLE, | 86 | .flags = DMAC_CHANNELS_TEI_CAPABLE, |
| @@ -98,6 +98,7 @@ static void __exit pvr2_dma_exit(void) | |||
| 98 | { | 98 | { |
| 99 | free_dma(PVR2_CASCADE_CHAN); | 99 | free_dma(PVR2_CASCADE_CHAN); |
| 100 | free_irq(HW_EVENT_PVR2_DMA, 0); | 100 | free_irq(HW_EVENT_PVR2_DMA, 0); |
| 101 | unregister_dmac(&pvr2_dma_info); | ||
| 101 | } | 102 | } |
| 102 | 103 | ||
| 103 | subsys_initcall(pvr2_dma_init); | 104 | subsys_initcall(pvr2_dma_init); |
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c index 31dacd4444b2..cca26c4c9d1b 100644 --- a/arch/sh/drivers/dma/dma-sh.c +++ b/arch/sh/drivers/dma/dma-sh.c | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2000 Takashi YOSHII | 6 | * Copyright (C) 2000 Takashi YOSHII |
| 7 | * Copyright (C) 2003, 2004 Paul Mundt | 7 | * Copyright (C) 2003, 2004 Paul Mundt |
| 8 | * Copyright (C) 2005 Andriy Skulysh | ||
| 8 | * | 9 | * |
| 9 | * This file is subject to the terms and conditions of the GNU General Public | 10 | * This file is subject to the terms and conditions of the GNU General Public |
| 10 | * License. See the file "COPYING" in the main directory of this archive | 11 | * License. See the file "COPYING" in the main directory of this archive |
| @@ -16,51 +17,28 @@ | |||
| 16 | #include <linux/irq.h> | 17 | #include <linux/irq.h> |
| 17 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
| 18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
| 20 | #include <asm/dreamcast/dma.h> | ||
| 19 | #include <asm/signal.h> | 21 | #include <asm/signal.h> |
| 20 | #include <asm/irq.h> | 22 | #include <asm/irq.h> |
| 21 | #include <asm/dma.h> | 23 | #include <asm/dma.h> |
| 22 | #include <asm/io.h> | 24 | #include <asm/io.h> |
| 23 | #include "dma-sh.h" | 25 | #include "dma-sh.h" |
| 24 | 26 | ||
| 25 | /* | ||
| 26 | * The SuperH DMAC supports a number of transmit sizes, we list them here, | ||
| 27 | * with their respective values as they appear in the CHCR registers. | ||
| 28 | * | ||
| 29 | * Defaults to a 64-bit transfer size. | ||
| 30 | */ | ||
| 31 | enum { | ||
| 32 | XMIT_SZ_64BIT, | ||
| 33 | XMIT_SZ_8BIT, | ||
| 34 | XMIT_SZ_16BIT, | ||
| 35 | XMIT_SZ_32BIT, | ||
| 36 | XMIT_SZ_256BIT, | ||
| 37 | }; | ||
| 38 | |||
| 39 | /* | ||
| 40 | * The DMA count is defined as the number of bytes to transfer. | ||
| 41 | */ | ||
| 42 | static unsigned int ts_shift[] = { | ||
| 43 | [XMIT_SZ_64BIT] = 3, | ||
| 44 | [XMIT_SZ_8BIT] = 0, | ||
| 45 | [XMIT_SZ_16BIT] = 1, | ||
| 46 | [XMIT_SZ_32BIT] = 2, | ||
| 47 | [XMIT_SZ_256BIT] = 5, | ||
| 48 | }; | ||
| 49 | |||
| 50 | static inline unsigned int get_dmte_irq(unsigned int chan) | 27 | static inline unsigned int get_dmte_irq(unsigned int chan) |
| 51 | { | 28 | { |
| 52 | unsigned int irq; | 29 | unsigned int irq = 0; |
| 53 | 30 | ||
| 54 | /* | 31 | /* |
| 55 | * Normally we could just do DMTE0_IRQ + chan outright, though in the | 32 | * Normally we could just do DMTE0_IRQ + chan outright, though in the |
| 56 | * case of the 7751R, the DMTE IRQs for channels > 4 start right above | 33 | * case of the 7751R, the DMTE IRQs for channels > 4 start right above |
| 57 | * the SCIF | 34 | * the SCIF |
| 58 | */ | 35 | */ |
| 59 | |||
| 60 | if (chan < 4) { | 36 | if (chan < 4) { |
| 61 | irq = DMTE0_IRQ + chan; | 37 | irq = DMTE0_IRQ + chan; |
| 62 | } else { | 38 | } else { |
| 39 | #ifdef DMTE4_IRQ | ||
| 63 | irq = DMTE4_IRQ + chan - 4; | 40 | irq = DMTE4_IRQ + chan - 4; |
| 41 | #endif | ||
| 64 | } | 42 | } |
| 65 | 43 | ||
| 66 | return irq; | 44 | return irq; |
| @@ -78,9 +56,7 @@ static inline unsigned int calc_xmit_shift(struct dma_channel *chan) | |||
| 78 | { | 56 | { |
| 79 | u32 chcr = ctrl_inl(CHCR[chan->chan]); | 57 | u32 chcr = ctrl_inl(CHCR[chan->chan]); |
| 80 | 58 | ||
| 81 | chcr >>= 4; | 59 | return ts_shift[(chcr & CHCR_TS_MASK)>>CHCR_TS_SHIFT]; |
| 82 | |||
| 83 | return ts_shift[chcr & 0x0007]; | ||
| 84 | } | 60 | } |
| 85 | 61 | ||
| 86 | /* | 62 | /* |
| @@ -109,8 +85,13 @@ static irqreturn_t dma_tei(int irq, void *dev_id, struct pt_regs *regs) | |||
| 109 | 85 | ||
| 110 | static int sh_dmac_request_dma(struct dma_channel *chan) | 86 | static int sh_dmac_request_dma(struct dma_channel *chan) |
| 111 | { | 87 | { |
| 88 | char name[32]; | ||
| 89 | |||
| 90 | snprintf(name, sizeof(name), "DMAC Transfer End (Channel %d)", | ||
| 91 | chan->chan); | ||
| 92 | |||
| 112 | return request_irq(get_dmte_irq(chan->chan), dma_tei, | 93 | return request_irq(get_dmte_irq(chan->chan), dma_tei, |
| 113 | SA_INTERRUPT, "DMAC Transfer End", chan); | 94 | SA_INTERRUPT, name, chan); |
| 114 | } | 95 | } |
| 115 | 96 | ||
| 116 | static void sh_dmac_free_dma(struct dma_channel *chan) | 97 | static void sh_dmac_free_dma(struct dma_channel *chan) |
| @@ -118,10 +99,18 @@ static void sh_dmac_free_dma(struct dma_channel *chan) | |||
| 118 | free_irq(get_dmte_irq(chan->chan), chan); | 99 | free_irq(get_dmte_irq(chan->chan), chan); |
| 119 | } | 100 | } |
| 120 | 101 | ||
| 121 | static void sh_dmac_configure_channel(struct dma_channel *chan, unsigned long chcr) | 102 | static void |
| 103 | sh_dmac_configure_channel(struct dma_channel *chan, unsigned long chcr) | ||
| 122 | { | 104 | { |
| 123 | if (!chcr) | 105 | if (!chcr) |
| 124 | chcr = RS_DUAL; | 106 | chcr = RS_DUAL | CHCR_IE; |
| 107 | |||
| 108 | if (chcr & CHCR_IE) { | ||
| 109 | chcr &= ~CHCR_IE; | ||
| 110 | chan->flags |= DMA_TEI_CAPABLE; | ||
| 111 | } else { | ||
| 112 | chan->flags &= ~DMA_TEI_CAPABLE; | ||
| 113 | } | ||
| 125 | 114 | ||
| 126 | ctrl_outl(chcr, CHCR[chan->chan]); | 115 | ctrl_outl(chcr, CHCR[chan->chan]); |
| 127 | 116 | ||
| @@ -130,22 +119,32 @@ static void sh_dmac_configure_channel(struct dma_channel *chan, unsigned long ch | |||
| 130 | 119 | ||
| 131 | static void sh_dmac_enable_dma(struct dma_channel *chan) | 120 | static void sh_dmac_enable_dma(struct dma_channel *chan) |
| 132 | { | 121 | { |
| 133 | int irq = get_dmte_irq(chan->chan); | 122 | int irq; |
| 134 | u32 chcr; | 123 | u32 chcr; |
| 135 | 124 | ||
| 136 | chcr = ctrl_inl(CHCR[chan->chan]); | 125 | chcr = ctrl_inl(CHCR[chan->chan]); |
| 137 | chcr |= CHCR_DE | CHCR_IE; | 126 | chcr |= CHCR_DE; |
| 127 | |||
| 128 | if (chan->flags & DMA_TEI_CAPABLE) | ||
| 129 | chcr |= CHCR_IE; | ||
| 130 | |||
| 138 | ctrl_outl(chcr, CHCR[chan->chan]); | 131 | ctrl_outl(chcr, CHCR[chan->chan]); |
| 139 | 132 | ||
| 140 | enable_irq(irq); | 133 | if (chan->flags & DMA_TEI_CAPABLE) { |
| 134 | irq = get_dmte_irq(chan->chan); | ||
| 135 | enable_irq(irq); | ||
| 136 | } | ||
| 141 | } | 137 | } |
| 142 | 138 | ||
| 143 | static void sh_dmac_disable_dma(struct dma_channel *chan) | 139 | static void sh_dmac_disable_dma(struct dma_channel *chan) |
| 144 | { | 140 | { |
| 145 | int irq = get_dmte_irq(chan->chan); | 141 | int irq; |
| 146 | u32 chcr; | 142 | u32 chcr; |
| 147 | 143 | ||
| 148 | disable_irq(irq); | 144 | if (chan->flags & DMA_TEI_CAPABLE) { |
| 145 | irq = get_dmte_irq(chan->chan); | ||
| 146 | disable_irq(irq); | ||
| 147 | } | ||
| 149 | 148 | ||
| 150 | chcr = ctrl_inl(CHCR[chan->chan]); | 149 | chcr = ctrl_inl(CHCR[chan->chan]); |
| 151 | chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE); | 150 | chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE); |
| @@ -158,7 +157,7 @@ static int sh_dmac_xfer_dma(struct dma_channel *chan) | |||
| 158 | * If we haven't pre-configured the channel with special flags, use | 157 | * If we haven't pre-configured the channel with special flags, use |
| 159 | * the defaults. | 158 | * the defaults. |
| 160 | */ | 159 | */ |
| 161 | if (!(chan->flags & DMA_CONFIGURED)) | 160 | if (unlikely(!(chan->flags & DMA_CONFIGURED))) |
| 162 | sh_dmac_configure_channel(chan, 0); | 161 | sh_dmac_configure_channel(chan, 0); |
| 163 | 162 | ||
| 164 | sh_dmac_disable_dma(chan); | 163 | sh_dmac_disable_dma(chan); |
| @@ -178,9 +177,11 @@ static int sh_dmac_xfer_dma(struct dma_channel *chan) | |||
| 178 | * cascading to the PVR2 DMAC. In this case, we still need to write | 177 | * cascading to the PVR2 DMAC. In this case, we still need to write |
| 179 | * SAR and DAR, regardless of value, in order for cascading to work. | 178 | * SAR and DAR, regardless of value, in order for cascading to work. |
| 180 | */ | 179 | */ |
| 181 | if (chan->sar || (mach_is_dreamcast() && chan->chan == 2)) | 180 | if (chan->sar || (mach_is_dreamcast() && |
| 181 | chan->chan == PVR2_CASCADE_CHAN)) | ||
| 182 | ctrl_outl(chan->sar, SAR[chan->chan]); | 182 | ctrl_outl(chan->sar, SAR[chan->chan]); |
| 183 | if (chan->dar || (mach_is_dreamcast() && chan->chan == 2)) | 183 | if (chan->dar || (mach_is_dreamcast() && |
| 184 | chan->chan == PVR2_CASCADE_CHAN)) | ||
| 184 | ctrl_outl(chan->dar, DAR[chan->chan]); | 185 | ctrl_outl(chan->dar, DAR[chan->chan]); |
| 185 | 186 | ||
| 186 | ctrl_outl(chan->count >> calc_xmit_shift(chan), DMATCR[chan->chan]); | 187 | ctrl_outl(chan->count >> calc_xmit_shift(chan), DMATCR[chan->chan]); |
| @@ -198,17 +199,38 @@ static int sh_dmac_get_dma_residue(struct dma_channel *chan) | |||
| 198 | return ctrl_inl(DMATCR[chan->chan]) << calc_xmit_shift(chan); | 199 | return ctrl_inl(DMATCR[chan->chan]) << calc_xmit_shift(chan); |
| 199 | } | 200 | } |
| 200 | 201 | ||
| 201 | #if defined(CONFIG_CPU_SH4) | 202 | #ifdef CONFIG_CPU_SUBTYPE_SH7780 |
| 202 | static irqreturn_t dma_err(int irq, void *dev_id, struct pt_regs *regs) | 203 | #define dmaor_read_reg() ctrl_inw(DMAOR) |
| 204 | #define dmaor_write_reg(data) ctrl_outw(data, DMAOR) | ||
| 205 | #else | ||
| 206 | #define dmaor_read_reg() ctrl_inl(DMAOR) | ||
| 207 | #define dmaor_write_reg(data) ctrl_outl(data, DMAOR) | ||
| 208 | #endif | ||
| 209 | |||
| 210 | static inline int dmaor_reset(void) | ||
| 203 | { | 211 | { |
| 204 | unsigned long dmaor = ctrl_inl(DMAOR); | 212 | unsigned long dmaor = dmaor_read_reg(); |
| 213 | |||
| 214 | /* Try to clear the error flags first, incase they are set */ | ||
| 215 | dmaor &= ~(DMAOR_NMIF | DMAOR_AE); | ||
| 216 | dmaor_write_reg(dmaor); | ||
| 205 | 217 | ||
| 206 | printk("DMAE: DMAOR=%lx\n", dmaor); | 218 | dmaor |= DMAOR_INIT; |
| 219 | dmaor_write_reg(dmaor); | ||
| 207 | 220 | ||
| 208 | ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_NMIF, DMAOR); | 221 | /* See if we got an error again */ |
| 209 | ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_AE, DMAOR); | 222 | if ((dmaor_read_reg() & (DMAOR_AE | DMAOR_NMIF))) { |
| 210 | ctrl_outl(ctrl_inl(DMAOR)|DMAOR_DME, DMAOR); | 223 | printk(KERN_ERR "dma-sh: Can't initialize DMAOR.\n"); |
| 224 | return -EINVAL; | ||
| 225 | } | ||
| 211 | 226 | ||
| 227 | return 0; | ||
| 228 | } | ||
| 229 | |||
| 230 | #if defined(CONFIG_CPU_SH4) | ||
| 231 | static irqreturn_t dma_err(int irq, void *dev_id, struct pt_regs *regs) | ||
| 232 | { | ||
| 233 | dmaor_reset(); | ||
| 212 | disable_irq(irq); | 234 | disable_irq(irq); |
| 213 | 235 | ||
| 214 | return IRQ_HANDLED; | 236 | return IRQ_HANDLED; |
| @@ -224,8 +246,8 @@ static struct dma_ops sh_dmac_ops = { | |||
| 224 | }; | 246 | }; |
| 225 | 247 | ||
| 226 | static struct dma_info sh_dmac_info = { | 248 | static struct dma_info sh_dmac_info = { |
| 227 | .name = "SuperH DMAC", | 249 | .name = "sh_dmac", |
| 228 | .nr_channels = 4, | 250 | .nr_channels = CONFIG_NR_ONCHIP_DMA_CHANNELS, |
| 229 | .ops = &sh_dmac_ops, | 251 | .ops = &sh_dmac_ops, |
| 230 | .flags = DMAC_CHANNELS_TEI_CAPABLE, | 252 | .flags = DMAC_CHANNELS_TEI_CAPABLE, |
| 231 | }; | 253 | }; |
| @@ -248,7 +270,13 @@ static int __init sh_dmac_init(void) | |||
| 248 | make_ipr_irq(irq, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); | 270 | make_ipr_irq(irq, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); |
| 249 | } | 271 | } |
| 250 | 272 | ||
| 251 | ctrl_outl(0x8000 | DMAOR_DME, DMAOR); | 273 | /* |
| 274 | * Initialize DMAOR, and clean up any error flags that may have | ||
| 275 | * been set. | ||
| 276 | */ | ||
| 277 | i = dmaor_reset(); | ||
| 278 | if (i < 0) | ||
| 279 | return i; | ||
| 252 | 280 | ||
| 253 | return register_dmac(info); | 281 | return register_dmac(info); |
| 254 | } | 282 | } |
| @@ -258,10 +286,12 @@ static void __exit sh_dmac_exit(void) | |||
| 258 | #ifdef CONFIG_CPU_SH4 | 286 | #ifdef CONFIG_CPU_SH4 |
| 259 | free_irq(DMAE_IRQ, 0); | 287 | free_irq(DMAE_IRQ, 0); |
| 260 | #endif | 288 | #endif |
| 289 | unregister_dmac(&sh_dmac_info); | ||
| 261 | } | 290 | } |
| 262 | 291 | ||
| 263 | subsys_initcall(sh_dmac_init); | 292 | subsys_initcall(sh_dmac_init); |
| 264 | module_exit(sh_dmac_exit); | 293 | module_exit(sh_dmac_exit); |
| 265 | 294 | ||
| 295 | MODULE_AUTHOR("Takashi YOSHII, Paul Mundt, Andriy Skulysh"); | ||
| 296 | MODULE_DESCRIPTION("SuperH On-Chip DMAC Support"); | ||
| 266 | MODULE_LICENSE("GPL"); | 297 | MODULE_LICENSE("GPL"); |
| 267 | |||
diff --git a/arch/sh/drivers/dma/dma-sh.h b/arch/sh/drivers/dma/dma-sh.h index dd9d547539a2..0f591fbc922d 100644 --- a/arch/sh/drivers/dma/dma-sh.h +++ b/arch/sh/drivers/dma/dma-sh.h | |||
| @@ -11,6 +11,8 @@ | |||
| 11 | #ifndef __DMA_SH_H | 11 | #ifndef __DMA_SH_H |
| 12 | #define __DMA_SH_H | 12 | #define __DMA_SH_H |
| 13 | 13 | ||
| 14 | #include <asm/cpu/dma.h> | ||
| 15 | |||
| 14 | /* Definitions for the SuperH DMAC */ | 16 | /* Definitions for the SuperH DMAC */ |
| 15 | #define REQ_L 0x00000000 | 17 | #define REQ_L 0x00000000 |
| 16 | #define REQ_E 0x00080000 | 18 | #define REQ_E 0x00080000 |
| @@ -26,27 +28,47 @@ | |||
| 26 | #define SM_DEC 0x00002000 | 28 | #define SM_DEC 0x00002000 |
| 27 | #define RS_IN 0x00000200 | 29 | #define RS_IN 0x00000200 |
| 28 | #define RS_OUT 0x00000300 | 30 | #define RS_OUT 0x00000300 |
| 29 | #define TM_BURST 0x0000080 | ||
| 30 | #define TS_8 0x00000010 | ||
| 31 | #define TS_16 0x00000020 | ||
| 32 | #define TS_32 0x00000030 | ||
| 33 | #define TS_64 0x00000000 | ||
| 34 | #define TS_BLK 0x00000040 | 31 | #define TS_BLK 0x00000040 |
| 35 | #define CHCR_DE 0x00000001 | 32 | #define CHCR_DE 0x00000001 |
| 36 | #define CHCR_TE 0x00000002 | 33 | #define CHCR_TE 0x00000002 |
| 37 | #define CHCR_IE 0x00000004 | 34 | #define CHCR_IE 0x00000004 |
| 38 | 35 | ||
| 39 | /* Define the default configuration for dual address memory-memory transfer. | 36 | /* DMAOR definitions */ |
| 40 | * The 0x400 value represents auto-request, external->external. | ||
| 41 | */ | ||
| 42 | #define RS_DUAL (DM_INC | SM_INC | 0x400 | TS_32) | ||
| 43 | |||
| 44 | #define DMAOR_COD 0x00000008 | ||
| 45 | #define DMAOR_AE 0x00000004 | 37 | #define DMAOR_AE 0x00000004 |
| 46 | #define DMAOR_NMIF 0x00000002 | 38 | #define DMAOR_NMIF 0x00000002 |
| 47 | #define DMAOR_DME 0x00000001 | 39 | #define DMAOR_DME 0x00000001 |
| 48 | 40 | ||
| 41 | /* | ||
| 42 | * Define the default configuration for dual address memory-memory transfer. | ||
| 43 | * The 0x400 value represents auto-request, external->external. | ||
| 44 | */ | ||
| 45 | #define RS_DUAL (DM_INC | SM_INC | 0x400 | TS_32) | ||
| 46 | |||
| 49 | #define MAX_DMAC_CHANNELS (CONFIG_NR_ONCHIP_DMA_CHANNELS) | 47 | #define MAX_DMAC_CHANNELS (CONFIG_NR_ONCHIP_DMA_CHANNELS) |
| 50 | 48 | ||
| 49 | /* | ||
| 50 | * Subtypes that have fewer channels than this simply need to change | ||
| 51 | * CONFIG_NR_ONCHIP_DMA_CHANNELS. Likewise, subtypes with a larger number | ||
| 52 | * of channels should expand on this. | ||
| 53 | * | ||
| 54 | * For most subtypes we can easily figure these values out with some | ||
| 55 | * basic calculation, unfortunately on other subtypes these are more | ||
| 56 | * scattered, so we just leave it unrolled for simplicity. | ||
| 57 | */ | ||
| 58 | #define SAR ((unsigned long[]){SH_DMAC_BASE + 0x00, SH_DMAC_BASE + 0x10, \ | ||
| 59 | SH_DMAC_BASE + 0x20, SH_DMAC_BASE + 0x30, \ | ||
| 60 | SH_DMAC_BASE + 0x50, SH_DMAC_BASE + 0x60}) | ||
| 61 | #define DAR ((unsigned long[]){SH_DMAC_BASE + 0x04, SH_DMAC_BASE + 0x14, \ | ||
| 62 | SH_DMAC_BASE + 0x24, SH_DMAC_BASE + 0x34, \ | ||
| 63 | SH_DMAC_BASE + 0x54, SH_DMAC_BASE + 0x64}) | ||
| 64 | #define DMATCR ((unsigned long[]){SH_DMAC_BASE + 0x08, SH_DMAC_BASE + 0x18, \ | ||
| 65 | SH_DMAC_BASE + 0x28, SH_DMAC_BASE + 0x38, \ | ||
| 66 | SH_DMAC_BASE + 0x58, SH_DMAC_BASE + 0x68}) | ||
| 67 | #define CHCR ((unsigned long[]){SH_DMAC_BASE + 0x0c, SH_DMAC_BASE + 0x1c, \ | ||
| 68 | SH_DMAC_BASE + 0x2c, SH_DMAC_BASE + 0x3c, \ | ||
| 69 | SH_DMAC_BASE + 0x5c, SH_DMAC_BASE + 0x6c}) | ||
| 70 | |||
| 71 | #define DMAOR (SH_DMAC_BASE + 0x40) | ||
| 72 | |||
| 51 | #endif /* __DMA_SH_H */ | 73 | #endif /* __DMA_SH_H */ |
| 52 | 74 | ||
diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c index 6e3b58bd8795..70a5d82eb2f8 100644 --- a/arch/sh/drivers/dma/dma-sysfs.c +++ b/arch/sh/drivers/dma/dma-sysfs.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * sysfs interface for SH DMA API | 4 | * sysfs interface for SH DMA API |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2004 Paul Mundt | 6 | * Copyright (C) 2004, 2005 Paul Mundt |
| 7 | * | 7 | * |
| 8 | * This file is subject to the terms and conditions of the GNU General Public | 8 | * This file is subject to the terms and conditions of the GNU General Public |
| 9 | * License. See the file "COPYING" in the main directory of this archive | 9 | * License. See the file "COPYING" in the main directory of this archive |
| @@ -12,7 +12,9 @@ | |||
| 12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <linux/sysdev.h> | 14 | #include <linux/sysdev.h> |
| 15 | #include <linux/platform_device.h> | ||
| 15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 17 | #include <linux/err.h> | ||
| 16 | #include <linux/string.h> | 18 | #include <linux/string.h> |
| 17 | #include <asm/dma.h> | 19 | #include <asm/dma.h> |
| 18 | 20 | ||
| @@ -77,7 +79,7 @@ static ssize_t dma_store_config(struct sys_device *dev, | |||
| 77 | unsigned long config; | 79 | unsigned long config; |
| 78 | 80 | ||
| 79 | config = simple_strtoul(buf, NULL, 0); | 81 | config = simple_strtoul(buf, NULL, 0); |
| 80 | dma_configure_channel(channel->chan, config); | 82 | dma_configure_channel(channel->vchan, config); |
| 81 | 83 | ||
| 82 | return count; | 84 | return count; |
| 83 | } | 85 | } |
| @@ -111,12 +113,13 @@ static SYSDEV_ATTR(field, S_IRUGO, dma_show_##field, NULL); | |||
| 111 | dma_ro_attr(count, "0x%08x\n"); | 113 | dma_ro_attr(count, "0x%08x\n"); |
| 112 | dma_ro_attr(flags, "0x%08lx\n"); | 114 | dma_ro_attr(flags, "0x%08lx\n"); |
| 113 | 115 | ||
| 114 | int __init dma_create_sysfs_files(struct dma_channel *chan) | 116 | int dma_create_sysfs_files(struct dma_channel *chan, struct dma_info *info) |
| 115 | { | 117 | { |
| 116 | struct sys_device *dev = &chan->dev; | 118 | struct sys_device *dev = &chan->dev; |
| 119 | char name[16]; | ||
| 117 | int ret; | 120 | int ret; |
| 118 | 121 | ||
| 119 | dev->id = chan->chan; | 122 | dev->id = chan->vchan; |
| 120 | dev->cls = &dma_sysclass; | 123 | dev->cls = &dma_sysclass; |
| 121 | 124 | ||
| 122 | ret = sysdev_register(dev); | 125 | ret = sysdev_register(dev); |
| @@ -129,6 +132,24 @@ int __init dma_create_sysfs_files(struct dma_channel *chan) | |||
| 129 | sysdev_create_file(dev, &attr_flags); | 132 | sysdev_create_file(dev, &attr_flags); |
| 130 | sysdev_create_file(dev, &attr_config); | 133 | sysdev_create_file(dev, &attr_config); |
| 131 | 134 | ||
| 132 | return 0; | 135 | snprintf(name, sizeof(name), "dma%d", chan->chan); |
| 136 | return sysfs_create_link(&info->pdev->dev.kobj, &dev->kobj, name); | ||
| 137 | } | ||
| 138 | |||
| 139 | void dma_remove_sysfs_files(struct dma_channel *chan, struct dma_info *info) | ||
| 140 | { | ||
| 141 | struct sys_device *dev = &chan->dev; | ||
| 142 | char name[16]; | ||
| 143 | |||
| 144 | sysdev_remove_file(dev, &attr_dev_id); | ||
| 145 | sysdev_remove_file(dev, &attr_count); | ||
| 146 | sysdev_remove_file(dev, &attr_mode); | ||
| 147 | sysdev_remove_file(dev, &attr_flags); | ||
| 148 | sysdev_remove_file(dev, &attr_config); | ||
| 149 | |||
| 150 | snprintf(name, sizeof(name), "dma%d", chan->chan); | ||
| 151 | sysfs_remove_link(&info->pdev->dev.kobj, name); | ||
| 152 | |||
| 153 | sysdev_unregister(dev); | ||
| 133 | } | 154 | } |
| 134 | 155 | ||
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index 8b819698df14..7a86eeb22655 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile | |||
| @@ -17,6 +17,4 @@ obj-$(CONFIG_SH_KGDB) += kgdb_stub.o kgdb_jmp.o | |||
| 17 | obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o | 17 | obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o |
| 18 | obj-$(CONFIG_MODULES) += module.o | 18 | obj-$(CONFIG_MODULES) += module.o |
| 19 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 19 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
| 20 | 20 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o | |
| 21 | USE_STANDARD_AS_RULE := true | ||
| 22 | |||
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile index cd43714df61a..5bfc33bec5d0 100644 --- a/arch/sh/kernel/cpu/Makefile +++ b/arch/sh/kernel/cpu/Makefile | |||
| @@ -2,15 +2,12 @@ | |||
| 2 | # Makefile for the Linux/SuperH CPU-specifc backends. | 2 | # Makefile for the Linux/SuperH CPU-specifc backends. |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-y := irq_ipr.o irq_imask.o init.o bus.o | 5 | obj-y += irq/ init.o bus.o clock.o |
| 6 | 6 | ||
| 7 | obj-$(CONFIG_CPU_SH2) += sh2/ | 7 | obj-$(CONFIG_CPU_SH2) += sh2/ |
| 8 | obj-$(CONFIG_CPU_SH3) += sh3/ | 8 | obj-$(CONFIG_CPU_SH3) += sh3/ |
| 9 | obj-$(CONFIG_CPU_SH4) += sh4/ | 9 | obj-$(CONFIG_CPU_SH4) += sh4/ |
| 10 | 10 | ||
| 11 | obj-$(CONFIG_SH_RTC) += rtc.o | 11 | obj-$(CONFIG_SH_RTC) += rtc.o |
| 12 | obj-$(CONFIG_UBC_WAKEUP) += ubc.o | 12 | obj-$(CONFIG_UBC_WAKEUP) += ubc.o |
| 13 | obj-$(CONFIG_SH_ADC) += adc.o | 13 | obj-$(CONFIG_SH_ADC) += adc.o |
| 14 | |||
| 15 | USE_STANDARD_AS_RULE := true | ||
| 16 | |||
diff --git a/arch/sh/kernel/cpu/bus.c b/arch/sh/kernel/cpu/bus.c index d4fee2a79373..fc6c4bd40c65 100644 --- a/arch/sh/kernel/cpu/bus.c +++ b/arch/sh/kernel/cpu/bus.c | |||
| @@ -53,21 +53,6 @@ static int sh_bus_resume(struct device *dev) | |||
| 53 | return 0; | 53 | return 0; |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | static struct device sh_bus_devices[SH_NR_BUSES] = { | ||
| 57 | { | ||
| 58 | .bus_id = SH_BUS_NAME_VIRT, | ||
| 59 | }, | ||
| 60 | }; | ||
| 61 | |||
| 62 | struct bus_type sh_bus_types[SH_NR_BUSES] = { | ||
| 63 | { | ||
| 64 | .name = SH_BUS_NAME_VIRT, | ||
| 65 | .match = sh_bus_match, | ||
| 66 | .suspend = sh_bus_suspend, | ||
| 67 | .resume = sh_bus_resume, | ||
| 68 | }, | ||
| 69 | }; | ||
| 70 | |||
| 71 | static int sh_device_probe(struct device *dev) | 56 | static int sh_device_probe(struct device *dev) |
| 72 | { | 57 | { |
| 73 | struct sh_dev *shdev = to_sh_dev(dev); | 58 | struct sh_dev *shdev = to_sh_dev(dev); |
| @@ -90,6 +75,23 @@ static int sh_device_remove(struct device *dev) | |||
| 90 | return 0; | 75 | return 0; |
| 91 | } | 76 | } |
| 92 | 77 | ||
| 78 | static struct device sh_bus_devices[SH_NR_BUSES] = { | ||
| 79 | { | ||
| 80 | .bus_id = SH_BUS_NAME_VIRT, | ||
| 81 | }, | ||
| 82 | }; | ||
| 83 | |||
| 84 | struct bus_type sh_bus_types[SH_NR_BUSES] = { | ||
| 85 | { | ||
| 86 | .name = SH_BUS_NAME_VIRT, | ||
| 87 | .match = sh_bus_match, | ||
| 88 | .probe = sh_bus_probe, | ||
| 89 | .remove = sh_bus_remove, | ||
| 90 | .suspend = sh_bus_suspend, | ||
| 91 | .resume = sh_bus_resume, | ||
| 92 | }, | ||
| 93 | }; | ||
| 94 | |||
| 93 | int sh_device_register(struct sh_dev *dev) | 95 | int sh_device_register(struct sh_dev *dev) |
| 94 | { | 96 | { |
| 95 | if (!dev) | 97 | if (!dev) |
| @@ -107,6 +109,8 @@ int sh_device_register(struct sh_dev *dev) | |||
| 107 | /* This is needed for USB OHCI to work */ | 109 | /* This is needed for USB OHCI to work */ |
| 108 | if (dev->dma_mask) | 110 | if (dev->dma_mask) |
| 109 | dev->dev.dma_mask = dev->dma_mask; | 111 | dev->dev.dma_mask = dev->dma_mask; |
| 112 | if (dev->coherent_dma_mask) | ||
| 113 | dev->dev.coherent_dma_mask = dev->coherent_dma_mask; | ||
| 110 | 114 | ||
| 111 | snprintf(dev->dev.bus_id, BUS_ID_SIZE, "%s%u", | 115 | snprintf(dev->dev.bus_id, BUS_ID_SIZE, "%s%u", |
| 112 | dev->name, dev->dev_id); | 116 | dev->name, dev->dev_id); |
| @@ -133,8 +137,6 @@ int sh_driver_register(struct sh_driver *drv) | |||
| 133 | return -EINVAL; | 137 | return -EINVAL; |
| 134 | } | 138 | } |
| 135 | 139 | ||
| 136 | drv->drv.probe = sh_device_probe; | ||
| 137 | drv->drv.remove = sh_device_remove; | ||
| 138 | drv->drv.bus = &sh_bus_types[drv->bus_id]; | 140 | drv->drv.bus = &sh_bus_types[drv->bus_id]; |
| 139 | 141 | ||
| 140 | return driver_register(&drv->drv); | 142 | return driver_register(&drv->drv); |
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c new file mode 100644 index 000000000000..989e7fdd524d --- /dev/null +++ b/arch/sh/kernel/cpu/clock.c | |||
| @@ -0,0 +1,287 @@ | |||
| 1 | /* | ||
| 2 | * arch/sh/kernel/cpu/clock.c - SuperH clock framework | ||
| 3 | * | ||
| 4 | * Copyright (C) 2005 Paul Mundt | ||
| 5 | * | ||
| 6 | * This clock framework is derived from the OMAP version by: | ||
| 7 | * | ||
| 8 | * Copyright (C) 2004 Nokia Corporation | ||
| 9 | * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> | ||
| 10 | * | ||
| 11 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 12 | * License. See the file "COPYING" in the main directory of this archive | ||
| 13 | * for more details. | ||
| 14 | */ | ||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/init.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/list.h> | ||
| 19 | #include <linux/kref.h> | ||
| 20 | #include <linux/seq_file.h> | ||
| 21 | #include <linux/err.h> | ||
| 22 | #include <asm/clock.h> | ||
| 23 | #include <asm/timer.h> | ||
| 24 | |||
| 25 | static LIST_HEAD(clock_list); | ||
| 26 | static DEFINE_SPINLOCK(clock_lock); | ||
| 27 | static DECLARE_MUTEX(clock_list_sem); | ||
| 28 | |||
| 29 | /* | ||
| 30 | * Each subtype is expected to define the init routines for these clocks, | ||
| 31 | * as each subtype (or processor family) will have these clocks at the | ||
| 32 | * very least. These are all provided through the CPG, which even some of | ||
| 33 | * the more quirky parts (such as ST40, SH4-202, etc.) still have. | ||
| 34 | * | ||
| 35 | * The processor-specific code is expected to register any additional | ||
| 36 | * clock sources that are of interest. | ||
| 37 | */ | ||
| 38 | static struct clk master_clk = { | ||
| 39 | .name = "master_clk", | ||
| 40 | .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, | ||
| 41 | #ifdef CONFIG_SH_PCLK_FREQ_BOOL | ||
| 42 | .rate = CONFIG_SH_PCLK_FREQ, | ||
| 43 | #endif | ||
| 44 | }; | ||
| 45 | |||
| 46 | static struct clk module_clk = { | ||
| 47 | .name = "module_clk", | ||
| 48 | .parent = &master_clk, | ||
| 49 | .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, | ||
| 50 | }; | ||
| 51 | |||
| 52 | static struct clk bus_clk = { | ||
| 53 | .name = "bus_clk", | ||
| 54 | .parent = &master_clk, | ||
| 55 | .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, | ||
| 56 | }; | ||
| 57 | |||
| 58 | static struct clk cpu_clk = { | ||
| 59 | .name = "cpu_clk", | ||
| 60 | .parent = &master_clk, | ||
| 61 | .flags = CLK_ALWAYS_ENABLED, | ||
| 62 | }; | ||
| 63 | |||
| 64 | /* | ||
| 65 | * The ordering of these clocks matters, do not change it. | ||
| 66 | */ | ||
| 67 | static struct clk *onchip_clocks[] = { | ||
| 68 | &master_clk, | ||
| 69 | &module_clk, | ||
| 70 | &bus_clk, | ||
| 71 | &cpu_clk, | ||
| 72 | }; | ||
| 73 | |||
| 74 | static void propagate_rate(struct clk *clk) | ||
| 75 | { | ||
| 76 | struct clk *clkp; | ||
| 77 | |||
| 78 | list_for_each_entry(clkp, &clock_list, node) { | ||
| 79 | if (likely(clkp->parent != clk)) | ||
| 80 | continue; | ||
| 81 | if (likely(clkp->ops && clkp->ops->recalc)) | ||
| 82 | clkp->ops->recalc(clkp); | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | int __clk_enable(struct clk *clk) | ||
| 87 | { | ||
| 88 | /* | ||
| 89 | * See if this is the first time we're enabling the clock, some | ||
| 90 | * clocks that are always enabled still require "special" | ||
| 91 | * initialization. This is especially true if the clock mode | ||
| 92 | * changes and the clock needs to hunt for the proper set of | ||
| 93 | * divisors to use before it can effectively recalc. | ||
| 94 | */ | ||
| 95 | if (unlikely(atomic_read(&clk->kref.refcount) == 1)) | ||
| 96 | if (clk->ops && clk->ops->init) | ||
| 97 | clk->ops->init(clk); | ||
| 98 | |||
| 99 | if (clk->flags & CLK_ALWAYS_ENABLED) | ||
| 100 | return 0; | ||
| 101 | |||
| 102 | if (likely(clk->ops && clk->ops->enable)) | ||
| 103 | clk->ops->enable(clk); | ||
| 104 | |||
| 105 | kref_get(&clk->kref); | ||
| 106 | return 0; | ||
| 107 | } | ||
| 108 | |||
| 109 | int clk_enable(struct clk *clk) | ||
| 110 | { | ||
| 111 | unsigned long flags; | ||
| 112 | int ret; | ||
| 113 | |||
| 114 | spin_lock_irqsave(&clock_lock, flags); | ||
| 115 | ret = __clk_enable(clk); | ||
| 116 | spin_unlock_irqrestore(&clock_lock, flags); | ||
| 117 | |||
| 118 | return ret; | ||
| 119 | } | ||
| 120 | |||
| 121 | static void clk_kref_release(struct kref *kref) | ||
| 122 | { | ||
| 123 | /* Nothing to do */ | ||
| 124 | } | ||
| 125 | |||
| 126 | void __clk_disable(struct clk *clk) | ||
| 127 | { | ||
| 128 | if (clk->flags & CLK_ALWAYS_ENABLED) | ||
| 129 | return; | ||
| 130 | |||
| 131 | kref_put(&clk->kref, clk_kref_release); | ||
| 132 | } | ||
| 133 | |||
| 134 | void clk_disable(struct clk *clk) | ||
| 135 | { | ||
| 136 | unsigned long flags; | ||
| 137 | |||
| 138 | spin_lock_irqsave(&clock_lock, flags); | ||
| 139 | __clk_disable(clk); | ||
| 140 | spin_unlock_irqrestore(&clock_lock, flags); | ||
| 141 | } | ||
| 142 | |||
| 143 | int clk_register(struct clk *clk) | ||
| 144 | { | ||
| 145 | down(&clock_list_sem); | ||
| 146 | |||
| 147 | list_add(&clk->node, &clock_list); | ||
| 148 | kref_init(&clk->kref); | ||
| 149 | |||
| 150 | up(&clock_list_sem); | ||
| 151 | |||
| 152 | return 0; | ||
| 153 | } | ||
| 154 | |||
| 155 | void clk_unregister(struct clk *clk) | ||
| 156 | { | ||
| 157 | down(&clock_list_sem); | ||
| 158 | list_del(&clk->node); | ||
| 159 | up(&clock_list_sem); | ||
| 160 | } | ||
| 161 | |||
| 162 | inline unsigned long clk_get_rate(struct clk *clk) | ||
| 163 | { | ||
| 164 | return clk->rate; | ||
| 165 | } | ||
| 166 | |||
| 167 | int clk_set_rate(struct clk *clk, unsigned long rate) | ||
| 168 | { | ||
| 169 | int ret = -EOPNOTSUPP; | ||
| 170 | |||
| 171 | if (likely(clk->ops && clk->ops->set_rate)) { | ||
| 172 | unsigned long flags; | ||
| 173 | |||
| 174 | spin_lock_irqsave(&clock_lock, flags); | ||
| 175 | ret = clk->ops->set_rate(clk, rate); | ||
| 176 | spin_unlock_irqrestore(&clock_lock, flags); | ||
| 177 | } | ||
| 178 | |||
| 179 | if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) | ||
| 180 | propagate_rate(clk); | ||
| 181 | |||
| 182 | return ret; | ||
| 183 | } | ||
| 184 | |||
| 185 | void clk_recalc_rate(struct clk *clk) | ||
| 186 | { | ||
| 187 | if (likely(clk->ops && clk->ops->recalc)) { | ||
| 188 | unsigned long flags; | ||
| 189 | |||
| 190 | spin_lock_irqsave(&clock_lock, flags); | ||
| 191 | clk->ops->recalc(clk); | ||
| 192 | spin_unlock_irqrestore(&clock_lock, flags); | ||
| 193 | } | ||
| 194 | |||
| 195 | if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) | ||
| 196 | propagate_rate(clk); | ||
| 197 | } | ||
| 198 | |||
| 199 | struct clk *clk_get(const char *id) | ||
| 200 | { | ||
| 201 | struct clk *p, *clk = ERR_PTR(-ENOENT); | ||
| 202 | |||
| 203 | down(&clock_list_sem); | ||
| 204 | list_for_each_entry(p, &clock_list, node) { | ||
| 205 | if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { | ||
| 206 | clk = p; | ||
| 207 | break; | ||
| 208 | } | ||
| 209 | } | ||
| 210 | up(&clock_list_sem); | ||
| 211 | |||
| 212 | return clk; | ||
| 213 | } | ||
| 214 | |||
| 215 | void clk_put(struct clk *clk) | ||
| 216 | { | ||
| 217 | if (clk && !IS_ERR(clk)) | ||
| 218 | module_put(clk->owner); | ||
| 219 | } | ||
| 220 | |||
| 221 | void __init __attribute__ ((weak)) | ||
| 222 | arch_init_clk_ops(struct clk_ops **ops, int type) | ||
| 223 | { | ||
| 224 | } | ||
| 225 | |||
| 226 | int __init clk_init(void) | ||
| 227 | { | ||
| 228 | int i, ret = 0; | ||
| 229 | |||
| 230 | if (unlikely(!master_clk.rate)) | ||
| 231 | /* | ||
| 232 | * NOTE: This will break if the default divisor has been | ||
| 233 | * changed. | ||
| 234 | * | ||
| 235 | * No one should be changing the default on us however, | ||
| 236 | * expect that a sane value for CONFIG_SH_PCLK_FREQ will | ||
| 237 | * be defined in the event of a different divisor. | ||
| 238 | */ | ||
| 239 | master_clk.rate = get_timer_frequency() * 4; | ||
| 240 | |||
| 241 | for (i = 0; i < ARRAY_SIZE(onchip_clocks); i++) { | ||
| 242 | struct clk *clk = onchip_clocks[i]; | ||
| 243 | |||
| 244 | arch_init_clk_ops(&clk->ops, i); | ||
| 245 | ret |= clk_register(clk); | ||
| 246 | clk_enable(clk); | ||
| 247 | } | ||
| 248 | |||
| 249 | /* Kick the child clocks.. */ | ||
| 250 | propagate_rate(&master_clk); | ||
| 251 | propagate_rate(&bus_clk); | ||
| 252 | |||
| 253 | return ret; | ||
| 254 | } | ||
| 255 | |||
| 256 | int show_clocks(struct seq_file *m) | ||
| 257 | { | ||
| 258 | struct clk *clk; | ||
| 259 | |||
| 260 | list_for_each_entry_reverse(clk, &clock_list, node) { | ||
| 261 | unsigned long rate = clk_get_rate(clk); | ||
| 262 | |||
| 263 | /* | ||
| 264 | * Don't bother listing dummy clocks with no ancestry | ||
| 265 | * that only support enable and disable ops. | ||
| 266 | */ | ||
| 267 | if (unlikely(!rate && !clk->parent)) | ||
| 268 | continue; | ||
| 269 | |||
| 270 | seq_printf(m, "%-12s\t: %ld.%02ldMHz\n", clk->name, | ||
| 271 | rate / 1000000, (rate % 1000000) / 10000); | ||
| 272 | } | ||
| 273 | |||
| 274 | return 0; | ||
| 275 | } | ||
| 276 | |||
| 277 | EXPORT_SYMBOL_GPL(clk_register); | ||
| 278 | EXPORT_SYMBOL_GPL(clk_unregister); | ||
| 279 | EXPORT_SYMBOL_GPL(clk_get); | ||
| 280 | EXPORT_SYMBOL_GPL(clk_put); | ||
| 281 | EXPORT_SYMBOL_GPL(clk_enable); | ||
| 282 | EXPORT_SYMBOL_GPL(clk_disable); | ||
| 283 | EXPORT_SYMBOL_GPL(__clk_enable); | ||
| 284 | EXPORT_SYMBOL_GPL(__clk_disable); | ||
| 285 | EXPORT_SYMBOL_GPL(clk_get_rate); | ||
| 286 | EXPORT_SYMBOL_GPL(clk_set_rate); | ||
| 287 | EXPORT_SYMBOL_GPL(clk_recalc_rate); | ||
diff --git a/arch/sh/kernel/cpu/irq/Makefile b/arch/sh/kernel/cpu/irq/Makefile new file mode 100644 index 000000000000..e3cccea15e1d --- /dev/null +++ b/arch/sh/kernel/cpu/irq/Makefile | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | # | ||
| 2 | # Makefile for the Linux/SuperH CPU-specifc IRQ handlers. | ||
| 3 | # | ||
| 4 | obj-y += ipr.o imask.o | ||
| 5 | |||
| 6 | obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o | ||
| 7 | obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o | ||
diff --git a/arch/sh/kernel/cpu/irq_imask.c b/arch/sh/kernel/cpu/irq/imask.c index a963d00a971e..baed9a550d39 100644 --- a/arch/sh/kernel/cpu/irq_imask.c +++ b/arch/sh/kernel/cpu/irq/imask.c | |||
| @@ -1,16 +1,12 @@ | |||
| 1 | /* $Id: irq_imask.c,v 1.1.2.1 2002/11/17 10:53:43 mrbrown Exp $ | 1 | /* |
| 2 | * | 2 | * arch/sh/kernel/cpu/irq/imask.c |
| 3 | * linux/arch/sh/kernel/irq_imask.c | ||
| 4 | * | 3 | * |
| 5 | * Copyright (C) 1999, 2000 Niibe Yutaka | 4 | * Copyright (C) 1999, 2000 Niibe Yutaka |
| 6 | * | 5 | * |
| 7 | * Simple interrupt handling using IMASK of SR register. | 6 | * Simple interrupt handling using IMASK of SR register. |
| 8 | * | 7 | * |
| 9 | */ | 8 | */ |
| 10 | |||
| 11 | /* NOTE: Will not work on level 15 */ | 9 | /* NOTE: Will not work on level 15 */ |
| 12 | |||
| 13 | |||
| 14 | #include <linux/ptrace.h> | 10 | #include <linux/ptrace.h> |
| 15 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
| 16 | #include <linux/kernel_stat.h> | 12 | #include <linux/kernel_stat.h> |
| @@ -19,13 +15,11 @@ | |||
| 19 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
| 20 | #include <linux/init.h> | 16 | #include <linux/init.h> |
| 21 | #include <linux/bitops.h> | 17 | #include <linux/bitops.h> |
| 22 | |||
| 23 | #include <asm/system.h> | ||
| 24 | #include <asm/irq.h> | ||
| 25 | |||
| 26 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
| 27 | #include <linux/cache.h> | 19 | #include <linux/cache.h> |
| 28 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
| 21 | #include <asm/system.h> | ||
| 22 | #include <asm/irq.h> | ||
| 29 | 23 | ||
| 30 | /* Bitmap of IRQ masked */ | 24 | /* Bitmap of IRQ masked */ |
| 31 | static unsigned long imask_mask = 0x7fff; | 25 | static unsigned long imask_mask = 0x7fff; |
| @@ -40,7 +34,7 @@ static void end_imask_irq(unsigned int irq); | |||
| 40 | #define IMASK_PRIORITY 15 | 34 | #define IMASK_PRIORITY 15 |
| 41 | 35 | ||
| 42 | static unsigned int startup_imask_irq(unsigned int irq) | 36 | static unsigned int startup_imask_irq(unsigned int irq) |
| 43 | { | 37 | { |
| 44 | /* Nothing to do */ | 38 | /* Nothing to do */ |
| 45 | return 0; /* never anything pending */ | 39 | return 0; /* never anything pending */ |
| 46 | } | 40 | } |
diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c new file mode 100644 index 000000000000..06e8afab32e4 --- /dev/null +++ b/arch/sh/kernel/cpu/irq/intc2.c | |||
| @@ -0,0 +1,284 @@ | |||
| 1 | /* | ||
| 2 | * Interrupt handling for INTC2-based IRQ. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2001 David J. Mckay (david.mckay@st.com) | ||
| 5 | * Copyright (C) 2005, 2006 Paul Mundt (lethal@linux-sh.org) | ||
| 6 | * | ||
| 7 | * May be copied or modified under the terms of the GNU General Public | ||
| 8 | * License. See linux/COPYING for more information. | ||
| 9 | * | ||
| 10 | * These are the "new Hitachi style" interrupts, as present on the | ||
| 11 | * Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/irq.h> | ||
| 17 | #include <asm/system.h> | ||
| 18 | #include <asm/io.h> | ||
| 19 | #include <asm/machvec.h> | ||
| 20 | |||
| 21 | struct intc2_data { | ||
| 22 | unsigned char msk_offset; | ||
| 23 | unsigned char msk_shift; | ||
| 24 | |||
| 25 | int (*clear_irq) (int); | ||
| 26 | }; | ||
| 27 | |||
| 28 | static struct intc2_data intc2_data[NR_INTC2_IRQS]; | ||
| 29 | |||
| 30 | static void enable_intc2_irq(unsigned int irq); | ||
| 31 | static void disable_intc2_irq(unsigned int irq); | ||
| 32 | |||
| 33 | /* shutdown is same as "disable" */ | ||
| 34 | #define shutdown_intc2_irq disable_intc2_irq | ||
| 35 | |||
| 36 | static void mask_and_ack_intc2(unsigned int); | ||
| 37 | static void end_intc2_irq(unsigned int irq); | ||
| 38 | |||
| 39 | static unsigned int startup_intc2_irq(unsigned int irq) | ||
| 40 | { | ||
| 41 | enable_intc2_irq(irq); | ||
| 42 | return 0; /* never anything pending */ | ||
| 43 | } | ||
| 44 | |||
| 45 | static struct hw_interrupt_type intc2_irq_type = { | ||
| 46 | .typename = "INTC2-IRQ", | ||
| 47 | .startup = startup_intc2_irq, | ||
| 48 | .shutdown = shutdown_intc2_irq, | ||
| 49 | .enable = enable_intc2_irq, | ||
| 50 | .disable = disable_intc2_irq, | ||
| 51 | .ack = mask_and_ack_intc2, | ||
| 52 | .end = end_intc2_irq | ||
| 53 | }; | ||
| 54 | |||
| 55 | static void disable_intc2_irq(unsigned int irq) | ||
| 56 | { | ||
| 57 | int irq_offset = irq - INTC2_FIRST_IRQ; | ||
| 58 | int msk_shift, msk_offset; | ||
| 59 | |||
| 60 | /* Sanity check */ | ||
| 61 | if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS)) | ||
| 62 | return; | ||
| 63 | |||
| 64 | msk_shift = intc2_data[irq_offset].msk_shift; | ||
| 65 | msk_offset = intc2_data[irq_offset].msk_offset; | ||
| 66 | |||
| 67 | ctrl_outl(1 << msk_shift, | ||
| 68 | INTC2_BASE + INTC2_INTMSK_OFFSET + msk_offset); | ||
| 69 | } | ||
| 70 | |||
| 71 | static void enable_intc2_irq(unsigned int irq) | ||
| 72 | { | ||
| 73 | int irq_offset = irq - INTC2_FIRST_IRQ; | ||
| 74 | int msk_shift, msk_offset; | ||
| 75 | |||
| 76 | /* Sanity check */ | ||
| 77 | if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS)) | ||
| 78 | return; | ||
| 79 | |||
| 80 | msk_shift = intc2_data[irq_offset].msk_shift; | ||
| 81 | msk_offset = intc2_data[irq_offset].msk_offset; | ||
| 82 | |||
| 83 | ctrl_outl(1 << msk_shift, | ||
| 84 | INTC2_BASE + INTC2_INTMSKCLR_OFFSET + msk_offset); | ||
| 85 | } | ||
| 86 | |||
| 87 | static void mask_and_ack_intc2(unsigned int irq) | ||
| 88 | { | ||
| 89 | disable_intc2_irq(irq); | ||
| 90 | } | ||
| 91 | |||
| 92 | static void end_intc2_irq(unsigned int irq) | ||
| 93 | { | ||
| 94 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
| 95 | enable_intc2_irq(irq); | ||
| 96 | |||
| 97 | if (unlikely(intc2_data[irq - INTC2_FIRST_IRQ].clear_irq)) | ||
| 98 | intc2_data[irq - INTC2_FIRST_IRQ].clear_irq(irq); | ||
| 99 | } | ||
| 100 | |||
| 101 | /* | ||
| 102 | * Setup an INTC2 style interrupt. | ||
| 103 | * NOTE: Unlike IPR interrupts, parameters are not shifted by this code, | ||
| 104 | * allowing the use of the numbers straight out of the datasheet. | ||
| 105 | * For example: | ||
| 106 | * PIO1 which is INTPRI00[19,16] and INTMSK00[13] | ||
| 107 | * would be: ^ ^ ^ ^ | ||
| 108 | * | | | | | ||
| 109 | * make_intc2_irq(84, 0, 16, 0, 13); | ||
| 110 | */ | ||
| 111 | void make_intc2_irq(unsigned int irq, | ||
| 112 | unsigned int ipr_offset, unsigned int ipr_shift, | ||
| 113 | unsigned int msk_offset, unsigned int msk_shift, | ||
| 114 | unsigned int priority) | ||
| 115 | { | ||
| 116 | int irq_offset = irq - INTC2_FIRST_IRQ; | ||
| 117 | unsigned int flags; | ||
| 118 | unsigned long ipr; | ||
| 119 | |||
| 120 | if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS)) | ||
| 121 | return; | ||
| 122 | |||
| 123 | disable_irq_nosync(irq); | ||
| 124 | |||
| 125 | /* Fill the data we need */ | ||
| 126 | intc2_data[irq_offset].msk_offset = msk_offset; | ||
| 127 | intc2_data[irq_offset].msk_shift = msk_shift; | ||
| 128 | intc2_data[irq_offset].clear_irq = NULL; | ||
| 129 | |||
| 130 | /* Set the priority level */ | ||
| 131 | local_irq_save(flags); | ||
| 132 | |||
| 133 | ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET + ipr_offset); | ||
| 134 | ipr &= ~(0xf << ipr_shift); | ||
| 135 | ipr |= priority << ipr_shift; | ||
| 136 | ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET + ipr_offset); | ||
| 137 | |||
| 138 | local_irq_restore(flags); | ||
| 139 | |||
| 140 | irq_desc[irq].handler = &intc2_irq_type; | ||
| 141 | |||
| 142 | disable_intc2_irq(irq); | ||
| 143 | } | ||
| 144 | |||
| 145 | static struct intc2_init { | ||
| 146 | unsigned short irq; | ||
| 147 | unsigned char ipr_offset, ipr_shift; | ||
| 148 | unsigned char msk_offset, msk_shift; | ||
| 149 | unsigned char priority; | ||
| 150 | } intc2_init_data[] __initdata = { | ||
| 151 | #if defined(CONFIG_CPU_SUBTYPE_ST40) | ||
| 152 | {64, 0, 0, 0, 0, 13}, /* PCI serr */ | ||
| 153 | {65, 0, 4, 0, 1, 13}, /* PCI err */ | ||
| 154 | {66, 0, 4, 0, 2, 13}, /* PCI ad */ | ||
| 155 | {67, 0, 4, 0, 3, 13}, /* PCI pwd down */ | ||
| 156 | {72, 0, 8, 0, 5, 13}, /* DMAC INT0 */ | ||
| 157 | {73, 0, 8, 0, 6, 13}, /* DMAC INT1 */ | ||
| 158 | {74, 0, 8, 0, 7, 13}, /* DMAC INT2 */ | ||
| 159 | {75, 0, 8, 0, 8, 13}, /* DMAC INT3 */ | ||
| 160 | {76, 0, 8, 0, 9, 13}, /* DMAC INT4 */ | ||
| 161 | {78, 0, 8, 0, 11, 13}, /* DMAC ERR */ | ||
| 162 | {80, 0, 12, 0, 12, 13}, /* PIO0 */ | ||
| 163 | {84, 0, 16, 0, 13, 13}, /* PIO1 */ | ||
| 164 | {88, 0, 20, 0, 14, 13}, /* PIO2 */ | ||
| 165 | {112, 4, 0, 4, 0, 13}, /* Mailbox */ | ||
| 166 | #ifdef CONFIG_CPU_SUBTYPE_ST40GX1 | ||
| 167 | {116, 4, 4, 4, 4, 13}, /* SSC0 */ | ||
| 168 | {120, 4, 8, 4, 8, 13}, /* IR Blaster */ | ||
| 169 | {124, 4, 12, 4, 12, 13}, /* USB host */ | ||
| 170 | {128, 4, 16, 4, 16, 13}, /* Video processor BLITTER */ | ||
| 171 | {132, 4, 20, 4, 20, 13}, /* UART0 */ | ||
| 172 | {134, 4, 20, 4, 22, 13}, /* UART2 */ | ||
| 173 | {136, 4, 24, 4, 24, 13}, /* IO_PIO0 */ | ||
| 174 | {140, 4, 28, 4, 28, 13}, /* EMPI */ | ||
| 175 | {144, 8, 0, 8, 0, 13}, /* MAFE */ | ||
| 176 | {148, 8, 4, 8, 4, 13}, /* PWM */ | ||
| 177 | {152, 8, 8, 8, 8, 13}, /* SSC1 */ | ||
| 178 | {156, 8, 12, 8, 12, 13}, /* IO_PIO1 */ | ||
| 179 | {160, 8, 16, 8, 16, 13}, /* USB target */ | ||
| 180 | {164, 8, 20, 8, 20, 13}, /* UART1 */ | ||
| 181 | {168, 8, 24, 8, 24, 13}, /* Teletext */ | ||
| 182 | {172, 8, 28, 8, 28, 13}, /* VideoSync VTG */ | ||
| 183 | {173, 8, 28, 8, 29, 13}, /* VideoSync DVP0 */ | ||
| 184 | {174, 8, 28, 8, 30, 13}, /* VideoSync DVP1 */ | ||
| 185 | #endif | ||
| 186 | #elif defined(CONFIG_CPU_SUBTYPE_SH7760) | ||
| 187 | /* | ||
| 188 | * SH7760 INTC2-Style interrupts, vectors IRQ48-111 INTEVT 0x800-0xFE0 | ||
| 189 | */ | ||
| 190 | /* INTPRIO0 | INTMSK0 */ | ||
| 191 | {48, 0, 28, 0, 31, 3}, /* IRQ 4 */ | ||
| 192 | {49, 0, 24, 0, 30, 3}, /* IRQ 3 */ | ||
| 193 | {50, 0, 20, 0, 29, 3}, /* IRQ 2 */ | ||
| 194 | {51, 0, 16, 0, 28, 3}, /* IRQ 1 */ | ||
| 195 | /* 52-55 (INTEVT 0x880-0x8E0) unused/reserved */ | ||
| 196 | /* INTPRIO4 | INTMSK0 */ | ||
| 197 | {56, 4, 28, 0, 25, 3}, /* HCAN2_CHAN0 */ | ||
| 198 | {57, 4, 24, 0, 24, 3}, /* HCAN2_CHAN1 */ | ||
| 199 | {58, 4, 20, 0, 23, 3}, /* I2S_CHAN0 */ | ||
| 200 | {59, 4, 16, 0, 22, 3}, /* I2S_CHAN1 */ | ||
| 201 | {60, 4, 12, 0, 21, 3}, /* AC97_CHAN0 */ | ||
| 202 | {61, 4, 8, 0, 20, 3}, /* AC97_CHAN1 */ | ||
| 203 | {62, 4, 4, 0, 19, 3}, /* I2C_CHAN0 */ | ||
| 204 | {63, 4, 0, 0, 18, 3}, /* I2C_CHAN1 */ | ||
| 205 | /* INTPRIO8 | INTMSK0 */ | ||
| 206 | {52, 8, 16, 0, 11, 3}, /* SCIF0_ERI_IRQ */ | ||
| 207 | {53, 8, 16, 0, 10, 3}, /* SCIF0_RXI_IRQ */ | ||
| 208 | {54, 8, 16, 0, 9, 3}, /* SCIF0_BRI_IRQ */ | ||
| 209 | {55, 8, 16, 0, 8, 3}, /* SCIF0_TXI_IRQ */ | ||
| 210 | {64, 8, 28, 0, 17, 3}, /* USBHI_IRQ */ | ||
| 211 | {65, 8, 24, 0, 16, 3}, /* LCDC */ | ||
| 212 | /* 66, 67 unused */ | ||
| 213 | {68, 8, 20, 0, 14, 13}, /* DMABRGI0_IRQ */ | ||
| 214 | {69, 8, 20, 0, 13, 13}, /* DMABRGI1_IRQ */ | ||
| 215 | {70, 8, 20, 0, 12, 13}, /* DMABRGI2_IRQ */ | ||
| 216 | /* 71 unused */ | ||
| 217 | {72, 8, 12, 0, 7, 3}, /* SCIF1_ERI_IRQ */ | ||
| 218 | {73, 8, 12, 0, 6, 3}, /* SCIF1_RXI_IRQ */ | ||
| 219 | {74, 8, 12, 0, 5, 3}, /* SCIF1_BRI_IRQ */ | ||
| 220 | {75, 8, 12, 0, 4, 3}, /* SCIF1_TXI_IRQ */ | ||
| 221 | {76, 8, 8, 0, 3, 3}, /* SCIF2_ERI_IRQ */ | ||
| 222 | {77, 8, 8, 0, 2, 3}, /* SCIF2_RXI_IRQ */ | ||
| 223 | {78, 8, 8, 0, 1, 3}, /* SCIF2_BRI_IRQ */ | ||
| 224 | {79, 8, 8, 0, 0, 3}, /* SCIF2_TXI_IRQ */ | ||
| 225 | /* | INTMSK4 */ | ||
| 226 | {80, 8, 4, 4, 23, 3}, /* SIM_ERI */ | ||
| 227 | {81, 8, 4, 4, 22, 3}, /* SIM_RXI */ | ||
| 228 | {82, 8, 4, 4, 21, 3}, /* SIM_TXI */ | ||
| 229 | {83, 8, 4, 4, 20, 3}, /* SIM_TEI */ | ||
| 230 | {84, 8, 0, 4, 19, 3}, /* HSPII */ | ||
| 231 | /* INTPRIOC | INTMSK4 */ | ||
| 232 | /* 85-87 unused/reserved */ | ||
| 233 | {88, 12, 20, 4, 18, 3}, /* MMCI0 */ | ||
| 234 | {89, 12, 20, 4, 17, 3}, /* MMCI1 */ | ||
| 235 | {90, 12, 20, 4, 16, 3}, /* MMCI2 */ | ||
| 236 | {91, 12, 20, 4, 15, 3}, /* MMCI3 */ | ||
| 237 | {92, 12, 12, 4, 6, 3}, /* MFI (unsure, bug? in my 7760 manual*/ | ||
| 238 | /* 93-107 reserved/undocumented */ | ||
| 239 | {108,12, 4, 4, 1, 3}, /* ADC */ | ||
| 240 | {109,12, 0, 4, 0, 3}, /* CMTI */ | ||
| 241 | /* 110-111 reserved/unused */ | ||
| 242 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) | ||
| 243 | { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2}, | ||
| 244 | #ifdef CONFIG_SH_RTC | ||
| 245 | { RTC_IRQ, 4, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY }, | ||
| 246 | #endif | ||
| 247 | { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, | ||
| 248 | { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, | ||
| 249 | { SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, | ||
| 250 | { SCIF0_TXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, | ||
| 251 | |||
| 252 | { SCIF1_ERI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, | ||
| 253 | { SCIF1_RXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, | ||
| 254 | { SCIF1_BRI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, | ||
| 255 | { SCIF1_TXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, | ||
| 256 | |||
| 257 | { PCIC0_IRQ, 0x10, 8, 0, INTC_PCIC0_MSK, PCIC0_PRIORITY }, | ||
| 258 | { PCIC1_IRQ, 0x10, 0, 0, INTC_PCIC1_MSK, PCIC1_PRIORITY }, | ||
| 259 | { PCIC2_IRQ, 0x14, 24, 0, INTC_PCIC2_MSK, PCIC2_PRIORITY }, | ||
| 260 | { PCIC3_IRQ, 0x14, 16, 0, INTC_PCIC3_MSK, PCIC3_PRIORITY }, | ||
| 261 | { PCIC4_IRQ, 0x14, 8, 0, INTC_PCIC4_MSK, PCIC4_PRIORITY }, | ||
| 262 | #endif | ||
| 263 | }; | ||
| 264 | |||
| 265 | void __init init_IRQ_intc2(void) | ||
| 266 | { | ||
| 267 | int i; | ||
| 268 | |||
| 269 | for (i = 0; i < ARRAY_SIZE(intc2_init_data); i++) { | ||
| 270 | struct intc2_init *p = intc2_init_data + i; | ||
| 271 | make_intc2_irq(p->irq, p->ipr_offset, p->ipr_shift, | ||
| 272 | p-> msk_offset, p->msk_shift, p->priority); | ||
| 273 | } | ||
| 274 | } | ||
| 275 | |||
| 276 | /* Adds a termination callback to the interrupt */ | ||
| 277 | void intc2_add_clear_irq(int irq, int (*fn)(int)) | ||
| 278 | { | ||
| 279 | if (unlikely(irq < INTC2_FIRST_IRQ)) | ||
| 280 | return; | ||
| 281 | |||
| 282 | intc2_data[irq - INTC2_FIRST_IRQ].clear_irq = fn; | ||
| 283 | } | ||
| 284 | |||
diff --git a/arch/sh/kernel/cpu/irq_ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index 71f92096132b..fdbd718ae5c6 100644 --- a/arch/sh/kernel/cpu/irq_ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | /* $Id: irq_ipr.c,v 1.1.2.1 2002/11/17 10:53:43 mrbrown Exp $ | 1 | /* |
| 2 | * | 2 | * arch/sh/kernel/cpu/irq/ipr.c |
| 3 | * linux/arch/sh/kernel/irq_ipr.c | ||
| 4 | * | 3 | * |
| 5 | * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi | 4 | * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi |
| 6 | * Copyright (C) 2000 Kazumoto Kojima | 5 | * Copyright (C) 2000 Kazumoto Kojima |
| @@ -109,7 +108,8 @@ static void end_ipr_irq(unsigned int irq) | |||
| 109 | enable_ipr_irq(irq); | 108 | enable_ipr_irq(irq); |
| 110 | } | 109 | } |
| 111 | 110 | ||
| 112 | void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority) | 111 | void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, |
| 112 | int priority, int maskpos) | ||
| 113 | { | 113 | { |
| 114 | disable_irq_nosync(irq); | 114 | disable_irq_nosync(irq); |
| 115 | ipr_data[irq].addr = addr; | 115 | ipr_data[irq].addr = addr; |
| @@ -120,126 +120,47 @@ void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority) | |||
| 120 | disable_ipr_irq(irq); | 120 | disable_ipr_irq(irq); |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | ||
| 124 | defined(CONFIG_CPU_SUBTYPE_SH7707) || \ | ||
| 125 | defined(CONFIG_CPU_SUBTYPE_SH7709) | ||
| 126 | static unsigned char pint_map[256]; | ||
| 127 | static unsigned long portcr_mask = 0; | ||
| 128 | |||
| 129 | static void enable_pint_irq(unsigned int irq); | ||
| 130 | static void disable_pint_irq(unsigned int irq); | ||
| 131 | |||
| 132 | /* shutdown is same as "disable" */ | ||
| 133 | #define shutdown_pint_irq disable_pint_irq | ||
| 134 | |||
| 135 | static void mask_and_ack_pint(unsigned int); | ||
| 136 | static void end_pint_irq(unsigned int irq); | ||
| 137 | |||
| 138 | static unsigned int startup_pint_irq(unsigned int irq) | ||
| 139 | { | ||
| 140 | enable_pint_irq(irq); | ||
| 141 | return 0; /* never anything pending */ | ||
| 142 | } | ||
| 143 | |||
| 144 | static struct hw_interrupt_type pint_irq_type = { | ||
| 145 | .typename = "PINT-IRQ", | ||
| 146 | .startup = startup_pint_irq, | ||
| 147 | .shutdown = shutdown_pint_irq, | ||
| 148 | .enable = enable_pint_irq, | ||
| 149 | .disable = disable_pint_irq, | ||
| 150 | .ack = mask_and_ack_pint, | ||
| 151 | .end = end_pint_irq | ||
| 152 | }; | ||
| 153 | |||
| 154 | static void disable_pint_irq(unsigned int irq) | ||
| 155 | { | ||
| 156 | unsigned long val, flags; | ||
| 157 | |||
| 158 | local_irq_save(flags); | ||
| 159 | val = ctrl_inw(INTC_INTER); | ||
| 160 | val &= ~(1 << (irq - PINT_IRQ_BASE)); | ||
| 161 | ctrl_outw(val, INTC_INTER); /* disable PINTn */ | ||
| 162 | portcr_mask &= ~(3 << (irq - PINT_IRQ_BASE)*2); | ||
| 163 | local_irq_restore(flags); | ||
| 164 | } | ||
| 165 | |||
| 166 | static void enable_pint_irq(unsigned int irq) | ||
| 167 | { | ||
| 168 | unsigned long val, flags; | ||
| 169 | |||
| 170 | local_irq_save(flags); | ||
| 171 | val = ctrl_inw(INTC_INTER); | ||
| 172 | val |= 1 << (irq - PINT_IRQ_BASE); | ||
| 173 | ctrl_outw(val, INTC_INTER); /* enable PINTn */ | ||
| 174 | portcr_mask |= 3 << (irq - PINT_IRQ_BASE)*2; | ||
| 175 | local_irq_restore(flags); | ||
| 176 | } | ||
| 177 | |||
| 178 | static void mask_and_ack_pint(unsigned int irq) | ||
| 179 | { | ||
| 180 | disable_pint_irq(irq); | ||
| 181 | } | ||
| 182 | |||
| 183 | static void end_pint_irq(unsigned int irq) | ||
| 184 | { | ||
| 185 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
| 186 | enable_pint_irq(irq); | ||
| 187 | } | ||
| 188 | |||
| 189 | void make_pint_irq(unsigned int irq) | ||
| 190 | { | ||
| 191 | disable_irq_nosync(irq); | ||
| 192 | irq_desc[irq].handler = &pint_irq_type; | ||
| 193 | disable_pint_irq(irq); | ||
| 194 | } | ||
| 195 | #endif | ||
| 196 | |||
| 197 | void __init init_IRQ(void) | 123 | void __init init_IRQ(void) |
| 198 | { | 124 | { |
| 199 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 125 | #ifndef CONFIG_CPU_SUBTYPE_SH7780 |
| 200 | defined(CONFIG_CPU_SUBTYPE_SH7707) || \ | 126 | make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY, 0); |
| 201 | defined(CONFIG_CPU_SUBTYPE_SH7709) | 127 | make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY, 0); |
| 202 | int i; | ||
| 203 | #endif | ||
| 204 | |||
| 205 | make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY); | ||
| 206 | make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY); | ||
| 207 | #if defined(CONFIG_SH_RTC) | 128 | #if defined(CONFIG_SH_RTC) |
| 208 | make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY); | 129 | make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY, 0); |
| 209 | #endif | 130 | #endif |
| 210 | 131 | ||
| 211 | #ifdef SCI_ERI_IRQ | 132 | #ifdef SCI_ERI_IRQ |
| 212 | make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY); | 133 | make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY, 0); |
| 213 | make_ipr_irq(SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY); | 134 | make_ipr_irq(SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY, 0); |
| 214 | make_ipr_irq(SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY); | 135 | make_ipr_irq(SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY, 0); |
| 215 | #endif | 136 | #endif |
| 216 | 137 | ||
| 217 | #ifdef SCIF1_ERI_IRQ | 138 | #ifdef SCIF1_ERI_IRQ |
| 218 | make_ipr_irq(SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY); | 139 | make_ipr_irq(SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0); |
| 219 | make_ipr_irq(SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY); | 140 | make_ipr_irq(SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0); |
| 220 | make_ipr_irq(SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY); | 141 | make_ipr_irq(SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0); |
| 221 | make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY); | 142 | make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0); |
| 222 | #endif | 143 | #endif |
| 223 | 144 | ||
| 224 | #if defined(CONFIG_CPU_SUBTYPE_SH7300) | 145 | #if defined(CONFIG_CPU_SUBTYPE_SH7300) |
| 225 | make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY); | 146 | make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY, 0); |
| 226 | make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); | 147 | make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY, 0); |
| 227 | make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); | 148 | make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY, 0); |
| 228 | make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); | 149 | make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY, 0); |
| 229 | #endif | 150 | #endif |
| 230 | 151 | ||
| 231 | #ifdef SCIF_ERI_IRQ | 152 | #ifdef SCIF_ERI_IRQ |
| 232 | make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); | 153 | make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0); |
| 233 | make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); | 154 | make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0); |
| 234 | make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); | 155 | make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0); |
| 235 | make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); | 156 | make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0); |
| 236 | #endif | 157 | #endif |
| 237 | 158 | ||
| 238 | #ifdef IRDA_ERI_IRQ | 159 | #ifdef IRDA_ERI_IRQ |
| 239 | make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); | 160 | make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0); |
| 240 | make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); | 161 | make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0); |
| 241 | make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); | 162 | make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0); |
| 242 | make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); | 163 | make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0); |
| 243 | #endif | 164 | #endif |
| 244 | 165 | ||
| 245 | #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ | 166 | #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ |
| @@ -254,86 +175,32 @@ void __init init_IRQ(void) | |||
| 254 | * You should set corresponding bits of PFC to "00" | 175 | * You should set corresponding bits of PFC to "00" |
| 255 | * to enable these interrupts. | 176 | * to enable these interrupts. |
| 256 | */ | 177 | */ |
| 257 | make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY); | 178 | make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY, 0); |
| 258 | make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY); | 179 | make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY, 0); |
| 259 | make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY); | 180 | make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY, 0); |
| 260 | make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY); | 181 | make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY, 0); |
| 261 | make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY); | 182 | make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY, 0); |
| 262 | make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY); | 183 | make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY, 0); |
| 263 | #if !defined(CONFIG_CPU_SUBTYPE_SH7300) | 184 | #endif |
| 264 | make_ipr_irq(PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY); | 185 | #endif |
| 265 | make_ipr_irq(PINT8_IRQ, PINT8_IPR_ADDR, PINT8_IPR_POS, PINT8_PRIORITY); | ||
| 266 | enable_ipr_irq(PINT0_IRQ); | ||
| 267 | enable_ipr_irq(PINT8_IRQ); | ||
| 268 | 186 | ||
| 269 | for(i = 0; i < 16; i++) | 187 | #ifdef CONFIG_CPU_HAS_PINT_IRQ |
| 270 | make_pint_irq(PINT_IRQ_BASE + i); | 188 | init_IRQ_pint(); |
| 271 | for(i = 0; i < 256; i++) | 189 | #endif |
| 272 | { | ||
| 273 | if(i & 1) pint_map[i] = 0; | ||
| 274 | else if(i & 2) pint_map[i] = 1; | ||
| 275 | else if(i & 4) pint_map[i] = 2; | ||
| 276 | else if(i & 8) pint_map[i] = 3; | ||
| 277 | else if(i & 0x10) pint_map[i] = 4; | ||
| 278 | else if(i & 0x20) pint_map[i] = 5; | ||
| 279 | else if(i & 0x40) pint_map[i] = 6; | ||
| 280 | else if(i & 0x80) pint_map[i] = 7; | ||
| 281 | } | ||
| 282 | #endif /* !CONFIG_CPU_SUBTYPE_SH7300 */ | ||
| 283 | #endif /* CONFIG_CPU_SUBTYPE_SH7707 || CONFIG_CPU_SUBTYPE_SH7709 || CONFIG_CPU_SUBTYPE_SH7300*/ | ||
| 284 | 190 | ||
| 285 | #ifdef CONFIG_CPU_SUBTYPE_ST40 | 191 | #ifdef CONFIG_CPU_HAS_INTC2_IRQ |
| 286 | init_IRQ_intc2(); | 192 | init_IRQ_intc2(); |
| 287 | #endif | 193 | #endif |
| 288 | |||
| 289 | /* Perform the machine specific initialisation */ | 194 | /* Perform the machine specific initialisation */ |
| 290 | if (sh_mv.mv_init_irq != NULL) { | 195 | if (sh_mv.mv_init_irq != NULL) |
| 291 | sh_mv.mv_init_irq(); | 196 | sh_mv.mv_init_irq(); |
| 292 | } | ||
| 293 | } | 197 | } |
| 294 | #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ | 198 | |
| 295 | defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) | 199 | #if !defined(CONFIG_CPU_HAS_PINT_IRQ) |
| 296 | int ipr_irq_demux(int irq) | 200 | int ipr_irq_demux(int irq) |
| 297 | { | 201 | { |
| 298 | #if !defined(CONFIG_CPU_SUBTYPE_SH7300) | ||
| 299 | unsigned long creg, dreg, d, sav; | ||
| 300 | |||
| 301 | if(irq == PINT0_IRQ) | ||
| 302 | { | ||
| 303 | #if defined(CONFIG_CPU_SUBTYPE_SH7707) | ||
| 304 | creg = PORT_PACR; | ||
| 305 | dreg = PORT_PADR; | ||
| 306 | #else | ||
| 307 | creg = PORT_PCCR; | ||
| 308 | dreg = PORT_PCDR; | ||
| 309 | #endif | ||
| 310 | sav = ctrl_inw(creg); | ||
| 311 | ctrl_outw(sav | portcr_mask, creg); | ||
| 312 | d = (~ctrl_inb(dreg) ^ ctrl_inw(INTC_ICR2)) & ctrl_inw(INTC_INTER) & 0xff; | ||
| 313 | ctrl_outw(sav, creg); | ||
| 314 | if(d == 0) return irq; | ||
| 315 | return PINT_IRQ_BASE + pint_map[d]; | ||
| 316 | } | ||
| 317 | else if(irq == PINT8_IRQ) | ||
| 318 | { | ||
| 319 | #if defined(CONFIG_CPU_SUBTYPE_SH7707) | ||
| 320 | creg = PORT_PBCR; | ||
| 321 | dreg = PORT_PBDR; | ||
| 322 | #else | ||
| 323 | creg = PORT_PFCR; | ||
| 324 | dreg = PORT_PFDR; | ||
| 325 | #endif | ||
| 326 | sav = ctrl_inw(creg); | ||
| 327 | ctrl_outw(sav | (portcr_mask >> 16), creg); | ||
| 328 | d = (~ctrl_inb(dreg) ^ (ctrl_inw(INTC_ICR2) >> 8)) & (ctrl_inw(INTC_INTER) >> 8) & 0xff; | ||
| 329 | ctrl_outw(sav, creg); | ||
| 330 | if(d == 0) return irq; | ||
| 331 | return PINT_IRQ_BASE + 8 + pint_map[d]; | ||
| 332 | } | ||
| 333 | #endif | ||
| 334 | return irq; | 202 | return irq; |
| 335 | } | 203 | } |
| 336 | #endif | 204 | #endif |
| 337 | 205 | ||
| 338 | EXPORT_SYMBOL(make_ipr_irq); | 206 | EXPORT_SYMBOL(make_ipr_irq); |
| 339 | |||
diff --git a/arch/sh/kernel/cpu/irq/pint.c b/arch/sh/kernel/cpu/irq/pint.c new file mode 100644 index 000000000000..95d6024fe1ae --- /dev/null +++ b/arch/sh/kernel/cpu/irq/pint.c | |||
| @@ -0,0 +1,169 @@ | |||
| 1 | /* | ||
| 2 | * arch/sh/kernel/cpu/irq/pint.c - Interrupt handling for PINT-based IRQs. | ||
| 3 | * | ||
| 4 | * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi | ||
| 5 | * Copyright (C) 2000 Kazumoto Kojima | ||
| 6 | * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp> | ||
| 7 | * | ||
| 8 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 9 | * License. See the file "COPYING" in the main directory of this archive | ||
| 10 | * for more details. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/config.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/irq.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | |||
| 18 | #include <asm/system.h> | ||
| 19 | #include <asm/io.h> | ||
| 20 | #include <asm/machvec.h> | ||
| 21 | |||
| 22 | static unsigned char pint_map[256]; | ||
| 23 | static unsigned long portcr_mask; | ||
| 24 | |||
| 25 | static void enable_pint_irq(unsigned int irq); | ||
| 26 | static void disable_pint_irq(unsigned int irq); | ||
| 27 | |||
| 28 | /* shutdown is same as "disable" */ | ||
| 29 | #define shutdown_pint_irq disable_pint_irq | ||
| 30 | |||
| 31 | static void mask_and_ack_pint(unsigned int); | ||
| 32 | static void end_pint_irq(unsigned int irq); | ||
| 33 | |||
| 34 | static unsigned int startup_pint_irq(unsigned int irq) | ||
| 35 | { | ||
| 36 | enable_pint_irq(irq); | ||
| 37 | return 0; /* never anything pending */ | ||
| 38 | } | ||
| 39 | |||
| 40 | static struct hw_interrupt_type pint_irq_type = { | ||
| 41 | .typename = "PINT-IRQ", | ||
| 42 | .startup = startup_pint_irq, | ||
| 43 | .shutdown = shutdown_pint_irq, | ||
| 44 | .enable = enable_pint_irq, | ||
| 45 | .disable = disable_pint_irq, | ||
| 46 | .ack = mask_and_ack_pint, | ||
| 47 | .end = end_pint_irq | ||
| 48 | }; | ||
| 49 | |||
| 50 | static void disable_pint_irq(unsigned int irq) | ||
| 51 | { | ||
| 52 | unsigned long val, flags; | ||
| 53 | |||
| 54 | local_irq_save(flags); | ||
| 55 | val = ctrl_inw(INTC_INTER); | ||
| 56 | val &= ~(1 << (irq - PINT_IRQ_BASE)); | ||
| 57 | ctrl_outw(val, INTC_INTER); /* disable PINTn */ | ||
| 58 | portcr_mask &= ~(3 << (irq - PINT_IRQ_BASE)*2); | ||
| 59 | local_irq_restore(flags); | ||
| 60 | } | ||
| 61 | |||
| 62 | static void enable_pint_irq(unsigned int irq) | ||
| 63 | { | ||
| 64 | unsigned long val, flags; | ||
| 65 | |||
| 66 | local_irq_save(flags); | ||
| 67 | val = ctrl_inw(INTC_INTER); | ||
| 68 | val |= 1 << (irq - PINT_IRQ_BASE); | ||
| 69 | ctrl_outw(val, INTC_INTER); /* enable PINTn */ | ||
| 70 | portcr_mask |= 3 << (irq - PINT_IRQ_BASE)*2; | ||
| 71 | local_irq_restore(flags); | ||
| 72 | } | ||
| 73 | |||
| 74 | static void mask_and_ack_pint(unsigned int irq) | ||
| 75 | { | ||
| 76 | disable_pint_irq(irq); | ||
| 77 | } | ||
| 78 | |||
| 79 | static void end_pint_irq(unsigned int irq) | ||
| 80 | { | ||
| 81 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
| 82 | enable_pint_irq(irq); | ||
| 83 | } | ||
| 84 | |||
| 85 | void make_pint_irq(unsigned int irq) | ||
| 86 | { | ||
| 87 | disable_irq_nosync(irq); | ||
| 88 | irq_desc[irq].handler = &pint_irq_type; | ||
| 89 | disable_pint_irq(irq); | ||
| 90 | } | ||
| 91 | |||
| 92 | void __init init_IRQ_pint(void) | ||
| 93 | { | ||
| 94 | int i; | ||
| 95 | |||
| 96 | make_ipr_irq(PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY); | ||
| 97 | make_ipr_irq(PINT8_IRQ, PINT8_IPR_ADDR, PINT8_IPR_POS, PINT8_PRIORITY); | ||
| 98 | |||
| 99 | enable_irq(PINT0_IRQ); | ||
| 100 | enable_irq(PINT8_IRQ); | ||
| 101 | |||
| 102 | for(i = 0; i < 16; i++) | ||
| 103 | make_pint_irq(PINT_IRQ_BASE + i); | ||
| 104 | |||
| 105 | for(i = 0; i < 256; i++) { | ||
| 106 | if (i & 1) | ||
| 107 | pint_map[i] = 0; | ||
| 108 | else if (i & 2) | ||
| 109 | pint_map[i] = 1; | ||
| 110 | else if (i & 4) | ||
| 111 | pint_map[i] = 2; | ||
| 112 | else if (i & 8) | ||
| 113 | pint_map[i] = 3; | ||
| 114 | else if (i & 0x10) | ||
| 115 | pint_map[i] = 4; | ||
| 116 | else if (i & 0x20) | ||
| 117 | pint_map[i] = 5; | ||
| 118 | else if (i & 0x40) | ||
| 119 | pint_map[i] = 6; | ||
| 120 | else if (i & 0x80) | ||
| 121 | pint_map[i] = 7; | ||
| 122 | } | ||
| 123 | } | ||
| 124 | |||
| 125 | int ipr_irq_demux(int irq) | ||
| 126 | { | ||
| 127 | unsigned long creg, dreg, d, sav; | ||
| 128 | |||
| 129 | if (irq == PINT0_IRQ) { | ||
| 130 | #if defined(CONFIG_CPU_SUBTYPE_SH7707) | ||
| 131 | creg = PORT_PACR; | ||
| 132 | dreg = PORT_PADR; | ||
| 133 | #else | ||
| 134 | creg = PORT_PCCR; | ||
| 135 | dreg = PORT_PCDR; | ||
| 136 | #endif | ||
| 137 | sav = ctrl_inw(creg); | ||
| 138 | ctrl_outw(sav | portcr_mask, creg); | ||
| 139 | d = (~ctrl_inb(dreg) ^ ctrl_inw(INTC_ICR2)) & | ||
| 140 | ctrl_inw(INTC_INTER) & 0xff; | ||
| 141 | ctrl_outw(sav, creg); | ||
| 142 | |||
| 143 | if (d == 0) | ||
| 144 | return irq; | ||
| 145 | |||
| 146 | return PINT_IRQ_BASE + pint_map[d]; | ||
| 147 | } else if (irq == PINT8_IRQ) { | ||
| 148 | #if defined(CONFIG_CPU_SUBTYPE_SH7707) | ||
| 149 | creg = PORT_PBCR; | ||
| 150 | dreg = PORT_PBDR; | ||
| 151 | #else | ||
| 152 | creg = PORT_PFCR; | ||
| 153 | dreg = PORT_PFDR; | ||
| 154 | #endif | ||
| 155 | sav = ctrl_inw(creg); | ||
| 156 | ctrl_outw(sav | (portcr_mask >> 16), creg); | ||
| 157 | d = (~ctrl_inb(dreg) ^ (ctrl_inw(INTC_ICR2) >> 8)) & | ||
| 158 | (ctrl_inw(INTC_INTER) >> 8) & 0xff; | ||
| 159 | ctrl_outw(sav, creg); | ||
| 160 | |||
| 161 | if (d == 0) | ||
| 162 | return irq; | ||
| 163 | |||
| 164 | return PINT_IRQ_BASE + 8 + pint_map[d]; | ||
| 165 | } | ||
| 166 | |||
| 167 | return irq; | ||
| 168 | } | ||
| 169 | |||
diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile index a64532e4dc63..b54dbb9a0c86 100644 --- a/arch/sh/kernel/cpu/sh3/Makefile +++ b/arch/sh/kernel/cpu/sh3/Makefile | |||
| @@ -4,3 +4,10 @@ | |||
| 4 | 4 | ||
| 5 | obj-y := ex.o probe.o | 5 | obj-y := ex.o probe.o |
| 6 | 6 | ||
| 7 | clock-$(CONFIG_CPU_SH3) := clock-sh3.o | ||
| 8 | clock-$(CONFIG_CPU_SUBTYPE_SH7300) := clock-sh7300.o | ||
| 9 | clock-$(CONFIG_CPU_SUBTYPE_SH7705) := clock-sh7705.o | ||
| 10 | clock-$(CONFIG_CPU_SUBTYPE_SH7709) := clock-sh7709.o | ||
| 11 | |||
| 12 | obj-y += $(clock-y) | ||
| 13 | |||
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh3.c b/arch/sh/kernel/cpu/sh3/clock-sh3.c new file mode 100644 index 000000000000..c3c945958baf --- /dev/null +++ b/arch/sh/kernel/cpu/sh3/clock-sh3.c | |||
| @@ -0,0 +1,89 @@ | |||
| 1 | /* | ||
| 2 | * arch/sh/kernel/cpu/sh3/clock-sh3.c | ||
| 3 | * | ||
| 4 | * Generic SH-3 support for the clock framework | ||
| 5 | * | ||
| 6 | * Copyright (C) 2005 Paul Mundt | ||
| 7 | * | ||
| 8 | * FRQCR parsing hacked out of arch/sh/kernel/time.c | ||
| 9 | * | ||
| 10 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka | ||
| 11 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> | ||
| 12 | * Copyright (C) 2002, 2003, 2004 Paul Mundt | ||
| 13 | * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> | ||
| 14 | * | ||
| 15 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 16 | * License. See the file "COPYING" in the main directory of this archive | ||
| 17 | * for more details. | ||
| 18 | */ | ||
| 19 | #include <linux/init.h> | ||
| 20 | #include <linux/kernel.h> | ||
| 21 | #include <asm/clock.h> | ||
| 22 | #include <asm/freq.h> | ||
| 23 | #include <asm/io.h> | ||
| 24 | |||
| 25 | static int stc_multipliers[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; | ||
| 26 | static int ifc_divisors[] = { 1, 2, 3, 4, 1, 1, 1, 1 }; | ||
| 27 | static int pfc_divisors[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; | ||
| 28 | |||
| 29 | static void master_clk_init(struct clk *clk) | ||
| 30 | { | ||
| 31 | int frqcr = ctrl_inw(FRQCR); | ||
| 32 | int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); | ||
| 33 | |||
| 34 | clk->rate *= pfc_divisors[idx]; | ||
| 35 | } | ||
| 36 | |||
| 37 | static struct clk_ops sh3_master_clk_ops = { | ||
| 38 | .init = master_clk_init, | ||
| 39 | }; | ||
| 40 | |||
| 41 | static void module_clk_recalc(struct clk *clk) | ||
| 42 | { | ||
| 43 | int frqcr = ctrl_inw(FRQCR); | ||
| 44 | int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); | ||
| 45 | |||
| 46 | clk->rate = clk->parent->rate / pfc_divisors[idx]; | ||
| 47 | } | ||
| 48 | |||
| 49 | static struct clk_ops sh3_module_clk_ops = { | ||
| 50 | .recalc = module_clk_recalc, | ||
| 51 | }; | ||
| 52 | |||
| 53 | static void bus_clk_recalc(struct clk *clk) | ||
| 54 | { | ||
| 55 | int frqcr = ctrl_inw(FRQCR); | ||
| 56 | int idx = ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4); | ||
| 57 | |||
| 58 | clk->rate = clk->parent->rate / stc_multipliers[idx]; | ||
| 59 | } | ||
| 60 | |||
| 61 | static struct clk_ops sh3_bus_clk_ops = { | ||
| 62 | .recalc = bus_clk_recalc, | ||
| 63 | }; | ||
| 64 | |||
| 65 | static void cpu_clk_recalc(struct clk *clk) | ||
| 66 | { | ||
| 67 | int frqcr = ctrl_inw(FRQCR); | ||
| 68 | int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2); | ||
| 69 | |||
| 70 | clk->rate = clk->parent->rate / ifc_divisors[idx]; | ||
| 71 | } | ||
| 72 | |||
| 73 | static struct clk_ops sh3_cpu_clk_ops = { | ||
| 74 | .recalc = cpu_clk_recalc, | ||
| 75 | }; | ||
| 76 | |||
| 77 | static struct clk_ops *sh3_clk_ops[] = { | ||
| 78 | &sh3_master_clk_ops, | ||
| 79 | &sh3_module_clk_ops, | ||
| 80 | &sh3_bus_clk_ops, | ||
| 81 | &sh3_cpu_clk_ops, | ||
| 82 | }; | ||
| 83 | |||
| 84 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | ||
| 85 | { | ||
| 86 | if (idx < ARRAY_SIZE(sh3_clk_ops)) | ||
| 87 | *ops = sh3_clk_ops[idx]; | ||
| 88 | } | ||
| 89 | |||
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7300.c b/arch/sh/kernel/cpu/sh3/clock-sh7300.c new file mode 100644 index 000000000000..e804174b9625 --- /dev/null +++ b/arch/sh/kernel/cpu/sh3/clock-sh7300.c | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | /* | ||
| 2 | * arch/sh/kernel/cpu/sh3/clock-sh7300.c | ||
| 3 | * | ||
| 4 | * SH7300 support for the clock framework | ||
| 5 | * | ||
| 6 | * Copyright (C) 2005 Paul Mundt | ||
| 7 | * | ||
| 8 | * FRQCR parsing hacked out of arch/sh/kernel/time.c | ||
| 9 | * | ||
| 10 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka | ||
| 11 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> | ||
| 12 | * Copyright (C) 2002, 2003, 2004 Paul Mundt | ||
| 13 | * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> | ||
| 14 | * | ||
| 15 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 16 | * License. See the file "COPYING" in the main directory of this archive | ||
| 17 | * for more details. | ||
| 18 | */ | ||
| 19 | #include <linux/init.h> | ||
| 20 | #include <linux/kernel.h> | ||
| 21 | #include <asm/clock.h> | ||
| 22 | #include <asm/freq.h> | ||
| 23 | #include <asm/io.h> | ||
| 24 | |||
| 25 | static int md_table[] = { 1, 2, 3, 4, 6, 8, 12 }; | ||
| 26 | |||
| 27 | static void master_clk_init(struct clk *clk) | ||
| 28 | { | ||
| 29 | clk->rate *= md_table[ctrl_inw(FRQCR) & 0x0007]; | ||
| 30 | } | ||
| 31 | |||
| 32 | static struct clk_ops sh7300_master_clk_ops = { | ||
| 33 | .init = master_clk_init, | ||
| 34 | }; | ||
| 35 | |||
| 36 | static void module_clk_recalc(struct clk *clk) | ||
| 37 | { | ||
| 38 | int idx = (ctrl_inw(FRQCR) & 0x0007); | ||
| 39 | clk->rate = clk->parent->rate / md_table[idx]; | ||
| 40 | } | ||
| 41 | |||
| 42 | static struct clk_ops sh7300_module_clk_ops = { | ||
| 43 | .recalc = module_clk_recalc, | ||
| 44 | }; | ||
| 45 | |||
| 46 | static void bus_clk_recalc(struct clk *clk) | ||
| 47 | { | ||
| 48 | int idx = (ctrl_inw(FRQCR) & 0x0700) >> 8; | ||
| 49 | clk->rate = clk->parent->rate / md_table[idx]; | ||
| 50 | } | ||
| 51 | |||
| 52 | static struct clk_ops sh7300_bus_clk_ops = { | ||
| 53 | .recalc = bus_clk_recalc, | ||
| 54 | }; | ||
| 55 | |||
| 56 | static void cpu_clk_recalc(struct clk *clk) | ||
| 57 | { | ||
| 58 | int idx = (ctrl_inw(FRQCR) & 0x0070) >> 4; | ||
| 59 | clk->rate = clk->parent->rate / md_table[idx]; | ||
| 60 | } | ||
| 61 | |||
| 62 | static struct clk_ops sh7300_cpu_clk_ops = { | ||
| 63 | .recalc = cpu_clk_recalc, | ||
| 64 | }; | ||
| 65 | |||
| 66 | static struct clk_ops *sh7300_clk_ops[] = { | ||
| 67 | &sh7300_master_clk_ops, | ||
| 68 | &sh7300_module_clk_ops, | ||
| 69 | &sh7300_bus_clk_ops, | ||
| 70 | &sh7300_cpu_clk_ops, | ||
| 71 | }; | ||
| 72 | |||
| 73 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | ||
| 74 | { | ||
| 75 | if (idx < ARRAY_SIZE(sh7300_clk_ops)) | ||
| 76 | *ops = sh7300_clk_ops[idx]; | ||
| 77 | } | ||
| 78 | |||
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7705.c b/arch/sh/kernel/cpu/sh3/clock-sh7705.c new file mode 100644 index 000000000000..dfdbf3277fd7 --- /dev/null +++ b/arch/sh/kernel/cpu/sh3/clock-sh7705.c | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | /* | ||
| 2 | * arch/sh/kernel/cpu/sh3/clock-sh7705.c | ||
| 3 | * | ||
| 4 | * SH7705 support for the clock framework | ||
| 5 | * | ||
| 6 | * Copyright (C) 2005 Paul Mundt | ||
| 7 | * | ||
| 8 | * FRQCR parsing hacked out of arch/sh/kernel/time.c | ||
| 9 | * | ||
| 10 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka | ||
| 11 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> | ||
| 12 | * Copyright (C) 2002, 2003, 2004 Paul Mundt | ||
| 13 | * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> | ||
| 14 | * | ||
| 15 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 16 | * License. See the file "COPYING" in the main directory of this archive | ||
| 17 | * for more details. | ||
| 18 | */ | ||
| 19 | #include <linux/init.h> | ||
| 20 | #include <linux/kernel.h> | ||
| 21 | #include <asm/clock.h> | ||
| 22 | #include <asm/freq.h> | ||
| 23 | #include <asm/io.h> | ||
| 24 | |||
| 25 | /* | ||
| 26 | * SH7705 uses the same divisors as the generic SH-3 case, it's just the | ||
| 27 | * FRQCR layout that is a bit different.. | ||
| 28 | */ | ||
| 29 | static int stc_multipliers[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; | ||
| 30 | static int ifc_divisors[] = { 1, 2, 3, 4, 1, 1, 1, 1 }; | ||
| 31 | static int pfc_divisors[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; | ||
| 32 | |||
| 33 | static void master_clk_init(struct clk *clk) | ||
| 34 | { | ||
| 35 | clk->rate *= pfc_divisors[ctrl_inw(FRQCR) & 0x0003]; | ||
| 36 | } | ||
| 37 | |||
| 38 | static struct clk_ops sh7705_master_clk_ops = { | ||
| 39 | .init = master_clk_init, | ||
| 40 | }; | ||
| 41 | |||
| 42 | static void module_clk_recalc(struct clk *clk) | ||
| 43 | { | ||
| 44 | int idx = ctrl_inw(FRQCR) & 0x0003; | ||
| 45 | clk->rate = clk->parent->rate / pfc_divisors[idx]; | ||
| 46 | } | ||
| 47 | |||
| 48 | static struct clk_ops sh7705_module_clk_ops = { | ||
| 49 | .recalc = module_clk_recalc, | ||
| 50 | }; | ||
| 51 | |||
| 52 | static void bus_clk_recalc(struct clk *clk) | ||
| 53 | { | ||
| 54 | int idx = (ctrl_inw(FRQCR) & 0x0300) >> 8; | ||
| 55 | clk->rate = clk->parent->rate / stc_multipliers[idx]; | ||
| 56 | } | ||
| 57 | |||
| 58 | static struct clk_ops sh7705_bus_clk_ops = { | ||
| 59 | .recalc = bus_clk_recalc, | ||
| 60 | }; | ||
| 61 | |||
| 62 | static void cpu_clk_recalc(struct clk *clk) | ||
| 63 | { | ||
| 64 | int idx = (ctrl_inw(FRQCR) & 0x0030) >> 4; | ||
| 65 | clk->rate = clk->parent->rate / ifc_divisors[idx]; | ||
| 66 | } | ||
| 67 | |||
| 68 | static struct clk_ops sh7705_cpu_clk_ops = { | ||
| 69 | .recalc = cpu_clk_recalc, | ||
| 70 | }; | ||
| 71 | |||
| 72 | static struct clk_ops *sh7705_clk_ops[] = { | ||
| 73 | &sh7705_master_clk_ops, | ||
| 74 | &sh7705_module_clk_ops, | ||
| 75 | &sh7705_bus_clk_ops, | ||
| 76 | &sh7705_cpu_clk_ops, | ||
| 77 | }; | ||
| 78 | |||
| 79 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | ||
| 80 | { | ||
| 81 | if (idx < ARRAY_SIZE(sh7705_clk_ops)) | ||
| 82 | *ops = sh7705_clk_ops[idx]; | ||
| 83 | } | ||
| 84 | |||
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7709.c b/arch/sh/kernel/cpu/sh3/clock-sh7709.c new file mode 100644 index 000000000000..10461a745e5f --- /dev/null +++ b/arch/sh/kernel/cpu/sh3/clock-sh7709.c | |||
| @@ -0,0 +1,96 @@ | |||
| 1 | /* | ||
| 2 | * arch/sh/kernel/cpu/sh3/clock-sh7709.c | ||
| 3 | * | ||
| 4 | * SH7709 support for the clock framework | ||
| 5 | * | ||
| 6 | * Copyright (C) 2005 Andriy Skulysh | ||
| 7 | * | ||
| 8 | * Based on arch/sh/kernel/cpu/sh3/clock-sh7705.c | ||
| 9 | * Copyright (C) 2005 Paul Mundt | ||
| 10 | * | ||
| 11 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 12 | * License. See the file "COPYING" in the main directory of this archive | ||
| 13 | * for more details. | ||
| 14 | */ | ||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <asm/clock.h> | ||
| 18 | #include <asm/freq.h> | ||
| 19 | #include <asm/io.h> | ||
| 20 | |||
| 21 | static int stc_multipliers[] = { 1, 2, 4, 8, 3, 6, 1, 1 }; | ||
| 22 | static int ifc_divisors[] = { 1, 2, 4, 1, 3, 1, 1, 1 }; | ||
| 23 | static int pfc_divisors[] = { 1, 2, 4, 1, 3, 6, 1, 1 }; | ||
| 24 | |||
| 25 | static void set_bus_parent(struct clk *clk) | ||
| 26 | { | ||
| 27 | struct clk *bus_clk = clk_get("bus_clk"); | ||
| 28 | clk->parent = bus_clk; | ||
| 29 | clk_put(bus_clk); | ||
| 30 | } | ||
| 31 | |||
| 32 | static void master_clk_init(struct clk *clk) | ||
| 33 | { | ||
| 34 | int frqcr = ctrl_inw(FRQCR); | ||
| 35 | int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); | ||
| 36 | |||
| 37 | clk->rate *= pfc_divisors[idx]; | ||
| 38 | } | ||
| 39 | |||
| 40 | static struct clk_ops sh7709_master_clk_ops = { | ||
| 41 | .init = master_clk_init, | ||
| 42 | }; | ||
| 43 | |||
| 44 | static void module_clk_recalc(struct clk *clk) | ||
| 45 | { | ||
| 46 | int frqcr = ctrl_inw(FRQCR); | ||
| 47 | int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); | ||
| 48 | |||
| 49 | clk->rate = clk->parent->rate / pfc_divisors[idx]; | ||
| 50 | } | ||
| 51 | |||
| 52 | static struct clk_ops sh7709_module_clk_ops = { | ||
| 53 | #ifdef CLOCK_MODE_0_1_2_7 | ||
| 54 | .init = set_bus_parent, | ||
| 55 | #endif | ||
| 56 | .recalc = module_clk_recalc, | ||
| 57 | }; | ||
| 58 | |||
| 59 | static void bus_clk_recalc(struct clk *clk) | ||
| 60 | { | ||
| 61 | int frqcr = ctrl_inw(FRQCR); | ||
| 62 | int idx = (frqcr & 0x0080) ? | ||
| 63 | ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4) : 1; | ||
| 64 | |||
| 65 | clk->rate = clk->parent->rate * stc_multipliers[idx]; | ||
| 66 | } | ||
| 67 | |||
| 68 | static struct clk_ops sh7709_bus_clk_ops = { | ||
| 69 | .recalc = bus_clk_recalc, | ||
| 70 | }; | ||
| 71 | |||
| 72 | static void cpu_clk_recalc(struct clk *clk) | ||
| 73 | { | ||
| 74 | int frqcr = ctrl_inw(FRQCR); | ||
| 75 | int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2); | ||
| 76 | |||
| 77 | clk->rate = clk->parent->rate / ifc_divisors[idx]; | ||
| 78 | } | ||
| 79 | |||
| 80 | static struct clk_ops sh7709_cpu_clk_ops = { | ||
| 81 | .init = set_bus_parent, | ||
| 82 | .recalc = cpu_clk_recalc, | ||
| 83 | }; | ||
| 84 | |||
| 85 | static struct clk_ops *sh7709_clk_ops[] = { | ||
| 86 | &sh7709_master_clk_ops, | ||
| 87 | &sh7709_module_clk_ops, | ||
| 88 | &sh7709_bus_clk_ops, | ||
| 89 | &sh7709_cpu_clk_ops, | ||
| 90 | }; | ||
| 91 | |||
| 92 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | ||
| 93 | { | ||
| 94 | if (idx < ARRAY_SIZE(sh7709_clk_ops)) | ||
| 95 | *ops = sh7709_clk_ops[idx]; | ||
| 96 | } | ||
diff --git a/arch/sh/kernel/cpu/sh4/Makefile b/arch/sh/kernel/cpu/sh4/Makefile index ead1071eac73..3d5cafc71ae3 100644 --- a/arch/sh/kernel/cpu/sh4/Makefile +++ b/arch/sh/kernel/cpu/sh4/Makefile | |||
| @@ -5,6 +5,15 @@ | |||
| 5 | obj-y := ex.o probe.o | 5 | obj-y := ex.o probe.o |
| 6 | 6 | ||
| 7 | obj-$(CONFIG_SH_FPU) += fpu.o | 7 | obj-$(CONFIG_SH_FPU) += fpu.o |
| 8 | obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += irq_intc2.o | ||
| 9 | obj-$(CONFIG_SH_STORE_QUEUES) += sq.o | 8 | obj-$(CONFIG_SH_STORE_QUEUES) += sq.o |
| 10 | 9 | ||
| 10 | # Primary on-chip clocks (common) | ||
| 11 | clock-$(CONFIG_CPU_SH4) := clock-sh4.o | ||
| 12 | clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o | ||
| 13 | clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o | ||
| 14 | clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o | ||
| 15 | |||
| 16 | # Additional clocks by subtype | ||
| 17 | clock-$(CONFIG_CPU_SUBTYPE_SH4_202) += clock-sh4-202.o | ||
| 18 | |||
| 19 | obj-y += $(clock-y) | ||
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c new file mode 100644 index 000000000000..bfdf5fe8d948 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c | |||
| @@ -0,0 +1,179 @@ | |||
| 1 | /* | ||
| 2 | * arch/sh/kernel/cpu/sh4/clock-sh4-202.c | ||
| 3 | * | ||
| 4 | * Additional SH4-202 support for the clock framework | ||
| 5 | * | ||
| 6 | * Copyright (C) 2005 Paul Mundt | ||
| 7 | * | ||
| 8 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 9 | * License. See the file "COPYING" in the main directory of this archive | ||
| 10 | * for more details. | ||
| 11 | */ | ||
| 12 | #include <linux/init.h> | ||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/err.h> | ||
| 15 | #include <asm/clock.h> | ||
| 16 | #include <asm/freq.h> | ||
| 17 | #include <asm/io.h> | ||
| 18 | |||
| 19 | #define CPG2_FRQCR3 0xfe0a0018 | ||
| 20 | |||
| 21 | static int frqcr3_divisors[] = { 1, 2, 3, 4, 6, 8, 16 }; | ||
| 22 | static int frqcr3_values[] = { 0, 1, 2, 3, 4, 5, 6 }; | ||
| 23 | |||
| 24 | static void emi_clk_recalc(struct clk *clk) | ||
| 25 | { | ||
| 26 | int idx = ctrl_inl(CPG2_FRQCR3) & 0x0007; | ||
| 27 | clk->rate = clk->parent->rate / frqcr3_divisors[idx]; | ||
| 28 | } | ||
| 29 | |||
| 30 | static inline int frqcr3_lookup(struct clk *clk, unsigned long rate) | ||
| 31 | { | ||
| 32 | int divisor = clk->parent->rate / rate; | ||
| 33 | int i; | ||
| 34 | |||
| 35 | for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) | ||
| 36 | if (frqcr3_divisors[i] == divisor) | ||
| 37 | return frqcr3_values[i]; | ||
| 38 | |||
| 39 | /* Safe fallback */ | ||
| 40 | return 5; | ||
| 41 | } | ||
| 42 | |||
| 43 | static struct clk_ops sh4202_emi_clk_ops = { | ||
| 44 | .recalc = emi_clk_recalc, | ||
| 45 | }; | ||
| 46 | |||
| 47 | static struct clk sh4202_emi_clk = { | ||
| 48 | .name = "emi_clk", | ||
| 49 | .flags = CLK_ALWAYS_ENABLED, | ||
| 50 | .ops = &sh4202_emi_clk_ops, | ||
| 51 | }; | ||
| 52 | |||
| 53 | static void femi_clk_recalc(struct clk *clk) | ||
| 54 | { | ||
| 55 | int idx = (ctrl_inl(CPG2_FRQCR3) >> 3) & 0x0007; | ||
| 56 | clk->rate = clk->parent->rate / frqcr3_divisors[idx]; | ||
| 57 | } | ||
| 58 | |||
| 59 | static struct clk_ops sh4202_femi_clk_ops = { | ||
| 60 | .recalc = femi_clk_recalc, | ||
| 61 | }; | ||
| 62 | |||
| 63 | static struct clk sh4202_femi_clk = { | ||
| 64 | .name = "femi_clk", | ||
| 65 | .flags = CLK_ALWAYS_ENABLED, | ||
| 66 | .ops = &sh4202_femi_clk_ops, | ||
| 67 | }; | ||
| 68 | |||
| 69 | static void shoc_clk_init(struct clk *clk) | ||
| 70 | { | ||
| 71 | int i; | ||
| 72 | |||
| 73 | /* | ||
| 74 | * For some reason, the shoc_clk seems to be set to some really | ||
| 75 | * insane value at boot (values outside of the allowable frequency | ||
| 76 | * range for instance). We deal with this by scaling it back down | ||
| 77 | * to something sensible just in case. | ||
| 78 | * | ||
| 79 | * Start scaling from the high end down until we find something | ||
| 80 | * that passes rate verification.. | ||
| 81 | */ | ||
| 82 | for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) { | ||
| 83 | int divisor = frqcr3_divisors[i]; | ||
| 84 | |||
| 85 | if (clk->ops->set_rate(clk, clk->parent->rate / divisor) == 0) | ||
| 86 | break; | ||
| 87 | } | ||
| 88 | |||
| 89 | WARN_ON(i == ARRAY_SIZE(frqcr3_divisors)); /* Undefined clock */ | ||
| 90 | } | ||
| 91 | |||
| 92 | static void shoc_clk_recalc(struct clk *clk) | ||
| 93 | { | ||
| 94 | int idx = (ctrl_inl(CPG2_FRQCR3) >> 6) & 0x0007; | ||
| 95 | clk->rate = clk->parent->rate / frqcr3_divisors[idx]; | ||
| 96 | } | ||
| 97 | |||
| 98 | static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate) | ||
| 99 | { | ||
| 100 | struct clk *bclk = clk_get("bus_clk"); | ||
| 101 | unsigned long bclk_rate = clk_get_rate(bclk); | ||
| 102 | |||
| 103 | clk_put(bclk); | ||
| 104 | |||
| 105 | if (rate > bclk_rate) | ||
| 106 | return 1; | ||
| 107 | if (rate > 66000000) | ||
| 108 | return 1; | ||
| 109 | |||
| 110 | return 0; | ||
| 111 | } | ||
| 112 | |||
| 113 | static int shoc_clk_set_rate(struct clk *clk, unsigned long rate) | ||
| 114 | { | ||
| 115 | unsigned long frqcr3; | ||
| 116 | unsigned int tmp; | ||
| 117 | |||
| 118 | /* Make sure we have something sensible to switch to */ | ||
| 119 | if (shoc_clk_verify_rate(clk, rate) != 0) | ||
| 120 | return -EINVAL; | ||
| 121 | |||
| 122 | tmp = frqcr3_lookup(clk, rate); | ||
| 123 | |||
| 124 | frqcr3 = ctrl_inl(CPG2_FRQCR3); | ||
| 125 | frqcr3 &= ~(0x0007 << 6); | ||
| 126 | frqcr3 |= tmp << 6; | ||
| 127 | ctrl_outl(frqcr3, CPG2_FRQCR3); | ||
| 128 | |||
| 129 | clk->rate = clk->parent->rate / frqcr3_divisors[tmp]; | ||
| 130 | |||
| 131 | return 0; | ||
| 132 | } | ||
| 133 | |||
| 134 | static struct clk_ops sh4202_shoc_clk_ops = { | ||
| 135 | .init = shoc_clk_init, | ||
| 136 | .recalc = shoc_clk_recalc, | ||
| 137 | .set_rate = shoc_clk_set_rate, | ||
| 138 | }; | ||
| 139 | |||
| 140 | static struct clk sh4202_shoc_clk = { | ||
| 141 | .name = "shoc_clk", | ||
| 142 | .flags = CLK_ALWAYS_ENABLED, | ||
| 143 | .ops = &sh4202_shoc_clk_ops, | ||
| 144 | }; | ||
| 145 | |||
| 146 | static struct clk *sh4202_onchip_clocks[] = { | ||
| 147 | &sh4202_emi_clk, | ||
| 148 | &sh4202_femi_clk, | ||
| 149 | &sh4202_shoc_clk, | ||
| 150 | }; | ||
| 151 | |||
| 152 | static int __init sh4202_clk_init(void) | ||
| 153 | { | ||
| 154 | struct clk *clk = clk_get("master_clk"); | ||
| 155 | int i; | ||
| 156 | |||
| 157 | for (i = 0; i < ARRAY_SIZE(sh4202_onchip_clocks); i++) { | ||
| 158 | struct clk *clkp = sh4202_onchip_clocks[i]; | ||
| 159 | |||
| 160 | clkp->parent = clk; | ||
| 161 | clk_register(clkp); | ||
| 162 | clk_enable(clkp); | ||
| 163 | } | ||
| 164 | |||
| 165 | /* | ||
| 166 | * Now that we have the rest of the clocks registered, we need to | ||
| 167 | * force the parent clock to propagate so that these clocks will | ||
| 168 | * automatically figure out their rate. We cheat by handing the | ||
| 169 | * parent clock its current rate and forcing child propagation. | ||
| 170 | */ | ||
| 171 | clk_set_rate(clk, clk_get_rate(clk)); | ||
| 172 | |||
| 173 | clk_put(clk); | ||
| 174 | |||
| 175 | return 0; | ||
| 176 | } | ||
| 177 | |||
| 178 | arch_initcall(sh4202_clk_init); | ||
| 179 | |||
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4.c b/arch/sh/kernel/cpu/sh4/clock-sh4.c new file mode 100644 index 000000000000..dca9f87a12d6 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4/clock-sh4.c | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | /* | ||
| 2 | * arch/sh/kernel/cpu/sh4/clock-sh4.c | ||
| 3 | * | ||
| 4 | * Generic SH-4 support for the clock framework | ||
| 5 | * | ||
| 6 | * Copyright (C) 2005 Paul Mundt | ||
| 7 | * | ||
| 8 | * FRQCR parsing hacked out of arch/sh/kernel/time.c | ||
| 9 | * | ||
| 10 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka | ||
| 11 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> | ||
| 12 | * Copyright (C) 2002, 2003, 2004 Paul Mundt | ||
| 13 | * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> | ||
| 14 | * | ||
| 15 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 16 | * License. See the file "COPYING" in the main directory of this archive | ||
| 17 | * for more details. | ||
| 18 | */ | ||
| 19 | #include <linux/init.h> | ||
| 20 | #include <linux/kernel.h> | ||
| 21 | #include <asm/clock.h> | ||
| 22 | #include <asm/freq.h> | ||
| 23 | #include <asm/io.h> | ||
| 24 | |||
| 25 | static int ifc_divisors[] = { 1, 2, 3, 4, 6, 8, 1, 1 }; | ||
| 26 | #define bfc_divisors ifc_divisors /* Same */ | ||
| 27 | static int pfc_divisors[] = { 2, 3, 4, 6, 8, 2, 2, 2 }; | ||
| 28 | |||
| 29 | static void master_clk_init(struct clk *clk) | ||
| 30 | { | ||
| 31 | clk->rate *= pfc_divisors[ctrl_inw(FRQCR) & 0x0007]; | ||
| 32 | } | ||
| 33 | |||
| 34 | static struct clk_ops sh4_master_clk_ops = { | ||
| 35 | .init = master_clk_init, | ||
| 36 | }; | ||
| 37 | |||
| 38 | static void module_clk_recalc(struct clk *clk) | ||
| 39 | { | ||
| 40 | int idx = (ctrl_inw(FRQCR) & 0x0007); | ||
| 41 | clk->rate = clk->parent->rate / pfc_divisors[idx]; | ||
| 42 | } | ||
| 43 | |||
| 44 | static struct clk_ops sh4_module_clk_ops = { | ||
| 45 | .recalc = module_clk_recalc, | ||
| 46 | }; | ||
| 47 | |||
| 48 | static void bus_clk_recalc(struct clk *clk) | ||
| 49 | { | ||
| 50 | int idx = (ctrl_inw(FRQCR) >> 3) & 0x0007; | ||
| 51 | clk->rate = clk->parent->rate / bfc_divisors[idx]; | ||
| 52 | } | ||
| 53 | |||
| 54 | static struct clk_ops sh4_bus_clk_ops = { | ||
| 55 | .recalc = bus_clk_recalc, | ||
| 56 | }; | ||
| 57 | |||
| 58 | static void cpu_clk_recalc(struct clk *clk) | ||
| 59 | { | ||
| 60 | int idx = (ctrl_inw(FRQCR) >> 6) & 0x0007; | ||
| 61 | clk->rate = clk->parent->rate / ifc_divisors[idx]; | ||
| 62 | } | ||
| 63 | |||
| 64 | static struct clk_ops sh4_cpu_clk_ops = { | ||
| 65 | .recalc = cpu_clk_recalc, | ||
| 66 | }; | ||
| 67 | |||
| 68 | static struct clk_ops *sh4_clk_ops[] = { | ||
| 69 | &sh4_master_clk_ops, | ||
| 70 | &sh4_module_clk_ops, | ||
| 71 | &sh4_bus_clk_ops, | ||
| 72 | &sh4_cpu_clk_ops, | ||
| 73 | }; | ||
| 74 | |||
| 75 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | ||
| 76 | { | ||
| 77 | if (idx < ARRAY_SIZE(sh4_clk_ops)) | ||
| 78 | *ops = sh4_clk_ops[idx]; | ||
| 79 | } | ||
| 80 | |||
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh73180.c b/arch/sh/kernel/cpu/sh4/clock-sh73180.c new file mode 100644 index 000000000000..2fa5cb2ae68d --- /dev/null +++ b/arch/sh/kernel/cpu/sh4/clock-sh73180.c | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | /* | ||
| 2 | * arch/sh/kernel/cpu/sh4/clock-sh73180.c | ||
| 3 | * | ||
| 4 | * SH73180 support for the clock framework | ||
| 5 | * | ||
| 6 | * Copyright (C) 2005 Paul Mundt | ||
| 7 | * | ||
| 8 | * FRQCR parsing hacked out of arch/sh/kernel/time.c | ||
| 9 | * | ||
| 10 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka | ||
| 11 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> | ||
| 12 | * Copyright (C) 2002, 2003, 2004 Paul Mundt | ||
| 13 | * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> | ||
| 14 | * | ||
| 15 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 16 | * License. See the file "COPYING" in the main directory of this archive | ||
| 17 | * for more details. | ||
| 18 | */ | ||
| 19 | #include <linux/init.h> | ||
| 20 | #include <linux/kernel.h> | ||
| 21 | #include <asm/clock.h> | ||
| 22 | #include <asm/freq.h> | ||
| 23 | #include <asm/io.h> | ||
| 24 | |||
| 25 | /* | ||
| 26 | * SH73180 uses a common set of divisors, so this is quite simple.. | ||
| 27 | */ | ||
| 28 | static int divisors[] = { 1, 2, 3, 4, 6, 8, 12, 16 }; | ||
| 29 | |||
| 30 | static void master_clk_init(struct clk *clk) | ||
| 31 | { | ||
| 32 | clk->rate *= divisors[ctrl_inl(FRQCR) & 0x0007]; | ||
| 33 | } | ||
| 34 | |||
| 35 | static struct clk_ops sh73180_master_clk_ops = { | ||
| 36 | .init = master_clk_init, | ||
| 37 | }; | ||
| 38 | |||
| 39 | static void module_clk_recalc(struct clk *clk) | ||
| 40 | { | ||
| 41 | int idx = (ctrl_inl(FRQCR) & 0x0007); | ||
| 42 | clk->rate = clk->parent->rate / divisors[idx]; | ||
| 43 | } | ||
| 44 | |||
| 45 | static struct clk_ops sh73180_module_clk_ops = { | ||
| 46 | .recalc = module_clk_recalc, | ||
| 47 | }; | ||
| 48 | |||
| 49 | static void bus_clk_recalc(struct clk *clk) | ||
| 50 | { | ||
| 51 | int idx = (ctrl_inl(FRQCR) >> 12) & 0x0007; | ||
| 52 | clk->rate = clk->parent->rate / divisors[idx]; | ||
| 53 | } | ||
| 54 | |||
| 55 | static struct clk_ops sh73180_bus_clk_ops = { | ||
| 56 | .recalc = bus_clk_recalc, | ||
| 57 | }; | ||
| 58 | |||
| 59 | static void cpu_clk_recalc(struct clk *clk) | ||
| 60 | { | ||
| 61 | int idx = (ctrl_inl(FRQCR) >> 20) & 0x0007; | ||
| 62 | clk->rate = clk->parent->rate / divisors[idx]; | ||
| 63 | } | ||
| 64 | |||
| 65 | static struct clk_ops sh73180_cpu_clk_ops = { | ||
| 66 | .recalc = cpu_clk_recalc, | ||
| 67 | }; | ||
| 68 | |||
| 69 | static struct clk_ops *sh73180_clk_ops[] = { | ||
| 70 | &sh73180_master_clk_ops, | ||
| 71 | &sh73180_module_clk_ops, | ||
| 72 | &sh73180_bus_clk_ops, | ||
| 73 | &sh73180_cpu_clk_ops, | ||
| 74 | }; | ||
| 75 | |||
| 76 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | ||
| 77 | { | ||
| 78 | if (idx < ARRAY_SIZE(sh73180_clk_ops)) | ||
| 79 | *ops = sh73180_clk_ops[idx]; | ||
| 80 | } | ||
| 81 | |||
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh7770.c b/arch/sh/kernel/cpu/sh4/clock-sh7770.c new file mode 100644 index 000000000000..c8694bac6477 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4/clock-sh7770.c | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | /* | ||
| 2 | * arch/sh/kernel/cpu/sh4/clock-sh7770.c | ||
| 3 | * | ||
| 4 | * SH7770 support for the clock framework | ||
| 5 | * | ||
| 6 | * Copyright (C) 2005 Paul Mundt | ||
| 7 | * | ||
| 8 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 9 | * License. See the file "COPYING" in the main directory of this archive | ||
| 10 | * for more details. | ||
| 11 | */ | ||
| 12 | #include <linux/init.h> | ||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <asm/clock.h> | ||
| 15 | #include <asm/freq.h> | ||
| 16 | #include <asm/io.h> | ||
| 17 | |||
| 18 | static int ifc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 1 }; | ||
| 19 | static int bfc_divisors[] = { 1, 1, 1, 1, 1, 8,12, 1 }; | ||
| 20 | static int pfc_divisors[] = { 1, 8, 1,10,12,16, 1, 1 }; | ||
| 21 | |||
| 22 | static void master_clk_init(struct clk *clk) | ||
| 23 | { | ||
| 24 | clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> 28) & 0x000f]; | ||
| 25 | } | ||
| 26 | |||
| 27 | static struct clk_ops sh7770_master_clk_ops = { | ||
| 28 | .init = master_clk_init, | ||
| 29 | }; | ||
| 30 | |||
| 31 | static void module_clk_recalc(struct clk *clk) | ||
| 32 | { | ||
| 33 | int idx = ((ctrl_inl(FRQCR) >> 28) & 0x000f); | ||
| 34 | clk->rate = clk->parent->rate / pfc_divisors[idx]; | ||
| 35 | } | ||
| 36 | |||
| 37 | static struct clk_ops sh7770_module_clk_ops = { | ||
| 38 | .recalc = module_clk_recalc, | ||
| 39 | }; | ||
| 40 | |||
| 41 | static void bus_clk_recalc(struct clk *clk) | ||
| 42 | { | ||
| 43 | int idx = (ctrl_inl(FRQCR) & 0x000f); | ||
| 44 | clk->rate = clk->parent->rate / bfc_divisors[idx]; | ||
| 45 | } | ||
| 46 | |||
| 47 | static struct clk_ops sh7770_bus_clk_ops = { | ||
| 48 | .recalc = bus_clk_recalc, | ||
| 49 | }; | ||
| 50 | |||
| 51 | static void cpu_clk_recalc(struct clk *clk) | ||
| 52 | { | ||
| 53 | int idx = ((ctrl_inl(FRQCR) >> 24) & 0x000f); | ||
| 54 | clk->rate = clk->parent->rate / ifc_divisors[idx]; | ||
| 55 | } | ||
| 56 | |||
| 57 | static struct clk_ops sh7770_cpu_clk_ops = { | ||
| 58 | .recalc = cpu_clk_recalc, | ||
| 59 | }; | ||
| 60 | |||
| 61 | static struct clk_ops *sh7770_clk_ops[] = { | ||
| 62 | &sh7770_master_clk_ops, | ||
| 63 | &sh7770_module_clk_ops, | ||
| 64 | &sh7770_bus_clk_ops, | ||
| 65 | &sh7770_cpu_clk_ops, | ||
| 66 | }; | ||
| 67 | |||
| 68 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | ||
| 69 | { | ||
| 70 | if (idx < ARRAY_SIZE(sh7770_clk_ops)) | ||
| 71 | *ops = sh7770_clk_ops[idx]; | ||
| 72 | } | ||
| 73 | |||
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh7780.c b/arch/sh/kernel/cpu/sh4/clock-sh7780.c new file mode 100644 index 000000000000..93ad367342c9 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4/clock-sh7780.c | |||
| @@ -0,0 +1,126 @@ | |||
| 1 | /* | ||
| 2 | * arch/sh/kernel/cpu/sh4/clock-sh7780.c | ||
| 3 | * | ||
| 4 | * SH7780 support for the clock framework | ||
| 5 | * | ||
| 6 | * Copyright (C) 2005 Paul Mundt | ||
| 7 | * | ||
| 8 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 9 | * License. See the file "COPYING" in the main directory of this archive | ||
| 10 | * for more details. | ||
| 11 | */ | ||
| 12 | #include <linux/init.h> | ||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <asm/clock.h> | ||
| 15 | #include <asm/freq.h> | ||
| 16 | #include <asm/io.h> | ||
| 17 | |||
| 18 | static int ifc_divisors[] = { 2, 4 }; | ||
| 19 | static int bfc_divisors[] = { 1, 1, 1, 8, 12, 16, 24, 1 }; | ||
| 20 | static int pfc_divisors[] = { 1, 24, 24, 1 }; | ||
| 21 | static int cfc_divisors[] = { 1, 1, 4, 1, 6, 1, 1, 1 }; | ||
| 22 | |||
| 23 | static void master_clk_init(struct clk *clk) | ||
| 24 | { | ||
| 25 | clk->rate *= pfc_divisors[ctrl_inl(FRQCR) & 0x0003]; | ||
| 26 | } | ||
| 27 | |||
| 28 | static struct clk_ops sh7780_master_clk_ops = { | ||
| 29 | .init = master_clk_init, | ||
| 30 | }; | ||
| 31 | |||
| 32 | static void module_clk_recalc(struct clk *clk) | ||
| 33 | { | ||
| 34 | int idx = (ctrl_inl(FRQCR) & 0x0003); | ||
| 35 | clk->rate = clk->parent->rate / pfc_divisors[idx]; | ||
| 36 | } | ||
| 37 | |||
| 38 | static struct clk_ops sh7780_module_clk_ops = { | ||
| 39 | .recalc = module_clk_recalc, | ||
| 40 | }; | ||
| 41 | |||
| 42 | static void bus_clk_recalc(struct clk *clk) | ||
| 43 | { | ||
| 44 | int idx = ((ctrl_inl(FRQCR) >> 16) & 0x0007); | ||
| 45 | clk->rate = clk->parent->rate / bfc_divisors[idx]; | ||
| 46 | } | ||
| 47 | |||
| 48 | static struct clk_ops sh7780_bus_clk_ops = { | ||
| 49 | .recalc = bus_clk_recalc, | ||
| 50 | }; | ||
| 51 | |||
| 52 | static void cpu_clk_recalc(struct clk *clk) | ||
| 53 | { | ||
| 54 | int idx = ((ctrl_inl(FRQCR) >> 24) & 0x0001); | ||
| 55 | clk->rate = clk->parent->rate / ifc_divisors[idx]; | ||
| 56 | } | ||
| 57 | |||
| 58 | static struct clk_ops sh7780_cpu_clk_ops = { | ||
| 59 | .recalc = cpu_clk_recalc, | ||
| 60 | }; | ||
| 61 | |||
| 62 | static struct clk_ops *sh7780_clk_ops[] = { | ||
| 63 | &sh7780_master_clk_ops, | ||
| 64 | &sh7780_module_clk_ops, | ||
| 65 | &sh7780_bus_clk_ops, | ||
| 66 | &sh7780_cpu_clk_ops, | ||
| 67 | }; | ||
| 68 | |||
| 69 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | ||
| 70 | { | ||
| 71 | if (idx < ARRAY_SIZE(sh7780_clk_ops)) | ||
| 72 | *ops = sh7780_clk_ops[idx]; | ||
| 73 | } | ||
| 74 | |||
| 75 | static void shyway_clk_recalc(struct clk *clk) | ||
| 76 | { | ||
| 77 | int idx = ((ctrl_inl(FRQCR) >> 20) & 0x0007); | ||
| 78 | clk->rate = clk->parent->rate / cfc_divisors[idx]; | ||
| 79 | } | ||
| 80 | |||
| 81 | static struct clk_ops sh7780_shyway_clk_ops = { | ||
| 82 | .recalc = shyway_clk_recalc, | ||
| 83 | }; | ||
| 84 | |||
| 85 | static struct clk sh7780_shyway_clk = { | ||
| 86 | .name = "shyway_clk", | ||
| 87 | .flags = CLK_ALWAYS_ENABLED, | ||
| 88 | .ops = &sh7780_shyway_clk_ops, | ||
| 89 | }; | ||
| 90 | |||
| 91 | /* | ||
| 92 | * Additional SH7780-specific on-chip clocks that aren't already part of the | ||
| 93 | * clock framework | ||
| 94 | */ | ||
| 95 | static struct clk *sh7780_onchip_clocks[] = { | ||
| 96 | &sh7780_shyway_clk, | ||
| 97 | }; | ||
| 98 | |||
| 99 | static int __init sh7780_clk_init(void) | ||
| 100 | { | ||
| 101 | struct clk *clk = clk_get("master_clk"); | ||
| 102 | int i; | ||
| 103 | |||
| 104 | for (i = 0; i < ARRAY_SIZE(sh7780_onchip_clocks); i++) { | ||
| 105 | struct clk *clkp = sh7780_onchip_clocks[i]; | ||
| 106 | |||
| 107 | clkp->parent = clk; | ||
| 108 | clk_register(clkp); | ||
| 109 | clk_enable(clkp); | ||
| 110 | } | ||
| 111 | |||
| 112 | /* | ||
| 113 | * Now that we have the rest of the clocks registered, we need to | ||
| 114 | * force the parent clock to propagate so that these clocks will | ||
| 115 | * automatically figure out their rate. We cheat by handing the | ||
| 116 | * parent clock its current rate and forcing child propagation. | ||
| 117 | */ | ||
| 118 | clk_set_rate(clk, clk_get_rate(clk)); | ||
| 119 | |||
| 120 | clk_put(clk); | ||
| 121 | |||
| 122 | return 0; | ||
| 123 | } | ||
| 124 | |||
| 125 | arch_initcall(sh7780_clk_init); | ||
| 126 | |||
diff --git a/arch/sh/kernel/cpu/sh4/irq_intc2.c b/arch/sh/kernel/cpu/sh4/irq_intc2.c deleted file mode 100644 index f6b16ba01932..000000000000 --- a/arch/sh/kernel/cpu/sh4/irq_intc2.c +++ /dev/null | |||
| @@ -1,222 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/sh/kernel/irq_intc2.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2001 David J. Mckay (david.mckay@st.com) | ||
| 5 | * | ||
| 6 | * May be copied or modified under the terms of the GNU General Public | ||
| 7 | * License. See linux/COPYING for more information. | ||
| 8 | * | ||
| 9 | * Interrupt handling for INTC2-based IRQ. | ||
| 10 | * | ||
| 11 | * These are the "new Hitachi style" interrupts, as present on the | ||
| 12 | * Hitachi 7751 and the STM ST40 STB1. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/init.h> | ||
| 17 | #include <linux/irq.h> | ||
| 18 | |||
| 19 | #include <asm/system.h> | ||
| 20 | #include <asm/io.h> | ||
| 21 | #include <asm/machvec.h> | ||
| 22 | |||
| 23 | |||
| 24 | struct intc2_data { | ||
| 25 | unsigned char msk_offset; | ||
| 26 | unsigned char msk_shift; | ||
| 27 | #ifdef CONFIG_CPU_SUBTYPE_ST40 | ||
| 28 | int (*clear_irq) (int); | ||
| 29 | #endif | ||
| 30 | }; | ||
| 31 | |||
| 32 | |||
| 33 | static struct intc2_data intc2_data[NR_INTC2_IRQS]; | ||
| 34 | |||
| 35 | static void enable_intc2_irq(unsigned int irq); | ||
| 36 | static void disable_intc2_irq(unsigned int irq); | ||
| 37 | |||
| 38 | /* shutdown is same as "disable" */ | ||
| 39 | #define shutdown_intc2_irq disable_intc2_irq | ||
| 40 | |||
| 41 | static void mask_and_ack_intc2(unsigned int); | ||
| 42 | static void end_intc2_irq(unsigned int irq); | ||
| 43 | |||
| 44 | static unsigned int startup_intc2_irq(unsigned int irq) | ||
| 45 | { | ||
| 46 | enable_intc2_irq(irq); | ||
| 47 | return 0; /* never anything pending */ | ||
| 48 | } | ||
| 49 | |||
| 50 | static struct hw_interrupt_type intc2_irq_type = { | ||
| 51 | .typename = "INTC2-IRQ", | ||
| 52 | .startup = startup_intc2_irq, | ||
| 53 | .shutdown = shutdown_intc2_irq, | ||
| 54 | .enable = enable_intc2_irq, | ||
| 55 | .disable = disable_intc2_irq, | ||
| 56 | .ack = mask_and_ack_intc2, | ||
| 57 | .end = end_intc2_irq | ||
| 58 | }; | ||
| 59 | |||
| 60 | static void disable_intc2_irq(unsigned int irq) | ||
| 61 | { | ||
| 62 | int irq_offset = irq - INTC2_FIRST_IRQ; | ||
| 63 | int msk_shift, msk_offset; | ||
| 64 | |||
| 65 | // Sanity check | ||
| 66 | if((irq_offset<0) || (irq_offset>=NR_INTC2_IRQS)) | ||
| 67 | return; | ||
| 68 | |||
| 69 | msk_shift = intc2_data[irq_offset].msk_shift; | ||
| 70 | msk_offset = intc2_data[irq_offset].msk_offset; | ||
| 71 | |||
| 72 | ctrl_outl(1<<msk_shift, | ||
| 73 | INTC2_BASE+INTC2_INTMSK_OFFSET+msk_offset); | ||
| 74 | } | ||
| 75 | |||
| 76 | static void enable_intc2_irq(unsigned int irq) | ||
| 77 | { | ||
| 78 | int irq_offset = irq - INTC2_FIRST_IRQ; | ||
| 79 | int msk_shift, msk_offset; | ||
| 80 | |||
| 81 | /* Sanity check */ | ||
| 82 | if((irq_offset<0) || (irq_offset>=NR_INTC2_IRQS)) | ||
| 83 | return; | ||
| 84 | |||
| 85 | msk_shift = intc2_data[irq_offset].msk_shift; | ||
| 86 | msk_offset = intc2_data[irq_offset].msk_offset; | ||
| 87 | |||
| 88 | ctrl_outl(1<<msk_shift, | ||
| 89 | INTC2_BASE+INTC2_INTMSKCLR_OFFSET+msk_offset); | ||
| 90 | } | ||
| 91 | |||
| 92 | static void mask_and_ack_intc2(unsigned int irq) | ||
| 93 | { | ||
| 94 | disable_intc2_irq(irq); | ||
| 95 | } | ||
| 96 | |||
| 97 | static void end_intc2_irq(unsigned int irq) | ||
| 98 | { | ||
| 99 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
| 100 | enable_intc2_irq(irq); | ||
| 101 | |||
| 102 | #ifdef CONFIG_CPU_SUBTYPE_ST40 | ||
| 103 | if (intc2_data[irq - INTC2_FIRST_IRQ].clear_irq) | ||
| 104 | intc2_data[irq - INTC2_FIRST_IRQ].clear_irq (irq); | ||
| 105 | #endif | ||
| 106 | } | ||
| 107 | |||
| 108 | /* | ||
| 109 | * Setup an INTC2 style interrupt. | ||
| 110 | * NOTE: Unlike IPR interrupts, parameters are not shifted by this code, | ||
| 111 | * allowing the use of the numbers straight out of the datasheet. | ||
| 112 | * For example: | ||
| 113 | * PIO1 which is INTPRI00[19,16] and INTMSK00[13] | ||
| 114 | * would be: ^ ^ ^ ^ | ||
| 115 | * | | | | | ||
| 116 | * make_intc2_irq(84, 0, 16, 0, 13); | ||
| 117 | */ | ||
| 118 | void make_intc2_irq(unsigned int irq, | ||
| 119 | unsigned int ipr_offset, unsigned int ipr_shift, | ||
| 120 | unsigned int msk_offset, unsigned int msk_shift, | ||
| 121 | unsigned int priority) | ||
| 122 | { | ||
| 123 | int irq_offset = irq - INTC2_FIRST_IRQ; | ||
| 124 | unsigned int flags; | ||
| 125 | unsigned long ipr; | ||
| 126 | |||
| 127 | if((irq_offset<0) || (irq_offset>=NR_INTC2_IRQS)) | ||
| 128 | return; | ||
| 129 | |||
| 130 | disable_irq_nosync(irq); | ||
| 131 | |||
| 132 | /* Fill the data we need */ | ||
| 133 | intc2_data[irq_offset].msk_offset = msk_offset; | ||
| 134 | intc2_data[irq_offset].msk_shift = msk_shift; | ||
| 135 | #ifdef CONFIG_CPU_SUBTYPE_ST40 | ||
| 136 | intc2_data[irq_offset].clear_irq = NULL; | ||
| 137 | #endif | ||
| 138 | |||
| 139 | /* Set the priority level */ | ||
| 140 | local_irq_save(flags); | ||
| 141 | |||
| 142 | ipr=ctrl_inl(INTC2_BASE+INTC2_INTPRI_OFFSET+ipr_offset); | ||
| 143 | ipr&=~(0xf<<ipr_shift); | ||
| 144 | ipr|=(priority)<<ipr_shift; | ||
| 145 | ctrl_outl(ipr, INTC2_BASE+INTC2_INTPRI_OFFSET+ipr_offset); | ||
| 146 | |||
| 147 | local_irq_restore(flags); | ||
| 148 | |||
| 149 | irq_desc[irq].handler=&intc2_irq_type; | ||
| 150 | |||
| 151 | disable_intc2_irq(irq); | ||
| 152 | } | ||
| 153 | |||
| 154 | #ifdef CONFIG_CPU_SUBTYPE_ST40 | ||
| 155 | |||
| 156 | struct intc2_init { | ||
| 157 | unsigned short irq; | ||
| 158 | unsigned char ipr_offset, ipr_shift; | ||
| 159 | unsigned char msk_offset, msk_shift; | ||
| 160 | }; | ||
| 161 | |||
| 162 | static struct intc2_init intc2_init_data[] __initdata = { | ||
| 163 | {64, 0, 0, 0, 0}, /* PCI serr */ | ||
| 164 | {65, 0, 4, 0, 1}, /* PCI err */ | ||
| 165 | {66, 0, 4, 0, 2}, /* PCI ad */ | ||
| 166 | {67, 0, 4, 0, 3}, /* PCI pwd down */ | ||
| 167 | {72, 0, 8, 0, 5}, /* DMAC INT0 */ | ||
| 168 | {73, 0, 8, 0, 6}, /* DMAC INT1 */ | ||
| 169 | {74, 0, 8, 0, 7}, /* DMAC INT2 */ | ||
| 170 | {75, 0, 8, 0, 8}, /* DMAC INT3 */ | ||
| 171 | {76, 0, 8, 0, 9}, /* DMAC INT4 */ | ||
| 172 | {78, 0, 8, 0, 11}, /* DMAC ERR */ | ||
| 173 | {80, 0, 12, 0, 12}, /* PIO0 */ | ||
| 174 | {84, 0, 16, 0, 13}, /* PIO1 */ | ||
| 175 | {88, 0, 20, 0, 14}, /* PIO2 */ | ||
| 176 | {112, 4, 0, 4, 0}, /* Mailbox */ | ||
| 177 | #ifdef CONFIG_CPU_SUBTYPE_ST40GX1 | ||
| 178 | {116, 4, 4, 4, 4}, /* SSC0 */ | ||
| 179 | {120, 4, 8, 4, 8}, /* IR Blaster */ | ||
| 180 | {124, 4, 12, 4, 12}, /* USB host */ | ||
| 181 | {128, 4, 16, 4, 16}, /* Video processor BLITTER */ | ||
| 182 | {132, 4, 20, 4, 20}, /* UART0 */ | ||
| 183 | {134, 4, 20, 4, 22}, /* UART2 */ | ||
| 184 | {136, 4, 24, 4, 24}, /* IO_PIO0 */ | ||
| 185 | {140, 4, 28, 4, 28}, /* EMPI */ | ||
| 186 | {144, 8, 0, 8, 0}, /* MAFE */ | ||
| 187 | {148, 8, 4, 8, 4}, /* PWM */ | ||
| 188 | {152, 8, 8, 8, 8}, /* SSC1 */ | ||
| 189 | {156, 8, 12, 8, 12}, /* IO_PIO1 */ | ||
| 190 | {160, 8, 16, 8, 16}, /* USB target */ | ||
| 191 | {164, 8, 20, 8, 20}, /* UART1 */ | ||
| 192 | {168, 8, 24, 8, 24}, /* Teletext */ | ||
| 193 | {172, 8, 28, 8, 28}, /* VideoSync VTG */ | ||
| 194 | {173, 8, 28, 8, 29}, /* VideoSync DVP0 */ | ||
| 195 | {174, 8, 28, 8, 30}, /* VideoSync DVP1 */ | ||
| 196 | #endif | ||
| 197 | }; | ||
| 198 | |||
| 199 | void __init init_IRQ_intc2(void) | ||
| 200 | { | ||
| 201 | struct intc2_init *p; | ||
| 202 | |||
| 203 | printk(KERN_ALERT "init_IRQ_intc2\n"); | ||
| 204 | |||
| 205 | for (p = intc2_init_data; | ||
| 206 | p<intc2_init_data+ARRAY_SIZE(intc2_init_data); | ||
| 207 | p++) { | ||
| 208 | make_intc2_irq(p->irq, p->ipr_offset, p->ipr_shift, | ||
| 209 | p-> msk_offset, p->msk_shift, 13); | ||
| 210 | } | ||
| 211 | } | ||
| 212 | |||
| 213 | /* Adds a termination callback to the interrupt */ | ||
| 214 | void intc2_add_clear_irq(int irq, int (*fn)(int)) | ||
| 215 | { | ||
| 216 | if (irq < INTC2_FIRST_IRQ) | ||
| 217 | return; | ||
| 218 | |||
| 219 | intc2_data[irq - INTC2_FIRST_IRQ].clear_irq = fn; | ||
| 220 | } | ||
| 221 | |||
| 222 | #endif /* CONFIG_CPU_SUBTYPE_ST40 */ | ||
diff --git a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c index d9932f25993b..71c9fde2fd90 100644 --- a/arch/sh/kernel/io.c +++ b/arch/sh/kernel/io.c | |||
| @@ -2,58 +2,73 @@ | |||
| 2 | * linux/arch/sh/kernel/io.c | 2 | * linux/arch/sh/kernel/io.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2000 Stuart Menefy | 4 | * Copyright (C) 2000 Stuart Menefy |
| 5 | * Copyright (C) 2005 Paul Mundt | ||
| 5 | * | 6 | * |
| 6 | * Provide real functions which expand to whatever the header file defined. | 7 | * Provide real functions which expand to whatever the header file defined. |
| 7 | * Also definitions of machine independent IO functions. | 8 | * Also definitions of machine independent IO functions. |
| 9 | * | ||
| 10 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 11 | * License. See the file "COPYING" in the main directory of this archive | ||
| 12 | * for more details. | ||
| 8 | */ | 13 | */ |
| 9 | |||
| 10 | #include <asm/io.h> | ||
| 11 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 15 | #include <asm/machvec.h> | ||
| 16 | #include <asm/io.h> | ||
| 12 | 17 | ||
| 13 | /* | 18 | /* |
| 14 | * Copy data from IO memory space to "real" memory space. | 19 | * Copy data from IO memory space to "real" memory space. |
| 15 | * This needs to be optimized. | 20 | * This needs to be optimized. |
| 16 | */ | 21 | */ |
| 17 | void memcpy_fromio(void * to, unsigned long from, unsigned long count) | 22 | void memcpy_fromio(void *to, volatile void __iomem *from, unsigned long count) |
| 18 | { | 23 | { |
| 19 | char *p = to; | 24 | char *p = to; |
| 20 | while (count) { | 25 | while (count) { |
| 21 | count--; | 26 | count--; |
| 22 | *p = readb(from); | 27 | *p = readb((void __iomem *)from); |
| 23 | p++; | 28 | p++; |
| 24 | from++; | 29 | from++; |
| 25 | } | 30 | } |
| 26 | } | 31 | } |
| 27 | 32 | EXPORT_SYMBOL(memcpy_fromio); | |
| 33 | |||
| 28 | /* | 34 | /* |
| 29 | * Copy data from "real" memory space to IO memory space. | 35 | * Copy data from "real" memory space to IO memory space. |
| 30 | * This needs to be optimized. | 36 | * This needs to be optimized. |
| 31 | */ | 37 | */ |
| 32 | void memcpy_toio(unsigned long to, const void * from, unsigned long count) | 38 | void memcpy_toio(volatile void __iomem *to, const void *from, unsigned long count) |
| 33 | { | 39 | { |
| 34 | const char *p = from; | 40 | const char *p = from; |
| 35 | while (count) { | 41 | while (count) { |
| 36 | count--; | 42 | count--; |
| 37 | writeb(*p, to); | 43 | writeb(*p, (void __iomem *)to); |
| 38 | p++; | 44 | p++; |
| 39 | to++; | 45 | to++; |
| 40 | } | 46 | } |
| 41 | } | 47 | } |
| 42 | 48 | EXPORT_SYMBOL(memcpy_toio); | |
| 49 | |||
| 43 | /* | 50 | /* |
| 44 | * "memset" on IO memory space. | 51 | * "memset" on IO memory space. |
| 45 | * This needs to be optimized. | 52 | * This needs to be optimized. |
| 46 | */ | 53 | */ |
| 47 | void memset_io(unsigned long dst, int c, unsigned long count) | 54 | void memset_io(volatile void __iomem *dst, int c, unsigned long count) |
| 48 | { | 55 | { |
| 49 | while (count) { | 56 | while (count) { |
| 50 | count--; | 57 | count--; |
| 51 | writeb(c, dst); | 58 | writeb(c, (void __iomem *)dst); |
| 52 | dst++; | 59 | dst++; |
| 53 | } | 60 | } |
| 54 | } | 61 | } |
| 55 | |||
| 56 | EXPORT_SYMBOL(memcpy_fromio); | ||
| 57 | EXPORT_SYMBOL(memcpy_toio); | ||
| 58 | EXPORT_SYMBOL(memset_io); | 62 | EXPORT_SYMBOL(memset_io); |
| 59 | 63 | ||
| 64 | void __iomem *ioport_map(unsigned long port, unsigned int nr) | ||
| 65 | { | ||
| 66 | return sh_mv.mv_ioport_map(port, nr); | ||
| 67 | } | ||
| 68 | EXPORT_SYMBOL(ioport_map); | ||
| 69 | |||
| 70 | void ioport_unmap(void __iomem *addr) | ||
| 71 | { | ||
| 72 | sh_mv.mv_ioport_unmap(addr); | ||
| 73 | } | ||
| 74 | EXPORT_SYMBOL(ioport_unmap); | ||
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c index a911b0149d1f..28ec7487de8c 100644 --- a/arch/sh/kernel/io_generic.c +++ b/arch/sh/kernel/io_generic.c | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | * linux/arch/sh/kernel/io_generic.c | 3 | * linux/arch/sh/kernel/io_generic.c |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2000 Niibe Yutaka | 5 | * Copyright (C) 2000 Niibe Yutaka |
| 6 | * Copyright (C) 2005 Paul Mundt | ||
| 6 | * | 7 | * |
| 7 | * Generic I/O routine. These can be used where a machine specific version | 8 | * Generic I/O routine. These can be used where a machine specific version |
| 8 | * is not required. | 9 | * is not required. |
| @@ -10,21 +11,20 @@ | |||
| 10 | * This file is subject to the terms and conditions of the GNU General Public | 11 | * This file is subject to the terms and conditions of the GNU General Public |
| 11 | * License. See the file "COPYING" in the main directory of this archive | 12 | * License. See the file "COPYING" in the main directory of this archive |
| 12 | * for more details. | 13 | * for more details. |
| 13 | * | ||
| 14 | */ | 14 | */ |
| 15 | 15 | #include <linux/module.h> | |
| 16 | #include <asm/io.h> | 16 | #include <asm/io.h> |
| 17 | #include <asm/machvec.h> | 17 | #include <asm/machvec.h> |
| 18 | #include <linux/module.h> | ||
| 19 | 18 | ||
| 20 | #if defined(CONFIG_CPU_SH3) | 19 | #ifdef CONFIG_CPU_SH3 |
| 20 | /* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a | ||
| 21 | * workaround. */ | ||
| 21 | /* I'm not sure SH7709 has this kind of bug */ | 22 | /* I'm not sure SH7709 has this kind of bug */ |
| 22 | #define SH3_PCMCIA_BUG_WORKAROUND 1 | 23 | #define dummy_read() ctrl_inb(0xba000000) |
| 23 | #define DUMMY_READ_AREA6 0xba000000 | 24 | #else |
| 25 | #define dummy_read() | ||
| 24 | #endif | 26 | #endif |
| 25 | 27 | ||
| 26 | #define PORT2ADDR(x) (sh_mv.mv_isa_port2addr(x)) | ||
| 27 | |||
| 28 | unsigned long generic_io_base; | 28 | unsigned long generic_io_base; |
| 29 | 29 | ||
| 30 | static inline void delay(void) | 30 | static inline void delay(void) |
| @@ -32,40 +32,40 @@ static inline void delay(void) | |||
| 32 | ctrl_inw(0xa0000000); | 32 | ctrl_inw(0xa0000000); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | unsigned char generic_inb(unsigned long port) | 35 | u8 generic_inb(unsigned long port) |
| 36 | { | 36 | { |
| 37 | return *(volatile unsigned char*)PORT2ADDR(port); | 37 | return ctrl_inb((unsigned long __force)ioport_map(port, 1)); |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | unsigned short generic_inw(unsigned long port) | 40 | u16 generic_inw(unsigned long port) |
| 41 | { | 41 | { |
| 42 | return *(volatile unsigned short*)PORT2ADDR(port); | 42 | return ctrl_inw((unsigned long __force)ioport_map(port, 2)); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | unsigned int generic_inl(unsigned long port) | 45 | u32 generic_inl(unsigned long port) |
| 46 | { | 46 | { |
| 47 | return *(volatile unsigned long*)PORT2ADDR(port); | 47 | return ctrl_inl((unsigned long __force)ioport_map(port, 4)); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | unsigned char generic_inb_p(unsigned long port) | 50 | u8 generic_inb_p(unsigned long port) |
| 51 | { | 51 | { |
| 52 | unsigned long v = *(volatile unsigned char*)PORT2ADDR(port); | 52 | unsigned long v = generic_inb(port); |
| 53 | 53 | ||
| 54 | delay(); | 54 | delay(); |
| 55 | return v; | 55 | return v; |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | unsigned short generic_inw_p(unsigned long port) | 58 | u16 generic_inw_p(unsigned long port) |
| 59 | { | 59 | { |
| 60 | unsigned long v = *(volatile unsigned short*)PORT2ADDR(port); | 60 | unsigned long v = generic_inw(port); |
| 61 | 61 | ||
| 62 | delay(); | 62 | delay(); |
| 63 | return v; | 63 | return v; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | unsigned int generic_inl_p(unsigned long port) | 66 | u32 generic_inl_p(unsigned long port) |
| 67 | { | 67 | { |
| 68 | unsigned long v = *(volatile unsigned long*)PORT2ADDR(port); | 68 | unsigned long v = generic_inl(port); |
| 69 | 69 | ||
| 70 | delay(); | 70 | delay(); |
| 71 | return v; | 71 | return v; |
| @@ -77,75 +77,70 @@ unsigned int generic_inl_p(unsigned long port) | |||
| 77 | * convert the port address to real address once. | 77 | * convert the port address to real address once. |
| 78 | */ | 78 | */ |
| 79 | 79 | ||
| 80 | void generic_insb(unsigned long port, void *buffer, unsigned long count) | 80 | void generic_insb(unsigned long port, void *dst, unsigned long count) |
| 81 | { | 81 | { |
| 82 | volatile unsigned char *port_addr; | 82 | volatile u8 *port_addr; |
| 83 | unsigned char *buf=buffer; | 83 | u8 *buf = dst; |
| 84 | |||
| 85 | port_addr = (volatile unsigned char *)PORT2ADDR(port); | ||
| 86 | 84 | ||
| 87 | while(count--) | 85 | port_addr = (volatile u8 *)ioport_map(port, 1); |
| 88 | *buf++ = *port_addr; | 86 | while (count--) |
| 87 | *buf++ = *port_addr; | ||
| 89 | } | 88 | } |
| 90 | 89 | ||
| 91 | void generic_insw(unsigned long port, void *buffer, unsigned long count) | 90 | void generic_insw(unsigned long port, void *dst, unsigned long count) |
| 92 | { | 91 | { |
| 93 | volatile unsigned short *port_addr; | 92 | volatile u16 *port_addr; |
| 94 | unsigned short *buf=buffer; | 93 | u16 *buf = dst; |
| 95 | 94 | ||
| 96 | port_addr = (volatile unsigned short *)PORT2ADDR(port); | 95 | port_addr = (volatile u16 *)ioport_map(port, 2); |
| 96 | while (count--) | ||
| 97 | *buf++ = *port_addr; | ||
| 97 | 98 | ||
| 98 | while(count--) | 99 | dummy_read(); |
| 99 | *buf++ = *port_addr; | ||
| 100 | #ifdef SH3_PCMCIA_BUG_WORKAROUND | ||
| 101 | ctrl_inb (DUMMY_READ_AREA6); | ||
| 102 | #endif | ||
| 103 | } | 100 | } |
| 104 | 101 | ||
| 105 | void generic_insl(unsigned long port, void *buffer, unsigned long count) | 102 | void generic_insl(unsigned long port, void *dst, unsigned long count) |
| 106 | { | 103 | { |
| 107 | volatile unsigned long *port_addr; | 104 | volatile u32 *port_addr; |
| 108 | unsigned long *buf=buffer; | 105 | u32 *buf = dst; |
| 109 | 106 | ||
| 110 | port_addr = (volatile unsigned long *)PORT2ADDR(port); | 107 | port_addr = (volatile u32 *)ioport_map(port, 4); |
| 108 | while (count--) | ||
| 109 | *buf++ = *port_addr; | ||
| 111 | 110 | ||
| 112 | while(count--) | 111 | dummy_read(); |
| 113 | *buf++ = *port_addr; | ||
| 114 | #ifdef SH3_PCMCIA_BUG_WORKAROUND | ||
| 115 | ctrl_inb (DUMMY_READ_AREA6); | ||
| 116 | #endif | ||
| 117 | } | 112 | } |
| 118 | 113 | ||
| 119 | void generic_outb(unsigned char b, unsigned long port) | 114 | void generic_outb(u8 b, unsigned long port) |
| 120 | { | 115 | { |
| 121 | *(volatile unsigned char*)PORT2ADDR(port) = b; | 116 | ctrl_outb(b, (unsigned long __force)ioport_map(port, 1)); |
| 122 | } | 117 | } |
| 123 | 118 | ||
| 124 | void generic_outw(unsigned short b, unsigned long port) | 119 | void generic_outw(u16 b, unsigned long port) |
| 125 | { | 120 | { |
| 126 | *(volatile unsigned short*)PORT2ADDR(port) = b; | 121 | ctrl_outw(b, (unsigned long __force)ioport_map(port, 2)); |
| 127 | } | 122 | } |
| 128 | 123 | ||
| 129 | void generic_outl(unsigned int b, unsigned long port) | 124 | void generic_outl(u32 b, unsigned long port) |
| 130 | { | 125 | { |
| 131 | *(volatile unsigned long*)PORT2ADDR(port) = b; | 126 | ctrl_outl(b, (unsigned long __force)ioport_map(port, 4)); |
| 132 | } | 127 | } |
| 133 | 128 | ||
| 134 | void generic_outb_p(unsigned char b, unsigned long port) | 129 | void generic_outb_p(u8 b, unsigned long port) |
| 135 | { | 130 | { |
| 136 | *(volatile unsigned char*)PORT2ADDR(port) = b; | 131 | generic_outb(b, port); |
| 137 | delay(); | 132 | delay(); |
| 138 | } | 133 | } |
| 139 | 134 | ||
| 140 | void generic_outw_p(unsigned short b, unsigned long port) | 135 | void generic_outw_p(u16 b, unsigned long port) |
| 141 | { | 136 | { |
| 142 | *(volatile unsigned short*)PORT2ADDR(port) = b; | 137 | generic_outw(b, port); |
| 143 | delay(); | 138 | delay(); |
| 144 | } | 139 | } |
| 145 | 140 | ||
| 146 | void generic_outl_p(unsigned int b, unsigned long port) | 141 | void generic_outl_p(u32 b, unsigned long port) |
| 147 | { | 142 | { |
| 148 | *(volatile unsigned long*)PORT2ADDR(port) = b; | 143 | generic_outl(b, port); |
| 149 | delay(); | 144 | delay(); |
| 150 | } | 145 | } |
| 151 | 146 | ||
| @@ -154,90 +149,77 @@ void generic_outl_p(unsigned int b, unsigned long port) | |||
| 154 | * address. However as the port address doesn't change we only need to | 149 | * address. However as the port address doesn't change we only need to |
| 155 | * convert the port address to real address once. | 150 | * convert the port address to real address once. |
| 156 | */ | 151 | */ |
| 157 | 152 | void generic_outsb(unsigned long port, const void *src, unsigned long count) | |
| 158 | void generic_outsb(unsigned long port, const void *buffer, unsigned long count) | ||
| 159 | { | 153 | { |
| 160 | volatile unsigned char *port_addr; | 154 | volatile u8 *port_addr; |
| 161 | const unsigned char *buf=buffer; | 155 | const u8 *buf = src; |
| 162 | 156 | ||
| 163 | port_addr = (volatile unsigned char *)PORT2ADDR(port); | 157 | port_addr = (volatile u8 __force *)ioport_map(port, 1); |
| 164 | 158 | ||
| 165 | while(count--) | 159 | while (count--) |
| 166 | *port_addr = *buf++; | 160 | *port_addr = *buf++; |
| 167 | } | 161 | } |
| 168 | 162 | ||
| 169 | void generic_outsw(unsigned long port, const void *buffer, unsigned long count) | 163 | void generic_outsw(unsigned long port, const void *src, unsigned long count) |
| 170 | { | 164 | { |
| 171 | volatile unsigned short *port_addr; | 165 | volatile u16 *port_addr; |
| 172 | const unsigned short *buf=buffer; | 166 | const u16 *buf = src; |
| 173 | 167 | ||
| 174 | port_addr = (volatile unsigned short *)PORT2ADDR(port); | 168 | port_addr = (volatile u16 __force *)ioport_map(port, 2); |
| 175 | 169 | ||
| 176 | while(count--) | 170 | while (count--) |
| 177 | *port_addr = *buf++; | 171 | *port_addr = *buf++; |
| 178 | 172 | ||
| 179 | #ifdef SH3_PCMCIA_BUG_WORKAROUND | 173 | dummy_read(); |
| 180 | ctrl_inb (DUMMY_READ_AREA6); | ||
| 181 | #endif | ||
| 182 | } | 174 | } |
| 183 | 175 | ||
| 184 | void generic_outsl(unsigned long port, const void *buffer, unsigned long count) | 176 | void generic_outsl(unsigned long port, const void *src, unsigned long count) |
| 185 | { | 177 | { |
| 186 | volatile unsigned long *port_addr; | 178 | volatile u32 *port_addr; |
| 187 | const unsigned long *buf=buffer; | 179 | const u32 *buf = src; |
| 188 | 180 | ||
| 189 | port_addr = (volatile unsigned long *)PORT2ADDR(port); | 181 | port_addr = (volatile u32 __force *)ioport_map(port, 4); |
| 182 | while (count--) | ||
| 183 | *port_addr = *buf++; | ||
| 190 | 184 | ||
| 191 | while(count--) | 185 | dummy_read(); |
| 192 | *port_addr = *buf++; | ||
| 193 | |||
| 194 | #ifdef SH3_PCMCIA_BUG_WORKAROUND | ||
| 195 | ctrl_inb (DUMMY_READ_AREA6); | ||
| 196 | #endif | ||
| 197 | } | ||
| 198 | |||
| 199 | unsigned char generic_readb(unsigned long addr) | ||
| 200 | { | ||
| 201 | return *(volatile unsigned char*)addr; | ||
| 202 | } | 186 | } |
| 203 | 187 | ||
| 204 | unsigned short generic_readw(unsigned long addr) | 188 | u8 generic_readb(void __iomem *addr) |
| 205 | { | 189 | { |
| 206 | return *(volatile unsigned short*)addr; | 190 | return ctrl_inb((unsigned long __force)addr); |
| 207 | } | 191 | } |
| 208 | 192 | ||
| 209 | unsigned int generic_readl(unsigned long addr) | 193 | u16 generic_readw(void __iomem *addr) |
| 210 | { | 194 | { |
| 211 | return *(volatile unsigned long*)addr; | 195 | return ctrl_inw((unsigned long __force)addr); |
| 212 | } | 196 | } |
| 213 | 197 | ||
| 214 | void generic_writeb(unsigned char b, unsigned long addr) | 198 | u32 generic_readl(void __iomem *addr) |
| 215 | { | 199 | { |
| 216 | *(volatile unsigned char*)addr = b; | 200 | return ctrl_inl((unsigned long __force)addr); |
| 217 | } | 201 | } |
| 218 | 202 | ||
| 219 | void generic_writew(unsigned short b, unsigned long addr) | 203 | void generic_writeb(u8 b, void __iomem *addr) |
| 220 | { | 204 | { |
| 221 | *(volatile unsigned short*)addr = b; | 205 | ctrl_outb(b, (unsigned long __force)addr); |
| 222 | } | 206 | } |
| 223 | 207 | ||
| 224 | void generic_writel(unsigned int b, unsigned long addr) | 208 | void generic_writew(u16 b, void __iomem *addr) |
| 225 | { | 209 | { |
| 226 | *(volatile unsigned long*)addr = b; | 210 | ctrl_outw(b, (unsigned long __force)addr); |
| 227 | } | 211 | } |
| 228 | 212 | ||
| 229 | void * generic_ioremap(unsigned long offset, unsigned long size) | 213 | void generic_writel(u32 b, void __iomem *addr) |
| 230 | { | 214 | { |
| 231 | return (void *) P2SEGADDR(offset); | 215 | ctrl_outl(b, (unsigned long __force)addr); |
| 232 | } | 216 | } |
| 233 | EXPORT_SYMBOL(generic_ioremap); | ||
| 234 | 217 | ||
| 235 | void generic_iounmap(void *addr) | 218 | void __iomem *generic_ioport_map(unsigned long addr, unsigned int size) |
| 236 | { | 219 | { |
| 220 | return (void __iomem *)(addr + generic_io_base); | ||
| 237 | } | 221 | } |
| 238 | EXPORT_SYMBOL(generic_iounmap); | ||
| 239 | 222 | ||
| 240 | unsigned long generic_isa_port2addr(unsigned long offset) | 223 | void generic_ioport_unmap(void __iomem *addr) |
| 241 | { | 224 | { |
| 242 | return offset + generic_io_base; | ||
| 243 | } | 225 | } |
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 54c171225b78..6883c00728cb 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c | |||
| @@ -8,38 +8,13 @@ | |||
| 8 | * SuperH version: Copyright (C) 1999 Niibe Yutaka | 8 | * SuperH version: Copyright (C) 1999 Niibe Yutaka |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | /* | 11 | #include <linux/irq.h> |
| 12 | * IRQs are in fact implemented a bit like signal handlers for the kernel. | ||
| 13 | * Naturally it's not a 1:1 relation, but there are similarities. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/config.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/ptrace.h> | ||
| 19 | #include <linux/errno.h> | ||
| 20 | #include <linux/kernel_stat.h> | ||
| 21 | #include <linux/signal.h> | ||
| 22 | #include <linux/sched.h> | ||
| 23 | #include <linux/ioport.h> | ||
| 24 | #include <linux/interrupt.h> | 12 | #include <linux/interrupt.h> |
| 25 | #include <linux/timex.h> | 13 | #include <linux/kernel_stat.h> |
| 26 | #include <linux/mm.h> | ||
| 27 | #include <linux/slab.h> | ||
| 28 | #include <linux/random.h> | ||
| 29 | #include <linux/smp.h> | ||
| 30 | #include <linux/smp_lock.h> | ||
| 31 | #include <linux/init.h> | ||
| 32 | #include <linux/seq_file.h> | 14 | #include <linux/seq_file.h> |
| 33 | #include <linux/kallsyms.h> | ||
| 34 | #include <linux/bitops.h> | ||
| 35 | |||
| 36 | #include <asm/system.h> | ||
| 37 | #include <asm/io.h> | ||
| 38 | #include <asm/pgalloc.h> | ||
| 39 | #include <asm/delay.h> | ||
| 40 | #include <asm/irq.h> | 15 | #include <asm/irq.h> |
| 41 | #include <linux/irq.h> | 16 | #include <asm/processor.h> |
| 42 | 17 | #include <asm/cpu/mmu_context.h> | |
| 43 | 18 | ||
| 44 | /* | 19 | /* |
| 45 | * 'what should we do if we get a hw irq event on an illegal vector'. | 20 | * 'what should we do if we get a hw irq event on an illegal vector'. |
| @@ -66,7 +41,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
| 66 | seq_putc(p, '\n'); | 41 | seq_putc(p, '\n'); |
| 67 | } | 42 | } |
| 68 | 43 | ||
| 69 | if (i < ACTUAL_NR_IRQS) { | 44 | if (i < NR_IRQS) { |
| 70 | spin_lock_irqsave(&irq_desc[i].lock, flags); | 45 | spin_lock_irqsave(&irq_desc[i].lock, flags); |
| 71 | action = irq_desc[i].action; | 46 | action = irq_desc[i].action; |
| 72 | if (!action) | 47 | if (!action) |
| @@ -86,19 +61,32 @@ unlock: | |||
| 86 | } | 61 | } |
| 87 | #endif | 62 | #endif |
| 88 | 63 | ||
| 64 | |||
| 89 | asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, | 65 | asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, |
| 90 | unsigned long r6, unsigned long r7, | 66 | unsigned long r6, unsigned long r7, |
| 91 | struct pt_regs regs) | 67 | struct pt_regs regs) |
| 92 | { | 68 | { |
| 93 | int irq; | 69 | int irq = r4; |
| 94 | 70 | ||
| 95 | irq_enter(); | 71 | irq_enter(); |
| 96 | asm volatile("stc r2_bank, %0\n\t" | 72 | |
| 97 | "shlr2 %0\n\t" | 73 | #ifdef CONFIG_CPU_HAS_INTEVT |
| 98 | "shlr2 %0\n\t" | 74 | __asm__ __volatile__ ( |
| 99 | "shlr %0\n\t" | 75 | #ifdef CONFIG_CPU_HAS_SR_RB |
| 100 | "add #-16, %0\n\t" | 76 | "stc r2_bank, %0\n\t" |
| 101 | :"=z" (irq)); | 77 | #else |
| 78 | "mov.l @%1, %0\n\t" | ||
| 79 | #endif | ||
| 80 | "shlr2 %0\n\t" | ||
| 81 | "shlr2 %0\n\t" | ||
| 82 | "shlr %0\n\t" | ||
| 83 | "add #-16, %0\n\t" | ||
| 84 | : "=z" (irq), "=r" (r4) | ||
| 85 | : "1" (INTEVT) | ||
| 86 | : "memory" | ||
| 87 | ); | ||
| 88 | #endif | ||
| 89 | |||
| 102 | irq = irq_demux(irq); | 90 | irq = irq_demux(irq); |
| 103 | __do_IRQ(irq, ®s); | 91 | __do_IRQ(irq, ®s); |
| 104 | irq_exit(); | 92 | irq_exit(); |
diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c new file mode 100644 index 000000000000..43546525f28f --- /dev/null +++ b/arch/sh/kernel/machine_kexec.c | |||
| @@ -0,0 +1,112 @@ | |||
| 1 | /* | ||
| 2 | * machine_kexec.c - handle transition of Linux booting another kernel | ||
| 3 | * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com> | ||
| 4 | * | ||
| 5 | * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz | ||
| 6 | * LANDISK/sh4 supported by kogiidena | ||
| 7 | * | ||
| 8 | * This source code is licensed under the GNU General Public License, | ||
| 9 | * Version 2. See the file COPYING for more details. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/mm.h> | ||
| 13 | #include <linux/kexec.h> | ||
| 14 | #include <linux/delay.h> | ||
| 15 | #include <linux/reboot.h> | ||
| 16 | #include <asm/pgtable.h> | ||
| 17 | #include <asm/pgalloc.h> | ||
| 18 | #include <asm/mmu_context.h> | ||
| 19 | #include <asm/io.h> | ||
| 20 | #include <asm/cacheflush.h> | ||
| 21 | |||
| 22 | typedef NORET_TYPE void (*relocate_new_kernel_t)( | ||
| 23 | unsigned long indirection_page, | ||
| 24 | unsigned long reboot_code_buffer, | ||
| 25 | unsigned long start_address, | ||
| 26 | unsigned long vbr_reg) ATTRIB_NORET; | ||
| 27 | |||
| 28 | const extern unsigned char relocate_new_kernel[]; | ||
| 29 | const extern unsigned int relocate_new_kernel_size; | ||
| 30 | extern void *gdb_vbr_vector; | ||
| 31 | |||
| 32 | /* | ||
| 33 | * Provide a dummy crash_notes definition while crash dump arrives to ppc. | ||
| 34 | * This prevents breakage of crash_notes attribute in kernel/ksysfs.c. | ||
| 35 | */ | ||
| 36 | void *crash_notes = NULL; | ||
| 37 | |||
| 38 | void machine_shutdown(void) | ||
| 39 | { | ||
| 40 | } | ||
| 41 | |||
| 42 | void machine_crash_shutdown(struct pt_regs *regs) | ||
| 43 | { | ||
| 44 | } | ||
| 45 | |||
| 46 | /* | ||
| 47 | * Do what every setup is needed on image and the | ||
| 48 | * reboot code buffer to allow us to avoid allocations | ||
| 49 | * later. | ||
| 50 | */ | ||
| 51 | int machine_kexec_prepare(struct kimage *image) | ||
| 52 | { | ||
| 53 | return 0; | ||
| 54 | } | ||
| 55 | |||
| 56 | void machine_kexec_cleanup(struct kimage *image) | ||
| 57 | { | ||
| 58 | } | ||
| 59 | |||
| 60 | static void kexec_info(struct kimage *image) | ||
| 61 | { | ||
| 62 | int i; | ||
| 63 | printk("kexec information\n"); | ||
| 64 | for (i = 0; i < image->nr_segments; i++) { | ||
| 65 | printk(" segment[%d]: 0x%08x - 0x%08x (0x%08x)\n", | ||
| 66 | i, | ||
| 67 | (unsigned int)image->segment[i].mem, | ||
| 68 | (unsigned int)image->segment[i].mem + image->segment[i].memsz, | ||
| 69 | (unsigned int)image->segment[i].memsz); | ||
| 70 | } | ||
| 71 | printk(" start : 0x%08x\n\n", (unsigned int)image->start); | ||
| 72 | } | ||
| 73 | |||
| 74 | |||
| 75 | /* | ||
| 76 | * Do not allocate memory (or fail in any way) in machine_kexec(). | ||
| 77 | * We are past the point of no return, committed to rebooting now. | ||
| 78 | */ | ||
| 79 | NORET_TYPE void machine_kexec(struct kimage *image) | ||
| 80 | { | ||
| 81 | |||
| 82 | unsigned long page_list; | ||
| 83 | unsigned long reboot_code_buffer; | ||
| 84 | unsigned long vbr_reg; | ||
| 85 | relocate_new_kernel_t rnk; | ||
| 86 | |||
| 87 | #if defined(CONFIG_SH_STANDARD_BIOS) | ||
| 88 | vbr_reg = ((unsigned long )gdb_vbr_vector) - 0x100; | ||
| 89 | #else | ||
| 90 | vbr_reg = 0x80000000; // dummy | ||
| 91 | #endif | ||
| 92 | /* Interrupts aren't acceptable while we reboot */ | ||
| 93 | local_irq_disable(); | ||
| 94 | |||
| 95 | page_list = image->head; | ||
| 96 | |||
| 97 | /* we need both effective and real address here */ | ||
| 98 | reboot_code_buffer = | ||
| 99 | (unsigned long)page_address(image->control_code_page); | ||
| 100 | |||
| 101 | /* copy our kernel relocation code to the control code page */ | ||
| 102 | memcpy((void *)reboot_code_buffer, relocate_new_kernel, | ||
| 103 | relocate_new_kernel_size); | ||
| 104 | |||
| 105 | kexec_info(image); | ||
| 106 | flush_cache_all(); | ||
| 107 | |||
| 108 | /* now call it */ | ||
| 109 | rnk = (relocate_new_kernel_t) reboot_code_buffer; | ||
| 110 | (*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg); | ||
| 111 | } | ||
| 112 | |||
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index aac15e42d03b..a4dc2b532e10 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c | |||
| @@ -71,6 +71,16 @@ void cpu_idle(void) | |||
| 71 | 71 | ||
| 72 | void machine_restart(char * __unused) | 72 | void machine_restart(char * __unused) |
| 73 | { | 73 | { |
| 74 | |||
| 75 | #ifdef CONFIG_KEXEC | ||
| 76 | struct kimage *image; | ||
| 77 | image = xchg(&kexec_image, 0); | ||
| 78 | if (image) { | ||
| 79 | machine_shutdown(); | ||
| 80 | machine_kexec(image); | ||
| 81 | } | ||
| 82 | #endif | ||
| 83 | |||
| 74 | /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */ | 84 | /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */ |
| 75 | asm volatile("ldc %0, sr\n\t" | 85 | asm volatile("ldc %0, sr\n\t" |
| 76 | "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001)); | 86 | "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001)); |
diff --git a/arch/sh/kernel/relocate_kernel.S b/arch/sh/kernel/relocate_kernel.S new file mode 100644 index 000000000000..b0695cffec6e --- /dev/null +++ b/arch/sh/kernel/relocate_kernel.S | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | /* | ||
| 2 | * relocate_kernel.S - put the kernel image in place to boot | ||
| 3 | * 2005.9.17 kogiidena@eggplant.ddo.jp | ||
| 4 | * | ||
| 5 | * LANDISK/sh4 is supported. Maybe, SH archtecture works well. | ||
| 6 | * | ||
| 7 | * This source code is licensed under the GNU General Public License, | ||
| 8 | * Version 2. See the file COPYING for more details. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/config.h> | ||
| 12 | #include <linux/linkage.h> | ||
| 13 | |||
| 14 | #define PAGE_SIZE 4096 /* must be same value as in <asm/page.h> */ | ||
| 15 | |||
| 16 | |||
| 17 | .globl relocate_new_kernel | ||
| 18 | relocate_new_kernel: | ||
| 19 | /* r4 = indirection_page */ | ||
| 20 | /* r5 = reboot_code_buffer */ | ||
| 21 | /* r6 = start_address */ | ||
| 22 | /* r7 = vbr_reg */ | ||
| 23 | |||
| 24 | mov.l 10f,r8 /* 4096 */ | ||
| 25 | mov.l 11f,r9 /* 0xa0000000 */ | ||
| 26 | |||
| 27 | /* stack setting */ | ||
| 28 | add r8,r5 | ||
| 29 | mov r5,r15 | ||
| 30 | |||
| 31 | bra 1f | ||
| 32 | mov r4,r0 /* cmd = indirection_page */ | ||
| 33 | 0: | ||
| 34 | mov.l @r4+,r0 /* cmd = *ind++ */ | ||
| 35 | |||
| 36 | 1: /* addr = (cmd | 0xa0000000) & 0xfffffff0 */ | ||
| 37 | mov r0,r2 | ||
| 38 | or r9,r2 | ||
| 39 | mov #-16,r1 | ||
| 40 | and r1,r2 | ||
| 41 | |||
| 42 | /* if(cmd & IND_DESTINATION) dst = addr */ | ||
| 43 | tst #1,r0 | ||
| 44 | bt 2f | ||
| 45 | bra 0b | ||
| 46 | mov r2,r5 | ||
| 47 | |||
| 48 | 2: /* else if(cmd & IND_INDIRECTION) ind = addr */ | ||
| 49 | tst #2,r0 | ||
| 50 | bt 3f | ||
| 51 | bra 0b | ||
| 52 | mov r2,r4 | ||
| 53 | |||
| 54 | 3: /* else if(cmd & IND_DONE) goto 6 */ | ||
| 55 | tst #4,r0 | ||
| 56 | bt 4f | ||
| 57 | bra 6f | ||
| 58 | nop | ||
| 59 | |||
| 60 | 4: /* else if(cmd & IND_SOURCE) memcpy(dst,addr,PAGE_SIZE) */ | ||
| 61 | tst #8,r0 | ||
| 62 | bt 0b | ||
| 63 | |||
| 64 | mov r8,r3 | ||
| 65 | shlr2 r3 | ||
| 66 | shlr2 r3 | ||
| 67 | 5: | ||
| 68 | dt r3 | ||
| 69 | mov.l @r2+,r1 /* 16n+0 */ | ||
| 70 | mov.l r1,@r5 | ||
| 71 | add #4,r5 | ||
| 72 | mov.l @r2+,r1 /* 16n+4 */ | ||
| 73 | mov.l r1,@r5 | ||
| 74 | add #4,r5 | ||
| 75 | mov.l @r2+,r1 /* 16n+8 */ | ||
| 76 | mov.l r1,@r5 | ||
| 77 | add #4,r5 | ||
| 78 | mov.l @r2+,r1 /* 16n+12 */ | ||
| 79 | mov.l r1,@r5 | ||
| 80 | add #4,r5 | ||
| 81 | bf 5b | ||
| 82 | |||
| 83 | bra 0b | ||
| 84 | nop | ||
| 85 | 6: | ||
| 86 | #ifdef CONFIG_SH_STANDARD_BIOS | ||
| 87 | ldc r7, vbr | ||
| 88 | #endif | ||
| 89 | jmp @r6 | ||
| 90 | nop | ||
| 91 | |||
| 92 | .align 2 | ||
| 93 | 10: | ||
| 94 | .long PAGE_SIZE | ||
| 95 | 11: | ||
| 96 | .long 0xa0000000 | ||
| 97 | |||
| 98 | relocate_new_kernel_end: | ||
| 99 | |||
| 100 | .globl relocate_new_kernel_size | ||
| 101 | relocate_new_kernel_size: | ||
| 102 | .long relocate_new_kernel_end - relocate_new_kernel | ||
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index 671b876416bf..314a275c04e0 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka | 4 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka |
| 5 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> | 5 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> |
| 6 | * Copyright (C) 2002, 2003, 2004 Paul Mundt | 6 | * Copyright (C) 2002, 2003, 2004, 2005 Paul Mundt |
| 7 | * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> | 7 | * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> |
| 8 | * | 8 | * |
| 9 | * Some code taken from i386 version. | 9 | * Some code taken from i386 version. |
| @@ -11,50 +11,21 @@ | |||
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/config.h> | 13 | #include <linux/config.h> |
| 14 | #include <linux/errno.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/sched.h> | ||
| 17 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
| 18 | #include <linux/param.h> | 15 | #include <linux/module.h> |
| 19 | #include <linux/string.h> | ||
| 20 | #include <linux/mm.h> | ||
| 21 | #include <linux/interrupt.h> | ||
| 22 | #include <linux/time.h> | ||
| 23 | #include <linux/delay.h> | ||
| 24 | #include <linux/init.h> | 16 | #include <linux/init.h> |
| 25 | #include <linux/smp.h> | ||
| 26 | #include <linux/profile.h> | 17 | #include <linux/profile.h> |
| 27 | 18 | #include <asm/clock.h> | |
| 28 | #include <asm/processor.h> | ||
| 29 | #include <asm/uaccess.h> | ||
| 30 | #include <asm/io.h> | ||
| 31 | #include <asm/irq.h> | ||
| 32 | #include <asm/delay.h> | ||
| 33 | #include <asm/machvec.h> | ||
| 34 | #include <asm/rtc.h> | 19 | #include <asm/rtc.h> |
| 35 | #include <asm/freq.h> | 20 | #include <asm/timer.h> |
| 36 | #include <asm/cpu/timer.h> | ||
| 37 | #ifdef CONFIG_SH_KGDB | ||
| 38 | #include <asm/kgdb.h> | 21 | #include <asm/kgdb.h> |
| 39 | #endif | ||
| 40 | |||
| 41 | #include <linux/timex.h> | ||
| 42 | #include <linux/irq.h> | ||
| 43 | |||
| 44 | #define TMU_TOCR_INIT 0x00 | ||
| 45 | #define TMU0_TCR_INIT 0x0020 | ||
| 46 | #define TMU_TSTR_INIT 1 | ||
| 47 | |||
| 48 | #define TMU0_TCR_CALIB 0x0000 | ||
| 49 | |||
| 50 | #ifdef CONFIG_CPU_SUBTYPE_ST40STB1 | ||
| 51 | #define CLOCKGEN_MEMCLKCR 0xbb040038 | ||
| 52 | #define MEMCLKCR_RATIO_MASK 0x7 | ||
| 53 | #endif /* CONFIG_CPU_SUBTYPE_ST40STB1 */ | ||
| 54 | 22 | ||
| 55 | extern unsigned long wall_jiffies; | 23 | extern unsigned long wall_jiffies; |
| 56 | #define TICK_SIZE (tick_nsec / 1000) | 24 | struct sys_timer *sys_timer; |
| 57 | DEFINE_SPINLOCK(tmu0_lock); | 25 | |
| 26 | /* Move this somewhere more sensible.. */ | ||
| 27 | DEFINE_SPINLOCK(rtc_lock); | ||
| 28 | EXPORT_SYMBOL(rtc_lock); | ||
| 58 | 29 | ||
| 59 | /* XXX: Can we initialize this in a routine somewhere? Dreamcast doesn't want | 30 | /* XXX: Can we initialize this in a routine somewhere? Dreamcast doesn't want |
| 60 | * these routines anywhere... */ | 31 | * these routines anywhere... */ |
| @@ -66,98 +37,14 @@ void (*rtc_get_time)(struct timespec *); | |||
| 66 | int (*rtc_set_time)(const time_t); | 37 | int (*rtc_set_time)(const time_t); |
| 67 | #endif | 38 | #endif |
| 68 | 39 | ||
| 69 | #if defined(CONFIG_CPU_SUBTYPE_SH7300) | ||
| 70 | static int md_table[] = { 1, 2, 3, 4, 6, 8, 12 }; | ||
| 71 | #endif | ||
| 72 | #if defined(CONFIG_CPU_SH3) | ||
| 73 | static int stc_multipliers[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; | ||
| 74 | static int stc_values[] = { 0, 1, 4, 2, 5, 0, 0, 0 }; | ||
| 75 | #define bfc_divisors stc_multipliers | ||
| 76 | #define bfc_values stc_values | ||
| 77 | static int ifc_divisors[] = { 1, 2, 3, 4, 1, 1, 1, 1 }; | ||
| 78 | static int ifc_values[] = { 0, 1, 4, 2, 0, 0, 0, 0 }; | ||
| 79 | static int pfc_divisors[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; | ||
| 80 | static int pfc_values[] = { 0, 1, 4, 2, 5, 0, 0, 0 }; | ||
| 81 | #elif defined(CONFIG_CPU_SH4) | ||
| 82 | #if defined(CONFIG_CPU_SUBTYPE_SH73180) | ||
| 83 | static int ifc_divisors[] = { 1, 2, 3, 4, 6, 8, 12, 16 }; | ||
| 84 | static int ifc_values[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; | ||
| 85 | #define bfc_divisors ifc_divisors /* Same */ | ||
| 86 | #define bfc_values ifc_values | ||
| 87 | #define pfc_divisors ifc_divisors /* Same */ | ||
| 88 | #define pfc_values ifc_values | ||
| 89 | #else | ||
| 90 | static int ifc_divisors[] = { 1, 2, 3, 4, 6, 8, 1, 1 }; | ||
| 91 | static int ifc_values[] = { 0, 1, 2, 3, 0, 4, 0, 5 }; | ||
| 92 | #define bfc_divisors ifc_divisors /* Same */ | ||
| 93 | #define bfc_values ifc_values | ||
| 94 | static int pfc_divisors[] = { 2, 3, 4, 6, 8, 2, 2, 2 }; | ||
| 95 | static int pfc_values[] = { 0, 0, 1, 2, 0, 3, 0, 4 }; | ||
| 96 | #endif | ||
| 97 | #else | ||
| 98 | #error "Unknown ifc/bfc/pfc/stc values for this processor" | ||
| 99 | #endif | ||
| 100 | |||
| 101 | /* | 40 | /* |
| 102 | * Scheduler clock - returns current time in nanosec units. | 41 | * Scheduler clock - returns current time in nanosec units. |
| 103 | */ | 42 | */ |
| 104 | unsigned long long sched_clock(void) | 43 | unsigned long long __attribute__ ((weak)) sched_clock(void) |
| 105 | { | 44 | { |
| 106 | return (unsigned long long)jiffies * (1000000000 / HZ); | 45 | return (unsigned long long)jiffies * (1000000000 / HZ); |
| 107 | } | 46 | } |
| 108 | 47 | ||
| 109 | static unsigned long do_gettimeoffset(void) | ||
| 110 | { | ||
| 111 | int count; | ||
| 112 | unsigned long flags; | ||
| 113 | |||
| 114 | static int count_p = 0x7fffffff; /* for the first call after boot */ | ||
| 115 | static unsigned long jiffies_p = 0; | ||
| 116 | |||
| 117 | /* | ||
| 118 | * cache volatile jiffies temporarily; we have IRQs turned off. | ||
| 119 | */ | ||
| 120 | unsigned long jiffies_t; | ||
| 121 | |||
| 122 | spin_lock_irqsave(&tmu0_lock, flags); | ||
| 123 | /* timer count may underflow right here */ | ||
| 124 | count = ctrl_inl(TMU0_TCNT); /* read the latched count */ | ||
| 125 | |||
| 126 | jiffies_t = jiffies; | ||
| 127 | |||
| 128 | /* | ||
| 129 | * avoiding timer inconsistencies (they are rare, but they happen)... | ||
| 130 | * there is one kind of problem that must be avoided here: | ||
| 131 | * 1. the timer counter underflows | ||
| 132 | */ | ||
| 133 | |||
| 134 | if( jiffies_t == jiffies_p ) { | ||
| 135 | if( count > count_p ) { | ||
| 136 | /* the nutcase */ | ||
| 137 | |||
| 138 | if(ctrl_inw(TMU0_TCR) & 0x100) { /* Check UNF bit */ | ||
| 139 | /* | ||
| 140 | * We cannot detect lost timer interrupts ... | ||
| 141 | * well, that's why we call them lost, don't we? :) | ||
| 142 | * [hmm, on the Pentium and Alpha we can ... sort of] | ||
| 143 | */ | ||
| 144 | count -= LATCH; | ||
| 145 | } else { | ||
| 146 | printk("do_slow_gettimeoffset(): hardware timer problem?\n"); | ||
| 147 | } | ||
| 148 | } | ||
| 149 | } else | ||
| 150 | jiffies_p = jiffies_t; | ||
| 151 | |||
| 152 | count_p = count; | ||
| 153 | spin_unlock_irqrestore(&tmu0_lock, flags); | ||
| 154 | |||
| 155 | count = ((LATCH-1) - count) * TICK_SIZE; | ||
| 156 | count = (count + LATCH/2) / LATCH; | ||
| 157 | |||
| 158 | return count; | ||
| 159 | } | ||
| 160 | |||
| 161 | void do_gettimeofday(struct timeval *tv) | 48 | void do_gettimeofday(struct timeval *tv) |
| 162 | { | 49 | { |
| 163 | unsigned long seq; | 50 | unsigned long seq; |
| @@ -166,7 +53,7 @@ void do_gettimeofday(struct timeval *tv) | |||
| 166 | 53 | ||
| 167 | do { | 54 | do { |
| 168 | seq = read_seqbegin(&xtime_lock); | 55 | seq = read_seqbegin(&xtime_lock); |
| 169 | usec = do_gettimeoffset(); | 56 | usec = get_timer_offset(); |
| 170 | 57 | ||
| 171 | lost = jiffies - wall_jiffies; | 58 | lost = jiffies - wall_jiffies; |
| 172 | if (lost) | 59 | if (lost) |
| @@ -202,7 +89,7 @@ int do_settimeofday(struct timespec *tv) | |||
| 202 | * wall time. Discover what correction gettimeofday() would have | 89 | * wall time. Discover what correction gettimeofday() would have |
| 203 | * made, and then undo it! | 90 | * made, and then undo it! |
| 204 | */ | 91 | */ |
| 205 | nsec -= 1000 * (do_gettimeoffset() + | 92 | nsec -= 1000 * (get_timer_offset() + |
| 206 | (jiffies - wall_jiffies) * (1000000 / HZ)); | 93 | (jiffies - wall_jiffies) * (1000000 / HZ)); |
| 207 | 94 | ||
| 208 | wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); | 95 | wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); |
| @@ -224,10 +111,10 @@ EXPORT_SYMBOL(do_settimeofday); | |||
| 224 | static long last_rtc_update; | 111 | static long last_rtc_update; |
| 225 | 112 | ||
| 226 | /* | 113 | /* |
| 227 | * timer_interrupt() needs to keep up the real-time clock, | 114 | * handle_timer_tick() needs to keep up the real-time clock, |
| 228 | * as well as call the "do_timer()" routine every clocktick | 115 | * as well as call the "do_timer()" routine every clocktick |
| 229 | */ | 116 | */ |
| 230 | static inline void do_timer_interrupt(int irq, struct pt_regs *regs) | 117 | void handle_timer_tick(struct pt_regs *regs) |
| 231 | { | 118 | { |
| 232 | do_timer(regs); | 119 | do_timer(regs); |
| 233 | #ifndef CONFIG_SMP | 120 | #ifndef CONFIG_SMP |
| @@ -252,337 +139,35 @@ static inline void do_timer_interrupt(int irq, struct pt_regs *regs) | |||
| 252 | if (rtc_set_time(xtime.tv_sec) == 0) | 139 | if (rtc_set_time(xtime.tv_sec) == 0) |
| 253 | last_rtc_update = xtime.tv_sec; | 140 | last_rtc_update = xtime.tv_sec; |
| 254 | else | 141 | else |
| 255 | last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ | 142 | /* do it again in 60s */ |
| 143 | last_rtc_update = xtime.tv_sec - 600; | ||
| 256 | } | 144 | } |
| 257 | } | 145 | } |
| 258 | 146 | ||
| 259 | /* | 147 | static struct sysdev_class timer_sysclass = { |
| 260 | * This is the same as the above, except we _also_ save the current | 148 | set_kset_name("timer"), |
| 261 | * Time Stamp Counter value at the time of the timer interrupt, so that | ||
| 262 | * we later on can estimate the time of day more exactly. | ||
| 263 | */ | ||
| 264 | static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
| 265 | { | ||
| 266 | unsigned long timer_status; | ||
| 267 | |||
| 268 | /* Clear UNF bit */ | ||
| 269 | timer_status = ctrl_inw(TMU0_TCR); | ||
| 270 | timer_status &= ~0x100; | ||
| 271 | ctrl_outw(timer_status, TMU0_TCR); | ||
| 272 | |||
| 273 | /* | ||
| 274 | * Here we are in the timer irq handler. We just have irqs locally | ||
| 275 | * disabled but we don't know if the timer_bh is running on the other | ||
| 276 | * CPU. We need to avoid to SMP race with it. NOTE: we don' t need | ||
| 277 | * the irq version of write_lock because as just said we have irq | ||
| 278 | * locally disabled. -arca | ||
| 279 | */ | ||
| 280 | write_seqlock(&xtime_lock); | ||
| 281 | do_timer_interrupt(irq, regs); | ||
| 282 | write_sequnlock(&xtime_lock); | ||
| 283 | |||
| 284 | return IRQ_HANDLED; | ||
| 285 | } | ||
| 286 | |||
| 287 | /* | ||
| 288 | * Hah! We'll see if this works (switching from usecs to nsecs). | ||
| 289 | */ | ||
| 290 | static unsigned int __init get_timer_frequency(void) | ||
| 291 | { | ||
| 292 | u32 freq; | ||
| 293 | struct timespec ts1, ts2; | ||
| 294 | unsigned long diff_nsec; | ||
| 295 | unsigned long factor; | ||
| 296 | |||
| 297 | /* Setup the timer: We don't want to generate interrupts, just | ||
| 298 | * have it count down at its natural rate. | ||
| 299 | */ | ||
| 300 | ctrl_outb(0, TMU_TSTR); | ||
| 301 | #if !defined(CONFIG_CPU_SUBTYPE_SH7300) | ||
| 302 | ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); | ||
| 303 | #endif | ||
| 304 | ctrl_outw(TMU0_TCR_CALIB, TMU0_TCR); | ||
| 305 | ctrl_outl(0xffffffff, TMU0_TCOR); | ||
| 306 | ctrl_outl(0xffffffff, TMU0_TCNT); | ||
| 307 | |||
| 308 | rtc_get_time(&ts2); | ||
| 309 | |||
| 310 | do { | ||
| 311 | rtc_get_time(&ts1); | ||
| 312 | } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); | ||
| 313 | |||
| 314 | /* actually start the timer */ | ||
| 315 | ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); | ||
| 316 | |||
| 317 | do { | ||
| 318 | rtc_get_time(&ts2); | ||
| 319 | } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); | ||
| 320 | |||
| 321 | freq = 0xffffffff - ctrl_inl(TMU0_TCNT); | ||
| 322 | if (ts2.tv_nsec < ts1.tv_nsec) { | ||
| 323 | ts2.tv_nsec += 1000000000; | ||
| 324 | ts2.tv_sec--; | ||
| 325 | } | ||
| 326 | |||
| 327 | diff_nsec = (ts2.tv_sec - ts1.tv_sec) * 1000000000 + (ts2.tv_nsec - ts1.tv_nsec); | ||
| 328 | |||
| 329 | /* this should work well if the RTC has a precision of n Hz, where | ||
| 330 | * n is an integer. I don't think we have to worry about the other | ||
| 331 | * cases. */ | ||
| 332 | factor = (1000000000 + diff_nsec/2) / diff_nsec; | ||
| 333 | |||
| 334 | if (factor * diff_nsec > 1100000000 || | ||
| 335 | factor * diff_nsec < 900000000) | ||
| 336 | panic("weird RTC (diff_nsec %ld)", diff_nsec); | ||
| 337 | |||
| 338 | return freq * factor; | ||
| 339 | } | ||
| 340 | |||
| 341 | void (*board_time_init)(void); | ||
| 342 | void (*board_timer_setup)(struct irqaction *irq); | ||
| 343 | |||
| 344 | static unsigned int sh_pclk_freq __initdata = CONFIG_SH_PCLK_FREQ; | ||
| 345 | |||
| 346 | static int __init sh_pclk_setup(char *str) | ||
| 347 | { | ||
| 348 | unsigned int freq; | ||
| 349 | |||
| 350 | if (get_option(&str, &freq)) | ||
| 351 | sh_pclk_freq = freq; | ||
| 352 | |||
| 353 | return 1; | ||
| 354 | } | ||
| 355 | __setup("sh_pclk=", sh_pclk_setup); | ||
| 356 | |||
| 357 | static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL}; | ||
| 358 | |||
| 359 | void get_current_frequency_divisors(unsigned int *ifc, unsigned int *bfc, unsigned int *pfc) | ||
| 360 | { | ||
| 361 | unsigned int frqcr = ctrl_inw(FRQCR); | ||
| 362 | |||
| 363 | #if defined(CONFIG_CPU_SH3) | ||
| 364 | #if defined(CONFIG_CPU_SUBTYPE_SH7300) | ||
| 365 | *ifc = md_table[((frqcr & 0x0070) >> 4)]; | ||
| 366 | *bfc = md_table[((frqcr & 0x0700) >> 8)]; | ||
| 367 | *pfc = md_table[frqcr & 0x0007]; | ||
| 368 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) | ||
| 369 | *bfc = stc_multipliers[(frqcr & 0x0300) >> 8]; | ||
| 370 | *ifc = ifc_divisors[(frqcr & 0x0030) >> 4]; | ||
| 371 | *pfc = pfc_divisors[frqcr & 0x0003]; | ||
| 372 | #else | ||
| 373 | unsigned int tmp; | ||
| 374 | |||
| 375 | tmp = (frqcr & 0x8000) >> 13; | ||
| 376 | tmp |= (frqcr & 0x0030) >> 4; | ||
| 377 | *bfc = stc_multipliers[tmp]; | ||
| 378 | tmp = (frqcr & 0x4000) >> 12; | ||
| 379 | tmp |= (frqcr & 0x000c) >> 2; | ||
| 380 | *ifc = ifc_divisors[tmp]; | ||
| 381 | tmp = (frqcr & 0x2000) >> 11; | ||
| 382 | tmp |= frqcr & 0x0003; | ||
| 383 | *pfc = pfc_divisors[tmp]; | ||
| 384 | #endif | ||
| 385 | #elif defined(CONFIG_CPU_SH4) | ||
| 386 | #if defined(CONFIG_CPU_SUBTYPE_SH73180) | ||
| 387 | *ifc = ifc_divisors[(frqcr>> 20) & 0x0007]; | ||
| 388 | *bfc = bfc_divisors[(frqcr>> 12) & 0x0007]; | ||
| 389 | *pfc = pfc_divisors[frqcr & 0x0007]; | ||
| 390 | #else | ||
| 391 | *ifc = ifc_divisors[(frqcr >> 6) & 0x0007]; | ||
| 392 | *bfc = bfc_divisors[(frqcr >> 3) & 0x0007]; | ||
| 393 | *pfc = pfc_divisors[frqcr & 0x0007]; | ||
| 394 | #endif | ||
| 395 | #endif | ||
| 396 | } | ||
| 397 | |||
| 398 | /* | ||
| 399 | * This bit of ugliness builds up accessor routines to get at both | ||
| 400 | * the divisors and the physical values. | ||
| 401 | */ | ||
| 402 | #define _FREQ_TABLE(x) \ | ||
| 403 | unsigned int get_##x##_divisor(unsigned int value) \ | ||
| 404 | { return x##_divisors[value]; } \ | ||
| 405 | \ | ||
| 406 | unsigned int get_##x##_value(unsigned int divisor) \ | ||
| 407 | { return x##_values[(divisor - 1)]; } | ||
| 408 | |||
| 409 | _FREQ_TABLE(ifc); | ||
| 410 | _FREQ_TABLE(bfc); | ||
| 411 | _FREQ_TABLE(pfc); | ||
| 412 | |||
| 413 | #ifdef CONFIG_CPU_SUBTYPE_ST40STB1 | ||
| 414 | |||
| 415 | /* | ||
| 416 | * The ST40 divisors are totally different so we set the cpu data | ||
| 417 | * clocks using a different algorithm | ||
| 418 | * | ||
| 419 | * I've just plugged this from the 2.4 code | ||
| 420 | * - Alex Bennee <kernel-hacker@bennee.com> | ||
| 421 | */ | ||
| 422 | #define CCN_PVR_CHIP_SHIFT 24 | ||
| 423 | #define CCN_PVR_CHIP_MASK 0xff | ||
| 424 | #define CCN_PVR_CHIP_ST40STB1 0x4 | ||
| 425 | |||
| 426 | |||
| 427 | struct frqcr_data { | ||
| 428 | unsigned short frqcr; | ||
| 429 | |||
| 430 | struct { | ||
| 431 | unsigned char multiplier; | ||
| 432 | unsigned char divisor; | ||
| 433 | } factor[3]; | ||
| 434 | }; | ||
| 435 | |||
| 436 | static struct frqcr_data st40_frqcr_table[] = { | ||
| 437 | { 0x000, {{1,1}, {1,1}, {1,2}}}, | ||
| 438 | { 0x002, {{1,1}, {1,1}, {1,4}}}, | ||
| 439 | { 0x004, {{1,1}, {1,1}, {1,8}}}, | ||
| 440 | { 0x008, {{1,1}, {1,2}, {1,2}}}, | ||
| 441 | { 0x00A, {{1,1}, {1,2}, {1,4}}}, | ||
| 442 | { 0x00C, {{1,1}, {1,2}, {1,8}}}, | ||
| 443 | { 0x011, {{1,1}, {2,3}, {1,6}}}, | ||
| 444 | { 0x013, {{1,1}, {2,3}, {1,3}}}, | ||
| 445 | { 0x01A, {{1,1}, {1,2}, {1,4}}}, | ||
| 446 | { 0x01C, {{1,1}, {1,2}, {1,8}}}, | ||
| 447 | { 0x023, {{1,1}, {2,3}, {1,3}}}, | ||
| 448 | { 0x02C, {{1,1}, {1,2}, {1,8}}}, | ||
| 449 | { 0x048, {{1,2}, {1,2}, {1,4}}}, | ||
| 450 | { 0x04A, {{1,2}, {1,2}, {1,6}}}, | ||
| 451 | { 0x04C, {{1,2}, {1,2}, {1,8}}}, | ||
| 452 | { 0x05A, {{1,2}, {1,3}, {1,6}}}, | ||
| 453 | { 0x05C, {{1,2}, {1,3}, {1,6}}}, | ||
| 454 | { 0x063, {{1,2}, {1,4}, {1,4}}}, | ||
| 455 | { 0x06C, {{1,2}, {1,4}, {1,8}}}, | ||
| 456 | { 0x091, {{1,3}, {1,3}, {1,6}}}, | ||
| 457 | { 0x093, {{1,3}, {1,3}, {1,6}}}, | ||
| 458 | { 0x0A3, {{1,3}, {1,6}, {1,6}}}, | ||
| 459 | { 0x0DA, {{1,4}, {1,4}, {1,8}}}, | ||
| 460 | { 0x0DC, {{1,4}, {1,4}, {1,8}}}, | ||
| 461 | { 0x0EC, {{1,4}, {1,8}, {1,8}}}, | ||
| 462 | { 0x123, {{1,4}, {1,4}, {1,8}}}, | ||
| 463 | { 0x16C, {{1,4}, {1,8}, {1,8}}}, | ||
| 464 | }; | 149 | }; |
| 465 | 150 | ||
| 466 | struct memclk_data { | 151 | static int __init timer_init_sysfs(void) |
| 467 | unsigned char multiplier; | ||
| 468 | unsigned char divisor; | ||
| 469 | }; | ||
| 470 | |||
| 471 | static struct memclk_data st40_memclk_table[8] = { | ||
| 472 | {1,1}, // 000 | ||
| 473 | {1,2}, // 001 | ||
| 474 | {1,3}, // 010 | ||
| 475 | {2,3}, // 011 | ||
| 476 | {1,4}, // 100 | ||
| 477 | {1,6}, // 101 | ||
| 478 | {1,8}, // 110 | ||
| 479 | {1,8} // 111 | ||
| 480 | }; | ||
| 481 | |||
| 482 | static void st40_specific_time_init(unsigned int module_clock, unsigned short frqcr) | ||
| 483 | { | 152 | { |
| 484 | unsigned int cpu_clock, master_clock, bus_clock, memory_clock; | 153 | int ret = sysdev_class_register(&timer_sysclass); |
| 485 | struct frqcr_data *d; | 154 | if (ret != 0) |
| 486 | int a; | 155 | return ret; |
| 487 | unsigned long memclkcr; | ||
| 488 | struct memclk_data *e; | ||
| 489 | 156 | ||
| 490 | for (a = 0; a < ARRAY_SIZE(st40_frqcr_table); a++) { | 157 | sys_timer->dev.cls = &timer_sysclass; |
| 491 | d = &st40_frqcr_table[a]; | 158 | return sysdev_register(&sys_timer->dev); |
| 492 | 159 | } | |
| 493 | if (d->frqcr == (frqcr & 0x1ff)) | ||
| 494 | break; | ||
| 495 | } | ||
| 496 | 160 | ||
| 497 | if (a == ARRAY_SIZE(st40_frqcr_table)) { | 161 | device_initcall(timer_init_sysfs); |
| 498 | d = st40_frqcr_table; | ||
| 499 | 162 | ||
| 500 | printk("ERROR: Unrecognised FRQCR value (0x%x), " | 163 | void (*board_time_init)(void); |
| 501 | "using default multipliers\n", frqcr); | ||
| 502 | } | ||
| 503 | |||
| 504 | memclkcr = ctrl_inl(CLOCKGEN_MEMCLKCR); | ||
| 505 | e = &st40_memclk_table[memclkcr & MEMCLKCR_RATIO_MASK]; | ||
| 506 | |||
| 507 | printk(KERN_INFO "Clock multipliers: CPU: %d/%d Bus: %d/%d " | ||
| 508 | "Mem: %d/%d Periph: %d/%d\n", | ||
| 509 | d->factor[0].multiplier, d->factor[0].divisor, | ||
| 510 | d->factor[1].multiplier, d->factor[1].divisor, | ||
| 511 | e->multiplier, e->divisor, | ||
| 512 | d->factor[2].multiplier, d->factor[2].divisor); | ||
| 513 | |||
| 514 | master_clock = module_clock * d->factor[2].divisor | ||
| 515 | / d->factor[2].multiplier; | ||
| 516 | bus_clock = master_clock * d->factor[1].multiplier | ||
| 517 | / d->factor[1].divisor; | ||
| 518 | memory_clock = master_clock * e->multiplier | ||
| 519 | / e->divisor; | ||
| 520 | cpu_clock = master_clock * d->factor[0].multiplier | ||
| 521 | / d->factor[0].divisor; | ||
| 522 | |||
| 523 | current_cpu_data.cpu_clock = cpu_clock; | ||
| 524 | current_cpu_data.master_clock = master_clock; | ||
| 525 | current_cpu_data.bus_clock = bus_clock; | ||
| 526 | current_cpu_data.memory_clock = memory_clock; | ||
| 527 | current_cpu_data.module_clock = module_clock; | ||
| 528 | } | ||
| 529 | #endif | ||
| 530 | 164 | ||
| 531 | void __init time_init(void) | 165 | void __init time_init(void) |
| 532 | { | 166 | { |
| 533 | unsigned int timer_freq = 0; | ||
| 534 | unsigned int ifc, pfc, bfc; | ||
| 535 | unsigned long interval; | ||
| 536 | #ifdef CONFIG_CPU_SUBTYPE_ST40STB1 | ||
| 537 | unsigned long pvr; | ||
| 538 | unsigned short frqcr; | ||
| 539 | #endif | ||
| 540 | |||
| 541 | if (board_time_init) | 167 | if (board_time_init) |
| 542 | board_time_init(); | 168 | board_time_init(); |
| 543 | 169 | ||
| 544 | /* | 170 | clk_init(); |
| 545 | * If we don't have an RTC (such as with the SH7300), don't attempt to | ||
| 546 | * probe the timer frequency. Rely on an either hardcoded peripheral | ||
| 547 | * clock value, or on the sh_pclk command line option. Note that we | ||
| 548 | * still need to have CONFIG_SH_PCLK_FREQ set in order for things like | ||
| 549 | * CLOCK_TICK_RATE to be sane. | ||
| 550 | */ | ||
| 551 | current_cpu_data.module_clock = sh_pclk_freq; | ||
| 552 | |||
| 553 | #ifdef CONFIG_SH_PCLK_CALC | ||
| 554 | /* XXX: Switch this over to a more generic test. */ | ||
| 555 | { | ||
| 556 | unsigned int freq; | ||
| 557 | |||
| 558 | /* | ||
| 559 | * If we've specified a peripheral clock frequency, and we have | ||
| 560 | * an RTC, compare it against the autodetected value. Complain | ||
| 561 | * if there's a mismatch. | ||
| 562 | */ | ||
| 563 | timer_freq = get_timer_frequency(); | ||
| 564 | freq = timer_freq * 4; | ||
| 565 | |||
| 566 | if (sh_pclk_freq && (sh_pclk_freq/100*99 > freq || sh_pclk_freq/100*101 < freq)) { | ||
| 567 | printk(KERN_NOTICE "Calculated peripheral clock value " | ||
| 568 | "%d differs from sh_pclk value %d, fixing..\n", | ||
| 569 | freq, sh_pclk_freq); | ||
| 570 | current_cpu_data.module_clock = freq; | ||
| 571 | } | ||
| 572 | } | ||
| 573 | #endif | ||
| 574 | |||
| 575 | #ifdef CONFIG_CPU_SUBTYPE_ST40STB1 | ||
| 576 | /* XXX: Update ST40 code to use board_time_init() */ | ||
| 577 | pvr = ctrl_inl(CCN_PVR); | ||
| 578 | frqcr = ctrl_inw(FRQCR); | ||
| 579 | printk("time.c ST40 Probe: PVR %08lx, FRQCR %04hx\n", pvr, frqcr); | ||
| 580 | |||
| 581 | if (((pvr >> CCN_PVR_CHIP_SHIFT) & CCN_PVR_CHIP_MASK) == CCN_PVR_CHIP_ST40STB1) | ||
| 582 | st40_specific_time_init(current_cpu_data.module_clock, frqcr); | ||
| 583 | else | ||
| 584 | #endif | ||
| 585 | get_current_frequency_divisors(&ifc, &bfc, &pfc); | ||
| 586 | 171 | ||
| 587 | if (rtc_get_time) { | 172 | if (rtc_get_time) { |
| 588 | rtc_get_time(&xtime); | 173 | rtc_get_time(&xtime); |
| @@ -594,51 +179,12 @@ void __init time_init(void) | |||
| 594 | set_normalized_timespec(&wall_to_monotonic, | 179 | set_normalized_timespec(&wall_to_monotonic, |
| 595 | -xtime.tv_sec, -xtime.tv_nsec); | 180 | -xtime.tv_sec, -xtime.tv_nsec); |
| 596 | 181 | ||
| 597 | if (board_timer_setup) { | ||
| 598 | board_timer_setup(&irq0); | ||
| 599 | } else { | ||
| 600 | setup_irq(TIMER_IRQ, &irq0); | ||
| 601 | } | ||
| 602 | |||
| 603 | /* | 182 | /* |
| 604 | * for ST40 chips the current_cpu_data should already be set | 183 | * Find the timer to use as the system timer, it will be |
| 605 | * so not having valid pfc/bfc/ifc shouldn't be a problem | 184 | * initialized for us. |
| 606 | */ | 185 | */ |
| 607 | if (!current_cpu_data.master_clock) | 186 | sys_timer = get_sys_timer(); |
| 608 | current_cpu_data.master_clock = current_cpu_data.module_clock * pfc; | 187 | printk(KERN_INFO "Using %s for system timer\n", sys_timer->name); |
| 609 | if (!current_cpu_data.bus_clock) | ||
| 610 | current_cpu_data.bus_clock = current_cpu_data.master_clock / bfc; | ||
| 611 | if (!current_cpu_data.cpu_clock) | ||
| 612 | current_cpu_data.cpu_clock = current_cpu_data.master_clock / ifc; | ||
| 613 | |||
| 614 | printk("CPU clock: %d.%02dMHz\n", | ||
| 615 | (current_cpu_data.cpu_clock / 1000000), | ||
| 616 | (current_cpu_data.cpu_clock % 1000000)/10000); | ||
| 617 | printk("Bus clock: %d.%02dMHz\n", | ||
| 618 | (current_cpu_data.bus_clock / 1000000), | ||
| 619 | (current_cpu_data.bus_clock % 1000000)/10000); | ||
| 620 | #ifdef CONFIG_CPU_SUBTYPE_ST40STB1 | ||
| 621 | printk("Memory clock: %d.%02dMHz\n", | ||
| 622 | (current_cpu_data.memory_clock / 1000000), | ||
| 623 | (current_cpu_data.memory_clock % 1000000)/10000); | ||
| 624 | #endif | ||
| 625 | printk("Module clock: %d.%02dMHz\n", | ||
| 626 | (current_cpu_data.module_clock / 1000000), | ||
| 627 | (current_cpu_data.module_clock % 1000000)/10000); | ||
| 628 | |||
| 629 | interval = (current_cpu_data.module_clock/4 + HZ/2) / HZ; | ||
| 630 | |||
| 631 | printk("Interval = %ld\n", interval); | ||
| 632 | |||
| 633 | /* Start TMU0 */ | ||
| 634 | ctrl_outb(0, TMU_TSTR); | ||
| 635 | #if !defined(CONFIG_CPU_SUBTYPE_SH7300) | ||
| 636 | ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); | ||
| 637 | #endif | ||
| 638 | ctrl_outw(TMU0_TCR_INIT, TMU0_TCR); | ||
| 639 | ctrl_outl(interval, TMU0_TCOR); | ||
| 640 | ctrl_outl(interval, TMU0_TCNT); | ||
| 641 | ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); | ||
| 642 | 188 | ||
| 643 | #if defined(CONFIG_SH_KGDB) | 189 | #if defined(CONFIG_SH_KGDB) |
| 644 | /* | 190 | /* |
diff --git a/arch/sh/kernel/timers/Makefile b/arch/sh/kernel/timers/Makefile new file mode 100644 index 000000000000..151a6a304cec --- /dev/null +++ b/arch/sh/kernel/timers/Makefile | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | # | ||
| 2 | # Makefile for the various Linux/SuperH timers | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-y := timer.o | ||
| 6 | |||
| 7 | obj-$(CONFIG_SH_TMU) += timer-tmu.o | ||
| 8 | |||
diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c new file mode 100644 index 000000000000..96a64cb13106 --- /dev/null +++ b/arch/sh/kernel/timers/timer-tmu.c | |||
| @@ -0,0 +1,229 @@ | |||
| 1 | /* | ||
| 2 | * arch/sh/kernel/timers/timer-tmu.c - TMU Timer Support | ||
| 3 | * | ||
| 4 | * Copyright (C) 2005 Paul Mundt | ||
| 5 | * | ||
| 6 | * TMU handling code hacked out of arch/sh/kernel/time.c | ||
| 7 | * | ||
| 8 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka | ||
| 9 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> | ||
| 10 | * Copyright (C) 2002, 2003, 2004 Paul Mundt | ||
| 11 | * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> | ||
| 12 | * | ||
| 13 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 14 | * License. See the file "COPYING" in the main directory of this archive | ||
| 15 | * for more details. | ||
| 16 | */ | ||
| 17 | #include <linux/init.h> | ||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/interrupt.h> | ||
| 20 | #include <linux/spinlock.h> | ||
| 21 | #include <linux/seqlock.h> | ||
| 22 | #include <asm/timer.h> | ||
| 23 | #include <asm/rtc.h> | ||
| 24 | #include <asm/io.h> | ||
| 25 | #include <asm/irq.h> | ||
| 26 | #include <asm/clock.h> | ||
| 27 | |||
| 28 | #define TMU_TOCR_INIT 0x00 | ||
| 29 | #define TMU0_TCR_INIT 0x0020 | ||
| 30 | #define TMU_TSTR_INIT 1 | ||
| 31 | |||
| 32 | #define TMU0_TCR_CALIB 0x0000 | ||
| 33 | |||
| 34 | static DEFINE_SPINLOCK(tmu0_lock); | ||
| 35 | |||
| 36 | static unsigned long tmu_timer_get_offset(void) | ||
| 37 | { | ||
| 38 | int count; | ||
| 39 | unsigned long flags; | ||
| 40 | |||
| 41 | static int count_p = 0x7fffffff; /* for the first call after boot */ | ||
| 42 | static unsigned long jiffies_p = 0; | ||
| 43 | |||
| 44 | /* | ||
| 45 | * cache volatile jiffies temporarily; we have IRQs turned off. | ||
| 46 | */ | ||
| 47 | unsigned long jiffies_t; | ||
| 48 | |||
| 49 | spin_lock_irqsave(&tmu0_lock, flags); | ||
| 50 | /* timer count may underflow right here */ | ||
| 51 | count = ctrl_inl(TMU0_TCNT); /* read the latched count */ | ||
| 52 | |||
| 53 | jiffies_t = jiffies; | ||
| 54 | |||
| 55 | /* | ||
| 56 | * avoiding timer inconsistencies (they are rare, but they happen)... | ||
| 57 | * there is one kind of problem that must be avoided here: | ||
| 58 | * 1. the timer counter underflows | ||
| 59 | */ | ||
| 60 | |||
| 61 | if (jiffies_t == jiffies_p) { | ||
| 62 | if (count > count_p) { | ||
| 63 | /* the nutcase */ | ||
| 64 | if (ctrl_inw(TMU0_TCR) & 0x100) { /* Check UNF bit */ | ||
| 65 | count -= LATCH; | ||
| 66 | } else { | ||
| 67 | printk("%s (): hardware timer problem?\n", | ||
| 68 | __FUNCTION__); | ||
| 69 | } | ||
| 70 | } | ||
| 71 | } else | ||
| 72 | jiffies_p = jiffies_t; | ||
| 73 | |||
| 74 | count_p = count; | ||
| 75 | spin_unlock_irqrestore(&tmu0_lock, flags); | ||
| 76 | |||
| 77 | count = ((LATCH-1) - count) * TICK_SIZE; | ||
| 78 | count = (count + LATCH/2) / LATCH; | ||
| 79 | |||
| 80 | return count; | ||
| 81 | } | ||
| 82 | |||
| 83 | static irqreturn_t tmu_timer_interrupt(int irq, void *dev_id, | ||
| 84 | struct pt_regs *regs) | ||
| 85 | { | ||
| 86 | unsigned long timer_status; | ||
| 87 | |||
| 88 | /* Clear UNF bit */ | ||
| 89 | timer_status = ctrl_inw(TMU0_TCR); | ||
| 90 | timer_status &= ~0x100; | ||
| 91 | ctrl_outw(timer_status, TMU0_TCR); | ||
| 92 | |||
| 93 | /* | ||
| 94 | * Here we are in the timer irq handler. We just have irqs locally | ||
| 95 | * disabled but we don't know if the timer_bh is running on the other | ||
| 96 | * CPU. We need to avoid to SMP race with it. NOTE: we don' t need | ||
| 97 | * the irq version of write_lock because as just said we have irq | ||
| 98 | * locally disabled. -arca | ||
| 99 | */ | ||
| 100 | write_seqlock(&xtime_lock); | ||
| 101 | handle_timer_tick(regs); | ||
| 102 | write_sequnlock(&xtime_lock); | ||
| 103 | |||
| 104 | return IRQ_HANDLED; | ||
| 105 | } | ||
| 106 | |||
| 107 | static struct irqaction tmu_irq = { | ||
| 108 | .name = "timer", | ||
| 109 | .handler = tmu_timer_interrupt, | ||
| 110 | .flags = SA_INTERRUPT, | ||
| 111 | .mask = CPU_MASK_NONE, | ||
| 112 | }; | ||
| 113 | |||
| 114 | /* | ||
| 115 | * Hah! We'll see if this works (switching from usecs to nsecs). | ||
| 116 | */ | ||
| 117 | static unsigned long tmu_timer_get_frequency(void) | ||
| 118 | { | ||
| 119 | u32 freq; | ||
| 120 | struct timespec ts1, ts2; | ||
| 121 | unsigned long diff_nsec; | ||
| 122 | unsigned long factor; | ||
| 123 | |||
| 124 | /* Setup the timer: We don't want to generate interrupts, just | ||
| 125 | * have it count down at its natural rate. | ||
| 126 | */ | ||
| 127 | ctrl_outb(0, TMU_TSTR); | ||
| 128 | #if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760) | ||
| 129 | ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); | ||
| 130 | #endif | ||
| 131 | ctrl_outw(TMU0_TCR_CALIB, TMU0_TCR); | ||
| 132 | ctrl_outl(0xffffffff, TMU0_TCOR); | ||
| 133 | ctrl_outl(0xffffffff, TMU0_TCNT); | ||
| 134 | |||
| 135 | rtc_get_time(&ts2); | ||
| 136 | |||
| 137 | do { | ||
| 138 | rtc_get_time(&ts1); | ||
| 139 | } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); | ||
| 140 | |||
| 141 | /* actually start the timer */ | ||
| 142 | ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); | ||
| 143 | |||
| 144 | do { | ||
| 145 | rtc_get_time(&ts2); | ||
| 146 | } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); | ||
| 147 | |||
| 148 | freq = 0xffffffff - ctrl_inl(TMU0_TCNT); | ||
| 149 | if (ts2.tv_nsec < ts1.tv_nsec) { | ||
| 150 | ts2.tv_nsec += 1000000000; | ||
| 151 | ts2.tv_sec--; | ||
| 152 | } | ||
| 153 | |||
| 154 | diff_nsec = (ts2.tv_sec - ts1.tv_sec) * 1000000000 + (ts2.tv_nsec - ts1.tv_nsec); | ||
| 155 | |||
| 156 | /* this should work well if the RTC has a precision of n Hz, where | ||
| 157 | * n is an integer. I don't think we have to worry about the other | ||
| 158 | * cases. */ | ||
| 159 | factor = (1000000000 + diff_nsec/2) / diff_nsec; | ||
| 160 | |||
| 161 | if (factor * diff_nsec > 1100000000 || | ||
| 162 | factor * diff_nsec < 900000000) | ||
| 163 | panic("weird RTC (diff_nsec %ld)", diff_nsec); | ||
| 164 | |||
| 165 | return freq * factor; | ||
| 166 | } | ||
| 167 | |||
| 168 | static void tmu_clk_init(struct clk *clk) | ||
| 169 | { | ||
| 170 | u8 divisor = TMU0_TCR_INIT & 0x7; | ||
| 171 | ctrl_outw(TMU0_TCR_INIT, TMU0_TCR); | ||
| 172 | clk->rate = clk->parent->rate / (4 << (divisor << 1)); | ||
| 173 | } | ||
| 174 | |||
| 175 | static void tmu_clk_recalc(struct clk *clk) | ||
| 176 | { | ||
| 177 | u8 divisor = ctrl_inw(TMU0_TCR) & 0x7; | ||
| 178 | clk->rate = clk->parent->rate / (4 << (divisor << 1)); | ||
| 179 | } | ||
| 180 | |||
| 181 | static struct clk_ops tmu_clk_ops = { | ||
| 182 | .init = tmu_clk_init, | ||
| 183 | .recalc = tmu_clk_recalc, | ||
| 184 | }; | ||
| 185 | |||
| 186 | static struct clk tmu0_clk = { | ||
| 187 | .name = "tmu0_clk", | ||
| 188 | .ops = &tmu_clk_ops, | ||
| 189 | }; | ||
| 190 | |||
| 191 | static int tmu_timer_init(void) | ||
| 192 | { | ||
| 193 | unsigned long interval; | ||
| 194 | |||
| 195 | setup_irq(TIMER_IRQ, &tmu_irq); | ||
| 196 | |||
| 197 | tmu0_clk.parent = clk_get("module_clk"); | ||
| 198 | |||
| 199 | /* Start TMU0 */ | ||
| 200 | ctrl_outb(0, TMU_TSTR); | ||
| 201 | #if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760) | ||
| 202 | ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); | ||
| 203 | #endif | ||
| 204 | |||
| 205 | clk_register(&tmu0_clk); | ||
| 206 | clk_enable(&tmu0_clk); | ||
| 207 | |||
| 208 | interval = (clk_get_rate(&tmu0_clk) + HZ / 2) / HZ; | ||
| 209 | printk(KERN_INFO "Interval = %ld\n", interval); | ||
| 210 | |||
| 211 | ctrl_outl(interval, TMU0_TCOR); | ||
| 212 | ctrl_outl(interval, TMU0_TCNT); | ||
| 213 | |||
| 214 | ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); | ||
| 215 | |||
| 216 | return 0; | ||
| 217 | } | ||
| 218 | |||
| 219 | struct sys_timer_ops tmu_timer_ops = { | ||
| 220 | .init = tmu_timer_init, | ||
| 221 | .get_frequency = tmu_timer_get_frequency, | ||
| 222 | .get_offset = tmu_timer_get_offset, | ||
| 223 | }; | ||
| 224 | |||
| 225 | struct sys_timer tmu_timer = { | ||
| 226 | .name = "tmu", | ||
| 227 | .ops = &tmu_timer_ops, | ||
| 228 | }; | ||
| 229 | |||
diff --git a/arch/sh/kernel/timers/timer.c b/arch/sh/kernel/timers/timer.c new file mode 100644 index 000000000000..dc1f631053a8 --- /dev/null +++ b/arch/sh/kernel/timers/timer.c | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | /* | ||
| 2 | * arch/sh/kernel/timers/timer.c - Common timer code | ||
| 3 | * | ||
| 4 | * Copyright (C) 2005 Paul Mundt | ||
| 5 | * | ||
| 6 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 7 | * License. See the file "COPYING" in the main directory of this archive | ||
| 8 | * for more details. | ||
| 9 | */ | ||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/timer.h> | ||
| 13 | #include <linux/string.h> | ||
| 14 | #include <asm/timer.h> | ||
| 15 | |||
| 16 | static struct sys_timer *sys_timers[] __initdata = { | ||
| 17 | #ifdef CONFIG_SH_TMU | ||
| 18 | &tmu_timer, | ||
| 19 | #endif | ||
| 20 | NULL, | ||
| 21 | }; | ||
| 22 | |||
| 23 | static char timer_override[10] __initdata; | ||
| 24 | static int __init timer_setup(char *str) | ||
| 25 | { | ||
| 26 | if (str) | ||
| 27 | strlcpy(timer_override, str, sizeof(timer_override)); | ||
| 28 | return 1; | ||
| 29 | } | ||
| 30 | __setup("timer=", timer_setup); | ||
| 31 | |||
| 32 | struct sys_timer *get_sys_timer(void) | ||
| 33 | { | ||
| 34 | int i; | ||
| 35 | |||
| 36 | for (i = 0; i < ARRAY_SIZE(sys_timers); i++) { | ||
| 37 | struct sys_timer *t = sys_timers[i]; | ||
| 38 | |||
| 39 | if (unlikely(!t)) | ||
| 40 | break; | ||
| 41 | if (unlikely(timer_override[0])) | ||
| 42 | if ((strcmp(timer_override, t->name) != 0)) | ||
| 43 | continue; | ||
| 44 | if (likely(t->ops->init() == 0)) | ||
| 45 | return t; | ||
| 46 | } | ||
| 47 | |||
| 48 | return NULL; | ||
| 49 | } | ||
| 50 | |||
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig new file mode 100644 index 000000000000..fb586b1cf8bb --- /dev/null +++ b/arch/sh/mm/Kconfig | |||
| @@ -0,0 +1,233 @@ | |||
| 1 | menu "Processor selection" | ||
| 2 | |||
| 3 | # | ||
| 4 | # Processor families | ||
| 5 | # | ||
| 6 | config CPU_SH2 | ||
| 7 | bool | ||
| 8 | select SH_WRITETHROUGH | ||
| 9 | |||
| 10 | config CPU_SH3 | ||
| 11 | bool | ||
| 12 | select CPU_HAS_INTEVT | ||
| 13 | select CPU_HAS_SR_RB | ||
| 14 | |||
| 15 | config CPU_SH4 | ||
| 16 | bool | ||
| 17 | select CPU_HAS_INTEVT | ||
| 18 | select CPU_HAS_SR_RB | ||
| 19 | |||
| 20 | config CPU_SH4A | ||
| 21 | bool | ||
| 22 | select CPU_SH4 | ||
| 23 | select CPU_HAS_INTC2_IRQ | ||
| 24 | |||
| 25 | config CPU_SUBTYPE_ST40 | ||
| 26 | bool | ||
| 27 | select CPU_SH4 | ||
| 28 | select CPU_HAS_INTC2_IRQ | ||
| 29 | |||
| 30 | # | ||
| 31 | # Processor subtypes | ||
| 32 | # | ||
| 33 | |||
| 34 | comment "SH-2 Processor Support" | ||
| 35 | |||
| 36 | config CPU_SUBTYPE_SH7604 | ||
| 37 | bool "Support SH7604 processor" | ||
| 38 | select CPU_SH2 | ||
| 39 | |||
| 40 | comment "SH-3 Processor Support" | ||
| 41 | |||
| 42 | config CPU_SUBTYPE_SH7300 | ||
| 43 | bool "Support SH7300 processor" | ||
| 44 | select CPU_SH3 | ||
| 45 | |||
| 46 | config CPU_SUBTYPE_SH7705 | ||
| 47 | bool "Support SH7705 processor" | ||
| 48 | select CPU_SH3 | ||
| 49 | select CPU_HAS_PINT_IRQ | ||
| 50 | |||
| 51 | config CPU_SUBTYPE_SH7707 | ||
| 52 | bool "Support SH7707 processor" | ||
| 53 | select CPU_SH3 | ||
| 54 | select CPU_HAS_PINT_IRQ | ||
| 55 | help | ||
| 56 | Select SH7707 if you have a 60 Mhz SH-3 HD6417707 CPU. | ||
| 57 | |||
| 58 | config CPU_SUBTYPE_SH7708 | ||
| 59 | bool "Support SH7708 processor" | ||
| 60 | select CPU_SH3 | ||
| 61 | help | ||
| 62 | Select SH7708 if you have a 60 Mhz SH-3 HD6417708S or | ||
| 63 | if you have a 100 Mhz SH-3 HD6417708R CPU. | ||
| 64 | |||
| 65 | config CPU_SUBTYPE_SH7709 | ||
| 66 | bool "Support SH7709 processor" | ||
| 67 | select CPU_SH3 | ||
| 68 | select CPU_HAS_PINT_IRQ | ||
| 69 | help | ||
| 70 | Select SH7709 if you have a 80 Mhz SH-3 HD6417709 CPU. | ||
| 71 | |||
| 72 | comment "SH-4 Processor Support" | ||
| 73 | |||
| 74 | config CPU_SUBTYPE_SH7750 | ||
| 75 | bool "Support SH7750 processor" | ||
| 76 | select CPU_SH4 | ||
| 77 | help | ||
| 78 | Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU. | ||
| 79 | |||
| 80 | config CPU_SUBTYPE_SH7091 | ||
| 81 | bool "Support SH7091 processor" | ||
| 82 | select CPU_SH4 | ||
| 83 | select CPU_SUBTYPE_SH7750 | ||
| 84 | help | ||
| 85 | Select SH7091 if you have an SH-4 based Sega device (such as | ||
| 86 | the Dreamcast, Naomi, and Naomi 2). | ||
| 87 | |||
| 88 | config CPU_SUBTYPE_SH7750R | ||
| 89 | bool "Support SH7750R processor" | ||
| 90 | select CPU_SH4 | ||
| 91 | select CPU_SUBTYPE_SH7750 | ||
| 92 | |||
| 93 | config CPU_SUBTYPE_SH7750S | ||
| 94 | bool "Support SH7750S processor" | ||
| 95 | select CPU_SH4 | ||
| 96 | select CPU_SUBTYPE_SH7750 | ||
| 97 | |||
| 98 | config CPU_SUBTYPE_SH7751 | ||
| 99 | bool "Support SH7751 processor" | ||
| 100 | select CPU_SH4 | ||
| 101 | help | ||
| 102 | Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU, | ||
| 103 | or if you have a HD6417751R CPU. | ||
| 104 | |||
| 105 | config CPU_SUBTYPE_SH7751R | ||
| 106 | bool "Support SH7751R processor" | ||
| 107 | select CPU_SH4 | ||
| 108 | select CPU_SUBTYPE_SH7751 | ||
| 109 | |||
| 110 | config CPU_SUBTYPE_SH7760 | ||
| 111 | bool "Support SH7760 processor" | ||
| 112 | select CPU_SH4 | ||
| 113 | select CPU_HAS_INTC2_IRQ | ||
| 114 | |||
| 115 | config CPU_SUBTYPE_SH4_202 | ||
| 116 | bool "Support SH4-202 processor" | ||
| 117 | select CPU_SH4 | ||
| 118 | |||
| 119 | comment "ST40 Processor Support" | ||
| 120 | |||
| 121 | config CPU_SUBTYPE_ST40STB1 | ||
| 122 | bool "Support ST40STB1/ST40RA processors" | ||
| 123 | select CPU_SUBTYPE_ST40 | ||
| 124 | help | ||
| 125 | Select ST40STB1 if you have a ST40RA CPU. | ||
| 126 | This was previously called the ST40STB1, hence the option name. | ||
| 127 | |||
| 128 | config CPU_SUBTYPE_ST40GX1 | ||
| 129 | bool "Support ST40GX1 processor" | ||
| 130 | select CPU_SUBTYPE_ST40 | ||
| 131 | help | ||
| 132 | Select ST40GX1 if you have a ST40GX1 CPU. | ||
| 133 | |||
| 134 | comment "SH-4A Processor Support" | ||
| 135 | |||
| 136 | config CPU_SUBTYPE_SH73180 | ||
| 137 | bool "Support SH73180 processor" | ||
| 138 | select CPU_SH4A | ||
| 139 | |||
| 140 | config CPU_SUBTYPE_SH7770 | ||
| 141 | bool "Support SH7770 processor" | ||
| 142 | select CPU_SH4A | ||
| 143 | |||
| 144 | config CPU_SUBTYPE_SH7780 | ||
| 145 | bool "Support SH7780 processor" | ||
| 146 | select CPU_SH4A | ||
| 147 | |||
| 148 | endmenu | ||
| 149 | |||
| 150 | menu "Memory management options" | ||
| 151 | |||
| 152 | config MMU | ||
| 153 | bool "Support for memory management hardware" | ||
| 154 | depends on !CPU_SH2 | ||
| 155 | default y | ||
| 156 | help | ||
| 157 | Some SH processors (such as SH-2/SH-2A) lack an MMU. In order to | ||
| 158 | boot on these systems, this option must not be set. | ||
| 159 | |||
| 160 | On other systems (such as the SH-3 and 4) where an MMU exists, | ||
| 161 | turning this off will boot the kernel on these machines with the | ||
| 162 | MMU implicitly switched off. | ||
| 163 | |||
| 164 | config 32BIT | ||
| 165 | bool "Support 32-bit physical addressing through PMB" | ||
| 166 | depends on CPU_SH4A | ||
| 167 | default y | ||
| 168 | help | ||
| 169 | If you say Y here, physical addressing will be extended to | ||
| 170 | 32-bits through the SH-4A PMB. If this is not set, legacy | ||
| 171 | 29-bit physical addressing will be used. | ||
| 172 | |||
| 173 | choice | ||
| 174 | prompt "HugeTLB page size" | ||
| 175 | depends on HUGETLB_PAGE && CPU_SH4 && MMU | ||
| 176 | default HUGETLB_PAGE_SIZE_64K | ||
| 177 | |||
| 178 | config HUGETLB_PAGE_SIZE_64K | ||
| 179 | bool "64K" | ||
| 180 | |||
| 181 | config HUGETLB_PAGE_SIZE_1MB | ||
| 182 | bool "1MB" | ||
| 183 | |||
| 184 | endchoice | ||
| 185 | |||
| 186 | source "mm/Kconfig" | ||
| 187 | |||
| 188 | endmenu | ||
| 189 | |||
| 190 | menu "Cache configuration" | ||
| 191 | |||
| 192 | config SH7705_CACHE_32KB | ||
| 193 | bool "Enable 32KB cache size for SH7705" | ||
| 194 | depends on CPU_SUBTYPE_SH7705 | ||
| 195 | default y | ||
| 196 | |||
| 197 | config SH_DIRECT_MAPPED | ||
| 198 | bool "Use direct-mapped caching" | ||
| 199 | default n | ||
| 200 | help | ||
| 201 | Selecting this option will configure the caches to be direct-mapped, | ||
| 202 | even if the cache supports a 2 or 4-way mode. This is useful primarily | ||
| 203 | for debugging on platforms with 2 and 4-way caches (SH7750R/SH7751R, | ||
| 204 | SH4-202, SH4-501, etc.) | ||
| 205 | |||
| 206 | Turn this option off for platforms that do not have a direct-mapped | ||
| 207 | cache, and you have no need to run the caches in such a configuration. | ||
| 208 | |||
| 209 | config SH_WRITETHROUGH | ||
| 210 | bool "Use write-through caching" | ||
| 211 | default y if CPU_SH2 | ||
| 212 | help | ||
| 213 | Selecting this option will configure the caches in write-through | ||
| 214 | mode, as opposed to the default write-back configuration. | ||
| 215 | |||
| 216 | Since there's sill some aliasing issues on SH-4, this option will | ||
| 217 | unfortunately still require the majority of flushing functions to | ||
| 218 | be implemented to deal with aliasing. | ||
| 219 | |||
| 220 | If unsure, say N. | ||
| 221 | |||
| 222 | config SH_OCRAM | ||
| 223 | bool "Operand Cache RAM (OCRAM) support" | ||
| 224 | help | ||
| 225 | Selecting this option will automatically tear down the number of | ||
| 226 | sets in the dcache by half, which in turn exposes a memory range. | ||
| 227 | |||
| 228 | The addresses for the OC RAM base will vary according to the | ||
| 229 | processor version. Consult vendor documentation for specifics. | ||
| 230 | |||
| 231 | If unsure, say N. | ||
| 232 | |||
| 233 | endmenu | ||
diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c index e794e27a72f1..96fa4a999e2a 100644 --- a/arch/sh/mm/ioremap.c +++ b/arch/sh/mm/ioremap.c | |||
| @@ -6,13 +6,19 @@ | |||
| 6 | * 640k-1MB IO memory area on PC's | 6 | * 640k-1MB IO memory area on PC's |
| 7 | * | 7 | * |
| 8 | * (C) Copyright 1995 1996 Linus Torvalds | 8 | * (C) Copyright 1995 1996 Linus Torvalds |
| 9 | * (C) Copyright 2005, 2006 Paul Mundt | ||
| 10 | * | ||
| 11 | * This file is subject to the terms and conditions of the GNU General | ||
| 12 | * Public License. See the file "COPYING" in the main directory of this | ||
| 13 | * archive for more details. | ||
| 9 | */ | 14 | */ |
| 10 | |||
| 11 | #include <linux/vmalloc.h> | 15 | #include <linux/vmalloc.h> |
| 16 | #include <linux/module.h> | ||
| 12 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
| 13 | #include <asm/io.h> | 18 | #include <asm/io.h> |
| 14 | #include <asm/page.h> | 19 | #include <asm/page.h> |
| 15 | #include <asm/pgalloc.h> | 20 | #include <asm/pgalloc.h> |
| 21 | #include <asm/addrspace.h> | ||
| 16 | #include <asm/cacheflush.h> | 22 | #include <asm/cacheflush.h> |
| 17 | #include <asm/tlbflush.h> | 23 | #include <asm/tlbflush.h> |
| 18 | 24 | ||
| @@ -80,9 +86,15 @@ int remap_area_pages(unsigned long address, unsigned long phys_addr, | |||
| 80 | if (address >= end) | 86 | if (address >= end) |
| 81 | BUG(); | 87 | BUG(); |
| 82 | do { | 88 | do { |
| 89 | pud_t *pud; | ||
| 83 | pmd_t *pmd; | 90 | pmd_t *pmd; |
| 84 | pmd = pmd_alloc(&init_mm, dir, address); | 91 | |
| 85 | error = -ENOMEM; | 92 | error = -ENOMEM; |
| 93 | |||
| 94 | pud = pud_alloc(&init_mm, dir, address); | ||
| 95 | if (!pud) | ||
| 96 | break; | ||
| 97 | pmd = pmd_alloc(&init_mm, pud, address); | ||
| 86 | if (!pmd) | 98 | if (!pmd) |
| 87 | break; | 99 | break; |
| 88 | if (remap_area_pmd(pmd, address, end - address, | 100 | if (remap_area_pmd(pmd, address, end - address, |
| @@ -97,10 +109,6 @@ int remap_area_pages(unsigned long address, unsigned long phys_addr, | |||
| 97 | } | 109 | } |
| 98 | 110 | ||
| 99 | /* | 111 | /* |
| 100 | * Generic mapping function (not visible outside): | ||
| 101 | */ | ||
| 102 | |||
| 103 | /* | ||
| 104 | * Remap an arbitrary physical address space into the kernel virtual | 112 | * Remap an arbitrary physical address space into the kernel virtual |
| 105 | * address space. Needed when the kernel wants to access high addresses | 113 | * address space. Needed when the kernel wants to access high addresses |
| 106 | * directly. | 114 | * directly. |
| @@ -109,11 +117,11 @@ int remap_area_pages(unsigned long address, unsigned long phys_addr, | |||
| 109 | * have to convert them into an offset in a page-aligned mapping, but the | 117 | * have to convert them into an offset in a page-aligned mapping, but the |
| 110 | * caller shouldn't need to know that small detail. | 118 | * caller shouldn't need to know that small detail. |
| 111 | */ | 119 | */ |
| 112 | void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) | 120 | void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, |
| 121 | unsigned long flags) | ||
| 113 | { | 122 | { |
| 114 | void * addr; | ||
| 115 | struct vm_struct * area; | 123 | struct vm_struct * area; |
| 116 | unsigned long offset, last_addr; | 124 | unsigned long offset, last_addr, addr, orig_addr; |
| 117 | 125 | ||
| 118 | /* Don't allow wraparound or zero size */ | 126 | /* Don't allow wraparound or zero size */ |
| 119 | last_addr = phys_addr + size - 1; | 127 | last_addr = phys_addr + size - 1; |
| @@ -124,7 +132,7 @@ void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long fla | |||
| 124 | * Don't remap the low PCI/ISA area, it's always mapped.. | 132 | * Don't remap the low PCI/ISA area, it's always mapped.. |
| 125 | */ | 133 | */ |
| 126 | if (phys_addr >= 0xA0000 && last_addr < 0x100000) | 134 | if (phys_addr >= 0xA0000 && last_addr < 0x100000) |
| 127 | return phys_to_virt(phys_addr); | 135 | return (void __iomem *)phys_to_virt(phys_addr); |
| 128 | 136 | ||
| 129 | /* | 137 | /* |
| 130 | * Don't allow anybody to remap normal RAM that we're using.. | 138 | * Don't allow anybody to remap normal RAM that we're using.. |
| @@ -146,16 +154,71 @@ void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long fla | |||
| 146 | if (!area) | 154 | if (!area) |
| 147 | return NULL; | 155 | return NULL; |
| 148 | area->phys_addr = phys_addr; | 156 | area->phys_addr = phys_addr; |
| 149 | addr = area->addr; | 157 | orig_addr = addr = (unsigned long)area->addr; |
| 150 | if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) { | 158 | |
| 151 | vunmap(addr); | 159 | #ifdef CONFIG_32BIT |
| 152 | return NULL; | 160 | /* |
| 161 | * First try to remap through the PMB once a valid VMA has been | ||
| 162 | * established. Smaller allocations (or the rest of the size | ||
| 163 | * remaining after a PMB mapping due to the size not being | ||
| 164 | * perfectly aligned on a PMB size boundary) are then mapped | ||
| 165 | * through the UTLB using conventional page tables. | ||
| 166 | * | ||
| 167 | * PMB entries are all pre-faulted. | ||
| 168 | */ | ||
| 169 | if (unlikely(size >= 0x1000000)) { | ||
| 170 | unsigned long mapped = pmb_remap(addr, phys_addr, size, flags); | ||
| 171 | |||
| 172 | if (likely(mapped)) { | ||
| 173 | addr += mapped; | ||
| 174 | phys_addr += mapped; | ||
| 175 | size -= mapped; | ||
| 176 | } | ||
| 153 | } | 177 | } |
| 154 | return (void *) (offset + (char *)addr); | 178 | #endif |
| 179 | |||
| 180 | if (likely(size)) | ||
| 181 | if (remap_area_pages(addr, phys_addr, size, flags)) { | ||
| 182 | vunmap((void *)orig_addr); | ||
| 183 | return NULL; | ||
| 184 | } | ||
| 185 | |||
| 186 | return (void __iomem *)(offset + (char *)orig_addr); | ||
| 155 | } | 187 | } |
| 188 | EXPORT_SYMBOL(__ioremap); | ||
| 156 | 189 | ||
| 157 | void p3_iounmap(void *addr) | 190 | void __iounmap(void __iomem *addr) |
| 158 | { | 191 | { |
| 159 | if (addr > high_memory) | 192 | unsigned long vaddr = (unsigned long __force)addr; |
| 160 | vfree((void *)(PAGE_MASK & (unsigned long)addr)); | 193 | struct vm_struct *p; |
| 194 | |||
| 195 | if (PXSEG(vaddr) < P3SEG) | ||
| 196 | return; | ||
| 197 | |||
| 198 | #ifdef CONFIG_32BIT | ||
| 199 | /* | ||
| 200 | * Purge any PMB entries that may have been established for this | ||
| 201 | * mapping, then proceed with conventional VMA teardown. | ||
| 202 | * | ||
| 203 | * XXX: Note that due to the way that remove_vm_area() does | ||
| 204 | * matching of the resultant VMA, we aren't able to fast-forward | ||
| 205 | * the address past the PMB space until the end of the VMA where | ||
| 206 | * the page tables reside. As such, unmap_vm_area() will be | ||
| 207 | * forced to linearly scan over the area until it finds the page | ||
| 208 | * tables where PTEs that need to be unmapped actually reside, | ||
| 209 | * which is far from optimal. Perhaps we need to use a separate | ||
| 210 | * VMA for the PMB mappings? | ||
| 211 | * -- PFM. | ||
| 212 | */ | ||
| 213 | pmb_unmap(vaddr); | ||
| 214 | #endif | ||
| 215 | |||
| 216 | p = remove_vm_area((void *)(vaddr & PAGE_MASK)); | ||
| 217 | if (!p) { | ||
| 218 | printk(KERN_ERR "%s: bad address %p\n", __FUNCTION__, addr); | ||
| 219 | return; | ||
| 220 | } | ||
| 221 | |||
| 222 | kfree(p); | ||
| 161 | } | 223 | } |
| 224 | EXPORT_SYMBOL(__iounmap); | ||
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types index 0693fbd1f956..182fe9092577 100644 --- a/arch/sh/tools/mach-types +++ b/arch/sh/tools/mach-types | |||
| @@ -10,10 +10,7 @@ SE SH_SOLUTION_ENGINE | |||
| 10 | 7300SE SH_7300_SOLUTION_ENGINE | 10 | 7300SE SH_7300_SOLUTION_ENGINE |
| 11 | 73180SE SH_73180_SOLUTION_ENGINE | 11 | 73180SE SH_73180_SOLUTION_ENGINE |
| 12 | 7751SYSTEMH SH_7751_SYSTEMH | 12 | 7751SYSTEMH SH_7751_SYSTEMH |
| 13 | HP600 SH_HP600 | 13 | HP6XX SH_HP6XX |
| 14 | HP620 SH_HP620 | ||
| 15 | HP680 SH_HP680 | ||
| 16 | HP690 SH_HP690 | ||
| 17 | HD64461 HD64461 | 14 | HD64461 HD64461 |
| 18 | HD64465 HD64465 | 15 | HD64465 HD64465 |
| 19 | SH2000 SH_SH2000 | 16 | SH2000 SH_SH2000 |
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c index 489bf68d5f05..77840c804786 100644 --- a/arch/sparc/mm/iommu.c +++ b/arch/sparc/mm/iommu.c | |||
| @@ -295,8 +295,7 @@ static void iommu_release_one(u32 busa, int npages, struct sbus_bus *sbus) | |||
| 295 | int ioptex; | 295 | int ioptex; |
| 296 | int i; | 296 | int i; |
| 297 | 297 | ||
| 298 | if (busa < iommu->start) | 298 | BUG_ON(busa < iommu->start); |
| 299 | BUG(); | ||
| 300 | ioptex = (busa - iommu->start) >> PAGE_SHIFT; | 299 | ioptex = (busa - iommu->start) >> PAGE_SHIFT; |
| 301 | for (i = 0; i < npages; i++) { | 300 | for (i = 0; i < npages; i++) { |
| 302 | iopte_val(iommu->page_table[ioptex + i]) = 0; | 301 | iopte_val(iommu->page_table[ioptex + i]) = 0; |
| @@ -340,9 +339,9 @@ static int iommu_map_dma_area(dma_addr_t *pba, unsigned long va, | |||
| 340 | iopte_t *first; | 339 | iopte_t *first; |
| 341 | int ioptex; | 340 | int ioptex; |
| 342 | 341 | ||
| 343 | if ((va & ~PAGE_MASK) != 0) BUG(); | 342 | BUG_ON((va & ~PAGE_MASK) != 0); |
| 344 | if ((addr & ~PAGE_MASK) != 0) BUG(); | 343 | BUG_ON((addr & ~PAGE_MASK) != 0); |
| 345 | if ((len & ~PAGE_MASK) != 0) BUG(); | 344 | BUG_ON((len & ~PAGE_MASK) != 0); |
| 346 | 345 | ||
| 347 | /* page color = physical address */ | 346 | /* page color = physical address */ |
| 348 | ioptex = bit_map_string_get(&iommu->usemap, len >> PAGE_SHIFT, | 347 | ioptex = bit_map_string_get(&iommu->usemap, len >> PAGE_SHIFT, |
| @@ -405,8 +404,8 @@ static void iommu_unmap_dma_area(unsigned long busa, int len) | |||
| 405 | unsigned long end; | 404 | unsigned long end; |
| 406 | int ioptex = (busa - iommu->start) >> PAGE_SHIFT; | 405 | int ioptex = (busa - iommu->start) >> PAGE_SHIFT; |
| 407 | 406 | ||
| 408 | if ((busa & ~PAGE_MASK) != 0) BUG(); | 407 | BUG_ON((busa & ~PAGE_MASK) != 0); |
| 409 | if ((len & ~PAGE_MASK) != 0) BUG(); | 408 | BUG_ON((len & ~PAGE_MASK) != 0); |
| 410 | 409 | ||
| 411 | iopte += ioptex; | 410 | iopte += ioptex; |
| 412 | end = busa + len; | 411 | end = busa + len; |
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 459c8fbe02b4..a22930d62adf 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c | |||
| @@ -280,9 +280,9 @@ static struct sparc64_tick_ops stick_operations __read_mostly = { | |||
| 280 | * Since STICK is constantly updating, we have to access it carefully. | 280 | * Since STICK is constantly updating, we have to access it carefully. |
| 281 | * | 281 | * |
| 282 | * The sequence we use to read is: | 282 | * The sequence we use to read is: |
| 283 | * 1) read low | 283 | * 1) read high |
| 284 | * 2) read high | 284 | * 2) read low |
| 285 | * 3) read low again, if it rolled over increment high by 1 | 285 | * 3) read high again, if it rolled re-read both low and high again. |
| 286 | * | 286 | * |
| 287 | * Writing STICK safely is also tricky: | 287 | * Writing STICK safely is also tricky: |
| 288 | * 1) write low to zero | 288 | * 1) write low to zero |
| @@ -295,18 +295,18 @@ static struct sparc64_tick_ops stick_operations __read_mostly = { | |||
| 295 | static unsigned long __hbird_read_stick(void) | 295 | static unsigned long __hbird_read_stick(void) |
| 296 | { | 296 | { |
| 297 | unsigned long ret, tmp1, tmp2, tmp3; | 297 | unsigned long ret, tmp1, tmp2, tmp3; |
| 298 | unsigned long addr = HBIRD_STICK_ADDR; | 298 | unsigned long addr = HBIRD_STICK_ADDR+8; |
| 299 | 299 | ||
| 300 | __asm__ __volatile__("ldxa [%1] %5, %2\n\t" | 300 | __asm__ __volatile__("ldxa [%1] %5, %2\n" |
| 301 | "add %1, 0x8, %1\n\t" | 301 | "1:\n\t" |
| 302 | "ldxa [%1] %5, %3\n\t" | ||
| 303 | "sub %1, 0x8, %1\n\t" | 302 | "sub %1, 0x8, %1\n\t" |
| 303 | "ldxa [%1] %5, %3\n\t" | ||
| 304 | "add %1, 0x8, %1\n\t" | ||
| 304 | "ldxa [%1] %5, %4\n\t" | 305 | "ldxa [%1] %5, %4\n\t" |
| 305 | "cmp %4, %2\n\t" | 306 | "cmp %4, %2\n\t" |
| 306 | "blu,a,pn %%xcc, 1f\n\t" | 307 | "bne,a,pn %%xcc, 1b\n\t" |
| 307 | " add %3, 1, %3\n" | 308 | " mov %4, %2\n\t" |
| 308 | "1:\n\t" | 309 | "sllx %4, 32, %4\n\t" |
| 309 | "sllx %3, 32, %3\n\t" | ||
| 310 | "or %3, %4, %0\n\t" | 310 | "or %3, %4, %0\n\t" |
| 311 | : "=&r" (ret), "=&r" (addr), | 311 | : "=&r" (ret), "=&r" (addr), |
| 312 | "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3) | 312 | "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3) |
diff --git a/arch/um/Makefile b/arch/um/Makefile index 322972fd064e..45435ff589c1 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile | |||
| @@ -67,7 +67,8 @@ USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \ | |||
| 67 | # in CFLAGS. Otherwise, it would cause ld to complain about the two different | 67 | # in CFLAGS. Otherwise, it would cause ld to complain about the two different |
| 68 | # errnos. | 68 | # errnos. |
| 69 | 69 | ||
| 70 | CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask | 70 | CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \ |
| 71 | -Dmktime=kernel_mktime | ||
| 71 | CFLAGS += $(call cc-option,-fno-unit-at-a-time,) | 72 | CFLAGS += $(call cc-option,-fno-unit-at-a-time,) |
| 72 | 73 | ||
| 73 | include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) | 74 | include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) |
diff --git a/arch/um/include/sysdep-i386/checksum.h b/arch/um/include/sysdep-i386/checksum.h index 764ba4db4788..7d3d202d7fff 100644 --- a/arch/um/include/sysdep-i386/checksum.h +++ b/arch/um/include/sysdep-i386/checksum.h | |||
| @@ -36,7 +36,7 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char * | |||
| 36 | int len, int sum) | 36 | int len, int sum) |
| 37 | { | 37 | { |
| 38 | memcpy(dst, src, len); | 38 | memcpy(dst, src, len); |
| 39 | return(csum_partial(dst, len, sum)); | 39 | return csum_partial(dst, len, sum); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | /* | 42 | /* |
| @@ -104,7 +104,7 @@ static inline unsigned short ip_fast_csum(unsigned char * iph, | |||
| 104 | : "=r" (sum), "=r" (iph), "=r" (ihl) | 104 | : "=r" (sum), "=r" (iph), "=r" (ihl) |
| 105 | : "1" (iph), "2" (ihl) | 105 | : "1" (iph), "2" (ihl) |
| 106 | : "memory"); | 106 | : "memory"); |
| 107 | return(sum); | 107 | return sum; |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | /* | 110 | /* |
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 2efc4be22709..2f9deca31cc9 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig | |||
| @@ -305,7 +305,11 @@ config ARCH_DISCONTIGMEM_DEFAULT | |||
| 305 | 305 | ||
| 306 | config ARCH_SPARSEMEM_ENABLE | 306 | config ARCH_SPARSEMEM_ENABLE |
| 307 | def_bool y | 307 | def_bool y |
| 308 | depends on NUMA | 308 | depends on (NUMA || EXPERIMENTAL) |
| 309 | |||
| 310 | config ARCH_MEMORY_PROBE | ||
| 311 | def_bool y | ||
| 312 | depends on MEMORY_HOTPLUG | ||
| 309 | 313 | ||
| 310 | config ARCH_FLATMEM_ENABLE | 314 | config ARCH_FLATMEM_ENABLE |
| 311 | def_bool y | 315 | def_bool y |
| @@ -315,6 +319,7 @@ source "mm/Kconfig" | |||
| 315 | 319 | ||
| 316 | config HAVE_ARCH_EARLY_PFN_TO_NID | 320 | config HAVE_ARCH_EARLY_PFN_TO_NID |
| 317 | def_bool y | 321 | def_bool y |
| 322 | depends on NUMA | ||
| 318 | 323 | ||
| 319 | config NR_CPUS | 324 | config NR_CPUS |
| 320 | int "Maximum number of CPUs (2-256)" | 325 | int "Maximum number of CPUs (2-256)" |
| @@ -350,7 +355,7 @@ config HPET_TIMER | |||
| 350 | <http://www.intel.com/hardwaredesign/hpetspec.htm>. | 355 | <http://www.intel.com/hardwaredesign/hpetspec.htm>. |
| 351 | 356 | ||
| 352 | config X86_PM_TIMER | 357 | config X86_PM_TIMER |
| 353 | bool "PM timer" | 358 | bool "PM timer" if EMBEDDED |
| 354 | depends on ACPI | 359 | depends on ACPI |
| 355 | default y | 360 | default y |
| 356 | help | 361 | help |
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig index 054dcd8a5e9d..5231fe83ea4b 100644 --- a/arch/x86_64/defconfig +++ b/arch/x86_64/defconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | # | 1 | # |
| 2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
| 3 | # Linux kernel version: 2.6.15-git7 | 3 | # Linux kernel version: 2.6.15-git12 |
| 4 | # Wed Jan 11 11:57:36 2006 | 4 | # Mon Jan 16 13:09:08 2006 |
| 5 | # | 5 | # |
| 6 | CONFIG_X86_64=y | 6 | CONFIG_X86_64=y |
| 7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
| @@ -319,6 +319,11 @@ CONFIG_IPV6=y | |||
| 319 | # CONFIG_ATALK is not set | 319 | # CONFIG_ATALK is not set |
| 320 | # CONFIG_X25 is not set | 320 | # CONFIG_X25 is not set |
| 321 | # CONFIG_LAPB is not set | 321 | # CONFIG_LAPB is not set |
| 322 | |||
| 323 | # | ||
| 324 | # TIPC Configuration (EXPERIMENTAL) | ||
| 325 | # | ||
| 326 | # CONFIG_TIPC is not set | ||
| 322 | # CONFIG_NET_DIVERT is not set | 327 | # CONFIG_NET_DIVERT is not set |
| 323 | # CONFIG_ECONET is not set | 328 | # CONFIG_ECONET is not set |
| 324 | # CONFIG_WAN_ROUTER is not set | 329 | # CONFIG_WAN_ROUTER is not set |
| @@ -537,8 +542,7 @@ CONFIG_SCSI_SATA_INTEL_COMBINED=y | |||
| 537 | # CONFIG_SCSI_IPR is not set | 542 | # CONFIG_SCSI_IPR is not set |
| 538 | # CONFIG_SCSI_QLOGIC_FC is not set | 543 | # CONFIG_SCSI_QLOGIC_FC is not set |
| 539 | # CONFIG_SCSI_QLOGIC_1280 is not set | 544 | # CONFIG_SCSI_QLOGIC_1280 is not set |
| 540 | CONFIG_SCSI_QLA2XXX=y | 545 | # CONFIG_SCSI_QLA_FC is not set |
| 541 | # CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE is not set | ||
| 542 | # CONFIG_SCSI_LPFC is not set | 546 | # CONFIG_SCSI_LPFC is not set |
| 543 | # CONFIG_SCSI_DC395x is not set | 547 | # CONFIG_SCSI_DC395x is not set |
| 544 | # CONFIG_SCSI_DC390T is not set | 548 | # CONFIG_SCSI_DC390T is not set |
| @@ -805,6 +809,7 @@ CONFIG_SOFT_WATCHDOG=y | |||
| 805 | # CONFIG_W83877F_WDT is not set | 809 | # CONFIG_W83877F_WDT is not set |
| 806 | # CONFIG_W83977F_WDT is not set | 810 | # CONFIG_W83977F_WDT is not set |
| 807 | # CONFIG_MACHZ_WDT is not set | 811 | # CONFIG_MACHZ_WDT is not set |
| 812 | # CONFIG_SBC_EPX_C3_WATCHDOG is not set | ||
| 808 | 813 | ||
| 809 | # | 814 | # |
| 810 | # PCI-based Watchdog Cards | 815 | # PCI-based Watchdog Cards |
| @@ -850,6 +855,12 @@ CONFIG_HPET_MMAP=y | |||
| 850 | # CONFIG_I2C is not set | 855 | # CONFIG_I2C is not set |
| 851 | 856 | ||
| 852 | # | 857 | # |
| 858 | # SPI support | ||
| 859 | # | ||
| 860 | # CONFIG_SPI is not set | ||
| 861 | # CONFIG_SPI_MASTER is not set | ||
| 862 | |||
| 863 | # | ||
| 853 | # Dallas's 1-wire bus | 864 | # Dallas's 1-wire bus |
| 854 | # | 865 | # |
| 855 | # CONFIG_W1 is not set | 866 | # CONFIG_W1 is not set |
| @@ -992,6 +1003,7 @@ CONFIG_USB_STORAGE=y | |||
| 992 | # | 1003 | # |
| 993 | CONFIG_USB_HID=y | 1004 | CONFIG_USB_HID=y |
| 994 | CONFIG_USB_HIDINPUT=y | 1005 | CONFIG_USB_HIDINPUT=y |
| 1006 | # CONFIG_USB_HIDINPUT_POWERBOOK is not set | ||
| 995 | # CONFIG_HID_FF is not set | 1007 | # CONFIG_HID_FF is not set |
| 996 | # CONFIG_USB_HIDDEV is not set | 1008 | # CONFIG_USB_HIDDEV is not set |
| 997 | # CONFIG_USB_AIPTEK is not set | 1009 | # CONFIG_USB_AIPTEK is not set |
| @@ -1276,6 +1288,7 @@ CONFIG_DETECT_SOFTLOCKUP=y | |||
| 1276 | CONFIG_DEBUG_FS=y | 1288 | CONFIG_DEBUG_FS=y |
| 1277 | # CONFIG_DEBUG_VM is not set | 1289 | # CONFIG_DEBUG_VM is not set |
| 1278 | # CONFIG_FRAME_POINTER is not set | 1290 | # CONFIG_FRAME_POINTER is not set |
| 1291 | # CONFIG_FORCED_INLINING is not set | ||
| 1279 | # CONFIG_RCU_TORTURE_TEST is not set | 1292 | # CONFIG_RCU_TORTURE_TEST is not set |
| 1280 | CONFIG_INIT_DEBUG=y | 1293 | CONFIG_INIT_DEBUG=y |
| 1281 | # CONFIG_DEBUG_RODATA is not set | 1294 | # CONFIG_DEBUG_RODATA is not set |
diff --git a/arch/x86_64/ia32/Makefile b/arch/x86_64/ia32/Makefile index 051608d55920..929e6b0771f8 100644 --- a/arch/x86_64/ia32/Makefile +++ b/arch/x86_64/ia32/Makefile | |||
| @@ -3,7 +3,8 @@ | |||
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_signal.o tls32.o \ | 5 | obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_signal.o tls32.o \ |
| 6 | ia32_binfmt.o fpu32.o ptrace32.o syscall32.o syscall32_syscall.o | 6 | ia32_binfmt.o fpu32.o ptrace32.o syscall32.o syscall32_syscall.o \ |
| 7 | mmap32.o | ||
| 7 | 8 | ||
| 8 | sysv-$(CONFIG_SYSVIPC) := ipc32.o | 9 | sysv-$(CONFIG_SYSVIPC) := ipc32.o |
| 9 | obj-$(CONFIG_IA32_EMULATION) += $(sysv-y) | 10 | obj-$(CONFIG_IA32_EMULATION) += $(sysv-y) |
diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c index 029bddab0459..572b3b28772d 100644 --- a/arch/x86_64/ia32/ia32_binfmt.c +++ b/arch/x86_64/ia32/ia32_binfmt.c | |||
| @@ -293,8 +293,6 @@ int ia32_setup_arg_pages(struct linux_binprm *bprm, unsigned long stack_top, int | |||
| 293 | } while(0) | 293 | } while(0) |
| 294 | 294 | ||
| 295 | 295 | ||
| 296 | #define elf_map elf32_map | ||
| 297 | |||
| 298 | #include <linux/module.h> | 296 | #include <linux/module.h> |
| 299 | 297 | ||
| 300 | MODULE_DESCRIPTION("Binary format loader for compatibility with IA32 ELF binaries."); | 298 | MODULE_DESCRIPTION("Binary format loader for compatibility with IA32 ELF binaries."); |
| @@ -390,21 +388,6 @@ int ia32_setup_arg_pages(struct linux_binprm *bprm, unsigned long stack_top, | |||
| 390 | } | 388 | } |
| 391 | EXPORT_SYMBOL(ia32_setup_arg_pages); | 389 | EXPORT_SYMBOL(ia32_setup_arg_pages); |
| 392 | 390 | ||
| 393 | static unsigned long | ||
| 394 | elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type) | ||
| 395 | { | ||
| 396 | unsigned long map_addr; | ||
| 397 | struct task_struct *me = current; | ||
| 398 | |||
| 399 | down_write(&me->mm->mmap_sem); | ||
| 400 | map_addr = do_mmap(filep, ELF_PAGESTART(addr), | ||
| 401 | eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot, | ||
| 402 | type, | ||
| 403 | eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr)); | ||
| 404 | up_write(&me->mm->mmap_sem); | ||
| 405 | return(map_addr); | ||
| 406 | } | ||
| 407 | |||
| 408 | #ifdef CONFIG_SYSCTL | 391 | #ifdef CONFIG_SYSCTL |
| 409 | /* Register vsyscall32 into the ABI table */ | 392 | /* Register vsyscall32 into the ABI table */ |
| 410 | #include <linux/sysctl.h> | 393 | #include <linux/sysctl.h> |
diff --git a/arch/x86_64/ia32/mmap32.c b/arch/x86_64/ia32/mmap32.c new file mode 100644 index 000000000000..079f4132575c --- /dev/null +++ b/arch/x86_64/ia32/mmap32.c | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/x86_64/ia32/mm/mmap.c | ||
| 3 | * | ||
| 4 | * flexible mmap layout support | ||
| 5 | * | ||
| 6 | * Based on the i386 version which was | ||
| 7 | * | ||
| 8 | * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina. | ||
| 9 | * All Rights Reserved. | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License as published by | ||
| 13 | * the Free Software Foundation; either version 2 of the License, or | ||
| 14 | * (at your option) any later version. | ||
| 15 | * | ||
| 16 | * This program is distributed in the hope that it will be useful, | ||
| 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 19 | * GNU General Public License for more details. | ||
| 20 | * | ||
| 21 | * You should have received a copy of the GNU General Public License | ||
| 22 | * along with this program; if not, write to the Free Software | ||
| 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 24 | * | ||
| 25 | * | ||
| 26 | * Started by Ingo Molnar <mingo@elte.hu> | ||
| 27 | */ | ||
| 28 | |||
| 29 | #include <linux/personality.h> | ||
| 30 | #include <linux/mm.h> | ||
| 31 | #include <linux/random.h> | ||
| 32 | |||
| 33 | /* | ||
| 34 | * Top of mmap area (just below the process stack). | ||
| 35 | * | ||
| 36 | * Leave an at least ~128 MB hole. | ||
| 37 | */ | ||
| 38 | #define MIN_GAP (128*1024*1024) | ||
| 39 | #define MAX_GAP (TASK_SIZE/6*5) | ||
| 40 | |||
| 41 | static inline unsigned long mmap_base(struct mm_struct *mm) | ||
| 42 | { | ||
| 43 | unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur; | ||
| 44 | unsigned long random_factor = 0; | ||
| 45 | |||
| 46 | if (current->flags & PF_RANDOMIZE) | ||
| 47 | random_factor = get_random_int() % (1024*1024); | ||
| 48 | |||
| 49 | if (gap < MIN_GAP) | ||
| 50 | gap = MIN_GAP; | ||
| 51 | else if (gap > MAX_GAP) | ||
| 52 | gap = MAX_GAP; | ||
| 53 | |||
| 54 | return PAGE_ALIGN(TASK_SIZE - gap - random_factor); | ||
| 55 | } | ||
| 56 | |||
| 57 | /* | ||
| 58 | * This function, called very early during the creation of a new | ||
| 59 | * process VM image, sets up which VM layout function to use: | ||
| 60 | */ | ||
| 61 | void ia32_pick_mmap_layout(struct mm_struct *mm) | ||
| 62 | { | ||
| 63 | /* | ||
| 64 | * Fall back to the standard layout if the personality | ||
| 65 | * bit is set, or if the expected stack growth is unlimited: | ||
| 66 | */ | ||
| 67 | if (sysctl_legacy_va_layout || | ||
| 68 | (current->personality & ADDR_COMPAT_LAYOUT) || | ||
| 69 | current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) { | ||
| 70 | mm->mmap_base = TASK_UNMAPPED_BASE; | ||
| 71 | mm->get_unmapped_area = arch_get_unmapped_area; | ||
| 72 | mm->unmap_area = arch_unmap_area; | ||
| 73 | } else { | ||
| 74 | mm->mmap_base = mmap_base(mm); | ||
| 75 | mm->get_unmapped_area = arch_get_unmapped_area_topdown; | ||
| 76 | mm->unmap_area = arch_unmap_area_topdown; | ||
| 77 | } | ||
| 78 | } | ||
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index 8fdd089fd17e..5d3c5b07b8db 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c | |||
| @@ -499,13 +499,10 @@ static int lapic_resume(struct sys_device *dev) | |||
| 499 | if (!apic_pm_state.active) | 499 | if (!apic_pm_state.active) |
| 500 | return 0; | 500 | return 0; |
| 501 | 501 | ||
| 502 | /* XXX: Pavel needs this for S3 resume, but can't explain why */ | ||
| 503 | set_fixmap_nocache(FIX_APIC_BASE, APIC_DEFAULT_PHYS_BASE); | ||
| 504 | |||
| 505 | local_irq_save(flags); | 502 | local_irq_save(flags); |
| 506 | rdmsr(MSR_IA32_APICBASE, l, h); | 503 | rdmsr(MSR_IA32_APICBASE, l, h); |
| 507 | l &= ~MSR_IA32_APICBASE_BASE; | 504 | l &= ~MSR_IA32_APICBASE_BASE; |
| 508 | l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE; | 505 | l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; |
| 509 | wrmsr(MSR_IA32_APICBASE, l, h); | 506 | wrmsr(MSR_IA32_APICBASE, l, h); |
| 510 | apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED); | 507 | apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED); |
| 511 | apic_write(APIC_ID, apic_pm_state.apic_id); | 508 | apic_write(APIC_ID, apic_pm_state.apic_id); |
diff --git a/arch/x86_64/kernel/asm-offsets.c b/arch/x86_64/kernel/asm-offsets.c index cfb4f9cebea4..38834bbbae11 100644 --- a/arch/x86_64/kernel/asm-offsets.c +++ b/arch/x86_64/kernel/asm-offsets.c | |||
| @@ -43,6 +43,7 @@ int main(void) | |||
| 43 | ENTRY(irqcount); | 43 | ENTRY(irqcount); |
| 44 | ENTRY(cpunumber); | 44 | ENTRY(cpunumber); |
| 45 | ENTRY(irqstackptr); | 45 | ENTRY(irqstackptr); |
| 46 | ENTRY(data_offset); | ||
| 46 | BLANK(); | 47 | BLANK(); |
| 47 | #undef ENTRY | 48 | #undef ENTRY |
| 48 | #ifdef CONFIG_IA32_EMULATION | 49 | #ifdef CONFIG_IA32_EMULATION |
| @@ -66,8 +67,6 @@ int main(void) | |||
| 66 | DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); | 67 | DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); |
| 67 | DEFINE(pbe_next, offsetof(struct pbe, next)); | 68 | DEFINE(pbe_next, offsetof(struct pbe, next)); |
| 68 | BLANK(); | 69 | BLANK(); |
| 69 | #if DEBUG_STKSZ > EXCEPTION_STKSZ | 70 | DEFINE(TSS_ist, offsetof(struct tss_struct, ist)); |
| 70 | DEFINE(DEBUG_IST, DEBUG_STACK); | ||
| 71 | #endif | ||
| 72 | return 0; | 71 | return 0; |
| 73 | } | 72 | } |
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 632fc0f59fcc..dbdba56e8faa 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | #include <asm/unistd.h> | 41 | #include <asm/unistd.h> |
| 42 | #include <asm/thread_info.h> | 42 | #include <asm/thread_info.h> |
| 43 | #include <asm/hw_irq.h> | 43 | #include <asm/hw_irq.h> |
| 44 | #include <asm/page.h> | ||
| 44 | 45 | ||
| 45 | .code64 | 46 | .code64 |
| 46 | 47 | ||
| @@ -674,9 +675,6 @@ ENTRY(spurious_interrupt) | |||
| 674 | 675 | ||
| 675 | /* error code is on the stack already */ | 676 | /* error code is on the stack already */ |
| 676 | /* handle NMI like exceptions that can happen everywhere */ | 677 | /* handle NMI like exceptions that can happen everywhere */ |
| 677 | #ifndef DEBUG_IST | ||
| 678 | # define DEBUG_IST 0 | ||
| 679 | #endif | ||
| 680 | .macro paranoidentry sym, ist=0 | 678 | .macro paranoidentry sym, ist=0 |
| 681 | SAVE_ALL | 679 | SAVE_ALL |
| 682 | cld | 680 | cld |
| @@ -695,11 +693,11 @@ ENTRY(spurious_interrupt) | |||
| 695 | movq ORIG_RAX(%rsp),%rsi | 693 | movq ORIG_RAX(%rsp),%rsi |
| 696 | movq $-1,ORIG_RAX(%rsp) | 694 | movq $-1,ORIG_RAX(%rsp) |
| 697 | .if \ist | 695 | .if \ist |
| 698 | subq $EXCEPTION_STACK_SIZE, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp) | 696 | subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp) |
| 699 | .endif | 697 | .endif |
| 700 | call \sym | 698 | call \sym |
| 701 | .if \ist | 699 | .if \ist |
| 702 | addq $EXCEPTION_STACK_SIZE, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp) | 700 | addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp) |
| 703 | .endif | 701 | .endif |
| 704 | cli | 702 | cli |
| 705 | .endm | 703 | .endm |
| @@ -918,7 +916,7 @@ KPROBE_ENTRY(debug) | |||
| 918 | INTR_FRAME | 916 | INTR_FRAME |
| 919 | pushq $0 | 917 | pushq $0 |
| 920 | CFI_ADJUST_CFA_OFFSET 8 | 918 | CFI_ADJUST_CFA_OFFSET 8 |
| 921 | paranoidentry do_debug, DEBUG_IST | 919 | paranoidentry do_debug, DEBUG_STACK |
| 922 | jmp paranoid_exit | 920 | jmp paranoid_exit |
| 923 | CFI_ENDPROC | 921 | CFI_ENDPROC |
| 924 | .previous .text | 922 | .previous .text |
| @@ -976,7 +974,7 @@ KPROBE_ENTRY(int3) | |||
| 976 | INTR_FRAME | 974 | INTR_FRAME |
| 977 | pushq $0 | 975 | pushq $0 |
| 978 | CFI_ADJUST_CFA_OFFSET 8 | 976 | CFI_ADJUST_CFA_OFFSET 8 |
| 979 | paranoidentry do_int3, DEBUG_IST | 977 | paranoidentry do_int3, DEBUG_STACK |
| 980 | jmp paranoid_exit | 978 | jmp paranoid_exit |
| 981 | CFI_ENDPROC | 979 | CFI_ENDPROC |
| 982 | .previous .text | 980 | .previous .text |
diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index 38fc3d5112e7..692c737feddb 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S | |||
| @@ -241,104 +241,70 @@ ljumpvector: | |||
| 241 | ENTRY(stext) | 241 | ENTRY(stext) |
| 242 | ENTRY(_stext) | 242 | ENTRY(_stext) |
| 243 | 243 | ||
| 244 | .org 0x1000 | 244 | $page = 0 |
| 245 | ENTRY(init_level4_pgt) | 245 | #define NEXT_PAGE(name) \ |
| 246 | $page = $page + 1; \ | ||
| 247 | .org $page * 0x1000; \ | ||
| 248 | phys_/**/name = $page * 0x1000 + __PHYSICAL_START; \ | ||
| 249 | ENTRY(name) | ||
| 250 | |||
| 251 | NEXT_PAGE(init_level4_pgt) | ||
| 246 | /* This gets initialized in x86_64_start_kernel */ | 252 | /* This gets initialized in x86_64_start_kernel */ |
| 247 | .fill 512,8,0 | 253 | .fill 512,8,0 |
| 248 | 254 | ||
| 249 | .org 0x2000 | 255 | NEXT_PAGE(level3_ident_pgt) |
| 250 | ENTRY(level3_ident_pgt) | 256 | .quad phys_level2_ident_pgt | 0x007 |
| 251 | .quad 0x0000000000004007 + __PHYSICAL_START | ||
| 252 | .fill 511,8,0 | 257 | .fill 511,8,0 |
| 253 | 258 | ||
| 254 | .org 0x3000 | 259 | NEXT_PAGE(level3_kernel_pgt) |
| 255 | ENTRY(level3_kernel_pgt) | ||
| 256 | .fill 510,8,0 | 260 | .fill 510,8,0 |
| 257 | /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */ | 261 | /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */ |
| 258 | .quad 0x0000000000005007 + __PHYSICAL_START /* -> level2_kernel_pgt */ | 262 | .quad phys_level2_kernel_pgt | 0x007 |
| 259 | .fill 1,8,0 | 263 | .fill 1,8,0 |
| 260 | 264 | ||
| 261 | .org 0x4000 | 265 | NEXT_PAGE(level2_ident_pgt) |
| 262 | ENTRY(level2_ident_pgt) | ||
| 263 | /* 40MB for bootup. */ | 266 | /* 40MB for bootup. */ |
| 264 | .quad 0x0000000000000083 | 267 | i = 0 |
| 265 | .quad 0x0000000000200083 | 268 | .rept 20 |
| 266 | .quad 0x0000000000400083 | 269 | .quad i << 21 | 0x083 |
| 267 | .quad 0x0000000000600083 | 270 | i = i + 1 |
| 268 | .quad 0x0000000000800083 | 271 | .endr |
| 269 | .quad 0x0000000000A00083 | ||
| 270 | .quad 0x0000000000C00083 | ||
| 271 | .quad 0x0000000000E00083 | ||
| 272 | .quad 0x0000000001000083 | ||
| 273 | .quad 0x0000000001200083 | ||
| 274 | .quad 0x0000000001400083 | ||
| 275 | .quad 0x0000000001600083 | ||
| 276 | .quad 0x0000000001800083 | ||
| 277 | .quad 0x0000000001A00083 | ||
| 278 | .quad 0x0000000001C00083 | ||
| 279 | .quad 0x0000000001E00083 | ||
| 280 | .quad 0x0000000002000083 | ||
| 281 | .quad 0x0000000002200083 | ||
| 282 | .quad 0x0000000002400083 | ||
| 283 | .quad 0x0000000002600083 | ||
| 284 | /* Temporary mappings for the super early allocator in arch/x86_64/mm/init.c */ | 272 | /* Temporary mappings for the super early allocator in arch/x86_64/mm/init.c */ |
| 285 | .globl temp_boot_pmds | 273 | .globl temp_boot_pmds |
| 286 | temp_boot_pmds: | 274 | temp_boot_pmds: |
| 287 | .fill 492,8,0 | 275 | .fill 492,8,0 |
| 288 | 276 | ||
| 289 | .org 0x5000 | 277 | NEXT_PAGE(level2_kernel_pgt) |
| 290 | ENTRY(level2_kernel_pgt) | ||
| 291 | /* 40MB kernel mapping. The kernel code cannot be bigger than that. | 278 | /* 40MB kernel mapping. The kernel code cannot be bigger than that. |
| 292 | When you change this change KERNEL_TEXT_SIZE in page.h too. */ | 279 | When you change this change KERNEL_TEXT_SIZE in page.h too. */ |
| 293 | /* (2^48-(2*1024*1024*1024)-((2^39)*511)-((2^30)*510)) = 0 */ | 280 | /* (2^48-(2*1024*1024*1024)-((2^39)*511)-((2^30)*510)) = 0 */ |
| 294 | .quad 0x0000000000000183 | 281 | i = 0 |
| 295 | .quad 0x0000000000200183 | 282 | .rept 20 |
| 296 | .quad 0x0000000000400183 | 283 | .quad i << 21 | 0x183 |
| 297 | .quad 0x0000000000600183 | 284 | i = i + 1 |
| 298 | .quad 0x0000000000800183 | 285 | .endr |
| 299 | .quad 0x0000000000A00183 | ||
| 300 | .quad 0x0000000000C00183 | ||
| 301 | .quad 0x0000000000E00183 | ||
| 302 | .quad 0x0000000001000183 | ||
| 303 | .quad 0x0000000001200183 | ||
| 304 | .quad 0x0000000001400183 | ||
| 305 | .quad 0x0000000001600183 | ||
| 306 | .quad 0x0000000001800183 | ||
| 307 | .quad 0x0000000001A00183 | ||
| 308 | .quad 0x0000000001C00183 | ||
| 309 | .quad 0x0000000001E00183 | ||
| 310 | .quad 0x0000000002000183 | ||
| 311 | .quad 0x0000000002200183 | ||
| 312 | .quad 0x0000000002400183 | ||
| 313 | .quad 0x0000000002600183 | ||
| 314 | /* Module mapping starts here */ | 286 | /* Module mapping starts here */ |
| 315 | .fill 492,8,0 | 287 | .fill 492,8,0 |
| 316 | 288 | ||
| 317 | .org 0x6000 | 289 | NEXT_PAGE(empty_zero_page) |
| 318 | ENTRY(empty_zero_page) | ||
| 319 | |||
| 320 | .org 0x7000 | ||
| 321 | ENTRY(empty_bad_page) | ||
| 322 | 290 | ||
| 323 | .org 0x8000 | 291 | NEXT_PAGE(level3_physmem_pgt) |
| 324 | ENTRY(empty_bad_pte_table) | 292 | .quad phys_level2_kernel_pgt | 0x007 /* so that __va works even before pagetable_init */ |
| 293 | .fill 511,8,0 | ||
| 325 | 294 | ||
| 326 | .org 0x9000 | 295 | #undef NEXT_PAGE |
| 327 | ENTRY(empty_bad_pmd_table) | ||
| 328 | 296 | ||
| 329 | .org 0xa000 | 297 | .data |
| 330 | ENTRY(level3_physmem_pgt) | ||
| 331 | .quad 0x0000000000005007 + __PHYSICAL_START /* -> level2_kernel_pgt (so that __va works even before pagetable_init) */ | ||
| 332 | 298 | ||
| 333 | .org 0xb000 | ||
| 334 | #ifdef CONFIG_ACPI_SLEEP | 299 | #ifdef CONFIG_ACPI_SLEEP |
| 300 | .align PAGE_SIZE | ||
| 335 | ENTRY(wakeup_level4_pgt) | 301 | ENTRY(wakeup_level4_pgt) |
| 336 | .quad 0x0000000000002007 + __PHYSICAL_START /* -> level3_ident_pgt */ | 302 | .quad phys_level3_ident_pgt | 0x007 |
| 337 | .fill 255,8,0 | 303 | .fill 255,8,0 |
| 338 | .quad 0x000000000000a007 + __PHYSICAL_START | 304 | .quad phys_level3_physmem_pgt | 0x007 |
| 339 | .fill 254,8,0 | 305 | .fill 254,8,0 |
| 340 | /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ | 306 | /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ |
| 341 | .quad 0x0000000000003007 + __PHYSICAL_START /* -> level3_kernel_pgt */ | 307 | .quad phys_level3_kernel_pgt | 0x007 |
| 342 | #endif | 308 | #endif |
| 343 | 309 | ||
| 344 | #ifndef CONFIG_HOTPLUG_CPU | 310 | #ifndef CONFIG_HOTPLUG_CPU |
| @@ -352,12 +318,12 @@ ENTRY(wakeup_level4_pgt) | |||
| 352 | */ | 318 | */ |
| 353 | .align PAGE_SIZE | 319 | .align PAGE_SIZE |
| 354 | ENTRY(boot_level4_pgt) | 320 | ENTRY(boot_level4_pgt) |
| 355 | .quad 0x0000000000002007 + __PHYSICAL_START /* -> level3_ident_pgt */ | 321 | .quad phys_level3_ident_pgt | 0x007 |
| 356 | .fill 255,8,0 | 322 | .fill 255,8,0 |
| 357 | .quad 0x000000000000a007 + __PHYSICAL_START | 323 | .quad phys_level3_physmem_pgt | 0x007 |
| 358 | .fill 254,8,0 | 324 | .fill 254,8,0 |
| 359 | /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ | 325 | /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ |
| 360 | .quad 0x0000000000003007 + __PHYSICAL_START /* -> level3_kernel_pgt */ | 326 | .quad phys_level3_kernel_pgt | 0x007 |
| 361 | 327 | ||
| 362 | .data | 328 | .data |
| 363 | 329 | ||
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c index 6eff51e9400c..8ac4db09610a 100644 --- a/arch/x86_64/kernel/setup64.c +++ b/arch/x86_64/kernel/setup64.c | |||
| @@ -38,7 +38,7 @@ struct desc_ptr idt_descr = { 256 * 16, (unsigned long) idt_table }; | |||
| 38 | char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned"))); | 38 | char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned"))); |
| 39 | 39 | ||
| 40 | unsigned long __supported_pte_mask __read_mostly = ~0UL; | 40 | unsigned long __supported_pte_mask __read_mostly = ~0UL; |
| 41 | static int do_not_nx __initdata = 0; | 41 | static int do_not_nx __cpuinitdata = 0; |
| 42 | 42 | ||
| 43 | /* noexec=on|off | 43 | /* noexec=on|off |
| 44 | Control non executable mappings for 64bit processes. | 44 | Control non executable mappings for 64bit processes. |
diff --git a/arch/x86_64/mm/Makefile b/arch/x86_64/mm/Makefile index 1d232a87f113..d25ac86fe27a 100644 --- a/arch/x86_64/mm/Makefile +++ b/arch/x86_64/mm/Makefile | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | # Makefile for the linux x86_64-specific parts of the memory manager. | 2 | # Makefile for the linux x86_64-specific parts of the memory manager. |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-y := init.o fault.o ioremap.o extable.o pageattr.o | 5 | obj-y := init.o fault.o ioremap.o extable.o pageattr.o mmap.o |
| 6 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o | 6 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o |
| 7 | obj-$(CONFIG_NUMA) += numa.o | 7 | obj-$(CONFIG_NUMA) += numa.o |
| 8 | obj-$(CONFIG_K8_NUMA) += k8topology.o | 8 | obj-$(CONFIG_K8_NUMA) += k8topology.o |
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index eca60125efc3..7af1742aa958 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c | |||
| @@ -24,6 +24,8 @@ | |||
| 24 | #include <linux/proc_fs.h> | 24 | #include <linux/proc_fs.h> |
| 25 | #include <linux/pci.h> | 25 | #include <linux/pci.h> |
| 26 | #include <linux/dma-mapping.h> | 26 | #include <linux/dma-mapping.h> |
| 27 | #include <linux/module.h> | ||
| 28 | #include <linux/memory_hotplug.h> | ||
| 27 | 29 | ||
| 28 | #include <asm/processor.h> | 30 | #include <asm/processor.h> |
| 29 | #include <asm/system.h> | 31 | #include <asm/system.h> |
| @@ -180,13 +182,19 @@ static struct temp_map { | |||
| 180 | {} | 182 | {} |
| 181 | }; | 183 | }; |
| 182 | 184 | ||
| 183 | static __init void *alloc_low_page(int *index, unsigned long *phys) | 185 | static __meminit void *alloc_low_page(int *index, unsigned long *phys) |
| 184 | { | 186 | { |
| 185 | struct temp_map *ti; | 187 | struct temp_map *ti; |
| 186 | int i; | 188 | int i; |
| 187 | unsigned long pfn = table_end++, paddr; | 189 | unsigned long pfn = table_end++, paddr; |
| 188 | void *adr; | 190 | void *adr; |
| 189 | 191 | ||
| 192 | if (after_bootmem) { | ||
| 193 | adr = (void *)get_zeroed_page(GFP_ATOMIC); | ||
| 194 | *phys = __pa(adr); | ||
| 195 | return adr; | ||
| 196 | } | ||
| 197 | |||
| 190 | if (pfn >= end_pfn) | 198 | if (pfn >= end_pfn) |
| 191 | panic("alloc_low_page: ran out of memory"); | 199 | panic("alloc_low_page: ran out of memory"); |
| 192 | for (i = 0; temp_mappings[i].allocated; i++) { | 200 | for (i = 0; temp_mappings[i].allocated; i++) { |
| @@ -199,55 +207,86 @@ static __init void *alloc_low_page(int *index, unsigned long *phys) | |||
| 199 | ti->allocated = 1; | 207 | ti->allocated = 1; |
| 200 | __flush_tlb(); | 208 | __flush_tlb(); |
| 201 | adr = ti->address + ((pfn << PAGE_SHIFT) & ~PMD_MASK); | 209 | adr = ti->address + ((pfn << PAGE_SHIFT) & ~PMD_MASK); |
| 210 | memset(adr, 0, PAGE_SIZE); | ||
| 202 | *index = i; | 211 | *index = i; |
| 203 | *phys = pfn * PAGE_SIZE; | 212 | *phys = pfn * PAGE_SIZE; |
| 204 | return adr; | 213 | return adr; |
| 205 | } | 214 | } |
| 206 | 215 | ||
| 207 | static __init void unmap_low_page(int i) | 216 | static __meminit void unmap_low_page(int i) |
| 208 | { | 217 | { |
| 209 | struct temp_map *ti = &temp_mappings[i]; | 218 | struct temp_map *ti; |
| 219 | |||
| 220 | if (after_bootmem) | ||
| 221 | return; | ||
| 222 | |||
| 223 | ti = &temp_mappings[i]; | ||
| 210 | set_pmd(ti->pmd, __pmd(0)); | 224 | set_pmd(ti->pmd, __pmd(0)); |
| 211 | ti->allocated = 0; | 225 | ti->allocated = 0; |
| 212 | } | 226 | } |
| 213 | 227 | ||
| 214 | static void __init phys_pud_init(pud_t *pud, unsigned long address, unsigned long end) | 228 | static void __meminit |
| 229 | phys_pmd_init(pmd_t *pmd, unsigned long address, unsigned long end) | ||
| 230 | { | ||
| 231 | int i; | ||
| 232 | |||
| 233 | for (i = 0; i < PTRS_PER_PMD; pmd++, i++, address += PMD_SIZE) { | ||
| 234 | unsigned long entry; | ||
| 235 | |||
| 236 | if (address > end) { | ||
| 237 | for (; i < PTRS_PER_PMD; i++, pmd++) | ||
| 238 | set_pmd(pmd, __pmd(0)); | ||
| 239 | break; | ||
| 240 | } | ||
| 241 | entry = _PAGE_NX|_PAGE_PSE|_KERNPG_TABLE|_PAGE_GLOBAL|address; | ||
| 242 | entry &= __supported_pte_mask; | ||
| 243 | set_pmd(pmd, __pmd(entry)); | ||
| 244 | } | ||
| 245 | } | ||
| 246 | |||
| 247 | static void __meminit | ||
| 248 | phys_pmd_update(pud_t *pud, unsigned long address, unsigned long end) | ||
| 249 | { | ||
| 250 | pmd_t *pmd = pmd_offset(pud, (unsigned long)__va(address)); | ||
| 251 | |||
| 252 | if (pmd_none(*pmd)) { | ||
| 253 | spin_lock(&init_mm.page_table_lock); | ||
| 254 | phys_pmd_init(pmd, address, end); | ||
| 255 | spin_unlock(&init_mm.page_table_lock); | ||
| 256 | __flush_tlb_all(); | ||
| 257 | } | ||
| 258 | } | ||
| 259 | |||
| 260 | static void __meminit phys_pud_init(pud_t *pud, unsigned long address, unsigned long end) | ||
| 215 | { | 261 | { |
| 216 | long i, j; | 262 | long i = pud_index(address); |
| 217 | 263 | ||
| 218 | i = pud_index(address); | ||
| 219 | pud = pud + i; | 264 | pud = pud + i; |
| 265 | |||
| 266 | if (after_bootmem && pud_val(*pud)) { | ||
| 267 | phys_pmd_update(pud, address, end); | ||
| 268 | return; | ||
| 269 | } | ||
| 270 | |||
| 220 | for (; i < PTRS_PER_PUD; pud++, i++) { | 271 | for (; i < PTRS_PER_PUD; pud++, i++) { |
| 221 | int map; | 272 | int map; |
| 222 | unsigned long paddr, pmd_phys; | 273 | unsigned long paddr, pmd_phys; |
| 223 | pmd_t *pmd; | 274 | pmd_t *pmd; |
| 224 | 275 | ||
| 225 | paddr = address + i*PUD_SIZE; | 276 | paddr = (address & PGDIR_MASK) + i*PUD_SIZE; |
| 226 | if (paddr >= end) { | 277 | if (paddr >= end) |
| 227 | for (; i < PTRS_PER_PUD; i++, pud++) | ||
| 228 | set_pud(pud, __pud(0)); | ||
| 229 | break; | 278 | break; |
| 230 | } | ||
| 231 | 279 | ||
| 232 | if (!e820_mapped(paddr, paddr+PUD_SIZE, 0)) { | 280 | if (!after_bootmem && !e820_mapped(paddr, paddr+PUD_SIZE, 0)) { |
| 233 | set_pud(pud, __pud(0)); | 281 | set_pud(pud, __pud(0)); |
| 234 | continue; | 282 | continue; |
| 235 | } | 283 | } |
| 236 | 284 | ||
| 237 | pmd = alloc_low_page(&map, &pmd_phys); | 285 | pmd = alloc_low_page(&map, &pmd_phys); |
| 286 | spin_lock(&init_mm.page_table_lock); | ||
| 238 | set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE)); | 287 | set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE)); |
| 239 | for (j = 0; j < PTRS_PER_PMD; pmd++, j++, paddr += PMD_SIZE) { | 288 | phys_pmd_init(pmd, paddr, end); |
| 240 | unsigned long pe; | 289 | spin_unlock(&init_mm.page_table_lock); |
| 241 | |||
| 242 | if (paddr >= end) { | ||
| 243 | for (; j < PTRS_PER_PMD; j++, pmd++) | ||
| 244 | set_pmd(pmd, __pmd(0)); | ||
| 245 | break; | ||
| 246 | } | ||
| 247 | pe = _PAGE_NX|_PAGE_PSE | _KERNPG_TABLE | _PAGE_GLOBAL | paddr; | ||
| 248 | pe &= __supported_pte_mask; | ||
| 249 | set_pmd(pmd, __pmd(pe)); | ||
| 250 | } | ||
| 251 | unmap_low_page(map); | 290 | unmap_low_page(map); |
| 252 | } | 291 | } |
| 253 | __flush_tlb(); | 292 | __flush_tlb(); |
| @@ -262,30 +301,25 @@ static void __init find_early_table_space(unsigned long end) | |||
| 262 | tables = round_up(puds * sizeof(pud_t), PAGE_SIZE) + | 301 | tables = round_up(puds * sizeof(pud_t), PAGE_SIZE) + |
| 263 | round_up(pmds * sizeof(pmd_t), PAGE_SIZE); | 302 | round_up(pmds * sizeof(pmd_t), PAGE_SIZE); |
| 264 | 303 | ||
| 265 | /* Put page tables beyond the DMA zones if possible. | 304 | /* RED-PEN putting page tables only on node 0 could |
| 266 | RED-PEN might be better to spread them out more over | 305 | cause a hotspot and fill up ZONE_DMA. The page tables |
| 267 | memory to avoid hotspots */ | 306 | need roughly 0.5KB per GB. */ |
| 268 | if (end > MAX_DMA32_PFN<<PAGE_SHIFT) | 307 | start = 0x8000; |
| 269 | start = MAX_DMA32_PFN << PAGE_SHIFT; | 308 | table_start = find_e820_area(start, end, tables); |
| 270 | else if (end > MAX_DMA_PFN << PAGE_SHIFT) | ||
| 271 | start = MAX_DMA_PFN << PAGE_SHIFT; | ||
| 272 | else | ||
| 273 | start = 0x8000; | ||
| 274 | |||
| 275 | table_start = find_e820_area(start, end, tables); | ||
| 276 | if (table_start == -1) | ||
| 277 | table_start = find_e820_area(0x8000, end, tables); | ||
| 278 | if (table_start == -1UL) | 309 | if (table_start == -1UL) |
| 279 | panic("Cannot find space for the kernel page tables"); | 310 | panic("Cannot find space for the kernel page tables"); |
| 280 | 311 | ||
| 281 | table_start >>= PAGE_SHIFT; | 312 | table_start >>= PAGE_SHIFT; |
| 282 | table_end = table_start; | 313 | table_end = table_start; |
| 314 | |||
| 315 | early_printk("kernel direct mapping tables up to %lx @ %lx-%lx\n", | ||
| 316 | end, table_start << PAGE_SHIFT, table_end << PAGE_SHIFT); | ||
| 283 | } | 317 | } |
| 284 | 318 | ||
| 285 | /* Setup the direct mapping of the physical memory at PAGE_OFFSET. | 319 | /* Setup the direct mapping of the physical memory at PAGE_OFFSET. |
| 286 | This runs before bootmem is initialized and gets pages directly from the | 320 | This runs before bootmem is initialized and gets pages directly from the |
| 287 | physical memory. To access them they are temporarily mapped. */ | 321 | physical memory. To access them they are temporarily mapped. */ |
| 288 | void __init init_memory_mapping(unsigned long start, unsigned long end) | 322 | void __meminit init_memory_mapping(unsigned long start, unsigned long end) |
| 289 | { | 323 | { |
| 290 | unsigned long next; | 324 | unsigned long next; |
| 291 | 325 | ||
| @@ -297,7 +331,8 @@ void __init init_memory_mapping(unsigned long start, unsigned long end) | |||
| 297 | * mapped. Unfortunately this is done currently before the nodes are | 331 | * mapped. Unfortunately this is done currently before the nodes are |
| 298 | * discovered. | 332 | * discovered. |
| 299 | */ | 333 | */ |
| 300 | find_early_table_space(end); | 334 | if (!after_bootmem) |
| 335 | find_early_table_space(end); | ||
| 301 | 336 | ||
| 302 | start = (unsigned long)__va(start); | 337 | start = (unsigned long)__va(start); |
| 303 | end = (unsigned long)__va(end); | 338 | end = (unsigned long)__va(end); |
| @@ -305,20 +340,26 @@ void __init init_memory_mapping(unsigned long start, unsigned long end) | |||
| 305 | for (; start < end; start = next) { | 340 | for (; start < end; start = next) { |
| 306 | int map; | 341 | int map; |
| 307 | unsigned long pud_phys; | 342 | unsigned long pud_phys; |
| 308 | pud_t *pud = alloc_low_page(&map, &pud_phys); | 343 | pgd_t *pgd = pgd_offset_k(start); |
| 344 | pud_t *pud; | ||
| 345 | |||
| 346 | if (after_bootmem) | ||
| 347 | pud = pud_offset_k(pgd, __PAGE_OFFSET); | ||
| 348 | else | ||
| 349 | pud = alloc_low_page(&map, &pud_phys); | ||
| 350 | |||
| 309 | next = start + PGDIR_SIZE; | 351 | next = start + PGDIR_SIZE; |
| 310 | if (next > end) | 352 | if (next > end) |
| 311 | next = end; | 353 | next = end; |
| 312 | phys_pud_init(pud, __pa(start), __pa(next)); | 354 | phys_pud_init(pud, __pa(start), __pa(next)); |
| 313 | set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys)); | 355 | if (!after_bootmem) |
| 356 | set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys)); | ||
| 314 | unmap_low_page(map); | 357 | unmap_low_page(map); |
| 315 | } | 358 | } |
| 316 | 359 | ||
| 317 | asm volatile("movq %%cr4,%0" : "=r" (mmu_cr4_features)); | 360 | if (!after_bootmem) |
| 361 | asm volatile("movq %%cr4,%0" : "=r" (mmu_cr4_features)); | ||
| 318 | __flush_tlb_all(); | 362 | __flush_tlb_all(); |
| 319 | early_printk("kernel direct mapping tables upto %lx @ %lx-%lx\n", end, | ||
| 320 | table_start<<PAGE_SHIFT, | ||
| 321 | table_end<<PAGE_SHIFT); | ||
| 322 | } | 363 | } |
| 323 | 364 | ||
| 324 | void __cpuinit zap_low_mappings(int cpu) | 365 | void __cpuinit zap_low_mappings(int cpu) |
| @@ -393,6 +434,9 @@ size_zones(unsigned long *z, unsigned long *h, | |||
| 393 | void __init paging_init(void) | 434 | void __init paging_init(void) |
| 394 | { | 435 | { |
| 395 | unsigned long zones[MAX_NR_ZONES], holes[MAX_NR_ZONES]; | 436 | unsigned long zones[MAX_NR_ZONES], holes[MAX_NR_ZONES]; |
| 437 | |||
| 438 | memory_present(0, 0, end_pfn); | ||
| 439 | sparse_init(); | ||
| 396 | size_zones(zones, holes, 0, end_pfn); | 440 | size_zones(zones, holes, 0, end_pfn); |
| 397 | free_area_init_node(0, NODE_DATA(0), zones, | 441 | free_area_init_node(0, NODE_DATA(0), zones, |
| 398 | __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes); | 442 | __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes); |
| @@ -433,6 +477,50 @@ void __init clear_kernel_mapping(unsigned long address, unsigned long size) | |||
| 433 | __flush_tlb_all(); | 477 | __flush_tlb_all(); |
| 434 | } | 478 | } |
| 435 | 479 | ||
| 480 | /* | ||
| 481 | * Memory hotplug specific functions | ||
| 482 | * These are only for non-NUMA machines right now. | ||
| 483 | */ | ||
| 484 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
| 485 | |||
| 486 | void online_page(struct page *page) | ||
| 487 | { | ||
| 488 | ClearPageReserved(page); | ||
| 489 | set_page_count(page, 1); | ||
| 490 | __free_page(page); | ||
| 491 | totalram_pages++; | ||
| 492 | num_physpages++; | ||
| 493 | } | ||
| 494 | |||
| 495 | int add_memory(u64 start, u64 size) | ||
| 496 | { | ||
| 497 | struct pglist_data *pgdat = NODE_DATA(0); | ||
| 498 | struct zone *zone = pgdat->node_zones + MAX_NR_ZONES-2; | ||
| 499 | unsigned long start_pfn = start >> PAGE_SHIFT; | ||
| 500 | unsigned long nr_pages = size >> PAGE_SHIFT; | ||
| 501 | int ret; | ||
| 502 | |||
| 503 | ret = __add_pages(zone, start_pfn, nr_pages); | ||
| 504 | if (ret) | ||
| 505 | goto error; | ||
| 506 | |||
| 507 | init_memory_mapping(start, (start + size -1)); | ||
| 508 | |||
| 509 | return ret; | ||
| 510 | error: | ||
| 511 | printk("%s: Problem encountered in __add_pages!\n", __func__); | ||
| 512 | return ret; | ||
| 513 | } | ||
| 514 | EXPORT_SYMBOL_GPL(add_memory); | ||
| 515 | |||
| 516 | int remove_memory(u64 start, u64 size) | ||
| 517 | { | ||
| 518 | return -EINVAL; | ||
| 519 | } | ||
| 520 | EXPORT_SYMBOL_GPL(remove_memory); | ||
| 521 | |||
| 522 | #endif | ||
| 523 | |||
| 436 | static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules, | 524 | static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules, |
| 437 | kcore_vsyscall; | 525 | kcore_vsyscall; |
| 438 | 526 | ||
| @@ -539,7 +627,7 @@ void mark_rodata_ro(void) | |||
| 539 | #ifdef CONFIG_BLK_DEV_INITRD | 627 | #ifdef CONFIG_BLK_DEV_INITRD |
| 540 | void free_initrd_mem(unsigned long start, unsigned long end) | 628 | void free_initrd_mem(unsigned long start, unsigned long end) |
| 541 | { | 629 | { |
| 542 | if (start < (unsigned long)&_end) | 630 | if (start >= end) |
| 543 | return; | 631 | return; |
| 544 | printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); | 632 | printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); |
| 545 | for (; start < end; start += PAGE_SIZE) { | 633 | for (; start < end; start += PAGE_SIZE) { |
diff --git a/arch/x86_64/mm/mmap.c b/arch/x86_64/mm/mmap.c new file mode 100644 index 000000000000..43e9b99bdf25 --- /dev/null +++ b/arch/x86_64/mm/mmap.c | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* Copyright 2005 Andi Kleen, SuSE Labs. | ||
| 2 | * Licensed under GPL, v.2 | ||
| 3 | */ | ||
| 4 | #include <linux/config.h> | ||
| 5 | #include <linux/mm.h> | ||
| 6 | #include <linux/sched.h> | ||
| 7 | #include <linux/random.h> | ||
| 8 | #include <asm/ia32.h> | ||
| 9 | |||
| 10 | /* Notebook: move the mmap code from sys_x86_64.c over here. */ | ||
| 11 | |||
| 12 | void arch_pick_mmap_layout(struct mm_struct *mm) | ||
| 13 | { | ||
| 14 | #ifdef CONFIG_IA32_EMULATION | ||
| 15 | if (current_thread_info()->flags & _TIF_IA32) | ||
| 16 | return ia32_pick_mmap_layout(mm); | ||
| 17 | #endif | ||
| 18 | mm->mmap_base = TASK_UNMAPPED_BASE; | ||
| 19 | if (current->flags & PF_RANDOMIZE) { | ||
| 20 | /* Add 28bit randomness which is about 40bits of address space | ||
| 21 | because mmap base has to be page aligned. | ||
| 22 | or ~1/128 of the total user VM | ||
| 23 | (total user address space is 47bits) */ | ||
| 24 | unsigned rnd = get_random_int() & 0xfffffff; | ||
| 25 | mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT; | ||
| 26 | } | ||
| 27 | mm->get_unmapped_area = arch_get_unmapped_area; | ||
| 28 | mm->unmap_area = arch_unmap_area; | ||
| 29 | } | ||
| 30 | |||
