Merge git://git.kernel.org/pub/scm/linux/kernel/git/bunk/trivial
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 9474501..b4a1ea7 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -123,6 +123,15 @@
---------------------------
+What: CONFIG_FORCED_INLINING
+When: June 2006
+Why: Config option is there to see if gcc is good enough. (in january
+ 2006). If it is, the behavior should just be the default. If it's not,
+ the option should just go away entirely.
+Who: Arjan van de Ven
+
+---------------------------
+
What: START_ARRAY ioctl for md
When: July 2006
Files: drivers/md/md.c
diff --git a/Documentation/filesystems/tmpfs.txt b/Documentation/filesystems/tmpfs.txt
index 0d783c5..dbe4d87 100644
--- a/Documentation/filesystems/tmpfs.txt
+++ b/Documentation/filesystems/tmpfs.txt
@@ -78,6 +78,18 @@
that instance in a system with many cpus making intensive use of it.
+tmpfs has a mount option to set the NUMA memory allocation policy for
+all files in that instance:
+mpol=interleave prefers to allocate memory from each node in turn
+mpol=default prefers to allocate memory from the local node
+mpol=bind prefers to allocate from mpol_nodelist
+mpol=preferred prefers to allocate from first node in mpol_nodelist
+
+The following mount option is used in conjunction with mpol=interleave,
+mpol=bind or mpol=preferred:
+mpol_nodelist: nodelist suitable for parsing with nodelist_parse.
+
+
To specify the initial root directory you can use the following mount
options:
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index fe11fcc..1cbcf65 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -471,7 +471,7 @@
arch/i386/kernel/cpu/cpufreq/elanfreq.c.
elevator= [IOSCHED]
- Format: {"as" | "cfq" | "deadline" | "noop"}
+ Format: {"anticipatory" | "cfq" | "deadline" | "noop"}
See Documentation/block/as-iosched.txt and
Documentation/block/deadline-iosched.txt for details.
@@ -712,9 +712,17 @@
load_ramdisk= [RAM] List of ramdisks to load from floppy
See Documentation/ramdisk.txt.
- lockd.udpport= [NFS]
+ lockd.nlm_grace_period=P [NFS] Assign grace period.
+ Format: <integer>
- lockd.tcpport= [NFS]
+ lockd.nlm_tcpport=N [NFS] Assign TCP port.
+ Format: <integer>
+
+ lockd.nlm_timeout=T [NFS] Assign timeout value.
+ Format: <integer>
+
+ lockd.nlm_udpport=M [NFS] Assign UDP port.
+ Format: <integer>
logibm.irq= [HW,MOUSE] Logitech Bus Mouse Driver
Format: <irq>
diff --git a/MAINTAINERS b/MAINTAINERS
index 873c3f7..6d1b048 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1301,6 +1301,12 @@
L: linux-kernel@vger.kernel.org
S: Maintained
+INTEL FRAMEBUFFER DRIVER (excluding 810 and 815)
+P: Sylvain Meyer
+M: sylvain.meyer@worldonline.fr
+L: linux-fbdev-devel@lists.sourceforge.net
+S: Maintained
+
INTEL 810/815 FRAMEBUFFER DRIVER
P: Antonino Daplas
M: adaplas@pol.net
@@ -1890,11 +1896,11 @@
T: git kernel.org:/pub/scm/linux/kernel/git/aia21/ntfs-2.6.git
S: Maintained
-NVIDIA (RIVA) FRAMEBUFFER DRIVER
-P: Ani Joshi
-M: ajoshi@shell.unixbox.com
-L: linux-nvidia@lists.surfsouth.com
-S: Maintained
+NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER
+P: Antonino Daplas
+M: adaplas@pol.net
+L: linux-fbdev-devel@lists.sourceforge.net
+S: Maintained
ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
P: Mark Fasheh
@@ -2189,6 +2195,12 @@
W: www.rtlinux.org
S: Maintained
+S3 SAVAGE FRAMEBUFFER DRIVER
+P: Antonino Daplas
+M: adaplas@pol.net
+L: linux-fbdev-devel@lists.sourceforge.net
+S: Maintained
+
S390
P: Martin Schwidefsky
M: schwidefsky@de.ibm.com
@@ -2954,6 +2966,12 @@
W: http://www.sangoma.com
S: Supported
+WATCHDOG DEVICE DRIVERS
+P: Wim Van Sebroeck
+M: wim@iguana.be
+T: git kernel.org:/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog.git
+S: Maintained
+
WAVELAN NETWORK DRIVER & WIRELESS EXTENSIONS
P: Jean Tourrilhes
M: jt@hpl.hp.com
diff --git a/Makefile b/Makefile
index deedaf7..673148e 100644
--- a/Makefile
+++ b/Makefile
@@ -151,7 +151,7 @@
SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
-e s/arm.*/arm/ -e s/sa110/arm/ \
-e s/s390x/s390/ -e s/parisc64/parisc/ \
- -e s/ppc64/powerpc/ )
+ -e s/ppc.*/powerpc/ )
# Cross compiling and selecting different set of gcc/bin-utils
# ---------------------------------------------------------------------------
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3cfd82a..5959e36 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -180,6 +180,7 @@
config ARCH_VERSATILE
bool "Versatile"
select ARM_AMBA
+ select ARM_VIC
select ICST307
help
This enables support for ARM Ltd Versatile board.
@@ -400,6 +401,38 @@
Currently at least OMAP, PXA2xx and SA11x0 platforms are known
to have accurate timekeeping with dynamic tick.
+config AEABI
+ bool "Use the ARM EABI to compile the kernel"
+ help
+ This option allows for the kernel to be compiled using the latest
+ ARM ABI (aka EABI). This is only useful if you are using a user
+ space environment that is also compiled with EABI.
+
+ Since there are major incompatibilities between the legacy ABI and
+ EABI, especially with regard to structure member alignment, this
+ option also changes the kernel syscall calling convention to
+ disambiguate both ABIs and allow for backward compatibility support
+ (selected with CONFIG_OABI_COMPAT).
+
+ To use this you need GCC version 4.0.0 or later.
+
+config OABI_COMPAT
+ bool "Allow old ABI binaries to run with this kernel"
+ depends on AEABI
+ default y
+ help
+ This option preserves the old syscall interface along with the
+ new (ARM EABI) one. It also provides a compatibility layer to
+ intercept syscalls that have structure arguments which layout
+ in memory differs between the legacy ABI and the new ARM EABI
+ (only for non "thumb" binaries). This option adds a tiny
+ overhead to all syscalls and produces a slightly larger kernel.
+ If you know you'll be using only pure EABI user space then you
+ can say N here. If this option is not selected and you attempt
+ to execute a legacy ABI binary then the result will be
+ UNPREDICTABLE (in fact it can be predicted that it won't work
+ at all). If in doubt say Y.
+
config ARCH_DISCONTIGMEM_ENABLE
bool
default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
@@ -586,6 +619,7 @@
config FPE_NWFPE
bool "NWFPE math emulation"
+ depends on !AEABI || OABI_COMPAT
---help---
Say Y to include the NWFPE floating point emulator in the kernel.
This is necessary to run most binaries. Linux does not currently
@@ -609,7 +643,7 @@
config FPE_FASTFPE
bool "FastFPE math emulation (EXPERIMENTAL)"
- depends on !CPU_32v3 && EXPERIMENTAL
+ depends on (!AEABI || OABI_COMPAT) && !CPU_32v3 && EXPERIMENTAL
---help---
Say Y here to include the FAST floating point emulator in the kernel.
This is an experimental much faster emulator which now also has full
@@ -641,6 +675,7 @@
config ARTHUR
tristate "RISC OS personality"
+ depends on !AEABI
help
Say Y here to include the kernel code necessary if you want to run
Acorn RISC OS/Arthur binaries under Linux. This code is still very
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 1fa2a10..fbfc14a 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -56,8 +56,13 @@
tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
tune-$(CONFIG_CPU_V6) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
-# Need -Uarm for gcc < 3.x
+ifeq ($(CONFIG_AEABI),y)
+CFLAGS_ABI :=-mabi=aapcs -mno-thumb-interwork
+else
CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,)
+endif
+
+# Need -Uarm for gcc < 3.x
CFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index d7509c7..5e34ca6 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -1,7 +1,10 @@
-config ICST525
+config ARM_GIC
bool
-config ARM_GIC
+config ARM_VIC
+ bool
+
+config ICST525
bool
config ICST307
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index ec8d17c..c81a2ff 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -4,6 +4,7 @@
obj-y += rtctime.o
obj-$(CONFIG_ARM_GIC) += gic.o
+obj-$(CONFIG_ARM_VIC) += vic.o
obj-$(CONFIG_ICST525) += icst525.o
obj-$(CONFIG_ICST307) += icst307.o
obj-$(CONFIG_SA1111) += sa1111.o
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
new file mode 100644
index 0000000..a45ed16
--- /dev/null
+++ b/arch/arm/common/vic.c
@@ -0,0 +1,92 @@
+/*
+ * linux/arch/arm/common/vic.c
+ *
+ * Copyright (C) 1999 - 2003 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/list.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/hardware/vic.h>
+
+static void __iomem *vic_base;
+
+static void vic_mask_irq(unsigned int irq)
+{
+ irq -= IRQ_VIC_START;
+ writel(1 << irq, vic_base + VIC_INT_ENABLE_CLEAR);
+}
+
+static void vic_unmask_irq(unsigned int irq)
+{
+ irq -= IRQ_VIC_START;
+ writel(1 << irq, vic_base + VIC_INT_ENABLE);
+}
+
+static struct irqchip vic_chip = {
+ .ack = vic_mask_irq,
+ .mask = vic_mask_irq,
+ .unmask = vic_unmask_irq,
+};
+
+void __init vic_init(void __iomem *base, u32 vic_sources)
+{
+ unsigned int i;
+
+ vic_base = base;
+
+ /* Disable all interrupts initially. */
+
+ writel(0, vic_base + VIC_INT_SELECT);
+ writel(0, vic_base + VIC_INT_ENABLE);
+ writel(~0, vic_base + VIC_INT_ENABLE_CLEAR);
+ writel(0, vic_base + VIC_IRQ_STATUS);
+ writel(0, vic_base + VIC_ITCR);
+ writel(~0, vic_base + VIC_INT_SOFT_CLEAR);
+
+ /*
+ * Make sure we clear all existing interrupts
+ */
+ writel(0, vic_base + VIC_VECT_ADDR);
+ for (i = 0; i < 19; i++) {
+ unsigned int value;
+
+ value = readl(vic_base + VIC_VECT_ADDR);
+ writel(value, vic_base + VIC_VECT_ADDR);
+ }
+
+ for (i = 0; i < 16; i++) {
+ void __iomem *reg = vic_base + VIC_VECT_CNTL0 + (i * 4);
+ writel(VIC_VECT_CNTL_ENABLE | i, reg);
+ }
+
+ writel(32, vic_base + VIC_DEF_VECT_ADDR);
+
+ for (i = 0; i < 32; i++) {
+ unsigned int irq = IRQ_VIC_START + i;
+
+ set_irq_chip(irq, &vic_chip);
+
+ if (vic_sources & (1 << i)) {
+ set_irq_handler(irq, do_level_IRQ);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+ }
+}
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index de94b0f..2ce0e3a 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -20,6 +20,7 @@
obj-$(CONFIG_ISA_DMA) += dma-isa.o
obj-$(CONFIG_PCI) += bios32.o
obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
obj-$(CONFIG_IWMMXT) += iwmmxt.o
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 9997098..1574941 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -35,6 +35,16 @@
extern void __umodsi3(void);
extern void __do_div64(void);
+extern void __aeabi_idiv(void);
+extern void __aeabi_idivmod(void);
+extern void __aeabi_lasr(void);
+extern void __aeabi_llsl(void);
+extern void __aeabi_llsr(void);
+extern void __aeabi_lmul(void);
+extern void __aeabi_uidiv(void);
+extern void __aeabi_uidivmod(void);
+extern void __aeabi_ulcmp(void);
+
extern void fpundefinstr(void);
extern void fp_enter(void);
@@ -141,6 +151,18 @@
EXPORT_SYMBOL(__umodsi3);
EXPORT_SYMBOL(__do_div64);
+#ifdef CONFIG_AEABI
+EXPORT_SYMBOL(__aeabi_idiv);
+EXPORT_SYMBOL(__aeabi_idivmod);
+EXPORT_SYMBOL(__aeabi_lasr);
+EXPORT_SYMBOL(__aeabi_llsl);
+EXPORT_SYMBOL(__aeabi_llsr);
+EXPORT_SYMBOL(__aeabi_lmul);
+EXPORT_SYMBOL(__aeabi_uidiv);
+EXPORT_SYMBOL(__aeabi_uidivmod);
+EXPORT_SYMBOL(__aeabi_ulcmp);
+#endif
+
/* bitops */
EXPORT_SYMBOL(_set_bit_le);
EXPORT_SYMBOL(_test_and_set_bit_le);
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 55076a7..75e6f9a 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -13,7 +13,7 @@
#define NR_syscalls 328
#else
-__syscall_start:
+100:
/* 0 */ .long sys_restart_syscall
.long sys_exit
.long sys_fork_wrapper
@@ -27,7 +27,7 @@
/* 10 */ .long sys_unlink
.long sys_execve_wrapper
.long sys_chdir
- .long sys_time /* used by libc4 */
+ .long OBSOLETE(sys_time) /* used by libc4 */
.long sys_mknod
/* 15 */ .long sys_chmod
.long sys_lchown16
@@ -36,15 +36,15 @@
.long sys_lseek
/* 20 */ .long sys_getpid
.long sys_mount
- .long sys_oldumount /* used by libc4 */
+ .long OBSOLETE(sys_oldumount) /* used by libc4 */
.long sys_setuid16
.long sys_getuid16
-/* 25 */ .long sys_stime
+/* 25 */ .long OBSOLETE(sys_stime)
.long sys_ptrace
- .long sys_alarm /* used by libc4 */
+ .long OBSOLETE(sys_alarm) /* used by libc4 */
.long sys_ni_syscall /* was sys_fstat */
.long sys_pause
-/* 30 */ .long sys_utime /* used by libc4 */
+/* 30 */ .long OBSOLETE(sys_utime) /* used by libc4 */
.long sys_ni_syscall /* was sys_stty */
.long sys_ni_syscall /* was sys_getty */
.long sys_access
@@ -90,21 +90,21 @@
.long sys_sigpending
.long sys_sethostname
/* 75 */ .long sys_setrlimit
- .long sys_old_getrlimit /* used by libc4 */
+ .long OBSOLETE(sys_old_getrlimit) /* used by libc4 */
.long sys_getrusage
.long sys_gettimeofday
.long sys_settimeofday
/* 80 */ .long sys_getgroups16
.long sys_setgroups16
- .long old_select /* used by libc4 */
+ .long OBSOLETE(old_select) /* used by libc4 */
.long sys_symlink
.long sys_ni_syscall /* was sys_lstat */
/* 85 */ .long sys_readlink
.long sys_uselib
.long sys_swapon
.long sys_reboot
- .long old_readdir /* used by libc4 */
-/* 90 */ .long old_mmap /* used by libc4 */
+ .long OBSOLETE(old_readdir) /* used by libc4 */
+/* 90 */ .long OBSOLETE(old_mmap) /* used by libc4 */
.long sys_munmap
.long sys_truncate
.long sys_ftruncate
@@ -116,7 +116,7 @@
.long sys_statfs
/* 100 */ .long sys_fstatfs
.long sys_ni_syscall
- .long sys_socketcall
+ .long OBSOLETE(sys_socketcall)
.long sys_syslog
.long sys_setitimer
/* 105 */ .long sys_getitimer
@@ -127,11 +127,11 @@
/* 110 */ .long sys_ni_syscall /* was sys_iopl */
.long sys_vhangup
.long sys_ni_syscall
- .long sys_syscall /* call a syscall */
+ .long OBSOLETE(sys_syscall) /* call a syscall */
.long sys_wait4
/* 115 */ .long sys_swapoff
.long sys_sysinfo
- .long sys_ipc
+ .long OBSOLETE(ABI(sys_ipc, sys_oabi_ipc))
.long sys_fsync
.long sys_sigreturn_wrapper
/* 120 */ .long sys_clone_wrapper
@@ -194,8 +194,8 @@
.long sys_rt_sigtimedwait
.long sys_rt_sigqueueinfo
.long sys_rt_sigsuspend_wrapper
-/* 180 */ .long sys_pread64
- .long sys_pwrite64
+/* 180 */ .long ABI(sys_pread64, sys_oabi_pread64)
+ .long ABI(sys_pwrite64, sys_oabi_pwrite64)
.long sys_chown16
.long sys_getcwd
.long sys_capget
@@ -207,11 +207,11 @@
/* 190 */ .long sys_vfork_wrapper
.long sys_getrlimit
.long sys_mmap2
- .long sys_truncate64
- .long sys_ftruncate64
-/* 195 */ .long sys_stat64
- .long sys_lstat64
- .long sys_fstat64
+ .long ABI(sys_truncate64, sys_oabi_truncate64)
+ .long ABI(sys_ftruncate64, sys_oabi_ftruncate64)
+/* 195 */ .long ABI(sys_stat64, sys_oabi_stat64)
+ .long ABI(sys_lstat64, sys_oabi_lstat64)
+ .long ABI(sys_fstat64, sys_oabi_fstat64)
.long sys_lchown
.long sys_getuid
/* 200 */ .long sys_getgid
@@ -235,11 +235,11 @@
.long sys_pivot_root
.long sys_mincore
/* 220 */ .long sys_madvise
- .long sys_fcntl64
+ .long ABI(sys_fcntl64, sys_oabi_fcntl64)
.long sys_ni_syscall /* TUX */
.long sys_ni_syscall
.long sys_gettid
-/* 225 */ .long sys_readahead
+/* 225 */ .long ABI(sys_readahead, sys_oabi_readahead)
.long sys_setxattr
.long sys_lsetxattr
.long sys_fsetxattr
@@ -265,8 +265,8 @@
.long sys_exit_group
.long sys_lookup_dcookie
/* 250 */ .long sys_epoll_create
- .long sys_epoll_ctl
- .long sys_epoll_wait
+ .long ABI(sys_epoll_ctl, sys_oabi_epoll_ctl)
+ .long ABI(sys_epoll_wait, sys_oabi_epoll_wait)
.long sys_remap_file_pages
.long sys_ni_syscall /* sys_set_thread_area */
/* 255 */ .long sys_ni_syscall /* sys_get_thread_area */
@@ -280,8 +280,8 @@
.long sys_clock_gettime
.long sys_clock_getres
/* 265 */ .long sys_clock_nanosleep
- .long sys_statfs64
- .long sys_fstatfs64
+ .long sys_statfs64_wrapper
+ .long sys_fstatfs64_wrapper
.long sys_tgkill
.long sys_utimes
/* 270 */ .long sys_arm_fadvise64_64
@@ -312,7 +312,7 @@
/* 295 */ .long sys_getsockopt
.long sys_sendmsg
.long sys_recvmsg
- .long sys_semop
+ .long ABI(sys_semop, sys_oabi_semop)
.long sys_semget
/* 300 */ .long sys_semctl
.long sys_msgsnd
@@ -326,7 +326,7 @@
.long sys_add_key
/* 310 */ .long sys_request_key
.long sys_keyctl
- .long sys_semtimedop
+ .long ABI(sys_semtimedop, sys_oabi_semtimedop)
/* vserver */ .long sys_ni_syscall
.long sys_ioprio_set
/* 315 */ .long sys_ioprio_get
@@ -336,9 +336,8 @@
.long sys_mbind
/* 320 */ .long sys_get_mempolicy
.long sys_set_mempolicy
-__syscall_end:
- .rept NR_syscalls - (__syscall_end - __syscall_start) / 4
+ .rept NR_syscalls - (. - 100b) / 4
.long sys_ni_syscall
.endr
#endif
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index a52baed..874e6bb 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -3,6 +3,7 @@
*
* Copyright (C) 1996,1997,1998 Russell King.
* ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk)
+ * nommu support by Hyok S. Choi (hyok.choi@samsung.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -104,14 +105,24 @@
/*
* SVC mode handlers
*/
+
+#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5)
+#define SPFIX(code...) code
+#else
+#define SPFIX(code...)
+#endif
+
.macro svc_entry
sub sp, sp, #S_FRAME_SIZE
+ SPFIX( tst sp, #4 )
+ SPFIX( bicne sp, sp, #4 )
stmib sp, {r1 - r12}
ldmia r0, {r1 - r3}
add r5, sp, #S_SP @ here for interlock avoidance
mov r4, #-1 @ "" "" "" ""
add r0, sp, #S_FRAME_SIZE @ "" "" "" ""
+ SPFIX( addne r0, r0, #4 )
str r1, [sp] @ save the "real" r0 copied
@ from the exception stack
@@ -302,7 +313,14 @@
/*
* User mode handlers
+ *
+ * EABI note: sp_svc is always 64-bit aligned here, so should S_FRAME_SIZE
*/
+
+#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) && (S_FRAME_SIZE & 7)
+#error "sizeof(struct pt_regs) must be a multiple of 8"
+#endif
+
.macro usr_entry
sub sp, sp, #S_FRAME_SIZE
stmib sp, {r1 - r12}
@@ -538,7 +556,11 @@
add ip, r1, #TI_CPU_SAVE
ldr r3, [r2, #TI_TP_VALUE]
stmia ip!, {r4 - sl, fp, sp, lr} @ Store most regs on stack
+#ifndef CONFIG_MMU
+ add r2, r2, #TI_CPU_DOMAIN
+#else
ldr r6, [r2, #TI_CPU_DOMAIN]!
+#endif
#if __LINUX_ARM_ARCH__ >= 6
#ifdef CONFIG_CPU_MPCORE
clrex
@@ -556,7 +578,9 @@
mov r4, #0xffff0fff
str r3, [r4, #-15] @ TLS val at 0xffff0ff0
#endif
+#ifdef CONFIG_MMU
mcr p15, 0, r6, c3, c0, 0 @ Set domain register
+#endif
#ifdef CONFIG_VFP
@ Always disable VFP so we can lazily save/restore the old
@ 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 e2b4299..2b92ce8 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -98,20 +98,14 @@
run on an ARM7 and we can save a couple of instructions.
--pb */
#ifdef CONFIG_CPU_ARM710
- .macro arm710_bug_check, instr, temp
- and \temp, \instr, #0x0f000000 @ check for SWI
- teq \temp, #0x0f000000
- bne .Larm700bug
- .endm
-
-.Larm700bug:
+#define A710(code...) code
+.Larm710bug:
ldmia sp, {r0 - lr}^ @ Get calling r0 - lr
mov r0, r0
add sp, sp, #S_FRAME_SIZE
subs pc, lr, #4
#else
- .macro arm710_bug_check, instr, temp
- .endm
+#define A710(code...)
#endif
.align 5
@@ -129,14 +123,50 @@
/*
* Get the system call number.
*/
+
+#if defined(CONFIG_OABI_COMPAT)
+
+ /*
+ * If we have CONFIG_OABI_COMPAT then we need to look at the swi
+ * value to determine if it is an EABI or an old ABI call.
+ */
#ifdef CONFIG_ARM_THUMB
+ tst r8, #PSR_T_BIT
+ movne r10, #0 @ no thumb OABI emulation
+ ldreq r10, [lr, #-4] @ get SWI instruction
+#else
+ ldr r10, [lr, #-4] @ get SWI instruction
+ A710( and ip, r10, #0x0f000000 @ check for SWI )
+ A710( teq ip, #0x0f000000 )
+ A710( bne .Larm710bug )
+#endif
+
+#elif defined(CONFIG_AEABI)
+
+ /*
+ * Pure EABI user space always put syscall number into scno (r7).
+ */
+ A710( ldr ip, [lr, #-4] @ get SWI instruction )
+ A710( and ip, ip, #0x0f000000 @ check for SWI )
+ A710( teq ip, #0x0f000000 )
+ A710( bne .Larm710bug )
+
+#elif defined(CONFIG_ARM_THUMB)
+
+ /* Legacy ABI only, possibly thumb mode. */
tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs
addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in
ldreq scno, [lr, #-4]
+
#else
+
+ /* Legacy ABI only. */
ldr scno, [lr, #-4] @ get SWI instruction
+ A710( and ip, scno, #0x0f000000 @ check for SWI )
+ A710( teq ip, #0x0f000000 )
+ A710( bne .Larm710bug )
+
#endif
- arm710_bug_check scno, ip
#ifdef CONFIG_ALIGNMENT_TRAP
ldr ip, __cr_alignment
@@ -145,18 +175,31 @@
#endif
enable_irq
- stmdb sp!, {r4, r5} @ push fifth and sixth args
-
get_thread_info tsk
+ adr tbl, sys_call_table @ load syscall table pointer
ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
+
+#if defined(CONFIG_OABI_COMPAT)
+ /*
+ * If the swi argument is zero, this is an EABI call and we do nothing.
+ *
+ * If this is an old ABI call, get the syscall number into scno and
+ * get the old ABI syscall table address.
+ */
+ bics r10, r10, #0xff000000
+ eorne scno, r10, #__NR_OABI_SYSCALL_BASE
+ ldrne tbl, =sys_oabi_call_table
+#elif !defined(CONFIG_AEABI)
bic scno, scno, #0xff000000 @ mask off SWI op-code
eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
- adr tbl, sys_call_table @ load syscall table pointer
+#endif
+
+ stmdb sp!, {r4, r5} @ push fifth and sixth args
tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
bne __sys_trace
- adr lr, ret_fast_syscall @ return address
cmp scno, #NR_syscalls @ check upper syscall limit
+ adr lr, ret_fast_syscall @ return address
ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
add r1, sp, #S_OFF
@@ -171,11 +214,13 @@
* context switches, and waiting for our parent to respond.
*/
__sys_trace:
+ mov r2, scno
add r1, sp, #S_OFF
mov r0, #0 @ trace entry [IP = 0]
bl syscall_trace
adr lr, __sys_trace_return @ return address
+ mov scno, r0 @ syscall number (possibly new)
add r1, sp, #S_R0 + S_OFF @ pointer to regs
cmp scno, #NR_syscalls @ check upper syscall limit
ldmccia r1, {r0 - r3} @ have to reload r0 - r3
@@ -184,6 +229,7 @@
__sys_trace_return:
str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
+ mov r2, scno
mov r1, sp
mov r0, #1 @ trace exit [IP = 1]
bl syscall_trace
@@ -195,10 +241,24 @@
__cr_alignment:
.word cr_alignment
#endif
+ .ltorg
+
+/*
+ * This is the syscall table declaration for native ABI syscalls.
+ * With EABI a couple syscalls are obsolete and defined as sys_ni_syscall.
+ */
+#define ABI(native, compat) native
+#ifdef CONFIG_AEABI
+#define OBSOLETE(syscall) sys_ni_syscall
+#else
+#define OBSOLETE(syscall) syscall
+#endif
.type sys_call_table, #object
ENTRY(sys_call_table)
#include "calls.S"
+#undef ABI
+#undef OBSOLETE
/*============================================================================
* Special system call wrappers
@@ -207,7 +267,7 @@
@ r8 = syscall table
.type sys_syscall, #function
sys_syscall:
- eor scno, r0, #__NR_SYSCALL_BASE
+ eor scno, r0, #__NR_OABI_SYSCALL_BASE
cmp scno, #__NR_syscall - __NR_SYSCALL_BASE
cmpne scno, #NR_syscalls @ check range
stmloia sp, {r5, r6} @ shuffle args
@@ -255,6 +315,16 @@
ldr r2, [sp, #S_OFF + S_SP]
b do_sigaltstack
+sys_statfs64_wrapper:
+ teq r1, #88
+ moveq r1, #84
+ b sys_statfs64
+
+sys_fstatfs64_wrapper:
+ teq r1, #88
+ moveq r1, #84
+ b sys_fstatfs64
+
/*
* Note: off_4k (r5) is always units of 4K. If we can't do the requested
* offset, we return EINVAL.
@@ -271,3 +341,49 @@
str r5, [sp, #4]
b do_mmap2
#endif
+
+#ifdef CONFIG_OABI_COMPAT
+
+/*
+ * These are syscalls with argument register differences
+ */
+
+sys_oabi_pread64:
+ stmia sp, {r3, r4}
+ b sys_pread64
+
+sys_oabi_pwrite64:
+ stmia sp, {r3, r4}
+ b sys_pwrite64
+
+sys_oabi_truncate64:
+ mov r3, r2
+ mov r2, r1
+ b sys_truncate64
+
+sys_oabi_ftruncate64:
+ mov r3, r2
+ mov r2, r1
+ b sys_ftruncate64
+
+sys_oabi_readahead:
+ str r3, [sp]
+ mov r3, r2
+ mov r2, r1
+ b sys_readahead
+
+/*
+ * Let's declare a second syscall table for old ABI binaries
+ * using the compatibility syscall entries.
+ */
+#define ABI(native, compat) compat
+#define OBSOLETE(syscall) syscall
+
+ .type sys_oabi_call_table, #object
+ENTRY(sys_oabi_call_table)
+#include "calls.S"
+#undef ABI
+#undef OBSOLETE
+
+#endif
+
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 648cfff..55c99cd 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -19,6 +19,7 @@
@
@ Most of the stack format comes from struct pt_regs, but with
@ the addition of 8 bytes for storing syscall args 5 and 6.
+@ This _must_ remain a multiple of 8 for EABI.
@
#define S_OFF 8
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 1e985f2..1aca1775 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -251,12 +251,11 @@
* r10 = procinfo
*
* Returns:
- * r0, r3, r5, r6, r7 corrupted
+ * r0, r3, r6, r7 corrupted
* r4 = physical page table address
*/
.type __create_page_tables, %function
__create_page_tables:
- ldr r5, [r8, #MACHINFO_PHYSRAM] @ physram
pgtbl r4 @ page table address
/*
@@ -303,7 +302,7 @@
* Then map first 1MB of ram in case it contains our boot params.
*/
add r0, r4, #PAGE_OFFSET >> 18
- orr r6, r5, r7
+ orr r6, r7, #PHYS_OFFSET
str r6, [r0]
#ifdef CONFIG_XIP_KERNEL
@@ -311,7 +310,7 @@
* Map some ram to cover our .data and .bss areas.
* Mapping 3MB should be plenty.
*/
- sub r3, r4, r5
+ sub r3, r4, #PHYS_OFFSET
mov r3, r3, lsr #20
add r0, r0, r3, lsl #2
add r6, r6, r3, lsl #20
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index e591f72b..7b6256b 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -766,6 +766,11 @@
(unsigned long __user *) data);
break;
+ case PTRACE_SET_SYSCALL:
+ ret = 0;
+ child->ptrace_message = data;
+ break;
+
default:
ret = ptrace_request(child, request, addr, data);
break;
@@ -774,14 +779,14 @@
return ret;
}
-asmlinkage void syscall_trace(int why, struct pt_regs *regs)
+asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
{
unsigned long ip;
if (!test_thread_flag(TIF_SYSCALL_TRACE))
- return;
+ return scno;
if (!(current->ptrace & PT_PTRACED))
- return;
+ return scno;
/*
* Save IP. IP is used to denote syscall entry/exit:
@@ -790,6 +795,8 @@
ip = regs->ARM_ip;
regs->ARM_ip = why;
+ current->ptrace_message = scno;
+
/* the 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
@@ -804,4 +811,6 @@
current->exit_code = 0;
}
regs->ARM_ip = ip;
+
+ return current->ptrace_message;
}
diff --git a/arch/arm/kernel/semaphore.c b/arch/arm/kernel/semaphore.c
index 4c31f29..981fe5c 100644
--- a/arch/arm/kernel/semaphore.c
+++ b/arch/arm/kernel/semaphore.c
@@ -177,41 +177,42 @@
* ip contains the semaphore pointer on entry. Save the C-clobbered
* registers (r0 to r3 and lr), but not ip, as we use it as a return
* value in some cases..
+ * To remain AAPCS compliant (64-bit stack align) we save r4 as well.
*/
asm(" .section .sched.text,\"ax\",%progbits \n\
.align 5 \n\
.globl __down_failed \n\
__down_failed: \n\
- stmfd sp!, {r0 - r3, lr} \n\
+ stmfd sp!, {r0 - r4, lr} \n\
mov r0, ip \n\
bl __down \n\
- ldmfd sp!, {r0 - r3, pc} \n\
+ ldmfd sp!, {r0 - r4, pc} \n\
\n\
.align 5 \n\
.globl __down_interruptible_failed \n\
__down_interruptible_failed: \n\
- stmfd sp!, {r0 - r3, lr} \n\
+ stmfd sp!, {r0 - r4, lr} \n\
mov r0, ip \n\
bl __down_interruptible \n\
mov ip, r0 \n\
- ldmfd sp!, {r0 - r3, pc} \n\
+ ldmfd sp!, {r0 - r4, pc} \n\
\n\
.align 5 \n\
.globl __down_trylock_failed \n\
__down_trylock_failed: \n\
- stmfd sp!, {r0 - r3, lr} \n\
+ stmfd sp!, {r0 - r4, lr} \n\
mov r0, ip \n\
bl __down_trylock \n\
mov ip, r0 \n\
- ldmfd sp!, {r0 - r3, pc} \n\
+ ldmfd sp!, {r0 - r4, pc} \n\
\n\
.align 5 \n\
.globl __up_wakeup \n\
__up_wakeup: \n\
- stmfd sp!, {r0 - r3, lr} \n\
+ stmfd sp!, {r0 - r4, lr} \n\
mov r0, ip \n\
bl __up \n\
- ldmfd sp!, {r0 - r3, pc} \n\
+ ldmfd sp!, {r0 - r4, pc} \n\
");
EXPORT_SYMBOL(__down_failed);
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index ea569ba..a491de2 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -147,6 +147,7 @@
return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
}
+#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
/*
* sys_ipc() is the de-multiplexer for the SysV IPC calls..
*
@@ -226,6 +227,7 @@
return -ENOSYS;
}
}
+#endif
/* Fork a new task - this creates a new program thread.
* 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 0000000..eafa8e5
--- /dev/null
+++ b/arch/arm/kernel/sys_oabi-compat.c
@@ -0,0 +1,339 @@
+/*
+ * arch/arm/kernel/sys_oabi-compat.c
+ *
+ * Compatibility wrappers for syscalls that are used from
+ * old ABI user space binaries with an EABI kernel.
+ *
+ * Author: Nicolas Pitre
+ * Created: Oct 7, 2005
+ * Copyright: MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * The legacy ABI and the new ARM EABI have different rules making some
+ * syscalls incompatible especially with structure arguments.
+ * Most notably, Eabi says 64-bit members should be 64-bit aligned instead of
+ * simply word aligned. EABI also pads structures to the size of the largest
+ * member it contains instead of the invariant 32-bit.
+ *
+ * The following syscalls are affected:
+ *
+ * sys_stat64:
+ * sys_lstat64:
+ * sys_fstat64:
+ *
+ * struct stat64 has different sizes and some members are shifted
+ * Compatibility wrappers are needed for them and provided below.
+ *
+ * sys_fcntl64:
+ *
+ * struct flock64 has different sizes and some members are shifted
+ * A compatibility wrapper is needed and provided below.
+ *
+ * sys_statfs64:
+ * sys_fstatfs64:
+ *
+ * struct statfs64 has extra padding with EABI growing its size from
+ * 84 to 88. This struct is now __attribute__((packed,aligned(4)))
+ * with a small assembly wrapper to force the sz argument to 84 if it is 88
+ * to avoid copying the extra padding over user space unexpecting it.
+ *
+ * sys_newuname:
+ *
+ * struct new_utsname has no padding with EABI. No problem there.
+ *
+ * sys_epoll_ctl:
+ * sys_epoll_wait:
+ *
+ * struct epoll_event has its second member shifted also affecting the
+ * structure size. Compatibility wrappers are needed and provided below.
+ *
+ * sys_ipc:
+ * sys_semop:
+ * sys_semtimedop:
+ *
+ * struct sembuf loses its padding with EABI. Since arrays of them are
+ * used they have to be copyed to remove the padding. Compatibility wrappers
+ * provided below.
+ */
+
+#include <linux/syscalls.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/fcntl.h>
+#include <linux/eventpoll.h>
+#include <linux/sem.h>
+#include <asm/ipc.h>
+#include <asm/uaccess.h>
+
+struct oldabi_stat64 {
+ unsigned long long st_dev;
+ unsigned int __pad1;
+ unsigned long __st_ino;
+ unsigned int st_mode;
+ unsigned int st_nlink;
+
+ unsigned long st_uid;
+ unsigned long st_gid;
+
+ unsigned long long st_rdev;
+ unsigned int __pad2;
+
+ long long st_size;
+ unsigned long st_blksize;
+ unsigned long long st_blocks;
+
+ unsigned long st_atime;
+ unsigned long st_atime_nsec;
+
+ unsigned long st_mtime;
+ unsigned long st_mtime_nsec;
+
+ unsigned long st_ctime;
+ unsigned long st_ctime_nsec;
+
+ unsigned long long st_ino;
+} __attribute__ ((packed,aligned(4)));
+
+static long cp_oldabi_stat64(struct kstat *stat,
+ struct oldabi_stat64 __user *statbuf)
+{
+ struct oldabi_stat64 tmp;
+
+ tmp.st_dev = huge_encode_dev(stat->dev);
+ tmp.__pad1 = 0;
+ tmp.__st_ino = stat->ino;
+ tmp.st_mode = stat->mode;
+ tmp.st_nlink = stat->nlink;
+ tmp.st_uid = stat->uid;
+ tmp.st_gid = stat->gid;
+ tmp.st_rdev = huge_encode_dev(stat->rdev);
+ tmp.st_size = stat->size;
+ tmp.st_blocks = stat->blocks;
+ tmp.__pad2 = 0;
+ tmp.st_blksize = stat->blksize;
+ tmp.st_atime = stat->atime.tv_sec;
+ tmp.st_atime_nsec = stat->atime.tv_nsec;
+ tmp.st_mtime = stat->mtime.tv_sec;
+ tmp.st_mtime_nsec = stat->mtime.tv_nsec;
+ tmp.st_ctime = stat->ctime.tv_sec;
+ tmp.st_ctime_nsec = stat->ctime.tv_nsec;
+ tmp.st_ino = stat->ino;
+ return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
+}
+
+asmlinkage long sys_oabi_stat64(char __user * filename,
+ struct oldabi_stat64 __user * statbuf)
+{
+ struct kstat stat;
+ int error = vfs_stat(filename, &stat);
+ if (!error)
+ error = cp_oldabi_stat64(&stat, statbuf);
+ return error;
+}
+
+asmlinkage long sys_oabi_lstat64(char __user * filename,
+ struct oldabi_stat64 __user * statbuf)
+{
+ struct kstat stat;
+ int error = vfs_lstat(filename, &stat);
+ if (!error)
+ error = cp_oldabi_stat64(&stat, statbuf);
+ return error;
+}
+
+asmlinkage long sys_oabi_fstat64(unsigned long fd,
+ struct oldabi_stat64 __user * statbuf)
+{
+ struct kstat stat;
+ int error = vfs_fstat(fd, &stat);
+ if (!error)
+ error = cp_oldabi_stat64(&stat, statbuf);
+ return error;
+}
+
+struct oabi_flock64 {
+ short l_type;
+ short l_whence;
+ loff_t l_start;
+ loff_t l_len;
+ pid_t l_pid;
+} __attribute__ ((packed,aligned(4)));
+
+asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
+ unsigned long arg)
+{
+ struct oabi_flock64 user;
+ struct flock64 kernel;
+ mm_segment_t fs = USER_DS; /* initialized to kill a warning */
+ unsigned long local_arg = arg;
+ int ret;
+
+ switch (cmd) {
+ case F_GETLK64:
+ case F_SETLK64:
+ case F_SETLKW64:
+ if (copy_from_user(&user, (struct oabi_flock64 __user *)arg,
+ sizeof(user)))
+ return -EFAULT;
+ kernel.l_type = user.l_type;
+ kernel.l_whence = user.l_whence;
+ kernel.l_start = user.l_start;
+ kernel.l_len = user.l_len;
+ kernel.l_pid = user.l_pid;
+ local_arg = (unsigned long)&kernel;
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ }
+
+ ret = sys_fcntl64(fd, cmd, local_arg);
+
+ switch (cmd) {
+ case F_GETLK64:
+ if (!ret) {
+ user.l_type = kernel.l_type;
+ user.l_whence = kernel.l_whence;
+ user.l_start = kernel.l_start;
+ user.l_len = kernel.l_len;
+ user.l_pid = kernel.l_pid;
+ if (copy_to_user((struct oabi_flock64 __user *)arg,
+ &user, sizeof(user)))
+ ret = -EFAULT;
+ }
+ case F_SETLK64:
+ case F_SETLKW64:
+ set_fs(fs);
+ }
+
+ return ret;
+}
+
+struct oabi_epoll_event {
+ __u32 events;
+ __u64 data;
+} __attribute__ ((packed,aligned(4)));
+
+asmlinkage long sys_oabi_epoll_ctl(int epfd, int op, int fd,
+ struct oabi_epoll_event __user *event)
+{
+ struct oabi_epoll_event user;
+ struct epoll_event kernel;
+ mm_segment_t fs;
+ long ret;
+
+ if (op == EPOLL_CTL_DEL)
+ return sys_epoll_ctl(epfd, op, fd, NULL);
+ if (copy_from_user(&user, event, sizeof(user)))
+ return -EFAULT;
+ kernel.events = user.events;
+ kernel.data = user.data;
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ ret = sys_epoll_ctl(epfd, op, fd, &kernel);
+ set_fs(fs);
+ return ret;
+}
+
+asmlinkage long sys_oabi_epoll_wait(int epfd,
+ struct oabi_epoll_event __user *events,
+ int maxevents, int timeout)
+{
+ struct epoll_event *kbuf;
+ mm_segment_t fs;
+ long ret, err, i;
+
+ if (maxevents <= 0 || maxevents > (INT_MAX/sizeof(struct epoll_event)))
+ return -EINVAL;
+ kbuf = kmalloc(sizeof(*kbuf) * maxevents, GFP_KERNEL);
+ if (!kbuf)
+ return -ENOMEM;
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ ret = sys_epoll_wait(epfd, kbuf, maxevents, timeout);
+ set_fs(fs);
+ err = 0;
+ for (i = 0; i < ret; i++) {
+ __put_user_error(kbuf[i].events, &events->events, err);
+ __put_user_error(kbuf[i].data, &events->data, err);
+ events++;
+ }
+ kfree(kbuf);
+ return err ? -EFAULT : ret;
+}
+
+struct oabi_sembuf {
+ unsigned short sem_num;
+ short sem_op;
+ short sem_flg;
+ unsigned short __pad;
+};
+
+asmlinkage long sys_oabi_semtimedop(int semid,
+ struct oabi_sembuf __user *tsops,
+ unsigned nsops,
+ const struct timespec __user *timeout)
+{
+ struct sembuf *sops;
+ struct timespec local_timeout;
+ long err;
+ int i;
+
+ if (nsops < 1)
+ return -EINVAL;
+ sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL);
+ if (!sops)
+ return -ENOMEM;
+ err = 0;
+ for (i = 0; i < nsops; i++) {
+ __get_user_error(sops[i].sem_num, &tsops->sem_num, err);
+ __get_user_error(sops[i].sem_op, &tsops->sem_op, err);
+ __get_user_error(sops[i].sem_flg, &tsops->sem_flg, err);
+ tsops++;
+ }
+ if (timeout) {
+ /* copy this as well before changing domain protection */
+ err |= copy_from_user(&local_timeout, timeout, sizeof(*timeout));
+ timeout = &local_timeout;
+ }
+ if (err) {
+ err = -EFAULT;
+ } else {
+ mm_segment_t fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_semtimedop(semid, sops, nsops, timeout);
+ set_fs(fs);
+ }
+ kfree(sops);
+ return err;
+}
+
+asmlinkage long sys_oabi_semop(int semid, struct oabi_sembuf __user *tsops,
+ unsigned nsops)
+{
+ return sys_oabi_semtimedop(semid, tsops, nsops, NULL);
+}
+
+extern asmlinkage int sys_ipc(uint call, int first, int second, int third,
+ void __user *ptr, long fifth);
+
+asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third,
+ void __user *ptr, long fifth)
+{
+ switch (call & 0xffff) {
+ case SEMOP:
+ return sys_oabi_semtimedop(first,
+ (struct oabi_sembuf __user *)ptr,
+ second, NULL);
+ case SEMTIMEDOP:
+ return sys_oabi_semtimedop(first,
+ (struct oabi_sembuf __user *)ptr,
+ second,
+ (const struct timespec __user *)fifth);
+ default:
+ return sys_ipc(call, first, second, third, ptr, fifth);
+ }
+}
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 93cfd3f..10235b0 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -404,7 +404,7 @@
struct thread_info *thread = current_thread_info();
siginfo_t info;
- if ((no >> 16) != 0x9f)
+ if ((no >> 16) != (__ARM_NR_BASE>> 16))
return bad_syscall(no, regs);
switch (no & 0xffff) {
diff --git a/arch/arm/lib/ashldi3.S b/arch/arm/lib/ashldi3.S
index 561e207..55e57a1c 100644
--- a/arch/arm/lib/ashldi3.S
+++ b/arch/arm/lib/ashldi3.S
@@ -37,6 +37,7 @@
#endif
ENTRY(__ashldi3)
+ENTRY(__aeabi_llsl)
subs r3, r2, #32
rsb ip, r2, #32
diff --git a/arch/arm/lib/ashrdi3.S b/arch/arm/lib/ashrdi3.S
index 86fb2a9..0b31398 100644
--- a/arch/arm/lib/ashrdi3.S
+++ b/arch/arm/lib/ashrdi3.S
@@ -37,6 +37,7 @@
#endif
ENTRY(__ashrdi3)
+ENTRY(__aeabi_lasr)
subs r3, r2, #32
rsb ip, r2, #32
diff --git a/arch/arm/lib/lib1funcs.S b/arch/arm/lib/lib1funcs.S
index 5902602..4e492f4 100644
--- a/arch/arm/lib/lib1funcs.S
+++ b/arch/arm/lib/lib1funcs.S
@@ -206,6 +206,7 @@
ENTRY(__udivsi3)
+ENTRY(__aeabi_uidiv)
subs r2, r1, #1
moveq pc, lr
@@ -246,6 +247,7 @@
ENTRY(__divsi3)
+ENTRY(__aeabi_idiv)
cmp r1, #0
eor ip, r0, r1 @ save the sign of the result.
@@ -303,12 +305,33 @@
rsbmi r0, r0, #0
mov pc, lr
+#ifdef CONFIG_AEABI
+
+ENTRY(__aeabi_uidivmod)
+
+ stmfd sp!, {r0, r1, ip, lr}
+ bl __aeabi_uidiv
+ ldmfd sp!, {r1, r2, ip, lr}
+ mul r3, r0, r2
+ sub r1, r1, r3
+ mov pc, lr
+
+ENTRY(__aeabi_idivmod)
+
+ stmfd sp!, {r0, r1, ip, lr}
+ bl __aeabi_idiv
+ ldmfd sp!, {r1, r2, ip, lr}
+ mul r3, r0, r2
+ sub r1, r1, r3
+ mov pc, lr
+
+#endif
Ldiv0:
- str lr, [sp, #-4]!
+ str lr, [sp, #-8]!
bl __div0
mov r0, #0 @ About as wrong as it could be.
- ldr pc, [sp], #4
+ ldr pc, [sp], #8
diff --git a/arch/arm/lib/lshrdi3.S b/arch/arm/lib/lshrdi3.S
index 46c2ed1..a86dbdd 100644
--- a/arch/arm/lib/lshrdi3.S
+++ b/arch/arm/lib/lshrdi3.S
@@ -37,6 +37,7 @@
#endif
ENTRY(__lshrdi3)
+ENTRY(__aeabi_llsr)
subs r3, r2, #32
rsb ip, r2, #32
diff --git a/arch/arm/lib/muldi3.S b/arch/arm/lib/muldi3.S
index c7fbdf0..72d5941 100644
--- a/arch/arm/lib/muldi3.S
+++ b/arch/arm/lib/muldi3.S
@@ -25,6 +25,7 @@
#endif
ENTRY(__muldi3)
+ENTRY(__aeabi_lmul)
mul xh, yl, xh
mla xh, xl, yh, xh
diff --git a/arch/arm/lib/ucmpdi2.S b/arch/arm/lib/ucmpdi2.S
index 112630f..d847a62 100644
--- a/arch/arm/lib/ucmpdi2.S
+++ b/arch/arm/lib/ucmpdi2.S
@@ -10,6 +10,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/config.h>
#include <linux/linkage.h>
#ifdef __ARMEB__
@@ -33,3 +34,16 @@
movhi r0, #2
mov pc, lr
+#ifdef CONFIG_AEABI
+
+ENTRY(__aeabi_ulcmp)
+
+ cmp xh, yh
+ cmpeq xl, yl
+ movlo r0, #-1
+ moveq r0, #0
+ movhi r0, #1
+ mov pc, lr
+
+#endif
+
diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c
index f5ef697..dc5fa8e 100644
--- a/arch/arm/mach-aaec2000/aaed2000.c
+++ b/arch/arm/mach-aaec2000/aaed2000.c
@@ -90,7 +90,6 @@
MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform")
/* Maintainer: Nicolas Bellido Y Ortega */
- .phys_ram = 0xf0000000,
.phys_io = PIO_BASE,
.io_pg_offst = ((VIO_BASE) >> 18) & 0xfffc,
.map_io = aaed2000_map_io,
diff --git a/arch/arm/mach-at91rm9200/board-csb337.c b/arch/arm/mach-at91rm9200/board-csb337.c
index 4aec834..54022e5 100644
--- a/arch/arm/mach-at91rm9200/board-csb337.c
+++ b/arch/arm/mach-at91rm9200/board-csb337.c
@@ -132,7 +132,6 @@
MACHINE_START(CSB337, "Cogent CSB337")
/* Maintainer: Bill Gatliff */
- .phys_ram = AT91_SDRAM_BASE,
.phys_io = AT91_BASE_SYS,
.io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.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 23e4cc2..8195f9d 100644
--- a/arch/arm/mach-at91rm9200/board-csb637.c
+++ b/arch/arm/mach-at91rm9200/board-csb637.c
@@ -105,7 +105,6 @@
MACHINE_START(CSB637, "Cogent CSB637")
/* Maintainer: Bill Gatliff */
- .phys_ram = AT91_SDRAM_BASE,
.phys_io = AT91_BASE_SYS,
.io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.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 8c747a3..8a78336 100644
--- a/arch/arm/mach-at91rm9200/board-dk.c
+++ b/arch/arm/mach-at91rm9200/board-dk.c
@@ -127,7 +127,6 @@
MACHINE_START(AT91RM9200DK, "Atmel AT91RM9200-DK")
/* Maintainer: SAN People/Atmel */
- .phys_ram = AT91_SDRAM_BASE,
.phys_io = AT91_BASE_SYS,
.io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.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 d140645..fd0752e 100644
--- a/arch/arm/mach-at91rm9200/board-ek.c
+++ b/arch/arm/mach-at91rm9200/board-ek.c
@@ -120,7 +120,6 @@
MACHINE_START(AT91RM9200EK, "Atmel AT91RM9200-EK")
/* Maintainer: SAN People/Atmel */
- .phys_ram = AT91_SDRAM_BASE,
.phys_io = AT91_BASE_SYS,
.io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c
index 43b9423..c13ca6c 100644
--- a/arch/arm/mach-clps711x/autcpu12.c
+++ b/arch/arm/mach-clps711x/autcpu12.c
@@ -64,7 +64,6 @@
MACHINE_START(AUTCPU12, "autronix autcpu12")
/* Maintainer: Thomas Gleixner */
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
.boot_params = 0xc0020000,
diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c
index cba7be5..831df00 100644
--- a/arch/arm/mach-clps711x/cdb89712.c
+++ b/arch/arm/mach-clps711x/cdb89712.c
@@ -55,7 +55,6 @@
MACHINE_START(CDB89712, "Cirrus-CDB89712")
/* Maintainer: Ray Lehtiniemi */
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
diff --git a/arch/arm/mach-clps711x/ceiva.c b/arch/arm/mach-clps711x/ceiva.c
index 35d51a7..e2b2c5a 100644
--- a/arch/arm/mach-clps711x/ceiva.c
+++ b/arch/arm/mach-clps711x/ceiva.c
@@ -56,7 +56,6 @@
MACHINE_START(CEIVA, "CEIVA/Polaroid Photo MAX Digital Picture Frame")
/* Maintainer: Rob Scott */
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
diff --git a/arch/arm/mach-clps711x/clep7312.c b/arch/arm/mach-clps711x/clep7312.c
index c83f3fd..09fb57e 100644
--- a/arch/arm/mach-clps711x/clep7312.c
+++ b/arch/arm/mach-clps711x/clep7312.c
@@ -38,7 +38,6 @@
MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312")
/* Maintainer: Nobody */
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c
index 255c98b..dc81cc6 100644
--- a/arch/arm/mach-clps711x/edb7211-arch.c
+++ b/arch/arm/mach-clps711x/edb7211-arch.c
@@ -52,7 +52,6 @@
MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
/* Maintainer: Jon McClintock */
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
.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 3d88da0..ff26a85 100644
--- a/arch/arm/mach-clps711x/fortunet.c
+++ b/arch/arm/mach-clps711x/fortunet.c
@@ -78,7 +78,6 @@
MACHINE_START(FORTUNET, "ARM-FortuNet")
/* Maintainer: FortuNet Inc. */
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xf0000000) >> 18) & 0xfffc,
.boot_params = 0x00000000,
diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c
index a1acb94..9ba45f4 100644
--- a/arch/arm/mach-clps711x/p720t.c
+++ b/arch/arm/mach-clps711x/p720t.c
@@ -90,7 +90,6 @@
MACHINE_START(P720T, "ARM-Prospector720T")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c
index d869af0..5b12cab 100644
--- a/arch/arm/mach-clps7500/core.c
+++ b/arch/arm/mach-clps7500/core.c
@@ -384,7 +384,6 @@
MACHINE_START(CLPS7500, "CL-PS7500")
/* Maintainer: Philip Blundell */
- .phys_ram = 0x10000000,
.phys_io = 0x03000000,
.io_pg_offst = ((0xe0000000) >> 18) & 0xfffc,
.map_io = clps7500_map_io,
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index ed46149..6d620d8 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -284,7 +284,6 @@
MACHINE_START(EBSA110, "EBSA110")
/* Maintainer: Russell King */
- .phys_ram = 0x00000000,
.phys_io = 0xe0000000,
.io_pg_offst = ((0xe0000000) >> 18) & 0xfffc,
.boot_params = 0x00000400,
diff --git a/arch/arm/mach-footbridge/cats-hw.c b/arch/arm/mach-footbridge/cats-hw.c
index 49b898a..5b64d5c 100644
--- a/arch/arm/mach-footbridge/cats-hw.c
+++ b/arch/arm/mach-footbridge/cats-hw.c
@@ -85,7 +85,6 @@
MACHINE_START(CATS, "Chalice-CATS")
/* Maintainer: Philip Blundell */
- .phys_ram = 0x00000000,
.phys_io = DC21285_ARMCSR_BASE,
.io_pg_offst = ((0xfe000000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
diff --git a/arch/arm/mach-footbridge/co285.c b/arch/arm/mach-footbridge/co285.c
index 548a790..4545576 100644
--- a/arch/arm/mach-footbridge/co285.c
+++ b/arch/arm/mach-footbridge/co285.c
@@ -29,7 +29,6 @@
MACHINE_START(CO285, "co-EBSA285")
/* Maintainer: Mark van Doesburg */
- .phys_ram = 0x00000000,
.phys_io = DC21285_ARMCSR_BASE,
.io_pg_offst = ((0x7cf00000) >> 18) & 0xfffc,
.fixup = fixup_coebsa285,
diff --git a/arch/arm/mach-footbridge/ebsa285.c b/arch/arm/mach-footbridge/ebsa285.c
index 1c37605..b1d3bf2 100644
--- a/arch/arm/mach-footbridge/ebsa285.c
+++ b/arch/arm/mach-footbridge/ebsa285.c
@@ -14,7 +14,6 @@
MACHINE_START(EBSA285, "EBSA285")
/* Maintainer: Russell King */
- .phys_ram = 0x00000000,
.phys_io = DC21285_ARMCSR_BASE,
.io_pg_offst = ((0xfe000000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c
index 9e563de..229bf05 100644
--- a/arch/arm/mach-footbridge/netwinder-hw.c
+++ b/arch/arm/mach-footbridge/netwinder-hw.c
@@ -649,7 +649,6 @@
MACHINE_START(NETWINDER, "Rebel-NetWinder")
/* Maintainer: Russell King/Rebel.com */
- .phys_ram = 0x00000000,
.phys_io = DC21285_ARMCSR_BASE,
.io_pg_offst = ((0xfe000000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
diff --git a/arch/arm/mach-footbridge/personal.c b/arch/arm/mach-footbridge/personal.c
index 0146b8b..c4f843f 100644
--- a/arch/arm/mach-footbridge/personal.c
+++ b/arch/arm/mach-footbridge/personal.c
@@ -14,7 +14,6 @@
MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer")
/* Maintainer: Jamey Hicks / George France */
- .phys_ram = 0x00000000,
.phys_io = DC21285_ARMCSR_BASE,
.io_pg_offst = ((0xfe000000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
diff --git a/arch/arm/mach-h720x/h7201-eval.c b/arch/arm/mach-h720x/h7201-eval.c
index fa59e9e..193f968 100644
--- a/arch/arm/mach-h720x/h7201-eval.c
+++ b/arch/arm/mach-h720x/h7201-eval.c
@@ -31,7 +31,6 @@
MACHINE_START(H7201, "Hynix GMS30C7201")
/* Maintainer: Robert Schwebel, Pengutronix */
- .phys_ram = 0x40000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xf0000000) >> 18) & 0xfffc,
.boot_params = 0xc0001000,
diff --git a/arch/arm/mach-h720x/h7202-eval.c b/arch/arm/mach-h720x/h7202-eval.c
index d75c822..3626689 100644
--- a/arch/arm/mach-h720x/h7202-eval.c
+++ b/arch/arm/mach-h720x/h7202-eval.c
@@ -72,7 +72,6 @@
MACHINE_START(H7202, "Hynix HMS30C7202")
/* Maintainer: Robert Schwebel, Pengutronix */
- .phys_ram = 0x40000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xf0000000) >> 18) & 0xfffc,
.boot_params = 0x40000100,
diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c
index c9e0cd8..dc31e3f 100644
--- a/arch/arm/mach-imx/mx1ads.c
+++ b/arch/arm/mach-imx/mx1ads.c
@@ -69,7 +69,6 @@
MACHINE_START(MX1ADS, "Motorola MX1ADS")
/* Maintainer: Sascha Hauer, Pengutronix */
- .phys_ram = 0x08000000,
.phys_io = 0x00200000,
.io_pg_offst = ((0xe0200000) >> 18) & 0xfffc,
.boot_params = 0x08000100,
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 3afedeb..d8d3c2a 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -347,7 +347,6 @@
MACHINE_START(INTEGRATOR, "ARM-Integrator")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_ram = 0x00000000,
.phys_io = 0x16000000,
.io_pg_offst = ((0xf1600000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 16cf248..3182017 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -578,7 +578,6 @@
MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_ram = 0x00000000,
.phys_io = 0x16000000,
.io_pg_offst = ((0xf1600000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
diff --git a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c
index 8077023..e4f4c52 100644
--- a/arch/arm/mach-iop3xx/iop321-setup.c
+++ b/arch/arm/mach-iop3xx/iop321-setup.c
@@ -151,7 +151,6 @@
#if defined(CONFIG_ARCH_IQ80321)
MACHINE_START(IQ80321, "Intel IQ80321")
/* Maintainer: Intel Corporation */
- .phys_ram = PHYS_OFFSET,
.phys_io = IQ80321_UART,
.io_pg_offst = ((IQ80321_UART) >> 18) & 0xfffc,
.map_io = iq80321_map_io,
@@ -163,7 +162,6 @@
#elif defined(CONFIG_ARCH_IQ31244)
MACHINE_START(IQ31244, "Intel IQ31244")
/* Maintainer: Intel Corp. */
- .phys_ram = PHYS_OFFSET,
.phys_io = IQ31244_UART,
.io_pg_offst = ((IQ31244_UART) >> 18) & 0xfffc,
.map_io = iq31244_map_io,
diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c
index e6ea1cb..6358548 100644
--- a/arch/arm/mach-iop3xx/iop331-setup.c
+++ b/arch/arm/mach-iop3xx/iop331-setup.c
@@ -195,7 +195,6 @@
#if defined(CONFIG_ARCH_IQ80331)
MACHINE_START(IQ80331, "Intel IQ80331")
/* Maintainer: Intel Corp. */
- .phys_ram = PHYS_OFFSET,
.phys_io = 0xfefff000,
.io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical
.map_io = iq80331_map_io,
@@ -208,7 +207,6 @@
#elif defined(CONFIG_MACH_IQ80332)
MACHINE_START(IQ80332, "Intel IQ80332")
/* Maintainer: Intel Corp. */
- .phys_ram = PHYS_OFFSET,
.phys_io = 0xfefff000,
.io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical
.map_io = iq80332_map_io,
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index 6851aba..cfd5bef 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -106,6 +106,16 @@
.length = IXP2000_MSF_SIZE,
.type = MT_IXP2000_DEVICE,
}, {
+ .virtual = IXP2000_SCRATCH_RING_VIRT_BASE,
+ .pfn = __phys_to_pfn(IXP2000_SCRATCH_RING_PHYS_BASE),
+ .length = IXP2000_SCRATCH_RING_SIZE,
+ .type = MT_IXP2000_DEVICE,
+ }, {
+ .virtual = IXP2000_SRAM0_VIRT_BASE,
+ .pfn = __phys_to_pfn(IXP2000_SRAM0_PHYS_BASE),
+ .length = IXP2000_SRAM0_SIZE,
+ .type = MT_IXP2000_DEVICE,
+ }, {
.virtual = IXP2000_PCI_IO_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE),
.length = IXP2000_PCI_IO_SIZE,
diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c
index 61f6006..9e5a13b 100644
--- a/arch/arm/mach-ixp2000/enp2611.c
+++ b/arch/arm/mach-ixp2000/enp2611.c
@@ -254,7 +254,6 @@
MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board")
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
- .phys_ram = 0x00000000,
.phys_io = IXP2000_UART_PHYS_BASE,
.io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c
index fd280a9..7c78240 100644
--- a/arch/arm/mach-ixp2000/ixdp2400.c
+++ b/arch/arm/mach-ixp2000/ixdp2400.c
@@ -169,7 +169,6 @@
MACHINE_START(IXDP2400, "Intel IXDP2400 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
- .phys_ram = 0x00000000,
.phys_io = IXP2000_UART_PHYS_BASE,
.io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c
index f9073aa..076e3f8 100644
--- a/arch/arm/mach-ixp2000/ixdp2800.c
+++ b/arch/arm/mach-ixp2000/ixdp2800.c
@@ -285,7 +285,6 @@
MACHINE_START(IXDP2800, "Intel IXDP2800 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
- .phys_ram = 0x00000000,
.phys_io = IXP2000_UART_PHYS_BASE,
.io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c
index e6a882f..10f0660 100644
--- a/arch/arm/mach-ixp2000/ixdp2x01.c
+++ b/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -376,7 +376,6 @@
#ifdef CONFIG_ARCH_IXDP2401
MACHINE_START(IXDP2401, "Intel IXDP2401 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
- .phys_ram = 0x00000000,
.phys_io = IXP2000_UART_PHYS_BASE,
.io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
@@ -390,7 +389,6 @@
#ifdef CONFIG_ARCH_IXDP2801
MACHINE_START(IXDP2801, "Intel IXDP2801 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
- .phys_ram = 0x00000000,
.phys_io = IXP2000_UART_PHYS_BASE,
.io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c
index 679594a..13f8a7a 100644
--- a/arch/arm/mach-ixp4xx/coyote-setup.c
+++ b/arch/arm/mach-ixp4xx/coyote-setup.c
@@ -101,7 +101,6 @@
#ifdef CONFIG_ARCH_ADI_COYOTE
MACHINE_START(ADI_COYOTE, "ADI Engineering Coyote")
/* Maintainer: MontaVista Software, Inc. */
- .phys_ram = PHYS_OFFSET,
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
@@ -119,7 +118,6 @@
#ifdef CONFIG_MACH_IXDPG425
MACHINE_START(IXDPG425, "Intel IXDPG425")
/* Maintainer: MontaVista Software, Inc. */
- .phys_ram = PHYS_OFFSET,
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
index 0386704..654e2ee 100644
--- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c
+++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
@@ -142,7 +142,6 @@
MACHINE_START(GTWX5715, "Gemtek GTWX5715 (Linksys WRV54G)")
/* Maintainer: George Joseph */
- .phys_ram = PHYS_OFFSET,
.phys_io = IXP4XX_UART2_BASE_PHYS,
.io_pg_offst = ((IXP4XX_UART2_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
index c2e105c..da72383 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -121,7 +121,6 @@
#ifdef CONFIG_ARCH_IXDP425
MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
- .phys_ram = PHYS_OFFSET,
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
@@ -135,7 +134,6 @@
#ifdef CONFIG_MACH_IXDP465
MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
- .phys_ram = PHYS_OFFSET,
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
@@ -149,7 +147,6 @@
#ifdef CONFIG_ARCH_PRPMC1100
MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
- .phys_ram = PHYS_OFFSET,
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
@@ -169,7 +166,6 @@
#ifdef CONFIG_ARCH_AVILA
MACHINE_START(AVILA, "Gateworks Avila Network Platform")
/* Maintainer: Deepak Saxena <dsaxena@plexity.net> */
- .phys_ram = PHYS_OFFSET,
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c
index 49998a8..856d56f 100644
--- a/arch/arm/mach-ixp4xx/nas100d-setup.c
+++ b/arch/arm/mach-ixp4xx/nas100d-setup.c
@@ -124,7 +124,6 @@
MACHINE_START(NAS100D, "Iomega NAS 100d")
/* Maintainer: www.nslu2-linux.org */
- .phys_ram = PHYS_OFFSET,
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c
index 289e94c..da9340a 100644
--- a/arch/arm/mach-ixp4xx/nslu2-setup.c
+++ b/arch/arm/mach-ixp4xx/nslu2-setup.c
@@ -123,7 +123,6 @@
MACHINE_START(NSLU2, "Linksys NSLU2")
/* Maintainer: www.nslu2-linux.org */
- .phys_ram = PHYS_OFFSET,
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
diff --git a/arch/arm/mach-l7200/core.c b/arch/arm/mach-l7200/core.c
index 03ed742..ac62643 100644
--- a/arch/arm/mach-l7200/core.c
+++ b/arch/arm/mach-l7200/core.c
@@ -91,7 +91,6 @@
MACHINE_START(L7200, "LinkUp Systems L7200")
/* Maintainer: Steve Hill / Scott McConnell */
- .phys_ram = 0xf0000000,
.phys_io = 0x80040000,
.io_pg_offst = ((0xd0000000) >> 18) & 0xfffc,
.map_io = l7200_map_io,
diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c
index 19f2fa2..2cccc27 100644
--- a/arch/arm/mach-lh7a40x/arch-kev7a400.c
+++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c
@@ -112,7 +112,6 @@
MACHINE_START (KEV7A400, "Sharp KEV7a400")
/* Maintainer: Marc Singer */
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc,
.boot_params = 0xc0000100,
diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
index 4eb962f..12e2327 100644
--- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
@@ -317,7 +317,6 @@
MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10")
/* Maintainer: Marc Singer */
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc,
.boot_params = 0xc0000100,
@@ -333,7 +332,6 @@
MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10")
/* Maintainer: Marc Singer */
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc,
.boot_params = 0xc0000100,
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
index 4b292e9..bdc20b5 100644
--- a/arch/arm/mach-omap1/board-generic.c
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -109,7 +109,6 @@
MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
/* Maintainer: Tony Lindgren <tony@atomide.com> */
- .phys_ram = 0x10000000,
.phys_io = 0xfff00000,
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index a07e2c9..9533c36 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -199,7 +199,6 @@
MACHINE_START(OMAP_H2, "TI-H2")
/* Maintainer: Imre Deak <imre.deak@nokia.com> */
- .phys_ram = 0x10000000,
.phys_io = 0xfff00000,
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index 668e278..d665efc 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -215,7 +215,6 @@
MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
/* Maintainer: Texas Instruments, Inc. */
- .phys_ram = 0x10000000,
.phys_io = 0xfff00000,
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 95f1ff3..652f37c 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -303,7 +303,6 @@
MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
/* Maintainer: MontaVista Software, Inc. */
- .phys_ram = 0x10000000,
.phys_io = 0xfff00000,
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c
index 0448fa7..58f7839 100644
--- a/arch/arm/mach-omap1/board-netstar.c
+++ b/arch/arm/mach-omap1/board-netstar.c
@@ -149,7 +149,6 @@
MACHINE_START(NETSTAR, "NetStar OMAP5910")
/* Maintainer: Ladislav Michl <michl@2n.cz> */
- .phys_ram = 0x10000000,
.phys_io = 0xfff00000,
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index e990e1b..e5d126e 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -274,7 +274,6 @@
MACHINE_START(OMAP_OSK, "TI-OSK")
/* Maintainer: Dirk Behme <dirk.behme@de.bosch.com> */
- .phys_ram = 0x10000000,
.phys_io = 0xfff00000,
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index 5c975eb..67fada2 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -76,7 +76,6 @@
}
MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
- .phys_ram = 0x10000000,
.phys_io = 0xfff00000,
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index 92ff5dc..88708a0 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -199,7 +199,6 @@
MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
/* Maintainer: Kevin Hilman <kjh@hilman.org> */
- .phys_ram = 0x10000000,
.phys_io = 0xfff00000,
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 6f9a622..959b4b8 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -281,7 +281,6 @@
MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910")
/* Maintainer: Ladislav Michl <michl@2n.cz> */
- .phys_ram = 0x10000000,
.phys_io = 0xfff00000,
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index c602e7a..b937123 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -69,7 +69,6 @@
MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx")
/* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
- .phys_ram = 0x80000000,
.phys_io = 0x48000000,
.io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index f255446..c3c35d4 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -186,7 +186,6 @@
MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
/* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
- .phys_ram = 0x80000000,
.phys_io = 0x48000000,
.io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 5a7b873..7ffd2de 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -342,7 +342,6 @@
#ifdef CONFIG_MACH_CORGI
MACHINE_START(CORGI, "SHARP Corgi")
- .phys_ram = 0xa0000000,
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_corgi,
@@ -355,7 +354,6 @@
#ifdef CONFIG_MACH_SHEPHERD
MACHINE_START(SHEPHERD, "SHARP Shepherd")
- .phys_ram = 0xa0000000,
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_corgi,
@@ -368,7 +366,6 @@
#ifdef CONFIG_MACH_HUSKY
MACHINE_START(HUSKY, "SHARP Husky")
- .phys_ram = 0xa0000000,
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_corgi,
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index 7de159e..347b9de 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -183,7 +183,6 @@
MACHINE_START(PXA_IDP, "Vibren PXA255 IDP")
/* Maintainer: Vibren Technologies */
- .phys_ram = 0xa0000000,
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = idp_map_io,
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index b464bc8..3e26d7c 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -437,7 +437,6 @@
MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)")
/* Maintainer: MontaVista Software Inc. */
- .phys_ram = 0xa0000000,
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = lubbock_map_io,
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 8da9d3e..d5bda60 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -489,7 +489,6 @@
MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
/* Maintainer: MontaVista Software Inc. */
- .phys_ram = 0xa0000000,
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = mainstone_map_io,
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 663c950..911e6ff 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -311,7 +311,6 @@
}
MACHINE_START(POODLE, "SHARP Poodle")
- .phys_ram = 0xa0000000,
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_poodle,
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index a9eacc0..c094d99 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -497,7 +497,6 @@
#ifdef CONFIG_MACH_SPITZ
MACHINE_START(SPITZ, "SHARP Spitz")
- .phys_ram = 0xa0000000,
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_spitz,
@@ -510,7 +509,6 @@
#ifdef CONFIG_MACH_BORZOI
MACHINE_START(BORZOI, "SHARP Borzoi")
- .phys_ram = 0xa0000000,
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_spitz,
@@ -523,7 +521,6 @@
#ifdef CONFIG_MACH_AKITA
MACHINE_START(AKITA, "SHARP Akita")
- .phys_ram = 0xa0000000,
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_spitz,
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index e4f92ef..d168286 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -295,7 +295,6 @@
}
MACHINE_START(TOSA, "SHARP Tosa")
- .phys_ram = 0xa0000000,
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_tosa,
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index 1299768..17f5f44 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -3,7 +3,6 @@
config MACH_REALVIEW_EB
bool "Support RealView/EB platform"
- default n
select ARM_GIC
help
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 112f759..d4a586e 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -166,7 +166,6 @@
MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_ram = 0x00000000,
.phys_io = REALVIEW_UART0_BASE,
.io_pg_offst = (IO_ADDRESS(REALVIEW_UART0_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c
index 5c4ac1c..208a2b5 100644
--- a/arch/arm/mach-rpc/riscpc.c
+++ b/arch/arm/mach-rpc/riscpc.c
@@ -177,7 +177,6 @@
MACHINE_START(RISCPC, "Acorn-RiscPC")
/* Maintainer: Russell King */
- .phys_ram = 0x10000000,
.phys_io = 0x03000000,
.io_pg_offst = ((0xe0000000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c
index 0f81fc0..3e327b8 100644
--- a/arch/arm/mach-s3c2410/mach-anubis.c
+++ b/arch/arm/mach-s3c2410/mach-anubis.c
@@ -294,7 +294,6 @@
MACHINE_START(ANUBIS, "Simtec-Anubis")
/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
- .phys_ram = S3C2410_SDRAM_PA,
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.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 4d96271..995bb8a 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -527,7 +527,6 @@
MACHINE_START(BAST, "Simtec-BAST")
/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
- .phys_ram = S3C2410_SDRAM_PA,
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.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 0aa8760..1c316f1 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -171,7 +171,6 @@
MACHINE_START(H1940, "IPAQ-H1940")
/* Maintainer: Ben Dooks <ben@fluff.org> */
- .phys_ram = S3C2410_SDRAM_PA,
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.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 378d640..116ac31 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -128,7 +128,6 @@
/* Maintainer: Christer Weinigel <christer@weinigel.se>,
Ben Dooks <ben-linux@fluff.org>
*/
- .phys_ram = S3C2410_SDRAM_PA,
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.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 42b0eef..07d0950 100644
--- a/arch/arm/mach-s3c2410/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2410/mach-nexcoder.c
@@ -148,7 +148,6 @@
MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")
/* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
- .phys_ram = S3C2410_SDRAM_PA,
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.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 a2eb9ed..b39daed 100644
--- a/arch/arm/mach-s3c2410/mach-otom.c
+++ b/arch/arm/mach-s3c2410/mach-otom.c
@@ -116,7 +116,6 @@
MACHINE_START(OTOM, "Nex Vision - Otom 1.1")
/* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
- .phys_ram = S3C2410_SDRAM_PA,
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.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 f8d86d1..0260ed5 100644
--- a/arch/arm/mach-s3c2410/mach-rx3715.c
+++ b/arch/arm/mach-s3c2410/mach-rx3715.c
@@ -205,7 +205,6 @@
MACHINE_START(RX3715, "IPAQ-RX3715")
/* Maintainer: Ben Dooks <ben@fluff.org> */
- .phys_ram = S3C2410_SDRAM_PA,
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.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 2c91965..1e76e1f 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -115,7 +115,6 @@
MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
* to SMDK2410 */
/* Maintainer: Jonas Dietsche */
- .phys_ram = S3C2410_SDRAM_PA,
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.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 4e31118..f431572 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2440.c
@@ -216,7 +216,6 @@
MACHINE_START(S3C2440, "SMDK2440")
/* Maintainer: Ben Dooks <ben@fluff.org> */
- .phys_ram = S3C2410_SDRAM_PA,
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.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 ae7e099..785fc9c 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -395,7 +395,6 @@
MACHINE_START(VR1000, "Thorcom-VR1000")
/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
- .phys_ram = S3C2410_SDRAM_PA,
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index a66ac61..a599bb0 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -447,7 +447,6 @@
MACHINE_START(ASSABET, "Intel-Assabet")
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
index edccd5e..f60b7a6 100644
--- a/arch/arm/mach-sa1100/badge4.c
+++ b/arch/arm/mach-sa1100/badge4.c
@@ -297,7 +297,6 @@
}
MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4")
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index 5085937..8269a9e 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -135,7 +135,6 @@
MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube")
/* Maintainer: support@intrinsyc.com */
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.map_io = cerf_map_io,
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 522abc0..6888816 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -191,7 +191,6 @@
}
MACHINE_START(COLLIE, "Sharp-Collie")
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.map_io = collie_map_io,
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index e8352b7..b04d922 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -392,7 +392,6 @@
}
MACHINE_START(H3100, "Compaq iPAQ H3100")
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
@@ -510,7 +509,6 @@
}
MACHINE_START(H3600, "Compaq iPAQ H3600")
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
@@ -897,7 +895,6 @@
}
MACHINE_START(H3800, "Compaq iPAQ H3800")
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
index c922e04..046b213 100644
--- a/arch/arm/mach-sa1100/hackkit.c
+++ b/arch/arm/mach-sa1100/hackkit.c
@@ -195,7 +195,6 @@
*/
MACHINE_START(HACKKIT, "HackKit Cpu Board")
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index 2f671cc..17f5a43 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -173,7 +173,6 @@
MACHINE_START(JORNADA720, "HP Jornada 720")
/* Maintainer: Michael Gernoth <michael@gernoth.net> */
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c
index 8c9e3dd..07d3a69 100644
--- a/arch/arm/mach-sa1100/lart.c
+++ b/arch/arm/mach-sa1100/lart.c
@@ -60,7 +60,6 @@
}
MACHINE_START(LART, "LART")
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c
index 58c18f9..0709ebab 100644
--- a/arch/arm/mach-sa1100/pleb.c
+++ b/arch/arm/mach-sa1100/pleb.c
@@ -146,7 +146,6 @@
}
MACHINE_START(PLEB, "PLEB")
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.map_io = pleb_map_io,
diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c
index 7482288..5aafe0b5 100644
--- a/arch/arm/mach-sa1100/shannon.c
+++ b/arch/arm/mach-sa1100/shannon.c
@@ -83,7 +83,6 @@
}
MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)")
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index 439ddc9..d2c23b2 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -229,7 +229,6 @@
MACHINE_START(SIMPAD, "Simpad")
/* Maintainer: Holger Freyther */
- .phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
.boot_params = 0xc0000100,
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
index 2d428b6..877600e 100644
--- a/arch/arm/mach-shark/core.c
+++ b/arch/arm/mach-shark/core.c
@@ -111,7 +111,6 @@
MACHINE_START(SHARK, "Shark")
/* Maintainer: Alexander Schulz */
- .phys_ram = 0x08000000,
.phys_io = 0x40000000,
.io_pg_offst = ((0xe0000000) >> 18) & 0xfffc,
.boot_params = 0x08003000,
diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig
index 8d787f4..95096af 100644
--- a/arch/arm/mach-versatile/Kconfig
+++ b/arch/arm/mach-versatile/Kconfig
@@ -9,7 +9,6 @@
config MACH_VERSATILE_AB
bool "Support Versatile/AB platform"
- default n
help
Include support for the ARM(R) Versatile/AP platform.
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 9002374..9ebbe80 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -35,6 +35,7 @@
#include <asm/leds.h>
#include <asm/hardware/arm_timer.h>
#include <asm/hardware/icst307.h>
+#include <asm/hardware/vic.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
@@ -56,24 +57,6 @@
#define VA_VIC_BASE __io_address(VERSATILE_VIC_BASE)
#define VA_SIC_BASE __io_address(VERSATILE_SIC_BASE)
-static void vic_mask_irq(unsigned int irq)
-{
- irq -= IRQ_VIC_START;
- writel(1 << irq, VA_VIC_BASE + VIC_IRQ_ENABLE_CLEAR);
-}
-
-static void vic_unmask_irq(unsigned int irq)
-{
- irq -= IRQ_VIC_START;
- writel(1 << irq, VA_VIC_BASE + VIC_IRQ_ENABLE);
-}
-
-static struct irqchip vic_chip = {
- .ack = vic_mask_irq,
- .mask = vic_mask_irq,
- .unmask = vic_unmask_irq,
-};
-
static void sic_mask_irq(unsigned int irq)
{
irq -= IRQ_SIC_START;
@@ -127,43 +110,12 @@
void __init versatile_init_irq(void)
{
- unsigned int i, value;
+ unsigned int i;
- /* Disable all interrupts initially. */
-
- writel(0, VA_VIC_BASE + VIC_INT_SELECT);
- writel(0, VA_VIC_BASE + VIC_IRQ_ENABLE);
- writel(~0, VA_VIC_BASE + VIC_IRQ_ENABLE_CLEAR);
- writel(0, VA_VIC_BASE + VIC_IRQ_STATUS);
- writel(0, VA_VIC_BASE + VIC_ITCR);
- writel(~0, VA_VIC_BASE + VIC_IRQ_SOFT_CLEAR);
-
- /*
- * Make sure we clear all existing interrupts
- */
- writel(0, VA_VIC_BASE + VIC_VECT_ADDR);
- for (i = 0; i < 19; i++) {
- value = readl(VA_VIC_BASE + VIC_VECT_ADDR);
- writel(value, VA_VIC_BASE + VIC_VECT_ADDR);
- }
-
- for (i = 0; i < 16; i++) {
- value = readl(VA_VIC_BASE + VIC_VECT_CNTL0 + (i * 4));
- writel(value | VICVectCntl_Enable | i, VA_VIC_BASE + VIC_VECT_CNTL0 + (i * 4));
- }
-
- writel(32, VA_VIC_BASE + VIC_DEF_VECT_ADDR);
-
- for (i = IRQ_VIC_START; i <= IRQ_VIC_END; i++) {
- if (i != IRQ_VICSOURCE31) {
- set_irq_chip(i, &vic_chip);
- set_irq_handler(i, do_level_IRQ);
- set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
- }
- }
+ vic_init(VA_VIC_BASE, ~(1 << 31));
set_irq_handler(IRQ_VICSOURCE31, sic_handle_irq);
- vic_unmask_irq(IRQ_VICSOURCE31);
+ enable_irq(IRQ_VICSOURCE31);
/* Do second interrupt controller */
writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
@@ -877,7 +829,7 @@
ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
do {
ticks1 = ticks2;
- status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS);
+ status = __raw_readl(VA_IC_BASE + VIC_RAW_STATUS);
ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
} while (ticks2 > ticks1);
diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c
index e74c8a2..1eb5967 100644
--- a/arch/arm/mach-versatile/versatile_ab.c
+++ b/arch/arm/mach-versatile/versatile_ab.c
@@ -36,7 +36,6 @@
MACHINE_START(VERSATILE_AB, "ARM-Versatile AB")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_ram = 0x00000000,
.phys_io = 0x101f1000,
.io_pg_offst = ((0xf11f1000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c
index 22d5ca0..f17ab4f 100644
--- a/arch/arm/mach-versatile/versatile_pb.c
+++ b/arch/arm/mach-versatile/versatile_pb.c
@@ -100,7 +100,6 @@
MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .phys_ram = 0x00000000,
.phys_io = 0x101f1000,
.io_pg_offst = ((0xf11f1000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
diff --git a/arch/arm/nwfpe/fpa11.h b/arch/arm/nwfpe/fpa11.h
index da4c616..28cd79a 100644
--- a/arch/arm/nwfpe/fpa11.h
+++ b/arch/arm/nwfpe/fpa11.h
@@ -62,7 +62,7 @@
#else
u32 padding[3];
#endif
-} FPREG;
+} __attribute__ ((packed,aligned(4))) FPREG;
/*
* FPA11 device model.
@@ -89,7 +89,7 @@
so we can use it to detect whether this
instance of the emulator needs to be
initialised. */
-} FPA11;
+} __attribute__ ((packed,aligned(4))) FPA11;
extern int8 SetRoundingMode(const unsigned int);
extern int8 SetRoundingPrecision(const unsigned int);
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 9693e9b..0887bb2 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -22,7 +22,6 @@
config OMAP_RESET_CLOCKS
bool "Reset unused clocks during boot"
depends on ARCH_OMAP
- default n
help
Say Y if you want to reset unused clocks during boot.
This option saves power, but assumes all drivers are
@@ -44,7 +43,6 @@
config OMAP_MUX_DEBUG
bool "Multiplexing debug output"
depends on OMAP_MUX
- default n
help
Makes the multiplexing functions print out a lot of debug info.
This is useful if you want to find out the correct values of the
@@ -93,7 +91,6 @@
config OMAP_DM_TIMER
bool "Use dual-mode timer"
- default n
depends on ARCH_OMAP16XX
help
Select this option if you want to use OMAP Dual-Mode timers.
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index d5d0df7..cbde675 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -702,6 +702,15 @@
Don't change this unless you know what you are doing.
+config HOTPLUG_CPU
+ bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
+ depends on SMP && HOTPLUG && EXPERIMENTAL
+ ---help---
+ Say Y here to experiment with turning CPUs off and on. CPUs
+ can be controlled through /sys/devices/system/cpu.
+
+ Say N.
+
endmenu
@@ -988,15 +997,6 @@
This support is also available as a module. If compiled as a
module, it will be called scx200.
-config HOTPLUG_CPU
- bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
- depends on SMP && HOTPLUG && EXPERIMENTAL
- ---help---
- Say Y here to experiment with turning CPUs off and on. CPUs
- can be controlled through /sys/devices/system/cpu.
-
- Say N.
-
source "drivers/pcmcia/Kconfig"
source "drivers/pci/hotplug/Kconfig"
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index d3c0409..bd2d53a 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -42,9 +42,9 @@
cflags-$(CONFIG_REGPARM) += $(shell if [ $(call cc-version) -ge 0300 ] ; then \
echo "-mregparm=3"; fi ;)
-# Disable unit-at-a-time mode, it makes gcc use a lot more stack
-# due to the lack of sharing of stacklots.
-CFLAGS += $(call cc-option,-fno-unit-at-a-time)
+# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
+# a lot more stack due to the lack of sharing of stacklots:
+CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;)
CFLAGS += $(cflags-y)
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index b9f0030..0aaebf3 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -112,33 +112,38 @@
p < (void *)tinfo + THREAD_SIZE - 3;
}
+static void print_addr_and_symbol(unsigned long addr, char *log_lvl)
+{
+ printk(log_lvl);
+ printk(" [<%08lx>] ", addr);
+ print_symbol("%s", addr);
+ printk("\n");
+}
+
static inline unsigned long print_context_stack(struct thread_info *tinfo,
- unsigned long *stack, unsigned long ebp)
+ unsigned long *stack, unsigned long ebp,
+ char *log_lvl)
{
unsigned long addr;
#ifdef CONFIG_FRAME_POINTER
while (valid_stack_ptr(tinfo, (void *)ebp)) {
addr = *(unsigned long *)(ebp + 4);
- printk(KERN_EMERG " [<%08lx>] ", addr);
- print_symbol("%s", addr);
- printk("\n");
+ print_addr_and_symbol(addr, log_lvl);
ebp = *(unsigned long *)ebp;
}
#else
while (valid_stack_ptr(tinfo, stack)) {
addr = *stack++;
- if (__kernel_text_address(addr)) {
- printk(KERN_EMERG " [<%08lx>]", addr);
- print_symbol(" %s", addr);
- printk("\n");
- }
+ if (__kernel_text_address(addr))
+ print_addr_and_symbol(addr, log_lvl);
}
#endif
return ebp;
}
-void show_trace(struct task_struct *task, unsigned long * stack)
+static void show_trace_log_lvl(struct task_struct *task,
+ unsigned long *stack, char *log_lvl)
{
unsigned long ebp;
@@ -157,7 +162,7 @@
struct thread_info *context;
context = (struct thread_info *)
((unsigned long)stack & (~(THREAD_SIZE - 1)));
- ebp = print_context_stack(context, stack, ebp);
+ ebp = print_context_stack(context, stack, ebp, log_lvl);
stack = (unsigned long*)context->previous_esp;
if (!stack)
break;
@@ -165,7 +170,13 @@
}
}
-void show_stack(struct task_struct *task, unsigned long *esp)
+void show_trace(struct task_struct *task, unsigned long * stack)
+{
+ show_trace_log_lvl(task, stack, "");
+}
+
+static void show_stack_log_lvl(struct task_struct *task, unsigned long *esp,
+ char *log_lvl)
{
unsigned long *stack;
int i;
@@ -178,16 +189,26 @@
}
stack = esp;
- printk(KERN_EMERG);
+ printk(log_lvl);
for(i = 0; i < kstack_depth_to_print; i++) {
if (kstack_end(stack))
break;
- if (i && ((i % 8) == 0))
- printk("\n" KERN_EMERG " ");
+ if (i && ((i % 8) == 0)) {
+ printk("\n");
+ printk(log_lvl);
+ printk(" ");
+ }
printk("%08lx ", *stack++);
}
- printk("\n" KERN_EMERG "Call Trace:\n");
- show_trace(task, esp);
+ printk("\n");
+ printk(log_lvl);
+ printk("Call Trace:\n");
+ show_trace_log_lvl(task, esp, log_lvl);
+}
+
+void show_stack(struct task_struct *task, unsigned long *esp)
+{
+ show_stack_log_lvl(task, esp, "");
}
/*
@@ -238,7 +259,7 @@
u8 __user *eip;
printk("\n" KERN_EMERG "Stack: ");
- show_stack(NULL, (unsigned long*)esp);
+ show_stack_log_lvl(NULL, (unsigned long *)esp, KERN_EMERG);
printk(KERN_EMERG "Code: ");
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
index 65f6707..83c3645 100644
--- a/arch/i386/pci/fixup.c
+++ b/arch/i386/pci/fixup.c
@@ -449,3 +449,19 @@
}
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_TI, 0x8032,
pci_post_fixup_toshiba_ohci1394);
+
+
+/*
+ * Prevent the BIOS trapping accesses to the Cyrix CS5530A video device
+ * configuration space.
+ */
+static void __devinit pci_early_fixup_cyrix_5530(struct pci_dev *dev)
+{
+ u8 r;
+ /* clear 'F4 Video Configuration Trap' bit */
+ pci_read_config_byte(dev, 0x42, &r);
+ r &= 0xfd;
+ pci_write_config_byte(dev, 0x42, r);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY,
+ pci_early_fixup_cyrix_5530);
diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig
index 80f8663..1d07d80 100644
--- a/arch/ia64/configs/gensparse_defconfig
+++ b/arch/ia64/configs/gensparse_defconfig
@@ -701,6 +701,7 @@
CONFIG_SERIAL_SGI_L1_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
CONFIG_SERIAL_SGI_IOC4=y
+CONFIG_SERIAL_SGI_IOC3=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -1046,6 +1047,7 @@
# SN Devices
#
CONFIG_SGI_IOC4=y
+CONFIG_SGI_IOC3=y
#
# File systems
diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig
index ff8bb37..3cb503b 100644
--- a/arch/ia64/configs/sn2_defconfig
+++ b/arch/ia64/configs/sn2_defconfig
@@ -659,6 +659,7 @@
CONFIG_SERIAL_SGI_L1_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
CONFIG_SERIAL_SGI_IOC4=y
+CONFIG_SERIAL_SGI_IOC3=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -899,6 +900,7 @@
# SN Devices
#
CONFIG_SGI_IOC4=y
+CONFIG_SGI_IOC3=y
#
# File systems
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 01feed0..df338c5 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -78,17 +78,6 @@
bool
default n
-config CRASH_DUMP
- bool "kernel crash dumps (EXPERIMENTAL)"
- depends on PPC_MULTIPLATFORM
- depends on EXPERIMENTAL
- help
- Build a kernel suitable for use as a kdump capture kernel.
- The kernel will be linked at a different address than normal, and
- so can only be used for Kdump.
-
- Don't change this unless you know what you are doing.
-
config GENERIC_TBSYNC
bool
default y if PPC32 && SMP
@@ -584,6 +573,16 @@
support. As of this writing the exact hardware interface is
strongly in flux, so no good recommendation can be made.
+config CRASH_DUMP
+ bool "kernel crash dumps (EXPERIMENTAL)"
+ depends on PPC_MULTIPLATFORM && PPC64 && EXPERIMENTAL
+ help
+ Build a kernel suitable for use as a kdump capture kernel.
+ The kernel will be linked at a different address than normal, and
+ so can only be used for Kdump.
+
+ Don't change this unless you know what you are doing.
+
config EMBEDDEDBOOT
bool
depends on 8xx || 8260
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 788dec4..840ae59 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -27,6 +27,7 @@
BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
OBJCOPYFLAGS := contents,alloc,load,readonly,data
OBJCOPY_COFF_ARGS := -O aixcoff-rs6000 --set-start 0x500000
+OBJCOPY_MIB_ARGS := -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c
zlibheader := infblock.h infcodes.h inffast.h inftrees.h infutil.h
@@ -90,11 +91,11 @@
hostprogs-y := addnote addRamDisk hack-coff
targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd \
- zImage.coff zImage.initrd.coff \
+ zImage.coff zImage.initrd.coff miboot.image miboot.initrd.image \
$(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
$(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
$(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \
- vmlinux.initrd
+ vmlinux.initrd dummy.o
extra-y := initrd.o
quiet_cmd_ramdisk = RAMDISK $@
@@ -116,6 +117,10 @@
quiet_cmd_addnote = ADDNOTE $@
cmd_addnote = $(obj)/addnote $@
+quiet_cmd_gen-miboot = GEN $@
+ cmd_gen-miboot = $(OBJCOPY) $(OBJCOPY_MIB_ARGS) \
+ --add-section=$1=$(word 2, $^) $< $@
+
quiet_cmd_gencoff = COFF $@
cmd_gencoff = $(OBJCOPY) $(OBJCOPY_COFF_ARGS) $@ && \
$(obj)/hack-coff $@
@@ -141,19 +146,25 @@
$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(srctree)/$(src)/zImage.lds
$(call cmd,bootld,$(obj-boot),zImage.lds)
-# For 32-bit powermacs, build the COFF images as well as the ELF images.
+# For 32-bit powermacs, build the COFF and miboot images
+# as well as the ELF images.
coffimage-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/zImage.coff
coffrdimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/zImage.initrd.coff
+mibootimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/miboot.image
+mibrdimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/miboot.initrd.image
-$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote $(coffimage-y-y)
+$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote $(coffimage-y-y) \
+ $(mibootimg-y-y)
@cp -f $< $@
$(call if_changed,addnote)
-$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote $(coffrdimg-y-y)
+$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote \
+ $(coffrdimg-y-y) $(mibrdimg-y-y)
@cp -f $< $@
$(call if_changed,addnote)
-$(obj)/zImage.coff: $(call obj-sec, $(required)) $(obj-boot) $(srctree)/$(src)/zImage.coff.lds $(obj)/hack-coff
+$(obj)/zImage.coff: $(call obj-sec, $(required)) $(obj-boot) \
+ $(srctree)/$(src)/zImage.coff.lds $(obj)/hack-coff
$(call cmd,bootld,$(obj-boot),zImage.coff.lds)
$(call cmd,gencoff)
@@ -162,6 +173,12 @@
$(call cmd,bootld,$(obj-boot),zImage.coff.lds)
$(call cmd,gencoff)
+$(obj)/miboot.image: $(obj)/dummy.o $(obj)/vmlinux.gz
+ $(call cmd,gen-miboot,image)
+
+$(obj)/miboot.initrd.image: $(obj)/miboot.image $(images)/ramdisk.image.gz
+ $(call cmd,gen-miboot,initrd)
+
#-----------------------------------------------------------
# build u-boot images
#-----------------------------------------------------------
diff --git a/arch/powerpc/boot/dummy.c b/arch/powerpc/boot/dummy.c
new file mode 100644
index 0000000..31dbf45
--- /dev/null
+++ b/arch/powerpc/boot/dummy.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig
index 398203b..2ace57d 100644
--- a/arch/powerpc/configs/pmac32_defconfig
+++ b/arch/powerpc/configs/pmac32_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc5
-# Tue Dec 13 17:24:05 2005
+# Linux kernel version: 2.6.15
+# Sat Jan 14 16:26:08 2006
#
# CONFIG_PPC64 is not set
CONFIG_PPC32=y
@@ -15,11 +15,15 @@
CONFIG_GENERIC_NVRAM=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+# CONFIG_PPC_UDBG_16550 is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_GENERIC_TBSYNC is not set
#
# Processor support
#
-CONFIG_6xx=y
+CONFIG_CLASSIC32=y
# CONFIG_PPC_52xx is not set
# CONFIG_PPC_82xx is not set
# CONFIG_PPC_83xx is not set
@@ -28,6 +32,7 @@
# CONFIG_8xx is not set
# CONFIG_E200 is not set
# CONFIG_E500 is not set
+CONFIG_6xx=y
CONFIG_PPC_FPU=y
CONFIG_ALTIVEC=y
CONFIG_PPC_STD_MMU=y
@@ -53,17 +58,18 @@
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
+CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
@@ -72,8 +78,10 @@
CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
#
# Loadable module support
@@ -113,13 +121,10 @@
# CONFIG_APUS is not set
# CONFIG_PPC_CHRP is not set
CONFIG_PPC_PMAC=y
-CONFIG_PPC_OF=y
CONFIG_MPIC=y
# CONFIG_PPC_RTAS is not set
# CONFIG_MMIO_NVRAM is not set
-# CONFIG_CRASH_DUMP is not set
CONFIG_PPC_MPC106=y
-# CONFIG_GENERIC_TBSYNC is not set
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TABLE=y
# CONFIG_CPU_FREQ_DEBUG is not set
@@ -195,6 +200,11 @@
# PC-card bridges
#
CONFIG_YENTA=m
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
# CONFIG_PD6729 is not set
# CONFIG_I82092 is not set
CONFIG_PCCARD_NONSTATIC=m
@@ -464,7 +474,7 @@
#
# CONFIG_STANDALONE is not set
CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
# CONFIG_DEBUG_DRIVER is not set
#
@@ -491,7 +501,7 @@
# Block devices
#
# CONFIG_BLK_DEV_FD is not set
-CONFIG_MAC_FLOPPY=y
+CONFIG_MAC_FLOPPY=m
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -603,7 +613,7 @@
# SCSI Transport Attributes
#
CONFIG_SCSI_SPI_ATTRS=y
-# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_FC_ATTRS=y
# CONFIG_SCSI_ISCSI_ATTRS is not set
# CONFIG_SCSI_SAS_ATTRS is not set
@@ -645,12 +655,7 @@
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
@@ -658,7 +663,7 @@
# CONFIG_SCSI_DEBUG is not set
CONFIG_SCSI_MESH=y
CONFIG_SCSI_MESH_SYNC_RATE=5
-CONFIG_SCSI_MESH_RESET_DELAY_MS=1000
+CONFIG_SCSI_MESH_RESET_DELAY_MS=4000
CONFIG_SCSI_MAC53C94=y
#
@@ -727,7 +732,6 @@
CONFIG_IEEE1394_ETH1394=m
CONFIG_IEEE1394_DV1394=m
CONFIG_IEEE1394_RAWIO=m
-# CONFIG_IEEE1394_CMP is not set
#
# I2O device support
@@ -740,7 +744,7 @@
CONFIG_ADB=y
CONFIG_ADB_CUDA=y
CONFIG_ADB_PMU=y
-CONFIG_PMAC_APM_EMU=y
+CONFIG_PMAC_APM_EMU=m
CONFIG_PMAC_MEDIABAY=y
CONFIG_PMAC_BACKLIGHT=y
CONFIG_INPUT_ADBHID=y
@@ -819,6 +823,7 @@
# CONFIG_R8169 is not set
# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
@@ -978,14 +983,14 @@
CONFIG_SERIAL_8250=m
# CONFIG_SERIAL_8250_CS is not set
CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
# CONFIG_SERIAL_8250_EXTENDED is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=m
-# CONFIG_SERIAL_PMACZILOG is not set
-# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_PMACZILOG=m
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -1058,7 +1063,7 @@
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_I810 is not set
# CONFIG_I2C_PIIX4 is not set
-CONFIG_I2C_KEYWEST=m
+CONFIG_I2C_POWERMAC=y
# CONFIG_I2C_MPC is not set
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
@@ -1160,7 +1165,6 @@
CONFIG_FB_ATY=y
CONFIG_FB_ATY_CT=y
# CONFIG_FB_ATY_GENERIC_LCD is not set
-# CONFIG_FB_ATY_XL_INIT is not set
CONFIG_FB_ATY_GX=y
# CONFIG_FB_SAVAGE is not set
# CONFIG_FB_SIS is not set
@@ -1169,7 +1173,6 @@
CONFIG_FB_3DFX=y
# CONFIG_FB_3DFX_ACCEL is not set
# CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_CYBLA is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_VIRTUAL is not set
@@ -1214,9 +1217,10 @@
CONFIG_SND_MIXER_OSS=m
CONFIG_SND_PCM_OSS=m
CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
-CONFIG_SND_GENERIC_DRIVER=y
#
# Generic devices
@@ -1230,6 +1234,8 @@
#
# PCI devices
#
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS4000 is not set
# CONFIG_SND_ALI5451 is not set
# CONFIG_SND_ATIIXP is not set
# CONFIG_SND_ATIIXP_MODEM is not set
@@ -1238,45 +1244,44 @@
# CONFIG_SND_AU8830 is not set
# CONFIG_SND_AZT3328 is not set
# CONFIG_SND_BT87X is not set
-# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_EMU10K1X is not set
-# CONFIG_SND_CA0106 is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_HDSPM is not set
-# CONFIG_SND_TRIDENT is not set
-# CONFIG_SND_YMFPCI is not set
-# CONFIG_SND_AD1889 is not set
-# CONFIG_SND_ALS4000 is not set
-# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_ENS1370 is not set
# CONFIG_SND_ENS1371 is not set
# CONFIG_SND_ES1938 is not set
# CONFIG_SND_ES1968 is not set
-# CONFIG_SND_MAESTRO3 is not set
# CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
# CONFIG_SND_ICE1712 is not set
# CONFIG_SND_ICE1724 is not set
# CONFIG_SND_INTEL8X0 is not set
# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
# CONFIG_SND_VIA82XX is not set
# CONFIG_SND_VIA82XX_MODEM is not set
# CONFIG_SND_VX222 is not set
-# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_YMFPCI is not set
#
# ALSA PowerMac devices
#
CONFIG_SND_POWERMAC=m
-# CONFIG_SND_POWERMAC_AUTO_DRC is not set
+CONFIG_SND_POWERMAC_AUTO_DRC=y
#
# USB devices
@@ -1336,6 +1341,7 @@
# may also be needed; see USB_STORAGE Help for more information
#
# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_LIBUSUAL is not set
#
# USB Input Devices
@@ -1355,6 +1361,7 @@
# CONFIG_USB_YEALINK is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
# CONFIG_USB_KEYSPAN_REMOTE is not set
CONFIG_USB_APPLETOUCH=y
@@ -1501,6 +1508,7 @@
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
@@ -1540,6 +1548,7 @@
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -1670,12 +1679,13 @@
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
@@ -1688,6 +1698,11 @@
CONFIG_XMON_DEFAULT=y
# CONFIG_BDI_SWITCH is not set
CONFIG_BOOTX_TEXT=y
+# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
+# CONFIG_PPC_EARLY_DEBUG_G5 is not set
+# CONFIG_PPC_EARLY_DEBUG_RTAS is not set
+# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
+# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
#
# Security options
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index a94699d..c287980 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -60,7 +60,8 @@
pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci_iommu.o \
pci_direct_iommu.o iomap.o
-obj-$(CONFIG_PCI) += $(pci64-y)
+pci32-$(CONFIG_PPC32) := pci_32.o
+obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y)
kexec-$(CONFIG_PPC64) := machine_kexec_64.o crash.o
kexec-$(CONFIG_PPC32) := machine_kexec_32.o
obj-$(CONFIG_KEXEC) += machine_kexec.o $(kexec-y)
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
index 5f248e3..8c21d37 100644
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -84,7 +84,10 @@
* squirrelled away. ELF notes happen to provide
* all of that that no need to invent something new.
*/
- buf = &crash_notes[cpu][0];
+ buf = (u32*)per_cpu_ptr(crash_notes, cpu);
+ if (!buf)
+ return;
+
memset(&prstatus, 0, sizeof(prstatus));
prstatus.pr_pid = current->pid;
elf_core_copy_regs(&prstatus.pr_reg, regs);
@@ -93,76 +96,6 @@
final_note(buf);
}
-/* FIXME Merge this with xmon_save_regs ?? */
-static inline void crash_get_current_regs(struct pt_regs *regs)
-{
- unsigned long tmp1, tmp2;
-
- __asm__ __volatile__ (
- "std 0,0(%2)\n"
- "std 1,8(%2)\n"
- "std 2,16(%2)\n"
- "std 3,24(%2)\n"
- "std 4,32(%2)\n"
- "std 5,40(%2)\n"
- "std 6,48(%2)\n"
- "std 7,56(%2)\n"
- "std 8,64(%2)\n"
- "std 9,72(%2)\n"
- "std 10,80(%2)\n"
- "std 11,88(%2)\n"
- "std 12,96(%2)\n"
- "std 13,104(%2)\n"
- "std 14,112(%2)\n"
- "std 15,120(%2)\n"
- "std 16,128(%2)\n"
- "std 17,136(%2)\n"
- "std 18,144(%2)\n"
- "std 19,152(%2)\n"
- "std 20,160(%2)\n"
- "std 21,168(%2)\n"
- "std 22,176(%2)\n"
- "std 23,184(%2)\n"
- "std 24,192(%2)\n"
- "std 25,200(%2)\n"
- "std 26,208(%2)\n"
- "std 27,216(%2)\n"
- "std 28,224(%2)\n"
- "std 29,232(%2)\n"
- "std 30,240(%2)\n"
- "std 31,248(%2)\n"
- "mfmsr %0\n"
- "std %0, 264(%2)\n"
- "mfctr %0\n"
- "std %0, 280(%2)\n"
- "mflr %0\n"
- "std %0, 288(%2)\n"
- "bl 1f\n"
- "1: mflr %1\n"
- "std %1, 256(%2)\n"
- "mtlr %0\n"
- "mfxer %0\n"
- "std %0, 296(%2)\n"
- : "=&r" (tmp1), "=&r" (tmp2)
- : "b" (regs));
-}
-
-/* We may have saved_regs from where the error came from
- * or it is NULL if via a direct panic().
- */
-static void crash_save_self(struct pt_regs *saved_regs)
-{
- struct pt_regs regs;
- int cpu;
-
- cpu = smp_processor_id();
- if (saved_regs)
- memcpy(®s, saved_regs, sizeof(regs));
- else
- crash_get_current_regs(®s);
- crash_save_this_cpu(®s, cpu);
-}
-
#ifdef CONFIG_SMP
static atomic_t waiting_for_crash_ipi;
@@ -260,5 +193,5 @@
*/
crashing_cpu = smp_processor_id();
crash_kexec_prepare_cpus();
- crash_save_self(regs);
+ crash_save_this_cpu(regs, crashing_cpu);
}
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
new file mode 100644
index 0000000..704c846
--- /dev/null
+++ b/arch/powerpc/kernel/pci_32.c
@@ -0,0 +1,1897 @@
+/*
+ * Common pmac/prep/chrp pci routines. -- Cort
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/capability.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/bootmem.h>
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/sections.h>
+#include <asm/pci-bridge.h>
+#include <asm/byteorder.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/machdep.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+unsigned long isa_io_base = 0;
+unsigned long isa_mem_base = 0;
+unsigned long pci_dram_offset = 0;
+int pcibios_assign_bus_offset = 1;
+
+void pcibios_make_OF_bus_map(void);
+
+static int pci_relocate_bridge_resource(struct pci_bus *bus, int i);
+static int probe_resource(struct pci_bus *parent, struct resource *pr,
+ struct resource *res, struct resource **conflict);
+static void update_bridge_base(struct pci_bus *bus, int i);
+static void pcibios_fixup_resources(struct pci_dev* dev);
+static void fixup_broken_pcnet32(struct pci_dev* dev);
+static int reparent_resources(struct resource *parent, struct resource *res);
+static void fixup_cpc710_pci64(struct pci_dev* dev);
+#ifdef CONFIG_PPC_OF
+static u8* pci_to_OF_bus_map;
+#endif
+
+/* By default, we don't re-assign bus numbers. We do this only on
+ * some pmacs
+ */
+int pci_assign_all_buses;
+
+struct pci_controller* hose_head;
+struct pci_controller** hose_tail = &hose_head;
+
+static int pci_bus_count;
+
+static void
+fixup_broken_pcnet32(struct pci_dev* dev)
+{
+ if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
+ dev->vendor = PCI_VENDOR_ID_AMD;
+ pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32);
+
+static void
+fixup_cpc710_pci64(struct pci_dev* dev)
+{
+ /* Hide the PCI64 BARs from the kernel as their content doesn't
+ * fit well in the resource management
+ */
+ dev->resource[0].start = dev->resource[0].end = 0;
+ dev->resource[0].flags = 0;
+ dev->resource[1].start = dev->resource[1].end = 0;
+ dev->resource[1].flags = 0;
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CPC710_PCI64, fixup_cpc710_pci64);
+
+static void
+pcibios_fixup_resources(struct pci_dev *dev)
+{
+ struct pci_controller* hose = (struct pci_controller *)dev->sysdata;
+ int i;
+ unsigned long offset;
+
+ if (!hose) {
+ printk(KERN_ERR "No hose for PCI dev %s!\n", pci_name(dev));
+ return;
+ }
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+ struct resource *res = dev->resource + i;
+ if (!res->flags)
+ continue;
+ if (res->end == 0xffffffff) {
+ DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n",
+ pci_name(dev), i, res->start, res->end);
+ res->end -= res->start;
+ res->start = 0;
+ res->flags |= IORESOURCE_UNSET;
+ continue;
+ }
+ offset = 0;
+ if (res->flags & IORESOURCE_MEM) {
+ offset = hose->pci_mem_offset;
+ } else if (res->flags & IORESOURCE_IO) {
+ offset = (unsigned long) hose->io_base_virt
+ - isa_io_base;
+ }
+ if (offset != 0) {
+ res->start += offset;
+ res->end += offset;
+#ifdef DEBUG
+ printk("Fixup res %d (%lx) of dev %s: %lx -> %lx\n",
+ i, res->flags, pci_name(dev),
+ res->start - offset, res->start);
+#endif
+ }
+ }
+
+ /* Call machine specific resource fixup */
+ if (ppc_md.pcibios_fixup_resources)
+ ppc_md.pcibios_fixup_resources(dev);
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources);
+
+void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+ struct resource *res)
+{
+ unsigned long offset = 0;
+ struct pci_controller *hose = dev->sysdata;
+
+ if (hose && res->flags & IORESOURCE_IO)
+ offset = (unsigned long)hose->io_base_virt - isa_io_base;
+ else if (hose && res->flags & IORESOURCE_MEM)
+ offset = hose->pci_mem_offset;
+ region->start = res->start - offset;
+ region->end = res->end - offset;
+}
+EXPORT_SYMBOL(pcibios_resource_to_bus);
+
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+ struct pci_bus_region *region)
+{
+ unsigned long offset = 0;
+ struct pci_controller *hose = dev->sysdata;
+
+ if (hose && res->flags & IORESOURCE_IO)
+ offset = (unsigned long)hose->io_base_virt - isa_io_base;
+ else if (hose && res->flags & IORESOURCE_MEM)
+ offset = hose->pci_mem_offset;
+ res->start = region->start + offset;
+ res->end = region->end + offset;
+}
+EXPORT_SYMBOL(pcibios_bus_to_resource);
+
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ *
+ * Why? Because some silly external IO cards only decode
+ * the low 10 bits of the IO address. The 0x00-0xff region
+ * is reserved for motherboard devices that decode all 16
+ * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
+ * but we want to try to avoid allocating at 0x2900-0x2bff
+ * which might have be mirrored at 0x0100-0x03ff..
+ */
+void pcibios_align_resource(void *data, struct resource *res, unsigned long size,
+ unsigned long align)
+{
+ struct pci_dev *dev = data;
+
+ if (res->flags & IORESOURCE_IO) {
+ unsigned long start = res->start;
+
+ if (size > 0x100) {
+ printk(KERN_ERR "PCI: I/O Region %s/%d too large"
+ " (%ld bytes)\n", pci_name(dev),
+ dev->resource - res, size);
+ }
+
+ if (start & 0x300) {
+ start = (start + 0x3ff) & ~0x3ff;
+ res->start = start;
+ }
+ }
+}
+EXPORT_SYMBOL(pcibios_align_resource);
+
+/*
+ * Handle resources of PCI devices. If the world were perfect, we could
+ * just allocate all the resource regions and do nothing more. It isn't.
+ * On the other hand, we cannot just re-allocate all devices, as it would
+ * require us to know lots of host bridge internals. So we attempt to
+ * keep as much of the original configuration as possible, but tweak it
+ * when it's found to be wrong.
+ *
+ * Known BIOS problems we have to work around:
+ * - I/O or memory regions not configured
+ * - regions configured, but not enabled in the command register
+ * - bogus I/O addresses above 64K used
+ * - expansion ROMs left enabled (this may sound harmless, but given
+ * the fact the PCI specs explicitly allow address decoders to be
+ * shared between expansion ROMs and other resource regions, it's
+ * at least dangerous)
+ *
+ * Our solution:
+ * (1) Allocate resources for all buses behind PCI-to-PCI bridges.
+ * This gives us fixed barriers on where we can allocate.
+ * (2) Allocate resources for all enabled devices. If there is
+ * a collision, just mark the resource as unallocated. Also
+ * disable expansion ROMs during this step.
+ * (3) Try to allocate resources for disabled devices. If the
+ * resources were assigned correctly, everything goes well,
+ * if they weren't, they won't disturb allocation of other
+ * resources.
+ * (4) Assign new addresses to resources which were either
+ * not configured at all or misconfigured. If explicitly
+ * requested by the user, configure expansion ROM address
+ * as well.
+ */
+
+static void __init
+pcibios_allocate_bus_resources(struct list_head *bus_list)
+{
+ struct pci_bus *bus;
+ int i;
+ struct resource *res, *pr;
+
+ /* Depth-First Search on bus tree */
+ list_for_each_entry(bus, bus_list, node) {
+ for (i = 0; i < 4; ++i) {
+ if ((res = bus->resource[i]) == NULL || !res->flags
+ || res->start > res->end)
+ continue;
+ if (bus->parent == NULL)
+ pr = (res->flags & IORESOURCE_IO)?
+ &ioport_resource: &iomem_resource;
+ else {
+ pr = pci_find_parent_resource(bus->self, res);
+ if (pr == res) {
+ /* this happens when the generic PCI
+ * code (wrongly) decides that this
+ * bridge is transparent -- paulus
+ */
+ continue;
+ }
+ }
+
+ DBG("PCI: bridge rsrc %lx..%lx (%lx), parent %p\n",
+ res->start, res->end, res->flags, pr);
+ if (pr) {
+ if (request_resource(pr, res) == 0)
+ continue;
+ /*
+ * Must be a conflict with an existing entry.
+ * Move that entry (or entries) under the
+ * bridge resource and try again.
+ */
+ if (reparent_resources(pr, res) == 0)
+ continue;
+ }
+ printk(KERN_ERR "PCI: Cannot allocate resource region "
+ "%d of PCI bridge %d\n", i, bus->number);
+ if (pci_relocate_bridge_resource(bus, i))
+ bus->resource[i] = NULL;
+ }
+ pcibios_allocate_bus_resources(&bus->children);
+ }
+}
+
+/*
+ * Reparent resource children of pr that conflict with res
+ * under res, and make res replace those children.
+ */
+static int __init
+reparent_resources(struct resource *parent, struct resource *res)
+{
+ struct resource *p, **pp;
+ struct resource **firstpp = NULL;
+
+ for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
+ if (p->end < res->start)
+ continue;
+ if (res->end < p->start)
+ break;
+ if (p->start < res->start || p->end > res->end)
+ return -1; /* not completely contained */
+ if (firstpp == NULL)
+ firstpp = pp;
+ }
+ if (firstpp == NULL)
+ return -1; /* didn't find any conflicting entries? */
+ res->parent = parent;
+ res->child = *firstpp;
+ res->sibling = *pp;
+ *firstpp = res;
+ *pp = NULL;
+ for (p = res->child; p != NULL; p = p->sibling) {
+ p->parent = res;
+ DBG(KERN_INFO "PCI: reparented %s [%lx..%lx] under %s\n",
+ p->name, p->start, p->end, res->name);
+ }
+ return 0;
+}
+
+/*
+ * A bridge has been allocated a range which is outside the range
+ * of its parent bridge, so it needs to be moved.
+ */
+static int __init
+pci_relocate_bridge_resource(struct pci_bus *bus, int i)
+{
+ struct resource *res, *pr, *conflict;
+ unsigned long try, size;
+ int j;
+ struct pci_bus *parent = bus->parent;
+
+ if (parent == NULL) {
+ /* shouldn't ever happen */
+ printk(KERN_ERR "PCI: can't move host bridge resource\n");
+ return -1;
+ }
+ res = bus->resource[i];
+ if (res == NULL)
+ return -1;
+ pr = NULL;
+ for (j = 0; j < 4; j++) {
+ struct resource *r = parent->resource[j];
+ if (!r)
+ continue;
+ if ((res->flags ^ r->flags) & (IORESOURCE_IO | IORESOURCE_MEM))
+ continue;
+ if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH)) {
+ pr = r;
+ break;
+ }
+ if (res->flags & IORESOURCE_PREFETCH)
+ pr = r;
+ }
+ if (pr == NULL)
+ return -1;
+ size = res->end - res->start;
+ if (pr->start > pr->end || size > pr->end - pr->start)
+ return -1;
+ try = pr->end;
+ for (;;) {
+ res->start = try - size;
+ res->end = try;
+ if (probe_resource(bus->parent, pr, res, &conflict) == 0)
+ break;
+ if (conflict->start <= pr->start + size)
+ return -1;
+ try = conflict->start - 1;
+ }
+ if (request_resource(pr, res)) {
+ DBG(KERN_ERR "PCI: huh? couldn't move to %lx..%lx\n",
+ res->start, res->end);
+ return -1; /* "can't happen" */
+ }
+ update_bridge_base(bus, i);
+ printk(KERN_INFO "PCI: bridge %d resource %d moved to %lx..%lx\n",
+ bus->number, i, res->start, res->end);
+ return 0;
+}
+
+static int __init
+probe_resource(struct pci_bus *parent, struct resource *pr,
+ struct resource *res, struct resource **conflict)
+{
+ struct pci_bus *bus;
+ struct pci_dev *dev;
+ struct resource *r;
+ int i;
+
+ for (r = pr->child; r != NULL; r = r->sibling) {
+ if (r->end >= res->start && res->end >= r->start) {
+ *conflict = r;
+ return 1;
+ }
+ }
+ list_for_each_entry(bus, &parent->children, node) {
+ for (i = 0; i < 4; ++i) {
+ if ((r = bus->resource[i]) == NULL)
+ continue;
+ if (!r->flags || r->start > r->end || r == res)
+ continue;
+ if (pci_find_parent_resource(bus->self, r) != pr)
+ continue;
+ if (r->end >= res->start && res->end >= r->start) {
+ *conflict = r;
+ return 1;
+ }
+ }
+ }
+ list_for_each_entry(dev, &parent->devices, bus_list) {
+ for (i = 0; i < 6; ++i) {
+ r = &dev->resource[i];
+ if (!r->flags || (r->flags & IORESOURCE_UNSET))
+ continue;
+ if (pci_find_parent_resource(dev, r) != pr)
+ continue;
+ if (r->end >= res->start && res->end >= r->start) {
+ *conflict = r;
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+static void __init
+update_bridge_base(struct pci_bus *bus, int i)
+{
+ struct resource *res = bus->resource[i];
+ u8 io_base_lo, io_limit_lo;
+ u16 mem_base, mem_limit;
+ u16 cmd;
+ unsigned long start, end, off;
+ struct pci_dev *dev = bus->self;
+ struct pci_controller *hose = dev->sysdata;
+
+ if (!hose) {
+ printk("update_bridge_base: no hose?\n");
+ return;
+ }
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ pci_write_config_word(dev, PCI_COMMAND,
+ cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
+ if (res->flags & IORESOURCE_IO) {
+ off = (unsigned long) hose->io_base_virt - isa_io_base;
+ start = res->start - off;
+ end = res->end - off;
+ io_base_lo = (start >> 8) & PCI_IO_RANGE_MASK;
+ io_limit_lo = (end >> 8) & PCI_IO_RANGE_MASK;
+ if (end > 0xffff) {
+ pci_write_config_word(dev, PCI_IO_BASE_UPPER16,
+ start >> 16);
+ pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16,
+ end >> 16);
+ io_base_lo |= PCI_IO_RANGE_TYPE_32;
+ } else
+ io_base_lo |= PCI_IO_RANGE_TYPE_16;
+ pci_write_config_byte(dev, PCI_IO_BASE, io_base_lo);
+ pci_write_config_byte(dev, PCI_IO_LIMIT, io_limit_lo);
+
+ } else if ((res->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH))
+ == IORESOURCE_MEM) {
+ off = hose->pci_mem_offset;
+ mem_base = ((res->start - off) >> 16) & PCI_MEMORY_RANGE_MASK;
+ mem_limit = ((res->end - off) >> 16) & PCI_MEMORY_RANGE_MASK;
+ pci_write_config_word(dev, PCI_MEMORY_BASE, mem_base);
+ pci_write_config_word(dev, PCI_MEMORY_LIMIT, mem_limit);
+
+ } else if ((res->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH))
+ == (IORESOURCE_MEM | IORESOURCE_PREFETCH)) {
+ off = hose->pci_mem_offset;
+ mem_base = ((res->start - off) >> 16) & PCI_PREF_RANGE_MASK;
+ mem_limit = ((res->end - off) >> 16) & PCI_PREF_RANGE_MASK;
+ pci_write_config_word(dev, PCI_PREF_MEMORY_BASE, mem_base);
+ pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT, mem_limit);
+
+ } else {
+ DBG(KERN_ERR "PCI: ugh, bridge %s res %d has flags=%lx\n",
+ pci_name(dev), i, res->flags);
+ }
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+}
+
+static inline void alloc_resource(struct pci_dev *dev, int idx)
+{
+ struct resource *pr, *r = &dev->resource[idx];
+
+ DBG("PCI:%s: Resource %d: %08lx-%08lx (f=%lx)\n",
+ pci_name(dev), idx, r->start, r->end, r->flags);
+ pr = pci_find_parent_resource(dev, r);
+ if (!pr || request_resource(pr, r) < 0) {
+ printk(KERN_ERR "PCI: Cannot allocate resource region %d"
+ " of device %s\n", idx, pci_name(dev));
+ if (pr)
+ DBG("PCI: parent is %p: %08lx-%08lx (f=%lx)\n",
+ pr, pr->start, pr->end, pr->flags);
+ /* We'll assign a new address later */
+ r->flags |= IORESOURCE_UNSET;
+ r->end -= r->start;
+ r->start = 0;
+ }
+}
+
+static void __init
+pcibios_allocate_resources(int pass)
+{
+ struct pci_dev *dev = NULL;
+ int idx, disabled;
+ u16 command;
+ struct resource *r;
+
+ for_each_pci_dev(dev) {
+ pci_read_config_word(dev, PCI_COMMAND, &command);
+ for (idx = 0; idx < 6; idx++) {
+ r = &dev->resource[idx];
+ if (r->parent) /* Already allocated */
+ continue;
+ if (!r->flags || (r->flags & IORESOURCE_UNSET))
+ continue; /* Not assigned at all */
+ if (r->flags & IORESOURCE_IO)
+ disabled = !(command & PCI_COMMAND_IO);
+ else
+ disabled = !(command & PCI_COMMAND_MEMORY);
+ if (pass == disabled)
+ alloc_resource(dev, idx);
+ }
+ if (pass)
+ continue;
+ r = &dev->resource[PCI_ROM_RESOURCE];
+ if (r->flags & IORESOURCE_ROM_ENABLE) {
+ /* Turn the ROM off, leave the resource region, but keep it unregistered. */
+ u32 reg;
+ DBG("PCI: Switching off ROM of %s\n", pci_name(dev));
+ r->flags &= ~IORESOURCE_ROM_ENABLE;
+ pci_read_config_dword(dev, dev->rom_base_reg, ®);
+ pci_write_config_dword(dev, dev->rom_base_reg,
+ reg & ~PCI_ROM_ADDRESS_ENABLE);
+ }
+ }
+}
+
+static void __init
+pcibios_assign_resources(void)
+{
+ struct pci_dev *dev = NULL;
+ int idx;
+ struct resource *r;
+
+ for_each_pci_dev(dev) {
+ int class = dev->class >> 8;
+
+ /* Don't touch classless devices and host bridges */
+ if (!class || class == PCI_CLASS_BRIDGE_HOST)
+ continue;
+
+ for (idx = 0; idx < 6; idx++) {
+ r = &dev->resource[idx];
+
+ /*
+ * We shall assign a new address to this resource,
+ * either because the BIOS (sic) forgot to do so
+ * or because we have decided the old address was
+ * unusable for some reason.
+ */
+ if ((r->flags & IORESOURCE_UNSET) && r->end &&
+ (!ppc_md.pcibios_enable_device_hook ||
+ !ppc_md.pcibios_enable_device_hook(dev, 1))) {
+ r->flags &= ~IORESOURCE_UNSET;
+ pci_assign_resource(dev, idx);
+ }
+ }
+
+#if 0 /* don't assign ROMs */
+ r = &dev->resource[PCI_ROM_RESOURCE];
+ r->end -= r->start;
+ r->start = 0;
+ if (r->end)
+ pci_assign_resource(dev, PCI_ROM_RESOURCE);
+#endif
+ }
+}
+
+
+int
+pcibios_enable_resources(struct pci_dev *dev, int mask)
+{
+ u16 cmd, old_cmd;
+ int idx;
+ struct resource *r;
+
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ old_cmd = cmd;
+ for (idx=0; idx<6; idx++) {
+ /* Only set up the requested stuff */
+ if (!(mask & (1<<idx)))
+ continue;
+
+ r = &dev->resource[idx];
+ if (r->flags & IORESOURCE_UNSET) {
+ printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev));
+ return -EINVAL;
+ }
+ if (r->flags & IORESOURCE_IO)
+ cmd |= PCI_COMMAND_IO;
+ if (r->flags & IORESOURCE_MEM)
+ cmd |= PCI_COMMAND_MEMORY;
+ }
+ if (dev->resource[PCI_ROM_RESOURCE].start)
+ cmd |= PCI_COMMAND_MEMORY;
+ if (cmd != old_cmd) {
+ printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+ }
+ return 0;
+}
+
+static int next_controller_index;
+
+struct pci_controller * __init
+pcibios_alloc_controller(void)
+{
+ struct pci_controller *hose;
+
+ hose = (struct pci_controller *)alloc_bootmem(sizeof(*hose));
+ memset(hose, 0, sizeof(struct pci_controller));
+
+ *hose_tail = hose;
+ hose_tail = &hose->next;
+
+ hose->index = next_controller_index++;
+
+ return hose;
+}
+
+#ifdef CONFIG_PPC_OF
+/*
+ * Functions below are used on OpenFirmware machines.
+ */
+static void
+make_one_node_map(struct device_node* node, u8 pci_bus)
+{
+ int *bus_range;
+ int len;
+
+ if (pci_bus >= pci_bus_count)
+ return;
+ bus_range = (int *) get_property(node, "bus-range", &len);
+ if (bus_range == NULL || len < 2 * sizeof(int)) {
+ printk(KERN_WARNING "Can't get bus-range for %s, "
+ "assuming it starts at 0\n", node->full_name);
+ pci_to_OF_bus_map[pci_bus] = 0;
+ } else
+ pci_to_OF_bus_map[pci_bus] = bus_range[0];
+
+ for (node=node->child; node != 0;node = node->sibling) {
+ struct pci_dev* dev;
+ unsigned int *class_code, *reg;
+
+ class_code = (unsigned int *) get_property(node, "class-code", NULL);
+ if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
+ (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
+ continue;
+ reg = (unsigned int *)get_property(node, "reg", NULL);
+ if (!reg)
+ continue;
+ dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff));
+ if (!dev || !dev->subordinate)
+ continue;
+ make_one_node_map(node, dev->subordinate->number);
+ }
+}
+
+void
+pcibios_make_OF_bus_map(void)
+{
+ int i;
+ struct pci_controller* hose;
+ u8* of_prop_map;
+
+ pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL);
+ if (!pci_to_OF_bus_map) {
+ printk(KERN_ERR "Can't allocate OF bus map !\n");
+ return;
+ }
+
+ /* We fill the bus map with invalid values, that helps
+ * debugging.
+ */
+ for (i=0; i<pci_bus_count; i++)
+ pci_to_OF_bus_map[i] = 0xff;
+
+ /* For each hose, we begin searching bridges */
+ for(hose=hose_head; hose; hose=hose->next) {
+ struct device_node* node;
+ node = (struct device_node *)hose->arch_data;
+ if (!node)
+ continue;
+ make_one_node_map(node, hose->first_busno);
+ }
+ of_prop_map = get_property(find_path_device("/"), "pci-OF-bus-map", NULL);
+ if (of_prop_map)
+ memcpy(of_prop_map, pci_to_OF_bus_map, pci_bus_count);
+#ifdef DEBUG
+ printk("PCI->OF bus map:\n");
+ for (i=0; i<pci_bus_count; i++) {
+ if (pci_to_OF_bus_map[i] == 0xff)
+ continue;
+ printk("%d -> %d\n", i, pci_to_OF_bus_map[i]);
+ }
+#endif
+}
+
+typedef int (*pci_OF_scan_iterator)(struct device_node* node, void* data);
+
+static struct device_node*
+scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* data)
+{
+ struct device_node* sub_node;
+
+ for (; node != 0;node = node->sibling) {
+ unsigned int *class_code;
+
+ if (filter(node, data))
+ return node;
+
+ /* For PCI<->PCI bridges or CardBus bridges, we go down
+ * Note: some OFs create a parent node "multifunc-device" as
+ * a fake root for all functions of a multi-function device,
+ * we go down them as well.
+ */
+ class_code = (unsigned int *) get_property(node, "class-code", NULL);
+ if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
+ (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) &&
+ strcmp(node->name, "multifunc-device"))
+ continue;
+ sub_node = scan_OF_pci_childs(node->child, filter, data);
+ if (sub_node)
+ return sub_node;
+ }
+ return NULL;
+}
+
+static int
+scan_OF_pci_childs_iterator(struct device_node* node, void* data)
+{
+ unsigned int *reg;
+ u8* fdata = (u8*)data;
+
+ reg = (unsigned int *) get_property(node, "reg", NULL);
+ if (reg && ((reg[0] >> 8) & 0xff) == fdata[1]
+ && ((reg[0] >> 16) & 0xff) == fdata[0])
+ return 1;
+ return 0;
+}
+
+static struct device_node*
+scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn)
+{
+ u8 filter_data[2] = {bus, dev_fn};
+
+ return scan_OF_pci_childs(node, scan_OF_pci_childs_iterator, filter_data);
+}
+
+/*
+ * Scans the OF tree for a device node matching a PCI device
+ */
+struct device_node *
+pci_busdev_to_OF_node(struct pci_bus *bus, int devfn)
+{
+ struct pci_controller *hose;
+ struct device_node *node;
+ int busnr;
+
+ if (!have_of)
+ return NULL;
+
+ /* Lookup the hose */
+ busnr = bus->number;
+ hose = pci_bus_to_hose(busnr);
+ if (!hose)
+ return NULL;
+
+ /* Check it has an OF node associated */
+ node = (struct device_node *) hose->arch_data;
+ if (!node)
+ return NULL;
+
+ /* Fixup bus number according to what OF think it is. */
+#ifdef CONFIG_PPC_PMAC
+ /* The G5 need a special case here. Basically, we don't remap all
+ * busses on it so we don't create the pci-OF-map. However, we do
+ * remap the AGP bus and so have to deal with it. A future better
+ * fix has to be done by making the remapping per-host and always
+ * filling the pci_to_OF map. --BenH
+ */
+ if (_machine == _MACH_Pmac && busnr >= 0xf0)
+ busnr -= 0xf0;
+ else
+#endif
+ if (pci_to_OF_bus_map)
+ busnr = pci_to_OF_bus_map[busnr];
+ if (busnr == 0xff)
+ return NULL;
+
+ /* Now, lookup childs of the hose */
+ return scan_OF_childs_for_device(node->child, busnr, devfn);
+}
+EXPORT_SYMBOL(pci_busdev_to_OF_node);
+
+struct device_node*
+pci_device_to_OF_node(struct pci_dev *dev)
+{
+ return pci_busdev_to_OF_node(dev->bus, dev->devfn);
+}
+EXPORT_SYMBOL(pci_device_to_OF_node);
+
+/* This routine is meant to be used early during boot, when the
+ * PCI bus numbers have not yet been assigned, and you need to
+ * issue PCI config cycles to an OF device.
+ * It could also be used to "fix" RTAS config cycles if you want
+ * to set pci_assign_all_buses to 1 and still use RTAS for PCI
+ * config cycles.
+ */
+struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
+{
+ if (!have_of)
+ return NULL;
+ while(node) {
+ struct pci_controller* hose;
+ for (hose=hose_head;hose;hose=hose->next)
+ if (hose->arch_data == node)
+ return hose;
+ node=node->parent;
+ }
+ return NULL;
+}
+
+static int
+find_OF_pci_device_filter(struct device_node* node, void* data)
+{
+ return ((void *)node == data);
+}
+
+/*
+ * Returns the PCI device matching a given OF node
+ */
+int
+pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
+{
+ unsigned int *reg;
+ struct pci_controller* hose;
+ struct pci_dev* dev = NULL;
+
+ if (!have_of)
+ return -ENODEV;
+ /* Make sure it's really a PCI device */
+ hose = pci_find_hose_for_OF_device(node);
+ if (!hose || !hose->arch_data)
+ return -ENODEV;
+ if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child,
+ find_OF_pci_device_filter, (void *)node))
+ return -ENODEV;
+ reg = (unsigned int *) get_property(node, "reg", NULL);
+ if (!reg)
+ return -ENODEV;
+ *bus = (reg[0] >> 16) & 0xff;
+ *devfn = ((reg[0] >> 8) & 0xff);
+
+ /* Ok, here we need some tweak. If we have already renumbered
+ * all busses, we can't rely on the OF bus number any more.
+ * the pci_to_OF_bus_map is not enough as several PCI busses
+ * may match the same OF bus number.
+ */
+ if (!pci_to_OF_bus_map)
+ return 0;
+
+ for_each_pci_dev(dev)
+ if (pci_to_OF_bus_map[dev->bus->number] == *bus &&
+ dev->devfn == *devfn) {
+ *bus = dev->bus->number;
+ pci_dev_put(dev);
+ return 0;
+ }
+
+ return -ENODEV;
+}
+EXPORT_SYMBOL(pci_device_from_OF_node);
+
+void __init
+pci_process_bridge_OF_ranges(struct pci_controller *hose,
+ struct device_node *dev, int primary)
+{
+ static unsigned int static_lc_ranges[256] __initdata;
+ unsigned int *dt_ranges, *lc_ranges, *ranges, *prev;
+ unsigned int size;
+ int rlen = 0, orig_rlen;
+ int memno = 0;
+ struct resource *res;
+ int np, na = prom_n_addr_cells(dev);
+ np = na + 5;
+
+ /* First we try to merge ranges to fix a problem with some pmacs
+ * that can have more than 3 ranges, fortunately using contiguous
+ * addresses -- BenH
+ */
+ dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
+ if (!dt_ranges)
+ return;
+ /* Sanity check, though hopefully that never happens */
+ if (rlen > sizeof(static_lc_ranges)) {
+ printk(KERN_WARNING "OF ranges property too large !\n");
+ rlen = sizeof(static_lc_ranges);
+ }
+ lc_ranges = static_lc_ranges;
+ memcpy(lc_ranges, dt_ranges, rlen);
+ orig_rlen = rlen;
+
+ /* Let's work on a copy of the "ranges" property instead of damaging
+ * the device-tree image in memory
+ */
+ ranges = lc_ranges;
+ prev = NULL;
+ while ((rlen -= np * sizeof(unsigned int)) >= 0) {
+ if (prev) {
+ if (prev[0] == ranges[0] && prev[1] == ranges[1] &&
+ (prev[2] + prev[na+4]) == ranges[2] &&
+ (prev[na+2] + prev[na+4]) == ranges[na+2]) {
+ prev[na+4] += ranges[na+4];
+ ranges[0] = 0;
+ ranges += np;
+ continue;
+ }
+ }
+ prev = ranges;
+ ranges += np;
+ }
+
+ /*
+ * The ranges property is laid out as an array of elements,
+ * each of which comprises:
+ * cells 0 - 2: a PCI address
+ * cells 3 or 3+4: a CPU physical address
+ * (size depending on dev->n_addr_cells)
+ * cells 4+5 or 5+6: the size of the range
+ */
+ ranges = lc_ranges;
+ rlen = orig_rlen;
+ while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) {
+ res = NULL;
+ size = ranges[na+4];
+ switch ((ranges[0] >> 24) & 0x3) {
+ case 1: /* I/O space */
+ if (ranges[2] != 0)
+ break;
+ hose->io_base_phys = ranges[na+2];
+ /* limit I/O space to 16MB */
+ if (size > 0x01000000)
+ size = 0x01000000;
+ hose->io_base_virt = ioremap(ranges[na+2], size);
+ if (primary)
+ isa_io_base = (unsigned long) hose->io_base_virt;
+ res = &hose->io_resource;
+ res->flags = IORESOURCE_IO;
+ res->start = ranges[2];
+ DBG("PCI: IO 0x%lx -> 0x%lx\n",
+ res->start, res->start + size - 1);
+ break;
+ case 2: /* memory space */
+ memno = 0;
+ if (ranges[1] == 0 && ranges[2] == 0
+ && ranges[na+4] <= (16 << 20)) {
+ /* 1st 16MB, i.e. ISA memory area */
+ if (primary)
+ isa_mem_base = ranges[na+2];
+ memno = 1;
+ }
+ while (memno < 3 && hose->mem_resources[memno].flags)
+ ++memno;
+ if (memno == 0)
+ hose->pci_mem_offset = ranges[na+2] - ranges[2];
+ if (memno < 3) {
+ res = &hose->mem_resources[memno];
+ res->flags = IORESOURCE_MEM;
+ if(ranges[0] & 0x40000000)
+ res->flags |= IORESOURCE_PREFETCH;
+ res->start = ranges[na+2];
+ DBG("PCI: MEM[%d] 0x%lx -> 0x%lx\n", memno,
+ res->start, res->start + size - 1);
+ }
+ break;
+ }
+ if (res != NULL) {
+ res->name = dev->full_name;
+ res->end = res->start + size - 1;
+ res->parent = NULL;
+ res->sibling = NULL;
+ res->child = NULL;
+ }
+ ranges += np;
+ }
+}
+
+/* We create the "pci-OF-bus-map" property now so it appears in the
+ * /proc device tree
+ */
+void __init
+pci_create_OF_bus_map(void)
+{
+ struct property* of_prop;
+
+ of_prop = (struct property*) alloc_bootmem(sizeof(struct property) + 256);
+ if (of_prop && find_path_device("/")) {
+ memset(of_prop, -1, sizeof(struct property) + 256);
+ of_prop->name = "pci-OF-bus-map";
+ of_prop->length = 256;
+ of_prop->value = (unsigned char *)&of_prop[1];
+ prom_add_property(find_path_device("/"), of_prop);
+ }
+}
+
+static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct pci_dev *pdev;
+ struct device_node *np;
+
+ pdev = to_pci_dev (dev);
+ np = pci_device_to_OF_node(pdev);
+ if (np == NULL || np->full_name == NULL)
+ return 0;
+ return sprintf(buf, "%s", np->full_name);
+}
+static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
+
+#else /* CONFIG_PPC_OF */
+void pcibios_make_OF_bus_map(void)
+{
+}
+#endif /* CONFIG_PPC_OF */
+
+/* Add sysfs properties */
+void pcibios_add_platform_entries(struct pci_dev *pdev)
+{
+#ifdef CONFIG_PPC_OF
+ device_create_file(&pdev->dev, &dev_attr_devspec);
+#endif /* CONFIG_PPC_OF */
+}
+
+
+#ifdef CONFIG_PPC_PMAC
+/*
+ * This set of routines checks for PCI<->PCI bridges that have closed
+ * IO resources and have child devices. It tries to re-open an IO
+ * window on them.
+ *
+ * This is a _temporary_ fix to workaround a problem with Apple's OF
+ * closing IO windows on P2P bridges when the OF drivers of cards
+ * below this bridge don't claim any IO range (typically ATI or
+ * Adaptec).
+ *
+ * A more complete fix would be to use drivers/pci/setup-bus.c, which
+ * involves a working pcibios_fixup_pbus_ranges(), some more care about
+ * ordering when creating the host bus resources, and maybe a few more
+ * minor tweaks
+ */
+
+/* Initialize bridges with base/limit values we have collected */
+static void __init
+do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga)
+{
+ struct pci_dev *bridge = bus->self;
+ struct pci_controller* hose = (struct pci_controller *)bridge->sysdata;
+ u32 l;
+ u16 w;
+ struct resource res;
+
+ if (bus->resource[0] == NULL)
+ return;
+ res = *(bus->resource[0]);
+
+ DBG("Remapping Bus %d, bridge: %s\n", bus->number, pci_name(bridge));
+ res.start -= ((unsigned long) hose->io_base_virt - isa_io_base);
+ res.end -= ((unsigned long) hose->io_base_virt - isa_io_base);
+ DBG(" IO window: %08lx-%08lx\n", res.start, res.end);
+
+ /* Set up the top and bottom of the PCI I/O segment for this bus. */
+ pci_read_config_dword(bridge, PCI_IO_BASE, &l);
+ l &= 0xffff000f;
+ l |= (res.start >> 8) & 0x00f0;
+ l |= res.end & 0xf000;
+ pci_write_config_dword(bridge, PCI_IO_BASE, l);
+
+ if ((l & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
+ l = (res.start >> 16) | (res.end & 0xffff0000);
+ pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, l);
+ }
+
+ pci_read_config_word(bridge, PCI_COMMAND, &w);
+ w |= PCI_COMMAND_IO;
+ pci_write_config_word(bridge, PCI_COMMAND, w);
+
+#if 0 /* Enabling this causes XFree 4.2.0 to hang during PCI probe */
+ if (enable_vga) {
+ pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &w);
+ w |= PCI_BRIDGE_CTL_VGA;
+ pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, w);
+ }
+#endif
+}
+
+/* This function is pretty basic and actually quite broken for the
+ * general case, it's enough for us right now though. It's supposed
+ * to tell us if we need to open an IO range at all or not and what
+ * size.
+ */
+static int __init
+check_for_io_childs(struct pci_bus *bus, struct resource* res, int *found_vga)
+{
+ struct pci_dev *dev;
+ int i;
+ int rc = 0;
+
+#define push_end(res, size) do { unsigned long __sz = (size) ; \
+ res->end = ((res->end + __sz) / (__sz + 1)) * (__sz + 1) + __sz; \
+ } while (0)
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ u16 class = dev->class >> 8;
+
+ if (class == PCI_CLASS_DISPLAY_VGA ||
+ class == PCI_CLASS_NOT_DEFINED_VGA)
+ *found_vga = 1;
+ if (class >> 8 == PCI_BASE_CLASS_BRIDGE && dev->subordinate)
+ rc |= check_for_io_childs(dev->subordinate, res, found_vga);
+ if (class == PCI_CLASS_BRIDGE_CARDBUS)
+ push_end(res, 0xfff);
+
+ for (i=0; i<PCI_NUM_RESOURCES; i++) {
+ struct resource *r;
+ unsigned long r_size;
+
+ if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI
+ && i >= PCI_BRIDGE_RESOURCES)
+ continue;
+ r = &dev->resource[i];
+ r_size = r->end - r->start;
+ if (r_size < 0xfff)
+ r_size = 0xfff;
+ if (r->flags & IORESOURCE_IO && (r_size) != 0) {
+ rc = 1;
+ push_end(res, r_size);
+ }
+ }
+ }
+
+ return rc;
+}
+
+/* Here we scan all P2P bridges of a given level that have a closed
+ * IO window. Note that the test for the presence of a VGA card should
+ * be improved to take into account already configured P2P bridges,
+ * currently, we don't see them and might end up configuring 2 bridges
+ * with VGA pass through enabled
+ */
+static void __init
+do_fixup_p2p_level(struct pci_bus *bus)
+{
+ struct pci_bus *b;
+ int i, parent_io;
+ int has_vga = 0;
+
+ for (parent_io=0; parent_io<4; parent_io++)
+ if (bus->resource[parent_io]
+ && bus->resource[parent_io]->flags & IORESOURCE_IO)
+ break;
+ if (parent_io >= 4)
+ return;
+
+ list_for_each_entry(b, &bus->children, node) {
+ struct pci_dev *d = b->self;
+ struct pci_controller* hose = (struct pci_controller *)d->sysdata;
+ struct resource *res = b->resource[0];
+ struct resource tmp_res;
+ unsigned long max;
+ int found_vga = 0;
+
+ memset(&tmp_res, 0, sizeof(tmp_res));
+ tmp_res.start = bus->resource[parent_io]->start;
+
+ /* We don't let low addresses go through that closed P2P bridge, well,
+ * that may not be necessary but I feel safer that way
+ */
+ if (tmp_res.start == 0)
+ tmp_res.start = 0x1000;
+
+ if (!list_empty(&b->devices) && res && res->flags == 0 &&
+ res != bus->resource[parent_io] &&
+ (d->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
+ check_for_io_childs(b, &tmp_res, &found_vga)) {
+ u8 io_base_lo;
+
+ printk(KERN_INFO "Fixing up IO bus %s\n", b->name);
+
+ if (found_vga) {
+ if (has_vga) {
+ printk(KERN_WARNING "Skipping VGA, already active"
+ " on bus segment\n");
+ found_vga = 0;
+ } else
+ has_vga = 1;
+ }
+ pci_read_config_byte(d, PCI_IO_BASE, &io_base_lo);
+
+ if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32)
+ max = ((unsigned long) hose->io_base_virt
+ - isa_io_base) + 0xffffffff;
+ else
+ max = ((unsigned long) hose->io_base_virt
+ - isa_io_base) + 0xffff;
+
+ *res = tmp_res;
+ res->flags = IORESOURCE_IO;
+ res->name = b->name;
+
+ /* Find a resource in the parent where we can allocate */
+ for (i = 0 ; i < 4; i++) {
+ struct resource *r = bus->resource[i];
+ if (!r)
+ continue;
+ if ((r->flags & IORESOURCE_IO) == 0)
+ continue;
+ DBG("Trying to allocate from %08lx, size %08lx from parent"
+ " res %d: %08lx -> %08lx\n",
+ res->start, res->end, i, r->start, r->end);
+
+ if (allocate_resource(r, res, res->end + 1, res->start, max,
+ res->end + 1, NULL, NULL) < 0) {
+ DBG("Failed !\n");
+ continue;
+ }
+ do_update_p2p_io_resource(b, found_vga);
+ break;
+ }
+ }
+ do_fixup_p2p_level(b);
+ }
+}
+
+static void
+pcibios_fixup_p2p_bridges(void)
+{
+ struct pci_bus *b;
+
+ list_for_each_entry(b, &pci_root_buses, node)
+ do_fixup_p2p_level(b);
+}
+
+#endif /* CONFIG_PPC_PMAC */
+
+static int __init
+pcibios_init(void)
+{
+ struct pci_controller *hose;
+ struct pci_bus *bus;
+ int next_busno;
+
+ printk(KERN_INFO "PCI: Probing PCI hardware\n");
+
+ /* Scan all of the recorded PCI controllers. */
+ for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
+ if (pci_assign_all_buses)
+ hose->first_busno = next_busno;
+ hose->last_busno = 0xff;
+ bus = pci_scan_bus(hose->first_busno, hose->ops, hose);
+ hose->last_busno = bus->subordinate;
+ if (pci_assign_all_buses || next_busno <= hose->last_busno)
+ next_busno = hose->last_busno + pcibios_assign_bus_offset;
+ }
+ pci_bus_count = next_busno;
+
+ /* OpenFirmware based machines need a map of OF bus
+ * numbers vs. kernel bus numbers since we may have to
+ * remap them.
+ */
+ if (pci_assign_all_buses && have_of)
+ pcibios_make_OF_bus_map();
+
+ /* Do machine dependent PCI interrupt routing */
+ if (ppc_md.pci_swizzle && ppc_md.pci_map_irq)
+ pci_fixup_irqs(ppc_md.pci_swizzle, ppc_md.pci_map_irq);
+
+ /* Call machine dependent fixup */
+ if (ppc_md.pcibios_fixup)
+ ppc_md.pcibios_fixup();
+
+ /* Allocate and assign resources */
+ pcibios_allocate_bus_resources(&pci_root_buses);
+ pcibios_allocate_resources(0);
+ pcibios_allocate_resources(1);
+#ifdef CONFIG_PPC_PMAC
+ pcibios_fixup_p2p_bridges();
+#endif /* CONFIG_PPC_PMAC */
+ pcibios_assign_resources();
+
+ /* Call machine dependent post-init code */
+ if (ppc_md.pcibios_after_init)
+ ppc_md.pcibios_after_init();
+
+ return 0;
+}
+
+subsys_initcall(pcibios_init);
+
+unsigned char __init
+common_swizzle(struct pci_dev *dev, unsigned char *pinp)
+{
+ struct pci_controller *hose = dev->sysdata;
+
+ if (dev->bus->number != hose->first_busno) {
+ u8 pin = *pinp;
+ do {
+ pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+ /* Move up the chain of bridges. */
+ dev = dev->bus->self;
+ } while (dev->bus->self);
+ *pinp = pin;
+
+ /* The slot is the idsel of the last bridge. */
+ }
+ return PCI_SLOT(dev->devfn);
+}
+
+unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
+ unsigned long start, unsigned long size)
+{
+ return start;
+}
+
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+ struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
+ unsigned long io_offset;
+ struct resource *res;
+ int i;
+
+ io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
+ if (bus->parent == NULL) {
+ /* This is a host bridge - fill in its resources */
+ hose->bus = bus;
+
+ bus->resource[0] = res = &hose->io_resource;
+ if (!res->flags) {
+ if (io_offset)
+ printk(KERN_ERR "I/O resource not set for host"
+ " bridge %d\n", hose->index);
+ res->start = 0;
+ res->end = IO_SPACE_LIMIT;
+ res->flags = IORESOURCE_IO;
+ }
+ res->start += io_offset;
+ res->end += io_offset;
+
+ for (i = 0; i < 3; ++i) {
+ res = &hose->mem_resources[i];
+ if (!res->flags) {
+ if (i > 0)
+ continue;
+ printk(KERN_ERR "Memory resource not set for "
+ "host bridge %d\n", hose->index);
+ res->start = hose->pci_mem_offset;
+ res->end = ~0U;
+ res->flags = IORESOURCE_MEM;
+ }
+ bus->resource[i+1] = res;
+ }
+ } else {
+ /* This is a subordinate bridge */
+ pci_read_bridge_bases(bus);
+
+ for (i = 0; i < 4; ++i) {
+ if ((res = bus->resource[i]) == NULL)
+ continue;
+ if (!res->flags)
+ continue;
+ if (io_offset && (res->flags & IORESOURCE_IO)) {
+ res->start += io_offset;
+ res->end += io_offset;
+ } else if (hose->pci_mem_offset
+ && (res->flags & IORESOURCE_MEM)) {
+ res->start += hose->pci_mem_offset;
+ res->end += hose->pci_mem_offset;
+ }
+ }
+ }
+
+ if (ppc_md.pcibios_fixup_bus)
+ ppc_md.pcibios_fixup_bus(bus);
+}
+
+char __init *pcibios_setup(char *str)
+{
+ return str;
+}
+
+/* the next one is stolen from the alpha port... */
+void __init
+pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+ /* XXX FIXME - update OF device tree node interrupt property */
+}
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+ u16 cmd, old_cmd;
+ int idx;
+ struct resource *r;
+
+ if (ppc_md.pcibios_enable_device_hook)
+ if (ppc_md.pcibios_enable_device_hook(dev, 0))
+ return -EINVAL;
+
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ old_cmd = cmd;
+ for (idx=0; idx<6; idx++) {
+ r = &dev->resource[idx];
+ if (r->flags & IORESOURCE_UNSET) {
+ printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev));
+ return -EINVAL;
+ }
+ if (r->flags & IORESOURCE_IO)
+ cmd |= PCI_COMMAND_IO;
+ if (r->flags & IORESOURCE_MEM)
+ cmd |= PCI_COMMAND_MEMORY;
+ }
+ if (cmd != old_cmd) {
+ printk("PCI: Enabling device %s (%04x -> %04x)\n",
+ pci_name(dev), old_cmd, cmd);
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+ }
+ return 0;
+}
+
+struct pci_controller*
+pci_bus_to_hose(int bus)
+{
+ struct pci_controller* hose = hose_head;
+
+ for (; hose; hose = hose->next)
+ if (bus >= hose->first_busno && bus <= hose->last_busno)
+ return hose;
+ return NULL;
+}
+
+void __iomem *
+pci_bus_io_base(unsigned int bus)
+{
+ struct pci_controller *hose;
+
+ hose = pci_bus_to_hose(bus);
+ if (!hose)
+ return NULL;
+ return hose->io_base_virt;
+}
+
+unsigned long
+pci_bus_io_base_phys(unsigned int bus)
+{
+ struct pci_controller *hose;
+
+ hose = pci_bus_to_hose(bus);
+ if (!hose)
+ return 0;
+ return hose->io_base_phys;
+}
+
+unsigned long
+pci_bus_mem_base_phys(unsigned int bus)
+{
+ struct pci_controller *hose;
+
+ hose = pci_bus_to_hose(bus);
+ if (!hose)
+ return 0;
+ return hose->pci_mem_offset;
+}
+
+unsigned long
+pci_resource_to_bus(struct pci_dev *pdev, struct resource *res)
+{
+ /* Hack alert again ! See comments in chrp_pci.c
+ */
+ struct pci_controller* hose =
+ (struct pci_controller *)pdev->sysdata;
+ if (hose && res->flags & IORESOURCE_MEM)
+ return res->start - hose->pci_mem_offset;
+ /* We may want to do something with IOs here... */
+ return res->start;
+}
+
+
+static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
+ unsigned long *offset,
+ enum pci_mmap_state mmap_state)
+{
+ struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
+ unsigned long io_offset = 0;
+ int i, res_bit;
+
+ if (hose == 0)
+ return NULL; /* should never happen */
+
+ /* If memory, add on the PCI bridge address offset */
+ if (mmap_state == pci_mmap_mem) {
+ *offset += hose->pci_mem_offset;
+ res_bit = IORESOURCE_MEM;
+ } else {
+ io_offset = hose->io_base_virt - ___IO_BASE;
+ *offset += io_offset;
+ res_bit = IORESOURCE_IO;
+ }
+
+ /*
+ * Check that the offset requested corresponds to one of the
+ * resources of the device.
+ */
+ for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+ struct resource *rp = &dev->resource[i];
+ int flags = rp->flags;
+
+ /* treat ROM as memory (should be already) */
+ if (i == PCI_ROM_RESOURCE)
+ flags |= IORESOURCE_MEM;
+
+ /* Active and same type? */
+ if ((flags & res_bit) == 0)
+ continue;
+
+ /* In the range of this resource? */
+ if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end)
+ continue;
+
+ /* found it! construct the final physical address */
+ if (mmap_state == pci_mmap_io)
+ *offset += hose->io_base_phys - io_offset;
+ return rp;
+ }
+
+ return NULL;
+}
+
+/*
+ * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
+ * device mapping.
+ */
+static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
+ pgprot_t protection,
+ enum pci_mmap_state mmap_state,
+ int write_combine)
+{
+ unsigned long prot = pgprot_val(protection);
+
+ /* Write combine is always 0 on non-memory space mappings. On
+ * memory space, if the user didn't pass 1, we check for a
+ * "prefetchable" resource. This is a bit hackish, but we use
+ * this to workaround the inability of /sysfs to provide a write
+ * combine bit
+ */
+ if (mmap_state != pci_mmap_mem)
+ write_combine = 0;
+ else if (write_combine == 0) {
+ if (rp->flags & IORESOURCE_PREFETCH)
+ write_combine = 1;
+ }
+
+ /* XXX would be nice to have a way to ask for write-through */
+ prot |= _PAGE_NO_CACHE;
+ if (write_combine)
+ prot &= ~_PAGE_GUARDED;
+ else
+ prot |= _PAGE_GUARDED;
+
+ printk("PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start,
+ prot);
+
+ return __pgprot(prot);
+}
+
+/*
+ * This one is used by /dev/mem and fbdev who have no clue about the
+ * PCI device, it tries to find the PCI device first and calls the
+ * above routine
+ */
+pgprot_t pci_phys_mem_access_prot(struct file *file,
+ unsigned long pfn,
+ unsigned long size,
+ pgprot_t protection)
+{
+ struct pci_dev *pdev = NULL;
+ struct resource *found = NULL;
+ unsigned long prot = pgprot_val(protection);
+ unsigned long offset = pfn << PAGE_SHIFT;
+ int i;
+
+ if (page_is_ram(pfn))
+ return prot;
+
+ prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
+
+ for_each_pci_dev(pdev) {
+ for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+ struct resource *rp = &pdev->resource[i];
+ int flags = rp->flags;
+
+ /* Active and same type? */
+ if ((flags & IORESOURCE_MEM) == 0)
+ continue;
+ /* In the range of this resource? */
+ if (offset < (rp->start & PAGE_MASK) ||
+ offset > rp->end)
+ continue;
+ found = rp;
+ break;
+ }
+ if (found)
+ break;
+ }
+ if (found) {
+ if (found->flags & IORESOURCE_PREFETCH)
+ prot &= ~_PAGE_GUARDED;
+ pci_dev_put(pdev);
+ }
+
+ DBG("non-PCI map for %lx, prot: %lx\n", offset, prot);
+
+ return __pgprot(prot);
+}
+
+
+/*
+ * Perform the actual remap of the pages for a PCI device mapping, as
+ * appropriate for this architecture. The region in the process to map
+ * is described by vm_start and vm_end members of VMA, the base physical
+ * address is found in vm_pgoff.
+ * The pci device structure is provided so that architectures may make mapping
+ * decisions on a per-device or per-bus basis.
+ *
+ * Returns a negative error code on failure, zero on success.
+ */
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state,
+ int write_combine)
+{
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+ struct resource *rp;
+ int ret;
+
+ rp = __pci_mmap_make_offset(dev, &offset, mmap_state);
+ if (rp == NULL)
+ return -EINVAL;
+
+ vma->vm_pgoff = offset >> PAGE_SHIFT;
+ vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO;
+ vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp,
+ vma->vm_page_prot,
+ mmap_state, write_combine);
+
+ ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot);
+
+ return ret;
+}
+
+/* Obsolete functions. Should be removed once the symbios driver
+ * is fixed
+ */
+unsigned long
+phys_to_bus(unsigned long pa)
+{
+ struct pci_controller *hose;
+ int i;
+
+ for (hose = hose_head; hose; hose = hose->next) {
+ for (i = 0; i < 3; ++i) {
+ if (pa >= hose->mem_resources[i].start
+ && pa <= hose->mem_resources[i].end) {
+ /*
+ * XXX the hose->pci_mem_offset really
+ * only applies to mem_resources[0].
+ * We need a way to store an offset for
+ * the others. -- paulus
+ */
+ if (i == 0)
+ pa -= hose->pci_mem_offset;
+ return pa;
+ }
+ }
+ }
+ /* hmmm, didn't find it */
+ return 0;
+}
+
+unsigned long
+pci_phys_to_bus(unsigned long pa, int busnr)
+{
+ struct pci_controller* hose = pci_bus_to_hose(busnr);
+ if (!hose)
+ return pa;
+ return pa - hose->pci_mem_offset;
+}
+
+unsigned long
+pci_bus_to_phys(unsigned int ba, int busnr)
+{
+ struct pci_controller* hose = pci_bus_to_hose(busnr);
+ if (!hose)
+ return ba;
+ return ba + hose->pci_mem_offset;
+}
+
+/* Provide information on locations of various I/O regions in physical
+ * memory. Do this on a per-card basis so that we choose the right
+ * root bridge.
+ * Note that the returned IO or memory base is a physical address
+ */
+
+long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
+{
+ struct pci_controller* hose;
+ long result = -EOPNOTSUPP;
+
+ /* Argh ! Please forgive me for that hack, but that's the
+ * simplest way to get existing XFree to not lockup on some
+ * G5 machines... So when something asks for bus 0 io base
+ * (bus 0 is HT root), we return the AGP one instead.
+ */
+#ifdef CONFIG_PPC_PMAC
+ if (_machine == _MACH_Pmac && machine_is_compatible("MacRISC4"))
+ if (bus == 0)
+ bus = 0xf0;
+#endif /* CONFIG_PPC_PMAC */
+
+ hose = pci_bus_to_hose(bus);
+ if (!hose)
+ return -ENODEV;
+
+ switch (which) {
+ case IOBASE_BRIDGE_NUMBER:
+ return (long)hose->first_busno;
+ case IOBASE_MEMORY:
+ return (long)hose->pci_mem_offset;
+ case IOBASE_IO:
+ return (long)hose->io_base_phys;
+ case IOBASE_ISA_IO:
+ return (long)isa_io_base;
+ case IOBASE_ISA_MEM:
+ return (long)isa_mem_base;
+ }
+
+ return result;
+}
+
+void pci_resource_to_user(const struct pci_dev *dev, int bar,
+ const struct resource *rsrc,
+ u64 *start, u64 *end)
+{
+ struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
+ unsigned long offset = 0;
+
+ if (hose == NULL)
+ return;
+
+ if (rsrc->flags & IORESOURCE_IO)
+ offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys;
+
+ *start = rsrc->start + offset;
+ *end = rsrc->end + offset;
+}
+
+void __init
+pci_init_resource(struct resource *res, unsigned long start, unsigned long end,
+ int flags, char *name)
+{
+ res->start = start;
+ res->end = end;
+ res->flags = flags;
+ res->name = name;
+ res->parent = NULL;
+ res->sibling = NULL;
+ res->child = NULL;
+}
+
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
+{
+ unsigned long start = pci_resource_start(dev, bar);
+ unsigned long len = pci_resource_len(dev, bar);
+ unsigned long flags = pci_resource_flags(dev, bar);
+
+ if (!len)
+ return NULL;
+ if (max && len > max)
+ len = max;
+ if (flags & IORESOURCE_IO)
+ return ioport_map(start, len);
+ if (flags & IORESOURCE_MEM)
+ /* Not checking IORESOURCE_CACHEABLE because PPC does
+ * not currently distinguish between ioremap and
+ * ioremap_nocache.
+ */
+ return ioremap(start, len);
+ /* What? */
+ return NULL;
+}
+
+void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
+{
+ /* Nothing to do */
+}
+EXPORT_SYMBOL(pci_iomap);
+EXPORT_SYMBOL(pci_iounmap);
+
+unsigned long pci_address_to_pio(phys_addr_t address)
+{
+ struct pci_controller* hose = hose_head;
+
+ for (; hose; hose = hose->next) {
+ unsigned int size = hose->io_resource.end -
+ hose->io_resource.start + 1;
+ if (address >= hose->io_base_phys &&
+ address < (hose->io_base_phys + size)) {
+ unsigned long base =
+ (unsigned long)hose->io_base_virt - _IO_BASE;
+ return base + (address - hose->io_base_phys);
+ }
+ }
+ return (unsigned int)-1;
+}
+EXPORT_SYMBOL(pci_address_to_pio);
+
+/*
+ * Null PCI config access functions, for the case when we can't
+ * find a hose.
+ */
+#define NULL_PCI_OP(rw, size, type) \
+static int \
+null_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \
+{ \
+ return PCIBIOS_DEVICE_NOT_FOUND; \
+}
+
+static int
+null_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ int len, u32 *val)
+{
+ return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+static int
+null_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ int len, u32 val)
+{
+ return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+static struct pci_ops null_pci_ops =
+{
+ null_read_config,
+ null_write_config
+};
+
+/*
+ * These functions are used early on before PCI scanning is done
+ * and all of the pci_dev and pci_bus structures have been created.
+ */
+static struct pci_bus *
+fake_pci_bus(struct pci_controller *hose, int busnr)
+{
+ static struct pci_bus bus;
+
+ if (hose == 0) {
+ hose = pci_bus_to_hose(busnr);
+ if (hose == 0)
+ printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr);
+ }
+ bus.number = busnr;
+ bus.sysdata = hose;
+ bus.ops = hose? hose->ops: &null_pci_ops;
+ return &bus;
+}
+
+#define EARLY_PCI_OP(rw, size, type) \
+int early_##rw##_config_##size(struct pci_controller *hose, int bus, \
+ int devfn, int offset, type value) \
+{ \
+ return pci_bus_##rw##_config_##size(fake_pci_bus(hose, bus), \
+ devfn, offset, value); \
+}
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index d963a12..7881ec9 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -605,7 +605,8 @@
opt = strstr(RELOC(prom_cmd_line), RELOC("crashkernel="));
if (opt) {
opt += 12;
- RELOC(prom_crashk_size) = prom_memparse(opt, &opt);
+ RELOC(prom_crashk_size) =
+ prom_memparse(opt, (const char **)&opt);
if (ALIGN(RELOC(prom_crashk_size), 0x1000000) !=
RELOC(prom_crashk_size)) {
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
index f40451d..7d4099a 100644
--- a/arch/powerpc/platforms/maple/pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -316,7 +316,6 @@
char* disp_name;
int *bus_range;
int primary = 1;
- struct property *of_prop;
DBG("Adding PCI host bridge %s\n", dev->full_name);
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index a1cb4d2..ec5c1e1 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -71,38 +71,60 @@
#define DBG(fmt...)
#endif
+static unsigned long maple_find_nvram_base(void)
+{
+ struct device_node *rtcs;
+ unsigned long result = 0;
+
+ /* find NVRAM device */
+ rtcs = of_find_compatible_node(NULL, "nvram", "AMD8111");
+ if (rtcs) {
+ struct resource r;
+ if (of_address_to_resource(rtcs, 0, &r)) {
+ printk(KERN_EMERG "Maple: Unable to translate NVRAM"
+ " address\n");
+ goto bail;
+ }
+ if (!(r.flags & IORESOURCE_IO)) {
+ printk(KERN_EMERG "Maple: NVRAM address isn't PIO!\n");
+ goto bail;
+ }
+ result = r.start;
+ } else
+ printk(KERN_EMERG "Maple: Unable to find NVRAM\n");
+ bail:
+ of_node_put(rtcs);
+ return result;
+}
+
static void maple_restart(char *cmd)
{
unsigned int maple_nvram_base;
unsigned int maple_nvram_offset;
unsigned int maple_nvram_command;
- struct device_node *rtcs;
+ struct device_node *sp;
- /* find NVRAM device */
- rtcs = find_compatible_devices("nvram", "AMD8111");
- if (rtcs && rtcs->addrs) {
- maple_nvram_base = rtcs->addrs[0].address;
- } else {
- printk(KERN_EMERG "Maple: Unable to find NVRAM\n");
- printk(KERN_EMERG "Maple: Manual Restart Required\n");
- return;
- }
+ maple_nvram_base = maple_find_nvram_base();
+ if (maple_nvram_base == 0)
+ goto fail;
/* find service processor device */
- rtcs = find_devices("service-processor");
- if (!rtcs) {
+ sp = of_find_node_by_name(NULL, "service-processor");
+ if (!sp) {
printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
- printk(KERN_EMERG "Maple: Manual Restart Required\n");
- return;
+ goto fail;
}
- maple_nvram_offset = *(unsigned int*) get_property(rtcs,
+ maple_nvram_offset = *(unsigned int*) get_property(sp,
"restart-addr", NULL);
- maple_nvram_command = *(unsigned int*) get_property(rtcs,
+ maple_nvram_command = *(unsigned int*) get_property(sp,
"restart-value", NULL);
+ of_node_put(sp);
/* send command */
outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
for (;;) ;
+ fail:
+ printk(KERN_EMERG "Maple: Manual Restart Required\n");
}
static void maple_power_off(void)
@@ -110,33 +132,29 @@
unsigned int maple_nvram_base;
unsigned int maple_nvram_offset;
unsigned int maple_nvram_command;
- struct device_node *rtcs;
+ struct device_node *sp;
- /* find NVRAM device */
- rtcs = find_compatible_devices("nvram", "AMD8111");
- if (rtcs && rtcs->addrs) {
- maple_nvram_base = rtcs->addrs[0].address;
- } else {
- printk(KERN_EMERG "Maple: Unable to find NVRAM\n");
- printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
- return;
- }
+ maple_nvram_base = maple_find_nvram_base();
+ if (maple_nvram_base == 0)
+ goto fail;
/* find service processor device */
- rtcs = find_devices("service-processor");
- if (!rtcs) {
+ sp = of_find_node_by_name(NULL, "service-processor");
+ if (!sp) {
printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
- printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
- return;
+ goto fail;
}
- maple_nvram_offset = *(unsigned int*) get_property(rtcs,
+ maple_nvram_offset = *(unsigned int*) get_property(sp,
"power-off-addr", NULL);
- maple_nvram_command = *(unsigned int*) get_property(rtcs,
+ maple_nvram_command = *(unsigned int*) get_property(sp,
"power-off-value", NULL);
+ of_node_put(sp);
/* send command */
outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
for (;;) ;
+ fail:
+ printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
}
static void maple_halt(void)
@@ -179,9 +197,6 @@
*/
static void __init maple_init_early(void)
{
- unsigned int default_speed;
- u64 physport;
-
DBG(" -> maple_init_early\n");
/* 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 15846cc..50bc4eb 100644
--- a/arch/powerpc/platforms/maple/time.c
+++ b/arch/powerpc/platforms/maple/time.c
@@ -168,11 +168,24 @@
struct rtc_time tm;
struct device_node *rtcs;
- rtcs = find_compatible_devices("rtc", "pnpPNP,b00");
- if (rtcs && rtcs->addrs) {
- maple_rtc_addr = rtcs->addrs[0].address;
- printk(KERN_INFO "Maple: Found RTC at 0x%x\n", maple_rtc_addr);
- } else {
+ rtcs = of_find_compatible_node(NULL, "rtc", "pnpPNP,b00");
+ if (rtcs) {
+ struct resource r;
+ if (of_address_to_resource(rtcs, 0, &r)) {
+ printk(KERN_EMERG "Maple: Unable to translate RTC"
+ " address\n");
+ goto bail;
+ }
+ if (!(r.flags & IORESOURCE_IO)) {
+ printk(KERN_EMERG "Maple: RTC address isn't PIO!\n");
+ goto bail;
+ }
+ maple_rtc_addr = r.start;
+ printk(KERN_INFO "Maple: Found RTC at IO 0x%x\n",
+ maple_rtc_addr);
+ }
+ bail:
+ if (maple_rtc_addr == 0) {
maple_rtc_addr = RTC_PORT(0); /* legacy address */
printk(KERN_INFO "Maple: No device node for RTC, assuming "
"legacy address (0x%x)\n", maple_rtc_addr);
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index d658101..11899f0 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -58,11 +58,11 @@
help
There are four types of PowerPC chips supported. The more common
types (601, 603, 604, 740, 750, 7400), the Motorola embedded
- versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the IBM embedded
- versions (403 and 405) and the high end 64 bit Power processors
- (POWER 3, POWER4, and IBM 970 also known as G5)
+ versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the IBM
+ embedded versions (403 and 405) and the POWER3 processor.
+ (For support for more recent 64-bit processors, set ARCH=powerpc.)
Unless you are building a kernel for one of the embedded processor
- systems, 64 bit IBM RS/6000 or an Apple G5, choose 6xx.
+ systems or a POWER3-based IBM RS/6000, choose 6xx.
Note that the kernel runs in 32-bit mode even on 64-bit chips.
Also note that because the 52xx, 82xx, & 83xx family has a 603e core,
specific support for that chipset is asked later on.
@@ -77,10 +77,6 @@
select PPC_FPU
bool "POWER3"
-config POWER4
- select PPC_FPU
- bool "POWER4 and 970 (G5)"
-
config 8xx
bool "8xx"
@@ -123,7 +119,7 @@
config ALTIVEC
bool "AltiVec Support"
- depends on 6xx || POWER4
+ depends on 6xx
depends on !8260 && !83xx
---help---
This option enables kernel support for the Altivec extensions to the
@@ -235,18 +231,9 @@
source "drivers/cpufreq/Kconfig"
-config CPU_FREQ_PMAC
- bool "Support for Apple PowerBooks"
- depends on CPU_FREQ && ADB_PMU
- select CPU_FREQ_TABLE
- help
- This adds support for frequency switching on Apple PowerBooks,
- this currently includes some models of iBook & Titanium
- PowerBook.
-
config PPC601_SYNC_FIX
bool "Workarounds for PPC601 bugs"
- depends on 6xx && (PPC_PREP || PPC_PMAC)
+ depends on 6xx && PPC_PREP
help
Some versions of the PPC601 (the first PowerPC chip) have bugs which
mean that extra synchronization instructions are required near
@@ -258,26 +245,17 @@
If in doubt, say Y here.
-config HOTPLUG_CPU
- bool "Support for enabling/disabling CPUs"
- depends on SMP && HOTPLUG && EXPERIMENTAL && PPC_PMAC
- ---help---
- Say Y here to be able to disable and re-enable individual
- CPUs at runtime on SMP machines.
-
- Say N if you are unsure.
-
source arch/ppc/platforms/4xx/Kconfig
source arch/ppc/platforms/85xx/Kconfig
config PPC64BRIDGE
bool
- depends on POWER3 || POWER4
+ depends on POWER3
default y
config PPC_STD_MMU
bool
- depends on 6xx || POWER3 || POWER4
+ depends on 6xx || POWER3
default y
config NOT_COHERENT_CACHE
@@ -505,7 +483,7 @@
choice
prompt "Machine Type"
- depends on 6xx || POWER3 || POWER4
+ depends on 6xx || POWER3
default PPC_MULTIPLATFORM
---help---
Linux currently supports several different kinds of PowerPC-based
@@ -516,11 +494,15 @@
Platform) machines (including all of the recent IBM RS/6000 and
pSeries machines), and several embedded PowerPC systems containing
4xx, 6xx, 7xx, 8xx, 74xx, and 82xx processors. Currently, the
- default option is to build a kernel which works on the first three.
+ default option is to build a kernel which works on PReP and CHRP.
- Select CHRP/PowerMac/PReP if configuring for an IBM RS/6000 or
- pSeries machine, a Power Macintosh (including iMacs, iBooks and
- Powerbooks), or a PReP machine.
+ Note that support for Apple machines is now only available with
+ ARCH=powerpc, and has been removed from this menu. If you wish
+ to build a kernel for an Apple machine, exit this configuration
+ process and re-run it with ARCH=powerpc.
+
+ Select CHRP/PReP if configuring for an IBM RS/6000 or
+ pSeries machine, or a PReP machine.
Select Gemini if configuring for a Synergy Microsystems' Gemini
series Single Board Computer. More information is available at:
@@ -530,7 +512,7 @@
available at: <http://linux-apus.sourceforge.net/>.
config PPC_MULTIPLATFORM
- bool "CHRP/PowerMac/PReP"
+ bool "CHRP/PReP"
config APUS
bool "Amiga-APUS"
@@ -768,25 +750,14 @@
on it (826x, 827x, 8560).
config PPC_CHRP
- bool
+ bool "Support for CHRP (Common Hardware Reference Platform) machines"
depends on PPC_MULTIPLATFORM
select PPC_I8259
select PPC_INDIRECT_PCI
default y
-config PPC_PMAC
- bool
- depends on PPC_MULTIPLATFORM
- select PPC_INDIRECT_PCI
- default y
-
-config PPC_PMAC64
- bool
- depends on PPC_PMAC && POWER4
- default y
-
config PPC_PREP
- bool
+ bool "Support for PReP (PowerPC Reference Platform) machines"
depends on PPC_MULTIPLATFORM
select PPC_I8259
select PPC_INDIRECT_PCI
@@ -794,7 +765,7 @@
config PPC_OF
bool
- depends on PPC_PMAC || PPC_CHRP
+ depends on PPC_CHRP
default y
config PPC_GEN550
@@ -1166,7 +1137,7 @@
config GENERIC_ISA_DMA
bool
- depends on POWER3 || POWER4 || 6xx && !CPM2
+ depends on POWER3 || 6xx && !CPM2
default y
config PPC_I8259
diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile
index 995f89b..efd8ce5 100644
--- a/arch/ppc/boot/Makefile
+++ b/arch/ppc/boot/Makefile
@@ -18,7 +18,7 @@
bootdir-y := simple
bootdir-$(CONFIG_PPC_OF) += openfirmware
subdir-y := lib common images
-subdir-$(CONFIG_PPC_OF) += of1275
+subdir-$(CONFIG_PPC_MULTIPLATFORM) += of1275
# for cleaning
subdir- += simple openfirmware
diff --git a/arch/ppc/boot/openfirmware/Makefile b/arch/ppc/boot/openfirmware/Makefile
index 83a6433..2a411ec 100644
--- a/arch/ppc/boot/openfirmware/Makefile
+++ b/arch/ppc/boot/openfirmware/Makefile
@@ -21,26 +21,16 @@
of1275 := $(boot)/of1275
images := $(boot)/images
-OBJCOPY_ARGS := -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
-COFF_LD_ARGS := -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00500000 \
- -Bstatic
CHRP_LD_ARGS := -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00800000
-NEWWORLD_LD_ARGS:= -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x01000000
COMMONOBJS := start.o misc.o common.o
-COFFOBJS := coffcrt0.o $(COMMONOBJS) coffmain.o
CHRPOBJS := crt0.o $(COMMONOBJS) chrpmain.o
-NEWWORLDOBJS := crt0.o $(COMMONOBJS) newworldmain.o
-targets := $(COFFOBJS) $(CHRPOBJS) $(NEWWORLDOBJS) dummy.o
-COFFOBJS := $(addprefix $(obj)/, $(COFFOBJS))
+targets := $(CHRPOBJS) dummy.o
CHRPOBJS := $(addprefix $(obj)/, $(CHRPOBJS))
-NEWWORLDOBJS := $(addprefix $(obj)/, $(NEWWORLDOBJS))
LIBS := lib/lib.a $(bootlib)/lib.a $(of1275)/lib.a $(common)/lib.a
-HACKCOFF := $(utils)/hack-coff
-
ifdef CONFIG_SMP
END := .smp
endif
@@ -72,56 +62,11 @@
$(obj)/image.initrd.o: $(obj)/image.o $(images)/ramdisk.image.gz FORCE
$(call if_changed,genimage-initrd)
-# Create the note section for New-World PowerMacs.
-quiet_cmd_mknote = MKNOTE $@
- cmd_mknote = $(utils)/mknote > $@
-targets += note
-$(obj)/note: $(utils)/mknote FORCE
- $(call if_changed,mknote)
-
-$(obj)/coffcrt0.o: EXTRA_AFLAGS := -DXCOFF
-targets += coffcrt0.o crt0.o
-$(obj)/coffcrt0.o $(obj)/crt0.o: $(common)/crt0.S FORCE
+targets += crt0.o
+$(obj)/crt0.o: $(common)/crt0.S FORCE
$(call if_changed_dep,as_o_S)
-quiet_cmd_gencoffb = COFF $@
- cmd_gencoffb = $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) $< $(LIBS) && \
- $(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec)
-targets += coffboot
-$(obj)/coffboot: $(obj)/image.o $(COFFOBJS) $(LIBS) $(srctree)/$(boot)/ld.script FORCE
- $(call if_changed,gencoffb)
-targets += coffboot.initrd
-$(obj)/coffboot.initrd: $(obj)/image.initrd.o $(COFFOBJS) $(LIBS) \
- $(srctree)/$(boot)/ld.script FORCE
- $(call if_changed,gencoffb)
-
-
-quiet_cmd_gen-coff = COFF $@
- cmd_gen-coff = $(OBJCOPY) $(OBJCOPY_ARGS) $< $@ && \
- $(HACKCOFF) $@ && \
- ln -sf $(notdir $@) $(images)/zImage$(initrd).pmac
-
-$(images)/vmlinux.coff: $(obj)/coffboot
- $(call cmd,gen-coff)
-
-$(images)/vmlinux.initrd.coff: $(obj)/coffboot.initrd
- $(call cmd,gen-coff)
-
-quiet_cmd_gen-elf-pmac = ELF $@
- cmd_gen-elf-pmac = $(LD) $(NEWWORLD_LD_ARGS) -o $@ \
- $(NEWWORLDOBJS) $(LIBS) $< && \
- $(OBJCOPY) $@ $@ --add-section=.note=$(obj)/note \
- -R .comment $(del-ramdisk-sec)
-
-$(images)/vmlinux.elf-pmac: $(obj)/image.o $(NEWWORLDOBJS) $(LIBS) \
- $(obj)/note $(srctree)/$(boot)/ld.script
- $(call cmd,gen-elf-pmac)
-$(images)/vmlinux.initrd.elf-pmac: $(obj)/image.initrd.o $(NEWWORLDOBJS) \
- $(LIBS) $(obj)/note \
- $(srctree)/$(boot)/ld.script
- $(call cmd,gen-elf-pmac)
-
quiet_cmd_gen-chrp = CHRP $@
cmd_gen-chrp = $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) $< $(LIBS) && \
$(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec)
@@ -139,46 +84,23 @@
%-rs6k: %
$(call cmd,addnote)
-quiet_cmd_gen-miboot = GEN $@
- cmd_gen-miboot = $(OBJCOPY) $(OBJCOPY_ARGS) \
- --add-section=$1=$(word 2, $^) $< $@
-$(images)/miboot.image: $(obj)/dummy.o $(images)/vmlinux.gz
- $(call cmd,gen-miboot,image)
-
-$(images)/miboot.initrd.image: $(images)/miboot.image $(images)/ramdisk.image.gz
- $(call cmd,gen-miboot,initrd)
-
# The targets used on the make command-line
.PHONY: zImage zImage.initrd
-zImage: $(images)/vmlinux.coff \
- $(images)/vmlinux.elf-pmac \
- $(images)/zImage.chrp \
- $(images)/zImage.chrp-rs6k \
- $(images)/miboot.image
+zImage: $(images)/zImage.chrp \
+ $(images)/zImage.chrp-rs6k
@echo ' kernel: $@ is ready ($<)'
-zImage.initrd: $(images)/vmlinux.initrd.coff \
- $(images)/vmlinux.initrd.elf-pmac \
- $(images)/zImage.initrd.chrp \
- $(images)/zImage.initrd.chrp-rs6k \
- $(images)/miboot.initrd.image
+zImage.initrd: $(images)/zImage.initrd.chrp \
+ $(images)/zImage.initrd.chrp-rs6k
@echo ' kernel: $@ is ready ($<)'
TFTPIMAGE := /tftpboot/zImage
.PHONY: znetboot znetboot.initrd
-znetboot: $(images)/vmlinux.coff \
- $(images)/vmlinux.elf-pmac \
- $(images)/zImage.chrp
- cp $(images)/vmlinux.coff $(TFTPIMAGE).pmac$(END)
- cp $(images)/vmlinux.elf-pmac $(TFTPIMAGE).pmac$(END).elf
+znetboot: $(images)/zImage.chrp
cp $(images)/zImage.chrp $(TFTPIMAGE).chrp$(END)
@echo ' kernel: $@ is ready ($<)'
-znetboot.initrd:$(images)/vmlinux.initrd.coff \
- $(images)/vmlinux.initrd.elf-pmac \
- $(images)/zImage.initrd.chrp
- cp $(images)/vmlinux.initrd.coff $(TFTPIMAGE).pmac$(END)
- cp $(images)/vmlinux.initrd.elf-pmac $(TFTPIMAGE).pmac$(END).elf
+znetboot.initrd:$(images)/zImage.initrd.chrp
cp $(images)/zImage.initrd.chrp $(TFTPIMAGE).chrp$(END)
@echo ' kernel: $@ is ready ($<)'
diff --git a/arch/ppc/boot/openfirmware/coffmain.c b/arch/ppc/boot/openfirmware/coffmain.c
deleted file mode 100644
index 2da8855..0000000
--- a/arch/ppc/boot/openfirmware/coffmain.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include <linux/string.h>
-#include <asm/processor.h>
-#include <asm/page.h>
-
-#include "nonstdio.h"
-#include "of1275.h"
-
-/* Passed from the linker */
-extern char __image_begin, __image_end;
-extern char __ramdisk_begin[], __ramdisk_end;
-extern char _start, _end;
-
-extern char image_data[], initrd_data[];
-extern int initrd_len, image_len;
-extern unsigned int heap_max;
-extern void flush_cache(void *start, unsigned int len);
-extern void gunzip(void *, int, unsigned char *, int *);
-extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
- unsigned int progend);
-extern void setup_bats(unsigned long start);
-
-char *avail_ram;
-char *begin_avail, *end_avail;
-char *avail_high;
-
-#define SCRATCH_SIZE (128 << 10)
-
-static char heap[SCRATCH_SIZE];
-
-static unsigned long ram_start = 0;
-static unsigned long ram_end = 0x1000000;
-
-static unsigned long prog_start = 0x800000;
-static unsigned long prog_size = 0x700000;
-
-typedef void (*kernel_start_t)(int, int, void *);
-
-void boot(int a1, int a2, void *prom)
-{
- unsigned sa, len;
- void *dst;
- unsigned char *im;
- unsigned initrd_start, initrd_size;
-
- printf("coffboot starting: loaded at 0x%p\n", &_start);
- setup_bats(ram_start);
-
- initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin);
- if (initrd_size) {
- initrd_start = (ram_end - initrd_size) & ~0xFFF;
- a1 = initrd_start;
- a2 = initrd_size;
- claim(initrd_start, ram_end - initrd_start, 0);
- printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r",
- initrd_start, (char *)(&__ramdisk_begin), initrd_size);
- memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size);
- prog_size = initrd_start - prog_start;
- } else
- a2 = 0xdeadbeef;
-
- im = (char *)(&__image_begin);
- len = (char *)(&__image_end) - (char *)(&__image_begin);
- /* claim 4MB starting at PROG_START */
- claim(prog_start, prog_size, 0);
- map(prog_start, prog_start, prog_size);
- dst = (void *) prog_start;
- if (im[0] == 0x1f && im[1] == 0x8b) {
- /* set up scratch space */
- begin_avail = avail_high = avail_ram = heap;
- end_avail = heap + sizeof(heap);
- printf("heap at 0x%p\n", avail_ram);
- printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
- gunzip(dst, prog_size, im, &len);
- printf("done %u bytes\n", len);
- printf("%u bytes of heap consumed, max in use %u\n",
- avail_high - begin_avail, heap_max);
- } else {
- memmove(dst, im, len);
- }
-
- flush_cache(dst, len);
- make_bi_recs(((unsigned long) dst + len), "coffboot", _MACH_Pmac,
- (prog_start + prog_size));
-
- sa = (unsigned long)prog_start;
- printf("start address = 0x%x\n", sa);
-
- (*(kernel_start_t)sa)(a1, a2, prom);
-
- printf("returned?\n");
-
- pause();
-}
diff --git a/arch/ppc/boot/openfirmware/newworldmain.c b/arch/ppc/boot/openfirmware/newworldmain.c
deleted file mode 100644
index fa8a8f9..0000000
--- a/arch/ppc/boot/openfirmware/newworldmain.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include <linux/string.h>
-#include "nonstdio.h"
-#include "of1275.h"
-#include <asm/processor.h>
-#include <asm/page.h>
-
-/* Passed from the linker */
-extern char __image_begin, __image_end;
-extern char __ramdisk_begin[], __ramdisk_end;
-extern char _start, _end;
-
-extern unsigned int heap_max;
-extern void flush_cache(void *start, unsigned int len);
-extern void gunzip(void *, int, unsigned char *, int *);
-extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
- unsigned int progend);
-
-char *avail_ram;
-char *begin_avail, *end_avail;
-char *avail_high;
-
-
-#define RAM_END (16 << 20)
-
-#define PROG_START 0x00010000
-#define PROG_SIZE 0x007f0000
-
-#define SCRATCH_SIZE (128 << 10)
-
-typedef void (*kernel_start_t)(int, int, void *);
-
-void boot(int a1, int a2, void *prom)
-{
- unsigned sa, len;
- void *dst;
- unsigned char *im;
- unsigned initrd_start, initrd_size;
-
- printf("chrpboot starting: loaded at 0x%p\n", &_start);
-
- initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin);
- if (initrd_size) {
- initrd_start = (RAM_END - initrd_size) & ~0xFFF;
- a1 = initrd_start;
- a2 = initrd_size;
- claim(initrd_start, RAM_END - initrd_start, 0);
- printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r",
- initrd_start, (char *)(&__ramdisk_begin), initrd_size);
- memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size);
- } else
- a2 = 0xdeadbeef;
-
- im = (char *)(&__image_begin);
- len = (char *)(&__image_end) - (char *)(&__image_begin);
- /* claim 3MB starting at PROG_START */
- claim(PROG_START, PROG_SIZE, 0);
- dst = (void *) PROG_START;
- if (im[0] == 0x1f && im[1] == 0x8b) {
- /* claim some memory for scratch space */
- avail_ram = (char *) claim(0, SCRATCH_SIZE, 0x10);
- begin_avail = avail_high = avail_ram;
- end_avail = avail_ram + SCRATCH_SIZE;
- printf("heap at 0x%p\n", avail_ram);
- printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
- gunzip(dst, PROG_SIZE, im, &len);
- printf("done %u bytes\n", len);
- printf("%u bytes of heap consumed, max in use %u\n",
- avail_high - begin_avail, heap_max);
- release(begin_avail, SCRATCH_SIZE);
- } else {
- memmove(dst, im, len);
- }
-
- flush_cache(dst, len);
- make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_Pmac,
- (PROG_START + PROG_SIZE));
-
- sa = (unsigned long)PROG_START;
- printf("start address = 0x%x\n", sa);
-
- (*(kernel_start_t)sa)(a1, a2, prom);
-
- printf("returned?\n");
-
- pause();
-}
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index ca02013..e399bbb 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -9,7 +9,6 @@
extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o
extra-$(CONFIG_8xx) := head_8xx.o
extra-$(CONFIG_6xx) += idle_6xx.o
-extra-$(CONFIG_POWER4) += idle_power4.o
extra-y += vmlinux.lds
obj-y := entry.o traps.o idle.o time.o misc.o \
@@ -17,7 +16,6 @@
ppc_htab.o
obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
-obj-$(CONFIG_POWER4) += cpu_setup_power4.o
obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o
obj-$(CONFIG_PCI) += pci.o
@@ -42,7 +40,6 @@
obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o
-obj-$(CONFIG_PCI) += pci.o
obj-$(CONFIG_KGDB) += ppc-stub.o
obj-$(CONFIG_TAU) += temp.o
ifndef CONFIG_E200
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index fb5658b..c3427ee 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -204,78 +204,6 @@
mtctr r5
bctr
-#if defined(CONFIG_CPU_FREQ_PMAC) && defined(CONFIG_6xx)
-
-/* This gets called by via-pmu.c to switch the PLL selection
- * on 750fx CPU. This function should really be moved to some
- * other place (as most of the cpufreq code in via-pmu
- */
-_GLOBAL(low_choose_750fx_pll)
- /* Clear MSR:EE */
- mfmsr r7
- rlwinm r0,r7,0,17,15
- mtmsr r0
-
- /* If switching to PLL1, disable HID0:BTIC */
- cmplwi cr0,r3,0
- beq 1f
- mfspr r5,SPRN_HID0
- rlwinm r5,r5,0,27,25
- sync
- mtspr SPRN_HID0,r5
- isync
- sync
-
-1:
- /* Calc new HID1 value */
- mfspr r4,SPRN_HID1 /* Build a HID1:PS bit from parameter */
- rlwinm r5,r3,16,15,15 /* Clear out HID1:PS from value read */
- rlwinm r4,r4,0,16,14 /* Could have I used rlwimi here ? */
- or r4,r4,r5
- mtspr SPRN_HID1,r4
-
- /* Store new HID1 image */
- rlwinm r6,r1,0,0,18
- lwz r6,TI_CPU(r6)
- slwi r6,r6,2
- addis r6,r6,nap_save_hid1@ha
- stw r4,nap_save_hid1@l(r6)
-
- /* If switching to PLL0, enable HID0:BTIC */
- cmplwi cr0,r3,0
- bne 1f
- mfspr r5,SPRN_HID0
- ori r5,r5,HID0_BTIC
- sync
- mtspr SPRN_HID0,r5
- isync
- sync
-
-1:
- /* Return */
- mtmsr r7
- blr
-
-_GLOBAL(low_choose_7447a_dfs)
- /* Clear MSR:EE */
- mfmsr r7
- rlwinm r0,r7,0,17,15
- mtmsr r0
-
- /* Calc new HID1 value */
- mfspr r4,SPRN_HID1
- insrwi r4,r3,1,9 /* insert parameter into bit 9 */
- sync
- mtspr SPRN_HID1,r4
- sync
- isync
-
- /* Return */
- mtmsr r7
- blr
-
-#endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_6xx */
-
/*
* complement mask on the msr then "or" some values on.
* _nmask_and_or_msr(nmask, value_to_or)
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 704c846..04d04c5 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -1,5 +1,5 @@
/*
- * Common pmac/prep/chrp pci routines. -- Cort
+ * Common prep/chrp pci routines. -- Cort
*/
#include <linux/config.h>
@@ -50,8 +50,7 @@
static u8* pci_to_OF_bus_map;
#endif
-/* By default, we don't re-assign bus numbers. We do this only on
- * some pmacs
+/* By default, we don't re-assign bus numbers.
*/
int pci_assign_all_buses;
@@ -780,17 +779,6 @@
return NULL;
/* Fixup bus number according to what OF think it is. */
-#ifdef CONFIG_PPC_PMAC
- /* The G5 need a special case here. Basically, we don't remap all
- * busses on it so we don't create the pci-OF-map. However, we do
- * remap the AGP bus and so have to deal with it. A future better
- * fix has to be done by making the remapping per-host and always
- * filling the pci_to_OF map. --BenH
- */
- if (_machine == _MACH_Pmac && busnr >= 0xf0)
- busnr -= 0xf0;
- else
-#endif
if (pci_to_OF_bus_map)
busnr = pci_to_OF_bus_map[busnr];
if (busnr == 0xff)
@@ -1040,216 +1028,6 @@
}
-#ifdef CONFIG_PPC_PMAC
-/*
- * This set of routines checks for PCI<->PCI bridges that have closed
- * IO resources and have child devices. It tries to re-open an IO
- * window on them.
- *
- * This is a _temporary_ fix to workaround a problem with Apple's OF
- * closing IO windows on P2P bridges when the OF drivers of cards
- * below this bridge don't claim any IO range (typically ATI or
- * Adaptec).
- *
- * A more complete fix would be to use drivers/pci/setup-bus.c, which
- * involves a working pcibios_fixup_pbus_ranges(), some more care about
- * ordering when creating the host bus resources, and maybe a few more
- * minor tweaks
- */
-
-/* Initialize bridges with base/limit values we have collected */
-static void __init
-do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga)
-{
- struct pci_dev *bridge = bus->self;
- struct pci_controller* hose = (struct pci_controller *)bridge->sysdata;
- u32 l;
- u16 w;
- struct resource res;
-
- if (bus->resource[0] == NULL)
- return;
- res = *(bus->resource[0]);
-
- DBG("Remapping Bus %d, bridge: %s\n", bus->number, pci_name(bridge));
- res.start -= ((unsigned long) hose->io_base_virt - isa_io_base);
- res.end -= ((unsigned long) hose->io_base_virt - isa_io_base);
- DBG(" IO window: %08lx-%08lx\n", res.start, res.end);
-
- /* Set up the top and bottom of the PCI I/O segment for this bus. */
- pci_read_config_dword(bridge, PCI_IO_BASE, &l);
- l &= 0xffff000f;
- l |= (res.start >> 8) & 0x00f0;
- l |= res.end & 0xf000;
- pci_write_config_dword(bridge, PCI_IO_BASE, l);
-
- if ((l & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
- l = (res.start >> 16) | (res.end & 0xffff0000);
- pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, l);
- }
-
- pci_read_config_word(bridge, PCI_COMMAND, &w);
- w |= PCI_COMMAND_IO;
- pci_write_config_word(bridge, PCI_COMMAND, w);
-
-#if 0 /* Enabling this causes XFree 4.2.0 to hang during PCI probe */
- if (enable_vga) {
- pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &w);
- w |= PCI_BRIDGE_CTL_VGA;
- pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, w);
- }
-#endif
-}
-
-/* This function is pretty basic and actually quite broken for the
- * general case, it's enough for us right now though. It's supposed
- * to tell us if we need to open an IO range at all or not and what
- * size.
- */
-static int __init
-check_for_io_childs(struct pci_bus *bus, struct resource* res, int *found_vga)
-{
- struct pci_dev *dev;
- int i;
- int rc = 0;
-
-#define push_end(res, size) do { unsigned long __sz = (size) ; \
- res->end = ((res->end + __sz) / (__sz + 1)) * (__sz + 1) + __sz; \
- } while (0)
-
- list_for_each_entry(dev, &bus->devices, bus_list) {
- u16 class = dev->class >> 8;
-
- if (class == PCI_CLASS_DISPLAY_VGA ||
- class == PCI_CLASS_NOT_DEFINED_VGA)
- *found_vga = 1;
- if (class >> 8 == PCI_BASE_CLASS_BRIDGE && dev->subordinate)
- rc |= check_for_io_childs(dev->subordinate, res, found_vga);
- if (class == PCI_CLASS_BRIDGE_CARDBUS)
- push_end(res, 0xfff);
-
- for (i=0; i<PCI_NUM_RESOURCES; i++) {
- struct resource *r;
- unsigned long r_size;
-
- if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI
- && i >= PCI_BRIDGE_RESOURCES)
- continue;
- r = &dev->resource[i];
- r_size = r->end - r->start;
- if (r_size < 0xfff)
- r_size = 0xfff;
- if (r->flags & IORESOURCE_IO && (r_size) != 0) {
- rc = 1;
- push_end(res, r_size);
- }
- }
- }
-
- return rc;
-}
-
-/* Here we scan all P2P bridges of a given level that have a closed
- * IO window. Note that the test for the presence of a VGA card should
- * be improved to take into account already configured P2P bridges,
- * currently, we don't see them and might end up configuring 2 bridges
- * with VGA pass through enabled
- */
-static void __init
-do_fixup_p2p_level(struct pci_bus *bus)
-{
- struct pci_bus *b;
- int i, parent_io;
- int has_vga = 0;
-
- for (parent_io=0; parent_io<4; parent_io++)
- if (bus->resource[parent_io]
- && bus->resource[parent_io]->flags & IORESOURCE_IO)
- break;
- if (parent_io >= 4)
- return;
-
- list_for_each_entry(b, &bus->children, node) {
- struct pci_dev *d = b->self;
- struct pci_controller* hose = (struct pci_controller *)d->sysdata;
- struct resource *res = b->resource[0];
- struct resource tmp_res;
- unsigned long max;
- int found_vga = 0;
-
- memset(&tmp_res, 0, sizeof(tmp_res));
- tmp_res.start = bus->resource[parent_io]->start;
-
- /* We don't let low addresses go through that closed P2P bridge, well,
- * that may not be necessary but I feel safer that way
- */
- if (tmp_res.start == 0)
- tmp_res.start = 0x1000;
-
- if (!list_empty(&b->devices) && res && res->flags == 0 &&
- res != bus->resource[parent_io] &&
- (d->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
- check_for_io_childs(b, &tmp_res, &found_vga)) {
- u8 io_base_lo;
-
- printk(KERN_INFO "Fixing up IO bus %s\n", b->name);
-
- if (found_vga) {
- if (has_vga) {
- printk(KERN_WARNING "Skipping VGA, already active"
- " on bus segment\n");
- found_vga = 0;
- } else
- has_vga = 1;
- }
- pci_read_config_byte(d, PCI_IO_BASE, &io_base_lo);
-
- if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32)
- max = ((unsigned long) hose->io_base_virt
- - isa_io_base) + 0xffffffff;
- else
- max = ((unsigned long) hose->io_base_virt
- - isa_io_base) + 0xffff;
-
- *res = tmp_res;
- res->flags = IORESOURCE_IO;
- res->name = b->name;
-
- /* Find a resource in the parent where we can allocate */
- for (i = 0 ; i < 4; i++) {
- struct resource *r = bus->resource[i];
- if (!r)
- continue;
- if ((r->flags & IORESOURCE_IO) == 0)
- continue;
- DBG("Trying to allocate from %08lx, size %08lx from parent"
- " res %d: %08lx -> %08lx\n",
- res->start, res->end, i, r->start, r->end);
-
- if (allocate_resource(r, res, res->end + 1, res->start, max,
- res->end + 1, NULL, NULL) < 0) {
- DBG("Failed !\n");
- continue;
- }
- do_update_p2p_io_resource(b, found_vga);
- break;
- }
- }
- do_fixup_p2p_level(b);
- }
-}
-
-static void
-pcibios_fixup_p2p_bridges(void)
-{
- struct pci_bus *b;
-
- list_for_each_entry(b, &pci_root_buses, node)
- do_fixup_p2p_level(b);
-}
-
-#endif /* CONFIG_PPC_PMAC */
-
static int __init
pcibios_init(void)
{
@@ -1290,9 +1068,6 @@
pcibios_allocate_bus_resources(&pci_root_buses);
pcibios_allocate_resources(0);
pcibios_allocate_resources(1);
-#ifdef CONFIG_PPC_PMAC
- pcibios_fixup_p2p_bridges();
-#endif /* CONFIG_PPC_PMAC */
pcibios_assign_resources();
/* Call machine dependent post-init code */
@@ -1722,17 +1497,6 @@
struct pci_controller* hose;
long result = -EOPNOTSUPP;
- /* Argh ! Please forgive me for that hack, but that's the
- * simplest way to get existing XFree to not lockup on some
- * G5 machines... So when something asks for bus 0 io base
- * (bus 0 is HT root), we return the AGP one instead.
- */
-#ifdef CONFIG_PPC_PMAC
- if (_machine == _MACH_Pmac && machine_is_compatible("MacRISC4"))
- if (bus == 0)
- bus = 0xf0;
-#endif /* CONFIG_PPC_PMAC */
-
hose = pci_bus_to_hose(bus);
if (!hose)
return -ENODEV;
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index fb0da7c..3a6e4bc 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -34,7 +34,6 @@
#include <asm/system.h>
#include <asm/pci-bridge.h>
#include <asm/irq.h>
-#include <asm/pmac_feature.h>
#include <asm/dma.h>
#include <asm/machdep.h>
#include <asm/hw_irq.h>
@@ -58,7 +57,6 @@
extern void alignment_exception(struct pt_regs *regs);
extern void program_check_exception(struct pt_regs *regs);
extern void single_step_exception(struct pt_regs *regs);
-extern int pmac_newworld;
extern int sys_sigreturn(struct pt_regs *regs);
long long __ashrdi3(long long, int);
@@ -213,10 +211,6 @@
EXPORT_SYMBOL(cuda_request);
EXPORT_SYMBOL(cuda_poll);
#endif /* CONFIG_ADB_CUDA */
-#ifdef CONFIG_PPC_PMAC
-EXPORT_SYMBOL(sys_ctrler);
-EXPORT_SYMBOL(pmac_newworld);
-#endif
#ifdef CONFIG_PPC_OF
EXPORT_SYMBOL(find_devices);
EXPORT_SYMBOL(find_type_devices);
@@ -241,9 +235,6 @@
#if defined(CONFIG_BOOTX_TEXT)
EXPORT_SYMBOL(btext_update_display);
#endif
-#if defined(CONFIG_SCSI) && defined(CONFIG_PPC_PMAC)
-EXPORT_SYMBOL(note_scsi_host);
-#endif
#ifdef CONFIG_VT
EXPORT_SYMBOL(kd_mksound);
#endif
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index e707c6f..c08ab432 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -1,5 +1,5 @@
/*
- * Common prep/pmac/chrp boot and setup code.
+ * Common prep/chrp boot and setup code.
*/
#include <linux/config.h>
@@ -35,7 +35,6 @@
#include <asm/machdep.h>
#include <asm/uaccess.h>
#include <asm/system.h>
-#include <asm/pmac_feature.h>
#include <asm/sections.h>
#include <asm/nvram.h>
#include <asm/xmon.h>
@@ -55,7 +54,6 @@
extern void platform_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7);
-extern void bootx_init(unsigned long r4, unsigned long phys);
extern void identify_cpu(unsigned long offset, unsigned long cpu);
extern void do_cpu_ftr_fixups(unsigned long offset);
extern void reloc_got2(unsigned long offset);
@@ -80,8 +78,6 @@
extern void prep_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7);
-extern void pmac_init(unsigned long r3, unsigned long r4,
- unsigned long r5, unsigned long r6, unsigned long r7);
extern void chrp_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7);
@@ -324,20 +320,15 @@
identify_cpu(offset, 0);
do_cpu_ftr_fixups(offset);
-#if defined(CONFIG_PPC_MULTIPLATFORM)
+#if defined(CONFIG_PPC_OF)
reloc_got2(offset);
- /* If we came here from BootX, clear the screen,
- * set up some pointers and return. */
- if ((r3 == 0x426f6f58) && (r5 == 0))
- bootx_init(r4, phys);
-
/*
* don't do anything on prep
* for now, don't use bootinfo because it breaks yaboot 0.5
* and assume that if we didn't find a magic number, we have OF
*/
- else if (*(unsigned long *)(0) != 0xdeadc0de)
+ if (*(unsigned long *)(0) != 0xdeadc0de)
phys = prom_init(r3, r4, (prom_entry)r5);
reloc_got2(-offset);
@@ -424,6 +415,7 @@
}
#endif
+#ifdef CONFIG_PPC_OF
have_of = 1;
/* prom_init has already been called from __start */
@@ -495,19 +487,17 @@
#endif /* CONFIG_ADB */
switch (_machine) {
-#ifdef CONFIG_PPC_PMAC
- case _MACH_Pmac:
- pmac_init(r3, r4, r5, r6, r7);
- break;
-#endif
#ifdef CONFIG_PPC_CHRP
case _MACH_chrp:
chrp_init(r3, r4, r5, r6, r7);
break;
#endif
}
+#endif /* CONFIG_PPC_OF */
}
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+#ifdef CONFIG_PPC_OF
#ifdef CONFIG_SERIAL_CORE_CONSOLE
extern char *of_stdout_device;
@@ -564,7 +554,7 @@
}
console_initcall(set_preferred_console);
#endif /* CONFIG_SERIAL_CORE_CONSOLE */
-#endif /* CONFIG_PPC_MULTIPLATFORM */
+#endif /* CONFIG_PPC_OF */
struct bi_record *find_bootinfo(void)
{
@@ -747,14 +737,6 @@
if (ppc_md.init_early)
ppc_md.init_early();
-#ifdef CONFIG_PPC_MULTIPLATFORM
- /* This could be called "early setup arch", it must be done
- * now because xmon need it
- */
- if (_machine == _MACH_Pmac)
- pmac_feature_init(); /* New cool way */
-#endif
-
#ifdef CONFIG_XMON
xmon_init(1);
if (strstr(cmd_line, "xmon"))
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index 9dbc4d2..6d0a183 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -38,9 +38,6 @@
#include <asm/io.h>
#include <asm/reg.h>
#include <asm/xmon.h>
-#ifdef CONFIG_PMAC_BACKLIGHT
-#include <asm/backlight.h>
-#endif
#include <asm/pmc.h>
#ifdef CONFIG_XMON
@@ -85,12 +82,6 @@
int nl = 0;
console_verbose();
spin_lock_irq(&die_lock);
-#ifdef CONFIG_PMAC_BACKLIGHT
- if (_machine == _MACH_Pmac) {
- set_backlight_enable(1);
- set_backlight_level(BACKLIGHT_MAX);
- }
-#endif
printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
#ifdef CONFIG_PREEMPT
printk("PREEMPT ");
@@ -159,7 +150,7 @@
*/
static inline int check_io_access(struct pt_regs *regs)
{
-#if defined CONFIG_PPC_PMAC || defined CONFIG_8xx
+#if defined CONFIG_8xx
unsigned long msr = regs->msr;
const struct exception_table_entry *entry;
unsigned int *nip = (unsigned int *)regs->nip;
@@ -196,7 +187,7 @@
return 1;
}
}
-#endif /* CONFIG_PPC_PMAC */
+#endif /* CONFIG_8xx */
return 0;
}
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index 45f0782..134db5c 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -67,10 +67,6 @@
int mem_init_done;
int init_bootmem_done;
int boot_mapsize;
-#ifdef CONFIG_PPC_PMAC
-unsigned long agp_special_page;
-EXPORT_SYMBOL(agp_special_page);
-#endif
extern char _end[];
extern char etext[], _stext[];
@@ -424,10 +420,6 @@
addr += PAGE_SIZE)
SetPageReserved(virt_to_page(addr));
#endif
-#ifdef CONFIG_PPC_PMAC
- if (agp_special_page)
- SetPageReserved(virt_to_page(agp_special_page));
-#endif
for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory;
addr += PAGE_SIZE) {
if (!PageReserved(virt_to_page(addr)))
@@ -463,11 +455,6 @@
initpages<< (PAGE_SHIFT-10),
(unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
-#ifdef CONFIG_PPC_PMAC
- if (agp_special_page)
- printk(KERN_INFO "AGP special page: 0x%08lx\n", agp_special_page);
-#endif
-
mem_init_done = 1;
}
@@ -512,22 +499,6 @@
if (rtas_data)
mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1);
#endif
-#ifdef CONFIG_PPC_PMAC
- /* Because of some uninorth weirdness, we need a page of
- * memory as high as possible (it must be outside of the
- * bus address seen as the AGP aperture). It will be used
- * by the r128 DRM driver
- *
- * FIXME: We need to make sure that page doesn't overlap any of the\
- * above. This could be done by improving mem_pieces_find to be able
- * to do a backward search from the end of the list.
- */
- if (_machine == _MACH_Pmac && find_devices("uni-north-agp")) {
- agp_special_page = (total_memory - PAGE_SIZE);
- mem_pieces_remove(&phys_avail, agp_special_page, PAGE_SIZE, 0);
- agp_special_page = (unsigned long)__va(agp_special_page);
- }
-#endif /* CONFIG_PPC_PMAC */
}
/* Mark some memory as reserved by removing it from phys_avail. */
diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile
index 7c5cdab..51430e2 100644
--- a/arch/ppc/platforms/Makefile
+++ b/arch/ppc/platforms/Makefile
@@ -3,26 +3,18 @@
#
# Extra CFLAGS so we don't have to do relative includes
-CFLAGS_pmac_setup.o += -Iarch/$(ARCH)/mm
+CFLAGS_chrp_setup.o += -Iarch/$(ARCH)/mm
obj-$(CONFIG_APUS) += apus_setup.o
ifeq ($(CONFIG_APUS),y)
obj-$(CONFIG_PCI) += apus_pci.o
endif
-obj-$(CONFIG_PPC_PMAC) += pmac_pic.o pmac_setup.o pmac_time.o \
- pmac_feature.o pmac_pci.o pmac_sleep.o \
- pmac_low_i2c.o pmac_cache.o
obj-$(CONFIG_PPC_CHRP) += chrp_setup.o chrp_time.o chrp_pci.o \
chrp_pegasos_eth.o
ifeq ($(CONFIG_PPC_CHRP),y)
obj-$(CONFIG_NVRAM) += chrp_nvram.o
endif
obj-$(CONFIG_PPC_PREP) += prep_pci.o prep_setup.o
-ifeq ($(CONFIG_PPC_PMAC),y)
-obj-$(CONFIG_NVRAM) += pmac_nvram.o
-obj-$(CONFIG_CPU_FREQ_PMAC) += pmac_cpufreq.o
-endif
-obj-$(CONFIG_PMAC_BACKLIGHT) += pmac_backlight.o
obj-$(CONFIG_PREP_RESIDUAL) += residual.o
obj-$(CONFIG_PQ2ADS) += pq2ads.o
obj-$(CONFIG_TQM8260) += tqm8260_setup.o
@@ -47,6 +39,5 @@
obj-$(CONFIG_EV64360) += ev64360.o
ifeq ($(CONFIG_SMP),y)
-obj-$(CONFIG_PPC_PMAC) += pmac_smp.o
obj-$(CONFIG_PPC_CHRP) += chrp_smp.o
endif
diff --git a/arch/ppc/platforms/chrp_pci.c b/arch/ppc/platforms/chrp_pci.c
index bd047aa..c7fe618 100644
--- a/arch/ppc/platforms/chrp_pci.c
+++ b/arch/ppc/platforms/chrp_pci.c
@@ -275,7 +275,7 @@
setup_python(hose, dev);
} else if (is_mot
|| strncmp(model, "Motorola, Grackle", 17) == 0) {
- setup_grackle(hose);
+ setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
} else if (is_longtrail) {
void __iomem *p = ioremap(GG2_PCI_CONFIG_BASE, 0x80000);
hose->ops = &gg2_pci_ops;
diff --git a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c
index 056ac2a..48996b7 100644
--- a/arch/ppc/platforms/chrp_setup.c
+++ b/arch/ppc/platforms/chrp_setup.c
@@ -53,6 +53,7 @@
#include <asm/i8259.h>
#include <asm/open_pic.h>
#include <asm/xmon.h>
+#include "mem_pieces.h"
unsigned long chrp_get_rtc_time(void);
int chrp_set_rtc_time(unsigned long nowtime);
@@ -65,7 +66,6 @@
void rtas_indicator_progress(char *, unsigned short);
void btext_progress(char *, unsigned short);
-extern unsigned long pmac_find_end_of_memory(void);
extern int of_show_percpuinfo(struct seq_file *, int);
int _chrp_type;
@@ -467,6 +467,75 @@
ppc_md.progress(" Have fun! ", 0x7777);
}
+static struct device_node *memory_node;
+
+static int __init get_mem_prop(char *name, struct mem_pieces *mp)
+{
+ struct reg_property *rp;
+ int i, s;
+ unsigned int *ip;
+ int nac = prom_n_addr_cells(memory_node);
+ int nsc = prom_n_size_cells(memory_node);
+
+ ip = (unsigned int *) get_property(memory_node, name, &s);
+ if (ip == NULL) {
+ printk(KERN_ERR "error: couldn't get %s property on /memory\n",
+ name);
+ return 0;
+ }
+ s /= (nsc + nac) * 4;
+ rp = mp->regions;
+ for (i = 0; i < s; ++i, ip += nac+nsc) {
+ if (nac >= 2 && ip[nac-2] != 0)
+ continue;
+ rp->address = ip[nac-1];
+ if (nsc >= 2 && ip[nac+nsc-2] != 0)
+ rp->size = ~0U;
+ else
+ rp->size = ip[nac+nsc-1];
+ ++rp;
+ }
+ mp->n_regions = rp - mp->regions;
+
+ /* Make sure the pieces are sorted. */
+ mem_pieces_sort(mp);
+ mem_pieces_coalesce(mp);
+ return 1;
+}
+
+static unsigned long __init chrp_find_end_of_memory(void)
+{
+ unsigned long a, total;
+ struct mem_pieces phys_mem;
+
+ /*
+ * Find out where physical memory is, and check that it
+ * starts at 0 and is contiguous. It seems that RAM is
+ * always physically contiguous on Power Macintoshes.
+ *
+ * Supporting discontiguous physical memory isn't hard,
+ * it just makes the virtual <-> physical mapping functions
+ * more complicated (or else you end up wasting space
+ * in mem_map).
+ */
+ memory_node = find_devices("memory");
+ if (memory_node == NULL || !get_mem_prop("reg", &phys_mem)
+ || phys_mem.n_regions == 0)
+ panic("No RAM??");
+ a = phys_mem.regions[0].address;
+ if (a != 0)
+ panic("RAM doesn't start at physical address 0");
+ total = phys_mem.regions[0].size;
+
+ if (phys_mem.n_regions > 1) {
+ printk("RAM starting at 0x%x is not contiguous\n",
+ phys_mem.regions[1].address);
+ printk("Using RAM from 0 to 0x%lx\n", total-1);
+ }
+
+ return total;
+}
+
void __init
chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
@@ -525,7 +594,7 @@
ppc_md.get_rtc_time = chrp_get_rtc_time;
ppc_md.calibrate_decr = chrp_calibrate_decr;
- ppc_md.find_end_of_memory = pmac_find_end_of_memory;
+ ppc_md.find_end_of_memory = chrp_find_end_of_memory;
if (rtas_data) {
struct device_node *rtas;
diff --git a/arch/ppc/platforms/chrp_time.c b/arch/ppc/platforms/chrp_time.c
index 29d074c..57753a5 100644
--- a/arch/ppc/platforms/chrp_time.c
+++ b/arch/ppc/platforms/chrp_time.c
@@ -163,13 +163,75 @@
return mktime(year, mon, day, hour, min, sec);
}
+/*
+ * Calibrate the decrementer frequency with the VIA timer 1.
+ */
+#define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */
+
+/* VIA registers */
+#define RS 0x200 /* skip between registers */
+#define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */
+#define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */
+#define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */
+#define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */
+#define ACR (11*RS) /* Auxiliary control register */
+#define IFR (13*RS) /* Interrupt flag register */
+
+/* Bits in ACR */
+#define T1MODE 0xc0 /* Timer 1 mode */
+#define T1MODE_CONT 0x40 /* continuous interrupts */
+
+/* Bits in IFR and IER */
+#define T1_INT 0x40 /* Timer 1 interrupt */
+
+static int __init chrp_via_calibrate_decr(void)
+{
+ struct device_node *vias;
+ volatile unsigned char __iomem *via;
+ int count = VIA_TIMER_FREQ_6 / 100;
+ unsigned int dstart, dend;
+
+ vias = find_devices("via-cuda");
+ if (vias == 0)
+ vias = find_devices("via");
+ if (vias == 0 || vias->n_addrs == 0)
+ return 0;
+ via = ioremap(vias->addrs[0].address, vias->addrs[0].size);
+
+ /* set timer 1 for continuous interrupts */
+ out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT);
+ /* set the counter to a small value */
+ out_8(&via[T1CH], 2);
+ /* set the latch to `count' */
+ out_8(&via[T1LL], count);
+ out_8(&via[T1LH], count >> 8);
+ /* wait until it hits 0 */
+ while ((in_8(&via[IFR]) & T1_INT) == 0)
+ ;
+ dstart = get_dec();
+ /* clear the interrupt & wait until it hits 0 again */
+ in_8(&via[T1CL]);
+ while ((in_8(&via[IFR]) & T1_INT) == 0)
+ ;
+ dend = get_dec();
+
+ tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100);
+ tb_to_us = mulhwu_scale_factor(dstart - dend, 60000);
+
+ printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n",
+ tb_ticks_per_jiffy, dstart - dend);
+
+ iounmap(via);
+
+ return 1;
+}
void __init chrp_calibrate_decr(void)
{
struct device_node *cpu;
unsigned int freq, *fp;
- if (via_calibrate_decr())
+ if (chrp_via_calibrate_decr())
return;
/*
diff --git a/arch/ppc/platforms/pmac_backlight.c b/arch/ppc/platforms/pmac_backlight.c
deleted file mode 100644
index 8be2f7d..0000000
--- a/arch/ppc/platforms/pmac_backlight.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Miscellaneous procedures for dealing with the PowerMac hardware.
- * Contains support for the backlight.
- *
- * Copyright (C) 2000 Benjamin Herrenschmidt
- *
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/stddef.h>
-#include <linux/reboot.h>
-#include <linux/nvram.h>
-#include <linux/console.h>
-#include <asm/sections.h>
-#include <asm/ptrace.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/nvram.h>
-#include <asm/backlight.h>
-
-#include <linux/adb.h>
-#include <linux/pmu.h>
-
-static struct backlight_controller *backlighter;
-static void* backlighter_data;
-static int backlight_autosave;
-static int backlight_level = BACKLIGHT_MAX;
-static int backlight_enabled = 1;
-static int backlight_req_level = -1;
-static int backlight_req_enable = -1;
-
-static void backlight_callback(void *);
-static DECLARE_WORK(backlight_work, backlight_callback, NULL);
-
-void register_backlight_controller(struct backlight_controller *ctrler,
- void *data, char *type)
-{
- struct device_node* bk_node;
- char *prop;
- int valid = 0;
-
- /* There's already a matching controller, bail out */
- if (backlighter != NULL)
- return;
-
- bk_node = find_devices("backlight");
-
-#ifdef CONFIG_ADB_PMU
- /* Special case for the old PowerBook since I can't test on it */
- backlight_autosave = machine_is_compatible("AAPL,3400/2400")
- || machine_is_compatible("AAPL,3500");
- if ((backlight_autosave
- || machine_is_compatible("AAPL,PowerBook1998")
- || machine_is_compatible("PowerBook1,1"))
- && !strcmp(type, "pmu"))
- valid = 1;
-#endif
- if (bk_node) {
- prop = get_property(bk_node, "backlight-control", NULL);
- if (prop && !strncmp(prop, type, strlen(type)))
- valid = 1;
- }
- if (!valid)
- return;
- backlighter = ctrler;
- backlighter_data = data;
-
- if (bk_node && !backlight_autosave)
- prop = get_property(bk_node, "bklt", NULL);
- else
- prop = NULL;
- if (prop) {
- backlight_level = ((*prop)+1) >> 1;
- if (backlight_level > BACKLIGHT_MAX)
- backlight_level = BACKLIGHT_MAX;
- }
-
-#ifdef CONFIG_ADB_PMU
- if (backlight_autosave) {
- struct adb_request req;
- pmu_request(&req, NULL, 2, 0xd9, 0);
- while (!req.complete)
- pmu_poll();
- backlight_level = req.reply[0] >> 4;
- }
-#endif
- acquire_console_sem();
- if (!backlighter->set_enable(1, backlight_level, data))
- backlight_enabled = 1;
- release_console_sem();
-
- printk(KERN_INFO "Registered \"%s\" backlight controller,"
- "level: %d/15\n", type, backlight_level);
-}
-EXPORT_SYMBOL(register_backlight_controller);
-
-void unregister_backlight_controller(struct backlight_controller
- *ctrler, void *data)
-{
- /* We keep the current backlight level (for now) */
- if (ctrler == backlighter && data == backlighter_data)
- backlighter = NULL;
-}
-EXPORT_SYMBOL(unregister_backlight_controller);
-
-static int __set_backlight_enable(int enable)
-{
- int rc;
-
- if (!backlighter)
- return -ENODEV;
- acquire_console_sem();
- rc = backlighter->set_enable(enable, backlight_level,
- backlighter_data);
- if (!rc)
- backlight_enabled = enable;
- release_console_sem();
- return rc;
-}
-int set_backlight_enable(int enable)
-{
- if (!backlighter)
- return -ENODEV;
- backlight_req_enable = enable;
- schedule_work(&backlight_work);
- return 0;
-}
-
-EXPORT_SYMBOL(set_backlight_enable);
-
-int get_backlight_enable(void)
-{
- if (!backlighter)
- return -ENODEV;
- return backlight_enabled;
-}
-EXPORT_SYMBOL(get_backlight_enable);
-
-static int __set_backlight_level(int level)
-{
- int rc = 0;
-
- if (!backlighter)
- return -ENODEV;
- if (level < BACKLIGHT_MIN)
- level = BACKLIGHT_OFF;
- if (level > BACKLIGHT_MAX)
- level = BACKLIGHT_MAX;
- acquire_console_sem();
- if (backlight_enabled)
- rc = backlighter->set_level(level, backlighter_data);
- if (!rc)
- backlight_level = level;
- release_console_sem();
- if (!rc && !backlight_autosave) {
- level <<=1;
- if (level & 0x10)
- level |= 0x01;
- // -- todo: save to property "bklt"
- }
- return rc;
-}
-int set_backlight_level(int level)
-{
- if (!backlighter)
- return -ENODEV;
- backlight_req_level = level;
- schedule_work(&backlight_work);
- return 0;
-}
-
-EXPORT_SYMBOL(set_backlight_level);
-
-int get_backlight_level(void)
-{
- if (!backlighter)
- return -ENODEV;
- return backlight_level;
-}
-EXPORT_SYMBOL(get_backlight_level);
-
-static void backlight_callback(void *dummy)
-{
- int level, enable;
-
- do {
- level = backlight_req_level;
- enable = backlight_req_enable;
- mb();
-
- if (level >= 0)
- __set_backlight_level(level);
- if (enable >= 0)
- __set_backlight_enable(enable);
- } while(cmpxchg(&backlight_req_level, level, -1) != level ||
- cmpxchg(&backlight_req_enable, enable, -1) != enable);
-}
diff --git a/arch/ppc/platforms/pmac_cache.S b/arch/ppc/platforms/pmac_cache.S
deleted file mode 100644
index fb977de..0000000
--- a/arch/ppc/platforms/pmac_cache.S
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * This file contains low-level cache management functions
- * used for sleep and CPU speed changes on Apple machines.
- * (In fact the only thing that is Apple-specific is that we assume
- * that we can read from ROM at physical address 0xfff00000.)
- *
- * Copyright (C) 2004 Paul Mackerras (paulus@samba.org) and
- * Benjamin Herrenschmidt (benh@kernel.crashing.org)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- */
-
-#include <linux/config.h>
-#include <asm/processor.h>
-#include <asm/ppc_asm.h>
-#include <asm/cputable.h>
-
-/*
- * Flush and disable all data caches (dL1, L2, L3). This is used
- * when going to sleep, when doing a PMU based cpufreq transition,
- * or when "offlining" a CPU on SMP machines. This code is over
- * paranoid, but I've had enough issues with various CPU revs and
- * bugs that I decided it was worth beeing over cautious
- */
-
-_GLOBAL(flush_disable_caches)
-#ifndef CONFIG_6xx
- blr
-#else
-BEGIN_FTR_SECTION
- b flush_disable_745x
-END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
-BEGIN_FTR_SECTION
- b flush_disable_75x
-END_FTR_SECTION_IFSET(CPU_FTR_L2CR)
- b __flush_disable_L1
-
-/* This is the code for G3 and 74[01]0 */
-flush_disable_75x:
- mflr r10
-
- /* Turn off EE and DR in MSR */
- mfmsr r11
- rlwinm r0,r11,0,~MSR_EE
- rlwinm r0,r0,0,~MSR_DR
- sync
- mtmsr r0
- isync
-
- /* Stop DST streams */
-BEGIN_FTR_SECTION
- DSSALL
- sync
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
-
- /* Stop DPM */
- mfspr r8,SPRN_HID0 /* Save SPRN_HID0 in r8 */
- rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */
- sync
- mtspr SPRN_HID0,r4 /* Disable DPM */
- sync
-
- /* Disp-flush L1. We have a weird problem here that I never
- * totally figured out. On 750FX, using the ROM for the flush
- * results in a non-working flush. We use that workaround for
- * now until I finally understand what's going on. --BenH
- */
-
- /* ROM base by default */
- lis r4,0xfff0
- mfpvr r3
- srwi r3,r3,16
- cmplwi cr0,r3,0x7000
- bne+ 1f
- /* RAM base on 750FX */
- li r4,0
-1: li r4,0x4000
- mtctr r4
-1: lwz r0,0(r4)
- addi r4,r4,32
- bdnz 1b
- sync
- isync
-
- /* Disable / invalidate / enable L1 data */
- mfspr r3,SPRN_HID0
- rlwinm r3,r3,0,~(HID0_DCE | HID0_ICE)
- mtspr SPRN_HID0,r3
- sync
- isync
- ori r3,r3,(HID0_DCE|HID0_DCI|HID0_ICE|HID0_ICFI)
- sync
- isync
- mtspr SPRN_HID0,r3
- xori r3,r3,(HID0_DCI|HID0_ICFI)
- mtspr SPRN_HID0,r3
- sync
-
- /* Get the current enable bit of the L2CR into r4 */
- mfspr r5,SPRN_L2CR
- /* Set to data-only (pre-745x bit) */
- oris r3,r5,L2CR_L2DO@h
- b 2f
- /* When disabling L2, code must be in L1 */
- .balign 32
-1: mtspr SPRN_L2CR,r3
-3: sync
- isync
- b 1f
-2: b 3f
-3: sync
- isync
- b 1b
-1: /* disp-flush L2. The interesting thing here is that the L2 can be
- * up to 2Mb ... so using the ROM, we'll end up wrapping back to memory
- * but that is probbaly fine. We disp-flush over 4Mb to be safe
- */
- lis r4,2
- mtctr r4
- lis r4,0xfff0
-1: lwz r0,0(r4)
- addi r4,r4,32
- bdnz 1b
- sync
- isync
- lis r4,2
- mtctr r4
- lis r4,0xfff0
-1: dcbf 0,r4
- addi r4,r4,32
- bdnz 1b
- sync
- isync
-
- /* now disable L2 */
- rlwinm r5,r5,0,~L2CR_L2E
- b 2f
- /* When disabling L2, code must be in L1 */
- .balign 32
-1: mtspr SPRN_L2CR,r5
-3: sync
- isync
- b 1f
-2: b 3f
-3: sync
- isync
- b 1b
-1: sync
- isync
- /* Invalidate L2. This is pre-745x, we clear the L2I bit ourselves */
- oris r4,r5,L2CR_L2I@h
- mtspr SPRN_L2CR,r4
- sync
- isync
-
- /* Wait for the invalidation to complete */
-1: mfspr r3,SPRN_L2CR
- rlwinm. r0,r3,0,31,31
- bne 1b
-
- /* Clear L2I */
- xoris r4,r4,L2CR_L2I@h
- sync
- mtspr SPRN_L2CR,r4
- sync
-
- /* now disable the L1 data cache */
- mfspr r0,SPRN_HID0
- rlwinm r0,r0,0,~(HID0_DCE|HID0_ICE)
- mtspr SPRN_HID0,r0
- sync
- isync
-
- /* Restore HID0[DPM] to whatever it was before */
- sync
- mfspr r0,SPRN_HID0
- rlwimi r0,r8,0,11,11 /* Turn back HID0[DPM] */
- mtspr SPRN_HID0,r0
- sync
-
- /* restore DR and EE */
- sync
- mtmsr r11
- isync
-
- mtlr r10
- blr
-
-/* This code is for 745x processors */
-flush_disable_745x:
- /* Turn off EE and DR in MSR */
- mfmsr r11
- rlwinm r0,r11,0,~MSR_EE
- rlwinm r0,r0,0,~MSR_DR
- sync
- mtmsr r0
- isync
-
- /* Stop prefetch streams */
- DSSALL
- sync
-
- /* Disable L2 prefetching */
- mfspr r0,SPRN_MSSCR0
- rlwinm r0,r0,0,0,29
- mtspr SPRN_MSSCR0,r0
- sync
- isync
- lis r4,0
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
-
- /* Due to a bug with the HW flush on some CPU revs, we occasionally
- * experience data corruption. I'm adding a displacement flush along
- * with a dcbf loop over a few Mb to "help". The problem isn't totally
- * fixed by this in theory, but at least, in practice, I couldn't reproduce
- * it even with a big hammer...
- */
-
- lis r4,0x0002
- mtctr r4
- li r4,0
-1:
- lwz r0,0(r4)
- addi r4,r4,32 /* Go to start of next cache line */
- bdnz 1b
- isync
-
- /* Now, flush the first 4MB of memory */
- lis r4,0x0002
- mtctr r4
- li r4,0
- sync
-1:
- dcbf 0,r4
- addi r4,r4,32 /* Go to start of next cache line */
- bdnz 1b
-
- /* Flush and disable the L1 data cache */
- mfspr r6,SPRN_LDSTCR
- lis r3,0xfff0 /* read from ROM for displacement flush */
- li r4,0xfe /* start with only way 0 unlocked */
- li r5,128 /* 128 lines in each way */
-1: mtctr r5
- rlwimi r6,r4,0,24,31
- mtspr SPRN_LDSTCR,r6
- sync
- isync
-2: lwz r0,0(r3) /* touch each cache line */
- addi r3,r3,32
- bdnz 2b
- rlwinm r4,r4,1,24,30 /* move on to the next way */
- ori r4,r4,1
- cmpwi r4,0xff /* all done? */
- bne 1b
- /* now unlock the L1 data cache */
- li r4,0
- rlwimi r6,r4,0,24,31
- sync
- mtspr SPRN_LDSTCR,r6
- sync
- isync
-
- /* Flush the L2 cache using the hardware assist */
- mfspr r3,SPRN_L2CR
- cmpwi r3,0 /* check if it is enabled first */
- bge 4f
- oris r0,r3,(L2CR_L2IO_745x|L2CR_L2DO_745x)@h
- b 2f
- /* When disabling/locking L2, code must be in L1 */
- .balign 32
-1: mtspr SPRN_L2CR,r0 /* lock the L2 cache */
-3: sync
- isync
- b 1f
-2: b 3f
-3: sync
- isync
- b 1b
-1: sync
- isync
- ori r0,r3,L2CR_L2HWF_745x
- sync
- mtspr SPRN_L2CR,r0 /* set the hardware flush bit */
-3: mfspr r0,SPRN_L2CR /* wait for it to go to 0 */
- andi. r0,r0,L2CR_L2HWF_745x
- bne 3b
- sync
- rlwinm r3,r3,0,~L2CR_L2E
- b 2f
- /* When disabling L2, code must be in L1 */
- .balign 32
-1: mtspr SPRN_L2CR,r3 /* disable the L2 cache */
-3: sync
- isync
- b 1f
-2: b 3f
-3: sync
- isync
- b 1b
-1: sync
- isync
- oris r4,r3,L2CR_L2I@h
- mtspr SPRN_L2CR,r4
- sync
- isync
-1: mfspr r4,SPRN_L2CR
- andis. r0,r4,L2CR_L2I@h
- bne 1b
- sync
-
-BEGIN_FTR_SECTION
- /* Flush the L3 cache using the hardware assist */
-4: mfspr r3,SPRN_L3CR
- cmpwi r3,0 /* check if it is enabled */
- bge 6f
- oris r0,r3,L3CR_L3IO@h
- ori r0,r0,L3CR_L3DO
- sync
- mtspr SPRN_L3CR,r0 /* lock the L3 cache */
- sync
- isync
- ori r0,r0,L3CR_L3HWF
- sync
- mtspr SPRN_L3CR,r0 /* set the hardware flush bit */
-5: mfspr r0,SPRN_L3CR /* wait for it to go to zero */
- andi. r0,r0,L3CR_L3HWF
- bne 5b
- rlwinm r3,r3,0,~L3CR_L3E
- sync
- mtspr SPRN_L3CR,r3 /* disable the L3 cache */
- sync
- ori r4,r3,L3CR_L3I
- mtspr SPRN_L3CR,r4
-1: mfspr r4,SPRN_L3CR
- andi. r0,r4,L3CR_L3I
- bne 1b
- sync
-END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
-
-6: mfspr r0,SPRN_HID0 /* now disable the L1 data cache */
- rlwinm r0,r0,0,~HID0_DCE
- mtspr SPRN_HID0,r0
- sync
- isync
- mtmsr r11 /* restore DR and EE */
- isync
- blr
-#endif /* CONFIG_6xx */
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c
deleted file mode 100644
index fba7e4d..0000000
--- a/arch/ppc/platforms/pmac_cpufreq.c
+++ /dev/null
@@ -1,735 +0,0 @@
-/*
- * arch/ppc/platforms/pmac_cpufreq.c
- *
- * Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
- * Copyright (C) 2004 John Steele Scott <toojays@toojays.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * TODO: Need a big cleanup here. Basically, we need to have different
- * cpufreq_driver structures for the different type of HW instead of the
- * current mess. We also need to better deal with the detection of the
- * type of machine.
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#include <linux/slab.h>
-#include <linux/cpufreq.h>
-#include <linux/init.h>
-#include <linux/sysdev.h>
-#include <linux/i2c.h>
-#include <linux/hardirq.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/irq.h>
-#include <asm/pmac_feature.h>
-#include <asm/mmu_context.h>
-#include <asm/sections.h>
-#include <asm/cputable.h>
-#include <asm/time.h>
-#include <asm/system.h>
-#include <asm/open_pic.h>
-#include <asm/keylargo.h>
-
-/* WARNING !!! This will cause calibrate_delay() to be called,
- * but this is an __init function ! So you MUST go edit
- * init/main.c to make it non-init before enabling DEBUG_FREQ
- */
-#undef DEBUG_FREQ
-
-/*
- * There is a problem with the core cpufreq code on SMP kernels,
- * it won't recalculate the Bogomips properly
- */
-#ifdef CONFIG_SMP
-#warning "WARNING, CPUFREQ not recommended on SMP kernels"
-#endif
-
-extern void low_choose_7447a_dfs(int dfs);
-extern void low_choose_750fx_pll(int pll);
-extern void low_sleep_handler(void);
-
-/*
- * Currently, PowerMac cpufreq supports only high & low frequencies
- * that are set by the firmware
- */
-static unsigned int low_freq;
-static unsigned int hi_freq;
-static unsigned int cur_freq;
-static unsigned int sleep_freq;
-
-/*
- * Different models uses different mecanisms to switch the frequency
- */
-static int (*set_speed_proc)(int low_speed);
-static unsigned int (*get_speed_proc)(void);
-
-/*
- * Some definitions used by the various speedprocs
- */
-static u32 voltage_gpio;
-static u32 frequency_gpio;
-static u32 slew_done_gpio;
-static int no_schedule;
-static int has_cpu_l2lve;
-static int is_pmu_based;
-
-/* There are only two frequency states for each processor. Values
- * are in kHz for the time being.
- */
-#define CPUFREQ_HIGH 0
-#define CPUFREQ_LOW 1
-
-static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
- {CPUFREQ_HIGH, 0},
- {CPUFREQ_LOW, 0},
- {0, CPUFREQ_TABLE_END},
-};
-
-static struct freq_attr* pmac_cpu_freqs_attr[] = {
- &cpufreq_freq_attr_scaling_available_freqs,
- NULL,
-};
-
-static inline void local_delay(unsigned long ms)
-{
- if (no_schedule)
- mdelay(ms);
- else
- msleep(ms);
-}
-
-static inline void wakeup_decrementer(void)
-{
- set_dec(tb_ticks_per_jiffy);
- /* No currently-supported powerbook has a 601,
- * so use get_tbl, not native
- */
- last_jiffy_stamp(0) = tb_last_stamp = get_tbl();
-}
-
-#ifdef DEBUG_FREQ
-static inline void debug_calc_bogomips(void)
-{
- /* This will cause a recalc of bogomips and display the
- * result. We backup/restore the value to avoid affecting the
- * core cpufreq framework's own calculation.
- */
- extern void calibrate_delay(void);
-
- unsigned long save_lpj = loops_per_jiffy;
- calibrate_delay();
- loops_per_jiffy = save_lpj;
-}
-#endif /* DEBUG_FREQ */
-
-/* Switch CPU speed under 750FX CPU control
- */
-static int cpu_750fx_cpu_speed(int low_speed)
-{
- u32 hid2;
-
- if (low_speed == 0) {
- /* ramping up, set voltage first */
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
- /* Make sure we sleep for at least 1ms */
- local_delay(10);
-
- /* tweak L2 for high voltage */
- if (has_cpu_l2lve) {
- hid2 = mfspr(SPRN_HID2);
- hid2 &= ~0x2000;
- mtspr(SPRN_HID2, hid2);
- }
- }
-#ifdef CONFIG_6xx
- low_choose_750fx_pll(low_speed);
-#endif
- if (low_speed == 1) {
- /* tweak L2 for low voltage */
- if (has_cpu_l2lve) {
- hid2 = mfspr(SPRN_HID2);
- hid2 |= 0x2000;
- mtspr(SPRN_HID2, hid2);
- }
-
- /* ramping down, set voltage last */
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
- local_delay(10);
- }
-
- return 0;
-}
-
-static unsigned int cpu_750fx_get_cpu_speed(void)
-{
- if (mfspr(SPRN_HID1) & HID1_PS)
- return low_freq;
- else
- return hi_freq;
-}
-
-/* Switch CPU speed using DFS */
-static int dfs_set_cpu_speed(int low_speed)
-{
- if (low_speed == 0) {
- /* ramping up, set voltage first */
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
- /* Make sure we sleep for at least 1ms */
- local_delay(1);
- }
-
- /* set frequency */
-#ifdef CONFIG_6xx
- low_choose_7447a_dfs(low_speed);
-#endif
- udelay(100);
-
- if (low_speed == 1) {
- /* ramping down, set voltage last */
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
- local_delay(1);
- }
-
- return 0;
-}
-
-static unsigned int dfs_get_cpu_speed(void)
-{
- if (mfspr(SPRN_HID1) & HID1_DFS)
- return low_freq;
- else
- return hi_freq;
-}
-
-
-/* Switch CPU speed using slewing GPIOs
- */
-static int gpios_set_cpu_speed(int low_speed)
-{
- int gpio, timeout = 0;
-
- /* If ramping up, set voltage first */
- if (low_speed == 0) {
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
- /* Delay is way too big but it's ok, we schedule */
- local_delay(10);
- }
-
- /* Set frequency */
- gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
- if (low_speed == ((gpio & 0x01) == 0))
- goto skip;
-
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio,
- low_speed ? 0x04 : 0x05);
- udelay(200);
- do {
- if (++timeout > 100)
- break;
- local_delay(1);
- gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, slew_done_gpio, 0);
- } while((gpio & 0x02) == 0);
- skip:
- /* If ramping down, set voltage last */
- if (low_speed == 1) {
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
- /* Delay is way too big but it's ok, we schedule */
- local_delay(10);
- }
-
-#ifdef DEBUG_FREQ
- debug_calc_bogomips();
-#endif
-
- return 0;
-}
-
-/* Switch CPU speed under PMU control
- */
-static int pmu_set_cpu_speed(int low_speed)
-{
- struct adb_request req;
- unsigned long save_l2cr;
- unsigned long save_l3cr;
- unsigned int pic_prio;
- unsigned long flags;
-
- preempt_disable();
-
-#ifdef DEBUG_FREQ
- printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
-#endif
- pmu_suspend();
-
- /* Disable all interrupt sources on openpic */
- pic_prio = openpic_get_priority();
- openpic_set_priority(0xf);
-
- /* Make sure the decrementer won't interrupt us */
- asm volatile("mtdec %0" : : "r" (0x7fffffff));
- /* Make sure any pending DEC interrupt occuring while we did
- * the above didn't re-enable the DEC */
- mb();
- asm volatile("mtdec %0" : : "r" (0x7fffffff));
-
- /* We can now disable MSR_EE */
- local_irq_save(flags);
-
- /* Giveup the FPU & vec */
- enable_kernel_fp();
-
-#ifdef CONFIG_ALTIVEC
- if (cpu_has_feature(CPU_FTR_ALTIVEC))
- enable_kernel_altivec();
-#endif /* CONFIG_ALTIVEC */
-
- /* Save & disable L2 and L3 caches */
- save_l3cr = _get_L3CR(); /* (returns -1 if not available) */
- save_l2cr = _get_L2CR(); /* (returns -1 if not available) */
-
- /* Send the new speed command. My assumption is that this command
- * will cause PLL_CFG[0..3] to be changed next time CPU goes to sleep
- */
- pmu_request(&req, NULL, 6, PMU_CPU_SPEED, 'W', 'O', 'O', 'F', low_speed);
- while (!req.complete)
- pmu_poll();
-
- /* Prepare the northbridge for the speed transition */
- pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,1);
-
- /* Call low level code to backup CPU state and recover from
- * hardware reset
- */
- low_sleep_handler();
-
- /* Restore the northbridge */
- pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,0);
-
- /* Restore L2 cache */
- if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0)
- _set_L2CR(save_l2cr);
- /* Restore L3 cache */
- if (save_l3cr != 0xffffffff && (save_l3cr & L3CR_L3E) != 0)
- _set_L3CR(save_l3cr);
-
- /* Restore userland MMU context */
- set_context(current->active_mm->context, current->active_mm->pgd);
-
-#ifdef DEBUG_FREQ
- printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
-#endif
-
- /* Restore low level PMU operations */
- pmu_unlock();
-
- /* Restore decrementer */
- wakeup_decrementer();
-
- /* Restore interrupts */
- openpic_set_priority(pic_prio);
-
- /* Let interrupts flow again ... */
- local_irq_restore(flags);
-
-#ifdef DEBUG_FREQ
- debug_calc_bogomips();
-#endif
-
- pmu_resume();
-
- preempt_enable();
-
- return 0;
-}
-
-static int do_set_cpu_speed(int speed_mode, int notify)
-{
- struct cpufreq_freqs freqs;
- unsigned long l3cr;
- static unsigned long prev_l3cr;
-
- freqs.old = cur_freq;
- freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
- freqs.cpu = smp_processor_id();
-
- if (freqs.old == freqs.new)
- return 0;
-
- if (notify)
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- if (speed_mode == CPUFREQ_LOW &&
- cpu_has_feature(CPU_FTR_L3CR)) {
- l3cr = _get_L3CR();
- if (l3cr & L3CR_L3E) {
- prev_l3cr = l3cr;
- _set_L3CR(0);
- }
- }
- set_speed_proc(speed_mode == CPUFREQ_LOW);
- if (speed_mode == CPUFREQ_HIGH &&
- cpu_has_feature(CPU_FTR_L3CR)) {
- l3cr = _get_L3CR();
- if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr)
- _set_L3CR(prev_l3cr);
- }
- if (notify)
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
- cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
-
- return 0;
-}
-
-static unsigned int pmac_cpufreq_get_speed(unsigned int cpu)
-{
- return cur_freq;
-}
-
-static int pmac_cpufreq_verify(struct cpufreq_policy *policy)
-{
- return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs);
-}
-
-static int pmac_cpufreq_target( struct cpufreq_policy *policy,
- unsigned int target_freq,
- unsigned int relation)
-{
- unsigned int newstate = 0;
-
- if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs,
- target_freq, relation, &newstate))
- return -EINVAL;
-
- return do_set_cpu_speed(newstate, 1);
-}
-
-unsigned int pmac_get_one_cpufreq(int i)
-{
- /* Supports only one CPU for now */
- return (i == 0) ? cur_freq : 0;
-}
-
-static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
-{
- if (policy->cpu != 0)
- return -ENODEV;
-
- policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
- policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
- policy->cur = cur_freq;
-
- cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu);
- return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs);
-}
-
-static u32 read_gpio(struct device_node *np)
-{
- u32 *reg = (u32 *)get_property(np, "reg", NULL);
- u32 offset;
-
- if (reg == NULL)
- return 0;
- /* That works for all keylargos but shall be fixed properly
- * some day... The problem is that it seems we can't rely
- * on the "reg" property of the GPIO nodes, they are either
- * relative to the base of KeyLargo or to the base of the
- * GPIO space, and the device-tree doesn't help.
- */
- offset = *reg;
- if (offset < KEYLARGO_GPIO_LEVELS0)
- offset += KEYLARGO_GPIO_LEVELS0;
- return offset;
-}
-
-static int pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg)
-{
- /* Ok, this could be made a bit smarter, but let's be robust for now. We
- * always force a speed change to high speed before sleep, to make sure
- * we have appropriate voltage and/or bus speed for the wakeup process,
- * and to make sure our loops_per_jiffies are "good enough", that is will
- * not cause too short delays if we sleep in low speed and wake in high
- * speed..
- */
- no_schedule = 1;
- sleep_freq = cur_freq;
- if (cur_freq == low_freq && !is_pmu_based)
- do_set_cpu_speed(CPUFREQ_HIGH, 0);
- return 0;
-}
-
-static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
-{
- /* If we resume, first check if we have a get() function */
- if (get_speed_proc)
- cur_freq = get_speed_proc();
- else
- cur_freq = 0;
-
- /* We don't, hrm... we don't really know our speed here, best
- * is that we force a switch to whatever it was, which is
- * probably high speed due to our suspend() routine
- */
- do_set_cpu_speed(sleep_freq == low_freq ?
- CPUFREQ_LOW : CPUFREQ_HIGH, 0);
-
- no_schedule = 0;
- return 0;
-}
-
-static struct cpufreq_driver pmac_cpufreq_driver = {
- .verify = pmac_cpufreq_verify,
- .target = pmac_cpufreq_target,
- .get = pmac_cpufreq_get_speed,
- .init = pmac_cpufreq_cpu_init,
- .suspend = pmac_cpufreq_suspend,
- .resume = pmac_cpufreq_resume,
- .flags = CPUFREQ_PM_NO_WARN,
- .attr = pmac_cpu_freqs_attr,
- .name = "powermac",
- .owner = THIS_MODULE,
-};
-
-
-static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
-{
- struct device_node *volt_gpio_np = of_find_node_by_name(NULL,
- "voltage-gpio");
- struct device_node *freq_gpio_np = of_find_node_by_name(NULL,
- "frequency-gpio");
- struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL,
- "slewing-done");
- u32 *value;
-
- /*
- * Check to see if it's GPIO driven or PMU only
- *
- * The way we extract the GPIO address is slightly hackish, but it
- * works well enough for now. We need to abstract the whole GPIO
- * stuff sooner or later anyway
- */
-
- if (volt_gpio_np)
- voltage_gpio = read_gpio(volt_gpio_np);
- if (freq_gpio_np)
- frequency_gpio = read_gpio(freq_gpio_np);
- if (slew_done_gpio_np)
- slew_done_gpio = read_gpio(slew_done_gpio_np);
-
- /* If we use the frequency GPIOs, calculate the min/max speeds based
- * on the bus frequencies
- */
- if (frequency_gpio && slew_done_gpio) {
- int lenp, rc;
- u32 *freqs, *ratio;
-
- freqs = (u32 *)get_property(cpunode, "bus-frequencies", &lenp);
- lenp /= sizeof(u32);
- if (freqs == NULL || lenp != 2) {
- printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n");
- return 1;
- }
- ratio = (u32 *)get_property(cpunode, "processor-to-bus-ratio*2", NULL);
- if (ratio == NULL) {
- printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n");
- return 1;
- }
-
- /* Get the min/max bus frequencies */
- low_freq = min(freqs[0], freqs[1]);
- hi_freq = max(freqs[0], freqs[1]);
-
- /* Grrrr.. It _seems_ that the device-tree is lying on the low bus
- * frequency, it claims it to be around 84Mhz on some models while
- * it appears to be approx. 101Mhz on all. Let's hack around here...
- * fortunately, we don't need to be too precise
- */
- if (low_freq < 98000000)
- low_freq = 101000000;
-
- /* Convert those to CPU core clocks */
- low_freq = (low_freq * (*ratio)) / 2000;
- hi_freq = (hi_freq * (*ratio)) / 2000;
-
- /* Now we get the frequencies, we read the GPIO to see what is out current
- * speed
- */
- rc = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
- cur_freq = (rc & 0x01) ? hi_freq : low_freq;
-
- set_speed_proc = gpios_set_cpu_speed;
- return 1;
- }
-
- /* If we use the PMU, look for the min & max frequencies in the
- * device-tree
- */
- value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL);
- if (!value)
- return 1;
- low_freq = (*value) / 1000;
- /* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree
- * here */
- if (low_freq < 100000)
- low_freq *= 10;
-
- value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL);
- if (!value)
- return 1;
- hi_freq = (*value) / 1000;
- set_speed_proc = pmu_set_cpu_speed;
- is_pmu_based = 1;
-
- return 0;
-}
-
-static int pmac_cpufreq_init_7447A(struct device_node *cpunode)
-{
- struct device_node *volt_gpio_np;
-
- if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)
- return 1;
-
- volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
- if (volt_gpio_np)
- voltage_gpio = read_gpio(volt_gpio_np);
- if (!voltage_gpio){
- printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n");
- return 1;
- }
-
- /* OF only reports the high frequency */
- hi_freq = cur_freq;
- low_freq = cur_freq/2;
-
- /* Read actual frequency from CPU */
- cur_freq = dfs_get_cpu_speed();
- set_speed_proc = dfs_set_cpu_speed;
- get_speed_proc = dfs_get_cpu_speed;
-
- return 0;
-}
-
-static int pmac_cpufreq_init_750FX(struct device_node *cpunode)
-{
- struct device_node *volt_gpio_np;
- u32 pvr, *value;
-
- if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)
- return 1;
-
- hi_freq = cur_freq;
- value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL);
- if (!value)
- return 1;
- low_freq = (*value) / 1000;
-
- volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
- if (volt_gpio_np)
- voltage_gpio = read_gpio(volt_gpio_np);
-
- pvr = mfspr(SPRN_PVR);
- has_cpu_l2lve = !((pvr & 0xf00) == 0x100);
-
- set_speed_proc = cpu_750fx_cpu_speed;
- get_speed_proc = cpu_750fx_get_cpu_speed;
- cur_freq = cpu_750fx_get_cpu_speed();
-
- return 0;
-}
-
-/* Currently, we support the following machines:
- *
- * - Titanium PowerBook 1Ghz (PMU based, 667Mhz & 1Ghz)
- * - Titanium PowerBook 800 (PMU based, 667Mhz & 800Mhz)
- * - Titanium PowerBook 400 (PMU based, 300Mhz & 400Mhz)
- * - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz)
- * - iBook2 500/600 (PMU based, 400Mhz & 500/600Mhz)
- * - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage)
- * - Recent MacRISC3 laptops
- * - All new machines with 7447A CPUs
- */
-static int __init pmac_cpufreq_setup(void)
-{
- struct device_node *cpunode;
- u32 *value;
-
- if (strstr(cmd_line, "nocpufreq"))
- return 0;
-
- /* Assume only one CPU */
- cpunode = find_type_devices("cpu");
- if (!cpunode)
- goto out;
-
- /* Get current cpu clock freq */
- value = (u32 *)get_property(cpunode, "clock-frequency", NULL);
- if (!value)
- goto out;
- cur_freq = (*value) / 1000;
-
- /* Check for 7447A based MacRISC3 */
- if (machine_is_compatible("MacRISC3") &&
- get_property(cpunode, "dynamic-power-step", NULL) &&
- PVR_VER(mfspr(SPRN_PVR)) == 0x8003) {
- pmac_cpufreq_init_7447A(cpunode);
- /* Check for other MacRISC3 machines */
- } else if (machine_is_compatible("PowerBook3,4") ||
- machine_is_compatible("PowerBook3,5") ||
- machine_is_compatible("MacRISC3")) {
- pmac_cpufreq_init_MacRISC3(cpunode);
- /* Else check for iBook2 500/600 */
- } else if (machine_is_compatible("PowerBook4,1")) {
- hi_freq = cur_freq;
- low_freq = 400000;
- set_speed_proc = pmu_set_cpu_speed;
- is_pmu_based = 1;
- }
- /* Else check for TiPb 550 */
- else if (machine_is_compatible("PowerBook3,3") && cur_freq == 550000) {
- hi_freq = cur_freq;
- low_freq = 500000;
- set_speed_proc = pmu_set_cpu_speed;
- is_pmu_based = 1;
- }
- /* Else check for TiPb 400 & 500 */
- else if (machine_is_compatible("PowerBook3,2")) {
- /* We only know about the 400 MHz and the 500Mhz model
- * they both have 300 MHz as low frequency
- */
- if (cur_freq < 350000 || cur_freq > 550000)
- goto out;
- hi_freq = cur_freq;
- low_freq = 300000;
- set_speed_proc = pmu_set_cpu_speed;
- is_pmu_based = 1;
- }
- /* Else check for 750FX */
- else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000)
- pmac_cpufreq_init_750FX(cpunode);
-out:
- if (set_speed_proc == NULL)
- return -ENODEV;
-
- pmac_cpu_freqs[CPUFREQ_LOW].frequency = low_freq;
- pmac_cpu_freqs[CPUFREQ_HIGH].frequency = hi_freq;
-
- printk(KERN_INFO "Registering PowerMac CPU frequency driver\n");
- printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz\n",
- low_freq/1000, hi_freq/1000, cur_freq/1000);
-
- return cpufreq_register_driver(&pmac_cpufreq_driver);
-}
-
-module_init(pmac_cpufreq_setup);
-
diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c
deleted file mode 100644
index 6b7b3a1..0000000
--- a/arch/ppc/platforms/pmac_feature.c
+++ /dev/null
@@ -1,3023 +0,0 @@
-/*
- * arch/ppc/platforms/pmac_feature.c
- *
- * Copyright (C) 1996-2001 Paul Mackerras (paulus@cs.anu.edu.au)
- * Ben. Herrenschmidt (benh@kernel.crashing.org)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * TODO:
- *
- * - Replace mdelay with some schedule loop if possible
- * - Shorten some obfuscated delays on some routines (like modem
- * power)
- * - Refcount some clocks (see darwin)
- * - Split split split...
- *
- */
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#include <asm/sections.h>
-#include <asm/errno.h>
-#include <asm/ohare.h>
-#include <asm/heathrow.h>
-#include <asm/keylargo.h>
-#include <asm/uninorth.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/dbdma.h>
-#include <asm/pci-bridge.h>
-#include <asm/pmac_low_i2c.h>
-
-#undef DEBUG_FEATURE
-
-#ifdef DEBUG_FEATURE
-#define DBG(fmt,...) printk(KERN_DEBUG fmt)
-#else
-#define DBG(fmt,...)
-#endif
-
-#ifdef CONFIG_6xx
-extern int powersave_lowspeed;
-#endif
-
-extern int powersave_nap;
-extern struct device_node *k2_skiplist[2];
-
-
-/*
- * We use a single global lock to protect accesses. Each driver has
- * to take care of its own locking
- */
-static DEFINE_SPINLOCK(feature_lock);
-
-#define LOCK(flags) spin_lock_irqsave(&feature_lock, flags);
-#define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags);
-
-
-/*
- * Instance of some macio stuffs
- */
-struct macio_chip macio_chips[MAX_MACIO_CHIPS];
-
-struct macio_chip* macio_find(struct device_node* child, int type)
-{
- while(child) {
- int i;
-
- for (i=0; i < MAX_MACIO_CHIPS && macio_chips[i].of_node; i++)
- if (child == macio_chips[i].of_node &&
- (!type || macio_chips[i].type == type))
- return &macio_chips[i];
- child = child->parent;
- }
- return NULL;
-}
-EXPORT_SYMBOL_GPL(macio_find);
-
-static const char* macio_names[] =
-{
- "Unknown",
- "Grand Central",
- "OHare",
- "OHareII",
- "Heathrow",
- "Gatwick",
- "Paddington",
- "Keylargo",
- "Pangea",
- "Intrepid",
- "K2"
-};
-
-
-
-/*
- * Uninorth reg. access. Note that Uni-N regs are big endian
- */
-
-#define UN_REG(r) (uninorth_base + ((r) >> 2))
-#define UN_IN(r) (in_be32(UN_REG(r)))
-#define UN_OUT(r,v) (out_be32(UN_REG(r), (v)))
-#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v)))
-#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v)))
-
-static struct device_node* uninorth_node;
-static u32 __iomem * uninorth_base;
-static u32 uninorth_rev;
-static int uninorth_u3;
-static void __iomem *u3_ht;
-
-/*
- * For each motherboard family, we have a table of functions pointers
- * that handle the various features.
- */
-
-typedef long (*feature_call)(struct device_node* node, long param, long value);
-
-struct feature_table_entry {
- unsigned int selector;
- feature_call function;
-};
-
-struct pmac_mb_def
-{
- const char* model_string;
- const char* model_name;
- int model_id;
- struct feature_table_entry* features;
- unsigned long board_flags;
-};
-static struct pmac_mb_def pmac_mb;
-
-/*
- * Here are the chip specific feature functions
- */
-
-static inline int
-simple_feature_tweak(struct device_node* node, int type, int reg, u32 mask, int value)
-{
- struct macio_chip* macio;
- unsigned long flags;
-
- macio = macio_find(node, type);
- if (!macio)
- return -ENODEV;
- LOCK(flags);
- if (value)
- MACIO_BIS(reg, mask);
- else
- MACIO_BIC(reg, mask);
- (void)MACIO_IN32(reg);
- UNLOCK(flags);
-
- return 0;
-}
-
-#ifndef CONFIG_POWER4
-
-static long
-ohare_htw_scc_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- unsigned long chan_mask;
- unsigned long fcr;
- unsigned long flags;
- int htw, trans;
- unsigned long rmask;
-
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
- if (!strcmp(node->name, "ch-a"))
- chan_mask = MACIO_FLAG_SCCA_ON;
- else if (!strcmp(node->name, "ch-b"))
- chan_mask = MACIO_FLAG_SCCB_ON;
- else
- return -ENODEV;
-
- htw = (macio->type == macio_heathrow || macio->type == macio_paddington
- || macio->type == macio_gatwick);
- /* On these machines, the HRW_SCC_TRANS_EN_N bit mustn't be touched */
- trans = (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
- pmac_mb.model_id != PMAC_TYPE_YIKES);
- if (value) {
-#ifdef CONFIG_ADB_PMU
- if ((param & 0xfff) == PMAC_SCC_IRDA)
- pmu_enable_irled(1);
-#endif /* CONFIG_ADB_PMU */
- LOCK(flags);
- fcr = MACIO_IN32(OHARE_FCR);
- /* Check if scc cell need enabling */
- if (!(fcr & OH_SCC_ENABLE)) {
- fcr |= OH_SCC_ENABLE;
- if (htw) {
- /* Side effect: this will also power up the
- * modem, but it's too messy to figure out on which
- * ports this controls the tranceiver and on which
- * it controls the modem
- */
- if (trans)
- fcr &= ~HRW_SCC_TRANS_EN_N;
- MACIO_OUT32(OHARE_FCR, fcr);
- fcr |= (rmask = HRW_RESET_SCC);
- MACIO_OUT32(OHARE_FCR, fcr);
- } else {
- fcr |= (rmask = OH_SCC_RESET);
- MACIO_OUT32(OHARE_FCR, fcr);
- }
- UNLOCK(flags);
- (void)MACIO_IN32(OHARE_FCR);
- mdelay(15);
- LOCK(flags);
- fcr &= ~rmask;
- MACIO_OUT32(OHARE_FCR, fcr);
- }
- if (chan_mask & MACIO_FLAG_SCCA_ON)
- fcr |= OH_SCCA_IO;
- if (chan_mask & MACIO_FLAG_SCCB_ON)
- fcr |= OH_SCCB_IO;
- MACIO_OUT32(OHARE_FCR, fcr);
- macio->flags |= chan_mask;
- UNLOCK(flags);
- if (param & PMAC_SCC_FLAG_XMON)
- macio->flags |= MACIO_FLAG_SCC_LOCKED;
- } else {
- if (macio->flags & MACIO_FLAG_SCC_LOCKED)
- return -EPERM;
- LOCK(flags);
- fcr = MACIO_IN32(OHARE_FCR);
- if (chan_mask & MACIO_FLAG_SCCA_ON)
- fcr &= ~OH_SCCA_IO;
- if (chan_mask & MACIO_FLAG_SCCB_ON)
- fcr &= ~OH_SCCB_IO;
- MACIO_OUT32(OHARE_FCR, fcr);
- if ((fcr & (OH_SCCA_IO | OH_SCCB_IO)) == 0) {
- fcr &= ~OH_SCC_ENABLE;
- if (htw && trans)
- fcr |= HRW_SCC_TRANS_EN_N;
- MACIO_OUT32(OHARE_FCR, fcr);
- }
- macio->flags &= ~(chan_mask);
- UNLOCK(flags);
- mdelay(10);
-#ifdef CONFIG_ADB_PMU
- if ((param & 0xfff) == PMAC_SCC_IRDA)
- pmu_enable_irled(0);
-#endif /* CONFIG_ADB_PMU */
- }
- return 0;
-}
-
-static long
-ohare_floppy_enable(struct device_node* node, long param, long value)
-{
- return simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_FLOPPY_ENABLE, value);
-}
-
-static long
-ohare_mesh_enable(struct device_node* node, long param, long value)
-{
- return simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_MESH_ENABLE, value);
-}
-
-static long
-ohare_ide_enable(struct device_node* node, long param, long value)
-{
- switch(param) {
- case 0:
- /* For some reason, setting the bit in set_initial_features()
- * doesn't stick. I'm still investigating... --BenH.
- */
- if (value)
- simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_IOBUS_ENABLE, 1);
- return simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_IDE0_ENABLE, value);
- case 1:
- return simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_BAY_IDE_ENABLE, value);
- default:
- return -ENODEV;
- }
-}
-
-static long
-ohare_ide_reset(struct device_node* node, long param, long value)
-{
- switch(param) {
- case 0:
- return simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_IDE0_RESET_N, !value);
- case 1:
- return simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_IDE1_RESET_N, !value);
- default:
- return -ENODEV;
- }
-}
-
-static long
-ohare_sleep_state(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
-
- if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
- return -EPERM;
- if (value == 1) {
- MACIO_BIC(OHARE_FCR, OH_IOBUS_ENABLE);
- } else if (value == 0) {
- MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
- }
-
- return 0;
-}
-
-static long
-heathrow_modem_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- u8 gpio;
- unsigned long flags;
-
- macio = macio_find(node, macio_unknown);
- if (!macio)
- return -ENODEV;
- gpio = MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1;
- if (!value) {
- LOCK(flags);
- MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio);
- UNLOCK(flags);
- (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
- mdelay(250);
- }
- if (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
- pmac_mb.model_id != PMAC_TYPE_YIKES) {
- LOCK(flags);
- if (value)
- MACIO_BIC(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
- else
- MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
- UNLOCK(flags);
- (void)MACIO_IN32(HEATHROW_FCR);
- mdelay(250);
- }
- if (value) {
- LOCK(flags);
- MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1);
- (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
- MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio);
- (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
- MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1);
- (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250);
- }
- return 0;
-}
-
-static long
-heathrow_floppy_enable(struct device_node* node, long param, long value)
-{
- return simple_feature_tweak(node, macio_unknown,
- HEATHROW_FCR,
- HRW_SWIM_ENABLE|HRW_BAY_FLOPPY_ENABLE,
- value);
-}
-
-static long
-heathrow_mesh_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
-
- macio = macio_find(node, macio_unknown);
- if (!macio)
- return -ENODEV;
- LOCK(flags);
- /* Set clear mesh cell enable */
- if (value)
- MACIO_BIS(HEATHROW_FCR, HRW_MESH_ENABLE);
- else
- MACIO_BIC(HEATHROW_FCR, HRW_MESH_ENABLE);
- (void)MACIO_IN32(HEATHROW_FCR);
- udelay(10);
- /* Set/Clear termination power */
- if (value)
- MACIO_BIC(HEATHROW_MBCR, 0x04000000);
- else
- MACIO_BIS(HEATHROW_MBCR, 0x04000000);
- (void)MACIO_IN32(HEATHROW_MBCR);
- udelay(10);
- UNLOCK(flags);
-
- return 0;
-}
-
-static long
-heathrow_ide_enable(struct device_node* node, long param, long value)
-{
- switch(param) {
- case 0:
- return simple_feature_tweak(node, macio_unknown,
- HEATHROW_FCR, HRW_IDE0_ENABLE, value);
- case 1:
- return simple_feature_tweak(node, macio_unknown,
- HEATHROW_FCR, HRW_BAY_IDE_ENABLE, value);
- default:
- return -ENODEV;
- }
-}
-
-static long
-heathrow_ide_reset(struct device_node* node, long param, long value)
-{
- switch(param) {
- case 0:
- return simple_feature_tweak(node, macio_unknown,
- HEATHROW_FCR, HRW_IDE0_RESET_N, !value);
- case 1:
- return simple_feature_tweak(node, macio_unknown,
- HEATHROW_FCR, HRW_IDE1_RESET_N, !value);
- default:
- return -ENODEV;
- }
-}
-
-static long
-heathrow_bmac_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
-
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
- if (value) {
- LOCK(flags);
- MACIO_BIS(HEATHROW_FCR, HRW_BMAC_IO_ENABLE);
- MACIO_BIS(HEATHROW_FCR, HRW_BMAC_RESET);
- UNLOCK(flags);
- (void)MACIO_IN32(HEATHROW_FCR);
- mdelay(10);
- LOCK(flags);
- MACIO_BIC(HEATHROW_FCR, HRW_BMAC_RESET);
- UNLOCK(flags);
- (void)MACIO_IN32(HEATHROW_FCR);
- mdelay(10);
- } else {
- LOCK(flags);
- MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE);
- UNLOCK(flags);
- }
- return 0;
-}
-
-static long
-heathrow_sound_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
-
- /* B&W G3 and Yikes don't support that properly (the
- * sound appear to never come back after beeing shut down).
- */
- if (pmac_mb.model_id == PMAC_TYPE_YOSEMITE ||
- pmac_mb.model_id == PMAC_TYPE_YIKES)
- return 0;
-
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
- if (value) {
- LOCK(flags);
- MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
- MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
- UNLOCK(flags);
- (void)MACIO_IN32(HEATHROW_FCR);
- } else {
- LOCK(flags);
- MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N);
- MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
- UNLOCK(flags);
- }
- return 0;
-}
-
-static u32 save_fcr[6];
-static u32 save_mbcr;
-static u32 save_gpio_levels[2];
-static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT];
-static u8 save_gpio_normal[KEYLARGO_GPIO_CNT];
-static u32 save_unin_clock_ctl;
-static struct dbdma_regs save_dbdma[13];
-static struct dbdma_regs save_alt_dbdma[13];
-
-static void
-dbdma_save(struct macio_chip* macio, struct dbdma_regs* save)
-{
- int i;
-
- /* Save state & config of DBDMA channels */
- for (i=0; i<13; i++) {
- volatile struct dbdma_regs __iomem * chan = (void __iomem *)
- (macio->base + ((0x8000+i*0x100)>>2));
- save[i].cmdptr_hi = in_le32(&chan->cmdptr_hi);
- save[i].cmdptr = in_le32(&chan->cmdptr);
- save[i].intr_sel = in_le32(&chan->intr_sel);
- save[i].br_sel = in_le32(&chan->br_sel);
- save[i].wait_sel = in_le32(&chan->wait_sel);
- }
-}
-
-static void
-dbdma_restore(struct macio_chip* macio, struct dbdma_regs* save)
-{
- int i;
-
- /* Save state & config of DBDMA channels */
- for (i=0; i<13; i++) {
- volatile struct dbdma_regs __iomem * chan = (void __iomem *)
- (macio->base + ((0x8000+i*0x100)>>2));
- out_le32(&chan->control, (ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN)<<16);
- while (in_le32(&chan->status) & ACTIVE)
- mb();
- out_le32(&chan->cmdptr_hi, save[i].cmdptr_hi);
- out_le32(&chan->cmdptr, save[i].cmdptr);
- out_le32(&chan->intr_sel, save[i].intr_sel);
- out_le32(&chan->br_sel, save[i].br_sel);
- out_le32(&chan->wait_sel, save[i].wait_sel);
- }
-}
-
-static void
-heathrow_sleep(struct macio_chip* macio, int secondary)
-{
- if (secondary) {
- dbdma_save(macio, save_alt_dbdma);
- save_fcr[2] = MACIO_IN32(0x38);
- save_fcr[3] = MACIO_IN32(0x3c);
- } else {
- dbdma_save(macio, save_dbdma);
- save_fcr[0] = MACIO_IN32(0x38);
- save_fcr[1] = MACIO_IN32(0x3c);
- save_mbcr = MACIO_IN32(0x34);
- /* Make sure sound is shut down */
- MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N);
- MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
- /* This seems to be necessary as well or the fan
- * keeps coming up and battery drains fast */
- MACIO_BIC(HEATHROW_FCR, HRW_IOBUS_ENABLE);
- MACIO_BIC(HEATHROW_FCR, HRW_IDE0_RESET_N);
- /* Make sure eth is down even if module or sleep
- * won't work properly */
- MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE | HRW_BMAC_RESET);
- }
- /* Make sure modem is shut down */
- MACIO_OUT8(HRW_GPIO_MODEM_RESET,
- MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1);
- MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
- MACIO_BIC(HEATHROW_FCR, OH_SCCA_IO|OH_SCCB_IO|HRW_SCC_ENABLE);
-
- /* Let things settle */
- (void)MACIO_IN32(HEATHROW_FCR);
-}
-
-static void
-heathrow_wakeup(struct macio_chip* macio, int secondary)
-{
- if (secondary) {
- MACIO_OUT32(0x38, save_fcr[2]);
- (void)MACIO_IN32(0x38);
- mdelay(1);
- MACIO_OUT32(0x3c, save_fcr[3]);
- (void)MACIO_IN32(0x38);
- mdelay(10);
- dbdma_restore(macio, save_alt_dbdma);
- } else {
- MACIO_OUT32(0x38, save_fcr[0] | HRW_IOBUS_ENABLE);
- (void)MACIO_IN32(0x38);
- mdelay(1);
- MACIO_OUT32(0x3c, save_fcr[1]);
- (void)MACIO_IN32(0x38);
- mdelay(1);
- MACIO_OUT32(0x34, save_mbcr);
- (void)MACIO_IN32(0x38);
- mdelay(10);
- dbdma_restore(macio, save_dbdma);
- }
-}
-
-static long
-heathrow_sleep_state(struct device_node* node, long param, long value)
-{
- if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
- return -EPERM;
- if (value == 1) {
- if (macio_chips[1].type == macio_gatwick)
- heathrow_sleep(&macio_chips[0], 1);
- heathrow_sleep(&macio_chips[0], 0);
- } else if (value == 0) {
- heathrow_wakeup(&macio_chips[0], 0);
- if (macio_chips[1].type == macio_gatwick)
- heathrow_wakeup(&macio_chips[0], 1);
- }
- return 0;
-}
-
-static long
-core99_scc_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
- unsigned long chan_mask;
- u32 fcr;
-
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
- if (!strcmp(node->name, "ch-a"))
- chan_mask = MACIO_FLAG_SCCA_ON;
- else if (!strcmp(node->name, "ch-b"))
- chan_mask = MACIO_FLAG_SCCB_ON;
- else
- return -ENODEV;
-
- if (value) {
- int need_reset_scc = 0;
- int need_reset_irda = 0;
-
- LOCK(flags);
- fcr = MACIO_IN32(KEYLARGO_FCR0);
- /* Check if scc cell need enabling */
- if (!(fcr & KL0_SCC_CELL_ENABLE)) {
- fcr |= KL0_SCC_CELL_ENABLE;
- need_reset_scc = 1;
- }
- if (chan_mask & MACIO_FLAG_SCCA_ON) {
- fcr |= KL0_SCCA_ENABLE;
- /* Don't enable line drivers for I2S modem */
- if ((param & 0xfff) == PMAC_SCC_I2S1)
- fcr &= ~KL0_SCC_A_INTF_ENABLE;
- else
- fcr |= KL0_SCC_A_INTF_ENABLE;
- }
- if (chan_mask & MACIO_FLAG_SCCB_ON) {
- fcr |= KL0_SCCB_ENABLE;
- /* Perform irda specific inits */
- if ((param & 0xfff) == PMAC_SCC_IRDA) {
- fcr &= ~KL0_SCC_B_INTF_ENABLE;
- fcr |= KL0_IRDA_ENABLE;
- fcr |= KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE;
- fcr |= KL0_IRDA_SOURCE1_SEL;
- fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0);
- fcr &= ~(KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND);
- need_reset_irda = 1;
- } else
- fcr |= KL0_SCC_B_INTF_ENABLE;
- }
- MACIO_OUT32(KEYLARGO_FCR0, fcr);
- macio->flags |= chan_mask;
- if (need_reset_scc) {
- MACIO_BIS(KEYLARGO_FCR0, KL0_SCC_RESET);
- (void)MACIO_IN32(KEYLARGO_FCR0);
- UNLOCK(flags);
- mdelay(15);
- LOCK(flags);
- MACIO_BIC(KEYLARGO_FCR0, KL0_SCC_RESET);
- }
- if (need_reset_irda) {
- MACIO_BIS(KEYLARGO_FCR0, KL0_IRDA_RESET);
- (void)MACIO_IN32(KEYLARGO_FCR0);
- UNLOCK(flags);
- mdelay(15);
- LOCK(flags);
- MACIO_BIC(KEYLARGO_FCR0, KL0_IRDA_RESET);
- }
- UNLOCK(flags);
- if (param & PMAC_SCC_FLAG_XMON)
- macio->flags |= MACIO_FLAG_SCC_LOCKED;
- } else {
- if (macio->flags & MACIO_FLAG_SCC_LOCKED)
- return -EPERM;
- LOCK(flags);
- fcr = MACIO_IN32(KEYLARGO_FCR0);
- if (chan_mask & MACIO_FLAG_SCCA_ON)
- fcr &= ~KL0_SCCA_ENABLE;
- if (chan_mask & MACIO_FLAG_SCCB_ON) {
- fcr &= ~KL0_SCCB_ENABLE;
- /* Perform irda specific clears */
- if ((param & 0xfff) == PMAC_SCC_IRDA) {
- fcr &= ~KL0_IRDA_ENABLE;
- fcr &= ~(KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE);
- fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0);
- fcr &= ~(KL0_IRDA_SOURCE1_SEL|KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND);
- }
- }
- MACIO_OUT32(KEYLARGO_FCR0, fcr);
- if ((fcr & (KL0_SCCA_ENABLE | KL0_SCCB_ENABLE)) == 0) {
- fcr &= ~KL0_SCC_CELL_ENABLE;
- MACIO_OUT32(KEYLARGO_FCR0, fcr);
- }
- macio->flags &= ~(chan_mask);
- UNLOCK(flags);
- mdelay(10);
- }
- return 0;
-}
-
-static long
-core99_modem_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- u8 gpio;
- unsigned long flags;
-
- /* Hack for internal USB modem */
- if (node == NULL) {
- if (macio_chips[0].type != macio_keylargo)
- return -ENODEV;
- node = macio_chips[0].of_node;
- }
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
- gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);
- gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;
- gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;
-
- if (!value) {
- LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
- UNLOCK(flags);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- mdelay(250);
- }
- LOCK(flags);
- if (value) {
- MACIO_BIC(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
- UNLOCK(flags);
- (void)MACIO_IN32(KEYLARGO_FCR2);
- mdelay(250);
- } else {
- MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
- UNLOCK(flags);
- }
- if (value) {
- LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250);
- }
- return 0;
-}
-
-static long
-pangea_modem_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- u8 gpio;
- unsigned long flags;
-
- /* Hack for internal USB modem */
- if (node == NULL) {
- if (macio_chips[0].type != macio_pangea &&
- macio_chips[0].type != macio_intrepid)
- return -ENODEV;
- node = macio_chips[0].of_node;
- }
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
- gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);
- gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;
- gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;
-
- if (!value) {
- LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
- UNLOCK(flags);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- mdelay(250);
- }
- LOCK(flags);
- if (value) {
- MACIO_OUT8(KL_GPIO_MODEM_POWER,
- KEYLARGO_GPIO_OUTPUT_ENABLE);
- UNLOCK(flags);
- (void)MACIO_IN32(KEYLARGO_FCR2);
- mdelay(250);
- } else {
- MACIO_OUT8(KL_GPIO_MODEM_POWER,
- KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
- UNLOCK(flags);
- }
- if (value) {
- LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250);
- }
- return 0;
-}
-
-static long
-core99_ata100_enable(struct device_node* node, long value)
-{
- unsigned long flags;
- struct pci_dev *pdev = NULL;
- u8 pbus, pid;
-
- if (uninorth_rev < 0x24)
- return -ENODEV;
-
- LOCK(flags);
- if (value)
- UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100);
- else
- UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100);
- (void)UN_IN(UNI_N_CLOCK_CNTL);
- UNLOCK(flags);
- udelay(20);
-
- if (value) {
- if (pci_device_from_OF_node(node, &pbus, &pid) == 0)
- pdev = pci_find_slot(pbus, pid);
- if (pdev == NULL)
- return 0;
- pci_enable_device(pdev);
- pci_set_master(pdev);
- }
- return 0;
-}
-
-static long
-core99_ide_enable(struct device_node* node, long param, long value)
-{
- /* Bus ID 0 to 2 are KeyLargo based IDE, busID 3 is U2
- * based ata-100
- */
- switch(param) {
- case 0:
- return simple_feature_tweak(node, macio_unknown,
- KEYLARGO_FCR1, KL1_EIDE0_ENABLE, value);
- case 1:
- return simple_feature_tweak(node, macio_unknown,
- KEYLARGO_FCR1, KL1_EIDE1_ENABLE, value);
- case 2:
- return simple_feature_tweak(node, macio_unknown,
- KEYLARGO_FCR1, KL1_UIDE_ENABLE, value);
- case 3:
- return core99_ata100_enable(node, value);
- default:
- return -ENODEV;
- }
-}
-
-static long
-core99_ide_reset(struct device_node* node, long param, long value)
-{
- switch(param) {
- case 0:
- return simple_feature_tweak(node, macio_unknown,
- KEYLARGO_FCR1, KL1_EIDE0_RESET_N, !value);
- case 1:
- return simple_feature_tweak(node, macio_unknown,
- KEYLARGO_FCR1, KL1_EIDE1_RESET_N, !value);
- case 2:
- return simple_feature_tweak(node, macio_unknown,
- KEYLARGO_FCR1, KL1_UIDE_RESET_N, !value);
- default:
- return -ENODEV;
- }
-}
-
-static long
-core99_gmac_enable(struct device_node* node, long param, long value)
-{
- unsigned long flags;
-
- LOCK(flags);
- if (value)
- UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
- else
- UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
- (void)UN_IN(UNI_N_CLOCK_CNTL);
- UNLOCK(flags);
- udelay(20);
-
- return 0;
-}
-
-static long
-core99_gmac_phy_reset(struct device_node* node, long param, long value)
-{
- unsigned long flags;
- struct macio_chip* macio;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea &&
- macio->type != macio_intrepid)
- return -ENODEV;
-
- LOCK(flags);
- MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE);
- (void)MACIO_IN8(KL_GPIO_ETH_PHY_RESET);
- UNLOCK(flags);
- mdelay(10);
- LOCK(flags);
- MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, /*KEYLARGO_GPIO_OUTPUT_ENABLE | */
- KEYLARGO_GPIO_OUTOUT_DATA);
- UNLOCK(flags);
- mdelay(10);
-
- return 0;
-}
-
-static long
-core99_sound_chip_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
-
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
-
- /* Do a better probe code, screamer G4 desktops &
- * iMacs can do that too, add a recalibrate in
- * the driver as well
- */
- if (pmac_mb.model_id == PMAC_TYPE_PISMO ||
- pmac_mb.model_id == PMAC_TYPE_TITANIUM) {
- LOCK(flags);
- if (value)
- MACIO_OUT8(KL_GPIO_SOUND_POWER,
- KEYLARGO_GPIO_OUTPUT_ENABLE |
- KEYLARGO_GPIO_OUTOUT_DATA);
- else
- MACIO_OUT8(KL_GPIO_SOUND_POWER,
- KEYLARGO_GPIO_OUTPUT_ENABLE);
- (void)MACIO_IN8(KL_GPIO_SOUND_POWER);
- UNLOCK(flags);
- }
- return 0;
-}
-
-static long
-core99_airport_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
- int state;
-
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
-
- /* Hint: we allow passing of macio itself for the sake of the
- * sleep code
- */
- if (node != macio->of_node &&
- (!node->parent || node->parent != macio->of_node))
- return -ENODEV;
- state = (macio->flags & MACIO_FLAG_AIRPORT_ON) != 0;
- if (value == state)
- return 0;
- if (value) {
- /* This code is a reproduction of OF enable-cardslot
- * and init-wireless methods, slightly hacked until
- * I got it working.
- */
- LOCK(flags);
- MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 5);
- (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf);
- UNLOCK(flags);
- mdelay(10);
- LOCK(flags);
- MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 4);
- (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf);
- UNLOCK(flags);
-
- mdelay(10);
-
- LOCK(flags);
- MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16);
- (void)MACIO_IN32(KEYLARGO_FCR2);
- udelay(10);
- MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xb, 0);
- (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xb);
- udelay(10);
- MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xa, 0x28);
- (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xa);
- udelay(10);
- MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xd, 0x28);
- (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xd);
- udelay(10);
- MACIO_OUT8(KEYLARGO_GPIO_0+0xd, 0x28);
- (void)MACIO_IN8(KEYLARGO_GPIO_0+0xd);
- udelay(10);
- MACIO_OUT8(KEYLARGO_GPIO_0+0xe, 0x28);
- (void)MACIO_IN8(KEYLARGO_GPIO_0+0xe);
- UNLOCK(flags);
- udelay(10);
- MACIO_OUT32(0x1c000, 0);
- mdelay(1);
- MACIO_OUT8(0x1a3e0, 0x41);
- (void)MACIO_IN8(0x1a3e0);
- udelay(10);
- LOCK(flags);
- MACIO_BIS(KEYLARGO_FCR2, KL2_CARDSEL_16);
- (void)MACIO_IN32(KEYLARGO_FCR2);
- UNLOCK(flags);
- mdelay(100);
-
- macio->flags |= MACIO_FLAG_AIRPORT_ON;
- } else {
- LOCK(flags);
- MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16);
- (void)MACIO_IN32(KEYLARGO_FCR2);
- MACIO_OUT8(KL_GPIO_AIRPORT_0, 0);
- MACIO_OUT8(KL_GPIO_AIRPORT_1, 0);
- MACIO_OUT8(KL_GPIO_AIRPORT_2, 0);
- MACIO_OUT8(KL_GPIO_AIRPORT_3, 0);
- MACIO_OUT8(KL_GPIO_AIRPORT_4, 0);
- (void)MACIO_IN8(KL_GPIO_AIRPORT_4);
- UNLOCK(flags);
-
- macio->flags &= ~MACIO_FLAG_AIRPORT_ON;
- }
- return 0;
-}
-
-#ifdef CONFIG_SMP
-static long
-core99_reset_cpu(struct device_node* node, long param, long value)
-{
- unsigned int reset_io = 0;
- unsigned long flags;
- struct macio_chip* macio;
- struct device_node* np;
- const int dflt_reset_lines[] = { KL_GPIO_RESET_CPU0,
- KL_GPIO_RESET_CPU1,
- KL_GPIO_RESET_CPU2,
- KL_GPIO_RESET_CPU3 };
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo)
- return -ENODEV;
-
- np = find_path_device("/cpus");
- if (np == NULL)
- return -ENODEV;
- for (np = np->child; np != NULL; np = np->sibling) {
- u32* num = (u32 *)get_property(np, "reg", NULL);
- u32* rst = (u32 *)get_property(np, "soft-reset", NULL);
- if (num == NULL || rst == NULL)
- continue;
- if (param == *num) {
- reset_io = *rst;
- break;
- }
- }
- if (np == NULL || reset_io == 0)
- reset_io = dflt_reset_lines[param];
-
- LOCK(flags);
- MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
- (void)MACIO_IN8(reset_io);
- udelay(1);
- MACIO_OUT8(reset_io, 0);
- (void)MACIO_IN8(reset_io);
- UNLOCK(flags);
-
- return 0;
-}
-#endif /* CONFIG_SMP */
-
-static long
-core99_usb_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
- char* prop;
- int number;
- u32 reg;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea &&
- macio->type != macio_intrepid)
- return -ENODEV;
-
- prop = (char *)get_property(node, "AAPL,clock-id", NULL);
- if (!prop)
- return -ENODEV;
- if (strncmp(prop, "usb0u048", 8) == 0)
- number = 0;
- else if (strncmp(prop, "usb1u148", 8) == 0)
- number = 2;
- else if (strncmp(prop, "usb2u248", 8) == 0)
- number = 4;
- else
- return -ENODEV;
-
- /* Sorry for the brute-force locking, but this is only used during
- * sleep and the timing seem to be critical
- */
- LOCK(flags);
- if (value) {
- /* Turn ON */
- if (number == 0) {
- MACIO_BIC(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
- (void)MACIO_IN32(KEYLARGO_FCR0);
- UNLOCK(flags);
- mdelay(1);
- LOCK(flags);
- MACIO_BIS(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
- } else if (number == 2) {
- MACIO_BIC(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
- UNLOCK(flags);
- (void)MACIO_IN32(KEYLARGO_FCR0);
- mdelay(1);
- LOCK(flags);
- MACIO_BIS(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
- } else if (number == 4) {
- MACIO_BIC(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1));
- UNLOCK(flags);
- (void)MACIO_IN32(KEYLARGO_FCR1);
- mdelay(1);
- LOCK(flags);
- MACIO_BIS(KEYLARGO_FCR1, KL1_USB2_CELL_ENABLE);
- }
- if (number < 4) {
- reg = MACIO_IN32(KEYLARGO_FCR4);
- reg &= ~(KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
- KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number));
- reg &= ~(KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
- KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1));
- MACIO_OUT32(KEYLARGO_FCR4, reg);
- (void)MACIO_IN32(KEYLARGO_FCR4);
- udelay(10);
- } else {
- reg = MACIO_IN32(KEYLARGO_FCR3);
- reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) |
- KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0));
- reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) |
- KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1));
- MACIO_OUT32(KEYLARGO_FCR3, reg);
- (void)MACIO_IN32(KEYLARGO_FCR3);
- udelay(10);
- }
- if (macio->type == macio_intrepid) {
- /* wait for clock stopped bits to clear */
- u32 test0 = 0, test1 = 0;
- u32 status0, status1;
- int timeout = 1000;
-
- UNLOCK(flags);
- switch (number) {
- case 0:
- test0 = UNI_N_CLOCK_STOPPED_USB0;
- test1 = UNI_N_CLOCK_STOPPED_USB0PCI;
- break;
- case 2:
- test0 = UNI_N_CLOCK_STOPPED_USB1;
- test1 = UNI_N_CLOCK_STOPPED_USB1PCI;
- break;
- case 4:
- test0 = UNI_N_CLOCK_STOPPED_USB2;
- test1 = UNI_N_CLOCK_STOPPED_USB2PCI;
- break;
- }
- do {
- if (--timeout <= 0) {
- printk(KERN_ERR "core99_usb_enable: "
- "Timeout waiting for clocks\n");
- break;
- }
- mdelay(1);
- status0 = UN_IN(UNI_N_CLOCK_STOP_STATUS0);
- status1 = UN_IN(UNI_N_CLOCK_STOP_STATUS1);
- } while ((status0 & test0) | (status1 & test1));
- LOCK(flags);
- }
- } else {
- /* Turn OFF */
- if (number < 4) {
- reg = MACIO_IN32(KEYLARGO_FCR4);
- reg |= KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
- KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number);
- reg |= KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
- KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1);
- MACIO_OUT32(KEYLARGO_FCR4, reg);
- (void)MACIO_IN32(KEYLARGO_FCR4);
- udelay(1);
- } else {
- reg = MACIO_IN32(KEYLARGO_FCR3);
- reg |= KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) |
- KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0);
- reg |= KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) |
- KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1);
- MACIO_OUT32(KEYLARGO_FCR3, reg);
- (void)MACIO_IN32(KEYLARGO_FCR3);
- udelay(1);
- }
- if (number == 0) {
- if (macio->type != macio_intrepid)
- MACIO_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
- (void)MACIO_IN32(KEYLARGO_FCR0);
- udelay(1);
- MACIO_BIS(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
- (void)MACIO_IN32(KEYLARGO_FCR0);
- } else if (number == 2) {
- if (macio->type != macio_intrepid)
- MACIO_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
- (void)MACIO_IN32(KEYLARGO_FCR0);
- udelay(1);
- MACIO_BIS(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
- (void)MACIO_IN32(KEYLARGO_FCR0);
- } else if (number == 4) {
- udelay(1);
- MACIO_BIS(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1));
- (void)MACIO_IN32(KEYLARGO_FCR1);
- }
- udelay(1);
- }
- UNLOCK(flags);
-
- return 0;
-}
-
-static long
-core99_firewire_enable(struct device_node* node, long param, long value)
-{
- unsigned long flags;
- struct macio_chip* macio;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea &&
- macio->type != macio_intrepid)
- return -ENODEV;
- if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
- return -ENODEV;
-
- LOCK(flags);
- if (value) {
- UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
- (void)UN_IN(UNI_N_CLOCK_CNTL);
- } else {
- UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
- (void)UN_IN(UNI_N_CLOCK_CNTL);
- }
- UNLOCK(flags);
- mdelay(1);
-
- return 0;
-}
-
-static long
-core99_firewire_cable_power(struct device_node* node, long param, long value)
-{
- unsigned long flags;
- struct macio_chip* macio;
-
- /* Trick: we allow NULL node */
- if ((pmac_mb.board_flags & PMAC_MB_HAS_FW_POWER) == 0)
- return -ENODEV;
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea &&
- macio->type != macio_intrepid)
- return -ENODEV;
- if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
- return -ENODEV;
-
- LOCK(flags);
- if (value) {
- MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 0);
- MACIO_IN8(KL_GPIO_FW_CABLE_POWER);
- udelay(10);
- } else {
- MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 4);
- MACIO_IN8(KL_GPIO_FW_CABLE_POWER); udelay(10);
- }
- UNLOCK(flags);
- mdelay(1);
-
- return 0;
-}
-
-static long
-intrepid_aack_delay_enable(struct device_node* node, long param, long value)
-{
- unsigned long flags;
-
- if (uninorth_rev < 0xd2)
- return -ENODEV;
-
- LOCK(flags);
- if (param)
- UN_BIS(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE);
- else
- UN_BIC(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE);
- UNLOCK(flags);
-
- return 0;
-}
-
-
-#endif /* CONFIG_POWER4 */
-
-static long
-core99_read_gpio(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
-
- return MACIO_IN8(param);
-}
-
-
-static long
-core99_write_gpio(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
-
- MACIO_OUT8(param, (u8)(value & 0xff));
- return 0;
-}
-
-#ifdef CONFIG_POWER4
-
-static long
-g5_gmac_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
- unsigned long flags;
- u8 pbus, pid;
-
- LOCK(flags);
- if (value) {
- MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
- mb();
- k2_skiplist[0] = NULL;
- } else {
- k2_skiplist[0] = node;
- mb();
- MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
- }
-
- UNLOCK(flags);
- mdelay(1);
-
- return 0;
-}
-
-static long
-g5_fw_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
- unsigned long flags;
-
- LOCK(flags);
- if (value) {
- MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
- mb();
- k2_skiplist[1] = NULL;
- } else {
- k2_skiplist[1] = node;
- mb();
- MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
- }
-
- UNLOCK(flags);
- mdelay(1);
-
- return 0;
-}
-
-static long
-g5_mpic_enable(struct device_node* node, long param, long value)
-{
- unsigned long flags;
-
- if (node->parent == NULL || strcmp(node->parent->name, "u3"))
- return 0;
-
- LOCK(flags);
- UN_BIS(U3_TOGGLE_REG, U3_MPIC_RESET | U3_MPIC_OUTPUT_ENABLE);
- UNLOCK(flags);
-
- return 0;
-}
-
-#ifdef CONFIG_SMP
-static long
-g5_reset_cpu(struct device_node* node, long param, long value)
-{
- unsigned int reset_io = 0;
- unsigned long flags;
- struct macio_chip* macio;
- struct device_node* np;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo2)
- return -ENODEV;
-
- np = find_path_device("/cpus");
- if (np == NULL)
- return -ENODEV;
- for (np = np->child; np != NULL; np = np->sibling) {
- u32* num = (u32 *)get_property(np, "reg", NULL);
- u32* rst = (u32 *)get_property(np, "soft-reset", NULL);
- if (num == NULL || rst == NULL)
- continue;
- if (param == *num) {
- reset_io = *rst;
- break;
- }
- }
- if (np == NULL || reset_io == 0)
- return -ENODEV;
-
- LOCK(flags);
- MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
- (void)MACIO_IN8(reset_io);
- udelay(1);
- MACIO_OUT8(reset_io, 0);
- (void)MACIO_IN8(reset_io);
- UNLOCK(flags);
-
- return 0;
-}
-#endif /* CONFIG_SMP */
-
-/*
- * This can be called from pmac_smp so isn't static
- *
- * This takes the second CPU off the bus on dual CPU machines
- * running UP
- */
-void g5_phy_disable_cpu1(void)
-{
- UN_OUT(U3_API_PHY_CONFIG_1, 0);
-}
-
-#endif /* CONFIG_POWER4 */
-
-#ifndef CONFIG_POWER4
-
-static void
-keylargo_shutdown(struct macio_chip* macio, int sleep_mode)
-{
- u32 temp;
-
- if (sleep_mode) {
- mdelay(1);
- MACIO_BIS(KEYLARGO_FCR0, KL0_USB_REF_SUSPEND);
- (void)MACIO_IN32(KEYLARGO_FCR0);
- mdelay(1);
- }
-
- MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
- KL0_SCC_CELL_ENABLE |
- KL0_IRDA_ENABLE | KL0_IRDA_CLK32_ENABLE |
- KL0_IRDA_CLK19_ENABLE);
-
- MACIO_BIC(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK);
- MACIO_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_IDE_ENABLE);
-
- MACIO_BIC(KEYLARGO_FCR1,
- KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
- KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE |
- KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
- KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
- KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
- KL1_EIDE0_ENABLE | KL1_EIDE0_RESET_N |
- KL1_EIDE1_ENABLE | KL1_EIDE1_RESET_N |
- KL1_UIDE_ENABLE);
-
- MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
- MACIO_BIC(KEYLARGO_FCR2, KL2_IOBUS_ENABLE);
-
- temp = MACIO_IN32(KEYLARGO_FCR3);
- if (macio->rev >= 2) {
- temp |= KL3_SHUTDOWN_PLL2X;
- if (sleep_mode)
- temp |= KL3_SHUTDOWN_PLL_TOTAL;
- }
-
- temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
- KL3_SHUTDOWN_PLLKW35;
- if (sleep_mode)
- temp |= KL3_SHUTDOWN_PLLKW12;
- temp &= ~(KL3_CLK66_ENABLE | KL3_CLK49_ENABLE | KL3_CLK45_ENABLE
- | KL3_CLK31_ENABLE | KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE);
- if (sleep_mode)
- temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE);
- MACIO_OUT32(KEYLARGO_FCR3, temp);
-
- /* Flush posted writes & wait a bit */
- (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
-}
-
-static void
-pangea_shutdown(struct macio_chip* macio, int sleep_mode)
-{
- u32 temp;
-
- MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
- KL0_SCC_CELL_ENABLE |
- KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE);
-
- MACIO_BIC(KEYLARGO_FCR1,
- KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
- KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE |
- KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
- KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
- KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
- KL1_UIDE_ENABLE);
- if (pmac_mb.board_flags & PMAC_MB_MOBILE)
- MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
-
- MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
-
- temp = MACIO_IN32(KEYLARGO_FCR3);
- temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
- KL3_SHUTDOWN_PLLKW35;
- temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE | KL3_CLK31_ENABLE
- | KL3_I2S0_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE);
- if (sleep_mode)
- temp &= ~(KL3_VIA_CLK16_ENABLE | KL3_TIMER_CLK18_ENABLE);
- MACIO_OUT32(KEYLARGO_FCR3, temp);
-
- /* Flush posted writes & wait a bit */
- (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
-}
-
-static void
-intrepid_shutdown(struct macio_chip* macio, int sleep_mode)
-{
- u32 temp;
-
- MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
- KL0_SCC_CELL_ENABLE);
-
- MACIO_BIC(KEYLARGO_FCR1,
- /*KL1_USB2_CELL_ENABLE |*/
- KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
- KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
- KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE);
- if (pmac_mb.board_flags & PMAC_MB_MOBILE)
- MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
-
- temp = MACIO_IN32(KEYLARGO_FCR3);
- temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE |
- KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE);
- if (sleep_mode)
- temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_IT_VIA_CLK32_ENABLE);
- MACIO_OUT32(KEYLARGO_FCR3, temp);
-
- /* Flush posted writes & wait a bit */
- (void)MACIO_IN32(KEYLARGO_FCR0);
- mdelay(10);
-}
-
-
-void pmac_tweak_clock_spreading(int enable)
-{
- struct macio_chip* macio = &macio_chips[0];
-
- /* Hack for doing clock spreading on some machines PowerBooks and
- * iBooks. This implements the "platform-do-clockspreading" OF
- * property as decoded manually on various models. For safety, we also
- * check the product ID in the device-tree in cases we'll whack the i2c
- * chip to make reasonably sure we won't set wrong values in there
- *
- * Of course, ultimately, we have to implement a real parser for
- * the platform-do-* stuff...
- */
-
- if (macio->type == macio_intrepid) {
- struct device_node *clock =
- of_find_node_by_path("/uni-n@f8000000/hw-clock");
- if (clock && get_property(clock, "platform-do-clockspreading",
- NULL)) {
- printk(KERN_INFO "%sabling clock spreading on Intrepid"
- " ASIC\n", enable ? "En" : "Dis");
- if (enable)
- UN_OUT(UNI_N_CLOCK_SPREADING, 2);
- else
- UN_OUT(UNI_N_CLOCK_SPREADING, 0);
- mdelay(40);
- }
- of_node_put(clock);
- }
-
- while (machine_is_compatible("PowerBook5,2") ||
- machine_is_compatible("PowerBook5,3") ||
- machine_is_compatible("PowerBook6,2") ||
- machine_is_compatible("PowerBook6,3")) {
- struct device_node *ui2c = of_find_node_by_type(NULL, "i2c");
- struct device_node *dt = of_find_node_by_name(NULL, "device-tree");
- u8 buffer[9];
- u32 *productID;
- int i, rc, changed = 0;
-
- if (dt == NULL)
- break;
- productID = (u32 *)get_property(dt, "pid#", NULL);
- if (productID == NULL)
- break;
- while(ui2c) {
- struct device_node *p = of_get_parent(ui2c);
- if (p && !strcmp(p->name, "uni-n"))
- break;
- ui2c = of_find_node_by_type(ui2c, "i2c");
- }
- if (ui2c == NULL)
- break;
- DBG("Trying to bump clock speed for PID: %08x...\n", *productID);
- rc = pmac_low_i2c_open(ui2c, 1);
- if (rc != 0)
- break;
- pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
- rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
- DBG("read result: %d,", rc);
- if (rc != 0) {
- pmac_low_i2c_close(ui2c);
- break;
- }
- for (i=0; i<9; i++)
- DBG(" %02x", buffer[i]);
- DBG("\n");
-
- switch(*productID) {
- case 0x1182: /* AlBook 12" rev 2 */
- case 0x1183: /* iBook G4 12" */
- buffer[0] = (buffer[0] & 0x8f) | 0x70;
- buffer[2] = (buffer[2] & 0x7f) | 0x00;
- buffer[5] = (buffer[5] & 0x80) | 0x31;
- buffer[6] = (buffer[6] & 0x40) | 0xb0;
- buffer[7] = (buffer[7] & 0x00) | (enable ? 0xc0 : 0xba);
- buffer[8] = (buffer[8] & 0x00) | 0x30;
- changed = 1;
- break;
- case 0x3142: /* AlBook 15" (ATI M10) */
- case 0x3143: /* AlBook 17" (ATI M10) */
- buffer[0] = (buffer[0] & 0xaf) | 0x50;
- buffer[2] = (buffer[2] & 0x7f) | 0x00;
- buffer[5] = (buffer[5] & 0x80) | 0x31;
- buffer[6] = (buffer[6] & 0x40) | 0xb0;
- buffer[7] = (buffer[7] & 0x00) | (enable ? 0xd0 : 0xc0);
- buffer[8] = (buffer[8] & 0x00) | 0x30;
- changed = 1;
- break;
- default:
- DBG("i2c-hwclock: Machine model not handled\n");
- break;
- }
- if (!changed) {
- pmac_low_i2c_close(ui2c);
- break;
- }
- printk(KERN_INFO "%sabling clock spreading on i2c clock chip\n",
- enable ? "En" : "Dis");
- pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub);
- rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9);
- DBG("write result: %d,", rc);
- pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
- rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
- DBG("read result: %d,", rc);
- if (rc != 0) {
- pmac_low_i2c_close(ui2c);
- break;
- }
- for (i=0; i<9; i++)
- DBG(" %02x", buffer[i]);
- pmac_low_i2c_close(ui2c);
- break;
- }
-}
-
-
-static int
-core99_sleep(void)
-{
- struct macio_chip* macio;
- int i;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea &&
- macio->type != macio_intrepid)
- return -ENODEV;
-
- /* We power off the wireless slot in case it was not done
- * by the driver. We don't power it on automatically however
- */
- if (macio->flags & MACIO_FLAG_AIRPORT_ON)
- core99_airport_enable(macio->of_node, 0, 0);
-
- /* We power off the FW cable. Should be done by the driver... */
- if (macio->flags & MACIO_FLAG_FW_SUPPORTED) {
- core99_firewire_enable(NULL, 0, 0);
- core99_firewire_cable_power(NULL, 0, 0);
- }
-
- /* We make sure int. modem is off (in case driver lost it) */
- if (macio->type == macio_keylargo)
- core99_modem_enable(macio->of_node, 0, 0);
- else
- pangea_modem_enable(macio->of_node, 0, 0);
-
- /* We make sure the sound is off as well */
- core99_sound_chip_enable(macio->of_node, 0, 0);
-
- /*
- * Save various bits of KeyLargo
- */
-
- /* Save the state of the various GPIOs */
- save_gpio_levels[0] = MACIO_IN32(KEYLARGO_GPIO_LEVELS0);
- save_gpio_levels[1] = MACIO_IN32(KEYLARGO_GPIO_LEVELS1);
- for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++)
- save_gpio_extint[i] = MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+i);
- for (i=0; i<KEYLARGO_GPIO_CNT; i++)
- save_gpio_normal[i] = MACIO_IN8(KEYLARGO_GPIO_0+i);
-
- /* Save the FCRs */
- if (macio->type == macio_keylargo)
- save_mbcr = MACIO_IN32(KEYLARGO_MBCR);
- save_fcr[0] = MACIO_IN32(KEYLARGO_FCR0);
- save_fcr[1] = MACIO_IN32(KEYLARGO_FCR1);
- save_fcr[2] = MACIO_IN32(KEYLARGO_FCR2);
- save_fcr[3] = MACIO_IN32(KEYLARGO_FCR3);
- save_fcr[4] = MACIO_IN32(KEYLARGO_FCR4);
- if (macio->type == macio_pangea || macio->type == macio_intrepid)
- save_fcr[5] = MACIO_IN32(KEYLARGO_FCR5);
-
- /* Save state & config of DBDMA channels */
- dbdma_save(macio, save_dbdma);
-
- /*
- * Turn off as much as we can
- */
- if (macio->type == macio_pangea)
- pangea_shutdown(macio, 1);
- else if (macio->type == macio_intrepid)
- intrepid_shutdown(macio, 1);
- else if (macio->type == macio_keylargo)
- keylargo_shutdown(macio, 1);
-
- /*
- * Put the host bridge to sleep
- */
-
- save_unin_clock_ctl = UN_IN(UNI_N_CLOCK_CNTL);
- /* Note: do not switch GMAC off, driver does it when necessary, WOL must keep it
- * enabled !
- */
- UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl &
- ~(/*UNI_N_CLOCK_CNTL_GMAC|*/UNI_N_CLOCK_CNTL_FW/*|UNI_N_CLOCK_CNTL_PCI*/));
- udelay(100);
- UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING);
- UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_SLEEP);
- mdelay(10);
-
- /*
- * FIXME: A bit of black magic with OpenPIC (don't ask me why)
- */
- if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) {
- MACIO_BIS(0x506e0, 0x00400000);
- MACIO_BIS(0x506e0, 0x80000000);
- }
- return 0;
-}
-
-static int
-core99_wake_up(void)
-{
- struct macio_chip* macio;
- int i;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea &&
- macio->type != macio_intrepid)
- return -ENODEV;
-
- /*
- * Wakeup the host bridge
- */
- UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL);
- udelay(10);
- UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING);
- udelay(10);
-
- /*
- * Restore KeyLargo
- */
-
- if (macio->type == macio_keylargo) {
- MACIO_OUT32(KEYLARGO_MBCR, save_mbcr);
- (void)MACIO_IN32(KEYLARGO_MBCR); udelay(10);
- }
- MACIO_OUT32(KEYLARGO_FCR0, save_fcr[0]);
- (void)MACIO_IN32(KEYLARGO_FCR0); udelay(10);
- MACIO_OUT32(KEYLARGO_FCR1, save_fcr[1]);
- (void)MACIO_IN32(KEYLARGO_FCR1); udelay(10);
- MACIO_OUT32(KEYLARGO_FCR2, save_fcr[2]);
- (void)MACIO_IN32(KEYLARGO_FCR2); udelay(10);
- MACIO_OUT32(KEYLARGO_FCR3, save_fcr[3]);
- (void)MACIO_IN32(KEYLARGO_FCR3); udelay(10);
- MACIO_OUT32(KEYLARGO_FCR4, save_fcr[4]);
- (void)MACIO_IN32(KEYLARGO_FCR4); udelay(10);
- if (macio->type == macio_pangea || macio->type == macio_intrepid) {
- MACIO_OUT32(KEYLARGO_FCR5, save_fcr[5]);
- (void)MACIO_IN32(KEYLARGO_FCR5); udelay(10);
- }
-
- dbdma_restore(macio, save_dbdma);
-
- MACIO_OUT32(KEYLARGO_GPIO_LEVELS0, save_gpio_levels[0]);
- MACIO_OUT32(KEYLARGO_GPIO_LEVELS1, save_gpio_levels[1]);
- for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++)
- MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+i, save_gpio_extint[i]);
- for (i=0; i<KEYLARGO_GPIO_CNT; i++)
- MACIO_OUT8(KEYLARGO_GPIO_0+i, save_gpio_normal[i]);
-
- /* FIXME more black magic with OpenPIC ... */
- if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) {
- MACIO_BIC(0x506e0, 0x00400000);
- MACIO_BIC(0x506e0, 0x80000000);
- }
-
- UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl);
- udelay(100);
-
- return 0;
-}
-
-static long
-core99_sleep_state(struct device_node* node, long param, long value)
-{
- /* Param == 1 means to enter the "fake sleep" mode that is
- * used for CPU speed switch
- */
- if (param == 1) {
- if (value == 1) {
- UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING);
- UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_IDLE2);
- } else {
- UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL);
- udelay(10);
- UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING);
- udelay(10);
- }
- return 0;
- }
- if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
- return -EPERM;
-
- if (value == 1)
- return core99_sleep();
- else if (value == 0)
- return core99_wake_up();
- return 0;
-}
-
-#endif /* CONFIG_POWER4 */
-
-static long
-generic_dev_can_wake(struct device_node* node, long param, long value)
-{
- /* Todo: eventually check we are really dealing with on-board
- * video device ...
- */
-
- if (pmac_mb.board_flags & PMAC_MB_MAY_SLEEP)
- pmac_mb.board_flags |= PMAC_MB_CAN_SLEEP;
- return 0;
-}
-
-static long
-generic_get_mb_info(struct device_node* node, long param, long value)
-{
- switch(param) {
- case PMAC_MB_INFO_MODEL:
- return pmac_mb.model_id;
- case PMAC_MB_INFO_FLAGS:
- return pmac_mb.board_flags;
- case PMAC_MB_INFO_NAME:
- /* hack hack hack... but should work */
- *((const char **)value) = pmac_mb.model_name;
- return 0;
- }
- return -EINVAL;
-}
-
-
-/*
- * Table definitions
- */
-
-/* Used on any machine
- */
-static struct feature_table_entry any_features[] = {
- { PMAC_FTR_GET_MB_INFO, generic_get_mb_info },
- { PMAC_FTR_DEVICE_CAN_WAKE, generic_dev_can_wake },
- { 0, NULL }
-};
-
-#ifndef CONFIG_POWER4
-
-/* OHare based motherboards. Currently, we only use these on the
- * 2400,3400 and 3500 series powerbooks. Some older desktops seem
- * to have issues with turning on/off those asic cells
- */
-static struct feature_table_entry ohare_features[] = {
- { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
- { PMAC_FTR_SWIM3_ENABLE, ohare_floppy_enable },
- { PMAC_FTR_MESH_ENABLE, ohare_mesh_enable },
- { PMAC_FTR_IDE_ENABLE, ohare_ide_enable},
- { PMAC_FTR_IDE_RESET, ohare_ide_reset},
- { PMAC_FTR_SLEEP_STATE, ohare_sleep_state },
- { 0, NULL }
-};
-
-/* Heathrow desktop machines (Beige G3).
- * Separated as some features couldn't be properly tested
- * and the serial port control bits appear to confuse it.
- */
-static struct feature_table_entry heathrow_desktop_features[] = {
- { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
- { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable },
- { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable },
- { PMAC_FTR_IDE_RESET, heathrow_ide_reset },
- { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable },
- { 0, NULL }
-};
-
-/* Heathrow based laptop, that is the Wallstreet and mainstreet
- * powerbooks.
- */
-static struct feature_table_entry heathrow_laptop_features[] = {
- { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
- { PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable },
- { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
- { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable },
- { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable },
- { PMAC_FTR_IDE_RESET, heathrow_ide_reset },
- { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable },
- { PMAC_FTR_SOUND_CHIP_ENABLE, heathrow_sound_enable },
- { PMAC_FTR_SLEEP_STATE, heathrow_sleep_state },
- { 0, NULL }
-};
-
-/* Paddington based machines
- * The lombard (101) powerbook, first iMac models, B&W G3 and Yikes G4.
- */
-static struct feature_table_entry paddington_features[] = {
- { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
- { PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable },
- { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
- { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable },
- { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable },
- { PMAC_FTR_IDE_RESET, heathrow_ide_reset },
- { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable },
- { PMAC_FTR_SOUND_CHIP_ENABLE, heathrow_sound_enable },
- { PMAC_FTR_SLEEP_STATE, heathrow_sleep_state },
- { 0, NULL }
-};
-
-/* Core99 & MacRISC 2 machines (all machines released since the
- * iBook (included), that is all AGP machines, except pangea
- * chipset. The pangea chipset is the "combo" UniNorth/KeyLargo
- * used on iBook2 & iMac "flow power".
- */
-static struct feature_table_entry core99_features[] = {
- { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
- { PMAC_FTR_MODEM_ENABLE, core99_modem_enable },
- { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
- { PMAC_FTR_IDE_RESET, core99_ide_reset },
- { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
- { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
- { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable },
- { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable },
- { PMAC_FTR_USB_ENABLE, core99_usb_enable },
- { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
- { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
- { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
-#ifdef CONFIG_SMP
- { PMAC_FTR_RESET_CPU, core99_reset_cpu },
-#endif /* CONFIG_SMP */
- { PMAC_FTR_READ_GPIO, core99_read_gpio },
- { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
- { 0, NULL }
-};
-
-/* RackMac
- */
-static struct feature_table_entry rackmac_features[] = {
- { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
- { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
- { PMAC_FTR_IDE_RESET, core99_ide_reset },
- { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
- { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
- { PMAC_FTR_USB_ENABLE, core99_usb_enable },
- { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
- { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
- { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
-#ifdef CONFIG_SMP
- { PMAC_FTR_RESET_CPU, core99_reset_cpu },
-#endif /* CONFIG_SMP */
- { PMAC_FTR_READ_GPIO, core99_read_gpio },
- { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
- { 0, NULL }
-};
-
-/* Pangea features
- */
-static struct feature_table_entry pangea_features[] = {
- { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
- { PMAC_FTR_MODEM_ENABLE, pangea_modem_enable },
- { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
- { PMAC_FTR_IDE_RESET, core99_ide_reset },
- { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
- { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
- { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable },
- { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable },
- { PMAC_FTR_USB_ENABLE, core99_usb_enable },
- { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
- { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
- { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
- { PMAC_FTR_READ_GPIO, core99_read_gpio },
- { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
- { 0, NULL }
-};
-
-/* Intrepid features
- */
-static struct feature_table_entry intrepid_features[] = {
- { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
- { PMAC_FTR_MODEM_ENABLE, pangea_modem_enable },
- { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
- { PMAC_FTR_IDE_RESET, core99_ide_reset },
- { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
- { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
- { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable },
- { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable },
- { PMAC_FTR_USB_ENABLE, core99_usb_enable },
- { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
- { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
- { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
- { PMAC_FTR_READ_GPIO, core99_read_gpio },
- { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
- { PMAC_FTR_AACK_DELAY_ENABLE, intrepid_aack_delay_enable },
- { 0, NULL }
-};
-
-#else /* CONFIG_POWER4 */
-
-/* G5 features
- */
-static struct feature_table_entry g5_features[] = {
- { PMAC_FTR_GMAC_ENABLE, g5_gmac_enable },
- { PMAC_FTR_1394_ENABLE, g5_fw_enable },
- { PMAC_FTR_ENABLE_MPIC, g5_mpic_enable },
-#ifdef CONFIG_SMP
- { PMAC_FTR_RESET_CPU, g5_reset_cpu },
-#endif /* CONFIG_SMP */
- { PMAC_FTR_READ_GPIO, core99_read_gpio },
- { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
- { 0, NULL }
-};
-
-#endif /* CONFIG_POWER4 */
-
-static struct pmac_mb_def pmac_mb_defs[] = {
-#ifndef CONFIG_POWER4
- /*
- * Desktops
- */
-
- { "AAPL,8500", "PowerMac 8500/8600",
- PMAC_TYPE_PSURGE, NULL,
- 0
- },
- { "AAPL,9500", "PowerMac 9500/9600",
- PMAC_TYPE_PSURGE, NULL,
- 0
- },
- { "AAPL,7200", "PowerMac 7200",
- PMAC_TYPE_PSURGE, NULL,
- 0
- },
- { "AAPL,7300", "PowerMac 7200/7300",
- PMAC_TYPE_PSURGE, NULL,
- 0
- },
- { "AAPL,7500", "PowerMac 7500",
- PMAC_TYPE_PSURGE, NULL,
- 0
- },
- { "AAPL,ShinerESB", "Apple Network Server",
- PMAC_TYPE_ANS, NULL,
- 0
- },
- { "AAPL,e407", "Alchemy",
- PMAC_TYPE_ALCHEMY, NULL,
- 0
- },
- { "AAPL,e411", "Gazelle",
- PMAC_TYPE_GAZELLE, NULL,
- 0
- },
- { "AAPL,Gossamer", "PowerMac G3 (Gossamer)",
- PMAC_TYPE_GOSSAMER, heathrow_desktop_features,
- 0
- },
- { "AAPL,PowerMac G3", "PowerMac G3 (Silk)",
- PMAC_TYPE_SILK, heathrow_desktop_features,
- 0
- },
- { "PowerMac1,1", "Blue&White G3",
- PMAC_TYPE_YOSEMITE, paddington_features,
- 0
- },
- { "PowerMac1,2", "PowerMac G4 PCI Graphics",
- PMAC_TYPE_YIKES, paddington_features,
- 0
- },
- { "PowerMac2,1", "iMac FireWire",
- PMAC_TYPE_FW_IMAC, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
- },
- { "PowerMac2,2", "iMac FireWire",
- PMAC_TYPE_FW_IMAC, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
- },
- { "PowerMac3,1", "PowerMac G4 AGP Graphics",
- PMAC_TYPE_SAWTOOTH, core99_features,
- PMAC_MB_OLD_CORE99
- },
- { "PowerMac3,2", "PowerMac G4 AGP Graphics",
- PMAC_TYPE_SAWTOOTH, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
- },
- { "PowerMac3,3", "PowerMac G4 AGP Graphics",
- PMAC_TYPE_SAWTOOTH, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
- },
- { "PowerMac3,4", "PowerMac G4 Silver",
- PMAC_TYPE_QUICKSILVER, core99_features,
- PMAC_MB_MAY_SLEEP
- },
- { "PowerMac3,5", "PowerMac G4 Silver",
- PMAC_TYPE_QUICKSILVER, core99_features,
- PMAC_MB_MAY_SLEEP
- },
- { "PowerMac3,6", "PowerMac G4 Windtunnel",
- PMAC_TYPE_WINDTUNNEL, core99_features,
- PMAC_MB_MAY_SLEEP,
- },
- { "PowerMac4,1", "iMac \"Flower Power\"",
- PMAC_TYPE_PANGEA_IMAC, pangea_features,
- PMAC_MB_MAY_SLEEP
- },
- { "PowerMac4,2", "Flat panel iMac",
- PMAC_TYPE_FLAT_PANEL_IMAC, pangea_features,
- PMAC_MB_CAN_SLEEP
- },
- { "PowerMac4,4", "eMac",
- PMAC_TYPE_EMAC, core99_features,
- PMAC_MB_MAY_SLEEP
- },
- { "PowerMac5,1", "PowerMac G4 Cube",
- PMAC_TYPE_CUBE, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
- },
- { "PowerMac6,1", "Flat panel iMac",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP,
- },
- { "PowerMac6,3", "Flat panel iMac",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP,
- },
- { "PowerMac6,4", "eMac",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP,
- },
- { "PowerMac10,1", "Mac mini",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER,
- },
- { "iMac,1", "iMac (first generation)",
- PMAC_TYPE_ORIG_IMAC, paddington_features,
- 0
- },
-
- /*
- * Xserve's
- */
-
- { "RackMac1,1", "XServe",
- PMAC_TYPE_RACKMAC, rackmac_features,
- 0,
- },
- { "RackMac1,2", "XServe rev. 2",
- PMAC_TYPE_RACKMAC, rackmac_features,
- 0,
- },
-
- /*
- * Laptops
- */
-
- { "AAPL,3400/2400", "PowerBook 3400",
- PMAC_TYPE_HOOPER, ohare_features,
- PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
- },
- { "AAPL,3500", "PowerBook 3500",
- PMAC_TYPE_KANGA, ohare_features,
- PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
- },
- { "AAPL,PowerBook1998", "PowerBook Wallstreet",
- PMAC_TYPE_WALLSTREET, heathrow_laptop_features,
- PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
- },
- { "PowerBook1,1", "PowerBook 101 (Lombard)",
- PMAC_TYPE_101_PBOOK, paddington_features,
- PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
- },
- { "PowerBook2,1", "iBook (first generation)",
- PMAC_TYPE_ORIG_IBOOK, core99_features,
- PMAC_MB_CAN_SLEEP | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
- },
- { "PowerBook2,2", "iBook FireWire",
- PMAC_TYPE_FW_IBOOK, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER |
- PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
- },
- { "PowerBook3,1", "PowerBook Pismo",
- PMAC_TYPE_PISMO, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER |
- PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
- },
- { "PowerBook3,2", "PowerBook Titanium",
- PMAC_TYPE_TITANIUM, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
- },
- { "PowerBook3,3", "PowerBook Titanium II",
- PMAC_TYPE_TITANIUM2, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
- },
- { "PowerBook3,4", "PowerBook Titanium III",
- PMAC_TYPE_TITANIUM3, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
- },
- { "PowerBook3,5", "PowerBook Titanium IV",
- PMAC_TYPE_TITANIUM4, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
- },
- { "PowerBook4,1", "iBook 2",
- PMAC_TYPE_IBOOK2, pangea_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
- },
- { "PowerBook4,2", "iBook 2",
- PMAC_TYPE_IBOOK2, pangea_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
- },
- { "PowerBook4,3", "iBook 2 rev. 2",
- PMAC_TYPE_IBOOK2, pangea_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
- },
- { "PowerBook5,1", "PowerBook G4 17\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook5,2", "PowerBook G4 15\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook5,3", "PowerBook G4 17\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook5,4", "PowerBook G4 15\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook5,5", "PowerBook G4 17\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook5,6", "PowerBook G4 15\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook5,7", "PowerBook G4 17\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook5,8", "PowerBook G4 15\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook5,9", "PowerBook G4 17\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook6,1", "PowerBook G4 12\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook6,2", "PowerBook G4",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook6,3", "iBook G4",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook6,4", "PowerBook G4 12\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook6,5", "iBook G4",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook6,7", "iBook G4",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook6,8", "PowerBook G4 12\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
-#else /* CONFIG_POWER4 */
- { "PowerMac7,2", "PowerMac G5",
- PMAC_TYPE_POWERMAC_G5, g5_features,
- 0,
- },
-#endif /* CONFIG_POWER4 */
-};
-
-/*
- * The toplevel feature_call callback
- */
-long
-pmac_do_feature_call(unsigned int selector, ...)
-{
- struct device_node* node;
- long param, value;
- int i;
- feature_call func = NULL;
- va_list args;
-
- if (pmac_mb.features)
- for (i=0; pmac_mb.features[i].function; i++)
- if (pmac_mb.features[i].selector == selector) {
- func = pmac_mb.features[i].function;
- break;
- }
- if (!func)
- for (i=0; any_features[i].function; i++)
- if (any_features[i].selector == selector) {
- func = any_features[i].function;
- break;
- }
- if (!func)
- return -ENODEV;
-
- va_start(args, selector);
- node = (struct device_node*)va_arg(args, void*);
- param = va_arg(args, long);
- value = va_arg(args, long);
- va_end(args);
-
- return func(node, param, value);
-}
-
-static int __init
-probe_motherboard(void)
-{
- int i;
- struct macio_chip* macio = &macio_chips[0];
- const char* model = NULL;
- struct device_node *dt;
-
- /* Lookup known motherboard type in device-tree. First try an
- * exact match on the "model" property, then try a "compatible"
- * match is none is found.
- */
- dt = find_devices("device-tree");
- if (dt != NULL)
- model = (const char *) get_property(dt, "model", NULL);
- for(i=0; model && i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
- if (strcmp(model, pmac_mb_defs[i].model_string) == 0) {
- pmac_mb = pmac_mb_defs[i];
- goto found;
- }
- }
- for(i=0; i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
- if (machine_is_compatible(pmac_mb_defs[i].model_string)) {
- pmac_mb = pmac_mb_defs[i];
- goto found;
- }
- }
-
- /* Fallback to selection depending on mac-io chip type */
- switch(macio->type) {
-#ifndef CONFIG_POWER4
- case macio_grand_central:
- pmac_mb.model_id = PMAC_TYPE_PSURGE;
- pmac_mb.model_name = "Unknown PowerSurge";
- break;
- case macio_ohare:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_OHARE;
- pmac_mb.model_name = "Unknown OHare-based";
- break;
- case macio_heathrow:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_HEATHROW;
- pmac_mb.model_name = "Unknown Heathrow-based";
- pmac_mb.features = heathrow_desktop_features;
- break;
- case macio_paddington:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PADDINGTON;
- pmac_mb.model_name = "Unknown Paddington-based";
- pmac_mb.features = paddington_features;
- break;
- case macio_keylargo:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_CORE99;
- pmac_mb.model_name = "Unknown Keylargo-based";
- pmac_mb.features = core99_features;
- break;
- case macio_pangea:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PANGEA;
- pmac_mb.model_name = "Unknown Pangea-based";
- pmac_mb.features = pangea_features;
- break;
- case macio_intrepid:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_INTREPID;
- pmac_mb.model_name = "Unknown Intrepid-based";
- pmac_mb.features = intrepid_features;
- break;
-#else /* CONFIG_POWER4 */
- case macio_keylargo2:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_K2;
- pmac_mb.model_name = "Unknown G5";
- pmac_mb.features = g5_features;
- break;
-#endif /* CONFIG_POWER4 */
- default:
- return -ENODEV;
- }
-found:
-#ifndef CONFIG_POWER4
- /* Fixup Hooper vs. Comet */
- if (pmac_mb.model_id == PMAC_TYPE_HOOPER) {
- u32 __iomem * mach_id_ptr = ioremap(0xf3000034, 4);
- if (!mach_id_ptr)
- return -ENODEV;
- /* Here, I used to disable the media-bay on comet. It
- * appears this is wrong, the floppy connector is actually
- * a kind of media-bay and works with the current driver.
- */
- if (__raw_readl(mach_id_ptr) & 0x20000000UL)
- pmac_mb.model_id = PMAC_TYPE_COMET;
- iounmap(mach_id_ptr);
- }
-#endif /* CONFIG_POWER4 */
-
-#ifdef CONFIG_6xx
- /* Set default value of powersave_nap on machines that support it.
- * It appears that uninorth rev 3 has a problem with it, we don't
- * enable it on those. In theory, the flush-on-lock property is
- * supposed to be set when not supported, but I'm not very confident
- * that all Apple OF revs did it properly, I do it the paranoid way.
- */
- while (uninorth_base && uninorth_rev > 3) {
- struct device_node* np = find_path_device("/cpus");
- if (!np || !np->child) {
- printk(KERN_WARNING "Can't find CPU(s) in device tree !\n");
- break;
- }
- np = np->child;
- /* Nap mode not supported on SMP */
- if (np->sibling)
- break;
- /* Nap mode not supported if flush-on-lock property is present */
- if (get_property(np, "flush-on-lock", NULL))
- break;
- powersave_nap = 1;
- printk(KERN_INFO "Processor NAP mode on idle enabled.\n");
- break;
- }
-
- /* On CPUs that support it (750FX), lowspeed by default during
- * NAP mode
- */
- powersave_lowspeed = 1;
-#endif /* CONFIG_6xx */
-#ifdef CONFIG_POWER4
- powersave_nap = 1;
-#endif
- /* Check for "mobile" machine */
- if (model && (strncmp(model, "PowerBook", 9) == 0
- || strncmp(model, "iBook", 5) == 0))
- pmac_mb.board_flags |= PMAC_MB_MOBILE;
-
-
- printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name);
- return 0;
-}
-
-/* Initialize the Core99 UniNorth host bridge and memory controller
- */
-static void __init
-probe_uninorth(void)
-{
- unsigned long actrl;
-
- /* Locate core99 Uni-N */
- uninorth_node = of_find_node_by_name(NULL, "uni-n");
- /* Locate G5 u3 */
- if (uninorth_node == NULL) {
- uninorth_node = of_find_node_by_name(NULL, "u3");
- uninorth_u3 = 1;
- }
- if (uninorth_node && uninorth_node->n_addrs > 0) {
- unsigned long address = uninorth_node->addrs[0].address;
- uninorth_base = ioremap(address, 0x40000);
- uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
- if (uninorth_u3)
- u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000);
- } else
- uninorth_node = NULL;
-
- if (!uninorth_node)
- return;
-
- printk(KERN_INFO "Found %s memory controller & host bridge, revision: %d\n",
- uninorth_u3 ? "U3" : "UniNorth", uninorth_rev);
- printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base);
-
- /* Set the arbitrer QAck delay according to what Apple does
- */
- if (uninorth_rev < 0x11) {
- actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK;
- actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 :
- UNI_N_ARB_CTRL_QACK_DELAY) << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT;
- UN_OUT(UNI_N_ARB_CTRL, actrl);
- }
-
- /* Some more magic as done by them in recent MacOS X on UniNorth
- * revs 1.5 to 2.O and Pangea. Seem to toggle the UniN Maxbus/PCI
- * memory timeout
- */
- if ((uninorth_rev >= 0x11 && uninorth_rev <= 0x24) || uninorth_rev == 0xc0)
- UN_OUT(0x2160, UN_IN(0x2160) & 0x00ffffff);
-}
-
-static void __init
-probe_one_macio(const char* name, const char* compat, int type)
-{
- struct device_node* node;
- int i;
- volatile u32 __iomem * base;
- u32* revp;
-
- node = find_devices(name);
- if (!node || !node->n_addrs)
- return;
- if (compat)
- do {
- if (device_is_compatible(node, compat))
- break;
- node = node->next;
- } while (node);
- if (!node)
- return;
- for(i=0; i<MAX_MACIO_CHIPS; i++) {
- if (!macio_chips[i].of_node)
- break;
- if (macio_chips[i].of_node == node)
- return;
- }
- if (i >= MAX_MACIO_CHIPS) {
- printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n");
- printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name);
- return;
- }
- base = ioremap(node->addrs[0].address, node->addrs[0].size);
- if (!base) {
- printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n");
- return;
- }
- if (type == macio_keylargo) {
- u32* did = (u32 *)get_property(node, "device-id", NULL);
- if (*did == 0x00000025)
- type = macio_pangea;
- if (*did == 0x0000003e)
- type = macio_intrepid;
- }
- macio_chips[i].of_node = node;
- macio_chips[i].type = type;
- macio_chips[i].base = base;
- macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON;
- macio_chips[i].name = macio_names[type];
- revp = (u32 *)get_property(node, "revision-id", NULL);
- if (revp)
- macio_chips[i].rev = *revp;
- printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n",
- macio_names[type], macio_chips[i].rev, macio_chips[i].base);
-}
-
-static int __init
-probe_macios(void)
-{
- /* Warning, ordering is important */
- probe_one_macio("gc", NULL, macio_grand_central);
- probe_one_macio("ohare", NULL, macio_ohare);
- probe_one_macio("pci106b,7", NULL, macio_ohareII);
- probe_one_macio("mac-io", "keylargo", macio_keylargo);
- probe_one_macio("mac-io", "paddington", macio_paddington);
- probe_one_macio("mac-io", "gatwick", macio_gatwick);
- probe_one_macio("mac-io", "heathrow", macio_heathrow);
- probe_one_macio("mac-io", "K2-Keylargo", macio_keylargo2);
-
- /* Make sure the "main" macio chip appear first */
- if (macio_chips[0].type == macio_gatwick
- && macio_chips[1].type == macio_heathrow) {
- struct macio_chip temp = macio_chips[0];
- macio_chips[0] = macio_chips[1];
- macio_chips[1] = temp;
- }
- if (macio_chips[0].type == macio_ohareII
- && macio_chips[1].type == macio_ohare) {
- struct macio_chip temp = macio_chips[0];
- macio_chips[0] = macio_chips[1];
- macio_chips[1] = temp;
- }
- macio_chips[0].lbus.index = 0;
- macio_chips[1].lbus.index = 1;
-
- return (macio_chips[0].of_node == NULL) ? -ENODEV : 0;
-}
-
-static void __init
-initial_serial_shutdown(struct device_node* np)
-{
- int len;
- struct slot_names_prop {
- int count;
- char name[1];
- } *slots;
- char *conn;
- int port_type = PMAC_SCC_ASYNC;
- int modem = 0;
-
- slots = (struct slot_names_prop *)get_property(np, "slot-names", &len);
- conn = get_property(np, "AAPL,connector", &len);
- if (conn && (strcmp(conn, "infrared") == 0))
- port_type = PMAC_SCC_IRDA;
- else if (device_is_compatible(np, "cobalt"))
- modem = 1;
- else if (slots && slots->count > 0) {
- if (strcmp(slots->name, "IrDA") == 0)
- port_type = PMAC_SCC_IRDA;
- else if (strcmp(slots->name, "Modem") == 0)
- modem = 1;
- }
- if (modem)
- pmac_call_feature(PMAC_FTR_MODEM_ENABLE, np, 0, 0);
- pmac_call_feature(PMAC_FTR_SCC_ENABLE, np, port_type, 0);
-}
-
-static void __init
-set_initial_features(void)
-{
- struct device_node* np;
-
- /* That hack appears to be necessary for some StarMax motherboards
- * but I'm not too sure it was audited for side-effects on other
- * ohare based machines...
- * Since I still have difficulties figuring the right way to
- * differenciate them all and since that hack was there for a long
- * time, I'll keep it around
- */
- if (macio_chips[0].type == macio_ohare && !find_devices("via-pmu")) {
- struct macio_chip* macio = &macio_chips[0];
- MACIO_OUT32(OHARE_FCR, STARMAX_FEATURES);
- } else if (macio_chips[0].type == macio_ohare) {
- struct macio_chip* macio = &macio_chips[0];
- MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
- } else if (macio_chips[1].type == macio_ohare) {
- struct macio_chip* macio = &macio_chips[1];
- MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
- }
-
-#ifdef CONFIG_POWER4
- if (macio_chips[0].type == macio_keylargo2) {
-#ifndef CONFIG_SMP
- /* On SMP machines running UP, we have the second CPU eating
- * bus cycles. We need to take it off the bus. This is done
- * from pmac_smp for SMP kernels running on one CPU
- */
- np = of_find_node_by_type(NULL, "cpu");
- if (np != NULL)
- np = of_find_node_by_type(np, "cpu");
- if (np != NULL) {
- g5_phy_disable_cpu1();
- of_node_put(np);
- }
-#endif /* CONFIG_SMP */
- /* Enable GMAC for now for PCI probing. It will be disabled
- * later on after PCI probe
- */
- np = of_find_node_by_name(NULL, "ethernet");
- while(np) {
- if (device_is_compatible(np, "K2-GMAC"))
- g5_gmac_enable(np, 0, 1);
- np = of_find_node_by_name(np, "ethernet");
- }
-
- /* Enable FW before PCI probe. Will be disabled later on
- * Note: We should have a batter way to check that we are
- * dealing with uninorth internal cell and not a PCI cell
- * on the external PCI. The code below works though.
- */
- np = of_find_node_by_name(NULL, "firewire");
- while(np) {
- if (device_is_compatible(np, "pci106b,5811")) {
- macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
- g5_fw_enable(np, 0, 1);
- }
- np = of_find_node_by_name(np, "firewire");
- }
- }
-#else /* CONFIG_POWER4 */
-
- if (macio_chips[0].type == macio_keylargo ||
- macio_chips[0].type == macio_pangea ||
- macio_chips[0].type == macio_intrepid) {
- /* Enable GMAC for now for PCI probing. It will be disabled
- * later on after PCI probe
- */
- np = of_find_node_by_name(NULL, "ethernet");
- while(np) {
- if (np->parent
- && device_is_compatible(np->parent, "uni-north")
- && device_is_compatible(np, "gmac"))
- core99_gmac_enable(np, 0, 1);
- np = of_find_node_by_name(np, "ethernet");
- }
-
- /* Enable FW before PCI probe. Will be disabled later on
- * Note: We should have a batter way to check that we are
- * dealing with uninorth internal cell and not a PCI cell
- * on the external PCI. The code below works though.
- */
- np = of_find_node_by_name(NULL, "firewire");
- while(np) {
- if (np->parent
- && device_is_compatible(np->parent, "uni-north")
- && (device_is_compatible(np, "pci106b,18") ||
- device_is_compatible(np, "pci106b,30") ||
- device_is_compatible(np, "pci11c1,5811"))) {
- macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
- core99_firewire_enable(np, 0, 1);
- }
- np = of_find_node_by_name(np, "firewire");
- }
-
- /* Enable ATA-100 before PCI probe. */
- np = of_find_node_by_name(NULL, "ata-6");
- while(np) {
- if (np->parent
- && device_is_compatible(np->parent, "uni-north")
- && device_is_compatible(np, "kauai-ata")) {
- core99_ata100_enable(np, 1);
- }
- np = of_find_node_by_name(np, "ata-6");
- }
-
- /* Switch airport off */
- np = find_devices("radio");
- while(np) {
- if (np && np->parent == macio_chips[0].of_node) {
- macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON;
- core99_airport_enable(np, 0, 0);
- }
- np = np->next;
- }
- }
-
- /* On all machines that support sound PM, switch sound off */
- if (macio_chips[0].of_node)
- pmac_do_feature_call(PMAC_FTR_SOUND_CHIP_ENABLE,
- macio_chips[0].of_node, 0, 0);
-
- /* While on some desktop G3s, we turn it back on */
- if (macio_chips[0].of_node && macio_chips[0].type == macio_heathrow
- && (pmac_mb.model_id == PMAC_TYPE_GOSSAMER ||
- pmac_mb.model_id == PMAC_TYPE_SILK)) {
- struct macio_chip* macio = &macio_chips[0];
- MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
- MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
- }
-
- /* Some machine models need the clock chip to be properly setup for
- * clock spreading now. This should be a platform function but we
- * don't do these at the moment
- */
- pmac_tweak_clock_spreading(1);
-
-#endif /* CONFIG_POWER4 */
-
- /* On all machines, switch modem & serial ports off */
- np = find_devices("ch-a");
- while(np) {
- initial_serial_shutdown(np);
- np = np->next;
- }
- np = find_devices("ch-b");
- while(np) {
- initial_serial_shutdown(np);
- np = np->next;
- }
-}
-
-void __init
-pmac_feature_init(void)
-{
- /* Detect the UniNorth memory controller */
- probe_uninorth();
-
- /* Probe mac-io controllers */
- if (probe_macios()) {
- printk(KERN_WARNING "No mac-io chip found\n");
- return;
- }
-
- /* Setup low-level i2c stuffs */
- pmac_init_low_i2c();
-
- /* Probe machine type */
- if (probe_motherboard())
- printk(KERN_WARNING "Unknown PowerMac !\n");
-
- /* Set some initial features (turn off some chips that will
- * be later turned on)
- */
- set_initial_features();
-}
-
-int __init
-pmac_feature_late_init(void)
-{
- struct device_node* np;
-
- /* Request some resources late */
- if (uninorth_node)
- request_OF_resource(uninorth_node, 0, NULL);
- np = find_devices("hammerhead");
- if (np)
- request_OF_resource(np, 0, NULL);
- np = find_devices("interrupt-controller");
- if (np)
- request_OF_resource(np, 0, NULL);
- return 0;
-}
-
-device_initcall(pmac_feature_late_init);
-
-#ifdef CONFIG_POWER4
-
-static void dump_HT_speeds(char *name, u32 cfg, u32 frq)
-{
- int freqs[16] = { 200,300,400,500,600,800,1000,0,0,0,0,0,0,0,0,0 };
- int bits[8] = { 8,16,0,32,2,4,0,0 };
- int freq = (frq >> 8) & 0xf;
-
- if (freqs[freq] == 0)
- printk("%s: Unknown HT link frequency %x\n", name, freq);
- else
- printk("%s: %d MHz on main link, (%d in / %d out) bits width\n",
- name, freqs[freq],
- bits[(cfg >> 28) & 0x7], bits[(cfg >> 24) & 0x7]);
-}
-
-void __init pmac_check_ht_link(void)
-{
- u32 ufreq, freq, ucfg, cfg;
- struct device_node *pcix_node;
- u8 px_bus, px_devfn;
- struct pci_controller *px_hose;
-
- (void)in_be32(u3_ht + U3_HT_LINK_COMMAND);
- ucfg = cfg = in_be32(u3_ht + U3_HT_LINK_CONFIG);
- ufreq = freq = in_be32(u3_ht + U3_HT_LINK_FREQ);
- dump_HT_speeds("U3 HyperTransport", cfg, freq);
-
- pcix_node = of_find_compatible_node(NULL, "pci", "pci-x");
- if (pcix_node == NULL) {
- printk("No PCI-X bridge found\n");
- return;
- }
- if (pci_device_from_OF_node(pcix_node, &px_bus, &px_devfn) != 0) {
- printk("PCI-X bridge found but not matched to pci\n");
- return;
- }
- px_hose = pci_find_hose_for_OF_device(pcix_node);
- if (px_hose == NULL) {
- printk("PCI-X bridge found but not matched to host\n");
- return;
- }
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg);
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq);
- dump_HT_speeds("PCI-X HT Uplink", cfg, freq);
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xc8, &cfg);
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xd0, &freq);
- dump_HT_speeds("PCI-X HT Downlink", cfg, freq);
-}
-
-#endif /* CONFIG_POWER4 */
-
-/*
- * Early video resume hook
- */
-
-static void (*pmac_early_vresume_proc)(void *data);
-static void *pmac_early_vresume_data;
-
-void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
-{
- if (_machine != _MACH_Pmac)
- return;
- preempt_disable();
- pmac_early_vresume_proc = proc;
- pmac_early_vresume_data = data;
- preempt_enable();
-}
-EXPORT_SYMBOL(pmac_set_early_video_resume);
-
-void pmac_call_early_video_resume(void)
-{
- if (pmac_early_vresume_proc)
- pmac_early_vresume_proc(pmac_early_vresume_data);
-}
-
-/*
- * AGP related suspend/resume code
- */
-
-static struct pci_dev *pmac_agp_bridge;
-static int (*pmac_agp_suspend)(struct pci_dev *bridge);
-static int (*pmac_agp_resume)(struct pci_dev *bridge);
-
-void pmac_register_agp_pm(struct pci_dev *bridge,
- int (*suspend)(struct pci_dev *bridge),
- int (*resume)(struct pci_dev *bridge))
-{
- if (suspend || resume) {
- pmac_agp_bridge = bridge;
- pmac_agp_suspend = suspend;
- pmac_agp_resume = resume;
- return;
- }
- if (bridge != pmac_agp_bridge)
- return;
- pmac_agp_suspend = pmac_agp_resume = NULL;
- return;
-}
-EXPORT_SYMBOL(pmac_register_agp_pm);
-
-void pmac_suspend_agp_for_card(struct pci_dev *dev)
-{
- if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL)
- return;
- if (pmac_agp_bridge->bus != dev->bus)
- return;
- pmac_agp_suspend(pmac_agp_bridge);
-}
-EXPORT_SYMBOL(pmac_suspend_agp_for_card);
-
-void pmac_resume_agp_for_card(struct pci_dev *dev)
-{
- if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL)
- return;
- if (pmac_agp_bridge->bus != dev->bus)
- return;
- pmac_agp_resume(pmac_agp_bridge);
-}
-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 08583fc..0000000
--- a/arch/ppc/platforms/pmac_low_i2c.c
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * arch/ppc/platforms/pmac_low_i2c.c
- *
- * Copyright (C) 2003 Ben. Herrenschmidt (benh@kernel.crashing.org)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * This file contains some low-level i2c access routines that
- * need to be used by various bits of the PowerMac platform code
- * at times where the real asynchronous & interrupt driven driver
- * cannot be used. The API borrows some semantics from the darwin
- * driver in order to ease the implementation of the platform
- * properties parser
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#include <asm/keylargo.h>
-#include <asm/uninorth.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/pmac_low_i2c.h>
-
-#define MAX_LOW_I2C_HOST 4
-
-#if 1
-#define DBG(x...) do {\
- printk(KERN_DEBUG "KW:" x); \
- } while(0)
-#else
-#define DBGG(x...)
-#endif
-
-struct low_i2c_host;
-
-typedef int (*low_i2c_func_t)(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len);
-
-struct low_i2c_host
-{
- struct device_node *np; /* OF device node */
- struct semaphore mutex; /* Access mutex for use by i2c-keywest */
- low_i2c_func_t func; /* Access function */
- int is_open : 1; /* Poor man's access control */
- int mode; /* Current mode */
- int channel; /* Current channel */
- int num_channels; /* Number of channels */
- void __iomem * base; /* For keywest-i2c, base address */
- int bsteps; /* And register stepping */
- int speed; /* And speed */
-};
-
-static struct low_i2c_host low_i2c_hosts[MAX_LOW_I2C_HOST];
-
-/* No locking is necessary on allocation, we are running way before
- * anything can race with us
- */
-static struct low_i2c_host *find_low_i2c_host(struct device_node *np)
-{
- int i;
-
- for (i = 0; i < MAX_LOW_I2C_HOST; i++)
- if (low_i2c_hosts[i].np == np)
- return &low_i2c_hosts[i];
- return NULL;
-}
-
-/*
- *
- * i2c-keywest implementation (UniNorth, U2, U3, Keylargo's)
- *
- */
-
-/*
- * Keywest i2c definitions borrowed from drivers/i2c/i2c-keywest.h,
- * should be moved somewhere in include/asm-ppc/
- */
-/* Register indices */
-typedef enum {
- reg_mode = 0,
- reg_control,
- reg_status,
- reg_isr,
- reg_ier,
- reg_addr,
- reg_subaddr,
- reg_data
-} reg_t;
-
-
-/* Mode register */
-#define KW_I2C_MODE_100KHZ 0x00
-#define KW_I2C_MODE_50KHZ 0x01
-#define KW_I2C_MODE_25KHZ 0x02
-#define KW_I2C_MODE_DUMB 0x00
-#define KW_I2C_MODE_STANDARD 0x04
-#define KW_I2C_MODE_STANDARDSUB 0x08
-#define KW_I2C_MODE_COMBINED 0x0C
-#define KW_I2C_MODE_MODE_MASK 0x0C
-#define KW_I2C_MODE_CHAN_MASK 0xF0
-
-/* Control register */
-#define KW_I2C_CTL_AAK 0x01
-#define KW_I2C_CTL_XADDR 0x02
-#define KW_I2C_CTL_STOP 0x04
-#define KW_I2C_CTL_START 0x08
-
-/* Status register */
-#define KW_I2C_STAT_BUSY 0x01
-#define KW_I2C_STAT_LAST_AAK 0x02
-#define KW_I2C_STAT_LAST_RW 0x04
-#define KW_I2C_STAT_SDA 0x08
-#define KW_I2C_STAT_SCL 0x10
-
-/* IER & ISR registers */
-#define KW_I2C_IRQ_DATA 0x01
-#define KW_I2C_IRQ_ADDR 0x02
-#define KW_I2C_IRQ_STOP 0x04
-#define KW_I2C_IRQ_START 0x08
-#define KW_I2C_IRQ_MASK 0x0F
-
-/* State machine states */
-enum {
- state_idle,
- state_addr,
- state_read,
- state_write,
- state_stop,
- state_dead
-};
-
-#define WRONG_STATE(name) do {\
- printk(KERN_DEBUG "KW: wrong state. Got %s, state: %s (isr: %02x)\n", \
- name, __kw_state_names[state], isr); \
- } while(0)
-
-static const char *__kw_state_names[] = {
- "state_idle",
- "state_addr",
- "state_read",
- "state_write",
- "state_stop",
- "state_dead"
-};
-
-static inline u8 __kw_read_reg(struct low_i2c_host *host, reg_t reg)
-{
- return in_8(host->base + (((unsigned)reg) << host->bsteps));
-}
-
-static inline void __kw_write_reg(struct low_i2c_host *host, reg_t reg, u8 val)
-{
- out_8(host->base + (((unsigned)reg) << host->bsteps), val);
- (void)__kw_read_reg(host, reg_subaddr);
-}
-
-#define kw_write_reg(reg, val) __kw_write_reg(host, reg, val)
-#define kw_read_reg(reg) __kw_read_reg(host, reg)
-
-
-/* Don't schedule, the g5 fan controller is too
- * timing sensitive
- */
-static u8 kw_wait_interrupt(struct low_i2c_host* host)
-{
- int i;
- u8 isr;
-
- for (i = 0; i < 200000; i++) {
- isr = kw_read_reg(reg_isr) & KW_I2C_IRQ_MASK;
- if (isr != 0)
- return isr;
- udelay(1);
- }
- return isr;
-}
-
-static int kw_handle_interrupt(struct low_i2c_host *host, int state, int rw, int *rc, u8 **data, int *len, u8 isr)
-{
- u8 ack;
-
- if (isr == 0) {
- if (state != state_stop) {
- DBG("KW: Timeout !\n");
- *rc = -EIO;
- goto stop;
- }
- if (state == state_stop) {
- ack = kw_read_reg(reg_status);
- if (!(ack & KW_I2C_STAT_BUSY)) {
- state = state_idle;
- kw_write_reg(reg_ier, 0x00);
- }
- }
- return state;
- }
-
- if (isr & KW_I2C_IRQ_ADDR) {
- ack = kw_read_reg(reg_status);
- if (state != state_addr) {
- kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR);
- WRONG_STATE("KW_I2C_IRQ_ADDR");
- *rc = -EIO;
- goto stop;
- }
- if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {
- *rc = -ENODEV;
- DBG("KW: NAK on address\n");
- return state_stop;
- } else {
- if (rw) {
- state = state_read;
- if (*len > 1)
- kw_write_reg(reg_control, KW_I2C_CTL_AAK);
- } else {
- state = state_write;
- kw_write_reg(reg_data, **data);
- (*data)++; (*len)--;
- }
- }
- kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR);
- }
-
- if (isr & KW_I2C_IRQ_DATA) {
- if (state == state_read) {
- **data = kw_read_reg(reg_data);
- (*data)++; (*len)--;
- kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
- if ((*len) == 0)
- state = state_stop;
- else if ((*len) == 1)
- kw_write_reg(reg_control, 0);
- } else if (state == state_write) {
- ack = kw_read_reg(reg_status);
- if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {
- DBG("KW: nack on data write\n");
- *rc = -EIO;
- goto stop;
- } else if (*len) {
- kw_write_reg(reg_data, **data);
- (*data)++; (*len)--;
- } else {
- kw_write_reg(reg_control, KW_I2C_CTL_STOP);
- state = state_stop;
- *rc = 0;
- }
- kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
- } else {
- kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
- WRONG_STATE("KW_I2C_IRQ_DATA");
- if (state != state_stop) {
- *rc = -EIO;
- goto stop;
- }
- }
- }
-
- if (isr & KW_I2C_IRQ_STOP) {
- kw_write_reg(reg_isr, KW_I2C_IRQ_STOP);
- if (state != state_stop) {
- WRONG_STATE("KW_I2C_IRQ_STOP");
- *rc = -EIO;
- }
- return state_idle;
- }
-
- if (isr & KW_I2C_IRQ_START)
- kw_write_reg(reg_isr, KW_I2C_IRQ_START);
-
- return state;
-
- stop:
- kw_write_reg(reg_control, KW_I2C_CTL_STOP);
- return state_stop;
-}
-
-static int keywest_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 subaddr, u8 *data, int len)
-{
- u8 mode_reg = host->speed;
- int state = state_addr;
- int rc = 0;
-
- /* Setup mode & subaddress if any */
- switch(host->mode) {
- case pmac_low_i2c_mode_dumb:
- printk(KERN_ERR "low_i2c: Dumb mode not supported !\n");
- return -EINVAL;
- case pmac_low_i2c_mode_std:
- mode_reg |= KW_I2C_MODE_STANDARD;
- break;
- case pmac_low_i2c_mode_stdsub:
- mode_reg |= KW_I2C_MODE_STANDARDSUB;
- kw_write_reg(reg_subaddr, subaddr);
- break;
- case pmac_low_i2c_mode_combined:
- mode_reg |= KW_I2C_MODE_COMBINED;
- kw_write_reg(reg_subaddr, subaddr);
- break;
- }
-
- /* Setup channel & clear pending irqs */
- kw_write_reg(reg_isr, kw_read_reg(reg_isr));
- kw_write_reg(reg_mode, mode_reg | (host->channel << 4));
- kw_write_reg(reg_status, 0);
-
- /* Set up address and r/w bit */
- kw_write_reg(reg_addr, addr);
-
- /* Start sending address & disable interrupt*/
- kw_write_reg(reg_ier, 0 /*KW_I2C_IRQ_MASK*/);
- kw_write_reg(reg_control, KW_I2C_CTL_XADDR);
-
- /* State machine, to turn into an interrupt handler */
- while(state != state_idle) {
- u8 isr = kw_wait_interrupt(host);
- state = kw_handle_interrupt(host, state, addr & 1, &rc, &data, &len, isr);
- }
-
- return rc;
-}
-
-static void keywest_low_i2c_add(struct device_node *np)
-{
- struct low_i2c_host *host = find_low_i2c_host(NULL);
- unsigned long *psteps, *prate, steps, aoffset = 0;
- struct device_node *parent;
-
- if (host == NULL) {
- printk(KERN_ERR "low_i2c: Can't allocate host for %s\n",
- np->full_name);
- return;
- }
- memset(host, 0, sizeof(*host));
-
- init_MUTEX(&host->mutex);
- host->np = of_node_get(np);
- psteps = (unsigned long *)get_property(np, "AAPL,address-step", NULL);
- steps = psteps ? (*psteps) : 0x10;
- for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++)
- steps >>= 1;
- parent = of_get_parent(np);
- host->num_channels = 1;
- if (parent && parent->name[0] == 'u') {
- host->num_channels = 2;
- aoffset = 3;
- }
- /* Select interface rate */
- host->speed = KW_I2C_MODE_100KHZ;
- prate = (unsigned long *)get_property(np, "AAPL,i2c-rate", NULL);
- if (prate) switch(*prate) {
- case 100:
- host->speed = KW_I2C_MODE_100KHZ;
- break;
- case 50:
- host->speed = KW_I2C_MODE_50KHZ;
- break;
- case 25:
- host->speed = KW_I2C_MODE_25KHZ;
- break;
- }
- host->mode = pmac_low_i2c_mode_std;
- host->base = ioremap(np->addrs[0].address + aoffset,
- np->addrs[0].size);
- host->func = keywest_low_i2c_func;
-}
-
-/*
- *
- * PMU implementation
- *
- */
-
-
-#ifdef CONFIG_ADB_PMU
-
-static int pmu_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len)
-{
- // TODO
- return -ENODEV;
-}
-
-static void pmu_low_i2c_add(struct device_node *np)
-{
- struct low_i2c_host *host = find_low_i2c_host(NULL);
-
- if (host == NULL) {
- printk(KERN_ERR "low_i2c: Can't allocate host for %s\n",
- np->full_name);
- return;
- }
- memset(host, 0, sizeof(*host));
-
- init_MUTEX(&host->mutex);
- host->np = of_node_get(np);
- host->num_channels = 3;
- host->mode = pmac_low_i2c_mode_std;
- host->func = pmu_low_i2c_func;
-}
-
-#endif /* CONFIG_ADB_PMU */
-
-void __init pmac_init_low_i2c(void)
-{
- struct device_node *np;
-
- /* Probe keywest-i2c busses */
- np = of_find_compatible_node(NULL, "i2c", "keywest-i2c");
- while(np) {
- keywest_low_i2c_add(np);
- np = of_find_compatible_node(np, "i2c", "keywest-i2c");
- }
-
-#ifdef CONFIG_ADB_PMU
- /* Probe PMU busses */
- np = of_find_node_by_name(NULL, "via-pmu");
- if (np)
- pmu_low_i2c_add(np);
-#endif /* CONFIG_ADB_PMU */
-
- /* TODO: Add CUDA support as well */
-}
-
-int pmac_low_i2c_lock(struct device_node *np)
-{
- struct low_i2c_host *host = find_low_i2c_host(np);
-
- if (!host)
- return -ENODEV;
- down(&host->mutex);
- return 0;
-}
-EXPORT_SYMBOL(pmac_low_i2c_lock);
-
-int pmac_low_i2c_unlock(struct device_node *np)
-{
- struct low_i2c_host *host = find_low_i2c_host(np);
-
- if (!host)
- return -ENODEV;
- up(&host->mutex);
- return 0;
-}
-EXPORT_SYMBOL(pmac_low_i2c_unlock);
-
-
-int pmac_low_i2c_open(struct device_node *np, int channel)
-{
- struct low_i2c_host *host = find_low_i2c_host(np);
-
- if (!host)
- return -ENODEV;
-
- if (channel >= host->num_channels)
- return -EINVAL;
-
- down(&host->mutex);
- host->is_open = 1;
- host->channel = channel;
-
- return 0;
-}
-EXPORT_SYMBOL(pmac_low_i2c_open);
-
-int pmac_low_i2c_close(struct device_node *np)
-{
- struct low_i2c_host *host = find_low_i2c_host(np);
-
- if (!host)
- return -ENODEV;
-
- host->is_open = 0;
- up(&host->mutex);
-
- return 0;
-}
-EXPORT_SYMBOL(pmac_low_i2c_close);
-
-int pmac_low_i2c_setmode(struct device_node *np, int mode)
-{
- struct low_i2c_host *host = find_low_i2c_host(np);
-
- if (!host)
- return -ENODEV;
- WARN_ON(!host->is_open);
- host->mode = mode;
-
- return 0;
-}
-EXPORT_SYMBOL(pmac_low_i2c_setmode);
-
-int pmac_low_i2c_xfer(struct device_node *np, u8 addrdir, u8 subaddr, u8 *data, int len)
-{
- struct low_i2c_host *host = find_low_i2c_host(np);
-
- if (!host)
- return -ENODEV;
- WARN_ON(!host->is_open);
-
- return host->func(host, addrdir, subaddr, data, len);
-}
-EXPORT_SYMBOL(pmac_low_i2c_xfer);
-
diff --git a/arch/ppc/platforms/pmac_nvram.c b/arch/ppc/platforms/pmac_nvram.c
deleted file mode 100644
index 8c9b008..0000000
--- a/arch/ppc/platforms/pmac_nvram.c
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- * arch/ppc/platforms/pmac_nvram.c
- *
- * Copyright (C) 2002 Benjamin Herrenschmidt (benh@kernel.crashing.org)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Todo: - add support for the OF persistent properties
- */
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/stddef.h>
-#include <linux/string.h>
-#include <linux/nvram.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#include <linux/bootmem.h>
-#include <linux/completion.h>
-#include <linux/spinlock.h>
-#include <asm/sections.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/nvram.h>
-
-#define DEBUG
-
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-#define NVRAM_SIZE 0x2000 /* 8kB of non-volatile RAM */
-
-#define CORE99_SIGNATURE 0x5a
-#define CORE99_ADLER_START 0x14
-
-/* On Core99, nvram is either a sharp, a micron or an AMD flash */
-#define SM_FLASH_STATUS_DONE 0x80
-#define SM_FLASH_STATUS_ERR 0x38
-#define SM_FLASH_CMD_ERASE_CONFIRM 0xd0
-#define SM_FLASH_CMD_ERASE_SETUP 0x20
-#define SM_FLASH_CMD_RESET 0xff
-#define SM_FLASH_CMD_WRITE_SETUP 0x40
-#define SM_FLASH_CMD_CLEAR_STATUS 0x50
-#define SM_FLASH_CMD_READ_STATUS 0x70
-
-/* CHRP NVRAM header */
-struct chrp_header {
- u8 signature;
- u8 cksum;
- u16 len;
- char name[12];
- u8 data[0];
-};
-
-struct core99_header {
- struct chrp_header hdr;
- u32 adler;
- u32 generation;
- u32 reserved[2];
-};
-
-/*
- * Read and write the non-volatile RAM on PowerMacs and CHRP machines.
- */
-static int nvram_naddrs;
-static volatile unsigned char *nvram_addr;
-static volatile unsigned char *nvram_data;
-static int nvram_mult, is_core_99;
-static int core99_bank = 0;
-static int nvram_partitions[3];
-static DEFINE_SPINLOCK(nv_lock);
-
-extern int pmac_newworld;
-extern int system_running;
-
-static int (*core99_write_bank)(int bank, u8* datas);
-static int (*core99_erase_bank)(int bank);
-
-static char *nvram_image;
-
-
-static unsigned char core99_nvram_read_byte(int addr)
-{
- if (nvram_image == NULL)
- return 0xff;
- return nvram_image[addr];
-}
-
-static void core99_nvram_write_byte(int addr, unsigned char val)
-{
- if (nvram_image == NULL)
- return;
- nvram_image[addr] = val;
-}
-
-
-static unsigned char direct_nvram_read_byte(int addr)
-{
- return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]);
-}
-
-static void direct_nvram_write_byte(int addr, unsigned char val)
-{
- out_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult], val);
-}
-
-
-static unsigned char indirect_nvram_read_byte(int addr)
-{
- unsigned char val;
- unsigned long flags;
-
- spin_lock_irqsave(&nv_lock, flags);
- out_8(nvram_addr, addr >> 5);
- val = in_8(&nvram_data[(addr & 0x1f) << 4]);
- spin_unlock_irqrestore(&nv_lock, flags);
-
- return val;
-}
-
-static void indirect_nvram_write_byte(int addr, unsigned char val)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&nv_lock, flags);
- out_8(nvram_addr, addr >> 5);
- out_8(&nvram_data[(addr & 0x1f) << 4], val);
- spin_unlock_irqrestore(&nv_lock, flags);
-}
-
-
-#ifdef CONFIG_ADB_PMU
-
-static void pmu_nvram_complete(struct adb_request *req)
-{
- if (req->arg)
- complete((struct completion *)req->arg);
-}
-
-static unsigned char pmu_nvram_read_byte(int addr)
-{
- struct adb_request req;
- DECLARE_COMPLETION(req_complete);
-
- req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
- if (pmu_request(&req, pmu_nvram_complete, 3, PMU_READ_NVRAM,
- (addr >> 8) & 0xff, addr & 0xff))
- return 0xff;
- if (system_state == SYSTEM_RUNNING)
- wait_for_completion(&req_complete);
- while (!req.complete)
- pmu_poll();
- return req.reply[0];
-}
-
-static void pmu_nvram_write_byte(int addr, unsigned char val)
-{
- struct adb_request req;
- DECLARE_COMPLETION(req_complete);
-
- req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
- if (pmu_request(&req, pmu_nvram_complete, 4, PMU_WRITE_NVRAM,
- (addr >> 8) & 0xff, addr & 0xff, val))
- return;
- if (system_state == SYSTEM_RUNNING)
- wait_for_completion(&req_complete);
- while (!req.complete)
- pmu_poll();
-}
-
-#endif /* CONFIG_ADB_PMU */
-
-
-static u8 chrp_checksum(struct chrp_header* hdr)
-{
- u8 *ptr;
- u16 sum = hdr->signature;
- for (ptr = (u8 *)&hdr->len; ptr < hdr->data; ptr++)
- sum += *ptr;
- while (sum > 0xFF)
- sum = (sum & 0xFF) + (sum>>8);
- return sum;
-}
-
-static u32 core99_calc_adler(u8 *buffer)
-{
- int cnt;
- u32 low, high;
-
- buffer += CORE99_ADLER_START;
- low = 1;
- high = 0;
- for (cnt=0; cnt<(NVRAM_SIZE-CORE99_ADLER_START); cnt++) {
- if ((cnt % 5000) == 0) {
- high %= 65521UL;
- high %= 65521UL;
- }
- low += buffer[cnt];
- high += low;
- }
- low %= 65521UL;
- high %= 65521UL;
-
- return (high << 16) | low;
-}
-
-static u32 core99_check(u8* datas)
-{
- struct core99_header* hdr99 = (struct core99_header*)datas;
-
- if (hdr99->hdr.signature != CORE99_SIGNATURE) {
- DBG("Invalid signature\n");
- return 0;
- }
- if (hdr99->hdr.cksum != chrp_checksum(&hdr99->hdr)) {
- DBG("Invalid checksum\n");
- return 0;
- }
- if (hdr99->adler != core99_calc_adler(datas)) {
- DBG("Invalid adler\n");
- return 0;
- }
- return hdr99->generation;
-}
-
-static int sm_erase_bank(int bank)
-{
- int stat, i;
- unsigned long timeout;
-
- u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
-
- DBG("nvram: Sharp/Micron Erasing bank %d...\n", bank);
-
- out_8(base, SM_FLASH_CMD_ERASE_SETUP);
- out_8(base, SM_FLASH_CMD_ERASE_CONFIRM);
- timeout = 0;
- do {
- if (++timeout > 1000000) {
- printk(KERN_ERR "nvram: Sharp/Miron flash erase timeout !\n");
- break;
- }
- out_8(base, SM_FLASH_CMD_READ_STATUS);
- stat = in_8(base);
- } while (!(stat & SM_FLASH_STATUS_DONE));
-
- out_8(base, SM_FLASH_CMD_CLEAR_STATUS);
- out_8(base, SM_FLASH_CMD_RESET);
-
- for (i=0; i<NVRAM_SIZE; i++)
- if (base[i] != 0xff) {
- printk(KERN_ERR "nvram: Sharp/Micron flash erase failed !\n");
- return -ENXIO;
- }
- return 0;
-}
-
-static int sm_write_bank(int bank, u8* datas)
-{
- int i, stat = 0;
- unsigned long timeout;
-
- u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
-
- DBG("nvram: Sharp/Micron Writing bank %d...\n", bank);
-
- for (i=0; i<NVRAM_SIZE; i++) {
- out_8(base+i, SM_FLASH_CMD_WRITE_SETUP);
- udelay(1);
- out_8(base+i, datas[i]);
- timeout = 0;
- do {
- if (++timeout > 1000000) {
- printk(KERN_ERR "nvram: Sharp/Micron flash write timeout !\n");
- break;
- }
- out_8(base, SM_FLASH_CMD_READ_STATUS);
- stat = in_8(base);
- } while (!(stat & SM_FLASH_STATUS_DONE));
- if (!(stat & SM_FLASH_STATUS_DONE))
- break;
- }
- out_8(base, SM_FLASH_CMD_CLEAR_STATUS);
- out_8(base, SM_FLASH_CMD_RESET);
- for (i=0; i<NVRAM_SIZE; i++)
- if (base[i] != datas[i]) {
- printk(KERN_ERR "nvram: Sharp/Micron flash write failed !\n");
- return -ENXIO;
- }
- return 0;
-}
-
-static int amd_erase_bank(int bank)
-{
- int i, stat = 0;
- unsigned long timeout;
-
- u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
-
- DBG("nvram: AMD Erasing bank %d...\n", bank);
-
- /* Unlock 1 */
- out_8(base+0x555, 0xaa);
- udelay(1);
- /* Unlock 2 */
- out_8(base+0x2aa, 0x55);
- udelay(1);
-
- /* Sector-Erase */
- out_8(base+0x555, 0x80);
- udelay(1);
- out_8(base+0x555, 0xaa);
- udelay(1);
- out_8(base+0x2aa, 0x55);
- udelay(1);
- out_8(base, 0x30);
- udelay(1);
-
- timeout = 0;
- do {
- if (++timeout > 1000000) {
- printk(KERN_ERR "nvram: AMD flash erase timeout !\n");
- break;
- }
- stat = in_8(base) ^ in_8(base);
- } while (stat != 0);
-
- /* Reset */
- out_8(base, 0xf0);
- udelay(1);
-
- for (i=0; i<NVRAM_SIZE; i++)
- if (base[i] != 0xff) {
- printk(KERN_ERR "nvram: AMD flash erase failed !\n");
- return -ENXIO;
- }
- return 0;
-}
-
-static int amd_write_bank(int bank, u8* datas)
-{
- int i, stat = 0;
- unsigned long timeout;
-
- u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
-
- DBG("nvram: AMD Writing bank %d...\n", bank);
-
- for (i=0; i<NVRAM_SIZE; i++) {
- /* Unlock 1 */
- out_8(base+0x555, 0xaa);
- udelay(1);
- /* Unlock 2 */
- out_8(base+0x2aa, 0x55);
- udelay(1);
-
- /* Write single word */
- out_8(base+0x555, 0xa0);
- udelay(1);
- out_8(base+i, datas[i]);
-
- timeout = 0;
- do {
- if (++timeout > 1000000) {
- printk(KERN_ERR "nvram: AMD flash write timeout !\n");
- break;
- }
- stat = in_8(base) ^ in_8(base);
- } while (stat != 0);
- if (stat != 0)
- break;
- }
-
- /* Reset */
- out_8(base, 0xf0);
- udelay(1);
-
- for (i=0; i<NVRAM_SIZE; i++)
- if (base[i] != datas[i]) {
- printk(KERN_ERR "nvram: AMD flash write failed !\n");
- return -ENXIO;
- }
- return 0;
-}
-
-static void __init lookup_partitions(void)
-{
- u8 buffer[17];
- int i, offset;
- struct chrp_header* hdr;
-
- if (pmac_newworld) {
- nvram_partitions[pmac_nvram_OF] = -1;
- nvram_partitions[pmac_nvram_XPRAM] = -1;
- nvram_partitions[pmac_nvram_NR] = -1;
- hdr = (struct chrp_header *)buffer;
-
- offset = 0;
- buffer[16] = 0;
- do {
- for (i=0;i<16;i++)
- buffer[i] = nvram_read_byte(offset+i);
- if (!strcmp(hdr->name, "common"))
- nvram_partitions[pmac_nvram_OF] = offset + 0x10;
- if (!strcmp(hdr->name, "APL,MacOS75")) {
- nvram_partitions[pmac_nvram_XPRAM] = offset + 0x10;
- nvram_partitions[pmac_nvram_NR] = offset + 0x110;
- }
- offset += (hdr->len * 0x10);
- } while(offset < NVRAM_SIZE);
- } else {
- nvram_partitions[pmac_nvram_OF] = 0x1800;
- nvram_partitions[pmac_nvram_XPRAM] = 0x1300;
- nvram_partitions[pmac_nvram_NR] = 0x1400;
- }
- DBG("nvram: OF partition at 0x%x\n", nvram_partitions[pmac_nvram_OF]);
- DBG("nvram: XP partition at 0x%x\n", nvram_partitions[pmac_nvram_XPRAM]);
- DBG("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]);
-}
-
-static void core99_nvram_sync(void)
-{
- struct core99_header* hdr99;
- unsigned long flags;
-
- if (!is_core_99 || !nvram_data || !nvram_image)
- return;
-
- spin_lock_irqsave(&nv_lock, flags);
- if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE,
- NVRAM_SIZE))
- goto bail;
-
- DBG("Updating nvram...\n");
-
- hdr99 = (struct core99_header*)nvram_image;
- hdr99->generation++;
- hdr99->hdr.signature = CORE99_SIGNATURE;
- hdr99->hdr.cksum = chrp_checksum(&hdr99->hdr);
- hdr99->adler = core99_calc_adler(nvram_image);
- core99_bank = core99_bank ? 0 : 1;
- if (core99_erase_bank)
- if (core99_erase_bank(core99_bank)) {
- printk("nvram: Error erasing bank %d\n", core99_bank);
- goto bail;
- }
- if (core99_write_bank)
- if (core99_write_bank(core99_bank, nvram_image))
- printk("nvram: Error writing bank %d\n", core99_bank);
- bail:
- spin_unlock_irqrestore(&nv_lock, flags);
-
-#ifdef DEBUG
- mdelay(2000);
-#endif
-}
-
-void __init pmac_nvram_init(void)
-{
- struct device_node *dp;
-
- nvram_naddrs = 0;
-
- dp = find_devices("nvram");
- if (dp == NULL) {
- printk(KERN_ERR "Can't find NVRAM device\n");
- return;
- }
- nvram_naddrs = dp->n_addrs;
- is_core_99 = device_is_compatible(dp, "nvram,flash");
- if (is_core_99) {
- int i;
- u32 gen_bank0, gen_bank1;
-
- if (nvram_naddrs < 1) {
- printk(KERN_ERR "nvram: no address\n");
- return;
- }
- nvram_image = alloc_bootmem(NVRAM_SIZE);
- if (nvram_image == NULL) {
- printk(KERN_ERR "nvram: can't allocate ram image\n");
- return;
- }
- nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2);
- nvram_naddrs = 1; /* Make sure we get the correct case */
-
- DBG("nvram: Checking bank 0...\n");
-
- gen_bank0 = core99_check((u8 *)nvram_data);
- gen_bank1 = core99_check((u8 *)nvram_data + NVRAM_SIZE);
- core99_bank = (gen_bank0 < gen_bank1) ? 1 : 0;
-
- DBG("nvram: gen0=%d, gen1=%d\n", gen_bank0, gen_bank1);
- DBG("nvram: Active bank is: %d\n", core99_bank);
-
- for (i=0; i<NVRAM_SIZE; i++)
- nvram_image[i] = nvram_data[i + core99_bank*NVRAM_SIZE];
-
- ppc_md.nvram_read_val = core99_nvram_read_byte;
- ppc_md.nvram_write_val = core99_nvram_write_byte;
- ppc_md.nvram_sync = core99_nvram_sync;
- /*
- * Maybe we could be smarter here though making an exclusive list
- * of known flash chips is a bit nasty as older OF didn't provide us
- * with a useful "compatible" entry. A solution would be to really
- * identify the chip using flash id commands and base ourselves on
- * a list of known chips IDs
- */
- if (device_is_compatible(dp, "amd-0137")) {
- core99_erase_bank = amd_erase_bank;
- core99_write_bank = amd_write_bank;
- } else {
- core99_erase_bank = sm_erase_bank;
- core99_write_bank = sm_write_bank;
- }
- } else if (_machine == _MACH_chrp && nvram_naddrs == 1) {
- nvram_data = ioremap(dp->addrs[0].address + isa_mem_base,
- dp->addrs[0].size);
- nvram_mult = 1;
- ppc_md.nvram_read_val = direct_nvram_read_byte;
- ppc_md.nvram_write_val = direct_nvram_write_byte;
- } else if (nvram_naddrs == 1) {
- nvram_data = ioremap(dp->addrs[0].address, dp->addrs[0].size);
- nvram_mult = (dp->addrs[0].size + NVRAM_SIZE - 1) / NVRAM_SIZE;
- ppc_md.nvram_read_val = direct_nvram_read_byte;
- ppc_md.nvram_write_val = direct_nvram_write_byte;
- } else if (nvram_naddrs == 2) {
- nvram_addr = ioremap(dp->addrs[0].address, dp->addrs[0].size);
- nvram_data = ioremap(dp->addrs[1].address, dp->addrs[1].size);
- ppc_md.nvram_read_val = indirect_nvram_read_byte;
- ppc_md.nvram_write_val = indirect_nvram_write_byte;
- } else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) {
-#ifdef CONFIG_ADB_PMU
- nvram_naddrs = -1;
- ppc_md.nvram_read_val = pmu_nvram_read_byte;
- ppc_md.nvram_write_val = pmu_nvram_write_byte;
-#endif /* CONFIG_ADB_PMU */
- } else {
- printk(KERN_ERR "Don't know how to access NVRAM with %d addresses\n",
- nvram_naddrs);
- }
- lookup_partitions();
-}
-
-int pmac_get_partition(int partition)
-{
- return nvram_partitions[partition];
-}
-
-u8 pmac_xpram_read(int xpaddr)
-{
- int offset = nvram_partitions[pmac_nvram_XPRAM];
-
- if (offset < 0)
- return 0xff;
-
- return ppc_md.nvram_read_val(xpaddr + offset);
-}
-
-void pmac_xpram_write(int xpaddr, u8 data)
-{
- int offset = nvram_partitions[pmac_nvram_XPRAM];
-
- if (offset < 0)
- return;
-
- ppc_md.nvram_write_val(xpaddr + offset, data);
-}
-
-EXPORT_SYMBOL(pmac_get_partition);
-EXPORT_SYMBOL(pmac_xpram_read);
-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 786295b..0000000
--- a/arch/ppc/platforms/pmac_pci.c
+++ /dev/null
@@ -1,1124 +0,0 @@
-/*
- * Support for PCI bridges found on Power Macintoshes.
- * At present the "bandit" and "chaos" bridges are supported.
- * Fortunately you access configuration space in the same
- * way with either bridge.
- *
- * Copyright (C) 1997 Paul Mackerras (paulus@cs.anu.edu.au)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/init.h>
-
-#include <asm/sections.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-
-#undef DEBUG
-
-#ifdef DEBUG
-#ifdef CONFIG_XMON
-extern void xmon_printf(const char *fmt, ...);
-#define DBG(x...) xmon_printf(x)
-#else
-#define DBG(x...) printk(x)
-#endif
-#else
-#define DBG(x...)
-#endif
-
-static int add_bridge(struct device_node *dev);
-extern void pmac_check_ht_link(void);
-
-/* XXX Could be per-controller, but I don't think we risk anything by
- * assuming we won't have both UniNorth and Bandit */
-static int has_uninorth;
-#ifdef CONFIG_POWER4
-static struct pci_controller *u3_agp;
-#endif /* CONFIG_POWER4 */
-
-extern u8 pci_cache_line_size;
-extern int pcibios_assign_bus_offset;
-
-struct device_node *k2_skiplist[2];
-
-/*
- * Magic constants for enabling cache coherency in the bandit/PSX bridge.
- */
-#define BANDIT_DEVID_2 8
-#define BANDIT_REVID 3
-
-#define BANDIT_DEVNUM 11
-#define BANDIT_MAGIC 0x50
-#define BANDIT_COHERENT 0x40
-
-static int __init
-fixup_one_level_bus_range(struct device_node *node, int higher)
-{
- for (; node != 0;node = node->sibling) {
- int * bus_range;
- unsigned int *class_code;
- int len;
-
- /* For PCI<->PCI bridges or CardBus bridges, we go down */
- class_code = (unsigned int *) get_property(node, "class-code", NULL);
- if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
- (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
- continue;
- bus_range = (int *) get_property(node, "bus-range", &len);
- if (bus_range != NULL && len > 2 * sizeof(int)) {
- if (bus_range[1] > higher)
- higher = bus_range[1];
- }
- higher = fixup_one_level_bus_range(node->child, higher);
- }
- return higher;
-}
-
-/* This routine fixes the "bus-range" property of all bridges in the
- * system since they tend to have their "last" member wrong on macs
- *
- * Note that the bus numbers manipulated here are OF bus numbers, they
- * are not Linux bus numbers.
- */
-static void __init
-fixup_bus_range(struct device_node *bridge)
-{
- int * bus_range;
- int len;
-
- /* Lookup the "bus-range" property for the hose */
- bus_range = (int *) get_property(bridge, "bus-range", &len);
- if (bus_range == NULL || len < 2 * sizeof(int)) {
- printk(KERN_WARNING "Can't get bus-range for %s\n",
- bridge->full_name);
- return;
- }
- bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
-}
-
-/*
- * Apple MacRISC (U3, UniNorth, Bandit, Chaos) PCI controllers.
- *
- * The "Bandit" version is present in all early PCI PowerMacs,
- * and up to the first ones using Grackle. Some machines may
- * have 2 bandit controllers (2 PCI busses).
- *
- * "Chaos" is used in some "Bandit"-type machines as a bridge
- * for the separate display bus. It is accessed the same
- * way as bandit, but cannot be probed for devices. It therefore
- * has its own config access functions.
- *
- * The "UniNorth" version is present in all Core99 machines
- * (iBook, G4, new IMacs, and all the recent Apple machines).
- * It contains 3 controllers in one ASIC.
- *
- * The U3 is the bridge used on G5 machines. It contains an
- * AGP bus which is dealt with the old UniNorth access routines
- * and a HyperTransport bus which uses its own set of access
- * functions.
- */
-
-#define MACRISC_CFA0(devfn, off) \
- ((1 << (unsigned long)PCI_SLOT(dev_fn)) \
- | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \
- | (((unsigned long)(off)) & 0xFCUL))
-
-#define MACRISC_CFA1(bus, devfn, off) \
- ((((unsigned long)(bus)) << 16) \
- |(((unsigned long)(devfn)) << 8) \
- |(((unsigned long)(off)) & 0xFCUL) \
- |1UL)
-
-static void volatile __iomem *
-macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset)
-{
- unsigned int caddr;
-
- if (bus == hose->first_busno) {
- if (dev_fn < (11 << 3))
- return NULL;
- caddr = MACRISC_CFA0(dev_fn, offset);
- } else
- caddr = MACRISC_CFA1(bus, dev_fn, offset);
-
- /* Uninorth will return garbage if we don't read back the value ! */
- do {
- out_le32(hose->cfg_addr, caddr);
- } while (in_le32(hose->cfg_addr) != caddr);
-
- offset &= has_uninorth ? 0x07 : 0x03;
- return hose->cfg_data + offset;
-}
-
-static int
-macrisc_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
- int len, u32 *val)
-{
- struct pci_controller *hose = bus->sysdata;
- void volatile __iomem *addr;
-
- addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- *val = in_8(addr);
- break;
- case 2:
- *val = in_le16(addr);
- break;
- default:
- *val = in_le32(addr);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-macrisc_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
- int len, u32 val)
-{
- struct pci_controller *hose = bus->sysdata;
- void volatile __iomem *addr;
-
- addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- out_8(addr, val);
- (void) in_8(addr);
- break;
- case 2:
- out_le16(addr, val);
- (void) in_le16(addr);
- break;
- default:
- out_le32(addr, val);
- (void) in_le32(addr);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops macrisc_pci_ops =
-{
- macrisc_read_config,
- macrisc_write_config
-};
-
-/*
- * Verifiy that a specific (bus, dev_fn) exists on chaos
- */
-static int
-chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
-{
- struct device_node *np;
- u32 *vendor, *device;
-
- np = pci_busdev_to_OF_node(bus, devfn);
- if (np == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- vendor = (u32 *)get_property(np, "vendor-id", NULL);
- device = (u32 *)get_property(np, "device-id", NULL);
- if (vendor == NULL || device == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- if ((*vendor == 0x106b) && (*device == 3) && (offset >= 0x10)
- && (offset != 0x14) && (offset != 0x18) && (offset <= 0x24))
- return PCIBIOS_BAD_REGISTER_NUMBER;
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
- int len, u32 *val)
-{
- int result = chaos_validate_dev(bus, devfn, offset);
- if (result == PCIBIOS_BAD_REGISTER_NUMBER)
- *val = ~0U;
- if (result != PCIBIOS_SUCCESSFUL)
- return result;
- return macrisc_read_config(bus, devfn, offset, len, val);
-}
-
-static int
-chaos_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
- int len, u32 val)
-{
- int result = chaos_validate_dev(bus, devfn, offset);
- if (result != PCIBIOS_SUCCESSFUL)
- return result;
- return macrisc_write_config(bus, devfn, offset, len, val);
-}
-
-static struct pci_ops chaos_pci_ops =
-{
- chaos_read_config,
- chaos_write_config
-};
-
-#ifdef CONFIG_POWER4
-
-/*
- * These versions of U3 HyperTransport config space access ops do not
- * implement self-view of the HT host yet
- */
-
-#define U3_HT_CFA0(devfn, off) \
- ((((unsigned long)devfn) << 8) | offset)
-#define U3_HT_CFA1(bus, devfn, off) \
- (U3_HT_CFA0(devfn, off) \
- + (((unsigned long)bus) << 16) \
- + 0x01000000UL)
-
-static void volatile __iomem *
-u3_ht_cfg_access(struct pci_controller* hose, u8 bus, u8 devfn, u8 offset)
-{
- if (bus == hose->first_busno) {
- /* For now, we don't self probe U3 HT bridge */
- if (PCI_FUNC(devfn) != 0 || PCI_SLOT(devfn) > 7 ||
- PCI_SLOT(devfn) < 1)
- return 0;
- return hose->cfg_data + U3_HT_CFA0(devfn, offset);
- } else
- return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset);
-}
-
-static int
-u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
- int len, u32 *val)
-{
- struct pci_controller *hose = bus->sysdata;
- void volatile __iomem *addr;
- int i;
-
- struct device_node *np = pci_busdev_to_OF_node(bus, devfn);
- if (np == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- /*
- * When a device in K2 is powered down, we die on config
- * cycle accesses. Fix that here.
- */
- for (i=0; i<2; i++)
- if (k2_skiplist[i] == np) {
- switch (len) {
- case 1:
- *val = 0xff; break;
- case 2:
- *val = 0xffff; break;
- default:
- *val = 0xfffffffful; break;
- }
- return PCIBIOS_SUCCESSFUL;
- }
-
- addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- *val = in_8(addr);
- break;
- case 2:
- *val = in_le16(addr);
- break;
- default:
- *val = in_le32(addr);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
- int len, u32 val)
-{
- struct pci_controller *hose = bus->sysdata;
- void volatile __iomem *addr;
- int i;
-
- struct device_node *np = pci_busdev_to_OF_node(bus, devfn);
- if (np == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * When a device in K2 is powered down, we die on config
- * cycle accesses. Fix that here.
- */
- for (i=0; i<2; i++)
- if (k2_skiplist[i] == np)
- return PCIBIOS_SUCCESSFUL;
-
- addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- out_8(addr, val);
- (void) in_8(addr);
- break;
- case 2:
- out_le16(addr, val);
- (void) in_le16(addr);
- break;
- default:
- out_le32(addr, val);
- (void) in_le32(addr);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops u3_ht_pci_ops =
-{
- u3_ht_read_config,
- u3_ht_write_config
-};
-
-#endif /* CONFIG_POWER4 */
-
-/*
- * For a bandit bridge, turn on cache coherency if necessary.
- * N.B. we could clean this up using the hose ops directly.
- */
-static void __init
-init_bandit(struct pci_controller *bp)
-{
- unsigned int vendev, magic;
- int rev;
-
- /* read the word at offset 0 in config space for device 11 */
- out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + PCI_VENDOR_ID);
- udelay(2);
- vendev = in_le32(bp->cfg_data);
- if (vendev == (PCI_DEVICE_ID_APPLE_BANDIT << 16) +
- PCI_VENDOR_ID_APPLE) {
- /* read the revision id */
- out_le32(bp->cfg_addr,
- (1UL << BANDIT_DEVNUM) + PCI_REVISION_ID);
- udelay(2);
- rev = in_8(bp->cfg_data);
- if (rev != BANDIT_REVID)
- printk(KERN_WARNING
- "Unknown revision %d for bandit\n", rev);
- } else if (vendev != (BANDIT_DEVID_2 << 16) + PCI_VENDOR_ID_APPLE) {
- printk(KERN_WARNING "bandit isn't? (%x)\n", vendev);
- return;
- }
-
- /* read the word at offset 0x50 */
- out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + BANDIT_MAGIC);
- udelay(2);
- magic = in_le32(bp->cfg_data);
- if ((magic & BANDIT_COHERENT) != 0)
- return;
- magic |= BANDIT_COHERENT;
- udelay(2);
- out_le32(bp->cfg_data, magic);
- printk(KERN_INFO "Cache coherency enabled for bandit/PSX\n");
-}
-
-
-/*
- * Tweak the PCI-PCI bridge chip on the blue & white G3s.
- */
-static void __init
-init_p2pbridge(void)
-{
- struct device_node *p2pbridge;
- struct pci_controller* hose;
- u8 bus, devfn;
- u16 val;
-
- /* XXX it would be better here to identify the specific
- PCI-PCI bridge chip we have. */
- if ((p2pbridge = find_devices("pci-bridge")) == 0
- || p2pbridge->parent == NULL
- || strcmp(p2pbridge->parent->name, "pci") != 0)
- return;
- if (pci_device_from_OF_node(p2pbridge, &bus, &devfn) < 0) {
- DBG("Can't find PCI infos for PCI<->PCI bridge\n");
- return;
- }
- /* Warning: At this point, we have not yet renumbered all busses.
- * So we must use OF walking to find out hose
- */
- hose = pci_find_hose_for_OF_device(p2pbridge);
- if (!hose) {
- DBG("Can't find hose for PCI<->PCI bridge\n");
- return;
- }
- if (early_read_config_word(hose, bus, devfn,
- PCI_BRIDGE_CONTROL, &val) < 0) {
- printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n");
- return;
- }
- val &= ~PCI_BRIDGE_CTL_MASTER_ABORT;
- early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val);
-}
-
-/*
- * Some Apple desktop machines have a NEC PD720100A USB2 controller
- * on the motherboard. Open Firmware, on these, will disable the
- * EHCI part of it so it behaves like a pair of OHCI's. This fixup
- * code re-enables it ;)
- */
-static void __init
-fixup_nec_usb2(void)
-{
- struct device_node *nec;
-
- for (nec = NULL; (nec = of_find_node_by_name(nec, "usb")) != NULL;) {
- struct pci_controller *hose;
- u32 data, *prop;
- u8 bus, devfn;
-
- prop = (u32 *)get_property(nec, "vendor-id", NULL);
- if (prop == NULL)
- continue;
- if (0x1033 != *prop)
- continue;
- prop = (u32 *)get_property(nec, "device-id", NULL);
- if (prop == NULL)
- continue;
- if (0x0035 != *prop)
- continue;
- prop = (u32 *)get_property(nec, "reg", NULL);
- if (prop == NULL)
- continue;
- devfn = (prop[0] >> 8) & 0xff;
- bus = (prop[0] >> 16) & 0xff;
- if (PCI_FUNC(devfn) != 0)
- continue;
- hose = pci_find_hose_for_OF_device(nec);
- if (!hose)
- continue;
- early_read_config_dword(hose, bus, devfn, 0xe4, &data);
- if (data & 1UL) {
- printk("Found NEC PD720100A USB2 chip with disabled EHCI, fixing up...\n");
- data &= ~1UL;
- early_write_config_dword(hose, bus, devfn, 0xe4, data);
- early_write_config_byte(hose, bus, devfn | 2, PCI_INTERRUPT_LINE,
- nec->intrs[0].line);
- }
- }
-}
-
-void __init
-pmac_find_bridges(void)
-{
- struct device_node *np, *root;
- struct device_node *ht = NULL;
-
- root = of_find_node_by_path("/");
- if (root == NULL) {
- printk(KERN_CRIT "pmac_find_bridges: can't find root of device tree\n");
- return;
- }
- for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) {
- if (np->name == NULL)
- continue;
- if (strcmp(np->name, "bandit") == 0
- || strcmp(np->name, "chaos") == 0
- || strcmp(np->name, "pci") == 0) {
- if (add_bridge(np) == 0)
- of_node_get(np);
- }
- if (strcmp(np->name, "ht") == 0) {
- of_node_get(np);
- ht = np;
- }
- }
- of_node_put(root);
-
- /* Probe HT last as it relies on the agp resources to be already
- * setup
- */
- if (ht && add_bridge(ht) != 0)
- of_node_put(ht);
-
- init_p2pbridge();
- fixup_nec_usb2();
-
- /* We are still having some issues with the Xserve G4, enabling
- * some offset between bus number and domains for now when we
- * assign all busses should help for now
- */
- if (pci_assign_all_buses)
- pcibios_assign_bus_offset = 0x10;
-
-#ifdef CONFIG_POWER4
- /* There is something wrong with DMA on U3/HT. I haven't figured out
- * the details yet, but if I set the cache line size to 128 bytes like
- * it should, I'm getting memory corruption caused by devices like
- * sungem (even without the MWI bit set, but maybe sungem doesn't
- * care). Right now, it appears that setting up a 64 bytes line size
- * works properly, 64 bytes beeing the max transfer size of HT, I
- * suppose this is related the way HT/PCI are hooked together. I still
- * need to dive into more specs though to be really sure of what's
- * going on. --BenH.
- *
- * Ok, apparently, it's just that HT can't do more than 64 bytes
- * transactions. MWI seem to be meaningless there as well, it may
- * be worth nop'ing out pci_set_mwi too though I haven't done that
- * yet.
- *
- * Note that it's a bit different for whatever is in the AGP slot.
- * For now, I don't care, but this can become a real issue, we
- * should probably hook pci_set_mwi anyway to make sure it sets
- * the real cache line size in there.
- */
- if (machine_is_compatible("MacRISC4"))
- pci_cache_line_size = 16; /* 64 bytes */
-
- pmac_check_ht_link();
-#endif /* CONFIG_POWER4 */
-}
-
-#define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \
- | (((o) & ~3) << 24))
-
-#define GRACKLE_PICR1_STG 0x00000040
-#define GRACKLE_PICR1_LOOPSNOOP 0x00000010
-
-/* N.B. this is called before bridges is initialized, so we can't
- use grackle_pcibios_{read,write}_config_dword. */
-static inline void grackle_set_stg(struct pci_controller* bp, int enable)
-{
- unsigned int val;
-
- out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
- val = in_le32(bp->cfg_data);
- val = enable? (val | GRACKLE_PICR1_STG) :
- (val & ~GRACKLE_PICR1_STG);
- out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
- out_le32(bp->cfg_data, val);
- (void)in_le32(bp->cfg_data);
-}
-
-static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable)
-{
- unsigned int val;
-
- out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
- val = in_le32(bp->cfg_data);
- val = enable? (val | GRACKLE_PICR1_LOOPSNOOP) :
- (val & ~GRACKLE_PICR1_LOOPSNOOP);
- out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
- out_le32(bp->cfg_data, val);
- (void)in_le32(bp->cfg_data);
-}
-
-static int __init
-setup_uninorth(struct pci_controller* hose, struct reg_property* addr)
-{
- pci_assign_all_buses = 1;
- has_uninorth = 1;
- hose->ops = ¯isc_pci_ops;
- hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
- hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
- /* We "know" that the bridge at f2000000 has the PCI slots. */
- return addr->address == 0xf2000000;
-}
-
-static void __init
-setup_bandit(struct pci_controller* hose, struct reg_property* addr)
-{
- hose->ops = ¯isc_pci_ops;
- hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
- hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
- init_bandit(hose);
-}
-
-static void __init
-setup_chaos(struct pci_controller* hose, struct reg_property* addr)
-{
- /* assume a `chaos' bridge */
- hose->ops = &chaos_pci_ops;
- hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
- hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
-}
-
-#ifdef CONFIG_POWER4
-
-static void __init
-setup_u3_agp(struct pci_controller* hose, struct reg_property* addr)
-{
- /* On G5, we move AGP up to high bus number so we don't need
- * to reassign bus numbers for HT. If we ever have P2P bridges
- * on AGP, we'll have to move pci_assign_all_buses to the
- * pci_controller structure so we enable it for AGP and not for
- * HT childs.
- * We hard code the address because of the different size of
- * the reg address cell, we shall fix that by killing struct
- * reg_property and using some accessor functions instead
- */
- hose->first_busno = 0xf0;
- hose->last_busno = 0xff;
- has_uninorth = 1;
- hose->ops = ¯isc_pci_ops;
- hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
- hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
-
- u3_agp = hose;
-}
-
-static void __init
-setup_u3_ht(struct pci_controller* hose, struct reg_property *addr)
-{
- struct device_node *np = (struct device_node *)hose->arch_data;
- int i, cur;
-
- hose->ops = &u3_ht_pci_ops;
-
- /* We hard code the address because of the different size of
- * the reg address cell, we shall fix that by killing struct
- * reg_property and using some accessor functions instead
- */
- hose->cfg_data = ioremap(0xf2000000, 0x02000000);
-
- /*
- * /ht node doesn't expose a "ranges" property, so we "remove" regions that
- * have been allocated to AGP. So far, this version of the code doesn't assign
- * any of the 0xfxxxxxxx "fine" memory regions to /ht.
- * We need to fix that sooner or later by either parsing all child "ranges"
- * properties or figuring out the U3 address space decoding logic and
- * then read its configuration register (if any).
- */
- hose->io_base_phys = 0xf4000000;
- hose->io_base_virt = ioremap(hose->io_base_phys, 0x00400000);
- isa_io_base = (unsigned long) hose->io_base_virt;
- hose->io_resource.name = np->full_name;
- hose->io_resource.start = 0;
- hose->io_resource.end = 0x003fffff;
- hose->io_resource.flags = IORESOURCE_IO;
- hose->pci_mem_offset = 0;
- hose->first_busno = 0;
- hose->last_busno = 0xef;
- hose->mem_resources[0].name = np->full_name;
- hose->mem_resources[0].start = 0x80000000;
- hose->mem_resources[0].end = 0xefffffff;
- hose->mem_resources[0].flags = IORESOURCE_MEM;
-
- if (u3_agp == NULL) {
- DBG("U3 has no AGP, using full resource range\n");
- return;
- }
-
- /* We "remove" the AGP resources from the resources allocated to HT, that
- * is we create "holes". However, that code does assumptions that so far
- * happen to be true (cross fingers...), typically that resources in the
- * AGP node are properly ordered
- */
- cur = 0;
- for (i=0; i<3; i++) {
- struct resource *res = &u3_agp->mem_resources[i];
- if (res->flags != IORESOURCE_MEM)
- continue;
- /* We don't care about "fine" resources */
- if (res->start >= 0xf0000000)
- continue;
- /* Check if it's just a matter of "shrinking" us in one direction */
- if (hose->mem_resources[cur].start == res->start) {
- DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n",
- cur, hose->mem_resources[cur].start, res->end + 1);
- hose->mem_resources[cur].start = res->end + 1;
- continue;
- }
- if (hose->mem_resources[cur].end == res->end) {
- DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n",
- cur, hose->mem_resources[cur].end, res->start - 1);
- hose->mem_resources[cur].end = res->start - 1;
- continue;
- }
- /* No, it's not the case, we need a hole */
- if (cur == 2) {
- /* not enough resources to make a hole, we drop part of the range */
- printk(KERN_WARNING "Running out of resources for /ht host !\n");
- hose->mem_resources[cur].end = res->start - 1;
- continue;
- }
- cur++;
- DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n",
- cur-1, res->start - 1, cur, res->end + 1);
- hose->mem_resources[cur].name = np->full_name;
- hose->mem_resources[cur].flags = IORESOURCE_MEM;
- hose->mem_resources[cur].start = res->end + 1;
- hose->mem_resources[cur].end = hose->mem_resources[cur-1].end;
- hose->mem_resources[cur-1].end = res->start - 1;
- }
-}
-
-#endif /* CONFIG_POWER4 */
-
-void __init
-setup_grackle(struct pci_controller *hose)
-{
- setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
- if (machine_is_compatible("AAPL,PowerBook1998"))
- grackle_set_loop_snoop(hose, 1);
-#if 0 /* Disabled for now, HW problems ??? */
- grackle_set_stg(hose, 1);
-#endif
-}
-
-/*
- * We assume that if we have a G3 powermac, we have one bridge called
- * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise,
- * if we have one or more bandit or chaos bridges, we don't have a MPC106.
- */
-static int __init
-add_bridge(struct device_node *dev)
-{
- int len;
- struct pci_controller *hose;
- struct reg_property *addr;
- char* disp_name;
- int *bus_range;
- int primary = 1;
-
- DBG("Adding PCI host bridge %s\n", dev->full_name);
-
- addr = (struct reg_property *) get_property(dev, "reg", &len);
- if (addr == NULL || len < sizeof(*addr)) {
- printk(KERN_WARNING "Can't use %s: no address\n",
- dev->full_name);
- return -ENODEV;
- }
- bus_range = (int *) get_property(dev, "bus-range", &len);
- if (bus_range == NULL || len < 2 * sizeof(int)) {
- printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
- dev->full_name);
- }
-
- hose = pcibios_alloc_controller();
- if (!hose)
- return -ENOMEM;
- hose->arch_data = dev;
- hose->first_busno = bus_range ? bus_range[0] : 0;
- hose->last_busno = bus_range ? bus_range[1] : 0xff;
-
- disp_name = NULL;
-#ifdef CONFIG_POWER4
- if (device_is_compatible(dev, "u3-agp")) {
- setup_u3_agp(hose, addr);
- disp_name = "U3-AGP";
- primary = 0;
- } else if (device_is_compatible(dev, "u3-ht")) {
- setup_u3_ht(hose, addr);
- disp_name = "U3-HT";
- primary = 1;
- } else
-#endif /* CONFIG_POWER4 */
- if (device_is_compatible(dev, "uni-north")) {
- primary = setup_uninorth(hose, addr);
- disp_name = "UniNorth";
- } else if (strcmp(dev->name, "pci") == 0) {
- /* XXX assume this is a mpc106 (grackle) */
- setup_grackle(hose);
- disp_name = "Grackle (MPC106)";
- } else if (strcmp(dev->name, "bandit") == 0) {
- setup_bandit(hose, addr);
- disp_name = "Bandit";
- } else if (strcmp(dev->name, "chaos") == 0) {
- setup_chaos(hose, addr);
- disp_name = "Chaos";
- primary = 0;
- }
- printk(KERN_INFO "Found %s PCI host bridge at 0x%08x. Firmware bus number: %d->%d\n",
- disp_name, addr->address, hose->first_busno, hose->last_busno);
- DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
- hose, hose->cfg_addr, hose->cfg_data);
-
- /* Interpret the "ranges" property */
- /* This also maps the I/O region and sets isa_io/mem_base */
- pci_process_bridge_OF_ranges(hose, dev, primary);
-
- /* Fixup "bus-range" OF property */
- fixup_bus_range(dev);
-
- return 0;
-}
-
-static void __init
-pcibios_fixup_OF_interrupts(void)
-{
- struct pci_dev* dev = NULL;
-
- /*
- * Open Firmware often doesn't initialize the
- * PCI_INTERRUPT_LINE config register properly, so we
- * should find the device node and apply the interrupt
- * obtained from the OF device-tree
- */
- for_each_pci_dev(dev) {
- struct device_node *node;
- node = pci_device_to_OF_node(dev);
- /* this is the node, see if it has interrupts */
- if (node && node->n_intrs > 0)
- dev->irq = node->intrs[0].line;
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
- }
-}
-
-void __init
-pmac_pcibios_fixup(void)
-{
- /* Fixup interrupts according to OF tree */
- pcibios_fixup_OF_interrupts();
-}
-
-int
-pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
-{
- struct device_node* node;
- int updatecfg = 0;
- int uninorth_child;
-
- node = pci_device_to_OF_node(dev);
-
- /* We don't want to enable USB controllers absent from the OF tree
- * (iBook second controller)
- */
- if (dev->vendor == PCI_VENDOR_ID_APPLE
- && (dev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10))
- && !node) {
- printk(KERN_INFO "Apple USB OHCI %s disabled by firmware\n",
- pci_name(dev));
- return -EINVAL;
- }
-
- if (!node)
- return 0;
-
- uninorth_child = node->parent &&
- device_is_compatible(node->parent, "uni-north");
-
- /* Firewire & GMAC were disabled after PCI probe, the driver is
- * claiming them, we must re-enable them now.
- */
- if (uninorth_child && !strcmp(node->name, "firewire") &&
- (device_is_compatible(node, "pci106b,18") ||
- device_is_compatible(node, "pci106b,30") ||
- device_is_compatible(node, "pci11c1,5811"))) {
- pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, node, 0, 1);
- pmac_call_feature(PMAC_FTR_1394_ENABLE, node, 0, 1);
- updatecfg = 1;
- }
- if (uninorth_child && !strcmp(node->name, "ethernet") &&
- device_is_compatible(node, "gmac")) {
- pmac_call_feature(PMAC_FTR_GMAC_ENABLE, node, 0, 1);
- updatecfg = 1;
- }
-
- if (updatecfg) {
- u16 cmd;
-
- /*
- * Make sure PCI is correctly configured
- *
- * We use old pci_bios versions of the function since, by
- * default, gmac is not powered up, and so will be absent
- * from the kernel initial PCI lookup.
- *
- * Should be replaced by 2.4 new PCI mechanisms and really
- * register the device.
- */
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16);
- pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, pci_cache_line_size);
- }
-
- return 0;
-}
-
-/* We power down some devices after they have been probed. They'll
- * be powered back on later on
- */
-void __init
-pmac_pcibios_after_init(void)
-{
- struct device_node* nd;
-
-#ifdef CONFIG_BLK_DEV_IDE
- struct pci_dev *dev = NULL;
-
- /* OF fails to initialize IDE controllers on macs
- * (and maybe other machines)
- *
- * Ideally, this should be moved to the IDE layer, but we need
- * to check specifically with Andre Hedrick how to do it cleanly
- * since the common IDE code seem to care about the fact that the
- * BIOS may have disabled a controller.
- *
- * -- BenH
- */
- for_each_pci_dev(dev) {
- if ((dev->class >> 16) == PCI_BASE_CLASS_STORAGE)
- pci_enable_device(dev);
- }
-#endif /* CONFIG_BLK_DEV_IDE */
-
- nd = find_devices("firewire");
- while (nd) {
- if (nd->parent && (device_is_compatible(nd, "pci106b,18") ||
- device_is_compatible(nd, "pci106b,30") ||
- device_is_compatible(nd, "pci11c1,5811"))
- && device_is_compatible(nd->parent, "uni-north")) {
- pmac_call_feature(PMAC_FTR_1394_ENABLE, nd, 0, 0);
- pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0);
- }
- nd = nd->next;
- }
- nd = find_devices("ethernet");
- while (nd) {
- if (nd->parent && device_is_compatible(nd, "gmac")
- && device_is_compatible(nd->parent, "uni-north"))
- pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0);
- nd = nd->next;
- }
-}
-
-void pmac_pci_fixup_cardbus(struct pci_dev* dev)
-{
- if (_machine != _MACH_Pmac)
- return;
- /*
- * Fix the interrupt routing on the various cardbus bridges
- * used on powerbooks
- */
- if (dev->vendor != PCI_VENDOR_ID_TI)
- return;
- if (dev->device == PCI_DEVICE_ID_TI_1130 ||
- dev->device == PCI_DEVICE_ID_TI_1131) {
- u8 val;
- /* Enable PCI interrupt */
- if (pci_read_config_byte(dev, 0x91, &val) == 0)
- pci_write_config_byte(dev, 0x91, val | 0x30);
- /* Disable ISA interrupt mode */
- if (pci_read_config_byte(dev, 0x92, &val) == 0)
- pci_write_config_byte(dev, 0x92, val & ~0x06);
- }
- if (dev->device == PCI_DEVICE_ID_TI_1210 ||
- dev->device == PCI_DEVICE_ID_TI_1211 ||
- dev->device == PCI_DEVICE_ID_TI_1410 ||
- dev->device == PCI_DEVICE_ID_TI_1510) {
- u8 val;
- /* 0x8c == TI122X_IRQMUX, 2 says to route the INTA
- signal out the MFUNC0 pin */
- if (pci_read_config_byte(dev, 0x8c, &val) == 0)
- pci_write_config_byte(dev, 0x8c, (val & ~0x0f) | 2);
- /* Disable ISA interrupt mode */
- if (pci_read_config_byte(dev, 0x92, &val) == 0)
- pci_write_config_byte(dev, 0x92, val & ~0x06);
- }
-}
-
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TI, PCI_ANY_ID, pmac_pci_fixup_cardbus);
-
-void pmac_pci_fixup_pciata(struct pci_dev* dev)
-{
- u8 progif = 0;
-
- /*
- * On PowerMacs, we try to switch any PCI ATA controller to
- * fully native mode
- */
- if (_machine != _MACH_Pmac)
- return;
- /* Some controllers don't have the class IDE */
- if (dev->vendor == PCI_VENDOR_ID_PROMISE)
- switch(dev->device) {
- case PCI_DEVICE_ID_PROMISE_20246:
- case PCI_DEVICE_ID_PROMISE_20262:
- case PCI_DEVICE_ID_PROMISE_20263:
- case PCI_DEVICE_ID_PROMISE_20265:
- case PCI_DEVICE_ID_PROMISE_20267:
- case PCI_DEVICE_ID_PROMISE_20268:
- case PCI_DEVICE_ID_PROMISE_20269:
- case PCI_DEVICE_ID_PROMISE_20270:
- case PCI_DEVICE_ID_PROMISE_20271:
- case PCI_DEVICE_ID_PROMISE_20275:
- case PCI_DEVICE_ID_PROMISE_20276:
- case PCI_DEVICE_ID_PROMISE_20277:
- goto good;
- }
- /* Others, check PCI class */
- if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
- return;
- good:
- pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
- if ((progif & 5) != 5) {
- printk(KERN_INFO "Forcing PCI IDE into native mode: %s\n", pci_name(dev));
- (void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5);
- if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) ||
- (progif & 5) != 5)
- printk(KERN_ERR "Rewrite of PROGIF failed !\n");
- }
-}
-DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata);
-
-
-/*
- * Disable second function on K2-SATA, it's broken
- * and disable IO BARs on first one
- */
-void pmac_pci_fixup_k2_sata(struct pci_dev* dev)
-{
- int i;
- u16 cmd;
-
- if (PCI_FUNC(dev->devfn) > 0) {
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- for (i = 0; i < 6; i++) {
- dev->resource[i].start = dev->resource[i].end = 0;
- dev->resource[i].flags = 0;
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);
- }
- } else {
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- cmd &= ~PCI_COMMAND_IO;
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- for (i = 0; i < 5; i++) {
- dev->resource[i].start = dev->resource[i].end = 0;
- dev->resource[i].flags = 0;
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);
- }
- }
-}
-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 4742bf6..0000000
--- a/arch/ppc/platforms/pmac_pic.c
+++ /dev/null
@@ -1,693 +0,0 @@
-/*
- * Support for the interrupt controllers found on Power Macintosh,
- * currently Apple's "Grand Central" interrupt controller in all
- * it's incarnations. OpenPIC support used on newer machines is
- * in a separate file
- *
- * Copyright (C) 1997 Paul Mackerras (paulus@cs.anu.edu.au)
- *
- * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- */
-
-#include <linux/config.h>
-#include <linux/stddef.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/sysdev.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-
-#include <asm/sections.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
-#include <asm/time.h>
-#include <asm/open_pic.h>
-#include <asm/xmon.h>
-#include <asm/pmac_feature.h>
-#include <asm/machdep.h>
-
-#include "pmac_pic.h"
-
-/*
- * XXX this should be in xmon.h, but putting it there means xmon.h
- * has to include <linux/interrupt.h> (to get irqreturn_t), which
- * causes all sorts of problems. -- paulus
- */
-extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
-
-struct pmac_irq_hw {
- unsigned int event;
- unsigned int enable;
- unsigned int ack;
- unsigned int level;
-};
-
-/* Default addresses */
-static volatile struct pmac_irq_hw *pmac_irq_hw[4] = {
- (struct pmac_irq_hw *) 0xf3000020,
- (struct pmac_irq_hw *) 0xf3000010,
- (struct pmac_irq_hw *) 0xf4000020,
- (struct pmac_irq_hw *) 0xf4000010,
-};
-
-#define GC_LEVEL_MASK 0x3ff00000
-#define OHARE_LEVEL_MASK 0x1ff00000
-#define HEATHROW_LEVEL_MASK 0x1ff00000
-
-static int max_irqs;
-static int max_real_irqs;
-static u32 level_mask[4];
-
-static DEFINE_SPINLOCK(pmac_pic_lock);
-
-
-#define GATWICK_IRQ_POOL_SIZE 10
-static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
-
-#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
-static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
-
-/*
- * Mark an irq as "lost". This is only used on the pmac
- * since it can lose interrupts (see pmac_set_irq_mask).
- * -- Cort
- */
-void
-__set_lost(unsigned long irq_nr, int nokick)
-{
- if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) {
- atomic_inc(&ppc_n_lost_interrupts);
- if (!nokick)
- set_dec(1);
- }
-}
-
-static void
-pmac_mask_and_ack_irq(unsigned int irq_nr)
-{
- unsigned long bit = 1UL << (irq_nr & 0x1f);
- int i = irq_nr >> 5;
- unsigned long flags;
-
- if ((unsigned)irq_nr >= max_irqs)
- return;
-
- clear_bit(irq_nr, ppc_cached_irq_mask);
- if (test_and_clear_bit(irq_nr, ppc_lost_interrupts))
- atomic_dec(&ppc_n_lost_interrupts);
- spin_lock_irqsave(&pmac_pic_lock, flags);
- out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
- out_le32(&pmac_irq_hw[i]->ack, bit);
- do {
- /* make sure ack gets to controller before we enable
- interrupts */
- mb();
- } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
- != (ppc_cached_irq_mask[i] & bit));
- spin_unlock_irqrestore(&pmac_pic_lock, flags);
-}
-
-static void pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
-{
- unsigned long bit = 1UL << (irq_nr & 0x1f);
- int i = irq_nr >> 5;
- unsigned long flags;
-
- if ((unsigned)irq_nr >= max_irqs)
- return;
-
- spin_lock_irqsave(&pmac_pic_lock, flags);
- /* enable unmasked interrupts */
- out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
-
- do {
- /* make sure mask gets to controller before we
- return to user */
- mb();
- } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
- != (ppc_cached_irq_mask[i] & bit));
-
- /*
- * Unfortunately, setting the bit in the enable register
- * when the device interrupt is already on *doesn't* set
- * the bit in the flag register or request another interrupt.
- */
- if (bit & ppc_cached_irq_mask[i] & in_le32(&pmac_irq_hw[i]->level))
- __set_lost((ulong)irq_nr, nokicklost);
- spin_unlock_irqrestore(&pmac_pic_lock, flags);
-}
-
-/* When an irq gets requested for the first client, if it's an
- * edge interrupt, we clear any previous one on the controller
- */
-static unsigned int pmac_startup_irq(unsigned int irq_nr)
-{
- unsigned long bit = 1UL << (irq_nr & 0x1f);
- int i = irq_nr >> 5;
-
- if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0)
- out_le32(&pmac_irq_hw[i]->ack, bit);
- set_bit(irq_nr, ppc_cached_irq_mask);
- pmac_set_irq_mask(irq_nr, 0);
-
- return 0;
-}
-
-static void pmac_mask_irq(unsigned int irq_nr)
-{
- clear_bit(irq_nr, ppc_cached_irq_mask);
- pmac_set_irq_mask(irq_nr, 0);
- mb();
-}
-
-static void pmac_unmask_irq(unsigned int irq_nr)
-{
- set_bit(irq_nr, ppc_cached_irq_mask);
- pmac_set_irq_mask(irq_nr, 0);
-}
-
-static void pmac_end_irq(unsigned int irq_nr)
-{
- if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
- && irq_desc[irq_nr].action) {
- set_bit(irq_nr, ppc_cached_irq_mask);
- pmac_set_irq_mask(irq_nr, 1);
- }
-}
-
-
-struct hw_interrupt_type pmac_pic = {
- .typename = " PMAC-PIC ",
- .startup = pmac_startup_irq,
- .enable = pmac_unmask_irq,
- .disable = pmac_mask_irq,
- .ack = pmac_mask_and_ack_irq,
- .end = pmac_end_irq,
-};
-
-struct hw_interrupt_type gatwick_pic = {
- .typename = " GATWICK ",
- .startup = pmac_startup_irq,
- .enable = pmac_unmask_irq,
- .disable = pmac_mask_irq,
- .ack = pmac_mask_and_ack_irq,
- .end = pmac_end_irq,
-};
-
-static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
-{
- int irq, bits;
-
- for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) {
- int i = irq >> 5;
- bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
- /* We must read level interrupts from the level register */
- bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]);
- bits &= ppc_cached_irq_mask[i];
- if (bits == 0)
- continue;
- irq += __ilog2(bits);
- __do_IRQ(irq, regs);
- return IRQ_HANDLED;
- }
- printk("gatwick irq not from gatwick pic\n");
- return IRQ_NONE;
-}
-
-int
-pmac_get_irq(struct pt_regs *regs)
-{
- int irq;
- unsigned long bits = 0;
-
-#ifdef CONFIG_SMP
- void psurge_smp_message_recv(struct pt_regs *);
-
- /* IPI's are a hack on the powersurge -- Cort */
- if ( smp_processor_id() != 0 ) {
- psurge_smp_message_recv(regs);
- return -2; /* ignore, already handled */
- }
-#endif /* CONFIG_SMP */
- for (irq = max_real_irqs; (irq -= 32) >= 0; ) {
- int i = irq >> 5;
- bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
- /* We must read level interrupts from the level register */
- bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]);
- bits &= ppc_cached_irq_mask[i];
- if (bits == 0)
- continue;
- irq += __ilog2(bits);
- break;
- }
-
- return irq;
-}
-
-/* This routine will fix some missing interrupt values in the device tree
- * on the gatwick mac-io controller used by some PowerBooks
- */
-static void __init
-pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base)
-{
- struct device_node *node;
- int count;
-
- memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool));
- node = gw->child;
- count = 0;
- while(node)
- {
- /* Fix SCC */
- if (strcasecmp(node->name, "escc") == 0)
- if (node->child) {
- if (node->child->n_intrs < 3) {
- node->child->intrs = &gatwick_int_pool[count];
- count += 3;
- }
- node->child->n_intrs = 3;
- node->child->intrs[0].line = 15+irq_base;
- node->child->intrs[1].line = 4+irq_base;
- node->child->intrs[2].line = 5+irq_base;
- printk(KERN_INFO "irq: fixed SCC on second controller (%d,%d,%d)\n",
- node->child->intrs[0].line,
- node->child->intrs[1].line,
- node->child->intrs[2].line);
- }
- /* Fix media-bay & left SWIM */
- if (strcasecmp(node->name, "media-bay") == 0) {
- struct device_node* ya_node;
-
- if (node->n_intrs == 0)
- node->intrs = &gatwick_int_pool[count++];
- node->n_intrs = 1;
- node->intrs[0].line = 29+irq_base;
- printk(KERN_INFO "irq: fixed media-bay on second controller (%d)\n",
- node->intrs[0].line);
-
- ya_node = node->child;
- while(ya_node)
- {
- if (strcasecmp(ya_node->name, "floppy") == 0) {
- if (ya_node->n_intrs < 2) {
- ya_node->intrs = &gatwick_int_pool[count];
- count += 2;
- }
- ya_node->n_intrs = 2;
- ya_node->intrs[0].line = 19+irq_base;
- ya_node->intrs[1].line = 1+irq_base;
- printk(KERN_INFO "irq: fixed floppy on second controller (%d,%d)\n",
- ya_node->intrs[0].line, ya_node->intrs[1].line);
- }
- if (strcasecmp(ya_node->name, "ata4") == 0) {
- if (ya_node->n_intrs < 2) {
- ya_node->intrs = &gatwick_int_pool[count];
- count += 2;
- }
- ya_node->n_intrs = 2;
- ya_node->intrs[0].line = 14+irq_base;
- ya_node->intrs[1].line = 3+irq_base;
- printk(KERN_INFO "irq: fixed ide on second controller (%d,%d)\n",
- ya_node->intrs[0].line, ya_node->intrs[1].line);
- }
- ya_node = ya_node->sibling;
- }
- }
- node = node->sibling;
- }
- if (count > 10) {
- printk("WARNING !! Gatwick interrupt pool overflow\n");
- printk(" GATWICK_IRQ_POOL_SIZE = %d\n", GATWICK_IRQ_POOL_SIZE);
- printk(" requested = %d\n", count);
- }
-}
-
-/*
- * The PowerBook 3400/2400/3500 can have a combo ethernet/modem
- * card which includes an ohare chip that acts as a second interrupt
- * controller. If we find this second ohare, set it up and fix the
- * interrupt value in the device tree for the ethernet chip.
- */
-static int __init enable_second_ohare(void)
-{
- unsigned char bus, devfn;
- unsigned short cmd;
- unsigned long addr;
- struct device_node *irqctrler = find_devices("pci106b,7");
- struct device_node *ether;
-
- if (irqctrler == NULL || irqctrler->n_addrs <= 0)
- return -1;
- addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40);
- pmac_irq_hw[1] = (volatile struct pmac_irq_hw *)(addr + 0x20);
- max_irqs = 64;
- if (pci_device_from_OF_node(irqctrler, &bus, &devfn) == 0) {
- struct pci_controller* hose = pci_find_hose_for_OF_device(irqctrler);
- if (!hose)
- printk(KERN_ERR "Can't find PCI hose for OHare2 !\n");
- else {
- early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd);
- cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
- cmd &= ~PCI_COMMAND_IO;
- early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd);
- }
- }
-
- /* Fix interrupt for the modem/ethernet combo controller. The number
- in the device tree (27) is bogus (correct for the ethernet-only
- board but not the combo ethernet/modem board).
- The real interrupt is 28 on the second controller -> 28+32 = 60.
- */
- ether = find_devices("pci1011,14");
- if (ether && ether->n_intrs > 0) {
- ether->intrs[0].line = 60;
- printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n",
- ether->intrs[0].line);
- }
-
- /* Return the interrupt number of the cascade */
- return irqctrler->intrs[0].line;
-}
-
-#ifdef CONFIG_POWER4
-static irqreturn_t k2u3_action(int cpl, void *dev_id, struct pt_regs *regs)
-{
- int irq;
-
- irq = openpic2_get_irq(regs);
- if (irq != -1)
- __do_IRQ(irq, regs);
- return IRQ_HANDLED;
-}
-
-static struct irqaction k2u3_cascade_action = {
- .handler = k2u3_action,
- .flags = 0,
- .mask = CPU_MASK_NONE,
- .name = "U3->K2 Cascade",
-};
-#endif /* CONFIG_POWER4 */
-
-#ifdef CONFIG_XMON
-static struct irqaction xmon_action = {
- .handler = xmon_irq,
- .flags = 0,
- .mask = CPU_MASK_NONE,
- .name = "NMI - XMON"
-};
-#endif
-
-static struct irqaction gatwick_cascade_action = {
- .handler = gatwick_action,
- .flags = SA_INTERRUPT,
- .mask = CPU_MASK_NONE,
- .name = "cascade",
-};
-
-void __init pmac_pic_init(void)
-{
- int i;
- struct device_node *irqctrler = NULL;
- struct device_node *irqctrler2 = NULL;
- struct device_node *np;
- unsigned long addr;
- int irq_cascade = -1;
-
- /* We first try to detect Apple's new Core99 chipset, since mac-io
- * is quite different on those machines and contains an IBM MPIC2.
- */
- np = find_type_devices("open-pic");
- while(np) {
- if (np->parent && !strcmp(np->parent->name, "u3"))
- irqctrler2 = np;
- else
- irqctrler = np;
- np = np->next;
- }
- if (irqctrler != NULL)
- {
- if (irqctrler->n_addrs > 0)
- {
- unsigned char senses[128];
-
- printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n",
- irqctrler->addrs[0].address);
-
- prom_get_irq_senses(senses, 0, 128);
- OpenPIC_InitSenses = senses;
- OpenPIC_NumInitSenses = 128;
- ppc_md.get_irq = openpic_get_irq;
- pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler, 0, 0);
- OpenPIC_Addr = ioremap(irqctrler->addrs[0].address,
- irqctrler->addrs[0].size);
- openpic_init(0);
-
-#ifdef CONFIG_POWER4
- if (irqctrler2 != NULL && irqctrler2->n_intrs > 0 &&
- irqctrler2->n_addrs > 0) {
- printk(KERN_INFO "Slave OpenPIC at 0x%08x hooked on IRQ %d\n",
- irqctrler2->addrs[0].address,
- irqctrler2->intrs[0].line);
- pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0);
- OpenPIC2_Addr = ioremap(irqctrler2->addrs[0].address,
- irqctrler2->addrs[0].size);
- prom_get_irq_senses(senses, PMAC_OPENPIC2_OFFSET,
- PMAC_OPENPIC2_OFFSET+128);
- OpenPIC_InitSenses = senses;
- OpenPIC_NumInitSenses = 128;
- openpic2_init(PMAC_OPENPIC2_OFFSET);
-
- if (setup_irq(irqctrler2->intrs[0].line,
- &k2u3_cascade_action))
- printk("Unable to get OpenPIC IRQ for cascade\n");
- }
-#endif /* CONFIG_POWER4 */
-
-#ifdef CONFIG_XMON
- {
- struct device_node* pswitch;
- int nmi_irq;
-
- pswitch = find_devices("programmer-switch");
- if (pswitch && pswitch->n_intrs) {
- nmi_irq = pswitch->intrs[0].line;
- openpic_init_nmi_irq(nmi_irq);
- setup_irq(nmi_irq, &xmon_action);
- }
- }
-#endif /* CONFIG_XMON */
- return;
- }
- irqctrler = NULL;
- }
-
- /* Get the level/edge settings, assume if it's not
- * a Grand Central nor an OHare, then it's an Heathrow
- * (or Paddington).
- */
- if (find_devices("gc"))
- level_mask[0] = GC_LEVEL_MASK;
- else if (find_devices("ohare")) {
- level_mask[0] = OHARE_LEVEL_MASK;
- /* We might have a second cascaded ohare */
- level_mask[1] = OHARE_LEVEL_MASK;
- } else {
- level_mask[0] = HEATHROW_LEVEL_MASK;
- level_mask[1] = 0;
- /* We might have a second cascaded heathrow */
- level_mask[2] = HEATHROW_LEVEL_MASK;
- level_mask[3] = 0;
- }
-
- /*
- * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts,
- * 1998 G3 Series PowerBooks have 128,
- * other powermacs have 32.
- * The combo ethernet/modem card for the Powerstar powerbooks
- * (2400/3400/3500, ohare based) has a second ohare chip
- * effectively making a total of 64.
- */
- max_irqs = max_real_irqs = 32;
- irqctrler = find_devices("mac-io");
- if (irqctrler)
- {
- max_real_irqs = 64;
- if (irqctrler->next)
- max_irqs = 128;
- else
- max_irqs = 64;
- }
- for ( i = 0; i < max_real_irqs ; i++ )
- irq_desc[i].handler = &pmac_pic;
-
- /* get addresses of first controller */
- if (irqctrler) {
- if (irqctrler->n_addrs > 0) {
- addr = (unsigned long)
- ioremap(irqctrler->addrs[0].address, 0x40);
- for (i = 0; i < 2; ++i)
- pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
- (addr + (2 - i) * 0x10);
- }
-
- /* get addresses of second controller */
- irqctrler = irqctrler->next;
- if (irqctrler && irqctrler->n_addrs > 0) {
- addr = (unsigned long)
- ioremap(irqctrler->addrs[0].address, 0x40);
- for (i = 2; i < 4; ++i)
- pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
- (addr + (4 - i) * 0x10);
- irq_cascade = irqctrler->intrs[0].line;
- if (device_is_compatible(irqctrler, "gatwick"))
- pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs);
- }
- } else {
- /* older powermacs have a GC (grand central) or ohare at
- f3000000, with interrupt control registers at f3000020. */
- addr = (unsigned long) ioremap(0xf3000000, 0x40);
- pmac_irq_hw[0] = (volatile struct pmac_irq_hw *) (addr + 0x20);
- }
-
- /* PowerBooks 3400 and 3500 can have a second controller in a second
- ohare chip, on the combo ethernet/modem card */
- if (machine_is_compatible("AAPL,3400/2400")
- || machine_is_compatible("AAPL,3500"))
- irq_cascade = enable_second_ohare();
-
- /* disable all interrupts in all controllers */
- for (i = 0; i * 32 < max_irqs; ++i)
- out_le32(&pmac_irq_hw[i]->enable, 0);
- /* mark level interrupts */
- for (i = 0; i < max_irqs; i++)
- if (level_mask[i >> 5] & (1UL << (i & 0x1f)))
- irq_desc[i].status = IRQ_LEVEL;
-
- /* get interrupt line of secondary interrupt controller */
- if (irq_cascade >= 0) {
- printk(KERN_INFO "irq: secondary controller on irq %d\n",
- (int)irq_cascade);
- for ( i = max_real_irqs ; i < max_irqs ; i++ )
- irq_desc[i].handler = &gatwick_pic;
- setup_irq(irq_cascade, &gatwick_cascade_action);
- }
- printk("System has %d possible interrupts\n", max_irqs);
- if (max_irqs != max_real_irqs)
- printk(KERN_DEBUG "%d interrupts on main controller\n",
- max_real_irqs);
-
-#ifdef CONFIG_XMON
- setup_irq(20, &xmon_action);
-#endif /* CONFIG_XMON */
-}
-
-#ifdef CONFIG_PM
-/*
- * These procedures are used in implementing sleep on the powerbooks.
- * sleep_save_intrs() saves the states of all interrupt enables
- * and disables all interrupts except for the nominated one.
- * sleep_restore_intrs() restores the states of all interrupt enables.
- */
-unsigned long sleep_save_mask[2];
-
-/* This used to be passed by the PMU driver but that link got
- * broken with the new driver model. We use this tweak for now...
- */
-static int pmacpic_find_viaint(void)
-{
- int viaint = -1;
-
-#ifdef CONFIG_ADB_PMU
- struct device_node *np;
-
- if (pmu_get_model() != PMU_OHARE_BASED)
- goto not_found;
- np = of_find_node_by_name(NULL, "via-pmu");
- if (np == NULL)
- goto not_found;
- viaint = np->intrs[0].line;
-#endif /* CONFIG_ADB_PMU */
-
-not_found:
- return viaint;
-}
-
-static int pmacpic_suspend(struct sys_device *sysdev, pm_message_t state)
-{
- int viaint = pmacpic_find_viaint();
-
- sleep_save_mask[0] = ppc_cached_irq_mask[0];
- sleep_save_mask[1] = ppc_cached_irq_mask[1];
- ppc_cached_irq_mask[0] = 0;
- ppc_cached_irq_mask[1] = 0;
- if (viaint > 0)
- set_bit(viaint, ppc_cached_irq_mask);
- out_le32(&pmac_irq_hw[0]->enable, ppc_cached_irq_mask[0]);
- if (max_real_irqs > 32)
- out_le32(&pmac_irq_hw[1]->enable, ppc_cached_irq_mask[1]);
- (void)in_le32(&pmac_irq_hw[0]->event);
- /* make sure mask gets to controller before we return to caller */
- mb();
- (void)in_le32(&pmac_irq_hw[0]->enable);
-
- return 0;
-}
-
-static int pmacpic_resume(struct sys_device *sysdev)
-{
- int i;
-
- out_le32(&pmac_irq_hw[0]->enable, 0);
- if (max_real_irqs > 32)
- out_le32(&pmac_irq_hw[1]->enable, 0);
- mb();
- for (i = 0; i < max_real_irqs; ++i)
- if (test_bit(i, sleep_save_mask))
- pmac_unmask_irq(i);
-
- return 0;
-}
-
-#endif /* CONFIG_PM */
-
-static struct sysdev_class pmacpic_sysclass = {
- set_kset_name("pmac_pic"),
-};
-
-static struct sys_device device_pmacpic = {
- .id = 0,
- .cls = &pmacpic_sysclass,
-};
-
-static struct sysdev_driver driver_pmacpic = {
-#ifdef CONFIG_PM
- .suspend = &pmacpic_suspend,
- .resume = &pmacpic_resume,
-#endif /* CONFIG_PM */
-};
-
-static int __init init_pmacpic_sysfs(void)
-{
- if (max_irqs == 0)
- return -ENODEV;
-
- printk(KERN_DEBUG "Registering pmac pic with sysfs...\n");
- sysdev_class_register(&pmacpic_sysclass);
- sysdev_register(&device_pmacpic);
- sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic);
- return 0;
-}
-
-subsys_initcall(init_pmacpic_sysfs);
-
diff --git a/arch/ppc/platforms/pmac_pic.h b/arch/ppc/platforms/pmac_pic.h
deleted file mode 100644
index 664103d..0000000
--- a/arch/ppc/platforms/pmac_pic.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef __PPC_PLATFORMS_PMAC_PIC_H
-#define __PPC_PLATFORMS_PMAC_PIC_H
-
-#include <linux/irq.h>
-
-extern struct hw_interrupt_type pmac_pic;
-
-void pmac_pic_init(void);
-int pmac_get_irq(struct pt_regs *regs);
-
-#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 55d2bef..0000000
--- a/arch/ppc/platforms/pmac_setup.c
+++ /dev/null
@@ -1,745 +0,0 @@
-/*
- * arch/ppc/platforms/setup.c
- *
- * PowerPC version
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- * Adapted for Power Macintosh by Paul Mackerras
- * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
- *
- * Derived from "arch/alpha/kernel/setup.c"
- * Copyright (C) 1995 Linus Torvalds
- *
- * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- */
-
-/*
- * bootup setup stuff..
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/tty.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/major.h>
-#include <linux/initrd.h>
-#include <linux/vt_kern.h>
-#include <linux/console.h>
-#include <linux/ide.h>
-#include <linux/pci.h>
-#include <linux/adb.h>
-#include <linux/cuda.h>
-#include <linux/pmu.h>
-#include <linux/seq_file.h>
-#include <linux/root_dev.h>
-#include <linux/bitops.h>
-#include <linux/suspend.h>
-
-#include <asm/reg.h>
-#include <asm/sections.h>
-#include <asm/prom.h>
-#include <asm/system.h>
-#include <asm/pgtable.h>
-#include <asm/io.h>
-#include <asm/pci-bridge.h>
-#include <asm/ohare.h>
-#include <asm/mediabay.h>
-#include <asm/machdep.h>
-#include <asm/dma.h>
-#include <asm/bootx.h>
-#include <asm/cputable.h>
-#include <asm/btext.h>
-#include <asm/pmac_feature.h>
-#include <asm/time.h>
-#include <asm/of_device.h>
-#include <asm/mmu_context.h>
-
-#include "pmac_pic.h"
-#include "mem_pieces.h"
-
-#undef SHOW_GATWICK_IRQS
-
-extern long pmac_time_init(void);
-extern unsigned long pmac_get_rtc_time(void);
-extern int pmac_set_rtc_time(unsigned long nowtime);
-extern void pmac_read_rtc_time(void);
-extern void pmac_calibrate_decr(void);
-extern void pmac_pcibios_fixup(void);
-extern void pmac_find_bridges(void);
-extern unsigned long pmac_ide_get_base(int index);
-extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
- unsigned long data_port, unsigned long ctrl_port, int *irq);
-
-extern void pmac_nvram_update(void);
-extern unsigned char pmac_nvram_read_byte(int addr);
-extern void pmac_nvram_write_byte(int addr, unsigned char val);
-extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial);
-extern void pmac_pcibios_after_init(void);
-extern int of_show_percpuinfo(struct seq_file *m, int i);
-
-struct device_node *memory_node;
-
-unsigned char drive_info;
-
-int ppc_override_l2cr = 0;
-int ppc_override_l2cr_value;
-int has_l2cache = 0;
-
-static int current_root_goodness = -1;
-
-extern int pmac_newworld;
-
-#define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */
-
-extern void zs_kgdb_hook(int tty_num);
-static void ohare_init(void);
-#ifdef CONFIG_BOOTX_TEXT
-static void pmac_progress(char *s, unsigned short hex);
-#endif
-
-sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN;
-
-#ifdef CONFIG_SMP
-extern struct smp_ops_t psurge_smp_ops;
-extern struct smp_ops_t core99_smp_ops;
-#endif /* CONFIG_SMP */
-
-static int
-pmac_show_cpuinfo(struct seq_file *m)
-{
- struct device_node *np;
- char *pp;
- int plen;
- int mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
- NULL, PMAC_MB_INFO_MODEL, 0);
- unsigned int mbflags = (unsigned int)pmac_call_feature(PMAC_FTR_GET_MB_INFO,
- NULL, PMAC_MB_INFO_FLAGS, 0);
- char* mbname;
-
- if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, (int)&mbname) != 0)
- mbname = "Unknown";
-
- /* find motherboard type */
- seq_printf(m, "machine\t\t: ");
- np = find_devices("device-tree");
- if (np != NULL) {
- pp = (char *) get_property(np, "model", NULL);
- if (pp != NULL)
- seq_printf(m, "%s\n", pp);
- else
- seq_printf(m, "PowerMac\n");
- pp = (char *) get_property(np, "compatible", &plen);
- if (pp != NULL) {
- seq_printf(m, "motherboard\t:");
- while (plen > 0) {
- int l = strlen(pp) + 1;
- seq_printf(m, " %s", pp);
- plen -= l;
- pp += l;
- }
- seq_printf(m, "\n");
- }
- } else
- seq_printf(m, "PowerMac\n");
-
- /* print parsed model */
- seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname);
- seq_printf(m, "pmac flags\t: %08x\n", mbflags);
-
- /* find l2 cache info */
- np = find_devices("l2-cache");
- if (np == 0)
- np = find_type_devices("cache");
- if (np != 0) {
- unsigned int *ic = (unsigned int *)
- get_property(np, "i-cache-size", NULL);
- unsigned int *dc = (unsigned int *)
- get_property(np, "d-cache-size", NULL);
- seq_printf(m, "L2 cache\t:");
- has_l2cache = 1;
- if (get_property(np, "cache-unified", NULL) != 0 && dc) {
- seq_printf(m, " %dK unified", *dc / 1024);
- } else {
- if (ic)
- seq_printf(m, " %dK instruction", *ic / 1024);
- if (dc)
- seq_printf(m, "%s %dK data",
- (ic? " +": ""), *dc / 1024);
- }
- pp = get_property(np, "ram-type", NULL);
- if (pp)
- seq_printf(m, " %s", pp);
- seq_printf(m, "\n");
- }
-
- /* find ram info */
- np = find_devices("memory");
- if (np != 0) {
- int n;
- struct reg_property *reg = (struct reg_property *)
- get_property(np, "reg", &n);
-
- if (reg != 0) {
- unsigned long total = 0;
-
- for (n /= sizeof(struct reg_property); n > 0; --n)
- total += (reg++)->size;
- seq_printf(m, "memory\t\t: %luMB\n", total >> 20);
- }
- }
-
- /* Checks "l2cr-value" property in the registry */
- np = find_devices("cpus");
- if (np == 0)
- np = find_type_devices("cpu");
- if (np != 0) {
- unsigned int *l2cr = (unsigned int *)
- get_property(np, "l2cr-value", NULL);
- if (l2cr != 0) {
- seq_printf(m, "l2cr override\t: 0x%x\n", *l2cr);
- }
- }
-
- /* Indicate newworld/oldworld */
- seq_printf(m, "pmac-generation\t: %s\n",
- pmac_newworld ? "NewWorld" : "OldWorld");
-
-
- return 0;
-}
-
-static int
-pmac_show_percpuinfo(struct seq_file *m, int i)
-{
-#ifdef CONFIG_CPU_FREQ_PMAC
- extern unsigned int pmac_get_one_cpufreq(int i);
- unsigned int freq = pmac_get_one_cpufreq(i);
- if (freq != 0) {
- seq_printf(m, "clock\t\t: %dMHz\n", freq/1000);
- return 0;
- }
-#endif /* CONFIG_CPU_FREQ_PMAC */
- return of_show_percpuinfo(m, i);
-}
-
-static volatile u32 *sysctrl_regs;
-
-void __init
-pmac_setup_arch(void)
-{
- struct device_node *cpu;
- int *fp;
- unsigned long pvr;
-
- pvr = PVR_VER(mfspr(SPRN_PVR));
-
- /* Set loops_per_jiffy to a half-way reasonable value,
- for use until calibrate_delay gets called. */
- cpu = find_type_devices("cpu");
- if (cpu != 0) {
- fp = (int *) get_property(cpu, "clock-frequency", NULL);
- if (fp != 0) {
- if (pvr == 4 || pvr >= 8)
- /* 604, G3, G4 etc. */
- loops_per_jiffy = *fp / HZ;
- else
- /* 601, 603, etc. */
- loops_per_jiffy = *fp / (2*HZ);
- } else
- loops_per_jiffy = 50000000 / HZ;
- }
-
- /* this area has the CPU identification register
- and some registers used by smp boards */
- sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000);
- ohare_init();
-
- /* Lookup PCI hosts */
- pmac_find_bridges();
-
- /* Checks "l2cr-value" property in the registry */
- if (cpu_has_feature(CPU_FTR_L2CR)) {
- struct device_node *np = find_devices("cpus");
- if (np == 0)
- np = find_type_devices("cpu");
- if (np != 0) {
- unsigned int *l2cr = (unsigned int *)
- get_property(np, "l2cr-value", NULL);
- if (l2cr != 0) {
- ppc_override_l2cr = 1;
- ppc_override_l2cr_value = *l2cr;
- _set_L2CR(0);
- _set_L2CR(ppc_override_l2cr_value);
- }
- }
- }
-
- if (ppc_override_l2cr)
- printk(KERN_INFO "L2CR overriden (0x%x), backside cache is %s\n",
- ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000)
- ? "enabled" : "disabled");
-
-#ifdef CONFIG_KGDB
- zs_kgdb_hook(0);
-#endif
-
-#ifdef CONFIG_ADB_CUDA
- find_via_cuda();
-#else
- if (find_devices("via-cuda")) {
- printk("WARNING ! Your machine is Cuda based but your kernel\n");
- printk(" wasn't compiled with CONFIG_ADB_CUDA option !\n");
- }
-#endif
-#ifdef CONFIG_ADB_PMU
- find_via_pmu();
-#else
- if (find_devices("via-pmu")) {
- printk("WARNING ! Your machine is PMU based but your kernel\n");
- printk(" wasn't compiled with CONFIG_ADB_PMU option !\n");
- }
-#endif
-#ifdef CONFIG_NVRAM
- pmac_nvram_init();
-#endif
-#ifdef CONFIG_BLK_DEV_INITRD
- if (initrd_start)
- ROOT_DEV = Root_RAM0;
- else
-#endif
- ROOT_DEV = DEFAULT_ROOT_DEVICE;
-
-#ifdef CONFIG_SMP
- /* Check for Core99 */
- if (find_devices("uni-n") || find_devices("u3"))
- smp_ops = &core99_smp_ops;
- else
- smp_ops = &psurge_smp_ops;
-#endif /* CONFIG_SMP */
-
- pci_create_OF_bus_map();
-}
-
-static void __init ohare_init(void)
-{
- /*
- * Turn on the L2 cache.
- * We assume that we have a PSX memory controller iff
- * we have an ohare I/O controller.
- */
- if (find_devices("ohare") != NULL) {
- if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) {
- if (sysctrl_regs[4] & 0x10)
- sysctrl_regs[4] |= 0x04000020;
- else
- sysctrl_regs[4] |= 0x04000000;
- if(has_l2cache)
- printk(KERN_INFO "Level 2 cache enabled\n");
- }
- }
-}
-
-extern char *bootpath;
-extern char *bootdevice;
-void *boot_host;
-int boot_target;
-int boot_part;
-extern dev_t boot_dev;
-
-#ifdef CONFIG_SCSI
-void __init
-note_scsi_host(struct device_node *node, void *host)
-{
- int l;
- char *p;
-
- l = strlen(node->full_name);
- if (bootpath != NULL && bootdevice != NULL
- && strncmp(node->full_name, bootdevice, l) == 0
- && (bootdevice[l] == '/' || bootdevice[l] == 0)) {
- boot_host = host;
- /*
- * There's a bug in OF 1.0.5. (Why am I not surprised.)
- * If you pass a path like scsi/sd@1:0 to canon, it returns
- * something like /bandit@F2000000/gc@10/53c94@10000/sd@0,0
- * That is, the scsi target number doesn't get preserved.
- * So we pick the target number out of bootpath and use that.
- */
- p = strstr(bootpath, "/sd@");
- if (p != NULL) {
- p += 4;
- boot_target = simple_strtoul(p, NULL, 10);
- p = strchr(p, ':');
- if (p != NULL)
- boot_part = simple_strtoul(p + 1, NULL, 10);
- }
- }
-}
-#endif
-
-#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
-static dev_t __init
-find_ide_boot(void)
-{
- char *p;
- int n;
- dev_t __init pmac_find_ide_boot(char *bootdevice, int n);
-
- if (bootdevice == NULL)
- return 0;
- p = strrchr(bootdevice, '/');
- if (p == NULL)
- return 0;
- n = p - bootdevice;
-
- return pmac_find_ide_boot(bootdevice, n);
-}
-#endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */
-
-static void __init
-find_boot_device(void)
-{
-#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
- boot_dev = find_ide_boot();
-#endif
-}
-
-static int initializing = 1;
-/* TODO: Merge the suspend-to-ram with the common code !!!
- * currently, this is a stub implementation for suspend-to-disk
- * only
- */
-
-#ifdef CONFIG_SOFTWARE_SUSPEND
-
-static int pmac_pm_prepare(suspend_state_t state)
-{
- printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
-
- return 0;
-}
-
-static int pmac_pm_enter(suspend_state_t state)
-{
- printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
-
- /* Giveup the lazy FPU & vec so we don't have to back them
- * up from the low level code
- */
- enable_kernel_fp();
-
-#ifdef CONFIG_ALTIVEC
- if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
- enable_kernel_altivec();
-#endif /* CONFIG_ALTIVEC */
-
- return 0;
-}
-
-static int pmac_pm_finish(suspend_state_t state)
-{
- printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
-
- /* Restore userland MMU context */
- set_context(current->active_mm->context, current->active_mm->pgd);
-
- return 0;
-}
-
-static struct pm_ops pmac_pm_ops = {
- .pm_disk_mode = PM_DISK_SHUTDOWN,
- .prepare = pmac_pm_prepare,
- .enter = pmac_pm_enter,
- .finish = pmac_pm_finish,
-};
-
-#endif /* CONFIG_SOFTWARE_SUSPEND */
-
-static int pmac_late_init(void)
-{
- initializing = 0;
-#ifdef CONFIG_SOFTWARE_SUSPEND
- pm_set_ops(&pmac_pm_ops);
-#endif /* CONFIG_SOFTWARE_SUSPEND */
- return 0;
-}
-
-late_initcall(pmac_late_init);
-
-/* can't be __init - can be called whenever a disk is first accessed */
-void
-note_bootable_part(dev_t dev, int part, int goodness)
-{
- static int found_boot = 0;
- char *p;
-
- if (!initializing)
- return;
- if ((goodness <= current_root_goodness) &&
- ROOT_DEV != DEFAULT_ROOT_DEVICE)
- return;
- p = strstr(saved_command_line, "root=");
- if (p != NULL && (p == saved_command_line || p[-1] == ' '))
- return;
-
- if (!found_boot) {
- find_boot_device();
- found_boot = 1;
- }
- if (!boot_dev || dev == boot_dev) {
- ROOT_DEV = dev + part;
- boot_dev = 0;
- current_root_goodness = goodness;
- }
-}
-
-static void
-pmac_restart(char *cmd)
-{
-#ifdef CONFIG_ADB_CUDA
- struct adb_request req;
-#endif /* CONFIG_ADB_CUDA */
-
- switch (sys_ctrler) {
-#ifdef CONFIG_ADB_CUDA
- case SYS_CTRLER_CUDA:
- cuda_request(&req, NULL, 2, CUDA_PACKET,
- CUDA_RESET_SYSTEM);
- for (;;)
- cuda_poll();
- break;
-#endif /* CONFIG_ADB_CUDA */
-#ifdef CONFIG_ADB_PMU
- case SYS_CTRLER_PMU:
- pmu_restart();
- break;
-#endif /* CONFIG_ADB_PMU */
- default: ;
- }
-}
-
-static void
-pmac_power_off(void)
-{
-#ifdef CONFIG_ADB_CUDA
- struct adb_request req;
-#endif /* CONFIG_ADB_CUDA */
-
- switch (sys_ctrler) {
-#ifdef CONFIG_ADB_CUDA
- case SYS_CTRLER_CUDA:
- cuda_request(&req, NULL, 2, CUDA_PACKET,
- CUDA_POWERDOWN);
- for (;;)
- cuda_poll();
- break;
-#endif /* CONFIG_ADB_CUDA */
-#ifdef CONFIG_ADB_PMU
- case SYS_CTRLER_PMU:
- pmu_shutdown();
- break;
-#endif /* CONFIG_ADB_PMU */
- default: ;
- }
-}
-
-static void
-pmac_halt(void)
-{
- pmac_power_off();
-}
-
-/*
- * Read in a property describing some pieces of memory.
- */
-
-static int __init
-get_mem_prop(char *name, struct mem_pieces *mp)
-{
- struct reg_property *rp;
- int i, s;
- unsigned int *ip;
- int nac = prom_n_addr_cells(memory_node);
- int nsc = prom_n_size_cells(memory_node);
-
- ip = (unsigned int *) get_property(memory_node, name, &s);
- if (ip == NULL) {
- printk(KERN_ERR "error: couldn't get %s property on /memory\n",
- name);
- return 0;
- }
- s /= (nsc + nac) * 4;
- rp = mp->regions;
- for (i = 0; i < s; ++i, ip += nac+nsc) {
- if (nac >= 2 && ip[nac-2] != 0)
- continue;
- rp->address = ip[nac-1];
- if (nsc >= 2 && ip[nac+nsc-2] != 0)
- rp->size = ~0U;
- else
- rp->size = ip[nac+nsc-1];
- ++rp;
- }
- mp->n_regions = rp - mp->regions;
-
- /* Make sure the pieces are sorted. */
- mem_pieces_sort(mp);
- mem_pieces_coalesce(mp);
- return 1;
-}
-
-/*
- * On systems with Open Firmware, collect information about
- * physical RAM and which pieces are already in use.
- * At this point, we have (at least) the first 8MB mapped with a BAT.
- * Our text, data, bss use something over 1MB, starting at 0.
- * Open Firmware may be using 1MB at the 4MB point.
- */
-unsigned long __init
-pmac_find_end_of_memory(void)
-{
- unsigned long a, total;
- struct mem_pieces phys_mem;
-
- /*
- * Find out where physical memory is, and check that it
- * starts at 0 and is contiguous. It seems that RAM is
- * always physically contiguous on Power Macintoshes.
- *
- * Supporting discontiguous physical memory isn't hard,
- * it just makes the virtual <-> physical mapping functions
- * more complicated (or else you end up wasting space
- * in mem_map).
- */
- memory_node = find_devices("memory");
- if (memory_node == NULL || !get_mem_prop("reg", &phys_mem)
- || phys_mem.n_regions == 0)
- panic("No RAM??");
- a = phys_mem.regions[0].address;
- if (a != 0)
- panic("RAM doesn't start at physical address 0");
- total = phys_mem.regions[0].size;
-
- if (phys_mem.n_regions > 1) {
- printk("RAM starting at 0x%x is not contiguous\n",
- phys_mem.regions[1].address);
- printk("Using RAM from 0 to 0x%lx\n", total-1);
- }
-
- return total;
-}
-
-void __init
-pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,
- unsigned long r6, unsigned long r7)
-{
- /* isa_io_base gets set in pmac_find_bridges */
- isa_mem_base = PMAC_ISA_MEM_BASE;
- pci_dram_offset = PMAC_PCI_DRAM_OFFSET;
- ISA_DMA_THRESHOLD = ~0L;
- DMA_MODE_READ = 1;
- DMA_MODE_WRITE = 2;
-
- ppc_md.setup_arch = pmac_setup_arch;
- ppc_md.show_cpuinfo = pmac_show_cpuinfo;
- ppc_md.show_percpuinfo = pmac_show_percpuinfo;
- ppc_md.init_IRQ = pmac_pic_init;
- ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */
-
- ppc_md.pcibios_fixup = pmac_pcibios_fixup;
- ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook;
- ppc_md.pcibios_after_init = pmac_pcibios_after_init;
- ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
-
- ppc_md.restart = pmac_restart;
- ppc_md.power_off = pmac_power_off;
- ppc_md.halt = pmac_halt;
-
- ppc_md.time_init = pmac_time_init;
- ppc_md.set_rtc_time = pmac_set_rtc_time;
- ppc_md.get_rtc_time = pmac_get_rtc_time;
- ppc_md.calibrate_decr = pmac_calibrate_decr;
-
- ppc_md.find_end_of_memory = pmac_find_end_of_memory;
-
- ppc_md.feature_call = pmac_do_feature_call;
-
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-#ifdef CONFIG_BLK_DEV_IDE_PMAC
- ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports;
- ppc_ide_md.default_io_base = pmac_ide_get_base;
-#endif /* CONFIG_BLK_DEV_IDE_PMAC */
-#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */
-
-#ifdef CONFIG_BOOTX_TEXT
- ppc_md.progress = pmac_progress;
-#endif /* CONFIG_BOOTX_TEXT */
-
- if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0);
-
-}
-
-#ifdef CONFIG_BOOTX_TEXT
-static void __init
-pmac_progress(char *s, unsigned short hex)
-{
- if (boot_text_mapped) {
- btext_drawstring(s);
- btext_drawchar('\n');
- }
-}
-#endif /* CONFIG_BOOTX_TEXT */
-
-static int __init
-pmac_declare_of_platform_devices(void)
-{
- struct device_node *np;
-
- np = find_devices("uni-n");
- if (np) {
- for (np = np->child; np != NULL; np = np->sibling)
- if (strncmp(np->name, "i2c", 3) == 0) {
- of_platform_device_create(np, "uni-n-i2c",
- NULL);
- break;
- }
- }
- np = find_devices("u3");
- if (np) {
- for (np = np->child; np != NULL; np = np->sibling)
- if (strncmp(np->name, "i2c", 3) == 0) {
- of_platform_device_create(np, "u3-i2c",
- NULL);
- break;
- }
- }
-
- np = find_devices("valkyrie");
- if (np)
- of_platform_device_create(np, "valkyrie", NULL);
- np = find_devices("platinum");
- if (np)
- of_platform_device_create(np, "platinum", NULL);
-
- return 0;
-}
-
-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 22b113d..0000000
--- a/arch/ppc/platforms/pmac_sleep.S
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * This file contains sleep low-level functions for PowerBook G3.
- * Copyright (C) 1999 Benjamin Herrenschmidt (benh@kernel.crashing.org)
- * and Paul Mackerras (paulus@samba.org).
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- */
-
-#include <linux/config.h>
-#include <asm/processor.h>
-#include <asm/page.h>
-#include <asm/ppc_asm.h>
-#include <asm/cputable.h>
-#include <asm/cache.h>
-#include <asm/thread_info.h>
-#include <asm/asm-offsets.h>
-
-#define MAGIC 0x4c617273 /* 'Lars' */
-
-/*
- * Structure for storing CPU registers on the stack.
- */
-#define SL_SP 0
-#define SL_PC 4
-#define SL_MSR 8
-#define SL_SDR1 0xc
-#define SL_SPRG0 0x10 /* 4 sprg's */
-#define SL_DBAT0 0x20
-#define SL_IBAT0 0x28
-#define SL_DBAT1 0x30
-#define SL_IBAT1 0x38
-#define SL_DBAT2 0x40
-#define SL_IBAT2 0x48
-#define SL_DBAT3 0x50
-#define SL_IBAT3 0x58
-#define SL_TB 0x60
-#define SL_R2 0x68
-#define SL_CR 0x6c
-#define SL_R12 0x70 /* r12 to r31 */
-#define SL_SIZE (SL_R12 + 80)
-
- .section .text
- .align 5
-
-#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC)
-
-/* This gets called by via-pmu.c late during the sleep process.
- * The PMU was already send the sleep command and will shut us down
- * soon. We need to save all that is needed and setup the wakeup
- * vector that will be called by the ROM on wakeup
- */
-_GLOBAL(low_sleep_handler)
-#ifndef CONFIG_6xx
- blr
-#else
- mflr r0
- stw r0,4(r1)
- stwu r1,-SL_SIZE(r1)
- mfcr r0
- stw r0,SL_CR(r1)
- stw r2,SL_R2(r1)
- stmw r12,SL_R12(r1)
-
- /* Save MSR & SDR1 */
- mfmsr r4
- stw r4,SL_MSR(r1)
- mfsdr1 r4
- stw r4,SL_SDR1(r1)
-
- /* Get a stable timebase and save it */
-1: mftbu r4
- stw r4,SL_TB(r1)
- mftb r5
- stw r5,SL_TB+4(r1)
- mftbu r3
- cmpw r3,r4
- bne 1b
-
- /* Save SPRGs */
- mfsprg r4,0
- stw r4,SL_SPRG0(r1)
- mfsprg r4,1
- stw r4,SL_SPRG0+4(r1)
- mfsprg r4,2
- stw r4,SL_SPRG0+8(r1)
- mfsprg r4,3
- stw r4,SL_SPRG0+12(r1)
-
- /* Save BATs */
- mfdbatu r4,0
- stw r4,SL_DBAT0(r1)
- mfdbatl r4,0
- stw r4,SL_DBAT0+4(r1)
- mfdbatu r4,1
- stw r4,SL_DBAT1(r1)
- mfdbatl r4,1
- stw r4,SL_DBAT1+4(r1)
- mfdbatu r4,2
- stw r4,SL_DBAT2(r1)
- mfdbatl r4,2
- stw r4,SL_DBAT2+4(r1)
- mfdbatu r4,3
- stw r4,SL_DBAT3(r1)
- mfdbatl r4,3
- stw r4,SL_DBAT3+4(r1)
- mfibatu r4,0
- stw r4,SL_IBAT0(r1)
- mfibatl r4,0
- stw r4,SL_IBAT0+4(r1)
- mfibatu r4,1
- stw r4,SL_IBAT1(r1)
- mfibatl r4,1
- stw r4,SL_IBAT1+4(r1)
- mfibatu r4,2
- stw r4,SL_IBAT2(r1)
- mfibatl r4,2
- stw r4,SL_IBAT2+4(r1)
- mfibatu r4,3
- stw r4,SL_IBAT3(r1)
- mfibatl r4,3
- stw r4,SL_IBAT3+4(r1)
-
- /* Backup various CPU config stuffs */
- bl __save_cpu_setup
-
- /* The ROM can wake us up via 2 different vectors:
- * - On wallstreet & lombard, we must write a magic
- * value 'Lars' at address 4 and a pointer to a
- * memory location containing the PC to resume from
- * at address 0.
- * - On Core99, we must store the wakeup vector at
- * address 0x80 and eventually it's parameters
- * at address 0x84. I've have some trouble with those
- * parameters however and I no longer use them.
- */
- lis r5,grackle_wake_up@ha
- addi r5,r5,grackle_wake_up@l
- tophys(r5,r5)
- stw r5,SL_PC(r1)
- lis r4,KERNELBASE@h
- tophys(r5,r1)
- addi r5,r5,SL_PC
- lis r6,MAGIC@ha
- addi r6,r6,MAGIC@l
- stw r5,0(r4)
- stw r6,4(r4)
- /* Setup stuffs at 0x80-0x84 for Core99 */
- lis r3,core99_wake_up@ha
- addi r3,r3,core99_wake_up@l
- tophys(r3,r3)
- stw r3,0x80(r4)
- stw r5,0x84(r4)
- /* Store a pointer to our backup storage into
- * a kernel global
- */
- lis r3,sleep_storage@ha
- addi r3,r3,sleep_storage@l
- stw r5,0(r3)
-
- .globl low_cpu_die
-low_cpu_die:
- /* Flush & disable all caches */
- bl flush_disable_caches
-
- /* Turn off data relocation. */
- mfmsr r3 /* Save MSR in r7 */
- rlwinm r3,r3,0,28,26 /* Turn off DR bit */
- sync
- mtmsr r3
- isync
-
-BEGIN_FTR_SECTION
- /* Flush any pending L2 data prefetches to work around HW bug */
- sync
- lis r3,0xfff0
- lwz r0,0(r3) /* perform cache-inhibited load to ROM */
- sync /* (caches are disabled at this point) */
-END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
-
-/*
- * Set the HID0 and MSR for sleep.
- */
- mfspr r2,SPRN_HID0
- rlwinm r2,r2,0,10,7 /* clear doze, nap */
- oris r2,r2,HID0_SLEEP@h
- sync
- isync
- mtspr SPRN_HID0,r2
- sync
-
-/* This loop puts us back to sleep in case we have a spurrious
- * wakeup so that the host bridge properly stays asleep. The
- * CPU will be turned off, either after a known time (about 1
- * second) on wallstreet & lombard, or as soon as the CPU enters
- * SLEEP mode on core99
- */
- mfmsr r2
- oris r2,r2,MSR_POW@h
-1: sync
- mtmsr r2
- isync
- b 1b
-
-/*
- * Here is the resume code.
- */
-
-
-/*
- * Core99 machines resume here
- * r4 has the physical address of SL_PC(sp) (unused)
- */
-_GLOBAL(core99_wake_up)
- /* Make sure HID0 no longer contains any sleep bit and that data cache
- * is disabled
- */
- mfspr r3,SPRN_HID0
- rlwinm r3,r3,0,11,7 /* clear SLEEP, NAP, DOZE bits */
- rlwinm 3,r3,0,18,15 /* clear DCE, ICE */
- mtspr SPRN_HID0,r3
- sync
- isync
-
- /* sanitize MSR */
- mfmsr r3
- ori r3,r3,MSR_EE|MSR_IP
- xori r3,r3,MSR_EE|MSR_IP
- sync
- isync
- mtmsr r3
- sync
- isync
-
- /* Recover sleep storage */
- lis r3,sleep_storage@ha
- addi r3,r3,sleep_storage@l
- tophys(r3,r3)
- lwz r1,0(r3)
-
- /* Pass thru to older resume code ... */
-/*
- * Here is the resume code for older machines.
- * r1 has the physical address of SL_PC(sp).
- */
-
-grackle_wake_up:
-
- /* Restore the kernel's segment registers before
- * we do any r1 memory access as we are not sure they
- * are in a sane state above the first 256Mb region
- */
- li r0,16 /* load up segment register values */
- mtctr r0 /* for context 0 */
- lis r3,0x2000 /* Ku = 1, VSID = 0 */
- li r4,0
-3: mtsrin r3,r4
- addi r3,r3,0x111 /* increment VSID */
- addis r4,r4,0x1000 /* address of next segment */
- bdnz 3b
- sync
- isync
-
- subi r1,r1,SL_PC
-
- /* Restore various CPU config stuffs */
- bl __restore_cpu_setup
-
- /* Make sure all FPRs have been initialized */
- bl reloc_offset
- bl __init_fpu_registers
-
- /* Invalidate & enable L1 cache, we don't care about
- * whatever the ROM may have tried to write to memory
- */
- bl __inval_enable_L1
-
- /* Restore the BATs, and SDR1. Then we can turn on the MMU. */
- lwz r4,SL_SDR1(r1)
- mtsdr1 r4
- lwz r4,SL_SPRG0(r1)
- mtsprg 0,r4
- lwz r4,SL_SPRG0+4(r1)
- mtsprg 1,r4
- lwz r4,SL_SPRG0+8(r1)
- mtsprg 2,r4
- lwz r4,SL_SPRG0+12(r1)
- mtsprg 3,r4
-
- lwz r4,SL_DBAT0(r1)
- mtdbatu 0,r4
- lwz r4,SL_DBAT0+4(r1)
- mtdbatl 0,r4
- lwz r4,SL_DBAT1(r1)
- mtdbatu 1,r4
- lwz r4,SL_DBAT1+4(r1)
- mtdbatl 1,r4
- lwz r4,SL_DBAT2(r1)
- mtdbatu 2,r4
- lwz r4,SL_DBAT2+4(r1)
- mtdbatl 2,r4
- lwz r4,SL_DBAT3(r1)
- mtdbatu 3,r4
- lwz r4,SL_DBAT3+4(r1)
- mtdbatl 3,r4
- lwz r4,SL_IBAT0(r1)
- mtibatu 0,r4
- lwz r4,SL_IBAT0+4(r1)
- mtibatl 0,r4
- lwz r4,SL_IBAT1(r1)
- mtibatu 1,r4
- lwz r4,SL_IBAT1+4(r1)
- mtibatl 1,r4
- lwz r4,SL_IBAT2(r1)
- mtibatu 2,r4
- lwz r4,SL_IBAT2+4(r1)
- mtibatl 2,r4
- lwz r4,SL_IBAT3(r1)
- mtibatu 3,r4
- lwz r4,SL_IBAT3+4(r1)
- mtibatl 3,r4
-
-BEGIN_FTR_SECTION
- li r4,0
- mtspr SPRN_DBAT4U,r4
- mtspr SPRN_DBAT4L,r4
- mtspr SPRN_DBAT5U,r4
- mtspr SPRN_DBAT5L,r4
- mtspr SPRN_DBAT6U,r4
- mtspr SPRN_DBAT6L,r4
- mtspr SPRN_DBAT7U,r4
- mtspr SPRN_DBAT7L,r4
- mtspr SPRN_IBAT4U,r4
- mtspr SPRN_IBAT4L,r4
- mtspr SPRN_IBAT5U,r4
- mtspr SPRN_IBAT5L,r4
- mtspr SPRN_IBAT6U,r4
- mtspr SPRN_IBAT6L,r4
- mtspr SPRN_IBAT7U,r4
- mtspr SPRN_IBAT7L,r4
-END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)
-
- /* Flush all TLBs */
- lis r4,0x1000
-1: addic. r4,r4,-0x1000
- tlbie r4
- blt 1b
- sync
-
- /* restore the MSR and turn on the MMU */
- lwz r3,SL_MSR(r1)
- bl turn_on_mmu
-
- /* get back the stack pointer */
- tovirt(r1,r1)
-
- /* Restore TB */
- li r3,0
- mttbl r3
- lwz r3,SL_TB(r1)
- lwz r4,SL_TB+4(r1)
- mttbu r3
- mttbl r4
-
- /* Restore the callee-saved registers and return */
- lwz r0,SL_CR(r1)
- mtcr r0
- lwz r2,SL_R2(r1)
- lmw r12,SL_R12(r1)
- addi r1,r1,SL_SIZE
- lwz r0,4(r1)
- mtlr r0
- blr
-
-turn_on_mmu:
- mflr r4
- tovirt(r4,r4)
- mtsrr0 r4
- mtsrr1 r3
- sync
- isync
- rfi
-
-#endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */
-
- .section .data
- .balign L1_CACHE_BYTES
-sleep_storage:
- .long 0
- .balign L1_CACHE_BYTES, 0
-
-#endif /* CONFIG_6xx */
- .section .text
diff --git a/arch/ppc/platforms/pmac_smp.c b/arch/ppc/platforms/pmac_smp.c
deleted file mode 100644
index 26ff262..0000000
--- a/arch/ppc/platforms/pmac_smp.c
+++ /dev/null
@@ -1,692 +0,0 @@
-/*
- * SMP support for power macintosh.
- *
- * We support both the old "powersurge" SMP architecture
- * and the current Core99 (G4 PowerMac) machines.
- *
- * Note that we don't support the very first rev. of
- * Apple/DayStar 2 CPUs board, the one with the funky
- * watchdog. Hopefully, none of these should be there except
- * maybe internally to Apple. I should probably still add some
- * code to detect this card though and disable SMP. --BenH.
- *
- * Support Macintosh G4 SMP by Troy Benjegerdes (hozer@drgw.net)
- * and Ben Herrenschmidt <benh@kernel.crashing.org>.
- *
- * Support for DayStar quad CPU cards
- * Copyright (C) XLR8, Inc. 1994-2000
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/errno.h>
-#include <linux/hardirq.h>
-#include <linux/cpu.h>
-
-#include <asm/ptrace.h>
-#include <asm/atomic.h>
-#include <asm/irq.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/sections.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/smp.h>
-#include <asm/residual.h>
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/time.h>
-#include <asm/open_pic.h>
-#include <asm/cacheflush.h>
-#include <asm/keylargo.h>
-
-/*
- * Powersurge (old powermac SMP) support.
- */
-
-extern void __secondary_start_pmac_0(void);
-
-/* Addresses for powersurge registers */
-#define HAMMERHEAD_BASE 0xf8000000
-#define HHEAD_CONFIG 0x90
-#define HHEAD_SEC_INTR 0xc0
-
-/* register for interrupting the primary processor on the powersurge */
-/* N.B. this is actually the ethernet ROM! */
-#define PSURGE_PRI_INTR 0xf3019000
-
-/* register for storing the start address for the secondary processor */
-/* N.B. this is the PCI config space address register for the 1st bridge */
-#define PSURGE_START 0xf2800000
-
-/* Daystar/XLR8 4-CPU card */
-#define PSURGE_QUAD_REG_ADDR 0xf8800000
-
-#define PSURGE_QUAD_IRQ_SET 0
-#define PSURGE_QUAD_IRQ_CLR 1
-#define PSURGE_QUAD_IRQ_PRIMARY 2
-#define PSURGE_QUAD_CKSTOP_CTL 3
-#define PSURGE_QUAD_PRIMARY_ARB 4
-#define PSURGE_QUAD_BOARD_ID 6
-#define PSURGE_QUAD_WHICH_CPU 7
-#define PSURGE_QUAD_CKSTOP_RDBK 8
-#define PSURGE_QUAD_RESET_CTL 11
-
-#define PSURGE_QUAD_OUT(r, v) (out_8(quad_base + ((r) << 4) + 4, (v)))
-#define PSURGE_QUAD_IN(r) (in_8(quad_base + ((r) << 4) + 4) & 0x0f)
-#define PSURGE_QUAD_BIS(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) | (v)))
-#define PSURGE_QUAD_BIC(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) & ~(v)))
-
-/* virtual addresses for the above */
-static volatile u8 __iomem *hhead_base;
-static volatile u8 __iomem *quad_base;
-static volatile u32 __iomem *psurge_pri_intr;
-static volatile u8 __iomem *psurge_sec_intr;
-static volatile u32 __iomem *psurge_start;
-
-/* values for psurge_type */
-#define PSURGE_NONE -1
-#define PSURGE_DUAL 0
-#define PSURGE_QUAD_OKEE 1
-#define PSURGE_QUAD_COTTON 2
-#define PSURGE_QUAD_ICEGRASS 3
-
-/* what sort of powersurge board we have */
-static int psurge_type = PSURGE_NONE;
-
-/* L2 and L3 cache settings to pass from CPU0 to CPU1 */
-volatile static long int core99_l2_cache;
-volatile static long int core99_l3_cache;
-
-/* Timebase freeze GPIO */
-static unsigned int core99_tb_gpio;
-
-/* Sync flag for HW tb sync */
-static volatile int sec_tb_reset = 0;
-static unsigned int pri_tb_hi, pri_tb_lo;
-static unsigned int pri_tb_stamp;
-
-static void __devinit core99_init_caches(int cpu)
-{
- if (!cpu_has_feature(CPU_FTR_L2CR))
- return;
-
- if (cpu == 0) {
- core99_l2_cache = _get_L2CR();
- printk("CPU0: L2CR is %lx\n", core99_l2_cache);
- } else {
- printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR());
- _set_L2CR(0);
- _set_L2CR(core99_l2_cache);
- printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache);
- }
-
- if (!cpu_has_feature(CPU_FTR_L3CR))
- return;
-
- if (cpu == 0){
- core99_l3_cache = _get_L3CR();
- printk("CPU0: L3CR is %lx\n", core99_l3_cache);
- } else {
- printk("CPU%d: L3CR was %lx\n", cpu, _get_L3CR());
- _set_L3CR(0);
- _set_L3CR(core99_l3_cache);
- printk("CPU%d: L3CR set to %lx\n", cpu, core99_l3_cache);
- }
-}
-
-/*
- * Set and clear IPIs for powersurge.
- */
-static inline void psurge_set_ipi(int cpu)
-{
- if (psurge_type == PSURGE_NONE)
- return;
- if (cpu == 0)
- in_be32(psurge_pri_intr);
- else if (psurge_type == PSURGE_DUAL)
- out_8(psurge_sec_intr, 0);
- else
- PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_SET, 1 << cpu);
-}
-
-static inline void psurge_clr_ipi(int cpu)
-{
- if (cpu > 0) {
- switch(psurge_type) {
- case PSURGE_DUAL:
- out_8(psurge_sec_intr, ~0);
- case PSURGE_NONE:
- break;
- default:
- PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, 1 << cpu);
- }
- }
-}
-
-/*
- * On powersurge (old SMP powermac architecture) we don't have
- * separate IPIs for separate messages like openpic does. Instead
- * we have a bitmap for each processor, where a 1 bit means that
- * the corresponding message is pending for that processor.
- * Ideally each cpu's entry would be in a different cache line.
- * -- paulus.
- */
-static unsigned long psurge_smp_message[NR_CPUS];
-
-void psurge_smp_message_recv(struct pt_regs *regs)
-{
- int cpu = smp_processor_id();
- int msg;
-
- /* clear interrupt */
- psurge_clr_ipi(cpu);
-
- if (num_online_cpus() < 2)
- return;
-
- /* make sure there is a message there */
- for (msg = 0; msg < 4; msg++)
- if (test_and_clear_bit(msg, &psurge_smp_message[cpu]))
- smp_message_recv(msg, regs);
-}
-
-irqreturn_t psurge_primary_intr(int irq, void *d, struct pt_regs *regs)
-{
- psurge_smp_message_recv(regs);
- return IRQ_HANDLED;
-}
-
-static void smp_psurge_message_pass(int target, int msg)
-{
- int i;
-
- if (num_online_cpus() < 2)
- return;
-
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_online(i))
- continue;
- if (target == MSG_ALL
- || (target == MSG_ALL_BUT_SELF && i != smp_processor_id())
- || target == i) {
- set_bit(msg, &psurge_smp_message[i]);
- psurge_set_ipi(i);
- }
- }
-}
-
-/*
- * Determine a quad card presence. We read the board ID register, we
- * force the data bus to change to something else, and we read it again.
- * It it's stable, then the register probably exist (ugh !)
- */
-static int __init psurge_quad_probe(void)
-{
- int type;
- unsigned int i;
-
- type = PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID);
- if (type < PSURGE_QUAD_OKEE || type > PSURGE_QUAD_ICEGRASS
- || type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
- return PSURGE_DUAL;
-
- /* looks OK, try a slightly more rigorous test */
- /* bogus is not necessarily cacheline-aligned,
- though I don't suppose that really matters. -- paulus */
- for (i = 0; i < 100; i++) {
- volatile u32 bogus[8];
- bogus[(0+i)%8] = 0x00000000;
- bogus[(1+i)%8] = 0x55555555;
- bogus[(2+i)%8] = 0xFFFFFFFF;
- bogus[(3+i)%8] = 0xAAAAAAAA;
- bogus[(4+i)%8] = 0x33333333;
- bogus[(5+i)%8] = 0xCCCCCCCC;
- bogus[(6+i)%8] = 0xCCCCCCCC;
- bogus[(7+i)%8] = 0x33333333;
- wmb();
- asm volatile("dcbf 0,%0" : : "r" (bogus) : "memory");
- mb();
- if (type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
- return PSURGE_DUAL;
- }
- return type;
-}
-
-static void __init psurge_quad_init(void)
-{
- int procbits;
-
- if (ppc_md.progress) ppc_md.progress("psurge_quad_init", 0x351);
- procbits = ~PSURGE_QUAD_IN(PSURGE_QUAD_WHICH_CPU);
- if (psurge_type == PSURGE_QUAD_ICEGRASS)
- PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
- else
- PSURGE_QUAD_BIC(PSURGE_QUAD_CKSTOP_CTL, procbits);
- mdelay(33);
- out_8(psurge_sec_intr, ~0);
- PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, procbits);
- PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
- if (psurge_type != PSURGE_QUAD_ICEGRASS)
- PSURGE_QUAD_BIS(PSURGE_QUAD_CKSTOP_CTL, procbits);
- PSURGE_QUAD_BIC(PSURGE_QUAD_PRIMARY_ARB, procbits);
- mdelay(33);
- PSURGE_QUAD_BIC(PSURGE_QUAD_RESET_CTL, procbits);
- mdelay(33);
- PSURGE_QUAD_BIS(PSURGE_QUAD_PRIMARY_ARB, procbits);
- mdelay(33);
-}
-
-static int __init smp_psurge_probe(void)
-{
- int i, ncpus;
-
- /* We don't do SMP on the PPC601 -- paulus */
- if (PVR_VER(mfspr(SPRN_PVR)) == 1)
- return 1;
-
- /*
- * The powersurge cpu board can be used in the generation
- * of powermacs that have a socket for an upgradeable cpu card,
- * including the 7500, 8500, 9500, 9600.
- * The device tree doesn't tell you if you have 2 cpus because
- * OF doesn't know anything about the 2nd processor.
- * Instead we look for magic bits in magic registers,
- * in the hammerhead memory controller in the case of the
- * dual-cpu powersurge board. -- paulus.
- */
- if (find_devices("hammerhead") == NULL)
- return 1;
-
- hhead_base = ioremap(HAMMERHEAD_BASE, 0x800);
- quad_base = ioremap(PSURGE_QUAD_REG_ADDR, 1024);
- psurge_sec_intr = hhead_base + HHEAD_SEC_INTR;
-
- psurge_type = psurge_quad_probe();
- if (psurge_type != PSURGE_DUAL) {
- psurge_quad_init();
- /* All released cards using this HW design have 4 CPUs */
- ncpus = 4;
- } else {
- iounmap(quad_base);
- if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) {
- /* not a dual-cpu card */
- iounmap(hhead_base);
- psurge_type = PSURGE_NONE;
- return 1;
- }
- ncpus = 2;
- }
-
- psurge_start = ioremap(PSURGE_START, 4);
- psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
-
- /* this is not actually strictly necessary -- paulus. */
- for (i = 1; i < ncpus; ++i)
- smp_hw_index[i] = i;
-
- if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352);
-
- return ncpus;
-}
-
-static void __init smp_psurge_kick_cpu(int nr)
-{
- unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8;
- unsigned long a;
-
- /* may need to flush here if secondary bats aren't setup */
- for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32)
- asm volatile("dcbf 0,%0" : : "r" (a) : "memory");
- asm volatile("sync");
-
- if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353);
-
- out_be32(psurge_start, start);
- mb();
-
- psurge_set_ipi(nr);
- udelay(10);
- psurge_clr_ipi(nr);
-
- if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);
-}
-
-/*
- * With the dual-cpu powersurge board, the decrementers and timebases
- * of both cpus are frozen after the secondary cpu is started up,
- * until we give the secondary cpu another interrupt. This routine
- * uses this to get the timebases synchronized.
- * -- paulus.
- */
-static void __init psurge_dual_sync_tb(int cpu_nr)
-{
- int t;
-
- set_dec(tb_ticks_per_jiffy);
- set_tb(0, 0);
- last_jiffy_stamp(cpu_nr) = 0;
-
- if (cpu_nr > 0) {
- mb();
- sec_tb_reset = 1;
- return;
- }
-
- /* wait for the secondary to have reset its TB before proceeding */
- for (t = 10000000; t > 0 && !sec_tb_reset; --t)
- ;
-
- /* now interrupt the secondary, starting both TBs */
- psurge_set_ipi(1);
-
- smp_tb_synchronized = 1;
-}
-
-static struct irqaction psurge_irqaction = {
- .handler = psurge_primary_intr,
- .flags = SA_INTERRUPT,
- .mask = CPU_MASK_NONE,
- .name = "primary IPI",
-};
-
-static void __init smp_psurge_setup_cpu(int cpu_nr)
-{
-
- if (cpu_nr == 0) {
- /* If we failed to start the second CPU, we should still
- * send it an IPI to start the timebase & DEC or we might
- * have them stuck.
- */
- if (num_online_cpus() < 2) {
- if (psurge_type == PSURGE_DUAL)
- psurge_set_ipi(1);
- return;
- }
- /* reset the entry point so if we get another intr we won't
- * try to startup again */
- out_be32(psurge_start, 0x100);
- if (setup_irq(30, &psurge_irqaction))
- printk(KERN_ERR "Couldn't get primary IPI interrupt");
- }
-
- if (psurge_type == PSURGE_DUAL)
- psurge_dual_sync_tb(cpu_nr);
-}
-
-void __init smp_psurge_take_timebase(void)
-{
- /* Dummy implementation */
-}
-
-void __init smp_psurge_give_timebase(void)
-{
- /* Dummy implementation */
-}
-
-static int __init smp_core99_probe(void)
-{
-#ifdef CONFIG_6xx
- extern int powersave_nap;
-#endif
- struct device_node *cpus, *firstcpu;
- int i, ncpus = 0, boot_cpu = -1;
- u32 *tbprop = NULL;
-
- if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
- cpus = firstcpu = find_type_devices("cpu");
- while(cpus != NULL) {
- u32 *regprop = (u32 *)get_property(cpus, "reg", NULL);
- char *stateprop = (char *)get_property(cpus, "state", NULL);
- if (regprop != NULL && stateprop != NULL &&
- !strncmp(stateprop, "running", 7))
- boot_cpu = *regprop;
- ++ncpus;
- cpus = cpus->next;
- }
- if (boot_cpu == -1)
- printk(KERN_WARNING "Couldn't detect boot CPU !\n");
- if (boot_cpu != 0)
- printk(KERN_WARNING "Boot CPU is %d, unsupported setup !\n", boot_cpu);
-
- if (machine_is_compatible("MacRISC4")) {
- extern struct smp_ops_t core99_smp_ops;
-
- core99_smp_ops.take_timebase = smp_generic_take_timebase;
- core99_smp_ops.give_timebase = smp_generic_give_timebase;
- } else {
- if (firstcpu != NULL)
- tbprop = (u32 *)get_property(firstcpu, "timebase-enable", NULL);
- if (tbprop)
- core99_tb_gpio = *tbprop;
- else
- core99_tb_gpio = KL_GPIO_TB_ENABLE;
- }
-
- if (ncpus > 1) {
- openpic_request_IPIs();
- for (i = 1; i < ncpus; ++i)
- smp_hw_index[i] = i;
-#ifdef CONFIG_6xx
- powersave_nap = 0;
-#endif
- core99_init_caches(0);
- }
-
- return ncpus;
-}
-
-static void __devinit smp_core99_kick_cpu(int nr)
-{
- unsigned long save_vector, new_vector;
- unsigned long flags;
-
- volatile unsigned long *vector
- = ((volatile unsigned long *)(KERNELBASE+0x100));
- if (nr < 0 || nr > 3)
- return;
- if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346);
-
- local_irq_save(flags);
- local_irq_disable();
-
- /* Save reset vector */
- save_vector = *vector;
-
- /* Setup fake reset vector that does
- * b __secondary_start_pmac_0 + nr*8 - KERNELBASE
- */
- new_vector = (unsigned long) __secondary_start_pmac_0 + nr * 8;
- *vector = 0x48000002 + new_vector - KERNELBASE;
-
- /* flush data cache and inval instruction cache */
- flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
-
- /* Put some life in our friend */
- pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0);
-
- /* FIXME: We wait a bit for the CPU to take the exception, I should
- * instead wait for the entry code to set something for me. Well,
- * ideally, all that crap will be done in prom.c and the CPU left
- * in a RAM-based wait loop like CHRP.
- */
- mdelay(1);
-
- /* Restore our exception vector */
- *vector = save_vector;
- flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
-
- local_irq_restore(flags);
- if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
-}
-
-static void __devinit smp_core99_setup_cpu(int cpu_nr)
-{
- /* Setup L2/L3 */
- if (cpu_nr != 0)
- core99_init_caches(cpu_nr);
-
- /* Setup openpic */
- do_openpic_setup_cpu();
-
- if (cpu_nr == 0) {
-#ifdef CONFIG_POWER4
- extern void g5_phy_disable_cpu1(void);
-
- /* If we didn't start the second CPU, we must take
- * it off the bus
- */
- if (machine_is_compatible("MacRISC4") &&
- num_online_cpus() < 2)
- g5_phy_disable_cpu1();
-#endif /* CONFIG_POWER4 */
- if (ppc_md.progress) ppc_md.progress("core99_setup_cpu 0 done", 0x349);
- }
-}
-
-/* not __init, called in sleep/wakeup code */
-void smp_core99_take_timebase(void)
-{
- unsigned long flags;
-
- /* tell the primary we're here */
- sec_tb_reset = 1;
- mb();
-
- /* wait for the primary to set pri_tb_hi/lo */
- while (sec_tb_reset < 2)
- mb();
-
- /* set our stuff the same as the primary */
- local_irq_save(flags);
- set_dec(1);
- set_tb(pri_tb_hi, pri_tb_lo);
- last_jiffy_stamp(smp_processor_id()) = pri_tb_stamp;
- mb();
-
- /* tell the primary we're done */
- sec_tb_reset = 0;
- mb();
- local_irq_restore(flags);
-}
-
-/* not __init, called in sleep/wakeup code */
-void smp_core99_give_timebase(void)
-{
- unsigned long flags;
- unsigned int t;
-
- /* wait for the secondary to be in take_timebase */
- for (t = 100000; t > 0 && !sec_tb_reset; --t)
- udelay(10);
- if (!sec_tb_reset) {
- printk(KERN_WARNING "Timeout waiting sync on second CPU\n");
- return;
- }
-
- /* freeze the timebase and read it */
- /* disable interrupts so the timebase is disabled for the
- shortest possible time */
- local_irq_save(flags);
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4);
- pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
- mb();
- pri_tb_hi = get_tbu();
- pri_tb_lo = get_tbl();
- pri_tb_stamp = last_jiffy_stamp(smp_processor_id());
- mb();
-
- /* tell the secondary we're ready */
- sec_tb_reset = 2;
- mb();
-
- /* wait for the secondary to have taken it */
- for (t = 100000; t > 0 && sec_tb_reset; --t)
- udelay(10);
- if (sec_tb_reset)
- printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n");
- else
- smp_tb_synchronized = 1;
-
- /* Now, restart the timebase by leaving the GPIO to an open collector */
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0);
- pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
- local_irq_restore(flags);
-}
-
-
-/* PowerSurge-style Macs */
-struct smp_ops_t psurge_smp_ops = {
- .message_pass = smp_psurge_message_pass,
- .probe = smp_psurge_probe,
- .kick_cpu = smp_psurge_kick_cpu,
- .setup_cpu = smp_psurge_setup_cpu,
- .give_timebase = smp_psurge_give_timebase,
- .take_timebase = smp_psurge_take_timebase,
-};
-
-/* Core99 Macs (dual G4s) */
-struct smp_ops_t core99_smp_ops = {
- .message_pass = smp_openpic_message_pass,
- .probe = smp_core99_probe,
- .kick_cpu = smp_core99_kick_cpu,
- .setup_cpu = smp_core99_setup_cpu,
- .give_timebase = smp_core99_give_timebase,
- .take_timebase = smp_core99_take_timebase,
-};
-
-#ifdef CONFIG_HOTPLUG_CPU
-
-int __cpu_disable(void)
-{
- cpu_clear(smp_processor_id(), cpu_online_map);
-
- /* XXX reset cpu affinity here */
- openpic_set_priority(0xf);
- asm volatile("mtdec %0" : : "r" (0x7fffffff));
- mb();
- udelay(20);
- asm volatile("mtdec %0" : : "r" (0x7fffffff));
- return 0;
-}
-
-extern void low_cpu_die(void) __attribute__((noreturn)); /* in pmac_sleep.S */
-static int cpu_dead[NR_CPUS];
-
-void cpu_die(void)
-{
- local_irq_disable();
- cpu_dead[smp_processor_id()] = 1;
- mb();
- low_cpu_die();
-}
-
-void __cpu_die(unsigned int cpu)
-{
- int timeout;
-
- timeout = 1000;
- while (!cpu_dead[cpu]) {
- if (--timeout == 0) {
- printk("CPU %u refused to die!\n", cpu);
- break;
- }
- msleep(1);
- }
- cpu_callin_map[cpu] = 0;
- cpu_dead[cpu] = 0;
-}
-
-#endif
diff --git a/arch/ppc/platforms/pmac_time.c b/arch/ppc/platforms/pmac_time.c
deleted file mode 100644
index edb9fcc..0000000
--- a/arch/ppc/platforms/pmac_time.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Support for periodic interrupts (100 per second) and for getting
- * the current time from the RTC on Power Macintoshes.
- *
- * We use the decrementer register for our periodic interrupts.
- *
- * Paul Mackerras August 1996.
- * Copyright (C) 1996 Paul Mackerras.
- */
-#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/adb.h>
-#include <linux/cuda.h>
-#include <linux/pmu.h>
-#include <linux/hardirq.h>
-
-#include <asm/sections.h>
-#include <asm/prom.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/machdep.h>
-#include <asm/time.h>
-#include <asm/nvram.h>
-
-/* Apparently the RTC stores seconds since 1 Jan 1904 */
-#define RTC_OFFSET 2082844800
-
-/*
- * Calibrate the decrementer frequency with the VIA timer 1.
- */
-#define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */
-
-/* VIA registers */
-#define RS 0x200 /* skip between registers */
-#define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */
-#define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */
-#define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */
-#define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */
-#define ACR (11*RS) /* Auxiliary control register */
-#define IFR (13*RS) /* Interrupt flag register */
-
-/* Bits in ACR */
-#define T1MODE 0xc0 /* Timer 1 mode */
-#define T1MODE_CONT 0x40 /* continuous interrupts */
-
-/* Bits in IFR and IER */
-#define T1_INT 0x40 /* Timer 1 interrupt */
-
-extern struct timezone sys_tz;
-
-long __init
-pmac_time_init(void)
-{
-#ifdef CONFIG_NVRAM
- s32 delta = 0;
- int dst;
-
- delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16;
- delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8;
- delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb);
- if (delta & 0x00800000UL)
- delta |= 0xFF000000UL;
- dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0);
- printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60,
- dst ? "on" : "off");
- return delta;
-#else
- return 0;
-#endif
-}
-
-unsigned long
-pmac_get_rtc_time(void)
-{
-#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU)
- struct adb_request req;
- unsigned long now;
-#endif
-
- /* Get the time from the RTC */
- switch (sys_ctrler) {
-#ifdef CONFIG_ADB_CUDA
- case SYS_CTRLER_CUDA:
- if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
- return 0;
- while (!req.complete)
- cuda_poll();
- if (req.reply_len != 7)
- printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n",
- req.reply_len);
- now = (req.reply[3] << 24) + (req.reply[4] << 16)
- + (req.reply[5] << 8) + req.reply[6];
- return now - RTC_OFFSET;
-#endif /* CONFIG_ADB_CUDA */
-#ifdef CONFIG_ADB_PMU
- case SYS_CTRLER_PMU:
- if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
- return 0;
- while (!req.complete)
- pmu_poll();
- if (req.reply_len != 4)
- printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n",
- req.reply_len);
- now = (req.reply[0] << 24) + (req.reply[1] << 16)
- + (req.reply[2] << 8) + req.reply[3];
- return now - RTC_OFFSET;
-#endif /* CONFIG_ADB_PMU */
- default: ;
- }
- return 0;
-}
-
-int
-pmac_set_rtc_time(unsigned long nowtime)
-{
-#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU)
- struct adb_request req;
-#endif
-
- nowtime += RTC_OFFSET;
-
- switch (sys_ctrler) {
-#ifdef CONFIG_ADB_CUDA
- case SYS_CTRLER_CUDA:
- if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
- nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0)
- return 0;
- while (!req.complete)
- cuda_poll();
- if ((req.reply_len != 3) && (req.reply_len != 7))
- printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n",
- req.reply_len);
- return 1;
-#endif /* CONFIG_ADB_CUDA */
-#ifdef CONFIG_ADB_PMU
- case SYS_CTRLER_PMU:
- if (pmu_request(&req, NULL, 5, PMU_SET_RTC,
- nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0)
- return 0;
- while (!req.complete)
- pmu_poll();
- if (req.reply_len != 0)
- printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n",
- req.reply_len);
- return 1;
-#endif /* CONFIG_ADB_PMU */
- default:
- return 0;
- }
-}
-
-/*
- * Calibrate the decrementer register using VIA timer 1.
- * This is used both on powermacs and CHRP machines.
- */
-int __init
-via_calibrate_decr(void)
-{
- struct device_node *vias;
- volatile unsigned char __iomem *via;
- int count = VIA_TIMER_FREQ_6 / 100;
- unsigned int dstart, dend;
-
- vias = find_devices("via-cuda");
- if (vias == 0)
- vias = find_devices("via-pmu");
- if (vias == 0)
- vias = find_devices("via");
- if (vias == 0 || vias->n_addrs == 0)
- return 0;
- via = ioremap(vias->addrs[0].address, vias->addrs[0].size);
-
- /* set timer 1 for continuous interrupts */
- out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT);
- /* set the counter to a small value */
- out_8(&via[T1CH], 2);
- /* set the latch to `count' */
- out_8(&via[T1LL], count);
- out_8(&via[T1LH], count >> 8);
- /* wait until it hits 0 */
- while ((in_8(&via[IFR]) & T1_INT) == 0)
- ;
- dstart = get_dec();
- /* clear the interrupt & wait until it hits 0 again */
- in_8(&via[T1CL]);
- while ((in_8(&via[IFR]) & T1_INT) == 0)
- ;
- dend = get_dec();
-
- tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100);
- tb_to_us = mulhwu_scale_factor(dstart - dend, 60000);
-
- printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n",
- tb_ticks_per_jiffy, dstart - dend);
-
- iounmap(via);
-
- return 1;
-}
-
-#ifdef CONFIG_PM
-/*
- * Reset the time after a sleep.
- */
-static int
-time_sleep_notify(struct pmu_sleep_notifier *self, int when)
-{
- static unsigned long time_diff;
- unsigned long flags;
- unsigned long seq;
-
- switch (when) {
- case PBOOK_SLEEP_NOW:
- do {
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
- time_diff = xtime.tv_sec - pmac_get_rtc_time();
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
- break;
- case PBOOK_WAKE:
- write_seqlock_irqsave(&xtime_lock, flags);
- xtime.tv_sec = pmac_get_rtc_time() + time_diff;
- xtime.tv_nsec = 0;
- last_rtc_update = xtime.tv_sec;
- write_sequnlock_irqrestore(&xtime_lock, flags);
- break;
- }
- return PBOOK_SLEEP_OK;
-}
-
-static struct pmu_sleep_notifier time_sleep_notifier = {
- time_sleep_notify, SLEEP_LEVEL_MISC,
-};
-#endif /* CONFIG_PM */
-
-/*
- * Query the OF and get the decr frequency.
- * This was taken from the pmac time_init() when merging the prep/pmac
- * time functions.
- */
-void __init
-pmac_calibrate_decr(void)
-{
- struct device_node *cpu;
- unsigned int freq, *fp;
-
-#ifdef CONFIG_PM
- pmu_register_sleep_notifier(&time_sleep_notifier);
-#endif /* CONFIG_PM */
-
- /* We assume MacRISC2 machines have correct device-tree
- * calibration. That's better since the VIA itself seems
- * to be slightly off. --BenH
- */
- if (!machine_is_compatible("MacRISC2") &&
- !machine_is_compatible("MacRISC3") &&
- !machine_is_compatible("MacRISC4"))
- if (via_calibrate_decr())
- return;
-
- /* Special case: QuickSilver G4s seem to have a badly calibrated
- * timebase-frequency in OF, VIA is much better on these. We should
- * probably implement calibration based on the KL timer on these
- * machines anyway... -BenH
- */
- if (machine_is_compatible("PowerMac3,5"))
- if (via_calibrate_decr())
- return;
- /*
- * The cpu node should have a timebase-frequency property
- * to tell us the rate at which the decrementer counts.
- */
- cpu = find_type_devices("cpu");
- if (cpu == 0)
- panic("can't find cpu node in time_init");
- fp = (unsigned int *) get_property(cpu, "timebase-frequency", NULL);
- if (fp == 0)
- panic("can't get cpu timebase frequency");
- freq = *fp;
- printk("time_init: decrementer frequency = %u.%.6u MHz\n",
- freq/1000000, freq%1000000);
- tb_ticks_per_jiffy = freq / HZ;
- tb_to_us = mulhwu_scale_factor(freq, 1000000);
-}
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
index 84ef030..159dcd9 100644
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -39,8 +39,6 @@
ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o
obj-$(CONFIG_PCI_QSPAN) += qspan_pci.o
obj-$(CONFIG_PPC_OF) += prom_init.o prom.o
-obj-$(CONFIG_PPC_PMAC) += open_pic.o
-obj-$(CONFIG_POWER4) += open_pic2.o
obj-$(CONFIG_PPC_CHRP) += open_pic.o
obj-$(CONFIG_PPC_PREP) += open_pic.o todc_time.o
obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o
diff --git a/arch/ppc/syslib/prom.c b/arch/ppc/syslib/prom.c
index af4deac..482f837 100644
--- a/arch/ppc/syslib/prom.c
+++ b/arch/ppc/syslib/prom.c
@@ -70,8 +70,6 @@
struct device_node *dflt_interrupt_controller;
int num_interrupt_controllers;
-int pmac_newworld;
-
extern unsigned int rtas_entry; /* physical pointer */
extern struct device_node *allnodes;
@@ -123,22 +121,13 @@
unsigned long mem = (unsigned long) klimit;
struct device_node *np;
- /* All newworld pmac machines and CHRPs now use the interrupt tree */
+ /* All CHRPs now use the interrupt tree */
for (np = allnodes; np != NULL; np = np->allnext) {
if (get_property(np, "interrupt-parent", NULL)) {
use_of_interrupt_tree = 1;
break;
}
}
- if (_machine == _MACH_Pmac && use_of_interrupt_tree)
- pmac_newworld = 1;
-
-#ifdef CONFIG_BOOTX_TEXT
- if (boot_infos && pmac_newworld) {
- prom_print("WARNING ! BootX/miBoot booting is not supported on this machine\n");
- prom_print(" You should use an Open Firmware bootloader\n");
- }
-#endif /* CONFIG_BOOTX_TEXT */
if (use_of_interrupt_tree) {
/*
@@ -434,16 +423,10 @@
* those machines, we want to offset interrupts from the
* second openpic by 128 -- BenH
*/
- if (_machine != _MACH_Pmac && num_interrupt_controllers > 1
+ if (num_interrupt_controllers > 1
&& ic != NULL
&& get_property(ic, "interrupt-parent", NULL) == NULL)
offset = 16;
- else if (_machine == _MACH_Pmac && num_interrupt_controllers > 1
- && ic != NULL && ic->parent != NULL) {
- char *name = get_property(ic->parent, "name", NULL);
- if (name && !strcmp(name, "u3"))
- offset = 128;
- }
np->intrs[i].line = irq[0] + offset;
if (n > 1)
diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c
index c80177f..4344cbe 100644
--- a/arch/ppc/xmon/start.c
+++ b/arch/ppc/xmon/start.c
@@ -18,7 +18,6 @@
#include <asm/bootx.h>
#include <asm/machdep.h>
#include <asm/errno.h>
-#include <asm/pmac_feature.h>
#include <asm/processor.h>
#include <asm/delay.h>
#include <asm/btext.h>
@@ -27,11 +26,9 @@
unsigned int TXRDY, RXRDY, DLAB;
static int xmon_expect(const char *str, unsigned int timeout);
-static int use_serial;
static int use_screen;
static int via_modem;
static int xmon_use_sccb;
-static struct device_node *channel_node;
#define TB_SPEED 25000000
@@ -112,96 +109,21 @@
#ifdef CONFIG_PPC_MULTIPLATFORM
volatile unsigned char *base;
- if (_machine == _MACH_Pmac) {
- struct device_node *np;
- unsigned long addr;
-#ifdef CONFIG_BOOTX_TEXT
- if (!use_screen && !use_serial
- && !machine_is_compatible("iMac")) {
- /* see if there is a keyboard in the device tree
- with a parent of type "adb" */
- for (np = find_devices("keyboard"); np; np = np->next)
- if (np->parent && np->parent->type
- && strcmp(np->parent->type, "adb") == 0)
- break;
-
- /* needs to be hacked if xmon_printk is to be used
- from within find_via_pmu() */
-#ifdef CONFIG_ADB_PMU
- if (np != NULL && boot_text_mapped && find_via_pmu())
- use_screen = 1;
-#endif
-#ifdef CONFIG_ADB_CUDA
- if (np != NULL && boot_text_mapped && find_via_cuda())
- use_screen = 1;
-#endif
- }
- if (!use_screen && (np = find_devices("escc")) != NULL) {
- /*
- * look for the device node for the serial port
- * we're using and see if it says it has a modem
- */
- char *name = xmon_use_sccb? "ch-b": "ch-a";
- char *slots;
- int l;
-
- np = np->child;
- while (np != NULL && strcmp(np->name, name) != 0)
- np = np->sibling;
- if (np != NULL) {
- /* XXX should parse this properly */
- channel_node = np;
- slots = get_property(np, "slot-names", &l);
- if (slots != NULL && l >= 10
- && strcmp(slots+4, "Modem") == 0)
- via_modem = 1;
- }
- }
- btext_drawstring("xmon uses ");
- if (use_screen)
- btext_drawstring("screen and keyboard\n");
- else {
- if (via_modem)
- btext_drawstring("modem on ");
- btext_drawstring(xmon_use_sccb? "printer": "modem");
- btext_drawstring(" port\n");
- }
-
-#endif /* CONFIG_BOOTX_TEXT */
-
-#ifdef CHRP_ESCC
- addr = 0xc1013020;
-#else
- addr = 0xf3013020;
-#endif
- TXRDY = 4;
- RXRDY = 1;
-
- np = find_devices("mac-io");
- if (np && np->n_addrs)
- addr = np->addrs[0].address + 0x13020;
- base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE);
- sccc = base + (addr & ~PAGE_MASK);
- sccd = sccc + 0x10;
-
- }
#ifdef CONFIG_PPC_CHRP
- else {
- base = (volatile unsigned char *) isa_io_base;
- if (_machine == _MACH_chrp)
- base = (volatile unsigned char *)
- ioremap(chrp_find_phys_io_base(), 0x1000);
+ base = (volatile unsigned char *) isa_io_base;
+ if (_machine == _MACH_chrp)
+ base = (volatile unsigned char *)
+ ioremap(chrp_find_phys_io_base(), 0x1000);
- sccc = base + 0x3fd;
- sccd = base + 0x3f8;
- if (xmon_use_sccb) {
- sccc -= 0x100;
- sccd -= 0x100;
- }
- TXRDY = 0x20;
- RXRDY = 1;
- DLAB = 0x80;
+ sccc = base + 0x3fd;
+ sccd = base + 0x3f8;
+ if (xmon_use_sccb) {
+ sccc -= 0x100;
+ sccd -= 0x100;
}
+ TXRDY = 0x20;
+ RXRDY = 1;
+ DLAB = 0x80;
#endif /* CONFIG_PPC_CHRP */
#elif defined(CONFIG_GEMINI)
/* should already be mapped by the kernel boot */
@@ -385,16 +307,6 @@
return *sccd;
}
-static unsigned char scc_inittab[] = {
- 13, 0, /* set baud rate divisor */
- 12, 1,
- 14, 1, /* baud rate gen enable, src=rtxc */
- 11, 0x50, /* clocks = br gen */
- 5, 0xea, /* tx 8 bits, assert DTR & RTS */
- 4, 0x46, /* x16 clock, 1 stop */
- 3, 0xc1, /* rx enable, 8 bits */
-};
-
void
xmon_init_scc(void)
{
@@ -407,43 +319,6 @@
sccd[3] = 3; eieio(); /* LCR = 8N1 */
sccd[1] = 0; eieio(); /* IER = 0 */
}
- else if ( _machine == _MACH_Pmac )
- {
- int i, x;
-
- if (channel_node != 0)
- pmac_call_feature(
- PMAC_FTR_SCC_ENABLE,
- channel_node,
- PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
- printk(KERN_INFO "Serial port locked ON by debugger !\n");
- if (via_modem && channel_node != 0) {
- unsigned int t0;
-
- pmac_call_feature(
- PMAC_FTR_MODEM_ENABLE,
- channel_node, 0, 1);
- printk(KERN_INFO "Modem powered up by debugger !\n");
- t0 = readtb();
- while (readtb() - t0 < 3*TB_SPEED)
- eieio();
- }
- /* use the B channel if requested */
- if (xmon_use_sccb) {
- sccc = (volatile unsigned char *)
- ((unsigned long)sccc & ~0x20);
- sccd = sccc + 0x10;
- }
- for (i = 20000; i != 0; --i) {
- x = *sccc; eieio();
- }
- *sccc = 9; eieio(); /* reset A or B side */
- *sccc = ((unsigned long)sccc & 0x20)? 0x80: 0x40; eieio();
- for (i = 0; i < sizeof(scc_inittab); ++i) {
- *sccc = scc_inittab[i];
- eieio();
- }
- }
scc_initialized = 1;
if (via_modem) {
for (;;) {
@@ -632,19 +507,9 @@
void
xmon_enter(void)
{
-#ifdef CONFIG_ADB_PMU
- if (_machine == _MACH_Pmac) {
- pmu_suspend();
- }
-#endif
}
void
xmon_leave(void)
{
-#ifdef CONFIG_ADB_PMU
- if (_machine == _MACH_Pmac) {
- pmu_resume();
- }
-#endif
}
diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
index 9075a75..bdaf659 100644
--- a/arch/ppc/xmon/xmon.c
+++ b/arch/ppc/xmon/xmon.c
@@ -16,9 +16,6 @@
#include <asm/bootx.h>
#include <asm/machdep.h>
#include <asm/xmon.h>
-#ifdef CONFIG_PMAC_BACKLIGHT
-#include <asm/backlight.h>
-#endif
#include "nonstdio.h"
#include "privinst.h"
@@ -260,16 +257,6 @@
*/
#endif /* CONFIG_SMP */
remove_bpts();
-#ifdef CONFIG_PMAC_BACKLIGHT
- if( setjmp(bus_error_jmp) == 0 ) {
- debugger_fault_handler = handle_fault;
- sync();
- set_backlight_enable(1);
- set_backlight_level(BACKLIGHT_MAX);
- sync();
- }
- debugger_fault_handler = NULL;
-#endif /* CONFIG_PMAC_BACKLIGHT */
cmd = cmds(excp);
if (cmd == 's') {
xmon_trace[smp_processor_id()] = SSTEP;
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c
index 7a1033d..c5ca2dc 100644
--- a/arch/s390/crypto/aes_s390.c
+++ b/arch/s390/crypto/aes_s390.c
@@ -114,80 +114,108 @@
const u8 *in, unsigned int nbytes)
{
struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(AES_BLOCK_SIZE - 1);
switch (sctx->key_len) {
case 16:
- crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in, nbytes);
+ ret = crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
case 24:
- crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in, nbytes);
+ ret = crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
case 32:
- crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in, nbytes);
+ ret = crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
}
- return nbytes & ~(AES_BLOCK_SIZE - 1);
+ return nbytes;
}
static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out,
const u8 *in, unsigned int nbytes)
{
struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(AES_BLOCK_SIZE - 1);
switch (sctx->key_len) {
case 16:
- crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, nbytes);
+ ret = crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
case 24:
- crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, nbytes);
+ ret = crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
case 32:
- crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, nbytes);
+ ret = crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
}
- return nbytes & ~(AES_BLOCK_SIZE - 1);
+ return nbytes;
}
static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out,
const u8 *in, unsigned int nbytes)
{
struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(AES_BLOCK_SIZE - 1);
memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE);
switch (sctx->key_len) {
case 16:
- crypt_s390_kmc(KMC_AES_128_ENCRYPT, &sctx->iv, out, in, nbytes);
+ ret = crypt_s390_kmc(KMC_AES_128_ENCRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
case 24:
- crypt_s390_kmc(KMC_AES_192_ENCRYPT, &sctx->iv, out, in, nbytes);
+ ret = crypt_s390_kmc(KMC_AES_192_ENCRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
case 32:
- crypt_s390_kmc(KMC_AES_256_ENCRYPT, &sctx->iv, out, in, nbytes);
+ ret = crypt_s390_kmc(KMC_AES_256_ENCRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
}
memcpy(desc->info, &sctx->iv, AES_BLOCK_SIZE);
- return nbytes & ~(AES_BLOCK_SIZE - 1);
+ return nbytes;
}
static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out,
const u8 *in, unsigned int nbytes)
{
struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(AES_BLOCK_SIZE - 1);
memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE);
switch (sctx->key_len) {
case 16:
- crypt_s390_kmc(KMC_AES_128_DECRYPT, &sctx->iv, out, in, nbytes);
+ ret = crypt_s390_kmc(KMC_AES_128_DECRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
case 24:
- crypt_s390_kmc(KMC_AES_192_DECRYPT, &sctx->iv, out, in, nbytes);
+ ret = crypt_s390_kmc(KMC_AES_192_DECRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
case 32:
- crypt_s390_kmc(KMC_AES_256_DECRYPT, &sctx->iv, out, in, nbytes);
+ ret = crypt_s390_kmc(KMC_AES_256_DECRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
}
- return nbytes & ~(AES_BLOCK_SIZE - 1);
+ return nbytes;
}
diff --git a/arch/s390/crypto/des_s390.c b/arch/s390/crypto/des_s390.c
index a38bb2a..e3c37aa 100644
--- a/arch/s390/crypto/des_s390.c
+++ b/arch/s390/crypto/des_s390.c
@@ -15,10 +15,8 @@
*/
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <asm/scatterlist.h>
#include <linux/crypto.h>
+
#include "crypt_s390.h"
#include "crypto_des.h"
@@ -46,38 +44,92 @@
u8 key[DES3_192_KEY_SIZE];
};
-static int
-des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
+static int des_setkey(void *ctx, const u8 *key, unsigned int keylen,
+ u32 *flags)
{
- struct crypt_s390_des_ctx *dctx;
+ struct crypt_s390_des_ctx *dctx = ctx;
int ret;
- dctx = ctx;
- //test if key is valid (not a weak key)
+ /* test if key is valid (not a weak key) */
ret = crypto_des_check_key(key, keylen, flags);
- if (ret == 0){
+ if (ret == 0)
memcpy(dctx->key, key, keylen);
- }
return ret;
}
-
-static void
-des_encrypt(void *ctx, u8 *dst, const u8 *src)
+static void des_encrypt(void *ctx, u8 *out, const u8 *in)
{
- struct crypt_s390_des_ctx *dctx;
+ struct crypt_s390_des_ctx *dctx = ctx;
- dctx = ctx;
- crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, dst, src, DES_BLOCK_SIZE);
+ crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, out, in, DES_BLOCK_SIZE);
}
-static void
-des_decrypt(void *ctx, u8 *dst, const u8 *src)
+static void des_decrypt(void *ctx, u8 *out, const u8 *in)
{
- struct crypt_s390_des_ctx *dctx;
+ struct crypt_s390_des_ctx *dctx = ctx;
- dctx = ctx;
- crypt_s390_km(KM_DEA_DECRYPT, dctx->key, dst, src, DES_BLOCK_SIZE);
+ crypt_s390_km(KM_DEA_DECRYPT, dctx->key, out, in, DES_BLOCK_SIZE);
+}
+
+static unsigned int des_encrypt_ecb(const struct cipher_desc *desc, u8 *out,
+ const u8 *in, unsigned int nbytes)
+{
+ struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES_BLOCK_SIZE - 1);
+ ret = crypt_s390_km(KM_DEA_ENCRYPT, sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ return nbytes;
+}
+
+static unsigned int des_decrypt_ecb(const struct cipher_desc *desc, u8 *out,
+ const u8 *in, unsigned int nbytes)
+{
+ struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES_BLOCK_SIZE - 1);
+ ret = crypt_s390_km(KM_DEA_DECRYPT, sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ return nbytes;
+}
+
+static unsigned int des_encrypt_cbc(const struct cipher_desc *desc, u8 *out,
+ const u8 *in, unsigned int nbytes)
+{
+ struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES_BLOCK_SIZE - 1);
+
+ memcpy(sctx->iv, desc->info, DES_BLOCK_SIZE);
+ ret = crypt_s390_kmc(KMC_DEA_ENCRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ memcpy(desc->info, sctx->iv, DES_BLOCK_SIZE);
+ return nbytes;
+}
+
+static unsigned int des_decrypt_cbc(const struct cipher_desc *desc, u8 *out,
+ const u8 *in, unsigned int nbytes)
+{
+ struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES_BLOCK_SIZE - 1);
+
+ memcpy(&sctx->iv, desc->info, DES_BLOCK_SIZE);
+ ret = crypt_s390_kmc(KMC_DEA_DECRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ return nbytes;
}
static struct crypto_alg des_alg = {
@@ -87,12 +139,19 @@
.cra_ctxsize = sizeof(struct crypt_s390_des_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(des_alg.cra_list),
- .cra_u = { .cipher = {
- .cia_min_keysize = DES_KEY_SIZE,
- .cia_max_keysize = DES_KEY_SIZE,
- .cia_setkey = des_setkey,
- .cia_encrypt = des_encrypt,
- .cia_decrypt = des_decrypt } }
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = DES_KEY_SIZE,
+ .cia_max_keysize = DES_KEY_SIZE,
+ .cia_setkey = des_setkey,
+ .cia_encrypt = des_encrypt,
+ .cia_decrypt = des_decrypt,
+ .cia_encrypt_ecb = des_encrypt_ecb,
+ .cia_decrypt_ecb = des_decrypt_ecb,
+ .cia_encrypt_cbc = des_encrypt_cbc,
+ .cia_decrypt_cbc = des_decrypt_cbc,
+ }
+ }
};
/*
@@ -107,20 +166,18 @@
* Implementers MUST reject keys that exhibit this property.
*
*/
-static int
-des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
+static int des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen,
+ u32 *flags)
{
int i, ret;
- struct crypt_s390_des3_128_ctx *dctx;
+ struct crypt_s390_des3_128_ctx *dctx = ctx;
const u8* temp_key = key;
- dctx = ctx;
if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) {
-
*flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
return -EINVAL;
}
- for (i = 0; i < 2; i++, temp_key += DES_KEY_SIZE) {
+ for (i = 0; i < 2; i++, temp_key += DES_KEY_SIZE) {
ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags);
if (ret < 0)
return ret;
@@ -129,24 +186,85 @@
return 0;
}
-static void
-des3_128_encrypt(void *ctx, u8 *dst, const u8 *src)
+static void des3_128_encrypt(void *ctx, u8 *dst, const u8 *src)
{
- struct crypt_s390_des3_128_ctx *dctx;
+ struct crypt_s390_des3_128_ctx *dctx = ctx;
- dctx = ctx;
crypt_s390_km(KM_TDEA_128_ENCRYPT, dctx->key, dst, (void*)src,
- DES3_128_BLOCK_SIZE);
+ DES3_128_BLOCK_SIZE);
}
-static void
-des3_128_decrypt(void *ctx, u8 *dst, const u8 *src)
+static void des3_128_decrypt(void *ctx, u8 *dst, const u8 *src)
{
- struct crypt_s390_des3_128_ctx *dctx;
+ struct crypt_s390_des3_128_ctx *dctx = ctx;
- dctx = ctx;
crypt_s390_km(KM_TDEA_128_DECRYPT, dctx->key, dst, (void*)src,
- DES3_128_BLOCK_SIZE);
+ DES3_128_BLOCK_SIZE);
+}
+
+static unsigned int des3_128_encrypt_ecb(const struct cipher_desc *desc,
+ u8 *out, const u8 *in,
+ unsigned int nbytes)
+{
+ struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
+ ret = crypt_s390_km(KM_TDEA_128_ENCRYPT, sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ return nbytes;
+}
+
+static unsigned int des3_128_decrypt_ecb(const struct cipher_desc *desc,
+ u8 *out, const u8 *in,
+ unsigned int nbytes)
+{
+ struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
+ ret = crypt_s390_km(KM_TDEA_128_DECRYPT, sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ return nbytes;
+}
+
+static unsigned int des3_128_encrypt_cbc(const struct cipher_desc *desc,
+ u8 *out, const u8 *in,
+ unsigned int nbytes)
+{
+ struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
+
+ memcpy(sctx->iv, desc->info, DES3_128_BLOCK_SIZE);
+ ret = crypt_s390_kmc(KMC_TDEA_128_ENCRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ memcpy(desc->info, sctx->iv, DES3_128_BLOCK_SIZE);
+ return nbytes;
+}
+
+static unsigned int des3_128_decrypt_cbc(const struct cipher_desc *desc,
+ u8 *out, const u8 *in,
+ unsigned int nbytes)
+{
+ struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
+
+ memcpy(&sctx->iv, desc->info, DES3_128_BLOCK_SIZE);
+ ret = crypt_s390_kmc(KMC_TDEA_128_DECRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ return nbytes;
}
static struct crypto_alg des3_128_alg = {
@@ -156,12 +274,19 @@
.cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(des3_128_alg.cra_list),
- .cra_u = { .cipher = {
- .cia_min_keysize = DES3_128_KEY_SIZE,
- .cia_max_keysize = DES3_128_KEY_SIZE,
- .cia_setkey = des3_128_setkey,
- .cia_encrypt = des3_128_encrypt,
- .cia_decrypt = des3_128_decrypt } }
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = DES3_128_KEY_SIZE,
+ .cia_max_keysize = DES3_128_KEY_SIZE,
+ .cia_setkey = des3_128_setkey,
+ .cia_encrypt = des3_128_encrypt,
+ .cia_decrypt = des3_128_decrypt,
+ .cia_encrypt_ecb = des3_128_encrypt_ecb,
+ .cia_decrypt_ecb = des3_128_decrypt_ecb,
+ .cia_encrypt_cbc = des3_128_encrypt_cbc,
+ .cia_decrypt_cbc = des3_128_decrypt_cbc,
+ }
+ }
};
/*
@@ -177,50 +302,108 @@
* property.
*
*/
-static int
-des3_192_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
+static int des3_192_setkey(void *ctx, const u8 *key, unsigned int keylen,
+ u32 *flags)
{
int i, ret;
- struct crypt_s390_des3_192_ctx *dctx;
- const u8* temp_key;
+ struct crypt_s390_des3_192_ctx *dctx = ctx;
+ const u8* temp_key = key;
- dctx = ctx;
- temp_key = key;
if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) &&
memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
- DES_KEY_SIZE))) {
+ DES_KEY_SIZE))) {
*flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
return -EINVAL;
}
for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) {
ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags);
- if (ret < 0){
+ if (ret < 0)
return ret;
- }
}
memcpy(dctx->key, key, keylen);
return 0;
}
-static void
-des3_192_encrypt(void *ctx, u8 *dst, const u8 *src)
+static void des3_192_encrypt(void *ctx, u8 *dst, const u8 *src)
{
- struct crypt_s390_des3_192_ctx *dctx;
+ struct crypt_s390_des3_192_ctx *dctx = ctx;
- dctx = ctx;
crypt_s390_km(KM_TDEA_192_ENCRYPT, dctx->key, dst, (void*)src,
- DES3_192_BLOCK_SIZE);
+ DES3_192_BLOCK_SIZE);
}
-static void
-des3_192_decrypt(void *ctx, u8 *dst, const u8 *src)
+static void des3_192_decrypt(void *ctx, u8 *dst, const u8 *src)
{
- struct crypt_s390_des3_192_ctx *dctx;
+ struct crypt_s390_des3_192_ctx *dctx = ctx;
- dctx = ctx;
crypt_s390_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src,
- DES3_192_BLOCK_SIZE);
+ DES3_192_BLOCK_SIZE);
+}
+
+static unsigned int des3_192_encrypt_ecb(const struct cipher_desc *desc,
+ u8 *out, const u8 *in,
+ unsigned int nbytes)
+{
+ struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
+ ret = crypt_s390_km(KM_TDEA_192_ENCRYPT, sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ return nbytes;
+}
+
+static unsigned int des3_192_decrypt_ecb(const struct cipher_desc *desc,
+ u8 *out, const u8 *in,
+ unsigned int nbytes)
+{
+ struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
+ ret = crypt_s390_km(KM_TDEA_192_DECRYPT, sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ return nbytes;
+}
+
+static unsigned int des3_192_encrypt_cbc(const struct cipher_desc *desc,
+ u8 *out, const u8 *in,
+ unsigned int nbytes)
+{
+ struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
+
+ memcpy(sctx->iv, desc->info, DES3_192_BLOCK_SIZE);
+ ret = crypt_s390_kmc(KMC_TDEA_192_ENCRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ memcpy(desc->info, sctx->iv, DES3_192_BLOCK_SIZE);
+ return nbytes;
+}
+
+static unsigned int des3_192_decrypt_cbc(const struct cipher_desc *desc,
+ u8 *out, const u8 *in,
+ unsigned int nbytes)
+{
+ struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
+
+ memcpy(&sctx->iv, desc->info, DES3_192_BLOCK_SIZE);
+ ret = crypt_s390_kmc(KMC_TDEA_192_DECRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ return nbytes;
}
static struct crypto_alg des3_192_alg = {
@@ -230,44 +413,43 @@
.cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(des3_192_alg.cra_list),
- .cra_u = { .cipher = {
- .cia_min_keysize = DES3_192_KEY_SIZE,
- .cia_max_keysize = DES3_192_KEY_SIZE,
- .cia_setkey = des3_192_setkey,
- .cia_encrypt = des3_192_encrypt,
- .cia_decrypt = des3_192_decrypt } }
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = DES3_192_KEY_SIZE,
+ .cia_max_keysize = DES3_192_KEY_SIZE,
+ .cia_setkey = des3_192_setkey,
+ .cia_encrypt = des3_192_encrypt,
+ .cia_decrypt = des3_192_decrypt,
+ .cia_encrypt_ecb = des3_192_encrypt_ecb,
+ .cia_decrypt_ecb = des3_192_decrypt_ecb,
+ .cia_encrypt_cbc = des3_192_encrypt_cbc,
+ .cia_decrypt_cbc = des3_192_decrypt_cbc,
+ }
+ }
};
-
-
-static int
-init(void)
+static int init(void)
{
- int ret;
+ int ret = 0;
if (!crypt_s390_func_available(KM_DEA_ENCRYPT) ||
!crypt_s390_func_available(KM_TDEA_128_ENCRYPT) ||
- !crypt_s390_func_available(KM_TDEA_192_ENCRYPT)){
+ !crypt_s390_func_available(KM_TDEA_192_ENCRYPT))
return -ENOSYS;
- }
- ret = 0;
- ret |= (crypto_register_alg(&des_alg) == 0)? 0:1;
- ret |= (crypto_register_alg(&des3_128_alg) == 0)? 0:2;
- ret |= (crypto_register_alg(&des3_192_alg) == 0)? 0:4;
- if (ret){
+ ret |= (crypto_register_alg(&des_alg) == 0) ? 0:1;
+ ret |= (crypto_register_alg(&des3_128_alg) == 0) ? 0:2;
+ ret |= (crypto_register_alg(&des3_192_alg) == 0) ? 0:4;
+ if (ret) {
crypto_unregister_alg(&des3_192_alg);
crypto_unregister_alg(&des3_128_alg);
crypto_unregister_alg(&des_alg);
return -EEXIST;
}
-
- printk(KERN_INFO "crypt_s390: des_s390 loaded.\n");
return 0;
}
-static void __exit
-fini(void)
+static void __exit fini(void)
{
crypto_unregister_alg(&des3_192_alg);
crypto_unregister_alg(&des3_128_alg);
diff --git a/arch/s390/crypto/sha256_s390.c b/arch/s390/crypto/sha256_s390.c
index b75bdbd..1ec5e92 100644
--- a/arch/s390/crypto/sha256_s390.c
+++ b/arch/s390/crypto/sha256_s390.c
@@ -51,6 +51,7 @@
{
struct s390_sha256_ctx *sctx = ctx;
unsigned int index;
+ int ret;
/* how much is already in the buffer? */
index = sctx->count / 8 & 0x3f;
@@ -58,15 +59,29 @@
/* update message bit length */
sctx->count += len * 8;
- /* process one block */
- if ((index + len) >= SHA256_BLOCK_SIZE) {
+ if ((index + len) < SHA256_BLOCK_SIZE)
+ goto store;
+
+ /* process one stored block */
+ if (index) {
memcpy(sctx->buf + index, data, SHA256_BLOCK_SIZE - index);
- crypt_s390_kimd(KIMD_SHA_256, sctx->state, sctx->buf,
- SHA256_BLOCK_SIZE);
+ ret = crypt_s390_kimd(KIMD_SHA_256, sctx->state, sctx->buf,
+ SHA256_BLOCK_SIZE);
+ BUG_ON(ret != SHA256_BLOCK_SIZE);
data += SHA256_BLOCK_SIZE - index;
len -= SHA256_BLOCK_SIZE - index;
}
+ /* process as many blocks as possible */
+ if (len >= SHA256_BLOCK_SIZE) {
+ ret = crypt_s390_kimd(KIMD_SHA_256, sctx->state, data,
+ len & ~(SHA256_BLOCK_SIZE - 1));
+ BUG_ON(ret != (len & ~(SHA256_BLOCK_SIZE - 1)));
+ data += ret;
+ len -= ret;
+ }
+
+store:
/* anything left? */
if (len)
memcpy(sctx->buf + index , data, len);
@@ -119,9 +134,9 @@
.cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_u = { .digest = {
.dia_digestsize = SHA256_DIGEST_SIZE,
- .dia_init = sha256_init,
- .dia_update = sha256_update,
- .dia_final = sha256_final } }
+ .dia_init = sha256_init,
+ .dia_update = sha256_update,
+ .dia_final = sha256_final } }
};
static int init(void)
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 2ff90a1..008c745 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -58,10 +58,18 @@
*/
unsigned long thread_saved_pc(struct task_struct *tsk)
{
- struct stack_frame *sf;
+ struct stack_frame *sf, *low, *high;
- sf = (struct stack_frame *) tsk->thread.ksp;
- sf = (struct stack_frame *) sf->back_chain;
+ if (!tsk || !task_stack_page(tsk))
+ return 0;
+ low = task_stack_page(tsk);
+ high = (struct stack_frame *) task_pt_regs(tsk);
+ sf = (struct stack_frame *) (tsk->thread.ksp & PSW_ADDR_INSN);
+ if (sf <= low || sf > high)
+ return 0;
+ sf = (struct stack_frame *) (sf->back_chain & PSW_ADDR_INSN);
+ if (sf <= low || sf > high)
+ return 0;
return sf->gprs[8];
}
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index b03847d..de87842 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -268,7 +268,7 @@
reipl_diag();
if (MACHINE_IS_VM)
- cpcmd ("IPL", NULL, 0);
+ cpcmd ("IPL", NULL, 0, NULL);
else
reipl (0x10000 | S390_lowcore.ipl_device);
}
@@ -276,14 +276,14 @@
static void do_machine_halt_nonsmp(void)
{
if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0)
- cpcmd(vmhalt_cmd, NULL, 0);
+ cpcmd(vmhalt_cmd, NULL, 0, NULL);
signal_processor(smp_processor_id(), sigp_stop_and_store_status);
}
static void do_machine_power_off_nonsmp(void)
{
if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
- cpcmd(vmpoff_cmd, NULL, 0);
+ cpcmd(vmpoff_cmd, NULL, 0, NULL);
signal_processor(smp_processor_id(), sigp_stop_and_store_status);
}
@@ -315,6 +315,11 @@
_machine_power_off();
}
+/*
+ * Dummy power off function.
+ */
+void (*pm_power_off)(void) = machine_power_off;
+
static void __init
add_memory_hole(unsigned long start, unsigned long end)
{
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index b0d8ca8..7c0fe15 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -214,7 +214,7 @@
#endif
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- account_user_vtime(current);
+ account_tick_vtime(current);
#else
while (ticks--)
update_process_times(user_mode(regs));
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 22a895e..dfe6f08 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -32,7 +32,7 @@
* Update process times based on virtual cpu times stored by entry.S
* to the lowcore fields user_timer, system_timer & steal_clock.
*/
-void account_user_vtime(struct task_struct *tsk)
+void account_tick_vtime(struct task_struct *tsk)
{
cputime_t cputime;
__u64 timer, clock;
@@ -76,6 +76,31 @@
* Update process times based on virtual cpu times stored by entry.S
* to the lowcore fields user_timer, system_timer & steal_clock.
*/
+void account_vtime(struct task_struct *tsk)
+{
+ cputime_t cputime;
+ __u64 timer;
+
+ timer = S390_lowcore.last_update_timer;
+ asm volatile (" STPT %0" /* Store current cpu timer value */
+ : "=m" (S390_lowcore.last_update_timer) );
+ S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer;
+
+ cputime = S390_lowcore.user_timer >> 12;
+ S390_lowcore.user_timer -= cputime << 12;
+ S390_lowcore.steal_clock -= cputime << 12;
+ account_user_time(tsk, cputime);
+
+ cputime = S390_lowcore.system_timer >> 12;
+ S390_lowcore.system_timer -= cputime << 12;
+ S390_lowcore.steal_clock -= cputime << 12;
+ account_system_time(tsk, 0, cputime);
+}
+
+/*
+ * Update process times based on virtual cpu times stored by entry.S
+ * to the lowcore fields user_timer, system_timer & steal_clock.
+ */
void account_system_vtime(struct task_struct *tsk)
{
cputime_t cputime;
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index d9b97b3..f20b51ff 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -4,5 +4,6 @@
EXTRA_AFLAGS := -traditional
-lib-y += delay.o string.o spinlock.o
+lib-y += delay.o string.o
lib-y += $(if $(CONFIG_64BIT),uaccess64.o,uaccess.o)
+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 68d79c5..60f80a4 100644
--- a/arch/s390/lib/spinlock.c
+++ b/arch/s390/lib/spinlock.c
@@ -13,7 +13,6 @@
#include <linux/init.h>
#include <asm/io.h>
-atomic_t spin_retry_counter;
int spin_retry = 1000;
/**
@@ -45,7 +44,6 @@
_diag44();
count = spin_retry;
}
- atomic_inc(&spin_retry_counter);
if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0)
return;
}
@@ -58,7 +56,6 @@
int count = spin_retry;
while (count-- > 0) {
- atomic_inc(&spin_retry_counter);
if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0)
return 1;
}
@@ -77,7 +74,6 @@
_diag44();
count = spin_retry;
}
- atomic_inc(&spin_retry_counter);
old = rw->lock & 0x7fffffffU;
if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old)
return;
@@ -92,7 +88,6 @@
int count = spin_retry;
while (count-- > 0) {
- atomic_inc(&spin_retry_counter);
old = rw->lock & 0x7fffffffU;
if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old)
return 1;
@@ -111,7 +106,6 @@
_diag44();
count = spin_retry;
}
- atomic_inc(&spin_retry_counter);
if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)
return;
}
@@ -124,7 +118,6 @@
int count = spin_retry;
while (count-- > 0) {
- atomic_inc(&spin_retry_counter);
if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)
return 1;
}
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 322972fd..45435ff 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -67,7 +67,8 @@
# in CFLAGS. Otherwise, it would cause ld to complain about the two different
# errnos.
-CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask
+CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \
+ -Dmktime=kernel_mktime
CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
diff --git a/block/genhd.c b/block/genhd.c
index f1ed83f..db57546 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -38,34 +38,100 @@
return major % MAX_PROBE_HASH;
}
-#ifdef CONFIG_PROC_FS
-/* get block device names in somewhat random order */
-int get_blkdev_list(char *p, int used)
+struct blkdev_info {
+ int index;
+ struct blk_major_name *bd;
+};
+
+/*
+ * iterate over a list of blkdev_info structures. allows
+ * the major_names array to be iterated over from outside this file
+ * must be called with the block_subsys_sem held
+ */
+void *get_next_blkdev(void *dev)
+{
+ struct blkdev_info *info;
+
+ if (dev == NULL) {
+ info = kmalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ goto out;
+ info->index=0;
+ info->bd = major_names[info->index];
+ if (info->bd)
+ goto out;
+ } else {
+ info = dev;
+ }
+
+ while (info->index < ARRAY_SIZE(major_names)) {
+ if (info->bd)
+ info->bd = info->bd->next;
+ if (info->bd)
+ goto out;
+ /*
+ * No devices on this chain, move to the next
+ */
+ info->index++;
+ info->bd = (info->index < ARRAY_SIZE(major_names)) ?
+ major_names[info->index] : NULL;
+ if (info->bd)
+ goto out;
+ }
+
+out:
+ return info;
+}
+
+void *acquire_blkdev_list(void)
+{
+ down(&block_subsys_sem);
+ return get_next_blkdev(NULL);
+}
+
+void release_blkdev_list(void *dev)
+{
+ up(&block_subsys_sem);
+ kfree(dev);
+}
+
+
+/*
+ * Count the number of records in the blkdev_list.
+ * must be called with the block_subsys_sem held
+ */
+int count_blkdev_list(void)
{
struct blk_major_name *n;
- int i, len;
+ int i, count;
- len = snprintf(p, (PAGE_SIZE-used), "\nBlock devices:\n");
+ count = 0;
- down(&block_subsys_sem);
for (i = 0; i < ARRAY_SIZE(major_names); i++) {
- for (n = major_names[i]; n; n = n->next) {
- /*
- * If the curent string plus the 5 extra characters
- * in the line would run us off the page, then we're done
- */
- if ((len + used + strlen(n->name) + 5) >= PAGE_SIZE)
- goto page_full;
- len += sprintf(p+len, "%3d %s\n",
- n->major, n->name);
- }
+ for (n = major_names[i]; n; n = n->next)
+ count++;
}
-page_full:
- up(&block_subsys_sem);
- return len;
+ return count;
}
-#endif
+
+/*
+ * extract the major and name values from a blkdev_info struct
+ * passed in as a void to *dev. Must be called with
+ * block_subsys_sem held
+ */
+int get_blkdev_info(void *dev, int *major, char **name)
+{
+ struct blkdev_info *info = dev;
+
+ if (info->bd == NULL)
+ return 1;
+
+ *major = info->bd->major;
+ *name = info->bd->name;
+ return 0;
+}
+
int register_blkdev(unsigned int major, const char *name)
{
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 7e1a445..3758b55 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -153,7 +153,7 @@
Transaction Management
-------------------------------------------------------------------------- */
-static inline u32 acpi_ec_read_status(union acpi_ec *ec)
+static u32 acpi_ec_read_status(union acpi_ec *ec)
{
u32 status = 0;
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 3d384e3..e97e911 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -48,7 +48,7 @@
struct timer_list timeout;
};
-static inline void
+static void
fw_load_abort(struct firmware_priv *fw_priv)
{
set_bit(FW_STATUS_ABORT, &fw_priv->status);
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 8647290..5f6d1a5 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -294,7 +294,7 @@
* This helper just factors out common code between do_lo_send_direct_write()
* and do_lo_send_write().
*/
-static inline int __do_lo_send_write(struct file *file,
+static int __do_lo_send_write(struct file *file,
u8 __user *buf, const int len, loff_t pos)
{
ssize_t bw;
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 51b7a5c..93affee 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -247,7 +247,7 @@
return rb_entry(n, struct pkt_rb_node, rb_node);
}
-static inline void pkt_rbtree_erase(struct pktcdvd_device *pd, struct pkt_rb_node *node)
+static void pkt_rbtree_erase(struct pktcdvd_device *pd, struct pkt_rb_node *node)
{
rb_erase(&node->rb_node, &pd->bio_queue);
mempool_free(node, pd->rb_pool);
@@ -315,7 +315,7 @@
/*
* Add a bio to a single linked list defined by its head and tail pointers.
*/
-static inline void pkt_add_list_last(struct bio *bio, struct bio **list_head, struct bio **list_tail)
+static void pkt_add_list_last(struct bio *bio, struct bio **list_head, struct bio **list_tail)
{
bio->bi_next = NULL;
if (*list_tail) {
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index 8fddfdf..7bd4ef9 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -494,7 +494,7 @@
}
}
-static inline void bcsp_complete_rx_pkt(struct hci_uart *hu)
+static void bcsp_complete_rx_pkt(struct hci_uart *hu)
{
struct bcsp_struct *bcsp = hu->priv;
int pass_up;
diff --git a/drivers/char/drm/r128_state.c b/drivers/char/drm/r128_state.c
index caeecc2..a080cdd 100644
--- a/drivers/char/drm/r128_state.c
+++ b/drivers/char/drm/r128_state.c
@@ -220,7 +220,7 @@
ADVANCE_RING();
}
-static __inline__ void r128_emit_state(drm_r128_private_t * dev_priv)
+static void r128_emit_state(drm_r128_private_t * dev_priv)
{
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int dirty = sarea_priv->dirty;
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
index a654479..c0dfcf2 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -395,12 +395,38 @@
To compile this driver as a module, choose M here: the
module will be called machzwd.
+config SBC_EPX_C3_WATCHDOG
+ tristate "Winsystems SBC EPX-C3 watchdog"
+ depends on WATCHDOG && X86
+ ---help---
+ This is the driver for the built-in watchdog timer on the EPX-C3
+ Single-board computer made by Winsystems, Inc.
+
+ *Note*: This hardware watchdog is not probeable and thus there
+ is no way to know if writing to its IO address will corrupt
+ your system or have any real effect. The only way to be sure
+ that this driver does what you want is to make sure you
+ are runnning it on an EPX-C3 from Winsystems with the watchdog
+ timer at IO address 0x1ee and 0x1ef. It will write to both those
+ IO ports. Basically, the assumption is made that if you compile
+ this driver into your kernel and/or load it as a module, that you
+ know what you are doing and that you are in fact running on an
+ EPX-C3 board!
+
+ To compile this driver as a module, choose M here: the
+ module will be called sbc_epx_c3.
+
+
# PowerPC Architecture
config 8xx_WDT
tristate "MPC8xx Watchdog Timer"
depends on WATCHDOG && 8xx
+config 83xx_WDT
+ tristate "MPC83xx Watchdog Timer"
+ depends on WATCHDOG && PPC_83xx
+
config MV64X60_WDT
tristate "MV64X60 (Marvell Discovery) Watchdog Timer"
depends on WATCHDOG && MV64X60
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
index cfd0a39..36c0b28 100644
--- a/drivers/char/watchdog/Makefile
+++ b/drivers/char/watchdog/Makefile
@@ -52,9 +52,11 @@
obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o
obj-$(CONFIG_W83977F_WDT) += w83977f_wdt.o
obj-$(CONFIG_MACHZ_WDT) += machzwd.o
+obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o
# PowerPC Architecture
obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
+obj-$(CONFIG_83xx_WDT) += mpc83xx_wdt.o
obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o
obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o
diff --git a/drivers/char/watchdog/mpc83xx_wdt.c b/drivers/char/watchdog/mpc83xx_wdt.c
new file mode 100644
index 0000000..5d6f506
--- /dev/null
+++ b/drivers/char/watchdog/mpc83xx_wdt.c
@@ -0,0 +1,229 @@
+/*
+ * mpc83xx_wdt.c - MPC83xx watchdog userspace interface
+ *
+ * Authors: Dave Updegraff <dave@cray.org>
+ * Kumar Gala <galak@kernel.crashing.org>
+ * Attribution: from 83xx_wst: Florian Schirmer <jolt@tuxbox.org>
+ * ..and from sc520_wdt
+ *
+ * Note: it appears that you can only actually ENABLE or DISABLE the thing
+ * once after POR. Once enabled, you cannot disable, and vice versa.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/watchdog.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+struct mpc83xx_wdt {
+ __be32 res0;
+ __be32 swcrr; /* System watchdog control register */
+#define SWCRR_SWTC 0xFFFF0000 /* Software Watchdog Time Count. */
+#define SWCRR_SWEN 0x00000004 /* Watchdog Enable bit. */
+#define SWCRR_SWRI 0x00000002 /* Software Watchdog Reset/Interrupt Select bit.*/
+#define SWCRR_SWPR 0x00000001 /* Software Watchdog Counter Prescale bit. */
+ __be32 swcnr; /* System watchdog count register */
+ u8 res1[2];
+ __be16 swsrr; /* System watchdog service register */
+ u8 res2[0xF0];
+};
+
+static struct mpc83xx_wdt __iomem *wd_base;
+
+static u16 timeout = 0xffff;
+module_param(timeout, ushort, 0);
+MODULE_PARM_DESC(timeout, "Watchdog timeout in ticks. (0<timeout<65536, default=65535");
+
+static int reset = 1;
+module_param(reset, bool, 0);
+MODULE_PARM_DESC(reset, "Watchdog Interrupt/Reset Mode. 0 = interrupt, 1 = reset");
+
+/*
+ * We always prescale, but if someone really doesn't want to they can set this
+ * to 0
+ */
+static int prescale = 1;
+static unsigned int timeout_sec;
+
+static unsigned long wdt_is_open;
+static spinlock_t wdt_spinlock;
+
+static void mpc83xx_wdt_keepalive(void)
+{
+ /* Ping the WDT */
+ spin_lock(&wdt_spinlock);
+ out_be16(&wd_base->swsrr, 0x556c);
+ out_be16(&wd_base->swsrr, 0xaa39);
+ spin_unlock(&wdt_spinlock);
+}
+
+static ssize_t mpc83xx_wdt_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ if (count)
+ mpc83xx_wdt_keepalive();
+ return count;
+}
+
+static int mpc83xx_wdt_open(struct inode *inode, struct file *file)
+{
+ u32 tmp = SWCRR_SWEN;
+ if (test_and_set_bit(0, &wdt_is_open))
+ return -EBUSY;
+
+ /* Once we start the watchdog we can't stop it */
+ __module_get(THIS_MODULE);
+
+ /* Good, fire up the show */
+ if (prescale)
+ tmp |= SWCRR_SWPR;
+ if (reset)
+ tmp |= SWCRR_SWRI;
+
+ tmp |= timeout << 16;
+
+ out_be32(&wd_base->swcrr, tmp);
+
+ return nonseekable_open(inode, file);
+}
+
+static int mpc83xx_wdt_release(struct inode *inode, struct file *file)
+{
+ printk(KERN_CRIT "Unexpected close, not stopping watchdog!\n");
+ mpc83xx_wdt_keepalive();
+ clear_bit(0, &wdt_is_open);
+ return 0;
+}
+
+static int mpc83xx_wdt_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
+ static struct watchdog_info ident = {
+ .options = WDIOF_KEEPALIVEPING,
+ .firmware_version = 1,
+ .identity = "MPC83xx",
+ };
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
+ case WDIOC_KEEPALIVE:
+ mpc83xx_wdt_keepalive();
+ return 0;
+ case WDIOC_GETTIMEOUT:
+ return put_user(timeout_sec, p);
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
+static struct file_operations mpc83xx_wdt_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = mpc83xx_wdt_write,
+ .ioctl = mpc83xx_wdt_ioctl,
+ .open = mpc83xx_wdt_open,
+ .release = mpc83xx_wdt_release,
+};
+
+static struct miscdevice mpc83xx_wdt_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &mpc83xx_wdt_fops,
+};
+
+static int __devinit mpc83xx_wdt_probe(struct platform_device *dev)
+{
+ struct resource *r;
+ int ret;
+ unsigned int *freq = dev->dev.platform_data;
+
+ /* get a pointer to the register memory */
+ r = platform_get_resource(dev, IORESOURCE_MEM, 0);
+
+ if (!r) {
+ ret = -ENODEV;
+ goto err_out;
+ }
+
+ wd_base = ioremap(r->start, sizeof (struct mpc83xx_wdt));
+
+ if (wd_base == NULL) {
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ ret = misc_register(&mpc83xx_wdt_miscdev);
+ if (ret) {
+ printk(KERN_ERR "cannot register miscdev on minor=%d "
+ "(err=%d)\n",
+ WATCHDOG_MINOR, ret);
+ goto err_unmap;
+ }
+
+ /* Calculate the timeout in seconds */
+ if (prescale)
+ timeout_sec = (timeout * 0x10000) / (*freq);
+ else
+ timeout_sec = timeout / (*freq);
+
+ printk(KERN_INFO "WDT driver for MPC83xx initialized. "
+ "mode:%s timeout=%d (%d seconds)\n",
+ reset ? "reset":"interrupt", timeout, timeout_sec);
+
+ spin_lock_init(&wdt_spinlock);
+
+ return 0;
+
+err_unmap:
+ iounmap(wd_base);
+err_out:
+ return ret;
+}
+
+static int __devexit mpc83xx_wdt_remove(struct platform_device *dev)
+{
+ misc_deregister(&mpc83xx_wdt_miscdev);
+ iounmap(wd_base);
+
+ return 0;
+}
+
+static struct platform_driver mpc83xx_wdt_driver = {
+ .probe = mpc83xx_wdt_probe,
+ .remove = __devexit_p(mpc83xx_wdt_remove),
+ .driver = {
+ .name = "mpc83xx_wdt",
+ },
+};
+
+static int __init mpc83xx_wdt_init(void)
+{
+ return platform_driver_register(&mpc83xx_wdt_driver);
+}
+
+static void __exit mpc83xx_wdt_exit(void)
+{
+ platform_driver_unregister(&mpc83xx_wdt_driver);
+}
+
+module_init(mpc83xx_wdt_init);
+module_exit(mpc83xx_wdt_exit);
+
+MODULE_AUTHOR("Dave Updegraff, Kumar Gala");
+MODULE_DESCRIPTION("Driver for watchdog timer in MPC83xx uProcessor");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/sa1100_wdt.c b/drivers/char/watchdog/sa1100_wdt.c
index fb88b40..b474ea5 100644
--- a/drivers/char/watchdog/sa1100_wdt.c
+++ b/drivers/char/watchdog/sa1100_wdt.c
@@ -74,7 +74,7 @@
return 0;
}
-static ssize_t sa1100dog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+static ssize_t sa1100dog_write(struct file *file, const char __user *data, size_t len, loff_t *ppos)
{
if (len)
/* Refresh OSMR3 timer. */
@@ -96,20 +96,20 @@
switch (cmd) {
case WDIOC_GETSUPPORT:
- ret = copy_to_user((struct watchdog_info *)arg, &ident,
+ ret = copy_to_user((struct watchdog_info __user *)arg, &ident,
sizeof(ident)) ? -EFAULT : 0;
break;
case WDIOC_GETSTATUS:
- ret = put_user(0, (int *)arg);
+ ret = put_user(0, (int __user *)arg);
break;
case WDIOC_GETBOOTSTATUS:
- ret = put_user(boot_status, (int *)arg);
+ ret = put_user(boot_status, (int __user *)arg);
break;
case WDIOC_SETTIMEOUT:
- ret = get_user(time, (int *)arg);
+ ret = get_user(time, (int __user *)arg);
if (ret)
break;
@@ -123,7 +123,7 @@
/*fall through*/
case WDIOC_GETTIMEOUT:
- ret = put_user(pre_margin / OSCR_FREQ, (int *)arg);
+ ret = put_user(pre_margin / OSCR_FREQ, (int __user *)arg);
break;
case WDIOC_KEEPALIVE:
diff --git a/drivers/char/watchdog/sbc_epx_c3.c b/drivers/char/watchdog/sbc_epx_c3.c
new file mode 100644
index 0000000..9517646
--- /dev/null
+++ b/drivers/char/watchdog/sbc_epx_c3.c
@@ -0,0 +1,216 @@
+/*
+ * SBC EPX C3 0.1 A Hardware Watchdog Device for the Winsystems EPX-C3
+ * single board computer
+ *
+ * (c) Copyright 2006 Calin A. Culianu <calin@ajvar.org>, All Rights
+ * Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * based on softdog.c by Alan Cox <alan@redhat.com>
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#define PFX "epx_c3: "
+static int epx_c3_alive;
+
+#define WATCHDOG_TIMEOUT 1 /* 1 sec default timeout */
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
+#define EPXC3_WATCHDOG_CTL_REG 0x1ee /* write 1 to enable, 0 to disable */
+#define EPXC3_WATCHDOG_PET_REG 0x1ef /* write anything to pet once enabled */
+
+static void epx_c3_start(void)
+{
+ outb(1, EPXC3_WATCHDOG_CTL_REG);
+}
+
+static void epx_c3_stop(void)
+{
+
+ outb(0, EPXC3_WATCHDOG_CTL_REG);
+
+ printk(KERN_INFO PFX "Stopped watchdog timer.\n");
+}
+
+static void epx_c3_pet(void)
+{
+ outb(1, EPXC3_WATCHDOG_PET_REG);
+}
+
+/*
+ * Allow only one person to hold it open
+ */
+static int epx_c3_open(struct inode *inode, struct file *file)
+{
+ if (epx_c3_alive)
+ return -EBUSY;
+
+ if (nowayout)
+ __module_get(THIS_MODULE);
+
+ /* Activate timer */
+ epx_c3_start();
+ epx_c3_pet();
+
+ epx_c3_alive = 1;
+ printk(KERN_INFO "Started watchdog timer.\n");
+
+ return nonseekable_open(inode, file);
+}
+
+static int epx_c3_release(struct inode *inode, struct file *file)
+{
+ /* Shut off the timer.
+ * Lock it in if it's a module and we defined ...NOWAYOUT */
+ if (!nowayout)
+ epx_c3_stop(); /* Turn the WDT off */
+
+ epx_c3_alive = 0;
+
+ return 0;
+}
+
+static ssize_t epx_c3_write(struct file *file, const char *data,
+ size_t len, loff_t *ppos)
+{
+ /* Refresh the timer. */
+ if (len)
+ epx_c3_pet();
+ return len;
+}
+
+static int epx_c3_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int options, retval = -EINVAL;
+ static struct watchdog_info ident = {
+ .options = WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE,
+ .firmware_version = 0,
+ .identity = "Winsystems EPX-C3 H/W Watchdog",
+ };
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ if (copy_to_user((struct watchdog_info *)arg,
+ &ident, sizeof(ident)))
+ return -EFAULT;
+ return 0;
+ case WDIOC_GETSTATUS:
+ case WDIOC_GETBOOTSTATUS:
+ return put_user(0,(int *)arg);
+ case WDIOC_KEEPALIVE:
+ epx_c3_pet();
+ return 0;
+ case WDIOC_GETTIMEOUT:
+ return put_user(WATCHDOG_TIMEOUT,(int *)arg);
+ case WDIOC_SETOPTIONS: {
+ if (get_user(options, (int *)arg))
+ return -EFAULT;
+
+ if (options & WDIOS_DISABLECARD) {
+ epx_c3_stop();
+ retval = 0;
+ }
+
+ if (options & WDIOS_ENABLECARD) {
+ epx_c3_start();
+ retval = 0;
+ }
+
+ return retval;
+ }
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
+static int epx_c3_notify_sys(struct notifier_block *this, unsigned long code,
+ void *unused)
+{
+ if (code == SYS_DOWN || code == SYS_HALT)
+ epx_c3_stop(); /* Turn the WDT off */
+
+ return NOTIFY_DONE;
+}
+
+static struct file_operations epx_c3_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = epx_c3_write,
+ .ioctl = epx_c3_ioctl,
+ .open = epx_c3_open,
+ .release = epx_c3_release,
+};
+
+static struct miscdevice epx_c3_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &epx_c3_fops,
+};
+
+static struct notifier_block epx_c3_notifier = {
+ .notifier_call = epx_c3_notify_sys,
+};
+
+static const char banner[] __initdata =
+ KERN_INFO PFX "Hardware Watchdog Timer for Winsystems EPX-C3 SBC: 0.1\n";
+
+static int __init watchdog_init(void)
+{
+ int ret;
+
+ ret = register_reboot_notifier(&epx_c3_notifier);
+ if (ret) {
+ printk(KERN_ERR PFX "cannot register reboot notifier "
+ "(err=%d)\n", ret);
+ return ret;
+ }
+
+ ret = misc_register(&epx_c3_miscdev);
+ if (ret) {
+ printk(KERN_ERR PFX "cannot register miscdev on minor=%d "
+ "(err=%d)\n", WATCHDOG_MINOR, ret);
+ unregister_reboot_notifier(&epx_c3_notifier);
+ return ret;
+ }
+
+ printk(banner);
+
+ return 0;
+}
+
+static void __exit watchdog_exit(void)
+{
+ misc_deregister(&epx_c3_miscdev);
+ unregister_reboot_notifier(&epx_c3_notifier);
+}
+
+module_init(watchdog_init);
+module_exit(watchdog_exit);
+
+MODULE_AUTHOR("Calin A. Culianu <calin@ajvar.org>");
+MODULE_DESCRIPTION("Hardware Watchdog Device for Winsystems EPX-C3 SBC. Note that there is no way to probe for this device -- so only use it if you are *sure* you are runnning on this specific SBC system from Winsystems! It writes to IO ports 0x1ee and 0x1ef!");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index a9163d0..277a843 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -41,7 +41,6 @@
/* internal prototypes */
static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event);
static void handle_update(void *data);
-static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci);
/**
* Two notifier lists: the "policy" list is involved in the
@@ -127,7 +126,7 @@
static unsigned int disable_ratelimit = 1;
static DEFINE_SPINLOCK(disable_ratelimit_lock);
-static inline void cpufreq_debug_enable_ratelimit(void)
+static void cpufreq_debug_enable_ratelimit(void)
{
unsigned long flags;
@@ -137,7 +136,7 @@
spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
}
-static inline void cpufreq_debug_disable_ratelimit(void)
+static void cpufreq_debug_disable_ratelimit(void)
{
unsigned long flags;
@@ -206,7 +205,7 @@
static unsigned long l_p_j_ref;
static unsigned int l_p_j_ref_freq;
-static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
+static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
{
if (ci->flags & CPUFREQ_CONST_LOOPS)
return;
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index dfedb77..fdb8b04 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -49,7 +49,7 @@
MODULE_AUTHOR("Abhay Salunke <abhay_salunke@dell.com>");
MODULE_DESCRIPTION("Driver for updating BIOS image on DELL systems");
MODULE_LICENSE("GPL");
-MODULE_VERSION("3.1");
+MODULE_VERSION("3.2");
#define BIOS_SCAN_LIMIT 0xffffffff
#define MAX_IMAGE_LENGTH 16
@@ -564,12 +564,10 @@
static void callbackfn_rbu(const struct firmware *fw, void *context)
{
- int rc = 0;
+ rbu_data.entry_created = 0;
- if (!fw || !fw->size) {
- rbu_data.entry_created = 0;
+ if (!fw || !fw->size)
return;
- }
spin_lock(&rbu_data.lock);
if (!strcmp(image_type, "mono")) {
@@ -592,15 +590,6 @@
} else
pr_debug("invalid image type specified.\n");
spin_unlock(&rbu_data.lock);
-
- rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG,
- "dell_rbu", &rbu_device->dev, &context, callbackfn_rbu);
- if (rc)
- printk(KERN_ERR
- "dell_rbu:%s request_firmware_nowait failed"
- " %d\n", __FUNCTION__, rc);
- else
- rbu_data.entry_created = 1;
}
static ssize_t read_rbu_image_type(struct kobject *kobj, char *buffer,
@@ -735,14 +724,7 @@
sysfs_create_bin_file(&rbu_device->dev.kobj,
&rbu_packet_size_attr);
- rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG,
- "dell_rbu", &rbu_device->dev, &context, callbackfn_rbu);
- if (rc)
- printk(KERN_ERR "dell_rbu:%s:request_firmware_nowait"
- " failed %d\n", __FUNCTION__, rc);
- else
- rbu_data.entry_created = 1;
-
+ rbu_data.entry_created = 0;
return rc;
}
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index ef09a7e..3325660 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -980,7 +980,7 @@
* and attempt to recover if there are problems. Returns 0 if everything's
* ok; nonzero if the request has been terminated.
*/
-static inline
+static
int cdrom_read_check_ireason (ide_drive_t *drive, int len, int ireason)
{
if (ireason == 2)
@@ -1539,7 +1539,7 @@
/*
* Write handling
*/
-static inline int cdrom_write_check_ireason(ide_drive_t *drive, int len, int ireason)
+static int cdrom_write_check_ireason(ide_drive_t *drive, int len, int ireason)
{
/* Two notes about IDE interrupt reason here - 0 means that
* the drive wants to receive data from us, 2 means that
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 245b508..ca25f9e 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -477,7 +477,7 @@
&& id->lba_capacity_2;
}
-static inline void idedisk_check_hpa(ide_drive_t *drive)
+static void idedisk_check_hpa(ide_drive_t *drive)
{
unsigned long long capacity, set_max;
int lba48 = idedisk_supports_lba48(drive->id);
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 62ebefd..9834dce 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -308,7 +308,7 @@
ide_pio_sector(drive, write);
}
-static inline void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
+static void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
unsigned int write)
{
if (rq->bio) /* fs request */
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index c06b181..2514de3 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -856,7 +856,7 @@
param->private_data_len);
}
-static inline int cm_validate_req_param(struct ib_cm_req_param *param)
+static int cm_validate_req_param(struct ib_cm_req_param *param)
{
/* peer-to-peer not supported */
if (param->peer_to_peer)
@@ -1005,7 +1005,7 @@
(be32_to_cpu(local_qpn) > be32_to_cpu(remote_qpn))));
}
-static inline void cm_format_paths_from_req(struct cm_req_msg *req_msg,
+static void cm_format_paths_from_req(struct cm_req_msg *req_msg,
struct ib_sa_path_rec *primary_path,
struct ib_sa_path_rec *alt_path)
{
diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c
index 5d8ee73..4abe5ff 100644
--- a/drivers/isdn/hisax/avm_pci.c
+++ b/drivers/isdn/hisax/avm_pci.c
@@ -358,7 +358,7 @@
}
}
-static inline void
+static void
HDLC_irq(struct BCState *bcs, u_int stat) {
int len;
struct sk_buff *skb;
diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c
index b62d6b3..b0ff1cc 100644
--- a/drivers/isdn/hisax/diva.c
+++ b/drivers/isdn/hisax/diva.c
@@ -476,7 +476,7 @@
}
}
-static inline void
+static void
Memhscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
{
u_char r;
diff --git a/drivers/isdn/hisax/hscx_irq.c b/drivers/isdn/hisax/hscx_irq.c
index 5fe9d42..7b1ad5e 100644
--- a/drivers/isdn/hisax/hscx_irq.c
+++ b/drivers/isdn/hisax/hscx_irq.c
@@ -119,7 +119,7 @@
}
}
-static inline void
+static void
hscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
{
u_char r;
@@ -221,7 +221,7 @@
}
}
-static inline void
+static void
hscx_int_main(struct IsdnCardState *cs, u_char val)
{
diff --git a/drivers/isdn/hisax/jade_irq.c b/drivers/isdn/hisax/jade_irq.c
index 0856340..1f201af 100644
--- a/drivers/isdn/hisax/jade_irq.c
+++ b/drivers/isdn/hisax/jade_irq.c
@@ -110,7 +110,7 @@
}
-static inline void
+static void
jade_interrupt(struct IsdnCardState *cs, u_char val, u_char jade)
{
u_char r;
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 76a189c..eae4473 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -200,7 +200,7 @@
/* if page is completely empty, put it back on the free list, or dealloc it */
/* if page was hijacked, unmark the flag so it might get alloced next time */
/* Note: lock should be held when calling this */
-static inline void bitmap_checkfree(struct bitmap *bitmap, unsigned long page)
+static void bitmap_checkfree(struct bitmap *bitmap, unsigned long page)
{
char *ptr;
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index a601a42..e7a650f 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -228,7 +228,7 @@
};
-static inline int
+static int
crypt_convert_scatterlist(struct crypt_config *cc, struct scatterlist *out,
struct scatterlist *in, unsigned int length,
int write, sector_t sector)
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 561bda5..1235135 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -598,7 +598,7 @@
/*
* Always use UUID for lookups if it's present, otherwise use name or dev.
*/
-static inline struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param)
+static struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param)
{
if (*param->uuid)
return __get_uuid_cell(param->uuid);
@@ -608,7 +608,7 @@
return dm_get_mdptr(huge_decode_dev(param->dev));
}
-static inline struct mapped_device *find_device(struct dm_ioctl *param)
+static struct mapped_device *find_device(struct dm_ioctl *param)
{
struct hash_cell *hc;
struct mapped_device *md = NULL;
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 4b9dd8f..87727d8 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -691,7 +691,7 @@
/*
* Dispatches the copy operation to kcopyd.
*/
-static inline void start_copy(struct pending_exception *pe)
+static void start_copy(struct pending_exception *pe)
{
struct dm_snapshot *s = pe->snap;
struct io_region src, dest;
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 097d1e54..8c16359 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -293,7 +293,7 @@
* Decrements the number of outstanding ios that a bio has been
* cloned into, completing the original io if necc.
*/
-static inline void dec_pending(struct dm_io *io, int error)
+static void dec_pending(struct dm_io *io, int error)
{
if (error)
io->error = error;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index a06ff91..d39f584 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -176,7 +176,7 @@
}
}
-static inline void free_r1bio(r1bio_t *r1_bio)
+static void free_r1bio(r1bio_t *r1_bio)
{
conf_t *conf = mddev_to_conf(r1_bio->mddev);
@@ -190,7 +190,7 @@
mempool_free(r1_bio, conf->r1bio_pool);
}
-static inline void put_buf(r1bio_t *r1_bio)
+static void put_buf(r1bio_t *r1_bio)
{
conf_t *conf = mddev_to_conf(r1_bio->mddev);
int i;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 9e658e5..9130d05 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -176,7 +176,7 @@
}
}
-static inline void free_r10bio(r10bio_t *r10_bio)
+static void free_r10bio(r10bio_t *r10_bio)
{
conf_t *conf = mddev_to_conf(r10_bio->mddev);
@@ -190,7 +190,7 @@
mempool_free(r10_bio, conf->r10bio_pool);
}
-static inline void put_buf(r10bio_t *r10_bio)
+static void put_buf(r10bio_t *r10_bio)
{
conf_t *conf = mddev_to_conf(r10_bio->mddev);
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 54f4a98..25976bf 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -69,7 +69,7 @@
static void print_raid5_conf (raid5_conf_t *conf);
-static inline void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh)
+static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh)
{
if (atomic_dec_and_test(&sh->count)) {
if (!list_empty(&sh->lru))
@@ -118,7 +118,7 @@
hlist_del_init(&sh->hash);
}
-static inline void insert_hash(raid5_conf_t *conf, struct stripe_head *sh)
+static void insert_hash(raid5_conf_t *conf, struct stripe_head *sh)
{
struct hlist_head *hp = stripe_hash(conf, sh->sector);
@@ -178,7 +178,7 @@
static void raid5_build_block (struct stripe_head *sh, int i);
-static inline void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx)
+static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx)
{
raid5_conf_t *conf = sh->raid_conf;
int disks = conf->raid_disks, i;
@@ -1415,7 +1415,7 @@
}
}
-static inline void raid5_activate_delayed(raid5_conf_t *conf)
+static void raid5_activate_delayed(raid5_conf_t *conf)
{
if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD) {
while (!list_empty(&conf->delayed_list)) {
@@ -1431,7 +1431,7 @@
}
}
-static inline void activate_bit_delay(raid5_conf_t *conf)
+static void activate_bit_delay(raid5_conf_t *conf)
{
/* device_lock is held */
struct list_head head;
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index 8c823d6..f618a53 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -88,7 +88,7 @@
static void print_raid6_conf (raid6_conf_t *conf);
-static inline void __release_stripe(raid6_conf_t *conf, struct stripe_head *sh)
+static void __release_stripe(raid6_conf_t *conf, struct stripe_head *sh)
{
if (atomic_dec_and_test(&sh->count)) {
if (!list_empty(&sh->lru))
@@ -197,7 +197,7 @@
static void raid6_build_block (struct stripe_head *sh, int i);
-static inline void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx)
+static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx)
{
raid6_conf_t *conf = sh->raid_conf;
int disks = conf->raid_disks, i;
@@ -1577,7 +1577,7 @@
}
}
-static inline void raid6_activate_delayed(raid6_conf_t *conf)
+static void raid6_activate_delayed(raid6_conf_t *conf)
{
if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD) {
while (!list_empty(&conf->delayed_list)) {
@@ -1593,7 +1593,7 @@
}
}
-static inline void activate_bit_delay(raid6_conf_t *conf)
+static void activate_bit_delay(raid6_conf_t *conf)
{
/* device_lock is held */
struct list_head head;
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index e86b522..9094fa9 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -93,7 +93,7 @@
int sat;
};
-static inline int tvp5150_read(struct i2c_client *c, unsigned char addr)
+static int tvp5150_read(struct i2c_client *c, unsigned char addr)
{
unsigned char buffer[1];
int rc;
diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c
index ea32886..246e67c 100644
--- a/drivers/media/video/zoran_card.c
+++ b/drivers/media/video/zoran_card.c
@@ -995,7 +995,7 @@
static int __devinit
zr36057_init (struct zoran *zr)
{
- unsigned long mem;
+ u32 *mem;
void *vdev;
unsigned mem_needed;
int j;
@@ -1058,10 +1058,10 @@
"%s: zr36057_init() - kmalloc (STAT_COM) failed\n",
ZR_DEVNAME(zr));
kfree(vdev);
- kfree((void *)mem);
+ kfree(mem);
return -ENOMEM;
}
- zr->stat_com = (u32 *) mem;
+ zr->stat_com = mem;
for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
zr->stat_com[j] = 1; /* mark as unavailable to zr36057 */
}
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index 0b1b728..73f5952 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -844,7 +844,7 @@
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static inline void
+static void
mpt_lan_wake_post_buckets_task(struct net_device *dev, int priority)
/*
* @priority: 0 = put it on the timer queue, 1 = put it on the immediate queue
@@ -866,7 +866,7 @@
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static inline int
+static int
mpt_lan_receive_skb(struct net_device *dev, struct sk_buff *skb)
{
struct mpt_lan_priv *priv = dev->priv;
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
index 9b7c37e..5b014c3 100644
--- a/drivers/mmc/mmc_block.c
+++ b/drivers/mmc/mmc_block.c
@@ -462,9 +462,10 @@
if (err)
goto out;
- printk(KERN_INFO "%s: %s %s %luKiB %s\n",
+ printk(KERN_INFO "%s: %s %s %lluKiB %s\n",
md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
- get_capacity(md->disk) >> 1, md->read_only ? "(ro)" : "");
+ (unsigned long long)(get_capacity(md->disk) >> 1),
+ md->read_only ? "(ro)" : "");
mmc_set_drvdata(card, md);
add_disk(md->disk);
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index be5e88b..e4345cf 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -138,7 +138,7 @@
bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
-static inline int DoC_Command(struct DiskOnChip *doc, unsigned char command,
+static int DoC_Command(struct DiskOnChip *doc, unsigned char command,
unsigned char xtraflags)
{
void __iomem *docptr = doc->virtadr;
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
index fcb28a6..681a9c7 100644
--- a/drivers/mtd/devices/doc2001.c
+++ b/drivers/mtd/devices/doc2001.c
@@ -103,7 +103,7 @@
with the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
-static inline void DoC_Command(void __iomem * docptr, unsigned char command,
+static void DoC_Command(void __iomem * docptr, unsigned char command,
unsigned char xtraflags)
{
/* Assert the CLE (Command Latch Enable) line to the flash chip */
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index 0595cc7..5f57f29 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -118,7 +118,7 @@
/* DoC_Command: Send a flash command to the flash chip through the Flash
* command register. Need 2 Write Pipeline Terminates to complete send.
*/
-static inline void DoC_Command(void __iomem * docptr, unsigned char command,
+static void DoC_Command(void __iomem * docptr, unsigned char command,
unsigned char xtraflags)
{
WriteDOC(command, docptr, Mplus_FlashCmd);
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index 21d4e8f..ec5e45e 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -1506,7 +1506,7 @@
return 1;
}
-static inline int __init doc_probe(unsigned long physadr)
+static int __init doc_probe(unsigned long physadr)
{
unsigned char ChipID;
struct mtd_info *mtd;
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index de46e75..1421941 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1387,7 +1387,7 @@
config CS89x0
tristate "CS89x0 support"
- depends on NET_PCI && (ISA || ARCH_IXDP2X01 || ARCH_PNX010X)
+ depends on NET_PCI && (ISA || MACH_IXDP2351 || ARCH_IXDP2X01 || ARCH_PNX010X)
---help---
Support for CS89x0 chipset based Ethernet cards. If you have a
network (Ethernet) card of this type, say Y and read the
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index e2cfde7..fab6586 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -87,6 +87,12 @@
Deepak Saxena : dsaxena@plexity.net
: Intel IXDP2x01 (XScale ixp2x00 NPU) platform support
+ Dmitry Pervushin : dpervushin@ru.mvista.com
+ : PNX010X platform support
+
+ Deepak Saxena : dsaxena@plexity.net
+ : Intel IXDP2351 platform support
+
*/
/* Always include 'config.h' first in case the user wants to turn on
@@ -171,6 +177,10 @@
static unsigned int netcard_portlist[] __initdata =
{ 0x0300, 0};
static unsigned int cs8900_irq_map[] = {1,0,0,0};
+#elif defined(CONFIG_MACH_IXDP2351)
+static unsigned int netcard_portlist[] __initdata = {IXDP2351_VIRT_CS8900_BASE, 0};
+static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0};
+#include <asm/irq.h>
#elif defined(CONFIG_ARCH_IXDP2X01)
#include <asm/irq.h>
static unsigned int netcard_portlist[] __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
@@ -338,45 +348,55 @@
}
#endif
-#if defined(CONFIG_ARCH_IXDP2X01)
-static int
+#if defined(CONFIG_MACH_IXDP2351)
+static u16
readword(unsigned long base_addr, int portno)
{
- return (u16)__raw_readl(base_addr + (portno << 1));
+ return __raw_readw(base_addr + (portno << 1));
}
static void
-writeword(unsigned long base_addr, int portno, int value)
+writeword(unsigned long base_addr, int portno, u16 value)
{
- __raw_writel((u16)value, base_addr + (portno << 1));
+ __raw_writew(value, base_addr + (portno << 1));
}
-#else
-#if defined(CONFIG_ARCH_PNX010X)
-static int
+#elif defined(CONFIG_ARCH_IXDP2X01)
+static u16
+readword(unsigned long base_addr, int portno)
+{
+ return __raw_readl(base_addr + (portno << 1));
+}
+
+static void
+writeword(unsigned long base_addr, int portno, u16 value)
+{
+ __raw_writel(value, base_addr + (portno << 1));
+}
+#elif defined(CONFIG_ARCH_PNX010X)
+static u16
readword(unsigned long base_addr, int portno)
{
return inw(base_addr + (portno << 1));
}
static void
-writeword(unsigned long base_addr, int portno, int value)
+writeword(unsigned long base_addr, int portno, u16 value)
{
outw(value, base_addr + (portno << 1));
}
#else
-static int
+static u16
readword(unsigned long base_addr, int portno)
{
return inw(base_addr + portno);
}
static void
-writeword(unsigned long base_addr, int portno, int value)
+writeword(unsigned long base_addr, int portno, u16 value)
{
outw(value, base_addr + portno);
}
#endif
-#endif
static void
readwords(unsigned long base_addr, int portno, void *buf, int length)
@@ -384,11 +404,11 @@
u8 *buf8 = (u8 *)buf;
do {
- u32 tmp32;
+ u16 tmp16;
- tmp32 = readword(base_addr, portno);
- *buf8++ = (u8)tmp32;
- *buf8++ = (u8)(tmp32 >> 8);
+ tmp16 = readword(base_addr, portno);
+ *buf8++ = (u8)tmp16;
+ *buf8++ = (u8)(tmp16 >> 8);
} while (--length);
}
@@ -398,23 +418,23 @@
u8 *buf8 = (u8 *)buf;
do {
- u32 tmp32;
+ u16 tmp16;
- tmp32 = *buf8++;
- tmp32 |= (*buf8++) << 8;
- writeword(base_addr, portno, tmp32);
+ tmp16 = *buf8++;
+ tmp16 |= (*buf8++) << 8;
+ writeword(base_addr, portno, tmp16);
} while (--length);
}
-static int
-readreg(struct net_device *dev, int regno)
+static u16
+readreg(struct net_device *dev, u16 regno)
{
writeword(dev->base_addr, ADD_PORT, regno);
return readword(dev->base_addr, DATA_PORT);
}
static void
-writereg(struct net_device *dev, int regno, int value)
+writereg(struct net_device *dev, u16 regno, u16 value)
{
writeword(dev->base_addr, ADD_PORT, regno);
writeword(dev->base_addr, DATA_PORT, value);
@@ -780,7 +800,7 @@
} else {
i = lp->isa_config & INT_NO_MASK;
if (lp->chip_type == CS8900) {
-#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX010X)
+#if defined(CONFIG_MACH_IXDP2351) || defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX010X)
i = cs8900_irq_map[0];
#else
/* Translate the IRQ using the IRQ mapping table. */
@@ -1012,7 +1032,7 @@
void __init reset_chip(struct net_device *dev)
{
-#ifndef CONFIG_ARCH_IXDP2X01
+#if !defined(CONFIG_MACH_IXDP2351) && !defined(CONFIG_ARCH_IXDP2X01)
struct net_local *lp = netdev_priv(dev);
int ioaddr = dev->base_addr;
#endif
@@ -1023,7 +1043,7 @@
/* wait 30 ms */
msleep(30);
-#ifndef CONFIG_ARCH_IXDP2X01
+#if !defined(CONFIG_MACH_IXDP2351) && !defined(CONFIG_ARCH_IXDP2X01)
if (lp->chip_type != CS8900) {
/* Hardware problem requires PNP registers to be reconfigured after a reset */
writeword(ioaddr, ADD_PORT, PP_CS8920_ISAINT);
@@ -1287,7 +1307,7 @@
else
#endif
{
-#if !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX010X)
+#if !defined(CONFIG_MACH_IXDP2351) && !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX010X)
if (((1 << dev->irq) & lp->irq_map) == 0) {
printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
dev->name, dev->irq, lp->irq_map);
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 23de226..4726722 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -592,7 +592,7 @@
(void)readb(&nic->csr->scb.status);
}
-static inline void e100_enable_irq(struct nic *nic)
+static void e100_enable_irq(struct nic *nic)
{
unsigned long flags;
@@ -602,7 +602,7 @@
e100_write_flush(nic);
}
-static inline void e100_disable_irq(struct nic *nic)
+static void e100_disable_irq(struct nic *nic)
{
unsigned long flags;
@@ -791,7 +791,7 @@
#define E100_WAIT_SCB_TIMEOUT 20000 /* we might have to wait 100ms!!! */
#define E100_WAIT_SCB_FAST 20 /* delay like the old code */
-static inline int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr)
+static int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr)
{
unsigned long flags;
unsigned int i;
@@ -822,7 +822,7 @@
return err;
}
-static inline int e100_exec_cb(struct nic *nic, struct sk_buff *skb,
+static int e100_exec_cb(struct nic *nic, struct sk_buff *skb,
void (*cb_prepare)(struct nic *, struct cb *, struct sk_buff *))
{
struct cb *cb;
@@ -1567,7 +1567,7 @@
mod_timer(&nic->watchdog, jiffies + E100_WATCHDOG_PERIOD);
}
-static inline void e100_xmit_prepare(struct nic *nic, struct cb *cb,
+static void e100_xmit_prepare(struct nic *nic, struct cb *cb,
struct sk_buff *skb)
{
cb->command = nic->tx_command;
@@ -1617,7 +1617,7 @@
return 0;
}
-static inline int e100_tx_clean(struct nic *nic)
+static int e100_tx_clean(struct nic *nic)
{
struct cb *cb;
int tx_cleaned = 0;
@@ -1728,7 +1728,7 @@
}
#define RFD_BUF_LEN (sizeof(struct rfd) + VLAN_ETH_FRAME_LEN)
-static inline int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
+static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
{
if(!(rx->skb = dev_alloc_skb(RFD_BUF_LEN + NET_IP_ALIGN)))
return -ENOMEM;
@@ -1762,7 +1762,7 @@
return 0;
}
-static inline int e100_rx_indicate(struct nic *nic, struct rx *rx,
+static int e100_rx_indicate(struct nic *nic, struct rx *rx,
unsigned int *work_done, unsigned int work_to_do)
{
struct sk_buff *skb = rx->skb;
@@ -1822,7 +1822,7 @@
return 0;
}
-static inline void e100_rx_clean(struct nic *nic, unsigned int *work_done,
+static void e100_rx_clean(struct nic *nic, unsigned int *work_done,
unsigned int work_to_do)
{
struct rx *rx;
diff --git a/drivers/net/sb1000.c b/drivers/net/sb1000.c
index d6388e1..7613947 100644
--- a/drivers/net/sb1000.c
+++ b/drivers/net/sb1000.c
@@ -94,7 +94,7 @@
const char* name);
static inline int card_wait_for_ready(const int ioaddr[], const char* name,
unsigned char in[]);
-static inline int card_send_command(const int ioaddr[], const char* name,
+static int card_send_command(const int ioaddr[], const char* name,
const unsigned char out[], unsigned char in[]);
/* SB1000 hardware routines to be used during frame rx interrupt */
@@ -309,7 +309,7 @@
}
/* Card Send Command (cannot be used during an interrupt) */
-static inline int
+static int
card_send_command(const int ioaddr[], const char* name,
const unsigned char out[], unsigned char in[])
{
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
index ffac508..4b13b76 100644
--- a/drivers/net/wireless/hostap/hostap_80211_rx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -435,7 +435,7 @@
}
-static inline int
+static int
hostap_rx_frame_mgmt(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats, u16 type,
u16 stype)
@@ -499,7 +499,7 @@
/* Called only as a tasklet (software IRQ) */
-static inline struct net_device *prism2_rx_get_wds(local_info_t *local,
+static struct net_device *prism2_rx_get_wds(local_info_t *local,
u8 *addr)
{
struct hostap_interface *iface = NULL;
@@ -519,7 +519,7 @@
}
-static inline int
+static int
hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
u16 fc, struct net_device **wds)
{
@@ -615,7 +615,7 @@
/* Called only as a tasklet (software IRQ) */
-static inline int
+static int
hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
struct ieee80211_crypt_data *crypt)
{
@@ -654,7 +654,7 @@
/* Called only as a tasklet (software IRQ) */
-static inline int
+static int
hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
int keyidx, struct ieee80211_crypt_data *crypt)
{
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index abfae7f..b1f142d 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -253,7 +253,7 @@
* @dev: pointer to net_device
* @entry: Prism2 command queue entry to be issued
*/
-static inline int hfa384x_cmd_issue(struct net_device *dev,
+static int hfa384x_cmd_issue(struct net_device *dev,
struct hostap_cmd_queue *entry)
{
struct hostap_interface *iface;
@@ -743,7 +743,7 @@
}
-static inline int hfa384x_wait_offset(struct net_device *dev, u16 o_off)
+static int hfa384x_wait_offset(struct net_device *dev, u16 o_off)
{
int tries = HFA384X_BAP_BUSY_TIMEOUT;
int res = HFA384X_INW(o_off) & HFA384X_OFFSET_BUSY;
@@ -1904,7 +1904,7 @@
* and will try to get the correct fid eventually. */
#define EXTRA_FID_READ_TESTS
-static inline u16 prism2_read_fid_reg(struct net_device *dev, u16 reg)
+static u16 prism2_read_fid_reg(struct net_device *dev, u16 reg)
{
#ifdef EXTRA_FID_READ_TESTS
u16 val, val2, val3;
@@ -2581,7 +2581,7 @@
/* Called only from hardware IRQ */
-static inline void prism2_check_magic(local_info_t *local)
+static void prism2_check_magic(local_info_t *local)
{
/* at least PCI Prism2.5 with bus mastering seems to sometimes
* return 0x0000 in SWSUPPORT0 for unknown reason, but re-reading the
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index cf05661..7518384 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -411,7 +411,7 @@
write_register(dev, IPW_REG_AUTOINCREMENT_DATA, val);
}
-static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
+static void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
const u8 * buf)
{
u32 aligned_addr;
@@ -449,7 +449,7 @@
*buf);
}
-static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
+static void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
u8 * buf)
{
u32 aligned_addr;
@@ -657,7 +657,7 @@
#define MAX_RESET_BACKOFF 10
-static inline void schedule_reset(struct ipw2100_priv *priv)
+static void schedule_reset(struct ipw2100_priv *priv)
{
unsigned long now = get_seconds();
@@ -1130,7 +1130,7 @@
write_register(priv->net_dev, IPW_REG_GPIO, reg);
}
-static inline int rf_kill_active(struct ipw2100_priv *priv)
+static int rf_kill_active(struct ipw2100_priv *priv)
{
#define MAX_RF_KILL_CHECKS 5
#define RF_KILL_CHECK_DELAY 40
@@ -2177,7 +2177,7 @@
};
#endif
-static inline int ipw2100_alloc_skb(struct ipw2100_priv *priv,
+static int ipw2100_alloc_skb(struct ipw2100_priv *priv,
struct ipw2100_rx_packet *packet)
{
packet->skb = dev_alloc_skb(sizeof(struct ipw2100_rx));
@@ -2201,7 +2201,7 @@
#define SEARCH_SNAPSHOT 1
#define SNAPSHOT_ADDR(ofs) (priv->snapshot[((ofs) >> 12) & 0xff] + ((ofs) & 0xfff))
-static inline int ipw2100_snapshot_alloc(struct ipw2100_priv *priv)
+static int ipw2100_snapshot_alloc(struct ipw2100_priv *priv)
{
int i;
if (priv->snapshot[0])
@@ -2221,7 +2221,7 @@
return 1;
}
-static inline void ipw2100_snapshot_free(struct ipw2100_priv *priv)
+static void ipw2100_snapshot_free(struct ipw2100_priv *priv)
{
int i;
if (!priv->snapshot[0])
@@ -2231,7 +2231,7 @@
priv->snapshot[0] = NULL;
}
-static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf,
+static u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf,
size_t len, int mode)
{
u32 i, j;
@@ -2288,7 +2288,7 @@
static u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH];
#endif
-static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
+static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
{
#ifdef CONFIG_IPW2100_DEBUG_C3
struct ipw2100_status *status = &priv->status_queue.drv[i];
@@ -2346,7 +2346,7 @@
schedule_reset(priv);
}
-static inline void isr_rx(struct ipw2100_priv *priv, int i,
+static void isr_rx(struct ipw2100_priv *priv, int i,
struct ieee80211_rx_stats *stats)
{
struct ipw2100_status *status = &priv->status_queue.drv[i];
@@ -2425,7 +2425,7 @@
priv->rx_queue.drv[i].host_addr = packet->dma_addr;
}
-static inline int ipw2100_corruption_check(struct ipw2100_priv *priv, int i)
+static int ipw2100_corruption_check(struct ipw2100_priv *priv, int i)
{
struct ipw2100_status *status = &priv->status_queue.drv[i];
struct ipw2100_rx *u = priv->rx_buffers[i].rxp;
@@ -2481,7 +2481,7 @@
* The WRITE index is cached in the variable 'priv->rx_queue.next'.
*
*/
-static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
+static void __ipw2100_rx_process(struct ipw2100_priv *priv)
{
struct ipw2100_bd_queue *rxq = &priv->rx_queue;
struct ipw2100_status_queue *sq = &priv->status_queue;
@@ -2634,7 +2634,7 @@
* for use by future command and data packets.
*
*/
-static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
+static int __ipw2100_tx_process(struct ipw2100_priv *priv)
{
struct ipw2100_bd_queue *txq = &priv->tx_queue;
struct ipw2100_bd *tbd;
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index cdfe502..819be2b 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -813,7 +813,7 @@
up(&priv->sem);
}
-static inline void __ipw_led_activity_on(struct ipw_priv *priv)
+static void __ipw_led_activity_on(struct ipw_priv *priv)
{
u32 led;
@@ -1508,7 +1508,7 @@
static DEVICE_ATTR(direct_dword, S_IWUSR | S_IRUGO,
show_direct_dword, store_direct_dword);
-static inline int rf_kill_active(struct ipw_priv *priv)
+static int rf_kill_active(struct ipw_priv *priv)
{
if (0 == (ipw_read32(priv, 0x30) & 0x10000))
priv->status |= STATUS_RF_KILL_HW;
@@ -2359,7 +2359,7 @@
}
/* perform a chip select operation */
-static inline void eeprom_cs(struct ipw_priv *priv)
+static void eeprom_cs(struct ipw_priv *priv)
{
eeprom_write_reg(priv, 0);
eeprom_write_reg(priv, EEPROM_BIT_CS);
@@ -2368,7 +2368,7 @@
}
/* perform a chip select operation */
-static inline void eeprom_disable_cs(struct ipw_priv *priv)
+static void eeprom_disable_cs(struct ipw_priv *priv)
{
eeprom_write_reg(priv, EEPROM_BIT_CS);
eeprom_write_reg(priv, 0);
@@ -2475,7 +2475,7 @@
IPW_DEBUG_TRACE("<<\n");
}
-static inline void ipw_zero_memory(struct ipw_priv *priv, u32 start, u32 count)
+static void ipw_zero_memory(struct ipw_priv *priv, u32 start, u32 count)
{
count >>= 2;
if (!count)
@@ -2772,7 +2772,7 @@
return ipw_read32(priv, 0x90) == 0xd55555d5;
}
-static inline int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask,
+static int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask,
int timeout)
{
int i = 0;
@@ -3150,7 +3150,7 @@
#define IPW_RX_BUF_SIZE (3000)
-static inline void ipw_rx_queue_reset(struct ipw_priv *priv,
+static void ipw_rx_queue_reset(struct ipw_priv *priv,
struct ipw_rx_queue *rxq)
{
unsigned long flags;
@@ -3608,7 +3608,7 @@
ipw_queue_tx_free(priv, &priv->txq[3]);
}
-static inline void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid)
+static void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid)
{
/* First 3 bytes are manufacturer */
bssid[0] = priv->mac_addr[0];
@@ -3622,7 +3622,7 @@
bssid[0] |= 0x02; /* set local assignment bit (IEEE802) */
}
-static inline u8 ipw_add_station(struct ipw_priv *priv, u8 * bssid)
+static u8 ipw_add_station(struct ipw_priv *priv, u8 * bssid)
{
struct ipw_station_entry entry;
int i;
@@ -3655,7 +3655,7 @@
return i;
}
-static inline u8 ipw_find_station(struct ipw_priv *priv, u8 * bssid)
+static u8 ipw_find_station(struct ipw_priv *priv, u8 * bssid)
{
int i;
@@ -3794,7 +3794,7 @@
memset(avg, 0, sizeof(*avg));
}
-static void inline average_add(struct average *avg, s16 val)
+static void average_add(struct average *avg, s16 val)
{
avg->sum -= avg->entries[avg->pos];
avg->sum += val;
@@ -3805,7 +3805,7 @@
}
}
-static s16 inline average_value(struct average *avg)
+static s16 average_value(struct average *avg)
{
if (!unlikely(avg->init)) {
if (avg->pos)
@@ -3847,7 +3847,7 @@
}
-static inline u32 ipw_get_max_rate(struct ipw_priv *priv)
+static u32 ipw_get_max_rate(struct ipw_priv *priv)
{
u32 i = 0x80000000;
u32 mask = priv->rates_mask;
@@ -4087,7 +4087,7 @@
* roaming_threshold -> disassociate_threshold, scan and roam for better signal.
* Above disassociate threshold, give up and stop scanning.
* Roaming is disabled if disassociate_threshold <= roaming_threshold */
-static inline void ipw_handle_missed_beacon(struct ipw_priv *priv,
+static void ipw_handle_missed_beacon(struct ipw_priv *priv,
int missed_count)
{
priv->notif_missed_beacons = missed_count;
@@ -4157,7 +4157,7 @@
* Handle host notification packet.
* Called from interrupt routine
*/
-static inline void ipw_rx_notification(struct ipw_priv *priv,
+static void ipw_rx_notification(struct ipw_priv *priv,
struct ipw_rx_notification *notif)
{
notif->size = le16_to_cpu(notif->size);
@@ -5095,7 +5095,7 @@
return 1;
}
-static inline void ipw_copy_rates(struct ipw_supported_rates *dest,
+static void ipw_copy_rates(struct ipw_supported_rates *dest,
const struct ipw_supported_rates *src)
{
u8 i;
@@ -5856,7 +5856,7 @@
#define ipw_debug_config(x) do {} while (0)
#endif
-static inline void ipw_set_fixed_rate(struct ipw_priv *priv, int mode)
+static void ipw_set_fixed_rate(struct ipw_priv *priv, int mode)
{
/* TODO: Verify that this works... */
struct ipw_fixed_rate fr = {
@@ -7634,7 +7634,7 @@
}
#endif
-static inline int is_network_packet(struct ipw_priv *priv,
+static int is_network_packet(struct ipw_priv *priv,
struct ieee80211_hdr_4addr *header)
{
/* Filter incoming packets to determine if they are targetted toward
@@ -7672,7 +7672,7 @@
#define IPW_PACKET_RETRY_TIME HZ
-static inline int is_duplicate_packet(struct ipw_priv *priv,
+static int is_duplicate_packet(struct ipw_priv *priv,
struct ieee80211_hdr_4addr *header)
{
u16 sc = le16_to_cpu(header->seq_ctl);
@@ -9581,7 +9581,7 @@
/* net device stuff */
-static inline void init_sys_config(struct ipw_sys_config *sys_config)
+static void init_sys_config(struct ipw_sys_config *sys_config)
{
memset(sys_config, 0, sizeof(struct ipw_sys_config));
sys_config->bt_coexistence = 1; /* We may need to look into prvStaBtConfig */
@@ -9627,7 +9627,7 @@
we need to heavily modify the ieee80211_skb_to_txb.
*/
-static inline int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
+static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
int pri)
{
struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
index b0d8b5b..ff192e9 100644
--- a/drivers/net/wireless/wavelan.c
+++ b/drivers/net/wireless/wavelan.c
@@ -102,7 +102,7 @@
* Write to card's Host Adapter Command Register. Include a delay for
* those times when it is needed.
*/
-static inline void hacr_write_slow(unsigned long ioaddr, u16 hacr)
+static void hacr_write_slow(unsigned long ioaddr, u16 hacr)
{
hacr_write(ioaddr, hacr);
/* delay might only be needed sometimes */
@@ -242,7 +242,7 @@
* The Windows drivers don't use the CRC, but the AP and the PtP tool
* depend on it.
*/
-static inline u16 psa_crc(u8 * psa, /* The PSA */
+static u16 psa_crc(u8 * psa, /* The PSA */
int size)
{ /* Number of short for CRC */
int byte_cnt; /* Loop on the PSA */
@@ -310,7 +310,7 @@
/*
* Write 1 byte to the MMC.
*/
-static inline void mmc_out(unsigned long ioaddr, u16 o, u8 d)
+static void mmc_out(unsigned long ioaddr, u16 o, u8 d)
{
int count = 0;
@@ -326,7 +326,7 @@
* Routine to write bytes to the Modem Management Controller.
* We start at the end because it is the way it should be!
*/
-static inline void mmc_write(unsigned long ioaddr, u8 o, u8 * b, int n)
+static void mmc_write(unsigned long ioaddr, u8 o, u8 * b, int n)
{
o += n;
b += n;
@@ -340,7 +340,7 @@
* Read a byte from the MMC.
* Optimised version for 1 byte, avoid using memory.
*/
-static inline u8 mmc_in(unsigned long ioaddr, u16 o)
+static u8 mmc_in(unsigned long ioaddr, u16 o)
{
int count = 0;
@@ -587,7 +587,7 @@
* Set channel attention bit and busy wait until command has
* completed, then acknowledge completion of the command.
*/
-static inline int wv_synchronous_cmd(struct net_device * dev, const char *str)
+static int wv_synchronous_cmd(struct net_device * dev, const char *str)
{
net_local *lp = (net_local *) dev->priv;
unsigned long ioaddr = dev->base_addr;
@@ -633,7 +633,7 @@
* Configuration commands completion interrupt.
* Check if done, and if OK.
*/
-static inline int
+static int
wv_config_complete(struct net_device * dev, unsigned long ioaddr, net_local * lp)
{
unsigned short mcs_addr;
@@ -843,7 +843,7 @@
* wavelan_interrupt is not an option), so you may experience
* delays sometimes.
*/
-static inline void wv_82586_reconfig(struct net_device * dev)
+static void wv_82586_reconfig(struct net_device * dev)
{
net_local *lp = (net_local *) dev->priv;
unsigned long flags;
@@ -1281,7 +1281,7 @@
* This is the information which is displayed by the driver at startup.
* There are lots of flags for configuring it to your liking.
*/
-static inline void wv_init_info(struct net_device * dev)
+static void wv_init_info(struct net_device * dev)
{
short ioaddr = dev->base_addr;
net_local *lp = (net_local *) dev->priv;
@@ -1502,7 +1502,7 @@
* It's a bit complicated and you don't really want to look into it.
* (called in wavelan_ioctl)
*/
-static inline int wv_set_frequency(unsigned long ioaddr, /* I/O port of the card */
+static int wv_set_frequency(unsigned long ioaddr, /* I/O port of the card */
iw_freq * frequency)
{
const int BAND_NUM = 10; /* Number of bands */
@@ -1677,7 +1677,7 @@
/*
* Give the list of available frequencies.
*/
-static inline int wv_frequency_list(unsigned long ioaddr, /* I/O port of the card */
+static int wv_frequency_list(unsigned long ioaddr, /* I/O port of the card */
iw_freq * list, /* List of frequencies to fill */
int max)
{ /* Maximum number of frequencies */
@@ -2489,7 +2489,7 @@
* Note: if any errors occur, the packet is "dropped on the floor".
* (called by wv_packet_rcv())
*/
-static inline void
+static void
wv_packet_read(struct net_device * dev, u16 buf_off, int sksize)
{
net_local *lp = (net_local *) dev->priv;
@@ -2585,7 +2585,7 @@
* (called in wavelan_interrupt()).
* Note : the spinlock is already grabbed for us.
*/
-static inline void wv_receive(struct net_device * dev)
+static void wv_receive(struct net_device * dev)
{
unsigned long ioaddr = dev->base_addr;
net_local *lp = (net_local *) dev->priv;
@@ -2768,7 +2768,7 @@
*
* (called in wavelan_packet_xmit())
*/
-static inline int wv_packet_write(struct net_device * dev, void *buf, short length)
+static int wv_packet_write(struct net_device * dev, void *buf, short length)
{
net_local *lp = (net_local *) dev->priv;
unsigned long ioaddr = dev->base_addr;
@@ -2964,7 +2964,7 @@
* Routine to initialize the Modem Management Controller.
* (called by wv_hw_reset())
*/
-static inline int wv_mmc_init(struct net_device * dev)
+static int wv_mmc_init(struct net_device * dev)
{
unsigned long ioaddr = dev->base_addr;
net_local *lp = (net_local *) dev->priv;
@@ -3136,7 +3136,7 @@
* Start the receive unit.
* (called by wv_hw_reset())
*/
-static inline int wv_ru_start(struct net_device * dev)
+static int wv_ru_start(struct net_device * dev)
{
net_local *lp = (net_local *) dev->priv;
unsigned long ioaddr = dev->base_addr;
@@ -3228,7 +3228,7 @@
*
* (called by wv_hw_reset())
*/
-static inline int wv_cu_start(struct net_device * dev)
+static int wv_cu_start(struct net_device * dev)
{
net_local *lp = (net_local *) dev->priv;
unsigned long ioaddr = dev->base_addr;
@@ -3329,7 +3329,7 @@
*
* (called by wv_hw_reset())
*/
-static inline int wv_82586_start(struct net_device * dev)
+static int wv_82586_start(struct net_device * dev)
{
net_local *lp = (net_local *) dev->priv;
unsigned long ioaddr = dev->base_addr;
@@ -3641,7 +3641,7 @@
* WaveLAN controller (i82586).
* (called by wavelan_close())
*/
-static inline void wv_82586_stop(struct net_device * dev)
+static void wv_82586_stop(struct net_device * dev)
{
net_local *lp = (net_local *) dev->priv;
unsigned long ioaddr = dev->base_addr;
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 9c25654..ef4c687 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -1635,7 +1635,7 @@
blk_queue_max_hw_segments(device->request_queue, -1L);
blk_queue_max_segment_size(device->request_queue, -1L);
blk_queue_segment_boundary(device->request_queue, -1L);
- blk_queue_ordered(device->request_queue, 1);
+ blk_queue_ordered(device->request_queue, QUEUE_ORDERED_TAG, NULL);
}
/*
diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c
index 83e6a06..cd2cc28 100644
--- a/drivers/s390/cio/airq.c
+++ b/drivers/s390/cio/airq.c
@@ -2,12 +2,12 @@
* drivers/s390/cio/airq.c
* S/390 common I/O routines -- support for adapter interruptions
*
- * $Revision: 1.12 $
+ * $Revision: 1.15 $
*
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
* Author(s): Ingo Adlung (adlung@de.ibm.com)
- * Cornelia Huck (cohuck@de.ibm.com)
+ * Cornelia Huck (cornelia.huck@de.ibm.com)
* Arnd Bergmann (arndb@de.ibm.com)
*/
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c
index daf21e0..72f27c1 100644
--- a/drivers/s390/cio/blacklist.c
+++ b/drivers/s390/cio/blacklist.c
@@ -1,12 +1,12 @@
/*
* drivers/s390/cio/blacklist.c
* S/390 common I/O routines -- blacklisting of specific devices
- * $Revision: 1.39 $
+ * $Revision: 1.42 $
*
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
* Author(s): Ingo Adlung (adlung@de.ibm.com)
- * Cornelia Huck (cohuck@de.ibm.com)
+ * Cornelia Huck (cornelia.huck@de.ibm.com)
* Arnd Bergmann (arndb@de.ibm.com)
*/
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 503a568..6c077ad 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -1,12 +1,12 @@
/*
* drivers/s390/cio/ccwgroup.c
* bus driver for ccwgroup
- * $Revision: 1.33 $
+ * $Revision: 1.35 $
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
* Author(s): Arnd Bergmann (arndb@de.ibm.com)
- * Cornelia Huck (cohuck@de.ibm.com)
+ * Cornelia Huck (cornelia.huck@de.ibm.com)
*/
#include <linux/module.h>
#include <linux/errno.h>
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 7270808..2cbb724 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -1,12 +1,12 @@
/*
* drivers/s390/cio/chsc.c
* S/390 common I/O routines -- channel subsystem call
- * $Revision: 1.126 $
+ * $Revision: 1.128 $
*
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
* Author(s): Ingo Adlung (adlung@de.ibm.com)
- * Cornelia Huck (cohuck@de.ibm.com)
+ * Cornelia Huck (cornelia.huck@de.ibm.com)
* Arnd Bergmann (arndb@de.ibm.com)
*/
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 7376bc8..6223b06 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -1,12 +1,12 @@
/*
* drivers/s390/cio/cio.c
* S/390 common I/O routines -- low level i/o calls
- * $Revision: 1.138 $
+ * $Revision: 1.140 $
*
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
* Author(s): Ingo Adlung (adlung@de.ibm.com)
- * Cornelia Huck (cohuck@de.ibm.com)
+ * Cornelia Huck (cornelia.huck@de.ibm.com)
* Arnd Bergmann (arndb@de.ibm.com)
* Martin Schwidefsky (schwidefsky@de.ibm.com)
*/
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 2d319fb..5161087 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -1,12 +1,12 @@
/*
* drivers/s390/cio/css.c
* driver for channel subsystem
- * $Revision: 1.93 $
+ * $Revision: 1.96 $
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
* Author(s): Arnd Bergmann (arndb@de.ibm.com)
- * Cornelia Huck (cohuck@de.ibm.com)
+ * Cornelia Huck (cornelia.huck@de.ibm.com)
*/
#include <linux/module.h>
#include <linux/init.h>
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index aa5ab5d..b637586 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -147,7 +147,7 @@
struct channel_subsystem {
u8 cssid;
int valid;
- struct channel_path *chps[__MAX_CHPID];
+ struct channel_path *chps[__MAX_CHPID + 1];
struct device device;
struct pgid global_pgid;
};
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index eb73605..a67e7e6 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -1,12 +1,12 @@
/*
* drivers/s390/cio/device.c
* bus driver for ccw devices
- * $Revision: 1.137 $
+ * $Revision: 1.140 $
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
* Author(s): Arnd Bergmann (arndb@de.ibm.com)
- * Cornelia Huck (cohuck@de.ibm.com)
+ * Cornelia Huck (cornelia.huck@de.ibm.com)
* Martin Schwidefsky (schwidefsky@de.ibm.com)
*/
#include <linux/config.h>
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 23d12b6..b302779 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -4,7 +4,7 @@
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
- * Author(s): Cornelia Huck(cohuck@de.ibm.com)
+ * Author(s): Cornelia Huck (cornelia.huck@de.ibm.com)
* Martin Schwidefsky (schwidefsky@de.ibm.com)
*/
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c
index 04ceba3..e60b2d8 100644
--- a/drivers/s390/cio/device_id.c
+++ b/drivers/s390/cio/device_id.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
- * Author(s): Cornelia Huck(cohuck@de.ibm.com)
+ * Author(s): Cornelia Huck (cornelia.huck@de.ibm.com)
* Martin Schwidefsky (schwidefsky@de.ibm.com)
*
* Sense ID functions.
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index 143b6c2..8b02189 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -1,12 +1,12 @@
/*
* drivers/s390/cio/device_ops.c
*
- * $Revision: 1.58 $
+ * $Revision: 1.61 $
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
- * Cornelia Huck (cohuck@de.ibm.com)
+ * Cornelia Huck (cornelia.huck@de.ibm.com)
*/
#include <linux/config.h>
#include <linux/module.h>
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c
index 052832d..d2a5b04 100644
--- a/drivers/s390/cio/device_pgid.c
+++ b/drivers/s390/cio/device_pgid.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
- * Author(s): Cornelia Huck(cohuck@de.ibm.com)
+ * Author(s): Cornelia Huck (cornelia.huck@de.ibm.com)
* Martin Schwidefsky (schwidefsky@de.ibm.com)
*
* Path Group ID functions.
diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c
index db09c20..dad4dd9 100644
--- a/drivers/s390/cio/device_status.c
+++ b/drivers/s390/cio/device_status.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
- * Author(s): Cornelia Huck(cohuck@de.ibm.com)
+ * Author(s): Cornelia Huck (cornelia.huck@de.ibm.com)
* Martin Schwidefsky (schwidefsky@de.ibm.com)
*
* Status accumulation and basic sense functions.
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index 30a836f..77be2c3 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -7,7 +7,7 @@
*
* Copyright 2000,2002 IBM Corporation
* Author(s): Utz Bacher <utz.bacher@de.ibm.com>
- * 2.6 cio integration by Cornelia Huck <cohuck@de.ibm.com>
+ * 2.6 cio integration by Cornelia Huck <cornelia.huck@de.ibm.com>
*
* Restriction: only 63 iqdio subchannels would have its own indicator,
* after that, subsequent subchannels share one indicator
@@ -56,7 +56,7 @@
#include "ioasm.h"
#include "chsc.h"
-#define VERSION_QDIO_C "$Revision: 1.114 $"
+#define VERSION_QDIO_C "$Revision: 1.117 $"
/****************** MODULE PARAMETER VARIABLES ********************/
MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
index 0db4f57..1901fee 100644
--- a/drivers/s390/net/ctcmain.c
+++ b/drivers/s390/net/ctcmain.c
@@ -1,5 +1,5 @@
/*
- * $Id: ctcmain.c,v 1.78 2005/09/07 12:18:02 pavlic Exp $
+ * $Id: ctcmain.c,v 1.79 2006/01/11 11:32:18 cohuck Exp $
*
* CTC / ESCON network driver
*
@@ -8,7 +8,7 @@
* Fixes by : Jochen Röhrig (roehrig@de.ibm.com)
* Arnaldo Carvalho de Melo <acme@conectiva.com.br>
Peter Tiedemann (ptiedem@de.ibm.com)
- * Driver Model stuff by : Cornelia Huck <cohuck@de.ibm.com>
+ * Driver Model stuff by : Cornelia Huck <huckc@de.ibm.com>
*
* Documentation used:
* - Principles of Operation (IBM doc#: SA22-7201-06)
@@ -37,7 +37,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.78 $
+ * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.79 $
*
*/
#undef DEBUG
@@ -248,7 +248,7 @@
print_banner(void)
{
static int printed = 0;
- char vbuf[] = "$Revision: 1.78 $";
+ char vbuf[] = "$Revision: 1.79 $";
char *version = vbuf;
if (printed)
diff --git a/drivers/s390/net/cu3088.c b/drivers/s390/net/cu3088.c
index 77dacb4..2014fb7 100644
--- a/drivers/s390/net/cu3088.c
+++ b/drivers/s390/net/cu3088.c
@@ -1,11 +1,11 @@
/*
- * $Id: cu3088.c,v 1.36 2005/10/25 14:37:17 cohuck Exp $
+ * $Id: cu3088.c,v 1.38 2006/01/12 14:33:09 cohuck Exp $
*
* CTC / LCS ccw_device driver
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Arnd Bergmann <arndb@de.ibm.com>
- * Cornelia Huck <cohuck@de.ibm.com>
+ * Cornelia Huck <cornelia.huck@de.ibm.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index 69425a7..ac4c4b8 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -1,12 +1,13 @@
/*
- * $Id: netiucv.c,v 1.66 2005/05/11 08:10:17 holzheu Exp $
+ * $Id: netiucv.c,v 1.69 2006/01/12 14:33:09 cohuck Exp $
*
* IUCV network driver
*
* Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
*
- * Driverfs integration and all bugs therein by Cornelia Huck(cohuck@de.ibm.com)
+ * Sysfs integration and all bugs therein by Cornelia Huck
+ * (cornelia.huck@de.ibm.com)
*
* Documentation used:
* the source of the original IUCV driver by:
@@ -30,7 +31,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * RELEASE-TAG: IUCV network driver $Revision: 1.66 $
+ * RELEASE-TAG: IUCV network driver $Revision: 1.69 $
*
*/
@@ -2076,7 +2077,7 @@
static void
netiucv_banner(void)
{
- char vbuf[] = "$Revision: 1.66 $";
+ char vbuf[] = "$Revision: 1.69 $";
char *version = vbuf;
if ((version = strchr(version, ':'))) {
diff --git a/drivers/s390/s390_rdev.c b/drivers/s390/s390_rdev.c
index 566cc3d..206518c 100644
--- a/drivers/s390/s390_rdev.c
+++ b/drivers/s390/s390_rdev.c
@@ -1,11 +1,11 @@
/*
* drivers/s390/s390_rdev.c
* s390 root device
- * $Revision: 1.2 $
+ * $Revision: 1.4 $
*
* Copyright (C) 2002, 2005 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
- * Author(s): Cornelia Huck (cohuck@de.ibm.com)
+ * Author(s): Cornelia Huck (cornelia.huck@de.ibm.com)
* Carsten Otte (cotte@de.ibm.com)
*/
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
index 33d56c3..770f164 100644
--- a/drivers/scsi/aic7xxx_old.c
+++ b/drivers/scsi/aic7xxx_old.c
@@ -1290,7 +1290,7 @@
*
***************************************************************************/
-static inline unsigned char
+static unsigned char
aic_inb(struct aic7xxx_host *p, long port)
{
#ifdef MMAPIO
@@ -1309,7 +1309,7 @@
#endif
}
-static inline void
+static void
aic_outb(struct aic7xxx_host *p, unsigned char val, long port)
{
#ifdef MMAPIO
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 1b495af..780bfcc 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -1418,7 +1418,7 @@
ctask->digest_count = 4;
}
-static inline int
+static int
iscsi_digest_final_send(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
struct iscsi_buf *buf, uint32_t *digest, int final)
{
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index f55b9b3..99bae83 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -1747,7 +1747,7 @@
{ ATA_SHIFT_PIO, XFER_PIO_0 },
};
-static inline u8 base_from_shift(unsigned int shift)
+static u8 base_from_shift(unsigned int shift)
{
int i;
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index d18a4bc..bf9f7f7 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -1266,7 +1266,7 @@
* return the scb from the head of the free list. NULL if there are none
* available
**/
-static inline scb_t *
+static scb_t *
megaraid_alloc_scb(adapter_t *adapter, struct scsi_cmnd *scp)
{
struct list_head *head = &adapter->kscb_pool;
@@ -1329,7 +1329,7 @@
*
* prepare the scatter-gather list
*/
-static inline int
+static int
megaraid_mbox_mksgl(adapter_t *adapter, scb_t *scb)
{
struct scatterlist *sgl;
@@ -1402,7 +1402,7 @@
*
* post the command to the controller if mailbox is availble.
*/
-static inline int
+static int
mbox_post_cmd(adapter_t *adapter, scb_t *scb)
{
mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter);
@@ -2070,7 +2070,7 @@
*
* Returns: 1 if the interrupt is valid, 0 otherwise
*/
-static inline int
+static int
megaraid_ack_sequence(adapter_t *adapter)
{
mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter);
@@ -2208,7 +2208,7 @@
*
* DMA sync if required.
*/
-static inline void
+static void
megaraid_mbox_sync_scb(adapter_t *adapter, scb_t *scb)
{
mbox_ccb_t *ccb;
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index c0bb806..511ed52 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -81,7 +81,7 @@
*
* Returns a free command from the pool
*/
-static inline struct megasas_cmd *megasas_get_cmd(struct megasas_instance
+static struct megasas_cmd *megasas_get_cmd(struct megasas_instance
*instance)
{
unsigned long flags;
@@ -263,7 +263,7 @@
* If successful, this function returns the number of SG elements. Otherwise,
* it returnes -1.
*/
-static inline int
+static int
megasas_make_sgl32(struct megasas_instance *instance, struct scsi_cmnd *scp,
union megasas_sgl *mfi_sgl)
{
@@ -311,7 +311,7 @@
* If successful, this function returns the number of SG elements. Otherwise,
* it returnes -1.
*/
-static inline int
+static int
megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
union megasas_sgl *mfi_sgl)
{
@@ -360,7 +360,7 @@
* This function prepares CDB commands. These are typcially pass-through
* commands to the devices.
*/
-static inline int
+static int
megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
struct megasas_cmd *cmd)
{
@@ -441,7 +441,7 @@
*
* Frames (and accompanying SGLs) for regular SCSI IOs use this function.
*/
-static inline int
+static int
megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
struct megasas_cmd *cmd)
{
@@ -563,7 +563,7 @@
* @scp: SCSI command
* @frame_count: [OUT] Number of frames used to prepare this command
*/
-static inline struct megasas_cmd *megasas_build_cmd(struct megasas_instance
+static struct megasas_cmd *megasas_build_cmd(struct megasas_instance
*instance,
struct scsi_cmnd *scp,
int *frame_count)
@@ -914,7 +914,7 @@
* @instance: Adapter soft state
* @cmd: Completed command
*/
-static inline void
+static void
megasas_unmap_sgbuf(struct megasas_instance *instance, struct megasas_cmd *cmd)
{
dma_addr_t buf_h;
@@ -958,7 +958,7 @@
* an alternate status (as in the case of aborted
* commands)
*/
-static inline void
+static void
megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
u8 alt_status)
{
@@ -1105,7 +1105,7 @@
* SCSI mid-layer instead of the status
* returned by the FW
*/
-static inline int
+static int
megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status)
{
u32 status;
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index dd80503..997f8e3 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -151,7 +151,7 @@
return cd;
}
-static inline void scsi_cd_put(struct scsi_cd *cd)
+static void scsi_cd_put(struct scsi_cd *cd)
{
struct scsi_device *sdev = cd->device;
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index fb610c3..d9ce8c5 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2454,6 +2454,7 @@
.resume = serial8250_resume,
.driver = {
.name = "serial8250",
+ .owner = THIS_MODULE,
},
};
@@ -2594,21 +2595,30 @@
if (ret)
goto out;
- serial8250_isa_devs = platform_device_register_simple("serial8250",
- PLAT8250_DEV_LEGACY, NULL, 0);
- if (IS_ERR(serial8250_isa_devs)) {
- ret = PTR_ERR(serial8250_isa_devs);
- goto unreg;
+ ret = platform_driver_register(&serial8250_isa_driver);
+ if (ret)
+ goto unreg_uart_drv;
+
+ serial8250_isa_devs = platform_device_alloc("serial8250",
+ PLAT8250_DEV_LEGACY);
+ if (!serial8250_isa_devs) {
+ ret = -ENOMEM;
+ goto unreg_plat_drv;
}
+ ret = platform_device_add(serial8250_isa_devs);
+ if (ret)
+ goto put_dev;
+
serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);
- ret = platform_driver_register(&serial8250_isa_driver);
- if (ret == 0)
- goto out;
+ goto out;
- platform_device_unregister(serial8250_isa_devs);
- unreg:
+ put_dev:
+ platform_device_put(serial8250_isa_devs);
+ unreg_plat_drv:
+ platform_driver_unregister(&serial8250_isa_driver);
+ unreg_uart_drv:
uart_unregister_driver(&serial8250_reg);
out:
return ret;
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 8437172..5e7199f 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -190,7 +190,6 @@
To compile this driver as a module, choose M here: the module
will be called 8250_boca.
-
config SERIAL_8250_HUB6
tristate "Support Hub6 cards"
depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
@@ -848,7 +847,7 @@
config SERIAL_M32R_PLDSIO
bool "M32R SIO I/F on a PLD"
- depends on SERIAL_M32R_SIO=y && (PLAT_OPSPUT || PALT_USRV || PLAT_M32700UT)
+ depends on SERIAL_M32R_SIO=y && (PLAT_OPSPUT || PLAT_USRV || PLAT_M32700UT)
default n
help
Say Y here if you want to use the M32R serial controller
@@ -917,4 +916,12 @@
and wish to use the serial ports on this card, say Y.
Otherwise, say N.
+config SERIAL_SGI_IOC3
+ tristate "SGI Altix IOC3 serial support"
+ depends on (IA64_GENERIC || IA64_SGI_SN2) && SGI_IOC3
+ select SERIAL_CORE
+ help
+ If you have an SGI Altix with an IOC3 serial card,
+ say Y or M. Otherwise, say N.
+
endmenu
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 24a583e..eaf8e01 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -56,4 +56,5 @@
obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o
obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o
obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o
+obj-$(CONFIG_SERIAL_SGI_IOC3) += ioc3_serial.o
obj-$(CONFIG_SERIAL_AT91) += at91_serial.o
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 5c098be..587cc6a 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -499,7 +499,7 @@
ucr2 |= UCR2_STPB;
if (termios->c_cflag & PARENB) {
ucr2 |= UCR2_PREN;
- if (!(termios->c_cflag & PARODD))
+ if (termios->c_cflag & PARODD)
ucr2 |= UCR2_PROE;
}
diff --git a/drivers/serial/ioc3_serial.c b/drivers/serial/ioc3_serial.c
new file mode 100644
index 0000000..8097cd9
--- /dev/null
+++ b/drivers/serial/ioc3_serial.c
@@ -0,0 +1,2197 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * This file contains a module version of the ioc3 serial driver. This
+ * includes all the support functions needed (support functions, etc.)
+ * and the serial driver itself.
+ */
+#include <linux/errno.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/circ_buf.h>
+#include <linux/serial_reg.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/serial_core.h>
+#include <linux/ioc3.h>
+
+/*
+ * Interesting things about the ioc3
+ */
+
+#define LOGICAL_PORTS 2 /* rs232(0) and rs422(1) */
+#define PORTS_PER_CARD 2
+#define LOGICAL_PORTS_PER_CARD (PORTS_PER_CARD * LOGICAL_PORTS)
+#define MAX_CARDS 8
+#define MAX_LOGICAL_PORTS (LOGICAL_PORTS_PER_CARD * MAX_CARDS)
+
+/* determine given the sio_ir what port it applies to */
+#define GET_PORT_FROM_SIO_IR(_x) (_x & SIO_IR_SA) ? 0 : 1
+
+
+/*
+ * we have 2 logical ports (rs232, rs422) for each physical port
+ * evens are rs232, odds are rs422
+ */
+#define GET_PHYSICAL_PORT(_x) ((_x) >> 1)
+#define GET_LOGICAL_PORT(_x) ((_x) & 1)
+#define IS_PHYSICAL_PORT(_x) !((_x) & 1)
+#define IS_RS232(_x) !((_x) & 1)
+
+static unsigned int Num_of_ioc3_cards;
+static unsigned int Submodule_slot;
+
+/* defining this will get you LOTS of great debug info */
+//#define DEBUG_INTERRUPTS
+#define DPRINT_CONFIG(_x...) ;
+//#define DPRINT_CONFIG(_x...) printk _x
+#define NOT_PROGRESS() ;
+//#define NOT_PROGRESS() printk("%s : fails %d\n", __FUNCTION__, __LINE__)
+
+/* number of characters we want to transmit to the lower level at a time */
+#define MAX_CHARS 256
+#define FIFO_SIZE (MAX_CHARS-1) /* it's a uchar */
+
+/* Device name we're using */
+#define DEVICE_NAME "ttySIOC"
+#define DEVICE_MAJOR 204
+#define DEVICE_MINOR 116
+
+/* flags for next_char_state */
+#define NCS_BREAK 0x1
+#define NCS_PARITY 0x2
+#define NCS_FRAMING 0x4
+#define NCS_OVERRUN 0x8
+
+/* cause we need SOME parameters ... */
+#define MIN_BAUD_SUPPORTED 1200
+#define MAX_BAUD_SUPPORTED 115200
+
+/* protocol types supported */
+#define PROTO_RS232 0
+#define PROTO_RS422 1
+
+/* Notification types */
+#define N_DATA_READY 0x01
+#define N_OUTPUT_LOWAT 0x02
+#define N_BREAK 0x04
+#define N_PARITY_ERROR 0x08
+#define N_FRAMING_ERROR 0x10
+#define N_OVERRUN_ERROR 0x20
+#define N_DDCD 0x40
+#define N_DCTS 0x80
+
+#define N_ALL_INPUT (N_DATA_READY | N_BREAK \
+ | N_PARITY_ERROR | N_FRAMING_ERROR \
+ | N_OVERRUN_ERROR | N_DDCD | N_DCTS)
+
+#define N_ALL_OUTPUT N_OUTPUT_LOWAT
+
+#define N_ALL_ERRORS (N_PARITY_ERROR | N_FRAMING_ERROR \
+ | N_OVERRUN_ERROR)
+
+#define N_ALL (N_DATA_READY | N_OUTPUT_LOWAT | N_BREAK \
+ | N_PARITY_ERROR | N_FRAMING_ERROR \
+ | N_OVERRUN_ERROR | N_DDCD | N_DCTS)
+
+#define SER_CLK_SPEED(prediv) ((22000000 << 1) / prediv)
+#define SER_DIVISOR(x, clk) (((clk) + (x) * 8) / ((x) * 16))
+#define DIVISOR_TO_BAUD(div, clk) ((clk) / 16 / (div))
+
+/* Some masks */
+#define LCR_MASK_BITS_CHAR (UART_LCR_WLEN5 | UART_LCR_WLEN6 \
+ | UART_LCR_WLEN7 | UART_LCR_WLEN8)
+#define LCR_MASK_STOP_BITS (UART_LCR_STOP)
+
+#define PENDING(_a, _p) (readl(&(_p)->vma->sio_ir) & (_a)->ic_enable)
+
+#define RING_BUF_SIZE 4096
+#define BUF_SIZE_BIT SBBR_L_SIZE
+#define PROD_CONS_MASK PROD_CONS_PTR_4K
+
+#define TOTAL_RING_BUF_SIZE (RING_BUF_SIZE * 4)
+
+/* driver specific - one per card */
+struct ioc3_card {
+ struct {
+ /* uart ports are allocated here */
+ struct uart_port icp_uart_port[LOGICAL_PORTS];
+ /* the ioc3_port used for this port */
+ struct ioc3_port *icp_port;
+ } ic_port[PORTS_PER_CARD];
+ /* currently enabled interrupts */
+ uint32_t ic_enable;
+};
+
+/* Local port info for each IOC3 serial port */
+struct ioc3_port {
+ /* handy reference material */
+ struct uart_port *ip_port;
+ struct ioc3_card *ip_card;
+ struct ioc3_driver_data *ip_idd;
+ struct ioc3_submodule *ip_is;
+
+ /* pci mem addresses for this port */
+ struct ioc3_serialregs __iomem *ip_serial_regs;
+ struct ioc3_uartregs __iomem *ip_uart_regs;
+
+ /* Ring buffer page for this port */
+ dma_addr_t ip_dma_ringbuf;
+ /* vaddr of ring buffer */
+ struct ring_buffer *ip_cpu_ringbuf;
+
+ /* Rings for this port */
+ struct ring *ip_inring;
+ struct ring *ip_outring;
+
+ /* Hook to port specific values */
+ struct port_hooks *ip_hooks;
+
+ spinlock_t ip_lock;
+
+ /* Various rx/tx parameters */
+ int ip_baud;
+ int ip_tx_lowat;
+ int ip_rx_timeout;
+
+ /* Copy of notification bits */
+ int ip_notify;
+
+ /* Shadow copies of various registers so we don't need to PIO
+ * read them constantly
+ */
+ uint32_t ip_sscr;
+ uint32_t ip_tx_prod;
+ uint32_t ip_rx_cons;
+ unsigned char ip_flags;
+};
+
+/* tx low water mark. We need to notify the driver whenever tx is getting
+ * close to empty so it can refill the tx buffer and keep things going.
+ * Let's assume that if we interrupt 1 ms before the tx goes idle, we'll
+ * have no trouble getting in more chars in time (I certainly hope so).
+ */
+#define TX_LOWAT_LATENCY 1000
+#define TX_LOWAT_HZ (1000000 / TX_LOWAT_LATENCY)
+#define TX_LOWAT_CHARS(baud) (baud / 10 / TX_LOWAT_HZ)
+
+/* Flags per port */
+#define INPUT_HIGH 0x01
+ /* used to signify that we have turned off the rx_high
+ * temporarily - we need to drain the fifo and don't
+ * want to get blasted with interrupts.
+ */
+#define DCD_ON 0x02
+ /* DCD state is on */
+#define LOWAT_WRITTEN 0x04
+#define READ_ABORTED 0x08
+ /* the read was aborted - used to avaoid infinate looping
+ * in the interrupt handler
+ */
+#define INPUT_ENABLE 0x10
+
+/* Since each port has different register offsets and bitmasks
+ * for everything, we'll store those that we need in tables so we
+ * don't have to be constantly checking the port we are dealing with.
+ */
+struct port_hooks {
+ uint32_t intr_delta_dcd;
+ uint32_t intr_delta_cts;
+ uint32_t intr_tx_mt;
+ uint32_t intr_rx_timer;
+ uint32_t intr_rx_high;
+ uint32_t intr_tx_explicit;
+ uint32_t intr_clear;
+ uint32_t intr_all;
+ char rs422_select_pin;
+};
+
+static struct port_hooks hooks_array[PORTS_PER_CARD] = {
+ /* values for port A */
+ {
+ .intr_delta_dcd = SIO_IR_SA_DELTA_DCD,
+ .intr_delta_cts = SIO_IR_SA_DELTA_CTS,
+ .intr_tx_mt = SIO_IR_SA_TX_MT,
+ .intr_rx_timer = SIO_IR_SA_RX_TIMER,
+ .intr_rx_high = SIO_IR_SA_RX_HIGH,
+ .intr_tx_explicit = SIO_IR_SA_TX_EXPLICIT,
+ .intr_clear = (SIO_IR_SA_TX_MT | SIO_IR_SA_RX_FULL
+ | SIO_IR_SA_RX_HIGH
+ | SIO_IR_SA_RX_TIMER
+ | SIO_IR_SA_DELTA_DCD
+ | SIO_IR_SA_DELTA_CTS
+ | SIO_IR_SA_INT
+ | SIO_IR_SA_TX_EXPLICIT
+ | SIO_IR_SA_MEMERR),
+ .intr_all = SIO_IR_SA,
+ .rs422_select_pin = GPPR_UARTA_MODESEL_PIN,
+ },
+
+ /* values for port B */
+ {
+ .intr_delta_dcd = SIO_IR_SB_DELTA_DCD,
+ .intr_delta_cts = SIO_IR_SB_DELTA_CTS,
+ .intr_tx_mt = SIO_IR_SB_TX_MT,
+ .intr_rx_timer = SIO_IR_SB_RX_TIMER,
+ .intr_rx_high = SIO_IR_SB_RX_HIGH,
+ .intr_tx_explicit = SIO_IR_SB_TX_EXPLICIT,
+ .intr_clear = (SIO_IR_SB_TX_MT | SIO_IR_SB_RX_FULL
+ | SIO_IR_SB_RX_HIGH
+ | SIO_IR_SB_RX_TIMER
+ | SIO_IR_SB_DELTA_DCD
+ | SIO_IR_SB_DELTA_CTS
+ | SIO_IR_SB_INT
+ | SIO_IR_SB_TX_EXPLICIT
+ | SIO_IR_SB_MEMERR),
+ .intr_all = SIO_IR_SB,
+ .rs422_select_pin = GPPR_UARTB_MODESEL_PIN,
+ }
+};
+
+struct ring_entry {
+ union {
+ struct {
+ uint32_t alldata;
+ uint32_t allsc;
+ } all;
+ struct {
+ char data[4]; /* data bytes */
+ char sc[4]; /* status/control */
+ } s;
+ } u;
+};
+
+/* Test the valid bits in any of the 4 sc chars using "allsc" member */
+#define RING_ANY_VALID \
+ ((uint32_t)(RXSB_MODEM_VALID | RXSB_DATA_VALID) * 0x01010101)
+
+#define ring_sc u.s.sc
+#define ring_data u.s.data
+#define ring_allsc u.all.allsc
+
+/* Number of entries per ring buffer. */
+#define ENTRIES_PER_RING (RING_BUF_SIZE / (int) sizeof(struct ring_entry))
+
+/* An individual ring */
+struct ring {
+ struct ring_entry entries[ENTRIES_PER_RING];
+};
+
+/* The whole enchilada */
+struct ring_buffer {
+ struct ring TX_A;
+ struct ring RX_A;
+ struct ring TX_B;
+ struct ring RX_B;
+};
+
+/* Get a ring from a port struct */
+#define RING(_p, _wh) &(((struct ring_buffer *)((_p)->ip_cpu_ringbuf))->_wh)
+
+/* for Infinite loop detection */
+#define MAXITER 10000000
+
+
+/**
+ * set_baud - Baud rate setting code
+ * @port: port to set
+ * @baud: baud rate to use
+ */
+static int set_baud(struct ioc3_port *port, int baud)
+{
+ int divisor;
+ int actual_baud;
+ int diff;
+ int lcr, prediv;
+ struct ioc3_uartregs __iomem *uart;
+
+ for (prediv = 6; prediv < 64; prediv++) {
+ divisor = SER_DIVISOR(baud, SER_CLK_SPEED(prediv));
+ if (!divisor)
+ continue; /* invalid divisor */
+ actual_baud = DIVISOR_TO_BAUD(divisor, SER_CLK_SPEED(prediv));
+
+ diff = actual_baud - baud;
+ if (diff < 0)
+ diff = -diff;
+
+ /* if we're within 1% we've found a match */
+ if (diff * 100 <= actual_baud)
+ break;
+ }
+
+ /* if the above loop completed, we didn't match
+ * the baud rate. give up.
+ */
+ if (prediv == 64) {
+ NOT_PROGRESS();
+ return 1;
+ }
+
+ uart = port->ip_uart_regs;
+ lcr = readb(&uart->iu_lcr);
+
+ writeb(lcr | UART_LCR_DLAB, &uart->iu_lcr);
+ writeb((unsigned char)divisor, &uart->iu_dll);
+ writeb((unsigned char)(divisor >> 8), &uart->iu_dlm);
+ writeb((unsigned char)prediv, &uart->iu_scr);
+ writeb((unsigned char)lcr, &uart->iu_lcr);
+
+ return 0;
+}
+
+/**
+ * get_ioc3_port - given a uart port, return the control structure
+ * @the_port: uart port to find
+ */
+static struct ioc3_port *get_ioc3_port(struct uart_port *the_port)
+{
+ struct ioc3_driver_data *idd = dev_get_drvdata(the_port->dev);
+ struct ioc3_card *card_ptr = idd->data[Submodule_slot];
+ int ii, jj;
+
+ if (!card_ptr) {
+ NOT_PROGRESS();
+ return NULL;
+ }
+ for (ii = 0; ii < PORTS_PER_CARD; ii++) {
+ for (jj = 0; jj < LOGICAL_PORTS; jj++) {
+ if (the_port == &card_ptr->ic_port[ii].icp_uart_port[jj])
+ return card_ptr->ic_port[ii].icp_port;
+ }
+ }
+ NOT_PROGRESS();
+ return NULL;
+}
+
+/**
+ * port_init - Initialize the sio and ioc3 hardware for a given port
+ * called per port from attach...
+ * @port: port to initialize
+ */
+static int inline port_init(struct ioc3_port *port)
+{
+ uint32_t sio_cr;
+ struct port_hooks *hooks = port->ip_hooks;
+ struct ioc3_uartregs __iomem *uart;
+ int reset_loop_counter = 0xfffff;
+ struct ioc3_driver_data *idd = port->ip_idd;
+
+ /* Idle the IOC3 serial interface */
+ writel(SSCR_RESET, &port->ip_serial_regs->sscr);
+
+ /* Wait until any pending bus activity for this port has ceased */
+ do {
+ sio_cr = readl(&idd->vma->sio_cr);
+ if (reset_loop_counter-- <= 0) {
+ printk(KERN_WARNING
+ "IOC3 unable to come out of reset"
+ " scr 0x%x\n", sio_cr);
+ return -1;
+ }
+ } while (!(sio_cr & SIO_CR_ARB_DIAG_IDLE) &&
+ (((sio_cr &= SIO_CR_ARB_DIAG) == SIO_CR_ARB_DIAG_TXA)
+ || sio_cr == SIO_CR_ARB_DIAG_TXB
+ || sio_cr == SIO_CR_ARB_DIAG_RXA
+ || sio_cr == SIO_CR_ARB_DIAG_RXB));
+
+ /* Finish reset sequence */
+ writel(0, &port->ip_serial_regs->sscr);
+
+ /* Once RESET is done, reload cached tx_prod and rx_cons values
+ * and set rings to empty by making prod == cons
+ */
+ port->ip_tx_prod = readl(&port->ip_serial_regs->stcir) & PROD_CONS_MASK;
+ writel(port->ip_tx_prod, &port->ip_serial_regs->stpir);
+ port->ip_rx_cons = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;
+ writel(port->ip_rx_cons | SRCIR_ARM, &port->ip_serial_regs->srcir);
+
+ /* Disable interrupts for this 16550 */
+ uart = port->ip_uart_regs;
+ writeb(0, &uart->iu_lcr);
+ writeb(0, &uart->iu_ier);
+
+ /* Set the default baud */
+ set_baud(port, port->ip_baud);
+
+ /* Set line control to 8 bits no parity */
+ writeb(UART_LCR_WLEN8 | 0, &uart->iu_lcr);
+ /* UART_LCR_STOP == 1 stop */
+
+ /* Enable the FIFOs */
+ writeb(UART_FCR_ENABLE_FIFO, &uart->iu_fcr);
+ /* then reset 16550 FIFOs */
+ writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
+ &uart->iu_fcr);
+
+ /* Clear modem control register */
+ writeb(0, &uart->iu_mcr);
+
+ /* Clear deltas in modem status register */
+ writel(0, &port->ip_serial_regs->shadow);
+
+ /* Only do this once per port pair */
+ if (port->ip_hooks == &hooks_array[0]) {
+ unsigned long ring_pci_addr;
+ uint32_t __iomem *sbbr_l, *sbbr_h;
+
+ sbbr_l = &idd->vma->sbbr_l;
+ sbbr_h = &idd->vma->sbbr_h;
+ ring_pci_addr = (unsigned long __iomem)port->ip_dma_ringbuf;
+ DPRINT_CONFIG(("%s: ring_pci_addr 0x%p\n",
+ __FUNCTION__, (void *)ring_pci_addr));
+
+ writel((unsigned int)((uint64_t) ring_pci_addr >> 32), sbbr_h);
+ writel((unsigned int)ring_pci_addr | BUF_SIZE_BIT, sbbr_l);
+ }
+
+ /* Set the receive timeout value to 10 msec */
+ writel(SRTR_HZ / 100, &port->ip_serial_regs->srtr);
+
+ /* Set rx threshold, enable DMA */
+ /* Set high water mark at 3/4 of full ring */
+ port->ip_sscr = (ENTRIES_PER_RING * 3 / 4);
+
+ /* uart experiences pauses at high baud rate reducing actual
+ * throughput by 10% or so unless we enable high speed polling
+ * XXX when this hardware bug is resolved we should revert to
+ * normal polling speed
+ */
+ port->ip_sscr |= SSCR_HIGH_SPD;
+
+ writel(port->ip_sscr, &port->ip_serial_regs->sscr);
+
+ /* Disable and clear all serial related interrupt bits */
+ port->ip_card->ic_enable &= ~hooks->intr_clear;
+ ioc3_disable(port->ip_is, idd, hooks->intr_clear);
+ ioc3_ack(port->ip_is, idd, hooks->intr_clear);
+ return 0;
+}
+
+/**
+ * enable_intrs - enable interrupts
+ * @port: port to enable
+ * @mask: mask to use
+ */
+static void enable_intrs(struct ioc3_port *port, uint32_t mask)
+{
+ if ((port->ip_card->ic_enable & mask) != mask) {
+ port->ip_card->ic_enable |= mask;
+ ioc3_enable(port->ip_is, port->ip_idd, mask);
+ }
+}
+
+/**
+ * local_open - local open a port
+ * @port: port to open
+ */
+static inline int local_open(struct ioc3_port *port)
+{
+ int spiniter = 0;
+
+ port->ip_flags = INPUT_ENABLE;
+
+ /* Pause the DMA interface if necessary */
+ if (port->ip_sscr & SSCR_DMA_EN) {
+ writel(port->ip_sscr | SSCR_DMA_PAUSE,
+ &port->ip_serial_regs->sscr);
+ while ((readl(&port->ip_serial_regs->sscr)
+ & SSCR_PAUSE_STATE) == 0) {
+ spiniter++;
+ if (spiniter > MAXITER) {
+ NOT_PROGRESS();
+ return -1;
+ }
+ }
+ }
+
+ /* Reset the input fifo. If the uart received chars while the port
+ * was closed and DMA is not enabled, the uart may have a bunch of
+ * chars hanging around in its rx fifo which will not be discarded
+ * by rclr in the upper layer. We must get rid of them here.
+ */
+ writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR,
+ &port->ip_uart_regs->iu_fcr);
+
+ writeb(UART_LCR_WLEN8, &port->ip_uart_regs->iu_lcr);
+ /* UART_LCR_STOP == 1 stop */
+
+ /* Re-enable DMA, set default threshold to intr whenever there is
+ * data available.
+ */
+ port->ip_sscr &= ~SSCR_RX_THRESHOLD;
+ port->ip_sscr |= 1; /* default threshold */
+
+ /* Plug in the new sscr. This implicitly clears the DMA_PAUSE
+ * flag if it was set above
+ */
+ writel(port->ip_sscr, &port->ip_serial_regs->sscr);
+ port->ip_tx_lowat = 1;
+ return 0;
+}
+
+/**
+ * set_rx_timeout - Set rx timeout and threshold values.
+ * @port: port to use
+ * @timeout: timeout value in ticks
+ */
+static inline int set_rx_timeout(struct ioc3_port *port, int timeout)
+{
+ int threshold;
+
+ port->ip_rx_timeout = timeout;
+
+ /* Timeout is in ticks. Let's figure out how many chars we
+ * can receive at the current baud rate in that interval
+ * and set the rx threshold to that amount. There are 4 chars
+ * per ring entry, so we'll divide the number of chars that will
+ * arrive in timeout by 4.
+ * So .... timeout * baud / 10 / HZ / 4, with HZ = 100.
+ */
+ threshold = timeout * port->ip_baud / 4000;
+ if (threshold == 0)
+ threshold = 1; /* otherwise we'll intr all the time! */
+
+ if ((unsigned)threshold > (unsigned)SSCR_RX_THRESHOLD)
+ return 1;
+
+ port->ip_sscr &= ~SSCR_RX_THRESHOLD;
+ port->ip_sscr |= threshold;
+ writel(port->ip_sscr, &port->ip_serial_regs->sscr);
+
+ /* Now set the rx timeout to the given value
+ * again timeout * SRTR_HZ / HZ
+ */
+ timeout = timeout * SRTR_HZ / 100;
+ if (timeout > SRTR_CNT)
+ timeout = SRTR_CNT;
+ writel(timeout, &port->ip_serial_regs->srtr);
+ return 0;
+}
+
+/**
+ * config_port - config the hardware
+ * @port: port to config
+ * @baud: baud rate for the port
+ * @byte_size: data size
+ * @stop_bits: number of stop bits
+ * @parenb: parity enable ?
+ * @parodd: odd parity ?
+ */
+static inline int
+config_port(struct ioc3_port *port,
+ int baud, int byte_size, int stop_bits, int parenb, int parodd)
+{
+ char lcr, sizebits;
+ int spiniter = 0;
+
+ DPRINT_CONFIG(("%s: line %d baud %d byte_size %d stop %d parenb %d "
+ "parodd %d\n",
+ __FUNCTION__, ((struct uart_port *)port->ip_port)->line,
+ baud, byte_size, stop_bits, parenb, parodd));
+
+ if (set_baud(port, baud))
+ return 1;
+
+ switch (byte_size) {
+ case 5:
+ sizebits = UART_LCR_WLEN5;
+ break;
+ case 6:
+ sizebits = UART_LCR_WLEN6;
+ break;
+ case 7:
+ sizebits = UART_LCR_WLEN7;
+ break;
+ case 8:
+ sizebits = UART_LCR_WLEN8;
+ break;
+ default:
+ return 1;
+ }
+
+ /* Pause the DMA interface if necessary */
+ if (port->ip_sscr & SSCR_DMA_EN) {
+ writel(port->ip_sscr | SSCR_DMA_PAUSE,
+ &port->ip_serial_regs->sscr);
+ while ((readl(&port->ip_serial_regs->sscr)
+ & SSCR_PAUSE_STATE) == 0) {
+ spiniter++;
+ if (spiniter > MAXITER)
+ return -1;
+ }
+ }
+
+ /* Clear relevant fields in lcr */
+ lcr = readb(&port->ip_uart_regs->iu_lcr);
+ lcr &= ~(LCR_MASK_BITS_CHAR | UART_LCR_EPAR |
+ UART_LCR_PARITY | LCR_MASK_STOP_BITS);
+
+ /* Set byte size in lcr */
+ lcr |= sizebits;
+
+ /* Set parity */
+ if (parenb) {
+ lcr |= UART_LCR_PARITY;
+ if (!parodd)
+ lcr |= UART_LCR_EPAR;
+ }
+
+ /* Set stop bits */
+ if (stop_bits)
+ lcr |= UART_LCR_STOP /* 2 stop bits */ ;
+
+ writeb(lcr, &port->ip_uart_regs->iu_lcr);
+
+ /* Re-enable the DMA interface if necessary */
+ if (port->ip_sscr & SSCR_DMA_EN) {
+ writel(port->ip_sscr, &port->ip_serial_regs->sscr);
+ }
+ port->ip_baud = baud;
+
+ /* When we get within this number of ring entries of filling the
+ * entire ring on tx, place an EXPLICIT intr to generate a lowat
+ * notification when output has drained.
+ */
+ port->ip_tx_lowat = (TX_LOWAT_CHARS(baud) + 3) / 4;
+ if (port->ip_tx_lowat == 0)
+ port->ip_tx_lowat = 1;
+
+ set_rx_timeout(port, 2);
+ return 0;
+}
+
+/**
+ * do_write - Write bytes to the port. Returns the number of bytes
+ * actually written. Called from transmit_chars
+ * @port: port to use
+ * @buf: the stuff to write
+ * @len: how many bytes in 'buf'
+ */
+static inline int do_write(struct ioc3_port *port, char *buf, int len)
+{
+ int prod_ptr, cons_ptr, total = 0;
+ struct ring *outring;
+ struct ring_entry *entry;
+ struct port_hooks *hooks = port->ip_hooks;
+
+ BUG_ON(!(len >= 0));
+
+ prod_ptr = port->ip_tx_prod;
+ cons_ptr = readl(&port->ip_serial_regs->stcir) & PROD_CONS_MASK;
+ outring = port->ip_outring;
+
+ /* Maintain a 1-entry red-zone. The ring buffer is full when
+ * (cons - prod) % ring_size is 1. Rather than do this subtraction
+ * in the body of the loop, I'll do it now.
+ */
+ cons_ptr = (cons_ptr - (int)sizeof(struct ring_entry)) & PROD_CONS_MASK;
+
+ /* Stuff the bytes into the output */
+ while ((prod_ptr != cons_ptr) && (len > 0)) {
+ int xx;
+
+ /* Get 4 bytes (one ring entry) at a time */
+ entry = (struct ring_entry *)((caddr_t) outring + prod_ptr);
+
+ /* Invalidate all entries */
+ entry->ring_allsc = 0;
+
+ /* Copy in some bytes */
+ for (xx = 0; (xx < 4) && (len > 0); xx++) {
+ entry->ring_data[xx] = *buf++;
+ entry->ring_sc[xx] = TXCB_VALID;
+ len--;
+ total++;
+ }
+
+ /* If we are within some small threshold of filling up the
+ * entire ring buffer, we must place an EXPLICIT intr here
+ * to generate a lowat interrupt in case we subsequently
+ * really do fill up the ring and the caller goes to sleep.
+ * No need to place more than one though.
+ */
+ if (!(port->ip_flags & LOWAT_WRITTEN) &&
+ ((cons_ptr - prod_ptr) & PROD_CONS_MASK)
+ <= port->ip_tx_lowat * (int)sizeof(struct ring_entry)) {
+ port->ip_flags |= LOWAT_WRITTEN;
+ entry->ring_sc[0] |= TXCB_INT_WHEN_DONE;
+ }
+
+ /* Go on to next entry */
+ prod_ptr += sizeof(struct ring_entry);
+ prod_ptr &= PROD_CONS_MASK;
+ }
+
+ /* If we sent something, start DMA if necessary */
+ if (total > 0 && !(port->ip_sscr & SSCR_DMA_EN)) {
+ port->ip_sscr |= SSCR_DMA_EN;
+ writel(port->ip_sscr, &port->ip_serial_regs->sscr);
+ }
+
+ /* Store the new producer pointer. If tx is disabled, we stuff the
+ * data into the ring buffer, but we don't actually start tx.
+ */
+ if (!uart_tx_stopped(port->ip_port)) {
+ writel(prod_ptr, &port->ip_serial_regs->stpir);
+
+ /* If we are now transmitting, enable tx_mt interrupt so we
+ * can disable DMA if necessary when the tx finishes.
+ */
+ if (total > 0)
+ enable_intrs(port, hooks->intr_tx_mt);
+ }
+ port->ip_tx_prod = prod_ptr;
+
+ return total;
+}
+
+/**
+ * disable_intrs - disable interrupts
+ * @port: port to enable
+ * @mask: mask to use
+ */
+static inline void disable_intrs(struct ioc3_port *port, uint32_t mask)
+{
+ if (port->ip_card->ic_enable & mask) {
+ ioc3_disable(port->ip_is, port->ip_idd, mask);
+ port->ip_card->ic_enable &= ~mask;
+ }
+}
+
+/**
+ * set_notification - Modify event notification
+ * @port: port to use
+ * @mask: events mask
+ * @set_on: set ?
+ */
+static int set_notification(struct ioc3_port *port, int mask, int set_on)
+{
+ struct port_hooks *hooks = port->ip_hooks;
+ uint32_t intrbits, sscrbits;
+
+ BUG_ON(!mask);
+
+ intrbits = sscrbits = 0;
+
+ if (mask & N_DATA_READY)
+ intrbits |= (hooks->intr_rx_timer | hooks->intr_rx_high);
+ if (mask & N_OUTPUT_LOWAT)
+ intrbits |= hooks->intr_tx_explicit;
+ if (mask & N_DDCD) {
+ intrbits |= hooks->intr_delta_dcd;
+ sscrbits |= SSCR_RX_RING_DCD;
+ }
+ if (mask & N_DCTS)
+ intrbits |= hooks->intr_delta_cts;
+
+ if (set_on) {
+ enable_intrs(port, intrbits);
+ port->ip_notify |= mask;
+ port->ip_sscr |= sscrbits;
+ } else {
+ disable_intrs(port, intrbits);
+ port->ip_notify &= ~mask;
+ port->ip_sscr &= ~sscrbits;
+ }
+
+ /* We require DMA if either DATA_READY or DDCD notification is
+ * currently requested. If neither of these is requested and
+ * there is currently no tx in progress, DMA may be disabled.
+ */
+ if (port->ip_notify & (N_DATA_READY | N_DDCD))
+ port->ip_sscr |= SSCR_DMA_EN;
+ else if (!(port->ip_card->ic_enable & hooks->intr_tx_mt))
+ port->ip_sscr &= ~SSCR_DMA_EN;
+
+ writel(port->ip_sscr, &port->ip_serial_regs->sscr);
+ return 0;
+}
+
+/**
+ * set_mcr - set the master control reg
+ * @the_port: port to use
+ * @mask1: mcr mask
+ * @mask2: shadow mask
+ */
+static inline int set_mcr(struct uart_port *the_port,
+ int mask1, int mask2)
+{
+ struct ioc3_port *port = get_ioc3_port(the_port);
+ uint32_t shadow;
+ int spiniter = 0;
+ char mcr;
+
+ if (!port)
+ return -1;
+
+ /* Pause the DMA interface if necessary */
+ if (port->ip_sscr & SSCR_DMA_EN) {
+ writel(port->ip_sscr | SSCR_DMA_PAUSE,
+ &port->ip_serial_regs->sscr);
+ while ((readl(&port->ip_serial_regs->sscr)
+ & SSCR_PAUSE_STATE) == 0) {
+ spiniter++;
+ if (spiniter > MAXITER)
+ return -1;
+ }
+ }
+ shadow = readl(&port->ip_serial_regs->shadow);
+ mcr = (shadow & 0xff000000) >> 24;
+
+ /* Set new value */
+ mcr |= mask1;
+ shadow |= mask2;
+ writeb(mcr, &port->ip_uart_regs->iu_mcr);
+ writel(shadow, &port->ip_serial_regs->shadow);
+
+ /* Re-enable the DMA interface if necessary */
+ if (port->ip_sscr & SSCR_DMA_EN) {
+ writel(port->ip_sscr, &port->ip_serial_regs->sscr);
+ }
+ return 0;
+}
+
+/**
+ * ioc3_set_proto - set the protocol for the port
+ * @port: port to use
+ * @proto: protocol to use
+ */
+static int ioc3_set_proto(struct ioc3_port *port, int proto)
+{
+ struct port_hooks *hooks = port->ip_hooks;
+
+ switch (proto) {
+ default:
+ case PROTO_RS232:
+ /* Clear the appropriate GIO pin */
+ DPRINT_CONFIG(("%s: rs232\n", __FUNCTION__));
+ writel(0, (&port->ip_idd->vma->gppr[0]
+ + hooks->rs422_select_pin));
+ break;
+
+ case PROTO_RS422:
+ /* Set the appropriate GIO pin */
+ DPRINT_CONFIG(("%s: rs422\n", __FUNCTION__));
+ writel(1, (&port->ip_idd->vma->gppr[0]
+ + hooks->rs422_select_pin));
+ break;
+ }
+ return 0;
+}
+
+/**
+ * transmit_chars - upper level write, called with the_port->lock
+ * @the_port: port to write
+ */
+static void transmit_chars(struct uart_port *the_port)
+{
+ int xmit_count, tail, head;
+ int result;
+ char *start;
+ struct tty_struct *tty;
+ struct ioc3_port *port = get_ioc3_port(the_port);
+ struct uart_info *info;
+
+ if (!the_port)
+ return;
+ if (!port)
+ return;
+
+ info = the_port->info;
+ tty = info->tty;
+
+ if (uart_circ_empty(&info->xmit) || uart_tx_stopped(the_port)) {
+ /* Nothing to do or hw stopped */
+ set_notification(port, N_ALL_OUTPUT, 0);
+ return;
+ }
+
+ head = info->xmit.head;
+ tail = info->xmit.tail;
+ start = (char *)&info->xmit.buf[tail];
+
+ /* write out all the data or until the end of the buffer */
+ xmit_count = (head < tail) ? (UART_XMIT_SIZE - tail) : (head - tail);
+ if (xmit_count > 0) {
+ result = do_write(port, start, xmit_count);
+ if (result > 0) {
+ /* booking */
+ xmit_count -= result;
+ the_port->icount.tx += result;
+ /* advance the pointers */
+ tail += result;
+ tail &= UART_XMIT_SIZE - 1;
+ info->xmit.tail = tail;
+ start = (char *)&info->xmit.buf[tail];
+ }
+ }
+ if (uart_circ_chars_pending(&info->xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(the_port);
+
+ if (uart_circ_empty(&info->xmit)) {
+ set_notification(port, N_OUTPUT_LOWAT, 0);
+ } else {
+ set_notification(port, N_OUTPUT_LOWAT, 1);
+ }
+}
+
+/**
+ * ioc3_change_speed - change the speed of the port
+ * @the_port: port to change
+ * @new_termios: new termios settings
+ * @old_termios: old termios settings
+ */
+static void
+ioc3_change_speed(struct uart_port *the_port,
+ struct termios *new_termios, struct termios *old_termios)
+{
+ struct ioc3_port *port = get_ioc3_port(the_port);
+ unsigned int cflag;
+ int baud;
+ int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8;
+ struct uart_info *info = the_port->info;
+
+ cflag = new_termios->c_cflag;
+
+ switch (cflag & CSIZE) {
+ case CS5:
+ new_data = 5;
+ break;
+ case CS6:
+ new_data = 6;
+ break;
+ case CS7:
+ new_data = 7;
+ break;
+ case CS8:
+ new_data = 8;
+ break;
+ default:
+ /* cuz we always need a default ... */
+ new_data = 5;
+ break;
+ }
+ if (cflag & CSTOPB) {
+ new_stop = 1;
+ }
+ if (cflag & PARENB) {
+ new_parity_enable = 1;
+ if (cflag & PARODD)
+ new_parity = 1;
+ }
+ baud = uart_get_baud_rate(the_port, new_termios, old_termios,
+ MIN_BAUD_SUPPORTED, MAX_BAUD_SUPPORTED);
+ DPRINT_CONFIG(("%s: returned baud %d for line %d\n", __FUNCTION__, baud,
+ the_port->line));
+
+ if (!the_port->fifosize)
+ the_port->fifosize = FIFO_SIZE;
+ uart_update_timeout(the_port, cflag, baud);
+
+ the_port->ignore_status_mask = N_ALL_INPUT;
+
+ info->tty->low_latency = 1;
+
+ if (I_IGNPAR(info->tty))
+ the_port->ignore_status_mask &= ~(N_PARITY_ERROR
+ | N_FRAMING_ERROR);
+ if (I_IGNBRK(info->tty)) {
+ the_port->ignore_status_mask &= ~N_BREAK;
+ if (I_IGNPAR(info->tty))
+ the_port->ignore_status_mask &= ~N_OVERRUN_ERROR;
+ }
+ if (!(cflag & CREAD)) {
+ /* ignore everything */
+ the_port->ignore_status_mask &= ~N_DATA_READY;
+ }
+
+ if (cflag & CRTSCTS) {
+ /* enable hardware flow control */
+ port->ip_sscr |= SSCR_HFC_EN;
+ }
+ else {
+ /* disable hardware flow control */
+ port->ip_sscr &= ~SSCR_HFC_EN;
+ }
+ writel(port->ip_sscr, &port->ip_serial_regs->sscr);
+
+ /* Set the configuration and proper notification call */
+ DPRINT_CONFIG(("%s : port 0x%p line %d cflag 0%o "
+ "config_port(baud %d data %d stop %d penable %d "
+ " parity %d), notification 0x%x\n",
+ __FUNCTION__, (void *)port, the_port->line, cflag, baud,
+ new_data, new_stop, new_parity_enable, new_parity,
+ the_port->ignore_status_mask));
+
+ if ((config_port(port, baud, /* baud */
+ new_data, /* byte size */
+ new_stop, /* stop bits */
+ new_parity_enable, /* set parity */
+ new_parity)) >= 0) { /* parity 1==odd */
+ set_notification(port, the_port->ignore_status_mask, 1);
+ }
+}
+
+/**
+ * ic3_startup_local - Start up the serial port - returns >= 0 if no errors
+ * @the_port: Port to operate on
+ */
+static inline int ic3_startup_local(struct uart_port *the_port)
+{
+ struct ioc3_port *port;
+
+ if (!the_port) {
+ NOT_PROGRESS();
+ return -1;
+ }
+
+ port = get_ioc3_port(the_port);
+ if (!port) {
+ NOT_PROGRESS();
+ return -1;
+ }
+
+ local_open(port);
+
+ /* set the protocol */
+ ioc3_set_proto(port, IS_RS232(the_port->line) ? PROTO_RS232 :
+ PROTO_RS422);
+ return 0;
+}
+
+/*
+ * ioc3_cb_output_lowat - called when the output low water mark is hit
+ * @port: port to output
+ */
+static void ioc3_cb_output_lowat(struct ioc3_port *port)
+{
+ unsigned long pflags;
+
+ /* the_port->lock is set on the call here */
+ if (port->ip_port) {
+ spin_lock_irqsave(&port->ip_port->lock, pflags);
+ transmit_chars(port->ip_port);
+ spin_unlock_irqrestore(&port->ip_port->lock, pflags);
+ }
+}
+
+/*
+ * ioc3_cb_post_ncs - called for some basic errors
+ * @port: port to use
+ * @ncs: event
+ */
+static void ioc3_cb_post_ncs(struct uart_port *the_port, int ncs)
+{
+ struct uart_icount *icount;
+
+ icount = &the_port->icount;
+
+ if (ncs & NCS_BREAK)
+ icount->brk++;
+ if (ncs & NCS_FRAMING)
+ icount->frame++;
+ if (ncs & NCS_OVERRUN)
+ icount->overrun++;
+ if (ncs & NCS_PARITY)
+ icount->parity++;
+}
+
+/**
+ * do_read - Read in bytes from the port. Return the number of bytes
+ * actually read.
+ * @the_port: port to use
+ * @buf: place to put the stuff we read
+ * @len: how big 'buf' is
+ */
+
+static inline int do_read(struct uart_port *the_port, char *buf, int len)
+{
+ int prod_ptr, cons_ptr, total;
+ struct ioc3_port *port = get_ioc3_port(the_port);
+ struct ring *inring;
+ struct ring_entry *entry;
+ struct port_hooks *hooks = port->ip_hooks;
+ int byte_num;
+ char *sc;
+ int loop_counter;
+
+ BUG_ON(!(len >= 0));
+ BUG_ON(!port);
+
+ /* There is a nasty timing issue in the IOC3. When the rx_timer
+ * expires or the rx_high condition arises, we take an interrupt.
+ * At some point while servicing the interrupt, we read bytes from
+ * the ring buffer and re-arm the rx_timer. However the rx_timer is
+ * not started until the first byte is received *after* it is armed,
+ * and any bytes pending in the rx construction buffers are not drained
+ * to memory until either there are 4 bytes available or the rx_timer
+ * expires. This leads to a potential situation where data is left
+ * in the construction buffers forever - 1 to 3 bytes were received
+ * after the interrupt was generated but before the rx_timer was
+ * re-armed. At that point as long as no subsequent bytes are received
+ * the timer will never be started and the bytes will remain in the
+ * construction buffer forever. The solution is to execute a DRAIN
+ * command after rearming the timer. This way any bytes received before
+ * the DRAIN will be drained to memory, and any bytes received after
+ * the DRAIN will start the TIMER and be drained when it expires.
+ * Luckily, this only needs to be done when the DMA buffer is empty
+ * since there is no requirement that this function return all
+ * available data as long as it returns some.
+ */
+ /* Re-arm the timer */
+
+ writel(port->ip_rx_cons | SRCIR_ARM, &port->ip_serial_regs->srcir);
+
+ prod_ptr = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;
+ cons_ptr = port->ip_rx_cons;
+
+ if (prod_ptr == cons_ptr) {
+ int reset_dma = 0;
+
+ /* Input buffer appears empty, do a flush. */
+
+ /* DMA must be enabled for this to work. */
+ if (!(port->ip_sscr & SSCR_DMA_EN)) {
+ port->ip_sscr |= SSCR_DMA_EN;
+ reset_dma = 1;
+ }
+
+ /* Potential race condition: we must reload the srpir after
+ * issuing the drain command, otherwise we could think the rx
+ * buffer is empty, then take a very long interrupt, and when
+ * we come back it's full and we wait forever for the drain to
+ * complete.
+ */
+ writel(port->ip_sscr | SSCR_RX_DRAIN,
+ &port->ip_serial_regs->sscr);
+ prod_ptr = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;
+
+ /* We must not wait for the DRAIN to complete unless there are
+ * at least 8 bytes (2 ring entries) available to receive the
+ * data otherwise the DRAIN will never complete and we'll
+ * deadlock here.
+ * In fact, to make things easier, I'll just ignore the flush if
+ * there is any data at all now available.
+ */
+ if (prod_ptr == cons_ptr) {
+ loop_counter = 0;
+ while (readl(&port->ip_serial_regs->sscr) &
+ SSCR_RX_DRAIN) {
+ loop_counter++;
+ if (loop_counter > MAXITER)
+ return -1;
+ }
+
+ /* SIGH. We have to reload the prod_ptr *again* since
+ * the drain may have caused it to change
+ */
+ prod_ptr = readl(&port->ip_serial_regs->srpir)
+ & PROD_CONS_MASK;
+ }
+ if (reset_dma) {
+ port->ip_sscr &= ~SSCR_DMA_EN;
+ writel(port->ip_sscr, &port->ip_serial_regs->sscr);
+ }
+ }
+ inring = port->ip_inring;
+ port->ip_flags &= ~READ_ABORTED;
+
+ total = 0;
+ loop_counter = 0xfffff; /* to avoid hangs */
+
+ /* Grab bytes from the hardware */
+ while ((prod_ptr != cons_ptr) && (len > 0)) {
+ entry = (struct ring_entry *)((caddr_t) inring + cons_ptr);
+
+ if (loop_counter-- <= 0) {
+ printk(KERN_WARNING "IOC3 serial: "
+ "possible hang condition/"
+ "port stuck on read (line %d).\n",
+ the_port->line);
+ break;
+ }
+
+ /* According to the producer pointer, this ring entry
+ * must contain some data. But if the PIO happened faster
+ * than the DMA, the data may not be available yet, so let's
+ * wait until it arrives.
+ */
+ if ((entry->ring_allsc & RING_ANY_VALID) == 0) {
+ /* Indicate the read is aborted so we don't disable
+ * the interrupt thinking that the consumer is
+ * congested.
+ */
+ port->ip_flags |= READ_ABORTED;
+ len = 0;
+ break;
+ }
+
+ /* Load the bytes/status out of the ring entry */
+ for (byte_num = 0; byte_num < 4 && len > 0; byte_num++) {
+ sc = &(entry->ring_sc[byte_num]);
+
+ /* Check for change in modem state or overrun */
+ if ((*sc & RXSB_MODEM_VALID)
+ && (port->ip_notify & N_DDCD)) {
+ /* Notify upper layer if DCD dropped */
+ if ((port->ip_flags & DCD_ON)
+ && !(*sc & RXSB_DCD)) {
+ /* If we have already copied some data,
+ * return it. We'll pick up the carrier
+ * drop on the next pass. That way we
+ * don't throw away the data that has
+ * already been copied back to
+ * the caller's buffer.
+ */
+ if (total > 0) {
+ len = 0;
+ break;
+ }
+ port->ip_flags &= ~DCD_ON;
+
+ /* Turn off this notification so the
+ * carrier drop protocol won't see it
+ * again when it does a read.
+ */
+ *sc &= ~RXSB_MODEM_VALID;
+
+ /* To keep things consistent, we need
+ * to update the consumer pointer so
+ * the next reader won't come in and
+ * try to read the same ring entries
+ * again. This must be done here before
+ * the dcd change.
+ */
+
+ if ((entry->ring_allsc & RING_ANY_VALID)
+ == 0) {
+ cons_ptr += (int)sizeof
+ (struct ring_entry);
+ cons_ptr &= PROD_CONS_MASK;
+ }
+ writel(cons_ptr,
+ &port->ip_serial_regs->srcir);
+ port->ip_rx_cons = cons_ptr;
+
+ /* Notify upper layer of carrier drop */
+ if ((port->ip_notify & N_DDCD)
+ && port->ip_port) {
+ uart_handle_dcd_change
+ (port->ip_port, 0);
+ wake_up_interruptible
+ (&the_port->info->
+ delta_msr_wait);
+ }
+
+ /* If we had any data to return, we
+ * would have returned it above.
+ */
+ return 0;
+ }
+ }
+ if (*sc & RXSB_MODEM_VALID) {
+ /* Notify that an input overrun occurred */
+ if ((*sc & RXSB_OVERRUN)
+ && (port->ip_notify & N_OVERRUN_ERROR)) {
+ ioc3_cb_post_ncs(the_port, NCS_OVERRUN);
+ }
+ /* Don't look at this byte again */
+ *sc &= ~RXSB_MODEM_VALID;
+ }
+
+ /* Check for valid data or RX errors */
+ if ((*sc & RXSB_DATA_VALID) &&
+ ((*sc & (RXSB_PAR_ERR
+ | RXSB_FRAME_ERR | RXSB_BREAK))
+ && (port->ip_notify & (N_PARITY_ERROR
+ | N_FRAMING_ERROR
+ | N_BREAK)))) {
+ /* There is an error condition on the next byte.
+ * If we have already transferred some bytes,
+ * we'll stop here. Otherwise if this is the
+ * first byte to be read, we'll just transfer
+ * it alone after notifying the
+ * upper layer of its status.
+ */
+ if (total > 0) {
+ len = 0;
+ break;
+ } else {
+ if ((*sc & RXSB_PAR_ERR) &&
+ (port->
+ ip_notify & N_PARITY_ERROR)) {
+ ioc3_cb_post_ncs(the_port,
+ NCS_PARITY);
+ }
+ if ((*sc & RXSB_FRAME_ERR) &&
+ (port->
+ ip_notify & N_FRAMING_ERROR)) {
+ ioc3_cb_post_ncs(the_port,
+ NCS_FRAMING);
+ }
+ if ((*sc & RXSB_BREAK)
+ && (port->ip_notify & N_BREAK)) {
+ ioc3_cb_post_ncs
+ (the_port, NCS_BREAK);
+ }
+ len = 1;
+ }
+ }
+ if (*sc & RXSB_DATA_VALID) {
+ *sc &= ~RXSB_DATA_VALID;
+ *buf = entry->ring_data[byte_num];
+ buf++;
+ len--;
+ total++;
+ }
+ }
+
+ /* If we used up this entry entirely, go on to the next one,
+ * otherwise we must have run out of buffer space, so
+ * leave the consumer pointer here for the next read in case
+ * there are still unread bytes in this entry.
+ */
+ if ((entry->ring_allsc & RING_ANY_VALID) == 0) {
+ cons_ptr += (int)sizeof(struct ring_entry);
+ cons_ptr &= PROD_CONS_MASK;
+ }
+ }
+
+ /* Update consumer pointer and re-arm rx timer interrupt */
+ writel(cons_ptr, &port->ip_serial_regs->srcir);
+ port->ip_rx_cons = cons_ptr;
+
+ /* If we have now dipped below the rx high water mark and we have
+ * rx_high interrupt turned off, we can now turn it back on again.
+ */
+ if ((port->ip_flags & INPUT_HIGH) && (((prod_ptr - cons_ptr)
+ & PROD_CONS_MASK) <
+ ((port->
+ ip_sscr &
+ SSCR_RX_THRESHOLD)
+ << PROD_CONS_PTR_OFF))) {
+ port->ip_flags &= ~INPUT_HIGH;
+ enable_intrs(port, hooks->intr_rx_high);
+ }
+ return total;
+}
+
+/**
+ * receive_chars - upper level read.
+ * @the_port: port to read from
+ */
+static int receive_chars(struct uart_port *the_port)
+{
+ struct tty_struct *tty;
+ unsigned char ch[MAX_CHARS];
+ int read_count = 0, read_room, flip = 0;
+ struct uart_info *info = the_port->info;
+ struct ioc3_port *port = get_ioc3_port(the_port);
+ unsigned long pflags;
+
+ /* Make sure all the pointers are "good" ones */
+ if (!info)
+ return 0;
+ if (!info->tty)
+ return 0;
+
+ if (!(port->ip_flags & INPUT_ENABLE))
+ return 0;
+
+ spin_lock_irqsave(&the_port->lock, pflags);
+ tty = info->tty;
+
+ read_count = do_read(the_port, ch, MAX_CHARS);
+ if (read_count > 0) {
+ flip = 1;
+ read_room = tty_buffer_request_room(tty, read_count);
+ tty_insert_flip_string(tty, ch, read_room);
+ the_port->icount.rx += read_count;
+ }
+ spin_unlock_irqrestore(&the_port->lock, pflags);
+
+ if (flip)
+ tty_flip_buffer_push(tty);
+
+ return read_count;
+}
+
+/**
+ * ioc3uart_intr_one - lowest level (per port) interrupt handler.
+ * @is : submodule
+ * @idd: driver data
+ * @pending: interrupts to handle
+ * @regs: pt_regs
+ */
+
+static int inline
+ioc3uart_intr_one(struct ioc3_submodule *is,
+ struct ioc3_driver_data *idd,
+ unsigned int pending, struct pt_regs *regs)
+{
+ int port_num = GET_PORT_FROM_SIO_IR(pending);
+ struct port_hooks *hooks;
+ unsigned int rx_high_rd_aborted = 0;
+ unsigned long flags;
+ struct uart_port *the_port;
+ struct ioc3_port *port;
+ int loop_counter;
+ struct ioc3_card *card_ptr;
+ unsigned int sio_ir;
+
+ card_ptr = idd->data[is->id];
+ port = card_ptr->ic_port[port_num].icp_port;
+ hooks = port->ip_hooks;
+
+ /* Possible race condition here: The tx_mt interrupt bit may be
+ * cleared without the intervention of the interrupt handler,
+ * e.g. by a write. If the top level interrupt handler reads a
+ * tx_mt, then some other processor does a write, starting up
+ * output, then we come in here, see the tx_mt and stop DMA, the
+ * output started by the other processor will hang. Thus we can
+ * only rely on tx_mt being legitimate if it is read while the
+ * port lock is held. Therefore this bit must be ignored in the
+ * passed in interrupt mask which was read by the top level
+ * interrupt handler since the port lock was not held at the time
+ * it was read. We can only rely on this bit being accurate if it
+ * is read while the port lock is held. So we'll clear it for now,
+ * and reload it later once we have the port lock.
+ */
+
+ sio_ir = pending & ~(hooks->intr_tx_mt);
+ spin_lock_irqsave(&port->ip_lock, flags);
+
+ loop_counter = MAXITER; /* to avoid hangs */
+
+ do {
+ uint32_t shadow;
+
+ if (loop_counter-- <= 0) {
+ printk(KERN_WARNING "IOC3 serial: "
+ "possible hang condition/"
+ "port stuck on interrupt (line %d).\n",
+ ((struct uart_port *)port->ip_port)->line);
+ break;
+ }
+ /* Handle a DCD change */
+ if (sio_ir & hooks->intr_delta_dcd) {
+ ioc3_ack(is, idd, hooks->intr_delta_dcd);
+ shadow = readl(&port->ip_serial_regs->shadow);
+
+ if ((port->ip_notify & N_DDCD)
+ && (shadow & SHADOW_DCD)
+ && (port->ip_port)) {
+ the_port = port->ip_port;
+ uart_handle_dcd_change(the_port,
+ shadow & SHADOW_DCD);
+ wake_up_interruptible
+ (&the_port->info->delta_msr_wait);
+ } else if ((port->ip_notify & N_DDCD)
+ && !(shadow & SHADOW_DCD)) {
+ /* Flag delta DCD/no DCD */
+ uart_handle_dcd_change(port->ip_port,
+ shadow & SHADOW_DCD);
+ port->ip_flags |= DCD_ON;
+ }
+ }
+
+ /* Handle a CTS change */
+ if (sio_ir & hooks->intr_delta_cts) {
+ ioc3_ack(is, idd, hooks->intr_delta_cts);
+ shadow = readl(&port->ip_serial_regs->shadow);
+
+ if ((port->ip_notify & N_DCTS) && (port->ip_port)) {
+ the_port = port->ip_port;
+ uart_handle_cts_change(the_port, shadow
+ & SHADOW_CTS);
+ wake_up_interruptible
+ (&the_port->info->delta_msr_wait);
+ }
+ }
+
+ /* rx timeout interrupt. Must be some data available. Put this
+ * before the check for rx_high since servicing this condition
+ * may cause that condition to clear.
+ */
+ if (sio_ir & hooks->intr_rx_timer) {
+ ioc3_ack(is, idd, hooks->intr_rx_timer);
+ if ((port->ip_notify & N_DATA_READY)
+ && (port->ip_port)) {
+ receive_chars(port->ip_port);
+ }
+ }
+
+ /* rx high interrupt. Must be after rx_timer. */
+ else if (sio_ir & hooks->intr_rx_high) {
+ /* Data available, notify upper layer */
+ if ((port->ip_notify & N_DATA_READY) && port->ip_port) {
+ receive_chars(port->ip_port);
+ }
+
+ /* We can't ACK this interrupt. If receive_chars didn't
+ * cause the condition to clear, we'll have to disable
+ * the interrupt until the data is drained.
+ * If the read was aborted, don't disable the interrupt
+ * as this may cause us to hang indefinitely. An
+ * aborted read generally means that this interrupt
+ * hasn't been delivered to the cpu yet anyway, even
+ * though we see it as asserted when we read the sio_ir.
+ */
+ if ((sio_ir = PENDING(card_ptr, idd))
+ & hooks->intr_rx_high) {
+ if (port->ip_flags & READ_ABORTED) {
+ rx_high_rd_aborted++;
+ }
+ else {
+ card_ptr->ic_enable &= ~hooks->intr_rx_high;
+ port->ip_flags |= INPUT_HIGH;
+ }
+ }
+ }
+
+ /* We got a low water interrupt: notify upper layer to
+ * send more data. Must come before tx_mt since servicing
+ * this condition may cause that condition to clear.
+ */
+ if (sio_ir & hooks->intr_tx_explicit) {
+ port->ip_flags &= ~LOWAT_WRITTEN;
+ ioc3_ack(is, idd, hooks->intr_tx_explicit);
+ if (port->ip_notify & N_OUTPUT_LOWAT)
+ ioc3_cb_output_lowat(port);
+ }
+
+ /* Handle tx_mt. Must come after tx_explicit. */
+ else if (sio_ir & hooks->intr_tx_mt) {
+ /* If we are expecting a lowat notification
+ * and we get to this point it probably means that for
+ * some reason the tx_explicit didn't work as expected
+ * (that can legitimately happen if the output buffer is
+ * filled up in just the right way).
+ * So send the notification now.
+ */
+ if (port->ip_notify & N_OUTPUT_LOWAT) {
+ ioc3_cb_output_lowat(port);
+
+ /* We need to reload the sio_ir since the lowat
+ * call may have caused another write to occur,
+ * clearing the tx_mt condition.
+ */
+ sio_ir = PENDING(card_ptr, idd);
+ }
+
+ /* If the tx_mt condition still persists even after the
+ * lowat call, we've got some work to do.
+ */
+ if (sio_ir & hooks->intr_tx_mt) {
+ /* If we are not currently expecting DMA input,
+ * and the transmitter has just gone idle,
+ * there is no longer any reason for DMA, so
+ * disable it.
+ */
+ if (!(port->ip_notify
+ & (N_DATA_READY | N_DDCD))) {
+ BUG_ON(!(port->ip_sscr
+ & SSCR_DMA_EN));
+ port->ip_sscr &= ~SSCR_DMA_EN;
+ writel(port->ip_sscr,
+ &port->ip_serial_regs->sscr);
+ }
+ /* Prevent infinite tx_mt interrupt */
+ card_ptr->ic_enable &= ~hooks->intr_tx_mt;
+ }
+ }
+ sio_ir = PENDING(card_ptr, idd);
+
+ /* if the read was aborted and only hooks->intr_rx_high,
+ * clear hooks->intr_rx_high, so we do not loop forever.
+ */
+
+ if (rx_high_rd_aborted && (sio_ir == hooks->intr_rx_high)) {
+ sio_ir &= ~hooks->intr_rx_high;
+ }
+ } while (sio_ir & hooks->intr_all);
+
+ spin_unlock_irqrestore(&port->ip_lock, flags);
+ ioc3_enable(is, idd, card_ptr->ic_enable);
+ return 0;
+}
+
+/**
+ * ioc3uart_intr - field all serial interrupts
+ * @is : submodule
+ * @idd: driver data
+ * @pending: interrupts to handle
+ * @regs: pt_regs
+ *
+ */
+
+static int ioc3uart_intr(struct ioc3_submodule *is,
+ struct ioc3_driver_data *idd,
+ unsigned int pending, struct pt_regs *regs)
+{
+ int ret = 0;
+
+ /*
+ * The upper level interrupt handler sends interrupts for both ports
+ * here. So we need to call for each port with its interrupts.
+ */
+
+ if (pending & SIO_IR_SA)
+ ret |= ioc3uart_intr_one(is, idd, pending & SIO_IR_SA, regs);
+ if (pending & SIO_IR_SB)
+ ret |= ioc3uart_intr_one(is, idd, pending & SIO_IR_SB, regs);
+
+ return ret;
+}
+
+/**
+ * ic3_type
+ * @port: Port to operate with (we ignore since we only have one port)
+ *
+ */
+static const char *ic3_type(struct uart_port *the_port)
+{
+ if (IS_RS232(the_port->line))
+ return "SGI IOC3 Serial [rs232]";
+ else
+ return "SGI IOC3 Serial [rs422]";
+}
+
+/**
+ * ic3_tx_empty - Is the transmitter empty?
+ * @port: Port to operate on
+ *
+ */
+static unsigned int ic3_tx_empty(struct uart_port *the_port)
+{
+ unsigned int ret = 0;
+ struct ioc3_port *port = get_ioc3_port(the_port);
+
+ if (readl(&port->ip_serial_regs->shadow) & SHADOW_TEMT)
+ ret = TIOCSER_TEMT;
+ return ret;
+}
+
+/**
+ * ic3_stop_tx - stop the transmitter
+ * @port: Port to operate on
+ *
+ */
+static void ic3_stop_tx(struct uart_port *the_port)
+{
+ struct ioc3_port *port = get_ioc3_port(the_port);
+
+ if (port)
+ set_notification(port, N_OUTPUT_LOWAT, 0);
+}
+
+/**
+ * ic3_stop_rx - stop the receiver
+ * @port: Port to operate on
+ *
+ */
+static void ic3_stop_rx(struct uart_port *the_port)
+{
+ struct ioc3_port *port = get_ioc3_port(the_port);
+
+ if (port)
+ port->ip_flags &= ~INPUT_ENABLE;
+}
+
+/**
+ * null_void_function
+ * @port: Port to operate on
+ *
+ */
+static void null_void_function(struct uart_port *the_port)
+{
+}
+
+/**
+ * ic3_shutdown - shut down the port - free irq and disable
+ * @port: port to shut down
+ *
+ */
+static void ic3_shutdown(struct uart_port *the_port)
+{
+ unsigned long port_flags;
+ struct ioc3_port *port;
+ struct uart_info *info;
+
+ port = get_ioc3_port(the_port);
+ if (!port)
+ return;
+
+ info = the_port->info;
+ wake_up_interruptible(&info->delta_msr_wait);
+
+ spin_lock_irqsave(&the_port->lock, port_flags);
+ set_notification(port, N_ALL, 0);
+ spin_unlock_irqrestore(&the_port->lock, port_flags);
+}
+
+/**
+ * ic3_set_mctrl - set control lines (dtr, rts, etc)
+ * @port: Port to operate on
+ * @mctrl: Lines to set/unset
+ *
+ */
+static void ic3_set_mctrl(struct uart_port *the_port, unsigned int mctrl)
+{
+ unsigned char mcr = 0;
+
+ if (mctrl & TIOCM_RTS)
+ mcr |= UART_MCR_RTS;
+ if (mctrl & TIOCM_DTR)
+ mcr |= UART_MCR_DTR;
+ if (mctrl & TIOCM_OUT1)
+ mcr |= UART_MCR_OUT1;
+ if (mctrl & TIOCM_OUT2)
+ mcr |= UART_MCR_OUT2;
+ if (mctrl & TIOCM_LOOP)
+ mcr |= UART_MCR_LOOP;
+
+ set_mcr(the_port, mcr, SHADOW_DTR);
+}
+
+/**
+ * ic3_get_mctrl - get control line info
+ * @port: port to operate on
+ *
+ */
+static unsigned int ic3_get_mctrl(struct uart_port *the_port)
+{
+ struct ioc3_port *port = get_ioc3_port(the_port);
+ uint32_t shadow;
+ unsigned int ret = 0;
+
+ if (!port)
+ return 0;
+
+ shadow = readl(&port->ip_serial_regs->shadow);
+ if (shadow & SHADOW_DCD)
+ ret |= TIOCM_CD;
+ if (shadow & SHADOW_DR)
+ ret |= TIOCM_DSR;
+ if (shadow & SHADOW_CTS)
+ ret |= TIOCM_CTS;
+ return ret;
+}
+
+/**
+ * ic3_start_tx - Start transmitter. Called with the_port->lock
+ * @port: Port to operate on
+ *
+ */
+static void ic3_start_tx(struct uart_port *the_port)
+{
+ struct ioc3_port *port = get_ioc3_port(the_port);
+
+ if (port) {
+ set_notification(port, N_OUTPUT_LOWAT, 1);
+ enable_intrs(port, port->ip_hooks->intr_tx_mt);
+ }
+}
+
+/**
+ * ic3_break_ctl - handle breaks
+ * @port: Port to operate on
+ * @break_state: Break state
+ *
+ */
+static void ic3_break_ctl(struct uart_port *the_port, int break_state)
+{
+}
+
+/**
+ * ic3_startup - Start up the serial port - always return 0 (We're always on)
+ * @port: Port to operate on
+ *
+ */
+static int ic3_startup(struct uart_port *the_port)
+{
+ int retval;
+ struct ioc3_port *port;
+ struct ioc3_card *card_ptr;
+ unsigned long port_flags;
+
+ if (!the_port) {
+ NOT_PROGRESS();
+ return -ENODEV;
+ }
+ port = get_ioc3_port(the_port);
+ if (!port) {
+ NOT_PROGRESS();
+ return -ENODEV;
+ }
+ card_ptr = port->ip_card;
+ port->ip_port = the_port;
+
+ if (!card_ptr) {
+ NOT_PROGRESS();
+ return -ENODEV;
+ }
+
+ /* Start up the serial port */
+ spin_lock_irqsave(&the_port->lock, port_flags);
+ retval = ic3_startup_local(the_port);
+ spin_unlock_irqrestore(&the_port->lock, port_flags);
+ return retval;
+}
+
+/**
+ * ic3_set_termios - set termios stuff
+ * @port: port to operate on
+ * @termios: New settings
+ * @termios: Old
+ *
+ */
+static void
+ic3_set_termios(struct uart_port *the_port,
+ struct termios *termios, struct termios *old_termios)
+{
+ unsigned long port_flags;
+
+ spin_lock_irqsave(&the_port->lock, port_flags);
+ ioc3_change_speed(the_port, termios, old_termios);
+ spin_unlock_irqrestore(&the_port->lock, port_flags);
+}
+
+/**
+ * ic3_request_port - allocate resources for port - no op....
+ * @port: port to operate on
+ *
+ */
+static int ic3_request_port(struct uart_port *port)
+{
+ return 0;
+}
+
+/* Associate the uart functions above - given to serial core */
+static struct uart_ops ioc3_ops = {
+ .tx_empty = ic3_tx_empty,
+ .set_mctrl = ic3_set_mctrl,
+ .get_mctrl = ic3_get_mctrl,
+ .stop_tx = ic3_stop_tx,
+ .start_tx = ic3_start_tx,
+ .stop_rx = ic3_stop_rx,
+ .enable_ms = null_void_function,
+ .break_ctl = ic3_break_ctl,
+ .startup = ic3_startup,
+ .shutdown = ic3_shutdown,
+ .set_termios = ic3_set_termios,
+ .type = ic3_type,
+ .release_port = null_void_function,
+ .request_port = ic3_request_port,
+};
+
+/*
+ * Boot-time initialization code
+ */
+
+static struct uart_driver ioc3_uart = {
+ .owner = THIS_MODULE,
+ .driver_name = "ioc3_serial",
+ .dev_name = DEVICE_NAME,
+ .major = DEVICE_MAJOR,
+ .minor = DEVICE_MINOR,
+ .nr = MAX_LOGICAL_PORTS
+};
+
+/**
+ * ioc3_serial_core_attach - register with serial core
+ * This is done during pci probing
+ * @is: submodule struct for this
+ * @idd: handle for this card
+ */
+static inline int ioc3_serial_core_attach( struct ioc3_submodule *is,
+ struct ioc3_driver_data *idd)
+{
+ struct ioc3_port *port;
+ struct uart_port *the_port;
+ struct ioc3_card *card_ptr = idd->data[is->id];
+ int ii, phys_port;
+ struct pci_dev *pdev = idd->pdev;
+
+ DPRINT_CONFIG(("%s: attach pdev 0x%p - card_ptr 0x%p\n",
+ __FUNCTION__, pdev, (void *)card_ptr));
+
+ if (!card_ptr)
+ return -ENODEV;
+
+ /* once around for each logical port on this card */
+ for (ii = 0; ii < LOGICAL_PORTS_PER_CARD; ii++) {
+ phys_port = GET_PHYSICAL_PORT(ii);
+ the_port = &card_ptr->ic_port[phys_port].
+ icp_uart_port[GET_LOGICAL_PORT(ii)];
+ port = card_ptr->ic_port[phys_port].icp_port;
+ port->ip_port = the_port;
+
+ DPRINT_CONFIG(("%s: attach the_port 0x%p / port 0x%p [%d/%d]\n",
+ __FUNCTION__, (void *)the_port, (void *)port,
+ phys_port, ii));
+
+ /* membase, iobase and mapbase just need to be non-0 */
+ the_port->membase = (unsigned char __iomem *)1;
+ the_port->iobase = (pdev->bus->number << 16) | ii;
+ the_port->line = (Num_of_ioc3_cards << 2) | ii;
+ the_port->mapbase = 1;
+ the_port->type = PORT_16550A;
+ the_port->fifosize = FIFO_SIZE;
+ the_port->ops = &ioc3_ops;
+ the_port->irq = idd->irq_io;
+ the_port->dev = &pdev->dev;
+
+ if (uart_add_one_port(&ioc3_uart, the_port) < 0) {
+ printk(KERN_WARNING
+ "%s: unable to add port %d bus %d\n",
+ __FUNCTION__, the_port->line, pdev->bus->number);
+ } else {
+ DPRINT_CONFIG(("IOC3 serial port %d irq %d bus %d\n",
+ the_port->line, the_port->irq, pdev->bus->number));
+ }
+
+ /* all ports are rs232 for now */
+ if (IS_PHYSICAL_PORT(ii))
+ ioc3_set_proto(port, PROTO_RS232);
+ }
+ return 0;
+}
+
+/**
+ * ioc3uart_remove - register detach function
+ * @is: submodule struct for this submodule
+ * @idd: ioc3 driver data for this submodule
+ */
+
+static int ioc3uart_remove(struct ioc3_submodule *is,
+ struct ioc3_driver_data *idd)
+{
+ struct ioc3_card *card_ptr = idd->data[is->id];
+ struct uart_port *the_port;
+ struct ioc3_port *port;
+ int ii;
+
+ if (card_ptr) {
+ for (ii = 0; ii < LOGICAL_PORTS_PER_CARD; ii++) {
+ the_port = &card_ptr->ic_port[GET_PHYSICAL_PORT(ii)].
+ icp_uart_port[GET_LOGICAL_PORT(ii)];
+ if (the_port)
+ uart_remove_one_port(&ioc3_uart, the_port);
+ port = card_ptr->ic_port[GET_PHYSICAL_PORT(ii)].icp_port;
+ if (port && IS_PHYSICAL_PORT(ii)
+ && (GET_PHYSICAL_PORT(ii) == 0)) {
+ pci_free_consistent(port->ip_idd->pdev,
+ TOTAL_RING_BUF_SIZE,
+ (void *)port->ip_cpu_ringbuf,
+ port->ip_dma_ringbuf);
+ kfree(port);
+ card_ptr->ic_port[GET_PHYSICAL_PORT(ii)].
+ icp_port = NULL;
+ }
+ }
+ kfree(card_ptr);
+ idd->data[is->id] = NULL;
+ }
+ return 0;
+}
+
+/**
+ * ioc3uart_probe - card probe function called from shim driver
+ * @is: submodule struct for this submodule
+ * @idd: ioc3 driver data for this card
+ */
+
+static int __devinit
+ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
+{
+ struct pci_dev *pdev = idd->pdev;
+ struct ioc3_card *card_ptr;
+ int ret = 0;
+ struct ioc3_port *port;
+ struct ioc3_port *ports[PORTS_PER_CARD];
+ int phys_port;
+
+ DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __FUNCTION__, is, idd));
+
+ card_ptr = kmalloc(sizeof(struct ioc3_card), GFP_KERNEL);
+ if (!card_ptr) {
+ printk(KERN_WARNING "ioc3_attach_one"
+ ": unable to get memory for the IOC3\n");
+ return -ENOMEM;
+ }
+ memset(card_ptr, 0, sizeof(struct ioc3_card));
+ idd->data[is->id] = card_ptr;
+ Submodule_slot = is->id;
+
+ writel(((UARTA_BASE >> 3) << SIO_CR_SER_A_BASE_SHIFT) |
+ ((UARTB_BASE >> 3) << SIO_CR_SER_B_BASE_SHIFT) |
+ (0xf << SIO_CR_CMD_PULSE_SHIFT), &idd->vma->sio_cr);
+
+ pci_write_config_dword(pdev, PCI_LAT, 0xff00);
+
+ /* Enable serial port mode select generic PIO pins as outputs */
+ ioc3_gpcr_set(idd, GPCR_UARTA_MODESEL | GPCR_UARTB_MODESEL);
+
+ /* Create port structures for each port */
+ for (phys_port = 0; phys_port < PORTS_PER_CARD; phys_port++) {
+ port = kmalloc(sizeof(struct ioc3_port), GFP_KERNEL);
+ if (!port) {
+ printk(KERN_WARNING
+ "IOC3 serial memory not available for port\n");
+ goto out4;
+ }
+ memset(port, 0, sizeof(struct ioc3_port));
+ spin_lock_init(&port->ip_lock);
+
+ /* we need to remember the previous ones, to point back to
+ * them farther down - setting up the ring buffers.
+ */
+ ports[phys_port] = port;
+
+ /* init to something useful */
+ card_ptr->ic_port[phys_port].icp_port = port;
+ port->ip_is = is;
+ port->ip_idd = idd;
+ port->ip_baud = 9600;
+ port->ip_card = card_ptr;
+ port->ip_hooks = &hooks_array[phys_port];
+
+ /* Setup each port */
+ if (phys_port == 0) {
+ port->ip_serial_regs = &idd->vma->port_a;
+ port->ip_uart_regs = &idd->vma->sregs.uarta;
+
+ DPRINT_CONFIG(("%s : Port A ip_serial_regs 0x%p "
+ "ip_uart_regs 0x%p\n",
+ __FUNCTION__,
+ (void *)port->ip_serial_regs,
+ (void *)port->ip_uart_regs));
+
+ /* setup ring buffers */
+ port->ip_cpu_ringbuf = pci_alloc_consistent(pdev,
+ TOTAL_RING_BUF_SIZE, &port->ip_dma_ringbuf);
+
+ BUG_ON(!((((int64_t) port->ip_dma_ringbuf) &
+ (TOTAL_RING_BUF_SIZE - 1)) == 0));
+ port->ip_inring = RING(port, RX_A);
+ port->ip_outring = RING(port, TX_A);
+ DPRINT_CONFIG(("%s : Port A ip_cpu_ringbuf 0x%p "
+ "ip_dma_ringbuf 0x%p, ip_inring 0x%p "
+ "ip_outring 0x%p\n",
+ __FUNCTION__,
+ (void *)port->ip_cpu_ringbuf,
+ (void *)port->ip_dma_ringbuf,
+ (void *)port->ip_inring,
+ (void *)port->ip_outring));
+ }
+ else {
+ port->ip_serial_regs = &idd->vma->port_b;
+ port->ip_uart_regs = &idd->vma->sregs.uartb;
+
+ DPRINT_CONFIG(("%s : Port B ip_serial_regs 0x%p "
+ "ip_uart_regs 0x%p\n",
+ __FUNCTION__,
+ (void *)port->ip_serial_regs,
+ (void *)port->ip_uart_regs));
+
+ /* share the ring buffers */
+ port->ip_dma_ringbuf =
+ ports[phys_port - 1]->ip_dma_ringbuf;
+ port->ip_cpu_ringbuf =
+ ports[phys_port - 1]->ip_cpu_ringbuf;
+ port->ip_inring = RING(port, RX_B);
+ port->ip_outring = RING(port, TX_B);
+ DPRINT_CONFIG(("%s : Port B ip_cpu_ringbuf 0x%p "
+ "ip_dma_ringbuf 0x%p, ip_inring 0x%p "
+ "ip_outring 0x%p\n",
+ __FUNCTION__,
+ (void *)port->ip_cpu_ringbuf,
+ (void *)port->ip_dma_ringbuf,
+ (void *)port->ip_inring,
+ (void *)port->ip_outring));
+ }
+
+ DPRINT_CONFIG(("%s : port %d [addr 0x%p] card_ptr 0x%p",
+ __FUNCTION__,
+ phys_port, (void *)port, (void *)card_ptr));
+ DPRINT_CONFIG((" ip_serial_regs 0x%p ip_uart_regs 0x%p\n",
+ (void *)port->ip_serial_regs,
+ (void *)port->ip_uart_regs));
+
+ /* Initialize the hardware for IOC3 */
+ port_init(port);
+
+ DPRINT_CONFIG(("%s: phys_port %d port 0x%p inring 0x%p "
+ "outring 0x%p\n",
+ __FUNCTION__,
+ phys_port, (void *)port,
+ (void *)port->ip_inring,
+ (void *)port->ip_outring));
+
+ }
+
+ /* register port with the serial core */
+
+ if ((ret = ioc3_serial_core_attach(is, idd)))
+ goto out4;
+
+ Num_of_ioc3_cards++;
+
+ return ret;
+
+ /* error exits that give back resources */
+out4:
+ kfree(card_ptr);
+ return ret;
+}
+
+static struct ioc3_submodule ioc3uart_submodule = {
+ .name = "IOC3uart",
+ .probe = ioc3uart_probe,
+ .remove = ioc3uart_remove,
+ /* call .intr for both ports initially */
+ .irq_mask = SIO_IR_SA | SIO_IR_SB,
+ .intr = ioc3uart_intr,
+ .owner = THIS_MODULE,
+};
+
+/**
+ * ioc3_detect - module init called,
+ */
+static int __devinit ioc3uart_init(void)
+{
+ int ret;
+
+ /* register with serial core */
+ if ((ret = uart_register_driver(&ioc3_uart)) < 0) {
+ printk(KERN_WARNING
+ "%s: Couldn't register IOC3 uart serial driver\n",
+ __FUNCTION__);
+ return ret;
+ }
+ ret = ioc3_register_submodule(&ioc3uart_submodule);
+ if (ret)
+ uart_unregister_driver(&ioc3_uart);
+ return ret;
+}
+
+static void __devexit ioc3uart_exit(void)
+{
+ ioc3_unregister_submodule(&ioc3uart_submodule);
+ uart_unregister_driver(&ioc3_uart);
+}
+
+module_init(ioc3uart_init);
+module_exit(ioc3uart_exit);
+
+MODULE_AUTHOR("Pat Gefre - Silicon Graphics Inc. (SGI) <pfg@sgi.com>");
+MODULE_DESCRIPTION("Serial PCI driver module for SGI IOC3 card");
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index 5f52883..4e03a87 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -69,7 +69,6 @@
#include <asm/pmac_feature.h>
#include <asm/dbdma.h>
#include <asm/macio.h>
-#include <asm/semaphore.h>
#if defined (CONFIG_SERIAL_PMACZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
@@ -1593,7 +1592,7 @@
state = pmz_uart_reg.state + uap->port.line;
mutex_lock(&pmz_irq_mutex);
- down(&state->sem);
+ mutex_lock(&state->mutex);
spin_lock_irqsave(&uap->port.lock, flags);
@@ -1624,7 +1623,7 @@
/* Shut the chip down */
pmz_set_scc_power(uap, 0);
- up(&state->sem);
+ mutex_unlock(&state->mutex);
mutex_unlock(&pmz_irq_mutex);
pmz_debug("suspend, switching complete\n");
@@ -1653,7 +1652,7 @@
state = pmz_uart_reg.state + uap->port.line;
mutex_lock(&pmz_irq_mutex);
- down(&state->sem);
+ mutex_lock(&state->mutex);
spin_lock_irqsave(&uap->port.lock, flags);
if (!ZS_IS_OPEN(uap) && !ZS_IS_CONS(uap)) {
@@ -1685,7 +1684,7 @@
}
bail:
- up(&state->sem);
+ mutex_unlock(&state->mutex);
mutex_unlock(&pmz_irq_mutex);
/* Right now, we deal with delay by blocking here, I'll be
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 2ca6209..9437704 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -638,7 +638,7 @@
* module insertion/removal doesn't change anything
* under us.
*/
- down(&state->sem);
+ mutex_lock(&state->mutex);
change_irq = new_serial.irq != port->irq;
@@ -797,7 +797,7 @@
} else
retval = uart_startup(state, 1);
exit:
- up(&state->sem);
+ mutex_unlock(&state->mutex);
return retval;
}
@@ -834,7 +834,7 @@
struct uart_port *port = state->port;
int result = -EIO;
- down(&state->sem);
+ mutex_lock(&state->mutex);
if ((!file || !tty_hung_up_p(file)) &&
!(tty->flags & (1 << TTY_IO_ERROR))) {
result = port->mctrl;
@@ -843,7 +843,7 @@
result |= port->ops->get_mctrl(port);
spin_unlock_irq(&port->lock);
}
- up(&state->sem);
+ mutex_unlock(&state->mutex);
return result;
}
@@ -856,13 +856,13 @@
struct uart_port *port = state->port;
int ret = -EIO;
- down(&state->sem);
+ mutex_lock(&state->mutex);
if ((!file || !tty_hung_up_p(file)) &&
!(tty->flags & (1 << TTY_IO_ERROR))) {
uart_update_mctrl(port, set, clear);
ret = 0;
}
- up(&state->sem);
+ mutex_unlock(&state->mutex);
return ret;
}
@@ -873,12 +873,12 @@
BUG_ON(!kernel_locked());
- down(&state->sem);
+ mutex_lock(&state->mutex);
if (port->type != PORT_UNKNOWN)
port->ops->break_ctl(port, break_state);
- up(&state->sem);
+ mutex_unlock(&state->mutex);
}
static int uart_do_autoconfig(struct uart_state *state)
@@ -894,7 +894,7 @@
* changing, and hence any extra opens of the port while
* we're auto-configuring.
*/
- if (down_interruptible(&state->sem))
+ if (mutex_lock_interruptible(&state->mutex))
return -ERESTARTSYS;
ret = -EBUSY;
@@ -920,7 +920,7 @@
ret = uart_startup(state, 1);
}
- up(&state->sem);
+ mutex_unlock(&state->mutex);
return ret;
}
@@ -1074,7 +1074,7 @@
if (ret != -ENOIOCTLCMD)
goto out;
- down(&state->sem);
+ mutex_lock(&state->mutex);
if (tty_hung_up_p(filp)) {
ret = -EIO;
@@ -1098,7 +1098,7 @@
}
}
out_up:
- up(&state->sem);
+ mutex_unlock(&state->mutex);
out:
return ret;
}
@@ -1186,7 +1186,7 @@
DPRINTK("uart_close(%d) called\n", port->line);
- down(&state->sem);
+ mutex_lock(&state->mutex);
if (tty_hung_up_p(filp))
goto done;
@@ -1260,7 +1260,7 @@
wake_up_interruptible(&state->info->open_wait);
done:
- up(&state->sem);
+ mutex_unlock(&state->mutex);
}
static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
@@ -1334,7 +1334,7 @@
BUG_ON(!kernel_locked());
DPRINTK("uart_hangup(%d)\n", state->port->line);
- down(&state->sem);
+ mutex_lock(&state->mutex);
if (state->info && state->info->flags & UIF_NORMAL_ACTIVE) {
uart_flush_buffer(tty);
uart_shutdown(state);
@@ -1344,7 +1344,7 @@
wake_up_interruptible(&state->info->open_wait);
wake_up_interruptible(&state->info->delta_msr_wait);
}
- up(&state->sem);
+ mutex_unlock(&state->mutex);
}
/*
@@ -1447,9 +1447,9 @@
if (mctrl & TIOCM_CAR)
break;
- up(&state->sem);
+ mutex_unlock(&state->mutex);
schedule();
- down(&state->sem);
+ mutex_lock(&state->mutex);
if (signal_pending(current))
break;
@@ -1475,7 +1475,7 @@
mutex_lock(&port_mutex);
state = drv->state + line;
- if (down_interruptible(&state->sem)) {
+ if (mutex_lock_interruptible(&state->mutex)) {
state = ERR_PTR(-ERESTARTSYS);
goto out;
}
@@ -1483,7 +1483,7 @@
state->count++;
if (!state->port) {
state->count--;
- up(&state->sem);
+ mutex_unlock(&state->mutex);
state = ERR_PTR(-ENXIO);
goto out;
}
@@ -1504,7 +1504,7 @@
(unsigned long)state);
} else {
state->count--;
- up(&state->sem);
+ mutex_unlock(&state->mutex);
state = ERR_PTR(-ENOMEM);
}
}
@@ -1571,7 +1571,7 @@
if (tty_hung_up_p(filp)) {
retval = -EAGAIN;
state->count--;
- up(&state->sem);
+ mutex_unlock(&state->mutex);
goto fail;
}
@@ -1591,7 +1591,7 @@
*/
if (retval == 0)
retval = uart_block_til_ready(filp, state);
- up(&state->sem);
+ mutex_unlock(&state->mutex);
/*
* If this is the first open to succeed, adjust things to suit.
@@ -1867,7 +1867,7 @@
{
struct uart_state *state = drv->state + port->line;
- down(&state->sem);
+ mutex_lock(&state->mutex);
if (state->info && state->info->flags & UIF_INITIALIZED) {
struct uart_ops *ops = port->ops;
@@ -1896,7 +1896,7 @@
uart_change_pm(state, 3);
- up(&state->sem);
+ mutex_unlock(&state->mutex);
return 0;
}
@@ -1905,7 +1905,7 @@
{
struct uart_state *state = drv->state + port->line;
- down(&state->sem);
+ mutex_lock(&state->mutex);
uart_change_pm(state, 0);
@@ -1954,7 +1954,7 @@
}
}
- up(&state->sem);
+ mutex_unlock(&state->mutex);
return 0;
}
@@ -2049,7 +2049,7 @@
if (info && info->tty)
tty_vhangup(info->tty);
- down(&state->sem);
+ mutex_lock(&state->mutex);
state->info = NULL;
@@ -2072,7 +2072,7 @@
kfree(info);
}
- up(&state->sem);
+ mutex_unlock(&state->mutex);
}
static struct tty_operations uart_ops = {
@@ -2161,7 +2161,7 @@
state->close_delay = 500; /* .5 seconds */
state->closing_wait = 30000; /* 30 seconds */
- init_MUTEX(&state->sem);
+ mutex_init(&state->mutex);
}
retval = tty_register_driver(normal);
diff --git a/drivers/sn/Kconfig b/drivers/sn/Kconfig
index 13b8d24..d95265b1 100644
--- a/drivers/sn/Kconfig
+++ b/drivers/sn/Kconfig
@@ -17,4 +17,18 @@
If you have an SGI Altix with an IOC4-based
I/O controller say Y. Otherwise say N.
+config SGI_IOC3
+ tristate "SGI IOC3 Base IO support"
+ depends on (IA64_GENERIC || IA64_SGI_SN2)
+ default m
+ ---help---
+ This option enables basic support for the SGI IOC3-based Base IO
+ controller card. This option does not enable any specific
+ functions on such a card, but provides necessary infrastructure
+ for other drivers to utilize.
+
+ If you have an SGI Altix with an IOC3-based
+ I/O controller or a PCI IOC3 serial card say Y.
+ Otherwise say N.
+
endmenu
diff --git a/drivers/sn/Makefile b/drivers/sn/Makefile
index c2a2841..2cda011 100644
--- a/drivers/sn/Makefile
+++ b/drivers/sn/Makefile
@@ -4,3 +4,4 @@
#
obj-$(CONFIG_SGI_IOC4) += ioc4.o
+obj-$(CONFIG_SGI_IOC3) += ioc3.o
diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c
new file mode 100644
index 0000000..aaa009f
--- /dev/null
+++ b/drivers/sn/ioc3.c
@@ -0,0 +1,851 @@
+/*
+ * SGI IOC3 master driver and IRQ demuxer
+ *
+ * Copyright (c) 2005 Stanislaw Skowronek <skylark@linux-mips.org>
+ * Heavily based on similar work by:
+ * Brent Casavant <bcasavan@sgi.com> - IOC4 master driver
+ * Pat Gefre <pfg@sgi.com> - IOC3 serial port IRQ demuxer
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/ioc3.h>
+#include <linux/rwsem.h>
+
+#define IOC3_PCI_SIZE 0x100000
+
+static LIST_HEAD(ioc3_devices);
+static int ioc3_counter;
+static DECLARE_RWSEM(ioc3_devices_rwsem);
+
+static struct ioc3_submodule *ioc3_submodules[IOC3_MAX_SUBMODULES];
+static struct ioc3_submodule *ioc3_ethernet;
+static rwlock_t ioc3_submodules_lock = RW_LOCK_UNLOCKED;
+
+/* NIC probing code */
+
+#define GPCR_MLAN_EN 0x00200000 /* enable MCR to pin 8 */
+
+static inline unsigned mcr_pack(unsigned pulse, unsigned sample)
+{
+ return (pulse << 10) | (sample << 2);
+}
+
+static int nic_wait(struct ioc3_driver_data *idd)
+{
+ volatile unsigned mcr;
+
+ do {
+ mcr = (volatile unsigned)idd->vma->mcr;
+ } while (!(mcr & 2));
+
+ return mcr & 1;
+}
+
+static int nic_reset(struct ioc3_driver_data *idd)
+{
+ int presence;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ idd->vma->mcr = mcr_pack(500, 65);
+ presence = nic_wait(idd);
+ local_irq_restore(flags);
+
+ udelay(500);
+
+ return presence;
+}
+
+static inline int nic_read_bit(struct ioc3_driver_data *idd)
+{
+ int result;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ idd->vma->mcr = mcr_pack(6, 13);
+ result = nic_wait(idd);
+ local_irq_restore(flags);
+
+ udelay(500);
+
+ return result;
+}
+
+static inline void nic_write_bit(struct ioc3_driver_data *idd, int bit)
+{
+ if (bit)
+ idd->vma->mcr = mcr_pack(6, 110);
+ else
+ idd->vma->mcr = mcr_pack(80, 30);
+
+ nic_wait(idd);
+}
+
+static unsigned nic_read_byte(struct ioc3_driver_data *idd)
+{
+ unsigned result = 0;
+ int i;
+
+ for (i = 0; i < 8; i++)
+ result = (result >> 1) | (nic_read_bit(idd) << 7);
+
+ return result;
+}
+
+static void nic_write_byte(struct ioc3_driver_data *idd, int byte)
+{
+ int i, bit;
+
+ for (i = 8; i; i--) {
+ bit = byte & 1;
+ byte >>= 1;
+
+ nic_write_bit(idd, bit);
+ }
+}
+
+static unsigned long
+nic_find(struct ioc3_driver_data *idd, int *last, unsigned long addr)
+{
+ int a, b, index, disc;
+
+ nic_reset(idd);
+
+ /* Search ROM. */
+ nic_write_byte(idd, 0xF0);
+
+ /* Algorithm from ``Book of iButton Standards''. */
+ for (index = 0, disc = 0; index < 64; index++) {
+ a = nic_read_bit(idd);
+ b = nic_read_bit(idd);
+
+ if (a && b) {
+ printk(KERN_WARNING "IOC3 NIC search failed.\n");
+ *last = 0;
+ return 0;
+ }
+
+ if (!a && !b) {
+ if (index == *last) {
+ addr |= 1UL << index;
+ } else if (index > *last) {
+ addr &= ~(1UL << index);
+ disc = index;
+ } else if ((addr & (1UL << index)) == 0)
+ disc = index;
+ nic_write_bit(idd, (addr>>index)&1);
+ continue;
+ } else {
+ if (a)
+ addr |= 1UL << index;
+ else
+ addr &= ~(1UL << index);
+ nic_write_bit(idd, a);
+ continue;
+ }
+ }
+ *last = disc;
+ return addr;
+}
+
+static void nic_addr(struct ioc3_driver_data *idd, unsigned long addr)
+{
+ int index;
+
+ nic_reset(idd);
+ nic_write_byte(idd, 0xF0);
+ for (index = 0; index < 64; index++) {
+ nic_read_bit(idd);
+ nic_read_bit(idd);
+ nic_write_bit(idd, (addr>>index)&1);
+ }
+}
+
+static void crc16_byte(unsigned int *crc, unsigned char db)
+{
+ int i;
+
+ for(i=0;i<8;i++) {
+ *crc <<= 1;
+ if((db^(*crc>>16)) & 1)
+ *crc ^= 0x8005;
+ db >>= 1;
+ }
+ *crc &= 0xFFFF;
+}
+
+static unsigned int crc16_area(unsigned char *dbs, int size, unsigned int crc)
+{
+ while(size--)
+ crc16_byte(&crc, *(dbs++));
+ return crc;
+}
+
+static void crc8_byte(unsigned int *crc, unsigned char db)
+{
+ int i,f;
+
+ for(i=0;i<8;i++) {
+ f = (*crc ^ db) & 1;
+ *crc >>= 1;
+ db >>= 1;
+ if(f)
+ *crc ^= 0x8c;
+ }
+ *crc &= 0xff;
+}
+
+static unsigned int crc8_addr(unsigned long addr)
+{
+ int i;
+ unsigned int crc = 0x00;
+
+ for(i=0;i<8;i++)
+ crc8_byte(&crc, addr>>(i<<3));
+ return crc;
+}
+
+static void
+read_redir_page(struct ioc3_driver_data *idd, unsigned long addr, int page,
+ unsigned char *redir, unsigned char *data)
+{
+ int loops = 16, i;
+
+ while(redir[page] != 0xFF) {
+ page = redir[page]^0xFF;
+ loops--;
+ if(loops<0) {
+ printk(KERN_ERR "IOC3: NIC circular redirection\n");
+ return;
+ }
+ }
+ loops = 3;
+ while(loops>0) {
+ nic_addr(idd, addr);
+ nic_write_byte(idd, 0xF0);
+ nic_write_byte(idd, (page << 5) & 0xE0);
+ nic_write_byte(idd, (page >> 3) & 0x1F);
+ for(i=0;i<0x20;i++)
+ data[i] = nic_read_byte(idd);
+ if(crc16_area(data, 0x20, 0x0000) == 0x800d)
+ return;
+ loops--;
+ }
+ printk(KERN_ERR "IOC3: CRC error in data page\n");
+ for(i=0;i<0x20;i++)
+ data[i] = 0x00;
+}
+
+static void
+read_redir_map(struct ioc3_driver_data *idd, unsigned long addr,
+ unsigned char *redir)
+{
+ int i,j,loops = 3,crc_ok;
+ unsigned int crc;
+
+ while(loops>0) {
+ crc_ok = 1;
+ nic_addr(idd, addr);
+ nic_write_byte(idd, 0xAA);
+ nic_write_byte(idd, 0x00);
+ nic_write_byte(idd, 0x01);
+ for(i=0;i<64;i+=8) {
+ for(j=0;j<8;j++)
+ redir[i+j] = nic_read_byte(idd);
+ crc = crc16_area(redir+i, 8, (i==0)?0x8707:0x0000);
+ crc16_byte(&crc, nic_read_byte(idd));
+ crc16_byte(&crc, nic_read_byte(idd));
+ if(crc != 0x800d)
+ crc_ok = 0;
+ }
+ if(crc_ok)
+ return;
+ loops--;
+ }
+ printk(KERN_ERR "IOC3: CRC error in redirection page\n");
+ for(i=0;i<64;i++)
+ redir[i] = 0xFF;
+}
+
+static void read_nic(struct ioc3_driver_data *idd, unsigned long addr)
+{
+ unsigned char redir[64];
+ unsigned char data[64],part[32];
+ int i,j;
+
+ /* read redirections */
+ read_redir_map(idd, addr, redir);
+ /* read data pages */
+ read_redir_page(idd, addr, 0, redir, data);
+ read_redir_page(idd, addr, 1, redir, data+32);
+ /* assemble the part # */
+ j=0;
+ for(i=0;i<19;i++)
+ if(data[i+11] != ' ')
+ part[j++] = data[i+11];
+ for(i=0;i<6;i++)
+ if(data[i+32] != ' ')
+ part[j++] = data[i+32];
+ part[j] = 0;
+ /* skip Octane power supplies */
+ if(!strncmp(part, "060-0035-", 9))
+ return;
+ if(!strncmp(part, "060-0038-", 9))
+ return;
+ strcpy(idd->nic_part, part);
+ /* assemble the serial # */
+ j=0;
+ for(i=0;i<10;i++)
+ if(data[i+1] != ' ')
+ idd->nic_serial[j++] = data[i+1];
+ idd->nic_serial[j] = 0;
+}
+
+static void read_mac(struct ioc3_driver_data *idd, unsigned long addr)
+{
+ int i, loops = 3;
+ unsigned char data[13];
+
+ while(loops>0) {
+ nic_addr(idd, addr);
+ nic_write_byte(idd, 0xF0);
+ nic_write_byte(idd, 0x00);
+ nic_write_byte(idd, 0x00);
+ nic_read_byte(idd);
+ for(i=0;i<13;i++)
+ data[i] = nic_read_byte(idd);
+ if(crc16_area(data, 13, 0x0000) == 0x800d) {
+ for(i=10;i>4;i--)
+ idd->nic_mac[10-i] = data[i];
+ return;
+ }
+ loops--;
+ }
+ printk(KERN_ERR "IOC3: CRC error in MAC address\n");
+ for(i=0;i<6;i++)
+ idd->nic_mac[i] = 0x00;
+}
+
+static void probe_nic(struct ioc3_driver_data *idd)
+{
+ int save = 0, loops = 3;
+ unsigned long first, addr;
+
+ idd->vma->gpcr_s = GPCR_MLAN_EN;
+
+ while(loops>0) {
+ idd->nic_part[0] = 0;
+ idd->nic_serial[0] = 0;
+ addr = first = nic_find(idd, &save, 0);
+ if(!first)
+ return;
+ while(1) {
+ if(crc8_addr(addr))
+ break;
+ else {
+ switch(addr & 0xFF) {
+ case 0x0B:
+ read_nic(idd, addr);
+ break;
+ case 0x09:
+ case 0x89:
+ case 0x91:
+ read_mac(idd, addr);
+ break;
+ }
+ }
+ addr = nic_find(idd, &save, addr);
+ if(addr == first)
+ return;
+ }
+ loops--;
+ }
+ printk(KERN_ERR "IOC3: CRC error in NIC address\n");
+}
+
+/* Interrupts */
+
+static inline void
+write_ireg(struct ioc3_driver_data *idd, uint32_t val, int which)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&idd->ir_lock, flags);
+ switch (which) {
+ case IOC3_W_IES:
+ writel(val, &idd->vma->sio_ies);
+ break;
+ case IOC3_W_IEC:
+ writel(val, &idd->vma->sio_iec);
+ break;
+ }
+ spin_unlock_irqrestore(&idd->ir_lock, flags);
+}
+static inline uint32_t get_pending_intrs(struct ioc3_driver_data *idd)
+{
+ unsigned long flag;
+ uint32_t intrs = 0;
+
+ spin_lock_irqsave(&idd->ir_lock, flag);
+ intrs = readl(&idd->vma->sio_ir);
+ intrs &= readl(&idd->vma->sio_ies);
+ spin_unlock_irqrestore(&idd->ir_lock, flag);
+ return intrs;
+}
+
+static irqreturn_t ioc3_intr_io(int irq, void *arg, struct pt_regs *regs)
+{
+ unsigned long flags;
+ struct ioc3_driver_data *idd = (struct ioc3_driver_data *)arg;
+ int handled = 1, id;
+ unsigned int pending;
+
+ read_lock_irqsave(&ioc3_submodules_lock, flags);
+
+ if(idd->dual_irq && idd->vma->eisr) {
+ /* send Ethernet IRQ to the driver */
+ if(ioc3_ethernet && idd->active[ioc3_ethernet->id] &&
+ ioc3_ethernet->intr) {
+ handled = handled && !ioc3_ethernet->intr(ioc3_ethernet,
+ idd, 0, regs);
+ }
+ }
+ pending = get_pending_intrs(idd); /* look at the IO IRQs */
+
+ for(id=0;id<IOC3_MAX_SUBMODULES;id++) {
+ if(idd->active[id] && ioc3_submodules[id]
+ && (pending & ioc3_submodules[id]->irq_mask)
+ && ioc3_submodules[id]->intr) {
+ write_ireg(idd, ioc3_submodules[id]->irq_mask,
+ IOC3_W_IEC);
+ if(!ioc3_submodules[id]->intr(ioc3_submodules[id],
+ idd, pending & ioc3_submodules[id]->irq_mask,
+ regs))
+ pending &= ~ioc3_submodules[id]->irq_mask;
+ if (ioc3_submodules[id]->reset_mask)
+ write_ireg(idd, ioc3_submodules[id]->irq_mask,
+ IOC3_W_IES);
+ }
+ }
+ read_unlock_irqrestore(&ioc3_submodules_lock, flags);
+ if(pending) {
+ printk(KERN_WARNING
+ "IOC3: Pending IRQs 0x%08x discarded and disabled\n",pending);
+ write_ireg(idd, pending, IOC3_W_IEC);
+ handled = 1;
+ }
+ return handled?IRQ_HANDLED:IRQ_NONE;
+}
+
+static irqreturn_t ioc3_intr_eth(int irq, void *arg, struct pt_regs *regs)
+{
+ unsigned long flags;
+ struct ioc3_driver_data *idd = (struct ioc3_driver_data *)arg;
+ int handled = 1;
+
+ if(!idd->dual_irq)
+ return IRQ_NONE;
+ read_lock_irqsave(&ioc3_submodules_lock, flags);
+ if(ioc3_ethernet && idd->active[ioc3_ethernet->id]
+ && ioc3_ethernet->intr)
+ handled = handled && !ioc3_ethernet->intr(ioc3_ethernet, idd, 0,
+ regs);
+ read_unlock_irqrestore(&ioc3_submodules_lock, flags);
+ return handled?IRQ_HANDLED:IRQ_NONE;
+}
+
+void ioc3_enable(struct ioc3_submodule *is,
+ struct ioc3_driver_data *idd, unsigned int irqs)
+{
+ write_ireg(idd, irqs & is->irq_mask, IOC3_W_IES);
+}
+
+void ioc3_ack(struct ioc3_submodule *is, struct ioc3_driver_data *idd,
+ unsigned int irqs)
+{
+ writel(irqs & is->irq_mask, &idd->vma->sio_ir);
+}
+
+void ioc3_disable(struct ioc3_submodule *is,
+ struct ioc3_driver_data *idd, unsigned int irqs)
+{
+ write_ireg(idd, irqs & is->irq_mask, IOC3_W_IEC);
+}
+
+void ioc3_gpcr_set(struct ioc3_driver_data *idd, unsigned int val)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&idd->gpio_lock, flags);
+ writel(val, &idd->vma->gpcr_s);
+ spin_unlock_irqrestore(&idd->gpio_lock, flags);
+}
+
+/* Keep it simple, stupid! */
+static int find_slot(void **tab, int max)
+{
+ int i;
+ for(i=0;i<max;i++)
+ if(!(tab[i]))
+ return i;
+ return -1;
+}
+
+/* Register an IOC3 submodule */
+int ioc3_register_submodule(struct ioc3_submodule *is)
+{
+ struct ioc3_driver_data *idd;
+ int alloc_id;
+ unsigned long flags;
+
+ write_lock_irqsave(&ioc3_submodules_lock, flags);
+ alloc_id = find_slot((void **)ioc3_submodules, IOC3_MAX_SUBMODULES);
+ if(alloc_id != -1) {
+ ioc3_submodules[alloc_id] = is;
+ if(is->ethernet) {
+ if(ioc3_ethernet==NULL)
+ ioc3_ethernet=is;
+ else
+ printk(KERN_WARNING
+ "IOC3 Ethernet module already registered!\n");
+ }
+ }
+ write_unlock_irqrestore(&ioc3_submodules_lock, flags);
+
+ if(alloc_id == -1) {
+ printk(KERN_WARNING "Increase IOC3_MAX_SUBMODULES!\n");
+ return -ENOMEM;
+ }
+
+ is->id=alloc_id;
+
+ /* Initialize submodule for each IOC3 */
+ if (!is->probe)
+ return 0;
+
+ down_read(&ioc3_devices_rwsem);
+ list_for_each_entry(idd, &ioc3_devices, list) {
+ /* set to 1 for IRQs in probe */
+ idd->active[alloc_id] = 1;
+ idd->active[alloc_id] = !is->probe(is, idd);
+ }
+ up_read(&ioc3_devices_rwsem);
+
+ return 0;
+}
+
+/* Unregister an IOC3 submodule */
+void ioc3_unregister_submodule(struct ioc3_submodule *is)
+{
+ struct ioc3_driver_data *idd;
+ unsigned long flags;
+
+ write_lock_irqsave(&ioc3_submodules_lock, flags);
+ if(ioc3_submodules[is->id]==is)
+ ioc3_submodules[is->id]=NULL;
+ else
+ printk(KERN_WARNING
+ "IOC3 submodule %s has wrong ID.\n",is->name);
+ if(ioc3_ethernet==is)
+ ioc3_ethernet = NULL;
+ write_unlock_irqrestore(&ioc3_submodules_lock, flags);
+
+ /* Remove submodule for each IOC3 */
+ down_read(&ioc3_devices_rwsem);
+ list_for_each_entry(idd, &ioc3_devices, list)
+ if(idd->active[is->id]) {
+ if(is->remove)
+ if(is->remove(is, idd))
+ printk(KERN_WARNING
+ "%s: IOC3 submodule %s remove failed "
+ "for pci_dev %s.\n",
+ __FUNCTION__, module_name(is->owner),
+ pci_name(idd->pdev));
+ idd->active[is->id] = 0;
+ if(is->irq_mask)
+ write_ireg(idd, is->irq_mask, IOC3_W_IEC);
+ }
+ up_read(&ioc3_devices_rwsem);
+}
+
+/*********************
+ * Device management *
+ *********************/
+
+static char *
+ioc3_class_names[]={"unknown", "IP27 BaseIO", "IP30 system", "MENET 1/2/3",
+ "MENET 4", "CADduo", "Altix Serial"};
+
+static int ioc3_class(struct ioc3_driver_data *idd)
+{
+ int res = IOC3_CLASS_NONE;
+ /* NIC-based logic */
+ if(!strncmp(idd->nic_part, "030-0891-", 9))
+ res = IOC3_CLASS_BASE_IP30;
+ if(!strncmp(idd->nic_part, "030-1155-", 9))
+ res = IOC3_CLASS_CADDUO;
+ if(!strncmp(idd->nic_part, "030-1657-", 9))
+ res = IOC3_CLASS_SERIAL;
+ if(!strncmp(idd->nic_part, "030-1664-", 9))
+ res = IOC3_CLASS_SERIAL;
+ /* total random heuristics */
+#ifdef CONFIG_SGI_IP27
+ if(!idd->nic_part[0])
+ res = IOC3_CLASS_BASE_IP27;
+#endif
+ /* print educational message */
+ printk(KERN_INFO "IOC3 part: [%s], serial: [%s] => class %s\n",
+ idd->nic_part, idd->nic_serial, ioc3_class_names[res]);
+ return res;
+}
+/* Adds a new instance of an IOC3 card */
+static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
+{
+ struct ioc3_driver_data *idd;
+ uint32_t pcmd;
+ int ret, id;
+
+ /* Enable IOC3 and take ownership of it */
+ if ((ret = pci_enable_device(pdev))) {
+ printk(KERN_WARNING
+ "%s: Failed to enable IOC3 device for pci_dev %s.\n",
+ __FUNCTION__, pci_name(pdev));
+ goto out;
+ }
+ pci_set_master(pdev);
+
+#ifdef USE_64BIT_DMA
+ ret = pci_set_dma_mask(pdev, 0xffffffffffffffffULL);
+ if (!ret) {
+ ret = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL);
+ if (ret < 0) {
+ printk(KERN_WARNING "%s: Unable to obtain 64 bit DMA "
+ "for consistent allocations\n",
+ __FUNCTION__);
+ }
+ }
+#endif
+
+ /* Set up per-IOC3 data */
+ idd = kmalloc(sizeof(struct ioc3_driver_data), GFP_KERNEL);
+ if (!idd) {
+ printk(KERN_WARNING
+ "%s: Failed to allocate IOC3 data for pci_dev %s.\n",
+ __FUNCTION__, pci_name(pdev));
+ ret = -ENODEV;
+ goto out_idd;
+ }
+ memset(idd, 0, sizeof(struct ioc3_driver_data));
+ spin_lock_init(&idd->ir_lock);
+ spin_lock_init(&idd->gpio_lock);
+ idd->pdev = pdev;
+
+ /* Map all IOC3 registers. These are shared between subdevices
+ * so the main IOC3 module manages them.
+ */
+ idd->pma = pci_resource_start(pdev, 0);
+ if (!idd->pma) {
+ printk(KERN_WARNING
+ "%s: Unable to find IOC3 resource "
+ "for pci_dev %s.\n",
+ __FUNCTION__, pci_name(pdev));
+ ret = -ENODEV;
+ goto out_pci;
+ }
+ if (!request_region(idd->pma, IOC3_PCI_SIZE, "ioc3")) {
+ printk(KERN_WARNING
+ "%s: Unable to request IOC3 region "
+ "for pci_dev %s.\n",
+ __FUNCTION__, pci_name(pdev));
+ ret = -ENODEV;
+ goto out_pci;
+ }
+ idd->vma = ioremap(idd->pma, IOC3_PCI_SIZE);
+ if (!idd->vma) {
+ printk(KERN_WARNING
+ "%s: Unable to remap IOC3 region "
+ "for pci_dev %s.\n",
+ __FUNCTION__, pci_name(pdev));
+ ret = -ENODEV;
+ goto out_misc_region;
+ }
+
+ /* Track PCI-device specific data */
+ pci_set_drvdata(pdev, idd);
+ down_write(&ioc3_devices_rwsem);
+ list_add(&idd->list, &ioc3_devices);
+ idd->id = ioc3_counter++;
+ up_write(&ioc3_devices_rwsem);
+
+ idd->gpdr_shadow = idd->vma->gpdr;
+
+ /* Read IOC3 NIC contents */
+ probe_nic(idd);
+
+ /* Detect IOC3 class */
+ idd->class = ioc3_class(idd);
+
+ /* Initialize IOC3 */
+ pci_read_config_dword(pdev, PCI_COMMAND, &pcmd);
+ pci_write_config_dword(pdev, PCI_COMMAND,
+ pcmd | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_PARITY | PCI_COMMAND_SERR |
+ PCI_SCR_DROP_MODE_EN);
+
+ write_ireg(idd, ~0, IOC3_W_IEC);
+ writel(~0, &idd->vma->sio_ir);
+
+ /* Set up IRQs */
+ if(idd->class == IOC3_CLASS_BASE_IP30
+ || idd->class == IOC3_CLASS_BASE_IP27) {
+ writel(0, &idd->vma->eier);
+ writel(~0, &idd->vma->eisr);
+
+ idd->dual_irq = 1;
+ if (!request_irq(pdev->irq, ioc3_intr_eth, SA_SHIRQ,
+ "ioc3-eth", (void *)idd)) {
+ idd->irq_eth = pdev->irq;
+ } else {
+ printk(KERN_WARNING
+ "%s : request_irq fails for IRQ 0x%x\n ",
+ __FUNCTION__, pdev->irq);
+ }
+ if (!request_irq(pdev->irq+2, ioc3_intr_io, SA_SHIRQ,
+ "ioc3-io", (void *)idd)) {
+ idd->irq_io = pdev->irq+2;
+ } else {
+ printk(KERN_WARNING
+ "%s : request_irq fails for IRQ 0x%x\n ",
+ __FUNCTION__, pdev->irq+2);
+ }
+ } else {
+ if (!request_irq(pdev->irq, ioc3_intr_io, SA_SHIRQ,
+ "ioc3", (void *)idd)) {
+ idd->irq_io = pdev->irq;
+ } else {
+ printk(KERN_WARNING
+ "%s : request_irq fails for IRQ 0x%x\n ",
+ __FUNCTION__, pdev->irq);
+ }
+ }
+
+ /* Add this IOC3 to all submodules */
+ read_lock(&ioc3_submodules_lock);
+ for(id=0;id<IOC3_MAX_SUBMODULES;id++)
+ if(ioc3_submodules[id] && ioc3_submodules[id]->probe) {
+ idd->active[id] = 1;
+ idd->active[id] = !ioc3_submodules[id]->probe
+ (ioc3_submodules[id], idd);
+ }
+ read_unlock(&ioc3_submodules_lock);
+
+ printk(KERN_INFO "IOC3 Master Driver loaded for %s\n", pci_name(pdev));
+
+ return 0;
+
+out_misc_region:
+ release_region(idd->pma, IOC3_PCI_SIZE);
+out_pci:
+ kfree(idd);
+out_idd:
+ pci_disable_device(pdev);
+out:
+ return ret;
+}
+
+/* Removes a particular instance of an IOC3 card. */
+static void ioc3_remove(struct pci_dev *pdev)
+{
+ int id;
+ struct ioc3_driver_data *idd;
+
+ idd = pci_get_drvdata(pdev);
+
+ /* Remove this IOC3 from all submodules */
+ read_lock(&ioc3_submodules_lock);
+ for(id=0;id<IOC3_MAX_SUBMODULES;id++)
+ if(idd->active[id]) {
+ if(ioc3_submodules[id] && ioc3_submodules[id]->remove)
+ if(ioc3_submodules[id]->remove(ioc3_submodules[id],
+ idd))
+ printk(KERN_WARNING
+ "%s: IOC3 submodule 0x%s remove failed "
+ "for pci_dev %s.\n",
+ __FUNCTION__,
+ module_name(ioc3_submodules[id]->owner),
+ pci_name(pdev));
+ idd->active[id] = 0;
+ }
+ read_unlock(&ioc3_submodules_lock);
+
+ /* Clear and disable all IRQs */
+ write_ireg(idd, ~0, IOC3_W_IEC);
+ writel(~0, &idd->vma->sio_ir);
+
+ /* Release resources */
+ free_irq(idd->irq_io, (void *)idd);
+ if(idd->dual_irq)
+ free_irq(idd->irq_eth, (void *)idd);
+ iounmap(idd->vma);
+ release_region(idd->pma, IOC3_PCI_SIZE);
+
+ /* Disable IOC3 and relinquish */
+ pci_disable_device(pdev);
+
+ /* Remove and free driver data */
+ down_write(&ioc3_devices_rwsem);
+ list_del(&idd->list);
+ up_write(&ioc3_devices_rwsem);
+ kfree(idd);
+}
+
+static struct pci_device_id ioc3_id_table[] = {
+ {PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, PCI_ANY_ID, PCI_ANY_ID},
+ {0}
+};
+
+static struct pci_driver ioc3_driver = {
+ .name = "IOC3",
+ .id_table = ioc3_id_table,
+ .probe = ioc3_probe,
+ .remove = ioc3_remove,
+};
+
+MODULE_DEVICE_TABLE(pci, ioc3_id_table);
+
+/*********************
+ * Module management *
+ *********************/
+
+/* Module load */
+static int __devinit ioc3_init(void)
+{
+ if (ia64_platform_is("sn2"))
+ return pci_register_driver(&ioc3_driver);
+ return 0;
+}
+
+/* Module unload */
+static void __devexit ioc3_exit(void)
+{
+ pci_unregister_driver(&ioc3_driver);
+}
+
+module_init(ioc3_init);
+module_exit(ioc3_exit);
+
+MODULE_AUTHOR("Stanislaw Skowronek <skylark@linux-mips.org>");
+MODULE_DESCRIPTION("PCI driver for SGI IOC3");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(ioc3_register_submodule);
+EXPORT_SYMBOL(ioc3_unregister_submodule);
+EXPORT_SYMBOL(ioc3_ack);
+EXPORT_SYMBOL(ioc3_gpcr_set);
+EXPORT_SYMBOL(ioc3_disable);
+EXPORT_SYMBOL(ioc3_enable);
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
index 9baa629..7af1883 100644
--- a/drivers/usb/atm/usbatm.c
+++ b/drivers/usb/atm/usbatm.c
@@ -207,7 +207,7 @@
** urbs **
************/
-static inline struct urb *usbatm_pop_urb(struct usbatm_channel *channel)
+static struct urb *usbatm_pop_urb(struct usbatm_channel *channel)
{
struct urb *urb;
@@ -224,7 +224,7 @@
return urb;
}
-static inline int usbatm_submit_urb(struct urb *urb)
+static int usbatm_submit_urb(struct urb *urb)
{
struct usbatm_channel *channel = urb->context;
int ret;
diff --git a/drivers/video/68328fb.c b/drivers/video/68328fb.c
index 3b0ddc5..78488bb 100644
--- a/drivers/video/68328fb.c
+++ b/drivers/video/68328fb.c
@@ -102,8 +102,7 @@
u_int transp, struct fb_info *info);
static int mc68x328fb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info);
-static int mc68x328fb_mmap(struct fb_info *info, struct file *file,
- struct vm_area_struct *vma);
+static int mc68x328fb_mmap(struct fb_info *info, struct vm_area_struct *vma);
static struct fb_ops mc68x328fb_ops = {
.fb_check_var = mc68x328fb_check_var,
@@ -398,8 +397,7 @@
* Most drivers don't need their own mmap function
*/
-static int mc68x328fb_mmap(struct fb_info *info, struct file *file,
- struct vm_area_struct *vma)
+static int mc68x328fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
#ifndef MMU
/* this is uClinux (no MMU) specific code */
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
index 750cebb..b058273 100644
--- a/drivers/video/acornfb.c
+++ b/drivers/video/acornfb.c
@@ -883,7 +883,7 @@
* Note that we are entered with the kernel locked.
*/
static int
-acornfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+acornfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
unsigned long off, start;
u32 len;
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index 0da4083..b218717 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -307,7 +307,7 @@
return 0;
}
-static int clcdfb_mmap(struct fb_info *info, struct file *file,
+static int clcdfb_mmap(struct fb_info *info,
struct vm_area_struct *vma)
{
struct clcd_fb *fb = to_clcd(info);
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 2c42a81..3033c72 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -1131,9 +1131,7 @@
const struct fb_copyarea *region);
static void amifb_imageblit(struct fb_info *info,
const struct fb_image *image);
-static int amifb_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg,
- struct fb_info *info);
+static int amifb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg);
/*
@@ -2172,9 +2170,8 @@
* Amiga Frame Buffer Specific ioctls
*/
-static int amifb_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg,
- struct fb_info *info)
+static int amifb_ioctl(struct fb_info *info,
+ unsigned int cmd, unsigned long arg)
{
union {
struct fb_fix_cursorinfo fix;
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index 89060b2..df8e566 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -399,9 +399,8 @@
image->height);
}
-static int arcfb_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg,
- struct fb_info *info)
+static int arcfb_ioctl(struct fb_info *info,
+ unsigned int cmd, unsigned long arg)
{
void __user *argp = (void __user *)arg;
struct arcfb_par *par = info->par;
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index 15ec129..e69ab65 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -2571,8 +2571,7 @@
}
static int
-atafb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg, int con, struct fb_info *info)
+atafb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
switch (cmd) {
#ifdef FBCMD_GET_CURRENTPAR
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index e686185..bfc8a93 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -431,8 +431,7 @@
static int aty128fb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *fb);
static int aty128fb_blank(int blank, struct fb_info *fb);
-static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
- u_long arg, struct fb_info *info);
+static int aty128fb_ioctl(struct fb_info *info, u_int cmd, unsigned long arg);
static int aty128fb_sync(struct fb_info *info);
/*
@@ -2108,8 +2107,7 @@
/* in param: u32* backlight value: 0 to 15 */
#define FBIO_ATY128_SET_MIRROR _IOW('@', 2, __u32)
-static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
- u_long arg, struct fb_info *info)
+static int aty128fb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
{
struct aty128fb_par *par = info->par;
u32 value;
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index ed81005..485be38 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -238,13 +238,12 @@
u_int transp, struct fb_info *info);
static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
static int atyfb_blank(int blank, struct fb_info *info);
-static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
- u_long arg, struct fb_info *info);
+static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg);
extern void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
extern void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
extern void atyfb_imageblit(struct fb_info *info, const struct fb_image *image);
#ifdef __sparc__
-static int atyfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
+static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma);
#endif
static int atyfb_sync(struct fb_info *info);
@@ -1739,8 +1738,7 @@
#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
#endif
-static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
- u_long arg, struct fb_info *info)
+static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
#ifdef __sparc__
@@ -1845,7 +1843,7 @@
}
#ifdef __sparc__
-static int atyfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
unsigned int size, page, map_size = 0;
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 156db84..c9f0c5a 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -864,8 +864,8 @@
}
-static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg, struct fb_info *info)
+static int radeonfb_ioctl (struct fb_info *info, unsigned int cmd,
+ unsigned long arg)
{
struct radeonfb_info *rinfo = info->par;
unsigned int tmp;
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index 097d668..556895e 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -2734,7 +2734,7 @@
* BIOS does tho. Right now, all this PM stuff is pmac-only for that
* reason. --BenH
*/
-#if defined(CONFIG_PM) && defined(CONFIG_PPC_OF)
+#if defined(CONFIG_PM) && defined(CONFIG_PPC_PMAC)
if (_machine == _MACH_Pmac && rinfo->of_node) {
if (rinfo->is_mobility && rinfo->pm_reg &&
rinfo->family <= CHIP_FAMILY_RV250)
@@ -2778,12 +2778,12 @@
OUTREG(TV_DAC_CNTL, INREG(TV_DAC_CNTL) | 0x07000000);
#endif
}
-#endif /* defined(CONFIG_PM) && defined(CONFIG_PPC_OF) */
+#endif /* defined(CONFIG_PM) && defined(CONFIG_PPC_PMAC) */
}
void radeonfb_pm_exit(struct radeonfb_info *rinfo)
{
-#if defined(CONFIG_PM) && defined(CONFIG_PPC_OF)
+#if defined(CONFIG_PM) && defined(CONFIG_PPC_PMAC)
if (rinfo->pm_mode != radeon_pm_none)
pmac_set_early_video_resume(NULL, NULL);
#endif
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index a512980..2406899 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -379,7 +379,7 @@
* Map video memory in user space. We don't use the generic fb_mmap method mainly
* to allow the use of the TLB streaming flag (CCA=6)
*/
-int au1100fb_fb_mmap(struct fb_info *fbi, struct file *file, struct vm_area_struct *vma)
+int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
{
struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
unsigned int len;
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index 9248fe1..c029db4 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -35,9 +35,8 @@
static int bw2_blank(int, struct fb_info *);
-static int bw2_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
-static int bw2_ioctl(struct inode *, struct file *, unsigned int,
- unsigned long, struct fb_info *);
+static int bw2_mmap(struct fb_info *, struct vm_area_struct *);
+static int bw2_ioctl(struct fb_info *, unsigned int, unsigned long);
/*
* Frame buffer operations
@@ -169,7 +168,7 @@
{ .size = 0 }
};
-static int bw2_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+static int bw2_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct bw2_par *par = (struct bw2_par *)info->par;
@@ -181,8 +180,7 @@
vma);
}
-static int bw2_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg, struct fb_info *info)
+static int bw2_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
struct bw2_par *par = (struct bw2_par *) info->par;
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index a561471..63b6c79 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -31,9 +31,8 @@
static int cg14_setcolreg(unsigned, unsigned, unsigned, unsigned,
unsigned, struct fb_info *);
-static int cg14_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
-static int cg14_ioctl(struct inode *, struct file *, unsigned int,
- unsigned long, struct fb_info *);
+static int cg14_mmap(struct fb_info *, struct vm_area_struct *);
+static int cg14_ioctl(struct fb_info *, unsigned int, unsigned long);
static int cg14_pan_display(struct fb_var_screeninfo *, struct fb_info *);
/*
@@ -268,7 +267,7 @@
return 0;
}
-static int cg14_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+static int cg14_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct cg14_par *par = (struct cg14_par *) info->par;
@@ -277,8 +276,7 @@
par->iospace, vma);
}
-static int cg14_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg, struct fb_info *info)
+static int cg14_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
struct cg14_par *par = (struct cg14_par *) info->par;
struct cg14_regs __iomem *regs = par->regs;
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index 9fcd896..3de6e1b 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -33,9 +33,8 @@
unsigned, struct fb_info *);
static int cg3_blank(int, struct fb_info *);
-static int cg3_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
-static int cg3_ioctl(struct inode *, struct file *, unsigned int,
- unsigned long, struct fb_info *);
+static int cg3_mmap(struct fb_info *, struct vm_area_struct *);
+static int cg3_ioctl(struct fb_info *, unsigned int, unsigned long);
/*
* Frame buffer operations
@@ -230,7 +229,7 @@
{ .size = 0 }
};
-static int cg3_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+static int cg3_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct cg3_par *par = (struct cg3_par *)info->par;
@@ -240,8 +239,7 @@
vma);
}
-static int cg3_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg, struct fb_info *info)
+static int cg3_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
struct cg3_par *par = (struct cg3_par *) info->par;
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 050835e3..7aab91e 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -36,9 +36,8 @@
static void cg6_imageblit(struct fb_info *, const struct fb_image *);
static void cg6_fillrect(struct fb_info *, const struct fb_fillrect *);
static int cg6_sync(struct fb_info *);
-static int cg6_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
-static int cg6_ioctl(struct inode *, struct file *, unsigned int,
- unsigned long, struct fb_info *);
+static int cg6_mmap(struct fb_info *, struct vm_area_struct *);
+static int cg6_ioctl(struct fb_info *, unsigned int, unsigned long);
/*
* Frame buffer operations
@@ -524,7 +523,7 @@
{ .size = 0 }
};
-static int cg6_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+static int cg6_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct cg6_par *par = (struct cg6_par *)info->par;
@@ -534,8 +533,7 @@
vma);
}
-static int cg6_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg, struct fb_info *info)
+static int cg6_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
struct cg6_par *par = (struct cg6_par *) info->par;
diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c
index 03798e9..655301a 100644
--- a/drivers/video/controlfb.c
+++ b/drivers/video/controlfb.c
@@ -128,7 +128,7 @@
static int controlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info);
static int controlfb_blank(int blank_mode, struct fb_info *info);
-static int controlfb_mmap(struct fb_info *info, struct file *file,
+static int controlfb_mmap(struct fb_info *info,
struct vm_area_struct *vma);
static int controlfb_set_par (struct fb_info *info);
static int controlfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info);
@@ -280,7 +280,7 @@
* for controlfb.
* Note there's no locking in here; it's done in fb_mmap() in fbmem.c.
*/
-static int controlfb_mmap(struct fb_info *info, struct file *file,
+static int controlfb_mmap(struct fb_info *info,
struct vm_area_struct *vma)
{
unsigned long off, start;
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 32a9b69..d2dede6 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -957,7 +957,7 @@
default:
if (fb->fb_ioctl == NULL)
return -EINVAL;
- return fb->fb_ioctl(inode, file, cmd, arg, info);
+ return fb->fb_ioctl(info, cmd, arg);
}
}
@@ -1107,7 +1107,7 @@
default:
if (fb->fb_compat_ioctl)
- ret = fb->fb_compat_ioctl(file, cmd, arg, info);
+ ret = fb->fb_compat_ioctl(info, cmd, arg);
break;
}
unlock_kernel();
@@ -1135,7 +1135,7 @@
if (fb->fb_mmap) {
int res;
lock_kernel();
- res = fb->fb_mmap(info, file, vma);
+ res = fb->fb_mmap(info, vma);
unlock_kernel();
return res;
}
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index c4870d5..9c9b21d 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -37,9 +37,8 @@
static void ffb_fillrect(struct fb_info *, const struct fb_fillrect *);
static void ffb_copyarea(struct fb_info *, const struct fb_copyarea *);
static int ffb_sync(struct fb_info *);
-static int ffb_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
-static int ffb_ioctl(struct inode *, struct file *, unsigned int,
- unsigned long, struct fb_info *);
+static int ffb_mmap(struct fb_info *, struct vm_area_struct *);
+static int ffb_ioctl(struct fb_info *, unsigned int, unsigned long);
static int ffb_pan_display(struct fb_var_screeninfo *, struct fb_info *);
/*
@@ -839,7 +838,7 @@
{ .size = 0 }
};
-static int ffb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+static int ffb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct ffb_par *par = (struct ffb_par *)info->par;
@@ -848,8 +847,7 @@
0, vma);
}
-static int ffb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg, struct fb_info *info)
+static int ffb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
struct ffb_par *par = (struct ffb_par *) info->par;
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index d744c51..38d2272 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -979,7 +979,7 @@
return 0;
}
-static int gbefb_mmap(struct fb_info *info, struct file *file,
+static int gbefb_mmap(struct fb_info *info,
struct vm_area_struct *vma)
{
unsigned long size = vma->vm_end - vma->vm_start;
@@ -1000,7 +1000,6 @@
pgprot_fb(pgprot_val(vma->vm_page_prot));
vma->vm_flags |= VM_IO | VM_RESERVED;
- vma->vm_file = file;
/* look for the starting tile */
tile = &gbe_tiles.cpu[offset >> TILE_SHIFT];
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c
index 8e8da74..20e6915 100644
--- a/drivers/video/geode/gx1fb_core.c
+++ b/drivers/video/geode/gx1fb_core.c
@@ -215,11 +215,11 @@
if (ret < 0)
return ret;
- ret = pci_request_region(dev, 1, "gx1fb (video)");
+ ret = pci_request_region(dev, 0, "gx1fb (video)");
if (ret < 0)
return ret;
- par->vid_regs = ioremap(pci_resource_start(dev, 1),
- pci_resource_len(dev, 1));
+ par->vid_regs = ioremap(pci_resource_start(dev, 0),
+ pci_resource_len(dev, 0));
if (!par->vid_regs)
return -ENOMEM;
@@ -229,12 +229,9 @@
if (!par->dc_regs)
return -ENOMEM;
- ret = pci_request_region(dev, 0, "gx1fb (frame buffer)");
- if (ret < 0 )
- return -EBUSY;
if ((fb_len = gx1_frame_buffer_size()) < 0)
return -ENOMEM;
- info->fix.smem_start = pci_resource_start(dev, 0);
+ info->fix.smem_start = gx_base + 0x800000;
info->fix.smem_len = fb_len;
info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
if (!info->screen_base)
diff --git a/drivers/video/igafb.c b/drivers/video/igafb.c
index e326f44..6b88050 100644
--- a/drivers/video/igafb.c
+++ b/drivers/video/igafb.c
@@ -219,7 +219,7 @@
}
#ifdef __sparc__
-static int igafb_mmap(struct fb_info *info, struct file *file,
+static int igafb_mmap(struct fb_info *info,
struct vm_area_struct *vma)
{
struct iga_par *par = (struct iga_par *)info->par;
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index a5d8130..ad416ae 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -1267,8 +1267,7 @@
#define FBIMSTT_GETIDXREG 0x545406
static int
-imsttfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
- u_long arg, struct fb_info *info)
+imsttfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
{
struct imstt_par *par = info->par;
void __user *argp = (void __user *)arg;
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 0090544..6b8bd3c 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -157,9 +157,8 @@
static int intelfb_sync(struct fb_info *info);
-static int intelfb_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg,
- struct fb_info *info);
+static int intelfb_ioctl(struct fb_info *info,
+ unsigned int cmd, unsigned long arg);
static int __devinit intelfb_pci_register(struct pci_dev *pdev,
const struct pci_device_id *ent);
@@ -1380,8 +1379,7 @@
/* When/if we have our own ioctls. */
static int
-intelfb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg, struct fb_info *info)
+intelfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
int retval = 0;
diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c
index bcd359b..477ad29 100644
--- a/drivers/video/kyro/fbdev.c
+++ b/drivers/video/kyro/fbdev.c
@@ -586,9 +586,8 @@
}
#endif
-static int kyrofb_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg,
- struct fb_info *info)
+static int kyrofb_ioctl(struct fb_info *info,
+ unsigned int cmd, unsigned long arg)
{
overlay_create ol_create;
overlay_viewport_set ol_viewport_set;
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index 494287f..a23cfdb 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -32,9 +32,8 @@
unsigned, struct fb_info *);
static int leo_blank(int, struct fb_info *);
-static int leo_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
-static int leo_ioctl(struct inode *, struct file *, unsigned int,
- unsigned long, struct fb_info *);
+static int leo_mmap(struct fb_info *, struct vm_area_struct *);
+static int leo_ioctl(struct fb_info *, unsigned int, unsigned long);
static int leo_pan_display(struct fb_var_screeninfo *, struct fb_info *);
/*
@@ -363,7 +362,7 @@
{ .size = 0 }
};
-static int leo_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+static int leo_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct leo_par *par = (struct leo_par *)info->par;
@@ -373,8 +372,7 @@
vma);
}
-static int leo_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg, struct fb_info *info)
+static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
struct leo_par *par = (struct leo_par *) info->par;
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index 1e74f4c..4055ff6 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -865,9 +865,8 @@
.name = "Panellink output",
};
-static int matroxfb_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg,
- struct fb_info *info)
+static int matroxfb_ioctl(struct fb_info *info,
+ unsigned int cmd, unsigned long arg)
{
void __user *argp = (void __user *)arg;
MINFO_FROM_INFO(info);
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c
index d52d7d8..27eb4bb 100644
--- a/drivers/video/matrox/matroxfb_crtc2.c
+++ b/drivers/video/matrox/matroxfb_crtc2.c
@@ -419,11 +419,10 @@
return 0;
}
-static int matroxfb_dh_ioctl(struct inode* inode,
- struct file* file,
+static int matroxfb_dh_ioctl(struct fb_info *info,
unsigned int cmd,
- unsigned long arg,
- struct fb_info* info) {
+ unsigned long arg)
+{
#define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
MINFO_FROM(m2info->primary_dev);
@@ -457,7 +456,7 @@
case MATROXFB_GET_OUTPUT_MODE:
case MATROXFB_GET_ALL_OUTPUTS:
{
- return ACCESS_FBINFO(fbcon.fbops)->fb_ioctl(inode, file, cmd, arg, &ACCESS_FBINFO(fbcon));
+ return ACCESS_FBINFO(fbcon.fbops)->fb_ioctl(&ACCESS_FBINFO(fbcon), cmd, arg);
}
case MATROXFB_SET_OUTPUT_CONNECTION:
{
diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c
index a1f2c5e..6019710 100644
--- a/drivers/video/matrox/matroxfb_maven.c
+++ b/drivers/video/matrox/matroxfb_maven.c
@@ -968,7 +968,7 @@
return 0;
}
-static inline int maven_program_timming(struct maven_data* md,
+static int maven_program_timming(struct maven_data* md,
const struct mavenregs* m) {
struct i2c_client* c = md->client;
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index e18c9f9..747602a 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -853,7 +853,7 @@
/* If the user did not specify any display devices, then... */
if (par->PanelDispCntlReg1 == 0x00) {
/* Default to internal (i.e., LCD) only. */
- par->PanelDispCntlReg1 |= 0x02;
+ par->PanelDispCntlReg1 = vga_rgfx(NULL, 0x20) & 0x03;
}
/* If we are using a fixed mode, then tell the chip we are. */
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c
index b251e75..0d19575 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -31,9 +31,8 @@
unsigned, struct fb_info *);
static int p9100_blank(int, struct fb_info *);
-static int p9100_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
-static int p9100_ioctl(struct inode *, struct file *, unsigned int,
- unsigned long, struct fb_info *);
+static int p9100_mmap(struct fb_info *, struct vm_area_struct *);
+static int p9100_ioctl(struct fb_info *, unsigned int, unsigned long);
/*
* Frame buffer operations
@@ -222,7 +221,7 @@
{ 0, 0, 0 }
};
-static int p9100_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+static int p9100_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct p9100_par *par = (struct p9100_par *)info->par;
@@ -232,8 +231,8 @@
vma);
}
-static int p9100_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg, struct fb_info *info)
+static int p9100_ioctl(struct fb_info *info, unsigned int cmd,
+ unsigned long arg)
{
struct p9100_par *par = (struct p9100_par *) info->par;
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
index 2e11b60..0e78ddc 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -657,9 +657,7 @@
static void pm3fb_detect(void);
static int pm3fb_pan_display(const struct fb_var_screeninfo *var,
struct fb_info_gen *info);
-static int pm3fb_ioctl(struct inode *inode, struct file *file,
- u_int cmd, u_long arg, int con,
- struct fb_info *info);
+static int pm3fb_ioctl(struct fb_info *info, u_int cmd, u_long arg);
/* the struct that hold them together */
@@ -3438,9 +3436,7 @@
return 0;
}
-static int pm3fb_ioctl(struct inode *inode, struct file *file,
- u_int cmd, u_long arg, int con,
- struct fb_info *info)
+static int pm3fb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
{
struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
u32 cm, i;
diff --git a/drivers/video/pmag-aa-fb.c b/drivers/video/pmag-aa-fb.c
index 28d1fe5..d92f352 100644
--- a/drivers/video/pmag-aa-fb.c
+++ b/drivers/video/pmag-aa-fb.c
@@ -299,8 +299,7 @@
return -EINVAL;
}
-static int aafb_ioctl(struct inode *inode, struct file *file, u32 cmd,
- unsigned long arg, int con, struct fb_info *info)
+static int aafb_ioctl(struct fb_info *info, u32 cmd, unsigned long arg)
{
/* TODO: Not yet implemented */
return -ENOIOCTLCMD;
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 9fc10b9..53ad61f 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -395,7 +395,7 @@
return 0;
}
-static int pxafb_mmap(struct fb_info *info, struct file *file,
+static int pxafb_mmap(struct fb_info *info,
struct vm_area_struct *vma)
{
struct pxafb_info *fbi = (struct pxafb_info *)info;
diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c
index 600318f..db9fb90 100644
--- a/drivers/video/radeonfb.c
+++ b/drivers/video/radeonfb.c
@@ -1497,8 +1497,8 @@
}
-static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg, struct fb_info *info)
+static int radeonfb_ioctl (struct fb_info *info, unsigned int cmd,
+ unsigned long arg)
{
struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
unsigned int tmp;
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 087e586..8a893ce 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -815,7 +815,7 @@
return 0;
}
-static int sa1100fb_mmap(struct fb_info *info, struct file *file,
+static int sa1100fb_mmap(struct fb_info *info,
struct vm_area_struct *vma)
{
struct sa1100fb_info *fbi = (struct sa1100fb_info *)info;
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
index 7054660..2e6df1f 100644
--- a/drivers/video/sgivwfb.c
+++ b/drivers/video/sgivwfb.c
@@ -115,7 +115,7 @@
static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green,
u_int blue, u_int transp,
struct fb_info *info);
-static int sgivwfb_mmap(struct fb_info *info, struct file *file,
+static int sgivwfb_mmap(struct fb_info *info,
struct vm_area_struct *vma);
static struct fb_ops sgivwfb_ops = {
@@ -706,7 +706,7 @@
return 0;
}
-static int sgivwfb_mmap(struct fb_info *info, struct file *file,
+static int sgivwfb_mmap(struct fb_info *info,
struct vm_area_struct *vma)
{
unsigned long size = vma->vm_end - vma->vm_start;
@@ -723,7 +723,6 @@
if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
size, vma->vm_page_prot))
return -EAGAIN;
- vma->vm_file = file;
printk(KERN_DEBUG "sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n",
offset, vma->vm_start);
return 0;
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index dea1a46..8adf5bf 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -1743,13 +1743,14 @@
/* ----------- FBDev related routines for all series ---------- */
-static int
-sisfb_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg,
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- int con,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
+static int sisfb_ioctl(struct fb_info *info, unsigned int cmd,
+ unsigned long arg)
+#else
+static int sisfb_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg,
+ struct fb_info *info)
#endif
- struct fb_info *info)
{
struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
struct sis_memreq sismemreq;
@@ -1924,19 +1925,6 @@
return 0;
}
-#ifdef SIS_NEW_CONFIG_COMPAT
-static long
-sisfb_compat_ioctl(struct file *f, unsigned int cmd, unsigned long arg, struct fb_info *info)
-{
- int ret;
-
- lock_kernel();
- ret = sisfb_ioctl(NULL, f, cmd, arg, info);
- unlock_kernel();
- return ret;
-}
-#endif
-
static int
sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
{
@@ -2007,7 +1995,7 @@
#endif
.fb_sync = fbcon_sis_sync,
#ifdef SIS_NEW_CONFIG_COMPAT
- .fb_compat_ioctl= sisfb_compat_ioctl,
+ .fb_compat_ioctl= sisfb_ioctl,
#endif
.fb_ioctl = sisfb_ioctl
};
diff --git a/drivers/video/sis/sis_main.h b/drivers/video/sis/sis_main.h
index 445bcbb..70b6df3 100644
--- a/drivers/video/sis/sis_main.h
+++ b/drivers/video/sis/sis_main.h
@@ -727,9 +727,14 @@
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
+static int sisfb_ioctl(struct fb_info *info, unsigned int cmd,
+ unsigned long arg);
+#else
static int sisfb_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg,
struct fb_info *info);
+#endif
static int sisfb_set_par(struct fb_info *info);
static int sisfb_blank(int blank,
struct fb_info *info);
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index 8a5ce21..99921df 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -771,8 +771,7 @@
return 0;
}
-static int sstfb_ioctl(struct inode *inode, struct file *file,
- u_int cmd, u_long arg, struct fb_info *info )
+static int sstfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
{
struct sstfb_par *par = info->par;
struct pci_dev *sst_dev = par->dev;
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index 2b27b44..95b9182 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -33,9 +33,8 @@
unsigned, struct fb_info *);
static int tcx_blank(int, struct fb_info *);
-static int tcx_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
-static int tcx_ioctl(struct inode *, struct file *, unsigned int,
- unsigned long, struct fb_info *);
+static int tcx_mmap(struct fb_info *, struct vm_area_struct *);
+static int tcx_ioctl(struct fb_info *, unsigned int, unsigned long);
static int tcx_pan_display(struct fb_var_screeninfo *, struct fb_info *);
/*
@@ -302,7 +301,7 @@
{ .size = 0 }
};
-static int tcx_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+static int tcx_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct tcx_par *par = (struct tcx_par *)info->par;
@@ -312,8 +311,8 @@
vma);
}
-static int tcx_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg, struct fb_info *info)
+static int tcx_ioctl(struct fb_info *info, unsigned int cmd,
+ unsigned long arg)
{
struct tcx_par *par = (struct tcx_par *) info->par;
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index ffa1ad4..53208cb 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -81,7 +81,7 @@
u_int transp, struct fb_info *info);
static int vfb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info);
-static int vfb_mmap(struct fb_info *info, struct file *file,
+static int vfb_mmap(struct fb_info *info,
struct vm_area_struct *vma);
static struct fb_ops vfb_ops = {
@@ -368,7 +368,7 @@
* Most drivers don't need their own mmap function
*/
-static int vfb_mmap(struct fb_info *info, struct file *file,
+static int vfb_mmap(struct fb_info *info,
struct vm_area_struct *vma)
{
return -EINVAL;
diff --git a/fs/9p/conv.c b/fs/9p/conv.c
index 55ccfa1..32a9f99 100644
--- a/fs/9p/conv.c
+++ b/fs/9p/conv.c
@@ -56,7 +56,7 @@
return buf->p > buf->ep;
}
-static inline int buf_check_size(struct cbuf *buf, int len)
+static int buf_check_size(struct cbuf *buf, int len)
{
if (buf->p + len > buf->ep) {
if (buf->p < buf->ep) {
@@ -72,7 +72,7 @@
return 1;
}
-static inline void *buf_alloc(struct cbuf *buf, int len)
+static void *buf_alloc(struct cbuf *buf, int len)
{
void *ret = NULL;
@@ -84,7 +84,7 @@
return ret;
}
-static inline void buf_put_int8(struct cbuf *buf, u8 val)
+static void buf_put_int8(struct cbuf *buf, u8 val)
{
if (buf_check_size(buf, 1)) {
buf->p[0] = val;
@@ -92,7 +92,7 @@
}
}
-static inline void buf_put_int16(struct cbuf *buf, u16 val)
+static void buf_put_int16(struct cbuf *buf, u16 val)
{
if (buf_check_size(buf, 2)) {
*(__le16 *) buf->p = cpu_to_le16(val);
@@ -100,7 +100,7 @@
}
}
-static inline void buf_put_int32(struct cbuf *buf, u32 val)
+static void buf_put_int32(struct cbuf *buf, u32 val)
{
if (buf_check_size(buf, 4)) {
*(__le32 *)buf->p = cpu_to_le32(val);
@@ -108,7 +108,7 @@
}
}
-static inline void buf_put_int64(struct cbuf *buf, u64 val)
+static void buf_put_int64(struct cbuf *buf, u64 val)
{
if (buf_check_size(buf, 8)) {
*(__le64 *)buf->p = cpu_to_le64(val);
@@ -116,7 +116,7 @@
}
}
-static inline void buf_put_stringn(struct cbuf *buf, const char *s, u16 slen)
+static void buf_put_stringn(struct cbuf *buf, const char *s, u16 slen)
{
if (buf_check_size(buf, slen + 2)) {
buf_put_int16(buf, slen);
@@ -130,7 +130,7 @@
buf_put_stringn(buf, s, strlen(s));
}
-static inline u8 buf_get_int8(struct cbuf *buf)
+static u8 buf_get_int8(struct cbuf *buf)
{
u8 ret = 0;
@@ -142,7 +142,7 @@
return ret;
}
-static inline u16 buf_get_int16(struct cbuf *buf)
+static u16 buf_get_int16(struct cbuf *buf)
{
u16 ret = 0;
@@ -154,7 +154,7 @@
return ret;
}
-static inline u32 buf_get_int32(struct cbuf *buf)
+static u32 buf_get_int32(struct cbuf *buf)
{
u32 ret = 0;
@@ -166,7 +166,7 @@
return ret;
}
-static inline u64 buf_get_int64(struct cbuf *buf)
+static u64 buf_get_int64(struct cbuf *buf)
{
u64 ret = 0;
@@ -178,7 +178,7 @@
return ret;
}
-static inline void buf_get_str(struct cbuf *buf, struct v9fs_str *vstr)
+static void buf_get_str(struct cbuf *buf, struct v9fs_str *vstr)
{
vstr->len = buf_get_int16(buf);
if (!buf_check_overflow(buf) && buf_check_size(buf, vstr->len)) {
@@ -190,7 +190,7 @@
}
}
-static inline void buf_get_qid(struct cbuf *bufp, struct v9fs_qid *qid)
+static void buf_get_qid(struct cbuf *bufp, struct v9fs_qid *qid)
{
qid->type = buf_get_int8(bufp);
qid->version = buf_get_int32(bufp);
@@ -254,7 +254,7 @@
*
*/
-static inline void
+static void
buf_get_stat(struct cbuf *bufp, struct v9fs_stat *stat, int extended)
{
stat->size = buf_get_int16(bufp);
@@ -427,7 +427,7 @@
buf_put_int64(bufp, val);
}
-static inline void
+static void
v9fs_put_str(struct cbuf *bufp, char *data, struct v9fs_str *str)
{
if (data) {
@@ -441,7 +441,7 @@
buf_put_stringn(bufp, data, str->len);
}
-static inline int
+static int
v9fs_put_user_data(struct cbuf *bufp, const char __user * data, int count,
unsigned char **pdata)
{
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index e93a7ae..62d8d4a 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -195,6 +195,8 @@
if (!empty)
d_invalidate(dentry);
+ nd.dentry = dentry;
+ nd.mnt = mnt;
nd.flags = LOOKUP_DIRECTORY;
status = (dentry->d_op->d_revalidate)(dentry, &nd);
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index f979ebb..1b117a4 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1218,7 +1218,7 @@
if (!dump_seek(file, (off))) \
goto end_coredump;
-static inline void fill_elf_header(struct elfhdr *elf, int segs)
+static void fill_elf_header(struct elfhdr *elf, int segs)
{
memcpy(elf->e_ident, ELFMAG, SELFMAG);
elf->e_ident[EI_CLASS] = ELF_CLASS;
@@ -1243,7 +1243,7 @@
return;
}
-static inline void fill_elf_note_phdr(struct elf_phdr *phdr, int sz, off_t offset)
+static void fill_elf_note_phdr(struct elf_phdr *phdr, int sz, off_t offset)
{
phdr->p_type = PT_NOTE;
phdr->p_offset = offset;
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 9ccc7d8..6a7b730 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -264,7 +264,7 @@
return p - from;
}
-static inline char * check_special_flags (char * sfs, Node * e)
+static char * check_special_flags (char * sfs, Node * e)
{
char * p = sfs;
int cont = 1;
diff --git a/fs/bio.c b/fs/bio.c
index 7b30695..bbc442b 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -123,7 +123,7 @@
bio_free(bio, fs_bio_set);
}
-inline void bio_init(struct bio *bio)
+void bio_init(struct bio *bio)
{
bio->bi_next = NULL;
bio->bi_bdev = NULL;
@@ -253,7 +253,7 @@
* the actual data it points to. Reference count of returned
* bio will be one.
*/
-inline void __bio_clone(struct bio *bio, struct bio *bio_src)
+void __bio_clone(struct bio *bio, struct bio *bio_src)
{
request_queue_t *q = bdev_get_queue(bio_src->bi_bdev);
diff --git a/fs/buffer.c b/fs/buffer.c
index b9bb7ad..7cdf48a 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1165,7 +1165,7 @@
* some of those buffers may be aliases of filesystem data.
* grow_dev_page() will go BUG() if this happens.
*/
-static inline int
+static int
grow_buffers(struct block_device *bdev, sector_t block, int size)
{
struct page *page;
@@ -1391,7 +1391,7 @@
/*
* Look up the bh in this cpu's LRU. If it's there, move it to the head.
*/
-static inline struct buffer_head *
+static struct buffer_head *
lookup_bh_lru(struct block_device *bdev, sector_t block, int size)
{
struct buffer_head *ret = NULL;
@@ -1541,7 +1541,7 @@
/*
* Called when truncating a buffer on a page completely.
*/
-static inline void discard_buffer(struct buffer_head * bh)
+static void discard_buffer(struct buffer_head * bh)
{
lock_buffer(bh);
clear_buffer_dirty(bh);
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 3b1b1ee..21195c4 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -35,7 +35,7 @@
unsigned int major;
unsigned int baseminor;
int minorct;
- const char *name;
+ char name[64];
struct file_operations *fops;
struct cdev *cdev; /* will die */
} *chrdevs[MAX_PROBE_HASH];
@@ -46,34 +46,84 @@
return major % MAX_PROBE_HASH;
}
-/* get char device names in somewhat random order */
-int get_chrdev_list(char *page)
+struct chrdev_info {
+ int index;
+ struct char_device_struct *cd;
+};
+
+void *get_next_chrdev(void *dev)
+{
+ struct chrdev_info *info;
+
+ if (dev == NULL) {
+ info = kmalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ goto out;
+ info->index=0;
+ info->cd = chrdevs[info->index];
+ if (info->cd)
+ goto out;
+ } else {
+ info = dev;
+ }
+
+ while (info->index < ARRAY_SIZE(chrdevs)) {
+ if (info->cd)
+ info->cd = info->cd->next;
+ if (info->cd)
+ goto out;
+ /*
+ * No devices on this chain, move to the next
+ */
+ info->index++;
+ info->cd = (info->index < ARRAY_SIZE(chrdevs)) ?
+ chrdevs[info->index] : NULL;
+ if (info->cd)
+ goto out;
+ }
+
+out:
+ return info;
+}
+
+void *acquire_chrdev_list(void)
+{
+ down(&chrdevs_lock);
+ return get_next_chrdev(NULL);
+}
+
+void release_chrdev_list(void *dev)
+{
+ up(&chrdevs_lock);
+ kfree(dev);
+}
+
+
+int count_chrdev_list(void)
{
struct char_device_struct *cd;
- int i, len;
+ int i, count;
- len = sprintf(page, "Character devices:\n");
+ count = 0;
- down(&chrdevs_lock);
for (i = 0; i < ARRAY_SIZE(chrdevs) ; i++) {
- for (cd = chrdevs[i]; cd; cd = cd->next) {
- /*
- * if the current name, plus the 5 extra characters
- * in the device line for this entry
- * would run us off the page, we're done
- */
- if ((len+strlen(cd->name) + 5) >= PAGE_SIZE)
- goto page_full;
-
-
- len += sprintf(page+len, "%3d %s\n",
- cd->major, cd->name);
- }
+ for (cd = chrdevs[i]; cd; cd = cd->next)
+ count++;
}
-page_full:
- up(&chrdevs_lock);
- return len;
+ return count;
+}
+
+int get_chrdev_info(void *dev, int *major, char **name)
+{
+ struct chrdev_info *info = dev;
+
+ if (info->cd == NULL)
+ return 1;
+
+ *major = info->cd->major;
+ *name = info->cd->name;
+ return 0;
}
/*
@@ -121,7 +171,7 @@
cd->major = major;
cd->baseminor = baseminor;
cd->minorct = minorct;
- cd->name = name;
+ strncpy(cd->name,name, 64);
i = major_to_index(major);
diff --git a/fs/compat.c b/fs/compat.c
index 271b75d..2468ac1 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1537,7 +1537,7 @@
* Ooo, nasty. We need here to frob 32-bit unsigned longs to
* 64-bit unsigned longs.
*/
-static inline
+static
int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
unsigned long *fdset)
{
@@ -1570,7 +1570,7 @@
return 0;
}
-static inline
+static
void compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
unsigned long *fdset)
{
diff --git a/fs/dcache.c b/fs/dcache.c
index 134d677..86bdb93 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -94,7 +94,7 @@
* d_iput() operation if defined.
* Called with dcache_lock and per dentry lock held, drops both.
*/
-static inline void dentry_iput(struct dentry * dentry)
+static void dentry_iput(struct dentry * dentry)
{
struct inode *inode = dentry->d_inode;
if (inode) {
diff --git a/fs/exec.c b/fs/exec.c
index b5bcf1a..62b40af 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -575,7 +575,7 @@
* disturbing other processes. (Other processes might share the signal
* table via the CLONE_SIGHAND option to clone().)
*/
-static inline int de_thread(struct task_struct *tsk)
+static int de_thread(struct task_struct *tsk)
{
struct signal_struct *sig = tsk->signal;
struct sighand_struct *newsighand, *oldsighand = tsk->sighand;
@@ -780,7 +780,7 @@
* so that a new one can be started
*/
-static inline void flush_old_files(struct files_struct * files)
+static void flush_old_files(struct files_struct * files)
{
long j = -1;
struct fdtable *fdt;
@@ -964,7 +964,7 @@
EXPORT_SYMBOL(prepare_binprm);
-static inline int unsafe_exec(struct task_struct *p)
+static int unsafe_exec(struct task_struct *p)
{
int unsafe = 0;
if (p->ptrace & PT_PTRACED) {
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index c551395..ad1432a 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -83,10 +83,7 @@
if (!inode)
return ERR_PTR(-EACCES);
}
- if (inode)
- return d_splice_alias(inode, dentry);
- d_add(dentry, inode);
- return NULL;
+ return d_splice_alias(inode, dentry);
}
struct dentry *ext2_get_parent(struct dentry *child)
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index af193a3..8bd8ac0 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -1005,10 +1005,7 @@
if (!inode)
return ERR_PTR(-EACCES);
}
- if (inode)
- return d_splice_alias(inode, dentry);
- d_add(dentry, inode);
- return NULL;
+ return d_splice_alias(inode, dentry);
}
diff --git a/fs/fcntl.c b/fs/fcntl.c
index d0767fe..5f96786 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -36,7 +36,7 @@
spin_unlock(&files->file_lock);
}
-static inline int get_close_on_exec(unsigned int fd)
+static int get_close_on_exec(unsigned int fd)
{
struct files_struct *files = current->files;
struct fdtable *fdt;
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index ab4c3a9..f568102 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -402,7 +402,7 @@
inode->i_mapping->backing_dev_info =&hugetlbfs_backing_dev_info;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
info = HUGETLBFS_I(inode);
- mpol_shared_policy_init(&info->policy);
+ mpol_shared_policy_init(&info->policy, MPOL_DEFAULT, NULL);
switch (mode & S_IFMT) {
default:
init_special_inode(inode, mode, dev);
diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c
index e37e82b..e7ba0c3 100644
--- a/fs/isofs/namei.c
+++ b/fs/isofs/namei.c
@@ -185,8 +185,5 @@
}
}
unlock_kernel();
- if (inode)
- return d_splice_alias(inode, dentry);
- d_add(dentry, inode);
- return NULL;
+ return d_splice_alias(inode, dentry);
}
diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c
index fff108b..70f7a89 100644
--- a/fs/jffs2/build.c
+++ b/fs/jffs2/build.c
@@ -47,7 +47,7 @@
ic = next_inode(&i, ic, (c)))
-static inline void jffs2_build_inode_pass1(struct jffs2_sb_info *c,
+static void jffs2_build_inode_pass1(struct jffs2_sb_info *c,
struct jffs2_inode_cache *ic)
{
struct jffs2_full_dirent *fd;
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c
index c79eebb..b635e16 100644
--- a/fs/jffs2/nodelist.c
+++ b/fs/jffs2/nodelist.c
@@ -134,7 +134,7 @@
/*
* Allocate and initializes a new fragment.
*/
-static inline struct jffs2_node_frag * new_fragment(struct jffs2_full_dnode *fn, uint32_t ofs, uint32_t size)
+static struct jffs2_node_frag * new_fragment(struct jffs2_full_dnode *fn, uint32_t ofs, uint32_t size)
{
struct jffs2_node_frag *newfrag;
@@ -513,7 +513,7 @@
*
* Checks the node if we are in the checking stage.
*/
-static inline int check_node(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn)
+static int check_node(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn)
{
int ret;
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c
index f01e9c0..200fbda 100644
--- a/fs/lockd/xdr.c
+++ b/fs/lockd/xdr.c
@@ -44,7 +44,7 @@
/*
* XDR functions for basic NLM types
*/
-static inline u32 *nlm_decode_cookie(u32 *p, struct nlm_cookie *c)
+static u32 *nlm_decode_cookie(u32 *p, struct nlm_cookie *c)
{
unsigned int len;
@@ -79,7 +79,7 @@
return p;
}
-static inline u32 *
+static u32 *
nlm_decode_fh(u32 *p, struct nfs_fh *f)
{
unsigned int len;
@@ -119,7 +119,7 @@
return xdr_encode_netobj(p, oh);
}
-static inline u32 *
+static u32 *
nlm_decode_lock(u32 *p, struct nlm_lock *lock)
{
struct file_lock *fl = &lock->fl;
diff --git a/fs/mbcache.c b/fs/mbcache.c
index 0f1e453..f5bbe4c 100644
--- a/fs/mbcache.c
+++ b/fs/mbcache.c
@@ -126,7 +126,7 @@
}
-static inline void
+static void
__mb_cache_entry_unhash(struct mb_cache_entry *ce)
{
int n;
@@ -139,7 +139,7 @@
}
-static inline void
+static void
__mb_cache_entry_forget(struct mb_cache_entry *ce, gfp_t gfp_mask)
{
struct mb_cache *cache = ce->e_cache;
@@ -158,7 +158,7 @@
}
-static inline void
+static void
__mb_cache_entry_release_unlock(struct mb_cache_entry *ce)
{
/* Wake up all processes queuing for this cache entry. */
diff --git a/fs/namei.c b/fs/namei.c
index 1e5746e..33fb5bd 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -113,7 +113,7 @@
* POSIX.1 2.4: an empty pathname is invalid (ENOENT).
* PATH_MAX includes the nul terminator --RR.
*/
-static inline int do_getname(const char __user *filename, char *page)
+static int do_getname(const char __user *filename, char *page)
{
int retval;
unsigned long len = PATH_MAX;
@@ -396,7 +396,7 @@
* short-cut DAC fails, then call permission() to do more
* complete permission check.
*/
-static inline int exec_permission_lite(struct inode *inode,
+static int exec_permission_lite(struct inode *inode,
struct nameidata *nd)
{
umode_t mode = inode->i_mode;
@@ -486,7 +486,7 @@
static int __emul_lookup_dentry(const char *, struct nameidata *);
/* SMP-safe */
-static inline int
+static __always_inline int
walk_init_root(const char *name, struct nameidata *nd)
{
read_lock(¤t->fs->lock);
@@ -504,7 +504,7 @@
return 1;
}
-static inline int __vfs_follow_link(struct nameidata *nd, const char *link)
+static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link)
{
int res = 0;
char *name;
@@ -544,7 +544,7 @@
struct dentry *dentry;
};
-static inline int __do_follow_link(struct path *path, struct nameidata *nd)
+static __always_inline int __do_follow_link(struct path *path, struct nameidata *nd)
{
int error;
void *cookie;
@@ -690,7 +690,7 @@
return 0;
}
-static inline void follow_dotdot(struct nameidata *nd)
+static __always_inline void follow_dotdot(struct nameidata *nd)
{
while(1) {
struct vfsmount *parent;
@@ -1294,7 +1294,7 @@
* 10. We don't allow removal of NFS sillyrenamed files; it's handled by
* nfs_async_unlink().
*/
-static inline int may_delete(struct inode *dir,struct dentry *victim,int isdir)
+static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
{
int error;
@@ -2315,7 +2315,7 @@
return error;
}
-static inline int do_rename(const char * oldname, const char * newname)
+static int do_rename(const char * oldname, const char * newname)
{
int error = 0;
struct dentry * old_dir, * new_dir;
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index 8c88392..d277a58 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -716,10 +716,8 @@
fput(server->ncp_filp);
kill_proc(server->m.wdog_pid, SIGTERM, 1);
- if (server->priv.data)
- ncp_kfree_s(server->priv.data, server->priv.len);
- if (server->auth.object_name)
- ncp_kfree_s(server->auth.object_name, server->auth.object_name_len);
+ kfree(server->priv.data);
+ kfree(server->auth.object_name);
vfree(server->packet);
sb->s_fs_info = NULL;
kfree(server);
@@ -958,11 +956,6 @@
return result;
}
-#ifdef DEBUG_NCP_MALLOC
-int ncp_malloced;
-int ncp_current_malloced;
-#endif
-
static struct super_block *ncp_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
@@ -981,10 +974,6 @@
int err;
DPRINTK("ncpfs: init_module called\n");
-#ifdef DEBUG_NCP_MALLOC
- ncp_malloced = 0;
- ncp_current_malloced = 0;
-#endif
err = init_inodecache();
if (err)
goto out1;
@@ -1003,10 +992,6 @@
DPRINTK("ncpfs: cleanup_module called\n");
unregister_filesystem(&ncp_fs_type);
destroy_inodecache();
-#ifdef DEBUG_NCP_MALLOC
- PRINTK("ncp_malloced: %d\n", ncp_malloced);
- PRINTK("ncp_current_malloced: %d\n", ncp_current_malloced);
-#endif
}
module_init(init_ncp_fs)
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c
index d6e0c08..eb3813a 100644
--- a/fs/ncpfs/ioctl.c
+++ b/fs/ncpfs/ioctl.c
@@ -518,10 +518,11 @@
if (user.object_name_len > NCP_OBJECT_NAME_MAX_LEN)
return -ENOMEM;
if (user.object_name_len) {
- newname = ncp_kmalloc(user.object_name_len, GFP_USER);
- if (!newname) return -ENOMEM;
+ newname = kmalloc(user.object_name_len, GFP_USER);
+ if (!newname)
+ return -ENOMEM;
if (copy_from_user(newname, user.object_name, user.object_name_len)) {
- ncp_kfree_s(newname, user.object_name_len);
+ kfree(newname);
return -EFAULT;
}
} else {
@@ -540,8 +541,8 @@
server->priv.len = 0;
server->priv.data = NULL;
/* leave critical section */
- if (oldprivate) ncp_kfree_s(oldprivate, oldprivatelen);
- if (oldname) ncp_kfree_s(oldname, oldnamelen);
+ kfree(oldprivate);
+ kfree(oldname);
return 0;
}
case NCP_IOC_GETPRIVATEDATA:
@@ -581,10 +582,11 @@
if (user.len > NCP_PRIVATE_DATA_MAX_LEN)
return -ENOMEM;
if (user.len) {
- new = ncp_kmalloc(user.len, GFP_USER);
- if (!new) return -ENOMEM;
+ new = kmalloc(user.len, GFP_USER);
+ if (!new)
+ return -ENOMEM;
if (copy_from_user(new, user.data, user.len)) {
- ncp_kfree_s(new, user.len);
+ kfree(new);
return -EFAULT;
}
} else {
@@ -596,7 +598,7 @@
server->priv.len = user.len;
server->priv.data = new;
/* leave critical section */
- if (old) ncp_kfree_s(old, oldlen);
+ kfree(old);
return 0;
}
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index aa7bb41..e3a0797 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -37,7 +37,7 @@
/*
* XDR functions for basic NFS types
*/
-static inline u32 *
+static u32 *
decode_fh(u32 *p, struct svc_fh *fhp)
{
fh_init(fhp, NFS_FHSIZE);
@@ -151,7 +151,7 @@
return p;
}
-static inline u32 *
+static u32 *
encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp,
struct kstat *stat)
{
diff --git a/fs/pipe.c b/fs/pipe.c
index eef0f29..d722579 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -50,7 +50,7 @@
mutex_lock(PIPE_MUTEX(*inode));
}
-static inline int
+static int
pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len)
{
unsigned long copy;
@@ -70,7 +70,7 @@
return 0;
}
-static inline int
+static int
pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len)
{
unsigned long copy;
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 63bf6c0..8f80142 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -20,6 +20,7 @@
#include <linux/time.h>
#include <linux/kernel.h>
#include <linux/kernel_stat.h>
+#include <linux/fs.h>
#include <linux/tty.h>
#include <linux/string.h>
#include <linux/mman.h>
@@ -62,7 +63,6 @@
*/
extern int get_hardware_list(char *);
extern int get_stram_list(char *);
-extern int get_chrdev_list(char *);
extern int get_filesystem_list(char *);
extern int get_exec_domain_list(char *);
extern int get_dma_list(char *);
@@ -248,6 +248,154 @@
{
return seq_open(file, &cpuinfo_op);
}
+
+enum devinfo_states {
+ CHR_HDR,
+ CHR_LIST,
+ BLK_HDR,
+ BLK_LIST,
+ DEVINFO_DONE
+};
+
+struct devinfo_state {
+ void *chrdev;
+ void *blkdev;
+ unsigned int num_records;
+ unsigned int cur_record;
+ enum devinfo_states state;
+};
+
+static void *devinfo_start(struct seq_file *f, loff_t *pos)
+{
+ struct devinfo_state *info = f->private;
+
+ if (*pos) {
+ if ((info) && (*pos <= info->num_records))
+ return info;
+ return NULL;
+ }
+ info = kmalloc(sizeof(*info), GFP_KERNEL);
+ f->private = info;
+ info->chrdev = acquire_chrdev_list();
+ info->blkdev = acquire_blkdev_list();
+ info->state = CHR_HDR;
+ info->num_records = count_chrdev_list();
+ info->num_records += count_blkdev_list();
+ info->num_records += 2; /* Character and Block headers */
+ *pos = 1;
+ info->cur_record = *pos;
+ return info;
+}
+
+static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
+{
+ int idummy;
+ char *ndummy;
+ struct devinfo_state *info = f->private;
+
+ switch (info->state) {
+ case CHR_HDR:
+ info->state = CHR_LIST;
+ (*pos)++;
+ /*fallthrough*/
+ case CHR_LIST:
+ if (get_chrdev_info(info->chrdev,&idummy,&ndummy)) {
+ /*
+ * The character dev list is complete
+ */
+ info->state = BLK_HDR;
+ } else {
+ info->chrdev = get_next_chrdev(info->chrdev);
+ }
+ (*pos)++;
+ break;
+ case BLK_HDR:
+ info->state = BLK_LIST;
+ (*pos)++;
+ break;
+ case BLK_LIST:
+ if (get_blkdev_info(info->blkdev,&idummy,&ndummy)) {
+ /*
+ * The block dev list is complete
+ */
+ info->state = DEVINFO_DONE;
+ } else {
+ info->blkdev = get_next_blkdev(info->blkdev);
+ }
+ (*pos)++;
+ break;
+ case DEVINFO_DONE:
+ (*pos)++;
+ info->cur_record = *pos;
+ info = NULL;
+ break;
+ default:
+ break;
+ }
+ if (info)
+ info->cur_record = *pos;
+ return info;
+}
+
+static void devinfo_stop(struct seq_file *f, void *v)
+{
+ struct devinfo_state *info = f->private;
+
+ if (info) {
+ release_chrdev_list(info->chrdev);
+ release_blkdev_list(info->blkdev);
+ f->private = NULL;
+ kfree(info);
+ }
+}
+
+static int devinfo_show(struct seq_file *f, void *arg)
+{
+ int major;
+ char *name;
+ struct devinfo_state *info = f->private;
+
+ switch(info->state) {
+ case CHR_HDR:
+ seq_printf(f,"Character devices:\n");
+ /* fallthrough */
+ case CHR_LIST:
+ if (!get_chrdev_info(info->chrdev,&major,&name))
+ seq_printf(f,"%3d %s\n",major,name);
+ break;
+ case BLK_HDR:
+ seq_printf(f,"\nBlock devices:\n");
+ /* fallthrough */
+ case BLK_LIST:
+ if (!get_blkdev_info(info->blkdev,&major,&name))
+ seq_printf(f,"%3d %s\n",major,name);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static struct seq_operations devinfo_op = {
+ .start = devinfo_start,
+ .next = devinfo_next,
+ .stop = devinfo_stop,
+ .show = devinfo_show,
+};
+
+static int devinfo_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &devinfo_op);
+}
+
+static struct file_operations proc_devinfo_operations = {
+ .open = devinfo_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
static struct file_operations proc_cpuinfo_operations = {
.open = cpuinfo_open,
.read = seq_read,
@@ -450,14 +598,6 @@
.release = single_release,
};
-static int devices_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- int len = get_chrdev_list(page);
- len += get_blkdev_list(page+len, len);
- return proc_calc_metrics(page, start, off, count, eof, len);
-}
-
/*
* /proc/interrupts
*/
@@ -582,7 +722,6 @@
#ifdef CONFIG_STRAM_PROC
{"stram", stram_read_proc},
#endif
- {"devices", devices_read_proc},
{"filesystems", filesystems_read_proc},
{"cmdline", cmdline_read_proc},
{"locks", locks_read_proc},
@@ -598,6 +737,7 @@
entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
if (entry)
entry->proc_fops = &proc_kmsg_operations;
+ create_seq_entry("devices", 0, &proc_devinfo_operations);
create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
create_seq_entry("partitions", 0, &proc_partitions_operations);
create_seq_entry("stat", 0, &proc_stat_operations);
diff --git a/fs/quota_v2.c b/fs/quota_v2.c
index 7afcbb1..a4ef91b 100644
--- a/fs/quota_v2.c
+++ b/fs/quota_v2.c
@@ -35,7 +35,8 @@
size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
if (size != sizeof(struct v2_disk_dqheader)) {
- printk("failed read\n");
+ printk("quota_v2: failed read expected=%d got=%d\n",
+ sizeof(struct v2_disk_dqheader), size);
return 0;
}
if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type] ||
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 3549067..8f8d8d0 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -375,11 +375,7 @@
return ERR_PTR(-EIO);
}
- if (inode)
- return d_splice_alias(inode, dentry);
-
- d_add(dentry, inode);
- return NULL;
+ return d_splice_alias(inode, dentry);
}
/*
diff --git a/fs/smbfs/Makefile b/fs/smbfs/Makefile
index 93246b7..6673ee8 100644
--- a/fs/smbfs/Makefile
+++ b/fs/smbfs/Makefile
@@ -13,7 +13,6 @@
EXTRA_CFLAGS += -DSMBFS_PARANOIA
#EXTRA_CFLAGS += -DSMBFS_DEBUG
#EXTRA_CFLAGS += -DSMBFS_DEBUG_VERBOSE
-#EXTRA_CFLAGS += -DDEBUG_SMB_MALLOC
#EXTRA_CFLAGS += -DDEBUG_SMB_TIMESTAMP
#EXTRA_CFLAGS += -Werror
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index 6ec88bf..02e3e82 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -487,11 +487,11 @@
if (server->conn_pid)
kill_proc(server->conn_pid, SIGTERM, 1);
- smb_kfree(server->ops);
+ kfree(server->ops);
smb_unload_nls(server);
sb->s_fs_info = NULL;
smb_unlock_server(server);
- smb_kfree(server);
+ kfree(server);
}
static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
@@ -519,11 +519,10 @@
sb->s_op = &smb_sops;
sb->s_time_gran = 100;
- server = smb_kmalloc(sizeof(struct smb_sb_info), GFP_KERNEL);
+ server = kzalloc(sizeof(struct smb_sb_info), GFP_KERNEL);
if (!server)
goto out_no_server;
sb->s_fs_info = server;
- memset(server, 0, sizeof(struct smb_sb_info));
server->super_block = sb;
server->mnt = NULL;
@@ -542,8 +541,8 @@
/* FIXME: move these to the smb_sb_info struct */
VERBOSE("alloc chunk = %d\n", sizeof(struct smb_ops) +
sizeof(struct smb_mount_data_kernel));
- mem = smb_kmalloc(sizeof(struct smb_ops) +
- sizeof(struct smb_mount_data_kernel), GFP_KERNEL);
+ mem = kmalloc(sizeof(struct smb_ops) +
+ sizeof(struct smb_mount_data_kernel), GFP_KERNEL);
if (!mem)
goto out_no_mem;
@@ -621,12 +620,12 @@
out_no_smbiod:
smb_unload_nls(server);
out_bad_option:
- smb_kfree(mem);
+ kfree(mem);
out_no_mem:
if (!server->mnt)
printk(KERN_ERR "smb_fill_super: allocation failure\n");
sb->s_fs_info = NULL;
- smb_kfree(server);
+ kfree(server);
goto out_fail;
out_wrong_data:
printk(KERN_ERR "smbfs: mount_data version %d is not supported\n", ver);
@@ -782,12 +781,6 @@
return error;
}
-#ifdef DEBUG_SMB_MALLOC
-int smb_malloced;
-int smb_current_kmalloced;
-int smb_current_vmalloced;
-#endif
-
static struct super_block *smb_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
@@ -807,12 +800,6 @@
int err;
DEBUG1("registering ...\n");
-#ifdef DEBUG_SMB_MALLOC
- smb_malloced = 0;
- smb_current_kmalloced = 0;
- smb_current_vmalloced = 0;
-#endif
-
err = init_inodecache();
if (err)
goto out_inode;
@@ -837,11 +824,6 @@
unregister_filesystem(&smb_fs_type);
smb_destroy_request_cache();
destroy_inodecache();
-#ifdef DEBUG_SMB_MALLOC
- printk(KERN_DEBUG "smb_malloced: %d\n", smb_malloced);
- printk(KERN_DEBUG "smb_current_kmalloced: %d\n",smb_current_kmalloced);
- printk(KERN_DEBUG "smb_current_vmalloced: %d\n",smb_current_vmalloced);
-#endif
}
module_init(init_smb_fs)
diff --git a/fs/smbfs/request.c b/fs/smbfs/request.c
index a0f296d..c71c375 100644
--- a/fs/smbfs/request.c
+++ b/fs/smbfs/request.c
@@ -68,7 +68,7 @@
goto out;
if (bufsize > 0) {
- buf = smb_kmalloc(bufsize, GFP_NOFS);
+ buf = kmalloc(bufsize, GFP_NOFS);
if (!buf) {
kmem_cache_free(req_cachep, req);
return NULL;
@@ -124,9 +124,8 @@
{
atomic_dec(&req->rq_server->nr_requests);
if (req->rq_buffer && !(req->rq_flags & SMB_REQ_STATIC))
- smb_kfree(req->rq_buffer);
- if (req->rq_trans2buffer)
- smb_kfree(req->rq_trans2buffer);
+ kfree(req->rq_buffer);
+ kfree(req->rq_trans2buffer);
kmem_cache_free(req_cachep, req);
}
@@ -183,8 +182,7 @@
req->rq_err = 0;
req->rq_errno = 0;
req->rq_fragment = 0;
- if (req->rq_trans2buffer)
- smb_kfree(req->rq_trans2buffer);
+ kfree(req->rq_trans2buffer);
return 0;
}
@@ -647,10 +645,9 @@
goto out_too_long;
req->rq_trans2bufsize = buf_len;
- req->rq_trans2buffer = smb_kmalloc(buf_len, GFP_NOFS);
+ req->rq_trans2buffer = kzalloc(buf_len, GFP_NOFS);
if (!req->rq_trans2buffer)
goto out_no_mem;
- memset(req->rq_trans2buffer, 0, buf_len);
req->rq_parm = req->rq_trans2buffer;
req->rq_data = req->rq_trans2buffer + parm_tot;
diff --git a/include/asm-arm/arch-ixp2000/ixp2000-regs.h b/include/asm-arm/arch-ixp2000/ixp2000-regs.h
index 8cf70ff..2b57f91 100644
--- a/include/asm-arm/arch-ixp2000/ixp2000-regs.h
+++ b/include/asm-arm/arch-ixp2000/ixp2000-regs.h
@@ -26,6 +26,8 @@
* fc000000 da000000 16M PCI CFG0
* fd000000 d8000000 16M PCI I/O
* fe[0-7]00000 8M per-platform mappings
+ * fe900000 80000000 1M SRAM #0 (first MB)
+ * fea00000 cb400000 1M SCRATCH ring get/put
* feb00000 c8000000 1M MSF
* fec00000 df000000 1M PCI CSRs
* fed00000 de000000 1M PCI CREG
@@ -91,6 +93,14 @@
#define IXP2000_MSF_VIRT_BASE 0xfeb00000
#define IXP2000_MSF_SIZE 0x00100000
+#define IXP2000_SCRATCH_RING_PHYS_BASE 0xcb400000
+#define IXP2000_SCRATCH_RING_VIRT_BASE 0xfea00000
+#define IXP2000_SCRATCH_RING_SIZE 0x00100000
+
+#define IXP2000_SRAM0_PHYS_BASE 0x80000000
+#define IXP2000_SRAM0_VIRT_BASE 0xfe900000
+#define IXP2000_SRAM0_SIZE 0x00100000
+
#define IXP2000_PCI_IO_PHYS_BASE 0xd8000000
#define IXP2000_PCI_IO_VIRT_BASE 0xfd000000
#define IXP2000_PCI_IO_SIZE 0x01000000
diff --git a/include/asm-arm/arch-versatile/entry-macro.S b/include/asm-arm/arch-versatile/entry-macro.S
index 58f0d71..feff771 100644
--- a/include/asm-arm/arch-versatile/entry-macro.S
+++ b/include/asm-arm/arch-versatile/entry-macro.S
@@ -8,6 +8,7 @@
* warranty of any kind, whether express or implied.
*/
#include <asm/hardware.h>
+#include <asm/hardware/vic.h>
.macro disable_fiq
.endm
diff --git a/include/asm-arm/arch-versatile/platform.h b/include/asm-arm/arch-versatile/platform.h
index cbdd9fb..72ef874 100644
--- a/include/asm-arm/arch-versatile/platform.h
+++ b/include/asm-arm/arch-versatile/platform.h
@@ -293,26 +293,7 @@
* VERSATILE_SYS_IC
*
*/
-#define VIC_IRQ_STATUS 0
-#define VIC_FIQ_STATUS 0x04
-#define VIC_IRQ_RAW_STATUS 0x08
-#define VIC_INT_SELECT 0x0C /* 1 = FIQ, 0 = IRQ */
-#define VIC_IRQ_ENABLE 0x10 /* 1 = enable, 0 = disable */
-#define VIC_IRQ_ENABLE_CLEAR 0x14
-#define VIC_IRQ_SOFT 0x18
-#define VIC_IRQ_SOFT_CLEAR 0x1C
-#define VIC_PROTECT 0x20
-#define VIC_VECT_ADDR 0x30
-#define VIC_DEF_VECT_ADDR 0x34
-#define VIC_VECT_ADDR0 0x100 /* 0 to 15 */
-#define VIC_VECT_CNTL0 0x200 /* 0 to 15 */
-#define VIC_ITCR 0x300 /* VIC test control register */
-
-#define VIC_FIQ_RAW_STATUS 0x08
-#define VIC_FIQ_ENABLE 0x10 /* 1 = enable, 0 = disable */
-#define VIC_FIQ_ENABLE_CLEAR 0x14
-#define VIC_FIQ_SOFT 0x18
-#define VIC_FIQ_SOFT_CLEAR 0x1C
+/* VIC definitions in include/asm-arm/hardware/vic.h */
#define SIC_IRQ_STATUS 0
#define SIC_IRQ_RAW_STATUS 0x04
@@ -325,8 +306,6 @@
#define SIC_INT_PIC_ENABLES 0x20 /* set interrupt pass through bits */
#define SIC_INT_PIC_ENABLEC 0x24 /* Clear interrupt pass through bits */
-#define VICVectCntl_Enable (1 << 5)
-
/* ------------------------------------------------------------------------
* Interrupts - bit assignment (primary)
* ------------------------------------------------------------------------
diff --git a/include/asm-arm/hardware/vic.h b/include/asm-arm/hardware/vic.h
new file mode 100644
index 0000000..81825eb
--- /dev/null
+++ b/include/asm-arm/hardware/vic.h
@@ -0,0 +1,45 @@
+/*
+ * linux/include/asm-arm/hardware/vic.h
+ *
+ * Copyright (c) ARM Limited 2003. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __ASM_ARM_HARDWARE_VIC_H
+#define __ASM_ARM_HARDWARE_VIC_H
+
+#define VIC_IRQ_STATUS 0x00
+#define VIC_FIQ_STATUS 0x04
+#define VIC_RAW_STATUS 0x08
+#define VIC_INT_SELECT 0x0c /* 1 = FIQ, 0 = IRQ */
+#define VIC_INT_ENABLE 0x10 /* 1 = enable, 0 = disable */
+#define VIC_INT_ENABLE_CLEAR 0x14
+#define VIC_INT_SOFT 0x18
+#define VIC_INT_SOFT_CLEAR 0x1c
+#define VIC_PROTECT 0x20
+#define VIC_VECT_ADDR 0x30
+#define VIC_DEF_VECT_ADDR 0x34
+
+#define VIC_VECT_ADDR0 0x100 /* 0 to 15 */
+#define VIC_VECT_CNTL0 0x200 /* 0 to 15 */
+#define VIC_ITCR 0x300 /* VIC test control register */
+
+#define VIC_VECT_CNTL_ENABLE (1 << 5)
+
+#ifndef __ASSEMBLY__
+void vic_init(void __iomem *base, u32 vic_sources);
+#endif
+
+#endif
diff --git a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h
index eb262e07..2cd57b4 100644
--- a/include/asm-arm/mach/arch.h
+++ b/include/asm-arm/mach/arch.h
@@ -10,6 +10,8 @@
#ifndef __ASSEMBLY__
+#include <linux/compiler.h>
+
struct tag;
struct meminfo;
struct sys_timer;
@@ -20,7 +22,7 @@
* by assembler code in head-armv.S
*/
unsigned int nr; /* architecture number */
- unsigned int phys_ram; /* start of physical ram */
+ unsigned int __deprecated phys_ram; /* start of physical ram */
unsigned int phys_io; /* start of physical io */
unsigned int io_pg_offst; /* byte offset for io
* page tabe entry */
diff --git a/include/asm-arm/page.h b/include/asm-arm/page.h
index 4da1d53..416320d 100644
--- a/include/asm-arm/page.h
+++ b/include/asm-arm/page.h
@@ -170,6 +170,13 @@
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+/*
+ * With EABI on ARMv5 and above we must have 64-bit aligned slab pointers.
+ */
+#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5)
+#define ARCH_SLAB_MINALIGN 8
+#endif
+
#endif /* __KERNEL__ */
#include <asm-generic/page.h>
diff --git a/include/asm-arm/processor.h b/include/asm-arm/processor.h
index 3129069..04f4d34 100644
--- a/include/asm-arm/processor.h
+++ b/include/asm-arm/processor.h
@@ -49,6 +49,12 @@
#define INIT_THREAD { }
+#ifdef CONFIG_MMU
+#define nommu_start_thread(regs) do { } while (0)
+#else
+#define nommu_start_thread(regs) regs->ARM_r10 = current->mm->start_data
+#endif
+
#define start_thread(regs,pc,sp) \
({ \
unsigned long *stack = (unsigned long *)sp; \
@@ -65,6 +71,7 @@
regs->ARM_r2 = stack[2]; /* r2 (envp) */ \
regs->ARM_r1 = stack[1]; /* r1 (argv) */ \
regs->ARM_r0 = stack[0]; /* r0 (argc) */ \
+ nommu_start_thread(regs); \
})
/* Forward declaration, a strange C thing */
diff --git a/include/asm-arm/ptrace.h b/include/asm-arm/ptrace.h
index 4377e22..77adb7f 100644
--- a/include/asm-arm/ptrace.h
+++ b/include/asm-arm/ptrace.h
@@ -23,6 +23,9 @@
#define PTRACE_OLDSETOPTIONS 21
#define PTRACE_GET_THREAD_AREA 22
+
+#define PTRACE_SET_SYSCALL 23
+
/*
* PSR bits
*/
@@ -60,9 +63,11 @@
#ifndef __ASSEMBLY__
-/* this struct defines the way the registers are stored on the
- stack during a system call. */
-
+/*
+ * This struct defines the way the registers are stored on the
+ * stack during a system call. Note that sizeof(struct pt_regs)
+ * has to be a multiple of 8.
+ */
struct pt_regs {
long uregs[18];
};
diff --git a/include/asm-arm/stat.h b/include/asm-arm/stat.h
index ec4e2c2..42c0c13 100644
--- a/include/asm-arm/stat.h
+++ b/include/asm-arm/stat.h
@@ -70,14 +70,7 @@
long long st_size;
unsigned long st_blksize;
-
-#if defined(__ARMEB__)
- unsigned long __pad4; /* Future possible st_blocks hi bits */
- unsigned long st_blocks; /* Number 512-byte blocks allocated. */
-#else /* Must be little */
- unsigned long st_blocks; /* Number 512-byte blocks allocated. */
- unsigned long __pad4; /* Future possible st_blocks hi bits */
-#endif
+ unsigned long long st_blocks; /* Number 512-byte blocks allocated. */
unsigned long st_atime;
unsigned long st_atime_nsec;
@@ -89,6 +82,6 @@
unsigned long st_ctime_nsec;
unsigned long long st_ino;
-} __attribute__((packed));
+};
#endif
diff --git a/include/asm-arm/statfs.h b/include/asm-arm/statfs.h
index e81f827..a02e6a8 100644
--- a/include/asm-arm/statfs.h
+++ b/include/asm-arm/statfs.h
@@ -1,6 +1,42 @@
#ifndef _ASMARM_STATFS_H
#define _ASMARM_STATFS_H
-#include <asm-generic/statfs.h>
+#ifndef __KERNEL_STRICT_NAMES
+# include <linux/types.h>
+typedef __kernel_fsid_t fsid_t;
+#endif
+
+struct statfs {
+ __u32 f_type;
+ __u32 f_bsize;
+ __u32 f_blocks;
+ __u32 f_bfree;
+ __u32 f_bavail;
+ __u32 f_files;
+ __u32 f_ffree;
+ __kernel_fsid_t f_fsid;
+ __u32 f_namelen;
+ __u32 f_frsize;
+ __u32 f_spare[5];
+};
+
+/*
+ * With EABI there is 4 bytes of padding added to this structure.
+ * Let's pack it so the padding goes away to simplify dual ABI support.
+ * Note that user space does NOT have to pack this structure.
+ */
+struct statfs64 {
+ __u32 f_type;
+ __u32 f_bsize;
+ __u64 f_blocks;
+ __u64 f_bfree;
+ __u64 f_bavail;
+ __u64 f_files;
+ __u64 f_ffree;
+ __kernel_fsid_t f_fsid;
+ __u32 f_namelen;
+ __u32 f_frsize;
+ __u32 f_spare[5];
+} __attribute__ ((packed,aligned(4)));
#endif
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
index d626e70..77430d6 100644
--- a/include/asm-arm/unistd.h
+++ b/include/asm-arm/unistd.h
@@ -15,10 +15,12 @@
#include <linux/linkage.h>
-#if defined(__thumb__)
+#define __NR_OABI_SYSCALL_BASE 0x900000
+
+#if defined(__thumb__) || defined(__ARM_EABI__)
#define __NR_SYSCALL_BASE 0
#else
-#define __NR_SYSCALL_BASE 0x900000
+#define __NR_SYSCALL_BASE __NR_OABI_SYSCALL_BASE
#endif
/*
@@ -373,13 +375,13 @@
#define __sys1(x) __sys2(x)
#ifndef __syscall
-#if defined(__thumb__)
-#define __syscall(name) \
- "push {r7}\n\t" \
- "mov r7, #" __sys1(__NR_##name) "\n\t" \
- "swi 0\n\t" \
- "pop {r7}"
+#if defined(__thumb__) || defined(__ARM_EABI__)
+#define __SYS_REG(name) register long __sysreg __asm__("r7") = __NR_##name;
+#define __SYS_REG_LIST(regs...) "r" (__sysreg) , ##regs
+#define __syscall(name) "swi\t0"
#else
+#define __SYS_REG(name)
+#define __SYS_REG_LIST(regs...) regs
#define __syscall(name) "swi\t" __sys1(__NR_##name) ""
#endif
#endif
@@ -395,33 +397,34 @@
#define _syscall0(type,name) \
type name(void) { \
+ __SYS_REG(name) \
register long __res_r0 __asm__("r0"); \
long __res; \
__asm__ __volatile__ ( \
__syscall(name) \
: "=r" (__res_r0) \
- : \
- : "lr"); \
+ : __SYS_REG_LIST() ); \
__res = __res_r0; \
__syscall_return(type,__res); \
}
#define _syscall1(type,name,type1,arg1) \
type name(type1 arg1) { \
+ __SYS_REG(name) \
register long __r0 __asm__("r0") = (long)arg1; \
register long __res_r0 __asm__("r0"); \
long __res; \
__asm__ __volatile__ ( \
__syscall(name) \
: "=r" (__res_r0) \
- : "r" (__r0) \
- : "lr"); \
+ : __SYS_REG_LIST( "0" (__r0) ) ); \
__res = __res_r0; \
__syscall_return(type,__res); \
}
#define _syscall2(type,name,type1,arg1,type2,arg2) \
type name(type1 arg1,type2 arg2) { \
+ __SYS_REG(name) \
register long __r0 __asm__("r0") = (long)arg1; \
register long __r1 __asm__("r1") = (long)arg2; \
register long __res_r0 __asm__("r0"); \
@@ -429,8 +432,7 @@
__asm__ __volatile__ ( \
__syscall(name) \
: "=r" (__res_r0) \
- : "r" (__r0),"r" (__r1) \
- : "lr"); \
+ : __SYS_REG_LIST( "0" (__r0), "r" (__r1) ) ); \
__res = __res_r0; \
__syscall_return(type,__res); \
}
@@ -438,6 +440,7 @@
#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
type name(type1 arg1,type2 arg2,type3 arg3) { \
+ __SYS_REG(name) \
register long __r0 __asm__("r0") = (long)arg1; \
register long __r1 __asm__("r1") = (long)arg2; \
register long __r2 __asm__("r2") = (long)arg3; \
@@ -446,8 +449,7 @@
__asm__ __volatile__ ( \
__syscall(name) \
: "=r" (__res_r0) \
- : "r" (__r0),"r" (__r1),"r" (__r2) \
- : "lr"); \
+ : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2) ) ); \
__res = __res_r0; \
__syscall_return(type,__res); \
}
@@ -455,6 +457,7 @@
#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)\
type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
+ __SYS_REG(name) \
register long __r0 __asm__("r0") = (long)arg1; \
register long __r1 __asm__("r1") = (long)arg2; \
register long __r2 __asm__("r2") = (long)arg3; \
@@ -464,8 +467,7 @@
__asm__ __volatile__ ( \
__syscall(name) \
: "=r" (__res_r0) \
- : "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3) \
- : "lr"); \
+ : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) ) ); \
__res = __res_r0; \
__syscall_return(type,__res); \
}
@@ -473,6 +475,7 @@
#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \
+ __SYS_REG(name) \
register long __r0 __asm__("r0") = (long)arg1; \
register long __r1 __asm__("r1") = (long)arg2; \
register long __r2 __asm__("r2") = (long)arg3; \
@@ -483,14 +486,15 @@
__asm__ __volatile__ ( \
__syscall(name) \
: "=r" (__res_r0) \
- : "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3),"r" (__r4) \
- : "lr"); \
+ : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), \
+ "r" (__r3), "r" (__r4) ) ); \
__res = __res_r0; \
__syscall_return(type,__res); \
}
#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) { \
+ __SYS_REG(name) \
register long __r0 __asm__("r0") = (long)arg1; \
register long __r1 __asm__("r1") = (long)arg2; \
register long __r2 __asm__("r2") = (long)arg3; \
@@ -502,30 +506,33 @@
__asm__ __volatile__ ( \
__syscall(name) \
: "=r" (__res_r0) \
- : "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3), "r" (__r4),"r" (__r5) \
- : "lr"); \
+ : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), \
+ "r" (__r3), "r" (__r4), "r" (__r5) ) ); \
__res = __res_r0; \
__syscall_return(type,__res); \
}
#ifdef __KERNEL__
#define __ARCH_WANT_IPC_PARSE_VERSION
-#define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_STAT64
-#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
#define __ARCH_WANT_SYS_PAUSE
-#define __ARCH_WANT_SYS_TIME
-#define __ARCH_WANT_SYS_UTIME
-#define __ARCH_WANT_SYS_SOCKETCALL
#define __ARCH_WANT_SYS_GETPGRP
#define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_SYS_NICE
-#define __ARCH_WANT_SYS_OLD_GETRLIMIT
-#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
+
+#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_OLDUMOUNT
+#define __ARCH_WANT_SYS_ALARM
+#define __ARCH_WANT_SYS_UTIME
+#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_OLD_READDIR
+#define __ARCH_WANT_SYS_SOCKETCALL
+#endif
#endif
#ifdef __KERNEL_SYSCALLS__
diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h
index 0fada8f..42a95d9 100644
--- a/include/asm-generic/atomic.h
+++ b/include/asm-generic/atomic.h
@@ -35,7 +35,7 @@
{
atomic64_t *v = (atomic64_t *)l;
- atomic_set(v, i);
+ atomic64_set(v, i);
}
static inline void atomic_long_inc(atomic_long_t *l)
diff --git a/include/asm-i386/bitops.h b/include/asm-i386/bitops.h
index fe0819f..88e6ca24 100644
--- a/include/asm-i386/bitops.h
+++ b/include/asm-i386/bitops.h
@@ -247,7 +247,7 @@
static int test_bit(int nr, const volatile void * addr);
#endif
-static inline int constant_test_bit(int nr, const volatile unsigned long *addr)
+static __always_inline int constant_test_bit(int nr, const volatile unsigned long *addr)
{
return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0;
}
diff --git a/include/asm-i386/current.h b/include/asm-i386/current.h
index d973289..3cbbecd 100644
--- a/include/asm-i386/current.h
+++ b/include/asm-i386/current.h
@@ -5,7 +5,7 @@
struct task_struct;
-static inline struct task_struct * get_current(void)
+static __always_inline struct task_struct * get_current(void)
{
return current_thread_info()->task;
}
diff --git a/include/asm-i386/string.h b/include/asm-i386/string.h
index 02c8f5d..bb5f88a 100644
--- a/include/asm-i386/string.h
+++ b/include/asm-i386/string.h
@@ -201,7 +201,7 @@
return __res;
}
-static inline void * __memcpy(void * to, const void * from, size_t n)
+static __always_inline void * __memcpy(void * to, const void * from, size_t n)
{
int d0, d1, d2;
__asm__ __volatile__(
@@ -223,7 +223,7 @@
* This looks ugly, but the compiler can optimize it totally,
* as the count is constant.
*/
-static inline void * __constant_memcpy(void * to, const void * from, size_t n)
+static __always_inline void * __constant_memcpy(void * to, const void * from, size_t n)
{
long esi, edi;
if (!n) return to;
@@ -367,7 +367,7 @@
* things 32 bits at a time even when we don't know the size of the
* area at compile-time..
*/
-static inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
+static __always_inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
{
int d0, d1;
__asm__ __volatile__(
@@ -416,7 +416,7 @@
* This looks horribly ugly, but the compiler can optimize it totally,
* as we by now know that both pattern and count is constant..
*/
-static inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
+static __always_inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
{
switch (count) {
case 0:
diff --git a/include/asm-i386/uaccess.h b/include/asm-i386/uaccess.h
index 89ab7e2..3f1337c 100644
--- a/include/asm-i386/uaccess.h
+++ b/include/asm-i386/uaccess.h
@@ -411,7 +411,7 @@
* Returns number of bytes that could not be copied.
* On success, this will be zero.
*/
-static inline unsigned long __must_check
+static __always_inline unsigned long __must_check
__copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
{
if (__builtin_constant_p(n)) {
@@ -432,7 +432,7 @@
return __copy_to_user_ll(to, from, n);
}
-static inline unsigned long __must_check
+static __always_inline unsigned long __must_check
__copy_to_user(void __user *to, const void *from, unsigned long n)
{
might_sleep();
@@ -456,7 +456,7 @@
* If some data could not be copied, this function will pad the copied
* data to the requested size using zero bytes.
*/
-static inline unsigned long
+static __always_inline unsigned long
__copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
{
if (__builtin_constant_p(n)) {
@@ -477,7 +477,7 @@
return __copy_from_user_ll(to, from, n);
}
-static inline unsigned long
+static __always_inline unsigned long
__copy_from_user(void *to, const void __user *from, unsigned long n)
{
might_sleep();
diff --git a/include/asm-ia64/sn/ioc3.h b/include/asm-ia64/sn/ioc3.h
new file mode 100644
index 0000000..95ed6cc
--- /dev/null
+++ b/include/asm-ia64/sn/ioc3.h
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2005 Silicon Graphics, Inc.
+ */
+#ifndef IA64_SN_IOC3_H
+#define IA64_SN_IOC3_H
+
+/* serial port register map */
+struct ioc3_serialregs {
+ uint32_t sscr;
+ uint32_t stpir;
+ uint32_t stcir;
+ uint32_t srpir;
+ uint32_t srcir;
+ uint32_t srtr;
+ uint32_t shadow;
+};
+
+/* SUPERIO uart register map */
+struct ioc3_uartregs {
+ char iu_lcr;
+ union {
+ char iir; /* read only */
+ char fcr; /* write only */
+ } u3;
+ union {
+ char ier; /* DLAB == 0 */
+ char dlm; /* DLAB == 1 */
+ } u2;
+ union {
+ char rbr; /* read only, DLAB == 0 */
+ char thr; /* write only, DLAB == 0 */
+ char dll; /* DLAB == 1 */
+ } u1;
+ char iu_scr;
+ char iu_msr;
+ char iu_lsr;
+ char iu_mcr;
+};
+
+#define iu_rbr u1.rbr
+#define iu_thr u1.thr
+#define iu_dll u1.dll
+#define iu_ier u2.ier
+#define iu_dlm u2.dlm
+#define iu_iir u3.iir
+#define iu_fcr u3.fcr
+
+struct ioc3_sioregs {
+ char fill[0x170];
+ struct ioc3_uartregs uartb;
+ struct ioc3_uartregs uarta;
+};
+
+/* PCI IO/mem space register map */
+struct ioc3 {
+ uint32_t pci_id;
+ uint32_t pci_scr;
+ uint32_t pci_rev;
+ uint32_t pci_lat;
+ uint32_t pci_addr;
+ uint32_t pci_err_addr_l;
+ uint32_t pci_err_addr_h;
+
+ uint32_t sio_ir;
+ /* these registers are read-only for general kernel code. To
+ * modify them use the functions in ioc3.c
+ */
+ uint32_t sio_ies;
+ uint32_t sio_iec;
+ uint32_t sio_cr;
+ uint32_t int_out;
+ uint32_t mcr;
+ uint32_t gpcr_s;
+ uint32_t gpcr_c;
+ uint32_t gpdr;
+ uint32_t gppr[9];
+ char fill[0x4c];
+
+ /* serial port registers */
+ uint32_t sbbr_h;
+ uint32_t sbbr_l;
+
+ struct ioc3_serialregs port_a;
+ struct ioc3_serialregs port_b;
+ char fill1[0x1ff10];
+ /* superio registers */
+ struct ioc3_sioregs sregs;
+};
+
+/* These don't exist on the ioc3 serial card... */
+#define eier fill1[8]
+#define eisr fill1[4]
+
+#define PCI_LAT 0xc /* Latency Timer */
+#define PCI_SCR_DROP_MODE_EN 0x00008000 /* drop pios on parity err */
+#define UARTA_BASE 0x178
+#define UARTB_BASE 0x170
+
+
+/* bitmasks for serial RX status byte */
+#define RXSB_OVERRUN 0x01 /* char(s) lost */
+#define RXSB_PAR_ERR 0x02 /* parity error */
+#define RXSB_FRAME_ERR 0x04 /* framing error */
+#define RXSB_BREAK 0x08 /* break character */
+#define RXSB_CTS 0x10 /* state of CTS */
+#define RXSB_DCD 0x20 /* state of DCD */
+#define RXSB_MODEM_VALID 0x40 /* DCD, CTS and OVERRUN are valid */
+#define RXSB_DATA_VALID 0x80 /* FRAME_ERR PAR_ERR & BREAK valid */
+
+/* bitmasks for serial TX control byte */
+#define TXCB_INT_WHEN_DONE 0x20 /* interrupt after this byte is sent */
+#define TXCB_INVALID 0x00 /* byte is invalid */
+#define TXCB_VALID 0x40 /* byte is valid */
+#define TXCB_MCR 0x80 /* data<7:0> to modem cntrl register */
+#define TXCB_DELAY 0xc0 /* delay data<7:0> mSec */
+
+/* bitmasks for SBBR_L */
+#define SBBR_L_SIZE 0x00000001 /* 0 1KB rings, 1 4KB rings */
+
+/* bitmasks for SSCR_<A:B> */
+#define SSCR_RX_THRESHOLD 0x000001ff /* hiwater mark */
+#define SSCR_TX_TIMER_BUSY 0x00010000 /* TX timer in progress */
+#define SSCR_HFC_EN 0x00020000 /* h/w flow cntrl enabled */
+#define SSCR_RX_RING_DCD 0x00040000 /* postRX record on delta-DCD */
+#define SSCR_RX_RING_CTS 0x00080000 /* postRX record on delta-CTS */
+#define SSCR_HIGH_SPD 0x00100000 /* 4X speed */
+#define SSCR_DIAG 0x00200000 /* bypass clock divider */
+#define SSCR_RX_DRAIN 0x08000000 /* drain RX buffer to memory */
+#define SSCR_DMA_EN 0x10000000 /* enable ring buffer DMA */
+#define SSCR_DMA_PAUSE 0x20000000 /* pause DMA */
+#define SSCR_PAUSE_STATE 0x40000000 /* set when PAUSE takes effect*/
+#define SSCR_RESET 0x80000000 /* reset DMA channels */
+
+/* all producer/comsumer pointers are the same bitfield */
+#define PROD_CONS_PTR_4K 0x00000ff8 /* for 4K buffers */
+#define PROD_CONS_PTR_1K 0x000003f8 /* for 1K buffers */
+#define PROD_CONS_PTR_OFF 3
+
+/* bitmasks for SRCIR_<A:B> */
+#define SRCIR_ARM 0x80000000 /* arm RX timer */
+
+/* bitmasks for SHADOW_<A:B> */
+#define SHADOW_DR 0x00000001 /* data ready */
+#define SHADOW_OE 0x00000002 /* overrun error */
+#define SHADOW_PE 0x00000004 /* parity error */
+#define SHADOW_FE 0x00000008 /* framing error */
+#define SHADOW_BI 0x00000010 /* break interrupt */
+#define SHADOW_THRE 0x00000020 /* transmit holding reg empty */
+#define SHADOW_TEMT 0x00000040 /* transmit shift reg empty */
+#define SHADOW_RFCE 0x00000080 /* char in RX fifo has error */
+#define SHADOW_DCTS 0x00010000 /* delta clear to send */
+#define SHADOW_DDCD 0x00080000 /* delta data carrier detect */
+#define SHADOW_CTS 0x00100000 /* clear to send */
+#define SHADOW_DCD 0x00800000 /* data carrier detect */
+#define SHADOW_DTR 0x01000000 /* data terminal ready */
+#define SHADOW_RTS 0x02000000 /* request to send */
+#define SHADOW_OUT1 0x04000000 /* 16550 OUT1 bit */
+#define SHADOW_OUT2 0x08000000 /* 16550 OUT2 bit */
+#define SHADOW_LOOP 0x10000000 /* loopback enabled */
+
+/* bitmasks for SRTR_<A:B> */
+#define SRTR_CNT 0x00000fff /* reload value for RX timer */
+#define SRTR_CNT_VAL 0x0fff0000 /* current value of RX timer */
+#define SRTR_CNT_VAL_SHIFT 16
+#define SRTR_HZ 16000 /* SRTR clock frequency */
+
+/* bitmasks for SIO_IR, SIO_IEC and SIO_IES */
+#define SIO_IR_SA_TX_MT 0x00000001 /* Serial port A TX empty */
+#define SIO_IR_SA_RX_FULL 0x00000002 /* port A RX buf full */
+#define SIO_IR_SA_RX_HIGH 0x00000004 /* port A RX hiwat */
+#define SIO_IR_SA_RX_TIMER 0x00000008 /* port A RX timeout */
+#define SIO_IR_SA_DELTA_DCD 0x00000010 /* port A delta DCD */
+#define SIO_IR_SA_DELTA_CTS 0x00000020 /* port A delta CTS */
+#define SIO_IR_SA_INT 0x00000040 /* port A pass-thru intr */
+#define SIO_IR_SA_TX_EXPLICIT 0x00000080 /* port A explicit TX thru */
+#define SIO_IR_SA_MEMERR 0x00000100 /* port A PCI error */
+#define SIO_IR_SB_TX_MT 0x00000200
+#define SIO_IR_SB_RX_FULL 0x00000400
+#define SIO_IR_SB_RX_HIGH 0x00000800
+#define SIO_IR_SB_RX_TIMER 0x00001000
+#define SIO_IR_SB_DELTA_DCD 0x00002000
+#define SIO_IR_SB_DELTA_CTS 0x00004000
+#define SIO_IR_SB_INT 0x00008000
+#define SIO_IR_SB_TX_EXPLICIT 0x00010000
+#define SIO_IR_SB_MEMERR 0x00020000
+#define SIO_IR_PP_INT 0x00040000 /* P port pass-thru intr */
+#define SIO_IR_PP_INTA 0x00080000 /* PP context A thru */
+#define SIO_IR_PP_INTB 0x00100000 /* PP context B thru */
+#define SIO_IR_PP_MEMERR 0x00200000 /* PP PCI error */
+#define SIO_IR_KBD_INT 0x00400000 /* kbd/mouse intr */
+#define SIO_IR_RT_INT 0x08000000 /* RT output pulse */
+#define SIO_IR_GEN_INT1 0x10000000 /* RT input pulse */
+#define SIO_IR_GEN_INT_SHIFT 28
+
+/* per device interrupt masks */
+#define SIO_IR_SA (SIO_IR_SA_TX_MT | \
+ SIO_IR_SA_RX_FULL | \
+ SIO_IR_SA_RX_HIGH | \
+ SIO_IR_SA_RX_TIMER | \
+ SIO_IR_SA_DELTA_DCD | \
+ SIO_IR_SA_DELTA_CTS | \
+ SIO_IR_SA_INT | \
+ SIO_IR_SA_TX_EXPLICIT | \
+ SIO_IR_SA_MEMERR)
+
+#define SIO_IR_SB (SIO_IR_SB_TX_MT | \
+ SIO_IR_SB_RX_FULL | \
+ SIO_IR_SB_RX_HIGH | \
+ SIO_IR_SB_RX_TIMER | \
+ SIO_IR_SB_DELTA_DCD | \
+ SIO_IR_SB_DELTA_CTS | \
+ SIO_IR_SB_INT | \
+ SIO_IR_SB_TX_EXPLICIT | \
+ SIO_IR_SB_MEMERR)
+
+#define SIO_IR_PP (SIO_IR_PP_INT | SIO_IR_PP_INTA | \
+ SIO_IR_PP_INTB | SIO_IR_PP_MEMERR)
+#define SIO_IR_RT (SIO_IR_RT_INT | SIO_IR_GEN_INT1)
+
+/* bitmasks for SIO_CR */
+#define SIO_CR_CMD_PULSE_SHIFT 15
+#define SIO_CR_SER_A_BASE_SHIFT 1
+#define SIO_CR_SER_B_BASE_SHIFT 8
+#define SIO_CR_ARB_DIAG 0x00380000 /* cur !enet PCI requet (ro) */
+#define SIO_CR_ARB_DIAG_TXA 0x00000000
+#define SIO_CR_ARB_DIAG_RXA 0x00080000
+#define SIO_CR_ARB_DIAG_TXB 0x00100000
+#define SIO_CR_ARB_DIAG_RXB 0x00180000
+#define SIO_CR_ARB_DIAG_PP 0x00200000
+#define SIO_CR_ARB_DIAG_IDLE 0x00400000 /* 0 -> active request (ro) */
+
+/* defs for some of the generic I/O pins */
+#define GPCR_PHY_RESET 0x20 /* pin is output to PHY reset */
+#define GPCR_UARTB_MODESEL 0x40 /* pin is output to port B mode sel */
+#define GPCR_UARTA_MODESEL 0x80 /* pin is output to port A mode sel */
+
+#define GPPR_PHY_RESET_PIN 5 /* GIO pin controlling phy reset */
+#define GPPR_UARTB_MODESEL_PIN 6 /* GIO pin cntrling uartb modeselect */
+#define GPPR_UARTA_MODESEL_PIN 7 /* GIO pin cntrling uarta modeselect */
+
+#endif /* IA64_SN_IOC3_H */
diff --git a/include/asm-powerpc/kexec.h b/include/asm-powerpc/kexec.h
index fffdf69..640a645 100644
--- a/include/asm-powerpc/kexec.h
+++ b/include/asm-powerpc/kexec.h
@@ -31,12 +31,80 @@
#define KEXEC_ARCH KEXEC_ARCH_PPC
#endif
-#define HAVE_ARCH_COPY_OLDMEM_PAGE
-
-#ifndef __ASSEMBLY__
-
#ifdef CONFIG_KEXEC
+#ifdef __powerpc64__
+/*
+ * This function is responsible for capturing register states if coming
+ * via panic or invoking dump using sysrq-trigger.
+ */
+static inline void crash_setup_regs(struct pt_regs *newregs,
+ struct pt_regs *oldregs)
+{
+ if (oldregs)
+ memcpy(newregs, oldregs, sizeof(*newregs));
+ else {
+ /* FIXME Merge this with xmon_save_regs ?? */
+ unsigned long tmp1, tmp2;
+ __asm__ __volatile__ (
+ "std 0,0(%2)\n"
+ "std 1,8(%2)\n"
+ "std 2,16(%2)\n"
+ "std 3,24(%2)\n"
+ "std 4,32(%2)\n"
+ "std 5,40(%2)\n"
+ "std 6,48(%2)\n"
+ "std 7,56(%2)\n"
+ "std 8,64(%2)\n"
+ "std 9,72(%2)\n"
+ "std 10,80(%2)\n"
+ "std 11,88(%2)\n"
+ "std 12,96(%2)\n"
+ "std 13,104(%2)\n"
+ "std 14,112(%2)\n"
+ "std 15,120(%2)\n"
+ "std 16,128(%2)\n"
+ "std 17,136(%2)\n"
+ "std 18,144(%2)\n"
+ "std 19,152(%2)\n"
+ "std 20,160(%2)\n"
+ "std 21,168(%2)\n"
+ "std 22,176(%2)\n"
+ "std 23,184(%2)\n"
+ "std 24,192(%2)\n"
+ "std 25,200(%2)\n"
+ "std 26,208(%2)\n"
+ "std 27,216(%2)\n"
+ "std 28,224(%2)\n"
+ "std 29,232(%2)\n"
+ "std 30,240(%2)\n"
+ "std 31,248(%2)\n"
+ "mfmsr %0\n"
+ "std %0, 264(%2)\n"
+ "mfctr %0\n"
+ "std %0, 280(%2)\n"
+ "mflr %0\n"
+ "std %0, 288(%2)\n"
+ "bl 1f\n"
+ "1: mflr %1\n"
+ "std %1, 256(%2)\n"
+ "mtlr %0\n"
+ "mfxer %0\n"
+ "std %0, 296(%2)\n"
+ : "=&r" (tmp1), "=&r" (tmp2)
+ : "b" (newregs));
+ }
+}
+#else
+/*
+ * Provide a dummy definition to avoid build failures. Will remain
+ * empty till crash dump support is enabled.
+ */
+static inline void crash_setup_regs(struct pt_regs *newregs,
+ struct pt_regs *oldregs) { }
+#endif /* !__powerpc64 __ */
+
+#ifndef __ASSEMBLY__
#define MAX_NOTE_BYTES 1024
#ifdef __powerpc64__
@@ -53,14 +121,7 @@
extern int default_machine_kexec_prepare(struct kimage *image);
extern void default_machine_crash_shutdown(struct pt_regs *regs);
-#endif /* !CONFIG_KEXEC */
-
-/*
- * Provide a dummy definition to avoid build failures. Will remain
- * empty till crash dump support is enabled.
- */
-static inline void crash_setup_regs(struct pt_regs *newregs,
- struct pt_regs *oldregs) { }
#endif /* ! __ASSEMBLY__ */
+#endif /* CONFIG_KEXEC */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_KEXEC_H */
diff --git a/include/asm-ppc/prom.h b/include/asm-ppc/prom.h
index eb317a0..6d431d6 100644
--- a/include/asm-ppc/prom.h
+++ b/include/asm-ppc/prom.h
@@ -167,6 +167,14 @@
extern int of_pci_address_to_resource(struct device_node *dev, int bar,
struct resource *r);
+#ifndef CONFIG_PPC_OF
+/*
+ * Fallback definitions for builds where we don't have prom.c included.
+ */
+#define machine_is_compatible(x) 0
+#define of_find_compatible_node(f, t, c) NULL
+#define get_property(p, n, l) NULL
+#endif
#endif /* _PPC_PROM_H */
#endif /* __KERNEL__ */
diff --git a/include/asm-s390/s390_rdev.h b/include/asm-s390/s390_rdev.h
index 3ad78f2..6fa2044 100644
--- a/include/asm-s390/s390_rdev.h
+++ b/include/asm-s390/s390_rdev.h
@@ -2,7 +2,7 @@
* include/asm-s390/ccwdev.h
*
* Copyright (C) 2002,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Cornelia Huck <cohuck@de.ibm.com>
+ * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
* Carsten Otte <cotte@de.ibm.com>
*
* Interface for s390 root device
diff --git a/include/asm-s390/sigcontext.h b/include/asm-s390/sigcontext.h
index 8035453..aeb6e0b 100644
--- a/include/asm-s390/sigcontext.h
+++ b/include/asm-s390/sigcontext.h
@@ -8,6 +8,8 @@
#ifndef _ASM_S390_SIGCONTEXT_H
#define _ASM_S390_SIGCONTEXT_H
+#include <linux/compiler.h>
+
#define __NUM_GPRS 16
#define __NUM_FPRS 16
#define __NUM_ACRS 16
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h
index c7c3a9a..b2e65e8 100644
--- a/include/asm-s390/system.h
+++ b/include/asm-s390/system.h
@@ -115,13 +115,14 @@
}
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
-extern void account_user_vtime(struct task_struct *);
+extern void account_vtime(struct task_struct *);
+extern void account_tick_vtime(struct task_struct *);
extern void account_system_vtime(struct task_struct *);
#endif
#define finish_arch_switch(prev) do { \
set_fs(current->thread.mm_segment); \
- account_system_vtime(prev); \
+ account_vtime(prev); \
} while (0)
#define nop() __asm__ __volatile__ ("nop")
diff --git a/include/asm-x86_64/fixmap.h b/include/asm-x86_64/fixmap.h
index a582cfc..7b286bd 100644
--- a/include/asm-x86_64/fixmap.h
+++ b/include/asm-x86_64/fixmap.h
@@ -76,7 +76,7 @@
* directly without translation, we catch the bug with a NULL-deference
* kernel oops. Illegal ranges of incoming indices are caught too.
*/
-static inline unsigned long fix_to_virt(const unsigned int idx)
+static __always_inline unsigned long fix_to_virt(const unsigned int idx)
{
/*
* this branch gets completely eliminated after inlining,
diff --git a/include/asm-x86_64/uaccess.h b/include/asm-x86_64/uaccess.h
index 2892c4b..bddffcb 100644
--- a/include/asm-x86_64/uaccess.h
+++ b/include/asm-x86_64/uaccess.h
@@ -244,7 +244,7 @@
extern unsigned long copy_from_user(void *to, const void __user *from, unsigned len);
extern unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len);
-static inline int __copy_from_user(void *dst, const void __user *src, unsigned size)
+static __always_inline int __copy_from_user(void *dst, const void __user *src, unsigned size)
{
int ret = 0;
if (!__builtin_constant_p(size))
@@ -273,7 +273,7 @@
}
}
-static inline int __copy_to_user(void __user *dst, const void *src, unsigned size)
+static __always_inline int __copy_to_user(void __user *dst, const void *src, unsigned size)
{
int ret = 0;
if (!__builtin_constant_p(size))
@@ -305,7 +305,7 @@
}
-static inline int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
+static __always_inline int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
{
int ret = 0;
if (!__builtin_constant_p(size))
diff --git a/include/linux/compiler-gcc3.h b/include/linux/compiler-gcc3.h
index 4209082..1698b84 100644
--- a/include/linux/compiler-gcc3.h
+++ b/include/linux/compiler-gcc3.h
@@ -13,3 +13,4 @@
#define __must_check __attribute__((warn_unused_result))
#endif
+#define __always_inline inline __attribute__((always_inline))
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
index e913e9b..6f5cc6f 100644
--- a/include/linux/compiler-gcc4.h
+++ b/include/linux/compiler-gcc4.h
@@ -3,7 +3,16 @@
/* These definitions are for GCC v4.x. */
#include <linux/compiler-gcc.h>
+#ifdef CONFIG_FORCED_INLINING
+# undef inline
+# undef __inline__
+# undef __inline
+# define inline inline __attribute__((always_inline))
+# define __inline__ __inline__ __attribute__((always_inline))
+# define __inline __inline __attribute__((always_inline))
+#endif
+
#define __attribute_used__ __attribute__((__used__))
#define __must_check __attribute__((warn_unused_result))
#define __compiler_offsetof(a,b) __builtin_offsetof(a,b)
-
+#define __always_inline inline __attribute__((always_inline))
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index c472f97..3bc6069 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -48,6 +48,9 @@
extern struct file_operations proc_cpuset_operations;
extern char *cpuset_task_status_allowed(struct task_struct *task, char *buffer);
+extern void cpuset_lock(void);
+extern void cpuset_unlock(void);
+
#else /* !CONFIG_CPUSETS */
static inline int cpuset_init_early(void) { return 0; }
@@ -93,6 +96,9 @@
return buffer;
}
+static inline void cpuset_lock(void) {}
+static inline void cpuset_unlock(void) {}
+
#endif /* !CONFIG_CPUSETS */
#endif /* _LINUX_CPUSET_H */
diff --git a/include/linux/fb.h b/include/linux/fb.h
index a973be2..2cb19e6 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -608,15 +608,15 @@
int (*fb_sync)(struct fb_info *info);
/* perform fb specific ioctl (optional) */
- int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg, struct fb_info *info);
+ int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
+ unsigned long arg);
/* Handle 32bit compat ioctl (optional) */
- long (*fb_compat_ioctl)(struct file *f, unsigned cmd, unsigned long arg,
- struct fb_info *info);
+ int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
+ unsigned long arg);
/* perform fb specific mmap */
- int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
+ int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
/* save current hardware state */
void (*fb_save_state)(struct fb_info *info);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index d1e370d..552cedf 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1383,6 +1383,12 @@
extern int unregister_chrdev(unsigned int, const char *);
extern void unregister_chrdev_region(dev_t, unsigned);
extern int chrdev_open(struct inode *, struct file *);
+extern int get_chrdev_list(char *);
+extern void *acquire_chrdev_list(void);
+extern int count_chrdev_list(void);
+extern void *get_next_chrdev(void *);
+extern int get_chrdev_info(void *, int *, char **);
+extern void release_chrdev_list(void *);
/* fs/block_dev.c */
#define BDEVNAME_SIZE 32 /* Largest string for a blockdev identifier */
@@ -1391,6 +1397,11 @@
extern struct block_device *lookup_bdev(const char *);
extern struct block_device *open_bdev_excl(const char *, int, void *);
extern void close_bdev_excl(struct block_device *);
+extern void *acquire_blkdev_list(void);
+extern int count_blkdev_list(void);
+extern void *get_next_blkdev(void *);
+extern int get_blkdev_info(void *, int *, char **);
+extern void release_blkdev_list(void *);
extern void init_special_inode(struct inode *, umode_t, dev_t);
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index 71d2b8a..eab5370 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -93,10 +93,6 @@
struct task_struct;
#ifndef CONFIG_VIRT_CPU_ACCOUNTING
-static inline void account_user_vtime(struct task_struct *tsk)
-{
-}
-
static inline void account_system_vtime(struct task_struct *tsk)
{
}
diff --git a/include/linux/ioc3.h b/include/linux/ioc3.h
new file mode 100644
index 0000000..e7906a7
--- /dev/null
+++ b/include/linux/ioc3.h
@@ -0,0 +1,93 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2005 Stanislaw Skowronek <skylark@linux-mips.org>
+ */
+
+#ifndef _LINUX_IOC3_H
+#define _LINUX_IOC3_H
+
+#include <asm/sn/ioc3.h>
+
+#define IOC3_MAX_SUBMODULES 32
+
+#define IOC3_CLASS_NONE 0
+#define IOC3_CLASS_BASE_IP27 1
+#define IOC3_CLASS_BASE_IP30 2
+#define IOC3_CLASS_MENET_123 3
+#define IOC3_CLASS_MENET_4 4
+#define IOC3_CLASS_CADDUO 5
+#define IOC3_CLASS_SERIAL 6
+
+/* One of these per IOC3 */
+struct ioc3_driver_data {
+ struct list_head list;
+ int id; /* IOC3 sequence number */
+ /* PCI mapping */
+ unsigned long pma; /* physical address */
+ struct __iomem ioc3 *vma; /* pointer to registers */
+ struct pci_dev *pdev; /* PCI device */
+ /* IRQ stuff */
+ int dual_irq; /* set if separate IRQs are used */
+ int irq_io, irq_eth; /* IRQ numbers */
+ /* GPIO magic */
+ spinlock_t gpio_lock;
+ unsigned int gpdr_shadow;
+ /* NIC identifiers */
+ char nic_part[32];
+ char nic_serial[16];
+ char nic_mac[6];
+ /* submodule set */
+ int class;
+ void *data[IOC3_MAX_SUBMODULES]; /* for submodule use */
+ int active[IOC3_MAX_SUBMODULES]; /* set if probe succeeds */
+ /* is_ir_lock must be held while
+ * modifying sio_ie values, so
+ * we can be sure that sio_ie is
+ * not changing when we read it
+ * along with sio_ir.
+ */
+ spinlock_t ir_lock; /* SIO_IE[SC] mod lock */
+};
+
+/* One per submodule */
+struct ioc3_submodule {
+ char *name; /* descriptive submodule name */
+ struct module *owner; /* owning kernel module */
+ int ethernet; /* set for ethernet drivers */
+ int (*probe) (struct ioc3_submodule *, struct ioc3_driver_data *);
+ int (*remove) (struct ioc3_submodule *, struct ioc3_driver_data *);
+ int id; /* assigned by IOC3, index for the "data" array */
+ /* IRQ stuff */
+ unsigned int irq_mask; /* IOC3 IRQ mask, leave clear for Ethernet */
+ int reset_mask; /* non-zero if you want the ioc3.c module to reset interrupts */
+ int (*intr) (struct ioc3_submodule *, struct ioc3_driver_data *, unsigned int, struct pt_regs *);
+ /* private submodule data */
+ void *data; /* assigned by submodule */
+};
+
+/**********************************
+ * Functions needed by submodules *
+ **********************************/
+
+#define IOC3_W_IES 0
+#define IOC3_W_IEC 1
+
+/* registers a submodule for all existing and future IOC3 chips */
+extern int ioc3_register_submodule(struct ioc3_submodule *);
+/* unregisters a submodule */
+extern void ioc3_unregister_submodule(struct ioc3_submodule *);
+/* enables IRQs indicated by irq_mask for a specified IOC3 chip */
+extern void ioc3_enable(struct ioc3_submodule *, struct ioc3_driver_data *, unsigned int);
+/* ackowledges specified IRQs */
+extern void ioc3_ack(struct ioc3_submodule *, struct ioc3_driver_data *, unsigned int);
+/* disables IRQs indicated by irq_mask for a specified IOC3 chip */
+extern void ioc3_disable(struct ioc3_submodule *, struct ioc3_driver_data *, unsigned int);
+/* atomically sets GPCR bits */
+extern void ioc3_gpcr_set(struct ioc3_driver_data *, unsigned int);
+/* general ireg writer */
+extern void ioc3_write_ireg(struct ioc3_driver_data *idd, uint32_t value, int reg);
+
+#endif
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index c7ac77e..d6a53ed 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -132,12 +132,8 @@
spinlock_t lock;
};
-static inline void mpol_shared_policy_init(struct shared_policy *info)
-{
- info->root = RB_ROOT;
- spin_lock_init(&info->lock);
-}
-
+void mpol_shared_policy_init(struct shared_policy *info, int policy,
+ nodemask_t *nodes);
int mpol_set_shared_policy(struct shared_policy *info,
struct vm_area_struct *vma,
struct mempolicy *new);
@@ -211,7 +207,8 @@
return -EINVAL;
}
-static inline void mpol_shared_policy_init(struct shared_policy *info)
+static inline void mpol_shared_policy_init(struct shared_policy *info,
+ int policy, nodemask_t *nodes)
{
}
diff --git a/include/linux/mm.h b/include/linux/mm.h
index c643016..85854b8 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -512,7 +512,7 @@
extern struct page *mem_map;
#endif
-static inline void *lowmem_page_address(struct page *page)
+static __always_inline void *lowmem_page_address(struct page *page)
{
return __va(page_to_pfn(page) << PAGE_SHIFT);
}
diff --git a/include/linux/ncp_fs.h b/include/linux/ncp_fs.h
index 7297e43..e013425 100644
--- a/include/linux/ncp_fs.h
+++ b/include/linux/ncp_fs.h
@@ -201,34 +201,6 @@
return container_of(inode, struct ncp_inode_info, vfs_inode);
}
-#ifdef DEBUG_NCP_MALLOC
-
-#include <linux/slab.h>
-
-extern int ncp_malloced;
-extern int ncp_current_malloced;
-
-static inline void *
- ncp_kmalloc(unsigned int size, int priority)
-{
- ncp_malloced += 1;
- ncp_current_malloced += 1;
- return kmalloc(size, priority);
-}
-
-static inline void ncp_kfree_s(void *obj, int size)
-{
- ncp_current_malloced -= 1;
- kfree(obj);
-}
-
-#else /* DEBUG_NCP_MALLOC */
-
-#define ncp_kmalloc(s,p) kmalloc(s,p)
-#define ncp_kfree_s(o,s) kfree(o)
-
-#endif /* DEBUG_NCP_MALLOC */
-
/* linux/fs/ncpfs/inode.c */
int ncp_notify_change(struct dentry *, struct iattr *);
struct inode *ncp_iget(struct super_block *, struct ncp_entry_info *);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index a72e171..2df1a1a 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -160,6 +160,7 @@
#define SCHED_NORMAL 0
#define SCHED_FIFO 1
#define SCHED_RR 2
+#define SCHED_BATCH 3
struct sched_param {
int sched_priority;
@@ -470,9 +471,9 @@
/*
* Priority of a process goes from 0..MAX_PRIO-1, valid RT
- * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL tasks are
- * in the range MAX_RT_PRIO..MAX_PRIO-1. Priority values
- * are inverted: lower p->prio value means higher priority.
+ * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
+ * tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority
+ * values are inverted: lower p->prio value means higher priority.
*
* The MAX_USER_RT_PRIO value allows the actual maximum
* RT priority to be separate from the value exported to
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index a8187c3..ec35100 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -136,6 +136,7 @@
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/tty.h>
+#include <linux/mutex.h>
struct uart_port;
struct uart_info;
@@ -284,7 +285,7 @@
struct uart_info *info;
struct uart_port *port;
- struct semaphore sem;
+ struct mutex mutex;
};
#define UART_XMIT_SIZE PAGE_SIZE
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index c3e5982..c057f0b 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -26,6 +26,8 @@
unsigned long free_blocks; /* How many are left for allocation */
unsigned long max_inodes; /* How many inodes are allowed */
unsigned long free_inodes; /* How many are left for allocation */
+ int policy; /* Default NUMA memory alloc policy */
+ nodemask_t policy_nodes; /* nodemask for preferred and bind */
spinlock_t stat_lock;
};
diff --git a/include/linux/smb_fs.h b/include/linux/smb_fs.h
index c415312..621a3d3 100644
--- a/include/linux/smb_fs.h
+++ b/include/linux/smb_fs.h
@@ -58,53 +58,6 @@
/* where to find the base of the SMB packet proper */
#define smb_base(buf) ((u8 *)(((u8 *)(buf))+4))
-#ifdef DEBUG_SMB_MALLOC
-
-#include <linux/slab.h>
-
-extern int smb_malloced;
-extern int smb_current_vmalloced;
-extern int smb_current_kmalloced;
-
-static inline void *
-smb_vmalloc(unsigned int size)
-{
- smb_malloced += 1;
- smb_current_vmalloced += 1;
- return vmalloc(size);
-}
-
-static inline void
-smb_vfree(void *obj)
-{
- smb_current_vmalloced -= 1;
- vfree(obj);
-}
-
-static inline void *
-smb_kmalloc(size_t size, int flags)
-{
- smb_malloced += 1;
- smb_current_kmalloced += 1;
- return kmalloc(size, flags);
-}
-
-static inline void
-smb_kfree(void *obj)
-{
- smb_current_kmalloced -= 1;
- kfree(obj);
-}
-
-#else /* DEBUG_SMB_MALLOC */
-
-#define smb_kmalloc(s,p) kmalloc(s,p)
-#define smb_kfree(o) kfree(o)
-#define smb_vmalloc(s) vmalloc(s)
-#define smb_vfree(o) vfree(o)
-
-#endif /* DEBUG_SMB_MALLOC */
-
/*
* Flags for the in-memory inode
*/
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 389d1c3..e92054d 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -180,6 +180,11 @@
extern int putback_lru_pages(struct list_head *l);
extern int migrate_pages(struct list_head *l, struct list_head *t,
struct list_head *moved, struct list_head *failed);
+#else
+static inline int isolate_lru_page(struct page *p) { return -ENOSYS; }
+static inline int putback_lru_pages(struct list_head *l) { return 0; }
+static inline int migrate_pages(struct list_head *l, struct list_head *t,
+ struct list_head *moved, struct list_head *failed) { return -ENOSYS; }
#endif
#ifdef CONFIG_MMU
diff --git a/init/main.c b/init/main.c
index e092b19..7c79da5 100644
--- a/init/main.c
+++ b/init/main.c
@@ -54,20 +54,18 @@
#include <asm/sections.h>
#include <asm/cacheflush.h>
-/*
- * This is one of the first .c files built. Error out early
- * if we have compiler trouble..
- */
-
#ifdef CONFIG_X86_LOCAL_APIC
#include <asm/smp.h>
#endif
/*
- * Versions of gcc older than that listed below may actually compile
- * and link okay, but the end product can have subtle run time bugs.
- * To avoid associated bogus bug reports, we flatly refuse to compile
- * with a gcc that is known to be too old from the very beginning.
+ * This is one of the first .c files built. Error out early if we have compiler
+ * trouble.
+ *
+ * Versions of gcc older than that listed below may actually compile and link
+ * okay, but the end product can have subtle run time bugs. To avoid associated
+ * bogus bug reports, we flatly refuse to compile with a gcc that is known to be
+ * too old from the very beginning.
*/
#if (__GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 2)
#error Sorry, your GCC is too old. It builds incorrect kernels.
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 2a75e44..fe2f71f 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -1554,7 +1554,7 @@
* when reading out p->cpuset, as we don't really care if it changes
* on the next cycle, and we are not going to try to dereference it.
*/
-static inline int pid_array_load(pid_t *pidarray, int npids, struct cpuset *cs)
+static int pid_array_load(pid_t *pidarray, int npids, struct cpuset *cs)
{
int n = 0;
struct task_struct *g, *p;
@@ -2150,6 +2150,33 @@
}
/**
+ * cpuset_lock - lock out any changes to cpuset structures
+ *
+ * The out of memory (oom) code needs to lock down cpusets
+ * from being changed while it scans the tasklist looking for a
+ * task in an overlapping cpuset. Expose callback_sem via this
+ * cpuset_lock() routine, so the oom code can lock it, before
+ * locking the task list. The tasklist_lock is a spinlock, so
+ * must be taken inside callback_sem.
+ */
+
+void cpuset_lock(void)
+{
+ down(&callback_sem);
+}
+
+/**
+ * cpuset_unlock - release lock on cpuset changes
+ *
+ * Undo the lock taken in a previous cpuset_lock() call.
+ */
+
+void cpuset_unlock(void)
+{
+ up(&callback_sem);
+}
+
+/**
* cpuset_excl_nodes_overlap - Do we overlap @p's mem_exclusive ancestors?
* @p: pointer to task_struct of some other task.
*
@@ -2158,7 +2185,7 @@
* determine if task @p's memory usage might impact the memory
* available to the current task.
*
- * Acquires callback_sem - not suitable for calling from a fast path.
+ * Call while holding callback_sem.
**/
int cpuset_excl_nodes_overlap(const struct task_struct *p)
@@ -2166,8 +2193,6 @@
const struct cpuset *cs1, *cs2; /* my and p's cpuset ancestors */
int overlap = 0; /* do cpusets overlap? */
- down(&callback_sem);
-
task_lock(current);
if (current->flags & PF_EXITING) {
task_unlock(current);
@@ -2186,8 +2211,6 @@
overlap = nodes_intersects(cs1->mems_allowed, cs2->mems_allowed);
done:
- up(&callback_sem);
-
return overlap;
}
diff --git a/kernel/exit.c b/kernel/exit.c
index f8e609f..93cee36 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -193,7 +193,7 @@
return retval;
}
-static inline int has_stopped_jobs(int pgrp)
+static int has_stopped_jobs(int pgrp)
{
int retval = 0;
struct task_struct *p;
@@ -230,7 +230,7 @@
*
* NOTE that reparent_to_init() gives the caller full capabilities.
*/
-static inline void reparent_to_init(void)
+static void reparent_to_init(void)
{
write_lock_irq(&tasklist_lock);
@@ -244,7 +244,9 @@
/* Set the exit signal to SIGCHLD so we signal init on exit */
current->exit_signal = SIGCHLD;
- if ((current->policy == SCHED_NORMAL) && (task_nice(current) < 0))
+ if ((current->policy == SCHED_NORMAL ||
+ current->policy == SCHED_BATCH)
+ && (task_nice(current) < 0))
set_user_nice(current, 0);
/* cpus_allowed? */
/* rt_priority? */
@@ -367,7 +369,7 @@
EXPORT_SYMBOL(daemonize);
-static inline void close_files(struct files_struct * files)
+static void close_files(struct files_struct * files)
{
int i, j;
struct fdtable *fdt;
@@ -541,7 +543,7 @@
p->real_parent = reaper;
}
-static inline void reparent_thread(task_t *p, task_t *father, int traced)
+static void reparent_thread(task_t *p, task_t *father, int traced)
{
/* We don't want people slaying init. */
if (p->exit_signal != -1)
@@ -605,7 +607,7 @@
* group, and if no such member exists, give it to
* the global child reaper process (ie "init")
*/
-static inline void forget_original_parent(struct task_struct * father,
+static void forget_original_parent(struct task_struct * father,
struct list_head *to_release)
{
struct task_struct *p, *reaper = father;
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index 9e66e61..197208b 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -192,7 +192,7 @@
return do_sys_settimeofday(tp, NULL);
}
-static inline int common_timer_create(struct k_itimer *new_timer)
+static int common_timer_create(struct k_itimer *new_timer)
{
hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock);
new_timer->it.real.timer.data = new_timer;
@@ -361,7 +361,7 @@
return ret;
}
-static inline struct task_struct * good_sigevent(sigevent_t * event)
+static struct task_struct * good_sigevent(sigevent_t * event)
{
struct task_struct *rtn = current->group_leader;
@@ -687,7 +687,7 @@
/* Set a POSIX.1b interval timer. */
/* timr->it_lock is taken. */
-static inline int
+static int
common_timer_set(struct k_itimer *timr, int flags,
struct itimerspec *new_setting, struct itimerspec *old_setting)
{
@@ -829,7 +829,7 @@
/*
* return timer owned by the process, used by exit_itimers
*/
-static inline void itimer_delete(struct k_itimer *timer)
+static void itimer_delete(struct k_itimer *timer)
{
unsigned long flags;
diff --git a/kernel/sched.c b/kernel/sched.c
index c9dec2a..788ecce 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -521,7 +521,7 @@
* long it was waiting to run. We also note when it began so that we
* can keep stats on how long its timeslice is.
*/
-static inline void sched_info_arrive(task_t *t)
+static void sched_info_arrive(task_t *t)
{
unsigned long now = jiffies, diff = 0;
struct runqueue *rq = task_rq(t);
@@ -748,10 +748,14 @@
unsigned long long __sleep_time = now - p->timestamp;
unsigned long sleep_time;
- if (__sleep_time > NS_MAX_SLEEP_AVG)
- sleep_time = NS_MAX_SLEEP_AVG;
- else
- sleep_time = (unsigned long)__sleep_time;
+ if (unlikely(p->policy == SCHED_BATCH))
+ sleep_time = 0;
+ else {
+ if (__sleep_time > NS_MAX_SLEEP_AVG)
+ sleep_time = NS_MAX_SLEEP_AVG;
+ else
+ sleep_time = (unsigned long)__sleep_time;
+ }
if (likely(sleep_time > 0)) {
/*
@@ -1003,7 +1007,7 @@
* We want to under-estimate the load of migration sources, to
* balance conservatively.
*/
-static inline unsigned long __source_load(int cpu, int type, enum idle_type idle)
+static unsigned long __source_load(int cpu, int type, enum idle_type idle)
{
runqueue_t *rq = cpu_rq(cpu);
unsigned long running = rq->nr_running;
@@ -1866,7 +1870,7 @@
* pull_task - move a task from a remote runqueue to the local runqueue.
* Both runqueues must be locked.
*/
-static inline
+static
void pull_task(runqueue_t *src_rq, prio_array_t *src_array, task_t *p,
runqueue_t *this_rq, prio_array_t *this_array, int this_cpu)
{
@@ -1888,7 +1892,7 @@
/*
* can_migrate_task - may task p from runqueue rq be migrated to this_cpu?
*/
-static inline
+static
int can_migrate_task(task_t *p, runqueue_t *rq, int this_cpu,
struct sched_domain *sd, enum idle_type idle,
int *all_pinned)
@@ -2374,7 +2378,7 @@
* idle_balance is called by schedule() if this_cpu is about to become
* idle. Attempts to pull tasks from other CPUs.
*/
-static inline void idle_balance(int this_cpu, runqueue_t *this_rq)
+static void idle_balance(int this_cpu, runqueue_t *this_rq)
{
struct sched_domain *sd;
@@ -2758,7 +2762,7 @@
resched_task(rq->idle);
}
-static inline void wake_sleeping_dependent(int this_cpu, runqueue_t *this_rq)
+static void wake_sleeping_dependent(int this_cpu, runqueue_t *this_rq)
{
struct sched_domain *tmp, *sd = NULL;
cpumask_t sibling_map;
@@ -2812,7 +2816,7 @@
return p->time_slice * (100 - sd->per_cpu_gain) / 100;
}
-static inline int dependent_sleeper(int this_cpu, runqueue_t *this_rq)
+static int dependent_sleeper(int this_cpu, runqueue_t *this_rq)
{
struct sched_domain *tmp, *sd = NULL;
cpumask_t sibling_map;
@@ -3560,7 +3564,7 @@
* The RT priorities are set via sched_setscheduler(), but we still
* allow the 'normal' nice value to be set - but as expected
* it wont have any effect on scheduling until the task is
- * not SCHED_NORMAL:
+ * not SCHED_NORMAL/SCHED_BATCH:
*/
if (rt_task(p)) {
p->static_prio = NICE_TO_PRIO(nice);
@@ -3706,10 +3710,16 @@
BUG_ON(p->array);
p->policy = policy;
p->rt_priority = prio;
- if (policy != SCHED_NORMAL)
+ if (policy != SCHED_NORMAL && policy != SCHED_BATCH) {
p->prio = MAX_RT_PRIO-1 - p->rt_priority;
- else
+ } else {
p->prio = p->static_prio;
+ /*
+ * SCHED_BATCH tasks are treated as perpetual CPU hogs:
+ */
+ if (policy == SCHED_BATCH)
+ p->sleep_avg = 0;
+ }
}
/**
@@ -3733,29 +3743,35 @@
if (policy < 0)
policy = oldpolicy = p->policy;
else if (policy != SCHED_FIFO && policy != SCHED_RR &&
- policy != SCHED_NORMAL)
- return -EINVAL;
+ policy != SCHED_NORMAL && policy != SCHED_BATCH)
+ return -EINVAL;
/*
* Valid priorities for SCHED_FIFO and SCHED_RR are
- * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL is 0.
+ * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL and
+ * SCHED_BATCH is 0.
*/
if (param->sched_priority < 0 ||
(p->mm && param->sched_priority > MAX_USER_RT_PRIO-1) ||
(!p->mm && param->sched_priority > MAX_RT_PRIO-1))
return -EINVAL;
- if ((policy == SCHED_NORMAL) != (param->sched_priority == 0))
+ if ((policy == SCHED_NORMAL || policy == SCHED_BATCH)
+ != (param->sched_priority == 0))
return -EINVAL;
/*
* Allow unprivileged RT tasks to decrease priority:
*/
if (!capable(CAP_SYS_NICE)) {
- /* can't change policy */
- if (policy != p->policy &&
- !p->signal->rlim[RLIMIT_RTPRIO].rlim_cur)
+ /*
+ * can't change policy, except between SCHED_NORMAL
+ * and SCHED_BATCH:
+ */
+ if (((policy != SCHED_NORMAL && p->policy != SCHED_BATCH) &&
+ (policy != SCHED_BATCH && p->policy != SCHED_NORMAL)) &&
+ !p->signal->rlim[RLIMIT_RTPRIO].rlim_cur)
return -EPERM;
/* can't increase priority */
- if (policy != SCHED_NORMAL &&
+ if ((policy != SCHED_NORMAL && policy != SCHED_BATCH) &&
param->sched_priority > p->rt_priority &&
param->sched_priority >
p->signal->rlim[RLIMIT_RTPRIO].rlim_cur)
@@ -4233,6 +4249,7 @@
ret = MAX_USER_RT_PRIO-1;
break;
case SCHED_NORMAL:
+ case SCHED_BATCH:
ret = 0;
break;
}
@@ -4256,6 +4273,7 @@
ret = 1;
break;
case SCHED_NORMAL:
+ case SCHED_BATCH:
ret = 0;
}
return ret;
@@ -5990,7 +6008,7 @@
* Detach sched domains from a group of cpus specified in cpu_map
* These cpus will now be attached to the NULL domain
*/
-static inline void detach_destroy_domains(const cpumask_t *cpu_map)
+static void detach_destroy_domains(const cpumask_t *cpu_map)
{
int i;
diff --git a/kernel/signal.c b/kernel/signal.c
index 1da2e74..5dafbd3 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -476,7 +476,7 @@
spin_unlock_irqrestore(¤t->sighand->siglock, flags);
}
-static inline int collect_signal(int sig, struct sigpending *list, siginfo_t *info)
+static int collect_signal(int sig, struct sigpending *list, siginfo_t *info)
{
struct sigqueue *q, *first = NULL;
int still_pending = 0;
@@ -1881,7 +1881,7 @@
* We return zero if we still hold the siglock and should look
* for another signal without checking group_stop_count again.
*/
-static inline int handle_group_stop(void)
+static int handle_group_stop(void)
{
int stop_count;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 62d4d95..f5d69b6 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -648,7 +648,7 @@
.mode = 0644,
.proc_handler = &proc_dointvec,
},
-#if defined(CONFIG_S390)
+#if defined(CONFIG_S390) && defined(CONFIG_SMP)
{
.ctl_name = KERN_SPIN_RETRY,
.procname = "spin_retry",
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 82c4fa7..b052e2c 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -147,7 +147,7 @@
return ret;
}
-static inline void run_workqueue(struct cpu_workqueue_struct *cwq)
+static void run_workqueue(struct cpu_workqueue_struct *cwq)
{
unsigned long flags;
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index a609235..a314e66 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -195,6 +195,20 @@
some architectures or if you use external debuggers.
If you don't debug the kernel, you can say N.
+config FORCED_INLINING
+ bool "Force gcc to inline functions marked 'inline'"
+ depends on DEBUG_KERNEL
+ default y
+ help
+ This option determines if the kernel forces gcc to inline the functions
+ developers have marked 'inline'. Doing so takes away freedom from gcc to
+ do what it thinks is best, which is desirable for the gcc 3.x series of
+ compilers. The gcc 4.x series have a rewritten inlining algorithm and
+ disabling this option will generate a smaller kernel there. Hopefully
+ this algorithm is so good that allowing gcc4 to make the decision can
+ become the default in the future, until then this option is there to
+ test gcc for this.
+
config RCU_TORTURE_TEST
tristate "torture tests for RCU"
depends on DEBUG_KERNEL
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index b62cab5..3171f88 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1359,6 +1359,30 @@
return 0;
}
+void mpol_shared_policy_init(struct shared_policy *info, int policy,
+ nodemask_t *policy_nodes)
+{
+ info->root = RB_ROOT;
+ spin_lock_init(&info->lock);
+
+ if (policy != MPOL_DEFAULT) {
+ struct mempolicy *newpol;
+
+ /* Falls back to MPOL_DEFAULT on any error */
+ newpol = mpol_new(policy, policy_nodes);
+ if (!IS_ERR(newpol)) {
+ /* Create pseudo-vma that contains just the policy */
+ struct vm_area_struct pvma;
+
+ memset(&pvma, 0, sizeof(struct vm_area_struct));
+ /* Policy covers entire file */
+ pvma.vm_end = TASK_SIZE;
+ mpol_set_shared_policy(info, &pvma, newpol);
+ mpol_free(newpol);
+ }
+ }
+}
+
int mpol_set_shared_policy(struct shared_policy *info,
struct vm_area_struct *vma, struct mempolicy *npol)
{
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 4748b90..14bd4ec 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -274,6 +274,7 @@
show_mem();
}
+ cpuset_lock();
read_lock(&tasklist_lock);
retry:
p = select_bad_process();
@@ -284,6 +285,7 @@
/* Found nothing?!?! Either we hang forever, or we panic. */
if (!p) {
read_unlock(&tasklist_lock);
+ cpuset_unlock();
panic("Out of memory and no killable processes...\n");
}
@@ -293,6 +295,7 @@
out:
read_unlock(&tasklist_lock);
+ cpuset_unlock();
if (mm)
mmput(mm);
diff --git a/mm/shmem.c b/mm/shmem.c
index 343b3c0..ce501bc 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1316,7 +1316,8 @@
case S_IFREG:
inode->i_op = &shmem_inode_operations;
inode->i_fop = &shmem_file_operations;
- mpol_shared_policy_init(&info->policy);
+ mpol_shared_policy_init(&info->policy, sbinfo->policy,
+ &sbinfo->policy_nodes);
break;
case S_IFDIR:
inode->i_nlink++;
@@ -1330,7 +1331,8 @@
* Must not load anything in the rbtree,
* mpol_free_shared_policy will not be called.
*/
- mpol_shared_policy_init(&info->policy);
+ mpol_shared_policy_init(&info->policy, MPOL_DEFAULT,
+ NULL);
break;
}
} else if (sbinfo->max_inodes) {
@@ -1843,7 +1845,9 @@
.put_link = shmem_put_link,
};
-static int shmem_parse_options(char *options, int *mode, uid_t *uid, gid_t *gid, unsigned long *blocks, unsigned long *inodes)
+static int shmem_parse_options(char *options, int *mode, uid_t *uid,
+ gid_t *gid, unsigned long *blocks, unsigned long *inodes,
+ int *policy, nodemask_t *policy_nodes)
{
char *this_char, *value, *rest;
@@ -1897,6 +1901,19 @@
*gid = simple_strtoul(value,&rest,0);
if (*rest)
goto bad_val;
+ } else if (!strcmp(this_char,"mpol")) {
+ if (!strcmp(value,"default"))
+ *policy = MPOL_DEFAULT;
+ else if (!strcmp(value,"preferred"))
+ *policy = MPOL_PREFERRED;
+ else if (!strcmp(value,"bind"))
+ *policy = MPOL_BIND;
+ else if (!strcmp(value,"interleave"))
+ *policy = MPOL_INTERLEAVE;
+ else
+ goto bad_val;
+ } else if (!strcmp(this_char,"mpol_nodelist")) {
+ nodelist_parse(value, *policy_nodes);
} else {
printk(KERN_ERR "tmpfs: Bad mount option %s\n",
this_char);
@@ -1917,12 +1934,14 @@
struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
unsigned long max_blocks = sbinfo->max_blocks;
unsigned long max_inodes = sbinfo->max_inodes;
+ int policy = sbinfo->policy;
+ nodemask_t policy_nodes = sbinfo->policy_nodes;
unsigned long blocks;
unsigned long inodes;
int error = -EINVAL;
- if (shmem_parse_options(data, NULL, NULL, NULL,
- &max_blocks, &max_inodes))
+ if (shmem_parse_options(data, NULL, NULL, NULL, &max_blocks,
+ &max_inodes, &policy, &policy_nodes))
return error;
spin_lock(&sbinfo->stat_lock);
@@ -1948,6 +1967,8 @@
sbinfo->free_blocks = max_blocks - blocks;
sbinfo->max_inodes = max_inodes;
sbinfo->free_inodes = max_inodes - inodes;
+ sbinfo->policy = policy;
+ sbinfo->policy_nodes = policy_nodes;
out:
spin_unlock(&sbinfo->stat_lock);
return error;
@@ -1972,6 +1993,8 @@
struct shmem_sb_info *sbinfo;
unsigned long blocks = 0;
unsigned long inodes = 0;
+ int policy = MPOL_DEFAULT;
+ nodemask_t policy_nodes = node_online_map;
#ifdef CONFIG_TMPFS
/*
@@ -1984,8 +2007,8 @@
inodes = totalram_pages - totalhigh_pages;
if (inodes > blocks)
inodes = blocks;
- if (shmem_parse_options(data, &mode, &uid, &gid,
- &blocks, &inodes))
+ if (shmem_parse_options(data, &mode, &uid, &gid, &blocks,
+ &inodes, &policy, &policy_nodes))
return -EINVAL;
}
#else
@@ -2003,6 +2026,8 @@
sbinfo->free_blocks = blocks;
sbinfo->max_inodes = inodes;
sbinfo->free_inodes = inodes;
+ sbinfo->policy = policy;
+ sbinfo->policy_nodes = policy_nodes;
sb->s_fs_info = sbinfo;
sb->s_maxbytes = SHMEM_MAX_BYTES;
diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c
index 321287b..90d18b7 100644
--- a/net/ieee80211/ieee80211_module.c
+++ b/net/ieee80211/ieee80211_module.c
@@ -62,7 +62,7 @@
MODULE_AUTHOR(DRV_COPYRIGHT);
MODULE_LICENSE("GPL");
-static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
+static int ieee80211_networks_allocate(struct ieee80211_device *ieee)
{
if (ieee->networks)
return 0;
@@ -90,7 +90,7 @@
ieee->networks = NULL;
}
-static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
+static void ieee80211_networks_initialize(struct ieee80211_device *ieee)
{
int i;
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 5e33803..7a12180 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -35,7 +35,7 @@
#include <net/ieee80211.h>
-static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
+static void ieee80211_monitor_rx(struct ieee80211_device *ieee,
struct sk_buff *skb,
struct ieee80211_rx_stats *rx_stats)
{
@@ -165,7 +165,7 @@
* Responsible for handling management control frames
*
* Called by ieee80211_rx */
-static inline int
+static int
ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
struct ieee80211_rx_stats *rx_stats, u16 type,
u16 stype)
@@ -266,7 +266,7 @@
}
/* Called only as a tasklet (software IRQ), by ieee80211_rx */
-static inline int
+static int
ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
struct ieee80211_crypt_data *crypt)
{
@@ -297,7 +297,7 @@
}
/* Called only as a tasklet (software IRQ), by ieee80211_rx */
-static inline int
+static int
ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
struct sk_buff *skb, int keyidx,
struct ieee80211_crypt_data *crypt)
@@ -1156,7 +1156,7 @@
/***************************************************/
-static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response
+static int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response
*beacon,
struct ieee80211_network *network,
struct ieee80211_rx_stats *stats)
@@ -1235,7 +1235,7 @@
!memcmp(src->ssid, dst->ssid, src->ssid_len));
}
-static inline void update_network(struct ieee80211_network *dst,
+static void update_network(struct ieee80211_network *dst,
struct ieee80211_network *src)
{
int qos_active;
@@ -1294,7 +1294,7 @@
return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON);
}
-static inline void ieee80211_process_probe_response(struct ieee80211_device
+static void ieee80211_process_probe_response(struct ieee80211_device
*ieee, struct
ieee80211_probe_response
*beacon, struct ieee80211_rx_stats
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
index e5b33c8..8fdd943 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -127,7 +127,7 @@
static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
-static inline int ieee80211_copy_snap(u8 * data, u16 h_proto)
+static int ieee80211_copy_snap(u8 * data, u16 h_proto)
{
struct ieee80211_snap_hdr *snap;
u8 *oui;
@@ -150,7 +150,7 @@
return SNAP_SIZE + sizeof(u16);
}
-static inline int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
+static int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
struct sk_buff *frag, int hdr_len)
{
struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx];
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 406d5b9..23e1630 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -42,7 +42,7 @@
};
#define MAX_CUSTOM_LEN 64
-static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
+static char *ipw2100_translate_scan(struct ieee80211_device *ieee,
char *start, char *stop,
struct ieee80211_network *network)
{
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 5b25fc0d..4e3d381 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -289,13 +289,13 @@
{
int i;
- for (i=1; i<=RTA_MAX; i++) {
- struct rtattr *attr = rta[i-1];
+ for (i=1; i<=RTA_MAX; i++, rta++) {
+ struct rtattr *attr = *rta;
if (attr) {
if (RTA_PAYLOAD(attr) < 4)
return -EINVAL;
if (i != RTA_MULTIPATH && i != RTA_METRICS)
- rta[i-1] = (struct rtattr*)RTA_DATA(attr);
+ *rta = (struct rtattr*)RTA_DATA(attr);
}
}
return 0;
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 95fdf04..f6063e8 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -212,7 +212,7 @@
}
/* Process one complete nfnetlink message. */
-static inline int nfnetlink_rcv_msg(struct sk_buff *skb,
+static int nfnetlink_rcv_msg(struct sk_buff *skb,
struct nlmsghdr *nlh, int *errp)
{
struct nfnl_callback *nc;
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 6647204..b9f8d97 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1019,7 +1019,7 @@
has the same SID as the process. If av is zero, then
access to the file is not checked, e.g. for cases
where only the descriptor is affected like seek. */
-static inline int file_has_perm(struct task_struct *tsk,
+static int file_has_perm(struct task_struct *tsk,
struct file *file,
u32 av)
{
diff --git a/sound/oss/esssolo1.c b/sound/oss/esssolo1.c
index a4ecab2f..849b59f 100644
--- a/sound/oss/esssolo1.c
+++ b/sound/oss/esssolo1.c
@@ -515,7 +515,7 @@
return 0;
}
-static inline int prog_dmabuf_dac(struct solo1_state *s)
+static int prog_dmabuf_dac(struct solo1_state *s)
{
unsigned long va;
int c;
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 9ffb600..3747a43 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -727,7 +727,7 @@
apu_data_set(chip, data);
}
-static inline void apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data)
+static void apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data)
{
unsigned long flags;
spin_lock_irqsave(&chip->reg_lock, flags);
@@ -743,7 +743,7 @@
return __maestro_read(chip, IDR0_DATA_PORT);
}
-static inline u16 apu_get_register(struct es1968 *chip, u16 channel, u8 reg)
+static u16 apu_get_register(struct es1968 *chip, u16 channel, u8 reg)
{
unsigned long flags;
u16 v;