diff options
Diffstat (limited to 'arch')
261 files changed, 7374 insertions, 13206 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/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..bd2d53a9dd2b 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile | |||
@@ -42,9 +42,9 @@ include $(srctree)/arch/i386/Makefile.cpu | |||
42 | cflags-$(CONFIG_REGPARM) += $(shell if [ $(call cc-version) -ge 0300 ] ; then \ | 42 | cflags-$(CONFIG_REGPARM) += $(shell if [ $(call cc-version) -ge 0300 ] ; then \ |
43 | echo "-mregparm=3"; fi ;) | 43 | echo "-mregparm=3"; fi ;) |
44 | 44 | ||
45 | # Disable unit-at-a-time mode, it makes gcc use a lot more stack | 45 | # 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. | 46 | # a lot more stack due to the lack of sharing of stacklots: |
47 | CFLAGS += $(call cc-option,-fno-unit-at-a-time) | 47 | CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;) |
48 | 48 | ||
49 | CFLAGS += $(cflags-y) | 49 | CFLAGS += $(cflags-y) |
50 | 50 | ||
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/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/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/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/sn/include/xtalk/hubdev.h b/arch/ia64/sn/include/xtalk/hubdev.h index 71c2b271b4c6..4d417c301201 100644 --- a/arch/ia64/sn/include/xtalk/hubdev.h +++ b/arch/ia64/sn/include/xtalk/hubdev.h | |||
@@ -26,11 +26,14 @@ | |||
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]; |
@@ -40,14 +43,19 @@ struct sn_flush_device_list { | |||
40 | uint32_t sfdl_persistent_busnum; | 43 | uint32_t sfdl_persistent_busnum; |
41 | uint32_t sfdl_persistent_segment; | 44 | uint32_t 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 | uint64_t iio_itte[8]; |
52 | }; | 60 | }; |
53 | 61 | ||
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..258d9d7aff98 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,7 +131,7 @@ 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 | { |
@@ -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 | /* |
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index 493fb3f38dc3..6a7939b16a1c 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 | } |
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_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c index 34093476e965..e68332d93171 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c | |||
@@ -218,7 +218,9 @@ void sn_dma_flush(uint64_t addr) | |||
218 | uint64_t flags; | 218 | uint64_t flags; |
219 | uint64_t itte; | 219 | uint64_t 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. */ |
@@ -304,24 +306,24 @@ void sn_dma_flush(uint64_t addr) | |||
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 uint32_t *)(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..e328e948175d 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c | |||
@@ -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 | } |
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/kernel/cpu/bus.c b/arch/sh/kernel/cpu/bus.c index d4fee2a79373..3278d234bb1b 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) |
@@ -133,8 +135,6 @@ int sh_driver_register(struct sh_driver *drv) | |||
133 | return -EINVAL; | 135 | return -EINVAL; |
134 | } | 136 | } |
135 | 137 | ||
136 | drv->drv.probe = sh_device_probe; | ||
137 | drv->drv.remove = sh_device_remove; | ||
138 | drv->drv.bus = &sh_bus_types[drv->bus_id]; | 138 | drv->drv.bus = &sh_bus_types[drv->bus_id]; |
139 | 139 | ||
140 | return driver_register(&drv->drv); | 140 | return driver_register(&drv->drv); |
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) |