Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb

* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (310 commits)
  V4L/DVB (6316): Change list_for_each+list_entry to list_for_each_entry
  V4L/DVB (6315): pvrusb2: Change list_for_each+list_entry to list_for_each_entry
  V4L/DVB (6314): saa7134: Replace list_for_each+list_entry with list_for_each_entry
  V4L/DVB (6313): ivtv: Replace list_for_each+list_entry with list_for_each_entry
  V4L/DVB (6312): cx88: Replace list_for_each+list_entry with list_for_each_entry
  V4L/DVB (6311): dvb: Replace list_for_each+list_entry with list_for_each_entry
  V4L/DVB (6308): V4L: zc0301, remove bad usage of ERESTARTSYS
  V4L/DVB (6307): V4L: w9968cf, remove bad usage of ERESTARTSYS
  V4L/DVB (6306): Few clenups for saa7134 resume code
  V4L/DVB (6305): V4L: videobuf-core.c avoid NULL dereferences in videobuf-core
  V4L/DVB (6301): pvrusb: Update DEBUGIFC sysfs to kernel 2.6.13+
  V4L/DVB (6300): CodingStyle cleanup
  V4L/DVB (6299): dvb: Add dependencies for VIDEOBUF_DVB
  V4L/DVB (6297): cx23885: remove wrong Kconfig selection of VIDEOBUF
  V4L/DVB (6296): dib0700: add support for AverMedia DVB-T Express card
  V4L/DVB (6295): saa7134: add autodetection for KWorld ATSC-115
  V4L/DVB (6293): V4L: convert struct class_device to struct device
  V4L/DVB (6292): videobuf_core init always require callback implementation
  V4L/DVB (6291): Fix: avoid oops on some SMP machines
  V4L/DVB (6290): remove videobuf_set_pci_ops
  ...
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 00928d2..675f756 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -306,3 +306,11 @@
 Who:    Stephen Hemminger <shemminger@linux-foundation.org>
 
 ---------------------------
+
+What:	i386/x86_64 bzImage symlinks
+When:	April 2008
+
+Why:	The i386/x86_64 merge provides a symlink to the old bzImage
+	location so not yet updated user space tools, e.g. package
+	scripts, do not break.
+Who:	Thomas Gleixner <tglx@linutronix.de>
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index 73c5f1f..103e346 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -46,7 +46,7 @@
 typedef uint16_t u16;
 typedef uint8_t u8;
 #include "../../include/linux/lguest_launcher.h"
-#include "../../include/asm-i386/e820.h"
+#include "../../include/asm-x86/e820_32.h"
 /*:*/
 
 #define PAGE_PRESENT 0x7 	/* Present, RW, Execute */
diff --git a/Kbuild b/Kbuild
index 56b8edf..1570d24 100644
--- a/Kbuild
+++ b/Kbuild
@@ -8,11 +8,11 @@
 # 1) Generate asm-offsets.h
 #
 
-offsets-file := include/asm-$(ARCH)/asm-offsets.h
+offsets-file := include/asm-$(SRCARCH)/asm-offsets.h
 
 always  := $(offsets-file)
 targets := $(offsets-file)
-targets += arch/$(ARCH)/kernel/asm-offsets.s
+targets += arch/$(SRCARCH)/kernel/asm-offsets.s
 clean-files := $(addprefix $(objtree)/,$(targets))
 
 # Default sed regexp - multiline due to syntax constraints
@@ -40,11 +40,11 @@
 endef
 
 # We use internal kbuild rules to avoid the "is up to date" message from make
-arch/$(ARCH)/kernel/asm-offsets.s: arch/$(ARCH)/kernel/asm-offsets.c FORCE
+arch/$(SRCARCH)/kernel/asm-offsets.s: arch/$(SRCARCH)/kernel/asm-offsets.c FORCE
 	$(Q)mkdir -p $(dir $@)
 	$(call if_changed_dep,cc_s_c)
 
-$(obj)/$(offsets-file): arch/$(ARCH)/kernel/asm-offsets.s Kbuild
+$(obj)/$(offsets-file): arch/$(SRCARCH)/kernel/asm-offsets.s Kbuild
 	$(Q)mkdir -p $(dir $@)
 	$(call cmd,offsets)
 
diff --git a/MAINTAINERS b/MAINTAINERS
index 9a91d9e..0df29ce 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2561,12 +2561,18 @@
 W:	http://www.atnf.csiro.au/~rgooch/linux/kernel-patches.html
 S:	Maintained
 
-MULTIMEDIA CARD (MMC) AND SECURE DIGITAL (SD) SUBSYSTEM
+MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM
 P:	Pierre Ossman
 M:	drzeus-mmc@drzeus.cx
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
+MULTIMEDIA CARD (MMC) ETC. OVER SPI
+P:	David Brownell
+M:	dbrownell@users.sourceforge.net
+L:	linux-kernel@vger.kernel.org
+S:	Odd fixes
+
 MULTISOUND SOUND DRIVER
 P:	Andrew Veliath
 M:	andrewtv@usa.net
diff --git a/Makefile b/Makefile
index 4635a64..1274084 100644
--- a/Makefile
+++ b/Makefile
@@ -186,7 +186,8 @@
 CROSS_COMPILE	?=
 
 # Architecture as present in compile.h
-UTS_MACHINE := $(ARCH)
+UTS_MACHINE 	:= $(ARCH)
+SRCARCH 	:= $(ARCH)
 
 KCONFIG_CONFIG	?= .config
 
@@ -322,7 +323,7 @@
 KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
 export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
-export ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
+export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
 export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE
 export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
 
@@ -609,7 +610,7 @@
 vmlinux-init := $(head-y) $(init-y)
 vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
 vmlinux-all  := $(vmlinux-init) $(vmlinux-main)
-vmlinux-lds  := arch/$(ARCH)/kernel/vmlinux.lds
+vmlinux-lds  := arch/$(SRCARCH)/kernel/vmlinux.lds
 export KBUILD_VMLINUX_OBJS := $(vmlinux-all)
 
 # Rule to link vmlinux - also used during CONFIG_KALLSYMS
@@ -862,7 +863,7 @@
 		/bin/false; \
 	fi;
 	$(Q)if [ ! -d include2 ]; then mkdir -p include2; fi;
-	$(Q)ln -fsn $(srctree)/include/asm-$(ARCH) include2/asm
+	$(Q)ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm
 endif
 
 # prepare2 creates a makefile if using a separate output directory
@@ -894,9 +895,9 @@
 # before switching between archs anyway.
 
 include/asm:
-	@echo '  SYMLINK $@ -> include/asm-$(ARCH)'
+	@echo '  SYMLINK $@ -> include/asm-$(SRCARCH)'
 	$(Q)if [ ! -d include ]; then mkdir -p include; fi;
-	@ln -fsn asm-$(ARCH) $@
+	@ln -fsn asm-$(SRCARCH) $@
 
 # Generate some files
 # ---------------------------------------------------------------------------
@@ -936,7 +937,8 @@
 INSTALL_HDR_PATH=$(objtree)/usr
 export INSTALL_HDR_PATH
 
-HDRARCHES=$(filter-out generic,$(patsubst $(srctree)/include/asm-%/Kbuild,%,$(wildcard $(srctree)/include/asm-*/Kbuild)))
+HDRFILTER=generic i386 x86_64
+HDRARCHES=$(filter-out $(HDRFILTER),$(patsubst $(srctree)/include/asm-%/Kbuild,%,$(wildcard $(srctree)/include/asm-*/Kbuild)))
 
 PHONY += headers_install_all
 headers_install_all: include/linux/version.h scripts_basic FORCE
@@ -947,11 +949,11 @@
 
 PHONY += headers_install
 headers_install: include/linux/version.h scripts_basic FORCE
-	@if [ ! -r $(srctree)/include/asm-$(ARCH)/Kbuild ]; then \
-	  echo '*** Error: Headers not exportable for this architecture ($(ARCH))'; \
+	@if [ ! -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \
+	  echo '*** Error: Headers not exportable for this architecture ($(SRCARCH))'; \
 	  exit 1 ; fi
 	$(Q)$(MAKE) $(build)=scripts scripts/unifdef
-	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst obj=include
+	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst ARCH=$(SRCARCH) obj=include
 
 PHONY += headers_check_all
 headers_check_all: headers_install_all
@@ -961,7 +963,7 @@
 
 PHONY += headers_check
 headers_check: headers_install
-	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst obj=include HDRCHECK=1
+	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst ARCH=$(SRCARCH) obj=include HDRCHECK=1
 
 # ---------------------------------------------------------------------------
 # Modules
@@ -1139,7 +1141,7 @@
 	@echo  '  cscope	  - Generate cscope index'
 	@echo  '  kernelrelease	  - Output the release version string'
 	@echo  '  kernelversion	  - Output the version stored in Makefile'
-	@if [ -r $(srctree)/include/asm-$(ARCH)/Kbuild ]; then \
+	@if [ -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \
 	 echo  '  headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH'; \
 	 echo  '                    (default: $(INSTALL_HDR_PATH))'; \
 	 fi
@@ -1147,7 +1149,7 @@
 	@echo  'Static analysers'
 	@echo  '  checkstack      - Generate a list of stack hogs'
 	@echo  '  namespacecheck  - Name space analysis on compiled kernel'
-	@if [ -r $(srctree)/include/asm-$(ARCH)/Kbuild ]; then \
+	@if [ -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \
 	 echo  '  headers_check   - Sanity check on exported headers'; \
 	 fi
 	@echo  ''
@@ -1292,18 +1294,23 @@
 ifeq ($(ARCH),um)
 ALLINCLUDE_ARCHS := $(ARCH) $(SUBARCH)
 else
-ALLINCLUDE_ARCHS := $(ARCH)
+ALLINCLUDE_ARCHS := $(SRCARCH)
 endif
 else
 #Allow user to specify only ALLSOURCE_PATHS on the command line, keeping existing behavour.
 ALLINCLUDE_ARCHS := $(ALLSOURCE_ARCHS)
 endif
 
+# Take care of arch/x86
+ifeq ($(ARCH), $(SRCARCH))
 ALLSOURCE_ARCHS := $(ARCH)
+else
+ALLSOURCE_ARCHS := $(ARCH) $(SRCARCH)
+endif
 
 define find-sources
         ( for ARCH in $(ALLSOURCE_ARCHS) ; do \
-	       find $(__srctree)arch/$${ARCH} $(RCS_FIND_IGNORE) \
+	       find $(__srctree)arch/$${SRCARCH} $(RCS_FIND_IGNORE) \
 	            -name $1 -print; \
 	  done ; \
 	  find $(__srctree)security/selinux/include $(RCS_FIND_IGNORE) \
@@ -1312,7 +1319,7 @@
 	       \( -name config -o -name 'asm-*' \) -prune \
 	       -o -name $1 -print; \
 	  for ARCH in $(ALLINCLUDE_ARCHS) ; do \
-	       find $(__srctree)include/asm-$${ARCH} $(RCS_FIND_IGNORE) \
+	       find $(__srctree)include/asm-$${SRCARCH} $(RCS_FIND_IGNORE) \
 	            -name $1 -print; \
 	  done ; \
 	  find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \
diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c
index da893c8..a9778c1 100644
--- a/arch/arm/mach-imx/mx1ads.c
+++ b/arch/arm/mach-imx/mx1ads.c
@@ -116,7 +116,7 @@
 };
 
 #ifdef CONFIG_MMC_IMX
-static int mx1ads_mmc_card_present(void)
+static int mx1ads_mmc_card_present(struct device *dev)
 {
 	/* MMC/SD Card Detect is PB 20 on MX1ADS V1.0.7 */
 	return (SSR(1) & (1 << 20) ? 0 : 1);
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 97b64d7..2d85e4b 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -226,7 +226,7 @@
 	  However, when run without a hypervisor the kernel is
 	  theoretically slower.  If in doubt, say N.
 
-source "arch/i386/xen/Kconfig"
+source "arch/x86/xen/Kconfig"
 
 config VMI
 	bool "VMI Paravirt-ops support"
@@ -707,7 +707,7 @@
 	  intend to use this kernel on different machines.
 
 	  More information about the internals of the Linux math coprocessor
-	  emulation can be found in <file:arch/i386/math-emu/README>.
+	  emulation can be found in <file:arch/x86/math-emu/README>.
 
 	  If you are not sure, say Y; apart from resulting in a 66 KB bigger
 	  kernel, it won't hurt.
@@ -1067,7 +1067,7 @@
 
 endif # APM
 
-source "arch/i386/kernel/cpu/cpufreq/Kconfig"
+source "arch/x86/kernel/cpu/cpufreq/Kconfig"
 
 endmenu
 
@@ -1240,7 +1240,7 @@
 
 if INSTRUMENTATION
 
-source "arch/i386/oprofile/Kconfig"
+source "arch/x86/oprofile/Kconfig"
 
 config KPROBES
 	bool "Kprobes"
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 52b9324..5e50dbf 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -17,6 +17,9 @@
 # 20050320  Kianusch Sayah Karadji <kianusch@sk-tech.net>
 #           Added support for GEODE CPU
 
+# Fill in SRCARCH
+SRCARCH	:= x86
+
 HAS_BIARCH      := $(call cc-option-yn, -m32)
 ifeq ($(HAS_BIARCH),y)
 AS              := $(AS) --32
@@ -61,62 +64,62 @@
 CFLAGS += $(cflags-y)
 
 # Default subarch .c files
-mcore-y  := mach-default
+mcore-y  := arch/x86/mach-default
 
 # Voyager subarch support
-mflags-$(CONFIG_X86_VOYAGER)	:= -Iinclude/asm-i386/mach-voyager
-mcore-$(CONFIG_X86_VOYAGER)	:= mach-voyager
+mflags-$(CONFIG_X86_VOYAGER)	:= -Iinclude/asm-x86/mach-voyager
+mcore-$(CONFIG_X86_VOYAGER)	:= arch/x86/mach-voyager
 
 # VISWS subarch support
-mflags-$(CONFIG_X86_VISWS)	:= -Iinclude/asm-i386/mach-visws
-mcore-$(CONFIG_X86_VISWS)	:= mach-visws
+mflags-$(CONFIG_X86_VISWS)	:= -Iinclude/asm-x86/mach-visws
+mcore-$(CONFIG_X86_VISWS)	:= arch/x86/mach-visws
 
 # NUMAQ subarch support
-mflags-$(CONFIG_X86_NUMAQ)	:= -Iinclude/asm-i386/mach-numaq
-mcore-$(CONFIG_X86_NUMAQ)	:= mach-default
+mflags-$(CONFIG_X86_NUMAQ)	:= -Iinclude/asm-x86/mach-numaq
+mcore-$(CONFIG_X86_NUMAQ)	:= arch/x86/mach-default
 
 # BIGSMP subarch support
-mflags-$(CONFIG_X86_BIGSMP)	:= -Iinclude/asm-i386/mach-bigsmp
-mcore-$(CONFIG_X86_BIGSMP)	:= mach-default
+mflags-$(CONFIG_X86_BIGSMP)	:= -Iinclude/asm-x86/mach-bigsmp
+mcore-$(CONFIG_X86_BIGSMP)	:= arch/x86/mach-default
 
 #Summit subarch support
-mflags-$(CONFIG_X86_SUMMIT) := -Iinclude/asm-i386/mach-summit
-mcore-$(CONFIG_X86_SUMMIT)  := mach-default
+mflags-$(CONFIG_X86_SUMMIT) := -Iinclude/asm-x86/mach-summit
+mcore-$(CONFIG_X86_SUMMIT)  := arch/x86/mach-default
 
 # generic subarchitecture
-mflags-$(CONFIG_X86_GENERICARCH) := -Iinclude/asm-i386/mach-generic
-mcore-$(CONFIG_X86_GENERICARCH) := mach-default
-core-$(CONFIG_X86_GENERICARCH) += arch/i386/mach-generic/
+mflags-$(CONFIG_X86_GENERICARCH) := -Iinclude/asm-x86/mach-generic
+mcore-$(CONFIG_X86_GENERICARCH) := arch/x86/mach-default
+core-$(CONFIG_X86_GENERICARCH) += arch/x86/mach-generic/
 
 # ES7000 subarch support
-mflags-$(CONFIG_X86_ES7000)	:= -Iinclude/asm-i386/mach-es7000
-mcore-$(CONFIG_X86_ES7000)	:= mach-default
-core-$(CONFIG_X86_ES7000)	:= arch/i386/mach-es7000/
+mflags-$(CONFIG_X86_ES7000)	:= -Iinclude/asm-x86/mach-es7000
+mcore-$(CONFIG_X86_ES7000)	:= arch/x86/mach-default
+core-$(CONFIG_X86_ES7000)	:= arch/x86/mach-es7000/
 
 # Xen paravirtualization support
-core-$(CONFIG_XEN)		+= arch/i386/xen/
+core-$(CONFIG_XEN)		+= arch/x86/xen/
 
 # default subarch .h files
-mflags-y += -Iinclude/asm-i386/mach-default
+mflags-y += -Iinclude/asm-x86/mach-default
 
-head-y := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
+head-y := arch/x86/kernel/head_32.o arch/x86/kernel/init_task_32.o
 
-libs-y 					+= arch/i386/lib/
-core-y					+= arch/i386/kernel/ \
-					   arch/i386/mm/ \
-					   arch/i386/$(mcore-y)/ \
-					   arch/i386/crypto/
-drivers-$(CONFIG_MATH_EMULATION)	+= arch/i386/math-emu/
-drivers-$(CONFIG_PCI)			+= arch/i386/pci/
+libs-y 					+= arch/x86/lib/
+core-y					+= arch/x86/kernel/ \
+					   arch/x86/mm/ \
+					   $(mcore-y)/ \
+					   arch/x86/crypto/
+drivers-$(CONFIG_MATH_EMULATION)	+= arch/x86/math-emu/
+drivers-$(CONFIG_PCI)			+= arch/x86/pci/
 # must be linked after kernel/
-drivers-$(CONFIG_OPROFILE)		+= arch/i386/oprofile/
-drivers-$(CONFIG_PM)			+= arch/i386/power/
-drivers-$(CONFIG_FB)                    += arch/i386/video/
+drivers-$(CONFIG_OPROFILE)		+= arch/x86/oprofile/
+drivers-$(CONFIG_PM)			+= arch/x86/power/
+drivers-$(CONFIG_FB)                    += arch/x86/video/
 
 CFLAGS += $(mflags-y)
 AFLAGS += $(mflags-y)
 
-boot := arch/i386/boot
+boot := arch/x86/boot
 
 PHONY += zImage bzImage compressed zlilo bzlilo \
          zdisk bzdisk fdimage fdimage144 fdimage288 isoimage install
@@ -125,9 +128,11 @@
 
 # KBUILD_IMAGE specify target image being built
                     KBUILD_IMAGE := $(boot)/bzImage
-zImage zlilo zdisk: KBUILD_IMAGE := arch/i386/boot/zImage
+zImage zlilo zdisk: KBUILD_IMAGE := arch/x86/boot/zImage
 
 zImage bzImage: vmlinux
+	$(Q)mkdir -p $(objtree)/arch/i386/boot
+	$(Q)ln -fsn $(objtree)/arch/x86/boot/bzImage $(objtree)/arch/i386/boot/bzImage
 	$(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)
 
 compressed: zImage
@@ -145,7 +150,8 @@
 	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
 
 archclean:
-	$(Q)$(MAKE) $(clean)=arch/i386/boot
+	$(Q)rm -rf $(objtree)/arch/i386/boot
+	$(Q)$(MAKE) $(clean)=arch/x86/boot
 
 define archhelp
   echo  '* bzImage	- Compressed kernel image (arch/$(ARCH)/boot/bzImage)'
diff --git a/arch/i386/crypto/Makefile b/arch/i386/crypto/Makefile
deleted file mode 100644
index 3fd19af..0000000
--- a/arch/i386/crypto/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# 
-# i386/crypto/Makefile 
-# 
-# Arch-specific CryptoAPI modules.
-# 
-
-obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
-obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o
-
-aes-i586-y := aes-i586-asm.o aes.o
-twofish-i586-y := twofish-i586-asm.o twofish.o
-
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
deleted file mode 100644
index 9d33b00..0000000
--- a/arch/i386/kernel/Makefile
+++ /dev/null
@@ -1,88 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-extra-y := head.o init_task.o vmlinux.lds
-
-obj-y	:= process.o signal.o entry.o traps.o irq.o \
-		ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \
-		pci-dma.o i386_ksyms.o i387.o bootflag.o e820.o\
-		quirks.o i8237.o topology.o alternative.o i8253.o tsc.o
-
-obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
-obj-y				+= cpu/
-obj-y				+= acpi/
-obj-$(CONFIG_X86_BIOS_REBOOT)	+= reboot.o
-obj-$(CONFIG_MCA)		+= mca.o
-obj-$(CONFIG_X86_MSR)		+= msr.o
-obj-$(CONFIG_X86_CPUID)		+= cpuid.o
-obj-$(CONFIG_MICROCODE)		+= microcode.o
-obj-$(CONFIG_APM)		+= apm.o
-obj-$(CONFIG_X86_SMP)		+= smp.o smpboot.o tsc_sync.o
-obj-$(CONFIG_SMP)		+= smpcommon.o
-obj-$(CONFIG_X86_TRAMPOLINE)	+= trampoline.o
-obj-$(CONFIG_X86_MPPARSE)	+= mpparse.o
-obj-$(CONFIG_X86_LOCAL_APIC)	+= apic.o nmi.o
-obj-$(CONFIG_X86_IO_APIC)	+= io_apic.o
-obj-$(CONFIG_X86_REBOOTFIXUPS)	+= reboot_fixups.o
-obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o crash.o
-obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
-obj-$(CONFIG_X86_NUMAQ)		+= numaq.o
-obj-$(CONFIG_X86_SUMMIT_NUMA)	+= summit.o
-obj-$(CONFIG_KPROBES)		+= kprobes.o
-obj-$(CONFIG_MODULES)		+= module.o
-obj-y				+= sysenter.o vsyscall.o
-obj-$(CONFIG_ACPI_SRAT) 	+= srat.o
-obj-$(CONFIG_EFI) 		+= efi.o efi_stub.o
-obj-$(CONFIG_DOUBLEFAULT) 	+= doublefault.o
-obj-$(CONFIG_VM86)		+= vm86.o
-obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
-obj-$(CONFIG_HPET_TIMER) 	+= hpet.o
-obj-$(CONFIG_K8_NB)		+= k8.o
-obj-$(CONFIG_MGEODE_LX)		+= geode.o
-
-obj-$(CONFIG_VMI)		+= vmi.o vmiclock.o
-obj-$(CONFIG_PARAVIRT)		+= paravirt.o
-obj-y				+= pcspeaker.o
-
-obj-$(CONFIG_SCx200)		+= scx200.o
-
-# vsyscall.o contains the vsyscall DSO images as __initdata.
-# We must build both images before we can assemble it.
-# Note: kbuild does not track this dependency due to usage of .incbin
-$(obj)/vsyscall.o: $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so
-targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so)
-targets += vsyscall-note.o vsyscall.lds
-
-# The DSO images are built using a special linker script.
-quiet_cmd_syscall = SYSCALL $@
-      cmd_syscall = $(CC) -m elf_i386 -nostdlib $(SYSCFLAGS_$(@F)) \
-		          -Wl,-T,$(filter-out FORCE,$^) -o $@
-
-export CPPFLAGS_vsyscall.lds += -P -C -U$(ARCH)
-
-vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1 \
-		 $(call ld-option, -Wl$(comma)--hash-style=sysv)
-SYSCFLAGS_vsyscall-sysenter.so	= $(vsyscall-flags)
-SYSCFLAGS_vsyscall-int80.so	= $(vsyscall-flags)
-
-$(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so: \
-$(obj)/vsyscall-%.so: $(src)/vsyscall.lds \
-		      $(obj)/vsyscall-%.o $(obj)/vsyscall-note.o FORCE
-	$(call if_changed,syscall)
-
-# We also create a special relocatable object that should mirror the symbol
-# table and layout of the linked DSO.  With ld -R we can then refer to
-# these symbols in the kernel code rather than hand-coded addresses.
-extra-y += vsyscall-syms.o
-$(obj)/built-in.o: $(obj)/vsyscall-syms.o
-$(obj)/built-in.o: ld_flags += -R $(obj)/vsyscall-syms.o
-
-SYSCFLAGS_vsyscall-syms.o = -r
-$(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \
-			$(obj)/vsyscall-sysenter.o $(obj)/vsyscall-note.o FORCE
-	$(call if_changed,syscall)
-
-k8-y                      += ../../x86_64/kernel/k8.o
-stacktrace-y		  += ../../x86_64/kernel/stacktrace.o
-
diff --git a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile
deleted file mode 100644
index 7f7be01..0000000
--- a/arch/i386/kernel/acpi/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-obj-$(CONFIG_ACPI)		+= boot.o
-ifneq ($(CONFIG_PCI),)
-obj-$(CONFIG_X86_IO_APIC)	+= earlyquirk.o
-endif
-obj-$(CONFIG_ACPI_SLEEP)	+= sleep.o wakeup.o
-
-ifneq ($(CONFIG_ACPI_PROCESSOR),)
-obj-y				+= cstate.o processor.o
-endif
-
diff --git a/arch/i386/kernel/early_printk.c b/arch/i386/kernel/early_printk.c
deleted file mode 100644
index 92f812b..0000000
--- a/arch/i386/kernel/early_printk.c
+++ /dev/null
@@ -1,2 +0,0 @@
-
-#include "../../x86_64/kernel/early_printk.c"
diff --git a/arch/i386/kernel/tsc_sync.c b/arch/i386/kernel/tsc_sync.c
deleted file mode 100644
index 1242462..0000000
--- a/arch/i386/kernel/tsc_sync.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../x86_64/kernel/tsc_sync.c"
diff --git a/arch/i386/lib/Makefile b/arch/i386/lib/Makefile
deleted file mode 100644
index 4d105fd..0000000
--- a/arch/i386/lib/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Makefile for i386-specific library files..
-#
-
-
-lib-y = checksum.o delay.o usercopy.o getuser.o putuser.o memcpy.o strstr.o \
-	bitops.o semaphore.o string.o
-
-lib-$(CONFIG_X86_USE_3DNOW) += mmx.o
-
-obj-$(CONFIG_SMP)	+= msr-on-cpu.o
diff --git a/arch/i386/mach-generic/Makefile b/arch/i386/mach-generic/Makefile
deleted file mode 100644
index 6914485..0000000
--- a/arch/i386/mach-generic/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Makefile for the generic architecture
-#
-
-EXTRA_CFLAGS	:= -Iarch/i386/kernel
-
-obj-y				:= probe.o summit.o bigsmp.o es7000.o default.o ../mach-es7000/
diff --git a/arch/i386/mm/Makefile b/arch/i386/mm/Makefile
deleted file mode 100644
index 80908b5..0000000
--- a/arch/i386/mm/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile for the linux i386-specific parts of the memory manager.
-#
-
-obj-y	:= init.o pgtable.o fault.o ioremap.o extable.o pageattr.o mmap.o
-
-obj-$(CONFIG_NUMA) += discontig.o
-obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
-obj-$(CONFIG_HIGHMEM) += highmem.o
-obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap.o
diff --git a/arch/ia64/ia32/audit.c b/arch/ia64/ia32/audit.c
index 8850fe4..5e901c7 100644
--- a/arch/ia64/ia32/audit.c
+++ b/arch/ia64/ia32/audit.c
@@ -1,4 +1,4 @@
-#include <asm-i386/unistd.h>
+#include <asm-x86/unistd_32.h>
 
 unsigned ia32_dir_class[] = {
 #include <asm-generic/audit_dir_write.h>
diff --git a/arch/um/sys-i386/sys_call_table.S b/arch/um/sys-i386/sys_call_table.S
index 2497554..12d4148 100644
--- a/arch/um/sys-i386/sys_call_table.S
+++ b/arch/um/sys-i386/sys_call_table.S
@@ -9,4 +9,4 @@
 
 #define old_mmap old_mmap_i386
 
-#include "../../i386/kernel/syscall_table.S"
+#include "../../x86/kernel/syscall_table_32.S"
diff --git a/arch/um/sys-x86_64/syscall_table.c b/arch/um/sys-x86_64/syscall_table.c
index 5133988..71b2ae4 100644
--- a/arch/um/sys-x86_64/syscall_table.c
+++ b/arch/um/sys-x86_64/syscall_table.c
@@ -36,7 +36,7 @@
 
 #define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ;
 #undef _ASM_X86_64_UNISTD_H_
-#include <asm-x86_64/unistd.h>
+#include <asm-x86/unistd_64.h>
 
 #undef __SYSCALL
 #define __SYSCALL(nr, sym) [ nr ] = sym,
@@ -49,5 +49,5 @@
 sys_call_ptr_t sys_call_table[UM_NR_syscall_max+1] __cacheline_aligned = {
 	/* Smells like a like a compiler bug -- it doesn't work when the & below is removed. */
 	[0 ... UM_NR_syscall_max] = &sys_ni_syscall,
-#include <asm-x86_64/unistd.h>
+#include <asm-x86/unistd_64.h>
 };
diff --git a/arch/i386/boot/.gitignore b/arch/x86/boot/.gitignore
similarity index 100%
rename from arch/i386/boot/.gitignore
rename to arch/x86/boot/.gitignore
diff --git a/arch/i386/boot/Makefile b/arch/x86/boot/Makefile
similarity index 99%
rename from arch/i386/boot/Makefile
rename to arch/x86/boot/Makefile
index 93386a4..cb1035f 100644
--- a/arch/i386/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -1,5 +1,5 @@
 #
-# arch/i386/boot/Makefile
+# arch/x86/boot/Makefile
 #
 # 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
diff --git a/arch/i386/boot/a20.c b/arch/x86/boot/a20.c
similarity index 100%
rename from arch/i386/boot/a20.c
rename to arch/x86/boot/a20.c
diff --git a/arch/i386/boot/apm.c b/arch/x86/boot/apm.c
similarity index 100%
rename from arch/i386/boot/apm.c
rename to arch/x86/boot/apm.c
diff --git a/arch/i386/boot/bitops.h b/arch/x86/boot/bitops.h
similarity index 100%
rename from arch/i386/boot/bitops.h
rename to arch/x86/boot/bitops.h
diff --git a/arch/i386/boot/boot.h b/arch/x86/boot/boot.h
similarity index 100%
rename from arch/i386/boot/boot.h
rename to arch/x86/boot/boot.h
diff --git a/arch/i386/boot/cmdline.c b/arch/x86/boot/cmdline.c
similarity index 100%
rename from arch/i386/boot/cmdline.c
rename to arch/x86/boot/cmdline.c
diff --git a/arch/i386/boot/code16gcc.h b/arch/x86/boot/code16gcc.h
similarity index 100%
rename from arch/i386/boot/code16gcc.h
rename to arch/x86/boot/code16gcc.h
diff --git a/arch/i386/boot/compressed/.gitignore b/arch/x86/boot/compressed/.gitignore
similarity index 100%
rename from arch/i386/boot/compressed/.gitignore
rename to arch/x86/boot/compressed/.gitignore
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
new file mode 100644
index 0000000..52c1db8
--- /dev/null
+++ b/arch/x86/boot/compressed/Makefile
@@ -0,0 +1,5 @@
+ifeq ($(CONFIG_X86_32),y)
+include ${srctree}/arch/x86/boot/compressed/Makefile_32
+else
+include ${srctree}/arch/x86/boot/compressed/Makefile_64
+endif
diff --git a/arch/i386/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile_32
similarity index 80%
rename from arch/i386/boot/compressed/Makefile
rename to arch/x86/boot/compressed/Makefile_32
index 189fa1d..22613c6 100644
--- a/arch/i386/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile_32
@@ -1,10 +1,10 @@
 #
-# linux/arch/i386/boot/compressed/Makefile
+# linux/arch/x86/boot/compressed/Makefile
 #
 # create a compressed vmlinux image from the original vmlinux
 #
 
-targets		:= vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o \
+targets		:= vmlinux vmlinux.bin vmlinux.bin.gz head_32.o misc_32.o piggy.o \
 			vmlinux.bin.all vmlinux.relocs
 EXTRA_AFLAGS	:= -traditional
 
@@ -17,7 +17,7 @@
 	   $(call cc-option,-fno-stack-protector)
 LDFLAGS := -m elf_i386
 
-$(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
+$(obj)/vmlinux: $(src)/vmlinux_32.lds $(obj)/head_32.o $(obj)/misc_32.o $(obj)/piggy.o FORCE
 	$(call if_changed,ld)
 	@:
 
@@ -46,5 +46,5 @@
 
 LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T
 
-$(obj)/piggy.o: $(src)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
+$(obj)/piggy.o: $(src)/vmlinux_32.scr $(obj)/vmlinux.bin.gz FORCE
 	$(call if_changed,ld)
diff --git a/arch/x86_64/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile_64
similarity index 67%
rename from arch/x86_64/boot/compressed/Makefile
rename to arch/x86/boot/compressed/Makefile_64
index 877c0bd..dc6b338 100644
--- a/arch/x86_64/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile_64
@@ -1,10 +1,10 @@
 #
-# linux/arch/x86_64/boot/compressed/Makefile
+# linux/arch/x86/boot/compressed/Makefile
 #
 # create a compressed vmlinux image from the original vmlinux
 #
 
-targets		:= vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
+targets		:= vmlinux vmlinux.bin vmlinux.bin.gz head_64.o misc_64.o piggy.o
 
 CFLAGS := -m64 -D__KERNEL__ $(LINUXINCLUDE) -O2  \
 	  -fno-strict-aliasing -fPIC -mcmodel=small \
@@ -14,7 +14,7 @@
 LDFLAGS := -m elf_x86_64
 
 LDFLAGS_vmlinux := -T
-$(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
+$(obj)/vmlinux: $(src)/vmlinux_64.lds $(obj)/head_64.o $(obj)/misc_64.o $(obj)/piggy.o FORCE
 	$(call if_changed,ld)
 	@:
 
@@ -26,5 +26,5 @@
 
 LDFLAGS_piggy.o := -r --format binary --oformat elf64-x86-64 -T
 
-$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
+$(obj)/piggy.o: $(obj)/vmlinux_64.scr $(obj)/vmlinux.bin.gz FORCE
 	$(call if_changed,ld)
diff --git a/arch/i386/boot/compressed/head.S b/arch/x86/boot/compressed/head_32.S
similarity index 100%
rename from arch/i386/boot/compressed/head.S
rename to arch/x86/boot/compressed/head_32.S
diff --git a/arch/x86_64/boot/compressed/head.S b/arch/x86/boot/compressed/head_64.S
similarity index 98%
rename from arch/x86_64/boot/compressed/head.S
rename to arch/x86/boot/compressed/head_64.S
index 9fd8030..4946764 100644
--- a/arch/x86_64/boot/compressed/head.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -174,7 +174,7 @@
 	hlt
 	jmp     1b
 
-#include "../../kernel/verify_cpu.S"
+#include "../../kernel/verify_cpu_64.S"
 
 	/* Be careful here startup_64 needs to be at a predictable
 	 * address so I can export it in an ELF header.  Bootloaders
diff --git a/arch/i386/boot/compressed/misc.c b/arch/x86/boot/compressed/misc_32.c
similarity index 100%
rename from arch/i386/boot/compressed/misc.c
rename to arch/x86/boot/compressed/misc_32.c
diff --git a/arch/x86_64/boot/compressed/misc.c b/arch/x86/boot/compressed/misc_64.c
similarity index 100%
rename from arch/x86_64/boot/compressed/misc.c
rename to arch/x86/boot/compressed/misc_64.c
diff --git a/arch/i386/boot/compressed/relocs.c b/arch/x86/boot/compressed/relocs.c
similarity index 100%
rename from arch/i386/boot/compressed/relocs.c
rename to arch/x86/boot/compressed/relocs.c
diff --git a/arch/i386/boot/compressed/vmlinux.lds b/arch/x86/boot/compressed/vmlinux_32.lds
similarity index 100%
rename from arch/i386/boot/compressed/vmlinux.lds
rename to arch/x86/boot/compressed/vmlinux_32.lds
diff --git a/arch/i386/boot/compressed/vmlinux.scr b/arch/x86/boot/compressed/vmlinux_32.scr
similarity index 100%
rename from arch/i386/boot/compressed/vmlinux.scr
rename to arch/x86/boot/compressed/vmlinux_32.scr
diff --git a/arch/x86_64/boot/compressed/vmlinux.lds b/arch/x86/boot/compressed/vmlinux_64.lds
similarity index 100%
rename from arch/x86_64/boot/compressed/vmlinux.lds
rename to arch/x86/boot/compressed/vmlinux_64.lds
diff --git a/arch/x86_64/boot/compressed/vmlinux.scr b/arch/x86/boot/compressed/vmlinux_64.scr
similarity index 100%
rename from arch/x86_64/boot/compressed/vmlinux.scr
rename to arch/x86/boot/compressed/vmlinux_64.scr
diff --git a/arch/i386/boot/copy.S b/arch/x86/boot/copy.S
similarity index 100%
rename from arch/i386/boot/copy.S
rename to arch/x86/boot/copy.S
diff --git a/arch/i386/boot/cpu.c b/arch/x86/boot/cpu.c
similarity index 100%
rename from arch/i386/boot/cpu.c
rename to arch/x86/boot/cpu.c
diff --git a/arch/i386/boot/cpucheck.c b/arch/x86/boot/cpucheck.c
similarity index 100%
rename from arch/i386/boot/cpucheck.c
rename to arch/x86/boot/cpucheck.c
diff --git a/arch/i386/boot/edd.c b/arch/x86/boot/edd.c
similarity index 100%
rename from arch/i386/boot/edd.c
rename to arch/x86/boot/edd.c
diff --git a/arch/i386/boot/header.S b/arch/x86/boot/header.S
similarity index 100%
rename from arch/i386/boot/header.S
rename to arch/x86/boot/header.S
diff --git a/arch/i386/boot/install.sh b/arch/x86/boot/install.sh
similarity index 100%
rename from arch/i386/boot/install.sh
rename to arch/x86/boot/install.sh
diff --git a/arch/i386/boot/main.c b/arch/x86/boot/main.c
similarity index 100%
rename from arch/i386/boot/main.c
rename to arch/x86/boot/main.c
diff --git a/arch/i386/boot/mca.c b/arch/x86/boot/mca.c
similarity index 100%
rename from arch/i386/boot/mca.c
rename to arch/x86/boot/mca.c
diff --git a/arch/i386/boot/memory.c b/arch/x86/boot/memory.c
similarity index 100%
rename from arch/i386/boot/memory.c
rename to arch/x86/boot/memory.c
diff --git a/arch/i386/boot/mtools.conf.in b/arch/x86/boot/mtools.conf.in
similarity index 100%
rename from arch/i386/boot/mtools.conf.in
rename to arch/x86/boot/mtools.conf.in
diff --git a/arch/i386/boot/pm.c b/arch/x86/boot/pm.c
similarity index 100%
rename from arch/i386/boot/pm.c
rename to arch/x86/boot/pm.c
diff --git a/arch/i386/boot/pmjump.S b/arch/x86/boot/pmjump.S
similarity index 100%
rename from arch/i386/boot/pmjump.S
rename to arch/x86/boot/pmjump.S
diff --git a/arch/i386/boot/printf.c b/arch/x86/boot/printf.c
similarity index 100%
rename from arch/i386/boot/printf.c
rename to arch/x86/boot/printf.c
diff --git a/arch/i386/boot/setup.ld b/arch/x86/boot/setup.ld
similarity index 100%
rename from arch/i386/boot/setup.ld
rename to arch/x86/boot/setup.ld
diff --git a/arch/i386/boot/string.c b/arch/x86/boot/string.c
similarity index 100%
rename from arch/i386/boot/string.c
rename to arch/x86/boot/string.c
diff --git a/arch/i386/boot/tools/.gitignore b/arch/x86/boot/tools/.gitignore
similarity index 100%
rename from arch/i386/boot/tools/.gitignore
rename to arch/x86/boot/tools/.gitignore
diff --git a/arch/i386/boot/tools/build.c b/arch/x86/boot/tools/build.c
similarity index 100%
rename from arch/i386/boot/tools/build.c
rename to arch/x86/boot/tools/build.c
diff --git a/arch/i386/boot/tty.c b/arch/x86/boot/tty.c
similarity index 100%
rename from arch/i386/boot/tty.c
rename to arch/x86/boot/tty.c
diff --git a/arch/i386/boot/version.c b/arch/x86/boot/version.c
similarity index 100%
rename from arch/i386/boot/version.c
rename to arch/x86/boot/version.c
diff --git a/arch/i386/boot/vesa.h b/arch/x86/boot/vesa.h
similarity index 100%
rename from arch/i386/boot/vesa.h
rename to arch/x86/boot/vesa.h
diff --git a/arch/i386/boot/video-bios.c b/arch/x86/boot/video-bios.c
similarity index 100%
rename from arch/i386/boot/video-bios.c
rename to arch/x86/boot/video-bios.c
diff --git a/arch/i386/boot/video-vesa.c b/arch/x86/boot/video-vesa.c
similarity index 100%
rename from arch/i386/boot/video-vesa.c
rename to arch/x86/boot/video-vesa.c
diff --git a/arch/i386/boot/video-vga.c b/arch/x86/boot/video-vga.c
similarity index 100%
rename from arch/i386/boot/video-vga.c
rename to arch/x86/boot/video-vga.c
diff --git a/arch/i386/boot/video.c b/arch/x86/boot/video.c
similarity index 100%
rename from arch/i386/boot/video.c
rename to arch/x86/boot/video.c
diff --git a/arch/i386/boot/video.h b/arch/x86/boot/video.h
similarity index 100%
rename from arch/i386/boot/video.h
rename to arch/x86/boot/video.h
diff --git a/arch/i386/boot/voyager.c b/arch/x86/boot/voyager.c
similarity index 100%
rename from arch/i386/boot/voyager.c
rename to arch/x86/boot/voyager.c
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
new file mode 100644
index 0000000..18dcdc6
--- /dev/null
+++ b/arch/x86/crypto/Makefile
@@ -0,0 +1,5 @@
+ifeq ($(CONFIG_X86_32),y)
+include ${srctree}/arch/x86/crypto/Makefile_32
+else
+include ${srctree}/arch/x86/crypto/Makefile_64
+endif
diff --git a/arch/x86/crypto/Makefile_32 b/arch/x86/crypto/Makefile_32
new file mode 100644
index 0000000..2d873a2
--- /dev/null
+++ b/arch/x86/crypto/Makefile_32
@@ -0,0 +1,12 @@
+# 
+# x86/crypto/Makefile 
+# 
+# Arch-specific CryptoAPI modules.
+# 
+
+obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
+obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o
+
+aes-i586-y := aes-i586-asm_32.o aes_32.o
+twofish-i586-y := twofish-i586-asm_32.o twofish_32.o
+
diff --git a/arch/x86/crypto/Makefile_64 b/arch/x86/crypto/Makefile_64
new file mode 100644
index 0000000..b408962
--- /dev/null
+++ b/arch/x86/crypto/Makefile_64
@@ -0,0 +1,12 @@
+# 
+# x86/crypto/Makefile 
+# 
+# Arch-specific CryptoAPI modules.
+# 
+
+obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o
+obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o
+
+aes-x86_64-y := aes-x86_64-asm_64.o aes_64.o
+twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_64.o
+
diff --git a/arch/i386/crypto/aes-i586-asm.S b/arch/x86/crypto/aes-i586-asm_32.S
similarity index 100%
rename from arch/i386/crypto/aes-i586-asm.S
rename to arch/x86/crypto/aes-i586-asm_32.S
diff --git a/arch/x86_64/crypto/aes-x86_64-asm.S b/arch/x86/crypto/aes-x86_64-asm_64.S
similarity index 100%
rename from arch/x86_64/crypto/aes-x86_64-asm.S
rename to arch/x86/crypto/aes-x86_64-asm_64.S
diff --git a/arch/i386/crypto/aes.c b/arch/x86/crypto/aes_32.c
similarity index 100%
rename from arch/i386/crypto/aes.c
rename to arch/x86/crypto/aes_32.c
diff --git a/arch/x86_64/crypto/aes.c b/arch/x86/crypto/aes_64.c
similarity index 100%
rename from arch/x86_64/crypto/aes.c
rename to arch/x86/crypto/aes_64.c
diff --git a/arch/i386/crypto/twofish-i586-asm.S b/arch/x86/crypto/twofish-i586-asm_32.S
similarity index 100%
rename from arch/i386/crypto/twofish-i586-asm.S
rename to arch/x86/crypto/twofish-i586-asm_32.S
diff --git a/arch/x86_64/crypto/twofish-x86_64-asm.S b/arch/x86/crypto/twofish-x86_64-asm_64.S
similarity index 100%
rename from arch/x86_64/crypto/twofish-x86_64-asm.S
rename to arch/x86/crypto/twofish-x86_64-asm_64.S
diff --git a/arch/i386/crypto/twofish.c b/arch/x86/crypto/twofish_32.c
similarity index 100%
rename from arch/i386/crypto/twofish.c
rename to arch/x86/crypto/twofish_32.c
diff --git a/arch/x86_64/crypto/twofish.c b/arch/x86/crypto/twofish_64.c
similarity index 100%
rename from arch/x86_64/crypto/twofish.c
rename to arch/x86/crypto/twofish_64.c
diff --git a/arch/x86_64/ia32/Makefile b/arch/x86/ia32/Makefile
similarity index 100%
rename from arch/x86_64/ia32/Makefile
rename to arch/x86/ia32/Makefile
diff --git a/arch/x86_64/ia32/audit.c b/arch/x86/ia32/audit.c
similarity index 95%
rename from arch/x86_64/ia32/audit.c
rename to arch/x86/ia32/audit.c
index 8850fe4..91b7b59 100644
--- a/arch/x86_64/ia32/audit.c
+++ b/arch/x86/ia32/audit.c
@@ -1,4 +1,4 @@
-#include <asm-i386/unistd.h>
+#include <asm/unistd_32.h>
 
 unsigned ia32_dir_class[] = {
 #include <asm-generic/audit_dir_write.h>
diff --git a/arch/x86_64/ia32/fpu32.c b/arch/x86/ia32/fpu32.c
similarity index 100%
rename from arch/x86_64/ia32/fpu32.c
rename to arch/x86/ia32/fpu32.c
diff --git a/arch/x86_64/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c
similarity index 100%
rename from arch/x86_64/ia32/ia32_aout.c
rename to arch/x86/ia32/ia32_aout.c
diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86/ia32/ia32_binfmt.c
similarity index 100%
rename from arch/x86_64/ia32/ia32_binfmt.c
rename to arch/x86/ia32/ia32_binfmt.c
diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
similarity index 100%
rename from arch/x86_64/ia32/ia32_signal.c
rename to arch/x86/ia32/ia32_signal.c
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
similarity index 100%
rename from arch/x86_64/ia32/ia32entry.S
rename to arch/x86/ia32/ia32entry.S
diff --git a/arch/x86_64/ia32/ipc32.c b/arch/x86/ia32/ipc32.c
similarity index 98%
rename from arch/x86_64/ia32/ipc32.c
rename to arch/x86/ia32/ipc32.c
index 369151d..2e1869e 100644
--- a/arch/x86_64/ia32/ipc32.c
+++ b/arch/x86/ia32/ipc32.c
@@ -9,7 +9,7 @@
 #include <linux/ipc.h>
 #include <linux/compat.h>
 
-#include <asm-i386/ipc.h>
+#include <asm/ipc.h>
 
 asmlinkage long
 sys32_ipc(u32 call, int first, int second, int third,
diff --git a/arch/x86_64/ia32/mmap32.c b/arch/x86/ia32/mmap32.c
similarity index 100%
rename from arch/x86_64/ia32/mmap32.c
rename to arch/x86/ia32/mmap32.c
diff --git a/arch/x86_64/ia32/ptrace32.c b/arch/x86/ia32/ptrace32.c
similarity index 100%
rename from arch/x86_64/ia32/ptrace32.c
rename to arch/x86/ia32/ptrace32.c
diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
similarity index 100%
rename from arch/x86_64/ia32/sys_ia32.c
rename to arch/x86/ia32/sys_ia32.c
diff --git a/arch/x86_64/ia32/syscall32.c b/arch/x86/ia32/syscall32.c
similarity index 100%
rename from arch/x86_64/ia32/syscall32.c
rename to arch/x86/ia32/syscall32.c
diff --git a/arch/x86_64/ia32/syscall32_syscall.S b/arch/x86/ia32/syscall32_syscall.S
similarity index 73%
rename from arch/x86_64/ia32/syscall32_syscall.S
rename to arch/x86/ia32/syscall32_syscall.S
index 8f8271b..933f0f0 100644
--- a/arch/x86_64/ia32/syscall32_syscall.S
+++ b/arch/x86/ia32/syscall32_syscall.S
@@ -6,12 +6,12 @@
 	.globl syscall32_syscall_end
 
 syscall32_syscall:
-	.incbin "arch/x86_64/ia32/vsyscall-syscall.so"
+	.incbin "arch/x86/ia32/vsyscall-syscall.so"
 syscall32_syscall_end:
 
 	.globl syscall32_sysenter
 	.globl syscall32_sysenter_end
 
 syscall32_sysenter:
-	.incbin "arch/x86_64/ia32/vsyscall-sysenter.so"
+	.incbin "arch/x86/ia32/vsyscall-sysenter.so"
 syscall32_sysenter_end:
diff --git a/arch/x86_64/ia32/tls32.c b/arch/x86/ia32/tls32.c
similarity index 100%
rename from arch/x86_64/ia32/tls32.c
rename to arch/x86/ia32/tls32.c
diff --git a/arch/x86_64/ia32/vsyscall-sigreturn.S b/arch/x86/ia32/vsyscall-sigreturn.S
similarity index 98%
rename from arch/x86_64/ia32/vsyscall-sigreturn.S
rename to arch/x86/ia32/vsyscall-sigreturn.S
index 1384367..b383be0 100644
--- a/arch/x86_64/ia32/vsyscall-sigreturn.S
+++ b/arch/x86/ia32/vsyscall-sigreturn.S
@@ -139,5 +139,5 @@
 	.align 4
 .LENDFDE3:
 
-#include "../../i386/kernel/vsyscall-note.S"
+#include "../../x86/kernel/vsyscall-note_32.S"
 
diff --git a/arch/x86_64/ia32/vsyscall-syscall.S b/arch/x86/ia32/vsyscall-syscall.S
similarity index 100%
rename from arch/x86_64/ia32/vsyscall-syscall.S
rename to arch/x86/ia32/vsyscall-syscall.S
diff --git a/arch/x86_64/ia32/vsyscall-sysenter.S b/arch/x86/ia32/vsyscall-sysenter.S
similarity index 100%
rename from arch/x86_64/ia32/vsyscall-sysenter.S
rename to arch/x86/ia32/vsyscall-sysenter.S
diff --git a/arch/x86_64/ia32/vsyscall.lds b/arch/x86/ia32/vsyscall.lds
similarity index 100%
rename from arch/x86_64/ia32/vsyscall.lds
rename to arch/x86/ia32/vsyscall.lds
diff --git a/arch/i386/kernel/.gitignore b/arch/x86/kernel/.gitignore
similarity index 100%
rename from arch/i386/kernel/.gitignore
rename to arch/x86/kernel/.gitignore
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
new file mode 100644
index 0000000..45855c9
--- /dev/null
+++ b/arch/x86/kernel/Makefile
@@ -0,0 +1,5 @@
+ifeq ($(CONFIG_X86_32),y)
+include ${srctree}/arch/x86/kernel/Makefile_32
+else
+include ${srctree}/arch/x86/kernel/Makefile_64
+endif
diff --git a/arch/x86/kernel/Makefile_32 b/arch/x86/kernel/Makefile_32
new file mode 100644
index 0000000..c624193
--- /dev/null
+++ b/arch/x86/kernel/Makefile_32
@@ -0,0 +1,86 @@
+#
+# Makefile for the linux kernel.
+#
+
+extra-y := head_32.o init_task_32.o vmlinux.lds
+
+obj-y	:= process_32.o signal_32.o entry_32.o traps_32.o irq_32.o \
+		ptrace_32.o time_32.o ioport_32.o ldt_32.o setup_32.o i8259_32.o sys_i386_32.o \
+		pci-dma_32.o i386_ksyms_32.o i387_32.o bootflag.o e820_32.o\
+		quirks.o i8237.o topology.o alternative.o i8253_32.o tsc_32.o
+
+obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
+obj-y				+= cpu/
+obj-y				+= acpi/
+obj-$(CONFIG_X86_BIOS_REBOOT)	+= reboot_32.o
+obj-$(CONFIG_MCA)		+= mca_32.o
+obj-$(CONFIG_X86_MSR)		+= msr.o
+obj-$(CONFIG_X86_CPUID)		+= cpuid.o
+obj-$(CONFIG_MICROCODE)		+= microcode.o
+obj-$(CONFIG_APM)		+= apm_32.o
+obj-$(CONFIG_X86_SMP)		+= smp_32.o smpboot_32.o tsc_sync.o
+obj-$(CONFIG_SMP)		+= smpcommon_32.o
+obj-$(CONFIG_X86_TRAMPOLINE)	+= trampoline_32.o
+obj-$(CONFIG_X86_MPPARSE)	+= mpparse_32.o
+obj-$(CONFIG_X86_LOCAL_APIC)	+= apic_32.o nmi_32.o
+obj-$(CONFIG_X86_IO_APIC)	+= io_apic_32.o
+obj-$(CONFIG_X86_REBOOTFIXUPS)	+= reboot_fixups_32.o
+obj-$(CONFIG_KEXEC)		+= machine_kexec_32.o relocate_kernel_32.o crash_32.o
+obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_32.o
+obj-$(CONFIG_X86_NUMAQ)		+= numaq_32.o
+obj-$(CONFIG_X86_SUMMIT_NUMA)	+= summit_32.o
+obj-$(CONFIG_KPROBES)		+= kprobes_32.o
+obj-$(CONFIG_MODULES)		+= module_32.o
+obj-y				+= sysenter_32.o vsyscall_32.o
+obj-$(CONFIG_ACPI_SRAT) 	+= srat_32.o
+obj-$(CONFIG_EFI) 		+= efi_32.o efi_stub_32.o
+obj-$(CONFIG_DOUBLEFAULT) 	+= doublefault_32.o
+obj-$(CONFIG_VM86)		+= vm86_32.o
+obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
+obj-$(CONFIG_HPET_TIMER) 	+= hpet_32.o
+obj-$(CONFIG_K8_NB)		+= k8.o
+obj-$(CONFIG_MGEODE_LX)		+= geode_32.o
+
+obj-$(CONFIG_VMI)		+= vmi_32.o vmiclock_32.o
+obj-$(CONFIG_PARAVIRT)		+= paravirt_32.o
+obj-y				+= pcspeaker.o
+
+obj-$(CONFIG_SCx200)		+= scx200_32.o
+
+# vsyscall_32.o contains the vsyscall DSO images as __initdata.
+# We must build both images before we can assemble it.
+# Note: kbuild does not track this dependency due to usage of .incbin
+$(obj)/vsyscall_32.o: $(obj)/vsyscall-int80_32.so $(obj)/vsyscall-sysenter_32.so
+targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so)
+targets += vsyscall-note_32.o vsyscall_32.lds
+
+# The DSO images are built using a special linker script.
+quiet_cmd_syscall = SYSCALL $@
+      cmd_syscall = $(CC) -m elf_i386 -nostdlib $(SYSCFLAGS_$(@F)) \
+		          -Wl,-T,$(filter-out FORCE,$^) -o $@
+
+export CPPFLAGS_vsyscall_32.lds += -P -C -U$(ARCH)
+
+vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1 \
+		 $(call ld-option, -Wl$(comma)--hash-style=sysv)
+SYSCFLAGS_vsyscall-sysenter_32.so	= $(vsyscall-flags)
+SYSCFLAGS_vsyscall-int80_32.so	= $(vsyscall-flags)
+
+$(obj)/vsyscall-int80_32.so $(obj)/vsyscall-sysenter_32.so: \
+$(obj)/vsyscall-%.so: $(src)/vsyscall_32.lds \
+		      $(obj)/vsyscall-%.o $(obj)/vsyscall-note_32.o FORCE
+	$(call if_changed,syscall)
+
+# We also create a special relocatable object that should mirror the symbol
+# table and layout of the linked DSO.  With ld -R we can then refer to
+# these symbols in the kernel code rather than hand-coded addresses.
+extra-y += vsyscall-syms.o
+$(obj)/built-in.o: $(obj)/vsyscall-syms.o
+$(obj)/built-in.o: ld_flags += -R $(obj)/vsyscall-syms.o
+
+SYSCFLAGS_vsyscall-syms.o = -r
+$(obj)/vsyscall-syms.o: $(src)/vsyscall_32.lds \
+			$(obj)/vsyscall-sysenter_32.o $(obj)/vsyscall-note_32.o FORCE
+	$(call if_changed,syscall)
+
+
diff --git a/arch/x86/kernel/Makefile_64 b/arch/x86/kernel/Makefile_64
new file mode 100644
index 0000000..3ab017a
--- /dev/null
+++ b/arch/x86/kernel/Makefile_64
@@ -0,0 +1,54 @@
+#
+# Makefile for the linux kernel.
+#
+
+extra-y 	:= head_64.o head64.o init_task_64.o vmlinux.lds
+EXTRA_AFLAGS	:= -traditional
+obj-y	:= process_64.o signal_64.o entry_64.o traps_64.o irq_64.o \
+		ptrace_64.o time_64.o ioport_64.o ldt_64.o setup_64.o i8259_64.o sys_x86_64.o \
+		x8664_ksyms_64.o i387_64.o syscall_64.o vsyscall_64.o \
+		setup64.o bootflag.o e820_64.o reboot_64.o quirks.o i8237.o \
+		pci-dma_64.o pci-nommu_64.o alternative.o hpet_64.o tsc_64.o bugs_64.o \
+		perfctr-watchdog.o
+
+obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
+obj-$(CONFIG_X86_MCE)		+= mce_64.o therm_throt.o
+obj-$(CONFIG_X86_MCE_INTEL)	+= mce_intel_64.o
+obj-$(CONFIG_X86_MCE_AMD)	+= mce_amd_64.o
+obj-$(CONFIG_MTRR)		+= cpu/mtrr/
+obj-$(CONFIG_ACPI)		+= acpi/
+obj-$(CONFIG_X86_MSR)		+= msr.o
+obj-$(CONFIG_MICROCODE)		+= microcode.o
+obj-$(CONFIG_X86_CPUID)		+= cpuid.o
+obj-$(CONFIG_SMP)		+= smp_64.o smpboot_64.o trampoline_64.o tsc_sync.o
+obj-y				+= apic_64.o  nmi_64.o
+obj-y				+= io_apic_64.o mpparse_64.o genapic_64.o genapic_flat_64.o
+obj-$(CONFIG_KEXEC)		+= machine_kexec_64.o relocate_kernel_64.o crash_64.o
+obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_64.o
+obj-$(CONFIG_PM)		+= suspend_64.o
+obj-$(CONFIG_HIBERNATION)	+= suspend_asm_64.o
+obj-$(CONFIG_CPU_FREQ)		+= cpu/cpufreq/
+obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
+obj-$(CONFIG_IOMMU)		+= pci-gart_64.o aperture_64.o
+obj-$(CONFIG_CALGARY_IOMMU)	+= pci-calgary_64.o tce_64.o
+obj-$(CONFIG_SWIOTLB)		+= pci-swiotlb_64.o
+obj-$(CONFIG_KPROBES)		+= kprobes_64.o
+obj-$(CONFIG_X86_PM_TIMER)	+= pmtimer_64.o
+obj-$(CONFIG_X86_VSMP)		+= vsmp_64.o
+obj-$(CONFIG_K8_NB)		+= k8.o
+obj-$(CONFIG_AUDIT)		+= audit_64.o
+
+obj-$(CONFIG_MODULES)		+= module_64.o
+obj-$(CONFIG_PCI)		+= early-quirks_64.o
+
+obj-y				+= topology.o
+obj-y				+= intel_cacheinfo.o
+obj-y				+= addon_cpuid_features.o
+obj-y				+= pcspeaker.o
+
+CFLAGS_vsyscall_64.o		:= $(PROFILING) -g0
+
+therm_throt-y                   += cpu/mcheck/therm_throt.o
+intel_cacheinfo-y		+= cpu/intel_cacheinfo.o
+addon_cpuid_features-y		+= cpu/addon_cpuid_features.o
+perfctr-watchdog-y		+= cpu/perfctr-watchdog.o
diff --git a/arch/x86/kernel/acpi/Makefile b/arch/x86/kernel/acpi/Makefile
new file mode 100644
index 0000000..3d56719
--- /dev/null
+++ b/arch/x86/kernel/acpi/Makefile
@@ -0,0 +1,5 @@
+ifeq ($(CONFIG_X86_32),y)
+include ${srctree}/arch/x86/kernel/acpi/Makefile_32
+else
+include ${srctree}/arch/x86/kernel/acpi/Makefile_64
+endif
diff --git a/arch/x86/kernel/acpi/Makefile_32 b/arch/x86/kernel/acpi/Makefile_32
new file mode 100644
index 0000000..a4852a2
--- /dev/null
+++ b/arch/x86/kernel/acpi/Makefile_32
@@ -0,0 +1,10 @@
+obj-$(CONFIG_ACPI)		+= boot.o
+ifneq ($(CONFIG_PCI),)
+obj-$(CONFIG_X86_IO_APIC)	+= earlyquirk_32.o
+endif
+obj-$(CONFIG_ACPI_SLEEP)	+= sleep_32.o wakeup_32.o
+
+ifneq ($(CONFIG_ACPI_PROCESSOR),)
+obj-y				+= cstate.o processor.o
+endif
+
diff --git a/arch/x86/kernel/acpi/Makefile_64 b/arch/x86/kernel/acpi/Makefile_64
new file mode 100644
index 0000000..629425b
--- /dev/null
+++ b/arch/x86/kernel/acpi/Makefile_64
@@ -0,0 +1,7 @@
+obj-y			:= boot.o
+obj-$(CONFIG_ACPI_SLEEP)	+= sleep_64.o wakeup_64.o
+
+ifneq ($(CONFIG_ACPI_PROCESSOR),)
+obj-y			+= processor.o cstate.o
+endif
+
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
similarity index 100%
rename from arch/i386/kernel/acpi/boot.c
rename to arch/x86/kernel/acpi/boot.c
diff --git a/arch/i386/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c
similarity index 100%
rename from arch/i386/kernel/acpi/cstate.c
rename to arch/x86/kernel/acpi/cstate.c
diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/x86/kernel/acpi/earlyquirk_32.c
similarity index 100%
rename from arch/i386/kernel/acpi/earlyquirk.c
rename to arch/x86/kernel/acpi/earlyquirk_32.c
diff --git a/arch/i386/kernel/acpi/processor.c b/arch/x86/kernel/acpi/processor.c
similarity index 100%
rename from arch/i386/kernel/acpi/processor.c
rename to arch/x86/kernel/acpi/processor.c
diff --git a/arch/i386/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep_32.c
similarity index 100%
rename from arch/i386/kernel/acpi/sleep.c
rename to arch/x86/kernel/acpi/sleep_32.c
diff --git a/arch/x86_64/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep_64.c
similarity index 100%
rename from arch/x86_64/kernel/acpi/sleep.c
rename to arch/x86/kernel/acpi/sleep_64.c
diff --git a/arch/i386/kernel/acpi/wakeup.S b/arch/x86/kernel/acpi/wakeup_32.S
similarity index 100%
rename from arch/i386/kernel/acpi/wakeup.S
rename to arch/x86/kernel/acpi/wakeup_32.S
diff --git a/arch/x86_64/kernel/acpi/wakeup.S b/arch/x86/kernel/acpi/wakeup_64.S
similarity index 99%
rename from arch/x86_64/kernel/acpi/wakeup.S
rename to arch/x86/kernel/acpi/wakeup_64.S
index a06f2bc..8b4357e 100644
--- a/arch/x86_64/kernel/acpi/wakeup.S
+++ b/arch/x86/kernel/acpi/wakeup_64.S
@@ -269,7 +269,7 @@
 	movb    $0xbc,%al       ;  outb %al,$0x80
 	jmp no_longmode
 
-#include "../verify_cpu.S"
+#include "../verify_cpu_64.S"
 	
 /* This code uses an extended set of video mode numbers. These include:
  * Aliases for standard modes
diff --git a/arch/i386/kernel/alternative.c b/arch/x86/kernel/alternative.c
similarity index 100%
rename from arch/i386/kernel/alternative.c
rename to arch/x86/kernel/alternative.c
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86/kernel/aperture_64.c
similarity index 100%
rename from arch/x86_64/kernel/aperture.c
rename to arch/x86/kernel/aperture_64.c
diff --git a/arch/i386/kernel/apic.c b/arch/x86/kernel/apic_32.c
similarity index 100%
rename from arch/i386/kernel/apic.c
rename to arch/x86/kernel/apic_32.c
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86/kernel/apic_64.c
similarity index 100%
rename from arch/x86_64/kernel/apic.c
rename to arch/x86/kernel/apic_64.c
diff --git a/arch/i386/kernel/apm.c b/arch/x86/kernel/apm_32.c
similarity index 100%
rename from arch/i386/kernel/apm.c
rename to arch/x86/kernel/apm_32.c
diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
new file mode 100644
index 0000000..cfa82c8
--- /dev/null
+++ b/arch/x86/kernel/asm-offsets.c
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "asm-offsets_32.c"
+#else
+# include "asm-offsets_64.c"
+#endif
diff --git a/arch/i386/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets_32.c
similarity index 98%
rename from arch/i386/kernel/asm-offsets.c
rename to arch/x86/kernel/asm-offsets_32.c
index 7288ac8..8029742 100644
--- a/arch/i386/kernel/asm-offsets.c
+++ b/arch/x86/kernel/asm-offsets_32.c
@@ -10,7 +10,7 @@
 #include <linux/personality.h>
 #include <linux/suspend.h>
 #include <asm/ucontext.h>
-#include "sigframe.h"
+#include "sigframe_32.h"
 #include <asm/pgtable.h>
 #include <asm/fixmap.h>
 #include <asm/processor.h>
diff --git a/arch/x86_64/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets_64.c
similarity index 100%
rename from arch/x86_64/kernel/asm-offsets.c
rename to arch/x86/kernel/asm-offsets_64.c
diff --git a/arch/x86_64/kernel/audit.c b/arch/x86/kernel/audit_64.c
similarity index 100%
rename from arch/x86_64/kernel/audit.c
rename to arch/x86/kernel/audit_64.c
diff --git a/arch/i386/kernel/bootflag.c b/arch/x86/kernel/bootflag.c
similarity index 100%
rename from arch/i386/kernel/bootflag.c
rename to arch/x86/kernel/bootflag.c
diff --git a/arch/x86_64/kernel/bugs.c b/arch/x86/kernel/bugs_64.c
similarity index 100%
rename from arch/x86_64/kernel/bugs.c
rename to arch/x86/kernel/bugs_64.c
diff --git a/arch/i386/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
similarity index 100%
rename from arch/i386/kernel/cpu/Makefile
rename to arch/x86/kernel/cpu/Makefile
diff --git a/arch/i386/kernel/cpu/addon_cpuid_features.c b/arch/x86/kernel/cpu/addon_cpuid_features.c
similarity index 100%
rename from arch/i386/kernel/cpu/addon_cpuid_features.c
rename to arch/x86/kernel/cpu/addon_cpuid_features.c
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
similarity index 100%
rename from arch/i386/kernel/cpu/amd.c
rename to arch/x86/kernel/cpu/amd.c
diff --git a/arch/i386/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
similarity index 100%
rename from arch/i386/kernel/cpu/bugs.c
rename to arch/x86/kernel/cpu/bugs.c
diff --git a/arch/i386/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c
similarity index 100%
rename from arch/i386/kernel/cpu/centaur.c
rename to arch/x86/kernel/cpu/centaur.c
diff --git a/arch/i386/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
similarity index 100%
rename from arch/i386/kernel/cpu/common.c
rename to arch/x86/kernel/cpu/common.c
diff --git a/arch/i386/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h
similarity index 100%
rename from arch/i386/kernel/cpu/cpu.h
rename to arch/x86/kernel/cpu/cpu.h
diff --git a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/x86/kernel/cpu/cpufreq/Kconfig
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/Kconfig
rename to arch/x86/kernel/cpu/cpufreq/Kconfig
diff --git a/arch/i386/kernel/cpu/cpufreq/Makefile b/arch/x86/kernel/cpu/cpufreq/Makefile
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/Makefile
rename to arch/x86/kernel/cpu/cpufreq/Makefile
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
rename to arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
diff --git a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
rename to arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
diff --git a/arch/i386/kernel/cpu/cpufreq/e_powersaver.c b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/e_powersaver.c
rename to arch/x86/kernel/cpu/cpufreq/e_powersaver.c
diff --git a/arch/i386/kernel/cpu/cpufreq/elanfreq.c b/arch/x86/kernel/cpu/cpufreq/elanfreq.c
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/elanfreq.c
rename to arch/x86/kernel/cpu/cpufreq/elanfreq.c
diff --git a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
rename to arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/x86/kernel/cpu/cpufreq/longhaul.c
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/longhaul.c
rename to arch/x86/kernel/cpu/cpufreq/longhaul.c
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.h b/arch/x86/kernel/cpu/cpufreq/longhaul.h
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/longhaul.h
rename to arch/x86/kernel/cpu/cpufreq/longhaul.h
diff --git a/arch/i386/kernel/cpu/cpufreq/longrun.c b/arch/x86/kernel/cpu/cpufreq/longrun.c
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/longrun.c
rename to arch/x86/kernel/cpu/cpufreq/longrun.c
diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
rename to arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/powernow-k6.c
rename to arch/x86/kernel/cpu/cpufreq/powernow-k6.c
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/powernow-k7.c
rename to arch/x86/kernel/cpu/cpufreq/powernow-k7.c
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.h b/arch/x86/kernel/cpu/cpufreq/powernow-k7.h
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/powernow-k7.h
rename to arch/x86/kernel/cpu/cpufreq/powernow-k7.h
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/powernow-k8.c
rename to arch/x86/kernel/cpu/cpufreq/powernow-k8.c
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/powernow-k8.h
rename to arch/x86/kernel/cpu/cpufreq/powernow-k8.h
diff --git a/arch/i386/kernel/cpu/cpufreq/sc520_freq.c b/arch/x86/kernel/cpu/cpufreq/sc520_freq.c
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/sc520_freq.c
rename to arch/x86/kernel/cpu/cpufreq/sc520_freq.c
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
rename to arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
rename to arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
rename to arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
rename to arch/x86/kernel/cpu/cpufreq/speedstep-lib.h
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
similarity index 100%
rename from arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
rename to arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c
similarity index 100%
rename from arch/i386/kernel/cpu/cyrix.c
rename to arch/x86/kernel/cpu/cyrix.c
diff --git a/arch/i386/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
similarity index 100%
rename from arch/i386/kernel/cpu/intel.c
rename to arch/x86/kernel/cpu/intel.c
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
similarity index 100%
rename from arch/i386/kernel/cpu/intel_cacheinfo.c
rename to arch/x86/kernel/cpu/intel_cacheinfo.c
diff --git a/arch/i386/kernel/cpu/mcheck/Makefile b/arch/x86/kernel/cpu/mcheck/Makefile
similarity index 100%
rename from arch/i386/kernel/cpu/mcheck/Makefile
rename to arch/x86/kernel/cpu/mcheck/Makefile
diff --git a/arch/i386/kernel/cpu/mcheck/k7.c b/arch/x86/kernel/cpu/mcheck/k7.c
similarity index 100%
rename from arch/i386/kernel/cpu/mcheck/k7.c
rename to arch/x86/kernel/cpu/mcheck/k7.c
diff --git a/arch/i386/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
similarity index 100%
rename from arch/i386/kernel/cpu/mcheck/mce.c
rename to arch/x86/kernel/cpu/mcheck/mce.c
diff --git a/arch/i386/kernel/cpu/mcheck/mce.h b/arch/x86/kernel/cpu/mcheck/mce.h
similarity index 100%
rename from arch/i386/kernel/cpu/mcheck/mce.h
rename to arch/x86/kernel/cpu/mcheck/mce.h
diff --git a/arch/i386/kernel/cpu/mcheck/non-fatal.c b/arch/x86/kernel/cpu/mcheck/non-fatal.c
similarity index 100%
rename from arch/i386/kernel/cpu/mcheck/non-fatal.c
rename to arch/x86/kernel/cpu/mcheck/non-fatal.c
diff --git a/arch/i386/kernel/cpu/mcheck/p4.c b/arch/x86/kernel/cpu/mcheck/p4.c
similarity index 100%
rename from arch/i386/kernel/cpu/mcheck/p4.c
rename to arch/x86/kernel/cpu/mcheck/p4.c
diff --git a/arch/i386/kernel/cpu/mcheck/p5.c b/arch/x86/kernel/cpu/mcheck/p5.c
similarity index 100%
rename from arch/i386/kernel/cpu/mcheck/p5.c
rename to arch/x86/kernel/cpu/mcheck/p5.c
diff --git a/arch/i386/kernel/cpu/mcheck/p6.c b/arch/x86/kernel/cpu/mcheck/p6.c
similarity index 100%
rename from arch/i386/kernel/cpu/mcheck/p6.c
rename to arch/x86/kernel/cpu/mcheck/p6.c
diff --git a/arch/i386/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c
similarity index 100%
rename from arch/i386/kernel/cpu/mcheck/therm_throt.c
rename to arch/x86/kernel/cpu/mcheck/therm_throt.c
diff --git a/arch/i386/kernel/cpu/mcheck/winchip.c b/arch/x86/kernel/cpu/mcheck/winchip.c
similarity index 100%
rename from arch/i386/kernel/cpu/mcheck/winchip.c
rename to arch/x86/kernel/cpu/mcheck/winchip.c
diff --git a/arch/i386/kernel/cpu/mtrr/Makefile b/arch/x86/kernel/cpu/mtrr/Makefile
similarity index 100%
rename from arch/i386/kernel/cpu/mtrr/Makefile
rename to arch/x86/kernel/cpu/mtrr/Makefile
diff --git a/arch/i386/kernel/cpu/mtrr/amd.c b/arch/x86/kernel/cpu/mtrr/amd.c
similarity index 100%
rename from arch/i386/kernel/cpu/mtrr/amd.c
rename to arch/x86/kernel/cpu/mtrr/amd.c
diff --git a/arch/i386/kernel/cpu/mtrr/centaur.c b/arch/x86/kernel/cpu/mtrr/centaur.c
similarity index 100%
rename from arch/i386/kernel/cpu/mtrr/centaur.c
rename to arch/x86/kernel/cpu/mtrr/centaur.c
diff --git a/arch/i386/kernel/cpu/mtrr/cyrix.c b/arch/x86/kernel/cpu/mtrr/cyrix.c
similarity index 100%
rename from arch/i386/kernel/cpu/mtrr/cyrix.c
rename to arch/x86/kernel/cpu/mtrr/cyrix.c
diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
similarity index 100%
rename from arch/i386/kernel/cpu/mtrr/generic.c
rename to arch/x86/kernel/cpu/mtrr/generic.c
diff --git a/arch/i386/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c
similarity index 100%
rename from arch/i386/kernel/cpu/mtrr/if.c
rename to arch/x86/kernel/cpu/mtrr/if.c
diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
similarity index 100%
rename from arch/i386/kernel/cpu/mtrr/main.c
rename to arch/x86/kernel/cpu/mtrr/main.c
diff --git a/arch/i386/kernel/cpu/mtrr/mtrr.h b/arch/x86/kernel/cpu/mtrr/mtrr.h
similarity index 100%
rename from arch/i386/kernel/cpu/mtrr/mtrr.h
rename to arch/x86/kernel/cpu/mtrr/mtrr.h
diff --git a/arch/i386/kernel/cpu/mtrr/state.c b/arch/x86/kernel/cpu/mtrr/state.c
similarity index 97%
rename from arch/i386/kernel/cpu/mtrr/state.c
rename to arch/x86/kernel/cpu/mtrr/state.c
index c9014ca..49e20c2 100644
--- a/arch/i386/kernel/cpu/mtrr/state.c
+++ b/arch/x86/kernel/cpu/mtrr/state.c
@@ -3,7 +3,7 @@
 #include <asm/io.h>
 #include <asm/mtrr.h>
 #include <asm/msr.h>
-#include <asm-i386/processor-cyrix.h>
+#include <asm/processor-cyrix.h>
 #include "mtrr.h"
 
 
diff --git a/arch/i386/kernel/cpu/nexgen.c b/arch/x86/kernel/cpu/nexgen.c
similarity index 100%
rename from arch/i386/kernel/cpu/nexgen.c
rename to arch/x86/kernel/cpu/nexgen.c
diff --git a/arch/i386/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c
similarity index 100%
rename from arch/i386/kernel/cpu/perfctr-watchdog.c
rename to arch/x86/kernel/cpu/perfctr-watchdog.c
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
similarity index 100%
rename from arch/i386/kernel/cpu/proc.c
rename to arch/x86/kernel/cpu/proc.c
diff --git a/arch/i386/kernel/cpu/transmeta.c b/arch/x86/kernel/cpu/transmeta.c
similarity index 100%
rename from arch/i386/kernel/cpu/transmeta.c
rename to arch/x86/kernel/cpu/transmeta.c
diff --git a/arch/i386/kernel/cpu/umc.c b/arch/x86/kernel/cpu/umc.c
similarity index 100%
rename from arch/i386/kernel/cpu/umc.c
rename to arch/x86/kernel/cpu/umc.c
diff --git a/arch/x86_64/kernel/cpufreq/Kconfig b/arch/x86/kernel/cpufreq/Kconfig
similarity index 100%
rename from arch/x86_64/kernel/cpufreq/Kconfig
rename to arch/x86/kernel/cpufreq/Kconfig
diff --git a/arch/i386/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
similarity index 100%
rename from arch/i386/kernel/cpuid.c
rename to arch/x86/kernel/cpuid.c
diff --git a/arch/i386/kernel/crash.c b/arch/x86/kernel/crash_32.c
similarity index 100%
rename from arch/i386/kernel/crash.c
rename to arch/x86/kernel/crash_32.c
diff --git a/arch/x86_64/kernel/crash.c b/arch/x86/kernel/crash_64.c
similarity index 100%
rename from arch/x86_64/kernel/crash.c
rename to arch/x86/kernel/crash_64.c
diff --git a/arch/i386/kernel/crash_dump.c b/arch/x86/kernel/crash_dump_32.c
similarity index 100%
rename from arch/i386/kernel/crash_dump.c
rename to arch/x86/kernel/crash_dump_32.c
diff --git a/arch/x86_64/kernel/crash_dump.c b/arch/x86/kernel/crash_dump_64.c
similarity index 100%
rename from arch/x86_64/kernel/crash_dump.c
rename to arch/x86/kernel/crash_dump_64.c
diff --git a/arch/i386/kernel/doublefault.c b/arch/x86/kernel/doublefault_32.c
similarity index 100%
rename from arch/i386/kernel/doublefault.c
rename to arch/x86/kernel/doublefault_32.c
diff --git a/arch/i386/kernel/e820.c b/arch/x86/kernel/e820_32.c
similarity index 100%
rename from arch/i386/kernel/e820.c
rename to arch/x86/kernel/e820_32.c
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86/kernel/e820_64.c
similarity index 100%
rename from arch/x86_64/kernel/e820.c
rename to arch/x86/kernel/e820_64.c
diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86/kernel/early-quirks_64.c
similarity index 100%
rename from arch/x86_64/kernel/early-quirks.c
rename to arch/x86/kernel/early-quirks_64.c
diff --git a/arch/x86_64/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
similarity index 100%
rename from arch/x86_64/kernel/early_printk.c
rename to arch/x86/kernel/early_printk.c
diff --git a/arch/i386/kernel/efi.c b/arch/x86/kernel/efi_32.c
similarity index 100%
rename from arch/i386/kernel/efi.c
rename to arch/x86/kernel/efi_32.c
diff --git a/arch/i386/kernel/efi_stub.S b/arch/x86/kernel/efi_stub_32.S
similarity index 100%
rename from arch/i386/kernel/efi_stub.S
rename to arch/x86/kernel/efi_stub_32.S
diff --git a/arch/i386/kernel/entry.S b/arch/x86/kernel/entry_32.S
similarity index 99%
rename from arch/i386/kernel/entry.S
rename to arch/x86/kernel/entry_32.S
index a714d6b..290b7bc 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/x86/kernel/entry_32.S
@@ -1107,6 +1107,6 @@
 #endif	/* CONFIG_XEN */
 
 .section .rodata,"a"
-#include "syscall_table.S"
+#include "syscall_table_32.S"
 
 syscall_table_size=(.-sys_call_table)
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86/kernel/entry_64.S
similarity index 100%
rename from arch/x86_64/kernel/entry.S
rename to arch/x86/kernel/entry_64.S
diff --git a/arch/x86_64/kernel/genapic.c b/arch/x86/kernel/genapic_64.c
similarity index 100%
rename from arch/x86_64/kernel/genapic.c
rename to arch/x86/kernel/genapic_64.c
diff --git a/arch/x86_64/kernel/genapic_flat.c b/arch/x86/kernel/genapic_flat_64.c
similarity index 100%
rename from arch/x86_64/kernel/genapic_flat.c
rename to arch/x86/kernel/genapic_flat_64.c
diff --git a/arch/i386/kernel/geode.c b/arch/x86/kernel/geode_32.c
similarity index 100%
rename from arch/i386/kernel/geode.c
rename to arch/x86/kernel/geode_32.c
diff --git a/arch/x86_64/kernel/head64.c b/arch/x86/kernel/head64.c
similarity index 100%
rename from arch/x86_64/kernel/head64.c
rename to arch/x86/kernel/head64.c
diff --git a/arch/i386/kernel/head.S b/arch/x86/kernel/head_32.S
similarity index 99%
rename from arch/i386/kernel/head.S
rename to arch/x86/kernel/head_32.S
index 8f03821..9150ca9 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/x86/kernel/head_32.S
@@ -537,7 +537,7 @@
 	.ascii "Int %d: CR2 %p  err %p  EIP %p  CS %p  flags %p\n"
 	.asciz "Stack: %p %p %p %p %p %p %p %p\n"
 
-#include "../xen/xen-head.S"
+#include "../../x86/xen/xen-head.S"
 
 /*
  * The IDT and GDT 'descriptors' are a strange 48-bit object
diff --git a/arch/x86_64/kernel/head.S b/arch/x86/kernel/head_64.S
similarity index 100%
rename from arch/x86_64/kernel/head.S
rename to arch/x86/kernel/head_64.S
diff --git a/arch/i386/kernel/hpet.c b/arch/x86/kernel/hpet_32.c
similarity index 100%
rename from arch/i386/kernel/hpet.c
rename to arch/x86/kernel/hpet_32.c
diff --git a/arch/x86_64/kernel/hpet.c b/arch/x86/kernel/hpet_64.c
similarity index 100%
rename from arch/x86_64/kernel/hpet.c
rename to arch/x86/kernel/hpet_64.c
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/x86/kernel/i386_ksyms_32.c
similarity index 100%
rename from arch/i386/kernel/i386_ksyms.c
rename to arch/x86/kernel/i386_ksyms_32.c
diff --git a/arch/i386/kernel/i387.c b/arch/x86/kernel/i387_32.c
similarity index 100%
rename from arch/i386/kernel/i387.c
rename to arch/x86/kernel/i387_32.c
diff --git a/arch/x86_64/kernel/i387.c b/arch/x86/kernel/i387_64.c
similarity index 100%
rename from arch/x86_64/kernel/i387.c
rename to arch/x86/kernel/i387_64.c
diff --git a/arch/i386/kernel/i8237.c b/arch/x86/kernel/i8237.c
similarity index 100%
rename from arch/i386/kernel/i8237.c
rename to arch/x86/kernel/i8237.c
diff --git a/arch/i386/kernel/i8253.c b/arch/x86/kernel/i8253_32.c
similarity index 100%
rename from arch/i386/kernel/i8253.c
rename to arch/x86/kernel/i8253_32.c
diff --git a/arch/i386/kernel/i8259.c b/arch/x86/kernel/i8259_32.c
similarity index 100%
rename from arch/i386/kernel/i8259.c
rename to arch/x86/kernel/i8259_32.c
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86/kernel/i8259_64.c
similarity index 100%
rename from arch/x86_64/kernel/i8259.c
rename to arch/x86/kernel/i8259_64.c
diff --git a/arch/i386/kernel/init_task.c b/arch/x86/kernel/init_task_32.c
similarity index 100%
rename from arch/i386/kernel/init_task.c
rename to arch/x86/kernel/init_task_32.c
diff --git a/arch/x86_64/kernel/init_task.c b/arch/x86/kernel/init_task_64.c
similarity index 100%
rename from arch/x86_64/kernel/init_task.c
rename to arch/x86/kernel/init_task_64.c
diff --git a/arch/i386/kernel/io_apic.c b/arch/x86/kernel/io_apic_32.c
similarity index 100%
rename from arch/i386/kernel/io_apic.c
rename to arch/x86/kernel/io_apic_32.c
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86/kernel/io_apic_64.c
similarity index 100%
rename from arch/x86_64/kernel/io_apic.c
rename to arch/x86/kernel/io_apic_64.c
diff --git a/arch/i386/kernel/ioport.c b/arch/x86/kernel/ioport_32.c
similarity index 100%
rename from arch/i386/kernel/ioport.c
rename to arch/x86/kernel/ioport_32.c
diff --git a/arch/x86_64/kernel/ioport.c b/arch/x86/kernel/ioport_64.c
similarity index 100%
rename from arch/x86_64/kernel/ioport.c
rename to arch/x86/kernel/ioport_64.c
diff --git a/arch/i386/kernel/irq.c b/arch/x86/kernel/irq_32.c
similarity index 100%
rename from arch/i386/kernel/irq.c
rename to arch/x86/kernel/irq_32.c
diff --git a/arch/x86_64/kernel/irq.c b/arch/x86/kernel/irq_64.c
similarity index 100%
rename from arch/x86_64/kernel/irq.c
rename to arch/x86/kernel/irq_64.c
diff --git a/arch/x86_64/kernel/k8.c b/arch/x86/kernel/k8.c
similarity index 100%
rename from arch/x86_64/kernel/k8.c
rename to arch/x86/kernel/k8.c
diff --git a/arch/i386/kernel/kprobes.c b/arch/x86/kernel/kprobes_32.c
similarity index 100%
rename from arch/i386/kernel/kprobes.c
rename to arch/x86/kernel/kprobes_32.c
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86/kernel/kprobes_64.c
similarity index 100%
rename from arch/x86_64/kernel/kprobes.c
rename to arch/x86/kernel/kprobes_64.c
diff --git a/arch/i386/kernel/ldt.c b/arch/x86/kernel/ldt_32.c
similarity index 100%
rename from arch/i386/kernel/ldt.c
rename to arch/x86/kernel/ldt_32.c
diff --git a/arch/x86_64/kernel/ldt.c b/arch/x86/kernel/ldt_64.c
similarity index 100%
rename from arch/x86_64/kernel/ldt.c
rename to arch/x86/kernel/ldt_64.c
diff --git a/arch/i386/kernel/machine_kexec.c b/arch/x86/kernel/machine_kexec_32.c
similarity index 100%
rename from arch/i386/kernel/machine_kexec.c
rename to arch/x86/kernel/machine_kexec_32.c
diff --git a/arch/x86_64/kernel/machine_kexec.c b/arch/x86/kernel/machine_kexec_64.c
similarity index 100%
rename from arch/x86_64/kernel/machine_kexec.c
rename to arch/x86/kernel/machine_kexec_64.c
diff --git a/arch/i386/kernel/mca.c b/arch/x86/kernel/mca_32.c
similarity index 100%
rename from arch/i386/kernel/mca.c
rename to arch/x86/kernel/mca_32.c
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86/kernel/mce_64.c
similarity index 100%
rename from arch/x86_64/kernel/mce.c
rename to arch/x86/kernel/mce_64.c
diff --git a/arch/x86_64/kernel/mce_amd.c b/arch/x86/kernel/mce_amd_64.c
similarity index 100%
rename from arch/x86_64/kernel/mce_amd.c
rename to arch/x86/kernel/mce_amd_64.c
diff --git a/arch/x86_64/kernel/mce_intel.c b/arch/x86/kernel/mce_intel_64.c
similarity index 100%
rename from arch/x86_64/kernel/mce_intel.c
rename to arch/x86/kernel/mce_intel_64.c
diff --git a/arch/i386/kernel/microcode.c b/arch/x86/kernel/microcode.c
similarity index 100%
rename from arch/i386/kernel/microcode.c
rename to arch/x86/kernel/microcode.c
diff --git a/arch/i386/kernel/module.c b/arch/x86/kernel/module_32.c
similarity index 100%
rename from arch/i386/kernel/module.c
rename to arch/x86/kernel/module_32.c
diff --git a/arch/x86_64/kernel/module.c b/arch/x86/kernel/module_64.c
similarity index 100%
rename from arch/x86_64/kernel/module.c
rename to arch/x86/kernel/module_64.c
diff --git a/arch/i386/kernel/mpparse.c b/arch/x86/kernel/mpparse_32.c
similarity index 100%
rename from arch/i386/kernel/mpparse.c
rename to arch/x86/kernel/mpparse_32.c
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86/kernel/mpparse_64.c
similarity index 100%
rename from arch/x86_64/kernel/mpparse.c
rename to arch/x86/kernel/mpparse_64.c
diff --git a/arch/i386/kernel/msr.c b/arch/x86/kernel/msr.c
similarity index 100%
rename from arch/i386/kernel/msr.c
rename to arch/x86/kernel/msr.c
diff --git a/arch/i386/kernel/nmi.c b/arch/x86/kernel/nmi_32.c
similarity index 100%
rename from arch/i386/kernel/nmi.c
rename to arch/x86/kernel/nmi_32.c
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86/kernel/nmi_64.c
similarity index 100%
rename from arch/x86_64/kernel/nmi.c
rename to arch/x86/kernel/nmi_64.c
diff --git a/arch/i386/kernel/numaq.c b/arch/x86/kernel/numaq_32.c
similarity index 100%
rename from arch/i386/kernel/numaq.c
rename to arch/x86/kernel/numaq_32.c
diff --git a/arch/i386/kernel/paravirt.c b/arch/x86/kernel/paravirt_32.c
similarity index 100%
rename from arch/i386/kernel/paravirt.c
rename to arch/x86/kernel/paravirt_32.c
diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86/kernel/pci-calgary_64.c
similarity index 100%
rename from arch/x86_64/kernel/pci-calgary.c
rename to arch/x86/kernel/pci-calgary_64.c
diff --git a/arch/i386/kernel/pci-dma.c b/arch/x86/kernel/pci-dma_32.c
similarity index 100%
rename from arch/i386/kernel/pci-dma.c
rename to arch/x86/kernel/pci-dma_32.c
diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86/kernel/pci-dma_64.c
similarity index 100%
rename from arch/x86_64/kernel/pci-dma.c
rename to arch/x86/kernel/pci-dma_64.c
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86/kernel/pci-gart_64.c
similarity index 100%
rename from arch/x86_64/kernel/pci-gart.c
rename to arch/x86/kernel/pci-gart_64.c
diff --git a/arch/x86_64/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu_64.c
similarity index 100%
rename from arch/x86_64/kernel/pci-nommu.c
rename to arch/x86/kernel/pci-nommu_64.c
diff --git a/arch/x86_64/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb_64.c
similarity index 100%
rename from arch/x86_64/kernel/pci-swiotlb.c
rename to arch/x86/kernel/pci-swiotlb_64.c
diff --git a/arch/i386/kernel/pcspeaker.c b/arch/x86/kernel/pcspeaker.c
similarity index 100%
rename from arch/i386/kernel/pcspeaker.c
rename to arch/x86/kernel/pcspeaker.c
diff --git a/arch/x86_64/kernel/pmtimer.c b/arch/x86/kernel/pmtimer_64.c
similarity index 100%
rename from arch/x86_64/kernel/pmtimer.c
rename to arch/x86/kernel/pmtimer_64.c
diff --git a/arch/i386/kernel/process.c b/arch/x86/kernel/process_32.c
similarity index 100%
rename from arch/i386/kernel/process.c
rename to arch/x86/kernel/process_32.c
diff --git a/arch/x86_64/kernel/process.c b/arch/x86/kernel/process_64.c
similarity index 100%
rename from arch/x86_64/kernel/process.c
rename to arch/x86/kernel/process_64.c
diff --git a/arch/i386/kernel/ptrace.c b/arch/x86/kernel/ptrace_32.c
similarity index 100%
rename from arch/i386/kernel/ptrace.c
rename to arch/x86/kernel/ptrace_32.c
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86/kernel/ptrace_64.c
similarity index 100%
rename from arch/x86_64/kernel/ptrace.c
rename to arch/x86/kernel/ptrace_64.c
diff --git a/arch/i386/kernel/quirks.c b/arch/x86/kernel/quirks.c
similarity index 100%
rename from arch/i386/kernel/quirks.c
rename to arch/x86/kernel/quirks.c
diff --git a/arch/i386/kernel/reboot.c b/arch/x86/kernel/reboot_32.c
similarity index 100%
rename from arch/i386/kernel/reboot.c
rename to arch/x86/kernel/reboot_32.c
diff --git a/arch/x86_64/kernel/reboot.c b/arch/x86/kernel/reboot_64.c
similarity index 100%
rename from arch/x86_64/kernel/reboot.c
rename to arch/x86/kernel/reboot_64.c
diff --git a/arch/i386/kernel/reboot_fixups.c b/arch/x86/kernel/reboot_fixups_32.c
similarity index 100%
rename from arch/i386/kernel/reboot_fixups.c
rename to arch/x86/kernel/reboot_fixups_32.c
diff --git a/arch/i386/kernel/relocate_kernel.S b/arch/x86/kernel/relocate_kernel_32.S
similarity index 100%
rename from arch/i386/kernel/relocate_kernel.S
rename to arch/x86/kernel/relocate_kernel_32.S
diff --git a/arch/x86_64/kernel/relocate_kernel.S b/arch/x86/kernel/relocate_kernel_64.S
similarity index 100%
rename from arch/x86_64/kernel/relocate_kernel.S
rename to arch/x86/kernel/relocate_kernel_64.S
diff --git a/arch/i386/kernel/scx200.c b/arch/x86/kernel/scx200_32.c
similarity index 100%
rename from arch/i386/kernel/scx200.c
rename to arch/x86/kernel/scx200_32.c
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86/kernel/setup64.c
similarity index 100%
rename from arch/x86_64/kernel/setup64.c
rename to arch/x86/kernel/setup64.c
diff --git a/arch/i386/kernel/setup.c b/arch/x86/kernel/setup_32.c
similarity index 100%
rename from arch/i386/kernel/setup.c
rename to arch/x86/kernel/setup_32.c
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86/kernel/setup_64.c
similarity index 100%
rename from arch/x86_64/kernel/setup.c
rename to arch/x86/kernel/setup_64.c
diff --git a/arch/i386/kernel/sigframe.h b/arch/x86/kernel/sigframe_32.h
similarity index 100%
rename from arch/i386/kernel/sigframe.h
rename to arch/x86/kernel/sigframe_32.h
diff --git a/arch/i386/kernel/signal.c b/arch/x86/kernel/signal_32.c
similarity index 99%
rename from arch/i386/kernel/signal.c
rename to arch/x86/kernel/signal_32.c
index f5dd856..c03570f 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/x86/kernel/signal_32.c
@@ -25,7 +25,7 @@
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 #include <asm/i387.h>
-#include "sigframe.h"
+#include "sigframe_32.h"
 
 #define DEBUG_SIG 0
 
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86/kernel/signal_64.c
similarity index 100%
rename from arch/x86_64/kernel/signal.c
rename to arch/x86/kernel/signal_64.c
diff --git a/arch/i386/kernel/smp.c b/arch/x86/kernel/smp_32.c
similarity index 100%
rename from arch/i386/kernel/smp.c
rename to arch/x86/kernel/smp_32.c
diff --git a/arch/x86_64/kernel/smp.c b/arch/x86/kernel/smp_64.c
similarity index 100%
rename from arch/x86_64/kernel/smp.c
rename to arch/x86/kernel/smp_64.c
diff --git a/arch/i386/kernel/smpboot.c b/arch/x86/kernel/smpboot_32.c
similarity index 100%
rename from arch/i386/kernel/smpboot.c
rename to arch/x86/kernel/smpboot_32.c
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86/kernel/smpboot_64.c
similarity index 100%
rename from arch/x86_64/kernel/smpboot.c
rename to arch/x86/kernel/smpboot_64.c
diff --git a/arch/i386/kernel/smpcommon.c b/arch/x86/kernel/smpcommon_32.c
similarity index 100%
rename from arch/i386/kernel/smpcommon.c
rename to arch/x86/kernel/smpcommon_32.c
diff --git a/arch/i386/kernel/srat.c b/arch/x86/kernel/srat_32.c
similarity index 100%
rename from arch/i386/kernel/srat.c
rename to arch/x86/kernel/srat_32.c
diff --git a/arch/x86_64/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c
similarity index 100%
rename from arch/x86_64/kernel/stacktrace.c
rename to arch/x86/kernel/stacktrace.c
diff --git a/arch/i386/kernel/summit.c b/arch/x86/kernel/summit_32.c
similarity index 100%
rename from arch/i386/kernel/summit.c
rename to arch/x86/kernel/summit_32.c
diff --git a/arch/x86_64/kernel/suspend.c b/arch/x86/kernel/suspend_64.c
similarity index 100%
rename from arch/x86_64/kernel/suspend.c
rename to arch/x86/kernel/suspend_64.c
diff --git a/arch/x86_64/kernel/suspend_asm.S b/arch/x86/kernel/suspend_asm_64.S
similarity index 100%
rename from arch/x86_64/kernel/suspend_asm.S
rename to arch/x86/kernel/suspend_asm_64.S
diff --git a/arch/i386/kernel/sys_i386.c b/arch/x86/kernel/sys_i386_32.c
similarity index 100%
rename from arch/i386/kernel/sys_i386.c
rename to arch/x86/kernel/sys_i386_32.c
diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
similarity index 100%
rename from arch/x86_64/kernel/sys_x86_64.c
rename to arch/x86/kernel/sys_x86_64.c
diff --git a/arch/x86_64/kernel/syscall.c b/arch/x86/kernel/syscall_64.c
similarity index 90%
rename from arch/x86_64/kernel/syscall.c
rename to arch/x86/kernel/syscall_64.c
index 63d592c..9d498c2 100644
--- a/arch/x86_64/kernel/syscall.c
+++ b/arch/x86/kernel/syscall_64.c
@@ -9,7 +9,7 @@
 
 #define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ; 
 #undef _ASM_X86_64_UNISTD_H_
-#include <asm-x86_64/unistd.h>
+#include <asm/unistd_64.h>
 
 #undef __SYSCALL
 #define __SYSCALL(nr, sym) [ nr ] = sym, 
@@ -22,5 +22,5 @@
 const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = {
 	/* Smells like a like a compiler bug -- it doesn't work when the & below is removed. */ 
 	[0 ... __NR_syscall_max] = &sys_ni_syscall,
-#include <asm-x86_64/unistd.h>
+#include <asm/unistd_64.h>
 };
diff --git a/arch/i386/kernel/syscall_table.S b/arch/x86/kernel/syscall_table_32.S
similarity index 100%
rename from arch/i386/kernel/syscall_table.S
rename to arch/x86/kernel/syscall_table_32.S
diff --git a/arch/i386/kernel/sysenter.c b/arch/x86/kernel/sysenter_32.c
similarity index 100%
rename from arch/i386/kernel/sysenter.c
rename to arch/x86/kernel/sysenter_32.c
diff --git a/arch/x86_64/kernel/tce.c b/arch/x86/kernel/tce_64.c
similarity index 100%
rename from arch/x86_64/kernel/tce.c
rename to arch/x86/kernel/tce_64.c
diff --git a/arch/i386/kernel/time.c b/arch/x86/kernel/time_32.c
similarity index 100%
rename from arch/i386/kernel/time.c
rename to arch/x86/kernel/time_32.c
diff --git a/arch/x86_64/kernel/time.c b/arch/x86/kernel/time_64.c
similarity index 100%
rename from arch/x86_64/kernel/time.c
rename to arch/x86/kernel/time_64.c
diff --git a/arch/i386/kernel/topology.c b/arch/x86/kernel/topology.c
similarity index 100%
rename from arch/i386/kernel/topology.c
rename to arch/x86/kernel/topology.c
diff --git a/arch/i386/kernel/trampoline.S b/arch/x86/kernel/trampoline_32.S
similarity index 100%
rename from arch/i386/kernel/trampoline.S
rename to arch/x86/kernel/trampoline_32.S
diff --git a/arch/x86_64/kernel/trampoline.S b/arch/x86/kernel/trampoline_64.S
similarity index 98%
rename from arch/x86_64/kernel/trampoline.S
rename to arch/x86/kernel/trampoline_64.S
index e7e2764..607983b 100644
--- a/arch/x86_64/kernel/trampoline.S
+++ b/arch/x86/kernel/trampoline_64.S
@@ -126,7 +126,7 @@
 no_longmode:
 	hlt
 	jmp no_longmode
-#include "verify_cpu.S"
+#include "verify_cpu_64.S"
 
 	# Careful these need to be in the same 64K segment as the above;
 tidt:
diff --git a/arch/i386/kernel/traps.c b/arch/x86/kernel/traps_32.c
similarity index 100%
rename from arch/i386/kernel/traps.c
rename to arch/x86/kernel/traps_32.c
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86/kernel/traps_64.c
similarity index 100%
rename from arch/x86_64/kernel/traps.c
rename to arch/x86/kernel/traps_64.c
diff --git a/arch/i386/kernel/tsc.c b/arch/x86/kernel/tsc_32.c
similarity index 100%
rename from arch/i386/kernel/tsc.c
rename to arch/x86/kernel/tsc_32.c
diff --git a/arch/x86_64/kernel/tsc.c b/arch/x86/kernel/tsc_64.c
similarity index 100%
rename from arch/x86_64/kernel/tsc.c
rename to arch/x86/kernel/tsc_64.c
diff --git a/arch/x86_64/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c
similarity index 100%
rename from arch/x86_64/kernel/tsc_sync.c
rename to arch/x86/kernel/tsc_sync.c
diff --git a/arch/x86_64/kernel/verify_cpu.S b/arch/x86/kernel/verify_cpu_64.S
similarity index 100%
rename from arch/x86_64/kernel/verify_cpu.S
rename to arch/x86/kernel/verify_cpu_64.S
diff --git a/arch/i386/kernel/vm86.c b/arch/x86/kernel/vm86_32.c
similarity index 100%
rename from arch/i386/kernel/vm86.c
rename to arch/x86/kernel/vm86_32.c
diff --git a/arch/i386/kernel/vmi.c b/arch/x86/kernel/vmi_32.c
similarity index 100%
rename from arch/i386/kernel/vmi.c
rename to arch/x86/kernel/vmi_32.c
diff --git a/arch/i386/kernel/vmiclock.c b/arch/x86/kernel/vmiclock_32.c
similarity index 100%
rename from arch/i386/kernel/vmiclock.c
rename to arch/x86/kernel/vmiclock_32.c
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
new file mode 100644
index 0000000..849ee61
--- /dev/null
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "vmlinux_32.lds.S"
+#else
+# include "vmlinux_64.lds.S"
+#endif
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux_32.lds.S
similarity index 100%
rename from arch/i386/kernel/vmlinux.lds.S
rename to arch/x86/kernel/vmlinux_32.lds.S
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux_64.lds.S
similarity index 100%
rename from arch/x86_64/kernel/vmlinux.lds.S
rename to arch/x86/kernel/vmlinux_64.lds.S
diff --git a/arch/x86_64/kernel/vsmp.c b/arch/x86/kernel/vsmp_64.c
similarity index 100%
rename from arch/x86_64/kernel/vsmp.c
rename to arch/x86/kernel/vsmp_64.c
diff --git a/arch/i386/kernel/vsyscall-int80.S b/arch/x86/kernel/vsyscall-int80_32.S
similarity index 96%
rename from arch/i386/kernel/vsyscall-int80.S
rename to arch/x86/kernel/vsyscall-int80_32.S
index 530d052..103cab6 100644
--- a/arch/i386/kernel/vsyscall-int80.S
+++ b/arch/x86/kernel/vsyscall-int80_32.S
@@ -50,4 +50,4 @@
 /*
  * Get the common code for the sigreturn entry points.
  */
-#include "vsyscall-sigreturn.S"
+#include "vsyscall-sigreturn_32.S"
diff --git a/arch/i386/kernel/vsyscall-note.S b/arch/x86/kernel/vsyscall-note_32.S
similarity index 95%
rename from arch/i386/kernel/vsyscall-note.S
rename to arch/x86/kernel/vsyscall-note_32.S
index 07c0daf..fcf376a 100644
--- a/arch/i386/kernel/vsyscall-note.S
+++ b/arch/x86/kernel/vsyscall-note_32.S
@@ -33,7 +33,7 @@
  * at boot time we set VDSO_NOTE_NONEGSEG_BIT if running under Xen.
  */
 
-#include "../xen/vdso.h"	/* Defines VDSO_NOTE_NONEGSEG_BIT.  */
+#include "../../x86/xen/vdso.h"	/* Defines VDSO_NOTE_NONEGSEG_BIT.  */
 
 	.globl VDSO_NOTE_MASK
 ELFNOTE_START(GNU, 2, "a")
diff --git a/arch/i386/kernel/vsyscall-sigreturn.S b/arch/x86/kernel/vsyscall-sigreturn_32.S
similarity index 100%
rename from arch/i386/kernel/vsyscall-sigreturn.S
rename to arch/x86/kernel/vsyscall-sigreturn_32.S
diff --git a/arch/i386/kernel/vsyscall-sysenter.S b/arch/x86/kernel/vsyscall-sysenter_32.S
similarity index 98%
rename from arch/i386/kernel/vsyscall-sysenter.S
rename to arch/x86/kernel/vsyscall-sysenter_32.S
index 1a36d26..ed879bf 100644
--- a/arch/i386/kernel/vsyscall-sysenter.S
+++ b/arch/x86/kernel/vsyscall-sysenter_32.S
@@ -119,4 +119,4 @@
 /*
  * Get the common code for the sigreturn entry points.
  */
-#include "vsyscall-sigreturn.S"
+#include "vsyscall-sigreturn_32.S"
diff --git a/arch/i386/kernel/vsyscall.S b/arch/x86/kernel/vsyscall_32.S
similarity index 70%
rename from arch/i386/kernel/vsyscall.S
rename to arch/x86/kernel/vsyscall_32.S
index b403890..a5ab3dc 100644
--- a/arch/i386/kernel/vsyscall.S
+++ b/arch/x86/kernel/vsyscall_32.S
@@ -4,12 +4,12 @@
 
 	.globl vsyscall_int80_start, vsyscall_int80_end
 vsyscall_int80_start:
-	.incbin "arch/i386/kernel/vsyscall-int80.so"
+	.incbin "arch/x86/kernel/vsyscall-int80_32.so"
 vsyscall_int80_end:
 
 	.globl vsyscall_sysenter_start, vsyscall_sysenter_end
 vsyscall_sysenter_start:
-	.incbin "arch/i386/kernel/vsyscall-sysenter.so"
+	.incbin "arch/x86/kernel/vsyscall-sysenter_32.so"
 vsyscall_sysenter_end:
 
 __FINIT
diff --git a/arch/i386/kernel/vsyscall.lds.S b/arch/x86/kernel/vsyscall_32.lds.S
similarity index 100%
rename from arch/i386/kernel/vsyscall.lds.S
rename to arch/x86/kernel/vsyscall_32.lds.S
diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86/kernel/vsyscall_64.c
similarity index 100%
rename from arch/x86_64/kernel/vsyscall.c
rename to arch/x86/kernel/vsyscall_64.c
diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86/kernel/x8664_ksyms_64.c
similarity index 100%
rename from arch/x86_64/kernel/x8664_ksyms.c
rename to arch/x86/kernel/x8664_ksyms_64.c
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
new file mode 100644
index 0000000..329da27
--- /dev/null
+++ b/arch/x86/lib/Makefile
@@ -0,0 +1,5 @@
+ifeq ($(CONFIG_X86_32),y)
+include ${srctree}/arch/x86/lib/Makefile_32
+else
+include ${srctree}/arch/x86/lib/Makefile_64
+endif
diff --git a/arch/x86/lib/Makefile_32 b/arch/x86/lib/Makefile_32
new file mode 100644
index 0000000..98d1f1e
--- /dev/null
+++ b/arch/x86/lib/Makefile_32
@@ -0,0 +1,11 @@
+#
+# Makefile for i386-specific library files..
+#
+
+
+lib-y = checksum_32.o delay_32.o usercopy_32.o getuser_32.o putuser_32.o memcpy_32.o strstr_32.o \
+	bitops_32.o semaphore_32.o string_32.o
+
+lib-$(CONFIG_X86_USE_3DNOW) += mmx_32.o
+
+obj-$(CONFIG_SMP)	+= msr-on-cpu.o
diff --git a/arch/x86/lib/Makefile_64 b/arch/x86/lib/Makefile_64
new file mode 100644
index 0000000..bbabad3
--- /dev/null
+++ b/arch/x86/lib/Makefile_64
@@ -0,0 +1,13 @@
+#
+# Makefile for x86_64-specific library files.
+#
+
+CFLAGS_csum-partial_64.o := -funroll-loops
+
+obj-y := io_64.o iomap_copy_64.o
+obj-$(CONFIG_SMP)	+= msr-on-cpu.o
+
+lib-y := csum-partial_64.o csum-copy_64.o csum-wrappers_64.o delay_64.o \
+	usercopy_64.o getuser_64.o putuser_64.o  \
+	thunk_64.o clear_page_64.o copy_page_64.o bitstr_64.o bitops_64.o
+lib-y += memcpy_64.o memmove_64.o memset_64.o copy_user_64.o rwlock_64.o copy_user_nocache_64.o
diff --git a/arch/i386/lib/bitops.c b/arch/x86/lib/bitops_32.c
similarity index 100%
rename from arch/i386/lib/bitops.c
rename to arch/x86/lib/bitops_32.c
diff --git a/arch/x86_64/lib/bitops.c b/arch/x86/lib/bitops_64.c
similarity index 100%
rename from arch/x86_64/lib/bitops.c
rename to arch/x86/lib/bitops_64.c
diff --git a/arch/x86_64/lib/bitstr.c b/arch/x86/lib/bitstr_64.c
similarity index 100%
rename from arch/x86_64/lib/bitstr.c
rename to arch/x86/lib/bitstr_64.c
diff --git a/arch/i386/lib/checksum.S b/arch/x86/lib/checksum_32.S
similarity index 100%
rename from arch/i386/lib/checksum.S
rename to arch/x86/lib/checksum_32.S
diff --git a/arch/x86_64/lib/clear_page.S b/arch/x86/lib/clear_page_64.S
similarity index 100%
rename from arch/x86_64/lib/clear_page.S
rename to arch/x86/lib/clear_page_64.S
diff --git a/arch/x86_64/lib/copy_page.S b/arch/x86/lib/copy_page_64.S
similarity index 100%
rename from arch/x86_64/lib/copy_page.S
rename to arch/x86/lib/copy_page_64.S
diff --git a/arch/x86_64/lib/copy_user.S b/arch/x86/lib/copy_user_64.S
similarity index 100%
rename from arch/x86_64/lib/copy_user.S
rename to arch/x86/lib/copy_user_64.S
diff --git a/arch/x86_64/lib/copy_user_nocache.S b/arch/x86/lib/copy_user_nocache_64.S
similarity index 100%
rename from arch/x86_64/lib/copy_user_nocache.S
rename to arch/x86/lib/copy_user_nocache_64.S
diff --git a/arch/x86_64/lib/csum-copy.S b/arch/x86/lib/csum-copy_64.S
similarity index 100%
rename from arch/x86_64/lib/csum-copy.S
rename to arch/x86/lib/csum-copy_64.S
diff --git a/arch/x86_64/lib/csum-partial.c b/arch/x86/lib/csum-partial_64.c
similarity index 100%
rename from arch/x86_64/lib/csum-partial.c
rename to arch/x86/lib/csum-partial_64.c
diff --git a/arch/x86_64/lib/csum-wrappers.c b/arch/x86/lib/csum-wrappers_64.c
similarity index 100%
rename from arch/x86_64/lib/csum-wrappers.c
rename to arch/x86/lib/csum-wrappers_64.c
diff --git a/arch/i386/lib/delay.c b/arch/x86/lib/delay_32.c
similarity index 100%
rename from arch/i386/lib/delay.c
rename to arch/x86/lib/delay_32.c
diff --git a/arch/x86_64/lib/delay.c b/arch/x86/lib/delay_64.c
similarity index 100%
rename from arch/x86_64/lib/delay.c
rename to arch/x86/lib/delay_64.c
diff --git a/arch/i386/lib/getuser.S b/arch/x86/lib/getuser_32.S
similarity index 100%
rename from arch/i386/lib/getuser.S
rename to arch/x86/lib/getuser_32.S
diff --git a/arch/x86_64/lib/getuser.S b/arch/x86/lib/getuser_64.S
similarity index 100%
rename from arch/x86_64/lib/getuser.S
rename to arch/x86/lib/getuser_64.S
diff --git a/arch/x86_64/lib/io.c b/arch/x86/lib/io_64.c
similarity index 100%
rename from arch/x86_64/lib/io.c
rename to arch/x86/lib/io_64.c
diff --git a/arch/x86_64/lib/iomap_copy.S b/arch/x86/lib/iomap_copy_64.S
similarity index 100%
rename from arch/x86_64/lib/iomap_copy.S
rename to arch/x86/lib/iomap_copy_64.S
diff --git a/arch/i386/lib/memcpy.c b/arch/x86/lib/memcpy_32.c
similarity index 100%
rename from arch/i386/lib/memcpy.c
rename to arch/x86/lib/memcpy_32.c
diff --git a/arch/x86_64/lib/memcpy.S b/arch/x86/lib/memcpy_64.S
similarity index 100%
rename from arch/x86_64/lib/memcpy.S
rename to arch/x86/lib/memcpy_64.S
diff --git a/arch/x86_64/lib/memmove.c b/arch/x86/lib/memmove_64.c
similarity index 100%
rename from arch/x86_64/lib/memmove.c
rename to arch/x86/lib/memmove_64.c
diff --git a/arch/x86_64/lib/memset.S b/arch/x86/lib/memset_64.S
similarity index 100%
rename from arch/x86_64/lib/memset.S
rename to arch/x86/lib/memset_64.S
diff --git a/arch/i386/lib/mmx.c b/arch/x86/lib/mmx_32.c
similarity index 100%
rename from arch/i386/lib/mmx.c
rename to arch/x86/lib/mmx_32.c
diff --git a/arch/i386/lib/msr-on-cpu.c b/arch/x86/lib/msr-on-cpu.c
similarity index 100%
rename from arch/i386/lib/msr-on-cpu.c
rename to arch/x86/lib/msr-on-cpu.c
diff --git a/arch/i386/lib/putuser.S b/arch/x86/lib/putuser_32.S
similarity index 100%
rename from arch/i386/lib/putuser.S
rename to arch/x86/lib/putuser_32.S
diff --git a/arch/x86_64/lib/putuser.S b/arch/x86/lib/putuser_64.S
similarity index 100%
rename from arch/x86_64/lib/putuser.S
rename to arch/x86/lib/putuser_64.S
diff --git a/arch/x86_64/lib/rwlock.S b/arch/x86/lib/rwlock_64.S
similarity index 100%
rename from arch/x86_64/lib/rwlock.S
rename to arch/x86/lib/rwlock_64.S
diff --git a/arch/i386/lib/semaphore.S b/arch/x86/lib/semaphore_32.S
similarity index 100%
rename from arch/i386/lib/semaphore.S
rename to arch/x86/lib/semaphore_32.S
diff --git a/arch/i386/lib/string.c b/arch/x86/lib/string_32.c
similarity index 100%
rename from arch/i386/lib/string.c
rename to arch/x86/lib/string_32.c
diff --git a/arch/i386/lib/strstr.c b/arch/x86/lib/strstr_32.c
similarity index 100%
rename from arch/i386/lib/strstr.c
rename to arch/x86/lib/strstr_32.c
diff --git a/arch/x86_64/lib/thunk.S b/arch/x86/lib/thunk_64.S
similarity index 100%
rename from arch/x86_64/lib/thunk.S
rename to arch/x86/lib/thunk_64.S
diff --git a/arch/i386/lib/usercopy.c b/arch/x86/lib/usercopy_32.c
similarity index 100%
rename from arch/i386/lib/usercopy.c
rename to arch/x86/lib/usercopy_32.c
diff --git a/arch/x86_64/lib/usercopy.c b/arch/x86/lib/usercopy_64.c
similarity index 100%
rename from arch/x86_64/lib/usercopy.c
rename to arch/x86/lib/usercopy_64.c
diff --git a/arch/i386/mach-default/Makefile b/arch/x86/mach-default/Makefile
similarity index 100%
rename from arch/i386/mach-default/Makefile
rename to arch/x86/mach-default/Makefile
diff --git a/arch/i386/mach-default/setup.c b/arch/x86/mach-default/setup.c
similarity index 100%
rename from arch/i386/mach-default/setup.c
rename to arch/x86/mach-default/setup.c
diff --git a/arch/i386/mach-es7000/Makefile b/arch/x86/mach-es7000/Makefile
similarity index 100%
rename from arch/i386/mach-es7000/Makefile
rename to arch/x86/mach-es7000/Makefile
diff --git a/arch/i386/mach-es7000/es7000.h b/arch/x86/mach-es7000/es7000.h
similarity index 100%
rename from arch/i386/mach-es7000/es7000.h
rename to arch/x86/mach-es7000/es7000.h
diff --git a/arch/i386/mach-es7000/es7000plat.c b/arch/x86/mach-es7000/es7000plat.c
similarity index 100%
rename from arch/i386/mach-es7000/es7000plat.c
rename to arch/x86/mach-es7000/es7000plat.c
diff --git a/arch/x86/mach-generic/Makefile b/arch/x86/mach-generic/Makefile
new file mode 100644
index 0000000..19d6d40
--- /dev/null
+++ b/arch/x86/mach-generic/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the generic architecture
+#
+
+EXTRA_CFLAGS	:= -Iarch/x86/kernel
+
+obj-y		:= probe.o summit.o bigsmp.o es7000.o default.o 
+obj-y		+= ../../x86/mach-es7000/
diff --git a/arch/i386/mach-generic/bigsmp.c b/arch/x86/mach-generic/bigsmp.c
similarity index 100%
rename from arch/i386/mach-generic/bigsmp.c
rename to arch/x86/mach-generic/bigsmp.c
diff --git a/arch/i386/mach-generic/default.c b/arch/x86/mach-generic/default.c
similarity index 100%
rename from arch/i386/mach-generic/default.c
rename to arch/x86/mach-generic/default.c
diff --git a/arch/i386/mach-generic/es7000.c b/arch/x86/mach-generic/es7000.c
similarity index 100%
rename from arch/i386/mach-generic/es7000.c
rename to arch/x86/mach-generic/es7000.c
diff --git a/arch/i386/mach-generic/probe.c b/arch/x86/mach-generic/probe.c
similarity index 100%
rename from arch/i386/mach-generic/probe.c
rename to arch/x86/mach-generic/probe.c
diff --git a/arch/i386/mach-generic/summit.c b/arch/x86/mach-generic/summit.c
similarity index 100%
rename from arch/i386/mach-generic/summit.c
rename to arch/x86/mach-generic/summit.c
diff --git a/arch/i386/mach-visws/Makefile b/arch/x86/mach-visws/Makefile
similarity index 100%
rename from arch/i386/mach-visws/Makefile
rename to arch/x86/mach-visws/Makefile
diff --git a/arch/i386/mach-visws/mpparse.c b/arch/x86/mach-visws/mpparse.c
similarity index 100%
rename from arch/i386/mach-visws/mpparse.c
rename to arch/x86/mach-visws/mpparse.c
diff --git a/arch/i386/mach-visws/reboot.c b/arch/x86/mach-visws/reboot.c
similarity index 100%
rename from arch/i386/mach-visws/reboot.c
rename to arch/x86/mach-visws/reboot.c
diff --git a/arch/i386/mach-visws/setup.c b/arch/x86/mach-visws/setup.c
similarity index 100%
rename from arch/i386/mach-visws/setup.c
rename to arch/x86/mach-visws/setup.c
diff --git a/arch/i386/mach-visws/traps.c b/arch/x86/mach-visws/traps.c
similarity index 100%
rename from arch/i386/mach-visws/traps.c
rename to arch/x86/mach-visws/traps.c
diff --git a/arch/i386/mach-visws/visws_apic.c b/arch/x86/mach-visws/visws_apic.c
similarity index 100%
rename from arch/i386/mach-visws/visws_apic.c
rename to arch/x86/mach-visws/visws_apic.c
diff --git a/arch/i386/mach-voyager/Makefile b/arch/x86/mach-voyager/Makefile
similarity index 79%
rename from arch/i386/mach-voyager/Makefile
rename to arch/x86/mach-voyager/Makefile
index 33b74cf..15c250b 100644
--- a/arch/i386/mach-voyager/Makefile
+++ b/arch/x86/mach-voyager/Makefile
@@ -2,7 +2,7 @@
 # Makefile for the linux kernel.
 #
 
-EXTRA_CFLAGS	:= -Iarch/i386/kernel
+EXTRA_CFLAGS	:= -Iarch/x86/kernel
 obj-y			:= setup.o voyager_basic.o voyager_thread.o
 
 obj-$(CONFIG_SMP)	+= voyager_smp.o voyager_cat.o
diff --git a/arch/i386/mach-voyager/setup.c b/arch/x86/mach-voyager/setup.c
similarity index 100%
rename from arch/i386/mach-voyager/setup.c
rename to arch/x86/mach-voyager/setup.c
diff --git a/arch/i386/mach-voyager/voyager_basic.c b/arch/x86/mach-voyager/voyager_basic.c
similarity index 100%
rename from arch/i386/mach-voyager/voyager_basic.c
rename to arch/x86/mach-voyager/voyager_basic.c
diff --git a/arch/i386/mach-voyager/voyager_cat.c b/arch/x86/mach-voyager/voyager_cat.c
similarity index 100%
rename from arch/i386/mach-voyager/voyager_cat.c
rename to arch/x86/mach-voyager/voyager_cat.c
diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c
similarity index 100%
rename from arch/i386/mach-voyager/voyager_smp.c
rename to arch/x86/mach-voyager/voyager_smp.c
diff --git a/arch/i386/mach-voyager/voyager_thread.c b/arch/x86/mach-voyager/voyager_thread.c
similarity index 100%
rename from arch/i386/mach-voyager/voyager_thread.c
rename to arch/x86/mach-voyager/voyager_thread.c
diff --git a/arch/i386/math-emu/Makefile b/arch/x86/math-emu/Makefile
similarity index 100%
rename from arch/i386/math-emu/Makefile
rename to arch/x86/math-emu/Makefile
diff --git a/arch/i386/math-emu/README b/arch/x86/math-emu/README
similarity index 100%
rename from arch/i386/math-emu/README
rename to arch/x86/math-emu/README
diff --git a/arch/i386/math-emu/control_w.h b/arch/x86/math-emu/control_w.h
similarity index 100%
rename from arch/i386/math-emu/control_w.h
rename to arch/x86/math-emu/control_w.h
diff --git a/arch/i386/math-emu/div_Xsig.S b/arch/x86/math-emu/div_Xsig.S
similarity index 100%
rename from arch/i386/math-emu/div_Xsig.S
rename to arch/x86/math-emu/div_Xsig.S
diff --git a/arch/i386/math-emu/div_small.S b/arch/x86/math-emu/div_small.S
similarity index 100%
rename from arch/i386/math-emu/div_small.S
rename to arch/x86/math-emu/div_small.S
diff --git a/arch/i386/math-emu/errors.c b/arch/x86/math-emu/errors.c
similarity index 100%
rename from arch/i386/math-emu/errors.c
rename to arch/x86/math-emu/errors.c
diff --git a/arch/i386/math-emu/exception.h b/arch/x86/math-emu/exception.h
similarity index 100%
rename from arch/i386/math-emu/exception.h
rename to arch/x86/math-emu/exception.h
diff --git a/arch/i386/math-emu/fpu_arith.c b/arch/x86/math-emu/fpu_arith.c
similarity index 100%
rename from arch/i386/math-emu/fpu_arith.c
rename to arch/x86/math-emu/fpu_arith.c
diff --git a/arch/i386/math-emu/fpu_asm.h b/arch/x86/math-emu/fpu_asm.h
similarity index 100%
rename from arch/i386/math-emu/fpu_asm.h
rename to arch/x86/math-emu/fpu_asm.h
diff --git a/arch/i386/math-emu/fpu_aux.c b/arch/x86/math-emu/fpu_aux.c
similarity index 100%
rename from arch/i386/math-emu/fpu_aux.c
rename to arch/x86/math-emu/fpu_aux.c
diff --git a/arch/i386/math-emu/fpu_emu.h b/arch/x86/math-emu/fpu_emu.h
similarity index 100%
rename from arch/i386/math-emu/fpu_emu.h
rename to arch/x86/math-emu/fpu_emu.h
diff --git a/arch/i386/math-emu/fpu_entry.c b/arch/x86/math-emu/fpu_entry.c
similarity index 100%
rename from arch/i386/math-emu/fpu_entry.c
rename to arch/x86/math-emu/fpu_entry.c
diff --git a/arch/i386/math-emu/fpu_etc.c b/arch/x86/math-emu/fpu_etc.c
similarity index 100%
rename from arch/i386/math-emu/fpu_etc.c
rename to arch/x86/math-emu/fpu_etc.c
diff --git a/arch/i386/math-emu/fpu_proto.h b/arch/x86/math-emu/fpu_proto.h
similarity index 100%
rename from arch/i386/math-emu/fpu_proto.h
rename to arch/x86/math-emu/fpu_proto.h
diff --git a/arch/i386/math-emu/fpu_system.h b/arch/x86/math-emu/fpu_system.h
similarity index 100%
rename from arch/i386/math-emu/fpu_system.h
rename to arch/x86/math-emu/fpu_system.h
diff --git a/arch/i386/math-emu/fpu_tags.c b/arch/x86/math-emu/fpu_tags.c
similarity index 100%
rename from arch/i386/math-emu/fpu_tags.c
rename to arch/x86/math-emu/fpu_tags.c
diff --git a/arch/i386/math-emu/fpu_trig.c b/arch/x86/math-emu/fpu_trig.c
similarity index 100%
rename from arch/i386/math-emu/fpu_trig.c
rename to arch/x86/math-emu/fpu_trig.c
diff --git a/arch/i386/math-emu/get_address.c b/arch/x86/math-emu/get_address.c
similarity index 100%
rename from arch/i386/math-emu/get_address.c
rename to arch/x86/math-emu/get_address.c
diff --git a/arch/i386/math-emu/load_store.c b/arch/x86/math-emu/load_store.c
similarity index 100%
rename from arch/i386/math-emu/load_store.c
rename to arch/x86/math-emu/load_store.c
diff --git a/arch/i386/math-emu/mul_Xsig.S b/arch/x86/math-emu/mul_Xsig.S
similarity index 100%
rename from arch/i386/math-emu/mul_Xsig.S
rename to arch/x86/math-emu/mul_Xsig.S
diff --git a/arch/i386/math-emu/poly.h b/arch/x86/math-emu/poly.h
similarity index 100%
rename from arch/i386/math-emu/poly.h
rename to arch/x86/math-emu/poly.h
diff --git a/arch/i386/math-emu/poly_2xm1.c b/arch/x86/math-emu/poly_2xm1.c
similarity index 100%
rename from arch/i386/math-emu/poly_2xm1.c
rename to arch/x86/math-emu/poly_2xm1.c
diff --git a/arch/i386/math-emu/poly_atan.c b/arch/x86/math-emu/poly_atan.c
similarity index 100%
rename from arch/i386/math-emu/poly_atan.c
rename to arch/x86/math-emu/poly_atan.c
diff --git a/arch/i386/math-emu/poly_l2.c b/arch/x86/math-emu/poly_l2.c
similarity index 100%
rename from arch/i386/math-emu/poly_l2.c
rename to arch/x86/math-emu/poly_l2.c
diff --git a/arch/i386/math-emu/poly_sin.c b/arch/x86/math-emu/poly_sin.c
similarity index 100%
rename from arch/i386/math-emu/poly_sin.c
rename to arch/x86/math-emu/poly_sin.c
diff --git a/arch/i386/math-emu/poly_tan.c b/arch/x86/math-emu/poly_tan.c
similarity index 100%
rename from arch/i386/math-emu/poly_tan.c
rename to arch/x86/math-emu/poly_tan.c
diff --git a/arch/i386/math-emu/polynom_Xsig.S b/arch/x86/math-emu/polynom_Xsig.S
similarity index 100%
rename from arch/i386/math-emu/polynom_Xsig.S
rename to arch/x86/math-emu/polynom_Xsig.S
diff --git a/arch/i386/math-emu/reg_add_sub.c b/arch/x86/math-emu/reg_add_sub.c
similarity index 100%
rename from arch/i386/math-emu/reg_add_sub.c
rename to arch/x86/math-emu/reg_add_sub.c
diff --git a/arch/i386/math-emu/reg_compare.c b/arch/x86/math-emu/reg_compare.c
similarity index 100%
rename from arch/i386/math-emu/reg_compare.c
rename to arch/x86/math-emu/reg_compare.c
diff --git a/arch/i386/math-emu/reg_constant.c b/arch/x86/math-emu/reg_constant.c
similarity index 100%
rename from arch/i386/math-emu/reg_constant.c
rename to arch/x86/math-emu/reg_constant.c
diff --git a/arch/i386/math-emu/reg_constant.h b/arch/x86/math-emu/reg_constant.h
similarity index 100%
rename from arch/i386/math-emu/reg_constant.h
rename to arch/x86/math-emu/reg_constant.h
diff --git a/arch/i386/math-emu/reg_convert.c b/arch/x86/math-emu/reg_convert.c
similarity index 100%
rename from arch/i386/math-emu/reg_convert.c
rename to arch/x86/math-emu/reg_convert.c
diff --git a/arch/i386/math-emu/reg_divide.c b/arch/x86/math-emu/reg_divide.c
similarity index 100%
rename from arch/i386/math-emu/reg_divide.c
rename to arch/x86/math-emu/reg_divide.c
diff --git a/arch/i386/math-emu/reg_ld_str.c b/arch/x86/math-emu/reg_ld_str.c
similarity index 100%
rename from arch/i386/math-emu/reg_ld_str.c
rename to arch/x86/math-emu/reg_ld_str.c
diff --git a/arch/i386/math-emu/reg_mul.c b/arch/x86/math-emu/reg_mul.c
similarity index 100%
rename from arch/i386/math-emu/reg_mul.c
rename to arch/x86/math-emu/reg_mul.c
diff --git a/arch/i386/math-emu/reg_norm.S b/arch/x86/math-emu/reg_norm.S
similarity index 100%
rename from arch/i386/math-emu/reg_norm.S
rename to arch/x86/math-emu/reg_norm.S
diff --git a/arch/i386/math-emu/reg_round.S b/arch/x86/math-emu/reg_round.S
similarity index 100%
rename from arch/i386/math-emu/reg_round.S
rename to arch/x86/math-emu/reg_round.S
diff --git a/arch/i386/math-emu/reg_u_add.S b/arch/x86/math-emu/reg_u_add.S
similarity index 100%
rename from arch/i386/math-emu/reg_u_add.S
rename to arch/x86/math-emu/reg_u_add.S
diff --git a/arch/i386/math-emu/reg_u_div.S b/arch/x86/math-emu/reg_u_div.S
similarity index 100%
rename from arch/i386/math-emu/reg_u_div.S
rename to arch/x86/math-emu/reg_u_div.S
diff --git a/arch/i386/math-emu/reg_u_mul.S b/arch/x86/math-emu/reg_u_mul.S
similarity index 100%
rename from arch/i386/math-emu/reg_u_mul.S
rename to arch/x86/math-emu/reg_u_mul.S
diff --git a/arch/i386/math-emu/reg_u_sub.S b/arch/x86/math-emu/reg_u_sub.S
similarity index 100%
rename from arch/i386/math-emu/reg_u_sub.S
rename to arch/x86/math-emu/reg_u_sub.S
diff --git a/arch/i386/math-emu/round_Xsig.S b/arch/x86/math-emu/round_Xsig.S
similarity index 100%
rename from arch/i386/math-emu/round_Xsig.S
rename to arch/x86/math-emu/round_Xsig.S
diff --git a/arch/i386/math-emu/shr_Xsig.S b/arch/x86/math-emu/shr_Xsig.S
similarity index 100%
rename from arch/i386/math-emu/shr_Xsig.S
rename to arch/x86/math-emu/shr_Xsig.S
diff --git a/arch/i386/math-emu/status_w.h b/arch/x86/math-emu/status_w.h
similarity index 100%
rename from arch/i386/math-emu/status_w.h
rename to arch/x86/math-emu/status_w.h
diff --git a/arch/i386/math-emu/version.h b/arch/x86/math-emu/version.h
similarity index 100%
rename from arch/i386/math-emu/version.h
rename to arch/x86/math-emu/version.h
diff --git a/arch/i386/math-emu/wm_shrx.S b/arch/x86/math-emu/wm_shrx.S
similarity index 100%
rename from arch/i386/math-emu/wm_shrx.S
rename to arch/x86/math-emu/wm_shrx.S
diff --git a/arch/i386/math-emu/wm_sqrt.S b/arch/x86/math-emu/wm_sqrt.S
similarity index 100%
rename from arch/i386/math-emu/wm_sqrt.S
rename to arch/x86/math-emu/wm_sqrt.S
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
new file mode 100644
index 0000000..9832910
--- /dev/null
+++ b/arch/x86/mm/Makefile
@@ -0,0 +1,5 @@
+ifeq ($(CONFIG_X86_32),y)
+include ${srctree}/arch/x86/mm/Makefile_32
+else
+include ${srctree}/arch/x86/mm/Makefile_64
+endif
diff --git a/arch/x86/mm/Makefile_32 b/arch/x86/mm/Makefile_32
new file mode 100644
index 0000000..362b4ad
--- /dev/null
+++ b/arch/x86/mm/Makefile_32
@@ -0,0 +1,10 @@
+#
+# Makefile for the linux i386-specific parts of the memory manager.
+#
+
+obj-y	:= init_32.o pgtable_32.o fault_32.o ioremap_32.o extable_32.o pageattr_32.o mmap_32.o
+
+obj-$(CONFIG_NUMA) += discontig_32.o
+obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
+obj-$(CONFIG_HIGHMEM) += highmem_32.o
+obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap_32.o
diff --git a/arch/x86/mm/Makefile_64 b/arch/x86/mm/Makefile_64
new file mode 100644
index 0000000..6bcb479
--- /dev/null
+++ b/arch/x86/mm/Makefile_64
@@ -0,0 +1,10 @@
+#
+# Makefile for the linux x86_64-specific parts of the memory manager.
+#
+
+obj-y	 := init_64.o fault_64.o ioremap_64.o extable_64.o pageattr_64.o mmap_64.o
+obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
+obj-$(CONFIG_NUMA) += numa_64.o
+obj-$(CONFIG_K8_NUMA) += k8topology_64.o
+obj-$(CONFIG_ACPI_NUMA) += srat_64.o
+
diff --git a/arch/i386/mm/boot_ioremap.c b/arch/x86/mm/boot_ioremap_32.c
similarity index 100%
rename from arch/i386/mm/boot_ioremap.c
rename to arch/x86/mm/boot_ioremap_32.c
diff --git a/arch/i386/mm/discontig.c b/arch/x86/mm/discontig_32.c
similarity index 100%
rename from arch/i386/mm/discontig.c
rename to arch/x86/mm/discontig_32.c
diff --git a/arch/i386/mm/extable.c b/arch/x86/mm/extable_32.c
similarity index 100%
rename from arch/i386/mm/extable.c
rename to arch/x86/mm/extable_32.c
diff --git a/arch/x86_64/mm/extable.c b/arch/x86/mm/extable_64.c
similarity index 100%
rename from arch/x86_64/mm/extable.c
rename to arch/x86/mm/extable_64.c
diff --git a/arch/i386/mm/fault.c b/arch/x86/mm/fault_32.c
similarity index 100%
rename from arch/i386/mm/fault.c
rename to arch/x86/mm/fault_32.c
diff --git a/arch/x86_64/mm/fault.c b/arch/x86/mm/fault_64.c
similarity index 100%
rename from arch/x86_64/mm/fault.c
rename to arch/x86/mm/fault_64.c
diff --git a/arch/i386/mm/highmem.c b/arch/x86/mm/highmem_32.c
similarity index 100%
rename from arch/i386/mm/highmem.c
rename to arch/x86/mm/highmem_32.c
diff --git a/arch/i386/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
similarity index 100%
rename from arch/i386/mm/hugetlbpage.c
rename to arch/x86/mm/hugetlbpage.c
diff --git a/arch/i386/mm/init.c b/arch/x86/mm/init_32.c
similarity index 100%
rename from arch/i386/mm/init.c
rename to arch/x86/mm/init_32.c
diff --git a/arch/x86_64/mm/init.c b/arch/x86/mm/init_64.c
similarity index 100%
rename from arch/x86_64/mm/init.c
rename to arch/x86/mm/init_64.c
diff --git a/arch/i386/mm/ioremap.c b/arch/x86/mm/ioremap_32.c
similarity index 100%
rename from arch/i386/mm/ioremap.c
rename to arch/x86/mm/ioremap_32.c
diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86/mm/ioremap_64.c
similarity index 100%
rename from arch/x86_64/mm/ioremap.c
rename to arch/x86/mm/ioremap_64.c
diff --git a/arch/x86_64/mm/k8topology.c b/arch/x86/mm/k8topology_64.c
similarity index 100%
rename from arch/x86_64/mm/k8topology.c
rename to arch/x86/mm/k8topology_64.c
diff --git a/arch/i386/mm/mmap.c b/arch/x86/mm/mmap_32.c
similarity index 100%
rename from arch/i386/mm/mmap.c
rename to arch/x86/mm/mmap_32.c
diff --git a/arch/x86_64/mm/mmap.c b/arch/x86/mm/mmap_64.c
similarity index 100%
rename from arch/x86_64/mm/mmap.c
rename to arch/x86/mm/mmap_64.c
diff --git a/arch/x86_64/mm/numa.c b/arch/x86/mm/numa_64.c
similarity index 100%
rename from arch/x86_64/mm/numa.c
rename to arch/x86/mm/numa_64.c
diff --git a/arch/i386/mm/pageattr.c b/arch/x86/mm/pageattr_32.c
similarity index 100%
rename from arch/i386/mm/pageattr.c
rename to arch/x86/mm/pageattr_32.c
diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86/mm/pageattr_64.c
similarity index 100%
rename from arch/x86_64/mm/pageattr.c
rename to arch/x86/mm/pageattr_64.c
diff --git a/arch/i386/mm/pgtable.c b/arch/x86/mm/pgtable_32.c
similarity index 100%
rename from arch/i386/mm/pgtable.c
rename to arch/x86/mm/pgtable_32.c
diff --git a/arch/x86_64/mm/srat.c b/arch/x86/mm/srat_64.c
similarity index 100%
rename from arch/x86_64/mm/srat.c
rename to arch/x86/mm/srat_64.c
diff --git a/arch/i386/oprofile/Kconfig b/arch/x86/oprofile/Kconfig
similarity index 100%
rename from arch/i386/oprofile/Kconfig
rename to arch/x86/oprofile/Kconfig
diff --git a/arch/i386/oprofile/Makefile b/arch/x86/oprofile/Makefile
similarity index 100%
rename from arch/i386/oprofile/Makefile
rename to arch/x86/oprofile/Makefile
diff --git a/arch/i386/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c
similarity index 100%
rename from arch/i386/oprofile/backtrace.c
rename to arch/x86/oprofile/backtrace.c
diff --git a/arch/i386/oprofile/init.c b/arch/x86/oprofile/init.c
similarity index 100%
rename from arch/i386/oprofile/init.c
rename to arch/x86/oprofile/init.c
diff --git a/arch/i386/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
similarity index 100%
rename from arch/i386/oprofile/nmi_int.c
rename to arch/x86/oprofile/nmi_int.c
diff --git a/arch/i386/oprofile/nmi_timer_int.c b/arch/x86/oprofile/nmi_timer_int.c
similarity index 100%
rename from arch/i386/oprofile/nmi_timer_int.c
rename to arch/x86/oprofile/nmi_timer_int.c
diff --git a/arch/i386/oprofile/op_counter.h b/arch/x86/oprofile/op_counter.h
similarity index 100%
rename from arch/i386/oprofile/op_counter.h
rename to arch/x86/oprofile/op_counter.h
diff --git a/arch/i386/oprofile/op_model_athlon.c b/arch/x86/oprofile/op_model_athlon.c
similarity index 100%
rename from arch/i386/oprofile/op_model_athlon.c
rename to arch/x86/oprofile/op_model_athlon.c
diff --git a/arch/i386/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c
similarity index 100%
rename from arch/i386/oprofile/op_model_p4.c
rename to arch/x86/oprofile/op_model_p4.c
diff --git a/arch/i386/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c
similarity index 100%
rename from arch/i386/oprofile/op_model_ppro.c
rename to arch/x86/oprofile/op_model_ppro.c
diff --git a/arch/i386/oprofile/op_x86_model.h b/arch/x86/oprofile/op_x86_model.h
similarity index 100%
rename from arch/i386/oprofile/op_x86_model.h
rename to arch/x86/oprofile/op_x86_model.h
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
new file mode 100644
index 0000000..c5c8e48
--- /dev/null
+++ b/arch/x86/pci/Makefile
@@ -0,0 +1,5 @@
+ifeq ($(CONFIG_X86_32),y)
+include ${srctree}/arch/x86/pci/Makefile_32
+else
+include ${srctree}/arch/x86/pci/Makefile_64
+endif
diff --git a/arch/i386/pci/Makefile b/arch/x86/pci/Makefile_32
similarity index 80%
rename from arch/i386/pci/Makefile
rename to arch/x86/pci/Makefile_32
index 44650e0..cdd6828 100644
--- a/arch/i386/pci/Makefile
+++ b/arch/x86/pci/Makefile_32
@@ -1,7 +1,7 @@
 obj-y				:= i386.o init.o
 
 obj-$(CONFIG_PCI_BIOS)		+= pcbios.o
-obj-$(CONFIG_PCI_MMCONFIG)	+= mmconfig.o direct.o mmconfig-shared.o
+obj-$(CONFIG_PCI_MMCONFIG)	+= mmconfig_32.o direct.o mmconfig-shared.o
 obj-$(CONFIG_PCI_DIRECT)	+= direct.o
 
 pci-y				:= fixup.o
diff --git a/arch/x86/pci/Makefile_64 b/arch/x86/pci/Makefile_64
new file mode 100644
index 0000000..7d8c467
--- /dev/null
+++ b/arch/x86/pci/Makefile_64
@@ -0,0 +1,17 @@
+#
+# Makefile for X86_64 specific PCI routines
+#
+# Reuse the i386 PCI subsystem
+#
+EXTRA_CFLAGS += -Iarch/x86/pci
+
+obj-y		:= i386.o
+obj-$(CONFIG_PCI_DIRECT)+= direct.o
+obj-y		+= fixup.o init.o
+obj-$(CONFIG_ACPI)	+= acpi.o
+obj-y			+= legacy.o irq.o common.o early.o
+# mmconfig has a 64bit special
+obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_64.o direct.o mmconfig-shared.o
+
+obj-$(CONFIG_NUMA)	+= k8-bus_64.o
+
diff --git a/arch/i386/pci/acpi.c b/arch/x86/pci/acpi.c
similarity index 100%
rename from arch/i386/pci/acpi.c
rename to arch/x86/pci/acpi.c
diff --git a/arch/i386/pci/common.c b/arch/x86/pci/common.c
similarity index 100%
rename from arch/i386/pci/common.c
rename to arch/x86/pci/common.c
diff --git a/arch/i386/pci/direct.c b/arch/x86/pci/direct.c
similarity index 100%
rename from arch/i386/pci/direct.c
rename to arch/x86/pci/direct.c
diff --git a/arch/i386/pci/early.c b/arch/x86/pci/early.c
similarity index 100%
rename from arch/i386/pci/early.c
rename to arch/x86/pci/early.c
diff --git a/arch/i386/pci/fixup.c b/arch/x86/pci/fixup.c
similarity index 100%
rename from arch/i386/pci/fixup.c
rename to arch/x86/pci/fixup.c
diff --git a/arch/i386/pci/i386.c b/arch/x86/pci/i386.c
similarity index 100%
rename from arch/i386/pci/i386.c
rename to arch/x86/pci/i386.c
diff --git a/arch/i386/pci/init.c b/arch/x86/pci/init.c
similarity index 100%
rename from arch/i386/pci/init.c
rename to arch/x86/pci/init.c
diff --git a/arch/i386/pci/irq.c b/arch/x86/pci/irq.c
similarity index 100%
rename from arch/i386/pci/irq.c
rename to arch/x86/pci/irq.c
diff --git a/arch/x86_64/pci/k8-bus.c b/arch/x86/pci/k8-bus_64.c
similarity index 100%
rename from arch/x86_64/pci/k8-bus.c
rename to arch/x86/pci/k8-bus_64.c
diff --git a/arch/i386/pci/legacy.c b/arch/x86/pci/legacy.c
similarity index 100%
rename from arch/i386/pci/legacy.c
rename to arch/x86/pci/legacy.c
diff --git a/arch/i386/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
similarity index 100%
rename from arch/i386/pci/mmconfig-shared.c
rename to arch/x86/pci/mmconfig-shared.c
diff --git a/arch/i386/pci/mmconfig.c b/arch/x86/pci/mmconfig_32.c
similarity index 100%
rename from arch/i386/pci/mmconfig.c
rename to arch/x86/pci/mmconfig_32.c
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86/pci/mmconfig_64.c
similarity index 100%
rename from arch/x86_64/pci/mmconfig.c
rename to arch/x86/pci/mmconfig_64.c
diff --git a/arch/i386/pci/numa.c b/arch/x86/pci/numa.c
similarity index 100%
rename from arch/i386/pci/numa.c
rename to arch/x86/pci/numa.c
diff --git a/arch/i386/pci/pcbios.c b/arch/x86/pci/pcbios.c
similarity index 100%
rename from arch/i386/pci/pcbios.c
rename to arch/x86/pci/pcbios.c
diff --git a/arch/i386/pci/pci.h b/arch/x86/pci/pci.h
similarity index 100%
rename from arch/i386/pci/pci.h
rename to arch/x86/pci/pci.h
diff --git a/arch/i386/pci/visws.c b/arch/x86/pci/visws.c
similarity index 100%
rename from arch/i386/pci/visws.c
rename to arch/x86/pci/visws.c
diff --git a/arch/i386/power/Makefile b/arch/x86/power/Makefile
similarity index 100%
rename from arch/i386/power/Makefile
rename to arch/x86/power/Makefile
diff --git a/arch/i386/power/cpu.c b/arch/x86/power/cpu.c
similarity index 100%
rename from arch/i386/power/cpu.c
rename to arch/x86/power/cpu.c
diff --git a/arch/i386/power/suspend.c b/arch/x86/power/suspend.c
similarity index 100%
rename from arch/i386/power/suspend.c
rename to arch/x86/power/suspend.c
diff --git a/arch/i386/power/swsusp.S b/arch/x86/power/swsusp.S
similarity index 100%
rename from arch/i386/power/swsusp.S
rename to arch/x86/power/swsusp.S
diff --git a/arch/x86_64/vdso/.gitignore b/arch/x86/vdso/.gitignore
similarity index 100%
rename from arch/x86_64/vdso/.gitignore
rename to arch/x86/vdso/.gitignore
diff --git a/arch/x86_64/vdso/Makefile b/arch/x86/vdso/Makefile
similarity index 100%
rename from arch/x86_64/vdso/Makefile
rename to arch/x86/vdso/Makefile
diff --git a/arch/x86_64/vdso/vclock_gettime.c b/arch/x86/vdso/vclock_gettime.c
similarity index 100%
rename from arch/x86_64/vdso/vclock_gettime.c
rename to arch/x86/vdso/vclock_gettime.c
diff --git a/arch/x86_64/vdso/vdso-note.S b/arch/x86/vdso/vdso-note.S
similarity index 100%
rename from arch/x86_64/vdso/vdso-note.S
rename to arch/x86/vdso/vdso-note.S
diff --git a/arch/x86_64/vdso/vdso-start.S b/arch/x86/vdso/vdso-start.S
similarity index 100%
rename from arch/x86_64/vdso/vdso-start.S
rename to arch/x86/vdso/vdso-start.S
diff --git a/arch/x86/vdso/vdso.S b/arch/x86/vdso/vdso.S
new file mode 100644
index 0000000..4b1620a
--- /dev/null
+++ b/arch/x86/vdso/vdso.S
@@ -0,0 +1,2 @@
+	.section ".vdso","a"
+	.incbin "arch/x86/vdso/vdso.so"
diff --git a/arch/x86_64/vdso/vdso.lds.S b/arch/x86/vdso/vdso.lds.S
similarity index 100%
rename from arch/x86_64/vdso/vdso.lds.S
rename to arch/x86/vdso/vdso.lds.S
diff --git a/arch/x86_64/vdso/vextern.h b/arch/x86/vdso/vextern.h
similarity index 100%
rename from arch/x86_64/vdso/vextern.h
rename to arch/x86/vdso/vextern.h
diff --git a/arch/x86_64/vdso/vgetcpu.c b/arch/x86/vdso/vgetcpu.c
similarity index 100%
rename from arch/x86_64/vdso/vgetcpu.c
rename to arch/x86/vdso/vgetcpu.c
diff --git a/arch/x86_64/vdso/vma.c b/arch/x86/vdso/vma.c
similarity index 100%
rename from arch/x86_64/vdso/vma.c
rename to arch/x86/vdso/vma.c
diff --git a/arch/x86_64/vdso/voffset.h b/arch/x86/vdso/voffset.h
similarity index 100%
rename from arch/x86_64/vdso/voffset.h
rename to arch/x86/vdso/voffset.h
diff --git a/arch/x86_64/vdso/vvar.c b/arch/x86/vdso/vvar.c
similarity index 100%
rename from arch/x86_64/vdso/vvar.c
rename to arch/x86/vdso/vvar.c
diff --git a/arch/i386/video/Makefile b/arch/x86/video/Makefile
similarity index 100%
rename from arch/i386/video/Makefile
rename to arch/x86/video/Makefile
diff --git a/arch/i386/video/fbdev.c b/arch/x86/video/fbdev.c
similarity index 100%
rename from arch/i386/video/fbdev.c
rename to arch/x86/video/fbdev.c
diff --git a/arch/i386/xen/Kconfig b/arch/x86/xen/Kconfig
similarity index 100%
rename from arch/i386/xen/Kconfig
rename to arch/x86/xen/Kconfig
diff --git a/arch/i386/xen/Makefile b/arch/x86/xen/Makefile
similarity index 100%
rename from arch/i386/xen/Makefile
rename to arch/x86/xen/Makefile
diff --git a/arch/i386/xen/enlighten.c b/arch/x86/xen/enlighten.c
similarity index 100%
rename from arch/i386/xen/enlighten.c
rename to arch/x86/xen/enlighten.c
diff --git a/arch/i386/xen/events.c b/arch/x86/xen/events.c
similarity index 100%
rename from arch/i386/xen/events.c
rename to arch/x86/xen/events.c
diff --git a/arch/i386/xen/features.c b/arch/x86/xen/features.c
similarity index 100%
rename from arch/i386/xen/features.c
rename to arch/x86/xen/features.c
diff --git a/arch/i386/xen/manage.c b/arch/x86/xen/manage.c
similarity index 100%
rename from arch/i386/xen/manage.c
rename to arch/x86/xen/manage.c
diff --git a/arch/i386/xen/mmu.c b/arch/x86/xen/mmu.c
similarity index 100%
rename from arch/i386/xen/mmu.c
rename to arch/x86/xen/mmu.c
diff --git a/arch/i386/xen/mmu.h b/arch/x86/xen/mmu.h
similarity index 100%
rename from arch/i386/xen/mmu.h
rename to arch/x86/xen/mmu.h
diff --git a/arch/i386/xen/multicalls.c b/arch/x86/xen/multicalls.c
similarity index 100%
rename from arch/i386/xen/multicalls.c
rename to arch/x86/xen/multicalls.c
diff --git a/arch/i386/xen/multicalls.h b/arch/x86/xen/multicalls.h
similarity index 100%
rename from arch/i386/xen/multicalls.h
rename to arch/x86/xen/multicalls.h
diff --git a/arch/i386/xen/setup.c b/arch/x86/xen/setup.c
similarity index 100%
rename from arch/i386/xen/setup.c
rename to arch/x86/xen/setup.c
diff --git a/arch/i386/xen/smp.c b/arch/x86/xen/smp.c
similarity index 100%
rename from arch/i386/xen/smp.c
rename to arch/x86/xen/smp.c
diff --git a/arch/i386/xen/time.c b/arch/x86/xen/time.c
similarity index 100%
rename from arch/i386/xen/time.c
rename to arch/x86/xen/time.c
diff --git a/arch/i386/xen/vdso.h b/arch/x86/xen/vdso.h
similarity index 100%
rename from arch/i386/xen/vdso.h
rename to arch/x86/xen/vdso.h
diff --git a/arch/i386/xen/xen-asm.S b/arch/x86/xen/xen-asm.S
similarity index 100%
rename from arch/i386/xen/xen-asm.S
rename to arch/x86/xen/xen-asm.S
diff --git a/arch/i386/xen/xen-head.S b/arch/x86/xen/xen-head.S
similarity index 100%
rename from arch/i386/xen/xen-head.S
rename to arch/x86/xen/xen-head.S
diff --git a/arch/i386/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
similarity index 100%
rename from arch/i386/xen/xen-ops.h
rename to arch/x86/xen/xen-ops.h
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index b4d9089..b1b98e6 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -704,7 +704,7 @@
 
 source "drivers/acpi/Kconfig"
 
-source "arch/x86_64/kernel/cpufreq/Kconfig"
+source "arch/x86/kernel/cpufreq/Kconfig"
 
 endmenu
 
@@ -778,7 +778,7 @@
 menu "Instrumentation Support"
         depends on EXPERIMENTAL
 
-source "arch/x86_64/oprofile/Kconfig"
+source "arch/x86/oprofile/Kconfig"
 
 config KPROBES
 	bool "Kprobes"
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile
index b024e4a..8bffb94 100644
--- a/arch/x86_64/Makefile
+++ b/arch/x86_64/Makefile
@@ -21,6 +21,9 @@
 #
 # $Id: Makefile,v 1.31 2002/03/22 15:56:07 ak Exp $
 
+# Fill in SRCARCH
+SRCARCH	:= x86
+
 LDFLAGS		:= -m elf_x86_64
 OBJCOPYFLAGS	:= -O binary -R .note -R .comment -S
 LDFLAGS_vmlinux :=
@@ -71,18 +74,18 @@
 CFLAGS_KERNEL += $(cflags-kernel-y)
 AFLAGS += -m64
 
-head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o
+head-y := arch/x86/kernel/head_64.o arch/x86/kernel/head64.o arch/x86/kernel/init_task_64.o
 
-libs-y 					+= arch/x86_64/lib/
-core-y					+= arch/x86_64/kernel/ \
-					   arch/x86_64/mm/ \
-					   arch/x86_64/crypto/ \
-					   arch/x86_64/vdso/
-core-$(CONFIG_IA32_EMULATION)		+= arch/x86_64/ia32/
-drivers-$(CONFIG_PCI)			+= arch/x86_64/pci/
-drivers-$(CONFIG_OPROFILE)		+= arch/x86_64/oprofile/
+libs-y 					+= arch/x86/lib/
+core-y					+= arch/x86/kernel/ \
+					   arch/x86/mm/ \
+					   arch/x86/crypto/ \
+					   arch/x86/vdso/
+core-$(CONFIG_IA32_EMULATION)		+= arch/x86/ia32/
+drivers-$(CONFIG_PCI)			+= arch/x86/pci/
+drivers-$(CONFIG_OPROFILE)		+= arch/x86/oprofile/
 
-boot := arch/x86_64/boot
+boot := arch/x86/boot
 
 PHONY += bzImage bzlilo install archmrproper \
 	 fdimage fdimage144 fdimage288 isoimage archclean
@@ -90,10 +93,12 @@
 #Default target when executing "make"
 all: bzImage
 
-BOOTIMAGE                     := arch/x86_64/boot/bzImage
+BOOTIMAGE                     := arch/x86/boot/bzImage
 KBUILD_IMAGE                  := $(BOOTIMAGE)
 
 bzImage: vmlinux
+	$(Q)mkdir -p $(objtree)/arch/x86_64/boot
+	$(Q)ln -fsn $(objtree)/arch/x86/boot/bzImage $(objtree)/arch/x86_64/boot/bzImage
 	$(Q)$(MAKE) $(build)=$(boot) $(BOOTIMAGE)
 
 bzlilo: vmlinux
@@ -109,6 +114,7 @@
 	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@ 
 
 archclean:
+	$(Q)rm -rf $(objtree)/arch/x86_64/boot
 	$(Q)$(MAKE) $(clean)=$(boot)
 
 define archhelp
diff --git a/arch/x86_64/boot/.gitignore b/arch/x86_64/boot/.gitignore
deleted file mode 100644
index 1846514..0000000
--- a/arch/x86_64/boot/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-bootsect
-bzImage
-setup
-setup.bin
-setup.elf
diff --git a/arch/x86_64/boot/Makefile b/arch/x86_64/boot/Makefile
deleted file mode 100644
index 6709638..0000000
--- a/arch/x86_64/boot/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# arch/x86_64/boot/Makefile
-#
-# The actual boot code is shared with i386 including the Makefile.
-# So tell kbuild that we fetch the code from i386 and include the
-# Makefile from i386 too.
-
-src := arch/i386/boot
-include $(src)/Makefile
diff --git a/arch/x86_64/boot/tools/.gitignore b/arch/x86_64/boot/tools/.gitignore
deleted file mode 100644
index 378eac2..0000000
--- a/arch/x86_64/boot/tools/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-build
diff --git a/arch/x86_64/crypto/Makefile b/arch/x86_64/crypto/Makefile
deleted file mode 100644
index 15b538a..0000000
--- a/arch/x86_64/crypto/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# 
-# x86_64/crypto/Makefile 
-# 
-# Arch-specific CryptoAPI modules.
-# 
-
-obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o
-obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o
-
-aes-x86_64-y := aes-x86_64-asm.o aes.o
-twofish-x86_64-y := twofish-x86_64-asm.o twofish.o
-
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
deleted file mode 100644
index ff5d8c9..0000000
--- a/arch/x86_64/kernel/Makefile
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-extra-y 	:= head.o head64.o init_task.o vmlinux.lds
-EXTRA_AFLAGS	:= -traditional
-obj-y	:= process.o signal.o entry.o traps.o irq.o \
-		ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \
-		x8664_ksyms.o i387.o syscall.o vsyscall.o \
-		setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \
-		pci-dma.o pci-nommu.o alternative.o hpet.o tsc.o bugs.o \
-		perfctr-watchdog.o
-
-obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
-obj-$(CONFIG_X86_MCE)		+= mce.o therm_throt.o
-obj-$(CONFIG_X86_MCE_INTEL)	+= mce_intel.o
-obj-$(CONFIG_X86_MCE_AMD)	+= mce_amd.o
-obj-$(CONFIG_MTRR)		+= ../../i386/kernel/cpu/mtrr/
-obj-$(CONFIG_ACPI)		+= acpi/
-obj-$(CONFIG_X86_MSR)		+= msr.o
-obj-$(CONFIG_MICROCODE)		+= microcode.o
-obj-$(CONFIG_X86_CPUID)		+= cpuid.o
-obj-$(CONFIG_SMP)		+= smp.o smpboot.o trampoline.o tsc_sync.o
-obj-y				+= apic.o  nmi.o
-obj-y				+= io_apic.o mpparse.o genapic.o genapic_flat.o
-obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o crash.o
-obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
-obj-$(CONFIG_PM)		+= suspend.o
-obj-$(CONFIG_HIBERNATION)	+= suspend_asm.o
-obj-$(CONFIG_CPU_FREQ)		+= cpufreq/
-obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
-obj-$(CONFIG_IOMMU)		+= pci-gart.o aperture.o
-obj-$(CONFIG_CALGARY_IOMMU)	+= pci-calgary.o tce.o
-obj-$(CONFIG_SWIOTLB)		+= pci-swiotlb.o
-obj-$(CONFIG_KPROBES)		+= kprobes.o
-obj-$(CONFIG_X86_PM_TIMER)	+= pmtimer.o
-obj-$(CONFIG_X86_VSMP)		+= vsmp.o
-obj-$(CONFIG_K8_NB)		+= k8.o
-obj-$(CONFIG_AUDIT)		+= audit.o
-
-obj-$(CONFIG_MODULES)		+= module.o
-obj-$(CONFIG_PCI)		+= early-quirks.o
-
-obj-y				+= topology.o
-obj-y				+= intel_cacheinfo.o
-obj-y				+= addon_cpuid_features.o
-obj-y				+= pcspeaker.o
-
-CFLAGS_vsyscall.o		:= $(PROFILING) -g0
-
-therm_throt-y                   += ../../i386/kernel/cpu/mcheck/therm_throt.o
-bootflag-y			+= ../../i386/kernel/bootflag.o
-cpuid-$(subst m,y,$(CONFIG_X86_CPUID))  += ../../i386/kernel/cpuid.o
-topology-y                     += ../../i386/kernel/topology.o
-microcode-$(subst m,y,$(CONFIG_MICROCODE))  += ../../i386/kernel/microcode.o
-intel_cacheinfo-y		+= ../../i386/kernel/cpu/intel_cacheinfo.o
-addon_cpuid_features-y		+= ../../i386/kernel/cpu/addon_cpuid_features.o
-quirks-y			+= ../../i386/kernel/quirks.o
-i8237-y				+= ../../i386/kernel/i8237.o
-msr-$(subst m,y,$(CONFIG_X86_MSR))  += ../../i386/kernel/msr.o
-alternative-y			+= ../../i386/kernel/alternative.o
-pcspeaker-y			+= ../../i386/kernel/pcspeaker.o
-perfctr-watchdog-y		+= ../../i386/kernel/cpu/perfctr-watchdog.o
diff --git a/arch/x86_64/kernel/acpi/Makefile b/arch/x86_64/kernel/acpi/Makefile
deleted file mode 100644
index 080b996..0000000
--- a/arch/x86_64/kernel/acpi/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-obj-y			:= boot.o
-boot-y			:= ../../../i386/kernel/acpi/boot.o
-obj-$(CONFIG_ACPI_SLEEP)	+= sleep.o wakeup.o
-
-ifneq ($(CONFIG_ACPI_PROCESSOR),)
-obj-y			+= processor.o
-processor-y		:= ../../../i386/kernel/acpi/processor.o ../../../i386/kernel/acpi/cstate.o
-endif
-
diff --git a/arch/x86_64/kernel/cpufreq/Makefile b/arch/x86_64/kernel/cpufreq/Makefile
deleted file mode 100644
index 753ce1d..0000000
--- a/arch/x86_64/kernel/cpufreq/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Reuse the i386 cpufreq drivers
-#
-
-SRCDIR := ../../../i386/kernel/cpu/cpufreq
-
-obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
-obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o
-obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o
-obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o
-obj-$(CONFIG_X86_SPEEDSTEP_LIB) += speedstep-lib.o
-
-powernow-k8-objs := ${SRCDIR}/powernow-k8.o
-speedstep-centrino-objs := ${SRCDIR}/speedstep-centrino.o
-acpi-cpufreq-objs := ${SRCDIR}/acpi-cpufreq.o
-p4-clockmod-objs := ${SRCDIR}/p4-clockmod.o
-speedstep-lib-objs := ${SRCDIR}/speedstep-lib.o
diff --git a/arch/x86_64/lib/Makefile b/arch/x86_64/lib/Makefile
deleted file mode 100644
index c943271..0000000
--- a/arch/x86_64/lib/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# Makefile for x86_64-specific library files.
-#
-
-CFLAGS_csum-partial.o := -funroll-loops
-
-obj-y := io.o iomap_copy.o
-obj-$(CONFIG_SMP)	+= msr-on-cpu.o
-
-lib-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \
-	usercopy.o getuser.o putuser.o  \
-	thunk.o clear_page.o copy_page.o bitstr.o bitops.o
-lib-y += memcpy.o memmove.o memset.o copy_user.o rwlock.o copy_user_nocache.o
diff --git a/arch/x86_64/lib/msr-on-cpu.c b/arch/x86_64/lib/msr-on-cpu.c
deleted file mode 100644
index 47e0ec4..0000000
--- a/arch/x86_64/lib/msr-on-cpu.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../i386/lib/msr-on-cpu.c"
diff --git a/arch/x86_64/mm/Makefile b/arch/x86_64/mm/Makefile
deleted file mode 100644
index d25ac86..0000000
--- a/arch/x86_64/mm/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Makefile for the linux x86_64-specific parts of the memory manager.
-#
-
-obj-y	 := init.o fault.o ioremap.o extable.o pageattr.o mmap.o
-obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
-obj-$(CONFIG_NUMA) += numa.o
-obj-$(CONFIG_K8_NUMA) += k8topology.o
-obj-$(CONFIG_ACPI_NUMA) += srat.o
-
-hugetlbpage-y = ../../i386/mm/hugetlbpage.o
diff --git a/arch/x86_64/oprofile/Kconfig b/arch/x86_64/oprofile/Kconfig
deleted file mode 100644
index d8a8408..0000000
--- a/arch/x86_64/oprofile/Kconfig
+++ /dev/null
@@ -1,17 +0,0 @@
-config PROFILING
-	bool "Profiling support (EXPERIMENTAL)"
-	help
-	  Say Y here to enable the extended profiling support mechanisms used
-	  by profilers such as OProfile.
-	  
-
-config OPROFILE
-	tristate "OProfile system profiling (EXPERIMENTAL)"
-	depends on PROFILING
-	help
-	  OProfile is a profiling system capable of profiling the
-	  whole system, include the kernel, kernel modules, libraries,
-	  and applications.
-
-	  If unsure, say N.
-
diff --git a/arch/x86_64/oprofile/Makefile b/arch/x86_64/oprofile/Makefile
deleted file mode 100644
index 6be3268..0000000
--- a/arch/x86_64/oprofile/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# oprofile for x86-64.
-# Just reuse the one from i386. 
-#
-
-obj-$(CONFIG_OPROFILE) += oprofile.o
- 
-DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
-	oprof.o cpu_buffer.o buffer_sync.o \
-	event_buffer.o oprofile_files.o \
-	oprofilefs.o oprofile_stats.o \
-	timer_int.o )
-
-OPROFILE-y := init.o backtrace.o
-OPROFILE-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o op_model_p4.o \
-				     op_model_ppro.o
-OPROFILE-$(CONFIG_X86_IO_APIC)    += nmi_timer_int.o 
-
-oprofile-y = $(DRIVER_OBJS) $(addprefix ../../i386/oprofile/, $(OPROFILE-y))
diff --git a/arch/x86_64/pci/Makefile b/arch/x86_64/pci/Makefile
deleted file mode 100644
index c9eddc8..0000000
--- a/arch/x86_64/pci/Makefile
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Makefile for X86_64 specific PCI routines
-#
-# Reuse the i386 PCI subsystem
-#
-EXTRA_CFLAGS += -Iarch/i386/pci
-
-obj-y		:= i386.o
-obj-$(CONFIG_PCI_DIRECT)+= direct.o
-obj-y		+= fixup.o init.o
-obj-$(CONFIG_ACPI)	+= acpi.o
-obj-y			+= legacy.o irq.o common.o early.o
-# mmconfig has a 64bit special
-obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o mmconfig-shared.o
-
-obj-$(CONFIG_NUMA)	+= k8-bus.o
-
-direct-y += ../../i386/pci/direct.o
-acpi-y   += ../../i386/pci/acpi.o
-legacy-y += ../../i386/pci/legacy.o
-irq-y    += ../../i386/pci/irq.o
-common-y += ../../i386/pci/common.o
-fixup-y  += ../../i386/pci/fixup.o
-i386-y  += ../../i386/pci/i386.o
-init-y += ../../i386/pci/init.o
-early-y += ../../i386/pci/early.o
-mmconfig-shared-y += ../../i386/pci/mmconfig-shared.o
diff --git a/arch/x86_64/vdso/vdso.S b/arch/x86_64/vdso/vdso.S
deleted file mode 100644
index 92e80c1..0000000
--- a/arch/x86_64/vdso/vdso.S
+++ /dev/null
@@ -1,2 +0,0 @@
-	.section ".vdso","a"
-	.incbin "arch/x86_64/vdso/vdso.so"
diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig
index a49cb97..aa8a4e4 100644
--- a/drivers/mmc/card/Kconfig
+++ b/drivers/mmc/card/Kconfig
@@ -32,3 +32,10 @@
 
 	  If unsure, say Y here.
 
+config SDIO_UART
+	tristate "SDIO UART/GPS class support"
+	depends on MMC
+	help
+	  SDIO function driver for SDIO cards that implements the UART
+	  class, as well as the GPS class which appears like a UART.
+
diff --git a/drivers/mmc/card/Makefile b/drivers/mmc/card/Makefile
index cf8c939..fc5a784 100644
--- a/drivers/mmc/card/Makefile
+++ b/drivers/mmc/card/Makefile
@@ -9,3 +9,5 @@
 obj-$(CONFIG_MMC_BLOCK)		+= mmc_block.o
 mmc_block-objs			:= block.o queue.o
 
+obj-$(CONFIG_SDIO_UART)		+= sdio_uart.o
+
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 93fe2e5..e38d5a3 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -151,17 +151,19 @@
 
 	cmd.opcode = MMC_APP_CMD;
 	cmd.arg = card->rca << 16;
-	cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
 
 	err = mmc_wait_for_cmd(card->host, &cmd, 0);
-	if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD))
+	if (err)
+		return (u32)-1;
+	if (!mmc_host_is_spi(card->host) && !(cmd.resp[0] & R1_APP_CMD))
 		return (u32)-1;
 
 	memset(&cmd, 0, sizeof(struct mmc_command));
 
 	cmd.opcode = SD_APP_SEND_NUM_WR_BLKS;
 	cmd.arg = 0;
-	cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
 
 	memset(&data, 0, sizeof(struct mmc_data));
 
@@ -192,7 +194,7 @@
 
 	mmc_wait_for_req(card->host, &mrq);
 
-	if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE)
+	if (cmd.error || data.error)
 		return (u32)-1;
 
 	blocks = ntohl(blocks);
@@ -220,17 +222,15 @@
 		brq.cmd.arg = req->sector;
 		if (!mmc_card_blockaddr(card))
 			brq.cmd.arg <<= 9;
-		brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+		brq.cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
 		brq.data.blksz = 1 << md->block_bits;
 		brq.stop.opcode = MMC_STOP_TRANSMISSION;
 		brq.stop.arg = 0;
-		brq.stop.flags = MMC_RSP_R1B | MMC_CMD_AC;
+		brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
 		brq.data.blocks = req->nr_sectors >> (md->block_bits - 9);
 		if (brq.data.blocks > card->host->max_blk_count)
 			brq.data.blocks = card->host->max_blk_count;
 
-		mmc_set_data_timeout(&brq.data, card, rq_data_dir(req) != READ);
-
 		/*
 		 * If the host doesn't support multiple block writes, force
 		 * block writes to single block. SD cards are excepted from
@@ -243,8 +243,12 @@
 			brq.data.blocks = 1;
 
 		if (brq.data.blocks > 1) {
-			brq.data.flags |= MMC_DATA_MULTI;
-			brq.mrq.stop = &brq.stop;
+			/* SPI multiblock writes terminate using a special
+			 * token, not a STOP_TRANSMISSION request.
+			 */
+			if (!mmc_host_is_spi(card->host)
+					|| rq_data_dir(req) == READ)
+				brq.mrq.stop = &brq.stop;
 			readcmd = MMC_READ_MULTIPLE_BLOCK;
 			writecmd = MMC_WRITE_MULTIPLE_BLOCK;
 		} else {
@@ -261,6 +265,8 @@
 			brq.data.flags |= MMC_DATA_WRITE;
 		}
 
+		mmc_set_data_timeout(&brq.data, card);
+
 		brq.data.sg = mq->sg;
 		brq.data.sg_len = mmc_queue_map_sg(mq);
 
@@ -302,7 +308,7 @@
 			goto cmd_err;
 		}
 
-		if (rq_data_dir(req) != READ) {
+		if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
 			do {
 				int err;
 
@@ -510,7 +516,7 @@
 	mmc_claim_host(card->host);
 	cmd.opcode = MMC_SET_BLOCKLEN;
 	cmd.arg = 1 << md->block_bits;
-	cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
 	err = mmc_wait_for_cmd(card->host, &cmd, 5);
 	mmc_release_host(card->host);
 
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
new file mode 100644
index 0000000..d552de6
--- /dev/null
+++ b/drivers/mmc/card/sdio_uart.c
@@ -0,0 +1,1158 @@
+/*
+ * linux/drivers/mmc/card/sdio_uart.c - SDIO UART/GPS driver
+ *
+ * Based on drivers/serial/8250.c and drivers/serial/serial_core.c
+ * by Russell King.
+ *
+ * Author:	Nicolas Pitre
+ * Created:	June 15, 2007
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+/*
+ * Note: Although this driver assumes a 16550A-like UART implementation,
+ * it is not possible to leverage the common 8250/16550 driver, nor the
+ * core UART infrastructure, as they assumes direct access to the hardware
+ * registers, often under a spinlock.  This is not possible in the SDIO
+ * context as SDIO access functions must be able to sleep.
+ *
+ * Because we need to lock the SDIO host to ensure an exclusive access to
+ * the card, we simply rely on that lock to also prevent and serialize
+ * concurrent access to the same port.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/serial_reg.h>
+#include <linux/circ_buf.h>
+#include <linux/gfp.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+
+#include <linux/mmc/core.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+
+
+#define UART_NR		8	/* Number of UARTs this driver can handle */
+
+
+#define UART_XMIT_SIZE	PAGE_SIZE
+#define WAKEUP_CHARS	256
+
+#define circ_empty(circ)	((circ)->head == (circ)->tail)
+#define circ_clear(circ)	((circ)->head = (circ)->tail = 0)
+
+#define circ_chars_pending(circ) \
+		(CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE))
+
+#define circ_chars_free(circ) \
+		(CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))
+
+
+struct uart_icount {
+	__u32	cts;
+	__u32	dsr;
+	__u32	rng;
+	__u32	dcd;
+	__u32	rx;
+	__u32	tx;
+	__u32	frame;
+	__u32	overrun;
+	__u32	parity;
+	__u32	brk;
+};
+
+struct sdio_uart_port {
+	struct kref		kref;
+	struct tty_struct	*tty;
+	unsigned int		index;
+	unsigned int		opened;
+	struct mutex		open_lock;
+	struct sdio_func	*func;
+	struct mutex		func_lock;
+	struct task_struct	*in_sdio_uart_irq;
+	unsigned int		regs_offset;
+	struct circ_buf		xmit;
+	spinlock_t		write_lock;
+	struct uart_icount	icount;
+	unsigned int		uartclk;
+	unsigned int		mctrl;
+	unsigned int		read_status_mask;
+	unsigned int		ignore_status_mask;
+	unsigned char		x_char;
+	unsigned char           ier;
+	unsigned char           lcr;
+};
+
+static struct sdio_uart_port *sdio_uart_table[UART_NR];
+static DEFINE_SPINLOCK(sdio_uart_table_lock);
+
+static int sdio_uart_add_port(struct sdio_uart_port *port)
+{
+	int index, ret = -EBUSY;
+
+	kref_init(&port->kref);
+	mutex_init(&port->open_lock);
+	mutex_init(&port->func_lock);
+	spin_lock_init(&port->write_lock);
+
+	spin_lock(&sdio_uart_table_lock);
+	for (index = 0; index < UART_NR; index++) {
+		if (!sdio_uart_table[index]) {
+			port->index = index;
+			sdio_uart_table[index] = port;
+			ret = 0;
+			break;
+		}
+	}
+	spin_unlock(&sdio_uart_table_lock);
+
+	return ret;
+}
+
+static struct sdio_uart_port *sdio_uart_port_get(unsigned index)
+{
+	struct sdio_uart_port *port;
+
+	if (index >= UART_NR)
+		return NULL;
+
+	spin_lock(&sdio_uart_table_lock);
+	port = sdio_uart_table[index];
+	if (port)
+		kref_get(&port->kref);
+	spin_unlock(&sdio_uart_table_lock);
+
+	return port;
+}
+
+static void sdio_uart_port_destroy(struct kref *kref)
+{
+	struct sdio_uart_port *port =
+		container_of(kref, struct sdio_uart_port, kref);
+	kfree(port);
+}
+
+static void sdio_uart_port_put(struct sdio_uart_port *port)
+{
+	kref_put(&port->kref, sdio_uart_port_destroy);
+}
+
+static void sdio_uart_port_remove(struct sdio_uart_port *port)
+{
+	struct sdio_func *func;
+
+	BUG_ON(sdio_uart_table[port->index] != port);
+
+	spin_lock(&sdio_uart_table_lock);
+	sdio_uart_table[port->index] = NULL;
+	spin_unlock(&sdio_uart_table_lock);
+
+	/*
+	 * We're killing a port that potentially still is in use by
+	 * the tty layer. Be careful to prevent any further access
+	 * to the SDIO function and arrange for the tty layer to
+	 * give up on that port ASAP.
+	 * Beware: the lock ordering is critical.
+	 */
+	mutex_lock(&port->open_lock);
+	mutex_lock(&port->func_lock);
+	func = port->func;
+	sdio_claim_host(func);
+	port->func = NULL;
+	mutex_unlock(&port->func_lock);
+	if (port->opened)
+		tty_hangup(port->tty);
+	mutex_unlock(&port->open_lock);
+	sdio_release_irq(func);
+	sdio_disable_func(func);
+	sdio_release_host(func);
+
+	sdio_uart_port_put(port);
+}
+
+static int sdio_uart_claim_func(struct sdio_uart_port *port)
+{
+	mutex_lock(&port->func_lock);
+	if (unlikely(!port->func)) {
+		mutex_unlock(&port->func_lock);
+		return -ENODEV;
+	}
+	if (likely(port->in_sdio_uart_irq != current))
+		sdio_claim_host(port->func);
+	mutex_unlock(&port->func_lock);
+	return 0;
+}
+
+static inline void sdio_uart_release_func(struct sdio_uart_port *port)
+{
+	if (likely(port->in_sdio_uart_irq != current))
+		sdio_release_host(port->func);
+}
+
+static inline unsigned int sdio_in(struct sdio_uart_port *port, int offset)
+{
+	unsigned char c;
+	c = sdio_readb(port->func, port->regs_offset + offset, NULL);
+	return c;
+}
+
+static inline void sdio_out(struct sdio_uart_port *port, int offset, int value)
+{
+	sdio_writeb(port->func, value, port->regs_offset + offset, NULL);
+}
+
+static unsigned int sdio_uart_get_mctrl(struct sdio_uart_port *port)
+{
+	unsigned char status;
+	unsigned int ret;
+
+	status = sdio_in(port, UART_MSR);
+
+	ret = 0;
+	if (status & UART_MSR_DCD)
+		ret |= TIOCM_CAR;
+	if (status & UART_MSR_RI)
+		ret |= TIOCM_RNG;
+	if (status & UART_MSR_DSR)
+		ret |= TIOCM_DSR;
+	if (status & UART_MSR_CTS)
+		ret |= TIOCM_CTS;
+	return ret;
+}
+
+static void sdio_uart_write_mctrl(struct sdio_uart_port *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;
+
+	sdio_out(port, UART_MCR, mcr);
+}
+
+static inline void sdio_uart_update_mctrl(struct sdio_uart_port *port,
+					  unsigned int set, unsigned int clear)
+{
+	unsigned int old;
+
+	old = port->mctrl;
+	port->mctrl = (old & ~clear) | set;
+	if (old != port->mctrl)
+		sdio_uart_write_mctrl(port, port->mctrl);
+}
+
+#define sdio_uart_set_mctrl(port, x)	sdio_uart_update_mctrl(port, x, 0)
+#define sdio_uart_clear_mctrl(port, x)	sdio_uart_update_mctrl(port, 0, x)
+
+static void sdio_uart_change_speed(struct sdio_uart_port *port,
+				   struct ktermios *termios,
+				   struct ktermios *old)
+{
+	unsigned char cval, fcr = 0;
+	unsigned int baud, quot;
+
+	switch (termios->c_cflag & CSIZE) {
+	case CS5:
+		cval = UART_LCR_WLEN5;
+		break;
+	case CS6:
+		cval = UART_LCR_WLEN6;
+		break;
+	case CS7:
+		cval = UART_LCR_WLEN7;
+		break;
+	default:
+	case CS8:
+		cval = UART_LCR_WLEN8;
+		break;
+	}
+
+	if (termios->c_cflag & CSTOPB)
+		cval |= UART_LCR_STOP;
+	if (termios->c_cflag & PARENB)
+		cval |= UART_LCR_PARITY;
+	if (!(termios->c_cflag & PARODD))
+		cval |= UART_LCR_EPAR;
+
+	for (;;) {
+		baud = tty_termios_baud_rate(termios);
+		if (baud == 0)
+			baud = 9600;  /* Special case: B0 rate. */
+		if (baud <= port->uartclk)
+			break;
+		/*
+		 * Oops, the quotient was zero.  Try again with the old
+		 * baud rate if possible, otherwise default to 9600.
+		 */
+		termios->c_cflag &= ~CBAUD;
+		if (old) {
+			termios->c_cflag |= old->c_cflag & CBAUD;
+			old = NULL;
+		} else
+			termios->c_cflag |= B9600;
+	}
+	quot = (2 * port->uartclk + baud) / (2 * baud);
+
+	if (baud < 2400)
+		fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
+	else
+		fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10;
+
+	port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
+	if (termios->c_iflag & INPCK)
+		port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
+	if (termios->c_iflag & (BRKINT | PARMRK))
+		port->read_status_mask |= UART_LSR_BI;
+
+	/*
+	 * Characters to ignore
+	 */
+	port->ignore_status_mask = 0;
+	if (termios->c_iflag & IGNPAR)
+		port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
+	if (termios->c_iflag & IGNBRK) {
+		port->ignore_status_mask |= UART_LSR_BI;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (termios->c_iflag & IGNPAR)
+			port->ignore_status_mask |= UART_LSR_OE;
+	}
+
+	/*
+	 * ignore all characters if CREAD is not set
+	 */
+	if ((termios->c_cflag & CREAD) == 0)
+		port->ignore_status_mask |= UART_LSR_DR;
+
+	/*
+	 * CTS flow control flag and modem status interrupts
+	 */
+	port->ier &= ~UART_IER_MSI;
+	if ((termios->c_cflag & CRTSCTS) || !(termios->c_cflag & CLOCAL))
+		port->ier |= UART_IER_MSI;
+
+	port->lcr = cval;
+
+	sdio_out(port, UART_IER, port->ier);
+	sdio_out(port, UART_LCR, cval | UART_LCR_DLAB);
+	sdio_out(port, UART_DLL, quot & 0xff);
+	sdio_out(port, UART_DLM, quot >> 8);
+	sdio_out(port, UART_LCR, cval);
+	sdio_out(port, UART_FCR, fcr);
+
+	sdio_uart_write_mctrl(port, port->mctrl);
+}
+
+static void sdio_uart_start_tx(struct sdio_uart_port *port)
+{
+	if (!(port->ier & UART_IER_THRI)) {
+		port->ier |= UART_IER_THRI;
+		sdio_out(port, UART_IER, port->ier);
+	}
+}
+
+static void sdio_uart_stop_tx(struct sdio_uart_port *port)
+{
+	if (port->ier & UART_IER_THRI) {
+		port->ier &= ~UART_IER_THRI;
+		sdio_out(port, UART_IER, port->ier);
+	}
+}
+
+static void sdio_uart_stop_rx(struct sdio_uart_port *port)
+{
+	port->ier &= ~UART_IER_RLSI;
+	port->read_status_mask &= ~UART_LSR_DR;
+	sdio_out(port, UART_IER, port->ier);
+}
+
+static void sdio_uart_receive_chars(struct sdio_uart_port *port, int *status)
+{
+	struct tty_struct *tty = port->tty;
+	unsigned int ch, flag;
+	int max_count = 256;
+
+	do {
+		ch = sdio_in(port, UART_RX);
+		flag = TTY_NORMAL;
+		port->icount.rx++;
+
+		if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE |
+				        UART_LSR_FE | UART_LSR_OE))) {
+			/*
+			 * For statistics only
+			 */
+			if (*status & UART_LSR_BI) {
+				*status &= ~(UART_LSR_FE | UART_LSR_PE);
+				port->icount.brk++;
+			} else if (*status & UART_LSR_PE)
+				port->icount.parity++;
+			else if (*status & UART_LSR_FE)
+				port->icount.frame++;
+			if (*status & UART_LSR_OE)
+				port->icount.overrun++;
+
+			/*
+			 * Mask off conditions which should be ignored.
+			 */
+			*status &= port->read_status_mask;
+			if (*status & UART_LSR_BI) {
+				flag = TTY_BREAK;
+			} else if (*status & UART_LSR_PE)
+				flag = TTY_PARITY;
+			else if (*status & UART_LSR_FE)
+				flag = TTY_FRAME;
+		}
+
+		if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0)
+			tty_insert_flip_char(tty, ch, flag);
+
+		/*
+		 * Overrun is special.  Since it's reported immediately,
+		 * it doesn't affect the current character.
+		 */
+		if (*status & ~port->ignore_status_mask & UART_LSR_OE)
+			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+
+		*status = sdio_in(port, UART_LSR);
+	} while ((*status & UART_LSR_DR) && (max_count-- > 0));
+	tty_flip_buffer_push(tty);
+}
+
+static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
+{
+	struct circ_buf *xmit = &port->xmit;
+	int count;
+
+	if (port->x_char) {
+		sdio_out(port, UART_TX, port->x_char);
+		port->icount.tx++;
+		port->x_char = 0;
+		return;
+	}
+	if (circ_empty(xmit) || port->tty->stopped || port->tty->hw_stopped) {
+		sdio_uart_stop_tx(port);
+		return;
+	}
+
+	count = 16;
+	do {
+		sdio_out(port, UART_TX, xmit->buf[xmit->tail]);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		port->icount.tx++;
+		if (circ_empty(xmit))
+			break;
+	} while (--count > 0);
+
+	if (circ_chars_pending(xmit) < WAKEUP_CHARS)
+		tty_wakeup(port->tty);
+
+	if (circ_empty(xmit))
+		sdio_uart_stop_tx(port);
+}
+
+static void sdio_uart_check_modem_status(struct sdio_uart_port *port)
+{
+	int status;
+
+	status = sdio_in(port, UART_MSR);
+
+	if ((status & UART_MSR_ANY_DELTA) == 0)
+		return;
+
+	if (status & UART_MSR_TERI)
+		port->icount.rng++;
+	if (status & UART_MSR_DDSR)
+		port->icount.dsr++;
+	if (status & UART_MSR_DDCD)
+		port->icount.dcd++;
+	if (status & UART_MSR_DCTS) {
+		port->icount.cts++;
+		if (port->tty->termios->c_cflag & CRTSCTS) {
+			int cts = (status & UART_MSR_CTS);
+			if (port->tty->hw_stopped) {
+				if (cts) {
+					port->tty->hw_stopped = 0;
+					sdio_uart_start_tx(port);
+					tty_wakeup(port->tty);
+				}
+			} else {
+				if (!cts) {
+					port->tty->hw_stopped = 1;
+					sdio_uart_stop_tx(port);
+				}
+			}
+		}
+	}
+}
+
+/*
+ * This handles the interrupt from one port.
+ */
+static void sdio_uart_irq(struct sdio_func *func)
+{
+	struct sdio_uart_port *port = sdio_get_drvdata(func);
+	unsigned int iir, lsr;
+
+	/*
+	 * In a few places sdio_uart_irq() is called directly instead of
+	 * waiting for the actual interrupt to be raised and the SDIO IRQ
+	 * thread scheduled in order to reduce latency.  However, some
+	 * interaction with the tty core may end up calling us back
+	 * (serial echo, flow control, etc.) through those same places
+	 * causing undesirable effects.  Let's stop the recursion here.
+	 */
+	if (unlikely(port->in_sdio_uart_irq == current))
+		return;
+
+	iir = sdio_in(port, UART_IIR);
+	if (iir & UART_IIR_NO_INT)
+		return;
+
+	port->in_sdio_uart_irq = current;
+	lsr = sdio_in(port, UART_LSR);
+	if (lsr & UART_LSR_DR)
+		sdio_uart_receive_chars(port, &lsr);
+	sdio_uart_check_modem_status(port);
+	if (lsr & UART_LSR_THRE)
+		sdio_uart_transmit_chars(port);
+	port->in_sdio_uart_irq = NULL;
+}
+
+static int sdio_uart_startup(struct sdio_uart_port *port)
+{
+	unsigned long page;
+	int ret;
+
+	/*
+	 * Set the TTY IO error marker - we will only clear this
+	 * once we have successfully opened the port.
+	 */
+	set_bit(TTY_IO_ERROR, &port->tty->flags);
+
+	/* Initialise and allocate the transmit buffer. */
+	page = __get_free_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+	port->xmit.buf = (unsigned char *)page;
+	circ_clear(&port->xmit);
+
+	ret = sdio_uart_claim_func(port);
+	if (ret)
+		goto err1;
+	ret = sdio_enable_func(port->func);
+	if (ret)
+		goto err2;
+	ret = sdio_claim_irq(port->func, sdio_uart_irq);
+	if (ret)
+		goto err3;
+
+	/*
+	 * Clear the FIFO buffers and disable them.
+	 * (they will be reenabled in sdio_change_speed())
+	 */
+	sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO);
+	sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO |
+			UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+	sdio_out(port, UART_FCR, 0);
+
+	/*
+	 * Clear the interrupt registers.
+	 */
+	(void) sdio_in(port, UART_LSR);
+	(void) sdio_in(port, UART_RX);
+	(void) sdio_in(port, UART_IIR);
+	(void) sdio_in(port, UART_MSR);
+
+	/*
+	 * Now, initialize the UART
+	 */
+	sdio_out(port, UART_LCR, UART_LCR_WLEN8);
+
+	port->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_RTOIE | UART_IER_UUE;
+	port->mctrl = TIOCM_OUT2;
+
+	sdio_uart_change_speed(port, port->tty->termios, NULL);
+
+	if (port->tty->termios->c_cflag & CBAUD)
+		sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
+
+	if (port->tty->termios->c_cflag & CRTSCTS)
+		if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS))
+			port->tty->hw_stopped = 1;
+
+	clear_bit(TTY_IO_ERROR, &port->tty->flags);
+
+	/* Kick the IRQ handler once while we're still holding the host lock */
+	sdio_uart_irq(port->func);
+
+	sdio_uart_release_func(port);
+	return 0;
+
+err3:
+	sdio_disable_func(port->func);
+err2:
+	sdio_uart_release_func(port);
+err1:
+	free_page((unsigned long)port->xmit.buf);
+	return ret;
+}
+
+static void sdio_uart_shutdown(struct sdio_uart_port *port)
+{
+	int ret;
+
+	ret = sdio_uart_claim_func(port);
+	if (ret)
+		goto skip;
+
+	sdio_uart_stop_rx(port);
+
+	/* TODO: wait here for TX FIFO to drain */
+
+	/* Turn off DTR and RTS early. */
+	if (port->tty->termios->c_cflag & HUPCL)
+		sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+
+	 /* Disable interrupts from this port */
+	sdio_release_irq(port->func);
+	port->ier = 0;
+	sdio_out(port, UART_IER, 0);
+
+	sdio_uart_clear_mctrl(port, TIOCM_OUT2);
+
+	/* Disable break condition and FIFOs. */
+	port->lcr &= ~UART_LCR_SBC;
+	sdio_out(port, UART_LCR, port->lcr);
+	sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO |
+				 UART_FCR_CLEAR_RCVR |
+				 UART_FCR_CLEAR_XMIT);
+	sdio_out(port, UART_FCR, 0);
+
+	sdio_disable_func(port->func);
+
+	sdio_uart_release_func(port);
+
+skip:
+	/* Free the transmit buffer page. */
+	free_page((unsigned long)port->xmit.buf);
+}
+
+static int sdio_uart_open (struct tty_struct *tty, struct file * filp)
+{
+	struct sdio_uart_port *port;
+	int ret;
+
+	port = sdio_uart_port_get(tty->index);
+	if (!port)
+		return -ENODEV;
+
+	mutex_lock(&port->open_lock);
+
+	/*
+	 * Make sure not to mess up with a dead port
+	 * which has not been closed yet.
+	 */
+	if (tty->driver_data && tty->driver_data != port) {
+		mutex_unlock(&port->open_lock);
+		sdio_uart_port_put(port);
+		return -EBUSY;
+	}
+
+	if (!port->opened) {
+		tty->driver_data = port;
+		port->tty = tty;
+		ret = sdio_uart_startup(port);
+		if (ret) {
+			tty->driver_data = NULL;
+			port->tty = NULL;
+			mutex_unlock(&port->open_lock);
+			sdio_uart_port_put(port);
+			return ret;
+		}
+	}
+	port->opened++;
+	mutex_unlock(&port->open_lock);
+	return 0;
+}
+
+static void sdio_uart_close(struct tty_struct *tty, struct file * filp)
+{
+	struct sdio_uart_port *port = tty->driver_data;
+
+	if (!port)
+		return;
+
+	mutex_lock(&port->open_lock);
+	BUG_ON(!port->opened);
+
+	/*
+	 * This is messy.  The tty layer calls us even when open()
+	 * returned an error.  Ignore this close request if tty->count
+	 * is larger than port->count.
+	 */
+	if (tty->count > port->opened) {
+		mutex_unlock(&port->open_lock);
+		return;
+	}
+
+	if (--port->opened == 0) {
+		tty->closing = 1;
+		sdio_uart_shutdown(port);
+		tty_ldisc_flush(tty);
+		port->tty = NULL;
+		tty->driver_data = NULL;
+		tty->closing = 0;
+	}
+	mutex_unlock(&port->open_lock);
+	sdio_uart_port_put(port);
+}
+
+static int sdio_uart_write(struct tty_struct * tty, const unsigned char *buf,
+			   int count)
+{
+	struct sdio_uart_port *port = tty->driver_data;
+	struct circ_buf *circ = &port->xmit;
+	int c, ret = 0;
+
+	if (!port->func)
+		return -ENODEV;
+
+	spin_lock(&port->write_lock);
+	while (1) {
+		c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
+		if (count < c)
+			c = count;
+		if (c <= 0)
+			break;
+		memcpy(circ->buf + circ->head, buf, c);
+		circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
+		buf += c;
+		count -= c;
+		ret += c;
+	}
+	spin_unlock(&port->write_lock);
+
+	if ( !(port->ier & UART_IER_THRI)) {
+		int err = sdio_uart_claim_func(port);
+		if (!err) {
+			sdio_uart_start_tx(port);
+			sdio_uart_irq(port->func);
+			sdio_uart_release_func(port);
+		} else
+			ret = err;
+	}
+
+	return ret;
+}
+
+static int sdio_uart_write_room(struct tty_struct *tty)
+{
+	struct sdio_uart_port *port = tty->driver_data;
+	return port ? circ_chars_free(&port->xmit) : 0;
+}
+
+static int sdio_uart_chars_in_buffer(struct tty_struct *tty)
+{
+	struct sdio_uart_port *port = tty->driver_data;
+	return port ? circ_chars_pending(&port->xmit) : 0;
+}
+
+static void sdio_uart_send_xchar(struct tty_struct *tty, char ch)
+{
+	struct sdio_uart_port *port = tty->driver_data;
+
+	port->x_char = ch;
+	if (ch && !(port->ier & UART_IER_THRI)) {
+		if (sdio_uart_claim_func(port) != 0)
+			return;
+		sdio_uart_start_tx(port);
+		sdio_uart_irq(port->func);
+		sdio_uart_release_func(port);
+	}
+}
+
+static void sdio_uart_throttle(struct tty_struct *tty)
+{
+	struct sdio_uart_port *port = tty->driver_data;
+
+	if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS))
+		return;
+
+	if (sdio_uart_claim_func(port) != 0)
+		return;
+
+	if (I_IXOFF(tty)) {
+		port->x_char = STOP_CHAR(tty);
+		sdio_uart_start_tx(port);
+	}
+
+	if (tty->termios->c_cflag & CRTSCTS)
+		sdio_uart_clear_mctrl(port, TIOCM_RTS);
+
+	sdio_uart_irq(port->func);
+	sdio_uart_release_func(port);
+}
+
+static void sdio_uart_unthrottle(struct tty_struct *tty)
+{
+	struct sdio_uart_port *port = tty->driver_data;
+
+	if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS))
+		return;
+
+	if (sdio_uart_claim_func(port) != 0)
+		return;
+
+	if (I_IXOFF(tty)) {
+		if (port->x_char) {
+			port->x_char = 0;
+		} else {
+			port->x_char = START_CHAR(tty);
+			sdio_uart_start_tx(port);
+		}
+	}
+
+	if (tty->termios->c_cflag & CRTSCTS)
+		sdio_uart_set_mctrl(port, TIOCM_RTS);
+
+	sdio_uart_irq(port->func);
+	sdio_uart_release_func(port);
+}
+
+static void sdio_uart_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
+{
+	struct sdio_uart_port *port = tty->driver_data;
+	unsigned int cflag = tty->termios->c_cflag;
+
+#define RELEVANT_IFLAG(iflag)   ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+	if ((cflag ^ old_termios->c_cflag) == 0 &&
+	    RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0)
+		return;
+
+	if (sdio_uart_claim_func(port) != 0)
+		return;
+
+	sdio_uart_change_speed(port, tty->termios, old_termios);
+
+	/* Handle transition to B0 status */
+	if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))
+		sdio_uart_clear_mctrl(port, TIOCM_RTS | TIOCM_DTR);
+
+	/* Handle transition away from B0 status */
+	if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
+		unsigned int mask = TIOCM_DTR;
+		if (!(cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags))
+			mask |= TIOCM_RTS;
+		sdio_uart_set_mctrl(port, mask);
+	}
+
+	/* Handle turning off CRTSCTS */
+	if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		sdio_uart_start_tx(port);
+	}
+
+	/* Handle turning on CRTSCTS */
+	if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
+		if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) {
+			tty->hw_stopped = 1;
+			sdio_uart_stop_tx(port);
+		}
+	}
+
+	sdio_uart_release_func(port);
+}
+
+static void sdio_uart_break_ctl(struct tty_struct *tty, int break_state)
+{
+	struct sdio_uart_port *port = tty->driver_data;
+
+	if (sdio_uart_claim_func(port) != 0)
+		return;
+
+	if (break_state == -1)
+		port->lcr |= UART_LCR_SBC;
+	else
+		port->lcr &= ~UART_LCR_SBC;
+	sdio_out(port, UART_LCR, port->lcr);
+
+	sdio_uart_release_func(port);
+}
+
+static int sdio_uart_tiocmget(struct tty_struct *tty, struct file *file)
+{
+	struct sdio_uart_port *port = tty->driver_data;
+	int result;
+
+	result = sdio_uart_claim_func(port);
+	if (!result) {
+		result = port->mctrl | sdio_uart_get_mctrl(port);
+		sdio_uart_release_func(port);
+	}
+
+	return result;
+}
+
+static int sdio_uart_tiocmset(struct tty_struct *tty, struct file *file,
+			      unsigned int set, unsigned int clear)
+{
+	struct sdio_uart_port *port = tty->driver_data;
+	int result;
+
+	result =sdio_uart_claim_func(port);
+	if(!result) {
+		sdio_uart_update_mctrl(port, set, clear);
+		sdio_uart_release_func(port);
+	}
+
+	return result;
+}
+
+static int sdio_uart_read_proc(char *page, char **start, off_t off,
+			       int count, int *eof, void *data)
+{
+	int i, len = 0;
+	off_t begin = 0;
+
+	len += sprintf(page, "serinfo:1.0 driver%s%s revision:%s\n",
+		       "", "", "");
+	for (i = 0; i < UART_NR && len < PAGE_SIZE - 96; i++) {
+		struct sdio_uart_port *port = sdio_uart_port_get(i);
+		if (port) {
+			len += sprintf(page+len, "%d: uart:SDIO", i);
+			if(capable(CAP_SYS_ADMIN)) {
+				len += sprintf(page + len, " tx:%d rx:%d",
+					       port->icount.tx, port->icount.rx);
+				if (port->icount.frame)
+					len += sprintf(page + len, " fe:%d",
+						       port->icount.frame);
+				if (port->icount.parity)
+					len += sprintf(page + len, " pe:%d",
+						       port->icount.parity);
+				if (port->icount.brk)
+					len += sprintf(page + len, " brk:%d",
+						       port->icount.brk);
+				if (port->icount.overrun)
+					len += sprintf(page + len, " oe:%d",
+						       port->icount.overrun);
+				if (port->icount.cts)
+					len += sprintf(page + len, " cts:%d",
+						       port->icount.cts);
+				if (port->icount.dsr)
+					len += sprintf(page + len, " dsr:%d",
+						       port->icount.dsr);
+				if (port->icount.rng)
+					len += sprintf(page + len, " rng:%d",
+						       port->icount.rng);
+				if (port->icount.dcd)
+					len += sprintf(page + len, " dcd:%d",
+						       port->icount.dcd);
+			}
+			strcat(page, "\n");
+			len++;
+			sdio_uart_port_put(port);
+		}
+
+		if (len + begin > off + count)
+			goto done;
+		if (len + begin < off) {
+			begin += len;
+			len = 0;
+		}
+	}
+	*eof = 1;
+
+done:
+	if (off >= len + begin)
+		return 0;
+	*start = page + (off - begin);
+	return (count < begin + len - off) ? count : (begin + len - off);
+}
+
+static const struct tty_operations sdio_uart_ops = {
+	.open			= sdio_uart_open,
+	.close			= sdio_uart_close,
+	.write			= sdio_uart_write,
+	.write_room		= sdio_uart_write_room,
+	.chars_in_buffer	= sdio_uart_chars_in_buffer,
+	.send_xchar		= sdio_uart_send_xchar,
+	.throttle		= sdio_uart_throttle,
+	.unthrottle		= sdio_uart_unthrottle,
+	.set_termios		= sdio_uart_set_termios,
+	.break_ctl		= sdio_uart_break_ctl,
+	.tiocmget		= sdio_uart_tiocmget,
+	.tiocmset		= sdio_uart_tiocmset,
+	.read_proc		= sdio_uart_read_proc,
+};
+
+static struct tty_driver *sdio_uart_tty_driver;
+
+static int sdio_uart_probe(struct sdio_func *func,
+			   const struct sdio_device_id *id)
+{
+	struct sdio_uart_port *port;
+	int ret;
+
+	port = kzalloc(sizeof(struct sdio_uart_port), GFP_KERNEL);
+	if (!port)
+		return -ENOMEM;
+
+	if (func->class == SDIO_CLASS_UART) {
+		printk(KERN_WARNING "%s: need info on UART class basic setup\n",
+		       sdio_func_id(func));
+		kfree(port);
+		return -ENOSYS;
+	} else if (func->class == SDIO_CLASS_GPS) {
+		/*
+		 * We need tuple 0x91.  It contains SUBTPL_SIOREG
+		 * and SUBTPL_RCVCAPS.
+		 */
+		struct sdio_func_tuple *tpl;
+		for (tpl = func->tuples; tpl; tpl = tpl->next) {
+			if (tpl->code != 0x91)
+				continue;
+			if (tpl->size < 10)
+				continue;
+			if (tpl->data[1] == 0)  /* SUBTPL_SIOREG */
+				break;
+		}
+		if (!tpl) {
+			printk(KERN_WARNING
+			       "%s: can't find tuple 0x91 subtuple 0 (SUBTPL_SIOREG) for GPS class\n",
+			       sdio_func_id(func));
+			kfree(port);
+			return -EINVAL;
+		}
+		printk(KERN_DEBUG "%s: Register ID = 0x%02x, Exp ID = 0x%02x\n",
+		       sdio_func_id(func), tpl->data[2], tpl->data[3]);
+		port->regs_offset = (tpl->data[4] << 0) |
+				    (tpl->data[5] << 8) |
+				    (tpl->data[6] << 16);
+		printk(KERN_DEBUG "%s: regs offset = 0x%x\n",
+		       sdio_func_id(func), port->regs_offset);
+		port->uartclk = tpl->data[7] * 115200;
+		if (port->uartclk == 0)
+			port->uartclk = 115200;
+		printk(KERN_DEBUG "%s: clk %d baudcode %u 4800-div %u\n",
+		       sdio_func_id(func), port->uartclk,
+		       tpl->data[7], tpl->data[8] | (tpl->data[9] << 8));
+	} else {
+		kfree(port);
+		return -EINVAL;
+	}
+
+	port->func = func;
+	sdio_set_drvdata(func, port);
+
+	ret = sdio_uart_add_port(port);
+	if (ret) {
+		kfree(port);
+	} else {
+		struct device *dev;
+		dev = tty_register_device(sdio_uart_tty_driver, port->index, &func->dev);
+		if (IS_ERR(dev)) {
+			sdio_uart_port_remove(port);
+			ret = PTR_ERR(dev);
+		}
+	}
+
+	return ret;
+}
+
+static void sdio_uart_remove(struct sdio_func *func)
+{
+	struct sdio_uart_port *port = sdio_get_drvdata(func);
+
+	tty_unregister_device(sdio_uart_tty_driver, port->index);
+	sdio_uart_port_remove(port);
+}
+
+static const struct sdio_device_id sdio_uart_ids[] = {
+	{ SDIO_DEVICE_CLASS(SDIO_CLASS_UART)		},
+	{ SDIO_DEVICE_CLASS(SDIO_CLASS_GPS)		},
+	{ /* end: all zeroes */				},
+};
+
+MODULE_DEVICE_TABLE(sdio, sdio_uart_ids);
+
+static struct sdio_driver sdio_uart_driver = {
+	.probe		= sdio_uart_probe,
+	.remove		= sdio_uart_remove,
+	.name		= "sdio_uart",
+	.id_table	= sdio_uart_ids,
+};
+
+static int __init sdio_uart_init(void)
+{
+	int ret;
+	struct tty_driver *tty_drv;
+
+	sdio_uart_tty_driver = tty_drv = alloc_tty_driver(UART_NR);
+	if (!tty_drv)
+		return -ENOMEM;
+
+	tty_drv->owner = THIS_MODULE;
+	tty_drv->driver_name = "sdio_uart";
+	tty_drv->name =   "ttySDIO";
+	tty_drv->major = 0;  /* dynamically allocated */
+	tty_drv->minor_start = 0;
+	tty_drv->type = TTY_DRIVER_TYPE_SERIAL;
+	tty_drv->subtype = SERIAL_TYPE_NORMAL;
+	tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+	tty_drv->init_termios = tty_std_termios;
+	tty_drv->init_termios.c_cflag = B4800 | CS8 | CREAD | HUPCL | CLOCAL;
+	tty_drv->init_termios.c_ispeed = 4800;
+	tty_drv->init_termios.c_ospeed = 4800;
+	tty_set_operations(tty_drv, &sdio_uart_ops);
+
+	ret = tty_register_driver(tty_drv);
+	if (ret)
+		goto err1;
+
+	ret = sdio_register_driver(&sdio_uart_driver);
+	if (ret)
+		goto err2;
+
+	return 0;
+
+err2:
+	tty_unregister_driver(tty_drv);
+err1:
+	put_tty_driver(tty_drv);
+	return ret;
+}
+
+static void __exit sdio_uart_exit(void)
+{
+	sdio_unregister_driver(&sdio_uart_driver);
+	tty_unregister_driver(sdio_uart_tty_driver);
+	put_tty_driver(sdio_uart_tty_driver);
+}
+
+module_init(sdio_uart_init);
+module_exit(sdio_uart_exit);
+
+MODULE_AUTHOR("Nicolas Pitre");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
index 3fdd08c..4985807 100644
--- a/drivers/mmc/core/Makefile
+++ b/drivers/mmc/core/Makefile
@@ -8,5 +8,7 @@
 
 obj-$(CONFIG_MMC)		+= mmc_core.o
 mmc_core-y			:= core.o sysfs.o bus.o host.o \
-				   mmc.o mmc_ops.o sd.o sd_ops.o
+				   mmc.o mmc_ops.o sd.o sd_ops.o \
+				   sdio.o sdio_ops.o sdio_bus.o \
+				   sdio_cis.o sdio_io.o sdio_irq.o
 
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 817a794..8d6f601 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -19,6 +19,7 @@
 
 #include "sysfs.h"
 #include "core.h"
+#include "sdio_cis.h"
 #include "bus.h"
 
 #define dev_to_mmc_card(d)	container_of(d, struct mmc_card, dev)
@@ -34,6 +35,8 @@
 		return sprintf(buf, "MMC\n");
 	case MMC_TYPE_SD:
 		return sprintf(buf, "SD\n");
+	case MMC_TYPE_SDIO:
+		return sprintf(buf, "SDIO\n");
 	default:
 		return -EFAULT;
 	}
@@ -59,28 +62,34 @@
 		int buf_size)
 {
 	struct mmc_card *card = dev_to_mmc_card(dev);
-	int retval = 0, i = 0, length = 0;
-
-#define add_env(fmt,val) do {					\
-	retval = add_uevent_var(envp, num_envp, &i,		\
-				buf, buf_size, &length,		\
-				fmt, val);			\
-	if (retval)						\
-		return retval;					\
-} while (0);
+	const char *type;
+	int i = 0, length = 0;
 
 	switch (card->type) {
 	case MMC_TYPE_MMC:
-		add_env("MMC_TYPE=%s", "MMC");
+		type = "MMC";
 		break;
 	case MMC_TYPE_SD:
-		add_env("MMC_TYPE=%s", "SD");
+		type = "SD";
 		break;
+	case MMC_TYPE_SDIO:
+		type = "SDIO";
+		break;
+	default:
+		type = NULL;
 	}
 
-	add_env("MMC_NAME=%s", mmc_card_name(card));
+	if (type) {
+		if (add_uevent_var(envp, num_envp, &i,
+				buf, buf_size, &length,
+				"MMC_TYPE=%s", type))
+			return -ENOMEM;
+	}
 
-#undef add_env
+	if (add_uevent_var(envp, num_envp, &i,
+			buf, buf_size, &length,
+			"MMC_NAME=%s", mmc_card_name(card)))
+		return -ENOMEM;
 
 	envp[i] = NULL;
 
@@ -176,6 +185,11 @@
 {
 	struct mmc_card *card = dev_to_mmc_card(dev);
 
+	sdio_free_common_cis(card);
+
+	if (card->info)
+		kfree(card->info);
+
 	kfree(card);
 }
 
@@ -221,15 +235,25 @@
 		if (mmc_card_blockaddr(card))
 			type = "SDHC";
 		break;
+	case MMC_TYPE_SDIO:
+		type = "SDIO";
+		break;
 	default:
 		type = "?";
 		break;
 	}
 
-	printk(KERN_INFO "%s: new %s%s card at address %04x\n",
-		mmc_hostname(card->host),
-		mmc_card_highspeed(card) ? "high speed " : "",
-		type, card->rca);
+	if (mmc_host_is_spi(card->host)) {
+		printk(KERN_INFO "%s: new %s%s card on SPI\n",
+			mmc_hostname(card->host),
+			mmc_card_highspeed(card) ? "high speed " : "",
+			type);
+	} else {
+		printk(KERN_INFO "%s: new %s%s card at address %04x\n",
+			mmc_hostname(card->host),
+			mmc_card_highspeed(card) ? "high speed " : "",
+			type, card->rca);
+	}
 
 	card->dev.uevent_suppress = 1;
 
@@ -261,8 +285,13 @@
 void mmc_remove_card(struct mmc_card *card)
 {
 	if (mmc_card_present(card)) {
-		printk(KERN_INFO "%s: card %04x removed\n",
-			mmc_hostname(card->host), card->rca);
+		if (mmc_host_is_spi(card->host)) {
+			printk(KERN_INFO "%s: SPI card removed\n",
+				mmc_hostname(card->host));
+		} else {
+			printk(KERN_INFO "%s: card %04x removed\n",
+				mmc_hostname(card->host), card->rca);
+		}
 
 		if (card->host->bus_ops->sysfs_remove)
 			card->host->bus_ops->sysfs_remove(card->host, card);
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index bfd2ae5..09435e0 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/pagemap.h>
 #include <linux/err.h>
+#include <linux/leds.h>
 #include <asm/scatterlist.h>
 #include <linux/scatterlist.h>
 
@@ -29,16 +30,27 @@
 #include "core.h"
 #include "bus.h"
 #include "host.h"
+#include "sdio_bus.h"
 
 #include "mmc_ops.h"
 #include "sd_ops.h"
+#include "sdio_ops.h"
 
 extern int mmc_attach_mmc(struct mmc_host *host, u32 ocr);
 extern int mmc_attach_sd(struct mmc_host *host, u32 ocr);
+extern int mmc_attach_sdio(struct mmc_host *host, u32 ocr);
 
 static struct workqueue_struct *workqueue;
 
 /*
+ * Enabling software CRCs on the data blocks can be a significant (30%)
+ * performance cost, and for other reasons may not always be desired.
+ * So we allow it it to be disabled.
+ */
+int use_spi_crc = 1;
+module_param(use_spi_crc, bool, 0);
+
+/*
  * Internal function. Schedule delayed work in the MMC work queue.
  */
 static int mmc_schedule_delayed_work(struct delayed_work *work,
@@ -68,6 +80,11 @@
 	struct mmc_command *cmd = mrq->cmd;
 	int err = cmd->error;
 
+	if (err && cmd->retries && mmc_host_is_spi(host)) {
+		if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND)
+			cmd->retries = 0;
+	}
+
 	if (err && cmd->retries) {
 		pr_debug("%s: req failed (CMD%u): %d, retrying...\n",
 			mmc_hostname(host), cmd->opcode, err);
@@ -76,6 +93,8 @@
 		cmd->error = 0;
 		host->ops->request(host, mrq);
 	} else {
+		led_trigger_event(host->led, LED_OFF);
+
 		pr_debug("%s: req done (CMD%u): %d: %08x %08x %08x %08x\n",
 			mmc_hostname(host), cmd->opcode, err,
 			cmd->resp[0], cmd->resp[1],
@@ -118,7 +137,7 @@
 			"tsac %d ms nsac %d\n",
 			mmc_hostname(host), mrq->data->blksz,
 			mrq->data->blocks, mrq->data->flags,
-			mrq->data->timeout_ns / 10000000,
+			mrq->data->timeout_ns / 1000000,
 			mrq->data->timeout_clks);
 	}
 
@@ -130,6 +149,8 @@
 
 	WARN_ON(!host->claimed);
 
+	led_trigger_event(host->led, LED_FULL);
+
 	mrq->cmd->error = 0;
 	mrq->cmd->mrq = mrq;
 	if (mrq->data) {
@@ -199,7 +220,7 @@
 {
 	struct mmc_request mrq;
 
-	BUG_ON(!host->claimed);
+	WARN_ON(!host->claimed);
 
 	memset(&mrq, 0, sizeof(struct mmc_request));
 
@@ -220,17 +241,24 @@
  *	mmc_set_data_timeout - set the timeout for a data command
  *	@data: data phase for command
  *	@card: the MMC card associated with the data transfer
- *	@write: flag to differentiate reads from writes
  *
  *	Computes the data timeout parameters according to the
  *	correct algorithm given the card type.
  */
-void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card,
-			  int write)
+void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
 {
 	unsigned int mult;
 
 	/*
+	 * SDIO cards only define an upper 1 s limit on access.
+	 */
+	if (mmc_card_sdio(card)) {
+		data->timeout_ns = 1000000000;
+		data->timeout_clks = 0;
+		return;
+	}
+
+	/*
 	 * SD cards use a 100 multiplier rather than 10
 	 */
 	mult = mmc_card_sd(card) ? 100 : 10;
@@ -239,7 +267,7 @@
 	 * Scale up the multiplier (and therefore the timeout) by
 	 * the r2w factor for writes.
 	 */
-	if (write)
+	if (data->flags & MMC_DATA_WRITE)
 		mult <<= card->csd.r2w_factor;
 
 	data->timeout_ns = card->csd.tacc_ns * mult;
@@ -255,7 +283,7 @@
 		timeout_us += data->timeout_clks * 1000 /
 			(card->host->ios.clock / 1000);
 
-		if (write)
+		if (data->flags & MMC_DATA_WRITE)
 			limit_us = 250000;
 		else
 			limit_us = 100000;
@@ -272,15 +300,20 @@
 EXPORT_SYMBOL(mmc_set_data_timeout);
 
 /**
- *	mmc_claim_host - exclusively claim a host
+ *	__mmc_claim_host - exclusively claim a host
  *	@host: mmc host to claim
+ *	@abort: whether or not the operation should be aborted
  *
- *	Claim a host for a set of operations.
+ *	Claim a host for a set of operations.  If @abort is non null and
+ *	dereference a non-zero value then this will return prematurely with
+ *	that non-zero value without acquiring the lock.  Returns zero
+ *	with the lock held otherwise.
  */
-void mmc_claim_host(struct mmc_host *host)
+int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)
 {
 	DECLARE_WAITQUEUE(wait, current);
 	unsigned long flags;
+	int stop;
 
 	might_sleep();
 
@@ -288,19 +321,24 @@
 	spin_lock_irqsave(&host->lock, flags);
 	while (1) {
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		if (!host->claimed)
+		stop = abort ? atomic_read(abort) : 0;
+		if (stop || !host->claimed)
 			break;
 		spin_unlock_irqrestore(&host->lock, flags);
 		schedule();
 		spin_lock_irqsave(&host->lock, flags);
 	}
 	set_current_state(TASK_RUNNING);
-	host->claimed = 1;
+	if (!stop)
+		host->claimed = 1;
+	else
+		wake_up(&host->wq);
 	spin_unlock_irqrestore(&host->lock, flags);
 	remove_wait_queue(&host->wq, &wait);
+	return stop;
 }
 
-EXPORT_SYMBOL(mmc_claim_host);
+EXPORT_SYMBOL(__mmc_claim_host);
 
 /**
  *	mmc_release_host - release a host
@@ -313,7 +351,7 @@
 {
 	unsigned long flags;
 
-	BUG_ON(!host->claimed);
+	WARN_ON(!host->claimed);
 
 	spin_lock_irqsave(&host->lock, flags);
 	host->claimed = 0;
@@ -433,19 +471,32 @@
 	int bit = fls(host->ocr_avail) - 1;
 
 	host->ios.vdd = bit;
-	host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
-	host->ios.chip_select = MMC_CS_DONTCARE;
+	if (mmc_host_is_spi(host)) {
+		host->ios.chip_select = MMC_CS_HIGH;
+		host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
+	} else {
+		host->ios.chip_select = MMC_CS_DONTCARE;
+		host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
+	}
 	host->ios.power_mode = MMC_POWER_UP;
 	host->ios.bus_width = MMC_BUS_WIDTH_1;
 	host->ios.timing = MMC_TIMING_LEGACY;
 	mmc_set_ios(host);
 
-	mmc_delay(1);
+	/*
+	 * This delay should be sufficient to allow the power supply
+	 * to reach the minimum voltage.
+	 */
+	mmc_delay(2);
 
 	host->ios.clock = host->f_min;
 	host->ios.power_mode = MMC_POWER_ON;
 	mmc_set_ios(host);
 
+	/*
+	 * This delay must be at least 74 clock sizes, or 1 ms, or the
+	 * time required to reach a stable voltage.
+	 */
 	mmc_delay(2);
 }
 
@@ -453,8 +504,10 @@
 {
 	host->ios.clock = 0;
 	host->ios.vdd = 0;
-	host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
-	host->ios.chip_select = MMC_CS_DONTCARE;
+	if (!mmc_host_is_spi(host)) {
+		host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
+		host->ios.chip_select = MMC_CS_DONTCARE;
+	}
 	host->ios.power_mode = MMC_POWER_OFF;
 	host->ios.bus_width = MMC_BUS_WIDTH_1;
 	host->ios.timing = MMC_TIMING_LEGACY;
@@ -511,7 +564,7 @@
 	BUG_ON(!host);
 	BUG_ON(!ops);
 
-	BUG_ON(!host->claimed);
+	WARN_ON(!host->claimed);
 
 	spin_lock_irqsave(&host->lock, flags);
 
@@ -535,8 +588,8 @@
 
 	BUG_ON(!host);
 
-	BUG_ON(!host->claimed);
-	BUG_ON(!host->bus_ops);
+	WARN_ON(!host->claimed);
+	WARN_ON(!host->bus_ops);
 
 	spin_lock_irqsave(&host->lock, flags);
 
@@ -564,7 +617,7 @@
 #ifdef CONFIG_MMC_DEBUG
 	unsigned long flags;
 	spin_lock_irqsave(&host->lock, flags);
-	BUG_ON(host->removed);
+	WARN_ON(host->removed);
 	spin_unlock_irqrestore(&host->lock, flags);
 #endif
 
@@ -597,24 +650,38 @@
 
 		mmc_send_if_cond(host, host->ocr_avail);
 
+		/*
+		 * First we search for SDIO...
+		 */
+		err = mmc_send_io_op_cond(host, 0, &ocr);
+		if (!err) {
+			if (mmc_attach_sdio(host, ocr))
+				mmc_power_off(host);
+			return;
+		}
+
+		/*
+		 * ...then normal SD...
+		 */
 		err = mmc_send_app_op_cond(host, 0, &ocr);
-		if (err == MMC_ERR_NONE) {
+		if (!err) {
 			if (mmc_attach_sd(host, ocr))
 				mmc_power_off(host);
-		} else {
-			/*
-			 * If we fail to detect any SD cards then try
-			 * searching for MMC cards.
-			 */
-			err = mmc_send_op_cond(host, 0, &ocr);
-			if (err == MMC_ERR_NONE) {
-				if (mmc_attach_mmc(host, ocr))
-					mmc_power_off(host);
-			} else {
-				mmc_power_off(host);
-				mmc_release_host(host);
-			}
+			return;
 		}
+
+		/*
+		 * ...and finally MMC.
+		 */
+		err = mmc_send_op_cond(host, 0, &ocr);
+		if (!err) {
+			if (mmc_attach_mmc(host, ocr))
+				mmc_power_off(host);
+			return;
+		}
+
+		mmc_release_host(host);
+		mmc_power_off(host);
 	} else {
 		if (host->bus_ops->detect && !host->bus_dead)
 			host->bus_ops->detect(host);
@@ -725,22 +792,38 @@
 		return -ENOMEM;
 
 	ret = mmc_register_bus();
-	if (ret == 0) {
-		ret = mmc_register_host_class();
-		if (ret)
-			mmc_unregister_bus();
-	}
+	if (ret)
+		goto destroy_workqueue;
+
+	ret = mmc_register_host_class();
+	if (ret)
+		goto unregister_bus;
+
+	ret = sdio_register_bus();
+	if (ret)
+		goto unregister_host_class;
+
+	return 0;
+
+unregister_host_class:
+	mmc_unregister_host_class();
+unregister_bus:
+	mmc_unregister_bus();
+destroy_workqueue:
+	destroy_workqueue(workqueue);
+
 	return ret;
 }
 
 static void __exit mmc_exit(void)
 {
+	sdio_unregister_bus();
 	mmc_unregister_host_class();
 	mmc_unregister_bus();
 	destroy_workqueue(workqueue);
 }
 
-module_init(mmc_init);
+subsys_initcall(mmc_init);
 module_exit(mmc_exit);
 
 MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index bb2774a..39daf2f 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -48,5 +48,7 @@
 void mmc_start_host(struct mmc_host *host);
 void mmc_stop_host(struct mmc_host *host);
 
+extern int use_spi_crc;
+
 #endif
 
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 2c7ce8f..64fbc97 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -15,6 +15,7 @@
 #include <linux/err.h>
 #include <linux/idr.h>
 #include <linux/pagemap.h>
+#include <linux/leds.h>
 
 #include <linux/mmc/host.h>
 
@@ -100,6 +101,9 @@
 {
 	int err;
 
+	WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&
+		!host->ops->enable_sdio_irq);
+
 	if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))
 		return -ENOMEM;
 
@@ -112,6 +116,8 @@
 	snprintf(host->class_dev.bus_id, BUS_ID_SIZE,
 		 "mmc%d", host->index);
 
+	led_trigger_register_simple(host->class_dev.bus_id, &host->led);
+
 	err = device_add(&host->class_dev);
 	if (err)
 		return err;
@@ -137,6 +143,8 @@
 
 	device_del(&host->class_dev);
 
+	led_trigger_unregister(host->led);
+
 	spin_lock(&mmc_host_lock);
 	idr_remove(&mmc_host_idr, host->index);
 	spin_unlock(&mmc_host_lock);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 21d7f48..65fe288 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -161,13 +161,12 @@
 {
 	int err;
 	u8 *ext_csd;
+	unsigned int ext_csd_struct;
 
 	BUG_ON(!card);
 
-	err = MMC_ERR_FAILED;
-
 	if (card->csd.mmca_vsn < CSD_SPEC_VER_4)
-		return MMC_ERR_NONE;
+		return 0;
 
 	/*
 	 * As the ext_csd is so large and mostly unused, we don't store the
@@ -176,13 +175,19 @@
 	ext_csd = kmalloc(512, GFP_KERNEL);
 	if (!ext_csd) {
 		printk(KERN_ERR "%s: could not allocate a buffer to "
-			"receive the ext_csd. mmc v4 cards will be "
-			"treated as v3.\n", mmc_hostname(card->host));
-		return MMC_ERR_FAILED;
+			"receive the ext_csd.\n", mmc_hostname(card->host));
+		return -ENOMEM;
 	}
 
 	err = mmc_send_ext_csd(card, ext_csd);
-	if (err != MMC_ERR_NONE) {
+	if (err) {
+		/*
+		 * We all hosts that cannot perform the command
+		 * to fail more gracefully
+		 */
+		if (err != -EINVAL)
+			goto out;
+
 		/*
 		 * High capacity cards should have this "magic" size
 		 * stored in their CSD.
@@ -197,18 +202,29 @@
 				"EXT_CSD, performance might "
 				"suffer.\n",
 				mmc_hostname(card->host));
-			err = MMC_ERR_NONE;
+			err = 0;
 		}
+
 		goto out;
 	}
 
-	card->ext_csd.sectors =
-		ext_csd[EXT_CSD_SEC_CNT + 0] << 0 |
-		ext_csd[EXT_CSD_SEC_CNT + 1] << 8 |
-		ext_csd[EXT_CSD_SEC_CNT + 2] << 16 |
-		ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
-	if (card->ext_csd.sectors)
-		mmc_card_set_blockaddr(card);
+	ext_csd_struct = ext_csd[EXT_CSD_REV];
+	if (ext_csd_struct > 2) {
+		printk(KERN_ERR "%s: unrecognised EXT_CSD structure "
+			"version %d\n", mmc_hostname(card->host),
+			ext_csd_struct);
+		return -EINVAL;
+	}
+
+	if (ext_csd_struct >= 2) {
+		card->ext_csd.sectors =
+			ext_csd[EXT_CSD_SEC_CNT + 0] << 0 |
+			ext_csd[EXT_CSD_SEC_CNT + 1] << 8 |
+			ext_csd[EXT_CSD_SEC_CNT + 2] << 16 |
+			ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
+		if (card->ext_csd.sectors)
+			mmc_card_set_blockaddr(card);
+	}
 
 	switch (ext_csd[EXT_CSD_CARD_TYPE]) {
 	case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
@@ -246,7 +262,7 @@
 	unsigned int max_dtr;
 
 	BUG_ON(!host);
-	BUG_ON(!host->claimed);
+	WARN_ON(!host->claimed);
 
 	/*
 	 * Since we're changing the OCR value, we seem to
@@ -258,19 +274,33 @@
 
 	/* The extra bit indicates that we support high capacity */
 	err = mmc_send_op_cond(host, ocr | (1 << 30), NULL);
-	if (err != MMC_ERR_NONE)
+	if (err)
 		goto err;
 
 	/*
+	 * For SPI, enable CRC as appropriate.
+	 */
+	if (mmc_host_is_spi(host)) {
+		err = mmc_spi_set_crc(host, use_spi_crc);
+		if (err)
+			goto err;
+	}
+
+	/*
 	 * Fetch CID from card.
 	 */
-	err = mmc_all_send_cid(host, cid);
-	if (err != MMC_ERR_NONE)
+	if (mmc_host_is_spi(host))
+		err = mmc_send_cid(host, cid);
+	else
+		err = mmc_all_send_cid(host, cid);
+	if (err)
 		goto err;
 
 	if (oldcard) {
-		if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0)
+		if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) {
+			err = -ENOENT;
 			goto err;
+		}
 
 		card = oldcard;
 	} else {
@@ -278,8 +308,10 @@
 		 * Allocate card structure.
 		 */
 		card = mmc_alloc_card(host);
-		if (IS_ERR(card))
+		if (IS_ERR(card)) {
+			err = PTR_ERR(card);
 			goto err;
+		}
 
 		card->type = MMC_TYPE_MMC;
 		card->rca = 1;
@@ -287,43 +319,47 @@
 	}
 
 	/*
-	 * Set card RCA.
+	 * For native busses:  set card RCA and quit open drain mode.
 	 */
-	err = mmc_set_relative_addr(card);
-	if (err != MMC_ERR_NONE)
-		goto free_card;
+	if (!mmc_host_is_spi(host)) {
+		err = mmc_set_relative_addr(card);
+		if (err)
+			goto free_card;
 
-	mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
+		mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
+	}
 
 	if (!oldcard) {
 		/*
 		 * Fetch CSD from card.
 		 */
 		err = mmc_send_csd(card, card->raw_csd);
-		if (err != MMC_ERR_NONE)
+		if (err)
 			goto free_card;
 
 		err = mmc_decode_csd(card);
-		if (err < 0)
+		if (err)
 			goto free_card;
 		err = mmc_decode_cid(card);
-		if (err < 0)
+		if (err)
 			goto free_card;
 	}
 
 	/*
 	 * Select card, as all following commands rely on that.
 	 */
-	err = mmc_select_card(card);
-	if (err != MMC_ERR_NONE)
-		goto free_card;
+	if (!mmc_host_is_spi(host)) {
+		err = mmc_select_card(card);
+		if (err)
+			goto free_card;
+	}
 
 	if (!oldcard) {
 		/*
-		 * Fetch and process extened CSD.
+		 * Fetch and process extended CSD.
 		 */
 		err = mmc_read_ext_csd(card);
-		if (err != MMC_ERR_NONE)
+		if (err)
 			goto free_card;
 	}
 
@@ -334,7 +370,7 @@
 		(host->caps & MMC_CAP_MMC_HIGHSPEED)) {
 		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 			EXT_CSD_HS_TIMING, 1);
-		if (err != MMC_ERR_NONE)
+		if (err)
 			goto free_card;
 
 		mmc_card_set_highspeed(card);
@@ -363,7 +399,7 @@
 		(host->caps & MMC_CAP_4_BIT_DATA)) {
 		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 			EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4);
-		if (err != MMC_ERR_NONE)
+		if (err)
 			goto free_card;
 
 		mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
@@ -372,14 +408,14 @@
 	if (!oldcard)
 		host->card = card;
 
-	return MMC_ERR_NONE;
+	return 0;
 
 free_card:
 	if (!oldcard)
 		mmc_remove_card(card);
 err:
 
-	return MMC_ERR_FAILED;
+	return err;
 }
 
 /*
@@ -413,7 +449,7 @@
 
 	mmc_release_host(host);
 
-	if (err != MMC_ERR_NONE) {
+	if (err) {
 		mmc_remove(host);
 
 		mmc_claim_host(host);
@@ -480,7 +516,8 @@
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
-	mmc_deselect_cards(host);
+	if (!mmc_host_is_spi(host))
+		mmc_deselect_cards(host);
 	host->card->state &= ~MMC_STATE_HIGHSPEED;
 	mmc_release_host(host);
 }
@@ -502,7 +539,7 @@
 	err = mmc_init_card(host, host->ocr, host->card);
 	mmc_release_host(host);
 
-	if (err != MMC_ERR_NONE) {
+	if (err) {
 		mmc_remove(host);
 
 		mmc_claim_host(host);
@@ -536,11 +573,20 @@
 	int err;
 
 	BUG_ON(!host);
-	BUG_ON(!host->claimed);
+	WARN_ON(!host->claimed);
 
 	mmc_attach_bus(host, &mmc_ops);
 
 	/*
+	 * We need to get OCR a different way for SPI.
+	 */
+	if (mmc_host_is_spi(host)) {
+		err = mmc_spi_read_ocr(host, 1, &ocr);
+		if (err)
+			goto err;
+	}
+
+	/*
 	 * Sanity check the voltages that the card claims to
 	 * support.
 	 */
@@ -565,7 +611,7 @@
 	 * Detect and init the card.
 	 */
 	err = mmc_init_card(host, host->ocr, NULL);
-	if (err != MMC_ERR_NONE)
+	if (err)
 		goto err;
 
 	mmc_release_host(host);
@@ -587,6 +633,6 @@
 	printk(KERN_ERR "%s: error %d whilst initialising MMC card\n",
 		mmc_hostname(host), err);
 
-	return 0;
+	return err;
 }
 
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 913e75f..bf4bc6a 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -40,10 +40,10 @@
 	}
 
 	err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
-	if (err != MMC_ERR_NONE)
+	if (err)
 		return err;
 
-	return MMC_ERR_NONE;
+	return 0;
 }
 
 int mmc_select_card(struct mmc_card *card)
@@ -63,23 +63,36 @@
 	int err;
 	struct mmc_command cmd;
 
-	mmc_set_chip_select(host, MMC_CS_HIGH);
-
-	mmc_delay(1);
+	/*
+	 * Non-SPI hosts need to prevent chipselect going active during
+	 * GO_IDLE; that would put chips into SPI mode.  Remind them of
+	 * that in case of hardware that won't pull up DAT3/nCS otherwise.
+	 *
+	 * SPI hosts ignore ios.chip_select; it's managed according to
+	 * rules that must accomodate non-MMC slaves which this layer
+	 * won't even know about.
+	 */
+	if (!mmc_host_is_spi(host)) {
+		mmc_set_chip_select(host, MMC_CS_HIGH);
+		mmc_delay(1);
+	}
 
 	memset(&cmd, 0, sizeof(struct mmc_command));
 
 	cmd.opcode = MMC_GO_IDLE_STATE;
 	cmd.arg = 0;
-	cmd.flags = MMC_RSP_NONE | MMC_CMD_BC;
+	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_NONE | MMC_CMD_BC;
 
 	err = mmc_wait_for_cmd(host, &cmd, 0);
 
 	mmc_delay(1);
 
-	mmc_set_chip_select(host, MMC_CS_DONTCARE);
+	if (!mmc_host_is_spi(host)) {
+		mmc_set_chip_select(host, MMC_CS_DONTCARE);
+		mmc_delay(1);
+	}
 
-	mmc_delay(1);
+	host->use_spi_crc = 0;
 
 	return err;
 }
@@ -94,23 +107,33 @@
 	memset(&cmd, 0, sizeof(struct mmc_command));
 
 	cmd.opcode = MMC_SEND_OP_COND;
-	cmd.arg = ocr;
-	cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
+	cmd.arg = mmc_host_is_spi(host) ? 0 : ocr;
+	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;
 
 	for (i = 100; i; i--) {
 		err = mmc_wait_for_cmd(host, &cmd, 0);
-		if (err != MMC_ERR_NONE)
+		if (err)
 			break;
 
-		if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0)
+		/* if we're just probing, do a single pass */
+		if (ocr == 0)
 			break;
 
-		err = MMC_ERR_TIMEOUT;
+		/* otherwise wait until reset completes */
+		if (mmc_host_is_spi(host)) {
+			if (!(cmd.resp[0] & R1_SPI_IDLE))
+				break;
+		} else {
+			if (cmd.resp[0] & MMC_CARD_BUSY)
+				break;
+		}
+
+		err = -ETIMEDOUT;
 
 		mmc_delay(10);
 	}
 
-	if (rocr)
+	if (rocr && !mmc_host_is_spi(host))
 		*rocr = cmd.resp[0];
 
 	return err;
@@ -131,12 +154,12 @@
 	cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
 
 	err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
-	if (err != MMC_ERR_NONE)
+	if (err)
 		return err;
 
 	memcpy(cid, cmd.resp, sizeof(u32) * 4);
 
-	return MMC_ERR_NONE;
+	return 0;
 }
 
 int mmc_set_relative_addr(struct mmc_card *card)
@@ -154,46 +177,52 @@
 	cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
 
 	err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
-	if (err != MMC_ERR_NONE)
+	if (err)
 		return err;
 
-	return MMC_ERR_NONE;
+	return 0;
 }
 
-int mmc_send_csd(struct mmc_card *card, u32 *csd)
+static int
+mmc_send_cxd_native(struct mmc_host *host, u32 arg, u32 *cxd, int opcode)
 {
 	int err;
 	struct mmc_command cmd;
 
-	BUG_ON(!card);
-	BUG_ON(!card->host);
-	BUG_ON(!csd);
+	BUG_ON(!host);
+	BUG_ON(!cxd);
 
 	memset(&cmd, 0, sizeof(struct mmc_command));
 
-	cmd.opcode = MMC_SEND_CSD;
-	cmd.arg = card->rca << 16;
+	cmd.opcode = opcode;
+	cmd.arg = arg;
 	cmd.flags = MMC_RSP_R2 | MMC_CMD_AC;
 
-	err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
-	if (err != MMC_ERR_NONE)
+	err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
+	if (err)
 		return err;
 
-	memcpy(csd, cmd.resp, sizeof(u32) * 4);
+	memcpy(cxd, cmd.resp, sizeof(u32) * 4);
 
-	return MMC_ERR_NONE;
+	return 0;
 }
 
-int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)
+static int
+mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
+		u32 opcode, void *buf, unsigned len)
 {
 	struct mmc_request mrq;
 	struct mmc_command cmd;
 	struct mmc_data data;
 	struct scatterlist sg;
+	void *data_buf;
 
-	BUG_ON(!card);
-	BUG_ON(!card->host);
-	BUG_ON(!ext_csd);
+	/* dma onto stack is unsafe/nonportable, but callers to this
+	 * routine normally provide temporary on-stack buffers ...
+	 */
+	data_buf = kmalloc(len, GFP_KERNEL);
+	if (data_buf == NULL)
+		return -ENOMEM;
 
 	memset(&mrq, 0, sizeof(struct mmc_request));
 	memset(&cmd, 0, sizeof(struct mmc_command));
@@ -202,28 +231,99 @@
 	mrq.cmd = &cmd;
 	mrq.data = &data;
 
-	cmd.opcode = MMC_SEND_EXT_CSD;
+	cmd.opcode = opcode;
 	cmd.arg = 0;
-	cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
 
-	data.blksz = 512;
+	/* NOTE HACK:  the MMC_RSP_SPI_R1 is always correct here, but we
+	 * rely on callers to never use this with "native" calls for reading
+	 * CSD or CID.  Native versions of those commands use the R2 type,
+	 * not R1 plus a data block.
+	 */
+	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
+
+	data.blksz = len;
 	data.blocks = 1;
 	data.flags = MMC_DATA_READ;
 	data.sg = &sg;
 	data.sg_len = 1;
 
-	sg_init_one(&sg, ext_csd, 512);
+	sg_init_one(&sg, data_buf, len);
 
-	mmc_set_data_timeout(&data, card, 0);
+	if (card)
+		mmc_set_data_timeout(&data, card);
 
-	mmc_wait_for_req(card->host, &mrq);
+	mmc_wait_for_req(host, &mrq);
 
-	if (cmd.error != MMC_ERR_NONE)
+	memcpy(buf, data_buf, len);
+	kfree(data_buf);
+
+	if (cmd.error)
 		return cmd.error;
-	if (data.error != MMC_ERR_NONE)
+	if (data.error)
 		return data.error;
 
-	return MMC_ERR_NONE;
+	return 0;
+}
+
+int mmc_send_csd(struct mmc_card *card, u32 *csd)
+{
+	if (!mmc_host_is_spi(card->host))
+		return mmc_send_cxd_native(card->host, card->rca << 16,
+				csd, MMC_SEND_CSD);
+
+	return mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16);
+}
+
+int mmc_send_cid(struct mmc_host *host, u32 *cid)
+{
+	if (!mmc_host_is_spi(host)) {
+		if (!host->card)
+			return -EINVAL;
+		return mmc_send_cxd_native(host, host->card->rca << 16,
+				cid, MMC_SEND_CID);
+	}
+
+	return mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16);
+}
+
+int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)
+{
+	return mmc_send_cxd_data(card, card->host, MMC_SEND_EXT_CSD,
+			ext_csd, 512);
+}
+
+int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp)
+{
+	struct mmc_command cmd;
+	int err;
+
+	memset(&cmd, 0, sizeof(struct mmc_command));
+
+	cmd.opcode = MMC_SPI_READ_OCR;
+	cmd.arg = highcap ? (1 << 30) : 0;
+	cmd.flags = MMC_RSP_SPI_R3;
+
+	err = mmc_wait_for_cmd(host, &cmd, 0);
+
+	*ocrp = cmd.resp[1];
+	return err;
+}
+
+int mmc_spi_set_crc(struct mmc_host *host, int use_crc)
+{
+	struct mmc_command cmd;
+	int err;
+
+	memset(&cmd, 0, sizeof(struct mmc_command));
+
+	cmd.opcode = MMC_SPI_CRC_ON_OFF;
+	cmd.flags = MMC_RSP_SPI_R1;
+	cmd.arg = use_crc;
+
+	err = mmc_wait_for_cmd(host, &cmd, 0);
+	if (!err)
+		host->use_spi_crc = use_crc;
+	return err;
 }
 
 int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value)
@@ -241,13 +341,13 @@
 		  (index << 16) |
 		  (value << 8) |
 		  set;
-	cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
+	cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
 
 	err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
-	if (err != MMC_ERR_NONE)
+	if (err)
 		return err;
 
-	return MMC_ERR_NONE;
+	return 0;
 }
 
 int mmc_send_status(struct mmc_card *card, u32 *status)
@@ -261,16 +361,20 @@
 	memset(&cmd, 0, sizeof(struct mmc_command));
 
 	cmd.opcode = MMC_SEND_STATUS;
-	cmd.arg = card->rca << 16;
-	cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+	if (!mmc_host_is_spi(card->host))
+		cmd.arg = card->rca << 16;
+	cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC;
 
 	err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
-	if (err != MMC_ERR_NONE)
+	if (err)
 		return err;
 
+	/* NOTE: callers are required to understand the difference
+	 * between "native" and SPI format status words!
+	 */
 	if (status)
 		*status = cmd.resp[0];
 
-	return MMC_ERR_NONE;
+	return 0;
 }
 
diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h
index 76d09a9..17854bf 100644
--- a/drivers/mmc/core/mmc_ops.h
+++ b/drivers/mmc/core/mmc_ops.h
@@ -22,6 +22,9 @@
 int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd);
 int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value);
 int mmc_send_status(struct mmc_card *card, u32 *status);
+int mmc_send_cid(struct mmc_host *host, u32 *cid);
+int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp);
+int mmc_spi_set_crc(struct mmc_host *host, int use_crc);
 
 #endif
 
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 1edc62b..d1c1e0f 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -166,8 +166,6 @@
 	unsigned int scr_struct;
 	u32 resp[4];
 
-	BUG_ON(!mmc_card_sd(card));
-
 	resp[3] = card->raw_scr[1];
 	resp[2] = card->raw_scr[0];
 
@@ -193,30 +191,38 @@
 	u8 *status;
 
 	if (card->scr.sda_vsn < SCR_SPEC_VER_1)
-		return MMC_ERR_NONE;
+		return 0;
 
 	if (!(card->csd.cmdclass & CCC_SWITCH)) {
 		printk(KERN_WARNING "%s: card lacks mandatory switch "
 			"function, performance might suffer.\n",
 			mmc_hostname(card->host));
-		return MMC_ERR_NONE;
+		return 0;
 	}
 
-	err = MMC_ERR_FAILED;
+	err = -EIO;
 
 	status = kmalloc(64, GFP_KERNEL);
 	if (!status) {
 		printk(KERN_ERR "%s: could not allocate a buffer for "
 			"switch capabilities.\n", mmc_hostname(card->host));
-		return err;
+		return -ENOMEM;
 	}
 
 	err = mmc_sd_switch(card, 0, 0, 1, status);
-	if (err != MMC_ERR_NONE) {
+	if (err) {
+		/*
+		 * We all hosts that cannot perform the command
+		 * to fail more gracefully
+		 */
+		if (err != -EINVAL)
+			goto out;
+
 		printk(KERN_WARNING "%s: problem reading switch "
 			"capabilities, performance might suffer.\n",
 			mmc_hostname(card->host));
-		err = MMC_ERR_NONE;
+		err = 0;
+
 		goto out;
 	}
 
@@ -238,28 +244,28 @@
 	u8 *status;
 
 	if (card->scr.sda_vsn < SCR_SPEC_VER_1)
-		return MMC_ERR_NONE;
+		return 0;
 
 	if (!(card->csd.cmdclass & CCC_SWITCH))
-		return MMC_ERR_NONE;
+		return 0;
 
 	if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED))
-		return MMC_ERR_NONE;
+		return 0;
 
 	if (card->sw_caps.hs_max_dtr == 0)
-		return MMC_ERR_NONE;
+		return 0;
 
-	err = MMC_ERR_FAILED;
+	err = -EIO;
 
 	status = kmalloc(64, GFP_KERNEL);
 	if (!status) {
 		printk(KERN_ERR "%s: could not allocate a buffer for "
 			"switch capabilities.\n", mmc_hostname(card->host));
-		return err;
+		return -ENOMEM;
 	}
 
 	err = mmc_sd_switch(card, 1, 0, 1, status);
-	if (err != MMC_ERR_NONE)
+	if (err)
 		goto out;
 
 	if ((status[16] & 0xF) != 1) {
@@ -292,7 +298,7 @@
 	unsigned int max_dtr;
 
 	BUG_ON(!host);
-	BUG_ON(!host->claimed);
+	WARN_ON(!host->claimed);
 
 	/*
 	 * Since we're changing the OCR value, we seem to
@@ -309,23 +315,37 @@
 	 * block-addressed SDHC cards.
 	 */
 	err = mmc_send_if_cond(host, ocr);
-	if (err == MMC_ERR_NONE)
+	if (!err)
 		ocr |= 1 << 30;
 
 	err = mmc_send_app_op_cond(host, ocr, NULL);
-	if (err != MMC_ERR_NONE)
+	if (err)
 		goto err;
 
 	/*
+	 * For SPI, enable CRC as appropriate.
+	 */
+	if (mmc_host_is_spi(host)) {
+		err = mmc_spi_set_crc(host, use_spi_crc);
+		if (err)
+			goto err;
+	}
+
+	/*
 	 * Fetch CID from card.
 	 */
-	err = mmc_all_send_cid(host, cid);
-	if (err != MMC_ERR_NONE)
+	if (mmc_host_is_spi(host))
+		err = mmc_send_cid(host, cid);
+	else
+		err = mmc_all_send_cid(host, cid);
+	if (err)
 		goto err;
 
 	if (oldcard) {
-		if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0)
+		if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) {
+			err = -ENOENT;
 			goto err;
+		}
 
 		card = oldcard;
 	} else {
@@ -333,32 +353,36 @@
 		 * Allocate card structure.
 		 */
 		card = mmc_alloc_card(host);
-		if (IS_ERR(card))
+		if (IS_ERR(card)) {
+			err = PTR_ERR(card);
 			goto err;
+		}
 
 		card->type = MMC_TYPE_SD;
 		memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
 	}
 
 	/*
-	 * Set card RCA.
+	 * For native busses:  get card RCA and quit open drain mode.
 	 */
-	err = mmc_send_relative_addr(host, &card->rca);
-	if (err != MMC_ERR_NONE)
-		goto free_card;
+	if (!mmc_host_is_spi(host)) {
+		err = mmc_send_relative_addr(host, &card->rca);
+		if (err)
+			goto free_card;
 
-	mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
+		mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
+	}
 
 	if (!oldcard) {
 		/*
 		 * Fetch CSD from card.
 		 */
 		err = mmc_send_csd(card, card->raw_csd);
-		if (err != MMC_ERR_NONE)
+		if (err)
 			goto free_card;
 
 		err = mmc_decode_csd(card);
-		if (err < 0)
+		if (err)
 			goto free_card;
 
 		mmc_decode_cid(card);
@@ -367,16 +391,18 @@
 	/*
 	 * Select card, as all following commands rely on that.
 	 */
-	err = mmc_select_card(card);
-	if (err != MMC_ERR_NONE)
-		goto free_card;
+	if (!mmc_host_is_spi(host)) {
+		err = mmc_select_card(card);
+		if (err)
+			goto free_card;
+	}
 
 	if (!oldcard) {
 		/*
 		 * Fetch SCR from card.
 		 */
 		err = mmc_app_send_scr(card, card->raw_scr);
-		if (err != MMC_ERR_NONE)
+		if (err)
 			goto free_card;
 
 		err = mmc_decode_scr(card);
@@ -387,7 +413,7 @@
 		 * Fetch switch information from card.
 		 */
 		err = mmc_read_switch(card);
-		if (err != MMC_ERR_NONE)
+		if (err)
 			goto free_card;
 	}
 
@@ -395,7 +421,7 @@
 	 * Attempt to change to high-speed (if supported)
 	 */
 	err = mmc_switch_hs(card);
-	if (err != MMC_ERR_NONE)
+	if (err)
 		goto free_card;
 
 	/*
@@ -418,7 +444,7 @@
 	if ((host->caps & MMC_CAP_4_BIT_DATA) &&
 		(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
 		err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
-		if (err != MMC_ERR_NONE)
+		if (err)
 			goto free_card;
 
 		mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
@@ -442,14 +468,14 @@
 	if (!oldcard)
 		host->card = card;
 
-	return MMC_ERR_NONE;
+	return 0;
 
 free_card:
 	if (!oldcard)
 		mmc_remove_card(card);
 err:
 
-	return MMC_ERR_FAILED;
+	return err;
 }
 
 /*
@@ -483,7 +509,7 @@
 
 	mmc_release_host(host);
 
-	if (err != MMC_ERR_NONE) {
+	if (err) {
 		mmc_sd_remove(host);
 
 		mmc_claim_host(host);
@@ -552,7 +578,8 @@
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
-	mmc_deselect_cards(host);
+	if (!mmc_host_is_spi(host))
+		mmc_deselect_cards(host);
 	host->card->state &= ~MMC_STATE_HIGHSPEED;
 	mmc_release_host(host);
 }
@@ -574,7 +601,7 @@
 	err = mmc_sd_init_card(host, host->ocr, host->card);
 	mmc_release_host(host);
 
-	if (err != MMC_ERR_NONE) {
+	if (err) {
 		mmc_sd_remove(host);
 
 		mmc_claim_host(host);
@@ -608,11 +635,22 @@
 	int err;
 
 	BUG_ON(!host);
-	BUG_ON(!host->claimed);
+	WARN_ON(!host->claimed);
 
 	mmc_attach_bus(host, &mmc_sd_ops);
 
 	/*
+	 * We need to get OCR a different way for SPI.
+	 */
+	if (mmc_host_is_spi(host)) {
+		mmc_go_idle(host);
+
+		err = mmc_spi_read_ocr(host, 0, &ocr);
+		if (err)
+			goto err;
+	}
+
+	/*
 	 * Sanity check the voltages that the card claims to
 	 * support.
 	 */
@@ -644,7 +682,7 @@
 	 * Detect and init the card.
 	 */
 	err = mmc_sd_init_card(host, host->ocr, NULL);
-	if (err != MMC_ERR_NONE)
+	if (err)
 		goto err;
 
 	mmc_release_host(host);
@@ -666,6 +704,6 @@
 	printk(KERN_ERR "%s: error %d whilst initialising SD card\n",
 		mmc_hostname(host), err);
 
-	return 0;
+	return err;
 }
 
diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c
index 342f340..ee4029a 100644
--- a/drivers/mmc/core/sd_ops.c
+++ b/drivers/mmc/core/sd_ops.c
@@ -33,21 +33,21 @@
 
 	if (card) {
 		cmd.arg = card->rca << 16;
-		cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+		cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
 	} else {
 		cmd.arg = 0;
-		cmd.flags = MMC_RSP_R1 | MMC_CMD_BCR;
+		cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_BCR;
 	}
 
 	err = mmc_wait_for_cmd(host, &cmd, 0);
-	if (err != MMC_ERR_NONE)
+	if (err)
 		return err;
 
 	/* Check that card supported application commands */
-	if (!(cmd.resp[0] & R1_APP_CMD))
-		return MMC_ERR_FAILED;
+	if (!mmc_host_is_spi(host) && !(cmd.resp[0] & R1_APP_CMD))
+		return -EOPNOTSUPP;
 
-	return MMC_ERR_NONE;
+	return 0;
 }
 
 /**
@@ -73,7 +73,7 @@
 	BUG_ON(!cmd);
 	BUG_ON(retries < 0);
 
-	err = MMC_ERR_INVALID;
+	err = -EIO;
 
 	/*
 	 * We have to resend MMC_APP_CMD for each attempt so
@@ -83,8 +83,14 @@
 		memset(&mrq, 0, sizeof(struct mmc_request));
 
 		err = mmc_app_cmd(host, card);
-		if (err != MMC_ERR_NONE)
+		if (err) {
+			/* no point in retrying; no APP commands allowed */
+			if (mmc_host_is_spi(host)) {
+				if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND)
+					break;
+			}
 			continue;
+		}
 
 		memset(&mrq, 0, sizeof(struct mmc_request));
 
@@ -97,8 +103,14 @@
 		mmc_wait_for_req(host, &mrq);
 
 		err = cmd->error;
-		if (cmd->error == MMC_ERR_NONE)
+		if (!cmd->error)
 			break;
+
+		/* no point in retrying illegal APP commands */
+		if (mmc_host_is_spi(host)) {
+			if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND)
+				break;
+		}
 	}
 
 	return err;
@@ -127,14 +139,14 @@
 		cmd.arg = SD_BUS_WIDTH_4;
 		break;
 	default:
-		return MMC_ERR_INVALID;
+		return -EINVAL;
 	}
 
 	err = mmc_wait_for_app_cmd(card->host, card, &cmd, MMC_CMD_RETRIES);
-	if (err != MMC_ERR_NONE)
+	if (err)
 		return err;
 
-	return MMC_ERR_NONE;
+	return 0;
 }
 
 int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
@@ -147,23 +159,36 @@
 	memset(&cmd, 0, sizeof(struct mmc_command));
 
 	cmd.opcode = SD_APP_OP_COND;
-	cmd.arg = ocr;
-	cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
+	if (mmc_host_is_spi(host))
+		cmd.arg = ocr & (1 << 30); /* SPI only defines one bit */
+	else
+		cmd.arg = ocr;
+	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;
 
 	for (i = 100; i; i--) {
 		err = mmc_wait_for_app_cmd(host, NULL, &cmd, MMC_CMD_RETRIES);
-		if (err != MMC_ERR_NONE)
+		if (err)
 			break;
 
-		if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0)
+		/* if we're just probing, do a single pass */
+		if (ocr == 0)
 			break;
 
-		err = MMC_ERR_TIMEOUT;
+		/* otherwise wait until reset completes */
+		if (mmc_host_is_spi(host)) {
+			if (!(cmd.resp[0] & R1_SPI_IDLE))
+				break;
+		} else {
+			if (cmd.resp[0] & MMC_CARD_BUSY)
+				break;
+		}
+
+		err = -ETIMEDOUT;
 
 		mmc_delay(10);
 	}
 
-	if (rocr)
+	if (rocr && !mmc_host_is_spi(host))
 		*rocr = cmd.resp[0];
 
 	return err;
@@ -174,6 +199,7 @@
 	struct mmc_command cmd;
 	int err;
 	static const u8 test_pattern = 0xAA;
+	u8 result_pattern;
 
 	/*
 	 * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND
@@ -182,16 +208,21 @@
 	 */
 	cmd.opcode = SD_SEND_IF_COND;
 	cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern;
-	cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR;
+	cmd.flags = MMC_RSP_SPI_R7 | MMC_RSP_R7 | MMC_CMD_BCR;
 
 	err = mmc_wait_for_cmd(host, &cmd, 0);
-	if (err != MMC_ERR_NONE)
+	if (err)
 		return err;
 
-	if ((cmd.resp[0] & 0xFF) != test_pattern)
-		return MMC_ERR_FAILED;
+	if (mmc_host_is_spi(host))
+		result_pattern = cmd.resp[1] & 0xFF;
+	else
+		result_pattern = cmd.resp[0] & 0xFF;
 
-	return MMC_ERR_NONE;
+	if (result_pattern != test_pattern)
+		return -EIO;
+
+	return 0;
 }
 
 int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca)
@@ -209,12 +240,12 @@
 	cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;
 
 	err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
-	if (err != MMC_ERR_NONE)
+	if (err)
 		return err;
 
 	*rca = cmd.resp[0] >> 16;
 
-	return MMC_ERR_NONE;
+	return 0;
 }
 
 int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
@@ -229,8 +260,10 @@
 	BUG_ON(!card->host);
 	BUG_ON(!scr);
 
+	/* NOTE: caller guarantees scr is heap-allocated */
+
 	err = mmc_app_cmd(card->host, card);
-	if (err != MMC_ERR_NONE)
+	if (err)
 		return err;
 
 	memset(&mrq, 0, sizeof(struct mmc_request));
@@ -242,7 +275,7 @@
 
 	cmd.opcode = SD_APP_SEND_SCR;
 	cmd.arg = 0;
-	cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
 
 	data.blksz = 8;
 	data.blocks = 1;
@@ -252,19 +285,19 @@
 
 	sg_init_one(&sg, scr, 8);
 
-	mmc_set_data_timeout(&data, card, 0);
+	mmc_set_data_timeout(&data, card);
 
 	mmc_wait_for_req(card->host, &mrq);
 
-	if (cmd.error != MMC_ERR_NONE)
+	if (cmd.error)
 		return cmd.error;
-	if (data.error != MMC_ERR_NONE)
+	if (data.error)
 		return data.error;
 
 	scr[0] = ntohl(scr[0]);
 	scr[1] = ntohl(scr[1]);
 
-	return MMC_ERR_NONE;
+	return 0;
 }
 
 int mmc_sd_switch(struct mmc_card *card, int mode, int group,
@@ -278,6 +311,8 @@
 	BUG_ON(!card);
 	BUG_ON(!card->host);
 
+	/* NOTE: caller guarantees resp is heap-allocated */
+
 	mode = !!mode;
 	value &= 0xF;
 
@@ -292,7 +327,7 @@
 	cmd.arg = mode << 31 | 0x00FFFFFF;
 	cmd.arg &= ~(0xF << (group * 4));
 	cmd.arg |= value << (group * 4);
-	cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
 
 	data.blksz = 64;
 	data.blocks = 1;
@@ -302,15 +337,15 @@
 
 	sg_init_one(&sg, resp, 64);
 
-	mmc_set_data_timeout(&data, card, 0);
+	mmc_set_data_timeout(&data, card);
 
 	mmc_wait_for_req(card->host, &mrq);
 
-	if (cmd.error != MMC_ERR_NONE)
+	if (cmd.error)
 		return cmd.error;
-	if (data.error != MMC_ERR_NONE)
+	if (data.error)
 		return data.error;
 
-	return MMC_ERR_NONE;
+	return 0;
 }
 
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
new file mode 100644
index 0000000..87a50f4
--- /dev/null
+++ b/drivers/mmc/core/sdio.c
@@ -0,0 +1,395 @@
+/*
+ *  linux/drivers/mmc/sdio.c
+ *
+ *  Copyright 2006-2007 Pierre Ossman
+ *
+ * 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/err.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sdio_func.h>
+
+#include "core.h"
+#include "bus.h"
+#include "sdio_bus.h"
+#include "mmc_ops.h"
+#include "sd_ops.h"
+#include "sdio_ops.h"
+#include "sdio_cis.h"
+
+static int sdio_read_fbr(struct sdio_func *func)
+{
+	int ret;
+	unsigned char data;
+
+	ret = mmc_io_rw_direct(func->card, 0, 0,
+		SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF, 0, &data);
+	if (ret)
+		goto out;
+
+	data &= 0x0f;
+
+	if (data == 0x0f) {
+		ret = mmc_io_rw_direct(func->card, 0, 0,
+			SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF_EXT, 0, &data);
+		if (ret)
+			goto out;
+	}
+
+	func->class = data;
+
+out:
+	return ret;
+}
+
+static int sdio_init_func(struct mmc_card *card, unsigned int fn)
+{
+	int ret;
+	struct sdio_func *func;
+
+	BUG_ON(fn > SDIO_MAX_FUNCS);
+
+	func = sdio_alloc_func(card);
+	if (IS_ERR(func))
+		return PTR_ERR(func);
+
+	func->num = fn;
+
+	ret = sdio_read_fbr(func);
+	if (ret)
+		goto fail;
+
+	ret = sdio_read_func_cis(func);
+	if (ret)
+		goto fail;
+
+	card->sdio_func[fn - 1] = func;
+
+	return 0;
+
+fail:
+	/*
+	 * It is okay to remove the function here even though we hold
+	 * the host lock as we haven't registered the device yet.
+	 */
+	sdio_remove_func(func);
+	return ret;
+}
+
+static int sdio_read_cccr(struct mmc_card *card)
+{
+	int ret;
+	int cccr_vsn;
+	unsigned char data;
+
+	memset(&card->cccr, 0, sizeof(struct sdio_cccr));
+
+	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_CCCR, 0, &data);
+	if (ret)
+		goto out;
+
+	cccr_vsn = data & 0x0f;
+
+	if (cccr_vsn > SDIO_CCCR_REV_1_20) {
+		printk(KERN_ERR "%s: unrecognised CCCR structure version %d\n",
+			mmc_hostname(card->host), cccr_vsn);
+		return -EINVAL;
+	}
+
+	card->cccr.sdio_vsn = (data & 0xf0) >> 4;
+
+	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_CAPS, 0, &data);
+	if (ret)
+		goto out;
+
+	if (data & SDIO_CCCR_CAP_SMB)
+		card->cccr.multi_block = 1;
+	if (data & SDIO_CCCR_CAP_LSC)
+		card->cccr.low_speed = 1;
+	if (data & SDIO_CCCR_CAP_4BLS)
+		card->cccr.wide_bus = 1;
+
+	if (cccr_vsn >= SDIO_CCCR_REV_1_10) {
+		ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_POWER, 0, &data);
+		if (ret)
+			goto out;
+
+		if (data & SDIO_POWER_SMPC)
+			card->cccr.high_power = 1;
+	}
+
+	if (cccr_vsn >= SDIO_CCCR_REV_1_20) {
+		ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &data);
+		if (ret)
+			goto out;
+
+		if (data & SDIO_SPEED_SHS)
+			card->cccr.high_speed = 1;
+	}
+
+out:
+	return ret;
+}
+
+static int sdio_enable_wide(struct mmc_card *card)
+{
+	int ret;
+	u8 ctrl;
+
+	if (!(card->host->caps & MMC_CAP_4_BIT_DATA))
+		return 0;
+
+	if (card->cccr.low_speed && !card->cccr.wide_bus)
+		return 0;
+
+	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl);
+	if (ret)
+		return ret;
+
+	ctrl |= SDIO_BUS_WIDTH_4BIT;
+
+	ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL);
+	if (ret)
+		return ret;
+
+	mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
+
+	return 0;
+}
+
+/*
+ * Host is being removed. Free up the current card.
+ */
+static void mmc_sdio_remove(struct mmc_host *host)
+{
+	int i;
+
+	BUG_ON(!host);
+	BUG_ON(!host->card);
+
+	for (i = 0;i < host->card->sdio_funcs;i++) {
+		if (host->card->sdio_func[i]) {
+			sdio_remove_func(host->card->sdio_func[i]);
+			host->card->sdio_func[i] = NULL;
+		}
+	}
+
+	mmc_remove_card(host->card);
+	host->card = NULL;
+}
+
+/*
+ * Card detection callback from host.
+ */
+static void mmc_sdio_detect(struct mmc_host *host)
+{
+	int err;
+
+	BUG_ON(!host);
+	BUG_ON(!host->card);
+
+	mmc_claim_host(host);
+
+	/*
+	 * Just check if our card has been removed.
+	 */
+	err = mmc_select_card(host->card);
+
+	mmc_release_host(host);
+
+	if (err) {
+		mmc_sdio_remove(host);
+
+		mmc_claim_host(host);
+		mmc_detach_bus(host);
+		mmc_release_host(host);
+	}
+}
+
+
+static const struct mmc_bus_ops mmc_sdio_ops = {
+	.remove = mmc_sdio_remove,
+	.detect = mmc_sdio_detect,
+};
+
+
+/*
+ * Starting point for SDIO card init.
+ */
+int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
+{
+	int err;
+	int i, funcs;
+	struct mmc_card *card;
+
+	BUG_ON(!host);
+	WARN_ON(!host->claimed);
+
+	mmc_attach_bus(host, &mmc_sdio_ops);
+
+	/*
+	 * Sanity check the voltages that the card claims to
+	 * support.
+	 */
+	if (ocr & 0x7F) {
+		printk(KERN_WARNING "%s: card claims to support voltages "
+		       "below the defined range. These will be ignored.\n",
+		       mmc_hostname(host));
+		ocr &= ~0x7F;
+	}
+
+	if (ocr & MMC_VDD_165_195) {
+		printk(KERN_WARNING "%s: SDIO card claims to support the "
+		       "incompletely defined 'low voltage range'. This "
+		       "will be ignored.\n", mmc_hostname(host));
+		ocr &= ~MMC_VDD_165_195;
+	}
+
+	host->ocr = mmc_select_voltage(host, ocr);
+
+	/*
+	 * Can we support the voltage(s) of the card(s)?
+	 */
+	if (!host->ocr) {
+		err = -EINVAL;
+		goto err;
+	}
+
+	/*
+	 * Inform the card of the voltage
+	 */
+	err = mmc_send_io_op_cond(host, host->ocr, &ocr);
+	if (err)
+		goto err;
+
+	/*
+	 * For SPI, enable CRC as appropriate.
+	 */
+	if (mmc_host_is_spi(host)) {
+		err = mmc_spi_set_crc(host, use_spi_crc);
+		if (err)
+			goto err;
+	}
+
+	/*
+	 * The number of functions on the card is encoded inside
+	 * the ocr.
+	 */
+	funcs = (ocr & 0x70000000) >> 28;
+
+	/*
+	 * Allocate card structure.
+	 */
+	card = mmc_alloc_card(host);
+	if (IS_ERR(card)) {
+		err = PTR_ERR(card);
+		goto err;
+	}
+
+	card->type = MMC_TYPE_SDIO;
+	card->sdio_funcs = funcs;
+
+	host->card = card;
+
+	/*
+	 * For native busses:  set card RCA and quit open drain mode.
+	 */
+	if (!mmc_host_is_spi(host)) {
+		err = mmc_send_relative_addr(host, &card->rca);
+		if (err)
+			goto remove;
+
+		mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
+	}
+
+	/*
+	 * Select card, as all following commands rely on that.
+	 */
+	if (!mmc_host_is_spi(host)) {
+		err = mmc_select_card(card);
+		if (err)
+			goto remove;
+	}
+
+	/*
+	 * Read the common registers.
+	 */
+	err = sdio_read_cccr(card);
+	if (err)
+		goto remove;
+
+	/*
+	 * Read the common CIS tuples.
+	 */
+	err = sdio_read_common_cis(card);
+	if (err)
+		goto remove;
+
+	/*
+	 * No support for high-speed yet, so just set
+	 * the card's maximum speed.
+	 */
+	mmc_set_clock(host, card->cis.max_dtr);
+
+	/*
+	 * Switch to wider bus (if supported).
+	 */
+	err = sdio_enable_wide(card);
+	if (err)
+		goto remove;
+
+	/*
+	 * Initialize (but don't add) all present functions.
+	 */
+	for (i = 0;i < funcs;i++) {
+		err = sdio_init_func(host->card, i + 1);
+		if (err)
+			goto remove;
+	}
+
+	mmc_release_host(host);
+
+	/*
+	 * First add the card to the driver model...
+	 */
+	err = mmc_add_card(host->card);
+	if (err)
+		goto remove_added;
+
+	/*
+	 * ...then the SDIO functions.
+	 */
+	for (i = 0;i < funcs;i++) {
+		err = sdio_add_func(host->card->sdio_func[i]);
+		if (err)
+			goto remove_added;
+	}
+
+	return 0;
+
+
+remove_added:
+	/* Remove without lock if the device has been added. */
+	mmc_sdio_remove(host);
+	mmc_claim_host(host);
+remove:
+	/* And with lock if it hasn't been added. */
+	if (host->card)
+		mmc_sdio_remove(host);
+err:
+	mmc_detach_bus(host);
+	mmc_release_host(host);
+
+	printk(KERN_ERR "%s: error %d whilst initialising SDIO card\n",
+		mmc_hostname(host), err);
+
+	return err;
+}
+
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
new file mode 100644
index 0000000..0713a8c
--- /dev/null
+++ b/drivers/mmc/core/sdio_bus.c
@@ -0,0 +1,270 @@
+/*
+ *  linux/drivers/mmc/core/sdio_bus.c
+ *
+ *  Copyright 2007 Pierre Ossman
+ *
+ * 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.
+ *
+ * SDIO function driver model
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+
+#include "sdio_cis.h"
+#include "sdio_bus.h"
+
+#define dev_to_sdio_func(d)	container_of(d, struct sdio_func, dev)
+#define to_sdio_driver(d)      container_of(d, struct sdio_driver, drv)
+
+/* show configuration fields */
+#define sdio_config_attr(field, format_string)				\
+static ssize_t								\
+field##_show(struct device *dev, struct device_attribute *attr, char *buf)				\
+{									\
+	struct sdio_func *func;						\
+									\
+	func = dev_to_sdio_func (dev);					\
+	return sprintf (buf, format_string, func->field);		\
+}
+
+sdio_config_attr(class, "0x%02x\n");
+sdio_config_attr(vendor, "0x%04x\n");
+sdio_config_attr(device, "0x%04x\n");
+
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct sdio_func *func = dev_to_sdio_func (dev);
+
+	return sprintf(buf, "sdio:c%02Xv%04Xd%04X\n",
+			func->class, func->vendor, func->device);
+}
+
+static struct device_attribute sdio_dev_attrs[] = {
+	__ATTR_RO(class),
+	__ATTR_RO(vendor),
+	__ATTR_RO(device),
+	__ATTR_RO(modalias),
+	__ATTR_NULL,
+};
+
+static const struct sdio_device_id *sdio_match_one(struct sdio_func *func,
+	const struct sdio_device_id *id)
+{
+	if (id->class != (__u8)SDIO_ANY_ID && id->class != func->class)
+		return NULL;
+	if (id->vendor != (__u16)SDIO_ANY_ID && id->vendor != func->vendor)
+		return NULL;
+	if (id->device != (__u16)SDIO_ANY_ID && id->device != func->device)
+		return NULL;
+	return id;
+}
+
+static const struct sdio_device_id *sdio_match_device(struct sdio_func *func,
+	struct sdio_driver *sdrv)
+{
+	const struct sdio_device_id *ids;
+
+	ids = sdrv->id_table;
+
+	if (ids) {
+		while (ids->class || ids->vendor || ids->device) {
+			if (sdio_match_one(func, ids))
+				return ids;
+			ids++;
+		}
+	}
+
+	return NULL;
+}
+
+static int sdio_bus_match(struct device *dev, struct device_driver *drv)
+{
+	struct sdio_func *func = dev_to_sdio_func(dev);
+	struct sdio_driver *sdrv = to_sdio_driver(drv);
+
+	if (sdio_match_device(func, sdrv))
+		return 1;
+
+	return 0;
+}
+
+static int
+sdio_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf,
+		int buf_size)
+{
+	struct sdio_func *func = dev_to_sdio_func(dev);
+	int i = 0, length = 0;
+
+	if (add_uevent_var(envp, num_envp, &i,
+			buf, buf_size, &length,
+			"SDIO_CLASS=%02X", func->class))
+		return -ENOMEM;
+
+	if (add_uevent_var(envp, num_envp, &i,
+			buf, buf_size, &length,
+			"SDIO_ID=%04X:%04X", func->vendor, func->device))
+		return -ENOMEM;
+
+	if (add_uevent_var(envp, num_envp, &i,
+			buf, buf_size, &length,
+			"MODALIAS=sdio:c%02Xv%04Xd%04X",
+			func->class, func->vendor, func->device))
+		return -ENOMEM;
+
+	envp[i] = NULL;
+
+	return 0;
+}
+
+static int sdio_bus_probe(struct device *dev)
+{
+	struct sdio_driver *drv = to_sdio_driver(dev->driver);
+	struct sdio_func *func = dev_to_sdio_func(dev);
+	const struct sdio_device_id *id;
+	int ret;
+
+	id = sdio_match_device(func, drv);
+	if (!id)
+		return -ENODEV;
+
+	/* Set the default block size so the driver is sure it's something
+	 * sensible. */
+	sdio_claim_host(func);
+	ret = sdio_set_block_size(func, 0);
+	sdio_release_host(func);
+	if (ret)
+		return ret;
+
+	return drv->probe(func, id);
+}
+
+static int sdio_bus_remove(struct device *dev)
+{
+	struct sdio_driver *drv = to_sdio_driver(dev->driver);
+	struct sdio_func *func = dev_to_sdio_func(dev);
+
+	drv->remove(func);
+
+	if (func->irq_handler) {
+		printk(KERN_WARNING "WARNING: driver %s did not remove "
+			"its interrupt handler!\n", drv->name);
+		sdio_claim_host(func);
+		sdio_release_irq(func);
+		sdio_release_host(func);
+	}
+
+	return 0;
+}
+
+static struct bus_type sdio_bus_type = {
+	.name		= "sdio",
+	.dev_attrs	= sdio_dev_attrs,
+	.match		= sdio_bus_match,
+	.uevent		= sdio_bus_uevent,
+	.probe		= sdio_bus_probe,
+	.remove		= sdio_bus_remove,
+};
+
+int sdio_register_bus(void)
+{
+	return bus_register(&sdio_bus_type);
+}
+
+void sdio_unregister_bus(void)
+{
+	bus_unregister(&sdio_bus_type);
+}
+
+/**
+ *	sdio_register_driver - register a function driver
+ *	@drv: SDIO function driver
+ */
+int sdio_register_driver(struct sdio_driver *drv)
+{
+	drv->drv.name = drv->name;
+	drv->drv.bus = &sdio_bus_type;
+	return driver_register(&drv->drv);
+}
+EXPORT_SYMBOL_GPL(sdio_register_driver);
+
+/**
+ *	sdio_unregister_driver - unregister a function driver
+ *	@drv: SDIO function driver
+ */
+void sdio_unregister_driver(struct sdio_driver *drv)
+{
+	drv->drv.bus = &sdio_bus_type;
+	driver_unregister(&drv->drv);
+}
+EXPORT_SYMBOL_GPL(sdio_unregister_driver);
+
+static void sdio_release_func(struct device *dev)
+{
+	struct sdio_func *func = dev_to_sdio_func(dev);
+
+	sdio_free_func_cis(func);
+
+	if (func->info)
+		kfree(func->info);
+
+	kfree(func);
+}
+
+/*
+ * Allocate and initialise a new SDIO function structure.
+ */
+struct sdio_func *sdio_alloc_func(struct mmc_card *card)
+{
+	struct sdio_func *func;
+
+	func = kzalloc(sizeof(struct sdio_func), GFP_KERNEL);
+	if (!func)
+		return ERR_PTR(-ENOMEM);
+
+	func->card = card;
+
+	device_initialize(&func->dev);
+
+	func->dev.parent = &card->dev;
+	func->dev.bus = &sdio_bus_type;
+	func->dev.release = sdio_release_func;
+
+	return func;
+}
+
+/*
+ * Register a new SDIO function with the driver model.
+ */
+int sdio_add_func(struct sdio_func *func)
+{
+	int ret;
+
+	snprintf(func->dev.bus_id, sizeof(func->dev.bus_id),
+		 "%s:%d", mmc_card_id(func->card), func->num);
+
+	ret = device_add(&func->dev);
+	if (ret == 0)
+		sdio_func_set_present(func);
+
+	return ret;
+}
+
+/*
+ * Unregister a SDIO function with the driver model, and
+ * (eventually) free it.
+ */
+void sdio_remove_func(struct sdio_func *func)
+{
+	if (sdio_func_present(func))
+		device_del(&func->dev);
+
+	put_device(&func->dev);
+}
+
diff --git a/drivers/mmc/core/sdio_bus.h b/drivers/mmc/core/sdio_bus.h
new file mode 100644
index 0000000..567a768
--- /dev/null
+++ b/drivers/mmc/core/sdio_bus.h
@@ -0,0 +1,22 @@
+/*
+ *  linux/drivers/mmc/core/sdio_bus.h
+ *
+ *  Copyright 2007 Pierre Ossman
+ *
+ * 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.
+ */
+#ifndef _MMC_CORE_SDIO_BUS_H
+#define _MMC_CORE_SDIO_BUS_H
+
+struct sdio_func *sdio_alloc_func(struct mmc_card *card);
+int sdio_add_func(struct sdio_func *func);
+void sdio_remove_func(struct sdio_func *func);
+
+int sdio_register_bus(void);
+void sdio_unregister_bus(void);
+
+#endif
+
diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c
new file mode 100644
index 0000000..d5e51b1
--- /dev/null
+++ b/drivers/mmc/core/sdio_cis.c
@@ -0,0 +1,346 @@
+/*
+ * linux/drivers/mmc/core/sdio_cis.c
+ *
+ * Author:	Nicolas Pitre
+ * Created:	June 11, 2007
+ * Copyright:	MontaVista Software Inc.
+ *
+ * Copyright 2007 Pierre Ossman
+ *
+ * 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/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sdio_func.h>
+
+#include "sdio_cis.h"
+#include "sdio_ops.h"
+
+static int cistpl_vers_1(struct mmc_card *card, struct sdio_func *func,
+			 const unsigned char *buf, unsigned size)
+{
+	unsigned i, nr_strings;
+	char **buffer, *string;
+
+	buf += 2;
+	size -= 2;
+
+	nr_strings = 0;
+	for (i = 0; i < size; i++) {
+		if (buf[i] == 0xff)
+			break;
+		if (buf[i] == 0)
+			nr_strings++;
+	}
+
+	if (buf[i-1] != '\0') {
+		printk(KERN_WARNING "SDIO: ignoring broken CISTPL_VERS_1\n");
+		return 0;
+	}
+
+	size = i;
+
+	buffer = kzalloc(sizeof(char*) * nr_strings + size, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	string = (char*)(buffer + nr_strings);
+
+	for (i = 0; i < nr_strings; i++) {
+		buffer[i] = string;
+		strcpy(string, buf);
+		string += strlen(string) + 1;
+		buf += strlen(buf) + 1;
+	}
+
+	if (func) {
+		func->num_info = nr_strings;
+		func->info = (const char**)buffer;
+	} else {
+		card->num_info = nr_strings;
+		card->info = (const char**)buffer;
+	}
+
+	return 0;
+}
+
+static int cistpl_manfid(struct mmc_card *card, struct sdio_func *func,
+			 const unsigned char *buf, unsigned size)
+{
+	unsigned int vendor, device;
+
+	/* TPLMID_MANF */
+	vendor = buf[0] | (buf[1] << 8);
+
+	/* TPLMID_CARD */
+	device = buf[2] | (buf[3] << 8);
+
+	if (func) {
+		func->vendor = vendor;
+		func->device = device;
+	} else {
+		card->cis.vendor = vendor;
+		card->cis.device = device;
+	}
+
+	return 0;
+}
+
+static const unsigned char speed_val[16] =
+	{ 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 };
+static const unsigned int speed_unit[8] =
+	{ 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 };
+
+static int cistpl_funce_common(struct mmc_card *card,
+			       const unsigned char *buf, unsigned size)
+{
+	if (size < 0x04 || buf[0] != 0)
+		return -EINVAL;
+
+	/* TPLFE_FN0_BLK_SIZE */
+	card->cis.blksize = buf[1] | (buf[2] << 8);
+
+	/* TPLFE_MAX_TRAN_SPEED */
+	card->cis.max_dtr = speed_val[(buf[3] >> 3) & 15] *
+			    speed_unit[buf[3] & 7];
+
+	return 0;
+}
+
+static int cistpl_funce_func(struct sdio_func *func,
+			     const unsigned char *buf, unsigned size)
+{
+	unsigned vsn;
+	unsigned min_size;
+
+	vsn = func->card->cccr.sdio_vsn;
+	min_size = (vsn == SDIO_SDIO_REV_1_00) ? 28 : 42;
+
+	if (size < min_size || buf[0] != 1)
+		return -EINVAL;
+
+	/* TPLFE_MAX_BLK_SIZE */
+	func->max_blksize = buf[12] | (buf[13] << 8);
+
+	return 0;
+}
+
+static int cistpl_funce(struct mmc_card *card, struct sdio_func *func,
+			const unsigned char *buf, unsigned size)
+{
+	int ret;
+
+	/*
+	 * There should be two versions of the CISTPL_FUNCE tuple,
+	 * one for the common CIS (function 0) and a version used by
+	 * the individual function's CIS (1-7). Yet, the later has a
+	 * different length depending on the SDIO spec version.
+	 */
+	if (func)
+		ret = cistpl_funce_func(func, buf, size);
+	else
+		ret = cistpl_funce_common(card, buf, size);
+
+	if (ret) {
+		printk(KERN_ERR "%s: bad CISTPL_FUNCE size %u "
+		       "type %u\n", mmc_hostname(card->host), size, buf[0]);
+		return ret;
+	}
+
+	return 0;
+}
+
+typedef int (tpl_parse_t)(struct mmc_card *, struct sdio_func *,
+			   const unsigned char *, unsigned);
+
+struct cis_tpl {
+	unsigned char code;
+	unsigned char min_size;
+	tpl_parse_t *parse;
+};
+
+static const struct cis_tpl cis_tpl_list[] = {
+	{	0x15,	3,	cistpl_vers_1		},
+	{	0x20,	4,	cistpl_manfid		},
+	{	0x21,	2,	/* cistpl_funcid */	},
+	{	0x22,	0,	cistpl_funce		},
+};
+
+static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
+{
+	int ret;
+	struct sdio_func_tuple *this, **prev;
+	unsigned i, ptr = 0;
+
+	/*
+	 * Note that this works for the common CIS (function number 0) as
+	 * well as a function's CIS * since SDIO_CCCR_CIS and SDIO_FBR_CIS
+	 * have the same offset.
+	 */
+	for (i = 0; i < 3; i++) {
+		unsigned char x, fn;
+
+		if (func)
+			fn = func->num;
+		else
+			fn = 0;
+
+		ret = mmc_io_rw_direct(card, 0, 0,
+			SDIO_FBR_BASE(fn) + SDIO_FBR_CIS + i, 0, &x);
+		if (ret)
+			return ret;
+		ptr |= x << (i * 8);
+	}
+
+	if (func)
+		prev = &func->tuples;
+	else
+		prev = &card->tuples;
+
+	BUG_ON(*prev);
+
+	do {
+		unsigned char tpl_code, tpl_link;
+
+		ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_code);
+		if (ret)
+			break;
+
+		/* 0xff means we're done */
+		if (tpl_code == 0xff)
+			break;
+
+		ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_link);
+		if (ret)
+			break;
+
+		this = kmalloc(sizeof(*this) + tpl_link, GFP_KERNEL);
+		if (!this)
+			return -ENOMEM;
+
+		for (i = 0; i < tpl_link; i++) {
+			ret = mmc_io_rw_direct(card, 0, 0,
+					       ptr + i, 0, &this->data[i]);
+			if (ret)
+				break;
+		}
+		if (ret) {
+			kfree(this);
+			break;
+		}
+
+		for (i = 0; i < ARRAY_SIZE(cis_tpl_list); i++)
+			if (cis_tpl_list[i].code == tpl_code)
+				break;
+		if (i >= ARRAY_SIZE(cis_tpl_list)) {
+			/* this tuple is unknown to the core */
+			this->next = NULL;
+			this->code = tpl_code;
+			this->size = tpl_link;
+			*prev = this;
+			prev = &this->next;
+			printk(KERN_DEBUG
+			       "%s: queuing CIS tuple 0x%02x length %u\n",
+			       mmc_hostname(card->host), tpl_code, tpl_link);
+		} else {
+			const struct cis_tpl *tpl = cis_tpl_list + i;
+			if (tpl_link < tpl->min_size) {
+				printk(KERN_ERR
+				       "%s: bad CIS tuple 0x%02x (length = %u, expected >= %u)\n",
+				       mmc_hostname(card->host),
+				       tpl_code, tpl_link, tpl->min_size);
+				ret = -EINVAL;
+			} else if (tpl->parse) {
+				ret = tpl->parse(card, func,
+						 this->data, tpl_link);
+			}
+			kfree(this);
+		}
+
+		ptr += tpl_link;
+	} while (!ret);
+
+	/*
+	 * Link in all unknown tuples found in the common CIS so that
+	 * drivers don't have to go digging in two places.
+	 */
+	if (func)
+		*prev = card->tuples;
+
+	return ret;
+}
+
+int sdio_read_common_cis(struct mmc_card *card)
+{
+	return sdio_read_cis(card, NULL);
+}
+
+void sdio_free_common_cis(struct mmc_card *card)
+{
+	struct sdio_func_tuple *tuple, *victim;
+
+	tuple = card->tuples;
+
+	while (tuple) {
+		victim = tuple;
+		tuple = tuple->next;
+		kfree(victim);
+	}
+
+	card->tuples = NULL;
+}
+
+int sdio_read_func_cis(struct sdio_func *func)
+{
+	int ret;
+
+	ret = sdio_read_cis(func->card, func);
+	if (ret)
+		return ret;
+
+	/*
+	 * Since we've linked to tuples in the card structure,
+	 * we must make sure we have a reference to it.
+	 */
+	get_device(&func->card->dev);
+
+	/*
+	 * Vendor/device id is optional for function CIS, so
+	 * copy it from the card structure as needed.
+	 */
+	if (func->vendor == 0) {
+		func->vendor = func->card->cis.vendor;
+		func->device = func->card->cis.device;
+	}
+
+	return 0;
+}
+
+void sdio_free_func_cis(struct sdio_func *func)
+{
+	struct sdio_func_tuple *tuple, *victim;
+
+	tuple = func->tuples;
+
+	while (tuple && tuple != func->card->tuples) {
+		victim = tuple;
+		tuple = tuple->next;
+		kfree(victim);
+	}
+
+	func->tuples = NULL;
+
+	/*
+	 * We have now removed the link to the tuples in the
+	 * card structure, so remove the reference.
+	 */
+	put_device(&func->card->dev);
+}
+
diff --git a/drivers/mmc/core/sdio_cis.h b/drivers/mmc/core/sdio_cis.h
new file mode 100644
index 0000000..4d903c2
--- /dev/null
+++ b/drivers/mmc/core/sdio_cis.h
@@ -0,0 +1,23 @@
+/*
+ * linux/drivers/mmc/core/sdio_cis.h
+ *
+ * Author:	Nicolas Pitre
+ * Created:	June 11, 2007
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef _MMC_SDIO_CIS_H
+#define _MMC_SDIO_CIS_H
+
+int sdio_read_common_cis(struct mmc_card *card);
+void sdio_free_common_cis(struct mmc_card *card);
+
+int sdio_read_func_cis(struct sdio_func *func);
+void sdio_free_func_cis(struct sdio_func *func);
+
+#endif
diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c
new file mode 100644
index 0000000..625b92c
--- /dev/null
+++ b/drivers/mmc/core/sdio_io.c
@@ -0,0 +1,548 @@
+/*
+ *  linux/drivers/mmc/core/sdio_io.c
+ *
+ *  Copyright 2007 Pierre Ossman
+ *
+ * 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/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sdio_func.h>
+
+#include "sdio_ops.h"
+
+/**
+ *	sdio_claim_host - exclusively claim a bus for a certain SDIO function
+ *	@func: SDIO function that will be accessed
+ *
+ *	Claim a bus for a set of operations. The SDIO function given
+ *	is used to figure out which bus is relevant.
+ */
+void sdio_claim_host(struct sdio_func *func)
+{
+	BUG_ON(!func);
+	BUG_ON(!func->card);
+
+	mmc_claim_host(func->card->host);
+}
+EXPORT_SYMBOL_GPL(sdio_claim_host);
+
+/**
+ *	sdio_release_host - release a bus for a certain SDIO function
+ *	@func: SDIO function that was accessed
+ *
+ *	Release a bus, allowing others to claim the bus for their
+ *	operations.
+ */
+void sdio_release_host(struct sdio_func *func)
+{
+	BUG_ON(!func);
+	BUG_ON(!func->card);
+
+	mmc_release_host(func->card->host);
+}
+EXPORT_SYMBOL_GPL(sdio_release_host);
+
+/**
+ *	sdio_enable_func - enables a SDIO function for usage
+ *	@func: SDIO function to enable
+ *
+ *	Powers up and activates a SDIO function so that register
+ *	access is possible.
+ */
+int sdio_enable_func(struct sdio_func *func)
+{
+	int ret;
+	unsigned char reg;
+	unsigned long timeout;
+
+	BUG_ON(!func);
+	BUG_ON(!func->card);
+
+	pr_debug("SDIO: Enabling device %s...\n", sdio_func_id(func));
+
+	ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IOEx, 0, &reg);
+	if (ret)
+		goto err;
+
+	reg |= 1 << func->num;
+
+	ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IOEx, reg, NULL);
+	if (ret)
+		goto err;
+
+	/*
+	 * FIXME: This should timeout based on information in the CIS,
+	 * but we don't have card to parse that yet.
+	 */
+	timeout = jiffies + HZ;
+
+	while (1) {
+		ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IORx, 0, &reg);
+		if (ret)
+			goto err;
+		if (reg & (1 << func->num))
+			break;
+		ret = -ETIME;
+		if (time_after(jiffies, timeout))
+			goto err;
+	}
+
+	pr_debug("SDIO: Enabled device %s\n", sdio_func_id(func));
+
+	return 0;
+
+err:
+	pr_debug("SDIO: Failed to enable device %s\n", sdio_func_id(func));
+	return ret;
+}
+EXPORT_SYMBOL_GPL(sdio_enable_func);
+
+/**
+ *	sdio_disable_func - disable a SDIO function
+ *	@func: SDIO function to disable
+ *
+ *	Powers down and deactivates a SDIO function. Register access
+ *	to this function will fail until the function is reenabled.
+ */
+int sdio_disable_func(struct sdio_func *func)
+{
+	int ret;
+	unsigned char reg;
+
+	BUG_ON(!func);
+	BUG_ON(!func->card);
+
+	pr_debug("SDIO: Disabling device %s...\n", sdio_func_id(func));
+
+	ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IOEx, 0, &reg);
+	if (ret)
+		goto err;
+
+	reg &= ~(1 << func->num);
+
+	ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IOEx, reg, NULL);
+	if (ret)
+		goto err;
+
+	pr_debug("SDIO: Disabled device %s\n", sdio_func_id(func));
+
+	return 0;
+
+err:
+	pr_debug("SDIO: Failed to disable device %s\n", sdio_func_id(func));
+	return -EIO;
+}
+EXPORT_SYMBOL_GPL(sdio_disable_func);
+
+/**
+ *	sdio_set_block_size - set the block size of an SDIO function
+ *	@func: SDIO function to change
+ *	@blksz: new block size or 0 to use the default.
+ *
+ *	The default block size is the largest supported by both the function
+ *	and the host, with a maximum of 512 to ensure that arbitrarily sized
+ *	data transfer use the optimal (least) number of commands.
+ *
+ *	A driver may call this to override the default block size set by the
+ *	core. This can be used to set a block size greater than the maximum
+ *	that reported by the card; it is the driver's responsibility to ensure
+ *	it uses a value that the card supports.
+ *
+ *	Returns 0 on success, -EINVAL if the host does not support the
+ *	requested block size, or -EIO (etc.) if one of the resultant FBR block
+ *	size register writes failed.
+ *
+ */
+int sdio_set_block_size(struct sdio_func *func, unsigned blksz)
+{
+	int ret;
+
+	if (blksz > func->card->host->max_blk_size)
+		return -EINVAL;
+
+	if (blksz == 0) {
+		blksz = min(min(
+			func->max_blksize,
+			func->card->host->max_blk_size),
+			512u);
+	}
+
+	ret = mmc_io_rw_direct(func->card, 1, 0,
+		SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE,
+		blksz & 0xff, NULL);
+	if (ret)
+		return ret;
+	ret = mmc_io_rw_direct(func->card, 1, 0,
+		SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE + 1,
+		(blksz >> 8) & 0xff, NULL);
+	if (ret)
+		return ret;
+	func->cur_blksize = blksz;
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(sdio_set_block_size);
+
+/* Split an arbitrarily sized data transfer into several
+ * IO_RW_EXTENDED commands. */
+static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
+	unsigned addr, int incr_addr, u8 *buf, unsigned size)
+{
+	unsigned remainder = size;
+	unsigned max_blocks;
+	int ret;
+
+	/* Do the bulk of the transfer using block mode (if supported). */
+	if (func->card->cccr.multi_block) {
+		/* Blocks per command is limited by host count, host transfer
+		 * size (we only use a single sg entry) and the maximum for
+		 * IO_RW_EXTENDED of 511 blocks. */
+		max_blocks = min(min(
+			func->card->host->max_blk_count,
+			func->card->host->max_seg_size / func->cur_blksize),
+			511u);
+
+		while (remainder > func->cur_blksize) {
+			unsigned blocks;
+
+			blocks = remainder / func->cur_blksize;
+			if (blocks > max_blocks)
+				blocks = max_blocks;
+			size = blocks * func->cur_blksize;
+
+			ret = mmc_io_rw_extended(func->card, write,
+				func->num, addr, incr_addr, buf,
+				blocks, func->cur_blksize);
+			if (ret)
+				return ret;
+
+			remainder -= size;
+			buf += size;
+			if (incr_addr)
+				addr += size;
+		}
+	}
+
+	/* Write the remainder using byte mode. */
+	while (remainder > 0) {
+		size = remainder;
+		if (size > func->cur_blksize)
+			size = func->cur_blksize;
+		if (size > 512)
+			size = 512; /* maximum size for byte mode */
+
+		ret = mmc_io_rw_extended(func->card, write, func->num, addr,
+			 incr_addr, buf, 1, size);
+		if (ret)
+			return ret;
+
+		remainder -= size;
+		buf += size;
+		if (incr_addr)
+			addr += size;
+	}
+	return 0;
+}
+
+/**
+ *	sdio_readb - read a single byte from a SDIO function
+ *	@func: SDIO function to access
+ *	@addr: address to read
+ *	@err_ret: optional status value from transfer
+ *
+ *	Reads a single byte from the address space of a given SDIO
+ *	function. If there is a problem reading the address, 0xff
+ *	is returned and @err_ret will contain the error code.
+ */
+unsigned char sdio_readb(struct sdio_func *func, unsigned int addr,
+	int *err_ret)
+{
+	int ret;
+	unsigned char val;
+
+	BUG_ON(!func);
+
+	if (err_ret)
+		*err_ret = 0;
+
+	ret = mmc_io_rw_direct(func->card, 0, func->num, addr, 0, &val);
+	if (ret) {
+		if (err_ret)
+			*err_ret = ret;
+		return 0xFF;
+	}
+
+	return val;
+}
+EXPORT_SYMBOL_GPL(sdio_readb);
+
+/**
+ *	sdio_writeb - write a single byte to a SDIO function
+ *	@func: SDIO function to access
+ *	@b: byte to write
+ *	@addr: address to write to
+ *	@err_ret: optional status value from transfer
+ *
+ *	Writes a single byte to the address space of a given SDIO
+ *	function. @err_ret will contain the status of the actual
+ *	transfer.
+ */
+void sdio_writeb(struct sdio_func *func, unsigned char b, unsigned int addr,
+	int *err_ret)
+{
+	int ret;
+
+	BUG_ON(!func);
+
+	ret = mmc_io_rw_direct(func->card, 1, func->num, addr, b, NULL);
+	if (err_ret)
+		*err_ret = ret;
+}
+EXPORT_SYMBOL_GPL(sdio_writeb);
+
+/**
+ *	sdio_memcpy_fromio - read a chunk of memory from a SDIO function
+ *	@func: SDIO function to access
+ *	@dst: buffer to store the data
+ *	@addr: address to begin reading from
+ *	@count: number of bytes to read
+ *
+ *	Reads from the address space of a given SDIO function. Return
+ *	value indicates if the transfer succeeded or not.
+ */
+int sdio_memcpy_fromio(struct sdio_func *func, void *dst,
+	unsigned int addr, int count)
+{
+	return sdio_io_rw_ext_helper(func, 0, addr, 1, dst, count);
+}
+EXPORT_SYMBOL_GPL(sdio_memcpy_fromio);
+
+/**
+ *	sdio_memcpy_toio - write a chunk of memory to a SDIO function
+ *	@func: SDIO function to access
+ *	@addr: address to start writing to
+ *	@src: buffer that contains the data to write
+ *	@count: number of bytes to write
+ *
+ *	Writes to the address space of a given SDIO function. Return
+ *	value indicates if the transfer succeeded or not.
+ */
+int sdio_memcpy_toio(struct sdio_func *func, unsigned int addr,
+	void *src, int count)
+{
+	return sdio_io_rw_ext_helper(func, 1, addr, 1, src, count);
+}
+EXPORT_SYMBOL_GPL(sdio_memcpy_toio);
+
+/**
+ *	sdio_readsb - read from a FIFO on a SDIO function
+ *	@func: SDIO function to access
+ *	@dst: buffer to store the data
+ *	@addr: address of (single byte) FIFO
+ *	@count: number of bytes to read
+ *
+ *	Reads from the specified FIFO of a given SDIO function. Return
+ *	value indicates if the transfer succeeded or not.
+ */
+int sdio_readsb(struct sdio_func *func, void *dst, unsigned int addr,
+	int count)
+{
+	return sdio_io_rw_ext_helper(func, 0, addr, 0, dst, count);
+}
+
+EXPORT_SYMBOL_GPL(sdio_readsb);
+
+/**
+ *	sdio_writesb - write to a FIFO of a SDIO function
+ *	@func: SDIO function to access
+ *	@addr: address of (single byte) FIFO
+ *	@src: buffer that contains the data to write
+ *	@count: number of bytes to write
+ *
+ *	Writes to the specified FIFO of a given SDIO function. Return
+ *	value indicates if the transfer succeeded or not.
+ */
+int sdio_writesb(struct sdio_func *func, unsigned int addr, void *src,
+	int count)
+{
+	return sdio_io_rw_ext_helper(func, 1, addr, 0, src, count);
+}
+EXPORT_SYMBOL_GPL(sdio_writesb);
+
+/**
+ *	sdio_readw - read a 16 bit integer from a SDIO function
+ *	@func: SDIO function to access
+ *	@addr: address to read
+ *	@err_ret: optional status value from transfer
+ *
+ *	Reads a 16 bit integer from the address space of a given SDIO
+ *	function. If there is a problem reading the address, 0xffff
+ *	is returned and @err_ret will contain the error code.
+ */
+unsigned short sdio_readw(struct sdio_func *func, unsigned int addr,
+	int *err_ret)
+{
+	int ret;
+
+	if (err_ret)
+		*err_ret = 0;
+
+	ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 2);
+	if (ret) {
+		if (err_ret)
+			*err_ret = ret;
+		return 0xFFFF;
+	}
+
+	return le16_to_cpu(*(u16*)func->tmpbuf);
+}
+EXPORT_SYMBOL_GPL(sdio_readw);
+
+/**
+ *	sdio_writew - write a 16 bit integer to a SDIO function
+ *	@func: SDIO function to access
+ *	@b: integer to write
+ *	@addr: address to write to
+ *	@err_ret: optional status value from transfer
+ *
+ *	Writes a 16 bit integer to the address space of a given SDIO
+ *	function. @err_ret will contain the status of the actual
+ *	transfer.
+ */
+void sdio_writew(struct sdio_func *func, unsigned short b, unsigned int addr,
+	int *err_ret)
+{
+	int ret;
+
+	*(u16*)func->tmpbuf = cpu_to_le16(b);
+
+	ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 2);
+	if (err_ret)
+		*err_ret = ret;
+}
+EXPORT_SYMBOL_GPL(sdio_writew);
+
+/**
+ *	sdio_readl - read a 32 bit integer from a SDIO function
+ *	@func: SDIO function to access
+ *	@addr: address to read
+ *	@err_ret: optional status value from transfer
+ *
+ *	Reads a 32 bit integer from the address space of a given SDIO
+ *	function. If there is a problem reading the address,
+ *	0xffffffff is returned and @err_ret will contain the error
+ *	code.
+ */
+unsigned long sdio_readl(struct sdio_func *func, unsigned int addr,
+	int *err_ret)
+{
+	int ret;
+
+	if (err_ret)
+		*err_ret = 0;
+
+	ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 4);
+	if (ret) {
+		if (err_ret)
+			*err_ret = ret;
+		return 0xFFFFFFFF;
+	}
+
+	return le32_to_cpu(*(u32*)func->tmpbuf);
+}
+EXPORT_SYMBOL_GPL(sdio_readl);
+
+/**
+ *	sdio_writel - write a 32 bit integer to a SDIO function
+ *	@func: SDIO function to access
+ *	@b: integer to write
+ *	@addr: address to write to
+ *	@err_ret: optional status value from transfer
+ *
+ *	Writes a 32 bit integer to the address space of a given SDIO
+ *	function. @err_ret will contain the status of the actual
+ *	transfer.
+ */
+void sdio_writel(struct sdio_func *func, unsigned long b, unsigned int addr,
+	int *err_ret)
+{
+	int ret;
+
+	*(u32*)func->tmpbuf = cpu_to_le32(b);
+
+	ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 4);
+	if (err_ret)
+		*err_ret = ret;
+}
+EXPORT_SYMBOL_GPL(sdio_writel);
+
+/**
+ *	sdio_f0_readb - read a single byte from SDIO function 0
+ *	@func: an SDIO function of the card
+ *	@addr: address to read
+ *	@err_ret: optional status value from transfer
+ *
+ *	Reads a single byte from the address space of SDIO function 0.
+ *	If there is a problem reading the address, 0xff is returned
+ *	and @err_ret will contain the error code.
+ */
+unsigned char sdio_f0_readb(struct sdio_func *func, unsigned int addr,
+	int *err_ret)
+{
+	int ret;
+	unsigned char val;
+
+	BUG_ON(!func);
+
+	if (err_ret)
+		*err_ret = 0;
+
+	ret = mmc_io_rw_direct(func->card, 0, 0, addr, 0, &val);
+	if (ret) {
+		if (err_ret)
+			*err_ret = ret;
+		return 0xFF;
+	}
+
+	return val;
+}
+EXPORT_SYMBOL_GPL(sdio_f0_readb);
+
+/**
+ *	sdio_f0_writeb - write a single byte to SDIO function 0
+ *	@func: an SDIO function of the card
+ *	@b: byte to write
+ *	@addr: address to write to
+ *	@err_ret: optional status value from transfer
+ *
+ *	Writes a single byte to the address space of SDIO function 0.
+ *	@err_ret will contain the status of the actual transfer.
+ *
+ *	Only writes to the vendor specific CCCR registers (0xF0 -
+ *	0xFF) are permiited; @err_ret will be set to -EINVAL for *
+ *	writes outside this range.
+ */
+void sdio_f0_writeb(struct sdio_func *func, unsigned char b, unsigned int addr,
+	int *err_ret)
+{
+	int ret;
+
+	BUG_ON(!func);
+
+	if (addr < 0xF0 || addr > 0xFF) {
+		if (err_ret)
+			*err_ret = -EINVAL;
+		return;
+	}
+
+	ret = mmc_io_rw_direct(func->card, 1, 0, addr, b, NULL);
+	if (err_ret)
+		*err_ret = ret;
+}
+EXPORT_SYMBOL_GPL(sdio_f0_writeb);
diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
new file mode 100644
index 0000000..3bd3021
--- /dev/null
+++ b/drivers/mmc/core/sdio_irq.c
@@ -0,0 +1,267 @@
+/*
+ * linux/drivers/mmc/core/sdio_irq.c
+ *
+ * Author:      Nicolas Pitre
+ * Created:     June 18, 2007
+ * 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 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/sched.h>
+#include <linux/kthread.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+
+#include <linux/mmc/core.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sdio_func.h>
+
+#include "sdio_ops.h"
+
+static int process_sdio_pending_irqs(struct mmc_card *card)
+{
+	int i, ret, count;
+	unsigned char pending;
+
+	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending);
+	if (ret) {
+		printk(KERN_DEBUG "%s: error %d reading SDIO_CCCR_INTx\n",
+		       mmc_card_id(card), ret);
+		return ret;
+	}
+
+	count = 0;
+	for (i = 1; i <= 7; i++) {
+		if (pending & (1 << i)) {
+			struct sdio_func *func = card->sdio_func[i - 1];
+			if (!func) {
+				printk(KERN_WARNING "%s: pending IRQ for "
+					"non-existant function\n",
+					mmc_card_id(card));
+				ret = -EINVAL;
+			} else if (func->irq_handler) {
+				func->irq_handler(func);
+				count++;
+			} else {
+				printk(KERN_WARNING "%s: pending IRQ with no handler\n",
+				       sdio_func_id(func));
+				ret = -EINVAL;
+			}
+		}
+	}
+
+	if (count)
+		return count;
+
+	return ret;
+}
+
+static int sdio_irq_thread(void *_host)
+{
+	struct mmc_host *host = _host;
+	struct sched_param param = { .sched_priority = 1 };
+	unsigned long period, idle_period;
+	int ret;
+
+	sched_setscheduler(current, SCHED_FIFO, &param);
+
+	/*
+	 * We want to allow for SDIO cards to work even on non SDIO
+	 * aware hosts.  One thing that non SDIO host cannot do is
+	 * asynchronous notification of pending SDIO card interrupts
+	 * hence we poll for them in that case.
+	 */
+	idle_period = msecs_to_jiffies(10);
+	period = (host->caps & MMC_CAP_SDIO_IRQ) ?
+		MAX_SCHEDULE_TIMEOUT : idle_period;
+
+	pr_debug("%s: IRQ thread started (poll period = %lu jiffies)\n",
+		 mmc_hostname(host), period);
+
+	do {
+		/*
+		 * We claim the host here on drivers behalf for a couple
+		 * reasons:
+		 *
+		 * 1) it is already needed to retrieve the CCCR_INTx;
+		 * 2) we want the driver(s) to clear the IRQ condition ASAP;
+		 * 3) we need to control the abort condition locally.
+		 *
+		 * Just like traditional hard IRQ handlers, we expect SDIO
+		 * IRQ handlers to be quick and to the point, so that the
+		 * holding of the host lock does not cover too much work
+		 * that doesn't require that lock to be held.
+		 */
+		ret = __mmc_claim_host(host, &host->sdio_irq_thread_abort);
+		if (ret)
+			break;
+		ret = process_sdio_pending_irqs(host->card);
+		mmc_release_host(host);
+
+		/*
+		 * Give other threads a chance to run in the presence of
+		 * errors.  FIXME: determine if due to card removal and
+		 * possibly exit this thread if so.
+		 */
+		if (ret < 0)
+			ssleep(1);
+
+		/*
+		 * Adaptive polling frequency based on the assumption
+		 * that an interrupt will be closely followed by more.
+		 * This has a substantial benefit for network devices.
+		 */
+		if (!(host->caps & MMC_CAP_SDIO_IRQ)) {
+			if (ret > 0)
+				period /= 2;
+			else {
+				period++;
+				if (period > idle_period)
+					period = idle_period;
+			}
+		}
+
+		set_task_state(current, TASK_INTERRUPTIBLE);
+		if (host->caps & MMC_CAP_SDIO_IRQ)
+			host->ops->enable_sdio_irq(host, 1);
+		if (!kthread_should_stop())
+			schedule_timeout(period);
+		set_task_state(current, TASK_RUNNING);
+	} while (!kthread_should_stop());
+
+	if (host->caps & MMC_CAP_SDIO_IRQ)
+		host->ops->enable_sdio_irq(host, 0);
+
+	pr_debug("%s: IRQ thread exiting with code %d\n",
+		 mmc_hostname(host), ret);
+
+	return ret;
+}
+
+static int sdio_card_irq_get(struct mmc_card *card)
+{
+	struct mmc_host *host = card->host;
+
+	WARN_ON(!host->claimed);
+
+	if (!host->sdio_irqs++) {
+		atomic_set(&host->sdio_irq_thread_abort, 0);
+		host->sdio_irq_thread =
+			kthread_run(sdio_irq_thread, host, "ksdiorqd");
+		if (IS_ERR(host->sdio_irq_thread)) {
+			int err = PTR_ERR(host->sdio_irq_thread);
+			host->sdio_irqs--;
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static int sdio_card_irq_put(struct mmc_card *card)
+{
+	struct mmc_host *host = card->host;
+
+	WARN_ON(!host->claimed);
+	BUG_ON(host->sdio_irqs < 1);
+
+	if (!--host->sdio_irqs) {
+		atomic_set(&host->sdio_irq_thread_abort, 1);
+		kthread_stop(host->sdio_irq_thread);
+	}
+
+	return 0;
+}
+
+/**
+ *	sdio_claim_irq - claim the IRQ for a SDIO function
+ *	@func: SDIO function
+ *	@handler: IRQ handler callback
+ *
+ *	Claim and activate the IRQ for the given SDIO function. The provided
+ *	handler will be called when that IRQ is asserted.  The host is always
+ *	claimed already when the handler is called so the handler must not
+ *	call sdio_claim_host() nor sdio_release_host().
+ */
+int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler)
+{
+	int ret;
+	unsigned char reg;
+
+	BUG_ON(!func);
+	BUG_ON(!func->card);
+
+	pr_debug("SDIO: Enabling IRQ for %s...\n", sdio_func_id(func));
+
+	if (func->irq_handler) {
+		pr_debug("SDIO: IRQ for %s already in use.\n", sdio_func_id(func));
+		return -EBUSY;
+	}
+
+	ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, &reg);
+	if (ret)
+		return ret;
+
+	reg |= 1 << func->num;
+
+	reg |= 1; /* Master interrupt enable */
+
+	ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, reg, NULL);
+	if (ret)
+		return ret;
+
+	func->irq_handler = handler;
+	ret = sdio_card_irq_get(func->card);
+	if (ret)
+		func->irq_handler = NULL;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(sdio_claim_irq);
+
+/**
+ *	sdio_release_irq - release the IRQ for a SDIO function
+ *	@func: SDIO function
+ *
+ *	Disable and release the IRQ for the given SDIO function.
+ */
+int sdio_release_irq(struct sdio_func *func)
+{
+	int ret;
+	unsigned char reg;
+
+	BUG_ON(!func);
+	BUG_ON(!func->card);
+
+	pr_debug("SDIO: Disabling IRQ for %s...\n", sdio_func_id(func));
+
+	if (func->irq_handler) {
+		func->irq_handler = NULL;
+		sdio_card_irq_put(func->card);
+	}
+
+	ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, &reg);
+	if (ret)
+		return ret;
+
+	reg &= ~(1 << func->num);
+
+	/* Disable master interrupt with the last function interrupt */
+	if (!(reg & 0xFE))
+		reg = 0;
+
+	ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, reg, NULL);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(sdio_release_irq);
+
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c
new file mode 100644
index 0000000..4d289b2
--- /dev/null
+++ b/drivers/mmc/core/sdio_ops.c
@@ -0,0 +1,176 @@
+/*
+ *  linux/drivers/mmc/sdio_ops.c
+ *
+ *  Copyright 2006-2007 Pierre Ossman
+ *
+ * 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 <asm/scatterlist.h>
+#include <linux/scatterlist.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sdio.h>
+
+#include "core.h"
+
+int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
+{
+	struct mmc_command cmd;
+	int i, err = 0;
+
+	BUG_ON(!host);
+
+	memset(&cmd, 0, sizeof(struct mmc_command));
+
+	cmd.opcode = SD_IO_SEND_OP_COND;
+	cmd.arg = ocr;
+	cmd.flags = MMC_RSP_SPI_R4 | MMC_RSP_R4 | MMC_CMD_BCR;
+
+	for (i = 100; i; i--) {
+		err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
+		if (err)
+			break;
+
+		/* if we're just probing, do a single pass */
+		if (ocr == 0)
+			break;
+
+		/* otherwise wait until reset completes */
+		if (mmc_host_is_spi(host)) {
+			/*
+			 * Both R1_SPI_IDLE and MMC_CARD_BUSY indicate
+			 * an initialized card under SPI, but some cards
+			 * (Marvell's) only behave when looking at this
+			 * one.
+			 */
+			if (cmd.resp[1] & MMC_CARD_BUSY)
+				break;
+		} else {
+			if (cmd.resp[0] & MMC_CARD_BUSY)
+				break;
+		}
+
+		err = -ETIMEDOUT;
+
+		mmc_delay(10);
+	}
+
+	if (rocr)
+		*rocr = cmd.resp[mmc_host_is_spi(host) ? 1 : 0];
+
+	return err;
+}
+
+int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
+	unsigned addr, u8 in, u8* out)
+{
+	struct mmc_command cmd;
+	int err;
+
+	BUG_ON(!card);
+	BUG_ON(fn > 7);
+
+	memset(&cmd, 0, sizeof(struct mmc_command));
+
+	cmd.opcode = SD_IO_RW_DIRECT;
+	cmd.arg = write ? 0x80000000 : 0x00000000;
+	cmd.arg |= fn << 28;
+	cmd.arg |= (write && out) ? 0x08000000 : 0x00000000;
+	cmd.arg |= addr << 9;
+	cmd.arg |= in;
+	cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC;
+
+	err = mmc_wait_for_cmd(card->host, &cmd, 0);
+	if (err)
+		return err;
+
+	if (mmc_host_is_spi(card->host)) {
+		/* host driver already reported errors */
+	} else {
+		if (cmd.resp[0] & R5_ERROR)
+			return -EIO;
+		if (cmd.resp[0] & R5_FUNCTION_NUMBER)
+			return -EINVAL;
+		if (cmd.resp[0] & R5_OUT_OF_RANGE)
+			return -ERANGE;
+	}
+
+	if (out) {
+		if (mmc_host_is_spi(card->host))
+			*out = (cmd.resp[0] >> 8) & 0xFF;
+		else
+			*out = cmd.resp[0] & 0xFF;
+	}
+
+	return 0;
+}
+
+int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
+	unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz)
+{
+	struct mmc_request mrq;
+	struct mmc_command cmd;
+	struct mmc_data data;
+	struct scatterlist sg;
+
+	BUG_ON(!card);
+	BUG_ON(fn > 7);
+	BUG_ON(blocks == 1 && blksz > 512);
+	WARN_ON(blocks == 0);
+	WARN_ON(blksz == 0);
+
+	memset(&mrq, 0, sizeof(struct mmc_request));
+	memset(&cmd, 0, sizeof(struct mmc_command));
+	memset(&data, 0, sizeof(struct mmc_data));
+
+	mrq.cmd = &cmd;
+	mrq.data = &data;
+
+	cmd.opcode = SD_IO_RW_EXTENDED;
+	cmd.arg = write ? 0x80000000 : 0x00000000;
+	cmd.arg |= fn << 28;
+	cmd.arg |= incr_addr ? 0x04000000 : 0x00000000;
+	cmd.arg |= addr << 9;
+	if (blocks == 1 && blksz <= 512)
+		cmd.arg |= (blksz == 512) ? 0 : blksz;	/* byte mode */
+	else
+		cmd.arg |= 0x08000000 | blocks;		/* block mode */
+	cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
+
+	data.blksz = blksz;
+	data.blocks = blocks;
+	data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
+	data.sg = &sg;
+	data.sg_len = 1;
+
+	sg_init_one(&sg, buf, blksz * blocks);
+
+	mmc_set_data_timeout(&data, card);
+
+	mmc_wait_for_req(card->host, &mrq);
+
+	if (cmd.error)
+		return cmd.error;
+	if (data.error)
+		return data.error;
+
+	if (mmc_host_is_spi(card->host)) {
+		/* host driver already reported errors */
+	} else {
+		if (cmd.resp[0] & R5_ERROR)
+			return -EIO;
+		if (cmd.resp[0] & R5_FUNCTION_NUMBER)
+			return -EINVAL;
+		if (cmd.resp[0] & R5_OUT_OF_RANGE)
+			return -ERANGE;
+	}
+
+	return 0;
+}
+
diff --git a/drivers/mmc/core/sdio_ops.h b/drivers/mmc/core/sdio_ops.h
new file mode 100644
index 0000000..e2e74b0
--- /dev/null
+++ b/drivers/mmc/core/sdio_ops.h
@@ -0,0 +1,22 @@
+/*
+ *  linux/drivers/mmc/sdio_ops.c
+ *
+ *  Copyright 2006-2007 Pierre Ossman
+ *
+ * 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.
+ */
+
+#ifndef _MMC_SDIO_OPS_H
+#define _MMC_SDIO_OPS_H
+
+int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr);
+int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
+	unsigned addr, u8 in, u8* out);
+int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
+	unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz);
+
+#endif
+
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index e23082f..5fef678 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -35,6 +35,23 @@
 
 	  If unsure, say N.
 
+config MMC_RICOH_MMC
+	tristate "Ricoh MMC Controller Disabler  (EXPERIMENTAL)"
+	depends on PCI && EXPERIMENTAL && MMC_SDHCI
+	help
+	  This selects the disabler for the Ricoh MMC Controller. This
+	  proprietary controller is unnecessary because the SDHCI driver
+	  supports MMC cards on the SD controller, but if it is not
+	  disabled, it will steal the MMC cards away - rendering them
+	  useless. It is safe to select this driver even if you don't
+	  have a Ricoh based card reader.
+
+
+	  To compile this driver as a module, choose M here:
+	  the module will be called ricoh_mmc.
+
+	  If unsure, say Y.
+
 config MMC_OMAP
 	tristate "TI OMAP Multimedia Card Interface support"
 	depends on ARCH_OMAP
@@ -100,3 +117,16 @@
           To compile this driver as a module, choose M here: the
 	  module will be called tifm_sd.
 
+config MMC_SPI
+	tristate "MMC/SD over SPI (EXPERIMENTAL)"
+	depends on MMC && SPI_MASTER && !HIGHMEM && EXPERIMENTAL
+	select CRC7
+	select CRC_ITU_T
+	help
+	  Some systems accss MMC/SD cards using a SPI controller instead of
+	  using a "native" MMC/SD controller.  This has a disadvantage of
+	  being relatively high overhead, but a compensating advantage of
+	  working on many systems without dedicated MMC/SD controllers.
+
+	  If unsure, or if your system has no SPI master driver, say N.
+
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 6685f64..3877c87 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -10,9 +10,11 @@
 obj-$(CONFIG_MMC_PXA)		+= pxamci.o
 obj-$(CONFIG_MMC_IMX)		+= imxmmc.o
 obj-$(CONFIG_MMC_SDHCI)		+= sdhci.o
+obj-$(CONFIG_MMC_RICOH_MMC)	+= ricoh_mmc.o
 obj-$(CONFIG_MMC_WBSD)		+= wbsd.o
 obj-$(CONFIG_MMC_AU1X)		+= au1xmmc.o
 obj-$(CONFIG_MMC_OMAP)		+= omap.o
 obj-$(CONFIG_MMC_AT91)		+= at91_mci.o
 obj-$(CONFIG_MMC_TIFM_SD)	+= tifm_sd.o
+obj-$(CONFIG_MMC_SPI)		+= mmc_spi.o
 
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index 955ea60..6ba98a4 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -328,7 +328,7 @@
 	data = cmd->data;
 	if (!data) return;
 
-	if (cmd->data->flags & MMC_DATA_MULTI) {
+	if (cmd->data->blocks > 1) {
 		pr_debug("multiple write : wait for BLKE...\n");
 		at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE);
 	} else
@@ -428,6 +428,14 @@
 	}
 
 	if (data) {
+
+		if ( data->blksz & 0x3 ) {
+			pr_debug("Unsupported block size\n");
+			cmd->error = -EINVAL;
+			mmc_request_done(host->mmc, host->request);
+			return;
+		}
+
 		block_length = data->blksz;
 		blocks = data->blocks;
 
@@ -439,7 +447,7 @@
 
 		if (data->flags & MMC_DATA_STREAM)
 			cmdr |= AT91_MCI_TRTYP_STREAM;
-		if (data->flags & MMC_DATA_MULTI)
+		if (data->blocks > 1)
 			cmdr |= AT91_MCI_TRTYP_MULTIPLE;
 	}
 	else {
@@ -577,24 +585,22 @@
 			AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE |
 			AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)) {
 		if ((status & AT91_MCI_RCRCE) && !(mmc_resp_type(cmd) & MMC_RSP_CRC)) {
-			cmd->error = MMC_ERR_NONE;
+			cmd->error = 0;
 		}
 		else {
 			if (status & (AT91_MCI_RTOE | AT91_MCI_DTOE))
-				cmd->error = MMC_ERR_TIMEOUT;
+				cmd->error = -ETIMEDOUT;
 			else if (status & (AT91_MCI_RCRCE | AT91_MCI_DCRCE))
-				cmd->error = MMC_ERR_BADCRC;
-			else if (status & (AT91_MCI_OVRE | AT91_MCI_UNRE))
-				cmd->error = MMC_ERR_FIFO;
+				cmd->error = -EILSEQ;
 			else
-				cmd->error = MMC_ERR_FAILED;
+				cmd->error = -EIO;
 
 			pr_debug("Error detected and set to %d (cmd = %d, retries = %d)\n",
 				 cmd->error, cmd->opcode, cmd->retries);
 		}
 	}
 	else
-		cmd->error = MMC_ERR_NONE;
+		cmd->error = 0;
 
 	at91_mci_process_next(host);
 }
@@ -836,7 +842,6 @@
 	mmc->f_min = 375000;
 	mmc->f_max = 25000000;
 	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
-	mmc->caps = MMC_CAP_BYTEBLOCK;
 
 	mmc->max_blk_size = 4095;
 	mmc->max_blk_count = mmc->max_req_size;
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index 34c99d4..92c4d0d 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -186,7 +186,7 @@
 }
 
 static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
-				struct mmc_command *cmd, unsigned int flags)
+				struct mmc_command *cmd, struct mmc_data *data)
 {
 	u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT);
 
@@ -208,19 +208,21 @@
 	default:
 		printk(KERN_INFO "au1xmmc: unhandled response type %02x\n",
 			mmc_resp_type(cmd));
-		return MMC_ERR_INVALID;
+		return -EINVAL;
 	}
 
-	if (flags & MMC_DATA_READ) {
-		if (flags & MMC_DATA_MULTI)
-			mmccmd |= SD_CMD_CT_4;
-		else
-			mmccmd |= SD_CMD_CT_2;
-	} else if (flags & MMC_DATA_WRITE) {
-		if (flags & MMC_DATA_MULTI)
-			mmccmd |= SD_CMD_CT_3;
-		else
-			mmccmd |= SD_CMD_CT_1;
+	if (data) {
+		if (flags & MMC_DATA_READ) {
+			if (data->blocks > 1)
+				mmccmd |= SD_CMD_CT_4;
+			else
+				mmccmd |= SD_CMD_CT_2;
+		} else if (flags & MMC_DATA_WRITE) {
+			if (data->blocks > 1)
+				mmccmd |= SD_CMD_CT_3;
+			else
+				mmccmd |= SD_CMD_CT_1;
+		}
 	}
 
 	au_writel(cmd->arg, HOST_CMDARG(host));
@@ -253,7 +255,7 @@
 		IRQ_ON(host, SD_CONFIG_CR);
 	}
 
-	return MMC_ERR_NONE;
+	return 0;
 }
 
 static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status)
@@ -278,7 +280,7 @@
 	while((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB))
 		status = au_readl(HOST_STATUS(host));
 
-	data->error = MMC_ERR_NONE;
+	data->error = 0;
 	dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma.dir);
 
         /* Process any errors */
@@ -288,14 +290,14 @@
 		crc |= ((status & 0x07) == 0x02) ? 0 : 1;
 
 	if (crc)
-		data->error = MMC_ERR_BADCRC;
+		data->error = -EILSEQ;
 
 	/* Clear the CRC bits */
 	au_writel(SD_STATUS_WC | SD_STATUS_RC, HOST_STATUS(host));
 
 	data->bytes_xfered = 0;
 
-	if (data->error == MMC_ERR_NONE) {
+	if (!data->error) {
 		if (host->flags & HOST_F_DMA) {
 			u32 chan = DMA_CHANNEL(host);
 
@@ -475,7 +477,7 @@
 		return;
 
 	cmd = mrq->cmd;
-	cmd->error = MMC_ERR_NONE;
+	cmd->error = 0;
 
 	if (cmd->flags & MMC_RSP_PRESENT) {
 		if (cmd->flags & MMC_RSP_136) {
@@ -512,11 +514,11 @@
         /* Figure out errors */
 
 	if (status & (SD_STATUS_SC | SD_STATUS_WC | SD_STATUS_RC))
-		cmd->error = MMC_ERR_BADCRC;
+		cmd->error = -EILSEQ;
 
 	trans = host->flags & (HOST_F_XMIT | HOST_F_RECV);
 
-	if (!trans || cmd->error != MMC_ERR_NONE) {
+	if (!trans || cmd->error) {
 
 		IRQ_OFF(host, SD_CONFIG_TH | SD_CONFIG_RA|SD_CONFIG_RF);
 		tasklet_schedule(&host->finish_task);
@@ -589,7 +591,7 @@
 				   data->sg_len, host->dma.dir);
 
 	if (host->dma.len == 0)
-		return MMC_ERR_TIMEOUT;
+		return -ETIMEDOUT;
 
 	au_writel(data->blksz - 1, HOST_BLKSIZE(host));
 
@@ -640,11 +642,11 @@
 			//IRQ_ON(host, SD_CONFIG_RA|SD_CONFIG_RF);
 	}
 
-	return MMC_ERR_NONE;
+	return 0;
 
  dataerr:
 	dma_unmap_sg(mmc_dev(host->mmc),data->sg,data->sg_len,host->dma.dir);
-	return MMC_ERR_TIMEOUT;
+	return -ETIMEDOUT;
 }
 
 /* static void au1xmmc_request
@@ -656,7 +658,7 @@
 
 	struct au1xmmc_host *host = mmc_priv(mmc);
 	unsigned int flags = 0;
-	int ret = MMC_ERR_NONE;
+	int ret = 0;
 
 	WARN_ON(irqs_disabled());
 	WARN_ON(host->status != HOST_S_IDLE);
@@ -672,10 +674,10 @@
 		ret = au1xmmc_prepare_data(host, mrq->data);
 	}
 
-	if (ret == MMC_ERR_NONE)
-		ret = au1xmmc_send_command(host, 0, mrq->cmd, flags);
+	if (!ret)
+		ret = au1xmmc_send_command(host, 0, mrq->cmd, mrq->data);
 
-	if (ret != MMC_ERR_NONE) {
+	if (ret) {
 		mrq->cmd->error = ret;
 		au1xmmc_finish_request(host);
 	}
@@ -764,10 +766,10 @@
 
 		if (host->mrq && (status & STATUS_TIMEOUT)) {
 			if (status & SD_STATUS_RAT)
-				host->mrq->cmd->error = MMC_ERR_TIMEOUT;
+				host->mrq->cmd->error = -ETIMEDOUT;
 
 			else if (status & SD_STATUS_DT)
-				host->mrq->data->error = MMC_ERR_TIMEOUT;
+				host->mrq->data->error = -ETIMEDOUT;
 
 			/* In PIO mode, interrupts might still be enabled */
 			IRQ_OFF(host, SD_CONFIG_NE | SD_CONFIG_TH);
diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c
index 54bfc9f..6ebc41e 100644
--- a/drivers/mmc/host/imxmmc.c
+++ b/drivers/mmc/host/imxmmc.c
@@ -428,11 +428,11 @@
 	if ( stat & STATUS_ERR_MASK ) {
 		dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",stat);
 		if(stat & (STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR))
-			data->error = MMC_ERR_BADCRC;
+			data->error = -EILSEQ;
 		else if(stat & STATUS_TIME_OUT_READ)
-			data->error = MMC_ERR_TIMEOUT;
+			data->error = -ETIMEDOUT;
 		else
-			data->error = MMC_ERR_FAILED;
+			data->error = -EIO;
 	} else {
 		data->bytes_xfered = host->dma_size;
 	}
@@ -458,10 +458,10 @@
 
 	if (stat & STATUS_TIME_OUT_RESP) {
 		dev_dbg(mmc_dev(host->mmc), "CMD TIMEOUT\n");
-		cmd->error = MMC_ERR_TIMEOUT;
+		cmd->error = -ETIMEDOUT;
 	} else if (stat & STATUS_RESP_CRC_ERR && cmd->flags & MMC_RSP_CRC) {
 		dev_dbg(mmc_dev(host->mmc), "cmd crc error\n");
-		cmd->error = MMC_ERR_BADCRC;
+		cmd->error = -EILSEQ;
 	}
 
 	if(cmd->flags & MMC_RSP_PRESENT) {
@@ -482,7 +482,7 @@
 	dev_dbg(mmc_dev(host->mmc), "RESP 0x%08x, 0x%08x, 0x%08x, 0x%08x, error %d\n",
 		cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3], cmd->error);
 
-	if (data && (cmd->error == MMC_ERR_NONE) && !(stat & STATUS_ERR_MASK)) {
+	if (data && !cmd->error && !(stat & STATUS_ERR_MASK)) {
 		if (host->req->data->flags & MMC_DATA_WRITE) {
 
 			/* Wait for FIFO to be empty before starting DMA write */
@@ -491,7 +491,7 @@
 			if(imxmci_busy_wait_for_status(host, &stat,
 				STATUS_APPL_BUFF_FE,
 				40, "imxmci_cmd_done DMA WR") < 0) {
-				cmd->error = MMC_ERR_FIFO;
+				cmd->error = -EIO;
 				imxmci_finish_data(host, stat);
 				if(host->req)
 					imxmci_finish_request(host, host->req);
@@ -884,9 +884,21 @@
 	}
 }
 
+static int imxmci_get_ro(struct mmc_host *mmc)
+{
+	struct imxmci_host *host = mmc_priv(mmc);
+
+	if (host->pdata && host->pdata->get_ro)
+		return host->pdata->get_ro(mmc_dev(mmc));
+	/* Host doesn't support read only detection so assume writeable */
+	return 0;
+}
+
+
 static const struct mmc_host_ops imxmci_ops = {
 	.request	= imxmci_request,
 	.set_ios	= imxmci_set_ios,
+	.get_ro		= imxmci_get_ro,
 };
 
 static struct resource *platform_device_resource(struct platform_device *dev, unsigned int mask, int nr)
@@ -913,7 +925,7 @@
 {
 	struct imxmci_host *host = (struct imxmci_host *)data;
 
-	if( host->pdata->card_present() != host->present ) {
+	if( host->pdata->card_present(mmc_dev(host->mmc)) != host->present ) {
 		host->present ^= 1;
 		dev_info(mmc_dev(host->mmc), "card %s\n",
 		      host->present ? "inserted" : "removed");
@@ -963,7 +975,7 @@
 	mmc->f_min = 150000;
 	mmc->f_max = CLK_RATE/2;
 	mmc->ocr_avail = MMC_VDD_32_33;
-	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_BYTEBLOCK;
+	mmc->caps = MMC_CAP_4_BIT_DATA;
 
 	/* MMC core transfer sizes tunable parameters */
 	mmc->max_hw_segs = 64;
@@ -1022,7 +1034,7 @@
 	if (ret)
 		goto out;
 
-	host->present = host->pdata->card_present();
+	host->present = host->pdata->card_present(mmc_dev(mmc));
 	init_timer(&host->timer);
 	host->timer.data = (unsigned long)host;
 	host->timer.function = imxmci_check_status;
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
new file mode 100644
index 0000000..f30327b
--- /dev/null
+++ b/drivers/mmc/host/mmc_spi.c
@@ -0,0 +1,1408 @@
+/*
+ * mmc_spi.c - Access SD/MMC cards through SPI master controllers
+ *
+ * (C) Copyright 2005, Intec Automation,
+ *		Mike Lavender (mike@steroidmicros)
+ * (C) Copyright 2006-2007, David Brownell
+ * (C) Copyright 2007, Axis Communications,
+ *		Hans-Peter Nilsson (hp@axis.com)
+ * (C) Copyright 2007, ATRON electronic GmbH,
+ *		Jan Nikitenko <jan.nikitenko@gmail.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
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/hrtimer.h>
+#include <linux/delay.h>
+#include <linux/blkdev.h>
+#include <linux/dma-mapping.h>
+#include <linux/crc7.h>
+#include <linux/crc-itu-t.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>		/* for R1_SPI_* bit values */
+
+#include <linux/spi/spi.h>
+#include <linux/spi/mmc_spi.h>
+
+#include <asm/unaligned.h>
+
+
+/* NOTES:
+ *
+ * - For now, we won't try to interoperate with a real mmc/sd/sdio
+ *   controller, although some of them do have hardware support for
+ *   SPI protocol.  The main reason for such configs would be mmc-ish
+ *   cards like DataFlash, which don't support that "native" protocol.
+ *
+ *   We don't have a "DataFlash/MMC/SD/SDIO card slot" abstraction to
+ *   switch between driver stacks, and in any case if "native" mode
+ *   is available, it will be faster and hence preferable.
+ *
+ * - MMC depends on a different chipselect management policy than the
+ *   SPI interface currently supports for shared bus segments:  it needs
+ *   to issue multiple spi_message requests with the chipselect active,
+ *   using the results of one message to decide the next one to issue.
+ *
+ *   Pending updates to the programming interface, this driver expects
+ *   that it not share the bus with other drivers (precluding conflicts).
+ *
+ * - We tell the controller to keep the chipselect active from the
+ *   beginning of an mmc_host_ops.request until the end.  So beware
+ *   of SPI controller drivers that mis-handle the cs_change flag!
+ *
+ *   However, many cards seem OK with chipselect flapping up/down
+ *   during that time ... at least on unshared bus segments.
+ */
+
+
+/*
+ * Local protocol constants, internal to data block protocols.
+ */
+
+/* Response tokens used to ack each block written: */
+#define SPI_MMC_RESPONSE_CODE(x)	((x) & 0x1f)
+#define SPI_RESPONSE_ACCEPTED		((2 << 1)|1)
+#define SPI_RESPONSE_CRC_ERR		((5 << 1)|1)
+#define SPI_RESPONSE_WRITE_ERR		((6 << 1)|1)
+
+/* Read and write blocks start with these tokens and end with crc;
+ * on error, read tokens act like a subset of R2_SPI_* values.
+ */
+#define SPI_TOKEN_SINGLE	0xfe	/* single block r/w, multiblock read */
+#define SPI_TOKEN_MULTI_WRITE	0xfc	/* multiblock write */
+#define SPI_TOKEN_STOP_TRAN	0xfd	/* terminate multiblock write */
+
+#define MMC_SPI_BLOCKSIZE	512
+
+
+/* These fixed timeouts come from the latest SD specs, which say to ignore
+ * the CSD values.  The R1B value is for card erase (e.g. the "I forgot the
+ * card's password" scenario); it's mostly applied to STOP_TRANSMISSION after
+ * reads which takes nowhere near that long.  Older cards may be able to use
+ * shorter timeouts ... but why bother?
+ */
+#define readblock_timeout	ktime_set(0, 100 * 1000 * 1000)
+#define writeblock_timeout	ktime_set(0, 250 * 1000 * 1000)
+#define r1b_timeout		ktime_set(3, 0)
+
+
+/****************************************************************************/
+
+/*
+ * Local Data Structures
+ */
+
+/* "scratch" is per-{command,block} data exchanged with the card */
+struct scratch {
+	u8			status[29];
+	u8			data_token;
+	__be16			crc_val;
+};
+
+struct mmc_spi_host {
+	struct mmc_host		*mmc;
+	struct spi_device	*spi;
+
+	unsigned char		power_mode;
+	u16			powerup_msecs;
+
+	struct mmc_spi_platform_data	*pdata;
+
+	/* for bulk data transfers */
+	struct spi_transfer	token, t, crc, early_status;
+	struct spi_message	m;
+
+	/* for status readback */
+	struct spi_transfer	status;
+	struct spi_message	readback;
+
+	/* underlying DMA-aware controller, or null */
+	struct device		*dma_dev;
+
+	/* buffer used for commands and for message "overhead" */
+	struct scratch		*data;
+	dma_addr_t		data_dma;
+
+	/* Specs say to write ones most of the time, even when the card
+	 * has no need to read its input data; and many cards won't care.
+	 * This is our source of those ones.
+	 */
+	void			*ones;
+	dma_addr_t		ones_dma;
+};
+
+
+/****************************************************************************/
+
+/*
+ * MMC-over-SPI protocol glue, used by the MMC stack interface
+ */
+
+static inline int mmc_cs_off(struct mmc_spi_host *host)
+{
+	/* chipselect will always be inactive after setup() */
+	return spi_setup(host->spi);
+}
+
+static int
+mmc_spi_readbytes(struct mmc_spi_host *host, unsigned len)
+{
+	int status;
+
+	if (len > sizeof(*host->data)) {
+		WARN_ON(1);
+		return -EIO;
+	}
+
+	host->status.len = len;
+
+	if (host->dma_dev)
+		dma_sync_single_for_device(host->dma_dev,
+				host->data_dma, sizeof(*host->data),
+				DMA_FROM_DEVICE);
+
+	status = spi_sync(host->spi, &host->readback);
+	if (status == 0)
+		status = host->readback.status;
+
+	if (host->dma_dev)
+		dma_sync_single_for_cpu(host->dma_dev,
+				host->data_dma, sizeof(*host->data),
+				DMA_FROM_DEVICE);
+
+	return status;
+}
+
+static int
+mmc_spi_skip(struct mmc_spi_host *host, ktime_t timeout, unsigned n, u8 byte)
+{
+	u8		*cp = host->data->status;
+
+	timeout = ktime_add(timeout, ktime_get());
+
+	while (1) {
+		int		status;
+		unsigned	i;
+
+		status = mmc_spi_readbytes(host, n);
+		if (status < 0)
+			return status;
+
+		for (i = 0; i < n; i++) {
+			if (cp[i] != byte)
+				return cp[i];
+		}
+
+		/* REVISIT investigate msleep() to avoid busy-wait I/O
+		 * in at least some cases.
+		 */
+		if (ktime_to_ns(ktime_sub(ktime_get(), timeout)) > 0)
+			break;
+	}
+	return -ETIMEDOUT;
+}
+
+static inline int
+mmc_spi_wait_unbusy(struct mmc_spi_host *host, ktime_t timeout)
+{
+	return mmc_spi_skip(host, timeout, sizeof(host->data->status), 0);
+}
+
+static int mmc_spi_readtoken(struct mmc_spi_host *host)
+{
+	return mmc_spi_skip(host, readblock_timeout, 1, 0xff);
+}
+
+
+/*
+ * Note that for SPI, cmd->resp[0] is not the same data as "native" protocol
+ * hosts return!  The low byte holds R1_SPI bits.  The next byte may hold
+ * R2_SPI bits ... for SEND_STATUS, or after data read errors.
+ *
+ * cmd->resp[1] holds any four-byte response, for R3 (READ_OCR) and on
+ * newer cards R7 (IF_COND).
+ */
+
+static char *maptype(struct mmc_command *cmd)
+{
+	switch (mmc_spi_resp_type(cmd)) {
+	case MMC_RSP_SPI_R1:	return "R1";
+	case MMC_RSP_SPI_R1B:	return "R1B";
+	case MMC_RSP_SPI_R2:	return "R2/R5";
+	case MMC_RSP_SPI_R3:	return "R3/R4/R7";
+	default:		return "?";
+	}
+}
+
+/* return zero, else negative errno after setting cmd->error */
+static int mmc_spi_response_get(struct mmc_spi_host *host,
+		struct mmc_command *cmd, int cs_on)
+{
+	u8	*cp = host->data->status;
+	u8	*end = cp + host->t.len;
+	int	value = 0;
+	char	tag[32];
+
+	snprintf(tag, sizeof(tag), "  ... CMD%d response SPI_%s",
+		cmd->opcode, maptype(cmd));
+
+	/* Except for data block reads, the whole response will already
+	 * be stored in the scratch buffer.  It's somewhere after the
+	 * command and the first byte we read after it.  We ignore that
+	 * first byte.  After STOP_TRANSMISSION command it may include
+	 * two data bits, but otherwise it's all ones.
+	 */
+	cp += 8;
+	while (cp < end && *cp == 0xff)
+		cp++;
+
+	/* Data block reads (R1 response types) may need more data... */
+	if (cp == end) {
+		unsigned	i;
+
+		cp = host->data->status;
+
+		/* Card sends N(CR) (== 1..8) bytes of all-ones then one
+		 * status byte ... and we already scanned 2 bytes.
+		 *
+		 * REVISIT block read paths use nasty byte-at-a-time I/O
+		 * so it can always DMA directly into the target buffer.
+		 * It'd probably be better to memcpy() the first chunk and
+		 * avoid extra i/o calls...
+		 */
+		for (i = 2; i < 9; i++) {
+			value = mmc_spi_readbytes(host, 1);
+			if (value < 0)
+				goto done;
+			if (*cp != 0xff)
+				goto checkstatus;
+		}
+		value = -ETIMEDOUT;
+		goto done;
+	}
+
+checkstatus:
+	if (*cp & 0x80) {
+		dev_dbg(&host->spi->dev, "%s: INVALID RESPONSE, %02x\n",
+					tag, *cp);
+		value = -EBADR;
+		goto done;
+	}
+
+	cmd->resp[0] = *cp++;
+	cmd->error = 0;
+
+	/* Status byte: the entire seven-bit R1 response.  */
+	if (cmd->resp[0] != 0) {
+		if ((R1_SPI_PARAMETER | R1_SPI_ADDRESS
+					| R1_SPI_ILLEGAL_COMMAND)
+				& cmd->resp[0])
+			value = -EINVAL;
+		else if (R1_SPI_COM_CRC & cmd->resp[0])
+			value = -EILSEQ;
+		else if ((R1_SPI_ERASE_SEQ | R1_SPI_ERASE_RESET)
+				& cmd->resp[0])
+			value = -EIO;
+		/* else R1_SPI_IDLE, "it's resetting" */
+	}
+
+	switch (mmc_spi_resp_type(cmd)) {
+
+	/* SPI R1B == R1 + busy; STOP_TRANSMISSION (for multiblock reads)
+	 * and less-common stuff like various erase operations.
+	 */
+	case MMC_RSP_SPI_R1B:
+		/* maybe we read all the busy tokens already */
+		while (cp < end && *cp == 0)
+			cp++;
+		if (cp == end)
+			mmc_spi_wait_unbusy(host, r1b_timeout);
+		break;
+
+	/* SPI R2 == R1 + second status byte; SEND_STATUS
+	 * SPI R5 == R1 + data byte; IO_RW_DIRECT
+	 */
+	case MMC_RSP_SPI_R2:
+		cmd->resp[0] |= *cp << 8;
+		break;
+
+	/* SPI R3, R4, or R7 == R1 + 4 bytes */
+	case MMC_RSP_SPI_R3:
+		cmd->resp[1] = be32_to_cpu(get_unaligned((u32 *)cp));
+		break;
+
+	/* SPI R1 == just one status byte */
+	case MMC_RSP_SPI_R1:
+		break;
+
+	default:
+		dev_dbg(&host->spi->dev, "bad response type %04x\n",
+				mmc_spi_resp_type(cmd));
+		if (value >= 0)
+			value = -EINVAL;
+		goto done;
+	}
+
+	if (value < 0)
+		dev_dbg(&host->spi->dev, "%s: resp %04x %08x\n",
+			tag, cmd->resp[0], cmd->resp[1]);
+
+	/* disable chipselect on errors and some success cases */
+	if (value >= 0 && cs_on)
+		return value;
+done:
+	if (value < 0)
+		cmd->error = value;
+	mmc_cs_off(host);
+	return value;
+}
+
+/* Issue command and read its response.
+ * Returns zero on success, negative for error.
+ *
+ * On error, caller must cope with mmc core retry mechanism.  That
+ * means immediate low-level resubmit, which affects the bus lock...
+ */
+static int
+mmc_spi_command_send(struct mmc_spi_host *host,
+		struct mmc_request *mrq,
+		struct mmc_command *cmd, int cs_on)
+{
+	struct scratch		*data = host->data;
+	u8			*cp = data->status;
+	u32			arg = cmd->arg;
+	int			status;
+	struct spi_transfer	*t;
+
+	/* We can handle most commands (except block reads) in one full
+	 * duplex I/O operation before either starting the next transfer
+	 * (data block or command) or else deselecting the card.
+	 *
+	 * First, write 7 bytes:
+	 *  - an all-ones byte to ensure the card is ready
+	 *  - opcode byte (plus start and transmission bits)
+	 *  - four bytes of big-endian argument
+	 *  - crc7 (plus end bit) ... always computed, it's cheap
+	 *
+	 * We init the whole buffer to all-ones, which is what we need
+	 * to write while we're reading (later) response data.
+	 */
+	memset(cp++, 0xff, sizeof(data->status));
+
+	*cp++ = 0x40 | cmd->opcode;
+	*cp++ = (u8)(arg >> 24);
+	*cp++ = (u8)(arg >> 16);
+	*cp++ = (u8)(arg >> 8);
+	*cp++ = (u8)arg;
+	*cp++ = (crc7(0, &data->status[1], 5) << 1) | 0x01;
+
+	/* Then, read up to 13 bytes (while writing all-ones):
+	 *  - N(CR) (== 1..8) bytes of all-ones
+	 *  - status byte (for all response types)
+	 *  - the rest of the response, either:
+	 *      + nothing, for R1 or R1B responses
+	 *	+ second status byte, for R2 responses
+	 *	+ four data bytes, for R3 and R7 responses
+	 *
+	 * Finally, read some more bytes ... in the nice cases we know in
+	 * advance how many, and reading 1 more is always OK:
+	 *  - N(EC) (== 0..N) bytes of all-ones, before deselect/finish
+	 *  - N(RC) (== 1..N) bytes of all-ones, before next command
+	 *  - N(WR) (== 1..N) bytes of all-ones, before data write
+	 *
+	 * So in those cases one full duplex I/O of at most 21 bytes will
+	 * handle the whole command, leaving the card ready to receive a
+	 * data block or new command.  We do that whenever we can, shaving
+	 * CPU and IRQ costs (especially when using DMA or FIFOs).
+	 *
+	 * There are two other cases, where it's not generally practical
+	 * to rely on a single I/O:
+	 *
+	 *  - R1B responses need at least N(EC) bytes of all-zeroes.
+	 *
+	 *    In this case we can *try* to fit it into one I/O, then
+	 *    maybe read more data later.
+	 *
+	 *  - Data block reads are more troublesome, since a variable
+	 *    number of padding bytes precede the token and data.
+	 *      + N(CX) (== 0..8) bytes of all-ones, before CSD or CID
+	 *      + N(AC) (== 1..many) bytes of all-ones
+	 *
+	 *    In this case we currently only have minimal speedups here:
+	 *    when N(CR) == 1 we can avoid I/O in response_get().
+	 */
+	if (cs_on && (mrq->data->flags & MMC_DATA_READ)) {
+		cp += 2;	/* min(N(CR)) + status */
+		/* R1 */
+	} else {
+		cp += 10;	/* max(N(CR)) + status + min(N(RC),N(WR)) */
+		if (cmd->flags & MMC_RSP_SPI_S2)	/* R2/R5 */
+			cp++;
+		else if (cmd->flags & MMC_RSP_SPI_B4)	/* R3/R4/R7 */
+			cp += 4;
+		else if (cmd->flags & MMC_RSP_BUSY)	/* R1B */
+			cp = data->status + sizeof(data->status);
+		/* else:  R1 (most commands) */
+	}
+
+	dev_dbg(&host->spi->dev, "  mmc_spi: CMD%d, resp %s\n",
+		cmd->opcode, maptype(cmd));
+
+	/* send command, leaving chipselect active */
+	spi_message_init(&host->m);
+
+	t = &host->t;
+	memset(t, 0, sizeof(*t));
+	t->tx_buf = t->rx_buf = data->status;
+	t->tx_dma = t->rx_dma = host->data_dma;
+	t->len = cp - data->status;
+	t->cs_change = 1;
+	spi_message_add_tail(t, &host->m);
+
+	if (host->dma_dev) {
+		host->m.is_dma_mapped = 1;
+		dma_sync_single_for_device(host->dma_dev,
+				host->data_dma, sizeof(*host->data),
+				DMA_BIDIRECTIONAL);
+	}
+	status = spi_sync(host->spi, &host->m);
+	if (status == 0)
+		status = host->m.status;
+
+	if (host->dma_dev)
+		dma_sync_single_for_cpu(host->dma_dev,
+				host->data_dma, sizeof(*host->data),
+				DMA_BIDIRECTIONAL);
+	if (status < 0) {
+		dev_dbg(&host->spi->dev, "  ... write returned %d\n", status);
+		cmd->error = status;
+		return status;
+	}
+
+	/* after no-data commands and STOP_TRANSMISSION, chipselect off */
+	return mmc_spi_response_get(host, cmd, cs_on);
+}
+
+/* Build data message with up to four separate transfers.  For TX, we
+ * start by writing the data token.  And in most cases, we finish with
+ * a status transfer.
+ *
+ * We always provide TX data for data and CRC.  The MMC/SD protocol
+ * requires us to write ones; but Linux defaults to writing zeroes;
+ * so we explicitly initialize it to all ones on RX paths.
+ *
+ * We also handle DMA mapping, so the underlying SPI controller does
+ * not need to (re)do it for each message.
+ */
+static void
+mmc_spi_setup_data_message(
+	struct mmc_spi_host	*host,
+	int			multiple,
+	enum dma_data_direction	direction)
+{
+	struct spi_transfer	*t;
+	struct scratch		*scratch = host->data;
+	dma_addr_t		dma = host->data_dma;
+
+	spi_message_init(&host->m);
+	if (dma)
+		host->m.is_dma_mapped = 1;
+
+	/* for reads, readblock() skips 0xff bytes before finding
+	 * the token; for writes, this transfer issues that token.
+	 */
+	if (direction == DMA_TO_DEVICE) {
+		t = &host->token;
+		memset(t, 0, sizeof(*t));
+		t->len = 1;
+		if (multiple)
+			scratch->data_token = SPI_TOKEN_MULTI_WRITE;
+		else
+			scratch->data_token = SPI_TOKEN_SINGLE;
+		t->tx_buf = &scratch->data_token;
+		if (dma)
+			t->tx_dma = dma + offsetof(struct scratch, data_token);
+		spi_message_add_tail(t, &host->m);
+	}
+
+	/* Body of transfer is buffer, then CRC ...
+	 * either TX-only, or RX with TX-ones.
+	 */
+	t = &host->t;
+	memset(t, 0, sizeof(*t));
+	t->tx_buf = host->ones;
+	t->tx_dma = host->ones_dma;
+	/* length and actual buffer info are written later */
+	spi_message_add_tail(t, &host->m);
+
+	t = &host->crc;
+	memset(t, 0, sizeof(*t));
+	t->len = 2;
+	if (direction == DMA_TO_DEVICE) {
+		/* the actual CRC may get written later */
+		t->tx_buf = &scratch->crc_val;
+		if (dma)
+			t->tx_dma = dma + offsetof(struct scratch, crc_val);
+	} else {
+		t->tx_buf = host->ones;
+		t->tx_dma = host->ones_dma;
+		t->rx_buf = &scratch->crc_val;
+		if (dma)
+			t->rx_dma = dma + offsetof(struct scratch, crc_val);
+	}
+	spi_message_add_tail(t, &host->m);
+
+	/*
+	 * A single block read is followed by N(EC) [0+] all-ones bytes
+	 * before deselect ... don't bother.
+	 *
+	 * Multiblock reads are followed by N(AC) [1+] all-ones bytes before
+	 * the next block is read, or a STOP_TRANSMISSION is issued.  We'll
+	 * collect that single byte, so readblock() doesn't need to.
+	 *
+	 * For a write, the one-byte data response follows immediately, then
+	 * come zero or more busy bytes, then N(WR) [1+] all-ones bytes.
+	 * Then single block reads may deselect, and multiblock ones issue
+	 * the next token (next data block, or STOP_TRAN).  We can try to
+	 * minimize I/O ops by using a single read to collect end-of-busy.
+	 */
+	if (multiple || direction == DMA_TO_DEVICE) {
+		t = &host->early_status;
+		memset(t, 0, sizeof(*t));
+		t->len = (direction == DMA_TO_DEVICE)
+				? sizeof(scratch->status)
+				: 1;
+		t->tx_buf = host->ones;
+		t->tx_dma = host->ones_dma;
+		t->rx_buf = scratch->status;
+		if (dma)
+			t->rx_dma = dma + offsetof(struct scratch, status);
+		t->cs_change = 1;
+		spi_message_add_tail(t, &host->m);
+	}
+}
+
+/*
+ * Write one block:
+ *  - caller handled preceding N(WR) [1+] all-ones bytes
+ *  - data block
+ *	+ token
+ *	+ data bytes
+ *	+ crc16
+ *  - an all-ones byte ... card writes a data-response byte
+ *  - followed by N(EC) [0+] all-ones bytes, card writes zero/'busy'
+ *
+ * Return negative errno, else success.
+ */
+static int
+mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t)
+{
+	struct spi_device	*spi = host->spi;
+	int			status, i;
+	struct scratch		*scratch = host->data;
+
+	if (host->mmc->use_spi_crc)
+		scratch->crc_val = cpu_to_be16(
+				crc_itu_t(0, t->tx_buf, t->len));
+	if (host->dma_dev)
+		dma_sync_single_for_device(host->dma_dev,
+				host->data_dma, sizeof(*scratch),
+				DMA_BIDIRECTIONAL);
+
+	status = spi_sync(spi, &host->m);
+	if (status == 0)
+		status = host->m.status;
+
+	if (status != 0) {
+		dev_dbg(&spi->dev, "write error (%d)\n", status);
+		return status;
+	}
+
+	if (host->dma_dev)
+		dma_sync_single_for_cpu(host->dma_dev,
+				host->data_dma, sizeof(*scratch),
+				DMA_BIDIRECTIONAL);
+
+	/*
+	 * Get the transmission data-response reply.  It must follow
+	 * immediately after the data block we transferred.  This reply
+	 * doesn't necessarily tell whether the write operation succeeded;
+	 * it just says if the transmission was ok and whether *earlier*
+	 * writes succeeded; see the standard.
+	 */
+	switch (SPI_MMC_RESPONSE_CODE(scratch->status[0])) {
+	case SPI_RESPONSE_ACCEPTED:
+		status = 0;
+		break;
+	case SPI_RESPONSE_CRC_ERR:
+		/* host shall then issue MMC_STOP_TRANSMISSION */
+		status = -EILSEQ;
+		break;
+	case SPI_RESPONSE_WRITE_ERR:
+		/* host shall then issue MMC_STOP_TRANSMISSION,
+		 * and should MMC_SEND_STATUS to sort it out
+		 */
+		status = -EIO;
+		break;
+	default:
+		status = -EPROTO;
+		break;
+	}
+	if (status != 0) {
+		dev_dbg(&spi->dev, "write error %02x (%d)\n",
+			scratch->status[0], status);
+		return status;
+	}
+
+	t->tx_buf += t->len;
+	if (host->dma_dev)
+		t->tx_dma += t->len;
+
+	/* Return when not busy.  If we didn't collect that status yet,
+	 * we'll need some more I/O.
+	 */
+	for (i = 1; i < sizeof(scratch->status); i++) {
+		if (scratch->status[i] != 0)
+			return 0;
+	}
+	return mmc_spi_wait_unbusy(host, writeblock_timeout);
+}
+
+/*
+ * Read one block:
+ *  - skip leading all-ones bytes ... either
+ *      + N(AC) [1..f(clock,CSD)] usually, else
+ *      + N(CX) [0..8] when reading CSD or CID
+ *  - data block
+ *	+ token ... if error token, no data or crc
+ *	+ data bytes
+ *	+ crc16
+ *
+ * After single block reads, we're done; N(EC) [0+] all-ones bytes follow
+ * before dropping chipselect.
+ *
+ * For multiblock reads, caller either reads the next block or issues a
+ * STOP_TRANSMISSION command.
+ */
+static int
+mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t)
+{
+	struct spi_device	*spi = host->spi;
+	int			status;
+	struct scratch		*scratch = host->data;
+
+	/* At least one SD card sends an all-zeroes byte when N(CX)
+	 * applies, before the all-ones bytes ... just cope with that.
+	 */
+	status = mmc_spi_readbytes(host, 1);
+	if (status < 0)
+		return status;
+	status = scratch->status[0];
+	if (status == 0xff || status == 0)
+		status = mmc_spi_readtoken(host);
+
+	if (status == SPI_TOKEN_SINGLE) {
+		if (host->dma_dev) {
+			dma_sync_single_for_device(host->dma_dev,
+					host->data_dma, sizeof(*scratch),
+					DMA_BIDIRECTIONAL);
+			dma_sync_single_for_device(host->dma_dev,
+					t->rx_dma, t->len,
+					DMA_FROM_DEVICE);
+		}
+
+		status = spi_sync(spi, &host->m);
+		if (status == 0)
+			status = host->m.status;
+
+		if (host->dma_dev) {
+			dma_sync_single_for_cpu(host->dma_dev,
+					host->data_dma, sizeof(*scratch),
+					DMA_BIDIRECTIONAL);
+			dma_sync_single_for_cpu(host->dma_dev,
+					t->rx_dma, t->len,
+					DMA_FROM_DEVICE);
+		}
+
+	} else {
+		dev_dbg(&spi->dev, "read error %02x (%d)\n", status, status);
+
+		/* we've read extra garbage, timed out, etc */
+		if (status < 0)
+			return status;
+
+		/* low four bits are an R2 subset, fifth seems to be
+		 * vendor specific ... map them all to generic error..
+		 */
+		return -EIO;
+	}
+
+	if (host->mmc->use_spi_crc) {
+		u16 crc = crc_itu_t(0, t->rx_buf, t->len);
+
+		be16_to_cpus(&scratch->crc_val);
+		if (scratch->crc_val != crc) {
+			dev_dbg(&spi->dev, "read - crc error: crc_val=0x%04x, "
+					"computed=0x%04x len=%d\n",
+					scratch->crc_val, crc, t->len);
+			return -EILSEQ;
+		}
+	}
+
+	t->rx_buf += t->len;
+	if (host->dma_dev)
+		t->rx_dma += t->len;
+
+	return 0;
+}
+
+/*
+ * An MMC/SD data stage includes one or more blocks, optional CRCs,
+ * and inline handshaking.  That handhaking makes it unlike most
+ * other SPI protocol stacks.
+ */
+static void
+mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
+		struct mmc_data *data, u32 blk_size)
+{
+	struct spi_device	*spi = host->spi;
+	struct device		*dma_dev = host->dma_dev;
+	struct spi_transfer	*t;
+	enum dma_data_direction	direction;
+	struct scatterlist	*sg;
+	unsigned		n_sg;
+	int			multiple = (data->blocks > 1);
+
+	if (data->flags & MMC_DATA_READ)
+		direction = DMA_FROM_DEVICE;
+	else
+		direction = DMA_TO_DEVICE;
+	mmc_spi_setup_data_message(host, multiple, direction);
+	t = &host->t;
+
+	/* Handle scatterlist segments one at a time, with synch for
+	 * each 512-byte block
+	 */
+	for (sg = data->sg, n_sg = data->sg_len; n_sg; n_sg--, sg++) {
+		int			status = 0;
+		dma_addr_t		dma_addr = 0;
+		void			*kmap_addr;
+		unsigned		length = sg->length;
+		enum dma_data_direction	dir = direction;
+
+		/* set up dma mapping for controller drivers that might
+		 * use DMA ... though they may fall back to PIO
+		 */
+		if (dma_dev) {
+			/* never invalidate whole *shared* pages ... */
+			if ((sg->offset != 0 || length != PAGE_SIZE)
+					&& dir == DMA_FROM_DEVICE)
+				dir = DMA_BIDIRECTIONAL;
+
+			dma_addr = dma_map_page(dma_dev, sg->page, 0,
+						PAGE_SIZE, dir);
+			if (direction == DMA_TO_DEVICE)
+				t->tx_dma = dma_addr + sg->offset;
+			else
+				t->rx_dma = dma_addr + sg->offset;
+		}
+
+		/* allow pio too; we don't allow highmem */
+		kmap_addr = kmap(sg->page);
+		if (direction == DMA_TO_DEVICE)
+			t->tx_buf = kmap_addr + sg->offset;
+		else
+			t->rx_buf = kmap_addr + sg->offset;
+
+		/* transfer each block, and update request status */
+		while (length) {
+			t->len = min(length, blk_size);
+
+			dev_dbg(&host->spi->dev,
+				"    mmc_spi: %s block, %d bytes\n",
+				(direction == DMA_TO_DEVICE)
+				? "write"
+				: "read",
+				t->len);
+
+			if (direction == DMA_TO_DEVICE)
+				status = mmc_spi_writeblock(host, t);
+			else
+				status = mmc_spi_readblock(host, t);
+			if (status < 0)
+				break;
+
+			data->bytes_xfered += t->len;
+			length -= t->len;
+
+			if (!multiple)
+				break;
+		}
+
+		/* discard mappings */
+		if (direction == DMA_FROM_DEVICE)
+			flush_kernel_dcache_page(sg->page);
+		kunmap(sg->page);
+		if (dma_dev)
+			dma_unmap_page(dma_dev, dma_addr, PAGE_SIZE, dir);
+
+		if (status < 0) {
+			data->error = status;
+			dev_dbg(&spi->dev, "%s status %d\n",
+				(direction == DMA_TO_DEVICE)
+					? "write" : "read",
+				status);
+			break;
+		}
+	}
+
+	/* NOTE some docs describe an MMC-only SET_BLOCK_COUNT (CMD23) that
+	 * can be issued before multiblock writes.  Unlike its more widely
+	 * documented analogue for SD cards (SET_WR_BLK_ERASE_COUNT, ACMD23),
+	 * that can affect the STOP_TRAN logic.   Complete (and current)
+	 * MMC specs should sort that out before Linux starts using CMD23.
+	 */
+	if (direction == DMA_TO_DEVICE && multiple) {
+		struct scratch	*scratch = host->data;
+		int		tmp;
+		const unsigned	statlen = sizeof(scratch->status);
+
+		dev_dbg(&spi->dev, "    mmc_spi: STOP_TRAN\n");
+
+		/* Tweak the per-block message we set up earlier by morphing
+		 * it to hold single buffer with the token followed by some
+		 * all-ones bytes ... skip N(BR) (0..1), scan the rest for
+		 * "not busy any longer" status, and leave chip selected.
+		 */
+		INIT_LIST_HEAD(&host->m.transfers);
+		list_add(&host->early_status.transfer_list,
+				&host->m.transfers);
+
+		memset(scratch->status, 0xff, statlen);
+		scratch->status[0] = SPI_TOKEN_STOP_TRAN;
+
+		host->early_status.tx_buf = host->early_status.rx_buf;
+		host->early_status.tx_dma = host->early_status.rx_dma;
+		host->early_status.len = statlen;
+
+		if (host->dma_dev)
+			dma_sync_single_for_device(host->dma_dev,
+					host->data_dma, sizeof(*scratch),
+					DMA_BIDIRECTIONAL);
+
+		tmp = spi_sync(spi, &host->m);
+		if (tmp == 0)
+			tmp = host->m.status;
+
+		if (host->dma_dev)
+			dma_sync_single_for_cpu(host->dma_dev,
+					host->data_dma, sizeof(*scratch),
+					DMA_BIDIRECTIONAL);
+
+		if (tmp < 0) {
+			if (!data->error)
+				data->error = tmp;
+			return;
+		}
+
+		/* Ideally we collected "not busy" status with one I/O,
+		 * avoiding wasteful byte-at-a-time scanning... but more
+		 * I/O is often needed.
+		 */
+		for (tmp = 2; tmp < statlen; tmp++) {
+			if (scratch->status[tmp] != 0)
+				return;
+		}
+		tmp = mmc_spi_wait_unbusy(host, writeblock_timeout);
+		if (tmp < 0 && !data->error)
+			data->error = tmp;
+	}
+}
+
+/****************************************************************************/
+
+/*
+ * MMC driver implementation -- the interface to the MMC stack
+ */
+
+static void mmc_spi_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	struct mmc_spi_host	*host = mmc_priv(mmc);
+	int			status = -EINVAL;
+
+#ifdef DEBUG
+	/* MMC core and layered drivers *MUST* issue SPI-aware commands */
+	{
+		struct mmc_command	*cmd;
+		int			invalid = 0;
+
+		cmd = mrq->cmd;
+		if (!mmc_spi_resp_type(cmd)) {
+			dev_dbg(&host->spi->dev, "bogus command\n");
+			cmd->error = -EINVAL;
+			invalid = 1;
+		}
+
+		cmd = mrq->stop;
+		if (cmd && !mmc_spi_resp_type(cmd)) {
+			dev_dbg(&host->spi->dev, "bogus STOP command\n");
+			cmd->error = -EINVAL;
+			invalid = 1;
+		}
+
+		if (invalid) {
+			dump_stack();
+			mmc_request_done(host->mmc, mrq);
+			return;
+		}
+	}
+#endif
+
+	/* issue command; then optionally data and stop */
+	status = mmc_spi_command_send(host, mrq, mrq->cmd, mrq->data != NULL);
+	if (status == 0 && mrq->data) {
+		mmc_spi_data_do(host, mrq->cmd, mrq->data, mrq->data->blksz);
+		if (mrq->stop)
+			status = mmc_spi_command_send(host, mrq, mrq->stop, 0);
+		else
+			mmc_cs_off(host);
+	}
+
+	mmc_request_done(host->mmc, mrq);
+}
+
+/* See Section 6.4.1, in SD "Simplified Physical Layer Specification 2.0"
+ *
+ * NOTE that here we can't know that the card has just been powered up;
+ * not all MMC/SD sockets support power switching.
+ *
+ * FIXME when the card is still in SPI mode, e.g. from a previous kernel,
+ * this doesn't seem to do the right thing at all...
+ */
+static void mmc_spi_initsequence(struct mmc_spi_host *host)
+{
+	/* Try to be very sure any previous command has completed;
+	 * wait till not-busy, skip debris from any old commands.
+	 */
+	mmc_spi_wait_unbusy(host, r1b_timeout);
+	mmc_spi_readbytes(host, 10);
+
+	/*
+	 * Do a burst with chipselect active-high.  We need to do this to
+	 * meet the requirement of 74 clock cycles with both chipselect
+	 * and CMD (MOSI) high before CMD0 ... after the card has been
+	 * powered up to Vdd(min), and so is ready to take commands.
+	 *
+	 * Some cards are particularly needy of this (e.g. Viking "SD256")
+	 * while most others don't seem to care.
+	 *
+	 * Note that this is one of the places MMC/SD plays games with the
+	 * SPI protocol.  Another is that when chipselect is released while
+	 * the card returns BUSY status, the clock must issue several cycles
+	 * with chipselect high before the card will stop driving its output.
+	 */
+	host->spi->mode |= SPI_CS_HIGH;
+	if (spi_setup(host->spi) != 0) {
+		/* Just warn; most cards work without it. */
+		dev_warn(&host->spi->dev,
+				"can't change chip-select polarity\n");
+		host->spi->mode &= ~SPI_CS_HIGH;
+	} else {
+		mmc_spi_readbytes(host, 18);
+
+		host->spi->mode &= ~SPI_CS_HIGH;
+		if (spi_setup(host->spi) != 0) {
+			/* Wot, we can't get the same setup we had before? */
+			dev_err(&host->spi->dev,
+					"can't restore chip-select polarity\n");
+		}
+	}
+}
+
+static char *mmc_powerstring(u8 power_mode)
+{
+	switch (power_mode) {
+	case MMC_POWER_OFF: return "off";
+	case MMC_POWER_UP:  return "up";
+	case MMC_POWER_ON:  return "on";
+	}
+	return "?";
+}
+
+static void mmc_spi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct mmc_spi_host *host = mmc_priv(mmc);
+
+	if (host->power_mode != ios->power_mode) {
+		int		canpower;
+
+		canpower = host->pdata && host->pdata->setpower;
+
+		dev_dbg(&host->spi->dev, "mmc_spi: power %s (%d)%s\n",
+				mmc_powerstring(ios->power_mode),
+				ios->vdd,
+				canpower ? ", can switch" : "");
+
+		/* switch power on/off if possible, accounting for
+		 * max 250msec powerup time if needed.
+		 */
+		if (canpower) {
+			switch (ios->power_mode) {
+			case MMC_POWER_OFF:
+			case MMC_POWER_UP:
+				host->pdata->setpower(&host->spi->dev,
+						ios->vdd);
+				if (ios->power_mode == MMC_POWER_UP)
+					msleep(host->powerup_msecs);
+			}
+		}
+
+		/* See 6.4.1 in the simplified SD card physical spec 2.0 */
+		if (ios->power_mode == MMC_POWER_ON)
+			mmc_spi_initsequence(host);
+
+		/* If powering down, ground all card inputs to avoid power
+		 * delivery from data lines!  On a shared SPI bus, this
+		 * will probably be temporary; 6.4.2 of the simplified SD
+		 * spec says this must last at least 1msec.
+		 *
+		 *   - Clock low means CPOL 0, e.g. mode 0
+		 *   - MOSI low comes from writing zero
+		 *   - Chipselect is usually active low...
+		 */
+		if (canpower && ios->power_mode == MMC_POWER_OFF) {
+			int mres;
+
+			host->spi->mode &= ~(SPI_CPOL|SPI_CPHA);
+			mres = spi_setup(host->spi);
+			if (mres < 0)
+				dev_dbg(&host->spi->dev,
+					"switch to SPI mode 0 failed\n");
+
+			if (spi_w8r8(host->spi, 0x00) < 0)
+				dev_dbg(&host->spi->dev,
+					"put spi signals to low failed\n");
+
+			/*
+			 * Now clock should be low due to spi mode 0;
+			 * MOSI should be low because of written 0x00;
+			 * chipselect should be low (it is active low)
+			 * power supply is off, so now MMC is off too!
+			 *
+			 * FIXME no, chipselect can be high since the
+			 * device is inactive and SPI_CS_HIGH is clear...
+			 */
+			msleep(10);
+			if (mres == 0) {
+				host->spi->mode |= (SPI_CPOL|SPI_CPHA);
+				mres = spi_setup(host->spi);
+				if (mres < 0)
+					dev_dbg(&host->spi->dev,
+						"switch back to SPI mode 3"
+						" failed\n");
+			}
+		}
+
+		host->power_mode = ios->power_mode;
+	}
+
+	if (host->spi->max_speed_hz != ios->clock && ios->clock != 0) {
+		int		status;
+
+		host->spi->max_speed_hz = ios->clock;
+		status = spi_setup(host->spi);
+		dev_dbg(&host->spi->dev,
+			"mmc_spi:  clock to %d Hz, %d\n",
+			host->spi->max_speed_hz, status);
+	}
+}
+
+static int mmc_spi_get_ro(struct mmc_host *mmc)
+{
+	struct mmc_spi_host *host = mmc_priv(mmc);
+
+	if (host->pdata && host->pdata->get_ro)
+		return host->pdata->get_ro(mmc->parent);
+	/* board doesn't support read only detection; assume writeable */
+	return 0;
+}
+
+
+static const struct mmc_host_ops mmc_spi_ops = {
+	.request	= mmc_spi_request,
+	.set_ios	= mmc_spi_set_ios,
+	.get_ro		= mmc_spi_get_ro,
+};
+
+
+/****************************************************************************/
+
+/*
+ * SPI driver implementation
+ */
+
+static irqreturn_t
+mmc_spi_detect_irq(int irq, void *mmc)
+{
+	struct mmc_spi_host *host = mmc_priv(mmc);
+	u16 delay_msec = max(host->pdata->detect_delay, (u16)100);
+
+	mmc_detect_change(mmc, msecs_to_jiffies(delay_msec));
+	return IRQ_HANDLED;
+}
+
+static int mmc_spi_probe(struct spi_device *spi)
+{
+	void			*ones;
+	struct mmc_host		*mmc;
+	struct mmc_spi_host	*host;
+	int			status;
+
+	/* MMC and SD specs only seem to care that sampling is on the
+	 * rising edge ... meaning SPI modes 0 or 3.  So either SPI mode
+	 * should be legit.  We'll use mode 0 since it seems to be a
+	 * bit less troublesome on some hardware ... unclear why.
+	 */
+	spi->mode = SPI_MODE_0;
+	spi->bits_per_word = 8;
+
+	status = spi_setup(spi);
+	if (status < 0) {
+		dev_dbg(&spi->dev, "needs SPI mode %02x, %d KHz; %d\n",
+				spi->mode, spi->max_speed_hz / 1000,
+				status);
+		return status;
+	}
+
+	/* We can use the bus safely iff nobody else will interfere with
+	 * us.  That is, either we have the experimental exclusive access
+	 * primitives ... or else there's nobody to share it with.
+	 */
+	if (spi->master->num_chipselect > 1) {
+		struct device	*parent = spi->dev.parent;
+
+		/* If there are multiple devices on this bus, we
+		 * can't proceed.
+		 */
+		spin_lock(&parent->klist_children.k_lock);
+		if (parent->klist_children.k_list.next
+				!= parent->klist_children.k_list.prev)
+			status = -EMLINK;
+		else
+			status = 0;
+		spin_unlock(&parent->klist_children.k_lock);
+		if (status < 0) {
+			dev_err(&spi->dev, "can't share SPI bus\n");
+			return status;
+		}
+
+		/* REVISIT we can't guarantee another device won't
+		 * be added later.  It's uncommon though ... for now,
+		 * work as if this is safe.
+		 */
+		dev_warn(&spi->dev, "ASSUMING unshared SPI bus!\n");
+	}
+
+	/* We need a supply of ones to transmit.  This is the only time
+	 * the CPU touches these, so cache coherency isn't a concern.
+	 *
+	 * NOTE if many systems use more than one MMC-over-SPI connector
+	 * it'd save some memory to share this.  That's evidently rare.
+	 */
+	status = -ENOMEM;
+	ones = kmalloc(MMC_SPI_BLOCKSIZE, GFP_KERNEL);
+	if (!ones)
+		goto nomem;
+	memset(ones, 0xff, MMC_SPI_BLOCKSIZE);
+
+	mmc = mmc_alloc_host(sizeof(*host), &spi->dev);
+	if (!mmc)
+		goto nomem;
+
+	mmc->ops = &mmc_spi_ops;
+	mmc->max_blk_size = MMC_SPI_BLOCKSIZE;
+
+	/* As long as we keep track of the number of successfully
+	 * transmitted blocks, we're good for multiwrite.
+	 */
+	mmc->caps = MMC_CAP_SPI | MMC_CAP_MULTIWRITE;
+
+	/* SPI doesn't need the lowspeed device identification thing for
+	 * MMC or SD cards, since it never comes up in open drain mode.
+	 * That's good; some SPI masters can't handle very low speeds!
+	 *
+	 * However, low speed SDIO cards need not handle over 400 KHz;
+	 * that's the only reason not to use a few MHz for f_min (until
+	 * the upper layer reads the target frequency from the CSD).
+	 */
+	mmc->f_min = 400000;
+	mmc->f_max = spi->max_speed_hz;
+
+	host = mmc_priv(mmc);
+	host->mmc = mmc;
+	host->spi = spi;
+
+	host->ones = ones;
+
+	/* Platform data is used to hook up things like card sensing
+	 * and power switching gpios.
+	 */
+	host->pdata = spi->dev.platform_data;
+	if (host->pdata)
+		mmc->ocr_avail = host->pdata->ocr_mask;
+	if (!mmc->ocr_avail) {
+		dev_warn(&spi->dev, "ASSUMING 3.2-3.4 V slot power\n");
+		mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
+	}
+	if (host->pdata && host->pdata->setpower) {
+		host->powerup_msecs = host->pdata->powerup_msecs;
+		if (!host->powerup_msecs || host->powerup_msecs > 250)
+			host->powerup_msecs = 250;
+	}
+
+	dev_set_drvdata(&spi->dev, mmc);
+
+	/* preallocate dma buffers */
+	host->data = kmalloc(sizeof(*host->data), GFP_KERNEL);
+	if (!host->data)
+		goto fail_nobuf1;
+
+	if (spi->master->cdev.dev->dma_mask) {
+		struct device	*dev = spi->master->cdev.dev;
+
+		host->dma_dev = dev;
+		host->ones_dma = dma_map_single(dev, ones,
+				MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE);
+		host->data_dma = dma_map_single(dev, host->data,
+				sizeof(*host->data), DMA_BIDIRECTIONAL);
+
+		/* REVISIT in theory those map operations can fail... */
+
+		dma_sync_single_for_cpu(host->dma_dev,
+				host->data_dma, sizeof(*host->data),
+				DMA_BIDIRECTIONAL);
+	}
+
+	/* setup message for status/busy readback */
+	spi_message_init(&host->readback);
+	host->readback.is_dma_mapped = (host->dma_dev != NULL);
+
+	spi_message_add_tail(&host->status, &host->readback);
+	host->status.tx_buf = host->ones;
+	host->status.tx_dma = host->ones_dma;
+	host->status.rx_buf = &host->data->status;
+	host->status.rx_dma = host->data_dma + offsetof(struct scratch, status);
+	host->status.cs_change = 1;
+
+	/* register card detect irq */
+	if (host->pdata && host->pdata->init) {
+		status = host->pdata->init(&spi->dev, mmc_spi_detect_irq, mmc);
+		if (status != 0)
+			goto fail_glue_init;
+	}
+
+	status = mmc_add_host(mmc);
+	if (status != 0)
+		goto fail_add_host;
+
+	dev_info(&spi->dev, "SD/MMC host %s%s%s%s\n",
+			mmc->class_dev.bus_id,
+			host->dma_dev ? "" : ", no DMA",
+			(host->pdata && host->pdata->get_ro)
+				? "" : ", no WP",
+			(host->pdata && host->pdata->setpower)
+				? "" : ", no poweroff");
+	return 0;
+
+fail_add_host:
+	mmc_remove_host (mmc);
+fail_glue_init:
+	if (host->dma_dev)
+		dma_unmap_single(host->dma_dev, host->data_dma,
+				sizeof(*host->data), DMA_BIDIRECTIONAL);
+	kfree(host->data);
+
+fail_nobuf1:
+	mmc_free_host(mmc);
+	dev_set_drvdata(&spi->dev, NULL);
+
+nomem:
+	kfree(ones);
+	return status;
+}
+
+
+static int __devexit mmc_spi_remove(struct spi_device *spi)
+{
+	struct mmc_host		*mmc = dev_get_drvdata(&spi->dev);
+	struct mmc_spi_host	*host;
+
+	if (mmc) {
+		host = mmc_priv(mmc);
+
+		/* prevent new mmc_detect_change() calls */
+		if (host->pdata && host->pdata->exit)
+			host->pdata->exit(&spi->dev, mmc);
+
+		mmc_remove_host(mmc);
+
+		if (host->dma_dev) {
+			dma_unmap_single(host->dma_dev, host->ones_dma,
+				MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE);
+			dma_unmap_single(host->dma_dev, host->data_dma,
+				sizeof(*host->data), DMA_BIDIRECTIONAL);
+		}
+
+		kfree(host->data);
+		kfree(host->ones);
+
+		spi->max_speed_hz = mmc->f_max;
+		mmc_free_host(mmc);
+		dev_set_drvdata(&spi->dev, NULL);
+	}
+	return 0;
+}
+
+
+static struct spi_driver mmc_spi_driver = {
+	.driver = {
+		.name =		"mmc_spi",
+		.bus =		&spi_bus_type,
+		.owner =	THIS_MODULE,
+	},
+	.probe =	mmc_spi_probe,
+	.remove =	__devexit_p(mmc_spi_remove),
+};
+
+
+static int __init mmc_spi_init(void)
+{
+	return spi_register_driver(&mmc_spi_driver);
+}
+module_init(mmc_spi_init);
+
+
+static void __exit mmc_spi_exit(void)
+{
+	spi_unregister_driver(&mmc_spi_driver);
+}
+module_exit(mmc_spi_exit);
+
+
+MODULE_AUTHOR("Mike Lavender, David Brownell, "
+		"Hans-Peter Nilsson, Jan Nikitenko");
+MODULE_DESCRIPTION("SPI SD/MMC host driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index be730c0..d0eb0a2 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/highmem.h>
+#include <linux/log2.h>
 #include <linux/mmc/host.h>
 #include <linux/amba/bus.h>
 #include <linux/clk.h>
@@ -154,11 +155,11 @@
 	}
 	if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
 		if (status & MCI_DATACRCFAIL)
-			data->error = MMC_ERR_BADCRC;
+			data->error = -EILSEQ;
 		else if (status & MCI_DATATIMEOUT)
-			data->error = MMC_ERR_TIMEOUT;
+			data->error = -ETIMEDOUT;
 		else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN))
-			data->error = MMC_ERR_FIFO;
+			data->error = -EIO;
 		status |= MCI_DATAEND;
 
 		/*
@@ -193,12 +194,12 @@
 	cmd->resp[3] = readl(base + MMCIRESPONSE3);
 
 	if (status & MCI_CMDTIMEOUT) {
-		cmd->error = MMC_ERR_TIMEOUT;
+		cmd->error = -ETIMEDOUT;
 	} else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) {
-		cmd->error = MMC_ERR_BADCRC;
+		cmd->error = -EILSEQ;
 	}
 
-	if (!cmd->data || cmd->error != MMC_ERR_NONE) {
+	if (!cmd->data || cmd->error) {
 		if (host->data)
 			mmci_stop_data(host);
 		mmci_request_end(host, cmd->mrq);
@@ -391,6 +392,14 @@
 
 	WARN_ON(host->mrq != NULL);
 
+	if (mrq->data && !is_power_of_2(mrq->data->blksz)) {
+		printk(KERN_ERR "%s: Unsupported block size (%d bytes)\n",
+			mmc_hostname(mmc), mrq->data->blksz);
+		mrq->cmd->error = -EINVAL;
+		mmc_request_done(mmc, mrq);
+		return;
+	}
+
 	spin_lock_irq(&host->lock);
 
 	host->mrq = mrq;
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 0cf97ed..60a67dfc 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -263,7 +263,7 @@
 		enum dma_data_direction dma_data_dir;
 
 		BUG_ON(host->dma_ch < 0);
-		if (data->error != MMC_ERR_NONE)
+		if (data->error)
 			omap_stop_dma(host->dma_ch);
 		/* Release DMA channel lazily */
 		mod_timer(&host->dma_timer, jiffies + HZ);
@@ -368,7 +368,7 @@
 		}
 	}
 
-	if (host->data == NULL || cmd->error != MMC_ERR_NONE) {
+	if (host->data == NULL || cmd->error) {
 		host->mrq = NULL;
 		clk_disable(host->fclk);
 		mmc_request_done(host->mmc, cmd->mrq);
@@ -475,14 +475,14 @@
 		if (status & OMAP_MMC_STAT_DATA_TOUT) {
 			dev_dbg(mmc_dev(host->mmc), "data timeout\n");
 			if (host->data) {
-				host->data->error |= MMC_ERR_TIMEOUT;
+				host->data->error = -ETIMEDOUT;
 				transfer_error = 1;
 			}
 		}
 
 		if (status & OMAP_MMC_STAT_DATA_CRC) {
 			if (host->data) {
-				host->data->error |= MMC_ERR_BADCRC;
+				host->data->error = -EILSEQ;
 				dev_dbg(mmc_dev(host->mmc),
 					 "data CRC error, bytes left %d\n",
 					host->total_bytes_left);
@@ -504,7 +504,7 @@
 					dev_err(mmc_dev(host->mmc),
 						"command timeout, CMD %d\n",
 						host->cmd->opcode);
-				host->cmd->error = MMC_ERR_TIMEOUT;
+				host->cmd->error = -ETIMEDOUT;
 				end_command = 1;
 			}
 		}
@@ -514,7 +514,7 @@
 				dev_err(mmc_dev(host->mmc),
 					"command CRC error (CMD%d, arg 0x%08x)\n",
 					host->cmd->opcode, host->cmd->arg);
-				host->cmd->error = MMC_ERR_BADCRC;
+				host->cmd->error = -EILSEQ;
 				end_command = 1;
 			} else
 				dev_err(mmc_dev(host->mmc),
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index ff96033..657901e 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -142,6 +142,10 @@
 				   host->dma_dir);
 
 	for (i = 0; i < host->dma_len; i++) {
+		unsigned int length = sg_dma_len(&data->sg[i]);
+		host->sg_cpu[i].dcmd = dcmd | length;
+		if (length & 31 && !(data->flags & MMC_DATA_READ))
+			host->sg_cpu[i].dcmd |= DCMD_ENDIRQEN;
 		if (data->flags & MMC_DATA_READ) {
 			host->sg_cpu[i].dsadr = host->res->start + MMC_RXFIFO;
 			host->sg_cpu[i].dtadr = sg_dma_address(&data->sg[i]);
@@ -149,7 +153,6 @@
 			host->sg_cpu[i].dsadr = sg_dma_address(&data->sg[i]);
 			host->sg_cpu[i].dtadr = host->res->start + MMC_TXFIFO;
 		}
-		host->sg_cpu[i].dcmd = dcmd | sg_dma_len(&data->sg[i]);
 		host->sg_cpu[i].ddadr = host->sg_dma + (i + 1) *
 					sizeof(struct pxa_dma_desc);
 	}
@@ -226,7 +229,7 @@
 	}
 
 	if (stat & STAT_TIME_OUT_RESPONSE) {
-		cmd->error = MMC_ERR_TIMEOUT;
+		cmd->error = -ETIMEDOUT;
 	} else if (stat & STAT_RES_CRC_ERR && cmd->flags & MMC_RSP_CRC) {
 #ifdef CONFIG_PXA27x
 		/*
@@ -239,11 +242,11 @@
 			pr_debug("ignoring CRC from command %d - *risky*\n", cmd->opcode);
 		} else
 #endif
-		cmd->error = MMC_ERR_BADCRC;
+		cmd->error = -EILSEQ;
 	}
 
 	pxamci_disable_irq(host, END_CMD_RES);
-	if (host->data && cmd->error == MMC_ERR_NONE) {
+	if (host->data && !cmd->error) {
 		pxamci_enable_irq(host, DATA_TRAN_DONE);
 	} else {
 		pxamci_finish_request(host, host->mrq);
@@ -264,9 +267,9 @@
 		     host->dma_dir);
 
 	if (stat & STAT_READ_TIME_OUT)
-		data->error = MMC_ERR_TIMEOUT;
+		data->error = -ETIMEDOUT;
 	else if (stat & (STAT_CRC_READ_ERROR|STAT_CRC_WRITE_ERROR))
-		data->error = MMC_ERR_BADCRC;
+		data->error = -EILSEQ;
 
 	/*
 	 * There appears to be a hardware design bug here.  There seems to
@@ -274,7 +277,7 @@
 	 * This means that if there was an error on any block, we mark all
 	 * data blocks as being in error.
 	 */
-	if (data->error == MMC_ERR_NONE)
+	if (!data->error)
 		data->bytes_xfered = data->blocks * data->blksz;
 	else
 		data->bytes_xfered = 0;
@@ -284,7 +287,7 @@
 	host->data = NULL;
 	if (host->mrq->stop) {
 		pxamci_stop_clock(host);
-		pxamci_start_cmd(host, host->mrq->stop, 0);
+		pxamci_start_cmd(host, host->mrq->stop, host->cmdat);
 	} else {
 		pxamci_finish_request(host, host->mrq);
 	}
@@ -298,7 +301,7 @@
 	unsigned int ireg;
 	int handled = 0;
 
-	ireg = readl(host->base + MMC_I_REG);
+	ireg = readl(host->base + MMC_I_REG) & ~readl(host->base + MMC_I_MASK);
 
 	if (ireg) {
 		unsigned stat = readl(host->base + MMC_STAT);
@@ -309,6 +312,10 @@
 			handled |= pxamci_cmd_done(host, stat);
 		if (ireg & DATA_TRAN_DONE)
 			handled |= pxamci_data_done(host, stat);
+		if (ireg & SDIO_INT) {
+			mmc_signal_sdio_irq(host->mmc);
+			handled = 1;
+		}
 	}
 
 	return IRQ_RETVAL(handled);
@@ -382,20 +389,46 @@
 			host->cmdat |= CMDAT_INIT;
 	}
 
+	if (ios->bus_width == MMC_BUS_WIDTH_4)
+		host->cmdat |= CMDAT_SD_4DAT;
+	else
+		host->cmdat &= ~CMDAT_SD_4DAT;
+
 	pr_debug("PXAMCI: clkrt = %x cmdat = %x\n",
 		 host->clkrt, host->cmdat);
 }
 
+static void pxamci_enable_sdio_irq(struct mmc_host *host, int enable)
+{
+	struct pxamci_host *pxa_host = mmc_priv(host);
+
+	if (enable)
+		pxamci_enable_irq(pxa_host, SDIO_INT);
+	else
+		pxamci_disable_irq(pxa_host, SDIO_INT);
+}
+
 static const struct mmc_host_ops pxamci_ops = {
-	.request	= pxamci_request,
-	.get_ro		= pxamci_get_ro,
-	.set_ios	= pxamci_set_ios,
+	.request		= pxamci_request,
+	.get_ro			= pxamci_get_ro,
+	.set_ios		= pxamci_set_ios,
+	.enable_sdio_irq	= pxamci_enable_sdio_irq,
 };
 
 static void pxamci_dma_irq(int dma, void *devid)
 {
-	printk(KERN_ERR "DMA%d: IRQ???\n", dma);
-	DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
+	struct pxamci_host *host = devid;
+	int dcsr = DCSR(dma);
+	DCSR(dma) = dcsr & ~DCSR_STOPIRQEN;
+
+	if (dcsr & DCSR_ENDINTR) {
+		writel(BUF_PART_FULL, host->base + MMC_PRTBUF);
+	} else {
+		printk(KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n",
+		       mmc_hostname(host->mmc), dma, dcsr);
+		host->data->error = -EIO;
+		pxamci_data_done(host, 0);
+	}
 }
 
 static irqreturn_t pxamci_detect_irq(int irq, void *devid)
@@ -444,9 +477,9 @@
 	mmc->max_seg_size = PAGE_SIZE;
 
 	/*
-	 * Block length register is 10 bits.
+	 * Block length register is only 10 bits before PXA27x.
 	 */
-	mmc->max_blk_size = 1023;
+	mmc->max_blk_size = (cpu_is_pxa21x() || cpu_is_pxa25x()) ? 1023 : 2048;
 
 	/*
 	 * Block count register is 16 bits.
@@ -460,6 +493,12 @@
 	mmc->ocr_avail = host->pdata ?
 			 host->pdata->ocr_mask :
 			 MMC_VDD_32_33|MMC_VDD_33_34;
+	mmc->caps = 0;
+	host->cmdat = 0;
+	if (!cpu_is_pxa21x() && !cpu_is_pxa25x()) {
+		mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
+		host->cmdat |= CMDAT_SDIO_INT_EN;
+	}
 
 	host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL);
 	if (!host->sg_cpu) {
diff --git a/drivers/mmc/host/pxamci.h b/drivers/mmc/host/pxamci.h
index df17c28..3153e77 100644
--- a/drivers/mmc/host/pxamci.h
+++ b/drivers/mmc/host/pxamci.h
@@ -25,6 +25,8 @@
 #define SPI_EN			(1 << 0)
 
 #define MMC_CMDAT	0x0010
+#define CMDAT_SDIO_INT_EN	(1 << 11)
+#define CMDAT_SD_4DAT		(1 << 8)
 #define CMDAT_DMAEN		(1 << 7)
 #define CMDAT_INIT		(1 << 6)
 #define CMDAT_BUSY		(1 << 5)
diff --git a/drivers/mmc/host/ricoh_mmc.c b/drivers/mmc/host/ricoh_mmc.c
new file mode 100644
index 0000000..1e87045
--- /dev/null
+++ b/drivers/mmc/host/ricoh_mmc.c
@@ -0,0 +1,151 @@
+/*
+ *  ricoh_mmc.c - Dummy driver to disable the Rioch MMC controller.
+ *
+ *  Copyright (C) 2007 Philip Langdale, 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 is a conceptually ridiculous driver, but it is required by the way
+ * the Ricoh multi-function R5C832 works. This chip implements firewire
+ * and four different memory card controllers. Two of those controllers are
+ * an SDHCI controller and a proprietary MMC controller. The linux SDHCI
+ * driver supports MMC cards but the chip detects MMC cards in hardware
+ * and directs them to the MMC controller - so the SDHCI driver never sees
+ * them. To get around this, we must disable the useless MMC controller.
+ * At that point, the SDHCI controller will start seeing them. As a bonus,
+ * a detection event occurs immediately, even if the MMC card is already
+ * in the reader.
+ *
+ * The relevant registers live on the firewire function, so this is unavoidably
+ * ugly. Such is life.
+ */
+
+#include <linux/pci.h>
+
+#define DRIVER_NAME "ricoh-mmc"
+
+static const struct pci_device_id pci_ids[] __devinitdata = {
+	{
+		.vendor		= PCI_VENDOR_ID_RICOH,
+		.device		= PCI_DEVICE_ID_RICOH_R5C843,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+	},
+	{ /* end: all zeroes */ },
+};
+
+MODULE_DEVICE_TABLE(pci, pci_ids);
+
+static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,
+				     const struct pci_device_id *ent)
+{
+	u8 rev;
+
+	struct pci_dev *fw_dev = NULL;
+
+	BUG_ON(pdev == NULL);
+	BUG_ON(ent == NULL);
+
+	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &rev);
+
+	printk(KERN_INFO DRIVER_NAME
+		": Ricoh MMC controller found at %s [%04x:%04x] (rev %x)\n",
+		pci_name(pdev), (int)pdev->vendor, (int)pdev->device,
+		(int)rev);
+
+	while ((fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) {
+		if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) &&
+		    pdev->bus == fw_dev->bus) {
+			u8 write_enable;
+			u8 disable;
+
+			pci_read_config_byte(fw_dev, 0xCB, &disable);
+			if (disable & 0x02) {
+				printk(KERN_INFO DRIVER_NAME
+				       ": Controller already disabled. Nothing to do.\n");
+				return -ENODEV;
+			}
+
+			pci_read_config_byte(fw_dev, 0xCA, &write_enable);
+			pci_write_config_byte(fw_dev, 0xCA, 0x57);
+			pci_write_config_byte(fw_dev, 0xCB, disable | 0x02);
+			pci_write_config_byte(fw_dev, 0xCA, write_enable);
+
+			pci_set_drvdata(pdev, fw_dev);
+
+			printk(KERN_INFO DRIVER_NAME
+			       ": Controller is now disabled.\n");
+
+			break;
+		}
+	}
+
+	if (pci_get_drvdata(pdev) == NULL) {
+		printk(KERN_WARNING DRIVER_NAME
+		       ": Main firewire function not found. Cannot disable controller.\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static void __devexit ricoh_mmc_remove(struct pci_dev *pdev)
+{
+	u8 write_enable;
+	u8 disable;
+	struct pci_dev *fw_dev = NULL;
+
+	fw_dev = pci_get_drvdata(pdev);
+	BUG_ON(fw_dev == NULL);
+
+	pci_read_config_byte(fw_dev, 0xCA, &write_enable);
+	pci_read_config_byte(fw_dev, 0xCB, &disable);
+	pci_write_config_byte(fw_dev, 0xCA, 0x57);
+	pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02);
+	pci_write_config_byte(fw_dev, 0xCA, write_enable);
+
+	printk(KERN_INFO DRIVER_NAME
+	       ": Controller is now re-enabled.\n");
+
+	pci_set_drvdata(pdev, NULL);
+}
+
+static struct pci_driver ricoh_mmc_driver = {
+	.name = 	DRIVER_NAME,
+	.id_table =	pci_ids,
+	.probe = 	ricoh_mmc_probe,
+	.remove =	__devexit_p(ricoh_mmc_remove),
+};
+
+/*****************************************************************************\
+ *                                                                           *
+ * Driver init/exit                                                          *
+ *                                                                           *
+\*****************************************************************************/
+
+static int __init ricoh_mmc_drv_init(void)
+{
+	printk(KERN_INFO DRIVER_NAME
+		": Ricoh MMC Controller disabling driver\n");
+	printk(KERN_INFO DRIVER_NAME ": Copyright(c) Philip Langdale\n");
+
+	return pci_register_driver(&ricoh_mmc_driver);
+}
+
+static void __exit ricoh_mmc_drv_exit(void)
+{
+	pci_unregister_driver(&ricoh_mmc_driver);
+}
+
+module_init(ricoh_mmc_drv_init);
+module_exit(ricoh_mmc_drv_exit);
+
+MODULE_AUTHOR("Philip Langdale <philipl@alumni.utexas.net>");
+MODULE_DESCRIPTION("Ricoh MMC Controller disabling driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 20a7d89..b397121 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -25,8 +25,6 @@
 #define DBG(f, x...) \
 	pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x)
 
-static unsigned int debug_nodma = 0;
-static unsigned int debug_forcedma = 0;
 static unsigned int debug_quirks = 0;
 
 #define SDHCI_QUIRK_CLOCK_BEFORE_RESET			(1<<0)
@@ -35,6 +33,7 @@
 #define SDHCI_QUIRK_NO_CARD_NO_RESET			(1<<2)
 #define SDHCI_QUIRK_SINGLE_POWER_WRITE			(1<<3)
 #define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS		(1<<4)
+#define SDHCI_QUIRK_BROKEN_DMA				(1<<5)
 
 static const struct pci_device_id pci_ids[] __devinitdata = {
 	{
@@ -68,7 +67,8 @@
 		.device		= PCI_DEVICE_ID_ENE_CB712_SD,
 		.subvendor	= PCI_ANY_ID,
 		.subdevice	= PCI_ANY_ID,
-		.driver_data	= SDHCI_QUIRK_SINGLE_POWER_WRITE,
+		.driver_data	= SDHCI_QUIRK_SINGLE_POWER_WRITE |
+				  SDHCI_QUIRK_BROKEN_DMA,
 	},
 
 	{
@@ -76,7 +76,8 @@
 		.device		= PCI_DEVICE_ID_ENE_CB712_SD_2,
 		.subvendor	= PCI_ANY_ID,
 		.subdevice	= PCI_ANY_ID,
-		.driver_data	= SDHCI_QUIRK_SINGLE_POWER_WRITE,
+		.driver_data	= SDHCI_QUIRK_SINGLE_POWER_WRITE |
+				  SDHCI_QUIRK_BROKEN_DMA,
 	},
 
 	{
@@ -132,7 +133,7 @@
 		readb(host->ioaddr + SDHCI_POWER_CONTROL),
 		readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL));
 	printk(KERN_DEBUG DRIVER_NAME ": Wake-up:  0x%08x | Clock:    0x%08x\n",
-		readb(host->ioaddr + SDHCI_WALK_UP_CONTROL),
+		readb(host->ioaddr + SDHCI_WAKE_UP_CONTROL),
 		readw(host->ioaddr + SDHCI_CLOCK_CONTROL));
 	printk(KERN_DEBUG DRIVER_NAME ": Timeout:  0x%08x | Int stat: 0x%08x\n",
 		readb(host->ioaddr + SDHCI_TIMEOUT_CONTROL),
@@ -481,16 +482,16 @@
 	 * Controller doesn't count down when in single block mode.
 	 */
 	if (data->blocks == 1)
-		blocks = (data->error == MMC_ERR_NONE) ? 0 : 1;
+		blocks = (data->error == 0) ? 0 : 1;
 	else
 		blocks = readw(host->ioaddr + SDHCI_BLOCK_COUNT);
 	data->bytes_xfered = data->blksz * (data->blocks - blocks);
 
-	if ((data->error == MMC_ERR_NONE) && blocks) {
+	if (!data->error && blocks) {
 		printk(KERN_ERR "%s: Controller signalled completion even "
 			"though there were blocks left.\n",
 			mmc_hostname(host->mmc));
-		data->error = MMC_ERR_FAILED;
+		data->error = -EIO;
 	}
 
 	if (data->stop) {
@@ -498,7 +499,7 @@
 		 * The controller needs a reset of internal state machines
 		 * upon error conditions.
 		 */
-		if (data->error != MMC_ERR_NONE) {
+		if (data->error) {
 			sdhci_reset(host, SDHCI_RESET_CMD);
 			sdhci_reset(host, SDHCI_RESET_DATA);
 		}
@@ -533,7 +534,7 @@
 			printk(KERN_ERR "%s: Controller never released "
 				"inhibit bit(s).\n", mmc_hostname(host->mmc));
 			sdhci_dumpregs(host);
-			cmd->error = MMC_ERR_FAILED;
+			cmd->error = -EIO;
 			tasklet_schedule(&host->finish_tasklet);
 			return;
 		}
@@ -554,7 +555,7 @@
 	if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) {
 		printk(KERN_ERR "%s: Unsupported response type!\n",
 			mmc_hostname(host->mmc));
-		cmd->error = MMC_ERR_INVALID;
+		cmd->error = -EINVAL;
 		tasklet_schedule(&host->finish_tasklet);
 		return;
 	}
@@ -601,7 +602,7 @@
 		}
 	}
 
-	host->cmd->error = MMC_ERR_NONE;
+	host->cmd->error = 0;
 
 	if (host->data && host->data_early)
 		sdhci_finish_data(host);
@@ -722,7 +723,7 @@
 	host->mrq = mrq;
 
 	if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
-		host->mrq->cmd->error = MMC_ERR_TIMEOUT;
+		host->mrq->cmd->error = -ENOMEDIUM;
 		tasklet_schedule(&host->finish_tasklet);
 	} else
 		sdhci_send_command(host, mrq->cmd);
@@ -800,10 +801,35 @@
 	return !(present & SDHCI_WRITE_PROTECT);
 }
 
+static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+	struct sdhci_host *host;
+	unsigned long flags;
+	u32 ier;
+
+	host = mmc_priv(mmc);
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	ier = readl(host->ioaddr + SDHCI_INT_ENABLE);
+
+	ier &= ~SDHCI_INT_CARD_INT;
+	if (enable)
+		ier |= SDHCI_INT_CARD_INT;
+
+	writel(ier, host->ioaddr + SDHCI_INT_ENABLE);
+	writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE);
+
+	mmiowb();
+
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
 static const struct mmc_host_ops sdhci_ops = {
 	.request	= sdhci_request,
 	.set_ios	= sdhci_set_ios,
 	.get_ro		= sdhci_get_ro,
+	.enable_sdio_irq = sdhci_enable_sdio_irq,
 };
 
 /*****************************************************************************\
@@ -831,7 +857,7 @@
 			sdhci_reset(host, SDHCI_RESET_CMD);
 			sdhci_reset(host, SDHCI_RESET_DATA);
 
-			host->mrq->cmd->error = MMC_ERR_FAILED;
+			host->mrq->cmd->error = -ENOMEDIUM;
 			tasklet_schedule(&host->finish_tasklet);
 		}
 	}
@@ -859,9 +885,9 @@
 	 * The controller needs a reset of internal state machines
 	 * upon error conditions.
 	 */
-	if ((mrq->cmd->error != MMC_ERR_NONE) ||
-		(mrq->data && ((mrq->data->error != MMC_ERR_NONE) ||
-		(mrq->data->stop && (mrq->data->stop->error != MMC_ERR_NONE))))) {
+	if (mrq->cmd->error ||
+		(mrq->data && (mrq->data->error ||
+		(mrq->data->stop && mrq->data->stop->error)))) {
 
 		/* Some controllers need this kick or reset won't work here */
 		if (host->chip->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) {
@@ -906,13 +932,13 @@
 		sdhci_dumpregs(host);
 
 		if (host->data) {
-			host->data->error = MMC_ERR_TIMEOUT;
+			host->data->error = -ETIMEDOUT;
 			sdhci_finish_data(host);
 		} else {
 			if (host->cmd)
-				host->cmd->error = MMC_ERR_TIMEOUT;
+				host->cmd->error = -ETIMEDOUT;
 			else
-				host->mrq->cmd->error = MMC_ERR_TIMEOUT;
+				host->mrq->cmd->error = -ETIMEDOUT;
 
 			tasklet_schedule(&host->finish_tasklet);
 		}
@@ -941,13 +967,12 @@
 	}
 
 	if (intmask & SDHCI_INT_TIMEOUT)
-		host->cmd->error = MMC_ERR_TIMEOUT;
-	else if (intmask & SDHCI_INT_CRC)
-		host->cmd->error = MMC_ERR_BADCRC;
-	else if (intmask & (SDHCI_INT_END_BIT | SDHCI_INT_INDEX))
-		host->cmd->error = MMC_ERR_FAILED;
+		host->cmd->error = -ETIMEDOUT;
+	else if (intmask & (SDHCI_INT_CRC | SDHCI_INT_END_BIT |
+			SDHCI_INT_INDEX))
+		host->cmd->error = -EILSEQ;
 
-	if (host->cmd->error != MMC_ERR_NONE)
+	if (host->cmd->error)
 		tasklet_schedule(&host->finish_tasklet);
 	else if (intmask & SDHCI_INT_RESPONSE)
 		sdhci_finish_command(host);
@@ -974,13 +999,11 @@
 	}
 
 	if (intmask & SDHCI_INT_DATA_TIMEOUT)
-		host->data->error = MMC_ERR_TIMEOUT;
-	else if (intmask & SDHCI_INT_DATA_CRC)
-		host->data->error = MMC_ERR_BADCRC;
-	else if (intmask & SDHCI_INT_DATA_END_BIT)
-		host->data->error = MMC_ERR_FAILED;
+		host->data->error = -ETIMEDOUT;
+	else if (intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_END_BIT))
+		host->data->error = -EILSEQ;
 
-	if (host->data->error != MMC_ERR_NONE)
+	if (host->data->error)
 		sdhci_finish_data(host);
 	else {
 		if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL))
@@ -1015,6 +1038,7 @@
 	irqreturn_t result;
 	struct sdhci_host* host = dev_id;
 	u32 intmask;
+	int cardint = 0;
 
 	spin_lock(&host->lock);
 
@@ -1059,6 +1083,11 @@
 
 	intmask &= ~SDHCI_INT_BUS_POWER;
 
+	if (intmask & SDHCI_INT_CARD_INT)
+		cardint = 1;
+
+	intmask &= ~SDHCI_INT_CARD_INT;
+
 	if (intmask) {
 		printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n",
 			mmc_hostname(host->mmc), intmask);
@@ -1073,6 +1102,12 @@
 out:
 	spin_unlock(&host->lock);
 
+	/*
+	 * We have to delay this as it calls back into the driver.
+	 */
+	if (cardint)
+		mmc_signal_sdio_irq(host->mmc);
+
 	return result;
 }
 
@@ -1258,20 +1293,26 @@
 
 	caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
 
-	if (debug_nodma)
-		DBG("DMA forced off\n");
-	else if (debug_forcedma) {
-		DBG("DMA forced on\n");
+	if (chip->quirks & SDHCI_QUIRK_FORCE_DMA)
 		host->flags |= SDHCI_USE_DMA;
-	} else if (chip->quirks & SDHCI_QUIRK_FORCE_DMA)
-		host->flags |= SDHCI_USE_DMA;
-	else if ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA)
-		DBG("Controller doesn't have DMA interface\n");
 	else if (!(caps & SDHCI_CAN_DO_DMA))
 		DBG("Controller doesn't have DMA capability\n");
 	else
 		host->flags |= SDHCI_USE_DMA;
 
+	if ((chip->quirks & SDHCI_QUIRK_BROKEN_DMA) &&
+		(host->flags & SDHCI_USE_DMA)) {
+		DBG("Disabling DMA as it is marked broken");
+		host->flags &= ~SDHCI_USE_DMA;
+	}
+
+	if (((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) &&
+		(host->flags & SDHCI_USE_DMA)) {
+		printk(KERN_WARNING "%s: Will use DMA "
+			"mode even though HW doesn't fully "
+			"claim to support it.\n", host->slot_descr);
+	}
+
 	if (host->flags & SDHCI_USE_DMA) {
 		if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
 			printk(KERN_WARNING "%s: No suitable DMA available. "
@@ -1312,7 +1353,7 @@
 	mmc->ops = &sdhci_ops;
 	mmc->f_min = host->max_clk / 256;
 	mmc->f_max = host->max_clk;
-	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK;
+	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_SDIO_IRQ;
 
 	if (caps & SDHCI_CAN_DO_HISPD)
 		mmc->caps |= MMC_CAP_SD_HIGHSPEED;
@@ -1565,14 +1606,10 @@
 module_init(sdhci_drv_init);
 module_exit(sdhci_drv_exit);
 
-module_param(debug_nodma, uint, 0444);
-module_param(debug_forcedma, uint, 0444);
 module_param(debug_quirks, uint, 0444);
 
 MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
 MODULE_DESCRIPTION("Secure Digital Host Controller Interface driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM_DESC(debug_nodma, "Forcefully disable DMA transfers. (default 0)");
-MODULE_PARM_DESC(debug_forcedma, "Forcefully enable DMA transfers. (default 0)");
 MODULE_PARM_DESC(debug_quirks, "Force certain quirks.");
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index e28987d..05195ea 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -81,7 +81,7 @@
 
 #define SDHCI_BLOCK_GAP_CONTROL	0x2A
 
-#define SDHCI_WALK_UP_CONTROL	0x2B
+#define SDHCI_WAKE_UP_CONTROL	0x2B
 
 #define SDHCI_CLOCK_CONTROL	0x2C
 #define  SDHCI_DIVIDER_SHIFT	8
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c
index 8b736e9..9b90479 100644
--- a/drivers/mmc/host/tifm_sd.c
+++ b/drivers/mmc/host/tifm_sd.c
@@ -16,6 +16,7 @@
 #include <linux/mmc/host.h>
 #include <linux/highmem.h>
 #include <linux/scatterlist.h>
+#include <linux/log2.h>
 #include <asm/io.h>
 
 #define DRIVER_NAME "tifm_sd"
@@ -404,14 +405,14 @@
 	struct tifm_dev *sock = host->dev;
 	struct mmc_command *cmd = host->req->cmd;
 
-	if (cmd->error != MMC_ERR_NONE)
+	if (cmd->error)
 		goto finish_request;
 
 	if (!(host->cmd_flags & CMD_READY))
 		return;
 
 	if (cmd->data) {
-		if (cmd->data->error != MMC_ERR_NONE) {
+		if (cmd->data->error) {
 			if ((host->cmd_flags & SCMD_ACTIVE)
 			    && !(host->cmd_flags & SCMD_READY))
 				return;
@@ -504,7 +505,7 @@
 {
 	struct tifm_sd *host;
 	unsigned int host_status = 0;
-	int cmd_error = MMC_ERR_NONE;
+	int cmd_error = 0;
 	struct mmc_command *cmd = NULL;
 	unsigned long flags;
 
@@ -521,15 +522,15 @@
 			writel(host_status & TIFM_MMCSD_ERRMASK,
 			       sock->addr + SOCK_MMCSD_STATUS);
 			if (host_status & TIFM_MMCSD_CTO)
-				cmd_error = MMC_ERR_TIMEOUT;
+				cmd_error = -ETIMEDOUT;
 			else if (host_status & TIFM_MMCSD_CCRC)
-				cmd_error = MMC_ERR_BADCRC;
+				cmd_error = -EILSEQ;
 
 			if (cmd->data) {
 				if (host_status & TIFM_MMCSD_DTO)
-					cmd->data->error = MMC_ERR_TIMEOUT;
+					cmd->data->error = -ETIMEDOUT;
 				else if (host_status & TIFM_MMCSD_DCRC)
-					cmd->data->error = MMC_ERR_BADCRC;
+					cmd->data->error = -EILSEQ;
 			}
 
 			writel(TIFM_FIFO_INT_SETALL,
@@ -626,14 +627,21 @@
 
 	spin_lock_irqsave(&sock->lock, flags);
 	if (host->eject) {
-		spin_unlock_irqrestore(&sock->lock, flags);
+		mrq->cmd->error = -ENOMEDIUM;
 		goto err_out;
 	}
 
 	if (host->req) {
 		printk(KERN_ERR "%s : unfinished request detected\n",
 		       sock->dev.bus_id);
-		spin_unlock_irqrestore(&sock->lock, flags);
+		mrq->cmd->error = -ETIMEDOUT;
+		goto err_out;
+	}
+
+	if (mrq->data && !is_power_of_2(mrq->data->blksz)) {
+		printk(KERN_ERR "%s: Unsupported block size (%d bytes)\n",
+			sock->dev.bus_id, mrq->data->blksz);
+		mrq->cmd->error = -EINVAL;
 		goto err_out;
 	}
 
@@ -722,7 +730,7 @@
 	return;
 
 err_out:
-	mrq->cmd->error = MMC_ERR_TIMEOUT;
+	spin_unlock_irqrestore(&sock->lock, flags);
 	mmc_request_done(mmc, mrq);
 }
 
@@ -1012,9 +1020,9 @@
 		writel(TIFM_FIFO_INT_SETALL,
 		       sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
 		writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
-		host->req->cmd->error = MMC_ERR_TIMEOUT;
+		host->req->cmd->error = -ENOMEDIUM;
 		if (host->req->stop)
-			host->req->stop->error = MMC_ERR_TIMEOUT;
+			host->req->stop->error = -ENOMEDIUM;
 		tasklet_schedule(&host->finish_tasklet);
 	}
 	spin_unlock_irqrestore(&sock->lock, flags);
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index 9bf2a87..80db11c 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -317,7 +317,7 @@
 	 * Correct response type?
 	 */
 	if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_SHORT) {
-		cmd->error = MMC_ERR_INVALID;
+		cmd->error = -EILSEQ;
 		return;
 	}
 
@@ -337,7 +337,7 @@
 	 * Correct response type?
 	 */
 	if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_LONG) {
-		cmd->error = MMC_ERR_INVALID;
+		cmd->error = -EILSEQ;
 		return;
 	}
 
@@ -372,7 +372,7 @@
 	for (i = 3; i >= 0; i--)
 		outb((cmd->arg >> (i * 8)) & 0xff, host->base + WBSD_CMDR);
 
-	cmd->error = MMC_ERR_NONE;
+	cmd->error = 0;
 
 	/*
 	 * Wait for the request to complete.
@@ -392,13 +392,13 @@
 
 		/* Card removed? */
 		if (isr & WBSD_INT_CARD)
-			cmd->error = MMC_ERR_TIMEOUT;
+			cmd->error = -ENOMEDIUM;
 		/* Timeout? */
 		else if (isr & WBSD_INT_TIMEOUT)
-			cmd->error = MMC_ERR_TIMEOUT;
+			cmd->error = -ETIMEDOUT;
 		/* CRC? */
 		else if ((cmd->flags & MMC_RSP_CRC) && (isr & WBSD_INT_CRC))
-			cmd->error = MMC_ERR_BADCRC;
+			cmd->error = -EILSEQ;
 		/* All ok */
 		else {
 			if (cmd->flags & MMC_RSP_136)
@@ -585,7 +585,7 @@
 			((blksize >> 4) & 0xF0) | WBSD_DATA_WIDTH);
 		wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF);
 	} else {
-		data->error = MMC_ERR_INVALID;
+		data->error = -EINVAL;
 		return;
 	}
 
@@ -607,7 +607,7 @@
 		 */
 		BUG_ON(size > 0x10000);
 		if (size > 0x10000) {
-			data->error = MMC_ERR_INVALID;
+			data->error = -EINVAL;
 			return;
 		}
 
@@ -669,7 +669,7 @@
 		}
 	}
 
-	data->error = MMC_ERR_NONE;
+	data->error = 0;
 }
 
 static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data)
@@ -724,8 +724,8 @@
 				"%d bytes left.\n",
 				mmc_hostname(host->mmc), count);
 
-			if (data->error == MMC_ERR_NONE)
-				data->error = MMC_ERR_FAILED;
+			if (!data->error)
+				data->error = -EIO;
 		} else {
 			/*
 			 * Transfer data from DMA buffer to
@@ -735,7 +735,7 @@
 				wbsd_dma_to_sg(host, data);
 		}
 
-		if (data->error != MMC_ERR_NONE) {
+		if (data->error) {
 			if (data->bytes_xfered)
 				data->bytes_xfered -= data->blksz;
 		}
@@ -767,11 +767,10 @@
 	host->mrq = mrq;
 
 	/*
-	 * If there is no card in the slot then
-	 * timeout immediatly.
+	 * Check that there is actually a card in the slot.
 	 */
 	if (!(host->flags & WBSD_FCARD_PRESENT)) {
-		cmd->error = MMC_ERR_TIMEOUT;
+		cmd->error = -ENOMEDIUM;
 		goto done;
 	}
 
@@ -807,7 +806,7 @@
 				"supported by this controller.\n",
 				mmc_hostname(host->mmc), cmd->opcode);
 #endif
-			cmd->error = MMC_ERR_INVALID;
+			cmd->error = -EINVAL;
 
 			goto done;
 		};
@@ -819,7 +818,7 @@
 	if (cmd->data) {
 		wbsd_prepare_data(host, cmd->data);
 
-		if (cmd->data->error != MMC_ERR_NONE)
+		if (cmd->data->error)
 			goto done;
 	}
 
@@ -830,7 +829,7 @@
 	 * will be finished after the data has
 	 * transfered.
 	 */
-	if (cmd->data && (cmd->error == MMC_ERR_NONE)) {
+	if (cmd->data && !cmd->error) {
 		/*
 		 * Dirty fix for hardware bug.
 		 */
@@ -1033,7 +1032,7 @@
 				mmc_hostname(host->mmc));
 			wbsd_reset(host);
 
-			host->mrq->cmd->error = MMC_ERR_FAILED;
+			host->mrq->cmd->error = -ENOMEDIUM;
 			tasklet_schedule(&host->finish_tasklet);
 		}
 
@@ -1097,7 +1096,7 @@
 
 	DBGF("CRC error\n");
 
-	data->error = MMC_ERR_BADCRC;
+	data->error = -EILSEQ;
 
 	tasklet_schedule(&host->finish_tasklet);
 
@@ -1121,7 +1120,7 @@
 
 	DBGF("Timeout\n");
 
-	data->error = MMC_ERR_TIMEOUT;
+	data->error = -ETIMEDOUT;
 
 	tasklet_schedule(&host->finish_tasklet);
 
@@ -1220,7 +1219,7 @@
 	mmc->f_min = 375000;
 	mmc->f_max = 24000000;
 	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
-	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK;
+	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE;
 
 	spin_lock_init(&host->lock);
 
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
index d590a99..2305cc4 100644
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -45,7 +45,7 @@
 
 #include "cpqphp.h"
 #include "cpqphp_nvram.h"
-#include "../../../arch/i386/pci/pci.h"	/* horrible hack showing how processor dependent we are... */
+#include "../../../arch/x86/pci/pci.h"	/* horrible hack showing how processor dependent we are... */
 
 
 /* Global variables */
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
index fc7c74d..3f6cd20 100644
--- a/drivers/pci/hotplug/cpqphp_pci.c
+++ b/drivers/pci/hotplug/cpqphp_pci.c
@@ -37,7 +37,7 @@
 #include "../pci.h"
 #include "cpqphp.h"
 #include "cpqphp_nvram.h"
-#include "../../../arch/i386/pci/pci.h"	/* horrible hack showing how processor dependent we are... */
+#include "../../../arch/x86/pci/pci.h"	/* horrible hack showing how processor dependent we are... */
 
 
 u8 cpqhp_nic_irq;
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index 0316eea..a90c28d 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -35,7 +35,7 @@
 #include <linux/delay.h>
 #include <linux/wait.h>
 #include "../pci.h"
-#include "../../../arch/i386/pci/pci.h"	/* for struct irq_routing_table */
+#include "../../../arch/x86/pci/pci.h"	/* for struct irq_routing_table */
 #include "ibmphp.h"
 
 #define attn_on(sl)  ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNON)
diff --git a/include/asm-arm/arch-imx/mmc.h b/include/asm-arm/arch-imx/mmc.h
index 84c7269..4712f35 100644
--- a/include/asm-arm/arch-imx/mmc.h
+++ b/include/asm-arm/arch-imx/mmc.h
@@ -3,8 +3,11 @@
 
 #include <linux/mmc/host.h>
 
+struct device;
+
 struct imxmmc_platform_data {
-	int (*card_present)(void);
+	int (*card_present)(struct device *);
+	int (*get_ro)(struct device *);
 };
 
 extern void imx_set_mmc_info(struct imxmmc_platform_data *info);
diff --git a/include/asm-i386/Kbuild b/include/asm-i386/Kbuild
deleted file mode 100644
index cbf6e8f..0000000
--- a/include/asm-i386/Kbuild
+++ /dev/null
@@ -1,12 +0,0 @@
-include include/asm-generic/Kbuild.asm
-
-header-y += boot.h
-header-y += debugreg.h
-header-y += ldt.h
-header-y += msr-index.h
-header-y += ptrace-abi.h
-header-y += ucontext.h
-
-unifdef-y += msr.h
-unifdef-y += mtrr.h
-unifdef-y += vm86.h
diff --git a/include/asm-i386/k8.h b/include/asm-i386/k8.h
deleted file mode 100644
index dfd88a6..0000000
--- a/include/asm-i386/k8.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-x86_64/k8.h>
diff --git a/include/asm-i386/pci-direct.h b/include/asm-i386/pci-direct.h
deleted file mode 100644
index 4f6738b..0000000
--- a/include/asm-i386/pci-direct.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "asm-x86_64/pci-direct.h"
diff --git a/include/asm-i386/stacktrace.h b/include/asm-i386/stacktrace.h
deleted file mode 100644
index 7d1f6a5..0000000
--- a/include/asm-i386/stacktrace.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-x86_64/stacktrace.h>
diff --git a/include/asm-sh/mpc1211/mc146818rtc.h b/include/asm-sh/mpc1211/mc146818rtc.h
index 0ec78f6..e245f2a 100644
--- a/include/asm-sh/mpc1211/mc146818rtc.h
+++ b/include/asm-sh/mpc1211/mc146818rtc.h
@@ -1,6 +1,6 @@
 /*
  * MPC1211 uses PC/AT style RTC definitions.
  */
-#include <asm-i386/mc146818rtc.h>
+#include <asm-x86/mc146818rtc_32.h>
 
 
diff --git a/include/asm-x86/8253pit.h b/include/asm-x86/8253pit.h
new file mode 100644
index 0000000..d3c2b38
--- /dev/null
+++ b/include/asm-x86/8253pit.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "8253pit_32.h"
+#else
+# include "8253pit_64.h"
+#endif
diff --git a/include/asm-i386/8253pit.h b/include/asm-x86/8253pit_32.h
similarity index 100%
rename from include/asm-i386/8253pit.h
rename to include/asm-x86/8253pit_32.h
diff --git a/include/asm-x86_64/8253pit.h b/include/asm-x86/8253pit_64.h
similarity index 100%
rename from include/asm-x86_64/8253pit.h
rename to include/asm-x86/8253pit_64.h
diff --git a/include/asm-x86/Kbuild b/include/asm-x86/Kbuild
new file mode 100644
index 0000000..c5e43cb
--- /dev/null
+++ b/include/asm-x86/Kbuild
@@ -0,0 +1,88 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += boot.h
+header-y += bootsetup.h
+header-y += debugreg_32.h
+header-y += debugreg_64.h
+header-y += debugreg.h
+header-y += ldt_32.h
+header-y += ldt_64.h
+header-y += ldt.h
+header-y += msr-index.h
+header-y += prctl.h
+header-y += ptrace-abi_32.h
+header-y += ptrace-abi_64.h
+header-y += ptrace-abi.h
+header-y += sigcontext32.h
+header-y += ucontext_32.h
+header-y += ucontext_64.h
+header-y += ucontext.h
+header-y += vsyscall32.h
+
+unifdef-y += a.out_32.h
+unifdef-y += a.out_64.h
+unifdef-y += auxvec_32.h
+unifdef-y += auxvec_64.h
+unifdef-y += byteorder_32.h
+unifdef-y += byteorder_64.h
+unifdef-y += elf_32.h
+unifdef-y += elf_64.h
+unifdef-y += errno_32.h
+unifdef-y += errno_64.h
+unifdef-y += ioctls_32.h
+unifdef-y += ioctls_64.h
+unifdef-y += ipcbuf_32.h
+unifdef-y += ipcbuf_64.h
+unifdef-y += mce.h
+unifdef-y += mman_32.h
+unifdef-y += mman_64.h
+unifdef-y += msgbuf_32.h
+unifdef-y += msgbuf_64.h
+unifdef-y += msr_32.h
+unifdef-y += msr_64.h
+unifdef-y += msr.h
+unifdef-y += mtrr_32.h
+unifdef-y += mtrr_64.h
+unifdef-y += mtrr.h
+unifdef-y += page_32.h
+unifdef-y += page_64.h
+unifdef-y += param_32.h
+unifdef-y += param_64.h
+unifdef-y += posix_types_32.h
+unifdef-y += posix_types_64.h
+unifdef-y += ptrace_32.h
+unifdef-y += ptrace_64.h
+unifdef-y += resource_32.h
+unifdef-y += resource_64.h
+unifdef-y += sembuf_32.h
+unifdef-y += sembuf_64.h
+unifdef-y += setup_32.h
+unifdef-y += setup_64.h
+unifdef-y += shmbuf_32.h
+unifdef-y += shmbuf_64.h
+unifdef-y += shmparam_32.h
+unifdef-y += shmparam_64.h
+unifdef-y += sigcontext_32.h
+unifdef-y += sigcontext_64.h
+unifdef-y += siginfo_32.h
+unifdef-y += siginfo_64.h
+unifdef-y += signal_32.h
+unifdef-y += signal_64.h
+unifdef-y += sockios_32.h
+unifdef-y += sockios_64.h
+unifdef-y += stat_32.h
+unifdef-y += stat_64.h
+unifdef-y += statfs_32.h
+unifdef-y += statfs_64.h
+unifdef-y += termbits_32.h
+unifdef-y += termbits_64.h
+unifdef-y += termios_32.h
+unifdef-y += termios_64.h
+unifdef-y += types_32.h
+unifdef-y += types_64.h
+unifdef-y += unistd_32.h
+unifdef-y += unistd_64.h
+unifdef-y += user_32.h
+unifdef-y += user_64.h
+unifdef-y += vm86.h
+unifdef-y += vsyscall.h
diff --git a/include/asm-x86/a.out.h b/include/asm-x86/a.out.h
new file mode 100644
index 0000000..5bc9b1d
--- /dev/null
+++ b/include/asm-x86/a.out.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "a.out_32.h"
+# else
+#  include "a.out_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "a.out_32.h"
+# else
+#  include "a.out_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/a.out.h b/include/asm-x86/a.out_32.h
similarity index 100%
rename from include/asm-i386/a.out.h
rename to include/asm-x86/a.out_32.h
diff --git a/include/asm-x86_64/a.out.h b/include/asm-x86/a.out_64.h
similarity index 100%
rename from include/asm-x86_64/a.out.h
rename to include/asm-x86/a.out_64.h
diff --git a/include/asm-x86/acpi.h b/include/asm-x86/acpi.h
new file mode 100644
index 0000000..0693689
--- /dev/null
+++ b/include/asm-x86/acpi.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "acpi_32.h"
+#else
+# include "acpi_64.h"
+#endif
diff --git a/include/asm-i386/acpi.h b/include/asm-x86/acpi_32.h
similarity index 100%
rename from include/asm-i386/acpi.h
rename to include/asm-x86/acpi_32.h
diff --git a/include/asm-x86_64/acpi.h b/include/asm-x86/acpi_64.h
similarity index 100%
rename from include/asm-x86_64/acpi.h
rename to include/asm-x86/acpi_64.h
diff --git a/include/asm-x86/agp.h b/include/asm-x86/agp.h
new file mode 100644
index 0000000..9348f1e
--- /dev/null
+++ b/include/asm-x86/agp.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "agp_32.h"
+#else
+# include "agp_64.h"
+#endif
diff --git a/include/asm-i386/agp.h b/include/asm-x86/agp_32.h
similarity index 100%
rename from include/asm-i386/agp.h
rename to include/asm-x86/agp_32.h
diff --git a/include/asm-x86_64/agp.h b/include/asm-x86/agp_64.h
similarity index 100%
rename from include/asm-x86_64/agp.h
rename to include/asm-x86/agp_64.h
diff --git a/include/asm-x86/alternative-asm.i b/include/asm-x86/alternative-asm.i
new file mode 100644
index 0000000..4f360cd
--- /dev/null
+++ b/include/asm-x86/alternative-asm.i
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "alternative-asm_32.i"
+#else
+# include "alternative-asm_64.i"
+#endif
diff --git a/include/asm-i386/alternative-asm.i b/include/asm-x86/alternative-asm_32.i
similarity index 100%
rename from include/asm-i386/alternative-asm.i
rename to include/asm-x86/alternative-asm_32.i
diff --git a/include/asm-x86_64/alternative-asm.i b/include/asm-x86/alternative-asm_64.i
similarity index 100%
rename from include/asm-x86_64/alternative-asm.i
rename to include/asm-x86/alternative-asm_64.i
diff --git a/include/asm-x86/alternative.h b/include/asm-x86/alternative.h
new file mode 100644
index 0000000..9eef6a32
--- /dev/null
+++ b/include/asm-x86/alternative.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "alternative_32.h"
+#else
+# include "alternative_64.h"
+#endif
diff --git a/include/asm-i386/alternative.h b/include/asm-x86/alternative_32.h
similarity index 100%
rename from include/asm-i386/alternative.h
rename to include/asm-x86/alternative_32.h
diff --git a/include/asm-x86_64/alternative.h b/include/asm-x86/alternative_64.h
similarity index 100%
rename from include/asm-x86_64/alternative.h
rename to include/asm-x86/alternative_64.h
diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h
new file mode 100644
index 0000000..9fbcc0b
--- /dev/null
+++ b/include/asm-x86/apic.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "apic_32.h"
+#else
+# include "apic_64.h"
+#endif
diff --git a/include/asm-i386/apic.h b/include/asm-x86/apic_32.h
similarity index 100%
rename from include/asm-i386/apic.h
rename to include/asm-x86/apic_32.h
diff --git a/include/asm-x86_64/apic.h b/include/asm-x86/apic_64.h
similarity index 100%
rename from include/asm-x86_64/apic.h
rename to include/asm-x86/apic_64.h
diff --git a/include/asm-x86/apicdef.h b/include/asm-x86/apicdef.h
new file mode 100644
index 0000000..4542c22
--- /dev/null
+++ b/include/asm-x86/apicdef.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "apicdef_32.h"
+#else
+# include "apicdef_64.h"
+#endif
diff --git a/include/asm-i386/apicdef.h b/include/asm-x86/apicdef_32.h
similarity index 100%
rename from include/asm-i386/apicdef.h
rename to include/asm-x86/apicdef_32.h
diff --git a/include/asm-x86_64/apicdef.h b/include/asm-x86/apicdef_64.h
similarity index 100%
rename from include/asm-x86_64/apicdef.h
rename to include/asm-x86/apicdef_64.h
diff --git a/include/asm-i386/arch_hooks.h b/include/asm-x86/arch_hooks.h
similarity index 100%
rename from include/asm-i386/arch_hooks.h
rename to include/asm-x86/arch_hooks.h
diff --git a/include/asm-x86/atomic.h b/include/asm-x86/atomic.h
new file mode 100644
index 0000000..4e1b887
--- /dev/null
+++ b/include/asm-x86/atomic.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "atomic_32.h"
+#else
+# include "atomic_64.h"
+#endif
diff --git a/include/asm-i386/atomic.h b/include/asm-x86/atomic_32.h
similarity index 100%
rename from include/asm-i386/atomic.h
rename to include/asm-x86/atomic_32.h
diff --git a/include/asm-x86_64/atomic.h b/include/asm-x86/atomic_64.h
similarity index 100%
rename from include/asm-x86_64/atomic.h
rename to include/asm-x86/atomic_64.h
diff --git a/include/asm-x86/auxvec.h b/include/asm-x86/auxvec.h
new file mode 100644
index 0000000..7ff866f
--- /dev/null
+++ b/include/asm-x86/auxvec.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "auxvec_32.h"
+# else
+#  include "auxvec_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "auxvec_32.h"
+# else
+#  include "auxvec_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/auxvec.h b/include/asm-x86/auxvec_32.h
similarity index 100%
rename from include/asm-i386/auxvec.h
rename to include/asm-x86/auxvec_32.h
diff --git a/include/asm-x86_64/auxvec.h b/include/asm-x86/auxvec_64.h
similarity index 100%
rename from include/asm-x86_64/auxvec.h
rename to include/asm-x86/auxvec_64.h
diff --git a/include/asm-x86/bitops.h b/include/asm-x86/bitops.h
new file mode 100644
index 0000000..07e3f6d
--- /dev/null
+++ b/include/asm-x86/bitops.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "bitops_32.h"
+#else
+# include "bitops_64.h"
+#endif
diff --git a/include/asm-i386/bitops.h b/include/asm-x86/bitops_32.h
similarity index 100%
rename from include/asm-i386/bitops.h
rename to include/asm-x86/bitops_32.h
diff --git a/include/asm-x86_64/bitops.h b/include/asm-x86/bitops_64.h
similarity index 100%
rename from include/asm-x86_64/bitops.h
rename to include/asm-x86/bitops_64.h
diff --git a/include/asm-i386/boot.h b/include/asm-x86/boot.h
similarity index 100%
rename from include/asm-i386/boot.h
rename to include/asm-x86/boot.h
diff --git a/include/asm-i386/bootparam.h b/include/asm-x86/bootparam.h
similarity index 100%
rename from include/asm-i386/bootparam.h
rename to include/asm-x86/bootparam.h
diff --git a/include/asm-x86_64/bootsetup.h b/include/asm-x86/bootsetup.h
similarity index 100%
rename from include/asm-x86_64/bootsetup.h
rename to include/asm-x86/bootsetup.h
diff --git a/include/asm-x86/bug.h b/include/asm-x86/bug.h
new file mode 100644
index 0000000..c655d7f
--- /dev/null
+++ b/include/asm-x86/bug.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "bug_32.h"
+#else
+# include "bug_64.h"
+#endif
diff --git a/include/asm-i386/bug.h b/include/asm-x86/bug_32.h
similarity index 100%
rename from include/asm-i386/bug.h
rename to include/asm-x86/bug_32.h
diff --git a/include/asm-x86_64/bug.h b/include/asm-x86/bug_64.h
similarity index 100%
rename from include/asm-x86_64/bug.h
rename to include/asm-x86/bug_64.h
diff --git a/include/asm-x86/bugs.h b/include/asm-x86/bugs.h
new file mode 100644
index 0000000..ddf42d3
--- /dev/null
+++ b/include/asm-x86/bugs.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "bugs_32.h"
+#else
+# include "bugs_64.h"
+#endif
diff --git a/include/asm-i386/bugs.h b/include/asm-x86/bugs_32.h
similarity index 100%
rename from include/asm-i386/bugs.h
rename to include/asm-x86/bugs_32.h
diff --git a/include/asm-x86_64/bugs.h b/include/asm-x86/bugs_64.h
similarity index 100%
rename from include/asm-x86_64/bugs.h
rename to include/asm-x86/bugs_64.h
diff --git a/include/asm-x86/byteorder.h b/include/asm-x86/byteorder.h
new file mode 100644
index 0000000..eb14b18
--- /dev/null
+++ b/include/asm-x86/byteorder.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "byteorder_32.h"
+# else
+#  include "byteorder_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "byteorder_32.h"
+# else
+#  include "byteorder_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/byteorder.h b/include/asm-x86/byteorder_32.h
similarity index 100%
rename from include/asm-i386/byteorder.h
rename to include/asm-x86/byteorder_32.h
diff --git a/include/asm-x86_64/byteorder.h b/include/asm-x86/byteorder_64.h
similarity index 100%
rename from include/asm-x86_64/byteorder.h
rename to include/asm-x86/byteorder_64.h
diff --git a/include/asm-x86/cache.h b/include/asm-x86/cache.h
new file mode 100644
index 0000000..c36d190
--- /dev/null
+++ b/include/asm-x86/cache.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "cache_32.h"
+#else
+# include "cache_64.h"
+#endif
diff --git a/include/asm-i386/cache.h b/include/asm-x86/cache_32.h
similarity index 100%
rename from include/asm-i386/cache.h
rename to include/asm-x86/cache_32.h
diff --git a/include/asm-x86_64/cache.h b/include/asm-x86/cache_64.h
similarity index 100%
rename from include/asm-x86_64/cache.h
rename to include/asm-x86/cache_64.h
diff --git a/include/asm-x86/cacheflush.h b/include/asm-x86/cacheflush.h
new file mode 100644
index 0000000..e2df3b5
--- /dev/null
+++ b/include/asm-x86/cacheflush.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "cacheflush_32.h"
+#else
+# include "cacheflush_64.h"
+#endif
diff --git a/include/asm-i386/cacheflush.h b/include/asm-x86/cacheflush_32.h
similarity index 100%
rename from include/asm-i386/cacheflush.h
rename to include/asm-x86/cacheflush_32.h
diff --git a/include/asm-x86_64/cacheflush.h b/include/asm-x86/cacheflush_64.h
similarity index 100%
rename from include/asm-x86_64/cacheflush.h
rename to include/asm-x86/cacheflush_64.h
diff --git a/include/asm-x86_64/calgary.h b/include/asm-x86/calgary.h
similarity index 100%
rename from include/asm-x86_64/calgary.h
rename to include/asm-x86/calgary.h
diff --git a/include/asm-x86_64/calling.h b/include/asm-x86/calling.h
similarity index 100%
rename from include/asm-x86_64/calling.h
rename to include/asm-x86/calling.h
diff --git a/include/asm-x86/checksum.h b/include/asm-x86/checksum.h
new file mode 100644
index 0000000..848850f
--- /dev/null
+++ b/include/asm-x86/checksum.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "checksum_32.h"
+#else
+# include "checksum_64.h"
+#endif
diff --git a/include/asm-i386/checksum.h b/include/asm-x86/checksum_32.h
similarity index 100%
rename from include/asm-i386/checksum.h
rename to include/asm-x86/checksum_32.h
diff --git a/include/asm-x86_64/checksum.h b/include/asm-x86/checksum_64.h
similarity index 100%
rename from include/asm-x86_64/checksum.h
rename to include/asm-x86/checksum_64.h
diff --git a/include/asm-x86/cmpxchg.h b/include/asm-x86/cmpxchg.h
new file mode 100644
index 0000000..a460fa0
--- /dev/null
+++ b/include/asm-x86/cmpxchg.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "cmpxchg_32.h"
+#else
+# include "cmpxchg_64.h"
+#endif
diff --git a/include/asm-i386/cmpxchg.h b/include/asm-x86/cmpxchg_32.h
similarity index 100%
rename from include/asm-i386/cmpxchg.h
rename to include/asm-x86/cmpxchg_32.h
diff --git a/include/asm-x86_64/cmpxchg.h b/include/asm-x86/cmpxchg_64.h
similarity index 100%
rename from include/asm-x86_64/cmpxchg.h
rename to include/asm-x86/cmpxchg_64.h
diff --git a/include/asm-x86_64/compat.h b/include/asm-x86/compat.h
similarity index 100%
rename from include/asm-x86_64/compat.h
rename to include/asm-x86/compat.h
diff --git a/include/asm-i386/cpu.h b/include/asm-x86/cpu.h
similarity index 100%
rename from include/asm-i386/cpu.h
rename to include/asm-x86/cpu.h
diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h
new file mode 100644
index 0000000..b7160a4
--- /dev/null
+++ b/include/asm-x86/cpufeature.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "cpufeature_32.h"
+#else
+# include "cpufeature_64.h"
+#endif
diff --git a/include/asm-i386/cpufeature.h b/include/asm-x86/cpufeature_32.h
similarity index 100%
rename from include/asm-i386/cpufeature.h
rename to include/asm-x86/cpufeature_32.h
diff --git a/include/asm-x86_64/cpufeature.h b/include/asm-x86/cpufeature_64.h
similarity index 90%
rename from include/asm-x86_64/cpufeature.h
rename to include/asm-x86/cpufeature_64.h
index 8baefc3..2983501 100644
--- a/include/asm-x86_64/cpufeature.h
+++ b/include/asm-x86/cpufeature_64.h
@@ -1,5 +1,5 @@
 /*
- * cpufeature.h
+ * cpufeature_32.h
  *
  * Defines x86 CPU feature bits
  */
@@ -7,7 +7,7 @@
 #ifndef __ASM_X8664_CPUFEATURE_H
 #define __ASM_X8664_CPUFEATURE_H
 
-#include <asm-i386/cpufeature.h>
+#include <asm/cpufeature_32.h>
 
 #undef  cpu_has_vme
 #define cpu_has_vme            0
diff --git a/include/asm-x86/cputime.h b/include/asm-x86/cputime.h
new file mode 100644
index 0000000..87c37cf
--- /dev/null
+++ b/include/asm-x86/cputime.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "cputime_32.h"
+#else
+# include "cputime_64.h"
+#endif
diff --git a/include/asm-i386/cputime.h b/include/asm-x86/cputime_32.h
similarity index 100%
rename from include/asm-i386/cputime.h
rename to include/asm-x86/cputime_32.h
diff --git a/include/asm-x86_64/cputime.h b/include/asm-x86/cputime_64.h
similarity index 100%
rename from include/asm-x86_64/cputime.h
rename to include/asm-x86/cputime_64.h
diff --git a/include/asm-x86/current.h b/include/asm-x86/current.h
new file mode 100644
index 0000000..d2526d3
--- /dev/null
+++ b/include/asm-x86/current.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "current_32.h"
+#else
+# include "current_64.h"
+#endif
diff --git a/include/asm-i386/current.h b/include/asm-x86/current_32.h
similarity index 100%
rename from include/asm-i386/current.h
rename to include/asm-x86/current_32.h
diff --git a/include/asm-x86_64/current.h b/include/asm-x86/current_64.h
similarity index 100%
rename from include/asm-x86_64/current.h
rename to include/asm-x86/current_64.h
diff --git a/include/asm-x86/debugreg.h b/include/asm-x86/debugreg.h
new file mode 100644
index 0000000..b6ce7e4
--- /dev/null
+++ b/include/asm-x86/debugreg.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "debugreg_32.h"
+# else
+#  include "debugreg_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "debugreg_32.h"
+# else
+#  include "debugreg_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/debugreg.h b/include/asm-x86/debugreg_32.h
similarity index 100%
rename from include/asm-i386/debugreg.h
rename to include/asm-x86/debugreg_32.h
diff --git a/include/asm-x86_64/debugreg.h b/include/asm-x86/debugreg_64.h
similarity index 100%
rename from include/asm-x86_64/debugreg.h
rename to include/asm-x86/debugreg_64.h
diff --git a/include/asm-x86/delay.h b/include/asm-x86/delay.h
new file mode 100644
index 0000000..10f2c71
--- /dev/null
+++ b/include/asm-x86/delay.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "delay_32.h"
+#else
+# include "delay_64.h"
+#endif
diff --git a/include/asm-i386/delay.h b/include/asm-x86/delay_32.h
similarity index 100%
rename from include/asm-i386/delay.h
rename to include/asm-x86/delay_32.h
diff --git a/include/asm-x86_64/delay.h b/include/asm-x86/delay_64.h
similarity index 100%
rename from include/asm-x86_64/delay.h
rename to include/asm-x86/delay_64.h
diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h
new file mode 100644
index 0000000..6065c50
--- /dev/null
+++ b/include/asm-x86/desc.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "desc_32.h"
+#else
+# include "desc_64.h"
+#endif
diff --git a/include/asm-i386/desc.h b/include/asm-x86/desc_32.h
similarity index 100%
rename from include/asm-i386/desc.h
rename to include/asm-x86/desc_32.h
diff --git a/include/asm-x86_64/desc.h b/include/asm-x86/desc_64.h
similarity index 100%
rename from include/asm-x86_64/desc.h
rename to include/asm-x86/desc_64.h
diff --git a/include/asm-x86_64/desc_defs.h b/include/asm-x86/desc_defs.h
similarity index 100%
rename from include/asm-x86_64/desc_defs.h
rename to include/asm-x86/desc_defs.h
diff --git a/include/asm-x86/device.h b/include/asm-x86/device.h
new file mode 100644
index 0000000..e2bcf7c
--- /dev/null
+++ b/include/asm-x86/device.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "device_32.h"
+#else
+# include "device_64.h"
+#endif
diff --git a/include/asm-i386/device.h b/include/asm-x86/device_32.h
similarity index 100%
rename from include/asm-i386/device.h
rename to include/asm-x86/device_32.h
diff --git a/include/asm-x86_64/device.h b/include/asm-x86/device_64.h
similarity index 100%
rename from include/asm-x86_64/device.h
rename to include/asm-x86/device_64.h
diff --git a/include/asm-x86/div64.h b/include/asm-x86/div64.h
new file mode 100644
index 0000000..8ac7da6
--- /dev/null
+++ b/include/asm-x86/div64.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "div64_32.h"
+#else
+# include "div64_64.h"
+#endif
diff --git a/include/asm-i386/div64.h b/include/asm-x86/div64_32.h
similarity index 100%
rename from include/asm-i386/div64.h
rename to include/asm-x86/div64_32.h
diff --git a/include/asm-x86_64/div64.h b/include/asm-x86/div64_64.h
similarity index 100%
rename from include/asm-x86_64/div64.h
rename to include/asm-x86/div64_64.h
diff --git a/include/asm-x86/dma-mapping.h b/include/asm-x86/dma-mapping.h
new file mode 100644
index 0000000..58f790f
--- /dev/null
+++ b/include/asm-x86/dma-mapping.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "dma-mapping_32.h"
+#else
+# include "dma-mapping_64.h"
+#endif
diff --git a/include/asm-i386/dma-mapping.h b/include/asm-x86/dma-mapping_32.h
similarity index 100%
rename from include/asm-i386/dma-mapping.h
rename to include/asm-x86/dma-mapping_32.h
diff --git a/include/asm-x86_64/dma-mapping.h b/include/asm-x86/dma-mapping_64.h
similarity index 100%
rename from include/asm-x86_64/dma-mapping.h
rename to include/asm-x86/dma-mapping_64.h
diff --git a/include/asm-x86/dma.h b/include/asm-x86/dma.h
new file mode 100644
index 0000000..9f936c6
--- /dev/null
+++ b/include/asm-x86/dma.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "dma_32.h"
+#else
+# include "dma_64.h"
+#endif
diff --git a/include/asm-i386/dma.h b/include/asm-x86/dma_32.h
similarity index 100%
rename from include/asm-i386/dma.h
rename to include/asm-x86/dma_32.h
diff --git a/include/asm-x86_64/dma.h b/include/asm-x86/dma_64.h
similarity index 100%
rename from include/asm-x86_64/dma.h
rename to include/asm-x86/dma_64.h
diff --git a/include/asm-x86/dmi.h b/include/asm-x86/dmi.h
new file mode 100644
index 0000000..c9e4e8e
--- /dev/null
+++ b/include/asm-x86/dmi.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "dmi_32.h"
+#else
+# include "dmi_64.h"
+#endif
diff --git a/include/asm-i386/dmi.h b/include/asm-x86/dmi_32.h
similarity index 100%
rename from include/asm-i386/dmi.h
rename to include/asm-x86/dmi_32.h
diff --git a/include/asm-x86_64/dmi.h b/include/asm-x86/dmi_64.h
similarity index 100%
rename from include/asm-x86_64/dmi.h
rename to include/asm-x86/dmi_64.h
diff --git a/include/asm-x86/dwarf2.h b/include/asm-x86/dwarf2.h
new file mode 100644
index 0000000..b3cbb0c
--- /dev/null
+++ b/include/asm-x86/dwarf2.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "dwarf2_32.h"
+#else
+# include "dwarf2_64.h"
+#endif
diff --git a/include/asm-i386/dwarf2.h b/include/asm-x86/dwarf2_32.h
similarity index 100%
rename from include/asm-i386/dwarf2.h
rename to include/asm-x86/dwarf2_32.h
diff --git a/include/asm-x86_64/dwarf2.h b/include/asm-x86/dwarf2_64.h
similarity index 100%
rename from include/asm-x86_64/dwarf2.h
rename to include/asm-x86/dwarf2_64.h
diff --git a/include/asm-x86/e820.h b/include/asm-x86/e820.h
new file mode 100644
index 0000000..5d4d218
--- /dev/null
+++ b/include/asm-x86/e820.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "e820_32.h"
+#else
+# include "e820_64.h"
+#endif
diff --git a/include/asm-i386/e820.h b/include/asm-x86/e820_32.h
similarity index 100%
rename from include/asm-i386/e820.h
rename to include/asm-x86/e820_32.h
diff --git a/include/asm-x86_64/e820.h b/include/asm-x86/e820_64.h
similarity index 100%
rename from include/asm-x86_64/e820.h
rename to include/asm-x86/e820_64.h
diff --git a/include/asm-x86/edac.h b/include/asm-x86/edac.h
new file mode 100644
index 0000000..f8b888e
--- /dev/null
+++ b/include/asm-x86/edac.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "edac_32.h"
+#else
+# include "edac_64.h"
+#endif
diff --git a/include/asm-i386/edac.h b/include/asm-x86/edac_32.h
similarity index 100%
rename from include/asm-i386/edac.h
rename to include/asm-x86/edac_32.h
diff --git a/include/asm-x86_64/edac.h b/include/asm-x86/edac_64.h
similarity index 100%
rename from include/asm-x86_64/edac.h
rename to include/asm-x86/edac_64.h
diff --git a/include/asm-x86/elf.h b/include/asm-x86/elf.h
new file mode 100644
index 0000000..ed6bb6e
--- /dev/null
+++ b/include/asm-x86/elf.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "elf_32.h"
+# else
+#  include "elf_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "elf_32.h"
+# else
+#  include "elf_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/elf.h b/include/asm-x86/elf_32.h
similarity index 100%
rename from include/asm-i386/elf.h
rename to include/asm-x86/elf_32.h
diff --git a/include/asm-x86_64/elf.h b/include/asm-x86/elf_64.h
similarity index 100%
rename from include/asm-x86_64/elf.h
rename to include/asm-x86/elf_64.h
diff --git a/include/asm-i386/emergency-restart.h b/include/asm-x86/emergency-restart.h
similarity index 100%
rename from include/asm-i386/emergency-restart.h
rename to include/asm-x86/emergency-restart.h
diff --git a/include/asm-x86/errno.h b/include/asm-x86/errno.h
new file mode 100644
index 0000000..9d511be
--- /dev/null
+++ b/include/asm-x86/errno.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "errno_32.h"
+# else
+#  include "errno_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "errno_32.h"
+# else
+#  include "errno_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/errno.h b/include/asm-x86/errno_32.h
similarity index 100%
rename from include/asm-i386/errno.h
rename to include/asm-x86/errno_32.h
diff --git a/include/asm-x86_64/errno.h b/include/asm-x86/errno_64.h
similarity index 100%
rename from include/asm-x86_64/errno.h
rename to include/asm-x86/errno_64.h
diff --git a/include/asm-x86/fb.h b/include/asm-x86/fb.h
new file mode 100644
index 0000000..238c7ca
--- /dev/null
+++ b/include/asm-x86/fb.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "fb_32.h"
+#else
+# include "fb_64.h"
+#endif
diff --git a/include/asm-i386/fb.h b/include/asm-x86/fb_32.h
similarity index 100%
rename from include/asm-i386/fb.h
rename to include/asm-x86/fb_32.h
diff --git a/include/asm-x86_64/fb.h b/include/asm-x86/fb_64.h
similarity index 100%
rename from include/asm-x86_64/fb.h
rename to include/asm-x86/fb_64.h
diff --git a/include/asm-i386/fcntl.h b/include/asm-x86/fcntl.h
similarity index 100%
rename from include/asm-i386/fcntl.h
rename to include/asm-x86/fcntl.h
diff --git a/include/asm-x86/fixmap.h b/include/asm-x86/fixmap.h
new file mode 100644
index 0000000..382eb27
--- /dev/null
+++ b/include/asm-x86/fixmap.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "fixmap_32.h"
+#else
+# include "fixmap_64.h"
+#endif
diff --git a/include/asm-i386/fixmap.h b/include/asm-x86/fixmap_32.h
similarity index 100%
rename from include/asm-i386/fixmap.h
rename to include/asm-x86/fixmap_32.h
diff --git a/include/asm-x86_64/fixmap.h b/include/asm-x86/fixmap_64.h
similarity index 100%
rename from include/asm-x86_64/fixmap.h
rename to include/asm-x86/fixmap_64.h
diff --git a/include/asm-x86/floppy.h b/include/asm-x86/floppy.h
new file mode 100644
index 0000000..aecbb6d
--- /dev/null
+++ b/include/asm-x86/floppy.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "floppy_32.h"
+#else
+# include "floppy_64.h"
+#endif
diff --git a/include/asm-i386/floppy.h b/include/asm-x86/floppy_32.h
similarity index 100%
rename from include/asm-i386/floppy.h
rename to include/asm-x86/floppy_32.h
diff --git a/include/asm-x86_64/floppy.h b/include/asm-x86/floppy_64.h
similarity index 100%
rename from include/asm-x86_64/floppy.h
rename to include/asm-x86/floppy_64.h
diff --git a/include/asm-x86_64/fpu32.h b/include/asm-x86/fpu32.h
similarity index 100%
rename from include/asm-x86_64/fpu32.h
rename to include/asm-x86/fpu32.h
diff --git a/include/asm-i386/frame.i b/include/asm-x86/frame.i
similarity index 100%
rename from include/asm-i386/frame.i
rename to include/asm-x86/frame.i
diff --git a/include/asm-x86/futex.h b/include/asm-x86/futex.h
new file mode 100644
index 0000000..1f4610e
--- /dev/null
+++ b/include/asm-x86/futex.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "futex_32.h"
+#else
+# include "futex_64.h"
+#endif
diff --git a/include/asm-i386/futex.h b/include/asm-x86/futex_32.h
similarity index 100%
rename from include/asm-i386/futex.h
rename to include/asm-x86/futex_32.h
diff --git a/include/asm-x86_64/futex.h b/include/asm-x86/futex_64.h
similarity index 100%
rename from include/asm-x86_64/futex.h
rename to include/asm-x86/futex_64.h
diff --git a/include/asm-x86/genapic.h b/include/asm-x86/genapic.h
new file mode 100644
index 0000000..d48bee6
--- /dev/null
+++ b/include/asm-x86/genapic.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "genapic_32.h"
+#else
+# include "genapic_64.h"
+#endif
diff --git a/include/asm-i386/genapic.h b/include/asm-x86/genapic_32.h
similarity index 100%
rename from include/asm-i386/genapic.h
rename to include/asm-x86/genapic_32.h
diff --git a/include/asm-x86_64/genapic.h b/include/asm-x86/genapic_64.h
similarity index 100%
rename from include/asm-x86_64/genapic.h
rename to include/asm-x86/genapic_64.h
diff --git a/include/asm-i386/geode.h b/include/asm-x86/geode.h
similarity index 100%
rename from include/asm-i386/geode.h
rename to include/asm-x86/geode.h
diff --git a/include/asm-x86/hardirq.h b/include/asm-x86/hardirq.h
new file mode 100644
index 0000000..314434d
--- /dev/null
+++ b/include/asm-x86/hardirq.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "hardirq_32.h"
+#else
+# include "hardirq_64.h"
+#endif
diff --git a/include/asm-i386/hardirq.h b/include/asm-x86/hardirq_32.h
similarity index 100%
rename from include/asm-i386/hardirq.h
rename to include/asm-x86/hardirq_32.h
diff --git a/include/asm-x86_64/hardirq.h b/include/asm-x86/hardirq_64.h
similarity index 100%
rename from include/asm-x86_64/hardirq.h
rename to include/asm-x86/hardirq_64.h
diff --git a/include/asm-i386/highmem.h b/include/asm-x86/highmem.h
similarity index 100%
rename from include/asm-i386/highmem.h
rename to include/asm-x86/highmem.h
diff --git a/include/asm-x86/hpet.h b/include/asm-x86/hpet.h
new file mode 100644
index 0000000..9eff486
--- /dev/null
+++ b/include/asm-x86/hpet.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "hpet_32.h"
+#else
+# include "hpet_64.h"
+#endif
diff --git a/include/asm-i386/hpet.h b/include/asm-x86/hpet_32.h
similarity index 100%
rename from include/asm-i386/hpet.h
rename to include/asm-x86/hpet_32.h
diff --git a/include/asm-x86_64/hpet.h b/include/asm-x86/hpet_64.h
similarity index 93%
rename from include/asm-x86_64/hpet.h
rename to include/asm-x86/hpet_64.h
index 79bb950..fd4deca 100644
--- a/include/asm-x86_64/hpet.h
+++ b/include/asm-x86/hpet_64.h
@@ -1,7 +1,7 @@
 #ifndef _ASM_X8664_HPET_H
 #define _ASM_X8664_HPET_H 1
 
-#include <asm-i386/hpet.h>
+#include <asm/hpet_32.h>
 
 #define HPET_TICK_RATE (HZ * 100000UL)
 
diff --git a/include/asm-x86/hw_irq.h b/include/asm-x86/hw_irq.h
new file mode 100644
index 0000000..bf02539
--- /dev/null
+++ b/include/asm-x86/hw_irq.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "hw_irq_32.h"
+#else
+# include "hw_irq_64.h"
+#endif
diff --git a/include/asm-i386/hw_irq.h b/include/asm-x86/hw_irq_32.h
similarity index 100%
rename from include/asm-i386/hw_irq.h
rename to include/asm-x86/hw_irq_32.h
diff --git a/include/asm-x86_64/hw_irq.h b/include/asm-x86/hw_irq_64.h
similarity index 100%
rename from include/asm-x86_64/hw_irq.h
rename to include/asm-x86/hw_irq_64.h
diff --git a/include/asm-i386/hypertransport.h b/include/asm-x86/hypertransport.h
similarity index 100%
rename from include/asm-i386/hypertransport.h
rename to include/asm-x86/hypertransport.h
diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h
new file mode 100644
index 0000000..a8bbed3
--- /dev/null
+++ b/include/asm-x86/i387.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "i387_32.h"
+#else
+# include "i387_64.h"
+#endif
diff --git a/include/asm-i386/i387.h b/include/asm-x86/i387_32.h
similarity index 100%
rename from include/asm-i386/i387.h
rename to include/asm-x86/i387_32.h
diff --git a/include/asm-x86_64/i387.h b/include/asm-x86/i387_64.h
similarity index 100%
rename from include/asm-x86_64/i387.h
rename to include/asm-x86/i387_64.h
diff --git a/include/asm-x86/i8253.h b/include/asm-x86/i8253.h
new file mode 100644
index 0000000..b2a4f99
--- /dev/null
+++ b/include/asm-x86/i8253.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "i8253_32.h"
+#else
+# include "i8253_64.h"
+#endif
diff --git a/include/asm-i386/i8253.h b/include/asm-x86/i8253_32.h
similarity index 100%
rename from include/asm-i386/i8253.h
rename to include/asm-x86/i8253_32.h
diff --git a/include/asm-x86_64/i8253.h b/include/asm-x86/i8253_64.h
similarity index 100%
rename from include/asm-x86_64/i8253.h
rename to include/asm-x86/i8253_64.h
diff --git a/include/asm-i386/i8259.h b/include/asm-x86/i8259.h
similarity index 100%
rename from include/asm-i386/i8259.h
rename to include/asm-x86/i8259.h
diff --git a/include/asm-x86_64/ia32.h b/include/asm-x86/ia32.h
similarity index 100%
rename from include/asm-x86_64/ia32.h
rename to include/asm-x86/ia32.h
diff --git a/include/asm-x86_64/ia32_unistd.h b/include/asm-x86/ia32_unistd.h
similarity index 100%
rename from include/asm-x86_64/ia32_unistd.h
rename to include/asm-x86/ia32_unistd.h
diff --git a/include/asm-i386/ide.h b/include/asm-x86/ide.h
similarity index 100%
rename from include/asm-i386/ide.h
rename to include/asm-x86/ide.h
diff --git a/include/asm-x86_64/idle.h b/include/asm-x86/idle.h
similarity index 100%
rename from include/asm-x86_64/idle.h
rename to include/asm-x86/idle.h
diff --git a/include/asm-x86/intel_arch_perfmon.h b/include/asm-x86/intel_arch_perfmon.h
new file mode 100644
index 0000000..4f6d4e6
--- /dev/null
+++ b/include/asm-x86/intel_arch_perfmon.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "intel_arch_perfmon_32.h"
+#else
+# include "intel_arch_perfmon_64.h"
+#endif
diff --git a/include/asm-i386/intel_arch_perfmon.h b/include/asm-x86/intel_arch_perfmon_32.h
similarity index 100%
rename from include/asm-i386/intel_arch_perfmon.h
rename to include/asm-x86/intel_arch_perfmon_32.h
diff --git a/include/asm-x86_64/intel_arch_perfmon.h b/include/asm-x86/intel_arch_perfmon_64.h
similarity index 100%
rename from include/asm-x86_64/intel_arch_perfmon.h
rename to include/asm-x86/intel_arch_perfmon_64.h
diff --git a/include/asm-x86/io.h b/include/asm-x86/io.h
new file mode 100644
index 0000000..5a58b17
--- /dev/null
+++ b/include/asm-x86/io.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "io_32.h"
+#else
+# include "io_64.h"
+#endif
diff --git a/include/asm-i386/io.h b/include/asm-x86/io_32.h
similarity index 100%
rename from include/asm-i386/io.h
rename to include/asm-x86/io_32.h
diff --git a/include/asm-x86_64/io.h b/include/asm-x86/io_64.h
similarity index 100%
rename from include/asm-x86_64/io.h
rename to include/asm-x86/io_64.h
diff --git a/include/asm-x86/io_apic.h b/include/asm-x86/io_apic.h
new file mode 100644
index 0000000..88494966
--- /dev/null
+++ b/include/asm-x86/io_apic.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "io_apic_32.h"
+#else
+# include "io_apic_64.h"
+#endif
diff --git a/include/asm-i386/io_apic.h b/include/asm-x86/io_apic_32.h
similarity index 100%
rename from include/asm-i386/io_apic.h
rename to include/asm-x86/io_apic_32.h
diff --git a/include/asm-x86_64/io_apic.h b/include/asm-x86/io_apic_64.h
similarity index 100%
rename from include/asm-x86_64/io_apic.h
rename to include/asm-x86/io_apic_64.h
diff --git a/include/asm-i386/ioctl.h b/include/asm-x86/ioctl.h
similarity index 100%
rename from include/asm-i386/ioctl.h
rename to include/asm-x86/ioctl.h
diff --git a/include/asm-x86/ioctls.h b/include/asm-x86/ioctls.h
new file mode 100644
index 0000000..1e0fd48
--- /dev/null
+++ b/include/asm-x86/ioctls.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "ioctls_32.h"
+# else
+#  include "ioctls_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "ioctls_32.h"
+# else
+#  include "ioctls_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/ioctls.h b/include/asm-x86/ioctls_32.h
similarity index 100%
rename from include/asm-i386/ioctls.h
rename to include/asm-x86/ioctls_32.h
diff --git a/include/asm-x86_64/ioctls.h b/include/asm-x86/ioctls_64.h
similarity index 100%
rename from include/asm-x86_64/ioctls.h
rename to include/asm-x86/ioctls_64.h
diff --git a/include/asm-x86_64/iommu.h b/include/asm-x86/iommu.h
similarity index 100%
rename from include/asm-x86_64/iommu.h
rename to include/asm-x86/iommu.h
diff --git a/include/asm-i386/ipc.h b/include/asm-x86/ipc.h
similarity index 100%
rename from include/asm-i386/ipc.h
rename to include/asm-x86/ipc.h
diff --git a/include/asm-x86/ipcbuf.h b/include/asm-x86/ipcbuf.h
new file mode 100644
index 0000000..eb2e448
--- /dev/null
+++ b/include/asm-x86/ipcbuf.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "ipcbuf_32.h"
+# else
+#  include "ipcbuf_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "ipcbuf_32.h"
+# else
+#  include "ipcbuf_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/ipcbuf.h b/include/asm-x86/ipcbuf_32.h
similarity index 100%
rename from include/asm-i386/ipcbuf.h
rename to include/asm-x86/ipcbuf_32.h
diff --git a/include/asm-x86_64/ipcbuf.h b/include/asm-x86/ipcbuf_64.h
similarity index 100%
rename from include/asm-x86_64/ipcbuf.h
rename to include/asm-x86/ipcbuf_64.h
diff --git a/include/asm-x86_64/ipi.h b/include/asm-x86/ipi.h
similarity index 100%
rename from include/asm-x86_64/ipi.h
rename to include/asm-x86/ipi.h
diff --git a/include/asm-x86/irq.h b/include/asm-x86/irq.h
new file mode 100644
index 0000000..7ba9054
--- /dev/null
+++ b/include/asm-x86/irq.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "irq_32.h"
+#else
+# include "irq_64.h"
+#endif
diff --git a/include/asm-i386/irq.h b/include/asm-x86/irq_32.h
similarity index 100%
rename from include/asm-i386/irq.h
rename to include/asm-x86/irq_32.h
diff --git a/include/asm-x86_64/irq.h b/include/asm-x86/irq_64.h
similarity index 100%
rename from include/asm-x86_64/irq.h
rename to include/asm-x86/irq_64.h
diff --git a/include/asm-x86/irq_regs.h b/include/asm-x86/irq_regs.h
new file mode 100644
index 0000000..89c898a
--- /dev/null
+++ b/include/asm-x86/irq_regs.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "irq_regs_32.h"
+#else
+# include "irq_regs_64.h"
+#endif
diff --git a/include/asm-i386/irq_regs.h b/include/asm-x86/irq_regs_32.h
similarity index 100%
rename from include/asm-i386/irq_regs.h
rename to include/asm-x86/irq_regs_32.h
diff --git a/include/asm-x86_64/irq_regs.h b/include/asm-x86/irq_regs_64.h
similarity index 100%
rename from include/asm-x86_64/irq_regs.h
rename to include/asm-x86/irq_regs_64.h
diff --git a/include/asm-x86/irqflags.h b/include/asm-x86/irqflags.h
new file mode 100644
index 0000000..1b695ff
--- /dev/null
+++ b/include/asm-x86/irqflags.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "irqflags_32.h"
+#else
+# include "irqflags_64.h"
+#endif
diff --git a/include/asm-i386/irqflags.h b/include/asm-x86/irqflags_32.h
similarity index 100%
rename from include/asm-i386/irqflags.h
rename to include/asm-x86/irqflags_32.h
diff --git a/include/asm-x86_64/irqflags.h b/include/asm-x86/irqflags_64.h
similarity index 100%
rename from include/asm-x86_64/irqflags.h
rename to include/asm-x86/irqflags_64.h
diff --git a/include/asm-i386/ist.h b/include/asm-x86/ist.h
similarity index 100%
rename from include/asm-i386/ist.h
rename to include/asm-x86/ist.h
diff --git a/include/asm-x86_64/k8.h b/include/asm-x86/k8.h
similarity index 100%
rename from include/asm-x86_64/k8.h
rename to include/asm-x86/k8.h
diff --git a/include/asm-x86/kdebug.h b/include/asm-x86/kdebug.h
new file mode 100644
index 0000000..3847910
--- /dev/null
+++ b/include/asm-x86/kdebug.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "kdebug_32.h"
+#else
+# include "kdebug_64.h"
+#endif
diff --git a/include/asm-i386/kdebug.h b/include/asm-x86/kdebug_32.h
similarity index 100%
rename from include/asm-i386/kdebug.h
rename to include/asm-x86/kdebug_32.h
diff --git a/include/asm-x86_64/kdebug.h b/include/asm-x86/kdebug_64.h
similarity index 100%
rename from include/asm-x86_64/kdebug.h
rename to include/asm-x86/kdebug_64.h
diff --git a/include/asm-x86/kexec.h b/include/asm-x86/kexec.h
new file mode 100644
index 0000000..718ddbf
--- /dev/null
+++ b/include/asm-x86/kexec.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "kexec_32.h"
+#else
+# include "kexec_64.h"
+#endif
diff --git a/include/asm-i386/kexec.h b/include/asm-x86/kexec_32.h
similarity index 100%
rename from include/asm-i386/kexec.h
rename to include/asm-x86/kexec_32.h
diff --git a/include/asm-x86_64/kexec.h b/include/asm-x86/kexec_64.h
similarity index 100%
rename from include/asm-x86_64/kexec.h
rename to include/asm-x86/kexec_64.h
diff --git a/include/asm-x86/kmap_types.h b/include/asm-x86/kmap_types.h
new file mode 100644
index 0000000..e4ec724
--- /dev/null
+++ b/include/asm-x86/kmap_types.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "kmap_types_32.h"
+#else
+# include "kmap_types_64.h"
+#endif
diff --git a/include/asm-i386/kmap_types.h b/include/asm-x86/kmap_types_32.h
similarity index 100%
rename from include/asm-i386/kmap_types.h
rename to include/asm-x86/kmap_types_32.h
diff --git a/include/asm-x86_64/kmap_types.h b/include/asm-x86/kmap_types_64.h
similarity index 100%
rename from include/asm-x86_64/kmap_types.h
rename to include/asm-x86/kmap_types_64.h
diff --git a/include/asm-x86/kprobes.h b/include/asm-x86/kprobes.h
new file mode 100644
index 0000000..b7bbd25
--- /dev/null
+++ b/include/asm-x86/kprobes.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "kprobes_32.h"
+#else
+# include "kprobes_64.h"
+#endif
diff --git a/include/asm-i386/kprobes.h b/include/asm-x86/kprobes_32.h
similarity index 100%
rename from include/asm-i386/kprobes.h
rename to include/asm-x86/kprobes_32.h
diff --git a/include/asm-x86_64/kprobes.h b/include/asm-x86/kprobes_64.h
similarity index 100%
rename from include/asm-x86_64/kprobes.h
rename to include/asm-x86/kprobes_64.h
diff --git a/include/asm-x86/ldt.h b/include/asm-x86/ldt.h
new file mode 100644
index 0000000..3d9cc20
--- /dev/null
+++ b/include/asm-x86/ldt.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "ldt_32.h"
+# else
+#  include "ldt_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "ldt_32.h"
+# else
+#  include "ldt_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/ldt.h b/include/asm-x86/ldt_32.h
similarity index 100%
rename from include/asm-i386/ldt.h
rename to include/asm-x86/ldt_32.h
diff --git a/include/asm-x86_64/ldt.h b/include/asm-x86/ldt_64.h
similarity index 100%
rename from include/asm-x86_64/ldt.h
rename to include/asm-x86/ldt_64.h
diff --git a/include/asm-x86/linkage.h b/include/asm-x86/linkage.h
new file mode 100644
index 0000000..94b257f
--- /dev/null
+++ b/include/asm-x86/linkage.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "linkage_32.h"
+#else
+# include "linkage_64.h"
+#endif
diff --git a/include/asm-i386/linkage.h b/include/asm-x86/linkage_32.h
similarity index 100%
rename from include/asm-i386/linkage.h
rename to include/asm-x86/linkage_32.h
diff --git a/include/asm-x86_64/linkage.h b/include/asm-x86/linkage_64.h
similarity index 100%
rename from include/asm-x86_64/linkage.h
rename to include/asm-x86/linkage_64.h
diff --git a/include/asm-x86/local.h b/include/asm-x86/local.h
new file mode 100644
index 0000000..c7a1b1c
--- /dev/null
+++ b/include/asm-x86/local.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "local_32.h"
+#else
+# include "local_64.h"
+#endif
diff --git a/include/asm-i386/local.h b/include/asm-x86/local_32.h
similarity index 100%
rename from include/asm-i386/local.h
rename to include/asm-x86/local_32.h
diff --git a/include/asm-x86_64/local.h b/include/asm-x86/local_64.h
similarity index 100%
rename from include/asm-x86_64/local.h
rename to include/asm-x86/local_64.h
diff --git a/include/asm-i386/mach-bigsmp/mach_apic.h b/include/asm-x86/mach-bigsmp/mach_apic.h
similarity index 100%
rename from include/asm-i386/mach-bigsmp/mach_apic.h
rename to include/asm-x86/mach-bigsmp/mach_apic.h
diff --git a/include/asm-i386/mach-bigsmp/mach_apicdef.h b/include/asm-x86/mach-bigsmp/mach_apicdef.h
similarity index 100%
rename from include/asm-i386/mach-bigsmp/mach_apicdef.h
rename to include/asm-x86/mach-bigsmp/mach_apicdef.h
diff --git a/include/asm-i386/mach-bigsmp/mach_ipi.h b/include/asm-x86/mach-bigsmp/mach_ipi.h
similarity index 100%
rename from include/asm-i386/mach-bigsmp/mach_ipi.h
rename to include/asm-x86/mach-bigsmp/mach_ipi.h
diff --git a/include/asm-i386/mach-bigsmp/mach_mpspec.h b/include/asm-x86/mach-bigsmp/mach_mpspec.h
similarity index 100%
rename from include/asm-i386/mach-bigsmp/mach_mpspec.h
rename to include/asm-x86/mach-bigsmp/mach_mpspec.h
diff --git a/include/asm-i386/mach-default/apm.h b/include/asm-x86/mach-default/apm.h
similarity index 100%
rename from include/asm-i386/mach-default/apm.h
rename to include/asm-x86/mach-default/apm.h
diff --git a/include/asm-i386/mach-default/bios_ebda.h b/include/asm-x86/mach-default/bios_ebda.h
similarity index 100%
rename from include/asm-i386/mach-default/bios_ebda.h
rename to include/asm-x86/mach-default/bios_ebda.h
diff --git a/include/asm-i386/mach-default/do_timer.h b/include/asm-x86/mach-default/do_timer.h
similarity index 100%
rename from include/asm-i386/mach-default/do_timer.h
rename to include/asm-x86/mach-default/do_timer.h
diff --git a/include/asm-i386/mach-default/entry_arch.h b/include/asm-x86/mach-default/entry_arch.h
similarity index 100%
rename from include/asm-i386/mach-default/entry_arch.h
rename to include/asm-x86/mach-default/entry_arch.h
diff --git a/include/asm-i386/mach-default/io_ports.h b/include/asm-x86/mach-default/io_ports.h
similarity index 100%
rename from include/asm-i386/mach-default/io_ports.h
rename to include/asm-x86/mach-default/io_ports.h
diff --git a/include/asm-i386/mach-default/irq_vectors.h b/include/asm-x86/mach-default/irq_vectors.h
similarity index 100%
rename from include/asm-i386/mach-default/irq_vectors.h
rename to include/asm-x86/mach-default/irq_vectors.h
diff --git a/include/asm-i386/mach-default/irq_vectors_limits.h b/include/asm-x86/mach-default/irq_vectors_limits.h
similarity index 100%
rename from include/asm-i386/mach-default/irq_vectors_limits.h
rename to include/asm-x86/mach-default/irq_vectors_limits.h
diff --git a/include/asm-i386/mach-default/mach_apic.h b/include/asm-x86/mach-default/mach_apic.h
similarity index 100%
rename from include/asm-i386/mach-default/mach_apic.h
rename to include/asm-x86/mach-default/mach_apic.h
diff --git a/include/asm-i386/mach-default/mach_apicdef.h b/include/asm-x86/mach-default/mach_apicdef.h
similarity index 100%
rename from include/asm-i386/mach-default/mach_apicdef.h
rename to include/asm-x86/mach-default/mach_apicdef.h
diff --git a/include/asm-i386/mach-default/mach_ipi.h b/include/asm-x86/mach-default/mach_ipi.h
similarity index 100%
rename from include/asm-i386/mach-default/mach_ipi.h
rename to include/asm-x86/mach-default/mach_ipi.h
diff --git a/include/asm-i386/mach-default/mach_mpparse.h b/include/asm-x86/mach-default/mach_mpparse.h
similarity index 100%
rename from include/asm-i386/mach-default/mach_mpparse.h
rename to include/asm-x86/mach-default/mach_mpparse.h
diff --git a/include/asm-i386/mach-default/mach_mpspec.h b/include/asm-x86/mach-default/mach_mpspec.h
similarity index 100%
rename from include/asm-i386/mach-default/mach_mpspec.h
rename to include/asm-x86/mach-default/mach_mpspec.h
diff --git a/include/asm-i386/mach-default/mach_reboot.h b/include/asm-x86/mach-default/mach_reboot.h
similarity index 100%
rename from include/asm-i386/mach-default/mach_reboot.h
rename to include/asm-x86/mach-default/mach_reboot.h
diff --git a/include/asm-i386/mach-default/mach_time.h b/include/asm-x86/mach-default/mach_time.h
similarity index 100%
rename from include/asm-i386/mach-default/mach_time.h
rename to include/asm-x86/mach-default/mach_time.h
diff --git a/include/asm-i386/mach-default/mach_timer.h b/include/asm-x86/mach-default/mach_timer.h
similarity index 100%
rename from include/asm-i386/mach-default/mach_timer.h
rename to include/asm-x86/mach-default/mach_timer.h
diff --git a/include/asm-i386/mach-default/mach_traps.h b/include/asm-x86/mach-default/mach_traps.h
similarity index 100%
rename from include/asm-i386/mach-default/mach_traps.h
rename to include/asm-x86/mach-default/mach_traps.h
diff --git a/include/asm-i386/mach-default/mach_wakecpu.h b/include/asm-x86/mach-default/mach_wakecpu.h
similarity index 100%
rename from include/asm-i386/mach-default/mach_wakecpu.h
rename to include/asm-x86/mach-default/mach_wakecpu.h
diff --git a/include/asm-i386/mach-default/pci-functions.h b/include/asm-x86/mach-default/pci-functions.h
similarity index 100%
rename from include/asm-i386/mach-default/pci-functions.h
rename to include/asm-x86/mach-default/pci-functions.h
diff --git a/include/asm-i386/mach-default/setup_arch.h b/include/asm-x86/mach-default/setup_arch.h
similarity index 100%
rename from include/asm-i386/mach-default/setup_arch.h
rename to include/asm-x86/mach-default/setup_arch.h
diff --git a/include/asm-i386/mach-default/smpboot_hooks.h b/include/asm-x86/mach-default/smpboot_hooks.h
similarity index 100%
rename from include/asm-i386/mach-default/smpboot_hooks.h
rename to include/asm-x86/mach-default/smpboot_hooks.h
diff --git a/include/asm-i386/mach-es7000/mach_apic.h b/include/asm-x86/mach-es7000/mach_apic.h
similarity index 100%
rename from include/asm-i386/mach-es7000/mach_apic.h
rename to include/asm-x86/mach-es7000/mach_apic.h
diff --git a/include/asm-i386/mach-es7000/mach_apicdef.h b/include/asm-x86/mach-es7000/mach_apicdef.h
similarity index 100%
rename from include/asm-i386/mach-es7000/mach_apicdef.h
rename to include/asm-x86/mach-es7000/mach_apicdef.h
diff --git a/include/asm-i386/mach-es7000/mach_ipi.h b/include/asm-x86/mach-es7000/mach_ipi.h
similarity index 100%
rename from include/asm-i386/mach-es7000/mach_ipi.h
rename to include/asm-x86/mach-es7000/mach_ipi.h
diff --git a/include/asm-i386/mach-es7000/mach_mpparse.h b/include/asm-x86/mach-es7000/mach_mpparse.h
similarity index 100%
rename from include/asm-i386/mach-es7000/mach_mpparse.h
rename to include/asm-x86/mach-es7000/mach_mpparse.h
diff --git a/include/asm-i386/mach-es7000/mach_mpspec.h b/include/asm-x86/mach-es7000/mach_mpspec.h
similarity index 100%
rename from include/asm-i386/mach-es7000/mach_mpspec.h
rename to include/asm-x86/mach-es7000/mach_mpspec.h
diff --git a/include/asm-i386/mach-es7000/mach_wakecpu.h b/include/asm-x86/mach-es7000/mach_wakecpu.h
similarity index 100%
rename from include/asm-i386/mach-es7000/mach_wakecpu.h
rename to include/asm-x86/mach-es7000/mach_wakecpu.h
diff --git a/include/asm-i386/mach-generic/irq_vectors_limits.h b/include/asm-x86/mach-generic/irq_vectors_limits.h
similarity index 100%
rename from include/asm-i386/mach-generic/irq_vectors_limits.h
rename to include/asm-x86/mach-generic/irq_vectors_limits.h
diff --git a/include/asm-i386/mach-generic/mach_apic.h b/include/asm-x86/mach-generic/mach_apic.h
similarity index 100%
rename from include/asm-i386/mach-generic/mach_apic.h
rename to include/asm-x86/mach-generic/mach_apic.h
diff --git a/include/asm-i386/mach-generic/mach_apicdef.h b/include/asm-x86/mach-generic/mach_apicdef.h
similarity index 100%
rename from include/asm-i386/mach-generic/mach_apicdef.h
rename to include/asm-x86/mach-generic/mach_apicdef.h
diff --git a/include/asm-i386/mach-generic/mach_ipi.h b/include/asm-x86/mach-generic/mach_ipi.h
similarity index 100%
rename from include/asm-i386/mach-generic/mach_ipi.h
rename to include/asm-x86/mach-generic/mach_ipi.h
diff --git a/include/asm-i386/mach-generic/mach_mpparse.h b/include/asm-x86/mach-generic/mach_mpparse.h
similarity index 100%
rename from include/asm-i386/mach-generic/mach_mpparse.h
rename to include/asm-x86/mach-generic/mach_mpparse.h
diff --git a/include/asm-i386/mach-generic/mach_mpspec.h b/include/asm-x86/mach-generic/mach_mpspec.h
similarity index 100%
rename from include/asm-i386/mach-generic/mach_mpspec.h
rename to include/asm-x86/mach-generic/mach_mpspec.h
diff --git a/include/asm-i386/mach-numaq/mach_apic.h b/include/asm-x86/mach-numaq/mach_apic.h
similarity index 100%
rename from include/asm-i386/mach-numaq/mach_apic.h
rename to include/asm-x86/mach-numaq/mach_apic.h
diff --git a/include/asm-i386/mach-numaq/mach_apicdef.h b/include/asm-x86/mach-numaq/mach_apicdef.h
similarity index 100%
rename from include/asm-i386/mach-numaq/mach_apicdef.h
rename to include/asm-x86/mach-numaq/mach_apicdef.h
diff --git a/include/asm-i386/mach-numaq/mach_ipi.h b/include/asm-x86/mach-numaq/mach_ipi.h
similarity index 100%
rename from include/asm-i386/mach-numaq/mach_ipi.h
rename to include/asm-x86/mach-numaq/mach_ipi.h
diff --git a/include/asm-i386/mach-numaq/mach_mpparse.h b/include/asm-x86/mach-numaq/mach_mpparse.h
similarity index 100%
rename from include/asm-i386/mach-numaq/mach_mpparse.h
rename to include/asm-x86/mach-numaq/mach_mpparse.h
diff --git a/include/asm-i386/mach-numaq/mach_mpspec.h b/include/asm-x86/mach-numaq/mach_mpspec.h
similarity index 100%
rename from include/asm-i386/mach-numaq/mach_mpspec.h
rename to include/asm-x86/mach-numaq/mach_mpspec.h
diff --git a/include/asm-i386/mach-numaq/mach_wakecpu.h b/include/asm-x86/mach-numaq/mach_wakecpu.h
similarity index 100%
rename from include/asm-i386/mach-numaq/mach_wakecpu.h
rename to include/asm-x86/mach-numaq/mach_wakecpu.h
diff --git a/include/asm-i386/mach-summit/irq_vectors_limits.h b/include/asm-x86/mach-summit/irq_vectors_limits.h
similarity index 100%
rename from include/asm-i386/mach-summit/irq_vectors_limits.h
rename to include/asm-x86/mach-summit/irq_vectors_limits.h
diff --git a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-x86/mach-summit/mach_apic.h
similarity index 100%
rename from include/asm-i386/mach-summit/mach_apic.h
rename to include/asm-x86/mach-summit/mach_apic.h
diff --git a/include/asm-i386/mach-summit/mach_apicdef.h b/include/asm-x86/mach-summit/mach_apicdef.h
similarity index 100%
rename from include/asm-i386/mach-summit/mach_apicdef.h
rename to include/asm-x86/mach-summit/mach_apicdef.h
diff --git a/include/asm-i386/mach-summit/mach_ipi.h b/include/asm-x86/mach-summit/mach_ipi.h
similarity index 100%
rename from include/asm-i386/mach-summit/mach_ipi.h
rename to include/asm-x86/mach-summit/mach_ipi.h
diff --git a/include/asm-i386/mach-summit/mach_mpparse.h b/include/asm-x86/mach-summit/mach_mpparse.h
similarity index 100%
rename from include/asm-i386/mach-summit/mach_mpparse.h
rename to include/asm-x86/mach-summit/mach_mpparse.h
diff --git a/include/asm-i386/mach-summit/mach_mpspec.h b/include/asm-x86/mach-summit/mach_mpspec.h
similarity index 100%
rename from include/asm-i386/mach-summit/mach_mpspec.h
rename to include/asm-x86/mach-summit/mach_mpspec.h
diff --git a/include/asm-i386/mach-visws/cobalt.h b/include/asm-x86/mach-visws/cobalt.h
similarity index 100%
rename from include/asm-i386/mach-visws/cobalt.h
rename to include/asm-x86/mach-visws/cobalt.h
diff --git a/include/asm-i386/mach-visws/entry_arch.h b/include/asm-x86/mach-visws/entry_arch.h
similarity index 100%
rename from include/asm-i386/mach-visws/entry_arch.h
rename to include/asm-x86/mach-visws/entry_arch.h
diff --git a/include/asm-i386/mach-visws/irq_vectors.h b/include/asm-x86/mach-visws/irq_vectors.h
similarity index 100%
rename from include/asm-i386/mach-visws/irq_vectors.h
rename to include/asm-x86/mach-visws/irq_vectors.h
diff --git a/include/asm-i386/mach-visws/lithium.h b/include/asm-x86/mach-visws/lithium.h
similarity index 100%
rename from include/asm-i386/mach-visws/lithium.h
rename to include/asm-x86/mach-visws/lithium.h
diff --git a/include/asm-i386/mach-visws/mach_apic.h b/include/asm-x86/mach-visws/mach_apic.h
similarity index 100%
rename from include/asm-i386/mach-visws/mach_apic.h
rename to include/asm-x86/mach-visws/mach_apic.h
diff --git a/include/asm-i386/mach-visws/mach_apicdef.h b/include/asm-x86/mach-visws/mach_apicdef.h
similarity index 100%
rename from include/asm-i386/mach-visws/mach_apicdef.h
rename to include/asm-x86/mach-visws/mach_apicdef.h
diff --git a/include/asm-i386/mach-visws/piix4.h b/include/asm-x86/mach-visws/piix4.h
similarity index 100%
rename from include/asm-i386/mach-visws/piix4.h
rename to include/asm-x86/mach-visws/piix4.h
diff --git a/include/asm-i386/mach-visws/setup_arch.h b/include/asm-x86/mach-visws/setup_arch.h
similarity index 100%
rename from include/asm-i386/mach-visws/setup_arch.h
rename to include/asm-x86/mach-visws/setup_arch.h
diff --git a/include/asm-i386/mach-visws/smpboot_hooks.h b/include/asm-x86/mach-visws/smpboot_hooks.h
similarity index 100%
rename from include/asm-i386/mach-visws/smpboot_hooks.h
rename to include/asm-x86/mach-visws/smpboot_hooks.h
diff --git a/include/asm-i386/mach-voyager/do_timer.h b/include/asm-x86/mach-voyager/do_timer.h
similarity index 100%
rename from include/asm-i386/mach-voyager/do_timer.h
rename to include/asm-x86/mach-voyager/do_timer.h
diff --git a/include/asm-i386/mach-voyager/entry_arch.h b/include/asm-x86/mach-voyager/entry_arch.h
similarity index 100%
rename from include/asm-i386/mach-voyager/entry_arch.h
rename to include/asm-x86/mach-voyager/entry_arch.h
diff --git a/include/asm-i386/mach-voyager/irq_vectors.h b/include/asm-x86/mach-voyager/irq_vectors.h
similarity index 100%
rename from include/asm-i386/mach-voyager/irq_vectors.h
rename to include/asm-x86/mach-voyager/irq_vectors.h
diff --git a/include/asm-i386/mach-voyager/setup_arch.h b/include/asm-x86/mach-voyager/setup_arch.h
similarity index 100%
rename from include/asm-i386/mach-voyager/setup_arch.h
rename to include/asm-x86/mach-voyager/setup_arch.h
diff --git a/include/asm-x86_64/mach_apic.h b/include/asm-x86/mach_apic.h
similarity index 100%
rename from include/asm-x86_64/mach_apic.h
rename to include/asm-x86/mach_apic.h
diff --git a/include/asm-i386/math_emu.h b/include/asm-x86/math_emu.h
similarity index 100%
rename from include/asm-i386/math_emu.h
rename to include/asm-x86/math_emu.h
diff --git a/include/asm-x86/mc146818rtc.h b/include/asm-x86/mc146818rtc.h
new file mode 100644
index 0000000..5c2bb66
--- /dev/null
+++ b/include/asm-x86/mc146818rtc.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "mc146818rtc_32.h"
+#else
+# include "mc146818rtc_64.h"
+#endif
diff --git a/include/asm-i386/mc146818rtc.h b/include/asm-x86/mc146818rtc_32.h
similarity index 100%
rename from include/asm-i386/mc146818rtc.h
rename to include/asm-x86/mc146818rtc_32.h
diff --git a/include/asm-x86_64/mc146818rtc.h b/include/asm-x86/mc146818rtc_64.h
similarity index 100%
rename from include/asm-x86_64/mc146818rtc.h
rename to include/asm-x86/mc146818rtc_64.h
diff --git a/include/asm-i386/mca.h b/include/asm-x86/mca.h
similarity index 100%
rename from include/asm-i386/mca.h
rename to include/asm-x86/mca.h
diff --git a/include/asm-i386/mca_dma.h b/include/asm-x86/mca_dma.h
similarity index 100%
rename from include/asm-i386/mca_dma.h
rename to include/asm-x86/mca_dma.h
diff --git a/include/asm-x86/mce.h b/include/asm-x86/mce.h
new file mode 100644
index 0000000..cc8ca38
--- /dev/null
+++ b/include/asm-x86/mce.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "mce_32.h"
+#else
+# include "mce_64.h"
+#endif
diff --git a/include/asm-i386/mce.h b/include/asm-x86/mce_32.h
similarity index 100%
rename from include/asm-i386/mce.h
rename to include/asm-x86/mce_32.h
diff --git a/include/asm-x86_64/mce.h b/include/asm-x86/mce_64.h
similarity index 100%
rename from include/asm-x86_64/mce.h
rename to include/asm-x86/mce_64.h
diff --git a/include/asm-x86/mman.h b/include/asm-x86/mman.h
new file mode 100644
index 0000000..322db07
--- /dev/null
+++ b/include/asm-x86/mman.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "mman_32.h"
+# else
+#  include "mman_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "mman_32.h"
+# else
+#  include "mman_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/mman.h b/include/asm-x86/mman_32.h
similarity index 100%
rename from include/asm-i386/mman.h
rename to include/asm-x86/mman_32.h
diff --git a/include/asm-x86_64/mman.h b/include/asm-x86/mman_64.h
similarity index 100%
rename from include/asm-x86_64/mman.h
rename to include/asm-x86/mman_64.h
diff --git a/include/asm-x86_64/mmsegment.h b/include/asm-x86/mmsegment.h
similarity index 100%
rename from include/asm-x86_64/mmsegment.h
rename to include/asm-x86/mmsegment.h
diff --git a/include/asm-x86/mmu.h b/include/asm-x86/mmu.h
new file mode 100644
index 0000000..9c628cd
--- /dev/null
+++ b/include/asm-x86/mmu.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "mmu_32.h"
+#else
+# include "mmu_64.h"
+#endif
diff --git a/include/asm-i386/mmu.h b/include/asm-x86/mmu_32.h
similarity index 100%
rename from include/asm-i386/mmu.h
rename to include/asm-x86/mmu_32.h
diff --git a/include/asm-x86_64/mmu.h b/include/asm-x86/mmu_64.h
similarity index 100%
rename from include/asm-x86_64/mmu.h
rename to include/asm-x86/mmu_64.h
diff --git a/include/asm-x86/mmu_context.h b/include/asm-x86/mmu_context.h
new file mode 100644
index 0000000..6598450
--- /dev/null
+++ b/include/asm-x86/mmu_context.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "mmu_context_32.h"
+#else
+# include "mmu_context_64.h"
+#endif
diff --git a/include/asm-i386/mmu_context.h b/include/asm-x86/mmu_context_32.h
similarity index 100%
rename from include/asm-i386/mmu_context.h
rename to include/asm-x86/mmu_context_32.h
diff --git a/include/asm-x86_64/mmu_context.h b/include/asm-x86/mmu_context_64.h
similarity index 100%
rename from include/asm-x86_64/mmu_context.h
rename to include/asm-x86/mmu_context_64.h
diff --git a/include/asm-i386/mmx.h b/include/asm-x86/mmx.h
similarity index 100%
rename from include/asm-i386/mmx.h
rename to include/asm-x86/mmx.h
diff --git a/include/asm-x86/mmzone.h b/include/asm-x86/mmzone.h
new file mode 100644
index 0000000..64217ea
--- /dev/null
+++ b/include/asm-x86/mmzone.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "mmzone_32.h"
+#else
+# include "mmzone_64.h"
+#endif
diff --git a/include/asm-i386/mmzone.h b/include/asm-x86/mmzone_32.h
similarity index 100%
rename from include/asm-i386/mmzone.h
rename to include/asm-x86/mmzone_32.h
diff --git a/include/asm-x86_64/mmzone.h b/include/asm-x86/mmzone_64.h
similarity index 100%
rename from include/asm-x86_64/mmzone.h
rename to include/asm-x86/mmzone_64.h
diff --git a/include/asm-x86/module.h b/include/asm-x86/module.h
new file mode 100644
index 0000000..2b2f18d8
--- /dev/null
+++ b/include/asm-x86/module.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "module_32.h"
+#else
+# include "module_64.h"
+#endif
diff --git a/include/asm-i386/module.h b/include/asm-x86/module_32.h
similarity index 100%
rename from include/asm-i386/module.h
rename to include/asm-x86/module_32.h
diff --git a/include/asm-x86_64/module.h b/include/asm-x86/module_64.h
similarity index 100%
rename from include/asm-x86_64/module.h
rename to include/asm-x86/module_64.h
diff --git a/include/asm-x86/mpspec.h b/include/asm-x86/mpspec.h
new file mode 100644
index 0000000..8f268e8
--- /dev/null
+++ b/include/asm-x86/mpspec.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "mpspec_32.h"
+#else
+# include "mpspec_64.h"
+#endif
diff --git a/include/asm-i386/mpspec.h b/include/asm-x86/mpspec_32.h
similarity index 100%
rename from include/asm-i386/mpspec.h
rename to include/asm-x86/mpspec_32.h
diff --git a/include/asm-x86_64/mpspec.h b/include/asm-x86/mpspec_64.h
similarity index 100%
rename from include/asm-x86_64/mpspec.h
rename to include/asm-x86/mpspec_64.h
diff --git a/include/asm-i386/mpspec_def.h b/include/asm-x86/mpspec_def.h
similarity index 100%
rename from include/asm-i386/mpspec_def.h
rename to include/asm-x86/mpspec_def.h
diff --git a/include/asm-x86/msgbuf.h b/include/asm-x86/msgbuf.h
new file mode 100644
index 0000000..154f7d6
--- /dev/null
+++ b/include/asm-x86/msgbuf.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "msgbuf_32.h"
+# else
+#  include "msgbuf_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "msgbuf_32.h"
+# else
+#  include "msgbuf_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/msgbuf.h b/include/asm-x86/msgbuf_32.h
similarity index 100%
rename from include/asm-i386/msgbuf.h
rename to include/asm-x86/msgbuf_32.h
diff --git a/include/asm-x86_64/msgbuf.h b/include/asm-x86/msgbuf_64.h
similarity index 100%
rename from include/asm-x86_64/msgbuf.h
rename to include/asm-x86/msgbuf_64.h
diff --git a/include/asm-i386/msidef.h b/include/asm-x86/msidef.h
similarity index 100%
rename from include/asm-i386/msidef.h
rename to include/asm-x86/msidef.h
diff --git a/include/asm-i386/msr-index.h b/include/asm-x86/msr-index.h
similarity index 100%
rename from include/asm-i386/msr-index.h
rename to include/asm-x86/msr-index.h
diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h
new file mode 100644
index 0000000..2f87ce0
--- /dev/null
+++ b/include/asm-x86/msr.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "msr_32.h"
+# else
+#  include "msr_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "msr_32.h"
+# else
+#  include "msr_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/msr.h b/include/asm-x86/msr_32.h
similarity index 100%
rename from include/asm-i386/msr.h
rename to include/asm-x86/msr_32.h
diff --git a/include/asm-x86_64/msr.h b/include/asm-x86/msr_64.h
similarity index 100%
rename from include/asm-x86_64/msr.h
rename to include/asm-x86/msr_64.h
diff --git a/include/asm-x86/mtrr.h b/include/asm-x86/mtrr.h
new file mode 100644
index 0000000..34f633b
--- /dev/null
+++ b/include/asm-x86/mtrr.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "mtrr_32.h"
+# else
+#  include "mtrr_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "mtrr_32.h"
+# else
+#  include "mtrr_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/mtrr.h b/include/asm-x86/mtrr_32.h
similarity index 100%
rename from include/asm-i386/mtrr.h
rename to include/asm-x86/mtrr_32.h
diff --git a/include/asm-x86_64/mtrr.h b/include/asm-x86/mtrr_64.h
similarity index 100%
rename from include/asm-x86_64/mtrr.h
rename to include/asm-x86/mtrr_64.h
diff --git a/include/asm-x86/mutex.h b/include/asm-x86/mutex.h
new file mode 100644
index 0000000..a731b9c
--- /dev/null
+++ b/include/asm-x86/mutex.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "mutex_32.h"
+#else
+# include "mutex_64.h"
+#endif
diff --git a/include/asm-i386/mutex.h b/include/asm-x86/mutex_32.h
similarity index 100%
rename from include/asm-i386/mutex.h
rename to include/asm-x86/mutex_32.h
diff --git a/include/asm-x86_64/mutex.h b/include/asm-x86/mutex_64.h
similarity index 100%
rename from include/asm-x86_64/mutex.h
rename to include/asm-x86/mutex_64.h
diff --git a/include/asm-x86/namei.h b/include/asm-x86/namei.h
new file mode 100644
index 0000000..732f8f0
--- /dev/null
+++ b/include/asm-x86/namei.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "namei_32.h"
+#else
+# include "namei_64.h"
+#endif
diff --git a/include/asm-i386/namei.h b/include/asm-x86/namei_32.h
similarity index 100%
rename from include/asm-i386/namei.h
rename to include/asm-x86/namei_32.h
diff --git a/include/asm-x86_64/namei.h b/include/asm-x86/namei_64.h
similarity index 100%
rename from include/asm-x86_64/namei.h
rename to include/asm-x86/namei_64.h
diff --git a/include/asm-x86/nmi.h b/include/asm-x86/nmi.h
new file mode 100644
index 0000000..53ccac1
--- /dev/null
+++ b/include/asm-x86/nmi.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "nmi_32.h"
+#else
+# include "nmi_64.h"
+#endif
diff --git a/include/asm-i386/nmi.h b/include/asm-x86/nmi_32.h
similarity index 100%
rename from include/asm-i386/nmi.h
rename to include/asm-x86/nmi_32.h
diff --git a/include/asm-x86_64/nmi.h b/include/asm-x86/nmi_64.h
similarity index 100%
rename from include/asm-x86_64/nmi.h
rename to include/asm-x86/nmi_64.h
diff --git a/include/asm-x86/numa.h b/include/asm-x86/numa.h
new file mode 100644
index 0000000..27da400
--- /dev/null
+++ b/include/asm-x86/numa.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "numa_32.h"
+#else
+# include "numa_64.h"
+#endif
diff --git a/include/asm-i386/numa.h b/include/asm-x86/numa_32.h
similarity index 100%
rename from include/asm-i386/numa.h
rename to include/asm-x86/numa_32.h
diff --git a/include/asm-x86_64/numa.h b/include/asm-x86/numa_64.h
similarity index 100%
rename from include/asm-x86_64/numa.h
rename to include/asm-x86/numa_64.h
diff --git a/include/asm-i386/numaq.h b/include/asm-x86/numaq.h
similarity index 100%
rename from include/asm-i386/numaq.h
rename to include/asm-x86/numaq.h
diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h
new file mode 100644
index 0000000..a757eb2
--- /dev/null
+++ b/include/asm-x86/page.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "page_32.h"
+# else
+#  include "page_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "page_32.h"
+# else
+#  include "page_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/page.h b/include/asm-x86/page_32.h
similarity index 100%
rename from include/asm-i386/page.h
rename to include/asm-x86/page_32.h
diff --git a/include/asm-x86_64/page.h b/include/asm-x86/page_64.h
similarity index 100%
rename from include/asm-x86_64/page.h
rename to include/asm-x86/page_64.h
diff --git a/include/asm-x86/param.h b/include/asm-x86/param.h
new file mode 100644
index 0000000..640851b
--- /dev/null
+++ b/include/asm-x86/param.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "param_32.h"
+# else
+#  include "param_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "param_32.h"
+# else
+#  include "param_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/param.h b/include/asm-x86/param_32.h
similarity index 100%
rename from include/asm-i386/param.h
rename to include/asm-x86/param_32.h
diff --git a/include/asm-x86_64/param.h b/include/asm-x86/param_64.h
similarity index 100%
rename from include/asm-x86_64/param.h
rename to include/asm-x86/param_64.h
diff --git a/include/asm-i386/paravirt.h b/include/asm-x86/paravirt.h
similarity index 100%
rename from include/asm-i386/paravirt.h
rename to include/asm-x86/paravirt.h
diff --git a/include/asm-x86/parport.h b/include/asm-x86/parport.h
new file mode 100644
index 0000000..2a31157
--- /dev/null
+++ b/include/asm-x86/parport.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "parport_32.h"
+#else
+# include "parport_64.h"
+#endif
diff --git a/include/asm-i386/parport.h b/include/asm-x86/parport_32.h
similarity index 100%
rename from include/asm-i386/parport.h
rename to include/asm-x86/parport_32.h
diff --git a/include/asm-x86_64/parport.h b/include/asm-x86/parport_64.h
similarity index 100%
rename from include/asm-x86_64/parport.h
rename to include/asm-x86/parport_64.h
diff --git a/include/asm-x86_64/pci-direct.h b/include/asm-x86/pci-direct.h
similarity index 100%
rename from include/asm-x86_64/pci-direct.h
rename to include/asm-x86/pci-direct.h
diff --git a/include/asm-x86/pci.h b/include/asm-x86/pci.h
new file mode 100644
index 0000000..a8cac8c
--- /dev/null
+++ b/include/asm-x86/pci.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "pci_32.h"
+#else
+# include "pci_64.h"
+#endif
diff --git a/include/asm-i386/pci.h b/include/asm-x86/pci_32.h
similarity index 100%
rename from include/asm-i386/pci.h
rename to include/asm-x86/pci_32.h
diff --git a/include/asm-x86_64/pci.h b/include/asm-x86/pci_64.h
similarity index 100%
rename from include/asm-x86_64/pci.h
rename to include/asm-x86/pci_64.h
diff --git a/include/asm-x86_64/pda.h b/include/asm-x86/pda.h
similarity index 100%
rename from include/asm-x86_64/pda.h
rename to include/asm-x86/pda.h
diff --git a/include/asm-x86/percpu.h b/include/asm-x86/percpu.h
new file mode 100644
index 0000000..a1aaad2
--- /dev/null
+++ b/include/asm-x86/percpu.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "percpu_32.h"
+#else
+# include "percpu_64.h"
+#endif
diff --git a/include/asm-i386/percpu.h b/include/asm-x86/percpu_32.h
similarity index 100%
rename from include/asm-i386/percpu.h
rename to include/asm-x86/percpu_32.h
diff --git a/include/asm-x86_64/percpu.h b/include/asm-x86/percpu_64.h
similarity index 100%
rename from include/asm-x86_64/percpu.h
rename to include/asm-x86/percpu_64.h
diff --git a/include/asm-x86/pgalloc.h b/include/asm-x86/pgalloc.h
new file mode 100644
index 0000000..5886eed
--- /dev/null
+++ b/include/asm-x86/pgalloc.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "pgalloc_32.h"
+#else
+# include "pgalloc_64.h"
+#endif
diff --git a/include/asm-i386/pgalloc.h b/include/asm-x86/pgalloc_32.h
similarity index 100%
rename from include/asm-i386/pgalloc.h
rename to include/asm-x86/pgalloc_32.h
diff --git a/include/asm-x86_64/pgalloc.h b/include/asm-x86/pgalloc_64.h
similarity index 100%
rename from include/asm-x86_64/pgalloc.h
rename to include/asm-x86/pgalloc_64.h
diff --git a/include/asm-i386/pgtable-2level-defs.h b/include/asm-x86/pgtable-2level-defs.h
similarity index 100%
rename from include/asm-i386/pgtable-2level-defs.h
rename to include/asm-x86/pgtable-2level-defs.h
diff --git a/include/asm-i386/pgtable-2level.h b/include/asm-x86/pgtable-2level.h
similarity index 100%
rename from include/asm-i386/pgtable-2level.h
rename to include/asm-x86/pgtable-2level.h
diff --git a/include/asm-i386/pgtable-3level-defs.h b/include/asm-x86/pgtable-3level-defs.h
similarity index 100%
rename from include/asm-i386/pgtable-3level-defs.h
rename to include/asm-x86/pgtable-3level-defs.h
diff --git a/include/asm-i386/pgtable-3level.h b/include/asm-x86/pgtable-3level.h
similarity index 100%
rename from include/asm-i386/pgtable-3level.h
rename to include/asm-x86/pgtable-3level.h
diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h
new file mode 100644
index 0000000..1039140
--- /dev/null
+++ b/include/asm-x86/pgtable.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "pgtable_32.h"
+#else
+# include "pgtable_64.h"
+#endif
diff --git a/include/asm-i386/pgtable.h b/include/asm-x86/pgtable_32.h
similarity index 100%
rename from include/asm-i386/pgtable.h
rename to include/asm-x86/pgtable_32.h
diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86/pgtable_64.h
similarity index 100%
rename from include/asm-x86_64/pgtable.h
rename to include/asm-x86/pgtable_64.h
diff --git a/include/asm-i386/poll.h b/include/asm-x86/poll.h
similarity index 100%
rename from include/asm-i386/poll.h
rename to include/asm-x86/poll.h
diff --git a/include/asm-x86/posix_types.h b/include/asm-x86/posix_types.h
new file mode 100644
index 0000000..bb7133d
--- /dev/null
+++ b/include/asm-x86/posix_types.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "posix_types_32.h"
+# else
+#  include "posix_types_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "posix_types_32.h"
+# else
+#  include "posix_types_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/posix_types.h b/include/asm-x86/posix_types_32.h
similarity index 100%
rename from include/asm-i386/posix_types.h
rename to include/asm-x86/posix_types_32.h
diff --git a/include/asm-x86_64/posix_types.h b/include/asm-x86/posix_types_64.h
similarity index 100%
rename from include/asm-x86_64/posix_types.h
rename to include/asm-x86/posix_types_64.h
diff --git a/include/asm-x86_64/prctl.h b/include/asm-x86/prctl.h
similarity index 100%
rename from include/asm-x86_64/prctl.h
rename to include/asm-x86/prctl.h
diff --git a/include/asm-i386/processor-cyrix.h b/include/asm-x86/processor-cyrix.h
similarity index 100%
rename from include/asm-i386/processor-cyrix.h
rename to include/asm-x86/processor-cyrix.h
diff --git a/include/asm-i386/processor-flags.h b/include/asm-x86/processor-flags.h
similarity index 100%
rename from include/asm-i386/processor-flags.h
rename to include/asm-x86/processor-flags.h
diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h
new file mode 100644
index 0000000..46e1c04
--- /dev/null
+++ b/include/asm-x86/processor.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "processor_32.h"
+#else
+# include "processor_64.h"
+#endif
diff --git a/include/asm-i386/processor.h b/include/asm-x86/processor_32.h
similarity index 100%
rename from include/asm-i386/processor.h
rename to include/asm-x86/processor_32.h
diff --git a/include/asm-x86_64/processor.h b/include/asm-x86/processor_64.h
similarity index 100%
rename from include/asm-x86_64/processor.h
rename to include/asm-x86/processor_64.h
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86/proto.h
similarity index 100%
rename from include/asm-x86_64/proto.h
rename to include/asm-x86/proto.h
diff --git a/include/asm-x86/ptrace-abi.h b/include/asm-x86/ptrace-abi.h
new file mode 100644
index 0000000..6824c49
--- /dev/null
+++ b/include/asm-x86/ptrace-abi.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "ptrace-abi_32.h"
+# else
+#  include "ptrace-abi_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "ptrace-abi_32.h"
+# else
+#  include "ptrace-abi_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/ptrace-abi.h b/include/asm-x86/ptrace-abi_32.h
similarity index 100%
rename from include/asm-i386/ptrace-abi.h
rename to include/asm-x86/ptrace-abi_32.h
diff --git a/include/asm-x86_64/ptrace-abi.h b/include/asm-x86/ptrace-abi_64.h
similarity index 100%
rename from include/asm-x86_64/ptrace-abi.h
rename to include/asm-x86/ptrace-abi_64.h
diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h
new file mode 100644
index 0000000..bc4d64a
--- /dev/null
+++ b/include/asm-x86/ptrace.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "ptrace_32.h"
+# else
+#  include "ptrace_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "ptrace_32.h"
+# else
+#  include "ptrace_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/ptrace.h b/include/asm-x86/ptrace_32.h
similarity index 100%
rename from include/asm-i386/ptrace.h
rename to include/asm-x86/ptrace_32.h
diff --git a/include/asm-x86_64/ptrace.h b/include/asm-x86/ptrace_64.h
similarity index 100%
rename from include/asm-x86_64/ptrace.h
rename to include/asm-x86/ptrace_64.h
diff --git a/include/asm-i386/reboot.h b/include/asm-x86/reboot.h
similarity index 100%
rename from include/asm-i386/reboot.h
rename to include/asm-x86/reboot.h
diff --git a/include/asm-i386/reboot_fixups.h b/include/asm-x86/reboot_fixups.h
similarity index 100%
rename from include/asm-i386/reboot_fixups.h
rename to include/asm-x86/reboot_fixups.h
diff --git a/include/asm-x86/required-features.h b/include/asm-x86/required-features.h
new file mode 100644
index 0000000..8b64f3e
--- /dev/null
+++ b/include/asm-x86/required-features.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "required-features_32.h"
+#else
+# include "required-features_64.h"
+#endif
diff --git a/include/asm-i386/required-features.h b/include/asm-x86/required-features_32.h
similarity index 100%
rename from include/asm-i386/required-features.h
rename to include/asm-x86/required-features_32.h
diff --git a/include/asm-x86_64/required-features.h b/include/asm-x86/required-features_64.h
similarity index 100%
rename from include/asm-x86_64/required-features.h
rename to include/asm-x86/required-features_64.h
diff --git a/include/asm-x86/resource.h b/include/asm-x86/resource.h
new file mode 100644
index 0000000..732410a
--- /dev/null
+++ b/include/asm-x86/resource.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "resource_32.h"
+# else
+#  include "resource_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "resource_32.h"
+# else
+#  include "resource_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/resource.h b/include/asm-x86/resource_32.h
similarity index 100%
rename from include/asm-i386/resource.h
rename to include/asm-x86/resource_32.h
diff --git a/include/asm-x86_64/resource.h b/include/asm-x86/resource_64.h
similarity index 100%
rename from include/asm-x86_64/resource.h
rename to include/asm-x86/resource_64.h
diff --git a/include/asm-x86/resume-trace.h b/include/asm-x86/resume-trace.h
new file mode 100644
index 0000000..9b6dd09
--- /dev/null
+++ b/include/asm-x86/resume-trace.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "resume-trace_32.h"
+#else
+# include "resume-trace_64.h"
+#endif
diff --git a/include/asm-i386/resume-trace.h b/include/asm-x86/resume-trace_32.h
similarity index 100%
rename from include/asm-i386/resume-trace.h
rename to include/asm-x86/resume-trace_32.h
diff --git a/include/asm-x86_64/resume-trace.h b/include/asm-x86/resume-trace_64.h
similarity index 100%
rename from include/asm-x86_64/resume-trace.h
rename to include/asm-x86/resume-trace_64.h
diff --git a/include/asm-x86_64/rio.h b/include/asm-x86/rio.h
similarity index 100%
rename from include/asm-x86_64/rio.h
rename to include/asm-x86/rio.h
diff --git a/include/asm-x86/rtc.h b/include/asm-x86/rtc.h
new file mode 100644
index 0000000..1f0c98e
--- /dev/null
+++ b/include/asm-x86/rtc.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "rtc_32.h"
+#else
+# include "rtc_64.h"
+#endif
diff --git a/include/asm-i386/rtc.h b/include/asm-x86/rtc_32.h
similarity index 100%
rename from include/asm-i386/rtc.h
rename to include/asm-x86/rtc_32.h
diff --git a/include/asm-x86_64/rtc.h b/include/asm-x86/rtc_64.h
similarity index 100%
rename from include/asm-x86_64/rtc.h
rename to include/asm-x86/rtc_64.h
diff --git a/include/asm-x86/rwlock.h b/include/asm-x86/rwlock.h
new file mode 100644
index 0000000..a3be7d8
--- /dev/null
+++ b/include/asm-x86/rwlock.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "rwlock_32.h"
+#else
+# include "rwlock_64.h"
+#endif
diff --git a/include/asm-i386/rwlock.h b/include/asm-x86/rwlock_32.h
similarity index 100%
rename from include/asm-i386/rwlock.h
rename to include/asm-x86/rwlock_32.h
diff --git a/include/asm-x86_64/rwlock.h b/include/asm-x86/rwlock_64.h
similarity index 100%
rename from include/asm-x86_64/rwlock.h
rename to include/asm-x86/rwlock_64.h
diff --git a/include/asm-i386/rwsem.h b/include/asm-x86/rwsem.h
similarity index 100%
rename from include/asm-i386/rwsem.h
rename to include/asm-x86/rwsem.h
diff --git a/include/asm-x86/scatterlist.h b/include/asm-x86/scatterlist.h
new file mode 100644
index 0000000..3a1e762
--- /dev/null
+++ b/include/asm-x86/scatterlist.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "scatterlist_32.h"
+#else
+# include "scatterlist_64.h"
+#endif
diff --git a/include/asm-i386/scatterlist.h b/include/asm-x86/scatterlist_32.h
similarity index 100%
rename from include/asm-i386/scatterlist.h
rename to include/asm-x86/scatterlist_32.h
diff --git a/include/asm-x86_64/scatterlist.h b/include/asm-x86/scatterlist_64.h
similarity index 100%
rename from include/asm-x86_64/scatterlist.h
rename to include/asm-x86/scatterlist_64.h
diff --git a/include/asm-x86/seccomp.h b/include/asm-x86/seccomp.h
new file mode 100644
index 0000000..c62e58a
--- /dev/null
+++ b/include/asm-x86/seccomp.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "seccomp_32.h"
+#else
+# include "seccomp_64.h"
+#endif
diff --git a/include/asm-i386/seccomp.h b/include/asm-x86/seccomp_32.h
similarity index 100%
rename from include/asm-i386/seccomp.h
rename to include/asm-x86/seccomp_32.h
diff --git a/include/asm-x86_64/seccomp.h b/include/asm-x86/seccomp_64.h
similarity index 100%
rename from include/asm-x86_64/seccomp.h
rename to include/asm-x86/seccomp_64.h
diff --git a/include/asm-x86/sections.h b/include/asm-x86/sections.h
new file mode 100644
index 0000000..ae6c69d
--- /dev/null
+++ b/include/asm-x86/sections.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "sections_32.h"
+#else
+# include "sections_64.h"
+#endif
diff --git a/include/asm-i386/sections.h b/include/asm-x86/sections_32.h
similarity index 100%
rename from include/asm-i386/sections.h
rename to include/asm-x86/sections_32.h
diff --git a/include/asm-x86_64/sections.h b/include/asm-x86/sections_64.h
similarity index 100%
rename from include/asm-x86_64/sections.h
rename to include/asm-x86/sections_64.h
diff --git a/include/asm-x86/segment.h b/include/asm-x86/segment.h
new file mode 100644
index 0000000..6050682
--- /dev/null
+++ b/include/asm-x86/segment.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "segment_32.h"
+#else
+# include "segment_64.h"
+#endif
diff --git a/include/asm-i386/segment.h b/include/asm-x86/segment_32.h
similarity index 100%
rename from include/asm-i386/segment.h
rename to include/asm-x86/segment_32.h
diff --git a/include/asm-x86_64/segment.h b/include/asm-x86/segment_64.h
similarity index 100%
rename from include/asm-x86_64/segment.h
rename to include/asm-x86/segment_64.h
diff --git a/include/asm-x86/semaphore.h b/include/asm-x86/semaphore.h
new file mode 100644
index 0000000..572c0b6
--- /dev/null
+++ b/include/asm-x86/semaphore.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "semaphore_32.h"
+#else
+# include "semaphore_64.h"
+#endif
diff --git a/include/asm-i386/semaphore.h b/include/asm-x86/semaphore_32.h
similarity index 100%
rename from include/asm-i386/semaphore.h
rename to include/asm-x86/semaphore_32.h
diff --git a/include/asm-x86_64/semaphore.h b/include/asm-x86/semaphore_64.h
similarity index 100%
rename from include/asm-x86_64/semaphore.h
rename to include/asm-x86/semaphore_64.h
diff --git a/include/asm-x86/sembuf.h b/include/asm-x86/sembuf.h
new file mode 100644
index 0000000..e42c971
--- /dev/null
+++ b/include/asm-x86/sembuf.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "sembuf_32.h"
+# else
+#  include "sembuf_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "sembuf_32.h"
+# else
+#  include "sembuf_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/sembuf.h b/include/asm-x86/sembuf_32.h
similarity index 100%
rename from include/asm-i386/sembuf.h
rename to include/asm-x86/sembuf_32.h
diff --git a/include/asm-x86_64/sembuf.h b/include/asm-x86/sembuf_64.h
similarity index 100%
rename from include/asm-x86_64/sembuf.h
rename to include/asm-x86/sembuf_64.h
diff --git a/include/asm-x86/serial.h b/include/asm-x86/serial.h
new file mode 100644
index 0000000..cf1b052
--- /dev/null
+++ b/include/asm-x86/serial.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "serial_32.h"
+#else
+# include "serial_64.h"
+#endif
diff --git a/include/asm-i386/serial.h b/include/asm-x86/serial_32.h
similarity index 100%
rename from include/asm-i386/serial.h
rename to include/asm-x86/serial_32.h
diff --git a/include/asm-x86_64/serial.h b/include/asm-x86/serial_64.h
similarity index 100%
rename from include/asm-x86_64/serial.h
rename to include/asm-x86/serial_64.h
diff --git a/include/asm-x86/setup.h b/include/asm-x86/setup.h
new file mode 100644
index 0000000..81c0d98
--- /dev/null
+++ b/include/asm-x86/setup.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "setup_32.h"
+# else
+#  include "setup_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "setup_32.h"
+# else
+#  include "setup_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/setup.h b/include/asm-x86/setup_32.h
similarity index 100%
rename from include/asm-i386/setup.h
rename to include/asm-x86/setup_32.h
diff --git a/include/asm-x86_64/setup.h b/include/asm-x86/setup_64.h
similarity index 100%
rename from include/asm-x86_64/setup.h
rename to include/asm-x86/setup_64.h
diff --git a/include/asm-x86/shmbuf.h b/include/asm-x86/shmbuf.h
new file mode 100644
index 0000000..e85f1cb
--- /dev/null
+++ b/include/asm-x86/shmbuf.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "shmbuf_32.h"
+# else
+#  include "shmbuf_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "shmbuf_32.h"
+# else
+#  include "shmbuf_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/shmbuf.h b/include/asm-x86/shmbuf_32.h
similarity index 100%
rename from include/asm-i386/shmbuf.h
rename to include/asm-x86/shmbuf_32.h
diff --git a/include/asm-x86_64/shmbuf.h b/include/asm-x86/shmbuf_64.h
similarity index 100%
rename from include/asm-x86_64/shmbuf.h
rename to include/asm-x86/shmbuf_64.h
diff --git a/include/asm-x86/shmparam.h b/include/asm-x86/shmparam.h
new file mode 100644
index 0000000..165627c
--- /dev/null
+++ b/include/asm-x86/shmparam.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "shmparam_32.h"
+# else
+#  include "shmparam_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "shmparam_32.h"
+# else
+#  include "shmparam_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/shmparam.h b/include/asm-x86/shmparam_32.h
similarity index 100%
rename from include/asm-i386/shmparam.h
rename to include/asm-x86/shmparam_32.h
diff --git a/include/asm-x86_64/shmparam.h b/include/asm-x86/shmparam_64.h
similarity index 100%
rename from include/asm-x86_64/shmparam.h
rename to include/asm-x86/shmparam_64.h
diff --git a/include/asm-x86/sigcontext.h b/include/asm-x86/sigcontext.h
new file mode 100644
index 0000000..0d16cef
--- /dev/null
+++ b/include/asm-x86/sigcontext.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "sigcontext_32.h"
+# else
+#  include "sigcontext_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "sigcontext_32.h"
+# else
+#  include "sigcontext_64.h"
+# endif
+#endif
diff --git a/include/asm-x86_64/sigcontext32.h b/include/asm-x86/sigcontext32.h
similarity index 100%
rename from include/asm-x86_64/sigcontext32.h
rename to include/asm-x86/sigcontext32.h
diff --git a/include/asm-i386/sigcontext.h b/include/asm-x86/sigcontext_32.h
similarity index 100%
rename from include/asm-i386/sigcontext.h
rename to include/asm-x86/sigcontext_32.h
diff --git a/include/asm-x86_64/sigcontext.h b/include/asm-x86/sigcontext_64.h
similarity index 100%
rename from include/asm-x86_64/sigcontext.h
rename to include/asm-x86/sigcontext_64.h
diff --git a/include/asm-x86/siginfo.h b/include/asm-x86/siginfo.h
new file mode 100644
index 0000000..0b8e4bb
--- /dev/null
+++ b/include/asm-x86/siginfo.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "siginfo_32.h"
+# else
+#  include "siginfo_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "siginfo_32.h"
+# else
+#  include "siginfo_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/siginfo.h b/include/asm-x86/siginfo_32.h
similarity index 100%
rename from include/asm-i386/siginfo.h
rename to include/asm-x86/siginfo_32.h
diff --git a/include/asm-x86_64/siginfo.h b/include/asm-x86/siginfo_64.h
similarity index 100%
rename from include/asm-x86_64/siginfo.h
rename to include/asm-x86/siginfo_64.h
diff --git a/include/asm-x86/signal.h b/include/asm-x86/signal.h
new file mode 100644
index 0000000..bf5a63f
--- /dev/null
+++ b/include/asm-x86/signal.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "signal_32.h"
+# else
+#  include "signal_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "signal_32.h"
+# else
+#  include "signal_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/signal.h b/include/asm-x86/signal_32.h
similarity index 100%
rename from include/asm-i386/signal.h
rename to include/asm-x86/signal_32.h
diff --git a/include/asm-x86_64/signal.h b/include/asm-x86/signal_64.h
similarity index 100%
rename from include/asm-x86_64/signal.h
rename to include/asm-x86/signal_64.h
diff --git a/include/asm-x86/smp.h b/include/asm-x86/smp.h
new file mode 100644
index 0000000..f2e8319
--- /dev/null
+++ b/include/asm-x86/smp.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "smp_32.h"
+#else
+# include "smp_64.h"
+#endif
diff --git a/include/asm-i386/smp.h b/include/asm-x86/smp_32.h
similarity index 100%
rename from include/asm-i386/smp.h
rename to include/asm-x86/smp_32.h
diff --git a/include/asm-x86_64/smp.h b/include/asm-x86/smp_64.h
similarity index 100%
rename from include/asm-x86_64/smp.h
rename to include/asm-x86/smp_64.h
diff --git a/include/asm-i386/socket.h b/include/asm-x86/socket.h
similarity index 100%
rename from include/asm-i386/socket.h
rename to include/asm-x86/socket.h
diff --git a/include/asm-x86/sockios.h b/include/asm-x86/sockios.h
new file mode 100644
index 0000000..5a134fc
--- /dev/null
+++ b/include/asm-x86/sockios.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "sockios_32.h"
+# else
+#  include "sockios_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "sockios_32.h"
+# else
+#  include "sockios_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/sockios.h b/include/asm-x86/sockios_32.h
similarity index 100%
rename from include/asm-i386/sockios.h
rename to include/asm-x86/sockios_32.h
diff --git a/include/asm-x86_64/sockios.h b/include/asm-x86/sockios_64.h
similarity index 100%
rename from include/asm-x86_64/sockios.h
rename to include/asm-x86/sockios_64.h
diff --git a/include/asm-x86/sparsemem.h b/include/asm-x86/sparsemem.h
new file mode 100644
index 0000000..3f203b1
--- /dev/null
+++ b/include/asm-x86/sparsemem.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "sparsemem_32.h"
+#else
+# include "sparsemem_64.h"
+#endif
diff --git a/include/asm-i386/sparsemem.h b/include/asm-x86/sparsemem_32.h
similarity index 100%
rename from include/asm-i386/sparsemem.h
rename to include/asm-x86/sparsemem_32.h
diff --git a/include/asm-x86_64/sparsemem.h b/include/asm-x86/sparsemem_64.h
similarity index 100%
rename from include/asm-x86_64/sparsemem.h
rename to include/asm-x86/sparsemem_64.h
diff --git a/include/asm-x86/spinlock.h b/include/asm-x86/spinlock.h
new file mode 100644
index 0000000..d74d85e
--- /dev/null
+++ b/include/asm-x86/spinlock.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "spinlock_32.h"
+#else
+# include "spinlock_64.h"
+#endif
diff --git a/include/asm-i386/spinlock.h b/include/asm-x86/spinlock_32.h
similarity index 100%
rename from include/asm-i386/spinlock.h
rename to include/asm-x86/spinlock_32.h
diff --git a/include/asm-x86_64/spinlock.h b/include/asm-x86/spinlock_64.h
similarity index 100%
rename from include/asm-x86_64/spinlock.h
rename to include/asm-x86/spinlock_64.h
diff --git a/include/asm-i386/spinlock_types.h b/include/asm-x86/spinlock_types.h
similarity index 100%
rename from include/asm-i386/spinlock_types.h
rename to include/asm-x86/spinlock_types.h
diff --git a/include/asm-i386/srat.h b/include/asm-x86/srat.h
similarity index 100%
rename from include/asm-i386/srat.h
rename to include/asm-x86/srat.h
diff --git a/include/asm-x86_64/stacktrace.h b/include/asm-x86/stacktrace.h
similarity index 100%
rename from include/asm-x86_64/stacktrace.h
rename to include/asm-x86/stacktrace.h
diff --git a/include/asm-x86/stat.h b/include/asm-x86/stat.h
new file mode 100644
index 0000000..3ff6b50
--- /dev/null
+++ b/include/asm-x86/stat.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "stat_32.h"
+# else
+#  include "stat_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "stat_32.h"
+# else
+#  include "stat_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/stat.h b/include/asm-x86/stat_32.h
similarity index 100%
rename from include/asm-i386/stat.h
rename to include/asm-x86/stat_32.h
diff --git a/include/asm-x86_64/stat.h b/include/asm-x86/stat_64.h
similarity index 100%
rename from include/asm-x86_64/stat.h
rename to include/asm-x86/stat_64.h
diff --git a/include/asm-x86/statfs.h b/include/asm-x86/statfs.h
new file mode 100644
index 0000000..327fb5d
--- /dev/null
+++ b/include/asm-x86/statfs.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "statfs_32.h"
+# else
+#  include "statfs_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "statfs_32.h"
+# else
+#  include "statfs_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/statfs.h b/include/asm-x86/statfs_32.h
similarity index 100%
rename from include/asm-i386/statfs.h
rename to include/asm-x86/statfs_32.h
diff --git a/include/asm-x86_64/statfs.h b/include/asm-x86/statfs_64.h
similarity index 100%
rename from include/asm-x86_64/statfs.h
rename to include/asm-x86/statfs_64.h
diff --git a/include/asm-x86/string.h b/include/asm-x86/string.h
new file mode 100644
index 0000000..6dfd6d9
--- /dev/null
+++ b/include/asm-x86/string.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "string_32.h"
+#else
+# include "string_64.h"
+#endif
diff --git a/include/asm-i386/string.h b/include/asm-x86/string_32.h
similarity index 100%
rename from include/asm-i386/string.h
rename to include/asm-x86/string_32.h
diff --git a/include/asm-x86_64/string.h b/include/asm-x86/string_64.h
similarity index 100%
rename from include/asm-x86_64/string.h
rename to include/asm-x86/string_64.h
diff --git a/include/asm-x86/suspend.h b/include/asm-x86/suspend.h
new file mode 100644
index 0000000..9bd521f
--- /dev/null
+++ b/include/asm-x86/suspend.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "suspend_32.h"
+#else
+# include "suspend_64.h"
+#endif
diff --git a/include/asm-i386/suspend.h b/include/asm-x86/suspend_32.h
similarity index 100%
rename from include/asm-i386/suspend.h
rename to include/asm-x86/suspend_32.h
diff --git a/include/asm-x86_64/suspend.h b/include/asm-x86/suspend_64.h
similarity index 100%
rename from include/asm-x86_64/suspend.h
rename to include/asm-x86/suspend_64.h
diff --git a/include/asm-x86_64/swiotlb.h b/include/asm-x86/swiotlb.h
similarity index 100%
rename from include/asm-x86_64/swiotlb.h
rename to include/asm-x86/swiotlb.h
diff --git a/include/asm-i386/sync_bitops.h b/include/asm-x86/sync_bitops.h
similarity index 100%
rename from include/asm-i386/sync_bitops.h
rename to include/asm-x86/sync_bitops.h
diff --git a/include/asm-x86/system.h b/include/asm-x86/system.h
new file mode 100644
index 0000000..692562b
--- /dev/null
+++ b/include/asm-x86/system.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "system_32.h"
+#else
+# include "system_64.h"
+#endif
diff --git a/include/asm-i386/system.h b/include/asm-x86/system_32.h
similarity index 100%
rename from include/asm-i386/system.h
rename to include/asm-x86/system_32.h
diff --git a/include/asm-x86_64/system.h b/include/asm-x86/system_64.h
similarity index 100%
rename from include/asm-x86_64/system.h
rename to include/asm-x86/system_64.h
diff --git a/include/asm-x86_64/tce.h b/include/asm-x86/tce.h
similarity index 100%
rename from include/asm-x86_64/tce.h
rename to include/asm-x86/tce.h
diff --git a/include/asm-x86/termbits.h b/include/asm-x86/termbits.h
new file mode 100644
index 0000000..69f3080
--- /dev/null
+++ b/include/asm-x86/termbits.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "termbits_32.h"
+# else
+#  include "termbits_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "termbits_32.h"
+# else
+#  include "termbits_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/termbits.h b/include/asm-x86/termbits_32.h
similarity index 100%
rename from include/asm-i386/termbits.h
rename to include/asm-x86/termbits_32.h
diff --git a/include/asm-x86_64/termbits.h b/include/asm-x86/termbits_64.h
similarity index 100%
rename from include/asm-x86_64/termbits.h
rename to include/asm-x86/termbits_64.h
diff --git a/include/asm-x86/termios.h b/include/asm-x86/termios.h
new file mode 100644
index 0000000..a4f4ae2
--- /dev/null
+++ b/include/asm-x86/termios.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "termios_32.h"
+# else
+#  include "termios_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "termios_32.h"
+# else
+#  include "termios_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/termios.h b/include/asm-x86/termios_32.h
similarity index 98%
rename from include/asm-i386/termios.h
rename to include/asm-x86/termios_32.h
index f520b7c..6fdb2c8 100644
--- a/include/asm-i386/termios.h
+++ b/include/asm-x86/termios_32.h
@@ -40,7 +40,6 @@
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
 #ifdef __KERNEL__
-#include <linux/module.h>
 
 /*	intr=^C		quit=^\		erase=del	kill=^U
 	eof=^D		vtime=\0	vmin=\1		sxtc=\0
diff --git a/include/asm-x86_64/termios.h b/include/asm-x86/termios_64.h
similarity index 100%
rename from include/asm-x86_64/termios.h
rename to include/asm-x86/termios_64.h
diff --git a/include/asm-i386/therm_throt.h b/include/asm-x86/therm_throt.h
similarity index 100%
rename from include/asm-i386/therm_throt.h
rename to include/asm-x86/therm_throt.h
diff --git a/include/asm-x86/thread_info.h b/include/asm-x86/thread_info.h
new file mode 100644
index 0000000..d5fd12f
--- /dev/null
+++ b/include/asm-x86/thread_info.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "thread_info_32.h"
+#else
+# include "thread_info_64.h"
+#endif
diff --git a/include/asm-i386/thread_info.h b/include/asm-x86/thread_info_32.h
similarity index 100%
rename from include/asm-i386/thread_info.h
rename to include/asm-x86/thread_info_32.h
diff --git a/include/asm-x86_64/thread_info.h b/include/asm-x86/thread_info_64.h
similarity index 100%
rename from include/asm-x86_64/thread_info.h
rename to include/asm-x86/thread_info_64.h
diff --git a/include/asm-i386/time.h b/include/asm-x86/time.h
similarity index 100%
rename from include/asm-i386/time.h
rename to include/asm-x86/time.h
diff --git a/include/asm-i386/timer.h b/include/asm-x86/timer.h
similarity index 100%
rename from include/asm-i386/timer.h
rename to include/asm-x86/timer.h
diff --git a/include/asm-x86/timex.h b/include/asm-x86/timex.h
new file mode 100644
index 0000000..d01c18c
--- /dev/null
+++ b/include/asm-x86/timex.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "timex_32.h"
+#else
+# include "timex_64.h"
+#endif
diff --git a/include/asm-i386/timex.h b/include/asm-x86/timex_32.h
similarity index 100%
rename from include/asm-i386/timex.h
rename to include/asm-x86/timex_32.h
diff --git a/include/asm-x86_64/timex.h b/include/asm-x86/timex_64.h
similarity index 100%
rename from include/asm-x86_64/timex.h
rename to include/asm-x86/timex_64.h
diff --git a/include/asm-x86/tlb.h b/include/asm-x86/tlb.h
new file mode 100644
index 0000000..7d55c37
--- /dev/null
+++ b/include/asm-x86/tlb.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "tlb_32.h"
+#else
+# include "tlb_64.h"
+#endif
diff --git a/include/asm-i386/tlb.h b/include/asm-x86/tlb_32.h
similarity index 100%
rename from include/asm-i386/tlb.h
rename to include/asm-x86/tlb_32.h
diff --git a/include/asm-x86_64/tlb.h b/include/asm-x86/tlb_64.h
similarity index 100%
rename from include/asm-x86_64/tlb.h
rename to include/asm-x86/tlb_64.h
diff --git a/include/asm-x86/tlbflush.h b/include/asm-x86/tlbflush.h
new file mode 100644
index 0000000..9af4cc8
--- /dev/null
+++ b/include/asm-x86/tlbflush.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "tlbflush_32.h"
+#else
+# include "tlbflush_64.h"
+#endif
diff --git a/include/asm-i386/tlbflush.h b/include/asm-x86/tlbflush_32.h
similarity index 100%
rename from include/asm-i386/tlbflush.h
rename to include/asm-x86/tlbflush_32.h
diff --git a/include/asm-x86_64/tlbflush.h b/include/asm-x86/tlbflush_64.h
similarity index 100%
rename from include/asm-x86_64/tlbflush.h
rename to include/asm-x86/tlbflush_64.h
diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h
new file mode 100644
index 0000000..b10fde9
--- /dev/null
+++ b/include/asm-x86/topology.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "topology_32.h"
+#else
+# include "topology_64.h"
+#endif
diff --git a/include/asm-i386/topology.h b/include/asm-x86/topology_32.h
similarity index 100%
rename from include/asm-i386/topology.h
rename to include/asm-x86/topology_32.h
diff --git a/include/asm-x86_64/topology.h b/include/asm-x86/topology_64.h
similarity index 100%
rename from include/asm-x86_64/topology.h
rename to include/asm-x86/topology_64.h
diff --git a/include/asm-i386/tsc.h b/include/asm-x86/tsc.h
similarity index 100%
rename from include/asm-i386/tsc.h
rename to include/asm-x86/tsc.h
diff --git a/include/asm-x86/types.h b/include/asm-x86/types.h
new file mode 100644
index 0000000..a777a9b
--- /dev/null
+++ b/include/asm-x86/types.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "types_32.h"
+# else
+#  include "types_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "types_32.h"
+# else
+#  include "types_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/types.h b/include/asm-x86/types_32.h
similarity index 100%
rename from include/asm-i386/types.h
rename to include/asm-x86/types_32.h
diff --git a/include/asm-x86_64/types.h b/include/asm-x86/types_64.h
similarity index 100%
rename from include/asm-x86_64/types.h
rename to include/asm-x86/types_64.h
diff --git a/include/asm-x86/uaccess.h b/include/asm-x86/uaccess.h
new file mode 100644
index 0000000..9fefd29
--- /dev/null
+++ b/include/asm-x86/uaccess.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "uaccess_32.h"
+#else
+# include "uaccess_64.h"
+#endif
diff --git a/include/asm-i386/uaccess.h b/include/asm-x86/uaccess_32.h
similarity index 100%
rename from include/asm-i386/uaccess.h
rename to include/asm-x86/uaccess_32.h
diff --git a/include/asm-x86_64/uaccess.h b/include/asm-x86/uaccess_64.h
similarity index 100%
rename from include/asm-x86_64/uaccess.h
rename to include/asm-x86/uaccess_64.h
diff --git a/include/asm-x86/ucontext.h b/include/asm-x86/ucontext.h
new file mode 100644
index 0000000..175c8cb
--- /dev/null
+++ b/include/asm-x86/ucontext.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "ucontext_32.h"
+# else
+#  include "ucontext_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "ucontext_32.h"
+# else
+#  include "ucontext_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/ucontext.h b/include/asm-x86/ucontext_32.h
similarity index 100%
rename from include/asm-i386/ucontext.h
rename to include/asm-x86/ucontext_32.h
diff --git a/include/asm-x86_64/ucontext.h b/include/asm-x86/ucontext_64.h
similarity index 100%
rename from include/asm-x86_64/ucontext.h
rename to include/asm-x86/ucontext_64.h
diff --git a/include/asm-x86/unaligned.h b/include/asm-x86/unaligned.h
new file mode 100644
index 0000000..6806715
--- /dev/null
+++ b/include/asm-x86/unaligned.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "unaligned_32.h"
+#else
+# include "unaligned_64.h"
+#endif
diff --git a/include/asm-i386/unaligned.h b/include/asm-x86/unaligned_32.h
similarity index 100%
rename from include/asm-i386/unaligned.h
rename to include/asm-x86/unaligned_32.h
diff --git a/include/asm-x86_64/unaligned.h b/include/asm-x86/unaligned_64.h
similarity index 100%
rename from include/asm-x86_64/unaligned.h
rename to include/asm-x86/unaligned_64.h
diff --git a/include/asm-x86/unistd.h b/include/asm-x86/unistd.h
new file mode 100644
index 0000000..2a58ed3
--- /dev/null
+++ b/include/asm-x86/unistd.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "unistd_32.h"
+# else
+#  include "unistd_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "unistd_32.h"
+# else
+#  include "unistd_64.h"
+# endif
+#endif
diff --git a/include/asm-i386/unistd.h b/include/asm-x86/unistd_32.h
similarity index 100%
rename from include/asm-i386/unistd.h
rename to include/asm-x86/unistd_32.h
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86/unistd_64.h
similarity index 100%
rename from include/asm-x86_64/unistd.h
rename to include/asm-x86/unistd_64.h
diff --git a/include/asm-x86/unwind.h b/include/asm-x86/unwind.h
new file mode 100644
index 0000000..7e4d7ad
--- /dev/null
+++ b/include/asm-x86/unwind.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "unwind_32.h"
+#else
+# include "unwind_64.h"
+#endif
diff --git a/include/asm-i386/unwind.h b/include/asm-x86/unwind_32.h
similarity index 100%
rename from include/asm-i386/unwind.h
rename to include/asm-x86/unwind_32.h
diff --git a/include/asm-x86_64/unwind.h b/include/asm-x86/unwind_64.h
similarity index 100%
rename from include/asm-x86_64/unwind.h
rename to include/asm-x86/unwind_64.h
diff --git a/include/asm-x86/user.h b/include/asm-x86/user.h
new file mode 100644
index 0000000..484715a
--- /dev/null
+++ b/include/asm-x86/user.h
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "user_32.h"
+# else
+#  include "user_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "user_32.h"
+# else
+#  include "user_64.h"
+# endif
+#endif
diff --git a/include/asm-x86_64/user32.h b/include/asm-x86/user32.h
similarity index 100%
rename from include/asm-x86_64/user32.h
rename to include/asm-x86/user32.h
diff --git a/include/asm-i386/user.h b/include/asm-x86/user_32.h
similarity index 100%
rename from include/asm-i386/user.h
rename to include/asm-x86/user_32.h
diff --git a/include/asm-x86_64/user.h b/include/asm-x86/user_64.h
similarity index 100%
rename from include/asm-x86_64/user.h
rename to include/asm-x86/user_64.h
diff --git a/include/asm-i386/vga.h b/include/asm-x86/vga.h
similarity index 100%
rename from include/asm-i386/vga.h
rename to include/asm-x86/vga.h
diff --git a/include/asm-x86_64/vgtod.h b/include/asm-x86/vgtod.h
similarity index 100%
rename from include/asm-x86_64/vgtod.h
rename to include/asm-x86/vgtod.h
diff --git a/include/asm-i386/vic.h b/include/asm-x86/vic.h
similarity index 100%
rename from include/asm-i386/vic.h
rename to include/asm-x86/vic.h
diff --git a/include/asm-i386/vm86.h b/include/asm-x86/vm86.h
similarity index 100%
rename from include/asm-i386/vm86.h
rename to include/asm-x86/vm86.h
diff --git a/include/asm-i386/vmi.h b/include/asm-x86/vmi.h
similarity index 100%
rename from include/asm-i386/vmi.h
rename to include/asm-x86/vmi.h
diff --git a/include/asm-i386/vmi_time.h b/include/asm-x86/vmi_time.h
similarity index 100%
rename from include/asm-i386/vmi_time.h
rename to include/asm-x86/vmi_time.h
diff --git a/include/asm-i386/voyager.h b/include/asm-x86/voyager.h
similarity index 100%
rename from include/asm-i386/voyager.h
rename to include/asm-x86/voyager.h
diff --git a/include/asm-x86_64/vsyscall.h b/include/asm-x86/vsyscall.h
similarity index 100%
rename from include/asm-x86_64/vsyscall.h
rename to include/asm-x86/vsyscall.h
diff --git a/include/asm-x86_64/vsyscall32.h b/include/asm-x86/vsyscall32.h
similarity index 100%
rename from include/asm-x86_64/vsyscall32.h
rename to include/asm-x86/vsyscall32.h
diff --git a/include/asm-i386/xen/hypercall.h b/include/asm-x86/xen/hypercall.h
similarity index 100%
rename from include/asm-i386/xen/hypercall.h
rename to include/asm-x86/xen/hypercall.h
diff --git a/include/asm-i386/xen/hypervisor.h b/include/asm-x86/xen/hypervisor.h
similarity index 100%
rename from include/asm-i386/xen/hypervisor.h
rename to include/asm-x86/xen/hypervisor.h
diff --git a/include/asm-i386/xen/interface.h b/include/asm-x86/xen/interface.h
similarity index 100%
rename from include/asm-i386/xen/interface.h
rename to include/asm-x86/xen/interface.h
diff --git a/include/asm-x86/xor.h b/include/asm-x86/xor.h
new file mode 100644
index 0000000..11b3bb8
--- /dev/null
+++ b/include/asm-x86/xor.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "xor_32.h"
+#else
+# include "xor_64.h"
+#endif
diff --git a/include/asm-i386/xor.h b/include/asm-x86/xor_32.h
similarity index 100%
rename from include/asm-i386/xor.h
rename to include/asm-x86/xor_32.h
diff --git a/include/asm-x86_64/xor.h b/include/asm-x86/xor_64.h
similarity index 100%
rename from include/asm-x86_64/xor.h
rename to include/asm-x86/xor_64.h
diff --git a/include/asm-x86_64/Kbuild b/include/asm-x86_64/Kbuild
deleted file mode 100644
index 75a2def..0000000
--- a/include/asm-x86_64/Kbuild
+++ /dev/null
@@ -1,21 +0,0 @@
-include include/asm-generic/Kbuild.asm
-
-ALTARCH := i386
-ARCHDEF := defined __x86_64__
-ALTARCHDEF := defined __i386__
-
-header-y += boot.h
-header-y += bootsetup.h
-header-y += debugreg.h
-header-y += ldt.h
-header-y += msr-index.h
-header-y += prctl.h
-header-y += ptrace-abi.h
-header-y += sigcontext32.h
-header-y += ucontext.h
-header-y += vsyscall32.h
-
-unifdef-y += mce.h
-unifdef-y += msr.h
-unifdef-y += mtrr.h
-unifdef-y += vsyscall.h
diff --git a/include/asm-x86_64/boot.h b/include/asm-x86_64/boot.h
deleted file mode 100644
index 3c46cea..0000000
--- a/include/asm-x86_64/boot.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/boot.h>
diff --git a/include/asm-x86_64/bootparam.h b/include/asm-x86_64/bootparam.h
deleted file mode 100644
index aa82e52..0000000
--- a/include/asm-x86_64/bootparam.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/bootparam.h>
diff --git a/include/asm-x86_64/cpu.h b/include/asm-x86_64/cpu.h
deleted file mode 100644
index 8eea076..0000000
--- a/include/asm-x86_64/cpu.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/cpu.h>
diff --git a/include/asm-x86_64/emergency-restart.h b/include/asm-x86_64/emergency-restart.h
deleted file mode 100644
index 680c395..0000000
--- a/include/asm-x86_64/emergency-restart.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_EMERGENCY_RESTART_H
-#define _ASM_EMERGENCY_RESTART_H
-
-extern void machine_emergency_restart(void);
-
-#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-x86_64/fcntl.h b/include/asm-x86_64/fcntl.h
deleted file mode 100644
index 46ab12d..0000000
--- a/include/asm-x86_64/fcntl.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/fcntl.h>
diff --git a/include/asm-x86_64/hypertransport.h b/include/asm-x86_64/hypertransport.h
deleted file mode 100644
index 5cbf9fa..0000000
--- a/include/asm-x86_64/hypertransport.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/hypertransport.h>
diff --git a/include/asm-x86_64/ide.h b/include/asm-x86_64/ide.h
deleted file mode 100644
index 4cef0ef..0000000
--- a/include/asm-x86_64/ide.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/ide.h>
diff --git a/include/asm-x86_64/ioctl.h b/include/asm-x86_64/ioctl.h
deleted file mode 100644
index b279fe0..0000000
--- a/include/asm-x86_64/ioctl.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ioctl.h>
diff --git a/include/asm-x86_64/ist.h b/include/asm-x86_64/ist.h
deleted file mode 100644
index 338857e..0000000
--- a/include/asm-x86_64/ist.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/ist.h>
diff --git a/include/asm-x86_64/msidef.h b/include/asm-x86_64/msidef.h
deleted file mode 100644
index 083ad58..0000000
--- a/include/asm-x86_64/msidef.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/msidef.h>
diff --git a/include/asm-x86_64/msr-index.h b/include/asm-x86_64/msr-index.h
deleted file mode 100644
index d77a63f..0000000
--- a/include/asm-x86_64/msr-index.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/msr-index.h>
diff --git a/include/asm-x86_64/node.h b/include/asm-x86_64/node.h
deleted file mode 100644
index 0ee6f88..0000000
--- a/include/asm-x86_64/node.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/node.h>
diff --git a/include/asm-x86_64/poll.h b/include/asm-x86_64/poll.h
deleted file mode 100644
index c98509d..0000000
--- a/include/asm-x86_64/poll.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/poll.h>
diff --git a/include/asm-x86_64/processor-flags.h b/include/asm-x86_64/processor-flags.h
deleted file mode 100644
index ec99a57..0000000
--- a/include/asm-x86_64/processor-flags.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/processor-flags.h>
diff --git a/include/asm-x86_64/socket.h b/include/asm-x86_64/socket.h
deleted file mode 100644
index 90af60c..0000000
--- a/include/asm-x86_64/socket.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef _ASM_SOCKET_H
-#define _ASM_SOCKET_H
-
-#include <asm/sockios.h>
-
-/* For setsockopt(2) */
-#define SOL_SOCKET	1
-
-#define SO_DEBUG	1
-#define SO_REUSEADDR	2
-#define SO_TYPE		3
-#define SO_ERROR	4
-#define SO_DONTROUTE	5
-#define SO_BROADCAST	6
-#define SO_SNDBUF	7
-#define SO_RCVBUF	8
-#define SO_SNDBUFFORCE	32
-#define SO_RCVBUFFORCE	33
-#define SO_KEEPALIVE	9
-#define SO_OOBINLINE	10
-#define SO_NO_CHECK	11
-#define SO_PRIORITY	12
-#define SO_LINGER	13
-#define SO_BSDCOMPAT	14
-/* To add :#define SO_REUSEPORT 15 */
-#define SO_PASSCRED	16
-#define SO_PEERCRED	17
-#define SO_RCVLOWAT	18
-#define SO_SNDLOWAT	19
-#define SO_RCVTIMEO	20
-#define SO_SNDTIMEO	21
-
-/* Security levels - as per NRL IPv6 - don't actually do anything */
-#define SO_SECURITY_AUTHENTICATION		22
-#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
-#define SO_SECURITY_ENCRYPTION_NETWORK		24
-
-#define SO_BINDTODEVICE	25
-
-/* Socket filtering */
-#define SO_ATTACH_FILTER        26
-#define SO_DETACH_FILTER        27
-
-#define SO_PEERNAME		28
-#define SO_TIMESTAMP		29
-#define SCM_TIMESTAMP		SO_TIMESTAMP
-
-#define SO_ACCEPTCONN		30
-
-#define SO_PEERSEC             31
-#define SO_PASSSEC		34
-#define SO_TIMESTAMPNS		35
-#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
-
-#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-x86_64/spinlock_types.h b/include/asm-x86_64/spinlock_types.h
deleted file mode 100644
index 4da9345..0000000
--- a/include/asm-x86_64/spinlock_types.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __ASM_SPINLOCK_TYPES_H
-#define __ASM_SPINLOCK_TYPES_H
-
-#ifndef __LINUX_SPINLOCK_TYPES_H
-# error "please don't include this file directly"
-#endif
-
-typedef struct {
-	unsigned int slock;
-} raw_spinlock_t;
-
-#define __RAW_SPIN_LOCK_UNLOCKED	{ 1 }
-
-typedef struct {
-	unsigned int lock;
-} raw_rwlock_t;
-
-#define __RAW_RW_LOCK_UNLOCKED		{ RW_LOCK_BIAS }
-
-#endif
diff --git a/include/asm-x86_64/therm_throt.h b/include/asm-x86_64/therm_throt.h
deleted file mode 100644
index 5aac059..0000000
--- a/include/asm-x86_64/therm_throt.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/therm_throt.h>
diff --git a/include/asm-x86_64/tsc.h b/include/asm-x86_64/tsc.h
deleted file mode 100644
index d66ba6e..0000000
--- a/include/asm-x86_64/tsc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/tsc.h>
diff --git a/include/asm-x86_64/vga.h b/include/asm-x86_64/vga.h
deleted file mode 100644
index 0ecf68a..0000000
--- a/include/asm-x86_64/vga.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *	Access to VGA videoram
- *
- *	(c) 1998 Martin Mares <mj@ucw.cz>
- */
-
-#ifndef _LINUX_ASM_VGA_H_
-#define _LINUX_ASM_VGA_H_
-
-/*
- *	On the PC, we can just recalculate addresses and then
- *	access the videoram directly without any black magic.
- */
-
-#define VGA_MAP_MEM(x,s) (unsigned long)phys_to_virt(x)
-
-#define vga_readb(x) (*(x))
-#define vga_writeb(x,y) (*(y) = (x))
-
-#endif
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index badf702..0d508ac 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -55,7 +55,28 @@
 	unsigned int		hs_max_dtr;
 };
 
+struct sdio_cccr {
+	unsigned int		sdio_vsn;
+	unsigned int		sd_vsn;
+	unsigned int		multi_block:1,
+				low_speed:1,
+				wide_bus:1,
+				high_power:1,
+				high_speed:1;
+};
+
+struct sdio_cis {
+	unsigned short		vendor;
+	unsigned short		device;
+	unsigned short		blksize;
+	unsigned int		max_dtr;
+};
+
 struct mmc_host;
+struct sdio_func;
+struct sdio_func_tuple;
+
+#define SDIO_MAX_FUNCS		7
 
 /*
  * MMC device
@@ -67,11 +88,13 @@
 	unsigned int		type;		/* card type */
 #define MMC_TYPE_MMC		0		/* MMC card */
 #define MMC_TYPE_SD		1		/* SD card */
+#define MMC_TYPE_SDIO		2		/* SDIO card */
 	unsigned int		state;		/* (our) card state */
 #define MMC_STATE_PRESENT	(1<<0)		/* present in sysfs */
 #define MMC_STATE_READONLY	(1<<1)		/* card is read-only */
 #define MMC_STATE_HIGHSPEED	(1<<2)		/* card is in high speed mode */
 #define MMC_STATE_BLOCKADDR	(1<<3)		/* card uses block-addressing */
+
 	u32			raw_cid[4];	/* raw card CID */
 	u32			raw_csd[4];	/* raw card CSD */
 	u32			raw_scr[2];	/* raw card SCR */
@@ -80,10 +103,19 @@
 	struct mmc_ext_csd	ext_csd;	/* mmc v4 extended card specific */
 	struct sd_scr		scr;		/* extra SD information */
 	struct sd_switch_caps	sw_caps;	/* switch (CMD6) caps */
+
+	unsigned int		sdio_funcs;	/* number of SDIO functions */
+	struct sdio_cccr	cccr;		/* common card info */
+	struct sdio_cis		cis;		/* common tuple info */
+	struct sdio_func	*sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions (devices) */
+	unsigned		num_info;	/* number of info strings */
+	const char		**info;		/* info strings */
+	struct sdio_func_tuple	*tuples;	/* unknown common tuples */
 };
 
 #define mmc_card_mmc(c)		((c)->type == MMC_TYPE_MMC)
 #define mmc_card_sd(c)		((c)->type == MMC_TYPE_SD)
+#define mmc_card_sdio(c)	((c)->type == MMC_TYPE_SDIO)
 
 #define mmc_card_present(c)	((c)->state & MMC_STATE_PRESENT)
 #define mmc_card_readonly(c)	((c)->state & MMC_STATE_READONLY)
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 63a80ea..d0c3abe 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -25,14 +25,20 @@
 #define MMC_RSP_CRC	(1 << 2)		/* expect valid crc */
 #define MMC_RSP_BUSY	(1 << 3)		/* card may send busy */
 #define MMC_RSP_OPCODE	(1 << 4)		/* response contains opcode */
-#define MMC_CMD_MASK	(3 << 5)		/* command type */
+
+#define MMC_CMD_MASK	(3 << 5)		/* non-SPI command type */
 #define MMC_CMD_AC	(0 << 5)
 #define MMC_CMD_ADTC	(1 << 5)
 #define MMC_CMD_BC	(2 << 5)
 #define MMC_CMD_BCR	(3 << 5)
 
+#define MMC_RSP_SPI_S1	(1 << 7)		/* one status byte */
+#define MMC_RSP_SPI_S2	(1 << 8)		/* second byte */
+#define MMC_RSP_SPI_B4	(1 << 9)		/* four data bytes */
+#define MMC_RSP_SPI_BUSY (1 << 10)		/* card may send busy */
+
 /*
- * These are the response types, and correspond to valid bit
+ * These are the native response types, and correspond to valid bit
  * patterns of the above flags.  One additional valid pattern
  * is all zeros, which means we don't expect a response.
  */
@@ -41,12 +47,30 @@
 #define MMC_RSP_R1B	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
 #define MMC_RSP_R2	(MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
 #define MMC_RSP_R3	(MMC_RSP_PRESENT)
+#define MMC_RSP_R4	(MMC_RSP_PRESENT)
+#define MMC_RSP_R5	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
 #define MMC_RSP_R6	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
 #define MMC_RSP_R7	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
 
 #define mmc_resp_type(cmd)	((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE))
 
 /*
+ * These are the SPI response types for MMC, SD, and SDIO cards.
+ * Commands return R1, with maybe more info.  Zero is an error type;
+ * callers must always provide the appropriate MMC_RSP_SPI_Rx flags.
+ */
+#define MMC_RSP_SPI_R1	(MMC_RSP_SPI_S1)
+#define MMC_RSP_SPI_R1B	(MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY)
+#define MMC_RSP_SPI_R2	(MMC_RSP_SPI_S1|MMC_RSP_SPI_S2)
+#define MMC_RSP_SPI_R3	(MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
+#define MMC_RSP_SPI_R4	(MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
+#define MMC_RSP_SPI_R5	(MMC_RSP_SPI_S1|MMC_RSP_SPI_S2)
+#define MMC_RSP_SPI_R7	(MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
+
+#define mmc_spi_resp_type(cmd)	((cmd)->flags & \
+		(MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY|MMC_RSP_SPI_S2|MMC_RSP_SPI_B4))
+
+/*
  * These are the command types.
  */
 #define mmc_cmd_type(cmd)	((cmd)->flags & MMC_CMD_MASK)
@@ -54,12 +78,19 @@
 	unsigned int		retries;	/* max number of retries */
 	unsigned int		error;		/* command error */
 
-#define MMC_ERR_NONE	0
-#define MMC_ERR_TIMEOUT	1
-#define MMC_ERR_BADCRC	2
-#define MMC_ERR_FIFO	3
-#define MMC_ERR_FAILED	4
-#define MMC_ERR_INVALID	5
+/*
+ * Standard errno values are used for errors, but some have specific
+ * meaning in the MMC layer:
+ *
+ * ETIMEDOUT    Card took too long to respond
+ * EILSEQ       Basic format problem with the received or sent data
+ *              (e.g. CRC check failed, incorrect opcode in response
+ *              or bad end bit)
+ * EINVAL       Request cannot be performed because of restrictions
+ *              in hardware and/or the driver
+ * ENOMEDIUM    Host can determine that the slot is empty and is
+ *              actively failing requests
+ */
 
 	struct mmc_data		*data;		/* data segment associated with cmd */
 	struct mmc_request	*mrq;		/* associated request */
@@ -76,7 +107,6 @@
 #define MMC_DATA_WRITE	(1 << 8)
 #define MMC_DATA_READ	(1 << 9)
 #define MMC_DATA_STREAM	(1 << 10)
-#define MMC_DATA_MULTI	(1 << 11)
 
 	unsigned int		bytes_xfered;
 
@@ -104,9 +134,20 @@
 extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *,
 	struct mmc_command *, int);
 
-extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *, int);
+extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *);
 
-extern void mmc_claim_host(struct mmc_host *host);
+extern int __mmc_claim_host(struct mmc_host *host, atomic_t *abort);
 extern void mmc_release_host(struct mmc_host *host);
 
+/**
+ *	mmc_claim_host - exclusively claim a host
+ *	@host: mmc host to claim
+ *
+ *	Claim a host for a set of operations.
+ */
+static inline void mmc_claim_host(struct mmc_host *host)
+{
+	__mmc_claim_host(host, NULL);
+}
+
 #endif
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index b1350df..125eee1 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -10,6 +10,8 @@
 #ifndef LINUX_MMC_HOST_H
 #define LINUX_MMC_HOST_H
 
+#include <linux/leds.h>
+
 #include <linux/mmc/core.h>
 
 struct mmc_ios {
@@ -51,6 +53,7 @@
 	void	(*request)(struct mmc_host *host, struct mmc_request *req);
 	void	(*set_ios)(struct mmc_host *host, struct mmc_ios *ios);
 	int	(*get_ro)(struct mmc_host *host);
+	void	(*enable_sdio_irq)(struct mmc_host *host, int enable);
 };
 
 struct mmc_card;
@@ -87,9 +90,10 @@
 
 #define MMC_CAP_4_BIT_DATA	(1 << 0)	/* Can the host do 4 bit transfers */
 #define MMC_CAP_MULTIWRITE	(1 << 1)	/* Can accurately report bytes sent to card on error */
-#define MMC_CAP_BYTEBLOCK	(1 << 2)	/* Can do non-log2 block sizes */
-#define MMC_CAP_MMC_HIGHSPEED	(1 << 3)	/* Can do MMC high-speed timing */
-#define MMC_CAP_SD_HIGHSPEED	(1 << 4)	/* Can do SD high-speed timing */
+#define MMC_CAP_MMC_HIGHSPEED	(1 << 2)	/* Can do MMC high-speed timing */
+#define MMC_CAP_SD_HIGHSPEED	(1 << 3)	/* Can do SD high-speed timing */
+#define MMC_CAP_SDIO_IRQ	(1 << 4)	/* Can signal pending SDIO IRQs */
+#define MMC_CAP_SPI		(1 << 5)	/* Talks only SPI protocols */
 
 	/* host specific block data */
 	unsigned int		max_seg_size;	/* see blk_queue_max_segment_size */
@@ -106,6 +110,14 @@
 	struct mmc_ios		ios;		/* current io bus settings */
 	u32			ocr;		/* the current OCR setting */
 
+	/* group bitfields together to minimize padding */
+	unsigned int		use_spi_crc:1;
+	unsigned int		claimed:1;	/* host exclusively claimed */
+	unsigned int		bus_dead:1;	/* bus has been released */
+#ifdef CONFIG_MMC_DEBUG
+	unsigned int		removed:1;	/* host is being removed */
+#endif
+
 	unsigned int		mode;		/* current card mode of host */
 #define MMC_MODE_MMC		0
 #define MMC_MODE_SD		1
@@ -113,16 +125,19 @@
 	struct mmc_card		*card;		/* device attached to this host */
 
 	wait_queue_head_t	wq;
-	unsigned int		claimed:1;	/* host exclusively claimed */
 
 	struct delayed_work	detect;
-#ifdef CONFIG_MMC_DEBUG
-	unsigned int		removed:1;	/* host is being removed */
-#endif
 
 	const struct mmc_bus_ops *bus_ops;	/* current bus driver */
 	unsigned int		bus_refs;	/* reference counter */
-	unsigned int		bus_dead:1;	/* bus has been released */
+
+	unsigned int		sdio_irqs;
+	struct task_struct	*sdio_irq_thread;
+	atomic_t		sdio_irq_thread_abort;
+
+#ifdef CONFIG_LEDS_TRIGGERS
+	struct led_trigger	*led;		/* activity led */
+#endif
 
 	unsigned long		private[0] ____cacheline_aligned;
 };
@@ -137,6 +152,8 @@
 	return (void *)host->private;
 }
 
+#define mmc_host_is_spi(host)	((host)->caps & MMC_CAP_SPI)
+
 #define mmc_dev(x)	((x)->parent)
 #define mmc_classdev(x)	(&(x)->class_dev)
 #define mmc_hostname(x)	((x)->class_dev.bus_id)
@@ -147,5 +164,11 @@
 extern void mmc_detect_change(struct mmc_host *, unsigned long delay);
 extern void mmc_request_done(struct mmc_host *, struct mmc_request *);
 
+static inline void mmc_signal_sdio_irq(struct mmc_host *host)
+{
+	host->ops->enable_sdio_irq(host, 0);
+	wake_up_process(host->sdio_irq_thread);
+}
+
 #endif
 
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index e3ed9b9..4236fbf 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -27,7 +27,7 @@
 
 /* Standard MMC commands (4.1)           type  argument     response */
    /* class 1 */
-#define	MMC_GO_IDLE_STATE         0   /* bc                          */
+#define MMC_GO_IDLE_STATE         0   /* bc                          */
 #define MMC_SEND_OP_COND          1   /* bcr  [31:0] OCR         R3  */
 #define MMC_ALL_SEND_CID          2   /* bcr                     R2  */
 #define MMC_SET_RELATIVE_ADDR     3   /* ac   [31:16] RCA        R1  */
@@ -39,8 +39,10 @@
 #define MMC_SEND_CID             10   /* ac   [31:16] RCA        R2  */
 #define MMC_READ_DAT_UNTIL_STOP  11   /* adtc [31:0] dadr        R1  */
 #define MMC_STOP_TRANSMISSION    12   /* ac                      R1b */
-#define MMC_SEND_STATUS	         13   /* ac   [31:16] RCA        R1  */
+#define MMC_SEND_STATUS          13   /* ac   [31:16] RCA        R1  */
 #define MMC_GO_INACTIVE_STATE    15   /* ac   [31:16] RCA            */
+#define MMC_SPI_READ_OCR         58   /* spi                  spi_R3 */
+#define MMC_SPI_CRC_ON_OFF       59   /* spi  [0:0] flag      spi_R1 */
 
   /* class 2 */
 #define MMC_SET_BLOCKLEN         16   /* ac   [31:0] block len   R1  */
@@ -90,15 +92,15 @@
  */
 
 /*
-  MMC status in R1
+  MMC status in R1, for native mode (SPI bits are different)
   Type
-  	e : error bit
+	e : error bit
 	s : status bit
 	r : detected and set for the actual command response
 	x : detected and set during command execution. the host must poll
             the card by sending status command in order to read these bits.
   Clear condition
-  	a : according to the card state
+	a : according to the card state
 	b : always related to the previous command. Reception of
             a valid command will clear it (with a delay of one command)
 	c : clear by read
@@ -124,10 +126,33 @@
 #define R1_CARD_ECC_DISABLED	(1 << 14)	/* sx, a */
 #define R1_ERASE_RESET		(1 << 13)	/* sr, c */
 #define R1_STATUS(x)            (x & 0xFFFFE000)
-#define R1_CURRENT_STATE(x)    	((x & 0x00001E00) >> 9)	/* sx, b (4 bits) */
+#define R1_CURRENT_STATE(x)	((x & 0x00001E00) >> 9)	/* sx, b (4 bits) */
 #define R1_READY_FOR_DATA	(1 << 8)	/* sx, a */
 #define R1_APP_CMD		(1 << 5)	/* sr, c */
 
+/*
+ * MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS
+ * R1 is the low order byte; R2 is the next highest byte, when present.
+ */
+#define R1_SPI_IDLE		(1 << 0)
+#define R1_SPI_ERASE_RESET	(1 << 1)
+#define R1_SPI_ILLEGAL_COMMAND	(1 << 2)
+#define R1_SPI_COM_CRC		(1 << 3)
+#define R1_SPI_ERASE_SEQ	(1 << 4)
+#define R1_SPI_ADDRESS		(1 << 5)
+#define R1_SPI_PARAMETER	(1 << 6)
+/* R1 bit 7 is always zero */
+#define R2_SPI_CARD_LOCKED	(1 << 8)
+#define R2_SPI_WP_ERASE_SKIP	(1 << 9)	/* or lock/unlock fail */
+#define R2_SPI_LOCK_UNLOCK_FAIL	R2_SPI_WP_ERASE_SKIP
+#define R2_SPI_ERROR		(1 << 10)
+#define R2_SPI_CC_ERROR		(1 << 11)
+#define R2_SPI_CARD_ECC_ERROR	(1 << 12)
+#define R2_SPI_WP_VIOLATION	(1 << 13)
+#define R2_SPI_ERASE_PARAM	(1 << 14)
+#define R2_SPI_OUT_OF_RANGE	(1 << 15)	/* or CSD overwrite */
+#define R2_SPI_CSD_OVERWRITE	R2_SPI_OUT_OF_RANGE
+
 /* These are unpacked versions of the actual responses */
 
 struct _mmc_csd {
@@ -182,6 +207,7 @@
  */
 #define CCC_BASIC		(1<<0)	/* (0) Basic protocol functions */
 					/* (CMD0,1,2,3,4,7,9,10,12,13,15) */
+					/* (and for SPI, CMD58,59) */
 #define CCC_STREAM_READ		(1<<1)	/* (1) Stream read commands */
 					/* (CMD11) */
 #define CCC_BLOCK_READ		(1<<2)	/* (2) Block read commands */
@@ -227,6 +253,7 @@
 #define EXT_CSD_BUS_WIDTH	183	/* R/W */
 #define EXT_CSD_HS_TIMING	185	/* R/W */
 #define EXT_CSD_CARD_TYPE	196	/* RO */
+#define EXT_CSD_REV		192	/* RO */
 #define EXT_CSD_SEC_CNT		212	/* RO, 4 bytes */
 
 /*
diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h
new file mode 100644
index 0000000..47ba464
--- /dev/null
+++ b/include/linux/mmc/sdio.h
@@ -0,0 +1,159 @@
+/*
+ *  include/linux/mmc/sdio.h
+ *
+ *  Copyright 2006-2007 Pierre Ossman
+ *
+ * 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.
+ */
+
+#ifndef MMC_SDIO_H
+#define MMC_SDIO_H
+
+/* SDIO commands                         type  argument     response */
+#define SD_IO_SEND_OP_COND          5 /* bcr  [23:0] OCR         R4  */
+#define SD_IO_RW_DIRECT            52 /* ac   [31:0] See below   R5  */
+#define SD_IO_RW_EXTENDED          53 /* adtc [31:0] See below   R5  */
+
+/*
+ * SD_IO_RW_DIRECT argument format:
+ *
+ *      [31] R/W flag
+ *      [30:28] Function number
+ *      [27] RAW flag
+ *      [25:9] Register address
+ *      [7:0] Data
+ */
+
+/*
+ * SD_IO_RW_EXTENDED argument format:
+ *
+ *      [31] R/W flag
+ *      [30:28] Function number
+ *      [27] Block mode
+ *      [26] Increment address
+ *      [25:9] Register address
+ *      [8:0] Byte/block count
+ */
+
+/*
+  SDIO status in R5
+  Type
+	e : error bit
+	s : status bit
+	r : detected and set for the actual command response
+	x : detected and set during command execution. the host must poll
+            the card by sending status command in order to read these bits.
+  Clear condition
+	a : according to the card state
+	b : always related to the previous command. Reception of
+            a valid command will clear it (with a delay of one command)
+	c : clear by read
+ */
+
+#define R5_COM_CRC_ERROR	(1 << 15)	/* er, b */
+#define R5_ILLEGAL_COMMAND	(1 << 14)	/* er, b */
+#define R5_ERROR		(1 << 11)	/* erx, c */
+#define R5_FUNCTION_NUMBER	(1 << 9)	/* er, c */
+#define R5_OUT_OF_RANGE		(1 << 8)	/* er, c */
+#define R5_STATUS(x)		(x & 0xCB00)
+#define R5_IO_CURRENT_STATE(x)	((x & 0x3000) >> 12) /* s, b */
+
+/*
+ * Card Common Control Registers (CCCR)
+ */
+
+#define SDIO_CCCR_CCCR		0x00
+
+#define  SDIO_CCCR_REV_1_00	0	/* CCCR/FBR Version 1.00 */
+#define  SDIO_CCCR_REV_1_10	1	/* CCCR/FBR Version 1.10 */
+#define  SDIO_CCCR_REV_1_20	2	/* CCCR/FBR Version 1.20 */
+
+#define  SDIO_SDIO_REV_1_00	0	/* SDIO Spec Version 1.00 */
+#define  SDIO_SDIO_REV_1_10	1	/* SDIO Spec Version 1.10 */
+#define  SDIO_SDIO_REV_1_20	2	/* SDIO Spec Version 1.20 */
+#define  SDIO_SDIO_REV_2_00	3	/* SDIO Spec Version 2.00 */
+
+#define SDIO_CCCR_SD		0x01
+
+#define  SDIO_SD_REV_1_01	0	/* SD Physical Spec Version 1.01 */
+#define  SDIO_SD_REV_1_10	1	/* SD Physical Spec Version 1.10 */
+#define  SDIO_SD_REV_2_00	2	/* SD Physical Spec Version 2.00 */
+
+#define SDIO_CCCR_IOEx		0x02
+#define SDIO_CCCR_IORx		0x03
+
+#define SDIO_CCCR_IENx		0x04	/* Function/Master Interrupt Enable */
+#define SDIO_CCCR_INTx		0x05	/* Function Interrupt Pending */
+
+#define SDIO_CCCR_ABORT		0x06	/* function abort/card reset */
+
+#define SDIO_CCCR_IF		0x07	/* bus interface controls */
+
+#define  SDIO_BUS_WIDTH_1BIT	0x00
+#define  SDIO_BUS_WIDTH_4BIT	0x02
+
+#define  SDIO_BUS_CD_DISABLE     0x80	/* disable pull-up on DAT3 (pin 1) */
+
+#define SDIO_CCCR_CAPS		0x08
+
+#define  SDIO_CCCR_CAP_SDC	0x01	/* can do CMD52 while data transfer */
+#define  SDIO_CCCR_CAP_SMB	0x02	/* can do multi-block xfers (CMD53) */
+#define  SDIO_CCCR_CAP_SRW	0x04	/* supports read-wait protocol */
+#define  SDIO_CCCR_CAP_SBS	0x08	/* supports suspend/resume */
+#define  SDIO_CCCR_CAP_S4MI	0x10	/* interrupt during 4-bit CMD53 */
+#define  SDIO_CCCR_CAP_E4MI	0x20	/* enable ints during 4-bit CMD53 */
+#define  SDIO_CCCR_CAP_LSC	0x40	/* low speed card */
+#define  SDIO_CCCR_CAP_4BLS	0x80	/* 4 bit low speed card */
+
+#define SDIO_CCCR_CIS		0x09	/* common CIS pointer (3 bytes) */
+
+/* Following 4 regs are valid only if SBS is set */
+#define SDIO_CCCR_SUSPEND	0x0c
+#define SDIO_CCCR_SELx		0x0d
+#define SDIO_CCCR_EXECx		0x0e
+#define SDIO_CCCR_READYx	0x0f
+
+#define SDIO_CCCR_BLKSIZE	0x10
+
+#define SDIO_CCCR_POWER		0x12
+
+#define  SDIO_POWER_SMPC	0x01	/* Supports Master Power Control */
+#define  SDIO_POWER_EMPC	0x02	/* Enable Master Power Control */
+
+#define SDIO_CCCR_SPEED		0x13
+
+#define  SDIO_SPEED_SHS		0x01	/* Supports High-Speed mode */
+#define  SDIO_SPEED_EHS		0x02	/* Enable High-Speed mode */
+
+/*
+ * Function Basic Registers (FBR)
+ */
+
+#define SDIO_FBR_BASE(f)	((f) * 0x100) /* base of function f's FBRs */
+
+#define SDIO_FBR_STD_IF		0x00
+
+#define  SDIO_FBR_SUPPORTS_CSA	0x40	/* supports Code Storage Area */
+#define  SDIO_FBR_ENABLE_CSA	0x80	/* enable Code Storage Area */
+
+#define SDIO_FBR_STD_IF_EXT	0x01
+
+#define SDIO_FBR_POWER		0x02
+
+#define  SDIO_FBR_POWER_SPS	0x01	/* Supports Power Selection */
+#define  SDIO_FBR_POWER_EPS	0x02	/* Enable (low) Power Selection */
+
+#define SDIO_FBR_CIS		0x09	/* CIS pointer (3 bytes) */
+
+
+#define SDIO_FBR_CSA		0x0C	/* CSA pointer (3 bytes) */
+
+#define SDIO_FBR_CSA_DATA	0x0F
+
+#define SDIO_FBR_BLKSIZE	0x10	/* block size (2 bytes) */
+
+#endif
+
diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h
new file mode 100644
index 0000000..b050f4d
--- /dev/null
+++ b/include/linux/mmc/sdio_func.h
@@ -0,0 +1,153 @@
+/*
+ *  include/linux/mmc/sdio_func.h
+ *
+ *  Copyright 2007 Pierre Ossman
+ *
+ * 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.
+ */
+
+#ifndef MMC_SDIO_FUNC_H
+#define MMC_SDIO_FUNC_H
+
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+
+struct mmc_card;
+struct sdio_func;
+
+typedef void (sdio_irq_handler_t)(struct sdio_func *);
+
+/*
+ * SDIO function CIS tuple (unknown to the core)
+ */
+struct sdio_func_tuple {
+	struct sdio_func_tuple *next;
+	unsigned char code;
+	unsigned char size;
+	unsigned char data[0];
+};
+
+/*
+ * SDIO function devices
+ */
+struct sdio_func {
+	struct mmc_card		*card;		/* the card this device belongs to */
+	struct device		dev;		/* the device */
+	sdio_irq_handler_t	*irq_handler;	/* IRQ callback */
+	unsigned int		num;		/* function number */
+
+	unsigned char		class;		/* standard interface class */
+	unsigned short		vendor;		/* vendor id */
+	unsigned short		device;		/* device id */
+
+	unsigned		max_blksize;	/* maximum block size */
+	unsigned		cur_blksize;	/* current block size */
+
+	unsigned int		state;		/* function state */
+#define SDIO_STATE_PRESENT	(1<<0)		/* present in sysfs */
+
+	u8			tmpbuf[4];	/* DMA:able scratch buffer */
+
+	unsigned		num_info;	/* number of info strings */
+	const char		**info;		/* info strings */
+
+	struct sdio_func_tuple *tuples;
+};
+
+#define sdio_func_present(f)	((f)->state & SDIO_STATE_PRESENT)
+
+#define sdio_func_set_present(f) ((f)->state |= SDIO_STATE_PRESENT)
+
+#define sdio_func_id(f)		((f)->dev.bus_id)
+
+#define sdio_get_drvdata(f)	dev_get_drvdata(&(f)->dev)
+#define sdio_set_drvdata(f,d)	dev_set_drvdata(&(f)->dev, d)
+
+/*
+ * SDIO function device driver
+ */
+struct sdio_driver {
+	char *name;
+	const struct sdio_device_id *id_table;
+
+	int (*probe)(struct sdio_func *, const struct sdio_device_id *);
+	void (*remove)(struct sdio_func *);
+
+	struct device_driver drv;
+};
+
+/**
+ * SDIO_DEVICE - macro used to describe a specific SDIO device
+ * @vend: the 16 bit manufacturer code
+ * @dev: the 16 bit function id
+ *
+ * This macro is used to create a struct sdio_device_id that matches a
+ * specific device. The class field will be set to SDIO_ANY_ID.
+ */
+#define SDIO_DEVICE(vend,dev) \
+	.class = SDIO_ANY_ID, \
+	.vendor = (vend), .device = (dev)
+
+/**
+ * SDIO_DEVICE_CLASS - macro used to describe a specific SDIO device class
+ * @dev_class: the 8 bit standard interface code
+ *
+ * This macro is used to create a struct sdio_device_id that matches a
+ * specific standard SDIO function type.  The vendor and device fields will
+ * be set to SDIO_ANY_ID.
+ */
+#define SDIO_DEVICE_CLASS(dev_class) \
+	.class = (dev_class), \
+	.vendor = SDIO_ANY_ID, .device = SDIO_ANY_ID
+
+extern int sdio_register_driver(struct sdio_driver *);
+extern void sdio_unregister_driver(struct sdio_driver *);
+
+/*
+ * SDIO I/O operations
+ */
+extern void sdio_claim_host(struct sdio_func *func);
+extern void sdio_release_host(struct sdio_func *func);
+
+extern int sdio_enable_func(struct sdio_func *func);
+extern int sdio_disable_func(struct sdio_func *func);
+
+extern int sdio_set_block_size(struct sdio_func *func, unsigned blksz);
+
+extern int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler);
+extern int sdio_release_irq(struct sdio_func *func);
+
+extern unsigned char sdio_readb(struct sdio_func *func,
+	unsigned int addr, int *err_ret);
+extern unsigned short sdio_readw(struct sdio_func *func,
+	unsigned int addr, int *err_ret);
+extern unsigned long sdio_readl(struct sdio_func *func,
+	unsigned int addr, int *err_ret);
+
+extern int sdio_memcpy_fromio(struct sdio_func *func, void *dst,
+	unsigned int addr, int count);
+extern int sdio_readsb(struct sdio_func *func, void *dst,
+	unsigned int addr, int count);
+
+extern void sdio_writeb(struct sdio_func *func, unsigned char b,
+	unsigned int addr, int *err_ret);
+extern void sdio_writew(struct sdio_func *func, unsigned short b,
+	unsigned int addr, int *err_ret);
+extern void sdio_writel(struct sdio_func *func, unsigned long b,
+	unsigned int addr, int *err_ret);
+
+extern int sdio_memcpy_toio(struct sdio_func *func, unsigned int addr,
+	void *src, int count);
+extern int sdio_writesb(struct sdio_func *func, unsigned int addr,
+	void *src, int count);
+
+extern unsigned char sdio_f0_readb(struct sdio_func *func,
+	unsigned int addr, int *err_ret);
+extern void sdio_f0_writeb(struct sdio_func *func, unsigned char b,
+	unsigned int addr, int *err_ret);
+
+#endif
+
diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h
new file mode 100644
index 0000000..09306d4
--- /dev/null
+++ b/include/linux/mmc/sdio_ids.h
@@ -0,0 +1,23 @@
+/*
+ * SDIO Classes, Interface Types, Manufacturer IDs, etc.
+ */
+
+#ifndef MMC_SDIO_IDS_H
+#define MMC_SDIO_IDS_H
+
+/*
+ * Standard SDIO Function Interfaces
+ */
+
+#define SDIO_CLASS_NONE		0x00	/* Not a SDIO standard interface */
+#define SDIO_CLASS_UART		0x01	/* standard UART interface */
+#define SDIO_CLASS_BT_A		0x02	/* Type-A BlueTooth std interface */
+#define SDIO_CLASS_BT_B		0x03	/* Type-B BlueTooth std interface */
+#define SDIO_CLASS_GPS		0x04	/* GPS standard interface */
+#define SDIO_CLASS_CAMERA	0x05	/* Camera standard interface */
+#define SDIO_CLASS_PHS		0x06	/* PHS standard interface */
+#define SDIO_CLASS_WLAN		0x07	/* WLAN interface */
+#define SDIO_CLASS_ATA		0x08	/* Embedded SDIO-ATA std interface */
+
+
+#endif
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 4dc5fa8..e47e595 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -340,4 +340,15 @@
 #define PA_HVERSION_ANY_ID	0xffff
 #define PA_SVERSION_ANY_ID	0xffffffff
 
+/* SDIO */
+
+#define SDIO_ANY_ID (~0)
+
+struct sdio_device_id {
+	__u8	class;			/* Standard interface or SDIO_ANY_ID */
+	__u16	vendor;			/* Vendor or SDIO_ANY_ID */
+	__u16	device;			/* Device ID or SDIO_ANY_ID */
+	kernel_ulong_t driver_data;	/* Data private to the driver */
+};
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 55f307f..c8636bb 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1471,6 +1471,8 @@
 #define PCI_DEVICE_ID_RICOH_RL5C476	0x0476
 #define PCI_DEVICE_ID_RICOH_RL5C478	0x0478
 #define PCI_DEVICE_ID_RICOH_R5C822	0x0822
+#define PCI_DEVICE_ID_RICOH_R5C832	0x0832
+#define PCI_DEVICE_ID_RICOH_R5C843	0x0843
 
 #define PCI_VENDOR_ID_DLINK		0x1186
 #define PCI_DEVICE_ID_DLINK_DGE510T	0x4c00
diff --git a/include/linux/spi/mmc_spi.h b/include/linux/spi/mmc_spi.h
new file mode 100644
index 0000000..e9bbe3e
--- /dev/null
+++ b/include/linux/spi/mmc_spi.h
@@ -0,0 +1,33 @@
+#ifndef __LINUX_SPI_MMC_SPI_H
+#define __LINUX_SPI_MMC_SPI_H
+
+struct device;
+struct mmc_host;
+
+/* Put this in platform_data of a device being used to manage an MMC/SD
+ * card slot.  (Modeled after PXA mmc glue; see that for usage examples.)
+ *
+ * REVISIT This is not a spi-specific notion.  Any card slot should be
+ * able to handle it.  If the MMC core doesn't adopt this kind of notion,
+ * switch the "struct device *" parameters over to "struct spi_device *".
+ */
+struct mmc_spi_platform_data {
+	/* driver activation and (optional) card detect irq hookup */
+	int (*init)(struct device *,
+		irqreturn_t (*)(int, void *),
+		void *);
+	void (*exit)(struct device *, void *);
+
+	/* sense switch on sd cards */
+	int (*get_ro)(struct device *);
+
+	/* how long to debounce card detect, in msecs */
+	u16 detect_delay;
+
+	/* power management */
+	u16 powerup_msecs;		/* delay of up to 250 msec */
+	u32 ocr_mask;			/* available voltages */
+	void (*setpower)(struct device *, unsigned int maskval);
+};
+
+#endif /* __LINUX_SPI_MMC_SPI_H */
diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh
index 0dcc01c..366f8c7 100755
--- a/scripts/checksyscalls.sh
+++ b/scripts/checksyscalls.sh
@@ -119,5 +119,5 @@
 \#endif/p }' $1
 }
 
-(ignore_list && syscall_list ${srctree}/include/asm-i386/unistd.h) | \
+(ignore_list && syscall_list ${srctree}/include/asm-x86/unistd_32.h) | \
 $* -E -x c - > /dev/null
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 8a09021..1e5d4d6 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -484,6 +484,22 @@
 	return 1;
 }
 
+/* Looks like: sdio:cNvNdN. */
+static int do_sdio_entry(const char *filename,
+			struct sdio_device_id *id, char *alias)
+{
+	id->class = TO_NATIVE(id->class);
+	id->vendor = TO_NATIVE(id->vendor);
+	id->device = TO_NATIVE(id->device);
+
+	strcpy(alias, "sdio:");
+	ADD(alias, "c", id->class != (__u8)SDIO_ANY_ID, id->class);
+	ADD(alias, "v", id->vendor != (__u16)SDIO_ANY_ID, id->vendor);
+	ADD(alias, "d", id->device != (__u16)SDIO_ANY_ID, id->device);
+
+	return 1;
+}
+
 /* Ignore any prefix, eg. v850 prepends _ */
 static inline int sym_is(const char *symbol, const char *name)
 {
@@ -599,6 +615,10 @@
 		do_table(symval, sym->st_size,
 			 sizeof(struct parisc_device_id), "parisc",
 			 do_parisc_entry, mod);
+	else if (sym_is(symname, "__mod_sdio_device_table"))
+		do_table(symval, sym->st_size,
+			 sizeof(struct sdio_device_id), "sdio",
+			 do_sdio_entry, mod);
 }
 
 /* Now add out buffered information to the generated C source */
diff --git a/scripts/namespace.pl b/scripts/namespace.pl
index f343738..c6e88c6 100755
--- a/scripts/namespace.pl
+++ b/scripts/namespace.pl
@@ -105,7 +105,7 @@
 	if (/.*\.o$/ &&
 		! (
 		m:/built-in.o$:
-		|| m:arch/i386/kernel/vsyscall-syms.o$:
+		|| m:arch/x86/kernel/vsyscall-syms.o$:
 		|| m:arch/ia64/ia32/ia32.o$:
 		|| m:arch/ia64/kernel/gate-syms.o$:
 		|| m:arch/ia64/lib/__divdi3.o$:
@@ -328,9 +328,9 @@
 			}
 			# Special case for i386 entry code
 			if ($#{$def{$name}} == 1 && $name =~ /^__kernel_/ &&
-			    $def{$name}[0] eq "arch/i386/kernel/vsyscall-int80.o" &&
-			    $def{$name}[1] eq "arch/i386/kernel/vsyscall-sysenter.o") {
-				&drop_def("arch/i386/kernel/vsyscall-sysenter.o", $name);
+			    $def{$name}[0] eq "arch/x86/kernel/vsyscall-int80_32.o" &&
+			    $def{$name}[1] eq "arch/x86/kernel/vsyscall-sysenter_32.o") {
+				&drop_def("arch/x86/kernel/vsyscall-sysenter_32.o", $name);
 				next;
 			}
 			printf "$name is multiply defined in :-\n";