Merge branch 'omap-all' into devel

Conflicts:

	arch/arm/mach-omap2/gpmc.c
	arch/arm/mach-omap2/irq.c
diff --git a/.mailmap b/.mailmap
index 7260842..dfab12f 100644
--- a/.mailmap
+++ b/.mailmap
@@ -96,4 +96,6 @@
 Thomas Graf <tgraf@suug.ch>
 Tony Luck <tony.luck@intel.com>
 Tsuneo Yoshioka <Tsuneo.Yoshioka@f-secure.com>
+Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
+Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
 Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
diff --git a/Documentation/ABI/testing/sysfs-gpio b/Documentation/ABI/testing/sysfs-gpio
new file mode 100644
index 0000000..8aab809
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-gpio
@@ -0,0 +1,26 @@
+What:		/sys/class/gpio/
+Date:		July 2008
+KernelVersion:	2.6.27
+Contact:	David Brownell <dbrownell@users.sourceforge.net>
+Description:
+
+  As a Kconfig option, individual GPIO signals may be accessed from
+  userspace.  GPIOs are only made available to userspace by an explicit
+  "export" operation.  If a given GPIO is not claimed for use by
+  kernel code, it may be exported by userspace (and unexported later).
+  Kernel code may export it for complete or partial access.
+
+  GPIOs are identified as they are inside the kernel, using integers in
+  the range 0..INT_MAX.  See Documentation/gpio.txt for more information.
+
+    /sys/class/gpio
+	/export ... asks the kernel to export a GPIO to userspace
+	/unexport ... to return a GPIO to the kernel
+	/gpioN ... for each exported GPIO #N
+	    /value ... always readable, writes fail for input GPIOs
+	    /direction ... r/w as: in, out (default low); write: high, low
+	/gpiochipN ... for each gpiochip; #N is its first GPIO
+	    /base ... (r/o) same as N
+	    /label ... (r/o) descriptive, not necessarily unique
+	    /ngpio ... (r/o) number of GPIOs; numbered N to N + (ngpio - 1)
+
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt
index 1f5a924..47e568a 100644
--- a/Documentation/cpusets.txt
+++ b/Documentation/cpusets.txt
@@ -635,14 +635,16 @@
 
 There is an exception to the above.  If hotplug functionality is used
 to remove all the CPUs that are currently assigned to a cpuset,
-then the kernel will automatically update the cpus_allowed of all
-tasks attached to CPUs in that cpuset to allow all CPUs.  When memory
-hotplug functionality for removing Memory Nodes is available, a
-similar exception is expected to apply there as well.  In general,
-the kernel prefers to violate cpuset placement, over starving a task
-that has had all its allowed CPUs or Memory Nodes taken offline.  User
-code should reconfigure cpusets to only refer to online CPUs and Memory
-Nodes when using hotplug to add or remove such resources.
+then all the tasks in that cpuset will be moved to the nearest ancestor
+with non-empty cpus.  But the moving of some (or all) tasks might fail if
+cpuset is bound with another cgroup subsystem which has some restrictions
+on task attaching.  In this failing case, those tasks will stay
+in the original cpuset, and the kernel will automatically update
+their cpus_allowed to allow all online CPUs.  When memory hotplug
+functionality for removing Memory Nodes is available, a similar exception
+is expected to apply there as well.  In general, the kernel prefers to
+violate cpuset placement, over starving a task that has had all
+its allowed CPUs or Memory Nodes taken offline.
 
 There is a second exception to the above.  GFP_ATOMIC requests are
 kernel internal allocations that must be satisfied, immediately.
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index eb1a47b..83c88ca 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -322,3 +322,11 @@
       controlled by a kernel/module/sysfs/sysctl parameter.
 Who:  Krzysztof Piotr Oledzki <ole@ans.pl>
 
+---------------------------
+
+What: ide-scsi (BLK_DEV_IDESCSI)
+When: 2.6.29
+Why:  The 2.6 kernel supports direct writing to ide CD drives, which
+      eliminates the need for ide-scsi. The new method is more
+      efficient in every way.
+Who:  FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 680fb56..8362860 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -144,8 +144,8 @@
 	void (*kill_sb) (struct super_block *);
 locking rules:
 		may block	BKL
-get_sb		yes		yes
-kill_sb		yes		yes
+get_sb		yes		no
+kill_sb		yes		no
 
 ->get_sb() returns error or 0 with locked superblock attached to the vfsmount
 (exclusive on ->s_umount).
@@ -409,12 +409,12 @@
 unlocked_ioctl:		no	(see below)
 compat_ioctl:		no
 mmap:			no
-open:			maybe	(see below)
+open:			no
 flush:			no
 release:		no
 fsync:			no	(see below)
 aio_fsync:		no
-fasync:			yes	(see below)
+fasync:			no
 lock:			yes
 readv:			no
 writev:			no
@@ -431,13 +431,6 @@
 semaphore.  Note some filesystems (i.e. remote ones) provide no
 protection for i_size so you will need to use the BKL.
 
-->open() locking is in-transit: big lock partially moved into the methods.
-The only exception is ->open() in the instances of file_operations that never
-end up in ->i_fop/->proc_fops, i.e. ones that belong to character devices
-(chrdev_open() takes lock before replacing ->f_op and calling the secondary
-method. As soon as we fix the handling of module reference counters all
-instances of ->open() will be called without the BKL.
-
 Note: ext2_release() was *the* source of contention on fs-intensive
 loads and dropping BKL on ->release() helps to get rid of that (we still
 grab BKL for cases when we close a file that had been opened r/w, but that
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index 394eb2c..f566ad9 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -2413,6 +2413,8 @@
   - (bit 1) anonymous shared memory
   - (bit 2) file-backed private memory
   - (bit 3) file-backed shared memory
+  - (bit 4) ELF header pages in file-backed private memory areas (it is
+            effective only if the bit 2 is cleared)
 
   Note that MMIO pages such as frame buffer are never dumped and vDSO pages
   are always dumped regardless of the bitmask status.
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index 02dc748..71f0fe1 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -44,7 +44,7 @@
 	- LCD brightness control
 	- Volume control
 	- Fan control and monitoring: fan speed, fan enable/disable
-	- Experimental: WAN enable and disable
+	- WAN enable and disable
 
 A compatibility table by model and feature is maintained on the web
 site, http://ibm-acpi.sf.net/. I appreciate any success or failure
@@ -1375,18 +1375,13 @@
 would be the safest choice, though).
 
 
-EXPERIMENTAL: WAN
------------------
+WAN
+---
 
 procfs: /proc/acpi/ibm/wan
 sysfs device attribute: wwan_enable (deprecated)
 sysfs rfkill class: switch "tpacpi_wwan_sw"
 
-This feature is marked EXPERIMENTAL because the implementation
-directly accesses hardware registers and may not work as expected. USE
-WITH CAUTION! To use this feature, you need to supply the
-experimental=1 parameter when loading the module.
-
 This feature shows the presence and current state of a W-WAN (Sierra
 Wireless EV-DO) device.
 
diff --git a/Documentation/sound/alsa/soc/dapm.txt b/Documentation/sound/alsa/soc/dapm.txt
index b2ed698..46f9684 100644
--- a/Documentation/sound/alsa/soc/dapm.txt
+++ b/Documentation/sound/alsa/soc/dapm.txt
@@ -135,11 +135,7 @@
 
 static int spitz_mic_bias(struct snd_soc_dapm_widget* w, int event)
 {
-	if(SND_SOC_DAPM_EVENT_ON(event))
-		set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_MIC_BIAS);
-	else
-		reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_MIC_BIAS);
-
+	gpio_set_value(SPITZ_GPIO_MIC_BIAS, SND_SOC_DAPM_EVENT_ON(event));
 	return 0;
 }
 
@@ -269,11 +265,7 @@
 /* turn speaker amplifier on/off depending on use */
 static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event)
 {
-	if (SND_SOC_DAPM_EVENT_ON(event))
-		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON);
-	else
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON);
-
+	gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event));
 	return 0;
 }
 
diff --git a/Documentation/video4linux/CARDLIST.au0828 b/Documentation/video4linux/CARDLIST.au0828
index eedc399..aa05e5b 100644
--- a/Documentation/video4linux/CARDLIST.au0828
+++ b/Documentation/video4linux/CARDLIST.au0828
@@ -3,3 +3,4 @@
   2 -> Hauppauge HVR850                         (au0828)        [2040:7240]
   3 -> DViCO FusionHDTV USB                     (au0828)        [0fe9:d620]
   4 -> Hauppauge HVR950Q rev xxF8               (au0828)        [2040:7201,2040:7211,2040:7281]
+  5 -> Hauppauge Woodbury                       (au0828)        [2040:8200]
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index 78a863a..0f03900 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -88,14 +88,14 @@
 zc3xx		0471:0326	Philips SPC 300 NC
 sonixj		0471:0327	Philips SPC 600 NC
 sonixj		0471:0328	Philips SPC 700 NC
-zc3xx		0471:032d	Philips spc210nc
-zc3xx		0471:032e	Philips spc315nc
-sonixj		0471:0330	Philips SPC 710NC
+zc3xx		0471:032d	Philips SPC 210 NC
+zc3xx		0471:032e	Philips SPC 315 NC
+sonixj		0471:0330	Philips SPC 710 NC
 spca501		0497:c001	Smile International
 sunplus		04a5:3003	Benq DC 1300
 sunplus		04a5:3008	Benq DC 1500
-sunplus		04a5:300a	Benq DC3410
-spca500		04a5:300c	Benq DC1016
+sunplus		04a5:300a	Benq DC 3410
+spca500		04a5:300c	Benq DC 1016
 sunplus		04f1:1001	JVC GC A50
 spca561		04fc:0561	Flexcam 100
 sunplus		04fc:500c	Sunplus CA500C
@@ -175,19 +175,21 @@
 tv8532		0923:010f	ICM532 cams
 mars		093a:050f	Mars-Semi Pc-Camera
 pac207		093a:2460	PAC207 Qtec Webcam 100
-pac207		093a:2463	Philips spc200nc pac207
+pac207		093a:2463	Philips SPC 220 NC
 pac207		093a:2464	Labtec Webcam 1200
 pac207		093a:2468	PAC207
 pac207		093a:2470	Genius GF112
-pac207		093a:2471	PAC207 Genius VideoCam ge111
-pac207		093a:2472	PAC207 Genius VideoCam ge110
+pac207		093a:2471	Genius VideoCam ge111
+pac207		093a:2472	Genius VideoCam ge110
 pac7311		093a:2600	PAC7311 Typhoon
-pac7311		093a:2601	PAC7311 Phillips SPC610NC
+pac7311		093a:2601	Philips SPC 610 NC
 pac7311		093a:2603	PAC7312
-pac7311		093a:2608	PAC7311 Trust WB-3300p
-pac7311		093a:260e	PAC7311 Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350
-pac7311		093a:260f	PAC7311 SnakeCam
+pac7311		093a:2608	Trust WB-3300p
+pac7311		093a:260e	Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350
+pac7311		093a:260f	SnakeCam
 pac7311		093a:2621	PAC731x
+pac7311		093a:2624	PAC7302
+pac7311		093a:2626	Labtec 2200
 zc3xx		0ac8:0302	Z-star Vimicro zc0302
 vc032x		0ac8:0321	Vimicro generic vc0321
 vc032x		0ac8:0323	Vimicro Vc0323
@@ -220,6 +222,7 @@
 sonixj		0c45:60ec	SN9C105+MO4000
 sonixj		0c45:60fb	Surfer NoName
 sonixj		0c45:60fc	LG-LIC300
+sonixj		0c45:6128	Microdia/Sonix SNP325
 sonixj		0c45:612a	Avant Camera
 sonixj		0c45:612c	Typhoon Rasy Cam 1.3MPix
 sonixj		0c45:6130	Sonix Pccam
@@ -234,7 +237,7 @@
 spca561		10fd:7e50	FlyCam Usb 100
 zc3xx		10fd:8050	Typhoon Webshot II USB 300k
 spca501		1776:501c	Arowana 300K CMOS Camera
-t613		17a1:0128	T613/TAS5130A
+t613		17a1:0128	TASCORP JPEG Webcam, NGS Cyclops
 vc032x		17ef:4802	Lenovo Vc0323+MI1310_SOC
 pac207		2001:f115	D-Link DSB-C120
 spca500		2899:012c	Toptro Industrial
diff --git a/MAINTAINERS b/MAINTAINERS
index ced3c20..c77df0f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -222,8 +222,7 @@
 S:	Maintained
 
 ACPI
-P:	Andi Kleen
-M:	ak@linux.intel.com
+P:	Len Brown
 M:	lenb@kernel.org
 L:	linux-acpi@vger.kernel.org
 W:	http://www.lesswatts.org/projects/acpi/
@@ -467,6 +466,12 @@
 L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 S:	Maintained
 
+ARM/AFEB9260 MACHINE SUPPORT
+P:	Sergey Lapin
+M:	slapin@ossfans.org
+L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S:	Maintained
+
 ARM/AJECO 1ARM MACHINE SUPPORT
 P:	Lennert Buytenhek
 M:	kernel@wantstofly.org
@@ -492,7 +497,7 @@
 L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 S:	Maintained
 
-ARM/COMPULAB CM-X270/EM-X270 MACHINE SUPPORT
+ARM/COMPULAB CM-X270/EM-X270 and CM-X300 MACHINE SUPPORT
 P:	Mike Rapoport
 M:	mike@compulab.co.il
 L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
@@ -624,6 +629,12 @@
 W:	http://hackndev.com
 S:	Maintained
 
+ARM/PALMZ72 SUPPORT
+P:     Sergey Lapin
+M:     slapin@ossfans.org
+W:     http://hackndev.com
+S:     Maintained
+
 ARM/PLEB SUPPORT
 P:	Peter Chubb
 M:	pleb@gelato.unsw.edu.au
@@ -751,11 +762,13 @@
 M:	syrjala@sci.fi
 S:	Maintained
 
-ATL1 ETHERNET DRIVER
+ATLX ETHERNET DRIVERS
 P:	Jay Cliburn
 M:	jcliburn@gmail.com
 P:	Chris Snook
 M:	csnook@redhat.com
+P:	Jie Yang
+M:	jie.yang@atheros.com
 L:	atl1-devel@lists.sourceforge.net
 W:	http://sourceforge.net/projects/atl1
 W:	http://atl1.sourceforge.net
@@ -1594,7 +1607,7 @@
 EMBEDDED LINUX
 P:	Paul Gortmaker
 M:	paul.gortmaker@windriver.com
-P	David Woodhouse
+P:	David Woodhouse
 M:	dwmw2@infradead.org
 L:	linux-embedded@vger.kernel.org
 S:	Maintained
@@ -4364,7 +4377,7 @@
 USB VIDEO CLASS
 P:	Laurent Pinchart
 M:	laurent.pinchart@skynet.be
-L:	linx-uvc-devel@berlios.de
+L:	linux-uvc-devel@lists.berlios.de
 L:	video4linux-list@redhat.com
 W:	http://linux-uvc.berlios.de
 S:	Maintained
diff --git a/Makefile b/Makefile
index f448e00..4ff83ea 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 27
-EXTRAVERSION = -rc5
+EXTRAVERSION = -rc6
 NAME = Rotary Wombat
 
 # *DOCUMENTATION*
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 70dba16..efeed65 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -148,7 +148,6 @@
 
 config ZONE_DMA
 	bool
-	default y
 
 config GENERIC_ISA_DMA
 	bool
@@ -178,6 +177,11 @@
 config OPROFILE_ARM11_CORE
 	bool
 
+config OPROFILE_ARMV7
+	def_bool y
+	depends on CPU_V7 && !SMP
+	bool
+
 endif
 
 config VECTORS_BASE
@@ -245,6 +249,7 @@
 	select TIMER_ACORN
 	select ISA
 	select NO_IOPORT
+	select ARCH_SPARSEMEM_ENABLE
 	help
 	  Support for the Cirrus Logic PS7500FE system-on-a-chip.
 
@@ -306,6 +311,7 @@
 	select PLAT_IOP
 	select PCI
 	select ARCH_SUPPORTS_MSI
+	select VMSPLIT_1G
 	help
 	  Support for Intel's IOP13XX (XScale) family of processors.
 
@@ -350,6 +356,7 @@
 	select GENERIC_GPIO
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
+	select ZONE_DMA if PCI
 	help
 	  Support for Intel's IXP4XX (XScale) family of processors.
 
@@ -434,7 +441,7 @@
 	help
 	  Support for the following Marvell Orion 5x series SoCs:
 	  Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182),
-	  Orion-2 (5281).
+	  Orion-2 (5281), Orion-1-90 (6183).
 
 config ARCH_PNX4008
 	bool "Philips Nexperia PNX4008 Mobile"
@@ -464,6 +471,7 @@
 	select HAVE_PATA_PLATFORM
 	select ISA_DMA_API
 	select NO_IOPORT
+	select ARCH_SPARSEMEM_ENABLE
 	help
 	  On the Acorn Risc-PC, Linux can support the internal IDE disk and
 	  CD-ROM interface, serial and parallel port, and the floppy drive.
@@ -471,9 +479,7 @@
 config ARCH_SA1100
 	bool "SA1100-based"
 	select ISA
-	select ARCH_DISCONTIGMEM_ENABLE
 	select ARCH_SPARSEMEM_ENABLE
-	select ARCH_SELECT_MEMORY_MODEL
 	select ARCH_MTD_XIP
 	select GENERIC_GPIO
 	select GENERIC_TIME
@@ -497,6 +503,7 @@
 	bool "Shark"
 	select ISA
 	select ISA_DMA
+	select ZONE_DMA
 	select PCI
 	help
 	  Support for the StrongARM based Digital DNARD machine, also known
@@ -504,6 +511,8 @@
 
 config ARCH_LH7A40X
 	bool "Sharp LH7A40X"
+	select ARCH_DISCONTIGMEM_ENABLE if !LH7A40X_CONTIGMEM
+	select ARCH_SPARSEMEM_ENABLE if !LH7A40X_CONTIGMEM
 	help
 	  Say Y here for systems based on one of the Sharp LH7A40X
 	  System on a Chip processors.  These CPUs include an ARM922T
@@ -515,7 +524,9 @@
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
 	select HAVE_CLK
+	select ZONE_DMA
 	help
 	  Support for TI's DaVinci platform.
 
@@ -734,6 +745,29 @@
 
 	  If you don't know what to do here, say N.
 
+choice
+	prompt "Memory split"
+	default VMSPLIT_3G
+	help
+	  Select the desired split between kernel and user memory.
+
+	  If you are not absolutely sure what you are doing, leave this
+	  option alone!
+
+	config VMSPLIT_3G
+		bool "3G/1G user/kernel split"
+	config VMSPLIT_2G
+		bool "2G/2G user/kernel split"
+	config VMSPLIT_1G
+		bool "1G/3G user/kernel split"
+endchoice
+
+config PAGE_OFFSET
+	hex
+	default 0x40000000 if VMSPLIT_1G
+	default 0x80000000 if VMSPLIT_2G
+	default 0xC0000000
+
 config NR_CPUS
 	int "Maximum number of CPUs (2-32)"
 	range 2 32
@@ -815,20 +849,18 @@
 	default y
 	depends on FLATMEM
 
+# Discontigmem is deprecated
 config ARCH_DISCONTIGMEM_ENABLE
 	bool
-	default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
-	help
-	  Say Y to support efficient handling of discontiguous physical memory,
-	  for architectures which are either NUMA (Non-Uniform Memory Access)
-	  or have huge holes in the physical address space for other reasons.
-	  See <file:Documentation/vm/numa> for more.
 
 config ARCH_SPARSEMEM_ENABLE
 	bool
 
+config ARCH_SPARSEMEM_DEFAULT
+	def_bool ARCH_SPARSEMEM_ENABLE
+
 config ARCH_SELECT_MEMORY_MODEL
-	bool
+	def_bool ARCH_DISCONTIGMEM_ENABLE && ARCH_SPARSEMEM_ENABLE
 
 config NODES_SHIFT
 	int
@@ -845,7 +877,7 @@
 		   ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
 		   ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
 		   ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
-		   ARCH_AT91 || MACH_TRIZEPS4 || ARCH_DAVINCI || \
+		   ARCH_AT91 || ARCH_DAVINCI || \
 		   ARCH_KS8695 || MACH_RD88F5182
 	help
 	  If you say Y here, the LEDs on your machine will be used
@@ -1005,9 +1037,9 @@
 
 endmenu
 
-if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA)
+menu "CPU Power Management"
 
-menu "CPU Frequency scaling"
+if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA)
 
 source "drivers/cpufreq/Kconfig"
 
@@ -1047,10 +1079,12 @@
 	default y
 	select CPU_FREQ_DEFAULT_GOV_USERSPACE
 
-endmenu
-
 endif
 
+source "drivers/cpuidle/Kconfig"
+
+endmenu
+
 menu "Floating point emulation"
 
 comment "At least one emulation must be selected"
@@ -1202,6 +1236,8 @@
 
 source "drivers/hwmon/Kconfig"
 
+source "drivers/thermal/Kconfig"
+
 source "drivers/watchdog/Kconfig"
 
 source "drivers/ssb/Kconfig"
@@ -1222,6 +1258,10 @@
 
 source "drivers/mmc/Kconfig"
 
+source "drivers/memstick/Kconfig"
+
+source "drivers/accessibility/Kconfig"
+
 source "drivers/leds/Kconfig"
 
 source "drivers/rtc/Kconfig"
@@ -1230,6 +1270,8 @@
 
 source "drivers/dca/Kconfig"
 
+source "drivers/auxdisplay/Kconfig"
+
 source "drivers/regulator/Kconfig"
 
 source "drivers/uio/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 552ea6d..9400314 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -47,7 +47,7 @@
 # Note that GCC does not numerically define an architecture version
 # macro, but instead defines a whole series of macros which makes
 # testing for a specific architecture or later rather impossible.
-arch-$(CONFIG_CPU_32v7)		:=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7a,-march=armv5t -Wa$(comma)-march=armv7a)
+arch-$(CONFIG_CPU_32v7)		:=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a)
 arch-$(CONFIG_CPU_32v6)		:=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
 # Only override the compiler option if ARMv6. The ARMv6K extensions are
 # always available in ARMv7
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 94462a0..7a03f20 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -76,7 +76,7 @@
 endif
 
 EXTRA_CFLAGS  := -fpic -fno-builtin
-EXTRA_AFLAGS  :=
+EXTRA_AFLAGS  := -Wa,-march=all
 
 # Supply ZRELADDR, INITRD_PHYS and PARAMS_PHYS to the decompressor via
 # linker symbols.  We only define initrd_phys and params_phys if the
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index d42f89b..84a1e04 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -421,6 +421,7 @@
 		add	r1, r1, #1048576
 		str	r1, [r0]
 		mov	pc, lr
+ENDPROC(__setup_mmu)
 
 __armv4_mmu_cache_on:
 		mov	r12, lr
@@ -801,7 +802,7 @@
 		add	r2, r2, #4		@ add 4 (line length offset)
 		ldr	r4, =0x3ff
 		ands	r4, r4, r1, lsr #3	@ find maximum number on the way size
-		.word	0xe16f5f14		@ clz r5, r4 - find bit position of way size increment
+		clz	r5, r4			@ find bit position of way size increment
 		ldr	r7, =0x7fff
 		ands	r7, r7, r1, lsr #13	@ extract max number of the index size
 loop2:
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index 3e07346..2e32acc 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -12,7 +12,8 @@
 
 config SA1111
 	bool
-	select DMABOUNCE
+	select DMABOUNCE if !ARCH_PXA
+	select ZONE_DMA if !ARCH_PXA
 
 config DMABOUNCE
 	bool
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index aecc6c3..f030f07 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -154,9 +154,7 @@
 #endif
 
 	write_lock_irqsave(&device_info->lock, flags);
-
 	list_add(&buf->node, &device_info->safe_buffers);
-
 	write_unlock_irqrestore(&device_info->lock, flags);
 
 	return buf;
@@ -205,8 +203,22 @@
 
 /* ************************************************** */
 
-static inline dma_addr_t
-map_single(struct device *dev, void *ptr, size_t size,
+static struct safe_buffer *find_safe_buffer_dev(struct device *dev,
+		dma_addr_t dma_addr, const char *where)
+{
+	if (!dev || !dev->archdata.dmabounce)
+		return NULL;
+	if (dma_mapping_error(dev, dma_addr)) {
+		if (dev)
+			dev_err(dev, "Trying to %s invalid mapping\n", where);
+		else
+			pr_err("unknown device: Trying to %s invalid mapping\n", where);
+		return NULL;
+	}
+	return find_safe_buffer(dev->archdata.dmabounce, dma_addr);
+}
+
+static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size,
 		enum dma_data_direction dir)
 {
 	struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
@@ -270,33 +282,21 @@
 	return dma_addr;
 }
 
-static inline void
-unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-		enum dma_data_direction dir)
+static inline void unmap_single(struct device *dev, dma_addr_t dma_addr,
+		size_t size, enum dma_data_direction dir)
 {
-	struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
-	struct safe_buffer *buf = NULL;
-
-	/*
-	 * Trying to unmap an invalid mapping
-	 */
-	if (dma_mapping_error(dev, dma_addr)) {
-		dev_err(dev, "Trying to unmap invalid mapping\n");
-		return;
-	}
-
-	if (device_info)
-		buf = find_safe_buffer(device_info, dma_addr);
+	struct safe_buffer *buf = find_safe_buffer_dev(dev, dma_addr, "unmap");
 
 	if (buf) {
 		BUG_ON(buf->size != size);
+		BUG_ON(buf->direction != dir);
 
 		dev_dbg(dev,
 			"%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
 			__func__, buf->ptr, virt_to_dma(dev, buf->ptr),
 			buf->safe, buf->safe_dma_addr);
 
-		DO_STATS ( device_info->bounce_count++ );
+		DO_STATS(dev->archdata.dmabounce->bounce_count++);
 
 		if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) {
 			void *ptr = buf->ptr;
@@ -317,74 +317,7 @@
 			dmac_clean_range(ptr, ptr + size);
 			outer_clean_range(__pa(ptr), __pa(ptr) + size);
 		}
-		free_safe_buffer(device_info, buf);
-	}
-}
-
-static int sync_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-			enum dma_data_direction dir)
-{
-	struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
-	struct safe_buffer *buf = NULL;
-
-	if (device_info)
-		buf = find_safe_buffer(device_info, dma_addr);
-
-	if (buf) {
-		/*
-		 * Both of these checks from original code need to be
-		 * commented out b/c some drivers rely on the following:
-		 *
-		 * 1) Drivers may map a large chunk of memory into DMA space
-		 *    but only sync a small portion of it. Good example is
-		 *    allocating a large buffer, mapping it, and then
-		 *    breaking it up into small descriptors. No point
-		 *    in syncing the whole buffer if you only have to
-		 *    touch one descriptor.
-		 *
-		 * 2) Buffers that are mapped as DMA_BIDIRECTIONAL are
-		 *    usually only synced in one dir at a time.
-		 *
-		 * See drivers/net/eepro100.c for examples of both cases.
-		 *
-		 * -ds
-		 *
-		 * BUG_ON(buf->size != size);
-		 * BUG_ON(buf->direction != dir);
-		 */
-
-		dev_dbg(dev,
-			"%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
-			__func__, buf->ptr, virt_to_dma(dev, buf->ptr),
-			buf->safe, buf->safe_dma_addr);
-
-		DO_STATS ( device_info->bounce_count++ );
-
-		switch (dir) {
-		case DMA_FROM_DEVICE:
-			dev_dbg(dev,
-				"%s: copy back safe %p to unsafe %p size %d\n",
-				__func__, buf->safe, buf->ptr, size);
-			memcpy(buf->ptr, buf->safe, size);
-			break;
-		case DMA_TO_DEVICE:
-			dev_dbg(dev,
-				"%s: copy out unsafe %p to safe %p, size %d\n",
-				__func__,buf->ptr, buf->safe, size);
-			memcpy(buf->safe, buf->ptr, size);
-			break;
-		case DMA_BIDIRECTIONAL:
-			BUG();	/* is this allowed?  what does it mean? */
-		default:
-			BUG();
-		}
-		/*
-		 * No need to sync the safe buffer - it was allocated
-		 * via the coherent allocators.
-		 */
-		return 0;
-	} else {
-		return 1;
+		free_safe_buffer(dev->archdata.dmabounce, buf);
 	}
 }
 
@@ -396,21 +329,29 @@
  * substitute the safe buffer for the unsafe one.
  * (basically move the buffer from an unsafe area to a safe one)
  */
-dma_addr_t
-dma_map_single(struct device *dev, void *ptr, size_t size,
+dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
 		enum dma_data_direction dir)
 {
-	dma_addr_t dma_addr;
-
 	dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
 		__func__, ptr, size, dir);
 
-	BUG_ON(dir == DMA_NONE);
+	BUG_ON(!valid_dma_direction(dir));
 
-	dma_addr = map_single(dev, ptr, size, dir);
-
-	return dma_addr;
+	return map_single(dev, ptr, size, dir);
 }
+EXPORT_SYMBOL(dma_map_single);
+
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
+		unsigned long offset, size_t size, enum dma_data_direction dir)
+{
+	dev_dbg(dev, "%s(page=%p,off=%#lx,size=%zx,dir=%x)\n",
+		__func__, page, offset, size, dir);
+
+	BUG_ON(!valid_dma_direction(dir));
+
+	return map_single(dev, page_address(page) + offset, size, dir);
+}
+EXPORT_SYMBOL(dma_map_page);
 
 /*
  * see if a mapped address was really a "safe" buffer and if so, copy
@@ -419,126 +360,76 @@
  * should be)
  */
 
-void
-dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-			enum dma_data_direction dir)
+void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+		enum dma_data_direction dir)
 {
 	dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
 		__func__, (void *) dma_addr, size, dir);
 
-	BUG_ON(dir == DMA_NONE);
-
 	unmap_single(dev, dma_addr, size, dir);
 }
+EXPORT_SYMBOL(dma_unmap_single);
 
-int
-dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir)
+int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
+		unsigned long off, size_t sz, enum dma_data_direction dir)
 {
-	int i;
+	struct safe_buffer *buf;
 
-	dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
-		__func__, sg, nents, dir);
+	dev_dbg(dev, "%s(dma=%#x,off=%#lx,sz=%zx,dir=%x)\n",
+		__func__, addr, off, sz, dir);
 
-	BUG_ON(dir == DMA_NONE);
+	buf = find_safe_buffer_dev(dev, addr, __func__);
+	if (!buf)
+		return 1;
 
-	for (i = 0; i < nents; i++, sg++) {
-		struct page *page = sg_page(sg);
-		unsigned int offset = sg->offset;
-		unsigned int length = sg->length;
-		void *ptr = page_address(page) + offset;
+	BUG_ON(buf->direction != dir);
 
-		sg->dma_address =
-			map_single(dev, ptr, length, dir);
+	dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
+		__func__, buf->ptr, virt_to_dma(dev, buf->ptr),
+		buf->safe, buf->safe_dma_addr);
+
+	DO_STATS(dev->archdata.dmabounce->bounce_count++);
+
+	if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) {
+		dev_dbg(dev, "%s: copy back safe %p to unsafe %p size %d\n",
+			__func__, buf->safe + off, buf->ptr + off, sz);
+		memcpy(buf->ptr + off, buf->safe + off, sz);
 	}
-
-	return nents;
+	return 0;
 }
+EXPORT_SYMBOL(dmabounce_sync_for_cpu);
 
-void
-dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction dir)
+int dmabounce_sync_for_device(struct device *dev, dma_addr_t addr,
+		unsigned long off, size_t sz, enum dma_data_direction dir)
 {
-	int i;
+	struct safe_buffer *buf;
 
-	dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
-		__func__, sg, nents, dir);
+	dev_dbg(dev, "%s(dma=%#x,off=%#lx,sz=%zx,dir=%x)\n",
+		__func__, addr, off, sz, dir);
 
-	BUG_ON(dir == DMA_NONE);
+	buf = find_safe_buffer_dev(dev, addr, __func__);
+	if (!buf)
+		return 1;
 
-	for (i = 0; i < nents; i++, sg++) {
-		dma_addr_t dma_addr = sg->dma_address;
-		unsigned int length = sg->length;
+	BUG_ON(buf->direction != dir);
 
-		unmap_single(dev, dma_addr, length, dir);
+	dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
+		__func__, buf->ptr, virt_to_dma(dev, buf->ptr),
+		buf->safe, buf->safe_dma_addr);
+
+	DO_STATS(dev->archdata.dmabounce->bounce_count++);
+
+	if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) {
+		dev_dbg(dev, "%s: copy out unsafe %p to safe %p, size %d\n",
+			__func__,buf->ptr + off, buf->safe + off, sz);
+		memcpy(buf->safe + off, buf->ptr + off, sz);
 	}
+	return 0;
 }
+EXPORT_SYMBOL(dmabounce_sync_for_device);
 
-void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_addr,
-				   unsigned long offset, size_t size,
-				   enum dma_data_direction dir)
-{
-	dev_dbg(dev, "%s(dma=%#x,off=%#lx,size=%zx,dir=%x)\n",
-		__func__, dma_addr, offset, size, dir);
-
-	if (sync_single(dev, dma_addr, offset + size, dir))
-		dma_cache_maint(dma_to_virt(dev, dma_addr) + offset, size, dir);
-}
-EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
-
-void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_addr,
-				      unsigned long offset, size_t size,
-				      enum dma_data_direction dir)
-{
-	dev_dbg(dev, "%s(dma=%#x,off=%#lx,size=%zx,dir=%x)\n",
-		__func__, dma_addr, offset, size, dir);
-
-	if (sync_single(dev, dma_addr, offset + size, dir))
-		dma_cache_maint(dma_to_virt(dev, dma_addr) + offset, size, dir);
-}
-EXPORT_SYMBOL(dma_sync_single_range_for_device);
-
-void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
-			enum dma_data_direction dir)
-{
-	int i;
-
-	dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
-		__func__, sg, nents, dir);
-
-	BUG_ON(dir == DMA_NONE);
-
-	for (i = 0; i < nents; i++, sg++) {
-		dma_addr_t dma_addr = sg->dma_address;
-		unsigned int length = sg->length;
-
-		sync_single(dev, dma_addr, length, dir);
-	}
-}
-
-void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
-			enum dma_data_direction dir)
-{
-	int i;
-
-	dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
-		__func__, sg, nents, dir);
-
-	BUG_ON(dir == DMA_NONE);
-
-	for (i = 0; i < nents; i++, sg++) {
-		dma_addr_t dma_addr = sg->dma_address;
-		unsigned int length = sg->length;
-
-		sync_single(dev, dma_addr, length, dir);
-	}
-}
-
-static int
-dmabounce_init_pool(struct dmabounce_pool *pool, struct device *dev, const char *name,
-		    unsigned long size)
+static int dmabounce_init_pool(struct dmabounce_pool *pool, struct device *dev,
+		const char *name, unsigned long size)
 {
 	pool->size = size;
 	DO_STATS(pool->allocs = 0);
@@ -549,9 +440,8 @@
 	return pool->pool ? 0 : -ENOMEM;
 }
 
-int
-dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
-			unsigned long large_buffer_size)
+int dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
+		unsigned long large_buffer_size)
 {
 	struct dmabounce_device_info *device_info;
 	int ret;
@@ -607,9 +497,9 @@
 	kfree(device_info);
 	return ret;
 }
+EXPORT_SYMBOL(dmabounce_register_dev);
 
-void
-dmabounce_unregister_dev(struct device *dev)
+void dmabounce_unregister_dev(struct device *dev)
 {
 	struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
 
@@ -642,15 +532,6 @@
 
 	dev_info(dev, "dmabounce: device unregistered\n");
 }
-
-
-EXPORT_SYMBOL(dma_map_single);
-EXPORT_SYMBOL(dma_unmap_single);
-EXPORT_SYMBOL(dma_map_sg);
-EXPORT_SYMBOL(dma_unmap_sg);
-EXPORT_SYMBOL(dma_sync_sg_for_cpu);
-EXPORT_SYMBOL(dma_sync_sg_for_device);
-EXPORT_SYMBOL(dmabounce_register_dev);
 EXPORT_SYMBOL(dmabounce_unregister_dev);
 
 MODULE_AUTHOR("Christopher Hoover <ch@hpl.hp.com>, Deepak Saxena <dsaxena@plexity.net>");
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 0c89bd3..7fc9860 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -27,9 +27,9 @@
 #include <linux/list.h>
 #include <linux/smp.h>
 #include <linux/cpumask.h>
+#include <linux/io.h>
 
 #include <asm/irq.h>
-#include <asm/io.h>
 #include <asm/mach/irq.h>
 #include <asm/hardware/gic.h>
 
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
index 5fe9588..2793447 100644
--- a/arch/arm/common/it8152.c
+++ b/arch/arm/common/it8152.c
@@ -66,14 +66,6 @@
        }
 }
 
-static inline void it8152_irq(int irq)
-{
-	struct irq_desc *desc;
-
-	desc = irq_desc + irq;
-	desc_handle_irq(irq, desc);
-}
-
 static struct irq_chip it8152_irq_chip = {
 	.name		= "it8152",
 	.ack		= it8152_mask_irq,
@@ -128,21 +120,21 @@
 	       bits_pd &= ((1 << IT8152_PD_IRQ_COUNT) - 1);
 	       while (bits_pd) {
 		       i = __ffs(bits_pd);
-		       it8152_irq(IT8152_PD_IRQ(i));
+		       generic_handle_irq(IT8152_PD_IRQ(i));
 		       bits_pd &= ~(1 << i);
 	       }
 
 	       bits_lp &= ((1 << IT8152_LP_IRQ_COUNT) - 1);
 	       while (bits_lp) {
 		       i = __ffs(bits_lp);
-		       it8152_irq(IT8152_LP_IRQ(i));
+		       generic_handle_irq(IT8152_LP_IRQ(i));
 		       bits_lp &= ~(1 << i);
 	       }
 
 	       bits_ld &= ((1 << IT8152_LD_IRQ_COUNT) - 1);
 	       while (bits_ld) {
 		       i = __ffs(bits_ld);
-		       it8152_irq(IT8152_LD_IRQ(i));
+		       generic_handle_irq(IT8152_LD_IRQ(i));
 		       bits_ld &= ~(1 << i);
 	       }
        }
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index 283051e..7c6b4b9 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -24,9 +24,9 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 
@@ -169,7 +169,6 @@
 static void locomo_handler(unsigned int irq, struct irq_desc *desc)
 {
 	int req, i;
-	struct irq_desc *d;
 	void __iomem *mapbase = get_irq_chip_data(irq);
 
 	/* Acknowledge the parent IRQ */
@@ -181,10 +180,9 @@
 	if (req) {
 		/* generate the next interrupt(s) */
 		irq = LOCOMO_IRQ_START;
-		d = irq_desc + irq;
-		for (i = 0; i <= 3; i++, d++, irq++) {
+		for (i = 0; i <= 3; i++, irq++) {
 			if (req & (0x0100 << i)) {
-				desc_handle_irq(irq, d);
+				generic_handle_irq(irq);
 			}
 
 		}
@@ -222,12 +220,10 @@
 
 static void locomo_key_handler(unsigned int irq, struct irq_desc *desc)
 {
-	struct irq_desc *d;
 	void __iomem *mapbase = get_irq_chip_data(irq);
 
 	if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) {
-		d = irq_desc + LOCOMO_IRQ_KEY_START;
-		desc_handle_irq(LOCOMO_IRQ_KEY_START, d);
+		generic_handle_irq(LOCOMO_IRQ_KEY_START);
 	}
 }
 
@@ -268,7 +264,6 @@
 static void locomo_gpio_handler(unsigned int irq, struct irq_desc *desc)
 {
 	int req, i;
-	struct irq_desc *d;
 	void __iomem *mapbase = get_irq_chip_data(irq);
 
 	req = 	locomo_readl(mapbase + LOCOMO_GIR) &
@@ -277,10 +272,9 @@
 
 	if (req) {
 		irq = LOCOMO_IRQ_GPIO_START;
-		d = irq_desc + LOCOMO_IRQ_GPIO_START;
-		for (i = 0; i <= 15; i++, irq++, d++) {
+		for (i = 0; i <= 15; i++, irq++) {
 			if (req & (0x0001 << i)) {
-				desc_handle_irq(irq, d);
+				generic_handle_irq(irq);
 			}
 		}
 	}
@@ -361,12 +355,10 @@
 
 static void locomo_lt_handler(unsigned int irq, struct irq_desc *desc)
 {
-	struct irq_desc *d;
 	void __iomem *mapbase = get_irq_chip_data(irq);
 
 	if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) {
-		d = irq_desc + LOCOMO_IRQ_LT_START;
-		desc_handle_irq(LOCOMO_IRQ_LT_START, d);
+		generic_handle_irq(LOCOMO_IRQ_LT_START);
 	}
 }
 
@@ -407,17 +399,15 @@
 static void locomo_spi_handler(unsigned int irq, struct irq_desc *desc)
 {
 	int req, i;
-	struct irq_desc *d;
 	void __iomem *mapbase = get_irq_chip_data(irq);
 
 	req = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIR) & 0x000F;
 	if (req) {
 		irq = LOCOMO_IRQ_SPI_START;
-		d = irq_desc + irq;
 
-		for (i = 0; i <= 3; i++, irq++, d++) {
+		for (i = 0; i <= 3; i++, irq++) {
 			if (req & (0x0001 << i)) {
-				desc_handle_irq(irq, d);
+				generic_handle_irq(irq);
 			}
 		}
 	}
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index ec8a547..fb86f24 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -25,10 +25,10 @@
 #include <linux/spinlock.h>
 #include <linux/dma-mapping.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 #include <asm/sizes.h>
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index ae39553..697c649 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -15,7 +15,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/gpio.h>
 #include <asm/hardware/scoop.h>
 
diff --git a/arch/arm/common/sharpsl_param.c b/arch/arm/common/sharpsl_param.c
index aad4d94..d56c932 100644
--- a/arch/arm/common/sharpsl_param.c
+++ b/arch/arm/common/sharpsl_param.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/string.h>
 #include <asm/mach/sharpsl_param.h>
 
@@ -36,6 +37,7 @@
 #define PHAD_MAGIC	MAGIC_CHG('P','H','A','D')
 
 struct sharpsl_param_info sharpsl_param;
+EXPORT_SYMBOL(sharpsl_param);
 
 void sharpsl_save_param(void)
 {
diff --git a/arch/arm/common/time-acorn.c b/arch/arm/common/time-acorn.c
index df0983a..deeed56 100644
--- a/arch/arm/common/time-acorn.c
+++ b/arch/arm/common/time-acorn.c
@@ -17,9 +17,9 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/hardware/ioc.h>
 
 #include <asm/mach/time.h>
diff --git a/arch/arm/common/uengine.c b/arch/arm/common/uengine.c
index 7ecd3c0..b520e56 100644
--- a/arch/arm/common/uengine.c
+++ b/arch/arm/common/uengine.c
@@ -16,9 +16,9 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/string.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
 #include <asm/hardware/uengine.h>
-#include <asm/io.h>
 
 #if defined(CONFIG_ARCH_IXP2000)
 #define IXP_UENGINE_CSR_VIRT_BASE	IXP2000_UENGINE_CSR_VIRT_BASE
diff --git a/arch/arm/common/via82c505.c b/arch/arm/common/via82c505.c
index 79a8206..8421d39 100644
--- a/arch/arm/common/via82c505.c
+++ b/arch/arm/common/via82c505.c
@@ -4,8 +4,8 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/system.h>
 
 #include <asm/mach/pci.h>
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index c026fa2..f1e4b8f 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -20,8 +20,8 @@
  */
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/mach/irq.h>
 #include <asm/hardware/vic.h>
 
diff --git a/arch/arm/configs/afeb9260_defconfig b/arch/arm/configs/afeb9260_defconfig
new file mode 100644
index 0000000..ce90958
--- /dev/null
+++ b/arch/arm/configs/afeb9260_defconfig
@@ -0,0 +1,1259 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27-rc2
+# Tue Aug 12 22:30:16 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_CLK=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+CONFIG_ARCH_AT91=y
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM7X00A is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Atmel AT91 System-on-Chip
+#
+# CONFIG_ARCH_AT91RM9200 is not set
+CONFIG_ARCH_AT91SAM9260=y
+# CONFIG_ARCH_AT91SAM9261 is not set
+# CONFIG_ARCH_AT91SAM9263 is not set
+# CONFIG_ARCH_AT91SAM9RL is not set
+# CONFIG_ARCH_AT91SAM9G20 is not set
+# CONFIG_ARCH_AT91CAP9 is not set
+# CONFIG_ARCH_AT91X40 is not set
+CONFIG_AT91_PMC_UNIT=y
+
+#
+# AT91SAM9260 Variants
+#
+# CONFIG_ARCH_AT91SAM9260_SAM9XE is not set
+
+#
+# AT91SAM9260 / AT91SAM9XE Board Type
+#
+# CONFIG_MACH_AT91SAM9260EK is not set
+# CONFIG_MACH_CAM60 is not set
+# CONFIG_MACH_SAM9_L9260 is not set
+CONFIG_MACH_AFEB9260=y
+# CONFIG_MACH_USB_A9260 is not set
+# CONFIG_MACH_QIL_A9260 is not set
+
+#
+# AT91 Board Options
+#
+
+#
+# AT91 Feature Selections
+#
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+CONFIG_AT91_TIMER_HZ=100
+CONFIG_AT91_EARLY_DBGU=y
+# CONFIG_AT91_EARLY_USART0 is not set
+# CONFIG_AT91_EARLY_USART1 is not set
+# CONFIG_AT91_EARLY_USART2 is not set
+# CONFIG_AT91_EARLY_USART3 is not set
+# CONFIG_AT91_EARLY_USART4 is not set
+# CONFIG_AT91_EARLY_USART5 is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_ATMEL=y
+# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
+CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
+# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_ATMEL_TCLIB is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_ATMEL_SSC=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+CONFIG_AT24=y
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+CONFIG_SPI_DEBUG=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+CONFIG_USB_GADGET_AT91=y
+CONFIG_USB_AT91=y
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+CONFIG_USB_ZERO=m
+# CONFIG_USB_ETH is not set
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+CONFIG_RTC_DEBUG=y
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+CONFIG_RTC_DRV_FM3130=y
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_AT91SAM9 is not set
+# CONFIG_DMADEVICES is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=y
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/at91sam9rlek_defconfig b/arch/arm/configs/at91sam9rlek_defconfig
index 1c76642..811bebb 100644
--- a/arch/arm/configs/at91sam9rlek_defconfig
+++ b/arch/arm/configs/at91sam9rlek_defconfig
@@ -496,6 +496,7 @@
 # CONFIG_TOUCHSCREEN_PENMOUNT is not set
 # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
 # CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+CONFIG_TOUCHSCREEN_ATMEL_TSADCC=y
 # CONFIG_TOUCHSCREEN_UCB1400 is not set
 # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
 # CONFIG_INPUT_MISC is not set
diff --git a/arch/arm/configs/xm_x270_defconfig b/arch/arm/configs/cm_x300_defconfig
similarity index 68%
copy from arch/arm/configs/xm_x270_defconfig
copy to arch/arm/configs/cm_x300_defconfig
index aa40d91..46f1c9d 100644
--- a/arch/arm/configs/xm_x270_defconfig
+++ b/arch/arm/configs/cm_x300_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.25
-# Sun May 11 15:12:52 2008
+# Linux kernel version: 2.6.27-rc3
+# Tue Aug 19 11:26:54 2008
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -12,6 +12,7 @@
 # CONFIG_NO_IOPORT is not set
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
@@ -24,6 +25,7 @@
 CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_ZONE_DMA=y
 CONFIG_ARCH_MTD_XIP=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -33,7 +35,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION="-cm-x300"
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
@@ -44,7 +46,7 @@
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
+CONFIG_LOG_BUF_SHIFT=18
 # CONFIG_CGROUPS is not set
 CONFIG_GROUP_SCHED=y
 CONFIG_FAIR_GROUP_SCHED=y
@@ -54,15 +56,18 @@
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
-# CONFIG_NAMESPACES is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
-CONFIG_EMBEDDED=y
+# CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -70,7 +75,7 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-# CONFIG_COMPAT_BRK is not set
+CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_ANON_INODES=y
@@ -79,8 +84,8 @@
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-# CONFIG_VM_EVENT_COUNTERS is not set
-# CONFIG_SLUB_DEBUG is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -88,14 +93,22 @@
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_PROC_PAGE_MONITOR is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_CLK=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
@@ -106,6 +119,7 @@
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -131,7 +145,6 @@
 # CONFIG_ARCH_AT91 is not set
 # CONFIG_ARCH_CLPS7500 is not set
 # CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
 # CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
@@ -145,8 +158,11 @@
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
 # CONFIG_ARCH_KS8695 is not set
 # CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
 # CONFIG_ARCH_MXC is not set
 # CONFIG_ARCH_ORION5X is not set
 # CONFIG_ARCH_PNX4008 is not set
@@ -159,15 +175,18 @@
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
 # CONFIG_ARCH_MSM7X00A is not set
-CONFIG_DMABOUNCE=y
 
 #
 # Intel PXA2xx/PXA3xx Implementations
 #
 
 #
-# Select target boards
+# Supported PXA3xx Processor Variants
 #
+CONFIG_CPU_PXA300=y
+# CONFIG_CPU_PXA310 is not set
+# CONFIG_CPU_PXA320 is not set
+# CONFIG_CPU_PXA930 is not set
 # CONFIG_ARCH_GUMSTIX is not set
 # CONFIG_ARCH_LUBBOCK is not set
 # CONFIG_MACH_LOGICPD_PXA270 is not set
@@ -176,14 +195,19 @@
 # CONFIG_PXA_SHARPSL is not set
 # CONFIG_ARCH_PXA_ESERIES is not set
 # CONFIG_MACH_TRIZEPS4 is not set
-CONFIG_MACH_EM_X270=y
+# CONFIG_MACH_EM_X270 is not set
 # CONFIG_MACH_COLIBRI is not set
 # CONFIG_MACH_ZYLONITE is not set
 # CONFIG_MACH_LITTLETON is not set
-CONFIG_MACH_ARMCORE=y
+# CONFIG_MACH_TAVOREVB is not set
+# CONFIG_MACH_SAAR is not set
+# CONFIG_MACH_ARMCORE is not set
+CONFIG_MACH_CM_X300=y
 # CONFIG_MACH_MAGICIAN is not set
 # CONFIG_MACH_PCM027 is not set
-CONFIG_PXA27x=y
+# CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_PXA_EZX is not set
+CONFIG_PXA3xx=y
 # CONFIG_PXA_PWM is not set
 
 #
@@ -198,7 +222,7 @@
 # Processor Type
 #
 CONFIG_CPU_32=y
-CONFIG_CPU_XSCALE=y
+CONFIG_CPU_XSC3=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
 CONFIG_CPU_PABRT_NOIFAR=y
@@ -206,45 +230,24 @@
 CONFIG_CPU_TLB_V4WBI=y
 CONFIG_CPU_CP15=y
 CONFIG_CPU_CP15_MMU=y
+CONFIG_IO_36=y
 
 #
 # Processor Features
 #
-CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMB is not set
 # CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_OUTER_CACHE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_OUTER_CACHE=y
+CONFIG_CACHE_XSC3L2=y
 CONFIG_IWMMXT=y
-CONFIG_XSCALE_PMU=y
 
 #
 # Bus support
 #
-CONFIG_PCI=y
-CONFIG_PCI_SYSCALL=y
-CONFIG_PCI_HOST_ITE8152=y
+# CONFIG_PCI_SYSCALL is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
-# CONFIG_PCI_DEBUG is not set
-CONFIG_PCCARD=m
-# CONFIG_PCMCIA_DEBUG is not set
-CONFIG_PCMCIA=m
-CONFIG_PCMCIA_LOAD_CIS=y
-CONFIG_PCMCIA_IOCTL=y
-CONFIG_CARDBUS=y
-
-#
-# PC-card bridges
-#
-CONFIG_YENTA=m
-# CONFIG_YENTA_O2 is not set
-# CONFIG_YENTA_RICOH is not set
-CONFIG_YENTA_TI=y
-# CONFIG_YENTA_ENE_TUNE is not set
-# CONFIG_YENTA_TOSHIBA is not set
-# CONFIG_PD6729 is not set
-# CONFIG_I82092 is not set
-CONFIG_PCMCIA_PXA2XX=m
-CONFIG_PCCARD_NONSTATIC=m
+# CONFIG_PCCARD is not set
 
 #
 # Kernel Features
@@ -279,14 +282,28 @@
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=1f03 mem=32M"
+CONFIG_CMDLINE="root=/dev/mtdblock5 rootfstype=jffs2 console=ttyS2,38400"
 # CONFIG_XIP_KERNEL is not set
 # CONFIG_KEXEC is not set
 
 #
 # CPU Frequency scaling
 #
-# CONFIG_CPU_FREQ is not set
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
 
 #
 # Floating point emulation
@@ -314,37 +331,27 @@
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
-CONFIG_APM_EMULATION=m
+CONFIG_APM_EMULATION=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
+# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
+# CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_FIB_HASH=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
+CONFIG_IP_PNP_RARP=y
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
 # CONFIG_ARPD is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_INET_AH is not set
@@ -352,9 +359,9 @@
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -391,10 +398,10 @@
 CONFIG_BT_L2CAP=m
 CONFIG_BT_SCO=m
 CONFIG_BT_RFCOMM=m
-# CONFIG_BT_RFCOMM_TTY is not set
+CONFIG_BT_RFCOMM_TTY=y
 CONFIG_BT_BNEP=m
-# CONFIG_BT_BNEP_MC_FILTER is not set
-# CONFIG_BT_BNEP_PROTO_FILTER is not set
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
 CONFIG_BT_HIDP=m
 
 #
@@ -407,10 +414,6 @@
 # CONFIG_BT_HCIBCM203X is not set
 # CONFIG_BT_HCIBPA10X is not set
 # CONFIG_BT_HCIBFUSB is not set
-# CONFIG_BT_HCIDTL1 is not set
-# CONFIG_BT_HCIBT3C is not set
-# CONFIG_BT_HCIBLUECARD is not set
-# CONFIG_BT_HCIBTUART is not set
 # CONFIG_BT_HCIVHCI is not set
 # CONFIG_AF_RXRPC is not set
 
@@ -419,8 +422,13 @@
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -434,7 +442,9 @@
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
@@ -444,7 +454,7 @@
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
 # CONFIG_MTD_AFS_PARTS is not set
 # CONFIG_MTD_AR7_PARTS is not set
 
@@ -464,14 +474,8 @@
 #
 # RAM/ROM/Flash chip drivers
 #
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_GEOMETRY is not set
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
 CONFIG_MTD_MAP_BANK_WIDTH_1=y
 CONFIG_MTD_MAP_BANK_WIDTH_2=y
 CONFIG_MTD_MAP_BANK_WIDTH_4=y
@@ -482,35 +486,20 @@
 CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_CFI_I4 is not set
 # CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_OTP is not set
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_STAA=y
-CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_XIP is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0x400000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
-CONFIG_MTD_PXA2XX=y
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_IMPA7 is not set
 # CONFIG_MTD_SHARP_SL is not set
-# CONFIG_MTD_INTEL_VR_NOR is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
 #
-# CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -530,10 +519,9 @@
 CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 # CONFIG_MTD_NAND_SHARPSL is not set
-# CONFIG_MTD_NAND_CAFE is not set
-CONFIG_MTD_NAND_CM_X270=y
+CONFIG_MTD_NAND_PXA3xx=y
 # CONFIG_MTD_NAND_NANDSIM is not set
-CONFIG_MTD_NAND_PLATFORM=y
+# CONFIG_MTD_NAND_PLATFORM is not set
 # CONFIG_MTD_ALAUDA is not set
 # CONFIG_MTD_ONENAND is not set
 
@@ -543,15 +531,10 @@
 # CONFIG_MTD_UBI is not set
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
@@ -602,185 +585,45 @@
 # CONFIG_SCSI_SRP_ATTRS is not set
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_AIC94XX is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_ARCMSR is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_MVSAS is not set
-# CONFIG_SCSI_STEX is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_QLA_FC is not set
-# CONFIG_SCSI_QLA_ISCSI is not set
-# CONFIG_SCSI_LPFC is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_SRP is not set
-# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
-CONFIG_ATA=m
-# CONFIG_ATA_NONSTANDARD is not set
-# CONFIG_SATA_PMP is not set
-# CONFIG_SATA_AHCI is not set
-# CONFIG_SATA_SIL24 is not set
-CONFIG_ATA_SFF=y
-# CONFIG_SATA_SVW is not set
-# CONFIG_ATA_PIIX is not set
-# CONFIG_SATA_MV is not set
-# CONFIG_SATA_NV is not set
-# CONFIG_PDC_ADMA is not set
-# CONFIG_SATA_QSTOR is not set
-# CONFIG_SATA_PROMISE is not set
-# CONFIG_SATA_SX4 is not set
-# CONFIG_SATA_SIL is not set
-# CONFIG_SATA_SIS is not set
-# CONFIG_SATA_ULI is not set
-# CONFIG_SATA_VIA is not set
-# CONFIG_SATA_VITESSE is not set
-# CONFIG_SATA_INIC162X is not set
-# CONFIG_PATA_ALI is not set
-# CONFIG_PATA_AMD is not set
-# CONFIG_PATA_ARTOP is not set
-# CONFIG_PATA_ATIIXP is not set
-# CONFIG_PATA_CMD640_PCI is not set
-# CONFIG_PATA_CMD64X is not set
-# CONFIG_PATA_CS5520 is not set
-# CONFIG_PATA_CS5530 is not set
-# CONFIG_PATA_CYPRESS is not set
-# CONFIG_PATA_EFAR is not set
-# CONFIG_ATA_GENERIC is not set
-# CONFIG_PATA_HPT366 is not set
-# CONFIG_PATA_HPT37X is not set
-# CONFIG_PATA_HPT3X2N is not set
-# CONFIG_PATA_HPT3X3 is not set
-# CONFIG_PATA_IT821X is not set
-# CONFIG_PATA_IT8213 is not set
-# CONFIG_PATA_JMICRON is not set
-# CONFIG_PATA_TRIFLEX is not set
-# CONFIG_PATA_MARVELL is not set
-# CONFIG_PATA_MPIIX is not set
-# CONFIG_PATA_OLDPIIX is not set
-# CONFIG_PATA_NETCELL is not set
-# CONFIG_PATA_NINJA32 is not set
-# CONFIG_PATA_NS87410 is not set
-# CONFIG_PATA_NS87415 is not set
-# CONFIG_PATA_OPTI is not set
-# CONFIG_PATA_OPTIDMA is not set
-CONFIG_PATA_PCMCIA=m
-# CONFIG_PATA_PDC_OLD is not set
-# CONFIG_PATA_RADISYS is not set
-# CONFIG_PATA_RZ1000 is not set
-# CONFIG_PATA_SC1200 is not set
-# CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
-# CONFIG_PATA_SIL680 is not set
-# CONFIG_PATA_SIS is not set
-# CONFIG_PATA_VIA is not set
-# CONFIG_PATA_WINBOND is not set
-# CONFIG_PATA_PLATFORM is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
 # CONFIG_MD is not set
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_FIREWIRE is not set
-# CONFIG_IEEE1394 is not set
-# CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
-# CONFIG_ARCNET is not set
 # CONFIG_PHYLIB is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_AX88796 is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 CONFIG_DM9000=y
-CONFIG_DM9000_DEBUGLEVEL=1
+CONFIG_DM9000_DEBUGLEVEL=0
+CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
 # CONFIG_SMC911X is not set
-# CONFIG_NET_TULIP is not set
-# CONFIG_HP100 is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-# CONFIG_EEPRO100 is not set
-# CONFIG_E100 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-CONFIG_8139TOO=y
-# CONFIG_8139TOO_PIO is not set
-# CONFIG_8139TOO_TUNE_TWISTER is not set
-# CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_OLD_RX_RESET is not set
-# CONFIG_R6040 is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_SC92031 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
-# CONFIG_TR is not set
 
 #
 # Wireless LAN
 #
 # CONFIG_WLAN_PRE80211 is not set
 CONFIG_WLAN_80211=y
-# CONFIG_PCMCIA_RAYCS is not set
-# CONFIG_IPW2100 is not set
-# CONFIG_IPW2200 is not set
 CONFIG_LIBERTAS=m
 # CONFIG_LIBERTAS_USB is not set
-# CONFIG_LIBERTAS_CS is not set
 CONFIG_LIBERTAS_SDIO=m
 # CONFIG_LIBERTAS_DEBUG is not set
-# CONFIG_HERMES is not set
-# CONFIG_ATMEL is not set
-# CONFIG_AIRO_CS is not set
-# CONFIG_PCMCIA_WL3501 is not set
-# CONFIG_PRISM54 is not set
 # CONFIG_USB_ZD1201 is not set
 # CONFIG_USB_NET_RNDIS_WLAN is not set
-# CONFIG_IWLWIFI is not set
 # CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_HOSTAP is not set
 
@@ -792,23 +635,9 @@
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
-# CONFIG_NET_PCMCIA is not set
 # CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-# CONFIG_PPP_MPPE is not set
-# CONFIG_PPPOE is not set
-# CONFIG_PPPOL2TP is not set
+# CONFIG_PPP is not set
 # CONFIG_SLIP is not set
-CONFIG_SLHC=m
-# CONFIG_NET_FC is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
@@ -825,19 +654,18 @@
 # Userland interfaces
 #
 CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
-# CONFIG_INPUT_APMPOWER is not set
 
 #
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_ATKBD is not set
 # CONFIG_KEYBOARD_SUNKBD is not set
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
@@ -853,39 +681,32 @@
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_ELO is not set
 # CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
 # CONFIG_TOUCHSCREEN_MK712 is not set
 # CONFIG_TOUCHSCREEN_PENMOUNT is not set
 # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
 # CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-CONFIG_TOUCHSCREEN_UCB1400=m
-CONFIG_TOUCHSCREEN_WM97XX=m
-# CONFIG_TOUCHSCREEN_WM9705 is not set
-CONFIG_TOUCHSCREEN_WM9712=y
-# CONFIG_TOUCHSCREEN_WM9713 is not set
-# CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
 # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
 # CONFIG_INPUT_MISC is not set
 
 #
 # Hardware I/O ports
 #
-CONFIG_SERIO=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
 
 #
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
 CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_NOZOMI is not set
 
 #
 # Serial drivers
@@ -899,65 +720,50 @@
 CONFIG_SERIAL_PXA_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_NVRAM is not set
 # CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# PCMCIA character devices
-#
-# CONFIG_SYNCLINK_CS is not set
-# CONFIG_CARDMAN_4000 is not set
-# CONFIG_CARDMAN_4040 is not set
-# CONFIG_IPWIRELESS is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
-CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=m
+# CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
 
 #
 # I2C Hardware Bus support
 #
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI1563 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
 # CONFIG_I2C_GPIO is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_OCORES is not set
 CONFIG_I2C_PXA=y
 # CONFIG_I2C_PXA_SLAVE is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_I2C_SIMTEC is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
 # CONFIG_I2C_TINY_USB is not set
-# CONFIG_I2C_VIA is not set
-# CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
 # CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
 
 #
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
@@ -970,20 +776,23 @@
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
-CONFIG_HAVE_GPIO_LIB=y
-
-#
-# GPIO Support
-#
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
 
 #
 # I2C GPIO expanders:
 #
-# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_MAX732X is not set
+CONFIG_GPIO_PCA953X=y
 # CONFIG_GPIO_PCF857X is not set
 
 #
+# PCI GPIO expanders:
+#
+
+#
 # SPI GPIO expanders:
 #
 # CONFIG_W1 is not set
@@ -1000,10 +809,14 @@
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_ASIC3 is not set
 # CONFIG_HTC_EGPIO is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
 
 #
 # Multimedia devices
@@ -1014,6 +827,7 @@
 #
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
 
 #
 # Multimedia drivers
@@ -1023,7 +837,6 @@
 #
 # Graphics support
 #
-# CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
 CONFIG_FB=y
@@ -1038,7 +851,6 @@
 # CONFIG_FB_SYS_IMAGEBLIT is not set
 # CONFIG_FB_FOREIGN_ENDIAN is not set
 # CONFIG_FB_SYS_FOPS is not set
-CONFIG_FB_DEFERRED_IO=y
 # CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
@@ -1048,33 +860,12 @@
 #
 # Frame buffer hardware drivers
 #
-# CONFIG_FB_CIRRUS is not set
-# CONFIG_FB_PM2 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_ASILIANT is not set
-# CONFIG_FB_IMSTT is not set
 # CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_NVIDIA is not set
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON is not set
-# CONFIG_FB_ATY128 is not set
-# CONFIG_FB_ATY is not set
-# CONFIG_FB_S3 is not set
-# CONFIG_FB_SAVAGE is not set
-# CONFIG_FB_SIS is not set
-# CONFIG_FB_NEOMAGIC is not set
-# CONFIG_FB_KYRO is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_VT8623 is not set
-# CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_ARK is not set
-# CONFIG_FB_PM3 is not set
 CONFIG_FB_PXA=y
 # CONFIG_FB_PXA_SMARTPANEL is not set
-CONFIG_FB_PXA_PARAMETERS=y
-CONFIG_FB_MBX=m
+# CONFIG_FB_PXA_PARAMETERS is not set
+# CONFIG_FB_MBX is not set
+# CONFIG_FB_W100 is not set
 # CONFIG_FB_AM200EPD is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
@@ -1090,147 +881,48 @@
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
 # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
-# CONFIG_FONTS is not set
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+# CONFIG_FONT_8x16 is not set
+CONFIG_FONT_6x11=y
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
 CONFIG_LOGO=y
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
 CONFIG_SOUND=m
-
-#
-# Advanced Linux Sound Architecture
-#
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
 # CONFIG_SND_SEQUENCER is not set
-CONFIG_SND_OSSEMUL=y
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
 # CONFIG_SND_DYNAMIC_MINORS is not set
 CONFIG_SND_SUPPORT_OLD_API=y
 CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
-
-#
-# Generic devices
-#
-CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_DRIVERS=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_MTPAV is not set
 # CONFIG_SND_SERIAL_U16550 is not set
 # CONFIG_SND_MPU401 is not set
-
-#
-# PCI devices
-#
-# CONFIG_SND_AD1889 is not set
-# CONFIG_SND_ALS300 is not set
-# CONFIG_SND_ALI5451 is not set
-# CONFIG_SND_ATIIXP is not set
-# CONFIG_SND_ATIIXP_MODEM is not set
-# CONFIG_SND_AU8810 is not set
-# CONFIG_SND_AU8820 is not set
-# CONFIG_SND_AU8830 is not set
-# CONFIG_SND_AW2 is not set
-# CONFIG_SND_AZT3328 is not set
-# CONFIG_SND_BT87X is not set
-# CONFIG_SND_CA0106 is not set
-# CONFIG_SND_CMIPCI is not set
-# CONFIG_SND_OXYGEN is not set
-# CONFIG_SND_CS4281 is not set
-# CONFIG_SND_CS46XX is not set
-# CONFIG_SND_DARLA20 is not set
-# CONFIG_SND_GINA20 is not set
-# CONFIG_SND_LAYLA20 is not set
-# CONFIG_SND_DARLA24 is not set
-# CONFIG_SND_GINA24 is not set
-# CONFIG_SND_LAYLA24 is not set
-# CONFIG_SND_MONA is not set
-# CONFIG_SND_MIA is not set
-# CONFIG_SND_ECHO3G is not set
-# CONFIG_SND_INDIGO is not set
-# CONFIG_SND_INDIGOIO is not set
-# CONFIG_SND_INDIGODJ is not set
-# CONFIG_SND_EMU10K1 is not set
-# CONFIG_SND_EMU10K1X is not set
-# CONFIG_SND_ENS1370 is not set
-# CONFIG_SND_ENS1371 is not set
-# CONFIG_SND_ES1938 is not set
-# CONFIG_SND_ES1968 is not set
-# CONFIG_SND_FM801 is not set
-# CONFIG_SND_HDA_INTEL is not set
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_HDSPM is not set
-# CONFIG_SND_HIFIER is not set
-# CONFIG_SND_ICE1712 is not set
-# CONFIG_SND_ICE1724 is not set
-# CONFIG_SND_INTEL8X0 is not set
-# CONFIG_SND_INTEL8X0M is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_MAESTRO3 is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_PCXHR is not set
-# CONFIG_SND_RIPTIDE is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_SONICVIBES is not set
-# CONFIG_SND_TRIDENT is not set
-# CONFIG_SND_VIA82XX is not set
-# CONFIG_SND_VIA82XX_MODEM is not set
-# CONFIG_SND_VIRTUOSO is not set
-# CONFIG_SND_VX222 is not set
-# CONFIG_SND_YMFPCI is not set
-# CONFIG_SND_AC97_POWER_SAVE is not set
-
-#
-# ALSA ARM devices
-#
-CONFIG_SND_PXA2XX_PCM=m
-CONFIG_SND_PXA2XX_AC97=m
-
-#
-# USB devices
-#
+CONFIG_SND_ARM=y
+# CONFIG_SND_PXA2XX_AC97 is not set
+CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
 # CONFIG_SND_USB_CAIAQ is not set
-
-#
-# PCMCIA devices
-#
-# CONFIG_SND_VXPOCKET is not set
-# CONFIG_SND_PDAUDIOCF is not set
-
-#
-# System on Chip audio support
-#
-# CONFIG_SND_SOC is not set
-
-#
-# ALSA SoC audio for Freescale SOCs
-#
-
-#
-# SoC Audio for the Texas Instruments OMAP
-#
-
-#
-# Open Sound System
-#
+CONFIG_SND_SOC=m
+CONFIG_SND_PXA2XX_SOC=m
 # CONFIG_SOUND_PRIME is not set
-CONFIG_AC97_BUS=m
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 CONFIG_HID_DEBUG=y
@@ -1246,7 +938,7 @@
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 # CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
@@ -1259,27 +951,28 @@
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
-# CONFIG_USB_OTG_WHITELIST is not set
-# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
 
 #
 # USB Host Controller Drivers
 #
-# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_C67X00_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
 # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
-# CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
 
 #
 # USB Device Class drivers
 #
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -1301,6 +994,7 @@
 # CONFIG_USB_STORAGE_ALAUDA is not set
 # CONFIG_USB_STORAGE_ONETOUCH is not set
 # CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_SIERRA is not set
 # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
 # CONFIG_USB_LIBUSUAL is not set
 
@@ -1309,7 +1003,6 @@
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-CONFIG_USB_MON=y
 
 #
 # USB port drivers
@@ -1322,7 +1015,6 @@
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
@@ -1338,6 +1030,7 @@
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_GADGET is not set
 CONFIG_MMC=m
 # CONFIG_MMC_DEBUG is not set
@@ -1349,21 +1042,22 @@
 CONFIG_MMC_BLOCK=m
 CONFIG_MMC_BLOCK_BOUNCE=y
 # CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
 
 #
 # MMC/SD Host Controller Drivers
 #
 CONFIG_MMC_PXA=m
 # CONFIG_MMC_SDHCI is not set
-# CONFIG_MMC_TIFM_SD is not set
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 
 #
 # LED drivers
 #
-# CONFIG_LEDS_GPIO is not set
-CONFIG_LEDS_CM_X270=y
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+# CONFIG_LEDS_PCA955X is not set
 
 #
 # LED Triggers
@@ -1401,6 +1095,7 @@
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
 # CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
 
 #
 # SPI RTC drivers
@@ -1416,12 +1111,21 @@
 # CONFIG_RTC_DRV_STK17TA8 is not set
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
-CONFIG_RTC_DRV_V3020=y
+# CONFIG_RTC_DRV_V3020 is not set
 
 #
 # on-CPU RTC drivers
 #
 CONFIG_RTC_DRV_SA1100=y
+# CONFIG_DMADEVICES is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
 # CONFIG_UIO is not set
 
 #
@@ -1431,15 +1135,13 @@
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT3_FS_XATTR is not set
 # CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
-CONFIG_FS_MBCACHE=y
+# CONFIG_JBD_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
@@ -1460,7 +1162,7 @@
 # DOS/FAT/NT Filesystems
 #
 CONFIG_FAT_FS=m
-# CONFIG_MSDOS_FS is not set
+CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
 CONFIG_FAT_DEFAULT_CODEPAGE=437
 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
@@ -1501,6 +1203,7 @@
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1509,21 +1212,23 @@
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFSD is not set
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
-# CONFIG_RPCSEC_GSS_KRB5 is not set
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_SMB_FS is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
-# CONFIG_CIFS_WEAK_PW_HASH is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
 # CONFIG_CIFS_XATTR is not set
 # CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_CIFS_EXPERIMENTAL is not set
@@ -1591,7 +1296,7 @@
 # CONFIG_NLS_ISO8859_15 is not set
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
-CONFIG_NLS_UTF8=m
+# CONFIG_NLS_UTF8 is not set
 # CONFIG_DLM is not set
 
 #
@@ -1600,10 +1305,10 @@
 # CONFIG_PRINTK_TIME is not set
 CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_FRAME_WARN=0
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
@@ -1612,6 +1317,8 @@
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1622,10 +1329,11 @@
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 CONFIG_FRAME_POINTER=y
@@ -1633,9 +1341,19 @@
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
 # CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
 CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_ERRORS is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUG_LL=y
 # CONFIG_DEBUG_ICEDCC is not set
@@ -1651,7 +1369,9 @@
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_MANAGER is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_CRYPTD is not set
@@ -1668,10 +1388,10 @@
 #
 # Block modes
 #
-# CONFIG_CRYPTO_CBC is not set
+CONFIG_CRYPTO_CBC=y
 # CONFIG_CRYPTO_CTR is not set
 # CONFIG_CRYPTO_CTS is not set
-# CONFIG_CRYPTO_ECB is not set
+CONFIG_CRYPTO_ECB=m
 # CONFIG_CRYPTO_LRW is not set
 # CONFIG_CRYPTO_PCBC is not set
 # CONFIG_CRYPTO_XTS is not set
@@ -1687,8 +1407,12 @@
 #
 # CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
@@ -1698,14 +1422,14 @@
 #
 # Ciphers
 #
-# CONFIG_CRYPTO_AES is not set
+CONFIG_CRYPTO_AES=m
 # CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_CAST5 is not set
 # CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_DES is not set
+CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_SALSA20 is not set
@@ -1727,8 +1451,9 @@
 CONFIG_BITREVERSE=y
 # CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
-CONFIG_CRC_CCITT=m
+# CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=y
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
diff --git a/arch/arm/configs/jornada720_defconfig b/arch/arm/configs/jornada720_defconfig
index 0c55628..81fadaf 100644
--- a/arch/arm/configs/jornada720_defconfig
+++ b/arch/arm/configs/jornada720_defconfig
@@ -1,84 +1,174 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 23:10:35 2005
+# Linux kernel version: 2.6.27-rc6
+# Tue Sep 16 18:56:58 2008
 #
 CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_MMU=y
-CONFIG_UID16=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_ZONE_DMA=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # General setup
 #
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_CLK=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 # CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
 
 #
 # System Type
 #
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
 # CONFIG_ARCH_CLPS7500 is not set
 # CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
 # CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_RPC is not set
 CONFIG_ARCH_SA1100=y
 # CONFIG_ARCH_S3C2410 is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_MSM7X00A is not set
+CONFIG_DMABOUNCE=y
 
 #
 # SA11x0 Implementations
@@ -91,12 +181,21 @@
 # CONFIG_SA1100_H3800 is not set
 # CONFIG_SA1100_BADGE4 is not set
 CONFIG_SA1100_JORNADA720=y
+CONFIG_SA1100_JORNADA720_SSP=y
 # CONFIG_SA1100_HACKKIT is not set
 # CONFIG_SA1100_LART is not set
 # CONFIG_SA1100_PLEB is not set
 # CONFIG_SA1100_SHANNON is not set
 # CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_SSP is not set
+CONFIG_SA1100_SSP=y
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
 
 #
 # Processor Type
@@ -105,44 +204,71 @@
 CONFIG_CPU_SA1100=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4=y
+CONFIG_CPU_PABRT_NOIFAR=y
 CONFIG_CPU_CACHE_V4WB=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WB=y
-CONFIG_CPU_MINICACHE=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
 
 #
 # Processor Features
 #
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
 CONFIG_SA1111=y
-CONFIG_DMABOUNCE=y
 CONFIG_FORCE_MAX_ZONEORDER=9
 
 #
 # Bus support
 #
 CONFIG_ISA=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCCARD=y
 # CONFIG_PCMCIA_DEBUG is not set
 CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
 
 #
 # PC-card bridges
 #
-CONFIG_I82365=y
+# CONFIG_I82365 is not set
 # CONFIG_TCIC is not set
 CONFIG_PCMCIA_SA1100=y
 # CONFIG_PCMCIA_SA1111 is not set
-CONFIG_PCCARD_NONSTATIC=y
 
 #
 # Kernel Features
 #
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 # CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_NODES_SHIFT=2
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM_MANUAL=y
+# CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_DISCONTIGMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_NEED_MULTIPLE_NODES=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
 # CONFIG_LEDS is not set
 CONFIG_ALIGNMENT_TRAP=y
 
@@ -151,8 +277,9 @@
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="keepinitrd mem=32M"
+CONFIG_CMDLINE=""
 # CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
 
 #
 # CPU Frequency scaling
@@ -174,7 +301,7 @@
 # Userspace binary formats
 #
 CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_AOUT=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_ARTHUR is not set
 
@@ -182,188 +309,12 @@
 # Power management options
 #
 CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
-# CONFIG_APM is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-CONFIG_MTD_DEBUG=y
-CONFIG_MTD_DEBUG_VERBOSE=1
-# CONFIG_MTD_CONCAT is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_GEOMETRY=y
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_XIP is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-CONFIG_MTD_SA1100=y
-# CONFIG_MTD_EDB7312 is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=m
-CONFIG_BLK_DEV_IDE=m
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=m
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECS is not set
-CONFIG_BLK_DEV_IDECD=m
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=m
-# CONFIG_IDE_ARM is not set
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
-#
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
 #
@@ -371,12 +322,17 @@
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
 # CONFIG_IP_PNP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
@@ -386,31 +342,42 @@
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
-# CONFIG_IP_TCPDIAG is not set
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 # CONFIG_IP_VS is not set
 # CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_XTABLES is not set
 
 #
 # IP: Netfilter Configuration
 #
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_CONNTRACK_MARK is not set
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
+# CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_VLAN_8021Q is not set
@@ -420,30 +387,22 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 CONFIG_IRDA=m
 
 #
 # IrDA protocols
 #
 CONFIG_IRLAN=m
-# CONFIG_IRNET is not set
 CONFIG_IRCOMM=m
 # CONFIG_IRDA_ULTRA is not set
 
@@ -468,89 +427,105 @@
 #
 
 #
-# Old SIR device drivers
-#
-# CONFIG_IRPORT_SIR is not set
-
-#
-# Old Serial dongle support
-#
-
-#
 # FIR device drivers
 #
-# CONFIG_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
 CONFIG_SA1100_FIR=m
 # CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+# CONFIG_PNP is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECS=y
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_PLATFORM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
 CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
+CONFIG_DUMMY=y
 # CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
 # CONFIG_ARCNET is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 # CONFIG_NET_ETHERNET is not set
 CONFIG_MII=m
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 
 #
-# Wireless LAN (non-hamradio)
+# Wireless LAN
 #
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-CONFIG_ARLAN=m
-CONFIG_WAVELAN=m
-CONFIG_PCMCIA_WAVELAN=m
-# CONFIG_PCMCIA_NETWAVE is not set
-
-#
-# Wireless 802.11 Frequency Hopping cards support
-#
-# CONFIG_PCMCIA_RAYCS is not set
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-CONFIG_HERMES=m
-# CONFIG_ATMEL is not set
-
-#
-# Wireless 802.11b Pcmcia/Cardbus cards support
-#
-CONFIG_PCMCIA_HERMES=m
-CONFIG_AIRO_CS=m
-# CONFIG_PCMCIA_WL3501 is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# PCMCIA network device support
-#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
 CONFIG_NET_PCMCIA=y
 CONFIG_PCMCIA_3C589=m
 CONFIG_PCMCIA_3C574=m
@@ -560,32 +535,20 @@
 CONFIG_PCMCIA_SMC91C92=m
 CONFIG_PCMCIA_XIRC2PS=m
 CONFIG_PCMCIA_AXNET=m
-
-#
-# Wan interfaces
-#
 # CONFIG_WAN is not set
-CONFIG_PPP=m
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-# CONFIG_PPPOE is not set
+# CONFIG_PPP is not set
 # CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
-
-#
-# ISDN subsystem
-#
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 # CONFIG_ISDN is not set
 
 #
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -595,7 +558,6 @@
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
@@ -603,20 +565,31 @@
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_ATKBD is not set
 # CONFIG_KEYBOARD_SUNKBD is not set
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_INPORT is not set
-# CONFIG_MOUSE_LOGIBM is not set
-# CONFIG_MOUSE_PC110PAD is not set
-# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_HP7XX=y
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_TOUCHSCREEN_HP7XX=y
+# CONFIG_TOUCHSCREEN_HTCPEN is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
 # CONFIG_INPUT_MISC is not set
 
 #
@@ -625,17 +598,18 @@
 CONFIG_SERIO=y
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_SA1111 is not set
-CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -652,69 +626,120 @@
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
+CONFIG_LEGACY_PTY_COUNT=32
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=m
 # CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 
 #
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-
-#
 # PCMCIA character devices
 #
 # CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_IPWIRELESS is not set
 # CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
 
 #
-# Misc devices
+# I2C GPIO expanders:
 #
 
 #
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP_SA11X0 is not set
+
+#
 # Multimedia devices
 #
-# CONFIG_VIDEO_DEV is not set
 
 #
-# Digital Video Broadcasting Devices
+# Multimedia core support
 #
-# CONFIG_DVB is not set
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
 
 #
 # Graphics support
 #
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 CONFIG_FB=y
-# CONFIG_FB_CFB_FILLRECT is not set
-# CONFIG_FB_CFB_COPYAREA is not set
-# CONFIG_FB_CFB_IMAGEBLIT is not set
-# CONFIG_FB_SOFT_CURSOR is not set
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
 # CONFIG_FB_SA1100 is not set
+CONFIG_FB_S1D13XXX=y
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
 
 #
 # Console display driver support
@@ -722,94 +747,110 @@
 # CONFIG_VGA_CONSOLE is not set
 # CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE is not set
-
-#
-# Logo configuration
-#
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
 # CONFIG_LOGO is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=m
-
-#
-# Advanced Linux Sound Architecture
-#
-# CONFIG_SND is not set
-
-#
-# Open Sound System
-#
-# CONFIG_SOUND_PRIME is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-# CONFIG_USB is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_SA1100=y
+# CONFIG_DMADEVICES is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_UIO is not set
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA is not set
+# CONFIG_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
 #
-CONFIG_ISO9660_FS=m
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
+# CONFIG_ISO9660_FS is not set
 # CONFIG_UDF_FS is not set
 
 #
 # DOS/FAT/NT Filesystems
 #
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
 
 #
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-CONFIG_DEVFS_DEBUG=y
-# CONFIG_DEVPTS_FS_XATTR is not set
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -821,75 +862,122 @@
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=2
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
-# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_SUNRPC=m
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
 
 #
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
-CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
-CONFIG_DEBUG_SLAB=y
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
 CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
 # CONFIG_DEBUG_USER is not set
 CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUG_LL=y
 # CONFIG_DEBUG_ICEDCC is not set
 
@@ -898,21 +986,100 @@
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
 
 #
-# Cryptographic options
+# Crypto core or helper
 #
-# CONFIG_CRYPTO is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
 
 #
-# Hardware crypto devices
+# Authenticated Encryption with Associated Data
 #
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig
index 4017d83..b2456ca 100644
--- a/arch/arm/configs/orion5x_defconfig
+++ b/arch/arm/configs/orion5x_defconfig
@@ -176,14 +176,17 @@
 CONFIG_MACH_DNS323=y
 CONFIG_MACH_TS209=y
 CONFIG_MACH_LINKSTATION_PRO=y
+CONFIG_MACH_LINKSTATION_MINI=y
 CONFIG_MACH_TS409=y
 CONFIG_MACH_WRT350N_V2=y
 CONFIG_MACH_TS78XX=y
 CONFIG_MACH_MV2120=y
+CONFIG_MACH_EDMINI_V2=y
 CONFIG_MACH_MSS2=y
 CONFIG_MACH_WNR854T=y
 CONFIG_MACH_RD88F5181L_GE=y
 CONFIG_MACH_RD88F5181L_FXO=y
+CONFIG_MACH_RD88F6183AP_GE=y
 
 #
 # Boot options
diff --git a/arch/arm/configs/palmz72_defconfig b/arch/arm/configs/palmz72_defconfig
new file mode 100644
index 0000000..3245f8f
--- /dev/null
+++ b/arch/arm/configs/palmz72_defconfig
@@ -0,0 +1,951 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27-rc4
+# Sun Aug 24 02:29:27 2008
+#
+CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_ZONE_DMA=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_CLK=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM7X00A is not set
+
+#
+# Intel PXA2xx/PXA3xx Implementations
+#
+# CONFIG_ARCH_GUMSTIX is not set
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_ARCH_PXA_IDP is not set
+# CONFIG_PXA_SHARPSL is not set
+# CONFIG_ARCH_PXA_ESERIES is not set
+# CONFIG_MACH_TRIZEPS4 is not set
+# CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_COLIBRI is not set
+# CONFIG_MACH_ZYLONITE is not set
+# CONFIG_MACH_LITTLETON is not set
+# CONFIG_MACH_TAVOREVB is not set
+# CONFIG_MACH_SAAR is not set
+# CONFIG_MACH_ARMCORE is not set
+# CONFIG_MACH_MAGICIAN is not set
+# CONFIG_MACH_PCM027 is not set
+CONFIG_ARCH_PXA_PALM=y
+# CONFIG_MACH_PALMTX is not set
+CONFIG_MACH_PALMZ72=y
+# CONFIG_PXA_EZX is not set
+CONFIG_PXA27x=y
+CONFIG_PXA_PWM=y
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_IWMMXT=y
+CONFIG_XSCALE_PMU=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=32M console=tty root=/dev/mmcblk0"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_APM_EMULATION=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_NETDEVICES is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_PXA27x=y
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_PXA is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PXA=y
+# CONFIG_I2C_PXA_SLAVE is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_PXA2XX is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+CONFIG_PDA_POWER=y
+# CONFIG_APM_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+# CONFIG_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_PXA=y
+# CONFIG_FB_PXA_SMARTPANEL is not set
+# CONFIG_FB_PXA_PARAMETERS is not set
+# CONFIG_FB_MBX is not set
+# CONFIG_FB_W100 is not set
+# CONFIG_FB_AM200EPD is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_PWM=y
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+# CONFIG_LOGO is not set
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_DEBUG=y
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+CONFIG_MMC_PXA=y
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_SA1100=y
+# CONFIG_DMADEVICES is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=866
+CONFIG_FAT_DEFAULT_IOCHARSET="utf8"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+CONFIG_NLS_CODEPAGE_866=y
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_DEBUG_USER=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=y
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/xm_x270_defconfig b/arch/arm/configs/viper_defconfig
similarity index 65%
copy from arch/arm/configs/xm_x270_defconfig
copy to arch/arm/configs/viper_defconfig
index aa40d91..d01fecb 100644
--- a/arch/arm/configs/xm_x270_defconfig
+++ b/arch/arm/configs/viper_defconfig
@@ -1,9 +1,10 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.25
-# Sun May 11 15:12:52 2008
+# Linux kernel version: 2.6.27-rc4
+# Thu Aug 21 17:12:07 2008
 #
 CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
@@ -12,6 +13,7 @@
 # CONFIG_NO_IOPORT is not set
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
@@ -24,6 +26,7 @@
 CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_ZONE_DMA=y
 CONFIG_ARCH_MTD_XIP=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -34,43 +37,36 @@
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_SWAP=y
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=13
 # CONFIG_CGROUPS is not set
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
+# CONFIG_GROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-# CONFIG_COMPAT_BRK is not set
+# CONFIG_ELF_CORE is not set
+CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_ANON_INODES=y
@@ -78,24 +74,31 @@
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-# CONFIG_VM_EVENT_COUNTERS is not set
-# CONFIG_SLUB_DEBUG is not set
-# CONFIG_SLAB is not set
-CONFIG_SLUB=y
+# CONFIG_SHMEM is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_PROC_PAGE_MONITOR is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_CLK=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
+CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
@@ -106,19 +109,20 @@
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_AS is not set
 CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
+# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_DEFAULT_AS is not set
-# CONFIG_DEFAULT_DEADLINE is not set
-CONFIG_DEFAULT_CFQ=y
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_DEFAULT_IOSCHED="deadline"
 CONFIG_CLASSIC_RCU=y
 
 #
@@ -131,7 +135,6 @@
 # CONFIG_ARCH_AT91 is not set
 # CONFIG_ARCH_CLPS7500 is not set
 # CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
 # CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
@@ -145,8 +148,11 @@
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
 # CONFIG_ARCH_KS8695 is not set
 # CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
 # CONFIG_ARCH_MXC is not set
 # CONFIG_ARCH_ORION5X is not set
 # CONFIG_ARCH_PNX4008 is not set
@@ -159,32 +165,33 @@
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
 # CONFIG_ARCH_MSM7X00A is not set
-CONFIG_DMABOUNCE=y
 
 #
 # Intel PXA2xx/PXA3xx Implementations
 #
-
-#
-# Select target boards
-#
 # CONFIG_ARCH_GUMSTIX is not set
 # CONFIG_ARCH_LUBBOCK is not set
 # CONFIG_MACH_LOGICPD_PXA270 is not set
 # CONFIG_MACH_MAINSTONE is not set
 # CONFIG_ARCH_PXA_IDP is not set
 # CONFIG_PXA_SHARPSL is not set
+CONFIG_ARCH_VIPER=y
 # CONFIG_ARCH_PXA_ESERIES is not set
 # CONFIG_MACH_TRIZEPS4 is not set
-CONFIG_MACH_EM_X270=y
+# CONFIG_MACH_EM_X270 is not set
 # CONFIG_MACH_COLIBRI is not set
 # CONFIG_MACH_ZYLONITE is not set
 # CONFIG_MACH_LITTLETON is not set
-CONFIG_MACH_ARMCORE=y
+# CONFIG_MACH_TAVOREVB is not set
+# CONFIG_MACH_SAAR is not set
+# CONFIG_MACH_ARMCORE is not set
 # CONFIG_MACH_MAGICIAN is not set
 # CONFIG_MACH_PCM027 is not set
-CONFIG_PXA27x=y
-# CONFIG_PXA_PWM is not set
+# CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_PXA_EZX is not set
+CONFIG_PXA25x=y
+CONFIG_PXA_PWM=m
+CONFIG_PXA_HAVE_ISA_IRQS=y
 
 #
 # Boot options
@@ -219,38 +226,28 @@
 #
 # Bus support
 #
-CONFIG_PCI=y
-CONFIG_PCI_SYSCALL=y
-CONFIG_PCI_HOST_ITE8152=y
+CONFIG_ISA=y
+# CONFIG_PCI_SYSCALL is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
-# CONFIG_PCI_DEBUG is not set
 CONFIG_PCCARD=m
 # CONFIG_PCMCIA_DEBUG is not set
 CONFIG_PCMCIA=m
 CONFIG_PCMCIA_LOAD_CIS=y
 CONFIG_PCMCIA_IOCTL=y
-CONFIG_CARDBUS=y
 
 #
 # PC-card bridges
 #
-CONFIG_YENTA=m
-# CONFIG_YENTA_O2 is not set
-# CONFIG_YENTA_RICOH is not set
-CONFIG_YENTA_TI=y
-# CONFIG_YENTA_ENE_TUNE is not set
-# CONFIG_YENTA_TOSHIBA is not set
-# CONFIG_PD6729 is not set
-# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
 CONFIG_PCMCIA_PXA2XX=m
-CONFIG_PCCARD_NONSTATIC=m
+CONFIG_PCMCIA_PROBE=y
 
 #
 # Kernel Features
 #
 CONFIG_TICK_ONESHOT=y
-CONFIG_NO_HZ=y
+# CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 # CONFIG_PREEMPT is not set
@@ -279,14 +276,29 @@
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=1f03 mem=32M"
+CONFIG_CMDLINE="root=31:02 rootfstype=jffs2 ro console=ttyS0,115200"
 # CONFIG_XIP_KERNEL is not set
 # CONFIG_KEXEC is not set
 
 #
 # CPU Frequency scaling
 #
-# CONFIG_CPU_FREQ is not set
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPU_FREQ_PXA=y
 
 #
 # Floating point emulation
@@ -295,9 +307,8 @@
 #
 # At least one emulation must be selected
 #
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
+# CONFIG_FPE_NWFPE is not set
+CONFIG_FPE_FASTFPE=y
 
 #
 # Userspace binary formats
@@ -314,19 +325,15 @@
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
-CONFIG_APM_EMULATION=m
+# CONFIG_APM_EMULATION is not set
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
+# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -335,18 +342,17 @@
 # CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
+# CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_FIB_HASH=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_BOOTP is not set
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
 # CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
+CONFIG_SYN_COOKIES=y
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
@@ -356,7 +362,8 @@
 CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_XFRM_MODE_BEET=y
 # CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -389,21 +396,24 @@
 # CONFIG_IRDA is not set
 CONFIG_BT=m
 CONFIG_BT_L2CAP=m
-CONFIG_BT_SCO=m
+# CONFIG_BT_SCO is not set
 CONFIG_BT_RFCOMM=m
-# CONFIG_BT_RFCOMM_TTY is not set
+CONFIG_BT_RFCOMM_TTY=y
 CONFIG_BT_BNEP=m
 # CONFIG_BT_BNEP_MC_FILTER is not set
 # CONFIG_BT_BNEP_PROTO_FILTER is not set
-CONFIG_BT_HIDP=m
+# CONFIG_BT_HIDP is not set
 
 #
 # Bluetooth device drivers
 #
 CONFIG_BT_HCIUSB=m
-CONFIG_BT_HCIUSB_SCO=y
-# CONFIG_BT_HCIBTSDIO is not set
-# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIUSB_SCO is not set
+# CONFIG_BT_HCIBTUSB is not set
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+# CONFIG_BT_HCIUART_LL is not set
 # CONFIG_BT_HCIBCM203X is not set
 # CONFIG_BT_HCIBPA10X is not set
 # CONFIG_BT_HCIBFUSB is not set
@@ -418,9 +428,13 @@
 # Wireless
 #
 # CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+# CONFIG_IEEE80211_CRYPT_CCMP is not set
+# CONFIG_IEEE80211_CRYPT_TKIP is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -435,6 +449,8 @@
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=m
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
@@ -443,15 +459,18 @@
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=0
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
 # CONFIG_MTD_AFS_PARTS is not set
 # CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
 #
-CONFIG_MTD_CHAR=y
+CONFIG_MTD_CHAR=m
 CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
@@ -471,23 +490,23 @@
 CONFIG_MTD_CFI_NOSWAP=y
 # CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
 # CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_GEOMETRY is not set
+CONFIG_MTD_CFI_GEOMETRY=y
 CONFIG_MTD_MAP_BANK_WIDTH_1=y
 CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
 # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
 # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
 # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
 CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I2 is not set
 # CONFIG_MTD_CFI_I4 is not set
 # CONFIG_MTD_CFI_I8 is not set
 # CONFIG_MTD_OTP is not set
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_STAA=y
+# CONFIG_MTD_CFI_STAA is not set
 CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
+CONFIG_MTD_RAM=y
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
 # CONFIG_MTD_XIP is not set
@@ -495,22 +514,21 @@
 #
 # Mapping drivers for chip access
 #
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0x400000
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0
 CONFIG_MTD_PHYSMAP_BANKWIDTH=2
 CONFIG_MTD_PXA2XX=y
 # CONFIG_MTD_ARM_INTEGRATOR is not set
 # CONFIG_MTD_IMPA7 is not set
 # CONFIG_MTD_SHARP_SL is not set
-# CONFIG_MTD_INTEL_VR_NOR is not set
 # CONFIG_MTD_PLATRAM is not set
+CONFIG_MTD_SPARSE_RAM=y
 
 #
 # Self-contained MTD device drivers
 #
-# CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -522,19 +540,7 @@
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-CONFIG_MTD_NAND=y
-# CONFIG_MTD_NAND_VERIFY_WRITE is not set
-# CONFIG_MTD_NAND_ECC_SMC is not set
-# CONFIG_MTD_NAND_MUSEUM_IDS is not set
-# CONFIG_MTD_NAND_H1900 is not set
-CONFIG_MTD_NAND_IDS=y
-# CONFIG_MTD_NAND_DISKONCHIP is not set
-# CONFIG_MTD_NAND_SHARPSL is not set
-# CONFIG_MTD_NAND_CAFE is not set
-CONFIG_MTD_NAND_CM_X270=y
-# CONFIG_MTD_NAND_NANDSIM is not set
-CONFIG_MTD_NAND_PLATFORM=y
-# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_NAND is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
@@ -542,24 +548,19 @@
 #
 # CONFIG_MTD_UBI is not set
 # CONFIG_PARPORT is not set
+# CONFIG_PNP is not set
 CONFIG_BLK_DEV=y
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP=m
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-# CONFIG_MISC_DEVICES is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -567,16 +568,16 @@
 # SCSI device support
 #
 # CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=y
+CONFIG_SCSI=m
 CONFIG_SCSI_DMA=y
 # CONFIG_SCSI_TGT is not set
 # CONFIG_SCSI_NETLINK is not set
-CONFIG_SCSI_PROC_FS=y
+# CONFIG_SCSI_PROC_FS is not set
 
 #
 # SCSI support type (disk, tape, CD-ROM)
 #
-CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SD=m
 # CONFIG_CHR_DEV_ST is not set
 # CONFIG_CHR_DEV_OSST is not set
 # CONFIG_BLK_DEV_SR is not set
@@ -602,111 +603,34 @@
 # CONFIG_SCSI_SRP_ATTRS is not set
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AHA152X is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_AIC94XX is not set
-# CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_ARCMSR is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_DTC3280 is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_MVSAS is not set
-# CONFIG_SCSI_STEX is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_QLA_FC is not set
-# CONFIG_SCSI_QLA_ISCSI is not set
-# CONFIG_SCSI_LPFC is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_SCSI_DH is not set
 CONFIG_ATA=m
 # CONFIG_ATA_NONSTANDARD is not set
 # CONFIG_SATA_PMP is not set
-# CONFIG_SATA_AHCI is not set
-# CONFIG_SATA_SIL24 is not set
 CONFIG_ATA_SFF=y
-# CONFIG_SATA_SVW is not set
-# CONFIG_ATA_PIIX is not set
 # CONFIG_SATA_MV is not set
-# CONFIG_SATA_NV is not set
-# CONFIG_PDC_ADMA is not set
-# CONFIG_SATA_QSTOR is not set
-# CONFIG_SATA_PROMISE is not set
-# CONFIG_SATA_SX4 is not set
-# CONFIG_SATA_SIL is not set
-# CONFIG_SATA_SIS is not set
-# CONFIG_SATA_ULI is not set
-# CONFIG_SATA_VIA is not set
-# CONFIG_SATA_VITESSE is not set
-# CONFIG_SATA_INIC162X is not set
-# CONFIG_PATA_ALI is not set
-# CONFIG_PATA_AMD is not set
-# CONFIG_PATA_ARTOP is not set
-# CONFIG_PATA_ATIIXP is not set
-# CONFIG_PATA_CMD640_PCI is not set
-# CONFIG_PATA_CMD64X is not set
-# CONFIG_PATA_CS5520 is not set
-# CONFIG_PATA_CS5530 is not set
-# CONFIG_PATA_CYPRESS is not set
-# CONFIG_PATA_EFAR is not set
-# CONFIG_ATA_GENERIC is not set
-# CONFIG_PATA_HPT366 is not set
-# CONFIG_PATA_HPT37X is not set
-# CONFIG_PATA_HPT3X2N is not set
-# CONFIG_PATA_HPT3X3 is not set
-# CONFIG_PATA_IT821X is not set
-# CONFIG_PATA_IT8213 is not set
-# CONFIG_PATA_JMICRON is not set
-# CONFIG_PATA_TRIFLEX is not set
-# CONFIG_PATA_MARVELL is not set
-# CONFIG_PATA_MPIIX is not set
-# CONFIG_PATA_OLDPIIX is not set
-# CONFIG_PATA_NETCELL is not set
-# CONFIG_PATA_NINJA32 is not set
-# CONFIG_PATA_NS87410 is not set
-# CONFIG_PATA_NS87415 is not set
-# CONFIG_PATA_OPTI is not set
-# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_LEGACY is not set
 CONFIG_PATA_PCMCIA=m
-# CONFIG_PATA_PDC_OLD is not set
-# CONFIG_PATA_RADISYS is not set
-# CONFIG_PATA_RZ1000 is not set
-# CONFIG_PATA_SC1200 is not set
-# CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
-# CONFIG_PATA_SIL680 is not set
-# CONFIG_PATA_SIS is not set
-# CONFIG_PATA_VIA is not set
-# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_QDI is not set
+# CONFIG_PATA_WINBOND_VLB is not set
 # CONFIG_PATA_PLATFORM is not set
 # CONFIG_MD is not set
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_FIREWIRE is not set
-# CONFIG_IEEE1394 is not set
-# CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -718,44 +642,22 @@
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_AX88796 is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_SMC91X is not set
-CONFIG_DM9000=y
-CONFIG_DM9000_DEBUGLEVEL=1
+# CONFIG_NET_VENDOR_SMC is not set
+CONFIG_SMC91X=y
+# CONFIG_DM9000 is not set
 # CONFIG_SMC911X is not set
-# CONFIG_NET_TULIP is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
 # CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-# CONFIG_EEPRO100 is not set
-# CONFIG_E100 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-CONFIG_8139TOO=y
-# CONFIG_8139TOO_PIO is not set
-# CONFIG_8139TOO_TUNE_TWISTER is not set
-# CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_OLD_RX_RESET is not set
-# CONFIG_R6040 is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_SC92031 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
@@ -764,41 +666,40 @@
 # Wireless LAN
 #
 # CONFIG_WLAN_PRE80211 is not set
-CONFIG_WLAN_80211=y
-# CONFIG_PCMCIA_RAYCS is not set
-# CONFIG_IPW2100 is not set
-# CONFIG_IPW2200 is not set
-CONFIG_LIBERTAS=m
-# CONFIG_LIBERTAS_USB is not set
-# CONFIG_LIBERTAS_CS is not set
-CONFIG_LIBERTAS_SDIO=m
-# CONFIG_LIBERTAS_DEBUG is not set
-# CONFIG_HERMES is not set
-# CONFIG_ATMEL is not set
-# CONFIG_AIRO_CS is not set
-# CONFIG_PCMCIA_WL3501 is not set
-# CONFIG_PRISM54 is not set
-# CONFIG_USB_ZD1201 is not set
-# CONFIG_USB_NET_RNDIS_WLAN is not set
-# CONFIG_IWLWIFI is not set
+# CONFIG_WLAN_80211 is not set
 # CONFIG_IWLWIFI_LEDS is not set
-# CONFIG_HOSTAP is not set
 
 #
 # USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
+CONFIG_USB_PEGASUS=m
 # CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
-# CONFIG_NET_PCMCIA is not set
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_GL620A is not set
+CONFIG_USB_NET_NET1080=m
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_MCS7830 is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+# CONFIG_PCMCIA_PCNET is not set
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_PCMCIA_AXNET is not set
 # CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
 CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
 CONFIG_PPP_ASYNC=m
 # CONFIG_PPP_SYNC_TTY is not set
 CONFIG_PPP_DEFLATE=m
@@ -808,7 +709,6 @@
 # CONFIG_PPPOL2TP is not set
 # CONFIG_SLIP is not set
 CONFIG_SLHC=m
-# CONFIG_NET_FC is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
@@ -824,55 +724,50 @@
 #
 # Userland interfaces
 #
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
-CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_EVBUG is not set
-# CONFIG_INPUT_APMPOWER is not set
 
 #
 # Input Device Drivers
 #
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_STOWAWAY is not set
-CONFIG_KEYBOARD_PXA27x=m
-# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
 CONFIG_INPUT_TOUCHSCREEN=y
-# CONFIG_TOUCHSCREEN_FUJITSU is not set
+CONFIG_TOUCHSCREEN_FUJITSU=m
 # CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_TOUCHSCREEN_ELO is not set
-# CONFIG_TOUCHSCREEN_MTOUCH is not set
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_INEXIO=m
 # CONFIG_TOUCHSCREEN_MK712 is not set
-# CONFIG_TOUCHSCREEN_PENMOUNT is not set
-# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
-# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-CONFIG_TOUCHSCREEN_UCB1400=m
-CONFIG_TOUCHSCREEN_WM97XX=m
-# CONFIG_TOUCHSCREEN_WM9705 is not set
-CONFIG_TOUCHSCREEN_WM9712=y
-# CONFIG_TOUCHSCREEN_WM9713 is not set
-# CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE is not set
+CONFIG_TOUCHSCREEN_HTCPEN=m
+CONFIG_TOUCHSCREEN_PENMOUNT=m
+CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
+CONFIG_TOUCHSCREEN_TOUCHWIN=m
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_WM97XX is not set
 # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
-# CONFIG_INPUT_MISC is not set
+CONFIG_TOUCHSCREEN_TOUCHIT213=m
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+CONFIG_INPUT_UINPUT=m
 
 #
 # Hardware I/O ports
 #
 CONFIG_SERIO=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
 
@@ -880,17 +775,21 @@
 # Character devices
 #
 CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
+# CONFIG_CONSOLE_TRANSLATIONS is not set
+# CONFIG_VT_CONSOLE is not set
 CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
 CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_NOZOMI is not set
 
 #
 # Serial drivers
 #
-# CONFIG_SERIAL_8250 is not set
+CONFIG_SERIAL_8250=m
+# CONFIG_SERIAL_8250_CS is not set
+CONFIG_SERIAL_8250_NR_UARTS=5
+CONFIG_SERIAL_8250_RUNTIME_UARTS=5
+# CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
 # Non-8250 serial port support
@@ -899,15 +798,13 @@
 CONFIG_SERIAL_PXA_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_HW_RANDOM is not set
+CONFIG_HW_RANDOM=m
 # CONFIG_NVRAM is not set
+# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
 
 #
 # PCMCIA character devices
@@ -921,46 +818,53 @@
 CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
 
 #
 # I2C Hardware Bus support
 #
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI1563 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_GPIO is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_OCORES is not set
 CONFIG_I2C_PXA=y
 # CONFIG_I2C_PXA_SLAVE is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_I2C_SIMTEC is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
 # CONFIG_I2C_TINY_USB is not set
-# CONFIG_I2C_VIA is not set
-# CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_ELEKTOR is not set
+# CONFIG_I2C_PCA_ISA is not set
 # CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
 
 #
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_SENSORS_MAX6875 is not set
@@ -970,26 +874,98 @@
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
-CONFIG_HAVE_GPIO_LIB=y
-
-#
-# GPIO Support
-#
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
 
 #
+# PCI GPIO expanders:
+#
+
+#
 # SPI GPIO expanders:
 #
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
-# CONFIG_WATCHDOG is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_SA1100_WATCHDOG is not set
+
+#
+# ISA-based Watchdog Cards
+#
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_WDT is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
 
 #
 # Sonics Silicon Backplane
@@ -1000,10 +976,14 @@
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_ASIC3 is not set
 # CONFIG_HTC_EGPIO is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
 
 #
 # Multimedia devices
@@ -1014,6 +994,7 @@
 #
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
 
 #
 # Multimedia drivers
@@ -1023,22 +1004,20 @@
 #
 # Graphics support
 #
-# CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
 CONFIG_FB=y
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB_DDC is not set
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_CFB_FILLRECT=m
+CONFIG_FB_CFB_COPYAREA=m
+CONFIG_FB_CFB_IMAGEBLIT=m
 # CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
 # CONFIG_FB_SYS_FILLRECT is not set
 # CONFIG_FB_SYS_COPYAREA is not set
 # CONFIG_FB_SYS_IMAGEBLIT is not set
 # CONFIG_FB_FOREIGN_ENDIAN is not set
 # CONFIG_FB_SYS_FOPS is not set
-CONFIG_FB_DEFERRED_IO=y
 # CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
@@ -1048,36 +1027,21 @@
 #
 # Frame buffer hardware drivers
 #
-# CONFIG_FB_CIRRUS is not set
-# CONFIG_FB_PM2 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_ASILIANT is not set
-# CONFIG_FB_IMSTT is not set
 # CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_NVIDIA is not set
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON is not set
-# CONFIG_FB_ATY128 is not set
-# CONFIG_FB_ATY is not set
-# CONFIG_FB_S3 is not set
-# CONFIG_FB_SAVAGE is not set
-# CONFIG_FB_SIS is not set
-# CONFIG_FB_NEOMAGIC is not set
-# CONFIG_FB_KYRO is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_VT8623 is not set
-# CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_ARK is not set
-# CONFIG_FB_PM3 is not set
-CONFIG_FB_PXA=y
+CONFIG_FB_PXA=m
 # CONFIG_FB_PXA_SMARTPANEL is not set
 CONFIG_FB_PXA_PARAMETERS=y
-CONFIG_FB_MBX=m
+# CONFIG_FB_MBX is not set
+# CONFIG_FB_W100 is not set
 # CONFIG_FB_AM200EPD is not set
 # CONFIG_FB_VIRTUAL is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=m
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_PWM=m
 
 #
 # Display device support
@@ -1088,8 +1052,9 @@
 # Console display driver support
 #
 # CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=m
 # CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
 # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 # CONFIG_FONTS is not set
@@ -1099,15 +1064,7 @@
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
 CONFIG_SOUND=m
-
-#
-# Advanced Linux Sound Architecture
-#
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
@@ -1121,133 +1078,49 @@
 CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
-
-#
-# Generic devices
-#
+CONFIG_SND_VMASTER=y
 CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_DRIVERS=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_MTPAV is not set
 # CONFIG_SND_SERIAL_U16550 is not set
 # CONFIG_SND_MPU401 is not set
-
-#
-# PCI devices
-#
-# CONFIG_SND_AD1889 is not set
-# CONFIG_SND_ALS300 is not set
-# CONFIG_SND_ALI5451 is not set
-# CONFIG_SND_ATIIXP is not set
-# CONFIG_SND_ATIIXP_MODEM is not set
-# CONFIG_SND_AU8810 is not set
-# CONFIG_SND_AU8820 is not set
-# CONFIG_SND_AU8830 is not set
-# CONFIG_SND_AW2 is not set
-# CONFIG_SND_AZT3328 is not set
-# CONFIG_SND_BT87X is not set
-# CONFIG_SND_CA0106 is not set
-# CONFIG_SND_CMIPCI is not set
-# CONFIG_SND_OXYGEN is not set
-# CONFIG_SND_CS4281 is not set
-# CONFIG_SND_CS46XX is not set
-# CONFIG_SND_DARLA20 is not set
-# CONFIG_SND_GINA20 is not set
-# CONFIG_SND_LAYLA20 is not set
-# CONFIG_SND_DARLA24 is not set
-# CONFIG_SND_GINA24 is not set
-# CONFIG_SND_LAYLA24 is not set
-# CONFIG_SND_MONA is not set
-# CONFIG_SND_MIA is not set
-# CONFIG_SND_ECHO3G is not set
-# CONFIG_SND_INDIGO is not set
-# CONFIG_SND_INDIGOIO is not set
-# CONFIG_SND_INDIGODJ is not set
-# CONFIG_SND_EMU10K1 is not set
-# CONFIG_SND_EMU10K1X is not set
-# CONFIG_SND_ENS1370 is not set
-# CONFIG_SND_ENS1371 is not set
-# CONFIG_SND_ES1938 is not set
-# CONFIG_SND_ES1968 is not set
-# CONFIG_SND_FM801 is not set
-# CONFIG_SND_HDA_INTEL is not set
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_HDSPM is not set
-# CONFIG_SND_HIFIER is not set
-# CONFIG_SND_ICE1712 is not set
-# CONFIG_SND_ICE1724 is not set
-# CONFIG_SND_INTEL8X0 is not set
-# CONFIG_SND_INTEL8X0M is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_MAESTRO3 is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_PCXHR is not set
-# CONFIG_SND_RIPTIDE is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_SONICVIBES is not set
-# CONFIG_SND_TRIDENT is not set
-# CONFIG_SND_VIA82XX is not set
-# CONFIG_SND_VIA82XX_MODEM is not set
-# CONFIG_SND_VIRTUOSO is not set
-# CONFIG_SND_VX222 is not set
-# CONFIG_SND_YMFPCI is not set
 # CONFIG_SND_AC97_POWER_SAVE is not set
-
-#
-# ALSA ARM devices
-#
+CONFIG_SND_ARM=y
 CONFIG_SND_PXA2XX_PCM=m
 CONFIG_SND_PXA2XX_AC97=m
-
-#
-# USB devices
-#
+CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
 # CONFIG_SND_USB_CAIAQ is not set
-
-#
-# PCMCIA devices
-#
+CONFIG_SND_PCMCIA=y
 # CONFIG_SND_VXPOCKET is not set
 # CONFIG_SND_PDAUDIOCF is not set
-
-#
-# System on Chip audio support
-#
 # CONFIG_SND_SOC is not set
-
-#
-# ALSA SoC audio for Freescale SOCs
-#
-
-#
-# SoC Audio for the Texas Instruments OMAP
-#
-
-#
-# Open Sound System
-#
 # CONFIG_SOUND_PRIME is not set
 CONFIG_AC97_BUS=m
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-CONFIG_HID_DEBUG=y
+# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 
 #
 # USB Input Devices
 #
-CONFIG_USB_HID=y
+CONFIG_USB_HID=m
 # CONFIG_USB_HIDINPUT_POWERBOOK is not set
 # CONFIG_HID_FF is not set
 # CONFIG_USB_HIDDEV is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARCH_HAS_EHCI=y
-CONFIG_USB=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=m
 # CONFIG_USB_DEBUG is not set
 # CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
 
@@ -1255,31 +1128,32 @@
 # Miscellaneous USB options
 #
 CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DEVICE_CLASS=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
+CONFIG_USB_SUSPEND=y
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
 
 #
 # USB Host Controller Drivers
 #
-# CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_ISP116X_HCD is not set
-CONFIG_USB_OHCI_HCD=y
-# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
-# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
-CONFIG_USB_OHCI_LITTLE_ENDIAN=y
-# CONFIG_USB_UHCI_HCD is not set
-# CONFIG_USB_SL811_HCD is not set
-# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_ISP116X_HCD=m
+# CONFIG_USB_ISP1760_HCD is not set
+CONFIG_USB_SL811_HCD=m
+# CONFIG_USB_SL811_CS is not set
+CONFIG_USB_R8A66597_HCD=m
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
 # USB Device Class drivers
 #
-# CONFIG_USB_ACM is not set
+CONFIG_USB_ACM=m
 # CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -1288,7 +1162,7 @@
 #
 # may also be needed; see USB_STORAGE Help for more information
 #
-CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
@@ -1301,6 +1175,7 @@
 # CONFIG_USB_STORAGE_ALAUDA is not set
 # CONFIG_USB_STORAGE_ONETOUCH is not set
 # CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_SIERRA is not set
 # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
 # CONFIG_USB_LIBUSUAL is not set
 
@@ -1309,12 +1184,53 @@
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-CONFIG_USB_MON=y
 
 #
 # USB port drivers
 #
-# CONFIG_USB_SERIAL is not set
+CONFIG_USB_SERIAL=m
+# CONFIG_USB_EZUSB is not set
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP2101 is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+CONFIG_USB_SERIAL_MCT_U232=m
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
 
 #
 # USB Miscellaneous drivers
@@ -1322,7 +1238,6 @@
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
@@ -1338,45 +1253,41 @@
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
-# CONFIG_USB_GADGET is not set
-CONFIG_MMC=m
-# CONFIG_MMC_DEBUG is not set
-# CONFIG_MMC_UNSAFE_RESUME is not set
-
-#
-# MMC/SD Card Drivers
-#
-CONFIG_MMC_BLOCK=m
-CONFIG_MMC_BLOCK_BOUNCE=y
-# CONFIG_SDIO_UART is not set
-
-#
-# MMC/SD Host Controller Drivers
-#
-CONFIG_MMC_PXA=m
-# CONFIG_MMC_SDHCI is not set
-# CONFIG_MMC_TIFM_SD is not set
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-
-#
-# LED drivers
-#
-# CONFIG_LEDS_GPIO is not set
-CONFIG_LEDS_CM_X270=y
-
-#
-# LED Triggers
-#
-CONFIG_LEDS_TRIGGERS=y
-# CONFIG_LEDS_TRIGGER_TIMER is not set
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+# CONFIG_USB_ISIGHTFW is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+CONFIG_USB_GADGET_PXA25X=y
+CONFIG_USB_PXA25X=m
+# CONFIG_USB_PXA25X_SMALL is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+CONFIG_USB_G_PRINTER=m
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
 CONFIG_RTC_LIB=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_HCTOSYS=y
-CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
-# CONFIG_RTC_DEBUG is not set
+CONFIG_RTC_CLASS=m
 
 #
 # RTC interfaces
@@ -1390,7 +1301,7 @@
 #
 # I2C RTC drivers
 #
-# CONFIG_RTC_DRV_DS1307 is not set
+CONFIG_RTC_DRV_DS1307=m
 # CONFIG_RTC_DRV_DS1374 is not set
 # CONFIG_RTC_DRV_DS1672 is not set
 # CONFIG_RTC_DRV_MAX6900 is not set
@@ -1401,6 +1312,7 @@
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
 # CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
 
 #
 # SPI RTC drivers
@@ -1416,33 +1328,39 @@
 # CONFIG_RTC_DRV_STK17TA8 is not set
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
-CONFIG_RTC_DRV_V3020=y
+# CONFIG_RTC_DRV_V3020 is not set
 
 #
 # on-CPU RTC drivers
 #
-CONFIG_RTC_DRV_SA1100=y
+CONFIG_RTC_DRV_SA1100=m
+# CONFIG_DMADEVICES is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
 # CONFIG_UIO is not set
 
 #
 # File systems
 #
-CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS=m
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT3_FS=m
+# CONFIG_EXT3_FS_XATTR is not set
 # CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=y
-CONFIG_FS_MBCACHE=y
+CONFIG_JBD=m
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
-CONFIG_DNOTIFY=y
+# CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
@@ -1491,7 +1409,7 @@
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
 # CONFIG_JFFS2_FS_WBUF_VERIFY is not set
-CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_SUMMARY is not set
 # CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
@@ -1501,6 +1419,7 @@
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1511,22 +1430,20 @@
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
-CONFIG_CIFS=m
-# CONFIG_CIFS_STATS is not set
-# CONFIG_CIFS_WEAK_PW_HASH is not set
-# CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_DEBUG2 is not set
-# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1557,7 +1474,7 @@
 CONFIG_NLS_CODEPAGE_437=m
 # CONFIG_NLS_CODEPAGE_737 is not set
 # CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
+CONFIG_NLS_CODEPAGE_850=m
 # CONFIG_NLS_CODEPAGE_852 is not set
 # CONFIG_NLS_CODEPAGE_855 is not set
 # CONFIG_NLS_CODEPAGE_857 is not set
@@ -1588,7 +1505,7 @@
 # CONFIG_NLS_ISO8859_9 is not set
 # CONFIG_NLS_ISO8859_13 is not set
 # CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
+CONFIG_NLS_ISO8859_15=m
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=m
@@ -1600,32 +1517,36 @@
 # CONFIG_PRINTK_TIME is not set
 CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_FRAME_WARN=0
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
-# CONFIG_DETECT_SOFTLOCKUP is not set
-# CONFIG_SCHED_DEBUG is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_MUTEXES is not set
+CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_LOCK_ALLOC is not set
 # CONFIG_PROVE_LOCKING is not set
 # CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 CONFIG_FRAME_POINTER=y
@@ -1633,12 +1554,21 @@
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
 # CONFIG_SAMPLES is not set
-CONFIG_DEBUG_USER=y
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
 CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_STACK_USAGE is not set
-CONFIG_DEBUG_LL=y
-# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_DEBUG_LL is not set
 
 #
 # Security options
@@ -1651,7 +1581,9 @@
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_MANAGER is not set
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_MANAGER=m
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_CRYPTD is not set
@@ -1671,7 +1603,7 @@
 # CONFIG_CRYPTO_CBC is not set
 # CONFIG_CRYPTO_CTR is not set
 # CONFIG_CRYPTO_CTS is not set
-# CONFIG_CRYPTO_ECB is not set
+CONFIG_CRYPTO_ECB=m
 # CONFIG_CRYPTO_LRW is not set
 # CONFIG_CRYPTO_PCBC is not set
 # CONFIG_CRYPTO_XTS is not set
@@ -1689,6 +1621,10 @@
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
@@ -1700,7 +1636,7 @@
 #
 # CONFIG_CRYPTO_AES is not set
 # CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=m
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_CAST5 is not set
@@ -1719,7 +1655,7 @@
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
-# CONFIG_CRYPTO_HW is not set
+CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
@@ -1729,6 +1665,7 @@
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=m
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
diff --git a/arch/arm/configs/xm_x270_defconfig b/arch/arm/configs/xm_x2xx_defconfig
similarity index 91%
rename from arch/arm/configs/xm_x270_defconfig
rename to arch/arm/configs/xm_x2xx_defconfig
index aa40d91..f891364 100644
--- a/arch/arm/configs/xm_x270_defconfig
+++ b/arch/arm/configs/xm_x2xx_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.25
-# Sun May 11 15:12:52 2008
+# Linux kernel version: 2.6.27-rc8
+# Sun Oct  5 11:05:36 2008
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -12,6 +12,7 @@
 # CONFIG_NO_IOPORT is not set
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
@@ -24,6 +25,7 @@
 CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_ZONE_DMA=y
 CONFIG_ARCH_MTD_XIP=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -62,7 +64,6 @@
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -88,14 +89,21 @@
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_CLK=y
 # CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
@@ -106,6 +114,7 @@
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -131,7 +140,6 @@
 # CONFIG_ARCH_AT91 is not set
 # CONFIG_ARCH_CLPS7500 is not set
 # CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
 # CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
@@ -145,8 +153,11 @@
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
 # CONFIG_ARCH_KS8695 is not set
 # CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
 # CONFIG_ARCH_MXC is not set
 # CONFIG_ARCH_ORION5X is not set
 # CONFIG_ARCH_PNX4008 is not set
@@ -164,26 +175,32 @@
 #
 # Intel PXA2xx/PXA3xx Implementations
 #
-
-#
-# Select target boards
-#
 # CONFIG_ARCH_GUMSTIX is not set
 # CONFIG_ARCH_LUBBOCK is not set
 # CONFIG_MACH_LOGICPD_PXA270 is not set
 # CONFIG_MACH_MAINSTONE is not set
+# CONFIG_MACH_MP900C is not set
 # CONFIG_ARCH_PXA_IDP is not set
 # CONFIG_PXA_SHARPSL is not set
+# CONFIG_ARCH_VIPER is not set
 # CONFIG_ARCH_PXA_ESERIES is not set
-# CONFIG_MACH_TRIZEPS4 is not set
+# CONFIG_TRIZEPS_PXA is not set
 CONFIG_MACH_EM_X270=y
 # CONFIG_MACH_COLIBRI is not set
 # CONFIG_MACH_ZYLONITE is not set
 # CONFIG_MACH_LITTLETON is not set
+# CONFIG_MACH_TAVOREVB is not set
+# CONFIG_MACH_SAAR is not set
 CONFIG_MACH_ARMCORE=y
+# CONFIG_MACH_CM_X300 is not set
 # CONFIG_MACH_MAGICIAN is not set
+# CONFIG_MACH_MIOA701 is not set
 # CONFIG_MACH_PCM027 is not set
+# CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_PXA_EZX is not set
+CONFIG_PXA25x=y
 CONFIG_PXA27x=y
+CONFIG_PXA_SSP=y
 # CONFIG_PXA_PWM is not set
 
 #
@@ -253,11 +270,17 @@
 CONFIG_NO_HZ=y
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
 # CONFIG_PREEMPT is not set
 CONFIG_HZ=100
 CONFIG_AEABI=y
 CONFIG_OABI_COMPAT=y
-# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -284,9 +307,10 @@
 # CONFIG_KEXEC is not set
 
 #
-# CPU Frequency scaling
+# CPU Power Management
 #
 # CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
 
 #
 # Floating point emulation
@@ -316,10 +340,6 @@
 CONFIG_SUSPEND_FREEZER=y
 CONFIG_APM_EMULATION=m
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -402,6 +422,7 @@
 #
 CONFIG_BT_HCIUSB=m
 CONFIG_BT_HCIUSB_SCO=y
+# CONFIG_BT_HCIBTUSB is not set
 # CONFIG_BT_HCIBTSDIO is not set
 # CONFIG_BT_HCIUART is not set
 # CONFIG_BT_HCIBCM203X is not set
@@ -419,6 +440,7 @@
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
 # CONFIG_RFKILL is not set
@@ -435,6 +457,8 @@
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=m
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
@@ -527,6 +551,7 @@
 # CONFIG_MTD_NAND_ECC_SMC is not set
 # CONFIG_MTD_NAND_MUSEUM_IDS is not set
 # CONFIG_MTD_NAND_H1900 is not set
+CONFIG_MTD_NAND_GPIO=m
 CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 # CONFIG_MTD_NAND_SHARPSL is not set
@@ -636,6 +661,7 @@
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_SCSI_DH is not set
 CONFIG_ATA=m
 # CONFIG_ATA_NONSTANDARD is not set
 # CONFIG_SATA_PMP is not set
@@ -696,17 +722,21 @@
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
+# CONFIG_PATA_SCH is not set
 # CONFIG_MD is not set
 # CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -725,6 +755,7 @@
 # CONFIG_SMC91X is not set
 CONFIG_DM9000=y
 CONFIG_DM9000_DEBUGLEVEL=1
+# CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL is not set
 # CONFIG_SMC911X is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
@@ -780,7 +811,6 @@
 # CONFIG_PRISM54 is not set
 # CONFIG_USB_ZD1201 is not set
 # CONFIG_USB_NET_RNDIS_WLAN is not set
-# CONFIG_IWLWIFI is not set
 # CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_HOSTAP is not set
 
@@ -853,17 +883,18 @@
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_ELO is not set
 # CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
 # CONFIG_TOUCHSCREEN_MK712 is not set
 # CONFIG_TOUCHSCREEN_PENMOUNT is not set
 # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
 # CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-CONFIG_TOUCHSCREEN_UCB1400=m
 CONFIG_TOUCHSCREEN_WM97XX=m
 # CONFIG_TOUCHSCREEN_WM9705 is not set
 CONFIG_TOUCHSCREEN_WM9712=y
 # CONFIG_TOUCHSCREEN_WM9713 is not set
 # CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE is not set
 # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
 # CONFIG_INPUT_MISC is not set
 
 #
@@ -880,6 +911,7 @@
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
@@ -922,45 +954,66 @@
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
 
 #
 # I2C Hardware Bus support
 #
+
+#
+# PC SMBus host controller drivers
+#
 # CONFIG_I2C_ALI1535 is not set
 # CONFIG_I2C_ALI1563 is not set
 # CONFIG_I2C_ALI15X3 is not set
 # CONFIG_I2C_AMD756 is not set
 # CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_GPIO is not set
 # CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
-CONFIG_I2C_PXA=y
-# CONFIG_I2C_PXA_SLAVE is not set
+# CONFIG_I2C_ISCH is not set
 # CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_I2C_SIMTEC is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_TINY_USB is not set
 # CONFIG_I2C_VIA is not set
 # CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PXA=y
+# CONFIG_I2C_PXA_SLAVE is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
 # CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
 # CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
 
 #
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_SENSORS_MAX6875 is not set
@@ -970,25 +1023,31 @@
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
-CONFIG_HAVE_GPIO_LIB=y
-
-#
-# GPIO Support
-#
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
 
 #
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+
+#
 # SPI GPIO expanders:
 #
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -1000,10 +1059,16 @@
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_ASIC3 is not set
 # CONFIG_HTC_EGPIO is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
 
 #
 # Multimedia devices
@@ -1014,6 +1079,7 @@
 #
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
 
 #
 # Multimedia drivers
@@ -1038,7 +1104,6 @@
 # CONFIG_FB_SYS_IMAGEBLIT is not set
 # CONFIG_FB_FOREIGN_ENDIAN is not set
 # CONFIG_FB_SYS_FOPS is not set
-CONFIG_FB_DEFERRED_IO=y
 # CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
@@ -1071,12 +1136,14 @@
 # CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_ARK is not set
 # CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
 CONFIG_FB_PXA=y
 # CONFIG_FB_PXA_SMARTPANEL is not set
 CONFIG_FB_PXA_PARAMETERS=y
 CONFIG_FB_MBX=m
-# CONFIG_FB_AM200EPD is not set
+# CONFIG_FB_W100 is not set
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -1099,15 +1166,7 @@
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
 CONFIG_SOUND=m
-
-#
-# Advanced Linux Sound Architecture
-#
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
@@ -1121,19 +1180,15 @@
 CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
-
-#
-# Generic devices
-#
+CONFIG_SND_VMASTER=y
 CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_DRIVERS=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_MTPAV is not set
 # CONFIG_SND_SERIAL_U16550 is not set
 # CONFIG_SND_MPU401 is not set
-
-#
-# PCI devices
-#
+# CONFIG_SND_AC97_POWER_SAVE is not set
+CONFIG_SND_PCI=y
 # CONFIG_SND_AD1889 is not set
 # CONFIG_SND_ALS300 is not set
 # CONFIG_SND_ALI5451 is not set
@@ -1193,42 +1248,16 @@
 # CONFIG_SND_VIRTUOSO is not set
 # CONFIG_SND_VX222 is not set
 # CONFIG_SND_YMFPCI is not set
-# CONFIG_SND_AC97_POWER_SAVE is not set
-
-#
-# ALSA ARM devices
-#
+CONFIG_SND_ARM=y
 CONFIG_SND_PXA2XX_PCM=m
 CONFIG_SND_PXA2XX_AC97=m
-
-#
-# USB devices
-#
+CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
 # CONFIG_SND_USB_CAIAQ is not set
-
-#
-# PCMCIA devices
-#
+CONFIG_SND_PCMCIA=y
 # CONFIG_SND_VXPOCKET is not set
 # CONFIG_SND_PDAUDIOCF is not set
-
-#
-# System on Chip audio support
-#
 # CONFIG_SND_SOC is not set
-
-#
-# ALSA SoC audio for Freescale SOCs
-#
-
-#
-# SoC Audio for the Texas Instruments OMAP
-#
-
-#
-# Open Sound System
-#
 # CONFIG_SOUND_PRIME is not set
 CONFIG_AC97_BUS=m
 CONFIG_HID_SUPPORT=y
@@ -1261,12 +1290,15 @@
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
 
 #
 # USB Host Controller Drivers
 #
+# CONFIG_USB_C67X00_HCD is not set
 # CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
 # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
@@ -1274,12 +1306,14 @@
 # CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
 
 #
 # USB Device Class drivers
 #
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -1309,7 +1343,6 @@
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-CONFIG_USB_MON=y
 
 #
 # USB port drivers
@@ -1322,7 +1355,6 @@
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
@@ -1338,6 +1370,7 @@
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_GADGET is not set
 CONFIG_MMC=m
 # CONFIG_MMC_DEBUG is not set
@@ -1349,6 +1382,7 @@
 CONFIG_MMC_BLOCK=m
 CONFIG_MMC_BLOCK_BOUNCE=y
 # CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
 
 #
 # MMC/SD Host Controller Drivers
@@ -1356,14 +1390,19 @@
 CONFIG_MMC_PXA=m
 # CONFIG_MMC_SDHCI is not set
 # CONFIG_MMC_TIFM_SD is not set
+# CONFIG_MMC_SDRICOH_CS is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 
 #
 # LED drivers
 #
+# CONFIG_LEDS_PCA9532 is not set
 # CONFIG_LEDS_GPIO is not set
 CONFIG_LEDS_CM_X270=y
+# CONFIG_LEDS_PCA955X is not set
 
 #
 # LED Triggers
@@ -1401,6 +1440,7 @@
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
 # CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
 
 #
 # SPI RTC drivers
@@ -1422,6 +1462,15 @@
 # on-CPU RTC drivers
 #
 CONFIG_RTC_DRV_SA1100=y
+# CONFIG_DMADEVICES is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
 # CONFIG_UIO is not set
 
 #
@@ -1501,6 +1550,7 @@
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1511,13 +1561,12 @@
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1626,6 +1675,7 @@
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 CONFIG_FRAME_POINTER=y
@@ -1633,7 +1683,17 @@
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
 # CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_STACK_USAGE is not set
@@ -1689,6 +1749,10 @@
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
@@ -1729,6 +1793,7 @@
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
diff --git a/arch/arm/include/asm/bug.h b/arch/arm/include/asm/bug.h
index 7b62351..4d88425 100644
--- a/arch/arm/include/asm/bug.h
+++ b/arch/arm/include/asm/bug.h
@@ -12,7 +12,7 @@
 #else
 
 /* this just causes an oops */
-#define BUG()		(*(int *)0 = 0)
+#define BUG()		do { *(int *)0 = 0; } while (1)
 
 #endif
 
diff --git a/arch/arm/include/asm/byteorder.h b/arch/arm/include/asm/byteorder.h
index d04a7a2..4fbfb22 100644
--- a/arch/arm/include/asm/byteorder.h
+++ b/arch/arm/include/asm/byteorder.h
@@ -18,15 +18,7 @@
 #include <linux/compiler.h>
 #include <asm/types.h>
 
-#ifdef __ARMEB__
-# define __BIG_ENDIAN
-#else
-# define __LITTLE_ENDIAN
-#endif
-
-#define __SWAB_64_THRU_32__
-
-static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
+static inline __attribute_const__ __u32 ___arch__swab32(__u32 x)
 {
 	__u32 t;
 
@@ -48,8 +40,19 @@
 
 	return x;
 }
-#define __arch_swab32 __arch_swab32
 
-#include <linux/byteorder.h>
+#define __arch__swab32(x) ___arch__swab32(x)
+
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#  define __SWAB_64_THRU_32__
+#endif
+
+#ifdef __ARMEB__
+#include <linux/byteorder/big_endian.h>
+#else
+#include <linux/byteorder/little_endian.h>
+#endif
 
 #endif
+
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index 9073d9c..de6c59f 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -444,94 +444,4 @@
 	dmac_inv_range(start, start + size);
 }
 
-#define __cacheid_present(val)			(val != read_cpuid(CPUID_ID))
-#define __cacheid_type_v7(val)			((val & (7 << 29)) == (4 << 29))
-
-#define __cacheid_vivt_prev7(val)		((val & (15 << 25)) != (14 << 25))
-#define __cacheid_vipt_prev7(val)		((val & (15 << 25)) == (14 << 25))
-#define __cacheid_vipt_nonaliasing_prev7(val)	((val & (15 << 25 | 1 << 23)) == (14 << 25))
-#define __cacheid_vipt_aliasing_prev7(val)	((val & (15 << 25 | 1 << 23)) == (14 << 25 | 1 << 23))
-
-#define __cacheid_vivt(val)			(__cacheid_type_v7(val) ? 0 : __cacheid_vivt_prev7(val))
-#define __cacheid_vipt(val)			(__cacheid_type_v7(val) ? 1 : __cacheid_vipt_prev7(val))
-#define __cacheid_vipt_nonaliasing(val)		(__cacheid_type_v7(val) ? 1 : __cacheid_vipt_nonaliasing_prev7(val))
-#define __cacheid_vipt_aliasing(val)		(__cacheid_type_v7(val) ? 0 : __cacheid_vipt_aliasing_prev7(val))
-#define __cacheid_vivt_asid_tagged_instr(val)	(__cacheid_type_v7(val) ? ((val & (3 << 14)) == (1 << 14)) : 0)
-
-#if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT)
-/*
- * VIVT caches only
- */
-#define cache_is_vivt()			1
-#define cache_is_vipt()			0
-#define cache_is_vipt_nonaliasing()	0
-#define cache_is_vipt_aliasing()	0
-#define icache_is_vivt_asid_tagged()	0
-
-#elif !defined(CONFIG_CPU_CACHE_VIVT) && defined(CONFIG_CPU_CACHE_VIPT)
-/*
- * VIPT caches only
- */
-#define cache_is_vivt()			0
-#define cache_is_vipt()			1
-#define cache_is_vipt_nonaliasing()					\
-	({								\
-		unsigned int __val = read_cpuid(CPUID_CACHETYPE);	\
-		__cacheid_vipt_nonaliasing(__val);			\
-	})
-
-#define cache_is_vipt_aliasing()					\
-	({								\
-		unsigned int __val = read_cpuid(CPUID_CACHETYPE);	\
-		__cacheid_vipt_aliasing(__val);				\
-	})
-
-#define icache_is_vivt_asid_tagged()					\
-	({								\
-		unsigned int __val = read_cpuid(CPUID_CACHETYPE);	\
-		__cacheid_vivt_asid_tagged_instr(__val);		\
-	})
-
-#else
-/*
- * VIVT or VIPT caches.  Note that this is unreliable since ARM926
- * and V6 CPUs satisfy the "(val & (15 << 25)) == (14 << 25)" test.
- * There's no way to tell from the CacheType register what type (!)
- * the cache is.
- */
-#define cache_is_vivt()							\
-	({								\
-		unsigned int __val = read_cpuid(CPUID_CACHETYPE);	\
-		(!__cacheid_present(__val)) || __cacheid_vivt(__val);	\
-	})
-		
-#define cache_is_vipt()							\
-	({								\
-		unsigned int __val = read_cpuid(CPUID_CACHETYPE);	\
-		__cacheid_present(__val) && __cacheid_vipt(__val);	\
-	})
-
-#define cache_is_vipt_nonaliasing()					\
-	({								\
-		unsigned int __val = read_cpuid(CPUID_CACHETYPE);	\
-		__cacheid_present(__val) &&				\
-		 __cacheid_vipt_nonaliasing(__val);			\
-	})
-
-#define cache_is_vipt_aliasing()					\
-	({								\
-		unsigned int __val = read_cpuid(CPUID_CACHETYPE);	\
-		__cacheid_present(__val) &&				\
-		 __cacheid_vipt_aliasing(__val);			\
-	})
-
-#define icache_is_vivt_asid_tagged()					\
-	({								\
-		unsigned int __val = read_cpuid(CPUID_CACHETYPE);	\
-		__cacheid_present(__val) &&				\
-		 __cacheid_vivt_asid_tagged_instr(__val);		\
-	})
-
-#endif
-
 #endif
diff --git a/arch/arm/include/asm/cachetype.h b/arch/arm/include/asm/cachetype.h
new file mode 100644
index 0000000..d3a4c2c
--- /dev/null
+++ b/arch/arm/include/asm/cachetype.h
@@ -0,0 +1,52 @@
+#ifndef __ASM_ARM_CACHETYPE_H
+#define __ASM_ARM_CACHETYPE_H
+
+#define CACHEID_VIVT			(1 << 0)
+#define CACHEID_VIPT_NONALIASING	(1 << 1)
+#define CACHEID_VIPT_ALIASING		(1 << 2)
+#define CACHEID_VIPT			(CACHEID_VIPT_ALIASING|CACHEID_VIPT_NONALIASING)
+#define CACHEID_ASID_TAGGED		(1 << 3)
+
+extern unsigned int cacheid;
+
+#define cache_is_vivt()			cacheid_is(CACHEID_VIVT)
+#define cache_is_vipt()			cacheid_is(CACHEID_VIPT)
+#define cache_is_vipt_nonaliasing()	cacheid_is(CACHEID_VIPT_NONALIASING)
+#define cache_is_vipt_aliasing()	cacheid_is(CACHEID_VIPT_ALIASING)
+#define icache_is_vivt_asid_tagged()	cacheid_is(CACHEID_ASID_TAGGED)
+
+/*
+ * __LINUX_ARM_ARCH__ is the minimum supported CPU architecture
+ * Mask out support which will never be present on newer CPUs.
+ * - v6+ is never VIVT
+ * - v7+ VIPT never aliases
+ */
+#if __LINUX_ARM_ARCH__ >= 7
+#define __CACHEID_ARCH_MIN	(CACHEID_VIPT_NONALIASING | CACHEID_ASID_TAGGED)
+#elif __LINUX_ARM_ARCH__ >= 6
+#define	__CACHEID_ARCH_MIN	(~CACHEID_VIVT)
+#else
+#define __CACHEID_ARCH_MIN	(~0)
+#endif
+
+/*
+ * Mask out support which isn't configured
+ */
+#if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT)
+#define __CACHEID_ALWAYS	(CACHEID_VIVT)
+#define __CACHEID_NEVER		(~CACHEID_VIVT)
+#elif !defined(CONFIG_CPU_CACHE_VIVT) && defined(CONFIG_CPU_CACHE_VIPT)
+#define __CACHEID_ALWAYS	(0)
+#define __CACHEID_NEVER		(CACHEID_VIVT)
+#else
+#define __CACHEID_ALWAYS	(0)
+#define __CACHEID_NEVER		(0)
+#endif
+
+static inline unsigned int __attribute__((pure)) cacheid_is(unsigned int mask)
+{
+	return (__CACHEID_ALWAYS & mask) |
+	       (~__CACHEID_NEVER & __CACHEID_ARCH_MIN & mask & cacheid);
+}
+
+#endif
diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
new file mode 100644
index 0000000..7b9d27e
--- /dev/null
+++ b/arch/arm/include/asm/cputype.h
@@ -0,0 +1,64 @@
+#ifndef __ASM_ARM_CPUTYPE_H
+#define __ASM_ARM_CPUTYPE_H
+
+#include <linux/stringify.h>
+
+#define CPUID_ID	0
+#define CPUID_CACHETYPE	1
+#define CPUID_TCM	2
+#define CPUID_TLBTYPE	3
+
+#ifdef CONFIG_CPU_CP15
+#define read_cpuid(reg)							\
+	({								\
+		unsigned int __val;					\
+		asm("mrc	p15, 0, %0, c0, c0, " __stringify(reg)	\
+		    : "=r" (__val)					\
+		    :							\
+		    : "cc");						\
+		__val;							\
+	})
+#else
+extern unsigned int processor_id;
+#define read_cpuid(reg) (processor_id)
+#endif
+
+/*
+ * The CPU ID never changes at run time, so we might as well tell the
+ * compiler that it's constant.  Use this function to read the CPU ID
+ * rather than directly reading processor_id or read_cpuid() directly.
+ */
+static inline unsigned int __attribute_const__ read_cpuid_id(void)
+{
+	return read_cpuid(CPUID_ID);
+}
+
+static inline unsigned int __attribute_const__ read_cpuid_cachetype(void)
+{
+	return read_cpuid(CPUID_CACHETYPE);
+}
+
+/*
+ * Intel's XScale3 core supports some v6 features (supersections, L2)
+ * but advertises itself as v5 as it does not support the v6 ISA.  For
+ * this reason, we need a way to explicitly test for this type of CPU.
+ */
+#ifndef CONFIG_CPU_XSC3
+#define cpu_is_xsc3()	0
+#else
+static inline int cpu_is_xsc3(void)
+{
+	if ((read_cpuid_id() & 0xffffe000) == 0x69056000)
+		return 1;
+
+	return 0;
+}
+#endif
+
+#if !defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_CPU_XSC3)
+#define	cpu_is_xscale()	0
+#else
+#define	cpu_is_xscale()	1
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 7b95d20..1cb8602 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -104,15 +104,14 @@
  * Dummy noncoherent implementation.  We don't provide a dma_cache_sync
  * function so drivers using this API are highlighted with build warnings.
  */
-static inline void *
-dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
+static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
+		dma_addr_t *handle, gfp_t gfp)
 {
 	return NULL;
 }
 
-static inline void
-dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr,
-		     dma_addr_t handle)
+static inline void dma_free_noncoherent(struct device *dev, size_t size,
+		void *cpu_addr, dma_addr_t handle)
 {
 }
 
@@ -127,8 +126,7 @@
  * return the CPU-viewed address, and sets @handle to be the
  * device-viewed address.
  */
-extern void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp);
+extern void *dma_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t);
 
 /**
  * dma_free_coherent - free memory allocated by dma_alloc_coherent
@@ -143,9 +141,7 @@
  * References to memory and mappings associated with cpu_addr/handle
  * during and after this call executing are illegal.
  */
-extern void
-dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
-		  dma_addr_t handle);
+extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t);
 
 /**
  * dma_mmap_coherent - map a coherent DMA allocation into user space
@@ -159,8 +155,8 @@
  * into user space.  The coherent DMA buffer must not be freed by the
  * driver until the user space mapping has been released.
  */
-int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
-		      void *cpu_addr, dma_addr_t handle, size_t size);
+int dma_mmap_coherent(struct device *, struct vm_area_struct *,
+		void *, dma_addr_t, size_t);
 
 
 /**
@@ -174,282 +170,16 @@
  * return the CPU-viewed address, and sets @handle to be the
  * device-viewed address.
  */
-extern void *
-dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp);
+extern void *dma_alloc_writecombine(struct device *, size_t, dma_addr_t *,
+		gfp_t);
 
 #define dma_free_writecombine(dev,size,cpu_addr,handle) \
 	dma_free_coherent(dev,size,cpu_addr,handle)
 
-int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
-			  void *cpu_addr, dma_addr_t handle, size_t size);
+int dma_mmap_writecombine(struct device *, struct vm_area_struct *,
+		void *, dma_addr_t, size_t);
 
 
-/**
- * dma_map_single - map a single buffer for streaming DMA
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @cpu_addr: CPU direct mapped address of buffer
- * @size: size of buffer to map
- * @dir: DMA transfer direction
- *
- * Ensure that any data held in the cache is appropriately discarded
- * or written back.
- *
- * The device owns this memory once this call has completed.  The CPU
- * can regain ownership by calling dma_unmap_single() or
- * dma_sync_single_for_cpu().
- */
-#ifndef CONFIG_DMABOUNCE
-static inline dma_addr_t
-dma_map_single(struct device *dev, void *cpu_addr, size_t size,
-	       enum dma_data_direction dir)
-{
-	if (!arch_is_coherent())
-		dma_cache_maint(cpu_addr, size, dir);
-
-	return virt_to_dma(dev, cpu_addr);
-}
-#else
-extern dma_addr_t dma_map_single(struct device *,void *, size_t, enum dma_data_direction);
-#endif
-
-/**
- * dma_map_page - map a portion of a page for streaming DMA
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @page: page that buffer resides in
- * @offset: offset into page for start of buffer
- * @size: size of buffer to map
- * @dir: DMA transfer direction
- *
- * Ensure that any data held in the cache is appropriately discarded
- * or written back.
- *
- * The device owns this memory once this call has completed.  The CPU
- * can regain ownership by calling dma_unmap_page() or
- * dma_sync_single_for_cpu().
- */
-static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page,
-	     unsigned long offset, size_t size,
-	     enum dma_data_direction dir)
-{
-	return dma_map_single(dev, page_address(page) + offset, size, dir);
-}
-
-/**
- * dma_unmap_single - unmap a single buffer previously mapped
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @handle: DMA address of buffer
- * @size: size of buffer to map
- * @dir: DMA transfer direction
- *
- * Unmap a single streaming mode DMA translation.  The handle and size
- * must match what was provided in the previous dma_map_single() call.
- * All other usages are undefined.
- *
- * After this call, reads by the CPU to the buffer are guaranteed to see
- * whatever the device wrote there.
- */
-#ifndef CONFIG_DMABOUNCE
-static inline void
-dma_unmap_single(struct device *dev, dma_addr_t handle, size_t size,
-		 enum dma_data_direction dir)
-{
-	/* nothing to do */
-}
-#else
-extern void dma_unmap_single(struct device *, dma_addr_t, size_t, enum dma_data_direction);
-#endif
-
-/**
- * dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @handle: DMA address of buffer
- * @size: size of buffer to map
- * @dir: DMA transfer direction
- *
- * Unmap a single streaming mode DMA translation.  The handle and size
- * must match what was provided in the previous dma_map_single() call.
- * All other usages are undefined.
- *
- * After this call, reads by the CPU to the buffer are guaranteed to see
- * whatever the device wrote there.
- */
-static inline void
-dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
-	       enum dma_data_direction dir)
-{
-	dma_unmap_single(dev, handle, size, dir);
-}
-
-/**
- * dma_map_sg - map a set of SG buffers for streaming mode DMA
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @sg: list of buffers
- * @nents: number of buffers to map
- * @dir: DMA transfer direction
- *
- * Map a set of buffers described by scatterlist in streaming
- * mode for DMA.  This is the scatter-gather version of the
- * above dma_map_single interface.  Here the scatter gather list
- * elements are each tagged with the appropriate dma address
- * and length.  They are obtained via sg_dma_{address,length}(SG).
- *
- * NOTE: An implementation may be able to use a smaller number of
- *       DMA address/length pairs than there are SG table elements.
- *       (for example via virtual mapping capabilities)
- *       The routine returns the number of addr/length pairs actually
- *       used, at most nents.
- *
- * Device ownership issues as mentioned above for dma_map_single are
- * the same here.
- */
-#ifndef CONFIG_DMABOUNCE
-static inline int
-dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-	   enum dma_data_direction dir)
-{
-	int i;
-
-	for (i = 0; i < nents; i++, sg++) {
-		char *virt;
-
-		sg->dma_address = page_to_dma(dev, sg_page(sg)) + sg->offset;
-		virt = sg_virt(sg);
-
-		if (!arch_is_coherent())
-			dma_cache_maint(virt, sg->length, dir);
-	}
-
-	return nents;
-}
-#else
-extern int dma_map_sg(struct device *, struct scatterlist *, int, enum dma_data_direction);
-#endif
-
-/**
- * dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @sg: list of buffers
- * @nents: number of buffers to map
- * @dir: DMA transfer direction
- *
- * Unmap a set of streaming mode DMA translations.
- * Again, CPU read rules concerning calls here are the same as for
- * dma_unmap_single() above.
- */
-#ifndef CONFIG_DMABOUNCE
-static inline void
-dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-	     enum dma_data_direction dir)
-{
-
-	/* nothing to do */
-}
-#else
-extern void dma_unmap_sg(struct device *, struct scatterlist *, int, enum dma_data_direction);
-#endif
-
-
-/**
- * dma_sync_single_range_for_cpu
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @handle: DMA address of buffer
- * @offset: offset of region to start sync
- * @size: size of region to sync
- * @dir: DMA transfer direction (same as passed to dma_map_single)
- *
- * Make physical memory consistent for a single streaming mode DMA
- * translation after a transfer.
- *
- * If you perform a dma_map_single() but wish to interrogate the
- * buffer using the cpu, yet do not wish to teardown the PCI dma
- * mapping, you must call this function before doing so.  At the
- * next point you give the PCI dma address back to the card, you
- * must first the perform a dma_sync_for_device, and then the
- * device again owns the buffer.
- */
-#ifndef CONFIG_DMABOUNCE
-static inline void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t handle,
-			      unsigned long offset, size_t size,
-			      enum dma_data_direction dir)
-{
-	if (!arch_is_coherent())
-		dma_cache_maint(dma_to_virt(dev, handle) + offset, size, dir);
-}
-
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t handle,
-				 unsigned long offset, size_t size,
-				 enum dma_data_direction dir)
-{
-	if (!arch_is_coherent())
-		dma_cache_maint(dma_to_virt(dev, handle) + offset, size, dir);
-}
-#else
-extern void dma_sync_single_range_for_cpu(struct device *, dma_addr_t, unsigned long, size_t, enum dma_data_direction);
-extern void dma_sync_single_range_for_device(struct device *, dma_addr_t, unsigned long, size_t, enum dma_data_direction);
-#endif
-
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size,
-			enum dma_data_direction dir)
-{
-	dma_sync_single_range_for_cpu(dev, handle, 0, size, dir);
-}
-
-static inline void
-dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size,
-			   enum dma_data_direction dir)
-{
-	dma_sync_single_range_for_device(dev, handle, 0, size, dir);
-}
-
-
-/**
- * dma_sync_sg_for_cpu
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @sg: list of buffers
- * @nents: number of buffers to map
- * @dir: DMA transfer direction
- *
- * Make physical memory consistent for a set of streaming
- * mode DMA translations after a transfer.
- *
- * The same as dma_sync_single_for_* but for a scatter-gather list,
- * same rules and usage.
- */
-#ifndef CONFIG_DMABOUNCE
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
-		    enum dma_data_direction dir)
-{
-	int i;
-
-	for (i = 0; i < nents; i++, sg++) {
-		char *virt = sg_virt(sg);
-		if (!arch_is_coherent())
-			dma_cache_maint(virt, sg->length, dir);
-	}
-}
-
-static inline void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
-		       enum dma_data_direction dir)
-{
-	int i;
-
-	for (i = 0; i < nents; i++, sg++) {
-		char *virt = sg_virt(sg);
-		if (!arch_is_coherent())
-			dma_cache_maint(virt, sg->length, dir);
-	}
-}
-#else
-extern void dma_sync_sg_for_cpu(struct device*, struct scatterlist*, int, enum dma_data_direction);
-extern void dma_sync_sg_for_device(struct device*, struct scatterlist*, int, enum dma_data_direction);
-#endif
-
 #ifdef CONFIG_DMABOUNCE
 /*
  * For SA-1111, IXP425, and ADI systems  the dma-mapping functions are "magic"
@@ -475,7 +205,8 @@
  * appropriate DMA pools for the device.
  *
  */
-extern int dmabounce_register_dev(struct device *, unsigned long, unsigned long);
+extern int dmabounce_register_dev(struct device *, unsigned long,
+		unsigned long);
 
 /**
  * dmabounce_unregister_dev
@@ -506,7 +237,184 @@
  *
  */
 extern int dma_needs_bounce(struct device*, dma_addr_t, size_t);
+
+/*
+ * The DMA API, implemented by dmabounce.c.  See below for descriptions.
+ */
+extern dma_addr_t dma_map_single(struct device *, void *, size_t,
+		enum dma_data_direction);
+extern dma_addr_t dma_map_page(struct device *, struct page *,
+		unsigned long, size_t, enum dma_data_direction);
+extern void dma_unmap_single(struct device *, dma_addr_t, size_t,
+		enum dma_data_direction);
+
+/*
+ * Private functions
+ */
+int dmabounce_sync_for_cpu(struct device *, dma_addr_t, unsigned long,
+		size_t, enum dma_data_direction);
+int dmabounce_sync_for_device(struct device *, dma_addr_t, unsigned long,
+		size_t, enum dma_data_direction);
+#else
+#define dmabounce_sync_for_cpu(dev,dma,off,sz,dir)	(1)
+#define dmabounce_sync_for_device(dev,dma,off,sz,dir)	(1)
+
+
+/**
+ * dma_map_single - map a single buffer for streaming DMA
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @cpu_addr: CPU direct mapped address of buffer
+ * @size: size of buffer to map
+ * @dir: DMA transfer direction
+ *
+ * Ensure that any data held in the cache is appropriately discarded
+ * or written back.
+ *
+ * The device owns this memory once this call has completed.  The CPU
+ * can regain ownership by calling dma_unmap_single() or
+ * dma_sync_single_for_cpu().
+ */
+static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
+		size_t size, enum dma_data_direction dir)
+{
+	BUG_ON(!valid_dma_direction(dir));
+
+	if (!arch_is_coherent())
+		dma_cache_maint(cpu_addr, size, dir);
+
+	return virt_to_dma(dev, cpu_addr);
+}
+
+/**
+ * dma_map_page - map a portion of a page for streaming DMA
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @page: page that buffer resides in
+ * @offset: offset into page for start of buffer
+ * @size: size of buffer to map
+ * @dir: DMA transfer direction
+ *
+ * Ensure that any data held in the cache is appropriately discarded
+ * or written back.
+ *
+ * The device owns this memory once this call has completed.  The CPU
+ * can regain ownership by calling dma_unmap_page().
+ */
+static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
+	     unsigned long offset, size_t size, enum dma_data_direction dir)
+{
+	BUG_ON(!valid_dma_direction(dir));
+
+	if (!arch_is_coherent())
+		dma_cache_maint(page_address(page) + offset, size, dir);
+
+	return page_to_dma(dev, page) + offset;
+}
+
+/**
+ * dma_unmap_single - unmap a single buffer previously mapped
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @handle: DMA address of buffer
+ * @size: size of buffer (same as passed to dma_map_single)
+ * @dir: DMA transfer direction (same as passed to dma_map_single)
+ *
+ * Unmap a single streaming mode DMA translation.  The handle and size
+ * must match what was provided in the previous dma_map_single() call.
+ * All other usages are undefined.
+ *
+ * After this call, reads by the CPU to the buffer are guaranteed to see
+ * whatever the device wrote there.
+ */
+static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
+		size_t size, enum dma_data_direction dir)
+{
+	/* nothing to do */
+}
 #endif /* CONFIG_DMABOUNCE */
 
+/**
+ * dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @handle: DMA address of buffer
+ * @size: size of buffer (same as passed to dma_map_page)
+ * @dir: DMA transfer direction (same as passed to dma_map_page)
+ *
+ * Unmap a page streaming mode DMA translation.  The handle and size
+ * must match what was provided in the previous dma_map_page() call.
+ * All other usages are undefined.
+ *
+ * After this call, reads by the CPU to the buffer are guaranteed to see
+ * whatever the device wrote there.
+ */
+static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
+		size_t size, enum dma_data_direction dir)
+{
+	dma_unmap_single(dev, handle, size, dir);
+}
+
+/**
+ * dma_sync_single_range_for_cpu
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @handle: DMA address of buffer
+ * @offset: offset of region to start sync
+ * @size: size of region to sync
+ * @dir: DMA transfer direction (same as passed to dma_map_single)
+ *
+ * Make physical memory consistent for a single streaming mode DMA
+ * translation after a transfer.
+ *
+ * If you perform a dma_map_single() but wish to interrogate the
+ * buffer using the cpu, yet do not wish to teardown the PCI dma
+ * mapping, you must call this function before doing so.  At the
+ * next point you give the PCI dma address back to the card, you
+ * must first the perform a dma_sync_for_device, and then the
+ * device again owns the buffer.
+ */
+static inline void dma_sync_single_range_for_cpu(struct device *dev,
+		dma_addr_t handle, unsigned long offset, size_t size,
+		enum dma_data_direction dir)
+{
+	BUG_ON(!valid_dma_direction(dir));
+
+	dmabounce_sync_for_cpu(dev, handle, offset, size, dir);
+}
+
+static inline void dma_sync_single_range_for_device(struct device *dev,
+		dma_addr_t handle, unsigned long offset, size_t size,
+		enum dma_data_direction dir)
+{
+	BUG_ON(!valid_dma_direction(dir));
+
+	if (!dmabounce_sync_for_device(dev, handle, offset, size, dir))
+		return;
+
+	if (!arch_is_coherent())
+		dma_cache_maint(dma_to_virt(dev, handle) + offset, size, dir);
+}
+
+static inline void dma_sync_single_for_cpu(struct device *dev,
+		dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+	dma_sync_single_range_for_cpu(dev, handle, 0, size, dir);
+}
+
+static inline void dma_sync_single_for_device(struct device *dev,
+		dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+	dma_sync_single_range_for_device(dev, handle, 0, size, dir);
+}
+
+/*
+ * The scatter list versions of the above methods.
+ */
+extern int dma_map_sg(struct device *, struct scatterlist *, int,
+		enum dma_data_direction);
+extern void dma_unmap_sg(struct device *, struct scatterlist *, int,
+		enum dma_data_direction);
+extern void dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int,
+		enum dma_data_direction);
+extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
+		enum dma_data_direction);
+
+
 #endif /* __KERNEL__ */
 #endif
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index 4ca7516..5be0169 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -3,7 +3,6 @@
 
 #include <asm/hwcap.h>
 
-#ifndef __ASSEMBLY__
 /*
  * ELF register definitions..
  */
@@ -17,12 +16,34 @@
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 
 typedef struct user_fp elf_fpregset_t;
-#endif
 
 #define EM_ARM	40
-#define EF_ARM_APCS26 0x08
-#define EF_ARM_SOFT_FLOAT 0x200
-#define EF_ARM_EABI_MASK 0xFF000000
+
+#define EF_ARM_EABI_MASK	0xff000000
+#define EF_ARM_EABI_UNKNOWN	0x00000000
+#define EF_ARM_EABI_VER1	0x01000000
+#define EF_ARM_EABI_VER2	0x02000000
+#define EF_ARM_EABI_VER3	0x03000000
+#define EF_ARM_EABI_VER4	0x04000000
+#define EF_ARM_EABI_VER5	0x05000000
+
+#define EF_ARM_BE8		0x00800000	/* ABI 4,5 */
+#define EF_ARM_LE8		0x00400000	/* ABI 4,5 */
+#define EF_ARM_MAVERICK_FLOAT	0x00000800	/* ABI 0 */
+#define EF_ARM_VFP_FLOAT	0x00000400	/* ABI 0 */
+#define EF_ARM_SOFT_FLOAT	0x00000200	/* ABI 0 */
+#define EF_ARM_OLD_ABI		0x00000100	/* ABI 0 */
+#define EF_ARM_NEW_ABI		0x00000080	/* ABI 0 */
+#define EF_ARM_ALIGN8		0x00000040	/* ABI 0 */
+#define EF_ARM_PIC		0x00000020	/* ABI 0 */
+#define EF_ARM_MAPSYMSFIRST	0x00000010	/* ABI 2 */
+#define EF_ARM_APCS_FLOAT	0x00000010	/* ABI 0, floats in fp regs */
+#define EF_ARM_DYNSYMSUSESEGIDX	0x00000008	/* ABI 2 */
+#define EF_ARM_APCS_26		0x00000008	/* ABI 0 */
+#define EF_ARM_SYMSARESORTED	0x00000004	/* ABI 1,2 */
+#define EF_ARM_INTERWORK	0x00000004	/* ABI 0 */
+#define EF_ARM_HASENTRY		0x00000002	/* All */
+#define EF_ARM_RELEXEC		0x00000001	/* All */
 
 #define R_ARM_NONE	0
 #define R_ARM_PC24	1
@@ -41,7 +62,6 @@
 #endif
 #define ELF_ARCH	EM_ARM
 
-#ifndef __ASSEMBLY__
 /*
  * This yields a string that ld.so will use to load implementation
  * specific libraries for optimization.  This is more specific in
@@ -59,25 +79,17 @@
 #define ELF_PLATFORM	(elf_platform)
 
 extern char elf_platform[];
-#endif
+
+struct elf32_hdr;
 
 /*
  * This is used to ensure we don't load something for the wrong architecture.
  */
-#define elf_check_arch(x) ((x)->e_machine == EM_ARM && ELF_PROC_OK(x))
+extern int elf_check_arch(const struct elf32_hdr *);
+#define elf_check_arch elf_check_arch
 
-/*
- * 32-bit code is always OK.  Some cpus can do 26-bit, some can't.
- */
-#define ELF_PROC_OK(x)	(ELF_THUMB_OK(x) && ELF_26BIT_OK(x))
-
-#define ELF_THUMB_OK(x) \
-	((elf_hwcap & HWCAP_THUMB && ((x)->e_entry & 1) == 1) || \
-	 ((x)->e_entry & 3) == 0)
-
-#define ELF_26BIT_OK(x) \
-	((elf_hwcap & HWCAP_26BIT && (x)->e_flags & EF_ARM_APCS26) || \
-	  ((x)->e_flags & EF_ARM_APCS26) == 0)
+extern int arm_elf_read_implies_exec(const struct elf32_hdr *, int);
+#define elf_read_implies_exec(ex,stk) arm_elf_read_implies_exec(&(ex), stk)
 
 #define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE	4096
@@ -94,23 +106,7 @@
    have no such handler.  */
 #define ELF_PLAT_INIT(_r, load_addr)	(_r)->ARM_r0 = 0
 
-/*
- * Since the FPA coprocessor uses CP1 and CP2, and iWMMXt uses CP0
- * and CP1, we only enable access to the iWMMXt coprocessor if the
- * binary is EABI or softfloat (and thus, guaranteed not to use
- * FPA instructions.)
- */
-#define SET_PERSONALITY(ex, ibcs2)					\
-	do {								\
-		if ((ex).e_flags & EF_ARM_APCS26) {			\
-			set_personality(PER_LINUX);			\
-		} else {						\
-			set_personality(PER_LINUX_32BIT);		\
-			if (elf_hwcap & HWCAP_IWMMXT && (ex).e_flags & (EF_ARM_EABI_MASK | EF_ARM_SOFT_FLOAT)) \
-				set_thread_flag(TIF_USING_IWMMXT);	\
-			else						\
-				clear_thread_flag(TIF_USING_IWMMXT);	\
-		}							\
-	} while (0)
+extern void elf_set_personality(const struct elf32_hdr *);
+#define SET_PERSONALITY(ex, ibcs2)	elf_set_personality(&(ex))
 
 #endif
diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h
index 6a332a9..9ee743b 100644
--- a/arch/arm/include/asm/futex.h
+++ b/arch/arm/include/asm/futex.h
@@ -1,6 +1,124 @@
-#ifndef _ASM_FUTEX_H
-#define _ASM_FUTEX_H
+#ifndef _ASM_ARM_FUTEX_H
+#define _ASM_ARM_FUTEX_H
+
+#ifdef __KERNEL__
+
+#ifdef CONFIG_SMP
 
 #include <asm-generic/futex.h>
 
-#endif
+#else /* !SMP, we can work around lack of atomic ops by disabling preemption */
+
+#include <linux/futex.h>
+#include <linux/preempt.h>
+#include <linux/uaccess.h>
+#include <asm/errno.h>
+
+#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)	\
+	__asm__ __volatile__(					\
+	"1:	ldrt	%1, [%2]\n"				\
+	"	" insn "\n"					\
+	"2:	strt	%0, [%2]\n"				\
+	"	mov	%0, #0\n"				\
+	"3:\n"							\
+	"	.section __ex_table,\"a\"\n"			\
+	"	.align	3\n"					\
+	"	.long	1b, 4f, 2b, 4f\n"			\
+	"	.previous\n"					\
+	"	.section .fixup,\"ax\"\n"			\
+	"4:	mov	%0, %4\n"				\
+	"	b	3b\n"					\
+	"	.previous"					\
+	: "=&r" (ret), "=&r" (oldval)				\
+	: "r" (uaddr), "r" (oparg), "Ir" (-EFAULT)		\
+	: "cc", "memory")
+
+static inline int
+futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
+{
+	int op = (encoded_op >> 28) & 7;
+	int cmp = (encoded_op >> 24) & 15;
+	int oparg = (encoded_op << 8) >> 20;
+	int cmparg = (encoded_op << 20) >> 20;
+	int oldval = 0, ret;
+
+	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
+		oparg = 1 << oparg;
+
+	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
+		return -EFAULT;
+
+	pagefault_disable();	/* implies preempt_disable() */
+
+	switch (op) {
+	case FUTEX_OP_SET:
+		__futex_atomic_op("mov	%0, %3", ret, oldval, uaddr, oparg);
+		break;
+	case FUTEX_OP_ADD:
+		__futex_atomic_op("add	%0, %1, %3", ret, oldval, uaddr, oparg);
+		break;
+	case FUTEX_OP_OR:
+		__futex_atomic_op("orr	%0, %1, %3", ret, oldval, uaddr, oparg);
+		break;
+	case FUTEX_OP_ANDN:
+		__futex_atomic_op("and	%0, %1, %3", ret, oldval, uaddr, ~oparg);
+		break;
+	case FUTEX_OP_XOR:
+		__futex_atomic_op("eor	%0, %1, %3", ret, oldval, uaddr, oparg);
+		break;
+	default:
+		ret = -ENOSYS;
+	}
+
+	pagefault_enable();	/* subsumes preempt_enable() */
+
+	if (!ret) {
+		switch (cmp) {
+		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
+		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
+		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
+		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
+		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
+		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
+		default: ret = -ENOSYS;
+		}
+	}
+	return ret;
+}
+
+static inline int
+futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
+{
+	int val;
+
+	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
+		return -EFAULT;
+
+	pagefault_disable();	/* implies preempt_disable() */
+
+	__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
+	"1:	ldrt	%0, [%3]\n"
+	"	teq	%0, %1\n"
+	"2:	streqt	%2, [%3]\n"
+	"3:\n"
+	"	.section __ex_table,\"a\"\n"
+	"	.align	3\n"
+	"	.long	1b, 4f, 2b, 4f\n"
+	"	.previous\n"
+	"	.section .fixup,\"ax\"\n"
+	"4:	mov	%0, %4\n"
+	"	b	3b\n"
+	"	.previous"
+	: "=&r" (val)
+	: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
+	: "cc", "memory");
+
+	pagefault_enable();	/* subsumes preempt_enable() */
+
+	return val;
+}
+
+#endif /* !SMP */
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_ARM_FUTEX_H */
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 94a95d7..a809445 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -60,7 +60,7 @@
 #define MT_DEVICE		0
 #define MT_DEVICE_NONSHARED	1
 #define MT_DEVICE_CACHED	2
-#define MT_DEVICE_IXP2000	3
+#define MT_DEVICE_WC		3
 /*
  * types 4 onwards can be found in asm/mach/map.h and are undefined
  * for ioremap
@@ -215,11 +215,13 @@
 #define ioremap(cookie,size)		__arm_ioremap(cookie, size, MT_DEVICE)
 #define ioremap_nocache(cookie,size)	__arm_ioremap(cookie, size, MT_DEVICE)
 #define ioremap_cached(cookie,size)	__arm_ioremap(cookie, size, MT_DEVICE_CACHED)
+#define ioremap_wc(cookie,size)		__arm_ioremap(cookie, size, MT_DEVICE_WC)
 #define iounmap(cookie)			__iounmap(cookie)
 #else
 #define ioremap(cookie,size)		__arch_ioremap((cookie), (size), MT_DEVICE)
 #define ioremap_nocache(cookie,size)	__arch_ioremap((cookie), (size), MT_DEVICE)
 #define ioremap_cached(cookie,size)	__arch_ioremap((cookie), (size), MT_DEVICE_CACHED)
+#define ioremap_wc(cookie,size)		__arch_ioremap((cookie), (size), MT_DEVICE_WC)
 #define iounmap(cookie)			__arch_iounmap(cookie)
 #endif
 
diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h
index d678609..a0009aa 100644
--- a/arch/arm/include/asm/irq.h
+++ b/arch/arm/include/asm/irq.h
@@ -22,6 +22,10 @@
 #ifndef __ASSEMBLY__
 struct irqaction;
 extern void migrate_irqs(void);
+
+extern void asm_do_IRQ(unsigned int, struct pt_regs *);
+void init_IRQ(void);
+
 #endif
 
 #endif
diff --git a/arch/arm/include/asm/kprobes.h b/arch/arm/include/asm/kprobes.h
index a5d0d99..bb8a19b 100644
--- a/arch/arm/include/asm/kprobes.h
+++ b/arch/arm/include/asm/kprobes.h
@@ -61,7 +61,6 @@
 void arch_remove_kprobe(struct kprobe *);
 void kretprobe_trampoline(void);
 
-int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr);
 int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
 int kprobe_exceptions_notify(struct notifier_block *self,
 			     unsigned long val, void *data);
diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h
index 06f583b..cb1139a 100644
--- a/arch/arm/include/asm/mach/map.h
+++ b/arch/arm/include/asm/mach/map.h
@@ -26,9 +26,6 @@
 #define MT_MEMORY		8
 #define MT_ROM			9
 
-#define MT_NONSHARED_DEVICE	MT_DEVICE_NONSHARED
-#define MT_IXP2000_DEVICE	MT_DEVICE_IXP2000
-
 #ifdef CONFIG_MMU
 extern void iotable_init(struct map_desc *, int);
 #else
diff --git a/arch/arm/include/asm/mach/udc_pxa2xx.h b/arch/arm/include/asm/mach/udc_pxa2xx.h
index 270902c..f3eabf1 100644
--- a/arch/arm/include/asm/mach/udc_pxa2xx.h
+++ b/arch/arm/include/asm/mach/udc_pxa2xx.h
@@ -18,8 +18,7 @@
 	/* Boards following the design guidelines in the developer's manual,
 	 * with on-chip GPIOs not Lubbock's weird hardware, can have a sane
 	 * VBUS IRQ and omit the methods above.  Store the GPIO number
-	 * here; for GPIO 0, also mask in one of the pxa_gpio_mode() bits.
-	 * Note that sometimes the signals go through inverters...
+	 * here.  Note that sometimes the signals go through inverters...
 	 */
 	bool	gpio_vbus_inverted;
 	u16	gpio_vbus;			/* high == vbus present */
diff --git a/arch/arm/include/asm/mc146818rtc.h b/arch/arm/include/asm/mc146818rtc.h
index e1ca48a..6b884d2 100644
--- a/arch/arm/include/asm/mc146818rtc.h
+++ b/arch/arm/include/asm/mc146818rtc.h
@@ -4,8 +4,8 @@
 #ifndef _ASM_MC146818RTC_H
 #define _ASM_MC146818RTC_H
 
+#include <linux/io.h>
 #include <mach/irqs.h>
-#include <asm/io.h>
 
 #ifndef RTC_PORT
 #define RTC_PORT(x)	(0x70 + (x))
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index bf7c737..809ff9a 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -13,30 +13,27 @@
 #ifndef __ASM_ARM_MEMORY_H
 #define __ASM_ARM_MEMORY_H
 
+#include <linux/compiler.h>
+#include <linux/const.h>
+#include <mach/memory.h>
+#include <asm/sizes.h>
+
 /*
  * Allow for constants defined here to be used from assembly code
  * by prepending the UL suffix only with actual C code compilation.
  */
-#ifndef __ASSEMBLY__
-#define UL(x) (x##UL)
-#else
-#define UL(x) (x)
-#endif
-
-#include <linux/compiler.h>
-#include <mach/memory.h>
-#include <asm/sizes.h>
+#define UL(x) _AC(x, UL)
 
 #ifdef CONFIG_MMU
 
-#ifndef TASK_SIZE
 /*
+ * PAGE_OFFSET - the virtual address of the start of the kernel image
  * TASK_SIZE - the maximum size of a user space task.
  * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area
  */
-#define TASK_SIZE		UL(0xbf000000)
-#define TASK_UNMAPPED_BASE	UL(0x40000000)
-#endif
+#define PAGE_OFFSET		UL(CONFIG_PAGE_OFFSET)
+#define TASK_SIZE		(UL(CONFIG_PAGE_OFFSET) - UL(0x01000000))
+#define TASK_UNMAPPED_BASE	(UL(CONFIG_PAGE_OFFSET) / 3)
 
 /*
  * The maximum size of a 26-bit user space task.
@@ -44,13 +41,6 @@
 #define TASK_SIZE_26		UL(0x04000000)
 
 /*
- * Page offset: 3GB
- */
-#ifndef PAGE_OFFSET
-#define PAGE_OFFSET		UL(0xc0000000)
-#endif
-
-/*
  * The module space lives between the addresses given by TASK_SIZE
  * and PAGE_OFFSET - it must be within 32MB of the kernel text.
  */
@@ -147,17 +137,11 @@
 
 #ifndef arch_adjust_zones
 #define arch_adjust_zones(node,size,holes) do { } while (0)
+#elif !defined(CONFIG_ZONE_DMA)
+#error "custom arch_adjust_zones() requires CONFIG_ZONE_DMA"
 #endif
 
 /*
- * Amount of memory reserved for the vmalloc() area, and minimum
- * address for vmalloc mappings.
- */
-extern unsigned long vmalloc_reserve;
-
-#define VMALLOC_MIN		(void *)(VMALLOC_END - vmalloc_reserve)
-
-/*
  * PFNs are used to describe any physical page; this means
  * PFN 0 == physical address 0.
  *
diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h
index a301e44..0559f37 100644
--- a/arch/arm/include/asm/mmu_context.h
+++ b/arch/arm/include/asm/mmu_context.h
@@ -15,6 +15,7 @@
 
 #include <linux/compiler.h>
 #include <asm/cacheflush.h>
+#include <asm/cachetype.h>
 #include <asm/proc-fns.h>
 #include <asm-generic/mm_hooks.h>
 
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index cf2e268..bed1c0a 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -184,8 +184,9 @@
 
 #endif /* !__ASSEMBLY__ */
 
-#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
-				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+#define VM_DATA_DEFAULT_FLAGS \
+	(((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
+	 VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
 /*
  * With EABI on ARMv5 and above we must have 64-bit aligned slab pointers.
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
index 721c03d..918d0cb 100644
--- a/arch/arm/include/asm/pci.h
+++ b/arch/arm/include/asm/pci.h
@@ -30,7 +30,7 @@
  * The networking and block device layers use this boolean for bounce
  * buffer decisions.
  */
-#define PCI_DMA_BUS_IS_PHYS     (0)
+#define PCI_DMA_BUS_IS_PHYS     (1)
 
 /*
  * Whether pci_unmap_{single,page} is a nop depends upon the
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 8e21ef1..110295c 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -164,14 +164,30 @@
 #define L_PTE_PRESENT		(1 << 0)
 #define L_PTE_FILE		(1 << 1)	/* only when !PRESENT */
 #define L_PTE_YOUNG		(1 << 1)
-#define L_PTE_BUFFERABLE	(1 << 2)	/* matches PTE */
-#define L_PTE_CACHEABLE		(1 << 3)	/* matches PTE */
-#define L_PTE_USER		(1 << 4)
-#define L_PTE_WRITE		(1 << 5)
-#define L_PTE_EXEC		(1 << 6)
-#define L_PTE_DIRTY		(1 << 7)
+#define L_PTE_BUFFERABLE	(1 << 2)	/* obsolete, matches PTE */
+#define L_PTE_CACHEABLE		(1 << 3)	/* obsolete, matches PTE */
+#define L_PTE_DIRTY		(1 << 6)
+#define L_PTE_WRITE		(1 << 7)
+#define L_PTE_USER		(1 << 8)
+#define L_PTE_EXEC		(1 << 9)
 #define L_PTE_SHARED		(1 << 10)	/* shared(v6), coherent(xsc3) */
 
+/*
+ * These are the memory types, defined to be compatible with
+ * pre-ARMv6 CPUs cacheable and bufferable bits:   XXCB
+ */
+#define L_PTE_MT_UNCACHED	(0x00 << 2)	/* 0000 */
+#define L_PTE_MT_BUFFERABLE	(0x01 << 2)	/* 0001 */
+#define L_PTE_MT_WRITETHROUGH	(0x02 << 2)	/* 0010 */
+#define L_PTE_MT_WRITEBACK	(0x03 << 2)	/* 0011 */
+#define L_PTE_MT_MINICACHE	(0x06 << 2)	/* 0110 (sa1100, xscale) */
+#define L_PTE_MT_WRITEALLOC	(0x07 << 2)	/* 0111 */
+#define L_PTE_MT_DEV_SHARED	(0x04 << 2)	/* 0100 */
+#define L_PTE_MT_DEV_NONSHARED	(0x0c << 2)	/* 1100 */
+#define L_PTE_MT_DEV_WC		(0x09 << 2)	/* 1001 */
+#define L_PTE_MT_DEV_CACHED	(0x0b << 2)	/* 1011 */
+#define L_PTE_MT_MASK		(0x0f << 2)
+
 #ifndef __ASSEMBLY__
 
 /*
@@ -180,23 +196,30 @@
  * as well as any architecture dependent bits like global/ASID and SMP
  * shared mapping bits.
  */
-#define _L_PTE_DEFAULT	L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_CACHEABLE | L_PTE_BUFFERABLE
-#define _L_PTE_READ	L_PTE_USER | L_PTE_EXEC
+#define _L_PTE_DEFAULT	L_PTE_PRESENT | L_PTE_YOUNG
 
 extern pgprot_t		pgprot_user;
 extern pgprot_t		pgprot_kernel;
 
-#define PAGE_NONE	pgprot_user
-#define PAGE_COPY	__pgprot(pgprot_val(pgprot_user) | _L_PTE_READ)
-#define PAGE_SHARED	__pgprot(pgprot_val(pgprot_user) | _L_PTE_READ | \
-				 L_PTE_WRITE)
-#define PAGE_READONLY	__pgprot(pgprot_val(pgprot_user) | _L_PTE_READ)
-#define PAGE_KERNEL	pgprot_kernel
+#define _MOD_PROT(p, b)	__pgprot(pgprot_val(p) | (b))
 
-#define __PAGE_NONE	__pgprot(_L_PTE_DEFAULT)
-#define __PAGE_COPY	__pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
-#define __PAGE_SHARED	__pgprot(_L_PTE_DEFAULT | _L_PTE_READ | L_PTE_WRITE)
-#define __PAGE_READONLY	__pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
+#define PAGE_NONE		pgprot_user
+#define PAGE_SHARED		_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE)
+#define PAGE_SHARED_EXEC	_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE | L_PTE_EXEC)
+#define PAGE_COPY		_MOD_PROT(pgprot_user, L_PTE_USER)
+#define PAGE_COPY_EXEC		_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_EXEC)
+#define PAGE_READONLY		_MOD_PROT(pgprot_user, L_PTE_USER)
+#define PAGE_READONLY_EXEC	_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_EXEC)
+#define PAGE_KERNEL		pgprot_kernel
+#define PAGE_KERNEL_EXEC	_MOD_PROT(pgprot_kernel, L_PTE_EXEC)
+
+#define __PAGE_NONE		__pgprot(_L_PTE_DEFAULT)
+#define __PAGE_SHARED		__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE)
+#define __PAGE_SHARED_EXEC	__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE | L_PTE_EXEC)
+#define __PAGE_COPY		__pgprot(_L_PTE_DEFAULT | L_PTE_USER)
+#define __PAGE_COPY_EXEC	__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_EXEC)
+#define __PAGE_READONLY		__pgprot(_L_PTE_DEFAULT | L_PTE_USER)
+#define __PAGE_READONLY_EXEC	__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_EXEC)
 
 #endif /* __ASSEMBLY__ */
 
@@ -212,19 +235,19 @@
 #define __P001  __PAGE_READONLY
 #define __P010  __PAGE_COPY
 #define __P011  __PAGE_COPY
-#define __P100  __PAGE_READONLY
-#define __P101  __PAGE_READONLY
-#define __P110  __PAGE_COPY
-#define __P111  __PAGE_COPY
+#define __P100  __PAGE_READONLY_EXEC
+#define __P101  __PAGE_READONLY_EXEC
+#define __P110  __PAGE_COPY_EXEC
+#define __P111  __PAGE_COPY_EXEC
 
 #define __S000  __PAGE_NONE
 #define __S001  __PAGE_READONLY
 #define __S010  __PAGE_SHARED
 #define __S011  __PAGE_SHARED
-#define __S100  __PAGE_READONLY
-#define __S101  __PAGE_READONLY
-#define __S110  __PAGE_SHARED
-#define __S111  __PAGE_SHARED
+#define __S100  __PAGE_READONLY_EXEC
+#define __S101  __PAGE_READONLY_EXEC
+#define __S110  __PAGE_SHARED_EXEC
+#define __S111  __PAGE_SHARED_EXEC
 
 #ifndef __ASSEMBLY__
 /*
@@ -286,8 +309,10 @@
 /*
  * Mark the prot value as uncacheable and unbufferable.
  */
-#define pgprot_noncached(prot)	__pgprot(pgprot_val(prot) & ~(L_PTE_CACHEABLE | L_PTE_BUFFERABLE))
-#define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~L_PTE_CACHEABLE)
+#define pgprot_noncached(prot) \
+	__pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_UNCACHED)
+#define pgprot_writecombine(prot) \
+	__pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_BUFFERABLE)
 
 #define pmd_none(pmd)		(!pmd_val(pmd))
 #define pmd_present(pmd)	(pmd_val(pmd))
@@ -320,11 +345,6 @@
 #define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd)))
 
 /*
- * Permanent address of a page. We never have highmem, so this is trivial.
- */
-#define pages_to_mb(x)		((x) >> (20 - PAGE_SHIFT))
-
-/*
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
  */
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index b415c0e..7319261 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -54,7 +54,6 @@
 #define PSR_C_BIT	0x20000000
 #define PSR_Z_BIT	0x40000000
 #define PSR_N_BIT	0x80000000
-#define PCMASK		0
 
 /*
  * Groups of PSR bits
@@ -139,11 +138,7 @@
 	return 0;
 }
 
-#define pc_pointer(v) \
-	((v) & ~PCMASK)
-
-#define instruction_pointer(regs) \
-	(pc_pointer((regs)->ARM_pc))
+#define instruction_pointer(regs)	(regs)->ARM_pc
 
 #ifdef CONFIG_SMP
 extern unsigned long profile_pc(struct pt_regs *regs);
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index 7bbf105..a65413b 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -209,6 +209,17 @@
 	struct membank bank[NR_BANKS];
 };
 
+#define for_each_nodebank(iter,mi,no)			\
+	for (iter = 0; iter < mi->nr_banks; iter++)	\
+		if (mi->bank[iter].node == no)
+
+#define bank_pfn_start(bank)	__phys_to_pfn((bank)->start)
+#define bank_pfn_end(bank)	__phys_to_pfn((bank)->start + (bank)->size)
+#define bank_pfn_size(bank)	((bank)->size >> PAGE_SHIFT)
+#define bank_phys_start(bank)	(bank)->start
+#define bank_phys_end(bank)	((bank)->start + (bank)->size)
+#define bank_phys_size(bank)	(bank)->size
+
 /*
  * Early command line parameters.
  */
diff --git a/arch/arm/include/asm/sparsemem.h b/arch/arm/include/asm/sparsemem.h
index 2771581..0009861 100644
--- a/arch/arm/include/asm/sparsemem.h
+++ b/arch/arm/include/asm/sparsemem.h
@@ -3,8 +3,22 @@
 
 #include <asm/memory.h>
 
-#define MAX_PHYSADDR_BITS	32
-#define MAX_PHYSMEM_BITS	32
-#define SECTION_SIZE_BITS	NODE_MEM_SIZE_BITS
+/*
+ * Two definitions are required for sparsemem:
+ *
+ * MAX_PHYSMEM_BITS: The number of physical address bits required
+ *   to address the last byte of memory.
+ *
+ * SECTION_SIZE_BITS: The number of physical address bits to cover
+ *   the maximum amount of memory in a section.
+ *
+ * Eg, if you have 2 banks of up to 64MB at 0x80000000, 0x84000000,
+ * then MAX_PHYSMEM_BITS is 32, SECTION_SIZE_BITS is 26.
+ *
+ * Define these in your mach/memory.h.
+ */
+#if !defined(SECTION_SIZE_BITS) || !defined(MAX_PHYSMEM_BITS)
+#error Sparsemem is not supported on this platform
+#endif
 
 #endif
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 514af79..7aad784 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -43,11 +43,6 @@
 #define CR_XP	(1 << 23)	/* Extended page tables			*/
 #define CR_VE	(1 << 24)	/* Vectored interrupts			*/
 
-#define CPUID_ID	0
-#define CPUID_CACHETYPE	1
-#define CPUID_TCM	2
-#define CPUID_TLBTYPE	3
-
 /*
  * This is used to ensure the compiler did actually allocate the register we
  * asked it for some inline assembly sequences.  Apparently we can't trust
@@ -61,36 +56,8 @@
 #ifndef __ASSEMBLY__
 
 #include <linux/linkage.h>
-#include <linux/stringify.h>
 #include <linux/irqflags.h>
 
-#ifdef CONFIG_CPU_CP15
-#define read_cpuid(reg)							\
-	({								\
-		unsigned int __val;					\
-		asm("mrc	p15, 0, %0, c0, c0, " __stringify(reg)	\
-		    : "=r" (__val)					\
-		    :							\
-		    : "cc");						\
-		__val;							\
-	})
-#else
-extern unsigned int processor_id;
-#define read_cpuid(reg) (processor_id)
-#endif
-
-/*
- * The CPU ID never changes at run time, so we might as well tell the
- * compiler that it's constant.  Use this function to read the CPU ID
- * rather than directly reading processor_id or read_cpuid() directly.
- */
-static inline unsigned int read_cpuid_id(void) __attribute_const__;
-
-static inline unsigned int read_cpuid_id(void)
-{
-	return read_cpuid(CPUID_ID);
-}
-
 #define __exception	__attribute__((section(".exception.text")))
 
 struct thread_info;
@@ -131,31 +98,6 @@
 void arm_machine_restart(char mode);
 extern void (*arm_pm_restart)(char str);
 
-/*
- * Intel's XScale3 core supports some v6 features (supersections, L2)
- * but advertises itself as v5 as it does not support the v6 ISA.  For
- * this reason, we need a way to explicitly test for this type of CPU.
- */
-#ifndef CONFIG_CPU_XSC3
-#define cpu_is_xsc3()	0
-#else
-static inline int cpu_is_xsc3(void)
-{
-	extern unsigned int processor_id;
-
-	if ((processor_id & 0xffffe000) == 0x69056000)
-		return 1;
-
-	return 0;
-}
-#endif
-
-#if !defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_CPU_XSC3)
-#define	cpu_is_xscale()	0
-#else
-#define	cpu_is_xscale()	1
-#endif
-
 #define UDBG_UNDEFINED	(1 << 0)
 #define UDBG_SYSCALL	(1 << 1)
 #define UDBG_BADABORT	(1 << 2)
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index e56fa48..68b9ec8 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -98,7 +98,7 @@
 }
 
 #define thread_saved_pc(tsk)	\
-	((unsigned long)(pc_pointer(task_thread_info(tsk)->cpu_context.pc)))
+	((unsigned long)(task_thread_info(tsk)->cpu_context.pc))
 #define thread_saved_fp(tsk)	\
 	((unsigned long)(task_thread_info(tsk)->cpu_context.fp))
 
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index d0f51ff..e98ec60 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -225,7 +225,7 @@
 
 #define __get_user_asm_byte(x,addr,err)				\
 	__asm__ __volatile__(					\
-	"1:	ldrbt	%1,[%2],#0\n"				\
+	"1:	ldrbt	%1,[%2]\n"				\
 	"2:\n"							\
 	"	.section .fixup,\"ax\"\n"			\
 	"	.align	2\n"					\
@@ -261,7 +261,7 @@
 
 #define __get_user_asm_word(x,addr,err)				\
 	__asm__ __volatile__(					\
-	"1:	ldrt	%1,[%2],#0\n"				\
+	"1:	ldrt	%1,[%2]\n"				\
 	"2:\n"							\
 	"	.section .fixup,\"ax\"\n"			\
 	"	.align	2\n"					\
@@ -306,7 +306,7 @@
 
 #define __put_user_asm_byte(x,__pu_addr,err)			\
 	__asm__ __volatile__(					\
-	"1:	strbt	%1,[%2],#0\n"				\
+	"1:	strbt	%1,[%2]\n"				\
 	"2:\n"							\
 	"	.section .fixup,\"ax\"\n"			\
 	"	.align	2\n"					\
@@ -339,7 +339,7 @@
 
 #define __put_user_asm_word(x,__pu_addr,err)			\
 	__asm__ __volatile__(					\
-	"1:	strt	%1,[%2],#0\n"				\
+	"1:	strt	%1,[%2]\n"				\
 	"2:\n"							\
 	"	.section .fixup,\"ax\"\n"			\
 	"	.align	2\n"					\
@@ -365,7 +365,7 @@
 #define __put_user_asm_dword(x,__pu_addr,err)			\
 	__asm__ __volatile__(					\
 	"1:	strt	" __reg_oper1 ", [%1], #4\n"		\
-	"2:	strt	" __reg_oper0 ", [%1], #0\n"		\
+	"2:	strt	" __reg_oper0 ", [%1]\n"		\
 	"3:\n"							\
 	"	.section .fixup,\"ax\"\n"			\
 	"	.align	2\n"					\
diff --git a/arch/arm/include/asm/vga.h b/arch/arm/include/asm/vga.h
index 6a3cd2a2..250a4dd 100644
--- a/arch/arm/include/asm/vga.h
+++ b/arch/arm/include/asm/vga.h
@@ -1,8 +1,8 @@
 #ifndef ASMARM_VGA_H
 #define ASMARM_VGA_H
 
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 
 #define VGA_MAP_MEM(x,s)	(PCIMEM_BASE + (x))
 
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 1d296fc..4305345 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -10,7 +10,7 @@
 
 # Object file lists.
 
-obj-y		:= compat.o entry-armv.o entry-common.o irq.o \
+obj-y		:= compat.o elf.o entry-armv.o entry-common.o irq.o \
 		   process.o ptrace.o setup.o signal.o \
 		   sys_arm.o stacktrace.o time.o traps.o
 
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index cc7b246..2357b1c 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -13,11 +13,11 @@
 #include <linux/delay.h>
 #include <linux/in6.h>
 #include <linux/syscalls.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
 
 #include <asm/checksum.h>
-#include <asm/io.h>
 #include <asm/system.h>
-#include <asm/uaccess.h>
 #include <asm/ftrace.h>
 
 /*
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index e574754..17a59b6 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -10,8 +10,8 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/mach-types.h>
 #include <asm/mach/pci.h>
 
diff --git a/arch/arm/kernel/crunch.c b/arch/arm/kernel/crunch.c
index 3b6a1c2..99995c2 100644
--- a/arch/arm/kernel/crunch.c
+++ b/arch/arm/kernel/crunch.c
@@ -15,9 +15,9 @@
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/init.h>
+#include <linux/io.h>
 #include <mach/ep93xx-regs.h>
 #include <asm/thread_notify.h>
-#include <asm/io.h>
 
 struct crunch_state *crunch_owner;
 
diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S
index 9550ff0..f53c582 100644
--- a/arch/arm/kernel/debug.S
+++ b/arch/arm/kernel/debug.S
@@ -89,10 +89,12 @@
 ENTRY(printhex8)
 		mov	r1, #8
 		b	printhex
+ENDPROC(printhex8)
 
 ENTRY(printhex4)
 		mov	r1, #4
 		b	printhex
+ENDPROC(printhex4)
 
 ENTRY(printhex2)
 		mov	r1, #2
@@ -110,6 +112,7 @@
 		bne	1b
 		mov	r0, r2
 		b	printascii
+ENDPROC(printhex2)
 
 		.ltorg
 
@@ -127,11 +130,13 @@
 		teqne	r1, #0
 		bne	1b
 		mov	pc, lr
+ENDPROC(printascii)
 
 ENTRY(printch)
 		addruart r3
 		mov	r1, r0
 		mov	r0, #0
 		b	1b
+ENDPROC(printch)
 
 hexbuf:		.space 16
diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c
index 2f080a3..4a3a504 100644
--- a/arch/arm/kernel/dma-isa.c
+++ b/arch/arm/kernel/dma-isa.c
@@ -19,10 +19,9 @@
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
+#include <linux/io.h>
 
 #include <asm/dma.h>
-#include <asm/io.h>
-
 #include <asm/mach/dma.h>
 
 #define ISA_DMA_MODE_READ	0x44
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index 7a50575..60c079d 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -587,8 +587,7 @@
 			pending = ecard_default_ops.irqpending(ec);
 
 		if (pending) {
-			struct irq_desc *d = irq_desc + ec->irq;
-			desc_handle_irq(ec->irq, d);
+			generic_handle_irq(ec->irq);
 			called ++;
 		}
 	}
@@ -622,7 +621,6 @@
 		ecard_t *ec = slot_to_ecard(slot);
 
 		if (ec->claimed) {
-			struct irq_desc *d = irq_desc + ec->irq;
 			/*
 			 * this ugly code is so that we can operate a
 			 * prioritorising system:
@@ -635,7 +633,7 @@
 			 * Serial cards should go in 0/1, ethernet/scsi in 2/3
 			 * otherwise you will lose serial data at high speeds!
 			 */
-			desc_handle_irq(ec->irq, d);
+			generic_handle_irq(ec->irq);
 		} else {
 			printk(KERN_WARNING "card%d: interrupt from unclaimed "
 			       "card???\n", slot);
diff --git a/arch/arm/kernel/elf.c b/arch/arm/kernel/elf.c
new file mode 100644
index 0000000..513f332
--- /dev/null
+++ b/arch/arm/kernel/elf.c
@@ -0,0 +1,79 @@
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/personality.h>
+#include <linux/binfmts.h>
+#include <linux/elf.h>
+
+int elf_check_arch(const struct elf32_hdr *x)
+{
+	unsigned int eflags;
+
+	/* Make sure it's an ARM executable */
+	if (x->e_machine != EM_ARM)
+		return 0;
+
+	/* Make sure the entry address is reasonable */
+	if (x->e_entry & 1) {
+		if (!(elf_hwcap & HWCAP_THUMB))
+			return 0;
+	} else if (x->e_entry & 3)
+		return 0;
+
+	eflags = x->e_flags;
+	if ((eflags & EF_ARM_EABI_MASK) == EF_ARM_EABI_UNKNOWN) {
+		/* APCS26 is only allowed if the CPU supports it */
+		if ((eflags & EF_ARM_APCS_26) && !(elf_hwcap & HWCAP_26BIT))
+			return 0;
+
+		/* VFP requires the supporting code */
+		if ((eflags & EF_ARM_VFP_FLOAT) && !(elf_hwcap & HWCAP_VFP))
+			return 0;
+	}
+	return 1;
+}
+EXPORT_SYMBOL(elf_check_arch);
+
+void elf_set_personality(const struct elf32_hdr *x)
+{
+	unsigned int eflags = x->e_flags;
+	unsigned int personality = PER_LINUX_32BIT;
+
+	/*
+	 * APCS-26 is only valid for OABI executables
+	 */
+	if ((eflags & EF_ARM_EABI_MASK) == EF_ARM_EABI_UNKNOWN) {
+		if (eflags & EF_ARM_APCS_26)
+			personality = PER_LINUX;
+	}
+
+	set_personality(personality);
+
+	/*
+	 * Since the FPA coprocessor uses CP1 and CP2, and iWMMXt uses CP0
+	 * and CP1, we only enable access to the iWMMXt coprocessor if the
+	 * binary is EABI or softfloat (and thus, guaranteed not to use
+	 * FPA instructions.)
+	 */
+	if (elf_hwcap & HWCAP_IWMMXT &&
+	    eflags & (EF_ARM_EABI_MASK | EF_ARM_SOFT_FLOAT)) {
+		set_thread_flag(TIF_USING_IWMMXT);
+	} else {
+		clear_thread_flag(TIF_USING_IWMMXT);
+	}
+}
+EXPORT_SYMBOL(elf_set_personality);
+
+/*
+ * Set READ_IMPLIES_EXEC if:
+ *  - the binary requires an executable stack
+ *  - we're running on a CPU which doesn't support NX.
+ */
+int arm_elf_read_implies_exec(const struct elf32_hdr *x, int executable_stack)
+{
+	if (executable_stack != EXSTACK_ENABLE_X)
+		return 1;
+	if (cpu_architecture() <= CPU_ARCH_ARMv6)
+		return 1;
+	return 0;
+}
+EXPORT_SYMBOL(arm_elf_read_implies_exec);
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 617e509..77b0474 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -76,14 +76,17 @@
 __pabt_invalid:
 	inv_entry BAD_PREFETCH
 	b	common_invalid
+ENDPROC(__pabt_invalid)
 
 __dabt_invalid:
 	inv_entry BAD_DATA
 	b	common_invalid
+ENDPROC(__dabt_invalid)
 
 __irq_invalid:
 	inv_entry BAD_IRQ
 	b	common_invalid
+ENDPROC(__irq_invalid)
 
 __und_invalid:
 	inv_entry BAD_UNDEFINSTR
@@ -107,6 +110,7 @@
 
 	mov	r0, sp
 	b	bad_mode
+ENDPROC(__und_invalid)
 
 /*
  * SVC mode handlers
@@ -192,6 +196,7 @@
 	ldr	r0, [sp, #S_PSR]
 	msr	spsr_cxsf, r0
 	ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
+ENDPROC(__dabt_svc)
 
 	.align	5
 __irq_svc:
@@ -223,6 +228,7 @@
 	bleq	trace_hardirqs_on
 #endif
 	ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
+ENDPROC(__irq_svc)
 
 	.ltorg
 
@@ -272,6 +278,7 @@
 	ldr	lr, [sp, #S_PSR]		@ Get SVC cpsr
 	msr	spsr_cxsf, lr
 	ldmia	sp, {r0 - pc}^			@ Restore SVC registers
+ENDPROC(__und_svc)
 
 	.align	5
 __pabt_svc:
@@ -313,6 +320,7 @@
 	ldr	r0, [sp, #S_PSR]
 	msr	spsr_cxsf, r0
 	ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
+ENDPROC(__pabt_svc)
 
 	.align	5
 .LCcralign:
@@ -412,6 +420,7 @@
 	mov	r2, sp
 	adr	lr, ret_from_exception
 	b	do_DataAbort
+ENDPROC(__dabt_usr)
 
 	.align	5
 __irq_usr:
@@ -441,6 +450,7 @@
 
 	mov	why, #0
 	b	ret_to_user
+ENDPROC(__irq_usr)
 
 	.ltorg
 
@@ -474,6 +484,7 @@
 #else
 	b	__und_usr_unknown
 #endif
+ENDPROC(__und_usr)
 
 	@
 	@ fallthrough to call_fpe
@@ -642,6 +653,7 @@
 	mov	r0, sp
 	adr	lr, ret_from_exception
 	b	do_undefinstr
+ENDPROC(__und_usr_unknown)
 
 	.align	5
 __pabt_usr:
@@ -666,6 +678,8 @@
 	get_thread_info tsk
 	mov	why, #0
 	b	ret_to_user
+ENDPROC(__pabt_usr)
+ENDPROC(ret_from_exception)
 
 /*
  * Register switch for ARMv3 and ARMv4 processors
@@ -702,6 +716,7 @@
 	bl	atomic_notifier_call_chain
 	mov	r0, r5
 	ldmia	r4, {r4 - sl, fp, sp, pc}	@ Load all regs saved previously
+ENDPROC(__switch_to)
 
 	__INIT
 
@@ -1029,6 +1044,7 @@
 	mov	r0, sp
 	ldr	lr, [pc, lr, lsl #2]
 	movs	pc, lr			@ branch to handler in SVC mode
+ENDPROC(vector_\name)
 	.endm
 
 	.globl	__stubs_start
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 060d7e2..3aa14dc 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -77,6 +77,7 @@
 	mov	r0, r0
 	add	sp, sp, #S_FRAME_SIZE - S_PC
 	movs	pc, lr				@ return & move spsr_svc into cpsr
+ENDPROC(ret_to_user)
 
 /*
  * This is how we return from a fork.
@@ -92,7 +93,7 @@
 	mov	r0, #1				@ trace exit [IP = 1]
 	bl	syscall_trace
 	b	ret_slow_syscall
-	
+ENDPROC(ret_from_fork)
 
 	.equ NR_syscalls,0
 #define CALL(x) .equ NR_syscalls,NR_syscalls+1
@@ -269,6 +270,7 @@
 	eor	r0, scno, #__NR_SYSCALL_BASE	@ put OS number back
 	bcs	arm_syscall	
 	b	sys_ni_syscall			@ not private func
+ENDPROC(vector_swi)
 
 	/*
 	 * This is the really slow path.  We're going to be doing
@@ -326,7 +328,6 @@
  */
 @ r0 = syscall number
 @ r8 = syscall table
-		.type	sys_syscall, #function
 sys_syscall:
 		bic	scno, r0, #__NR_OABI_SYSCALL_BASE
 		cmp	scno, #__NR_syscall - __NR_SYSCALL_BASE
@@ -338,53 +339,65 @@
 		movlo	r3, r4
 		ldrlo	pc, [tbl, scno, lsl #2]
 		b	sys_ni_syscall
+ENDPROC(sys_syscall)
 
 sys_fork_wrapper:
 		add	r0, sp, #S_OFF
 		b	sys_fork
+ENDPROC(sys_fork_wrapper)
 
 sys_vfork_wrapper:
 		add	r0, sp, #S_OFF
 		b	sys_vfork
+ENDPROC(sys_vfork_wrapper)
 
 sys_execve_wrapper:
 		add	r3, sp, #S_OFF
 		b	sys_execve
+ENDPROC(sys_execve_wrapper)
 
 sys_clone_wrapper:
 		add	ip, sp, #S_OFF
 		str	ip, [sp, #4]
 		b	sys_clone
+ENDPROC(sys_clone_wrapper)
 
 sys_sigsuspend_wrapper:
 		add	r3, sp, #S_OFF
 		b	sys_sigsuspend
+ENDPROC(sys_sigsuspend_wrapper)
 
 sys_rt_sigsuspend_wrapper:
 		add	r2, sp, #S_OFF
 		b	sys_rt_sigsuspend
+ENDPROC(sys_rt_sigsuspend_wrapper)
 
 sys_sigreturn_wrapper:
 		add	r0, sp, #S_OFF
 		b	sys_sigreturn
+ENDPROC(sys_sigreturn_wrapper)
 
 sys_rt_sigreturn_wrapper:
 		add	r0, sp, #S_OFF
 		b	sys_rt_sigreturn
+ENDPROC(sys_rt_sigreturn_wrapper)
 
 sys_sigaltstack_wrapper:
 		ldr	r2, [sp, #S_OFF + S_SP]
 		b	do_sigaltstack
+ENDPROC(sys_sigaltstack_wrapper)
 
 sys_statfs64_wrapper:
 		teq	r1, #88
 		moveq	r1, #84
 		b	sys_statfs64
+ENDPROC(sys_statfs64_wrapper)
 
 sys_fstatfs64_wrapper:
 		teq	r1, #88
 		moveq	r1, #84
 		b	sys_fstatfs64
+ENDPROC(sys_fstatfs64_wrapper)
 
 /*
  * Note: off_4k (r5) is always units of 4K.  If we can't do the requested
@@ -402,11 +415,14 @@
 		str	r5, [sp, #4]
 		b	do_mmap2
 #endif
+ENDPROC(sys_mmap2)
 
 ENTRY(pabort_ifar)
 		mrc	p15, 0, r0, cr6, cr0, 2
 ENTRY(pabort_noifar)
 		mov	pc, lr
+ENDPROC(pabort_ifar)
+ENDPROC(pabort_noifar)
 
 #ifdef CONFIG_OABI_COMPAT
 
@@ -417,26 +433,31 @@
 sys_oabi_pread64:
 		stmia	sp, {r3, r4}
 		b	sys_pread64
+ENDPROC(sys_oabi_pread64)
 
 sys_oabi_pwrite64:
 		stmia	sp, {r3, r4}
 		b	sys_pwrite64
+ENDPROC(sys_oabi_pwrite64)
 
 sys_oabi_truncate64:
 		mov	r3, r2
 		mov	r2, r1
 		b	sys_truncate64
+ENDPROC(sys_oabi_truncate64)
 
 sys_oabi_ftruncate64:
 		mov	r3, r2
 		mov	r2, r1
 		b	sys_ftruncate64
+ENDPROC(sys_oabi_ftruncate64)
 
 sys_oabi_readahead:
 		str	r3, [sp]
 		mov	r3, r2
 		mov	r2, r1
 		b	sys_readahead
+ENDPROC(sys_oabi_readahead)
 
 /*
  * Let's declare a second syscall table for old ABI binaries
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
index e8e9034..36f81d9 100644
--- a/arch/arm/kernel/fiq.c
+++ b/arch/arm/kernel/fiq.c
@@ -45,7 +45,6 @@
 #include <asm/fiq.h>
 #include <asm/irq.h>
 #include <asm/system.h>
-#include <asm/uaccess.h>
 
 static unsigned long no_fiq_insn;
 
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index 1c3c6ea..bde52df 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -36,7 +36,6 @@
  *  r2  = atags pointer
  *  r9  = processor ID
  */
-	.type	__mmap_switched, %function
 __mmap_switched:
 	adr	r3, __switch_data + 4
 
@@ -59,6 +58,7 @@
 	bic	r4, r0, #CR_A			@ Clear 'A' bit
 	stmia	r7, {r0, r4}			@ Save control register values
 	b	start_kernel
+ENDPROC(__mmap_switched)
 
 /*
  * Exception handling.  Something went wrong and we can't proceed.  We
@@ -69,8 +69,6 @@
  * and hope for the best (useful if bootloader fails to pass a proper
  * machine ID for example).
  */
-
-	.type	__error_p, %function
 __error_p:
 #ifdef CONFIG_DEBUG_LL
 	adr	r0, str_p1
@@ -84,8 +82,8 @@
 str_p2:	.asciz	").\n"
 	.align
 #endif
+ENDPROC(__error_p)
 
-	.type	__error_a, %function
 __error_a:
 #ifdef CONFIG_DEBUG_LL
 	mov	r4, r1				@ preserve machine ID
@@ -115,13 +113,14 @@
 	adr	r0, str_a3
 	bl	printascii
 	b	__error
+ENDPROC(__error_a)
+
 str_a1:	.asciz	"\nError: unrecognized/unsupported machine ID (r1 = 0x"
 str_a2:	.asciz	").\n\nAvailable machine support:\n\nID (hex)\tNAME\n"
 str_a3:	.asciz	"\nPlease check your kernel config and/or bootloader.\n"
 	.align
 #endif
 
-	.type	__error, %function
 __error:
 #ifdef CONFIG_ARCH_RPC
 /*
@@ -138,6 +137,7 @@
 #endif
 1:	mov	r0, r0
 	b	1b
+ENDPROC(__error)
 
 
 /*
@@ -153,7 +153,6 @@
  *	r5 = proc_info pointer in physical address space
  *	r9 = cpuid (preserved)
  */
-	.type	__lookup_processor_type, %function
 __lookup_processor_type:
 	adr	r3, 3f
 	ldmda	r3, {r5 - r7}
@@ -169,6 +168,7 @@
 	blo	1b
 	mov	r5, #0				@ unknown processor
 2:	mov	pc, lr
+ENDPROC(__lookup_processor_type)
 
 /*
  * This provides a C-API version of the above function.
@@ -179,6 +179,7 @@
 	bl	__lookup_processor_type
 	mov	r0, r5
 	ldmfd	sp!, {r4 - r7, r9, pc}
+ENDPROC(lookup_processor_type)
 
 /*
  * Look in <asm/procinfo.h> and arch/arm/kernel/arch.[ch] for
@@ -201,7 +202,6 @@
  *  r3, r4, r6 corrupted
  *  r5 = mach_info pointer in physical address space
  */
-	.type	__lookup_machine_type, %function
 __lookup_machine_type:
 	adr	r3, 3b
 	ldmia	r3, {r4, r5, r6}
@@ -216,6 +216,7 @@
 	blo	1b
 	mov	r5, #0				@ unknown machine
 2:	mov	pc, lr
+ENDPROC(__lookup_machine_type)
 
 /*
  * This provides a C-API version of the above function.
@@ -226,6 +227,7 @@
 	bl	__lookup_machine_type
 	mov	r0, r5
 	ldmfd	sp!, {r4 - r6, pc}
+ENDPROC(lookup_machine_type)
 
 /* Determine validity of the r2 atags pointer.  The heuristic requires
  * that the pointer be aligned, in the first 16k of physical RAM and
@@ -239,8 +241,6 @@
  *  r2 either valid atags pointer, or zero
  *  r5, r6 corrupted
  */
-
-	.type	__vet_atags, %function
 __vet_atags:
 	tst	r2, #0x3			@ aligned?
 	bne	1f
@@ -257,3 +257,4 @@
 
 1:	mov	r2, #0
 	mov	pc, lr
+ENDPROC(__vet_atags)
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
index 27329bd..cc87e17 100644
--- a/arch/arm/kernel/head-nommu.S
+++ b/arch/arm/kernel/head-nommu.S
@@ -33,7 +33,6 @@
  *
  */
 	.section ".text.head", "ax"
-	.type	stext, %function
 ENTRY(stext)
 	msr	cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
 						@ and irqs disabled
@@ -53,11 +52,11 @@
 						@ the initialization is done
 	adr	lr, __after_proc_init		@ return (PIC) address
 	add	pc, r10, #PROCINFO_INITFUNC
+ENDPROC(stext)
 
 /*
  * Set the Control Register and Read the process ID.
  */
-	.type	__after_proc_init, %function
 __after_proc_init:
 #ifdef CONFIG_CPU_CP15
 	mrc	p15, 0, r0, c1, c0, 0		@ read control reg
@@ -85,6 +84,7 @@
 
 	mov	pc, r13				@ clear the BSS and jump
 						@ to start_kernel
+ENDPROC(__after_proc_init)
 	.ltorg
 
 #include "head-common.S"
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index bff4c6e..21e17dc 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -75,7 +75,6 @@
  * circumstances, zImage) is for.
  */
 	.section ".text.head", "ax"
-	.type	stext, %function
 ENTRY(stext)
 	msr	cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
 						@ and irqs disabled
@@ -100,9 +99,9 @@
 						@ mmu has been enabled
 	adr	lr, __enable_mmu		@ return (PIC) address
 	add	pc, r10, #PROCINFO_INITFUNC
+ENDPROC(stext)
 
 #if defined(CONFIG_SMP)
-	.type   secondary_startup, #function
 ENTRY(secondary_startup)
 	/*
 	 * Common entry point for secondary CPUs.
@@ -128,6 +127,7 @@
 	adr	lr, __enable_mmu		@ return address
 	add	pc, r10, #PROCINFO_INITFUNC	@ initialise processor
 						@ (return control reg)
+ENDPROC(secondary_startup)
 
 	/*
 	 * r6  = &secondary_data
@@ -136,6 +136,7 @@
 	ldr	sp, [r7, #4]			@ get secondary_data.stack
 	mov	fp, #0
 	b	secondary_start_kernel
+ENDPROC(__secondary_switched)
 
 	.type	__secondary_data, %object
 __secondary_data:
@@ -151,7 +152,6 @@
  * this is just loading the page table pointer and domain access
  * registers.
  */
-	.type	__enable_mmu, %function
 __enable_mmu:
 #ifdef CONFIG_ALIGNMENT_TRAP
 	orr	r0, r0, #CR_A
@@ -174,6 +174,7 @@
 	mcr	p15, 0, r5, c3, c0, 0		@ load domain access register
 	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
 	b	__turn_mmu_on
+ENDPROC(__enable_mmu)
 
 /*
  * Enable the MMU.  This completely changes the structure of the visible
@@ -187,7 +188,6 @@
  * other registers depend on the function called upon completion
  */
 	.align	5
-	.type	__turn_mmu_on, %function
 __turn_mmu_on:
 	mov	r0, r0
 	mcr	p15, 0, r0, c1, c0, 0		@ write control reg
@@ -195,7 +195,7 @@
 	mov	r3, r3
 	mov	r3, r3
 	mov	pc, r13
-
+ENDPROC(__turn_mmu_on)
 
 
 /*
@@ -211,7 +211,6 @@
  *  r0, r3, r6, r7 corrupted
  *  r4 = physical page table address
  */
-	.type	__create_page_tables, %function
 __create_page_tables:
 	pgtbl	r4				@ page table address
 
@@ -325,6 +324,7 @@
 #endif
 #endif
 	mov	pc, lr
+ENDPROC(__create_page_tables)
 	.ltorg
 
 #include "head-common.S"
diff --git a/arch/arm/kernel/init_task.c b/arch/arm/kernel/init_task.c
index 8b8c9d3..0bbf806 100644
--- a/arch/arm/kernel/init_task.c
+++ b/arch/arm/kernel/init_task.c
@@ -8,8 +8,8 @@
 #include <linux/init.h>
 #include <linux/init_task.h>
 #include <linux/mqueue.h>
+#include <linux/uaccess.h>
 
-#include <asm/uaccess.h>
 #include <asm/pgtable.h>
 
 static struct fs_struct init_fs = INIT_FS;
diff --git a/arch/arm/kernel/io.c b/arch/arm/kernel/io.c
index 1f6822d..f447030 100644
--- a/arch/arm/kernel/io.c
+++ b/arch/arm/kernel/io.c
@@ -1,7 +1,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
 /*
  * Copy data from IO memory space to "real" memory space.
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index f88efb1..2f3eb79 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -112,18 +112,17 @@
 asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
 {
 	struct pt_regs *old_regs = set_irq_regs(regs);
-	struct irq_desc *desc = irq_desc + irq;
+
+	irq_enter();
 
 	/*
 	 * Some hardware gives randomly wrong interrupts.  Rather
 	 * than crashing, do something sensible.
 	 */
 	if (irq >= NR_IRQS)
-		desc = &bad_irq_desc;
-
-	irq_enter();
-
-	desc_handle_irq(irq, desc);
+		handle_bad_irq(irq, &bad_irq_desc);
+	else
+		generic_handle_irq(irq);
 
 	/* AT91 specific workaround */
 	irq_finish(irq);
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
index b4565bb..da1f949 100644
--- a/arch/arm/kernel/kprobes-decode.c
+++ b/arch/arm/kernel/kprobes-decode.c
@@ -488,7 +488,7 @@
 
 	if (!ubit)
 		addr -= reg_count;
-	addr += (!pbit ^ !ubit);
+	addr += (!pbit == !ubit);
 
 	reg_bit_vector = insn & 0xffff;
 	while (reg_bit_vector) {
@@ -503,7 +503,7 @@
 	if (wbit) {
 		if (!ubit)
 			addr -= reg_count;
-		addr -= (!pbit ^ !ubit);
+		addr -= (!pbit == !ubit);
 		regs->uregs[rn] = (long)addr;
 	}
 }
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c
index d28513f1..3f9abe0 100644
--- a/arch/arm/kernel/kprobes.c
+++ b/arch/arm/kernel/kprobes.c
@@ -200,9 +200,12 @@
 	}
 }
 
-int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr)
+static int __kprobes kprobe_trap_handler(struct pt_regs *regs, unsigned int instr)
 {
+	unsigned long flags;
+	local_irq_save(flags);
 	kprobe_handler(regs);
+	local_irq_restore(flags);
 	return 0;
 }
 
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index fae5beb..440dc62 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -6,10 +6,10 @@
 #include <linux/kexec.h>
 #include <linux/delay.h>
 #include <linux/reboot.h>
+#include <linux/io.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
-#include <asm/io.h>
 #include <asm/cacheflush.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index a68259a..9203ba7 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -47,7 +47,7 @@
 	if (!area)
 		return NULL;
 
-	return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL);
+	return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
 }
 #else /* CONFIG_MMU */
 void *module_alloc(unsigned long size)
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 3fd8823..d3ea6fa 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -28,12 +28,12 @@
 #include <linux/pm.h>
 #include <linux/tick.h>
 #include <linux/utsname.h>
+#include <linux/uaccess.h>
 
 #include <asm/leds.h>
 #include <asm/processor.h>
 #include <asm/system.h>
 #include <asm/thread_notify.h>
-#include <asm/uaccess.h>
 #include <asm/mach/time.h>
 
 static const char *processor_modes[] = {
@@ -267,35 +267,6 @@
 	__backtrace();
 }
 
-void show_fpregs(struct user_fp *regs)
-{
-	int i;
-
-	for (i = 0; i < 8; i++) {
-		unsigned long *p;
-		char type;
-
-		p = (unsigned long *)(regs->fpregs + i);
-
-		switch (regs->ftype[i]) {
-			case 1: type = 'f'; break;
-			case 2: type = 'd'; break;
-			case 3: type = 'e'; break;
-			default: type = '?'; break;
-		}
-		if (regs->init_flag)
-			type = '?';
-
-		printk("  f%d(%c): %08lx %08lx %08lx%c",
-			i, type, p[0], p[1], p[2], i & 1 ? '\n' : ' ');
-	}
-			
-
-	printk("FPSR: %08lx FPCR: %08lx\n",
-		(unsigned long)regs->fpsr,
-		(unsigned long)regs->fpcr);
-}
-
 /*
  * Free current thread data structures etc..
  */
@@ -414,7 +385,7 @@
 	do {
 		if (fp < stack_start || fp > stack_end)
 			return 0;
-		lr = pc_pointer (((unsigned long *)fp)[-1]);
+		lr = ((unsigned long *)fp)[-1];
 		if (!in_sched_functions(lr))
 			return lr;
 		fp = *(unsigned long *) (fp - 12);
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 4b05dc5..df653ea 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -18,8 +18,8 @@
 #include <linux/security.h>
 #include <linux/init.h>
 #include <linux/signal.h>
+#include <linux/uaccess.h>
 
-#include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/traps.h>
@@ -126,7 +126,7 @@
 
 	val = get_user_reg(child, reg);
 	if (reg == 15)
-		val = pc_pointer(val + 8);
+		val += 8;
 
 	return val;
 }
@@ -278,8 +278,7 @@
 				else
 					base -= aluop2;
 			}
-			if (read_u32(child, base, &alt) == 0)
-				alt = pc_pointer(alt);
+			read_u32(child, base, &alt);
 		}
 		break;
 
@@ -305,8 +304,7 @@
 
 			base = ptrace_getrn(child, insn);
 
-			if (read_u32(child, base + nr_regs, &alt) == 0)
-				alt = pc_pointer(alt);
+			read_u32(child, base + nr_regs, &alt);
 			break;
 		}
 		break;
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 2ca7038..1f1eecc 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -26,11 +26,13 @@
 #include <linux/fs.h>
 
 #include <asm/cpu.h>
+#include <asm/cputype.h>
 #include <asm/elf.h>
 #include <asm/procinfo.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/cacheflush.h>
+#include <asm/cachetype.h>
 #include <asm/tlbflush.h>
 
 #include <asm/mach/arch.h>
@@ -59,13 +61,14 @@
 
 extern void paging_init(struct meminfo *, struct machine_desc *desc);
 extern void reboot_setup(char *str);
-extern int root_mountflags;
-extern void _stext, _text, _etext, __data_start, _edata, _end;
+extern void _text, _etext, __data_start, _edata, _end;
 
 unsigned int processor_id;
 EXPORT_SYMBOL(processor_id);
 unsigned int __machine_arch_type;
 EXPORT_SYMBOL(__machine_arch_type);
+unsigned int cacheid;
+EXPORT_SYMBOL(cacheid);
 
 unsigned int __atags_pointer __initdata;
 
@@ -81,8 +84,6 @@
 unsigned int elf_hwcap;
 EXPORT_SYMBOL(elf_hwcap);
 
-unsigned long __initdata vmalloc_reserve = 128 << 20;
-
 
 #ifdef MULTI_CPU
 struct processor processor;
@@ -111,9 +112,6 @@
 char elf_platform[ELF_PLATFORM_SIZE];
 EXPORT_SYMBOL(elf_platform);
 
-unsigned long phys_initrd_start __initdata = 0;
-unsigned long phys_initrd_size __initdata = 0;
-
 static struct meminfo meminfo __initdata = { 0, };
 static const char *cpu_name;
 static const char *machine_name;
@@ -178,63 +176,6 @@
 #define lp1 io_res[1]
 #define lp2 io_res[2]
 
-static const char *cache_types[16] = {
-	"write-through",
-	"write-back",
-	"write-back",
-	"undefined 3",
-	"undefined 4",
-	"undefined 5",
-	"write-back",
-	"write-back",
-	"undefined 8",
-	"undefined 9",
-	"undefined 10",
-	"undefined 11",
-	"undefined 12",
-	"undefined 13",
-	"write-back",
-	"undefined 15",
-};
-
-static const char *cache_clean[16] = {
-	"not required",
-	"read-block",
-	"cp15 c7 ops",
-	"undefined 3",
-	"undefined 4",
-	"undefined 5",
-	"cp15 c7 ops",
-	"cp15 c7 ops",
-	"undefined 8",
-	"undefined 9",
-	"undefined 10",
-	"undefined 11",
-	"undefined 12",
-	"undefined 13",
-	"cp15 c7 ops",
-	"undefined 15",
-};
-
-static const char *cache_lockdown[16] = {
-	"not supported",
-	"not supported",
-	"not supported",
-	"undefined 3",
-	"undefined 4",
-	"undefined 5",
-	"format A",
-	"format B",
-	"undefined 8",
-	"undefined 9",
-	"undefined 10",
-	"undefined 11",
-	"undefined 12",
-	"undefined 13",
-	"format C",
-	"undefined 15",
-};
-
 static const char *proc_arch[] = {
 	"undefined/unknown",
 	"3",
@@ -255,61 +196,19 @@
 	"?(17)",
 };
 
-#define CACHE_TYPE(x)	(((x) >> 25) & 15)
-#define CACHE_S(x)	((x) & (1 << 24))
-#define CACHE_DSIZE(x)	(((x) >> 12) & 4095)	/* only if S=1 */
-#define CACHE_ISIZE(x)	((x) & 4095)
-
-#define CACHE_SIZE(y)	(((y) >> 6) & 7)
-#define CACHE_ASSOC(y)	(((y) >> 3) & 7)
-#define CACHE_M(y)	((y) & (1 << 2))
-#define CACHE_LINE(y)	((y) & 3)
-
-static inline void dump_cache(const char *prefix, int cpu, unsigned int cache)
-{
-	unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0);
-
-	printk("CPU%u: %s: %d bytes, associativity %d, %d byte lines, %d sets\n",
-		cpu, prefix,
-		mult << (8 + CACHE_SIZE(cache)),
-		(mult << CACHE_ASSOC(cache)) >> 1,
-		8 << CACHE_LINE(cache),
-		1 << (6 + CACHE_SIZE(cache) - CACHE_ASSOC(cache) -
-			CACHE_LINE(cache)));
-}
-
-static void __init dump_cpu_info(int cpu)
-{
-	unsigned int info = read_cpuid(CPUID_CACHETYPE);
-
-	if (info != processor_id) {
-		printk("CPU%u: D %s %s cache\n", cpu, cache_is_vivt() ? "VIVT" : "VIPT",
-		       cache_types[CACHE_TYPE(info)]);
-		if (CACHE_S(info)) {
-			dump_cache("I cache", cpu, CACHE_ISIZE(info));
-			dump_cache("D cache", cpu, CACHE_DSIZE(info));
-		} else {
-			dump_cache("cache", cpu, CACHE_ISIZE(info));
-		}
-	}
-
-	if (arch_is_coherent())
-		printk("Cache coherency enabled\n");
-}
-
 int cpu_architecture(void)
 {
 	int cpu_arch;
 
-	if ((processor_id & 0x0008f000) == 0) {
+	if ((read_cpuid_id() & 0x0008f000) == 0) {
 		cpu_arch = CPU_ARCH_UNKNOWN;
-	} else if ((processor_id & 0x0008f000) == 0x00007000) {
-		cpu_arch = (processor_id & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
-	} else if ((processor_id & 0x00080000) == 0x00000000) {
-		cpu_arch = (processor_id >> 16) & 7;
+	} else if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
+		cpu_arch = (read_cpuid_id() & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
+	} else if ((read_cpuid_id() & 0x00080000) == 0x00000000) {
+		cpu_arch = (read_cpuid_id() >> 16) & 7;
 		if (cpu_arch)
 			cpu_arch += CPU_ARCH_ARMv3;
-	} else if ((processor_id & 0x000f0000) == 0x000f0000) {
+	} else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
 		unsigned int mmfr0;
 
 		/* Revised CPUID format. Read the Memory Model Feature
@@ -330,6 +229,34 @@
 	return cpu_arch;
 }
 
+static void __init cacheid_init(void)
+{
+	unsigned int cachetype = read_cpuid_cachetype();
+	unsigned int arch = cpu_architecture();
+
+	if (arch >= CPU_ARCH_ARMv7) {
+		cacheid = CACHEID_VIPT_NONALIASING;
+		if ((cachetype & (3 << 14)) == 1 << 14)
+			cacheid |= CACHEID_ASID_TAGGED;
+	} else if (arch >= CPU_ARCH_ARMv6) {
+		if (cachetype & (1 << 23))
+			cacheid = CACHEID_VIPT_ALIASING;
+		else
+			cacheid = CACHEID_VIPT_NONALIASING;
+	} else {
+		cacheid = CACHEID_VIVT;
+	}
+
+	printk("CPU: %s data cache, %s instruction cache\n",
+		cache_is_vivt() ? "VIVT" :
+		cache_is_vipt_aliasing() ? "VIPT aliasing" :
+		cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown",
+		cache_is_vivt() ? "VIVT" :
+		icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
+		cache_is_vipt_aliasing() ? "VIPT aliasing" :
+		cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown");
+}
+
 /*
  * These functions re-use the assembly code in head.S, which
  * already provide the required functionality.
@@ -346,10 +273,10 @@
 	 * types.  The linker builds this table for us from the
 	 * entries in arch/arm/mm/proc-*.S
 	 */
-	list = lookup_processor_type(processor_id);
+	list = lookup_processor_type(read_cpuid_id());
 	if (!list) {
 		printk("CPU configuration botched (ID %08x), unable "
-		       "to continue.\n", processor_id);
+		       "to continue.\n", read_cpuid_id());
 		while (1);
 	}
 
@@ -369,7 +296,7 @@
 #endif
 
 	printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n",
-	       cpu_name, processor_id, (int)processor_id & 15,
+	       cpu_name, read_cpuid_id(), read_cpuid_id() & 15,
 	       proc_arch[cpu_architecture()], cr_alignment);
 
 	sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS);
@@ -379,14 +306,14 @@
 	elf_hwcap &= ~HWCAP_THUMB;
 #endif
 
+	cacheid_init();
 	cpu_proc_init();
 }
 
 /*
  * cpu_init - initialise one CPU.
  *
- * cpu_init dumps the cache information, initialises SMP specific
- * information, and sets up the per-CPU stacks.
+ * cpu_init sets up the per-CPU stacks.
  */
 void cpu_init(void)
 {
@@ -398,9 +325,6 @@
 		BUG();
 	}
 
-	if (system_state == SYSTEM_BOOTING)
-		dump_cpu_info(cpu);
-
 	/*
 	 * setup stacks for re-entrant exception handlers
 	 */
@@ -443,20 +367,6 @@
 	return list;
 }
 
-static void __init early_initrd(char **p)
-{
-	unsigned long start, size;
-
-	start = memparse(*p, p);
-	if (**p == ',') {
-		size = memparse((*p) + 1, p);
-
-		phys_initrd_start = start;
-		phys_initrd_size = size;
-	}
-}
-__early_param("initrd=", early_initrd);
-
 static void __init arm_add_memory(unsigned long start, unsigned long size)
 {
 	struct membank *bank;
@@ -503,17 +413,6 @@
 __early_param("mem=", early_mem);
 
 /*
- * vmalloc=size forces the vmalloc area to be exactly 'size'
- * bytes. This can be used to increase (or decrease) the vmalloc
- * area - the default is 128m.
- */
-static void __init early_vmalloc(char **arg)
-{
-	vmalloc_reserve = memparse(*arg, arg);
-}
-__early_param("vmalloc=", early_vmalloc);
-
-/*
  * Initial parsing of the command line.
  */
 static void __init parse_cmdline(char **cmdline_p, char *from)
@@ -527,12 +426,12 @@
 			struct early_params *p;
 
 			for (p = &__early_begin; p < &__early_end; p++) {
-				int len = strlen(p->arg);
+				int arglen = strlen(p->arg);
 
-				if (memcmp(from, p->arg, len) == 0) {
+				if (memcmp(from, p->arg, arglen) == 0) {
 					if (to != command_line)
 						to -= 1;
-					from += len;
+					from += arglen;
 					p->fn(&from);
 
 					while (*from != ' ' && *from != '\0')
@@ -579,18 +478,13 @@
 	kernel_data.end     = virt_to_phys(&_end - 1);
 
 	for (i = 0; i < mi->nr_banks; i++) {
-		unsigned long virt_start, virt_end;
-
 		if (mi->bank[i].size == 0)
 			continue;
 
-		virt_start = __phys_to_virt(mi->bank[i].start);
-		virt_end   = virt_start + mi->bank[i].size - 1;
-
 		res = alloc_bootmem_low(sizeof(*res));
 		res->name  = "System RAM";
-		res->start = __virt_to_phys(virt_start);
-		res->end   = __virt_to_phys(virt_end);
+		res->start = mi->bank[i].start;
+		res->end   = mi->bank[i].start + mi->bank[i].size - 1;
 		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
 
 		request_resource(&iomem_resource, res);
@@ -694,26 +588,6 @@
 
 __tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
 
-static int __init parse_tag_initrd(const struct tag *tag)
-{
-	printk(KERN_WARNING "ATAG_INITRD is deprecated; "
-		"please update your bootloader.\n");
-	phys_initrd_start = __virt_to_phys(tag->u.initrd.start);
-	phys_initrd_size = tag->u.initrd.size;
-	return 0;
-}
-
-__tagtable(ATAG_INITRD, parse_tag_initrd);
-
-static int __init parse_tag_initrd2(const struct tag *tag)
-{
-	phys_initrd_start = tag->u.initrd.start;
-	phys_initrd_size = tag->u.initrd.size;
-	return 0;
-}
-
-__tagtable(ATAG_INITRD2, parse_tag_initrd2);
-
 static int __init parse_tag_serialnr(const struct tag *tag)
 {
 	system_serial_low = tag->u.serialnr.low;
@@ -901,28 +775,12 @@
 	NULL
 };
 
-static void
-c_show_cache(struct seq_file *m, const char *type, unsigned int cache)
-{
-	unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0);
-
-	seq_printf(m, "%s size\t\t: %d\n"
-		      "%s assoc\t\t: %d\n"
-		      "%s line length\t: %d\n"
-		      "%s sets\t\t: %d\n",
-		type, mult << (8 + CACHE_SIZE(cache)),
-		type, (mult << CACHE_ASSOC(cache)) >> 1,
-		type, 8 << CACHE_LINE(cache),
-		type, 1 << (6 + CACHE_SIZE(cache) - CACHE_ASSOC(cache) -
-			    CACHE_LINE(cache)));
-}
-
 static int c_show(struct seq_file *m, void *v)
 {
 	int i;
 
 	seq_printf(m, "Processor\t: %s rev %d (%s)\n",
-		   cpu_name, (int)processor_id & 15, elf_platform);
+		   cpu_name, read_cpuid_id() & 15, elf_platform);
 
 #if defined(CONFIG_SMP)
 	for_each_online_cpu(i) {
@@ -949,47 +807,26 @@
 		if (elf_hwcap & (1 << i))
 			seq_printf(m, "%s ", hwcap_str[i]);
 
-	seq_printf(m, "\nCPU implementer\t: 0x%02x\n", processor_id >> 24);
+	seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24);
 	seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]);
 
-	if ((processor_id & 0x0008f000) == 0x00000000) {
+	if ((read_cpuid_id() & 0x0008f000) == 0x00000000) {
 		/* pre-ARM7 */
-		seq_printf(m, "CPU part\t: %07x\n", processor_id >> 4);
+		seq_printf(m, "CPU part\t: %07x\n", read_cpuid_id() >> 4);
 	} else {
-		if ((processor_id & 0x0008f000) == 0x00007000) {
+		if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
 			/* ARM7 */
 			seq_printf(m, "CPU variant\t: 0x%02x\n",
-				   (processor_id >> 16) & 127);
+				   (read_cpuid_id() >> 16) & 127);
 		} else {
 			/* post-ARM7 */
 			seq_printf(m, "CPU variant\t: 0x%x\n",
-				   (processor_id >> 20) & 15);
+				   (read_cpuid_id() >> 20) & 15);
 		}
 		seq_printf(m, "CPU part\t: 0x%03x\n",
-			   (processor_id >> 4) & 0xfff);
+			   (read_cpuid_id() >> 4) & 0xfff);
 	}
-	seq_printf(m, "CPU revision\t: %d\n", processor_id & 15);
-
-	{
-		unsigned int cache_info = read_cpuid(CPUID_CACHETYPE);
-		if (cache_info != processor_id) {
-			seq_printf(m, "Cache type\t: %s\n"
-				      "Cache clean\t: %s\n"
-				      "Cache lockdown\t: %s\n"
-				      "Cache format\t: %s\n",
-				   cache_types[CACHE_TYPE(cache_info)],
-				   cache_clean[CACHE_TYPE(cache_info)],
-				   cache_lockdown[CACHE_TYPE(cache_info)],
-				   CACHE_S(cache_info) ? "Harvard" : "Unified");
-
-			if (CACHE_S(cache_info)) {
-				c_show_cache(m, "I", CACHE_ISIZE(cache_info));
-				c_show_cache(m, "D", CACHE_DSIZE(cache_info));
-			} else {
-				c_show_cache(m, "Cache", CACHE_ISIZE(cache_info));
-			}
-		}
-	}
+	seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15);
 
 	seq_puts(m, "\n");
 
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index ef2f86a..80b8b5c 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -11,11 +11,11 @@
 #include <linux/signal.h>
 #include <linux/personality.h>
 #include <linux/freezer.h>
+#include <linux/uaccess.h>
 
 #include <asm/elf.h>
 #include <asm/cacheflush.h>
 #include <asm/ucontext.h>
-#include <asm/uaccess.h>
 #include <asm/unistd.h>
 
 #include "ptrace.h"
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index 0128687..b3ec641 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -27,8 +27,7 @@
 #include <linux/file.h>
 #include <linux/utsname.h>
 #include <linux/ipc.h>
-
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 extern unsigned long do_mremap(unsigned long addr, unsigned long old_len,
 			       unsigned long new_len, unsigned long flags,
diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c
index 96ab5f5..42623db 100644
--- a/arch/arm/kernel/sys_oabi-compat.c
+++ b/arch/arm/kernel/sys_oabi-compat.c
@@ -82,7 +82,7 @@
 #include <linux/socket.h>
 #include <linux/net.h>
 #include <linux/ipc.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 struct oldabi_stat64 {
 	unsigned long long st_dev;
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 368d171..c68b44a 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -59,7 +59,7 @@
 
 	if (in_lock_functions(pc)) {
 		fp = regs->ARM_fp;
-		pc = pc_pointer(((unsigned long *)fp)[-1]);
+		pc = ((unsigned long *)fp)[-1];
 	}
 
 	return pc;
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 872f1f8..57e6874 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -19,15 +19,13 @@
 #include <linux/kallsyms.h>
 #include <linux/delay.h>
 #include <linux/init.h>
-#include <linux/kprobes.h>
+#include <linux/uaccess.h>
 
 #include <asm/atomic.h>
 #include <asm/cacheflush.h>
 #include <asm/system.h>
-#include <asm/uaccess.h>
 #include <asm/unistd.h>
 #include <asm/traps.h>
-#include <asm/io.h>
 
 #include "ptrace.h"
 #include "signal.h"
@@ -69,7 +67,8 @@
  */
 static int verify_stack(unsigned long sp)
 {
-	if (sp < PAGE_OFFSET || (sp > (unsigned long)high_memory && high_memory != 0))
+	if (sp < PAGE_OFFSET ||
+	    (sp > (unsigned long)high_memory && high_memory != NULL))
 		return -EFAULT;
 
 	return 0;
@@ -328,17 +327,6 @@
 		get_user(instr, (u32 __user *)pc);
 	}
 
-#ifdef CONFIG_KPROBES
-	/*
-	 * It is possible to have recursive kprobes, so we can't call
-	 * the kprobe trap handler with the undef_lock held.
-	 */
-	if (instr == KPROBE_BREAKPOINT_INSTRUCTION && !user_mode(regs)) {
-		kprobe_trap_handler(regs, instr);
-		return;
-	}
-#endif
-
 	if (call_undef_hook(regs, instr) == 0)
 		return;
 
diff --git a/arch/arm/kernel/xscale-cp0.c b/arch/arm/kernel/xscale-cp0.c
index 180000b..17127db 100644
--- a/arch/arm/kernel/xscale-cp0.c
+++ b/arch/arm/kernel/xscale-cp0.c
@@ -14,8 +14,8 @@
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/init.h>
+#include <linux/io.h>
 #include <asm/thread_notify.h>
-#include <asm/io.h>
 
 static inline void dsp_save_state(u32 *state)
 {
diff --git a/arch/arm/lib/ashldi3.S b/arch/arm/lib/ashldi3.S
index 55e57a1c..1154d92 100644
--- a/arch/arm/lib/ashldi3.S
+++ b/arch/arm/lib/ashldi3.S
@@ -47,3 +47,5 @@
 	mov	al, al, lsl r2
 	mov	pc, lr
 
+ENDPROC(__ashldi3)
+ENDPROC(__aeabi_llsl)
diff --git a/arch/arm/lib/ashrdi3.S b/arch/arm/lib/ashrdi3.S
index 0b31398..9f8b355 100644
--- a/arch/arm/lib/ashrdi3.S
+++ b/arch/arm/lib/ashrdi3.S
@@ -47,3 +47,5 @@
 	mov	ah, ah, asr r2
 	mov	pc, lr
 
+ENDPROC(__ashrdi3)
+ENDPROC(__aeabi_lasr)
diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S
index 84dc890..b0951d0 100644
--- a/arch/arm/lib/backtrace.S
+++ b/arch/arm/lib/backtrace.S
@@ -30,6 +30,8 @@
 
 #if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
 		mov	pc, lr
+ENDPROC(__backtrace)
+ENDPROC(c_backtrace)
 #else
 		stmfd	sp!, {r4 - r8, lr}	@ Save an extra register so we have a location...
 		movs	frame, r0		@ if frame pointer is zero
@@ -103,6 +105,8 @@
 		mov	r1, frame
 		bl	printk
 no_frame:	ldmfd	sp!, {r4 - r8, pc}
+ENDPROC(__backtrace)
+ENDPROC(c_backtrace)
 		
 		.section __ex_table,"a"
 		.align	3
diff --git a/arch/arm/lib/changebit.S b/arch/arm/lib/changebit.S
index 389567c..80f3115 100644
--- a/arch/arm/lib/changebit.S
+++ b/arch/arm/lib/changebit.S
@@ -19,3 +19,5 @@
 		eor	r0, r0, #0x18		@ big endian byte ordering
 ENTRY(_change_bit_le)
 	bitop	eor
+ENDPROC(_change_bit_be)
+ENDPROC(_change_bit_le)
diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S
index ecb28dc..4d6bc71 100644
--- a/arch/arm/lib/clear_user.S
+++ b/arch/arm/lib/clear_user.S
@@ -41,9 +41,10 @@
 USER(		strnebt	r2, [r0], #1)
 USER(		strnebt	r2, [r0], #1)
 		tst	r1, #1			@ x1 x0 x1 x0 x1 x0 x1
-USER(		strnebt	r2, [r0], #1)
+USER(		strnebt	r2, [r0])
 		mov	r0, #0
 		ldmfd	sp!, {r1, pc}
+ENDPROC(__clear_user)
 
 		.section .fixup,"ax"
 		.align	0
diff --git a/arch/arm/lib/clearbit.S b/arch/arm/lib/clearbit.S
index 3475165..1a63e43 100644
--- a/arch/arm/lib/clearbit.S
+++ b/arch/arm/lib/clearbit.S
@@ -20,3 +20,5 @@
 		eor	r0, r0, #0x18		@ big endian byte ordering
 ENTRY(_clear_bit_le)
 	bitop	bic
+ENDPROC(_clear_bit_be)
+ENDPROC(_clear_bit_le)
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
index 6b7363c..56799a1 100644
--- a/arch/arm/lib/copy_from_user.S
+++ b/arch/arm/lib/copy_from_user.S
@@ -87,6 +87,8 @@
 
 #include "copy_template.S"
 
+ENDPROC(__copy_from_user)
+
 	.section .fixup,"ax"
 	.align 0
 	copy_abort_preamble
diff --git a/arch/arm/lib/copy_page.S b/arch/arm/lib/copy_page.S
index 666c99c..6ae04db 100644
--- a/arch/arm/lib/copy_page.S
+++ b/arch/arm/lib/copy_page.S
@@ -44,3 +44,4 @@
 	PLD(	ldmeqia r1!, {r3, r4, ip, lr}	)
 	PLD(	beq	2b			)
 		ldmfd	sp!, {r4, pc}			@	3
+ENDPROC(copy_page)
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
index 5224d94..22f968b 100644
--- a/arch/arm/lib/copy_to_user.S
+++ b/arch/arm/lib/copy_to_user.S
@@ -90,6 +90,8 @@
 
 #include "copy_template.S"
 
+ENDPROC(__copy_to_user)
+
 	.section .fixup,"ax"
 	.align 0
 	copy_abort_preamble
diff --git a/arch/arm/lib/csumipv6.S b/arch/arm/lib/csumipv6.S
index 9621469..3ac6ef0 100644
--- a/arch/arm/lib/csumipv6.S
+++ b/arch/arm/lib/csumipv6.S
@@ -29,4 +29,5 @@
 		adcs	r0, r0, r2
 		adcs	r0, r0, #0
 		ldmfd	sp!, {pc}
+ENDPROC(__csum_ipv6_magic)
 
diff --git a/arch/arm/lib/csumpartial.S b/arch/arm/lib/csumpartial.S
index a78dae5..31d3cb3 100644
--- a/arch/arm/lib/csumpartial.S
+++ b/arch/arm/lib/csumpartial.S
@@ -139,3 +139,4 @@
 		tst	len, #0x1c
 		bne	4b
 		b	.Lless4
+ENDPROC(csum_partial)
diff --git a/arch/arm/lib/csumpartialcopy.S b/arch/arm/lib/csumpartialcopy.S
index 21effe0..d03fc71 100644
--- a/arch/arm/lib/csumpartialcopy.S
+++ b/arch/arm/lib/csumpartialcopy.S
@@ -18,13 +18,11 @@
  */
 
 		.macro	save_regs
-		mov	ip, sp
-		stmfd	sp!, {r1, r4 - r8, fp, ip, lr, pc}
-		sub	fp, ip, #4
+		stmfd	sp!, {r1, r4 - r8, lr}
 		.endm
 
 		.macro	load_regs
-		ldmfd	sp, {r1, r4 - r8, fp, sp, pc}
+		ldmfd	sp!, {r1, r4 - r8, pc}
 		.endm
 
 		.macro	load1b, reg1
@@ -50,5 +48,6 @@
 		.endm
 
 #define FN_ENTRY	ENTRY(csum_partial_copy_nocheck)
+#define FN_EXIT		ENDPROC(csum_partial_copy_nocheck)
 
 #include "csumpartialcopygeneric.S"
diff --git a/arch/arm/lib/csumpartialcopygeneric.S b/arch/arm/lib/csumpartialcopygeneric.S
index c50e8f5..d620a5f 100644
--- a/arch/arm/lib/csumpartialcopygeneric.S
+++ b/arch/arm/lib/csumpartialcopygeneric.S
@@ -329,3 +329,4 @@
 		adcs	sum, sum, r4, push #24
 		mov	r5, r4, get_byte_1
 		b	.Lexit
+FN_EXIT
diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S
index c3b93e2..14677fb 100644
--- a/arch/arm/lib/csumpartialcopyuser.S
+++ b/arch/arm/lib/csumpartialcopyuser.S
@@ -18,13 +18,11 @@
 		.text
 
 		.macro	save_regs
-		mov	ip, sp
-		stmfd	sp!, {r1 - r2, r4 - r8, fp, ip, lr, pc}
-		sub	fp, ip, #4
+		stmfd	sp!, {r1, r2, r4 - r8, lr}
 		.endm
 
 		.macro	load_regs
-		ldmfd	sp, {r1, r2, r4-r8, fp, sp, pc}
+		ldmfd	sp!, {r1, r2, r4 - r8, pc}
 		.endm
 
 		.macro	load1b,	reg1
@@ -82,6 +80,7 @@
  */
 
 #define FN_ENTRY	ENTRY(csum_partial_copy_from_user)
+#define FN_EXIT		ENDPROC(csum_partial_copy_from_user)
 
 #include "csumpartialcopygeneric.S"
 
diff --git a/arch/arm/lib/delay.S b/arch/arm/lib/delay.S
index 930a702..8d6a876 100644
--- a/arch/arm/lib/delay.S
+++ b/arch/arm/lib/delay.S
@@ -60,3 +60,6 @@
 #endif
 		bhi	__delay
 		mov	pc, lr
+ENDPROC(__udelay)
+ENDPROC(__const_udelay)
+ENDPROC(__delay)
diff --git a/arch/arm/lib/div64.S b/arch/arm/lib/div64.S
index 58eef66..1425e78 100644
--- a/arch/arm/lib/div64.S
+++ b/arch/arm/lib/div64.S
@@ -198,3 +198,4 @@
 	mov	xh, #0
 	ldr	pc, [sp], #8
 
+ENDPROC(__do_div64)
diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S
index a5ca024..8c4defc 100644
--- a/arch/arm/lib/findbit.S
+++ b/arch/arm/lib/findbit.S
@@ -33,6 +33,7 @@
 		blo	1b
 3:		mov	r0, r1			@ no free bits
 		mov	pc, lr
+ENDPROC(_find_first_zero_bit_le)
 
 /*
  * Purpose  : Find next 'zero' bit
@@ -50,6 +51,7 @@
 		orr	r2, r2, #7		@ if zero, then no bits here
 		add	r2, r2, #1		@ align bit pointer
 		b	2b			@ loop for next bit
+ENDPROC(_find_next_zero_bit_le)
 
 /*
  * Purpose  : Find a 'one' bit
@@ -67,6 +69,7 @@
 		blo	1b
 3:		mov	r0, r1			@ no free bits
 		mov	pc, lr
+ENDPROC(_find_first_bit_le)
 
 /*
  * Purpose  : Find next 'one' bit
@@ -83,6 +86,7 @@
 		orr	r2, r2, #7		@ if zero, then no bits here
 		add	r2, r2, #1		@ align bit pointer
 		b	2b			@ loop for next bit
+ENDPROC(_find_next_bit_le)
 
 #ifdef __ARMEB__
 
@@ -99,6 +103,7 @@
 		blo	1b
 3:		mov	r0, r1			@ no free bits
 		mov	pc, lr
+ENDPROC(_find_first_zero_bit_be)
 
 ENTRY(_find_next_zero_bit_be)
 		teq	r1, #0
@@ -113,6 +118,7 @@
 		orr	r2, r2, #7		@ if zero, then no bits here
 		add	r2, r2, #1		@ align bit pointer
 		b	2b			@ loop for next bit
+ENDPROC(_find_next_zero_bit_be)
 
 ENTRY(_find_first_bit_be)
 		teq	r1, #0
@@ -127,6 +133,7 @@
 		blo	1b
 3:		mov	r0, r1			@ no free bits
 		mov	pc, lr
+ENDPROC(_find_first_bit_be)
 
 ENTRY(_find_next_bit_be)
 		teq	r1, #0
@@ -140,6 +147,7 @@
 		orr	r2, r2, #7		@ if zero, then no bits here
 		add	r2, r2, #1		@ align bit pointer
 		b	2b			@ loop for next bit
+ENDPROC(_find_next_bit_be)
 
 #endif
 
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
index 2034d4d..6763088 100644
--- a/arch/arm/lib/getuser.S
+++ b/arch/arm/lib/getuser.S
@@ -26,16 +26,16 @@
  * Note that ADDR_LIMIT is either 0 or 0xc0000000.
  * Note also that it is intended that __get_user_bad is not global.
  */
+#include <linux/linkage.h>
 #include <asm/errno.h>
 
-	.global	__get_user_1
-__get_user_1:
+ENTRY(__get_user_1)
 1:	ldrbt	r2, [r0]
 	mov	r0, #0
 	mov	pc, lr
+ENDPROC(__get_user_1)
 
-	.global	__get_user_2
-__get_user_2:
+ENTRY(__get_user_2)
 2:	ldrbt	r2, [r0], #1
 3:	ldrbt	r3, [r0]
 #ifndef __ARMEB__
@@ -45,17 +45,19 @@
 #endif
 	mov	r0, #0
 	mov	pc, lr
+ENDPROC(__get_user_2)
 
-	.global	__get_user_4
-__get_user_4:
+ENTRY(__get_user_4)
 4:	ldrt	r2, [r0]
 	mov	r0, #0
 	mov	pc, lr
+ENDPROC(__get_user_4)
 
 __get_user_bad:
 	mov	r2, #0
 	mov	r0, #-EFAULT
 	mov	pc, lr
+ENDPROC(__get_user_bad)
 
 .section __ex_table, "a"
 	.long	1b, __get_user_bad
diff --git a/arch/arm/lib/io-readsb.S b/arch/arm/lib/io-readsb.S
index fb966ad..9f42389 100644
--- a/arch/arm/lib/io-readsb.S
+++ b/arch/arm/lib/io-readsb.S
@@ -120,3 +120,4 @@
 		strgtb	r3, [r1]
 
 		ldmfd	sp!, {r4 - r6, pc}
+ENDPROC(__raw_readsb)
diff --git a/arch/arm/lib/io-readsl.S b/arch/arm/lib/io-readsl.S
index 75a9121..5fb97e7 100644
--- a/arch/arm/lib/io-readsl.S
+++ b/arch/arm/lib/io-readsl.S
@@ -76,3 +76,4 @@
 8:		mov	r3, ip, get_byte_0
 		strb	r3, [r1, #0]
 		mov	pc, lr
+ENDPROC(__raw_readsl)
diff --git a/arch/arm/lib/io-readsw-armv4.S b/arch/arm/lib/io-readsw-armv4.S
index 4db1c5f..1f393d4 100644
--- a/arch/arm/lib/io-readsw-armv4.S
+++ b/arch/arm/lib/io-readsw-armv4.S
@@ -128,3 +128,4 @@
    _BE_ONLY_(	movne	ip, ip, lsr #24		)
 		strneb	ip, [r1]
 		ldmfd	sp!, {r4, pc}
+ENDPROC(__raw_readsw)
diff --git a/arch/arm/lib/io-writesb.S b/arch/arm/lib/io-writesb.S
index 7eba2b6..68b92f4 100644
--- a/arch/arm/lib/io-writesb.S
+++ b/arch/arm/lib/io-writesb.S
@@ -91,3 +91,4 @@
 		strgtb	r3, [r0]
 
 		ldmfd	sp!, {r4, r5, pc}
+ENDPROC(__raw_writesb)
diff --git a/arch/arm/lib/io-writesl.S b/arch/arm/lib/io-writesl.S
index f8f14dd..8d3b781 100644
--- a/arch/arm/lib/io-writesl.S
+++ b/arch/arm/lib/io-writesl.S
@@ -64,3 +64,4 @@
 		str	ip, [r0]
 		bne	6b
 		mov	pc, lr
+ENDPROC(__raw_writesl)
diff --git a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S
index c8e85bd..d658561 100644
--- a/arch/arm/lib/io-writesw-armv4.S
+++ b/arch/arm/lib/io-writesw-armv4.S
@@ -94,3 +94,4 @@
 3:		movne	ip, r3, lsr #8
 		strneh	ip, [r0]
 		mov	pc, lr
+ENDPROC(__raw_writesw)
diff --git a/arch/arm/lib/lib1funcs.S b/arch/arm/lib/lib1funcs.S
index 4e492f4..67964bc 100644
--- a/arch/arm/lib/lib1funcs.S
+++ b/arch/arm/lib/lib1funcs.S
@@ -230,6 +230,8 @@
 	mov	r0, r0, lsr r2
 	mov	pc, lr
 
+ENDPROC(__udivsi3)
+ENDPROC(__aeabi_uidiv)
 
 ENTRY(__umodsi3)
 
@@ -245,6 +247,7 @@
 
 	mov	pc, lr
 
+ENDPROC(__umodsi3)
 
 ENTRY(__divsi3)
 ENTRY(__aeabi_idiv)
@@ -284,6 +287,8 @@
 	rsbmi	r0, r0, #0
 	mov	pc, lr
 
+ENDPROC(__divsi3)
+ENDPROC(__aeabi_idiv)
 
 ENTRY(__modsi3)
 
@@ -305,6 +310,8 @@
 	rsbmi	r0, r0, #0
 	mov	pc, lr
 
+ENDPROC(__modsi3)
+
 #ifdef CONFIG_AEABI
 
 ENTRY(__aeabi_uidivmod)
@@ -316,6 +323,8 @@
 	sub	r1, r1, r3
 	mov	pc, lr
 
+ENDPROC(__aeabi_uidivmod)
+
 ENTRY(__aeabi_idivmod)
 
 	stmfd	sp!, {r0, r1, ip, lr}
@@ -325,6 +334,8 @@
 	sub	r1, r1, r3
 	mov	pc, lr
 
+ENDPROC(__aeabi_idivmod)
+
 #endif
 
 Ldiv0:
diff --git a/arch/arm/lib/lshrdi3.S b/arch/arm/lib/lshrdi3.S
index a86dbdd..99ea338 100644
--- a/arch/arm/lib/lshrdi3.S
+++ b/arch/arm/lib/lshrdi3.S
@@ -47,3 +47,5 @@
 	mov	ah, ah, lsr r2
 	mov	pc, lr
 
+ENDPROC(__lshrdi3)
+ENDPROC(__aeabi_llsr)
diff --git a/arch/arm/lib/memchr.S b/arch/arm/lib/memchr.S
index e7ab1ea..1da8699 100644
--- a/arch/arm/lib/memchr.S
+++ b/arch/arm/lib/memchr.S
@@ -23,3 +23,4 @@
 	sub	r0, r0, #1
 2:	movne	r0, #0
 	mov	pc, lr
+ENDPROC(memchr)
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
index 7e71d67..e0d0026 100644
--- a/arch/arm/lib/memcpy.S
+++ b/arch/arm/lib/memcpy.S
@@ -57,3 +57,4 @@
 
 #include "copy_template.S"
 
+ENDPROC(memcpy)
diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S
index 2e301b7..1254918 100644
--- a/arch/arm/lib/memmove.S
+++ b/arch/arm/lib/memmove.S
@@ -196,3 +196,4 @@
 
 18:		backward_copy_shift	push=24	pull=8
 
+ENDPROC(memmove)
diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S
index b477d4a..761eefa 100644
--- a/arch/arm/lib/memset.S
+++ b/arch/arm/lib/memset.S
@@ -124,3 +124,4 @@
 	tst	r2, #1
 	strneb	r1, [r0], #1
 	mov	pc, lr
+ENDPROC(memset)
diff --git a/arch/arm/lib/memzero.S b/arch/arm/lib/memzero.S
index b8f79d8..3fbdef5 100644
--- a/arch/arm/lib/memzero.S
+++ b/arch/arm/lib/memzero.S
@@ -122,3 +122,4 @@
 	tst	r1, #1			@ 1 a byte left over
 	strneb	r2, [r0], #1		@ 1
 	mov	pc, lr			@ 1
+ENDPROC(__memzero)
diff --git a/arch/arm/lib/muldi3.S b/arch/arm/lib/muldi3.S
index d89c606..36c91b4 100644
--- a/arch/arm/lib/muldi3.S
+++ b/arch/arm/lib/muldi3.S
@@ -43,3 +43,5 @@
 	adc	xh, xh, ip, lsr #16
 	mov	pc, lr
 
+ENDPROC(__muldi3)
+ENDPROC(__aeabi_lmul)
diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S
index 08ec7df..864f3c1 100644
--- a/arch/arm/lib/putuser.S
+++ b/arch/arm/lib/putuser.S
@@ -26,16 +26,16 @@
  * Note that ADDR_LIMIT is either 0 or 0xc0000000
  * Note also that it is intended that __put_user_bad is not global.
  */
+#include <linux/linkage.h>
 #include <asm/errno.h>
 
-	.global	__put_user_1
-__put_user_1:
+ENTRY(__put_user_1)
 1:	strbt	r2, [r0]
 	mov	r0, #0
 	mov	pc, lr
+ENDPROC(__put_user_1)
 
-	.global	__put_user_2
-__put_user_2:
+ENTRY(__put_user_2)
 	mov	ip, r2, lsr #8
 #ifndef __ARMEB__
 2:	strbt	r2, [r0], #1
@@ -46,23 +46,25 @@
 #endif
 	mov	r0, #0
 	mov	pc, lr
+ENDPROC(__put_user_2)
 
-	.global	__put_user_4
-__put_user_4:
+ENTRY(__put_user_4)
 4:	strt	r2, [r0]
 	mov	r0, #0
 	mov	pc, lr
+ENDPROC(__put_user_4)
 
-	.global	__put_user_8
-__put_user_8:
+ENTRY(__put_user_8)
 5:	strt	r2, [r0], #4
 6:	strt	r3, [r0]
 	mov	r0, #0
 	mov	pc, lr
+ENDPROC(__put_user_8)
 
 __put_user_bad:
 	mov	r0, #-EFAULT
 	mov	pc, lr
+ENDPROC(__put_user_bad)
 
 .section __ex_table, "a"
 	.long	1b, __put_user_bad
diff --git a/arch/arm/lib/setbit.S b/arch/arm/lib/setbit.S
index 83bc23d..1dd7176 100644
--- a/arch/arm/lib/setbit.S
+++ b/arch/arm/lib/setbit.S
@@ -20,3 +20,5 @@
 		eor	r0, r0, #0x18		@ big endian byte ordering
 ENTRY(_set_bit_le)
 	bitop	orr
+ENDPROC(_set_bit_be)
+ENDPROC(_set_bit_le)
diff --git a/arch/arm/lib/sha1.S b/arch/arm/lib/sha1.S
index 67c2bf4..a16fb20 100644
--- a/arch/arm/lib/sha1.S
+++ b/arch/arm/lib/sha1.S
@@ -185,6 +185,8 @@
 
 	ldmfd	sp!, {r4 - r8, pc}
 
+ENDPROC(sha_transform)
+
 .L_sha_K:
 	.word	0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
 
@@ -204,3 +206,4 @@
 	stmia	r0, {r1, r2, r3, ip, lr}
 	ldr	pc, [sp], #4
 
+ENDPROC(sha_init)
diff --git a/arch/arm/lib/strchr.S b/arch/arm/lib/strchr.S
index 9f18d6f..d8f2a1c 100644
--- a/arch/arm/lib/strchr.S
+++ b/arch/arm/lib/strchr.S
@@ -24,3 +24,4 @@
 		movne	r0, #0
 		subeq	r0, r0, #1
 		mov	pc, lr
+ENDPROC(strchr)
diff --git a/arch/arm/lib/strncpy_from_user.S b/arch/arm/lib/strncpy_from_user.S
index 36e3741..330373c 100644
--- a/arch/arm/lib/strncpy_from_user.S
+++ b/arch/arm/lib/strncpy_from_user.S
@@ -31,6 +31,7 @@
 	sub	r1, r1, #1	@ take NUL character out of count
 2:	sub	r0, r1, ip
 	mov	pc, lr
+ENDPROC(__strncpy_from_user)
 
 	.section .fixup,"ax"
 	.align	0
diff --git a/arch/arm/lib/strnlen_user.S b/arch/arm/lib/strnlen_user.S
index 18d8fa4..90bb9d0 100644
--- a/arch/arm/lib/strnlen_user.S
+++ b/arch/arm/lib/strnlen_user.S
@@ -31,6 +31,7 @@
 	add	r0, r0, #1
 2:	sub	r0, r0, r2
 	mov	pc, lr
+ENDPROC(__strnlen_user)
 
 	.section .fixup,"ax"
 	.align	0
diff --git a/arch/arm/lib/strrchr.S b/arch/arm/lib/strrchr.S
index 538df22..302f20c 100644
--- a/arch/arm/lib/strrchr.S
+++ b/arch/arm/lib/strrchr.S
@@ -23,3 +23,4 @@
 		bne	1b
 		mov	r0, r3
 		mov	pc, lr
+ENDPROC(strrchr)
diff --git a/arch/arm/lib/testchangebit.S b/arch/arm/lib/testchangebit.S
index b25dcd2..5c98dc5 100644
--- a/arch/arm/lib/testchangebit.S
+++ b/arch/arm/lib/testchangebit.S
@@ -16,3 +16,5 @@
 		eor	r0, r0, #0x18		@ big endian byte ordering
 ENTRY(_test_and_change_bit_le)
 	testop	eor, strb
+ENDPROC(_test_and_change_bit_be)
+ENDPROC(_test_and_change_bit_le)
diff --git a/arch/arm/lib/testclearbit.S b/arch/arm/lib/testclearbit.S
index 2dcc4b1..543d709 100644
--- a/arch/arm/lib/testclearbit.S
+++ b/arch/arm/lib/testclearbit.S
@@ -16,3 +16,5 @@
 		eor	r0, r0, #0x18		@ big endian byte ordering
 ENTRY(_test_and_clear_bit_le)
 	testop	bicne, strneb
+ENDPROC(_test_and_clear_bit_be)
+ENDPROC(_test_and_clear_bit_le)
diff --git a/arch/arm/lib/testsetbit.S b/arch/arm/lib/testsetbit.S
index 9011c96..0b3f390 100644
--- a/arch/arm/lib/testsetbit.S
+++ b/arch/arm/lib/testsetbit.S
@@ -16,3 +16,5 @@
 		eor	r0, r0, #0x18		@ big endian byte ordering
 ENTRY(_test_and_set_bit_le)
 	testop	orreq, streqb
+ENDPROC(_test_and_set_bit_be)
+ENDPROC(_test_and_set_bit_le)
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S
index b48bd6d..ffdd274 100644
--- a/arch/arm/lib/uaccess.S
+++ b/arch/arm/lib/uaccess.S
@@ -277,6 +277,7 @@
 		ldrgtb	r3, [r1], #0
 USER(		strgtbt	r3, [r0], #1)			@ May fault
 		b	.Lc2u_finished
+ENDPROC(__copy_to_user)
 
 		.section .fixup,"ax"
 		.align	0
@@ -542,6 +543,7 @@
 USER(		ldrgtbt	r3, [r1], #1)			@ May fault
 		strgtb	r3, [r0], #1
 		b	.Lcfu_finished
+ENDPROC(__copy_from_user)
 
 		.section .fixup,"ax"
 		.align	0
diff --git a/arch/arm/lib/ucmpdi2.S b/arch/arm/lib/ucmpdi2.S
index f76de07..f0df6a91 100644
--- a/arch/arm/lib/ucmpdi2.S
+++ b/arch/arm/lib/ucmpdi2.S
@@ -33,6 +33,8 @@
 	movhi	r0, #2
 	mov	pc, lr
 
+ENDPROC(__ucmpdi2)
+
 #ifdef CONFIG_AEABI
 
 ENTRY(__aeabi_ulcmp)
@@ -44,5 +46,7 @@
 	movhi	r0, #1
 	mov	pc, lr
 
+ENDPROC(__aeabi_ulcmp)
+
 #endif
 
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index a048b92..5aafb2e 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -175,6 +175,15 @@
 	  Select this if you are using Olimex's SAM9-L9260 board based on the Atmel AT91SAM9260.
 	  <http://www.olimex.com/dev/sam9-L9260.html>
 
+config MACH_AFEB9260
+	bool "Custom afeb9260 board v1"
+	depends on ARCH_AT91SAM9260
+	help
+	  Select this if you are using custom afeb9260 board based on
+	  open hardware design. Select this for revision 1 of the board.
+	  <svn://194.85.238.22/home/users/george/svn/arm9eb>
+	  <http://groups.google.com/group/arm9fpga-evolution-board>
+
 config MACH_USB_A9260
 	bool "CALAO USB-A9260"
 	depends on ARCH_AT91SAM9260
@@ -314,6 +323,19 @@
 	  Select this if you need to program one or more of the PCK0..PCK3
 	  programmable clock outputs.
 
+config AT91_SLOW_CLOCK
+	bool "Suspend-to-RAM disables main oscillator"
+	depends on SUSPEND
+	help
+	  Select this if you want Suspend-to-RAM to save the most power
+	  possible (without powering off the CPU) by disabling the PLLs
+	  and main oscillator so that only the 32 KiHz clock is available.
+
+	  When only that slow-clock is available, some peripherals lose
+	  functionality.  Many can't issue wakeup events unless faster
+	  clocks are available.  Some lose their operating state and
+	  need to be completely re-initialized.
+
 config AT91_TIMER_HZ
        int "Kernel HZ (jiffies per second)"
        range 32 1024
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 7d641f9..cca612d 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -39,6 +39,7 @@
 obj-$(CONFIG_MACH_SAM9_L9260)	+= board-sam9-l9260.o
 obj-$(CONFIG_MACH_USB_A9260)	+= board-usb-a9260.o
 obj-$(CONFIG_MACH_QIL_A9260)	+= board-qil-a9260.o
+obj-$(CONFIG_MACH_AFEB9260)	+= board-afeb-9260v1.o
 
 # AT91SAM9261 board-specific support
 obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o
@@ -64,6 +65,7 @@
 
 # Power Management
 obj-$(CONFIG_PM)		+= pm.o
+obj-$(CONFIG_AT91_SLOW_CLOCK)	+= pm_slowclock.o
 
 ifeq ($(CONFIG_PM_DEBUG),y)
 CFLAGS_pm.o += -DDEBUG
diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c
index 638948c..0fc0ada 100644
--- a/arch/arm/mach-at91/at91cap9.c
+++ b/arch/arm/mach-at91/at91cap9.c
@@ -141,8 +141,8 @@
 	.pmc_mask	= 1 << AT91CAP9_ID_TCB,
 	.type		= CLK_TYPE_PERIPHERAL,
 };
-static struct clk pwmc_clk = {
-	.name		= "pwmc_clk",
+static struct clk pwm_clk = {
+	.name		= "pwm_clk",
 	.pmc_mask	= 1 << AT91CAP9_ID_PWMC,
 	.type		= CLK_TYPE_PERIPHERAL,
 };
@@ -207,7 +207,7 @@
 	&ssc1_clk,
 	&ac97_clk,
 	&tcb_clk,
-	&pwmc_clk,
+	&pwm_clk,
 	&macb_clk,
 	&aestdes_clk,
 	&adc_clk,
diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c
index abb4aac..5ebd427 100644
--- a/arch/arm/mach-at91/at91cap9_devices.c
+++ b/arch/arm/mach-at91/at91cap9_devices.c
@@ -719,6 +719,60 @@
 
 
 /* --------------------------------------------------------------------
+ *  PWM
+ * --------------------------------------------------------------------*/
+
+#if defined(CONFIG_ATMEL_PWM)
+static u32 pwm_mask;
+
+static struct resource pwm_resources[] = {
+	[0] = {
+		.start	= AT91CAP9_BASE_PWMC,
+		.end	= AT91CAP9_BASE_PWMC + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91CAP9_ID_PWMC,
+		.end	= AT91CAP9_ID_PWMC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91cap9_pwm0_device = {
+	.name	= "atmel_pwm",
+	.id	= -1,
+	.dev	= {
+		.platform_data		= &pwm_mask,
+	},
+	.resource	= pwm_resources,
+	.num_resources	= ARRAY_SIZE(pwm_resources),
+};
+
+void __init at91_add_device_pwm(u32 mask)
+{
+	if (mask & (1 << AT91_PWM0))
+		at91_set_A_periph(AT91_PIN_PB19, 1);	/* enable PWM0 */
+
+	if (mask & (1 << AT91_PWM1))
+		at91_set_B_periph(AT91_PIN_PB8, 1);	/* enable PWM1 */
+
+	if (mask & (1 << AT91_PWM2))
+		at91_set_B_periph(AT91_PIN_PC29, 1);	/* enable PWM2 */
+
+	if (mask & (1 << AT91_PWM3))
+		at91_set_B_periph(AT91_PIN_PA11, 1);	/* enable PWM3 */
+
+	pwm_mask = mask;
+
+	platform_device_register(&at91cap9_pwm0_device);
+}
+#else
+void __init at91_add_device_pwm(u32 mask) {}
+#endif
+
+
+
+/* --------------------------------------------------------------------
  *  AC97
  * -------------------------------------------------------------------- */
 
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 80bfab5..ada4b67 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -129,8 +129,8 @@
 	.pmc_mask	= 1 << AT91SAM9263_ID_TCB,
 	.type		= CLK_TYPE_PERIPHERAL,
 };
-static struct clk pwmc_clk = {
-	.name		= "pwmc_clk",
+static struct clk pwm_clk = {
+	.name		= "pwm_clk",
 	.pmc_mask	= 1 << AT91SAM9263_ID_PWMC,
 	.type		= CLK_TYPE_PERIPHERAL,
 };
@@ -187,7 +187,7 @@
 	&ssc1_clk,
 	&ac97_clk,
 	&tcb_clk,
-	&pwmc_clk,
+	&pwm_clk,
 	&macb_clk,
 	&twodge_clk,
 	&udc_clk,
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index c93992f..8b88408 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -886,6 +886,59 @@
 
 
 /* --------------------------------------------------------------------
+ *  PWM
+ * --------------------------------------------------------------------*/
+
+#if defined(CONFIG_ATMEL_PWM)
+static u32 pwm_mask;
+
+static struct resource pwm_resources[] = {
+	[0] = {
+		.start	= AT91SAM9263_BASE_PWMC,
+		.end	= AT91SAM9263_BASE_PWMC + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9263_ID_PWMC,
+		.end	= AT91SAM9263_ID_PWMC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9263_pwm0_device = {
+	.name	= "atmel_pwm",
+	.id	= -1,
+	.dev	= {
+		.platform_data		= &pwm_mask,
+	},
+	.resource	= pwm_resources,
+	.num_resources	= ARRAY_SIZE(pwm_resources),
+};
+
+void __init at91_add_device_pwm(u32 mask)
+{
+	if (mask & (1 << AT91_PWM0))
+		at91_set_B_periph(AT91_PIN_PB7, 1);	/* enable PWM0 */
+
+	if (mask & (1 << AT91_PWM1))
+		at91_set_B_periph(AT91_PIN_PB8, 1);	/* enable PWM1 */
+
+	if (mask & (1 << AT91_PWM2))
+		at91_set_B_periph(AT91_PIN_PC29, 1);	/* enable PWM2 */
+
+	if (mask & (1 << AT91_PWM3))
+		at91_set_B_periph(AT91_PIN_PB29, 1);	/* enable PWM3 */
+
+	pwm_mask = mask;
+
+	platform_device_register(&at91sam9263_pwm0_device);
+}
+#else
+void __init at91_add_device_pwm(u32 mask) {}
+#endif
+
+
+/* --------------------------------------------------------------------
  *  SSC -- Synchronous Serial Controller
  * -------------------------------------------------------------------- */
 
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index 556bddf..252e954 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -131,8 +131,8 @@
 	.pmc_mask	= 1 << AT91SAM9RL_ID_TC2,
 	.type		= CLK_TYPE_PERIPHERAL,
 };
-static struct clk pwmc_clk = {
-	.name		= "pwmc_clk",
+static struct clk pwm_clk = {
+	.name		= "pwm_clk",
 	.pmc_mask	= 1 << AT91SAM9RL_ID_PWMC,
 	.type		= CLK_TYPE_PERIPHERAL,
 };
@@ -180,7 +180,7 @@
 	&tc0_clk,
 	&tc1_clk,
 	&tc2_clk,
-	&pwmc_clk,
+	&pwm_clk,
 	&tsc_clk,
 	&dma_clk,
 	&udphs_clk,
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index 6208863..87deb1e 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -527,6 +527,51 @@
 
 
 /* --------------------------------------------------------------------
+ *  Touchscreen
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE)
+static u64 tsadcc_dmamask = DMA_BIT_MASK(32);
+
+static struct resource tsadcc_resources[] = {
+	[0] = {
+		.start	= AT91SAM9RL_BASE_TSC,
+		.end	= AT91SAM9RL_BASE_TSC + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9RL_ID_TSC,
+		.end	= AT91SAM9RL_ID_TSC,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device at91sam9rl_tsadcc_device = {
+	.name		= "atmel_tsadcc",
+	.id		= -1,
+	.dev		= {
+				.dma_mask		= &tsadcc_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= tsadcc_resources,
+	.num_resources	= ARRAY_SIZE(tsadcc_resources),
+};
+
+void __init at91_add_device_tsadcc(void)
+{
+	at91_set_A_periph(AT91_PIN_PA17, 0);	/* AD0_XR */
+	at91_set_A_periph(AT91_PIN_PA18, 0);	/* AD1_XL */
+	at91_set_A_periph(AT91_PIN_PA19, 0);	/* AD2_YT */
+	at91_set_A_periph(AT91_PIN_PA20, 0);	/* AD3_TB */
+
+	platform_device_register(&at91sam9rl_tsadcc_device);
+}
+#else
+void __init at91_add_device_tsadcc(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
  *  RTC
  * -------------------------------------------------------------------- */
 
@@ -592,6 +637,59 @@
 
 
 /* --------------------------------------------------------------------
+ *  PWM
+ * --------------------------------------------------------------------*/
+
+#if defined(CONFIG_ATMEL_PWM)
+static u32 pwm_mask;
+
+static struct resource pwm_resources[] = {
+	[0] = {
+		.start	= AT91SAM9RL_BASE_PWMC,
+		.end	= AT91SAM9RL_BASE_PWMC + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9RL_ID_PWMC,
+		.end	= AT91SAM9RL_ID_PWMC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9rl_pwm0_device = {
+	.name	= "atmel_pwm",
+	.id	= -1,
+	.dev	= {
+		.platform_data		= &pwm_mask,
+	},
+	.resource	= pwm_resources,
+	.num_resources	= ARRAY_SIZE(pwm_resources),
+};
+
+void __init at91_add_device_pwm(u32 mask)
+{
+	if (mask & (1 << AT91_PWM0))
+		at91_set_B_periph(AT91_PIN_PB8, 1);	/* enable PWM0 */
+
+	if (mask & (1 << AT91_PWM1))
+		at91_set_B_periph(AT91_PIN_PB9, 1);	/* enable PWM1 */
+
+	if (mask & (1 << AT91_PWM2))
+		at91_set_B_periph(AT91_PIN_PD5, 1);	/* enable PWM2 */
+
+	if (mask & (1 << AT91_PWM3))
+		at91_set_B_periph(AT91_PIN_PD8, 1);	/* enable PWM3 */
+
+	pwm_mask = mask;
+
+	platform_device_register(&at91sam9rl_pwm0_device);
+}
+#else
+void __init at91_add_device_pwm(u32 mask) {}
+#endif
+
+
+/* --------------------------------------------------------------------
  *  SSC -- Synchronous Serial Controller
  * -------------------------------------------------------------------- */
 
diff --git a/arch/arm/mach-at91/at91x40_time.c b/arch/arm/mach-at91/at91x40_time.c
index 869b5e2..dfff289 100644
--- a/arch/arm/mach-at91/at91x40_time.c
+++ b/arch/arm/mach-at91/at91x40_time.c
@@ -23,8 +23,8 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/time.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/mach/time.h>
 #include <mach/at91_tc.h>
 
diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c
new file mode 100644
index 0000000..9c040c7
--- /dev/null
+++ b/arch/arm/mach-at91/board-afeb-9260v1.c
@@ -0,0 +1,210 @@
+/*
+ * linux/arch/arm/mach-at91/board-afeb-9260v1.c
+ *
+ *  Copyright (C) 2005 SAN People
+ *  Copyright (C) 2006 Atmel
+ *  Copyright (C) 2008 Sergey Lapin
+ *
+ * A custom board designed as open hardware; PCBs and various information
+ * is available at http://groups.google.com/group/arm9fpga-evolution-board/
+ * Subversion repository: svn://194.85.238.22/home/users/george/svn/arm9eb
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+
+#include "generic.h"
+
+
+static void __init afeb9260_map_io(void)
+{
+	/* Initialize processor: 18.432 MHz crystal */
+	at91sam9260_initialize(18432000);
+
+	/* DGBU on ttyS0. (Rx & Tx only) */
+	at91_register_uart(0, 0, 0);
+
+	/* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+	at91_register_uart(AT91SAM9260_ID_US0, 1,
+			     ATMEL_UART_CTS | ATMEL_UART_RTS
+			   | ATMEL_UART_DTR | ATMEL_UART_DSR
+			   | ATMEL_UART_DCD | ATMEL_UART_RI);
+
+	/* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
+	at91_register_uart(AT91SAM9260_ID_US1, 2,
+			ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+	/* set serial console to ttyS0 (ie, DBGU) */
+	at91_set_serial_console(0);
+}
+
+static void __init afeb9260_init_irq(void)
+{
+	at91sam9260_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata afeb9260_usbh_data = {
+	.ports		= 1,
+};
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata afeb9260_udc_data = {
+	.vbus_pin	= AT91_PIN_PC5,
+	.pullup_pin	= 0,		/* pull-up driven by UDC */
+};
+
+
+
+/*
+ * SPI devices.
+ */
+static struct spi_board_info afeb9260_spi_devices[] = {
+	{	/* DataFlash chip */
+		.modalias	= "mtd_dataflash",
+		.chip_select	= 1,
+		.max_speed_hz	= 15 * 1000 * 1000,
+		.bus_num	= 0,
+	},
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata afeb9260_macb_data = {
+	.phy_irq_pin	= AT91_PIN_PA9,
+	.is_rmii	= 0,
+};
+
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata afeb9260_nand_partition[] = {
+	{
+		.name	= "bootloader",
+		.offset	= 0,
+		.size	= (640 * SZ_1K),
+	},
+	{
+		.name	= "kernel",
+		.offset	= MTDPART_OFS_NXTBLK,
+		.size	= SZ_2M,
+	},
+	{
+		.name	= "rootfs",
+		.offset	= MTDPART_OFS_NXTBLK,
+		.size	= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+	*num_partitions = ARRAY_SIZE(afeb9260_nand_partition);
+	return afeb9260_nand_partition;
+}
+
+static struct atmel_nand_data __initdata afeb9260_nand_data = {
+	.ale		= 21,
+	.cle		= 22,
+	.rdy_pin	= AT91_PIN_PC13,
+	.enable_pin	= AT91_PIN_PC14,
+	.partition_info	= nand_partitions,
+	.bus_width_16	= 0,
+};
+
+
+/*
+ * MCI (SD/MMC)
+ */
+static struct at91_mmc_data __initdata afeb9260_mmc_data = {
+	.slot_b		= 1,
+	.wire4		= 1,
+};
+
+
+
+static struct i2c_board_info __initdata afeb9260_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("fm3130", 0x68),
+		I2C_BOARD_INFO("24c64", 0x50),
+	},
+};
+
+static void __init afeb9260_board_init(void)
+{
+	/* Serial */
+	at91_add_device_serial();
+	/* USB Host */
+	at91_add_device_usbh(&afeb9260_usbh_data);
+	/* USB Device */
+	at91_add_device_udc(&afeb9260_udc_data);
+	/* SPI */
+	at91_add_device_spi(afeb9260_spi_devices,
+			ARRAY_SIZE(afeb9260_spi_devices));
+	/* NAND */
+	at91_add_device_nand(&afeb9260_nand_data);
+	/* Ethernet */
+	at91_add_device_eth(&afeb9260_macb_data);
+
+	/* Standard function's pin assignments are not
+	 * appropriate for us and generic code provide
+	 * no API to configure these pins any other way */
+	at91_set_B_periph(AT91_PIN_PA10, 0);	/* ETX2 */
+	at91_set_B_periph(AT91_PIN_PA11, 0);	/* ETX3 */
+	/* MMC */
+	at91_add_device_mmc(0, &afeb9260_mmc_data);
+	/* I2C */
+	at91_add_device_i2c(afeb9260_i2c_devices,
+			ARRAY_SIZE(afeb9260_i2c_devices));
+}
+
+MACHINE_START(AFEB9260, "Custom afeb9260 board")
+	/* Maintainer: Sergey Lapin <slapin@ossfans.org> */
+	.phys_io	= AT91_BASE_SYS,
+	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+	.boot_params	= AT91_SDRAM_BASE + 0x100,
+	.timer		= &at91sam926x_timer,
+	.map_io		= afeb9260_map_io,
+	.init_irq	= afeb9260_init_irq,
+	.init_machine	= afeb9260_board_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c
index 1961995..201b893 100644
--- a/arch/arm/mach-at91/board-cap9adk.c
+++ b/arch/arm/mach-at91/board-cap9adk.c
@@ -214,7 +214,7 @@
 };
 
 #define NOR_BASE	AT91_CHIPSELECT_0
-#define NOR_SIZE	0x800000
+#define NOR_SIZE	SZ_8M
 
 static struct resource nor_flash_resources[] = {
 	{
diff --git a/arch/arm/mach-at91/board-carmeva.c b/arch/arm/mach-at91/board-carmeva.c
index afa1ff0..db1f954 100644
--- a/arch/arm/mach-at91/board-carmeva.c
+++ b/arch/arm/mach-at91/board-carmeva.c
@@ -25,7 +25,6 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
-#include <mach/hardware.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/irq.h>
@@ -34,6 +33,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <mach/hardware.h>
 #include <mach/board.h>
 #include <mach/gpio.h>
 
@@ -114,6 +114,30 @@
 	},
 };
 
+static struct gpio_led carmeva_leds[] = {
+	{ /* "user led 1", LED9 */
+		.name			= "led9",
+		.gpio			= AT91_PIN_PA21,
+		.active_low		= 1,
+		.default_trigger	= "heartbeat",
+	},
+	{ /* "user led 2", LED10 */
+		.name			= "led10",
+		.gpio			= AT91_PIN_PA25,
+		.active_low		= 1,
+	},
+	{ /* "user led 3", LED11 */
+		.name			= "led11",
+		.gpio			= AT91_PIN_PA26,
+		.active_low		= 1,
+	},
+	{ /* "user led 4", LED12 */
+		.name			= "led12",
+		.gpio			= AT91_PIN_PA18,
+		.active_low		= 1,
+	}
+};
+
 static void __init carmeva_board_init(void)
 {
 	/* Serial */
@@ -132,6 +156,8 @@
 //	at91_add_device_cf(&carmeva_cf_data);
 	/* MMC */
 	at91_add_device_mmc(0, &carmeva_mmc_data);
+	/* LEDs */
+	at91_gpio_leds(carmeva_leds, ARRAY_SIZE(carmeva_leds));
 }
 
 MACHINE_START(CARMEVA, "Carmeva")
diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c
index cb7c9a8..fea2529 100644
--- a/arch/arm/mach-at91/board-csb337.c
+++ b/arch/arm/mach-at91/board-csb337.c
@@ -28,7 +28,6 @@
 #include <linux/input.h>
 #include <linux/gpio_keys.h>
 
-#include <mach/hardware.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/irq.h>
@@ -37,6 +36,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <mach/hardware.h>
 #include <mach/board.h>
 #include <mach/gpio.h>
 
@@ -114,7 +114,7 @@
 };
 
 #define CSB_FLASH_BASE	AT91_CHIPSELECT_0
-#define CSB_FLASH_SIZE	0x800000
+#define CSB_FLASH_SIZE	SZ_8M
 
 static struct mtd_partition csb_flash_partitions[] = {
 	{
@@ -193,11 +193,11 @@
 
 static void __init csb300_add_device_buttons(void)
 {
-	at91_set_gpio_input(AT91_PIN_PB29, 0);	/* sw0 */
+	at91_set_gpio_input(AT91_PIN_PB29, 1);	/* sw0 */
 	at91_set_deglitch(AT91_PIN_PB29, 1);
-	at91_set_gpio_input(AT91_PIN_PB28, 0);	/* sw1 */
+	at91_set_gpio_input(AT91_PIN_PB28, 1);	/* sw1 */
 	at91_set_deglitch(AT91_PIN_PB28, 1);
-	at91_set_gpio_input(AT91_PIN_PA21, 0);	/* sw2 */
+	at91_set_gpio_input(AT91_PIN_PA21, 1);	/* sw2 */
 	at91_set_deglitch(AT91_PIN_PA21, 1);
 
 	platform_device_register(&csb300_button_device);
@@ -224,7 +224,7 @@
 		.gpio			= AT91_PIN_PB0,
 		.active_low		= 1,
 		.default_trigger	= "ide-disk",
-	},
+	}
 };
 
 
diff --git a/arch/arm/mach-at91/board-csb637.c b/arch/arm/mach-at91/board-csb637.c
index 8db8bd8..cfa3f04 100644
--- a/arch/arm/mach-at91/board-csb637.c
+++ b/arch/arm/mach-at91/board-csb637.c
@@ -25,7 +25,6 @@
 #include <linux/platform_device.h>
 #include <linux/mtd/physmap.h>
 
-#include <mach/hardware.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/irq.h>
@@ -34,6 +33,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <mach/hardware.h>
 #include <mach/board.h>
 #include <mach/gpio.h>
 
@@ -72,7 +72,7 @@
 };
 
 #define CSB_FLASH_BASE	AT91_CHIPSELECT_0
-#define CSB_FLASH_SIZE	0x1000000
+#define CSB_FLASH_SIZE	SZ_16M
 
 static struct mtd_partition csb_flash_partitions[] = {
 	{
diff --git a/arch/arm/mach-at91/board-dk.c b/arch/arm/mach-at91/board-dk.c
index 43e1aa7..0fd0f5b 100644
--- a/arch/arm/mach-at91/board-dk.c
+++ b/arch/arm/mach-at91/board-dk.c
@@ -29,7 +29,6 @@
 #include <linux/spi/spi.h>
 #include <linux/mtd/physmap.h>
 
-#include <mach/hardware.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/irq.h>
@@ -38,6 +37,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <mach/hardware.h>
 #include <mach/board.h>
 #include <mach/gpio.h>
 #include <mach/at91rm9200_mc.h>
@@ -157,7 +157,7 @@
 };
 
 #define DK_FLASH_BASE	AT91_CHIPSELECT_0
-#define DK_FLASH_SIZE	0x200000
+#define DK_FLASH_SIZE	SZ_2M
 
 static struct physmap_flash_data dk_flash_data = {
 	.width		= 2,
diff --git a/arch/arm/mach-at91/board-ecbat91.c b/arch/arm/mach-at91/board-ecbat91.c
index bfeee8a2..1d69908 100644
--- a/arch/arm/mach-at91/board-ecbat91.c
+++ b/arch/arm/mach-at91/board-ecbat91.c
@@ -86,7 +86,7 @@
 	{	/* 0x8400 */
 		.name	= "Darrell-loader",
 		.offset	= 0,
-		.size	= 12* 1056,
+		.size	= 12 * 1056,
 	},
 	{
 		.name	= "U-boot",
diff --git a/arch/arm/mach-at91/board-ek.c b/arch/arm/mach-at91/board-ek.c
index 60626e7..4cdfaac 100644
--- a/arch/arm/mach-at91/board-ek.c
+++ b/arch/arm/mach-at91/board-ek.c
@@ -29,7 +29,6 @@
 #include <linux/spi/spi.h>
 #include <linux/mtd/physmap.h>
 
-#include <mach/hardware.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/irq.h>
@@ -38,6 +37,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <mach/hardware.h>
 #include <mach/board.h>
 #include <mach/gpio.h>
 #include <mach/at91rm9200_mc.h>
@@ -116,7 +116,7 @@
 };
 
 #define EK_FLASH_BASE	AT91_CHIPSELECT_0
-#define EK_FLASH_SIZE	0x200000
+#define EK_FLASH_SIZE	SZ_2M
 
 static struct physmap_flash_data ek_flash_data = {
 	.width		= 2,
diff --git a/arch/arm/mach-at91/board-picotux200.c b/arch/arm/mach-at91/board-picotux200.c
index dbc912d..859727e 100644
--- a/arch/arm/mach-at91/board-picotux200.c
+++ b/arch/arm/mach-at91/board-picotux200.c
@@ -105,7 +105,7 @@
 // };
 
 #define PICOTUX200_FLASH_BASE	AT91_CHIPSELECT_0
-#define PICOTUX200_FLASH_SIZE	0x400000
+#define PICOTUX200_FLASH_SIZE	SZ_4M
 
 static struct physmap_flash_data picotux200_flash_data = {
 	.width	= 2,
diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c
index 4c28413..cfb4571 100644
--- a/arch/arm/mach-at91/board-qil-a9260.c
+++ b/arch/arm/mach-at91/board-qil-a9260.c
@@ -30,7 +30,6 @@
 #include <linux/input.h>
 #include <linux/clk.h>
 
-#include <mach/hardware.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/irq.h>
@@ -39,6 +38,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <mach/hardware.h>
 #include <mach/board.h>
 #include <mach/gpio.h>
 #include <mach/at91_shdwc.h>
@@ -119,18 +119,18 @@
 static struct mtd_partition __initdata ek_nand_partition[] = {
 	{
 		.name	= "Uboot & Kernel",
-		.offset	= 0x00000000,
-		.size	= 16 * 1024 * 1024,
+		.offset	= 0,
+		.size	= SZ_16M,
 	},
 	{
 		.name	= "Root FS",
-		.offset	= 0x01000000,
-		.size	= 120 * 1024 * 1024,
+		.offset	= MTDPART_OFS_NXTBLK,
+		.size	= 120 * SZ_1M,
 	},
 	{
 		.name	= "FS",
-		.offset	= 0x08800000,
-		.size	= 120 * 1024 * 1024,
+		.offset	= MTDPART_OFS_NXTBLK,
+		.size	= 120 * SZ_1M,
 	},
 };
 
diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c
index e4910cb..99bb4cc 100644
--- a/arch/arm/mach-at91/board-sam9-l9260.c
+++ b/arch/arm/mach-at91/board-sam9-l9260.c
@@ -126,11 +126,11 @@
 	{
 		.name	= "Bootloader Area",
 		.offset	= 0,
-		.size	= 10 * 1024 * 1024,
+		.size	= 10 * SZ_1M,
 	},
 	{
 		.name	= "User Area",
-		.offset	= 10 * 1024 * 1024,
+		.offset	= MTDPART_OFS_NXTBLK,
 		.size	= MTDPART_SIZ_FULL,
 	},
 };
diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c
index cb20e70..b49eb6e 100644
--- a/arch/arm/mach-at91/board-sam9260ek.c
+++ b/arch/arm/mach-at91/board-sam9260ek.c
@@ -27,8 +27,10 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/at73c213.h>
 #include <linux/clk.h>
+#include <linux/i2c/at24.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
 
-#include <mach/hardware.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/irq.h>
@@ -37,6 +39,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <mach/hardware.h>
 #include <mach/board.h>
 #include <mach/gpio.h>
 
@@ -163,11 +166,11 @@
 	{
 		.name	= "Partition 1",
 		.offset	= 0,
-		.size	= 256 * 1024,
+		.size	= SZ_256K,
 	},
 	{
 		.name	= "Partition 2",
-		.offset	= 256 * 1024,
+		.offset	= MTDPART_OFS_NXTBLK,
 		.size	= MTDPART_SIZ_FULL,
 	},
 };
@@ -222,6 +225,73 @@
 	}
 };
 
+/*
+ * I2C devices
+ */
+static struct at24_platform_data at24c512 = {
+	.byte_len	= SZ_512K / 8,
+	.page_size	= 128,
+	.flags		= AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info __initdata ek_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("24c512", 0x50),
+		.platform_data = &at24c512,
+	},
+	/* more devices can be added using expansion connectors */
+};
+
+
+/*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button ek_buttons[] = {
+	{
+		.gpio		= AT91_PIN_PA30,
+		.code		= BTN_3,
+		.desc		= "Button 3",
+		.active_low	= 1,
+		.wakeup		= 1,
+	},
+	{
+		.gpio		= AT91_PIN_PA31,
+		.code		= BTN_4,
+		.desc		= "Button 4",
+		.active_low	= 1,
+		.wakeup		= 1,
+	}
+};
+
+static struct gpio_keys_platform_data ek_button_data = {
+	.buttons	= ek_buttons,
+	.nbuttons	= ARRAY_SIZE(ek_buttons),
+};
+
+static struct platform_device ek_button_device = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.num_resources	= 0,
+	.dev		= {
+		.platform_data	= &ek_button_data,
+	}
+};
+
+static void __init ek_add_device_buttons(void)
+{
+	at91_set_gpio_input(AT91_PIN_PA30, 1);	/* btn3 */
+	at91_set_deglitch(AT91_PIN_PA30, 1);
+	at91_set_gpio_input(AT91_PIN_PA31, 1);	/* btn4 */
+	at91_set_deglitch(AT91_PIN_PA31, 1);
+
+	platform_device_register(&ek_button_device);
+}
+#else
+static void __init ek_add_device_buttons(void) {}
+#endif
+
+
 static void __init ek_board_init(void)
 {
 	/* Serial */
@@ -239,12 +309,14 @@
 	/* MMC */
 	at91_add_device_mmc(0, &ek_mmc_data);
 	/* I2C */
-	at91_add_device_i2c(NULL, 0);
+	at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
 	/* SSC (to AT73C213) */
 	at73c213_set_clk(&at73c213_data);
 	at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX);
 	/* LEDs */
 	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+	/* Push Buttons */
+	ek_add_device_buttons();
 }
 
 MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK")
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index 1a9963b8..4977409 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -35,7 +35,6 @@
 
 #include <video/atmel_lcdc.h>
 
-#include <mach/hardware.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/irq.h>
@@ -44,6 +43,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <mach/hardware.h>
 #include <mach/board.h>
 #include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
@@ -168,11 +168,11 @@
 	{
 		.name	= "Partition 1",
 		.offset	= 0,
-		.size	= 256 * 1024,
+		.size	= SZ_256K,
 	},
 	{
 		.name	= "Partition 2",
-		.offset	= 256 * 1024 ,
+		.offset	= MTDPART_OFS_NXTBLK,
 		.size	= MTDPART_SIZ_FULL,
 	},
 };
@@ -435,24 +435,28 @@
 		.code		= BTN_0,
 		.desc		= "Button 0",
 		.active_low	= 1,
+		.wakeup		= 1,
 	},
 	{
 		.gpio		= AT91_PIN_PA26,
 		.code		= BTN_1,
 		.desc		= "Button 1",
 		.active_low	= 1,
+		.wakeup		= 1,
 	},
 	{
 		.gpio		= AT91_PIN_PA25,
 		.code		= BTN_2,
 		.desc		= "Button 2",
 		.active_low	= 1,
+		.wakeup		= 1,
 	},
 	{
 		.gpio		= AT91_PIN_PA24,
 		.code		= BTN_3,
 		.desc		= "Button 3",
 		.active_low	= 1,
+		.wakeup		= 1,
 	}
 };
 
@@ -472,13 +476,13 @@
 
 static void __init ek_add_device_buttons(void)
 {
-	at91_set_gpio_input(AT91_PIN_PA27, 0);	/* btn0 */
+	at91_set_gpio_input(AT91_PIN_PA27, 1);	/* btn0 */
 	at91_set_deglitch(AT91_PIN_PA27, 1);
-	at91_set_gpio_input(AT91_PIN_PA26, 0);	/* btn1 */
+	at91_set_gpio_input(AT91_PIN_PA26, 1);	/* btn1 */
 	at91_set_deglitch(AT91_PIN_PA26, 1);
-	at91_set_gpio_input(AT91_PIN_PA25, 0);	/* btn2 */
+	at91_set_gpio_input(AT91_PIN_PA25, 1);	/* btn2 */
 	at91_set_deglitch(AT91_PIN_PA25, 1);
-	at91_set_gpio_input(AT91_PIN_PA24, 0);	/* btn3 */
+	at91_set_gpio_input(AT91_PIN_PA24, 1);	/* btn3 */
 	at91_set_deglitch(AT91_PIN_PA24, 1);
 
 	platform_device_register(&ek_button_device);
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index b1d1196..8354015 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -26,13 +26,14 @@
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
+#include <linux/i2c/at24.h>
 #include <linux/fb.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
+#include <linux/leds.h>
 
 #include <video/atmel_lcdc.h>
 
-#include <mach/hardware.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/irq.h>
@@ -41,6 +42,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <mach/hardware.h>
 #include <mach/board.h>
 #include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
@@ -172,11 +174,11 @@
 	{
 		.name	= "Partition 1",
 		.offset	= 0,
-		.size	= 64 * 1024 * 1024,
+		.size	= SZ_64M,
 	},
 	{
 		.name	= "Partition 2",
-		.offset	= 64 * 1024 * 1024,
+		.offset	= MTDPART_OFS_NXTBLK,
 		.size	= MTDPART_SIZ_FULL,
 	},
 };
@@ -203,12 +205,30 @@
 
 
 /*
+ * I2C devices
+ */
+static struct at24_platform_data at24c512 = {
+	.byte_len	= SZ_512K / 8,
+	.page_size	= 128,
+	.flags		= AT24_FLAG_ADDR16,
+};
+
+
+static struct i2c_board_info __initdata ek_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("24c512", 0x50),
+		.platform_data = &at24c512,
+	},
+	/* more devices can be added using expansion connectors */
+};
+
+/*
  * LCD Controller
  */
 #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
 static struct fb_videomode at91_tft_vga_modes[] = {
 	{
-	        .name           = "TX09D50VM1CCA @ 60",
+		.name		= "TX09D50VM1CCA @ 60",
 		.refresh	= 60,
 		.xres		= 240,		.yres		= 320,
 		.pixclock	= KHZ2PICOS(4965),
@@ -224,7 +244,7 @@
 
 static struct fb_monspecs at91fb_default_monspecs = {
 	.manufacturer	= "HIT",
-	.monitor        = "TX09D70VM1CCA",
+	.monitor	= "TX09D70VM1CCA",
 
 	.modedb		= at91_tft_vga_modes,
 	.modedb_len	= ARRAY_SIZE(at91_tft_vga_modes),
@@ -235,7 +255,7 @@
 };
 
 #define AT91SAM9263_DEFAULT_LCDCON2 	(ATMEL_LCDC_MEMOR_LITTLE \
-					| ATMEL_LCDC_DISTYPE_TFT    \
+					| ATMEL_LCDC_DISTYPE_TFT \
 					| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
 
 static void at91_lcdc_power_control(int on)
@@ -277,7 +297,7 @@
 		.active_low	= 1,
 		.desc		= "right_click",
 		.wakeup		= 1,
-	},
+	}
 };
 
 static struct gpio_keys_platform_data ek_button_data = {
@@ -296,9 +316,9 @@
 
 static void __init ek_add_device_buttons(void)
 {
-	at91_set_GPIO_periph(AT91_PIN_PC5, 0);	/* left button */
+	at91_set_GPIO_periph(AT91_PIN_PC5, 1);	/* left button */
 	at91_set_deglitch(AT91_PIN_PC5, 1);
-	at91_set_GPIO_periph(AT91_PIN_PC4, 0);	/* right button */
+	at91_set_GPIO_periph(AT91_PIN_PC4, 1);	/* right button */
 	at91_set_deglitch(AT91_PIN_PC4, 1);
 
 	platform_device_register(&ek_button_device);
@@ -320,25 +340,32 @@
  * LEDs ... these could all be PWM-driven, for variable brightness
  */
 static struct gpio_led ek_leds[] = {
-	{	/* "left" led, green, userled1, pwm1 */
-		.name			= "ds1",
-		.gpio			= AT91_PIN_PB8,
-		.active_low		= 1,
-		.default_trigger	= "mmc0",
-	},
-	{	/* "right" led, green, userled2, pwm2 */
+	{	/* "right" led, green, userled2 (could be driven by pwm2) */
 		.name			= "ds2",
 		.gpio			= AT91_PIN_PC29,
 		.active_low		= 1,
 		.default_trigger	= "nand-disk",
 	},
-	{	/* "power" led, yellow, pwm0 */
+	{	/* "power" led, yellow (could be driven by pwm0) */
 		.name			= "ds3",
 		.gpio			= AT91_PIN_PB7,
 		.default_trigger	= "heartbeat",
 	}
 };
 
+/*
+ * PWM Leds
+ */
+static struct gpio_led ek_pwm_led[] = {
+	/* For now only DS1 is PWM-driven (by pwm1) */
+	{
+		.name			= "ds1",
+		.gpio			= 1,	/* is PWM channel number */
+		.active_low		= 1,
+		.default_trigger	= "none",
+	}
+};
+
 
 static void __init ek_board_init(void)
 {
@@ -360,7 +387,7 @@
 	/* NAND */
 	at91_add_device_nand(&ek_nand_data);
 	/* I2C */
-	at91_add_device_i2c(NULL, 0);
+	at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
 	/* LCD Controller */
 	at91_add_device_lcdc(&ek_lcdc_data);
 	/* Push Buttons */
@@ -369,6 +396,7 @@
 	at91_add_device_ac97(&ek_ac97_data);
 	/* LEDs */
 	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+	at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led));
 }
 
 MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK")
diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c
index d4eba5c..b588ead 100644
--- a/arch/arm/mach-at91/board-sam9g20ek.c
+++ b/arch/arm/mach-at91/board-sam9g20ek.c
@@ -122,16 +122,16 @@
 	{
 		.name   = "Bootstrap",
 		.offset = 0,
-		.size   = 4 * 1024 * 1024,
+		.size   = 4 * SZ_1M,
 	},
 	{
 		.name	= "Partition 1",
-		.offset	= 4 * 1024 * 1024,
-		.size	= 60 * 1024 * 1024,
+		.offset	= MTDPART_OFS_NXTBLK,
+		.size	= 60 * SZ_1M,
 	},
 	{
 		.name	= "Partition 2",
-		.offset	= 64 * 1024 * 1024,
+		.offset	= MTDPART_OFS_NXTBLK,
 		.size	= MTDPART_SIZ_FULL,
 	},
 };
diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c
index c6dce49..2708518 100644
--- a/arch/arm/mach-at91/board-sam9rlek.c
+++ b/arch/arm/mach-at91/board-sam9rlek.c
@@ -18,7 +18,6 @@
 
 #include <video/atmel_lcdc.h>
 
-#include <mach/hardware.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/irq.h>
@@ -27,6 +26,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <mach/hardware.h>
 #include <mach/board.h>
 #include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
@@ -81,11 +81,11 @@
 	{
 		.name	= "Partition 1",
 		.offset	= 0,
-		.size	= 256 * 1024,
+		.size	= SZ_256K,
 	},
 	{
 		.name	= "Partition 2",
-		.offset	= 256 * 1024 ,
+		.offset	= MTDPART_OFS_NXTBLK,
 		.size	= MTDPART_SIZ_FULL,
 	},
 };
@@ -195,6 +195,8 @@
 	at91_add_device_mmc(0, &ek_mmc_data);
 	/* LCD Controller */
 	at91_add_device_lcdc(&ek_lcdc_data);
+	/* Touch Screen Controller */
+	at91_add_device_tsadcc();
 }
 
 MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK")
diff --git a/arch/arm/mach-at91/board-usb-a9260.c b/arch/arm/mach-at91/board-usb-a9260.c
index f9d0b65..7c35035 100644
--- a/arch/arm/mach-at91/board-usb-a9260.c
+++ b/arch/arm/mach-at91/board-usb-a9260.c
@@ -30,7 +30,6 @@
 #include <linux/input.h>
 #include <linux/clk.h>
 
-#include <mach/hardware.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/irq.h>
@@ -39,6 +38,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <mach/hardware.h>
 #include <mach/board.h>
 #include <mach/gpio.h>
 #include <mach/at91_shdwc.h>
@@ -93,18 +93,18 @@
 static struct mtd_partition __initdata ek_nand_partition[] = {
 	{
 		.name	= "Uboot & Kernel",
-		.offset	= 0x00000000,
-		.size	= 16 * 1024 * 1024,
+		.offset	= 0,
+		.size	= SZ_16M,
 	},
 	{
 		.name	= "Root FS",
-		.offset	= 0x01000000,
-		.size	= 120 * 1024 * 1024,
+		.offset	= MTDPART_OFS_NXTBLK,
+		.size	= 120 * SZ_1M,
 	},
 	{
 		.name	= "FS",
-		.offset	= 0x08800000,
-		.size	= 120 * 1024 * 1024,
+		.offset	= MTDPART_OFS_NXTBLK,
+		.size	= 120 * SZ_1M,
 	}
 };
 
diff --git a/arch/arm/mach-at91/board-usb-a9263.c b/arch/arm/mach-at91/board-usb-a9263.c
index 673e5c2..391b566 100644
--- a/arch/arm/mach-at91/board-usb-a9263.c
+++ b/arch/arm/mach-at91/board-usb-a9263.c
@@ -29,7 +29,6 @@
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 
-#include <mach/hardware.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/irq.h>
@@ -38,6 +37,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <mach/hardware.h>
 #include <mach/board.h>
 #include <mach/gpio.h>
 #include <mach/at91_shdwc.h>
@@ -106,18 +106,18 @@
 static struct mtd_partition __initdata ek_nand_partition[] = {
 	{
 		.name	= "Linux Kernel",
-		.offset	= 0x00000000,
-		.size	= 16 * 1024 * 1024,
+		.offset	= 0,
+		.size	= SZ_16M,
 	},
 	{
 		.name	= "Root FS",
-		.offset	= 0x01000000,
-		.size	= 120 * 1024 * 1024,
+		.offset	= MTDPART_OFS_NXTBLK,
+		.size	= 120 * SZ_1M,
 	},
 	{
 		.name	= "FS",
-		.offset	= 0x08800000,
-		.size	= 120 * 1024 * 1024,
+		.offset	= MTDPART_OFS_NXTBLK,
+		.size	= 120 * SZ_1M,
 	}
 };
 
diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c
index 36b380a..e22bf05 100644
--- a/arch/arm/mach-at91/board-yl-9200.c
+++ b/arch/arm/mach-at91/board-yl-9200.c
@@ -33,7 +33,6 @@
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 
-#include <mach/hardware.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/irq.h>
@@ -42,6 +41,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <mach/hardware.h>
 #include <mach/board.h>
 #include <mach/gpio.h>
 #include <mach/at91rm9200_mc.h>
@@ -150,27 +150,27 @@
 	{
 		.name	= "AT91 NAND partition 1, boot",
 		.offset	= 0,
-		.size	= 1 * SZ_256K
+		.size	= SZ_256K
 	},
 	{
 		.name	= "AT91 NAND partition 2, kernel",
-		.offset	= 1 * SZ_256K,
-		.size	= 2 * SZ_1M - 1 * SZ_256K
+		.offset	= MTDPART_OFS_NXTBLK,
+		.size	= (2 * SZ_1M) - SZ_256K
 	},
 	{
 		.name	= "AT91 NAND partition 3, filesystem",
-		.offset	= 2 * SZ_1M,
+		.offset	= MTDPART_OFS_NXTBLK,
 		.size	= 14 * SZ_1M
 	},
 	{
 		.name	= "AT91 NAND partition 4, storage",
-		.offset	= 16 * SZ_1M,
-		.size	= 16 * SZ_1M
+		.offset	= MTDPART_OFS_NXTBLK,
+		.size	= SZ_16M
 	},
 	{
 		.name	= "AT91 NAND partition 5, ext-fs",
-		.offset	= 32 * SZ_1M,
-		.size	= 32 * SZ_1M
+		.offset	= MTDPART_OFS_NXTBLK,
+		.size	= SZ_32M
 	}
 };
 
@@ -193,24 +193,24 @@
  * NOR Flash
  */
 #define YL9200_FLASH_BASE	AT91_CHIPSELECT_0
-#define YL9200_FLASH_SIZE	0x1000000
+#define YL9200_FLASH_SIZE	SZ_16M
 
 static struct mtd_partition yl9200_flash_partitions[] = {
 	{
 		.name		= "Bootloader",
-		.size		= 0x00040000,
 		.offset		= 0,
+		.size		= SZ_256K,
 		.mask_flags	= MTD_WRITEABLE,	/* force read-only */
 	},
 	{
 		.name		= "Kernel",
-		.size		= 0x001C0000,
-		.offset		= 0x00040000,
+		.offset		= MTDPART_OFS_NXTBLK,
+		.size		= (2 * SZ_1M) - SZ_256K
 	},
 	{
 		.name		= "Filesystem",
-		.size		= MTDPART_SIZ_FULL,
-		.offset		= 0x00200000
+		.offset		= MTDPART_OFS_NXTBLK,
+		.size		= MTDPART_SIZ_FULL
 	}
 };
 
@@ -390,10 +390,6 @@
 #if defined(CONFIG_FB_S1D135XX) || defined(CONFIG_FB_S1D13XXX_MODULE)
 #include <video/s1d13xxxfb.h>
 
-#define AT91_FB_REG_BASE	0x80000000L
-#define AT91_FB_REG_SIZE	0x200
-#define AT91_FB_VMEM_BASE	0x80200000L
-#define AT91_FB_VMEM_SIZE	0x200000L
 
 static void __init yl9200_init_video(void)
 {
@@ -516,29 +512,33 @@
 	{S1DREG_COM_DISP_MODE,		0x01},	/* Display Mode Register, LCD only*/
 };
 
-static u64 s1dfb_dmamask = DMA_BIT_MASK(32);
-
 static struct s1d13xxxfb_pdata yl9200_s1dfb_pdata = {
 	.initregs		= yl9200_s1dfb_initregs,
 	.initregssize		= ARRAY_SIZE(yl9200_s1dfb_initregs),
 	.platform_init_video	= yl9200_init_video,
 };
 
+#define YL9200_FB_REG_BASE	AT91_CHIPSELECT_7
+#define YL9200_FB_VMEM_BASE	YL9200_FB_REG_BASE + SZ_2M
+#define YL9200_FB_VMEM_SIZE	SZ_2M
+
 static struct resource yl9200_s1dfb_resource[] = {
 	[0] = {	/* video mem */
 		.name	= "s1d13xxxfb memory",
-		.start	= AT91_FB_VMEM_BASE,
-		.end	= AT91_FB_VMEM_BASE + AT91_FB_VMEM_SIZE -1,
+		.start	= YL9200_FB_VMEM_BASE,
+		.end	= YL9200_FB_VMEM_BASE + YL9200_FB_VMEM_SIZE -1,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {	/* video registers */
 		.name	= "s1d13xxxfb registers",
-		.start	= AT91_FB_REG_BASE,
-		.end	= AT91_FB_REG_BASE + AT91_FB_REG_SIZE -1,
+		.start	= YL9200_FB_REG_BASE,
+		.end	= YL9200_FB_REG_BASE + SZ_512 -1,
 		.flags	= IORESOURCE_MEM,
 	},
 };
 
+static u64 s1dfb_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device yl9200_s1dfb_device = {
 	.name		= "s1d13806fb",
 	.id		= -1,
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index f5c2847..e434510 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -22,8 +22,7 @@
 #include <linux/spinlock.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <mach/at91_pmc.h>
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index 8392d5b..7e5ebb5 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -18,8 +18,8 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <mach/hardware.h>
 #include <mach/at91_pio.h>
 #include <mach/gpio.h>
@@ -404,7 +404,6 @@
 		}
 
 		pin = bank->chipbase;
-		gpio = &irq_desc[pin];
 
 		while (isr) {
 			if (isr & 1) {
@@ -417,7 +416,7 @@
 					gpio_irq_mask(pin);
 				}
 				else
-					desc_handle_irq(pin, gpio);
+					generic_handle_irq(pin);
 			}
 			pin++;
 			gpio++;
diff --git a/arch/arm/mach-at91/include/mach/at91_pit.h b/arch/arm/mach-at91/include/mach/at91_pit.h
index 0448ac3..974d0bd 100644
--- a/arch/arm/mach-at91/include/mach/at91_pit.h
+++ b/arch/arm/mach-at91/include/mach/at91_pit.h
@@ -1,6 +1,9 @@
 /*
  * arch/arm/mach-at91/include/mach/at91_pit.h
  *
+ * Copyright (C) 2007 Andrew Victor
+ * Copyright (C) 2007 Atmel Corporation.
+ *
  * Periodic Interval Timer (PIT) - System peripherals regsters.
  * Based on AT91SAM9261 datasheet revision D.
  *
diff --git a/arch/arm/mach-at91/include/mach/at91_rstc.h b/arch/arm/mach-at91/include/mach/at91_rstc.h
index 7cd1b39..cbd2bf0 100644
--- a/arch/arm/mach-at91/include/mach/at91_rstc.h
+++ b/arch/arm/mach-at91/include/mach/at91_rstc.h
@@ -1,6 +1,9 @@
 /*
  * arch/arm/mach-at91/include/mach/at91_rstc.h
  *
+ * Copyright (C) 2007 Andrew Victor
+ * Copyright (C) 2007 Atmel Corporation.
+ *
  * Reset Controller (RSTC) - System peripherals regsters.
  * Based on AT91SAM9261 datasheet revision D.
  *
diff --git a/arch/arm/mach-at91/include/mach/at91_rtt.h b/arch/arm/mach-at91/include/mach/at91_rtt.h
index 71782e5..7ec75de 100644
--- a/arch/arm/mach-at91/include/mach/at91_rtt.h
+++ b/arch/arm/mach-at91/include/mach/at91_rtt.h
@@ -1,6 +1,9 @@
 /*
  * arch/arm/mach-at91/include/mach/at91_rtt.h
  *
+ * Copyright (C) 2007 Andrew Victor
+ * Copyright (C) 2007 Atmel Corporation.
+ *
  * Real-time Timer (RTT) - System peripherals regsters.
  * Based on AT91SAM9261 datasheet revision D.
  *
diff --git a/arch/arm/mach-at91/include/mach/at91_shdwc.h b/arch/arm/mach-at91/include/mach/at91_shdwc.h
index 60be5ae..c4ce07e 100644
--- a/arch/arm/mach-at91/include/mach/at91_shdwc.h
+++ b/arch/arm/mach-at91/include/mach/at91_shdwc.h
@@ -1,6 +1,9 @@
 /*
  * arch/arm/mach-at91/include/mach/at91_shdwc.h
  *
+ * Copyright (C) 2007 Andrew Victor
+ * Copyright (C) 2007 Atmel Corporation.
+ *
  * Shutdown Controller (SHDWC) - System peripherals regsters.
  * Based on AT91SAM9261 datasheet revision D.
  *
diff --git a/arch/arm/mach-at91/include/mach/at91_wdt.h b/arch/arm/mach-at91/include/mach/at91_wdt.h
index 973b452..fecc2e9 100644
--- a/arch/arm/mach-at91/include/mach/at91_wdt.h
+++ b/arch/arm/mach-at91/include/mach/at91_wdt.h
@@ -1,6 +1,9 @@
 /*
  * arch/arm/mach-at91/include/mach/at91_wdt.h
  *
+ * Copyright (C) 2007 Andrew Victor
+ * Copyright (C) 2007 Atmel Corporation.
+ *
  * Watchdog Timer (WDT) - System peripherals regsters.
  * Based on AT91SAM9261 datasheet revision D.
  *
diff --git a/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
index bca878f..1499b1c 100644
--- a/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
+++ b/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
@@ -1,6 +1,8 @@
 /*
  * arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
  *
+ *  (C) 2008 Andrew Victor
+ *
  * DDR/SDR Controller (DDRSDRC) - System peripherals registers.
  * Based on AT91CAP9 datasheet revision B.
  *
diff --git a/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h
index f027de5..020f02e 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h
@@ -1,6 +1,8 @@
 /*
  * arch/arm/mach-at91/include/mach/at91sam9260_matrix.h
  *
+ *  Copyright (C) 2007 Atmel Corporation.
+ *
  * Memory Controllers (MATRIX, EBI) - System peripherals registers.
  * Based on AT91SAM9260 datasheet revision B.
  *
diff --git a/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h
index db62b1f1..69c6501 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h
@@ -1,6 +1,8 @@
 /*
  * arch/arm/mach-at91/include/mach/at91sam9261_matrix.h
  *
+ *  Copyright (C) 2007 Atmel Corporation.
+ *
  * Memory Controllers (MATRIX, EBI) - System peripherals registers.
  * Based on AT91SAM9261 datasheet revision D.
  *
diff --git a/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h b/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h
index 1921181..b726038 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h
@@ -1,6 +1,9 @@
 /*
  * arch/arm/mach-at91/include/mach/at91sam9_sdramc.h
  *
+ * Copyright (C) 2007 Andrew Victor
+ * Copyright (C) 2007 Atmel Corporation.
+ *
  * SDRAM Controllers (SDRAMC) - System peripherals registers.
  * Based on AT91SAM9261 datasheet revision D.
  *
diff --git a/arch/arm/mach-at91/include/mach/at91sam9_smc.h b/arch/arm/mach-at91/include/mach/at91sam9_smc.h
index ec6ad13..57de620 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9_smc.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9_smc.h
@@ -1,6 +1,9 @@
 /*
  * arch/arm/mach-at91/include/mach/at91sam9_smc.h
  *
+ * Copyright (C) 2007 Andrew Victor
+ * Copyright (C) 2007 Atmel Corporation.
+ *
  * Static Memory Controllers (SMC) - System peripherals registers.
  * Based on AT91SAM9261 datasheet revision D.
  *
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
index acd60f2..fb51f0e 100644
--- a/arch/arm/mach-at91/include/mach/board.h
+++ b/arch/arm/mach-at91/include/mach/board.h
@@ -133,6 +133,16 @@
 extern void __init at91_add_device_serial(void);
 
 /*
+ * PWM
+ */
+#define AT91_PWM0	0
+#define AT91_PWM1	1
+#define AT91_PWM2	2
+#define AT91_PWM3	3
+
+extern void __init at91_add_device_pwm(u32 mask);
+
+/*
  * SSC -- accessed through ssc_request(id).  Drivers don't bind to SSC
  * platform devices.  Their SSC ID is part of their configuration data,
  * along with information about which SSC signals they should use.
@@ -162,9 +172,13 @@
  /* ISI */
 extern void __init at91_add_device_isi(void);
 
+ /* Touchscreen Controller */
+extern void __init at91_add_device_tsadcc(void);
+
  /* LEDs */
 extern void __init at91_init_leds(u8 cpu_led, u8 timer_led);
 extern void __init at91_gpio_leds(struct gpio_led *leds, int nr);
+extern void __init at91_pwm_leds(struct gpio_led *leds, int nr);
 
 /* FIXME: this needs a better location, but gets stuff building again */
 extern int at91_suspend_entering_slow_clock(void);
diff --git a/arch/arm/mach-at91/include/mach/irqs.h b/arch/arm/mach-at91/include/mach/irqs.h
index bda29ccb..36bd55f 100644
--- a/arch/arm/mach-at91/include/mach/irqs.h
+++ b/arch/arm/mach-at91/include/mach/irqs.h
@@ -21,7 +21,7 @@
 #ifndef __ASM_ARCH_IRQS_H
 #define __ASM_ARCH_IRQS_H
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <mach/at91_aic.h>
 
 #define NR_AIC_IRQS 32
diff --git a/arch/arm/mach-at91/include/mach/uncompress.h b/arch/arm/mach-at91/include/mach/uncompress.h
index 0410d54..18bdcde 100644
--- a/arch/arm/mach-at91/include/mach/uncompress.h
+++ b/arch/arm/mach-at91/include/mach/uncompress.h
@@ -21,7 +21,7 @@
 #ifndef __ASM_ARCH_UNCOMPRESS_H
 #define __ASM_ARCH_UNCOMPRESS_H
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/atmel_serial.h>
 
 #if defined(CONFIG_AT91_EARLY_DBGU)
diff --git a/arch/arm/mach-at91/leds.c b/arch/arm/mach-at91/leds.c
index fec03c5..0415a839 100644
--- a/arch/arm/mach-at91/leds.c
+++ b/arch/arm/mach-at91/leds.c
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/platform_device.h>
 
 #include <mach/board.h>
 #include <mach/gpio.h>
@@ -21,15 +22,13 @@
 
 #if defined(CONFIG_NEW_LEDS)
 
-#include <linux/platform_device.h>
-
 /*
  * New cross-platform LED support.
  */
 
 static struct gpio_led_platform_data led_data;
 
-static struct platform_device at91_leds = {
+static struct platform_device at91_gpio_leds_device = {
 	.name			= "leds-gpio",
 	.id			= -1,
 	.dev.platform_data	= &led_data,
@@ -47,7 +46,7 @@
 
 	led_data.leds = leds;
 	led_data.num_leds = nr;
-	platform_device_register(&at91_leds);
+	platform_device_register(&at91_gpio_leds_device);
 }
 
 #else
@@ -57,6 +56,44 @@
 
 /* ------------------------------------------------------------------------- */
 
+#if defined (CONFIG_LEDS_ATMEL_PWM)
+
+/*
+ * PWM Leds
+ */
+
+static struct gpio_led_platform_data pwm_led_data;
+
+static struct platform_device at91_pwm_leds_device = {
+	.name			= "leds-atmel-pwm",
+	.id			= -1,
+	.dev.platform_data	= &pwm_led_data,
+};
+
+void __init at91_pwm_leds(struct gpio_led *leds, int nr)
+{
+	int i;
+	u32 pwm_mask = 0;
+
+	if (!nr)
+		return;
+
+	for (i = 0; i < nr; i++)
+		pwm_mask |= (1 << leds[i].gpio);
+
+	pwm_led_data.leds = leds;
+	pwm_led_data.num_leds = nr;
+
+	at91_add_device_pwm(pwm_mask);
+	platform_device_register(&at91_pwm_leds_device);
+}
+#else
+void __init at91_pwm_leds(struct gpio_led *leds, int nr){}
+#endif
+
+
+/* ------------------------------------------------------------------------- */
+
 #if defined(CONFIG_LEDS)
 
 #include <asm/leds.h>
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index ec2fe4c..9bb4f04 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -17,8 +17,8 @@
 #include <linux/sysfs.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/atomic.h>
 #include <asm/mach/time.h>
diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S
new file mode 100644
index 0000000..987fab3
--- /dev/null
+++ b/arch/arm/mach-at91/pm_slowclock.S
@@ -0,0 +1,283 @@
+/*
+ * arch/arm/mach-at91/pm_slow_clock.S
+ *
+ *  Copyright (C) 2006 Savin Zlobec
+ *
+ * AT91SAM9 support:
+ *  Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/linkage.h>
+#include <mach/hardware.h>
+#include <mach/at91_pmc.h>
+
+#ifdef CONFIG_ARCH_AT91RM9200
+#include <mach/at91rm9200_mc.h>
+#elif defined(CONFIG_ARCH_AT91CAP9)
+#include <mach/at91cap9_ddrsdr.h>
+#else
+#include <mach/at91sam9_sdramc.h>
+#endif
+
+
+#ifdef CONFIG_ARCH_AT91SAM9263
+/*
+ * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
+ * handle those cases both here and in the Suspend-To-RAM support.
+ */
+#define AT91_SDRAMC	AT91_SDRAMC0
+#warning Assuming EB1 SDRAM controller is *NOT* used
+#endif
+
+/*
+ * When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master
+ * clock during suspend by adjusting its prescalar and divisor.
+ * NOTE: This hasn't been shown to be stable on SAM9s; and on the RM9200 there
+ *       are errata regarding adjusting the prescalar and divisor.
+ */
+#undef SLOWDOWN_MASTER_CLOCK
+
+#define MCKRDY_TIMEOUT		1000
+#define MOSCRDY_TIMEOUT 	1000
+#define PLLALOCK_TIMEOUT	1000
+#define PLLBLOCK_TIMEOUT	1000
+
+
+/*
+ * Wait until master clock is ready (after switching master clock source)
+ */
+	.macro wait_mckrdy
+	mov	r4, #MCKRDY_TIMEOUT
+1:	sub	r4, r4, #1
+	cmp	r4, #0
+	beq	2f
+	ldr	r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
+	tst	r3, #AT91_PMC_MCKRDY
+	beq	1b
+2:
+	.endm
+
+/*
+ * Wait until master oscillator has stabilized.
+ */
+	.macro wait_moscrdy
+	mov	r4, #MOSCRDY_TIMEOUT
+1:	sub	r4, r4, #1
+	cmp	r4, #0
+	beq	2f
+	ldr	r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
+	tst	r3, #AT91_PMC_MOSCS
+	beq	1b
+2:
+	.endm
+
+/*
+ * Wait until PLLA has locked.
+ */
+	.macro wait_pllalock
+	mov	r4, #PLLALOCK_TIMEOUT
+1:	sub	r4, r4, #1
+	cmp	r4, #0
+	beq	2f
+	ldr	r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
+	tst	r3, #AT91_PMC_LOCKA
+	beq	1b
+2:
+	.endm
+
+/*
+ * Wait until PLLB has locked.
+ */
+	.macro wait_pllblock
+	mov	r4, #PLLBLOCK_TIMEOUT
+1:	sub	r4, r4, #1
+	cmp	r4, #0
+	beq	2f
+	ldr	r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
+	tst	r3, #AT91_PMC_LOCKB
+	beq	1b
+2:
+	.endm
+
+	.text
+
+ENTRY(at91_slow_clock)
+	/* Save registers on stack */
+	stmfd	sp!, {r0 - r12, lr}
+
+	/*
+	 * Register usage:
+	 *  R1 = Base address of AT91_PMC
+	 *  R2 = Base address of AT91_SDRAMC (or AT91_SYS on AT91RM9200)
+	 *  R3 = temporary register
+	 *  R4 = temporary register
+	 */
+	ldr	r1, .at91_va_base_pmc
+	ldr	r2, .at91_va_base_sdramc
+
+	/* Drain write buffer */
+	mcr	p15, 0, r0, c7, c10, 4
+
+#ifdef CONFIG_ARCH_AT91RM9200
+	/* Put SDRAM in self-refresh mode */
+	mov	r3, #1
+	str	r3, [r2, #AT91_SDRAMC_SRR]
+#elif defined(CONFIG_ARCH_AT91CAP9)
+	/* Enable SDRAM self-refresh mode */
+	ldr	r3, [r2, #AT91_DDRSDRC_LPR - AT91_DDRSDRC]
+	str	r3, .saved_sam9_lpr
+
+	mov	r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
+	str	r3, [r2, #AT91_DDRSDRC_LPR - AT91_DDRSDRC]
+#else
+	/* Enable SDRAM self-refresh mode */
+	ldr	r3, [r2, #AT91_SDRAMC_LPR - AT91_SDRAMC]
+	str	r3, .saved_sam9_lpr
+
+	mov	r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
+	str	r3, [r2, #AT91_SDRAMC_LPR - AT91_SDRAMC]
+#endif
+
+	/* Save Master clock setting */
+	ldr	r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
+	str	r3, .saved_mckr
+
+	/*
+	 * Set the Master clock source to slow clock
+	 */
+	bic	r3, r3, #AT91_PMC_CSS
+	str	r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
+
+	wait_mckrdy
+
+#ifdef SLOWDOWN_MASTER_CLOCK
+	/*
+	 * Set the Master Clock PRES and MDIV fields.
+	 *
+	 * See AT91RM9200 errata #27 and #28 for details.
+	 */
+	mov	r3, #0
+	str	r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
+
+	wait_mckrdy
+#endif
+
+	/* Save PLLA setting and disable it */
+	ldr	r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
+	str	r3, .saved_pllar
+
+	mov	r3, #AT91_PMC_PLLCOUNT
+	orr	r3, r3, #(1 << 29)		/* bit 29 always set */
+	str	r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
+
+	wait_pllalock
+
+	/* Save PLLB setting and disable it */
+	ldr	r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
+	str	r3, .saved_pllbr
+
+	mov	r3, #AT91_PMC_PLLCOUNT
+	str	r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
+
+	wait_pllblock
+
+	/* Turn off the main oscillator */
+	ldr	r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
+	bic	r3, r3, #AT91_PMC_MOSCEN
+	str	r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
+
+	/* Wait for interrupt */
+	mcr	p15, 0, r0, c7, c0, 4
+
+	/* Turn on the main oscillator */
+	ldr	r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
+	orr	r3, r3, #AT91_PMC_MOSCEN
+	str	r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
+
+	wait_moscrdy
+
+	/* Restore PLLB setting */
+	ldr	r3, .saved_pllbr
+	str	r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
+
+	wait_pllblock
+
+	/* Restore PLLA setting */
+	ldr	r3, .saved_pllar
+	str	r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
+
+	wait_pllalock
+
+#ifdef SLOWDOWN_MASTER_CLOCK
+	/*
+	 * First set PRES if it was not 0,
+	 * than set CSS and MDIV fields.
+	 *
+	 * See AT91RM9200 errata #27 and #28 for details.
+	 */
+	ldr	r3, .saved_mckr
+	tst	r3, #AT91_PMC_PRES
+	beq	2f
+	and	r3, r3, #AT91_PMC_PRES
+	str	r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
+
+	wait_mckrdy
+#endif
+
+	/*
+	 * Restore master clock setting
+	 */
+2:	ldr	r3, .saved_mckr
+	str	r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
+
+	wait_mckrdy
+
+#ifdef CONFIG_ARCH_AT91RM9200
+	/* Do nothing - self-refresh is automatically disabled. */
+#elif defined(CONFIG_ARCH_AT91CAP9)
+	/* Restore LPR on AT91CAP9 */
+	ldr	r3, .saved_sam9_lpr
+	str	r3, [r2, #AT91_DDRSDRC_LPR - AT91_DDRSDRC]
+#else
+	/* Restore LPR on AT91SAM9 */
+	ldr	r3, .saved_sam9_lpr
+	str	r3, [r2, #AT91_SDRAMC_LPR - AT91_SDRAMC]
+#endif
+
+	/* Restore registers, and return */
+	ldmfd	sp!, {r0 - r12, pc}
+
+
+.saved_mckr:
+	.word 0
+
+.saved_pllar:
+	.word 0
+
+.saved_pllbr:
+	.word 0
+
+.saved_sam9_lpr:
+	.word 0
+
+.at91_va_base_pmc:
+	.word AT91_VA_BASE_SYS + AT91_PMC
+
+#ifdef CONFIG_ARCH_AT91RM9200
+.at91_va_base_sdramc:
+	.word AT91_VA_BASE_SYS
+#elif defined(CONFIG_ARCH_AT91CAP9)
+.at91_va_base_sdramc:
+	.word AT91_VA_BASE_SYS + AT91_DDRSDRC
+#else
+.at91_va_base_sdramc:
+	.word AT91_VA_BASE_SYS + AT91_SDRAMC
+#endif
+
+ENTRY(at91_slow_clock_sz)
+	.word .-at91_slow_clock
diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c
index 474616d..5f18ecc 100644
--- a/arch/arm/mach-clps711x/autcpu12.c
+++ b/arch/arm/mach-clps711x/autcpu12.c
@@ -22,10 +22,10 @@
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/mm.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/sizes.h>
-#include <asm/io.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c
index aa02aa5..71a80b5 100644
--- a/arch/arm/mach-clps711x/cdb89712.c
+++ b/arch/arm/mach-clps711x/cdb89712.c
@@ -22,9 +22,9 @@
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/mm.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <asm/setup.h>
diff --git a/arch/arm/mach-clps711x/include/mach/system.h b/arch/arm/mach-clps711x/include/mach/system.h
index a8eade4..24e9615 100644
--- a/arch/arm/mach-clps711x/include/mach/system.h
+++ b/arch/arm/mach-clps711x/include/mach/system.h
@@ -20,9 +20,9 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
+#include <linux/io.h>
 #include <mach/hardware.h>
 #include <asm/hardware/clps7111.h>
-#include <asm/io.h>
 
 static inline void arch_idle(void)
 {
diff --git a/arch/arm/mach-clps711x/irq.c b/arch/arm/mach-clps711x/irq.c
index 38623cf..9a12d85 100644
--- a/arch/arm/mach-clps711x/irq.c
+++ b/arch/arm/mach-clps711x/irq.c
@@ -19,10 +19,10 @@
  */
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/io.h>
 
 #include <asm/mach/irq.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 
 #include <asm/hardware/clps7111.h>
diff --git a/arch/arm/mach-clps711x/p720t-leds.c b/arch/arm/mach-clps711x/p720t-leds.c
index 262c3c3..1512144 100644
--- a/arch/arm/mach-clps711x/p720t-leds.c
+++ b/arch/arm/mach-clps711x/p720t-leds.c
@@ -21,9 +21,9 @@
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/leds.h>
 #include <asm/system.h>
 #include <asm/mach-types.h>
diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c
index f51f97d..0d94a30 100644
--- a/arch/arm/mach-clps711x/p720t.c
+++ b/arch/arm/mach-clps711x/p720t.c
@@ -22,9 +22,9 @@
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/mm.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <asm/setup.h>
diff --git a/arch/arm/mach-clps711x/time.c b/arch/arm/mach-clps711x/time.c
index ef1fcd1..d581ef0 100644
--- a/arch/arm/mach-clps711x/time.c
+++ b/arch/arm/mach-clps711x/time.c
@@ -21,11 +21,11 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/sched.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/leds.h>
-#include <asm/io.h>
 #include <asm/hardware/clps7111.h>
 
 #include <asm/mach/time.h>
diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c
index cc1b821..c3a33b8 100644
--- a/arch/arm/mach-clps7500/core.c
+++ b/arch/arm/mach-clps7500/core.c
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/serial_8250.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -23,7 +24,6 @@
 
 #include <mach/hardware.h>
 #include <asm/hardware/iomd.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-clps7500/include/mach/irq.h b/arch/arm/mach-clps7500/include/mach/irq.h
index e8da3c5..d02fcf2 100644
--- a/arch/arm/mach-clps7500/include/mach/irq.h
+++ b/arch/arm/mach-clps7500/include/mach/irq.h
@@ -10,8 +10,8 @@
  *   11-08-1999	PJB	Created ARM7500 version, derived from RiscPC code
  */
 
+#include <linux/io.h>
 #include <asm/hardware/iomd.h>
-#include <asm/io.h>
 
 static inline int fixup_irq(unsigned int irq)
 {
diff --git a/arch/arm/mach-clps7500/include/mach/memory.h b/arch/arm/mach-clps7500/include/mach/memory.h
index 3326aa9..87b32db 100644
--- a/arch/arm/mach-clps7500/include/mach/memory.h
+++ b/arch/arm/mach-clps7500/include/mach/memory.h
@@ -32,4 +32,12 @@
 #define FLUSH_BASE_PHYS		0x00000000
 #define FLUSH_BASE		0xdf000000
 
+/*
+ * Sparsemem support.  Each section is a maximum of 64MB.  The sections
+ * are offset by 128MB and can cover 128MB, so that gives us a maximum
+ * of 29 physmem bits.
+ */
+#define MAX_PHYSMEM_BITS	29
+#define SECTION_SIZE_BITS	26
+
 #endif
diff --git a/arch/arm/mach-clps7500/include/mach/system.h b/arch/arm/mach-clps7500/include/mach/system.h
index 624fc28..6d325fb 100644
--- a/arch/arm/mach-clps7500/include/mach/system.h
+++ b/arch/arm/mach-clps7500/include/mach/system.h
@@ -6,8 +6,8 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
+#include <linux/io.h>
 #include <asm/hardware/iomd.h>
-#include <asm/io.h>
 
 static inline void arch_idle(void)
 {
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index 99ac2e5..4dc4585 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -5,7 +5,7 @@
 
 # Common objects
 obj-y 			:= time.o irq.o clock.o serial.o io.o id.o psc.o \
-			   gpio.o mux.o
+			   gpio.o mux.o devices.o usb.o
 
 # Board specific
 obj-$(CONFIG_MACH_DAVINCI_EVM)  += board-evm.o
diff --git a/arch/arm/mach-davinci/board-evm.c b/arch/arm/mach-davinci/board-evm.c
index 1343557..a957d23 100644
--- a/arch/arm/mach-davinci/board-evm.c
+++ b/arch/arm/mach-davinci/board-evm.c
@@ -13,20 +13,28 @@
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c/pcf857x.h>
+#include <linux/i2c/at24.h>
+
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
+#include <linux/io.h>
 
 #include <asm/setup.h>
-#include <asm/io.h>
 #include <asm/mach-types.h>
-#include <mach/hardware.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/flash.h>
 
+#include <mach/hardware.h>
 #include <mach/common.h>
+#include <mach/i2c.h>
 
 /* other misc. init functions */
 void __init davinci_psc_init(void);
@@ -34,10 +42,10 @@
 void __init davinci_map_common_io(void);
 void __init davinci_init_common_hw(void);
 
-/* NOR Flash base address set to CS0 by default */
-#define NOR_FLASH_PHYS 0x02000000
+#if defined(CONFIG_MTD_PHYSMAP) || \
+    defined(CONFIG_MTD_PHYSMAP_MODULE)
 
-static struct mtd_partition davinci_evm_partitions[] = {
+static struct mtd_partition davinci_evm_norflash_partitions[] = {
 	/* bootloader (U-Boot, etc) in first 4 sectors */
 	{
 		.name		= "bootloader",
@@ -68,32 +76,323 @@
 	}
 };
 
-static struct physmap_flash_data davinci_evm_flash_data = {
+static struct physmap_flash_data davinci_evm_norflash_data = {
 	.width		= 2,
-	.parts		= davinci_evm_partitions,
-	.nr_parts	= ARRAY_SIZE(davinci_evm_partitions),
+	.parts		= davinci_evm_norflash_partitions,
+	.nr_parts	= ARRAY_SIZE(davinci_evm_norflash_partitions),
 };
 
 /* NOTE: CFI probe will correctly detect flash part as 32M, but EMIF
  * limits addresses to 16M, so using addresses past 16M will wrap */
-static struct resource davinci_evm_flash_resource = {
-	.start		= NOR_FLASH_PHYS,
-	.end		= NOR_FLASH_PHYS + SZ_16M - 1,
+static struct resource davinci_evm_norflash_resource = {
+	.start		= DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
+	.end		= DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
 	.flags		= IORESOURCE_MEM,
 };
 
-static struct platform_device davinci_evm_flash_device = {
+static struct platform_device davinci_evm_norflash_device = {
 	.name		= "physmap-flash",
 	.id		= 0,
 	.dev		= {
-		.platform_data	= &davinci_evm_flash_data,
+		.platform_data	= &davinci_evm_norflash_data,
 	},
 	.num_resources	= 1,
-	.resource	= &davinci_evm_flash_resource,
+	.resource	= &davinci_evm_norflash_resource,
 };
 
+#endif
+
+#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
+    defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
+
+static struct resource ide_resources[] = {
+	{
+		.start          = DAVINCI_CFC_ATA_BASE,
+		.end            = DAVINCI_CFC_ATA_BASE + 0x7ff,
+		.flags          = IORESOURCE_MEM,
+	},
+	{
+		.start          = IRQ_IDE,
+		.end            = IRQ_IDE,
+		.flags          = IORESOURCE_IRQ,
+	},
+};
+
+static u64 ide_dma_mask = DMA_32BIT_MASK;
+
+static struct platform_device ide_dev = {
+	.name           = "palm_bk3710",
+	.id             = -1,
+	.resource       = ide_resources,
+	.num_resources  = ARRAY_SIZE(ide_resources),
+	.dev = {
+		.dma_mask		= &ide_dma_mask,
+		.coherent_dma_mask      = DMA_32BIT_MASK,
+	},
+};
+
+#endif
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * I2C GPIO expanders
+ */
+
+#define PCF_Uxx_BASE(x)	(DAVINCI_N_GPIO + ((x) * 8))
+
+
+/* U2 -- LEDs */
+
+static struct gpio_led evm_leds[] = {
+	{ .name = "DS8", .active_low = 1,
+		.default_trigger = "heartbeat", },
+	{ .name = "DS7", .active_low = 1, },
+	{ .name = "DS6", .active_low = 1, },
+	{ .name = "DS5", .active_low = 1, },
+	{ .name = "DS4", .active_low = 1, },
+	{ .name = "DS3", .active_low = 1, },
+	{ .name = "DS2", .active_low = 1,
+		.default_trigger = "mmc0", },
+	{ .name = "DS1", .active_low = 1,
+		.default_trigger = "ide-disk", },
+};
+
+static const struct gpio_led_platform_data evm_led_data = {
+	.num_leds	= ARRAY_SIZE(evm_leds),
+	.leds		= evm_leds,
+};
+
+static struct platform_device *evm_led_dev;
+
+static int
+evm_led_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+	struct gpio_led *leds = evm_leds;
+	int status;
+
+	while (ngpio--) {
+		leds->gpio = gpio++;
+		leds++;
+	}
+
+	/* what an extremely annoying way to be forced to handle
+	 * device unregistration ...
+	 */
+	evm_led_dev = platform_device_alloc("leds-gpio", 0);
+	platform_device_add_data(evm_led_dev,
+			&evm_led_data, sizeof evm_led_data);
+
+	evm_led_dev->dev.parent = &client->dev;
+	status = platform_device_add(evm_led_dev);
+	if (status < 0) {
+		platform_device_put(evm_led_dev);
+		evm_led_dev = NULL;
+	}
+	return status;
+}
+
+static int
+evm_led_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+	if (evm_led_dev) {
+		platform_device_unregister(evm_led_dev);
+		evm_led_dev = NULL;
+	}
+	return 0;
+}
+
+static struct pcf857x_platform_data pcf_data_u2 = {
+	.gpio_base	= PCF_Uxx_BASE(0),
+	.setup		= evm_led_setup,
+	.teardown	= evm_led_teardown,
+};
+
+
+/* U18 - A/V clock generator and user switch */
+
+static int sw_gpio;
+
+static ssize_t
+sw_show(struct device *d, struct device_attribute *a, char *buf)
+{
+	char *s = gpio_get_value_cansleep(sw_gpio) ? "on\n" : "off\n";
+
+	strcpy(buf, s);
+	return strlen(s);
+}
+
+static DEVICE_ATTR(user_sw, S_IRUGO, sw_show, NULL);
+
+static int
+evm_u18_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+	int	status;
+
+	/* export dip switch option */
+	sw_gpio = gpio + 7;
+	status = gpio_request(sw_gpio, "user_sw");
+	if (status == 0)
+		status = gpio_direction_input(sw_gpio);
+	if (status == 0)
+		status = device_create_file(&client->dev, &dev_attr_user_sw);
+	else
+		gpio_free(sw_gpio);
+	if (status != 0)
+		sw_gpio = -EINVAL;
+
+	/* audio PLL:  48 kHz (vs 44.1 or 32), single rate (vs double) */
+	gpio_request(gpio + 3, "pll_fs2");
+	gpio_direction_output(gpio + 3, 0);
+
+	gpio_request(gpio + 2, "pll_fs1");
+	gpio_direction_output(gpio + 2, 0);
+
+	gpio_request(gpio + 1, "pll_sr");
+	gpio_direction_output(gpio + 1, 0);
+
+	return 0;
+}
+
+static int
+evm_u18_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+	gpio_free(gpio + 1);
+	gpio_free(gpio + 2);
+	gpio_free(gpio + 3);
+
+	if (sw_gpio > 0) {
+		device_remove_file(&client->dev, &dev_attr_user_sw);
+		gpio_free(sw_gpio);
+	}
+	return 0;
+}
+
+static struct pcf857x_platform_data pcf_data_u18 = {
+	.gpio_base	= PCF_Uxx_BASE(1),
+	.n_latch	= (1 << 3) | (1 << 2) | (1 << 1),
+	.setup		= evm_u18_setup,
+	.teardown	= evm_u18_teardown,
+};
+
+
+/* U35 - various I/O signals used to manage USB, CF, ATA, etc */
+
+static int
+evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+	/* p0 = nDRV_VBUS (initial:  don't supply it) */
+	gpio_request(gpio + 0, "nDRV_VBUS");
+	gpio_direction_output(gpio + 0, 1);
+
+	/* p1 = VDDIMX_EN */
+	gpio_request(gpio + 1, "VDDIMX_EN");
+	gpio_direction_output(gpio + 1, 1);
+
+	/* p2 = VLYNQ_EN */
+	gpio_request(gpio + 2, "VLYNQ_EN");
+	gpio_direction_output(gpio + 2, 1);
+
+	/* p3 = n3V3_CF_RESET (initial: stay in reset) */
+	gpio_request(gpio + 3, "nCF_RESET");
+	gpio_direction_output(gpio + 3, 0);
+
+	/* (p4 unused) */
+
+	/* p5 = 1V8_WLAN_RESET (initial: stay in reset) */
+	gpio_request(gpio + 5, "WLAN_RESET");
+	gpio_direction_output(gpio + 5, 1);
+
+	/* p6 = nATA_SEL (initial: select) */
+	gpio_request(gpio + 6, "nATA_SEL");
+	gpio_direction_output(gpio + 6, 0);
+
+	/* p7 = nCF_SEL (initial: deselect) */
+	gpio_request(gpio + 7, "nCF_SEL");
+	gpio_direction_output(gpio + 7, 1);
+
+	return 0;
+}
+
+static int
+evm_u35_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+	gpio_free(gpio + 7);
+	gpio_free(gpio + 6);
+	gpio_free(gpio + 5);
+	gpio_free(gpio + 3);
+	gpio_free(gpio + 2);
+	gpio_free(gpio + 1);
+	gpio_free(gpio + 0);
+	return 0;
+}
+
+static struct pcf857x_platform_data pcf_data_u35 = {
+	.gpio_base	= PCF_Uxx_BASE(2),
+	.setup		= evm_u35_setup,
+	.teardown	= evm_u35_teardown,
+};
+
+/*----------------------------------------------------------------------*/
+
+/* Most of this EEPROM is unused, but U-Boot uses some data:
+ *  - 0x7f00, 6 bytes Ethernet Address
+ *  - 0x0039, 1 byte NTSC vs PAL (bit 0x80 == PAL)
+ *  - ... newer boards may have more
+ */
+static struct at24_platform_data eeprom_info = {
+	.byte_len	= (256*1024) / 8,
+	.page_size	= 64,
+	.flags		= AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info __initdata i2c_info[] =  {
+	{
+		I2C_BOARD_INFO("pcf8574", 0x38),
+		.platform_data	= &pcf_data_u2,
+	},
+	{
+		I2C_BOARD_INFO("pcf8574", 0x39),
+		.platform_data	= &pcf_data_u18,
+	},
+	{
+		I2C_BOARD_INFO("pcf8574", 0x3a),
+		.platform_data	= &pcf_data_u35,
+	},
+	{
+		I2C_BOARD_INFO("24c256", 0x50),
+		.platform_data	= &eeprom_info,
+	},
+	/* ALSO:
+	 * - tvl320aic33 audio codec (0x1b)
+	 * - msp430 microcontroller (0x23)
+	 * - tvp5146 video decoder (0x5d)
+	 */
+};
+
+/* The msp430 uses a slow bitbanged I2C implementation (ergo 20 KHz),
+ * which requires 100 usec of idle bus after i2c writes sent to it.
+ */
+static struct davinci_i2c_platform_data i2c_pdata = {
+	.bus_freq	= 20 /* kHz */,
+	.bus_delay	= 100 /* usec */,
+};
+
+static void __init evm_init_i2c(void)
+{
+	davinci_init_i2c(&i2c_pdata);
+	i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
+}
+
 static struct platform_device *davinci_evm_devices[] __initdata = {
-	&davinci_evm_flash_device,
+#if defined(CONFIG_MTD_PHYSMAP) || \
+    defined(CONFIG_MTD_PHYSMAP_MODULE)
+	&davinci_evm_norflash_device,
+#endif
+#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
+    defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
+	&ide_dev,
+#endif
 };
 
 static void __init
@@ -106,13 +405,21 @@
 {
 	davinci_psc_init();
 
-#if defined(CONFIG_BLK_DEV_DAVINCI) || defined(CONFIG_BLK_DEV_DAVINCI_MODULE)
+#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
+    defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
+#if defined(CONFIG_MTD_PHYSMAP) || \
+    defined(CONFIG_MTD_PHYSMAP_MODULE)
 	printk(KERN_WARNING "WARNING: both IDE and NOR flash are enabled, "
 	       "but share pins.\n\t Disable IDE for NOR support.\n");
 #endif
+#endif
 
 	platform_add_devices(davinci_evm_devices,
 			     ARRAY_SIZE(davinci_evm_devices));
+	evm_init_i2c();
+
+	/* irlml6401 sustains over 3A, switches 5V in under 8 msec */
+	setup_usb(500, 8);
 }
 
 static __init void davinci_evm_irq_init(void)
@@ -124,7 +431,7 @@
 MACHINE_START(DAVINCI_EVM, "DaVinci EVM")
 	/* Maintainer: MontaVista Software <source@mvista.com> */
 	.phys_io      = IO_PHYS,
-	.io_pg_offst  = (io_p2v(IO_PHYS) >> 18) & 0xfffc,
+	.io_pg_offst  = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
 	.boot_params  = (DAVINCI_DDR_BASE + 0x100),
 	.map_io	      = davinci_evm_map_io,
 	.init_irq     = davinci_evm_irq_init,
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index d46c69b..28f6dbc 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -16,9 +16,9 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 
 #include <mach/psc.h>
 #include "clock.h"
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
new file mode 100644
index 0000000..3d4b1de
--- /dev/null
+++ b/arch/arm/mach-davinci/devices.c
@@ -0,0 +1,48 @@
+/*
+ * mach-davinci/devices.c
+ *
+ * DaVinci platform device setup/initialization
+ *
+ * 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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/i2c.h>
+
+static struct resource i2c_resources[] = {
+	{
+		.start		= DAVINCI_I2C_BASE,
+		.end		= DAVINCI_I2C_BASE + 0x40,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= IRQ_I2C,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device davinci_i2c_device = {
+	.name           = "i2c_davinci",
+	.id             = 1,
+	.num_resources	= ARRAY_SIZE(i2c_resources),
+	.resource	= i2c_resources,
+};
+
+void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata)
+{
+	davinci_i2c_device.dev.platform_data = pdata;
+	(void) platform_device_register(&davinci_i2c_device);
+}
+
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
index c9cb4f0..b49e9d0 100644
--- a/arch/arm/mach-davinci/gpio.c
+++ b/arch/arm/mach-davinci/gpio.c
@@ -1,7 +1,7 @@
 /*
  * TI DaVinci GPIO Support
  *
- * Copyright (c) 2006 David Brownell
+ * Copyright (c) 2006-2007 David Brownell
  * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -26,63 +26,23 @@
 
 #include <asm/mach/irq.h>
 
+
 static DEFINE_SPINLOCK(gpio_lock);
-static DECLARE_BITMAP(gpio_in_use, DAVINCI_N_GPIO);
 
-int gpio_request(unsigned gpio, const char *tag)
-{
-	if (gpio >= DAVINCI_N_GPIO)
-		return -EINVAL;
+struct davinci_gpio {
+	struct gpio_chip	chip;
+	struct gpio_controller	*__iomem regs;
+};
 
-	if (test_and_set_bit(gpio, gpio_in_use))
-		return -EBUSY;
+static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
 
-	return 0;
-}
-EXPORT_SYMBOL(gpio_request);
-
-void gpio_free(unsigned gpio)
-{
-	if (gpio >= DAVINCI_N_GPIO)
-		return;
-
-	clear_bit(gpio, gpio_in_use);
-}
-EXPORT_SYMBOL(gpio_free);
 
 /* create a non-inlined version */
-static struct gpio_controller *__iomem gpio2controller(unsigned gpio)
+static struct gpio_controller *__iomem __init gpio2controller(unsigned gpio)
 {
 	return __gpio_to_controller(gpio);
 }
 
-/*
- * Assuming the pin is muxed as a gpio output, set its output value.
- */
-void __gpio_set(unsigned gpio, int value)
-{
-	struct gpio_controller *__iomem g = gpio2controller(gpio);
-
-	__raw_writel(__gpio_mask(gpio), value ? &g->set_data : &g->clr_data);
-}
-EXPORT_SYMBOL(__gpio_set);
-
-
-/*
- * Read the pin's value (works even if it's set up as output);
- * returns zero/nonzero.
- *
- * Note that changes are synched to the GPIO clock, so reading values back
- * right after you've set them may give old values.
- */
-int __gpio_get(unsigned gpio)
-{
-	struct gpio_controller *__iomem g = gpio2controller(gpio);
-
-	return !!(__gpio_mask(gpio) & __raw_readl(&g->in_data));
-}
-EXPORT_SYMBOL(__gpio_get);
-
 
 /*--------------------------------------------------------------------------*/
 
@@ -91,36 +51,45 @@
  * needed, and enable the GPIO clock.
  */
 
-int gpio_direction_input(unsigned gpio)
+static int davinci_direction_in(struct gpio_chip *chip, unsigned offset)
 {
-	struct gpio_controller *__iomem g = gpio2controller(gpio);
+	struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
+	struct gpio_controller *__iomem g = d->regs;
 	u32 temp;
-	u32 mask;
-
-	if (!g)
-		return -EINVAL;
 
 	spin_lock(&gpio_lock);
-	mask = __gpio_mask(gpio);
 	temp = __raw_readl(&g->dir);
-	temp |= mask;
+	temp |= (1 << offset);
 	__raw_writel(temp, &g->dir);
 	spin_unlock(&gpio_lock);
+
 	return 0;
 }
-EXPORT_SYMBOL(gpio_direction_input);
 
-int gpio_direction_output(unsigned gpio, int value)
+/*
+ * Read the pin's value (works even if it's set up as output);
+ * returns zero/nonzero.
+ *
+ * Note that changes are synched to the GPIO clock, so reading values back
+ * right after you've set them may give old values.
+ */
+static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
-	struct gpio_controller *__iomem g = gpio2controller(gpio);
-	u32 temp;
-	u32 mask;
+	struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
+	struct gpio_controller *__iomem g = d->regs;
 
-	if (!g)
-		return -EINVAL;
+	return (1 << offset) & __raw_readl(&g->in_data);
+}
+
+static int
+davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
+	struct gpio_controller *__iomem g = d->regs;
+	u32 temp;
+	u32 mask = 1 << offset;
 
 	spin_lock(&gpio_lock);
-	mask = __gpio_mask(gpio);
 	temp = __raw_readl(&g->dir);
 	temp &= ~mask;
 	__raw_writel(mask, value ? &g->set_data : &g->clr_data);
@@ -128,9 +97,49 @@
 	spin_unlock(&gpio_lock);
 	return 0;
 }
-EXPORT_SYMBOL(gpio_direction_output);
 
 /*
+ * Assuming the pin is muxed as a gpio output, set its output value.
+ */
+static void
+davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
+	struct gpio_controller *__iomem g = d->regs;
+
+	__raw_writel((1 << offset), value ? &g->set_data : &g->clr_data);
+}
+
+static int __init davinci_gpio_setup(void)
+{
+	int i, base;
+
+	for (i = 0, base = 0;
+			i < ARRAY_SIZE(chips);
+			i++, base += 32) {
+		chips[i].chip.label = "DaVinci";
+
+		chips[i].chip.direction_input = davinci_direction_in;
+		chips[i].chip.get = davinci_gpio_get;
+		chips[i].chip.direction_output = davinci_direction_out;
+		chips[i].chip.set = davinci_gpio_set;
+
+		chips[i].chip.base = base;
+		chips[i].chip.ngpio = DAVINCI_N_GPIO - base;
+		if (chips[i].chip.ngpio > 32)
+			chips[i].chip.ngpio = 32;
+
+		chips[i].regs = gpio2controller(base);
+
+		gpiochip_add(&chips[i].chip);
+	}
+
+	return 0;
+}
+pure_initcall(davinci_gpio_setup);
+
+/*--------------------------------------------------------------------------*/
+/*
  * We expect irqs will normally be set up as input pins, but they can also be
  * used as output pins ... which is convenient for testing.
  *
@@ -201,7 +210,6 @@
 	desc->chip->ack(irq);
 	while (1) {
 		u32		status;
-		struct irq_desc	*gpio;
 		int		n;
 		int		res;
 
@@ -215,12 +223,10 @@
 
 		/* now demux them to the right lowlevel handler */
 		n = (int)get_irq_data(irq);
-		gpio = &irq_desc[n];
 		while (status) {
 			res = ffs(status);
 			n += res;
-			gpio += res;
-			desc_handle_irq(n - 1, gpio - 1);
+			generic_handle_irq(n - 1);
 			status >>= res;
 		}
 	}
diff --git a/arch/arm/mach-davinci/id.c b/arch/arm/mach-davinci/id.c
index 70608f7..bf067d6 100644
--- a/arch/arm/mach-davinci/id.c
+++ b/arch/arm/mach-davinci/id.c
@@ -13,8 +13,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
 #define JTAG_ID_BASE		0x01c40028
 
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index a97dfbb..4b522e5 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -16,4 +16,7 @@
 
 extern struct sys_timer davinci_timer;
 
+/* parameters describe VBUS sourcing for host mode */
+extern void setup_usb(unsigned mA, unsigned potpgt_msec);
+
 #endif /* __ARCH_ARM_MACH_DAVINCI_COMMON_H */
diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h
index ec151cc..b3a2961 100644
--- a/arch/arm/mach-davinci/include/mach/gpio.h
+++ b/arch/arm/mach-davinci/include/mach/gpio.h
@@ -14,6 +14,7 @@
 #define	__DAVINCI_GPIO_H
 
 #include <linux/io.h>
+#include <asm-generic/gpio.h>
 #include <mach/hardware.h>
 
 /*
@@ -27,13 +28,16 @@
  * need to pay attention to PINMUX0 and PINMUX1 to be sure those pins are
  * used as gpios, not with other peripherals.
  *
- * GPIOs are numbered 0..(DAVINCI_N_GPIO-1).  For documentation, and maybe
- * for later updates, code should write GPIO(N) or:
+ * On-chip GPIOs are numbered 0..(DAVINCI_N_GPIO-1).  For documentation,
+ * and maybe for later updates, code should write GPIO(N) or:
  *  - GPIOV18(N) for 1.8V pins, N in 0..53; same as GPIO(0)..GPIO(53)
  *  - GPIOV33(N) for 3.3V pins, N in 0..17; same as GPIO(54)..GPIO(70)
  *
  * For GPIO IRQs use gpio_to_irq(GPIO(N)) or gpio_to_irq(GPIOV33(N)) etc
  * for now, that's != GPIO(N)
+ *
+ * GPIOs can also be on external chips, numbered after the ones built-in
+ * to the DaVinci chip.  For now, they won't be usable as IRQ sources.
  */
 #define	GPIO(X)		(X)		/* 0 <= X <= 70 */
 #define	GPIOV18(X)	(X)		/* 1.8V i/o; 0 <= X <= 53 */
@@ -67,11 +71,11 @@
 	void *__iomem ptr;
 
 	if (gpio < 32)
-		ptr = (void *__iomem)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10);
+		ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10);
 	else if (gpio < 64)
-		ptr = (void *__iomem)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x38);
+		ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x38);
 	else if (gpio < DAVINCI_N_GPIO)
-		ptr = (void *__iomem)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x60);
+		ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x60);
 	else
 		ptr = NULL;
 	return ptr;
@@ -83,25 +87,17 @@
 }
 
 /* The get/set/clear functions will inline when called with constant
- * parameters, for low-overhead bitbanging.  Illegal constant parameters
- * cause link-time errors.
+ * parameters referencing built-in GPIOs, for low-overhead bitbanging.
  *
- * Otherwise, calls with variable parameters use outlined functions.
+ * Otherwise, calls with variable parameters or referencing external
+ * GPIOs (e.g. on GPIO expander chips) use outlined functions.
  */
-extern int __error_inval_gpio(void);
-
-extern void __gpio_set(unsigned gpio, int value);
-extern int __gpio_get(unsigned gpio);
-
 static inline void gpio_set_value(unsigned gpio, int value)
 {
-	if (__builtin_constant_p(value)) {
+	if (__builtin_constant_p(value) && gpio < DAVINCI_N_GPIO) {
 		struct gpio_controller	*__iomem g;
 		u32			mask;
 
-		if (gpio >= DAVINCI_N_GPIO)
-			__error_inval_gpio();
-
 		g = __gpio_to_controller(gpio);
 		mask = __gpio_mask(gpio);
 		if (value)
@@ -111,48 +107,47 @@
 		return;
 	}
 
-	__gpio_set(gpio, value);
+	__gpio_set_value(gpio, value);
 }
 
 /* Returns zero or nonzero; works for gpios configured as inputs OR
- * as outputs.
+ * as outputs, at least for built-in GPIOs.
  *
- * NOTE: changes in reported values are synchronized to the GPIO clock.
- * This is most easily seen after calling gpio_set_value() and then immediatly
- * gpio_get_value(), where the gpio_get_value() would return the old value
- * until the GPIO clock ticks and the new value gets latched.
+ * NOTE: for built-in GPIOs, changes in reported values are synchronized
+ * to the GPIO clock.  This is easily seen after calling gpio_set_value()
+ * and then immediately gpio_get_value(), where the gpio_get_value() will
+ * return the old value until the GPIO clock ticks and the new value gets
+ * latched.
  */
-
 static inline int gpio_get_value(unsigned gpio)
 {
-	struct gpio_controller *__iomem g;
+	struct gpio_controller	*__iomem g;
 
-	if (!__builtin_constant_p(gpio))
-		return __gpio_get(gpio);
-
-	if (gpio >= DAVINCI_N_GPIO)
-		return __error_inval_gpio();
+	if (!__builtin_constant_p(gpio) || gpio >= DAVINCI_N_GPIO)
+		return __gpio_get_value(gpio);
 
 	g = __gpio_to_controller(gpio);
-	return !!(__gpio_mask(gpio) & __raw_readl(&g->in_data));
+	return __gpio_mask(gpio) & __raw_readl(&g->in_data);
 }
 
-/* powerup default direction is IN */
-extern int gpio_direction_input(unsigned gpio);
-extern int gpio_direction_output(unsigned gpio, int value);
-
-#include <asm-generic/gpio.h>	/* cansleep wrappers */
-
-extern int gpio_request(unsigned gpio, const char *tag);
-extern void gpio_free(unsigned gpio);
+static inline int gpio_cansleep(unsigned gpio)
+{
+	if (__builtin_constant_p(gpio) && gpio < DAVINCI_N_GPIO)
+		return 0;
+	else
+		return __gpio_cansleep(gpio);
+}
 
 static inline int gpio_to_irq(unsigned gpio)
 {
+	if (gpio >= DAVINCI_N_GPIO)
+		return -EINVAL;
 	return DAVINCI_N_AINTC_IRQ + gpio;
 }
 
 static inline int irq_to_gpio(unsigned irq)
 {
+	/* caller guarantees gpio_to_irq() succeeded */
 	return irq - DAVINCI_N_AINTC_IRQ;
 }
 
diff --git a/arch/arm/mach-davinci/include/mach/i2c.h b/arch/arm/mach-davinci/include/mach/i2c.h
index e2f5416..c248e9b 100644
--- a/arch/arm/mach-davinci/include/mach/i2c.h
+++ b/arch/arm/mach-davinci/include/mach/i2c.h
@@ -14,8 +14,11 @@
 
 /* All frequencies are expressed in kHz */
 struct davinci_i2c_platform_data {
-	unsigned int	bus_freq;	/* standard bus frequency */
-	unsigned int	bus_delay;	/* transaction delay */
+	unsigned int	bus_freq;	/* standard bus frequency (kHz) */
+	unsigned int	bus_delay;	/* post-transaction delay (usec) */
 };
 
+/* for board setup code */
+void davinci_init_i2c(struct davinci_i2c_platform_data *);
+
 #endif /* __ASM_ARCH_I2C_H */
diff --git a/arch/arm/mach-davinci/include/mach/io.h b/arch/arm/mach-davinci/include/mach/io.h
index e7accb9..b78ee91 100644
--- a/arch/arm/mach-davinci/include/mach/io.h
+++ b/arch/arm/mach-davinci/include/mach/io.h
@@ -22,9 +22,8 @@
 #define IO_OFFSET	0xfd000000 /* Virtual IO = 0xfec00000 */
 #define IO_SIZE		0x00400000
 #define IO_VIRT		(IO_PHYS + IO_OFFSET)
-#define io_p2v(pa)	((pa) + IO_OFFSET)
 #define io_v2p(va)	((va) - IO_OFFSET)
-#define IO_ADDRESS(x)	io_p2v(x)
+#define __IO_ADDRESS(x)	((x) + IO_OFFSET)
 
 /*
  * We don't actually have real ISA nor PCI buses, but there is so many
@@ -35,7 +34,12 @@
 #define __mem_pci(a)		(a)
 #define __mem_isa(a)		(a)
 
-#ifndef __ASSEMBLER__
+#define IO_ADDRESS(pa)          IOMEM(__IO_ADDRESS(pa))
+
+#ifdef __ASSEMBLER__
+#define IOMEM(x)                x
+#else
+#define IOMEM(x)                ((void __force __iomem *)(x))
 
 /*
  * Functions to access the DaVinci IO region
@@ -46,34 +50,13 @@
  *	 - DO NOT use hardcoded virtual addresses to allow changing the
  *	   IO address space again if needed
  */
-#define davinci_readb(a)	(*(volatile unsigned char  *)IO_ADDRESS(a))
-#define davinci_readw(a)	(*(volatile unsigned short *)IO_ADDRESS(a))
-#define davinci_readl(a)	(*(volatile unsigned int   *)IO_ADDRESS(a))
+#define davinci_readb(a)	__raw_readb(IO_ADDRESS(a))
+#define davinci_readw(a)	__raw_readw(IO_ADDRESS(a))
+#define davinci_readl(a)	__raw_readl(IO_ADDRESS(a))
 
-#define davinci_writeb(v,a)	(*(volatile unsigned char  *)IO_ADDRESS(a) = (v))
-#define davinci_writew(v,a)	(*(volatile unsigned short *)IO_ADDRESS(a) = (v))
-#define davinci_writel(v,a)	(*(volatile unsigned int   *)IO_ADDRESS(a) = (v))
-
-/* 16 bit uses LDRH/STRH, base +/- offset_8 */
-typedef struct { volatile u16 offset[256]; } __regbase16;
-#define __REGV16(vaddr)		((__regbase16 *)((vaddr)&~0xff)) \
-					->offset[((vaddr)&0xff)>>1]
-#define __REG16(paddr)          __REGV16(io_p2v(paddr))
-
-/* 8/32 bit uses LDR/STR, base +/- offset_12 */
-typedef struct { volatile u8 offset[4096]; } __regbase8;
-#define __REGV8(vaddr)		((__regbase8  *)((vaddr)&~4095)) \
-					->offset[((vaddr)&4095)>>0]
-#define __REG8(paddr)		__REGV8(io_p2v(paddr))
-
-typedef struct { volatile u32 offset[4096]; } __regbase32;
-#define __REGV32(vaddr)		((__regbase32 *)((vaddr)&~4095)) \
-					->offset[((vaddr)&4095)>>2]
-
-#define __REG(paddr)		__REGV32(io_p2v(paddr))
-#else
-
-#define __REG(x)	(*((volatile unsigned long *)io_p2v(x)))
+#define davinci_writeb(v, a)	__raw_writeb(v, IO_ADDRESS(a))
+#define davinci_writew(v, a)	__raw_writew(v, IO_ADDRESS(a))
+#define davinci_writel(v, a)	__raw_writel(v, IO_ADDRESS(a))
 
 #endif /* __ASSEMBLER__ */
 #endif /* __ASM_ARCH_IO_H */
diff --git a/arch/arm/mach-davinci/include/mach/system.h b/arch/arm/mach-davinci/include/mach/system.h
index 84ff77a..17ca41d 100644
--- a/arch/arm/mach-davinci/include/mach/system.h
+++ b/arch/arm/mach-davinci/include/mach/system.h
@@ -11,7 +11,7 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
 
 extern void davinci_watchdog_reset(void);
diff --git a/arch/arm/mach-davinci/io.c b/arch/arm/mach-davinci/io.c
index 5bb66b6..299515f 100644
--- a/arch/arm/mach-davinci/io.c
+++ b/arch/arm/mach-davinci/io.c
@@ -11,9 +11,9 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
 #include <asm/tlb.h>
-#include <asm/io.h>
 #include <asm/memory.h>
 
 #include <asm/mach/map.h>
diff --git a/arch/arm/mach-davinci/irq.c b/arch/arm/mach-davinci/irq.c
index 12ca9f2..38021af 100644
--- a/arch/arm/mach-davinci/irq.c
+++ b/arch/arm/mach-davinci/irq.c
@@ -22,9 +22,9 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/mach/irq.h>
 
 #define IRQ_BIT(irq)		((irq) & 0x1f)
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c
index 720c48b..42b976e 100644
--- a/arch/arm/mach-davinci/psc.c
+++ b/arch/arm/mach-davinci/psc.c
@@ -21,8 +21,8 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <mach/hardware.h>
 #include <mach/psc.h>
 #include <mach/mux.h>
diff --git a/arch/arm/mach-davinci/serial.c b/arch/arm/mach-davinci/serial.c
index caf101e..3010f99 100644
--- a/arch/arm/mach-davinci/serial.c
+++ b/arch/arm/mach-davinci/serial.c
@@ -26,8 +26,8 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <mach/hardware.h>
 #include <mach/serial.h>
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index 206e80d..3b9a296 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -15,8 +15,8 @@
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/spinlock.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <mach/hardware.h>
 #include <asm/system.h>
 #include <asm/irq.h>
diff --git a/arch/arm/mach-davinci/usb.c b/arch/arm/mach-davinci/usb.c
new file mode 100644
index 0000000..fe182a8
--- /dev/null
+++ b/arch/arm/mach-davinci/usb.c
@@ -0,0 +1,116 @@
+/*
+ * USB
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/usb/musb.h>
+#include <linux/usb/otg.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+
+#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
+static struct musb_hdrc_eps_bits musb_eps[] = {
+	{ "ep1_tx", 8, },
+	{ "ep1_rx", 8, },
+	{ "ep2_tx", 8, },
+	{ "ep2_rx", 8, },
+	{ "ep3_tx", 5, },
+	{ "ep3_rx", 5, },
+	{ "ep4_tx", 5, },
+	{ "ep4_rx", 5, },
+};
+
+static struct musb_hdrc_config musb_config = {
+	.multipoint	= true,
+	.dyn_fifo	= true,
+	.soft_con	= true,
+	.dma		= true,
+
+	.num_eps	= 5,
+	.dma_channels	= 8,
+	.ram_bits	= 10,
+	.eps_bits	= musb_eps,
+};
+
+static struct musb_hdrc_platform_data usb_data = {
+#if defined(CONFIG_USB_MUSB_OTG)
+	/* OTG requires a Mini-AB connector */
+	.mode           = MUSB_OTG,
+#elif defined(CONFIG_USB_MUSB_PERIPHERAL)
+	.mode           = MUSB_PERIPHERAL,
+#elif defined(CONFIG_USB_MUSB_HOST)
+	.mode           = MUSB_HOST,
+#endif
+	.config		= &musb_config,
+};
+
+static struct resource usb_resources[] = {
+	{
+		/* physical address */
+		.start          = DAVINCI_USB_OTG_BASE,
+		.end            = DAVINCI_USB_OTG_BASE + 0x5ff,
+		.flags          = IORESOURCE_MEM,
+	},
+	{
+		.start          = IRQ_USBINT,
+		.flags          = IORESOURCE_IRQ,
+	},
+};
+
+static u64 usb_dmamask = DMA_32BIT_MASK;
+
+static struct platform_device usb_dev = {
+	.name           = "musb_hdrc",
+	.id             = -1,
+	.dev = {
+		.platform_data		= &usb_data,
+		.dma_mask		= &usb_dmamask,
+		.coherent_dma_mask      = DMA_32BIT_MASK,
+	},
+	.resource       = usb_resources,
+	.num_resources  = ARRAY_SIZE(usb_resources),
+};
+
+#ifdef CONFIG_USB_MUSB_OTG
+
+static struct otg_transceiver *xceiv;
+
+struct otg_transceiver *otg_get_transceiver(void)
+{
+	if (xceiv)
+		get_device(xceiv->dev);
+	return xceiv;
+}
+EXPORT_SYMBOL(otg_get_transceiver);
+
+int otg_set_transceiver(struct otg_transceiver *x)
+{
+	if (xceiv && x)
+		return -EBUSY;
+	xceiv = x;
+	return 0;
+}
+EXPORT_SYMBOL(otg_set_transceiver);
+
+#endif
+
+void __init setup_usb(unsigned mA, unsigned potpgt_msec)
+{
+	usb_data.power = mA / 2;
+	usb_data.potpgt = potpgt_msec / 2;
+	platform_device_register(&usb_dev);
+}
+
+#else
+
+void __init setup_usb(unsigned mA, unsigned potpgt_msec)
+{
+}
+
+#endif  /* CONFIG_USB_MUSB_HDRC */
+
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index 65cc7c2..c7bc7fb 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -14,10 +14,10 @@
 #include <linux/interrupt.h>
 #include <linux/serial_8250.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/pgtable.h>
diff --git a/arch/arm/mach-ebsa110/io.c b/arch/arm/mach-ebsa110/io.c
index 53748f5..c52e304 100644
--- a/arch/arm/mach-ebsa110/io.c
+++ b/arch/arm/mach-ebsa110/io.c
@@ -23,9 +23,9 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/page.h>
 
 static void __iomem *__isamem_convert_addr(const volatile void __iomem *addr)
diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig
index ea8549b..5a1b8c0 100644
--- a/arch/arm/mach-ep93xx/Kconfig
+++ b/arch/arm/mach-ep93xx/Kconfig
@@ -88,6 +88,20 @@
 	  Say 'Y' here if you want your kernel to support the
 	  Technologic Systems TS-72xx board.
 
+choice
+	prompt "Select a UART for early kernel messages"
+
+config EP93XX_EARLY_UART1
+	bool "UART1"
+
+config EP93XX_EARLY_UART2
+	bool "UART2"
+
+config EP93XX_EARLY_UART3
+	bool "UART3"
+
+endchoice
+
 endmenu
 
 endif
diff --git a/arch/arm/mach-ep93xx/adssphere.c b/arch/arm/mach-ep93xx/adssphere.c
index aa1fb35..561db73 100644
--- a/arch/arm/mach-ep93xx/adssphere.c
+++ b/arch/arm/mach-ep93xx/adssphere.c
@@ -18,7 +18,7 @@
 #include <linux/ioport.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -47,36 +47,12 @@
 	.phy_id		= 1,
 };
 
-static struct resource adssphere_eth_resource[] = {
-	{
-		.start	= EP93XX_ETHERNET_PHYS_BASE,
-		.end	= EP93XX_ETHERNET_PHYS_BASE + 0xffff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_EP93XX_ETHERNET,
-		.end	= IRQ_EP93XX_ETHERNET,
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
-static struct platform_device adssphere_eth_device = {
-	.name		= "ep93xx-eth",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= &adssphere_eth_data,
-	},
-	.num_resources	= 2,
-	.resource	= adssphere_eth_resource,
-};
-
 static void __init adssphere_init_machine(void)
 {
 	ep93xx_init_devices();
 	platform_device_register(&adssphere_flash);
 
-	memcpy(adssphere_eth_data.dev_addr,
-		(void *)(EP93XX_ETHERNET_BASE + 0x50), 6);
-	platform_device_register(&adssphere_eth_device);
+	ep93xx_register_eth(&adssphere_eth_data, 1);
 }
 
 MACHINE_START(ADSSPHERE, "ADS Sphere board")
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index 6062e47..8c9f249 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -15,9 +15,9 @@
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/string.h>
+#include <linux/io.h>
 #include <asm/div64.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 
 struct clk {
 	char		*name;
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index f99f436..de53f0b 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -32,6 +32,7 @@
 #include <linux/termios.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/serial.h>
+#include <linux/io.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
@@ -41,7 +42,6 @@
 #include <asm/system.h>
 #include <asm/tlbflush.h>
 #include <asm/pgtable.h>
-#include <asm/io.h>
 
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
@@ -157,7 +157,7 @@
 static const u8 int_type1_register_offset[3]	= { 0x90, 0xac, 0x4c };
 static const u8 int_type2_register_offset[3]	= { 0x94, 0xb0, 0x50 };
 static const u8 eoi_register_offset[3]		= { 0x98, 0xb4, 0x54 };
-static const u8 int_en_register_offset[3]	= { 0x9c, 0xb8, 0x5c };
+static const u8 int_en_register_offset[3]	= { 0x9c, 0xb8, 0x58 };
 
 void ep93xx_gpio_update_int_params(unsigned port)
 {
@@ -192,8 +192,7 @@
 	for (i = 0; i < 8; i++) {
 		if (status & (1 << i)) {
 			int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i;
-			desc = irq_desc + gpio_irq;
-			desc_handle_irq(gpio_irq, desc);
+			generic_handle_irq(gpio_irq);
 		}
 	}
 
@@ -202,7 +201,7 @@
 		if (status & (1 << i)) {
 			int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i;
 			desc = irq_desc + gpio_irq;
-			desc_handle_irq(gpio_irq, desc);
+			generic_handle_irq(gpio_irq);
 		}
 	}
 }
@@ -217,7 +216,7 @@
 	int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
 	int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx;
 
-	desc_handle_irq(gpio_irq, irq_desc + gpio_irq);
+	generic_handle_irq(gpio_irq);
 }
 
 static void ep93xx_gpio_irq_ack(unsigned int irq)
@@ -461,6 +460,41 @@
 	.resource	= ep93xx_ohci_resources,
 };
 
+static struct ep93xx_eth_data ep93xx_eth_data;
+
+static struct resource ep93xx_eth_resource[] = {
+	{
+		.start	= EP93XX_ETHERNET_PHYS_BASE,
+		.end	= EP93XX_ETHERNET_PHYS_BASE + 0xffff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_EP93XX_ETHERNET,
+		.end	= IRQ_EP93XX_ETHERNET,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device ep93xx_eth_device = {
+	.name		= "ep93xx-eth",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &ep93xx_eth_data,
+	},
+	.num_resources	= ARRAY_SIZE(ep93xx_eth_resource),
+	.resource	= ep93xx_eth_resource,
+};
+
+void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr)
+{
+	if (copy_addr) {
+		memcpy(data->dev_addr,
+			(void *)(EP93XX_ETHERNET_BASE + 0x50), 6);
+	}
+
+	ep93xx_eth_data = *data;
+	platform_device_register(&ep93xx_eth_device);
+}
+
 extern void ep93xx_gpio_init(void);
 
 void __init ep93xx_init_devices(void)
diff --git a/arch/arm/mach-ep93xx/edb9302.c b/arch/arm/mach-ep93xx/edb9302.c
index 97550c0..e4add5b 100644
--- a/arch/arm/mach-ep93xx/edb9302.c
+++ b/arch/arm/mach-ep93xx/edb9302.c
@@ -18,7 +18,7 @@
 #include <linux/ioport.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -43,10 +43,16 @@
 	.resource	= &edb9302_flash_resource,
 };
 
+static struct ep93xx_eth_data edb9302_eth_data = {
+	.phy_id		= 1,
+};
+
 static void __init edb9302_init_machine(void)
 {
 	ep93xx_init_devices();
 	platform_device_register(&edb9302_flash);
+
+	ep93xx_register_eth(&edb9302_eth_data, 1);
 }
 
 MACHINE_START(EDB9302, "Cirrus Logic EDB9302 Evaluation Board")
diff --git a/arch/arm/mach-ep93xx/edb9302a.c b/arch/arm/mach-ep93xx/edb9302a.c
index 99b01d4..02c4405 100644
--- a/arch/arm/mach-ep93xx/edb9302a.c
+++ b/arch/arm/mach-ep93xx/edb9302a.c
@@ -18,7 +18,7 @@
 #include <linux/ioport.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -47,36 +47,12 @@
 	.phy_id			= 1,
 };
 
-static struct resource edb9302a_eth_resource[] = {
-	{
-		.start	= EP93XX_ETHERNET_PHYS_BASE,
-		.end	= EP93XX_ETHERNET_PHYS_BASE + 0xffff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_EP93XX_ETHERNET,
-		.end	= IRQ_EP93XX_ETHERNET,
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
-static struct platform_device edb9302a_eth_device = {
-	.name		= "ep93xx-eth",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= &edb9302a_eth_data,
-	},
-	.num_resources	= 2,
-	.resource	= edb9302a_eth_resource,
-};
-
 static void __init edb9302a_init_machine(void)
 {
 	ep93xx_init_devices();
 	platform_device_register(&edb9302a_flash);
 
-	memcpy(edb9302a_eth_data.dev_addr,
-		(void *)(EP93XX_ETHERNET_BASE + 0x50), 6);
-	platform_device_register(&edb9302a_eth_device);
+	ep93xx_register_eth(&edb9302a_eth_data, 1);
 }
 
 MACHINE_START(EDB9302A, "Cirrus Logic EDB9302A Evaluation Board")
diff --git a/arch/arm/mach-ep93xx/edb9307.c b/arch/arm/mach-ep93xx/edb9307.c
index 9fb72d0..040edbd 100644
--- a/arch/arm/mach-ep93xx/edb9307.c
+++ b/arch/arm/mach-ep93xx/edb9307.c
@@ -18,7 +18,7 @@
 #include <linux/ioport.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -47,36 +47,12 @@
 	.phy_id			= 1,
 };
 
-static struct resource edb9307_eth_resource[] = {
-	{
-		.start	= EP93XX_ETHERNET_PHYS_BASE,
-		.end	= EP93XX_ETHERNET_PHYS_BASE + 0xffff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_EP93XX_ETHERNET,
-		.end	= IRQ_EP93XX_ETHERNET,
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
-static struct platform_device edb9307_eth_device = {
-	.name		= "ep93xx-eth",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= &edb9307_eth_data,
-	},
-	.num_resources	= 2,
-	.resource	= edb9307_eth_resource,
-};
-
 static void __init edb9307_init_machine(void)
 {
 	ep93xx_init_devices();
 	platform_device_register(&edb9307_flash);
 
-	memcpy(edb9307_eth_data.dev_addr,
-		(void *)(EP93XX_ETHERNET_BASE + 0x50), 6);
-	platform_device_register(&edb9307_eth_device);
+	ep93xx_register_eth(&edb9307_eth_data, 1);
 }
 
 MACHINE_START(EDB9307, "Cirrus Logic EDB9307 Evaluation Board")
diff --git a/arch/arm/mach-ep93xx/edb9312.c b/arch/arm/mach-ep93xx/edb9312.c
index 87267a5..6853e30 100644
--- a/arch/arm/mach-ep93xx/edb9312.c
+++ b/arch/arm/mach-ep93xx/edb9312.c
@@ -19,7 +19,7 @@
 #include <linux/ioport.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -44,10 +44,16 @@
 	.resource	= &edb9312_flash_resource,
 };
 
+static struct ep93xx_eth_data edb9312_eth_data = {
+	.phy_id			= 1,
+};
+
 static void __init edb9312_init_machine(void)
 {
 	ep93xx_init_devices();
 	platform_device_register(&edb9312_flash);
+
+	ep93xx_register_eth(&edb9312_eth_data, 1);
 }
 
 MACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board")
diff --git a/arch/arm/mach-ep93xx/edb9315.c b/arch/arm/mach-ep93xx/edb9315.c
index 7e37395..9469b35 100644
--- a/arch/arm/mach-ep93xx/edb9315.c
+++ b/arch/arm/mach-ep93xx/edb9315.c
@@ -18,7 +18,7 @@
 #include <linux/ioport.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -43,10 +43,16 @@
 	.resource	= &edb9315_flash_resource,
 };
 
+static struct ep93xx_eth_data edb9315_eth_data = {
+	.phy_id			= 1,
+};
+
 static void __init edb9315_init_machine(void)
 {
 	ep93xx_init_devices();
 	platform_device_register(&edb9315_flash);
+
+	ep93xx_register_eth(&edb9315_eth_data, 1);
 }
 
 MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board")
diff --git a/arch/arm/mach-ep93xx/edb9315a.c b/arch/arm/mach-ep93xx/edb9315a.c
index 08a7c9b..584457c 100644
--- a/arch/arm/mach-ep93xx/edb9315a.c
+++ b/arch/arm/mach-ep93xx/edb9315a.c
@@ -18,7 +18,7 @@
 #include <linux/ioport.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -47,36 +47,12 @@
 	.phy_id			= 1,
 };
 
-static struct resource edb9315a_eth_resource[] = {
-	{
-		.start	= EP93XX_ETHERNET_PHYS_BASE,
-		.end	= EP93XX_ETHERNET_PHYS_BASE + 0xffff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_EP93XX_ETHERNET,
-		.end	= IRQ_EP93XX_ETHERNET,
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
-static struct platform_device edb9315a_eth_device = {
-	.name		= "ep93xx-eth",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= &edb9315a_eth_data,
-	},
-	.num_resources	= 2,
-	.resource	= edb9315a_eth_resource,
-};
-
 static void __init edb9315a_init_machine(void)
 {
 	ep93xx_init_devices();
 	platform_device_register(&edb9315a_flash);
 
-	memcpy(edb9315a_eth_data.dev_addr,
-		(void *)(EP93XX_ETHERNET_BASE + 0x50), 6);
-	platform_device_register(&edb9315a_eth_device);
+	ep93xx_register_eth(&edb9315a_eth_data, 1);
 }
 
 MACHINE_START(EDB9315A, "Cirrus Logic EDB9315A Evaluation Board")
diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c
index 9b41ec1..035b24e 100644
--- a/arch/arm/mach-ep93xx/gesbc9312.c
+++ b/arch/arm/mach-ep93xx/gesbc9312.c
@@ -18,7 +18,7 @@
 #include <linux/ioport.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -44,36 +44,15 @@
 };
 
 static struct ep93xx_eth_data gesbc9312_eth_data = {
-	.phy_id			= 1,
-};
-
-static struct resource gesbc9312_eth_resource[] = {
-	{
-		.start	= EP93XX_ETHERNET_PHYS_BASE,
-		.end	= EP93XX_ETHERNET_PHYS_BASE + 0xffff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_EP93XX_ETHERNET,
-		.end	= IRQ_EP93XX_ETHERNET,
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
-static struct platform_device gesbc9312_eth_device = {
-	.name		= "ep93xx-eth",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= &gesbc9312_eth_data,
-	},
-	.num_resources	= 2,
-	.resource	= gesbc9312_eth_resource,
+	.phy_id		= 1,
 };
 
 static void __init gesbc9312_init_machine(void)
 {
 	ep93xx_init_devices();
 	platform_device_register(&gesbc9312_flash);
-	platform_device_register(&gesbc9312_eth_device);
+
+	ep93xx_register_eth(&gesbc9312_eth_data, 0);
 }
 
 MACHINE_START(GESBC9312, "Glomation GESBC-9312-sx")
diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c
index 0f3fb87..482cf3d 100644
--- a/arch/arm/mach-ep93xx/gpio.c
+++ b/arch/arm/mach-ep93xx/gpio.c
@@ -16,9 +16,9 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/seq_file.h>
+#include <linux/io.h>
 
 #include <mach/ep93xx-regs.h>
-#include <asm/io.h>
 #include <asm/gpio.h>
 
 struct ep93xx_gpio_chip {
@@ -141,10 +141,10 @@
 static struct ep93xx_gpio_chip ep93xx_gpio_banks[] = {
 	EP93XX_GPIO_BANK("A", 0x00, 0x10, 0),
 	EP93XX_GPIO_BANK("B", 0x04, 0x14, 8),
-	EP93XX_GPIO_BANK("C", 0x30, 0x34, 40),
+	EP93XX_GPIO_BANK("C", 0x08, 0x18, 40),
 	EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 24),
 	EP93XX_GPIO_BANK("E", 0x20, 0x24, 32),
-	EP93XX_GPIO_BANK("F", 0x08, 0x18, 16),
+	EP93XX_GPIO_BANK("F", 0x30, 0x34, 16),
 	EP93XX_GPIO_BANK("G", 0x38, 0x3c, 48),
 	EP93XX_GPIO_BANK("H", 0x40, 0x44, 56),
 };
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
index 9f4458c..22d6c9a 100644
--- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
@@ -6,6 +6,40 @@
 #define __ASM_ARCH_EP93XX_REGS_H
 
 /*
+ * EP93xx Physical Memory Map:
+ *
+ * The ASDO pin is sampled at system reset to select a synchronous or
+ * asynchronous boot configuration.  When ASDO is "1" (i.e. pulled-up)
+ * the synchronous boot mode is selected.  When ASDO is "0" (i.e
+ * pulled-down) the asynchronous boot mode is selected.
+ *
+ * In synchronous boot mode nSDCE3 is decoded starting at physical address
+ * 0x00000000 and nCS0 is decoded starting at 0xf0000000.  For asynchronous
+ * boot mode they are swapped with nCS0 decoded at 0x00000000 ann nSDCE3
+ * decoded at 0xf0000000.
+ *
+ * There is known errata for the EP93xx dealing with External Memory
+ * Configurations.  Please refer to "AN273: EP93xx Silicon Rev E Design
+ * Guidelines" for more information.  This document can be found at:
+ *
+ *	http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf
+ */
+
+#define EP93XX_CS0_PHYS_BASE_ASYNC	0x00000000	/* ASDO Pin = 0 */
+#define EP93XX_SDCE3_PHYS_BASE_SYNC	0x00000000	/* ASDO Pin = 1 */
+#define EP93XX_CS1_PHYS_BASE		0x10000000
+#define EP93XX_CS2_PHYS_BASE		0x20000000
+#define EP93XX_CS3_PHYS_BASE		0x30000000
+#define EP93XX_PCMCIA_PHYS_BASE		0x40000000
+#define EP93XX_CS6_PHYS_BASE		0x60000000
+#define EP93XX_CS7_PHYS_BASE		0x70000000
+#define EP93XX_SDCE0_PHYS_BASE		0xc0000000
+#define EP93XX_SDCE1_PHYS_BASE		0xd0000000
+#define EP93XX_SDCE2_PHYS_BASE		0xe0000000
+#define EP93XX_SDCE3_PHYS_BASE_ASYNC	0xf0000000	/* ASDO Pin = 0 */
+#define EP93XX_CS0_PHYS_BASE_SYNC	0xf0000000	/* ASDO Pin = 1 */
+
+/*
  * EP93xx linux memory map:
  *
  * virt		phys		size
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
index b5c1824..db2489d 100644
--- a/arch/arm/mach-ep93xx/include/mach/platform.h
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -4,17 +4,17 @@
 
 #ifndef __ASSEMBLY__
 
-void ep93xx_map_io(void);
-void ep93xx_init_irq(void);
-void ep93xx_init_time(unsigned long);
-void ep93xx_init_devices(void);
-extern struct sys_timer ep93xx_timer;
-
 struct ep93xx_eth_data
 {
 	unsigned char	dev_addr[6];
 	unsigned char	phy_id;
 };
 
+void ep93xx_map_io(void);
+void ep93xx_init_irq(void);
+void ep93xx_init_time(unsigned long);
+void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr);
+void ep93xx_init_devices(void);
+extern struct sys_timer ep93xx_timer;
 
 #endif
diff --git a/arch/arm/mach-ep93xx/include/mach/ts72xx.h b/arch/arm/mach-ep93xx/include/mach/ts72xx.h
index 30b318a..34ddec0 100644
--- a/arch/arm/mach-ep93xx/include/mach/ts72xx.h
+++ b/arch/arm/mach-ep93xx/include/mach/ts72xx.h
@@ -70,7 +70,7 @@
 
 
 #ifndef __ASSEMBLY__
-#include <asm/io.h>
+#include <linux/io.h>
 
 static inline int board_is_ts7200(void)
 {
diff --git a/arch/arm/mach-ep93xx/include/mach/uncompress.h b/arch/arm/mach-ep93xx/include/mach/uncompress.h
index 1fd2f17..16026c2 100644
--- a/arch/arm/mach-ep93xx/include/mach/uncompress.h
+++ b/arch/arm/mach-ep93xx/include/mach/uncompress.h
@@ -31,10 +31,19 @@
 	*((volatile unsigned int *)ptr) = value;
 }
 
+#if defined(CONFIG_EP93XX_EARLY_UART1)
+#define UART_BASE		EP93XX_UART1_PHYS_BASE
+#elif defined(CONFIG_EP93XX_EARLY_UART2)
+#define UART_BASE		EP93XX_UART2_PHYS_BASE
+#elif defined(CONFIG_EP93XX_EARLY_UART3)
+#define UART_BASE		EP93XX_UART3_PHYS_BASE
+#else
+#define UART_BASE		EP93XX_UART1_PHYS_BASE
+#endif
 
-#define PHYS_UART1_DATA		0x808c0000
-#define PHYS_UART1_FLAG		0x808c0018
-#define UART1_FLAG_TXFF		0x20
+#define PHYS_UART_DATA		(UART_BASE + 0x00)
+#define PHYS_UART_FLAG		(UART_BASE + 0x18)
+#define UART_FLAG_TXFF		0x20
 
 static inline void putc(int c)
 {
@@ -42,11 +51,11 @@
 
 	for (i = 0; i < 1000; i++) {
 		/* Transmit fifo not full?  */
-		if (!(__raw_readb(PHYS_UART1_FLAG) & UART1_FLAG_TXFF))
+		if (!(__raw_readb(PHYS_UART_FLAG) & UART_FLAG_TXFF))
 			break;
 	}
 
-	__raw_writeb(c, PHYS_UART1_DATA);
+	__raw_writeb(c, PHYS_UART_DATA);
 }
 
 static inline void flush(void)
diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c
index de047a5..c219723 100644
--- a/arch/arm/mach-ep93xx/micro9.c
+++ b/arch/arm/mach-ep93xx/micro9.c
@@ -16,10 +16,9 @@
 #include <linux/mm.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
-
+#include <linux/io.h>
 #include <linux/mtd/physmap.h>
 
-#include <asm/io.h>
 #include <mach/hardware.h>
 
 #include <asm/mach/arch.h>
@@ -29,38 +28,9 @@
        .phy_id                 = 0x1f,
 };
 
-static struct resource micro9_eth_resource[] = {
-       {
-               .start  = EP93XX_ETHERNET_PHYS_BASE,
-               .end    = EP93XX_ETHERNET_PHYS_BASE + 0xffff,
-               .flags  = IORESOURCE_MEM,
-       }, {
-               .start  = IRQ_EP93XX_ETHERNET,
-               .end    = IRQ_EP93XX_ETHERNET,
-               .flags  = IORESOURCE_IRQ,
-       }
-};
-
-static struct platform_device micro9_eth_device = {
-       .name           = "ep93xx-eth",
-       .id             = -1,
-       .dev            = {
-               .platform_data  = &micro9_eth_data,
-       },
-       .num_resources = ARRAY_SIZE(micro9_eth_resource),
-       .resource       = micro9_eth_resource,
-};
-
-static void __init micro9_eth_init(void)
-{
-       memcpy(micro9_eth_data.dev_addr,
-               (void *)(EP93XX_ETHERNET_BASE + 0x50), 6);
-       platform_device_register(&micro9_eth_device);
-}
-
 static void __init micro9_init(void)
 {
-       micro9_eth_init();
+	ep93xx_register_eth(&micro9_eth_data, 1);
 }
 
 /*
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index c3cbff1..b4aa4c0 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -19,7 +19,7 @@
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
 #include <linux/m48t86.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -161,28 +161,6 @@
 	.phy_id			= 1,
 };
 
-static struct resource ts72xx_eth_resource[] = {
-	{
-		.start	= EP93XX_ETHERNET_PHYS_BASE,
-		.end	= EP93XX_ETHERNET_PHYS_BASE + 0xffff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_EP93XX_ETHERNET,
-		.end	= IRQ_EP93XX_ETHERNET,
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
-static struct platform_device ts72xx_eth_device = {
-	.name		= "ep93xx-eth",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= &ts72xx_eth_data,
-	},
-	.num_resources	= 2,
-	.resource	= ts72xx_eth_resource,
-};
-
 static void __init ts72xx_init_machine(void)
 {
 	ep93xx_init_devices();
@@ -190,9 +168,7 @@
 		platform_device_register(&ts72xx_flash);
 	platform_device_register(&ts72xx_rtc_device);
 
-	memcpy(ts72xx_eth_data.dev_addr,
-		(void *)(EP93XX_ETHERNET_BASE + 0x50), 6);
-	platform_device_register(&ts72xx_eth_device);
+	ep93xx_register_eth(&ts72xx_eth_data, 1);
 }
 
 MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
diff --git a/arch/arm/mach-footbridge/cats-hw.c b/arch/arm/mach-footbridge/cats-hw.c
index c261472..6a5b437 100644
--- a/arch/arm/mach-footbridge/cats-hw.c
+++ b/arch/arm/mach-footbridge/cats-hw.c
@@ -9,9 +9,9 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/screen_info.h>
+#include <linux/io.h>
 
 #include <asm/hardware/dec21285.h>
-#include <asm/io.h>
 #include <asm/mach-types.h>
 #include <asm/setup.h>
 
diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c
index b08ab50..818014e 100644
--- a/arch/arm/mach-footbridge/common.c
+++ b/arch/arm/mach-footbridge/common.c
@@ -13,11 +13,11 @@
 #include <linux/ioport.h>
 #include <linux/list.h>
 #include <linux/init.h>
+#include <linux/io.h>
  
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 #include <asm/mach-types.h>
 #include <asm/setup.h>
 #include <asm/hardware/dec21285.h>
diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c
index d0dc51e..d4c1e52 100644
--- a/arch/arm/mach-footbridge/dc21285.c
+++ b/arch/arm/mach-footbridge/dc21285.c
@@ -16,8 +16,8 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/mach/pci.h>
diff --git a/arch/arm/mach-footbridge/dma.c b/arch/arm/mach-footbridge/dma.c
index 1f9b09b..b653e9c 100644
--- a/arch/arm/mach-footbridge/dma.c
+++ b/arch/arm/mach-footbridge/dma.c
@@ -11,9 +11,9 @@
  *			ISA DMA controllers.
  */
 #include <linux/init.h>
+#include <linux/io.h>
 
 #include <asm/dma.h>
-#include <asm/io.h>
 #include <asm/scatterlist.h>
 
 #include <asm/mach/dma.h>
diff --git a/arch/arm/mach-footbridge/include/mach/memory.h b/arch/arm/mach-footbridge/include/mach/memory.h
index e9cae99..6ae2f1a 100644
--- a/arch/arm/mach-footbridge/include/mach/memory.h
+++ b/arch/arm/mach-footbridge/include/mach/memory.h
@@ -42,10 +42,6 @@
 
 #endif
 
-/* Task size and page offset at 3GB */
-#define TASK_SIZE		UL(0xbf000000)
-#define PAGE_OFFSET		UL(0xc0000000)
-
 /*
  * Cache flushing area.
  */
@@ -56,12 +52,6 @@
  */
 #define PHYS_OFFSET		UL(0x00000000)
 
-/*
- * This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-#define TASK_UNMAPPED_BASE ((TASK_SIZE + 0x01000000) / 3)
-
 #define FLUSH_BASE_PHYS		0x50000000
 
 #endif
diff --git a/arch/arm/mach-footbridge/include/mach/system.h b/arch/arm/mach-footbridge/include/mach/system.h
index 01c9f40..2db7f36 100644
--- a/arch/arm/mach-footbridge/include/mach/system.h
+++ b/arch/arm/mach-footbridge/include/mach/system.h
@@ -7,8 +7,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/io.h>
 #include <asm/hardware/dec21285.h>
-#include <asm/io.h>
 #include <mach/hardware.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
diff --git a/arch/arm/mach-footbridge/isa-irq.c b/arch/arm/mach-footbridge/isa-irq.c
index 7132e52..54fec9a 100644
--- a/arch/arm/mach-footbridge/isa-irq.c
+++ b/arch/arm/mach-footbridge/isa-irq.c
@@ -18,13 +18,13 @@
 #include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
 #include <asm/mach/irq.h>
 
 #include <mach/hardware.h>
 #include <asm/hardware/dec21285.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 #include <asm/mach-types.h>
 
 static void isa_mask_pic_lo_irq(unsigned int irq)
@@ -94,8 +94,7 @@
 		return;
 	}
 
-	desc = irq_desc + isa_irq;
-	desc_handle_irq(isa_irq, desc);
+	generic_handle_irq(isa_irq);
 }
 
 static struct irqaction irq_cascade = {
diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c
index a764e01..0c83900 100644
--- a/arch/arm/mach-footbridge/isa-timer.c
+++ b/arch/arm/mach-footbridge/isa-timer.c
@@ -7,8 +7,8 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 
 #include <asm/mach/time.h>
diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c
index a1f381c..00b0ddc 100644
--- a/arch/arm/mach-footbridge/netwinder-hw.c
+++ b/arch/arm/mach-footbridge/netwinder-hw.c
@@ -10,9 +10,9 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
 #include <asm/hardware/dec21285.h>
-#include <asm/io.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
 #include <asm/setup.h>
diff --git a/arch/arm/mach-footbridge/time.c b/arch/arm/mach-footbridge/time.c
index 004819e..cd1b54f 100644
--- a/arch/arm/mach-footbridge/time.c
+++ b/arch/arm/mach-footbridge/time.c
@@ -22,9 +22,9 @@
 #include <linux/sched.h>
 #include <linux/mc146818rtc.h>
 #include <linux/bcd.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 
 #include <asm/mach/time.h>
 #include "common.h"
diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c
index b5f9741..7a26148 100644
--- a/arch/arm/mach-h720x/common.c
+++ b/arch/arm/mach-h720x/common.c
@@ -18,11 +18,11 @@
 #include <linux/mman.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/dma.h>
-#include <asm/io.h>
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
@@ -104,14 +104,12 @@
                  struct irq_desc *desc)
 {
 	IRQDBG("%s irq: %d\n", __func__, irq);
-	desc = irq_desc + irq;
 	while (mask) {
 		if (mask & 1) {
 			IRQDBG("handling irq %d\n", irq);
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 		}
 		irq++;
-		desc++;
 		mask >>= 1;
 	}
 }
diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c
index 53e1f62..fd33a19 100644
--- a/arch/arm/mach-h720x/cpu-h7202.c
+++ b/arch/arm/mach-h720x/cpu-h7202.c
@@ -120,12 +120,10 @@
 
 	mask >>= 1;
 	irq = IRQ_TIMER1;
-	desc = irq_desc + irq;
 	while (mask) {
 		if (mask & 1)
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 		irq++;
-		desc++;
 		mask >>= 1;
 	}
 }
diff --git a/arch/arm/mach-imx/clock.c b/arch/arm/mach-imx/clock.c
index 4b4230d..7ec60fc 100644
--- a/arch/arm/mach-imx/clock.c
+++ b/arch/arm/mach-imx/clock.c
@@ -21,8 +21,8 @@
 #include <linux/list.h>
 #include <linux/math64.h>
 #include <linux/err.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <mach/imx-regs.h>
 
 /*
diff --git a/arch/arm/mach-imx/include/mach/irqs.h b/arch/arm/mach-imx/include/mach/irqs.h
index eb8d5bd..67812c5a 100644
--- a/arch/arm/mach-imx/include/mach/irqs.h
+++ b/arch/arm/mach-imx/include/mach/irqs.h
@@ -111,6 +111,11 @@
 /* decode irq number to use with IMR(x), ISR(x) and friends */
 #define IRQ_TO_REG(irq) ((irq - IMX_IRQS) >> 5)
 
+/* all normal IRQs can be FIQs */
+#define FIQ_START	0
+/* switch betwean IRQ and FIQ */
+extern int imx_set_irq_fiq(unsigned int irq, unsigned int type);
+
 #define NR_IRQS (IRQ_GPIOD(32) + 1)
 #define IRQ_GPIO(x)
 #endif
diff --git a/arch/arm/mach-imx/irq.c b/arch/arm/mach-imx/irq.c
index 798f221..531b95d 100644
--- a/arch/arm/mach-imx/irq.c
+++ b/arch/arm/mach-imx/irq.c
@@ -26,20 +26,17 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/timer.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 
 #include <asm/mach/irq.h>
 
 /*
  *
  * We simply use the ENABLE DISABLE registers inside of the IMX
- * to turn on/off specific interrupts.  FIXME- We should
- * also add support for the accelerated interrupt controller
- * by putting offets to irq jump code in the appropriate
- * places.
+ * to turn on/off specific interrupts.
  *
  */
 
@@ -102,6 +99,28 @@
 	__raw_writel(irq, IMX_AITC_INTENNUM);
 }
 
+#ifdef CONFIG_FIQ
+int imx_set_irq_fiq(unsigned int irq, unsigned int type)
+{
+	unsigned int irqt;
+
+	if (irq >= IMX_IRQS)
+		return -EINVAL;
+
+	if (irq < IMX_IRQS / 2) {
+		irqt = __raw_readl(IMX_AITC_INTTYPEL) & ~(1 << irq);
+		__raw_writel(irqt | (!!type << irq), IMX_AITC_INTTYPEL);
+	} else {
+		irq -= IMX_IRQS / 2;
+		irqt = __raw_readl(IMX_AITC_INTTYPEH) & ~(1 << irq);
+		__raw_writel(irqt | (!!type << irq), IMX_AITC_INTTYPEH);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(imx_set_irq_fiq);
+#endif /* CONFIG_FIQ */
+
 static int
 imx_gpio_irq_type(unsigned int _irq, unsigned int type)
 {
@@ -182,14 +201,12 @@
 imx_gpio_handler(unsigned int mask, unsigned int irq,
                  struct irq_desc *desc)
 {
-	desc = irq_desc + irq;
 	while (mask) {
 		if (mask & 1) {
 			DEBUG_IRQ("handling irq %d\n", irq);
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 		}
 		irq++;
-		desc++;
 		mask >>= 1;
 	}
 }
@@ -286,4 +303,9 @@
 
 	/* Release masking of interrupts according to priority */
 	__raw_writel(-1, IMX_AITC_NIMASK);
+
+#ifdef CONFIG_FIQ
+	/* Initialize FIQ */
+	init_FIQ();
+#endif
 }
diff --git a/arch/arm/mach-imx/leds-mx1ads.c b/arch/arm/mach-imx/leds-mx1ads.c
index af81621..1d48f27 100644
--- a/arch/arm/mach-imx/leds-mx1ads.c
+++ b/arch/arm/mach-imx/leds-mx1ads.c
@@ -13,9 +13,9 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
 #include <asm/system.h>
-#include <asm/io.h>
 #include <asm/leds.h>
 #include "leds.h"
 
diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index 08be387..a11765f 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -18,9 +18,9 @@
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/leds.h>
 #include <asm/irq.h>
 #include <asm/mach/time.h>
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 8bacf6d4..595b739 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -19,10 +19,10 @@
 #include <linux/termios.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/serial.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 #include <asm/hardware/arm_timer.h>
 #include <mach/cm.h>
 #include <asm/system.h>
diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c
index 7c49d55..e4f72d2 100644
--- a/arch/arm/mach-integrator/cpu.c
+++ b/arch/arm/mach-integrator/cpu.c
@@ -17,9 +17,9 @@
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/mach-types.h>
 #include <asm/hardware/icst525.h>
 
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index 3c8383d..172299a 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -20,8 +20,8 @@
 #include <linux/mm.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/clcd.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/hardware/icst525.h>
 #include <mach/lm.h>
 #include <mach/impd1.h>
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 6e472b5..8138a7e 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -27,9 +27,9 @@
 #include <linux/sysdev.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/kmi.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/setup.h>
 #include <asm/param.h>		/* HZ */
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 6b99e9c..88026cc 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -19,9 +19,9 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/kmi.h>
 #include <linux/amba/clcd.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
@@ -217,8 +217,7 @@
 
 		irq += IRQ_SIC_START;
 
-		desc = irq_desc + irq;
-		desc_handle_irq(irq, desc);
+		generic_handle_irq(irq);
 	} while (status);
 }
 
diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c
index 7bc6881..8dcc823 100644
--- a/arch/arm/mach-integrator/leds.c
+++ b/arch/arm/mach-integrator/leds.c
@@ -24,9 +24,9 @@
 #include <linux/init.h>
 #include <linux/smp.h>
 #include <linux/spinlock.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/leds.h>
 #include <asm/system.h>
 #include <asm/mach-types.h>
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index 9f2b1ea..f1d72b2 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -27,9 +27,9 @@
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/mach/pci.h>
diff --git a/arch/arm/mach-iop13xx/include/mach/memory.h b/arch/arm/mach-iop13xx/include/mach/memory.h
index e8b59d8..b82602d 100644
--- a/arch/arm/mach-iop13xx/include/mach/memory.h
+++ b/arch/arm/mach-iop13xx/include/mach/memory.h
@@ -7,9 +7,6 @@
  * Physical DRAM offset.
  */
 #define PHYS_OFFSET	UL(0x00000000)
-#define TASK_SIZE  	UL(0x3f000000)
-#define PAGE_OFFSET	UL(0x40000000)
-#define TASK_UNMAPPED_BASE ((TASK_SIZE + 0x01000000) / 3)
 
 #ifndef __ASSEMBLY__
 
@@ -29,32 +26,52 @@
 
 /* RAM has 1:1 mapping on the PCIe/x Busses */
 #define __virt_to_bus(x)	(__virt_to_phys(x))
-#define __bus_to_virt(x)    (__phys_to_virt(x))
+#define __bus_to_virt(x)	(__phys_to_virt(x))
 
-#define virt_to_lbus(x) 					   \
-(( ((void*)(x) >= (void*)IOP13XX_PMMR_V_START) &&		   \
-((void*)(x) < (void*)IOP13XX_PMMR_V_END) ) ? 			   \
-((x) - IOP13XX_PMMR_VIRT_MEM_BASE + IOP13XX_PMMR_PHYS_MEM_BASE) : \
-((x) - PAGE_OFFSET + PHYS_OFFSET))
+static inline dma_addr_t __virt_to_lbus(unsigned long x)
+{
+	return x + IOP13XX_PMMR_PHYS_MEM_BASE - IOP13XX_PMMR_VIRT_MEM_BASE;
+}
 
-#define lbus_to_virt(x)                                            \
-(( ((x) >= IOP13XX_PMMR_P_START) && ((x) < IOP13XX_PMMR_P_END) ) ? \
-((x) - IOP13XX_PMMR_PHYS_MEM_BASE + IOP13XX_PMMR_VIRT_MEM_BASE ) : \
-((x) - PHYS_OFFSET + PAGE_OFFSET))
+static inline unsigned long __lbus_to_virt(dma_addr_t x)
+{
+	return x + IOP13XX_PMMR_VIRT_MEM_BASE - IOP13XX_PMMR_PHYS_MEM_BASE;
+}
+
+#define __is_lbus_dma(a)				\
+	((a) >= IOP13XX_PMMR_P_START && (a) < IOP13XX_PMMR_P_END)
+
+#define __is_lbus_virt(a)				\
+	((a) >= IOP13XX_PMMR_V_START && (a) < IOP13XX_PMMR_V_END)
 
 /* Device is an lbus device if it is on the platform bus of the IOP13XX */
-#define is_lbus_device(dev) (dev &&\
-			     (strncmp(dev->bus->name, "platform", 8) == 0))
+#define is_lbus_device(dev) 				\
+	(dev && strncmp(dev->bus->name, "platform", 8) == 0)
+
+#define __arch_dma_to_virt(dev, addr)					\
+	({								\
+		unsigned long __virt;					\
+		dma_addr_t __dma = addr;				\
+		if (is_lbus_device(dev) && __is_lbus_dma(__dma))	\
+			__virt = __lbus_to_virt(__dma);			\
+		else							\
+			__virt = __bus_to_virt(__dma);			\
+		(void *)__virt;						\
+	})
+
+#define __arch_virt_to_dma(dev, addr)					\
+	({								\
+		unsigned long __virt = (unsigned long)addr;		\
+		dma_addr_t __dma;					\
+		if (is_lbus_device(dev) && __is_lbus_virt(__virt))	\
+			__dma = __virt_to_lbus(__virt);			\
+		else							\
+			__dma = __virt_to_bus(__virt);			\
+		__dma;							\
+	})
 
 #define __arch_page_to_dma(dev, page)					\
-({is_lbus_device(dev) ? (dma_addr_t)virt_to_lbus(page_address(page)) : \
-(dma_addr_t)__virt_to_bus(page_address(page));})
-
-#define __arch_dma_to_virt(dev, addr) \
-({is_lbus_device(dev) ? lbus_to_virt(addr) : __bus_to_virt(addr);})
-
-#define __arch_virt_to_dma(dev, addr) \
-({is_lbus_device(dev) ? virt_to_lbus(addr) : __virt_to_bus(addr);})
+	__arch_virt_to_dma(dev, page_address(page))
 
 #endif /* CONFIG_ARCH_IOP13XX */
 #endif /* !ASSEMBLY */
diff --git a/arch/arm/mach-iop13xx/include/mach/pci.h b/arch/arm/mach-iop13xx/include/mach/pci.h
index 17b5515..59f42b5 100644
--- a/arch/arm/mach-iop13xx/include/mach/pci.h
+++ b/arch/arm/mach-iop13xx/include/mach/pci.h
@@ -1,7 +1,7 @@
 #ifndef _IOP13XX_PCI_H_
 #define _IOP13XX_PCI_H_
+#include <linux/io.h>
 #include <mach/irqs.h>
-#include <asm/io.h>
 
 struct pci_sys_data;
 struct hw_pci;
diff --git a/arch/arm/mach-iop13xx/io.c b/arch/arm/mach-iop13xx/io.c
index 26cfa31..5295809 100644
--- a/arch/arm/mach-iop13xx/io.c
+++ b/arch/arm/mach-iop13xx/io.c
@@ -18,8 +18,8 @@
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 
 void * __iomem __iop13xx_io(unsigned long io_addr)
 {
diff --git a/arch/arm/mach-iop13xx/msi.c b/arch/arm/mach-iop13xx/msi.c
index 63ef1124c..f34b0ed 100644
--- a/arch/arm/mach-iop13xx/msi.c
+++ b/arch/arm/mach-iop13xx/msi.c
@@ -110,8 +110,7 @@
 		do {
 			j = find_first_bit(&status, 32);
 			(write_imipr[i])(1 << j); /* write back to clear bit */
-			desc = irq_desc + IRQ_IOP13XX_MSI_0 + j + (32*i);
-			desc_handle_irq(IRQ_IOP13XX_MSI_0 + j + (32*i),	desc);
+			generic_handle_irq(IRQ_IOP13XX_MSI_0 + j + (32*i));
 			status = (read_imipr[i])();
 		} while (status);
 	}
diff --git a/arch/arm/mach-iop13xx/setup.c b/arch/arm/mach-iop13xx/setup.c
index b17ccc8..cfd4d2e 100644
--- a/arch/arm/mach-iop13xx/setup.c
+++ b/arch/arm/mach-iop13xx/setup.c
@@ -18,13 +18,13 @@
  */
 
 #include <linux/serial_8250.h>
+#include <linux/io.h>
 #ifdef CONFIG_MTD_PHYSMAP
 #include <linux/mtd/physmap.h>
 #endif
 #include <asm/mach/map.h>
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 #include <asm/hardware/iop_adma.h>
 
 #define IOP13XX_UART_XTAL 33334000
diff --git a/arch/arm/mach-iop13xx/tpmi.c b/arch/arm/mach-iop13xx/tpmi.c
index 2476347..c6af1e1 100644
--- a/arch/arm/mach-iop13xx/tpmi.c
+++ b/arch/arm/mach-iop13xx/tpmi.c
@@ -21,7 +21,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/irq.h>
 #include <asm/sizes.h>
 
diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c
index 45d6127..a9c2dfd 100644
--- a/arch/arm/mach-iop32x/glantank.c
+++ b/arch/arm/mach-iop32x/glantank.c
@@ -25,8 +25,8 @@
 #include <linux/mtd/physmap.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c
index 082818aa..dd1cd99 100644
--- a/arch/arm/mach-iop32x/iq31244.c
+++ b/arch/arm/mach-iop32x/iq31244.c
@@ -26,8 +26,9 @@
 #include <linux/serial_8250.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
+#include <asm/cputype.h>
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -49,8 +50,7 @@
 
 static int is_80219(void)
 {
-	extern int processor_id;
-	return !!((processor_id & 0xffffffe0) == 0x69052e20);
+	return !!((read_cpuid_id() & 0xffffffe0) == 0x69052e20);
 }
 
 static int is_ep80219(void)
diff --git a/arch/arm/mach-iop32x/iq80321.c b/arch/arm/mach-iop32x/iq80321.c
index d735539..fbe2779 100644
--- a/arch/arm/mach-iop32x/iq80321.c
+++ b/arch/arm/mach-iop32x/iq80321.c
@@ -23,8 +23,8 @@
 #include <linux/serial_8250.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c
index 3173f9c..d2e4278 100644
--- a/arch/arm/mach-iop32x/n2100.c
+++ b/arch/arm/mach-iop32x/n2100.c
@@ -30,8 +30,8 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/reboot.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
diff --git a/arch/arm/mach-iop33x/iq80331.c b/arch/arm/mach-iop33x/iq80331.c
index c7d99f9..d51e10c 100644
--- a/arch/arm/mach-iop33x/iq80331.c
+++ b/arch/arm/mach-iop33x/iq80331.c
@@ -22,8 +22,8 @@
 #include <linux/serial_8250.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
diff --git a/arch/arm/mach-iop33x/iq80332.c b/arch/arm/mach-iop33x/iq80332.c
index af616c5..92fb44c 100644
--- a/arch/arm/mach-iop33x/iq80332.c
+++ b/arch/arm/mach-iop33x/iq80332.c
@@ -22,8 +22,8 @@
 #include <linux/serial_8250.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
diff --git a/arch/arm/mach-iop33x/uart.c b/arch/arm/mach-iop33x/uart.c
index 8c21870..cdae24e 100644
--- a/arch/arm/mach-iop33x/uart.c
+++ b/arch/arm/mach-iop33x/uart.c
@@ -17,7 +17,7 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <asm/mach/map.h>
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index a6a4f93..babb225 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -84,64 +84,57 @@
 		.virtual	= IXP2000_CAP_VIRT_BASE,
 		.pfn		= __phys_to_pfn(IXP2000_CAP_PHYS_BASE),
 		.length		= IXP2000_CAP_SIZE,
-		.type		= MT_DEVICE_IXP2000,
+		.type		= MT_DEVICE,
 	}, {
 		.virtual	= IXP2000_INTCTL_VIRT_BASE,
 		.pfn		= __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE),
 		.length		= IXP2000_INTCTL_SIZE,
-		.type		= MT_DEVICE_IXP2000,
+		.type		= MT_DEVICE,
 	}, {
 		.virtual	= IXP2000_PCI_CREG_VIRT_BASE,
 		.pfn		= __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE),
 		.length		= IXP2000_PCI_CREG_SIZE,
-		.type		= MT_DEVICE_IXP2000,
+		.type		= MT_DEVICE,
 	}, {
 		.virtual	= IXP2000_PCI_CSR_VIRT_BASE,
 		.pfn		= __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE),
 		.length		= IXP2000_PCI_CSR_SIZE,
-		.type		= MT_DEVICE_IXP2000,
+		.type		= MT_DEVICE,
 	}, {
 		.virtual	= IXP2000_MSF_VIRT_BASE,
 		.pfn		= __phys_to_pfn(IXP2000_MSF_PHYS_BASE),
 		.length		= IXP2000_MSF_SIZE,
-		.type		= MT_DEVICE_IXP2000,
+		.type		= MT_DEVICE,
 	}, {
 		.virtual	= IXP2000_SCRATCH_RING_VIRT_BASE,
 		.pfn		= __phys_to_pfn(IXP2000_SCRATCH_RING_PHYS_BASE),
 		.length		= IXP2000_SCRATCH_RING_SIZE,
-		.type		= MT_DEVICE_IXP2000,
+		.type		= MT_DEVICE,
 	}, {
 		.virtual	= IXP2000_SRAM0_VIRT_BASE,
 		.pfn		= __phys_to_pfn(IXP2000_SRAM0_PHYS_BASE),
 		.length		= IXP2000_SRAM0_SIZE,
-		.type		= MT_DEVICE_IXP2000,
+		.type		= MT_DEVICE,
 	}, {
 		.virtual	= IXP2000_PCI_IO_VIRT_BASE,
 		.pfn		= __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE),
 		.length		= IXP2000_PCI_IO_SIZE,
-		.type		= MT_DEVICE_IXP2000,
+		.type		= MT_DEVICE,
 	}, {
 		.virtual	= IXP2000_PCI_CFG0_VIRT_BASE,
 		.pfn		= __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE),
 		.length		= IXP2000_PCI_CFG0_SIZE,
-		.type		= MT_DEVICE_IXP2000,
+		.type		= MT_DEVICE,
 	}, {
 		.virtual	= IXP2000_PCI_CFG1_VIRT_BASE,
 		.pfn		= __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE),
 		.length		= IXP2000_PCI_CFG1_SIZE,
-		.type		= MT_DEVICE_IXP2000,
+		.type		= MT_DEVICE,
 	}
 };
 
 void __init ixp2000_map_io(void)
 {
-	/*
-	 * On IXP2400 CPUs we need to use MT_DEVICE_IXP2000 so that
-	 * XCB=101 (to avoid triggering erratum #66), and given that
-	 * this mode speeds up I/O accesses and we have write buffer
-	 * flushes in the right places anyway, it doesn't hurt to use
-	 * XCB=101 for all IXP2000s.
-	 */
 	iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc));
 
 	/* Set slowport to 8-bit mode.  */
@@ -311,8 +304,7 @@
 		   
 	for (i = 0; i <= 7; i++) {
 		if (status & (1<<i)) {
-			desc = irq_desc + i + IRQ_IXP2000_GPIO0;
-			desc_handle_irq(i + IRQ_IXP2000_GPIO0, desc);
+			generic_handle_irq(i + IRQ_IXP2000_GPIO0);
 		}
 	}
 }
@@ -404,8 +396,7 @@
 
 	for(i = 31; i >= 0; i--) {
 		if(status & (1 << i)) {
-			desc = irq_desc + IRQ_IXP2000_DRAM0_MIN_ERR + i;
-			desc_handle_irq(IRQ_IXP2000_DRAM0_MIN_ERR + i, desc);
+			generic_handle_irq(IRQ_IXP2000_DRAM0_MIN_ERR + i);
 		}
 	}
 }
diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c
index c62ed65..c84dfac 100644
--- a/arch/arm/mach-ixp2000/enp2611.c
+++ b/arch/arm/mach-ixp2000/enp2611.c
@@ -32,8 +32,8 @@
 #include <linux/tty.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
@@ -70,17 +70,17 @@
 		.virtual	= ENP2611_CALEB_VIRT_BASE,
 		.pfn		= __phys_to_pfn(ENP2611_CALEB_PHYS_BASE),
 		.length		= ENP2611_CALEB_SIZE,
-		.type		= MT_DEVICE_IXP2000,
+		.type		= MT_DEVICE,
 	}, {
 		.virtual	= ENP2611_PM3386_0_VIRT_BASE,
 		.pfn		= __phys_to_pfn(ENP2611_PM3386_0_PHYS_BASE),
 		.length		= ENP2611_PM3386_0_SIZE,
-		.type		= MT_DEVICE_IXP2000,
+		.type		= MT_DEVICE,
 	}, {
 		.virtual	= ENP2611_PM3386_1_VIRT_BASE,
 		.pfn		= __phys_to_pfn(ENP2611_PM3386_1_PHYS_BASE),
 		.length		= ENP2611_PM3386_1_SIZE,
-		.type		= MT_DEVICE_IXP2000,
+		.type		= MT_DEVICE,
 	}
 };
 
diff --git a/arch/arm/mach-ixp2000/include/mach/ixp2000-regs.h b/arch/arm/mach-ixp2000/include/mach/ixp2000-regs.h
index 19d8037..822f63f 100644
--- a/arch/arm/mach-ixp2000/include/mach/ixp2000-regs.h
+++ b/arch/arm/mach-ixp2000/include/mach/ixp2000-regs.h
@@ -41,13 +41,7 @@
  * Most of the registers are clumped in 4K regions spread throughout
  * the 0xc0000000 -> 0xc0100000 address range, but we just map in
  * the whole range using a single 1 MB section instead of small
- * 4K pages.  This has two advantages for us:
- *
- * 1) We use only one TLB entry for large number of on-chip I/O devices.
- *
- * 2) We can easily set the Section attributes to XCB=101 on the IXP2400
- *    as required per erratum #66.  We accomplish this by using a
- *    new MT_IXP2000_DEVICE memory type with the bits set as required.
+ * 4K pages.
  *
  * CAP stands for CSR Access Proxy.
  *
diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c
index c673b9e..4467c42 100644
--- a/arch/arm/mach-ixp2000/ixdp2400.c
+++ b/arch/arm/mach-ixp2000/ixdp2400.c
@@ -25,8 +25,8 @@
 #include <linux/ioport.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c
index 6715b50..94f68ba 100644
--- a/arch/arm/mach-ixp2000/ixdp2800.c
+++ b/arch/arm/mach-ixp2000/ixdp2800.c
@@ -25,8 +25,8 @@
 #include <linux/ioport.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c
index 5a781fd..b0653a8 100644
--- a/arch/arm/mach-ixp2000/ixdp2x00.c
+++ b/arch/arm/mach-ixp2000/ixdp2x00.c
@@ -25,8 +25,8 @@
 #include <linux/ioport.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
@@ -129,10 +129,8 @@
 
 	for(i = 0; i < board_irq_count; i++) {
 		if(ex_interrupt & (1 << i))  {
-			struct irq_desc *cpld_desc;
 			int cpld_irq = IXP2000_BOARD_IRQ(0) + i;
-			cpld_desc = irq_desc + cpld_irq;
-			desc_handle_irq(cpld_irq, cpld_desc);
+			generic_handle_irq(cpld_irq);
 		}
 	}
 
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c
index 78a2341..4a12327a0 100644
--- a/arch/arm/mach-ixp2000/ixdp2x01.c
+++ b/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -30,8 +30,8 @@
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/serial_8250.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
@@ -79,10 +79,8 @@
 
 	for (i = 0; i < IXP2000_BOARD_IRQS; i++) {
 		if (ex_interrupt & (1 << i)) {
-			struct irq_desc *cpld_desc;
 			int cpld_irq = IXP2000_BOARD_IRQ(0) + i;
-			cpld_desc = irq_desc + cpld_irq;
-			desc_handle_irq(cpld_irq, cpld_desc);
+			generic_handle_irq(cpld_irq);
 		}
 	}
 
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c
index 03d916f..60e9fd0 100644
--- a/arch/arm/mach-ixp2000/pci.c
+++ b/arch/arm/mach-ixp2000/pci.c
@@ -24,8 +24,8 @@
 #include <linux/ioport.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <mach/hardware.h>
diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c
index 68b4ac5..aa4c442 100644
--- a/arch/arm/mach-ixp23xx/core.c
+++ b/arch/arm/mach-ixp23xx/core.c
@@ -253,7 +253,6 @@
 {
 	u32 pci_interrupt;
 	unsigned int irqno;
-	struct irq_desc *int_desc;
 
 	pci_interrupt = *IXP23XX_PCI_XSCALE_INT_STATUS;
 
@@ -268,8 +267,7 @@
 		BUG();
 	}
 
-	int_desc = irq_desc + irqno;
-	desc_handle_irq(irqno, int_desc);
+	generic_handle_irq(irqno);
 
 	desc->chip->unmask(irq);
 }
diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c
index b6e0bfa..f1b124a 100644
--- a/arch/arm/mach-ixp23xx/ixdp2351.c
+++ b/arch/arm/mach-ixp23xx/ixdp2351.c
@@ -68,11 +68,9 @@
 
 	for (i = 0; i < IXDP2351_INTA_IRQ_NUM; i++) {
 		if (ex_interrupt & (1 << i)) {
-			struct irq_desc *cpld_desc;
 			int cpld_irq =
 				IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE + i);
-			cpld_desc = irq_desc + cpld_irq;
-			desc_handle_irq(cpld_irq, cpld_desc);
+			generic_handle_irq(cpld_irq);
 		}
 	}
 
@@ -105,11 +103,9 @@
 
 	for (i = 0; i < IXDP2351_INTB_IRQ_NUM; i++) {
 		if (ex_interrupt & (1 << i)) {
-			struct irq_desc *cpld_desc;
 			int cpld_irq =
 				IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE + i);
-			cpld_desc = irq_desc + cpld_irq;
-			desc_handle_irq(cpld_irq, cpld_desc);
+			generic_handle_irq(cpld_irq);
 		}
 	}
 
diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c
index 701d60a..59022be 100644
--- a/arch/arm/mach-ixp23xx/pci.c
+++ b/arch/arm/mach-ixp23xx/pci.c
@@ -25,8 +25,8 @@
 #include <linux/ioport.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/sizes.h>
 #include <asm/system.h>
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index 192538a..d816c51 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -25,9 +25,10 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/io.h>
 #include <asm/dma-mapping.h>
 
-#include <asm/io.h>
+#include <asm/cputype.h>
 #include <asm/irq.h>
 #include <asm/sizes.h>
 #include <asm/system.h>
@@ -366,15 +367,13 @@
 
 void __init ixp4xx_pci_preinit(void)
 {  
-	unsigned long processor_id;
-
-	asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :);
+	unsigned long cpuid = read_cpuid_id();
 
 	/*
 	 * Determine which PCI read method to use.
 	 * Rev 0 IXP425 requires workaround.
 	 */
-	if (!(processor_id & 0xf) && cpu_is_ixp42x()) {
+	if (!(cpuid & 0xf) && cpu_is_ixp42x()) {
 		printk("PCI: IXP42x A0 silicon detected - "
 			"PCI Non-Prefetch Workaround Enabled\n");
 		ixp4xx_pci_read = ixp4xx_pci_read_errata;
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 58bd284..7766f46 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -28,11 +28,11 @@
 #include <linux/timex.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
+#include <linux/io.h>
 
 #include <mach/udc.h>
 #include <mach/hardware.h>
 #include <asm/uaccess.h>
-#include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <asm/irq.h>
diff --git a/arch/arm/mach-ixp4xx/fsg-setup.c b/arch/arm/mach-ixp4xx/fsg-setup.c
index 501dfdc..e7c6386 100644
--- a/arch/arm/mach-ixp4xx/fsg-setup.c
+++ b/arch/arm/mach-ixp4xx/fsg-setup.c
@@ -23,11 +23,11 @@
 #include <linux/reboot.h>
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
+#include <linux/io.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
-#include <asm/io.h>
 #include <asm/gpio.h>
 
 static struct flash_platform_data fsg_flash_data = {
diff --git a/arch/arm/mach-ixp4xx/include/mach/cpu.h b/arch/arm/mach-ixp4xx/include/mach/cpu.h
index ff8aa23..51bd69c 100644
--- a/arch/arm/mach-ixp4xx/include/mach/cpu.h
+++ b/arch/arm/mach-ixp4xx/include/mach/cpu.h
@@ -14,18 +14,19 @@
 #ifndef __ASM_ARCH_CPU_H__
 #define __ASM_ARCH_CPU_H__
 
-extern unsigned int processor_id;
+#include <asm/cputype.h>
+
 /* Processor id value in CP15 Register 0 */
 #define IXP425_PROCESSOR_ID_VALUE	0x690541c0
 #define IXP435_PROCESSOR_ID_VALUE	0x69054040
 #define IXP465_PROCESSOR_ID_VALUE	0x69054200
 #define IXP4XX_PROCESSOR_ID_MASK	0xfffffff0
 
-#define cpu_is_ixp42x()	((processor_id & IXP4XX_PROCESSOR_ID_MASK) == \
+#define cpu_is_ixp42x()	((read_cpuid_id() & IXP4XX_PROCESSOR_ID_MASK) == \
 			  IXP425_PROCESSOR_ID_VALUE)
-#define cpu_is_ixp43x()	((processor_id & IXP4XX_PROCESSOR_ID_MASK) == \
+#define cpu_is_ixp43x()	((read_cpuid_id() & IXP4XX_PROCESSOR_ID_MASK) == \
 			  IXP435_PROCESSOR_ID_VALUE)
-#define cpu_is_ixp46x()	((processor_id & IXP4XX_PROCESSOR_ID_MASK) == \
+#define cpu_is_ixp46x()	((read_cpuid_id() & IXP4XX_PROCESSOR_ID_MASK) == \
 			  IXP465_PROCESSOR_ID_VALUE)
 
 static inline u32 ixp4xx_read_feature_bits(void)
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
index 9b2d2ec..f4a0c1b 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -20,6 +20,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/delay.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
@@ -29,7 +30,6 @@
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
-#include <asm/delay.h>
 
 static struct flash_platform_data ixdp425_flash_data = {
 	.map_name	= "cfi_probe",
diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c
index 84b5e62..0acd95e 100644
--- a/arch/arm/mach-ixp4xx/nas100d-setup.c
+++ b/arch/arm/mach-ixp4xx/nas100d-setup.c
@@ -28,11 +28,11 @@
 #include <linux/reboot.h>
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
+#include <linux/io.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
-#include <asm/io.h>
 #include <asm/gpio.h>
 
 static struct flash_platform_data nas100d_flash_data = {
diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c
index a48a665..bc9d920 100644
--- a/arch/arm/mach-ixp4xx/nslu2-setup.c
+++ b/arch/arm/mach-ixp4xx/nslu2-setup.c
@@ -25,12 +25,12 @@
 #include <linux/reboot.h>
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
+#include <linux/io.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 #include <asm/mach/time.h>
-#include <asm/io.h>
 #include <asm/gpio.h>
 
 static struct flash_platform_data nslu2_flash_data = {
diff --git a/arch/arm/mach-kirkwood/addr-map.c b/arch/arm/mach-kirkwood/addr-map.c
index c79f492..5db4f0b 100644
--- a/arch/arm/mach-kirkwood/addr-map.c
+++ b/arch/arm/mach-kirkwood/addr-map.c
@@ -48,6 +48,7 @@
 
 
 struct mbus_dram_target_info kirkwood_mbus_dram_info;
+static int __initdata win_alloc_count;
 
 static int __init cpu_win_can_remap(int win)
 {
@@ -111,6 +112,8 @@
 	setup_cpu_win(2, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE,
 		      TARGET_DEV_BUS, ATTR_DEV_NAND, -1);
 
+	win_alloc_count = 3;
+
 	/*
 	 * Setup MBUS dram target info.
 	 */
@@ -137,3 +140,8 @@
 	}
 	kirkwood_mbus_dram_info.num_cs = cs;
 }
+
+void __init kirkwood_setup_sram_win(u32 base, u32 size)
+{
+	setup_cpu_win(win_alloc_count++, base, size, 0x03, 0x00, -1);
+}
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index 189f16f..85cad05 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -98,7 +98,6 @@
  * GE00
  ****************************************************************************/
 struct mv643xx_eth_shared_platform_data kirkwood_ge00_shared_data = {
-	.t_clk		= KIRKWOOD_TCLK,
 	.dram		= &kirkwood_mbus_dram_info,
 };
 
@@ -108,6 +107,11 @@
 		.start	= GE00_PHYS_BASE + 0x2000,
 		.end	= GE00_PHYS_BASE + 0x3fff,
 		.flags	= IORESOURCE_MEM,
+	}, {
+		.name	= "ge00 err irq",
+		.start	= IRQ_KIRKWOOD_GE00_ERR,
+		.end	= IRQ_KIRKWOOD_GE00_ERR,
+		.flags	= IORESOURCE_IRQ,
 	},
 };
 
@@ -117,7 +121,7 @@
 	.dev		= {
 		.platform_data	= &kirkwood_ge00_shared_data,
 	},
-	.num_resources	= 1,
+	.num_resources	= ARRAY_SIZE(kirkwood_ge00_shared_resources),
 	.resource	= kirkwood_ge00_shared_resources,
 };
 
@@ -201,7 +205,6 @@
  * SPI
  ****************************************************************************/
 static struct orion_spi_info kirkwood_spi_plat_data = {
-	.tclk		= KIRKWOOD_TCLK,
 };
 
 static struct resource kirkwood_spi_resources[] = {
@@ -239,7 +242,7 @@
 		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
 		.iotype		= UPIO_MEM,
 		.regshift	= 2,
-		.uartclk	= KIRKWOOD_TCLK,
+		.uartclk	= 0,
 	}, {
 	},
 };
@@ -283,7 +286,7 @@
 		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
 		.iotype		= UPIO_MEM,
 		.regshift	= 2,
-		.uartclk	= KIRKWOOD_TCLK,
+		.uartclk	= 0,
 	}, {
 	},
 };
@@ -525,9 +528,23 @@
 /*****************************************************************************
  * Time handling
  ****************************************************************************/
+int kirkwood_tclk;
+
+int __init kirkwood_find_tclk(void)
+{
+	u32 dev, rev;
+
+	kirkwood_pcie_id(&dev, &rev);
+	if (dev == MV88F6281_DEV_ID && rev == MV88F6281_REV_A0)
+		return 200000000;
+
+	return 166666667;
+}
+
 static void kirkwood_timer_init(void)
 {
-	orion_time_init(IRQ_KIRKWOOD_BRIDGE, KIRKWOOD_TCLK);
+	kirkwood_tclk = kirkwood_find_tclk();
+	orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
 }
 
 struct sys_timer kirkwood_timer = {
@@ -538,33 +555,62 @@
 /*****************************************************************************
  * General
  ****************************************************************************/
+/*
+ * Identify device ID and revision.
+ */
 static char * __init kirkwood_id(void)
 {
-	switch (readl(DEVICE_ID) & 0x3) {
-	case 0:
-		return "88F6180";
-	case 1:
-		return "88F6192";
-	case 2:
-		return "88F6281";
-	}
+	u32 dev, rev;
 
-	return "unknown 88F6000 variant";
+	kirkwood_pcie_id(&dev, &rev);
+
+	if (dev == MV88F6281_DEV_ID) {
+		if (rev == MV88F6281_REV_Z0)
+			return "MV88F6281-Z0";
+		else if (rev == MV88F6281_REV_A0)
+			return "MV88F6281-A0";
+		else
+			return "MV88F6281-Rev-Unsupported";
+	} else if (dev == MV88F6192_DEV_ID) {
+		if (rev == MV88F6192_REV_Z0)
+			return "MV88F6192-Z0";
+		else if (rev == MV88F6192_REV_A0)
+			return "MV88F6192-A0";
+		else
+			return "MV88F6192-Rev-Unsupported";
+	} else if (dev == MV88F6180_DEV_ID) {
+		if (rev == MV88F6180_REV_A0)
+			return "MV88F6180-Rev-A0";
+		else
+			return "MV88F6180-Rev-Unsupported";
+	} else {
+		return "Device-Unknown";
+	}
 }
 
-static int __init is_l2_writethrough(void)
+static void __init kirkwood_l2_init(void)
 {
-	return !!(readl(L2_CONFIG_REG) & L2_WRITETHROUGH);
+#ifdef CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH
+	writel(readl(L2_CONFIG_REG) | L2_WRITETHROUGH, L2_CONFIG_REG);
+	feroceon_l2_init(1);
+#else
+	writel(readl(L2_CONFIG_REG) & ~L2_WRITETHROUGH, L2_CONFIG_REG);
+	feroceon_l2_init(0);
+#endif
 }
 
 void __init kirkwood_init(void)
 {
 	printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n",
-		kirkwood_id(), KIRKWOOD_TCLK);
+		kirkwood_id(), kirkwood_tclk);
+	kirkwood_ge00_shared_data.t_clk = kirkwood_tclk;
+	kirkwood_spi_plat_data.tclk = kirkwood_tclk;
+	kirkwood_uart0_data[0].uartclk = kirkwood_tclk;
+	kirkwood_uart1_data[0].uartclk = kirkwood_tclk;
 
 	kirkwood_setup_cpu_mbus();
 
 #ifdef CONFIG_CACHE_FEROCEON_L2
-	feroceon_l2_init(is_l2_writethrough());
+	kirkwood_l2_init();
 #endif
 }
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
index 69cd113..8fa0f6a 100644
--- a/arch/arm/mach-kirkwood/common.h
+++ b/arch/arm/mach-kirkwood/common.h
@@ -23,10 +23,9 @@
 
 extern struct mbus_dram_target_info kirkwood_mbus_dram_info;
 void kirkwood_setup_cpu_mbus(void);
-void kirkwood_setup_pcie_io_win(int window, u32 base, u32 size,
-				int maj, int min);
-void kirkwood_setup_pcie_mem_win(int window, u32 base, u32 size,
-				 int maj, int min);
+void kirkwood_setup_sram_win(u32 base, u32 size);
+
+void kirkwood_pcie_id(u32 *dev, u32 *rev);
 
 void kirkwood_ehci_init(void);
 void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data);
diff --git a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
index 610fb24..89d746d 100644
--- a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
+++ b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
@@ -44,7 +44,6 @@
 	kirkwood_rtc_init();
 	kirkwood_sata_init(&db88f6281_sata_data);
 	kirkwood_uart0_init();
-	kirkwood_uart1_init();
 }
 
 static int __init db88f6281_pci_init(void)
diff --git a/arch/arm/mach-kirkwood/include/mach/irqs.h b/arch/arm/mach-kirkwood/include/mach/irqs.h
index 6fd0583..ffab89f 100644
--- a/arch/arm/mach-kirkwood/include/mach/irqs.h
+++ b/arch/arm/mach-kirkwood/include/mach/irqs.h
@@ -50,6 +50,7 @@
 #define IRQ_KIRKWOOD_GPIO_HIGH_0_7	39
 #define IRQ_KIRKWOOD_GPIO_HIGH_8_15	40
 #define IRQ_KIRKWOOD_GPIO_HIGH_16_23	41
+#define IRQ_KIRKWOOD_GE00_ERR	46
 
 /*
  * KIRKWOOD General Purpose Pins
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
index 5c69992..eae4240 100644
--- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h
+++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
@@ -68,6 +68,20 @@
 #define   L2_WRITETHROUGH	0x00000010
 
 /*
+ * Supported devices and revisions.
+ */
+#define MV88F6281_DEV_ID	0x6281
+#define MV88F6281_REV_Z0	0
+#define MV88F6281_REV_A0	2
+
+#define MV88F6192_DEV_ID	0x6192
+#define MV88F6192_REV_Z0	0
+#define MV88F6192_REV_A0	2
+
+#define MV88F6180_DEV_ID	0x6180
+#define MV88F6180_REV_A0	2
+
+/*
  * Register Map
  */
 #define DDR_VIRT_BASE		(KIRKWOOD_REGS_VIRT_BASE | 0x00000)
diff --git a/arch/arm/mach-kirkwood/include/mach/timex.h b/arch/arm/mach-kirkwood/include/mach/timex.h
index f77ef4a..c923cd1 100644
--- a/arch/arm/mach-kirkwood/include/mach/timex.h
+++ b/arch/arm/mach-kirkwood/include/mach/timex.h
@@ -8,4 +8,3 @@
 
 #define CLOCK_TICK_RATE		(100 * HZ)
 
-#define KIRKWOOD_TCLK		166666667
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index 2195fa3..f6b08f2 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -18,6 +18,12 @@
 
 #define PCIE_BASE	((void __iomem *)PCIE_VIRT_BASE)
 
+void __init kirkwood_pcie_id(u32 *dev, u32 *rev)
+{
+	*dev = orion_pcie_dev_id(PCIE_BASE);
+	*rev = orion_pcie_rev(PCIE_BASE);
+}
+
 static int pcie_valid_config(int bus, int dev)
 {
 	/*
diff --git a/arch/arm/mach-kirkwood/rd88f6281-setup.c b/arch/arm/mach-kirkwood/rd88f6281-setup.c
index d96487a0..fb8990f 100644
--- a/arch/arm/mach-kirkwood/rd88f6281-setup.c
+++ b/arch/arm/mach-kirkwood/rd88f6281-setup.c
@@ -90,7 +90,6 @@
 	kirkwood_rtc_init();
 	kirkwood_sata_init(&rd88f6281_sata_data);
 	kirkwood_uart0_init();
-	kirkwood_uart1_init();
 
 	platform_device_register(&rd88f6281_nand_flash);
 }
diff --git a/arch/arm/mach-ks8695/cpu.c b/arch/arm/mach-ks8695/cpu.c
index c6c08e8..7f3f240 100644
--- a/arch/arm/mach-ks8695/cpu.c
+++ b/arch/arm/mach-ks8695/cpu.c
@@ -24,9 +24,9 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
diff --git a/arch/arm/mach-ks8695/gpio.c b/arch/arm/mach-ks8695/gpio.c
index 3624e65..9aecf0c 100644
--- a/arch/arm/mach-ks8695/gpio.c
+++ b/arch/arm/mach-ks8695/gpio.c
@@ -23,8 +23,8 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/module.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <mach/hardware.h>
 #include <asm/mach/irq.h>
 
@@ -72,7 +72,7 @@
 
 	/* set pin as input */
 	x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
-	x &= ~IOPM_(pin);
+	x &= ~IOPM(pin);
 	__raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
 
 	local_irq_restore(flags);
@@ -108,7 +108,7 @@
 
 	/* set pin as input */
 	x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
-	x &= ~IOPM_(pin);
+	x &= ~IOPM(pin);
 	__raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
 
 	local_irq_restore(flags);
@@ -136,14 +136,14 @@
 	/* set line state */
 	x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
 	if (state)
-		x |= (1 << pin);
+		x |= IOPD(pin);
 	else
-		x &= ~(1 << pin);
+		x &= ~IOPD(pin);
 	__raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD);
 
 	/* set pin as output */
 	x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
-	x |= IOPM_(pin);
+	x |= IOPM(pin);
 	__raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
 
 	local_irq_restore(flags);
@@ -168,9 +168,9 @@
 	/* set output line state */
 	x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
 	if (state)
-		x |= (1 << pin);
+		x |= IOPD(pin);
 	else
-		x &= ~(1 << pin);
+		x &= ~IOPD(pin);
 	__raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD);
 
 	local_irq_restore(flags);
@@ -189,7 +189,7 @@
 		return -EINVAL;
 
 	x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
-	return (x & (1 << pin)) != 0;
+	return (x & IOPD(pin)) != 0;
 }
 EXPORT_SYMBOL(gpio_get_value);
 
@@ -240,7 +240,7 @@
 	for (i = KS8695_GPIO_0; i <= KS8695_GPIO_15 ; i++) {
 		seq_printf(s, "%i:\t", i);
 
-		seq_printf(s, "%s\t", (mode & IOPM_(i)) ? "Output" : "Input");
+		seq_printf(s, "%s\t", (mode & IOPM(i)) ? "Output" : "Input");
 
 		if (i <= KS8695_GPIO_3) {
 			if (ctrl & enable[i]) {
@@ -273,7 +273,7 @@
 
 		seq_printf(s, "\t");
 
-		seq_printf(s, "%i\n", (data & IOPD_(i)) ? 1 : 0);
+		seq_printf(s, "%i\n", (data & IOPD(i)) ? 1 : 0);
 	}
 	return 0;
 }
diff --git a/arch/arm/mach-ks8695/include/mach/memory.h b/arch/arm/mach-ks8695/include/mach/memory.h
index dadbe66..8fbc4c7 100644
--- a/arch/arm/mach-ks8695/include/mach/memory.h
+++ b/arch/arm/mach-ks8695/include/mach/memory.h
@@ -31,8 +31,8 @@
 /* Platform-bus mapping */
 extern struct bus_type platform_bus_type;
 #define is_lbus_device(dev)		(dev && dev->bus == &platform_bus_type)
-#define __arch_dma_to_virt(dev, x)	({ is_lbus_device(dev) ? \
-					__phys_to_virt(x) : __bus_to_virt(x); })
+#define __arch_dma_to_virt(dev, x)	({ (void *) (is_lbus_device(dev) ? \
+					__phys_to_virt(x) : __bus_to_virt(x)); })
 #define __arch_virt_to_dma(dev, x)	({ is_lbus_device(dev) ? \
 					(dma_addr_t)__virt_to_phys(x) : (dma_addr_t)__virt_to_bus(x); })
 #define __arch_page_to_dma(dev, x)	__arch_virt_to_dma(dev, page_address(x))
diff --git a/arch/arm/mach-ks8695/include/mach/regs-gpio.h b/arch/arm/mach-ks8695/include/mach/regs-gpio.h
index 0df6fe6..90614a7 100644
--- a/arch/arm/mach-ks8695/include/mach/regs-gpio.h
+++ b/arch/arm/mach-ks8695/include/mach/regs-gpio.h
@@ -24,7 +24,7 @@
 
 
 /* Port Mode Register */
-#define IOPM_(x)		(1 << (x))	/* Mode for GPIO Pin x */
+#define IOPM(x)			(1 << (x))	/* Mode for GPIO Pin x */
 
 /* Port Control Register */
 #define IOPC_IOTIM1EN		(1 << 17)	/* GPIO Pin for Timer1 Enable */
@@ -50,6 +50,6 @@
 #define IOPC_TM_EDGE		(6)		/* Both Edge Detection */
 
 /* Port Data Register */
-#define IOPD_(x)		(1 << (x))	/* Signal Level of GPIO Pin x */
+#define IOPD(x)			(1 << (x))	/* Signal Level of GPIO Pin x */
 
 #endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-lan.h b/arch/arm/mach-ks8695/include/mach/regs-lan.h
index 9ef4099..82c5f37 100644
--- a/arch/arm/mach-ks8695/include/mach/regs-lan.h
+++ b/arch/arm/mach-ks8695/include/mach/regs-lan.h
@@ -29,8 +29,8 @@
 #define KS8695_LRDLB		(0x14)		/* Receive Descriptor List Base Address */
 #define KS8695_LMAL		(0x18)		/* MAC Station Address Low */
 #define KS8695_LMAH		(0x1c)		/* MAC Station Address High */
-#define KS8695_LMAAL_(n)	(0x80 + ((n)*8))	/* MAC Additional Station Address (0..15) Low */
-#define KS8695_LMAAH_(n)	(0x84 + ((n)*8))	/* MAC Additional Station Address (0..15) High */
+#define KS8695_LMAAL(n)		(0x80 + ((n)*8))	/* MAC Additional Station Address (0..15) Low */
+#define KS8695_LMAAH(n)		(0x84 + ((n)*8))	/* MAC Additional Station Address (0..15) High */
 
 
 /* DMA Transmit Control Register */
diff --git a/arch/arm/mach-ks8695/include/mach/regs-wan.h b/arch/arm/mach-ks8695/include/mach/regs-wan.h
index eb494ec..c475bed 100644
--- a/arch/arm/mach-ks8695/include/mach/regs-wan.h
+++ b/arch/arm/mach-ks8695/include/mach/regs-wan.h
@@ -29,8 +29,8 @@
 #define KS8695_WRDLB		(0x14)		/* Receive Descriptor List Base Address */
 #define KS8695_WMAL		(0x18)		/* MAC Station Address Low */
 #define KS8695_WMAH		(0x1c)		/* MAC Station Address High */
-#define KS8695_WMAAL_(n)	(0x80 + ((n)*8))	/* MAC Additional Station Address (0..15) Low */
-#define KS8695_WMAAH_(n)	(0x84 + ((n)*8))	/* MAC Additional Station Address (0..15) High */
+#define KS8695_WMAAL(n)		(0x80 + ((n)*8))	/* MAC Additional Station Address (0..15) Low */
+#define KS8695_WMAAH(n)		(0x84 + ((n)*8))	/* MAC Additional Station Address (0..15) High */
 
 
 /* DMA Transmit Control Register */
diff --git a/arch/arm/mach-ks8695/include/mach/system.h b/arch/arm/mach-ks8695/include/mach/system.h
index 2a6f918..5a9b032 100644
--- a/arch/arm/mach-ks8695/include/mach/system.h
+++ b/arch/arm/mach-ks8695/include/mach/system.h
@@ -14,7 +14,7 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <mach/regs-timer.h>
 
 static void arch_idle(void)
diff --git a/arch/arm/mach-ks8695/include/mach/uncompress.h b/arch/arm/mach-ks8695/include/mach/uncompress.h
index 0eee37a..9495cb4 100644
--- a/arch/arm/mach-ks8695/include/mach/uncompress.h
+++ b/arch/arm/mach-ks8695/include/mach/uncompress.h
@@ -14,7 +14,7 @@
 #ifndef __ASM_ARCH_UNCOMPRESS_H
 #define __ASM_ARCH_UNCOMPRESS_H
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <mach/regs-uart.h>
 
 static void putc(char c)
diff --git a/arch/arm/mach-ks8695/irq.c b/arch/arm/mach-ks8695/irq.c
index e5e71f4..e375c1d 100644
--- a/arch/arm/mach-ks8695/irq.c
+++ b/arch/arm/mach-ks8695/irq.c
@@ -24,10 +24,10 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/sysdev.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 
 #include <asm/mach/irq.h>
 
diff --git a/arch/arm/mach-ks8695/pci.c b/arch/arm/mach-ks8695/pci.c
index 1746c67..f5ebcc0 100644
--- a/arch/arm/mach-ks8695/pci.c
+++ b/arch/arm/mach-ks8695/pci.c
@@ -27,8 +27,8 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/signal.h>
 #include <asm/mach/pci.h>
 #include <mach/hardware.h>
@@ -141,7 +141,7 @@
 	.write	= ks8695_pci_writeconfig,
 };
 
-static struct pci_bus *ks8695_pci_scan_bus(int nr, struct pci_sys_data *sys)
+static struct pci_bus* __init ks8695_pci_scan_bus(int nr, struct pci_sys_data *sys)
 {
 	return pci_scan_bus(sys->busnr, &ks8695_pci_ops, sys);
 }
diff --git a/arch/arm/mach-ks8695/time.c b/arch/arm/mach-ks8695/time.c
index 940888d..69c072c 100644
--- a/arch/arm/mach-ks8695/time.c
+++ b/arch/arm/mach-ks8695/time.c
@@ -24,8 +24,8 @@
 #include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/mach/time.h>
 
 #include <mach/regs-timer.h>
diff --git a/arch/arm/mach-lh7a40x/Kconfig b/arch/arm/mach-lh7a40x/Kconfig
index 6f4c6a1..9be7466 100644
--- a/arch/arm/mach-lh7a40x/Kconfig
+++ b/arch/arm/mach-lh7a40x/Kconfig
@@ -40,23 +40,22 @@
 	bool
 
 config LH7A40X_CONTIGMEM
-	bool "Disable NUMA Support"
-	depends on ARCH_LH7A40X
+	bool "Disable NUMA/SparseMEM Support"
 	help
 	  Say Y here if your bootloader sets the SROMLL bit(s) in
 	  the SDRAM controller, organizing memory as a contiguous
-	  array.  This option will disable CONFIG_DISCONTIGMEM and
-          force the kernel to manage all memory in one node.
+	  array.  This option will disable sparse memory support
+          and force the kernel to manage all memory in one node.
 
-	  Setting this option incorrectly may prevent the kernel from
-	  booting.  It is OK to leave it N.
+	  Setting this option incorrectly may prevent the kernel
+	  from booting.  It is OK to leave it N.
 
 	  For more information, consult
 	    <file:Documentation/arm/Sharp-LH/SDRAM>.
 
 config LH7A40X_ONE_BANK_PER_NODE
 	bool "Optimize NUMA Node Tables for Size"
-	depends on ARCH_LH7A40X && !LH7A40X_CONTIGMEM
+	depends on !LH7A40X_CONTIGMEM
 	help
 	  Say Y here to produce compact memory node tables.  By
 	  default pairs of adjacent physical RAM banks are managed
diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c
index 551b972..3d7bd50 100644
--- a/arch/arm/mach-lh7a40x/arch-kev7a400.c
+++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c
@@ -77,7 +77,7 @@
 	irq = IRQ_KEV7A400_CPLD;
 	for (; mask; mask >>= 1, ++irq)
 		if (mask & 1)
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 }
 
 void __init lh7a40x_init_board_irq (void)
diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
index e373fb8..cb15e5d 100644
--- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
@@ -214,11 +214,11 @@
 	desc->chip->ack (irq);
 
 	if ((mask & (1<<0)) == 0)	/* WLAN */
-		IRQ_DISPATCH (IRQ_LPD7A40X_ETH_INT);
+		generic_handle_irq(IRQ_LPD7A40X_ETH_INT);
 
 #if defined (IRQ_TOUCH)
 	if ((mask & (1<<1)) == 0)	/* Touch */
-		IRQ_DISPATCH (IRQ_TOUCH);
+		generic_handle_irq(IRQ_TOUCH);
 #endif
 
 	desc->chip->unmask (irq); /* Level-triggered need this */
diff --git a/arch/arm/mach-lh7a40x/common.h b/arch/arm/mach-lh7a40x/common.h
index 0ca20c6..6ed3f6b 100644
--- a/arch/arm/mach-lh7a40x/common.h
+++ b/arch/arm/mach-lh7a40x/common.h
@@ -15,4 +15,3 @@
 extern void lh7a40x_clcd_init (void);
 extern void lh7a40x_init_board_irq (void);
 
-#define IRQ_DISPATCH(irq) desc_handle_irq((irq),(irq_desc + irq))
diff --git a/arch/arm/mach-lh7a40x/include/mach/memory.h b/arch/arm/mach-lh7a40x/include/mach/memory.h
index f7107b4..1da14ff 100644
--- a/arch/arm/mach-lh7a40x/include/mach/memory.h
+++ b/arch/arm/mach-lh7a40x/include/mach/memory.h
@@ -73,4 +73,10 @@
 
 #endif
 
+/*
+ * Sparsemem version of the above
+ */
+#define MAX_PHYSMEM_BITS	32
+#define SECTION_SIZE_BITS	24
+
 #endif
diff --git a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
index 0d5063eb..fd033bb 100644
--- a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
@@ -63,10 +63,10 @@
 	desc->chip->ack (irq);
 
 	if ((mask & 0x1) == 0)	/* WLAN */
-		IRQ_DISPATCH (IRQ_LPD7A40X_ETH_INT);
+		generic_handle_irq(IRQ_LPD7A40X_ETH_INT);
 
 	if ((mask & 0x2) == 0)	/* Touch */
-		IRQ_DISPATCH (IRQ_LPD7A400_TS);
+		generic_handle_irq(IRQ_LPD7A400_TS);
 
 	desc->chip->unmask (irq); /* Level-triggered need this */
 }
diff --git a/arch/arm/mach-lh7a40x/ssp-cpld.c b/arch/arm/mach-lh7a40x/ssp-cpld.c
index 51fbef9..2901d49 100644
--- a/arch/arm/mach-lh7a40x/ssp-cpld.c
+++ b/arch/arm/mach-lh7a40x/ssp-cpld.c
@@ -43,8 +43,8 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <mach/hardware.h>
 
diff --git a/arch/arm/mach-lh7a40x/time.c b/arch/arm/mach-lh7a40x/time.c
index 7fe9e06..4601e425 100644
--- a/arch/arm/mach-lh7a40x/time.c
+++ b/arch/arm/mach-lh7a40x/time.c
@@ -13,9 +13,9 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/time.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/leds.h>
 
diff --git a/arch/arm/mach-loki/addr-map.c b/arch/arm/mach-loki/addr-map.c
index 70ca56b..0332d8f 100644
--- a/arch/arm/mach-loki/addr-map.c
+++ b/arch/arm/mach-loki/addr-map.c
@@ -11,8 +11,8 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/mbus.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include "common.h"
 
 /*
diff --git a/arch/arm/mach-loki/irq.c b/arch/arm/mach-loki/irq.c
index 5a48793..e1f9733 100644
--- a/arch/arm/mach-loki/irq.c
+++ b/arch/arm/mach-loki/irq.c
@@ -11,7 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/irq.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <plat/irq.h>
 #include "common.h"
 
diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c
index 995afc4a..a242591 100644
--- a/arch/arm/mach-msm/board-halibut.c
+++ b/arch/arm/mach-msm/board-halibut.c
@@ -18,6 +18,8 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
+#include <linux/io.h>
+#include <linux/delay.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -28,9 +30,6 @@
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
 
-#include <asm/io.h>
-#include <asm/delay.h>
-
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 
diff --git a/arch/arm/mach-msm/common.c b/arch/arm/mach-msm/common.c
index 3a51136..604f8ad 100644
--- a/arch/arm/mach-msm/common.c
+++ b/arch/arm/mach-msm/common.c
@@ -19,9 +19,9 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <asm/mach/flash.h>
-#include <asm/io.h>
 
 #include <asm/setup.h>
 
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index 9de0826..0c8f252 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -13,7 +13,7 @@
  *
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/interrupt.h>
 #include <mach/dma.h>
 
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 5976200..7999e4b 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -18,9 +18,9 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/page.h>
 #include <mach/msm_iomap.h>
 #include <asm/mach/map.h>
diff --git a/arch/arm/mach-msm/irq.c b/arch/arm/mach-msm/irq.c
index 66901ba..04b8d18 100644
--- a/arch/arm/mach-msm/irq.c
+++ b/arch/arm/mach-msm/irq.c
@@ -19,11 +19,10 @@
 #include <linux/interrupt.h>
 #include <linux/ptrace.h>
 #include <linux/timer.h>
-
 #include <linux/irq.h>
-#include <mach/hardware.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
+#include <mach/hardware.h>
 
 #include <mach/msm_iomap.h>
 
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 9f02d7d..2bffe9b 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -20,12 +20,11 @@
 #include <linux/clk.h>
 #include <linux/clockchips.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 
 #include <asm/mach/time.h>
 #include <mach/msm_iomap.h>
 
-#include <asm/io.h>
-
 #define MSM_DGT_BASE (MSM_GPT_BASE + 0x10)
 #define MSM_DGT_SHIFT (5)
 
diff --git a/arch/arm/mach-mv78xx0/addr-map.c b/arch/arm/mach-mv78xx0/addr-map.c
index 4004b67..311d5b0 100644
--- a/arch/arm/mach-mv78xx0/addr-map.c
+++ b/arch/arm/mach-mv78xx0/addr-map.c
@@ -11,7 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/mbus.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include "common.h"
 
 /*
diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c
index 953a26c..d56a05e 100644
--- a/arch/arm/mach-mv78xx0/common.c
+++ b/arch/arm/mach-mv78xx0/common.c
@@ -285,6 +285,11 @@
 		.start	= GE00_PHYS_BASE + 0x2000,
 		.end	= GE00_PHYS_BASE + 0x3fff,
 		.flags	= IORESOURCE_MEM,
+	}, {
+		.name	= "ge err irq",
+		.start	= IRQ_MV78XX0_GE_ERR,
+		.end	= IRQ_MV78XX0_GE_ERR,
+		.flags	= IORESOURCE_IRQ,
 	},
 };
 
@@ -294,7 +299,7 @@
 	.dev		= {
 		.platform_data	= &mv78xx0_ge00_shared_data,
 	},
-	.num_resources	= 1,
+	.num_resources	= ARRAY_SIZE(mv78xx0_ge00_shared_resources),
 	.resource	= mv78xx0_ge00_shared_resources,
 };
 
diff --git a/arch/arm/mach-mv78xx0/include/mach/entry-macro.S b/arch/arm/mach-mv78xx0/include/mach/entry-macro.S
index ed4a46b..fbfb269 100644
--- a/arch/arm/mach-mv78xx0/include/mach/entry-macro.S
+++ b/arch/arm/mach-mv78xx0/include/mach/entry-macro.S
@@ -26,14 +26,22 @@
 	ldr	\tmp, [\base, #IRQ_MASK_LOW_OFF]
 	mov	\irqnr, #31
 	ands	\irqstat, \irqstat, \tmp
+	bne	1001f
 
 	@ if no low interrupts set, check high interrupts
-	ldreq	\irqstat, [\base, #IRQ_CAUSE_HIGH_OFF]
-	ldreq	\tmp, [\base, #IRQ_MASK_HIGH_OFF]
-	moveq	\irqnr, #63
-	andeqs	\irqstat, \irqstat, \tmp
+	ldr	\irqstat, [\base, #IRQ_CAUSE_HIGH_OFF]
+	ldr	\tmp, [\base, #IRQ_MASK_HIGH_OFF]
+	mov	\irqnr, #63
+	ands	\irqstat, \irqstat, \tmp
+	bne	1001f
+
+	@ if no high interrupts set, check error interrupts
+	ldr	\irqstat, [\base, #IRQ_CAUSE_ERR_OFF]
+	ldr	\tmp, [\base, #IRQ_MASK_ERR_OFF]
+	mov	\irqnr, #95
+	ands	\irqstat, \irqstat, \tmp
 
 	@ find first active interrupt source
-	clzne	\irqstat, \irqstat
+1001:	clzne	\irqstat, \irqstat
 	subne	\irqnr, \irqnr, \irqstat
 	.endm
diff --git a/arch/arm/mach-mv78xx0/include/mach/irqs.h b/arch/arm/mach-mv78xx0/include/mach/irqs.h
index 995d7fb..bebc330 100644
--- a/arch/arm/mach-mv78xx0/include/mach/irqs.h
+++ b/arch/arm/mach-mv78xx0/include/mach/irqs.h
@@ -80,9 +80,14 @@
 #define IRQ_MV78XX0_DB_OUT	61
 
 /*
+ * MV78xx0 Error Interrupt Controller
+ */
+#define IRQ_MV78XX0_GE_ERR	70
+
+/*
  * MV78XX0 General Purpose Pins
  */
-#define IRQ_MV78XX0_GPIO_START	64
+#define IRQ_MV78XX0_GPIO_START	96
 #define NR_GPIO_IRQS		GPIO_MAX
 
 #define NR_IRQS			(IRQ_MV78XX0_GPIO_START + NR_GPIO_IRQS)
diff --git a/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
index ad66417..ee9c559 100644
--- a/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
+++ b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
@@ -71,8 +71,10 @@
 #define   BRIDGE_INT_TIMER1	0x0004
 #define   BRIDGE_INT_TIMER1_CLR	(~0x0004)
 #define  IRQ_VIRT_BASE		(BRIDGE_VIRT_BASE | 0x0200)
+#define   IRQ_CAUSE_ERR_OFF	0x0000
 #define   IRQ_CAUSE_LOW_OFF	0x0004
 #define   IRQ_CAUSE_HIGH_OFF	0x0008
+#define   IRQ_MASK_ERR_OFF	0x000c
 #define   IRQ_MASK_LOW_OFF	0x0010
 #define   IRQ_MASK_HIGH_OFF	0x0014
 #define  TIMER_VIRT_BASE	(BRIDGE_VIRT_BASE | 0x0300)
diff --git a/arch/arm/mach-mv78xx0/irq.c b/arch/arm/mach-mv78xx0/irq.c
index 28248d3..503e5d1 100644
--- a/arch/arm/mach-mv78xx0/irq.c
+++ b/arch/arm/mach-mv78xx0/irq.c
@@ -19,4 +19,5 @@
 {
 	orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF));
 	orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF));
+	orion_irq_init(64, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_ERR_OFF));
 }
diff --git a/arch/arm/mach-mx2/devices.h b/arch/arm/mach-mx2/devices.h
new file mode 100644
index 0000000..c77a4b8
--- /dev/null
+++ b/arch/arm/mach-mx2/devices.h
@@ -0,0 +1,15 @@
+
+extern struct platform_device mxc_gpt1;
+extern struct platform_device mxc_gpt2;
+extern struct platform_device mxc_gpt3;
+extern struct platform_device mxc_gpt4;
+extern struct platform_device mxc_gpt5;
+extern struct platform_device mxc_wdt;
+extern struct platform_device mxc_irda_device;
+extern struct platform_device mxc_uart_device0;
+extern struct platform_device mxc_uart_device1;
+extern struct platform_device mxc_uart_device2;
+extern struct platform_device mxc_uart_device3;
+extern struct platform_device mxc_uart_device4;
+extern struct platform_device mxc_uart_device5;
+
diff --git a/arch/arm/mach-mx2/mx27ads.c b/arch/arm/mach-mx2/mx27ads.c
index 4ce56ef..56e22d3 100644
--- a/arch/arm/mach-mx2/mx27ads.c
+++ b/arch/arm/mach-mx2/mx27ads.c
@@ -34,6 +34,8 @@
 #include <mach/iomux-mx1-mx2.h>
 #include <mach/board-mx27ads.h>
 
+#include "devices.h"
+
 /* ADS's NOR flash */
 static struct physmap_flash_data mx27ads_flash_data = {
 	.width = 2,
@@ -251,12 +253,14 @@
 
 static void __init mx27ads_board_init(void)
 {
-	int i;
-
 	gpio_fec_active();
 
-	for (i = 0; i < 6; i++)
-		imx_init_uart(i, &uart_pdata[i]);
+	mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
+	mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
+	mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
+	mxc_register_device(&mxc_uart_device3, &uart_pdata[3]);
+	mxc_register_device(&mxc_uart_device4, &uart_pdata[4]);
+	mxc_register_device(&mxc_uart_device5, &uart_pdata[5]);
 
 	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
 }
diff --git a/arch/arm/mach-mx2/pcm038.c b/arch/arm/mach-mx2/pcm038.c
index 1028f45..7f55746 100644
--- a/arch/arm/mach-mx2/pcm038.c
+++ b/arch/arm/mach-mx2/pcm038.c
@@ -28,6 +28,8 @@
 #include <mach/imx-uart.h>
 #include <mach/board-pcm038.h>
 
+#include "devices.h"
+
 /*
  * Phytec's phyCORE-i.MX27 comes with 32MiB flash,
  * 16 bit width
@@ -170,11 +172,11 @@
 
 static void __init pcm038_init(void)
 {
-	int i;
 	gpio_fec_active();
 
-	for (i = 0; i < 3; i++)
-		imx_init_uart(i, &uart_pdata[i]);
+	mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
+	mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
+	mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
 
 	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
 
diff --git a/arch/arm/mach-mx2/serial.c b/arch/arm/mach-mx2/serial.c
index e31fd44..16debc2 100644
--- a/arch/arm/mach-mx2/serial.c
+++ b/arch/arm/mach-mx2/serial.c
@@ -35,7 +35,7 @@
 	},
 };
 
-static struct platform_device mxc_uart_device0 = {
+struct platform_device mxc_uart_device0 = {
 	.name = "imx-uart",
 	.id = 0,
 	.resource = uart0,
@@ -54,7 +54,7 @@
 	},
 };
 
-static struct platform_device mxc_uart_device1 = {
+struct platform_device mxc_uart_device1 = {
 	.name = "imx-uart",
 	.id = 1,
 	.resource = uart1,
@@ -73,7 +73,7 @@
 	},
 };
 
-static struct platform_device mxc_uart_device2 = {
+struct platform_device mxc_uart_device2 = {
 	.name = "imx-uart",
 	.id = 2,
 	.resource = uart2,
@@ -92,7 +92,7 @@
 	},
 };
 
-static struct platform_device mxc_uart_device3 = {
+struct platform_device mxc_uart_device3 = {
 	.name = "imx-uart",
 	.id = 3,
 	.resource = uart3,
@@ -111,7 +111,7 @@
 	},
 };
 
-static struct platform_device mxc_uart_device4 = {
+struct platform_device mxc_uart_device4 = {
 	.name = "imx-uart",
 	.id = 4,
 	.resource = uart4,
@@ -130,48 +130,9 @@
 	},
 };
 
-static struct platform_device mxc_uart_device5 = {
+struct platform_device mxc_uart_device5 = {
 	.name = "imx-uart",
 	.id = 5,
 	.resource = uart5,
 	.num_resources = ARRAY_SIZE(uart5),
 };
-
-/*
- * Register only those UARTs that physically exists
- */
-int __init imx_init_uart(int uart_no, struct imxuart_platform_data *pdata)
-{
-	switch (uart_no) {
-	case 0:
-		mxc_uart_device0.dev.platform_data = pdata;
-		platform_device_register(&mxc_uart_device0);
-		break;
-	case 1:
-		mxc_uart_device1.dev.platform_data = pdata;
-		platform_device_register(&mxc_uart_device1);
-		break;
-#ifndef CONFIG_MXC_IRDA
-	case 2:
-		mxc_uart_device2.dev.platform_data = pdata;
-		platform_device_register(&mxc_uart_device2);
-		break;
-#endif
-	case 3:
-		mxc_uart_device3.dev.platform_data = pdata;
-		platform_device_register(&mxc_uart_device3);
-		break;
-	case 4:
-		mxc_uart_device4.dev.platform_data = pdata;
-		platform_device_register(&mxc_uart_device4);
-		break;
-	case 5:
-		mxc_uart_device5.dev.platform_data = pdata;
-		platform_device_register(&mxc_uart_device5);
-		break;
-	default:
-		return -ENODEV;
-	}
-
-	return 0;
-}
diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c
index e08c6a8..a6bdcc0 100644
--- a/arch/arm/mach-mx3/devices.c
+++ b/arch/arm/mach-mx3/devices.c
@@ -36,7 +36,7 @@
 	},
 };
 
-static struct platform_device mxc_uart_device0 = {
+struct platform_device mxc_uart_device0 = {
 	.name = "imx-uart",
 	.id = 0,
 	.resource = uart0,
@@ -55,7 +55,7 @@
 	},
 };
 
-static struct platform_device mxc_uart_device1 = {
+struct platform_device mxc_uart_device1 = {
 	.name = "imx-uart",
 	.id = 1,
 	.resource = uart1,
@@ -74,7 +74,7 @@
 	},
 };
 
-static struct platform_device mxc_uart_device2 = {
+struct platform_device mxc_uart_device2 = {
 	.name = "imx-uart",
 	.id = 2,
 	.resource = uart2,
@@ -93,7 +93,7 @@
 	},
 };
 
-static struct platform_device mxc_uart_device3 = {
+struct platform_device mxc_uart_device3 = {
 	.name = "imx-uart",
 	.id = 3,
 	.resource = uart3,
@@ -112,46 +112,13 @@
 	},
 };
 
-static struct platform_device mxc_uart_device4 = {
+struct platform_device mxc_uart_device4 = {
 	.name = "imx-uart",
 	.id = 4,
 	.resource = uart4,
 	.num_resources = ARRAY_SIZE(uart4),
 };
 
-/*
- * Register only those UARTs that physically exist
- */
-int __init imx_init_uart(int uart_no, struct imxuart_platform_data *pdata)
-{
-	switch (uart_no) {
-	case 0:
-		mxc_uart_device0.dev.platform_data = pdata;
-		platform_device_register(&mxc_uart_device0);
-		break;
-	case 1:
-		mxc_uart_device1.dev.platform_data = pdata;
-		platform_device_register(&mxc_uart_device1);
-		break;
-	case 2:
-		mxc_uart_device2.dev.platform_data = pdata;
-		platform_device_register(&mxc_uart_device2);
-		break;
-	case 3:
-		mxc_uart_device3.dev.platform_data = pdata;
-		platform_device_register(&mxc_uart_device3);
-		break;
-	case 4:
-		mxc_uart_device4.dev.platform_data = pdata;
-		platform_device_register(&mxc_uart_device4);
-		break;
-	default:
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
 /* GPIO port description */
 static struct mxc_gpio_port imx_gpio_ports[] = {
 	[0] = {
diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h
new file mode 100644
index 0000000..4dc03f9
--- /dev/null
+++ b/arch/arm/mach-mx3/devices.h
@@ -0,0 +1,6 @@
+
+extern struct platform_device mxc_uart_device0;
+extern struct platform_device mxc_uart_device1;
+extern struct platform_device mxc_uart_device2;
+extern struct platform_device mxc_uart_device3;
+extern struct platform_device mxc_uart_device4;
diff --git a/arch/arm/mach-mx3/iomux.c b/arch/arm/mach-mx3/iomux.c
index 3dda1fe..6e664be 100644
--- a/arch/arm/mach-mx3/iomux.c
+++ b/arch/arm/mach-mx3/iomux.c
@@ -43,7 +43,8 @@
  */
 int mxc_iomux_mode(unsigned int pin_mode)
 {
-	u32 reg, field, l, mode, ret = 0;
+	u32 field, l, mode, ret = 0;
+	void __iomem *reg;
 
 	reg = IOMUXSW_MUX_CTL + (pin_mode & IOMUX_REG_MASK);
 	field = pin_mode & 0x3;
@@ -70,7 +71,8 @@
  */
 void mxc_iomux_set_pad(enum iomux_pins pin, u32 config)
 {
-	u32 reg, field, l;
+	u32 field, l;
+	void __iomem *reg;
 
 	reg = IOMUXSW_PAD_CTL + (pin + 2) / 3;
 	field = (pin + 2) % 3;
diff --git a/arch/arm/mach-mx3/mm.c b/arch/arm/mach-mx3/mm.c
index 30d842b..0589b5c 100644
--- a/arch/arm/mach-mx3/mm.c
+++ b/arch/arm/mach-mx3/mm.c
@@ -49,7 +49,7 @@
 		.virtual	= AVIC_BASE_ADDR_VIRT,
 		.pfn		= __phys_to_pfn(AVIC_BASE_ADDR),
 		.length		= AVIC_SIZE,
-		.type		= MT_NONSHARED_DEVICE
+		.type		= MT_DEVICE_NONSHARED
 	},
 };
 
diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c
index 60fb4e0..1be4a39 100644
--- a/arch/arm/mach-mx3/mx31ads.c
+++ b/arch/arm/mach-mx3/mx31ads.c
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/serial_8250.h>
+#include <linux/irq.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -31,6 +32,8 @@
 #include <asm/mach/map.h>
 #include <mach/common.h>
 #include <mach/board-mx31ads.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
 
 /*!
  * @file mx31ads.c
@@ -84,6 +87,108 @@
 }
 #endif
 
+#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static inline void mxc_init_imx_uart(void)
+{
+	mxc_iomux_mode(MX31_PIN_CTS1__CTS1);
+	mxc_iomux_mode(MX31_PIN_RTS1__RTS1);
+	mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
+	mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
+
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+}
+#else /* !SERIAL_IMX */
+static inline void mxc_init_imx_uart(void)
+{
+}
+#endif /* !SERIAL_IMX */
+
+static void mx31ads_expio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+	u32 imr_val;
+	u32 int_valid;
+	u32 expio_irq;
+
+	imr_val = __raw_readw(PBC_INTMASK_SET_REG);
+	int_valid = __raw_readw(PBC_INTSTATUS_REG) & imr_val;
+
+	expio_irq = MXC_EXP_IO_BASE;
+	for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
+		if ((int_valid & 1) == 0)
+			continue;
+
+		generic_handle_irq(expio_irq);
+	}
+}
+
+/*
+ * Disable an expio pin's interrupt by setting the bit in the imr.
+ * @param irq           an expio virtual irq number
+ */
+static void expio_mask_irq(u32 irq)
+{
+	u32 expio = MXC_IRQ_TO_EXPIO(irq);
+	/* mask the interrupt */
+	__raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG);
+	__raw_readw(PBC_INTMASK_CLEAR_REG);
+}
+
+/*
+ * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr.
+ * @param irq           an expanded io virtual irq number
+ */
+static void expio_ack_irq(u32 irq)
+{
+	u32 expio = MXC_IRQ_TO_EXPIO(irq);
+	/* clear the interrupt status */
+	__raw_writew(1 << expio, PBC_INTSTATUS_REG);
+}
+
+/*
+ * Enable a expio pin's interrupt by clearing the bit in the imr.
+ * @param irq           a expio virtual irq number
+ */
+static void expio_unmask_irq(u32 irq)
+{
+	u32 expio = MXC_IRQ_TO_EXPIO(irq);
+	/* unmask the interrupt */
+	__raw_writew(1 << expio, PBC_INTMASK_SET_REG);
+}
+
+static struct irq_chip expio_irq_chip = {
+	.ack = expio_ack_irq,
+	.mask = expio_mask_irq,
+	.unmask = expio_unmask_irq,
+};
+
+static void __init mx31ads_init_expio(void)
+{
+	int i;
+
+	printk(KERN_INFO "MX31ADS EXPIO(CPLD) hardware\n");
+
+	/*
+	 * Configure INT line as GPIO input
+	 */
+	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO));
+
+	/* disable the interrupt and clear the status */
+	__raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG);
+	__raw_writew(0xFFFF, PBC_INTSTATUS_REG);
+	for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES);
+	     i++) {
+		set_irq_chip(i, &expio_irq_chip);
+		set_irq_handler(i, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+	set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_HIGH);
+	set_irq_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler);
+}
+
 /*!
  * This structure defines static mappings for the i.MX31ADS board.
  */
@@ -92,17 +197,17 @@
 		.virtual	= AIPS1_BASE_ADDR_VIRT,
 		.pfn		= __phys_to_pfn(AIPS1_BASE_ADDR),
 		.length		= AIPS1_SIZE,
-		.type		= MT_NONSHARED_DEVICE
+		.type		= MT_DEVICE_NONSHARED
 	}, {
 		.virtual	= SPBA0_BASE_ADDR_VIRT,
 		.pfn		= __phys_to_pfn(SPBA0_BASE_ADDR),
 		.length		= SPBA0_SIZE,
-		.type		= MT_NONSHARED_DEVICE
+		.type		= MT_DEVICE_NONSHARED
 	}, {
 		.virtual	= AIPS2_BASE_ADDR_VIRT,
 		.pfn		= __phys_to_pfn(AIPS2_BASE_ADDR),
 		.length		= AIPS2_SIZE,
-		.type		= MT_NONSHARED_DEVICE
+		.type		= MT_DEVICE_NONSHARED
 	}, {
 		.virtual	= CS4_BASE_ADDR_VIRT,
 		.pfn		= __phys_to_pfn(CS4_BASE_ADDR),
@@ -120,12 +225,19 @@
 	iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc));
 }
 
+void __init mx31ads_init_irq(void)
+{
+	mxc_init_irq();
+	mx31ads_init_expio();
+}
+
 /*!
  * Board specific initialization.
  */
 static void __init mxc_board_init(void)
 {
 	mxc_init_extuart();
+	mxc_init_imx_uart();
 }
 
 static void __init mx31ads_timer_init(void)
@@ -148,7 +260,7 @@
 	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
 	.map_io         = mx31ads_map_io,
-	.init_irq       = mxc_init_irq,
+	.init_irq       = mx31ads_init_irq,
 	.init_machine   = mxc_board_init,
 	.timer          = &mx31ads_timer,
 MACHINE_END
diff --git a/arch/arm/mach-mx3/mx31lite.c b/arch/arm/mach-mx3/mx31lite.c
index d363a6e..c434400 100644
--- a/arch/arm/mach-mx3/mx31lite.c
+++ b/arch/arm/mach-mx3/mx31lite.c
@@ -45,17 +45,17 @@
 		.virtual = AIPS1_BASE_ADDR_VIRT,
 		.pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
 		.length = AIPS1_SIZE,
-		.type = MT_NONSHARED_DEVICE
+		.type = MT_DEVICE_NONSHARED
 	}, {
 		.virtual = SPBA0_BASE_ADDR_VIRT,
 		.pfn = __phys_to_pfn(SPBA0_BASE_ADDR),
 		.length = SPBA0_SIZE,
-		.type = MT_NONSHARED_DEVICE
+		.type = MT_DEVICE_NONSHARED
 	}, {
 		.virtual = AIPS2_BASE_ADDR_VIRT,
 		.pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
 		.length = AIPS2_SIZE,
-		.type = MT_NONSHARED_DEVICE
+		.type = MT_DEVICE_NONSHARED
 	}, {
 		.virtual = CS4_BASE_ADDR_VIRT,
 		.pfn = __phys_to_pfn(CS4_BASE_ADDR),
diff --git a/arch/arm/mach-mx3/pcm037.c b/arch/arm/mach-mx3/pcm037.c
index 0a152ed..11fda95 100644
--- a/arch/arm/mach-mx3/pcm037.c
+++ b/arch/arm/mach-mx3/pcm037.c
@@ -33,6 +33,8 @@
 #include <mach/iomux-mx3.h>
 #include <mach/board-pcm037.h>
 
+#include "devices.h"
+
 static struct physmap_flash_data pcm037_flash_data = {
 	.width  = 2,
 };
@@ -54,7 +56,7 @@
 };
 
 static struct imxuart_platform_data uart_pdata = {
-	.flags = 0,
+	.flags = IMXUART_HAVE_RTSCTS,
 };
 
 static struct platform_device *devices[] __initdata = {
@@ -73,12 +75,12 @@
 	mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
 	mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
 
-	imx_init_uart(0, &uart_pdata);
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
 
 	mxc_iomux_mode(MX31_PIN_CSPI3_MOSI__RXD3);
 	mxc_iomux_mode(MX31_PIN_CSPI3_MISO__TXD3);
 
-	imx_init_uart(2, &uart_pdata);
+	mxc_register_device(&mxc_uart_device2, &uart_pdata);
 }
 
 /*
diff --git a/arch/arm/mach-netx/generic.c b/arch/arm/mach-netx/generic.c
index 1b40483..79df60c 100644
--- a/arch/arm/mach-netx/generic.c
+++ b/arch/arm/mach-netx/generic.c
@@ -22,10 +22,10 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
 #include <asm/mach/map.h>
 #include <asm/hardware/vic.h>
-#include <asm/io.h>
 #include <mach/netx-regs.h>
 #include <asm/mach/irq.h>
 
@@ -77,15 +77,12 @@
 	stat = ((readl(NETX_DPMAS_INT_EN) &
 		readl(NETX_DPMAS_INT_STAT)) >> 24) & 0x1f;
 
-	desc = irq_desc + NETX_IRQ_HIF_CHAINED(0);
-
 	while (stat) {
 		if (stat & 1) {
 			DEBUG_IRQ("handling irq %d\n", irq);
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 		}
 		irq++;
-		desc++;
 		stat >>= 1;
 	}
 }
diff --git a/arch/arm/mach-netx/include/mach/system.h b/arch/arm/mach-netx/include/mach/system.h
index 27d8ef8..6c1023b 100644
--- a/arch/arm/mach-netx/include/mach/system.h
+++ b/arch/arm/mach-netx/include/mach/system.h
@@ -19,7 +19,7 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
 #include "netx-regs.h"
 
diff --git a/arch/arm/mach-netx/pfifo.c b/arch/arm/mach-netx/pfifo.c
index 19ae0a7..0398494 100644
--- a/arch/arm/mach-netx/pfifo.c
+++ b/arch/arm/mach-netx/pfifo.c
@@ -20,8 +20,8 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <mach/hardware.h>
 #include <mach/netx-regs.h>
 #include <mach/pfifo.h>
diff --git a/arch/arm/mach-netx/time.c b/arch/arm/mach-netx/time.c
index ac8e5bf..7c540c1 100644
--- a/arch/arm/mach-netx/time.c
+++ b/arch/arm/mach-netx/time.c
@@ -21,9 +21,9 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/clocksource.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/mach/time.h>
 #include <mach/netx-regs.h>
 
diff --git a/arch/arm/mach-netx/xc.c b/arch/arm/mach-netx/xc.c
index 04c34e8..32eabf5 100644
--- a/arch/arm/mach-netx/xc.c
+++ b/arch/arm/mach-netx/xc.c
@@ -21,8 +21,8 @@
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <linux/mutex.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <mach/hardware.h>
 #include <mach/netx-regs.h>
 
diff --git a/arch/arm/mach-ns9xxx/board-a9m9750dev.c b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
index a22a608..b45bb3b 100644
--- a/arch/arm/mach-ns9xxx/board-a9m9750dev.c
+++ b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
@@ -86,13 +86,10 @@
 
 	while (stat != 0) {
 		int irqno = fls(stat) - 1;
-		struct irq_desc *fpgadesc;
 
 		stat &= ~(1 << irqno);
 
-		fpgadesc = irq_desc + FPGA_IRQ(irqno);
-
-		desc_handle_irq(FPGA_IRQ(irqno), fpgadesc);
+		generic_handle_irq(FPGA_IRQ(irqno));
 	}
 
 	desc->chip->unmask(irq);
diff --git a/arch/arm/mach-ns9xxx/gpio.c b/arch/arm/mach-ns9xxx/gpio.c
index 804c300..5241e6a 100644
--- a/arch/arm/mach-ns9xxx/gpio.c
+++ b/arch/arm/mach-ns9xxx/gpio.c
@@ -12,13 +12,13 @@
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/module.h>
+#include <linux/bitops.h>
 
 #include <mach/gpio.h>
 #include <mach/processor.h>
 #include <mach/processor-ns9360.h>
 #include <asm/bug.h>
 #include <asm/types.h>
-#include <asm/bitops.h>
 
 #include "gpio-ns9360.h"
 
diff --git a/arch/arm/mach-ns9xxx/include/mach/uncompress.h b/arch/arm/mach-ns9xxx/include/mach/uncompress.h
index 5dbc3c5..1b12d32 100644
--- a/arch/arm/mach-ns9xxx/include/mach/uncompress.h
+++ b/arch/arm/mach-ns9xxx/include/mach/uncompress.h
@@ -11,7 +11,7 @@
 #ifndef __ASM_ARCH_UNCOMPRESS_H
 #define __ASM_ARCH_UNCOMPRESS_H
 
-#include <asm/io.h>
+#include <linux/io.h>
 
 #define __REG(x)	((void __iomem __force *)(x))
 
diff --git a/arch/arm/mach-ns9xxx/irq.c b/arch/arm/mach-ns9xxx/irq.c
index 38260d5..22e0eb6 100644
--- a/arch/arm/mach-ns9xxx/irq.c
+++ b/arch/arm/mach-ns9xxx/irq.c
@@ -10,7 +10,7 @@
  */
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/mach/irq.h>
 #include <mach/regs-sys-common.h>
 #include <mach/irqs.h>
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 213b487..45a0131 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -21,6 +21,7 @@
 #include <linux/reboot.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_reg.h>
+#include <linux/irq.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index 90ae0ef..5fba207 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -17,8 +17,8 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/mach-types.h>
 
 #include <mach/cpu.h>
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 79cfe01..e382b43 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -13,9 +13,9 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/mach/map.h>
 
 #include <mach/tc.h>
diff --git a/arch/arm/mach-omap1/fpga.c b/arch/arm/mach-omap1/fpga.c
index 4449d86..0499538 100644
--- a/arch/arm/mach-omap1/fpga.c
+++ b/arch/arm/mach-omap1/fpga.c
@@ -21,9 +21,9 @@
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/errno.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 
@@ -86,7 +86,6 @@
 
 void innovator_fpga_IRQ_demux(unsigned int irq, struct irq_desc *desc)
 {
-	struct irq_desc *d;
 	u32 stat;
 	int fpga_irq;
 
@@ -99,8 +98,7 @@
 	     (fpga_irq < OMAP_FPGA_IRQ_END) && stat;
 	     fpga_irq++, stat >>= 1) {
 		if (stat & 1) {
-			d = irq_desc + fpga_irq;
-			desc_handle_irq(fpga_irq, d);
+			generic_handle_irq(fpga_irq);
 		}
 	}
 }
diff --git a/arch/arm/mach-omap1/id.c b/arch/arm/mach-omap1/id.c
index da13c3e..13083d7 100644
--- a/arch/arm/mach-omap1/id.c
+++ b/arch/arm/mach-omap1/id.c
@@ -14,8 +14,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
 #define OMAP_DIE_ID_0		0xfffe1800
 #define OMAP_DIE_ID_1		0xfffe1804
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index 2b9750b..b3bd8ca 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -11,10 +11,10 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
 #include <asm/tlb.h>
 #include <asm/mach/map.h>
-#include <asm/io.h>
 #include <mach/mux.h>
 #include <mach/tc.h>
 
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
index 0ec6c1ec..9ad5197 100644
--- a/arch/arm/mach-omap1/irq.c
+++ b/arch/arm/mach-omap1/irq.c
@@ -40,6 +40,7 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
@@ -47,8 +48,6 @@
 #include <mach/gpio.h>
 #include <mach/cpu.h>
 
-#include <asm/io.h>
-
 #define IRQ_BANK(irq) ((irq) >> 5)
 #define IRQ_BIT(irq)  ((irq) & 0x1f)
 
diff --git a/arch/arm/mach-omap1/leds-h2p2-debug.c b/arch/arm/mach-omap1/leds-h2p2-debug.c
index 610f51f..71fe2cc 100644
--- a/arch/arm/mach-omap1/leds-h2p2-debug.c
+++ b/arch/arm/mach-omap1/leds-h2p2-debug.c
@@ -12,8 +12,8 @@
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
 #include <linux/sched.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <mach/hardware.h>
 #include <asm/leds.h>
 #include <asm/system.h>
diff --git a/arch/arm/mach-omap1/mailbox.c b/arch/arm/mach-omap1/mailbox.c
index af44eab..59abbf3 100644
--- a/arch/arm/mach-omap1/mailbox.c
+++ b/arch/arm/mach-omap1/mailbox.c
@@ -13,9 +13,9 @@
 #include <linux/resource.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 #include <mach/mailbox.h>
 #include <mach/irqs.h>
-#include <asm/io.h>
 
 #define MAILBOX_ARM2DSP1		0x00
 #define MAILBOX_ARM2DSP1b		0x04
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c
index 898516e..062c905 100644
--- a/arch/arm/mach-omap1/mux.c
+++ b/arch/arm/mach-omap1/mux.c
@@ -24,10 +24,11 @@
  */
 #include <linux/module.h>
 #include <linux/init.h>
-#include <asm/system.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/spinlock.h>
 
+#include <asm/system.h>
+
 #include <mach/mux.h>
 
 #ifdef CONFIG_OMAP_MUX
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
index 63c4ea1..770d256 100644
--- a/arch/arm/mach-omap1/pm.c
+++ b/arch/arm/mach-omap1/pm.c
@@ -41,8 +41,8 @@
 #include <linux/interrupt.h>
 #include <linux/sysfs.h>
 #include <linux/module.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/atomic.h>
 #include <asm/mach/time.h>
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index 4965986..528691d5c 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -18,8 +18,8 @@
 #include <linux/serial_8250.h>
 #include <linux/serial_reg.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/mach-types.h>
 
 #include <mach/board.h>
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
index e547085..2cf7e32 100644
--- a/arch/arm/mach-omap1/time.c
+++ b/arch/arm/mach-omap1/time.c
@@ -43,10 +43,10 @@
 #include <linux/err.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
+#include <linux/io.h>
 
 #include <asm/system.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/leds.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c
index e677601..705367e 100644
--- a/arch/arm/mach-omap1/timer32k.c
+++ b/arch/arm/mach-omap1/timer32k.c
@@ -44,10 +44,10 @@
 #include <linux/clk.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
+#include <linux/io.h>
 
 #include <asm/system.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/leds.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index b72ca13..24688ef 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -21,6 +21,7 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -34,8 +35,6 @@
 #include <mach/common.h>
 #include <mach/gpmc.h>
 
-#include <asm/io.h>
-
 
 #define	SDP2430_FLASH_CS	0
 #define	SDP2430_SMC91X_CS	5
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 9e2624c..d4e3b6f 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -21,6 +21,7 @@
 #include <linux/input.h>
 #include <linux/err.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -41,8 +42,6 @@
 #include <mach/dma.h>
 #include <mach/gpmc.h>
 
-#include <asm/io.h>
-
 #define H4_FLASH_CS	0
 #define H4_SMC91X_CS	1
 
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 57c4405..ad721e0 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -21,9 +21,8 @@
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
-#include <asm/bitops.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
 
 #include <mach/clock.h>
 #include <mach/clockdomain.h>
diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c
index 295e671..d382eb0 100644
--- a/arch/arm/mach-omap2/clock24xx.c
+++ b/arch/arm/mach-omap2/clock24xx.c
@@ -24,14 +24,13 @@
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
-
 #include <linux/io.h>
 #include <linux/cpufreq.h>
+#include <linux/bitops.h>
 
 #include <mach/clock.h>
 #include <mach/sram.h>
 #include <asm/div64.h>
-#include <asm/bitops.h>
 
 #include "memory.h"
 #include "clock.h"
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 0bf661d..084e110 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -25,11 +25,11 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/limits.h>
+#include <linux/bitops.h>
 
 #include <mach/clock.h>
 #include <mach/sram.h>
 #include <asm/div64.h>
-#include <asm/bitops.h>
 
 #include "memory.h"
 #include "clock.h"
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 7cca33e..90af2ac 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -13,9 +13,9 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
 
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 375ad27..763bdbe 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -17,9 +17,9 @@
 #include <linux/clk.h>
 #include <linux/ioport.h>
 #include <linux/spinlock.h>
+#include <linux/io.h>
 #include <linux/module.h>
 
-#include <asm/io.h>
 #include <asm/mach-types.h>
 #include <mach/gpmc.h>
 
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 0670c8d..bf45ff3 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -14,8 +14,9 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
+#include <asm/cputype.h>
 
 #include <mach/common.h>
 #include <mach/control.h>
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 71a9de3..5ea64f9 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -18,9 +18,9 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
 #include <asm/tlb.h>
-#include <asm/io.h>
 
 #include <asm/mach/map.h>
 
diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c
index a480b96..32b7af3 100644
--- a/arch/arm/mach-omap2/mailbox.c
+++ b/arch/arm/mach-omap2/mailbox.c
@@ -14,9 +14,9 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 #include <mach/mailbox.h>
 #include <mach/irqs.h>
-#include <asm/io.h>
 
 #define MAILBOX_REVISION		0x00
 #define MAILBOX_SYSCONFIG		0x10
diff --git a/arch/arm/mach-omap2/memory.c b/arch/arm/mach-omap2/memory.c
index 48b01f4..882c702 100644
--- a/arch/arm/mach-omap2/memory.c
+++ b/arch/arm/mach-omap2/memory.c
@@ -21,8 +21,7 @@
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include <mach/common.h>
 #include <mach/clock.h>
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 5558803..b139367 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -25,10 +25,11 @@
  */
 #include <linux/module.h>
 #include <linux/init.h>
-#include <asm/system.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/spinlock.h>
 
+#include <asm/system.h>
+
 #include <mach/control.h>
 #include <mach/mux.h>
 
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 8671e10..55361c1 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -24,8 +24,8 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/atomic.h>
 #include <asm/mach/time.h>
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 78ab2be..4dcf39c2 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -17,8 +17,7 @@
 #include <linux/serial_8250.h>
 #include <linux/serial_reg.h>
 #include <linux/clk.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include <mach/common.h>
 #include <mach/board.h>
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig
index ddcd41b..f59a8d0 100644
--- a/arch/arm/mach-orion5x/Kconfig
+++ b/arch/arm/mach-orion5x/Kconfig
@@ -36,6 +36,12 @@
 	  Say 'Y' here if you want your kernel to support the
 	  QNAP TS-109/TS-209 platform.
 
+config MACH_TERASTATION_PRO2
+	bool "Buffalo Terastation Pro II/Live"
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Buffalo Terastation Pro II/Live platform.
+
 config MACH_LINKSTATION_PRO
 	bool "Buffalo Linkstation Pro/Live"
 	select I2C_BOARDINFO
@@ -44,6 +50,13 @@
 	  Buffalo Linkstation Pro/Live platform. Both v1 and
 	  v2 devices are supported.
 
+config MACH_LINKSTATION_MINI
+	bool "Buffalo Linkstation Mini"
+	select I2C_BOARDINFO
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Buffalo Linkstation Mini platform.
+
 config MACH_TS409
 	bool "QNAP TS-409"
 	help
@@ -68,6 +81,13 @@
 	  Say 'Y' here if you want your kernel to support the
 	  HP Media Vault mv2120 or mv5100.
 
+config MACH_EDMINI_V2
+	bool "LaCie Ethernet Disk mini V2"
+	select I2C_BOARDINFO
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  LaCie Ethernet Disk mini V2.
+
 config MACH_MSS2
 	bool "Maxtor Shared Storage II"
 	help
@@ -92,6 +112,12 @@
 	  Say 'Y' here if you want your kernel to support the
 	  Marvell Orion-VoIP FXO (88F5181L) RD.
 
+config MACH_RD88F6183AP_GE
+	bool "Marvell Orion-1-90 AP GE Reference Design"
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Marvell Orion-1-90 (88F6183) AP GE RD.
+
 endmenu
 
 endif
diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile
index fcc48a8..3d4a1bc 100644
--- a/arch/arm/mach-orion5x/Makefile
+++ b/arch/arm/mach-orion5x/Makefile
@@ -2,14 +2,18 @@
 obj-$(CONFIG_MACH_DB88F5281)	+= db88f5281-setup.o
 obj-$(CONFIG_MACH_RD88F5182)	+= rd88f5182-setup.o
 obj-$(CONFIG_MACH_KUROBOX_PRO)	+= kurobox_pro-setup.o
+obj-$(CONFIG_MACH_TERASTATION_PRO2)	+= terastation_pro2-setup.o
 obj-$(CONFIG_MACH_LINKSTATION_PRO) += kurobox_pro-setup.o
+obj-$(CONFIG_MACH_LINKSTATION_MINI) += lsmini-setup.o
 obj-$(CONFIG_MACH_DNS323)	+= dns323-setup.o
 obj-$(CONFIG_MACH_TS209)	+= ts209-setup.o tsx09-common.o
 obj-$(CONFIG_MACH_TS409)	+= ts409-setup.o tsx09-common.o
 obj-$(CONFIG_MACH_WRT350N_V2)	+= wrt350n-v2-setup.o
 obj-$(CONFIG_MACH_TS78XX)	+= ts78xx-setup.o
 obj-$(CONFIG_MACH_MV2120)	+= mv2120-setup.o
+obj-$(CONFIG_MACH_EDMINI_V2)	+= edmini_v2-setup.o
 obj-$(CONFIG_MACH_MSS2)		+= mss2-setup.o
 obj-$(CONFIG_MACH_WNR854T)	+= wnr854t-setup.o
 obj-$(CONFIG_MACH_RD88F5181L_GE)	+= rd88f5181l-ge-setup.o
 obj-$(CONFIG_MACH_RD88F5181L_FXO)	+= rd88f5181l-fxo-setup.o
+obj-$(CONFIG_MACH_RD88F6183AP_GE)	+= rd88f6183ap-ge-setup.o
diff --git a/arch/arm/mach-orion5x/addr-map.c b/arch/arm/mach-orion5x/addr-map.c
index bea3797..719957e 100644
--- a/arch/arm/mach-orion5x/addr-map.c
+++ b/arch/arm/mach-orion5x/addr-map.c
@@ -13,8 +13,8 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/mbus.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include "common.h"
 
 /*
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c
index 7b11e55..9625ef5 100644
--- a/arch/arm/mach-orion5x/common.c
+++ b/arch/arm/mach-orion5x/common.c
@@ -18,6 +18,7 @@
 #include <linux/mv643xx_eth.h>
 #include <linux/mv643xx_i2c.h>
 #include <linux/ata_platform.h>
+#include <linux/spi/orion_spi.h>
 #include <asm/page.h>
 #include <asm/setup.h>
 #include <asm/timex.h>
@@ -146,7 +147,6 @@
  ****************************************************************************/
 struct mv643xx_eth_shared_platform_data orion5x_eth_shared_data = {
 	.dram		= &orion5x_mbus_dram_info,
-	.t_clk		= ORION5X_TCLK,
 };
 
 static struct resource orion5x_eth_shared_resources[] = {
@@ -154,6 +154,10 @@
 		.start	= ORION5X_ETH_PHYS_BASE + 0x2000,
 		.end	= ORION5X_ETH_PHYS_BASE + 0x3fff,
 		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_ORION5X_ETH_ERR,
+		.end	= IRQ_ORION5X_ETH_ERR,
+		.flags	= IORESOURCE_IRQ,
 	},
 };
 
@@ -163,7 +167,7 @@
 	.dev		= {
 		.platform_data	= &orion5x_eth_shared_data,
 	},
-	.num_resources	= 1,
+	.num_resources	= ARRAY_SIZE(orion5x_eth_shared_resources),
 	.resource	= orion5x_eth_shared_resources,
 };
 
@@ -268,6 +272,38 @@
 
 
 /*****************************************************************************
+ * SPI
+ ****************************************************************************/
+static struct orion_spi_info orion5x_spi_plat_data = {
+	.tclk		= 0,
+};
+
+static struct resource orion5x_spi_resources[] = {
+	{
+		.name	= "spi base",
+		.start	= SPI_PHYS_BASE,
+		.end	= SPI_PHYS_BASE + 0x1f,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device orion5x_spi = {
+	.name		= "orion_spi",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &orion5x_spi_plat_data,
+	},
+	.num_resources	= ARRAY_SIZE(orion5x_spi_resources),
+	.resource	= orion5x_spi_resources,
+};
+
+void __init orion5x_spi_init()
+{
+	platform_device_register(&orion5x_spi);
+}
+
+
+/*****************************************************************************
  * UART0
  ****************************************************************************/
 static struct plat_serial8250_port orion5x_uart0_data[] = {
@@ -278,7 +314,7 @@
 		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
 		.iotype		= UPIO_MEM,
 		.regshift	= 2,
-		.uartclk	= ORION5X_TCLK,
+		.uartclk	= 0,
 	}, {
 	},
 };
@@ -322,7 +358,7 @@
 		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
 		.iotype		= UPIO_MEM,
 		.regshift	= 2,
-		.uartclk	= ORION5X_TCLK,
+		.uartclk	= 0,
 	}, {
 	},
 };
@@ -455,9 +491,24 @@
 /*****************************************************************************
  * Time handling
  ****************************************************************************/
+int orion5x_tclk;
+
+int __init orion5x_find_tclk(void)
+{
+	u32 dev, rev;
+
+	orion5x_pcie_id(&dev, &rev);
+	if (dev == MV88F6183_DEV_ID &&
+	    (readl(MPP_RESET_SAMPLE) & 0x00000200) == 0)
+		return 133333333;
+
+	return 166666667;
+}
+
 static void orion5x_timer_init(void)
 {
-	orion_time_init(IRQ_ORION5X_BRIDGE, ORION5X_TCLK);
+	orion5x_tclk = orion5x_find_tclk();
+	orion_time_init(IRQ_ORION5X_BRIDGE, orion5x_tclk);
 }
 
 struct sys_timer orion5x_timer = {
@@ -499,6 +550,12 @@
 		} else {
 			*dev_name = "MV88F5181(L)-Rev-Unsupported";
 		}
+	} else if (*dev == MV88F6183_DEV_ID) {
+		if (*rev == MV88F6183_REV_B0) {
+			*dev_name = "MV88F6183-Rev-B0";
+		} else {
+			*dev_name = "MV88F6183-Rev-Unsupported";
+		}
 	} else {
 		*dev_name = "Device-Unknown";
 	}
@@ -510,7 +567,12 @@
 	u32 dev, rev;
 
 	orion5x_id(&dev, &rev, &dev_name);
-	printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, ORION5X_TCLK);
+	printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, orion5x_tclk);
+
+	orion5x_eth_shared_data.t_clk = orion5x_tclk;
+	orion5x_spi_plat_data.tclk = orion5x_tclk;
+	orion5x_uart0_data[0].uartclk = orion5x_tclk;
+	orion5x_uart1_data[0].uartclk = orion5x_tclk;
 
 	/*
 	 * Setup Orion address map
diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h
index 0bd1955..1f8b2da 100644
--- a/arch/arm/mach-orion5x/common.h
+++ b/arch/arm/mach-orion5x/common.h
@@ -10,6 +10,7 @@
 void orion5x_map_io(void);
 void orion5x_init_irq(void);
 void orion5x_init(void);
+extern int orion5x_tclk;
 extern struct sys_timer orion5x_timer;
 
 /*
@@ -30,6 +31,7 @@
 void orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data);
 void orion5x_i2c_init(void);
 void orion5x_sata_init(struct mv_sata_platform_data *sata_data);
+void orion5x_spi_init(void);
 void orion5x_uart0_init(void);
 void orion5x_uart1_init(void);
 void orion5x_xor_init(void);
diff --git a/arch/arm/mach-orion5x/edmini_v2-setup.c b/arch/arm/mach-orion5x/edmini_v2-setup.c
new file mode 100644
index 0000000..b24ee0c
--- /dev/null
+++ b/arch/arm/mach-orion5x/edmini_v2-setup.c
@@ -0,0 +1,262 @@
+/*
+ * arch/arm/mach-orion5x/edmini_v2-setup.c
+ *
+ * LaCie Ethernet Disk mini V2 Setup
+ *
+ * Copyright (C) 2008 Christopher Moore <moore@free.fr>
+ * Copyright (C) 2008 Albert Aribaud <albert.aribaud@free.fr>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/*
+ * TODO: add Orion USB device port init when kernel.org support is added.
+ * TODO: add flash write support: see below.
+ * TODO: add power-off support.
+ * TODO: add I2C EEPROM support.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/ata_platform.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * EDMINI_V2 Info
+ ****************************************************************************/
+
+/*
+ * 512KB NOR flash Device bus boot chip select
+ */
+
+#define EDMINI_V2_NOR_BOOT_BASE		0xfff80000
+#define EDMINI_V2_NOR_BOOT_SIZE		SZ_512K
+
+/*****************************************************************************
+ * 512KB NOR Flash on BOOT Device
+ ****************************************************************************/
+
+/*
+ * Currently the MTD code does not recognize the MX29LV400CBCT as a bottom
+ * -type device. This could cause risks of accidentally erasing critical
+ * flash sectors. We thus define a single, write-protected partition covering
+ * the whole flash.
+ * TODO: once the flash part TOP/BOTTOM detection issue is sorted out in the MTD
+ * code, break this into at least three partitions: 'u-boot code', 'u-boot
+ * environment' and 'whatever is left'.
+ */
+
+static struct mtd_partition edmini_v2_partitions[] = {
+	{
+		.name		= "Full512kb",
+		.size		= 0x00080000,
+		.offset		= 0x00000000,
+		.mask_flags	= MTD_WRITEABLE,
+	},
+};
+
+static struct physmap_flash_data edmini_v2_nor_flash_data = {
+	.width		= 1,
+	.parts		= edmini_v2_partitions,
+	.nr_parts	= ARRAY_SIZE(edmini_v2_partitions),
+};
+
+static struct resource edmini_v2_nor_flash_resource = {
+	.flags			= IORESOURCE_MEM,
+	.start			= EDMINI_V2_NOR_BOOT_BASE,
+	.end			= EDMINI_V2_NOR_BOOT_BASE
+		+ EDMINI_V2_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device edmini_v2_nor_flash = {
+	.name			= "physmap-flash",
+	.id			= 0,
+	.dev		= {
+		.platform_data	= &edmini_v2_nor_flash_data,
+	},
+	.num_resources		= 1,
+	.resource		= &edmini_v2_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data edmini_v2_eth_data = {
+	.phy_addr	= 8,
+};
+
+/*****************************************************************************
+ * RTC 5C372a on I2C bus
+ ****************************************************************************/
+
+#define EDMINIV2_RTC_GPIO	3
+
+static struct i2c_board_info __initdata edmini_v2_i2c_rtc = {
+	I2C_BOARD_INFO("rs5c372a", 0x32),
+	.irq = 0,
+};
+
+/*****************************************************************************
+ * Sata
+ ****************************************************************************/
+
+static struct mv_sata_platform_data edmini_v2_sata_data = {
+	.n_ports	= 2,
+};
+
+/*****************************************************************************
+ * GPIO LED (simple - doesn't use hardware blinking support)
+ ****************************************************************************/
+
+#define EDMINI_V2_GPIO_LED_POWER	16
+
+static struct gpio_led edmini_v2_leds[] = {
+	{
+		.name = "power:blue",
+		.gpio = EDMINI_V2_GPIO_LED_POWER,
+		.active_low = 1,
+	},
+};
+
+static struct gpio_led_platform_data edmini_v2_led_data = {
+	.num_leds = ARRAY_SIZE(edmini_v2_leds),
+	.leds = edmini_v2_leds,
+};
+
+static struct platform_device edmini_v2_gpio_leds = {
+	.name           = "leds-gpio",
+	.id             = -1,
+	.dev            = {
+		.platform_data  = &edmini_v2_led_data,
+	},
+};
+
+/****************************************************************************
+ * GPIO key
+ ****************************************************************************/
+
+#define EDMINI_V2_GPIO_KEY_POWER	18
+
+static struct gpio_keys_button edmini_v2_buttons[] = {
+	{
+		.code		= KEY_POWER,
+		.gpio		= EDMINI_V2_GPIO_KEY_POWER,
+		.desc		= "Power Button",
+		.active_low	= 0,
+	},
+};
+
+static struct gpio_keys_platform_data edmini_v2_button_data = {
+	.buttons	= edmini_v2_buttons,
+	.nbuttons	= ARRAY_SIZE(edmini_v2_buttons),
+};
+
+static struct platform_device edmini_v2_gpio_buttons = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &edmini_v2_button_data,
+	},
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static struct orion5x_mpp_mode edminiv2_mpp_modes[] __initdata = {
+	{  0, MPP_UNUSED },
+	{  1, MPP_UNUSED },
+	{  2, MPP_UNUSED },
+	{  3, MPP_GPIO },	/* RTC interrupt */
+	{  4, MPP_UNUSED },
+	{  5, MPP_UNUSED },
+	{  6, MPP_UNUSED },
+	{  7, MPP_UNUSED },
+	{  8, MPP_UNUSED },
+	{  9, MPP_UNUSED },
+	{ 10, MPP_UNUSED },
+	{ 11, MPP_UNUSED },
+	{ 12, MPP_SATA_LED },	/* SATA 0 presence */
+	{ 13, MPP_SATA_LED },	/* SATA 1 presence */
+	{ 14, MPP_SATA_LED },	/* SATA 0 active */
+	{ 15, MPP_SATA_LED },	/* SATA 1 active */
+	/* 16: Power LED control (0 = On, 1 = Off) */
+	{ 16, MPP_GPIO },
+	/* 17: Power LED control select (0 = CPLD, 1 = GPIO16) */
+	{ 17, MPP_GPIO },
+	/* 18: Power button status (0 = Released, 1 = Pressed) */
+	{ 18, MPP_GPIO },
+	{ 19, MPP_UNUSED },
+	{ -1 }
+};
+
+static void __init edmini_v2_init(void)
+{
+	/*
+	 * Setup basic Orion functions. Need to be called early.
+	 */
+	orion5x_init();
+
+	orion5x_mpp_conf(edminiv2_mpp_modes);
+
+	/*
+	 * Configure peripherals.
+	 */
+	orion5x_ehci0_init();
+	orion5x_eth_init(&edmini_v2_eth_data);
+	orion5x_i2c_init();
+	orion5x_sata_init(&edmini_v2_sata_data);
+	orion5x_uart0_init();
+
+	orion5x_setup_dev_boot_win(EDMINI_V2_NOR_BOOT_BASE,
+				EDMINI_V2_NOR_BOOT_SIZE);
+	platform_device_register(&edmini_v2_nor_flash);
+	platform_device_register(&edmini_v2_gpio_leds);
+	platform_device_register(&edmini_v2_gpio_buttons);
+
+	pr_notice("edmini_v2: USB device port, flash write and power-off "
+		  "are not yet supported.\n");
+
+	/* Get RTC IRQ and register the chip */
+	if (gpio_request(EDMINIV2_RTC_GPIO, "rtc") == 0) {
+		if (gpio_direction_input(EDMINIV2_RTC_GPIO) == 0)
+			edmini_v2_i2c_rtc.irq = gpio_to_irq(EDMINIV2_RTC_GPIO);
+		else
+			gpio_free(EDMINIV2_RTC_GPIO);
+	}
+
+	if (edmini_v2_i2c_rtc.irq == 0)
+		pr_warning("edmini_v2: failed to get RTC IRQ\n");
+
+	i2c_register_board_info(0, &edmini_v2_i2c_rtc, 1);
+}
+
+/* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
+MACHINE_START(EDMINI_V2, "LaCie Ethernet Disk mini V2")
+	/* Maintainer: Christopher Moore <moore@free.fr> */
+	.phys_io	= ORION5X_REGS_PHYS_BASE,
+	.io_pg_offst	= ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+	.boot_params	= 0x00000100,
+	.init_machine	= edmini_v2_init,
+	.map_io		= orion5x_map_io,
+	.init_irq	= orion5x_init_irq,
+	.timer		= &orion5x_timer,
+	.fixup		= tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/gpio.c b/arch/arm/mach-orion5x/gpio.c
index cd8a16f..fc41986 100644
--- a/arch/arm/mach-orion5x/gpio.c
+++ b/arch/arm/mach-orion5x/gpio.c
@@ -15,8 +15,8 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/bitops.h>
+#include <linux/io.h>
 #include <asm/gpio.h>
-#include <asm/io.h>
 #include <mach/orion5x.h>
 #include "common.h"
 
diff --git a/arch/arm/mach-orion5x/include/mach/orion5x.h b/arch/arm/mach-orion5x/include/mach/orion5x.h
index 61eb74a..e67c843 100644
--- a/arch/arm/mach-orion5x/include/mach/orion5x.h
+++ b/arch/arm/mach-orion5x/include/mach/orion5x.h
@@ -2,7 +2,7 @@
  * arch/arm/mach-orion5x/include/mach/orion5x.h
  *
  * Generic definitions of Orion SoC flavors:
- *  Orion-1, Orion-VoIP, Orion-NAS, and Orion-2.
+ *  Orion-1, Orion-VoIP, Orion-NAS, Orion-2, and Orion-1-90.
  *
  * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
  *
@@ -76,6 +76,9 @@
 #define MV88F5281_REV_D0	4
 #define MV88F5281_REV_D1	5
 #define MV88F5281_REV_D2	6
+/* Orion-1-90 (88F6183) */
+#define MV88F6183_DEV_ID	0x6183
+#define MV88F6183_REV_B0	3
 
 /*******************************************************************************
  * Orion Registers Map
@@ -86,6 +89,7 @@
 #define ORION5X_DEV_BUS_PHYS_BASE	(ORION5X_REGS_PHYS_BASE | 0x10000)
 #define ORION5X_DEV_BUS_VIRT_BASE	(ORION5X_REGS_VIRT_BASE | 0x10000)
 #define ORION5X_DEV_BUS_REG(x)		(ORION5X_DEV_BUS_VIRT_BASE | (x))
+#define  SPI_PHYS_BASE			(ORION5X_DEV_BUS_PHYS_BASE | 0x0600)
 #define  I2C_PHYS_BASE			(ORION5X_DEV_BUS_PHYS_BASE | 0x1000)
 #define  UART0_PHYS_BASE		(ORION5X_DEV_BUS_PHYS_BASE | 0x2000)
 #define  UART0_VIRT_BASE		(ORION5X_DEV_BUS_VIRT_BASE | 0x2000)
diff --git a/arch/arm/mach-orion5x/include/mach/timex.h b/arch/arm/mach-orion5x/include/mach/timex.h
index e82e44d..4c69820 100644
--- a/arch/arm/mach-orion5x/include/mach/timex.h
+++ b/arch/arm/mach-orion5x/include/mach/timex.h
@@ -9,5 +9,3 @@
  */
 
 #define CLOCK_TICK_RATE		(100 * HZ)
-
-#define ORION5X_TCLK		166666667
diff --git a/arch/arm/mach-orion5x/irq.c b/arch/arm/mach-orion5x/irq.c
index 2545ff9..632a36f 100644
--- a/arch/arm/mach-orion5x/irq.c
+++ b/arch/arm/mach-orion5x/irq.c
@@ -13,8 +13,8 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/io.h>
 #include <asm/gpio.h>
-#include <asm/io.h>
 #include <mach/orion5x.h>
 #include <plat/irq.h>
 #include "common.h"
@@ -162,7 +162,7 @@
 				polarity ^= 1 << pin;
 				writel(polarity, GPIO_IN_POL);
 			}
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 		}
 	}
 }
diff --git a/arch/arm/mach-orion5x/kurobox_pro-setup.c b/arch/arm/mach-orion5x/kurobox_pro-setup.c
index e321ec3..c5bd54d 100644
--- a/arch/arm/mach-orion5x/kurobox_pro-setup.c
+++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c
@@ -293,7 +293,7 @@
 	const unsigned char shutdownwait[]	= {0x00, 0x0c};
 	const unsigned char poweroff[]		= {0x00, 0x06};
 	/* 38400 baud divisor */
-	const unsigned divisor = ((ORION5X_TCLK + (8 * 38400)) / (16 * 38400));
+	const unsigned divisor = ((orion5x_tclk + (8 * 38400)) / (16 * 38400));
 
 	pr_info("%s: triggering power-off...\n", __func__);
 
diff --git a/arch/arm/mach-orion5x/lsmini-setup.c b/arch/arm/mach-orion5x/lsmini-setup.c
new file mode 100644
index 0000000..e0c43b8
--- /dev/null
+++ b/arch/arm/mach-orion5x/lsmini-setup.c
@@ -0,0 +1,279 @@
+/*
+ * arch/arm/mach-orion5x/lsmini-setup.c
+ *
+ * Maintainer: Alexey Kopytko <alexey@kopytko.ru>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/ata_platform.h>
+#include <asm/mach-types.h>
+#include <linux/gpio.h>
+#include <asm/mach/arch.h>
+#include "common.h"
+#include "mpp.h"
+#include "include/mach/system.h"
+
+/*****************************************************************************
+ * Linkstation Mini Info
+ ****************************************************************************/
+
+/*
+ * 256K NOR flash Device bus boot chip select
+ */
+
+#define LSMINI_NOR_BOOT_BASE	0xf4000000
+#define LSMINI_NOR_BOOT_SIZE	SZ_256K
+
+/*****************************************************************************
+ * 256KB NOR Flash on BOOT Device
+ ****************************************************************************/
+
+static struct physmap_flash_data lsmini_nor_flash_data = {
+	.width		= 1,
+};
+
+static struct resource lsmini_nor_flash_resource = {
+	.flags	= IORESOURCE_MEM,
+	.start	= LSMINI_NOR_BOOT_BASE,
+	.end	= LSMINI_NOR_BOOT_BASE + LSMINI_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device lsmini_nor_flash = {
+	.name			= "physmap-flash",
+	.id			= 0,
+	.dev		= {
+		.platform_data	= &lsmini_nor_flash_data,
+	},
+	.num_resources		= 1,
+	.resource		= &lsmini_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data lsmini_eth_data = {
+	.phy_addr	= 8,
+};
+
+/*****************************************************************************
+ * RTC 5C372a on I2C bus
+ ****************************************************************************/
+
+static struct i2c_board_info __initdata lsmini_i2c_rtc = {
+	I2C_BOARD_INFO("rs5c372a", 0x32),
+};
+
+/*****************************************************************************
+ * LEDs attached to GPIO
+ ****************************************************************************/
+
+#define LSMINI_GPIO_LED_ALARM	2
+#define LSMINI_GPIO_LED_INFO	3
+#define LSMINI_GPIO_LED_FUNC	9
+#define LSMINI_GPIO_LED_PWR	14
+
+static struct gpio_led lsmini_led_pins[] = {
+	{
+		.name	   = "alarm:red",
+		.gpio	   = LSMINI_GPIO_LED_ALARM,
+		.active_low     = 1,
+	}, {
+		.name	   = "info:amber",
+		.gpio	   = LSMINI_GPIO_LED_INFO,
+		.active_low     = 1,
+	}, {
+		.name	   = "func:blue:top",
+		.gpio	   = LSMINI_GPIO_LED_FUNC,
+		.active_low     = 1,
+	}, {
+		.name	   = "power:blue:bottom",
+		.gpio	   = LSMINI_GPIO_LED_PWR,
+	},
+};
+
+static struct gpio_led_platform_data lsmini_led_data = {
+	.leds	   = lsmini_led_pins,
+	.num_leds       = ARRAY_SIZE(lsmini_led_pins),
+};
+
+static struct platform_device lsmini_leds = {
+	.name   = "leds-gpio",
+	.id     = -1,
+	.dev    = {
+		.platform_data  = &lsmini_led_data,
+	},
+};
+
+/****************************************************************************
+ * GPIO Attached Keys
+ ****************************************************************************/
+
+#define LSMINI_GPIO_KEY_FUNC       15
+#define LSMINI_GPIO_KEY_POWER	   18
+#define LSMINI_GPIO_KEY_AUTOPOWER 17
+
+#define LSMINI_SW_POWER		0x00
+#define LSMINI_SW_AUTOPOWER	0x01
+
+static struct gpio_keys_button lsmini_buttons[] = {
+	{
+		.code	   = KEY_OPTION,
+		.gpio	   = LSMINI_GPIO_KEY_FUNC,
+		.desc	   = "Function Button",
+		.active_low     = 1,
+	}, {
+		.type		= EV_SW,
+		.code	   = LSMINI_SW_POWER,
+		.gpio	   = LSMINI_GPIO_KEY_POWER,
+		.desc	   = "Power-on Switch",
+		.active_low     = 1,
+	}, {
+		.type		= EV_SW,
+		.code	   = LSMINI_SW_AUTOPOWER,
+		.gpio	   = LSMINI_GPIO_KEY_AUTOPOWER,
+		.desc	   = "Power-auto Switch",
+		.active_low     = 1,
+	},
+};
+
+static struct gpio_keys_platform_data lsmini_button_data = {
+	.buttons	= lsmini_buttons,
+	.nbuttons       = ARRAY_SIZE(lsmini_buttons),
+};
+
+static struct platform_device lsmini_button_device = {
+	.name	   = "gpio-keys",
+	.id	     = -1,
+	.num_resources  = 0,
+	.dev	    = {
+		.platform_data  = &lsmini_button_data,
+	},
+};
+
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+static struct mv_sata_platform_data lsmini_sata_data = {
+	.n_ports	= 2,
+};
+
+
+/*****************************************************************************
+ * Linkstation Mini specific power off method: reboot
+ ****************************************************************************/
+/*
+ * On the Linkstation Mini, the shutdown process is following:
+ * - Userland monitors key events until the power switch goes to off position
+ * - The board reboots
+ * - U-boot starts and goes into an idle mode waiting for the user
+ *   to move the switch to ON position
+ */
+
+static void lsmini_power_off(void)
+{
+	arch_reset(0);
+}
+
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+#define LSMINI_GPIO_USB_POWER	16
+#define LSMINI_GPIO_AUTO_POWER	17
+#define LSMINI_GPIO_POWER	18
+
+#define LSMINI_GPIO_HDD_POWER0	1
+#define LSMINI_GPIO_HDD_POWER1	19
+
+static struct orion5x_mpp_mode lsmini_mpp_modes[] __initdata = {
+	{  0, MPP_UNUSED }, /* LED_RESERVE1 (unused) */
+	{  1, MPP_GPIO }, /* HDD_PWR */
+	{  2, MPP_GPIO }, /* LED_ALARM */
+	{  3, MPP_GPIO }, /* LED_INFO */
+	{  4, MPP_UNUSED },
+	{  5, MPP_UNUSED },
+	{  6, MPP_UNUSED },
+	{  7, MPP_UNUSED },
+	{  8, MPP_UNUSED },
+	{  9, MPP_GPIO }, /* LED_FUNC */
+	{ 10, MPP_UNUSED },
+	{ 11, MPP_UNUSED }, /* LED_ETH (dummy) */
+	{ 12, MPP_UNUSED },
+	{ 13, MPP_UNUSED },
+	{ 14, MPP_GPIO }, /* LED_PWR */
+	{ 15, MPP_GPIO }, /* FUNC */
+	{ 16, MPP_GPIO }, /* USB_PWR */
+	{ 17, MPP_GPIO }, /* AUTO_POWER */
+	{ 18, MPP_GPIO }, /* POWER */
+	{ 19, MPP_GPIO }, /* HDD_PWR1 */
+	{ -1 },
+};
+
+static void __init lsmini_init(void)
+{
+	/*
+	 * Setup basic Orion functions. Need to be called early.
+	 */
+	orion5x_init();
+
+	orion5x_mpp_conf(lsmini_mpp_modes);
+
+	/*
+	 * Configure peripherals.
+	 */
+	orion5x_ehci0_init();
+	orion5x_ehci1_init();
+	orion5x_eth_init(&lsmini_eth_data);
+	orion5x_i2c_init();
+	orion5x_sata_init(&lsmini_sata_data);
+	orion5x_uart0_init();
+	orion5x_xor_init();
+
+	orion5x_setup_dev_boot_win(LSMINI_NOR_BOOT_BASE,
+				   LSMINI_NOR_BOOT_SIZE);
+	platform_device_register(&lsmini_nor_flash);
+
+	platform_device_register(&lsmini_button_device);
+
+	platform_device_register(&lsmini_leds);
+
+	i2c_register_board_info(0, &lsmini_i2c_rtc, 1);
+
+	/* enable USB power */
+	gpio_set_value(LSMINI_GPIO_USB_POWER, 1);
+
+	/* register power-off method */
+	pm_power_off = lsmini_power_off;
+
+	pr_info("%s: finished\n", __func__);
+}
+
+#ifdef CONFIG_MACH_LINKSTATION_MINI
+MACHINE_START(LINKSTATION_MINI, "Buffalo Linkstation Mini")
+	/* Maintainer: Alexey Kopytko <alexey@kopytko.ru> */
+	.phys_io	= ORION5X_REGS_PHYS_BASE,
+	.io_pg_offst	= ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+	.boot_params	= 0x00000100,
+	.init_machine	= lsmini_init,
+	.map_io		= orion5x_map_io,
+	.init_irq	= orion5x_init_irq,
+	.timer		= &orion5x_timer,
+	.fixup		= tag_fixup_mem32,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-orion5x/mpp.c b/arch/arm/mach-orion5x/mpp.c
index c04ab0e..640ea2a 100644
--- a/arch/arm/mach-orion5x/mpp.c
+++ b/arch/arm/mach-orion5x/mpp.c
@@ -11,8 +11,8 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/mbus.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include "common.h"
 #include "mpp.h"
 
diff --git a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
new file mode 100644
index 0000000..40e0495
--- /dev/null
+++ b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
@@ -0,0 +1,117 @@
+/*
+ * arch/arm/mach-orion5x/rd88f6183-ap-ge-setup.c
+ *
+ * Marvell Orion-1-90 AP GE Reference Design Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/orion_spi.h>
+#include <linux/spi/flash.h>
+#include <linux/ethtool.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/leds.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mv643xx_eth_platform_data rd88f6183ap_ge_eth_data = {
+	.phy_addr	= -1,
+	.speed		= SPEED_1000,
+	.duplex		= DUPLEX_FULL,
+};
+
+static struct mtd_partition rd88f6183ap_ge_partitions[] = {
+	{
+		.name	= "kernel",
+		.offset	= 0x00000000,
+		.size	= 0x00200000,
+	}, {
+		.name	= "rootfs",
+		.offset	= 0x00200000,
+		.size	= 0x00500000,
+	}, {
+		.name	= "nvram",
+		.offset	= 0x00700000,
+		.size	= 0x00080000,
+	},
+};
+
+static struct flash_platform_data rd88f6183ap_ge_spi_slave_data = {
+	.type		= "m25p64",
+	.nr_parts	= ARRAY_SIZE(rd88f6183ap_ge_partitions),
+	.parts		= rd88f6183ap_ge_partitions,
+};
+
+static struct spi_board_info __initdata rd88f6183ap_ge_spi_slave_info[] = {
+	{
+		.modalias	= "m25p80",
+		.platform_data	= &rd88f6183ap_ge_spi_slave_data,
+		.irq		= NO_IRQ,
+		.max_speed_hz	= 20000000,
+		.bus_num	= 0,
+		.chip_select	= 0,
+	},
+};
+
+static void __init rd88f6183ap_ge_init(void)
+{
+	/*
+	 * Setup basic Orion functions. Need to be called early.
+	 */
+	orion5x_init();
+
+	/*
+	 * Configure peripherals.
+	 */
+	orion5x_ehci0_init();
+	orion5x_eth_init(&rd88f6183ap_ge_eth_data);
+	spi_register_board_info(rd88f6183ap_ge_spi_slave_info,
+				ARRAY_SIZE(rd88f6183ap_ge_spi_slave_info));
+	orion5x_spi_init();
+	orion5x_uart0_init();
+}
+
+static struct hw_pci rd88f6183ap_ge_pci __initdata = {
+	.nr_controllers	= 2,
+	.swizzle	= pci_std_swizzle,
+	.setup		= orion5x_pci_sys_setup,
+	.scan		= orion5x_pci_sys_scan_bus,
+	.map_irq	= orion5x_pci_map_irq,
+};
+
+static int __init rd88f6183ap_ge_pci_init(void)
+{
+	if (machine_is_rd88f6183ap_ge()) {
+		orion5x_pci_disable();
+		pci_common_init(&rd88f6183ap_ge_pci);
+	}
+
+	return 0;
+}
+subsys_initcall(rd88f6183ap_ge_pci_init);
+
+MACHINE_START(RD88F6183AP_GE, "Marvell Orion-1-90 AP GE Reference Design")
+	/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
+	.phys_io	= ORION5X_REGS_PHYS_BASE,
+	.io_pg_offst	= ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+	.boot_params	= 0x00000100,
+	.init_machine	= rd88f6183ap_ge_init,
+	.map_io		= orion5x_map_io,
+	.init_irq	= orion5x_init_irq,
+	.timer		= &orion5x_timer,
+	.fixup		= tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/terastation_pro2-setup.c b/arch/arm/mach-orion5x/terastation_pro2-setup.c
new file mode 100644
index 0000000..0b101d7d
--- /dev/null
+++ b/arch/arm/mach-orion5x/terastation_pro2-setup.c
@@ -0,0 +1,369 @@
+/*
+ * Buffalo Terastation Pro II/Live Board Setup
+ *
+ * Maintainer: Sylver Bruneau <sylver.bruneau@googlemail.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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/i2c.h>
+#include <linux/serial_reg.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * Terastation Pro 2/Live Info
+ ****************************************************************************/
+
+/*
+ * Terastation Pro 2 hardware :
+ * - Marvell 88F5281-D0
+ * - Marvell 88SX6042 SATA controller (PCI)
+ * - Marvell 88E1118 Gigabit Ethernet PHY
+ * - 256KB NOR flash
+ * - 128MB of DDR RAM
+ * - PCIe port (not equipped)
+ */
+
+/*
+ * 256K NOR flash Device bus boot chip select
+ */
+
+#define TSP2_NOR_BOOT_BASE	0xf4000000
+#define TSP2_NOR_BOOT_SIZE	SZ_256K
+
+/*****************************************************************************
+ * 256KB NOR Flash on BOOT Device
+ ****************************************************************************/
+
+static struct physmap_flash_data tsp2_nor_flash_data = {
+	.width    = 1,
+};
+
+static struct resource tsp2_nor_flash_resource = {
+	.flags = IORESOURCE_MEM,
+	.start = TSP2_NOR_BOOT_BASE,
+	.end   = TSP2_NOR_BOOT_BASE + TSP2_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device tsp2_nor_flash = {
+	.name          = "physmap-flash",
+	.id            = 0,
+	.dev           = {
+		.platform_data	= &tsp2_nor_flash_data,
+	},
+	.num_resources = 1,
+	.resource      = &tsp2_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+#define TSP2_PCI_SLOT0_OFFS		7
+#define TSP2_PCI_SLOT0_IRQ_PIN		11
+
+void __init tsp2_pci_preinit(void)
+{
+	int pin;
+
+	/*
+	 * Configure PCI GPIO IRQ pins
+	 */
+	pin = TSP2_PCI_SLOT0_IRQ_PIN;
+	if (gpio_request(pin, "PCI Int1") == 0) {
+		if (gpio_direction_input(pin) == 0) {
+			set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
+		} else {
+			printk(KERN_ERR "tsp2_pci_preinit failed "
+					"to set_irq_type pin %d\n", pin);
+			gpio_free(pin);
+		}
+	} else {
+		printk(KERN_ERR "tsp2_pci_preinit failed to "
+				"gpio_request %d\n", pin);
+	}
+}
+
+static int __init tsp2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int irq;
+
+	/*
+	 * Check for devices with hard-wired IRQs.
+	 */
+	irq = orion5x_pci_map_irq(dev, slot, pin);
+	if (irq != -1)
+		return irq;
+
+	/*
+	 * PCI IRQs are connected via GPIOs.
+	 */
+	if (slot == TSP2_PCI_SLOT0_OFFS)
+		return gpio_to_irq(TSP2_PCI_SLOT0_IRQ_PIN);
+
+	return -1;
+}
+
+static struct hw_pci tsp2_pci __initdata = {
+	.nr_controllers = 2,
+	.preinit        = tsp2_pci_preinit,
+	.swizzle        = pci_std_swizzle,
+	.setup          = orion5x_pci_sys_setup,
+	.scan           = orion5x_pci_sys_scan_bus,
+	.map_irq        = tsp2_pci_map_irq,
+};
+
+static int __init tsp2_pci_init(void)
+{
+	if (machine_is_terastation_pro2())
+		pci_common_init(&tsp2_pci);
+
+	return 0;
+}
+
+subsys_initcall(tsp2_pci_init);
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data tsp2_eth_data = {
+	.phy_addr	= 0,
+};
+
+/*****************************************************************************
+ * RTC 5C372a on I2C bus
+ ****************************************************************************/
+
+#define TSP2_RTC_GPIO	9
+
+static struct i2c_board_info __initdata tsp2_i2c_rtc = {
+	I2C_BOARD_INFO("rs5c372a", 0x32),
+};
+
+/*****************************************************************************
+ * Terastation Pro II specific power off method via UART1-attached
+ * microcontroller
+ ****************************************************************************/
+
+#define UART1_REG(x)	(UART1_VIRT_BASE + ((UART_##x) << 2))
+
+static int tsp2_miconread(unsigned char *buf, int count)
+{
+	int i;
+	int timeout;
+
+	for (i = 0; i < count; i++) {
+		timeout = 10;
+
+		while (!(readl(UART1_REG(LSR)) & UART_LSR_DR)) {
+			if (--timeout == 0)
+				break;
+			udelay(1000);
+		}
+
+		if (timeout == 0)
+			break;
+		buf[i] = readl(UART1_REG(RX));
+	}
+
+	/* return read bytes */
+	return i;
+}
+
+static int tsp2_miconwrite(const unsigned char *buf, int count)
+{
+	int i = 0;
+
+	while (count--) {
+		while (!(readl(UART1_REG(LSR)) & UART_LSR_THRE))
+			barrier();
+		writel(buf[i++], UART1_REG(TX));
+	}
+
+	return 0;
+}
+
+static int tsp2_miconsend(const unsigned char *data, int count)
+{
+	int i;
+	unsigned char checksum = 0;
+	unsigned char recv_buf[40];
+	unsigned char send_buf[40];
+	unsigned char correct_ack[3];
+	int retry = 2;
+
+	/* Generate checksum */
+	for (i = 0; i < count; i++)
+		checksum -=  data[i];
+
+	do {
+		/* Send data */
+		tsp2_miconwrite(data, count);
+
+		/* send checksum */
+		tsp2_miconwrite(&checksum, 1);
+
+		if (tsp2_miconread(recv_buf, sizeof(recv_buf)) <= 3) {
+			printk(KERN_ERR ">%s: receive failed.\n", __func__);
+
+			/* send preamble to clear the receive buffer */
+			memset(&send_buf, 0xff, sizeof(send_buf));
+			tsp2_miconwrite(send_buf, sizeof(send_buf));
+
+			/* make dummy reads */
+			mdelay(100);
+			tsp2_miconread(recv_buf, sizeof(recv_buf));
+		} else {
+			/* Generate expected ack */
+			correct_ack[0] = 0x01;
+			correct_ack[1] = data[1];
+			correct_ack[2] = 0x00;
+
+			/* checksum Check */
+			if ((recv_buf[0] + recv_buf[1] + recv_buf[2] +
+			     recv_buf[3]) & 0xFF) {
+				printk(KERN_ERR ">%s: Checksum Error : "
+					"Received data[%02x, %02x, %02x, %02x]"
+					"\n", __func__, recv_buf[0],
+					recv_buf[1], recv_buf[2], recv_buf[3]);
+			} else {
+				/* Check Received Data */
+				if (correct_ack[0] == recv_buf[0] &&
+				    correct_ack[1] == recv_buf[1] &&
+				    correct_ack[2] == recv_buf[2]) {
+					/* Interval for next command */
+					mdelay(10);
+
+					/* Receive ACK */
+					return 0;
+				}
+			}
+			/* Received NAK or illegal Data */
+			printk(KERN_ERR ">%s: Error : NAK or Illegal Data "
+					"Received\n", __func__);
+		}
+	} while (retry--);
+
+	/* Interval for next command */
+	mdelay(10);
+
+	return -1;
+}
+
+static void tsp2_power_off(void)
+{
+	const unsigned char watchdogkill[]	= {0x01, 0x35, 0x00};
+	const unsigned char shutdownwait[]	= {0x00, 0x0c};
+	const unsigned char poweroff[]		= {0x00, 0x06};
+	/* 38400 baud divisor */
+	const unsigned divisor = ((orion5x_tclk + (8 * 38400)) / (16 * 38400));
+
+	pr_info("%s: triggering power-off...\n", __func__);
+
+	/* hijack uart1 and reset into sane state (38400,8n1,even parity) */
+	writel(0x83, UART1_REG(LCR));
+	writel(divisor & 0xff, UART1_REG(DLL));
+	writel((divisor >> 8) & 0xff, UART1_REG(DLM));
+	writel(0x1b, UART1_REG(LCR));
+	writel(0x00, UART1_REG(IER));
+	writel(0x07, UART1_REG(FCR));
+	writel(0x00, UART1_REG(MCR));
+
+	/* Send the commands to shutdown the Terastation Pro II */
+	tsp2_miconsend(watchdogkill, sizeof(watchdogkill)) ;
+	tsp2_miconsend(shutdownwait, sizeof(shutdownwait)) ;
+	tsp2_miconsend(poweroff, sizeof(poweroff));
+}
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static struct orion5x_mpp_mode tsp2_mpp_modes[] __initdata = {
+	{  0, MPP_PCIE_RST_OUTn },
+	{  1, MPP_UNUSED },
+	{  2, MPP_UNUSED },
+	{  3, MPP_UNUSED },
+	{  4, MPP_NAND },		/* BOOT NAND Flash REn */
+	{  5, MPP_NAND },		/* BOOT NAND Flash WEn */
+	{  6, MPP_NAND },		/* BOOT NAND Flash HREn[0] */
+	{  7, MPP_NAND },		/* BOOT NAND Flash WEn[0] */
+	{  8, MPP_GPIO },		/* MICON int */
+	{  9, MPP_GPIO },		/* RTC int */
+	{ 10, MPP_UNUSED },
+	{ 11, MPP_GPIO },		/* PCI Int A */
+	{ 12, MPP_UNUSED },
+	{ 13, MPP_GPIO },		/* UPS on UART0 enable */
+	{ 14, MPP_GPIO },		/* UPS low battery detection */
+	{ 15, MPP_UNUSED },
+	{ 16, MPP_UART },		/* UART1 RXD */
+	{ 17, MPP_UART },		/* UART1 TXD */
+	{ 18, MPP_UART },		/* UART1 CTSn */
+	{ 19, MPP_UART },		/* UART1 RTSn */
+	{ -1 },
+};
+
+static void __init tsp2_init(void)
+{
+	/*
+	 * Setup basic Orion functions. Need to be called early.
+	 */
+	orion5x_init();
+
+	orion5x_mpp_conf(tsp2_mpp_modes);
+
+	/*
+	 * Configure peripherals.
+	 */
+	orion5x_setup_dev_boot_win(TSP2_NOR_BOOT_BASE,
+				   TSP2_NOR_BOOT_SIZE);
+	platform_device_register(&tsp2_nor_flash);
+
+	orion5x_ehci0_init();
+	orion5x_eth_init(&tsp2_eth_data);
+	orion5x_i2c_init();
+	orion5x_uart0_init();
+	orion5x_uart1_init();
+
+	/* Get RTC IRQ and register the chip */
+	if (gpio_request(TSP2_RTC_GPIO, "rtc") == 0) {
+		if (gpio_direction_input(TSP2_RTC_GPIO) == 0)
+			tsp2_i2c_rtc.irq = gpio_to_irq(TSP2_RTC_GPIO);
+		else
+			gpio_free(TSP2_RTC_GPIO);
+	}
+	if (tsp2_i2c_rtc.irq == 0)
+		pr_warning("tsp2_init: failed to get RTC IRQ\n");
+	i2c_register_board_info(0, &tsp2_i2c_rtc, 1);
+
+	/* register Terastation Pro II specific power-off method */
+	pm_power_off = tsp2_power_off;
+}
+
+MACHINE_START(TERASTATION_PRO2, "Buffalo Terastation Pro II/Live")
+	/* Maintainer:  Sylver Bruneau <sylver.bruneau@googlemail.com> */
+	.phys_io	= ORION5X_REGS_PHYS_BASE,
+	.io_pg_offst	= ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+	.boot_params	= 0x00000100,
+	.init_machine	= tsp2_init,
+	.map_io		= orion5x_map_io,
+	.init_irq	= orion5x_init_irq,
+	.timer		= &orion5x_timer,
+	.fixup		= tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/tsx09-common.c b/arch/arm/mach-orion5x/tsx09-common.c
index 83feac3..5128da1 100644
--- a/arch/arm/mach-orion5x/tsx09-common.c
+++ b/arch/arm/mach-orion5x/tsx09-common.c
@@ -16,6 +16,7 @@
 #include <linux/timex.h>
 #include <linux/serial_reg.h>
 #include "tsx09-common.h"
+#include "common.h"
 
 /*****************************************************************************
  * QNAP TS-x09 specific power off method via UART1-attached PIC
@@ -26,7 +27,7 @@
 void qnap_tsx09_power_off(void)
 {
 	/* 19200 baud divisor */
-	const unsigned divisor = ((ORION5X_TCLK + (8 * 19200)) / (16 * 19200));
+	const unsigned divisor = ((orion5x_tclk + (8 * 19200)) / (16 * 19200));
 
 	pr_info("%s: triggering power-off...\n", __func__);
 
diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c
index 24d036a..898c0e8 100644
--- a/arch/arm/mach-pnx4008/clock.c
+++ b/arch/arm/mach-pnx4008/clock.c
@@ -20,9 +20,9 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 
 #include <mach/clock.h>
 #include "clock.h"
diff --git a/arch/arm/mach-pnx4008/core.c b/arch/arm/mach-pnx4008/core.c
index 3ba46ed..45734bb 100644
--- a/arch/arm/mach-pnx4008/core.c
+++ b/arch/arm/mach-pnx4008/core.c
@@ -25,9 +25,9 @@
 #include <linux/serial_8250.h>
 #include <linux/device.h>
 #include <linux/spi/spi.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/pgtable.h>
diff --git a/arch/arm/mach-pnx4008/dma.c b/arch/arm/mach-pnx4008/dma.c
index 833c56be..ac2f70e 100644
--- a/arch/arm/mach-pnx4008/dma.c
+++ b/arch/arm/mach-pnx4008/dma.c
@@ -21,12 +21,12 @@
 #include <linux/err.h>
 #include <linux/dma-mapping.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
 #include <asm/system.h>
 #include <mach/hardware.h>
 #include <asm/dma.h>
 #include <asm/dma-mapping.h>
-#include <asm/io.h>
 #include <asm/mach/dma.h>
 #include <mach/clock.h>
 
diff --git a/arch/arm/mach-pnx4008/gpio.c b/arch/arm/mach-pnx4008/gpio.c
index fb51f72..015cc21 100644
--- a/arch/arm/mach-pnx4008/gpio.c
+++ b/arch/arm/mach-pnx4008/gpio.c
@@ -17,7 +17,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <mach/platform.h>
 #include <mach/gpio.h>
 
diff --git a/arch/arm/mach-pnx4008/include/mach/system.h b/arch/arm/mach-pnx4008/include/mach/system.h
index 8985a4622..e12e7ab 100644
--- a/arch/arm/mach-pnx4008/include/mach/system.h
+++ b/arch/arm/mach-pnx4008/include/mach/system.h
@@ -21,8 +21,8 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <mach/platform.h>
 
 static void arch_idle(void)
diff --git a/arch/arm/mach-pnx4008/include/mach/timex.h b/arch/arm/mach-pnx4008/include/mach/timex.h
index 956fbd8e..5ff0196 100644
--- a/arch/arm/mach-pnx4008/include/mach/timex.h
+++ b/arch/arm/mach-pnx4008/include/mach/timex.h
@@ -14,8 +14,8 @@
 #ifndef __PNX4008_TIMEX_H
 #define __PNX4008_TIMEX_H
 
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 
 #define CLOCK_TICK_RATE		1000000
 
diff --git a/arch/arm/mach-pnx4008/irq.c b/arch/arm/mach-pnx4008/irq.c
index 5c4f55a..a9ce02b 100644
--- a/arch/arm/mach-pnx4008/irq.c
+++ b/arch/arm/mach-pnx4008/irq.c
@@ -23,8 +23,8 @@
 #include <linux/ioport.h>
 #include <linux/device.h>
 #include <linux/irq.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/setup.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
diff --git a/arch/arm/mach-pnx4008/pm.c b/arch/arm/mach-pnx4008/pm.c
index f970906d..b3d8d53 100644
--- a/arch/arm/mach-pnx4008/pm.c
+++ b/arch/arm/mach-pnx4008/pm.c
@@ -18,8 +18,8 @@
 #include <linux/suspend.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/cacheflush.h>
 #include <mach/pm.h>
 #include <mach/clock.h>
diff --git a/arch/arm/mach-pnx4008/serial.c b/arch/arm/mach-pnx4008/serial.c
index 9be84bb..f40961e 100644
--- a/arch/arm/mach-pnx4008/serial.c
+++ b/arch/arm/mach-pnx4008/serial.c
@@ -12,8 +12,7 @@
 
 #include <linux/kernel.h>
 #include <linux/types.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include <mach/platform.h>
 #include <mach/hardware.h>
diff --git a/arch/arm/mach-pnx4008/time.c b/arch/arm/mach-pnx4008/time.c
index 1809752..fc0ba18 100644
--- a/arch/arm/mach-pnx4008/time.c
+++ b/arch/arm/mach-pnx4008/time.c
@@ -22,10 +22,10 @@
 #include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/irq.h>
+#include <linux/io.h>
 
 #include <asm/system.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/leds.h>
 #include <asm/mach/time.h>
 #include <asm/errno.h>
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index e8ee7ec..f27f6b3 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -38,16 +38,23 @@
 	bool "Intel DBPXA250 Development Platform"
 	select PXA25x
 	select SA1111
+	select PXA_HAVE_BOARD_IRQS
 
 config MACH_LOGICPD_PXA270
 	bool "LogicPD PXA270 Card Engine Development Platform"
 	select PXA27x
 	select HAVE_PWM
+	select PXA_HAVE_BOARD_IRQS
 
 config MACH_MAINSTONE
 	bool "Intel HCDDBBVA0 Development Platform"
 	select PXA27x
 	select HAVE_PWM
+	select PXA_HAVE_BOARD_IRQS
+
+config MACH_MP900C
+	bool "Nec Mobilepro 900/c"
+	select PXA25x
 
 config ARCH_PXA_IDP
 	bool "Accelent Xscale IDP"
@@ -114,10 +121,21 @@
 	bool "Enable Sharp SL-6000x (Tosa) Support"
 	depends on PXA_SHARPSL
 	select PXA25x
+	select PXA_HAVE_BOARD_IRQS
+
+config ARCH_VIPER
+	bool "Arcom/Eurotech VIPER SBC"
+	select PXA25x
+	select ISA
+	select I2C_GPIO
+	select HAVE_PWM
+	select PXA_HAVE_BOARD_IRQS
+	select PXA_HAVE_ISA_IRQS
 
 config ARCH_PXA_ESERIES
 	bool "PXA based Toshiba e-series PDAs"
 	select PXA25x
+	select PXA_HAVE_BOARD_IRQS
 
 config MACH_E330
 	bool "Toshiba e330"
@@ -170,13 +188,41 @@
 	  Say Y here if you intend to run this kernel on a Toshiba
 	  e800 family PDA.
 
+config TRIZEPS_PXA
+	bool "PXA based Keith und Koep Trizeps DIMM-Modules"
+
 config MACH_TRIZEPS4
 	bool "Keith und Koep Trizeps4 DIMM-Module"
+	depends on TRIZEPS_PXA
+	select TRIZEPS_PCMCIA
 	select PXA27x
 
-config MACH_TRIZEPS4_CONXS
+config MACH_TRIZEPS4WL
+	bool "Keith und Koep Trizeps4-WL DIMM-Module"
+	depends on TRIZEPS_PXA
+	select TRIZEPS_PCMCIA
+	select PXA27x
+	select PXA_SSP
+
+choice
+	prompt "Select base board for Trizeps module"
+	depends on TRIZEPS_PXA
+
+config MACH_TRIZEPS_CONXS
 	bool "ConXS Eval Board"
-	depends on MACH_TRIZEPS4
+
+config MACH_TRIZEPS_UCONXS
+	bool "uConXS Eval Board"
+
+config MACH_TRIZEPS_ANY
+	bool "another Board"
+
+endchoice
+
+config TRIZEPS_PCMCIA
+	bool
+	help
+	  Enable PCMCIA support for Trizeps modules
 
 config MACH_EM_X270
 	bool "CompuLab EM-x270 platform"
@@ -189,6 +235,7 @@
 config MACH_ZYLONITE
 	bool "PXA3xx Development Platform (aka Zylonite)"
 	select PXA3xx
+	select PXA_SSP
 	select HAVE_PWM
 
 config MACH_LITTLETON
@@ -207,20 +254,42 @@
 	select PXA930
 
 config MACH_ARMCORE
-	bool "CompuLab CM-X270 modules"
+	bool "CompuLab CM-X255/CM-X270 modules"
 	select PXA27x
 	select IWMMXT
+	select ZONE_DMA if PCI
+	select PXA25x
+	select PXA_SSP
+
+config MACH_CM_X300
+	bool "CompuLab CM-X300 modules"
+	select PXA3xx
+	select CPU_PXA300
 
 config MACH_MAGICIAN
 	bool "Enable HTC Magician Support"
 	select PXA27x
 	select IWMMXT
+	select PXA_HAVE_BOARD_IRQS
+
+config MACH_MIOA701
+	bool "Mitac Mio A701 Support"
+	select PXA27x
+	select IWMMXT
+	select LEDS_GPIO
+	select HAVE_PWM
+	select GPIO_SYSFS
+	help
+	  Say Y here if you intend to run this kernel on a
+	  MIO A701. Currently there is only basic support
+	  for this PDA.
 
 config MACH_PCM027
 	bool "Phytec phyCORE-PXA270 CPU module (PCM-027)"
 	select PXA27x
 	select IWMMXT
 	select PXA_SSP
+	select PXA_HAVE_BOARD_IRQS
 
 config ARCH_PXA_PALM
 	bool "PXA based Palm PDAs"
@@ -236,6 +305,16 @@
 	  Say Y here if you intend to run this kernel on a Palm T|X
 	  handheld computer.
 
+config MACH_PALMZ72
+	bool "Palm Zire 72"
+	default y
+	depends on ARCH_PXA_PALM
+	select PXA27x
+	select IWMMXT
+	help
+	  Say Y here if you intend to run this kernel on Palm Zire 72
+	  handheld computer.
+
 config MACH_PCM990_BASEBOARD
 	bool "PHYTEC PCM-990 development board"
 	select HAVE_PWM
@@ -256,6 +335,9 @@
 
 endchoice
 
+config MACH_AM200EPD
+	depends on MACH_GUMSTIX_F
+	bool "Enable AM200EPD board support"
 
 config PXA_EZX
 	bool "Motorola EZX Platform"
@@ -343,4 +425,10 @@
 	  This is a simple driver that is able to control
 	  the state of built in bluetooth chip on tosa.
 
+config PXA_HAVE_BOARD_IRQS
+	bool
+
+config PXA_HAVE_ISA_IRQS
+	bool
+
 endif
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 99ecbe7..d31c997 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -6,7 +6,12 @@
 obj-y				+= clock.o devices.o generic.o irq.o dma.o \
 				   time.o gpio.o reset.o
 obj-$(CONFIG_PM)		+= pm.o sleep.o standby.o
-obj-$(CONFIG_CPU_FREQ)		+= cpu-pxa.o
+
+ifeq ($(CONFIG_CPU_FREQ),y)
+obj-$(CONFIG_PXA25x)		+= cpufreq-pxa2xx.o
+obj-$(CONFIG_PXA27x)		+= cpufreq-pxa2xx.o
+obj-$(CONFIG_PXA3xx)		+= cpufreq-pxa3xx.o
+endif
 
 # Generic drivers that other drivers may depend upon
 obj-$(CONFIG_PXA_SSP)		+= ssp.o
@@ -22,27 +27,33 @@
 
 # Specific board support
 obj-$(CONFIG_ARCH_GUMSTIX)	+= gumstix.o
+obj-$(CONFIG_MACH_AM200EPD)	+= am200epd.o
 obj-$(CONFIG_ARCH_LUBBOCK)	+= lubbock.o
 obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o
 obj-$(CONFIG_MACH_MAINSTONE)	+= mainstone.o
+obj-$(CONFIG_MACH_MP900C)	+= mp900.o
 obj-$(CONFIG_ARCH_PXA_IDP)	+= idp.o
 obj-$(CONFIG_MACH_TRIZEPS4)	+= trizeps4.o
 obj-$(CONFIG_MACH_COLIBRI)	+= colibri.o
-obj-$(CONFIG_PXA_SHARP_C7xx)	+= corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o
-obj-$(CONFIG_PXA_SHARP_Cxx00)	+= spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o
-obj-$(CONFIG_MACH_AKITA)	+= akita-ioexp.o
-obj-$(CONFIG_MACH_POODLE)	+= poodle.o corgi_ssp.o
+obj-$(CONFIG_PXA_SHARP_C7xx)	+= corgi.o sharpsl_pm.o corgi_pm.o
+obj-$(CONFIG_PXA_SHARP_Cxx00)	+= spitz.o sharpsl_pm.o spitz_pm.o
+obj-$(CONFIG_MACH_POODLE)	+= poodle.o
 obj-$(CONFIG_MACH_PCM027)	+= pcm027.o
 obj-$(CONFIG_MACH_PCM990_BASEBOARD)	+= pcm990-baseboard.o
 obj-$(CONFIG_MACH_TOSA)		+= tosa.o
 obj-$(CONFIG_MACH_EM_X270)	+= em-x270.o
 obj-$(CONFIG_MACH_MAGICIAN)	+= magician.o
-obj-$(CONFIG_ARCH_PXA_ESERIES)	+= eseries.o eseries_udc.o
-obj-$(CONFIG_MACH_E740)		+= e740_lcd.o
-obj-$(CONFIG_MACH_E750)		+= e750_lcd.o
-obj-$(CONFIG_MACH_E400)		+= e400_lcd.o
-obj-$(CONFIG_MACH_E800)		+= e800_lcd.o
+obj-$(CONFIG_MACH_MIOA701)	+= mioa701.o mioa701_bootresume.o
+obj-$(CONFIG_ARCH_PXA_ESERIES)	+= eseries.o
+obj-$(CONFIG_MACH_E330)		+= e330.o
+obj-$(CONFIG_MACH_E350)		+= e350.o
+obj-$(CONFIG_MACH_E740)		+= e740.o
+obj-$(CONFIG_MACH_E750)		+= e750.o
+obj-$(CONFIG_MACH_E400)		+= e400.o
+obj-$(CONFIG_MACH_E800)		+= e800.o
 obj-$(CONFIG_MACH_PALMTX)	+= palmtx.o
+obj-$(CONFIG_MACH_PALMZ72)	+= palmz72.o
+obj-$(CONFIG_ARCH_VIPER)	+= viper.o
 
 ifeq ($(CONFIG_MACH_ZYLONITE),y)
   obj-y				+= zylonite.o
@@ -53,7 +64,8 @@
 obj-$(CONFIG_MACH_TAVOREVB)	+= tavorevb.o
 obj-$(CONFIG_MACH_SAAR)		+= saar.o
 
-obj-$(CONFIG_MACH_ARMCORE)      += cm-x270.o
+obj-$(CONFIG_MACH_ARMCORE)      += cm-x2xx.o cm-x255.o cm-x270.o
+obj-$(CONFIG_MACH_CM_X300)      += cm-x300.o
 obj-$(CONFIG_PXA_EZX)           += ezx.o
 
 # Support for blinky lights
@@ -61,12 +73,11 @@
 led-$(CONFIG_ARCH_LUBBOCK)	+= leds-lubbock.o
 led-$(CONFIG_MACH_MAINSTONE)	+= leds-mainstone.o
 led-$(CONFIG_ARCH_PXA_IDP)	+= leds-idp.o
-led-$(CONFIG_MACH_TRIZEPS4)	+= leds-trizeps4.o
 
 obj-$(CONFIG_LEDS)		+= $(led-y)
 
 ifeq ($(CONFIG_PCI),y)
-obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o
+obj-$(CONFIG_MACH_ARMCORE) += cm-x2xx-pci.o
 endif
 
 obj-$(CONFIG_TOSA_BT)		+= tosa-bt.o
diff --git a/arch/arm/mach-pxa/akita-ioexp.c b/arch/arm/mach-pxa/akita-ioexp.c
deleted file mode 100644
index 5c67b18..0000000
--- a/arch/arm/mach-pxa/akita-ioexp.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Support for the Extra GPIOs on the Sharp SL-C1000 (Akita)
- * (uses a Maxim MAX7310 8 Port IO Expander)
- *
- * Copyright 2005 Openedhand Ltd.
- *
- * Author: Richard Purdie <richard@openedhand.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <mach/akita.h>
-
-/* MAX7310 Regiser Map */
-#define MAX7310_INPUT    0x00
-#define MAX7310_OUTPUT   0x01
-#define MAX7310_POLINV   0x02
-#define MAX7310_IODIR    0x03 /* 1 = Input, 0 = Output */
-#define MAX7310_TIMEOUT  0x04
-
-/* Addresses to scan */
-static const unsigned short normal_i2c[] = { 0x18, I2C_CLIENT_END };
-
-/* I2C Magic */
-I2C_CLIENT_INSMOD;
-
-static int max7310_write(struct i2c_client *client, int address, int data);
-static struct i2c_client max7310_template;
-static void akita_ioexp_work(struct work_struct *private_);
-
-static struct device *akita_ioexp_device;
-static unsigned char ioexp_output_value = AKITA_IOEXP_IO_OUT;
-DECLARE_WORK(akita_ioexp, akita_ioexp_work);
-
-
-/*
- * MAX7310 Access
- */
-static int max7310_config(struct device *dev, int iomode, int polarity)
-{
-	int ret;
-	struct i2c_client *client = to_i2c_client(dev);
-
-	ret = max7310_write(client, MAX7310_POLINV, polarity);
-	if (ret < 0)
-		return ret;
-	ret = max7310_write(client, MAX7310_IODIR, iomode);
-	return ret;
-}
-
-static int max7310_set_ouputs(struct device *dev, int outputs)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-
-	return max7310_write(client, MAX7310_OUTPUT, outputs);
-}
-
-/*
- * I2C Functions
- */
-static int max7310_write(struct i2c_client *client, int address, int value)
-{
-	u8 data[2];
-
-	data[0] = address & 0xff;
-	data[1] = value & 0xff;
-
-	if (i2c_master_send(client, data, 2) == 2)
-		return 0;
-	return -1;
-}
-
-static int max7310_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	struct i2c_client *new_client;
-	int err;
-
-	if (!(new_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL)))
-		return -ENOMEM;
-
-	max7310_template.adapter = adapter;
-	max7310_template.addr = address;
-
-	memcpy(new_client, &max7310_template, sizeof(struct i2c_client));
-
-	if ((err = i2c_attach_client(new_client))) {
-		kfree(new_client);
-		return err;
-	}
-
-	max7310_config(&new_client->dev, AKITA_IOEXP_IO_DIR, 0);
-	akita_ioexp_device = &new_client->dev;
-	schedule_work(&akita_ioexp);
-
-	return 0;
-}
-
-static int max7310_attach_adapter(struct i2c_adapter *adapter)
-{
-	return i2c_probe(adapter, &addr_data, max7310_detect);
-}
-
-static int max7310_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	akita_ioexp_device = NULL;
-
-	if ((err = i2c_detach_client(client)))
-		return err;
-
-	kfree(client);
-	return 0;
-}
-
-static struct i2c_driver max7310_i2c_driver = {
-	.driver = {
-		.name	= "akita-max7310",
-	},
-	.id		= I2C_DRIVERID_AKITAIOEXP,
-	.attach_adapter	= max7310_attach_adapter,
-	.detach_client	= max7310_detach_client,
-};
-
-static struct i2c_client max7310_template = {
-	name:   "akita-max7310",
-	driver: &max7310_i2c_driver,
-};
-
-void akita_set_ioexp(struct device *dev, unsigned char bit)
-{
-	ioexp_output_value |= bit;
-
-	if (akita_ioexp_device)
-		schedule_work(&akita_ioexp);
-	return;
-}
-
-void akita_reset_ioexp(struct device *dev, unsigned char bit)
-{
-	ioexp_output_value &= ~bit;
-
-	if (akita_ioexp_device)
-		schedule_work(&akita_ioexp);
-	return;
-}
-
-EXPORT_SYMBOL(akita_set_ioexp);
-EXPORT_SYMBOL(akita_reset_ioexp);
-
-static void akita_ioexp_work(struct work_struct *private_)
-{
-	if (akita_ioexp_device)
-		max7310_set_ouputs(akita_ioexp_device, ioexp_output_value);
-}
-
-
-#ifdef CONFIG_PM
-static int akita_ioexp_suspend(struct platform_device *pdev, pm_message_t state)
-{
-	flush_scheduled_work();
-	return 0;
-}
-
-static int akita_ioexp_resume(struct platform_device *pdev)
-{
-	schedule_work(&akita_ioexp);
-	return 0;
-}
-#else
-#define akita_ioexp_suspend NULL
-#define akita_ioexp_resume NULL
-#endif
-
-static int __init akita_ioexp_probe(struct platform_device *pdev)
-{
-	return i2c_add_driver(&max7310_i2c_driver);
-}
-
-static int akita_ioexp_remove(struct platform_device *pdev)
-{
-	i2c_del_driver(&max7310_i2c_driver);
-	return 0;
-}
-
-static struct platform_driver akita_ioexp_driver = {
-	.probe		= akita_ioexp_probe,
-	.remove		= akita_ioexp_remove,
-	.suspend	= akita_ioexp_suspend,
-	.resume		= akita_ioexp_resume,
-	.driver		= {
-		.name	= "akita-ioexp",
-	},
-};
-
-static int __init akita_ioexp_init(void)
-{
-	return platform_driver_register(&akita_ioexp_driver);
-}
-
-static void __exit akita_ioexp_exit(void)
-{
-	platform_driver_unregister(&akita_ioexp_driver);
-}
-
-MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
-MODULE_DESCRIPTION("Akita IO-Expander driver");
-MODULE_LICENSE("GPL");
-
-fs_initcall(akita_ioexp_init);
-module_exit(akita_ioexp_exit);
-
diff --git a/arch/arm/mach-pxa/am200epd.c b/arch/arm/mach-pxa/am200epd.c
new file mode 100644
index 0000000..b965085
--- /dev/null
+++ b/arch/arm/mach-pxa/am200epd.c
@@ -0,0 +1,374 @@
+/*
+ * am200epd.c -- Platform device for AM200 EPD kit
+ *
+ * Copyright (C) 2008, Jaya Kumar
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven.
+ *
+ * This work was made possible by help and equipment support from E-Ink
+ * Corporation. http://support.eink.com/community
+ *
+ * This driver is written to be used with the Metronome display controller.
+ * on the AM200 EPD prototype kit/development kit with an E-Ink 800x600
+ * Vizplex EPD on a Gumstix board using the Lyre interface board.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+
+#include <mach/pxafb.h>
+
+#include <video/metronomefb.h>
+
+static unsigned int panel_type = 6;
+static struct platform_device *am200_device;
+static struct metronome_board am200_board;
+
+static struct pxafb_mode_info am200_fb_mode_9inch7 = {
+	.pixclock	= 40000,
+	.xres		= 1200,
+	.yres		= 842,
+	.bpp		= 16,
+	.hsync_len	= 2,
+	.left_margin	= 2,
+	.right_margin	= 2,
+	.vsync_len	= 1,
+	.upper_margin	= 2,
+	.lower_margin	= 25,
+	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mode_info am200_fb_mode_8inch = {
+	.pixclock	= 40000,
+	.xres		= 1088,
+	.yres		= 791,
+	.bpp		= 16,
+	.hsync_len	= 28,
+	.left_margin	= 8,
+	.right_margin	= 30,
+	.vsync_len	= 8,
+	.upper_margin	= 10,
+	.lower_margin	= 8,
+	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mode_info am200_fb_mode_6inch = {
+	.pixclock	= 40189,
+	.xres		= 832,
+	.yres		= 622,
+	.bpp		= 16,
+	.hsync_len	= 28,
+	.left_margin	= 34,
+	.right_margin	= 34,
+	.vsync_len	= 25,
+	.upper_margin	= 0,
+	.lower_margin	= 2,
+	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info am200_fb_info = {
+	.modes		= &am200_fb_mode_6inch,
+	.num_modes	= 1,
+	.lcd_conn	= LCD_TYPE_COLOR_TFT | LCD_PCLK_EDGE_FALL |
+			  LCD_AC_BIAS_FREQ(24),
+};
+
+/* register offsets for gpio control */
+#define LED_GPIO_PIN 51
+#define STDBY_GPIO_PIN 48
+#define RST_GPIO_PIN 49
+#define RDY_GPIO_PIN 32
+#define ERR_GPIO_PIN 17
+#define PCBPWR_GPIO_PIN 16
+static int gpios[] = { LED_GPIO_PIN , STDBY_GPIO_PIN , RST_GPIO_PIN,
+			RDY_GPIO_PIN, ERR_GPIO_PIN, PCBPWR_GPIO_PIN };
+static char *gpio_names[] = { "LED" , "STDBY" , "RST", "RDY", "ERR", "PCBPWR" };
+
+static int am200_init_gpio_regs(struct metronomefb_par *par)
+{
+	int i;
+	int err;
+
+	for (i = 0; i < ARRAY_SIZE(gpios); i++) {
+		err = gpio_request(gpios[i], gpio_names[i]);
+		if (err) {
+			dev_err(&am200_device->dev, "failed requesting "
+				"gpio %s, err=%d\n", gpio_names[i], err);
+			goto err_req_gpio;
+		}
+	}
+
+	gpio_direction_output(LED_GPIO_PIN, 0);
+	gpio_direction_output(STDBY_GPIO_PIN, 0);
+	gpio_direction_output(RST_GPIO_PIN, 0);
+
+	gpio_direction_input(RDY_GPIO_PIN);
+	gpio_direction_input(ERR_GPIO_PIN);
+
+	gpio_direction_output(PCBPWR_GPIO_PIN, 0);
+
+	return 0;
+
+err_req_gpio:
+	while (i > 0)
+		gpio_free(gpios[i--]);
+
+	return err;
+}
+
+static void am200_cleanup(struct metronomefb_par *par)
+{
+	int i;
+
+	free_irq(IRQ_GPIO(RDY_GPIO_PIN), par);
+
+	for (i = 0; i < ARRAY_SIZE(gpios); i++)
+		gpio_free(gpios[i]);
+}
+
+static int am200_share_video_mem(struct fb_info *info)
+{
+	/* rough check if this is our desired fb and not something else */
+	if ((info->var.xres != am200_fb_info.modes->xres)
+		|| (info->var.yres != am200_fb_info.modes->yres))
+		return 0;
+
+	/* we've now been notified that we have our new fb */
+	am200_board.metromem = info->screen_base;
+	am200_board.host_fbinfo = info;
+
+	/* try to refcount host drv since we are the consumer after this */
+	if (!try_module_get(info->fbops->owner))
+		return -ENODEV;
+
+	return 0;
+}
+
+static int am200_unshare_video_mem(struct fb_info *info)
+{
+	dev_dbg(&am200_device->dev, "ENTER %s\n", __func__);
+
+	if (info != am200_board.host_fbinfo)
+		return 0;
+
+	module_put(am200_board.host_fbinfo->fbops->owner);
+	return 0;
+}
+
+static int am200_fb_notifier_callback(struct notifier_block *self,
+				 unsigned long event, void *data)
+{
+	struct fb_event *evdata = data;
+	struct fb_info *info = evdata->info;
+
+	dev_dbg(&am200_device->dev, "ENTER %s\n", __func__);
+
+	if (event == FB_EVENT_FB_REGISTERED)
+		return am200_share_video_mem(info);
+	else if (event == FB_EVENT_FB_UNREGISTERED)
+		return am200_unshare_video_mem(info);
+
+	return 0;
+}
+
+static struct notifier_block am200_fb_notif = {
+	.notifier_call = am200_fb_notifier_callback,
+};
+
+/* this gets called as part of our init. these steps must be done now so
+ * that we can use set_pxa_fb_info */
+static void __init am200_presetup_fb(void)
+{
+	int fw;
+	int fh;
+	int padding_size;
+	int totalsize;
+
+	switch (panel_type) {
+	case 6:
+		am200_fb_info.modes = &am200_fb_mode_6inch;
+		break;
+	case 8:
+		am200_fb_info.modes = &am200_fb_mode_8inch;
+		break;
+	case 97:
+		am200_fb_info.modes = &am200_fb_mode_9inch7;
+		break;
+	default:
+		dev_err(&am200_device->dev, "invalid panel_type selection,"
+						" setting to 6\n");
+		am200_fb_info.modes = &am200_fb_mode_6inch;
+		break;
+	}
+
+	/* the frame buffer is divided as follows:
+	command | CRC | padding
+	16kb waveform data | CRC | padding
+	image data | CRC
+	*/
+
+	fw = am200_fb_info.modes->xres;
+	fh = am200_fb_info.modes->yres;
+
+	/* waveform must be 16k + 2 for checksum */
+	am200_board.wfm_size = roundup(16*1024 + 2, fw);
+
+	padding_size = PAGE_SIZE + (4 * fw);
+
+	/* total is 1 cmd , 1 wfm, padding and image */
+	totalsize = fw + am200_board.wfm_size + padding_size + (fw*fh);
+
+	/* save this off because we're manipulating fw after this and
+	 * we'll need it when we're ready to setup the framebuffer */
+	am200_board.fw = fw;
+	am200_board.fh = fh;
+
+	/* the reason we do this adjustment is because we want to acquire
+	 * more framebuffer memory without imposing custom awareness on the
+	 * underlying pxafb driver */
+	am200_fb_info.modes->yres = DIV_ROUND_UP(totalsize, fw);
+
+	/* we divide since we told the LCD controller we're 16bpp */
+	am200_fb_info.modes->xres /= 2;
+
+	set_pxa_fb_info(&am200_fb_info);
+
+}
+
+/* this gets called by metronomefb as part of its init, in our case, we
+ * have already completed initial framebuffer init in presetup_fb so we
+ * can just setup the fb access pointers */
+static int am200_setup_fb(struct metronomefb_par *par)
+{
+	int fw;
+	int fh;
+
+	fw = am200_board.fw;
+	fh = am200_board.fh;
+
+	/* metromem was set up by the notifier in share_video_mem so now
+	 * we can use its value to calculate the other entries */
+	par->metromem_cmd = (struct metromem_cmd *) am200_board.metromem;
+	par->metromem_wfm = am200_board.metromem + fw;
+	par->metromem_img = par->metromem_wfm + am200_board.wfm_size;
+	par->metromem_img_csum = (u16 *) (par->metromem_img + (fw * fh));
+	par->metromem_dma = am200_board.host_fbinfo->fix.smem_start;
+
+	return 0;
+}
+
+static int am200_get_panel_type(void)
+{
+	return panel_type;
+}
+
+static irqreturn_t am200_handle_irq(int irq, void *dev_id)
+{
+	struct metronomefb_par *par = dev_id;
+
+	wake_up_interruptible(&par->waitq);
+	return IRQ_HANDLED;
+}
+
+static int am200_setup_irq(struct fb_info *info)
+{
+	int ret;
+
+	ret = request_irq(IRQ_GPIO(RDY_GPIO_PIN), am200_handle_irq,
+				IRQF_DISABLED|IRQF_TRIGGER_FALLING,
+				"AM200", info->par);
+	if (ret)
+		dev_err(&am200_device->dev, "request_irq failed: %d\n", ret);
+
+	return ret;
+}
+
+static void am200_set_rst(struct metronomefb_par *par, int state)
+{
+	gpio_set_value(RST_GPIO_PIN, state);
+}
+
+static void am200_set_stdby(struct metronomefb_par *par, int state)
+{
+	gpio_set_value(STDBY_GPIO_PIN, state);
+}
+
+static int am200_wait_event(struct metronomefb_par *par)
+{
+	return wait_event_timeout(par->waitq, gpio_get_value(RDY_GPIO_PIN), HZ);
+}
+
+static int am200_wait_event_intr(struct metronomefb_par *par)
+{
+	return wait_event_interruptible_timeout(par->waitq,
+					gpio_get_value(RDY_GPIO_PIN), HZ);
+}
+
+static struct metronome_board am200_board = {
+	.owner			= THIS_MODULE,
+	.setup_irq		= am200_setup_irq,
+	.setup_io		= am200_init_gpio_regs,
+	.setup_fb		= am200_setup_fb,
+	.set_rst		= am200_set_rst,
+	.set_stdby		= am200_set_stdby,
+	.met_wait_event		= am200_wait_event,
+	.met_wait_event_intr	= am200_wait_event_intr,
+	.get_panel_type		= am200_get_panel_type,
+	.cleanup		= am200_cleanup,
+};
+
+static int __init am200_init(void)
+{
+	int ret;
+
+	/* before anything else, we request notification for any fb
+	 * creation events */
+	fb_register_client(&am200_fb_notif);
+
+	/* request our platform independent driver */
+	request_module("metronomefb");
+
+	am200_device = platform_device_alloc("metronomefb", -1);
+	if (!am200_device)
+		return -ENOMEM;
+
+	/* the am200_board that will be seen by metronomefb is a copy */
+	platform_device_add_data(am200_device, &am200_board,
+					sizeof(am200_board));
+
+	/* this _add binds metronomefb to am200. metronomefb refcounts am200 */
+	ret = platform_device_add(am200_device);
+
+	if (ret) {
+		platform_device_put(am200_device);
+		fb_unregister_client(&am200_fb_notif);
+		return ret;
+	}
+
+	am200_presetup_fb();
+
+	return 0;
+}
+
+module_param(panel_type, uint, 0);
+MODULE_PARM_DESC(panel_type, "Select the panel type: 6, 8, 97");
+
+module_init(am200_init);
+
+MODULE_DESCRIPTION("board driver for am200 metronome epd kit");
+MODULE_AUTHOR("Jaya Kumar");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-pxa/cm-x255.c b/arch/arm/mach-pxa/cm-x255.c
new file mode 100644
index 0000000..83a4cdf
--- /dev/null
+++ b/arch/arm/mach-pxa/cm-x255.c
@@ -0,0 +1,258 @@
+/*
+ * linux/arch/arm/mach-pxa/cm-x255.c
+ *
+ * Copyright (C) 2007, 2008 CompuLab, Ltd.
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand-gpio.h>
+
+#include <linux/spi/spi.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa2xx-regs.h>
+#include <mach/mfp-pxa25x.h>
+#include <mach/pxa2xx_spi.h>
+#include <mach/bitfield.h>
+
+#include "generic.h"
+
+#define GPIO_NAND_CS	(5)
+#define GPIO_NAND_ALE	(4)
+#define GPIO_NAND_CLE	(3)
+#define GPIO_NAND_RB	(10)
+
+static unsigned long cmx255_pin_config[] = {
+	/* AC'97 */
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
+
+	/* BTUART */
+	GPIO42_BTUART_RXD,
+	GPIO43_BTUART_TXD,
+	GPIO44_BTUART_CTS,
+	GPIO45_BTUART_RTS,
+
+	/* STUART */
+	GPIO46_STUART_RXD,
+	GPIO47_STUART_TXD,
+
+	/* LCD */
+	GPIO58_LCD_LDD_0,
+	GPIO59_LCD_LDD_1,
+	GPIO60_LCD_LDD_2,
+	GPIO61_LCD_LDD_3,
+	GPIO62_LCD_LDD_4,
+	GPIO63_LCD_LDD_5,
+	GPIO64_LCD_LDD_6,
+	GPIO65_LCD_LDD_7,
+	GPIO66_LCD_LDD_8,
+	GPIO67_LCD_LDD_9,
+	GPIO68_LCD_LDD_10,
+	GPIO69_LCD_LDD_11,
+	GPIO70_LCD_LDD_12,
+	GPIO71_LCD_LDD_13,
+	GPIO72_LCD_LDD_14,
+	GPIO73_LCD_LDD_15,
+	GPIO74_LCD_FCLK,
+	GPIO75_LCD_LCLK,
+	GPIO76_LCD_PCLK,
+	GPIO77_LCD_BIAS,
+
+	/* SSP1 */
+	GPIO23_SSP1_SCLK,
+	GPIO24_SSP1_SFRM,
+	GPIO25_SSP1_TXD,
+	GPIO26_SSP1_RXD,
+
+	/* SSP2 */
+	GPIO81_SSP2_CLK_OUT,
+	GPIO82_SSP2_FRM_OUT,
+	GPIO83_SSP2_TXD,
+	GPIO84_SSP2_RXD,
+
+	/* PC Card */
+	GPIO48_nPOE,
+	GPIO49_nPWE,
+	GPIO50_nPIOR,
+	GPIO51_nPIOW,
+	GPIO52_nPCE_1,
+	GPIO53_nPCE_2,
+	GPIO54_nPSKTSEL,
+	GPIO55_nPREG,
+	GPIO56_nPWAIT,
+	GPIO57_nIOIS16,
+
+	/* SDRAM and local bus */
+	GPIO15_nCS_1,
+	GPIO78_nCS_2,
+	GPIO79_nCS_3,
+	GPIO80_nCS_4,
+	GPIO33_nCS_5,
+	GPIO18_RDY,
+
+	/* GPIO */
+	GPIO0_GPIO	| WAKEUP_ON_EDGE_BOTH,
+	GPIO9_GPIO,				/* PC card reset */
+
+	/* NAND controls */
+	GPIO5_GPIO	| MFP_LPM_DRIVE_HIGH,	/* NAND CE# */
+	GPIO4_GPIO	| MFP_LPM_DRIVE_LOW,	/* NAND ALE */
+	GPIO3_GPIO	| MFP_LPM_DRIVE_LOW,	/* NAND CLE */
+	GPIO10_GPIO,				/* NAND Ready/Busy */
+
+	/* interrupts */
+	GPIO22_GPIO,	/* DM9000 interrupt */
+};
+
+#if defined(CONFIG_SPI_PXA2XX)
+static struct pxa2xx_spi_master pxa_ssp_master_info = {
+	.num_chipselect	= 1,
+};
+
+static struct spi_board_info spi_board_info[] __initdata = {
+	[0] = {
+		.modalias	= "rtc-max6902",
+		.max_speed_hz	= 1000000,
+		.bus_num	= 1,
+		.chip_select	= 0,
+	},
+};
+
+static void __init cmx255_init_rtc(void)
+{
+	pxa2xx_set_spi_info(1, &pxa_ssp_master_info);
+	spi_register_board_info(ARRAY_AND_SIZE(spi_board_info));
+}
+#else
+static inline void cmx255_init_rtc(void) {}
+#endif
+
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition cmx255_nor_partitions[] = {
+	{
+		.name		= "ARMmon",
+		.size		= 0x00030000,
+		.offset		= 0,
+		.mask_flags	= MTD_WRITEABLE  /* force read-only */
+	} , {
+		.name		= "ARMmon setup block",
+		.size		= 0x00010000,
+		.offset		= MTDPART_OFS_APPEND,
+		.mask_flags	= MTD_WRITEABLE  /* force read-only */
+	} , {
+		.name		= "kernel",
+		.size		= 0x00160000,
+		.offset		= MTDPART_OFS_APPEND,
+	} , {
+		.name		= "ramdisk",
+		.size		= MTDPART_SIZ_FULL,
+		.offset		= MTDPART_OFS_APPEND
+	}
+};
+
+static struct physmap_flash_data cmx255_nor_flash_data[] = {
+	{
+		.width		= 2,	/* bankwidth in bytes */
+		.parts		= cmx255_nor_partitions,
+		.nr_parts	= ARRAY_SIZE(cmx255_nor_partitions)
+	}
+};
+
+static struct resource cmx255_nor_resource = {
+	.start	= PXA_CS0_PHYS,
+	.end	= PXA_CS0_PHYS + SZ_8M - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device cmx255_nor = {
+	.name	= "physmap-flash",
+	.id	= -1,
+	.dev	= {
+		.platform_data = cmx255_nor_flash_data,
+	},
+	.resource = &cmx255_nor_resource,
+	.num_resources = 1,
+};
+
+static void __init cmx255_init_nor(void)
+{
+	platform_device_register(&cmx255_nor);
+}
+#else
+static inline void cmx255_init_nor(void) {}
+#endif
+
+#if defined(CONFIG_MTD_NAND_GPIO) || defined(CONFIG_MTD_NAND_GPIO_MODULE)
+static struct resource cmx255_nand_resource[] = {
+	[0] = {
+		.start = PXA_CS1_PHYS,
+		.end   = PXA_CS1_PHYS + 11,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = PXA_CS5_PHYS,
+		.end   = PXA_CS5_PHYS + 3,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static struct mtd_partition cmx255_nand_parts[] = {
+	[0] = {
+		.name	= "cmx255-nand",
+		.size	= MTDPART_SIZ_FULL,
+		.offset	= 0,
+	},
+};
+
+static struct gpio_nand_platdata cmx255_nand_platdata = {
+	.gpio_nce = GPIO_NAND_CS,
+	.gpio_cle = GPIO_NAND_CLE,
+	.gpio_ale = GPIO_NAND_ALE,
+	.gpio_rdy = GPIO_NAND_RB,
+	.gpio_nwp = -1,
+	.parts = cmx255_nand_parts,
+	.num_parts = ARRAY_SIZE(cmx255_nand_parts),
+	.chip_delay = 25,
+};
+
+static struct platform_device cmx255_nand = {
+	.name		= "gpio-nand",
+	.num_resources	= ARRAY_SIZE(cmx255_nand_resource),
+	.resource	= cmx255_nand_resource,
+	.id		= -1,
+	.dev		= {
+		.platform_data = &cmx255_nand_platdata,
+	}
+};
+
+static void __init cmx255_init_nand(void)
+{
+	platform_device_register(&cmx255_nand);
+}
+#else
+static inline void cmx255_init_nand(void) {}
+#endif
+
+void __init cmx255_init(void)
+{
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx255_pin_config));
+
+	cmx255_init_rtc();
+	cmx255_init_nor();
+	cmx255_init_nand();
+}
diff --git a/arch/arm/mach-pxa/cm-x270-pci.h b/arch/arm/mach-pxa/cm-x270-pci.h
deleted file mode 100644
index 48f532f..0000000
--- a/arch/arm/mach-pxa/cm-x270-pci.h
+++ /dev/null
@@ -1,13 +0,0 @@
-extern void __cmx270_pci_init_irq(int irq_gpio);
-extern void __cmx270_pci_suspend(void);
-extern void __cmx270_pci_resume(void);
-
-#ifdef CONFIG_PCI
-#define cmx270_pci_init_irq(x) __cmx270_pci_init_irq(x)
-#define cmx270_pci_suspend(x) __cmx270_pci_suspend(x)
-#define cmx270_pci_resume(x) __cmx270_pci_resume(x)
-#else
-#define cmx270_pci_init_irq(x) do {} while (0)
-#define cmx270_pci_suspend(x) do {} while (0)
-#define cmx270_pci_resume(x) do {} while (0)
-#endif
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c
index af003a2..a82dad1 100644
--- a/arch/arm/mach-pxa/cm-x270.c
+++ b/arch/arm/mach-pxa/cm-x270.c
@@ -14,46 +14,22 @@
 #include <linux/irq.h>
 #include <linux/gpio.h>
 
-#include <linux/dm9000.h>
 #include <linux/rtc-v3020.h>
 #include <video/mbxfb.h>
-#include <linux/leds.h>
 
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-#include <asm/mach/map.h>
-
-#include <mach/pxa2xx-regs.h>
 #include <mach/mfp-pxa27x.h>
-#include <mach/pxa-regs.h>
-#include <mach/audio.h>
-#include <mach/pxafb.h>
 #include <mach/ohci.h>
 #include <mach/mmc.h>
-#include <mach/bitfield.h>
-
-#include <asm/hardware/it8152.h>
 
 #include "generic.h"
-#include "cm-x270-pci.h"
 
-/* virtual addresses for statically mapped regions */
-#define CMX270_VIRT_BASE	(0xe8000000)
-#define CMX270_IT8152_VIRT	(CMX270_VIRT_BASE)
-
+/* physical address if local-bus attached devices */
 #define RTC_PHYS_BASE		(PXA_CS1_PHYS + (5 << 22))
-#define DM9000_PHYS_BASE	(PXA_CS1_PHYS + (6 << 22))
 
 /* GPIO IRQ usage */
-#define GPIO10_ETHIRQ		(10)
-#define GPIO22_IT8152_IRQ	(22)
 #define GPIO83_MMC_IRQ		(83)
-#define GPIO95_GFXIRQ		(95)
 
-#define CMX270_ETHIRQ		IRQ_GPIO(GPIO10_ETHIRQ)
-#define CMX270_IT8152_IRQ	IRQ_GPIO(GPIO22_IT8152_IRQ)
 #define CMX270_MMC_IRQ		IRQ_GPIO(GPIO83_MMC_IRQ)
-#define CMX270_GFXIRQ		IRQ_GPIO(GPIO95_GFXIRQ)
 
 /* MMC power enable */
 #define GPIO105_MMC_POWER	(105)
@@ -157,62 +133,6 @@
 	GPIO83_GPIO,	/* MMC card detect */
 };
 
-#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
-static struct resource cmx270_dm9000_resource[] = {
-	[0] = {
-		.start = DM9000_PHYS_BASE,
-		.end   = DM9000_PHYS_BASE + 4,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = DM9000_PHYS_BASE + 8,
-		.end   = DM9000_PHYS_BASE + 8 + 500,
-		.flags = IORESOURCE_MEM,
-	},
-	[2] = {
-		.start = CMX270_ETHIRQ,
-		.end   = CMX270_ETHIRQ,
-		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
-	}
-};
-
-static struct dm9000_plat_data cmx270_dm9000_platdata = {
-	.flags		= DM9000_PLATF_32BITONLY,
-};
-
-static struct platform_device cmx270_dm9000_device = {
-	.name		= "dm9000",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(cmx270_dm9000_resource),
-	.resource	= cmx270_dm9000_resource,
-	.dev		= {
-		.platform_data = &cmx270_dm9000_platdata,
-	}
-};
-
-static void __init cmx270_init_dm9000(void)
-{
-	platform_device_register(&cmx270_dm9000_device);
-}
-#else
-static inline void cmx270_init_dm9000(void) {}
-#endif
-
-/* UCB1400 touchscreen controller */
-#if defined(CONFIG_TOUCHSCREEN_UCB1400) || defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
-static struct platform_device cmx270_ts_device = {
-	.name		= "ucb1400_ts",
-	.id		= -1,
-};
-
-static void __init cmx270_init_touchscreen(void)
-{
-	platform_device_register(&cmx270_ts_device);
-}
-#else
-static inline void cmx270_init_touchscreen(void) {}
-#endif
-
 /* V3020 RTC */
 #if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE)
 static struct resource cmx270_v3020_resource[] = {
@@ -242,45 +162,7 @@
 	platform_device_register(&cmx270_rtc_device);
 }
 #else
-static inline void cmx270_init_rtc(void) {}
-#endif
-
-/* CM-X270 LEDs */
-#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
-static struct gpio_led cmx270_leds[] = {
-	[0] = {
-		.name = "cm-x270:red",
-		.default_trigger = "nand-disk",
-		.gpio = 93,
-		.active_low = 1,
-	},
-	[1] = {
-		.name = "cm-x270:green",
-		.default_trigger = "heartbeat",
-		.gpio = 94,
-		.active_low = 1,
-	},
-};
-
-static struct gpio_led_platform_data cmx270_gpio_led_pdata = {
-	.num_leds = ARRAY_SIZE(cmx270_leds),
-	.leds = cmx270_leds,
-};
-
-static struct platform_device cmx270_led_device = {
-	.name		= "leds-gpio",
-	.id		= -1,
-	.dev		= {
-		.platform_data = &cmx270_gpio_led_pdata,
-	},
-};
-
-static void __init cmx270_init_leds(void)
-{
-	platform_device_register(&cmx270_led_device);
-}
-#else
-static inline void cmx270_init_leds(void) {}
+static inline void cmx2xx_init_rtc(void) {}
 #endif
 
 /* 2700G graphics */
@@ -373,238 +255,11 @@
 static inline void cmx270_init_2700G(void) {}
 #endif
 
-#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
-/*
-  Display definitions
-  keep these for backwards compatibility, although symbolic names (as
-  e.g. in lpd270.c) looks better
-*/
-#define MTYPE_STN320x240	0
-#define MTYPE_TFT640x480	1
-#define MTYPE_CRT640x480	2
-#define MTYPE_CRT800x600	3
-#define MTYPE_TFT320x240	6
-#define MTYPE_STN640x480	7
-
-static struct pxafb_mode_info generic_stn_320x240_mode = {
-	.pixclock	= 76923,
-	.bpp		= 8,
-	.xres		= 320,
-	.yres		= 240,
-	.hsync_len	= 3,
-	.vsync_len	= 2,
-	.left_margin	= 3,
-	.upper_margin	= 0,
-	.right_margin	= 3,
-	.lower_margin	= 0,
-	.sync		= (FB_SYNC_HOR_HIGH_ACT |
-			   FB_SYNC_VERT_HIGH_ACT),
-	.cmap_greyscale = 0,
-};
-
-static struct pxafb_mach_info generic_stn_320x240 = {
-	.modes		= &generic_stn_320x240_mode,
-	.num_modes	= 1,
-	.lccr0		= 0,
-	.lccr3		= (LCCR3_PixClkDiv(0x03) |
-			   LCCR3_Acb(0xff) |
-			   LCCR3_PCP),
-	.cmap_inverse	= 0,
-	.cmap_static	= 0,
-};
-
-static struct pxafb_mode_info generic_tft_640x480_mode = {
-	.pixclock	= 38461,
-	.bpp		= 8,
-	.xres		= 640,
-	.yres		= 480,
-	.hsync_len	= 60,
-	.vsync_len	= 2,
-	.left_margin	= 70,
-	.upper_margin	= 10,
-	.right_margin	= 70,
-	.lower_margin	= 5,
-	.sync		= 0,
-	.cmap_greyscale = 0,
-};
-
-static struct pxafb_mach_info generic_tft_640x480 = {
-	.modes		= &generic_tft_640x480_mode,
-	.num_modes	= 1,
-	.lccr0		= (LCCR0_PAS),
-	.lccr3		= (LCCR3_PixClkDiv(0x01) |
-			   LCCR3_Acb(0xff) |
-			   LCCR3_PCP),
-	.cmap_inverse	= 0,
-	.cmap_static	= 0,
-};
-
-static struct pxafb_mode_info generic_crt_640x480_mode = {
-	.pixclock	= 38461,
-	.bpp		= 8,
-	.xres		= 640,
-	.yres		= 480,
-	.hsync_len	= 63,
-	.vsync_len	= 2,
-	.left_margin	= 81,
-	.upper_margin	= 33,
-	.right_margin	= 16,
-	.lower_margin	= 10,
-	.sync		= (FB_SYNC_HOR_HIGH_ACT |
-			   FB_SYNC_VERT_HIGH_ACT),
-	.cmap_greyscale = 0,
-};
-
-static struct pxafb_mach_info generic_crt_640x480 = {
-	.modes		= &generic_crt_640x480_mode,
-	.num_modes	= 1,
-	.lccr0		= (LCCR0_PAS),
-	.lccr3		= (LCCR3_PixClkDiv(0x01) |
-			   LCCR3_Acb(0xff)),
-	.cmap_inverse	= 0,
-	.cmap_static	= 0,
-};
-
-static struct pxafb_mode_info generic_crt_800x600_mode = {
-	.pixclock	= 28846,
-	.bpp		= 8,
-	.xres		= 800,
-	.yres	  	= 600,
-	.hsync_len	= 63,
-	.vsync_len	= 2,
-	.left_margin	= 26,
-	.upper_margin	= 21,
-	.right_margin	= 26,
-	.lower_margin	= 11,
-	.sync		= (FB_SYNC_HOR_HIGH_ACT |
-			   FB_SYNC_VERT_HIGH_ACT),
-	.cmap_greyscale = 0,
-};
-
-static struct pxafb_mach_info generic_crt_800x600 = {
-	.modes		= &generic_crt_800x600_mode,
-	.num_modes	= 1,
-	.lccr0		= (LCCR0_PAS),
-	.lccr3		= (LCCR3_PixClkDiv(0x02) |
-			   LCCR3_Acb(0xff)),
-	.cmap_inverse	= 0,
-	.cmap_static	= 0,
-};
-
-static struct pxafb_mode_info generic_tft_320x240_mode = {
-	.pixclock	= 134615,
-	.bpp		= 16,
-	.xres		= 320,
-	.yres		= 240,
-	.hsync_len	= 63,
-	.vsync_len	= 7,
-	.left_margin	= 75,
-	.upper_margin	= 0,
-	.right_margin	= 15,
-	.lower_margin	= 15,
-	.sync		= 0,
-	.cmap_greyscale = 0,
-};
-
-static struct pxafb_mach_info generic_tft_320x240 = {
-	.modes		= &generic_tft_320x240_mode,
-	.num_modes	= 1,
-	.lccr0		= (LCCR0_PAS),
-	.lccr3		= (LCCR3_PixClkDiv(0x06) |
-			   LCCR3_Acb(0xff) |
-			   LCCR3_PCP),
-	.cmap_inverse	= 0,
-	.cmap_static	= 0,
-};
-
-static struct pxafb_mode_info generic_stn_640x480_mode = {
-	.pixclock	= 57692,
-	.bpp		= 8,
-	.xres		= 640,
-	.yres		= 480,
-	.hsync_len	= 4,
-	.vsync_len	= 2,
-	.left_margin	= 10,
-	.upper_margin	= 5,
-	.right_margin	= 10,
-	.lower_margin	= 5,
-	.sync		= (FB_SYNC_HOR_HIGH_ACT |
-			   FB_SYNC_VERT_HIGH_ACT),
-	.cmap_greyscale = 0,
-};
-
-static struct pxafb_mach_info generic_stn_640x480 = {
-	.modes		= &generic_stn_640x480_mode,
-	.num_modes	= 1,
-	.lccr0		= 0,
-	.lccr3		= (LCCR3_PixClkDiv(0x02) |
-			   LCCR3_Acb(0xff)),
-	.cmap_inverse	= 0,
-	.cmap_static	= 0,
-};
-
-static struct pxafb_mach_info *cmx270_display = &generic_crt_640x480;
-
-static int __init cmx270_set_display(char *str)
-{
-	int disp_type = simple_strtol(str, NULL, 0);
-	switch (disp_type) {
-	case MTYPE_STN320x240:
-		cmx270_display = &generic_stn_320x240;
-		break;
-	case MTYPE_TFT640x480:
-		cmx270_display = &generic_tft_640x480;
-		break;
-	case MTYPE_CRT640x480:
-		cmx270_display = &generic_crt_640x480;
-		break;
-	case MTYPE_CRT800x600:
-		cmx270_display = &generic_crt_800x600;
-		break;
-	case MTYPE_TFT320x240:
-		cmx270_display = &generic_tft_320x240;
-		break;
-	case MTYPE_STN640x480:
-		cmx270_display = &generic_stn_640x480;
-		break;
-	default: /* fallback to CRT 640x480 */
-		cmx270_display = &generic_crt_640x480;
-		break;
-	}
-	return 1;
-}
-
-/*
-   This should be done really early to get proper configuration for
-   frame buffer.
-   Indeed, pxafb parameters can be used istead, but CM-X270 bootloader
-   has limitied line length for kernel command line, and also it will
-   break compatibitlty with proprietary releases already in field.
-*/
-__setup("monitor=", cmx270_set_display);
-
-static void __init cmx270_init_display(void)
-{
-	set_pxa_fb_info(cmx270_display);
-}
-#else
-static inline void cmx270_init_display(void) {}
-#endif
-
 /* PXA27x OHCI controller setup */
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-static int cmx270_ohci_init(struct device *dev)
-{
-	/* Set the Power Control Polarity Low */
-	UHCHR = (UHCHR | UHCHR_PCPL) &
-		~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE);
-
-	return 0;
-}
-
 static struct pxaohci_platform_data cmx270_ohci_platform_data = {
 	.port_mode	= PMM_PERPORT_MODE,
-	.init		= cmx270_ohci_init,
+	.flags		= ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
 };
 
 static void __init cmx270_init_ohci(void)
@@ -676,131 +331,12 @@
 static inline void cmx270_init_mmc(void) {}
 #endif
 
-#ifdef CONFIG_PM
-static unsigned long sleep_save_msc[10];
-
-static int cmx270_suspend(struct sys_device *dev, pm_message_t state)
+void __init cmx270_init(void)
 {
-	cmx270_pci_suspend();
-
-	/* save MSC registers */
-	sleep_save_msc[0] = MSC0;
-	sleep_save_msc[1] = MSC1;
-	sleep_save_msc[2] = MSC2;
-
-	/* setup power saving mode registers */
-	PCFR = 0x0;
-	PSLR = 0xff400000;
-	PMCR  = 0x00000005;
-	PWER  = 0x80000000;
-	PFER  = 0x00000000;
-	PRER  = 0x00000000;
-	PGSR0 = 0xC0018800;
-	PGSR1 = 0x004F0002;
-	PGSR2 = 0x6021C000;
-	PGSR3 = 0x00020000;
-
-	return 0;
-}
-
-static int cmx270_resume(struct sys_device *dev)
-{
-	cmx270_pci_resume();
-
-	/* restore MSC registers */
-	MSC0 = sleep_save_msc[0];
-	MSC1 = sleep_save_msc[1];
-	MSC2 = sleep_save_msc[2];
-
-	return 0;
-}
-
-static struct sysdev_class cmx270_pm_sysclass = {
-	.name = "pm",
-	.resume = cmx270_resume,
-	.suspend = cmx270_suspend,
-};
-
-static struct sys_device cmx270_pm_device = {
-	.cls = &cmx270_pm_sysclass,
-};
-
-static int __init cmx270_pm_init(void)
-{
-	int error;
-	error = sysdev_class_register(&cmx270_pm_sysclass);
-	if (error == 0)
-		error = sysdev_register(&cmx270_pm_device);
-	return error;
-}
-#else
-static int __init cmx270_pm_init(void) { return 0; }
-#endif
-
-#if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE)
-static void __init cmx270_init_ac97(void)
-{
-	pxa_set_ac97_info(NULL);
-}
-#else
-static inline void cmx270_init_ac97(void) {}
-#endif
-
-static void __init cmx270_init(void)
-{
-	cmx270_pm_init();
-
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_pin_config));
 
-	cmx270_init_dm9000();
 	cmx270_init_rtc();
-	cmx270_init_display();
 	cmx270_init_mmc();
 	cmx270_init_ohci();
-	cmx270_init_ac97();
-	cmx270_init_touchscreen();
-	cmx270_init_leds();
 	cmx270_init_2700G();
 }
-
-static void __init cmx270_init_irq(void)
-{
-	pxa27x_init_irq();
-
-	cmx270_pci_init_irq(GPIO22_IT8152_IRQ);
-}
-
-#ifdef CONFIG_PCI
-/* Map PCI companion statically */
-static struct map_desc cmx270_io_desc[] __initdata = {
-	[0] = { /* PCI bridge */
-		.virtual	= CMX270_IT8152_VIRT,
-		.pfn		= __phys_to_pfn(PXA_CS4_PHYS),
-		.length		= SZ_64M,
-		.type		= MT_DEVICE
-	},
-};
-
-static void __init cmx270_map_io(void)
-{
-	pxa_map_io();
-	iotable_init(cmx270_io_desc, ARRAY_SIZE(cmx270_io_desc));
-
-	it8152_base_address = CMX270_IT8152_VIRT;
-}
-#else
-static void __init cmx270_map_io(void)
-{
-	pxa_map_io();
-}
-#endif
-
-MACHINE_START(ARMCORE, "Compulab CM-x270")
-	.boot_params	= 0xa0000100,
-	.phys_io	= 0x40000000,
-	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
-	.map_io		= cmx270_map_io,
-	.init_irq	= cmx270_init_irq,
-	.timer		= &pxa_timer,
-	.init_machine	= cmx270_init,
-MACHINE_END
diff --git a/arch/arm/mach-pxa/cm-x270-pci.c b/arch/arm/mach-pxa/cm-x2xx-pci.c
similarity index 77%
rename from arch/arm/mach-pxa/cm-x270-pci.c
rename to arch/arm/mach-pxa/cm-x2xx-pci.c
index 2d5bcea..3156b25 100644
--- a/arch/arm/mach-pxa/cm-x270-pci.c
+++ b/arch/arm/mach-pxa/cm-x2xx-pci.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-pxa/cm-x270-pci.c
+ * linux/arch/arm/mach-pxa/cm-x2xx-pci.c
  *
  * PCI bios-type initialisation for PCI machines
  *
@@ -28,7 +28,7 @@
 #include <asm/hardware/it8152.h>
 
 unsigned long it8152_base_address;
-static int cmx270_it8152_irq_gpio;
+static int cmx2xx_it8152_irq_gpio;
 
 /*
  * Only first 64MB of memory can be accessed via PCI.
@@ -36,13 +36,13 @@
  * This is really ugly and we need a better way of specifying
  * DMA-capable regions of memory.
  */
-void __init cmx270_pci_adjust_zones(int node, unsigned long *zone_size,
+void __init cmx2xx_pci_adjust_zones(int node, unsigned long *zone_size,
 	unsigned long *zhole_size)
 {
 	unsigned int sz = SZ_64M >> PAGE_SHIFT;
 
 	if (machine_is_armcore()) {
-		pr_info("Adjusting zones for CM-X270\n");
+		pr_info("Adjusting zones for CM-X2XX\n");
 
 		/*
 		 * Only adjust if > 64M on current system
@@ -57,29 +57,29 @@
 	}
 }
 
-static void cmx270_it8152_irq_demux(unsigned int irq, struct irq_desc *desc)
+static void cmx2xx_it8152_irq_demux(unsigned int irq, struct irq_desc *desc)
 {
 	/* clear our parent irq */
-	GEDR(cmx270_it8152_irq_gpio) = GPIO_bit(cmx270_it8152_irq_gpio);
+	GEDR(cmx2xx_it8152_irq_gpio) = GPIO_bit(cmx2xx_it8152_irq_gpio);
 
 	it8152_irq_demux(irq, desc);
 }
 
-void __cmx270_pci_init_irq(int irq_gpio)
+void __cmx2xx_pci_init_irq(int irq_gpio)
 {
 	it8152_init_irq();
 
-	cmx270_it8152_irq_gpio = irq_gpio;
+	cmx2xx_it8152_irq_gpio = irq_gpio;
 
 	set_irq_type(gpio_to_irq(irq_gpio), IRQ_TYPE_EDGE_RISING);
 
-	set_irq_chained_handler(gpio_to_irq(irq_gpio), cmx270_it8152_irq_demux);
+	set_irq_chained_handler(gpio_to_irq(irq_gpio), cmx2xx_it8152_irq_demux);
 }
 
 #ifdef CONFIG_PM
 static unsigned long sleep_save_ite[10];
 
-void __cmx270_pci_suspend(void)
+void __cmx2xx_pci_suspend(void)
 {
 	/* save ITE state */
 	sleep_save_ite[0] = __raw_readl(IT8152_INTC_PDCNIMR);
@@ -91,7 +91,7 @@
 	__raw_writel((0), IT8152_INTC_LPCNIRR);
 }
 
-void __cmx270_pci_resume(void)
+void __cmx2xx_pci_resume(void)
 {
 	/* restore IT8152 state */
 	__raw_writel((sleep_save_ite[0]), IT8152_INTC_PDCNIMR);
@@ -99,12 +99,12 @@
 	__raw_writel((sleep_save_ite[2]), IT8152_INTC_LPNIAR);
 }
 #else
-void cmx270_pci_suspend(void) {}
-void cmx270_pci_resume(void) {}
+void cmx2xx_pci_suspend(void) {}
+void cmx2xx_pci_resume(void) {}
 #endif
 
 /* PCI IRQ mapping*/
-static int __init cmx270_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+static int __init cmx2xx_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
 	int irq;
 
@@ -116,14 +116,14 @@
 
 	/*
 	  Here comes the ugly part. The routing is baseboard specific,
-	  but defining a platform for each possible base of CM-X270 is
-	  unrealistic. Here we keep mapping for ATXBase and SB-X270.
+	  but defining a platform for each possible base of CM-X2XX is
+	  unrealistic. Here we keep mapping for ATXBase and SB-X2XX.
 	*/
 	/* ATXBASE PCI slot */
 	if (slot == 7)
 		return IT8152_PCI_INTA;
 
-	/* ATXBase/SB-x270 CardBus */
+	/* ATXBase/SB-X2XX CardBus */
 	if (slot == 8 || slot == 0)
 		return IT8152_PCI_INTB;
 
@@ -131,7 +131,11 @@
 	if (slot == 9)
 		return IT8152_PCI_INTA;
 
-	/* SB-x270 Ethernet */
+	/* CM-x255 Onboard Ethernet */
+	if (slot == 15)
+		return IT8152_PCI_INTC;
+
+	/* SB-x2xx Ethernet */
 	if (slot == 16)
 		return IT8152_PCI_INTA;
 
@@ -144,9 +148,9 @@
 	return(0);
 }
 
-static void cmx270_pci_preinit(void)
+static void cmx2xx_pci_preinit(void)
 {
-	pr_info("Initializing CM-X270 PCI subsystem\n");
+	pr_info("Initializing CM-X2XX PCI subsystem\n");
 
 	__raw_writel(0x800, IT8152_PCI_CFG_ADDR);
 	if (__raw_readl(IT8152_PCI_CFG_DATA) == 0x81521283) {
@@ -200,21 +204,21 @@
 	}
 }
 
-static struct hw_pci cmx270_pci __initdata = {
+static struct hw_pci cmx2xx_pci __initdata = {
 	.swizzle	= pci_std_swizzle,
-	.map_irq	= cmx270_pci_map_irq,
+	.map_irq	= cmx2xx_pci_map_irq,
 	.nr_controllers	= 1,
 	.setup		= it8152_pci_setup,
 	.scan		= it8152_pci_scan_bus,
-	.preinit	= cmx270_pci_preinit,
+	.preinit	= cmx2xx_pci_preinit,
 };
 
-static int __init cmx270_init_pci(void)
+static int __init cmx2xx_init_pci(void)
 {
 	if (machine_is_armcore())
-		pci_common_init(&cmx270_pci);
+		pci_common_init(&cmx2xx_pci);
 
 	return 0;
 }
 
-subsys_initcall(cmx270_init_pci);
+subsys_initcall(cmx2xx_init_pci);
diff --git a/arch/arm/mach-pxa/cm-x2xx-pci.h b/arch/arm/mach-pxa/cm-x2xx-pci.h
new file mode 100644
index 0000000..e24aad2
--- /dev/null
+++ b/arch/arm/mach-pxa/cm-x2xx-pci.h
@@ -0,0 +1,13 @@
+extern void __cmx2xx_pci_init_irq(int irq_gpio);
+extern void __cmx2xx_pci_suspend(void);
+extern void __cmx2xx_pci_resume(void);
+
+#ifdef CONFIG_PCI
+#define cmx2xx_pci_init_irq(x) __cmx2xx_pci_init_irq(x)
+#define cmx2xx_pci_suspend(x) __cmx2xx_pci_suspend(x)
+#define cmx2xx_pci_resume(x) __cmx2xx_pci_resume(x)
+#else
+#define cmx2xx_pci_init_irq(x) do {} while (0)
+#define cmx2xx_pci_suspend(x) do {} while (0)
+#define cmx2xx_pci_resume(x) do {} while (0)
+#endif
diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c
new file mode 100644
index 0000000..0b3ce3b
--- /dev/null
+++ b/arch/arm/mach-pxa/cm-x2xx.c
@@ -0,0 +1,531 @@
+/*
+ * linux/arch/arm/mach-pxa/cm-x2xx.c
+ *
+ * Copyright (C) 2008 CompuLab, Ltd.
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+
+#include <linux/dm9000.h>
+#include <linux/leds.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa2xx-regs.h>
+#include <mach/mfp-pxa27x.h>
+#include <mach/pxa-regs.h>
+#include <mach/audio.h>
+#include <mach/pxafb.h>
+
+#include <asm/hardware/it8152.h>
+
+#include "generic.h"
+#include "cm-x2xx-pci.h"
+
+extern void cmx255_init(void);
+extern void cmx270_init(void);
+
+/* virtual addresses for statically mapped regions */
+#define CMX2XX_VIRT_BASE	(0xe8000000)
+#define CMX2XX_IT8152_VIRT	(CMX2XX_VIRT_BASE)
+
+/* physical address if local-bus attached devices */
+#define CMX255_DM9000_PHYS_BASE (PXA_CS1_PHYS + (8 << 22))
+#define CMX270_DM9000_PHYS_BASE	(PXA_CS1_PHYS + (6 << 22))
+
+/* leds */
+#define CMX255_GPIO_RED		(27)
+#define CMX255_GPIO_GREEN	(32)
+#define CMX270_GPIO_RED		(93)
+#define CMX270_GPIO_GREEN	(94)
+
+/* GPIO IRQ usage */
+#define GPIO22_ETHIRQ		(22)
+#define GPIO10_ETHIRQ		(10)
+#define CMX255_GPIO_IT8152_IRQ	(0)
+#define CMX270_GPIO_IT8152_IRQ	(22)
+
+#define CMX255_ETHIRQ		IRQ_GPIO(GPIO22_ETHIRQ)
+#define CMX270_ETHIRQ		IRQ_GPIO(GPIO10_ETHIRQ)
+
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+static struct resource cmx255_dm9000_resource[] = {
+	[0] = {
+		.start = CMX255_DM9000_PHYS_BASE,
+		.end   = CMX255_DM9000_PHYS_BASE + 3,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = CMX255_DM9000_PHYS_BASE + 4,
+		.end   = CMX255_DM9000_PHYS_BASE + 4 + 500,
+		.flags = IORESOURCE_MEM,
+	},
+	[2] = {
+		.start = CMX255_ETHIRQ,
+		.end   = CMX255_ETHIRQ,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+	}
+};
+
+static struct resource cmx270_dm9000_resource[] = {
+	[0] = {
+		.start = CMX270_DM9000_PHYS_BASE,
+		.end   = CMX270_DM9000_PHYS_BASE + 3,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = CMX270_DM9000_PHYS_BASE + 8,
+		.end   = CMX270_DM9000_PHYS_BASE + 8 + 500,
+		.flags = IORESOURCE_MEM,
+	},
+	[2] = {
+		.start = CMX270_ETHIRQ,
+		.end   = CMX270_ETHIRQ,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+	}
+};
+
+static struct dm9000_plat_data cmx270_dm9000_platdata = {
+	.flags		= DM9000_PLATF_32BITONLY,
+};
+
+static struct platform_device cmx2xx_dm9000_device = {
+	.name		= "dm9000",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(cmx270_dm9000_resource),
+	.dev		= {
+		.platform_data = &cmx270_dm9000_platdata,
+	}
+};
+
+static void __init cmx2xx_init_dm9000(void)
+{
+	if (cpu_is_pxa25x())
+		cmx2xx_dm9000_device.resource = cmx255_dm9000_resource;
+	else
+		cmx2xx_dm9000_device.resource = cmx270_dm9000_resource;
+	platform_device_register(&cmx2xx_dm9000_device);
+}
+#else
+static inline void cmx2xx_init_dm9000(void) {}
+#endif
+
+/* UCB1400 touchscreen controller */
+#if defined(CONFIG_TOUCHSCREEN_UCB1400) || defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
+static struct platform_device cmx2xx_ts_device = {
+	.name		= "ucb1400_ts",
+	.id		= -1,
+};
+
+static void __init cmx2xx_init_touchscreen(void)
+{
+	platform_device_register(&cmx2xx_ts_device);
+}
+#else
+static inline void cmx2xx_init_touchscreen(void) {}
+#endif
+
+/* CM-X270 LEDs */
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+static struct gpio_led cmx2xx_leds[] = {
+	[0] = {
+		.name = "cm-x2xx:red",
+		.default_trigger = "nand-disk",
+		.active_low = 1,
+	},
+	[1] = {
+		.name = "cm-x2xx:green",
+		.default_trigger = "heartbeat",
+		.active_low = 1,
+	},
+};
+
+static struct gpio_led_platform_data cmx2xx_gpio_led_pdata = {
+	.num_leds = ARRAY_SIZE(cmx2xx_leds),
+	.leds = cmx2xx_leds,
+};
+
+static struct platform_device cmx2xx_led_device = {
+	.name		= "leds-gpio",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &cmx2xx_gpio_led_pdata,
+	},
+};
+
+static void __init cmx2xx_init_leds(void)
+{
+	if (cpu_is_pxa25x()) {
+		cmx2xx_leds[0].gpio = CMX255_GPIO_RED;
+		cmx2xx_leds[1].gpio = CMX255_GPIO_GREEN;
+	} else {
+		cmx2xx_leds[0].gpio = CMX270_GPIO_RED;
+		cmx2xx_leds[1].gpio = CMX270_GPIO_GREEN;
+	}
+	platform_device_register(&cmx2xx_led_device);
+}
+#else
+static inline void cmx2xx_init_leds(void) {}
+#endif
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+/*
+  Display definitions
+  keep these for backwards compatibility, although symbolic names (as
+  e.g. in lpd270.c) looks better
+*/
+#define MTYPE_STN320x240	0
+#define MTYPE_TFT640x480	1
+#define MTYPE_CRT640x480	2
+#define MTYPE_CRT800x600	3
+#define MTYPE_TFT320x240	6
+#define MTYPE_STN640x480	7
+
+static struct pxafb_mode_info generic_stn_320x240_mode = {
+	.pixclock	= 76923,
+	.bpp		= 8,
+	.xres		= 320,
+	.yres		= 240,
+	.hsync_len	= 3,
+	.vsync_len	= 2,
+	.left_margin	= 3,
+	.upper_margin	= 0,
+	.right_margin	= 3,
+	.lower_margin	= 0,
+	.sync		= (FB_SYNC_HOR_HIGH_ACT |
+			   FB_SYNC_VERT_HIGH_ACT),
+	.cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info generic_stn_320x240 = {
+	.modes		= &generic_stn_320x240_mode,
+	.num_modes	= 1,
+	.lccr0		= 0,
+	.lccr3		= (LCCR3_PixClkDiv(0x03) |
+			   LCCR3_Acb(0xff) |
+			   LCCR3_PCP),
+	.cmap_inverse	= 0,
+	.cmap_static	= 0,
+};
+
+static struct pxafb_mode_info generic_tft_640x480_mode = {
+	.pixclock	= 38461,
+	.bpp		= 8,
+	.xres		= 640,
+	.yres		= 480,
+	.hsync_len	= 60,
+	.vsync_len	= 2,
+	.left_margin	= 70,
+	.upper_margin	= 10,
+	.right_margin	= 70,
+	.lower_margin	= 5,
+	.sync		= 0,
+	.cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info generic_tft_640x480 = {
+	.modes		= &generic_tft_640x480_mode,
+	.num_modes	= 1,
+	.lccr0		= (LCCR0_PAS),
+	.lccr3		= (LCCR3_PixClkDiv(0x01) |
+			   LCCR3_Acb(0xff) |
+			   LCCR3_PCP),
+	.cmap_inverse	= 0,
+	.cmap_static	= 0,
+};
+
+static struct pxafb_mode_info generic_crt_640x480_mode = {
+	.pixclock	= 38461,
+	.bpp		= 8,
+	.xres		= 640,
+	.yres		= 480,
+	.hsync_len	= 63,
+	.vsync_len	= 2,
+	.left_margin	= 81,
+	.upper_margin	= 33,
+	.right_margin	= 16,
+	.lower_margin	= 10,
+	.sync		= (FB_SYNC_HOR_HIGH_ACT |
+			   FB_SYNC_VERT_HIGH_ACT),
+	.cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info generic_crt_640x480 = {
+	.modes		= &generic_crt_640x480_mode,
+	.num_modes	= 1,
+	.lccr0		= (LCCR0_PAS),
+	.lccr3		= (LCCR3_PixClkDiv(0x01) |
+			   LCCR3_Acb(0xff)),
+	.cmap_inverse	= 0,
+	.cmap_static	= 0,
+};
+
+static struct pxafb_mode_info generic_crt_800x600_mode = {
+	.pixclock	= 28846,
+	.bpp		= 8,
+	.xres		= 800,
+	.yres	  	= 600,
+	.hsync_len	= 63,
+	.vsync_len	= 2,
+	.left_margin	= 26,
+	.upper_margin	= 21,
+	.right_margin	= 26,
+	.lower_margin	= 11,
+	.sync		= (FB_SYNC_HOR_HIGH_ACT |
+			   FB_SYNC_VERT_HIGH_ACT),
+	.cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info generic_crt_800x600 = {
+	.modes		= &generic_crt_800x600_mode,
+	.num_modes	= 1,
+	.lccr0		= (LCCR0_PAS),
+	.lccr3		= (LCCR3_PixClkDiv(0x02) |
+			   LCCR3_Acb(0xff)),
+	.cmap_inverse	= 0,
+	.cmap_static	= 0,
+};
+
+static struct pxafb_mode_info generic_tft_320x240_mode = {
+	.pixclock	= 134615,
+	.bpp		= 16,
+	.xres		= 320,
+	.yres		= 240,
+	.hsync_len	= 63,
+	.vsync_len	= 7,
+	.left_margin	= 75,
+	.upper_margin	= 0,
+	.right_margin	= 15,
+	.lower_margin	= 15,
+	.sync		= 0,
+	.cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info generic_tft_320x240 = {
+	.modes		= &generic_tft_320x240_mode,
+	.num_modes	= 1,
+	.lccr0		= (LCCR0_PAS),
+	.lccr3		= (LCCR3_PixClkDiv(0x06) |
+			   LCCR3_Acb(0xff) |
+			   LCCR3_PCP),
+	.cmap_inverse	= 0,
+	.cmap_static	= 0,
+};
+
+static struct pxafb_mode_info generic_stn_640x480_mode = {
+	.pixclock	= 57692,
+	.bpp		= 8,
+	.xres		= 640,
+	.yres		= 480,
+	.hsync_len	= 4,
+	.vsync_len	= 2,
+	.left_margin	= 10,
+	.upper_margin	= 5,
+	.right_margin	= 10,
+	.lower_margin	= 5,
+	.sync		= (FB_SYNC_HOR_HIGH_ACT |
+			   FB_SYNC_VERT_HIGH_ACT),
+	.cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info generic_stn_640x480 = {
+	.modes		= &generic_stn_640x480_mode,
+	.num_modes	= 1,
+	.lccr0		= 0,
+	.lccr3		= (LCCR3_PixClkDiv(0x02) |
+			   LCCR3_Acb(0xff)),
+	.cmap_inverse	= 0,
+	.cmap_static	= 0,
+};
+
+static struct pxafb_mach_info *cmx2xx_display = &generic_crt_640x480;
+
+static int __init cmx2xx_set_display(char *str)
+{
+	int disp_type = simple_strtol(str, NULL, 0);
+	switch (disp_type) {
+	case MTYPE_STN320x240:
+		cmx2xx_display = &generic_stn_320x240;
+		break;
+	case MTYPE_TFT640x480:
+		cmx2xx_display = &generic_tft_640x480;
+		break;
+	case MTYPE_CRT640x480:
+		cmx2xx_display = &generic_crt_640x480;
+		break;
+	case MTYPE_CRT800x600:
+		cmx2xx_display = &generic_crt_800x600;
+		break;
+	case MTYPE_TFT320x240:
+		cmx2xx_display = &generic_tft_320x240;
+		break;
+	case MTYPE_STN640x480:
+		cmx2xx_display = &generic_stn_640x480;
+		break;
+	default: /* fallback to CRT 640x480 */
+		cmx2xx_display = &generic_crt_640x480;
+		break;
+	}
+	return 1;
+}
+
+/*
+   This should be done really early to get proper configuration for
+   frame buffer.
+   Indeed, pxafb parameters can be used istead, but CM-X2XX bootloader
+   has limitied line length for kernel command line, and also it will
+   break compatibitlty with proprietary releases already in field.
+*/
+__setup("monitor=", cmx2xx_set_display);
+
+static void __init cmx2xx_init_display(void)
+{
+	set_pxa_fb_info(cmx2xx_display);
+}
+#else
+static inline void cmx2xx_init_display(void) {}
+#endif
+
+#ifdef CONFIG_PM
+static unsigned long sleep_save_msc[10];
+
+static int cmx2xx_suspend(struct sys_device *dev, pm_message_t state)
+{
+	cmx2xx_pci_suspend();
+
+	/* save MSC registers */
+	sleep_save_msc[0] = MSC0;
+	sleep_save_msc[1] = MSC1;
+	sleep_save_msc[2] = MSC2;
+
+	/* setup power saving mode registers */
+	PCFR = 0x0;
+	PSLR = 0xff400000;
+	PMCR  = 0x00000005;
+	PWER  = 0x80000000;
+	PFER  = 0x00000000;
+	PRER  = 0x00000000;
+	PGSR0 = 0xC0018800;
+	PGSR1 = 0x004F0002;
+	PGSR2 = 0x6021C000;
+	PGSR3 = 0x00020000;
+
+	return 0;
+}
+
+static int cmx2xx_resume(struct sys_device *dev)
+{
+	cmx2xx_pci_resume();
+
+	/* restore MSC registers */
+	MSC0 = sleep_save_msc[0];
+	MSC1 = sleep_save_msc[1];
+	MSC2 = sleep_save_msc[2];
+
+	return 0;
+}
+
+static struct sysdev_class cmx2xx_pm_sysclass = {
+	.name = "pm",
+	.resume = cmx2xx_resume,
+	.suspend = cmx2xx_suspend,
+};
+
+static struct sys_device cmx2xx_pm_device = {
+	.cls = &cmx2xx_pm_sysclass,
+};
+
+static int __init cmx2xx_pm_init(void)
+{
+	int error;
+	error = sysdev_class_register(&cmx2xx_pm_sysclass);
+	if (error == 0)
+		error = sysdev_register(&cmx2xx_pm_device);
+	return error;
+}
+#else
+static int __init cmx2xx_pm_init(void) { return 0; }
+#endif
+
+#if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE)
+static void __init cmx2xx_init_ac97(void)
+{
+	pxa_set_ac97_info(NULL);
+}
+#else
+static inline void cmx2xx_init_ac97(void) {}
+#endif
+
+static void __init cmx2xx_init(void)
+{
+	cmx2xx_pm_init();
+
+	if (cpu_is_pxa25x())
+		cmx255_init();
+	else
+		cmx270_init();
+
+	cmx2xx_init_dm9000();
+	cmx2xx_init_display();
+	cmx2xx_init_ac97();
+	cmx2xx_init_touchscreen();
+	cmx2xx_init_leds();
+}
+
+static void __init cmx2xx_init_irq(void)
+{
+	pxa27x_init_irq();
+
+	if (cpu_is_pxa25x()) {
+		pxa25x_init_irq();
+		cmx2xx_pci_init_irq(CMX255_GPIO_IT8152_IRQ);
+	} else {
+		pxa27x_init_irq();
+		cmx2xx_pci_init_irq(CMX270_GPIO_IT8152_IRQ);
+	}
+}
+
+#ifdef CONFIG_PCI
+/* Map PCI companion statically */
+static struct map_desc cmx2xx_io_desc[] __initdata = {
+	[0] = { /* PCI bridge */
+		.virtual	= CMX2XX_IT8152_VIRT,
+		.pfn		= __phys_to_pfn(PXA_CS4_PHYS),
+		.length		= SZ_64M,
+		.type		= MT_DEVICE
+	},
+};
+
+static void __init cmx2xx_map_io(void)
+{
+	pxa_map_io();
+	iotable_init(cmx2xx_io_desc, ARRAY_SIZE(cmx2xx_io_desc));
+
+	it8152_base_address = CMX2XX_IT8152_VIRT;
+}
+#else
+static void __init cmx2xx_map_io(void)
+{
+	pxa_map_io();
+}
+#endif
+
+MACHINE_START(ARMCORE, "Compulab CM-X2XX")
+	.boot_params	= 0xa0000100,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.map_io		= cmx2xx_map_io,
+	.init_irq	= cmx2xx_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= cmx2xx_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
new file mode 100644
index 0000000..deb46cd
--- /dev/null
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -0,0 +1,465 @@
+/*
+ * linux/arch/arm/mach-pxa/cm-x300.c
+ *
+ * Support for the CompuLab CM-X300 modules
+ *
+ * Copyright (C) 2008 CompuLab Ltd.
+ *
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <linux/gpio.h>
+#include <linux/dm9000.h>
+#include <linux/leds.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c/pca953x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/mfp-pxa300.h>
+
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <mach/ohci.h>
+#include <mach/i2c.h>
+#include <mach/pxa3xx_nand.h>
+
+#include <asm/mach/map.h>
+
+#include "generic.h"
+
+#define CM_X300_ETH_PHYS	0x08000010
+
+#define GPIO82_MMC2_IRQ		(82)
+#define GPIO85_MMC2_WP		(85)
+
+#define	CM_X300_MMC2_IRQ	IRQ_GPIO(GPIO82_MMC2_IRQ)
+
+static mfp_cfg_t cm_x300_mfp_cfg[] __initdata = {
+	/* LCD */
+	GPIO54_LCD_LDD_0,
+	GPIO55_LCD_LDD_1,
+	GPIO56_LCD_LDD_2,
+	GPIO57_LCD_LDD_3,
+	GPIO58_LCD_LDD_4,
+	GPIO59_LCD_LDD_5,
+	GPIO60_LCD_LDD_6,
+	GPIO61_LCD_LDD_7,
+	GPIO62_LCD_LDD_8,
+	GPIO63_LCD_LDD_9,
+	GPIO64_LCD_LDD_10,
+	GPIO65_LCD_LDD_11,
+	GPIO66_LCD_LDD_12,
+	GPIO67_LCD_LDD_13,
+	GPIO68_LCD_LDD_14,
+	GPIO69_LCD_LDD_15,
+	GPIO72_LCD_FCLK,
+	GPIO73_LCD_LCLK,
+	GPIO74_LCD_PCLK,
+	GPIO75_LCD_BIAS,
+
+	/* BTUART */
+	GPIO111_UART2_RTS,
+	GPIO112_UART2_RXD | MFP_LPM_EDGE_FALL,
+	GPIO113_UART2_TXD,
+	GPIO114_UART2_CTS | MFP_LPM_EDGE_BOTH,
+
+	/* STUART */
+	GPIO109_UART3_TXD,
+	GPIO110_UART3_RXD | MFP_LPM_EDGE_FALL,
+
+	/* AC97 */
+	GPIO23_AC97_nACRESET,
+	GPIO24_AC97_SYSCLK,
+	GPIO29_AC97_BITCLK,
+	GPIO25_AC97_SDATA_IN_0,
+	GPIO27_AC97_SDATA_OUT,
+	GPIO28_AC97_SYNC,
+
+	/* Keypad */
+	GPIO115_KP_MKIN_0 | MFP_LPM_EDGE_BOTH,
+	GPIO116_KP_MKIN_1 | MFP_LPM_EDGE_BOTH,
+	GPIO117_KP_MKIN_2 | MFP_LPM_EDGE_BOTH,
+	GPIO118_KP_MKIN_3 | MFP_LPM_EDGE_BOTH,
+	GPIO119_KP_MKIN_4 | MFP_LPM_EDGE_BOTH,
+	GPIO120_KP_MKIN_5 | MFP_LPM_EDGE_BOTH,
+	GPIO2_2_KP_MKIN_6 | MFP_LPM_EDGE_BOTH,
+	GPIO3_2_KP_MKIN_7 | MFP_LPM_EDGE_BOTH,
+	GPIO121_KP_MKOUT_0,
+	GPIO122_KP_MKOUT_1,
+	GPIO123_KP_MKOUT_2,
+	GPIO124_KP_MKOUT_3,
+	GPIO125_KP_MKOUT_4,
+	GPIO4_2_KP_MKOUT_5,
+
+	/* MMC1 */
+	GPIO3_MMC1_DAT0,
+	GPIO4_MMC1_DAT1 | MFP_LPM_EDGE_BOTH,
+	GPIO5_MMC1_DAT2,
+	GPIO6_MMC1_DAT3,
+	GPIO7_MMC1_CLK,
+	GPIO8_MMC1_CMD,	/* CMD0 for slot 0 */
+
+	/* MMC2 */
+	GPIO9_MMC2_DAT0,
+	GPIO10_MMC2_DAT1 | MFP_LPM_EDGE_BOTH,
+	GPIO11_MMC2_DAT2,
+	GPIO12_MMC2_DAT3,
+	GPIO13_MMC2_CLK,
+	GPIO14_MMC2_CMD,
+
+	/* FFUART */
+	GPIO30_UART1_RXD | MFP_LPM_EDGE_FALL,
+	GPIO31_UART1_TXD,
+	GPIO32_UART1_CTS,
+	GPIO37_UART1_RTS,
+	GPIO33_UART1_DCD,
+	GPIO34_UART1_DSR | MFP_LPM_EDGE_FALL,
+	GPIO35_UART1_RI,
+	GPIO36_UART1_DTR,
+
+	/* GPIOs */
+	GPIO79_GPIO,			/* LED */
+	GPIO82_GPIO | MFP_PULL_HIGH,	/* MMC CD */
+	GPIO85_GPIO,			/* MMC WP */
+	GPIO99_GPIO,			/* Ethernet IRQ */
+};
+
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+static struct resource dm9000_resources[] = {
+	[0] = {
+		.start	= CM_X300_ETH_PHYS,
+		.end	= CM_X300_ETH_PHYS + 0x3,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= CM_X300_ETH_PHYS + 0x4,
+		.end	= CM_X300_ETH_PHYS + 0x4 + 500,
+		.flags	= IORESOURCE_MEM,
+	},
+	[2] = {
+		.start	= IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO99)),
+		.end	= IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO99)),
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+	}
+};
+
+static struct dm9000_plat_data cm_x300_dm9000_platdata = {
+	.flags		= DM9000_PLATF_16BITONLY,
+};
+
+static struct platform_device dm9000_device = {
+	.name		= "dm9000",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(dm9000_resources),
+	.resource	= dm9000_resources,
+	.dev		= {
+		.platform_data = &cm_x300_dm9000_platdata,
+	}
+
+};
+
+static void __init cm_x300_init_dm9000(void)
+{
+	platform_device_register(&dm9000_device);
+}
+#else
+static inline void cm_x300_init_dm9000(void) {}
+#endif
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct pxafb_mode_info cm_x300_lcd_modes[] = {
+	[0] = {
+		.pixclock	= 38000,
+		.bpp		= 16,
+		.xres		= 480,
+		.yres		= 640,
+		.hsync_len	= 8,
+		.vsync_len	= 2,
+		.left_margin	= 8,
+		.upper_margin	= 0,
+		.right_margin	= 24,
+		.lower_margin	= 4,
+		.cmap_greyscale	= 0,
+	},
+	[1] = {
+		.pixclock	= 153800,
+		.bpp		= 16,
+		.xres		= 240,
+		.yres		= 320,
+		.hsync_len	= 8,
+		.vsync_len	= 2,
+		.left_margin	= 8,
+		.upper_margin	= 2,
+		.right_margin	= 88,
+		.lower_margin	= 2,
+		.cmap_greyscale	= 0,
+	},
+};
+
+static struct pxafb_mach_info cm_x300_lcd = {
+	.modes			= cm_x300_lcd_modes,
+	.num_modes		= 2,
+	.lcd_conn		= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+static void __init cm_x300_init_lcd(void)
+{
+	set_pxa_fb_info(&cm_x300_lcd);
+}
+#else
+static inline void cm_x300_init_lcd(void) {}
+#endif
+
+#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+static struct mtd_partition cm_x300_nand_partitions[] = {
+	[0] = {
+		.name        = "OBM",
+		.offset      = 0,
+		.size        = SZ_256K,
+		.mask_flags  = MTD_WRITEABLE, /* force read-only */
+	},
+	[1] = {
+		.name        = "U-Boot",
+		.offset      = MTDPART_OFS_APPEND,
+		.size        = SZ_256K,
+		.mask_flags  = MTD_WRITEABLE, /* force read-only */
+	},
+	[2] = {
+		.name        = "Environment",
+		.offset      = MTDPART_OFS_APPEND,
+		.size        = SZ_256K,
+	},
+	[3] = {
+		.name        = "reserved",
+		.offset      = MTDPART_OFS_APPEND,
+		.size        = SZ_256K + SZ_1M,
+		.mask_flags  = MTD_WRITEABLE, /* force read-only */
+	},
+	[4] = {
+		.name        = "kernel",
+		.offset      = MTDPART_OFS_APPEND,
+		.size        = SZ_4M,
+	},
+	[5] = {
+		.name        = "fs",
+		.offset      = MTDPART_OFS_APPEND,
+		.size        = MTDPART_SIZ_FULL,
+	},
+};
+
+static struct pxa3xx_nand_platform_data cm_x300_nand_info = {
+	.enable_arbiter	= 1,
+	.parts		= cm_x300_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(cm_x300_nand_partitions),
+};
+
+static void __init cm_x300_init_nand(void)
+{
+	pxa3xx_set_nand_info(&cm_x300_nand_info);
+}
+#else
+static inline void cm_x300_init_nand(void) {}
+#endif
+
+#if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
+/* The first MMC slot of CM-X300 is hardwired to Libertas card and has
+   no detection/ro pins */
+static int cm_x300_mci_init(struct device *dev,
+			    irq_handler_t cm_x300_detect_int,
+			    void *data)
+{
+	return 0;
+}
+
+static void cm_x300_mci_exit(struct device *dev, void *data)
+{
+}
+
+static struct pxamci_platform_data cm_x300_mci_platform_data = {
+	.detect_delay	= 20,
+	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init 		= cm_x300_mci_init,
+	.exit		= cm_x300_mci_exit,
+};
+
+static int cm_x300_mci2_ro(struct device *dev)
+{
+	return gpio_get_value(GPIO85_MMC2_WP);
+}
+
+static int cm_x300_mci2_init(struct device *dev,
+			     irq_handler_t cm_x300_detect_int,
+			     void *data)
+{
+	int err;
+
+	/*
+	 * setup GPIO for CM-X300 MMC controller
+	 */
+	err = gpio_request(GPIO82_MMC2_IRQ, "mmc card detect");
+	if (err)
+		goto err_request_cd;
+	gpio_direction_input(GPIO82_MMC2_IRQ);
+
+	err = gpio_request(GPIO85_MMC2_WP, "mmc write protect");
+	if (err)
+		goto err_request_wp;
+	gpio_direction_input(GPIO85_MMC2_WP);
+
+	err = request_irq(CM_X300_MMC2_IRQ, cm_x300_detect_int,
+			  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+			  "MMC card detect", data);
+	if (err) {
+		printk(KERN_ERR "%s: MMC/SD/SDIO: "
+				"can't request card detect IRQ\n", __func__);
+		goto err_request_irq;
+	}
+
+	return 0;
+
+err_request_irq:
+	gpio_free(GPIO85_MMC2_WP);
+err_request_wp:
+	gpio_free(GPIO82_MMC2_IRQ);
+err_request_cd:
+	return err;
+}
+
+static void cm_x300_mci2_exit(struct device *dev, void *data)
+{
+	free_irq(CM_X300_MMC2_IRQ, data);
+	gpio_free(GPIO82_MMC2_IRQ);
+	gpio_free(GPIO85_MMC2_WP);
+}
+
+static struct pxamci_platform_data cm_x300_mci2_platform_data = {
+	.detect_delay	= 20,
+	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init 		= cm_x300_mci2_init,
+	.exit		= cm_x300_mci2_exit,
+	.get_ro		= cm_x300_mci2_ro,
+};
+
+static void __init cm_x300_init_mmc(void)
+{
+	pxa_set_mci_info(&cm_x300_mci_platform_data);
+	pxa3xx_set_mci2_info(&cm_x300_mci2_platform_data);
+}
+#else
+static inline void cm_x300_init_mmc(void) {}
+#endif
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static struct pxaohci_platform_data cm_x300_ohci_platform_data = {
+	.port_mode	= PMM_PERPORT_MODE,
+	.flags		= ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
+};
+
+static void __init cm_x300_init_ohci(void)
+{
+	pxa_set_ohci_info(&cm_x300_ohci_platform_data);
+}
+#else
+static inline void cm_x300_init_ohci(void) {}
+#endif
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+static struct gpio_led cm_x300_leds[] = {
+	[0] = {
+		.name = "cm-x300:green",
+		.default_trigger = "heartbeat",
+		.gpio = 79,
+		.active_low = 1,
+	},
+};
+
+static struct gpio_led_platform_data cm_x300_gpio_led_pdata = {
+	.num_leds = ARRAY_SIZE(cm_x300_leds),
+	.leds = cm_x300_leds,
+};
+
+static struct platform_device cm_x300_led_device = {
+	.name		= "leds-gpio",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &cm_x300_gpio_led_pdata,
+	},
+};
+
+static void __init cm_x300_init_leds(void)
+{
+	platform_device_register(&cm_x300_led_device);
+}
+#else
+static inline void cm_x300_init_leds(void) {}
+#endif
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+/* PCA9555 */
+static struct pca953x_platform_data cm_x300_gpio_ext_pdata_0 = {
+	.gpio_base = 128,
+};
+
+static struct pca953x_platform_data cm_x300_gpio_ext_pdata_1 = {
+	.gpio_base = 144,
+};
+
+static struct i2c_board_info cm_x300_gpio_ext_info[] = {
+	[0] = {
+		I2C_BOARD_INFO("pca9555", 0x24),
+		.platform_data = &cm_x300_gpio_ext_pdata_0,
+	},
+	[1] = {
+		I2C_BOARD_INFO("pca9555", 0x25),
+		.platform_data = &cm_x300_gpio_ext_pdata_1,
+	},
+};
+
+static void __init cm_x300_init_i2c(void)
+{
+	pxa_set_i2c_info(NULL);
+	i2c_register_board_info(0, cm_x300_gpio_ext_info,
+				ARRAY_SIZE(cm_x300_gpio_ext_info));
+}
+#else
+static inline void cm_x300_init_i2c(void) {}
+#endif
+
+static void __init cm_x300_init(void)
+{
+	/* board-processor specific GPIO initialization */
+	pxa3xx_mfp_config(ARRAY_AND_SIZE(cm_x300_mfp_cfg));
+
+	cm_x300_init_dm9000();
+	cm_x300_init_lcd();
+	cm_x300_init_ohci();
+	cm_x300_init_mmc();
+	cm_x300_init_nand();
+	cm_x300_init_leds();
+	cm_x300_init_i2c();
+}
+
+MACHINE_START(CM_X300, "CM-X300 module")
+	.phys_io	= 0x40000000,
+	.boot_params	= 0xa0000100,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa3xx_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= cm_x300_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/colibri.c b/arch/arm/mach-pxa/colibri.c
index abce13c..e847362 100644
--- a/arch/arm/mach-pxa/colibri.c
+++ b/arch/arm/mach-pxa/colibri.c
@@ -29,12 +29,17 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/flash.h>
 #include <mach/pxa-regs.h>
-#include <mach/pxa2xx-gpio.h>
+#include <mach/mfp-pxa27x.h>
 #include <mach/colibri.h>
 
 #include "generic.h"
 #include "devices.h"
 
+static unsigned long colibri_pin_config[] __initdata = {
+	GPIO78_nCS_2,	/* Ethernet CS */
+	GPIO114_GPIO,	/* Ethernet IRQ */
+};
+
 /*
  * Flash
  */
@@ -116,9 +121,7 @@
 
 static void __init colibri_init(void)
 {
-	/* DM9000 LAN */
-	pxa_gpio_mode(GPIO78_nCS_2_MD);
-	pxa_gpio_mode(GPIO_DM9000 | GPIO_IN);
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(colibri_pin_config));
 
 	platform_add_devices(colibri_devices, ARRAY_SIZE(colibri_devices));
 }
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index e703a8d..65558d6 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -20,7 +20,12 @@
 #include <linux/interrupt.h>
 #include <linux/mmc/host.h>
 #include <linux/pm.h>
+#include <linux/gpio.h>
 #include <linux/backlight.h>
+#include <linux/io.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/spi/corgi_lcd.h>
 #include <video/w100fb.h>
 
 #include <asm/setup.h>
@@ -28,7 +33,6 @@
 #include <asm/mach-types.h>
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 #include <asm/system.h>
 
 #include <asm/mach/arch.h>
@@ -37,11 +41,12 @@
 
 #include <mach/pxa-regs.h>
 #include <mach/pxa2xx-regs.h>
-#include <mach/pxa2xx-gpio.h>
+#include <mach/mfp-pxa25x.h>
 #include <mach/i2c.h>
 #include <mach/irda.h>
 #include <mach/mmc.h>
 #include <mach/udc.h>
+#include <mach/pxa2xx_spi.h>
 #include <mach/corgi.h>
 #include <mach/sharpsl.h>
 
@@ -52,6 +57,61 @@
 #include "devices.h"
 #include "sharpsl.h"
 
+static unsigned long corgi_pin_config[] __initdata = {
+	/* Static Memory I/O */
+	GPIO78_nCS_2,	/* w100fb */
+	GPIO80_nCS_4,	/* scoop */
+
+	/* SSP1 */
+	GPIO23_SSP1_SCLK,
+	GPIO25_SSP1_TXD,
+	GPIO26_SSP1_RXD,
+	GPIO24_GPIO,	/* CORGI_GPIO_ADS7846_CS - SFRM as chip select */
+
+	/* I2S */
+	GPIO28_I2S_BITCLK_OUT,
+	GPIO29_I2S_SDATA_IN,
+	GPIO30_I2S_SDATA_OUT,
+	GPIO31_I2S_SYNC,
+	GPIO32_I2S_SYSCLK,
+
+	/* Infra-Red */
+	GPIO47_FICP_TXD,
+	GPIO46_FICP_RXD,
+
+	/* FFUART */
+	GPIO40_FFUART_DTR,
+	GPIO41_FFUART_RTS,
+	GPIO39_FFUART_TXD,
+	GPIO37_FFUART_DSR,
+	GPIO34_FFUART_RXD,
+	GPIO35_FFUART_CTS,
+
+	/* PC Card */
+	GPIO48_nPOE,
+	GPIO49_nPWE,
+	GPIO50_nPIOR,
+	GPIO51_nPIOW,
+	GPIO52_nPCE_1,
+	GPIO53_nPCE_2,
+	GPIO54_nPSKTSEL,
+	GPIO55_nPREG,
+	GPIO56_nPWAIT,
+	GPIO57_nIOIS16,
+
+	/* MMC */
+	GPIO6_MMC_CLK,
+	GPIO8_MMC_CS0,
+
+	/* GPIO */
+	GPIO9_GPIO,	/* CORGI_GPIO_nSD_DETECT */
+	GPIO7_GPIO,	/* CORGI_GPIO_nSD_WP */
+	GPIO33_GPIO,	/* CORGI_GPIO_SD_PWR */
+	GPIO22_GPIO,	/* CORGI_GPIO_IR_ON */
+	GPIO44_GPIO,	/* CORGI_GPIO_HSYNC */
+
+	GPIO1_GPIO | WAKEUP_ON_EDGE_RISE,
+};
 
 /*
  * Corgi SCOOP Device
@@ -67,6 +127,7 @@
 static struct scoop_config corgi_scoop_setup = {
 	.io_dir 	= CORGI_SCOOP_IO_DIR,
 	.io_out		= CORGI_SCOOP_IO_OUT,
+	.gpio_base	= CORGI_SCOOP_GPIO_BASE,
 };
 
 struct platform_device corgiscoop_device = {
@@ -79,27 +140,6 @@
 	.resource	= corgi_scoop_resources,
 };
 
-static void corgi_pcmcia_init(void)
-{
-	/* Setup default state of GPIO outputs
-	   before we enable them as outputs. */
-	GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
-		GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
-		GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) |
-		GPIO_bit(GPIO53_nPCE_2);
-
-	pxa_gpio_mode(GPIO48_nPOE_MD);
-	pxa_gpio_mode(GPIO49_nPWE_MD);
-	pxa_gpio_mode(GPIO50_nPIOR_MD);
-	pxa_gpio_mode(GPIO51_nPIOW_MD);
-	pxa_gpio_mode(GPIO55_nPREG_MD);
-	pxa_gpio_mode(GPIO56_nPWAIT_MD);
-	pxa_gpio_mode(GPIO57_nIOIS16_MD);
-	pxa_gpio_mode(GPIO52_nPCE_1_MD);
-	pxa_gpio_mode(GPIO53_nPCE_2_MD);
-	pxa_gpio_mode(GPIO54_pSKTSEL_MD);
-}
-
 static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = {
 {
 	.dev        = &corgiscoop_device.dev,
@@ -112,58 +152,10 @@
 static struct scoop_pcmcia_config corgi_pcmcia_config = {
 	.devs         = &corgi_pcmcia_scoop[0],
 	.num_devs     = 1,
-	.pcmcia_init  = corgi_pcmcia_init,
 };
 
 EXPORT_SYMBOL(corgiscoop_device);
 
-
-/*
- * Corgi SSP Device
- *
- * Set the parent as the scoop device because a lot of SSP devices
- * also use scoop functions and this makes the power up/down order
- * work correctly.
- */
-struct platform_device corgissp_device = {
-	.name		= "corgi-ssp",
-	.dev		= {
- 		.parent = &corgiscoop_device.dev,
-	},
-	.id		= -1,
-};
-
-struct corgissp_machinfo corgi_ssp_machinfo = {
-	.port		= 1,
-	.cs_lcdcon	= CORGI_GPIO_LCDCON_CS,
-	.cs_ads7846	= CORGI_GPIO_ADS7846_CS,
-	.cs_max1111	= CORGI_GPIO_MAX1111_CS,
-	.clk_lcdcon	= 76,
-	.clk_ads7846	= 2,
-	.clk_max1111	= 8,
-};
-
-
-/*
- * LCD/Framebuffer
- */
-static void w100_lcdtg_suspend(struct w100fb_par *par)
-{
-	corgi_lcdtg_suspend();
-}
-
-static void w100_lcdtg_init(struct w100fb_par *par)
-{
-	corgi_lcdtg_hw_init(par->xres);
-}
-
-
-static struct w100_tg_info corgi_lcdtg_info = {
-	.change  = w100_lcdtg_init,
-	.suspend = w100_lcdtg_suspend,
-	.resume  = w100_lcdtg_init,
-};
-
 static struct w100_mem_info corgi_fb_mem = {
 	.ext_cntl          = 0x00040003,
 	.sdram_mode_reg    = 0x00650021,
@@ -242,7 +234,6 @@
 };
 
 static struct w100fb_mach_info corgi_fb_info = {
-	.tg         = &corgi_lcdtg_info,
 	.init_mode  = INIT_MODE_ROTATED,
 	.mem        = &corgi_fb_mem,
 	.regs       = &corgi_fb_regs,
@@ -268,60 +259,10 @@
 	.resource	= corgi_fb_resources,
 	.dev            = {
 		.platform_data = &corgi_fb_info,
-		.parent = &corgissp_device.dev,
 	},
 
 };
 
-
-/*
- * Corgi Backlight Device
- */
-static void corgi_bl_kick_battery(void)
-{
-	void (*kick_batt)(void);
-
-	kick_batt = symbol_get(sharpsl_battery_kick);
-	if (kick_batt) {
-		kick_batt();
-		symbol_put(sharpsl_battery_kick);
-	}
-}
-
-static void corgi_bl_set_intensity(int intensity)
-{
-	if (intensity > 0x10)
-		intensity += 0x10;
-
-	/* Bits 0-4 are accessed via the SSP interface */
-	corgi_ssp_blduty_set(intensity & 0x1f);
-
-	/* Bit 5 is via SCOOP */
-	if (intensity & 0x0020)
-		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
-	else
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
-}
-
-static struct generic_bl_info corgi_bl_machinfo = {
-	.name = "corgi-bl",
-	.max_intensity = 0x2f,
-	.default_intensity = 0x1f,
-	.limit_mask = 0x0b,
-	.set_bl_intensity = corgi_bl_set_intensity,
-	.kick_battery = corgi_bl_kick_battery,
-};
-
-static struct platform_device corgibl_device = {
-	.name		= "generic-bl",
-	.dev		= {
- 		.parent = &corgifb_device.dev,
-		.platform_data	= &corgi_bl_machinfo,
-	},
-	.id		= -1,
-};
-
-
 /*
  * Corgi Keyboard Device
  */
@@ -330,75 +271,35 @@
 	.id		= -1,
 };
 
-
 /*
  * Corgi LEDs
  */
+static struct gpio_led corgi_gpio_leds[] = {
+	{
+		.name			= "corgi:amber:charge",
+		.default_trigger	= "sharpsl-charge",
+		.gpio			= CORGI_GPIO_LED_ORANGE,
+	},
+	{
+		.name			= "corgi:green:mail",
+		.default_trigger	= "nand-disk",
+		.gpio			= CORGI_GPIO_LED_GREEN,
+	},
+};
+
+static struct gpio_led_platform_data corgi_gpio_leds_info = {
+	.leds		= corgi_gpio_leds,
+	.num_leds	= ARRAY_SIZE(corgi_gpio_leds),
+};
+
 static struct platform_device corgiled_device = {
-	.name		= "corgi-led",
+	.name		= "leds-gpio",
 	.id		= -1,
-};
-
-
-/*
- * Corgi Touch Screen Device
- */
-static unsigned long (*get_hsync_invperiod)(struct device *dev);
-
-static void inline sharpsl_wait_sync(int gpio)
-{
-	while((GPLR(gpio) & GPIO_bit(gpio)) == 0);
-	while((GPLR(gpio) & GPIO_bit(gpio)) != 0);
-}
-
-static unsigned long corgi_get_hsync_invperiod(void)
-{
-	if (!get_hsync_invperiod)
-		get_hsync_invperiod = symbol_get(w100fb_get_hsynclen);
-	if (!get_hsync_invperiod)
-		return 0;
-
-	return get_hsync_invperiod(&corgifb_device.dev);
-}
-
-static void corgi_put_hsync(void)
-{
-	if (get_hsync_invperiod)
-		symbol_put(w100fb_get_hsynclen);
-	get_hsync_invperiod = NULL;
-}
-
-static void corgi_wait_hsync(void)
-{
-	sharpsl_wait_sync(CORGI_GPIO_HSYNC);
-}
-
-static struct resource corgits_resources[] = {
-	[0] = {
-		.start		= CORGI_IRQ_GPIO_TP_INT,
-		.end		= CORGI_IRQ_GPIO_TP_INT,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct corgits_machinfo  corgi_ts_machinfo = {
-	.get_hsync_invperiod = corgi_get_hsync_invperiod,
-	.put_hsync           = corgi_put_hsync,
-	.wait_hsync          = corgi_wait_hsync,
-};
-
-static struct platform_device corgits_device = {
-	.name		= "corgi-ts",
 	.dev		= {
- 		.parent = &corgissp_device.dev,
-		.platform_data	= &corgi_ts_machinfo,
+		.platform_data = &corgi_gpio_leds_info,
 	},
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(corgits_resources),
-	.resource	= corgits_resources,
 };
 
-
 /*
  * MMC/SD Device
  *
@@ -411,20 +312,42 @@
 {
 	int err;
 
-	/* setup GPIO for PXA25x MMC controller	*/
-	pxa_gpio_mode(GPIO6_MMCCLK_MD);
-	pxa_gpio_mode(GPIO8_MMCCS0_MD);
-	pxa_gpio_mode(CORGI_GPIO_nSD_DETECT | GPIO_IN);
-	pxa_gpio_mode(CORGI_GPIO_SD_PWR | GPIO_OUT);
+	err = gpio_request(CORGI_GPIO_nSD_DETECT, "nSD_DETECT");
+	if (err)
+		goto err_out;
+
+	err = gpio_request(CORGI_GPIO_nSD_WP, "nSD_WP");
+	if (err)
+		goto err_free_1;
+
+	err = gpio_request(CORGI_GPIO_SD_PWR, "SD_PWR");
+	if (err)
+		goto err_free_2;
+
+	gpio_direction_input(CORGI_GPIO_nSD_DETECT);
+	gpio_direction_input(CORGI_GPIO_nSD_WP);
+	gpio_direction_output(CORGI_GPIO_SD_PWR, 0);
 
 	corgi_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 
 	err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_detect_int,
-			  IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-			  "MMC card detect", data);
-	if (err)
-		printk(KERN_ERR "corgi_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
+				IRQF_DISABLED | IRQF_TRIGGER_RISING |
+				IRQF_TRIGGER_FALLING,
+				"MMC card detect", data);
+	if (err) {
+		pr_err("%s: MMC/SD: can't request MMC card detect IRQ\n",
+				__func__);
+		goto err_free_3;
+	}
+	return 0;
 
+err_free_3:
+	gpio_free(CORGI_GPIO_SD_PWR);
+err_free_2:
+	gpio_free(CORGI_GPIO_nSD_WP);
+err_free_1:
+	gpio_free(CORGI_GPIO_nSD_DETECT);
+err_out:
 	return err;
 }
 
@@ -432,20 +355,20 @@
 {
 	struct pxamci_platform_data* p_d = dev->platform_data;
 
-	if (( 1 << vdd) & p_d->ocr_mask)
-		GPSR1 = GPIO_bit(CORGI_GPIO_SD_PWR);
-	else
-		GPCR1 = GPIO_bit(CORGI_GPIO_SD_PWR);
+	gpio_set_value(CORGI_GPIO_SD_PWR, ((1 << vdd) & p_d->ocr_mask));
 }
 
 static int corgi_mci_get_ro(struct device *dev)
 {
-	return GPLR(CORGI_GPIO_nSD_WP) & GPIO_bit(CORGI_GPIO_nSD_WP);
+	return gpio_get_value(CORGI_GPIO_nSD_WP);
 }
 
 static void corgi_mci_exit(struct device *dev, void *data)
 {
 	free_irq(CORGI_IRQ_GPIO_nSD_DETECT, data);
+	gpio_free(CORGI_GPIO_SD_PWR);
+	gpio_free(CORGI_GPIO_nSD_WP);
+	gpio_free(CORGI_GPIO_nSD_DETECT);
 }
 
 static struct pxamci_platform_data corgi_mci_platform_data = {
@@ -462,16 +385,32 @@
  */
 static void corgi_irda_transceiver_mode(struct device *dev, int mode)
 {
-	if (mode & IR_OFF)
-		GPSR(CORGI_GPIO_IR_ON) = GPIO_bit(CORGI_GPIO_IR_ON);
-	else
-		GPCR(CORGI_GPIO_IR_ON) = GPIO_bit(CORGI_GPIO_IR_ON);
+	gpio_set_value(CORGI_GPIO_IR_ON, mode & IR_OFF);
 	pxa2xx_transceiver_mode(dev, mode);
 }
 
+static int corgi_irda_startup(struct device *dev)
+{
+	int err;
+
+	err = gpio_request(CORGI_GPIO_IR_ON, "IR_ON");
+	if (err)
+		return err;
+
+	gpio_direction_output(CORGI_GPIO_IR_ON, 1);
+	return 0;
+}
+
+static void corgi_irda_shutdown(struct device *dev)
+{
+	gpio_free(CORGI_GPIO_IR_ON);
+}
+
 static struct pxaficp_platform_data corgi_ficp_platform_data = {
-	.transceiver_cap  = IR_SIRMODE | IR_OFF,
-	.transceiver_mode = corgi_irda_transceiver_mode,
+	.transceiver_cap	= IR_SIRMODE | IR_OFF,
+	.transceiver_mode	= corgi_irda_transceiver_mode,
+	.startup		= corgi_irda_startup,
+	.shutdown		= corgi_irda_shutdown,
 };
 
 
@@ -483,14 +422,129 @@
 	.gpio_pullup		= CORGI_GPIO_USB_PULLUP,
 };
 
+#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MASTER)
+static struct pxa2xx_spi_master corgi_spi_info = {
+	.num_chipselect	= 3,
+};
+
+static struct ads7846_platform_data corgi_ads7846_info = {
+	.model			= 7846,
+	.vref_delay_usecs	= 100,
+	.x_plate_ohms		= 419,
+	.y_plate_ohms		= 486,
+	.gpio_pendown		= CORGI_GPIO_TP_INT,
+};
+
+static void corgi_ads7846_cs(u32 command)
+{
+	gpio_set_value(CORGI_GPIO_ADS7846_CS, !(command == PXA2XX_CS_ASSERT));
+}
+
+static struct pxa2xx_spi_chip corgi_ads7846_chip = {
+	.cs_control	= corgi_ads7846_cs,
+};
+
+static void corgi_bl_kick_battery(void)
+{
+	void (*kick_batt)(void);
+
+	kick_batt = symbol_get(sharpsl_battery_kick);
+	if (kick_batt) {
+		kick_batt();
+		symbol_put(sharpsl_battery_kick);
+	}
+}
+
+static struct corgi_lcd_platform_data corgi_lcdcon_info = {
+	.init_mode		= CORGI_LCD_MODE_VGA,
+	.max_intensity		= 0x2f,
+	.default_intensity	= 0x1f,
+	.limit_mask		= 0x0b,
+	.gpio_backlight_cont	= CORGI_GPIO_BACKLIGHT_CONT,
+	.gpio_backlight_on	= -1,
+	.kick_battery		= corgi_bl_kick_battery,
+};
+
+static void corgi_lcdcon_cs(u32 command)
+{
+	gpio_set_value(CORGI_GPIO_LCDCON_CS, !(command == PXA2XX_CS_ASSERT));
+}
+
+static struct pxa2xx_spi_chip corgi_lcdcon_chip = {
+	.cs_control	= corgi_lcdcon_cs,
+};
+
+static void corgi_max1111_cs(u32 command)
+{
+	gpio_set_value(CORGI_GPIO_MAX1111_CS, !(command == PXA2XX_CS_ASSERT));
+}
+
+static struct pxa2xx_spi_chip corgi_max1111_chip = {
+	.cs_control	= corgi_max1111_cs,
+};
+
+static struct spi_board_info corgi_spi_devices[] = {
+	{
+		.modalias	= "ads7846",
+		.max_speed_hz	= 1200000,
+		.bus_num	= 1,
+		.chip_select	= 0,
+		.platform_data	= &corgi_ads7846_info,
+		.controller_data= &corgi_ads7846_chip,
+		.irq		= gpio_to_irq(CORGI_GPIO_TP_INT),
+	}, {
+		.modalias	= "corgi-lcd",
+		.max_speed_hz	= 50000,
+		.bus_num	= 1,
+		.chip_select	= 1,
+		.platform_data	= &corgi_lcdcon_info,
+		.controller_data= &corgi_lcdcon_chip,
+	}, {
+		.modalias	= "max1111",
+		.max_speed_hz	= 450000,
+		.bus_num	= 1,
+		.chip_select	= 2,
+		.controller_data= &corgi_max1111_chip,
+	},
+};
+
+static void __init corgi_init_spi(void)
+{
+	int err;
+
+	err = gpio_request(CORGI_GPIO_ADS7846_CS, "ADS7846_CS");
+	if (err)
+		return;
+
+	err = gpio_request(CORGI_GPIO_LCDCON_CS, "LCDCON_CS");
+	if (err)
+		goto err_free_1;
+
+	err = gpio_request(CORGI_GPIO_MAX1111_CS, "MAX1111_CS");
+	if (err)
+		goto err_free_2;
+
+	gpio_direction_output(CORGI_GPIO_ADS7846_CS, 1);
+	gpio_direction_output(CORGI_GPIO_LCDCON_CS, 1);
+	gpio_direction_output(CORGI_GPIO_MAX1111_CS, 1);
+
+	pxa2xx_set_spi_info(1, &corgi_spi_info);
+	spi_register_board_info(ARRAY_AND_SIZE(corgi_spi_devices));
+	return;
+
+err_free_2:
+	gpio_free(CORGI_GPIO_LCDCON_CS);
+err_free_1:
+	gpio_free(CORGI_GPIO_ADS7846_CS);
+}
+#else
+static inline void corgi_init_spi(void) {}
+#endif
 
 static struct platform_device *devices[] __initdata = {
 	&corgiscoop_device,
-	&corgissp_device,
 	&corgifb_device,
 	&corgikbd_device,
-	&corgibl_device,
-	&corgits_device,
 	&corgiled_device,
 };
 
@@ -498,7 +552,8 @@
 {
 	if (!machine_is_corgi())
 		/* Green LED off tells the bootloader to halt */
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
+		gpio_set_value(CORGI_GPIO_LED_GREEN, 0);
+
 	arm_machine_restart('h');
 }
 
@@ -506,7 +561,8 @@
 {
 	if (!machine_is_corgi())
 		/* Green LED on tells the bootloader to reboot */
-		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
+		gpio_set_value(CORGI_GPIO_LED_GREEN, 1);
+
 	arm_machine_restart('h');
 }
 
@@ -515,20 +571,12 @@
 	pm_power_off = corgi_poweroff;
 	arm_pm_restart = corgi_restart;
 
-	/* setup sleep mode values */
-	PWER  = 0x00000002;
-	PFER  = 0x00000000;
-	PRER  = 0x00000002;
-	PGSR0 = 0x0158C000;
-	PGSR1 = 0x00FF0080;
-	PGSR2 = 0x0001C004;
 	/* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
 	PCFR |= PCFR_OPDE;
 
-	corgi_ssp_set_machinfo(&corgi_ssp_machinfo);
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(corgi_pin_config));
 
-	pxa_gpio_mode(CORGI_GPIO_IR_ON | GPIO_OUT);
-	pxa_gpio_mode(CORGI_GPIO_HSYNC | GPIO_IN);
+	corgi_init_spi();
 
  	pxa_set_udc_info(&udc_info);
 	pxa_set_mci_info(&corgi_mci_platform_data);
diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
deleted file mode 100644
index 311baf1..0000000
--- a/arch/arm/mach-pxa/corgi_lcd.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * linux/arch/arm/mach-pxa/corgi_lcd.c
- *
- * Corgi/Spitz LCD Specific Code
- *
- * Copyright (C) 2005 Richard Purdie
- *
- * Connectivity:
- *   Corgi - LCD to ATI Imageon w100 (Wallaby)
- *   Spitz - LCD to PXA Framebuffer
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <mach/akita.h>
-#include <mach/corgi.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
-#include <mach/sharpsl.h>
-#include <mach/spitz.h>
-#include <asm/hardware/scoop.h>
-#include <asm/mach/sharpsl_param.h>
-#include "generic.h"
-
-/* Register Addresses */
-#define RESCTL_ADRS     0x00
-#define PHACTRL_ADRS    0x01
-#define DUTYCTRL_ADRS   0x02
-#define POWERREG0_ADRS  0x03
-#define POWERREG1_ADRS  0x04
-#define GPOR3_ADRS      0x05
-#define PICTRL_ADRS     0x06
-#define POLCTRL_ADRS    0x07
-
-/* Register Bit Definitions */
-#define RESCTL_QVGA     0x01
-#define RESCTL_VGA      0x00
-
-#define POWER1_VW_ON    0x01  /* VW Supply FET ON */
-#define POWER1_GVSS_ON  0x02  /* GVSS(-8V) Power Supply ON */
-#define POWER1_VDD_ON   0x04  /* VDD(8V),SVSS(-4V) Power Supply ON */
-
-#define POWER1_VW_OFF   0x00  /* VW Supply FET OFF */
-#define POWER1_GVSS_OFF 0x00  /* GVSS(-8V) Power Supply OFF */
-#define POWER1_VDD_OFF  0x00  /* VDD(8V),SVSS(-4V) Power Supply OFF */
-
-#define POWER0_COM_DCLK 0x01  /* COM Voltage DC Bias DAC Serial Data Clock */
-#define POWER0_COM_DOUT 0x02  /* COM Voltage DC Bias DAC Serial Data Out */
-#define POWER0_DAC_ON   0x04  /* DAC Power Supply ON */
-#define POWER0_COM_ON   0x08  /* COM Power Supply ON */
-#define POWER0_VCC5_ON  0x10  /* VCC5 Power Supply ON */
-
-#define POWER0_DAC_OFF  0x00  /* DAC Power Supply OFF */
-#define POWER0_COM_OFF  0x00  /* COM Power Supply OFF */
-#define POWER0_VCC5_OFF 0x00  /* VCC5 Power Supply OFF */
-
-#define PICTRL_INIT_STATE      0x01
-#define PICTRL_INIOFF          0x02
-#define PICTRL_POWER_DOWN      0x04
-#define PICTRL_COM_SIGNAL_OFF  0x08
-#define PICTRL_DAC_SIGNAL_OFF  0x10
-
-#define POLCTRL_SYNC_POL_FALL  0x01
-#define POLCTRL_EN_POL_FALL    0x02
-#define POLCTRL_DATA_POL_FALL  0x04
-#define POLCTRL_SYNC_ACT_H     0x08
-#define POLCTRL_EN_ACT_L       0x10
-
-#define POLCTRL_SYNC_POL_RISE  0x00
-#define POLCTRL_EN_POL_RISE    0x00
-#define POLCTRL_DATA_POL_RISE  0x00
-#define POLCTRL_SYNC_ACT_L     0x00
-#define POLCTRL_EN_ACT_H       0x00
-
-#define PHACTRL_PHASE_MANUAL   0x01
-#define DEFAULT_PHAD_QVGA     (9)
-#define DEFAULT_COMADJ        (125)
-
-/*
- * This is only a psuedo I2C interface. We can't use the standard kernel
- * routines as the interface is write only. We just assume the data is acked...
- */
-static void lcdtg_ssp_i2c_send(u8 data)
-{
-	corgi_ssp_lcdtg_send(POWERREG0_ADRS, data);
-	udelay(10);
-}
-
-static void lcdtg_i2c_send_bit(u8 data)
-{
-	lcdtg_ssp_i2c_send(data);
-	lcdtg_ssp_i2c_send(data | POWER0_COM_DCLK);
-	lcdtg_ssp_i2c_send(data);
-}
-
-static void lcdtg_i2c_send_start(u8 base)
-{
-	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
-	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
-	lcdtg_ssp_i2c_send(base);
-}
-
-static void lcdtg_i2c_send_stop(u8 base)
-{
-	lcdtg_ssp_i2c_send(base);
-	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
-	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
-}
-
-static void lcdtg_i2c_send_byte(u8 base, u8 data)
-{
-	int i;
-	for (i = 0; i < 8; i++) {
-		if (data & 0x80)
-			lcdtg_i2c_send_bit(base | POWER0_COM_DOUT);
-		else
-			lcdtg_i2c_send_bit(base);
-		data <<= 1;
-	}
-}
-
-static void lcdtg_i2c_wait_ack(u8 base)
-{
-	lcdtg_i2c_send_bit(base);
-}
-
-static void lcdtg_set_common_voltage(u8 base_data, u8 data)
-{
-	/* Set Common Voltage to M62332FP via I2C */
-	lcdtg_i2c_send_start(base_data);
-	lcdtg_i2c_send_byte(base_data, 0x9c);
-	lcdtg_i2c_wait_ack(base_data);
-	lcdtg_i2c_send_byte(base_data, 0x00);
-	lcdtg_i2c_wait_ack(base_data);
-	lcdtg_i2c_send_byte(base_data, data);
-	lcdtg_i2c_wait_ack(base_data);
-	lcdtg_i2c_send_stop(base_data);
-}
-
-/* Set Phase Adjust */
-static void lcdtg_set_phadadj(int mode)
-{
-	int adj;
-	switch(mode) {
-		case 480:
-		case 640:
-			/* Setting for VGA */
-			adj = sharpsl_param.phadadj;
-			if (adj < 0) {
-				adj = PHACTRL_PHASE_MANUAL;
-			} else {
-				adj = ((adj & 0x0f) << 1) | PHACTRL_PHASE_MANUAL;
-			}
-			break;
-		case 240:
-		case 320:
-		default:
-			/* Setting for QVGA */
-			adj = (DEFAULT_PHAD_QVGA << 1) | PHACTRL_PHASE_MANUAL;
-			break;
-	}
-
-	corgi_ssp_lcdtg_send(PHACTRL_ADRS, adj);
-}
-
-static int lcd_inited;
-
-void corgi_lcdtg_hw_init(int mode)
-{
-	if (!lcd_inited) {
-		int comadj;
-
-		/* Initialize Internal Logic & Port */
-		corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_POWER_DOWN | PICTRL_INIOFF | PICTRL_INIT_STATE
-	  			| PICTRL_COM_SIGNAL_OFF | PICTRL_DAC_SIGNAL_OFF);
-
-		corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF
-				| POWER0_COM_OFF | POWER0_VCC5_OFF);
-
-		corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
-
-		/* VDD(+8V), SVSS(-4V) ON */
-		corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
-		mdelay(3);
-
-		/* DAC ON */
-		corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON
-				| POWER0_COM_OFF | POWER0_VCC5_OFF);
-
-		/* INIB = H, INI = L  */
-		/* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */
-		corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF);
-
-		/* Set Common Voltage */
-		comadj = sharpsl_param.comadj;
-		if (comadj < 0)
-			comadj = DEFAULT_COMADJ;
-		lcdtg_set_common_voltage((POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF), comadj);
-
-		/* VCC5 ON, DAC ON */
-		corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON |
-				POWER0_COM_OFF | POWER0_VCC5_ON);
-
-		/* GVSS(-8V) ON, VDD ON */
-		corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
-		mdelay(2);
-
-		/* COM SIGNAL ON (PICTL[3] = L) */
-		corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE);
-
-		/* COM ON, DAC ON, VCC5_ON */
-		corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON
-				| POWER0_COM_ON | POWER0_VCC5_ON);
-
-		/* VW ON, GVSS ON, VDD ON */
-		corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_ON | POWER1_GVSS_ON | POWER1_VDD_ON);
-
-		/* Signals output enable */
-		corgi_ssp_lcdtg_send(PICTRL_ADRS, 0);
-
-		/* Set Phase Adjust */
-		lcdtg_set_phadadj(mode);
-
-		/* Initialize for Input Signals from ATI */
-		corgi_ssp_lcdtg_send(POLCTRL_ADRS, POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE
-				| POLCTRL_DATA_POL_RISE | POLCTRL_SYNC_ACT_L | POLCTRL_EN_ACT_H);
-		udelay(1000);
-
-		lcd_inited=1;
-	} else {
-		lcdtg_set_phadadj(mode);
-	}
-
-	switch(mode) {
-		case 480:
-		case 640:
-			/* Set Lcd Resolution (VGA) */
-			corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_VGA);
-			break;
-		case 240:
-		case 320:
-		default:
-			/* Set Lcd Resolution (QVGA) */
-			corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_QVGA);
-			break;
-	}
-}
-
-void corgi_lcdtg_suspend(void)
-{
-	/* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
-	mdelay(34);
-
-	/* (1)VW OFF */
-	corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
-
-	/* (2)COM OFF */
-	corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF);
-	corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON);
-
-	/* (3)Set Common Voltage Bias 0V */
-	lcdtg_set_common_voltage(POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON, 0);
-
-	/* (4)GVSS OFF */
-	corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
-
-	/* (5)VCC5 OFF */
-	corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF);
-
-	/* (6)Set PDWN, INIOFF, DACOFF */
-	corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF |
-			PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF);
-
-	/* (7)DAC OFF */
-	corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF);
-
-	/* (8)VDD OFF */
-	corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
-
-	lcd_inited = 0;
-}
-
diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c
index 35bbfcc..eb7d6c9 100644
--- a/arch/arm/mach-pxa/corgi_pm.c
+++ b/arch/arm/mach-pxa/corgi_pm.c
@@ -21,7 +21,6 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 #include <mach/hardware.h>
-#include <asm/hardware/scoop.h>
 
 #include <mach/sharpsl.h>
 #include <mach/corgi.h>
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
deleted file mode 100644
index 8e2f221..0000000
--- a/arch/arm/mach-pxa/corgi_ssp.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- *  SSP control code for Sharp Corgi devices
- *
- *  Copyright (c) 2004-2005 Richard Purdie
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-
-#include <mach/ssp.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-gpio.h>
-#include <mach/regs-ssp.h>
-#include "sharpsl.h"
-
-static DEFINE_SPINLOCK(corgi_ssp_lock);
-static struct ssp_dev corgi_ssp_dev;
-static struct ssp_state corgi_ssp_state;
-static struct corgissp_machinfo *ssp_machinfo;
-
-/*
- * There are three devices connected to the SSP interface:
- *   1. A touchscreen controller (TI ADS7846 compatible)
- *   2. An LCD controller (with some Backlight functionality)
- *   3. A battery monitoring IC (Maxim MAX1111)
- *
- * Each device uses a different speed/mode of communication.
- *
- * The touchscreen is very sensitive and the most frequently used
- * so the port is left configured for this.
- *
- * Devices are selected using Chip Selects on GPIOs.
- */
-
-/*
- *  ADS7846 Routines
- */
-unsigned long corgi_ssp_ads7846_putget(ulong data)
-{
-	unsigned long flag;
-	u32 ret = 0;
-
-	spin_lock_irqsave(&corgi_ssp_lock, flag);
-	if (ssp_machinfo->cs_ads7846 >= 0)
-		GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
-
-	ssp_write_word(&corgi_ssp_dev,data);
- 	ssp_read_word(&corgi_ssp_dev, &ret);
-
-	if (ssp_machinfo->cs_ads7846 >= 0)
-		GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
-	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
-
-	return ret;
-}
-
-/*
- * NOTE: These functions should always be called in interrupt context
- * and use the _lock and _unlock functions. They are very time sensitive.
- */
-void corgi_ssp_ads7846_lock(void)
-{
-	spin_lock(&corgi_ssp_lock);
-	if (ssp_machinfo->cs_ads7846 >= 0)
-		GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
-}
-
-void corgi_ssp_ads7846_unlock(void)
-{
-	if (ssp_machinfo->cs_ads7846 >= 0)
-		GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
-	spin_unlock(&corgi_ssp_lock);
-}
-
-void corgi_ssp_ads7846_put(ulong data)
-{
-	ssp_write_word(&corgi_ssp_dev,data);
-}
-
-unsigned long corgi_ssp_ads7846_get(void)
-{
-	u32 ret = 0;
-	ssp_read_word(&corgi_ssp_dev, &ret);
-	return ret;
-}
-
-EXPORT_SYMBOL(corgi_ssp_ads7846_putget);
-EXPORT_SYMBOL(corgi_ssp_ads7846_lock);
-EXPORT_SYMBOL(corgi_ssp_ads7846_unlock);
-EXPORT_SYMBOL(corgi_ssp_ads7846_put);
-EXPORT_SYMBOL(corgi_ssp_ads7846_get);
-
-
-/*
- *  LCD/Backlight Routines
- */
-unsigned long corgi_ssp_dac_put(ulong data)
-{
-	unsigned long flag, sscr1 = SSCR1_SPH;
-	u32 tmp;
-
-	spin_lock_irqsave(&corgi_ssp_lock, flag);
-
-	if (machine_is_spitz() || machine_is_akita() || machine_is_borzoi())
-		sscr1 = 0;
-
-	ssp_disable(&corgi_ssp_dev);
-	ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), sscr1, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_lcdcon));
-	ssp_enable(&corgi_ssp_dev);
-
-	if (ssp_machinfo->cs_lcdcon >= 0)
-		GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
-	ssp_write_word(&corgi_ssp_dev,data);
-	/* Read null data back from device to prevent SSP overflow */
-	ssp_read_word(&corgi_ssp_dev, &tmp);
-	if (ssp_machinfo->cs_lcdcon >= 0)
-		GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
-
-	ssp_disable(&corgi_ssp_dev);
-	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
-	ssp_enable(&corgi_ssp_dev);
-
-	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
-
-	return 0;
-}
-
-void corgi_ssp_lcdtg_send(u8 adrs, u8 data)
-{
-	corgi_ssp_dac_put(((adrs & 0x07) << 5) | (data & 0x1f));
-}
-
-void corgi_ssp_blduty_set(int duty)
-{
-	corgi_ssp_lcdtg_send(0x02,duty);
-}
-
-EXPORT_SYMBOL(corgi_ssp_lcdtg_send);
-EXPORT_SYMBOL(corgi_ssp_blduty_set);
-
-/*
- *  Max1111 Routines
- */
-int corgi_ssp_max1111_get(ulong data)
-{
-	unsigned long flag;
-	long voltage = 0, voltage1 = 0, voltage2 = 0;
-
-	spin_lock_irqsave(&corgi_ssp_lock, flag);
-	if (ssp_machinfo->cs_max1111 >= 0)
-		GPCR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
-	ssp_disable(&corgi_ssp_dev);
-	ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_max1111));
-	ssp_enable(&corgi_ssp_dev);
-
-	udelay(1);
-
-	/* TB1/RB1 */
-	ssp_write_word(&corgi_ssp_dev,data);
-	ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1); /* null read */
-
-	/* TB12/RB2 */
-	ssp_write_word(&corgi_ssp_dev,0);
-	ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1);
-
-	/* TB13/RB3*/
-	ssp_write_word(&corgi_ssp_dev,0);
-	ssp_read_word(&corgi_ssp_dev, (u32*)&voltage2);
-
-	ssp_disable(&corgi_ssp_dev);
-	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
-	ssp_enable(&corgi_ssp_dev);
-	if (ssp_machinfo->cs_max1111 >= 0)
-		GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
-	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
-
-	if (voltage1 & 0xc0 || voltage2 & 0x3f)
-		voltage = -1;
-	else
-		voltage = ((voltage1 << 2) & 0xfc) | ((voltage2 >> 6) & 0x03);
-
-	return voltage;
-}
-
-EXPORT_SYMBOL(corgi_ssp_max1111_get);
-
-/*
- *  Support Routines
- */
-
-void __init corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo)
-{
-	ssp_machinfo = machinfo;
-}
-
-static int __init corgi_ssp_probe(struct platform_device *dev)
-{
-	int ret;
-
-	/* Chip Select - Disable All */
-	if (ssp_machinfo->cs_lcdcon >= 0)
-		pxa_gpio_mode(ssp_machinfo->cs_lcdcon  | GPIO_OUT | GPIO_DFLT_HIGH);
-	if (ssp_machinfo->cs_max1111 >= 0)
-	        pxa_gpio_mode(ssp_machinfo->cs_max1111 | GPIO_OUT | GPIO_DFLT_HIGH);
-	if (ssp_machinfo->cs_ads7846 >= 0)
-        	pxa_gpio_mode(ssp_machinfo->cs_ads7846 | GPIO_OUT | GPIO_DFLT_HIGH);
-
-	ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0);
-
-	if (ret)
-		printk(KERN_ERR "Unable to register SSP handler!\n");
-	else {
-		ssp_disable(&corgi_ssp_dev);
-		ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
-		ssp_enable(&corgi_ssp_dev);
-	}
-
-	return ret;
-}
-
-static int corgi_ssp_remove(struct platform_device *dev)
-{
-	ssp_exit(&corgi_ssp_dev);
-	return 0;
-}
-
-static int corgi_ssp_suspend(struct platform_device *dev, pm_message_t state)
-{
-	ssp_flush(&corgi_ssp_dev);
-	ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state);
-
-	return 0;
-}
-
-static int corgi_ssp_resume(struct platform_device *dev)
-{
-	if (ssp_machinfo->cs_lcdcon >= 0)
-		GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);  /* High - Disable LCD Control/Timing Gen */
-	if (ssp_machinfo->cs_max1111 >= 0)
-		GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
-	if (ssp_machinfo->cs_ads7846 >= 0)
-		GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
-	ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
-	ssp_enable(&corgi_ssp_dev);
-
-	return 0;
-}
-
-static struct platform_driver corgissp_driver = {
-	.probe		= corgi_ssp_probe,
-	.remove		= corgi_ssp_remove,
-	.suspend	= corgi_ssp_suspend,
-	.resume		= corgi_ssp_resume,
-	.driver		= {
-		.name	= "corgi-ssp",
-	},
-};
-
-int __init corgi_ssp_init(void)
-{
-	return platform_driver_register(&corgissp_driver);
-}
-
-arch_initcall(corgi_ssp_init);
diff --git a/arch/arm/mach-pxa/cpu-pxa.c b/arch/arm/mach-pxa/cpufreq-pxa2xx.c
similarity index 99%
rename from arch/arm/mach-pxa/cpu-pxa.c
rename to arch/arm/mach-pxa/cpufreq-pxa2xx.c
index 6f5569b..d82528e 100644
--- a/arch/arm/mach-pxa/cpu-pxa.c
+++ b/arch/arm/mach-pxa/cpufreq-pxa2xx.c
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/mach-pxa/cpu-pxa.c
+ *  linux/arch/arm/mach-pxa/cpufreq-pxa2xx.c
  *
  *  Copyright (C) 2002,2003 Intrinsyc Software
  *
diff --git a/arch/arm/mach-pxa/cpufreq-pxa3xx.c b/arch/arm/mach-pxa/cpufreq-pxa3xx.c
new file mode 100644
index 0000000..1ea0c9c
--- /dev/null
+++ b/arch/arm/mach-pxa/cpufreq-pxa3xx.c
@@ -0,0 +1,258 @@
+/*
+ * linux/arch/arm/mach-pxa/cpufreq-pxa3xx.c
+ *
+ * Copyright (C) 2008 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+
+#include <mach/hardware.h>
+#include <mach/pxa-regs.h>
+#include <mach/pxa3xx-regs.h>
+
+#include "generic.h"
+
+#define HSS_104M	(0)
+#define HSS_156M	(1)
+#define HSS_208M	(2)
+#define HSS_312M	(3)
+
+#define SMCFS_78M	(0)
+#define SMCFS_104M	(2)
+#define SMCFS_208M	(5)
+
+#define SFLFS_104M	(0)
+#define SFLFS_156M	(1)
+#define SFLFS_208M	(2)
+#define SFLFS_312M	(3)
+
+#define XSPCLK_156M	(0)
+#define XSPCLK_NONE	(3)
+
+#define DMCFS_26M	(0)
+#define DMCFS_260M	(3)
+
+struct pxa3xx_freq_info {
+	unsigned int cpufreq_mhz;
+	unsigned int core_xl : 5;
+	unsigned int core_xn : 3;
+	unsigned int hss : 2;
+	unsigned int dmcfs : 2;
+	unsigned int smcfs : 3;
+	unsigned int sflfs : 2;
+	unsigned int df_clkdiv : 3;
+
+	int	vcc_core;	/* in mV */
+	int	vcc_sram;	/* in mV */
+};
+
+#define OP(cpufreq, _xl, _xn, _hss, _dmc, _smc, _sfl, _dfi, vcore, vsram) \
+{									\
+	.cpufreq_mhz	= cpufreq,					\
+	.core_xl	= _xl,						\
+	.core_xn	= _xn,						\
+	.hss		= HSS_##_hss##M,				\
+	.dmcfs		= DMCFS_##_dmc##M,				\
+	.smcfs		= SMCFS_##_smc##M,				\
+	.sflfs		= SFLFS_##_sfl##M,				\
+	.df_clkdiv	= _dfi,						\
+	.vcc_core	= vcore,					\
+	.vcc_sram	= vsram,					\
+}
+
+static struct pxa3xx_freq_info pxa300_freqs[] = {
+	/*  CPU XL XN  HSS DMEM SMEM SRAM DFI VCC_CORE VCC_SRAM */
+	OP(104,  8, 1, 104, 260,  78, 104, 3, 1000, 1100), /* 104MHz */
+	OP(208, 16, 1, 104, 260, 104, 156, 2, 1000, 1100), /* 208MHz */
+	OP(416, 16, 2, 156, 260, 104, 208, 2, 1100, 1200), /* 416MHz */
+	OP(624, 24, 2, 208, 260, 208, 312, 3, 1375, 1400), /* 624MHz */
+};
+
+static struct pxa3xx_freq_info pxa320_freqs[] = {
+	/*  CPU XL XN  HSS DMEM SMEM SRAM DFI VCC_CORE VCC_SRAM */
+	OP(104,  8, 1, 104, 260,  78, 104, 3, 1000, 1100), /* 104MHz */
+	OP(208, 16, 1, 104, 260, 104, 156, 2, 1000, 1100), /* 208MHz */
+	OP(416, 16, 2, 156, 260, 104, 208, 2, 1100, 1200), /* 416MHz */
+	OP(624, 24, 2, 208, 260, 208, 312, 3, 1375, 1400), /* 624MHz */
+	OP(806, 31, 2, 208, 260, 208, 312, 3, 1400, 1400), /* 806MHz */
+};
+
+static unsigned int pxa3xx_freqs_num;
+static struct pxa3xx_freq_info *pxa3xx_freqs;
+static struct cpufreq_frequency_table *pxa3xx_freqs_table;
+
+static int setup_freqs_table(struct cpufreq_policy *policy,
+			     struct pxa3xx_freq_info *freqs, int num)
+{
+	struct cpufreq_frequency_table *table;
+	int i;
+
+	table = kzalloc((num + 1) * sizeof(*table), GFP_KERNEL);
+	if (table == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < num; i++) {
+		table[i].index = i;
+		table[i].frequency = freqs[i].cpufreq_mhz * 1000;
+	}
+	table[num].frequency = i;
+	table[num].frequency = CPUFREQ_TABLE_END;
+
+	pxa3xx_freqs = freqs;
+	pxa3xx_freqs_num = num;
+	pxa3xx_freqs_table = table;
+
+	return cpufreq_frequency_table_cpuinfo(policy, table);
+}
+
+static void __update_core_freq(struct pxa3xx_freq_info *info)
+{
+	uint32_t mask = ACCR_XN_MASK | ACCR_XL_MASK;
+	uint32_t accr = ACCR;
+	uint32_t xclkcfg;
+
+	accr &= ~(ACCR_XN_MASK | ACCR_XL_MASK | ACCR_XSPCLK_MASK);
+	accr |= ACCR_XN(info->core_xn) | ACCR_XL(info->core_xl);
+
+	/* No clock until core PLL is re-locked */
+	accr |= ACCR_XSPCLK(XSPCLK_NONE);
+
+	xclkcfg = (info->core_xn == 2) ? 0x3 : 0x2;	/* turbo bit */
+
+	ACCR = accr;
+	__asm__("mcr p14, 0, %0, c6, c0, 0\n" : : "r"(xclkcfg));
+
+	while ((ACSR & mask) != (accr & mask))
+		cpu_relax();
+}
+
+static void __update_bus_freq(struct pxa3xx_freq_info *info)
+{
+	uint32_t mask;
+	uint32_t accr = ACCR;
+
+	mask = ACCR_SMCFS_MASK | ACCR_SFLFS_MASK | ACCR_HSS_MASK |
+		ACCR_DMCFS_MASK;
+
+	accr &= ~mask;
+	accr |= ACCR_SMCFS(info->smcfs) | ACCR_SFLFS(info->sflfs) |
+		ACCR_HSS(info->hss) | ACCR_DMCFS(info->dmcfs);
+
+	ACCR = accr;
+
+	while ((ACSR & mask) != (accr & mask))
+		cpu_relax();
+}
+
+static int pxa3xx_cpufreq_verify(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, pxa3xx_freqs_table);
+}
+
+static unsigned int pxa3xx_cpufreq_get(unsigned int cpu)
+{
+	return get_clk_frequency_khz(0);
+}
+
+static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy,
+			      unsigned int target_freq,
+			      unsigned int relation)
+{
+	struct pxa3xx_freq_info *next;
+	struct cpufreq_freqs freqs;
+	unsigned long flags;
+	int idx;
+
+	if (policy->cpu != 0)
+		return -EINVAL;
+
+	/* Lookup the next frequency */
+	if (cpufreq_frequency_table_target(policy, pxa3xx_freqs_table,
+				target_freq, relation, &idx))
+		return -EINVAL;
+
+	next = &pxa3xx_freqs[idx];
+
+	freqs.old = policy->cur;
+	freqs.new = next->cpufreq_mhz * 1000;
+	freqs.cpu = policy->cpu;
+
+	pr_debug("CPU frequency from %d MHz to %d MHz%s\n",
+			freqs.old / 1000, freqs.new / 1000,
+			(freqs.old == freqs.new) ? " (skipped)" : "");
+
+	if (freqs.old == target_freq)
+		return 0;
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	local_irq_save(flags);
+	__update_core_freq(next);
+	__update_bus_freq(next);
+	local_irq_restore(flags);
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+	return 0;
+}
+
+static __init int pxa3xx_cpufreq_init(struct cpufreq_policy *policy)
+{
+	int ret = -EINVAL;
+
+	/* set default policy and cpuinfo */
+	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+	policy->cpuinfo.min_freq = 104000;
+	policy->cpuinfo.max_freq = (cpu_is_pxa320()) ? 806000 : 624000;
+	policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
+	policy->cur = policy->min = policy->max = get_clk_frequency_khz(0);
+
+	if (cpu_is_pxa300() || cpu_is_pxa310())
+		ret = setup_freqs_table(policy, ARRAY_AND_SIZE(pxa300_freqs));
+
+	if (cpu_is_pxa320())
+		ret = setup_freqs_table(policy, ARRAY_AND_SIZE(pxa320_freqs));
+
+	if (ret) {
+		pr_err("failed to setup frequency table\n");
+		return ret;
+	}
+
+	pr_info("CPUFREQ support for PXA3xx initialized\n");
+	return 0;
+}
+
+static struct cpufreq_driver pxa3xx_cpufreq_driver = {
+	.verify		= pxa3xx_cpufreq_verify,
+	.target		= pxa3xx_cpufreq_set,
+	.init		= pxa3xx_cpufreq_init,
+	.get		= pxa3xx_cpufreq_get,
+	.name		= "pxa3xx-cpufreq",
+};
+
+static int __init cpufreq_init(void)
+{
+	if (cpu_is_pxa3xx())
+		return cpufreq_register_driver(&pxa3xx_cpufreq_driver);
+
+	return 0;
+}
+module_init(cpufreq_init);
+
+static void __exit cpufreq_exit(void)
+{
+	cpufreq_unregister_driver(&pxa3xx_cpufreq_driver);
+}
+module_exit(cpufreq_exit);
+
+MODULE_DESCRIPTION("CPU frequency scaling driver for PXA3xx");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h
index 887c738..bb04af4 100644
--- a/arch/arm/mach-pxa/devices.h
+++ b/arch/arm/mach-pxa/devices.h
@@ -32,5 +32,6 @@
 extern struct platform_device pxa27x_device_pwm1;
 
 extern struct platform_device pxa3xx_device_nand;
+extern struct platform_device pxa3xx_device_i2c_power;
 
 void __init pxa_register_device(struct platform_device *dev, void *data);
diff --git a/arch/arm/mach-pxa/e330.c b/arch/arm/mach-pxa/e330.c
new file mode 100644
index 0000000..d488ede
--- /dev/null
+++ b/arch/arm/mach-pxa/e330.c
@@ -0,0 +1,43 @@
+/*
+ * Hardware definitions for the Toshiba eseries PDAs
+ *
+ * Copyright (c) 2003 Ian Molton <spyro@f2s.com>
+ *
+ * This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/setup.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <mach/mfp-pxa25x.h>
+#include <mach/hardware.h>
+#include <mach/udc.h>
+
+#include "generic.h"
+#include "eseries.h"
+
+static void __init e330_init(void)
+{
+	pxa_set_udc_info(&e7xx_udc_mach_info);
+}
+
+MACHINE_START(E330, "Toshiba e330")
+	/* Maintainer: Ian Molton (spyro@f2s.com) */
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa25x_init_irq,
+	.fixup		= eseries_fixup,
+	.init_machine	= e330_init,
+	.timer		= &pxa_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-pxa/e350.c b/arch/arm/mach-pxa/e350.c
new file mode 100644
index 0000000..8ecbc54
--- /dev/null
+++ b/arch/arm/mach-pxa/e350.c
@@ -0,0 +1,43 @@
+/*
+ * Hardware definitions for the Toshiba eseries PDAs
+ *
+ * Copyright (c) 2003 Ian Molton <spyro@f2s.com>
+ *
+ * This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/setup.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <mach/mfp-pxa25x.h>
+#include <mach/hardware.h>
+#include <mach/udc.h>
+
+#include "generic.h"
+#include "eseries.h"
+
+static void __init e350_init(void)
+{
+	pxa_set_udc_info(&e7xx_udc_mach_info);
+}
+
+MACHINE_START(E350, "Toshiba e350")
+	/* Maintainer: Ian Molton (spyro@f2s.com) */
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa25x_init_irq,
+	.fixup		= eseries_fixup,
+	.init_machine	= e350_init,
+	.timer		= &pxa_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-pxa/e400.c b/arch/arm/mach-pxa/e400.c
new file mode 100644
index 0000000..544bbaa
--- /dev/null
+++ b/arch/arm/mach-pxa/e400.c
@@ -0,0 +1,94 @@
+/*
+ * Hardware definitions for the Toshiba eseries PDAs
+ *
+ * Copyright (c) 2003 Ian Molton <spyro@f2s.com>
+ *
+ * This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/setup.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <mach/pxa-regs.h>
+#include <mach/mfp-pxa25x.h>
+#include <mach/hardware.h>
+
+#include <mach/pxafb.h>
+#include <mach/udc.h>
+
+#include "generic.h"
+#include "eseries.h"
+
+/* ------------------------ E400 LCD definitions ------------------------ */
+
+static struct pxafb_mode_info e400_pxafb_mode_info = {
+	.pixclock       = 140703,
+	.xres           = 240,
+	.yres           = 320,
+	.bpp            = 16,
+	.hsync_len      = 4,
+	.left_margin    = 28,
+	.right_margin   = 8,
+	.vsync_len      = 3,
+	.upper_margin   = 5,
+	.lower_margin   = 6,
+	.sync           = 0,
+};
+
+static struct pxafb_mach_info e400_pxafb_mach_info = {
+	.modes          = &e400_pxafb_mode_info,
+	.num_modes      = 1,
+	.lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+	.lccr3          = 0,
+	.pxafb_backlight_power  = NULL,
+};
+
+/* ------------------------ E400 MFP config ----------------------------- */
+
+static unsigned long e400_pin_config[] __initdata = {
+	/* Chip selects */
+	GPIO15_nCS_1,   /* CS1 - Flash */
+	GPIO80_nCS_4,   /* CS4 - TMIO */
+
+	/* Clocks */
+	GPIO12_32KHz,
+
+	/* BTUART */
+	GPIO42_BTUART_RXD,
+	GPIO43_BTUART_TXD,
+	GPIO44_BTUART_CTS,
+	GPIO45_GPIO, /* Used by TMIO for #SUSPEND */
+
+	/* wakeup */
+	GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,
+};
+
+/* ---------------------------------------------------------------------- */
+
+static void __init e400_init(void)
+{
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(e400_pin_config));
+	set_pxa_fb_info(&e400_pxafb_mach_info);
+	pxa_set_udc_info(&e7xx_udc_mach_info);
+}
+
+MACHINE_START(E400, "Toshiba e400")
+	/* Maintainer: Ian Molton (spyro@f2s.com) */
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa25x_init_irq,
+	.fixup		= eseries_fixup,
+	.init_machine	= e400_init,
+	.timer		= &pxa_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-pxa/e400_lcd.c b/arch/arm/mach-pxa/e400_lcd.c
deleted file mode 100644
index 2638841..0000000
--- a/arch/arm/mach-pxa/e400_lcd.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * e400_lcd.c
- *
- * (c) 2005 Ian Molton <spyro@f2s.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include <asm/mach-types.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxafb.h>
-
-static struct pxafb_mode_info e400_pxafb_mode_info = {
-	.pixclock       = 140703,
-	.xres           = 240,
-	.yres           = 320,
-	.bpp            = 16,
-	.hsync_len      = 4,
-	.left_margin    = 28,
-	.right_margin   = 8,
-	.vsync_len      = 3,
-	.upper_margin   = 5,
-	.lower_margin   = 6,
-	.sync           = 0,
-};
-
-static struct pxafb_mach_info e400_pxafb_mach_info = {
-	.modes          = &e400_pxafb_mode_info,
-	.num_modes      = 1,
-	.lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-	.lccr3          = 0,
-	.pxafb_backlight_power  = NULL,
-};
-
-static int __init e400_lcd_init(void)
-{
-	if (!machine_is_e400())
-		return -ENODEV;
-
-	set_pxa_fb_info(&e400_pxafb_mach_info);
-	return 0;
-}
-
-module_init(e400_lcd_init);
-
-MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
-MODULE_DESCRIPTION("e400 lcd driver");
-MODULE_LICENSE("GPLv2");
-
diff --git a/arch/arm/mach-pxa/e740.c b/arch/arm/mach-pxa/e740.c
new file mode 100644
index 0000000..c57a15b
--- /dev/null
+++ b/arch/arm/mach-pxa/e740.c
@@ -0,0 +1,169 @@
+/*
+ * Hardware definitions for the Toshiba eseries PDAs
+ *
+ * Copyright (c) 2003 Ian Molton <spyro@f2s.com>
+ *
+ * This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+
+#include <video/w100fb.h>
+
+#include <asm/setup.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <mach/mfp-pxa25x.h>
+#include <mach/hardware.h>
+#include <mach/udc.h>
+
+#include "generic.h"
+#include "eseries.h"
+
+
+/* ------------------------ e740 video support --------------------------- */
+
+static struct w100_gen_regs e740_lcd_regs = {
+	.lcd_format =            0x00008023,
+	.lcdd_cntl1 =            0x0f000000,
+	.lcdd_cntl2 =            0x0003ffff,
+	.genlcd_cntl1 =          0x00ffff03,
+	.genlcd_cntl2 =          0x003c0f03,
+	.genlcd_cntl3 =          0x000143aa,
+};
+
+static struct w100_mode e740_lcd_mode = {
+	.xres            = 240,
+	.yres            = 320,
+	.left_margin     = 20,
+	.right_margin    = 28,
+	.upper_margin    = 9,
+	.lower_margin    = 8,
+	.crtc_ss         = 0x80140013,
+	.crtc_ls         = 0x81150110,
+	.crtc_gs         = 0x80050005,
+	.crtc_vpos_gs    = 0x000a0009,
+	.crtc_rev        = 0x0040010a,
+	.crtc_dclk       = 0xa906000a,
+	.crtc_gclk       = 0x80050108,
+	.crtc_goe        = 0x80050108,
+	.pll_freq        = 57,
+	.pixclk_divider         = 4,
+	.pixclk_divider_rotated = 4,
+	.pixclk_src     = CLK_SRC_XTAL,
+	.sysclk_divider  = 1,
+	.sysclk_src     = CLK_SRC_PLL,
+	.crtc_ps1_active =       0x41060010,
+};
+
+static struct w100_gpio_regs e740_w100_gpio_info = {
+	.init_data1 = 0x21002103,
+	.gpio_dir1  = 0xffffdeff,
+	.gpio_oe1   = 0x03c00643,
+	.init_data2 = 0x003f003f,
+	.gpio_dir2  = 0xffffffff,
+	.gpio_oe2   = 0x000000ff,
+};
+
+static struct w100fb_mach_info e740_fb_info = {
+	.modelist   = &e740_lcd_mode,
+	.num_modes  = 1,
+	.regs       = &e740_lcd_regs,
+	.gpio       = &e740_w100_gpio_info,
+	.xtal_freq = 14318000,
+	.xtal_dbl   = 1,
+};
+
+static struct resource e740_fb_resources[] = {
+	[0] = {
+		.start          = 0x0c000000,
+		.end            = 0x0cffffff,
+		.flags          = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device e740_fb_device = {
+	.name           = "w100fb",
+	.id             = -1,
+	.dev            = {
+		.platform_data  = &e740_fb_info,
+	},
+	.num_resources  = ARRAY_SIZE(e740_fb_resources),
+	.resource       = e740_fb_resources,
+};
+
+/* --------------------------- MFP Pin config -------------------------- */
+
+static unsigned long e740_pin_config[] __initdata = {
+	/* Chip selects */
+	GPIO15_nCS_1,   /* CS1 - Flash */
+	GPIO79_nCS_3,   /* CS3 - IMAGEON */
+	GPIO80_nCS_4,   /* CS4 - TMIO */
+
+	/* Clocks */
+	GPIO12_32KHz,
+
+	/* BTUART */
+	GPIO42_BTUART_RXD,
+	GPIO43_BTUART_TXD,
+	GPIO44_BTUART_CTS,
+	GPIO45_GPIO, /* Used by TMIO for #SUSPEND */
+
+	/* PC Card */
+	GPIO8_GPIO,   /* CD0 */
+	GPIO44_GPIO,  /* CD1 */
+	GPIO11_GPIO,  /* IRQ0 */
+	GPIO6_GPIO,   /* IRQ1 */
+	GPIO27_GPIO,  /* RST0 */
+	GPIO24_GPIO,  /* RST1 */
+	GPIO20_GPIO,  /* PWR0 */
+	GPIO23_GPIO,  /* PWR1 */
+	GPIO48_nPOE,
+	GPIO49_nPWE,
+	GPIO50_nPIOR,
+	GPIO51_nPIOW,
+	GPIO52_nPCE_1,
+	GPIO53_nPCE_2,
+	GPIO54_nPSKTSEL,
+	GPIO55_nPREG,
+	GPIO56_nPWAIT,
+	GPIO57_nIOIS16,
+
+	/* wakeup */
+	GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static struct platform_device *devices[] __initdata = {
+	&e740_fb_device,
+};
+
+static void __init e740_init(void)
+{
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(e740_pin_config));
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+	pxa_set_udc_info(&e7xx_udc_mach_info);
+}
+
+MACHINE_START(E740, "Toshiba e740")
+	/* Maintainer: Ian Molton (spyro@f2s.com) */
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa25x_init_irq,
+	.fixup		= eseries_fixup,
+	.init_machine	= e740_init,
+	.timer		= &pxa_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-pxa/e740_lcd.c b/arch/arm/mach-pxa/e740_lcd.c
deleted file mode 100644
index 26bd599..0000000
--- a/arch/arm/mach-pxa/e740_lcd.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/* e740_lcd.c
- *
- * This file contains the definitions for the LCD timings and functions
- * to control the LCD power / frontlighting via the w100fb driver.
- *
- * (c) 2005 Ian Molton <spyro@f2s.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/fb.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach-types.h>
-
-#include <video/w100fb.h>
-
-/*
-**potential** shutdown routine - to be investigated
-devmem2 0x0c010528 w 0xff3fff00
-devmem2 0x0c010190 w 0x7FFF8000
-devmem2 0x0c0101b0 w 0x00FF0000
-devmem2 0x0c01008c w 0x00000000
-devmem2 0x0c010080 w 0x000000bf
-devmem2 0x0c010098 w 0x00000015
-devmem2 0x0c010088 w 0x4b000204
-devmem2 0x0c010098 w 0x0000001d
-*/
-
-static struct w100_gen_regs e740_lcd_regs = {
-	.lcd_format =            0x00008023,
-	.lcdd_cntl1 =            0x0f000000,
-	.lcdd_cntl2 =            0x0003ffff,
-	.genlcd_cntl1 =          0x00ffff03,
-	.genlcd_cntl2 =          0x003c0f03,
-	.genlcd_cntl3 =          0x000143aa,
-};
-
-static struct w100_mode e740_lcd_mode = {
-	.xres            = 240,
-	.yres            = 320,
-	.left_margin     = 20,
-	.right_margin    = 28,
-	.upper_margin    = 9,
-	.lower_margin    = 8,
-	.crtc_ss         = 0x80140013,
-	.crtc_ls         = 0x81150110,
-	.crtc_gs         = 0x80050005,
-	.crtc_vpos_gs    = 0x000a0009,
-	.crtc_rev        = 0x0040010a,
-	.crtc_dclk       = 0xa906000a,
-	.crtc_gclk       = 0x80050108,
-	.crtc_goe        = 0x80050108,
-	.pll_freq        = 57,
-	.pixclk_divider         = 4,
-	.pixclk_divider_rotated = 4,
-	.pixclk_src     = CLK_SRC_XTAL,
-	.sysclk_divider  = 1,
-	.sysclk_src     = CLK_SRC_PLL,
-	.crtc_ps1_active =       0x41060010,
-};
-
-
-static struct w100_gpio_regs e740_w100_gpio_info = {
-	.init_data1 = 0x21002103,
-	.gpio_dir1  = 0xffffdeff,
-	.gpio_oe1   = 0x03c00643,
-	.init_data2 = 0x003f003f,
-	.gpio_dir2  = 0xffffffff,
-	.gpio_oe2   = 0x000000ff,
-};
-
-static struct w100fb_mach_info e740_fb_info = {
-	.modelist   = &e740_lcd_mode,
-	.num_modes  = 1,
-	.regs       = &e740_lcd_regs,
-	.gpio       = &e740_w100_gpio_info,
-	.xtal_freq = 14318000,
-	.xtal_dbl   = 1,
-};
-
-static struct resource e740_fb_resources[] = {
-	[0] = {
-		.start          = 0x0c000000,
-		.end            = 0x0cffffff,
-		.flags          = IORESOURCE_MEM,
-	},
-};
-
-/* ----------------------- device declarations -------------------------- */
-
-
-static struct platform_device e740_fb_device = {
-	.name           = "w100fb",
-	.id             = -1,
-	.dev            = {
-		.platform_data  = &e740_fb_info,
-	},
-	.num_resources  = ARRAY_SIZE(e740_fb_resources),
-	.resource       = e740_fb_resources,
-};
-
-static int e740_lcd_init(void)
-{
-	int ret;
-
-	if (!machine_is_e740())
-		return -ENODEV;
-
-	return platform_device_register(&e740_fb_device);
-}
-
-module_init(e740_lcd_init);
-
-MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
-MODULE_DESCRIPTION("e740 lcd driver");
-MODULE_LICENSE("GPLv2");
diff --git a/arch/arm/mach-pxa/e750_lcd.c b/arch/arm/mach-pxa/e750.c
similarity index 61%
rename from arch/arm/mach-pxa/e750_lcd.c
rename to arch/arm/mach-pxa/e750.c
index 75edc3b..640e738 100644
--- a/arch/arm/mach-pxa/e750_lcd.c
+++ b/arch/arm/mach-pxa/e750.c
@@ -1,26 +1,36 @@
-/* e750_lcd.c
+/*
+ * Hardware definitions for the Toshiba eseries PDAs
  *
- * This file contains the definitions for the LCD timings and functions
- * to control the LCD power / frontlighting via the w100fb driver.
+ * Copyright (c) 2003 Ian Molton <spyro@f2s.com>
  *
- * (c) 2005 Ian Molton <spyro@f2s.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  *
  */
 
-#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
 #include <linux/device.h>
-#include <linux/fb.h>
-#include <linux/err.h>
 #include <linux/platform_device.h>
-
-#include <asm/mach-types.h>
+#include <linux/fb.h>
 
 #include <video/w100fb.h>
 
+#include <asm/setup.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <mach/mfp-pxa25x.h>
+#include <mach/hardware.h>
+#include <mach/udc.h>
+
+#include "generic.h"
+#include "eseries.h"
+
+/* ---------------------- E750 LCD definitions -------------------- */
+
 static struct w100_gen_regs e750_lcd_regs = {
 	.lcd_format =            0x00008003,
 	.lcdd_cntl1 =            0x00000000,
@@ -54,7 +64,6 @@
 	.sysclk_src     = CLK_SRC_PLL,
 };
 
-
 static struct w100_gpio_regs e750_w100_gpio_info = {
 	.init_data1 = 0x01192f1b,
 	.gpio_dir1  = 0xd5ffdeff,
@@ -81,9 +90,6 @@
 	},
 };
 
-/* ----------------------- device declarations -------------------------- */
-
-
 static struct platform_device e750_fb_device = {
 	.name           = "w100fb",
 	.id             = -1,
@@ -94,16 +100,27 @@
 	.resource       = e750_fb_resources,
 };
 
-static int e750_lcd_init(void)
-{
-	if (!machine_is_e750())
-		return -ENODEV;
+/* ----------------------------------------------------------------------- */
 
-	return platform_device_register(&e750_fb_device);
+static struct platform_device *devices[] __initdata = {
+	&e750_fb_device,
+};
+
+static void __init e750_init(void)
+{
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+	pxa_set_udc_info(&e7xx_udc_mach_info);
 }
 
-module_init(e750_lcd_init);
+MACHINE_START(E750, "Toshiba e750")
+	/* Maintainer: Ian Molton (spyro@f2s.com) */
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa25x_init_irq,
+	.fixup		= eseries_fixup,
+	.init_machine	= e750_init,
+	.timer		= &pxa_timer,
+MACHINE_END
 
-MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
-MODULE_DESCRIPTION("e750 lcd driver");
-MODULE_LICENSE("GPLv2");
diff --git a/arch/arm/mach-pxa/e800_lcd.c b/arch/arm/mach-pxa/e800.c
similarity index 65%
rename from arch/arm/mach-pxa/e800_lcd.c
rename to arch/arm/mach-pxa/e800.c
index e6aeab0e..a293e09 100644
--- a/arch/arm/mach-pxa/e800_lcd.c
+++ b/arch/arm/mach-pxa/e800.c
@@ -1,26 +1,37 @@
-/* e800_lcd.c
+/*
+ * Hardware definitions for the Toshiba eseries PDAs
  *
- * This file contains the definitions for the LCD timings and functions
- * to control the LCD power / frontlighting via the w100fb driver.
+ * Copyright (c) 2003 Ian Molton <spyro@f2s.com>
  *
- * (c) 2005 Ian Molton <spyro@f2s.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  *
  */
 
-#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
 #include <linux/device.h>
-#include <linux/fb.h>
-#include <linux/err.h>
 #include <linux/platform_device.h>
-
-#include <asm/mach-types.h>
+#include <linux/fb.h>
 
 #include <video/w100fb.h>
 
+#include <asm/setup.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <mach/mfp-pxa25x.h>
+#include <mach/hardware.h>
+#include <mach/eseries-gpio.h>
+#include <mach/udc.h>
+
+#include "generic.h"
+#include "eseries.h"
+
+/* ------------------------ e800 LCD definitions ------------------------- */
+
 static struct w100_gen_regs e800_lcd_regs = {
 	.lcd_format =            0x00008003,
 	.lcdd_cntl1 =            0x02a00000,
@@ -71,8 +82,8 @@
 		.crtc_goe        = 0x80cc0015,
 		.crtc_ps1_active = 0x00000000,
 		.pll_freq        = 100,
-		.pixclk_divider         = 6, /* Wince uses 14 which gives a 7MHz pclk. */
-		.pixclk_divider_rotated = 6, /* we want a 14MHz one (much nicer to look at) */
+		.pixclk_divider         = 6, /* Wince uses 14 which gives a */
+		.pixclk_divider_rotated = 6, /* 7MHz Pclk. We use a 14MHz one */
 		.pixclk_src     = CLK_SRC_PLL,
 		.sysclk_divider  = 0,
 		.sysclk_src     = CLK_SRC_PLL,
@@ -131,9 +142,6 @@
 	},
 };
 
-/* ----------------------- device declarations -------------------------- */
-
-
 static struct platform_device e800_fb_device = {
 	.name           = "w100fb",
 	.id             = -1,
@@ -144,16 +152,35 @@
 	.resource       = e800_fb_resources,
 };
 
-static int e800_lcd_init(void)
-{
-	if (!machine_is_e800())
-		return -ENODEV;
+/* --------------------------- UDC definitions --------------------------- */
 
-	return platform_device_register(&e800_fb_device);
+static struct pxa2xx_udc_mach_info e800_udc_mach_info = {
+	.gpio_vbus   = GPIO_E800_USB_DISC,
+	.gpio_pullup = GPIO_E800_USB_PULLUP,
+	.gpio_pullup_inverted = 1
+};
+
+/* ----------------------------------------------------------------------- */
+
+static struct platform_device *devices[] __initdata = {
+	&e800_fb_device,
+};
+
+static void __init e800_init(void)
+{
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+	pxa_set_udc_info(&e800_udc_mach_info);
 }
 
-module_init(e800_lcd_init);
+MACHINE_START(E800, "Toshiba e800")
+	/* Maintainer: Ian Molton (spyro@f2s.com) */
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa25x_init_irq,
+	.fixup		= eseries_fixup,
+	.init_machine	= e800_init,
+	.timer		= &pxa_timer,
+MACHINE_END
 
-MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
-MODULE_DESCRIPTION("e800 lcd driver");
-MODULE_LICENSE("GPLv2");
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
index 7a0a681..f5ed803 100644
--- a/arch/arm/mach-pxa/em-x270.c
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -373,10 +373,6 @@
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
 static int em_x270_ohci_init(struct device *dev)
 {
-	/* Set the Power Control Polarity Low */
-	UHCHR = (UHCHR | UHCHR_PCPL) &
-		~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE);
-
 	/* enable port 2 transiever */
 	UP2OCR = UP2OCR_HXS | UP2OCR_HXOE;
 
@@ -385,6 +381,7 @@
 
 static struct pxaohci_platform_data em_x270_ohci_platform_data = {
 	.port_mode	= PMM_PERPORT_MODE,
+	.flags		= ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
 	.init		= em_x270_ohci_init,
 };
 
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
index 001a252..d28849b 100644
--- a/arch/arm/mach-pxa/eseries.c
+++ b/arch/arm/mach-pxa/eseries.c
@@ -19,68 +19,13 @@
 
 #include <mach/mfp-pxa25x.h>
 #include <mach/hardware.h>
+#include <mach/eseries-gpio.h>
+#include <mach/udc.h>
 
 #include "generic.h"
 
-static unsigned long e740_pin_config[] __initdata = {
-	/* Chip selects */
-	GPIO15_nCS_1,   /* CS1 - Flash */
-	GPIO79_nCS_3,   /* CS3 - IMAGEON */
-	GPIO80_nCS_4,   /* CS4 - TMIO */
-
-	/* Clocks */
-	GPIO12_32KHz,
-
-	/* BTUART */
-	GPIO42_BTUART_RXD,
-	GPIO43_BTUART_TXD,
-	GPIO44_BTUART_CTS,
-	GPIO45_GPIO, /* Used by TMIO for #SUSPEND */
-
-	/* PC Card */
-	GPIO8_GPIO,   /* CD0 */
-	GPIO44_GPIO,  /* CD1 */
-	GPIO11_GPIO,  /* IRQ0 */
-	GPIO6_GPIO,   /* IRQ1 */
-	GPIO27_GPIO,  /* RST0 */
-	GPIO24_GPIO,  /* RST1 */
-	GPIO20_GPIO,  /* PWR0 */
-	GPIO23_GPIO,  /* PWR1 */
-	GPIO48_nPOE,
-	GPIO49_nPWE,
-	GPIO50_nPIOR,
-	GPIO51_nPIOW,
-	GPIO52_nPCE_1,
-	GPIO53_nPCE_2,
-	GPIO54_nPSKTSEL,
-	GPIO55_nPREG,
-	GPIO56_nPWAIT,
-	GPIO57_nIOIS16,
-
-	/* wakeup */
-	GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,
-};
-
-static unsigned long e400_pin_config[] __initdata = {
-	/* Chip selects */
-	GPIO15_nCS_1,   /* CS1 - Flash */
-	GPIO80_nCS_4,   /* CS4 - TMIO */
-
-	/* Clocks */
-	GPIO12_32KHz,
-
-	/* BTUART */
-	GPIO42_BTUART_RXD,
-	GPIO43_BTUART_TXD,
-	GPIO44_BTUART_CTS,
-	GPIO45_GPIO, /* Used by TMIO for #SUSPEND */
-
-	/* wakeup */
-	GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,
-};
-
 /* Only e800 has 128MB RAM */
-static void __init eseries_fixup(struct machine_desc *desc,
+void __init eseries_fixup(struct machine_desc *desc,
 	struct tag *tags, char **cmdline, struct meminfo *mi)
 {
 	mi->nr_banks=1;
@@ -92,95 +37,9 @@
 		mi->bank[0].size = (64*1024*1024);
 }
 
-static void __init e740_init(void)
-{
-	pxa2xx_mfp_config(ARRAY_AND_SIZE(e740_pin_config));
-}
-
-static void __init e400_init(void)
-{
-	pxa2xx_mfp_config(ARRAY_AND_SIZE(e400_pin_config));
-}
-
-/* e-series machine definitions */
-
-#ifdef CONFIG_MACH_E330
-MACHINE_START(E330, "Toshiba e330")
-	/* Maintainer: Ian Molton (spyro@f2s.com) */
-	.phys_io	= 0x40000000,
-	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
-	.boot_params	= 0xa0000100,
-	.map_io		= pxa_map_io,
-	.init_irq	= pxa25x_init_irq,
-	.fixup		= eseries_fixup,
-	.timer		= &pxa_timer,
-MACHINE_END
-#endif
-
-#ifdef CONFIG_MACH_E350
-MACHINE_START(E350, "Toshiba e350")
-	/* Maintainer: Ian Molton (spyro@f2s.com) */
-	.phys_io	= 0x40000000,
-	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
-	.boot_params	= 0xa0000100,
-	.map_io		= pxa_map_io,
-	.init_irq	= pxa25x_init_irq,
-	.fixup		= eseries_fixup,
-	.timer		= &pxa_timer,
-MACHINE_END
-#endif
-
-#ifdef CONFIG_MACH_E740
-MACHINE_START(E740, "Toshiba e740")
-	/* Maintainer: Ian Molton (spyro@f2s.com) */
-	.phys_io	= 0x40000000,
-	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
-	.boot_params	= 0xa0000100,
-	.map_io		= pxa_map_io,
-	.init_irq	= pxa25x_init_irq,
-	.fixup		= eseries_fixup,
-	.init_machine	= e740_init,
-	.timer		= &pxa_timer,
-MACHINE_END
-#endif
-
-#ifdef CONFIG_MACH_E750
-MACHINE_START(E750, "Toshiba e750")
-	/* Maintainer: Ian Molton (spyro@f2s.com) */
-	.phys_io	= 0x40000000,
-	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
-	.boot_params	= 0xa0000100,
-	.map_io		= pxa_map_io,
-	.init_irq	= pxa25x_init_irq,
-	.fixup		= eseries_fixup,
-	.timer		= &pxa_timer,
-MACHINE_END
-#endif
-
-#ifdef CONFIG_MACH_E400
-MACHINE_START(E400, "Toshiba e400")
-	/* Maintainer: Ian Molton (spyro@f2s.com) */
-	.phys_io	= 0x40000000,
-	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
-	.boot_params	= 0xa0000100,
-	.map_io		= pxa_map_io,
-	.init_irq	= pxa25x_init_irq,
-	.fixup		= eseries_fixup,
-	.init_machine	= e400_init,
-	.timer		= &pxa_timer,
-MACHINE_END
-#endif
-
-#ifdef CONFIG_MACH_E800
-MACHINE_START(E800, "Toshiba e800")
-	/* Maintainer: Ian Molton (spyro@f2s.com) */
-	.phys_io	= 0x40000000,
-	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
-	.boot_params	= 0xa0000100,
-	.map_io		= pxa_map_io,
-	.init_irq	= pxa25x_init_irq,
-	.fixup		= eseries_fixup,
-	.timer		= &pxa_timer,
-MACHINE_END
-#endif
+struct pxa2xx_udc_mach_info e7xx_udc_mach_info = {
+	.gpio_vbus   = GPIO_E7XX_USB_DISC,
+	.gpio_pullup = GPIO_E7XX_USB_PULLUP,
+	.gpio_pullup_inverted = 1
+};
 
diff --git a/arch/arm/mach-pxa/eseries.h b/arch/arm/mach-pxa/eseries.h
new file mode 100644
index 0000000..a83f88d
--- /dev/null
+++ b/arch/arm/mach-pxa/eseries.h
@@ -0,0 +1,4 @@
+void __init eseries_fixup(struct machine_desc *desc,
+	struct tag *tags, char **cmdline, struct meminfo *mi);
+
+extern struct pxa2xx_udc_mach_info e7xx_udc_mach_info;
diff --git a/arch/arm/mach-pxa/eseries_udc.c b/arch/arm/mach-pxa/eseries_udc.c
deleted file mode 100644
index d622c04..0000000
--- a/arch/arm/mach-pxa/eseries_udc.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * UDC functions for the Toshiba e-series PDAs
- *
- * Copyright (c) Ian Molton 2003
- *
- * This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-
-#include <mach/udc.h>
-#include <mach/eseries-gpio.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-#include <asm/mach/map.h>
-#include <asm/domain.h>
-
-/* local PXA generic code */
-#include "generic.h"
-
-static struct pxa2xx_udc_mach_info e7xx_udc_mach_info = {
-	.gpio_vbus   = GPIO_E7XX_USB_DISC,
-	.gpio_pullup = GPIO_E7XX_USB_PULLUP,
-	.gpio_pullup_inverted = 1
-};
-
-static struct pxa2xx_udc_mach_info e800_udc_mach_info = {
-	.gpio_vbus   = GPIO_E800_USB_DISC,
-	.gpio_pullup = GPIO_E800_USB_PULLUP,
-	.gpio_pullup_inverted = 1
-};
-
-static int __init eseries_udc_init(void)
-{
-	if (machine_is_e330() || machine_is_e350() ||
-	    machine_is_e740() || machine_is_e750() ||
-	    machine_is_e400())
-		pxa_set_udc_info(&e7xx_udc_mach_info);
-	else if (machine_is_e800())
-		pxa_set_udc_info(&e800_udc_mach_info);
-
-	return 0;
-}
-
-module_init(eseries_udc_init);
-
-MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
-MODULE_DESCRIPTION("eseries UDC support");
-MODULE_LICENSE("GPLv2");
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index ceaed00..85ed0b3 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -46,7 +46,7 @@
  */
 unsigned int get_clk_frequency_khz(int info)
 {
-	if (cpu_is_pxa21x() || cpu_is_pxa25x())
+	if (cpu_is_pxa25x())
 		return pxa25x_get_clk_frequency_khz(info);
 	else if (cpu_is_pxa27x())
 		return pxa27x_get_clk_frequency_khz(info);
@@ -60,7 +60,7 @@
  */
 unsigned int get_memclk_frequency_10khz(void)
 {
-	if (cpu_is_pxa21x() || cpu_is_pxa25x())
+	if (cpu_is_pxa25x())
 		return pxa25x_get_memclk_frequency_10khz();
 	else if (cpu_is_pxa27x())
 		return pxa27x_get_memclk_frequency_10khz();
@@ -88,11 +88,6 @@
 		.pfn		= __phys_to_pfn(0x48000000),
 		.length		= 0x00200000,
 		.type		= MT_DEVICE
-	}, {	/* USB host */
-		.virtual	=  0xf8000000,
-		.pfn		= __phys_to_pfn(0x4c000000),
-		.length		= 0x00100000,
-		.type		= MT_DEVICE
 	}, {	/* Camera */
 		.virtual	=  0xfa000000,
 		.pfn		= __phys_to_pfn(0x50000000),
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index 041c048..dc876a8 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -65,4 +65,5 @@
 
 extern struct sysdev_class pxa_irq_sysclass;
 extern struct sysdev_class pxa_gpio_sysclass;
+extern struct sysdev_class pxa2xx_mfp_sysclass;
 extern struct sysdev_class pxa3xx_mfp_sysclass;
diff --git a/arch/arm/mach-pxa/gpio.c b/arch/arm/mach-pxa/gpio.c
index 07acc1b..14930cf 100644
--- a/arch/arm/mach-pxa/gpio.c
+++ b/arch/arm/mach-pxa/gpio.c
@@ -16,10 +16,10 @@
 #include <linux/module.h>
 #include <linux/irq.h>
 #include <linux/sysdev.h>
+#include <linux/io.h>
 
 #include <asm/gpio.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <mach/pxa-regs.h>
 #include <mach/pxa2xx-gpio.h>
 
@@ -275,7 +275,7 @@
 			loop = 1;
 
 			n = PXA_GPIO_IRQ_BASE + bit;
-			desc_handle_irq(n, irq_desc + n);
+			generic_handle_irq(n);
 
 			bit = find_next_bit(gedr, GEDR_BITS, bit + 1);
 		}
diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c
index c009247..d8962a0 100644
--- a/arch/arm/mach-pxa/gumstix.c
+++ b/arch/arm/mach-pxa/gumstix.c
@@ -20,8 +20,12 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
+#include <linux/delay.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/gpio.h>
+#include <linux/err.h>
+#include <linux/clk.h>
 
 #include <asm/setup.h>
 #include <asm/memory.h>
@@ -40,7 +44,7 @@
 
 #include <mach/pxa-regs.h>
 #include <mach/pxa2xx-regs.h>
-#include <mach/pxa2xx-gpio.h>
+#include <mach/mfp-pxa25x.h>
 
 #include "generic.h"
 
@@ -85,21 +89,8 @@
 };
 
 #ifdef CONFIG_MMC_PXA
-static struct pxamci_platform_data gumstix_mci_platform_data;
-
-static int gumstix_mci_init(struct device *dev, irq_handler_t detect_int,
-				void *data)
-{
-	pxa_gpio_mode(GPIO6_MMCCLK_MD);
-	pxa_gpio_mode(GPIO53_MMCCLK_MD);
-	pxa_gpio_mode(GPIO8_MMCCS0_MD);
-
-	return 0;
-}
-
 static struct pxamci_platform_data gumstix_mci_platform_data = {
 	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
-	.init		= gumstix_mci_init,
 };
 
 static void __init gumstix_mmc_init(void)
@@ -109,11 +100,11 @@
 #else
 static void __init gumstix_mmc_init(void)
 {
-	printk(KERN_INFO "Gumstix mmc disabled\n");
+	pr_debug("Gumstix mmc disabled\n");
 }
 #endif
 
-#ifdef CONFIG_USB_GADGET_PXA2XX
+#ifdef CONFIG_USB_GADGET_PXA25X
 static struct pxa2xx_udc_mach_info gumstix_udc_info __initdata = {
 	.gpio_vbus		= GPIO_GUMSTIX_USB_GPIOn,
 	.gpio_pullup		= GPIO_GUMSTIX_USB_GPIOx,
@@ -126,12 +117,87 @@
 #else
 static void gumstix_udc_init(void)
 {
-	printk(KERN_INFO "Gumstix udc is disabled\n");
+	pr_debug("Gumstix udc is disabled\n");
 }
 #endif
 
+#ifdef CONFIG_BT
+/* Normally, the bootloader would have enabled this 32kHz clock but many
+** boards still have u-boot 1.1.4 so we check if it has been turned on and
+** if not, we turn it on with a warning message. */
+static void gumstix_setup_bt_clock(void)
+{
+	int timeout = 500;
+
+	if (!(OSCC & OSCC_OOK))
+		pr_warning("32kHz clock was not on. Bootloader may need to "
+				"be updated\n");
+	else
+		return;
+
+	OSCC |= OSCC_OON;
+	do {
+		if (OSCC & OSCC_OOK)
+			break;
+		udelay(1);
+	} while (--timeout);
+	if (!timeout)
+		pr_err("Failed to start 32kHz clock\n");
+}
+
+static void __init gumstix_bluetooth_init(void)
+{
+	int err;
+
+	gumstix_setup_bt_clock();
+
+	err = gpio_request(GPIO_GUMSTIX_BTRESET, "BTRST");
+	if (err) {
+		pr_err("gumstix: failed request gpio for bluetooth reset\n");
+		return;
+	}
+
+	err = gpio_direction_output(GPIO_GUMSTIX_BTRESET, 1);
+	if (err) {
+		pr_err("gumstix: can't reset bluetooth\n");
+		return;
+	}
+	gpio_set_value(GPIO_GUMSTIX_BTRESET, 0);
+	udelay(100);
+	gpio_set_value(GPIO_GUMSTIX_BTRESET, 1);
+}
+#else
+static void gumstix_bluetooth_init(void)
+{
+	pr_debug("Gumstix Bluetooth is disabled\n");
+}
+#endif
+
+static unsigned long gumstix_pin_config[] __initdata = {
+	GPIO12_32KHz,
+	/* BTUART */
+	GPIO42_HWUART_RXD,
+	GPIO43_HWUART_TXD,
+	GPIO44_HWUART_CTS,
+	GPIO45_HWUART_RTS,
+	/* MMC */
+	GPIO6_MMC_CLK,
+	GPIO53_MMC_CLK,
+	GPIO8_MMC_CS0,
+	/* these are used by AM200EPD */
+	GPIO51_GPIO,
+	GPIO49_GPIO,
+	GPIO48_GPIO,
+	GPIO32_GPIO,
+	GPIO17_GPIO,
+	GPIO16_GPIO,
+};
+
 static void __init gumstix_init(void)
 {
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(gumstix_pin_config));
+
+	gumstix_bluetooth_init();
 	gumstix_udc_init();
 	gumstix_mmc_init();
 	(void) platform_add_devices(devices, ARRAY_SIZE(devices));
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index 5aa0270..013b15b 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -32,7 +32,7 @@
 #include <asm/mach/map.h>
 
 #include <mach/pxa-regs.h>
-#include <mach/pxa2xx-gpio.h>
+#include <mach/mfp-pxa25x.h>
 #include <mach/idp.h>
 #include <mach/pxafb.h>
 #include <mach/bitfield.h>
@@ -46,6 +46,47 @@
  * - Ethernet interrupt
  */
 
+static unsigned long idp_pin_config[] __initdata = {
+	/* LCD */
+	GPIO58_LCD_LDD_0,
+	GPIO59_LCD_LDD_1,
+	GPIO60_LCD_LDD_2,
+	GPIO61_LCD_LDD_3,
+	GPIO62_LCD_LDD_4,
+	GPIO63_LCD_LDD_5,
+	GPIO64_LCD_LDD_6,
+	GPIO65_LCD_LDD_7,
+	GPIO66_LCD_LDD_8,
+	GPIO67_LCD_LDD_9,
+	GPIO68_LCD_LDD_10,
+	GPIO69_LCD_LDD_11,
+	GPIO70_LCD_LDD_12,
+	GPIO71_LCD_LDD_13,
+	GPIO72_LCD_LDD_14,
+	GPIO73_LCD_LDD_15,
+	GPIO74_LCD_FCLK,
+	GPIO75_LCD_LCLK,
+	GPIO76_LCD_PCLK,
+
+	/* BTUART */
+	GPIO42_BTUART_RXD,
+	GPIO43_BTUART_TXD,
+	GPIO44_BTUART_CTS,
+	GPIO45_BTUART_RTS,
+
+	/* STUART */
+	GPIO46_STUART_RXD,
+	GPIO47_STUART_TXD,
+
+	/* MMC */
+	GPIO6_MMC_CLK,
+	GPIO8_MMC_CS0,
+
+	/* Ethernet */
+	GPIO33_nCS_5,	/* Ethernet CS */
+	GPIO4_GPIO,	/* Ethernet IRQ */
+};
+
 static struct resource smc91x_resources[] = {
 	[0] = {
 		.start	= (IDP_ETH_PHYS + 0x300),
@@ -121,44 +162,28 @@
 	.num_modes      = 1,
 	.cmap_inverse	= 0,
 	.cmap_static	= 0,
-	.lccr0		= LCCR0_SDS,
-	.lccr3		= LCCR3_PCP | LCCR3_Acb(255),
+	.lcd_conn	= LCD_COLOR_DSTN_16BPP | LCD_PCLK_EDGE_FALL |
+			  LCD_AC_BIAS_FREQ(255),
 	.pxafb_backlight_power = &idp_backlight_power,
 	.pxafb_lcd_power = &idp_lcd_power
 };
 
-static int idp_mci_init(struct device *dev, irq_handler_t idp_detect_int, void *data)
-{
-	/* setup GPIO for PXA25x MMC controller	*/
-	pxa_gpio_mode(GPIO6_MMCCLK_MD);
-	pxa_gpio_mode(GPIO8_MMCCS0_MD);
-
-	return 0;
-}
-
 static struct pxamci_platform_data idp_mci_platform_data = {
 	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
-	.init 		= idp_mci_init,
 };
 
 static void __init idp_init(void)
 {
 	printk("idp_init()\n");
 
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(idp_pin_config));
+
 	platform_device_register(&smc91x_device);
 	//platform_device_register(&mst_audio_device);
 	set_pxa_fb_info(&sharp_lm8v31);
 	pxa_set_mci_info(&idp_mci_platform_data);
 }
 
-static void __init idp_init_irq(void)
-{
-
-	pxa25x_init_irq();
-
-	set_irq_type(TOUCH_PANEL_IRQ, TOUCH_PANEL_IRQ_EDGE);
-}
-
 static struct map_desc idp_io_desc[] __initdata = {
   	{
 		.virtual	=  IDP_COREVOLT_VIRT,
@@ -177,15 +202,6 @@
 {
 	pxa_map_io();
 	iotable_init(idp_io_desc, ARRAY_SIZE(idp_io_desc));
-
-	// serial ports 2 & 3
-	pxa_gpio_mode(GPIO42_BTRXD_MD);
-	pxa_gpio_mode(GPIO43_BTTXD_MD);
-	pxa_gpio_mode(GPIO44_BTCTS_MD);
-	pxa_gpio_mode(GPIO45_BTRTS_MD);
-	pxa_gpio_mode(GPIO46_STRXD_MD);
-	pxa_gpio_mode(GPIO47_STTXD_MD);
-
 }
 
 
@@ -194,7 +210,7 @@
 	.phys_io	= 0x40000000,
 	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
 	.map_io		= idp_map_io,
-	.init_irq	= idp_init_irq,
+	.init_irq	= pxa25x_init_irq,
 	.timer		= &pxa_timer,
 	.init_machine	= idp_init,
 MACHINE_END
diff --git a/arch/arm/mach-pxa/include/mach/akita.h b/arch/arm/mach-pxa/include/mach/akita.h
deleted file mode 100644
index 5d8cc1d..0000000
--- a/arch/arm/mach-pxa/include/mach/akita.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Hardware specific definitions for SL-C1000 (Akita)
- *
- * Copyright (c) 2005 Richard Purdie
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-/* Akita IO Expander GPIOs */
-
-#define AKITA_IOEXP_RESERVED_7      (1 << 7)
-#define AKITA_IOEXP_IR_ON           (1 << 6)
-#define AKITA_IOEXP_AKIN_PULLUP     (1 << 5)
-#define AKITA_IOEXP_BACKLIGHT_CONT  (1 << 4)
-#define AKITA_IOEXP_BACKLIGHT_ON    (1 << 3)
-#define AKITA_IOEXP_MIC_BIAS        (1 << 2)
-#define AKITA_IOEXP_RESERVED_1      (1 << 1)
-#define AKITA_IOEXP_RESERVED_0      (1 << 0)
-
-/* Direction Bitfield  0=output  1=input */
-#define AKITA_IOEXP_IO_DIR	0
-/* Default Values */
-#define AKITA_IOEXP_IO_OUT	(AKITA_IOEXP_IR_ON | AKITA_IOEXP_AKIN_PULLUP)
-
-extern struct platform_device akitaioexp_device;
-
-void akita_set_ioexp(struct device *dev, unsigned char bitmask);
-void akita_reset_ioexp(struct device *dev, unsigned char bitmask);
-
diff --git a/arch/arm/mach-pxa/include/mach/corgi.h b/arch/arm/mach-pxa/include/mach/corgi.h
index bf85650..585970e 100644
--- a/arch/arm/mach-pxa/include/mach/corgi.h
+++ b/arch/arm/mach-pxa/include/mach/corgi.h
@@ -98,12 +98,21 @@
 			CORGI_SCP_MIC_BIAS )
 #define CORGI_SCOOP_IO_OUT	( CORGI_SCP_MUTE_L | CORGI_SCP_MUTE_R )
 
+#define CORGI_SCOOP_GPIO_BASE		(NR_BUILTIN_GPIO)
+#define CORGI_GPIO_LED_GREEN		(CORGI_SCOOP_GPIO_BASE + 0)
+#define CORGI_GPIO_SWA			(CORGI_SCOOP_GPIO_BASE + 1)  /* Hinge Switch A */
+#define CORGI_GPIO_SWB			(CORGI_SCOOP_GPIO_BASE + 2)  /* Hinge Switch B */
+#define CORGI_GPIO_MUTE_L		(CORGI_SCOOP_GPIO_BASE + 3)
+#define CORGI_GPIO_MUTE_R		(CORGI_SCOOP_GPIO_BASE + 4)
+#define CORGI_GPIO_AKIN_PULLUP		(CORGI_SCOOP_GPIO_BASE + 5)
+#define CORGI_GPIO_APM_ON		(CORGI_SCOOP_GPIO_BASE + 6)
+#define CORGI_GPIO_BACKLIGHT_CONT	(CORGI_SCOOP_GPIO_BASE + 7)
+#define CORGI_GPIO_MIC_BIAS		(CORGI_SCOOP_GPIO_BASE + 8)
 
 /*
  * Shared data structures
  */
 extern struct platform_device corgiscoop_device;
-extern struct platform_device corgissp_device;
 
 #endif /* __ASM_ARCH_CORGI_H  */
 
diff --git a/arch/arm/mach-pxa/include/mach/entry-macro.S b/arch/arm/mach-pxa/include/mach/entry-macro.S
index de16c12..f6b4bf3 100644
--- a/arch/arm/mach-pxa/include/mach/entry-macro.S
+++ b/arch/arm/mach-pxa/include/mach/entry-macro.S
@@ -41,7 +41,7 @@
 		and	\irqstat, \irqstat, \irqnr
 		clz	\irqnr, \irqstat
 		rsb	\irqnr, \irqnr, #31
-		add	\irqnr, \irqnr, #32
+		add	\irqnr, \irqnr, #(32 + PXA_IRQ(0))
 		b	1001f
 1003:
 		mrc	p6, 0, \irqstat, c0, c0, 0	@ ICIP
@@ -52,6 +52,6 @@
 		rsb	\irqstat, \irqnr, #0
 		and	\irqstat, \irqstat, \irqnr
 		clz	\irqnr, \irqstat
-		rsb	\irqnr, \irqnr, #31
+		rsb	\irqnr, \irqnr, #(31 + PXA_IRQ(0))
 1001:
 		.endm
diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h
index e89df4d..a582a6d 100644
--- a/arch/arm/mach-pxa/include/mach/hardware.h
+++ b/arch/arm/mach-pxa/include/mach/hardware.h
@@ -62,26 +62,74 @@
 
 #ifndef __ASSEMBLY__
 
+#include <asm/cputype.h>
+
+/*
+ *   CPU     Stepping     CPU_ID         JTAG_ID
+ *
+ *  PXA210	B0	0x69052922	0x2926C013
+ *  PXA210	B1	0x69052923	0x3926C013
+ *  PXA210	B2	0x69052924	0x4926C013
+ *  PXA210	C0	0x69052D25	0x5926C013
+ *
+ *  PXA250	A0	0x69052100	0x09264013
+ *  PXA250	A1	0x69052101	0x19264013
+ *  PXA250	B0	0x69052902	0x29264013
+ *  PXA250	B1	0x69052903	0x39264013
+ *  PXA250	B2	0x69052904	0x49264013
+ *  PXA250	C0	0x69052D05	0x59264013
+ *
+ *  PXA255	A0	0x69052D06	0x69264013
+ *
+ *  PXA26x	A0	0x69052903	0x39264013
+ *  PXA26x	B0	0x69052D05	0x59264013
+ *
+ *  PXA27x	A0	0x69054110	0x09265013
+ *  PXA27x	A1	0x69054111	0x19265013
+ *  PXA27x	B0	0x69054112	0x29265013
+ *  PXA27x	B1	0x69054113	0x39265013
+ *  PXA27x	C0	0x69054114	0x49265013
+ *  PXA27x	C5	0x69054117	0x79265013
+ *
+ *  PXA30x	A0	0x69056880	0x0E648013
+ *  PXA30x	A1	0x69056881	0x1E648013
+ *  PXA31x	A0	0x69056890	0x0E649013
+ *  PXA31x	A1	0x69056891	0x1E649013
+ *  PXA31x	A2	0x69056892	0x2E649013
+ *  PXA32x	B1	0x69056825	0x5E642013
+ *  PXA32x	B2	0x69056826	0x6E642013
+ *
+ *  PXA930	B0	0x69056835	0x5E643013
+ *  PXA930	B1	0x69056837	0x7E643013
+ *  PXA930	B2	0x69056838	0x8E643013
+ */
 #ifdef CONFIG_PXA25x
-#define __cpu_is_pxa21x(id)				\
+#define __cpu_is_pxa210(id)				\
 	({						\
-		unsigned int _id = (id) >> 4 & 0xf3f;	\
-		_id == 0x212;				\
+		unsigned int _id = (id) & 0xf3f0;	\
+		_id == 0x2120;				\
 	})
 
-#define __cpu_is_pxa255(id)                             \
-	({                                              \
-		unsigned int _id = (id) >> 4 & 0xfff;   \
-		_id == 0x2d0;                           \
-	 })
+#define __cpu_is_pxa250(id)				\
+	({						\
+		unsigned int _id = (id) & 0xf3ff;	\
+		_id <= 0x2105;				\
+	})
+
+#define __cpu_is_pxa255(id)				\
+	({						\
+		unsigned int _id = (id) & 0xffff;	\
+		_id == 0x2d06;				\
+	})
 
 #define __cpu_is_pxa25x(id)				\
 	({						\
-		unsigned int _id = (id) >> 4 & 0xfff;	\
-		_id == 0x2d0 || _id == 0x290;		\
+		unsigned int _id = (id) & 0xf300;	\
+		_id == 0x2100;				\
 	})
 #else
-#define __cpu_is_pxa21x(id)	(0)
+#define __cpu_is_pxa210(id)	(0)
+#define __cpu_is_pxa250(id)	(0)
 #define __cpu_is_pxa255(id)	(0)
 #define __cpu_is_pxa25x(id)	(0)
 #endif
@@ -136,9 +184,14 @@
 #define __cpu_is_pxa930(id)	(0)
 #endif
 
-#define cpu_is_pxa21x()					\
+#define cpu_is_pxa210()					\
 	({						\
-		__cpu_is_pxa21x(read_cpuid_id());	\
+		__cpu_is_pxa210(read_cpuid_id());	\
+	})
+
+#define cpu_is_pxa250()					\
+	({						\
+		__cpu_is_pxa250(read_cpuid_id());	\
 	})
 
 #define cpu_is_pxa255()                                 \
@@ -151,6 +204,8 @@
 		__cpu_is_pxa25x(read_cpuid_id());	\
 	})
 
+extern int cpu_is_pxa26x(void);
+
 #define cpu_is_pxa27x()					\
 	({						\
 		__cpu_is_pxa27x(read_cpuid_id());	\
diff --git a/arch/arm/mach-pxa/include/mach/i2c.h b/arch/arm/mach-pxa/include/mach/i2c.h
index 80596b0..1a9f65e 100644
--- a/arch/arm/mach-pxa/include/mach/i2c.h
+++ b/arch/arm/mach-pxa/include/mach/i2c.h
@@ -65,13 +65,18 @@
 	unsigned int		slave_addr;
 	struct i2c_slave_client	*slave;
 	unsigned int		class;
-	int			use_pio;
+	unsigned int		use_pio :1;
+	unsigned int		fast_mode :1;
 };
 
 extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info);
 
 #ifdef CONFIG_PXA27x
-extern void pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info);
+extern void pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info);
+#endif
+
+#ifdef CONFIG_PXA3xx
+extern void pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info);
 #endif
 
 #endif
diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h
index 108b5db..9c163e1 100644
--- a/arch/arm/mach-pxa/include/mach/irqs.h
+++ b/arch/arm/mach-pxa/include/mach/irqs.h
@@ -11,7 +11,14 @@
  */
 
 
-#define PXA_IRQ(x)	(x)
+#ifdef CONFIG_PXA_HAVE_ISA_IRQS
+#define PXA_ISA_IRQ(x)	(x)
+#define PXA_ISA_IRQ_NUM	(16)
+#else
+#define PXA_ISA_IRQ_NUM	(0)
+#endif
+
+#define PXA_IRQ(x)	(PXA_ISA_IRQ_NUM + (x))
 
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #define IRQ_SSP3	PXA_IRQ(0)	/* SSP3 service request */
@@ -73,7 +80,7 @@
 #define IRQ_MMC3	PXA_IRQ(55)	/* MMC3 Controller (PXA310) */
 #endif
 
-#define PXA_GPIO_IRQ_BASE	(64)
+#define PXA_GPIO_IRQ_BASE	PXA_IRQ(64)
 #define PXA_GPIO_IRQ_NUM	(128)
 
 #define GPIO_2_x_TO_IRQ(x)	(PXA_GPIO_IRQ_BASE + (x))
@@ -178,13 +185,7 @@
 #define NR_IRQS			(IRQ_S1_BVD1_STSCHG + 1)
 #elif defined(CONFIG_SHARP_LOCOMO)
 #define NR_IRQS			(IRQ_LOCOMO_SPI_TEND + 1)
-#elif defined(CONFIG_ARCH_LUBBOCK) || \
-      defined(CONFIG_MACH_LOGICPD_PXA270) || \
-      defined(CONFIG_MACH_TOSA) || \
-      defined(CONFIG_MACH_MAINSTONE) || \
-      defined(CONFIG_MACH_PCM027) || \
-      defined(CONFIG_ARCH_PXA_ESERIES) || \
-      defined(CONFIG_MACH_MAGICIAN)
+#elif defined(CONFIG_PXA_HAVE_BOARD_IRQS)
 #define NR_IRQS			(IRQ_BOARD_END)
 #elif defined(CONFIG_MACH_ZYLONITE)
 #define NR_IRQS			(IRQ_BOARD_START + 32)
diff --git a/arch/arm/mach-pxa/include/mach/littleton.h b/arch/arm/mach-pxa/include/mach/littleton.h
index 79d209b..5c4e320 100644
--- a/arch/arm/mach-pxa/include/mach/littleton.h
+++ b/arch/arm/mach-pxa/include/mach/littleton.h
@@ -3,4 +3,6 @@
 
 #define LITTLETON_ETH_PHYS	0x30000000
 
+#define LITTLETON_GPIO_LCD_CS	(17)
+
 #endif /* __ASM_ARCH_ZYLONITE_H */
diff --git a/arch/arm/mach-pxa/include/mach/memory.h b/arch/arm/mach-pxa/include/mach/memory.h
index 552eb7f..59aef89 100644
--- a/arch/arm/mach-pxa/include/mach/memory.h
+++ b/arch/arm/mach-pxa/include/mach/memory.h
@@ -40,11 +40,11 @@
 #define NODE_MEM_SIZE_BITS	26
 
 #if !defined(__ASSEMBLY__) && defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI)
-void cmx270_pci_adjust_zones(int node, unsigned long *size,
+void cmx2xx_pci_adjust_zones(int node, unsigned long *size,
 			     unsigned long *holes);
 
 #define arch_adjust_zones(node, size, holes) \
-	cmx270_pci_adjust_zones(node, size, holes)
+	cmx2xx_pci_adjust_zones(node, size, holes)
 
 #define ISA_DMA_THRESHOLD	(PHYS_OFFSET + SZ_64M - 1)
 #endif
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
index 6c8e722..617cab2 100644
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
@@ -17,7 +17,7 @@
 
 /* Crystal and Clock Signals */
 #define GPIO10_RTCCLK		MFP_CFG_OUT(GPIO10, AF1, DRIVE_LOW)
-#define GPIO70_RTC_CLK		MFP_CFG_OUT(GPIO70, AF1, DRIVE_LOW)
+#define GPIO70_RTCCLK		MFP_CFG_OUT(GPIO70, AF1, DRIVE_LOW)
 #define GPIO7_48MHz		MFP_CFG_OUT(GPIO7,  AF1, DRIVE_LOW)
 #define GPIO11_3_6MHz		MFP_CFG_OUT(GPIO11, AF1, DRIVE_LOW)
 #define GPIO71_3_6MHz		MFP_CFG_OUT(GPIO71, AF1, DRIVE_LOW)
@@ -156,6 +156,6 @@
 #define GPIO74_LCD_FCLK		MFP_CFG_OUT(GPIO74, AF2, DRIVE_LOW)
 #define GPIO75_LCD_LCLK		MFP_CFG_OUT(GPIO75, AF2, DRIVE_LOW)
 #define GPIO76_LCD_PCLK		MFP_CFG_OUT(GPIO76, AF2, DRIVE_LOW)
-#define GPIO77_LCD_ACBIAS	MFP_CFG_OUT(GPIO77, AF2, DRIVE_LOW)
+#define GPIO77_LCD_BIAS		MFP_CFG_OUT(GPIO77, AF2, DRIVE_LOW)
 
 #endif /* __ASM_ARCH_MFP_PXA25X_H */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa320.h b/arch/arm/mach-pxa/include/mach/mfp-pxa320.h
index 7499051..67f8385 100644
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa320.h
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa320.h
@@ -257,10 +257,10 @@
 #define GPIO38_SSP2_RXD		MFP_CFG(GPIO38, AF2)
 #define GPIO38_SSP2_TXD		MFP_CFG(GPIO38, AF5)
 
-#define GPIO69_SSP3_SCLK	MFP_CFG(GPIO69, AF2, DS08X, FLOAT)
-#define GPIO70_SSP3_FRM		MFP_CFG(GPIO70, AF2, DS08X, DRIVE_LOW)
-#define GPIO89_SSP3_SCLK	MFP_CFG(GPIO89, AF1, DS08X, FLOAT)
-#define GPIO90_SSP3_FRM		MFP_CFG(GPIO90, AF1, DS08X, DRIVE_LOW)
+#define GPIO69_SSP3_SCLK	MFP_CFG_X(GPIO69, AF2, DS08X, FLOAT)
+#define GPIO70_SSP3_FRM		MFP_CFG_X(GPIO70, AF2, DS08X, DRIVE_LOW)
+#define GPIO89_SSP3_SCLK	MFP_CFG_X(GPIO89, AF1, DS08X, FLOAT)
+#define GPIO90_SSP3_FRM		MFP_CFG_X(GPIO90, AF1, DS08X, DRIVE_LOW)
 #define GPIO71_SSP3_RXD		MFP_CFG_X(GPIO71, AF5, DS08X, FLOAT)
 #define GPIO71_SSP3_TXD		MFP_CFG_X(GPIO71, AF2, DS08X, DRIVE_LOW)
 #define GPIO72_SSP3_RXD		MFP_CFG_X(GPIO72, AF2, DS08X, FLOAT)
diff --git a/arch/arm/mach-pxa/include/mach/mfp.h b/arch/arm/mach-pxa/include/mach/mfp.h
index 8769567..4821850 100644
--- a/arch/arm/mach-pxa/include/mach/mfp.h
+++ b/arch/arm/mach-pxa/include/mach/mfp.h
@@ -274,12 +274,13 @@
 #define MFP_DS_MASK		(0x7 << 13)
 #define MFP_DS(x)		(((x) >> 13) & 0x7)
 
-#define MFP_LPM_INPUT		(0x0 << 16)
+#define MFP_LPM_DEFAULT		(0x0 << 16)
 #define MFP_LPM_DRIVE_LOW	(0x1 << 16)
 #define MFP_LPM_DRIVE_HIGH	(0x2 << 16)
 #define MFP_LPM_PULL_LOW	(0x3 << 16)
 #define MFP_LPM_PULL_HIGH	(0x4 << 16)
 #define MFP_LPM_FLOAT		(0x5 << 16)
+#define MFP_LPM_INPUT		(0x6 << 16)
 #define MFP_LPM_STATE_MASK	(0x7 << 16)
 #define MFP_LPM_STATE(x)	(((x) >> 16) & 0x7)
 
@@ -297,7 +298,7 @@
 #define MFP_PULL_MASK		(0x3 << 21)
 #define MFP_PULL(x)		(((x) >> 21) & 0x3)
 
-#define MFP_CFG_DEFAULT		(MFP_AF0 | MFP_DS03X | MFP_LPM_INPUT |\
+#define MFP_CFG_DEFAULT		(MFP_AF0 | MFP_DS03X | MFP_LPM_DEFAULT |\
 				 MFP_LPM_EDGE_NONE | MFP_PULL_NONE)
 
 #define MFP_CFG(pin, af)		\
diff --git a/arch/arm/mach-pxa/include/mach/mioa701.h b/arch/arm/mach-pxa/include/mach/mioa701.h
new file mode 100644
index 0000000..8483cb5
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mioa701.h
@@ -0,0 +1,67 @@
+#ifndef _MIOA701_H_
+#define _MIOA701_H_
+
+#define MIO_CFG_IN(pin, af)		\
+	((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK)) |\
+	 (MFP_PIN(pin) | MFP_##af | MFP_DIR_IN))
+
+#define MIO_CFG_OUT(pin, af, state)	\
+	((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK | MFP_LPM_STATE_MASK)) |\
+	 (MFP_PIN(pin) | MFP_##af | MFP_DIR_OUT | MFP_LPM_##state))
+
+/* Global GPIOs */
+#define GPIO9_CHARGE_nEN			9
+#define GPIO18_POWEROFF				18
+#define GPIO87_LCD_POWER			87
+
+/* USB */
+#define GPIO13_USB_DETECT			13
+#define GPIO22_USB_ENABLE			22
+
+/* SDIO bits */
+#define GPIO78_SDIO_RO				78
+#define GPIO15_SDIO_INSERT			15
+#define GPIO91_SDIO_EN				91
+
+/* Bluetooth */
+#define GPIO83_BT_ON				83
+
+/* GPS */
+#define GPIO23_GPS_UNKNOWN1			23
+#define GPIO26_GPS_ON				26
+#define GPIO27_GPS_RESET			27
+#define GPIO106_GPS_UNKNOWN2			106
+#define GPIO107_GPS_UNKNOWN3			107
+
+/* GSM */
+#define GPIO24_GSM_MOD_RESET_CMD		24
+#define GPIO88_GSM_nMOD_ON_CMD			88
+#define GPIO90_GSM_nMOD_OFF_CMD			90
+#define GPIO114_GSM_nMOD_DTE_UART_STATE 	114
+#define GPIO25_GSM_MOD_ON_STATE			25
+#define GPIO113_GSM_EVENT			113
+
+/* SOUND */
+#define GPIO12_HPJACK_INSERT			12
+
+/* LEDS */
+#define GPIO10_LED_nCharging			10
+#define GPIO97_LED_nBlue			97
+#define GPIO98_LED_nOrange			98
+#define GPIO82_LED_nVibra			82
+#define GPIO115_LED_nKeyboard			115
+
+/* Keyboard */
+#define GPIO0_KEY_POWER				0
+#define GPIO93_KEY_VOLUME_UP			93
+#define GPIO94_KEY_VOLUME_DOWN			94
+
+extern struct input_dev *mioa701_evdev;
+extern void mioa701_gpio_lpm_set(unsigned long mfp_pin);
+
+/* Assembler externals mioa701_bootresume.S */
+extern u32 mioa701_bootstrap;
+extern u32 mioa701_jumpaddr;
+extern u32 mioa701_bootstrap_lg;
+
+#endif /* _MIOA701_H */
diff --git a/arch/arm/mach-pxa/include/mach/ohci.h b/arch/arm/mach-pxa/include/mach/ohci.h
index e848a47..95b6e2a 100644
--- a/arch/arm/mach-pxa/include/mach/ohci.h
+++ b/arch/arm/mach-pxa/include/mach/ohci.h
@@ -7,6 +7,22 @@
 	int (*init)(struct device *);
 	void (*exit)(struct device *);
 
+	unsigned long flags;
+#define ENABLE_PORT1		(1 << 0)
+#define ENABLE_PORT2		(1 << 1)
+#define ENABLE_PORT3		(1 << 2)
+#define ENABLE_PORT_ALL		(ENABLE_PORT1 | ENABLE_PORT2 | ENABLE_PORT3)
+
+#define POWER_SENSE_LOW		(1 << 3)
+#define POWER_CONTROL_LOW	(1 << 4)
+#define NO_OC_PROTECTION	(1 << 5)
+#define OC_MODE_GLOBAL		(0 << 6)
+#define OC_MODE_PERPORT		(1 << 6)
+
+	int power_on_delay;	/* Power On to Power Good time - in ms
+				 * HCD must wait for this duration before
+				 * accessing a powered on port
+				 */
 	int port_mode;
 #define PMM_NPS_MODE           1
 #define PMM_GLOBAL_MODE        2
diff --git a/arch/arm/mach-pxa/include/mach/palmz72.h b/arch/arm/mach-pxa/include/mach/palmz72.h
new file mode 100644
index 0000000..5032307
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/palmz72.h
@@ -0,0 +1,80 @@
+/*
+ * GPIOs and interrupts for Palm Zire72 Handheld Computer
+ *
+ * Authors:	Alex Osborne <bobofdoom@gmail.com>
+ *		Jan Herman <2hp@seznam.cz>
+ *		Sergey Lapin <slapin@ossfans.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _INCLUDE_PALMZ72_H_
+#define _INCLUDE_PALMZ72_H_
+
+/* Power and control */
+#define GPIO_NR_PALMZ72_GPIO_RESET		1
+#define GPIO_NR_PALMZ72_POWER_DETECT		0
+
+/* SD/MMC */
+#define GPIO_NR_PALMZ72_SD_DETECT_N		14
+#define GPIO_NR_PALMZ72_SD_POWER_N		98
+#define GPIO_NR_PALMZ72_SD_RO 115
+
+/* Touchscreen */
+#define GPIO_NR_PALMZ72_WM9712_IRQ		27
+
+/* IRDA -  disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */
+#define GPIO_NR_PALMZ72_IR_DISABLE		49
+
+/* USB */
+#define GPIO_NR_PALMZ72_USB_DETECT_N		15
+#define GPIO_NR_PALMZ72_USB_POWER		95
+#define GPIO_NR_PALMZ72_USB_PULLUP		12
+
+/* LCD/Backlight */
+#define GPIO_NR_PALMZ72_BL_POWER		20
+#define GPIO_NR_PALMZ72_LCD_POWER		96
+
+/* LED */
+#define GPIO_NR_PALMZ72_LED_GREEN		88
+
+/* Bluetooth */
+#define GPIO_NR_PALMZ72_BT_POWER		17
+#define GPIO_NR_PALMZ72_BT_RESET		83
+
+/** Initial values **/
+
+/* Battery */
+#define PALMZ72_BAT_MAX_VOLTAGE		4000	/* 4.00v current voltage */
+#define PALMZ72_BAT_MIN_VOLTAGE		3550	/* 3.55v critical voltage */
+#define PALMZ72_BAT_MAX_CURRENT		0	/* unknokn */
+#define PALMZ72_BAT_MIN_CURRENT		0	/* unknown */
+#define PALMZ72_BAT_MAX_CHARGE		1	/* unknown */
+#define PALMZ72_BAT_MIN_CHARGE		1	/* unknown */
+#define PALMZ72_MAX_LIFE_MINS		360	/* on-life in minutes */
+
+/* Backlight */
+#define PALMZ72_MAX_INTENSITY		0xFE
+#define PALMZ72_DEFAULT_INTENSITY	0x7E
+#define PALMZ72_LIMIT_MASK		0x7F
+#define PALMZ72_PRESCALER		0x3F
+#define PALMZ72_PERIOD_NS		3500
+
+#ifdef CONFIG_PM
+struct palmz72_resume_info {
+	u32 magic0;		/* 0x0 */
+	u32 magic1;		/* 0x4 */
+	u32 resume_addr;	/* 0x8 */
+	u32 pad[11];		/* 0xc..0x37 */
+	u32 arm_control;	/* 0x38 */
+	u32 aux_control;	/* 0x3c */
+	u32 ttb;		/* 0x40 */
+	u32 domain_access;	/* 0x44 */
+	u32 process_id;		/* 0x48 */
+};
+#endif
+#endif
+
diff --git a/arch/arm/mach-pxa/include/mach/pm.h b/arch/arm/mach-pxa/include/mach/pm.h
index 261e5bc..8334246 100644
--- a/arch/arm/mach-pxa/include/mach/pm.h
+++ b/arch/arm/mach-pxa/include/mach/pm.h
@@ -15,6 +15,8 @@
 	void	(*restore)(unsigned long *);
 	int	(*valid)(suspend_state_t state);
 	void	(*enter)(suspend_state_t state);
+	int	(*prepare)(void);
+	void	(*finish)(void);
 };
 
 extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns;
diff --git a/arch/arm/mach-pxa/include/mach/poodle.h b/arch/arm/mach-pxa/include/mach/poodle.h
index 67debc4..0b3e6d0 100644
--- a/arch/arm/mach-pxa/include/mach/poodle.h
+++ b/arch/arm/mach-pxa/include/mach/poodle.h
@@ -23,6 +23,7 @@
 #define POODLE_GPIO_AC_IN		(1)
 #define POODLE_GPIO_CO			16
 #define POODLE_GPIO_TP_INT		(5)
+#define POODLE_GPIO_TP_CS		(24)
 #define POODLE_GPIO_WAKEUP		(11)	/* change battery */
 #define POODLE_GPIO_GA_INT		(10)
 #define POODLE_GPIO_IR_ON		(22)
@@ -70,6 +71,14 @@
 #define POODLE_SCOOP_IO_DIR	( POODLE_SCOOP_VPEN | POODLE_SCOOP_HS_OUT )
 #define POODLE_SCOOP_IO_OUT	( 0 )
 
+#define POODLE_SCOOP_GPIO_BASE	(NR_BUILTIN_GPIO)
+#define POODLE_GPIO_CHARGE_ON	(POODLE_SCOOP_GPIO_BASE + 0)
+#define POODLE_GPIO_CP401	(POODLE_SCOOP_GPIO_BASE + 2)
+#define POODLE_GPIO_VPEN	(POODLE_SCOOP_GPIO_BASE + 7)
+#define POODLE_GPIO_L_PCLK	(POODLE_SCOOP_GPIO_BASE + 9)
+#define POODLE_GPIO_L_LCLK	(POODLE_SCOOP_GPIO_BASE + 10)
+#define POODLE_GPIO_HS_OUT	(POODLE_SCOOP_GPIO_BASE + 11)
+
 #define POODLE_LOCOMO_GPIO_AMP_ON      LOCOMO_GPIO(8)
 #define POODLE_LOCOMO_GPIO_MUTE_L      LOCOMO_GPIO(10)
 #define POODLE_LOCOMO_GPIO_MUTE_R      LOCOMO_GPIO(11)
diff --git a/arch/arm/mach-pxa/include/mach/pxa-regs.h b/arch/arm/mach-pxa/include/mach/pxa-regs.h
index 12288ca..15295d9 100644
--- a/arch/arm/mach-pxa/include/mach/pxa-regs.h
+++ b/arch/arm/mach-pxa/include/mach/pxa-regs.h
@@ -69,30 +69,18 @@
 /*
  * DMA Controller
  */
-
-#define DCSR0		__REG(0x40000000)  /* DMA Control / Status Register for Channel 0 */
-#define DCSR1		__REG(0x40000004)  /* DMA Control / Status Register for Channel 1 */
-#define DCSR2		__REG(0x40000008)  /* DMA Control / Status Register for Channel 2 */
-#define DCSR3		__REG(0x4000000c)  /* DMA Control / Status Register for Channel 3 */
-#define DCSR4		__REG(0x40000010)  /* DMA Control / Status Register for Channel 4 */
-#define DCSR5		__REG(0x40000014)  /* DMA Control / Status Register for Channel 5 */
-#define DCSR6		__REG(0x40000018)  /* DMA Control / Status Register for Channel 6 */
-#define DCSR7		__REG(0x4000001c)  /* DMA Control / Status Register for Channel 7 */
-#define DCSR8		__REG(0x40000020)  /* DMA Control / Status Register for Channel 8 */
-#define DCSR9		__REG(0x40000024)  /* DMA Control / Status Register for Channel 9 */
-#define DCSR10		__REG(0x40000028)  /* DMA Control / Status Register for Channel 10 */
-#define DCSR11		__REG(0x4000002c)  /* DMA Control / Status Register for Channel 11 */
-#define DCSR12		__REG(0x40000030)  /* DMA Control / Status Register for Channel 12 */
-#define DCSR13		__REG(0x40000034)  /* DMA Control / Status Register for Channel 13 */
-#define DCSR14		__REG(0x40000038)  /* DMA Control / Status Register for Channel 14 */
-#define DCSR15		__REG(0x4000003c)  /* DMA Control / Status Register for Channel 15 */
-
 #define DCSR(x)		__REG2(0x40000000, (x) << 2)
 
 #define DCSR_RUN	(1 << 31)	/* Run Bit (read / write) */
 #define DCSR_NODESC	(1 << 30)	/* No-Descriptor Fetch (read / write) */
 #define DCSR_STOPIRQEN	(1 << 29)	/* Stop Interrupt Enable (read / write) */
-#ifdef CONFIG_PXA27x
+#define DCSR_REQPEND	(1 << 8)	/* Request Pending (read-only) */
+#define DCSR_STOPSTATE	(1 << 3)	/* Stop State (read-only) */
+#define DCSR_ENDINTR	(1 << 2)	/* End Interrupt (read / write) */
+#define DCSR_STARTINTR	(1 << 1)	/* Start Interrupt (read / write) */
+#define DCSR_BUSERR	(1 << 0)	/* Bus Error Interrupt (read / write) */
+
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #define DCSR_EORIRQEN	(1 << 28)       /* End of Receive Interrupt Enable (R/W) */
 #define DCSR_EORJMPEN	(1 << 27)       /* Jump to next descriptor on EOR */
 #define DCSR_EORSTOPEN	(1 << 26)       /* STOP on an EOR */
@@ -101,11 +89,6 @@
 #define DCSR_CMPST	(1 << 10)       /* The Descriptor Compare Status */
 #define DCSR_EORINTR	(1 << 9)        /* The end of Receive */
 #endif
-#define DCSR_REQPEND	(1 << 8)	/* Request Pending (read-only) */
-#define DCSR_STOPSTATE	(1 << 3)	/* Stop State (read-only) */
-#define DCSR_ENDINTR	(1 << 2)	/* End Interrupt (read / write) */
-#define DCSR_STARTINTR	(1 << 1)	/* Start Interrupt (read / write) */
-#define DCSR_BUSERR	(1 << 0)	/* Bus Error Interrupt (read / write) */
 
 #define DALGN		__REG(0x400000a0)  /* DMA Alignment Register */
 #define DINT		__REG(0x400000f0)  /* DMA Interrupt Register */
@@ -114,145 +97,9 @@
 			&__REG2(0x40000100, ((n) & 0x3f) << 2) : \
 			&__REG2(0x40001100, ((n) & 0x3f) << 2)))
 
-#define DRCMR0		__REG(0x40000100)  /* Request to Channel Map Register for DREQ 0 */
-#define DRCMR1		__REG(0x40000104)  /* Request to Channel Map Register for DREQ 1 */
-#define DRCMR2		__REG(0x40000108)  /* Request to Channel Map Register for I2S receive Request */
-#define DRCMR3		__REG(0x4000010c)  /* Request to Channel Map Register for I2S transmit Request */
-#define DRCMR4		__REG(0x40000110)  /* Request to Channel Map Register for BTUART receive Request */
-#define DRCMR5		__REG(0x40000114)  /* Request to Channel Map Register for BTUART transmit Request. */
-#define DRCMR6		__REG(0x40000118)  /* Request to Channel Map Register for FFUART receive Request */
-#define DRCMR7		__REG(0x4000011c)  /* Request to Channel Map Register for FFUART transmit Request */
-#define DRCMR8		__REG(0x40000120)  /* Request to Channel Map Register for AC97 microphone Request */
-#define DRCMR9		__REG(0x40000124)  /* Request to Channel Map Register for AC97 modem receive Request */
-#define DRCMR10		__REG(0x40000128)  /* Request to Channel Map Register for AC97 modem transmit Request */
-#define DRCMR11		__REG(0x4000012c)  /* Request to Channel Map Register for AC97 audio receive Request */
-#define DRCMR12		__REG(0x40000130)  /* Request to Channel Map Register for AC97 audio transmit Request */
-#define DRCMR13		__REG(0x40000134)  /* Request to Channel Map Register for SSP receive Request */
-#define DRCMR14		__REG(0x40000138)  /* Request to Channel Map Register for SSP transmit Request */
-#define DRCMR15		__REG(0x4000013c)  /* Request to Channel Map Register for SSP2 receive Request */
-#define DRCMR16		__REG(0x40000140)  /* Request to Channel Map Register for SSP2 transmit Request */
-#define DRCMR17		__REG(0x40000144)  /* Request to Channel Map Register for ICP receive Request */
-#define DRCMR18		__REG(0x40000148)  /* Request to Channel Map Register for ICP transmit Request */
-#define DRCMR19		__REG(0x4000014c)  /* Request to Channel Map Register for STUART receive Request */
-#define DRCMR20		__REG(0x40000150)  /* Request to Channel Map Register for STUART transmit Request */
-#define DRCMR21		__REG(0x40000154)  /* Request to Channel Map Register for MMC receive Request */
-#define DRCMR22		__REG(0x40000158)  /* Request to Channel Map Register for MMC transmit Request */
-#define DRCMR23		__REG(0x4000015c)  /* Reserved */
-#define DRCMR24		__REG(0x40000160)  /* Reserved */
-#define DRCMR25		__REG(0x40000164)  /* Request to Channel Map Register for USB endpoint 1 Request */
-#define DRCMR26		__REG(0x40000168)  /* Request to Channel Map Register for USB endpoint 2 Request */
-#define DRCMR27		__REG(0x4000016C)  /* Request to Channel Map Register for USB endpoint 3 Request */
-#define DRCMR28		__REG(0x40000170)  /* Request to Channel Map Register for USB endpoint 4 Request */
-#define DRCMR29		__REG(0x40000174)  /* Reserved */
-#define DRCMR30		__REG(0x40000178)  /* Request to Channel Map Register for USB endpoint 6 Request */
-#define DRCMR31		__REG(0x4000017C)  /* Request to Channel Map Register for USB endpoint 7 Request */
-#define DRCMR32		__REG(0x40000180)  /* Request to Channel Map Register for USB endpoint 8 Request */
-#define DRCMR33		__REG(0x40000184)  /* Request to Channel Map Register for USB endpoint 9 Request */
-#define DRCMR34		__REG(0x40000188)  /* Reserved */
-#define DRCMR35		__REG(0x4000018C)  /* Request to Channel Map Register for USB endpoint 11 Request */
-#define DRCMR36		__REG(0x40000190)  /* Request to Channel Map Register for USB endpoint 12 Request */
-#define DRCMR37		__REG(0x40000194)  /* Request to Channel Map Register for USB endpoint 13 Request */
-#define DRCMR38		__REG(0x40000198)  /* Request to Channel Map Register for USB endpoint 14 Request */
-#define DRCMR39		__REG(0x4000019C)  /* Reserved */
-#define DRCMR66		__REG(0x40001108)  /* Request to Channel Map Register for SSP3 receive Request */
-#define DRCMR67		__REG(0x4000110C)  /* Request to Channel Map Register for SSP3 transmit Request */
-#define DRCMR68		__REG(0x40001110)  /* Request to Channel Map Register for Camera FIFO 0 Request */
-#define DRCMR69		__REG(0x40001114)  /* Request to Channel Map Register for Camera FIFO 1 Request */
-#define DRCMR70		__REG(0x40001118)  /* Request to Channel Map Register for Camera FIFO 2 Request */
-
-#define DRCMRRXSADR	DRCMR2
-#define DRCMRTXSADR	DRCMR3
-#define DRCMRRXBTRBR	DRCMR4
-#define DRCMRTXBTTHR	DRCMR5
-#define DRCMRRXFFRBR	DRCMR6
-#define DRCMRTXFFTHR	DRCMR7
-#define DRCMRRXMCDR	DRCMR8
-#define DRCMRRXMODR	DRCMR9
-#define DRCMRTXMODR	DRCMR10
-#define DRCMRRXPCDR	DRCMR11
-#define DRCMRTXPCDR	DRCMR12
-#define DRCMRRXSSDR	DRCMR13
-#define DRCMRTXSSDR	DRCMR14
-#define DRCMRRXSS2DR   DRCMR15
-#define DRCMRTXSS2DR   DRCMR16
-#define DRCMRRXICDR	DRCMR17
-#define DRCMRTXICDR	DRCMR18
-#define DRCMRRXSTRBR	DRCMR19
-#define DRCMRTXSTTHR	DRCMR20
-#define DRCMRRXMMC	DRCMR21
-#define DRCMRTXMMC	DRCMR22
-#define DRCMRRXSS3DR   DRCMR66
-#define DRCMRTXSS3DR   DRCMR67
-#define DRCMRUDC(x)	DRCMR((x) + 24)
-
 #define DRCMR_MAPVLD	(1 << 7)	/* Map Valid (read / write) */
 #define DRCMR_CHLNUM	0x1f		/* mask for Channel Number (read / write) */
 
-#define DDADR0		__REG(0x40000200)  /* DMA Descriptor Address Register Channel 0 */
-#define DSADR0		__REG(0x40000204)  /* DMA Source Address Register Channel 0 */
-#define DTADR0		__REG(0x40000208)  /* DMA Target Address Register Channel 0 */
-#define DCMD0		__REG(0x4000020c)  /* DMA Command Address Register Channel 0 */
-#define DDADR1		__REG(0x40000210)  /* DMA Descriptor Address Register Channel 1 */
-#define DSADR1		__REG(0x40000214)  /* DMA Source Address Register Channel 1 */
-#define DTADR1		__REG(0x40000218)  /* DMA Target Address Register Channel 1 */
-#define DCMD1		__REG(0x4000021c)  /* DMA Command Address Register Channel 1 */
-#define DDADR2		__REG(0x40000220)  /* DMA Descriptor Address Register Channel 2 */
-#define DSADR2		__REG(0x40000224)  /* DMA Source Address Register Channel 2 */
-#define DTADR2		__REG(0x40000228)  /* DMA Target Address Register Channel 2 */
-#define DCMD2		__REG(0x4000022c)  /* DMA Command Address Register Channel 2 */
-#define DDADR3		__REG(0x40000230)  /* DMA Descriptor Address Register Channel 3 */
-#define DSADR3		__REG(0x40000234)  /* DMA Source Address Register Channel 3 */
-#define DTADR3		__REG(0x40000238)  /* DMA Target Address Register Channel 3 */
-#define DCMD3		__REG(0x4000023c)  /* DMA Command Address Register Channel 3 */
-#define DDADR4		__REG(0x40000240)  /* DMA Descriptor Address Register Channel 4 */
-#define DSADR4		__REG(0x40000244)  /* DMA Source Address Register Channel 4 */
-#define DTADR4		__REG(0x40000248)  /* DMA Target Address Register Channel 4 */
-#define DCMD4		__REG(0x4000024c)  /* DMA Command Address Register Channel 4 */
-#define DDADR5		__REG(0x40000250)  /* DMA Descriptor Address Register Channel 5 */
-#define DSADR5		__REG(0x40000254)  /* DMA Source Address Register Channel 5 */
-#define DTADR5		__REG(0x40000258)  /* DMA Target Address Register Channel 5 */
-#define DCMD5		__REG(0x4000025c)  /* DMA Command Address Register Channel 5 */
-#define DDADR6		__REG(0x40000260)  /* DMA Descriptor Address Register Channel 6 */
-#define DSADR6		__REG(0x40000264)  /* DMA Source Address Register Channel 6 */
-#define DTADR6		__REG(0x40000268)  /* DMA Target Address Register Channel 6 */
-#define DCMD6		__REG(0x4000026c)  /* DMA Command Address Register Channel 6 */
-#define DDADR7		__REG(0x40000270)  /* DMA Descriptor Address Register Channel 7 */
-#define DSADR7		__REG(0x40000274)  /* DMA Source Address Register Channel 7 */
-#define DTADR7		__REG(0x40000278)  /* DMA Target Address Register Channel 7 */
-#define DCMD7		__REG(0x4000027c)  /* DMA Command Address Register Channel 7 */
-#define DDADR8		__REG(0x40000280)  /* DMA Descriptor Address Register Channel 8 */
-#define DSADR8		__REG(0x40000284)  /* DMA Source Address Register Channel 8 */
-#define DTADR8		__REG(0x40000288)  /* DMA Target Address Register Channel 8 */
-#define DCMD8		__REG(0x4000028c)  /* DMA Command Address Register Channel 8 */
-#define DDADR9		__REG(0x40000290)  /* DMA Descriptor Address Register Channel 9 */
-#define DSADR9		__REG(0x40000294)  /* DMA Source Address Register Channel 9 */
-#define DTADR9		__REG(0x40000298)  /* DMA Target Address Register Channel 9 */
-#define DCMD9		__REG(0x4000029c)  /* DMA Command Address Register Channel 9 */
-#define DDADR10		__REG(0x400002a0)  /* DMA Descriptor Address Register Channel 10 */
-#define DSADR10		__REG(0x400002a4)  /* DMA Source Address Register Channel 10 */
-#define DTADR10		__REG(0x400002a8)  /* DMA Target Address Register Channel 10 */
-#define DCMD10		__REG(0x400002ac)  /* DMA Command Address Register Channel 10 */
-#define DDADR11		__REG(0x400002b0)  /* DMA Descriptor Address Register Channel 11 */
-#define DSADR11		__REG(0x400002b4)  /* DMA Source Address Register Channel 11 */
-#define DTADR11		__REG(0x400002b8)  /* DMA Target Address Register Channel 11 */
-#define DCMD11		__REG(0x400002bc)  /* DMA Command Address Register Channel 11 */
-#define DDADR12		__REG(0x400002c0)  /* DMA Descriptor Address Register Channel 12 */
-#define DSADR12		__REG(0x400002c4)  /* DMA Source Address Register Channel 12 */
-#define DTADR12		__REG(0x400002c8)  /* DMA Target Address Register Channel 12 */
-#define DCMD12		__REG(0x400002cc)  /* DMA Command Address Register Channel 12 */
-#define DDADR13		__REG(0x400002d0)  /* DMA Descriptor Address Register Channel 13 */
-#define DSADR13		__REG(0x400002d4)  /* DMA Source Address Register Channel 13 */
-#define DTADR13		__REG(0x400002d8)  /* DMA Target Address Register Channel 13 */
-#define DCMD13		__REG(0x400002dc)  /* DMA Command Address Register Channel 13 */
-#define DDADR14		__REG(0x400002e0)  /* DMA Descriptor Address Register Channel 14 */
-#define DSADR14		__REG(0x400002e4)  /* DMA Source Address Register Channel 14 */
-#define DTADR14		__REG(0x400002e8)  /* DMA Target Address Register Channel 14 */
-#define DCMD14		__REG(0x400002ec)  /* DMA Command Address Register Channel 14 */
-#define DDADR15		__REG(0x400002f0)  /* DMA Descriptor Address Register Channel 15 */
-#define DSADR15		__REG(0x400002f4)  /* DMA Source Address Register Channel 15 */
-#define DTADR15		__REG(0x400002f8)  /* DMA Target Address Register Channel 15 */
-#define DCMD15		__REG(0x400002fc)  /* DMA Command Address Register Channel 15 */
-
 #define DDADR(x)	__REG2(0x40000200, (x) << 4)
 #define DSADR(x)	__REG2(0x40000204, (x) << 4)
 #define DTADR(x)	__REG2(0x40000208, (x) << 4)
@@ -418,91 +265,13 @@
 
 
 /*
- * I2C registers
+ * I2C registers - moved into drivers/i2c/busses/i2c-pxa.c
  */
 
-#define IBMR		__REG(0x40301680)  /* I2C Bus Monitor Register - IBMR */
-#define IDBR		__REG(0x40301688)  /* I2C Data Buffer Register - IDBR */
-#define ICR		__REG(0x40301690)  /* I2C Control Register - ICR */
-#define ISR		__REG(0x40301698)  /* I2C Status Register - ISR */
-#define ISAR		__REG(0x403016A0)  /* I2C Slave Address Register - ISAR */
-
-#define PWRIBMR    __REG(0x40f00180)  /* Power I2C Bus Monitor Register-IBMR */
-#define PWRIDBR    __REG(0x40f00188)  /* Power I2C Data Buffer Register-IDBR */
-#define PWRICR __REG(0x40f00190)  /* Power I2C Control Register - ICR */
-#define PWRISR __REG(0x40f00198)  /* Power I2C Status Register - ISR */
-#define PWRISAR    __REG(0x40f001A0)  /*Power I2C Slave Address Register-ISAR */
-
-#define ICR_START	(1 << 0)	   /* start bit */
-#define ICR_STOP	(1 << 1)	   /* stop bit */
-#define ICR_ACKNAK	(1 << 2)	   /* send ACK(0) or NAK(1) */
-#define ICR_TB		(1 << 3)	   /* transfer byte bit */
-#define ICR_MA		(1 << 4)	   /* master abort */
-#define ICR_SCLE	(1 << 5)	   /* master clock enable */
-#define ICR_IUE		(1 << 6)	   /* unit enable */
-#define ICR_GCD		(1 << 7)	   /* general call disable */
-#define ICR_ITEIE	(1 << 8)	   /* enable tx interrupts */
-#define ICR_IRFIE	(1 << 9)	   /* enable rx interrupts */
-#define ICR_BEIE	(1 << 10)	   /* enable bus error ints */
-#define ICR_SSDIE	(1 << 11)	   /* slave STOP detected int enable */
-#define ICR_ALDIE	(1 << 12)	   /* enable arbitration interrupt */
-#define ICR_SADIE	(1 << 13)	   /* slave address detected int enable */
-#define ICR_UR		(1 << 14)	   /* unit reset */
-
-#define ISR_RWM		(1 << 0)	   /* read/write mode */
-#define ISR_ACKNAK	(1 << 1)	   /* ack/nak status */
-#define ISR_UB		(1 << 2)	   /* unit busy */
-#define ISR_IBB		(1 << 3)	   /* bus busy */
-#define ISR_SSD		(1 << 4)	   /* slave stop detected */
-#define ISR_ALD		(1 << 5)	   /* arbitration loss detected */
-#define ISR_ITE		(1 << 6)	   /* tx buffer empty */
-#define ISR_IRF		(1 << 7)	   /* rx buffer full */
-#define ISR_GCAD	(1 << 8)	   /* general call address detected */
-#define ISR_SAD		(1 << 9)	   /* slave address detected */
-#define ISR_BED		(1 << 10)	   /* bus error no ACK/NAK */
-
-
 /*
- * Serial Audio Controller
+ * Serial Audio Controller - moved into sound/soc/pxa/pxa2xx-i2s.c
  */
 
-#define SACR0		__REG(0x40400000)  /* Global Control Register */
-#define SACR1		__REG(0x40400004)  /* Serial Audio I 2 S/MSB-Justified Control Register */
-#define SASR0		__REG(0x4040000C)  /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */
-#define SAIMR		__REG(0x40400014)  /* Serial Audio Interrupt Mask Register */
-#define SAICR		__REG(0x40400018)  /* Serial Audio Interrupt Clear Register */
-#define SADIV		__REG(0x40400060)  /* Audio Clock Divider Register. */
-#define SADR		__REG(0x40400080)  /* Serial Audio Data Register (TX and RX FIFO access Register). */
-
-#define SACR0_RFTH(x)	((x) << 12)	/* Rx FIFO Interrupt or DMA Trigger Threshold */
-#define SACR0_TFTH(x)	((x) << 8)	/* Tx FIFO Interrupt or DMA Trigger Threshold */
-#define SACR0_STRF	(1 << 5)	/* FIFO Select for EFWR Special Function */
-#define SACR0_EFWR	(1 << 4)	/* Enable EFWR Function  */
-#define SACR0_RST	(1 << 3)	/* FIFO, i2s Register Reset */
-#define SACR0_BCKD	(1 << 2) 	/* Bit Clock Direction */
-#define SACR0_ENB	(1 << 0)	/* Enable I2S Link */
-#define SACR1_ENLBF	(1 << 5)	/* Enable Loopback */
-#define SACR1_DRPL	(1 << 4) 	/* Disable Replaying Function */
-#define SACR1_DREC	(1 << 3)	/* Disable Recording Function */
-#define SACR1_AMSL	(1 << 0)	/* Specify Alternate Mode */
-
-#define SASR0_I2SOFF	(1 << 7)	/* Controller Status */
-#define SASR0_ROR	(1 << 6)	/* Rx FIFO Overrun */
-#define SASR0_TUR	(1 << 5)	/* Tx FIFO Underrun */
-#define SASR0_RFS	(1 << 4)	/* Rx FIFO Service Request */
-#define SASR0_TFS	(1 << 3)	/* Tx FIFO Service Request */
-#define SASR0_BSY	(1 << 2)	/* I2S Busy */
-#define SASR0_RNE	(1 << 1)	/* Rx FIFO Not Empty */
-#define SASR0_TNF	(1 << 0) 	/* Tx FIFO Not Empty */
-
-#define SAICR_ROR	(1 << 6)	/* Clear Rx FIFO Overrun Interrupt */
-#define SAICR_TUR	(1 << 5)	/* Clear Tx FIFO Underrun Interrupt */
-
-#define SAIMR_ROR	(1 << 6)	/* Enable Rx FIFO Overrun Condition Interrupt */
-#define SAIMR_TUR	(1 << 5)	/* Enable Tx FIFO Underrun Condition Interrupt */
-#define SAIMR_RFS	(1 << 4)	/* Enable Rx FIFO Service Interrupt */
-#define SAIMR_TFS	(1 << 3)	/* Enable Tx FIFO Service Interrupt */
-
 /*
  * AC97 Controller registers
  */
@@ -989,77 +758,6 @@
 
 #endif
 
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
-/*
- * UHC: USB Host Controller (OHCI-like) register definitions
- */
-#define UHC_BASE_PHYS	(0x4C000000)
-#define UHCREV		__REG(0x4C000000) /* UHC HCI Spec Revision */
-#define UHCHCON		__REG(0x4C000004) /* UHC Host Control Register */
-#define UHCCOMS		__REG(0x4C000008) /* UHC Command Status Register */
-#define UHCINTS		__REG(0x4C00000C) /* UHC Interrupt Status Register */
-#define UHCINTE		__REG(0x4C000010) /* UHC Interrupt Enable */
-#define UHCINTD		__REG(0x4C000014) /* UHC Interrupt Disable */
-#define UHCHCCA		__REG(0x4C000018) /* UHC Host Controller Comm. Area */
-#define UHCPCED		__REG(0x4C00001C) /* UHC Period Current Endpt Descr */
-#define UHCCHED		__REG(0x4C000020) /* UHC Control Head Endpt Descr */
-#define UHCCCED		__REG(0x4C000024) /* UHC Control Current Endpt Descr */
-#define UHCBHED		__REG(0x4C000028) /* UHC Bulk Head Endpt Descr */
-#define UHCBCED		__REG(0x4C00002C) /* UHC Bulk Current Endpt Descr */
-#define UHCDHEAD	__REG(0x4C000030) /* UHC Done Head */
-#define UHCFMI		__REG(0x4C000034) /* UHC Frame Interval */
-#define UHCFMR		__REG(0x4C000038) /* UHC Frame Remaining */
-#define UHCFMN		__REG(0x4C00003C) /* UHC Frame Number */
-#define UHCPERS		__REG(0x4C000040) /* UHC Periodic Start */
-#define UHCLS		__REG(0x4C000044) /* UHC Low Speed Threshold */
-
-#define UHCRHDA		__REG(0x4C000048) /* UHC Root Hub Descriptor A */
-#define UHCRHDA_NOCP	(1 << 12)	/* No over current protection */
-
-#define UHCRHDB		__REG(0x4C00004C) /* UHC Root Hub Descriptor B */
-#define UHCRHS		__REG(0x4C000050) /* UHC Root Hub Status */
-#define UHCRHPS1	__REG(0x4C000054) /* UHC Root Hub Port 1 Status */
-#define UHCRHPS2	__REG(0x4C000058) /* UHC Root Hub Port 2 Status */
-#define UHCRHPS3	__REG(0x4C00005C) /* UHC Root Hub Port 3 Status */
-
-#define UHCSTAT		__REG(0x4C000060) /* UHC Status Register */
-#define UHCSTAT_UPS3	(1 << 16)	/* USB Power Sense Port3 */
-#define UHCSTAT_SBMAI	(1 << 15)	/* System Bus Master Abort Interrupt*/
-#define UHCSTAT_SBTAI	(1 << 14)	/* System Bus Target Abort Interrupt*/
-#define UHCSTAT_UPRI	(1 << 13)	/* USB Port Resume Interrupt */
-#define UHCSTAT_UPS2	(1 << 12)	/* USB Power Sense Port 2 */
-#define UHCSTAT_UPS1	(1 << 11)	/* USB Power Sense Port 1 */
-#define UHCSTAT_HTA	(1 << 10)	/* HCI Target Abort */
-#define UHCSTAT_HBA	(1 << 8)	/* HCI Buffer Active */
-#define UHCSTAT_RWUE	(1 << 7)	/* HCI Remote Wake Up Event */
-
-#define UHCHR           __REG(0x4C000064) /* UHC Reset Register */
-#define UHCHR_SSEP3	(1 << 11)	/* Sleep Standby Enable for Port3 */
-#define UHCHR_SSEP2	(1 << 10)	/* Sleep Standby Enable for Port2 */
-#define UHCHR_SSEP1	(1 << 9)	/* Sleep Standby Enable for Port1 */
-#define UHCHR_PCPL	(1 << 7)	/* Power control polarity low */
-#define UHCHR_PSPL	(1 << 6)	/* Power sense polarity low */
-#define UHCHR_SSE	(1 << 5)	/* Sleep Standby Enable */
-#define UHCHR_UIT	(1 << 4)	/* USB Interrupt Test */
-#define UHCHR_SSDC	(1 << 3)	/* Simulation Scale Down Clock */
-#define UHCHR_CGR	(1 << 2)	/* Clock Generation Reset */
-#define UHCHR_FHR	(1 << 1)	/* Force Host Controller Reset */
-#define UHCHR_FSBIR	(1 << 0)	/* Force System Bus Iface Reset */
-
-#define UHCHIE          __REG(0x4C000068) /* UHC Interrupt Enable Register*/
-#define UHCHIE_UPS3IE	(1 << 14)	/* Power Sense Port3 IntEn */
-#define UHCHIE_UPRIE	(1 << 13)	/* Port Resume IntEn */
-#define UHCHIE_UPS2IE	(1 << 12)	/* Power Sense Port2 IntEn */
-#define UHCHIE_UPS1IE	(1 << 11)	/* Power Sense Port1 IntEn */
-#define UHCHIE_TAIE	(1 << 10)	/* HCI Interface Transfer Abort
-					   Interrupt Enable*/
-#define UHCHIE_HBAIE	(1 << 8)	/* HCI Buffer Active IntEn */
-#define UHCHIE_RWIE	(1 << 7)	/* Remote Wake-up IntEn */
-
-#define UHCHIT          __REG(0x4C00006C) /* UHC Interrupt Test register */
-
-#endif /* CONFIG_PXA27x || CONFIG_PXA3xx */
-
 /* PWRMODE register M field values */
 
 #define PWRMODE_IDLE		0x1
diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h
index 39eb683..b1fcd10 100644
--- a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h
+++ b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h
@@ -131,6 +131,28 @@
 #define CKENB		__REG(0x41340010)	/* B Clock Enable Register */
 #define AC97_DIV	__REG(0x41340014)	/* AC97 clock divisor value register */
 
+#define ACCR_XPDIS		(1 << 31)	/* Core PLL Output Disable */
+#define ACCR_SPDIS		(1 << 30)	/* System PLL Output Disable */
+#define ACCR_D0CS		(1 << 26)	/* D0 Mode Clock Select */
+#define ACCR_PCCE		(1 << 11)	/* Power Mode Change Clock Enable */
+#define ACCR_DDR_D0CS		(1 << 7)	/* DDR SDRAM clock frequency in D0CS (PXA31x only) */
+
+#define ACCR_SMCFS_MASK		(0x7 << 23)	/* Static Memory Controller Frequency Select */
+#define ACCR_SFLFS_MASK		(0x3 << 18)	/* Frequency Select for Internal Memory Controller */
+#define ACCR_XSPCLK_MASK	(0x3 << 16)	/* Core Frequency during Frequency Change */
+#define ACCR_HSS_MASK		(0x3 << 14)	/* System Bus-Clock Frequency Select */
+#define ACCR_DMCFS_MASK		(0x3 << 12)	/* Dynamic Memory Controller Clock Frequency Select */
+#define ACCR_XN_MASK		(0x7 << 8)	/* Core PLL Turbo-Mode-to-Run-Mode Ratio */
+#define ACCR_XL_MASK		(0x1f)		/* Core PLL Run-Mode-to-Oscillator Ratio */
+
+#define ACCR_SMCFS(x)		(((x) & 0x7) << 23)
+#define ACCR_SFLFS(x)		(((x) & 0x3) << 18)
+#define ACCR_XSPCLK(x)		(((x) & 0x3) << 16)
+#define ACCR_HSS(x)		(((x) & 0x3) << 14)
+#define ACCR_DMCFS(x)		(((x) & 0x3) << 12)
+#define ACCR_XN(x)		(((x) & 0x7) << 8)
+#define ACCR_XL(x)		((x) & 0x1f)
+
 /*
  * Clock Enable Bit
  */
diff --git a/arch/arm/mach-pxa/include/mach/spitz.h b/arch/arm/mach-pxa/include/mach/spitz.h
index bd14365..31ac26b 100644
--- a/arch/arm/mach-pxa/include/mach/spitz.h
+++ b/arch/arm/mach-pxa/include/mach/spitz.h
@@ -16,6 +16,7 @@
 #endif
 
 #include <linux/fb.h>
+#include <linux/gpio.h>
 
 /* Spitz/Akita GPIOs */
 
@@ -100,13 +101,24 @@
 #define SPITZ_SCP_JK_A          SCOOP_GPCR_PA18  /* Low */
 #define SPITZ_SCP_ADC_TEMP_ON   SCOOP_GPCR_PA19  /* Low */
 
-#define SPITZ_SCP_IO_DIR      (SPITZ_SCP_LED_GREEN | SPITZ_SCP_JK_B | SPITZ_SCP_CHRG_ON | \
-                               SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R | SPITZ_SCP_LED_ORANGE | \
+#define SPITZ_SCP_IO_DIR      (SPITZ_SCP_JK_B | SPITZ_SCP_CHRG_ON | \
+                               SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R | \
                                SPITZ_SCP_CF_POWER | SPITZ_SCP_JK_A | SPITZ_SCP_ADC_TEMP_ON)
 #define SPITZ_SCP_IO_OUT      (SPITZ_SCP_CHRG_ON | SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R)
 #define SPITZ_SCP_SUS_CLR     (SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R | SPITZ_SCP_JK_A | SPITZ_SCP_ADC_TEMP_ON)
 #define SPITZ_SCP_SUS_SET     0
 
+#define SPITZ_SCP_GPIO_BASE	(NR_BUILTIN_GPIO)
+#define SPITZ_GPIO_LED_GREEN	(SPITZ_SCP_GPIO_BASE + 0)
+#define SPITZ_GPIO_JK_B		(SPITZ_SCP_GPIO_BASE + 1)
+#define SPITZ_GPIO_CHRG_ON	(SPITZ_SCP_GPIO_BASE + 2)
+#define SPITZ_GPIO_MUTE_L	(SPITZ_SCP_GPIO_BASE + 3)
+#define SPITZ_GPIO_MUTE_R	(SPITZ_SCP_GPIO_BASE + 4)
+#define SPITZ_GPIO_CF_POWER	(SPITZ_SCP_GPIO_BASE + 5)
+#define SPITZ_GPIO_LED_ORANGE	(SPITZ_SCP_GPIO_BASE + 6)
+#define SPITZ_GPIO_JK_A		(SPITZ_SCP_GPIO_BASE + 7)
+#define SPITZ_GPIO_ADC_TEMP_ON	(SPITZ_SCP_GPIO_BASE + 8)
+
 /* Spitz Scoop Device (No. 2) GPIOs */
 /* Suspend States in comments */
 #define SPITZ_SCP2_IR_ON           SCOOP_GPCR_PA11  /* High */
@@ -119,15 +131,36 @@
 #define SPITZ_SCP2_BACKLIGHT_ON    SCOOP_GPCR_PA18  /* Low */
 #define SPITZ_SCP2_MIC_BIAS        SCOOP_GPCR_PA19  /* Low */
 
-#define SPITZ_SCP2_IO_DIR (SPITZ_SCP2_IR_ON | SPITZ_SCP2_AKIN_PULLUP | SPITZ_SCP2_RESERVED_1 | \
+#define SPITZ_SCP2_IO_DIR (SPITZ_SCP2_AKIN_PULLUP | SPITZ_SCP2_RESERVED_1 | \
                            SPITZ_SCP2_RESERVED_2 | SPITZ_SCP2_RESERVED_3 | SPITZ_SCP2_RESERVED_4 | \
                            SPITZ_SCP2_BACKLIGHT_CONT | SPITZ_SCP2_BACKLIGHT_ON | SPITZ_SCP2_MIC_BIAS)
 
-#define SPITZ_SCP2_IO_OUT   (SPITZ_SCP2_IR_ON | SPITZ_SCP2_AKIN_PULLUP | SPITZ_SCP2_RESERVED_1)
+#define SPITZ_SCP2_IO_OUT   (SPITZ_SCP2_AKIN_PULLUP | SPITZ_SCP2_RESERVED_1)
 #define SPITZ_SCP2_SUS_CLR  (SPITZ_SCP2_RESERVED_2 | SPITZ_SCP2_RESERVED_3 | SPITZ_SCP2_RESERVED_4 | \
                              SPITZ_SCP2_BACKLIGHT_CONT | SPITZ_SCP2_BACKLIGHT_ON | SPITZ_SCP2_MIC_BIAS)
 #define SPITZ_SCP2_SUS_SET  (SPITZ_SCP2_IR_ON | SPITZ_SCP2_RESERVED_1)
 
+#define SPITZ_SCP2_GPIO_BASE		(NR_BUILTIN_GPIO + 12)
+#define SPITZ_GPIO_IR_ON		(SPITZ_SCP2_GPIO_BASE + 0)
+#define SPITZ_GPIO_AKIN_PULLUP		(SPITZ_SCP2_GPIO_BASE + 1
+#define SPITZ_GPIO_RESERVED_1		(SPITZ_SCP2_GPIO_BASE + 2)
+#define SPITZ_GPIO_RESERVED_2		(SPITZ_SCP2_GPIO_BASE + 3)
+#define SPITZ_GPIO_RESERVED_3		(SPITZ_SCP2_GPIO_BASE + 4)
+#define SPITZ_GPIO_RESERVED_4		(SPITZ_SCP2_GPIO_BASE + 5)
+#define SPITZ_GPIO_BACKLIGHT_CONT	(SPITZ_SCP2_GPIO_BASE + 6)
+#define SPITZ_GPIO_BACKLIGHT_ON		(SPITZ_SCP2_GPIO_BASE + 7)
+#define SPITZ_GPIO_MIC_BIAS		(SPITZ_SCP2_GPIO_BASE + 8)
+
+/* Akita IO Expander GPIOs */
+#define AKITA_IOEXP_GPIO_BASE		(NR_BUILTIN_GPIO + 12)
+#define AKITA_GPIO_RESERVED_0		(AKITA_IOEXP_GPIO_BASE + 0)
+#define AKITA_GPIO_RESERVED_1		(AKITA_IOEXP_GPIO_BASE + 1)
+#define AKITA_GPIO_MIC_BIAS		(AKITA_IOEXP_GPIO_BASE + 2)
+#define AKITA_GPIO_BACKLIGHT_ON		(AKITA_IOEXP_GPIO_BASE + 3)
+#define AKITA_GPIO_BACKLIGHT_CONT	(AKITA_IOEXP_GPIO_BASE + 4)
+#define AKITA_GPIO_AKIN_PULLUP		(AKITA_IOEXP_GPIO_BASE + 5)
+#define AKITA_GPIO_IR_ON		(AKITA_IOEXP_GPIO_BASE + 6)
+#define AKITA_GPIO_RESERVED_7		(AKITA_IOEXP_GPIO_BASE + 7)
 
 /* Spitz IRQ Definitions */
 
@@ -154,5 +187,4 @@
  */
 extern struct platform_device spitzscoop_device;
 extern struct platform_device spitzscoop2_device;
-extern struct platform_device spitzssp_device;
 extern struct sharpsl_charger_machinfo spitz_pm_machinfo;
diff --git a/arch/arm/mach-pxa/include/mach/ssp.h b/arch/arm/mach-pxa/include/mach/ssp.h
index a012882..cb5cb76 100644
--- a/arch/arm/mach-pxa/include/mach/ssp.h
+++ b/arch/arm/mach-pxa/include/mach/ssp.h
@@ -20,6 +20,7 @@
 #define __ASM_ARCH_SSP_H
 
 #include <linux/list.h>
+#include <linux/io.h>
 
 enum pxa_ssp_type {
 	SSP_UNDEFINED = 0,
@@ -78,6 +79,29 @@
 int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed);
 void ssp_exit(struct ssp_dev *dev);
 
+/**
+ * ssp_write_reg - Write to a SSP register
+ *
+ * @dev: SSP device to access
+ * @reg: Register to write to
+ * @val: Value to be written.
+ */
+static inline void ssp_write_reg(struct ssp_device *dev, u32 reg, u32 val)
+{
+	__raw_writel(val, dev->mmio_base + reg);
+}
+
+/**
+ * ssp_read_reg - Read from a SSP register
+ *
+ * @dev: SSP device to access
+ * @reg: Register to read from
+ */
+static inline u32 ssp_read_reg(struct ssp_device *dev, u32 reg)
+{
+	return __raw_readl(dev->mmio_base + reg);
+}
+
 struct ssp_device *ssp_request(int port, const char *label);
 void ssp_free(struct ssp_device *);
 #endif /* __ASM_ARCH_SSP_H */
diff --git a/arch/arm/mach-pxa/include/mach/trizeps4.h b/arch/arm/mach-pxa/include/mach/trizeps4.h
index 641d0ec..903e1a2 100644
--- a/arch/arm/mach-pxa/include/mach/trizeps4.h
+++ b/arch/arm/mach-pxa/include/mach/trizeps4.h
@@ -17,11 +17,16 @@
 #define TRIZEPS4_PIC_PHYS	(PXA_CS3_PHYS)	/* Logic chip on ConXS-Board */
 #define TRIZEPS4_SDRAM_BASE	0xa0000000      /* SDRAM region */
 
-#define TRIZEPS4_CFSR_PHYS	(PXA_CS3_PHYS)			/* Logic chip on ConXS-Board CSFR register */
-#define TRIZEPS4_BOCR_PHYS	(PXA_CS3_PHYS+0x02000000)	/* Logic chip on ConXS-Board BOCR register */
-#define TRIZEPS4_IRCR_PHYS	(PXA_CS3_PHYS+0x02400000)	/* Logic chip on ConXS-Board IRCR register*/
-#define TRIZEPS4_UPSR_PHYS	(PXA_CS3_PHYS+0x02800000)	/* Logic chip on ConXS-Board UPSR register*/
-#define TRIZEPS4_DICR_PHYS	(PXA_CS3_PHYS+0x03800000)	/* Logic chip on ConXS-Board DICR register*/
+				/* Logic on ConXS-board CSFR register*/
+#define TRIZEPS4_CFSR_PHYS	(PXA_CS3_PHYS)
+				/* Logic on ConXS-board BOCR register*/
+#define TRIZEPS4_BOCR_PHYS	(PXA_CS3_PHYS+0x02000000)
+				/* Logic on ConXS-board IRCR register*/
+#define TRIZEPS4_IRCR_PHYS	(PXA_CS3_PHYS+0x02400000)
+				/* Logic on ConXS-board UPSR register*/
+#define TRIZEPS4_UPSR_PHYS	(PXA_CS3_PHYS+0x02800000)
+				/* Logic on ConXS-board DICR register*/
+#define TRIZEPS4_DICR_PHYS	(PXA_CS3_PHYS+0x03800000)
 
 /* virtual memory regions */
 #define TRIZEPS4_DISK_VIRT	0xF0000000	/* Disk On Chip region */
@@ -54,6 +59,15 @@
 #define GPIO_MMC_DET		12
 #define TRIZEPS4_MMC_IRQ	IRQ_GPIO(GPIO_MMC_DET)
 
+/* DOC NAND chip */
+#define GPIO_DOC_LOCK           94
+#define GPIO_DOC_IRQ            93
+#define TRIZEPS4_DOC_IRQ        IRQ_GPIO(GPIO_DOC_IRQ)
+
+/* SPI interface */
+#define GPIO_SPI                53
+#define TRIZEPS4_SPI_IRQ        IRQ_GPIO(GPIO_SPI)
+
 /* LEDS using tx2 / rx2 */
 #define GPIO_SYS_BUSY_LED	46
 #define GPIO_HEARTBEAT_LED	47
@@ -62,24 +76,66 @@
 #define GPIO_PIC		0
 #define TRIZEPS4_PIC_IRQ	IRQ_GPIO(GPIO_PIC)
 
-#define CFSR_P2V(x)		((x) - TRIZEPS4_CFSR_PHYS + TRIZEPS4_CFSR_VIRT)
-#define CFSR_V2P(x)		((x) - TRIZEPS4_CFSR_VIRT + TRIZEPS4_CFSR_PHYS)
+#ifdef CONFIG_MACH_TRIZEPS_CONXS
+/* for CONXS base board define these registers */
+#define CFSR_P2V(x)	((x) - TRIZEPS4_CFSR_PHYS + TRIZEPS4_CFSR_VIRT)
+#define CFSR_V2P(x)	((x) - TRIZEPS4_CFSR_VIRT + TRIZEPS4_CFSR_PHYS)
 
-#define BCR_P2V(x)		((x) - TRIZEPS4_BOCR_PHYS + TRIZEPS4_BOCR_VIRT)
-#define BCR_V2P(x)		((x) - TRIZEPS4_BOCR_VIRT + TRIZEPS4_BOCR_PHYS)
+#define BCR_P2V(x)	((x) - TRIZEPS4_BOCR_PHYS + TRIZEPS4_BOCR_VIRT)
+#define BCR_V2P(x)	((x) - TRIZEPS4_BOCR_VIRT + TRIZEPS4_BOCR_PHYS)
 
-#define DCR_P2V(x)		((x) - TRIZEPS4_DICR_PHYS + TRIZEPS4_DICR_VIRT)
-#define DCR_V2P(x)		((x) - TRIZEPS4_DICR_VIRT + TRIZEPS4_DICR_PHYS)
+#define DCR_P2V(x)	((x) - TRIZEPS4_DICR_PHYS + TRIZEPS4_DICR_VIRT)
+#define DCR_V2P(x)	((x) - TRIZEPS4_DICR_VIRT + TRIZEPS4_DICR_PHYS)
+
+#define IRCR_P2V(x)	((x) - TRIZEPS4_IRCR_PHYS + TRIZEPS4_IRCR_VIRT)
+#define IRCR_V2P(x)	((x) - TRIZEPS4_IRCR_VIRT + TRIZEPS4_IRCR_PHYS)
 
 #ifndef __ASSEMBLY__
-#define ConXS_CFSR		(*((volatile unsigned short *)CFSR_P2V(0x0C000000)))
-#define ConXS_BCR		(*((volatile unsigned short *)BCR_P2V(0x0E000000)))
-#define ConXS_DCR		(*((volatile unsigned short *)DCR_P2V(0x0F800000)))
+static inline unsigned short CFSR_readw(void)
+{
+	/* [Compact Flash Status Register] is read only */
+	return *((unsigned short *)CFSR_P2V(0x0C000000));
+}
+static inline void BCR_writew(unsigned short value)
+{
+	/* [Board Control Regsiter] is write only */
+	*((unsigned short *)BCR_P2V(0x0E000000)) = value;
+}
+static inline void DCR_writew(unsigned short value)
+{
+	/* [Display Control Register] is write only */
+	*((unsigned short *)DCR_P2V(0x0E000000)) = value;
+}
+static inline void IRCR_writew(unsigned short value)
+{
+	/* [InfraRed data Control Register] is write only */
+	*((unsigned short *)IRCR_P2V(0x0E000000)) = value;
+}
 #else
 #define ConXS_CFSR		CFSR_P2V(0x0C000000)
 #define ConXS_BCR		BCR_P2V(0x0E000000)
 #define ConXS_DCR		DCR_P2V(0x0F800000)
+#define ConXS_IRCR		IRCR_P2V(0x0F800000)
 #endif
+#else
+/* for whatever baseboard define function registers */
+static inline unsigned short CFSR_readw(void)
+{
+	return 0;
+}
+static inline void BCR_writew(unsigned short value)
+{
+	;
+}
+static inline void DCR_writew(unsigned short value)
+{
+	;
+}
+static inline void IRCR_writew(unsigned short value)
+{
+	;
+}
+#endif	/* CONFIG_MACH_TRIZEPS_CONXS */
 
 #define ConXS_CFSR_BVD_MASK	0x0003
 #define ConXS_CFSR_BVD1		(1 << 0)
diff --git a/arch/arm/mach-pxa/include/mach/viper.h b/arch/arm/mach-pxa/include/mach/viper.h
new file mode 100644
index 0000000..10988c2
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/viper.h
@@ -0,0 +1,96 @@
+/*
+ * arch/arm/mach-pxa/include/mach/viper.h
+ *
+ * Author:	Ian Campbell
+ * Created:	Feb 03, 2003
+ * Copyright:	Arcom Control Systems.
+ *
+ * Maintained by Marc Zyngier <maz@misterjones.org>
+ *			      <marc.zyngier@altran.com>
+ *
+ * Created based on lubbock.h:
+ *  Author:	Nicolas Pitre
+ *  Created:	Jun 15, 2001
+ *  Copyright:	MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef ARCH_VIPER_H
+#define ARCH_VIPER_H
+
+#define VIPER_BOOT_PHYS		PXA_CS0_PHYS
+#define VIPER_FLASH_PHYS	PXA_CS1_PHYS
+#define VIPER_ETH_PHYS		PXA_CS2_PHYS
+#define VIPER_USB_PHYS		PXA_CS3_PHYS
+#define VIPER_ETH_DATA_PHYS	PXA_CS4_PHYS
+#define VIPER_CPLD_PHYS		PXA_CS5_PHYS
+
+#define VIPER_CPLD_BASE		(0xf0000000)
+#define VIPER_PC104IO_BASE	(0xf1000000)
+#define VIPER_USB_BASE		(0xf1800000)
+
+#define VIPER_ETH_GPIO		(0)
+#define VIPER_CPLD_GPIO		(1)
+#define VIPER_USB_GPIO		(2)
+#define VIPER_UARTA_GPIO	(4)
+#define VIPER_UARTB_GPIO	(3)
+#define VIPER_CF_CD_GPIO	(32)
+#define VIPER_CF_RDY_GPIO	(8)
+#define VIPER_BCKLIGHT_EN_GPIO	(9)
+#define VIPER_LCD_EN_GPIO	(10)
+#define VIPER_PSU_DATA_GPIO	(6)
+#define VIPER_PSU_CLK_GPIO	(11)
+#define VIPER_UART_SHDN_GPIO	(12)
+#define VIPER_BRIGHTNESS_GPIO	(16)
+#define VIPER_PSU_nCS_LD_GPIO	(19)
+#define VIPER_UPS_GPIO		(20)
+#define VIPER_CF_POWER_GPIO	(82)
+#define VIPER_TPM_I2C_SDA_GPIO	(26)
+#define VIPER_TPM_I2C_SCL_GPIO	(27)
+#define VIPER_RTC_I2C_SDA_GPIO	(83)
+#define VIPER_RTC_I2C_SCL_GPIO	(84)
+
+#define VIPER_CPLD_P2V(x)	((x) - VIPER_CPLD_PHYS + VIPER_CPLD_BASE)
+#define VIPER_CPLD_V2P(x)	((x) - VIPER_CPLD_BASE + VIPER_CPLD_PHYS)
+
+#ifndef __ASSEMBLY__
+#  define __VIPER_CPLD_REG(x)	(*((volatile u16 *)VIPER_CPLD_P2V(x)))
+#endif
+
+/* board level registers in the CPLD: (offsets from CPLD_BASE) ... */
+
+/* ... Physical addresses */
+#define _VIPER_LO_IRQ_STATUS	(VIPER_CPLD_PHYS + 0x100000)
+#define _VIPER_ICR_PHYS		(VIPER_CPLD_PHYS + 0x100002)
+#define _VIPER_HI_IRQ_STATUS	(VIPER_CPLD_PHYS + 0x100004)
+#define _VIPER_VERSION_PHYS	(VIPER_CPLD_PHYS + 0x100006)
+#define VIPER_UARTA_PHYS	(VIPER_CPLD_PHYS + 0x300010)
+#define VIPER_UARTB_PHYS	(VIPER_CPLD_PHYS + 0x300000)
+#define _VIPER_SRAM_BASE	(VIPER_CPLD_PHYS + 0x800000)
+
+/* ... Virtual addresses */
+#define VIPER_LO_IRQ_STATUS	__VIPER_CPLD_REG(_VIPER_LO_IRQ_STATUS)
+#define VIPER_HI_IRQ_STATUS	__VIPER_CPLD_REG(_VIPER_HI_IRQ_STATUS)
+#define VIPER_VERSION		__VIPER_CPLD_REG(_VIPER_VERSION_PHYS)
+#define VIPER_ICR		__VIPER_CPLD_REG(_VIPER_ICR_PHYS)
+
+/* Decode VIPER_VERSION register */
+#define VIPER_CPLD_REVISION(x)	(((x) >> 5) & 0x7)
+#define VIPER_BOARD_VERSION(x)	(((x) >> 3) & 0x3)
+#define VIPER_BOARD_ISSUE(x)	(((x) >> 0) & 0x7)
+
+/* Interrupt and Configuration Register (VIPER_ICR) */
+/* This is a write only register. Only CF_RST is used under Linux */
+
+extern void viper_cf_rst(int state);
+
+#define VIPER_ICR_RETRIG	(1 << 0)
+#define VIPER_ICR_AUTO_CLR	(1 << 1)
+#define VIPER_ICR_R_DIS		(1 << 2)
+#define VIPER_ICR_CF_RST	(1 << 3)
+
+#endif
+
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 5e95c53..fa69c3a 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -57,7 +57,7 @@
 
 	pxa_internal_irq_nr = irq_nr;
 
-	for (irq = 0; irq < irq_nr; irq += 32) {
+	for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq += 32) {
 		_ICMR(irq) = 0;	/* disable all IRQs */
 		_ICLR(irq) = 0;	/* all IRQs are IRQ, not FIQ */
 	}
diff --git a/arch/arm/mach-pxa/leds-trizeps4.c b/arch/arm/mach-pxa/leds-trizeps4.c
deleted file mode 100644
index 3bc2900..0000000
--- a/arch/arm/mach-pxa/leds-trizeps4.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * linux/arch/arm/mach-pxa/leds-trizeps4.c
- *
- *  Author:	Jürgen Schindele
- *  Created:	20 02, 2006
- *  Copyright:	Jürgen Schindele
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-
-#include <mach/hardware.h>
-#include <asm/system.h>
-#include <asm/types.h>
-#include <asm/leds.h>
-
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-gpio.h>
-#include <mach/trizeps4.h>
-
-#include "leds.h"
-
-#define LED_STATE_ENABLED	1
-#define LED_STATE_CLAIMED	2
-
-#define SYS_BUSY		0x01
-#define HEARTBEAT		0x02
-#define BLINK			0x04
-
-static unsigned int led_state;
-static unsigned int hw_led_state;
-
-void trizeps4_leds_event(led_event_t evt)
-{
-	unsigned long flags;
-
-	local_irq_save(flags);
-
-	switch (evt) {
-	case led_start:
-		hw_led_state = 0;
-		pxa_gpio_mode( GPIO_SYS_BUSY_LED  | GPIO_OUT);		/* LED1 */
-		pxa_gpio_mode( GPIO_HEARTBEAT_LED | GPIO_OUT);		/* LED2 */
-		led_state = LED_STATE_ENABLED;
-		break;
-
-	case led_stop:
-		led_state &= ~LED_STATE_ENABLED;
-		break;
-
-	case led_claim:
-		led_state |= LED_STATE_CLAIMED;
-		hw_led_state = 0;
-		break;
-
-	case led_release:
-		led_state &= ~LED_STATE_CLAIMED;
-		hw_led_state = 0;
-		break;
-
-#ifdef CONFIG_LEDS_TIMER
-	case led_timer:
-		hw_led_state ^= HEARTBEAT;
-		break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
-	case led_idle_start:
-		hw_led_state &= ~SYS_BUSY;
-		break;
-
-	case led_idle_end:
-		hw_led_state |= SYS_BUSY;
-		break;
-#endif
-
-	case led_halted:
-		break;
-
-	case led_green_on:
-		hw_led_state |= BLINK;
-		break;
-
-	case led_green_off:
-		hw_led_state &= ~BLINK;
-		break;
-
-	case led_amber_on:
-		break;
-
-	case led_amber_off:
-		break;
-
-	case led_red_on:
-		break;
-
-	case led_red_off:
-		break;
-
-	default:
-		break;
-	}
-
-	if  (led_state & LED_STATE_ENABLED) {
-		switch (hw_led_state) {
-			case 0:
-				GPSR(GPIO_SYS_BUSY_LED)  |= GPIO_bit(GPIO_SYS_BUSY_LED);
-				GPSR(GPIO_HEARTBEAT_LED) |= GPIO_bit(GPIO_HEARTBEAT_LED);
-				break;
-			case 1:
-				GPCR(GPIO_SYS_BUSY_LED)  |= GPIO_bit(GPIO_SYS_BUSY_LED);
-				GPSR(GPIO_HEARTBEAT_LED) |= GPIO_bit(GPIO_HEARTBEAT_LED);
-				break;
-			case 2:
-				GPSR(GPIO_SYS_BUSY_LED)  |= GPIO_bit(GPIO_SYS_BUSY_LED);
-				GPCR(GPIO_HEARTBEAT_LED) |= GPIO_bit(GPIO_HEARTBEAT_LED);
-				break;
-			case 3:
-				GPCR(GPIO_SYS_BUSY_LED)  |= GPIO_bit(GPIO_SYS_BUSY_LED);
-				GPCR(GPIO_HEARTBEAT_LED) |= GPIO_bit(GPIO_HEARTBEAT_LED);
-				break;
-		}
-	}
-	else {
-		/* turn all off */
-		GPSR(GPIO_SYS_BUSY_LED)  |= GPIO_bit(GPIO_SYS_BUSY_LED);
-		GPSR(GPIO_HEARTBEAT_LED) |= GPIO_bit(GPIO_HEARTBEAT_LED);
-	}
-
-	local_irq_restore(flags);
-}
diff --git a/arch/arm/mach-pxa/leds.c b/arch/arm/mach-pxa/leds.c
index e13eb84..bbe4d5f 100644
--- a/arch/arm/mach-pxa/leds.c
+++ b/arch/arm/mach-pxa/leds.c
@@ -24,8 +24,6 @@
 		leds_event = mainstone_leds_event;
 	if (machine_is_pxa_idp())
 		leds_event = idp_leds_event;
-	if (machine_is_trizeps4())
-		leds_event = trizeps4_leds_event;
 
 	leds_event(led_start);
 	return 0;
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
index 58f3402..b4d00ab 100644
--- a/arch/arm/mach-pxa/littleton.c
+++ b/arch/arm/mach-pxa/littleton.c
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/spi/spi.h>
 #include <linux/smc91x.h>
 
 #include <asm/types.h>
@@ -38,6 +39,7 @@
 #include <mach/gpio.h>
 #include <mach/pxafb.h>
 #include <mach/ssp.h>
+#include <mach/pxa2xx_spi.h>
 #include <mach/pxa27x_keypad.h>
 #include <mach/pxa3xx_nand.h>
 #include <mach/littleton.h>
@@ -72,8 +74,8 @@
 
 	/* SSP2 */
 	GPIO25_SSP2_SCLK,
-	GPIO17_SSP2_FRM,
 	GPIO27_SSP2_TXD,
+	GPIO17_GPIO,	/* SFRM as chip-select */
 
 	/* Debug Ethernet */
 	GPIO90_GPIO,
@@ -123,160 +125,6 @@
 };
 
 #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
-/* use bit 30, 31 as the indicator of command parameter number */
-#define CMD0(x)		((0x00000000) | ((x) << 9))
-#define CMD1(x, x1)	((0x40000000) | ((x) << 9) | 0x100 | (x1))
-#define CMD2(x, x1, x2)	((0x80000000) | ((x) << 18) | 0x20000 |\
-			 ((x1) << 9) | 0x100 | (x2))
-
-static uint32_t lcd_panel_reset[] = {
-	CMD0(0x1), /* reset */
-	CMD0(0x0), /* nop */
-	CMD0(0x0), /* nop */
-	CMD0(0x0), /* nop */
-};
-
-static uint32_t lcd_panel_on[] = {
-	CMD0(0x29),		/* Display ON */
-	CMD2(0xB8, 0xFF, 0xF9),	/* Output Control */
-	CMD0(0x11),		/* Sleep out */
-	CMD1(0xB0, 0x16),	/* Wake */
-};
-
-static uint32_t lcd_panel_off[] = {
-	CMD0(0x28),		/* Display OFF */
-	CMD2(0xB8, 0x80, 0x02),	/* Output Control */
-	CMD0(0x10),		/* Sleep in */
-	CMD1(0xB0, 0x00),	/* Deep stand by in */
-};
-
-static uint32_t lcd_vga_pass_through[] = {
-	CMD1(0xB0, 0x16),
-	CMD1(0xBC, 0x80),
-	CMD1(0xE1, 0x00),
-	CMD1(0x36, 0x50),
-	CMD1(0x3B, 0x00),
-};
-
-static uint32_t lcd_qvga_pass_through[] = {
-	CMD1(0xB0, 0x16),
-	CMD1(0xBC, 0x81),
-	CMD1(0xE1, 0x00),
-	CMD1(0x36, 0x50),
-	CMD1(0x3B, 0x22),
-};
-
-static uint32_t lcd_vga_transfer[] = {
-	CMD1(0xcf, 0x02), 	/* Blanking period control (1) */
-	CMD2(0xd0, 0x08, 0x04),	/* Blanking period control (2) */
-	CMD1(0xd1, 0x01),	/* CKV timing control on/off */
-	CMD2(0xd2, 0x14, 0x00),	/* CKV 1,2 timing control */
-	CMD2(0xd3, 0x1a, 0x0f),	/* OEV timing control */
-	CMD2(0xd4, 0x1f, 0xaf),	/* ASW timing control (1) */
-	CMD1(0xd5, 0x14),	/* ASW timing control (2) */
-	CMD0(0x21),		/* Invert for normally black display */
-	CMD0(0x29),		/* Display on */
-};
-
-static uint32_t lcd_qvga_transfer[] = {
-	CMD1(0xd6, 0x02),	/* Blanking period control (1) */
-	CMD2(0xd7, 0x08, 0x04),	/* Blanking period control (2) */
-	CMD1(0xd8, 0x01),	/* CKV timing control on/off */
-	CMD2(0xd9, 0x00, 0x08),	/* CKV 1,2 timing control */
-	CMD2(0xde, 0x05, 0x0a),	/* OEV timing control */
-	CMD2(0xdf, 0x0a, 0x19),	/* ASW timing control (1) */
-	CMD1(0xe0, 0x0a),	/* ASW timing control (2) */
-	CMD0(0x21),		/* Invert for normally black display */
-	CMD0(0x29),		/* Display on */
-};
-
-static uint32_t lcd_panel_config[] = {
-	CMD2(0xb8, 0xff, 0xf9),	/* Output control */
-	CMD0(0x11),		/* sleep out */
-	CMD1(0xba, 0x01),	/* Display mode (1) */
-	CMD1(0xbb, 0x00),	/* Display mode (2) */
-	CMD1(0x3a, 0x60),	/* Display mode 18-bit RGB */
-	CMD1(0xbf, 0x10),	/* Drive system change control */
-	CMD1(0xb1, 0x56),	/* Booster operation setup */
-	CMD1(0xb2, 0x33),	/* Booster mode setup */
-	CMD1(0xb3, 0x11),	/* Booster frequency setup */
-	CMD1(0xb4, 0x02),	/* Op amp/system clock */
-	CMD1(0xb5, 0x35),	/* VCS voltage */
-	CMD1(0xb6, 0x40),	/* VCOM voltage */
-	CMD1(0xb7, 0x03),	/* External display signal */
-	CMD1(0xbd, 0x00),	/* ASW slew rate */
-	CMD1(0xbe, 0x00),	/* Dummy data for QuadData operation */
-	CMD1(0xc0, 0x11),	/* Sleep out FR count (A) */
-	CMD1(0xc1, 0x11),	/* Sleep out FR count (B) */
-	CMD1(0xc2, 0x11),	/* Sleep out FR count (C) */
-	CMD2(0xc3, 0x20, 0x40),	/* Sleep out FR count (D) */
-	CMD2(0xc4, 0x60, 0xc0),	/* Sleep out FR count (E) */
-	CMD2(0xc5, 0x10, 0x20),	/* Sleep out FR count (F) */
-	CMD1(0xc6, 0xc0),	/* Sleep out FR count (G) */
-	CMD2(0xc7, 0x33, 0x43),	/* Gamma 1 fine tuning (1) */
-	CMD1(0xc8, 0x44),	/* Gamma 1 fine tuning (2) */
-	CMD1(0xc9, 0x33),	/* Gamma 1 inclination adjustment */
-	CMD1(0xca, 0x00),	/* Gamma 1 blue offset adjustment */
-	CMD2(0xec, 0x01, 0xf0),	/* Horizontal clock cycles */
-};
-
-static void ssp_reconfig(struct ssp_dev *dev, int nparam)
-{
-	static int last_nparam = -1;
-
-	/* check if it is necessary to re-config SSP */
-	if (nparam == last_nparam)
-		return;
-
-	ssp_disable(dev);
-	ssp_config(dev, (nparam == 2) ? 0x0010058a : 0x00100581, 0x18, 0, 0);
-
-	last_nparam = nparam;
-}
-
-static void ssp_send_cmd(uint32_t *cmd, int num)
-{
-	static int ssp_initialized;
-	static struct ssp_dev ssp2;
-
-	int i;
-
-	if (!ssp_initialized) {
-		ssp_init(&ssp2, 2, SSP_NO_IRQ);
-		ssp_initialized = 1;
-	}
-
-	clk_enable(ssp2.ssp->clk);
-	for (i = 0; i < num; i++, cmd++) {
-		ssp_reconfig(&ssp2, (*cmd >> 30) & 0x3);
-		ssp_write_word(&ssp2, *cmd & 0x3fffffff);
-
-		/* FIXME: ssp_flush() is mandatory here to work */
-		ssp_flush(&ssp2);
-	}
-	clk_disable(ssp2.ssp->clk);
-}
-
-static void littleton_lcd_power(int on, struct fb_var_screeninfo *var)
-{
-	if (on) {
-		ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_on));
-		ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_reset));
-		if (var->xres > 240) {
-			/* VGA */
-			ssp_send_cmd(ARRAY_AND_SIZE(lcd_vga_pass_through));
-			ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_config));
-			ssp_send_cmd(ARRAY_AND_SIZE(lcd_vga_transfer));
-		} else {
-			/* QVGA */
-			ssp_send_cmd(ARRAY_AND_SIZE(lcd_qvga_pass_through));
-			ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_config));
-			ssp_send_cmd(ARRAY_AND_SIZE(lcd_qvga_transfer));
-		}
-	} else
-		ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_off));
-}
-
 static struct pxafb_mode_info tpo_tdo24mtea1_modes[] = {
 	[0] = {
 		/* VGA */
@@ -312,7 +160,6 @@
 	.modes			= tpo_tdo24mtea1_modes,
 	.num_modes		= 2,
 	.lcd_conn		= LCD_COLOR_TFT_16BPP,
-	.pxafb_lcd_power	= littleton_lcd_power,
 };
 
 static void littleton_init_lcd(void)
@@ -323,6 +170,51 @@
 static inline void littleton_init_lcd(void) {};
 #endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULE */
 
+#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
+static struct pxa2xx_spi_master littleton_spi_info = {
+	.num_chipselect		= 1,
+};
+
+static void littleton_tdo24m_cs(u32 cmd)
+{
+	gpio_set_value(LITTLETON_GPIO_LCD_CS, !(cmd == PXA2XX_CS_ASSERT));
+}
+
+static struct pxa2xx_spi_chip littleton_tdo24m_chip = {
+	.rx_threshold	= 1,
+	.tx_threshold	= 1,
+	.cs_control	= littleton_tdo24m_cs,
+};
+
+static struct spi_board_info littleton_spi_devices[] __initdata = {
+	{
+		.modalias	= "tdo24m",
+		.max_speed_hz	= 1000000,
+		.bus_num	= 2,
+		.chip_select	= 0,
+		.controller_data= &littleton_tdo24m_chip,
+	},
+};
+
+static void __init littleton_init_spi(void)
+{
+	int err;
+
+	err = gpio_request(LITTLETON_GPIO_LCD_CS, "LCD_CS");
+	if (err) {
+		pr_warning("failed to request GPIO for LCS CS\n");
+		return;
+	}
+
+	gpio_direction_output(LITTLETON_GPIO_LCD_CS, 1);
+
+	pxa2xx_set_spi_info(2, &littleton_spi_info);
+	spi_register_board_info(ARRAY_AND_SIZE(littleton_spi_devices));
+}
+#else
+static inline void littleton_init_spi(void) {}
+#endif
+
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
 static unsigned int littleton_matrix_key_map[] = {
 	/* KEY(row, col, key_code) */
@@ -433,6 +325,7 @@
 	 */
 	platform_device_register(&smc91x_device);
 
+	littleton_init_spi();
 	littleton_init_lcd();
 	littleton_init_keypad();
 	littleton_init_nand();
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index b703894..de3f67d 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -40,7 +40,7 @@
 
 #include <mach/pxa-regs.h>
 #include <mach/pxa2xx-regs.h>
-#include <mach/pxa2xx-gpio.h>
+#include <mach/mfp-pxa27x.h>
 #include <mach/lpd270.h>
 #include <mach/audio.h>
 #include <mach/pxafb.h>
@@ -51,6 +51,43 @@
 #include "generic.h"
 #include "devices.h"
 
+static unsigned long lpd270_pin_config[] __initdata = {
+	/* Chip Selects */
+	GPIO15_nCS_1,	/* Mainboard Flash */
+	GPIO78_nCS_2,	/* CPLD + Ethernet */
+
+	/* LCD - 16bpp Active TFT */
+	GPIO58_LCD_LDD_0,
+	GPIO59_LCD_LDD_1,
+	GPIO60_LCD_LDD_2,
+	GPIO61_LCD_LDD_3,
+	GPIO62_LCD_LDD_4,
+	GPIO63_LCD_LDD_5,
+	GPIO64_LCD_LDD_6,
+	GPIO65_LCD_LDD_7,
+	GPIO66_LCD_LDD_8,
+	GPIO67_LCD_LDD_9,
+	GPIO68_LCD_LDD_10,
+	GPIO69_LCD_LDD_11,
+	GPIO70_LCD_LDD_12,
+	GPIO71_LCD_LDD_13,
+	GPIO72_LCD_LDD_14,
+	GPIO73_LCD_LDD_15,
+	GPIO74_LCD_FCLK,
+	GPIO75_LCD_LCLK,
+	GPIO76_LCD_PCLK,
+	GPIO77_LCD_BIAS,
+	GPIO16_PWM0_OUT,	/* Backlight */
+
+	/* USB Host */
+	GPIO88_USBH1_PWR,
+	GPIO89_USBH1_PEN,
+
+	/* AC97 */
+	GPIO45_AC97_SYSCLK,
+
+	GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
+};
 
 static unsigned int lpd270_irq_enabled;
 
@@ -88,8 +125,7 @@
 		GEDR(0) = GPIO_bit(0);  /* clear useless edge notification */
 		if (likely(pending)) {
 			irq = LPD270_IRQ(0) + __ffs(pending);
-			desc = irq_desc + irq;
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 
 			pending = __raw_readw(LPD270_INT_STATUS) &
 						lpd270_irq_enabled;
@@ -265,8 +301,8 @@
 static struct pxafb_mach_info sharp_lq057q3dc02 = {
 	.modes			= &sharp_lq057q3dc02_mode,
 	.num_modes		= 1,
-	.lccr0			= 0x07800080,
-	.lccr3			= 0x00400000,
+	.lcd_conn		= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |
+				  LCD_ALTERNATE_MAPPING,
 };
 
 /* 12.1" TFT SVGA (LoLo display number 2) */
@@ -287,8 +323,8 @@
 static struct pxafb_mach_info sharp_lq121s1dg31 = {
 	.modes			= &sharp_lq121s1dg31_mode,
 	.num_modes		= 1,
-	.lccr0			= 0x07800080,
-	.lccr3			= 0x00400000,
+	.lcd_conn		= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |
+				  LCD_ALTERNATE_MAPPING,
 };
 
 /* 3.6" TFT QVGA (LoLo display number 3) */
@@ -309,8 +345,8 @@
 static struct pxafb_mach_info sharp_lq036q1da01 = {
 	.modes			= &sharp_lq036q1da01_mode,
 	.num_modes		= 1,
-	.lccr0			= 0x07800080,
-	.lccr3			= 0x00400000,
+	.lcd_conn		= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |
+				  LCD_ALTERNATE_MAPPING,
 };
 
 /* 6.4" TFT VGA (LoLo display number 5) */
@@ -331,8 +367,8 @@
 static struct pxafb_mach_info sharp_lq64d343 = {
 	.modes			= &sharp_lq64d343_mode,
 	.num_modes		= 1,
-	.lccr0			= 0x07800080,
-	.lccr3			= 0x00400000,
+	.lcd_conn		= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |
+				  LCD_ALTERNATE_MAPPING,
 };
 
 /* 10.4" TFT VGA (LoLo display number 7) */
@@ -353,8 +389,8 @@
 static struct pxafb_mach_info sharp_lq10d368 = {
 	.modes			= &sharp_lq10d368_mode,
 	.num_modes		= 1,
-	.lccr0			= 0x07800080,
-	.lccr3			= 0x00400000,
+	.lcd_conn		= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |
+				  LCD_ALTERNATE_MAPPING,
 };
 
 /* 3.5" TFT QVGA (LoLo display number 8) */
@@ -375,8 +411,8 @@
 static struct pxafb_mach_info sharp_lq035q7db02_20 = {
 	.modes			= &sharp_lq035q7db02_20_mode,
 	.num_modes		= 1,
-	.lccr0			= 0x07800080,
-	.lccr3			= 0x00400000,
+	.lcd_conn		= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |
+				  LCD_ALTERNATE_MAPPING,
 };
 
 static struct pxafb_mach_info *lpd270_lcd_to_use;
@@ -411,27 +447,15 @@
 	&lpd270_flash_device[1],
 };
 
-static int lpd270_ohci_init(struct device *dev)
-{
-	/* setup Port1 GPIO pin. */
-	pxa_gpio_mode(88 | GPIO_ALT_FN_1_IN);	/* USBHPWR1 */
-	pxa_gpio_mode(89 | GPIO_ALT_FN_2_OUT);	/* USBHPEN1 */
-
-	/* Set the Power Control Polarity Low and Power Sense
-	   Polarity Low to active low. */
-	UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
-		~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
-
-	return 0;
-}
-
 static struct pxaohci_platform_data lpd270_ohci_platform_data = {
 	.port_mode	= PMM_PERPORT_MODE,
-	.init		= lpd270_ohci_init,
+	.flags		= ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
 };
 
 static void __init lpd270_init(void)
 {
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(lpd270_pin_config));
+
 	lpd270_flash_data[0].width = (BOOT_DEF & 1) ? 2 : 4;
 	lpd270_flash_data[1].width = 4;
 
@@ -442,12 +466,6 @@
 	 */
 	ARB_CNTRL = ARB_CORE_PARK | 0x234;
 
-	/*
-	 * On LogicPD PXA270, we route AC97_SYSCLK via GPIO45.
-	 */
-	pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD);
-	pxa_gpio_mode(GPIO16_PWM0_MD);
-
 	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
 
 	pxa_set_ac97_info(NULL);
@@ -473,15 +491,6 @@
 	pxa_map_io();
 	iotable_init(lpd270_io_desc, ARRAY_SIZE(lpd270_io_desc));
 
-	/* initialize sleep mode regs (wake-up sources, etc) */
-	PGSR0 = 0x00008800;
-	PGSR1 = 0x00000002;
-	PGSR2 = 0x0001FC00;
-	PGSR3 = 0x00001F81;
-	PWER  = 0xC0000002;
-	PRER  = 0x00000002;
-	PFER  = 0x00000002;
-
 	/* for use I SRAM as framebuffer.  */
 	PSLR |= 0x00000F04;
 	PCFR  = 0x00000066;
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 4ffdff2..bff7043 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -57,13 +57,36 @@
 
 static unsigned long lubbock_pin_config[] __initdata = {
 	GPIO15_nCS_1,	/* CS1 - Flash */
+	GPIO78_nCS_2,	/* CS2 - Baseboard FGPA */
 	GPIO79_nCS_3,	/* CS3 - SMC ethernet */
+	GPIO80_nCS_4,	/* CS4 - SA1111 */
 
 	/* SSP data pins */
 	GPIO23_SSP1_SCLK,
 	GPIO25_SSP1_TXD,
 	GPIO26_SSP1_RXD,
 
+	/* LCD - 16bpp DSTN */
+	GPIO58_LCD_LDD_0,
+	GPIO59_LCD_LDD_1,
+	GPIO60_LCD_LDD_2,
+	GPIO61_LCD_LDD_3,
+	GPIO62_LCD_LDD_4,
+	GPIO63_LCD_LDD_5,
+	GPIO64_LCD_LDD_6,
+	GPIO65_LCD_LDD_7,
+	GPIO66_LCD_LDD_8,
+	GPIO67_LCD_LDD_9,
+	GPIO68_LCD_LDD_10,
+	GPIO69_LCD_LDD_11,
+	GPIO70_LCD_LDD_12,
+	GPIO71_LCD_LDD_13,
+	GPIO72_LCD_LDD_14,
+	GPIO73_LCD_LDD_15,
+	GPIO74_LCD_FCLK,
+	GPIO75_LCD_LCLK,
+	GPIO76_LCD_PCLK,
+
 	/* BTUART */
 	GPIO42_BTUART_RXD,
 	GPIO43_BTUART_TXD,
@@ -132,8 +155,7 @@
 		GEDR(0) = GPIO_bit(0);	/* clear our parent irq */
 		if (likely(pending)) {
 			irq = LUBBOCK_IRQ(0) + __ffs(pending);
-			desc = irq_desc + irq;
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 		}
 		pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
 	} while (pending);
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 143f28a..519138b 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -409,7 +409,7 @@
  * LEDs
  */
 
-struct gpio_led gpio_leds[] = {
+static struct gpio_led gpio_leds[] = {
 	{
 		.name = "magician::vibra",
 		.default_trigger = "none",
@@ -669,18 +669,10 @@
  * USB OHCI
  */
 
-static int magician_ohci_init(struct device *dev)
-{
-	UHCHR = (UHCHR | UHCHR_SSEP2 | UHCHR_PCPL | UHCHR_CGR) &
-	    ~(UHCHR_SSEP1 | UHCHR_SSEP3 | UHCHR_SSE);
-
-	return 0;
-}
-
 static struct pxaohci_platform_data magician_ohci_info = {
-	.port_mode    = PMM_PERPORT_MODE,
-	.init         = magician_ohci_init,
-	.power_budget = 0,
+	.port_mode	= PMM_PERPORT_MODE,
+	.flags		= ENABLE_PORT1 | ENABLE_PORT3 | POWER_CONTROL_LOW,
+	.power_budget	= 0,
 };
 
 
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index d44af76..f2c7ad8 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -162,8 +162,7 @@
 		GEDR(0) = GPIO_bit(0);  /* clear useless edge notification */
 		if (likely(pending)) {
 			irq = MAINSTONE_IRQ(0) + __ffs(pending);
-			desc = irq_desc + irq;
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 		}
 		pending = MST_INTSETCLR & mainstone_irq_enabled;
 	} while (pending);
@@ -508,19 +507,9 @@
 	&mst_gpio_keys_device,
 };
 
-static int mainstone_ohci_init(struct device *dev)
-{
-	/* Set the Power Control Polarity Low and Power Sense
-	   Polarity Low to active low. */
-	UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
-		~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
-
-	return 0;
-}
-
 static struct pxaohci_platform_data mainstone_ohci_platform_data = {
 	.port_mode	= PMM_PERPORT_MODE,
-	.init		= mainstone_ohci_init,
+	.flags		= ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
 };
 
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c
index 925575f..2061c00 100644
--- a/arch/arm/mach-pxa/mfp-pxa2xx.c
+++ b/arch/arm/mach-pxa/mfp-pxa2xx.c
@@ -25,7 +25,12 @@
 
 #include "generic.h"
 
-#define PGSR(x)		__REG2(0x40F00020, ((x) & 0x60) >> 3)
+#define gpio_to_bank(gpio)	((gpio) >> 5)
+
+#define PGSR(x)		__REG2(0x40F00020, (x) << 2)
+#define __GAFR(u, x)	__REG2((u) ? 0x40E00058 : 0x40E00054, (x) << 3)
+#define GAFR_L(x)	__GAFR(0, x)
+#define GAFR_U(x)	__GAFR(1, x)
 
 #define PWER_WE35	(1 << 24)
 
@@ -38,49 +43,59 @@
 };
 
 static struct gpio_desc gpio_desc[MFP_PIN_GPIO127 + 1];
+static int gpio_nr;
 
-static int __mfp_config_lpm(unsigned gpio, unsigned long lpm)
-{
-	unsigned mask = GPIO_bit(gpio);
-
-	/* low power state */
-	switch (lpm) {
-	case MFP_LPM_DRIVE_HIGH:
-		PGSR(gpio) |= mask;
-		break;
-	case MFP_LPM_DRIVE_LOW:
-		PGSR(gpio) &= ~mask;
-		break;
-	case MFP_LPM_INPUT:
-		break;
-	default:
-		pr_warning("%s: invalid low power state for GPIO%d\n",
-				__func__, gpio);
-		return -EINVAL;
-	}
-	return 0;
-}
+static unsigned long gpdr_lpm[4];
 
 static int __mfp_config_gpio(unsigned gpio, unsigned long c)
 {
 	unsigned long gafr, mask = GPIO_bit(gpio);
-	int fn;
+	int bank = gpio_to_bank(gpio);
+	int uorl = !!(gpio & 0x10); /* GAFRx_U or GAFRx_L ? */
+	int shft = (gpio & 0xf) << 1;
+	int fn = MFP_AF(c);
+	int dir = c & MFP_DIR_OUT;
 
-	fn = MFP_AF(c);
 	if (fn > 3)
 		return -EINVAL;
 
-	/* alternate function and direction */
-	gafr = GAFR(gpio) & ~(0x3 << ((gpio & 0xf) * 2));
-	GAFR(gpio) = gafr |  (fn  << ((gpio & 0xf) * 2));
+	/* alternate function and direction at run-time */
+	gafr = (uorl == 0) ? GAFR_L(bank) : GAFR_U(bank);
+	gafr = (gafr & ~(0x3 << shft)) | (fn << shft);
 
-	if (c & MFP_DIR_OUT)
+	if (uorl == 0)
+		GAFR_L(bank) = gafr;
+	else
+		GAFR_U(bank) = gafr;
+
+	if (dir == MFP_DIR_OUT)
 		GPDR(gpio) |= mask;
 	else
 		GPDR(gpio) &= ~mask;
 
-	if (__mfp_config_lpm(gpio, c & MFP_LPM_STATE_MASK))
-		return -EINVAL;
+	/* alternate function and direction at low power mode */
+	switch (c & MFP_LPM_STATE_MASK) {
+	case MFP_LPM_DRIVE_HIGH:
+		PGSR(bank) |= mask;
+		dir = MFP_DIR_OUT;
+		break;
+	case MFP_LPM_DRIVE_LOW:
+		PGSR(bank) &= ~mask;
+		dir = MFP_DIR_OUT;
+		break;
+	case MFP_LPM_DEFAULT:
+		break;
+	default:
+		/* warning and fall through, treat as MFP_LPM_DEFAULT */
+		pr_warning("%s: GPIO%d: unsupported low power mode\n",
+				__func__, gpio);
+		break;
+	}
+
+	if (dir == MFP_DIR_OUT)
+		gpdr_lpm[bank] |= mask;
+	else
+		gpdr_lpm[bank] &= ~mask;
 
 	/* give early warning if MFP_LPM_CAN_WAKEUP is set on the
 	 * configurations of those pins not able to wakeup
@@ -91,7 +106,7 @@
 		return -EINVAL;
 	}
 
-	if ((c & MFP_LPM_CAN_WAKEUP) && (c & MFP_DIR_OUT)) {
+	if ((c & MFP_LPM_CAN_WAKEUP) && (dir == MFP_DIR_OUT)) {
 		pr_warning("%s: output GPIO%d unable to wakeup\n",
 				__func__, gpio);
 		return -EINVAL;
@@ -135,7 +150,7 @@
 
 void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm)
 {
-	unsigned long flags;
+	unsigned long flags, c;
 	int gpio;
 
 	gpio = __mfp_validate(mfp);
@@ -143,7 +158,11 @@
 		return;
 
 	local_irq_save(flags);
-	__mfp_config_lpm(gpio, lpm);
+
+	c = gpio_desc[gpio].config;
+	c = (c & ~MFP_LPM_STATE_MASK) | lpm;
+	__mfp_config_gpio(gpio, c);
+
 	local_irq_restore(flags);
 }
 
@@ -187,23 +206,22 @@
 }
 
 #ifdef CONFIG_PXA25x
-static int __init pxa25x_mfp_init(void)
+static void __init pxa25x_mfp_init(void)
 {
 	int i;
 
-	if (cpu_is_pxa25x()) {
-		for (i = 0; i <= 84; i++)
-			gpio_desc[i].valid = 1;
+	for (i = 0; i <= 84; i++)
+		gpio_desc[i].valid = 1;
 
-		for (i = 0; i <= 15; i++) {
-			gpio_desc[i].can_wakeup = 1;
-			gpio_desc[i].mask = GPIO_bit(i);
-		}
+	for (i = 0; i <= 15; i++) {
+		gpio_desc[i].can_wakeup = 1;
+		gpio_desc[i].mask = GPIO_bit(i);
 	}
 
-	return 0;
+	gpio_nr = 85;
 }
-postcore_initcall(pxa25x_mfp_init);
+#else
+static inline void pxa25x_mfp_init(void) {}
 #endif /* CONFIG_PXA25x */
 
 #ifdef CONFIG_PXA27x
@@ -233,45 +251,106 @@
 	return 0;
 }
 
-static int __init pxa27x_mfp_init(void)
+static void __init pxa27x_mfp_init(void)
 {
 	int i, gpio;
 
-	if (cpu_is_pxa27x()) {
-		for (i = 0; i <= 120; i++) {
-			/* skip GPIO2, 5, 6, 7, 8, they are not
-			 * valid pins allow configuration
-			 */
-			if (i == 2 || i == 5 || i == 6 ||
-			    i == 7 || i == 8)
-				continue;
+	for (i = 0; i <= 120; i++) {
+		/* skip GPIO2, 5, 6, 7, 8, they are not
+		 * valid pins allow configuration
+		 */
+		if (i == 2 || i == 5 || i == 6 || i == 7 || i == 8)
+			continue;
 
-			gpio_desc[i].valid = 1;
-		}
-
-		/* Keypad GPIOs */
-		for (i = 0; i < ARRAY_SIZE(pxa27x_pkwr_gpio); i++) {
-			gpio = pxa27x_pkwr_gpio[i];
-			gpio_desc[gpio].can_wakeup = 1;
-			gpio_desc[gpio].keypad_gpio = 1;
-			gpio_desc[gpio].mask = 1 << i;
-		}
-
-		/* Overwrite GPIO13 as a PWER wakeup source */
-		for (i = 0; i <= 15; i++) {
-			/* skip GPIO2, 5, 6, 7, 8 */
-			if (GPIO_bit(i) & 0x1e4)
-				continue;
-
-			gpio_desc[i].can_wakeup = 1;
-			gpio_desc[i].mask = GPIO_bit(i);
-		}
-
-		gpio_desc[35].can_wakeup = 1;
-		gpio_desc[35].mask = PWER_WE35;
+		gpio_desc[i].valid = 1;
 	}
 
+	/* Keypad GPIOs */
+	for (i = 0; i < ARRAY_SIZE(pxa27x_pkwr_gpio); i++) {
+		gpio = pxa27x_pkwr_gpio[i];
+		gpio_desc[gpio].can_wakeup = 1;
+		gpio_desc[gpio].keypad_gpio = 1;
+		gpio_desc[gpio].mask = 1 << i;
+	}
+
+	/* Overwrite GPIO13 as a PWER wakeup source */
+	for (i = 0; i <= 15; i++) {
+		/* skip GPIO2, 5, 6, 7, 8 */
+		if (GPIO_bit(i) & 0x1e4)
+			continue;
+
+		gpio_desc[i].can_wakeup = 1;
+		gpio_desc[i].mask = GPIO_bit(i);
+	}
+
+	gpio_desc[35].can_wakeup = 1;
+	gpio_desc[35].mask = PWER_WE35;
+
+	gpio_nr = 121;
+}
+#else
+static inline void pxa27x_mfp_init(void) {}
+#endif /* CONFIG_PXA27x */
+
+#ifdef CONFIG_PM
+static unsigned long saved_gafr[2][4];
+static unsigned long saved_gpdr[4];
+
+static int pxa2xx_mfp_suspend(struct sys_device *d, pm_message_t state)
+{
+	int i;
+
+	for (i = 0; i <= gpio_to_bank(gpio_nr); i++) {
+
+		saved_gafr[0][i] = GAFR_L(i);
+		saved_gafr[1][i] = GAFR_U(i);
+		saved_gpdr[i] = GPDR(i * 32);
+
+		GPDR(i * 32) = gpdr_lpm[i];
+	}
 	return 0;
 }
-postcore_initcall(pxa27x_mfp_init);
-#endif /* CONFIG_PXA27x */
+
+static int pxa2xx_mfp_resume(struct sys_device *d)
+{
+	int i;
+
+	for (i = 0; i <= gpio_to_bank(gpio_nr); i++) {
+		GAFR_L(i) = saved_gafr[0][i];
+		GAFR_U(i) = saved_gafr[1][i];
+		GPDR(i * 32) = saved_gpdr[i];
+	}
+	PSSR = PSSR_RDH | PSSR_PH;
+	return 0;
+}
+#else
+#define pxa2xx_mfp_suspend	NULL
+#define pxa2xx_mfp_resume	NULL
+#endif
+
+struct sysdev_class pxa2xx_mfp_sysclass = {
+	.name		= "mfp",
+	.suspend	= pxa2xx_mfp_suspend,
+	.resume		= pxa2xx_mfp_resume,
+};
+
+static int __init pxa2xx_mfp_init(void)
+{
+	int i;
+
+	if (!cpu_is_pxa2xx())
+		return 0;
+
+	if (cpu_is_pxa25x())
+		pxa25x_mfp_init();
+
+	if (cpu_is_pxa27x())
+		pxa27x_mfp_init();
+
+	/* initialize gafr_run[], pgsr_lpm[] from existing values */
+	for (i = 0; i <= gpio_to_bank(gpio_nr); i++)
+		gpdr_lpm[i] = GPDR(i * 32);
+
+	return sysdev_class_register(&pxa2xx_mfp_sysclass);
+}
+postcore_initcall(pxa2xx_mfp_init);
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
new file mode 100644
index 0000000..0842c53
--- /dev/null
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -0,0 +1,905 @@
+/*
+ * Handles the Mitac Mio A701 Board
+ *
+ * Copyright (C) 2008 Robert Jarzmik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/input.h>
+#include <linux/delay.h>
+#include <linux/gpio_keys.h>
+#include <linux/pwm_backlight.h>
+#include <linux/rtc.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/pda_power.h>
+#include <linux/power_supply.h>
+#include <linux/wm97xx.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/mfp-pxa27x.h>
+#include <mach/pxa27x_keypad.h>
+#include <mach/pxafb.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/mmc.h>
+#include <mach/udc.h>
+#include <mach/pxa27x-udc.h>
+
+#include <mach/mioa701.h>
+
+#include "generic.h"
+#include "devices.h"
+
+static unsigned long mioa701_pin_config[] = {
+	/* Mio global */
+	MIO_CFG_OUT(GPIO9_CHARGE_nEN, AF0, DRIVE_LOW),
+	MIO_CFG_OUT(GPIO18_POWEROFF, AF0, DRIVE_LOW),
+	MFP_CFG_OUT(GPIO3, AF0, DRIVE_HIGH),
+	MFP_CFG_OUT(GPIO4, AF0, DRIVE_HIGH),
+
+	/* Backlight PWM 0 */
+	GPIO16_PWM0_OUT,
+
+	/* MMC */
+	GPIO32_MMC_CLK,
+	GPIO92_MMC_DAT_0,
+	GPIO109_MMC_DAT_1,
+	GPIO110_MMC_DAT_2,
+	GPIO111_MMC_DAT_3,
+	GPIO112_MMC_CMD,
+	MIO_CFG_IN(GPIO78_SDIO_RO, AF0),
+	MIO_CFG_IN(GPIO15_SDIO_INSERT, AF0),
+	MIO_CFG_OUT(GPIO91_SDIO_EN, AF0, DRIVE_LOW),
+
+	/* USB */
+	MIO_CFG_IN(GPIO13_USB_DETECT, AF0),
+	MIO_CFG_OUT(GPIO22_USB_ENABLE, AF0, DRIVE_LOW),
+
+	/* LCD */
+	GPIO58_LCD_LDD_0,
+	GPIO59_LCD_LDD_1,
+	GPIO60_LCD_LDD_2,
+	GPIO61_LCD_LDD_3,
+	GPIO62_LCD_LDD_4,
+	GPIO63_LCD_LDD_5,
+	GPIO64_LCD_LDD_6,
+	GPIO65_LCD_LDD_7,
+	GPIO66_LCD_LDD_8,
+	GPIO67_LCD_LDD_9,
+	GPIO68_LCD_LDD_10,
+	GPIO69_LCD_LDD_11,
+	GPIO70_LCD_LDD_12,
+	GPIO71_LCD_LDD_13,
+	GPIO72_LCD_LDD_14,
+	GPIO73_LCD_LDD_15,
+	GPIO74_LCD_FCLK,
+	GPIO75_LCD_LCLK,
+	GPIO76_LCD_PCLK,
+
+	/* Bluetooth */
+	GPIO44_BTUART_CTS,
+	GPIO42_BTUART_RXD,
+	GPIO45_BTUART_RTS,
+	GPIO43_BTUART_TXD,
+	MIO_CFG_OUT(GPIO83_BT_ON, AF0, DRIVE_LOW),
+
+	/* GPS */
+	MIO_CFG_OUT(GPIO23_GPS_UNKNOWN1, AF0, DRIVE_LOW),
+	MIO_CFG_OUT(GPIO26_GPS_ON, AF0, DRIVE_LOW),
+	MIO_CFG_OUT(GPIO27_GPS_RESET, AF0, DRIVE_LOW),
+	MIO_CFG_OUT(GPIO106_GPS_UNKNOWN2, AF0, DRIVE_LOW),
+	MIO_CFG_OUT(GPIO107_GPS_UNKNOWN3, AF0, DRIVE_LOW),
+	GPIO46_STUART_RXD,
+	GPIO47_STUART_TXD,
+
+	/* GSM */
+	MIO_CFG_OUT(GPIO24_GSM_MOD_RESET_CMD, AF0, DRIVE_LOW),
+	MIO_CFG_OUT(GPIO88_GSM_nMOD_ON_CMD, AF0, DRIVE_HIGH),
+	MIO_CFG_OUT(GPIO90_GSM_nMOD_OFF_CMD, AF0, DRIVE_HIGH),
+	MIO_CFG_OUT(GPIO114_GSM_nMOD_DTE_UART_STATE, AF0, DRIVE_HIGH),
+	MIO_CFG_IN(GPIO25_GSM_MOD_ON_STATE, AF0),
+	MIO_CFG_IN(GPIO113_GSM_EVENT, AF0) | WAKEUP_ON_EDGE_BOTH,
+	GPIO34_FFUART_RXD,
+	GPIO35_FFUART_CTS,
+	GPIO36_FFUART_DCD,
+	GPIO37_FFUART_DSR,
+	GPIO39_FFUART_TXD,
+	GPIO40_FFUART_DTR,
+	GPIO41_FFUART_RTS,
+
+	/* Sound */
+	GPIO89_AC97_SYSCLK,
+	MIO_CFG_IN(GPIO12_HPJACK_INSERT, AF0),
+
+	/* Leds */
+	MIO_CFG_OUT(GPIO10_LED_nCharging, AF0, DRIVE_HIGH),
+	MIO_CFG_OUT(GPIO97_LED_nBlue, AF0, DRIVE_HIGH),
+	MIO_CFG_OUT(GPIO98_LED_nOrange, AF0, DRIVE_HIGH),
+	MIO_CFG_OUT(GPIO82_LED_nVibra, AF0, DRIVE_HIGH),
+	MIO_CFG_OUT(GPIO115_LED_nKeyboard, AF0, DRIVE_HIGH),
+
+	/* Keyboard */
+	MIO_CFG_IN(GPIO0_KEY_POWER, AF0) | WAKEUP_ON_EDGE_BOTH,
+	MIO_CFG_IN(GPIO93_KEY_VOLUME_UP, AF0),
+	MIO_CFG_IN(GPIO94_KEY_VOLUME_DOWN, AF0),
+	GPIO100_KP_MKIN_0,
+	GPIO101_KP_MKIN_1,
+	GPIO102_KP_MKIN_2,
+	GPIO103_KP_MKOUT_0,
+	GPIO104_KP_MKOUT_1,
+	GPIO105_KP_MKOUT_2,
+
+	/* Unknown */
+	MFP_CFG_IN(GPIO14, AF0),
+	MFP_CFG_IN(GPIO20, AF0),
+	MFP_CFG_IN(GPIO21, AF0),
+	MFP_CFG_IN(GPIO33, AF0),
+	MFP_CFG_OUT(GPIO49, AF0, DRIVE_HIGH),
+	MFP_CFG_OUT(GPIO57, AF0, DRIVE_HIGH),
+	MFP_CFG_OUT(GPIO77, AF0, DRIVE_HIGH),
+	MFP_CFG_IN(GPIO80, AF0),
+	MFP_CFG_OUT(GPIO86, AF0, DRIVE_HIGH),
+	MFP_CFG_IN(GPIO96, AF0),
+	MFP_CFG_OUT(GPIO116, AF0, DRIVE_HIGH),
+};
+
+#define MIO_GPIO_IN(num, _desc) \
+	{ .gpio = (num), .dir = 0, .desc = (_desc) }
+#define MIO_GPIO_OUT(num, _init, _desc) \
+	{ .gpio = (num), .dir = 1, .init = (_init), .desc = (_desc) }
+struct gpio_ress {
+	unsigned gpio : 8;
+	unsigned dir : 1;
+	unsigned init : 1;
+	char *desc;
+};
+
+static int mio_gpio_request(struct gpio_ress *gpios, int size)
+{
+	int i, rc = 0;
+	int gpio;
+	int dir;
+
+	for (i = 0; (!rc) && (i < size); i++) {
+		gpio = gpios[i].gpio;
+		dir = gpios[i].dir;
+		rc = gpio_request(gpio, gpios[i].desc);
+		if (rc) {
+			printk(KERN_ERR "Error requesting GPIO %d(%s) : %d\n",
+			       gpio, gpios[i].desc, rc);
+			continue;
+		}
+		if (dir)
+			gpio_direction_output(gpio, gpios[i].init);
+		else
+			gpio_direction_input(gpio);
+	}
+	while ((rc) && (--i >= 0))
+		gpio_free(gpios[i].gpio);
+	return rc;
+}
+
+static void mio_gpio_free(struct gpio_ress *gpios, int size)
+{
+	int i;
+
+	for (i = 0; i < size; i++)
+		gpio_free(gpios[i].gpio);
+}
+
+/* LCD Screen and Backlight */
+static struct platform_pwm_backlight_data mioa701_backlight_data = {
+	.pwm_id		= 0,
+	.max_brightness	= 100,
+	.dft_brightness	= 50,
+	.pwm_period_ns	= 4000 * 1024,	/* Fl = 250kHz */
+};
+
+/*
+ * LTM0305A776C LCD panel timings
+ *
+ * see:
+ *  - the LTM0305A776C datasheet,
+ *  - and the PXA27x Programmers' manual
+ */
+static struct pxafb_mode_info mioa701_ltm0305a776c = {
+	.pixclock		= 220000,	/* CLK=4.545 MHz */
+	.xres			= 240,
+	.yres			= 320,
+	.bpp			= 16,
+	.hsync_len		= 4,
+	.vsync_len		= 2,
+	.left_margin		= 6,
+	.right_margin		= 4,
+	.upper_margin		= 5,
+	.lower_margin		= 3,
+};
+
+static void mioa701_lcd_power(int on, struct fb_var_screeninfo *si)
+{
+	gpio_set_value(GPIO87_LCD_POWER, on);
+}
+
+static struct pxafb_mach_info mioa701_pxafb_info = {
+	.modes			= &mioa701_ltm0305a776c,
+	.num_modes		= 1,
+	.lcd_conn		= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+	.pxafb_lcd_power	= mioa701_lcd_power,
+};
+
+/*
+ * Keyboard configuration
+ */
+static unsigned int mioa701_matrix_keys[] = {
+	KEY(0, 0, KEY_UP),
+	KEY(0, 1, KEY_RIGHT),
+	KEY(0, 2, KEY_MEDIA),
+	KEY(1, 0, KEY_DOWN),
+	KEY(1, 1, KEY_ENTER),
+	KEY(1, 2, KEY_CONNECT),	/* GPS key */
+	KEY(2, 0, KEY_LEFT),
+	KEY(2, 1, KEY_PHONE),	/* Phone Green key */
+	KEY(2, 2, KEY_CAMERA)	/* Camera key */
+};
+static struct pxa27x_keypad_platform_data mioa701_keypad_info = {
+	.matrix_key_rows = 3,
+	.matrix_key_cols = 3,
+	.matrix_key_map = mioa701_matrix_keys,
+	.matrix_key_map_size = ARRAY_SIZE(mioa701_matrix_keys),
+};
+
+/*
+ * GPIO Key Configuration
+ */
+#define MIO_KEY(key, _gpio, _desc, _wakeup) \
+	{ .code = (key), .gpio = (_gpio), .active_low = 0, \
+	.desc = (_desc), .type = EV_KEY, .wakeup = (_wakeup) }
+static struct gpio_keys_button mioa701_button_table[] = {
+	MIO_KEY(KEY_EXIT, GPIO0_KEY_POWER, "Power button", 1),
+	MIO_KEY(KEY_VOLUMEUP, GPIO93_KEY_VOLUME_UP, "Volume up", 0),
+	MIO_KEY(KEY_VOLUMEDOWN, GPIO94_KEY_VOLUME_DOWN, "Volume down", 0),
+	MIO_KEY(KEY_HP, GPIO12_HPJACK_INSERT, "HP jack detect", 0)
+};
+
+static struct gpio_keys_platform_data mioa701_gpio_keys_data = {
+	.buttons  = mioa701_button_table,
+	.nbuttons = ARRAY_SIZE(mioa701_button_table),
+};
+
+/*
+ * Leds and vibrator
+ */
+#define ONE_LED(_gpio, _name) \
+{ .gpio = (_gpio), .name = (_name), .active_low = true }
+static struct gpio_led gpio_leds[] = {
+	ONE_LED(GPIO10_LED_nCharging, "mioa701:charging"),
+	ONE_LED(GPIO97_LED_nBlue, "mioa701:blue"),
+	ONE_LED(GPIO98_LED_nOrange, "mioa701:orange"),
+	ONE_LED(GPIO82_LED_nVibra, "mioa701:vibra"),
+	ONE_LED(GPIO115_LED_nKeyboard, "mioa701:keyboard")
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+	.leds = gpio_leds,
+	.num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+/*
+ * GSM Sagem XS200 chip
+ *
+ * GSM handling was purged from kernel. For history, this is the way to go :
+ *   - init : GPIO24_GSM_MOD_RESET_CMD = 0, GPIO114_GSM_nMOD_DTE_UART_STATE = 1
+ *            GPIO88_GSM_nMOD_ON_CMD = 1, GPIO90_GSM_nMOD_OFF_CMD = 1
+ *   - reset : GPIO24_GSM_MOD_RESET_CMD = 1, msleep(100),
+ *             GPIO24_GSM_MOD_RESET_CMD = 0
+ *   - turn on  : GPIO88_GSM_nMOD_ON_CMD = 0, msleep(1000),
+ *                GPIO88_GSM_nMOD_ON_CMD = 1
+ *   - turn off : GPIO90_GSM_nMOD_OFF_CMD = 0, msleep(1000),
+ *                GPIO90_GSM_nMOD_OFF_CMD = 1
+ */
+static int is_gsm_on(void)
+{
+	int is_on;
+
+	is_on = !!gpio_get_value(GPIO25_GSM_MOD_ON_STATE);
+	return is_on;
+}
+
+irqreturn_t gsm_on_irq(int irq, void *p)
+{
+	printk(KERN_DEBUG "Mioa701: GSM status changed to %s\n",
+	       is_gsm_on() ? "on" : "off");
+	return IRQ_HANDLED;
+}
+
+struct gpio_ress gsm_gpios[] = {
+	MIO_GPIO_IN(GPIO25_GSM_MOD_ON_STATE, "GSM state"),
+	MIO_GPIO_IN(GPIO113_GSM_EVENT, "GSM event"),
+};
+
+static int __init gsm_init(void)
+{
+	int rc;
+
+	rc = mio_gpio_request(ARRAY_AND_SIZE(gsm_gpios));
+	if (rc)
+		goto err_gpio;
+	rc = request_irq(gpio_to_irq(GPIO25_GSM_MOD_ON_STATE), gsm_on_irq,
+			 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+			 "GSM XS200 Power Irq", NULL);
+	if (rc)
+		goto err_irq;
+
+	gpio_set_wake(GPIO113_GSM_EVENT, 1);
+	return 0;
+
+err_irq:
+	printk(KERN_ERR "Mioa701: Can't request GSM_ON irq\n");
+	mio_gpio_free(ARRAY_AND_SIZE(gsm_gpios));
+err_gpio:
+	printk(KERN_ERR "Mioa701: gsm not available\n");
+	return rc;
+}
+
+static void gsm_exit(void)
+{
+	free_irq(gpio_to_irq(GPIO25_GSM_MOD_ON_STATE), NULL);
+	mio_gpio_free(ARRAY_AND_SIZE(gsm_gpios));
+}
+
+/*
+ * Bluetooth BRF6150 chip
+ *
+ * BT handling was purged from kernel. For history, this is the way to go :
+ * - turn on  : GPIO83_BT_ON = 1
+ * - turn off : GPIO83_BT_ON = 0
+ */
+
+/*
+ * GPS Sirf Star III chip
+ *
+ * GPS handling was purged from kernel. For history, this is the way to go :
+ * - init : GPIO23_GPS_UNKNOWN1 = 1, GPIO26_GPS_ON = 0, GPIO27_GPS_RESET = 0
+ *          GPIO106_GPS_UNKNOWN2 = 0, GPIO107_GPS_UNKNOWN3 = 0
+ * - turn on  : GPIO27_GPS_RESET = 1, GPIO26_GPS_ON = 1
+ * - turn off : GPIO26_GPS_ON = 0, GPIO27_GPS_RESET = 0
+ */
+
+/*
+ * USB UDC
+ */
+static void udc_power_command(int cmd)
+{
+	switch (cmd) {
+	case PXA2XX_UDC_CMD_DISCONNECT:
+		gpio_set_value(GPIO22_USB_ENABLE, 0);
+		break;
+	case PXA2XX_UDC_CMD_CONNECT:
+		gpio_set_value(GPIO22_USB_ENABLE, 1);
+		break;
+	default:
+		printk(KERN_INFO "udc_control: unknown command (0x%x)!\n", cmd);
+		break;
+	}
+}
+
+static int is_usb_connected(void)
+{
+	return !!gpio_get_value(GPIO13_USB_DETECT);
+}
+
+static struct pxa2xx_udc_mach_info mioa701_udc_info = {
+	.udc_is_connected = is_usb_connected,
+	.udc_command	  = udc_power_command,
+};
+
+struct gpio_ress udc_gpios[] = {
+	MIO_GPIO_OUT(GPIO22_USB_ENABLE, 0, "USB Vbus enable")
+};
+
+static int __init udc_init(void)
+{
+	pxa_set_udc_info(&mioa701_udc_info);
+	return mio_gpio_request(ARRAY_AND_SIZE(udc_gpios));
+}
+
+static void udc_exit(void)
+{
+	mio_gpio_free(ARRAY_AND_SIZE(udc_gpios));
+}
+
+/*
+ * SDIO/MMC Card controller
+ */
+static void mci_setpower(struct device *dev, unsigned int vdd)
+{
+	struct pxamci_platform_data *p_d = dev->platform_data;
+
+	if ((1 << vdd) & p_d->ocr_mask)
+		gpio_set_value(GPIO91_SDIO_EN, 1);	/* enable SDIO power */
+	else
+		gpio_set_value(GPIO91_SDIO_EN, 0);	/* disable SDIO power */
+}
+
+static int mci_get_ro(struct device *dev)
+{
+	return gpio_get_value(GPIO78_SDIO_RO);
+}
+
+struct gpio_ress mci_gpios[] = {
+	MIO_GPIO_IN(GPIO78_SDIO_RO, 	"SDIO readonly detect"),
+	MIO_GPIO_IN(GPIO15_SDIO_INSERT,	"SDIO insertion detect"),
+	MIO_GPIO_OUT(GPIO91_SDIO_EN, 0,	"SDIO power enable")
+};
+
+static void mci_exit(struct device *dev, void *data)
+{
+	mio_gpio_free(ARRAY_AND_SIZE(mci_gpios));
+	free_irq(gpio_to_irq(GPIO15_SDIO_INSERT), data);
+}
+
+static struct pxamci_platform_data mioa701_mci_info;
+
+/**
+ * The card detect interrupt isn't debounced so we delay it by 250ms
+ * to give the card a chance to fully insert/eject.
+ */
+static int mci_init(struct device *dev, irq_handler_t detect_int, void *data)
+{
+	int rc;
+	int irq = gpio_to_irq(GPIO15_SDIO_INSERT);
+
+	rc = mio_gpio_request(ARRAY_AND_SIZE(mci_gpios));
+	if (rc)
+		goto err_gpio;
+	/* enable RE/FE interrupt on card insertion and removal */
+	rc = request_irq(irq, detect_int,
+			 IRQF_DISABLED | IRQF_TRIGGER_RISING |
+			 IRQF_TRIGGER_FALLING,
+			 "MMC card detect", data);
+	if (rc)
+		goto err_irq;
+
+	mioa701_mci_info.detect_delay = msecs_to_jiffies(250);
+	return 0;
+
+err_irq:
+	dev_err(dev, "mioa701_mci_init: MMC/SD:"
+		" can't request MMC card detect IRQ\n");
+	mio_gpio_free(ARRAY_AND_SIZE(mci_gpios));
+err_gpio:
+	return rc;
+}
+
+static struct pxamci_platform_data mioa701_mci_info = {
+	.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+	.init	  = mci_init,
+	.get_ro	  = mci_get_ro,
+	.setpower = mci_setpower,
+	.exit	  = mci_exit,
+};
+
+/* FlashRAM */
+static struct resource strataflash_resource = {
+	.start = PXA_CS0_PHYS,
+	.end   = PXA_CS0_PHYS + SZ_64M - 1,
+	.flags = IORESOURCE_MEM,
+};
+
+static struct physmap_flash_data strataflash_data = {
+	.width = 2,
+	/* .set_vpp = mioa701_set_vpp, */
+};
+
+static struct platform_device strataflash = {
+	.name	       = "physmap-flash",
+	.id	       = -1,
+	.resource      = &strataflash_resource,
+	.num_resources = 1,
+	.dev = {
+		.platform_data = &strataflash_data,
+	},
+};
+
+/*
+ * Suspend/Resume bootstrap management
+ *
+ * MIO A701 reboot sequence is highly ROM dependant. From the one dissassembled,
+ * this sequence is as follows :
+ *   - disables interrupts
+ *   - initialize SDRAM (self refresh RAM into active RAM)
+ *   - initialize GPIOs (depends on value at 0xa020b020)
+ *   - initialize coprossessors
+ *   - if edge detect on PWR_SCL(GPIO3), then proceed to cold start
+ *   - or if value at 0xa020b000 not equal to 0x0f0f0f0f, proceed to cold start
+ *   - else do a resume, ie. jump to addr 0xa0100000
+ */
+#define RESUME_ENABLE_ADDR	0xa020b000
+#define RESUME_ENABLE_VAL	0x0f0f0f0f
+#define RESUME_BT_ADDR		0xa020b020
+#define RESUME_UNKNOWN_ADDR	0xa020b024
+#define RESUME_VECTOR_ADDR	0xa0100000
+#define BOOTSTRAP_WORDS		mioa701_bootstrap_lg/4
+
+static u32 *save_buffer;
+
+static void install_bootstrap(void)
+{
+	int i;
+	u32 *rom_bootstrap  = phys_to_virt(RESUME_VECTOR_ADDR);
+	u32 *src = &mioa701_bootstrap;
+
+	for (i = 0; i < BOOTSTRAP_WORDS; i++)
+		rom_bootstrap[i] = src[i];
+}
+
+
+static int mioa701_sys_suspend(struct sys_device *sysdev, pm_message_t state)
+{
+	int i = 0, is_bt_on;
+	u32 *mem_resume_vector	= phys_to_virt(RESUME_VECTOR_ADDR);
+	u32 *mem_resume_enabler = phys_to_virt(RESUME_ENABLE_ADDR);
+	u32 *mem_resume_bt	= phys_to_virt(RESUME_BT_ADDR);
+	u32 *mem_resume_unknown	= phys_to_virt(RESUME_UNKNOWN_ADDR);
+
+	/* Devices prepare suspend */
+	is_bt_on = gpio_get_value(GPIO83_BT_ON);
+	pxa2xx_mfp_set_lpm(GPIO83_BT_ON,
+			   is_bt_on ? MFP_LPM_DRIVE_HIGH : MFP_LPM_DRIVE_LOW);
+
+	for (i = 0; i < BOOTSTRAP_WORDS; i++)
+		save_buffer[i] = mem_resume_vector[i];
+	save_buffer[i++] = *mem_resume_enabler;
+	save_buffer[i++] = *mem_resume_bt;
+	save_buffer[i++] = *mem_resume_unknown;
+
+	*mem_resume_enabler = RESUME_ENABLE_VAL;
+	*mem_resume_bt	    = is_bt_on;
+
+	install_bootstrap();
+	return 0;
+}
+
+static int mioa701_sys_resume(struct sys_device *sysdev)
+{
+	int i = 0;
+	u32 *mem_resume_vector	= phys_to_virt(RESUME_VECTOR_ADDR);
+	u32 *mem_resume_enabler = phys_to_virt(RESUME_ENABLE_ADDR);
+	u32 *mem_resume_bt	= phys_to_virt(RESUME_BT_ADDR);
+	u32 *mem_resume_unknown	= phys_to_virt(RESUME_UNKNOWN_ADDR);
+
+	for (i = 0; i < BOOTSTRAP_WORDS; i++)
+		mem_resume_vector[i] = save_buffer[i];
+	*mem_resume_enabler = save_buffer[i++];
+	*mem_resume_bt	    = save_buffer[i++];
+	*mem_resume_unknown = save_buffer[i++];
+
+	return 0;
+}
+
+static struct sysdev_class mioa701_sysclass = {
+	.name = "mioa701",
+};
+
+static struct sys_device sysdev_bootstrap = {
+	.cls		= &mioa701_sysclass,
+};
+
+static struct sysdev_driver driver_bootstrap = {
+	.suspend	= &mioa701_sys_suspend,
+	.resume		= &mioa701_sys_resume,
+};
+
+static int __init bootstrap_init(void)
+{
+	int rc;
+	int save_size = mioa701_bootstrap_lg + (sizeof(u32) * 3);
+
+	rc = sysdev_class_register(&mioa701_sysclass);
+	if (rc) {
+		printk(KERN_ERR "Failed registering mioa701 sys class\n");
+		return -ENODEV;
+	}
+	rc = sysdev_register(&sysdev_bootstrap);
+	if (rc) {
+		printk(KERN_ERR "Failed registering mioa701 sys device\n");
+		return -ENODEV;
+	}
+	rc = sysdev_driver_register(&mioa701_sysclass, &driver_bootstrap);
+	if (rc) {
+		printk(KERN_ERR "Failed registering PMU sys driver\n");
+		return -ENODEV;
+	}
+
+	save_buffer = kmalloc(save_size, GFP_KERNEL);
+	if (!save_buffer)
+		return -ENOMEM;
+	printk(KERN_INFO "MioA701: allocated %d bytes for bootstrap\n",
+	       save_size);
+	return 0;
+}
+
+static void bootstrap_exit(void)
+{
+	kfree(save_buffer);
+	sysdev_driver_unregister(&mioa701_sysclass, &driver_bootstrap);
+	sysdev_unregister(&sysdev_bootstrap);
+	sysdev_class_unregister(&mioa701_sysclass);
+
+	printk(KERN_CRIT "Unregistering mioa701 suspend will hang next"
+	       "resume !!!\n");
+}
+
+/*
+ * Power Supply
+ */
+static char *supplicants[] = {
+	"mioa701_battery"
+};
+
+static void mioa701_set_charge(int flags)
+{
+	gpio_set_value(GPIO9_CHARGE_nEN, !flags);
+}
+
+static struct pda_power_pdata power_pdata = {
+	.is_ac_online	= is_usb_connected,
+	.set_charge = mioa701_set_charge,
+	.supplied_to = supplicants,
+	.num_supplicants = ARRAY_SIZE(supplicants),
+};
+
+static struct resource power_resources[] = {
+	[0] = {
+		.name	= "ac",
+		.start	= gpio_to_irq(GPIO13_USB_DETECT),
+		.end	= gpio_to_irq(GPIO13_USB_DETECT),
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+		IORESOURCE_IRQ_LOWEDGE,
+	},
+};
+
+static struct platform_device power_dev = {
+	.name		= "pda-power",
+	.id		= -1,
+	.resource	= power_resources,
+	.num_resources	= ARRAY_SIZE(power_resources),
+	.dev = {
+		.platform_data	= &power_pdata,
+	},
+};
+
+#if defined(CONFIG_PDA_POWER) && defined(CONFIG_TOUCHSCREEN_WM97XX)
+static struct wm97xx *battery_wm;
+
+static enum power_supply_property battery_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,	/* Necessary for apm */
+};
+
+static int get_battery_voltage(void)
+{
+	int adc = -1;
+
+	if (battery_wm)
+		adc = wm97xx_read_aux_adc(battery_wm, WM97XX_AUX_ID1);
+	return adc;
+}
+
+static int get_battery_status(struct power_supply *b)
+{
+	int status;
+
+	if (is_usb_connected())
+		status = POWER_SUPPLY_STATUS_CHARGING;
+	else
+		status = POWER_SUPPLY_STATUS_DISCHARGING;
+
+	return status;
+}
+
+static int get_property(struct power_supply *b,
+			enum power_supply_property psp,
+			union power_supply_propval *val)
+{
+	int rc = 0;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_STATUS:
+		val->intval = get_battery_status(b);
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+		val->intval = 0xfd0;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+		val->intval = 0xc00;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		val->intval = get_battery_voltage();
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+		val->intval = 100;
+		break;
+	default:
+		val->intval = -1;
+		rc = -1;
+	}
+
+	return rc;
+};
+
+static struct power_supply battery_ps = {
+	.name = "mioa701_battery",
+	.type = POWER_SUPPLY_TYPE_BATTERY,
+	.get_property = get_property,
+	.properties = battery_props,
+	.num_properties = ARRAY_SIZE(battery_props),
+};
+
+static int battery_probe(struct platform_device *pdev)
+{
+	struct wm97xx *wm = platform_get_drvdata(pdev);
+	int rc;
+
+	battery_wm = wm;
+
+	rc = power_supply_register(NULL, &battery_ps);
+	if (rc)
+		dev_err(&pdev->dev,
+		"Could not register mioa701 battery -> %d\n", rc);
+	return rc;
+}
+
+static int battery_remove(struct platform_device *pdev)
+{
+	battery_wm = NULL;
+	return 0;
+}
+
+static struct platform_driver mioa701_battery_driver = {
+	.driver = {
+		.name = "wm97xx-battery",
+	},
+	.probe = battery_probe,
+	.remove = battery_remove
+};
+
+static int __init mioa701_battery_init(void)
+{
+	int rc;
+
+	rc = platform_driver_register(&mioa701_battery_driver);
+	if (rc)
+		printk(KERN_ERR "Could not register mioa701 battery driver\n");
+	return rc;
+}
+
+#else
+static int __init mioa701_battery_init(void)
+{
+	return 0;
+}
+#endif
+
+/*
+ * Mio global
+ */
+
+/* Devices */
+#define MIO_PARENT_DEV(var, strname, tparent, pdata)	\
+static struct platform_device var = {			\
+	.name		= strname,			\
+	.id		= -1,				\
+	.dev		= {				\
+		.platform_data = pdata,			\
+		.parent	= tparent,			\
+	},						\
+};
+#define MIO_SIMPLE_DEV(var, strname, pdata)	\
+	MIO_PARENT_DEV(var, strname, NULL, pdata)
+
+MIO_SIMPLE_DEV(mioa701_gpio_keys, "gpio-keys",	    &mioa701_gpio_keys_data)
+MIO_PARENT_DEV(mioa701_backlight, "pwm-backlight",  &pxa27x_device_pwm0.dev,
+		&mioa701_backlight_data);
+MIO_SIMPLE_DEV(mioa701_led,	  "leds-gpio",	    &gpio_led_info)
+MIO_SIMPLE_DEV(pxa2xx_pcm,	  "pxa2xx-pcm",	    NULL)
+MIO_SIMPLE_DEV(pxa2xx_ac97,	  "pxa2xx-ac97",    NULL)
+MIO_PARENT_DEV(mio_wm9713_codec,  "wm9713-codec",   &pxa2xx_ac97.dev, NULL)
+MIO_SIMPLE_DEV(mioa701_sound,	  "mioa701-wm9713", NULL)
+MIO_SIMPLE_DEV(mioa701_board,	  "mioa701-board",  NULL)
+
+static struct platform_device *devices[] __initdata = {
+	&mioa701_gpio_keys,
+	&mioa701_backlight,
+	&mioa701_led,
+	&pxa2xx_pcm,
+	&pxa2xx_ac97,
+	&mio_wm9713_codec,
+	&mioa701_sound,
+	&power_dev,
+	&strataflash,
+	&mioa701_board
+};
+
+static void mioa701_machine_exit(void);
+
+static void mioa701_poweroff(void)
+{
+	mioa701_machine_exit();
+	gpio_set_value(GPIO18_POWEROFF, 1);
+}
+
+static void mioa701_restart(char c)
+{
+	mioa701_machine_exit();
+	arm_machine_restart(c);
+}
+
+struct gpio_ress global_gpios[] = {
+	MIO_GPIO_OUT(GPIO9_CHARGE_nEN, 1, "Charger enable"),
+	MIO_GPIO_OUT(GPIO18_POWEROFF, 0, "Power Off"),
+	MIO_GPIO_OUT(GPIO87_LCD_POWER, 0, "LCD Power")
+};
+
+static void __init mioa701_machine_init(void)
+{
+	PSLR  = 0xff100000; /* SYSDEL=125ms, PWRDEL=125ms, PSLR_SL_ROD=1 */
+	PCFR = PCFR_DC_EN | PCFR_GPR_EN | PCFR_OPDE;
+	RTTR = 32768 - 1; /* Reset crazy WinCE value */
+	UP2OCR = UP2OCR_HXOE;
+
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(mioa701_pin_config));
+	mio_gpio_request(ARRAY_AND_SIZE(global_gpios));
+	bootstrap_init();
+	set_pxa_fb_info(&mioa701_pxafb_info);
+	pxa_set_mci_info(&mioa701_mci_info);
+	pxa_set_keypad_info(&mioa701_keypad_info);
+	udc_init();
+	pm_power_off = mioa701_poweroff;
+	arm_pm_restart = mioa701_restart;
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+	gsm_init();
+	mioa701_battery_init();
+}
+
+static void mioa701_machine_exit(void)
+{
+	udc_exit();
+	bootstrap_exit();
+	gsm_exit();
+}
+
+MACHINE_START(MIOA701, "MIO A701")
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= &pxa_map_io,
+	.init_irq	= &pxa27x_init_irq,
+	.init_machine	= mioa701_machine_init,
+	.timer		= &pxa_timer,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/mioa701_bootresume.S b/arch/arm/mach-pxa/mioa701_bootresume.S
new file mode 100644
index 0000000..a647693
--- /dev/null
+++ b/arch/arm/mach-pxa/mioa701_bootresume.S
@@ -0,0 +1,36 @@
+/* Bootloader to resume MIO A701
+ *
+ * 2007-1-12 Robert Jarzmik
+ *
+ * This code is licenced under the GPLv2.
+*/
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Note: Yes, part of the following code is located into the .data section.
+ *       This is to allow jumpaddr to be accessed with a relative load
+ *       while we can't rely on any MMU translation.  We could have put
+ *       sleep_save_sp in the .text section as well, but some setups might
+ *       insist on it to be truly read-only.
+ */
+	.data
+ENTRY(mioa701_bootstrap)
+0:
+	b	1f
+ENTRY(mioa701_jumpaddr)
+	.word	0x40f00008		@ PSPR in no-MMU mode
+1:
+	mov	r0,     #0xa0000000	@ Don't suppose memory access works
+	orr	r0, r0, #0x00200000	@ even if it's supposed to
+	mov	r1, #0
+	str	r1, [r0]		@ Early disable resume for next boot
+	ldr	r0, mioa701_jumpaddr	@ (Murphy's Law)
+	ldr	r0, [r0]
+	mov	pc, r0
+2:
+
+ENTRY(mioa701_bootstrap_lg)
+	.data
+	.word	2b-0b
diff --git a/arch/arm/mach-pxa/mp900.c b/arch/arm/mach-pxa/mp900.c
new file mode 100644
index 0000000..8a73814
--- /dev/null
+++ b/arch/arm/mach-pxa/mp900.c
@@ -0,0 +1,100 @@
+/*
+ *  linux/arch/arm/mach-pxa/mp900.c
+ *
+ *  Support for the NEC MobilePro900/C platform
+ *
+ *  Based on mach-pxa/gumstix.c
+ *
+ *  2007, 2008 Kristoffer Ericson <kristoffer.ericson@gmail.com>
+ *  2007, 2008 Michael Petchkovsky <mkpetch@internode.on.net>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/usb/isp116x.h>
+
+#include <mach/hardware.h>
+#include <mach/pxa-regs.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include "generic.h"
+
+static void isp116x_pfm_delay(struct device *dev, int delay)
+{
+
+	/* 400Mhz PXA2 = 2.5ns / instruction */
+
+	int cyc = delay / 10;
+
+	/* 4 Instructions = 4 x 2.5ns = 10ns */
+	__asm__ volatile ("0:\n"
+		"subs %0, %1, #1\n"
+		"bge 0b\n"
+		:"=r" (cyc)
+		:"0"(cyc)
+	);
+}
+
+static struct isp116x_platform_data isp116x_pfm_data = {
+	.remote_wakeup_enable = 1,
+	.delay = isp116x_pfm_delay,
+};
+
+static struct resource isp116x_pfm_resources[] = {
+	[0] =	{
+		.start	= 0x0d000000,
+		.end	= 0x0d000000 + 1,
+		.flags	= IORESOURCE_MEM,
+		},
+	[1] =	{
+		.start  = 0x0d000000 + 4,
+		.end	= 0x0d000000 + 5,
+		.flags  = IORESOURCE_MEM,
+		},
+	[2] =	{
+		.start	= 61,
+		.end	= 61,
+		.flags	= IORESOURCE_IRQ,
+		},
+};
+
+static struct platform_device mp900c_dummy_device = {
+	.name		= "mp900c_dummy",
+	.id		= -1,
+};
+
+static struct platform_device mp900c_usb = {
+	.name		= "isp116x-hcd",
+	.num_resources	= ARRAY_SIZE(isp116x_pfm_resources),
+	.resource	= isp116x_pfm_resources,
+	.dev.platform_data = &isp116x_pfm_data,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&mp900c_dummy_device,
+	&mp900c_usb,
+};
+
+static void __init mp900c_init(void)
+{
+	printk(KERN_INFO "MobilePro 900/C machine init\n");
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+/* Maintainer - Michael Petchkovsky <mkpetch@internode.on.net> */
+MACHINE_START(NEC_MP900, "MobilePro900/C")
+	.phys_io	= 0x40000000,
+	.boot_params	= 0xa0220100,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.timer		= &pxa_timer,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa25x_init_irq,
+	.init_machine	= mp900c_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c
index fe924a2..4447711 100644
--- a/arch/arm/mach-pxa/palmtx.c
+++ b/arch/arm/mach-pxa/palmtx.c
@@ -25,6 +25,8 @@
 #include <linux/pda_power.h>
 #include <linux/pwm_backlight.h>
 #include <linux/gpio.h>
+#include <linux/wm97xx_batt.h>
+#include <linux/power_supply.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -340,6 +342,23 @@
 };
 
 /******************************************************************************
+ * WM97xx battery
+ ******************************************************************************/
+static struct wm97xx_batt_info wm97xx_batt_pdata = {
+	.batt_aux	= WM97XX_AUX_ID3,
+	.temp_aux	= WM97XX_AUX_ID2,
+	.charge_gpio	= -1,
+	.max_voltage	= PALMTX_BAT_MAX_VOLTAGE,
+	.min_voltage	= PALMTX_BAT_MIN_VOLTAGE,
+	.batt_mult	= 1000,
+	.batt_div	= 414,
+	.temp_mult	= 1,
+	.temp_div	= 1,
+	.batt_tech	= POWER_SUPPLY_TECHNOLOGY_LIPO,
+	.batt_name	= "main-batt",
+};
+
+/******************************************************************************
  * Framebuffer
  ******************************************************************************/
 static struct pxafb_mode_info palmtx_lcd_modes[] = {
@@ -401,6 +420,7 @@
 	pxa_set_ac97_info(NULL);
 	pxa_set_ficp_info(&palmtx_ficp_platform_data);
 	pxa_set_keypad_info(&palmtx_keypad_platform_data);
+	wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
 
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 }
diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c
new file mode 100644
index 0000000..2f730da
--- /dev/null
+++ b/arch/arm/mach-pxa/palmz72.c
@@ -0,0 +1,554 @@
+/*
+ * Hardware definitions for Palm Zire72
+ *
+ * Authors:
+ *	Vladimir "Farcaller" Pouzanov <farcaller@gmail.com>
+ *	Sergey Lapin <slapin@ossfans.org>
+ *	Alex Osborne <bobofdoom@gmail.com>
+ *	Jan Herman <2hp@seznam.cz>
+ *
+ * Rewrite for mainline:
+ *	Marek Vasut <marek.vasut@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (find more info at www.hackndev.com)
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/pda_power.h>
+#include <linux/pwm_backlight.h>
+#include <linux/gpio.h>
+#include <linux/power_supply.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/audio.h>
+#include <mach/palmz72.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <mach/pxa-regs.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/mfp-pxa27x.h>
+#include <mach/irda.h>
+#include <mach/pxa27x_keypad.h>
+#include <mach/udc.h>
+#include <mach/pm.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long palmz72_pin_config[] __initdata = {
+	/* MMC */
+	GPIO32_MMC_CLK,
+	GPIO92_MMC_DAT_0,
+	GPIO109_MMC_DAT_1,
+	GPIO110_MMC_DAT_2,
+	GPIO111_MMC_DAT_3,
+	GPIO112_MMC_CMD,
+	GPIO14_GPIO,	/* SD detect */
+	GPIO115_GPIO,	/* SD RO */
+	GPIO98_GPIO,	/* SD power */
+
+	/* AC97 */
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
+
+	/* IrDA */
+	GPIO49_GPIO,	/* ir disable */
+	GPIO46_FICP_RXD,
+	GPIO47_FICP_TXD,
+
+	/* PWM */
+	GPIO16_PWM0_OUT,
+
+	/* USB */
+	GPIO15_GPIO,	/* usb detect */
+	GPIO12_GPIO,	/* usb pullup */
+	GPIO95_GPIO,	/* usb power */
+
+	/* Matrix keypad */
+	GPIO100_KP_MKIN_0	| WAKEUP_ON_LEVEL_HIGH,
+	GPIO101_KP_MKIN_1	| WAKEUP_ON_LEVEL_HIGH,
+	GPIO102_KP_MKIN_2	| WAKEUP_ON_LEVEL_HIGH,
+	GPIO97_KP_MKIN_3	| WAKEUP_ON_LEVEL_HIGH,
+	GPIO103_KP_MKOUT_0,
+	GPIO104_KP_MKOUT_1,
+	GPIO105_KP_MKOUT_2,
+
+	/* LCD */
+	GPIO58_LCD_LDD_0,
+	GPIO59_LCD_LDD_1,
+	GPIO60_LCD_LDD_2,
+	GPIO61_LCD_LDD_3,
+	GPIO62_LCD_LDD_4,
+	GPIO63_LCD_LDD_5,
+	GPIO64_LCD_LDD_6,
+	GPIO65_LCD_LDD_7,
+	GPIO66_LCD_LDD_8,
+	GPIO67_LCD_LDD_9,
+	GPIO68_LCD_LDD_10,
+	GPIO69_LCD_LDD_11,
+	GPIO70_LCD_LDD_12,
+	GPIO71_LCD_LDD_13,
+	GPIO72_LCD_LDD_14,
+	GPIO73_LCD_LDD_15,
+	GPIO74_LCD_FCLK,
+	GPIO75_LCD_LCLK,
+	GPIO76_LCD_PCLK,
+	GPIO77_LCD_BIAS,
+	GPIO20_GPIO,	/* bl power */
+	GPIO21_GPIO,	/* LCD border switch */
+	GPIO22_GPIO,	/* LCD border color */
+	GPIO96_GPIO,	/* lcd power */
+
+	/* Misc. */
+	GPIO0_GPIO	| WAKEUP_ON_LEVEL_HIGH,	/* power detect */
+	GPIO88_GPIO,				/* green led */
+	GPIO27_GPIO,				/* WM9712 IRQ */
+};
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+static int palmz72_mci_init(struct device *dev,
+				irq_handler_t palmz72_detect_int, void *data)
+{
+	int err = 0;
+
+	/* Setup an interrupt for detecting card insert/remove events */
+	err = gpio_request(GPIO_NR_PALMZ72_SD_DETECT_N, "SD IRQ");
+	if (err)
+		goto err;
+	err = gpio_direction_input(GPIO_NR_PALMZ72_SD_DETECT_N);
+	if (err)
+		goto err2;
+	err = request_irq(gpio_to_irq(GPIO_NR_PALMZ72_SD_DETECT_N),
+			palmz72_detect_int, IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
+			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+			"SD/MMC card detect", data);
+	if (err) {
+		printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n",
+				__func__);
+		goto err2;
+	}
+
+	/* SD_POWER is not actually power, but it is more like chip
+	 * select, i.e. it is inverted */
+
+	err = gpio_request(GPIO_NR_PALMZ72_SD_POWER_N, "SD_POWER");
+	if (err)
+		goto err3;
+	err = gpio_direction_output(GPIO_NR_PALMZ72_SD_POWER_N, 0);
+	if (err)
+		goto err4;
+	err = gpio_request(GPIO_NR_PALMZ72_SD_RO, "SD_RO");
+	if (err)
+		goto err4;
+	err = gpio_direction_input(GPIO_NR_PALMZ72_SD_RO);
+	if (err)
+		goto err5;
+
+	printk(KERN_DEBUG "%s: irq registered\n", __func__);
+
+	return 0;
+
+err5:
+	gpio_free(GPIO_NR_PALMZ72_SD_RO);
+err4:
+	gpio_free(GPIO_NR_PALMZ72_SD_POWER_N);
+err3:
+	free_irq(gpio_to_irq(GPIO_NR_PALMZ72_SD_DETECT_N), data);
+err2:
+	gpio_free(GPIO_NR_PALMZ72_SD_DETECT_N);
+err:
+	return err;
+}
+
+static void palmz72_mci_exit(struct device *dev, void *data)
+{
+	gpio_free(GPIO_NR_PALMZ72_SD_POWER_N);
+	free_irq(gpio_to_irq(GPIO_NR_PALMZ72_SD_DETECT_N), data);
+	gpio_free(GPIO_NR_PALMZ72_SD_DETECT_N);
+	gpio_free(GPIO_NR_PALMZ72_SD_RO);
+}
+
+static void palmz72_mci_power(struct device *dev, unsigned int vdd)
+{
+	struct pxamci_platform_data *p_d = dev->platform_data;
+	if (p_d->ocr_mask & (1 << vdd))
+		gpio_set_value(GPIO_NR_PALMZ72_SD_POWER_N, 0);
+	else
+		gpio_set_value(GPIO_NR_PALMZ72_SD_POWER_N, 1);
+}
+
+static int palmz72_mci_ro(struct device *dev)
+{
+	return gpio_get_value(GPIO_NR_PALMZ72_SD_RO);
+}
+
+static struct pxamci_platform_data palmz72_mci_platform_data = {
+	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.setpower	= palmz72_mci_power,
+	.get_ro		= palmz72_mci_ro,
+	.init 		= palmz72_mci_init,
+	.exit		= palmz72_mci_exit,
+};
+
+/******************************************************************************
+ * GPIO keyboard
+ ******************************************************************************/
+static unsigned int palmz72_matrix_keys[] = {
+	KEY(0, 0, KEY_POWER),
+	KEY(0, 1, KEY_F1),
+	KEY(0, 2, KEY_ENTER),
+
+	KEY(1, 0, KEY_F2),
+	KEY(1, 1, KEY_F3),
+	KEY(1, 2, KEY_F4),
+
+	KEY(2, 0, KEY_UP),
+	KEY(2, 2, KEY_DOWN),
+
+	KEY(3, 0, KEY_RIGHT),
+	KEY(3, 2, KEY_LEFT),
+};
+
+static struct pxa27x_keypad_platform_data palmz72_keypad_platform_data = {
+	.matrix_key_rows	= 4,
+	.matrix_key_cols	= 3,
+	.matrix_key_map		= palmz72_matrix_keys,
+	.matrix_key_map_size	= ARRAY_SIZE(palmz72_matrix_keys),
+
+	.debounce_interval	= 30,
+};
+
+/******************************************************************************
+ * Backlight
+ ******************************************************************************/
+static int palmz72_backlight_init(struct device *dev)
+{
+	int ret;
+
+	ret = gpio_request(GPIO_NR_PALMZ72_BL_POWER, "BL POWER");
+	if (ret)
+		goto err;
+	ret = gpio_direction_output(GPIO_NR_PALMZ72_BL_POWER, 0);
+	if (ret)
+		goto err2;
+	ret = gpio_request(GPIO_NR_PALMZ72_LCD_POWER, "LCD POWER");
+	if (ret)
+		goto err2;
+	ret = gpio_direction_output(GPIO_NR_PALMZ72_LCD_POWER, 0);
+	if (ret)
+		goto err3;
+
+	return 0;
+err3:
+	gpio_free(GPIO_NR_PALMZ72_LCD_POWER);
+err2:
+	gpio_free(GPIO_NR_PALMZ72_BL_POWER);
+err:
+	return ret;
+}
+
+static int palmz72_backlight_notify(int brightness)
+{
+	gpio_set_value(GPIO_NR_PALMZ72_BL_POWER, brightness);
+	gpio_set_value(GPIO_NR_PALMZ72_LCD_POWER, brightness);
+	return brightness;
+}
+
+static void palmz72_backlight_exit(struct device *dev)
+{
+	gpio_free(GPIO_NR_PALMZ72_BL_POWER);
+	gpio_free(GPIO_NR_PALMZ72_LCD_POWER);
+}
+
+static struct platform_pwm_backlight_data palmz72_backlight_data = {
+	.pwm_id		= 0,
+	.max_brightness	= PALMZ72_MAX_INTENSITY,
+	.dft_brightness	= PALMZ72_MAX_INTENSITY,
+	.pwm_period_ns	= PALMZ72_PERIOD_NS,
+	.init		= palmz72_backlight_init,
+	.notify		= palmz72_backlight_notify,
+	.exit		= palmz72_backlight_exit,
+};
+
+static struct platform_device palmz72_backlight = {
+	.name	= "pwm-backlight",
+	.dev	= {
+		.parent		= &pxa27x_device_pwm0.dev,
+		.platform_data	= &palmz72_backlight_data,
+	},
+};
+
+/******************************************************************************
+ * IrDA
+ ******************************************************************************/
+static int palmz72_irda_startup(struct device *dev)
+{
+	int err;
+	err = gpio_request(GPIO_NR_PALMZ72_IR_DISABLE, "IR DISABLE");
+	if (err)
+		goto err;
+	err = gpio_direction_output(GPIO_NR_PALMZ72_IR_DISABLE, 1);
+	if (err)
+		gpio_free(GPIO_NR_PALMZ72_IR_DISABLE);
+err:
+	return err;
+}
+
+static void palmz72_irda_shutdown(struct device *dev)
+{
+	gpio_free(GPIO_NR_PALMZ72_IR_DISABLE);
+}
+
+static void palmz72_irda_transceiver_mode(struct device *dev, int mode)
+{
+	gpio_set_value(GPIO_NR_PALMZ72_IR_DISABLE, mode & IR_OFF);
+	pxa2xx_transceiver_mode(dev, mode);
+}
+
+static struct pxaficp_platform_data palmz72_ficp_platform_data = {
+	.startup		= palmz72_irda_startup,
+	.shutdown		= palmz72_irda_shutdown,
+	.transceiver_cap	= IR_SIRMODE | IR_OFF,
+	.transceiver_mode	= palmz72_irda_transceiver_mode,
+};
+
+/******************************************************************************
+ * LEDs
+ ******************************************************************************/
+static struct gpio_led gpio_leds[] = {
+	{
+		.name			= "palmz72:green:led",
+		.default_trigger	= "none",
+		.gpio			= GPIO_NR_PALMZ72_LED_GREEN,
+	},
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+	.leds		= gpio_leds,
+	.num_leds	= ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device palmz72_leds = {
+	.name	= "leds-gpio",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &gpio_led_info,
+	}
+};
+
+/******************************************************************************
+ * Power supply
+ ******************************************************************************/
+static int power_supply_init(struct device *dev)
+{
+	int ret;
+
+	ret = gpio_request(GPIO_NR_PALMZ72_POWER_DETECT, "CABLE_STATE_AC");
+	if (ret)
+		goto err1;
+	ret = gpio_direction_input(GPIO_NR_PALMZ72_POWER_DETECT);
+	if (ret)
+		goto err2;
+
+	ret = gpio_request(GPIO_NR_PALMZ72_USB_DETECT_N, "CABLE_STATE_USB");
+	if (ret)
+		goto err2;
+	ret = gpio_direction_input(GPIO_NR_PALMZ72_USB_DETECT_N);
+	if (ret)
+		goto err3;
+
+	return 0;
+err3:
+	gpio_free(GPIO_NR_PALMZ72_USB_DETECT_N);
+err2:
+	gpio_free(GPIO_NR_PALMZ72_POWER_DETECT);
+err1:
+	return ret;
+}
+
+static int palmz72_is_ac_online(void)
+{
+	return gpio_get_value(GPIO_NR_PALMZ72_POWER_DETECT);
+}
+
+static int palmz72_is_usb_online(void)
+{
+	return !gpio_get_value(GPIO_NR_PALMZ72_USB_DETECT_N);
+}
+
+static void power_supply_exit(struct device *dev)
+{
+	gpio_free(GPIO_NR_PALMZ72_USB_DETECT_N);
+	gpio_free(GPIO_NR_PALMZ72_POWER_DETECT);
+}
+
+static char *palmz72_supplicants[] = {
+	"main-battery",
+};
+
+static struct pda_power_pdata power_supply_info = {
+	.init            = power_supply_init,
+	.is_ac_online    = palmz72_is_ac_online,
+	.is_usb_online   = palmz72_is_usb_online,
+	.exit            = power_supply_exit,
+	.supplied_to     = palmz72_supplicants,
+	.num_supplicants = ARRAY_SIZE(palmz72_supplicants),
+};
+
+static struct platform_device power_supply = {
+	.name = "pda-power",
+	.id   = -1,
+	.dev  = {
+		.platform_data = &power_supply_info,
+	},
+};
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+static struct pxafb_mode_info palmz72_lcd_modes[] = {
+{
+	.pixclock	= 115384,
+	.xres		= 320,
+	.yres		= 320,
+	.bpp		= 16,
+
+	.left_margin	= 27,
+	.right_margin	= 7,
+	.upper_margin	= 7,
+	.lower_margin	= 8,
+
+	.hsync_len	= 6,
+	.vsync_len	= 1,
+},
+};
+
+static struct pxafb_mach_info palmz72_lcd_screen = {
+	.modes		= palmz72_lcd_modes,
+	.num_modes	= ARRAY_SIZE(palmz72_lcd_modes),
+	.lcd_conn	= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+#ifdef CONFIG_PM
+
+/* We have some black magic here
+ * PalmOS ROM on recover expects special struct physical address
+ * to be transferred via PSPR. Using this struct PalmOS restores
+ * its state after sleep. As for Linux, we need to setup it the
+ * same way. More than that, PalmOS ROM changes some values in memory.
+ * For now only one location is found, which needs special treatment.
+ * Thanks to Alex Osborne, Andrzej Zaborowski, and lots of other people
+ * for reading backtraces for me :)
+ */
+
+#define PALMZ72_SAVE_DWORD ((unsigned long *)0xc0000050)
+
+static struct palmz72_resume_info palmz72_resume_info = {
+	.magic0 = 0xb4e6,
+	.magic1 = 1,
+
+	/* reset state, MMU off etc */
+	.arm_control = 0,
+	.aux_control = 0,
+	.ttb = 0,
+	.domain_access = 0,
+	.process_id = 0,
+};
+
+static unsigned long store_ptr;
+
+/* sys_device for Palm Zire 72 PM */
+
+static int palmz72_pm_suspend(struct sys_device *dev, pm_message_t msg)
+{
+	/* setup the resume_info struct for the original bootloader */
+	palmz72_resume_info.resume_addr = (u32) pxa_cpu_resume;
+
+	/* Storing memory touched by ROM */
+	store_ptr = *PALMZ72_SAVE_DWORD;
+
+	/* Setting PSPR to a proper value */
+	PSPR = virt_to_phys(&palmz72_resume_info);
+
+	return 0;
+}
+
+static int palmz72_pm_resume(struct sys_device *dev)
+{
+	*PALMZ72_SAVE_DWORD = store_ptr;
+	return 0;
+}
+
+static struct sysdev_class palmz72_pm_sysclass = {
+	.name = "palmz72_pm",
+	.suspend = palmz72_pm_suspend,
+	.resume = palmz72_pm_resume,
+};
+
+static struct sys_device palmz72_pm_device = {
+	.cls = &palmz72_pm_sysclass,
+};
+
+static int __init palmz72_pm_init(void)
+{
+	int ret = -ENODEV;
+	if (machine_is_palmz72()) {
+		ret = sysdev_class_register(&palmz72_pm_sysclass);
+		if (ret == 0)
+			ret = sysdev_register(&palmz72_pm_device);
+	}
+	return ret;
+}
+
+device_initcall(palmz72_pm_init);
+#endif
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static struct platform_device *devices[] __initdata = {
+	&palmz72_backlight,
+	&palmz72_leds,
+	&power_supply,
+};
+
+static void __init palmz72_init(void)
+{
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmz72_pin_config));
+	set_pxa_fb_info(&palmz72_lcd_screen);
+	pxa_set_mci_info(&palmz72_mci_platform_data);
+	pxa_set_ac97_info(NULL);
+	pxa_set_ficp_info(&palmz72_ficp_platform_data);
+	pxa_set_keypad_info(&palmz72_keypad_platform_data);
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(PALMZ72, "Palm Zire72")
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= io_p2v(0x40000000),
+	.boot_params	= 0xa0000100,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa27x_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= palmz72_init
+MACHINE_END
diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c
index 730b9f6..36135a0 100644
--- a/arch/arm/mach-pxa/pcm027.c
+++ b/arch/arm/mach-pxa/pcm027.c
@@ -31,7 +31,7 @@
 #include <asm/mach/arch.h>
 #include <mach/hardware.h>
 #include <mach/pxa-regs.h>
-#include <mach/pxa2xx-gpio.h>
+#include <mach/mfp-pxa27x.h>
 #include <mach/pxa2xx-regs.h>
 #include <mach/pxa2xx_spi.h>
 #include <mach/pcm027.h>
@@ -86,6 +86,28 @@
  * *) CPU internal use only
  */
 
+static unsigned long pcm027_pin_config[] __initdata = {
+	/* Chip Selects */
+	GPIO20_nSDCS_2,
+	GPIO21_nSDCS_3,
+	GPIO15_nCS_1,
+	GPIO78_nCS_2,
+	GPIO80_nCS_4,
+	GPIO33_nCS_5,	/* Ethernet */
+
+	/* I2C */
+	GPIO117_I2C_SCL,
+	GPIO118_I2C_SDA,
+
+	/* GPIO */
+	GPIO52_GPIO,	/* IRQ from network controller */
+#ifdef CONFIG_LEDS_GPIO
+	GPIO90_GPIO,	/* PCM027_LED_CPU */
+	GPIO91_GPIO,	/* PCM027_LED_HEART_BEAT */
+#endif
+	GPIO114_GPIO,	/* IRQ from CAN controller */
+};
+
 /*
  * SMC91x network controller specific stuff
  */
@@ -206,13 +228,9 @@
 	 */
 	ARB_CNTRL = ARB_CORE_PARK | 0x234;
 
-	platform_add_devices(devices, ARRAY_SIZE(devices));
+	pxa2xx_mfp_config(pcm027_pin_config, ARRAY_SIZE(pcm027_pin_config));
 
-	/* LEDs (on demand only) */
-#ifdef CONFIG_LEDS_GPIO
-	pxa_gpio_mode(PCM027_LED_CPU | GPIO_OUT);
-	pxa_gpio_mode(PCM027_LED_HEARD_BEAT | GPIO_OUT);
-#endif /* CONFIG_LEDS_GPIO */
+	platform_add_devices(devices, ARRAY_SIZE(devices));
 
 	/* at last call the baseboard to initialize itself */
 #ifdef CONFIG_MACH_PCM990_BASEBOARD
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
index 420c9b3..f601425 100644
--- a/arch/arm/mach-pxa/pcm990-baseboard.c
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -262,8 +262,7 @@
 					GPIO_bit(PCM990_CTRL_INT_IRQ_GPIO);
 		if (likely(pending)) {
 			irq = PCM027_IRQ(0) + __ffs(pending);
-			desc = irq_desc + irq;
-			desc_handle_irq(irq, desc);
+			generic_handle_irq(irq);
 		}
 		pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled;
 	} while (pending);
@@ -328,36 +327,10 @@
 	.exit		= pcm990_mci_exit,
 };
 
-/*
- * init OHCI hardware to work with
- *
- * Note: Only USB port 1 (host only) is connected
- *
- * GPIO88 (USBHPWR#1): overcurrent in, overcurrent when low
- * GPIO89 (USBHPEN#1): power-on out, on when low
- */
-static int pcm990_ohci_init(struct device *dev)
-{
-	/*
-	 * disable USB port 2 and 3
-	 * power sense is active low
-	 */
-	UHCHR = ((UHCHR) | UHCHR_PCPL | UHCHR_PSPL | UHCHR_SSEP2 |
-				UHCHR_SSEP3) & ~(UHCHR_SSEP1 | UHCHR_SSE);
-	/*
-	 * wait 10ms after Power on
-	 * overcurrent per port
-	 * power switch per port
-	 */
-	UHCRHDA = (5<<24) | (1<<11) | (1<<8);	/* FIXME: Required? */
-
-	return 0;
-}
-
 static struct pxaohci_platform_data pcm990_ohci_platform_data = {
 	.port_mode	= PMM_PERPORT_MODE,
-	.init		= pcm990_ohci_init,
-	.exit		= NULL,
+	.flags		= ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW,
+	.power_on_delay	= 10,
 };
 
 /*
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index 1b539e6..164eb0b 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -86,9 +86,27 @@
 	return -EINVAL;
 }
 
+static int pxa_pm_prepare(void)
+{
+	int ret = 0;
+
+	if (pxa_cpu_pm_fns && pxa_cpu_pm_fns->prepare)
+		ret = pxa_cpu_pm_fns->prepare();
+
+	return ret;
+}
+
+static void pxa_pm_finish(void)
+{
+	if (pxa_cpu_pm_fns && pxa_cpu_pm_fns->finish)
+		pxa_cpu_pm_fns->finish();
+}
+
 static struct platform_suspend_ops pxa_pm_ops = {
 	.valid		= pxa_pm_valid,
 	.enter		= pxa_pm_enter,
+	.prepare	= pxa_pm_prepare,
+	.finish		= pxa_pm_finish,
 };
 
 static int __init pxa_pm_init(void)
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 3f5f484..2e3bd8b 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -20,6 +20,9 @@
 #include <linux/fb.h>
 #include <linux/pm.h>
 #include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -33,7 +36,7 @@
 
 #include <mach/pxa-regs.h>
 #include <mach/pxa2xx-regs.h>
-#include <mach/pxa2xx-gpio.h>
+#include <mach/mfp-pxa25x.h>
 #include <mach/mmc.h>
 #include <mach/udc.h>
 #include <mach/i2c.h>
@@ -42,6 +45,7 @@
 #include <mach/pxafb.h>
 #include <mach/sharpsl.h>
 #include <mach/ssp.h>
+#include <mach/pxa2xx_spi.h>
 
 #include <asm/hardware/scoop.h>
 #include <asm/hardware/locomo.h>
@@ -51,6 +55,88 @@
 #include "devices.h"
 #include "sharpsl.h"
 
+static unsigned long poodle_pin_config[] __initdata = {
+	/* I/O */
+	GPIO79_nCS_3,
+	GPIO80_nCS_4,
+	GPIO18_RDY,
+
+	/* Clock */
+	GPIO12_32KHz,
+
+	/* SSP1 */
+	GPIO23_SSP1_SCLK,
+	GPIO25_SSP1_TXD,
+	GPIO26_SSP1_RXD,
+	GPIO24_GPIO,	/* POODLE_GPIO_TP_CS - SFRM as chip select */
+
+	/* I2S */
+	GPIO28_I2S_BITCLK_OUT,
+	GPIO29_I2S_SDATA_IN,
+	GPIO30_I2S_SDATA_OUT,
+	GPIO31_I2S_SYNC,
+	GPIO32_I2S_SYSCLK,
+
+	/* Infra-Red */
+	GPIO47_FICP_TXD,
+	GPIO46_FICP_RXD,
+
+	/* FFUART */
+	GPIO40_FFUART_DTR,
+	GPIO41_FFUART_RTS,
+	GPIO39_FFUART_TXD,
+	GPIO37_FFUART_DSR,
+	GPIO34_FFUART_RXD,
+	GPIO35_FFUART_CTS,
+
+	/* LCD */
+	GPIO58_LCD_LDD_0,
+	GPIO59_LCD_LDD_1,
+	GPIO60_LCD_LDD_2,
+	GPIO61_LCD_LDD_3,
+	GPIO62_LCD_LDD_4,
+	GPIO63_LCD_LDD_5,
+	GPIO64_LCD_LDD_6,
+	GPIO65_LCD_LDD_7,
+	GPIO66_LCD_LDD_8,
+	GPIO67_LCD_LDD_9,
+	GPIO68_LCD_LDD_10,
+	GPIO69_LCD_LDD_11,
+	GPIO70_LCD_LDD_12,
+	GPIO71_LCD_LDD_13,
+	GPIO72_LCD_LDD_14,
+	GPIO73_LCD_LDD_15,
+	GPIO74_LCD_FCLK,
+	GPIO75_LCD_LCLK,
+	GPIO76_LCD_PCLK,
+	GPIO77_LCD_BIAS,
+
+	/* PC Card */
+	GPIO48_nPOE,
+	GPIO49_nPWE,
+	GPIO50_nPIOR,
+	GPIO51_nPIOW,
+	GPIO52_nPCE_1,
+	GPIO53_nPCE_2,
+	GPIO54_nPSKTSEL,
+	GPIO55_nPREG,
+	GPIO56_nPWAIT,
+	GPIO57_nIOIS16,
+
+	/* MMC */
+	GPIO6_MMC_CLK,
+	GPIO8_MMC_CS0,
+
+	/* GPIO */
+	GPIO9_GPIO,	/* POODLE_GPIO_nSD_DETECT */
+	GPIO7_GPIO,	/* POODLE_GPIO_nSD_WP */
+	GPIO3_GPIO,	/* POODLE_GPIO_SD_PWR */
+	GPIO33_GPIO,	/* POODLE_GPIO_SD_PWR1 */
+
+	GPIO20_GPIO,	/* POODLE_GPIO_USB_PULLUP */
+	GPIO22_GPIO,	/* POODLE_GPIO_IR_ON */
+};
+
 static struct resource poodle_scoop_resources[] = {
 	[0] = {
 		.start		= 0x10800000,
@@ -62,6 +148,7 @@
 static struct scoop_config poodle_scoop_setup = {
 	.io_dir		= POODLE_SCOOP_IO_DIR,
 	.io_out		= POODLE_SCOOP_IO_OUT,
+	.gpio_base	= POODLE_SCOOP_GPIO_BASE,
 };
 
 struct platform_device poodle_scoop_device = {
@@ -74,27 +161,6 @@
 	.resource	= poodle_scoop_resources,
 };
 
-static void poodle_pcmcia_init(void)
-{
-	/* Setup default state of GPIO outputs
-	   before we enable them as outputs. */
-	GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
-		GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
-		GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) |
-		GPIO_bit(GPIO53_nPCE_2);
-
-	pxa_gpio_mode(GPIO48_nPOE_MD);
-	pxa_gpio_mode(GPIO49_nPWE_MD);
-	pxa_gpio_mode(GPIO50_nPIOR_MD);
-	pxa_gpio_mode(GPIO51_nPIOW_MD);
-	pxa_gpio_mode(GPIO55_nPREG_MD);
-	pxa_gpio_mode(GPIO56_nPWAIT_MD);
-	pxa_gpio_mode(GPIO57_nIOIS16_MD);
-	pxa_gpio_mode(GPIO52_nPCE_1_MD);
-	pxa_gpio_mode(GPIO53_nPCE_2_MD);
-	pxa_gpio_mode(GPIO54_pSKTSEL_MD);
-}
-
 static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = {
 {
 	.dev        = &poodle_scoop_device.dev,
@@ -107,7 +173,6 @@
 static struct scoop_pcmcia_config poodle_pcmcia_config = {
 	.devs         = &poodle_pcmcia_scoop[0],
 	.num_devs     = 1,
-	.pcmcia_init  = poodle_pcmcia_init,
 };
 
 EXPORT_SYMBOL(poodle_scoop_device);
@@ -136,62 +201,55 @@
 
 EXPORT_SYMBOL(poodle_locomo_device);
 
-/*
- * Poodle SSP Device
- */
-
-struct platform_device poodle_ssp_device = {
-	.name		= "corgi-ssp",
-	.id		= -1,
+#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
+static struct pxa2xx_spi_master poodle_spi_info = {
+	.num_chipselect	= 1,
 };
 
-struct corgissp_machinfo poodle_ssp_machinfo = {
-	.port		= 1,
-	.cs_lcdcon	= -1,
-	.cs_ads7846	= -1,
-	.cs_max1111	= -1,
-	.clk_lcdcon	= 2,
-	.clk_ads7846	= 36,
-	.clk_max1111	= 2,
+static struct ads7846_platform_data poodle_ads7846_info = {
+	.model			= 7846,
+	.vref_delay_usecs	= 100,
+	.x_plate_ohms		= 419,
+	.y_plate_ohms		= 486,
+	.gpio_pendown		= POODLE_GPIO_TP_INT,
 };
 
+static void ads7846_cs(u32 command)
+{
+	gpio_set_value(POODLE_GPIO_TP_CS, !(command == PXA2XX_CS_ASSERT));
+}
 
-/*
- * Poodle Touch Screen Device
- */
-static struct resource poodlets_resources[] = {
-	[0] = {
-		.start		= POODLE_IRQ_GPIO_TP_INT,
-		.end		= POODLE_IRQ_GPIO_TP_INT,
-		.flags		= IORESOURCE_IRQ,
+static struct pxa2xx_spi_chip poodle_ads7846_chip = {
+	.cs_control		= ads7846_cs,
+};
+
+static struct spi_board_info poodle_spi_devices[] = {
+	{
+		.modalias	= "ads7846",
+		.max_speed_hz	= 10000,
+		.bus_num	= 1,
+		.platform_data	= &poodle_ads7846_info,
+		.controller_data= &poodle_ads7846_chip,
+		.irq		= gpio_to_irq(POODLE_GPIO_TP_INT),
 	},
 };
 
-static unsigned long poodle_get_hsync_invperiod(void)
+static void __init poodle_init_spi(void)
 {
-	return 0;
+	int err;
+
+	err = gpio_request(POODLE_GPIO_TP_CS, "ADS7846_CS");
+	if (err)
+		return;
+
+	gpio_direction_output(POODLE_GPIO_TP_CS, 1);
+
+	pxa2xx_set_spi_info(1, &poodle_spi_info);
+	spi_register_board_info(ARRAY_AND_SIZE(poodle_spi_devices));
 }
-
-static void poodle_null_hsync(void)
-{
-}
-
-static struct corgits_machinfo  poodle_ts_machinfo = {
-	.get_hsync_invperiod	= poodle_get_hsync_invperiod,
-	.put_hsync       	= poodle_null_hsync,
-	.wait_hsync      	= poodle_null_hsync,
-};
-
-static struct platform_device poodle_ts_device = {
-	.name		= "corgi-ts",
-	.dev		= {
-		.platform_data	= &poodle_ts_machinfo,
-	},
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(poodlets_resources),
-	.resource	= poodlets_resources,
-};
-
+#else
+static inline void poodle_init_spi(void) {}
+#endif
 
 /*
  * MMC/SD Device
@@ -205,22 +263,50 @@
 {
 	int err;
 
-	/* setup GPIO for PXA25x MMC controller	*/
-	pxa_gpio_mode(GPIO6_MMCCLK_MD);
-	pxa_gpio_mode(GPIO8_MMCCS0_MD);
-	pxa_gpio_mode(POODLE_GPIO_nSD_DETECT | GPIO_IN);
-	pxa_gpio_mode(POODLE_GPIO_nSD_WP | GPIO_IN);
-	pxa_gpio_mode(POODLE_GPIO_SD_PWR | GPIO_OUT);
-	pxa_gpio_mode(POODLE_GPIO_SD_PWR1 | GPIO_OUT);
+	err = gpio_request(POODLE_GPIO_nSD_DETECT, "nSD_DETECT");
+	if (err)
+		goto err_out;
+
+	err = gpio_request(POODLE_GPIO_nSD_WP, "nSD_WP");
+	if (err)
+		goto err_free_1;
+
+	err = gpio_request(POODLE_GPIO_SD_PWR, "SD_PWR");
+	if (err)
+		goto err_free_2;
+
+	err = gpio_request(POODLE_GPIO_SD_PWR1, "SD_PWR1");
+	if (err)
+		goto err_free_3;
+
+	gpio_direction_input(POODLE_GPIO_nSD_DETECT);
+	gpio_direction_input(POODLE_GPIO_nSD_WP);
+
+	gpio_direction_output(POODLE_GPIO_SD_PWR, 0);
+	gpio_direction_output(POODLE_GPIO_SD_PWR1, 0);
 
 	poodle_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 
 	err = request_irq(POODLE_IRQ_GPIO_nSD_DETECT, poodle_detect_int,
 			  IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 			  "MMC card detect", data);
-	if (err)
-		printk(KERN_ERR "poodle_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
+	if (err) {
+		pr_err("%s: MMC/SD: can't request MMC card detect IRQ\n",
+				__func__);
+		goto err_free_4;
+	}
 
+	return 0;
+
+err_free_4:
+	gpio_free(POODLE_GPIO_SD_PWR1);
+err_free_3:
+	gpio_free(POODLE_GPIO_SD_PWR);
+err_free_2:
+	gpio_free(POODLE_GPIO_nSD_WP);
+err_free_1:
+	gpio_free(POODLE_GPIO_nSD_DETECT);
+err_out:
 	return err;
 }
 
@@ -228,18 +314,19 @@
 {
 	struct pxamci_platform_data* p_d = dev->platform_data;
 
-	if (( 1 << vdd) & p_d->ocr_mask) {
-		GPSR(POODLE_GPIO_SD_PWR) = GPIO_bit(POODLE_GPIO_SD_PWR);
+	if ((1 << vdd) & p_d->ocr_mask) {
+		gpio_set_value(POODLE_GPIO_SD_PWR, 1);
 		mdelay(2);
-		GPSR(POODLE_GPIO_SD_PWR1) = GPIO_bit(POODLE_GPIO_SD_PWR1);
+		gpio_set_value(POODLE_GPIO_SD_PWR1, 1);
 	} else {
-		GPCR(POODLE_GPIO_SD_PWR1) = GPIO_bit(POODLE_GPIO_SD_PWR1);
-		GPCR(POODLE_GPIO_SD_PWR) = GPIO_bit(POODLE_GPIO_SD_PWR);
+		gpio_set_value(POODLE_GPIO_SD_PWR1, 0);
+		gpio_set_value(POODLE_GPIO_SD_PWR, 0);
 	}
 }
 
 static int poodle_mci_get_ro(struct device *dev)
 {
+	return !!gpio_get_value(POODLE_GPIO_nSD_WP);
 	return GPLR(POODLE_GPIO_nSD_WP) & GPIO_bit(POODLE_GPIO_nSD_WP);
 }
 
@@ -247,6 +334,10 @@
 static void poodle_mci_exit(struct device *dev, void *data)
 {
 	free_irq(POODLE_IRQ_GPIO_nSD_DETECT, data);
+	gpio_free(POODLE_GPIO_SD_PWR1);
+	gpio_free(POODLE_GPIO_SD_PWR);
+	gpio_free(POODLE_GPIO_nSD_WP);
+	gpio_free(POODLE_GPIO_nSD_DETECT);
 }
 
 static struct pxamci_platform_data poodle_mci_platform_data = {
@@ -263,38 +354,41 @@
  */
 static void poodle_irda_transceiver_mode(struct device *dev, int mode)
 {
-	if (mode & IR_OFF) {
-		GPSR(POODLE_GPIO_IR_ON) = GPIO_bit(POODLE_GPIO_IR_ON);
-	} else {
-		GPCR(POODLE_GPIO_IR_ON) = GPIO_bit(POODLE_GPIO_IR_ON);
-	}
+	gpio_set_value(POODLE_GPIO_IR_ON, mode & IR_OFF);
 	pxa2xx_transceiver_mode(dev, mode);
 }
 
+static int poodle_irda_startup(struct device *dev)
+{
+	int err;
+
+	err = gpio_request(POODLE_GPIO_IR_ON, "IR_ON");
+	if (err)
+		return err;
+
+	gpio_direction_output(POODLE_GPIO_IR_ON, 1);
+	return 0;
+}
+
+static void poodle_irda_shutdown(struct device *dev)
+{
+	gpio_free(POODLE_GPIO_IR_ON);
+}
+
 static struct pxaficp_platform_data poodle_ficp_platform_data = {
-	.transceiver_cap  = IR_SIRMODE | IR_OFF,
-	.transceiver_mode = poodle_irda_transceiver_mode,
+	.transceiver_cap	= IR_SIRMODE | IR_OFF,
+	.transceiver_mode	= poodle_irda_transceiver_mode,
+	.startup		= poodle_irda_startup,
+	.shutdown		= poodle_irda_shutdown,
 };
 
 
 /*
  * USB Device Controller
  */
-static void poodle_udc_command(int cmd)
-{
-	switch(cmd)	{
-	case PXA2XX_UDC_CMD_CONNECT:
-		GPSR(POODLE_GPIO_USB_PULLUP) = GPIO_bit(POODLE_GPIO_USB_PULLUP);
-		break;
-	case PXA2XX_UDC_CMD_DISCONNECT:
-		GPCR(POODLE_GPIO_USB_PULLUP) = GPIO_bit(POODLE_GPIO_USB_PULLUP);
-		break;
-	}
-}
-
 static struct pxa2xx_udc_mach_info udc_info __initdata = {
 	/* no connect GPIO; poodle can't tell connection status */
-	.udc_command		= poodle_udc_command,
+	.gpio_pullup	= POODLE_GPIO_USB_PULLUP,
 };
 
 
@@ -316,15 +410,12 @@
 static struct pxafb_mach_info poodle_fb_info = {
 	.modes		= &poodle_fb_mode,
 	.num_modes	= 1,
-	.lccr0		= LCCR0_Act | LCCR0_Sngl | LCCR0_Color,
-	.lccr3		= 0,
+	.lcd_conn	= LCD_COLOR_TFT_16BPP,
 };
 
 static struct platform_device *devices[] __initdata = {
 	&poodle_locomo_device,
 	&poodle_scoop_device,
-	&poodle_ssp_device,
-	&poodle_ts_device,
 };
 
 static void poodle_poweroff(void)
@@ -344,59 +435,23 @@
 	pm_power_off = poodle_poweroff;
 	arm_pm_restart = poodle_restart;
 
-	/* setup sleep mode values */
-	PWER  = 0x00000002;
-	PFER  = 0x00000000;
-	PRER  = 0x00000002;
-	PGSR0 = 0x00008000;
-	PGSR1 = 0x003F0202;
-	PGSR2 = 0x0001C000;
 	PCFR |= PCFR_OPDE;
 
-	/* cpu initialize */
-	/* Pgsr Register */
-  	PGSR0 = 0x0146dd80;
-  	PGSR1 = 0x03bf0890;
-  	PGSR2 = 0x0001c000;
-
-	/* Alternate Register */
-  	GAFR0_L = 0x01001000;
-  	GAFR0_U = 0x591a8010;
-  	GAFR1_L = 0x900a8451;
-  	GAFR1_U = 0xaaa5aaaa;
-  	GAFR2_L = 0x8aaaaaaa;
-  	GAFR2_U = 0x00000002;
-
-	/* Direction Register */
-  	GPDR0 = 0xd3f0904c;
-  	GPDR1 = 0xfcffb7d3;
-  	GPDR2 = 0x0001ffff;
-
-	/* Output Register */
-  	GPCR0 = 0x00000000;
-  	GPCR1 = 0x00000000;
-  	GPCR2 = 0x00000000;
-
-  	GPSR0 = 0x00400000;
-  	GPSR1 = 0x00000000;
-        GPSR2 = 0x00000000;
-
-	set_pxa_fb_parent(&poodle_locomo_device.dev);
-	set_pxa_fb_info(&poodle_fb_info);
-	pxa_gpio_mode(POODLE_GPIO_USB_PULLUP | GPIO_OUT);
-	pxa_gpio_mode(POODLE_GPIO_IR_ON | GPIO_OUT);
-	pxa_set_udc_info(&udc_info);
-	pxa_set_mci_info(&poodle_mci_platform_data);
-	pxa_set_ficp_info(&poodle_ficp_platform_data);
-	pxa_set_i2c_info(NULL);
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(poodle_pin_config));
 
 	platform_scoop_config = &poodle_pcmcia_config;
 
 	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
-	if (ret) {
-		printk(KERN_WARNING "poodle: Unable to register LoCoMo device\n");
-	}
-	corgi_ssp_set_machinfo(&poodle_ssp_machinfo);
+	if (ret)
+		pr_warning("poodle: Unable to register LoCoMo device\n");
+
+	set_pxa_fb_parent(&poodle_locomo_device.dev);
+	set_pxa_fb_info(&poodle_fb_info);
+	pxa_set_udc_info(&udc_info);
+	pxa_set_mci_info(&poodle_mci_platform_data);
+	pxa_set_ficp_info(&poodle_ficp_platform_data);
+	pxa_set_i2c_info(NULL);
+	poodle_init_spi();
 }
 
 static void __init fixup_poodle(struct machine_desc *desc,
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 305452b..25d17a1 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -36,6 +36,12 @@
 #include "devices.h"
 #include "clock.h"
 
+int cpu_is_pxa26x(void)
+{
+	return cpu_is_pxa250() && ((BOOT_DEF & 0x8) == 0);
+}
+EXPORT_SYMBOL_GPL(cpu_is_pxa26x);
+
 /*
  * Various clock factors driven by the CCCR register.
  */
@@ -203,48 +209,21 @@
  * More ones like CP and general purpose register values are preserved
  * with the stack pointer in sleep.S.
  */
-enum {	SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2,
-
-	SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
-	SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U,
-	SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U,
-
+enum {
 	SLEEP_SAVE_PSTR,
-
 	SLEEP_SAVE_CKEN,
-
 	SLEEP_SAVE_COUNT
 };
 
 
 static void pxa25x_cpu_pm_save(unsigned long *sleep_save)
 {
-	SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2);
-
-	SAVE(GAFR0_L); SAVE(GAFR0_U);
-	SAVE(GAFR1_L); SAVE(GAFR1_U);
-	SAVE(GAFR2_L); SAVE(GAFR2_U);
-
 	SAVE(CKEN);
 	SAVE(PSTR);
-
-	/* Clear GPIO transition detect bits */
-	GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2;
 }
 
 static void pxa25x_cpu_pm_restore(unsigned long *sleep_save)
 {
-	/* ensure not to come back here if it wasn't intended */
-	PSPR = 0;
-
-	/* restore registers */
-	RESTORE(GAFR0_L); RESTORE(GAFR0_U);
-	RESTORE(GAFR1_L); RESTORE(GAFR1_U);
-	RESTORE(GAFR2_L); RESTORE(GAFR2_U);
-	RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2);
-
-	PSSR = PSSR_RDH | PSSR_PH;
-
 	RESTORE(CKEN);
 	RESTORE(PSTR);
 }
@@ -256,19 +235,32 @@
 
 	switch (state) {
 	case PM_SUSPEND_MEM:
-		/* set resume return address */
-		PSPR = virt_to_phys(pxa_cpu_resume);
 		pxa25x_cpu_suspend(PWRMODE_SLEEP);
 		break;
 	}
 }
 
+static int pxa25x_cpu_pm_prepare(void)
+{
+	/* set resume return address */
+	PSPR = virt_to_phys(pxa_cpu_resume);
+	return 0;
+}
+
+static void pxa25x_cpu_pm_finish(void)
+{
+	/* ensure not to come back here if it wasn't intended */
+	PSPR = 0;
+}
+
 static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = {
 	.save_count	= SLEEP_SAVE_COUNT,
 	.valid		= suspend_valid_only_mem,
 	.save		= pxa25x_cpu_pm_save,
 	.restore	= pxa25x_cpu_pm_restore,
 	.enter		= pxa25x_cpu_pm_enter,
+	.prepare	= pxa25x_cpu_pm_prepare,
+	.finish		= pxa25x_cpu_pm_finish,
 };
 
 static void __init pxa25x_init_pm(void)
@@ -330,6 +322,8 @@
 	{
 		.cls	= &pxa_irq_sysclass,
 	}, {
+		.cls	= &pxa2xx_mfp_sysclass,
+	}, {
 		.cls	= &pxa_gpio_sysclass,
 	},
 };
@@ -338,11 +332,7 @@
 {
 	int i, ret = 0;
 
-	/* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
-	if (cpu_is_pxa255())
-		clks_register(&pxa25x_hwuart_clk, 1);
-
-	if (cpu_is_pxa21x() || cpu_is_pxa25x()) {
+	if (cpu_is_pxa25x()) {
 
 		reset_status = RCSR;
 
@@ -365,9 +355,11 @@
 			return ret;
 	}
 
-	/* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
-	if (cpu_is_pxa255())
+	/* Only add HWUART for PXA255/26x; PXA210/250 do not have it. */
+	if (cpu_is_pxa255() || cpu_is_pxa26x()) {
+		clks_register(&pxa25x_hwuart_clk, 1);
 		ret = platform_device_register(&pxa_device_hwuart);
+	}
 
 	return ret;
 }
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index f9f6a9c..3e4ab22 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -34,6 +34,13 @@
 #include "devices.h"
 #include "clock.h"
 
+void pxa27x_clear_otgph(void)
+{
+	if (cpu_is_pxa27x() && (PSSR & PSSR_OTGPH))
+		PSSR |= PSSR_OTGPH;
+}
+EXPORT_SYMBOL(pxa27x_clear_otgph);
+
 /* Crystal clock: 13MHz */
 #define BASE_CLK	13000000
 
@@ -183,36 +190,18 @@
  * More ones like CP and general purpose register values are preserved
  * with the stack pointer in sleep.S.
  */
-enum {	SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3,
-
-	SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
-	SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U,
-	SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U,
-	SLEEP_SAVE_GAFR3_L, SLEEP_SAVE_GAFR3_U,
-
+enum {
 	SLEEP_SAVE_PSTR,
-
 	SLEEP_SAVE_CKEN,
-
 	SLEEP_SAVE_MDREFR,
-	SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER,
-	SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR,
-
+	SLEEP_SAVE_PCFR,
 	SLEEP_SAVE_COUNT
 };
 
 void pxa27x_cpu_pm_save(unsigned long *sleep_save)
 {
-	SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); SAVE(PGSR3);
-
-	SAVE(GAFR0_L); SAVE(GAFR0_U);
-	SAVE(GAFR1_L); SAVE(GAFR1_U);
-	SAVE(GAFR2_L); SAVE(GAFR2_U);
-	SAVE(GAFR3_L); SAVE(GAFR3_U);
-
 	SAVE(MDREFR);
-	SAVE(PWER); SAVE(PCFR); SAVE(PRER);
-	SAVE(PFER); SAVE(PKWR);
+	SAVE(PCFR);
 
 	SAVE(CKEN);
 	SAVE(PSTR);
@@ -220,24 +209,12 @@
 
 void pxa27x_cpu_pm_restore(unsigned long *sleep_save)
 {
-	/* ensure not to come back here if it wasn't intended */
-	PSPR = 0;
-
-	/* restore registers */
-	RESTORE(GAFR0_L); RESTORE(GAFR0_U);
-	RESTORE(GAFR1_L); RESTORE(GAFR1_U);
-	RESTORE(GAFR2_L); RESTORE(GAFR2_U);
-	RESTORE(GAFR3_L); RESTORE(GAFR3_U);
-	RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3);
-
 	RESTORE(MDREFR);
-	RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER);
-	RESTORE(PFER); RESTORE(PKWR);
+	RESTORE(PCFR);
 
 	PSSR = PSSR_RDH | PSSR_PH;
 
 	RESTORE(CKEN);
-
 	RESTORE(PSTR);
 }
 
@@ -259,8 +236,6 @@
 		pxa_cpu_standby();
 		break;
 	case PM_SUSPEND_MEM:
-		/* set resume return address */
-		PSPR = virt_to_phys(pxa_cpu_resume);
 		pxa27x_cpu_suspend(PWRMODE_SLEEP);
 		break;
 	}
@@ -271,12 +246,27 @@
 	return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY;
 }
 
+static int pxa27x_cpu_pm_prepare(void)
+{
+	/* set resume return address */
+	PSPR = virt_to_phys(pxa_cpu_resume);
+	return 0;
+}
+
+static void pxa27x_cpu_pm_finish(void)
+{
+	/* ensure not to come back here if it wasn't intended */
+	PSPR = 0;
+}
+
 static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = {
 	.save_count	= SLEEP_SAVE_COUNT,
 	.save		= pxa27x_cpu_pm_save,
 	.restore	= pxa27x_cpu_pm_restore,
 	.valid		= pxa27x_cpu_pm_valid,
 	.enter		= pxa27x_cpu_pm_enter,
+	.prepare	= pxa27x_cpu_pm_prepare,
+	.finish		= pxa27x_cpu_pm_finish,
 };
 
 static void __init pxa27x_init_pm(void)
@@ -349,7 +339,7 @@
 	.num_resources	= ARRAY_SIZE(i2c_power_resources),
 };
 
-void __init pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info)
+void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
 {
 	local_irq_disable();
 	PCFR |= PCFR_PI2CEN;
@@ -376,6 +366,8 @@
 	{
 		.cls	= &pxa_irq_sysclass,
 	}, {
+		.cls	= &pxa2xx_mfp_sysclass,
+	}, {
 		.cls	= &pxa_gpio_sysclass,
 	},
 };
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 03cbc381..b3cd5d0 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -203,6 +203,19 @@
 	.disable	= clk_pout_disable,
 };
 
+static void clk_dummy_enable(struct clk *clk)
+{
+}
+
+static void clk_dummy_disable(struct clk *clk)
+{
+}
+
+static const struct clkops clk_dummy_ops = {
+	.enable		= clk_dummy_enable,
+	.disable	= clk_dummy_disable,
+};
+
 static struct clk pxa3xx_clks[] = {
 	{
 		.name           = "CLK_POUT",
@@ -211,6 +224,13 @@
 		.delay          = 70,
 	},
 
+	/* Power I2C clock is always on */
+	{
+		.name		= "I2CCLK",
+		.ops		= &clk_dummy_ops,
+		.dev		= &pxa3xx_device_i2c_power.dev,
+	},
+
 	PXA3xx_CK("LCDCLK",  LCD,    &clk_pxa3xx_hsio_ops, &pxa_device_fb.dev),
 	PXA3xx_CK("CAMCLK",  CAMERA, &clk_pxa3xx_hsio_ops, NULL),
 	PXA3xx_CK("AC97CLK", AC97,   &clk_pxa3xx_ac97_ops, NULL),
@@ -509,6 +529,30 @@
  * device registration specific to PXA3xx.
  */
 
+static struct resource i2c_power_resources[] = {
+	{
+		.start  = 0x40f500c0,
+		.end    = 0x40f500d3,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_PWRI2C,
+		.end	= IRQ_PWRI2C,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device pxa3xx_device_i2c_power = {
+	.name		= "pxa2xx-i2c",
+	.id		= 1,
+	.resource	= i2c_power_resources,
+	.num_resources	= ARRAY_SIZE(i2c_power_resources),
+};
+
+void __init pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info)
+{
+	pxa3xx_device_i2c_power.dev.platform_data = info;
+}
+
 static struct platform_device *devices[] __initdata = {
 /*	&pxa_device_udc,	The UDC driver is PXA25x only */
 	&pxa_device_ffuart,
@@ -522,6 +566,7 @@
 	&pxa3xx_device_ssp4,
 	&pxa27x_device_pwm0,
 	&pxa27x_device_pwm1,
+	&pxa3xx_device_i2c_power,
 };
 
 static struct sys_device pxa3xx_sysdev[] = {
diff --git a/arch/arm/mach-pxa/reset.c b/arch/arm/mach-pxa/reset.c
index 9996c61..31d7885 100644
--- a/arch/arm/mach-pxa/reset.c
+++ b/arch/arm/mach-pxa/reset.c
@@ -7,7 +7,7 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/gpio.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/proc-fns.h>
 
 #include <mach/pxa-regs.h>
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
index e804ae0..15c2f1a 100644
--- a/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -116,24 +116,20 @@
 	{   0,   0},
 };
 
-/* MAX1111 Commands */
-#define MAXCTRL_PD0      1u << 0
-#define MAXCTRL_PD1      1u << 1
-#define MAXCTRL_SGL      1u << 2
-#define MAXCTRL_UNI      1u << 3
-#define MAXCTRL_SEL_SH   4
-#define MAXCTRL_STR      1u << 7
-
 /*
  * Read MAX1111 ADC
  */
+extern int max1111_read_channel(int);
+
 int sharpsl_pm_pxa_read_max1111(int channel)
 {
 	if (machine_is_tosa()) // Ugly, better move this function into another module
 	    return 0;
 
-	return corgi_ssp_max1111_get((channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1
-			| MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR);
+	/* max1111 accepts channels from 0-3, however,
+	 * it is encoded from 0-7 here in the code.
+	 */
+	return max1111_read_channel(channel >> 1);
 }
 
 void sharpsl_pm_pxa_init(void)
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index b569f3b..9b4f24c 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -19,16 +19,23 @@
 #include <linux/major.h>
 #include <linux/fs.h>
 #include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
 #include <linux/mmc/host.h>
 #include <linux/pm.h>
 #include <linux/backlight.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/spi/corgi_lcd.h>
 
 #include <asm/setup.h>
 #include <asm/memory.h>
 #include <asm/mach-types.h>
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 #include <asm/system.h>
 
 #include <asm/mach/arch.h>
@@ -37,7 +44,7 @@
 
 #include <mach/pxa-regs.h>
 #include <mach/pxa2xx-regs.h>
-#include <mach/pxa2xx-gpio.h>
+#include <mach/mfp-pxa27x.h>
 #include <mach/pxa27x-udc.h>
 #include <mach/reset.h>
 #include <mach/i2c.h>
@@ -46,7 +53,7 @@
 #include <mach/ohci.h>
 #include <mach/udc.h>
 #include <mach/pxafb.h>
-#include <mach/akita.h>
+#include <mach/pxa2xx_spi.h>
 #include <mach/spitz.h>
 #include <mach/sharpsl.h>
 
@@ -57,6 +64,66 @@
 #include "devices.h"
 #include "sharpsl.h"
 
+static unsigned long spitz_pin_config[] __initdata = {
+	/* Chip Selects */
+	GPIO78_nCS_2,	/* SCOOP #2 */
+	GPIO80_nCS_4,	/* SCOOP #1 */
+
+	/* LCD - 16bpp Active TFT */
+	GPIO58_LCD_LDD_0,
+	GPIO59_LCD_LDD_1,
+	GPIO60_LCD_LDD_2,
+	GPIO61_LCD_LDD_3,
+	GPIO62_LCD_LDD_4,
+	GPIO63_LCD_LDD_5,
+	GPIO64_LCD_LDD_6,
+	GPIO65_LCD_LDD_7,
+	GPIO66_LCD_LDD_8,
+	GPIO67_LCD_LDD_9,
+	GPIO68_LCD_LDD_10,
+	GPIO69_LCD_LDD_11,
+	GPIO70_LCD_LDD_12,
+	GPIO71_LCD_LDD_13,
+	GPIO72_LCD_LDD_14,
+	GPIO73_LCD_LDD_15,
+	GPIO74_LCD_FCLK,
+	GPIO75_LCD_LCLK,
+	GPIO76_LCD_PCLK,
+
+	/* PC Card */
+	GPIO48_nPOE,
+	GPIO49_nPWE,
+	GPIO50_nPIOR,
+	GPIO51_nPIOW,
+	GPIO85_nPCE_1,
+	GPIO54_nPCE_2,
+	GPIO79_PSKTSEL,
+	GPIO55_nPREG,
+	GPIO56_nPWAIT,
+	GPIO57_nIOIS16,
+
+	/* MMC */
+	GPIO32_MMC_CLK,
+	GPIO112_MMC_CMD,
+	GPIO92_MMC_DAT_0,
+	GPIO109_MMC_DAT_1,
+	GPIO110_MMC_DAT_2,
+	GPIO111_MMC_DAT_3,
+
+	/* GPIOs */
+	GPIO9_GPIO,	/* SPITZ_GPIO_nSD_DETECT */
+	GPIO81_GPIO,	/* SPITZ_GPIO_nSD_WP */
+	GPIO41_GPIO,	/* SPITZ_GPIO_USB_CONNECT */
+	GPIO37_GPIO,	/* SPITZ_GPIO_USB_HOST */
+	GPIO35_GPIO,	/* SPITZ_GPIO_USB_DEVICE */
+	GPIO22_GPIO,	/* SPITZ_GPIO_HSYNC */
+	GPIO94_GPIO,	/* SPITZ_GPIO_CF_CD */
+	GPIO105_GPIO,	/* SPITZ_GPIO_CF_IRQ */
+	GPIO106_GPIO,	/* SPITZ_GPIO_CF2_IRQ */
+
+	GPIO1_GPIO | WAKEUP_ON_EDGE_RISE,
+};
+
 /*
  * Spitz SCOOP Device #1
  */
@@ -69,10 +136,11 @@
 };
 
 static struct scoop_config spitz_scoop_setup = {
-	.io_dir 	= SPITZ_SCP_IO_DIR,
+	.io_dir		= SPITZ_SCP_IO_DIR,
 	.io_out		= SPITZ_SCP_IO_OUT,
-	.suspend_clr = SPITZ_SCP_SUS_CLR,
-	.suspend_set = SPITZ_SCP_SUS_SET,
+	.suspend_clr	= SPITZ_SCP_SUS_CLR,
+	.suspend_set	= SPITZ_SCP_SUS_SET,
+	.gpio_base	= SPITZ_SCP_GPIO_BASE,
 };
 
 struct platform_device spitzscoop_device = {
@@ -97,10 +165,11 @@
 };
 
 static struct scoop_config spitz_scoop2_setup = {
-	.io_dir 	= SPITZ_SCP2_IO_DIR,
+	.io_dir		= SPITZ_SCP2_IO_DIR,
 	.io_out		= SPITZ_SCP2_IO_OUT,
-	.suspend_clr = SPITZ_SCP2_SUS_CLR,
-	.suspend_set = SPITZ_SCP2_SUS_SET,
+	.suspend_clr	= SPITZ_SCP2_SUS_CLR,
+	.suspend_set	= SPITZ_SCP2_SUS_SET,
+	.gpio_base	= SPITZ_SCP2_GPIO_BASE,
 };
 
 struct platform_device spitzscoop2_device = {
@@ -122,7 +191,7 @@
 	unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR);
 
 	if (new_cpr & 0x0007) {
-	        set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
+		gpio_set_value(SPITZ_GPIO_CF_POWER, 1);
 		if (!(cpr & 0x0002) && !(cpr & 0x0004))
 		        mdelay(5);
 		if (device == SPITZ_PWR_CF)
@@ -138,34 +207,13 @@
 		if (!(cpr & 0x0002) && !(cpr & 0x0004)) {
 			write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, 0x0000);
 		        mdelay(1);
-		        reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
+			gpio_set_value(SPITZ_GPIO_CF_POWER, 0);
 		} else {
 		        write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr);
 		}
 	}
 }
 
-static void spitz_pcmcia_init(void)
-{
-	/* Setup default state of GPIO outputs
-	   before we enable them as outputs. */
-	GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
-		GPIO_bit(GPIO49_nPWE) |	GPIO_bit(GPIO50_nPIOR) |
-		GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO54_nPCE_2);
-	GPSR(GPIO85_nPCE_1) = GPIO_bit(GPIO85_nPCE_1);
-
-	pxa_gpio_mode(GPIO48_nPOE_MD);
-	pxa_gpio_mode(GPIO49_nPWE_MD);
-	pxa_gpio_mode(GPIO50_nPIOR_MD);
-	pxa_gpio_mode(GPIO51_nPIOW_MD);
-	pxa_gpio_mode(GPIO55_nPREG_MD);
-	pxa_gpio_mode(GPIO56_nPWAIT_MD);
-	pxa_gpio_mode(GPIO57_nIOIS16_MD);
-	pxa_gpio_mode(GPIO85_nPCE_1_MD);
-	pxa_gpio_mode(GPIO54_nPCE_2_MD);
-	pxa_gpio_mode(GPIO104_pSKTSEL_MD);
-}
-
 static void spitz_pcmcia_pwr(struct device *scoop, unsigned short cpr, int nr)
 {
 	/* Only need to override behaviour for slot 0 */
@@ -191,71 +239,12 @@
 static struct scoop_pcmcia_config spitz_pcmcia_config = {
 	.devs         = &spitz_pcmcia_scoop[0],
 	.num_devs     = 2,
-	.pcmcia_init  = spitz_pcmcia_init,
 	.power_ctrl   = spitz_pcmcia_pwr,
 };
 
 EXPORT_SYMBOL(spitzscoop_device);
 EXPORT_SYMBOL(spitzscoop2_device);
 
-
-/*
- * Spitz SSP Device
- *
- * Set the parent as the scoop device because a lot of SSP devices
- * also use scoop functions and this makes the power up/down order
- * work correctly.
- */
-struct platform_device spitzssp_device = {
-	.name		= "corgi-ssp",
-	.dev		= {
- 		.parent = &spitzscoop_device.dev,
-	},
-	.id		= -1,
-};
-
-struct corgissp_machinfo spitz_ssp_machinfo = {
-	.port		= 2,
-	.cs_lcdcon	= SPITZ_GPIO_LCDCON_CS,
-	.cs_ads7846	= SPITZ_GPIO_ADS7846_CS,
-	.cs_max1111	= SPITZ_GPIO_MAX1111_CS,
-	.clk_lcdcon	= 520,
-	.clk_ads7846	= 14,
-	.clk_max1111	= 56,
-};
-
-
-/*
- * Spitz Backlight Device
- */
-static void spitz_bl_kick_battery(void)
-{
-	void (*kick_batt)(void);
-
-	kick_batt = symbol_get(sharpsl_battery_kick);
-	if (kick_batt) {
-		kick_batt();
-		symbol_put(sharpsl_battery_kick);
-	}
-}
-
-static struct generic_bl_info spitz_bl_machinfo = {
-	.name = "corgi-bl",
-	.default_intensity = 0x1f,
-	.limit_mask = 0x0b,
-	.max_intensity = 0x2f,
-	.kick_battery = spitz_bl_kick_battery,
-};
-
-static struct platform_device spitzbl_device = {
-	.name		= "generic-bl",
-	.dev		= {
- 		.platform_data	= &spitz_bl_machinfo,
-	},
-	.id		= -1,
-};
-
-
 /*
  * Spitz Keyboard Device
  */
@@ -268,88 +257,151 @@
 /*
  * Spitz LEDs
  */
+static struct gpio_led spitz_gpio_leds[] = {
+	{
+		.name			= "spitz:amber:charge",
+		.default_trigger	= "sharpsl-charge",
+		.gpio			= SPITZ_GPIO_LED_ORANGE,
+	},
+	{
+		.name			= "spitz:green:hddactivity",
+		.default_trigger	= "ide-disk",
+		.gpio			= SPITZ_GPIO_LED_GREEN,
+	},
+};
+
+static struct gpio_led_platform_data spitz_gpio_leds_info = {
+	.leds		= spitz_gpio_leds,
+	.num_leds	= ARRAY_SIZE(spitz_gpio_leds),
+};
+
 static struct platform_device spitzled_device = {
-	.name		= "spitz-led",
+	.name		= "leds-gpio",
 	.id		= -1,
-};
-
-/*
- * Spitz Touch Screen Device
- */
-
-static unsigned long (*get_hsync_invperiod)(struct device *dev);
-
-static void inline sharpsl_wait_sync(int gpio)
-{
-	while((GPLR(gpio) & GPIO_bit(gpio)) == 0);
-	while((GPLR(gpio) & GPIO_bit(gpio)) != 0);
-}
-
-static struct device *spitz_pxafb_dev;
-
-static int is_pxafb_device(struct device * dev, void * data)
-{
-	struct platform_device *pdev = container_of(dev, struct platform_device, dev);
-
-	return (strncmp(pdev->name, "pxa2xx-fb", 9) == 0);
-}
-
-static unsigned long spitz_get_hsync_invperiod(void)
-{
-#ifdef CONFIG_FB_PXA
-	if (!spitz_pxafb_dev) {
-		spitz_pxafb_dev = bus_find_device(&platform_bus_type, NULL, NULL, is_pxafb_device);
-		if (!spitz_pxafb_dev)
-			return 0;
-	}
-	if (!get_hsync_invperiod)
-		get_hsync_invperiod = symbol_get(pxafb_get_hsync_time);
-	if (!get_hsync_invperiod)
-#endif
-		return 0;
-
-	return get_hsync_invperiod(spitz_pxafb_dev);
-}
-
-static void spitz_put_hsync(void)
-{
-	put_device(spitz_pxafb_dev);
-	if (get_hsync_invperiod)
-		symbol_put(pxafb_get_hsync_time);
-	spitz_pxafb_dev = NULL;
-	get_hsync_invperiod = NULL;
-}
-
-static void spitz_wait_hsync(void)
-{
-	sharpsl_wait_sync(SPITZ_GPIO_HSYNC);
-}
-
-static struct resource spitzts_resources[] = {
-	[0] = {
-		.start		= SPITZ_IRQ_GPIO_TP_INT,
-		.end		= SPITZ_IRQ_GPIO_TP_INT,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct corgits_machinfo  spitz_ts_machinfo = {
-	.get_hsync_invperiod = spitz_get_hsync_invperiod,
-	.put_hsync           = spitz_put_hsync,
-	.wait_hsync          = spitz_wait_hsync,
-};
-
-static struct platform_device spitzts_device = {
-	.name		= "corgi-ts",
 	.dev		= {
- 		.parent = &spitzssp_device.dev,
-		.platform_data	= &spitz_ts_machinfo,
+		.platform_data = &spitz_gpio_leds_info,
 	},
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(spitzts_resources),
-	.resource	= spitzts_resources,
 };
 
+#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
+static struct pxa2xx_spi_master spitz_spi_info = {
+	.num_chipselect	= 3,
+};
+
+static struct ads7846_platform_data spitz_ads7846_info = {
+	.model			= 7846,
+	.vref_delay_usecs	= 100,
+	.x_plate_ohms		= 419,
+	.y_plate_ohms		= 486,
+	.gpio_pendown		= SPITZ_GPIO_TP_INT,
+};
+
+static void spitz_ads7846_cs(u32 command)
+{
+	gpio_set_value(SPITZ_GPIO_ADS7846_CS, !(command == PXA2XX_CS_ASSERT));
+}
+
+static struct pxa2xx_spi_chip spitz_ads7846_chip = {
+	.cs_control		= spitz_ads7846_cs,
+};
+
+static void spitz_bl_kick_battery(void)
+{
+	void (*kick_batt)(void);
+
+	kick_batt = symbol_get(sharpsl_battery_kick);
+	if (kick_batt) {
+		kick_batt();
+		symbol_put(sharpsl_battery_kick);
+	}
+}
+
+static struct corgi_lcd_platform_data spitz_lcdcon_info = {
+	.init_mode		= CORGI_LCD_MODE_VGA,
+	.max_intensity		= 0x2f,
+	.default_intensity	= 0x1f,
+	.limit_mask		= 0x0b,
+	.gpio_backlight_cont	= SPITZ_GPIO_BACKLIGHT_CONT,
+	.gpio_backlight_on	= SPITZ_GPIO_BACKLIGHT_ON,
+	.kick_battery		= spitz_bl_kick_battery,
+};
+
+static void spitz_lcdcon_cs(u32 command)
+{
+	gpio_set_value(SPITZ_GPIO_LCDCON_CS, !(command == PXA2XX_CS_ASSERT));
+}
+
+static struct pxa2xx_spi_chip spitz_lcdcon_chip = {
+	.cs_control	= spitz_lcdcon_cs,
+};
+
+static void spitz_max1111_cs(u32 command)
+{
+	gpio_set_value(SPITZ_GPIO_MAX1111_CS, !(command == PXA2XX_CS_ASSERT));
+}
+
+static struct pxa2xx_spi_chip spitz_max1111_chip = {
+	.cs_control	= spitz_max1111_cs,
+};
+
+static struct spi_board_info spitz_spi_devices[] = {
+	{
+		.modalias	= "ads7846",
+		.max_speed_hz	= 1200000,
+		.bus_num	= 2,
+		.chip_select	= 0,
+		.platform_data	= &spitz_ads7846_info,
+		.controller_data= &spitz_ads7846_chip,
+		.irq		= gpio_to_irq(SPITZ_GPIO_TP_INT),
+	}, {
+		.modalias	= "corgi-lcd",
+		.max_speed_hz	= 50000,
+		.bus_num	= 2,
+		.chip_select	= 1,
+		.platform_data	= &spitz_lcdcon_info,
+		.controller_data= &spitz_lcdcon_chip,
+	}, {
+		.modalias	= "max1111",
+		.max_speed_hz	= 450000,
+		.bus_num	= 2,
+		.chip_select	= 2,
+		.controller_data= &spitz_max1111_chip,
+	},
+};
+
+static void __init spitz_init_spi(void)
+{
+	int err;
+
+	err = gpio_request(SPITZ_GPIO_ADS7846_CS, "ADS7846_CS");
+	if (err)
+		return;
+
+	err = gpio_request(SPITZ_GPIO_LCDCON_CS, "LCDCON_CS");
+	if (err)
+		goto err_free_1;
+
+	err = gpio_request(SPITZ_GPIO_MAX1111_CS, "MAX1111_CS");
+	if (err)
+		goto err_free_2;
+
+	if (machine_is_akita()) {
+		spitz_lcdcon_info.gpio_backlight_cont = AKITA_GPIO_BACKLIGHT_CONT;
+		spitz_lcdcon_info.gpio_backlight_on = AKITA_GPIO_BACKLIGHT_ON;
+	}
+
+	pxa2xx_set_spi_info(2, &spitz_spi_info);
+	spi_register_board_info(ARRAY_AND_SIZE(spitz_spi_devices));
+	return;
+
+err_free_2:
+	gpio_free(SPITZ_GPIO_LCDCON_CS);
+err_free_1:
+	gpio_free(SPITZ_GPIO_ADS7846_CS);
+}
+#else
+static inline void spitz_init_spi(void) {}
+#endif
 
 /*
  * MMC/SD Device
@@ -364,24 +416,35 @@
 {
 	int err;
 
-	/* setup GPIO for PXA27x MMC controller	*/
-	pxa_gpio_mode(GPIO32_MMCCLK_MD);
-	pxa_gpio_mode(GPIO112_MMCCMD_MD);
-	pxa_gpio_mode(GPIO92_MMCDAT0_MD);
-	pxa_gpio_mode(GPIO109_MMCDAT1_MD);
-	pxa_gpio_mode(GPIO110_MMCDAT2_MD);
-	pxa_gpio_mode(GPIO111_MMCDAT3_MD);
-	pxa_gpio_mode(SPITZ_GPIO_nSD_DETECT | GPIO_IN);
-	pxa_gpio_mode(SPITZ_GPIO_nSD_WP | GPIO_IN);
+	err = gpio_request(SPITZ_GPIO_nSD_DETECT, "nSD_DETECT");
+	if (err)
+		goto err_out;
+
+	err = gpio_request(SPITZ_GPIO_nSD_WP, "nSD_WP");
+	if (err)
+		goto err_free_1;
+
+	gpio_direction_input(SPITZ_GPIO_nSD_DETECT);
+	gpio_direction_input(SPITZ_GPIO_nSD_WP);
 
 	spitz_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 
 	err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int,
-			  IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+			  IRQF_DISABLED | IRQF_TRIGGER_RISING |
+			  IRQF_TRIGGER_FALLING,
 			  "MMC card detect", data);
-	if (err)
-		printk(KERN_ERR "spitz_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
+	if (err) {
+		pr_err("%s: MMC/SD: can't request MMC card detect IRQ\n",
+				__func__);
+		goto err_free_2;
+	}
+	return 0;
 
+err_free_2:
+	gpio_free(SPITZ_GPIO_nSD_WP);
+err_free_1:
+	gpio_free(SPITZ_GPIO_nSD_DETECT);
+err_out:
 	return err;
 }
 
@@ -397,12 +460,14 @@
 
 static int spitz_mci_get_ro(struct device *dev)
 {
-	return GPLR(SPITZ_GPIO_nSD_WP) & GPIO_bit(SPITZ_GPIO_nSD_WP);
+	return gpio_get_value(SPITZ_GPIO_nSD_WP);
 }
 
 static void spitz_mci_exit(struct device *dev, void *data)
 {
 	free_irq(SPITZ_IRQ_GPIO_nSD_DETECT, data);
+	gpio_free(SPITZ_GPIO_nSD_WP);
+	gpio_free(SPITZ_GPIO_nSD_DETECT);
 }
 
 static struct pxamci_platform_data spitz_mci_platform_data = {
@@ -419,27 +484,24 @@
  */
 static int spitz_ohci_init(struct device *dev)
 {
-	/* Only Port 2 is connected */
-	pxa_gpio_mode(SPITZ_GPIO_USB_CONNECT | GPIO_IN);
-	pxa_gpio_mode(SPITZ_GPIO_USB_HOST | GPIO_OUT);
-	pxa_gpio_mode(SPITZ_GPIO_USB_DEVICE | GPIO_IN);
+	int err;
 
-	/* Setup USB Port 2 Output Control Register */
+	err = gpio_request(SPITZ_GPIO_USB_HOST, "USB_HOST");
+	if (err)
+		return err;
+
+	/* Only Port 2 is connected
+	 * Setup USB Port 2 Output Control Register
+	 */
 	UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE;
 
-	GPSR(SPITZ_GPIO_USB_HOST) = GPIO_bit(SPITZ_GPIO_USB_HOST);
-
-	UHCHR = (UHCHR) &
-		~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
-
-	UHCRHDA |= UHCRHDA_NOCP;
-
-	return 0;
+	return gpio_direction_output(SPITZ_GPIO_USB_HOST, 1);
 }
 
 static struct pxaohci_platform_data spitz_ohci_platform_data = {
 	.port_mode	= PMM_NPS_MODE,
 	.init		= spitz_ohci_init,
+	.flags		= ENABLE_PORT_ALL | NO_OC_PROTECTION,
 	.power_budget	= 150,
 };
 
@@ -447,29 +509,50 @@
 /*
  * Irda
  */
+static int spitz_irda_startup(struct device *dev)
+{
+	int rc;
+
+	rc = gpio_request(SPITZ_GPIO_IR_ON, "IrDA on");
+	if (rc)
+		goto err;
+
+	rc = gpio_direction_output(SPITZ_GPIO_IR_ON, 1);
+	if (rc)
+		goto err_dir;
+
+	return 0;
+
+err_dir:
+	gpio_free(SPITZ_GPIO_IR_ON);
+err:
+	return rc;
+}
+
+static void spitz_irda_shutdown(struct device *dev)
+{
+	gpio_free(SPITZ_GPIO_IR_ON);
+}
+
 static void spitz_irda_transceiver_mode(struct device *dev, int mode)
 {
-	if (mode & IR_OFF)
-		set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON);
-	else
-		reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON);
+	gpio_set_value(SPITZ_GPIO_IR_ON, mode & IR_OFF);
 	pxa2xx_transceiver_mode(dev, mode);
 }
 
 #ifdef CONFIG_MACH_AKITA
 static void akita_irda_transceiver_mode(struct device *dev, int mode)
 {
-	if (mode & IR_OFF)
-		akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_IR_ON);
-	else
-		akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_IR_ON);
+	gpio_set_value(AKITA_GPIO_IR_ON, mode & IR_OFF);
 	pxa2xx_transceiver_mode(dev, mode);
 }
 #endif
 
 static struct pxaficp_platform_data spitz_ficp_platform_data = {
-	.transceiver_cap  = IR_SIRMODE | IR_OFF,
-	.transceiver_mode = spitz_irda_transceiver_mode,
+	.transceiver_cap	= IR_SIRMODE | IR_OFF,
+	.transceiver_mode	= spitz_irda_transceiver_mode,
+	.startup		= spitz_irda_startup,
+	.shutdown		= spitz_irda_shutdown,
 };
 
 
@@ -477,14 +560,6 @@
  * Spitz PXA Framebuffer
  */
 
-static void spitz_lcd_power(int on, struct fb_var_screeninfo *var)
-{
-	if (on)
-		corgi_lcdtg_hw_init(var->xres);
-	else
-		corgi_lcdtg_suspend();
-}
-
 static struct pxafb_mode_info spitz_pxafb_modes[] = {
 {
 	.pixclock       = 19231,
@@ -517,18 +592,13 @@
 	.modes          = &spitz_pxafb_modes[0],
 	.num_modes      = 2,
 	.fixed_modes    = 1,
-	.lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act | LCCR0_LDDALT | LCCR0_OUC | LCCR0_CMDIM | LCCR0_RDSTM,
-	.lccr3          = LCCR3_PixRsEdg | LCCR3_OutEnH,
-	.pxafb_lcd_power = spitz_lcd_power,
+	.lcd_conn	= LCD_COLOR_TFT_16BPP | LCD_ALTERNATE_MAPPING,
 };
 
 
 static struct platform_device *devices[] __initdata = {
 	&spitzscoop_device,
-	&spitzssp_device,
 	&spitzkbd_device,
-	&spitzts_device,
-	&spitzbl_device,
 	&spitzled_device,
 };
 
@@ -554,57 +624,26 @@
 
 	PMCR = 0x00;
 
-	/* setup sleep mode values */
-	PWER  = 0x00000002;
-	PFER  = 0x00000000;
-	PRER  = 0x00000002;
-	PGSR0 = 0x0158C000;
-	PGSR1 = 0x00FF0080;
-	PGSR2 = 0x0001C004;
-
 	/* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
 	PCFR |= PCFR_OPDE;
 
-	corgi_ssp_set_machinfo(&spitz_ssp_machinfo);
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(spitz_pin_config));
 
-	pxa_gpio_mode(SPITZ_GPIO_HSYNC | GPIO_IN);
+	spitz_init_spi();
 
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 	pxa_set_mci_info(&spitz_mci_platform_data);
 	pxa_set_ohci_info(&spitz_ohci_platform_data);
 	pxa_set_ficp_info(&spitz_ficp_platform_data);
-	set_pxa_fb_parent(&spitzssp_device.dev);
 	set_pxa_fb_info(&spitz_pxafb_info);
 	pxa_set_i2c_info(NULL);
 }
 
 #if defined(CONFIG_MACH_SPITZ) || defined(CONFIG_MACH_BORZOI)
-static void spitz_bl_set_intensity(int intensity)
-{
-	if (intensity > 0x10)
-		intensity += 0x10;
-
-	/* Bits 0-4 are accessed via the SSP interface */
-	corgi_ssp_blduty_set(intensity & 0x1f);
-
-	/* Bit 5 is via SCOOP */
-	if (intensity & 0x0020)
-		reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT);
-	else
-		set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT);
-
-	if (intensity)
-		set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON);
-	else
-		reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON);
-}
-
 static void __init spitz_init(void)
 {
 	platform_scoop_config = &spitz_pcmcia_config;
 
-	spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity;
-
 	common_init();
 
 	platform_device_register(&spitzscoop2_device);
@@ -615,32 +654,17 @@
 /*
  * Akita IO Expander
  */
-struct platform_device akitaioexp_device = {
-	.name		= "akita-ioexp",
-	.id		= -1,
+static struct pca953x_platform_data akita_ioexp = {
+	.gpio_base		= AKITA_IOEXP_GPIO_BASE,
 };
 
-EXPORT_SYMBOL_GPL(akitaioexp_device);
-
-static void akita_bl_set_intensity(int intensity)
-{
-	if (intensity > 0x10)
-		intensity += 0x10;
-
-	/* Bits 0-4 are accessed via the SSP interface */
-	corgi_ssp_blduty_set(intensity & 0x1f);
-
-	/* Bit 5 is via IO-Expander */
-	if (intensity & 0x0020)
-		akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT);
-	else
-		akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT);
-
-	if (intensity)
-		akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON);
-	else
-		akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON);
-}
+static struct i2c_board_info akita_i2c_board_info[] = {
+	{
+		.type		= "max7310",
+		.addr		= 0x18,
+		.platform_data	= &akita_ioexp,
+	},
+};
 
 static void __init akita_init(void)
 {
@@ -649,11 +673,10 @@
 	/* We just pretend the second element of the array doesn't exist */
 	spitz_pcmcia_config.num_devs = 1;
 	platform_scoop_config = &spitz_pcmcia_config;
-	spitz_bl_machinfo.set_bl_intensity = akita_bl_set_intensity;
 
-	platform_device_register(&akitaioexp_device);
+	pxa_set_i2c_info(NULL);
+	i2c_register_board_info(0, ARRAY_AND_SIZE(akita_i2c_board_info));
 
-	spitzscoop_device.dev.parent = &akitaioexp_device.dev;
 	common_init();
 }
 #endif
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
index 8a40505..53018db 100644
--- a/arch/arm/mach-pxa/spitz_pm.c
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -21,7 +21,6 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 #include <mach/hardware.h>
-#include <asm/hardware/scoop.h>
 
 #include <mach/sharpsl.h>
 #include <mach/spitz.h>
@@ -48,44 +47,35 @@
 
 static void spitz_measure_temp(int on)
 {
-	if (on)
-		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_ADC_TEMP_ON);
-	else
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_ADC_TEMP_ON);
+	gpio_set_value(SPITZ_GPIO_ADC_TEMP_ON, on);
 }
 
 static void spitz_charge(int on)
 {
 	if (on) {
 		if (sharpsl_pm.flags & SHARPSL_SUSPENDED) {
-			set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_B);
-			reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CHRG_ON);
+			gpio_set_value(SPITZ_GPIO_JK_B, 1);
+			gpio_set_value(SPITZ_GPIO_CHRG_ON, 0);
 		} else {
-			reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_B);
-			reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CHRG_ON);
+			gpio_set_value(SPITZ_GPIO_JK_B, 0);
+			gpio_set_value(SPITZ_GPIO_CHRG_ON, 0);
 		}
 	} else {
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_B);
-		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CHRG_ON);
+		gpio_set_value(SPITZ_GPIO_JK_B, 0);
+		gpio_set_value(SPITZ_GPIO_CHRG_ON, 1);
 	}
 }
 
 static void spitz_discharge(int on)
 {
-	if (on)
-		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_A);
-	else
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_A);
+	gpio_set_value(SPITZ_GPIO_JK_A, on);
 }
 
 /* HACK - For unknown reasons, accurate voltage readings are only made with a load
    on the power bus which the green led on spitz provides */
 static void spitz_discharge1(int on)
 {
-	if (on)
-		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN);
-	else
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN);
+	gpio_set_value(SPITZ_GPIO_LED_GREEN, on);
 }
 
 static void spitz_presuspend(void)
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
index 9bd93c5..2c31ec7 100644
--- a/arch/arm/mach-pxa/ssp.c
+++ b/arch/arm/mach-pxa/ssp.c
@@ -28,8 +28,8 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <mach/hardware.h>
 #include <mach/ssp.h>
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index 67e1850..18d1497 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -155,7 +155,7 @@
 	OIER = 0;
 	OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3;
 
-	if (cpu_is_pxa21x() || cpu_is_pxa25x())
+	if (cpu_is_pxa25x())
 		clock_tick_rate = 3686400;
 	else if (machine_is_mainstone())
 		clock_tick_rate = 3249600;
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 5dab30e..9f3ef9e 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -50,6 +50,7 @@
 #include <asm/mach/sharpsl_param.h>
 
 #include "generic.h"
+#include "clock.h"
 #include "devices.h"
 
 static unsigned long tosa_pin_config[] = {
@@ -521,6 +522,14 @@
 		.wakeup	= 1,
 		.active_low = 1,
 	},
+	{
+		.type	= EV_SW,
+		.code	= SW_HEADPHONE_INSERT,
+		.gpio	= TOSA_GPIO_EAR_IN,
+		.desc	= "HeadPhone insert",
+		.active_low = 1,
+		.debounce_interval = 300,
+	},
 };
 
 static struct gpio_keys_platform_data tosa_gpio_keys_platform_data = {
@@ -792,6 +801,8 @@
 	pxa_set_i2c_info(NULL);
 	platform_scoop_config = &tosa_pcmcia_config;
 
+	clk_add_alias("CLK_CK3P6MI", &tc6393xb_device.dev, "GPIO11_CLK", NULL);
+
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index 3ed757e..a13dbf3 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -22,8 +22,8 @@
 #include <linux/fb.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
-#include <linux/serial_8250.h>
-#include <linux/mtd/mtd.h>
+#include <linux/gpio.h>
+#include <linux/dm9000.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/partitions.h>
 
@@ -31,7 +31,6 @@
 #include <asm/setup.h>
 #include <asm/memory.h>
 #include <asm/mach-types.h>
-#include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/sizes.h>
 
@@ -40,41 +39,148 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/flash.h>
 
+#include <mach/hardware.h>
 #include <mach/pxa-regs.h>
 #include <mach/pxa2xx-regs.h>
-#include <mach/pxa2xx-gpio.h>
+#include <mach/mfp-pxa27x.h>
+#include <mach/pxa2xx_spi.h>
 #include <mach/trizeps4.h>
 #include <mach/audio.h>
 #include <mach/pxafb.h>
 #include <mach/mmc.h>
 #include <mach/irda.h>
 #include <mach/ohci.h>
+#include <mach/i2c.h>
 
 #include "generic.h"
 #include "devices.h"
 
-/********************************************************************************************
+/*	comment out the following line if you want to use the
+ *	Standard UART from PXA for serial / irda transmission
+ *	and acivate it if you have status leds connected */
+#define STATUS_LEDS_ON_STUART_PINS 1
+
+/*****************************************************************************
+ * MultiFunctionPins of CPU
+ *****************************************************************************/
+static unsigned long trizeps4_pin_config[] __initdata = {
+	/* Chip Selects */
+	GPIO15_nCS_1,		/* DiskOnChip CS */
+	GPIO93_GPIO,		/* TRIZEPS4_DOC_IRQ */
+	GPIO94_GPIO,		/* DOC lock */
+
+	GPIO78_nCS_2,		/* DM9000 CS */
+	GPIO101_GPIO,		/* TRIZEPS4_ETH_IRQ */
+
+	GPIO79_nCS_3,		/* Logic CS */
+	GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,	/* Logic irq */
+
+	/* LCD - 16bpp Active TFT */
+	GPIO58_LCD_LDD_0,
+	GPIO59_LCD_LDD_1,
+	GPIO60_LCD_LDD_2,
+	GPIO61_LCD_LDD_3,
+	GPIO62_LCD_LDD_4,
+	GPIO63_LCD_LDD_5,
+	GPIO64_LCD_LDD_6,
+	GPIO65_LCD_LDD_7,
+	GPIO66_LCD_LDD_8,
+	GPIO67_LCD_LDD_9,
+	GPIO68_LCD_LDD_10,
+	GPIO69_LCD_LDD_11,
+	GPIO70_LCD_LDD_12,
+	GPIO71_LCD_LDD_13,
+	GPIO72_LCD_LDD_14,
+	GPIO73_LCD_LDD_15,
+	GPIO74_LCD_FCLK,
+	GPIO75_LCD_LCLK,
+	GPIO76_LCD_PCLK,
+	GPIO77_LCD_BIAS,
+
+	/* UART */
+	GPIO9_FFUART_CTS,
+	GPIO10_FFUART_DCD,
+	GPIO16_FFUART_TXD,
+	GPIO33_FFUART_DSR,
+	GPIO38_FFUART_RI,
+	GPIO82_FFUART_DTR,
+	GPIO83_FFUART_RTS,
+	GPIO96_FFUART_RXD,
+
+	GPIO42_BTUART_RXD,
+	GPIO43_BTUART_TXD,
+	GPIO44_BTUART_CTS,
+	GPIO45_BTUART_RTS,
+#ifdef STATUS_LEDS_ON_STUART_PINS
+	GPIO46_GPIO,
+	GPIO47_GPIO,
+#else
+	GPIO46_STUART_RXD,
+	GPIO47_STUART_TXD,
+#endif
+	/* PCMCIA */
+	GPIO11_GPIO,			/* TRIZEPS4_CD_IRQ */
+	GPIO13_GPIO,			/* TRIZEPS4_READY_NINT */
+	GPIO48_nPOE,
+	GPIO49_nPWE,
+	GPIO50_nPIOR,
+	GPIO51_nPIOW,
+	GPIO54_nPCE_2,
+	GPIO55_nPREG,
+	GPIO56_nPWAIT,
+	GPIO57_nIOIS16,
+	GPIO102_nPCE_1,
+	GPIO104_PSKTSEL,
+
+	/* MultiMediaCard */
+	GPIO32_MMC_CLK,
+	GPIO92_MMC_DAT_0,
+	GPIO109_MMC_DAT_1,
+	GPIO110_MMC_DAT_2,
+	GPIO111_MMC_DAT_3,
+	GPIO112_MMC_CMD,
+	GPIO12_GPIO,			/* TRIZEPS4_MMC_IRQ */
+
+	/* USB OHCI */
+	GPIO88_USBH1_PWR,		/* USBHPWR1 */
+	GPIO89_USBH1_PEN,		/* USBHPEN1 */
+
+	/* I2C */
+	GPIO117_I2C_SCL,
+	GPIO118_I2C_SDA,
+};
+
+static unsigned long trizeps4wl_pin_config[] __initdata = {
+	/* SSP 2 */
+	GPIO14_SSP2_SFRM,
+	GPIO19_SSP2_SCLK,
+	GPIO53_GPIO,			/* TRIZEPS4_SPI_IRQ */
+	GPIO86_SSP2_RXD,
+	GPIO87_SSP2_TXD,
+};
+
+/****************************************************************************
  * ONBOARD FLASH
- ********************************************************************************************/
+ ****************************************************************************/
 static struct mtd_partition trizeps4_partitions[] = {
 	{
 		.name =		"Bootloader",
 		.offset =	0x00000000,
 		.size =		0x00040000,
 		.mask_flags =	MTD_WRITEABLE  /* force read-only */
-	},{
+	}, {
 		.name =		"Backup",
 		.offset =	0x00040000,
 		.size =		0x00040000,
-	},{
+	}, {
 		.name =		"Image",
 		.offset =	0x00080000,
 		.size =		0x01080000,
-	},{
+	}, {
 		.name =		"IPSM",
 		.offset =	0x01100000,
 		.size =		0x00e00000,
-	},{
+	}, {
 		.name =		"Registry",
 		.offset =	0x01f00000,
 		.size =		MTDPART_SIZ_FULL,
@@ -105,9 +211,9 @@
 	.num_resources = 1,
 };
 
-/********************************************************************************************
+/****************************************************************************
  * DAVICOM DM9000 Ethernet
- ********************************************************************************************/
+ ****************************************************************************/
 static struct resource dm9000_resources[] = {
 	[0] = {
 		.start	= TRIZEPS4_ETH_PHYS+0x300,
@@ -122,67 +228,68 @@
 	[2] = {
 		.start	= TRIZEPS4_ETH_IRQ,
 		.end	= TRIZEPS4_ETH_IRQ,
-		.flags	= (IORESOURCE_IRQ | IRQ_TYPE_EDGE_RISING),
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 	},
 };
 
+static struct dm9000_plat_data tri_dm9000_platdata = {
+	.flags		= DM9000_PLATF_32BITONLY,
+};
+
 static struct platform_device dm9000_device = {
 	.name		= "dm9000",
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(dm9000_resources),
 	.resource	= dm9000_resources,
+	.dev		= {
+		.platform_data = &tri_dm9000_platdata,
+	}
 };
 
-/********************************************************************************************
- * PXA270 serial ports
- ********************************************************************************************/
-static struct plat_serial8250_port tri_serial_ports[] = {
-#ifdef CONFIG_SERIAL_PXA
-	/* this uses the own PXA driver */
+/****************************************************************************
+ * LED's on GPIO pins of PXA
+ ****************************************************************************/
+static struct gpio_led trizeps4_led[] = {
+#ifdef STATUS_LEDS_ON_STUART_PINS
 	{
-		0,
-	},
-#else
-	/* this uses the generic 8520 driver */
-	[0] = {
-		.membase	= (void *)&FFUART,
-		.irq		= IRQ_FFUART,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.iotype		= UPIO_MEM32,
-		.regshift	= 2,
-		.uartclk	= (921600*16),
-	},
-	[1] = {
-		.membase	= (void *)&BTUART,
-		.irq		= IRQ_BTUART,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.iotype		= UPIO_MEM32,
-		.regshift	= 2,
-		.uartclk	= (921600*16),
+		.name = "led0:orange:heartbeat",	/* */
+		.default_trigger = "heartbeat",
+		.gpio = GPIO_HEARTBEAT_LED,
+		.active_low = 1,
 	},
 	{
-		0,
+		.name = "led1:yellow:cpubusy",		/* */
+		.default_trigger = "cpu-busy",
+		.gpio = GPIO_SYS_BUSY_LED,
+		.active_low = 1,
 	},
 #endif
 };
 
-static struct platform_device uart_devices = {
-	.name		= "serial8250",
-	.id		= 0,
+static struct gpio_led_platform_data trizeps4_led_data = {
+	.leds		= trizeps4_led,
+	.num_leds	= ARRAY_SIZE(trizeps4_led),
+};
+
+static struct platform_device leds_devices = {
+	.name		= "leds-gpio",
+	.id		= -1,
 	.dev		= {
-		.platform_data	= tri_serial_ports,
+		.platform_data	= &trizeps4_led_data,
 	},
-	.num_resources	= 0,
-	.resource	= NULL,
 };
 
-static struct platform_device * trizeps4_devices[] __initdata = {
+static struct platform_device *trizeps4_devices[] __initdata = {
 	&flash_device,
-	&uart_devices,
 	&dm9000_device,
+	&leds_devices,
 };
 
-#ifdef CONFIG_MACH_TRIZEPS4_CONXS
+static struct platform_device *trizeps4wl_devices[] __initdata = {
+	&flash_device,
+	&leds_devices,
+};
+
 static short trizeps_conxs_bcr;
 
 /* PCCARD power switching supports only 3,3V */
@@ -192,108 +299,63 @@
 		/* switch power on, put in reset and enable buffers */
 		trizeps_conxs_bcr |= power;
 		trizeps_conxs_bcr |= ConXS_BCR_CF_RESET;
-		trizeps_conxs_bcr &= ~(ConXS_BCR_CF_BUF_EN);
-		ConXS_BCR = trizeps_conxs_bcr;
+		trizeps_conxs_bcr &= ~ConXS_BCR_CF_BUF_EN;
+		BCR_writew(trizeps_conxs_bcr);
 		/* wait a little */
 		udelay(2000);
 		/* take reset away */
-		trizeps_conxs_bcr &= ~(ConXS_BCR_CF_RESET);
-		ConXS_BCR = trizeps_conxs_bcr;
+		trizeps_conxs_bcr &= ~ConXS_BCR_CF_RESET;
+		BCR_writew(trizeps_conxs_bcr);
 		udelay(2000);
 	} else {
 		/* put in reset */
 		trizeps_conxs_bcr |= ConXS_BCR_CF_RESET;
-		ConXS_BCR = trizeps_conxs_bcr;
+		BCR_writew(trizeps_conxs_bcr);
 		udelay(1000);
 		/* switch power off */
-		trizeps_conxs_bcr &= ~(0xf);
-		ConXS_BCR = trizeps_conxs_bcr;
-
+		trizeps_conxs_bcr &= ~0xf;
+		BCR_writew(trizeps_conxs_bcr);
 	}
-	pr_debug("%s: o%s 0x%x\n", __func__, power ? "n": "ff", trizeps_conxs_bcr);
+	pr_debug("%s: o%s 0x%x\n", __func__, power ? "n" : "ff",
+			trizeps_conxs_bcr);
 }
+EXPORT_SYMBOL(board_pcmcia_power);
 
 /* backlight power switching for LCD panel */
 static void board_backlight_power(int on)
 {
-	if (on) {
+	if (on)
 		trizeps_conxs_bcr |= ConXS_BCR_L_DISP;
-	} else {
+	else
 		trizeps_conxs_bcr &= ~ConXS_BCR_L_DISP;
-	}
-	pr_debug("%s: o%s 0x%x\n", __func__, on ? "n" : "ff", trizeps_conxs_bcr);
-	ConXS_BCR = trizeps_conxs_bcr;
+
+	pr_debug("%s: o%s 0x%x\n", __func__, on ? "n" : "ff",
+			trizeps_conxs_bcr);
+	BCR_writew(trizeps_conxs_bcr);
 }
 
-/* Powersupply for MMC/SD cardslot */
-static void board_mci_power(struct device *dev, unsigned int vdd)
-{
-	struct pxamci_platform_data* p_d = dev->platform_data;
+/* a I2C based RTC is known on CONXS board */
+static struct i2c_board_info trizeps4_i2c_devices[] __initdata = {
+	{ I2C_BOARD_INFO("rtc-pcf8593", 0x51) }
+};
 
-	if (( 1 << vdd) & p_d->ocr_mask) {
-		pr_debug("%s: on\n", __func__);
-		/* FIXME fill in values here */
-	} else {
-		pr_debug("%s: off\n", __func__);
-		/* FIXME fill in values here */
-	}
-}
-
-static short trizeps_conxs_ircr;
-
-/* Switch modes and Power for IRDA receiver */
-static void board_irda_mode(struct device *dev, int mode)
-{
-	unsigned long flags;
-
-	local_irq_save(flags);
-	if (mode & IR_SIRMODE) {
-		/* Slow mode */
-		trizeps_conxs_ircr &= ~ConXS_IRCR_MODE;
-	} else if (mode & IR_FIRMODE) {
-		/* Fast mode */
-		trizeps_conxs_ircr |= ConXS_IRCR_MODE;
-	}
-	pxa2xx_transceiver_mode(dev, mode);
-	if (mode & IR_OFF) {
-		trizeps_conxs_ircr |= ConXS_IRCR_SD;
-	} else {
-		trizeps_conxs_ircr &= ~ConXS_IRCR_SD;
-	}
-	/* FIXME write values to register */
-	local_irq_restore(flags);
-}
-
-#else
-/* for other baseboards define dummies */
-void board_pcmcia_power(int power)	{;}
-#define board_backlight_power		NULL
-#define board_mci_power			NULL
-#define board_irda_mode			NULL
-
-#endif		/* CONFIG_MACH_TRIZEPS4_CONXS */
-EXPORT_SYMBOL(board_pcmcia_power);
-
-static int trizeps4_mci_init(struct device *dev, irq_handler_t mci_detect_int, void *data)
+/****************************************************************************
+ * MMC card slot external to module
+ ****************************************************************************/
+static int trizeps4_mci_init(struct device *dev, irq_handler_t mci_detect_int,
+		void *data)
 {
 	int err;
-	/* setup GPIO for PXA27x MMC controller */
-	pxa_gpio_mode(GPIO32_MMCCLK_MD);
-	pxa_gpio_mode(GPIO112_MMCCMD_MD);
-	pxa_gpio_mode(GPIO92_MMCDAT0_MD);
-	pxa_gpio_mode(GPIO109_MMCDAT1_MD);
-	pxa_gpio_mode(GPIO110_MMCDAT2_MD);
-	pxa_gpio_mode(GPIO111_MMCDAT3_MD);
-
-	pxa_gpio_mode(GPIO_MMC_DET | GPIO_IN);
 
 	err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int,
-			  IRQF_DISABLED | IRQF_TRIGGER_RISING,
-			  "MMC card detect", data);
-	if (err)
-		printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
-
-	return err;
+		IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_SAMPLE_RANDOM,
+		"MMC card detect", data);
+	if (err) {
+		printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request"
+						"MMC card detect IRQ\n");
+		return -1;
+	}
+	return 0;
 }
 
 static void trizeps4_mci_exit(struct device *dev, void *data)
@@ -303,39 +365,69 @@
 
 static struct pxamci_platform_data trizeps4_mci_platform_data = {
 	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.detect_delay	= 1,
 	.init 		= trizeps4_mci_init,
 	.exit		= trizeps4_mci_exit,
-	.setpower 	= board_mci_power,
+	.get_ro		= NULL,	/* write-protection not supported */
+	.setpower 	= NULL,	/* power-switching not supported */
 };
 
-static struct pxaficp_platform_data trizeps4_ficp_platform_data = {
-	.transceiver_cap  = IR_SIRMODE | IR_FIRMODE | IR_OFF,
-	.transceiver_mode = board_irda_mode,
-};
+/****************************************************************************
+ * IRDA mode switching on stuart
+ ****************************************************************************/
+#ifndef STATUS_LEDS_ON_STUART_PINS
+static short trizeps_conxs_ircr;
 
-static int trizeps4_ohci_init(struct device *dev)
+static int trizeps4_irda_startup(struct device *dev)
 {
-	/* setup Port1 GPIO pin. */
-	pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN);	/* USBHPWR1 */
-	pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT);	/* USBHPEN1 */
-
-	/* Set the Power Control Polarity Low and Power Sense
-	   Polarity Low to active low. */
-	UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
-		~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
-
+	trizeps_conxs_ircr &= ~ConXS_IRCR_SD;
+	IRCR_writew(trizeps_conxs_ircr);
 	return 0;
 }
 
-static void trizeps4_ohci_exit(struct device *dev)
+static void trizeps4_irda_shutdown(struct device *dev)
 {
-	;
+	trizeps_conxs_ircr |= ConXS_IRCR_SD;
+	IRCR_writew(trizeps_conxs_ircr);
 }
 
+static void trizeps4_irda_transceiver_mode(struct device *dev, int mode)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	/* Switch mode */
+	if (mode & IR_SIRMODE)
+		trizeps_conxs_ircr &= ~ConXS_IRCR_MODE;	/* Slow mode */
+	else if (mode & IR_FIRMODE) {
+		trizeps_conxs_ircr |= ConXS_IRCR_MODE;	/* Fast mode */
+
+	/* Switch power */
+	if (mode & IR_OFF)
+		trizeps_conxs_ircr |= ConXS_IRCR_SD;
+	else
+		trizeps_conxs_ircr &= ~ConXS_IRCR_SD;
+
+	IRCR_writew(trizeps_conxs_ircr);
+	local_irq_restore(flags);
+
+	pxa2xx_transceiver_mode(dev, mode);
+}
+
+static struct pxaficp_platform_data trizeps4_ficp_platform_data = {
+	.transceiver_cap	= IR_SIRMODE | IR_FIRMODE | IR_OFF,
+	.transceiver_mode	= trizeps4_irda_transceiver_mode,
+	.startup		= trizeps4_irda_startup,
+	.shutdown		= trizeps4_irda_shutdown,
+};
+#endif
+
+/****************************************************************************
+ * OHCI USB port
+ ****************************************************************************/
 static struct pxaohci_platform_data trizeps4_ohci_platform_data = {
 	.port_mode	= PMM_PERPORT_MODE,
-	.init		= trizeps4_ohci_init,
-	.exit		= trizeps4_ohci_exit,
+	.flags		= ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
 };
 
 static struct map_desc trizeps4_io_desc[] __initdata = {
@@ -372,105 +464,80 @@
 };
 
 static struct pxafb_mode_info sharp_lcd_mode = {
-    .pixclock		= 78000,
-    .xres		= 640,
-    .yres		= 480,
-    .bpp		= 8,
-    .hsync_len		= 4,
-    .left_margin	= 4,
-    .right_margin	= 4,
-    .vsync_len		= 2,
-    .upper_margin	= 0,
-    .lower_margin	= 0,
-    .sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-    .cmap_greyscale	= 0,
+	.pixclock	= 78000,
+	.xres		= 640,
+	.yres		= 480,
+	.bpp		= 8,
+	.hsync_len	= 4,
+	.left_margin	= 4,
+	.right_margin	= 4,
+	.vsync_len	= 2,
+	.upper_margin	= 0,
+	.lower_margin	= 0,
+	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	.cmap_greyscale	= 0,
 };
 
 static struct pxafb_mach_info sharp_lcd = {
-    .modes		= &sharp_lcd_mode,
-    .num_modes	= 1,
-    .cmap_inverse	= 0,
-    .cmap_static	= 0,
-    .lccr0		= LCCR0_Color | LCCR0_Pas | LCCR0_Dual,
-    .lccr3		= 0x0340ff02,
-    .pxafb_backlight_power = board_backlight_power,
+	.modes		= &sharp_lcd_mode,
+	.num_modes	= 1,
+	.lcd_conn	= LCD_COLOR_DSTN_16BPP | LCD_PCLK_EDGE_FALL,
+	.cmap_inverse	= 0,
+	.cmap_static	= 0,
+	.pxafb_backlight_power = board_backlight_power,
 };
 
 static struct pxafb_mode_info toshiba_lcd_mode = {
-    .pixclock		= 39720,
-    .xres		= 640,
-    .yres		= 480,
-    .bpp		= 8,
-    .hsync_len		= 63,
-    .left_margin	= 12,
-    .right_margin	= 12,
-    .vsync_len		= 4,
-    .upper_margin	= 32,
-    .lower_margin	= 10,
-    .sync		= 0,
-    .cmap_greyscale	= 0,
+	.pixclock	= 39720,
+	.xres		= 640,
+	.yres		= 480,
+	.bpp		= 8,
+	.hsync_len	= 63,
+	.left_margin	= 12,
+	.right_margin	= 12,
+	.vsync_len	= 4,
+	.upper_margin	= 32,
+	.lower_margin	= 10,
+	.sync		= 0,
+	.cmap_greyscale	= 0,
 };
 
 static struct pxafb_mach_info toshiba_lcd = {
-    .modes		= &toshiba_lcd_mode,
-    .num_modes	= 1,
-    .cmap_inverse	= 0,
-    .cmap_static	= 0,
-    .lccr0		= LCCR0_Color | LCCR0_Act,
-    .lccr3		= 0x03400002,
-    .pxafb_backlight_power = board_backlight_power,
+	.modes		= &toshiba_lcd_mode,
+	.num_modes	= 1,
+	.lcd_conn	= (LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL),
+	.cmap_inverse	= 0,
+	.cmap_static	= 0,
+	.pxafb_backlight_power = board_backlight_power,
 };
 
 static void __init trizeps4_init(void)
 {
-	platform_add_devices(trizeps4_devices, ARRAY_SIZE(trizeps4_devices));
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(trizeps4_pin_config));
+	if (machine_is_trizeps4wl()) {
+		pxa2xx_mfp_config(ARRAY_AND_SIZE(trizeps4wl_pin_config));
+		platform_add_devices(trizeps4wl_devices,
+					ARRAY_SIZE(trizeps4wl_devices));
+	} else {
+		platform_add_devices(trizeps4_devices,
+					ARRAY_SIZE(trizeps4_devices));
+	}
 
-/*	set_pxa_fb_info(&sharp_lcd); */
-	set_pxa_fb_info(&toshiba_lcd);
+	if (0)	/* dont know how to determine LCD */
+		set_pxa_fb_info(&sharp_lcd);
+	else
+		set_pxa_fb_info(&toshiba_lcd);
 
 	pxa_set_mci_info(&trizeps4_mci_platform_data);
+#ifndef STATUS_LEDS_ON_STUART_PINS
 	pxa_set_ficp_info(&trizeps4_ficp_platform_data);
+#endif
 	pxa_set_ohci_info(&trizeps4_ohci_platform_data);
 	pxa_set_ac97_info(NULL);
-}
+	pxa_set_i2c_info(NULL);
+	i2c_register_board_info(0, trizeps4_i2c_devices,
+					ARRAY_SIZE(trizeps4_i2c_devices));
 
-static void __init trizeps4_map_io(void)
-{
-	pxa_map_io();
-	iotable_init(trizeps4_io_desc, ARRAY_SIZE(trizeps4_io_desc));
-
-	/* for DiskOnChip */
-	pxa_gpio_mode(GPIO15_nCS_1_MD);
-
-	/* for off-module PIC on ConXS board */
-	pxa_gpio_mode(GPIO_PIC | GPIO_IN);
-
-	/* UCB1400 irq */
-	pxa_gpio_mode(GPIO_UCB1400 | GPIO_IN);
-
-	/* for DM9000 LAN */
-	pxa_gpio_mode(GPIO78_nCS_2_MD);
-	pxa_gpio_mode(GPIO_DM9000 | GPIO_IN);
-
-	/* for PCMCIA device */
-	pxa_gpio_mode(GPIO_PCD | GPIO_IN);
-	pxa_gpio_mode(GPIO_PRDY | GPIO_IN);
-
-	/* for I2C adapter */
-	pxa_gpio_mode(GPIO117_I2CSCL_MD);
-	pxa_gpio_mode(GPIO118_I2CSDA_MD);
-
-	/* MMC_DET s.o. */
-	pxa_gpio_mode(GPIO_MMC_DET | GPIO_IN);
-
-	/* whats that for ??? */
-	pxa_gpio_mode(GPIO79_nCS_3_MD);
-
-#ifdef CONFIG_LEDS
-	pxa_gpio_mode( GPIO_SYS_BUSY_LED  | GPIO_OUT);		/* LED1 */
-	pxa_gpio_mode( GPIO_HEARTBEAT_LED | GPIO_OUT);		/* LED2 */
-#endif
-#ifdef CONFIG_MACH_TRIZEPS4_CONXS
 #ifdef CONFIG_IDE_PXA_CF
 	/* if boot direct from compact flash dont disable power */
 	trizeps_conxs_bcr = 0x0009;
@@ -478,18 +545,24 @@
 	/* this is the reset value */
 	trizeps_conxs_bcr = 0x00A0;
 #endif
-	ConXS_BCR = trizeps_conxs_bcr;
-#endif
+	BCR_writew(trizeps_conxs_bcr);
+	board_backlight_power(1);
+}
 
-#warning FIXME - accessing PM registers directly is deprecated
-	PWER  = 0x00000002;
-	PFER  = 0x00000000;
-	PRER  = 0x00000002;
-	PGSR0 = 0x0158C000;
-	PGSR1 = 0x00FF0080;
-	PGSR2 = 0x0001C004;
-	/* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
-	PCFR |= PCFR_OPDE;
+static void __init trizeps4_map_io(void)
+{
+	pxa_map_io();
+	iotable_init(trizeps4_io_desc, ARRAY_SIZE(trizeps4_io_desc));
+
+	if ((MSC0 & 0x8) && (BOOT_DEF & 0x1)) {
+		/* if flash is 16 bit wide its a Trizeps4 WL */
+		__machine_arch_type = MACH_TYPE_TRIZEPS4WL;
+		trizeps4_flash_data[0].width = 2;
+	} else {
+		/* if flash is 32 bit wide its a Trizeps4 */
+		__machine_arch_type = MACH_TYPE_TRIZEPS4;
+		trizeps4_flash_data[0].width = 4;
+	}
 }
 
 MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module")
@@ -503,3 +576,13 @@
 	.timer		= &pxa_timer,
 MACHINE_END
 
+MACHINE_START(TRIZEPS4WL, "Keith und Koep Trizeps IV-WL module")
+	/* MAINTAINER("Jürgen Schindele") */
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= TRIZEPS4_SDRAM_BASE + 0x100,
+	.init_machine	= trizeps4_init,
+	.map_io		= trizeps4_map_io,
+	.init_irq	= pxa27x_init_irq,
+	.timer		= &pxa_timer,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
new file mode 100644
index 0000000..d7632f6
--- /dev/null
+++ b/arch/arm/mach-pxa/viper.c
@@ -0,0 +1,951 @@
+/*
+ *  linux/arch/arm/mach-pxa/viper.c
+ *
+ *  Support for the Arcom VIPER SBC.
+ *
+ *  Author:	Ian Campbell
+ *  Created:    Feb 03, 2003
+ *  Copyright:  Arcom Control Systems
+ *
+ *  Maintained by Marc Zyngier <maz@misterjones.org>
+ *                             <marc.zyngier@altran.com>
+ *
+ * Based on lubbock.c:
+ *  Author:	Nicolas Pitre
+ *  Created:	Jun 15, 2001
+ *  Copyright:	MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <linux/memory.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/major.h>
+#include <linux/module.h>
+#include <linux/pm.h>
+#include <linux/sched.h>
+#include <linux/gpio.h>
+#include <linux/i2c-gpio.h>
+#include <linux/serial_8250.h>
+#include <linux/smc91x.h>
+#include <linux/pwm_backlight.h>
+#include <linux/usb/isp116x.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+
+#include <mach/pxa-regs.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/bitfield.h>
+#include <mach/audio.h>
+#include <mach/pxafb.h>
+#include <mach/mfp-pxa25x.h>
+#include <mach/i2c.h>
+#include <mach/viper.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include "generic.h"
+#include "devices.h"
+
+static unsigned int icr;
+
+static void viper_icr_set_bit(unsigned int bit)
+{
+	icr |= bit;
+	VIPER_ICR = icr;
+}
+
+static void viper_icr_clear_bit(unsigned int bit)
+{
+	icr &= ~bit;
+	VIPER_ICR = icr;
+}
+
+/* This function is used from the pcmcia module to reset the CF */
+void viper_cf_rst(int state)
+{
+	if (state)
+		viper_icr_set_bit(VIPER_ICR_CF_RST);
+	else
+		viper_icr_clear_bit(VIPER_ICR_CF_RST);
+}
+EXPORT_SYMBOL(viper_cf_rst);
+
+/*
+ * The CPLD version register was not present on VIPER boards prior to
+ * v2i1. On v1 boards where the version register is not present we
+ * will just read back the previous value from the databus.
+ *
+ * Therefore we do two reads. The first time we write 0 to the
+ * (read-only) register before reading and the second time we write
+ * 0xff first. If the two reads do not match or they read back as 0xff
+ * or 0x00 then we have version 1 hardware.
+ */
+static u8 viper_hw_version(void)
+{
+	u8 v1, v2;
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	VIPER_VERSION = 0;
+	v1 = VIPER_VERSION;
+	VIPER_VERSION = 0xff;
+	v2 = VIPER_VERSION;
+
+	v1 = (v1 != v2 || v1 == 0xff) ? 0 : v1;
+
+	local_irq_restore(flags);
+	return v1;
+}
+
+/* CPU sysdev */
+static int viper_cpu_suspend(struct sys_device *sysdev, pm_message_t state)
+{
+	viper_icr_set_bit(VIPER_ICR_R_DIS);
+	return 0;
+}
+
+static int viper_cpu_resume(struct sys_device *sysdev)
+{
+	viper_icr_clear_bit(VIPER_ICR_R_DIS);
+	return 0;
+}
+
+static struct sysdev_driver viper_cpu_sysdev_driver = {
+	.suspend	= viper_cpu_suspend,
+	.resume		= viper_cpu_resume,
+};
+
+static unsigned int current_voltage_divisor;
+
+/*
+ * If force is not true then step from existing to new divisor. If
+ * force is true then jump straight to the new divisor. Stepping is
+ * used because if the jump in voltage is too large, the VCC can dip
+ * too low and the regulator cuts out.
+ *
+ * force can be used to initialize the divisor to a know state by
+ * setting the value for the current clock speed, since we are already
+ * running at that speed we know the voltage should be pretty close so
+ * the jump won't be too large
+ */
+static void viper_set_core_cpu_voltage(unsigned long khz, int force)
+{
+	int i = 0;
+	unsigned int divisor = 0;
+	const char *v;
+
+	if (khz < 200000) {
+		v = "1.0"; divisor = 0xfff;
+	} else if (khz < 300000) {
+		v = "1.1"; divisor = 0xde5;
+	} else {
+		v = "1.3"; divisor = 0x325;
+	}
+
+	pr_debug("viper: setting CPU core voltage to %sV at %d.%03dMHz\n",
+		 v, (int)khz / 1000, (int)khz % 1000);
+
+#define STEP 0x100
+	do {
+		int step;
+
+		if (force)
+			step = divisor;
+		else if (current_voltage_divisor < divisor - STEP)
+			step = current_voltage_divisor + STEP;
+		else if (current_voltage_divisor > divisor + STEP)
+			step = current_voltage_divisor - STEP;
+		else
+			step = divisor;
+		force = 0;
+
+		gpio_set_value(VIPER_PSU_CLK_GPIO, 0);
+		gpio_set_value(VIPER_PSU_nCS_LD_GPIO, 0);
+
+		for (i = 1 << 11 ; i > 0 ; i >>= 1) {
+			udelay(1);
+
+			gpio_set_value(VIPER_PSU_DATA_GPIO, step & i);
+			udelay(1);
+
+			gpio_set_value(VIPER_PSU_CLK_GPIO, 1);
+			udelay(1);
+
+			gpio_set_value(VIPER_PSU_CLK_GPIO, 0);
+		}
+		udelay(1);
+
+		gpio_set_value(VIPER_PSU_nCS_LD_GPIO, 1);
+		udelay(1);
+
+		gpio_set_value(VIPER_PSU_nCS_LD_GPIO, 0);
+
+		current_voltage_divisor = step;
+	} while (current_voltage_divisor != divisor);
+}
+
+/* Interrupt handling */
+static unsigned long viper_irq_enabled_mask;
+
+static void viper_ack_irq(unsigned int irq)
+{
+	int viper_irq = irq - PXA_ISA_IRQ(0);
+
+	if (viper_irq < 8)
+		VIPER_LO_IRQ_STATUS = 1 << viper_irq;
+	else
+		VIPER_HI_IRQ_STATUS = 1 << (viper_irq - 8);
+}
+
+static void viper_mask_irq(unsigned int irq)
+{
+	viper_irq_enabled_mask &= ~(1 << (irq - PXA_ISA_IRQ(0)));
+}
+
+static void viper_unmask_irq(unsigned int irq)
+{
+	viper_irq_enabled_mask |= (1 << (irq - PXA_ISA_IRQ(0)));
+}
+
+static inline unsigned long viper_irq_pending(void)
+{
+	return (VIPER_HI_IRQ_STATUS << 8 | VIPER_LO_IRQ_STATUS) &
+			viper_irq_enabled_mask;
+}
+
+static void viper_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	unsigned long pending;
+
+	pending = viper_irq_pending();
+	do {
+		if (likely(pending)) {
+			irq = PXA_ISA_IRQ(0) + __ffs(pending);
+			generic_handle_irq(irq);
+		}
+		pending = viper_irq_pending();
+	} while (pending);
+}
+
+static struct irq_chip viper_irq_chip = {
+	.name	= "ISA",
+	.ack	= viper_ack_irq,
+	.mask	= viper_mask_irq,
+	.unmask	= viper_unmask_irq
+};
+
+static void __init viper_init_irq(void)
+{
+	const int isa_irqs[] = { 3, 4, 5, 6, 7, 10, 11, 12, 9, 14, 15 };
+	int irq;
+	int isa_irq;
+
+	pxa25x_init_irq();
+
+	/* setup ISA IRQs */
+	for (irq = 0; irq < ARRAY_SIZE(isa_irqs); irq++) {
+		isa_irq = isa_irqs[irq];
+		set_irq_chip(isa_irq, &viper_irq_chip);
+		set_irq_handler(isa_irq, handle_edge_irq);
+		set_irq_flags(isa_irq, IRQF_VALID | IRQF_PROBE);
+	}
+
+	set_irq_chained_handler(gpio_to_irq(VIPER_CPLD_GPIO),
+				viper_irq_handler);
+	set_irq_type(gpio_to_irq(VIPER_CPLD_GPIO), IRQ_TYPE_EDGE_BOTH);
+
+#ifndef CONFIG_SERIAL_PXA
+	/*
+	 * 8250 doesn't support IRQ_TYPE being passed as part
+	 * of the plat_serial8250_port structure...
+	 */
+	set_irq_type(gpio_to_irq(VIPER_UARTA_GPIO), IRQ_TYPE_EDGE_RISING);
+	set_irq_type(gpio_to_irq(VIPER_UARTB_GPIO), IRQ_TYPE_EDGE_RISING);
+#endif
+}
+
+/* Flat Panel */
+static struct pxafb_mode_info fb_mode_info[] = {
+	{
+		.pixclock	= 157500,
+
+		.xres		= 320,
+		.yres		= 240,
+
+		.bpp		= 16,
+
+		.hsync_len	= 63,
+		.left_margin	= 7,
+		.right_margin	= 13,
+
+		.vsync_len	= 20,
+		.upper_margin	= 0,
+		.lower_margin	= 0,
+
+		.sync		= 0,
+	},
+};
+
+static struct pxafb_mach_info fb_info = {
+	.modes			= fb_mode_info,
+	.num_modes		= 1,
+	.lcd_conn		= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+static int viper_backlight_init(struct device *dev)
+{
+	int ret;
+
+	/* GPIO9 and 10 control FB backlight. Initialise to off */
+	ret = gpio_request(VIPER_BCKLIGHT_EN_GPIO, "Backlight");
+	if (ret)
+		goto err_request_bckl;
+
+	ret = gpio_request(VIPER_LCD_EN_GPIO, "LCD");
+	if (ret)
+		goto err_request_lcd;
+
+	ret = gpio_direction_output(VIPER_BCKLIGHT_EN_GPIO, 0);
+	if (ret)
+		goto err_dir;
+
+	ret = gpio_direction_output(VIPER_LCD_EN_GPIO, 0);
+	if (ret)
+		goto err_dir;
+
+	return 0;
+
+err_dir:
+	gpio_free(VIPER_LCD_EN_GPIO);
+err_request_lcd:
+	gpio_free(VIPER_BCKLIGHT_EN_GPIO);
+err_request_bckl:
+	dev_err(dev, "Failed to setup LCD GPIOs\n");
+
+	return ret;
+}
+
+static int viper_backlight_notify(int brightness)
+{
+	gpio_set_value(VIPER_LCD_EN_GPIO, !!brightness);
+	gpio_set_value(VIPER_BCKLIGHT_EN_GPIO, !!brightness);
+
+	return brightness;
+}
+
+static void viper_backlight_exit(struct device *dev)
+{
+	gpio_free(VIPER_LCD_EN_GPIO);
+	gpio_free(VIPER_BCKLIGHT_EN_GPIO);
+}
+
+static struct platform_pwm_backlight_data viper_backlight_data = {
+	.pwm_id		= 0,
+	.max_brightness	= 100,
+	.dft_brightness	= 100,
+	.pwm_period_ns	= 1000000,
+	.init		= viper_backlight_init,
+	.notify		= viper_backlight_notify,
+	.exit		= viper_backlight_exit,
+};
+
+static struct platform_device viper_backlight_device = {
+	.name		= "pwm-backlight",
+	.dev		= {
+		.parent		= &pxa25x_device_pwm0.dev,
+		.platform_data	= &viper_backlight_data,
+	},
+};
+
+/* Ethernet */
+static struct resource smc91x_resources[] = {
+	[0] = {
+		.name	= "smc91x-regs",
+		.start  = VIPER_ETH_PHYS + 0x300,
+		.end    = VIPER_ETH_PHYS + 0x30f,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = gpio_to_irq(VIPER_ETH_GPIO),
+		.end    = gpio_to_irq(VIPER_ETH_GPIO),
+		.flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+	},
+	[2] = {
+		.name	= "smc91x-data32",
+		.start  = VIPER_ETH_DATA_PHYS,
+		.end    = VIPER_ETH_DATA_PHYS + 3,
+		.flags  = IORESOURCE_MEM,
+	},
+};
+
+static struct smc91x_platdata viper_smc91x_info = {
+	.flags	= SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda	= RPC_LED_100_10,
+	.ledb	= RPC_LED_TX_RX,
+};
+
+static struct platform_device smc91x_device = {
+	.name		= "smc91x",
+	.id		= -1,
+	.num_resources  = ARRAY_SIZE(smc91x_resources),
+	.resource       = smc91x_resources,
+	.dev		= {
+		.platform_data	= &viper_smc91x_info,
+	},
+};
+
+/* i2c */
+static struct i2c_gpio_platform_data i2c_bus_data = {
+	.sda_pin = VIPER_RTC_I2C_SDA_GPIO,
+	.scl_pin = VIPER_RTC_I2C_SCL_GPIO,
+	.udelay  = 10,
+	.timeout = 100,
+};
+
+static struct platform_device i2c_bus_device = {
+	.name		= "i2c-gpio",
+	.id		= 1, /* pxa2xx-i2c is bus 0, so start at 1 */
+	.dev = {
+		.platform_data = &i2c_bus_data,
+	}
+};
+
+static struct i2c_board_info __initdata viper_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("ds1338", 0x68),
+	},
+};
+
+/*
+ * Serial configuration:
+ * You can either have the standard PXA ports driven by the PXA driver,
+ * or all the ports (PXA + 16850) driven by the 8250 driver.
+ * Choose your poison.
+ */
+
+static struct resource viper_serial_resources[] = {
+#ifndef CONFIG_SERIAL_PXA
+	{
+		.start	= 0x40100000,
+		.end	= 0x4010001f,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= 0x40200000,
+		.end	= 0x4020001f,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= 0x40700000,
+		.end	= 0x4070001f,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= VIPER_UARTA_PHYS,
+		.end	= VIPER_UARTA_PHYS + 0xf,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= VIPER_UARTB_PHYS,
+		.end	= VIPER_UARTB_PHYS + 0xf,
+		.flags	= IORESOURCE_MEM,
+	},
+#else
+	{
+		0,
+	},
+#endif
+};
+
+static struct plat_serial8250_port serial_platform_data[] = {
+#ifndef CONFIG_SERIAL_PXA
+	/* Internal UARTs */
+	{
+		.membase	= (void *)&FFUART,
+		.mapbase	= __PREG(FFUART),
+		.irq		= IRQ_FFUART,
+		.uartclk	= 921600 * 16,
+		.regshift	= 2,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+	},
+	{
+		.membase	= (void *)&BTUART,
+		.mapbase	= __PREG(BTUART),
+		.irq		= IRQ_BTUART,
+		.uartclk	= 921600 * 16,
+		.regshift	= 2,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+	},
+	{
+		.membase	= (void *)&STUART,
+		.mapbase	= __PREG(STUART),
+		.irq		= IRQ_STUART,
+		.uartclk	= 921600 * 16,
+		.regshift	= 2,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+	},
+	/* External UARTs */
+	{
+		.mapbase	= VIPER_UARTA_PHYS,
+		.irq		= gpio_to_irq(VIPER_UARTA_GPIO),
+		.uartclk	= 1843200,
+		.regshift	= 1,
+		.iotype		= UPIO_MEM,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP |
+				  UPF_SKIP_TEST,
+	},
+	{
+		.mapbase	= VIPER_UARTB_PHYS,
+		.irq		= gpio_to_irq(VIPER_UARTB_GPIO),
+		.uartclk	= 1843200,
+		.regshift	= 1,
+		.iotype		= UPIO_MEM,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP |
+				  UPF_SKIP_TEST,
+	},
+#endif
+	{ },
+};
+
+static struct platform_device serial_device = {
+	.name			= "serial8250",
+	.id			= 0,
+	.dev			= {
+		.platform_data	= serial_platform_data,
+	},
+	.num_resources		= ARRAY_SIZE(viper_serial_resources),
+	.resource		= viper_serial_resources,
+};
+
+/* USB */
+static void isp116x_delay(struct device *dev, int delay)
+{
+	ndelay(delay);
+}
+
+static struct resource isp116x_resources[] = {
+	[0] = { /* DATA */
+		.start  = VIPER_USB_PHYS + 0,
+		.end    = VIPER_USB_PHYS + 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = { /* ADDR */
+		.start  = VIPER_USB_PHYS + 2,
+		.end    = VIPER_USB_PHYS + 3,
+		.flags  = IORESOURCE_MEM,
+	},
+	[2] = {
+		.start  = gpio_to_irq(VIPER_USB_GPIO),
+		.end    = gpio_to_irq(VIPER_USB_GPIO),
+		.flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+	},
+};
+
+/* (DataBusWidth16|AnalogOCEnable|DREQOutputPolarity|DownstreamPort15KRSel ) */
+static struct isp116x_platform_data isp116x_platform_data = {
+	/* Enable internal resistors on downstream ports */
+	.sel15Kres		= 1,
+	/* On-chip overcurrent protection */
+	.oc_enable		= 1,
+	/* INT output polarity */
+	.int_act_high		= 1,
+	/* INT edge or level triggered */
+	.int_edge_triggered	= 0,
+
+	/* WAKEUP pin connected - NOT SUPPORTED  */
+	/* .remote_wakeup_connected = 0, */
+	/* Wakeup by devices on usb bus enabled */
+	.remote_wakeup_enable	= 0,
+	.delay			= isp116x_delay,
+};
+
+static struct platform_device isp116x_device = {
+	.name			= "isp116x-hcd",
+	.id			= -1,
+	.num_resources  	= ARRAY_SIZE(isp116x_resources),
+	.resource       	= isp116x_resources,
+	.dev			= {
+		.platform_data	= &isp116x_platform_data,
+	},
+
+};
+
+/* MTD */
+static struct resource mtd_resources[] = {
+	[0] = {	/* RedBoot config + filesystem flash */
+		.start	= VIPER_FLASH_PHYS,
+		.end	= VIPER_FLASH_PHYS + SZ_32M - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {	/* Boot flash */
+		.start	= VIPER_BOOT_PHYS,
+		.end	= VIPER_BOOT_PHYS + SZ_1M - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[2] = { /*
+		 * SRAM size is actually 256KB, 8bits, with a sparse mapping
+		 * (each byte is on a 16bit boundary).
+		 */
+		.start	= _VIPER_SRAM_BASE,
+		.end	= _VIPER_SRAM_BASE + SZ_512K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct mtd_partition viper_boot_flash_partition = {
+	.name		= "RedBoot",
+	.size		= SZ_1M,
+	.offset		= 0,
+	.mask_flags	= MTD_WRITEABLE,	/* force R/O */
+};
+
+static struct physmap_flash_data viper_flash_data[] = {
+	[0] = {
+		.width		= 2,
+		.parts		= NULL,
+		.nr_parts	= 0,
+	},
+	[1] = {
+		.width		= 2,
+		.parts		= &viper_boot_flash_partition,
+		.nr_parts	= 1,
+	},
+};
+
+static struct platform_device viper_mtd_devices[] = {
+	[0] = {
+		.name		= "physmap-flash",
+		.id		= 0,
+		.dev		= {
+			.platform_data	= &viper_flash_data[0],
+		},
+		.resource	= &mtd_resources[0],
+		.num_resources	= 1,
+	},
+	[1] = {
+		.name		= "physmap-flash",
+		.id		= 1,
+		.dev		= {
+			.platform_data	= &viper_flash_data[1],
+		},
+		.resource	= &mtd_resources[1],
+		.num_resources	= 1,
+	},
+};
+
+static struct platform_device *viper_devs[] __initdata = {
+	&smc91x_device,
+	&i2c_bus_device,
+	&serial_device,
+	&isp116x_device,
+	&viper_mtd_devices[0],
+	&viper_mtd_devices[1],
+	&viper_backlight_device,
+};
+
+static mfp_cfg_t viper_pin_config[] __initdata = {
+	/* Chip selects */
+	GPIO15_nCS_1,
+	GPIO78_nCS_2,
+	GPIO79_nCS_3,
+	GPIO80_nCS_4,
+	GPIO33_nCS_5,
+
+	/* FP Backlight */
+	GPIO9_GPIO, 				/* VIPER_BCKLIGHT_EN_GPIO */
+	GPIO10_GPIO,				/* VIPER_LCD_EN_GPIO */
+	GPIO16_PWM0_OUT,
+
+	/* Ethernet PHY Ready */
+	GPIO18_RDY,
+
+	/* Serial shutdown */
+	GPIO12_GPIO | MFP_LPM_DRIVE_HIGH,	/* VIPER_UART_SHDN_GPIO */
+
+	/* Compact-Flash / PC104 */
+	GPIO48_nPOE,
+	GPIO49_nPWE,
+	GPIO50_nPIOR,
+	GPIO51_nPIOW,
+	GPIO52_nPCE_1,
+	GPIO53_nPCE_2,
+	GPIO54_nPSKTSEL,
+	GPIO55_nPREG,
+	GPIO56_nPWAIT,
+	GPIO57_nIOIS16,
+	GPIO8_GPIO,				/* VIPER_CF_RDY_GPIO */
+	GPIO32_GPIO,				/* VIPER_CF_CD_GPIO */
+	GPIO82_GPIO,				/* VIPER_CF_POWER_GPIO */
+
+	/* Integrated UPS control */
+	GPIO20_GPIO,				/* VIPER_UPS_GPIO */
+
+	/* Vcc regulator control */
+	GPIO6_GPIO,				/* VIPER_PSU_DATA_GPIO */
+	GPIO11_GPIO,				/* VIPER_PSU_CLK_GPIO */
+	GPIO19_GPIO,				/* VIPER_PSU_nCS_LD_GPIO */
+
+	/* i2c busses */
+	GPIO26_GPIO,				/* VIPER_TPM_I2C_SDA_GPIO */
+	GPIO27_GPIO,				/* VIPER_TPM_I2C_SCL_GPIO */
+	GPIO83_GPIO,				/* VIPER_RTC_I2C_SDA_GPIO */
+	GPIO84_GPIO,				/* VIPER_RTC_I2C_SCL_GPIO */
+
+	/* PC/104 Interrupt */
+	GPIO1_GPIO | WAKEUP_ON_EDGE_RISE,	/* VIPER_CPLD_GPIO */
+};
+
+static unsigned long viper_tpm;
+
+static int __init viper_tpm_setup(char *str)
+{
+	strict_strtoul(str, 10, &viper_tpm);
+	return 1;
+}
+
+__setup("tpm=", viper_tpm_setup);
+
+static void __init viper_tpm_init(void)
+{
+	struct platform_device *tpm_device;
+	struct i2c_gpio_platform_data i2c_tpm_data = {
+		.sda_pin = VIPER_TPM_I2C_SDA_GPIO,
+		.scl_pin = VIPER_TPM_I2C_SCL_GPIO,
+		.udelay  = 10,
+		.timeout = 100,
+	};
+	char *errstr;
+
+	/* Allocate TPM i2c bus if requested */
+	if (!viper_tpm)
+		return;
+
+	tpm_device = platform_device_alloc("i2c-gpio", 2);
+	if (tpm_device) {
+		if (!platform_device_add_data(tpm_device,
+					      &i2c_tpm_data,
+					      sizeof(i2c_tpm_data))) {
+			if (platform_device_add(tpm_device)) {
+				errstr = "register TPM i2c bus";
+				goto error_free_tpm;
+			}
+		} else {
+			errstr = "allocate TPM i2c bus data";
+			goto error_free_tpm;
+		}
+	} else {
+		errstr = "allocate TPM i2c device";
+		goto error_tpm;
+	}
+
+	return;
+
+error_free_tpm:
+	kfree(tpm_device);
+error_tpm:
+	pr_err("viper: Couldn't %s, giving up\n", errstr);
+}
+
+static void __init viper_init_vcore_gpios(void)
+{
+	if (gpio_request(VIPER_PSU_DATA_GPIO, "PSU data"))
+		goto err_request_data;
+
+	if (gpio_request(VIPER_PSU_CLK_GPIO, "PSU clock"))
+		goto err_request_clk;
+
+	if (gpio_request(VIPER_PSU_nCS_LD_GPIO, "PSU cs"))
+		goto err_request_cs;
+
+	if (gpio_direction_output(VIPER_PSU_DATA_GPIO, 0) ||
+	    gpio_direction_output(VIPER_PSU_CLK_GPIO, 0) ||
+	    gpio_direction_output(VIPER_PSU_nCS_LD_GPIO, 0))
+		goto err_dir;
+
+	/* c/should assume redboot set the correct level ??? */
+	viper_set_core_cpu_voltage(get_clk_frequency_khz(0), 1);
+
+	return;
+
+err_dir:
+	gpio_free(VIPER_PSU_nCS_LD_GPIO);
+err_request_cs:
+	gpio_free(VIPER_PSU_CLK_GPIO);
+err_request_clk:
+	gpio_free(VIPER_PSU_DATA_GPIO);
+err_request_data:
+	pr_err("viper: Failed to setup vcore control GPIOs\n");
+}
+
+static void __init viper_init_serial_gpio(void)
+{
+	if (gpio_request(VIPER_UART_SHDN_GPIO, "UARTs shutdown"))
+		goto err_request;
+
+	if (gpio_direction_output(VIPER_UART_SHDN_GPIO, 0))
+		goto err_dir;
+
+	return;
+
+err_dir:
+	gpio_free(VIPER_UART_SHDN_GPIO);
+err_request:
+	pr_err("viper: Failed to setup UART shutdown GPIO\n");
+}
+
+#ifdef CONFIG_CPU_FREQ
+static int viper_cpufreq_notifier(struct notifier_block *nb,
+				  unsigned long val, void *data)
+{
+	struct cpufreq_freqs *freq = data;
+
+	/* TODO: Adjust timings??? */
+
+	switch (val) {
+	case CPUFREQ_PRECHANGE:
+		if (freq->old < freq->new) {
+			/* we are getting faster so raise the voltage
+			 * before we change freq */
+			viper_set_core_cpu_voltage(freq->new, 0);
+		}
+		break;
+	case CPUFREQ_POSTCHANGE:
+		if (freq->old > freq->new) {
+			/* we are slowing down so drop the power
+			 * after we change freq */
+			viper_set_core_cpu_voltage(freq->new, 0);
+		}
+		break;
+	case CPUFREQ_RESUMECHANGE:
+		viper_set_core_cpu_voltage(freq->new, 0);
+		break;
+	default:
+		/* ignore */
+		break;
+	}
+
+	return 0;
+}
+
+static struct notifier_block viper_cpufreq_notifier_block = {
+	.notifier_call  = viper_cpufreq_notifier
+};
+
+static void __init viper_init_cpufreq(void)
+{
+	if (cpufreq_register_notifier(&viper_cpufreq_notifier_block,
+				      CPUFREQ_TRANSITION_NOTIFIER))
+		pr_err("viper: Failed to setup cpufreq notifier\n");
+}
+#else
+static inline void viper_init_cpufreq(void) {}
+#endif
+
+static void viper_power_off(void)
+{
+	pr_notice("Shutting off UPS\n");
+	gpio_set_value(VIPER_UPS_GPIO, 1);
+	/* Spin to death... */
+	while (1);
+}
+
+static void __init viper_init(void)
+{
+	u8 version;
+
+	pm_power_off = viper_power_off;
+
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(viper_pin_config));
+
+	/* Wake-up serial console */
+	viper_init_serial_gpio();
+
+	set_pxa_fb_info(&fb_info);
+
+	/* v1 hardware cannot use the datacs line */
+	version = viper_hw_version();
+	if (version == 0)
+		smc91x_device.num_resources--;
+
+	pxa_set_i2c_info(NULL);
+	platform_add_devices(viper_devs, ARRAY_SIZE(viper_devs));
+
+	viper_init_vcore_gpios();
+	viper_init_cpufreq();
+
+	sysdev_driver_register(&cpu_sysdev_class, &viper_cpu_sysdev_driver);
+
+	if (version) {
+		pr_info("viper: hardware v%di%d detected. "
+			"CPLD revision %d.\n",
+			VIPER_BOARD_VERSION(version),
+			VIPER_BOARD_ISSUE(version),
+			VIPER_CPLD_REVISION(version));
+		system_rev = (VIPER_BOARD_VERSION(version) << 8) |
+			     (VIPER_BOARD_ISSUE(version) << 4) |
+			     VIPER_CPLD_REVISION(version);
+	} else {
+		pr_info("viper: No version register.\n");
+	}
+
+	i2c_register_board_info(1, ARRAY_AND_SIZE(viper_i2c_devices));
+
+	viper_tpm_init();
+	pxa_set_ac97_info(NULL);
+}
+
+static struct map_desc viper_io_desc[] __initdata = {
+	{
+		.virtual = VIPER_CPLD_BASE,
+		.pfn     = __phys_to_pfn(VIPER_CPLD_PHYS),
+		.length  = 0x00300000,
+		.type    = MT_DEVICE,
+	},
+	{
+		.virtual = VIPER_PC104IO_BASE,
+		.pfn     = __phys_to_pfn(_PCMCIA1IO),
+		.length  = 0x00800000,
+		.type    = MT_DEVICE,
+	},
+};
+
+static void __init viper_map_io(void)
+{
+	pxa_map_io();
+
+	iotable_init(viper_io_desc, ARRAY_SIZE(viper_io_desc));
+
+	PCFR |= PCFR_OPDE;
+}
+
+MACHINE_START(VIPER, "Arcom/Eurotech VIPER SBC")
+	/* Maintainer: Marc Zyngier <maz@misterjones.org> */
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= viper_map_io,
+	.init_irq	= viper_init_irq,
+	.timer          = &pxa_timer,
+	.init_machine	= viper_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index 0cb65b5..8138044 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -29,6 +29,7 @@
 #include <mach/pxafb.h>
 #include <mach/zylonite.h>
 #include <mach/mmc.h>
+#include <mach/ohci.h>
 #include <mach/pxa27x_keypad.h>
 #include <mach/pxa3xx_nand.h>
 
@@ -423,6 +424,21 @@
 static inline void zylonite_init_nand(void) {}
 #endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */
 
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static struct pxaohci_platform_data zylonite_ohci_info = {
+	.port_mode	= PMM_PERPORT_MODE,
+	.flags		= ENABLE_PORT1 | ENABLE_PORT2 |
+			  POWER_CONTROL_LOW | POWER_SENSE_LOW,
+};
+
+static void __init zylonite_init_ohci(void)
+{
+	pxa_set_ohci_info(&zylonite_ohci_info);
+}
+#else
+static inline void zylonite_init_ohci(void) {}
+#endif /* CONFIG_USB_OHCI_HCD || CONFIG_USB_OHCI_HCD_MODULE */
+
 static void __init zylonite_init(void)
 {
 	/* board-processor specific initialization */
@@ -443,6 +459,7 @@
 	zylonite_init_keypad();
 	zylonite_init_nand();
 	zylonite_init_leds();
+	zylonite_init_ohci();
 }
 
 MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c
index 095f5c6..4653888 100644
--- a/arch/arm/mach-pxa/zylonite_pxa300.c
+++ b/arch/arm/mach-pxa/zylonite_pxa300.c
@@ -73,6 +73,12 @@
 	GPIO27_AC97_SDATA_OUT,
 	GPIO28_AC97_SYNC,
 
+	/* SSP3 */
+	GPIO91_SSP3_SCLK,
+	GPIO92_SSP3_FRM,
+	GPIO93_SSP3_TXD,
+	GPIO94_SSP3_RXD,
+
 	/* WM9713 IRQ */
 	GPIO26_GPIO,
 
@@ -113,6 +119,10 @@
 	GPIO13_MMC2_CLK,
 	GPIO14_MMC2_CMD,
 
+	/* USB Host */
+	GPIO0_2_USBH_PEN,
+	GPIO1_2_USBH_PWR,
+
 	/* Standard I2C */
 	GPIO21_I2C_SCL,
 	GPIO22_I2C_SDA,
@@ -209,7 +219,7 @@
 	},
 };
 
-struct i2c_board_info zylonite_i2c_board_info[] = {
+static struct i2c_board_info zylonite_i2c_board_info[] = {
 	{
 		.type		= "pca9539",
 		.addr		= 0x74,
diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c
index 9879d7d..0f24474 100644
--- a/arch/arm/mach-pxa/zylonite_pxa320.c
+++ b/arch/arm/mach-pxa/zylonite_pxa320.c
@@ -69,6 +69,12 @@
 	GPIO39_AC97_BITCLK,
 	GPIO40_AC97_nACRESET,
 
+	/* SSP3 */
+	GPIO89_SSP3_SCLK,
+	GPIO90_SSP3_FRM,
+	GPIO91_SSP3_TXD,
+	GPIO92_SSP3_RXD,
+
 	/* WM9713 IRQ */
 	GPIO15_GPIO,
 
@@ -117,6 +123,10 @@
 	GPIO28_MMC2_CLK,
 	GPIO29_MMC2_CMD,
 
+	/* USB Host */
+	GPIO2_2_USBH_PEN,
+	GPIO3_2_USBH_PWR,
+
 	/* Debug LEDs */
 	GPIO1_2_GPIO | MFP_LPM_DRIVE_HIGH,
 	GPIO4_2_GPIO | MFP_LPM_DRIVE_HIGH,
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 4f9c84a..2f04d54 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -27,10 +27,10 @@
 #include <linux/amba/clcd.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
+#include <linux/io.h>
 
 #include <asm/system.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/hardware/arm_timer.h>
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
index 33dbbb4..3cea92c 100644
--- a/arch/arm/mach-realview/core.h
+++ b/arch/arm/mach-realview/core.h
@@ -23,9 +23,9 @@
 #define __ASM_ARCH_REALVIEW_H
 
 #include <linux/amba/bus.h>
+#include <linux/io.h>
 
 #include <asm/leds.h>
-#include <asm/io.h>
 
 #define AMBA_DEVICE(name,busid,base,plat)			\
 static struct amba_device name##_device = {			\
diff --git a/arch/arm/mach-realview/include/mach/system.h b/arch/arm/mach-realview/include/mach/system.h
index 4d3c8f3..a2f61c7 100644
--- a/arch/arm/mach-realview/include/mach/system.h
+++ b/arch/arm/mach-realview/include/mach/system.h
@@ -21,8 +21,8 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <mach/platform.h>
 
 static inline void arch_idle(void)
diff --git a/arch/arm/mach-realview/localtimer.c b/arch/arm/mach-realview/localtimer.c
index 82fa1f2..44d178c 100644
--- a/arch/arm/mach-realview/localtimer.c
+++ b/arch/arm/mach-realview/localtimer.c
@@ -17,11 +17,11 @@
 #include <linux/percpu.h>
 #include <linux/clockchips.h>
 #include <linux/irq.h>
+#include <linux/io.h>
 
 #include <asm/hardware/arm_twd.h>
 #include <asm/hardware/gic.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 
 static DEFINE_PER_CPU(struct clock_event_device, local_clockevent);
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index 1907d22..e102aeb 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -13,10 +13,10 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/smp.h>
+#include <linux/io.h>
 
 #include <asm/cacheflush.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/mach-types.h>
 
 #include <mach/board-eb.h>
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 19a9968..eb829eb 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -23,9 +23,9 @@
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
 #include <linux/amba/bus.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index 0986cbd..cccdb3e 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -23,9 +23,9 @@
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
 #include <linux/amba/bus.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index f4e7135..8b86314 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -23,9 +23,9 @@
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
 #include <linux/amba/bus.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
diff --git a/arch/arm/mach-rpc/dma.c b/arch/arm/mach-rpc/dma.c
index 4b19fe4..7958a30 100644
--- a/arch/arm/mach-rpc/dma.c
+++ b/arch/arm/mach-rpc/dma.c
@@ -14,11 +14,11 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
+#include <linux/io.h>
 
 #include <asm/page.h>
 #include <asm/dma.h>
 #include <asm/fiq.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <mach/hardware.h>
 #include <asm/uaccess.h>
diff --git a/arch/arm/mach-rpc/include/mach/memory.h b/arch/arm/mach-rpc/include/mach/memory.h
index 05425d5..9bf7e43 100644
--- a/arch/arm/mach-rpc/include/mach/memory.h
+++ b/arch/arm/mach-rpc/include/mach/memory.h
@@ -36,4 +36,12 @@
 #define FLUSH_BASE_PHYS		0x00000000
 #define FLUSH_BASE		0xdf000000
 
+/*
+ * Sparsemem support.  Each section is a maximum of 64MB.  The sections
+ * are offset by 128MB and can cover 128MB, so that gives us a maximum
+ * of 29 physmem bits.
+ */
+#define MAX_PHYSMEM_BITS	29
+#define SECTION_SIZE_BITS	26
+
 #endif
diff --git a/arch/arm/mach-rpc/include/mach/system.h b/arch/arm/mach-rpc/include/mach/system.h
index 54d6e3f..bd7268ba 100644
--- a/arch/arm/mach-rpc/include/mach/system.h
+++ b/arch/arm/mach-rpc/include/mach/system.h
@@ -7,9 +7,9 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/io.h>
 #include <mach/hardware.h>
 #include <asm/hardware/iomd.h>
-#include <asm/io.h>
 
 static inline void arch_idle(void)
 {
diff --git a/arch/arm/mach-rpc/include/mach/uncompress.h b/arch/arm/mach-rpc/include/mach/uncompress.h
index baa9c866..d586236 100644
--- a/arch/arm/mach-rpc/include/mach/uncompress.h
+++ b/arch/arm/mach-rpc/include/mach/uncompress.h
@@ -9,8 +9,8 @@
  */
 #define VIDMEM ((char *)SCREEN_START)
  
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/setup.h>
 #include <asm/page.h>
 
diff --git a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c
index 7a02962..9dd15d6 100644
--- a/arch/arm/mach-rpc/irq.c
+++ b/arch/arm/mach-rpc/irq.c
@@ -1,10 +1,10 @@
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/io.h>
 
 #include <asm/mach/irq.h>
 #include <asm/hardware/iomd.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 
 static void iomd_ack_irq_a(unsigned int irq)
 {
diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c
index ce8470fea..e88d417 100644
--- a/arch/arm/mach-rpc/riscpc.c
+++ b/arch/arm/mach-rpc/riscpc.c
@@ -18,9 +18,9 @@
 #include <linux/device.h>
 #include <linux/serial_8250.h>
 #include <linux/ata_platform.h>
+#include <linux/io.h>
 
 #include <asm/elf.h>
-#include <asm/io.h>
 #include <asm/mach-types.h>
 #include <mach/hardware.h>
 #include <asm/page.h>
diff --git a/arch/arm/mach-s3c2400/gpio.c b/arch/arm/mach-s3c2400/gpio.c
index 148d0dd..7a7ed417 100644
--- a/arch/arm/mach-s3c2400/gpio.c
+++ b/arch/arm/mach-s3c2400/gpio.c
@@ -24,10 +24,10 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 
 #include <mach/regs-gpio.h>
 
diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c
index c66021b..7573800 100644
--- a/arch/arm/mach-s3c2410/bast-irq.c
+++ b/arch/arm/mach-s3c2410/bast-irq.c
@@ -25,12 +25,12 @@
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/sysdev.h>
+#include <linux/io.h>
 
 #include <asm/mach-types.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 
 #include <asm/mach/irq.h>
 
@@ -130,8 +130,7 @@
 		for (i = 0; stat != 0; i++, stat >>= 1) {
 			if (stat & 1) {
 				irqno = bast_pc104_irqs[i];
-				desc = irq_desc + irqno;
-				desc_handle_irq(irqno, desc);
+				generic_handle_irq(irqno);
 			}
 		}
 	}
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index 1322851..fef646c 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -31,11 +31,11 @@
 #include <linux/mutex.h>
 #include <linux/delay.h>
 #include <linux/serial_core.h>
+#include <linux/io.h>
 
 #include <asm/mach/map.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 
 #include <asm/plat-s3c/regs-serial.h>
 #include <mach/regs-clock.h>
diff --git a/arch/arm/mach-s3c2410/gpio.c b/arch/arm/mach-s3c2410/gpio.c
index c6eefb1..36a3132 100644
--- a/arch/arm/mach-s3c2410/gpio.c
+++ b/arch/arm/mach-s3c2410/gpio.c
@@ -25,10 +25,10 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 
 #include <mach/regs-gpio.h>
 
diff --git a/arch/arm/mach-s3c2410/include/mach/system-reset.h b/arch/arm/mach-s3c2410/include/mach/system-reset.h
index ec2defe..43535a0 100644
--- a/arch/arm/mach-s3c2410/include/mach/system-reset.h
+++ b/arch/arm/mach-s3c2410/include/mach/system-reset.h
@@ -11,7 +11,7 @@
 */
 
 #include <mach/hardware.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include <asm/plat-s3c/regs-watchdog.h>
 #include <mach/regs-clock.h>
diff --git a/arch/arm/mach-s3c2410/include/mach/system.h b/arch/arm/mach-s3c2410/include/mach/system.h
index e9f676b..a8cbca6 100644
--- a/arch/arm/mach-s3c2410/include/mach/system.h
+++ b/arch/arm/mach-s3c2410/include/mach/system.h
@@ -10,8 +10,8 @@
  * published by the Free Software Foundation.
 */
 
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 
 #include <mach/map.h>
 #include <mach/idle.h>
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c
index f0de3c2..527f88a 100644
--- a/arch/arm/mach-s3c2410/mach-amlm5900.c
+++ b/arch/arm/mach-s3c2410/mach-amlm5900.c
@@ -36,6 +36,7 @@
 #include <linux/platform_device.h>
 #include <linux/proc_fs.h>
 #include <linux/serial_core.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -43,7 +44,6 @@
 #include <asm/mach/flash.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 #include <mach/fb.h>
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index 24c6334..e4368e6 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -22,6 +22,7 @@
 #include <linux/dm9000.h>
 #include <linux/ata_platform.h>
 #include <linux/i2c.h>
+#include <linux/io.h>
 
 #include <net/ax88796.h>
 
@@ -34,7 +35,6 @@
 #include <mach/bast-cpld.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index e35933a..85e710f 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -20,13 +20,13 @@
 #include <linux/sysdev.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
index 80fe2ed..3ece2d0 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -25,9 +25,9 @@
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
 #include <linux/timer.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c
index 606ee15..c4dfe3e 100644
--- a/arch/arm/mach-s3c2410/mach-otom.c
+++ b/arch/arm/mach-s3c2410/mach-otom.c
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -25,7 +26,6 @@
 #include <mach/otom-map.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
index 7d34844..97c1319 100644
--- a/arch/arm/mach-s3c2410/mach-qt2410.c
+++ b/arch/arm/mach-s3c2410/mach-qt2410.c
@@ -32,7 +32,7 @@
 #include <linux/serial_core.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
-
+#include <linux/io.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand_ecc.h>
@@ -43,7 +43,6 @@
 #include <asm/mach/irq.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
index b88939d..d49e58a 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -36,13 +36,13 @@
 #include <linux/init.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-s3c2410/mach-tct_hammer.c b/arch/arm/mach-s3c2410/mach-tct_hammer.c
index ec87306..cc2e79f 100644
--- a/arch/arm/mach-s3c2410/mach-tct_hammer.c
+++ b/arch/arm/mach-s3c2410/mach-tct_hammer.c
@@ -33,6 +33,7 @@
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -40,7 +41,6 @@
 #include <asm/mach/flash.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index fbc0213..ed3acb0 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -25,6 +25,7 @@
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_reg.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -36,7 +37,6 @@
 #include <mach/vr1000-cpld.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c
index ba43ff9..733f8a2 100644
--- a/arch/arm/mach-s3c2410/pm.c
+++ b/arch/arm/mach-s3c2410/pm.c
@@ -25,9 +25,9 @@
 #include <linux/errno.h>
 #include <linux/time.h>
 #include <linux/sysdev.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index 5d977f9..b1e658c 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -19,13 +19,13 @@
 #include <linux/sysdev.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 
 #include <mach/regs-clock.h>
diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c2410/usb-simtec.c
index 4dacf8a..eb6fc0b 100644
--- a/arch/arm/mach-s3c2410/usb-simtec.c
+++ b/arch/arm/mach-s3c2410/usb-simtec.c
@@ -21,6 +21,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -32,7 +33,6 @@
 #include <mach/regs-gpio.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 
 #include <asm/plat-s3c24xx/devs.h>
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c
index af4b2ce..5fbaac6 100644
--- a/arch/arm/mach-s3c2412/clock.c
+++ b/arch/arm/mach-s3c2412/clock.c
@@ -31,11 +31,11 @@
 #include <linux/mutex.h>
 #include <linux/delay.h>
 #include <linux/serial_core.h>
+#include <linux/io.h>
 
 #include <asm/mach/map.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 
 #include <asm/plat-s3c/regs-serial.h>
 #include <mach/regs-clock.h>
diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c
index 22fc04a..dcfff6b 100644
--- a/arch/arm/mach-s3c2412/dma.c
+++ b/arch/arm/mach-s3c2412/dma.c
@@ -16,10 +16,10 @@
 #include <linux/init.h>
 #include <linux/sysdev.h>
 #include <linux/serial_core.h>
+#include <linux/io.h>
 
 #include <asm/dma.h>
 #include <mach/dma.h>
-#include <asm/io.h>
 
 #include <asm/plat-s3c24xx/dma.h>
 #include <asm/plat-s3c24xx/cpu.h>
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c
index ac62b79..41720f2 100644
--- a/arch/arm/mach-s3c2412/irq.c
+++ b/arch/arm/mach-s3c2412/irq.c
@@ -24,10 +24,10 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/sysdev.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 
 #include <asm/mach/irq.h>
 
@@ -123,10 +123,10 @@
 	subsrc  &= ~submsk;
 
 	if (subsrc & INTBIT(IRQ_S3C2412_SDI))
-		desc_handle_irq(IRQ_S3C2412_SDI, irq_desc + IRQ_S3C2412_SDI);
+		generic_handle_irq(IRQ_S3C2412_SDI);
 
 	if (subsrc & INTBIT(IRQ_S3C2412_CF))
-		desc_handle_irq(IRQ_S3C2412_CF, irq_desc + IRQ_S3C2412_CF);
+		generic_handle_irq(IRQ_S3C2412_CF);
 }
 
 #define INTMSK_CFSDI	(1UL << (IRQ_S3C2412_CFSDI - IRQ_EINT0))
diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c
index 80affb1..8f8d911 100644
--- a/arch/arm/mach-s3c2412/mach-smdk2413.c
+++ b/arch/arm/mach-s3c2412/mach-smdk2413.c
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -27,7 +28,6 @@
 #include <mach/hardware.h>
 #include <asm/hardware/iomd.h>
 #include <asm/setup.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-s3c2412/mach-vstms.c b/arch/arm/mach-s3c2412/mach-vstms.c
index 7a08b37..bb9bf63 100644
--- a/arch/arm/mach-s3c2412/mach-vstms.c
+++ b/arch/arm/mach-s3c2412/mach-vstms.c
@@ -17,7 +17,7 @@
 #include <linux/init.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
-
+#include <linux/io.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand_ecc.h>
@@ -29,7 +29,6 @@
 
 #include <mach/hardware.h>
 #include <asm/setup.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-s3c2412/pm.c b/arch/arm/mach-s3c2412/pm.c
index 737523a..9540ef7 100644
--- a/arch/arm/mach-s3c2412/pm.c
+++ b/arch/arm/mach-s3c2412/pm.c
@@ -18,9 +18,9 @@
 #include <linux/init.h>
 #include <linux/sysdev.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 
 #include <mach/regs-power.h>
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
index d278010..42440fc 100644
--- a/arch/arm/mach-s3c2412/s3c2412.c
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -20,6 +20,7 @@
 #include <linux/sysdev.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -27,7 +28,6 @@
 
 #include <mach/hardware.h>
 #include <asm/proc-fns.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 
 #include <mach/reset.h>
diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c
index 95567e6..40503a6 100644
--- a/arch/arm/mach-s3c2440/clock.c
+++ b/arch/arm/mach-s3c2440/clock.c
@@ -33,11 +33,11 @@
 #include <linux/ioport.h>
 #include <linux/mutex.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/atomic.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 
 #include <mach/regs-clock.h>
 
diff --git a/arch/arm/mach-s3c2440/dsc.c b/arch/arm/mach-s3c2440/dsc.c
index c0c6743..4f7d06b 100644
--- a/arch/arm/mach-s3c2440/dsc.c
+++ b/arch/arm/mach-s3c2440/dsc.c
@@ -15,13 +15,13 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 
 #include <mach/regs-gpio.h>
diff --git a/arch/arm/mach-s3c2440/irq.c b/arch/arm/mach-s3c2440/irq.c
index 276b823..33e3ede 100644
--- a/arch/arm/mach-s3c2440/irq.c
+++ b/arch/arm/mach-s3c2440/irq.c
@@ -24,10 +24,10 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/sysdev.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 
 #include <asm/mach/irq.h>
 
@@ -44,7 +44,6 @@
 				  struct irq_desc *desc)
 {
 	unsigned int subsrc, submsk;
-	struct irq_desc *mydesc;
 
 	/* read the current pending interrupts, and the mask
 	 * for what it is available */
@@ -58,12 +57,10 @@
 
 	if (subsrc != 0) {
 		if (subsrc & 1) {
-			mydesc = irq_desc + IRQ_S3C2440_WDT;
-			desc_handle_irq(IRQ_S3C2440_WDT, mydesc);
+			generic_handle_irq(IRQ_S3C2440_WDT);
 		}
 		if (subsrc & 2) {
-			mydesc = irq_desc + IRQ_S3C2440_AC97;
-			desc_handle_irq(IRQ_S3C2440_AC97, mydesc);
+			generic_handle_irq(IRQ_S3C2440_AC97);
 		}
 	}
 }
diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c
index 441f4bc..19eb0e52 100644
--- a/arch/arm/mach-s3c2440/mach-anubis.c
+++ b/arch/arm/mach-s3c2440/mach-anubis.c
@@ -19,7 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/ata_platform.h>
 #include <linux/i2c.h>
-
+#include <linux/io.h>
 #include <linux/sm501.h>
 #include <linux/sm501-regs.h>
 
@@ -32,7 +32,6 @@
 #include <mach/anubis-cpld.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-s3c2440/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c
index 1a5e702..49e828d 100644
--- a/arch/arm/mach-s3c2440/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2440/mach-nexcoder.c
@@ -21,6 +21,7 @@
 #include <linux/string.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <linux/mtd/map.h>
 
@@ -30,7 +31,6 @@
 
 #include <asm/setup.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index 8b83f93..85144aa 100644
--- a/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -20,6 +20,7 @@
 #include <linux/serial_core.h>
 #include <linux/clk.h>
 #include <linux/i2c.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -29,7 +30,6 @@
 #include <mach/osiris-cpld.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index e0b07e6..a4c6904 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -23,7 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
 #include <linux/serial.h>
-
+#include <linux/io.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand_ecc.h>
@@ -34,7 +34,6 @@
 #include <asm/mach/irq.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c
index 327c8f3..7ac60b8 100644
--- a/arch/arm/mach-s3c2440/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2440/mach-smdk2440.c
@@ -21,13 +21,13 @@
 #include <linux/init.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c
index d6b9a92..c81cdb3 100644
--- a/arch/arm/mach-s3c2440/s3c2440.c
+++ b/arch/arm/mach-s3c2440/s3c2440.c
@@ -20,13 +20,13 @@
 #include <linux/serial_core.h>
 #include <linux/sysdev.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 
 #include <asm/plat-s3c24xx/s3c2440.h>
diff --git a/arch/arm/mach-s3c2442/clock.c b/arch/arm/mach-s3c2442/clock.c
index 569b5c3..18f2ce4 100644
--- a/arch/arm/mach-s3c2442/clock.c
+++ b/arch/arm/mach-s3c2442/clock.c
@@ -33,11 +33,11 @@
 #include <linux/ioport.h>
 #include <linux/mutex.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/atomic.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 
 #include <mach/regs-clock.h>
 
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index 6a8d7cc..603b5ea 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -31,11 +31,11 @@
 #include <linux/mutex.h>
 #include <linux/delay.h>
 #include <linux/serial_core.h>
+#include <linux/io.h>
 
 #include <asm/mach/map.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 
 #include <mach/regs-s3c2443-clock.h>
 
diff --git a/arch/arm/mach-s3c2443/dma.c b/arch/arm/mach-s3c2443/dma.c
index c1ff03a..5d9ee77 100644
--- a/arch/arm/mach-s3c2443/dma.c
+++ b/arch/arm/mach-s3c2443/dma.c
@@ -16,10 +16,10 @@
 #include <linux/init.h>
 #include <linux/sysdev.h>
 #include <linux/serial_core.h>
+#include <linux/io.h>
 
 #include <asm/dma.h>
 #include <mach/dma.h>
-#include <asm/io.h>
 
 #include <asm/plat-s3c24xx/dma.h>
 #include <asm/plat-s3c24xx/cpu.h>
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c
index 9674de7..e44341d 100644
--- a/arch/arm/mach-s3c2443/irq.c
+++ b/arch/arm/mach-s3c2443/irq.c
@@ -24,10 +24,10 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/sysdev.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 
 #include <asm/mach/irq.h>
 
@@ -44,7 +44,6 @@
 {
 	unsigned int subsrc, submsk;
 	unsigned int end;
-	struct irq_desc *mydesc;
 
 	/* read the current pending interrupts, and the mask
 	 * for what it is available */
@@ -57,13 +56,11 @@
 	subsrc  &= (1 << len)-1;
 
 	end = len + irq;
-	mydesc = irq_desc + irq;
 
 	for (; irq < end && subsrc; irq++) {
 		if (subsrc & 1)
-			desc_handle_irq(irq, mydesc);
+			generic_handle_irq(irq);
 
-		mydesc++;
 		subsrc >>= 1;
 	}
 }
diff --git a/arch/arm/mach-s3c2443/mach-smdk2443.c b/arch/arm/mach-s3c2443/mach-smdk2443.c
index e3c0d58..f0d119d 100644
--- a/arch/arm/mach-s3c2443/mach-smdk2443.c
+++ b/arch/arm/mach-s3c2443/mach-smdk2443.c
@@ -21,13 +21,13 @@
 #include <linux/init.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-s3c2443/s3c2443.c b/arch/arm/mach-s3c2443/s3c2443.c
index 37793f9..c973b68 100644
--- a/arch/arm/mach-s3c2443/s3c2443.c
+++ b/arch/arm/mach-s3c2443/s3c2443.c
@@ -20,13 +20,13 @@
 #include <linux/serial_core.h>
 #include <linux/sysdev.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 
 #include <mach/regs-s3c2443-clock.h>
diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
index 3efefbd..ab5883b 100644
--- a/arch/arm/mach-sa1100/badge4.c
+++ b/arch/arm/mach-sa1100/badge4.c
@@ -95,19 +95,19 @@
  *   One-hundred-twenty-seven 32 KiW Main Blocks (8128 Ki b)
  */
 static struct mtd_partition badge4_partitions[] = {
-        {
-                .name           = "BLOB boot loader",
-                .offset         = 0,
-                .size           = 0x0000A000
-        }, {
-                .name           = "params",
-                .offset         = MTDPART_OFS_APPEND,
-                .size           = 0x00006000
-        }, {
-                .name           = "root",
-                .offset         = MTDPART_OFS_APPEND,
-                .size           = MTDPART_SIZ_FULL
-        }
+	{
+		.name	= "BLOB boot loader",
+		.offset	= 0,
+		.size	= 0x0000A000
+	}, {
+		.name	= "params",
+		.offset	= MTDPART_OFS_APPEND,
+		.size	= 0x00006000
+	}, {
+		.name	= "root",
+		.offset	= MTDPART_OFS_APPEND,
+		.size	= MTDPART_SIZ_FULL
+	}
 };
 
 static struct flash_platform_data badge4_flash_data = {
@@ -126,7 +126,7 @@
 
 static int __init five_v_on_setup(char *ignore)
 {
-        five_v_on = 1;
+	five_v_on = 1;
 	return 1;
 }
 __setup("five_v_on", five_v_on_setup);
@@ -171,15 +171,15 @@
 	GPCR  = BADGE4_GPIO_TESTPT_J7;
 	GPDR |= BADGE4_GPIO_TESTPT_J7;
 
- 	/* 5V supply rail. */
- 	GPCR  = BADGE4_GPIO_PCMEN5V;		/* initially off */
-  	GPDR |= BADGE4_GPIO_PCMEN5V;
+	/* 5V supply rail. */
+	GPCR  = BADGE4_GPIO_PCMEN5V;		/* initially off */
+	GPDR |= BADGE4_GPIO_PCMEN5V;
 
 	/* CPLD sdram type inputs; set up by blob */
 	//GPDR |= (BADGE4_GPIO_SDTYP1 | BADGE4_GPIO_SDTYP0);
 	printk(KERN_DEBUG __FILE__ ": SDRAM CPLD typ1=%d typ0=%d\n",
-	       !!(GPLR & BADGE4_GPIO_SDTYP1),
-	       !!(GPLR & BADGE4_GPIO_SDTYP0));
+		!!(GPLR & BADGE4_GPIO_SDTYP1),
+		!!(GPLR & BADGE4_GPIO_SDTYP0));
 
 	/* SA1111 reset pin; set up by blob */
 	//GPSR  = BADGE4_GPIO_SA1111_NRST;
@@ -205,8 +205,8 @@
 	ret = badge4_sa1111_init();
 	if (ret < 0)
 		printk(KERN_ERR
-		       "%s: SA-1111 initialization failed (%d)\n",
-		       __func__, ret);
+			"%s: SA-1111 initialization failed (%d)\n",
+			__func__, ret);
 
 
 	/* maybe turn on 5v0 from the start */
@@ -254,7 +254,7 @@
 
 
 static struct map_desc badge4_io_desc[] __initdata = {
-  	{	/* SRAM  bank 1 */
+	{	/* SRAM  bank 1 */
 		.virtual	= 0xf1000000,
 		.pfn		= __phys_to_pfn(0x08000000),
 		.length		= 0x00100000,
diff --git a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c
index da3a898..f7fa0347 100644
--- a/arch/arm/mach-sa1100/cpu-sa1100.c
+++ b/arch/arm/mach-sa1100/cpu-sa1100.c
@@ -88,6 +88,8 @@
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 
+#include <asm/cputype.h>
+
 #include <mach/hardware.h>
 
 #include "generic.h"
@@ -240,7 +242,7 @@
 
 static int __init sa1100_dram_init(void)
 {
- 	if ((processor_id & CPU_SA1100_MASK) == CPU_SA1100_ID)
+	if (cpu_is_sa1100())
 		return cpufreq_register_driver(&sa1100_driver);
 	else
 		return -ENODEV;
diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c
index 029dbfb..3e4fb21 100644
--- a/arch/arm/mach-sa1100/cpu-sa1110.c
+++ b/arch/arm/mach-sa1100/cpu-sa1110.c
@@ -23,10 +23,11 @@
 #include <linux/cpufreq.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
+#include <asm/cputype.h>
 #include <asm/mach-types.h>
-#include <asm/io.h>
 #include <asm/system.h>
 
 #include "generic.h"
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 1362994..b9fae2a 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -42,7 +42,7 @@
 static const unsigned short cclk_frequency_100khz[NR_FREQS] = {
 	 590,	/*  59.0 MHz */
 	 737,	/*  73.7 MHz */
-	 885, 	/*  88.5 MHz */
+	 885,	/*  88.5 MHz */
 	1032,	/* 103.2 MHz */
 	1180,	/* 118.0 MHz */
 	1327,	/* 132.7 MHz */
@@ -52,10 +52,10 @@
 	1917,	/* 191.7 MHz */
 	2064,	/* 206.4 MHz */
 	2212,	/* 221.2 MHz */
-	2359,   /* 235.9 MHz */
-	2507,   /* 250.7 MHz */
-	2654,   /* 265.4 MHz */
-	2802    /* 280.2 MHz */
+	2359,	/* 235.9 MHz */
+	2507,	/* 250.7 MHz */
+	2654,	/* 265.4 MHz */
+	2802	/* 280.2 MHz */
 };
 
 #if defined(CONFIG_CPU_FREQ_SA1100) || defined(CONFIG_CPU_FREQ_SA1110)
@@ -113,7 +113,7 @@
 #else
 /*
  * We still need to provide this so building without cpufreq works.
- */ 
+ */
 unsigned int cpufreq_get(unsigned int cpu)
 {
 	return cclk_frequency_100khz[PPCR & 0xf] * 100;
@@ -389,7 +389,7 @@
  */
 
 static struct map_desc standard_io_desc[] __initdata = {
-  	{	/* PCM */
+	{	/* PCM */
 		.virtual	=  0xf8000000,
 		.pfn		= __phys_to_pfn(0x80000000),
 		.length		= 0x00100000,
diff --git a/arch/arm/mach-sa1100/include/mach/SA-1100.h b/arch/arm/mach-sa1100/include/mach/SA-1100.h
index 62aaf04..4f7ea01 100644
--- a/arch/arm/mach-sa1100/include/mach/SA-1100.h
+++ b/arch/arm/mach-sa1100/include/mach/SA-1100.h
@@ -2054,19 +2054,3 @@
                 	        	/* active display mode)            */
 #define LCCR3_OutEnH	(LCCR3_OEP*0)	/*  Output Enable active High      */
 #define LCCR3_OutEnL	(LCCR3_OEP*1)	/*  Output Enable active Low       */
-
-#ifndef __ASSEMBLY__
-extern unsigned int processor_id;
-#endif
-
-#define CPU_REVISION	(processor_id & 15)
-#define CPU_SA1110_A0	(0)
-#define CPU_SA1110_B0	(4)
-#define CPU_SA1110_B1	(5)
-#define CPU_SA1110_B2	(6)
-#define CPU_SA1110_B4	(8)
-
-#define CPU_SA1100_ID	(0x4401a110)
-#define CPU_SA1100_MASK	(0xfffffff0)
-#define CPU_SA1110_ID	(0x6901b110)
-#define CPU_SA1110_MASK	(0xfffffff0)
diff --git a/arch/arm/mach-sa1100/include/mach/hardware.h b/arch/arm/mach-sa1100/include/mach/hardware.h
index 5976435..b70846c 100644
--- a/arch/arm/mach-sa1100/include/mach/hardware.h
+++ b/arch/arm/mach-sa1100/include/mach/hardware.h
@@ -36,8 +36,26 @@
 #define io_v2p( x )             \
    ( (((x)&0x00ffffff) | (((x)&(0x30000000>>VIO_SHIFT))<<VIO_SHIFT)) + PIO_START )
 
+#define CPU_SA1110_A0	(0)
+#define CPU_SA1110_B0	(4)
+#define CPU_SA1110_B1	(5)
+#define CPU_SA1110_B2	(6)
+#define CPU_SA1110_B4	(8)
+
+#define CPU_SA1100_ID	(0x4401a110)
+#define CPU_SA1100_MASK	(0xfffffff0)
+#define CPU_SA1110_ID	(0x6901b110)
+#define CPU_SA1110_MASK	(0xfffffff0)
+
 #ifndef __ASSEMBLY__
 
+#include <asm/cputype.h>
+
+#define CPU_REVISION	(read_cpuid_id() & 15)
+
+#define cpu_is_sa1100()	((read_cpuid_id() & CPU_SA1100_MASK) == CPU_SA1100_ID)
+#define cpu_is_sa1110()	((read_cpuid_id() & CPU_SA1110_MASK) == CPU_SA1110_ID)
+
 # define __REG(x)	(*((volatile unsigned long *)io_p2v(x)))
 # define __PREG(x)	(io_v2p((unsigned long)&(x)))
 
diff --git a/arch/arm/mach-sa1100/include/mach/memory.h b/arch/arm/mach-sa1100/include/mach/memory.h
index 29f639e..1c127b6 100644
--- a/arch/arm/mach-sa1100/include/mach/memory.h
+++ b/arch/arm/mach-sa1100/include/mach/memory.h
@@ -40,23 +40,21 @@
 #define __bus_to_virt(x)	 __phys_to_virt(x)
 
 /*
- * Because of the wide memory address space between physical RAM banks on the 
- * SA1100, it's much convenient to use Linux's NUMA support to implement our 
- * memory map representation.  Assuming all memory nodes have equal access 
+ * Because of the wide memory address space between physical RAM banks on the
+ * SA1100, it's much convenient to use Linux's SparseMEM support to implement
+ * our memory map representation.  Assuming all memory nodes have equal access
  * characteristics, we then have generic discontiguous memory support.
  *
- * Of course, all this isn't mandatory for SA1100 implementations with only
- * one used memory bank.  For those, simply undefine CONFIG_DISCONTIGMEM.
- *
- * The nodes are matched with the physical memory bank addresses which are 
- * incidentally the same as virtual addresses.
+ * The sparsemem banks are matched with the physical memory bank addresses
+ * which are incidentally the same as virtual addresses.
  * 
  * 	node 0:  0xc0000000 - 0xc7ffffff
  * 	node 1:  0xc8000000 - 0xcfffffff
  * 	node 2:  0xd0000000 - 0xd7ffffff
  * 	node 3:  0xd8000000 - 0xdfffffff
  */
-#define NODE_MEM_SIZE_BITS	27
+#define MAX_PHYSMEM_BITS	32
+#define SECTION_SIZE_BITS	27
 
 /*
  * Cache flushing area - SA1100 zero bank
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 86369a8..3093d46 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -122,14 +122,12 @@
 		GEDR = mask;
 
 		irq = IRQ_GPIO11;
-		desc = irq_desc + irq;
 		mask >>= 11;
 		do {
 			if (mask & 1)
-				desc_handle_irq(irq, desc);
+				generic_handle_irq(irq);
 			mask >>= 1;
 			irq++;
-			desc++;
 		} while (mask);
 
 		mask = GEDR & 0xfffff800;
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 4856a6b..6ccd175 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -33,8 +33,6 @@
 	unsigned int irr;
 
 	while (1) {
-		struct irq_desc *d;
-
 		/*
 		 * Acknowledge the parent IRQ.
 		 */
@@ -67,21 +65,18 @@
 			desc->chip->ack(irq);
 
 			if (irr & IRR_ETHERNET) {
-				d = irq_desc + IRQ_NEPONSET_SMC9196;
-				desc_handle_irq(IRQ_NEPONSET_SMC9196, d);
+				generic_handle_irq(IRQ_NEPONSET_SMC9196);
 			}
 
 			if (irr & IRR_USAR) {
-				d = irq_desc + IRQ_NEPONSET_USAR;
-				desc_handle_irq(IRQ_NEPONSET_USAR, d);
+				generic_handle_irq(IRQ_NEPONSET_USAR);
 			}
 
 			desc->chip->unmask(irq);
 		}
 
 		if (irr & IRR_SA1111) {
-			d = irq_desc + IRQ_NEPONSET_SA1111;
-			desc_handle_irq(IRQ_NEPONSET_SA1111, d);
+			generic_handle_irq(IRQ_NEPONSET_SA1111);
 		}
 	}
 }
diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c
index 83be1c6..e45d3a1 100644
--- a/arch/arm/mach-sa1100/pleb.c
+++ b/arch/arm/mach-sa1100/pleb.c
@@ -8,11 +8,10 @@
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
 #include <linux/irq.h>
-
+#include <linux/io.h>
 #include <linux/mtd/partitions.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 
@@ -39,8 +38,8 @@
 
 static struct resource smc91x_resources[] = {
 	[0] = {
-		.start	=  PLEB_ETH0_P,
-		.end	=  PLEB_ETH0_P | 0x03ffffff,
+		.start	= PLEB_ETH0_P,
+		.end	= PLEB_ETH0_P | 0x03ffffff,
 		.flags	= IORESOURCE_MEM,
 	},
 #if 0 /* Autoprobe instead, to get rising/falling edge characteristic right */
@@ -87,15 +86,15 @@
 static struct mtd_partition pleb_partitions[] = {
 	{
 		.name		= "blob",
-		.offset 	= 0,
+		.offset		= 0,
 		.size		= 0x00020000,
 	}, {
 		.name		= "kernel",
-		.offset 	= MTDPART_OFS_APPEND,
+		.offset		= MTDPART_OFS_APPEND,
 		.size		= 0x000e0000,
 	}, {
 		.name		= "rootfs",
-		.offset 	= MTDPART_OFS_APPEND,
+		.offset		= MTDPART_OFS_APPEND,
 		.size		= 0x00300000,
 	}
 };
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index 8dd6353..3c74534 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -12,6 +12,7 @@
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/io.h>
 
 #include <asm/irq.h>
 #include <mach/hardware.h>
@@ -27,7 +28,6 @@
 
 #include <linux/serial_core.h>
 #include <linux/ioport.h>
-#include <asm/io.h>
 
 #include "generic.h"
 
diff --git a/arch/arm/mach-sa1100/ssp.c b/arch/arm/mach-sa1100/ssp.c
index 641f361..b20ff93 100644
--- a/arch/arm/mach-sa1100/ssp.c
+++ b/arch/arm/mach-sa1100/ssp.c
@@ -17,8 +17,8 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <mach/hardware.h>
 #include <asm/hardware/ssp.h>
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
index 09d9f33..a9400d9 100644
--- a/arch/arm/mach-shark/core.c
+++ b/arch/arm/mach-shark/core.c
@@ -9,10 +9,10 @@
 #include <linux/irq.h>
 #include <linux/sched.h>
 #include <linux/serial_8250.h>
+#include <linux/io.h>
 
 #include <asm/setup.h>
 #include <asm/mach-types.h>
-#include <asm/io.h>
 #include <asm/leds.h>
 #include <asm/param.h>
 
diff --git a/arch/arm/mach-shark/include/mach/system.h b/arch/arm/mach-shark/include/mach/system.h
index 85aceef..e45bd73 100644
--- a/arch/arm/mach-shark/include/mach/system.h
+++ b/arch/arm/mach-shark/include/mach/system.h
@@ -6,7 +6,7 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-#include <asm/io.h>
+#include <linux/io.h>
 
 static void arch_reset(char mode)
 {
diff --git a/arch/arm/mach-shark/irq.c b/arch/arm/mach-shark/irq.c
index 44b0811..c04eb6a 100644
--- a/arch/arm/mach-shark/irq.c
+++ b/arch/arm/mach-shark/irq.c
@@ -11,9 +11,9 @@
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 
 #include <asm/irq.h>
-#include <asm/io.h>
 #include <asm/mach/irq.h>
 
 /*
diff --git a/arch/arm/mach-shark/leds.c b/arch/arm/mach-shark/leds.c
index b189647..8bd8d6b 100644
--- a/arch/arm/mach-shark/leds.c
+++ b/arch/arm/mach-shark/leds.c
@@ -20,10 +20,10 @@
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/ioport.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/leds.h>
-#include <asm/io.h>
 #include <asm/system.h>
 
 #define LED_STATE_ENABLED	1
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index d75e795..824121d 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -28,11 +28,11 @@
 #include <linux/amba/clcd.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
+#include <linux/io.h>
 
 #include <asm/cnt32_to_63.h>
 #include <asm/system.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/hardware/arm_timer.h>
@@ -95,8 +95,7 @@
 
 		irq += IRQ_SIC_START;
 
-		desc = irq_desc + irq;
-		desc_handle_irq(irq, desc);
+		generic_handle_irq(irq);
 	} while (status);
 }
 
diff --git a/arch/arm/mach-versatile/include/mach/system.h b/arch/arm/mach-versatile/include/mach/system.h
index 91fa559..c59e610 100644
--- a/arch/arm/mach-versatile/include/mach/system.h
+++ b/arch/arm/mach-versatile/include/mach/system.h
@@ -21,8 +21,8 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <mach/platform.h>
 
 static inline void arch_idle(void)
diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c
index 36f23f8..7161ba2 100644
--- a/arch/arm/mach-versatile/pci.c
+++ b/arch/arm/mach-versatile/pci.c
@@ -21,9 +21,9 @@
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/mach/pci.h>
diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c
index 76375c6..bb8ec77 100644
--- a/arch/arm/mach-versatile/versatile_ab.c
+++ b/arch/arm/mach-versatile/versatile_ab.c
@@ -23,9 +23,9 @@
 #include <linux/device.h>
 #include <linux/sysdev.h>
 #include <linux/amba/bus.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c
index 1725f01..aa051c0 100644
--- a/arch/arm/mach-versatile/versatile_pb.c
+++ b/arch/arm/mach-versatile/versatile_pb.c
@@ -23,9 +23,9 @@
 #include <linux/device.h>
 #include <linux/sysdev.h>
 #include <linux/amba/bus.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 546d7e7..d119388 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -735,6 +735,14 @@
 	help
 	  This option enables the Feroceon L2 cache controller.
 
+config CACHE_FEROCEON_L2_WRITETHROUGH
+	bool "Force Feroceon L2 cache write through"
+	depends on CACHE_FEROCEON_L2
+	default n
+	help
+	  Say Y here to use the Feroceon L2 cache in writethrough mode.
+	  Unless you specifically require this, say N for writeback mode.
+
 config CACHE_L2X0
 	bool "Enable the L2x0 outer cache controller"
 	depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 2e27a8c..480f78a 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -2,7 +2,7 @@
 # Makefile for the linux arm-specific parts of the memory manager.
 #
 
-obj-y				:= consistent.o extable.o fault.o init.o \
+obj-y				:= dma-mapping.o extable.o fault.o init.o \
 				   iomap.o
 
 obj-$(CONFIG_MMU)		+= fault-armv.o flush.o ioremap.o mmap.o \
diff --git a/arch/arm/mm/abort-ev7.S b/arch/arm/mm/abort-ev7.S
index eb90bce..2e6dc04 100644
--- a/arch/arm/mm/abort-ev7.S
+++ b/arch/arm/mm/abort-ev7.S
@@ -30,3 +30,4 @@
 	 * New designs should not need to patch up faults.
 	 */
 	mov	pc, lr
+ENDPROC(v7_early_abort)
diff --git a/arch/arm/mm/abort-nommu.S b/arch/arm/mm/abort-nommu.S
index a7cc7f9e..625e580 100644
--- a/arch/arm/mm/abort-nommu.S
+++ b/arch/arm/mm/abort-nommu.S
@@ -17,3 +17,4 @@
 	mov	r0, #0				@ clear r0, r1 (no FSR/FAR)
 	mov	r1, #0
 	mov	pc, lr
+ENDPROC(nommu_early_abort)
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index e162cca..133e65d 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -17,8 +17,8 @@
 #include <linux/string.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
+#include <linux/uaccess.h>
 
-#include <asm/uaccess.h>
 #include <asm/unaligned.h>
 
 #include "fault.h"
diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c
index 7b5a25d..13cdae8 100644
--- a/arch/arm/mm/cache-feroceon-l2.c
+++ b/arch/arm/mm/cache-feroceon-l2.c
@@ -48,11 +48,12 @@
 	 * L2 is PIPT and range operations only do a TLB lookup on
 	 * the start address.
 	 */
-	BUG_ON((start ^ end) & ~(PAGE_SIZE - 1));
+	BUG_ON((start ^ end) >> PAGE_SHIFT);
 
 	raw_local_irq_save(flags);
-	__asm__("mcr p15, 1, %0, c15, c9, 4" : : "r" (start));
-	__asm__("mcr p15, 1, %0, c15, c9, 5" : : "r" (end));
+	__asm__("mcr p15, 1, %0, c15, c9, 4\n\t"
+		"mcr p15, 1, %1, c15, c9, 5"
+		: : "r" (start), "r" (end));
 	raw_local_irq_restore(flags);
 }
 
@@ -80,11 +81,12 @@
 	 * L2 is PIPT and range operations only do a TLB lookup on
 	 * the start address.
 	 */
-	BUG_ON((start ^ end) & ~(PAGE_SIZE - 1));
+	BUG_ON((start ^ end) >> PAGE_SHIFT);
 
 	raw_local_irq_save(flags);
-	__asm__("mcr p15, 1, %0, c15, c11, 4" : : "r" (start));
-	__asm__("mcr p15, 1, %0, c15, c11, 5" : : "r" (end));
+	__asm__("mcr p15, 1, %0, c15, c11, 4\n\t"
+		"mcr p15, 1, %1, c15, c11, 5"
+		: : "r" (start), "r" (end));
 	raw_local_irq_restore(flags);
 }
 
@@ -205,7 +207,7 @@
  * time.  These are necessary because the L2 cache can only be enabled
  * or disabled while the L1 Dcache and Icache are both disabled.
  */
-static void __init invalidate_and_disable_dcache(void)
+static int __init flush_and_disable_dcache(void)
 {
 	u32 cr;
 
@@ -217,7 +219,9 @@
 		flush_cache_all();
 		set_cr(cr & ~CR_C);
 		raw_local_irq_restore(flags);
+		return 1;
 	}
+	return 0;
 }
 
 static void __init enable_dcache(void)
@@ -225,18 +229,17 @@
 	u32 cr;
 
 	cr = get_cr();
-	if (!(cr & CR_C))
-		set_cr(cr | CR_C);
+	set_cr(cr | CR_C);
 }
 
 static void __init __invalidate_icache(void)
 {
 	int dummy;
 
-	__asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0\n" : "=r" (dummy));
+	__asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0" : "=r" (dummy));
 }
 
-static void __init invalidate_and_disable_icache(void)
+static int __init invalidate_and_disable_icache(void)
 {
 	u32 cr;
 
@@ -244,7 +247,9 @@
 	if (cr & CR_I) {
 		set_cr(cr & ~CR_I);
 		__invalidate_icache();
+		return 1;
 	}
+	return 0;
 }
 
 static void __init enable_icache(void)
@@ -252,8 +257,7 @@
 	u32 cr;
 
 	cr = get_cr();
-	if (!(cr & CR_I))
-		set_cr(cr | CR_I);
+	set_cr(cr | CR_I);
 }
 
 static inline u32 read_extra_features(void)
@@ -291,13 +295,17 @@
 
 	u = read_extra_features();
 	if (!(u & 0x00400000)) {
+		int i, d;
+
 		printk(KERN_INFO "Feroceon L2: Enabling L2\n");
 
-		invalidate_and_disable_dcache();
-		invalidate_and_disable_icache();
+		d = flush_and_disable_dcache();
+		i = invalidate_and_disable_icache();
 		write_extra_features(u | 0x00400000);
-		enable_icache();
-		enable_dcache();
+		if (i)
+			enable_icache();
+		if (d)
+			enable_dcache();
 	}
 }
 
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 76b800a..b480f1d 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -18,9 +18,9 @@
  */
 #include <linux/init.h>
 #include <linux/spinlock.h>
+#include <linux/io.h>
 
 #include <asm/cacheflush.h>
-#include <asm/io.h>
 #include <asm/hardware/cache-l2x0.h>
 
 #define CACHE_LINE_SIZE		32
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 35ffc4d..d19c2be 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -66,6 +66,7 @@
 	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level in cssr
 	isb
 	mov	pc, lr
+ENDPROC(v7_flush_dcache_all)
 
 /*
  *	v7_flush_cache_all()
@@ -85,6 +86,7 @@
 	mcr	p15, 0, r0, c7, c5, 0		@ I+BTB cache invalidate
 	ldmfd	sp!, {r4-r5, r7, r9-r11, lr}
 	mov	pc, lr
+ENDPROC(v7_flush_kern_cache_all)
 
 /*
  *	v7_flush_cache_all()
@@ -110,6 +112,8 @@
  */
 ENTRY(v7_flush_user_cache_range)
 	mov	pc, lr
+ENDPROC(v7_flush_user_cache_all)
+ENDPROC(v7_flush_user_cache_range)
 
 /*
  *	v7_coherent_kern_range(start,end)
@@ -155,6 +159,8 @@
 	dsb
 	isb
 	mov	pc, lr
+ENDPROC(v7_coherent_kern_range)
+ENDPROC(v7_coherent_user_range)
 
 /*
  *	v7_flush_kern_dcache_page(kaddr)
@@ -174,6 +180,7 @@
 	blo	1b
 	dsb
 	mov	pc, lr
+ENDPROC(v7_flush_kern_dcache_page)
 
 /*
  *	v7_dma_inv_range(start,end)
@@ -202,6 +209,7 @@
 	blo	1b
 	dsb
 	mov	pc, lr
+ENDPROC(v7_dma_inv_range)
 
 /*
  *	v7_dma_clean_range(start,end)
@@ -219,6 +227,7 @@
 	blo	1b
 	dsb
 	mov	pc, lr
+ENDPROC(v7_dma_clean_range)
 
 /*
  *	v7_dma_flush_range(start,end)
@@ -236,6 +245,7 @@
 	blo	1b
 	dsb
 	mov	pc, lr
+ENDPROC(v7_dma_flush_range)
 
 	__INITDATA
 
diff --git a/arch/arm/mm/cache-xsc3l2.c b/arch/arm/mm/cache-xsc3l2.c
index 158bd96..10b1bae 100644
--- a/arch/arm/mm/cache-xsc3l2.c
+++ b/arch/arm/mm/cache-xsc3l2.c
@@ -18,10 +18,11 @@
  */
 #include <linux/init.h>
 #include <linux/spinlock.h>
+#include <linux/io.h>
 
 #include <asm/system.h>
+#include <asm/cputype.h>
 #include <asm/cacheflush.h>
-#include <asm/io.h>
 
 #define CR_L2	(1 << 26)
 
diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c
index ded0e96..8d33e25 100644
--- a/arch/arm/mm/copypage-v4mc.c
+++ b/arch/arm/mm/copypage-v4mc.c
@@ -28,7 +28,7 @@
  * specific hacks for copying pages efficiently.
  */
 #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
-				  L_PTE_CACHEABLE)
+				  L_PTE_MT_MINICACHE)
 
 static DEFINE_SPINLOCK(minicache_lock);
 
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
index 3adb792..0e21c07 100644
--- a/arch/arm/mm/copypage-v6.c
+++ b/arch/arm/mm/copypage-v6.c
@@ -16,6 +16,7 @@
 #include <asm/shmparam.h>
 #include <asm/tlbflush.h>
 #include <asm/cacheflush.h>
+#include <asm/cachetype.h>
 
 #include "mm.h"
 
diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c
index 2e455f8..bad4933 100644
--- a/arch/arm/mm/copypage-xscale.c
+++ b/arch/arm/mm/copypage-xscale.c
@@ -30,7 +30,7 @@
 #define COPYPAGE_MINICACHE	0xffff8000
 
 #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
-				  L_PTE_CACHEABLE)
+				  L_PTE_MT_MINICACHE)
 
 static DEFINE_SPINLOCK(minicache_lock);
 
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/dma-mapping.c
similarity index 79%
rename from arch/arm/mm/consistent.c
rename to arch/arm/mm/dma-mapping.c
index db7b3e3..6796001 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/mm/consistent.c
+ *  linux/arch/arm/mm/dma-mapping.c
  *
  *  Copyright (C) 2000-2004 Russell King
  *
@@ -512,3 +512,105 @@
 	}
 }
 EXPORT_SYMBOL(dma_cache_maint);
+
+/**
+ * dma_map_sg - map a set of SG buffers for streaming mode DMA
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @sg: list of buffers
+ * @nents: number of buffers to map
+ * @dir: DMA transfer direction
+ *
+ * Map a set of buffers described by scatterlist in streaming mode for DMA.
+ * This is the scatter-gather version of the dma_map_single interface.
+ * Here the scatter gather list elements are each tagged with the
+ * appropriate dma address and length.  They are obtained via
+ * sg_dma_{address,length}.
+ *
+ * Device ownership issues as mentioned for dma_map_single are the same
+ * here.
+ */
+int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+		enum dma_data_direction dir)
+{
+	struct scatterlist *s;
+	int i, j;
+
+	for_each_sg(sg, s, nents, i) {
+		s->dma_address = dma_map_page(dev, sg_page(s), s->offset,
+						s->length, dir);
+		if (dma_mapping_error(dev, s->dma_address))
+			goto bad_mapping;
+	}
+	return nents;
+
+ bad_mapping:
+	for_each_sg(sg, s, i, j)
+		dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
+	return 0;
+}
+EXPORT_SYMBOL(dma_map_sg);
+
+/**
+ * dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @sg: list of buffers
+ * @nents: number of buffers to unmap (returned from dma_map_sg)
+ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
+ *
+ * Unmap a set of streaming mode DMA translations.  Again, CPU access
+ * rules concerning calls here are the same as for dma_unmap_single().
+ */
+void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
+		enum dma_data_direction dir)
+{
+	struct scatterlist *s;
+	int i;
+
+	for_each_sg(sg, s, nents, i)
+		dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
+}
+EXPORT_SYMBOL(dma_unmap_sg);
+
+/**
+ * dma_sync_sg_for_cpu
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @sg: list of buffers
+ * @nents: number of buffers to map (returned from dma_map_sg)
+ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
+ */
+void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+			int nents, enum dma_data_direction dir)
+{
+	struct scatterlist *s;
+	int i;
+
+	for_each_sg(sg, s, nents, i) {
+		dmabounce_sync_for_cpu(dev, sg_dma_address(s), 0,
+					sg_dma_len(s), dir);
+	}
+}
+EXPORT_SYMBOL(dma_sync_sg_for_cpu);
+
+/**
+ * dma_sync_sg_for_device
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @sg: list of buffers
+ * @nents: number of buffers to map (returned from dma_map_sg)
+ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
+ */
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+			int nents, enum dma_data_direction dir)
+{
+	struct scatterlist *s;
+	int i;
+
+	for_each_sg(sg, s, nents, i) {
+		if (!dmabounce_sync_for_device(dev, sg_dma_address(s), 0,
+					sg_dma_len(s), dir))
+			continue;
+
+		if (!arch_is_coherent())
+			dma_cache_maint(sg_virt(s), s->length, dir);
+	}
+}
+EXPORT_SYMBOL(dma_sync_sg_for_device);
diff --git a/arch/arm/mm/extable.c b/arch/arm/mm/extable.c
index 9592c3e..9d28562 100644
--- a/arch/arm/mm/extable.c
+++ b/arch/arm/mm/extable.c
@@ -2,7 +2,7 @@
  *  linux/arch/arm/mm/extable.c
  */
 #include <linux/module.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 int fixup_exception(struct pt_regs *regs)
 {
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index a8ec97b..81d0b87 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -17,11 +17,13 @@
 #include <linux/init.h>
 #include <linux/pagemap.h>
 
+#include <asm/bugs.h>
 #include <asm/cacheflush.h>
+#include <asm/cachetype.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 
-static unsigned long shared_pte_mask = L_PTE_CACHEABLE;
+static unsigned long shared_pte_mask = L_PTE_MT_BUFFERABLE;
 
 /*
  * We take the easy way out of this problem - we make the
@@ -63,9 +65,10 @@
 	 * If this page isn't present, or is already setup to
 	 * fault (ie, is old), we can safely ignore any issues.
 	 */
-	if (ret && pte_val(entry) & shared_pte_mask) {
+	if (ret && (pte_val(entry) & L_PTE_MT_MASK) != shared_pte_mask) {
 		flush_cache_page(vma, address, pte_pfn(entry));
-		pte_val(entry) &= ~shared_pte_mask;
+		pte_val(entry) &= ~L_PTE_MT_MASK;
+		pte_val(entry) |= shared_pte_mask;
 		set_pte_at(vma->vm_mm, address, pte, entry);
 		flush_tlb_page(vma, address);
 	}
@@ -197,7 +200,7 @@
 		unsigned long *p1, *p2;
 		pgprot_t prot = __pgprot(L_PTE_PRESENT|L_PTE_YOUNG|
 					 L_PTE_DIRTY|L_PTE_WRITE|
-					 L_PTE_BUFFERABLE);
+					 L_PTE_MT_BUFFERABLE);
 
 		p1 = vmap(&page, 1, VM_IOREMAP, prot);
 		p2 = vmap(&page, 1, VM_IOREMAP, prot);
@@ -218,7 +221,7 @@
 
 	if (v) {
 		printk("failed, %s\n", reason);
-		shared_pte_mask |= L_PTE_BUFFERABLE;
+		shared_pte_mask = L_PTE_MT_UNCACHED;
 	} else {
 		printk("ok\n");
 	}
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 28ad7ab..2df8d9f 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -13,11 +13,11 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/kprobes.h>
+#include <linux/uaccess.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
-#include <asm/uaccess.h>
 
 #include "fault.h"
 
@@ -72,9 +72,8 @@
 		}
 
 		pmd = pmd_offset(pgd, addr);
-#if PTRS_PER_PMD != 1
-		printk(", *pmd=%08lx", pmd_val(*pmd));
-#endif
+		if (PTRS_PER_PMD != 1)
+			printk(", *pmd=%08lx", pmd_val(*pmd));
 
 		if (pmd_none(*pmd))
 			break;
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 029ee65..0fa9bf3 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -12,6 +12,7 @@
 #include <linux/pagemap.h>
 
 #include <asm/cacheflush.h>
+#include <asm/cachetype.h>
 #include <asm/system.h>
 #include <asm/tlbflush.h>
 
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 30a69d6..82c4b42 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -26,9 +26,42 @@
 
 #include "mm.h"
 
-extern void _text, _etext, __data_start, _end, __init_begin, __init_end;
-extern unsigned long phys_initrd_start;
-extern unsigned long phys_initrd_size;
+static unsigned long phys_initrd_start __initdata = 0;
+static unsigned long phys_initrd_size __initdata = 0;
+
+static void __init early_initrd(char **p)
+{
+	unsigned long start, size;
+
+	start = memparse(*p, p);
+	if (**p == ',') {
+		size = memparse((*p) + 1, p);
+
+		phys_initrd_start = start;
+		phys_initrd_size = size;
+	}
+}
+__early_param("initrd=", early_initrd);
+
+static int __init parse_tag_initrd(const struct tag *tag)
+{
+	printk(KERN_WARNING "ATAG_INITRD is deprecated; "
+		"please update your bootloader.\n");
+	phys_initrd_start = __virt_to_phys(tag->u.initrd.start);
+	phys_initrd_size = tag->u.initrd.size;
+	return 0;
+}
+
+__tagtable(ATAG_INITRD, parse_tag_initrd);
+
+static int __init parse_tag_initrd2(const struct tag *tag)
+{
+	phys_initrd_start = tag->u.initrd.start;
+	phys_initrd_size = tag->u.initrd.size;
+	return 0;
+}
+
+__tagtable(ATAG_INITRD2, parse_tag_initrd2);
 
 /*
  * This is used to pass memory configuration data from paging_init
@@ -36,10 +69,6 @@
  */
 static struct meminfo meminfo = { 0, };
 
-#define for_each_nodebank(iter,mi,no)			\
-	for (iter = 0; iter < mi->nr_banks; iter++)	\
-		if (mi->bank[iter].node == no)
-
 void show_mem(void)
 {
 	int free = 0, total = 0, reserved = 0;
@@ -50,14 +79,15 @@
 	show_free_areas();
 	for_each_online_node(node) {
 		pg_data_t *n = NODE_DATA(node);
-		struct page *map = n->node_mem_map - n->node_start_pfn;
+		struct page *map = pgdat_page_nr(n, 0) - n->node_start_pfn;
 
 		for_each_nodebank (i,mi,node) {
+			struct membank *bank = &mi->bank[i];
 			unsigned int pfn1, pfn2;
 			struct page *page, *end;
 
-			pfn1 = __phys_to_pfn(mi->bank[i].start);
-			pfn2 = __phys_to_pfn(mi->bank[i].size + mi->bank[i].start);
+			pfn1 = bank_pfn_start(bank);
+			pfn2 = bank_pfn_end(bank);
 
 			page = map + pfn1;
 			end  = map + pfn2;
@@ -96,17 +126,17 @@
 static unsigned int __init
 find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages)
 {
-	unsigned int start_pfn, bank, bootmap_pfn;
+	unsigned int start_pfn, i, bootmap_pfn;
 
 	start_pfn   = PAGE_ALIGN(__pa(&_end)) >> PAGE_SHIFT;
 	bootmap_pfn = 0;
 
-	for_each_nodebank(bank, mi, node) {
+	for_each_nodebank(i, mi, node) {
+		struct membank *bank = &mi->bank[i];
 		unsigned int start, end;
 
-		start = mi->bank[bank].start >> PAGE_SHIFT;
-		end   = (mi->bank[bank].size +
-			 mi->bank[bank].start) >> PAGE_SHIFT;
+		start = bank_pfn_start(bank);
+		end   = bank_pfn_end(bank);
 
 		if (end < start_pfn)
 			continue;
@@ -145,13 +175,10 @@
 		initrd_node = -1;
 
 		for (i = 0; i < mi->nr_banks; i++) {
-			unsigned long bank_end;
-
-			bank_end = mi->bank[i].start + mi->bank[i].size;
-
-			if (mi->bank[i].start <= phys_initrd_start &&
-			    end <= bank_end)
-				initrd_node = mi->bank[i].node;
+			struct membank *bank = &mi->bank[i];
+			if (bank_phys_start(bank) <= phys_initrd_start &&
+			    end <= bank_phys_end(bank))
+				initrd_node = bank->node;
 		}
 	}
 
@@ -171,19 +198,17 @@
 #ifdef CONFIG_MMU
 	struct map_desc map;
 
-	map.pfn = __phys_to_pfn(bank->start);
-	map.virtual = __phys_to_virt(bank->start);
-	map.length = bank->size;
+	map.pfn = bank_pfn_start(bank);
+	map.virtual = __phys_to_virt(bank_phys_start(bank));
+	map.length = bank_phys_size(bank);
 	map.type = MT_MEMORY;
 
 	create_mapping(&map);
 #endif
 }
 
-static unsigned long __init
-bootmem_init_node(int node, int initrd_node, struct meminfo *mi)
+static unsigned long __init bootmem_init_node(int node, struct meminfo *mi)
 {
-	unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
 	unsigned long start_pfn, end_pfn, boot_pfn;
 	unsigned int boot_pages;
 	pg_data_t *pgdat;
@@ -199,8 +224,8 @@
 		struct membank *bank = &mi->bank[i];
 		unsigned long start, end;
 
-		start = bank->start >> PAGE_SHIFT;
-		end = (bank->start + bank->size) >> PAGE_SHIFT;
+		start = bank_pfn_start(bank);
+		end = bank_pfn_end(bank);
 
 		if (start_pfn > start)
 			start_pfn = start;
@@ -230,8 +255,11 @@
 	pgdat = NODE_DATA(node);
 	init_bootmem_node(pgdat, boot_pfn, start_pfn, end_pfn);
 
-	for_each_nodebank(i, mi, node)
-		free_bootmem_node(pgdat, mi->bank[i].start, mi->bank[i].size);
+	for_each_nodebank(i, mi, node) {
+		struct membank *bank = &mi->bank[i];
+		free_bootmem_node(pgdat, bank_phys_start(bank), bank_phys_size(bank));
+		memory_present(node, bank_pfn_start(bank), bank_pfn_end(bank));
+	}
 
 	/*
 	 * Reserve the bootmem bitmap for this node.
@@ -239,31 +267,39 @@
 	reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT,
 			     boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT);
 
-	/*
-	 * Reserve any special node zero regions.
-	 */
-	if (node == 0)
-		reserve_node_zero(pgdat);
+	return end_pfn;
+}
 
+static void __init bootmem_reserve_initrd(int node)
+{
 #ifdef CONFIG_BLK_DEV_INITRD
-	/*
-	 * If the initrd is in this node, reserve its memory.
-	 */
-	if (node == initrd_node) {
-		int res = reserve_bootmem_node(pgdat, phys_initrd_start,
-				     phys_initrd_size, BOOTMEM_EXCLUSIVE);
+	pg_data_t *pgdat = NODE_DATA(node);
+	int res;
 
-		if (res == 0) {
-			initrd_start = __phys_to_virt(phys_initrd_start);
-			initrd_end = initrd_start + phys_initrd_size;
-		} else {
-			printk(KERN_ERR
-				"INITRD: 0x%08lx+0x%08lx overlaps in-use "
-				"memory region - disabling initrd\n",
-				phys_initrd_start, phys_initrd_size);
-		}
+	res = reserve_bootmem_node(pgdat, phys_initrd_start,
+			     phys_initrd_size, BOOTMEM_EXCLUSIVE);
+
+	if (res == 0) {
+		initrd_start = __phys_to_virt(phys_initrd_start);
+		initrd_end = initrd_start + phys_initrd_size;
+	} else {
+		printk(KERN_ERR
+			"INITRD: 0x%08lx+0x%08lx overlaps in-use "
+			"memory region - disabling initrd\n",
+			phys_initrd_start, phys_initrd_size);
 	}
 #endif
+}
+
+static void __init bootmem_free_node(int node, struct meminfo *mi)
+{
+	unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
+	unsigned long start_pfn, end_pfn;
+	pg_data_t *pgdat = NODE_DATA(node);
+	int i;
+
+	start_pfn = pgdat->bdata->node_min_pfn;
+	end_pfn = pgdat->bdata->node_low_pfn;
 
 	/*
 	 * initialise the zones within this node.
@@ -284,7 +320,7 @@
 	 */
 	zhole_size[0] = zone_size[0];
 	for_each_nodebank(i, mi, node)
-		zhole_size[0] -= mi->bank[i].size >> PAGE_SHIFT;
+		zhole_size[0] -= bank_pfn_size(&mi->bank[i]);
 
 	/*
 	 * Adjust the sizes according to any special requirements for
@@ -293,21 +329,12 @@
 	arch_adjust_zones(node, zone_size, zhole_size);
 
 	free_area_init_node(node, zone_size, start_pfn, zhole_size);
-
-	return end_pfn;
 }
 
 void __init bootmem_init(struct meminfo *mi)
 {
 	unsigned long memend_pfn = 0;
-	int node, initrd_node, i;
-
-	/*
-	 * Invalidate the node number for empty or invalid memory banks
-	 */
-	for (i = 0; i < mi->nr_banks; i++)
-		if (mi->bank[i].size == 0 || mi->bank[i].node >= MAX_NUMNODES)
-			mi->bank[i].node = -1;
+	int node, initrd_node;
 
 	memcpy(&meminfo, mi, sizeof(meminfo));
 
@@ -320,9 +347,19 @@
 	 * Run through each node initialising the bootmem allocator.
 	 */
 	for_each_node(node) {
-		unsigned long end_pfn;
+		unsigned long end_pfn = bootmem_init_node(node, mi);
 
-		end_pfn = bootmem_init_node(node, initrd_node, mi);
+		/*
+		 * Reserve any special node zero regions.
+		 */
+		if (node == 0)
+			reserve_node_zero(NODE_DATA(node));
+
+		/*
+		 * If the initrd is in this node, reserve its memory.
+		 */
+		if (node == initrd_node)
+			bootmem_reserve_initrd(node);
 
 		/*
 		 * Remember the highest memory PFN.
@@ -331,6 +368,19 @@
 			memend_pfn = end_pfn;
 	}
 
+	/*
+	 * sparse_init() needs the bootmem allocator up and running.
+	 */
+	sparse_init();
+
+	/*
+	 * Now free memory in each node - free_area_init_node needs
+	 * the sparse mem_map arrays initialized by sparse_init()
+	 * for memmap_init_zone(), otherwise all PFNs are invalid.
+	 */
+	for_each_node(node)
+		bootmem_free_node(node, mi);
+
 	high_memory = __va(memend_pfn << PAGE_SHIFT);
 
 	/*
@@ -401,7 +451,9 @@
 	 * information on the command line.
 	 */
 	for_each_nodebank(i, mi, node) {
-		bank_start = mi->bank[i].start >> PAGE_SHIFT;
+		struct membank *bank = &mi->bank[i];
+
+		bank_start = bank_pfn_start(bank);
 		if (bank_start < prev_bank_end) {
 			printk(KERN_ERR "MEM: unordered memory banks.  "
 				"Not freeing memmap.\n");
@@ -415,8 +467,7 @@
 		if (prev_bank_end && prev_bank_end != bank_start)
 			free_memmap(node, prev_bank_end, bank_start);
 
-		prev_bank_end = (mi->bank[i].start +
-				 mi->bank[i].size) >> PAGE_SHIFT;
+		prev_bank_end = bank_pfn_end(bank);
 	}
 }
 
@@ -461,8 +512,8 @@
 
 	num_physpages = 0;
 	for (i = 0; i < meminfo.nr_banks; i++) {
-		num_physpages += meminfo.bank[i].size >> PAGE_SHIFT;
-		printk(" %ldMB", meminfo.bank[i].size >> 20);
+		num_physpages += bank_pfn_size(&meminfo.bank[i]);
+		printk(" %ldMB", bank_phys_size(&meminfo.bank[i]) >> 20);
 	}
 
 	printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
diff --git a/arch/arm/mm/iomap.c b/arch/arm/mm/iomap.c
index 7429f8c..ffad039 100644
--- a/arch/arm/mm/iomap.c
+++ b/arch/arm/mm/iomap.c
@@ -7,8 +7,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
 #ifdef __io
 void __iomem *ioport_map(unsigned long port, unsigned int nr)
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index b81dbf9..18373f7 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -24,9 +24,10 @@
 #include <linux/errno.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
+#include <linux/io.h>
 
+#include <asm/cputype.h>
 #include <asm/cacheflush.h>
-#include <asm/io.h>
 #include <asm/mmu_context.h>
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
@@ -55,8 +56,7 @@
 		if (!pte_none(*pte))
 			goto bad;
 
-		set_pte_ext(pte, pfn_pte(phys_addr >> PAGE_SHIFT, prot),
-			    type->prot_pte_ext);
+		set_pte_ext(pte, pfn_pte(phys_addr >> PAGE_SHIFT, prot), 0);
 		phys_addr += PAGE_SIZE;
 	} while (pte++, addr += PAGE_SIZE, addr != end);
 	return 0;
@@ -332,15 +332,14 @@
 }
 EXPORT_SYMBOL(__arm_ioremap);
 
-void __iounmap(volatile void __iomem *addr)
+void __iounmap(volatile void __iomem *io_addr)
 {
+	void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr);
 #ifndef CONFIG_SMP
 	struct vm_struct **p, *tmp;
 #endif
 	unsigned int section_mapping = 0;
 
-	addr = (volatile void __iomem *)(PAGE_MASK & (unsigned long)addr);
-
 #ifndef CONFIG_SMP
 	/*
 	 * If this is a section based mapping we need to handle it
@@ -351,7 +350,7 @@
 	 */
 	write_lock(&vmlist_lock);
 	for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) {
-		if((tmp->flags & VM_IOREMAP) && (tmp->addr == addr)) {
+		if ((tmp->flags & VM_IOREMAP) && (tmp->addr == addr)) {
 			if (tmp->flags & VM_ARM_SECTION_MAPPING) {
 				*p = tmp->next;
 				unmap_area_sections((unsigned long)tmp->addr,
@@ -366,6 +365,6 @@
 #endif
 
 	if (!section_mapping)
-		vunmap((void __force *)addr);
+		vunmap(addr);
 }
 EXPORT_SYMBOL(__iounmap);
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index 7647c59..5d9f539 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -18,7 +18,6 @@
 
 struct mem_type {
 	unsigned int prot_pte;
-	unsigned int prot_pte_ext;
 	unsigned int prot_l1;
 	unsigned int prot_sect;
 	unsigned int domain;
@@ -35,3 +34,5 @@
 void __init create_mapping(struct map_desc *md);
 void __init bootmem_init(struct meminfo *mi);
 void reserve_node_zero(struct pglist_data *pgdat);
+
+extern void _text, _stext, _etext, __data_start, _end, __init_begin, __init_end;
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index 3f6dc40..5358fcc 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -6,6 +6,8 @@
 #include <linux/mman.h>
 #include <linux/shm.h>
 #include <linux/sched.h>
+#include <linux/io.h>
+#include <asm/cputype.h>
 #include <asm/system.h>
 
 #define COLOUR_ALIGN(addr,pgoff)		\
@@ -37,8 +39,8 @@
 	 * caches alias.  This is indicated by bits 9 and 21 of the
 	 * cache type register.
 	 */
-	cache_type = read_cpuid(CPUID_CACHETYPE);
-	if (cache_type != read_cpuid(CPUID_ID)) {
+	cache_type = read_cpuid_cachetype();
+	if (cache_type != read_cpuid_id()) {
 		aliasing = (cache_type | cache_type >> 12) & (1 << 11);
 		if (aliasing)
 			do_align = filp || flags & MAP_SHARED;
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 25d9a11..8ba7540 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -15,6 +15,7 @@
 #include <linux/mman.h>
 #include <linux/nodemask.h>
 
+#include <asm/cputype.h>
 #include <asm/mach-types.h>
 #include <asm/setup.h>
 #include <asm/sizes.h>
@@ -27,9 +28,6 @@
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
-extern void _stext, _etext, __data_start, _end;
-extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
-
 /*
  * empty_zero_page is a special page that is used for
  * zero-initialized data and COW.
@@ -68,27 +66,27 @@
 		.policy		= "uncached",
 		.cr_mask	= CR_W|CR_C,
 		.pmd		= PMD_SECT_UNCACHED,
-		.pte		= 0,
+		.pte		= L_PTE_MT_UNCACHED,
 	}, {
 		.policy		= "buffered",
 		.cr_mask	= CR_C,
 		.pmd		= PMD_SECT_BUFFERED,
-		.pte		= PTE_BUFFERABLE,
+		.pte		= L_PTE_MT_BUFFERABLE,
 	}, {
 		.policy		= "writethrough",
 		.cr_mask	= 0,
 		.pmd		= PMD_SECT_WT,
-		.pte		= PTE_CACHEABLE,
+		.pte		= L_PTE_MT_WRITETHROUGH,
 	}, {
 		.policy		= "writeback",
 		.cr_mask	= 0,
 		.pmd		= PMD_SECT_WB,
-		.pte		= PTE_BUFFERABLE|PTE_CACHEABLE,
+		.pte		= L_PTE_MT_WRITEBACK,
 	}, {
 		.policy		= "writealloc",
 		.cr_mask	= 0,
 		.pmd		= PMD_SECT_WBWA,
-		.pte		= PTE_BUFFERABLE|PTE_CACHEABLE,
+		.pte		= L_PTE_MT_WRITEALLOC,
 	}
 };
 
@@ -186,29 +184,28 @@
 
 static struct mem_type mem_types[] = {
 	[MT_DEVICE] = {		  /* Strongly ordered / ARMv6 shared device */
-		.prot_pte	= PROT_PTE_DEVICE,
+		.prot_pte	= PROT_PTE_DEVICE | L_PTE_MT_DEV_SHARED |
+				  L_PTE_SHARED,
 		.prot_l1	= PMD_TYPE_TABLE,
 		.prot_sect	= PROT_SECT_DEVICE | PMD_SECT_UNCACHED,
 		.domain		= DOMAIN_IO,
 	},
 	[MT_DEVICE_NONSHARED] = { /* ARMv6 non-shared device */
-		.prot_pte	= PROT_PTE_DEVICE,
-		.prot_pte_ext	= PTE_EXT_TEX(2),
+		.prot_pte	= PROT_PTE_DEVICE | L_PTE_MT_DEV_NONSHARED,
 		.prot_l1	= PMD_TYPE_TABLE,
 		.prot_sect	= PROT_SECT_DEVICE | PMD_SECT_TEX(2),
 		.domain		= DOMAIN_IO,
 	},
 	[MT_DEVICE_CACHED] = {	  /* ioremap_cached */
-		.prot_pte	= PROT_PTE_DEVICE | L_PTE_CACHEABLE | L_PTE_BUFFERABLE,
+		.prot_pte	= PROT_PTE_DEVICE | L_PTE_MT_DEV_CACHED,
 		.prot_l1	= PMD_TYPE_TABLE,
 		.prot_sect	= PROT_SECT_DEVICE | PMD_SECT_WB,
 		.domain		= DOMAIN_IO,
 	},	
-	[MT_DEVICE_IXP2000] = {	  /* IXP2400 requires XCB=101 for on-chip I/O */
-		.prot_pte	= PROT_PTE_DEVICE,
+	[MT_DEVICE_WC] = {	/* ioremap_wc */
+		.prot_pte	= PROT_PTE_DEVICE | L_PTE_MT_DEV_WC,
 		.prot_l1	= PMD_TYPE_TABLE,
-		.prot_sect	= PROT_SECT_DEVICE | PMD_SECT_BUFFERABLE |
-				  PMD_SECT_TEX(1),
+		.prot_sect	= PROT_SECT_DEVICE | PMD_SECT_BUFFERABLE,
 		.domain		= DOMAIN_IO,
 	},
 	[MT_CACHECLEAN] = {
@@ -253,7 +250,7 @@
 {
 	struct cachepolicy *cp;
 	unsigned int cr = get_cr();
-	unsigned int user_pgprot, kern_pgprot;
+	unsigned int user_pgprot, kern_pgprot, vecs_pgprot;
 	int cpu_arch = cpu_architecture();
 	int i;
 
@@ -271,6 +268,20 @@
 			cachepolicy = CPOLICY_WRITEBACK;
 		ecc_mask = 0;
 	}
+#ifdef CONFIG_SMP
+	cachepolicy = CPOLICY_WRITEALLOC;
+#endif
+
+	/*
+	 * On non-Xscale3 ARMv5-and-older systems, use CB=01
+	 * (Uncached/Buffered) for ioremap_wc() mappings.  On XScale3
+	 * and ARMv6+, use TEXCB=00100 mappings (Inner/Outer Uncacheable
+	 * in xsc3 parlance, Uncached Normal in ARMv6 parlance).
+	 */
+	if (cpu_is_xsc3() || cpu_arch >= CPU_ARCH_ARMv6) {
+		mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_TEX(1);
+		mem_types[MT_DEVICE_WC].prot_sect &= ~PMD_SECT_BUFFERABLE;
+	}
 
 	/*
 	 * ARMv5 and lower, bit 4 must be set for page tables.
@@ -292,7 +303,15 @@
 	}
 
 	cp = &cache_policies[cachepolicy];
-	kern_pgprot = user_pgprot = cp->pte;
+	vecs_pgprot = kern_pgprot = user_pgprot = cp->pte;
+
+#ifndef CONFIG_SMP
+	/*
+	 * Only use write-through for non-SMP systems
+	 */
+	if (cpu_arch >= CPU_ARCH_ARMv5 && cachepolicy > CPOLICY_WRITETHROUGH)
+		vecs_pgprot = cache_policies[CPOLICY_WRITETHROUGH].pte;
+#endif
 
 	/*
 	 * Enable CPU-specific coherency if supported.
@@ -320,7 +339,6 @@
 		/*
 		 * Mark the device area as "shared device"
 		 */
-		mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE;
 		mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED;
 
 #ifdef CONFIG_SMP
@@ -329,30 +347,21 @@
 		 */
 		user_pgprot |= L_PTE_SHARED;
 		kern_pgprot |= L_PTE_SHARED;
+		vecs_pgprot |= L_PTE_SHARED;
 		mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
 #endif
 	}
 
 	for (i = 0; i < 16; i++) {
 		unsigned long v = pgprot_val(protection_map[i]);
-		v = (v & ~(L_PTE_BUFFERABLE|L_PTE_CACHEABLE)) | user_pgprot;
-		protection_map[i] = __pgprot(v);
+		protection_map[i] = __pgprot(v | user_pgprot);
 	}
 
-	mem_types[MT_LOW_VECTORS].prot_pte |= kern_pgprot;
-	mem_types[MT_HIGH_VECTORS].prot_pte |= kern_pgprot;
+	mem_types[MT_LOW_VECTORS].prot_pte |= vecs_pgprot;
+	mem_types[MT_HIGH_VECTORS].prot_pte |= vecs_pgprot;
 
-	if (cpu_arch >= CPU_ARCH_ARMv5) {
-#ifndef CONFIG_SMP
-		/*
-		 * Only use write-through for non-SMP systems
-		 */
-		mem_types[MT_LOW_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE;
-		mem_types[MT_HIGH_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE;
-#endif
-	} else {
+	if (cpu_arch < CPU_ARCH_ARMv5)
 		mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1);
-	}
 
 	pgprot_user   = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | user_pgprot);
 	pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
@@ -400,8 +409,7 @@
 
 	pte = pte_offset_kernel(pmd, addr);
 	do {
-		set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)),
-			    type->prot_pte_ext);
+		set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), 0);
 		pfn++;
 	} while (pte++, addr += PAGE_SIZE, addr != end);
 }
@@ -568,12 +576,35 @@
 		create_mapping(io_desc + i);
 }
 
+static unsigned long __initdata vmalloc_reserve = SZ_128M;
+
+/*
+ * vmalloc=size forces the vmalloc area to be exactly 'size'
+ * bytes. This can be used to increase (or decrease) the vmalloc
+ * area - the default is 128m.
+ */
+static void __init early_vmalloc(char **arg)
+{
+	vmalloc_reserve = memparse(*arg, arg);
+
+	if (vmalloc_reserve < SZ_16M) {
+		vmalloc_reserve = SZ_16M;
+		printk(KERN_WARNING
+			"vmalloc area too small, limiting to %luMB\n",
+			vmalloc_reserve >> 20);
+	}
+}
+__early_param("vmalloc=", early_vmalloc);
+
+#define VMALLOC_MIN	(void *)(VMALLOC_END - vmalloc_reserve)
+
 static int __init check_membank_valid(struct membank *mb)
 {
 	/*
-	 * Check whether this memory region has non-zero size.
+	 * Check whether this memory region has non-zero size or
+	 * invalid node number.
 	 */
-	if (mb->size == 0)
+	if (mb->size == 0 || mb->node >= MAX_NUMNODES)
 		return 0;
 
 	/*
@@ -607,8 +638,7 @@
 
 static void __init sanity_check_meminfo(struct meminfo *mi)
 {
-	int i;
-	int j;
+	int i, j;
 
 	for (i = 0, j = 0; i < mi->nr_banks; i++) {
 		if (check_membank_valid(&mi->bank[i]))
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index 63c62fd..07b62b2 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -7,16 +7,14 @@
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/bootmem.h>
+#include <linux/io.h>
 
 #include <asm/cacheflush.h>
-#include <asm/io.h>
 #include <asm/page.h>
 #include <asm/mach/arch.h>
 
 #include "mm.h"
 
-extern void _stext, __data_start, _end;
-
 /*
  * Reserve the various regions of node 0
  */
@@ -43,12 +41,26 @@
 			BOOTMEM_DEFAULT);
 }
 
+static void __init sanity_check_meminfo(struct meminfo *mi)
+{
+	int i, j;
+
+	for (i = 0, j = 0; i < mi->nr_banks; i++) {
+		struct membank *mb = &mi->bank[i];
+
+		if (mb->size != 0 && mb->node < MAX_NUMNODES)
+			mi->bank[j++] = mi->bank[i];
+	}
+	mi->nr_banks = j;
+}
+
 /*
  * paging_init() sets up the page tables, initialises the zone memory
  * maps, and sets up the zero page, bad page and bad page tables.
  */
 void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc)
 {
+	sanity_check_meminfo(mi);
 	bootmem_init(mi);
 }
 
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index 5673f4d..b5551bf 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -29,7 +29,7 @@
 #include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/ptrace.h>
@@ -399,29 +399,7 @@
 	.align	5
 ENTRY(cpu_arm1020_set_pte_ext)
 #ifdef CONFIG_MMU
-	str	r1, [r0], #-2048		@ linux version
-
-	eor	r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
-
-	bic	r2, r1, #PTE_SMALL_AP_MASK
-	bic	r2, r2, #PTE_TYPE_MASK
-	orr	r2, r2, #PTE_TYPE_SMALL
-
-	tst	r1, #L_PTE_USER			@ User?
-	orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
-
-	tst	r1, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
-	orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
-
-	tst	r1, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
-	movne	r2, #0
-
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	eor	r3, r1, #0x0a			@ C & small page?
-	tst	r3, #0x0b
-	biceq	r2, r2, #4
-#endif
-	str	r2, [r0]			@ hardware version
+	armv3_set_pte_ext
 	mov	r0, r0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
 	mcr	p15, 0, r0, c7, c10, 4
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index 4343fdb..8bc6740 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -29,7 +29,7 @@
 #include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/ptrace.h>
@@ -383,29 +383,7 @@
 	.align	5
 ENTRY(cpu_arm1020e_set_pte_ext)
 #ifdef CONFIG_MMU
-	str	r1, [r0], #-2048		@ linux version
-
-	eor	r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
-
-	bic	r2, r1, #PTE_SMALL_AP_MASK
-	bic	r2, r2, #PTE_TYPE_MASK
-	orr	r2, r2, #PTE_TYPE_SMALL
-
-	tst	r1, #L_PTE_USER			@ User?
-	orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
-
-	tst	r1, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
-	orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
-
-	tst	r1, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
-	movne	r2, #0
-
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	eor	r3, r1, #0x0a			@ C & small page?
-	tst	r3, #0x0b
-	biceq	r2, r2, #4
-#endif
-	str	r2, [r0]			@ hardware version
+	armv3_set_pte_ext
 	mov	r0, r0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index 2a4ea16..2cd03e6 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -18,7 +18,7 @@
 #include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/ptrace.h>
@@ -365,29 +365,7 @@
 	.align	5
 ENTRY(cpu_arm1022_set_pte_ext)
 #ifdef CONFIG_MMU
-	str	r1, [r0], #-2048		@ linux version
-
-	eor	r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
-
-	bic	r2, r1, #PTE_SMALL_AP_MASK
-	bic	r2, r2, #PTE_TYPE_MASK
-	orr	r2, r2, #PTE_TYPE_SMALL
-
-	tst	r1, #L_PTE_USER			@ User?
-	orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
-
-	tst	r1, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
-	orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
-
-	tst	r1, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
-	movne	r2, #0
-
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	eor	r3, r1, #0x0a			@ C & small page?
-	tst	r3, #0x0b
-	biceq	r2, r2, #4
-#endif
-	str	r2, [r0]			@ hardware version
+	armv3_set_pte_ext
 	mov	r0, r0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index 77a1bab..ad961a8 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -18,7 +18,7 @@
 #include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/ptrace.h>
@@ -354,29 +354,7 @@
 	.align	5
 ENTRY(cpu_arm1026_set_pte_ext)
 #ifdef CONFIG_MMU
-	str	r1, [r0], #-2048		@ linux version
-
-	eor	r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
-
-	bic	r2, r1, #PTE_SMALL_AP_MASK
-	bic	r2, r2, #PTE_TYPE_MASK
-	orr	r2, r2, #PTE_TYPE_SMALL
-
-	tst	r1, #L_PTE_USER			@ User?
-	orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
-
-	tst	r1, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
-	orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
-
-	tst	r1, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
-	movne	r2, #0
-
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	eor	r3, r1, #0x0a			@ C & small page?
-	tst	r3, #0x0b
-	biceq	r2, r2, #4
-#endif
-	str	r2, [r0]			@ hardware version
+	armv3_set_pte_ext
 	mov	r0, r0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index c371fc8..80d6e1d 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -15,11 +15,13 @@
 #include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/ptrace.h>
 
+#include "proc-macros.S"
+
 ENTRY(cpu_arm6_dcache_clean_area)
 ENTRY(cpu_arm7_dcache_clean_area)
 		mov	pc, lr
@@ -214,30 +216,13 @@
  *	   : r1 = value to set
  * Purpose : Set a PTE and flush it out of any WB cache
  */
-		.align	5
+	.align	5
 ENTRY(cpu_arm6_set_pte_ext)
 ENTRY(cpu_arm7_set_pte_ext)
 #ifdef CONFIG_MMU
-		str	r1, [r0], #-2048		@ linux version
-
-		eor	r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
-
-		bic	r2, r1, #PTE_SMALL_AP_MASK
-		bic	r2, r2, #PTE_TYPE_MASK
-		orr	r2, r2, #PTE_TYPE_SMALL
-
-		tst	r1, #L_PTE_USER			@ User?
-		orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
-
-		tst	r1, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
-		orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
-
-		tst	r1, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young
-		movne	r2, #0
-
-		str	r2, [r0]			@ hardware version
+	armv3_set_pte_ext wc_disable=0
 #endif /* CONFIG_MMU */
-		mov	pc, lr
+	mov	pc, lr
 
 /*
  * Function: _arm6_7_reset
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index eda733d..85ae186 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -36,7 +36,7 @@
 #include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/ptrace.h>
@@ -93,29 +93,12 @@
  *	   : r1 = value to set
  * Purpose : Set a PTE and flush it out of any WB cache
  */
-		.align	5
+	.align	5
 ENTRY(cpu_arm720_set_pte_ext)
 #ifdef CONFIG_MMU
-		str	r1, [r0], #-2048		@ linux version
-
-		eor	r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
-
-		bic	r2, r1, #PTE_SMALL_AP_MASK
-		bic	r2, r2, #PTE_TYPE_MASK
-		orr	r2, r2, #PTE_TYPE_SMALL
-
-		tst	r1, #L_PTE_USER			@ User?
-		orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
-
-		tst	r1, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
-		orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
-
-		tst	r1, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young
-		movne	r2, #0
-
-		str	r2, [r0]			@ hardware version
+	armv3_set_pte_ext wc_disable=0
 #endif
-		mov	pc, lr
+	mov	pc, lr
 
 /*
  * Function: arm720_reset
diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S
index 3a57376..4f95bee 100644
--- a/arch/arm/mm/proc-arm740.S
+++ b/arch/arm/mm/proc-arm740.S
@@ -12,7 +12,7 @@
 #include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/ptrace.h>
diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S
index 7b3ecde..93e05fa 100644
--- a/arch/arm/mm/proc-arm7tdmi.S
+++ b/arch/arm/mm/proc-arm7tdmi.S
@@ -12,7 +12,7 @@
 #include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/ptrace.h>
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 28cdb06..914d688 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -28,7 +28,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/assembler.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
@@ -351,33 +351,11 @@
 	.align	5
 ENTRY(cpu_arm920_set_pte_ext)
 #ifdef CONFIG_MMU
-	str	r1, [r0], #-2048		@ linux version
-
-	eor	r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
-
-	bic	r2, r1, #PTE_SMALL_AP_MASK
-	bic	r2, r2, #PTE_TYPE_MASK
-	orr	r2, r2, #PTE_TYPE_SMALL
-
-	tst	r1, #L_PTE_USER			@ User?
-	orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
-
-	tst	r1, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
-	orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
-
-	tst	r1, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
-	movne	r2, #0
-
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	eor	r3, r2, #0x0a			@ C & small page?
-	tst	r3, #0x0b
-	biceq	r2, r2, #4
-#endif
-	str	r2, [r0]			@ hardware version
+	armv3_set_pte_ext
 	mov	r0, r0
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
-#endif /* CONFIG_MMU */
+#endif
 	mov	pc, lr
 
 	__INIT
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index 94ddcb4..51c9c98 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -29,7 +29,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/assembler.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
@@ -355,29 +355,7 @@
 	.align	5
 ENTRY(cpu_arm922_set_pte_ext)
 #ifdef CONFIG_MMU
-	str	r1, [r0], #-2048		@ linux version
-
-	eor	r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
-
-	bic	r2, r1, #PTE_SMALL_AP_MASK
-	bic	r2, r2, #PTE_TYPE_MASK
-	orr	r2, r2, #PTE_TYPE_SMALL
-
-	tst	r1, #L_PTE_USER			@ User?
-	orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
-
-	tst	r1, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
-	orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
-
-	tst	r1, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
-	movne	r2, #0
-
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	eor	r3, r2, #0x0a			@ C & small page?
-	tst	r3, #0x0b
-	biceq	r2, r2, #4
-#endif
-	str	r2, [r0]			@ hardware version
+	armv3_set_pte_ext
 	mov	r0, r0
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index d045812..2724526 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -52,7 +52,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/assembler.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
@@ -398,29 +398,7 @@
 	.align	5
 ENTRY(cpu_arm925_set_pte_ext)
 #ifdef CONFIG_MMU
-	str	r1, [r0], #-2048		@ linux version
-
-	eor	r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
-
-	bic	r2, r1, #PTE_SMALL_AP_MASK
-	bic	r2, r2, #PTE_TYPE_MASK
-	orr	r2, r2, #PTE_TYPE_SMALL
-
-	tst	r1, #L_PTE_USER			@ User?
-	orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
-
-	tst	r1, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
-	orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
-
-	tst	r1, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
-	movne	r2, #0
-
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	eor	r3, r2, #0x0a			@ C & small page?
-	tst	r3, #0x0b
-	biceq	r2, r2, #4
-#endif
-	str	r2, [r0]			@ hardware version
+	armv3_set_pte_ext
 	mov	r0, r0
 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 4cd3316..5446693 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -28,7 +28,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/assembler.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
@@ -359,29 +359,7 @@
 	.align	5
 ENTRY(cpu_arm926_set_pte_ext)
 #ifdef CONFIG_MMU
-	str	r1, [r0], #-2048		@ linux version
-
-	eor	r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
-
-	bic	r2, r1, #PTE_SMALL_AP_MASK
-	bic	r2, r2, #PTE_TYPE_MASK
-	orr	r2, r2, #PTE_TYPE_SMALL
-
-	tst	r1, #L_PTE_USER			@ User?
-	orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
-
-	tst	r1, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
-	orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
-
-	tst	r1, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
-	movne	r2, #0
-
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	eor	r3, r2, #0x0a			@ C & small page?
-	tst	r3, #0x0b
-	biceq	r2, r2, #4
-#endif
-	str	r2, [r0]			@ hardware version
+	armv3_set_pte_ext
 	mov	r0, r0
 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
index 551244d..f595117 100644
--- a/arch/arm/mm/proc-arm940.S
+++ b/arch/arm/mm/proc-arm940.S
@@ -11,7 +11,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/assembler.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/ptrace.h>
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
index 6168c61..e03f6ff 100644
--- a/arch/arm/mm/proc-arm946.S
+++ b/arch/arm/mm/proc-arm946.S
@@ -13,7 +13,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/assembler.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/ptrace.h>
diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S
index c85c1f5..be6c11d 100644
--- a/arch/arm/mm/proc-arm9tdmi.S
+++ b/arch/arm/mm/proc-arm9tdmi.S
@@ -12,7 +12,7 @@
 #include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/ptrace.h>
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index f2e5884..0fe1f8f 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -22,7 +22,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/assembler.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
@@ -80,7 +80,8 @@
 	msr	cpsr_c, ip
 	bl	feroceon_flush_kern_cache_all
 
-#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH)
+#if defined(CONFIG_CACHE_FEROCEON_L2) && \
+	!defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
 	mov	r0, #0
 	mcr	p15, 1, r0, c15, c9, 0		@ clean L2
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
@@ -389,7 +390,8 @@
 
 	.align	5
 ENTRY(cpu_feroceon_dcache_clean_area)
-#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH)
+#if defined(CONFIG_CACHE_FEROCEON_L2) && \
+	!defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
 	mov	r2, r0
 	mov	r3, r1
 #endif
@@ -397,7 +399,8 @@
 	add	r0, r0, #CACHE_DLINESIZE
 	subs	r1, r1, #CACHE_DLINESIZE
 	bhi	1b
-#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH)
+#if defined(CONFIG_CACHE_FEROCEON_L2) && \
+	!defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
 1:	mcr	p15, 1, r2, c15, c9, 1		@ clean L2 entry
 	add	r2, r2, #CACHE_DLINESIZE
 	subs	r3, r3, #CACHE_DLINESIZE
@@ -446,27 +449,11 @@
 	.align	5
 ENTRY(cpu_feroceon_set_pte_ext)
 #ifdef CONFIG_MMU
-	str	r1, [r0], #-2048		@ linux version
-
-	eor	r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
-
-	bic	r2, r1, #PTE_SMALL_AP_MASK
-	bic	r2, r2, #PTE_TYPE_MASK
-	orr	r2, r2, #PTE_TYPE_SMALL
-
-	tst	r1, #L_PTE_USER			@ User?
-	orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
-
-	tst	r1, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
-	orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
-
-	tst	r1, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
-	movne	r2, #0
-
-	str	r2, [r0]			@ hardware version
+	armv3_set_pte_ext wc_disable=0
 	mov	r0, r0
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
-#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH)
+#if defined(CONFIG_CACHE_FEROCEON_L2) && \
+	!defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
 	mcr	p15, 1, r0, c15, c9, 1		@ clean L2 entry
 #endif
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index b131500..54b1f72 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -71,3 +71,173 @@
 	mov	\reg, #16			@ size offset
 	mov	\reg, \reg, lsl \tmp		@ actual cache line size
 	.endm
+
+
+/*
+ * Sanity check the PTE configuration for the code below - which makes
+ * certain assumptions about how these bits are layed out.
+ */
+#if L_PTE_SHARED != PTE_EXT_SHARED
+#error PTE shared bit mismatch
+#endif
+#if L_PTE_BUFFERABLE != PTE_BUFFERABLE
+#error PTE bufferable bit mismatch
+#endif
+#if L_PTE_CACHEABLE != PTE_CACHEABLE
+#error PTE cacheable bit mismatch
+#endif
+#if (L_PTE_EXEC+L_PTE_USER+L_PTE_WRITE+L_PTE_DIRTY+L_PTE_YOUNG+\
+     L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED
+#error Invalid Linux PTE bit settings
+#endif
+
+/*
+ * The ARMv6 and ARMv7 set_pte_ext translation function.
+ *
+ * Permission translation:
+ *  YUWD  APX AP1 AP0	SVC	User
+ *  0xxx   0   0   0	no acc	no acc
+ *  100x   1   0   1	r/o	no acc
+ *  10x0   1   0   1	r/o	no acc
+ *  1011   0   0   1	r/w	no acc
+ *  110x   0   1   0	r/w	r/o
+ *  11x0   0   1   0	r/w	r/o
+ *  1111   0   1   1	r/w	r/w
+ */
+	.macro	armv6_mt_table pfx
+\pfx\()_mt_table:
+	.long	0x00						@ L_PTE_MT_UNCACHED
+	.long	PTE_EXT_TEX(1)					@ L_PTE_MT_BUFFERABLE
+	.long	PTE_CACHEABLE					@ L_PTE_MT_WRITETHROUGH
+	.long	PTE_CACHEABLE | PTE_BUFFERABLE			@ L_PTE_MT_WRITEBACK
+	.long	PTE_BUFFERABLE					@ L_PTE_MT_DEV_SHARED
+	.long	0x00						@ unused
+	.long	0x00						@ L_PTE_MT_MINICACHE (not present)
+	.long	PTE_EXT_TEX(1) | PTE_CACHEABLE | PTE_BUFFERABLE	@ L_PTE_MT_WRITEALLOC
+	.long	0x00						@ unused
+	.long	PTE_EXT_TEX(1)					@ L_PTE_MT_DEV_WC
+	.long	0x00						@ unused
+	.long	PTE_CACHEABLE | PTE_BUFFERABLE			@ L_PTE_MT_DEV_CACHED
+	.long	PTE_EXT_TEX(2)					@ L_PTE_MT_DEV_NONSHARED
+	.long	0x00						@ unused
+	.long	0x00						@ unused
+	.long	0x00						@ unused
+	.endm
+
+	.macro	armv6_set_pte_ext pfx
+	str	r1, [r0], #-2048		@ linux version
+
+	bic	r3, r1, #0x000003fc
+	bic	r3, r3, #PTE_TYPE_MASK
+	orr	r3, r3, r2
+	orr	r3, r3, #PTE_EXT_AP0 | 2
+
+	adr	ip, \pfx\()_mt_table
+	and	r2, r1, #L_PTE_MT_MASK
+	ldr	r2, [ip, r2]
+
+	tst	r1, #L_PTE_WRITE
+	tstne	r1, #L_PTE_DIRTY
+	orreq	r3, r3, #PTE_EXT_APX
+
+	tst	r1, #L_PTE_USER
+	orrne	r3, r3, #PTE_EXT_AP1
+	tstne	r3, #PTE_EXT_APX
+	bicne	r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
+
+	tst	r1, #L_PTE_EXEC
+	orreq	r3, r3, #PTE_EXT_XN
+
+	orr	r3, r3, r2
+
+	tst	r1, #L_PTE_YOUNG
+	tstne	r1, #L_PTE_PRESENT
+	moveq	r3, #0
+
+	str	r3, [r0]
+	mcr	p15, 0, r0, c7, c10, 1		@ flush_pte
+	.endm
+
+
+/*
+ * The ARMv3, ARMv4 and ARMv5 set_pte_ext translation function,
+ * covering most CPUs except Xscale and Xscale 3.
+ *
+ * Permission translation:
+ *  YUWD   AP	SVC	User
+ *  0xxx  0x00	no acc	no acc
+ *  100x  0x00	r/o	no acc
+ *  10x0  0x00	r/o	no acc
+ *  1011  0x55	r/w	no acc
+ *  110x  0xaa	r/w	r/o
+ *  11x0  0xaa	r/w	r/o
+ *  1111  0xff	r/w	r/w
+ */
+	.macro	armv3_set_pte_ext wc_disable=1
+	str	r1, [r0], #-2048		@ linux version
+
+	eor	r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+
+	bic	r2, r1, #PTE_SMALL_AP_MASK	@ keep C, B bits
+	bic	r2, r2, #PTE_TYPE_MASK
+	orr	r2, r2, #PTE_TYPE_SMALL
+
+	tst	r3, #L_PTE_USER			@ user?
+	orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
+
+	tst	r3, #L_PTE_WRITE | L_PTE_DIRTY	@ write and dirty?
+	orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
+
+	tst	r3, #L_PTE_PRESENT | L_PTE_YOUNG	@ present and young?
+	movne	r2, #0
+
+	.if	\wc_disable
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	tst	r2, #PTE_CACHEABLE
+	bicne	r2, r2, #PTE_BUFFERABLE
+#endif
+	.endif
+	str	r2, [r0]			@ hardware version
+	.endm
+
+
+/*
+ * Xscale set_pte_ext translation, split into two halves to cope
+ * with work-arounds.  r3 must be preserved by code between these
+ * two macros.
+ *
+ * Permission translation:
+ *  YUWD  AP	SVC	User
+ *  0xxx  00	no acc	no acc
+ *  100x  00	r/o	no acc
+ *  10x0  00	r/o	no acc
+ *  1011  01	r/w	no acc
+ *  110x  10	r/w	r/o
+ *  11x0  10	r/w	r/o
+ *  1111  11	r/w	r/w
+ */
+	.macro	xscale_set_pte_ext_prologue
+	str	r1, [r0], #-2048		@ linux version
+
+	eor	r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+
+	bic	r2, r1, #PTE_SMALL_AP_MASK	@ keep C, B bits
+	orr	r2, r2, #PTE_TYPE_EXT		@ extended page
+
+	tst	r3, #L_PTE_USER			@ user?
+	orrne	r2, r2, #PTE_EXT_AP_URO_SRW	@ yes -> user r/o, system r/w
+
+	tst	r3, #L_PTE_WRITE | L_PTE_DIRTY	@ write and dirty?
+	orreq	r2, r2, #PTE_EXT_AP_UNO_SRW	@ yes -> user n/a, system r/w
+						@ combined with user -> user r/w
+	.endm
+
+	.macro	xscale_set_pte_ext_epilogue
+	tst	r3, #L_PTE_PRESENT | L_PTE_YOUNG	@ present and young?
+	movne	r2, #0				@ no -> fault
+
+	str	r2, [r0]			@ hardware version
+	mov	ip, #0
+	mcr	p15, 0, r0, c7, c10, 1		@ clean L1 D line
+	mcr	p15, 0, ip, c7, c10, 4		@ data write barrier
+	.endm
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index bbe1057..90a7e52 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -17,7 +17,7 @@
 #include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <mach/hardware.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
@@ -153,24 +153,7 @@
 	.align	5
 ENTRY(cpu_sa110_set_pte_ext)
 #ifdef CONFIG_MMU
-	str	r1, [r0], #-2048		@ linux version
-
-	eor	r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
-
-	bic	r2, r1, #PTE_SMALL_AP_MASK
-	bic	r2, r2, #PTE_TYPE_MASK
-	orr	r2, r2, #PTE_TYPE_SMALL
-
-	tst	r1, #L_PTE_USER			@ User?
-	orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
-
-	tst	r1, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
-	orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
-
-	tst	r1, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
-	movne	r2, #0
-
-	str	r2, [r0]			@ hardware version
+	armv3_set_pte_ext wc_disable=0
 	mov	r0, r0
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 871ba01..451e2d9 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -22,7 +22,7 @@
 #include <linux/init.h>
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <mach/hardware.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
@@ -166,24 +166,7 @@
 	.align	5
 ENTRY(cpu_sa1100_set_pte_ext)
 #ifdef CONFIG_MMU
-	str	r1, [r0], #-2048		@ linux version
-
-	eor	r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
-
-	bic	r2, r1, #PTE_SMALL_AP_MASK
-	bic	r2, r2, #PTE_TYPE_MASK
-	orr	r2, r2, #PTE_TYPE_SMALL
-
-	tst	r1, #L_PTE_USER			@ User?
-	orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
-
-	tst	r1, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
-	orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
-
-	tst	r1, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
-	movne	r2, #0
-
-	str	r2, [r0]			@ hardware version
+	armv3_set_pte_ext wc_disable=0
 	mov	r0, r0
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 5702ec5..294943b 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -13,7 +13,7 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 
@@ -114,46 +114,12 @@
  *		  (hardware version is stored at -1024 bytes)
  *	- pte   - PTE value to store
  *	- ext	- value for extended PTE bits
- *
- *	Permissions:
- *	  YUWD  APX AP1 AP0	SVC	User
- *	  0xxx   0   0   0	no acc	no acc
- *	  100x   1   0   1	r/o	no acc
- *	  10x0   1   0   1	r/o	no acc
- *	  1011   0   0   1	r/w	no acc
- *	  110x   0   1   0	r/w	r/o
- *	  11x0   0   1   0	r/w	r/o
- *	  1111   0   1   1	r/w	r/w
  */
+	armv6_mt_table cpu_v6
+
 ENTRY(cpu_v6_set_pte_ext)
 #ifdef CONFIG_MMU
-	str	r1, [r0], #-2048		@ linux version
-
-	bic	r3, r1, #0x000003f0
-	bic	r3, r3, #0x00000003
-	orr	r3, r3, r2
-	orr	r3, r3, #PTE_EXT_AP0 | 2
-
-	tst	r1, #L_PTE_WRITE
-	tstne	r1, #L_PTE_DIRTY
-	orreq	r3, r3, #PTE_EXT_APX
-
-	tst	r1, #L_PTE_USER
-	orrne	r3, r3, #PTE_EXT_AP1
-	tstne	r3, #PTE_EXT_APX
-	bicne	r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
-
-	tst	r1, #L_PTE_YOUNG
-	biceq	r3, r3, #PTE_EXT_APX | PTE_EXT_AP_MASK
-
-	tst	r1, #L_PTE_EXEC
-	orreq	r3, r3, #PTE_EXT_XN
-
-	tst	r1, #L_PTE_PRESENT
-	moveq	r3, #0
-
-	str	r3, [r0]
-	mcr	p15, 0, r0, c7, c10, 1 @ flush_pte
+	armv6_set_pte_ext cpu_v6
 #endif
 	mov	pc, lr
 
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index b49f9a4..34e4240 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -12,7 +12,7 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 
@@ -25,9 +25,11 @@
 
 ENTRY(cpu_v7_proc_init)
 	mov	pc, lr
+ENDPROC(cpu_v7_proc_init)
 
 ENTRY(cpu_v7_proc_fin)
 	mov	pc, lr
+ENDPROC(cpu_v7_proc_fin)
 
 /*
  *	cpu_v7_reset(loc)
@@ -43,6 +45,7 @@
 	.align	5
 ENTRY(cpu_v7_reset)
 	mov	pc, r0
+ENDPROC(cpu_v7_reset)
 
 /*
  *	cpu_v7_do_idle()
@@ -52,8 +55,9 @@
  *	IRQs are already disabled.
  */
 ENTRY(cpu_v7_do_idle)
-	.long	0xe320f003			@ ARM V7 WFI instruction
+	wfi
 	mov	pc, lr
+ENDPROC(cpu_v7_do_idle)
 
 ENTRY(cpu_v7_dcache_clean_area)
 #ifndef TLB_CAN_READ_FROM_L1_CACHE
@@ -65,6 +69,7 @@
 	dsb
 #endif
 	mov	pc, lr
+ENDPROC(cpu_v7_dcache_clean_area)
 
 /*
  *	cpu_v7_switch_mm(pgd_phys, tsk)
@@ -89,6 +94,7 @@
 	isb
 #endif
 	mov	pc, lr
+ENDPROC(cpu_v7_switch_mm)
 
 /*
  *	cpu_v7_set_pte_ext(ptep, pte)
@@ -99,26 +105,19 @@
  *		  (hardware version is stored at -1024 bytes)
  *	- pte   - PTE value to store
  *	- ext	- value for extended PTE bits
- *
- *	Permissions:
- *	  YUWD  APX AP1 AP0	SVC	User
- *	  0xxx   0   0   0	no acc	no acc
- *	  100x   1   0   1	r/o	no acc
- *	  10x0   1   0   1	r/o	no acc
- *	  1011   0   0   1	r/w	no acc
- *	  110x   0   1   0	r/w	r/o
- *	  11x0   0   1   0	r/w	r/o
- *	  1111   0   1   1	r/w	r/w
  */
 ENTRY(cpu_v7_set_pte_ext)
 #ifdef CONFIG_MMU
 	str	r1, [r0], #-2048		@ linux version
 
 	bic	r3, r1, #0x000003f0
-	bic	r3, r3, #0x00000003
+	bic	r3, r3, #PTE_TYPE_MASK
 	orr	r3, r3, r2
 	orr	r3, r3, #PTE_EXT_AP0 | 2
 
+	tst	r2, #1 << 4
+	orrne	r3, r3, #PTE_EXT_TEX(1)
+
 	tst	r1, #L_PTE_WRITE
 	tstne	r1, #L_PTE_DIRTY
 	orreq	r3, r3, #PTE_EXT_APX
@@ -128,19 +127,18 @@
 	tstne	r3, #PTE_EXT_APX
 	bicne	r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
 
-	tst	r1, #L_PTE_YOUNG
-	biceq	r3, r3, #PTE_EXT_APX | PTE_EXT_AP_MASK
-
 	tst	r1, #L_PTE_EXEC
 	orreq	r3, r3, #PTE_EXT_XN
 
-	tst	r1, #L_PTE_PRESENT
+	tst	r1, #L_PTE_YOUNG
+	tstne	r1, #L_PTE_PRESENT
 	moveq	r3, #0
 
 	str	r3, [r0]
 	mcr	p15, 0, r0, c7, c10, 1		@ flush_pte
 #endif
 	mov	pc, lr
+ENDPROC(cpu_v7_set_pte_ext)
 
 cpu_v7_name:
 	.ascii	"ARMv7 Processor"
@@ -182,12 +180,17 @@
 	mov	r10, #0x1f			@ domains 0, 1 = manager
 	mcr	p15, 0, r10, c3, c0, 0		@ load domain access register
 #endif
+	ldr	r5, =0x40e040e0
+	ldr	r6, =0xff0aa1a8
+	mcr	p15, 0, r5, c10, c2, 0		@ write PRRR
+	mcr	p15, 0, r6, c10, c2, 1		@ write NMRR
 	adr	r5, v7_crval
 	ldmia	r5, {r5, r6}
    	mrc	p15, 0, r0, c1, c0, 0		@ read control register
 	bic	r0, r0, r5			@ clear bits them
 	orr	r0, r0, r6			@ set them
 	mov	pc, lr				@ return to head.S:__ret
+ENDPROC(__v7_setup)
 
 	/*
 	 *         V X F   I D LR
@@ -197,7 +200,7 @@
 	 */
 	.type	v7_crval, #object
 v7_crval:
-	crval	clear=0x0120c302, mmuset=0x00c0387d, ucset=0x00c0187c
+	crval	clear=0x0120c302, mmuset=0x10c0387d, ucset=0x00c0187c
 
 __v7_setup_stack:
 	.space	4 * 11				@ 11 registers
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index 7bd9e71..04dc8b6 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -27,7 +27,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/assembler.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <mach/hardware.h>
 #include <asm/pgtable.h>
 #include <asm/pgtable-hwdef.h>
@@ -345,38 +345,38 @@
  * cpu_xsc3_set_pte_ext(ptep, pte, ext)
  *
  * Set a PTE and flush it out
- *
  */
+cpu_xsc3_mt_table:
+	.long	0x00						@ L_PTE_MT_UNCACHED
+	.long	PTE_EXT_TEX(1)					@ L_PTE_MT_BUFFERABLE
+	.long	PTE_CACHEABLE					@ L_PTE_MT_WRITETHROUGH
+	.long	PTE_CACHEABLE | PTE_BUFFERABLE			@ L_PTE_MT_WRITEBACK
+	.long	PTE_EXT_TEX(1) | PTE_BUFFERABLE			@ L_PTE_MT_DEV_SHARED
+	.long	0x00						@ unused
+	.long	0x00						@ L_PTE_MT_MINICACHE (not present)
+	.long	PTE_EXT_TEX(5) | PTE_CACHEABLE | PTE_BUFFERABLE	@ L_PTE_MT_WRITEALLOC (not present?)
+	.long	0x00						@ unused
+	.long	PTE_EXT_TEX(1)					@ L_PTE_MT_DEV_WC
+	.long	0x00						@ unused
+	.long	PTE_CACHEABLE | PTE_BUFFERABLE			@ L_PTE_MT_DEV_CACHED
+	.long	PTE_EXT_TEX(2)					@ L_PTE_MT_DEV_NONSHARED
+	.long	0x00						@ unused
+	.long	0x00						@ unused
+	.long	0x00						@ unused
+
 	.align	5
 ENTRY(cpu_xsc3_set_pte_ext)
-	str	r1, [r0], #-2048		@ linux version
+	xscale_set_pte_ext_prologue
 
-	bic	r2, r1, #0xff0			@ keep C, B bits
-	orr	r2, r2, #PTE_TYPE_EXT		@ extended page
 	tst	r1, #L_PTE_SHARED		@ shared?
-	orrne	r2, r2, #0x200
+	and	r1, r1, #L_PTE_MT_MASK
+	adr	ip, cpu_xsc3_mt_table
+	ldr	ip, [ip, r1]
+	orrne	r2, r2, #PTE_EXT_COHERENT	@ interlock: mask in coherent bit
+	bic	r2, r2, #0x0c			@ clear old C,B bits
+	orr	r2, r2, ip
 
-	eor	r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
-
-	tst	r3, #L_PTE_USER			@ user?
-	orrne	r2, r2, #PTE_EXT_AP_URO_SRW	@ yes -> user r/o, system r/w
-
-	tst	r3, #L_PTE_WRITE | L_PTE_DIRTY	@ write and dirty?
-	orreq	r2, r2, #PTE_EXT_AP_UNO_SRW	@ yes -> user n/a, system r/w
-						@ combined with user -> user r/w
-
-	@ If it's cacheable, it needs to be in L2 also.
-	eor	ip, r1, #L_PTE_CACHEABLE
-	tst	ip, #L_PTE_CACHEABLE
-	orreq	r2, r2, #PTE_EXT_TEX(0x5)
-
-	tst	r3, #L_PTE_PRESENT | L_PTE_YOUNG	@ present and young?
-	movne	r2, #0				@ no -> fault
-
-	str	r2, [r0]			@ hardware version
-	mov	ip, #0
-	mcr	p15, 0, r0, c7, c10, 1		@ clean L1 D line
-	mcr	p15, 0, ip, c7, c10, 4		@ data write barrier
+	xscale_set_pte_ext_epilogue
 	mov	pc, lr
 
 	.ltorg
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 2dd8527..0cce37b 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -23,7 +23,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/assembler.h>
-#include <asm/elf.h>
+#include <asm/hwcap.h>
 #include <asm/pgtable.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/page.h>
@@ -406,8 +406,6 @@
 
 /* =============================== PageTable ============================== */
 
-#define PTE_CACHE_WRITE_ALLOCATE 0
-
 /*
  * cpu_xscale_switch_mm(pgd)
  *
@@ -431,56 +429,42 @@
  *
  * Errata 40: must set memory to write-through for user read-only pages.
  */
+cpu_xscale_mt_table:
+	.long	0x00						@ L_PTE_MT_UNCACHED
+	.long	PTE_BUFFERABLE					@ L_PTE_MT_BUFFERABLE
+	.long	PTE_CACHEABLE					@ L_PTE_MT_WRITETHROUGH
+	.long	PTE_CACHEABLE | PTE_BUFFERABLE			@ L_PTE_MT_WRITEBACK
+	.long	PTE_EXT_TEX(1) | PTE_BUFFERABLE			@ L_PTE_MT_DEV_SHARED
+	.long	0x00						@ unused
+	.long	PTE_EXT_TEX(1) | PTE_CACHEABLE			@ L_PTE_MT_MINICACHE
+	.long	PTE_EXT_TEX(1) | PTE_CACHEABLE | PTE_BUFFERABLE	@ L_PTE_MT_WRITEALLOC
+	.long	0x00						@ unused
+	.long	PTE_BUFFERABLE					@ L_PTE_MT_DEV_WC
+	.long	0x00						@ unused
+	.long	PTE_CACHEABLE | PTE_BUFFERABLE			@ L_PTE_MT_DEV_CACHED
+	.long	0x00						@ L_PTE_MT_DEV_NONSHARED
+	.long	0x00						@ unused
+	.long	0x00						@ unused
+	.long	0x00						@ unused
+
 	.align	5
 ENTRY(cpu_xscale_set_pte_ext)
-	str	r1, [r0], #-2048		@ linux version
-
-	bic	r2, r1, #0xff0
-	orr	r2, r2, #PTE_TYPE_EXT		@ extended page
-
-	eor	r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
-
-	tst	r3, #L_PTE_USER			@ User?
-	orrne	r2, r2, #PTE_EXT_AP_URO_SRW	@ yes -> user r/o, system r/w
-
-	tst	r3, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
-	orreq	r2, r2, #PTE_EXT_AP_UNO_SRW	@ yes -> user n/a, system r/w
-						@ combined with user -> user r/w
+	xscale_set_pte_ext_prologue
 
 	@
-	@ Handle the X bit.  We want to set this bit for the minicache
-	@ (U = E = B = W = 0, C = 1) or when write allocate is enabled,
-	@ and we have a writeable, cacheable region.  If we ignore the
-	@ U and E bits, we can allow user space to use the minicache as
-	@ well.
+	@ Erratum 40: must set memory to write-through for user read-only pages
 	@
-	@  X = (C & ~W & ~B) | (C & W & B & write_allocate)
-	@
-	eor	ip, r1, #L_PTE_CACHEABLE
-	tst	ip, #L_PTE_CACHEABLE | L_PTE_WRITE | L_PTE_BUFFERABLE
-#if PTE_CACHE_WRITE_ALLOCATE
-	eorne	ip, r1, #L_PTE_CACHEABLE | L_PTE_WRITE | L_PTE_BUFFERABLE
-	tstne	ip, #L_PTE_CACHEABLE | L_PTE_WRITE | L_PTE_BUFFERABLE
-#endif
-	orreq	r2, r2, #PTE_EXT_TEX(1)
+	and	ip, r1, #(L_PTE_MT_MASK | L_PTE_USER | L_PTE_WRITE) & ~(4 << 2)
+	teq	ip, #L_PTE_MT_WRITEBACK | L_PTE_USER
 
-	@
-	@ Erratum 40: The B bit must be cleared for a user read-only
-	@ cacheable page.
-	@
-	@  B = B & ~(U & C & ~W)
-	@
-	and	ip, r1, #L_PTE_USER | L_PTE_WRITE | L_PTE_CACHEABLE
-	teq	ip, #L_PTE_USER | L_PTE_CACHEABLE
-	biceq	r2, r2, #PTE_BUFFERABLE
+	moveq	r1, #L_PTE_MT_WRITETHROUGH
+	and	r1, r1, #L_PTE_MT_MASK
+	adr	ip, cpu_xscale_mt_table
+	ldr	ip, [ip, r1]
+	bic	r2, r2, #0x0c
+	orr	r2, r2, ip
 
-	tst	r3, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
-	movne	r2, #0				@ no -> fault
-
-	str	r2, [r0]			@ hardware version
-	mov	ip, #0
-	mcr	p15, 0, r0, c7, c10, 1		@ Clean D cache line
-	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
+	xscale_set_pte_ext_epilogue
 	mov	pc, lr
 
 
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S
index b56dda8..24ba510 100644
--- a/arch/arm/mm/tlb-v7.S
+++ b/arch/arm/mm/tlb-v7.S
@@ -51,6 +51,7 @@
 	mcr	p15, 0, ip, c7, c5, 6		@ flush BTAC/BTB
 	dsb
 	mov	pc, lr
+ENDPROC(v7wbi_flush_user_tlb_range)
 
 /*
  *	v7wbi_flush_kern_tlb_range(start,end)
@@ -77,6 +78,7 @@
 	dsb
 	isb
 	mov	pc, lr
+ENDPROC(v7wbi_flush_kern_tlb_range)
 
 	.section ".text.init", #alloc, #execinstr
 
diff --git a/arch/arm/nwfpe/fpa11_cpdt.c b/arch/arm/nwfpe/fpa11_cpdt.c
index 79f8e67..d31c49f 100644
--- a/arch/arm/nwfpe/fpa11_cpdt.c
+++ b/arch/arm/nwfpe/fpa11_cpdt.c
@@ -26,7 +26,7 @@
 #include "fpmodule.h"
 #include "fpmodule.inl"
 
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 static inline void loadSingle(const unsigned int Fn, const unsigned int __user *pMem)
 {
diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile
index e61d0cc..88e31f5 100644
--- a/arch/arm/oprofile/Makefile
+++ b/arch/arm/oprofile/Makefile
@@ -11,3 +11,4 @@
 oprofile-$(CONFIG_OPROFILE_ARM11_CORE)	+= op_model_arm11_core.o
 oprofile-$(CONFIG_OPROFILE_ARMV6)	+= op_model_v6.o
 oprofile-$(CONFIG_OPROFILE_MPCORE)	+= op_model_mpcore.o
+oprofile-$(CONFIG_OPROFILE_ARMV7)	+= op_model_v7.o
diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c
index f5ebf30..cefc21c 100644
--- a/arch/arm/oprofile/backtrace.c
+++ b/arch/arm/oprofile/backtrace.c
@@ -16,8 +16,8 @@
 #include <linux/oprofile.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/uaccess.h>
 #include <asm/ptrace.h>
-#include <asm/uaccess.h>
 
 #include "../kernel/stacktrace.h"
 
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
index 0a5cf3a..3fcd752 100644
--- a/arch/arm/oprofile/common.c
+++ b/arch/arm/oprofile/common.c
@@ -145,6 +145,10 @@
 	spec = &op_mpcore_spec;
 #endif
 
+#ifdef CONFIG_OPROFILE_ARMV7
+	spec = &op_armv7_spec;
+#endif
+
 	if (spec) {
 		ret = spec->init();
 		if (ret < 0)
diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h
index 4899c62..8c4e4f6 100644
--- a/arch/arm/oprofile/op_arm_model.h
+++ b/arch/arm/oprofile/op_arm_model.h
@@ -26,6 +26,7 @@
 
 extern struct op_arm_model_spec op_armv6_spec;
 extern struct op_arm_model_spec op_mpcore_spec;
+extern struct op_arm_model_spec op_armv7_spec;
 
 extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth);
 
diff --git a/arch/arm/oprofile/op_model_mpcore.c b/arch/arm/oprofile/op_model_mpcore.c
index 92db6e0..4de366e 100644
--- a/arch/arm/oprofile/op_model_mpcore.c
+++ b/arch/arm/oprofile/op_model_mpcore.c
@@ -36,8 +36,8 @@
 #include <linux/oprofile.h>
 #include <linux/interrupt.h>
 #include <linux/smp.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 #include <mach/hardware.h>
diff --git a/arch/arm/oprofile/op_model_v7.c b/arch/arm/oprofile/op_model_v7.c
new file mode 100644
index 0000000..f20295f
--- /dev/null
+++ b/arch/arm/oprofile/op_model_v7.c
@@ -0,0 +1,411 @@
+/**
+ * op_model_v7.c
+ * ARM V7 (Cortex A8) Event Monitor Driver
+ *
+ * Copyright 2008 Jean Pihet <jpihet@mvista.com>
+ * Copyright 2004 ARM SMP Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/oprofile.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/smp.h>
+
+#include "op_counter.h"
+#include "op_arm_model.h"
+#include "op_model_v7.h"
+
+/* #define DEBUG */
+
+
+/*
+ * ARM V7 PMNC support
+ */
+
+static u32 cnt_en[CNTMAX];
+
+static inline void armv7_pmnc_write(u32 val)
+{
+	val &= PMNC_MASK;
+	asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r" (val));
+}
+
+static inline u32 armv7_pmnc_read(void)
+{
+	u32 val;
+
+	asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
+	return val;
+}
+
+static inline u32 armv7_pmnc_enable_counter(unsigned int cnt)
+{
+	u32 val;
+
+	if (cnt >= CNTMAX) {
+		printk(KERN_ERR "oprofile: CPU%u enabling wrong PMNC counter"
+			" %d\n", smp_processor_id(), cnt);
+		return -1;
+	}
+
+	if (cnt == CCNT)
+		val = CNTENS_C;
+	else
+		val = (1 << (cnt - CNT0));
+
+	val &= CNTENS_MASK;
+	asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val));
+
+	return cnt;
+}
+
+static inline u32 armv7_pmnc_disable_counter(unsigned int cnt)
+{
+	u32 val;
+
+	if (cnt >= CNTMAX) {
+		printk(KERN_ERR "oprofile: CPU%u disabling wrong PMNC counter"
+			" %d\n", smp_processor_id(), cnt);
+		return -1;
+	}
+
+	if (cnt == CCNT)
+		val = CNTENC_C;
+	else
+		val = (1 << (cnt - CNT0));
+
+	val &= CNTENC_MASK;
+	asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val));
+
+	return cnt;
+}
+
+static inline u32 armv7_pmnc_enable_intens(unsigned int cnt)
+{
+	u32 val;
+
+	if (cnt >= CNTMAX) {
+		printk(KERN_ERR "oprofile: CPU%u enabling wrong PMNC counter"
+			" interrupt enable %d\n", smp_processor_id(), cnt);
+		return -1;
+	}
+
+	if (cnt == CCNT)
+		val = INTENS_C;
+	else
+		val = (1 << (cnt - CNT0));
+
+	val &= INTENS_MASK;
+	asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val));
+
+	return cnt;
+}
+
+static inline u32 armv7_pmnc_getreset_flags(void)
+{
+	u32 val;
+
+	/* Read */
+	asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
+
+	/* Write to clear flags */
+	val &= FLAG_MASK;
+	asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
+
+	return val;
+}
+
+static inline int armv7_pmnc_select_counter(unsigned int cnt)
+{
+	u32 val;
+
+	if ((cnt == CCNT) || (cnt >= CNTMAX)) {
+		printk(KERN_ERR "oprofile: CPU%u selecting wrong PMNC counteri"
+			" %d\n", smp_processor_id(), cnt);
+		return -1;
+	}
+
+	val = (cnt - CNT0) & SELECT_MASK;
+	asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val));
+
+	return cnt;
+}
+
+static inline void armv7_pmnc_write_evtsel(unsigned int cnt, u32 val)
+{
+	if (armv7_pmnc_select_counter(cnt) == cnt) {
+		val &= EVTSEL_MASK;
+		asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
+	}
+}
+
+static void armv7_pmnc_reset_counter(unsigned int cnt)
+{
+	u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), cnt);
+	u32 val = -(u32)counter_config[cpu_cnt].count;
+
+	switch (cnt) {
+	case CCNT:
+		armv7_pmnc_disable_counter(cnt);
+
+		asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (val));
+
+		if (cnt_en[cnt] != 0)
+		    armv7_pmnc_enable_counter(cnt);
+
+		break;
+
+	case CNT0:
+	case CNT1:
+	case CNT2:
+	case CNT3:
+		armv7_pmnc_disable_counter(cnt);
+
+		if (armv7_pmnc_select_counter(cnt) == cnt)
+		    asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (val));
+
+		if (cnt_en[cnt] != 0)
+		    armv7_pmnc_enable_counter(cnt);
+
+		break;
+
+	default:
+		printk(KERN_ERR "oprofile: CPU%u resetting wrong PMNC counter"
+			" %d\n", smp_processor_id(), cnt);
+		break;
+	}
+}
+
+int armv7_setup_pmnc(void)
+{
+	unsigned int cnt;
+
+	if (armv7_pmnc_read() & PMNC_E) {
+		printk(KERN_ERR "oprofile: CPU%u PMNC still enabled when setup"
+			" new event counter.\n", smp_processor_id());
+		return -EBUSY;
+	}
+
+	/*
+	 * Initialize & Reset PMNC: C bit, D bit and P bit.
+	 *  Note: Using a slower count for CCNT (D bit: divide by 64) results
+	 *   in a more stable system
+	 */
+	armv7_pmnc_write(PMNC_P | PMNC_C | PMNC_D);
+
+
+	for (cnt = CCNT; cnt < CNTMAX; cnt++) {
+		unsigned long event;
+		u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), cnt);
+
+		/*
+		 * Disable counter
+		 */
+		armv7_pmnc_disable_counter(cnt);
+		cnt_en[cnt] = 0;
+
+		if (!counter_config[cpu_cnt].enabled)
+			continue;
+
+		event = counter_config[cpu_cnt].event & 255;
+
+		/*
+		 * Set event (if destined for PMNx counters)
+		 * We don't need to set the event if it's a cycle count
+		 */
+		if (cnt != CCNT)
+			armv7_pmnc_write_evtsel(cnt, event);
+
+		/*
+		 * Enable interrupt for this counter
+		 */
+		armv7_pmnc_enable_intens(cnt);
+
+		/*
+		 * Reset counter
+		 */
+		armv7_pmnc_reset_counter(cnt);
+
+		/*
+		 * Enable counter
+		 */
+		armv7_pmnc_enable_counter(cnt);
+		cnt_en[cnt] = 1;
+	}
+
+	return 0;
+}
+
+static inline void armv7_start_pmnc(void)
+{
+	armv7_pmnc_write(armv7_pmnc_read() | PMNC_E);
+}
+
+static inline void armv7_stop_pmnc(void)
+{
+	armv7_pmnc_write(armv7_pmnc_read() & ~PMNC_E);
+}
+
+/*
+ * CPU counters' IRQ handler (one IRQ per CPU)
+ */
+static irqreturn_t armv7_pmnc_interrupt(int irq, void *arg)
+{
+	struct pt_regs *regs = get_irq_regs();
+	unsigned int cnt;
+	u32 flags;
+
+
+	/*
+	 * Stop IRQ generation
+	 */
+	armv7_stop_pmnc();
+
+	/*
+	 * Get and reset overflow status flags
+	 */
+	flags = armv7_pmnc_getreset_flags();
+
+	/*
+	 * Cycle counter
+	 */
+	if (flags & FLAG_C) {
+		u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), CCNT);
+		armv7_pmnc_reset_counter(CCNT);
+		oprofile_add_sample(regs, cpu_cnt);
+	}
+
+	/*
+	 * PMNC counters 0:3
+	 */
+	for (cnt = CNT0; cnt < CNTMAX; cnt++) {
+		if (flags & (1 << (cnt - CNT0))) {
+			u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), cnt);
+			armv7_pmnc_reset_counter(cnt);
+			oprofile_add_sample(regs, cpu_cnt);
+		}
+	}
+
+	/*
+	 * Allow IRQ generation
+	 */
+	armv7_start_pmnc();
+
+	return IRQ_HANDLED;
+}
+
+int armv7_request_interrupts(int *irqs, int nr)
+{
+	unsigned int i;
+	int ret = 0;
+
+	for (i = 0; i < nr; i++) {
+		ret = request_irq(irqs[i], armv7_pmnc_interrupt,
+				IRQF_DISABLED, "CP15 PMNC", NULL);
+		if (ret != 0) {
+			printk(KERN_ERR "oprofile: unable to request IRQ%u"
+				" for ARMv7\n",
+			       irqs[i]);
+			break;
+		}
+	}
+
+	if (i != nr)
+		while (i-- != 0)
+			free_irq(irqs[i], NULL);
+
+	return ret;
+}
+
+void armv7_release_interrupts(int *irqs, int nr)
+{
+	unsigned int i;
+
+	for (i = 0; i < nr; i++)
+		free_irq(irqs[i], NULL);
+}
+
+#ifdef DEBUG
+static void armv7_pmnc_dump_regs(void)
+{
+	u32 val;
+	unsigned int cnt;
+
+	printk(KERN_INFO "PMNC registers dump:\n");
+
+	asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
+	printk(KERN_INFO "PMNC  =0x%08x\n", val);
+
+	asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
+	printk(KERN_INFO "CNTENS=0x%08x\n", val);
+
+	asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
+	printk(KERN_INFO "INTENS=0x%08x\n", val);
+
+	asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
+	printk(KERN_INFO "FLAGS =0x%08x\n", val);
+
+	asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
+	printk(KERN_INFO "SELECT=0x%08x\n", val);
+
+	asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
+	printk(KERN_INFO "CCNT  =0x%08x\n", val);
+
+	for (cnt = CNT0; cnt < CNTMAX; cnt++) {
+		armv7_pmnc_select_counter(cnt);
+		asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
+		printk(KERN_INFO "CNT[%d] count =0x%08x\n", cnt-CNT0, val);
+		asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
+		printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n", cnt-CNT0, val);
+	}
+}
+#endif
+
+
+static int irqs[] = {
+#ifdef CONFIG_ARCH_OMAP3
+	INT_34XX_BENCH_MPU_EMUL,
+#endif
+};
+
+static void armv7_pmnc_stop(void)
+{
+#ifdef DEBUG
+	armv7_pmnc_dump_regs();
+#endif
+	armv7_stop_pmnc();
+	armv7_release_interrupts(irqs, ARRAY_SIZE(irqs));
+}
+
+static int armv7_pmnc_start(void)
+{
+	int ret;
+
+#ifdef DEBUG
+	armv7_pmnc_dump_regs();
+#endif
+	ret = armv7_request_interrupts(irqs, ARRAY_SIZE(irqs));
+	if (ret >= 0)
+		armv7_start_pmnc();
+
+	return ret;
+}
+
+static int armv7_detect_pmnc(void)
+{
+	return 0;
+}
+
+struct op_arm_model_spec op_armv7_spec = {
+	.init		= armv7_detect_pmnc,
+	.num_counters	= 5,
+	.setup_ctrs	= armv7_setup_pmnc,
+	.start		= armv7_pmnc_start,
+	.stop		= armv7_pmnc_stop,
+	.name		= "arm/armv7",
+};
diff --git a/arch/arm/oprofile/op_model_v7.h b/arch/arm/oprofile/op_model_v7.h
new file mode 100644
index 0000000..0e19bcc
--- /dev/null
+++ b/arch/arm/oprofile/op_model_v7.h
@@ -0,0 +1,103 @@
+/**
+ * op_model_v7.h
+ * ARM v7 (Cortex A8) Event Monitor Driver
+ *
+ * Copyright 2008 Jean Pihet <jpihet@mvista.com>
+ * Copyright 2004 ARM SMP Development Team
+ * Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
+ * Copyright 2000-2004 MontaVista Software Inc
+ * Copyright 2004 Dave Jiang <dave.jiang@intel.com>
+ * Copyright 2004 Intel Corporation
+ * Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
+ * Copyright 2004 Oprofile Authors
+ *
+ * Read the file COPYING
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef OP_MODEL_V7_H
+#define OP_MODEL_V7_H
+
+/*
+ * Per-CPU PMNC: config reg
+ */
+#define PMNC_E		(1 << 0)	/* Enable all counters */
+#define PMNC_P		(1 << 1)	/* Reset all counters */
+#define PMNC_C		(1 << 2)	/* Cycle counter reset */
+#define PMNC_D		(1 << 3)	/* CCNT counts every 64th cpu cycle */
+#define PMNC_X		(1 << 4)	/* Export to ETM */
+#define PMNC_DP		(1 << 5)	/* Disable CCNT if non-invasive debug*/
+#define	PMNC_MASK	0x3f		/* Mask for writable bits */
+
+/*
+ * Available counters
+ */
+#define CCNT 		0
+#define CNT0 		1
+#define CNT1 		2
+#define CNT2 		3
+#define CNT3 		4
+#define CNTMAX 		5
+
+#define CPU_COUNTER(cpu, counter)	((cpu) * CNTMAX + (counter))
+
+/*
+ * CNTENS: counters enable reg
+ */
+#define CNTENS_P0	(1 << 0)
+#define CNTENS_P1	(1 << 1)
+#define CNTENS_P2	(1 << 2)
+#define CNTENS_P3	(1 << 3)
+#define CNTENS_C	(1 << 31)
+#define	CNTENS_MASK	0x8000000f	/* Mask for writable bits */
+
+/*
+ * CNTENC: counters disable reg
+ */
+#define CNTENC_P0	(1 << 0)
+#define CNTENC_P1	(1 << 1)
+#define CNTENC_P2	(1 << 2)
+#define CNTENC_P3	(1 << 3)
+#define CNTENC_C	(1 << 31)
+#define	CNTENC_MASK	0x8000000f	/* Mask for writable bits */
+
+/*
+ * INTENS: counters overflow interrupt enable reg
+ */
+#define INTENS_P0	(1 << 0)
+#define INTENS_P1	(1 << 1)
+#define INTENS_P2	(1 << 2)
+#define INTENS_P3	(1 << 3)
+#define INTENS_C	(1 << 31)
+#define	INTENS_MASK	0x8000000f	/* Mask for writable bits */
+
+/*
+ * EVTSEL: Event selection reg
+ */
+#define	EVTSEL_MASK	0x7f		/* Mask for writable bits */
+
+/*
+ * SELECT: Counter selection reg
+ */
+#define	SELECT_MASK	0x1f		/* Mask for writable bits */
+
+/*
+ * FLAG: counters overflow flag status reg
+ */
+#define FLAG_P0		(1 << 0)
+#define FLAG_P1		(1 << 1)
+#define FLAG_P2		(1 << 2)
+#define FLAG_P3		(1 << 3)
+#define FLAG_C		(1 << 31)
+#define	FLAG_MASK	0x8000000f	/* Mask for writable bits */
+
+
+int armv7_setup_pmu(void);
+int armv7_start_pmu(void);
+int armv7_stop_pmu(void);
+int armv7_request_interrupts(int *, int);
+void armv7_release_interrupts(int *, int);
+
+#endif
diff --git a/arch/arm/oprofile/op_model_xscale.c b/arch/arm/oprofile/op_model_xscale.c
index 7c3289c..724ab9c 100644
--- a/arch/arm/oprofile/op_model_xscale.c
+++ b/arch/arm/oprofile/op_model_xscale.c
@@ -22,7 +22,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 
-#include <asm/system.h>
+#include <asm/cputype.h>
 
 #include "op_counter.h"
 #include "op_arm_model.h"
diff --git a/arch/arm/plat-iop/i2c.c b/arch/arm/plat-iop/i2c.c
index 6dcbcc4..4efe392 100644
--- a/arch/arm/plat-iop/i2c.c
+++ b/arch/arm/plat-iop/i2c.c
@@ -18,7 +18,7 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_core.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <asm/mach/map.h>
diff --git a/arch/arm/plat-iop/io.c b/arch/arm/plat-iop/io.c
index 39dcfb4..ed0bbec 100644
--- a/arch/arm/plat-iop/io.c
+++ b/arch/arm/plat-iop/io.c
@@ -18,8 +18,8 @@
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 
 void * __iomem __iop3xx_ioremap(unsigned long cookie, size_t size,
 	unsigned int mtype)
diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c
index 54708bf..77fa7cc 100644
--- a/arch/arm/plat-iop/pci.c
+++ b/arch/arm/plat-iop/pci.c
@@ -17,7 +17,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/irq.h>
 #include <asm/signal.h>
 #include <asm/system.h>
diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c
index c53fefb..3695bbe 100644
--- a/arch/arm/plat-iop/time.c
+++ b/arch/arm/plat-iop/time.c
@@ -18,8 +18,8 @@
 #include <linux/time.h>
 #include <linux/init.h>
 #include <linux/timex.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 #include <asm/mach/irq.h>
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index e14eaad..b2a7e3f 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -23,4 +23,15 @@
 
 endmenu
 
+config MXC_IRQ_PRIOR
+	bool "Use IRQ priority"
+	depends on ARCH_MXC
+	help
+	  Select this if you want to use prioritized IRQ handling.
+	  This feature prevents higher priority ISR to be interrupted
+	  by lower priority IRQ even IRQF_DISABLED flag is not set.
+	  This may be useful in embedded applications, where are strong
+	  requirements for timing.
+	  Say N here, unless you have a specialized requirement.
+
 endif
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index db66e9a..067556f 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -3,6 +3,6 @@
 #
 
 # Common support
-obj-y := irq.o clock.o gpio.o time.o
+obj-y := irq.o clock.o gpio.o time.o devices.o
 
-obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o
+obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o
diff --git a/arch/arm/plat-mxc/devices.c b/arch/arm/plat-mxc/devices.c
new file mode 100644
index 0000000..c667482
--- /dev/null
+++ b/arch/arm/plat-mxc/devices.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2008 Sascha Hauer, kernel@pengutronix.de
+ *
+ * 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+int __init mxc_register_device(struct platform_device *pdev, void *data)
+{
+	int ret;
+
+	pdev->dev.platform_data = data;
+
+	ret = platform_device_register(pdev);
+	if (ret)
+		pr_debug("Unable to register platform device '%s': %d\n",
+			 pdev->name, ret);
+
+	return ret;
+}
+
diff --git a/arch/arm/plat-mxc/dma-mx1-mx2.c b/arch/arm/plat-mxc/dma-mx1-mx2.c
new file mode 100644
index 0000000..b296f19
--- /dev/null
+++ b/arch/arm/plat-mxc/dma-mx1-mx2.c
@@ -0,0 +1,840 @@
+/*
+ *  linux/arch/arm/plat-mxc/dma-mx1-mx2.c
+ *
+ *  i.MX DMA registration and IRQ dispatching
+ *
+ * Copyright 2006 Pavel Pisa <pisa@cmp.felk.cvut.cz>
+ * Copyright 2008 Juergen Beisert, <kernel@pengutronix.de>
+ * Copyright 2008 Sascha Hauer, <s.hauer@pengutronix.de>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/scatterlist.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <asm/dma.h>
+#include <mach/dma-mx1-mx2.h>
+
+#define DMA_DCR     0x00		/* Control Register */
+#define DMA_DISR    0x04		/* Interrupt status Register */
+#define DMA_DIMR    0x08		/* Interrupt mask Register */
+#define DMA_DBTOSR  0x0c		/* Burst timeout status Register */
+#define DMA_DRTOSR  0x10		/* Request timeout Register */
+#define DMA_DSESR   0x14		/* Transfer Error Status Register */
+#define DMA_DBOSR   0x18		/* Buffer overflow status Register */
+#define DMA_DBTOCR  0x1c		/* Burst timeout control Register */
+#define DMA_WSRA    0x40		/* W-Size Register A */
+#define DMA_XSRA    0x44		/* X-Size Register A */
+#define DMA_YSRA    0x48		/* Y-Size Register A */
+#define DMA_WSRB    0x4c		/* W-Size Register B */
+#define DMA_XSRB    0x50		/* X-Size Register B */
+#define DMA_YSRB    0x54		/* Y-Size Register B */
+#define DMA_SAR(x)  (0x80 + ((x) << 6))	/* Source Address Registers */
+#define DMA_DAR(x)  (0x84 + ((x) << 6))	/* Destination Address Registers */
+#define DMA_CNTR(x) (0x88 + ((x) << 6))	/* Count Registers */
+#define DMA_CCR(x)  (0x8c + ((x) << 6))	/* Control Registers */
+#define DMA_RSSR(x) (0x90 + ((x) << 6))	/* Request source select Registers */
+#define DMA_BLR(x)  (0x94 + ((x) << 6))	/* Burst length Registers */
+#define DMA_RTOR(x) (0x98 + ((x) << 6))	/* Request timeout Registers */
+#define DMA_BUCR(x) (0x98 + ((x) << 6))	/* Bus Utilization Registers */
+#define DMA_CCNR(x) (0x9C + ((x) << 6))	/* Channel counter Registers */
+
+#define DCR_DRST           (1<<1)
+#define DCR_DEN            (1<<0)
+#define DBTOCR_EN          (1<<15)
+#define DBTOCR_CNT(x)      ((x) & 0x7fff)
+#define CNTR_CNT(x)        ((x) & 0xffffff)
+#define CCR_ACRPT          (1<<14)
+#define CCR_DMOD_LINEAR    (0x0 << 12)
+#define CCR_DMOD_2D        (0x1 << 12)
+#define CCR_DMOD_FIFO      (0x2 << 12)
+#define CCR_DMOD_EOBFIFO   (0x3 << 12)
+#define CCR_SMOD_LINEAR    (0x0 << 10)
+#define CCR_SMOD_2D        (0x1 << 10)
+#define CCR_SMOD_FIFO      (0x2 << 10)
+#define CCR_SMOD_EOBFIFO   (0x3 << 10)
+#define CCR_MDIR_DEC       (1<<9)
+#define CCR_MSEL_B         (1<<8)
+#define CCR_DSIZ_32        (0x0 << 6)
+#define CCR_DSIZ_8         (0x1 << 6)
+#define CCR_DSIZ_16        (0x2 << 6)
+#define CCR_SSIZ_32        (0x0 << 4)
+#define CCR_SSIZ_8         (0x1 << 4)
+#define CCR_SSIZ_16        (0x2 << 4)
+#define CCR_REN            (1<<3)
+#define CCR_RPT            (1<<2)
+#define CCR_FRC            (1<<1)
+#define CCR_CEN            (1<<0)
+#define RTOR_EN            (1<<15)
+#define RTOR_CLK           (1<<14)
+#define RTOR_PSC           (1<<13)
+
+/*
+ * struct imx_dma_channel - i.MX specific DMA extension
+ * @name: name specified by DMA client
+ * @irq_handler: client callback for end of transfer
+ * @err_handler: client callback for error condition
+ * @data: clients context data for callbacks
+ * @dma_mode: direction of the transfer %DMA_MODE_READ or %DMA_MODE_WRITE
+ * @sg: pointer to the actual read/written chunk for scatter-gather emulation
+ * @resbytes: total residual number of bytes to transfer
+ *            (it can be lower or same as sum of SG mapped chunk sizes)
+ * @sgcount: number of chunks to be read/written
+ *
+ * Structure is used for IMX DMA processing. It would be probably good
+ * @struct dma_struct in the future for external interfacing and use
+ * @struct imx_dma_channel only as extension to it.
+ */
+
+struct imx_dma_channel {
+	const char *name;
+	void (*irq_handler) (int, void *);
+	void (*err_handler) (int, void *, int errcode);
+	void (*prog_handler) (int, void *, struct scatterlist *);
+	void *data;
+	dmamode_t  dma_mode;
+	struct scatterlist *sg;
+	unsigned int resbytes;
+	int dma_num;
+
+	int in_use;
+
+	u32 ccr_from_device;
+	u32 ccr_to_device;
+
+	struct timer_list watchdog;
+
+	int hw_chaining;
+};
+
+static struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS];
+
+static struct clk *dma_clk;
+
+static int imx_dma_hw_chain(struct imx_dma_channel *imxdma)
+{
+	if (cpu_is_mx27())
+		return imxdma->hw_chaining;
+	else
+		return 0;
+}
+
+
+/*
+ * imx_dma_sg_next - prepare next chunk for scatter-gather DMA emulation
+ */
+static inline int imx_dma_sg_next(int channel, struct scatterlist *sg)
+{
+	struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+	unsigned long now;
+
+	if (!imxdma->name) {
+		printk(KERN_CRIT "%s: called for  not allocated channel %d\n",
+		       __func__, channel);
+		return 0;
+	}
+
+	now = min(imxdma->resbytes, sg->length);
+	imxdma->resbytes -= now;
+
+	if ((imxdma->dma_mode & DMA_MODE_MASK) == DMA_MODE_READ)
+		__raw_writel(sg->dma_address, DMA_BASE + DMA_DAR(channel));
+	else
+		__raw_writel(sg->dma_address, DMA_BASE + DMA_SAR(channel));
+
+	__raw_writel(now, DMA_BASE + DMA_CNTR(channel));
+
+	pr_debug("imxdma%d: next sg chunk dst 0x%08x, src 0x%08x, "
+		"size 0x%08x\n", channel,
+		 __raw_readl(DMA_BASE + DMA_DAR(channel)),
+		 __raw_readl(DMA_BASE + DMA_SAR(channel)),
+		 __raw_readl(DMA_BASE + DMA_CNTR(channel)));
+
+	return now;
+}
+
+/**
+ * imx_dma_setup_single - setup i.MX DMA channel for linear memory to/from
+ * device transfer
+ *
+ * @channel: i.MX DMA channel number
+ * @dma_address: the DMA/physical memory address of the linear data block
+ *		to transfer
+ * @dma_length: length of the data block in bytes
+ * @dev_addr: physical device port address
+ * @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory
+ *           or %DMA_MODE_WRITE from memory to the device
+ *
+ * Return value: if incorrect parameters are provided -%EINVAL.
+ *		Zero indicates success.
+ */
+int
+imx_dma_setup_single(int channel, dma_addr_t dma_address,
+		     unsigned int dma_length, unsigned int dev_addr,
+		     dmamode_t dmamode)
+{
+	struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+
+	imxdma->sg = NULL;
+	imxdma->dma_mode = dmamode;
+
+	if (!dma_address) {
+		printk(KERN_ERR "imxdma%d: imx_dma_setup_single null address\n",
+		       channel);
+		return -EINVAL;
+	}
+
+	if (!dma_length) {
+		printk(KERN_ERR "imxdma%d: imx_dma_setup_single zero length\n",
+		       channel);
+		return -EINVAL;
+	}
+
+	if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) {
+		pr_debug("imxdma%d: %s dma_addressg=0x%08x dma_length=%d "
+			"dev_addr=0x%08x for read\n",
+			channel, __func__, (unsigned int)dma_address,
+			dma_length, dev_addr);
+
+		__raw_writel(dev_addr, DMA_BASE + DMA_SAR(channel));
+		__raw_writel(dma_address, DMA_BASE + DMA_DAR(channel));
+		__raw_writel(imxdma->ccr_from_device,
+				DMA_BASE + DMA_CCR(channel));
+	} else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
+		pr_debug("imxdma%d: %s dma_addressg=0x%08x dma_length=%d "
+			"dev_addr=0x%08x for write\n",
+			channel, __func__, (unsigned int)dma_address,
+			dma_length, dev_addr);
+
+		__raw_writel(dma_address, DMA_BASE + DMA_SAR(channel));
+		__raw_writel(dev_addr, DMA_BASE + DMA_DAR(channel));
+		__raw_writel(imxdma->ccr_to_device,
+				DMA_BASE + DMA_CCR(channel));
+	} else {
+		printk(KERN_ERR "imxdma%d: imx_dma_setup_single bad dmamode\n",
+		       channel);
+		return -EINVAL;
+	}
+
+	__raw_writel(dma_length, DMA_BASE + DMA_CNTR(channel));
+
+	return 0;
+}
+EXPORT_SYMBOL(imx_dma_setup_single);
+
+/**
+ * imx_dma_setup_sg - setup i.MX DMA channel SG list to/from device transfer
+ * @channel: i.MX DMA channel number
+ * @sg: pointer to the scatter-gather list/vector
+ * @sgcount: scatter-gather list hungs count
+ * @dma_length: total length of the transfer request in bytes
+ * @dev_addr: physical device port address
+ * @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory
+ *           or %DMA_MODE_WRITE from memory to the device
+ *
+ * The function sets up DMA channel state and registers to be ready for
+ * transfer specified by provided parameters. The scatter-gather emulation
+ * is set up according to the parameters.
+ *
+ * The full preparation of the transfer requires setup of more register
+ * by the caller before imx_dma_enable() can be called.
+ *
+ * %BLR(channel) holds transfer burst length in bytes, 0 means 64 bytes
+ *
+ * %RSSR(channel) has to be set to the DMA request line source %DMA_REQ_xxx
+ *
+ * %CCR(channel) has to specify transfer parameters, the next settings is
+ * typical for linear or simple scatter-gather transfers if %DMA_MODE_READ is
+ * specified
+ *
+ * %CCR_DMOD_LINEAR | %CCR_DSIZ_32 | %CCR_SMOD_FIFO | %CCR_SSIZ_x
+ *
+ * The typical setup for %DMA_MODE_WRITE is specified by next options
+ * combination
+ *
+ * %CCR_SMOD_LINEAR | %CCR_SSIZ_32 | %CCR_DMOD_FIFO | %CCR_DSIZ_x
+ *
+ * Be careful here and do not mistakenly mix source and target device
+ * port sizes constants, they are really different:
+ * %CCR_SSIZ_8, %CCR_SSIZ_16, %CCR_SSIZ_32,
+ * %CCR_DSIZ_8, %CCR_DSIZ_16, %CCR_DSIZ_32
+ *
+ * Return value: if incorrect parameters are provided -%EINVAL.
+ * Zero indicates success.
+ */
+int
+imx_dma_setup_sg(int channel,
+		 struct scatterlist *sg, unsigned int sgcount,
+		 unsigned int dma_length, unsigned int dev_addr,
+		 dmamode_t dmamode)
+{
+	struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+
+	if (imxdma->in_use)
+		return -EBUSY;
+
+	imxdma->sg = sg;
+	imxdma->dma_mode = dmamode;
+	imxdma->resbytes = dma_length;
+
+	if (!sg || !sgcount) {
+		printk(KERN_ERR "imxdma%d: imx_dma_setup_sg epty sg list\n",
+		       channel);
+		return -EINVAL;
+	}
+
+	if (!sg->length) {
+		printk(KERN_ERR "imxdma%d: imx_dma_setup_sg zero length\n",
+		       channel);
+		return -EINVAL;
+	}
+
+	if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) {
+		pr_debug("imxdma%d: %s sg=%p sgcount=%d total length=%d "
+			"dev_addr=0x%08x for read\n",
+			channel, __func__, sg, sgcount, dma_length, dev_addr);
+
+		__raw_writel(dev_addr, DMA_BASE + DMA_SAR(channel));
+		__raw_writel(imxdma->ccr_from_device,
+				DMA_BASE + DMA_CCR(channel));
+	} else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
+		pr_debug("imxdma%d: %s sg=%p sgcount=%d total length=%d "
+			"dev_addr=0x%08x for write\n",
+			channel, __func__, sg, sgcount, dma_length, dev_addr);
+
+		__raw_writel(dev_addr, DMA_BASE + DMA_DAR(channel));
+		__raw_writel(imxdma->ccr_to_device,
+				DMA_BASE + DMA_CCR(channel));
+	} else {
+		printk(KERN_ERR "imxdma%d: imx_dma_setup_sg bad dmamode\n",
+		       channel);
+		return -EINVAL;
+	}
+
+	imx_dma_sg_next(channel, sg);
+
+	return 0;
+}
+EXPORT_SYMBOL(imx_dma_setup_sg);
+
+int
+imx_dma_config_channel(int channel, unsigned int config_port,
+	unsigned int config_mem, unsigned int dmareq, int hw_chaining)
+{
+	struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+	u32 dreq = 0;
+
+	imxdma->hw_chaining = 0;
+
+	if (hw_chaining) {
+		imxdma->hw_chaining = 1;
+		if (!imx_dma_hw_chain(imxdma))
+			return -EINVAL;
+	}
+
+	if (dmareq)
+		dreq = CCR_REN;
+
+	imxdma->ccr_from_device = config_port | (config_mem << 2) | dreq;
+	imxdma->ccr_to_device = config_mem | (config_port << 2) | dreq;
+
+	__raw_writel(dmareq, DMA_BASE + DMA_RSSR(channel));
+
+	return 0;
+}
+EXPORT_SYMBOL(imx_dma_config_channel);
+
+void imx_dma_config_burstlen(int channel, unsigned int burstlen)
+{
+	__raw_writel(burstlen, DMA_BASE + DMA_BLR(channel));
+}
+EXPORT_SYMBOL(imx_dma_config_burstlen);
+
+/**
+ * imx_dma_setup_handlers - setup i.MX DMA channel end and error notification
+ * handlers
+ * @channel: i.MX DMA channel number
+ * @irq_handler: the pointer to the function called if the transfer
+ *		ends successfully
+ * @err_handler: the pointer to the function called if the premature
+ *		end caused by error occurs
+ * @data: user specified value to be passed to the handlers
+ */
+int
+imx_dma_setup_handlers(int channel,
+		       void (*irq_handler) (int, void *),
+		       void (*err_handler) (int, void *, int),
+		       void *data)
+{
+	struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+	unsigned long flags;
+
+	if (!imxdma->name) {
+		printk(KERN_CRIT "%s: called for  not allocated channel %d\n",
+		       __func__, channel);
+		return -ENODEV;
+	}
+
+	local_irq_save(flags);
+	__raw_writel(1 << channel, DMA_BASE + DMA_DISR);
+	imxdma->irq_handler = irq_handler;
+	imxdma->err_handler = err_handler;
+	imxdma->data = data;
+	local_irq_restore(flags);
+	return 0;
+}
+EXPORT_SYMBOL(imx_dma_setup_handlers);
+
+/**
+ * imx_dma_setup_progression_handler - setup i.MX DMA channel progression
+ * handlers
+ * @channel: i.MX DMA channel number
+ * @prog_handler: the pointer to the function called if the transfer progresses
+ */
+int
+imx_dma_setup_progression_handler(int channel,
+			void (*prog_handler) (int, void*, struct scatterlist*))
+{
+	struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+	unsigned long flags;
+
+	if (!imxdma->name) {
+		printk(KERN_CRIT "%s: called for  not allocated channel %d\n",
+		       __func__, channel);
+		return -ENODEV;
+	}
+
+	local_irq_save(flags);
+	imxdma->prog_handler = prog_handler;
+	local_irq_restore(flags);
+	return 0;
+}
+EXPORT_SYMBOL(imx_dma_setup_progression_handler);
+
+/**
+ * imx_dma_enable - function to start i.MX DMA channel operation
+ * @channel: i.MX DMA channel number
+ *
+ * The channel has to be allocated by driver through imx_dma_request()
+ * or imx_dma_request_by_prio() function.
+ * The transfer parameters has to be set to the channel registers through
+ * call of the imx_dma_setup_single() or imx_dma_setup_sg() function
+ * and registers %BLR(channel), %RSSR(channel) and %CCR(channel) has to
+ * be set prior this function call by the channel user.
+ */
+void imx_dma_enable(int channel)
+{
+	struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+	unsigned long flags;
+
+	pr_debug("imxdma%d: imx_dma_enable\n", channel);
+
+	if (!imxdma->name) {
+		printk(KERN_CRIT "%s: called for  not allocated channel %d\n",
+		       __func__, channel);
+		return;
+	}
+
+	if (imxdma->in_use)
+		return;
+
+	local_irq_save(flags);
+
+	__raw_writel(1 << channel, DMA_BASE + DMA_DISR);
+	__raw_writel(__raw_readl(DMA_BASE + DMA_DIMR) & ~(1 << channel),
+		DMA_BASE + DMA_DIMR);
+	__raw_writel(__raw_readl(DMA_BASE + DMA_CCR(channel)) | CCR_CEN |
+		CCR_ACRPT,
+		DMA_BASE + DMA_CCR(channel));
+
+#ifdef CONFIG_ARCH_MX2
+	if (imxdma->sg && imx_dma_hw_chain(imxdma)) {
+		imxdma->sg = sg_next(imxdma->sg);
+		if (imxdma->sg) {
+			u32 tmp;
+			imx_dma_sg_next(channel, imxdma->sg);
+			tmp = __raw_readl(DMA_BASE + DMA_CCR(channel));
+			__raw_writel(tmp | CCR_RPT | CCR_ACRPT,
+				DMA_BASE + DMA_CCR(channel));
+		}
+	}
+#endif
+	imxdma->in_use = 1;
+
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(imx_dma_enable);
+
+/**
+ * imx_dma_disable - stop, finish i.MX DMA channel operatin
+ * @channel: i.MX DMA channel number
+ */
+void imx_dma_disable(int channel)
+{
+	struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+	unsigned long flags;
+
+	pr_debug("imxdma%d: imx_dma_disable\n", channel);
+
+	if (imx_dma_hw_chain(imxdma))
+		del_timer(&imxdma->watchdog);
+
+	local_irq_save(flags);
+	__raw_writel(__raw_readl(DMA_BASE + DMA_DIMR) | (1 << channel),
+		DMA_BASE + DMA_DIMR);
+	__raw_writel(__raw_readl(DMA_BASE + DMA_CCR(channel)) & ~CCR_CEN,
+		DMA_BASE + DMA_CCR(channel));
+	__raw_writel(1 << channel, DMA_BASE + DMA_DISR);
+	imxdma->in_use = 0;
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(imx_dma_disable);
+
+static void imx_dma_watchdog(unsigned long chno)
+{
+	struct imx_dma_channel *imxdma = &imx_dma_channels[chno];
+
+	__raw_writel(0, DMA_BASE + DMA_CCR(chno));
+	imxdma->in_use = 0;
+	imxdma->sg = NULL;
+
+	if (imxdma->err_handler)
+		imxdma->err_handler(chno, imxdma->data, IMX_DMA_ERR_TIMEOUT);
+}
+
+static irqreturn_t dma_err_handler(int irq, void *dev_id)
+{
+	int i, disr;
+	struct imx_dma_channel *imxdma;
+	unsigned int err_mask;
+	int errcode;
+
+	disr = __raw_readl(DMA_BASE + DMA_DISR);
+
+	err_mask = __raw_readl(DMA_BASE + DMA_DBTOSR) |
+		   __raw_readl(DMA_BASE + DMA_DRTOSR) |
+		   __raw_readl(DMA_BASE + DMA_DSESR)  |
+		   __raw_readl(DMA_BASE + DMA_DBOSR);
+
+	if (!err_mask)
+		return IRQ_HANDLED;
+
+	__raw_writel(disr & err_mask, DMA_BASE + DMA_DISR);
+
+	for (i = 0; i < IMX_DMA_CHANNELS; i++) {
+		if (!(err_mask & (1 << i)))
+			continue;
+		imxdma = &imx_dma_channels[i];
+		errcode = 0;
+
+		if (__raw_readl(DMA_BASE + DMA_DBTOSR) & (1 << i)) {
+			__raw_writel(1 << i, DMA_BASE + DMA_DBTOSR);
+			errcode |= IMX_DMA_ERR_BURST;
+		}
+		if (__raw_readl(DMA_BASE + DMA_DRTOSR) & (1 << i)) {
+			__raw_writel(1 << i, DMA_BASE + DMA_DRTOSR);
+			errcode |= IMX_DMA_ERR_REQUEST;
+		}
+		if (__raw_readl(DMA_BASE + DMA_DSESR) & (1 << i)) {
+			__raw_writel(1 << i, DMA_BASE + DMA_DSESR);
+			errcode |= IMX_DMA_ERR_TRANSFER;
+		}
+		if (__raw_readl(DMA_BASE + DMA_DBOSR) & (1 << i)) {
+			__raw_writel(1 << i, DMA_BASE + DMA_DBOSR);
+			errcode |= IMX_DMA_ERR_BUFFER;
+		}
+		if (imxdma->name && imxdma->err_handler) {
+			imxdma->err_handler(i, imxdma->data, errcode);
+			continue;
+		}
+
+		imx_dma_channels[i].sg = NULL;
+
+		printk(KERN_WARNING
+		       "DMA timeout on channel %d (%s) -%s%s%s%s\n",
+		       i, imxdma->name,
+		       errcode & IMX_DMA_ERR_BURST ?    " burst" : "",
+		       errcode & IMX_DMA_ERR_REQUEST ?  " request" : "",
+		       errcode & IMX_DMA_ERR_TRANSFER ? " transfer" : "",
+		       errcode & IMX_DMA_ERR_BUFFER ?   " buffer" : "");
+	}
+	return IRQ_HANDLED;
+}
+
+static void dma_irq_handle_channel(int chno)
+{
+	struct imx_dma_channel *imxdma = &imx_dma_channels[chno];
+
+	if (!imxdma->name) {
+		/*
+		 * IRQ for an unregistered DMA channel:
+		 * let's clear the interrupts and disable it.
+		 */
+		printk(KERN_WARNING
+		       "spurious IRQ for DMA channel %d\n", chno);
+		return;
+	}
+
+	if (imxdma->sg) {
+		u32 tmp;
+		struct scatterlist *current_sg = imxdma->sg;
+		imxdma->sg = sg_next(imxdma->sg);
+
+		if (imxdma->sg) {
+			imx_dma_sg_next(chno, imxdma->sg);
+
+			tmp = __raw_readl(DMA_BASE + DMA_CCR(chno));
+
+			if (imx_dma_hw_chain(imxdma)) {
+				/* FIXME: The timeout should probably be
+				 * configurable
+				 */
+				mod_timer(&imxdma->watchdog,
+					jiffies + msecs_to_jiffies(500));
+
+				tmp |= CCR_CEN | CCR_RPT | CCR_ACRPT;
+				__raw_writel(tmp, DMA_BASE +
+						DMA_CCR(chno));
+			} else {
+				__raw_writel(tmp & ~CCR_CEN, DMA_BASE +
+						DMA_CCR(chno));
+				tmp |= CCR_CEN;
+			}
+
+			__raw_writel(tmp, DMA_BASE + DMA_CCR(chno));
+
+			if (imxdma->prog_handler)
+				imxdma->prog_handler(chno, imxdma->data,
+						current_sg);
+
+			return;
+		}
+
+		if (imx_dma_hw_chain(imxdma)) {
+			del_timer(&imxdma->watchdog);
+			return;
+		}
+	}
+
+	__raw_writel(0, DMA_BASE + DMA_CCR(chno));
+	imxdma->in_use = 0;
+	if (imxdma->irq_handler)
+		imxdma->irq_handler(chno, imxdma->data);
+}
+
+static irqreturn_t dma_irq_handler(int irq, void *dev_id)
+{
+	int i, disr;
+
+#ifdef CONFIG_ARCH_MX2
+	dma_err_handler(irq, dev_id);
+#endif
+
+	disr = __raw_readl(DMA_BASE + DMA_DISR);
+
+	pr_debug("imxdma: dma_irq_handler called, disr=0x%08x\n",
+		     disr);
+
+	__raw_writel(disr, DMA_BASE + DMA_DISR);
+	for (i = 0; i < IMX_DMA_CHANNELS; i++) {
+		if (disr & (1 << i))
+			dma_irq_handle_channel(i);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * imx_dma_request - request/allocate specified channel number
+ * @channel: i.MX DMA channel number
+ * @name: the driver/caller own non-%NULL identification
+ */
+int imx_dma_request(int channel, const char *name)
+{
+	struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+	unsigned long flags;
+	int ret;
+
+	/* basic sanity checks */
+	if (!name)
+		return -EINVAL;
+
+	if (channel >= IMX_DMA_CHANNELS) {
+		printk(KERN_CRIT "%s: called for  non-existed channel %d\n",
+		       __func__, channel);
+		return -EINVAL;
+	}
+
+	local_irq_save(flags);
+	if (imxdma->name) {
+		local_irq_restore(flags);
+		return -EBUSY;
+	}
+
+#ifdef CONFIG_ARCH_MX2
+	ret = request_irq(MXC_INT_DMACH0 + channel, dma_irq_handler, 0, "DMA",
+			NULL);
+	if (ret) {
+		printk(KERN_CRIT "Can't register IRQ %d for DMA channel %d\n",
+				MXC_INT_DMACH0 + channel, channel);
+		return ret;
+	}
+	init_timer(&imxdma->watchdog);
+	imxdma->watchdog.function = &imx_dma_watchdog;
+	imxdma->watchdog.data = channel;
+#endif
+
+	imxdma->name = name;
+	imxdma->irq_handler = NULL;
+	imxdma->err_handler = NULL;
+	imxdma->data = NULL;
+	imxdma->sg = NULL;
+
+	local_irq_restore(flags);
+	return 0;
+}
+EXPORT_SYMBOL(imx_dma_request);
+
+/**
+ * imx_dma_free - release previously acquired channel
+ * @channel: i.MX DMA channel number
+ */
+void imx_dma_free(int channel)
+{
+	unsigned long flags;
+	struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+
+	if (!imxdma->name) {
+		printk(KERN_CRIT
+		       "%s: trying to free free channel %d\n",
+		       __func__, channel);
+		return;
+	}
+
+	local_irq_save(flags);
+	/* Disable interrupts */
+	__raw_writel(__raw_readl(DMA_BASE + DMA_DIMR) | (1 << channel),
+		DMA_BASE + DMA_DIMR);
+	__raw_writel(__raw_readl(DMA_BASE + DMA_CCR(channel)) & ~CCR_CEN,
+		DMA_BASE + DMA_CCR(channel));
+	imxdma->name = NULL;
+
+#ifdef CONFIG_ARCH_MX2
+	free_irq(MXC_INT_DMACH0 + channel, NULL);
+#endif
+
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(imx_dma_free);
+
+/**
+ * imx_dma_request_by_prio - find and request some of free channels best
+ * suiting requested priority
+ * @channel: i.MX DMA channel number
+ * @name: the driver/caller own non-%NULL identification
+ *
+ * This function tries to find a free channel in the specified priority group
+ * This function tries to find a free channel in the specified priority group
+ * if the priority cannot be achieved it tries to look for free channel
+ * in the higher and then even lower priority groups.
+ *
+ * Return value: If there is no free channel to allocate, -%ENODEV is returned.
+ *               On successful allocation channel is returned.
+ */
+int imx_dma_request_by_prio(const char *name, enum imx_dma_prio prio)
+{
+	int i;
+	int best;
+
+	switch (prio) {
+	case (DMA_PRIO_HIGH):
+		best = 8;
+		break;
+	case (DMA_PRIO_MEDIUM):
+		best = 4;
+		break;
+	case (DMA_PRIO_LOW):
+	default:
+		best = 0;
+		break;
+	}
+
+	for (i = best; i < IMX_DMA_CHANNELS; i++)
+		if (!imx_dma_request(i, name))
+			return i;
+
+	for (i = best - 1; i >= 0; i--)
+		if (!imx_dma_request(i, name))
+			return i;
+
+	printk(KERN_ERR "%s: no free DMA channel found\n", __func__);
+
+	return -ENODEV;
+}
+EXPORT_SYMBOL(imx_dma_request_by_prio);
+
+static int __init imx_dma_init(void)
+{
+	int ret = 0;
+	int i;
+
+	dma_clk = clk_get(NULL, "dma_clk");
+	clk_enable(dma_clk);
+
+	/* reset DMA module */
+	__raw_writel(DCR_DRST, DMA_BASE + DMA_DCR);
+
+#ifdef CONFIG_ARCH_MX1
+	ret = request_irq(DMA_INT, dma_irq_handler, 0, "DMA", NULL);
+	if (ret) {
+		printk(KERN_CRIT "Wow!  Can't register IRQ for DMA\n");
+		return ret;
+	}
+
+	ret = request_irq(DMA_ERR, dma_err_handler, 0, "DMA", NULL);
+	if (ret) {
+		printk(KERN_CRIT "Wow!  Can't register ERRIRQ for DMA\n");
+		free_irq(DMA_INT, NULL);
+		return ret;
+	}
+#endif
+	/* enable DMA module */
+	__raw_writel(DCR_DEN, DMA_BASE + DMA_DCR);
+
+	/* clear all interrupts */
+	__raw_writel((1 << IMX_DMA_CHANNELS) - 1, DMA_BASE + DMA_DISR);
+
+	/* disable interrupts */
+	__raw_writel((1 << IMX_DMA_CHANNELS) - 1, DMA_BASE + DMA_DIMR);
+
+	for (i = 0; i < IMX_DMA_CHANNELS; i++) {
+		imx_dma_channels[i].sg = NULL;
+		imx_dma_channels[i].dma_num = i;
+	}
+
+	return ret;
+}
+
+arch_initcall(imx_dma_init);
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31ads.h b/arch/arm/plat-mxc/include/mach/board-mx31ads.h
index 1bc6fb0..745b488 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx31ads.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx31ads.h
@@ -90,6 +90,9 @@
 #define PBC_INTMASK_CLEAR_REG	(PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS)
 #define EXPIO_PARENT_INT	IOMUX_TO_IRQ(MX31_PIN_GPIO1_4)
 
+#define MXC_EXP_IO_BASE		(MXC_MAX_INT_LINES + MXC_MAX_GPIO_LINES)
+#define MXC_IRQ_TO_EXPIO(irq)	((irq) - MXC_EXP_IO_BASE)
+
 #define EXPIO_INT_LOW_BAT	(MXC_EXP_IO_BASE + 0)
 #define EXPIO_INT_PB_IRQ	(MXC_EXP_IO_BASE + 1)
 #define EXPIO_INT_OTG_FS_OVR	(MXC_EXP_IO_BASE + 2)
diff --git a/arch/arm/plat-mxc/include/mach/clock.h b/arch/arm/plat-mxc/include/mach/clock.h
index 24caa2b..d21f78e 100644
--- a/arch/arm/plat-mxc/include/mach/clock.h
+++ b/arch/arm/plat-mxc/include/mach/clock.h
@@ -39,7 +39,7 @@
 	/* Register bit position for clock's enable/disable control. */
 	u8 enable_shift;
 	/* Register address for clock's enable/disable control. */
-	u32 enable_reg;
+	void __iomem *enable_reg;
 	u32 flags;
 	/* get the current clock rate (always a fresh value) */
 	unsigned long (*get_rate) (struct clk *);
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index a6d2e24..6350287 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -11,10 +11,13 @@
 #ifndef __ASM_ARCH_MXC_COMMON_H__
 #define __ASM_ARCH_MXC_COMMON_H__
 
+struct platform_device;
+
 extern void mxc_map_io(void);
 extern void mxc_init_irq(void);
 extern void mxc_timer_init(const char *clk_timer);
 extern int mxc_clocks_init(unsigned long fref);
 extern int mxc_register_gpios(void);
+extern int mxc_register_device(struct platform_device *pdev, void *data);
 
 #endif
diff --git a/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h b/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h
new file mode 100644
index 0000000..e85fd94
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h
@@ -0,0 +1,89 @@
+/*
+ *  linux/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h
+ *
+ *  i.MX DMA registration and IRQ dispatching
+ *
+ * Copyright 2006 Pavel Pisa <pisa@cmp.felk.cvut.cz>
+ * Copyright 2008 Juergen Beisert, <kernel@pengutronix.de>
+ * Copyright 2008 Sascha Hauer, <s.hauer@pengutronix.de>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <asm/dma.h>
+
+#ifndef __ASM_ARCH_MXC_DMA_H
+#define __ASM_ARCH_MXC_DMA_H
+
+#define IMX_DMA_CHANNELS  16
+
+#define DMA_BASE IO_ADDRESS(DMA_BASE_ADDR)
+
+#define IMX_DMA_MEMSIZE_32	(0 << 4)
+#define IMX_DMA_MEMSIZE_8	(1 << 4)
+#define IMX_DMA_MEMSIZE_16	(2 << 4)
+#define IMX_DMA_TYPE_LINEAR	(0 << 10)
+#define IMX_DMA_TYPE_2D		(1 << 10)
+#define IMX_DMA_TYPE_FIFO	(2 << 10)
+
+#define IMX_DMA_ERR_BURST     (1 << 0)
+#define IMX_DMA_ERR_REQUEST   (1 << 1)
+#define IMX_DMA_ERR_TRANSFER  (1 << 2)
+#define IMX_DMA_ERR_BUFFER    (1 << 3)
+#define IMX_DMA_ERR_TIMEOUT   (1 << 4)
+
+int
+imx_dma_config_channel(int channel, unsigned int config_port,
+	unsigned int config_mem, unsigned int dmareq, int hw_chaining);
+
+void
+imx_dma_config_burstlen(int channel, unsigned int burstlen);
+
+int
+imx_dma_setup_single(int channel, dma_addr_t dma_address,
+		unsigned int dma_length, unsigned int dev_addr,
+		dmamode_t dmamode);
+
+int
+imx_dma_setup_sg(int channel, struct scatterlist *sg,
+		unsigned int sgcount, unsigned int dma_length,
+		unsigned int dev_addr, dmamode_t dmamode);
+
+int
+imx_dma_setup_handlers(int channel,
+		void (*irq_handler) (int, void *),
+		void (*err_handler) (int, void *, int), void *data);
+
+int
+imx_dma_setup_progression_handler(int channel,
+		void (*prog_handler) (int, void*, struct scatterlist*));
+
+void imx_dma_enable(int channel);
+
+void imx_dma_disable(int channel);
+
+int imx_dma_request(int channel, const char *name);
+
+void imx_dma_free(int channel);
+
+enum imx_dma_prio {
+	DMA_PRIO_HIGH = 0,
+	DMA_PRIO_MEDIUM = 1,
+	DMA_PRIO_LOW = 2
+};
+
+int imx_dma_request_by_prio(const char *name, enum imx_dma_prio prio);
+
+#endif	/* _ASM_ARCH_MXC_DMA_H */
diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
index b542433..1163202 100644
--- a/arch/arm/plat-mxc/include/mach/entry-macro.S
+++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
@@ -9,11 +9,17 @@
  * published by the Free Software Foundation.
  */
 
+#define AVIC_NIMASK	0x04
+
 	@ this macro disables fast irq (not implemented)
 	.macro	disable_fiq
 	.endm
 
 	.macro  get_irqnr_preamble, base, tmp
+	ldr	\base, =AVIC_IO_ADDRESS(AVIC_BASE_ADDR)
+#ifdef CONFIG_MXC_IRQ_PRIOR
+	ldr	r4, [\base, #AVIC_NIMASK]
+#endif
 	.endm
 
 	.macro  arch_ret_to_user, tmp1, tmp2
@@ -23,7 +29,6 @@
 	@ and returns its number in irqnr
 	@ and returns if an interrupt occured in irqstat
 	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-	ldr	\base, =AVIC_IO_ADDRESS(AVIC_BASE_ADDR)
 	@ Load offset & priority of the highest priority
 	@ interrupt pending from AVIC_NIVECSR
 	ldr	\irqstat, [\base, #0x40]
@@ -32,6 +37,11 @@
 	mov	\irqnr, \irqstat, asr #16
 	@ set zero flag if IRQ + 1 == 0
 	adds	\tmp, \irqnr, #1
+#ifdef CONFIG_MXC_IRQ_PRIOR
+	bicne	\tmp, \irqstat, #0xFFFFFFE0
+	strne	\tmp, [\base, #AVIC_NIMASK]
+	streq	r4, [\base, #AVIC_NIMASK]
+#endif
 	.endm
 
 	@ irq priority table (not used)
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx1-mx2.h b/arch/arm/plat-mxc/include/mach/iomux-mx1-mx2.h
index 076d37b..3d09bfd 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx1-mx2.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx1-mx2.h
@@ -247,6 +247,11 @@
 #endif
 
 #ifdef CONFIG_ARCH_MX2
+#define PA0_PF_USBH2_CLK	(GPIO_PORTA | GPIO_PF | 0)
+#define PA1_PF_USBH2_DIR	(GPIO_PORTA | GPIO_PF | 1)
+#define PA2_PF_USBH2_DATA7	(GPIO_PORTA | GPIO_PF | 2)
+#define PA3_PF_USBH2_NXT	(GPIO_PORTA | GPIO_PF | 3)
+#define PA4_PF_USBH2_STP	(GPIO_PORTA | GPIO_PF | 4)
 #define PA5_PF_LSCLK		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 5)
 #define PA6_PF_LD0		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 6)
 #define PA7_PF_LD1		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 7)
@@ -294,6 +299,16 @@
 #define PB20_AF_UART5_CTS	(GPIO_PORTB | GPIO_OUT | GPIO_AF | 20)
 #define PB21_PF_CSI_HSYNC	(GPIO_PORTB | GPIO_OUT | GPIO_PF | 21)
 #define PB21_AF_UART5_RTS	(GPIO_PORTB | GPIO_IN  | GPIO_AF | 21)
+#define PB22_PF_USBH1_SUSP	(GPIO_PORTB | GPIO_PF | 22)
+#define PB23_PF_USB_PWR		(GPIO_PORTB | GPIO_PF | 23)
+#define PB24_PF_USB_OC_B	(GPIO_PORTB | GPIO_PF | 24)
+#define PB25_PF_USBH1_RCV	(GPIO_PORTB | GPIO_PF | 25)
+#define PB26_PF_USBH1_FS	(GPIO_PORTB | GPIO_PF | 26)
+#define PB27_PF_USBH1_OE_B	(GPIO_PORTB | GPIO_PF | 27)
+#define PB28_PF_USBH1_TXDM	(GPIO_PORTB | GPIO_PF | 28)
+#define PB29_PF_USBH1_TXDP	(GPIO_PORTB | GPIO_PF | 29)
+#define PB30_PF_USBH1_RXDM	(GPIO_PORTB | GPIO_PF | 30)
+#define PB31_PF_USBH1_RXDP	(GPIO_PORTB | GPIO_PF | 31)
 #define PB26_AF_UART4_RTS	(GPIO_PORTB | GPIO_IN  | GPIO_PF | 26)
 #define PB28_AF_UART4_TXD	(GPIO_PORTB | GPIO_OUT | GPIO_AF | 28)
 #define PB29_AF_UART4_CTS	(GPIO_PORTB | GPIO_OUT | GPIO_AF | 29)
@@ -335,8 +350,15 @@
 #define PD16_AIN_FEC_TX_ER	(GPIO_PORTD | GPIO_OUT | GPIO_AIN | 16)
 #define PD17_PF_I2C_DATA	(GPIO_PORTD | GPIO_OUT | GPIO_PF | 17)
 #define PD18_PF_I2C_CLK		(GPIO_PORTD | GPIO_OUT | GPIO_PF | 18)
+#define PD19_AF_USBH2_DATA4	(GPIO_PORTD | GPIO_AF | 19)
+#define PD20_AF_USBH2_DATA3	(GPIO_PORTD | GPIO_AF | 20)
+#define PD21_AF_USBH2_DATA6	(GPIO_PORTD | GPIO_AF | 21)
+#define PD22_AF_USBH2_DATA0	(GPIO_PORTD | GPIO_AF | 22)
+#define PD23_AF_USBH2_DATA2	(GPIO_PORTD | GPIO_AF | 23)
+#define PD24_AF_USBH2_DATA1	(GPIO_PORTD | GPIO_AF | 24)
 #define PD25_PF_CSPI1_RDY	(GPIO_PORTD | GPIO_OUT | GPIO_PF  | 25)
 #define PD26_PF_CSPI1_SS2	(GPIO_PORTD | GPIO_OUT | GPIO_PF  | 26)
+#define PD26_AF_USBH2_DATA5     (GPIO_PORTD | GPIO_AF | 26)
 #define PD27_PF_CSPI1_SS1	(GPIO_PORTD | GPIO_OUT | GPIO_PF  | 27)
 #define PD28_PF_CSPI1_SS0	(GPIO_PORTD | GPIO_OUT | GPIO_PF  | 28)
 #define PD29_PF_CSPI1_SCLK	(GPIO_PORTD | GPIO_OUT | GPIO_PF  | 29)
@@ -355,6 +377,8 @@
 #define PE13_PF_UART1_RXD	(GPIO_PORTE | GPIO_IN  | GPIO_PF | 13)
 #define PE14_PF_UART1_CTS	(GPIO_PORTE | GPIO_OUT | GPIO_PF | 14)
 #define PE15_PF_UART1_RTS	(GPIO_PORTE | GPIO_IN  | GPIO_PF | 15)
+#define PE16_AF_RTCK		(GPIO_PORTE | GPIO_OUT | GPIO_AF | 16)
+#define PE16_PF_RTCK		(GPIO_PORTE | GPIO_OUT | GPIO_PF | 16)
 #define PE18_AF_CSPI3_MISO	(GPIO_PORTE | GPIO_IN  | GPIO_AF | 18)
 #define PE21_AF_CSPI3_SS	(GPIO_PORTE | GPIO_OUT | GPIO_AF | 21)
 #define PE22_AF_CSPI3_MOSI	(GPIO_PORTE | GPIO_OUT | GPIO_AF | 22)
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
index 7509e76..c9f39c2 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
@@ -491,6 +491,26 @@
 #define MX31_PIN_RTS1__RTS1		IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_TXD1__TXD1		IOMUX_MODE(MX31_PIN_TXD1, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_RXD1__RXD1		IOMUX_MODE(MX31_PIN_RXD1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI1_MOSI__MOSI	IOMUX_MODE(MX31_PIN_CSPI1_MOSI, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI1_MISO__MISO	IOMUX_MODE(MX31_PIN_CSPI1_MISO, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI1_SCLK__SCLK	IOMUX_MODE(MX31_PIN_CSPI1_SCLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI1_SPI_RDY__SPI_RDY	IOMUX_MODE(MX31_PIN_CSPI1_SPI_RDY, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI1_SS0__SS0		IOMUX_MODE(MX31_PIN_CSPI1_SS0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI1_SS1__SS1		IOMUX_MODE(MX31_PIN_CSPI1_SS1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI1_SS2__SS2		IOMUX_MODE(MX31_PIN_CSPI1_SS2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI2_MOSI__MOSI	IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI2_MISO__MISO	IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI2_SCLK__SCLK	IOMUX_MODE(MX31_PIN_CSPI2_SCLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI2_SPI_RDY__SPI_RDY	IOMUX_MODE(MX31_PIN_CSPI2_SPI_RDY, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI2_SS0__SS0		IOMUX_MODE(MX31_PIN_CSPI2_SS0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI2_SS1__SS1		IOMUX_MODE(MX31_PIN_CSPI2_SS1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI2_SS2__SS2		IOMUX_MODE(MX31_PIN_CSPI2_SS2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI3_MOSI__MOSI	IOMUX_MODE(MX31_PIN_CSPI3_MOSI, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI3_MISO__MISO	IOMUX_MODE(MX31_PIN_CSPI3_MISO, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI3_SCLK__SCLK	IOMUX_MODE(MX31_PIN_CSPI3_SCLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI3_SPI_RDY__SPI_RDY	IOMUX_MODE(MX31_PIN_CSPI3_SPI_RDY, IOMUX_CONFIG_FUNC)
+/*XXX: The SS0, SS1, SS2, SS3 lines of spi3 are multiplexed by cspi2_ss0, cspi2_ss1, cspi1_ss0
+ * cspi1_ss1*/
 
 /*
  * This function configures the pad value for a IOMUX pin.
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
index 228c4f6..b55bba3 100644
--- a/arch/arm/plat-mxc/include/mach/irqs.h
+++ b/arch/arm/plat-mxc/include/mach/irqs.h
@@ -12,5 +12,6 @@
 #define __ASM_ARCH_MXC_IRQS_H__
 
 #include <mach/hardware.h>
+extern void imx_irq_set_priority(unsigned char irq, unsigned char prio);
 
 #endif /* __ASM_ARCH_MXC_IRQS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx27.h b/arch/arm/plat-mxc/include/mach/mx27.h
index 212ecc2..a86db64 100644
--- a/arch/arm/plat-mxc/include/mach/mx27.h
+++ b/arch/arm/plat-mxc/include/mach/mx27.h
@@ -128,6 +128,7 @@
  * it returns 0xDEADBEEF
  */
 #define IO_ADDRESS(x)   \
+	(void __iomem *) \
 	(((x >= AIPI_BASE_ADDR) && (x < (AIPI_BASE_ADDR + AIPI_SIZE))) ? \
 		AIPI_IO_ADDRESS(x) : \
 	((x >= SAHB1_BASE_ADDR) && (x < (SAHB1_BASE_ADDR + SAHB1_SIZE))) ? \
diff --git a/arch/arm/plat-mxc/include/mach/mx31.h b/arch/arm/plat-mxc/include/mach/mx31.h
index a7373e4..0536f89 100644
--- a/arch/arm/plat-mxc/include/mach/mx31.h
+++ b/arch/arm/plat-mxc/include/mach/mx31.h
@@ -198,6 +198,7 @@
  * it returns 0xDEADBEEF
  */
 #define IO_ADDRESS(x)   \
+	(void __iomem *) \
 	(((x >= IRAM_BASE_ADDR) && (x < (IRAM_BASE_ADDR + IRAM_SIZE))) ? IRAM_IO_ADDRESS(x):\
 	((x >= L2CC_BASE_ADDR) && (x < (L2CC_BASE_ADDR + L2CC_SIZE))) ? L2CC_IO_ADDRESS(x):\
 	((x >= AIPS1_BASE_ADDR) && (x < (AIPS1_BASE_ADDR + AIPS1_SIZE))) ? AIPS1_IO_ADDRESS(x):\
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index 332eda4..f6caab0 100644
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -33,4 +33,10 @@
 # define cpu_is_mx27() (0)
 #endif
 
+#if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2)
+#define CSCR_U(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10)
+#define CSCR_L(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x4)
+#define CSCR_A(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x8)
+#endif
+
 #endif /*  __ASM_ARCH_MXC_H__ */
diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c
index 1053b66..d862c9e 100644
--- a/arch/arm/plat-mxc/irq.c
+++ b/arch/arm/plat-mxc/irq.c
@@ -18,7 +18,7 @@
  */
 
 #include <linux/irq.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <mach/common.h>
 
 #define AVIC_BASE		IO_ADDRESS(AVIC_BASE_ADDR)
@@ -30,14 +30,7 @@
 #define AVIC_INTENABLEL		(AVIC_BASE + 0x14)	/* int enable reg low */
 #define AVIC_INTTYPEH		(AVIC_BASE + 0x18)	/* int type reg high */
 #define AVIC_INTTYPEL		(AVIC_BASE + 0x1C)	/* int type reg low */
-#define AVIC_NIPRIORITY7	(AVIC_BASE + 0x20)	/* norm int priority lvl7 */
-#define AVIC_NIPRIORITY6	(AVIC_BASE + 0x24)	/* norm int priority lvl6 */
-#define AVIC_NIPRIORITY5	(AVIC_BASE + 0x28)	/* norm int priority lvl5 */
-#define AVIC_NIPRIORITY4	(AVIC_BASE + 0x2C)	/* norm int priority lvl4 */
-#define AVIC_NIPRIORITY3	(AVIC_BASE + 0x30)	/* norm int priority lvl3 */
-#define AVIC_NIPRIORITY2	(AVIC_BASE + 0x34)	/* norm int priority lvl2 */
-#define AVIC_NIPRIORITY1	(AVIC_BASE + 0x38)	/* norm int priority lvl1 */
-#define AVIC_NIPRIORITY0	(AVIC_BASE + 0x3C)	/* norm int priority lvl0 */
+#define AVIC_NIPRIORITY(x)	(AVIC_BASE + (0x20 + 4 * (7 - (x)))) /* int priority */
 #define AVIC_NIVECSR		(AVIC_BASE + 0x40)	/* norm int vector/status */
 #define AVIC_FIVECSR		(AVIC_BASE + 0x44)	/* fast int vector/status */
 #define AVIC_INTSRCH		(AVIC_BASE + 0x48)	/* int source reg high */
@@ -54,6 +47,24 @@
 #define IIM_PROD_REV_SH		3
 #define IIM_PROD_REV_LEN	5
 
+#ifdef CONFIG_MXC_IRQ_PRIOR
+void imx_irq_set_priority(unsigned char irq, unsigned char prio)
+{
+	unsigned int temp;
+	unsigned int mask = 0x0F << irq % 8 * 4;
+
+	if (irq > 63)
+		return;
+
+	temp = __raw_readl(AVIC_NIPRIORITY(irq / 8));
+	temp &= ~mask;
+	temp |= prio & mask;
+
+	__raw_writel(temp, AVIC_NIPRIORITY(irq / 8));
+}
+EXPORT_SYMBOL(imx_irq_set_priority);
+#endif
+
 /* Disable interrupt number "irq" in the AVIC */
 static void mxc_mask_irq(unsigned int irq)
 {
@@ -101,10 +112,9 @@
 		set_irq_flags(i, IRQF_VALID);
 	}
 
-	/* Set WDOG2's interrupt the highest priority level (bit 28-31) */
-	reg = __raw_readl(AVIC_NIPRIORITY6);
-	reg |= (0xF << 28);
-	__raw_writel(reg, AVIC_NIPRIORITY6);
+	/* Set default priority value (0) for all IRQ's */
+	for (i = 0; i < 8; i++)
+		__raw_writel(0, AVIC_NIPRIORITY(i));
 
 	/* init architectures chained interrupt handler */
 	mxc_register_gpios();
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 197974d..bf6a10c 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -22,8 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/cpufreq.h>
 #include <linux/debugfs.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include <mach/clock.h>
 
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index e3143fe..0843b88 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -18,12 +18,12 @@
 #include <linux/serial_8250.h>
 #include <linux/serial_reg.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
 #include <asm/mach/map.h>
-#include <asm/io.h>
 #include <asm/setup.h>
 
 #include <mach/common.h>
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
index ae1de30..b269024 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -20,9 +20,9 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/system.h>
 
 #define VERY_HI_RATE	900000000
diff --git a/arch/arm/plat-omap/debug-devices.c b/arch/arm/plat-omap/debug-devices.c
index 5b73bb2..e31154b 100644
--- a/arch/arm/plat-omap/debug-devices.c
+++ b/arch/arm/plat-omap/debug-devices.c
@@ -12,9 +12,9 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 
 #include <mach/board.h>
 #include <mach/gpio.h>
diff --git a/arch/arm/plat-omap/debug-leds.c b/arch/arm/plat-omap/debug-leds.c
index 9422dee..2f4c0ca 100644
--- a/arch/arm/plat-omap/debug-leds.c
+++ b/arch/arm/plat-omap/debug-leds.c
@@ -11,8 +11,8 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/leds.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <mach/hardware.h>
 #include <asm/leds.h>
 #include <asm/system.h>
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 6467f57..25232b2 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -13,15 +13,16 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
 
 #include <mach/tc.h>
 #include <mach/control.h>
 #include <mach/board.h>
+#include <mach/mmc.h>
 #include <mach/mux.h>
 #include <mach/gpio.h>
 #include <mach/menelaus.h>
@@ -191,25 +192,38 @@
 
 /*-------------------------------------------------------------------------*/
 
-#if	defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+#if	defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
+	defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
 
-#ifdef CONFIG_ARCH_OMAP24XX
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 #define	OMAP_MMC1_BASE		0x4809c000
-#define OMAP_MMC1_INT		INT_24XX_MMC_IRQ
-#else
-#define	OMAP_MMC1_BASE		0xfffb7800
-#define OMAP_MMC1_INT		INT_MMC
-#endif
-#define	OMAP_MMC2_BASE		0xfffb7c00	/* omap16xx only */
+#define	OMAP_MMC1_END		(OMAP_MMC1_BASE + 0x1fc)
+#define	OMAP_MMC1_INT		INT_24XX_MMC_IRQ
 
-static struct omap_mmc_conf mmc1_conf;
+#define	OMAP_MMC2_BASE		0x480b4000
+#define	OMAP_MMC2_END		(OMAP_MMC2_BASE + 0x1fc)
+#define	OMAP_MMC2_INT		INT_24XX_MMC2_IRQ
+
+#else
+
+#define	OMAP_MMC1_BASE		0xfffb7800
+#define	OMAP_MMC1_END		(OMAP_MMC1_BASE + 0x7f)
+#define OMAP_MMC1_INT		INT_MMC
+
+#define	OMAP_MMC2_BASE		0xfffb7c00	/* omap16xx only */
+#define	OMAP_MMC2_END		(OMAP_MMC2_BASE + 0x7f)
+#define	OMAP_MMC2_INT		INT_1610_MMC2
+
+#endif
+
+static struct omap_mmc_platform_data mmc1_data;
 
 static u64 mmc1_dmamask = 0xffffffff;
 
 static struct resource mmc1_resources[] = {
 	{
 		.start		= OMAP_MMC1_BASE,
-		.end		= OMAP_MMC1_BASE + 0x7f,
+		.end		= OMAP_MMC1_END,
 		.flags		= IORESOURCE_MEM,
 	},
 	{
@@ -223,26 +237,27 @@
 	.id		= 1,
 	.dev = {
 		.dma_mask	= &mmc1_dmamask,
-		.platform_data	= &mmc1_conf,
+		.platform_data	= &mmc1_data,
 	},
 	.num_resources	= ARRAY_SIZE(mmc1_resources),
 	.resource	= mmc1_resources,
 };
 
-#ifdef	CONFIG_ARCH_OMAP16XX
+#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
+	defined(CONFIG_ARCH_OMAP34XX)
 
-static struct omap_mmc_conf mmc2_conf;
+static struct omap_mmc_platform_data mmc2_data;
 
 static u64 mmc2_dmamask = 0xffffffff;
 
 static struct resource mmc2_resources[] = {
 	{
 		.start		= OMAP_MMC2_BASE,
-		.end		= OMAP_MMC2_BASE + 0x7f,
+		.end		= OMAP_MMC2_END,
 		.flags		= IORESOURCE_MEM,
 	},
 	{
-		.start		= INT_1610_MMC2,
+		.start		= OMAP_MMC2_INT,
 		.flags		= IORESOURCE_IRQ,
 	},
 };
@@ -252,26 +267,19 @@
 	.id		= 2,
 	.dev = {
 		.dma_mask	= &mmc2_dmamask,
-		.platform_data	= &mmc2_conf,
+		.platform_data	= &mmc2_data,
 	},
 	.num_resources	= ARRAY_SIZE(mmc2_resources),
 	.resource	= mmc2_resources,
 };
 #endif
 
-static void __init omap_init_mmc(void)
+static inline void omap_init_mmc_conf(const struct omap_mmc_config *mmc_conf)
 {
-	const struct omap_mmc_config	*mmc_conf;
-	const struct omap_mmc_conf	*mmc;
-
-	/* NOTE:  assumes MMC was never (wrongly) enabled */
-	mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
-	if (!mmc_conf)
+	if (cpu_is_omap2430() || cpu_is_omap34xx())
 		return;
 
-	/* block 1 is always available and has just one pinout option */
-	mmc = &mmc_conf->mmc[0];
-	if (mmc->enabled) {
+	if (mmc_conf->mmc[0].enabled) {
 		if (cpu_is_omap24xx()) {
 			omap_cfg_reg(H18_24XX_MMC_CMD);
 			omap_cfg_reg(H15_24XX_MMC_CLKI);
@@ -289,7 +297,7 @@
 				omap_cfg_reg(P20_1710_MMC_DATDIR0);
 			}
 		}
-		if (mmc->wire4) {
+		if (mmc_conf->mmc[0].wire4) {
 			if (cpu_is_omap24xx()) {
 				omap_cfg_reg(H14_24XX_MMC_DAT1);
 				omap_cfg_reg(E19_24XX_MMC_DAT2);
@@ -300,25 +308,35 @@
 			} else {
 				omap_cfg_reg(MMC_DAT1);
 				/* NOTE:  DAT2 can be on W10 (here) or M15 */
-				if (!mmc->nomux)
+				if (!mmc_conf->mmc[0].nomux)
 					omap_cfg_reg(MMC_DAT2);
 				omap_cfg_reg(MMC_DAT3);
 			}
 		}
-		mmc1_conf = *mmc;
-		(void) platform_device_register(&mmc_omap_device1);
+#if defined(CONFIG_ARCH_OMAP2420)
+		if (mmc_conf->mmc[0].internal_clock) {
+			/*
+			 * Use internal loop-back in MMC/SDIO
+			 * Module Input Clock selection
+			 */
+			if (cpu_is_omap24xx()) {
+				u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+				v |= (1 << 24); /* not used in 243x */
+				omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
+			}
+		}
+#endif
 	}
 
 #ifdef	CONFIG_ARCH_OMAP16XX
 	/* block 2 is on newer chips, and has many pinout options */
-	mmc = &mmc_conf->mmc[1];
-	if (mmc->enabled) {
-		if (!mmc->nomux) {
+	if (mmc_conf->mmc[1].enabled) {
+		if (!mmc_conf->mmc[1].nomux) {
 			omap_cfg_reg(Y8_1610_MMC2_CMD);
 			omap_cfg_reg(Y10_1610_MMC2_CLK);
 			omap_cfg_reg(R18_1610_MMC2_CLKIN);
 			omap_cfg_reg(W8_1610_MMC2_DAT0);
-			if (mmc->wire4) {
+			if (mmc_conf->mmc[1].wire4) {
 				omap_cfg_reg(V8_1610_MMC2_DAT1);
 				omap_cfg_reg(W15_1610_MMC2_DAT2);
 				omap_cfg_reg(R10_1610_MMC2_DAT3);
@@ -334,14 +352,55 @@
 		if (cpu_is_omap1710())
 			omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
 				     MOD_CONF_CTRL_1);
-		mmc2_conf = *mmc;
+	}
+#endif
+}
+
+static void __init omap_init_mmc(void)
+{
+	const struct omap_mmc_config	*mmc_conf;
+
+	/* NOTE:  assumes MMC was never (wrongly) enabled */
+	mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
+	if (!mmc_conf)
+		return;
+
+	omap_init_mmc_conf(mmc_conf);
+
+	if (mmc_conf->mmc[0].enabled) {
+		mmc1_data.conf = mmc_conf->mmc[0];
+		(void) platform_device_register(&mmc_omap_device1);
+	}
+
+#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
+	defined(CONFIG_ARCH_OMAP34XX)
+	if (mmc_conf->mmc[1].enabled) {
+		mmc2_data.conf = mmc_conf->mmc[1];
 		(void) platform_device_register(&mmc_omap_device2);
 	}
 #endif
-	return;
 }
+
+void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info)
+{
+	switch (host) {
+	case 1:
+		mmc1_data = *info;
+		break;
+#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
+	defined(CONFIG_ARCH_OMAP34XX)
+	case 2:
+		mmc2_data = *info;
+		break;
+#endif
+	default:
+		BUG();
+	}
+}
+
 #else
 static inline void omap_init_mmc(void) {}
+void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info) {}
 #endif
 
 /*-------------------------------------------------------------------------*/
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index df61ad2..963c31c 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -32,9 +32,9 @@
 #include <linux/list.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
 #include <mach/dmtimer.h>
-#include <asm/io.h>
 #include <mach/irqs.h>
 
 /* register offsets */
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
index 17a92a3..ce6b4ba 100644
--- a/arch/arm/plat-omap/fb.c
+++ b/arch/arm/plat-omap/fb.c
@@ -27,9 +27,9 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/bootmem.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/mach/map.h>
 
 #include <mach/board.h>
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 5de70d6..8679fbc 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -17,6 +17,7 @@
 #include <linux/sysdev.h>
 #include <linux/err.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
@@ -24,8 +25,6 @@
 #include <mach/gpio.h>
 #include <asm/mach/irq.h>
 
-#include <asm/io.h>
-
 /*
  * OMAP1510 GPIO registers
  */
@@ -1052,13 +1051,10 @@
 
 		gpio_irq = bank->virtual_irq_start;
 		for (; isr != 0; isr >>= 1, gpio_irq++) {
-			struct irq_desc *d;
-
 			if (!(isr & 1))
 				continue;
-			d = irq_desc + gpio_irq;
 
-			desc_handle_irq(gpio_irq, d);
+			generic_handle_irq(gpio_irq);
 		}
 	}
 	/* if bank has any level sensitive GPIO pin interrupt
diff --git a/arch/arm/plat-omap/include/mach/gpio.h b/arch/arm/plat-omap/include/mach/gpio.h
index 5bb7460..98e9008 100644
--- a/arch/arm/plat-omap/include/mach/gpio.h
+++ b/arch/arm/plat-omap/include/mach/gpio.h
@@ -26,8 +26,8 @@
 #ifndef __ASM_ARCH_OMAP_GPIO_H
 #define __ASM_ARCH_OMAP_GPIO_H
 
+#include <linux/io.h>
 #include <mach/irqs.h>
-#include <asm/io.h>
 
 #define OMAP_MPUIO_BASE			0xfffb5000
 
diff --git a/arch/arm/plat-omap/include/mach/irqs.h b/arch/arm/plat-omap/include/mach/irqs.h
index ed1c125..a2929ac 100644
--- a/arch/arm/plat-omap/include/mach/irqs.h
+++ b/arch/arm/plat-omap/include/mach/irqs.h
@@ -339,6 +339,8 @@
 #define INT_34XX_MMC3_IRQ	94
 #define INT_34XX_GPT12_IRQ	95
 
+#define	INT_34XX_BENCH_MPU_EMUL	3
+
 /* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730) and
  * 16 MPUIO lines */
 #define OMAP_MAX_GPIO_LINES	192
diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
index 1d7aec1..b52ce05 100644
--- a/arch/arm/plat-omap/mailbox.c
+++ b/arch/arm/plat-omap/mailbox.c
@@ -30,7 +30,7 @@
 #include <linux/blkdev.h>
 #include <linux/err.h>
 #include <linux/delay.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <mach/mailbox.h>
 #include "mailbox.h"
 
diff --git a/arch/arm/plat-omap/mux.c b/arch/arm/plat-omap/mux.c
index 847df20..80b040f 100644
--- a/arch/arm/plat-omap/mux.c
+++ b/arch/arm/plat-omap/mux.c
@@ -25,8 +25,8 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/io.h>
 #include <asm/system.h>
-#include <asm/io.h>
 #include <linux/spinlock.h>
 #include <mach/mux.h>
 
diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c
index 8bdbf97..ebe0c73 100644
--- a/arch/arm/plat-omap/ocpi.c
+++ b/arch/arm/plat-omap/ocpi.c
@@ -31,8 +31,8 @@
 #include <linux/spinlock.h>
 #include <linux/err.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <mach/hardware.h>
 
 #define OCPI_BASE		0xfffec320
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 4d22452..9f9a921 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -15,9 +15,9 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
 #include <asm/tlb.h>
-#include <asm/io.h>
 #include <asm/cacheflush.h>
 
 #include <asm/mach/map.h>
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c
index 777485e..67ca1e2 100644
--- a/arch/arm/plat-omap/usb.c
+++ b/arch/arm/plat-omap/usb.c
@@ -27,8 +27,8 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/usb/otg.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <mach/hardware.h>
diff --git a/arch/arm/plat-s3c24xx/clock.c b/arch/arm/plat-s3c24xx/clock.c
index 54d4b8e..4005413 100644
--- a/arch/arm/plat-s3c24xx/clock.c
+++ b/arch/arm/plat-s3c24xx/clock.c
@@ -39,10 +39,10 @@
 #include <linux/clk.h>
 #include <linux/mutex.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 
 #include <mach/regs-clock.h>
 #include <mach/regs-gpio.h>
diff --git a/arch/arm/plat-s3c24xx/common-smdk.c b/arch/arm/plat-s3c24xx/common-smdk.c
index 1863a1b..d528f46 100644
--- a/arch/arm/plat-s3c24xx/common-smdk.c
+++ b/arch/arm/plat-s3c24xx/common-smdk.c
@@ -25,6 +25,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -32,7 +33,6 @@
 
 #include <asm/mach-types.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 
 #include <mach/regs-gpio.h>
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
index 89ce60e..9c607bb 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -29,11 +29,11 @@
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/delay.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/delay.h>
 #include <asm/cacheflush.h>
 
 #include <asm/mach/arch.h>
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c
index d6fb765..6b13b54 100644
--- a/arch/arm/plat-s3c24xx/devs.c
+++ b/arch/arm/plat-s3c24xx/devs.c
@@ -19,13 +19,13 @@
 #include <linux/init.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 #include <mach/fb.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 
 #include <asm/plat-s3c/regs-serial.h>
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index 08c2aaf..d634446 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -26,11 +26,11 @@
 #include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 
 #include <asm/system.h>
 #include <asm/irq.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/dma.h>
 
 #include <asm/mach/dma.h>
diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c
index dd27334..4a899c2 100644
--- a/arch/arm/plat-s3c24xx/gpio.c
+++ b/arch/arm/plat-s3c24xx/gpio.c
@@ -26,10 +26,10 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 
 #include <mach/regs-gpio.h>
 
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index 36cefe1..590fc5a 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -55,10 +55,10 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/sysdev.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 
 #include <asm/mach/irq.h>
 
@@ -468,7 +468,6 @@
 {
 	unsigned int subsrc, submsk;
 	unsigned int offset = 9;
-	struct irq_desc *mydesc;
 
 	/* read the current pending interrupts, and the mask
 	 * for what it is available */
@@ -482,12 +481,10 @@
 
 	if (subsrc != 0) {
 		if (subsrc & 1) {
-			mydesc = irq_desc + IRQ_TC;
-			desc_handle_irq(IRQ_TC, mydesc);
+			generic_handle_irq(IRQ_TC);
 		}
 		if (subsrc & 2) {
-			mydesc = irq_desc + IRQ_ADC;
-			desc_handle_irq(IRQ_ADC, mydesc);
+			generic_handle_irq(IRQ_ADC);
 		}
 	}
 }
@@ -496,7 +493,6 @@
 {
 	unsigned int subsrc, submsk;
 	unsigned int offset = start - IRQ_S3CUART_RX0;
-	struct irq_desc *desc;
 
 	/* read the current pending interrupts, and the mask
 	 * for what it is available */
@@ -512,20 +508,14 @@
 	subsrc &= 7;
 
 	if (subsrc != 0) {
-		desc = irq_desc + start;
-
 		if (subsrc & 1)
-			desc_handle_irq(start, desc);
-
-		desc++;
+			generic_handle_irq(start);
 
 		if (subsrc & 2)
-			desc_handle_irq(start+1, desc);
-
-		desc++;
+			generic_handle_irq(start+1);
 
 		if (subsrc & 4)
-			desc_handle_irq(start+2, desc);
+			generic_handle_irq(start+2);
 	}
 }
 
@@ -572,7 +562,7 @@
 		eintpnd &= ~(1<<irq);
 
 		irq += (IRQ_EINT4 - 4);
-		desc_handle_irq(irq, irq_desc + irq);
+		generic_handle_irq(irq);
 	}
 
 }
@@ -595,7 +585,7 @@
 
 		irq += (IRQ_EINT4 - 4);
 
-		desc_handle_irq(irq, irq_desc + irq);
+		generic_handle_irq(irq);
 	}
 }
 
diff --git a/arch/arm/plat-s3c24xx/pm-simtec.c b/arch/arm/plat-s3c24xx/pm-simtec.c
index e670501..0a074d3 100644
--- a/arch/arm/plat-s3c24xx/pm-simtec.c
+++ b/arch/arm/plat-s3c24xx/pm-simtec.c
@@ -20,12 +20,12 @@
 #include <linux/init.h>
 #include <linux/sysdev.h>
 #include <linux/device.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 
 #include <mach/map.h>
 #include <mach/regs-gpio.h>
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c
index fc4b731..d3934b1 100644
--- a/arch/arm/plat-s3c24xx/pm.c
+++ b/arch/arm/plat-s3c24xx/pm.c
@@ -35,10 +35,10 @@
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/serial_core.h>
+#include <linux/io.h>
 
 #include <asm/cacheflush.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 
 #include <asm/plat-s3c/regs-serial.h>
 #include <mach/regs-clock.h>
diff --git a/arch/arm/plat-s3c24xx/s3c244x-clock.c b/arch/arm/plat-s3c24xx/s3c244x-clock.c
index 8a5fffd..119647a 100644
--- a/arch/arm/plat-s3c24xx/s3c244x-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c244x-clock.c
@@ -33,11 +33,11 @@
 #include <linux/ioport.h>
 #include <linux/mutex.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/atomic.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 
 #include <mach/regs-clock.h>
 
diff --git a/arch/arm/plat-s3c24xx/s3c244x-irq.c b/arch/arm/plat-s3c24xx/s3c244x-irq.c
index f3dc38c..0601c5f 100644
--- a/arch/arm/plat-s3c24xx/s3c244x-irq.c
+++ b/arch/arm/plat-s3c24xx/s3c244x-irq.c
@@ -24,10 +24,10 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/sysdev.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 
 #include <asm/mach/irq.h>
 
@@ -44,7 +44,6 @@
 			      struct irq_desc *desc)
 {
 	unsigned int subsrc, submsk;
-	struct irq_desc *mydesc;
 
 	/* read the current pending interrupts, and the mask
 	 * for what it is available */
@@ -58,12 +57,10 @@
 
 	if (subsrc != 0) {
 		if (subsrc & 1) {
-			mydesc = irq_desc + IRQ_S3C2440_CAM_C;
-			desc_handle_irq(IRQ_S3C2440_CAM_C, mydesc);
+			generic_handle_irq(IRQ_S3C2440_CAM_C);
 		}
 		if (subsrc & 2) {
-			mydesc = irq_desc + IRQ_S3C2440_CAM_P;
-			desc_handle_irq(IRQ_S3C2440_CAM_P, mydesc);
+			generic_handle_irq(IRQ_S3C2440_CAM_P);
 		}
 	}
 }
diff --git a/arch/arm/plat-s3c24xx/s3c244x.c b/arch/arm/plat-s3c24xx/s3c244x.c
index 281b480..146863a 100644
--- a/arch/arm/plat-s3c24xx/s3c244x.c
+++ b/arch/arm/plat-s3c24xx/s3c244x.c
@@ -20,13 +20,13 @@
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 
 #include <mach/regs-clock.h>
diff --git a/arch/arm/plat-s3c24xx/time.c b/arch/arm/plat-s3c24xx/time.c
index b471a21..64bfa19 100644
--- a/arch/arm/plat-s3c24xx/time.c
+++ b/arch/arm/plat-s3c24xx/time.c
@@ -25,12 +25,12 @@
 #include <linux/irq.h>
 #include <linux/err.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
 #include <asm/system.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <mach/map.h>
 #include <asm/plat-s3c/regs-timer.h>
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 56281c0..43aa202 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Wed Aug 13 21:56:02 2008
+# Last update: Thu Sep 25 10:10:50 2008
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -1810,7 +1810,7 @@
 pilz_pmi5		MACH_PILZ_PMI5		PILZ_PMI5		1820
 jade			MACH_JADE		JADE			1821
 ks8695_softplc		MACH_KS8695_SOFTPLC	KS8695_SOFTPLC		1822
-gprisc3			MACH_GPRISC4		GPRISC4			1823
+gprisc3			MACH_GPRISC3		GPRISC3			1823
 stamp9260		MACH_STAMP9260		STAMP9260		1824
 smdk6430		MACH_SMDK6430		SMDK6430		1825
 smdkc100		MACH_SMDKC100		SMDKC100		1826
@@ -1859,5 +1859,43 @@
 ginza			MACH_GINZA		GINZA			1869
 a636n			MACH_A636N		A636N			1870
 imx27ipcam		MACH_IMX27IPCAM		IMX27IPCAM		1871
-nenoc			MACH_NEMOC		NEMOC			1872
+nemoc			MACH_NEMOC		NEMOC			1872
 geneva			MACH_GENEVA		GENEVA			1873
+htcpharos		MACH_HTCPHAROS		HTCPHAROS		1874
+neonc			MACH_NEONC		NEONC			1875
+nas7100			MACH_NAS7100		NAS7100			1876
+teuphone		MACH_TEUPHONE		TEUPHONE		1877
+annax_eth2		MACH_ANNAX_ETH2		ANNAX_ETH2		1878
+csb733			MACH_CSB733		CSB733			1879
+bk3			MACH_BK3		BK3			1880
+omap_em32		MACH_OMAP_EM32		OMAP_EM32		1881
+et9261cp		MACH_ET9261CP		ET9261CP		1882
+jasperc			MACH_JASPERC		JASPERC			1883
+issi_arm9		MACH_ISSI_ARM9		ISSI_ARM9		1884
+ued			MACH_UED		UED			1885
+esiblade		MACH_ESIBLADE		ESIBLADE		1886
+eye02			MACH_EYE02		EYE02			1887
+imx27kbd		MACH_IMX27KBD		IMX27KBD		1888
+sst61vc010_fpga		MACH_SST61VC010_FPGA	SST61VC010_FPGA		1889
+kixvp435		MACH_KIXVP435		KIXVP435		1890
+kixnp435		MACH_KIXNP435		KIXNP435		1891
+africa			MACH_AFRICA		AFRICA			1892
+nh233			MACH_NH233		NH233			1893
+rd88f6183ap_ge		MACH_RD88F6183AP_GE	RD88F6183AP_GE		1894
+bcm4760			MACH_BCM4760		BCM4760			1895
+eddy_v2			MACH_EDDY_V2		EDDY_V2			1896
+realview_pba8		MACH_REALVIEW_PBA8	REALVIEW_PBA8		1897
+hid_a7			MACH_HID_A7		HID_A7			1898
+hero			MACH_HERO		HERO			1899
+omap_poseidon		MACH_OMAP_POSEIDON	OMAP_POSEIDON		1900
+realview_pbx		MACH_REALVIEW_PBX	REALVIEW_PBX		1901
+micro9s			MACH_MICRO9S		MICRO9S			1902
+mako			MACH_MAKO		MAKO			1903
+xdaflame		MACH_XDAFLAME		XDAFLAME		1904
+phidget_sbc2		MACH_PHIDGET_SBC2	PHIDGET_SBC2		1905
+limestone		MACH_LIMESTONE		LIMESTONE		1906
+iprobe_c32		MACH_IPROBE_C32		IPROBE_C32		1907
+rut100			MACH_RUT100		RUT100			1908
+asusp535		MACH_ASUSP535		ASUSP535		1909
+htcraphael		MACH_HTCRAPHAEL		HTCRAPHAEL		1910
+sygdg1			MACH_SYGDG1		SYGDG1			1911
diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S
index 806ce26..ba592a9 100644
--- a/arch/arm/vfp/entry.S
+++ b/arch/arm/vfp/entry.S
@@ -21,13 +21,13 @@
 #include <asm/assembler.h>
 #include <asm/vfpmacros.h>
 
-	.globl	do_vfp
-do_vfp:
+ENTRY(do_vfp)
 	enable_irq
  	ldr	r4, .LCvfp
 	ldr	r11, [r10, #TI_CPU]	@ CPU number
 	add	r10, r10, #TI_VFPSTATE	@ r10 = workspace
 	ldr	pc, [r4]		@ call VFP entry point
+ENDPROC(do_vfp)
 
 ENTRY(vfp_null_entry)
 	mov	pc, lr
@@ -40,11 +40,11 @@
 @ failure to the VFP initialisation code.
 
 	__INIT
-	.globl	vfp_testing_entry
-vfp_testing_entry:
+ENTRY(vfp_testing_entry)
 	ldr	r0, VFP_arch_address
 	str	r5, [r0]		@ known non-zero value
 	mov	pc, r9			@ we have handled the fault
+ENDPROC(vfp_testing_entry)
 
 VFP_arch_address:
 	.word	VFP_arch
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index 353f9e5..a62dcf7 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -68,8 +68,7 @@
 @  r11 = CPU number
 @  lr  = failure return
 
-	.globl	vfp_support_entry
-vfp_support_entry:
+ENTRY(vfp_support_entry)
 	DBGSTR3	"instr %08x pc %08x state %p", r0, r2, r10
 
 	VFPFMRX	r1, FPEXC		@ Is the VFP enabled?
@@ -165,11 +164,10 @@
 					@ code will raise an exception if
 					@ required. If not, the user code will
 					@ retry the faulted instruction
+ENDPROC(vfp_support_entry)
 
 #ifdef CONFIG_SMP
-	.globl	vfp_save_state
-	.type	vfp_save_state, %function
-vfp_save_state:
+ENTRY(vfp_save_state)
 	@ Save the current VFP state
 	@ r0 - save location
 	@ r1 - FPEXC
@@ -182,13 +180,13 @@
 	VFPFMRX	r12, FPINST2, NE	@ FPINST2 if needed (and present)
 	stmia	r0, {r1, r2, r3, r12}	@ save FPEXC, FPSCR, FPINST, FPINST2
 	mov	pc, lr
+ENDPROC(vfp_save_state)
 #endif
 
 last_VFP_context_address:
 	.word	last_VFP_context
 
-	.globl	vfp_get_float
-vfp_get_float:
+ENTRY(vfp_get_float)
 	add	pc, pc, r0, lsl #3
 	mov	r0, r0
 	.irp	dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
@@ -197,9 +195,9 @@
 	mrc	p10, 0, r0, c\dr, c0, 4	@ fmrs	r0, s1
 	mov	pc, lr
 	.endr
+ENDPROC(vfp_get_float)
 
-	.globl	vfp_put_float
-vfp_put_float:
+ENTRY(vfp_put_float)
 	add	pc, pc, r1, lsl #3
 	mov	r0, r0
 	.irp	dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
@@ -208,9 +206,9 @@
 	mcr	p10, 0, r0, c\dr, c0, 4	@ fmsr	r0, s1
 	mov	pc, lr
 	.endr
+ENDPROC(vfp_put_float)
 
-	.globl	vfp_get_double
-vfp_get_double:
+ENTRY(vfp_get_double)
 	add	pc, pc, r0, lsl #3
 	mov	r0, r0
 	.irp	dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
@@ -229,9 +227,9 @@
 	mov	r0, #0
 	mov	r1, #0
 	mov	pc, lr
+ENDPROC(vfp_get_double)
 
-	.globl	vfp_put_double
-vfp_put_double:
+ENTRY(vfp_put_double)
 	add	pc, pc, r2, lsl #3
 	mov	r0, r0
 	.irp	dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
@@ -245,3 +243,4 @@
 	mov	pc, lr
 	.endr
 #endif
+ENDPROC(vfp_put_double)
diff --git a/arch/avr32/kernel/asm-offsets.c b/arch/avr32/kernel/asm-offsets.c
index e4796c6..d6a8193 100644
--- a/arch/avr32/kernel/asm-offsets.c
+++ b/arch/avr32/kernel/asm-offsets.c
@@ -4,6 +4,8 @@
  * to extract and format the required data.
  */
 
+#include <linux/mm.h>
+#include <linux/sched.h>
 #include <linux/thread_info.h>
 #include <linux/kbuild.h>
 
@@ -17,4 +19,8 @@
 	OFFSET(TI_rar_saved, thread_info, rar_saved);
 	OFFSET(TI_rsr_saved, thread_info, rsr_saved);
 	OFFSET(TI_restart_block, thread_info, restart_block);
+	BLANK();
+	OFFSET(TSK_active_mm, task_struct, active_mm);
+	BLANK();
+	OFFSET(MM_pgd, mm_struct, pgd);
 }
diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S
index 2b398ca..33d4937 100644
--- a/arch/avr32/kernel/entry-avr32b.S
+++ b/arch/avr32/kernel/entry-avr32b.S
@@ -334,9 +334,64 @@
 
 	/* Low-level exception handlers */
 handle_critical:
+	/*
+	 * AT32AP700x errata:
+	 *
+	 * After a Java stack overflow or underflow trap, any CPU
+	 * memory access may cause erratic behavior. This will happen
+	 * when the four least significant bits of the JOSP system
+	 * register contains any value between 9 and 15 (inclusive).
+	 *
+	 * Possible workarounds:
+	 *   - Don't use the Java Extension Module
+	 *   - Ensure that the stack overflow and underflow trap
+	 *     handlers do not do any memory access or trigger any
+	 *     exceptions before the overflow/underflow condition is
+	 *     cleared (by incrementing or decrementing the JOSP)
+	 *   - Make sure that JOSP does not contain any problematic
+	 *     value before doing any exception or interrupt
+	 *     processing.
+	 *   - Set up a critical exception handler which writes a
+	 *     known-to-be-safe value, e.g. 4, to JOSP before doing
+	 *     any further processing.
+	 *
+	 * We'll use the last workaround for now since we cannot
+	 * guarantee that user space processes don't use Java mode.
+	 * Non-well-behaving userland will be terminated with extreme
+	 * prejudice.
+	 */
+#ifdef CONFIG_CPU_AT32AP700X
+	/*
+	 * There's a chance we can't touch memory, so temporarily
+	 * borrow PTBR to save the stack pointer while we fix things
+	 * up...
+	 */
+	mtsr	SYSREG_PTBR, sp
+	mov	sp, 4
+	mtsr	SYSREG_JOSP, sp
+	mfsr	sp, SYSREG_PTBR
+	sub	pc, -2
+
+	/* Push most of pt_regs on stack. We'll do the rest later */
 	sub	sp, 4
-	stmts	--sp, r0-lr
-	rcall	save_full_context_ex
+	pushm	r0-r12
+
+	/* PTBR mirrors current_thread_info()->task->active_mm->pgd */
+	get_thread_info r0
+	ld.w	r1, r0[TI_task]
+	ld.w	r2, r1[TSK_active_mm]
+	ld.w	r3, r2[MM_pgd]
+	mtsr	SYSREG_PTBR, r3
+#else
+	sub	sp, 4
+	pushm	r0-r12
+#endif
+	sub	r0, sp, -(14 * 4)
+	mov	r1, lr
+	mfsr	r2, SYSREG_RAR_EX
+	mfsr	r3, SYSREG_RSR_EX
+	pushm	r0-r3
+
 	mfsr	r12, SYSREG_ECR
 	mov	r11, sp
 	rcall	do_critical_exception
diff --git a/arch/avr32/mach-at32ap/pm-at32ap700x.S b/arch/avr32/mach-at32ap/pm-at32ap700x.S
index 5be4de6..17503b0 100644
--- a/arch/avr32/mach-at32ap/pm-at32ap700x.S
+++ b/arch/avr32/mach-at32ap/pm-at32ap700x.S
@@ -134,7 +134,7 @@
 	mov	r11, SDRAMC_LPR_LPCB_SELF_RFR
 	bfins	r10, r11, 0, 2		/* LPCB <- self Refresh */
 	sync	0			/* flush write buffer */
-	st.w	r12[SDRAMC_LPR], r11	/* put SDRAM in self-refresh mode */
+	st.w	r12[SDRAMC_LPR], r10	/* put SDRAM in self-refresh mode */
 	ld.w	r11, r12[SDRAMC_LPR]
 	unmask_interrupts
 	sleep	CPU_SLEEP_FROZEN
diff --git a/arch/ia64/include/asm/elf.h b/arch/ia64/include/asm/elf.h
index 5e0c1a6..2acb6b6 100644
--- a/arch/ia64/include/asm/elf.h
+++ b/arch/ia64/include/asm/elf.h
@@ -266,4 +266,19 @@
 	}								\
 } while (0)
 
+/*
+ * format for entries in the Global Offset Table
+ */
+struct got_entry {
+	uint64_t val;
+};
+
+/*
+ * Layout of the Function Descriptor
+ */
+struct fdesc {
+	uint64_t ip;
+	uint64_t gp;
+};
+
 #endif /* _ASM_IA64_ELF_H */
diff --git a/arch/ia64/include/asm/sections.h b/arch/ia64/include/asm/sections.h
index 7286e4a..f667998 100644
--- a/arch/ia64/include/asm/sections.h
+++ b/arch/ia64/include/asm/sections.h
@@ -6,6 +6,8 @@
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
+#include <linux/elf.h>
+#include <linux/uaccess.h>
 #include <asm-generic/sections.h>
 
 extern char __per_cpu_start[], __per_cpu_end[], __phys_per_cpu_start[];
@@ -21,5 +23,17 @@
 extern char __start_unwind[], __end_unwind[];
 extern char __start_ivt_text[], __end_ivt_text[];
 
+#undef dereference_function_descriptor
+static inline void *dereference_function_descriptor(void *ptr)
+{
+	struct fdesc *desc = ptr;
+	void *p;
+
+	if (!probe_kernel_address(&desc->ip, p))
+		ptr = p;
+	return ptr;
+}
+
+
 #endif /* _ASM_IA64_SECTIONS_H */
 
diff --git a/arch/ia64/include/asm/sn/bte.h b/arch/ia64/include/asm/sn/bte.h
index a0d214f..5efecf0 100644
--- a/arch/ia64/include/asm/sn/bte.h
+++ b/arch/ia64/include/asm/sn/bte.h
@@ -223,10 +223,11 @@
  * until the transfer is complete.  In order to get the asynch
  * version of bte_copy, you must perform this check yourself.
  */
-#define BTE_UNALIGNED_COPY(src, dest, len, mode)                        \
-	(((len & L1_CACHE_MASK) || (src & L1_CACHE_MASK) ||             \
-	  (dest & L1_CACHE_MASK)) ?                                     \
-	 bte_unaligned_copy(src, dest, len, mode) :              	\
+#define BTE_UNALIGNED_COPY(src, dest, len, mode)			\
+	(((len & (L1_CACHE_BYTES - 1)) ||				\
+	  (src & (L1_CACHE_BYTES - 1)) ||				\
+	  (dest & (L1_CACHE_BYTES - 1))) ?				\
+	 bte_unaligned_copy(src, dest, len, mode) :			\
 	 bte_copy(src, dest, len, mode, NULL))
 
 
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
index 29aad34..aaa7d90 100644
--- a/arch/ia64/kernel/module.c
+++ b/arch/ia64/kernel/module.c
@@ -135,15 +135,6 @@
 
 #undef N
 
-struct got_entry {
-	uint64_t val;
-};
-
-struct fdesc {
-	uint64_t ip;
-	uint64_t gp;
-};
-
 /* Opaque struct for insns, to protect against derefs. */
 struct insn;
 
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index bcea81e..d8f05e5 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -741,16 +741,14 @@
 			return -EBUSY;
 	}
 
-	cpu_clear(cpu, cpu_online_map);
-
 	if (migrate_platform_irqs(cpu)) {
 		cpu_set(cpu, cpu_online_map);
 		return (-EBUSY);
 	}
 
 	remove_siblinginfo(cpu);
-	cpu_clear(cpu, cpu_online_map);
 	fixup_irqs();
+	cpu_clear(cpu, cpu_online_map);
 	local_flush_tlb_all();
 	cpu_clear(cpu, cpu_callin_map);
 	return 0;
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c
index 529462c..79165122 100644
--- a/arch/ia64/sn/pci/tioca_provider.c
+++ b/arch/ia64/sn/pci/tioca_provider.c
@@ -420,8 +420,10 @@
 		entry = find_next_zero_bit(map, mapsize, last_entry);
 	}
 
-	if (entry > mapsize)
+	if (entry > mapsize) {
+		kfree(ca_dmamap);
 		goto map_return;
+	}
 
 	for (i = 0; i < entries; i++)
 		set_bit(entry + i, map);
diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig
index 8e2a0f5..8bd61a64 100644
--- a/arch/m68k/configs/amiga_defconfig
+++ b/arch/m68k/configs/amiga_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:00 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -166,10 +172,6 @@
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_ZORRO_NAMES=y
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -183,6 +185,7 @@
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -413,6 +416,7 @@
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -432,7 +436,9 @@
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -460,6 +466,7 @@
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -470,6 +477,7 @@
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
@@ -489,8 +497,6 @@
 CONFIG_BLK_DEV_IDEDOUBLER=y
 CONFIG_BLK_DEV_BUDDHA=y
 # CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
@@ -556,6 +562,7 @@
 CONFIG_GVP11_SCSI=y
 CONFIG_SCSI_A4000T=y
 CONFIG_SCSI_ZORRO7XX=y
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -564,7 +571,7 @@
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -573,13 +580,9 @@
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -722,6 +725,7 @@
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -757,6 +761,7 @@
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -768,8 +773,10 @@
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -844,10 +851,6 @@
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
 CONFIG_SOUND=m
 CONFIG_DMASOUND_PAULA=m
 CONFIG_DMASOUND=m
@@ -861,6 +864,7 @@
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
@@ -899,6 +903,7 @@
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -958,6 +963,7 @@
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -980,7 +986,6 @@
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
 CONFIG_SUNRPC_GSS=m
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=m
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -989,7 +994,6 @@
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -1054,6 +1058,8 @@
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -1113,6 +1119,10 @@
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1154,6 +1164,7 @@
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig
index e2d511e..c41b854 100644
--- a/arch/m68k/configs/apollo_defconfig
+++ b/arch/m68k/configs/apollo_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:01 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -161,10 +167,6 @@
 CONFIG_PROC_HARDWARE=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -178,6 +180,7 @@
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -411,6 +414,7 @@
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -430,7 +434,9 @@
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -448,6 +454,7 @@
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -499,6 +506,7 @@
 CONFIG_SCSI_LOWLEVEL=y
 CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -507,7 +515,7 @@
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -516,13 +524,9 @@
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -532,7 +536,6 @@
 # CONFIG_PHYLIB is not set
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
-CONFIG_APOLLO_ELPLUS=y
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -627,6 +630,7 @@
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -657,6 +661,7 @@
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -668,8 +673,10 @@
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -738,10 +745,6 @@
 CONFIG_LOGO_LINUX_MONO=y
 # CONFIG_LOGO_LINUX_VGA16 is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
@@ -753,6 +756,7 @@
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 
 #
@@ -789,6 +793,7 @@
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -848,6 +853,7 @@
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -860,18 +866,17 @@
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -880,7 +885,6 @@
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -944,6 +948,8 @@
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -1003,6 +1009,10 @@
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1044,6 +1054,7 @@
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig
index 6e20d65..654c5ac 100644
--- a/arch/m68k/configs/atari_defconfig
+++ b/arch/m68k/configs/atari_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:02 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -162,10 +168,6 @@
 CONFIG_PROC_HARDWARE=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -179,6 +181,7 @@
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -409,6 +412,7 @@
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -428,7 +432,9 @@
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -452,6 +458,7 @@
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -462,6 +469,7 @@
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
@@ -479,8 +487,6 @@
 # CONFIG_BLK_DEV_PLATFORM is not set
 CONFIG_BLK_DEV_FALCON_IDE=y
 # CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
@@ -530,6 +536,7 @@
 CONFIG_ATARI_SCSI=y
 # CONFIG_ATARI_SCSI_TOSHIBA_DELAY is not set
 # CONFIG_ATARI_SCSI_RESET_BOOT is not set
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -538,7 +545,7 @@
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -547,13 +554,9 @@
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -666,6 +669,7 @@
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -700,6 +704,7 @@
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -711,8 +716,10 @@
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -782,10 +789,6 @@
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
 CONFIG_SOUND=m
 CONFIG_DMASOUND_ATARI=m
 CONFIG_DMASOUND=m
@@ -799,6 +802,7 @@
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
@@ -806,11 +810,8 @@
 # Character devices
 #
 CONFIG_ATARI_MFPSER=m
-CONFIG_ATARI_SCC=y
-CONFIG_ATARI_SCC_DMA=y
 CONFIG_ATARI_MIDI=m
 CONFIG_ATARI_DSP56K=m
-# CONFIG_SERIAL_CONSOLE is not set
 
 #
 # File systems
@@ -820,8 +821,10 @@
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
-# CONFIG_EXT4DEV_FS is not set
+CONFIG_EXT4DEV_FS=y
+# CONFIG_EXT4DEV_FS_XATTR is not set
 CONFIG_JBD=y
+CONFIG_JBD2=y
 CONFIG_REISERFS_FS=m
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_REISERFS_PROC_INFO is not set
@@ -840,6 +843,7 @@
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -899,6 +903,7 @@
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -920,7 +925,6 @@
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-CONFIG_SUNRPC_BIND34=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -929,7 +933,6 @@
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -994,6 +997,8 @@
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -1053,6 +1058,10 @@
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1094,6 +1103,7 @@
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig
index a0a9b30..2e44af0 100644
--- a/arch/m68k/configs/bvme6000_defconfig
+++ b/arch/m68k/configs/bvme6000_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:03 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -163,10 +169,6 @@
 CONFIG_PROC_HARDWARE=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -180,6 +182,7 @@
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -413,6 +416,7 @@
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -432,7 +436,9 @@
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -450,6 +456,7 @@
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -503,6 +510,7 @@
 CONFIG_53C700_BE_BUS=y
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_BVME6000_SCSI=y
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -511,7 +519,7 @@
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -520,13 +528,9 @@
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -631,6 +635,7 @@
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -661,6 +666,7 @@
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -672,8 +678,10 @@
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -708,10 +716,6 @@
 # Console display driver support
 #
 CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
@@ -723,6 +727,7 @@
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 
 #
@@ -759,6 +764,7 @@
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -818,6 +824,7 @@
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -830,18 +837,17 @@
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -850,7 +856,6 @@
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -915,6 +920,8 @@
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -974,6 +981,10 @@
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1015,6 +1026,7 @@
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=m
 # CONFIG_CRC7 is not set
diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig
index 6778041..3570fc8 100644
--- a/arch/m68k/configs/hp300_defconfig
+++ b/arch/m68k/configs/hp300_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:04 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -162,10 +168,6 @@
 CONFIG_PROC_HARDWARE=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -179,6 +181,7 @@
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -412,6 +415,7 @@
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -431,7 +435,9 @@
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -449,6 +455,7 @@
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -500,6 +507,7 @@
 CONFIG_SCSI_LOWLEVEL=y
 CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -508,7 +516,7 @@
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -517,13 +525,9 @@
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -636,6 +640,7 @@
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -666,6 +671,7 @@
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -677,8 +683,10 @@
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -747,10 +755,6 @@
 # CONFIG_LOGO_LINUX_MONO is not set
 # CONFIG_LOGO_LINUX_VGA16 is not set
 CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
@@ -762,6 +766,7 @@
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 
 #
@@ -796,6 +801,7 @@
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -855,6 +861,7 @@
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -867,18 +874,17 @@
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -887,7 +893,6 @@
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -951,6 +956,8 @@
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -1010,6 +1017,10 @@
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1051,6 +1062,7 @@
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig
index 7cd3757..db6e882 100644
--- a/arch/m68k/configs/mac_defconfig
+++ b/arch/m68k/configs/mac_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:06 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -163,10 +169,6 @@
 CONFIG_PROC_HARDWARE=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -180,6 +182,7 @@
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -413,6 +416,7 @@
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -432,7 +436,9 @@
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -450,6 +456,7 @@
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -460,6 +467,7 @@
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
@@ -477,8 +485,6 @@
 # CONFIG_BLK_DEV_PLATFORM is not set
 CONFIG_BLK_DEV_MAC_IDE=y
 # CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
@@ -527,6 +533,7 @@
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_MAC_SCSI=y
 CONFIG_SCSI_MAC_ESP=y
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -535,7 +542,7 @@
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -544,9 +551,6 @@
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_MACINTOSH_DRIVERS=y
@@ -559,7 +563,6 @@
 CONFIG_INPUT_ADBHID=y
 CONFIG_MAC_EMUMOUSEBTN=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -670,6 +673,7 @@
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -700,6 +704,7 @@
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -711,8 +716,10 @@
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -784,10 +791,6 @@
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
 CONFIG_LOGO_MAC_CLUT224=y
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
@@ -799,6 +802,7 @@
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 
 #
@@ -836,6 +840,7 @@
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -895,6 +900,7 @@
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -917,7 +923,6 @@
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
 CONFIG_SUNRPC_GSS=m
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=m
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -926,7 +931,6 @@
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -991,6 +995,8 @@
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -1050,6 +1056,10 @@
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1091,6 +1101,7 @@
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig
index 0747fa3..1a80610 100644
--- a/arch/m68k/configs/multi_defconfig
+++ b/arch/m68k/configs/multi_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:07 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -173,10 +179,6 @@
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_ZORRO_NAMES=y
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -190,6 +192,7 @@
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -427,6 +430,7 @@
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -446,7 +450,9 @@
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -476,6 +482,7 @@
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -486,6 +493,7 @@
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
@@ -508,8 +516,6 @@
 CONFIG_BLK_DEV_MAC_IDE=y
 CONFIG_BLK_DEV_Q40IDE=y
 # CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
@@ -584,6 +590,7 @@
 CONFIG_MVME16x_SCSI=y
 CONFIG_BVME6000_SCSI=y
 CONFIG_SUN3X_ESP=y
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -592,7 +599,7 @@
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -601,9 +608,6 @@
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_MACINTOSH_DRIVERS=y
@@ -616,7 +620,6 @@
 CONFIG_INPUT_ADBHID=y
 CONFIG_MAC_EMUMOUSEBTN=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -632,7 +635,6 @@
 CONFIG_HYDRA=m
 CONFIG_ZORRO8390=m
 CONFIG_APNE=m
-CONFIG_APOLLO_ELPLUS=y
 CONFIG_MAC8390=y
 CONFIG_MAC89x0=m
 CONFIG_MACSONIC=m
@@ -791,6 +793,7 @@
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -827,6 +830,7 @@
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -838,8 +842,10 @@
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -923,10 +929,6 @@
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
 CONFIG_LOGO_MAC_CLUT224=y
-
-#
-# Sound
-#
 CONFIG_SOUND=m
 CONFIG_DMASOUND_ATARI=m
 CONFIG_DMASOUND_PAULA=m
@@ -942,6 +944,7 @@
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
@@ -949,8 +952,6 @@
 # Character devices
 #
 CONFIG_ATARI_MFPSER=m
-CONFIG_ATARI_SCC=y
-CONFIG_ATARI_SCC_DMA=y
 CONFIG_ATARI_MIDI=m
 CONFIG_ATARI_DSP56K=m
 CONFIG_AMIGA_BUILTIN_SERIAL=y
@@ -972,8 +973,10 @@
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
-# CONFIG_EXT4DEV_FS is not set
+CONFIG_EXT4DEV_FS=y
+# CONFIG_EXT4DEV_FS_XATTR is not set
 CONFIG_JBD=y
+CONFIG_JBD2=y
 CONFIG_REISERFS_FS=m
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_REISERFS_PROC_INFO is not set
@@ -992,6 +995,7 @@
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -1051,6 +1055,7 @@
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1063,18 +1068,17 @@
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1083,7 +1087,6 @@
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -1152,6 +1155,8 @@
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -1211,6 +1216,10 @@
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1252,6 +1261,7 @@
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig
index e7a8246..cacb5ae 100644
--- a/arch/m68k/configs/mvme147_defconfig
+++ b/arch/m68k/configs/mvme147_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:08 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -163,10 +169,6 @@
 CONFIG_PROC_HARDWARE=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -180,6 +182,7 @@
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -413,6 +416,7 @@
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -432,7 +436,9 @@
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -450,6 +456,7 @@
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -502,6 +509,7 @@
 CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_MVME147_SCSI=y
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -510,7 +518,7 @@
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -519,13 +527,9 @@
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -630,6 +634,7 @@
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -660,6 +665,7 @@
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -671,8 +677,10 @@
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -707,10 +715,6 @@
 # Console display driver support
 #
 CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
@@ -722,6 +726,7 @@
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 
 #
@@ -758,6 +763,7 @@
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -817,6 +823,7 @@
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -829,18 +836,17 @@
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -849,7 +855,6 @@
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -914,6 +919,8 @@
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -973,6 +980,10 @@
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1014,6 +1025,7 @@
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig
index ab536eb..a183e25 100644
--- a/arch/m68k/configs/mvme16x_defconfig
+++ b/arch/m68k/configs/mvme16x_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:09 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -163,10 +169,6 @@
 CONFIG_PROC_HARDWARE=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -180,6 +182,7 @@
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -413,6 +416,7 @@
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -432,7 +436,9 @@
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -450,6 +456,7 @@
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -503,6 +510,7 @@
 CONFIG_53C700_BE_BUS=y
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_MVME16x_SCSI=y
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -511,7 +519,7 @@
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -520,13 +528,9 @@
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -631,6 +635,7 @@
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -661,6 +666,7 @@
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -672,8 +678,10 @@
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -708,10 +716,6 @@
 # Console display driver support
 #
 CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
@@ -723,6 +727,7 @@
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 
 #
@@ -760,6 +765,7 @@
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -819,6 +825,7 @@
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -831,18 +838,17 @@
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -851,7 +857,6 @@
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -916,6 +921,8 @@
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -975,6 +982,10 @@
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1016,6 +1027,7 @@
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig
index e05be68..72eaff0 100644
--- a/arch/m68k/configs/q40_defconfig
+++ b/arch/m68k/configs/q40_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:10 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -163,10 +169,6 @@
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -180,6 +182,7 @@
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -410,6 +413,7 @@
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -429,7 +433,9 @@
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -448,6 +454,7 @@
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -458,6 +465,7 @@
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
@@ -475,8 +483,6 @@
 # CONFIG_BLK_DEV_PLATFORM is not set
 CONFIG_BLK_DEV_Q40IDE=y
 # CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
@@ -536,6 +542,7 @@
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -544,7 +551,7 @@
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -553,13 +560,9 @@
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -680,6 +683,7 @@
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -711,6 +715,7 @@
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -722,8 +727,10 @@
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -792,10 +799,6 @@
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
 CONFIG_SOUND=m
 CONFIG_DMASOUND_Q40=m
 CONFIG_DMASOUND=m
@@ -809,6 +812,7 @@
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 
 #
@@ -843,6 +847,7 @@
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -902,6 +907,7 @@
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -924,7 +930,6 @@
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -933,7 +938,6 @@
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -997,6 +1001,8 @@
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -1056,6 +1062,10 @@
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1097,6 +1107,7 @@
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig
index 296340d..cb62b96 100644
--- a/arch/m68k/configs/sun3_defconfig
+++ b/arch/m68k/configs/sun3_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:11 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -149,10 +155,6 @@
 CONFIG_PROC_HARDWARE=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -166,6 +168,7 @@
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -399,6 +402,7 @@
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -418,7 +422,9 @@
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -436,6 +442,7 @@
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -488,6 +495,7 @@
 CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_SUN3_SCSI=y
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -496,7 +504,7 @@
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -505,13 +513,9 @@
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -527,7 +531,6 @@
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-# CONFIG_B44 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 
@@ -617,6 +620,7 @@
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -647,19 +651,20 @@
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
-# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -727,10 +732,6 @@
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
@@ -776,6 +777,7 @@
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -835,6 +837,7 @@
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -847,18 +850,17 @@
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -867,7 +869,6 @@
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -932,6 +933,8 @@
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -991,6 +994,10 @@
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1032,6 +1039,7 @@
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig
index 8d3a416..04b4363 100644
--- a/arch/m68k/configs/sun3x_defconfig
+++ b/arch/m68k/configs/sun3x_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:12 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -160,10 +166,6 @@
 CONFIG_PROC_HARDWARE=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -177,6 +179,7 @@
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -410,6 +413,7 @@
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -429,7 +433,9 @@
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -447,6 +453,7 @@
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -499,6 +506,7 @@
 CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_SUN3X_ESP=y
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -507,7 +515,7 @@
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -516,13 +524,9 @@
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -627,6 +631,7 @@
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -657,6 +662,7 @@
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -668,8 +674,10 @@
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -737,10 +745,6 @@
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
@@ -752,6 +756,7 @@
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 
 #
@@ -786,6 +791,7 @@
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -845,6 +851,7 @@
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -857,18 +864,17 @@
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -877,7 +883,6 @@
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -942,6 +947,8 @@
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -1001,6 +1008,10 @@
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1042,6 +1053,7 @@
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 4da736e..49896a2 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1886,6 +1886,15 @@
 
 source "init/Kconfig"
 
+config PROBE_INITRD_HEADER
+	bool "Probe initrd header created by addinitrd"
+	depends on BLK_DEV_INITRD
+	help
+	  Probe initrd header at the last page of kernel image.
+	  Say Y here if you are using arch/mips/boot/addinitrd.c to
+	  add initrd or initramfs image to the kernel image.
+	  Otherwise, say N.
+
 menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)"
 
 config HW_HAS_EISA
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 2aae76b..16f8edf 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -160,30 +160,33 @@
 static unsigned long __init init_initrd(void)
 {
 	unsigned long end;
-	u32 *initrd_header;
 
 	/*
 	 * Board specific code or command line parser should have
 	 * already set up initrd_start and initrd_end. In these cases
 	 * perfom sanity checks and use them if all looks good.
 	 */
-	if (initrd_start && initrd_end > initrd_start)
-		goto sanitize;
+	if (!initrd_start || initrd_end <= initrd_start) {
+#ifdef CONFIG_PROBE_INITRD_HEADER
+		u32 *initrd_header;
 
-	/*
-	 * See if initrd has been added to the kernel image by
-	 * arch/mips/boot/addinitrd.c. In that case a header is
-	 * prepended to initrd and is made up by 8 bytes. The fisrt
-	 * word is a magic number and the second one is the size of
-	 * initrd.  Initrd start must be page aligned in any cases.
-	 */
-	initrd_header = __va(PAGE_ALIGN(__pa_symbol(&_end) + 8)) - 8;
-	if (initrd_header[0] != 0x494E5244)
+		/*
+		 * See if initrd has been added to the kernel image by
+		 * arch/mips/boot/addinitrd.c. In that case a header is
+		 * prepended to initrd and is made up by 8 bytes. The first
+		 * word is a magic number and the second one is the size of
+		 * initrd.  Initrd start must be page aligned in any cases.
+		 */
+		initrd_header = __va(PAGE_ALIGN(__pa_symbol(&_end) + 8)) - 8;
+		if (initrd_header[0] != 0x494E5244)
+			goto disable;
+		initrd_start = (unsigned long)(initrd_header + 2);
+		initrd_end = initrd_start + initrd_header[1];
+#else
 		goto disable;
-	initrd_start = (unsigned long)(initrd_header + 2);
-	initrd_end = initrd_start + initrd_header[1];
+#endif
+	}
 
-sanitize:
 	if (initrd_start & ~PAGE_MASK) {
 		pr_err("initrd start must be page aligned\n");
 		goto disable;
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 426cced..6bee290 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -373,8 +373,8 @@
 	do_exit(SIGSEGV);
 }
 
-extern const struct exception_table_entry __start___dbe_table[];
-extern const struct exception_table_entry __stop___dbe_table[];
+extern struct exception_table_entry __start___dbe_table[];
+extern struct exception_table_entry __stop___dbe_table[];
 
 __asm__(
 "	.section	__dbe_table, \"a\"\n"
@@ -1200,7 +1200,7 @@
 	if (n == 0 && cpu_has_divec) {
 		*(u32 *)(ebase + 0x200) = 0x08000000 |
 					  (0x03ffffff & (handler >> 2));
-		flush_icache_range(ebase + 0x200, ebase + 0x204);
+		local_flush_icache_range(ebase + 0x200, ebase + 0x204);
 	}
 	return (void *)old_handler;
 }
@@ -1283,7 +1283,8 @@
 		*w = (*w & 0xffff0000) | (((u32)handler >> 16) & 0xffff);
 		w = (u32 *)(b + ori_offset);
 		*w = (*w & 0xffff0000) | ((u32)handler & 0xffff);
-		flush_icache_range((unsigned long)b, (unsigned long)(b+handler_len));
+		local_flush_icache_range((unsigned long)b,
+					 (unsigned long)(b+handler_len));
 	}
 	else {
 		/*
@@ -1295,7 +1296,8 @@
 		w = (u32 *)b;
 		*w++ = 0x08000000 | (((u32)handler >> 2) & 0x03fffff); /* j handler */
 		*w = 0;
-		flush_icache_range((unsigned long)b, (unsigned long)(b+8));
+		local_flush_icache_range((unsigned long)b,
+					 (unsigned long)(b+8));
 	}
 
 	return (void *)old_handler;
@@ -1515,7 +1517,7 @@
 void __init set_handler(unsigned long offset, void *addr, unsigned long size)
 {
 	memcpy((void *)(ebase + offset), addr, size);
-	flush_icache_range(ebase + offset, ebase + offset + size);
+	local_flush_icache_range(ebase + offset, ebase + offset + size);
 }
 
 static char panic_null_cerr[] __cpuinitdata =
@@ -1680,6 +1682,8 @@
 	signal32_init();
 #endif
 
-	flush_icache_range(ebase, ebase + 0x400);
+	local_flush_icache_range(ebase, ebase + 0x400);
 	flush_tlb_handlers();
+
+	sort_extable(__start___dbe_table, __stop___dbe_table);
 }
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c
index 27a5b46..5500c20 100644
--- a/arch/mips/mm/c-r3k.c
+++ b/arch/mips/mm/c-r3k.c
@@ -320,6 +320,7 @@
 	flush_cache_range = r3k_flush_cache_range;
 	flush_cache_page = r3k_flush_cache_page;
 	flush_icache_range = r3k_flush_icache_range;
+	local_flush_icache_range = r3k_flush_icache_range;
 
 	flush_cache_sigtramp = r3k_flush_cache_sigtramp;
 	local_flush_data_cache_page = local_r3k_flush_data_cache_page;
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 71df339..6e99665 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -543,12 +543,8 @@
 	unsigned long end;
 };
 
-static inline void local_r4k_flush_icache_range(void *args)
+static inline void local_r4k_flush_icache_range(unsigned long start, unsigned long end)
 {
-	struct flush_icache_range_args *fir_args = args;
-	unsigned long start = fir_args->start;
-	unsigned long end = fir_args->end;
-
 	if (!cpu_has_ic_fills_f_dc) {
 		if (end - start >= dcache_size) {
 			r4k_blast_dcache();
@@ -564,6 +560,15 @@
 		protected_blast_icache_range(start, end);
 }
 
+static inline void local_r4k_flush_icache_range_ipi(void *args)
+{
+	struct flush_icache_range_args *fir_args = args;
+	unsigned long start = fir_args->start;
+	unsigned long end = fir_args->end;
+
+	local_r4k_flush_icache_range(start, end);
+}
+
 static void r4k_flush_icache_range(unsigned long start, unsigned long end)
 {
 	struct flush_icache_range_args args;
@@ -571,7 +576,7 @@
 	args.start = start;
 	args.end = end;
 
-	r4k_on_each_cpu(local_r4k_flush_icache_range, &args, 1);
+	r4k_on_each_cpu(local_r4k_flush_icache_range_ipi, &args, 1);
 	instruction_hazard();
 }
 
@@ -1375,6 +1380,7 @@
 	local_flush_data_cache_page	= local_r4k_flush_data_cache_page;
 	flush_data_cache_page	= r4k_flush_data_cache_page;
 	flush_icache_range	= r4k_flush_icache_range;
+	local_flush_icache_range	= local_r4k_flush_icache_range;
 
 #if defined(CONFIG_DMA_NONCOHERENT)
 	if (coherentio) {
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c
index a9f7f1f..f7c8f9c 100644
--- a/arch/mips/mm/c-tx39.c
+++ b/arch/mips/mm/c-tx39.c
@@ -362,6 +362,7 @@
 		flush_cache_range	= (void *) tx39h_flush_icache_all;
 		flush_cache_page	= (void *) tx39h_flush_icache_all;
 		flush_icache_range	= (void *) tx39h_flush_icache_all;
+		local_flush_icache_range = (void *) tx39h_flush_icache_all;
 
 		flush_cache_sigtramp	= (void *) tx39h_flush_icache_all;
 		local_flush_data_cache_page	= (void *) tx39h_flush_icache_all;
@@ -390,6 +391,7 @@
 		flush_cache_range = tx39_flush_cache_range;
 		flush_cache_page = tx39_flush_cache_page;
 		flush_icache_range = tx39_flush_icache_range;
+		local_flush_icache_range = tx39_flush_icache_range;
 
 		flush_cache_sigtramp = tx39_flush_cache_sigtramp;
 		local_flush_data_cache_page = local_tx39_flush_data_cache_page;
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 034e850..1eb7c71 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -29,6 +29,7 @@
 void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
 	unsigned long pfn);
 void (*flush_icache_range)(unsigned long start, unsigned long end);
+void (*local_flush_icache_range)(unsigned long start, unsigned long end);
 
 void (*__flush_cache_vmap)(void);
 void (*__flush_cache_vunmap)(void);
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 76da73a..979cf91 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -1273,10 +1273,10 @@
 
 void __cpuinit flush_tlb_handlers(void)
 {
-	flush_icache_range((unsigned long)handle_tlbl,
+	local_flush_icache_range((unsigned long)handle_tlbl,
 			   (unsigned long)handle_tlbl + sizeof(handle_tlbl));
-	flush_icache_range((unsigned long)handle_tlbs,
+	local_flush_icache_range((unsigned long)handle_tlbs,
 			   (unsigned long)handle_tlbs + sizeof(handle_tlbs));
-	flush_icache_range((unsigned long)handle_tlbm,
+	local_flush_icache_range((unsigned long)handle_tlbm,
 			   (unsigned long)handle_tlbm + sizeof(handle_tlbm));
 }
diff --git a/arch/mips/sgi-ip22/ip22-platform.c b/arch/mips/sgi-ip22/ip22-platform.c
index 6014123..52486c4d 100644
--- a/arch/mips/sgi-ip22/ip22-platform.c
+++ b/arch/mips/sgi-ip22/ip22-platform.c
@@ -150,7 +150,7 @@
 		return res;
 
 	/* Second HPC is missing? */
-	if (!ip22_is_fullhouse() ||
+	if (ip22_is_fullhouse() ||
 	    get_dbe(tmp, (unsigned int *)&hpc3c1->pbdma[1]))
 		return 0;
 
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c
index 0afe94c..fe6bee0 100644
--- a/arch/mips/txx9/generic/setup.c
+++ b/arch/mips/txx9/generic/setup.c
@@ -53,6 +53,7 @@
 		txx9_ce_res[i].name = txx9_ce_res_name[i];
 	}
 
+	txx9_pcode = pcode;
 	sprintf(txx9_pcode_str, "TX%x", pcode);
 	if (base) {
 		txx9_reg_res.start = base & 0xfffffffffULL;
diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c
index cba36a2..92dd1a0 100644
--- a/arch/mips/vr41xx/common/irq.c
+++ b/arch/mips/vr41xx/common/irq.c
@@ -72,6 +72,7 @@
 	cascade = irq_cascade + irq;
 	if (cascade->get_irq != NULL) {
 		unsigned int source_irq = irq;
+		int ret;
 		desc = irq_desc + source_irq;
 		if (desc->chip->mask_ack)
 			desc->chip->mask_ack(source_irq);
@@ -79,8 +80,9 @@
 			desc->chip->mask(source_irq);
 			desc->chip->ack(source_irq);
 		}
-		irq = cascade->get_irq(irq);
-		if (irq < 0)
+		ret = cascade->get_irq(irq);
+		irq = ret;
+		if (ret < 0)
 			atomic_inc(&irq_err_count);
 		else
 			irq_dispatch(irq);
diff --git a/arch/mn10300/mm/fault.c b/arch/mn10300/mm/fault.c
index 78f092c..33cf250 100644
--- a/arch/mn10300/mm/fault.c
+++ b/arch/mn10300/mm/fault.c
@@ -174,7 +174,7 @@
 	 * If we're in an interrupt or have no user
 	 * context, we must not take the fault..
 	 */
-	if (in_interrupt() || !mm)
+	if (in_atomic() || !mm)
 		goto no_context;
 
 	down_read(&mm->mmap_sem);
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
index fdacdd4..44138c3 100644
--- a/arch/parisc/kernel/module.c
+++ b/arch/parisc/kernel/module.c
@@ -47,7 +47,9 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/bug.h>
+#include <linux/uaccess.h>
 
+#include <asm/sections.h>
 #include <asm/unwind.h>
 
 #if 0
@@ -860,3 +862,15 @@
 	deregister_unwind_table(mod);
 	module_bug_cleanup(mod);
 }
+
+#ifdef CONFIG_64BIT
+void *dereference_function_descriptor(void *ptr)
+{
+	Elf64_Fdesc *desc = ptr;
+	void *p;
+
+	if (!probe_kernel_address(&desc->addr, p))
+		ptr = p;
+	return ptr;
+}
+#endif
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 9155c93..c6be19e 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -116,6 +116,11 @@
 KBUILD_CFLAGS		+= -mcpu=powerpc
 endif
 
+# Work around a gcc code-gen bug with -fno-omit-frame-pointer.
+ifeq ($(CONFIG_FTRACE),y)
+KBUILD_CFLAGS		+= -mno-sched-epilog
+endif
+
 cpu-as-$(CONFIG_4xx)		+= -Wa,-m405
 cpu-as-$(CONFIG_6xx)		+= -Wa,-maltivec
 cpu-as-$(CONFIG_POWER4)		+= -Wa,-maltivec
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 14174aa..717a3bc 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -49,7 +49,7 @@
 zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h
 zliblinuxheader := zlib.h zconf.h zutil.h
 
-$(addprefix $(obj)/,$(zlib) gunzip_util.o main.o): \
+$(addprefix $(obj)/,$(zlib) cuboot-c2k.o gunzip_util.o main.o prpmc2800.o): \
 	$(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
 
 src-libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h
index db0b8f3..4597c49 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64.h
@@ -153,12 +153,10 @@
 #define __S110	PAGE_SHARED_X
 #define __S111	PAGE_SHARED_X
 
-#ifdef CONFIG_HUGETLB_PAGE
-
+#ifdef CONFIG_PPC_MM_SLICES
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
-
-#endif
+#endif /* CONFIG_PPC_MM_SLICES */
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
index 916018e..7710e9e 100644
--- a/arch/powerpc/include/asm/sections.h
+++ b/arch/powerpc/include/asm/sections.h
@@ -16,6 +16,9 @@
 	return 0;
 }
 
+#undef dereference_function_descriptor
+void *dereference_function_descriptor(void *);
+
 #endif
 
 #endif /* __KERNEL__ */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 64f5948..946daea 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -14,12 +14,13 @@
 
 ifdef CONFIG_FTRACE
 # Do not trace early boot code
-CFLAGS_REMOVE_cputable.o = -pg
-CFLAGS_REMOVE_prom_init.o = -pg
+CFLAGS_REMOVE_cputable.o = -pg -mno-sched-epilog
+CFLAGS_REMOVE_prom_init.o = -pg -mno-sched-epilog
+CFLAGS_REMOVE_btext.o = -pg -mno-sched-epilog
 
 ifdef CONFIG_DYNAMIC_FTRACE
 # dynamic ftrace setup.
-CFLAGS_REMOVE_ftrace.o = -pg
+CFLAGS_REMOVE_ftrace.o = -pg -mno-sched-epilog
 endif
 
 endif
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index 3671297..5af4e9b 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -647,7 +647,7 @@
 		       unsigned int flags, unsigned int length)
 {
 	char *ptr = (char *) &current->thread.TS_FPR(reg);
-	int ret;
+	int ret = 0;
 
 	flush_vsx_to_thread(current);
 
diff --git a/arch/powerpc/kernel/idle_6xx.S b/arch/powerpc/kernel/idle_6xx.S
index 019b02d..15c611d 100644
--- a/arch/powerpc/kernel/idle_6xx.S
+++ b/arch/powerpc/kernel/idle_6xx.S
@@ -158,7 +158,7 @@
 	stw	r9,_NIP(r11)		/* make it do a blr */
 
 #ifdef CONFIG_SMP
-	mfspr	r12,SPRN_SPRG3
+	rlwinm	r12,r11,0,0,31-THREAD_SHIFT
 	lwz	r11,TI_CPU(r12)		/* get cpu number * 4 */
 	slwi	r11,r11,2
 #else
diff --git a/arch/powerpc/kernel/idle_e500.S b/arch/powerpc/kernel/idle_e500.S
index 0630403..47a1a98 100644
--- a/arch/powerpc/kernel/idle_e500.S
+++ b/arch/powerpc/kernel/idle_e500.S
@@ -84,10 +84,11 @@
 	stw	r9,_NIP(r11)		/* make it do a blr */
 
 #ifdef CONFIG_SMP
-	mfspr	r12,SPRN_SPRG3
+	rlwinm	r12,r1,0,0,31-THREAD_SHIFT
 	lwz	r11,TI_CPU(r12)		/* get cpu number * 4 */
 	slwi	r11,r11,2
 #else
 	li	r11,0
 #endif
+
 	b	transfer_to_handler_cont
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index ee6a298..ad79de2 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -21,8 +21,9 @@
 #include <linux/err.h>
 #include <linux/vmalloc.h>
 #include <linux/bug.h>
+#include <linux/uaccess.h>
 #include <asm/module.h>
-#include <asm/uaccess.h>
+#include <asm/sections.h>
 #include <asm/firmware.h>
 #include <asm/code-patching.h>
 #include <linux/sort.h>
@@ -451,3 +452,13 @@
 
 	return 0;
 }
+
+void *dereference_function_descriptor(void *ptr)
+{
+	struct ppc64_opd_entry *desc = ptr;
+	void *p;
+
+	if (!probe_kernel_address(&desc->funcaddr, p))
+		ptr = p;
+	return ptr;
+}
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 4a8ce62..9f6c1ca 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -66,11 +66,12 @@
 		__got2_end = .;
 #endif /* CONFIG_PPC32 */
 
-		. = ALIGN(PAGE_SIZE);
-		_etext = .;
-		PROVIDE32 (etext = .);
 	} :kernel
 
+	. = ALIGN(PAGE_SIZE);
+	_etext = .;
+	PROVIDE32 (etext = .);
+
 	/* Read-only data */
 	RODATA
 
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 14be408..8920eea 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -191,12 +191,17 @@
 		unsigned long hash, hpteg;
 		unsigned long vsid = get_kernel_vsid(vaddr, ssize);
 		unsigned long va = hpt_va(vaddr, vsid, ssize);
+		unsigned long tprot = prot;
+
+		/* Make kernel text executable */
+		if (in_kernel_text(vaddr))
+			tprot &= ~HPTE_R_N;
 
 		hash = hpt_hash(va, shift, ssize);
 		hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
 
 		BUG_ON(!ppc_md.hpte_insert);
-		ret = ppc_md.hpte_insert(hpteg, va, paddr, prot,
+		ret = ppc_md.hpte_insert(hpteg, va, paddr, tprot,
 					 HPTE_V_BOLTED, psize, ssize);
 
 		if (ret < 0)
@@ -584,7 +589,7 @@
 {
 	unsigned long table;
 	unsigned long pteg_count;
-	unsigned long prot, tprot;
+	unsigned long prot;
 	unsigned long base = 0, size = 0, limit;
 	int i;
 
@@ -660,10 +665,9 @@
 	for (i=0; i < lmb.memory.cnt; i++) {
 		base = (unsigned long)__va(lmb.memory.region[i].base);
 		size = lmb.memory.region[i].size;
-		tprot = prot | (in_kernel_text(base) ? _PAGE_EXEC : 0);
 
 		DBG("creating mapping for region: %lx..%lx (prot: %x)\n",
-		    base, size, tprot);
+		    base, size, prot);
 
 #ifdef CONFIG_U3_DART
 		/* Do not map the DART space. Fortunately, it will be aligned
@@ -680,21 +684,21 @@
 			unsigned long dart_table_end = dart_tablebase + 16 * MB;
 			if (base != dart_tablebase)
 				BUG_ON(htab_bolt_mapping(base, dart_tablebase,
-							__pa(base), tprot,
+							__pa(base), prot,
 							mmu_linear_psize,
 							mmu_kernel_ssize));
 			if ((base + size) > dart_table_end)
 				BUG_ON(htab_bolt_mapping(dart_tablebase+16*MB,
 							base + size,
 							__pa(dart_table_end),
-							 tprot,
+							 prot,
 							 mmu_linear_psize,
 							 mmu_kernel_ssize));
 			continue;
 		}
 #endif /* CONFIG_U3_DART */
 		BUG_ON(htab_bolt_mapping(base, base + size, __pa(base),
-				tprot, mmu_linear_psize, mmu_kernel_ssize));
+				prot, mmu_linear_psize, mmu_kernel_ssize));
        }
 
 	/*
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 1c1b627..67595bc 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -643,9 +643,10 @@
 			    !(tmp->flags & SPU_CREATE_NOSCHED) &&
 			    (!victim || tmp->prio > victim->prio)) {
 				victim = spu->ctx;
-				get_spu_context(victim);
 			}
 		}
+		if (victim)
+			get_spu_context(victim);
 		mutex_unlock(&cbe_spu_info[node].list_mutex);
 
 		if (victim) {
@@ -727,17 +728,33 @@
 	/* not a candidate for interruptible because it's called either
 	   from the scheduler thread or from spu_deactivate */
 	mutex_lock(&ctx->state_mutex);
-	__spu_schedule(spu, ctx);
+	if (ctx->state == SPU_STATE_SAVED)
+		__spu_schedule(spu, ctx);
 	spu_release(ctx);
 }
 
-static void spu_unschedule(struct spu *spu, struct spu_context *ctx)
+/**
+ * spu_unschedule - remove a context from a spu, and possibly release it.
+ * @spu:	The SPU to unschedule from
+ * @ctx:	The context currently scheduled on the SPU
+ * @free_spu	Whether to free the SPU for other contexts
+ *
+ * Unbinds the context @ctx from the SPU @spu. If @free_spu is non-zero, the
+ * SPU is made available for other contexts (ie, may be returned by
+ * spu_get_idle). If this is zero, the caller is expected to schedule another
+ * context to this spu.
+ *
+ * Should be called with ctx->state_mutex held.
+ */
+static void spu_unschedule(struct spu *spu, struct spu_context *ctx,
+		int free_spu)
 {
 	int node = spu->node;
 
 	mutex_lock(&cbe_spu_info[node].list_mutex);
 	cbe_spu_info[node].nr_active--;
-	spu->alloc_state = SPU_FREE;
+	if (free_spu)
+		spu->alloc_state = SPU_FREE;
 	spu_unbind_context(spu, ctx);
 	ctx->stats.invol_ctx_switch++;
 	spu->stats.invol_ctx_switch++;
@@ -837,7 +854,7 @@
 	if (spu) {
 		new = grab_runnable_context(max_prio, spu->node);
 		if (new || force) {
-			spu_unschedule(spu, ctx);
+			spu_unschedule(spu, ctx, new == NULL);
 			if (new) {
 				if (new->flags & SPU_CREATE_NOSCHED)
 					wake_up(&new->stop_wq);
@@ -910,7 +927,7 @@
 
 	new = grab_runnable_context(ctx->prio + 1, spu->node);
 	if (new) {
-		spu_unschedule(spu, ctx);
+		spu_unschedule(spu, ctx, 0);
 		if (test_bit(SPU_SCHED_SPU_RUN, &ctx->sched_flags))
 			spu_add_to_rq(ctx);
 	} else {
diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile
index 58ecdd7..be60d64 100644
--- a/arch/powerpc/platforms/powermac/Makefile
+++ b/arch/powerpc/platforms/powermac/Makefile
@@ -2,7 +2,7 @@
 
 ifdef CONFIG_FTRACE
 # Do not trace early boot code
-CFLAGS_REMOVE_bootx_init.o = -pg
+CFLAGS_REMOVE_bootx_init.o = -pg -mno-sched-epilog
 endif
 
 obj-y				+= pic.o setup.o time.o feature.o pci.o \
diff --git a/arch/s390/kernel/compat_ptrace.h b/arch/s390/kernel/compat_ptrace.h
index cde81fa..a2be3a9 100644
--- a/arch/s390/kernel/compat_ptrace.h
+++ b/arch/s390/kernel/compat_ptrace.h
@@ -42,6 +42,7 @@
 	u32 gprs[NUM_GPRS];
 	u32 acrs[NUM_ACRS];
 	u32 orig_gpr2;
+	/* nb: there's a 4-byte hole here */
 	s390_fp_regs fp_regs;
 	/*
 	 * These per registers are in here so that gdb can modify them
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 2815bfe..c8b0828 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -170,6 +170,13 @@
 		 */
 		tmp = (addr_t) task_pt_regs(child)->orig_gpr2;
 
+	} else if (addr < (addr_t) &dummy->regs.fp_regs) {
+		/*
+		 * prevent reads of padding hole between
+		 * orig_gpr2 and fp_regs on s390.
+		 */
+		tmp = 0;
+
 	} else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
 		/* 
 		 * floating point regs. are stored in the thread structure
@@ -270,6 +277,13 @@
 		 */
 		task_pt_regs(child)->orig_gpr2 = data;
 
+	} else if (addr < (addr_t) &dummy->regs.fp_regs) {
+		/*
+		 * prevent writes of padding hole between
+		 * orig_gpr2 and fp_regs on s390.
+		 */
+		return 0;
+
 	} else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
 		/*
 		 * floating point regs. are stored in the thread structure
@@ -428,6 +442,13 @@
 		 */
 		tmp = *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4);
 
+	} else if (addr < (addr_t) &dummy32->regs.fp_regs) {
+		/*
+		 * prevent reads of padding hole between
+		 * orig_gpr2 and fp_regs on s390.
+		 */
+		tmp = 0;
+
 	} else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
 		/*
 		 * floating point regs. are stored in the thread structure 
@@ -514,6 +535,13 @@
 		 */
 		*(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4) = tmp;
 
+	} else if (addr < (addr_t) &dummy32->regs.fp_regs) {
+		/*
+		 * prevent writess of padding hole between
+		 * orig_gpr2 and fp_regs on s390.
+		 */
+		return 0;
+
 	} else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
 		/*
 		 * floating point regs. are stored in the thread structure 
diff --git a/arch/sh/configs/ap325rxa_defconfig b/arch/sh/configs/ap325rxa_defconfig
index 29926a9..851c870 100644
--- a/arch/sh/configs/ap325rxa_defconfig
+++ b/arch/sh/configs/ap325rxa_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26
-# Wed Jul 30 01:18:59 2008
+# Linux kernel version: 2.6.27-rc4
+# Tue Aug 26 14:21:17 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -11,6 +11,7 @@
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_TIME=y
@@ -20,7 +21,6 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -58,7 +58,6 @@
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_KALLSYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
@@ -89,6 +88,7 @@
 # CONFIG_USE_GENERIC_SMP_HELPERS is not set
 CONFIG_HAVE_CLK=y
 CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -261,9 +261,10 @@
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
-# CONFIG_SCHED_HRTICK is not set
+CONFIG_SCHED_HRTICK=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SECCOMP=y
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
@@ -289,10 +290,6 @@
 #
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -647,6 +644,7 @@
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -690,7 +688,10 @@
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
-# CONFIG_UIO is not set
+CONFIG_UIO=y
+# CONFIG_UIO_PDRV is not set
+CONFIG_UIO_PDRV_GENIRQ=y
+# CONFIG_UIO_SMX is not set
 
 #
 # File systems
@@ -854,6 +855,7 @@
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
diff --git a/arch/sh/configs/migor_defconfig b/arch/sh/configs/migor_defconfig
index c4b3e1d..4f8b197 100644
--- a/arch/sh/configs/migor_defconfig
+++ b/arch/sh/configs/migor_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26
-# Wed Jul 30 01:44:41 2008
+# Linux kernel version: 2.6.27-rc4
+# Tue Aug 26 14:18:17 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -11,6 +11,7 @@
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_TIME=y
@@ -21,7 +22,6 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -87,6 +87,7 @@
 # CONFIG_USE_GENERIC_SMP_HELPERS is not set
 CONFIG_HAVE_CLK=y
 CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -270,6 +271,7 @@
 # CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SECCOMP=y
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
@@ -294,10 +296,6 @@
 #
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -649,6 +647,7 @@
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
 # CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
 
 #
 # I2C Hardware Bus support
@@ -709,6 +708,7 @@
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -755,6 +755,8 @@
 # CONFIG_USB is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -842,7 +844,10 @@
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
-# CONFIG_UIO is not set
+CONFIG_UIO=y
+# CONFIG_UIO_PDRV is not set
+CONFIG_UIO_PDRV_GENIRQ=y
+# CONFIG_UIO_SMX is not set
 
 #
 # File systems
diff --git a/arch/sh/include/asm/uaccess_64.h b/arch/sh/include/asm/uaccess_64.h
index 81b3d51..5580fd4 100644
--- a/arch/sh/include/asm/uaccess_64.h
+++ b/arch/sh/include/asm/uaccess_64.h
@@ -76,4 +76,6 @@
 extern long __put_user_asm_q(void *, long);
 extern void __put_user_unknown(void);
 
+extern long __strnlen_user(const char *__s, long __n);
+
 #endif /* __ASM_SH_UACCESS_64_H */
diff --git a/arch/sh/kernel/cpu/sh5/entry.S b/arch/sh/kernel/cpu/sh5/entry.S
index 04c7da9..e640c63 100644
--- a/arch/sh/kernel/cpu/sh5/entry.S
+++ b/arch/sh/kernel/cpu/sh5/entry.S
@@ -2,7 +2,7 @@
  * arch/sh/kernel/cpu/sh5/entry.S
  *
  * Copyright (C) 2000, 2001  Paolo Alberelli
- * Copyright (C) 2004 - 2007  Paul Mundt
+ * Copyright (C) 2004 - 2008  Paul Mundt
  * Copyright (C) 2003, 2004  Richard Curnow
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -923,6 +923,8 @@
 	blink   tr0, ZERO
 
 resume_kernel:
+	CLI()
+
 	pta	restore_all, tr0
 
 	getcon	KCR0, r6
@@ -939,19 +941,11 @@
 	andi	r7, 0xf0, r7
 	bne	r7, ZERO, tr0
 
-	movi	((PREEMPT_ACTIVE >> 16) & 65535), r8
-	shori	(PREEMPT_ACTIVE & 65535), r8
-	st.l	r6, TI_PRE_COUNT, r8
-
-	STI()
-	movi	schedule, r7
+	movi	preempt_schedule_irq, r7
 	ori	r7, 1, r7
 	ptabs	r7, tr1
 	blink	tr1, LINK
 
-	st.l	r6, TI_PRE_COUNT, ZERO
-	CLI()
-
 	pta	need_resched, tr1
 	blink	tr1, ZERO
 #endif
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index 0bc17de..efbb426 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -92,6 +92,7 @@
 	bra	resume_userspace
 	 nop
 ENTRY(resume_kernel)
+	cli
 	mov.l	@(TI_PRE_COUNT,r8), r0	! current_thread_info->preempt_count
 	tst	r0, r0
 	bf	noresched
@@ -105,28 +106,9 @@
 	and	#0xf0, r0		! interrupts off (exception path)?
 	cmp/eq	#0xf0, r0
 	bt	noresched
-
-	mov.l	1f, r0
-	mov.l	r0, @(TI_PRE_COUNT,r8)
-
-#ifdef CONFIG_TRACE_IRQFLAGS
 	mov.l	3f, r0
-	jsr	@r0
+	jsr	@r0			! call preempt_schedule_irq
 	 nop
-#endif
-	sti
-	mov.l	2f, r0
-	jsr	@r0
-	 nop
-	mov	#0, r0
-	mov.l	r0, @(TI_PRE_COUNT,r8)
-	cli
-#ifdef CONFIG_TRACE_IRQFLAGS
-	mov.l	4f, r0
-	jsr	@r0
-	 nop
-#endif
-
 	bra	need_resched
 	 nop
 
@@ -137,10 +119,7 @@
 	.align 2
 1:	.long	PREEMPT_ACTIVE
 2:	.long	schedule
-#ifdef CONFIG_TRACE_IRQFLAGS
-3:	.long	trace_hardirqs_on
-4:	.long	trace_hardirqs_off
-#endif
+3:	.long	preempt_schedule_irq
 #endif
 
 ENTRY(resume_userspace)
diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c
index 4703dff..94df56b 100644
--- a/arch/sh/kernel/machine_kexec.c
+++ b/arch/sh/kernel/machine_kexec.c
@@ -102,7 +102,7 @@
 
 	/* now call it */
 	rnk = (relocate_new_kernel_t) reboot_code_buffer;
-	(*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg);
+	(*rnk)(page_list, reboot_code_buffer, P2SEGADDR(image->start), vbr_reg);
 }
 
 void arch_crash_save_vmcoreinfo(void)
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index 5922edd..9c64248 100644
--- a/arch/sh/kernel/ptrace_64.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -131,6 +131,8 @@
 
 void user_disable_single_step(struct task_struct *child)
 {
+	struct pt_regs *regs = child->thread.uregs;
+
 	regs->sr &= ~SR_SSTEP;
 }
 
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index a352076..de83205 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -171,6 +171,7 @@
 				(unsigned long)(free_mem >> 20));
 		crashk_res.start = crash_base;
 		crashk_res.end   = crash_base + crash_size - 1;
+		insert_resource(&iomem_resource, &crashk_res);
 	}
 }
 #else
@@ -204,11 +205,6 @@
 	request_resource(res, &data_resource);
 	request_resource(res, &bss_resource);
 
-#ifdef CONFIG_KEXEC
-	if (crashk_res.start != crashk_res.end)
-		request_resource(res, &crashk_res);
-#endif
-
 	add_active_range(nid, start_pfn, end_pfn);
 }
 
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index 59cd285..9061b86 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -170,7 +170,7 @@
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
-	if (call <= SEMCTL)
+	if (call <= SEMTIMEDOP)
 		switch (call) {
 		case SEMOP:
 			return sys_semtimedop(first,
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index 895bb3f..64b8f7f 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -101,7 +101,7 @@
 }
 __setup("memchunk.", memchunk_setup);
 
-static void memchunk_cmdline_override(char *name, unsigned long *sizep)
+static void __init memchunk_cmdline_override(char *name, unsigned long *sizep)
 {
 	char *p = boot_command_line;
 	int k = strlen(name);
@@ -118,8 +118,8 @@
 	}
 }
 
-int platform_resource_setup_memory(struct platform_device *pdev,
-				   char *name, unsigned long memsize)
+int __init platform_resource_setup_memory(struct platform_device *pdev,
+					  char *name, unsigned long memsize)
 {
 	struct resource *r;
 	dma_addr_t dma_handle;
diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c
index c481d45..f58c537 100644
--- a/arch/sparc/kernel/of_device.c
+++ b/arch/sparc/kernel/of_device.c
@@ -241,7 +241,7 @@
 	return of_bus_default_map(addr, range, na, ns, pna);
 }
 
-static unsigned int of_bus_sbus_get_flags(const u32 *addr)
+static unsigned long of_bus_sbus_get_flags(const u32 *addr, unsigned long flags)
 {
 	return IORESOURCE_MEM;
 }
diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c
index 20699c7..8ce6285 100644
--- a/arch/sparc/kernel/ptrace.c
+++ b/arch/sparc/kernel/ptrace.c
@@ -288,7 +288,7 @@
 	 */
 	[REGSET_GENERAL] = {
 		.core_note_type = NT_PRSTATUS,
-		.n = 38 * sizeof(u32),
+		.n = 38,
 		.size = sizeof(u32), .align = sizeof(u32),
 		.get = genregs32_get, .set = genregs32_set
 	},
@@ -304,7 +304,7 @@
 	 */
 	[REGSET_FP] = {
 		.core_note_type = NT_PRFPREG,
-		.n = 99 * sizeof(u32),
+		.n = 99,
 		.size = sizeof(u32), .align = sizeof(u32),
 		.get = fpregs32_get, .set = fpregs32_set
 	},
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index 9b6689d..2396388 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -792,6 +792,8 @@
 		}
 		spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
 	}
+
+	tick_ops->disable_irq();
 }
 #endif
 
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index ef5fe29..e205ade 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -744,16 +744,16 @@
 	 * the second will just error out since we do not pass in
 	 * IRQF_SHARED.
 	 */
-	err = request_irq(op->irqs[1], psycho_ue_intr, 0,
+	err = request_irq(op->irqs[1], psycho_ue_intr, IRQF_SHARED,
 			  "PSYCHO_UE", pbm);
-	err = request_irq(op->irqs[2], psycho_ce_intr, 0,
+	err = request_irq(op->irqs[2], psycho_ce_intr, IRQF_SHARED,
 			  "PSYCHO_CE", pbm);
 
 	/* This one, however, ought not to fail.  We can just warn
 	 * about it since the system can still operate properly even
 	 * if this fails.
 	 */
-	err = request_irq(op->irqs[0], psycho_pcierr_intr, 0,
+	err = request_irq(op->irqs[0], psycho_pcierr_intr, IRQF_SHARED,
 			  "PSYCHO_PCIERR", pbm);
 	if (err)
 		printk(KERN_WARNING "%s: Could not register PCIERR, "
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index 3c048ac..7151513 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -156,55 +156,11 @@
 		return PSYCHO_IMAP_B_SLOT0 + (slot * 8);
 }
 
-#define PSYCHO_IMAP_SCSI	0x1000UL
-#define PSYCHO_IMAP_ETH		0x1008UL
-#define PSYCHO_IMAP_BPP		0x1010UL
-#define PSYCHO_IMAP_AU_REC	0x1018UL
-#define PSYCHO_IMAP_AU_PLAY	0x1020UL
-#define PSYCHO_IMAP_PFAIL	0x1028UL
-#define PSYCHO_IMAP_KMS		0x1030UL
-#define PSYCHO_IMAP_FLPY	0x1038UL
-#define PSYCHO_IMAP_SHW		0x1040UL
-#define PSYCHO_IMAP_KBD		0x1048UL
-#define PSYCHO_IMAP_MS		0x1050UL
-#define PSYCHO_IMAP_SER		0x1058UL
-#define PSYCHO_IMAP_TIM0	0x1060UL
-#define PSYCHO_IMAP_TIM1	0x1068UL
-#define PSYCHO_IMAP_UE		0x1070UL
-#define PSYCHO_IMAP_CE		0x1078UL
-#define PSYCHO_IMAP_A_ERR	0x1080UL
-#define PSYCHO_IMAP_B_ERR	0x1088UL
-#define PSYCHO_IMAP_PMGMT	0x1090UL
-#define PSYCHO_IMAP_GFX		0x1098UL
-#define PSYCHO_IMAP_EUPA	0x10a0UL
+#define PSYCHO_OBIO_IMAP_BASE	0x1000UL
 
-static unsigned long __psycho_onboard_imap_off[] = {
-/*0x20*/	PSYCHO_IMAP_SCSI,
-/*0x21*/	PSYCHO_IMAP_ETH,
-/*0x22*/	PSYCHO_IMAP_BPP,
-/*0x23*/	PSYCHO_IMAP_AU_REC,
-/*0x24*/	PSYCHO_IMAP_AU_PLAY,
-/*0x25*/	PSYCHO_IMAP_PFAIL,
-/*0x26*/	PSYCHO_IMAP_KMS,
-/*0x27*/	PSYCHO_IMAP_FLPY,
-/*0x28*/	PSYCHO_IMAP_SHW,
-/*0x29*/	PSYCHO_IMAP_KBD,
-/*0x2a*/	PSYCHO_IMAP_MS,
-/*0x2b*/	PSYCHO_IMAP_SER,
-/*0x2c*/	PSYCHO_IMAP_TIM0,
-/*0x2d*/	PSYCHO_IMAP_TIM1,
-/*0x2e*/	PSYCHO_IMAP_UE,
-/*0x2f*/	PSYCHO_IMAP_CE,
-/*0x30*/	PSYCHO_IMAP_A_ERR,
-/*0x31*/	PSYCHO_IMAP_B_ERR,
-/*0x32*/	PSYCHO_IMAP_PMGMT,
-/*0x33*/	PSYCHO_IMAP_GFX,
-/*0x34*/	PSYCHO_IMAP_EUPA,
-};
 #define PSYCHO_ONBOARD_IRQ_BASE		0x20
-#define PSYCHO_ONBOARD_IRQ_LAST		0x34
 #define psycho_onboard_imap_offset(__ino) \
-	__psycho_onboard_imap_off[(__ino) - PSYCHO_ONBOARD_IRQ_BASE]
+	(PSYCHO_OBIO_IMAP_BASE + (((__ino) & 0x1f) << 3))
 
 #define PSYCHO_ICLR_A_SLOT0	0x1400UL
 #define PSYCHO_ICLR_SCSI	0x1800UL
@@ -228,10 +184,6 @@
 		imap_off = psycho_pcislot_imap_offset(ino);
 	} else {
 		/* Onboard device */
-		if (ino > PSYCHO_ONBOARD_IRQ_LAST) {
-			prom_printf("psycho_irq_build: Wacky INO [%x]\n", ino);
-			prom_halt();
-		}
 		imap_off = psycho_onboard_imap_offset(ino);
 	}
 
@@ -318,23 +270,6 @@
 
 #define SABRE_IMAP_A_SLOT0	0x0c00UL
 #define SABRE_IMAP_B_SLOT0	0x0c20UL
-#define SABRE_IMAP_SCSI		0x1000UL
-#define SABRE_IMAP_ETH		0x1008UL
-#define SABRE_IMAP_BPP		0x1010UL
-#define SABRE_IMAP_AU_REC	0x1018UL
-#define SABRE_IMAP_AU_PLAY	0x1020UL
-#define SABRE_IMAP_PFAIL	0x1028UL
-#define SABRE_IMAP_KMS		0x1030UL
-#define SABRE_IMAP_FLPY		0x1038UL
-#define SABRE_IMAP_SHW		0x1040UL
-#define SABRE_IMAP_KBD		0x1048UL
-#define SABRE_IMAP_MS		0x1050UL
-#define SABRE_IMAP_SER		0x1058UL
-#define SABRE_IMAP_UE		0x1070UL
-#define SABRE_IMAP_CE		0x1078UL
-#define SABRE_IMAP_PCIERR	0x1080UL
-#define SABRE_IMAP_GFX		0x1098UL
-#define SABRE_IMAP_EUPA		0x10a0UL
 #define SABRE_ICLR_A_SLOT0	0x1400UL
 #define SABRE_ICLR_B_SLOT0	0x1480UL
 #define SABRE_ICLR_SCSI		0x1800UL
@@ -364,33 +299,10 @@
 		return SABRE_IMAP_B_SLOT0 + (slot * 8);
 }
 
-static unsigned long __sabre_onboard_imap_off[] = {
-/*0x20*/	SABRE_IMAP_SCSI,
-/*0x21*/	SABRE_IMAP_ETH,
-/*0x22*/	SABRE_IMAP_BPP,
-/*0x23*/	SABRE_IMAP_AU_REC,
-/*0x24*/	SABRE_IMAP_AU_PLAY,
-/*0x25*/	SABRE_IMAP_PFAIL,
-/*0x26*/	SABRE_IMAP_KMS,
-/*0x27*/	SABRE_IMAP_FLPY,
-/*0x28*/	SABRE_IMAP_SHW,
-/*0x29*/	SABRE_IMAP_KBD,
-/*0x2a*/	SABRE_IMAP_MS,
-/*0x2b*/	SABRE_IMAP_SER,
-/*0x2c*/	0 /* reserved */,
-/*0x2d*/	0 /* reserved */,
-/*0x2e*/	SABRE_IMAP_UE,
-/*0x2f*/	SABRE_IMAP_CE,
-/*0x30*/	SABRE_IMAP_PCIERR,
-/*0x31*/	0 /* reserved */,
-/*0x32*/	0 /* reserved */,
-/*0x33*/	SABRE_IMAP_GFX,
-/*0x34*/	SABRE_IMAP_EUPA,
-};
-#define SABRE_ONBOARD_IRQ_BASE		0x20
-#define SABRE_ONBOARD_IRQ_LAST		0x30
+#define SABRE_OBIO_IMAP_BASE	0x1000UL
+#define SABRE_ONBOARD_IRQ_BASE	0x20
 #define sabre_onboard_imap_offset(__ino) \
-	__sabre_onboard_imap_off[(__ino) - SABRE_ONBOARD_IRQ_BASE]
+	(SABRE_OBIO_IMAP_BASE + (((__ino) & 0x1f) << 3))
 
 #define sabre_iclr_offset(ino)					      \
 	((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) :  \
@@ -453,10 +365,6 @@
 		imap_off = sabre_pcislot_imap_offset(ino);
 	} else {
 		/* onboard device */
-		if (ino > SABRE_ONBOARD_IRQ_LAST) {
-			prom_printf("sabre_irq_build: Wacky INO [%x]\n", ino);
-			prom_halt();
-		}
 		imap_off = sabre_onboard_imap_offset(ino);
 	}
 
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
index bd578cc..10306e4 100644
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -443,7 +443,7 @@
 	 */
 	[REGSET_GENERAL] = {
 		.core_note_type = NT_PRSTATUS,
-		.n = 36 * sizeof(u64),
+		.n = 36,
 		.size = sizeof(u64), .align = sizeof(u64),
 		.get = genregs64_get, .set = genregs64_set
 	},
@@ -455,7 +455,7 @@
 	 */
 	[REGSET_FP] = {
 		.core_note_type = NT_PRFPREG,
-		.n = 35 * sizeof(u64),
+		.n = 35,
 		.size = sizeof(u64), .align = sizeof(u64),
 		.get = fpregs64_get, .set = fpregs64_set
 	},
@@ -801,7 +801,7 @@
 	 */
 	[REGSET_GENERAL] = {
 		.core_note_type = NT_PRSTATUS,
-		.n = 38 * sizeof(u32),
+		.n = 38,
 		.size = sizeof(u32), .align = sizeof(u32),
 		.get = genregs32_get, .set = genregs32_set
 	},
@@ -817,7 +817,7 @@
 	 */
 	[REGSET_FP] = {
 		.core_note_type = NT_PRFPREG,
-		.n = 99 * sizeof(u32),
+		.n = 99,
 		.size = sizeof(u32), .align = sizeof(u32),
 		.get = fpregs32_get, .set = fpregs32_set
 	},
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 743ccad..2be166c 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -80,8 +80,6 @@
 			   i, cpu_data(i).clock_tick);
 }
 
-static __cacheline_aligned_in_smp DEFINE_SPINLOCK(call_lock);
-
 extern void setup_sparc64_timer(void);
 
 static volatile unsigned long callin_flag = 0;
@@ -120,9 +118,9 @@
 	while (!cpu_isset(cpuid, smp_commenced_mask))
 		rmb();
 
-	spin_lock(&call_lock);
+	ipi_call_lock();
 	cpu_set(cpuid, cpu_online_map);
-	spin_unlock(&call_lock);
+	ipi_call_unlock();
 
 	/* idle thread is expected to have preempt disabled */
 	preempt_disable();
@@ -1305,10 +1303,6 @@
 	c->core_id = 0;
 	c->proc_id = -1;
 
-	spin_lock(&call_lock);
-	cpu_clear(cpu, cpu_online_map);
-	spin_unlock(&call_lock);
-
 	smp_wmb();
 
 	/* Make sure no interrupts point to this cpu.  */
@@ -1318,6 +1312,10 @@
 	mdelay(1);
 	local_irq_disable();
 
+	ipi_call_lock();
+	cpu_clear(cpu, cpu_online_map);
+	ipi_call_unlock();
+
 	return 0;
 }
 
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 2c518fb..b225219 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -382,14 +382,17 @@
 # P6_NOPs are a relatively minor optimization that require a family >=
 # 6 processor, except that it is broken on certain VIA chips.
 # Furthermore, AMD chips prefer a totally different sequence of NOPs
-# (which work on all CPUs).  As a result, disallow these if we're
-# compiling X86_GENERIC but not X86_64 (these NOPs do work on all
-# x86-64 capable chips); the list of processors in the right-hand clause
-# are the cores that benefit from this optimization.
+# (which work on all CPUs).  In addition, it looks like Virtual PC
+# does not understand them.
+#
+# As a result, disallow these if we're not compiling for X86_64 (these
+# NOPs do work on all x86-64 capable chips); the list of processors in
+# the right-hand clause are the cores that benefit from this optimization.
 #
 config X86_P6_NOP
 	def_bool y
-	depends on (X86_64 || !X86_GENERIC) && (M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4 || MPSC)
+	depends on X86_64
+	depends on (MCORE2 || MPENTIUM4 || MPSC)
 
 config X86_TSC
 	def_bool y
diff --git a/arch/x86/boot/cpucheck.c b/arch/x86/boot/cpucheck.c
index 4b9ae7c..4d3ff03 100644
--- a/arch/x86/boot/cpucheck.c
+++ b/arch/x86/boot/cpucheck.c
@@ -38,12 +38,12 @@
 {
 	REQUIRED_MASK0,
 	REQUIRED_MASK1,
-	REQUIRED_MASK2,
-	REQUIRED_MASK3,
+	0, /* REQUIRED_MASK2 not implemented in this file */
+	0, /* REQUIRED_MASK3 not implemented in this file */
 	REQUIRED_MASK4,
-	REQUIRED_MASK5,
+	0, /* REQUIRED_MASK5 not implemented in this file */
 	REQUIRED_MASK6,
-	REQUIRED_MASK7,
+	0, /* REQUIRED_MASK7 not implemented in this file */
 };
 
 #define A32(a, b, c, d) (((d) << 24)+((c) << 16)+((b) << 8)+(a))
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 2763cb3..65a0c1b 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -145,35 +145,25 @@
 extern char __vsyscall_0;
 const unsigned char *const *find_nop_table(void)
 {
-	return boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
-	       boot_cpu_data.x86 < 6 ? k8_nops : p6_nops;
+	if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
+	    boot_cpu_has(X86_FEATURE_NOPL))
+		return p6_nops;
+	else
+		return k8_nops;
 }
 
 #else /* CONFIG_X86_64 */
 
-static const struct nop {
-	int cpuid;
-	const unsigned char *const *noptable;
-} noptypes[] = {
-	{ X86_FEATURE_K8, k8_nops },
-	{ X86_FEATURE_K7, k7_nops },
-	{ X86_FEATURE_P4, p6_nops },
-	{ X86_FEATURE_P3, p6_nops },
-	{ -1, NULL }
-};
-
 const unsigned char *const *find_nop_table(void)
 {
-	const unsigned char *const *noptable = intel_nops;
-	int i;
-
-	for (i = 0; noptypes[i].cpuid >= 0; i++) {
-		if (boot_cpu_has(noptypes[i].cpuid)) {
-			noptable = noptypes[i].noptable;
-			break;
-		}
-	}
-	return noptable;
+	if (boot_cpu_has(X86_FEATURE_K8))
+		return k8_nops;
+	else if (boot_cpu_has(X86_FEATURE_K7))
+		return k7_nops;
+	else if (boot_cpu_has(X86_FEATURE_NOPL))
+		return p6_nops;
+	else
+		return intel_nops;
 }
 
 #endif /* CONFIG_X86_64 */
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index cae9cab..18514ed 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -31,6 +31,11 @@
 		if (c->x86_power & (1<<8))
 			set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
 	}
+
+	/*  Set MTRR capability flag if appropriate */
+	if (c->x86_model == 13 || c->x86_model == 9 ||
+	   (c->x86_model == 8 && c->x86_mask >= 8))
+		set_cpu_cap(c, X86_FEATURE_K6_MTRR);
 }
 
 static void __cpuinit init_amd(struct cpuinfo_x86 *c)
@@ -166,10 +171,6 @@
 						mbytes);
 				}
 
-				/*  Set MTRR capability flag if appropriate */
-				if (c->x86_model == 13 || c->x86_model == 9 ||
-				   (c->x86_model == 8 && c->x86_mask >= 8))
-					set_cpu_cap(c, X86_FEATURE_K6_MTRR);
 				break;
 			}
 
diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c
index e0f45ed..a0534c0 100644
--- a/arch/x86/kernel/cpu/centaur.c
+++ b/arch/x86/kernel/cpu/centaur.c
@@ -314,6 +314,16 @@
 		EAMD3D		= 1<<20,
 };
 
+static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c)
+{
+	switch (c->x86) {
+	case 5:
+		/* Emulate MTRRs using Centaur's MCR. */
+		set_cpu_cap(c, X86_FEATURE_CENTAUR_MCR);
+		break;
+	}
+}
+
 static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
 {
 
@@ -462,6 +472,7 @@
 static struct cpu_dev centaur_cpu_dev __cpuinitdata = {
 	.c_vendor	= "Centaur",
 	.c_ident	= { "CentaurHauls" },
+	.c_early_init	= early_init_centaur,
 	.c_init		= init_centaur,
 	.c_size_cache	= centaur_size_cache,
 };
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 80ab20d..8aab851 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -13,6 +13,7 @@
 #include <asm/mtrr.h>
 #include <asm/mce.h>
 #include <asm/pat.h>
+#include <asm/asm.h>
 #ifdef CONFIG_X86_LOCAL_APIC
 #include <asm/mpspec.h>
 #include <asm/apic.h>
@@ -334,11 +335,40 @@
 
 	get_cpu_vendor(c, 1);
 
+	early_get_cap(c);
+
 	if (c->x86_vendor != X86_VENDOR_UNKNOWN &&
 	    cpu_devs[c->x86_vendor]->c_early_init)
 		cpu_devs[c->x86_vendor]->c_early_init(c);
+}
 
-	early_get_cap(c);
+/*
+ * The NOPL instruction is supposed to exist on all CPUs with
+ * family >= 6, unfortunately, that's not true in practice because
+ * of early VIA chips and (more importantly) broken virtualizers that
+ * are not easy to detect.  Hence, probe for it based on first
+ * principles.
+ */
+static void __cpuinit detect_nopl(struct cpuinfo_x86 *c)
+{
+	const u32 nopl_signature = 0x888c53b1; /* Random number */
+	u32 has_nopl = nopl_signature;
+
+	clear_cpu_cap(c, X86_FEATURE_NOPL);
+	if (c->x86 >= 6) {
+		asm volatile("\n"
+			     "1:      .byte 0x0f,0x1f,0xc0\n" /* nopl %eax */
+			     "2:\n"
+			     "        .section .fixup,\"ax\"\n"
+			     "3:      xor %0,%0\n"
+			     "        jmp 2b\n"
+			     "        .previous\n"
+			     _ASM_EXTABLE(1b,3b)
+			     : "+a" (has_nopl));
+
+		if (has_nopl == nopl_signature)
+			set_cpu_cap(c, X86_FEATURE_NOPL);
+	}
 }
 
 static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
@@ -395,8 +425,8 @@
 		}
 
 		init_scattered_cpuid_features(c);
+		detect_nopl(c);
 	}
-
 }
 
 static void __cpuinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
diff --git a/arch/x86/kernel/cpu/common_64.c b/arch/x86/kernel/cpu/common_64.c
index dd6e3f1..a11f5d4 100644
--- a/arch/x86/kernel/cpu/common_64.c
+++ b/arch/x86/kernel/cpu/common_64.c
@@ -18,6 +18,7 @@
 #include <asm/mtrr.h>
 #include <asm/mce.h>
 #include <asm/pat.h>
+#include <asm/asm.h>
 #include <asm/numa.h>
 #ifdef CONFIG_X86_LOCAL_APIC
 #include <asm/mpspec.h>
@@ -215,6 +216,39 @@
 	}
 }
 
+/*
+ * The NOPL instruction is supposed to exist on all CPUs with
+ * family >= 6, unfortunately, that's not true in practice because
+ * of early VIA chips and (more importantly) broken virtualizers that
+ * are not easy to detect.  Hence, probe for it based on first
+ * principles.
+ *
+ * Note: no 64-bit chip is known to lack these, but put the code here
+ * for consistency with 32 bits, and to make it utterly trivial to
+ * diagnose the problem should it ever surface.
+ */
+static void __cpuinit detect_nopl(struct cpuinfo_x86 *c)
+{
+	const u32 nopl_signature = 0x888c53b1; /* Random number */
+	u32 has_nopl = nopl_signature;
+
+	clear_cpu_cap(c, X86_FEATURE_NOPL);
+	if (c->x86 >= 6) {
+		asm volatile("\n"
+			     "1:      .byte 0x0f,0x1f,0xc0\n" /* nopl %eax */
+			     "2:\n"
+			     "        .section .fixup,\"ax\"\n"
+			     "3:      xor %0,%0\n"
+			     "        jmp 2b\n"
+			     "        .previous\n"
+			     _ASM_EXTABLE(1b,3b)
+			     : "+a" (has_nopl));
+
+		if (has_nopl == nopl_signature)
+			set_cpu_cap(c, X86_FEATURE_NOPL);
+	}
+}
+
 static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c);
 
 void __init early_cpu_init(void)
@@ -313,6 +347,8 @@
 		c->x86_phys_bits = eax & 0xff;
 	}
 
+	detect_nopl(c);
+
 	if (c->x86_vendor != X86_VENDOR_UNKNOWN &&
 	    cpu_devs[c->x86_vendor]->c_early_init)
 		cpu_devs[c->x86_vendor]->c_early_init(c);
@@ -493,17 +529,20 @@
 		/* others are initialized in smpboot.c */
 		pda->pcurrent = &init_task;
 		pda->irqstackptr = boot_cpu_stack;
+		pda->irqstackptr += IRQSTACKSIZE - 64;
 	} else {
-		pda->irqstackptr = (char *)
-			__get_free_pages(GFP_ATOMIC, IRQSTACK_ORDER);
-		if (!pda->irqstackptr)
-			panic("cannot allocate irqstack for cpu %d", cpu);
+		if (!pda->irqstackptr) {
+			pda->irqstackptr = (char *)
+				__get_free_pages(GFP_ATOMIC, IRQSTACK_ORDER);
+			if (!pda->irqstackptr)
+				panic("cannot allocate irqstack for cpu %d",
+				      cpu);
+			pda->irqstackptr += IRQSTACKSIZE - 64;
+		}
 
 		if (pda->nodenumber == 0 && cpu_to_node(cpu) != NUMA_NO_NODE)
 			pda->nodenumber = cpu_to_node(cpu);
 	}
-
-	pda->irqstackptr += IRQSTACKSIZE-64;
 }
 
 char boot_exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ +
@@ -601,19 +640,22 @@
 	/*
 	 * set up and load the per-CPU TSS
 	 */
-	for (v = 0; v < N_EXCEPTION_STACKS; v++) {
+	if (!orig_ist->ist[0]) {
 		static const unsigned int order[N_EXCEPTION_STACKS] = {
-			[0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER,
-			[DEBUG_STACK - 1] = DEBUG_STACK_ORDER
+		  [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER,
+		  [DEBUG_STACK - 1] = DEBUG_STACK_ORDER
 		};
-		if (cpu) {
-			estacks = (char *)__get_free_pages(GFP_ATOMIC, order[v]);
-			if (!estacks)
-				panic("Cannot allocate exception stack %ld %d\n",
-				      v, cpu);
+		for (v = 0; v < N_EXCEPTION_STACKS; v++) {
+			if (cpu) {
+				estacks = (char *)__get_free_pages(GFP_ATOMIC, order[v]);
+				if (!estacks)
+					panic("Cannot allocate exception "
+					      "stack %ld %d\n", v, cpu);
+			}
+			estacks += PAGE_SIZE << order[v];
+			orig_ist->ist[v] = t->x86_tss.ist[v] =
+					(unsigned long)estacks;
 		}
-		estacks += PAGE_SIZE << order[v];
-		orig_ist->ist[v] = t->x86_tss.ist[v] = (unsigned long)estacks;
 	}
 
 	t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c
index e710a21..898a5a2 100644
--- a/arch/x86/kernel/cpu/cyrix.c
+++ b/arch/x86/kernel/cpu/cyrix.c
@@ -15,13 +15,11 @@
 /*
  * Read NSC/Cyrix DEVID registers (DIR) to get more detailed info. about the CPU
  */
-static void __cpuinit do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
+static void __cpuinit __do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
 {
 	unsigned char ccr2, ccr3;
-	unsigned long flags;
 
 	/* we test for DEVID by checking whether CCR3 is writable */
-	local_irq_save(flags);
 	ccr3 = getCx86(CX86_CCR3);
 	setCx86(CX86_CCR3, ccr3 ^ 0x80);
 	getCx86(0xc0);   /* dummy to change bus */
@@ -44,9 +42,16 @@
 		*dir0 = getCx86(CX86_DIR0);
 		*dir1 = getCx86(CX86_DIR1);
 	}
-	local_irq_restore(flags);
 }
 
+static void __cpuinit do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	__do_cyrix_devid(dir0, dir1);
+	local_irq_restore(flags);
+}
 /*
  * Cx86_dir0_msb is a HACK needed by check_cx686_cpuid/slop in bugs.h in
  * order to identify the Cyrix CPU model after we're out of setup.c
@@ -161,6 +166,24 @@
 	local_irq_restore(flags);
 }
 
+static void __cpuinit early_init_cyrix(struct cpuinfo_x86 *c)
+{
+	unsigned char dir0, dir0_msn, dir1 = 0;
+
+	__do_cyrix_devid(&dir0, &dir1);
+	dir0_msn = dir0 >> 4; /* identifies CPU "family"   */
+
+	switch (dir0_msn) {
+	case 3: /* 6x86/6x86L */
+		/* Emulate MTRRs using Cyrix's ARRs. */
+		set_cpu_cap(c, X86_FEATURE_CYRIX_ARR);
+		break;
+	case 5: /* 6x86MX/M II */
+		/* Emulate MTRRs using Cyrix's ARRs. */
+		set_cpu_cap(c, X86_FEATURE_CYRIX_ARR);
+		break;
+	}
+}
 
 static void __cpuinit init_cyrix(struct cpuinfo_x86 *c)
 {
@@ -416,6 +439,7 @@
 static struct cpu_dev cyrix_cpu_dev __cpuinitdata = {
 	.c_vendor	= "Cyrix",
 	.c_ident	= { "CyrixInstead" },
+	.c_early_init	= early_init_cyrix,
 	.c_init		= init_cyrix,
 	.c_identify	= cyrix_identify,
 };
diff --git a/arch/x86/kernel/cpu/feature_names.c b/arch/x86/kernel/cpu/feature_names.c
index e43ad4a..c901779 100644
--- a/arch/x86/kernel/cpu/feature_names.c
+++ b/arch/x86/kernel/cpu/feature_names.c
@@ -39,7 +39,8 @@
 	NULL, NULL, NULL, NULL,
 	"constant_tsc", "up", NULL, "arch_perfmon",
 	"pebs", "bts", NULL, NULL,
-	"rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	"rep_good", NULL, NULL, NULL,
+	"nopl", NULL, NULL, NULL,
 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
 	/* Intel-defined (#2) */
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 9af8907..66e48aa 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -1203,7 +1203,7 @@
 	if (!p)
 		return -EINVAL;
 
-	if (!strcmp(p, "exactmap")) {
+	if (!strncmp(p, "exactmap", 8)) {
 #ifdef CONFIG_CRASH_DUMP
 		/*
 		 * If we are doing a crash dump, we still need to know
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 59fd3b6..73deaff 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -210,8 +210,8 @@
 	/* Calculate the min / max delta */
 	hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
 							   &hpet_clockevent);
-	hpet_clockevent.min_delta_ns = clockevent_delta2ns(0x30,
-							   &hpet_clockevent);
+	/* 5 usec minimum reprogramming delta. */
+	hpet_clockevent.min_delta_ns = 5000;
 
 	/*
 	 * Start hpet with the boot cpu mask and make it
@@ -270,15 +270,22 @@
 }
 
 static int hpet_legacy_next_event(unsigned long delta,
-			   struct clock_event_device *evt)
+				  struct clock_event_device *evt)
 {
-	unsigned long cnt;
+	u32 cnt;
 
 	cnt = hpet_readl(HPET_COUNTER);
-	cnt += delta;
+	cnt += (u32) delta;
 	hpet_writel(cnt, HPET_T0_CMP);
 
-	return ((long)(hpet_readl(HPET_COUNTER) - cnt ) > 0) ? -ETIME : 0;
+	/*
+	 * We need to read back the CMP register to make sure that
+	 * what we wrote hit the chip before we compare it to the
+	 * counter.
+	 */
+	WARN_ON((u32)hpet_readl(HPET_T0_CMP) != cnt);
+
+	return (s32)((u32)hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
 }
 
 /*
diff --git a/arch/x86/kernel/io_delay.c b/arch/x86/kernel/io_delay.c
index 1c3a66a..720d260 100644
--- a/arch/x86/kernel/io_delay.c
+++ b/arch/x86/kernel/io_delay.c
@@ -92,6 +92,14 @@
 			DMI_MATCH(DMI_BOARD_NAME, "30BF")
 		}
 	},
+	{
+		.callback	= dmi_io_delay_0xed_port,
+		.ident		= "Presario F700",
+		.matches	= {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
+			DMI_MATCH(DMI_BOARD_NAME, "30D3")
+		}
+	},
 	{ }
 };
 
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index ac79bd1..8f98e9d 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -122,15 +122,75 @@
 	return ULLONG_MAX;
 }
 
+/*
+ * Try to calibrate the TSC against the Programmable
+ * Interrupt Timer and return the frequency of the TSC
+ * in kHz.
+ *
+ * Return ULONG_MAX on failure to calibrate.
+ */
+static unsigned long pit_calibrate_tsc(void)
+{
+	u64 tsc, t1, t2, delta;
+	unsigned long tscmin, tscmax;
+	int pitcnt;
+
+	/* Set the Gate high, disable speaker */
+	outb((inb(0x61) & ~0x02) | 0x01, 0x61);
+
+	/*
+	 * Setup CTC channel 2* for mode 0, (interrupt on terminal
+	 * count mode), binary count. Set the latch register to 50ms
+	 * (LSB then MSB) to begin countdown.
+	 */
+	outb(0xb0, 0x43);
+	outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42);
+	outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42);
+
+	tsc = t1 = t2 = get_cycles();
+
+	pitcnt = 0;
+	tscmax = 0;
+	tscmin = ULONG_MAX;
+	while ((inb(0x61) & 0x20) == 0) {
+		t2 = get_cycles();
+		delta = t2 - tsc;
+		tsc = t2;
+		if ((unsigned long) delta < tscmin)
+			tscmin = (unsigned int) delta;
+		if ((unsigned long) delta > tscmax)
+			tscmax = (unsigned int) delta;
+		pitcnt++;
+	}
+
+	/*
+	 * Sanity checks:
+	 *
+	 * If we were not able to read the PIT more than 5000
+	 * times, then we have been hit by a massive SMI
+	 *
+	 * If the maximum is 10 times larger than the minimum,
+	 * then we got hit by an SMI as well.
+	 */
+	if (pitcnt < 5000 || tscmax > 10 * tscmin)
+		return ULONG_MAX;
+
+	/* Calculate the PIT value */
+	delta = t2 - t1;
+	do_div(delta, 50);
+	return delta;
+}
+
+
 /**
  * native_calibrate_tsc - calibrate the tsc on boot
  */
 unsigned long native_calibrate_tsc(void)
 {
-	u64 tsc1, tsc2, tr1, tr2, tsc, delta, pm1, pm2, hpet1, hpet2;
+	u64 tsc1, tsc2, delta, pm1, pm2, hpet1, hpet2;
 	unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX;
-	unsigned long flags, tscmin, tscmax;
-	int hpet = is_hpet_enabled(), pitcnt, i;
+	unsigned long flags;
+	int hpet = is_hpet_enabled(), i;
 
 	/*
 	 * Run 5 calibration loops to get the lowest frequency value
@@ -157,72 +217,22 @@
 	 * amount of time anyway.
 	 */
 	for (i = 0; i < 5; i++) {
-
-		tscmin = ULONG_MAX;
-		tscmax = 0;
-		pitcnt = 0;
-
-		local_irq_save(flags);
+		unsigned long tsc_pit_khz;
 
 		/*
 		 * Read the start value and the reference count of
-		 * hpet/pmtimer when available:
+		 * hpet/pmtimer when available. Then do the PIT
+		 * calibration, which will take at least 50ms, and
+		 * read the end value.
 		 */
+		local_irq_save(flags);
 		tsc1 = tsc_read_refs(&pm1, hpet ? &hpet1 : NULL);
-
-		/* Set the Gate high, disable speaker */
-		outb((inb(0x61) & ~0x02) | 0x01, 0x61);
-
-		/*
-		 * Setup CTC channel 2* for mode 0, (interrupt on terminal
-		 * count mode), binary count. Set the latch register to 50ms
-		 * (LSB then MSB) to begin countdown.
-		 *
-		 * Some devices need a delay here.
-		 */
-		outb(0xb0, 0x43);
-		outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42);
-		outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42);
-
-		tsc = tr1 = tr2 = get_cycles();
-
-		while ((inb(0x61) & 0x20) == 0) {
-			tr2 = get_cycles();
-			delta = tr2 - tsc;
-			tsc = tr2;
-			if ((unsigned int) delta < tscmin)
-				tscmin = (unsigned int) delta;
-			if ((unsigned int) delta > tscmax)
-				tscmax = (unsigned int) delta;
-			pitcnt++;
-		}
-
-		/*
-		 * We waited at least 50ms above. Now read
-		 * pmtimer/hpet reference again
-		 */
+		tsc_pit_khz = pit_calibrate_tsc();
 		tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL);
-
 		local_irq_restore(flags);
 
-		/*
-		 * Sanity checks:
-		 *
-		 * If we were not able to read the PIT more than 5000
-		 * times, then we have been hit by a massive SMI
-		 *
-		 * If the maximum is 10 times larger than the minimum,
-		 * then we got hit by an SMI as well.
-		 */
-		if (pitcnt > 5000 && tscmax < 10 * tscmin) {
-
-			/* Calculate the PIT value */
-			delta = tr2 - tr1;
-			do_div(delta, 50);
-
-			/* We take the smallest value into account */
-			tsc_pit_min = min(tsc_pit_min, (unsigned long) delta);
-		}
+		/* Pick the lowest PIT TSC calibration so far */
+		tsc_pit_min = min(tsc_pit_min, tsc_pit_khz);
 
 		/* hpet or pmtimer available ? */
 		if (!hpet && !pm1 && !pm2)
@@ -257,8 +267,7 @@
 	 */
 	if (tsc_pit_min == ULONG_MAX) {
 		/* PIT gave no useful value */
-		printk(KERN_WARNING "TSC: PIT calibration failed due to "
-		       "SMI disturbance.\n");
+		printk(KERN_WARNING "TSC: Unable to calibrate against PIT\n");
 
 		/* We don't have an alternative source, disable TSC */
 		if (!hpet && !pm1 && !pm2) {
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 0bfe2bd..3da2508 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -711,6 +711,10 @@
 	u64 *spte;
 	int young = 0;
 
+	/* always return old for EPT */
+	if (!shadow_accessed_mask)
+		return 0;
+
 	spte = rmap_next(kvm, rmapp, NULL);
 	while (spte) {
 		int _young;
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index e2ee264..8233b86 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -62,6 +62,7 @@
 module_param(npt, int, S_IRUGO);
 
 static void kvm_reput_irq(struct vcpu_svm *svm);
+static void svm_flush_tlb(struct kvm_vcpu *vcpu);
 
 static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu)
 {
@@ -878,6 +879,10 @@
 static void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
 {
 	unsigned long host_cr4_mce = read_cr4() & X86_CR4_MCE;
+	unsigned long old_cr4 = to_svm(vcpu)->vmcb->save.cr4;
+
+	if (npt_enabled && ((old_cr4 ^ cr4) & X86_CR4_PGE))
+		force_new_asid(vcpu);
 
 	vcpu->arch.cr4 = cr4;
 	if (!npt_enabled)
@@ -1027,6 +1032,13 @@
 		KVMTRACE_3D(TDP_FAULT, &svm->vcpu, error_code,
 			    (u32)fault_address, (u32)(fault_address >> 32),
 			    handler);
+	/*
+	 * FIXME: Tis shouldn't be necessary here, but there is a flush
+	 * missing in the MMU code. Until we find this bug, flush the
+	 * complete TLB here on an NPF
+	 */
+	if (npt_enabled)
+		svm_flush_tlb(&svm->vcpu);
 
 	if (event_injection)
 		kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address);
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 2a69773..7041cc5 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -3301,8 +3301,7 @@
 		kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK |
 			VMX_EPT_WRITABLE_MASK |
 			VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT);
-		kvm_mmu_set_mask_ptes(0ull, VMX_EPT_FAKE_ACCESSED_MASK,
-				VMX_EPT_FAKE_DIRTY_MASK, 0ull,
+		kvm_mmu_set_mask_ptes(0ull, 0ull, 0ull, 0ull,
 				VMX_EPT_EXECUTABLE_MASK);
 		kvm_enable_tdp();
 	} else
diff --git a/arch/x86/kvm/vmx.h b/arch/x86/kvm/vmx.h
index 425a134..23e8373 100644
--- a/arch/x86/kvm/vmx.h
+++ b/arch/x86/kvm/vmx.h
@@ -370,8 +370,6 @@
 #define VMX_EPT_READABLE_MASK			0x1ull
 #define VMX_EPT_WRITABLE_MASK			0x2ull
 #define VMX_EPT_EXECUTABLE_MASK			0x4ull
-#define VMX_EPT_FAKE_ACCESSED_MASK		(1ull << 62)
-#define VMX_EPT_FAKE_DIRTY_MASK			(1ull << 63)
 
 #define VMX_EPT_IDENTITY_PAGETABLE_ADDR		0xfffbc000ul
 
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 9ff6e3c..a4e201b 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1324,7 +1324,7 @@
 	.ptep_modify_prot_commit = __ptep_modify_prot_commit,
 
 	.pte_val = xen_pte_val,
-	.pte_flags = native_pte_val,
+	.pte_flags = native_pte_flags,
 	.pgd_val = xen_pgd_val,
 
 	.make_pte = xen_make_pte,
diff --git a/block/cmd-filter.c b/block/cmd-filter.c
index 228b644..79c1499 100644
--- a/block/cmd-filter.c
+++ b/block/cmd-filter.c
@@ -49,6 +49,7 @@
 }
 EXPORT_SYMBOL(blk_verify_command);
 
+#if 0
 /* and now, the sysfs stuff */
 static ssize_t rcf_cmds_show(struct blk_cmd_filter *filter, char *page,
 			     int rw)
@@ -233,3 +234,4 @@
 	kobject_put(disk->holder_dir->parent);
 }
 EXPORT_SYMBOL(blk_unregister_filter);
+#endif
diff --git a/crypto/async_tx/async_tx.c b/crypto/async_tx/async_tx.c
index 85eaf7b..e8362c1 100644
--- a/crypto/async_tx/async_tx.c
+++ b/crypto/async_tx/async_tx.c
@@ -137,7 +137,8 @@
 		spin_lock_bh(&next->lock);
 		next->parent = NULL;
 		_next = next->next;
-		next->next = NULL;
+		if (_next && _next->chan == chan)
+			next->next = NULL;
 		spin_unlock_bh(&next->lock);
 
 		next->tx_submit(next);
diff --git a/crypto/camellia.c b/crypto/camellia.c
index b1cc4de..493fee7 100644
--- a/crypto/camellia.c
+++ b/crypto/camellia.c
@@ -35,8 +35,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/bitops.h>
-#include <asm/unaligned.h>
 
 static const u32 camellia_sp1110[256] = {
 	0x70707000,0x82828200,0x2c2c2c00,0xececec00,
@@ -337,6 +335,20 @@
 /*
  *  macros
  */
+#define GETU32(v, pt) \
+    do { \
+	/* latest breed of gcc is clever enough to use move */ \
+	memcpy(&(v), (pt), 4); \
+	(v) = be32_to_cpu(v); \
+    } while(0)
+
+/* rotation right shift 1byte */
+#define ROR8(x) (((x) >> 8) + ((x) << 24))
+/* rotation left shift 1bit */
+#define ROL1(x) (((x) << 1) + ((x) >> 31))
+/* rotation left shift 1byte */
+#define ROL8(x) (((x) << 8) + ((x) >> 24))
+
 #define ROLDQ(ll, lr, rl, rr, w0, w1, bits)		\
     do {						\
 	w0 = ll;					\
@@ -371,7 +383,7 @@
 	   ^ camellia_sp3033[(u8)(il >> 8)]			\
 	   ^ camellia_sp4404[(u8)(il     )];			\
 	yl ^= yr;						\
-	yr = ror32(yr, 8);					\
+	yr = ROR8(yr);						\
 	yr ^= yl;						\
     } while(0)
 
@@ -393,7 +405,7 @@
 	subL[7] ^= subL[1]; subR[7] ^= subR[1];
 	subL[1] ^= subR[1] & ~subR[9];
 	dw = subL[1] & subL[9],
-		subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl2) */
+		subR[1] ^= ROL1(dw); /* modified for FLinv(kl2) */
 	/* round 8 */
 	subL[11] ^= subL[1]; subR[11] ^= subR[1];
 	/* round 10 */
@@ -402,7 +414,7 @@
 	subL[15] ^= subL[1]; subR[15] ^= subR[1];
 	subL[1] ^= subR[1] & ~subR[17];
 	dw = subL[1] & subL[17],
-		subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl4) */
+		subR[1] ^= ROL1(dw); /* modified for FLinv(kl4) */
 	/* round 14 */
 	subL[19] ^= subL[1]; subR[19] ^= subR[1];
 	/* round 16 */
@@ -418,7 +430,7 @@
 	} else {
 		subL[1] ^= subR[1] & ~subR[25];
 		dw = subL[1] & subL[25],
-			subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl6) */
+			subR[1] ^= ROL1(dw); /* modified for FLinv(kl6) */
 		/* round 20 */
 		subL[27] ^= subL[1]; subR[27] ^= subR[1];
 		/* round 22 */
@@ -438,7 +450,7 @@
 		subL[26] ^= kw4l; subR[26] ^= kw4r;
 		kw4l ^= kw4r & ~subR[24];
 		dw = kw4l & subL[24],
-			kw4r ^= rol32(dw, 1); /* modified for FL(kl5) */
+			kw4r ^= ROL1(dw); /* modified for FL(kl5) */
 	}
 	/* round 17 */
 	subL[22] ^= kw4l; subR[22] ^= kw4r;
@@ -448,7 +460,7 @@
 	subL[18] ^= kw4l; subR[18] ^= kw4r;
 	kw4l ^= kw4r & ~subR[16];
 	dw = kw4l & subL[16],
-		kw4r ^= rol32(dw, 1); /* modified for FL(kl3) */
+		kw4r ^= ROL1(dw); /* modified for FL(kl3) */
 	/* round 11 */
 	subL[14] ^= kw4l; subR[14] ^= kw4r;
 	/* round 9 */
@@ -457,7 +469,7 @@
 	subL[10] ^= kw4l; subR[10] ^= kw4r;
 	kw4l ^= kw4r & ~subR[8];
 	dw = kw4l & subL[8],
-		kw4r ^= rol32(dw, 1); /* modified for FL(kl1) */
+		kw4r ^= ROL1(dw); /* modified for FL(kl1) */
 	/* round 5 */
 	subL[6] ^= kw4l; subR[6] ^= kw4r;
 	/* round 3 */
@@ -482,7 +494,7 @@
 	SUBKEY_R(6) = subR[5] ^ subR[7];
 	tl = subL[10] ^ (subR[10] & ~subR[8]);
 	dw = tl & subL[8],  /* FL(kl1) */
-		tr = subR[10] ^ rol32(dw, 1);
+		tr = subR[10] ^ ROL1(dw);
 	SUBKEY_L(7) = subL[6] ^ tl; /* round 6 */
 	SUBKEY_R(7) = subR[6] ^ tr;
 	SUBKEY_L(8) = subL[8];       /* FL(kl1) */
@@ -491,7 +503,7 @@
 	SUBKEY_R(9) = subR[9];
 	tl = subL[7] ^ (subR[7] & ~subR[9]);
 	dw = tl & subL[9],  /* FLinv(kl2) */
-		tr = subR[7] ^ rol32(dw, 1);
+		tr = subR[7] ^ ROL1(dw);
 	SUBKEY_L(10) = tl ^ subL[11]; /* round 7 */
 	SUBKEY_R(10) = tr ^ subR[11];
 	SUBKEY_L(11) = subL[10] ^ subL[12]; /* round 8 */
@@ -504,7 +516,7 @@
 	SUBKEY_R(14) = subR[13] ^ subR[15];
 	tl = subL[18] ^ (subR[18] & ~subR[16]);
 	dw = tl & subL[16], /* FL(kl3) */
-		tr = subR[18] ^ rol32(dw, 1);
+		tr = subR[18] ^ ROL1(dw);
 	SUBKEY_L(15) = subL[14] ^ tl; /* round 12 */
 	SUBKEY_R(15) = subR[14] ^ tr;
 	SUBKEY_L(16) = subL[16];     /* FL(kl3) */
@@ -513,7 +525,7 @@
 	SUBKEY_R(17) = subR[17];
 	tl = subL[15] ^ (subR[15] & ~subR[17]);
 	dw = tl & subL[17], /* FLinv(kl4) */
-		tr = subR[15] ^ rol32(dw, 1);
+		tr = subR[15] ^ ROL1(dw);
 	SUBKEY_L(18) = tl ^ subL[19]; /* round 13 */
 	SUBKEY_R(18) = tr ^ subR[19];
 	SUBKEY_L(19) = subL[18] ^ subL[20]; /* round 14 */
@@ -532,7 +544,7 @@
 	} else {
 		tl = subL[26] ^ (subR[26] & ~subR[24]);
 		dw = tl & subL[24], /* FL(kl5) */
-			tr = subR[26] ^ rol32(dw, 1);
+			tr = subR[26] ^ ROL1(dw);
 		SUBKEY_L(23) = subL[22] ^ tl; /* round 18 */
 		SUBKEY_R(23) = subR[22] ^ tr;
 		SUBKEY_L(24) = subL[24];     /* FL(kl5) */
@@ -541,7 +553,7 @@
 		SUBKEY_R(25) = subR[25];
 		tl = subL[23] ^ (subR[23] & ~subR[25]);
 		dw = tl & subL[25], /* FLinv(kl6) */
-			tr = subR[23] ^ rol32(dw, 1);
+			tr = subR[23] ^ ROL1(dw);
 		SUBKEY_L(26) = tl ^ subL[27]; /* round 19 */
 		SUBKEY_R(26) = tr ^ subR[27];
 		SUBKEY_L(27) = subL[26] ^ subL[28]; /* round 20 */
@@ -561,17 +573,17 @@
 	/* apply the inverse of the last half of P-function */
 	i = 2;
 	do {
-		dw = SUBKEY_L(i + 0) ^ SUBKEY_R(i + 0); dw = rol32(dw, 8);/* round 1 */
+		dw = SUBKEY_L(i + 0) ^ SUBKEY_R(i + 0); dw = ROL8(dw);/* round 1 */
 		SUBKEY_R(i + 0) = SUBKEY_L(i + 0) ^ dw; SUBKEY_L(i + 0) = dw;
-		dw = SUBKEY_L(i + 1) ^ SUBKEY_R(i + 1); dw = rol32(dw, 8);/* round 2 */
+		dw = SUBKEY_L(i + 1) ^ SUBKEY_R(i + 1); dw = ROL8(dw);/* round 2 */
 		SUBKEY_R(i + 1) = SUBKEY_L(i + 1) ^ dw; SUBKEY_L(i + 1) = dw;
-		dw = SUBKEY_L(i + 2) ^ SUBKEY_R(i + 2); dw = rol32(dw, 8);/* round 3 */
+		dw = SUBKEY_L(i + 2) ^ SUBKEY_R(i + 2); dw = ROL8(dw);/* round 3 */
 		SUBKEY_R(i + 2) = SUBKEY_L(i + 2) ^ dw; SUBKEY_L(i + 2) = dw;
-		dw = SUBKEY_L(i + 3) ^ SUBKEY_R(i + 3); dw = rol32(dw, 8);/* round 4 */
+		dw = SUBKEY_L(i + 3) ^ SUBKEY_R(i + 3); dw = ROL8(dw);/* round 4 */
 		SUBKEY_R(i + 3) = SUBKEY_L(i + 3) ^ dw; SUBKEY_L(i + 3) = dw;
-		dw = SUBKEY_L(i + 4) ^ SUBKEY_R(i + 4); dw = rol32(dw, 9);/* round 5 */
+		dw = SUBKEY_L(i + 4) ^ SUBKEY_R(i + 4); dw = ROL8(dw);/* round 5 */
 		SUBKEY_R(i + 4) = SUBKEY_L(i + 4) ^ dw; SUBKEY_L(i + 4) = dw;
-		dw = SUBKEY_L(i + 5) ^ SUBKEY_R(i + 5); dw = rol32(dw, 8);/* round 6 */
+		dw = SUBKEY_L(i + 5) ^ SUBKEY_R(i + 5); dw = ROL8(dw);/* round 6 */
 		SUBKEY_R(i + 5) = SUBKEY_L(i + 5) ^ dw; SUBKEY_L(i + 5) = dw;
 		i += 8;
 	} while (i < max);
@@ -587,10 +599,10 @@
 	/**
 	 *  k == kll || klr || krl || krr (|| is concatenation)
 	 */
-	kll = get_unaligned_be32(key);
-	klr = get_unaligned_be32(key + 4);
-	krl = get_unaligned_be32(key + 8);
-	krr = get_unaligned_be32(key + 12);
+	GETU32(kll, key     );
+	GETU32(klr, key +  4);
+	GETU32(krl, key +  8);
+	GETU32(krr, key + 12);
 
 	/* generate KL dependent subkeys */
 	/* kw1 */
@@ -695,14 +707,14 @@
 	 *  key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
 	 *  (|| is concatenation)
 	 */
-	kll = get_unaligned_be32(key);
-	klr = get_unaligned_be32(key + 4);
-	krl = get_unaligned_be32(key + 8);
-	krr = get_unaligned_be32(key + 12);
-	krll = get_unaligned_be32(key + 16);
-	krlr = get_unaligned_be32(key + 20);
-	krrl = get_unaligned_be32(key + 24);
-	krrr = get_unaligned_be32(key + 28);
+	GETU32(kll,  key     );
+	GETU32(klr,  key +  4);
+	GETU32(krl,  key +  8);
+	GETU32(krr,  key + 12);
+	GETU32(krll, key + 16);
+	GETU32(krlr, key + 20);
+	GETU32(krrl, key + 24);
+	GETU32(krrr, key + 28);
 
 	/* generate KL dependent subkeys */
 	/* kw1 */
@@ -858,13 +870,13 @@
 	t0 &= ll;							\
 	t2 |= rr;							\
 	rl ^= t2;							\
-	lr ^= rol32(t0, 1);						\
+	lr ^= ROL1(t0);							\
 	t3 = krl;							\
 	t1 = klr;							\
 	t3 &= rl;							\
 	t1 |= lr;							\
 	ll ^= t1;							\
-	rr ^= rol32(t3, 1);						\
+	rr ^= ROL1(t3);							\
     } while(0)
 
 #define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir)		\
@@ -880,7 +892,7 @@
 	il ^= kl;							\
 	ir ^= il ^ kr;							\
 	yl ^= ir;							\
-	yr ^= ror32(il, 8) ^ ir;						\
+	yr ^= ROR8(il) ^ ir;						\
     } while(0)
 
 /* max = 24: 128bit encrypt, max = 32: 256bit encrypt */
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
index 1022e38..0f28058 100644
--- a/drivers/acpi/dispatcher/dsobject.c
+++ b/drivers/acpi/dispatcher/dsobject.c
@@ -496,7 +496,7 @@
 			arg = arg->common.next;
 		}
 
-		ACPI_ERROR((AE_INFO,
+		ACPI_WARNING((AE_INFO,
 			    "Package List length (%X) larger than NumElements count (%X), truncated\n",
 			    i, element_count));
 	} else if (i < element_count) {
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 80e3209..80c251e 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -71,7 +71,7 @@
  *  1 -> ignore _PPC totally -> forced by user through boot param
  */
 static int ignore_ppc = -1;
-module_param(ignore_ppc, uint, 0644);
+module_param(ignore_ppc, int, 0644);
 MODULE_PARM_DESC(ignore_ppc, "If the frequency of your machine gets wrongly" \
 		 "limited by BIOS, this should help");
 
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c
index bcf2c70..a4e3767 100644
--- a/drivers/acpi/sbshc.c
+++ b/drivers/acpi/sbshc.c
@@ -107,6 +107,13 @@
 	if (wait_event_timeout(hc->wait, smb_check_done(hc),
 			       msecs_to_jiffies(timeout)))
 		return 0;
+	/*
+	 * After the timeout happens, OS will try to check the status of SMbus.
+	 * If the status is what OS expected, it will be regarded as the bogus
+	 * timeout.
+	 */
+	if (smb_check_done(hc))
+		return 0;
 	else
 		return -ETIME;
 }
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index c341918..775c97a 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -300,6 +300,8 @@
 
 static int __init acpi_parse_apic_instance(char *str)
 {
+	if (!str)
+		return -EINVAL;
 
 	acpi_apic_instance = simple_strtoul(str, NULL, 0);
 
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index ae84949..11c8c19 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -448,8 +448,10 @@
 	tristate "Marvell PATA support via legacy mode"
 	depends on PCI
 	help
-	  This option enables limited support for the Marvell 88SE6145 ATA
-	  controller.
+	  This option enables limited support for the Marvell 88SE61xx ATA
+	  controllers. If you wish to use only the SATA ports then select
+	  the AHCI driver alone. If you wish to the use the PATA port or
+	  both SATA and PATA include this driver.
 
 	  If unsure, say N.
 
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index c729e69..2e1a7cb 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -420,7 +420,7 @@
 	/* board_ahci_mv */
 	{
 		AHCI_HFLAGS	(AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_MSI |
-				 AHCI_HFLAG_MV_PATA),
+				 AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP),
 		.flags		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
 				  ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA,
 		.pio_mask	= 0x1f, /* pio0-4 */
@@ -487,7 +487,9 @@
 	{ PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */
 	{ PCI_VDEVICE(INTEL, 0x3a25), board_ahci }, /* ICH10 */
 	{ PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */
+	{ PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */
 	{ PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
+	{ PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */
 
 	/* JMicron 360/1/3/5/6, match class to avoid IDE function */
 	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -610,6 +612,15 @@
 MODULE_PARM_DESC(ahci_em_messages,
 	"Set AHCI Enclosure Management Message type (0 = disabled, 1 = LED");
 
+#if defined(CONFIG_PATA_MARVELL) || defined(CONFIG_PATA_MARVELL_MODULE)
+static int marvell_enable;
+#else
+static int marvell_enable = 1;
+#endif
+module_param(marvell_enable, int, 0644);
+MODULE_PARM_DESC(marvell_enable, "Marvell SATA via AHCI (1 = enabled)");
+
+
 static inline int ahci_nr_ports(u32 cap)
 {
 	return (cap & 0x1f) + 1;
@@ -732,6 +743,8 @@
 			   "MV_AHCI HACK: port_map %x -> %x\n",
 			   port_map,
 			   port_map & mv);
+		dev_printk(KERN_ERR, &pdev->dev,
+			  "Disabling your PATA port. Use the boot option 'ahci.marvell_enable=0' to avoid this.\n");
 
 		port_map &= mv;
 	}
@@ -2533,6 +2546,12 @@
 	if (!printed_version++)
 		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+	/* The AHCI driver can only drive the SATA ports, the PATA driver
+	   can drive them all so if both drivers are selected make sure
+	   AHCI stays out of the way */
+	if (pdev->vendor == PCI_VENDOR_ID_MARVELL && !marvell_enable)
+		return -ENODEV;
+
 	/* acquire resources */
 	rc = pcim_enable_device(pdev);
 	if (rc)
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index b1d08a8..e6b4606 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -1499,7 +1499,7 @@
 	 * off.
 	 */
 	if (pdev->vendor == PCI_VENDOR_ID_INTEL && pdev->device == 0x2652) {
-		int rc = piix_disable_ahci(pdev);
+		rc = piix_disable_ahci(pdev);
 		if (rc)
 			return rc;
 	}
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 304fdc6..2a4c516 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -1315,11 +1315,6 @@
 		break;
 
 	case HSM_ST_ERR:
-		/* make sure qc->err_mask is available to
-		 * know what's wrong and recover
-		 */
-		WARN_ON(!(qc->err_mask & (AC_ERR_DEV | AC_ERR_HSM)));
-
 		ap->hsm_task_state = HSM_ST_IDLE;
 
 		/* complete taskfile transaction */
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c
index 24a011b..0d87eec 100644
--- a/drivers/ata/pata_marvell.c
+++ b/drivers/ata/pata_marvell.c
@@ -20,7 +20,42 @@
 #include <linux/ata.h>
 
 #define DRV_NAME	"pata_marvell"
-#define DRV_VERSION	"0.1.4"
+#define DRV_VERSION	"0.1.6"
+
+/**
+ *	marvell_pata_active	-	check if PATA is active
+ *	@pdev: PCI device
+ *
+ *	Returns 1 if the PATA port may be active. We know how to check this
+ *	for the 6145 but not the other devices
+ */
+
+static int marvell_pata_active(struct pci_dev *pdev)
+{
+	int i;
+	u32 devices;
+	void __iomem *barp;
+
+	/* We don't yet know how to do this for other devices */
+	if (pdev->device != 0x6145)
+		return 1;	
+
+	barp = pci_iomap(pdev, 5, 0x10);
+	if (barp == NULL)
+		return -ENOMEM;
+
+	printk("BAR5:");
+	for(i = 0; i <= 0x0F; i++)
+		printk("%02X:%02X ", i, ioread8(barp + i));
+	printk("\n");
+
+	devices = ioread32(barp + 0x0C);
+	pci_iounmap(pdev, barp);
+
+	if (devices & 0x10)
+		return 1;
+	return 0;
+}
 
 /**
  *	marvell_pre_reset	-	check for 40/80 pin
@@ -34,26 +69,10 @@
 {
 	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-	u32 devices;
-	void __iomem *barp;
-	int i;
 
-	/* Check if our port is enabled */
-
-	barp = pci_iomap(pdev, 5, 0x10);
-	if (barp == NULL)
-		return -ENOMEM;
-	printk("BAR5:");
-	for(i = 0; i <= 0x0F; i++)
-		printk("%02X:%02X ", i, ioread8(barp + i));
-	printk("\n");
-
-	devices = ioread32(barp + 0x0C);
-	pci_iounmap(pdev, barp);
-
-	if ((pdev->device == 0x6145) && (ap->port_no == 0) &&
-	    (!(devices & 0x10)))	/* PATA enable ? */
-		return -ENOENT;
+	if (pdev->device == 0x6145 && ap->port_no == 0 &&
+		!marvell_pata_active(pdev))	/* PATA enable ? */
+			return -ENOENT;
 
 	return ata_sff_prereset(link, deadline);
 }
@@ -128,6 +147,12 @@
 	if (pdev->device == 0x6101)
 		ppi[1] = &ata_dummy_port_info;
 
+#if defined(CONFIG_AHCI) || defined(CONFIG_AHCI_MODULE)
+	if (!marvell_pata_active(pdev)) {
+		printk(KERN_INFO DRV_NAME ": PATA port not active, deferring to AHCI driver.\n");
+		return -ENODEV;
+	}
+#endif
 	return ata_pci_sff_init_one(pdev, ppi, &marvell_sht, NULL);
 }
 
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index 720b864..e970b22 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -322,9 +322,6 @@
 	/* Try to acquire MMIO resources and fallback to PIO if
 	 * that fails
 	 */
-	rc = pcim_enable_device(pdev);
-	if (rc)
-		return rc;
 	rc = pcim_iomap_regions(pdev, 1 << SIL680_MMIO_BAR, DRV_NAME);
 	if (rc)
 		goto use_ioports;
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index 3ead02f..5032c32 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -96,6 +96,7 @@
 	PORT_SCR		= 0x20,
 
 	/* HOST_CTL bits */
+	HCTL_LEDEN		= (1 << 3),  /* enable LED operation */
 	HCTL_IRQOFF		= (1 << 8),  /* global IRQ off */
 	HCTL_FTHD0		= (1 << 10), /* fifo threshold 0 */
 	HCTL_FTHD1		= (1 << 11), /* fifo threshold 1*/
@@ -540,7 +541,7 @@
 	void __iomem *port_base = inic_port_base(ap);
 
 	/* fire up the ADMA engine */
-	writew(HCTL_FTHD0, port_base + HOST_CTL);
+	writew(HCTL_FTHD0 | HCTL_LEDEN, port_base + HOST_CTL);
 	writew(IDMA_CTL_GO, port_base + PORT_IDMA_CTL);
 	writeb(0, port_base + PORT_CPB_PTQFIFO);
 
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 13c1d2a..c815f8e 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -667,7 +667,8 @@
 	{ PCI_VDEVICE(MARVELL, 0x5041), chip_504x },
 	{ PCI_VDEVICE(MARVELL, 0x5080), chip_5080 },
 	{ PCI_VDEVICE(MARVELL, 0x5081), chip_508x },
-	/* RocketRAID 1740/174x have different identifiers */
+	/* RocketRAID 1720/174x have different identifiers */
+	{ PCI_VDEVICE(TTI, 0x1720), chip_6042 },
 	{ PCI_VDEVICE(TTI, 0x1740), chip_508x },
 	{ PCI_VDEVICE(TTI, 0x1742), chip_508x },
 
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 858f706..1e1f3f3 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -309,8 +309,6 @@
 static void nv_nf2_thaw(struct ata_port *ap);
 static void nv_ck804_freeze(struct ata_port *ap);
 static void nv_ck804_thaw(struct ata_port *ap);
-static int nv_hardreset(struct ata_link *link, unsigned int *class,
-			unsigned long deadline);
 static int nv_adma_slave_config(struct scsi_device *sdev);
 static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc);
 static void nv_adma_qc_prep(struct ata_queued_cmd *qc);
@@ -407,7 +405,7 @@
 
 static struct ata_port_operations nv_generic_ops = {
 	.inherits		= &ata_bmdma_port_ops,
-	.hardreset		= nv_hardreset,
+	.hardreset		= ATA_OP_NULL,
 	.scr_read		= nv_scr_read,
 	.scr_write		= nv_scr_write,
 };
@@ -1588,21 +1586,6 @@
 	ata_sff_thaw(ap);
 }
 
-static int nv_hardreset(struct ata_link *link, unsigned int *class,
-			unsigned long deadline)
-{
-	int rc;
-
-	/* SATA hardreset fails to retrieve proper device signature on
-	 * some controllers.  Request follow up SRST.  For more info,
-	 * see http://bugzilla.kernel.org/show_bug.cgi?id=3352
-	 */
-	rc = sata_sff_hardreset(link, class, deadline);
-	if (rc)
-		return rc;
-	return -EAGAIN;
-}
-
 static void nv_adma_error_handler(struct ata_port *ap)
 {
 	struct nv_adma_port_priv *pp = ap->private_data;
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c
index 5ca1d80..4eee533 100644
--- a/drivers/clocksource/acpi_pm.c
+++ b/drivers/clocksource/acpi_pm.c
@@ -21,6 +21,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/delay.h>
 #include <asm/io.h>
 
 /*
@@ -151,13 +152,13 @@
  */
 static int verify_pmtmr_rate(void)
 {
-	u32 value1, value2;
+	cycle_t value1, value2;
 	unsigned long count, delta;
 
 	mach_prepare_counter();
-	value1 = read_pmtmr();
+	value1 = clocksource_acpi_pm.read();
 	mach_countup(&count);
-	value2 = read_pmtmr();
+	value2 = clocksource_acpi_pm.read();
 	delta = (value2 - value1) & ACPI_PM_MASK;
 
 	/* Check that the PMTMR delta is within 5% of what we expect */
@@ -175,10 +176,13 @@
 #define verify_pmtmr_rate() (0)
 #endif
 
+/* Number of monotonicity checks to perform during initialization */
+#define ACPI_PM_MONOTONICITY_CHECKS 10
+
 static int __init init_acpi_pm_clocksource(void)
 {
-	u32 value1, value2;
-	unsigned int i;
+	cycle_t value1, value2;
+	unsigned int i, j, good = 0;
 
 	if (!pmtmr_ioport)
 		return -ENODEV;
@@ -187,24 +191,32 @@
 						clocksource_acpi_pm.shift);
 
 	/* "verify" this timing source: */
-	value1 = read_pmtmr();
-	for (i = 0; i < 10000; i++) {
-		value2 = read_pmtmr();
-		if (value2 == value1)
-			continue;
-		if (value2 > value1)
-			goto pm_good;
-		if ((value2 < value1) && ((value2) < 0xFFF))
-			goto pm_good;
-		printk(KERN_INFO "PM-Timer had inconsistent results:"
-			" 0x%#x, 0x%#x - aborting.\n", value1, value2);
-		return -EINVAL;
+	for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
+		value1 = clocksource_acpi_pm.read();
+		for (i = 0; i < 10000; i++) {
+			value2 = clocksource_acpi_pm.read();
+			if (value2 == value1)
+				continue;
+			if (value2 > value1)
+				good++;
+				break;
+			if ((value2 < value1) && ((value2) < 0xFFF))
+				good++;
+				break;
+			printk(KERN_INFO "PM-Timer had inconsistent results:"
+			       " 0x%#llx, 0x%#llx - aborting.\n",
+			       value1, value2);
+			return -EINVAL;
+		}
+		udelay(300 * i);
 	}
-	printk(KERN_INFO "PM-Timer had no reasonable result:"
-			" 0x%#x - aborting.\n", value1);
-	return -ENODEV;
 
-pm_good:
+	if (good != ACPI_PM_MONOTONICITY_CHECKS) {
+		printk(KERN_INFO "PM-Timer failed consistency check "
+		       " (0x%#llx) - aborting.\n", value1);
+		return -ENODEV;
+	}
+
 	if (verify_pmtmr_rate() != 0)
 		return -ENODEV;
 
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index ee827a7..b6ad3ac 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1157,6 +1157,8 @@
 	edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
 
 	memcpy(req->giv, ctx->iv, crypto_aead_ivsize(authenc));
+	/* avoid consecutive packets going out with same IV */
+	*(__be64 *)req->giv ^= cpu_to_be64(req->seq);
 
 	return ipsec_esp(edesc, areq, req->giv, req->seq,
 			 ipsec_esp_encrypt_done);
@@ -1449,6 +1451,8 @@
 
 	priv->ofdev = ofdev;
 
+	INIT_LIST_HEAD(&priv->alg_list);
+
 	tasklet_init(&priv->done_task, talitos_done, (unsigned long)dev);
 	tasklet_init(&priv->error_task, talitos_error, (unsigned long)dev);
 
@@ -1575,8 +1579,6 @@
 	}
 
 	/* register crypto algorithms the device supports */
-	INIT_LIST_HEAD(&priv->alg_list);
-
 	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
 		if (hw_supports(dev, driver_algs[i].desc_hdr_template)) {
 			struct talitos_crypto_alg *t_alg;
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index d402e8d..3309e86 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -540,6 +540,15 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called lm93.
 
+config SENSORS_MAX1111
+	tristate "Maxim MAX1111 Multichannel, Serial 8-bit ADC chip"
+	depends on SPI_MASTER
+	help
+	  Say y here to support Maxim's MAX1111 ADC chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called max1111.
+
 config SENSORS_MAX1619
 	tristate "Maxim MAX1619 sensor chip"
 	depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 950134a..6babc80 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -59,6 +59,7 @@
 obj-$(CONFIG_SENSORS_LM90)	+= lm90.o
 obj-$(CONFIG_SENSORS_LM92)	+= lm92.o
 obj-$(CONFIG_SENSORS_LM93)	+= lm93.o
+obj-$(CONFIG_SENSORS_MAX1111)	+= max1111.o
 obj-$(CONFIG_SENSORS_MAX1619)	+= max1619.o
 obj-$(CONFIG_SENSORS_MAX6650)	+= max6650.o
 obj-$(CONFIG_SENSORS_PC87360)	+= pc87360.o
diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c
new file mode 100644
index 0000000..bfaa665
--- /dev/null
+++ b/drivers/hwmon/max1111.c
@@ -0,0 +1,244 @@
+/*
+ * max1111.c - +2.7V, Low-Power, Multichannel, Serial 8-bit ADCs
+ *
+ * Based on arch/arm/mach-pxa/corgi_ssp.c
+ *
+ * Copyright (C) 2004-2005 Richard Purdie
+ *
+ * Copyright (C) 2008 Marvell International Ltd.
+ * 	Eric Miao <eric.miao@marvell.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/spi/spi.h>
+
+#define MAX1111_TX_BUF_SIZE	1
+#define MAX1111_RX_BUF_SIZE	2
+
+/* MAX1111 Commands */
+#define MAX1111_CTRL_PD0      (1u << 0)
+#define MAX1111_CTRL_PD1      (1u << 1)
+#define MAX1111_CTRL_SGL      (1u << 2)
+#define MAX1111_CTRL_UNI      (1u << 3)
+#define MAX1111_CTRL_SEL_SH   (5)	/* NOTE: bit 4 is ignored */
+#define MAX1111_CTRL_STR      (1u << 7)
+
+struct max1111_data {
+	struct spi_device	*spi;
+	struct device		*hwmon_dev;
+	struct spi_message	msg;
+	struct spi_transfer	xfer[2];
+	uint8_t *tx_buf;
+	uint8_t *rx_buf;
+};
+
+static int max1111_read(struct device *dev, int channel)
+{
+	struct max1111_data *data = dev_get_drvdata(dev);
+	uint8_t v1, v2;
+	int err;
+
+	data->tx_buf[0] = (channel << MAX1111_CTRL_SEL_SH) |
+		MAX1111_CTRL_PD0 | MAX1111_CTRL_PD1 |
+		MAX1111_CTRL_SGL | MAX1111_CTRL_UNI | MAX1111_CTRL_STR;
+
+	err = spi_sync(data->spi, &data->msg);
+	if (err < 0) {
+		dev_err(dev, "spi_sync failed with %d\n", err);
+		return err;
+	}
+
+	v1 = data->rx_buf[0];
+	v2 = data->rx_buf[1];
+
+	if ((v1 & 0xc0) || (v2 & 0x3f))
+		return -EINVAL;
+
+	return (v1 << 2) | (v2 >> 6);
+}
+
+#ifdef CONFIG_SHARPSL_PM
+static struct max1111_data *the_max1111;
+
+int max1111_read_channel(int channel)
+{
+	return max1111_read(&the_max1111->spi->dev, channel);
+}
+EXPORT_SYMBOL(max1111_read_channel);
+#endif
+
+/*
+ * NOTE: SPI devices do not have a default 'name' attribute, which is
+ * likely to be used by hwmon applications to distinguish between
+ * different devices, explicitly add a name attribute here.
+ */
+static ssize_t show_name(struct device *dev,
+			 struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "max1111\n");
+}
+
+static ssize_t show_adc(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	int channel = to_sensor_dev_attr(attr)->index;
+	int ret;
+
+	ret = max1111_read(dev, channel);
+	if (ret < 0)
+		return ret;
+
+	return sprintf(buf, "%d\n", ret);
+}
+
+#define MAX1111_ADC_ATTR(_id)		\
+	SENSOR_DEVICE_ATTR(adc##_id##_in, S_IRUGO, show_adc, NULL, _id)
+
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+static MAX1111_ADC_ATTR(0);
+static MAX1111_ADC_ATTR(1);
+static MAX1111_ADC_ATTR(2);
+static MAX1111_ADC_ATTR(3);
+
+static struct attribute *max1111_attributes[] = {
+	&dev_attr_name.attr,
+	&sensor_dev_attr_adc0_in.dev_attr.attr,
+	&sensor_dev_attr_adc1_in.dev_attr.attr,
+	&sensor_dev_attr_adc2_in.dev_attr.attr,
+	&sensor_dev_attr_adc3_in.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group max1111_attr_group = {
+	.attrs	= max1111_attributes,
+};
+
+static int setup_transfer(struct max1111_data *data)
+{
+	struct spi_message *m;
+	struct spi_transfer *x;
+
+	data->tx_buf = kmalloc(MAX1111_TX_BUF_SIZE, GFP_KERNEL);
+	if (!data->tx_buf)
+		return -ENOMEM;
+
+	data->rx_buf = kmalloc(MAX1111_RX_BUF_SIZE, GFP_KERNEL);
+	if (!data->rx_buf) {
+		kfree(data->tx_buf);
+		return -ENOMEM;
+	}
+
+	m = &data->msg;
+	x = &data->xfer[0];
+
+	spi_message_init(m);
+
+	x->tx_buf = &data->tx_buf[0];
+	x->len = 1;
+	spi_message_add_tail(x, m);
+
+	x++;
+	x->rx_buf = &data->rx_buf[0];
+	x->len = 2;
+	spi_message_add_tail(x, m);
+
+	return 0;
+}
+
+static int __devinit max1111_probe(struct spi_device *spi)
+{
+	struct max1111_data *data;
+	int err;
+
+	spi->bits_per_word = 8;
+	spi->mode = SPI_MODE_0;
+	err = spi_setup(spi);
+	if (err < 0)
+		return err;
+
+	data = kzalloc(sizeof(struct max1111_data), GFP_KERNEL);
+	if (data == NULL) {
+		dev_err(&spi->dev, "failed to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	err = setup_transfer(data);
+	if (err)
+		goto err_free_data;
+
+	data->spi = spi;
+	spi_set_drvdata(spi, data);
+
+	err = sysfs_create_group(&spi->dev.kobj, &max1111_attr_group);
+	if (err) {
+		dev_err(&spi->dev, "failed to create attribute group\n");
+		goto err_free_all;
+	}
+
+	data->hwmon_dev = hwmon_device_register(&spi->dev);
+	if (IS_ERR(data->hwmon_dev)) {
+		dev_err(&spi->dev, "failed to create hwmon device\n");
+		err = PTR_ERR(data->hwmon_dev);
+		goto err_remove;
+	}
+
+#ifdef CONFIG_SHARPSL_PM
+	the_max1111 = data;
+#endif
+	return 0;
+
+err_remove:
+	sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group);
+err_free_all:
+	kfree(data->rx_buf);
+	kfree(data->tx_buf);
+err_free_data:
+	kfree(data);
+	return err;
+}
+
+static int __devexit max1111_remove(struct spi_device *spi)
+{
+	struct max1111_data *data = spi_get_drvdata(spi);
+
+	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group);
+	kfree(data->rx_buf);
+	kfree(data->tx_buf);
+	kfree(data);
+	return 0;
+}
+
+static struct spi_driver max1111_driver = {
+	.driver		= {
+		.name	= "max1111",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= max1111_probe,
+	.remove		= __devexit_p(max1111_remove),
+};
+
+static int __init max1111_init(void)
+{
+	return spi_register_driver(&max1111_driver);
+}
+module_init(max1111_init);
+
+static void __exit max1111_exit(void)
+{
+	spi_unregister_driver(&max1111_driver);
+}
+module_exit(max1111_exit);
+
+MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
+MODULE_DESCRIPTION("MAX1111 ADC Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 44d8384..906f9b9 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -38,7 +38,44 @@
 #include <asm/irq.h>
 #include <asm/io.h>
 #include <mach/i2c.h>
-#include <mach/pxa-regs.h>
+
+/*
+ * I2C registers and bit definitions
+ */
+#define IBMR		(0x00)
+#define IDBR		(0x08)
+#define ICR		(0x10)
+#define ISR		(0x18)
+#define ISAR		(0x20)
+
+#define ICR_START	(1 << 0)	   /* start bit */
+#define ICR_STOP	(1 << 1)	   /* stop bit */
+#define ICR_ACKNAK	(1 << 2)	   /* send ACK(0) or NAK(1) */
+#define ICR_TB		(1 << 3)	   /* transfer byte bit */
+#define ICR_MA		(1 << 4)	   /* master abort */
+#define ICR_SCLE	(1 << 5)	   /* master clock enable */
+#define ICR_IUE		(1 << 6)	   /* unit enable */
+#define ICR_GCD		(1 << 7)	   /* general call disable */
+#define ICR_ITEIE	(1 << 8)	   /* enable tx interrupts */
+#define ICR_IRFIE	(1 << 9)	   /* enable rx interrupts */
+#define ICR_BEIE	(1 << 10)	   /* enable bus error ints */
+#define ICR_SSDIE	(1 << 11)	   /* slave STOP detected int enable */
+#define ICR_ALDIE	(1 << 12)	   /* enable arbitration interrupt */
+#define ICR_SADIE	(1 << 13)	   /* slave address detected int enable */
+#define ICR_UR		(1 << 14)	   /* unit reset */
+#define ICR_FM		(1 << 15)	   /* fast mode */
+
+#define ISR_RWM		(1 << 0)	   /* read/write mode */
+#define ISR_ACKNAK	(1 << 1)	   /* ack/nak status */
+#define ISR_UB		(1 << 2)	   /* unit busy */
+#define ISR_IBB		(1 << 3)	   /* bus busy */
+#define ISR_SSD		(1 << 4)	   /* slave stop detected */
+#define ISR_ALD		(1 << 5)	   /* arbitration loss detected */
+#define ISR_ITE		(1 << 6)	   /* tx buffer empty */
+#define ISR_IRF		(1 << 7)	   /* rx buffer full */
+#define ISR_GCAD	(1 << 8)	   /* general call address detected */
+#define ISR_SAD		(1 << 9)	   /* slave address detected */
+#define ISR_BED		(1 << 10)	   /* bus error no ACK/NAK */
 
 struct pxa_i2c {
 	spinlock_t		lock;
@@ -60,19 +97,21 @@
 	u32			icrlog[32];
 
 	void __iomem		*reg_base;
+	unsigned int		reg_shift;
 
 	unsigned long		iobase;
 	unsigned long		iosize;
 
 	int			irq;
-	int			use_pio;
+	unsigned int		use_pio :1;
+	unsigned int		fast_mode :1;
 };
 
-#define _IBMR(i2c)	((i2c)->reg_base + 0)
-#define _IDBR(i2c)	((i2c)->reg_base + 8)
-#define _ICR(i2c)	((i2c)->reg_base + 0x10)
-#define _ISR(i2c)	((i2c)->reg_base + 0x18)
-#define _ISAR(i2c)	((i2c)->reg_base + 0x20)
+#define _IBMR(i2c)	((i2c)->reg_base + (0x0 << (i2c)->reg_shift))
+#define _IDBR(i2c)	((i2c)->reg_base + (0x4 << (i2c)->reg_shift))
+#define _ICR(i2c)	((i2c)->reg_base + (0x8 << (i2c)->reg_shift))
+#define _ISR(i2c)	((i2c)->reg_base + (0xc << (i2c)->reg_shift))
+#define _ISAR(i2c)	((i2c)->reg_base + (0x10 << (i2c)->reg_shift))
 
 /*
  * I2C Slave mode address
@@ -188,14 +227,14 @@
 
 static void i2c_pxa_abort(struct pxa_i2c *i2c)
 {
-	unsigned long timeout = jiffies + HZ/4;
+	int i = 250;
 
 	if (i2c_pxa_is_slavemode(i2c)) {
 		dev_dbg(&i2c->adap.dev, "%s: called in slave mode\n", __func__);
 		return;
 	}
 
-	while (time_before(jiffies, timeout) && (readl(_IBMR(i2c)) & 0x1) == 0) {
+	while ((i > 0) && (readl(_IBMR(i2c)) & 0x1) == 0) {
 		unsigned long icr = readl(_ICR(i2c));
 
 		icr &= ~ICR_START;
@@ -205,7 +244,8 @@
 
 		show_state(i2c);
 
-		msleep(1);
+		mdelay(1);
+		i --;
 	}
 
 	writel(readl(_ICR(i2c)) & ~(ICR_MA | ICR_START | ICR_STOP),
@@ -364,7 +404,7 @@
 	writel(i2c->slave_addr, _ISAR(i2c));
 
 	/* set control register values */
-	writel(I2C_ICR_INIT, _ICR(i2c));
+	writel(I2C_ICR_INIT | (i2c->fast_mode ? ICR_FM : 0), _ICR(i2c));
 
 #ifdef CONFIG_I2C_PXA_SLAVE
 	dev_info(&i2c->adap.dev, "Enabling slave mode\n");
@@ -907,12 +947,6 @@
 	struct pxa_i2c *i2c = adap->algo_data;
 	int ret, i;
 
-	/* If the I2C controller is disabled we need to reset it (probably due
- 	   to a suspend/resume destroying state). We do this here as we can then
- 	   avoid worrying about resuming the controller before its users. */
-	if (!(readl(_ICR(i2c)) & ICR_IUE))
-		i2c_pxa_reset(i2c);
-
 	for (i = adap->retries; i >= 0; i--) {
 		ret = i2c_pxa_do_xfer(i2c, msgs, num);
 		if (ret != I2C_RETRY)
@@ -993,6 +1027,7 @@
 		ret = -EIO;
 		goto eremap;
 	}
+	i2c->reg_shift = (cpu_is_pxa3xx() && (dev->id == 1)) ? 0 : 1;
 
 	i2c->iobase = res->start;
 	i2c->iosize = res_len(res);
@@ -1013,6 +1048,7 @@
 	if (plat) {
 		i2c->adap.class = plat->class;
 		i2c->use_pio = plat->use_pio;
+		i2c->fast_mode = plat->fast_mode;
 	}
 
 	if (i2c->use_pio) {
@@ -1082,9 +1118,33 @@
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int i2c_pxa_suspend_late(struct platform_device *dev, pm_message_t state)
+{
+	struct pxa_i2c *i2c = platform_get_drvdata(dev);
+	clk_disable(i2c->clk);
+	return 0;
+}
+
+static int i2c_pxa_resume_early(struct platform_device *dev)
+{
+	struct pxa_i2c *i2c = platform_get_drvdata(dev);
+
+	clk_enable(i2c->clk);
+	i2c_pxa_reset(i2c);
+
+	return 0;
+}
+#else
+#define i2c_pxa_suspend_late NULL
+#define i2c_pxa_resume_early NULL
+#endif
+
 static struct platform_driver i2c_pxa_driver = {
 	.probe		= i2c_pxa_probe,
 	.remove		= __exit_p(i2c_pxa_remove),
+	.suspend_late	= i2c_pxa_suspend_late,
+	.resume_early	= i2c_pxa_resume_early,
 	.driver		= {
 		.name	= "pxa2xx-i2c",
 		.owner	= THIS_MODULE,
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index 840e634f..640cbb2 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -31,13 +31,84 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 
+/* Transmit operation:                                                      */
+/*                                                                          */
+/* 0 byte transmit                                                          */
+/* BUS:     S     A8     ACK   P                                            */
+/* IRQ:       DTE   WAIT                                                    */
+/* ICIC:                                                                    */
+/* ICCR: 0x94 0x90                                                          */
+/* ICDR:      A8                                                            */
+/*                                                                          */
+/* 1 byte transmit                                                          */
+/* BUS:     S     A8     ACK   D8(1)   ACK   P                              */
+/* IRQ:       DTE   WAIT         WAIT                                       */
+/* ICIC:      -DTE                                                          */
+/* ICCR: 0x94       0x90                                                    */
+/* ICDR:      A8    D8(1)                                                   */
+/*                                                                          */
+/* 2 byte transmit                                                          */
+/* BUS:     S     A8     ACK   D8(1)   ACK   D8(2)   ACK   P                */
+/* IRQ:       DTE   WAIT         WAIT          WAIT                         */
+/* ICIC:      -DTE                                                          */
+/* ICCR: 0x94                    0x90                                       */
+/* ICDR:      A8    D8(1)        D8(2)                                      */
+/*                                                                          */
+/* 3 bytes or more, +---------+ gets repeated                               */
+/*                                                                          */
+/*                                                                          */
+/* Receive operation:                                                       */
+/*                                                                          */
+/* 0 byte receive - not supported since slave may hold SDA low              */
+/*                                                                          */
+/* 1 byte receive       [TX] | [RX]                                         */
+/* BUS:     S     A8     ACK | D8(1)   ACK   P                              */
+/* IRQ:       DTE   WAIT     |   WAIT     DTE                               */
+/* ICIC:      -DTE           |   +DTE                                       */
+/* ICCR: 0x94       0x81     |   0xc0                                       */
+/* ICDR:      A8             |            D8(1)                             */
+/*                                                                          */
+/* 2 byte receive        [TX]| [RX]                                         */
+/* BUS:     S     A8     ACK | D8(1)   ACK   D8(2)   ACK   P                */
+/* IRQ:       DTE   WAIT     |   WAIT          WAIT     DTE                 */
+/* ICIC:      -DTE           |                 +DTE                         */
+/* ICCR: 0x94       0x81     |                 0xc0                         */
+/* ICDR:      A8             |                 D8(1)    D8(2)               */
+/*                                                                          */
+/* 3 byte receive       [TX] | [RX]                                         */
+/* BUS:     S     A8     ACK | D8(1)   ACK   D8(2)   ACK   D8(3)   ACK    P */
+/* IRQ:       DTE   WAIT     |   WAIT          WAIT         WAIT      DTE   */
+/* ICIC:      -DTE           |                              +DTE            */
+/* ICCR: 0x94       0x81     |                              0xc0            */
+/* ICDR:      A8             |                 D8(1)        D8(2)     D8(3) */
+/*                                                                          */
+/* 4 bytes or more, this part is repeated    +---------+                    */
+/*                                                                          */
+/*                                                                          */
+/* Interrupt order and BUSY flag                                            */
+/*     ___                                                 _                */
+/* SDA ___\___XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAAAAAAAAA___/                 */
+/* SCL      \_/1\_/2\_/3\_/4\_/5\_/6\_/7\_/8\___/9\_____/                   */
+/*                                                                          */
+/*        S   D7  D6  D5  D4  D3  D2  D1  D0              P                 */
+/*                                           ___                            */
+/* WAIT IRQ ________________________________/   \___________                */
+/* TACK IRQ ____________________________________/   \_______                */
+/* DTE  IRQ __________________________________________/   \_                */
+/* AL   IRQ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                */
+/*         _______________________________________________                  */
+/* BUSY __/                                               \_                */
+/*                                                                          */
+
 enum sh_mobile_i2c_op {
 	OP_START = 0,
-	OP_TX_ONLY,
+	OP_TX_FIRST,
+	OP_TX,
 	OP_TX_STOP,
 	OP_TX_TO_RX,
-	OP_RX_ONLY,
+	OP_RX,
 	OP_RX_STOP,
+	OP_RX_STOP_DATA,
 };
 
 struct sh_mobile_i2c_data {
@@ -127,25 +198,34 @@
 	spin_lock_irqsave(&pd->lock, flags);
 
 	switch (op) {
-	case OP_START:
+	case OP_START: /* issue start and trigger DTE interrupt */
 		iowrite8(0x94, ICCR(pd));
 		break;
-	case OP_TX_ONLY:
+	case OP_TX_FIRST: /* disable DTE interrupt and write data */
+		iowrite8(ICIC_WAITE | ICIC_ALE | ICIC_TACKE, ICIC(pd));
 		iowrite8(data, ICDR(pd));
 		break;
-	case OP_TX_STOP:
+	case OP_TX: /* write data */
+		iowrite8(data, ICDR(pd));
+		break;
+	case OP_TX_STOP: /* write data and issue a stop afterwards */
 		iowrite8(data, ICDR(pd));
 		iowrite8(0x90, ICCR(pd));
-		iowrite8(ICIC_ALE | ICIC_TACKE, ICIC(pd));
 		break;
-	case OP_TX_TO_RX:
-		iowrite8(data, ICDR(pd));
+	case OP_TX_TO_RX: /* select read mode */
 		iowrite8(0x81, ICCR(pd));
 		break;
-	case OP_RX_ONLY:
+	case OP_RX: /* just read data */
 		ret = ioread8(ICDR(pd));
 		break;
-	case OP_RX_STOP:
+	case OP_RX_STOP: /* enable DTE interrupt, issue stop */
+		iowrite8(ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE,
+			 ICIC(pd));
+		iowrite8(0xc0, ICCR(pd));
+		break;
+	case OP_RX_STOP_DATA: /* enable DTE interrupt, read data, issue stop */
+		iowrite8(ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE,
+			 ICIC(pd));
 		ret = ioread8(ICDR(pd));
 		iowrite8(0xc0, ICCR(pd));
 		break;
@@ -157,58 +237,120 @@
 	return ret;
 }
 
+static int sh_mobile_i2c_is_first_byte(struct sh_mobile_i2c_data *pd)
+{
+	if (pd->pos == -1)
+		return 1;
+
+	return 0;
+}
+
+static int sh_mobile_i2c_is_last_byte(struct sh_mobile_i2c_data *pd)
+{
+	if (pd->pos == (pd->msg->len - 1))
+		return 1;
+
+	return 0;
+}
+
+static void sh_mobile_i2c_get_data(struct sh_mobile_i2c_data *pd,
+				   unsigned char *buf)
+{
+	switch (pd->pos) {
+	case -1:
+		*buf = (pd->msg->addr & 0x7f) << 1;
+		*buf |= (pd->msg->flags & I2C_M_RD) ? 1 : 0;
+		break;
+	default:
+		*buf = pd->msg->buf[pd->pos];
+	}
+}
+
+static int sh_mobile_i2c_isr_tx(struct sh_mobile_i2c_data *pd)
+{
+	unsigned char data;
+
+	if (pd->pos == pd->msg->len)
+		return 1;
+
+	sh_mobile_i2c_get_data(pd, &data);
+
+	if (sh_mobile_i2c_is_last_byte(pd))
+		i2c_op(pd, OP_TX_STOP, data);
+	else if (sh_mobile_i2c_is_first_byte(pd))
+		i2c_op(pd, OP_TX_FIRST, data);
+	else
+		i2c_op(pd, OP_TX, data);
+
+	pd->pos++;
+	return 0;
+}
+
+static int sh_mobile_i2c_isr_rx(struct sh_mobile_i2c_data *pd)
+{
+	unsigned char data;
+	int real_pos;
+
+	do {
+		if (pd->pos <= -1) {
+			sh_mobile_i2c_get_data(pd, &data);
+
+			if (sh_mobile_i2c_is_first_byte(pd))
+				i2c_op(pd, OP_TX_FIRST, data);
+			else
+				i2c_op(pd, OP_TX, data);
+			break;
+		}
+
+		if (pd->pos == 0) {
+			i2c_op(pd, OP_TX_TO_RX, 0);
+			break;
+		}
+
+		real_pos = pd->pos - 2;
+
+		if (pd->pos == pd->msg->len) {
+			if (real_pos < 0) {
+				i2c_op(pd, OP_RX_STOP, 0);
+				break;
+			}
+			data = i2c_op(pd, OP_RX_STOP_DATA, 0);
+		} else
+			data = i2c_op(pd, OP_RX, 0);
+
+		pd->msg->buf[real_pos] = data;
+	} while (0);
+
+	pd->pos++;
+	return pd->pos == (pd->msg->len + 2);
+}
+
 static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
 {
 	struct platform_device *dev = dev_id;
 	struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev);
-	struct i2c_msg *msg = pd->msg;
-	unsigned char data, sr;
-	int wakeup = 0;
+	unsigned char sr;
+	int wakeup;
 
 	sr = ioread8(ICSR(pd));
-	pd->sr |= sr;
+	pd->sr |= sr; /* remember state */
 
 	dev_dbg(pd->dev, "i2c_isr 0x%02x 0x%02x %s %d %d!\n", sr, pd->sr,
-	       (msg->flags & I2C_M_RD) ? "read" : "write",
-	       pd->pos, msg->len);
+	       (pd->msg->flags & I2C_M_RD) ? "read" : "write",
+	       pd->pos, pd->msg->len);
 
 	if (sr & (ICSR_AL | ICSR_TACK)) {
-		iowrite8(0, ICIC(pd)); /* disable interrupts */
-		wakeup = 1;
-		goto do_wakeup;
-	}
+		/* don't interrupt transaction - continue to issue stop */
+		iowrite8(sr & ~(ICSR_AL | ICSR_TACK), ICSR(pd));
+		wakeup = 0;
+	} else if (pd->msg->flags & I2C_M_RD)
+		wakeup = sh_mobile_i2c_isr_rx(pd);
+	else
+		wakeup = sh_mobile_i2c_isr_tx(pd);
 
-	if (pd->pos == msg->len) {
-		i2c_op(pd, OP_RX_ONLY, 0);
-		wakeup = 1;
-		goto do_wakeup;
-	}
+	if (sr & ICSR_WAIT) /* TODO: add delay here to support slow acks */
+		iowrite8(sr & ~ICSR_WAIT, ICSR(pd));
 
-	if (pd->pos == -1) {
-		data = (msg->addr & 0x7f) << 1;
-		data |= (msg->flags & I2C_M_RD) ? 1 : 0;
-	} else
-		data = msg->buf[pd->pos];
-
-	if ((pd->pos == -1) || !(msg->flags & I2C_M_RD)) {
-		if (msg->flags & I2C_M_RD)
-			i2c_op(pd, OP_TX_TO_RX, data);
-		else if (pd->pos == (msg->len - 1)) {
-			i2c_op(pd, OP_TX_STOP, data);
-			wakeup = 1;
-		} else
-			i2c_op(pd, OP_TX_ONLY, data);
-	} else {
-		if (pd->pos == (msg->len - 1))
-			data = i2c_op(pd, OP_RX_STOP, 0);
-		else
-			data = i2c_op(pd, OP_RX_ONLY, 0);
-
-		msg->buf[pd->pos] = data;
-	}
-	pd->pos++;
-
- do_wakeup:
 	if (wakeup) {
 		pd->sr |= SW_DONE;
 		wake_up(&pd->wait);
@@ -219,6 +361,11 @@
 
 static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg)
 {
+	if (usr_msg->len == 0 && (usr_msg->flags & I2C_M_RD)) {
+		dev_err(pd->dev, "Unsupported zero length i2c read\n");
+		return -EIO;
+	}
+
 	/* Initialize channel registers */
 	iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd));
 
@@ -233,9 +380,8 @@
 	pd->pos = -1;
 	pd->sr = 0;
 
-	/* Enable all interrupts except wait */
-	iowrite8(ioread8(ICIC(pd)) | ICIC_ALE | ICIC_TACKE | ICIC_DTEE,
-		 ICIC(pd));
+	/* Enable all interrupts to begin with */
+	iowrite8(ICIC_WAITE | ICIC_ALE | ICIC_TACKE | ICIC_DTEE, ICIC(pd));
 	return 0;
 }
 
@@ -268,25 +414,18 @@
 		if (!k)
 			dev_err(pd->dev, "Transfer request timed out\n");
 
-		retry_count = 10;
+		retry_count = 1000;
 again:
 		val = ioread8(ICSR(pd));
 
 		dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr);
 
-		if ((val | pd->sr) & (ICSR_TACK | ICSR_AL)) {
-			err = -EIO;
-			break;
-		}
-
 		/* the interrupt handler may wake us up before the
 		 * transfer is finished, so poll the hardware
 		 * until we're done.
 		 */
-
-		if (!(!(val & ICSR_BUSY) && (val & ICSR_SCLM) &&
-		      (val & ICSR_SDAM))) {
-			msleep(1);
+		if (val & ICSR_BUSY) {
+			udelay(10);
 			if (retry_count--)
 				goto again;
 
@@ -294,6 +433,12 @@
 			dev_err(pd->dev, "Polling timed out\n");
 			break;
 		}
+
+		/* handle missing acknowledge and arbitration lost */
+		if ((val | pd->sr) & (ICSR_TACK | ICSR_AL)) {
+			err = -EIO;
+			break;
+		}
 	}
 
 	deactivate_ch(pd);
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index f148999..49a8c58 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -1933,7 +1933,6 @@
 
 	ide_proc_unregister_driver(drive, info->driver);
 
-	blk_unregister_filter(info->disk);
 	del_gendisk(info->disk);
 
 	ide_cd_put(info);
@@ -2159,7 +2158,6 @@
 	g->fops = &idecd_ops;
 	g->flags |= GENHD_FL_REMOVABLE;
 	add_disk(g);
-	blk_register_filter(g);
 	return 0;
 
 out_free_cd:
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index eb107ee..c37ab17 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -613,6 +613,14 @@
 	return 0;
 }
 
+static struct hpt_info *hpt3xx_get_info(struct device *dev)
+{
+	struct ide_host *host	= dev_get_drvdata(dev);
+	struct hpt_info *info	= (struct hpt_info *)host->host_priv;
+
+	return dev == host->dev[1] ? info + 1 : info;
+}
+
 /*
  * The Marvell bridge chips used on the HighPoint SATA cards do not seem
  * to support the UltraDMA modes 1, 2, and 3 as well as any MWDMA modes...
@@ -621,9 +629,7 @@
 static u8 hpt3xx_udma_filter(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
-	struct pci_dev *dev	= to_pci_dev(hwif->dev);
-	struct ide_host *host	= pci_get_drvdata(dev);
-	struct hpt_info *info	= host->host_priv + (hwif->dev == host->dev[1]);
+	struct hpt_info *info	= hpt3xx_get_info(hwif->dev);
 	u8 mask 		= hwif->ultra_mask;
 
 	switch (info->chip_type) {
@@ -662,9 +668,7 @@
 static u8 hpt3xx_mdma_filter(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
-	struct pci_dev *dev	= to_pci_dev(hwif->dev);
-	struct ide_host *host	= pci_get_drvdata(dev);
-	struct hpt_info *info	= host->host_priv + (hwif->dev == host->dev[1]);
+	struct hpt_info *info	= hpt3xx_get_info(hwif->dev);
 
 	switch (info->chip_type) {
 	case HPT372 :
@@ -700,8 +704,7 @@
 {
 	ide_hwif_t *hwif	= drive->hwif;
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
-	struct ide_host *host	= pci_get_drvdata(dev);
-	struct hpt_info *info	= host->host_priv + (hwif->dev == host->dev[1]);
+	struct hpt_info *info	= hpt3xx_get_info(hwif->dev);
 	struct hpt_timings *t	= info->timings;
 	u8  itr_addr		= 0x40 + (drive->dn * 4);
 	u32 old_itr		= 0;
@@ -744,8 +747,7 @@
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct pci_dev	*dev	= to_pci_dev(hwif->dev);
-	struct ide_host *host	= pci_get_drvdata(dev);
-	struct hpt_info *info	= host->host_priv + (hwif->dev == host->dev[1]);
+	struct hpt_info *info	= hpt3xx_get_info(hwif->dev);
 
 	if (drive->quirk_list) {
 		if (info->chip_type >= HPT370) {
@@ -973,8 +975,7 @@
 static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev)
 {
 	unsigned long io_base	= pci_resource_start(dev, 4);
-	struct ide_host *host	= pci_get_drvdata(dev);
-	struct hpt_info *info	= host->host_priv + (&dev->dev == host->dev[1]);
+	struct hpt_info *info	= hpt3xx_get_info(&dev->dev);
 	const char *name	= DRV_NAME;
 	u8 pci_clk,  dpll_clk	= 0;	/* PCI and DPLL clock in MHz */
 	u8 chip_type;
@@ -1217,8 +1218,7 @@
 static u8 hpt3xx_cable_detect(ide_hwif_t *hwif)
 {
 	struct pci_dev	*dev	= to_pci_dev(hwif->dev);
-	struct ide_host *host	= pci_get_drvdata(dev);
-	struct hpt_info *info	= host->host_priv + (hwif->dev == host->dev[1]);
+	struct hpt_info *info	= hpt3xx_get_info(hwif->dev);
 	u8 chip_type		= info->chip_type;
 	u8 scr1 = 0, ata66	= hwif->channel ? 0x01 : 0x02;
 
@@ -1262,8 +1262,7 @@
 static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
 {
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
-	struct ide_host *host	= pci_get_drvdata(dev);
-	struct hpt_info *info	= host->host_priv + (hwif->dev == host->dev[1]);
+	struct hpt_info *info	= hpt3xx_get_info(hwif->dev);
 	int serialize		= HPT_SERIALIZE_IO;
 	u8  chip_type		= info->chip_type;
 	u8  new_mcr, old_mcr	= 0;
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c
index 134e67b..c8ed065 100644
--- a/drivers/input/keyboard/corgikbd.c
+++ b/drivers/input/keyboard/corgikbd.c
@@ -80,9 +80,9 @@
 #define KB_ACTIVATE_DELAY	10
 
 /* Helper functions for reading the keyboard matrix
- * Note: We should really be using pxa_gpio_mode to alter GPDR but it
- *       requires a function call per GPIO bit which is excessive
- *       when we need to access 12 bits at once multiple times.
+ * Note: We should really be using the generic gpio functions to alter
+ *       GPDR but it requires a function call per GPIO bit which is
+ *       excessive when we need to access 12 bits at once, multiple times.
  * These functions must be called within local_irq_save()/local_irq_restore()
  * or similar.
  */
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
index de67b8e..c48b76a 100644
--- a/drivers/input/keyboard/spitzkbd.c
+++ b/drivers/input/keyboard/spitzkbd.c
@@ -101,9 +101,9 @@
 #define KB_ACTIVATE_DELAY	10
 
 /* Helper functions for reading the keyboard matrix
- * Note: We should really be using pxa_gpio_mode to alter GPDR but it
- *       requires a function call per GPIO bit which is excessive
- *       when we need to access 11 bits at once, multiple times.
+ * Note: We should really be using the generic gpio functions to alter
+ *       GPDR but it requires a function call per GPIO bit which is
+ *       excessive when we need to access 11 bits at once, multiple times.
  * These functions must be called within local_irq_save()/local_irq_restore()
  * or similar.
  */
diff --git a/drivers/input/keyboard/tosakbd.c b/drivers/input/keyboard/tosakbd.c
index 44cb50a..677276b 100644
--- a/drivers/input/keyboard/tosakbd.c
+++ b/drivers/input/keyboard/tosakbd.c
@@ -59,9 +59,9 @@
 
 
 /* Helper functions for reading the keyboard matrix
- * Note: We should really be using pxa_gpio_mode to alter GPDR but it
- *       requires a function call per GPIO bit which is excessive
- *       when we need to access 12 bits at once, multiple times.
+ * Note: We should really be using the generic gpio functions to alter
+ *       GPDR but it requires a function call per GPIO bit which is
+ *       excessive when we need to access 12 bits at once, multiple times.
  * These functions must be called within local_irq_save()/local_irq_restore()
  * or similar.
  */
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
index 2ec921b..18f4d7f 100644
--- a/drivers/input/mouse/bcm5974.c
+++ b/drivers/input/mouse/bcm5974.c
@@ -63,7 +63,7 @@
 }
 
 /* table of devices that work with this driver */
-static const struct usb_device_id bcm5974_table [] = {
+static const struct usb_device_id bcm5974_table[] = {
 	/* MacbookAir1.1 */
 	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
 	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ISO),
@@ -105,7 +105,7 @@
 
 /* trackpad finger structure */
 struct tp_finger {
-	__le16 origin;		/* left/right origin? */
+	__le16 origin;		/* zero when switching track finger */
 	__le16 abs_x;		/* absolute x coodinate */
 	__le16 abs_y;		/* absolute y coodinate */
 	__le16 rel_x;		/* relative x coodinate */
@@ -159,6 +159,7 @@
 	struct bt_data *bt_data;	/* button transferred data */
 	struct urb *tp_urb;		/* trackpad usb request block */
 	struct tp_data *tp_data;	/* trackpad transferred data */
+	int fingers;			/* number of fingers on trackpad */
 };
 
 /* logical dimensions */
@@ -172,6 +173,10 @@
 #define SN_WIDTH	100		/* width signal-to-noise ratio */
 #define SN_COORD	250		/* coordinate signal-to-noise ratio */
 
+/* pressure thresholds */
+#define PRESSURE_LOW	(2 * DIM_PRESSURE / SN_PRESSURE)
+#define PRESSURE_HIGH	(3 * PRESSURE_LOW)
+
 /* device constants */
 static const struct bcm5974_config bcm5974_config_table[] = {
 	{
@@ -248,6 +253,7 @@
 				0, cfg->y.dim, cfg->y.fuzz, 0);
 
 	__set_bit(EV_KEY, input_dev->evbit);
+	__set_bit(BTN_TOUCH, input_dev->keybit);
 	__set_bit(BTN_TOOL_FINGER, input_dev->keybit);
 	__set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
 	__set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
@@ -273,32 +279,66 @@
 	const struct tp_finger *f = dev->tp_data->finger;
 	struct input_dev *input = dev->input;
 	const int fingers = (size - 26) / 28;
-	int p = 0, w, x, y, n = 0;
+	int raw_p, raw_w, raw_x, raw_y;
+	int ptest = 0, origin = 0, nmin = 0, nmax = 0;
+	int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0;
 
 	if (size < 26 || (size - 26) % 28 != 0)
 		return -EIO;
 
+	/* always track the first finger; when detached, start over */
 	if (fingers) {
-		p = raw2int(f->force_major);
-		w = raw2int(f->size_major);
-		x = raw2int(f->abs_x);
-		y = raw2int(f->abs_y);
-		n = p > 0 ? fingers : 0;
+		raw_p = raw2int(f->force_major);
+		raw_w = raw2int(f->size_major);
+		raw_x = raw2int(f->abs_x);
+		raw_y = raw2int(f->abs_y);
 
 		dprintk(9,
-			"bcm5974: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n",
-			p, w, x, y, n);
+			"bcm5974: raw: p: %+05d w: %+05d x: %+05d y: %+05d\n",
+			raw_p, raw_w, raw_x, raw_y);
 
-		input_report_abs(input, ABS_TOOL_WIDTH, int2bound(&c->w, w));
-		input_report_abs(input, ABS_X, int2bound(&c->x, x - c->x.devmin));
-		input_report_abs(input, ABS_Y, int2bound(&c->y, c->y.devmax - y));
+		ptest = int2bound(&c->p, raw_p);
+		origin = raw2int(f->origin);
 	}
 
-	input_report_abs(input, ABS_PRESSURE, int2bound(&c->p, p));
+	/* while tracking finger still valid, count all fingers */
+	if (ptest > PRESSURE_LOW && origin) {
+		abs_p = ptest;
+		abs_w = int2bound(&c->w, raw_w);
+		abs_x = int2bound(&c->x, raw_x - c->x.devmin);
+		abs_y = int2bound(&c->y, c->y.devmax - raw_y);
+		for (; f != dev->tp_data->finger + fingers; f++) {
+			ptest = int2bound(&c->p, raw2int(f->force_major));
+			if (ptest > PRESSURE_LOW)
+				nmax++;
+			if (ptest > PRESSURE_HIGH)
+				nmin++;
+		}
+	}
 
-	input_report_key(input, BTN_TOOL_FINGER, n == 1);
-	input_report_key(input, BTN_TOOL_DOUBLETAP, n == 2);
-	input_report_key(input, BTN_TOOL_TRIPLETAP, n > 2);
+	if (dev->fingers < nmin)
+		dev->fingers = nmin;
+	if (dev->fingers > nmax)
+		dev->fingers = nmax;
+
+	input_report_key(input, BTN_TOUCH, dev->fingers > 0);
+	input_report_key(input, BTN_TOOL_FINGER, dev->fingers == 1);
+	input_report_key(input, BTN_TOOL_DOUBLETAP, dev->fingers == 2);
+	input_report_key(input, BTN_TOOL_TRIPLETAP, dev->fingers > 2);
+
+	input_report_abs(input, ABS_PRESSURE, abs_p);
+	input_report_abs(input, ABS_TOOL_WIDTH, abs_w);
+
+	if (abs_p) {
+		input_report_abs(input, ABS_X, abs_x);
+		input_report_abs(input, ABS_Y, abs_y);
+
+		dprintk(8,
+			"bcm5974: abs: p: %+05d w: %+05d x: %+05d y: %+05d "
+			"nmin: %d nmax: %d n: %d\n",
+			abs_p, abs_w, abs_x, abs_y, nmin, nmax, dev->fingers);
+
+	}
 
 	input_sync(input);
 
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 3282b74..5aafe24 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -305,7 +305,7 @@
 		.ident = "Lenovo 3000 n100",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-			DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "076804U"),
 		},
 	},
 	{
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 25287e8..6e1e8c6 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -220,6 +220,7 @@
 config TOUCHSCREEN_UCB1400
 	tristate "Philips UCB1400 touchscreen"
 	select AC97_BUS
+	depends on UCB1400_CORE
 	help
 	  This enables support for the Philips UCB1400 touchscreen interface.
 	  The UCB1400 is an AC97 audio codec.  The touchscreen interface
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index ce6f48c..8583c76 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -24,6 +24,7 @@
 #include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
+#include <linux/gpio.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 #include <asm/irq.h>
@@ -116,6 +117,7 @@
 	void			*filter_data;
 	void			(*filter_cleanup)(void *data);
 	int			(*get_pendown_state)(void);
+	int			gpio_pendown;
 };
 
 /* leave chip selected when we're done, for quicker re-select? */
@@ -491,6 +493,14 @@
 
 /*--------------------------------------------------------------------------*/
 
+static int get_pendown_state(struct ads7846 *ts)
+{
+	if (ts->get_pendown_state)
+		return ts->get_pendown_state();
+
+	return !gpio_get_value(ts->gpio_pendown);
+}
+
 /*
  * PENIRQ only kicks the timer.  The timer only reissues the SPI transfer,
  * to retrieve touchscreen status.
@@ -550,7 +560,7 @@
 	 */
 	if (ts->penirq_recheck_delay_usecs) {
 		udelay(ts->penirq_recheck_delay_usecs);
-		if (!ts->get_pendown_state())
+		if (!get_pendown_state(ts))
 			Rt = 0;
 	}
 
@@ -677,7 +687,7 @@
 
 	spin_lock_irq(&ts->lock);
 
-	if (unlikely(!ts->get_pendown_state() ||
+	if (unlikely(!get_pendown_state(ts) ||
 		     device_suspended(&ts->spi->dev))) {
 		if (ts->pendown) {
 			struct input_dev *input = ts->input;
@@ -716,7 +726,7 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&ts->lock, flags);
-	if (likely(ts->get_pendown_state())) {
+	if (likely(get_pendown_state(ts))) {
 		if (!ts->irq_disabled) {
 			/* The ARM do_simple_IRQ() dispatcher doesn't act
 			 * like the other dispatchers:  it will report IRQs
@@ -806,6 +816,36 @@
 	return 0;
 }
 
+static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts)
+{
+	struct ads7846_platform_data *pdata = spi->dev.platform_data;
+	int err;
+
+	/* REVISIT when the irq can be triggered active-low, or if for some
+	 * reason the touchscreen isn't hooked up, we don't need to access
+	 * the pendown state.
+	 */
+	if (!pdata->get_pendown_state && !gpio_is_valid(pdata->gpio_pendown)) {
+		dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n");
+		return -EINVAL;
+	}
+
+	if (pdata->get_pendown_state) {
+		ts->get_pendown_state = pdata->get_pendown_state;
+		return 0;
+	}
+
+	err = gpio_request(pdata->gpio_pendown, "ads7846_pendown");
+	if (err) {
+		dev_err(&spi->dev, "failed to request pendown GPIO%d\n",
+				pdata->gpio_pendown);
+		return err;
+	}
+
+	ts->gpio_pendown = pdata->gpio_pendown;
+	return 0;
+}
+
 static int __devinit ads7846_probe(struct spi_device *spi)
 {
 	struct ads7846			*ts;
@@ -833,15 +873,6 @@
 		return -EINVAL;
 	}
 
-	/* REVISIT when the irq can be triggered active-low, or if for some
-	 * reason the touchscreen isn't hooked up, we don't need to access
-	 * the pendown state.
-	 */
-	if (pdata->get_pendown_state == NULL) {
-		dev_dbg(&spi->dev, "no get_pendown_state function?\n");
-		return -EINVAL;
-	}
-
 	/* We'd set TX wordsize 8 bits and RX wordsize to 13 bits ... except
 	 * that even if the hardware can do that, the SPI controller driver
 	 * may not.  So we stick to very-portable 8 bit words, both RX and TX.
@@ -893,7 +924,10 @@
 		ts->filter_data = ts;
 	} else
 		ts->filter = ads7846_no_filter;
-	ts->get_pendown_state = pdata->get_pendown_state;
+
+	err = setup_pendown(spi, ts);
+	if (err)
+		goto err_cleanup_filter;
 
 	if (pdata->penirq_recheck_delay_usecs)
 		ts->penirq_recheck_delay_usecs =
@@ -1085,7 +1119,7 @@
 			spi->dev.driver->name, ts)) {
 		dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
 		err = -EBUSY;
-		goto err_cleanup_filter;
+		goto err_free_gpio;
 	}
 
 	err = ads784x_hwmon_register(spi, ts);
@@ -1116,6 +1150,9 @@
 	ads784x_hwmon_unregister(spi, ts);
  err_free_irq:
 	free_irq(spi->irq, ts);
+ err_free_gpio:
+	if (ts->gpio_pendown != -1)
+		gpio_free(ts->gpio_pendown);
  err_cleanup_filter:
 	if (ts->filter_cleanup)
 		ts->filter_cleanup(ts->filter_data);
@@ -1140,6 +1177,9 @@
 	/* suspend left the IRQ disabled */
 	enable_irq(ts->spi->irq);
 
+	if (ts->gpio_pendown != -1)
+		gpio_free(ts->gpio_pendown);
+
 	if (ts->filter_cleanup)
 		ts->filter_cleanup(ts->filter_data);
 
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index bce018e..5498662 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -5,6 +5,10 @@
  *  Created:	September 25, 2006
  *  Copyright:	MontaVista Software, Inc.
  *
+ * Spliting done by: Marek Vasut <marek.vasut@gmail.com>
+ * If something doesnt work and it worked before spliting, e-mail me,
+ * dont bother Nicolas please ;-)
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
@@ -25,124 +29,16 @@
 #include <linux/slab.h>
 #include <linux/kthread.h>
 #include <linux/freezer.h>
-
-#include <sound/core.h>
-#include <sound/ac97_codec.h>
-
-
-/*
- * Interesting UCB1400 AC-link registers
- */
-
-#define UCB_IE_RIS		0x5e
-#define UCB_IE_FAL		0x60
-#define UCB_IE_STATUS		0x62
-#define UCB_IE_CLEAR		0x62
-#define UCB_IE_ADC		(1 << 11)
-#define UCB_IE_TSPX		(1 << 12)
-
-#define UCB_TS_CR		0x64
-#define UCB_TS_CR_TSMX_POW	(1 << 0)
-#define UCB_TS_CR_TSPX_POW	(1 << 1)
-#define UCB_TS_CR_TSMY_POW	(1 << 2)
-#define UCB_TS_CR_TSPY_POW	(1 << 3)
-#define UCB_TS_CR_TSMX_GND	(1 << 4)
-#define UCB_TS_CR_TSPX_GND	(1 << 5)
-#define UCB_TS_CR_TSMY_GND	(1 << 6)
-#define UCB_TS_CR_TSPY_GND	(1 << 7)
-#define UCB_TS_CR_MODE_INT	(0 << 8)
-#define UCB_TS_CR_MODE_PRES	(1 << 8)
-#define UCB_TS_CR_MODE_POS	(2 << 8)
-#define UCB_TS_CR_BIAS_ENA	(1 << 11)
-#define UCB_TS_CR_TSPX_LOW	(1 << 12)
-#define UCB_TS_CR_TSMX_LOW	(1 << 13)
-
-#define UCB_ADC_CR		0x66
-#define UCB_ADC_SYNC_ENA	(1 << 0)
-#define UCB_ADC_VREFBYP_CON	(1 << 1)
-#define UCB_ADC_INP_TSPX	(0 << 2)
-#define UCB_ADC_INP_TSMX	(1 << 2)
-#define UCB_ADC_INP_TSPY	(2 << 2)
-#define UCB_ADC_INP_TSMY	(3 << 2)
-#define UCB_ADC_INP_AD0		(4 << 2)
-#define UCB_ADC_INP_AD1		(5 << 2)
-#define UCB_ADC_INP_AD2		(6 << 2)
-#define UCB_ADC_INP_AD3		(7 << 2)
-#define UCB_ADC_EXT_REF		(1 << 5)
-#define UCB_ADC_START		(1 << 7)
-#define UCB_ADC_ENA		(1 << 15)
-
-#define UCB_ADC_DATA		0x68
-#define UCB_ADC_DAT_VALID	(1 << 15)
-#define UCB_ADC_DAT_VALUE(x)	((x) & 0x3ff)
-
-#define UCB_ID			0x7e
-#define UCB_ID_1400             0x4304
-
-
-struct ucb1400 {
-	struct snd_ac97		*ac97;
-	struct input_dev	*ts_idev;
-
-	int			irq;
-
-	wait_queue_head_t	ts_wait;
-	struct task_struct	*ts_task;
-
-	unsigned int		irq_pending;	/* not bit field shared */
-	unsigned int		ts_restart:1;
-	unsigned int		adcsync:1;
-};
+#include <linux/ucb1400.h>
 
 static int adcsync;
 static int ts_delay = 55; /* us */
 static int ts_delay_pressure;	/* us */
 
-static inline u16 ucb1400_reg_read(struct ucb1400 *ucb, u16 reg)
-{
-	return ucb->ac97->bus->ops->read(ucb->ac97, reg);
-}
-
-static inline void ucb1400_reg_write(struct ucb1400 *ucb, u16 reg, u16 val)
-{
-	ucb->ac97->bus->ops->write(ucb->ac97, reg, val);
-}
-
-static inline void ucb1400_adc_enable(struct ucb1400 *ucb)
-{
-	ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA);
-}
-
-static unsigned int ucb1400_adc_read(struct ucb1400 *ucb, u16 adc_channel)
-{
-	unsigned int val;
-
-	if (ucb->adcsync)
-		adc_channel |= UCB_ADC_SYNC_ENA;
-
-	ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | adc_channel);
-	ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | adc_channel | UCB_ADC_START);
-
-	for (;;) {
-		val = ucb1400_reg_read(ucb, UCB_ADC_DATA);
-		if (val & UCB_ADC_DAT_VALID)
-			break;
-		/* yield to other processes */
-		schedule_timeout_uninterruptible(1);
-	}
-
-	return UCB_ADC_DAT_VALUE(val);
-}
-
-static inline void ucb1400_adc_disable(struct ucb1400 *ucb)
-{
-	ucb1400_reg_write(ucb, UCB_ADC_CR, 0);
-}
-
 /* Switch to interrupt mode. */
-static inline void ucb1400_ts_mode_int(struct ucb1400 *ucb)
+static inline void ucb1400_ts_mode_int(struct snd_ac97 *ac97)
 {
-	ucb1400_reg_write(ucb, UCB_TS_CR,
+	ucb1400_reg_write(ac97, UCB_TS_CR,
 			UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
 			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
 			UCB_TS_CR_MODE_INT);
@@ -152,14 +48,14 @@
  * Switch to pressure mode, and read pressure.  We don't need to wait
  * here, since both plates are being driven.
  */
-static inline unsigned int ucb1400_ts_read_pressure(struct ucb1400 *ucb)
+static inline unsigned int ucb1400_ts_read_pressure(struct ucb1400_ts *ucb)
 {
-	ucb1400_reg_write(ucb, UCB_TS_CR,
+	ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
 			UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
 			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
 			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
 	udelay(ts_delay_pressure);
-	return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPY);
+	return ucb1400_adc_read(ucb->ac97, UCB_ADC_INP_TSPY, adcsync);
 }
 
 /*
@@ -168,21 +64,21 @@
  * gives a faster response time.  Even so, we need to wait about 55us
  * for things to stabilise.
  */
-static inline unsigned int ucb1400_ts_read_xpos(struct ucb1400 *ucb)
+static inline unsigned int ucb1400_ts_read_xpos(struct ucb1400_ts *ucb)
 {
-	ucb1400_reg_write(ucb, UCB_TS_CR,
+	ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
 			UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
 			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-	ucb1400_reg_write(ucb, UCB_TS_CR,
+	ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
 			UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
 			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-	ucb1400_reg_write(ucb, UCB_TS_CR,
+	ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
 			UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
 			UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
 
 	udelay(ts_delay);
 
-	return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPY);
+	return ucb1400_adc_read(ucb->ac97, UCB_ADC_INP_TSPY, adcsync);
 }
 
 /*
@@ -191,63 +87,63 @@
  * gives a faster response time.  Even so, we need to wait about 55us
  * for things to stabilise.
  */
-static inline unsigned int ucb1400_ts_read_ypos(struct ucb1400 *ucb)
+static inline unsigned int ucb1400_ts_read_ypos(struct ucb1400_ts *ucb)
 {
-	ucb1400_reg_write(ucb, UCB_TS_CR,
+	ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
 			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
 			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-	ucb1400_reg_write(ucb, UCB_TS_CR,
+	ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
 			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
 			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-	ucb1400_reg_write(ucb, UCB_TS_CR,
+	ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
 			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
 			UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
 
 	udelay(ts_delay);
 
-	return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPX);
+	return ucb1400_adc_read(ucb->ac97, UCB_ADC_INP_TSPX, adcsync);
 }
 
 /*
  * Switch to X plate resistance mode.  Set MX to ground, PX to
  * supply.  Measure current.
  */
-static inline unsigned int ucb1400_ts_read_xres(struct ucb1400 *ucb)
+static inline unsigned int ucb1400_ts_read_xres(struct ucb1400_ts *ucb)
 {
-	ucb1400_reg_write(ucb, UCB_TS_CR,
+	ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
 			UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
 			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-	return ucb1400_adc_read(ucb, 0);
+	return ucb1400_adc_read(ucb->ac97, 0, adcsync);
 }
 
 /*
  * Switch to Y plate resistance mode.  Set MY to ground, PY to
  * supply.  Measure current.
  */
-static inline unsigned int ucb1400_ts_read_yres(struct ucb1400 *ucb)
+static inline unsigned int ucb1400_ts_read_yres(struct ucb1400_ts *ucb)
 {
-	ucb1400_reg_write(ucb, UCB_TS_CR,
+	ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
 			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
 			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-	return ucb1400_adc_read(ucb, 0);
+	return ucb1400_adc_read(ucb->ac97, 0, adcsync);
 }
 
-static inline int ucb1400_ts_pen_down(struct ucb1400 *ucb)
+static inline int ucb1400_ts_pen_down(struct snd_ac97 *ac97)
 {
-	unsigned short val = ucb1400_reg_read(ucb, UCB_TS_CR);
-	return (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW));
+	unsigned short val = ucb1400_reg_read(ac97, UCB_TS_CR);
+	return val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW);
 }
 
-static inline void ucb1400_ts_irq_enable(struct ucb1400 *ucb)
+static inline void ucb1400_ts_irq_enable(struct snd_ac97 *ac97)
 {
-	ucb1400_reg_write(ucb, UCB_IE_CLEAR, UCB_IE_TSPX);
-	ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0);
-	ucb1400_reg_write(ucb, UCB_IE_FAL, UCB_IE_TSPX);
+	ucb1400_reg_write(ac97, UCB_IE_CLEAR, UCB_IE_TSPX);
+	ucb1400_reg_write(ac97, UCB_IE_CLEAR, 0);
+	ucb1400_reg_write(ac97, UCB_IE_FAL, UCB_IE_TSPX);
 }
 
-static inline void ucb1400_ts_irq_disable(struct ucb1400 *ucb)
+static inline void ucb1400_ts_irq_disable(struct snd_ac97 *ac97)
 {
-	ucb1400_reg_write(ucb, UCB_IE_FAL, 0);
+	ucb1400_reg_write(ac97, UCB_IE_FAL, 0);
 }
 
 static void ucb1400_ts_evt_add(struct input_dev *idev, u16 pressure, u16 x, u16 y)
@@ -264,25 +160,24 @@
 	input_sync(idev);
 }
 
-static void ucb1400_handle_pending_irq(struct ucb1400 *ucb)
+static void ucb1400_handle_pending_irq(struct ucb1400_ts *ucb)
 {
 	unsigned int isr;
 
-	isr = ucb1400_reg_read(ucb, UCB_IE_STATUS);
-	ucb1400_reg_write(ucb, UCB_IE_CLEAR, isr);
-	ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0);
+	isr = ucb1400_reg_read(ucb->ac97, UCB_IE_STATUS);
+	ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, isr);
+	ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0);
 
-	if (isr & UCB_IE_TSPX)
-		ucb1400_ts_irq_disable(ucb);
-	else
+	if (isr & UCB_IE_TSPX) {
+		ucb1400_ts_irq_disable(ucb->ac97);
+		enable_irq(ucb->irq);
+	} else
 		printk(KERN_ERR "ucb1400: unexpected IE_STATUS = %#x\n", isr);
-
-	enable_irq(ucb->irq);
 }
 
 static int ucb1400_ts_thread(void *_ucb)
 {
-	struct ucb1400 *ucb = _ucb;
+	struct ucb1400_ts *ucb = _ucb;
 	struct task_struct *tsk = current;
 	int valid = 0;
 	struct sched_param param = { .sched_priority = 1 };
@@ -301,19 +196,19 @@
 			ucb1400_handle_pending_irq(ucb);
 		}
 
-		ucb1400_adc_enable(ucb);
+		ucb1400_adc_enable(ucb->ac97);
 		x = ucb1400_ts_read_xpos(ucb);
 		y = ucb1400_ts_read_ypos(ucb);
 		p = ucb1400_ts_read_pressure(ucb);
-		ucb1400_adc_disable(ucb);
+		ucb1400_adc_disable(ucb->ac97);
 
 		/* Switch back to interrupt mode. */
-		ucb1400_ts_mode_int(ucb);
+		ucb1400_ts_mode_int(ucb->ac97);
 
 		msleep(10);
 
-		if (ucb1400_ts_pen_down(ucb)) {
-			ucb1400_ts_irq_enable(ucb);
+		if (ucb1400_ts_pen_down(ucb->ac97)) {
+			ucb1400_ts_irq_enable(ucb->ac97);
 
 			/*
 			 * If we spat out a valid sample set last time,
@@ -332,8 +227,8 @@
 		}
 
 		wait_event_freezable_timeout(ucb->ts_wait,
-			ucb->irq_pending || ucb->ts_restart || kthread_should_stop(),
-			timeout);
+			ucb->irq_pending || ucb->ts_restart ||
+			kthread_should_stop(), timeout);
 	}
 
 	/* Send the "pen off" if we are stopping with the pen still active */
@@ -356,7 +251,7 @@
  */
 static irqreturn_t ucb1400_hard_irq(int irqnr, void *devid)
 {
-	struct ucb1400 *ucb = devid;
+	struct ucb1400_ts *ucb = devid;
 
 	if (irqnr == ucb->irq) {
 		disable_irq(ucb->irq);
@@ -369,7 +264,7 @@
 
 static int ucb1400_ts_open(struct input_dev *idev)
 {
-	struct ucb1400 *ucb = input_get_drvdata(idev);
+	struct ucb1400_ts *ucb = input_get_drvdata(idev);
 	int ret = 0;
 
 	BUG_ON(ucb->ts_task);
@@ -385,19 +280,143 @@
 
 static void ucb1400_ts_close(struct input_dev *idev)
 {
-	struct ucb1400 *ucb = input_get_drvdata(idev);
+	struct ucb1400_ts *ucb = input_get_drvdata(idev);
 
 	if (ucb->ts_task)
 		kthread_stop(ucb->ts_task);
 
-	ucb1400_ts_irq_disable(ucb);
-	ucb1400_reg_write(ucb, UCB_TS_CR, 0);
+	ucb1400_ts_irq_disable(ucb->ac97);
+	ucb1400_reg_write(ucb->ac97, UCB_TS_CR, 0);
+}
+
+#ifndef NO_IRQ
+#define NO_IRQ	0
+#endif
+
+/*
+ * Try to probe our interrupt, rather than relying on lots of
+ * hard-coded machine dependencies.
+ */
+static int ucb1400_ts_detect_irq(struct ucb1400_ts *ucb)
+{
+	unsigned long mask, timeout;
+
+	mask = probe_irq_on();
+
+	/* Enable the ADC interrupt. */
+	ucb1400_reg_write(ucb->ac97, UCB_IE_RIS, UCB_IE_ADC);
+	ucb1400_reg_write(ucb->ac97, UCB_IE_FAL, UCB_IE_ADC);
+	ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0xffff);
+	ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0);
+
+	/* Cause an ADC interrupt. */
+	ucb1400_reg_write(ucb->ac97, UCB_ADC_CR, UCB_ADC_ENA);
+	ucb1400_reg_write(ucb->ac97, UCB_ADC_CR, UCB_ADC_ENA | UCB_ADC_START);
+
+	/* Wait for the conversion to complete. */
+	timeout = jiffies + HZ/2;
+	while (!(ucb1400_reg_read(ucb->ac97, UCB_ADC_DATA) &
+						UCB_ADC_DAT_VALID)) {
+		cpu_relax();
+		if (time_after(jiffies, timeout)) {
+			printk(KERN_ERR "ucb1400: timed out in IRQ probe\n");
+			probe_irq_off(mask);
+			return -ENODEV;
+		}
+	}
+	ucb1400_reg_write(ucb->ac97, UCB_ADC_CR, 0);
+
+	/* Disable and clear interrupt. */
+	ucb1400_reg_write(ucb->ac97, UCB_IE_RIS, 0);
+	ucb1400_reg_write(ucb->ac97, UCB_IE_FAL, 0);
+	ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0xffff);
+	ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0);
+
+	/* Read triggered interrupt. */
+	ucb->irq = probe_irq_off(mask);
+	if (ucb->irq < 0 || ucb->irq == NO_IRQ)
+		return -ENODEV;
+
+	return 0;
+}
+
+static int ucb1400_ts_probe(struct platform_device *dev)
+{
+	int error, x_res, y_res;
+	struct ucb1400_ts *ucb = dev->dev.platform_data;
+
+	ucb->ts_idev = input_allocate_device();
+	if (!ucb->ts_idev) {
+		error = -ENOMEM;
+		goto err;
+	}
+
+	error = ucb1400_ts_detect_irq(ucb);
+	if (error) {
+		printk(KERN_ERR "UCB1400: IRQ probe failed\n");
+		goto err_free_devs;
+	}
+
+	init_waitqueue_head(&ucb->ts_wait);
+
+	error = request_irq(ucb->irq, ucb1400_hard_irq, IRQF_TRIGGER_RISING,
+				"UCB1400", ucb);
+	if (error) {
+		printk(KERN_ERR "ucb1400: unable to grab irq%d: %d\n",
+				ucb->irq, error);
+		goto err_free_devs;
+	}
+	printk(KERN_DEBUG "UCB1400: found IRQ %d\n", ucb->irq);
+
+	input_set_drvdata(ucb->ts_idev, ucb);
+
+	ucb->ts_idev->dev.parent	= &dev->dev;
+	ucb->ts_idev->name		= "UCB1400 touchscreen interface";
+	ucb->ts_idev->id.vendor		= ucb1400_reg_read(ucb->ac97,
+						AC97_VENDOR_ID1);
+	ucb->ts_idev->id.product	= ucb->id;
+	ucb->ts_idev->open		= ucb1400_ts_open;
+	ucb->ts_idev->close		= ucb1400_ts_close;
+	ucb->ts_idev->evbit[0]		= BIT_MASK(EV_ABS);
+
+	ucb1400_adc_enable(ucb->ac97);
+	x_res = ucb1400_ts_read_xres(ucb);
+	y_res = ucb1400_ts_read_yres(ucb);
+	ucb1400_adc_disable(ucb->ac97);
+	printk(KERN_DEBUG "UCB1400: x/y = %d/%d\n", x_res, y_res);
+
+	input_set_abs_params(ucb->ts_idev, ABS_X, 0, x_res, 0, 0);
+	input_set_abs_params(ucb->ts_idev, ABS_Y, 0, y_res, 0, 0);
+	input_set_abs_params(ucb->ts_idev, ABS_PRESSURE, 0, 0, 0, 0);
+
+	error = input_register_device(ucb->ts_idev);
+	if (error)
+		goto err_free_irq;
+
+	return 0;
+
+err_free_irq:
+	free_irq(ucb->irq, ucb);
+err_free_devs:
+	input_free_device(ucb->ts_idev);
+err:
+	return error;
+
+}
+
+static int ucb1400_ts_remove(struct platform_device *dev)
+{
+	struct ucb1400_ts *ucb = dev->dev.platform_data;
+
+	free_irq(ucb->irq, ucb);
+	input_unregister_device(ucb->ts_idev);
+	return 0;
 }
 
 #ifdef CONFIG_PM
-static int ucb1400_ts_resume(struct device *dev)
+static int ucb1400_ts_resume(struct platform_device *dev)
 {
-	struct ucb1400 *ucb = dev_get_drvdata(dev);
+	struct ucb1400_ts *ucb = platform_get_drvdata(dev);
 
 	if (ucb->ts_task) {
 		/*
@@ -414,169 +433,36 @@
 #define ucb1400_ts_resume NULL
 #endif
 
-#ifndef NO_IRQ
-#define NO_IRQ	0
-#endif
-
-/*
- * Try to probe our interrupt, rather than relying on lots of
- * hard-coded machine dependencies.
- */
-static int ucb1400_detect_irq(struct ucb1400 *ucb)
-{
-	unsigned long mask, timeout;
-
-	mask = probe_irq_on();
-
-	/* Enable the ADC interrupt. */
-	ucb1400_reg_write(ucb, UCB_IE_RIS, UCB_IE_ADC);
-	ucb1400_reg_write(ucb, UCB_IE_FAL, UCB_IE_ADC);
-	ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0xffff);
-	ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0);
-
-	/* Cause an ADC interrupt. */
-	ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA);
-	ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | UCB_ADC_START);
-
-	/* Wait for the conversion to complete. */
-	timeout = jiffies + HZ/2;
-	while (!(ucb1400_reg_read(ucb, UCB_ADC_DATA) & UCB_ADC_DAT_VALID)) {
-		cpu_relax();
-		if (time_after(jiffies, timeout)) {
-			printk(KERN_ERR "ucb1400: timed out in IRQ probe\n");
-			probe_irq_off(mask);
-			return -ENODEV;
-		}
-	}
-	ucb1400_reg_write(ucb, UCB_ADC_CR, 0);
-
-	/* Disable and clear interrupt. */
-	ucb1400_reg_write(ucb, UCB_IE_RIS, 0);
-	ucb1400_reg_write(ucb, UCB_IE_FAL, 0);
-	ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0xffff);
-	ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0);
-
-	/* Read triggered interrupt. */
-	ucb->irq = probe_irq_off(mask);
-	if (ucb->irq < 0 || ucb->irq == NO_IRQ)
-		return -ENODEV;
-
-	return 0;
-}
-
-static int ucb1400_ts_probe(struct device *dev)
-{
-	struct ucb1400 *ucb;
-	struct input_dev *idev;
-	int error, id, x_res, y_res;
-
-	ucb = kzalloc(sizeof(struct ucb1400), GFP_KERNEL);
-	idev = input_allocate_device();
-	if (!ucb || !idev) {
-		error = -ENOMEM;
-		goto err_free_devs;
-	}
-
-	ucb->ts_idev = idev;
-	ucb->adcsync = adcsync;
-	ucb->ac97 = to_ac97_t(dev);
-	init_waitqueue_head(&ucb->ts_wait);
-
-	id = ucb1400_reg_read(ucb, UCB_ID);
-	if (id != UCB_ID_1400) {
-		error = -ENODEV;
-		goto err_free_devs;
-	}
-
-	error = ucb1400_detect_irq(ucb);
-	if (error) {
-		printk(KERN_ERR "UCB1400: IRQ probe failed\n");
-		goto err_free_devs;
-	}
-
-	error = request_irq(ucb->irq, ucb1400_hard_irq, IRQF_TRIGGER_RISING,
-				"UCB1400", ucb);
-	if (error) {
-		printk(KERN_ERR "ucb1400: unable to grab irq%d: %d\n",
-				ucb->irq, error);
-		goto err_free_devs;
-	}
-	printk(KERN_DEBUG "UCB1400: found IRQ %d\n", ucb->irq);
-
-	input_set_drvdata(idev, ucb);
-
-	idev->dev.parent	= dev;
-	idev->name		= "UCB1400 touchscreen interface";
-	idev->id.vendor		= ucb1400_reg_read(ucb, AC97_VENDOR_ID1);
-	idev->id.product	= id;
-	idev->open		= ucb1400_ts_open;
-	idev->close		= ucb1400_ts_close;
-	idev->evbit[0]		= BIT_MASK(EV_ABS);
-
-	ucb1400_adc_enable(ucb);
-	x_res = ucb1400_ts_read_xres(ucb);
-	y_res = ucb1400_ts_read_yres(ucb);
-	ucb1400_adc_disable(ucb);
-	printk(KERN_DEBUG "UCB1400: x/y = %d/%d\n", x_res, y_res);
-
-	input_set_abs_params(idev, ABS_X, 0, x_res, 0, 0);
-	input_set_abs_params(idev, ABS_Y, 0, y_res, 0, 0);
-	input_set_abs_params(idev, ABS_PRESSURE, 0, 0, 0, 0);
-
-	error = input_register_device(idev);
-	if (error)
-		goto err_free_irq;
-
-	dev_set_drvdata(dev, ucb);
-	return 0;
-
- err_free_irq:
-	free_irq(ucb->irq, ucb);
- err_free_devs:
-	input_free_device(idev);
-	kfree(ucb);
-	return error;
-}
-
-static int ucb1400_ts_remove(struct device *dev)
-{
-	struct ucb1400 *ucb = dev_get_drvdata(dev);
-
-	free_irq(ucb->irq, ucb);
-	input_unregister_device(ucb->ts_idev);
-	dev_set_drvdata(dev, NULL);
-	kfree(ucb);
-	return 0;
-}
-
-static struct device_driver ucb1400_ts_driver = {
-	.name		= "ucb1400_ts",
-	.owner		= THIS_MODULE,
-	.bus		= &ac97_bus_type,
-	.probe		= ucb1400_ts_probe,
-	.remove		= ucb1400_ts_remove,
-	.resume		= ucb1400_ts_resume,
+static struct platform_driver ucb1400_ts_driver = {
+	.probe	= ucb1400_ts_probe,
+	.remove	= ucb1400_ts_remove,
+	.resume	= ucb1400_ts_resume,
+	.driver	= {
+		.name	= "ucb1400_ts",
+	},
 };
 
 static int __init ucb1400_ts_init(void)
 {
-	return driver_register(&ucb1400_ts_driver);
+	return platform_driver_register(&ucb1400_ts_driver);
 }
 
 static void __exit ucb1400_ts_exit(void)
 {
-	driver_unregister(&ucb1400_ts_driver);
+	platform_driver_unregister(&ucb1400_ts_driver);
 }
 
 module_param(adcsync, bool, 0444);
 MODULE_PARM_DESC(adcsync, "Synchronize touch readings with ADCSYNC pin.");
 
 module_param(ts_delay, int, 0444);
-MODULE_PARM_DESC(ts_delay, "Delay between panel setup and position read. Default = 55us.");
+MODULE_PARM_DESC(ts_delay, "Delay between panel setup and"
+			    " position read. Default = 55us.");
 
 module_param(ts_delay_pressure, int, 0444);
 MODULE_PARM_DESC(ts_delay_pressure,
-		  "delay between panel setup and pressure read.  Default = 0us.");
+		"delay between panel setup and pressure read."
+		"  Default = 0us.");
 
 module_init(ucb1400_ts_init);
 module_exit(ucb1400_ts_exit);
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 9556262..5b14262 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -24,13 +24,6 @@
 	  This option enables support for LEDs driven using outputs
 	  of the dedicated PWM controller found on newer Atmel SOCs.
 
-config LEDS_CORGI
-	tristate "LED Support for the Sharp SL-C7x0 series"
-	depends on LEDS_CLASS && PXA_SHARP_C7xx
-	help
-	  This option enables support for the LEDs on Sharp Zaurus
-	  SL-C7x0 series (C700, C750, C760, C860).
-
 config LEDS_LOCOMO
 	tristate "LED Support for Locomo device"
 	depends on LEDS_CLASS && SHARP_LOCOMO
@@ -38,13 +31,6 @@
 	  This option enables support for the LEDs on Sharp Locomo.
 	  Zaurus models SL-5500 and SL-5600.
 
-config LEDS_SPITZ
-	tristate "LED Support for the Sharp SL-Cxx00 series"
-	depends on LEDS_CLASS && PXA_SHARP_Cxx00
-	help
-	  This option enables support for the LEDs on Sharp Zaurus
-	  SL-Cxx00 series (C1000, C3000, C3100).
-
 config LEDS_S3C24XX
 	tristate "LED Support for Samsung S3C24XX GPIO LEDs"
 	depends on LEDS_CLASS && ARCH_S3C2410
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index ff7982b..3a8e6a0 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -6,9 +6,7 @@
 
 # LED Platform Drivers
 obj-$(CONFIG_LEDS_ATMEL_PWM)		+= leds-atmel-pwm.o
-obj-$(CONFIG_LEDS_CORGI)		+= leds-corgi.o
 obj-$(CONFIG_LEDS_LOCOMO)		+= leds-locomo.o
-obj-$(CONFIG_LEDS_SPITZ)		+= leds-spitz.o
 obj-$(CONFIG_LEDS_S3C24XX)		+= leds-s3c24xx.o
 obj-$(CONFIG_LEDS_AMS_DELTA)		+= leds-ams-delta.o
 obj-$(CONFIG_LEDS_NET48XX)		+= leds-net48xx.o
diff --git a/drivers/leds/leds-corgi.c b/drivers/leds/leds-corgi.c
deleted file mode 100644
index bc2dcd8..0000000
--- a/drivers/leds/leds-corgi.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * LED Triggers Core
- *
- * Copyright 2005-2006 Openedhand Ltd.
- *
- * Author: Richard Purdie <rpurdie@openedhand.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/leds.h>
-#include <mach/corgi.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
-#include <asm/hardware/scoop.h>
-
-static void corgiled_amber_set(struct led_classdev *led_cdev,
-			       enum led_brightness value)
-{
-	if (value)
-		GPSR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
-	else
-		GPCR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
-}
-
-static void corgiled_green_set(struct led_classdev *led_cdev,
-			       enum led_brightness value)
-{
-	if (value)
-		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
-	else
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
-}
-
-static struct led_classdev corgi_amber_led = {
-	.name			= "corgi:amber:charge",
-	.default_trigger	= "sharpsl-charge",
-	.brightness_set		= corgiled_amber_set,
-};
-
-static struct led_classdev corgi_green_led = {
-	.name			= "corgi:green:mail",
-	.default_trigger	= "nand-disk",
-	.brightness_set		= corgiled_green_set,
-};
-
-#ifdef CONFIG_PM
-static int corgiled_suspend(struct platform_device *dev, pm_message_t state)
-{
-#ifdef CONFIG_LEDS_TRIGGERS
-	if (corgi_amber_led.trigger &&
-	    strcmp(corgi_amber_led.trigger->name, "sharpsl-charge"))
-#endif
-		led_classdev_suspend(&corgi_amber_led);
-	led_classdev_suspend(&corgi_green_led);
-	return 0;
-}
-
-static int corgiled_resume(struct platform_device *dev)
-{
-	led_classdev_resume(&corgi_amber_led);
-	led_classdev_resume(&corgi_green_led);
-	return 0;
-}
-#endif
-
-static int corgiled_probe(struct platform_device *pdev)
-{
-	int ret;
-
-	ret = led_classdev_register(&pdev->dev, &corgi_amber_led);
-	if (ret < 0)
-		return ret;
-
-	ret = led_classdev_register(&pdev->dev, &corgi_green_led);
-	if (ret < 0)
-		led_classdev_unregister(&corgi_amber_led);
-
-	return ret;
-}
-
-static int corgiled_remove(struct platform_device *pdev)
-{
-	led_classdev_unregister(&corgi_amber_led);
-	led_classdev_unregister(&corgi_green_led);
-	return 0;
-}
-
-static struct platform_driver corgiled_driver = {
-	.probe		= corgiled_probe,
-	.remove		= corgiled_remove,
-#ifdef CONFIG_PM
-	.suspend	= corgiled_suspend,
-	.resume		= corgiled_resume,
-#endif
-	.driver		= {
-		.name		= "corgi-led",
-		.owner		= THIS_MODULE,
-	},
-};
-
-static int __init corgiled_init(void)
-{
-	return platform_driver_register(&corgiled_driver);
-}
-
-static void __exit corgiled_exit(void)
-{
-	platform_driver_unregister(&corgiled_driver);
-}
-
-module_init(corgiled_init);
-module_exit(corgiled_exit);
-
-MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
-MODULE_DESCRIPTION("Corgi LED driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:corgi-led");
diff --git a/drivers/leds/leds-spitz.c b/drivers/leds/leds-spitz.c
deleted file mode 100644
index 178831c..0000000
--- a/drivers/leds/leds-spitz.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * LED Triggers Core
- *
- * Copyright 2005-2006 Openedhand Ltd.
- *
- * Author: Richard Purdie <rpurdie@openedhand.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/leds.h>
-#include <asm/hardware/scoop.h>
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
-#include <mach/spitz.h>
-
-static void spitzled_amber_set(struct led_classdev *led_cdev,
-			       enum led_brightness value)
-{
-	if (value)
-		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
-	else
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
-}
-
-static void spitzled_green_set(struct led_classdev *led_cdev,
-			       enum led_brightness value)
-{
-	if (value)
-		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN);
-	else
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN);
-}
-
-static struct led_classdev spitz_amber_led = {
-	.name			= "spitz:amber:charge",
-	.default_trigger	= "sharpsl-charge",
-	.brightness_set		= spitzled_amber_set,
-};
-
-static struct led_classdev spitz_green_led = {
-	.name			= "spitz:green:hddactivity",
-	.default_trigger	= "ide-disk",
-	.brightness_set		= spitzled_green_set,
-};
-
-#ifdef CONFIG_PM
-static int spitzled_suspend(struct platform_device *dev, pm_message_t state)
-{
-#ifdef CONFIG_LEDS_TRIGGERS
-	if (spitz_amber_led.trigger &&
-	    strcmp(spitz_amber_led.trigger->name, "sharpsl-charge"))
-#endif
-		led_classdev_suspend(&spitz_amber_led);
-	led_classdev_suspend(&spitz_green_led);
-	return 0;
-}
-
-static int spitzled_resume(struct platform_device *dev)
-{
-	led_classdev_resume(&spitz_amber_led);
-	led_classdev_resume(&spitz_green_led);
-	return 0;
-}
-#endif
-
-static int spitzled_probe(struct platform_device *pdev)
-{
-	int ret;
-
-	if (machine_is_akita()) {
-		spitz_green_led.name = "spitz:green:mail";
-		spitz_green_led.default_trigger = "nand-disk";
-	}
-
-	ret = led_classdev_register(&pdev->dev, &spitz_amber_led);
-	if (ret < 0)
-		return ret;
-
-	ret = led_classdev_register(&pdev->dev, &spitz_green_led);
-	if (ret < 0)
-		led_classdev_unregister(&spitz_amber_led);
-
-	return ret;
-}
-
-static int spitzled_remove(struct platform_device *pdev)
-{
-	led_classdev_unregister(&spitz_amber_led);
-	led_classdev_unregister(&spitz_green_led);
-
-	return 0;
-}
-
-static struct platform_driver spitzled_driver = {
-	.probe		= spitzled_probe,
-	.remove		= spitzled_remove,
-#ifdef CONFIG_PM
-	.suspend	= spitzled_suspend,
-	.resume		= spitzled_resume,
-#endif
-	.driver		= {
-		.name		= "spitz-led",
-		.owner		= THIS_MODULE,
-	},
-};
-
-static int __init spitzled_init(void)
-{
-	return platform_driver_register(&spitzled_driver);
-}
-
-static void __exit spitzled_exit(void)
-{
-	platform_driver_unregister(&spitzled_driver);
-}
-
-module_init(spitzled_init);
-module_exit(spitzled_exit);
-
-MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
-MODULE_DESCRIPTION("Spitz LED driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:spitz-led");
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index e8bc7ab..99be9e5 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -1068,7 +1068,7 @@
 	{
 		v4l2_std_id *id = arg;
 		int found = 0;
-		int i, err;
+		int i;
 
 		DEB_EE(("VIDIOC_S_STD\n"));
 
@@ -1116,7 +1116,6 @@
 	case VIDIOC_OVERLAY:
 	{
 		int on = *(int *)arg;
-		int err = 0;
 
 		DEB_D(("VIDIOC_OVERLAY on:%d\n",on));
 		if (on != 0) {
@@ -1192,7 +1191,6 @@
 	case VIDIOCGMBUF:
 	{
 		struct video_mbuf *mbuf = arg;
-		struct videobuf_queue *q;
 		int i;
 
 		/* fixme: number of capture buffers and sizes for v4l apps */
diff --git a/drivers/media/common/tuners/mt2131.c b/drivers/media/common/tuners/mt2131.c
index e254bcf..e8d3c48 100644
--- a/drivers/media/common/tuners/mt2131.c
+++ b/drivers/media/common/tuners/mt2131.c
@@ -1,7 +1,7 @@
 /*
  *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
  *
- *  Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/common/tuners/mt2131.h b/drivers/media/common/tuners/mt2131.h
index cd8376f..6632de6 100644
--- a/drivers/media/common/tuners/mt2131.h
+++ b/drivers/media/common/tuners/mt2131.h
@@ -1,7 +1,7 @@
 /*
  *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
  *
- *  Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/common/tuners/mt2131_priv.h b/drivers/media/common/tuners/mt2131_priv.h
index e930759..4e05a67 100644
--- a/drivers/media/common/tuners/mt2131_priv.h
+++ b/drivers/media/common/tuners/mt2131_priv.h
@@ -1,7 +1,7 @@
 /*
  *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
  *
- *  Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c
index 0dc2bef..227642b 100644
--- a/drivers/media/common/tuners/mxl5005s.c
+++ b/drivers/media/common/tuners/mxl5005s.c
@@ -2,7 +2,7 @@
     MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
 
     Copyright (C) 2008 MaxLinear
-    Copyright (C) 2006 Steven Toth <stoth@hauppauge.com>
+    Copyright (C) 2006 Steven Toth <stoth@linuxtv.org>
       Functions:
 	mxl5005s_reset()
 	mxl5005s_writereg()
@@ -3837,7 +3837,7 @@
 /* ----------------------------------------------------------------
  * Begin: Everything after here is new code to adapt the
  * proprietary Realtek driver into a Linux API tuner.
- * Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+ * Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
  */
 static int mxl5005s_reset(struct dvb_frontend *fe)
 {
diff --git a/drivers/media/common/tuners/mxl5005s.h b/drivers/media/common/tuners/mxl5005s.h
index 396db15..7ac6815 100644
--- a/drivers/media/common/tuners/mxl5005s.h
+++ b/drivers/media/common/tuners/mxl5005s.h
@@ -2,7 +2,7 @@
     MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
 
     Copyright (C) 2008 MaxLinear
-    Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c
index 597e47f..aa773a6 100644
--- a/drivers/media/common/tuners/tuner-simple.c
+++ b/drivers/media/common/tuners/tuner-simple.c
@@ -253,7 +253,7 @@
 
 static int simple_config_lookup(struct dvb_frontend *fe,
 				struct tuner_params *t_params,
-				int *frequency, u8 *config, u8 *cb)
+				unsigned *frequency, u8 *config, u8 *cb)
 {
 	struct tuner_simple_priv *priv = fe->tuner_priv;
 	int i;
@@ -587,45 +587,45 @@
 	priv->last_div = div;
 	if (t_params->has_tda9887) {
 		struct v4l2_priv_tun_config tda9887_cfg;
-		int config = 0;
+		int tda_config = 0;
 		int is_secam_l = (params->std & (V4L2_STD_SECAM_L |
 						 V4L2_STD_SECAM_LC)) &&
 			!(params->std & ~(V4L2_STD_SECAM_L |
 					  V4L2_STD_SECAM_LC));
 
 		tda9887_cfg.tuner = TUNER_TDA9887;
-		tda9887_cfg.priv  = &config;
+		tda9887_cfg.priv  = &tda_config;
 
 		if (params->std == V4L2_STD_SECAM_LC) {
 			if (t_params->port1_active ^ t_params->port1_invert_for_secam_lc)
-				config |= TDA9887_PORT1_ACTIVE;
+				tda_config |= TDA9887_PORT1_ACTIVE;
 			if (t_params->port2_active ^ t_params->port2_invert_for_secam_lc)
-				config |= TDA9887_PORT2_ACTIVE;
+				tda_config |= TDA9887_PORT2_ACTIVE;
 		} else {
 			if (t_params->port1_active)
-				config |= TDA9887_PORT1_ACTIVE;
+				tda_config |= TDA9887_PORT1_ACTIVE;
 			if (t_params->port2_active)
-				config |= TDA9887_PORT2_ACTIVE;
+				tda_config |= TDA9887_PORT2_ACTIVE;
 		}
 		if (t_params->intercarrier_mode)
-			config |= TDA9887_INTERCARRIER;
+			tda_config |= TDA9887_INTERCARRIER;
 		if (is_secam_l) {
 			if (i == 0 && t_params->default_top_secam_low)
-				config |= TDA9887_TOP(t_params->default_top_secam_low);
+				tda_config |= TDA9887_TOP(t_params->default_top_secam_low);
 			else if (i == 1 && t_params->default_top_secam_mid)
-				config |= TDA9887_TOP(t_params->default_top_secam_mid);
+				tda_config |= TDA9887_TOP(t_params->default_top_secam_mid);
 			else if (t_params->default_top_secam_high)
-				config |= TDA9887_TOP(t_params->default_top_secam_high);
+				tda_config |= TDA9887_TOP(t_params->default_top_secam_high);
 		} else {
 			if (i == 0 && t_params->default_top_low)
-				config |= TDA9887_TOP(t_params->default_top_low);
+				tda_config |= TDA9887_TOP(t_params->default_top_low);
 			else if (i == 1 && t_params->default_top_mid)
-				config |= TDA9887_TOP(t_params->default_top_mid);
+				tda_config |= TDA9887_TOP(t_params->default_top_mid);
 			else if (t_params->default_top_high)
-				config |= TDA9887_TOP(t_params->default_top_high);
+				tda_config |= TDA9887_TOP(t_params->default_top_high);
 		}
 		if (t_params->default_pll_gating_18)
-			config |= TDA9887_GATING_18;
+			tda_config |= TDA9887_GATING_18;
 		i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG,
 				    &tda9887_cfg);
 	}
@@ -813,7 +813,8 @@
 	static struct tuner_params *t_params;
 	u8 config, cb;
 	u32 div;
-	int ret, frequency = params->frequency / 62500;
+	int ret;
+	unsigned frequency = params->frequency / 62500;
 
 	t_params = simple_tuner_params(fe, TUNER_PARAM_TYPE_DIGITAL);
 	ret = simple_config_lookup(fe, t_params, &frequency, &config, &cb);
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index 5f99de0..dcddfa8 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -2,7 +2,7 @@
  *  Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
  *
  *  Copyright (c) 2007 Xceive Corporation
- *  Copyright (c) 2007 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h
index c910715..5389f74 100644
--- a/drivers/media/common/tuners/xc5000.h
+++ b/drivers/media/common/tuners/xc5000.h
@@ -1,7 +1,7 @@
 /*
  *  Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
  *
- *  Copyright (c) 2007 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/common/tuners/xc5000_priv.h b/drivers/media/common/tuners/xc5000_priv.h
index a72a988..b2a0074 100644
--- a/drivers/media/common/tuners/xc5000_priv.h
+++ b/drivers/media/common/tuners/xc5000_priv.h
@@ -1,7 +1,7 @@
 /*
  *  Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
  *
- *  Copyright (c) 2007 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index f9d0876..4eed783 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -137,7 +137,8 @@
 			flexcop_diseqc_send_byte(fe, 0xff);
 		else {
 			flexcop_set_tone(fe, SEC_TONE_ON);
-			udelay(12500);
+			mdelay(12);
+			udelay(500);
 			flexcop_set_tone(fe, SEC_TONE_OFF);
 		}
 		msleep(20);
diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c
index 55973ea..43a112e 100644
--- a/drivers/media/dvb/b2c2/flexcop-i2c.c
+++ b/drivers/media/dvb/b2c2/flexcop-i2c.c
@@ -221,12 +221,12 @@
 	fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM;
 	fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER;
 
-	strncpy(fc->fc_i2c_adap[0].i2c_adap.name,
-		"B2C2 FlexCop I2C to demod", I2C_NAME_SIZE);
-	strncpy(fc->fc_i2c_adap[1].i2c_adap.name,
-		"B2C2 FlexCop I2C to eeprom", I2C_NAME_SIZE);
-	strncpy(fc->fc_i2c_adap[2].i2c_adap.name,
-		"B2C2 FlexCop I2C to tuner", I2C_NAME_SIZE);
+	strlcpy(fc->fc_i2c_adap[0].i2c_adap.name, "B2C2 FlexCop I2C to demod",
+		sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
+	strlcpy(fc->fc_i2c_adap[1].i2c_adap.name, "B2C2 FlexCop I2C to eeprom",
+		sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
+	strlcpy(fc->fc_i2c_adap[2].i2c_adap.name, "B2C2 FlexCop I2C to tuner",
+		sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
 
 	i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]);
 	i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]);
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index a763756..aa3db57 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -1244,7 +1244,7 @@
 		goto error;
 	}
 	if (state->type_flags & DST_TYPE_HAS_FW_1)
-		udelay(3000);
+		mdelay(3);
 	if (read_dst(state, &reply, GET_ACK)) {
 		dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
 		if ((dst_error_recovery(state)) < 0) {
@@ -1260,7 +1260,7 @@
 	if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
 		goto error;
 	if (state->type_flags & DST_TYPE_HAS_FW_1)
-		udelay(3000);
+		mdelay(3);
 	else
 		udelay(2000);
 	if (!dst_wait_dst_ready(state, NO_DELAY))
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 1cf9fcb..069d847 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -641,7 +641,6 @@
 		struct timespec timeout = { 0 };
 		struct dmx_pes_filter_params *para = &filter->params.pes;
 		dmx_output_t otype;
-		int ret;
 		int ts_type;
 		enum dmx_ts_pes ts_pes;
 		struct dmx_ts_feed **tsfeed = &filter->feed.ts;
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 8e5dd7b..98ee167 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -1032,7 +1032,7 @@
 					/* we need this extra check for annoying interfaces like the budget-av */
 					if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) &&
 					    (ca->pub->poll_slot_status)) {
-						int status = ca->pub->poll_slot_status(ca->pub, slot, 0);
+						status = ca->pub->poll_slot_status(ca->pub, slot, 0);
 						if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) {
 							ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
 							dvb_ca_en50221_thread_update_delay(ca);
@@ -1089,7 +1089,7 @@
 					/* we need this extra check for annoying interfaces like the budget-av */
 					if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) &&
 					    (ca->pub->poll_slot_status)) {
-						int status = ca->pub->poll_slot_status(ca->pub, slot, 0);
+						status = ca->pub->poll_slot_status(ca->pub, slot, 0);
 						if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) {
 							ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
 							dvb_ca_en50221_thread_update_delay(ca);
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 8cbdb21..3526e3e 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -889,13 +889,13 @@
 			 * initialization, so parg is 8 bits and does not
 			 * include the initialization or start bit
 			 */
-			unsigned long cmd = ((unsigned long) parg) << 1;
+			unsigned long swcmd = ((unsigned long) parg) << 1;
 			struct timeval nexttime;
 			struct timeval tv[10];
 			int i;
 			u8 last = 1;
 			if (dvb_frontend_debug)
-				printk("%s switch command: 0x%04lx\n", __func__, cmd);
+				printk("%s switch command: 0x%04lx\n", __func__, swcmd);
 			do_gettimeofday(&nexttime);
 			if (dvb_frontend_debug)
 				memcpy(&tv[0], &nexttime, sizeof(struct timeval));
@@ -908,12 +908,12 @@
 			for (i = 0; i < 9; i++) {
 				if (dvb_frontend_debug)
 					do_gettimeofday(&tv[i + 1]);
-				if ((cmd & 0x01) != last) {
+				if ((swcmd & 0x01) != last) {
 					/* set voltage to (last ? 13V : 18V) */
 					fe->ops.set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18);
 					last = (last) ? 0 : 1;
 				}
-				cmd = cmd >> 1;
+				swcmd = swcmd >> 1;
 				if (i != 8)
 					dvb_frontend_sleep_until(&nexttime, 8000);
 			}
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index aaa0b6f..5634002 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -210,7 +210,7 @@
 	if (d->state == DVB_USB_STATE_INIT &&
 	    usb_set_interface(d->udev, 0, 0) < 0)
 		err("set interface failed");
-	do; while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) &&
+	do {} while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) &&
 		   !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) &&
 		   !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0);
 	if (!ret) {
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 3dd20bf..6c0e5c5 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -1117,7 +1117,8 @@
 	{ USB_DEVICE(USB_VID_TERRATEC,	USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
 	{ USB_DEVICE(USB_VID_TERRATEC,	USB_PID_TERRATEC_CINERGY_T_XXS) },
 	{ USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
-	{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
+/* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
+	{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) },
 	{ 0 }		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1373,7 +1374,7 @@
 			}
 		},
 
-		.num_device_descs = 3,
+		.num_device_descs = 4,
 		.devices = {
 			{   "DiBcom STK7070PD reference design",
 				{ &dib0700_usb_id_table[17], NULL },
@@ -1386,6 +1387,10 @@
 			{   "Hauppauge Nova-TD Stick (52009)",
 				{ &dib0700_usb_id_table[35], NULL },
 				{ NULL },
+			},
+			{   "Hauppauge Nova-TD-500 (84xxx)",
+				{ &dib0700_usb_id_table[36], NULL },
+				{ NULL },
 			}
 		}
 	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 029b437..03dfb9f 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -129,6 +129,7 @@
 #define USB_PID_WINTV_NOVA_T_USB2_WARM			0x9301
 #define USB_PID_HAUPPAUGE_NOVA_T_500			0x9941
 #define USB_PID_HAUPPAUGE_NOVA_T_500_2			0x9950
+#define USB_PID_HAUPPAUGE_NOVA_T_500_3			0x8400
 #define USB_PID_HAUPPAUGE_NOVA_T_STICK			0x7050
 #define USB_PID_HAUPPAUGE_NOVA_T_STICK_2		0x7060
 #define USB_PID_HAUPPAUGE_NOVA_T_STICK_3		0x7070
diff --git a/drivers/media/dvb/frontends/au8522.c b/drivers/media/dvb/frontends/au8522.c
index f7b7165..0b82cc2 100644
--- a/drivers/media/dvb/frontends/au8522.c
+++ b/drivers/media/dvb/frontends/au8522.c
@@ -1,7 +1,7 @@
 /*
     Auvitek AU8522 QAM/8VSB demodulator driver
 
-    Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -304,6 +304,43 @@
 	return ret;
 }
 
+static int au8522_set_if(struct dvb_frontend *fe, enum au8522_if_freq if_freq)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+	u8 r0b5, r0b6, r0b7;
+	char *ifmhz;
+
+	switch (if_freq) {
+	case AU8522_IF_3_25MHZ:
+		ifmhz = "3.25";
+		r0b5 = 0x00;
+		r0b6 = 0x3d;
+		r0b7 = 0xa0;
+		break;
+	case AU8522_IF_4MHZ:
+		ifmhz = "4.00";
+		r0b5 = 0x00;
+		r0b6 = 0x4b;
+		r0b7 = 0xd9;
+		break;
+	case AU8522_IF_6MHZ:
+		ifmhz = "6.00";
+		r0b5 = 0xfb;
+		r0b6 = 0x8e;
+		r0b7 = 0x39;
+		break;
+	default:
+		dprintk("%s() IF Frequency not supported\n", __func__);
+		return -EINVAL;
+	}
+	dprintk("%s() %s MHz\n", __func__, ifmhz);
+	au8522_writereg(state, 0x80b5, r0b5);
+	au8522_writereg(state, 0x80b6, r0b6);
+	au8522_writereg(state, 0x80b7, r0b7);
+
+	return 0;
+}
+
 /* VSB Modulation table */
 static struct {
 	u16 reg;
@@ -334,9 +371,6 @@
 	{ 0x80af, 0x66 },
 	{ 0x821b, 0xcc },
 	{ 0x821d, 0x80 },
-	{ 0x80b5, 0xfb },
-	{ 0x80b6, 0x8e },
-	{ 0x80b7, 0x39 },
 	{ 0x80a4, 0xe8 },
 	{ 0x8231, 0x13 },
 };
@@ -350,9 +384,6 @@
 	{ 0x80a4, 0x00 },
 	{ 0x8081, 0xc4 },
 	{ 0x80a5, 0x40 },
-	{ 0x80b5, 0xfb },
-	{ 0x80b6, 0x8e },
-	{ 0x80b7, 0x39 },
 	{ 0x80aa, 0x77 },
 	{ 0x80ad, 0x77 },
 	{ 0x80a6, 0x67 },
@@ -438,6 +469,7 @@
 			au8522_writereg(state,
 				VSB_mod_tab[i].reg,
 				VSB_mod_tab[i].data);
+		au8522_set_if(fe, state->config->vsb_if);
 		break;
 	case QAM_64:
 	case QAM_256:
@@ -446,6 +478,7 @@
 			au8522_writereg(state,
 				QAM_mod_tab[i].reg,
 				QAM_mod_tab[i].data);
+		au8522_set_if(fe, state->config->qam_if);
 		break;
 	default:
 		dprintk("%s() Invalid modulation\n", __func__);
diff --git a/drivers/media/dvb/frontends/au8522.h b/drivers/media/dvb/frontends/au8522.h
index d7affa3..595915a 100644
--- a/drivers/media/dvb/frontends/au8522.h
+++ b/drivers/media/dvb/frontends/au8522.h
@@ -1,7 +1,7 @@
 /*
     Auvitek AU8522 QAM/8VSB demodulator driver
 
-    Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -24,6 +24,12 @@
 
 #include <linux/dvb/frontend.h>
 
+enum au8522_if_freq {
+	AU8522_IF_6MHZ = 0,
+	AU8522_IF_4MHZ,
+	AU8522_IF_3_25MHZ,
+};
+
 struct au8522_config {
 	/* the demodulator's i2c address */
 	u8 demod_address;
@@ -32,6 +38,9 @@
 #define AU8522_TUNERLOCKING 0
 #define AU8522_DEMODLOCKING 1
 	u8 status_mode;
+
+	enum au8522_if_freq vsb_if;
+	enum au8522_if_freq qam_if;
 };
 
 #if defined(CONFIG_DVB_AU8522) || 				\
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
index cc1db4e..9430e03 100644
--- a/drivers/media/dvb/frontends/cx22702.c
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -7,7 +7,7 @@
     Copyright (C) 2001-2002 Convergence Integrated Media GmbH
 	  Holger Waechtler <holger@convergence.de>
 
-    Copyright (C) 2004 Steven Toth <stoth@hauppauge.com>
+    Copyright (C) 2004 Steven Toth <stoth@linuxtv.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h
index 8af766a..b1e465c 100644
--- a/drivers/media/dvb/frontends/cx22702.h
+++ b/drivers/media/dvb/frontends/cx22702.h
@@ -7,7 +7,7 @@
     Copyright (C) 2001-2002 Convergence Integrated Media GmbH
 	  Holger Waechtler <holger@convergence.de>
 
-    Copyright (C) 2004 Steven Toth <stoth@hauppauge.com>
+    Copyright (C) 2004 Steven Toth <stoth@linuxtv.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c
index 7f68d78..7156157 100644
--- a/drivers/media/dvb/frontends/cx24123.c
+++ b/drivers/media/dvb/frontends/cx24123.c
@@ -1,7 +1,7 @@
 /*
  *   Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
  *
- *   Copyright (C) 2005 Steven Toth <stoth@hauppauge.com>
+ *   Copyright (C) 2005 Steven Toth <stoth@linuxtv.org>
  *
  *   Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc>
  *
@@ -1072,8 +1072,8 @@
     if (config->dont_use_pll)
 	cx24123_repeater_mode(state, 1, 0);
 
-	strncpy(state->tuner_i2c_adapter.name,
-		"CX24123 tuner I2C bus", I2C_NAME_SIZE);
+	strlcpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus",
+		sizeof(state->tuner_i2c_adapter.name));
 	state->tuner_i2c_adapter.class     = I2C_CLASS_TV_DIGITAL,
 	state->tuner_i2c_adapter.algo      = &cx24123_tuner_i2c_algo;
 	state->tuner_i2c_adapter.algo_data = NULL;
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h
index 81ebc3d..cc6b411 100644
--- a/drivers/media/dvb/frontends/cx24123.h
+++ b/drivers/media/dvb/frontends/cx24123.h
@@ -1,7 +1,7 @@
 /*
     Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
 
-    Copyright (C) 2005 Steven Toth <stoth@hauppauge.com>
+    Copyright (C) 2005 Steven Toth <stoth@linuxtv.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c
index 5ddb2dc..7500a1c 100644
--- a/drivers/media/dvb/frontends/s5h1409.c
+++ b/drivers/media/dvb/frontends/s5h1409.c
@@ -1,7 +1,7 @@
 /*
     Samsung S5H1409 VSB/QAM demodulator driver
 
-    Copyright (C) 2006 Steven Toth <stoth@hauppauge.com>
+    Copyright (C) 2006 Steven Toth <stoth@linuxtv.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -404,6 +404,7 @@
 		break;
 	case QAM_64:
 	case QAM_256:
+	case QAM_AUTO:
 		dprintk("%s() QAM_AUTO (64/256)\n", __func__);
 		if (state->if_freq != S5H1409_QAM_IF_FREQ)
 			s5h1409_set_if_freq(fe, S5H1409_QAM_IF_FREQ);
diff --git a/drivers/media/dvb/frontends/s5h1409.h b/drivers/media/dvb/frontends/s5h1409.h
index 59f4335..d1a1d2e 100644
--- a/drivers/media/dvb/frontends/s5h1409.h
+++ b/drivers/media/dvb/frontends/s5h1409.h
@@ -1,7 +1,7 @@
 /*
     Samsung S5H1409 VSB/QAM demodulator driver
 
-    Copyright (C) 2006 Steven Toth <stoth@hauppauge.com>
+    Copyright (C) 2006 Steven Toth <stoth@linuxtv.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c
index cff360c..2da1a37 100644
--- a/drivers/media/dvb/frontends/s5h1411.c
+++ b/drivers/media/dvb/frontends/s5h1411.c
@@ -1,7 +1,7 @@
 /*
     Samsung S5H1411 VSB/QAM demodulator driver
 
-    Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -488,6 +488,7 @@
 		break;
 	case QAM_64:
 	case QAM_256:
+	case QAM_AUTO:
 		dprintk("%s() QAM_AUTO (64/256)\n", __func__);
 		s5h1411_set_if_freq(fe, state->config->qam_if);
 		s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x0171);
diff --git a/drivers/media/dvb/frontends/s5h1411.h b/drivers/media/dvb/frontends/s5h1411.h
index 1855f64..7d542bc 100644
--- a/drivers/media/dvb/frontends/s5h1411.h
+++ b/drivers/media/dvb/frontends/s5h1411.h
@@ -1,7 +1,7 @@
 /*
     Samsung S5H1411 VSB/QAM demodulator driver
 
-    Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
index 720ed9f..747d3fa 100644
--- a/drivers/media/dvb/frontends/s5h1420.c
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -915,7 +915,8 @@
 	state->frontend.demodulator_priv = state;
 
 	/* create tuner i2c adapter */
-	strncpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus", I2C_NAME_SIZE);
+	strlcpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus",
+		sizeof(state->tuner_i2c_adapter.name));
 	state->tuner_i2c_adapter.class     = I2C_CLASS_TV_DIGITAL,
 	state->tuner_i2c_adapter.algo      = &s5h1420_tuner_i2c_algo;
 	state->tuner_i2c_adapter.algo_data = NULL;
diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c
index 0ab8d86b..04e7f1c 100644
--- a/drivers/media/dvb/frontends/tda10048.c
+++ b/drivers/media/dvb/frontends/tda10048.c
@@ -1,7 +1,7 @@
 /*
     NXP TDA10048HN DVB OFDM demodulator driver
 
-    Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -303,7 +303,7 @@
 
 	if (fw->size != TDA10048_DEFAULT_FIRMWARE_SIZE) {
 		printk(KERN_ERR "%s: firmware incorrect size\n", __func__);
-		return -EIO;
+		ret = -EIO;
 	} else {
 		printk(KERN_INFO "%s: firmware uploading\n", __func__);
 
diff --git a/drivers/media/dvb/frontends/tda10048.h b/drivers/media/dvb/frontends/tda10048.h
index 2b5c78e..0457b24 100644
--- a/drivers/media/dvb/frontends/tda10048.h
+++ b/drivers/media/dvb/frontends/tda10048.h
@@ -1,7 +1,7 @@
 /*
     NXP TDA10048HN DVB OFDM demodulator driver
 
-    Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
index e7a8ac0..cc5efb6 100644
--- a/drivers/media/dvb/siano/sms-cards.c
+++ b/drivers/media/dvb/siano/sms-cards.c
@@ -4,7 +4,7 @@
  *  Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3 as
+ *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation;
  *
  *  Software distributed under the License is distributed on an "AS IS"
diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h
index 83b39bc..c8f3da6 100644
--- a/drivers/media/dvb/siano/sms-cards.h
+++ b/drivers/media/dvb/siano/sms-cards.h
@@ -4,7 +4,7 @@
  *  Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3 as
+ *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation;
  *
  *  Software distributed under the License is distributed on an "AS IS"
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
index c5f45fe..6576fbb 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -8,7 +8,7 @@
  *  Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
  *
  *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3 as
+ *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation;
  *
  *  Software distributed under the License is distributed on an "AS IS"
diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h
index c1f8f1d..8d973f7 100644
--- a/drivers/media/dvb/siano/smscoreapi.h
+++ b/drivers/media/dvb/siano/smscoreapi.h
@@ -6,7 +6,7 @@
  *  Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
  *
  *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3 as
+ *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation;
  *
  *  Software distributed under the License is distributed on an "AS IS"
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c
index 229274a..8d490e1 100644
--- a/drivers/media/dvb/siano/smsdvb.c
+++ b/drivers/media/dvb/siano/smsdvb.c
@@ -6,7 +6,7 @@
  *  Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
  *
  *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3 as
+ *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation;
  *
  *  Software distributed under the License is distributed on an "AS IS"
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
index c10b184..87a3c24 100644
--- a/drivers/media/dvb/siano/smsusb.c
+++ b/drivers/media/dvb/siano/smsusb.c
@@ -6,7 +6,7 @@
  *  Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
  *
  *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3 as
+ *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation;
  *
  *  Software distributed under the License is distributed on an "AS IS"
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
index 39bd0a2..aa5ed4e 100644
--- a/drivers/media/dvb/ttpci/budget-patch.c
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -116,7 +116,8 @@
 			DiseqcSendByte(budget, 0xff);
 		else {
 			saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
-			udelay(12500);
+			mdelay(12);
+			udelay(500);
 			saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
 		}
 		msleep(20);
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 2293d80..f006899 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -108,7 +108,8 @@
 			DiseqcSendByte(budget, 0xff);
 		else {
 			saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
-			udelay(12500);
+			mdelay(12);
+			udelay(500);
 			saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
 		}
 		msleep(20);
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index a30159f..7ca71ab 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -2,8 +2,6 @@
 # Makefile for the kernel character device drivers.
 #
 
-miropcm20-objs	:= miropcm20-rds-core.o miropcm20-radio.o
-
 obj-$(CONFIG_RADIO_AZTECH) += radio-aztech.o
 obj-$(CONFIG_RADIO_RTRACK2) += radio-rtrack2.o
 obj-$(CONFIG_RADIO_SF16FMI) += radio-sf16fmi.o
@@ -14,8 +12,6 @@
 obj-$(CONFIG_RADIO_MAXIRADIO) += radio-maxiradio.o
 obj-$(CONFIG_RADIO_RTRACK) += radio-aimslab.o
 obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o
-obj-$(CONFIG_RADIO_MIROPCM20) += miropcm20.o
-obj-$(CONFIG_RADIO_MIROPCM20_RDS) += miropcm20-rds.o
 obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o
 obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o
 obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index 1ed88f3..70c65a7 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -493,7 +493,7 @@
 	radio->usbdev = interface_to_usbdev(intf);
 	radio->curfreq = FREQ_MIN*FREQ_MUL;
 	video_set_drvdata(radio->videodev, radio);
-	if (video_register_device(radio->videodev, VFL_TYPE_RADIO,radio_nr)) {
+	if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr) < 0) {
 		warn("Could not register video device");
 		video_device_release(radio->videodev);
 		kfree(radio->transfer_buffer);
diff --git a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c
deleted file mode 100644
index 7fd7ee2..0000000
--- a/drivers/media/radio/miropcm20-radio.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/* Miro PCM20 radio driver for Linux radio support
- * (c) 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
- * Thanks to Norberto Pellici for the ACI device interface specification
- * The API part is based on the radiotrack driver by M. Kirkwood
- * This driver relies on the aci mixer (drivers/sound/aci.c)
- * Look there for further info...
- */
-
-/* Revision history:
- *
- *   1998        Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
- *   2000-09-05  Robert Siemer <Robert.Siemer@gmx.de>
- *        removed unfinished volume control (maybe adding it later again)
- *        use OSS-mixer; added stereo control
- */
-
-/* What ever you think about the ACI, version 0x07 is not very well!
- * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono
- * conditions...                Robert
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include "oss/aci.h"
-#include "miropcm20-rds-core.h"
-
-static int radio_nr = -1;
-module_param(radio_nr, int, 0);
-
-struct pcm20_device {
-	unsigned long freq;
-	int muted;
-	int stereo;
-};
-
-
-static int pcm20_mute(struct pcm20_device *dev, unsigned char mute)
-{
-	dev->muted = mute;
-	return aci_write_cmd(ACI_SET_TUNERMUTE, mute);
-}
-
-static int pcm20_stereo(struct pcm20_device *dev, unsigned char stereo)
-{
-	dev->stereo = stereo;
-	return aci_write_cmd(ACI_SET_TUNERMONO, !stereo);
-}
-
-static int pcm20_setfreq(struct pcm20_device *dev, unsigned long freq)
-{
-	unsigned char freql;
-	unsigned char freqh;
-
-	dev->freq=freq;
-
-	freq /= 160;
-	if (!(aci_version==0x07 || aci_version>=0xb0))
-		freq /= 10;  /* I don't know exactly which version
-			      * needs this hack */
-	freql = freq & 0xff;
-	freqh = freq >> 8;
-
-	aci_rds_cmd(RDS_RESET, NULL, 0);
-	pcm20_stereo(dev, 1);
-
-	return aci_rw_cmd(ACI_WRITE_TUNE, freql, freqh);
-}
-
-static int pcm20_getflags(struct pcm20_device *dev, __u32 *flags, __u16 *signal)
-{
-	/* okay, check for signal, stereo and rds here... */
-	int i;
-	unsigned char buf;
-
-	if ((i=aci_rw_cmd(ACI_READ_TUNERSTATION, -1, -1))<0)
-		return i;
-	pr_debug("check_sig: 0x%x\n", i);
-	if (i & 0x80) {
-		/* no signal from tuner */
-		*flags=0;
-		*signal=0;
-		return 0;
-	} else
-		*signal=0xffff;
-
-	if ((i=aci_rw_cmd(ACI_READ_TUNERSTEREO, -1, -1))<0)
-		return i;
-	if (i & 0x40) {
-		*flags=0;
-	} else {
-		/* stereo */
-		*flags=VIDEO_TUNER_STEREO_ON;
-		/* I can't see stereo, when forced to mono */
-		dev->stereo=1;
-	}
-
-	if ((i=aci_rds_cmd(RDS_STATUS, &buf, 1))<0)
-		return i;
-	if (buf & 1)
-		/* RDS available */
-		*flags|=VIDEO_TUNER_RDS_ON;
-	else
-		return 0;
-
-	if ((i=aci_rds_cmd(RDS_RXVALUE, &buf, 1))<0)
-		return i;
-	pr_debug("rds-signal: %d\n", buf);
-	if (buf > 15) {
-		printk("miropcm20-radio: RX strengths unexpected high...\n");
-		buf=15;
-	}
-	/* refine signal */
-	if ((*signal=SCALE(15, 0xffff, buf))==0)
-		*signal = 1;
-
-	return 0;
-}
-
-static int pcm20_do_ioctl(struct inode *inode, struct file *file,
-			  unsigned int cmd, void *arg)
-{
-	struct video_device *dev = video_devdata(file);
-	struct pcm20_device *pcm20 = dev->priv;
-	int i;
-
-	switch(cmd)
-	{
-		case VIDIOCGCAP:
-		{
-			struct video_capability *v = arg;
-			memset(v,0,sizeof(*v));
-			v->type=VID_TYPE_TUNER;
-			strcpy(v->name, "Miro PCM20");
-			v->channels=1;
-			v->audios=1;
-			return 0;
-		}
-		case VIDIOCGTUNER:
-		{
-			struct video_tuner *v = arg;
-			if(v->tuner)	/* Only 1 tuner */
-				return -EINVAL;
-			v->rangelow=87*16000;
-			v->rangehigh=108*16000;
-			pcm20_getflags(pcm20, &v->flags, &v->signal);
-			v->flags|=VIDEO_TUNER_LOW;
-			v->mode=VIDEO_MODE_AUTO;
-			strcpy(v->name, "FM");
-			return 0;
-		}
-		case VIDIOCSTUNER:
-		{
-			struct video_tuner *v = arg;
-			if(v->tuner!=0)
-				return -EINVAL;
-			/* Only 1 tuner so no setting needed ! */
-			return 0;
-		}
-		case VIDIOCGFREQ:
-		{
-			unsigned long *freq = arg;
-			*freq = pcm20->freq;
-			return 0;
-		}
-		case VIDIOCSFREQ:
-		{
-			unsigned long *freq = arg;
-			pcm20->freq = *freq;
-			i=pcm20_setfreq(pcm20, pcm20->freq);
-			pr_debug("First view (setfreq): 0x%x\n", i);
-			return i;
-		}
-		case VIDIOCGAUDIO:
-		{
-			struct video_audio *v = arg;
-			memset(v,0, sizeof(*v));
-			v->flags=VIDEO_AUDIO_MUTABLE;
-			if (pcm20->muted)
-				v->flags|=VIDEO_AUDIO_MUTE;
-			v->mode=VIDEO_SOUND_STEREO;
-			if (pcm20->stereo)
-				v->mode|=VIDEO_SOUND_MONO;
-			/* v->step=2048; */
-			strcpy(v->name, "Radio");
-			return 0;
-		}
-		case VIDIOCSAUDIO:
-		{
-			struct video_audio *v = arg;
-			if(v->audio)
-				return -EINVAL;
-
-			pcm20_mute(pcm20, !!(v->flags&VIDEO_AUDIO_MUTE));
-			if(v->flags&VIDEO_SOUND_MONO)
-				pcm20_stereo(pcm20, 0);
-			if(v->flags&VIDEO_SOUND_STEREO)
-				pcm20_stereo(pcm20, 1);
-
-			return 0;
-		}
-		default:
-			return -ENOIOCTLCMD;
-	}
-}
-
-static int pcm20_ioctl(struct inode *inode, struct file *file,
-		       unsigned int cmd, unsigned long arg)
-{
-	return video_usercopy(inode, file, cmd, arg, pcm20_do_ioctl);
-}
-
-static struct pcm20_device pcm20_unit = {
-	.freq   = 87*16000,
-	.muted  = 1,
-};
-
-static const struct file_operations pcm20_fops = {
-	.owner		= THIS_MODULE,
-	.open           = video_exclusive_open,
-	.release        = video_exclusive_release,
-	.ioctl		= pcm20_ioctl,
-#ifdef CONFIG_COMPAT
-	.compat_ioctl	= v4l_compat_ioctl32,
-#endif
-	.llseek         = no_llseek,
-};
-
-static struct video_device pcm20_radio = {
-	.name		= "Miro PCM 20 radio",
-	.fops           = &pcm20_fops,
-	.priv		= &pcm20_unit
-};
-
-static int __init pcm20_init(void)
-{
-	if(video_register_device(&pcm20_radio, VFL_TYPE_RADIO, radio_nr)==-1)
-		goto video_register_device;
-
-	if(attach_aci_rds()<0)
-		goto attach_aci_rds;
-
-	printk(KERN_INFO "Miro PCM20 radio card driver.\n");
-
-	return 0;
-
- attach_aci_rds:
-	video_unregister_device(&pcm20_radio);
- video_register_device:
-	return -EINVAL;
-}
-
-MODULE_AUTHOR("Ruurd Reitsma");
-MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card.");
-MODULE_LICENSE("GPL");
-
-static void __exit pcm20_cleanup(void)
-{
-	unload_aci_rds();
-	video_unregister_device(&pcm20_radio);
-}
-
-module_init(pcm20_init);
-module_exit(pcm20_cleanup);
diff --git a/drivers/media/radio/miropcm20-rds-core.c b/drivers/media/radio/miropcm20-rds-core.c
deleted file mode 100644
index 9428d8b..0000000
--- a/drivers/media/radio/miropcm20-rds-core.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- *  Many thanks to Fred Seidel <seidel@metabox.de>, the
- *  designer of the RDS decoder hardware. With his help
- *  I was able to code this driver.
- *  Thanks also to Norberto Pellicci, Dominic Mounteney
- *  <DMounteney@pinnaclesys.com> and www.teleauskunft.de
- *  for good hints on finding Fred. It was somewhat hard
- *  to locate him here in Germany... [:
- *
- * Revision history:
- *
- *   2000-08-09  Robert Siemer <Robert.Siemer@gmx.de>
- *        RDS support for MiroSound PCM20 radio
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-
-#include <asm/io.h>
-#include "oss/aci.h"
-#include "miropcm20-rds-core.h"
-
-#define DEBUG 0
-
-static struct mutex aci_rds_mutex;
-
-#define RDS_DATASHIFT          2   /* Bit 2 */
-#define RDS_DATAMASK        (1 << RDS_DATASHIFT)
-#define RDS_BUSYMASK        0x10   /* Bit 4 */
-#define RDS_CLOCKMASK       0x08   /* Bit 3 */
-
-#define RDS_DATA(x)         (((x) >> RDS_DATASHIFT) & 1)
-
-
-#if DEBUG
-static void print_matrix(char array[], unsigned int length)
-{
-	int i, j;
-
-	for (i=0; i<length; i++) {
-		printk(KERN_DEBUG "aci-rds: ");
-		for (j=7; j>=0; j--) {
-			printk("%d", (array[i] >> j) & 0x1);
-		}
-		if (i%8 == 0)
-			printk(" byte-border\n");
-		else
-			printk("\n");
-	}
-}
-#endif /* DEBUG */
-
-static int byte2trans(unsigned char byte, unsigned char sendbuffer[], int size)
-{
-	int i;
-
-	if (size != 8)
-		return -1;
-	for (i = 7; i >= 0; i--)
-		sendbuffer[7-i] = (byte & (1 << i)) ? RDS_DATAMASK : 0;
-	sendbuffer[0] |= RDS_CLOCKMASK;
-
-	return 0;
-}
-
-static int rds_waitread(void)
-{
-	unsigned char byte;
-	int i=2000;
-
-	do {
-		byte=inb(RDS_REGISTER);
-		i--;
-	}
-	while ((byte & RDS_BUSYMASK) && i);
-
-	if (i) {
-		#if DEBUG
-		printk(KERN_DEBUG "rds_waitread()");
-		print_matrix(&byte, 1);
-		#endif
-		return (byte);
-	} else {
-		printk(KERN_WARNING "aci-rds: rds_waitread() timeout...\n");
-		return -1;
-	}
-}
-
-/* don't use any ..._nowait() function if you are not sure what you do... */
-
-static inline void rds_rawwrite_nowait(unsigned char byte)
-{
-	#if DEBUG
-	printk(KERN_DEBUG "rds_rawwrite()");
-	print_matrix(&byte, 1);
-	#endif
-	outb(byte, RDS_REGISTER);
-}
-
-static int rds_rawwrite(unsigned char byte)
-{
-	if (rds_waitread() >= 0) {
-		rds_rawwrite_nowait(byte);
-		return 0;
-	} else
-		return -1;
-}
-
-static int rds_write(unsigned char cmd)
-{
-	unsigned char sendbuffer[8];
-	int i;
-
-	if (byte2trans(cmd, sendbuffer, 8) != 0){
-		return -1;
-	} else {
-		for (i=0; i<8; i++) {
-			rds_rawwrite(sendbuffer[i]);
-		}
-	}
-	return 0;
-}
-
-static int rds_readcycle_nowait(void)
-{
-	rds_rawwrite_nowait(0);
-	return rds_waitread();
-}
-
-static int rds_readcycle(void)
-{
-	if (rds_rawwrite(0) < 0)
-		return -1;
-	return rds_waitread();
-}
-
-static int rds_read(unsigned char databuffer[], int datasize)
-{
-	#define READSIZE (8*datasize)
-
-	int i,j;
-
-	if (datasize < 1)  /* nothing to read */
-		return 0;
-
-	/* to be able to use rds_readcycle_nowait()
-	   I have to waitread() here */
-	if (rds_waitread() < 0)
-		return -1;
-
-	memset(databuffer, 0, datasize);
-
-	for (i=0; i< READSIZE; i++)
-		if((j=rds_readcycle_nowait()) < 0) {
-			return -1;
-		} else {
-			databuffer[i/8]|=(RDS_DATA(j) << (7-(i%8)));
-		}
-
-	return 0;
-}
-
-static int rds_ack(void)
-{
-	int i=rds_readcycle();
-
-	if (i < 0)
-		return -1;
-	if (i & RDS_DATAMASK) {
-		return 0;  /* ACK  */
-	} else {
-		printk(KERN_DEBUG "aci-rds: NACK\n");
-		return 1;  /* NACK */
-	}
-}
-
-int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize)
-{
-	int ret;
-
-	if (mutex_lock_interruptible(&aci_rds_mutex))
-		return -EINTR;
-
-	rds_write(cmd);
-
-	/* RDS_RESET doesn't need further processing */
-	if (cmd!=RDS_RESET && (rds_ack() || rds_read(databuffer, datasize)))
-		ret = -1;
-	else
-		ret = 0;
-
-	mutex_unlock(&aci_rds_mutex);
-
-	return ret;
-}
-EXPORT_SYMBOL(aci_rds_cmd);
-
-int __init attach_aci_rds(void)
-{
-	mutex_init(&aci_rds_mutex);
-	return 0;
-}
-
-void __exit unload_aci_rds(void)
-{
-}
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/radio/miropcm20-rds-core.h b/drivers/media/radio/miropcm20-rds-core.h
deleted file mode 100644
index aeb5761..0000000
--- a/drivers/media/radio/miropcm20-rds-core.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef _MIROPCM20_RDS_CORE_H_
-#define _MIROPCM20_RDS_CORE_H_
-
-extern int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize);
-
-#define RDS_STATUS      0x01
-#define RDS_STATIONNAME 0x02
-#define RDS_TEXT        0x03
-#define RDS_ALTFREQ     0x04
-#define RDS_TIMEDATE    0x05
-#define RDS_PI_CODE     0x06
-#define RDS_PTYTATP     0x07
-#define RDS_RESET       0x08
-#define RDS_RXVALUE     0x09
-
-extern void __exit unload_aci_rds(void);
-extern int __init attach_aci_rds(void);
-
-#endif /* _MIROPCM20_RDS_CORE_H_ */
diff --git a/drivers/media/radio/miropcm20-rds.c b/drivers/media/radio/miropcm20-rds.c
deleted file mode 100644
index 3e840f7..0000000
--- a/drivers/media/radio/miropcm20-rds.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/* MiroSOUND PCM20 radio rds interface driver
- * (c) 2001 Robert Siemer <Robert.Siemer@gmx.de>
- * Thanks to Fred Seidel. See miropcm20-rds-core.c for further information.
- */
-
-/* Revision history:
- *
- *   2001-04-18  Robert Siemer <Robert.Siemer@gmx.de>
- *        separate file for user interface driver
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/delay.h>
-#include <asm/uaccess.h>
-#include "miropcm20-rds-core.h"
-
-static char * text_buffer;
-static int rds_users;
-
-
-static int rds_f_open(struct inode *in, struct file *fi)
-{
-	if (rds_users)
-		return -EBUSY;
-
-	lock_kernel();
-	rds_users++;
-	if ((text_buffer=kmalloc(66, GFP_KERNEL)) == 0) {
-		rds_users--;
-		printk(KERN_NOTICE "aci-rds: Out of memory by open()...\n");
-		unlock_kernel();
-		return -ENOMEM;
-	}
-
-	unlock_kernel();
-	return 0;
-}
-
-static int rds_f_release(struct inode *in, struct file *fi)
-{
-	kfree(text_buffer);
-
-	rds_users--;
-	return 0;
-}
-
-static void print_matrix(char *ch, char out[])
-{
-	int j;
-
-	for (j=7; j>=0; j--) {
-		 out[7-j] = ((*ch >> j) & 0x1) + '0';
-	}
-}
-
-static ssize_t rds_f_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
-{
-//	i = sprintf(text_buffer, "length: %d, offset: %d\n", length, *offset);
-
-	char c;
-	char bits[8];
-
-	msleep(2000);
-	aci_rds_cmd(RDS_STATUS, &c, 1);
-	print_matrix(&c, bits);
-	if (copy_to_user(buffer, bits, 8))
-		return -EFAULT;
-
-/*	if ((c >> 3) & 1) {
-		aci_rds_cmd(RDS_STATIONNAME, text_buffer+1, 8);
-		text_buffer[0]  = ' ' ;
-		text_buffer[9]  = '\n';
-		return copy_to_user(buffer+8, text_buffer, 10) ? -EFAULT: 18;
-	}
-*/
-/*	if ((c >> 6) & 1) {
-		aci_rds_cmd(RDS_PTYTATP, &c, 1);
-		if ( c & 1)
-			sprintf(text_buffer, " M");
-		else
-			sprintf(text_buffer, " S");
-		if ((c >> 1) & 1)
-			sprintf(text_buffer+2, " TA");
-		else
-			sprintf(text_buffer+2, " --");
-		if ((c >> 7) & 1)
-			sprintf(text_buffer+5, " TP");
-		else
-			sprintf(text_buffer+5, " --");
-		sprintf(text_buffer+8, " %2d\n", (c >> 2) & 0x1f);
-		return copy_to_user(buffer+8, text_buffer, 12) ? -EFAULT: 20;
-	}
-*/
-
-	if ((c >> 4) & 1) {
-		aci_rds_cmd(RDS_TEXT, text_buffer, 65);
-		text_buffer[0]  = ' ' ;
-		text_buffer[65] = '\n';
-		return copy_to_user(buffer+8, text_buffer,66) ? -EFAULT : 66+8;
-	} else {
-		put_user('\n', buffer+8);
-		return 9;
-	}
-}
-
-static const struct file_operations rds_fops = {
-	.owner		= THIS_MODULE,
-	.read		= rds_f_read,
-	.open		= rds_f_open,
-	.release	= rds_f_release
-};
-
-static struct miscdevice rds_miscdev = {
-	.minor		= MISC_DYNAMIC_MINOR,
-	.name		= "radiotext",
-	.fops		= &rds_fops,
-};
-
-static int __init miropcm20_rds_init(void)
-{
-	return misc_register(&rds_miscdev);
-}
-
-static void __exit miropcm20_rds_cleanup(void)
-{
-	misc_deregister(&rds_miscdev);
-}
-
-module_init(miropcm20_rds_init);
-module_exit(miropcm20_rds_cleanup);
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index eba9209..1f064f4 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -426,8 +426,7 @@
 
 	rtrack_radio.priv=&rtrack_unit;
 
-	if(video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr)==-1)
-	{
+	if (video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
 		release_region(io, 2);
 		return -EINVAL;
 	}
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index 3fe5504..628c689 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -394,8 +394,7 @@
 	mutex_init(&lock);
 	aztech_radio.priv=&aztech_unit;
 
-	if(video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr)==-1)
-	{
+	if (video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
 		release_region(io,2);
 		return -EINVAL;
 	}
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index 6166e72..04c3698 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -682,7 +682,7 @@
 	}
 	if (!request_region(io,2,"cadet"))
 		goto fail;
-	if(video_register_device(&cadet_radio,VFL_TYPE_RADIO,radio_nr)==-1) {
+	if (video_register_device(&cadet_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
 		release_region(io,2);
 		goto fail;
 	}
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index 36e754e..5cd7f03 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -425,7 +425,7 @@
 	}
 	*devradio = vdev_template;
 
-	if ( video_register_device( devradio, VFL_TYPE_RADIO , nr_radio) == -1 ) {
+	if (video_register_device(devradio, VFL_TYPE_RADIO, nr_radio) < 0) {
 		kfree( devradio );
 		goto err_video;
 	}
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 2b1a622..0a0f956 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -612,8 +612,7 @@
 
 	gemtek_radio.priv = &gemtek_unit;
 
-	if (video_register_device(&gemtek_radio, VFL_TYPE_RADIO,
-		radio_nr) == -1) {
+	if (video_register_device(&gemtek_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
 		release_region(io, 1);
 		return -EBUSY;
 	}
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index 0ada1c6..9ef0a76 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -409,8 +409,7 @@
 	video_set_drvdata(maestro_radio_inst, radio_unit);
 	pci_set_drvdata(pdev, maestro_radio_inst);
 
-	retval = video_register_device(maestro_radio_inst, VFL_TYPE_RADIO,
-		radio_nr);
+	retval = video_register_device(maestro_radio_inst, VFL_TYPE_RADIO, radio_nr);
 	if (retval) {
 		printk(KERN_ERR "can't register video device!\n");
 		goto errfr1;
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index 43c7549..0cc6fcb 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -156,28 +156,28 @@
 {
 	unsigned long int si;
 	int bl;
-	int data = FREQ2BITS(freq);
+	int val = FREQ2BITS(freq);
 
 	/* TEA5757 shift register bits (see pdf) */
 
-	outbit(0,io); // 24  search
-	outbit(1,io); // 23  search up/down
+	outbit(0, io); /* 24  search */
+	outbit(1, io); /* 23  search up/down */
 
-	outbit(0,io); // 22  stereo/mono
+	outbit(0, io); /* 22  stereo/mono */
 
-	outbit(0,io); // 21  band
-	outbit(0,io); // 20  band (only 00=FM works I think)
+	outbit(0, io); /* 21  band */
+	outbit(0, io); /* 20  band (only 00=FM works I think) */
 
-	outbit(0,io); // 19  port ?
-	outbit(0,io); // 18  port ?
+	outbit(0, io); /* 19  port ? */
+	outbit(0, io); /* 18  port ? */
 
-	outbit(0,io); // 17  search level
-	outbit(0,io); // 16  search level
+	outbit(0, io); /* 17  search level */
+	outbit(0, io); /* 16  search level */
 
 	si = 0x8000;
-	for (bl = 1; bl <= 16 ; bl++) {
-		outbit(data & si,io);
-		si >>=1;
+	for (bl = 1; bl <= 16; bl++) {
+		outbit(val & si, io);
+		si >>= 1;
 	}
 
 	dprintk(1, "Radio freq set to %d.%02d MHz\n",
@@ -410,7 +410,7 @@
 	mutex_init(&radio_unit.lock);
 	maxiradio_radio.priv = &radio_unit;
 
-	if (video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr)==-1) {
+	if (video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
 		printk("radio-maxiradio: can't register device!");
 		goto err_out_free_region;
 	}
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index e2dde08..6d820e2 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -332,8 +332,7 @@
 	rtrack2_radio.priv=&rtrack2_unit;
 
 	spin_lock_init(&lock);
-	if(video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr)==-1)
-	{
+	if (video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
 		release_region(io, 4);
 		return -EINVAL;
 	}
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index bb5d92f..0d478f5 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -377,7 +377,7 @@
 
 	mutex_init(&lock);
 
-	if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) == -1) {
+	if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
 		release_region(io, 2);
 		return -EINVAL;
 	}
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index a4984ff..16c7ef2 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -1694,8 +1694,8 @@
 	INIT_DELAYED_WORK(&radio->work, si470x_work);
 
 	/* register video device */
-	if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
-		retval = -EIO;
+	retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
+	if (retval) {
 		printk(KERN_WARNING DRIVER_NAME
 				": Could not register video device\n");
 		goto err_all;
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index cefa44f..0876fec 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -405,8 +405,7 @@
 
 	spin_lock_init(&lock);
 
-	if(video_register_device(&terratec_radio, VFL_TYPE_RADIO, radio_nr)==-1)
-	{
+	if (video_register_device(&terratec_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
 		release_region(io,2);
 		return -EINVAL;
 	}
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index d70172d..1931619 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -378,8 +378,7 @@
 		printk(KERN_ERR "trust: port 0x%x already in use\n", io);
 		return -EBUSY;
 	}
-	if(video_register_device(&trust_radio, VFL_TYPE_RADIO, radio_nr)==-1)
-	{
+	if (video_register_device(&trust_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
 		release_region(io, 2);
 		return -EINVAL;
 	}
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index 9f17a33..51d57ed 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -446,8 +446,7 @@
 		return -EBUSY;
 	}
 
-	if (video_register_device(&zoltrix_radio, VFL_TYPE_RADIO, radio_nr) == -1)
-	{
+	if (video_register_device(&zoltrix_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
 		release_region(io, 2);
 		return -EINVAL;
 	}
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index ecbfa1b..3e9e0dc 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -968,7 +968,7 @@
 
 config VIDEO_SH_MOBILE_CEU
 	tristate "SuperH Mobile CEU Interface driver"
-	depends on VIDEO_DEV
+	depends on VIDEO_DEV && HAS_DMA
 	select SOC_CAMERA
 	select VIDEOBUF_DMA_CONTIG
 	---help---
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index bbc6f8b..ef7c8d3 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -20,6 +20,8 @@
   obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o
 endif
 
+obj-$(CONFIG_VIDEO_TUNER) += tuner.o
+
 obj-$(CONFIG_VIDEO_BT848) += bt8xx/
 obj-$(CONFIG_VIDEO_IR_I2C)  += ir-kbd-i2c.o
 obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
@@ -85,8 +87,6 @@
 obj-$(CONFIG_VIDEO_DPC) += dpc7146.o
 obj-$(CONFIG_TUNER_3036) += tuner-3036.o
 
-obj-$(CONFIG_VIDEO_TUNER) += tuner.o
-
 obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
 obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
 obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o
diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig
index ed9a50f..018f72b 100644
--- a/drivers/media/video/au0828/Kconfig
+++ b/drivers/media/video/au0828/Kconfig
@@ -7,6 +7,7 @@
 	select DVB_AU8522 if !DVB_FE_CUSTOMIZE
 	select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
 	select MEDIA_TUNER_MXL5007T if !DVB_FE_CUSTOMIZE
+	select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
 	---help---
 	  This is a video4linux driver for Auvitek's USB device.
 
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index 443e590..ed48908 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -1,7 +1,7 @@
 /*
  *  Driver for the Auvitek USB bridge
  *
- *  Copyright (c) 2008 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -38,6 +38,9 @@
 	[AU0828_BOARD_DVICO_FUSIONHDTV7] = {
 		.name	= "DViCO FusionHDTV USB",
 	},
+	[AU0828_BOARD_HAUPPAUGE_WOODBURY] = {
+		.name = "Hauppauge Woodbury",
+	},
 };
 
 /* Tuner callback function for au0828 boards. Currently only needed
@@ -115,6 +118,7 @@
 	case AU0828_BOARD_HAUPPAUGE_HVR850:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
+	case AU0828_BOARD_HAUPPAUGE_WOODBURY:
 		if (dev->i2c_rc == 0)
 			hauppauge_eeprom(dev, eeprom+0xa0);
 		break;
@@ -134,6 +138,7 @@
 	case AU0828_BOARD_HAUPPAUGE_HVR850:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
+	case AU0828_BOARD_HAUPPAUGE_WOODBURY:
 		/* GPIO's
 		 * 4 - CS5340
 		 * 5 - AU8522 Demodulator
@@ -205,6 +210,8 @@
 		.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL },
 	{ USB_DEVICE(0x2040, 0x7281),
 		.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL },
+	{ USB_DEVICE(0x2040, 0x8200),
+		.driver_info = AU0828_BOARD_HAUPPAUGE_WOODBURY },
 	{ },
 };
 
diff --git a/drivers/media/video/au0828/au0828-cards.h b/drivers/media/video/au0828/au0828-cards.h
index c37f5fd..48a1882 100644
--- a/drivers/media/video/au0828/au0828-cards.h
+++ b/drivers/media/video/au0828/au0828-cards.h
@@ -1,7 +1,7 @@
 /*
  *  Driver for the Auvitek USB bridge
  *
- *  Copyright (c) 2008 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -24,3 +24,4 @@
 #define AU0828_BOARD_HAUPPAUGE_HVR850 	2
 #define AU0828_BOARD_DVICO_FUSIONHDTV7	3
 #define AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL	4
+#define AU0828_BOARD_HAUPPAUGE_WOODBURY	5
diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c
index 54bfc0f..d856de9 100644
--- a/drivers/media/video/au0828/au0828-core.c
+++ b/drivers/media/video/au0828/au0828-core.c
@@ -1,7 +1,7 @@
 /*
  *  Driver for the Auvitek USB bridge
  *
- *  Copyright (c) 2008 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -252,5 +252,5 @@
 module_exit(au0828_exit);
 
 MODULE_DESCRIPTION("Driver for Auvitek AU0828 based products");
-MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>");
+MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
 MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c
index 584a83a..ba94be7 100644
--- a/drivers/media/video/au0828/au0828-dvb.c
+++ b/drivers/media/video/au0828/au0828-dvb.c
@@ -1,7 +1,7 @@
 /*
  *  Driver for the Auvitek USB bridge
  *
- *  Copyright (c) 2008 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -29,6 +29,7 @@
 #include "au8522.h"
 #include "xc5000.h"
 #include "mxl5007t.h"
+#include "tda18271.h"
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
@@ -38,6 +39,15 @@
 static struct au8522_config hauppauge_hvr950q_config = {
 	.demod_address = 0x8e >> 1,
 	.status_mode   = AU8522_DEMODLOCKING,
+	.qam_if        = AU8522_IF_6MHZ,
+	.vsb_if        = AU8522_IF_6MHZ,
+};
+
+static struct au8522_config hauppauge_woodbury_config = {
+	.demod_address = 0x8e >> 1,
+	.status_mode   = AU8522_DEMODLOCKING,
+	.qam_if        = AU8522_IF_4MHZ,
+	.vsb_if        = AU8522_IF_3_25MHZ,
 };
 
 static struct xc5000_config hauppauge_hvr950q_tunerconfig = {
@@ -51,6 +61,10 @@
 	.if_freq_hz = MxL_IF_6_MHZ,
 };
 
+static struct tda18271_config hauppauge_woodbury_tunerconfig = {
+	.gate    = TDA18271_GATE_DIGITAL,
+};
+
 /*-------------------------------------------------------------------*/
 static void urb_completion(struct urb *purb)
 {
@@ -357,6 +371,15 @@
 				   &dev->i2c_adap, 0x60,
 				   &mxl5007t_hvr950q_config);
 		break;
+	case AU0828_BOARD_HAUPPAUGE_WOODBURY:
+		dvb->frontend = dvb_attach(au8522_attach,
+				&hauppauge_woodbury_config,
+				&dev->i2c_adap);
+		if (dvb->frontend != NULL)
+			dvb_attach(tda18271_attach, dvb->frontend,
+				   0x60, &dev->i2c_adap,
+				   &hauppauge_woodbury_tunerconfig);
+		break;
 	default:
 		printk(KERN_WARNING "The frontend of your DVB/ATSC card "
 		       "isn't supported yet\n");
diff --git a/drivers/media/video/au0828/au0828-i2c.c b/drivers/media/video/au0828/au0828-i2c.c
index 741a493..d618fba 100644
--- a/drivers/media/video/au0828/au0828-i2c.c
+++ b/drivers/media/video/au0828/au0828-i2c.c
@@ -1,7 +1,7 @@
 /*
  *  Driver for the Auvitek AU0828 USB bridge
  *
- *  Copyright (c) 2008 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/au0828/au0828-reg.h b/drivers/media/video/au0828/au0828-reg.h
index 3982755..1e87fa0c6 100644
--- a/drivers/media/video/au0828/au0828-reg.h
+++ b/drivers/media/video/au0828/au0828-reg.h
@@ -1,7 +1,7 @@
 /*
  *  Driver for the Auvitek USB bridge
  *
- *  Copyright (c) 2008 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h
index 7beb571..4f10ff3 100644
--- a/drivers/media/video/au0828/au0828.h
+++ b/drivers/media/video/au0828/au0828.h
@@ -1,7 +1,7 @@
 /*
  *  Driver for the Auvitek AU0828 USB bridge
  *
- *  Copyright (c) 2008 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index 1c56ae9..6081edc 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -3144,8 +3144,9 @@
 
 static void flyvideo_gpio(struct bttv *btv)
 {
-	int gpio,has_remote,has_radio,is_capture_only,is_lr90,has_tda9820_tda9821;
-	int tuner=UNSET,ttype;
+	int gpio, has_remote, has_radio, is_capture_only;
+	int is_lr90, has_tda9820_tda9821;
+	int tuner_type = UNSET, ttype;
 
 	gpio_inout(0xffffff, 0);
 	udelay(8);  /* without this we would see the 0x1800 mask */
@@ -3163,20 +3164,26 @@
 	 * xxxF00(LR26/LR50), xxxFE0(LR90): Remote control chip (LVA001 or CF45) soldered
 	 * Note: Some bits are Audio_Mask !
 	 */
-	ttype=(gpio&0x0f0000)>>16;
-	switch(ttype) {
-	case 0x0: tuner=2; /* NTSC, e.g. TPI8NSR11P */
+	ttype = (gpio & 0x0f0000) >> 16;
+	switch (ttype) {
+	case 0x0:
+		tuner_type = 2;  /* NTSC, e.g. TPI8NSR11P */
 		break;
-	case 0x2: tuner=39;/* LG NTSC (newer TAPC series) TAPC-H701P */
+	case 0x2:
+		tuner_type = 39; /* LG NTSC (newer TAPC series) TAPC-H701P */
 		break;
-	case 0x4: tuner=5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */
+	case 0x4:
+		tuner_type = 5;  /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */
 		break;
-	case 0x6: tuner=37;/* LG PAL (newer TAPC series) TAPC-G702P */
+	case 0x6:
+		tuner_type = 37; /* LG PAL (newer TAPC series) TAPC-G702P */
 		break;
-		case 0xC: tuner=3; /* Philips SECAM(+PAL) FQ1216ME or FI1216MF */
+	case 0xC:
+		tuner_type = 3;  /* Philips SECAM(+PAL) FQ1216ME or FI1216MF */
 		break;
 	default:
 		printk(KERN_INFO "bttv%d: FlyVideo_gpio: unknown tuner type.\n", btv->c.nr);
+		break;
 	}
 
 	has_remote          =   gpio & 0x800000;
@@ -3189,23 +3196,26 @@
 	/*
 	 * gpio & 0x001000    output bit for audio routing */
 
-	if(is_capture_only)
-		tuner = TUNER_ABSENT; /* No tuner present */
+	if (is_capture_only)
+		tuner_type = TUNER_ABSENT; /* No tuner present */
 
 	printk(KERN_INFO "bttv%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n",
-	       btv->c.nr, has_radio? "yes":"no ", has_remote? "yes":"no ", tuner, gpio);
+		btv->c.nr, has_radio ? "yes" : "no ",
+		has_remote ? "yes" : "no ", tuner_type, gpio);
 	printk(KERN_INFO "bttv%d: FlyVideo  LR90=%s tda9821/tda9820=%s capture_only=%s\n",
-		btv->c.nr, is_lr90?"yes":"no ", has_tda9820_tda9821?"yes":"no ",
-		is_capture_only?"yes":"no ");
+		btv->c.nr, is_lr90 ? "yes" : "no ",
+		has_tda9820_tda9821 ? "yes" : "no ",
+		is_capture_only ? "yes" : "no ");
 
-	if (tuner != UNSET) /* only set if known tuner autodetected, else let insmod option through */
-		btv->tuner_type = tuner;
+	if (tuner_type != UNSET) /* only set if known tuner autodetected, else let insmod option through */
+		btv->tuner_type = tuner_type;
 	btv->has_radio = has_radio;
 
 	/* LR90 Audio Routing is done by 2 hef4052, so Audio_Mask has 4 bits: 0x001c80
 	 * LR26/LR50 only has 1 hef4052, Audio_Mask 0x000c00
 	 * Audio options: from tuner, from tda9821/tda9821(mono,stereo,sap), from tda9874, ext., mute */
-	if(has_tda9820_tda9821) btv->audio_mode_gpio = lt9415_audio;
+	if (has_tda9820_tda9821)
+		btv->audio_mode_gpio = lt9415_audio;
 	/* todo: if(has_tda9874) btv->audio_mode_gpio = fv2000s_audio; */
 }
 
@@ -3962,7 +3972,7 @@
 
 static void __devinit avermedia_eeprom(struct bttv *btv)
 {
-	int tuner_make,tuner_tv_fm,tuner_format,tuner=0;
+	int tuner_make, tuner_tv_fm, tuner_format, tuner_type = 0;
 
 	tuner_make      = (eeprom_data[0x41] & 0x7);
 	tuner_tv_fm     = (eeprom_data[0x41] & 0x18) >> 3;
@@ -3970,24 +3980,24 @@
 	btv->has_remote = (eeprom_data[0x42] & 0x01);
 
 	if (tuner_make == 0 || tuner_make == 2)
-		if(tuner_format <=0x0a)
-			tuner = tuner_0_table[tuner_format];
+		if (tuner_format <= 0x0a)
+			tuner_type = tuner_0_table[tuner_format];
 	if (tuner_make == 1)
-		if(tuner_format <=9)
-			tuner = tuner_1_table[tuner_format];
+		if (tuner_format <= 9)
+			tuner_type = tuner_1_table[tuner_format];
 
 	if (tuner_make == 4)
-		if(tuner_format == 0x09)
-			tuner = TUNER_LG_NTSC_NEW_TAPC; /* TAPC-G702P */
+		if (tuner_format == 0x09)
+			tuner_type = TUNER_LG_NTSC_NEW_TAPC; /* TAPC-G702P */
 
 	printk(KERN_INFO "bttv%d: Avermedia eeprom[0x%02x%02x]: tuner=",
-		btv->c.nr,eeprom_data[0x41],eeprom_data[0x42]);
-	if(tuner) {
-		btv->tuner_type=tuner;
-		printk("%d",tuner);
+		btv->c.nr, eeprom_data[0x41], eeprom_data[0x42]);
+	if (tuner_type) {
+		btv->tuner_type = tuner_type;
+		printk(KERN_CONT "%d", tuner_type);
 	} else
-		printk("Unknown type");
-	printk(" radio:%s remote control:%s\n",
+		printk(KERN_CONT "Unknown type");
+	printk(KERN_CONT " radio:%s remote control:%s\n",
 	       tuner_tv_fm     ? "yes" : "no",
 	       btv->has_remote ? "yes" : "no");
 }
@@ -4029,7 +4039,8 @@
 
 	gpio_inout(mask,mask);
 	gpio_bits(mask,0);
-	udelay(2500);
+	mdelay(2);
+	udelay(500);
 	gpio_bits(mask,mask);
 
 	if (bttv_gpio)
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 85bf31a..6ae4cc8 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -96,7 +96,6 @@
 static unsigned int uv_ratio    = 50;
 static unsigned int full_luma_range;
 static unsigned int coring;
-extern int no_overlay;
 
 /* API features (turn on/off stuff for testing) */
 static unsigned int v4l2        = 1;
diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c
index 649682a..5b1b8e4 100644
--- a/drivers/media/video/bt8xx/bttv-risc.c
+++ b/drivers/media/video/bt8xx/bttv-risc.c
@@ -244,7 +244,8 @@
 		  const struct bttv_format *fmt, struct bttv_overlay *ov,
 		  int skip_even, int skip_odd)
 {
-	int dwords,rc,line,maxy,start,end,skip,nskips;
+	int dwords, rc, line, maxy, start, end;
+	unsigned skip, nskips;
 	struct btcx_skiplist *skips;
 	__le32 *rp;
 	u32 ri,ra;
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h
index 08ef54a..b4d940b 100644
--- a/drivers/media/video/bt8xx/bttvp.h
+++ b/drivers/media/video/bt8xx/bttvp.h
@@ -267,6 +267,11 @@
 int bttv_sub_del_devices(struct bttv_core *core);
 
 /* ---------------------------------------------------------- */
+/* bttv-cards.c                                               */
+
+extern int no_overlay;
+
+/* ---------------------------------------------------------- */
 /* bttv-driver.c                                              */
 
 /* insmod options */
diff --git a/drivers/media/video/btcx-risc.c b/drivers/media/video/btcx-risc.c
index f42701f..3324ab3 100644
--- a/drivers/media/video/btcx-risc.c
+++ b/drivers/media/video/btcx-risc.c
@@ -184,12 +184,12 @@
 }
 
 void
-btcx_calc_skips(int line, int width, unsigned int *maxy,
+btcx_calc_skips(int line, int width, int *maxy,
 		struct btcx_skiplist *skips, unsigned int *nskips,
 		const struct v4l2_clip *clips, unsigned int nclips)
 {
 	unsigned int clip,skip;
-	int end,maxline;
+	int end, maxline;
 
 	skip=0;
 	maxline = 9999;
diff --git a/drivers/media/video/btcx-risc.h b/drivers/media/video/btcx-risc.h
index 861bc81..f8bc6e8 100644
--- a/drivers/media/video/btcx-risc.h
+++ b/drivers/media/video/btcx-risc.h
@@ -23,7 +23,7 @@
 int btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips,
 	       unsigned int n, int mask);
 void btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips);
-void btcx_calc_skips(int line, int width, unsigned int *maxy,
+void btcx_calc_skips(int line, int width, int *maxy,
 		     struct btcx_skiplist *skips, unsigned int *nskips,
 		     const struct v4l2_clip *clips, unsigned int nclips);
 
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index d3b3268..6e39e25 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -946,8 +946,7 @@
 
 	printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name);
 
-	if(video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1)
-	{
+	if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
 		parport_unregister_device(qcam->pdev);
 		kfree(qcam);
 		return -ENODEV;
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
index fe9379b..7f6c6b4 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/video/c-qcam.c
@@ -787,8 +787,7 @@
 
 	parport_release(qcam->pdev);
 
-	if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1)
-	{
+	if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
 		printk(KERN_ERR "Unable to register Colour QuickCam on %s\n",
 		       qcam->pport->name);
 		parport_unregister_device(qcam->pdev);
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index dc8cc61..a661800 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -3955,7 +3955,7 @@
 	camera->lowlevel_data = lowlevel;
 
 	/* register v4l device */
-	if (video_register_device(&camera->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
+	if (video_register_device(&camera->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
 		kfree(camera);
 		printk(KERN_DEBUG "video_register_device failed\n");
 		return NULL;
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index 515c8b5..eb9f15c 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -1024,7 +1024,6 @@
 		if(cam->params.pnp_id.device_type == DEVICE_STV_672 &&
 		   cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){
 			// Maximum 15fps
-			int i;
 			for(i=0; i<c->maximum; ++i) {
 				if(framerate_controls[i].value ==
 				   CPIA2_VP_FRAMERATE_15) {
@@ -1959,8 +1958,7 @@
 	reset_camera_struct_v4l(cam);
 
 	/* register v4l device */
-	if (video_register_device
-	    (cam->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
+	if (video_register_device(cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
 		ERR("video_register_device failed\n");
 		video_device_release(cam->vdev);
 		return -ENODEV;
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
index 834b924..e996a4e 100644
--- a/drivers/media/video/cx18/cx18-av-firmware.c
+++ b/drivers/media/video/cx18/cx18-av-firmware.c
@@ -32,7 +32,7 @@
 	u32 v;
 	const u8 *ptr;
 	int i;
-	int retries = 0;
+	int retries1 = 0;
 
 	if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) {
 		CX18_ERR("unable to open firmware %s\n", FWFILE);
@@ -41,7 +41,7 @@
 
 	/* The firmware load often has byte errors, so allow for several
 	   retries, both at byte level and at the firmware load level. */
-	while (retries < 5) {
+	while (retries1 < 5) {
 		cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000);
 		cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6);
 
@@ -57,9 +57,9 @@
 		for (i = 0; i < size; i++) {
 			u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16);
 			u32 value = 0;
-			int retries;
+			int retries2;
 
-			for (retries = 0; retries < 5; retries++) {
+			for (retries2 = 0; retries2 < 5; retries2++) {
 				cx18_av_write4(cx, CXADEC_DL_CTL, dl_control);
 				udelay(10);
 				value = cx18_av_read4(cx, CXADEC_DL_CTL);
@@ -69,18 +69,18 @@
 				   the address.  We can only write the lower
 				   address byte of the address. */
 				if ((value & 0x3F00) != (dl_control & 0x3F00)) {
-					retries = 5;
+					retries2 = 5;
 					break;
 				}
 			}
-			if (retries >= 5)
+			if (retries2 >= 5)
 				break;
 		}
 		if (i == size)
 			break;
-		retries++;
+		retries1++;
 	}
-	if (retries >= 5) {
+	if (retries1 >= 5) {
 		CX18_ERR("unable to load firmware %s\n", FWFILE);
 		release_firmware(fw);
 		return -EIO;
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 22434aa..bd18afe 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -74,9 +74,9 @@
 				     -1, -1, -1, -1, -1, -1, -1, -1,
 				     -1, -1, -1, -1, -1, -1, -1, -1 };
 
-static int cardtype_c = 1;
-static int tuner_c = 1;
-static int radio_c = 1;
+static unsigned cardtype_c = 1;
+static unsigned tuner_c = 1;
+static unsigned radio_c = 1;
 static char pal[] = "--";
 static char secam[] = "--";
 static char ntsc[] = "-";
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index cae3898..1e420a8 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -1,7 +1,7 @@
 /*
  *  cx18 functions for DVB support
  *
- *  Copyright (c) 2008 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-dvb.h b/drivers/media/video/cx18/cx18-dvb.h
index d6a6ccd..bf8d8f6 100644
--- a/drivers/media/video/cx18/cx18-dvb.h
+++ b/drivers/media/video/cx18/cx18-dvb.h
@@ -1,7 +1,7 @@
 /*
  *  cx18 functions for DVB support
  *
- *  Copyright (c) 2008 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c
index 25114a5..ab21831 100644
--- a/drivers/media/video/cx18/cx18-irq.c
+++ b/drivers/media/video/cx18/cx18-irq.c
@@ -61,7 +61,7 @@
 		CX18_WARN("Ack struct = %d for %s\n",
 			mb->args[2], s->name);
 	id = read_enc(off);
-	buf = cx18_queue_find_buf(s, id, read_enc(off + 4));
+	buf = cx18_queue_get_buf_irq(s, id, read_enc(off + 4));
 	CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id);
 	if (buf) {
 		cx18_buf_sync_for_cpu(s, buf);
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index 6990b77..dbe792a 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -78,12 +78,13 @@
 	return buf;
 }
 
-struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id,
+struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id,
 	u32 bytesused)
 {
 	struct cx18 *cx = s->cx;
 	struct list_head *p;
 
+	spin_lock(&s->qlock);
 	list_for_each(p, &s->q_free.list) {
 		struct cx18_buffer *buf =
 			list_entry(p, struct cx18_buffer, list);
@@ -92,114 +93,48 @@
 			continue;
 		buf->bytesused = bytesused;
 		/* the transport buffers are handled differently,
-		   so there is no need to move them to the full queue */
-		if (s->type == CX18_ENC_STREAM_TYPE_TS)
-			return buf;
-		s->q_free.buffers--;
-		s->q_free.length -= s->buf_size;
-		s->q_full.buffers++;
-		s->q_full.length += s->buf_size;
-		s->q_full.bytesused += buf->bytesused;
-		list_move_tail(&buf->list, &s->q_full.list);
+		   they are not moved to the full queue */
+		if (s->type != CX18_ENC_STREAM_TYPE_TS) {
+			s->q_free.buffers--;
+			s->q_free.length -= s->buf_size;
+			s->q_full.buffers++;
+			s->q_full.length += s->buf_size;
+			s->q_full.bytesused += buf->bytesused;
+			list_move_tail(&buf->list, &s->q_full.list);
+		}
+		spin_unlock(&s->qlock);
 		return buf;
 	}
+	spin_unlock(&s->qlock);
 	CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name);
 	return NULL;
 }
 
-static void cx18_queue_move_buf(struct cx18_stream *s, struct cx18_queue *from,
-		struct cx18_queue *to, int clear, int full)
-{
-	struct cx18_buffer *buf =
-		list_entry(from->list.next, struct cx18_buffer, list);
-
-	list_move_tail(from->list.next, &to->list);
-	from->buffers--;
-	from->length -= s->buf_size;
-	from->bytesused -= buf->bytesused - buf->readpos;
-	/* special handling for q_free */
-	if (clear)
-		buf->bytesused = buf->readpos = buf->b_flags = 0;
-	else if (full) {
-		/* special handling for stolen buffers, assume
-		   all bytes are used. */
-		buf->bytesused = s->buf_size;
-		buf->readpos = buf->b_flags = 0;
-	}
-	to->buffers++;
-	to->length += s->buf_size;
-	to->bytesused += buf->bytesused - buf->readpos;
-}
-
-/* Move 'needed_bytes' worth of buffers from queue 'from' into queue 'to'.
-   If 'needed_bytes' == 0, then move all buffers from 'from' into 'to'.
-   If 'steal' != NULL, then buffers may also taken from that queue if
-   needed.
-
-   The buffer is automatically cleared if it goes to the free queue. It is
-   also cleared if buffers need to be taken from the 'steal' queue and
-   the 'from' queue is the free queue.
-
-   When 'from' is q_free, then needed_bytes is compared to the total
-   available buffer length, otherwise needed_bytes is compared to the
-   bytesused value. For the 'steal' queue the total available buffer
-   length is always used.
-
-   -ENOMEM is returned if the buffers could not be obtained, 0 if all
-   buffers where obtained from the 'from' list and if non-zero then
-   the number of stolen buffers is returned. */
-static int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
-			   struct cx18_queue *steal, struct cx18_queue *to,
-			   int needed_bytes)
+/* Move all buffers of a queue to q_free, while flushing the buffers */
+static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q)
 {
 	unsigned long flags;
-	int rc = 0;
-	int from_free = from == &s->q_free;
-	int to_free = to == &s->q_free;
-	int bytes_available;
+	struct cx18_buffer *buf;
+
+	if (q == &s->q_free)
+		return;
 
 	spin_lock_irqsave(&s->qlock, flags);
-	if (needed_bytes == 0) {
-		from_free = 1;
-		needed_bytes = from->length;
+	while (!list_empty(&q->list)) {
+		buf = list_entry(q->list.next, struct cx18_buffer, list);
+		list_move_tail(q->list.next, &s->q_free.list);
+		buf->bytesused = buf->readpos = buf->b_flags = 0;
+		s->q_free.buffers++;
+		s->q_free.length += s->buf_size;
 	}
-
-	bytes_available = from_free ? from->length : from->bytesused;
-	bytes_available += steal ? steal->length : 0;
-
-	if (bytes_available < needed_bytes) {
-		spin_unlock_irqrestore(&s->qlock, flags);
-		return -ENOMEM;
-	}
-	if (from_free) {
-		u32 old_length = to->length;
-
-		while (to->length - old_length < needed_bytes) {
-			if (list_empty(&from->list))
-				from = steal;
-			if (from == steal)
-				rc++; 	/* keep track of 'stolen' buffers */
-			cx18_queue_move_buf(s, from, to, 1, 0);
-		}
-	} else {
-		u32 old_bytesused = to->bytesused;
-
-		while (to->bytesused - old_bytesused < needed_bytes) {
-			if (list_empty(&from->list))
-				from = steal;
-			if (from == steal)
-				rc++; 	/* keep track of 'stolen' buffers */
-			cx18_queue_move_buf(s, from, to, to_free, rc);
-		}
-	}
+	cx18_queue_init(q);
 	spin_unlock_irqrestore(&s->qlock, flags);
-	return rc;
 }
 
 void cx18_flush_queues(struct cx18_stream *s)
 {
-	cx18_queue_move(s, &s->q_io, NULL, &s->q_free, 0);
-	cx18_queue_move(s, &s->q_full, NULL, &s->q_free, 0);
+	cx18_queue_flush(s, &s->q_io);
+	cx18_queue_flush(s, &s->q_full);
 }
 
 int cx18_stream_alloc(struct cx18_stream *s)
@@ -214,10 +149,10 @@
 		s->name, s->buffers, s->buf_size,
 		s->buffers * s->buf_size / 1024);
 
-	if (((char *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] -
-				(char *)cx->scb) > SCB_RESERVED_SIZE) {
-		unsigned bufsz = (((char *)cx->scb) + SCB_RESERVED_SIZE -
-					((char *)cx->scb->cpu_mdl));
+	if (((char __iomem *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] -
+				(char __iomem *)cx->scb) > SCB_RESERVED_SIZE) {
+		unsigned bufsz = (((char __iomem *)cx->scb) + SCB_RESERVED_SIZE -
+					((char __iomem *)cx->scb->cpu_mdl));
 
 		CX18_ERR("Too many buffers, cannot fit in SCB area\n");
 		CX18_ERR("Max buffers = %zd\n",
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
index 91423b9..7f93bb1 100644
--- a/drivers/media/video/cx18/cx18-queue.h
+++ b/drivers/media/video/cx18/cx18-queue.h
@@ -46,7 +46,7 @@
 void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
 	struct cx18_queue *q);
 struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
-struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id,
+struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id,
 	u32 bytesused);
 void cx18_flush_queues(struct cx18_stream *s);
 
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index 8118091..7b0e8c0 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -4,7 +4,7 @@
  *
  *    (c) 2004 Jelle Foks <jelle@foks.8m.com>
  *    (c) 2004 Gerd Knorr <kraxel@bytesex.org>
- *    (c) 2008 Steven Toth <stoth@hauppauge.com>
+ *    (c) 2008 Steven Toth <stoth@linuxtv.org>
  *      - CX23885/7/8 support
  *
  *  Includes parts from the ivtv driver( http://ivtv.sourceforge.net/),
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index a19de85..c36d3f6 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -1,7 +1,7 @@
 /*
  *  Driver for the Conexant CX23885 PCIe bridge
  *
- *  Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index 6286a9c..25fb099 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -1,7 +1,7 @@
 /*
  *  Driver for the Conexant CX23885 PCIe bridge
  *
- *  Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -33,7 +33,7 @@
 #include "cx23885.h"
 
 MODULE_DESCRIPTION("Driver for cx23885 based TV cards");
-MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>");
+MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
 MODULE_LICENSE("GPL");
 
 static unsigned int debug;
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 0a2e655..291b9d0 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -1,7 +1,7 @@
 /*
  *  Driver for the Conexant CX23885 PCIe bridge
  *
- *  Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
index c6bb0a0..f98e476 100644
--- a/drivers/media/video/cx23885/cx23885-i2c.c
+++ b/drivers/media/video/cx23885/cx23885-i2c.c
@@ -1,7 +1,7 @@
 /*
  *  Driver for the Conexant CX23885 PCIe bridge
  *
- *  Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx23885/cx23885-reg.h b/drivers/media/video/cx23885/cx23885-reg.h
index bdd11bc..20b68a2 100644
--- a/drivers/media/video/cx23885/cx23885-reg.h
+++ b/drivers/media/video/cx23885/cx23885-reg.h
@@ -1,7 +1,7 @@
 /*
  *  Driver for the Conexant CX23885 PCIe bridge
  *
- *  Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx23885/cx23885-vbi.c b/drivers/media/video/cx23885/cx23885-vbi.c
index e36e3fc..35e61cd 100644
--- a/drivers/media/video/cx23885/cx23885-vbi.c
+++ b/drivers/media/video/cx23885/cx23885-vbi.c
@@ -1,7 +1,7 @@
 /*
  *  Driver for the Conexant CX23885 PCIe bridge
  *
- *  Copyright (c) 2007 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index ad2235d..6047c78 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -1,7 +1,7 @@
 /*
  *  Driver for the Conexant CX23885 PCIe bridge
  *
- *  Copyright (c) 2007 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -41,7 +41,7 @@
 #endif
 
 MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards");
-MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>");
+MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
 MODULE_LICENSE("GPL");
 
 /* ------------------------------------------------------------------ */
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 00dfdc8..e23d97c0 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -1,7 +1,7 @@
 /*
  *  Driver for the Conexant CX23885 PCIe bridge
  *
- *  Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
+ *  Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 209d3bc..4da8cd7 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -13,7 +13,7 @@
  * NTSC sliced VBI support by Christopher Neufeld <television@cneufeld.ca>
  * with additional fixes by Hans Verkuil <hverkuil@xs4all.nl>.
  *
- * CX23885 support by Steven Toth <stoth@hauppauge.com>.
+ * CX23885 support by Steven Toth <stoth@linuxtv.org>.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
index 2d170d1..8db2a05 100644
--- a/drivers/media/video/et61x251/et61x251_core.c
+++ b/drivers/media/video/et61x251/et61x251_core.c
@@ -2588,6 +2588,7 @@
 	cam->v4ldev->fops = &et61x251_fops;
 	cam->v4ldev->minor = video_nr[dev_nr];
 	cam->v4ldev->release = video_device_release;
+	cam->v4ldev->parent = &udev->dev;
 	video_set_drvdata(cam->v4ldev, cam);
 
 	init_completion(&cam->probe);
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index cd3a3f5..4d9f4cc 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -124,7 +124,7 @@
 	struct usb_device *dev = gspca_dev->dev;
 
 #ifdef GSPCA_DEBUG
-	if (len > sizeof gspca_dev->usb_buf) {
+	if (len > USB_BUF_SZ) {
 		err("reg_r: buffer overflow");
 		return;
 	}
@@ -164,7 +164,7 @@
 	struct usb_device *dev = gspca_dev->dev;
 
 #ifdef GSPCA_DEBUG
-	if (len > sizeof gspca_dev->usb_buf) {
+	if (len > USB_BUF_SZ) {
 		err("reg_w: buffer overflow");
 		return;
 	}
@@ -731,13 +731,13 @@
 	reg_w_val(gspca_dev, 0x0000, 0x00);
 	/* wait for completion */
 	retry = 50;
-	while (retry--) {
+	do {
 		reg_r(gspca_dev, 0x0002, 1);
 							/* 0x07 until 0x00 */
 		if (gspca_dev->usb_buf[0] == 0x00)
 			break;
 		reg_w_val(gspca_dev, 0x0053, 0x00);
-	}
+	} while (--retry);
 	if (retry == 0)
 		PDEBUG(D_ERR, "Damned Errors sending jpeg Table");
 	/* send the qtable now */
@@ -826,8 +826,8 @@
 	return 0;
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
 {
 	cx11646_init1(gspca_dev);
 	cx11646_initsize(gspca_dev);
@@ -845,10 +845,6 @@
 	cx11646_jpeg(gspca_dev);
 }
 
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
-}
-
 static void sd_stop0(struct gspca_dev *gspca_dev)
 {
 	int retry = 50;
@@ -871,10 +867,6 @@
 	reg_w_val(gspca_dev, 0x00fc, 0xe0);
 }
 
-static void sd_close(struct gspca_dev *gspca_dev)
-{
-}
-
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
@@ -998,11 +990,9 @@
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
-	.open = sd_open,
+	.init = sd_init,
 	.start = sd_start,
-	.stopN = sd_stopN,
 	.stop0 = sd_stop0,
-	.close = sd_close,
 	.pkt_scan = sd_pkt_scan,
 };
 
@@ -1026,6 +1016,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index 1dbe92d..4ff0e38 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -81,6 +81,7 @@
 	 .set = sd_setcontrast,
 	 .get = sd_getcontrast,
 	 },
+#define COLOR_IDX 2
 	{
 	 {
 	  .id = V4L2_CID_SATURATION,
@@ -234,7 +235,7 @@
 	struct usb_device *dev = gspca_dev->dev;
 
 #ifdef GSPCA_DEBUG
-	if (len > sizeof gspca_dev->usb_buf) {
+	if (len > USB_BUF_SZ) {
 		err("reg_r: buffer overflow");
 		return;
 	}
@@ -272,7 +273,7 @@
 	struct usb_device *dev = gspca_dev->dev;
 
 #ifdef GSPCA_DEBUG
-	if (len > sizeof gspca_dev->usb_buf) {
+	if (len > USB_BUF_SZ) {
 		err("reg_w: buffer overflow");
 		return;
 	}
@@ -665,6 +666,7 @@
 	} else {
 		cam->cam_mode = vga_mode;
 		cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+		gspca_dev->ctrl_dis = (1 << COLOR_IDX);
 	}
 	sd->brightness = BRIGHTNESS_DEF;
 	sd->contrast = CONTRAST_DEF;
@@ -674,8 +676,8 @@
 	return 0;
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
@@ -709,14 +711,6 @@
 	et_video(gspca_dev, 0);		/* video off */
 }
 
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
-}
-
-static void sd_close(struct gspca_dev *gspca_dev)
-{
-}
-
 static __u8 Et_getgainG(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -893,21 +887,19 @@
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
-	.open = sd_open,
+	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
-	.stop0 = sd_stop0,
-	.close = sd_close,
 	.pkt_scan = sd_pkt_scan,
 	.dq_callback = do_autogain,
 };
 
 /* -- module initialisation -- */
 static __devinitdata struct usb_device_id device_table[] = {
-#ifndef CONFIG_USB_ET61X251
 	{USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106},
-#endif
+#if !defined CONFIG_USB_ET61X251 && !defined CONFIG_USB_ET61X251_MODULE
 	{USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX},
+#endif
 	{}
 };
 
@@ -926,6 +918,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 15d302b..7be6928 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -114,7 +114,10 @@
 	cam_pkt_op pkt_scan;
 
 	if (urb->status != 0) {
-		PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
+#ifdef CONFIG_PM
+		if (!gspca_dev->frozen)
+#endif
+			PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
 		return;		/* disconnection ? */
 	}
 	pkt_scan = gspca_dev->sd_desc->pkt_scan;
@@ -555,10 +558,12 @@
 	gspca_dev->streaming = 0;
 	atomic_set(&gspca_dev->nevent, 0);
 	if (gspca_dev->present) {
-		gspca_dev->sd_desc->stopN(gspca_dev);
+		if (gspca_dev->sd_desc->stopN)
+			gspca_dev->sd_desc->stopN(gspca_dev);
 		destroy_urbs(gspca_dev);
 		gspca_set_alt0(gspca_dev);
-		gspca_dev->sd_desc->stop0(gspca_dev);
+		if (gspca_dev->sd_desc->stop0)
+			gspca_dev->sd_desc->stop0(gspca_dev);
 		PDEBUG(D_STREAM, "stream off OK");
 	}
 }
@@ -767,19 +772,7 @@
 		goto out;
 	}
 
-	/* if not done yet, initialize the sensor */
-	if (gspca_dev->users == 0) {
-		if (mutex_lock_interruptible(&gspca_dev->usb_lock)) {
-			ret = -ERESTARTSYS;
-			goto out;
-		}
-		ret = gspca_dev->sd_desc->open(gspca_dev);
-		mutex_unlock(&gspca_dev->usb_lock);
-		if (ret != 0) {
-			PDEBUG(D_ERR|D_CONF, "init device failed %d", ret);
-			goto out;
-		}
-	} else if (gspca_dev->users > 4) {	/* (arbitrary value) */
+	if (gspca_dev->users > 4) {	/* (arbitrary value) */
 		ret = -EBUSY;
 		goto out;
 	}
@@ -792,6 +785,7 @@
 	else
 		gspca_dev->vdev.debug &= ~3;
 #endif
+	ret = 0;
 out:
 	mutex_unlock(&gspca_dev->queue_lock);
 	if (ret != 0)
@@ -812,11 +806,11 @@
 
 	/* if the file did the capture, free the streaming resources */
 	if (gspca_dev->capt_file == file) {
-		mutex_lock(&gspca_dev->usb_lock);
-		if (gspca_dev->streaming)
+		if (gspca_dev->streaming) {
+			mutex_lock(&gspca_dev->usb_lock);
 			gspca_stream_off(gspca_dev);
-		gspca_dev->sd_desc->close(gspca_dev);
-		mutex_unlock(&gspca_dev->usb_lock);
+			mutex_unlock(&gspca_dev->usb_lock);
+		}
 		frame_free(gspca_dev);
 		gspca_dev->capt_file = NULL;
 		gspca_dev->memory = GSPCA_MEMORY_NO;
@@ -853,42 +847,44 @@
 	return 0;
 }
 
-/* the use of V4L2_CTRL_FLAG_NEXT_CTRL asks for the controls to be sorted */
 static int vidioc_queryctrl(struct file *file, void *priv,
 			   struct v4l2_queryctrl *q_ctrl)
 {
 	struct gspca_dev *gspca_dev = priv;
-	int i;
+	int i, ix;
 	u32 id;
 
+	ix = -1;
 	id = q_ctrl->id;
 	if (id & V4L2_CTRL_FLAG_NEXT_CTRL) {
 		id &= V4L2_CTRL_ID_MASK;
 		id++;
 		for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
-			if (id >= gspca_dev->sd_desc->ctrls[i].qctrl.id) {
-				memcpy(q_ctrl,
-					&gspca_dev->sd_desc->ctrls[i].qctrl,
-					sizeof *q_ctrl);
-				return 0;
+			if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id)
+				continue;
+			if (ix < 0) {
+				ix = i;
+				continue;
 			}
+			if (gspca_dev->sd_desc->ctrls[i].qctrl.id
+				    > gspca_dev->sd_desc->ctrls[ix].qctrl.id)
+				continue;
+			ix = i;
 		}
-		return -EINVAL;
 	}
 	for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
 		if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) {
-			memcpy(q_ctrl,
-				&gspca_dev->sd_desc->ctrls[i].qctrl,
-				sizeof *q_ctrl);
-			return 0;
+			ix = i;
+			break;
 		}
 	}
-	if (id >= V4L2_CID_BASE
-	    && id <= V4L2_CID_LASTP1) {
+	if (ix < 0)
+		return -EINVAL;
+	memcpy(q_ctrl, &gspca_dev->sd_desc->ctrls[ix].qctrl,
+		sizeof *q_ctrl);
+	if (gspca_dev->ctrl_dis & (1 << ix))
 		q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
-		return 0;
-	}
-	return -EINVAL;
+	return 0;
 }
 
 static int vidioc_s_ctrl(struct file *file, void *priv,
@@ -903,6 +899,8 @@
 	     i++, ctrls++) {
 		if (ctrl->id != ctrls->qctrl.id)
 			continue;
+		if (gspca_dev->ctrl_dis & (1 << i))
+			return -EINVAL;
 		if (ctrl->value < ctrls->qctrl.minimum
 		    || ctrl->value > ctrls->qctrl.maximum)
 			return -ERANGE;
@@ -929,6 +927,8 @@
 	     i++, ctrls++) {
 		if (ctrl->id != ctrls->qctrl.id)
 			continue;
+		if (gspca_dev->ctrl_dis & (1 << i))
+			return -EINVAL;
 		if (mutex_lock_interruptible(&gspca_dev->usb_lock))
 			return -ERESTARTSYS;
 		ret = ctrls->get(gspca_dev, &ctrl->value);
@@ -1403,7 +1403,7 @@
 	i = ret;				/* frame index */
 	frame = &gspca_dev->frame[i];
 	if (gspca_dev->memory == V4L2_MEMORY_USERPTR) {
-		if (copy_to_user((__u8 *) frame->v4l2_buf.m.userptr,
+		if (copy_to_user((__u8 __user *) frame->v4l2_buf.m.userptr,
 				 frame->data,
 				 frame->v4l2_buf.bytesused)) {
 			PDEBUG(D_ERR|D_STREAM,
@@ -1731,6 +1731,12 @@
 		err("couldn't kzalloc gspca struct");
 		return -EIO;
 	}
+	gspca_dev->usb_buf = kmalloc(USB_BUF_SZ, GFP_KERNEL);
+	if (!gspca_dev->usb_buf) {
+		err("out of memory");
+		ret = -EIO;
+		goto out;
+	}
 	gspca_dev->dev = dev;
 	gspca_dev->iface = interface->bInterfaceNumber;
 	gspca_dev->nbalt = intf->num_altsetting;
@@ -1738,10 +1744,13 @@
 /*	gspca_dev->users = 0;			(done by kzalloc) */
 	gspca_dev->nbufread = 2;
 
-	/* configure the subdriver */
+	/* configure the subdriver and initialize the USB device */
 	ret = gspca_dev->sd_desc->config(gspca_dev, id);
 	if (ret < 0)
 		goto out;
+	ret = gspca_dev->sd_desc->init(gspca_dev);
+	if (ret < 0)
+		goto out;
 	ret = gspca_set_alt0(gspca_dev);
 	if (ret < 0)
 		goto out;
@@ -1771,6 +1780,7 @@
 	PDEBUG(D_PROBE, "probe ok");
 	return 0;
 out:
+	kfree(gspca_dev->usb_buf);
 	kfree(gspca_dev);
 	return ret;
 }
@@ -1803,11 +1813,42 @@
 /* We don't want people trying to open up the device */
 	video_unregister_device(&gspca_dev->vdev);
 /* Free the memory */
+	kfree(gspca_dev->usb_buf);
 	kfree(gspca_dev);
 	PDEBUG(D_PROBE, "disconnect complete");
 }
 EXPORT_SYMBOL(gspca_disconnect);
 
+#ifdef CONFIG_PM
+int gspca_suspend(struct usb_interface *intf, pm_message_t message)
+{
+	struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
+
+	if (!gspca_dev->streaming)
+		return 0;
+	gspca_dev->frozen = 1;		/* avoid urb error messages */
+	if (gspca_dev->sd_desc->stopN)
+		gspca_dev->sd_desc->stopN(gspca_dev);
+	destroy_urbs(gspca_dev);
+	gspca_set_alt0(gspca_dev);
+	if (gspca_dev->sd_desc->stop0)
+		gspca_dev->sd_desc->stop0(gspca_dev);
+	return 0;
+}
+EXPORT_SYMBOL(gspca_suspend);
+
+int gspca_resume(struct usb_interface *intf)
+{
+	struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
+
+	gspca_dev->frozen = 0;
+	gspca_dev->sd_desc->init(gspca_dev);
+	if (gspca_dev->streaming)
+		return gspca_init_transfer(gspca_dev);
+	return 0;
+}
+EXPORT_SYMBOL(gspca_resume);
+#endif
 /* -- cam driver utility functions -- */
 
 /* auto gain and exposure algorithm based on the knee algorithm described here:
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 67e4489..c17625c 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -56,7 +56,6 @@
 
 /* device information - set at probe time */
 struct cam {
-	char *dev_name;
 	struct v4l2_pix_format *cam_mode;	/* size nmodes */
 	char nmodes;
 	__u8 epaddr;
@@ -91,15 +90,14 @@
 /* controls */
 	const struct ctrl *ctrls;
 	int nctrls;
-/* operations */
+/* mandatory operations */
 	cam_cf_op config;	/* called on probe */
-	cam_op open;		/* called on open */
+	cam_op init;		/* called on probe and resume */
 	cam_v_op start;		/* called on stream on */
-	cam_v_op stopN;		/* called on stream off - main alt */
-	cam_v_op stop0;		/* called on stream off - alt 0 */
-	cam_v_op close;		/* called on close */
 	cam_pkt_op pkt_scan;
 /* optional operations */
+	cam_v_op stopN;		/* called on stream off - main alt */
+	cam_v_op stop0;		/* called on stream off - alt 0 */
 	cam_v_op dq_callback;	/* called when a frame has been dequeued */
 	cam_jpg_op get_jcomp;
 	cam_jpg_op set_jcomp;
@@ -127,8 +125,10 @@
 
 	struct cam cam;				/* device information */
 	const struct sd_desc *sd_desc;		/* subdriver description */
+	unsigned ctrl_dis;		/* disabled controls (bit map) */
 
-	__u8 usb_buf[8];			/* buffer for USB exchanges */
+#define USB_BUF_SZ 64
+	__u8 *usb_buf;				/* buffer for USB exchanges */
 	struct urb *urb[MAX_NURBS];
 
 	__u8 *frbuf;				/* buffer for nframes */
@@ -155,6 +155,9 @@
 	struct mutex queue_lock;	/* ISOC queue protection */
 	__u32 sequence;			/* frame sequence number */
 	char streaming;
+#ifdef CONFIG_PM
+	char frozen;			/* suspend - resume */
+#endif
 	char users;			/* number of opens */
 	char present;			/* device connected */
 	char nbufread;			/* number of buffers for read() */
@@ -174,6 +177,10 @@
 				    struct gspca_frame *frame,
 				    const __u8 *data,
 				    int len);
+#ifdef CONFIG_PM
+int gspca_suspend(struct usb_interface *intf, pm_message_t message);
+int gspca_resume(struct usb_interface *intf);
+#endif
 int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum,
 	int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee);
 #endif /* GSPCAV2_H */
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index 21c4ee5..4d5db47 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -100,22 +100,6 @@
 	return rc;
 }
 
-static int reg_w_buf(struct gspca_dev *gspca_dev,
-			__u16 index, __u8 *buf, int len)
-{
-	int rc;
-
-	rc = usb_control_msg(gspca_dev->dev,
-			 usb_sndbulkpipe(gspca_dev->dev, 4),
-			 0x12,
-			 0xc8,		/* ?? */
-			 0,		/* value */
-			 index, buf, len, 500);
-	if (rc < 0)
-		PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc);
-	return rc;
-}
-
 static void bulk_w(struct gspca_dev *gspca_dev,
 		   __u16 *pch,
 		   __u16 Address)
@@ -144,8 +128,8 @@
 	return 0;
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
 {
 	return 0;
 }
@@ -175,7 +159,6 @@
 	/*
 	   Initialize the MR97113 chip register
 	 */
-	data = kmalloc(16, GFP_KERNEL);
 	data[0] = 0x00;		/* address */
 	data[1] = 0x0c | 0x01;	/* reg 0 */
 	data[2] = 0x01;		/* reg 1 */
@@ -195,12 +178,10 @@
 	data[10] = 0x5d;	/* reg 9, I2C device address
 				 *	[for PAS5101 (0x40)] [for MI (0x5d)] */
 
-	err_code = reg_w_buf(gspca_dev, data[0], data, 11);
-	kfree(data);
+	err_code = reg_w(gspca_dev, data[0], 11);
 	if (err_code < 0)
 		return;
 
-	data = gspca_dev->usb_buf;
 	data[0] = 0x23;		/* address */
 	data[1] = 0x09;		/* reg 35, append frame header */
 
@@ -358,14 +339,6 @@
 		PDEBUG(D_ERR, "Camera Stop failed");
 }
 
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
-}
-
-static void sd_close(struct gspca_dev *gspca_dev)
-{
-}
-
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
@@ -411,11 +384,9 @@
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
-	.open = sd_open,
+	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
-	.stop0 = sd_stop0,
-	.close = sd_close,
 	.pkt_scan = sd_pkt_scan,
 };
 
@@ -439,6 +410,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index b4f00ec..4df4eec 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -63,11 +63,10 @@
 #define SEN_OV6630 2
 #define SEN_OV7610 3
 #define SEN_OV7620 4
-#define SEN_OV7630 5
-#define SEN_OV7640 6
-#define SEN_OV7670 7
-#define SEN_OV76BE 8
-#define SEN_OV8610 9
+#define SEN_OV7640 5
+#define SEN_OV7670 6
+#define SEN_OV76BE 7
+#define SEN_OV8610 8
 
 };
 
@@ -127,6 +126,7 @@
 	    .get = sd_getcolors,
 	},
 /* next controls work with ov7670 only */
+#define HFLIP_IDX 3
 	{
 	    {
 		.id      = V4L2_CID_HFLIP,
@@ -141,6 +141,7 @@
 	    .set = sd_sethflip,
 	    .get = sd_gethflip,
 	},
+#define VFLIP_IDX 4
 	{
 	    {
 		.id      = V4L2_CID_VFLIP,
@@ -293,6 +294,541 @@
 #define OV7670_REG_HAECC7      0xaa    /* Hist AEC/AGC control 7 */
 #define OV7670_REG_BD60MAX     0xab    /* 60hz banding step limit */
 
+struct ov_regvals {
+	__u8 reg;
+	__u8 val;
+};
+struct ov_i2c_regvals {
+	__u8 reg;
+	__u8 val;
+};
+
+static const struct ov_i2c_regvals norm_6x20[] = {
+	{ 0x12, 0x80 }, /* reset */
+	{ 0x11, 0x01 },
+	{ 0x03, 0x60 },
+	{ 0x05, 0x7f }, /* For when autoadjust is off */
+	{ 0x07, 0xa8 },
+	/* The ratio of 0x0c and 0x0d  controls the white point */
+	{ 0x0c, 0x24 },
+	{ 0x0d, 0x24 },
+	{ 0x0f, 0x15 }, /* COMS */
+	{ 0x10, 0x75 }, /* AEC Exposure time */
+	{ 0x12, 0x24 }, /* Enable AGC */
+	{ 0x14, 0x04 },
+	/* 0x16: 0x06 helps frame stability with moving objects */
+	{ 0x16, 0x06 },
+/*	{ 0x20, 0x30 },  * Aperture correction enable */
+	{ 0x26, 0xb2 }, /* BLC enable */
+	/* 0x28: 0x05 Selects RGB format if RGB on */
+	{ 0x28, 0x05 },
+	{ 0x2a, 0x04 }, /* Disable framerate adjust */
+/*	{ 0x2b, 0xac },  * Framerate; Set 2a[7] first */
+	{ 0x2d, 0x99 },
+	{ 0x33, 0xa0 }, /* Color Processing Parameter */
+	{ 0x34, 0xd2 }, /* Max A/D range */
+	{ 0x38, 0x8b },
+	{ 0x39, 0x40 },
+
+	{ 0x3c, 0x39 }, /* Enable AEC mode changing */
+	{ 0x3c, 0x3c }, /* Change AEC mode */
+	{ 0x3c, 0x24 }, /* Disable AEC mode changing */
+
+	{ 0x3d, 0x80 },
+	/* These next two registers (0x4a, 0x4b) are undocumented.
+	 * They control the color balance */
+	{ 0x4a, 0x80 },
+	{ 0x4b, 0x80 },
+	{ 0x4d, 0xd2 }, /* This reduces noise a bit */
+	{ 0x4e, 0xc1 },
+	{ 0x4f, 0x04 },
+/* Do 50-53 have any effect? */
+/* Toggle 0x12[2] off and on here? */
+};
+
+static const struct ov_i2c_regvals norm_6x30[] = {
+	{ 0x12, 0x80 }, /* Reset */
+	{ 0x00, 0x1f }, /* Gain */
+	{ 0x01, 0x99 }, /* Blue gain */
+	{ 0x02, 0x7c }, /* Red gain */
+	{ 0x03, 0xc0 }, /* Saturation */
+	{ 0x05, 0x0a }, /* Contrast */
+	{ 0x06, 0x95 }, /* Brightness */
+	{ 0x07, 0x2d }, /* Sharpness */
+	{ 0x0c, 0x20 },
+	{ 0x0d, 0x20 },
+	{ 0x0e, 0x20 },
+	{ 0x0f, 0x05 },
+	{ 0x10, 0x9a },
+	{ 0x11, 0x00 }, /* Pixel clock = fastest */
+	{ 0x12, 0x24 }, /* Enable AGC and AWB */
+	{ 0x13, 0x21 },
+	{ 0x14, 0x80 },
+	{ 0x15, 0x01 },
+	{ 0x16, 0x03 },
+	{ 0x17, 0x38 },
+	{ 0x18, 0xea },
+	{ 0x19, 0x04 },
+	{ 0x1a, 0x93 },
+	{ 0x1b, 0x00 },
+	{ 0x1e, 0xc4 },
+	{ 0x1f, 0x04 },
+	{ 0x20, 0x20 },
+	{ 0x21, 0x10 },
+	{ 0x22, 0x88 },
+	{ 0x23, 0xc0 }, /* Crystal circuit power level */
+	{ 0x25, 0x9a }, /* Increase AEC black ratio */
+	{ 0x26, 0xb2 }, /* BLC enable */
+	{ 0x27, 0xa2 },
+	{ 0x28, 0x00 },
+	{ 0x29, 0x00 },
+	{ 0x2a, 0x84 }, /* 60 Hz power */
+	{ 0x2b, 0xa8 }, /* 60 Hz power */
+	{ 0x2c, 0xa0 },
+	{ 0x2d, 0x95 }, /* Enable auto-brightness */
+	{ 0x2e, 0x88 },
+	{ 0x33, 0x26 },
+	{ 0x34, 0x03 },
+	{ 0x36, 0x8f },
+	{ 0x37, 0x80 },
+	{ 0x38, 0x83 },
+	{ 0x39, 0x80 },
+	{ 0x3a, 0x0f },
+	{ 0x3b, 0x3c },
+	{ 0x3c, 0x1a },
+	{ 0x3d, 0x80 },
+	{ 0x3e, 0x80 },
+	{ 0x3f, 0x0e },
+	{ 0x40, 0x00 }, /* White bal */
+	{ 0x41, 0x00 }, /* White bal */
+	{ 0x42, 0x80 },
+	{ 0x43, 0x3f }, /* White bal */
+	{ 0x44, 0x80 },
+	{ 0x45, 0x20 },
+	{ 0x46, 0x20 },
+	{ 0x47, 0x80 },
+	{ 0x48, 0x7f },
+	{ 0x49, 0x00 },
+	{ 0x4a, 0x00 },
+	{ 0x4b, 0x80 },
+	{ 0x4c, 0xd0 },
+	{ 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
+	{ 0x4e, 0x40 },
+	{ 0x4f, 0x07 }, /* UV avg., col. killer: max */
+	{ 0x50, 0xff },
+	{ 0x54, 0x23 }, /* Max AGC gain: 18dB */
+	{ 0x55, 0xff },
+	{ 0x56, 0x12 },
+	{ 0x57, 0x81 },
+	{ 0x58, 0x75 },
+	{ 0x59, 0x01 }, /* AGC dark current comp.: +1 */
+	{ 0x5a, 0x2c },
+	{ 0x5b, 0x0f }, /* AWB chrominance levels */
+	{ 0x5c, 0x10 },
+	{ 0x3d, 0x80 },
+	{ 0x27, 0xa6 },
+	{ 0x12, 0x20 }, /* Toggle AWB */
+	{ 0x12, 0x24 },
+};
+
+/* Lawrence Glaister <lg@jfm.bc.ca> reports:
+ *
+ * Register 0x0f in the 7610 has the following effects:
+ *
+ * 0x85 (AEC method 1): Best overall, good contrast range
+ * 0x45 (AEC method 2): Very overexposed
+ * 0xa5 (spec sheet default): Ok, but the black level is
+ *	shifted resulting in loss of contrast
+ * 0x05 (old driver setting): very overexposed, too much
+ *	contrast
+ */
+static const struct ov_i2c_regvals norm_7610[] = {
+	{ 0x10, 0xff },
+	{ 0x16, 0x06 },
+	{ 0x28, 0x24 },
+	{ 0x2b, 0xac },
+	{ 0x12, 0x00 },
+	{ 0x38, 0x81 },
+	{ 0x28, 0x24 },	/* 0c */
+	{ 0x0f, 0x85 },	/* lg's setting */
+	{ 0x15, 0x01 },
+	{ 0x20, 0x1c },
+	{ 0x23, 0x2a },
+	{ 0x24, 0x10 },
+	{ 0x25, 0x8a },
+	{ 0x26, 0xa2 },
+	{ 0x27, 0xc2 },
+	{ 0x2a, 0x04 },
+	{ 0x2c, 0xfe },
+	{ 0x2d, 0x93 },
+	{ 0x30, 0x71 },
+	{ 0x31, 0x60 },
+	{ 0x32, 0x26 },
+	{ 0x33, 0x20 },
+	{ 0x34, 0x48 },
+	{ 0x12, 0x24 },
+	{ 0x11, 0x01 },
+	{ 0x0c, 0x24 },
+	{ 0x0d, 0x24 },
+};
+
+static const struct ov_i2c_regvals norm_7620[] = {
+	{ 0x00, 0x00 },		/* gain */
+	{ 0x01, 0x80 },		/* blue gain */
+	{ 0x02, 0x80 },		/* red gain */
+	{ 0x03, 0xc0 },		/* OV7670_REG_VREF */
+	{ 0x06, 0x60 },
+	{ 0x07, 0x00 },
+	{ 0x0c, 0x24 },
+	{ 0x0c, 0x24 },
+	{ 0x0d, 0x24 },
+	{ 0x11, 0x01 },
+	{ 0x12, 0x24 },
+	{ 0x13, 0x01 },
+	{ 0x14, 0x84 },
+	{ 0x15, 0x01 },
+	{ 0x16, 0x03 },
+	{ 0x17, 0x2f },
+	{ 0x18, 0xcf },
+	{ 0x19, 0x06 },
+	{ 0x1a, 0xf5 },
+	{ 0x1b, 0x00 },
+	{ 0x20, 0x18 },
+	{ 0x21, 0x80 },
+	{ 0x22, 0x80 },
+	{ 0x23, 0x00 },
+	{ 0x26, 0xa2 },
+	{ 0x27, 0xea },
+	{ 0x28, 0x20 },
+	{ 0x29, 0x00 },
+	{ 0x2a, 0x10 },
+	{ 0x2b, 0x00 },
+	{ 0x2c, 0x88 },
+	{ 0x2d, 0x91 },
+	{ 0x2e, 0x80 },
+	{ 0x2f, 0x44 },
+	{ 0x60, 0x27 },
+	{ 0x61, 0x02 },
+	{ 0x62, 0x5f },
+	{ 0x63, 0xd5 },
+	{ 0x64, 0x57 },
+	{ 0x65, 0x83 },
+	{ 0x66, 0x55 },
+	{ 0x67, 0x92 },
+	{ 0x68, 0xcf },
+	{ 0x69, 0x76 },
+	{ 0x6a, 0x22 },
+	{ 0x6b, 0x00 },
+	{ 0x6c, 0x02 },
+	{ 0x6d, 0x44 },
+	{ 0x6e, 0x80 },
+	{ 0x6f, 0x1d },
+	{ 0x70, 0x8b },
+	{ 0x71, 0x00 },
+	{ 0x72, 0x14 },
+	{ 0x73, 0x54 },
+	{ 0x74, 0x00 },
+	{ 0x75, 0x8e },
+	{ 0x76, 0x00 },
+	{ 0x77, 0xff },
+	{ 0x78, 0x80 },
+	{ 0x79, 0x80 },
+	{ 0x7a, 0x80 },
+	{ 0x7b, 0xe2 },
+	{ 0x7c, 0x00 },
+};
+
+/* 7640 and 7648. The defaults should be OK for most registers. */
+static const struct ov_i2c_regvals norm_7640[] = {
+	{ 0x12, 0x80 },
+	{ 0x12, 0x14 },
+};
+
+/* 7670. Defaults taken from OmniVision provided data,
+*  as provided by Jonathan Corbet of OLPC		*/
+static const struct ov_i2c_regvals norm_7670[] = {
+	{ OV7670_REG_COM7, OV7670_COM7_RESET },
+	{ OV7670_REG_TSLB, 0x04 },		/* OV */
+	{ OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
+	{ OV7670_REG_CLKRC, 0x01 },
+/*
+ * Set the hardware window.  These values from OV don't entirely
+ * make sense - hstop is less than hstart.  But they work...
+ */
+	{ OV7670_REG_HSTART, 0x13 },
+	{ OV7670_REG_HSTOP, 0x01 },
+	{ OV7670_REG_HREF, 0xb6 },
+	{ OV7670_REG_VSTART, 0x02 },
+	{ OV7670_REG_VSTOP, 0x7a },
+	{ OV7670_REG_VREF, 0x0a },
+
+	{ OV7670_REG_COM3, 0 },
+	{ OV7670_REG_COM14, 0 },
+/* Mystery scaling numbers */
+	{ 0x70, 0x3a },
+	{ 0x71, 0x35 },
+	{ 0x72, 0x11 },
+	{ 0x73, 0xf0 },
+	{ 0xa2, 0x02 },
+/*	{ OV7670_REG_COM10, 0x0 }, */
+
+/* Gamma curve values */
+	{ 0x7a, 0x20 },
+	{ 0x7b, 0x10 },
+	{ 0x7c, 0x1e },
+	{ 0x7d, 0x35 },
+	{ 0x7e, 0x5a },
+	{ 0x7f, 0x69 },
+	{ 0x80, 0x76 },
+	{ 0x81, 0x80 },
+	{ 0x82, 0x88 },
+	{ 0x83, 0x8f },
+	{ 0x84, 0x96 },
+	{ 0x85, 0xa3 },
+	{ 0x86, 0xaf },
+	{ 0x87, 0xc4 },
+	{ 0x88, 0xd7 },
+	{ 0x89, 0xe8 },
+
+/* AGC and AEC parameters.  Note we start by disabling those features,
+   then turn them only after tweaking the values. */
+	{ OV7670_REG_COM8, OV7670_COM8_FASTAEC
+			 | OV7670_COM8_AECSTEP
+			 | OV7670_COM8_BFILT },
+	{ OV7670_REG_GAIN, 0 },
+	{ OV7670_REG_AECH, 0 },
+	{ OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
+	{ OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
+	{ OV7670_REG_BD50MAX, 0x05 },
+	{ OV7670_REG_BD60MAX, 0x07 },
+	{ OV7670_REG_AEW, 0x95 },
+	{ OV7670_REG_AEB, 0x33 },
+	{ OV7670_REG_VPT, 0xe3 },
+	{ OV7670_REG_HAECC1, 0x78 },
+	{ OV7670_REG_HAECC2, 0x68 },
+	{ 0xa1, 0x03 }, /* magic */
+	{ OV7670_REG_HAECC3, 0xd8 },
+	{ OV7670_REG_HAECC4, 0xd8 },
+	{ OV7670_REG_HAECC5, 0xf0 },
+	{ OV7670_REG_HAECC6, 0x90 },
+	{ OV7670_REG_HAECC7, 0x94 },
+	{ OV7670_REG_COM8, OV7670_COM8_FASTAEC
+			| OV7670_COM8_AECSTEP
+			| OV7670_COM8_BFILT
+			| OV7670_COM8_AGC
+			| OV7670_COM8_AEC },
+
+/* Almost all of these are magic "reserved" values.  */
+	{ OV7670_REG_COM5, 0x61 },
+	{ OV7670_REG_COM6, 0x4b },
+	{ 0x16, 0x02 },
+	{ OV7670_REG_MVFP, 0x07 },
+	{ 0x21, 0x02 },
+	{ 0x22, 0x91 },
+	{ 0x29, 0x07 },
+	{ 0x33, 0x0b },
+	{ 0x35, 0x0b },
+	{ 0x37, 0x1d },
+	{ 0x38, 0x71 },
+	{ 0x39, 0x2a },
+	{ OV7670_REG_COM12, 0x78 },
+	{ 0x4d, 0x40 },
+	{ 0x4e, 0x20 },
+	{ OV7670_REG_GFIX, 0 },
+	{ 0x6b, 0x4a },
+	{ 0x74, 0x10 },
+	{ 0x8d, 0x4f },
+	{ 0x8e, 0 },
+	{ 0x8f, 0 },
+	{ 0x90, 0 },
+	{ 0x91, 0 },
+	{ 0x96, 0 },
+	{ 0x9a, 0 },
+	{ 0xb0, 0x84 },
+	{ 0xb1, 0x0c },
+	{ 0xb2, 0x0e },
+	{ 0xb3, 0x82 },
+	{ 0xb8, 0x0a },
+
+/* More reserved magic, some of which tweaks white balance */
+	{ 0x43, 0x0a },
+	{ 0x44, 0xf0 },
+	{ 0x45, 0x34 },
+	{ 0x46, 0x58 },
+	{ 0x47, 0x28 },
+	{ 0x48, 0x3a },
+	{ 0x59, 0x88 },
+	{ 0x5a, 0x88 },
+	{ 0x5b, 0x44 },
+	{ 0x5c, 0x67 },
+	{ 0x5d, 0x49 },
+	{ 0x5e, 0x0e },
+	{ 0x6c, 0x0a },
+	{ 0x6d, 0x55 },
+	{ 0x6e, 0x11 },
+	{ 0x6f, 0x9f },
+					/* "9e for advance AWB" */
+	{ 0x6a, 0x40 },
+	{ OV7670_REG_BLUE, 0x40 },
+	{ OV7670_REG_RED, 0x60 },
+	{ OV7670_REG_COM8, OV7670_COM8_FASTAEC
+			| OV7670_COM8_AECSTEP
+			| OV7670_COM8_BFILT
+			| OV7670_COM8_AGC
+			| OV7670_COM8_AEC
+			| OV7670_COM8_AWB },
+
+/* Matrix coefficients */
+	{ 0x4f, 0x80 },
+	{ 0x50, 0x80 },
+	{ 0x51, 0 },
+	{ 0x52, 0x22 },
+	{ 0x53, 0x5e },
+	{ 0x54, 0x80 },
+	{ 0x58, 0x9e },
+
+	{ OV7670_REG_COM16, OV7670_COM16_AWBGAIN },
+	{ OV7670_REG_EDGE, 0 },
+	{ 0x75, 0x05 },
+	{ 0x76, 0xe1 },
+	{ 0x4c, 0 },
+	{ 0x77, 0x01 },
+	{ OV7670_REG_COM13, OV7670_COM13_GAMMA
+			  | OV7670_COM13_UVSAT
+			  | 2},		/* was 3 */
+	{ 0x4b, 0x09 },
+	{ 0xc9, 0x60 },
+	{ OV7670_REG_COM16, 0x38 },
+	{ 0x56, 0x40 },
+
+	{ 0x34, 0x11 },
+	{ OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
+	{ 0xa4, 0x88 },
+	{ 0x96, 0 },
+	{ 0x97, 0x30 },
+	{ 0x98, 0x20 },
+	{ 0x99, 0x30 },
+	{ 0x9a, 0x84 },
+	{ 0x9b, 0x29 },
+	{ 0x9c, 0x03 },
+	{ 0x9d, 0x4c },
+	{ 0x9e, 0x3f },
+	{ 0x78, 0x04 },
+
+/* Extra-weird stuff.  Some sort of multiplexor register */
+	{ 0x79, 0x01 },
+	{ 0xc8, 0xf0 },
+	{ 0x79, 0x0f },
+	{ 0xc8, 0x00 },
+	{ 0x79, 0x10 },
+	{ 0xc8, 0x7e },
+	{ 0x79, 0x0a },
+	{ 0xc8, 0x80 },
+	{ 0x79, 0x0b },
+	{ 0xc8, 0x01 },
+	{ 0x79, 0x0c },
+	{ 0xc8, 0x0f },
+	{ 0x79, 0x0d },
+	{ 0xc8, 0x20 },
+	{ 0x79, 0x09 },
+	{ 0xc8, 0x80 },
+	{ 0x79, 0x02 },
+	{ 0xc8, 0xc0 },
+	{ 0x79, 0x03 },
+	{ 0xc8, 0x40 },
+	{ 0x79, 0x05 },
+	{ 0xc8, 0x30 },
+	{ 0x79, 0x26 },
+};
+
+static const struct ov_i2c_regvals norm_8610[] = {
+	{ 0x12, 0x80 },
+	{ 0x00, 0x00 },
+	{ 0x01, 0x80 },
+	{ 0x02, 0x80 },
+	{ 0x03, 0xc0 },
+	{ 0x04, 0x30 },
+	{ 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */
+	{ 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */
+	{ 0x0a, 0x86 },
+	{ 0x0b, 0xb0 },
+	{ 0x0c, 0x20 },
+	{ 0x0d, 0x20 },
+	{ 0x11, 0x01 },
+	{ 0x12, 0x25 },
+	{ 0x13, 0x01 },
+	{ 0x14, 0x04 },
+	{ 0x15, 0x01 }, /* Lin and Win think different about UV order */
+	{ 0x16, 0x03 },
+	{ 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */
+	{ 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */
+	{ 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */
+	{ 0x1a, 0xf5 },
+	{ 0x1b, 0x00 },
+	{ 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */
+	{ 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */
+	{ 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */
+	{ 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */
+	{ 0x26, 0xa2 },
+	{ 0x27, 0xea },
+	{ 0x28, 0x00 },
+	{ 0x29, 0x00 },
+	{ 0x2a, 0x80 },
+	{ 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */
+	{ 0x2c, 0xac },
+	{ 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */
+	{ 0x2e, 0x80 },
+	{ 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */
+	{ 0x4c, 0x00 },
+	{ 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */
+	{ 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */
+	{ 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */
+	{ 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */
+	{ 0x63, 0xff },
+	{ 0x64, 0x53 }, /* new windrv 090403 says 0x57,
+			 * maybe thats wrong */
+	{ 0x65, 0x00 },
+	{ 0x66, 0x55 },
+	{ 0x67, 0xb0 },
+	{ 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */
+	{ 0x69, 0x02 },
+	{ 0x6a, 0x22 },
+	{ 0x6b, 0x00 },
+	{ 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but
+			 * deleting bit7 colors the first images red */
+	{ 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */
+	{ 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */
+	{ 0x6f, 0x01 },
+	{ 0x70, 0x8b },
+	{ 0x71, 0x00 },
+	{ 0x72, 0x14 },
+	{ 0x73, 0x54 },
+	{ 0x74, 0x00 },/* 0x60? - was 0x00, new from windrv 090403 */
+	{ 0x75, 0x0e },
+	{ 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */
+	{ 0x77, 0xff },
+	{ 0x78, 0x80 },
+	{ 0x79, 0x80 },
+	{ 0x7a, 0x80 },
+	{ 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */
+	{ 0x7c, 0x00 },
+	{ 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */
+	{ 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */
+	{ 0x7f, 0xfb },
+	{ 0x80, 0x28 },
+	{ 0x81, 0x00 },
+	{ 0x82, 0x23 },
+	{ 0x83, 0x0b },
+	{ 0x84, 0x00 },
+	{ 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */
+	{ 0x86, 0xc9 },
+	{ 0x87, 0x00 },
+	{ 0x88, 0x00 },
+	{ 0x89, 0x01 },
+	{ 0x12, 0x20 },
+	{ 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */
+};
+
 static unsigned char ov7670_abs_to_sm(unsigned char v)
 {
 	if (v > 127)
@@ -537,18 +1073,10 @@
 	rc = reg_w(sd, R51x_I2C_W_SID, slave);
 	if (rc < 0)
 		return rc;
+	sd->primary_i2c_slave = slave;
 	return reg_w(sd, R51x_I2C_R_SID, slave + 1);
 }
 
-struct ov_regvals {
-	__u8 reg;
-	__u8 val;
-};
-struct ov_i2c_regvals {
-	__u8 reg;
-	__u8 val;
-};
-
 static int write_regvals(struct sd *sd,
 			 const struct ov_regvals *regvals,
 			 int n)
@@ -591,101 +1119,9 @@
 static int ov8xx0_configure(struct sd *sd)
 {
 	int rc;
-	static const struct ov_i2c_regvals norm_8610[] = {
-		{ 0x12, 0x80 },
-		{ 0x00, 0x00 },
-		{ 0x01, 0x80 },
-		{ 0x02, 0x80 },
-		{ 0x03, 0xc0 },
-		{ 0x04, 0x30 },
-		{ 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */
-		{ 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */
-		{ 0x0a, 0x86 },
-		{ 0x0b, 0xb0 },
-		{ 0x0c, 0x20 },
-		{ 0x0d, 0x20 },
-		{ 0x11, 0x01 },
-		{ 0x12, 0x25 },
-		{ 0x13, 0x01 },
-		{ 0x14, 0x04 },
-		{ 0x15, 0x01 }, /* Lin and Win think different about UV order */
-		{ 0x16, 0x03 },
-		{ 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */
-		{ 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */
-		{ 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */
-		{ 0x1a, 0xf5 },
-		{ 0x1b, 0x00 },
-		{ 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */
-		{ 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */
-		{ 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */
-		{ 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */
-		{ 0x26, 0xa2 },
-		{ 0x27, 0xea },
-		{ 0x28, 0x00 },
-		{ 0x29, 0x00 },
-		{ 0x2a, 0x80 },
-		{ 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */
-		{ 0x2c, 0xac },
-		{ 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */
-		{ 0x2e, 0x80 },
-		{ 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */
-		{ 0x4c, 0x00 },
-		{ 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */
-		{ 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */
-		{ 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */
-		{ 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */
-		{ 0x63, 0xff },
-		{ 0x64, 0x53 }, /* new windrv 090403 says 0x57,
-				 * maybe thats wrong */
-		{ 0x65, 0x00 },
-		{ 0x66, 0x55 },
-		{ 0x67, 0xb0 },
-		{ 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */
-		{ 0x69, 0x02 },
-		{ 0x6a, 0x22 },
-		{ 0x6b, 0x00 },
-		{ 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but
-				   deleting bit7 colors the first images red */
-		{ 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */
-		{ 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */
-		{ 0x6f, 0x01 },
-		{ 0x70, 0x8b },
-		{ 0x71, 0x00 },
-		{ 0x72, 0x14 },
-		{ 0x73, 0x54 },
-		{ 0x74, 0x00 },/* 0x60? - was 0x00, new from windrv 090403 */
-		{ 0x75, 0x0e },
-		{ 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */
-		{ 0x77, 0xff },
-		{ 0x78, 0x80 },
-		{ 0x79, 0x80 },
-		{ 0x7a, 0x80 },
-		{ 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */
-		{ 0x7c, 0x00 },
-		{ 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */
-		{ 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */
-		{ 0x7f, 0xfb },
-		{ 0x80, 0x28 },
-		{ 0x81, 0x00 },
-		{ 0x82, 0x23 },
-		{ 0x83, 0x0b },
-		{ 0x84, 0x00 },
-		{ 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */
-		{ 0x86, 0xc9 },
-		{ 0x87, 0x00 },
-		{ 0x88, 0x00 },
-		{ 0x89, 0x01 },
-		{ 0x12, 0x20 },
-		{ 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */
-	};
 
 	PDEBUG(D_PROBE, "starting ov8xx0 configuration");
 
-	if (init_ov_sensor(sd) < 0)
-		PDEBUG(D_ERR|D_PROBE, "Failed to read sensor ID");
-	else
-		PDEBUG(D_PROBE, "OV86x0 initialized");
-
 	/* Detect sensor (sub)type */
 	rc = i2c_r(sd, OV7610_REG_COM_I);
 	if (rc < 0) {
@@ -698,9 +1134,6 @@
 		PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3);
 		return -1;
 	}
-	PDEBUG(D_PROBE, "Writing 8610 registers");
-	if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)))
-		return -1;
 
 	/* Set sensor-specific vars */
 /*	sd->sif = 0;		already done */
@@ -714,252 +1147,6 @@
 {
 	int rc, high, low;
 
-	/* Lawrence Glaister <lg@jfm.bc.ca> reports:
-	 *
-	 * Register 0x0f in the 7610 has the following effects:
-	 *
-	 * 0x85 (AEC method 1): Best overall, good contrast range
-	 * 0x45 (AEC method 2): Very overexposed
-	 * 0xa5 (spec sheet default): Ok, but the black level is
-	 *	shifted resulting in loss of contrast
-	 * 0x05 (old driver setting): very overexposed, too much
-	 *	contrast
-	 */
-	static const struct ov_i2c_regvals norm_7610[] = {
-		{ 0x10, 0xff },
-		{ 0x16, 0x06 },
-		{ 0x28, 0x24 },
-		{ 0x2b, 0xac },
-		{ 0x12, 0x00 },
-		{ 0x38, 0x81 },
-		{ 0x28, 0x24 },	/* 0c */
-		{ 0x0f, 0x85 },	/* lg's setting */
-		{ 0x15, 0x01 },
-		{ 0x20, 0x1c },
-		{ 0x23, 0x2a },
-		{ 0x24, 0x10 },
-		{ 0x25, 0x8a },
-		{ 0x26, 0xa2 },
-		{ 0x27, 0xc2 },
-		{ 0x2a, 0x04 },
-		{ 0x2c, 0xfe },
-		{ 0x2d, 0x93 },
-		{ 0x30, 0x71 },
-		{ 0x31, 0x60 },
-		{ 0x32, 0x26 },
-		{ 0x33, 0x20 },
-		{ 0x34, 0x48 },
-		{ 0x12, 0x24 },
-		{ 0x11, 0x01 },
-		{ 0x0c, 0x24 },
-		{ 0x0d, 0x24 },
-	};
-
-	static const struct ov_i2c_regvals norm_7620[] = {
-		{ 0x00, 0x00 },		/* gain */
-		{ 0x01, 0x80 },		/* blue gain */
-		{ 0x02, 0x80 },		/* red gain */
-		{ 0x03, 0xc0 },		/* OV7670_REG_VREF */
-		{ 0x06, 0x60 },
-		{ 0x07, 0x00 },
-		{ 0x0c, 0x24 },
-		{ 0x0c, 0x24 },
-		{ 0x0d, 0x24 },
-		{ 0x11, 0x01 },
-		{ 0x12, 0x24 },
-		{ 0x13, 0x01 },
-		{ 0x14, 0x84 },
-		{ 0x15, 0x01 },
-		{ 0x16, 0x03 },
-		{ 0x17, 0x2f },
-		{ 0x18, 0xcf },
-		{ 0x19, 0x06 },
-		{ 0x1a, 0xf5 },
-		{ 0x1b, 0x00 },
-		{ 0x20, 0x18 },
-		{ 0x21, 0x80 },
-		{ 0x22, 0x80 },
-		{ 0x23, 0x00 },
-		{ 0x26, 0xa2 },
-		{ 0x27, 0xea },
-		{ 0x28, 0x20 },
-		{ 0x29, 0x00 },
-		{ 0x2a, 0x10 },
-		{ 0x2b, 0x00 },
-		{ 0x2c, 0x88 },
-		{ 0x2d, 0x91 },
-		{ 0x2e, 0x80 },
-		{ 0x2f, 0x44 },
-		{ 0x60, 0x27 },
-		{ 0x61, 0x02 },
-		{ 0x62, 0x5f },
-		{ 0x63, 0xd5 },
-		{ 0x64, 0x57 },
-		{ 0x65, 0x83 },
-		{ 0x66, 0x55 },
-		{ 0x67, 0x92 },
-		{ 0x68, 0xcf },
-		{ 0x69, 0x76 },
-		{ 0x6a, 0x22 },
-		{ 0x6b, 0x00 },
-		{ 0x6c, 0x02 },
-		{ 0x6d, 0x44 },
-		{ 0x6e, 0x80 },
-		{ 0x6f, 0x1d },
-		{ 0x70, 0x8b },
-		{ 0x71, 0x00 },
-		{ 0x72, 0x14 },
-		{ 0x73, 0x54 },
-		{ 0x74, 0x00 },
-		{ 0x75, 0x8e },
-		{ 0x76, 0x00 },
-		{ 0x77, 0xff },
-		{ 0x78, 0x80 },
-		{ 0x79, 0x80 },
-		{ 0x7a, 0x80 },
-		{ 0x7b, 0xe2 },
-		{ 0x7c, 0x00 },
-	};
-
-	/* 7640 and 7648. The defaults should be OK for most registers. */
-	static const struct ov_i2c_regvals norm_7640[] = {
-		{ 0x12, 0x80 },
-		{ 0x12, 0x14 },
-	};
-
-	/* 7670. Defaults taken from OmniVision provided data,
-	*  as provided by Jonathan Corbet of OLPC		*/
-	static const struct ov_i2c_regvals norm_7670[] = {
-		{ OV7670_REG_COM7, OV7670_COM7_RESET },
-		{ OV7670_REG_TSLB, 0x04 },		/* OV */
-		{ OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
-		{ OV7670_REG_CLKRC, 0x01 },
-	/*
-	 * Set the hardware window.  These values from OV don't entirely
-	 * make sense - hstop is less than hstart.  But they work...
-	 */
-		{ OV7670_REG_HSTART, 0x13 },	{ OV7670_REG_HSTOP, 0x01 },
-		{ OV7670_REG_HREF, 0xb6 },	{ OV7670_REG_VSTART, 0x02 },
-		{ OV7670_REG_VSTOP, 0x7a },	{ OV7670_REG_VREF, 0x0a },
-
-		{ OV7670_REG_COM3, 0 },	{ OV7670_REG_COM14, 0 },
-	/* Mystery scaling numbers */
-		{ 0x70, 0x3a },		{ 0x71, 0x35 },
-		{ 0x72, 0x11 },		{ 0x73, 0xf0 },
-		{ 0xa2, 0x02 },
-/*		{ OV7670_REG_COM10, 0x0 }, */
-
-	/* Gamma curve values */
-		{ 0x7a, 0x20 },
-		{ 0x7b, 0x10 },
-		{ 0x7c, 0x1e },
-		{ 0x7d, 0x35 },
-		{ 0x7e, 0x5a },		{ 0x7f, 0x69 },
-		{ 0x80, 0x76 },		{ 0x81, 0x80 },
-		{ 0x82, 0x88 },		{ 0x83, 0x8f },
-		{ 0x84, 0x96 },		{ 0x85, 0xa3 },
-		{ 0x86, 0xaf },		{ 0x87, 0xc4 },
-		{ 0x88, 0xd7 },		{ 0x89, 0xe8 },
-
-	/* AGC and AEC parameters.  Note we start by disabling those features,
-	   then turn them only after tweaking the values. */
-		{ OV7670_REG_COM8, OV7670_COM8_FASTAEC
-				 | OV7670_COM8_AECSTEP
-				 | OV7670_COM8_BFILT },
-		{ OV7670_REG_GAIN, 0 },	{ OV7670_REG_AECH, 0 },
-		{ OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
-		{ OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
-		{ OV7670_REG_BD50MAX, 0x05 },	{ OV7670_REG_BD60MAX, 0x07 },
-		{ OV7670_REG_AEW, 0x95 },	{ OV7670_REG_AEB, 0x33 },
-		{ OV7670_REG_VPT, 0xe3 },	{ OV7670_REG_HAECC1, 0x78 },
-		{ OV7670_REG_HAECC2, 0x68 },
-		{ 0xa1, 0x03 }, /* magic */
-		{ OV7670_REG_HAECC3, 0xd8 },	{ OV7670_REG_HAECC4, 0xd8 },
-		{ OV7670_REG_HAECC5, 0xf0 },	{ OV7670_REG_HAECC6, 0x90 },
-		{ OV7670_REG_HAECC7, 0x94 },
-		{ OV7670_REG_COM8, OV7670_COM8_FASTAEC
-				| OV7670_COM8_AECSTEP
-				| OV7670_COM8_BFILT
-				| OV7670_COM8_AGC
-				| OV7670_COM8_AEC },
-
-	/* Almost all of these are magic "reserved" values.  */
-		{ OV7670_REG_COM5, 0x61 },	{ OV7670_REG_COM6, 0x4b },
-		{ 0x16, 0x02 },
-		{ OV7670_REG_MVFP, 0x07 },
-		{ 0x21, 0x02 },		{ 0x22, 0x91 },
-		{ 0x29, 0x07 },		{ 0x33, 0x0b },
-		{ 0x35, 0x0b },		{ 0x37, 0x1d },
-		{ 0x38, 0x71 },		{ 0x39, 0x2a },
-		{ OV7670_REG_COM12, 0x78 },	{ 0x4d, 0x40 },
-		{ 0x4e, 0x20 },		{ OV7670_REG_GFIX, 0 },
-		{ 0x6b, 0x4a },		{ 0x74, 0x10 },
-		{ 0x8d, 0x4f },		{ 0x8e, 0 },
-		{ 0x8f, 0 },		{ 0x90, 0 },
-		{ 0x91, 0 },		{ 0x96, 0 },
-		{ 0x9a, 0 },		{ 0xb0, 0x84 },
-		{ 0xb1, 0x0c },		{ 0xb2, 0x0e },
-		{ 0xb3, 0x82 },		{ 0xb8, 0x0a },
-
-	/* More reserved magic, some of which tweaks white balance */
-		{ 0x43, 0x0a },		{ 0x44, 0xf0 },
-		{ 0x45, 0x34 },		{ 0x46, 0x58 },
-		{ 0x47, 0x28 },		{ 0x48, 0x3a },
-		{ 0x59, 0x88 },		{ 0x5a, 0x88 },
-		{ 0x5b, 0x44 },		{ 0x5c, 0x67 },
-		{ 0x5d, 0x49 },		{ 0x5e, 0x0e },
-		{ 0x6c, 0x0a },		{ 0x6d, 0x55 },
-		{ 0x6e, 0x11 },		{ 0x6f, 0x9f },
-						/* "9e for advance AWB" */
-		{ 0x6a, 0x40 },		{ OV7670_REG_BLUE, 0x40 },
-		{ OV7670_REG_RED, 0x60 },
-		{ OV7670_REG_COM8, OV7670_COM8_FASTAEC
-				| OV7670_COM8_AECSTEP
-				| OV7670_COM8_BFILT
-				| OV7670_COM8_AGC
-				| OV7670_COM8_AEC
-				| OV7670_COM8_AWB },
-
-	/* Matrix coefficients */
-		{ 0x4f, 0x80 },		{ 0x50, 0x80 },
-		{ 0x51, 0 },		{ 0x52, 0x22 },
-		{ 0x53, 0x5e },		{ 0x54, 0x80 },
-		{ 0x58, 0x9e },
-
-		{ OV7670_REG_COM16, OV7670_COM16_AWBGAIN },
-		{ OV7670_REG_EDGE, 0 },
-		{ 0x75, 0x05 },		{ 0x76, 0xe1 },
-		{ 0x4c, 0 },		{ 0x77, 0x01 },
-		{ OV7670_REG_COM13, OV7670_COM13_GAMMA
-				  | OV7670_COM13_UVSAT
-				  | 2},		/* was 3 */
-		{ 0x4b, 0x09 },
-		{ 0xc9, 0x60 },		{ OV7670_REG_COM16, 0x38 },
-		{ 0x56, 0x40 },
-
-		{ 0x34, 0x11 },
-		{ OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
-		{ 0xa4, 0x88 },		{ 0x96, 0 },
-		{ 0x97, 0x30 },		{ 0x98, 0x20 },
-		{ 0x99, 0x30 },		{ 0x9a, 0x84 },
-		{ 0x9b, 0x29 },		{ 0x9c, 0x03 },
-		{ 0x9d, 0x4c },		{ 0x9e, 0x3f },
-		{ 0x78, 0x04 },
-
-	/* Extra-weird stuff.  Some sort of multiplexor register */
-		{ 0x79, 0x01 },		{ 0xc8, 0xf0 },
-		{ 0x79, 0x0f },		{ 0xc8, 0x00 },
-		{ 0x79, 0x10 },		{ 0xc8, 0x7e },
-		{ 0x79, 0x0a },		{ 0xc8, 0x80 },
-		{ 0x79, 0x0b },		{ 0xc8, 0x01 },
-		{ 0x79, 0x0c },		{ 0xc8, 0x0f },
-		{ 0x79, 0x0d },		{ 0xc8, 0x20 },
-		{ 0x79, 0x09 },		{ 0xc8, 0x80 },
-		{ 0x79, 0x02 },		{ 0xc8, 0xc0 },
-		{ 0x79, 0x03 },		{ 0xc8, 0x40 },
-		{ 0x79, 0x05 },		{ 0xc8, 0x30 },
-		{ 0x79, 0x26 },
-	};
 
 	PDEBUG(D_PROBE, "starting OV7xx0 configuration");
 
@@ -1011,8 +1198,9 @@
 			switch (low) {
 			case 0x30:
 				PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635");
-				sd->sensor = SEN_OV7630;
-				break;
+				PDEBUG(D_ERR,
+				      "7630 is not supported by this driver");
+				return -1;
 			case 0x40:
 				PDEBUG(D_PROBE, "Sensor is an OV7645");
 				sd->sensor = SEN_OV7640; /* FIXME */
@@ -1038,32 +1226,6 @@
 		return -1;
 	}
 
-	switch (sd->sensor) {
-	case SEN_OV7620:
-		PDEBUG(D_PROBE, "Writing 7620 registers");
-		if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
-			return -1;
-		break;
-	case SEN_OV7630:
-		PDEBUG(D_ERR, "7630 is not supported by this driver version");
-		return -1;
-	case SEN_OV7640:
-		PDEBUG(D_PROBE, "Writing 7640 registers");
-		if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
-			return -1;
-		break;
-	case SEN_OV7670:
-		PDEBUG(D_PROBE, "Writing 7670 registers");
-		if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)))
-			return -1;
-		break;
-	default:
-		PDEBUG(D_PROBE, "Writing 7610 registers");
-		if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)))
-			return -1;
-		break;
-	}
-
 	/* Set sensor-specific vars */
 /*	sd->sif = 0;		already done */
 	return 0;
@@ -1073,141 +1235,7 @@
 static int ov6xx0_configure(struct sd *sd)
 {
 	int rc;
-	static const struct ov_i2c_regvals norm_6x20[] = {
-		{ 0x12, 0x80 }, /* reset */
-		{ 0x11, 0x01 },
-		{ 0x03, 0x60 },
-		{ 0x05, 0x7f }, /* For when autoadjust is off */
-		{ 0x07, 0xa8 },
-		/* The ratio of 0x0c and 0x0d  controls the white point */
-		{ 0x0c, 0x24 },
-		{ 0x0d, 0x24 },
-		{ 0x0f, 0x15 }, /* COMS */
-		{ 0x10, 0x75 }, /* AEC Exposure time */
-		{ 0x12, 0x24 }, /* Enable AGC */
-		{ 0x14, 0x04 },
-		/* 0x16: 0x06 helps frame stability with moving objects */
-		{ 0x16, 0x06 },
-/*		{ 0x20, 0x30 },  * Aperture correction enable */
-		{ 0x26, 0xb2 }, /* BLC enable */
-		/* 0x28: 0x05 Selects RGB format if RGB on */
-		{ 0x28, 0x05 },
-		{ 0x2a, 0x04 }, /* Disable framerate adjust */
-/*		{ 0x2b, 0xac },  * Framerate; Set 2a[7] first */
-		{ 0x2d, 0x99 },
-		{ 0x33, 0xa0 }, /* Color Processing Parameter */
-		{ 0x34, 0xd2 }, /* Max A/D range */
-		{ 0x38, 0x8b },
-		{ 0x39, 0x40 },
-
-		{ 0x3c, 0x39 }, /* Enable AEC mode changing */
-		{ 0x3c, 0x3c }, /* Change AEC mode */
-		{ 0x3c, 0x24 }, /* Disable AEC mode changing */
-
-		{ 0x3d, 0x80 },
-		/* These next two registers (0x4a, 0x4b) are undocumented.
-		 * They control the color balance */
-		{ 0x4a, 0x80 },
-		{ 0x4b, 0x80 },
-		{ 0x4d, 0xd2 }, /* This reduces noise a bit */
-		{ 0x4e, 0xc1 },
-		{ 0x4f, 0x04 },
-/* Do 50-53 have any effect? */
-/* Toggle 0x12[2] off and on here? */
-	};
-
-	static const struct ov_i2c_regvals norm_6x30[] = {
-		{ 0x12, 0x80 }, /* Reset */
-		{ 0x00, 0x1f }, /* Gain */
-		{ 0x01, 0x99 }, /* Blue gain */
-		{ 0x02, 0x7c }, /* Red gain */
-		{ 0x03, 0xc0 }, /* Saturation */
-		{ 0x05, 0x0a }, /* Contrast */
-		{ 0x06, 0x95 }, /* Brightness */
-		{ 0x07, 0x2d }, /* Sharpness */
-		{ 0x0c, 0x20 },
-		{ 0x0d, 0x20 },
-		{ 0x0e, 0x20 },
-		{ 0x0f, 0x05 },
-		{ 0x10, 0x9a },
-		{ 0x11, 0x00 }, /* Pixel clock = fastest */
-		{ 0x12, 0x24 }, /* Enable AGC and AWB */
-		{ 0x13, 0x21 },
-		{ 0x14, 0x80 },
-		{ 0x15, 0x01 },
-		{ 0x16, 0x03 },
-		{ 0x17, 0x38 },
-		{ 0x18, 0xea },
-		{ 0x19, 0x04 },
-		{ 0x1a, 0x93 },
-		{ 0x1b, 0x00 },
-		{ 0x1e, 0xc4 },
-		{ 0x1f, 0x04 },
-		{ 0x20, 0x20 },
-		{ 0x21, 0x10 },
-		{ 0x22, 0x88 },
-		{ 0x23, 0xc0 }, /* Crystal circuit power level */
-		{ 0x25, 0x9a }, /* Increase AEC black ratio */
-		{ 0x26, 0xb2 }, /* BLC enable */
-		{ 0x27, 0xa2 },
-		{ 0x28, 0x00 },
-		{ 0x29, 0x00 },
-		{ 0x2a, 0x84 }, /* 60 Hz power */
-		{ 0x2b, 0xa8 }, /* 60 Hz power */
-		{ 0x2c, 0xa0 },
-		{ 0x2d, 0x95 }, /* Enable auto-brightness */
-		{ 0x2e, 0x88 },
-		{ 0x33, 0x26 },
-		{ 0x34, 0x03 },
-		{ 0x36, 0x8f },
-		{ 0x37, 0x80 },
-		{ 0x38, 0x83 },
-		{ 0x39, 0x80 },
-		{ 0x3a, 0x0f },
-		{ 0x3b, 0x3c },
-		{ 0x3c, 0x1a },
-		{ 0x3d, 0x80 },
-		{ 0x3e, 0x80 },
-		{ 0x3f, 0x0e },
-		{ 0x40, 0x00 }, /* White bal */
-		{ 0x41, 0x00 }, /* White bal */
-		{ 0x42, 0x80 },
-		{ 0x43, 0x3f }, /* White bal */
-		{ 0x44, 0x80 },
-		{ 0x45, 0x20 },
-		{ 0x46, 0x20 },
-		{ 0x47, 0x80 },
-		{ 0x48, 0x7f },
-		{ 0x49, 0x00 },
-		{ 0x4a, 0x00 },
-		{ 0x4b, 0x80 },
-		{ 0x4c, 0xd0 },
-		{ 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
-		{ 0x4e, 0x40 },
-		{ 0x4f, 0x07 }, /* UV avg., col. killer: max */
-		{ 0x50, 0xff },
-		{ 0x54, 0x23 }, /* Max AGC gain: 18dB */
-		{ 0x55, 0xff },
-		{ 0x56, 0x12 },
-		{ 0x57, 0x81 },
-		{ 0x58, 0x75 },
-		{ 0x59, 0x01 }, /* AGC dark current comp.: +1 */
-		{ 0x5a, 0x2c },
-		{ 0x5b, 0x0f }, /* AWB chrominance levels */
-		{ 0x5c, 0x10 },
-		{ 0x3d, 0x80 },
-		{ 0x27, 0xa6 },
-		{ 0x12, 0x20 }, /* Toggle AWB */
-		{ 0x12, 0x24 },
-	};
-
-	PDEBUG(D_PROBE, "starting sensor configuration");
-
-	if (init_ov_sensor(sd) < 0) {
-		PDEBUG(D_ERR, "Failed to read sensor ID.");
-		return -1;
-	}
-	PDEBUG(D_PROBE, "OV6xx0 sensor detected");
+	PDEBUG(D_PROBE, "starting OV6xx0 configuration");
 
 	/* Detect sensor (sub)type */
 	rc = i2c_r(sd, OV7610_REG_COM_I);
@@ -1251,15 +1279,6 @@
 	/* Set sensor-specific vars */
 	sd->sif = 1;
 
-	if (sd->sensor == SEN_OV6620) {
-		PDEBUG(D_PROBE, "Writing 6x20 registers");
-		if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
-			return -1;
-	} else {
-		PDEBUG(D_PROBE, "Writing 6x30 registers");
-		if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)))
-			return -1;
-	}
 	return 0;
 }
 
@@ -1298,22 +1317,31 @@
 	ov51x_led_control(sd, 0);	/* turn LED off */
 
 	/* Test for 76xx */
-	sd->primary_i2c_slave = OV7xx0_SID;
 	if (ov51x_set_slave_ids(sd, OV7xx0_SID) < 0)
 		goto error;
 
 	/* The OV519 must be more aggressive about sensor detection since
 	 * I2C write will never fail if the sensor is not present. We have
 	 * to try to initialize the sensor to detect its presence */
-	if (init_ov_sensor(sd) < 0) {
+	if (init_ov_sensor(sd) >= 0) {
+		if (ov7xx0_configure(sd) < 0) {
+			PDEBUG(D_ERR, "Failed to configure OV7xx0");
+			goto error;
+		}
+	} else {
+
 		/* Test for 6xx0 */
-		sd->primary_i2c_slave = OV6xx0_SID;
 		if (ov51x_set_slave_ids(sd, OV6xx0_SID) < 0)
 			goto error;
 
-		if (init_ov_sensor(sd) < 0) {
+		if (init_ov_sensor(sd) >= 0) {
+			if (ov6xx0_configure(sd) < 0) {
+				PDEBUG(D_ERR, "Failed to configure OV6xx0");
+				goto error;
+			}
+		} else {
+
 			/* Test for 8xx0 */
-			sd->primary_i2c_slave = OV8xx0_SID;
 			if (ov51x_set_slave_ids(sd, OV8xx0_SID) < 0)
 				goto error;
 
@@ -1321,24 +1349,13 @@
 				PDEBUG(D_ERR,
 					"Can't determine sensor slave IDs");
 				goto error;
-			} else {
-				if (ov8xx0_configure(sd) < 0) {
-					PDEBUG(D_ERR,
-					   "Failed to configure OV8xx0 sensor");
-					goto error;
-				}
 			}
-		} else {
-			if (ov6xx0_configure(sd) < 0) {
-				PDEBUG(D_ERR, "Failed to configure OV6xx0");
+			if (ov8xx0_configure(sd) < 0) {
+				PDEBUG(D_ERR,
+				   "Failed to configure OV8xx0 sensor");
 				goto error;
 			}
 		}
-	} else {
-		if (ov7xx0_configure(sd) < 0) {
-			PDEBUG(D_ERR, "Failed to configure OV7xx0");
-			goto error;
-		}
 	}
 
 	cam = &gspca_dev->cam;
@@ -1355,15 +1372,53 @@
 	sd->colors = COLOR_DEF;
 	sd->hflip = HFLIP_DEF;
 	sd->vflip = VFLIP_DEF;
+	if (sd->sensor != SEN_OV7670)
+		gspca_dev->ctrl_dis = (1 << HFLIP_IDX)
+					| (1 << VFLIP_IDX);
 	return 0;
 error:
 	PDEBUG(D_ERR, "OV519 Config failed");
 	return -EBUSY;
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
 {
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	/* initialize the sensor */
+	switch (sd->sensor) {
+	case SEN_OV6620:
+		if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
+			return -EIO;
+		break;
+	case SEN_OV6630:
+		if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)))
+			return -EIO;
+		break;
+	default:
+/*	case SEN_OV7610: */
+/*	case SEN_OV76BE: */
+		if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)))
+			return -EIO;
+		break;
+	case SEN_OV7620:
+		if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
+			return -EIO;
+		break;
+	case SEN_OV7640:
+		if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
+			return -EIO;
+		break;
+	case SEN_OV7670:
+		if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)))
+			return -EIO;
+		break;
+	case SEN_OV8610:
+		if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)))
+			return -EIO;
+		break;
+	}
 	return 0;
 }
 
@@ -1827,14 +1882,6 @@
 	ov51x_led_control((struct sd *) gspca_dev, 0);
 }
 
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
-}
-
-static void sd_close(struct gspca_dev *gspca_dev)
-{
-}
-
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
@@ -2091,11 +2138,9 @@
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
-	.open = sd_open,
+	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
-	.stop0 = sd_stop0,
-	.close = sd_close,
 	.pkt_scan = sd_pkt_scan,
 };
 
@@ -2132,6 +2177,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 7ef18d5..83b5f74 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -56,12 +56,6 @@
 #define PAC207_GAIN_KNEE		20
 
 #define PAC207_AUTOGAIN_DEADZONE	30
-/* We calculating the autogain at the end of the transfer of a frame, at this
-   moment a frame with the old settings is being transmitted, and a frame is
-   being captured with the old settings. So if we adjust the autogain we must
-   ignore atleast the 2 next frames for the new settings to come into effect
-   before doing any other adjustments */
-#define PAC207_AUTOGAIN_IGNORE_FRAMES	3
 
 /* specific webcam descriptor */
 struct sd {
@@ -131,7 +125,8 @@
 		.minimum = 0,
 		.maximum = 1,
 		.step	= 1,
-		.default_value = 1,
+#define AUTOGAIN_DEF 1
+		.default_value = AUTOGAIN_DEF,
 		.flags = 0,
 	    },
 	    .set = sd_setautogain,
@@ -181,9 +176,6 @@
 			/* 48 reg_72 Rate Control end BalSize_4a =0x36 */
 static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 };
 
-static const unsigned char pac207_sof_marker[5] =
-		{ 0xff, 0xff, 0x00, 0xff, 0x96 };
-
 static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
 	const u8 *buffer, u16 length)
 {
@@ -259,6 +251,25 @@
 		return -ENODEV;
 	}
 
+	PDEBUG(D_PROBE,
+		"Pixart PAC207BCA Image Processor and Control Chip detected"
+		" (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+
+	cam = &gspca_dev->cam;
+	cam->epaddr = 0x05;
+	cam->cam_mode = sif_mode;
+	cam->nmodes = ARRAY_SIZE(sif_mode);
+	sd->brightness = PAC207_BRIGHTNESS_DEFAULT;
+	sd->exposure = PAC207_EXPOSURE_DEFAULT;
+	sd->gain = PAC207_GAIN_DEFAULT;
+	sd->autogain = AUTOGAIN_DEF;
+
+	return 0;
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
 	pac207_write_reg(gspca_dev, 0x41, 0x00);
 				/* Bit_0=Image Format,
 				 * Bit_1=LED,
@@ -266,28 +277,6 @@
 	pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
 	pac207_write_reg(gspca_dev, 0x11, 0x30); /* Analog Bias */
 
-	PDEBUG(D_PROBE,
-		"Pixart PAC207BCA Image Processor and Control Chip detected"
-		" (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
-
-	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
-	cam->epaddr = 0x05;
-	cam->cam_mode = sif_mode;
-	cam->nmodes = ARRAY_SIZE(sif_mode);
-	sd->brightness = PAC207_BRIGHTNESS_DEFAULT;
-	sd->exposure = PAC207_EXPOSURE_DEFAULT;
-	sd->gain = PAC207_GAIN_DEFAULT;
-
-	return 0;
-}
-
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	sd->autogain = 1;
 	return 0;
 }
 
@@ -343,14 +332,8 @@
 	pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
 }
 
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
-}
-
-/* this function is called at close time */
-static void sd_close(struct gspca_dev *gspca_dev)
-{
-}
+/* Include pac common sof detection functions */
+#include "pac_common.h"
 
 static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
 {
@@ -365,33 +348,7 @@
 	else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
 			100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE,
 			PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE))
-		sd->autogain_ignore_frames = PAC207_AUTOGAIN_IGNORE_FRAMES;
-}
-
-static unsigned char *pac207_find_sof(struct gspca_dev *gspca_dev,
-					unsigned char *m, int len)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	int i;
-
-	/* Search for the SOF marker (fixed part) in the header */
-	for (i = 0; i < len; i++) {
-		if (m[i] == pac207_sof_marker[sd->sof_read]) {
-			sd->sof_read++;
-			if (sd->sof_read == sizeof(pac207_sof_marker)) {
-				PDEBUG(D_STREAM,
-					"SOF found, bytes to analyze: %u."
-					" Frame starts at byte #%u",
-					len, i + 1);
-				sd->sof_read = 0;
-				return m + i + 1;
-			}
-		} else {
-			sd->sof_read = 0;
-		}
-	}
-
-	return NULL;
+		sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -402,14 +359,14 @@
 	struct sd *sd = (struct sd *) gspca_dev;
 	unsigned char *sof;
 
-	sof = pac207_find_sof(gspca_dev, data, len);
+	sof = pac_find_sof(gspca_dev, data, len);
 	if (sof) {
 		int n;
 
 		/* finish decoding current frame */
 		n = sof - data;
-		if (n > sizeof pac207_sof_marker)
-			n -= sizeof pac207_sof_marker;
+		if (n > sizeof pac_sof_marker)
+			n -= sizeof pac_sof_marker;
 		else
 			n = 0;
 		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
@@ -537,7 +494,7 @@
 		sd->gain = PAC207_GAIN_DEFAULT;
 		if (gspca_dev->streaming) {
 			sd->autogain_ignore_frames =
-				PAC207_AUTOGAIN_IGNORE_FRAMES;
+				PAC_AUTOGAIN_IGNORE_FRAMES;
 			setexposure(gspca_dev);
 			setgain(gspca_dev);
 		}
@@ -560,11 +517,9 @@
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
-	.open = sd_open,
+	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
-	.stop0 = sd_stop0,
-	.close = sd_close,
 	.dq_callback = pac207_do_auto_gain,
 	.pkt_scan = sd_pkt_scan,
 };
@@ -597,6 +552,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index 815bea6..d4be518 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -19,6 +19,36 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
+/* Some documentation about various registers as determined by trial and error.
+   When the register addresses differ between the 7202 and the 7311 the 2
+   different addresses are written as 7302addr/7311addr, when one of the 2
+   addresses is a - sign that register description is not valid for the
+   matching IC.
+
+   Register page 1:
+
+   Address	Description
+   -/0x08	Unknown compressor related, must always be 8 except when not
+		in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
+   -/0x1b	Auto white balance related, bit 0 is AWB enable (inverted)
+		bits 345 seem to toggle per color gains on/off (inverted)
+   0x78		Global control, bit 6 controls the LED (inverted)
+   -/0x80	JPEG compression ratio ? Best not touched
+
+   Register page 3/4:
+
+   Address	Description
+   0x02		Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
+		the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
+   -/0x0f	Master gain 1-245, low value = high gain
+   0x10/-	Master gain 0-31
+   -/0x10	Another gain 0-15, limited influence (1-2x gain I guess)
+   0x21		Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
+   -/0x27	Seems to toggle various gains on / off, Setting bit 7 seems to
+		completely disable the analog amplification block. Set to 0x68
+		for max gain, 0x14 for minimal gain.
+*/
+
 #define MODULE_NAME "pac7311"
 
 #include "gspca.h"
@@ -31,18 +61,23 @@
 struct sd {
 	struct gspca_dev gspca_dev;		/* !! must be the first item */
 
-	int lum_sum;
-	atomic_t avg_lum;
-	atomic_t do_gain;
-
 	unsigned char brightness;
 	unsigned char contrast;
 	unsigned char colors;
+	unsigned char gain;
+	unsigned char exposure;
 	unsigned char autogain;
+	__u8 hflip;
+	__u8 vflip;
 
-	char ffseq;
-	signed char ag_cnt;
-#define AG_CNT_START 13
+	__u8 sensor;
+#define SENSOR_PAC7302 0
+#define SENSOR_PAC7311 1
+
+	u8 sof_read;
+	u8 autogain_ignore_frames;
+
+	atomic_t avg_lum;
 };
 
 /* V4L2 controls supported by the driver */
@@ -54,8 +89,18 @@
 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
 
 static struct ctrl sd_ctrls[] = {
+/* This control is pac7302 only */
+#define BRIGHTNESS_IDX 0
 	{
 	    {
 		.id      = V4L2_CID_BRIGHTNESS,
@@ -71,13 +116,15 @@
 	    .set = sd_setbrightness,
 	    .get = sd_getbrightness,
 	},
+/* This control is for both the 7302 and the 7311 */
 	{
 	    {
 		.id      = V4L2_CID_CONTRAST,
 		.type    = V4L2_CTRL_TYPE_INTEGER,
 		.name    = "Contrast",
 		.minimum = 0,
-		.maximum = 255,
+#define CONTRAST_MAX 255
+		.maximum = CONTRAST_MAX,
 		.step    = 1,
 #define CONTRAST_DEF 127
 		.default_value = CONTRAST_DEF,
@@ -85,13 +132,16 @@
 	    .set = sd_setcontrast,
 	    .get = sd_getcontrast,
 	},
+/* This control is pac7302 only */
+#define SATURATION_IDX 2
 	{
 	    {
 		.id      = V4L2_CID_SATURATION,
 		.type    = V4L2_CTRL_TYPE_INTEGER,
-		.name    = "Color",
+		.name    = "Saturation",
 		.minimum = 0,
-		.maximum = 255,
+#define COLOR_MAX 255
+		.maximum = COLOR_MAX,
 		.step    = 1,
 #define COLOR_DEF 127
 		.default_value = COLOR_DEF,
@@ -99,6 +149,39 @@
 	    .set = sd_setcolors,
 	    .get = sd_getcolors,
 	},
+/* All controls below are for both the 7302 and the 7311 */
+	{
+	    {
+		.id      = V4L2_CID_GAIN,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Gain",
+		.minimum = 0,
+#define GAIN_MAX 255
+		.maximum = GAIN_MAX,
+		.step    = 1,
+#define GAIN_DEF 127
+#define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
+		.default_value = GAIN_DEF,
+	    },
+	    .set = sd_setgain,
+	    .get = sd_getgain,
+	},
+	{
+	    {
+		.id      = V4L2_CID_EXPOSURE,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Exposure",
+		.minimum = 0,
+#define EXPOSURE_MAX 255
+		.maximum = EXPOSURE_MAX,
+		.step    = 1,
+#define EXPOSURE_DEF  16 /*  32 ms / 30 fps */
+#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
+		.default_value = EXPOSURE_DEF,
+	    },
+	    .set = sd_setexposure,
+	    .get = sd_getexposure,
+	},
 	{
 	    {
 		.id      = V4L2_CID_AUTOGAIN,
@@ -113,101 +196,207 @@
 	    .set = sd_setautogain,
 	    .get = sd_getautogain,
 	},
+	{
+	    {
+		.id      = V4L2_CID_HFLIP,
+		.type    = V4L2_CTRL_TYPE_BOOLEAN,
+		.name    = "Mirror",
+		.minimum = 0,
+		.maximum = 1,
+		.step    = 1,
+#define HFLIP_DEF 0
+		.default_value = HFLIP_DEF,
+	    },
+	    .set = sd_sethflip,
+	    .get = sd_gethflip,
+	},
+	{
+	    {
+		.id      = V4L2_CID_VFLIP,
+		.type    = V4L2_CTRL_TYPE_BOOLEAN,
+		.name    = "Vflip",
+		.minimum = 0,
+		.maximum = 1,
+		.step    = 1,
+#define VFLIP_DEF 0
+		.default_value = VFLIP_DEF,
+	    },
+	    .set = sd_setvflip,
+	    .get = sd_getvflip,
+	},
 };
 
 static struct v4l2_pix_format vga_mode[] = {
-	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+	{160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
 		.bytesperline = 160,
 		.sizeimage = 160 * 120 * 3 / 8 + 590,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 2},
-	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+	{320, 240, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
 		.bytesperline = 320,
 		.sizeimage = 320 * 240 * 3 / 8 + 590,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 1},
-	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+	{640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
 		.bytesperline = 640,
 		.sizeimage = 640 * 480 * 3 / 8 + 590,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 0},
 };
 
-#define PAC7311_JPEG_HEADER_SIZE (sizeof pac7311_jpeg_header)	/* (594) */
+/* pac 7302 */
+static const __u8 init_7302[] = {
+/*	index,value */
+	0xff, 0x01,		/* page 1 */
+	0x78, 0x00,		/* deactivate */
+	0xff, 0x01,
+	0x78, 0x40,		/* led off */
+};
+static const __u8 start_7302[] = {
+/*	index, len, [value]* */
+	0xff, 1,	0x00,		/* page 0 */
+	0x00, 12,	0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
+			0x00, 0x00, 0x00, 0x00,
+	0x0d, 24,	0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
+			0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
+			0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
+	0x26, 2,	0xaa, 0xaa,
+	0x2e, 1,	0x31,
+	0x38, 1,	0x01,
+	0x3a, 3,	0x14, 0xff, 0x5a,
+	0x43, 11,	0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
+			0x00, 0x54, 0x11,
+	0x55, 1,	0x00,
+	0x62, 4, 	0x10, 0x1e, 0x1e, 0x18,
+	0x6b, 1,	0x00,
+	0x6e, 3,	0x08, 0x06, 0x00,
+	0x72, 3,	0x00, 0xff, 0x00,
+	0x7d, 23,	0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
+			0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
+			0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
+	0xa2, 10,	0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
+			0xd2, 0xeb,
+	0xaf, 1,	0x02,
+	0xb5, 2,	0x08, 0x08,
+	0xb8, 2,	0x08, 0x88,
+	0xc4, 4,	0xae, 0x01, 0x04, 0x01,
+	0xcc, 1,	0x00,
+	0xd1, 11,	0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
+			0xc1, 0xd7, 0xec,
+	0xdc, 1,	0x01,
+	0xff, 1,	0x01,		/* page 1 */
+	0x12, 3,	0x02, 0x00, 0x01,
+	0x3e, 2,	0x00, 0x00,
+	0x76, 5,	0x01, 0x20, 0x40, 0x00, 0xf2,
+	0x7c, 1,	0x00,
+	0x7f, 10,	0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
+			0x02, 0x00,
+	0x96, 5,	0x01, 0x10, 0x04, 0x01, 0x04,
+	0xc8, 14,	0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
+			0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
+	0xd8, 1,	0x01,
+	0xdb, 2,	0x00, 0x01,
+	0xde, 7,	0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
+	0xe6, 4,	0x00, 0x00, 0x00, 0x01,
+	0xeb, 1,	0x00,
+	0xff, 1,	0x02,		/* page 2 */
+	0x22, 1,	0x00,
+	0xff, 1,	0x03,		/* page 3 */
+	0x00, 255,			/* load the page 3 */
+	0x11, 1,	0x01,
+	0xff, 1,	0x02,		/* page 2 */
+	0x13, 1,	0x00,
+	0x22, 4,	0x1f, 0xa4, 0xf0, 0x96,
+	0x27, 2,	0x14, 0x0c,
+	0x2a, 5,	0xc8, 0x00, 0x18, 0x12, 0x22,
+	0x64, 8,	0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
+	0x6e, 1,	0x08,
+	0xff, 1,	0x01,		/* page 1 */
+	0x78, 1,	0x00,
+	0, 0				/* end of sequence */
+};
 
-static const __u8 pac7311_jpeg_header[] = {
-	0xff, 0xd8,
-	0xff, 0xe0, 0x00, 0x03, 0x20,
-	0xff, 0xc0, 0x00, 0x11, 0x08,
-		0x01, 0xe0,			/* 12: height */
-		0x02, 0x80,			/* 14: width */
-		0x03,				/* 16 */
-			0x01, 0x21, 0x00,
-			0x02, 0x11, 0x01,
-			0x03, 0x11, 0x01,
-	0xff, 0xdb, 0x00, 0x84,
-	0x00, 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d,
-	0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a, 0x18, 0x16,
-	0x16, 0x18, 0x31, 0x23, 0x25, 0x1d, 0x28, 0x3a, 0x33, 0x3d,
-	0x3c, 0x39, 0x33, 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40,
-	0x44, 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57, 0x5f,
-	0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, 0x79, 0x70, 0x64,
-	0x78, 0x5c, 0x65, 0x67, 0x63, 0x01, 0x11, 0x12, 0x12, 0x18,
-	0x15, 0x18, 0x2f, 0x1a, 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42,
-	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-	0xff, 0xc4, 0x01, 0xa2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01,
-	0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-	0x09, 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02,
-	0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
-	0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31,
-	0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32,
-	0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52,
-	0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
-	0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
-	0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45,
-	0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57,
-	0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
-	0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83,
-	0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94,
-	0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
-	0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
-	0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
-	0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
-	0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
-	0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
-	0xf9, 0xfa, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01,
-	0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
-	0x0b, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
-	0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01,
-	0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41,
-	0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14,
-	0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
-	0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25,
-	0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a,
-	0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46,
-	0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
-	0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,
-	0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83,
-	0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94,
-	0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
-	0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
-	0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
-	0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
-	0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
-	0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
-	0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03,
-	0x11, 0x00, 0x3f, 0x00
+/* page 3 - the value 0xaa says skip the index - see reg_w_page() */
+static const __u8 page3_7302[] = {
+	0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
+	0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
+	0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
+	0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
+	0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
+	0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
+	0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
+	0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
+	0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+	0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
+	0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
+	0x00
+};
+
+/* pac 7311 */
+static const __u8 init_7311[] = {
+	0x78, 0x40,	/* Bit_0=start stream, Bit_6=LED */
+	0x78, 0x40,	/* Bit_0=start stream, Bit_6=LED */
+	0x78, 0x44,	/* Bit_0=start stream, Bit_6=LED */
+	0xff, 0x04,
+	0x27, 0x80,
+	0x28, 0xca,
+	0x29, 0x53,
+	0x2a, 0x0e,
+	0xff, 0x01,
+	0x3e, 0x20,
+};
+
+static const __u8 start_7311[] = {
+/*	index, len, [value]* */
+	0xff, 1,	0x01,		/* page 1 */
+	0x02, 43,	0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00,
+			0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c,
+			0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10,
+			0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00,
+	0x3e, 42,	0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e,
+			0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49,
+			0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48,
+			0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78,
+			0x00, 0x00, 0x09, 0x1b, 0x34, 0x49, 0x5c, 0x9b,
+			0xd0, 0xff,
+	0x78, 6,	0x44, 0x00, 0xf2, 0x01, 0x01, 0x80,
+	0x7f, 18,	0x2a, 0x1c, 0x00, 0xc8, 0x02, 0x58, 0x03, 0x84,
+			0x12, 0x00, 0x1a, 0x04, 0x08, 0x0c, 0x10, 0x14,
+			0x18, 0x20,
+	0x96, 3,	0x01, 0x08, 0x04,
+	0xa0, 4,	0x44, 0x44, 0x44, 0x04,
+	0xf0, 13,	0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
+			0x3f, 0x00, 0x0a, 0x01, 0x00,
+	0xff, 1,	0x04,		/* page 4 */
+	0x00, 254,			/* load the page 4 */
+	0x11, 1,	0x01,
+	0, 0				/* end of sequence */
+};
+
+/* page 4 - the value 0xaa says skip the index - see reg_w_page() */
+static const __u8 page4_7311[] = {
+	0xaa, 0xaa, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
+	0x09, 0x00, 0xaa, 0xaa, 0x07, 0x00, 0x00, 0x62,
+	0x08, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, 0xaa,
+	0xaa, 0x00, 0x08, 0xaa, 0x03, 0xaa, 0x00, 0x68,
+	0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
+	0x23, 0x28, 0x04, 0x11, 0x00, 0x00
 };
 
 static void reg_w_buf(struct gspca_dev *gspca_dev,
-		  __u16 index,
-		  const char *buffer, __u16 len)
+		  __u8 index,
+		  const char *buffer, int len)
 {
 	memcpy(gspca_dev->usb_buf, buffer, len);
 	usb_control_msg(gspca_dev->dev,
@@ -219,21 +408,9 @@
 			500);
 }
 
-static __u8 reg_r(struct gspca_dev *gspca_dev,
-			     __u16 index)
-{
-	usb_control_msg(gspca_dev->dev,
-			usb_rcvctrlpipe(gspca_dev->dev, 0),
-			0,			/* request */
-			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-			0,			/* value */
-			index, gspca_dev->usb_buf, 1,
-			500);
-	return gspca_dev->usb_buf[0];
-}
 
 static void reg_w(struct gspca_dev *gspca_dev,
-		  __u16 index,
+		  __u8 index,
 		  __u8 value)
 {
 	gspca_dev->usb_buf[0] = value;
@@ -241,10 +418,78 @@
 			usb_sndctrlpipe(gspca_dev->dev, 0),
 			0,			/* request */
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-			value, index, gspca_dev->usb_buf, 1,
+			0, index, gspca_dev->usb_buf, 1,
 			500);
 }
 
+static void reg_w_seq(struct gspca_dev *gspca_dev,
+		const __u8 *seq, int len)
+{
+	while (--len >= 0) {
+		reg_w(gspca_dev, seq[0], seq[1]);
+		seq += 2;
+	}
+}
+
+/* load the beginning of a page */
+static void reg_w_page(struct gspca_dev *gspca_dev,
+			const __u8 *page, int len)
+{
+	int index;
+
+	for (index = 0; index < len; index++) {
+		if (page[index] == 0xaa)		/* skip this index */
+			continue;
+		gspca_dev->usb_buf[0] = page[index];
+		usb_control_msg(gspca_dev->dev,
+				usb_sndctrlpipe(gspca_dev->dev, 0),
+				0,			/* request */
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+				0, index, gspca_dev->usb_buf, 1,
+				500);
+	}
+}
+
+/* output a variable sequence */
+static void reg_w_var(struct gspca_dev *gspca_dev,
+			const __u8 *seq)
+{
+	int index, len;
+
+	for (;;) {
+		index = *seq++;
+		len = *seq++;
+		switch (len) {
+		case 0:
+			return;
+		case 254:
+			reg_w_page(gspca_dev, page4_7311, sizeof page4_7311);
+			break;
+		case 255:
+			reg_w_page(gspca_dev, page3_7302, sizeof page3_7302);
+			break;
+		default:
+			if (len > 64) {
+				PDEBUG(D_ERR|D_STREAM,
+					"Incorrect variable sequence");
+				return;
+			}
+			while (len > 0) {
+				if (len < 8) {
+					reg_w_buf(gspca_dev, index, seq, len);
+					seq += len;
+					break;
+				}
+				reg_w_buf(gspca_dev, index, seq, 8);
+				seq += 8;
+				index += 8;
+				len -= 8;
+			}
+		}
+	}
+	/* not reached */
+}
+
 /* this function is called at probe time */
 static int sd_config(struct gspca_dev *gspca_dev,
 			const struct usb_device_id *id)
@@ -252,203 +497,245 @@
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
 
-	PDEBUG(D_CONF, "Find Sensor PAC7311");
-	reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */
-	reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */
-	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
-	reg_w(gspca_dev, 0xff, 0x04);
-	reg_w(gspca_dev, 0x27, 0x80);
-	reg_w(gspca_dev, 0x28, 0xca);
-	reg_w(gspca_dev, 0x29, 0x53);
-	reg_w(gspca_dev, 0x2a, 0x0e);
-	reg_w(gspca_dev, 0xff, 0x01);
-	reg_w(gspca_dev, 0x3e, 0x20);
-
 	cam = &gspca_dev->cam;
 	cam->epaddr = 0x05;
-	cam->cam_mode = vga_mode;
-	cam->nmodes = ARRAY_SIZE(vga_mode);
+
+	sd->sensor = id->driver_info;
+	if (sd->sensor == SENSOR_PAC7302) {
+		PDEBUG(D_CONF, "Find Sensor PAC7302");
+		cam->cam_mode = &vga_mode[2];	/* only 640x480 */
+		cam->nmodes = 1;
+	} else {
+		PDEBUG(D_CONF, "Find Sensor PAC7311");
+		cam->cam_mode = vga_mode;
+		cam->nmodes = ARRAY_SIZE(vga_mode);
+		gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX)
+				| (1 << SATURATION_IDX);
+	}
 
 	sd->brightness = BRIGHTNESS_DEF;
 	sd->contrast = CONTRAST_DEF;
 	sd->colors = COLOR_DEF;
+	sd->gain = GAIN_DEF;
+	sd->exposure = EXPOSURE_DEF;
 	sd->autogain = AUTOGAIN_DEF;
-	sd->ag_cnt = -1;
+	sd->hflip = HFLIP_DEF;
+	sd->vflip = VFLIP_DEF;
 	return 0;
 }
 
-static void setbrightness(struct gspca_dev *gspca_dev)
+/* This function is used by pac7302 only */
+static void setbrightcont(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int brightness;
+	int i, v;
+	static const __u8 max[10] =
+		{0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
+		 0xd4, 0xec};
+	static const __u8 delta[10] =
+		{0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
+		 0x11, 0x0b};
 
-/*jfm: inverted?*/
-	brightness = BRIGHTNESS_MAX - sd->brightness;
-	reg_w(gspca_dev, 0xff, 0x04);
-/*	reg_w(gspca_dev, 0x0e, 0x00); */
-	reg_w(gspca_dev, 0x0f, brightness);
-	/* load registers to sensor (Bit 0, auto clear) */
-	reg_w(gspca_dev, 0x11, 0x01);
-	PDEBUG(D_CONF|D_STREAM, "brightness: %i", brightness);
+	reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
+	for (i = 0; i < 10; i++) {
+		v = max[i];
+		v += (sd->brightness - BRIGHTNESS_MAX)
+			* 150 / BRIGHTNESS_MAX;		/* 200 ? */
+		v -= delta[i] * sd->contrast / CONTRAST_MAX;
+		if (v < 0)
+			v = 0;
+		else if (v > 0xff)
+			v = 0xff;
+		reg_w(gspca_dev, 0xa2 + i, v);
+	}
+	reg_w(gspca_dev, 0xdc, 0x01);
 }
 
+/* This function is used by pac7311 only */
 static void setcontrast(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	reg_w(gspca_dev, 0xff, 0x01);
-	reg_w(gspca_dev, 0x80, sd->contrast);
+	reg_w(gspca_dev, 0xff, 0x04);
+	reg_w(gspca_dev, 0x10, sd->contrast >> 4);
 	/* load registers to sensor (Bit 0, auto clear) */
 	reg_w(gspca_dev, 0x11, 0x01);
-	PDEBUG(D_CONF|D_STREAM, "contrast: %i", sd->contrast);
 }
 
+/* This function is used by pac7302 only */
 static void setcolors(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	int i, v;
+	static const int a[9] =
+		{217, -212, 0, -101, 170, -67, -38, -315, 355};
+	static const int b[9] =
+		{19, 106, 0, 19, 106, 1, 19, 106, 1};
 
-	reg_w(gspca_dev, 0xff, 0x01);
-	reg_w(gspca_dev, 0x10, sd->colors);
-	/* load registers to sensor (Bit 0, auto clear) */
+	reg_w(gspca_dev, 0xff, 0x03);	/* page 3 */
 	reg_w(gspca_dev, 0x11, 0x01);
+	reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
+	reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
+	for (i = 0; i < 9; i++) {
+		v = a[i] * sd->colors / COLOR_MAX + b[i];
+		reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
+		reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
+	}
+	reg_w(gspca_dev, 0xdc, 0x01);
 	PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
 }
 
-static void setautogain(struct gspca_dev *gspca_dev)
+static void setgain(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	if (sd->autogain) {
-		sd->lum_sum = 0;
-		sd->ag_cnt = AG_CNT_START;
+	if (sd->sensor == SENSOR_PAC7302) {
+		reg_w(gspca_dev, 0xff, 0x03);		/* page 3 */
+		reg_w(gspca_dev, 0x10, sd->gain >> 3);
 	} else {
-		sd->ag_cnt = -1;
+		int gain = GAIN_MAX - sd->gain;
+		if (gain < 1)
+			gain = 1;
+		else if (gain > 245)
+			gain = 245;
+		reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
+		reg_w(gspca_dev, 0x0e, 0x00);
+		reg_w(gspca_dev, 0x0f, gain);
 	}
+	/* load registers to sensor (Bit 0, auto clear) */
+	reg_w(gspca_dev, 0x11, 0x01);
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
+static void setexposure(struct gspca_dev *gspca_dev)
 {
-	reg_w(gspca_dev, 0x78, 0x00);	/* Turn on LED */
+	struct sd *sd = (struct sd *) gspca_dev;
+	__u8 reg;
+
+	/* register 2 of frame 3/4 contains the clock divider configuring the
+	   no fps according to the formula: 60 / reg. sd->exposure is the
+	   desired exposure time in ms. */
+	reg = 120 * sd->exposure / 1000;
+	if (reg < 2)
+		reg = 2;
+	else if (reg > 63)
+		reg = 63;
+
+	if (sd->sensor == SENSOR_PAC7302) {
+		/* On the pac7302 reg2 MUST be a multiple of 3, so round it to
+		   the nearest multiple of 3, except when between 6 and 12? */
+		if (reg < 6 || reg > 12)
+			reg = ((reg + 1) / 3) * 3;
+		reg_w(gspca_dev, 0xff, 0x03);		/* page 3 */
+		reg_w(gspca_dev, 0x02, reg);
+	} else {
+		reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
+		reg_w(gspca_dev, 0x02, reg);
+		/* Page 1 register 8 must always be 0x08 except when not in
+		   640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
+		reg_w(gspca_dev, 0xff, 0x01);
+		if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
+				reg <= 3)
+			reg_w(gspca_dev, 0x08, 0x09);
+		else
+			reg_w(gspca_dev, 0x08, 0x08);
+	}
+	/* load registers to sensor (Bit 0, auto clear) */
+	reg_w(gspca_dev, 0x11, 0x01);
+}
+
+static void sethvflip(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	__u8 data;
+
+	if (sd->sensor == SENSOR_PAC7302) {
+		reg_w(gspca_dev, 0xff, 0x03);		/* page 3 */
+		data = (sd->hflip ? 0x08 : 0x00)
+			| (sd->vflip ? 0x04 : 0x00);
+	} else {
+		reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
+		data = (sd->hflip ? 0x04 : 0x00)
+			| (sd->vflip ? 0x08 : 0x00);
+	}
+	reg_w(gspca_dev, 0x21, data);
+	/* load registers to sensor (Bit 0, auto clear) */
+	reg_w(gspca_dev, 0x11, 0x01);
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->sensor == SENSOR_PAC7302)
+		reg_w_seq(gspca_dev, init_7302, sizeof init_7302);
+	else
+		reg_w_seq(gspca_dev, init_7311, sizeof init_7311);
+
 	return 0;
 }
 
 static void sd_start(struct gspca_dev *gspca_dev)
 {
-	reg_w(gspca_dev, 0xff, 0x01);
-	reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8);
-	reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8);
-	reg_w_buf(gspca_dev, 0x0012, "\x00\x07\x00\x0a\x10\x00\xa0\x10", 8);
-	reg_w_buf(gspca_dev, 0x001a, "\x02\x00\x00\x00\x00\x0b\x01\x00", 8);
-	reg_w_buf(gspca_dev, 0x0022, "\x00\x00\x00\x00\x00\x00\x00\x00", 8);
-	reg_w_buf(gspca_dev, 0x002a, "\x00\x00\x00", 3);
-	reg_w_buf(gspca_dev, 0x003e, "\x00\x00\x78\x52\x4a\x52\x78\x6e", 8);
-	reg_w_buf(gspca_dev, 0x0046, "\x48\x46\x48\x6e\x5f\x49\x42\x49", 8);
-	reg_w_buf(gspca_dev, 0x004e, "\x5f\x5f\x49\x42\x49\x5f\x6e\x48", 8);
-	reg_w_buf(gspca_dev, 0x0056, "\x46\x48\x6e\x78\x52\x4a\x52\x78", 8);
-	reg_w_buf(gspca_dev, 0x005e, "\x00\x00\x09\x1b\x34\x49\x5c\x9b", 8);
-	reg_w_buf(gspca_dev, 0x0066, "\xd0\xff", 2);
-	reg_w_buf(gspca_dev, 0x0078, "\x44\x00\xf2\x01\x01\x80", 6);
-	reg_w_buf(gspca_dev, 0x007f, "\x2a\x1c\x00\xc8\x02\x58\x03\x84", 8);
-	reg_w_buf(gspca_dev, 0x0087, "\x12\x00\x1a\x04\x08\x0c\x10\x14", 8);
-	reg_w_buf(gspca_dev, 0x008f, "\x18\x20", 2);
-	reg_w_buf(gspca_dev, 0x0096, "\x01\x08\x04", 3);
-	reg_w_buf(gspca_dev, 0x00a0, "\x44\x44\x44\x04", 4);
-	reg_w_buf(gspca_dev, 0x00f0, "\x01\x00\x00\x00\x22\x00\x20\x00", 8);
-	reg_w_buf(gspca_dev, 0x00f8, "\x3f\x00\x0a\x01\x00", 5);
+	struct sd *sd = (struct sd *) gspca_dev;
 
-	reg_w(gspca_dev, 0xff, 0x04);
-	reg_w(gspca_dev, 0x02, 0x04);
-	reg_w(gspca_dev, 0x03, 0x54);
-	reg_w(gspca_dev, 0x04, 0x07);
-	reg_w(gspca_dev, 0x05, 0x2b);
-	reg_w(gspca_dev, 0x06, 0x09);
-	reg_w(gspca_dev, 0x07, 0x0f);
-	reg_w(gspca_dev, 0x08, 0x09);
-	reg_w(gspca_dev, 0x09, 0x00);
-	reg_w(gspca_dev, 0x0c, 0x07);
-	reg_w(gspca_dev, 0x0d, 0x00);
-	reg_w(gspca_dev, 0x0e, 0x00);
-	reg_w(gspca_dev, 0x0f, 0x62);
-	reg_w(gspca_dev, 0x10, 0x08);
-	reg_w(gspca_dev, 0x12, 0x07);
-	reg_w(gspca_dev, 0x13, 0x00);
-	reg_w(gspca_dev, 0x14, 0x00);
-	reg_w(gspca_dev, 0x15, 0x00);
-	reg_w(gspca_dev, 0x16, 0x00);
-	reg_w(gspca_dev, 0x17, 0x00);
-	reg_w(gspca_dev, 0x18, 0x00);
-	reg_w(gspca_dev, 0x19, 0x00);
-	reg_w(gspca_dev, 0x1a, 0x00);
-	reg_w(gspca_dev, 0x1b, 0x03);
-	reg_w(gspca_dev, 0x1c, 0xa0);
-	reg_w(gspca_dev, 0x1d, 0x01);
-	reg_w(gspca_dev, 0x1e, 0xf4);
-	reg_w(gspca_dev, 0x21, 0x00);
-	reg_w(gspca_dev, 0x22, 0x08);
-	reg_w(gspca_dev, 0x24, 0x03);
-	reg_w(gspca_dev, 0x26, 0x00);
-	reg_w(gspca_dev, 0x27, 0x01);
-	reg_w(gspca_dev, 0x28, 0xca);
-	reg_w(gspca_dev, 0x29, 0x10);
-	reg_w(gspca_dev, 0x2a, 0x06);
-	reg_w(gspca_dev, 0x2b, 0x78);
-	reg_w(gspca_dev, 0x2c, 0x00);
-	reg_w(gspca_dev, 0x2d, 0x00);
-	reg_w(gspca_dev, 0x2e, 0x00);
-	reg_w(gspca_dev, 0x2f, 0x00);
-	reg_w(gspca_dev, 0x30, 0x23);
-	reg_w(gspca_dev, 0x31, 0x28);
-	reg_w(gspca_dev, 0x32, 0x04);
-	reg_w(gspca_dev, 0x33, 0x11);
-	reg_w(gspca_dev, 0x34, 0x00);
-	reg_w(gspca_dev, 0x35, 0x00);
-	reg_w(gspca_dev, 0x11, 0x01);
-	setcontrast(gspca_dev);
-	setbrightness(gspca_dev);
-	setcolors(gspca_dev);
-	setautogain(gspca_dev);
+	sd->sof_read = 0;
+
+	if (sd->sensor == SENSOR_PAC7302) {
+		reg_w_var(gspca_dev, start_7302);
+		setbrightcont(gspca_dev);
+		setcolors(gspca_dev);
+	} else {
+		reg_w_var(gspca_dev, start_7311);
+		setcontrast(gspca_dev);
+	}
+	setgain(gspca_dev);
+	setexposure(gspca_dev);
+	sethvflip(gspca_dev);
 
 	/* set correct resolution */
 	switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
-	case 2:					/* 160x120 */
-		reg_w(gspca_dev, 0xff, 0x04);
-		reg_w(gspca_dev, 0x02, 0x03);
+	case 2:					/* 160x120 pac7311 */
 		reg_w(gspca_dev, 0xff, 0x01);
-		reg_w(gspca_dev, 0x08, 0x09);
 		reg_w(gspca_dev, 0x17, 0x20);
-		reg_w(gspca_dev, 0x1b, 0x00);
-/*		reg_w(gspca_dev, 0x80, 0x69); */
 		reg_w(gspca_dev, 0x87, 0x10);
 		break;
-	case 1:					/* 320x240 */
-		reg_w(gspca_dev, 0xff, 0x04);
-		reg_w(gspca_dev, 0x02, 0x03);
+	case 1:					/* 320x240 pac7311 */
 		reg_w(gspca_dev, 0xff, 0x01);
-		reg_w(gspca_dev, 0x08, 0x09);
 		reg_w(gspca_dev, 0x17, 0x30);
-/*		reg_w(gspca_dev, 0x80, 0x3f); */
 		reg_w(gspca_dev, 0x87, 0x11);
 		break;
 	case 0:					/* 640x480 */
-		reg_w(gspca_dev, 0xff, 0x04);
-		reg_w(gspca_dev, 0x02, 0x03);
+		if (sd->sensor == SENSOR_PAC7302)
+			break;
 		reg_w(gspca_dev, 0xff, 0x01);
-		reg_w(gspca_dev, 0x08, 0x08);
 		reg_w(gspca_dev, 0x17, 0x00);
-/*		reg_w(gspca_dev, 0x80, 0x1c); */
 		reg_w(gspca_dev, 0x87, 0x12);
 		break;
 	}
 
+	sd->sof_read = 0;
+	sd->autogain_ignore_frames = 0;
+	atomic_set(&sd->avg_lum, -1);
+
 	/* start stream */
 	reg_w(gspca_dev, 0xff, 0x01);
-	reg_w(gspca_dev, 0x78, 0x04);
-	reg_w(gspca_dev, 0x78, 0x05);
+	if (sd->sensor == SENSOR_PAC7302)
+		reg_w(gspca_dev, 0x78, 0x01);
+	else
+		reg_w(gspca_dev, 0x78, 0x05);
 }
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
 {
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->sensor == SENSOR_PAC7302) {
+		reg_w(gspca_dev, 0xff, 0x01);
+		reg_w(gspca_dev, 0x78, 0x00);
+		reg_w(gspca_dev, 0x78, 0x00);
+		return;
+	}
 	reg_w(gspca_dev, 0xff, 0x04);
 	reg_w(gspca_dev, 0x27, 0x80);
 	reg_w(gspca_dev, 0x28, 0xca);
@@ -456,187 +743,147 @@
 	reg_w(gspca_dev, 0x2a, 0x0e);
 	reg_w(gspca_dev, 0xff, 0x01);
 	reg_w(gspca_dev, 0x3e, 0x20);
-	reg_w(gspca_dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */
-	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
-	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
+	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
+	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
+	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
 }
 
 static void sd_stop0(struct gspca_dev *gspca_dev)
 {
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->sensor == SENSOR_PAC7302) {
+		reg_w(gspca_dev, 0xff, 0x01);
+		reg_w(gspca_dev, 0x78, 0x40);
+	}
 }
 
-/* this function is called at close time */
-static void sd_close(struct gspca_dev *gspca_dev)
-{
-	reg_w(gspca_dev, 0xff, 0x04);
-	reg_w(gspca_dev, 0x27, 0x80);
-	reg_w(gspca_dev, 0x28, 0xca);
-	reg_w(gspca_dev, 0x29, 0x53);
-	reg_w(gspca_dev, 0x2a, 0x0e);
-	reg_w(gspca_dev, 0xff, 0x01);
-	reg_w(gspca_dev, 0x3e, 0x20);
-	reg_w(gspca_dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */
-	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
-	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
-}
+/* Include pac common sof detection functions */
+#include "pac_common.h"
 
 static void do_autogain(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int luma;
-	int luma_mean = 128;
-	int luma_delta = 20;
-	__u8 spring = 5;
-	int Gbright;
+	int avg_lum = atomic_read(&sd->avg_lum);
+	int desired_lum, deadzone;
 
-	if (!atomic_read(&sd->do_gain))
+	if (avg_lum == -1)
 		return;
-	atomic_set(&sd->do_gain, 0);
 
-	luma = atomic_read(&sd->avg_lum);
-	Gbright = reg_r(gspca_dev, 0x02);
-	PDEBUG(D_FRAM, "luma mean %d", luma);
-	if (luma < luma_mean - luma_delta ||
-	    luma > luma_mean + luma_delta) {
-		Gbright += (luma_mean - luma) >> spring;
-		if (Gbright > 0x1a)
-			Gbright = 0x1a;
-		else if (Gbright < 4)
-			Gbright = 4;
-		PDEBUG(D_FRAM, "gbright %d", Gbright);
-		reg_w(gspca_dev, 0xff, 0x04);
-		reg_w(gspca_dev, 0x0f, Gbright);
-		/* load registers to sensor (Bit 0, auto clear) */
-		reg_w(gspca_dev, 0x11, 0x01);
+	if (sd->sensor == SENSOR_PAC7302) {
+		desired_lum = 270 + sd->brightness * 4;
+		/* Hack hack, with the 7202 the first exposure step is
+		   pretty large, so if we're about to make the first
+		   exposure increase make the deadzone large to avoid
+		   oscilating */
+		if (desired_lum > avg_lum && sd->gain == GAIN_DEF &&
+				sd->exposure > EXPOSURE_DEF &&
+				sd->exposure < 42)
+			deadzone = 90;
+		else
+			deadzone = 30;
+	} else {
+		desired_lum = 200;
+		deadzone = 20;
 	}
+
+	if (sd->autogain_ignore_frames > 0)
+		sd->autogain_ignore_frames--;
+	else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
+			deadzone, GAIN_KNEE, EXPOSURE_KNEE))
+		sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
 }
 
+static const unsigned char pac7311_jpeg_header1[] = {
+  0xff, 0xd8, 0xff, 0xc0, 0x00, 0x11, 0x08
+};
+
+static const unsigned char pac7311_jpeg_header2[] = {
+  0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda,
+  0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
+};
+
+/* this function is run at interrupt level */
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	unsigned char tmpbuf[4];
-	int i, p, ffseq;
+	unsigned char *sof;
 
-/*	if (len < 5) { */
-	if (len < 6) {
-/*		gspca_dev->last_packet_type = DISCARD_PACKET; */
-		return;
-	}
+	sof = pac_find_sof(gspca_dev, data, len);
+	if (sof) {
+		unsigned char tmpbuf[4];
+		int n, lum_offset, footer_length;
 
-	ffseq = sd->ffseq;
+		if (sd->sensor == SENSOR_PAC7302) {
+		  /* 6 bytes after the FF D9 EOF marker a number of lumination
+		     bytes are send corresponding to different parts of the
+		     image, the 14th and 15th byte after the EOF seem to
+		     correspond to the center of the image */
+		  lum_offset = 61 + sizeof pac_sof_marker;
+		  footer_length = 74;
+		} else {
+		  lum_offset = 24 + sizeof pac_sof_marker;
+		  footer_length = 26;
+		}
 
-	for (p = 0; p < len - 6; p++) {
-		if ((data[0 + p] == 0xff)
-		    && (data[1 + p] == 0xff)
-		    && (data[2 + p] == 0x00)
-		    && (data[3 + p] == 0xff)
-		    && (data[4 + p] == 0x96)) {
-
-			/* start of frame */
-			if (sd->ag_cnt >= 0 && p > 28) {
-				sd->lum_sum += data[p - 23];
-				if (--sd->ag_cnt < 0) {
-					sd->ag_cnt = AG_CNT_START;
-					atomic_set(&sd->avg_lum,
-						sd->lum_sum / AG_CNT_START);
-					sd->lum_sum = 0;
-					atomic_set(&sd->do_gain, 1);
-				}
-			}
-
-			/* copy the end of data to the current frame */
+		/* Finish decoding current frame */
+		n = (sof - data) - (footer_length + sizeof pac_sof_marker);
+		if (n < 0) {
+			frame->data_end += n;
+			n = 0;
+		}
+		frame = gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+					data, n);
+		if (gspca_dev->last_packet_type != DISCARD_PACKET &&
+				frame->data_end[-2] == 0xff &&
+				frame->data_end[-1] == 0xd9)
 			frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-						data, p);
+						NULL, 0);
 
-			/* put the JPEG header in the new frame */
-			gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-					(unsigned char *) pac7311_jpeg_header,
-					12);
+		n = sof - data;
+		len -= n;
+		data = sof;
+
+		/* Get average lumination */
+		if (gspca_dev->last_packet_type == LAST_PACKET &&
+				n >= lum_offset)
+			atomic_set(&sd->avg_lum, data[-lum_offset] +
+						data[-lum_offset + 1]);
+		else
+			atomic_set(&sd->avg_lum, -1);
+
+		/* Start the new frame with the jpeg header */
+		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+			pac7311_jpeg_header1, sizeof(pac7311_jpeg_header1));
+		if (sd->sensor == SENSOR_PAC7302) {
+			/* The PAC7302 has the image rotated 90 degrees */
+			tmpbuf[0] = gspca_dev->width >> 8;
+			tmpbuf[1] = gspca_dev->width & 0xff;
+			tmpbuf[2] = gspca_dev->height >> 8;
+			tmpbuf[3] = gspca_dev->height & 0xff;
+		} else {
 			tmpbuf[0] = gspca_dev->height >> 8;
 			tmpbuf[1] = gspca_dev->height & 0xff;
 			tmpbuf[2] = gspca_dev->width >> 8;
 			tmpbuf[3] = gspca_dev->width & 0xff;
-			gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-					tmpbuf, 4);
-			gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-				(unsigned char *) &pac7311_jpeg_header[16],
-				PAC7311_JPEG_HEADER_SIZE - 16);
-
-			data += p + 7;
-			len -= p + 7;
-			ffseq = 0;
-			break;
 		}
+		gspca_frame_add(gspca_dev, INTER_PACKET, frame, tmpbuf, 4);
+		gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+			pac7311_jpeg_header2, sizeof(pac7311_jpeg_header2));
 	}
-
-	/* remove the 'ff ff ff xx' sequences */
-	switch (ffseq) {
-	case 3:
-		data += 1;
-		len -= 1;
-		break;
-	case 2:
-		if (data[0] == 0xff) {
-			data += 2;
-			len -= 2;
-			frame->data_end -= 2;
-		}
-		break;
-	case 1:
-		if (data[0] == 0xff
-		    && data[1] == 0xff) {
-			data += 3;
-			len -= 3;
-			frame->data_end -= 1;
-		}
-		break;
-	}
-	for (i = 0; i < len - 4; i++) {
-		if (data[i] == 0xff
-		    && data[i + 1] == 0xff
-		    && data[i + 2] == 0xff) {
-			memmove(&data[i], &data[i + 4], len - i - 4);
-			len -= 4;
-		}
-	}
-	ffseq = 0;
-	if (data[len - 4] == 0xff) {
-		if (data[len - 3] == 0xff
-		    && data[len - 2] == 0xff) {
-			len -= 4;
-		}
-	} else if (data[len - 3] == 0xff) {
-		if (data[len - 2] == 0xff
-		    && data[len - 1] == 0xff)
-			ffseq = 3;
-	} else if (data[len - 2] == 0xff) {
-		if (data[len - 1] == 0xff)
-			ffseq = 2;
-	} else if (data[len - 1] == 0xff)
-		ffseq = 1;
-	sd->ffseq = ffseq;
 	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
 }
 
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
-/*	sd->brightness = reg_r(gspca_dev, 0x08);
-	return sd->brightness;	*/
-/*	PDEBUG(D_CONF, "Called pac7311_getbrightness: Not implemented yet"); */
-}
-
-
-
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	sd->brightness = val;
 	if (gspca_dev->streaming)
-		setbrightness(gspca_dev);
+		setbrightcont(gspca_dev);
 	return 0;
 }
 
@@ -644,7 +891,6 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	getbrightness(gspca_dev);
 	*val = sd->brightness;
 	return 0;
 }
@@ -654,8 +900,12 @@
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	sd->contrast = val;
-	if (gspca_dev->streaming)
-		setcontrast(gspca_dev);
+	if (gspca_dev->streaming) {
+		if (sd->sensor == SENSOR_PAC7302)
+			setbrightcont(gspca_dev);
+		else
+			setcontrast(gspca_dev);
+	}
 	return 0;
 }
 
@@ -663,7 +913,6 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-/*	getcontrast(gspca_dev); */
 	*val = sd->contrast;
 	return 0;
 }
@@ -682,18 +931,66 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-/*	getcolors(gspca_dev); */
 	*val = sd->colors;
 	return 0;
 }
 
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->gain = val;
+	if (gspca_dev->streaming)
+		setgain(gspca_dev);
+	return 0;
+}
+
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->gain;
+	return 0;
+}
+
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->exposure = val;
+	if (gspca_dev->streaming)
+		setexposure(gspca_dev);
+	return 0;
+}
+
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->exposure;
+	return 0;
+}
+
 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	sd->autogain = val;
-	if (gspca_dev->streaming)
-		setautogain(gspca_dev);
+	/* when switching to autogain set defaults to make sure
+	   we are on a valid point of the autogain gain /
+	   exposure knee graph, and give this change time to
+	   take effect before doing autogain. */
+	if (sd->autogain) {
+		sd->exposure = EXPOSURE_DEF;
+		sd->gain = GAIN_DEF;
+		if (gspca_dev->streaming) {
+			sd->autogain_ignore_frames =
+				PAC_AUTOGAIN_IGNORE_FRAMES;
+			setexposure(gspca_dev);
+			setgain(gspca_dev);
+		}
+	}
+
 	return 0;
 }
 
@@ -705,30 +1002,67 @@
 	return 0;
 }
 
+static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->hflip = val;
+	if (gspca_dev->streaming)
+		sethvflip(gspca_dev);
+	return 0;
+}
+
+static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->hflip;
+	return 0;
+}
+
+static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->vflip = val;
+	if (gspca_dev->streaming)
+		sethvflip(gspca_dev);
+	return 0;
+}
+
+static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->vflip;
+	return 0;
+}
+
 /* sub-driver description */
 static struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
-	.open = sd_open,
+	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
 	.stop0 = sd_stop0,
-	.close = sd_close,
 	.pkt_scan = sd_pkt_scan,
 	.dq_callback = do_autogain,
 };
 
 /* -- module initialisation -- */
 static __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x093a, 0x2600)},
-	{USB_DEVICE(0x093a, 0x2601)},
-	{USB_DEVICE(0x093a, 0x2603)},
-	{USB_DEVICE(0x093a, 0x2608)},
-	{USB_DEVICE(0x093a, 0x260e)},
-	{USB_DEVICE(0x093a, 0x260f)},
-	{USB_DEVICE(0x093a, 0x2621)},
+	{USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311},
+	{USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311},
+	{USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311},
+	{USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311},
+	{USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311},
+	{USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311},
+	{USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302},
+	{USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302},
+	{USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
@@ -746,6 +1080,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/pac_common.h b/drivers/media/video/gspca/pac_common.h
new file mode 100644
index 0000000..34d4b14
--- /dev/null
+++ b/drivers/media/video/gspca/pac_common.h
@@ -0,0 +1,60 @@
+/*
+ * Pixart PAC207BCA / PAC73xx common functions
+ *
+ * Copyright (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl>
+ * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
+ * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/* We calculate the autogain at the end of the transfer of a frame, at this
+   moment a frame with the old settings is being transmitted, and a frame is
+   being captured with the old settings. So if we adjust the autogain we must
+   ignore atleast the 2 next frames for the new settings to come into effect
+   before doing any other adjustments */
+#define PAC_AUTOGAIN_IGNORE_FRAMES	3
+
+static const unsigned char pac_sof_marker[5] =
+		{ 0xff, 0xff, 0x00, 0xff, 0x96 };
+
+static unsigned char *pac_find_sof(struct gspca_dev *gspca_dev,
+					unsigned char *m, int len)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int i;
+
+	/* Search for the SOF marker (fixed part) in the header */
+	for (i = 0; i < len; i++) {
+		if (m[i] == pac_sof_marker[sd->sof_read]) {
+			sd->sof_read++;
+			if (sd->sof_read == sizeof(pac_sof_marker)) {
+				PDEBUG(D_FRAM,
+					"SOF found, bytes to analyze: %u."
+					" Frame starts at byte #%u",
+					len, i + 1);
+				sd->sof_read = 0;
+				return m + i + 1;
+			}
+		} else {
+			sd->sof_read = 0;
+		}
+	}
+
+	return NULL;
+}
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 11210c7..5dd78c6 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -20,6 +20,26 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
+/* Some documentation on known sonixb registers:
+
+Reg	Use
+0x10	high nibble red gain low nibble blue gain
+0x11	low nibble green gain
+0x12	hstart
+0x13	vstart
+0x15	hsize (hsize = register-value * 16)
+0x16	vsize (vsize = register-value * 16)
+0x17	bit 0 toggle compression quality (according to sn9c102 driver)
+0x18	bit 7 enables compression, bit 4-5 set image down scaling:
+	00 scale 1, 01 scale 1/2, 10, scale 1/4
+0x19	high-nibble is sensor clock divider, changes exposure on sensors which
+	use a clock generated by the bridge. Some sensors have their own clock.
+0x1c	auto_exposure area (for avg_lum) startx (startx = register-value * 32)
+0x1d	auto_exposure area (for avg_lum) starty (starty = register-value * 32)
+0x1e	auto_exposure area (for avg_lum) stopx (hsize = (0x1e - 0x1c) * 32)
+0x1f	auto_exposure area (for avg_lum) stopy (vsize = (0x1f - 0x1d) * 32)
+*/
+
 #define MODULE_NAME "sonixb"
 
 #include "gspca.h"
@@ -31,10 +51,8 @@
 /* specific webcam descriptor */
 struct sd {
 	struct gspca_dev gspca_dev;	/* !! must be the first item */
-
-	struct sd_desc sd_desc;		/* our nctrls differ dependend upon the
-					   sensor, so we use a per cam copy */
 	atomic_t avg_lum;
+	int prev_avg_lum;
 
 	unsigned char gain;
 	unsigned char exposure;
@@ -44,8 +62,12 @@
 	unsigned char frames_to_drop;
 	unsigned char freq;		/* light freq filter setting */
 
-	unsigned char fr_h_sz;		/* size of frame header */
-	char sensor;			/* Type of image sensor chip */
+	__u8 bridge;			/* Type of bridge */
+#define BRIDGE_101 0
+#define BRIDGE_102 0 /* We make no difference between 101 and 102 */
+#define BRIDGE_103 1
+
+	__u8 sensor;			/* Type of image sensor chip */
 #define SENSOR_HV7131R 0
 #define SENSOR_OV6650 1
 #define SENSOR_OV7630 2
@@ -53,16 +75,35 @@
 #define SENSOR_PAS202 4
 #define SENSOR_TAS5110 5
 #define SENSOR_TAS5130CXX 6
-	char sensor_has_gain;
-	__u8 sensor_addr;
 	__u8 reg11;
 };
 
-/* flags used in the device id table */
+typedef const __u8 sensor_init_t[8];
+
+struct sensor_data {
+	const __u8 *bridge_init[2];
+	int bridge_init_size[2];
+	sensor_init_t *sensor_init;
+	int sensor_init_size;
+	sensor_init_t *sensor_bridge_init[2];
+	int sensor_bridge_init_size[2];
+	int flags;
+	unsigned ctrl_dis;
+	__u8 sensor_addr;
+};
+
+/* sensor_data flags */
 #define F_GAIN 0x01		/* has gain */
-#define F_AUTO 0x02		/* has autogain */
-#define F_SIF  0x04		/* sif or vga */
-#define F_H18  0x08		/* long (18 b) or short (12 b) frame header */
+#define F_SIF  0x02		/* sif or vga */
+
+/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
+#define MODE_RAW 0x10		/* raw bayer mode */
+#define MODE_REDUCED_SIF 0x20	/* vga mode (320x240 / 160x120) on sif cam */
+
+/* ctrl_dis helper macros */
+#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX))
+#define NO_FREQ (1 << FREQ_IDX)
+#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
 
 #define COMP2 0x8f
 #define COMP 0xc7		/* 0x87 //0x07 */
@@ -73,6 +114,18 @@
 
 #define SYS_CLK 0x04
 
+#define SENS(bridge_1, bridge_3, sensor, sensor_1, \
+	sensor_3, _flags, _ctrl_dis, _sensor_addr) \
+{ \
+	.bridge_init = { bridge_1, bridge_3 }, \
+	.bridge_init_size = { sizeof(bridge_1), sizeof(bridge_3) }, \
+	.sensor_init = sensor, \
+	.sensor_init_size = sizeof(sensor), \
+	.sensor_bridge_init = { sensor_1, sensor_3,}, \
+	.sensor_bridge_init_size = { sizeof(sensor_1), sizeof(sensor_3)}, \
+	.flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \
+}
+
 /* We calculate the autogain at the end of the transfer of a frame, at this
    moment a frame with the old settings is being transmitted, and a frame is
    being captured with the old settings. So if we adjust the autogain we must
@@ -95,6 +148,7 @@
 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
 
 static struct ctrl sd_ctrls[] = {
+#define BRIGHTNESS_IDX 0
 	{
 	    {
 		.id      = V4L2_CID_BRIGHTNESS,
@@ -109,6 +163,7 @@
 	    .set = sd_setbrightness,
 	    .get = sd_getbrightness,
 	},
+#define GAIN_IDX 1
 	{
 	    {
 		.id      = V4L2_CID_GAIN,
@@ -124,6 +179,7 @@
 	    .set = sd_setgain,
 	    .get = sd_getgain,
 	},
+#define EXPOSURE_IDX 2
 	{
 		{
 			.id = V4L2_CID_EXPOSURE,
@@ -140,6 +196,7 @@
 		.set = sd_setexposure,
 		.get = sd_getexposure,
 	},
+#define AUTOGAIN_IDX 3
 	{
 		{
 			.id = V4L2_CID_AUTOGAIN,
@@ -155,6 +212,7 @@
 		.set = sd_setautogain,
 		.get = sd_getautogain,
 	},
+#define FREQ_IDX 4
 	{
 		{
 			.id	 = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -172,31 +230,56 @@
 };
 
 static struct v4l2_pix_format vga_mode[] = {
+	{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 160,
+		.sizeimage = 160 * 120 * 5 / 4,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 2 | MODE_RAW},
 	{160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
 		.bytesperline = 160,
-		.sizeimage = 160 * 120,
+		.sizeimage = 160 * 120 * 5 / 4,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 2},
 	{320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
 		.bytesperline = 320,
-		.sizeimage = 320 * 240,
+		.sizeimage = 320 * 240 * 5 / 4,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 1},
 	{640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
 		.bytesperline = 640,
-		.sizeimage = 640 * 480,
+		.sizeimage = 640 * 480 * 5 / 4,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 0},
 };
 static struct v4l2_pix_format sif_mode[] = {
+	{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 160,
+		.sizeimage = 160 * 120,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1 | MODE_RAW | MODE_REDUCED_SIF},
+	{160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
+		.bytesperline = 160,
+		.sizeimage = 160 * 120 * 5 / 4,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1 | MODE_REDUCED_SIF},
+	{176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 176,
+		.sizeimage = 176 * 144 * 5 / 4,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1 | MODE_RAW},
 	{176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
 		.bytesperline = 176,
-		.sizeimage = 176 * 144,
+		.sizeimage = 176 * 144 * 5 / 4,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 1},
+	{320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 320 * 240 * 5 / 4,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0 | MODE_REDUCED_SIF},
 	{352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
 		.bytesperline = 352,
-		.sizeimage = 352 * 288,
+		.sizeimage = 352 * 288 * 5 / 4,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 0},
 };
@@ -204,7 +287,7 @@
 static const __u8 initHv7131[] = {
 	0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
 	0x00, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0x01, 0x00,	/* shift from 0x02 0x01 0x00 */
+	0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
 	0x28, 0x1e, 0x60, 0x8a, 0x20,
 	0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
 };
@@ -218,8 +301,8 @@
 static const __u8 initOv6650[] = {
 	0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
 	0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x0b,
-	0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00
+	0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
+	0x10, 0x1d, 0x10, 0x02, 0x02, 0x09, 0x07
 };
 static const __u8 ov6650_sensor_init[][8] =
 {
@@ -257,15 +340,15 @@
 static const __u8 initOv7630[] = {
 	0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,	/* r01 .. r08 */
 	0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* r09 .. r10 */
-	0x00, 0x02, 0x01, 0x0a,				/* r11 .. r14 */
+	0x00, 0x01, 0x01, 0x0a,				/* r11 .. r14 */
 	0x28, 0x1e,			/* H & V sizes     r15 .. r16 */
-	0x68, COMP1, MCK_INIT1,				/* r17 .. r19 */
+	0x68, COMP2, MCK_INIT1,				/* r17 .. r19 */
 	0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c		/* r1a .. r1f */
 };
 static const __u8 initOv7630_3[] = {
 	0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80,	/* r01 .. r08 */
 	0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,	/* r09 .. r10 */
-	0x00, 0x01, 0x01, 0x0a,				/* r11 .. r14 */
+	0x00, 0x02, 0x01, 0x0a,				/* r11 .. r14 */
 	0x28, 0x1e,			/* H & V sizes     r15 .. r16 */
 	0x68, 0x8f, MCK_INIT1,				/* r17 .. r19 */
 	0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00,	/* r1a .. r20 */
@@ -294,47 +377,65 @@
 	{0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
 };
 
+static const __u8 ov7630_sensor_init_3[][8] = {
+	{0xa0, 0x21, 0x13, 0x80, 0x00,	0x00, 0x00, 0x10},
+};
+
 static const __u8 initPas106[] = {
 	0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
 	0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x01, 0x00,
-	0x16, 0x12, 0x28, COMP1, MCK_INIT1,
-	0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
+	0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
+	0x16, 0x12, 0x24, COMP1, MCK_INIT1,
+	0x18, 0x10, 0x02, 0x02, 0x09, 0x07
 };
 /* compression 0x86 mckinit1 0x2b */
-static const __u8 pas106_data[][2] = {
-	{0x02, 0x04},		/* Pixel Clock Divider 6 */
-	{0x03, 0x13},		/* Frame Time MSB */
-/*	{0x03, 0x12},		 * Frame Time MSB */
-	{0x04, 0x06},		/* Frame Time LSB */
-/*	{0x04, 0x05},		 * Frame Time LSB */
-	{0x05, 0x65},		/* Shutter Time Line Offset */
-/*	{0x05, 0x6d},		 * Shutter Time Line Offset */
-/*	{0x06, 0xb1},		 * Shutter Time Pixel Offset */
-	{0x06, 0xcd},		/* Shutter Time Pixel Offset */
-	{0x07, 0xc1},		/* Black Level Subtract Sign */
-/*	{0x07, 0x00},		 * Black Level Subtract Sign */
-	{0x08, 0x06},		/* Black Level Subtract Level */
-	{0x08, 0x06},		/* Black Level Subtract Level */
-/*	{0x08, 0x01},		 * Black Level Subtract Level */
-	{0x09, 0x05},		/* Color Gain B Pixel 5 a */
-	{0x0a, 0x04},		/* Color Gain G1 Pixel 1 5 */
-	{0x0b, 0x04},		/* Color Gain G2 Pixel 1 0 5 */
-	{0x0c, 0x05},		/* Color Gain R Pixel 3 1 */
-	{0x0d, 0x00},		/* Color GainH  Pixel */
-	{0x0e, 0x0e},		/* Global Gain */
-	{0x0f, 0x00},		/* Contrast */
-	{0x10, 0x06},		/* H&V synchro polarity */
-	{0x11, 0x06},		/* ?default */
-	{0x12, 0x06},		/* DAC scale */
-	{0x14, 0x02},		/* ?default */
-	{0x13, 0x01},		/* Validate Settings */
+static const __u8 pas106_sensor_init[][8] = {
+	/* Pixel Clock Divider 6 */
+	{ 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 },
+	/* Frame Time MSB (also seen as 0x12) */
+	{ 0xa1, 0x40, 0x03, 0x13, 0x00, 0x00, 0x00, 0x14 },
+	/* Frame Time LSB (also seen as 0x05) */
+	{ 0xa1, 0x40, 0x04, 0x06, 0x00, 0x00, 0x00, 0x14 },
+	/* Shutter Time Line Offset (also seen as 0x6d) */
+	{ 0xa1, 0x40, 0x05, 0x65, 0x00, 0x00, 0x00, 0x14 },
+	/* Shutter Time Pixel Offset (also seen as 0xb1) */
+	{ 0xa1, 0x40, 0x06, 0xcd, 0x00, 0x00, 0x00, 0x14 },
+	/* Black Level Subtract Sign (also seen 0x00) */
+	{ 0xa1, 0x40, 0x07, 0xc1, 0x00, 0x00, 0x00, 0x14 },
+	/* Black Level Subtract Level (also seen 0x01) */
+	{ 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
+	{ 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
+	/* Color Gain B Pixel 5 a */
+	{ 0xa1, 0x40, 0x09, 0x05, 0x00, 0x00, 0x00, 0x14 },
+	/* Color Gain G1 Pixel 1 5 */
+	{ 0xa1, 0x40, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x14 },
+	/* Color Gain G2 Pixel 1 0 5 */
+	{ 0xa1, 0x40, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x14 },
+	/* Color Gain R Pixel 3 1 */
+	{ 0xa1, 0x40, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x14 },
+	/* Color GainH  Pixel */
+	{ 0xa1, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x14 },
+	/* Global Gain */
+	{ 0xa1, 0x40, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x14 },
+	/* Contrast */
+	{ 0xa1, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x14 },
+	/* H&V synchro polarity */
+	{ 0xa1, 0x40, 0x10, 0x06, 0x00, 0x00, 0x00, 0x14 },
+	/* ?default */
+	{ 0xa1, 0x40, 0x11, 0x06, 0x00, 0x00, 0x00, 0x14 },
+	/* DAC scale */
+	{ 0xa1, 0x40, 0x12, 0x06, 0x00, 0x00, 0x00, 0x14 },
+	/* ?default */
+	{ 0xa1, 0x40, 0x14, 0x02, 0x00, 0x00, 0x00, 0x14 },
+	/* Validate Settings */
+	{ 0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14 },
 };
+
 static const __u8 initPas202[] = {
 	0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
 	0x00, 0x00,
-	0x00, 0x00, 0x00, 0x07, 0x03, 0x0a,	/* 6 */
-	0x28, 0x1e, 0x28, 0x89, 0x30,
+	0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
+	0x28, 0x1e, 0x28, 0x89, 0x20,
 	0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
 };
 static const __u8 pas202_sensor_init[][8] = {
@@ -364,7 +465,7 @@
 static const __u8 initTas5110[] = {
 	0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
 	0x00, 0x00,
-	0x00, 0x01, 0x00, 0x46, 0x09, 0x0a,	/* shift from 0x45 0x09 0x0a */
+	0x00, 0x01, 0x00, 0x45, 0x09, 0x0a,
 	0x16, 0x12, 0x60, 0x86, 0x2b,
 	0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
 };
@@ -377,7 +478,7 @@
 static const __u8 initTas5130[] = {
 	0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
 	0x00, 0x00,
-	0x00, 0x01, 0x00, 0x69, 0x0c, 0x0a,
+	0x00, 0x01, 0x00, 0x68, 0x0c, 0x0a,
 	0x28, 0x1e, 0x60, COMP, MCK_INIT,
 	0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
 };
@@ -389,6 +490,21 @@
 	{0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
 };
 
+struct sensor_data sensor_data[] = {
+SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0),
+SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60),
+SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
+	F_GAIN, 0, 0x21),
+SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ,
+	0),
+SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0,
+	NO_EXPO|NO_FREQ, 0),
+SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF,
+	NO_BRIGHTNESS|NO_FREQ, 0),
+SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ,
+	0),
+};
+
 /* get one byte in gspca_dev->usb_buf */
 static void reg_r(struct gspca_dev *gspca_dev,
 		  __u16 value)
@@ -409,7 +525,7 @@
 		  int len)
 {
 #ifdef GSPCA_DEBUG
-	if (len > sizeof gspca_dev->usb_buf) {
+	if (len > USB_BUF_SZ) {
 		PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
 		return;
 	}
@@ -425,26 +541,6 @@
 			500);
 }
 
-static void reg_w_big(struct gspca_dev *gspca_dev,
-		  __u16 value,
-		  const __u8 *buffer,
-		  int len)
-{
-	__u8 *tmpbuf;
-
-	tmpbuf = kmalloc(len, GFP_KERNEL);
-	memcpy(tmpbuf, buffer, len);
-	usb_control_msg(gspca_dev->dev,
-			usb_sndctrlpipe(gspca_dev->dev, 0),
-			0x08,			/* request */
-			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
-			value,
-			0,			/* index */
-			tmpbuf, len,
-			500);
-	kfree(tmpbuf);
-}
-
 static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
 {
 	int retry = 60;
@@ -487,7 +583,7 @@
 			{0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
 
 		/* change reg 0x06 */
-		i2cOV[1] = sd->sensor_addr;
+		i2cOV[1] = sensor_data[sd->sensor].sensor_addr;
 		i2cOV[3] = sd->brightness;
 		if (i2c_w(gspca_dev, i2cOV) < 0)
 			goto err;
@@ -545,9 +641,6 @@
 			goto err;
 		break;
 	    }
-	case SENSOR_TAS5110:
-		/* FIXME figure out howto control brightness on TAS5110 */
-		break;
 	}
 	return;
 err:
@@ -577,7 +670,7 @@
 	case SENSOR_OV7630: {
 		__u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
 
-		i2c[1] = sd->sensor_addr;
+		i2c[1] = sensor_data[sd->sensor].sensor_addr;
 		i2c[3] = gain >> 2;
 		if (i2c_w(gspca_dev, i2c) < 0)
 			goto err;
@@ -604,7 +697,7 @@
 	rgb_value = gain;
 	reg_w(gspca_dev, 0x11, &rgb_value, 1);
 
-	if (sd->sensor_has_gain)
+	if (sensor_data[sd->sensor].flags & F_GAIN)
 		setsensorgain(gspca_dev);
 }
 
@@ -665,6 +758,11 @@
 		else if (reg11 > 16)
 			reg11 = 16;
 
+		/* In 640x480, if the reg11 has less than 3, the image is
+		   unstable (not enough bandwidth). */
+		if (gspca_dev->width == 640 && reg11 < 3)
+			reg11 = 3;
+
 		/* frame exposure time in ms = 1000 * reg11 / 30    ->
 		reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
 		reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
@@ -678,13 +776,8 @@
 		else if (reg10 > reg10_max)
 			reg10 = reg10_max;
 
-		/* In 640x480, if the reg11 has less than 3, the image is
-		   unstable (not enough bandwidth). */
-		if (gspca_dev->width == 640 && reg11 < 3)
-			reg11 = 3;
-
 		/* Write reg 10 and reg11 low nibble */
-		i2c[1] = sd->sensor_addr;
+		i2c[1] = sensor_data[sd->sensor].sensor_addr;
 		i2c[3] = reg10;
 		i2c[4] |= reg11 - 1;
 
@@ -724,7 +817,7 @@
 					? 0x4f : 0x8a;
 			break;
 		}
-		i2c[1] = sd->sensor_addr;
+		i2c[1] = sensor_data[sd->sensor].sensor_addr;
 		if (i2c_w(gspca_dev, i2c) < 0)
 			PDEBUG(D_ERR, "i2c error setfreq");
 		break;
@@ -757,30 +850,19 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
-	int sif = 0;
 
-	/* nctrls depends upon the sensor, so we use a per cam copy */
-	memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc));
-	gspca_dev->sd_desc = &sd->sd_desc;
+	reg_r(gspca_dev, 0x00);
+	if (gspca_dev->usb_buf[0] != 0x10)
+		return -ENODEV;
 
 	/* copy the webcam info from the device id */
-	sd->sensor = (id->driver_info >> 24) & 0xff;
-	if (id->driver_info & (F_GAIN << 16))
-		sd->sensor_has_gain = 1;
-	if (id->driver_info & (F_AUTO << 16))
-		sd->sd_desc.dq_callback = do_autogain;
-	if (id->driver_info & (F_SIF << 16))
-		sif = 1;
-	if (id->driver_info & (F_H18 << 16))
-		sd->fr_h_sz = 18;		/* size of frame header */
-	else
-		sd->fr_h_sz = 12;
-	sd->sd_desc.nctrls = (id->driver_info >> 8) & 0xff;
-	sd->sensor_addr = id->driver_info & 0xff;
+	sd->sensor = id->driver_info >> 8;
+	sd->bridge = id->driver_info & 0xff;
+	gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
 
 	cam = &gspca_dev->cam;
 	cam->epaddr = 0x01;
-	if (!sif) {
+	if (!(sensor_data[sd->sensor].flags & F_SIF)) {
 		cam->cam_mode = vga_mode;
 		cam->nmodes = ARRAY_SIZE(vga_mode);
 	} else {
@@ -790,95 +872,61 @@
 	sd->brightness = BRIGHTNESS_DEF;
 	sd->gain = GAIN_DEF;
 	sd->exposure = EXPOSURE_DEF;
-	sd->autogain = AUTOGAIN_DEF;
+	if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
+		sd->autogain = 0; /* Disable do_autogain callback */
+	else
+		sd->autogain = AUTOGAIN_DEF;
 	sd->freq = FREQ_DEF;
 
 	return 0;
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
 {
-	reg_r(gspca_dev, 0x00);
-	if (gspca_dev->usb_buf[0] != 0x10)
-		return -ENODEV;
+	const __u8 stop = 0x09; /* Disable stream turn of LED */
+
+	reg_w(gspca_dev, 0x01, &stop, 1);
+
 	return 0;
 }
 
-static void pas106_i2cinit(struct gspca_dev *gspca_dev)
-{
-	int i;
-	const __u8 *data;
-	__u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 };
-
-	i = ARRAY_SIZE(pas106_data);
-	data = pas106_data[0];
-	while (--i >= 0) {
-		memcpy(&i2c1[2], data, 2);
-					/* copy 2 bytes from the template */
-		if (i2c_w(gspca_dev, i2c1) < 0)
-			PDEBUG(D_ERR, "i2c error pas106");
-		data += 2;
-	}
-}
-
 /* -- start the camera -- */
 static void sd_start(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int mode, l = 0x1f;
+	struct cam *cam = &gspca_dev->cam;
+	int mode, l;
 	const __u8 *sn9c10x;
-	__u8 reg17_19[3];
+	__u8 reg12_19[8];
 
-	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+	mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07;
+	sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge];
+	l = sensor_data[sd->sensor].bridge_init_size[sd->bridge];
+	memcpy(reg12_19, &sn9c10x[0x12 - 1], 8);
+	reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4);
+	/* Special cases where reg 17 and or 19 value depends on mode */
 	switch (sd->sensor) {
-	case SENSOR_HV7131R:
-		sn9c10x = initHv7131;
-		reg17_19[0] = 0x60;
-		reg17_19[1] = (mode << 4) | 0x8a;
-		reg17_19[2] = 0x20;
-		break;
-	case SENSOR_OV6650:
-		sn9c10x = initOv6650;
-		reg17_19[0] = 0x68;
-		reg17_19[1] = (mode << 4) | 0x8b;
-		reg17_19[2] = 0x20;
-		break;
-	case SENSOR_OV7630:
-		if (sd->fr_h_sz == 18) { /* SN9C103 */
-			sn9c10x = initOv7630_3;
-			l = sizeof initOv7630_3;
-		} else
-			sn9c10x = initOv7630;
-		reg17_19[0] = 0x68;
-		reg17_19[1] = (mode << 4) | COMP2;
-		reg17_19[2] = MCK_INIT1;
-		break;
-	case SENSOR_PAS106:
-		sn9c10x = initPas106;
-		reg17_19[0] = 0x24;		/* 0x28 */
-		reg17_19[1] = (mode << 4) | COMP1;
-		reg17_19[2] = MCK_INIT1;
-		break;
 	case SENSOR_PAS202:
-		sn9c10x = initPas202;
-		reg17_19[0] = mode ? 0x24 : 0x20;
-		reg17_19[1] = (mode << 4) | 0x89;
-		reg17_19[2] = 0x20;
+		reg12_19[5] = mode ? 0x24 : 0x20;
 		break;
-	case SENSOR_TAS5110:
-		sn9c10x = initTas5110;
-		reg17_19[0] = 0x60;
-		reg17_19[1] = (mode << 4) | 0x86;
-		reg17_19[2] = 0x2b;		/* 0xf3; */
+	case SENSOR_TAS5130CXX:
+		/* probably not mode specific at all most likely the upper
+		   nibble of 0x19 is exposure (clock divider) just as with
+		   the tas5110, we need someone to test this. */
+		reg12_19[7] = mode ? 0x23 : 0x43;
 		break;
-	default:
-/*	case SENSOR_TAS5130CXX: */
-		sn9c10x = initTas5130;
-		reg17_19[0] = 0x60;
-		reg17_19[1] = (mode << 4) | COMP;
-		reg17_19[2] = mode ? 0x23 : 0x43;
-		break;
+	}
+	/* Disable compression when the raw bayer format has been selected */
+	if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
+		reg12_19[6] &= ~0x80;
+
+	/* Vga mode emulation on SIF sensor? */
+	if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) {
+		reg12_19[0] += 16; /* 0x12: hstart adjust */
+		reg12_19[1] += 24; /* 0x13: vstart adjust */
+		reg12_19[3] = 320 / 16; /* 0x15: hsize */
+		reg12_19[4] = 240 / 16; /* 0x16: vsize */
 	}
 
 	/* reg 0x01 bit 2 video transfert on */
@@ -886,61 +934,36 @@
 	/* reg 0x17 SensorClk enable inv Clk 0x60 */
 	reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
 	/* Set the registers from the template */
-	reg_w_big(gspca_dev, 0x01, sn9c10x, l);
-	switch (sd->sensor) {
-	case SENSOR_HV7131R:
-		i2c_w_vector(gspca_dev, hv7131_sensor_init,
-				sizeof hv7131_sensor_init);
-		break;
-	case SENSOR_OV6650:
-		i2c_w_vector(gspca_dev, ov6650_sensor_init,
-				sizeof ov6650_sensor_init);
-		break;
-	case SENSOR_OV7630:
-		i2c_w_vector(gspca_dev, ov7630_sensor_init,
-				sizeof ov7630_sensor_init);
-		if (sd->fr_h_sz == 18) { /* SN9C103 */
-			const __u8 i2c[] = { 0xa0, 0x21, 0x13, 0x80, 0x00,
-						0x00, 0x00, 0x10 };
-			i2c_w(gspca_dev, i2c);
-		}
-		break;
-	case SENSOR_PAS106:
-		pas106_i2cinit(gspca_dev);
-		break;
-	case SENSOR_PAS202:
-		i2c_w_vector(gspca_dev, pas202_sensor_init,
-				sizeof pas202_sensor_init);
-		break;
-	case SENSOR_TAS5110:
-		i2c_w_vector(gspca_dev, tas5110_sensor_init,
-				sizeof tas5110_sensor_init);
-		break;
-	default:
-/*	case SENSOR_TAS5130CXX: */
-		i2c_w_vector(gspca_dev, tas5130_sensor_init,
-				sizeof tas5130_sensor_init);
-		break;
-	}
+	reg_w(gspca_dev, 0x01, sn9c10x, l);
+
+	/* Init the sensor */
+	i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init,
+			sensor_data[sd->sensor].sensor_init_size);
+	if (sensor_data[sd->sensor].sensor_bridge_init[sd->bridge])
+		i2c_w_vector(gspca_dev,
+			sensor_data[sd->sensor].sensor_bridge_init[sd->bridge],
+			sensor_data[sd->sensor].sensor_bridge_init_size[
+				sd->bridge]);
+
 	/* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
-	reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2);
+	reg_w(gspca_dev, 0x15, &reg12_19[3], 2);
 	/* compression register */
-	reg_w(gspca_dev, 0x18, &reg17_19[1], 1);
+	reg_w(gspca_dev, 0x18, &reg12_19[6], 1);
 	/* H_start */
-	reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1);
+	reg_w(gspca_dev, 0x12, &reg12_19[0], 1);
 	/* V_START */
-	reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1);
+	reg_w(gspca_dev, 0x13, &reg12_19[1], 1);
 	/* reset 0x17 SensorClk enable inv Clk 0x60 */
 				/*fixme: ov7630 [17]=68 8f (+20 if 102)*/
-	reg_w(gspca_dev, 0x17, &reg17_19[0], 1);
+	reg_w(gspca_dev, 0x17, &reg12_19[5], 1);
 	/*MCKSIZE ->3 */	/*fixme: not ov7630*/
-	reg_w(gspca_dev, 0x19, &reg17_19[2], 1);
+	reg_w(gspca_dev, 0x19, &reg12_19[7], 1);
 	/* AE_STRX AE_STRY AE_ENDX AE_ENDY */
 	reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
 	/* Enable video transfert */
 	reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
 	/* Compression */
-	reg_w(gspca_dev, 0x18, &reg17_19[1], 2);
+	reg_w(gspca_dev, 0x18, &reg12_19[6], 2);
 	msleep(20);
 
 	sd->reg11 = -1;
@@ -957,18 +980,7 @@
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
 {
-	__u8 ByteSend;
-
-	ByteSend = 0x09;	/* 0X00 */
-	reg_w(gspca_dev, 0x01, &ByteSend, 1);
-}
-
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
-}
-
-static void sd_close(struct gspca_dev *gspca_dev)
-{
+	sd_init(gspca_dev);
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -978,6 +990,7 @@
 {
 	int i;
 	struct sd *sd = (struct sd *) gspca_dev;
+	struct cam *cam = &gspca_dev->cam;
 
 	/* frames start with:
 	 *	ff ff 00 c4 c4 96	synchro
@@ -998,20 +1011,31 @@
 			    && data[5 + i] == 0x96) {	/* start of frame */
 				int lum = -1;
 				int pkt_type = LAST_PACKET;
+				int fr_h_sz = (sd->bridge == BRIDGE_103) ?
+					18 : 12;
 
-				if (len - i < sd->fr_h_sz) {
+				if (len - i < fr_h_sz) {
 					PDEBUG(D_STREAM, "packet too short to"
 						" get avg brightness");
-				} else if (sd->fr_h_sz == 12) {
-					lum = data[i + 8] + (data[i + 9] << 8);
-				} else {
+				} else if (sd->bridge == BRIDGE_103) {
 					lum = data[i + 9] +
 						(data[i + 10] << 8);
+				} else {
+					lum = data[i + 8] + (data[i + 9] << 8);
 				}
-				if (lum == 0) {
+				/* When exposure changes midway a frame we
+				   get a lum of 0 in this case drop 2 frames
+				   as the frames directly after an exposure
+				   change have an unstable image. Sometimes lum
+				   *really* is 0 (cam used in low light with
+				   low exposure setting), so do not drop frames
+				   if the previous lum was 0 too. */
+				if (lum == 0 && sd->prev_avg_lum != 0) {
 					lum = -1;
 					sd->frames_to_drop = 2;
-				}
+					sd->prev_avg_lum = 0;
+				} else
+					sd->prev_avg_lum = lum;
 				atomic_set(&sd->avg_lum, lum);
 
 				if (sd->frames_to_drop) {
@@ -1021,14 +1045,25 @@
 
 				frame = gspca_frame_add(gspca_dev, pkt_type,
 							frame, data, 0);
-				data += i + sd->fr_h_sz;
-				len -= i + sd->fr_h_sz;
+				data += i + fr_h_sz;
+				len -= i + fr_h_sz;
 				gspca_frame_add(gspca_dev, FIRST_PACKET,
 						frame, data, len);
 				return;
 			}
 		}
 	}
+
+	if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
+		/* In raw mode we sometimes get some garbage after the frame
+		   ignore this */
+		int used = frame->data_end - frame->data;
+		int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
+
+		if (used + len > size)
+			len = size - used;
+	}
+
 	gspca_frame_add(gspca_dev, INTER_PACKET,
 			frame, data, len);
 }
@@ -1162,58 +1197,45 @@
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
-	.open = sd_open,
+	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
-	.stop0 = sd_stop0,
-	.close = sd_close,
 	.pkt_scan = sd_pkt_scan,
 	.querymenu = sd_querymenu,
+	.dq_callback = do_autogain,
 };
 
 /* -- module initialisation -- */
-#define SFCI(sensor, flags, nctrls, i2c_addr) \
-	.driver_info = (SENSOR_ ## sensor << 24) \
-			| ((flags) << 16) \
-			| ((nctrls) << 8) \
-			| (i2c_addr)
+#define SB(sensor, bridge) \
+	.driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
+
+
 static __devinitdata struct usb_device_id device_table[] = {
-#ifndef CONFIG_USB_SN9C102
-	{USB_DEVICE(0x0c45, 0x6001),			/* SN9C102 */
-			SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
-	{USB_DEVICE(0x0c45, 0x6005),			/* SN9C101 */
-			SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
-	{USB_DEVICE(0x0c45, 0x6007),			/* SN9C101 */
-			SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
-	{USB_DEVICE(0x0c45, 0x6009),			/* SN9C101 */
-			SFCI(PAS106, F_SIF, 2, 0)},
-	{USB_DEVICE(0x0c45, 0x600d),			/* SN9C101 */
-			SFCI(PAS106, F_SIF, 2, 0)},
+	{USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, /* TAS5110C1B */
+	{USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, /* TAS5110C1B */
+#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
+	{USB_DEVICE(0x0c45, 0x6007), SB(TAS5110, 101)}, /* TAS5110D */
+	{USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
+	{USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
 #endif
-	{USB_DEVICE(0x0c45, 0x6011),		/* SN9C101 - SN9C101G */
-			SFCI(OV6650, F_GAIN|F_AUTO|F_SIF, 5, 0x60)},
-#ifndef CONFIG_USB_SN9C102
-	{USB_DEVICE(0x0c45, 0x6019),			/* SN9C101 */
-			SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
-	{USB_DEVICE(0x0c45, 0x6024),			/* SN9C102 */
-			SFCI(TAS5130CXX, 0, 2, 0)},
-	{USB_DEVICE(0x0c45, 0x6025),			/* SN9C102 */
-			SFCI(TAS5130CXX, 0, 2, 0)},
-	{USB_DEVICE(0x0c45, 0x6028),			/* SN9C102 */
-			SFCI(PAS202, 0, 2, 0)},
-	{USB_DEVICE(0x0c45, 0x6029),			/* SN9C101 */
-			SFCI(PAS106, F_SIF, 2, 0)},
-	{USB_DEVICE(0x0c45, 0x602c),			/* SN9C102 */
-			SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
-	{USB_DEVICE(0x0c45, 0x602d),			/* SN9C102 */
-			SFCI(HV7131R, 0, 2, 0)},
-	{USB_DEVICE(0x0c45, 0x602e),			/* SN9C102 */
-			SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
-	{USB_DEVICE(0x0c45, 0x60af),			/* SN9C103 */
-			SFCI(PAS202, F_H18, 2, 0)},
-	{USB_DEVICE(0x0c45, 0x60b0),			/* SN9C103 */
-			SFCI(OV7630, F_GAIN|F_AUTO|F_H18, 5, 0x21)},
+	{USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
+#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
+	{USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
+	{USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
+	{USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
+	{USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
+	{USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
+	{USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
 #endif
+	{USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
+#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
+	{USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
+#endif
+	{USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
+#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
+	{USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
+#endif
+	{USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
@@ -1231,6 +1253,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 245a30e..d75b1d2 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -54,8 +54,10 @@
 #define SENSOR_HV7131R 0
 #define SENSOR_MI0360 1
 #define SENSOR_MO4000 2
-#define SENSOR_OV7648 3
-#define SENSOR_OV7660 4
+#define SENSOR_OM6802 3
+#define SENSOR_OV7630 4
+#define SENSOR_OV7648 5
+#define SENSOR_OV7660 6
 	unsigned char i2c_base;
 };
 
@@ -76,7 +78,8 @@
 		.type    = V4L2_CTRL_TYPE_INTEGER,
 		.name    = "Brightness",
 		.minimum = 0,
-		.maximum = 0xffff,
+#define BRIGHTNESS_MAX 0xffff
+		.maximum = BRIGHTNESS_MAX,
 		.step    = 1,
 #define BRIGHTNESS_DEF 0x7fff
 		.default_value = BRIGHTNESS_DEF,
@@ -90,7 +93,8 @@
 		.type    = V4L2_CTRL_TYPE_INTEGER,
 		.name    = "Contrast",
 		.minimum = 0,
-		.maximum = 127,
+#define CONTRAST_MAX 127
+		.maximum = CONTRAST_MAX,
 		.step    = 1,
 #define CONTRAST_DEF 63
 		.default_value = CONTRAST_DEF,
@@ -104,14 +108,15 @@
 		.type    = V4L2_CTRL_TYPE_INTEGER,
 		.name    = "Color",
 		.minimum = 0,
-		.maximum = 255,
+		.maximum = 64,
 		.step    = 1,
-#define COLOR_DEF 127
+#define COLOR_DEF 32
 		.default_value = COLOR_DEF,
 	    },
 	    .set = sd_setcolors,
 	    .get = sd_getcolors,
 	},
+#define AUTOGAIN_IDX 3
 	{
 	    {
 		.id      = V4L2_CID_AUTOGAIN,
@@ -131,7 +136,7 @@
 static struct v4l2_pix_format vga_mode[] = {
 	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 		.bytesperline = 160,
-		.sizeimage = 160 * 120 * 3 / 8 + 590,
+		.sizeimage = 160 * 120 * 4 / 8 + 590,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 2},
 	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
@@ -180,6 +185,31 @@
 	0x08,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00
 };
 
+static const __u8 sn_om6802[] = {
+/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
+	0x00,	0x23,	0x72,	0x00,	0x1a,	0x34,	0x27,	0x20,
+/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
+	0x80,	0x34,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
+/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
+	0x03,	0x00,	0x51,	0x01,	0x00,	0x28,	0x1e,	0x40,
+/*	reg18	reg19	reg1a	reg1b	reg1c	reg1d	reg1e	reg1f */
+	0x05,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
+	0x08,	0x22,	0x44,	0x63,	0x7d,	0x92,	0xa3,	0xaf,
+	0xbc,	0xc4,	0xcd,	0xd5,	0xdc,	0xe1,	0xe8,	0xef,
+	0xf7
+};
+
+static const __u8 sn_ov7630[] = {
+/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
+	0x00,	0x21,	0x40,	0x00,	0x1a,	0x20,	0x1f,	0x20,
+/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
+	0xa1,	0x21,	0x76,	0x21,	0x00,	0x00,	0x00,	0x10,
+/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
+	0x03,	0x00,	0x04,	0x01,	0x0a,	0x28,	0x1e,	0xc2,
+/*	reg18	reg19	reg1a	reg1b	reg1c	reg1d	reg1e	reg1f */
+	0x0b,	0x00,	0x00,	0x00,	0x00,	0x00
+};
+
 static const __u8 sn_ov7648[] = {
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
 	0x00,	0x21,	0x62,	0x00,	0x1a,	0x20,	0x20,	0x20,
@@ -207,31 +237,22 @@
 	sn_hv7131,
 	sn_mi0360,
 	sn_mo4000,
+	sn_om6802,
+	sn_ov7630,
 	sn_ov7648,
 	sn_ov7660
 };
 
-static const __u8 regsn20[] = {
+static const __u8 gamma_def[] = {
 	0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
 	0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
 };
-static const __u8 regsn20_sn9c325[] = {
-	0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4,
-	0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5
-};
 
 static const __u8 reg84[] = {
 	0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f,
 	0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f,
-/*	0x00, 0x00, 0x00, 0x00, 0x00 */
-	0xf7, 0x0f, 0x0a, 0x00, 0x00
+	0xf7, 0x0f, 0x00, 0x00, 0x00
 };
-static const __u8 reg84_sn9c325[] = {
-	0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f,
-	0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f,
-	0xf8, 0x0f, 0x00, 0x00, 0x00
-};
-
 static const __u8 hv7131r_sensor_init[][8] = {
 	{0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
 	{0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
@@ -340,6 +361,92 @@
 	{0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
 	{}
 };
+static __u8 om6802_sensor_init[][8] = {
+	{0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
+	{0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
+	{0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
+	{0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
+/*	{0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
+	{0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
+					/* white balance & auto-exposure */
+/*	{0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
+							 * set color mode */
+/*	{0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
+						 * max AGC value in AE */
+/*	{0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
+							 * preset AGC */
+/*	{0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
+						 * preset brightness */
+/*	{0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
+							 * preset contrast */
+/*	{0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
+							 * preset gamma */
+	{0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
+					/* luminance mode (0x4f = AE) */
+	{0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
+							/* preset shutter */
+/*	{0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
+							 * auto frame rate */
+/*	{0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
+
+/*	{0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
+/*	{0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
+/*	{0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
+/*	{0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
+	{}
+};
+static const __u8 ov7630_sensor_init[][8] = {
+	{0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
+/* win: delay 20ms */
+	{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
+/* win: delay 20ms */
+	{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
+/* win: i2c_r from 00 to 80 */
+	{0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
+	{0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
+	{0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
+	{0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
+	{0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
+	{0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
+	{0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
+	{0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
+	{0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
+	{0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
+	{0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
+	{0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
+	{0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
+	{0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
+	{0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
+	{0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
+	{0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
+	{0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
+	{0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
+/* */
+	{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
+/*fixme: + 0x12, 0x04*/
+	{0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
+/* */
+	{0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
+/* */
+	{0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
+/*	{0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
+	{}
+};
 static const __u8 ov7660_sensor_init[][8] = {
 	{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
 /*		(delay 20ms) */
@@ -506,10 +613,16 @@
 	0x29, 0x29, 0x29, 0x29
 };
 
-/* read <len> bytes (len < sizeof gspca_dev->usb_buf) to gspca_dev->usb_buf */
+/* read <len> bytes to gspca_dev->usb_buf */
 static void reg_r(struct gspca_dev *gspca_dev,
 		  __u16 value, int len)
 {
+#ifdef GSPCA_DEBUG
+	if (len > USB_BUF_SZ) {
+		err("reg_r: buffer overflow");
+		return;
+	}
+#endif
 	usb_control_msg(gspca_dev->dev,
 			usb_rcvctrlpipe(gspca_dev->dev, 0),
 			0,
@@ -542,29 +655,20 @@
 {
 	PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
 		value, buffer[0], buffer[1]);
-	if (len <= sizeof gspca_dev->usb_buf) {
-		memcpy(gspca_dev->usb_buf, buffer, len);
-		usb_control_msg(gspca_dev->dev,
-				usb_sndctrlpipe(gspca_dev->dev, 0),
-				0x08,
-			   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
-				value, 0,
-				gspca_dev->usb_buf, len,
-				500);
-	} else {
-		__u8 *tmpbuf;
-
-		tmpbuf = kmalloc(len, GFP_KERNEL);
-		memcpy(tmpbuf, buffer, len);
-		usb_control_msg(gspca_dev->dev,
-				usb_sndctrlpipe(gspca_dev->dev, 0),
-				0x08,
-			   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
-				value, 0,
-				tmpbuf, len,
-				500);
-		kfree(tmpbuf);
+#ifdef GSPCA_DEBUG
+	if (len > USB_BUF_SZ) {
+		err("reg_w: buffer overflow");
+		return;
 	}
+#endif
+	memcpy(gspca_dev->usb_buf, buffer, len);
+	usb_control_msg(gspca_dev->dev,
+			usb_sndctrlpipe(gspca_dev->dev, 0),
+			0x08,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+			value, 0,
+			gspca_dev->usb_buf, len,
+			500);
 }
 
 /* I2C write 1 byte */
@@ -665,7 +769,7 @@
 	static const __u8 regd4[] = {0x60, 0x00, 0x00};
 
 	reg_w1(gspca_dev, 0xf1, 0x00);
-	reg_w1(gspca_dev, 0x01, 0x00);		/*jfm was sn9c1xx[1] in v1*/
+	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
 
 	/* configure gpio */
 	reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
@@ -685,21 +789,41 @@
 
 	reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
 
-	switch (sd->bridge) {
-	case BRIDGE_SN9C325:
+	switch (sd->sensor) {
+	case SENSOR_OM6802:
+		reg_w1(gspca_dev, 0x02, 0x71);
+		reg_w1(gspca_dev, 0x01, 0x42);
+		reg_w1(gspca_dev, 0x17, 0x64);
+		reg_w1(gspca_dev, 0x01, 0x42);
+		break;
+/*jfm: from win trace */
+	case SENSOR_OV7630:
+		reg_w1(gspca_dev, 0x01, 0x61);
+		reg_w1(gspca_dev, 0x17, 0xe2);
+		reg_w1(gspca_dev, 0x01, 0x60);
+		reg_w1(gspca_dev, 0x01, 0x40);
+		break;
+	case SENSOR_OV7648:
 		reg_w1(gspca_dev, 0x01, 0x43);
 		reg_w1(gspca_dev, 0x17, 0xae);
 		reg_w1(gspca_dev, 0x01, 0x42);
 		break;
+/*jfm: from win trace */
+	case SENSOR_OV7660:
+		reg_w1(gspca_dev, 0x01, 0x61);
+		reg_w1(gspca_dev, 0x17, 0x20);
+		reg_w1(gspca_dev, 0x01, 0x60);
+		reg_w1(gspca_dev, 0x01, 0x40);
+		break;
 	default:
 		reg_w1(gspca_dev, 0x01, 0x43);
 		reg_w1(gspca_dev, 0x17, 0x61);
 		reg_w1(gspca_dev, 0x01, 0x42);
-	}
-
-	if (sd->sensor == SENSOR_HV7131R) {
-		if (probesensor(gspca_dev) < 0)
-			return -ENODEV;
+		if (sd->sensor == SENSOR_HV7131R) {
+			if (probesensor(gspca_dev) < 0)
+				return -ENODEV;
+		}
+		break;
 	}
 	return 0;
 }
@@ -737,6 +861,40 @@
 	}
 }
 
+static void om6802_InitSensor(struct gspca_dev *gspca_dev)
+{
+	int i = 0;
+
+	while (om6802_sensor_init[i][0]) {
+		i2c_w8(gspca_dev, om6802_sensor_init[i]);
+		i++;
+	}
+}
+
+static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
+{
+	int i = 0;
+
+	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 76 01 */
+	i++;
+	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 12 c8 (RGB+SRST) */
+	i++;
+	msleep(20);
+	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 12 48 */
+	i++;
+	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 12 c8 */
+	i++;
+	msleep(20);
+	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 12 48 */
+	i++;
+/*jfm:win i2c_r from 00 to 80*/
+
+	while (ov7630_sensor_init[i][0]) {
+		i2c_w8(gspca_dev, ov7630_sensor_init[i]);
+		i++;
+	}
+}
+
 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
 {
 	int i = 0;
@@ -783,11 +941,19 @@
 	sd->autogain = AUTOGAIN_DEF;
 	sd->ag_cnt = -1;
 
+	switch (sd->sensor) {
+	case SENSOR_OV7630:
+	case SENSOR_OV7648:
+	case SENSOR_OV7660:
+		gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
+		break;
+	}
+
 	return 0;
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 /*	const __u8 *sn9c1xx; */
@@ -891,16 +1057,53 @@
 			| ((expoMo10[3] & 0x30) >> 4));
 		break;
 	    }
+	case SENSOR_OM6802: {
+		__u8 gainOm[] =
+			{ 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
+
+		if (expo > 0x03ff)
+			expo = 0x03ff;
+		 if (expo < 0x0001)
+			expo = 0x0001;
+		gainOm[3] = expo >> 2;
+		i2c_w8(gspca_dev, gainOm);
+		reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
+		PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
+		break;
+	    }
 	}
 	return expo;
 }
 
+/* this function is used for sensors o76xx only */
+static void setbrightcont(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	unsigned val;
+	__u8 reg84_full[0x15];
+
+	memset(reg84_full, 0, sizeof reg84_full);
+	val = sd->contrast * 0x20 / CONTRAST_MAX + 0x10;	/* 10..30 */
+	reg84_full[2] = val;
+	reg84_full[0] = (val + 1) / 2;
+	reg84_full[4] = (val + 1) / 5;
+	if (val > BRIGHTNESS_DEF)
+		val = (sd->brightness - BRIGHTNESS_DEF) * 0x20
+			/ BRIGHTNESS_MAX;
+	else
+		val = 0;
+	reg84_full[0x12] = val;			/* 00..1f */
+	reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
+}
+
+/* sensor != ov76xx */
 static void setbrightness(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	unsigned int expo;
 	__u8 k2;
 
+	k2 = sd->brightness >> 10;
 	switch (sd->sensor) {
 	case SENSOR_HV7131R:
 		expo = sd->brightness << 4;
@@ -915,12 +1118,17 @@
 		expo = sd->brightness >> 4;
 		sd->exposure = setexposure(gspca_dev, expo);
 		break;
+	case SENSOR_OM6802:
+		expo = sd->brightness >> 6;
+		sd->exposure = setexposure(gspca_dev, expo);
+		k2 = sd->brightness >> 11;
+		break;
 	}
 
-	k2 = sd->brightness >> 10;
 	reg_w1(gspca_dev, 0x96, k2);
 }
 
+/* sensor != ov76xx */
 static void setcontrast(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -937,31 +1145,30 @@
 static void setcolors(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	__u8 data;
-	int colour;
+	__u8 blue, red;
 
-	colour = sd->colors - 128;
-	if (colour > 0)
-		data = (colour + 32) & 0x7f;	/* blue */
-	else
-		data = (-colour + 32) & 0x7f;	/* red */
-	reg_w1(gspca_dev, 0x05, data);
+	if (sd->colors >= 32) {
+		red = 32 + (sd->colors - 32) / 2;
+		blue = 64 - sd->colors;
+	} else {
+		red = sd->colors;
+		blue = 32 + (32 - sd->colors) / 2;
+	}
+	reg_w1(gspca_dev, 0x05, red);
+/*	reg_w1(gspca_dev, 0x07, 32); */
+	reg_w1(gspca_dev, 0x06, blue);
 }
 
 static void setautogain(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	switch (sd->sensor) {
-	case SENSOR_HV7131R:
-	case SENSOR_MO4000:
-	case SENSOR_MI0360:
-		if (sd->autogain)
-			sd->ag_cnt = AG_CNT_START;
-		else
-			sd->ag_cnt = -1;
-		break;
-	}
+	if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
+		return;
+	if (sd->autogain)
+		sd->ag_cnt = AG_CNT_START;
+	else
+		sd->ag_cnt = -1;
 }
 
 /* -- start the camera -- */
@@ -975,13 +1182,12 @@
 	static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
 	static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
 	static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };	/* MI0360 */
-	static const __u8 CE_sn9c325[] =
-			{ 0x32, 0xdd, 0x32, 0xdd };	/* OV7648 - SN9C325 */
+	static const __u8 CE_ov76xx[] =
+			{ 0x32, 0xdd, 0x32, 0xdd };	/* OV7630/48 */
 
 	sn9c1xx = sn_tb[(int) sd->sensor];
 	configure_gpio(gspca_dev, sn9c1xx);
 
-/*	reg_w1(gspca_dev, 0x01, 0x44);		jfm from win trace*/
 	reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
 	reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
 	reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
@@ -994,10 +1200,17 @@
 	reg_w1(gspca_dev, 0xc8, 0x50);
 	reg_w1(gspca_dev, 0xc9, 0x3c);
 	reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
-	switch (sd->bridge) {
-	case BRIDGE_SN9C325:
+	switch (sd->sensor) {
+	case SENSOR_OV7630:
+		reg17 = 0xe2;
+		break;
+	case SENSOR_OV7648:
 		reg17 = 0xae;
 		break;
+/*jfm: from win trace */
+	case SENSOR_OV7660:
+		reg17 = 0xa0;
+		break;
 	default:
 		reg17 = 0x60;
 		break;
@@ -1007,24 +1220,11 @@
 	reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
 	reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
 	reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
-	switch (sd->bridge) {
-	case BRIDGE_SN9C325:
-		reg_w(gspca_dev, 0x20, regsn20_sn9c325,
-				sizeof regsn20_sn9c325);
-		for (i = 0; i < 8; i++)
-			reg_w(gspca_dev, 0x84, reg84_sn9c325,
-					sizeof reg84_sn9c325);
-		reg_w1(gspca_dev, 0x9a, 0x0a);
-		reg_w1(gspca_dev, 0x99, 0x60);
-		break;
-	default:
-		reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20);
-		for (i = 0; i < 8; i++)
-			reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
+	reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
+	for (i = 0; i < 8; i++)
+		reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
 		reg_w1(gspca_dev, 0x9a, 0x08);
 		reg_w1(gspca_dev, 0x99, 0x59);
-		break;
-	}
 
 	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
 	if (mode)
@@ -1049,6 +1249,15 @@
 /*			reg1 = 0x06;	 * 640 clk 24Mz (done) */
 		}
 		break;
+	case SENSOR_OM6802:
+		om6802_InitSensor(gspca_dev);
+		reg17 = 0x64;		/* 640 MCKSIZE */
+		break;
+	case SENSOR_OV7630:
+		ov7630_InitSensor(gspca_dev);
+		reg17 = 0xe2;
+		reg1 = 0x44;
+		break;
 	case SENSOR_OV7648:
 		ov7648_InitSensor(gspca_dev);
 		reg17 = 0xa2;
@@ -1073,9 +1282,10 @@
 	}
 	reg_w(gspca_dev, 0xc0, C0, 6);
 	reg_w(gspca_dev, 0xca, CA, 4);
-	switch (sd->bridge) {
-	case BRIDGE_SN9C325:
-		reg_w(gspca_dev, 0xce, CE_sn9c325, 4);
+	switch (sd->sensor) {
+	case SENSOR_OV7630:
+	case SENSOR_OV7648:
+		reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
 		break;
 	default:
 		reg_w(gspca_dev, 0xce, CE, 4);
@@ -1093,10 +1303,20 @@
 	reg_w1(gspca_dev, 0x18, reg18);
 
 	reg_w1(gspca_dev, 0x17, reg17);
-	reg_w1(gspca_dev, 0x01, reg1);
-	setbrightness(gspca_dev);
-	setcontrast(gspca_dev);
+	switch (sd->sensor) {
+	case SENSOR_HV7131R:
+	case SENSOR_MI0360:
+	case SENSOR_MO4000:
+	case SENSOR_OM6802:
+		setbrightness(gspca_dev);
+		setcontrast(gspca_dev);
+		break;
+	default:			/* OV76xx */
+		setbrightcont(gspca_dev);
+		break;
+	}
 	setautogain(gspca_dev);
+	reg_w1(gspca_dev, 0x01, reg1);
 }
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -1119,6 +1339,7 @@
 		i2c_w8(gspca_dev, stopmi0360);
 		data = 0x29;
 		break;
+	case SENSOR_OV7630:
 	case SENSOR_OV7648:
 		data = 0x29;
 		break;
@@ -1132,15 +1353,7 @@
 	reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
 	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
 	reg_w1(gspca_dev, 0x01, data);
-	reg_w1(gspca_dev, 0xf1, 0x01);
-}
-
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
-}
-
-static void sd_close(struct gspca_dev *gspca_dev)
-{
+	reg_w1(gspca_dev, 0xf1, 0x00);
 }
 
 static void do_autogain(struct gspca_dev *gspca_dev)
@@ -1174,6 +1387,7 @@
 		default:
 /*		case SENSOR_MO4000: */
 /*		case SENSOR_MI0360: */
+/*		case SENSOR_OM6802: */
 			expotimes = sd->exposure;
 			expotimes += (luma_mean - delta) >> 6;
 			if (expotimes < 0)
@@ -1229,69 +1443,24 @@
 	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
 }
 
-static unsigned int getexposure(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	__u8 hexpo, mexpo, lexpo;
-
-	switch (sd->sensor) {
-	case SENSOR_HV7131R:
-		/* read sensor exposure */
-		i2c_r5(gspca_dev, 0x25);
-		return (gspca_dev->usb_buf[0] << 16)
-			| (gspca_dev->usb_buf[1] << 8)
-			| gspca_dev->usb_buf[2];
-	case SENSOR_MI0360:
-		/* read sensor exposure */
-		i2c_r5(gspca_dev, 0x09);
-		return (gspca_dev->usb_buf[0] << 8)
-			| gspca_dev->usb_buf[1];
-	case SENSOR_MO4000:
-		i2c_r5(gspca_dev, 0x0e);
-		hexpo = 0;		/* gspca_dev->usb_buf[1] & 0x07; */
-		mexpo = 0x40;		/* gspca_dev->usb_buf[2] & 0xff; */
-		lexpo = (gspca_dev->usb_buf[1] & 0x30) >> 4;
-		PDEBUG(D_CONF, "exposure %d",
-			(hexpo << 10) | (mexpo << 2) | lexpo);
-		return (hexpo << 10) | (mexpo << 2) | lexpo;
-	default:
-/*	case SENSOR_OV7648:		* jfm: is it ok for 7648? */
-/*	case SENSOR_OV7660: */
-		/* read sensor exposure */
-		i2c_r5(gspca_dev, 0x04);
-		hexpo = gspca_dev->usb_buf[3] & 0x2f;
-		lexpo = gspca_dev->usb_buf[0] & 0x02;
-		i2c_r5(gspca_dev, 0x08);
-		mexpo = gspca_dev->usb_buf[2];
-		return (hexpo << 10) | (mexpo << 2) | lexpo;
-	}
-}
-
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	/* hardcoded registers seem not readable */
-	switch (sd->sensor) {
-	case SENSOR_HV7131R:
-		sd->brightness = getexposure(gspca_dev) >> 4;
-		break;
-	case SENSOR_MI0360:
-		sd->brightness = getexposure(gspca_dev) << 4;
-		break;
-	case SENSOR_MO4000:
-		sd->brightness = getexposure(gspca_dev) << 4;
-		break;
-	}
-}
-
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	sd->brightness = val;
-	if (gspca_dev->streaming)
-		setbrightness(gspca_dev);
+	if (gspca_dev->streaming) {
+		switch (sd->sensor) {
+		case SENSOR_HV7131R:
+		case SENSOR_MI0360:
+		case SENSOR_MO4000:
+		case SENSOR_OM6802:
+			setbrightness(gspca_dev);
+			break;
+		default:			/* OV76xx */
+			setbrightcont(gspca_dev);
+			break;
+		}
+	}
 	return 0;
 }
 
@@ -1299,7 +1468,6 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	getbrightness(gspca_dev);
 	*val = sd->brightness;
 	return 0;
 }
@@ -1309,8 +1477,19 @@
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	sd->contrast = val;
-	if (gspca_dev->streaming)
-		setcontrast(gspca_dev);
+	if (gspca_dev->streaming) {
+		switch (sd->sensor) {
+		case SENSOR_HV7131R:
+		case SENSOR_MI0360:
+		case SENSOR_MO4000:
+		case SENSOR_OM6802:
+			setcontrast(gspca_dev);
+			break;
+		default:			/* OV76xx */
+			setbrightcont(gspca_dev);
+			break;
+		}
+	}
 	return 0;
 }
 
@@ -1364,11 +1543,9 @@
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
-	.open = sd_open,
+	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
-	.stop0 = sd_stop0,
-	.close = sd_close,
 	.pkt_scan = sd_pkt_scan,
 	.dq_callback = do_autogain,
 };
@@ -1379,7 +1556,7 @@
 			| (SENSOR_ ## sensor << 8) \
 			| (i2c_addr)
 static const __devinitdata struct usb_device_id device_table[] = {
-#ifndef CONFIG_USB_SN9C102
+#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
 	{USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
 	{USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
 	{USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
@@ -1406,15 +1583,17 @@
 /*	{USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
 /*	{USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
 /*	{USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
-	{USB_DEVICE(0x0c45, 0x612a), BSI(SN9C325, OV7648, 0x21)},
-/* bw600.inf:
-	{USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, */
+	{USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
+/*bw600.inf:*/
+	{USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/
 	{USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
-/*	{USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x??)}, */
+	{USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
 /*	{USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
-#ifndef CONFIG_USB_SN9C102
+#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
 	{USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
+#endif
 	{USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
+#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
 /*	{USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
 	{USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
 	{USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
@@ -1438,6 +1617,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index 17fe2c2..6e73390 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -645,8 +645,8 @@
 	return 0;
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
@@ -880,14 +880,6 @@
 		gspca_dev->usb_buf[0]);
 }
 
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
-}
-
-static void sd_close(struct gspca_dev *gspca_dev)
-{
-}
-
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
@@ -1051,11 +1043,9 @@
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
-	.open = sd_open,
+	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
-	.stop0 = sd_stop0,
-	.close = sd_close,
 	.pkt_scan = sd_pkt_scan,
 };
 
@@ -1093,6 +1083,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index 51a3c34..e9eb59b 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -1953,8 +1953,8 @@
 	return -EINVAL;
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
@@ -2023,11 +2023,6 @@
 
 static void sd_stop0(struct gspca_dev *gspca_dev)
 {
-}
-
-/* this function is called at close time */
-static void sd_close(struct gspca_dev *gspca_dev)
-{
 	reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00);
 }
 
@@ -2120,11 +2115,10 @@
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
-	.open = sd_open,
+	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
 	.stop0 = sd_stop0,
-	.close = sd_close,
 	.pkt_scan = sd_pkt_scan,
 };
 
@@ -2154,6 +2148,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index eda29d6..f601daf 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -655,8 +655,8 @@
 	return 0;
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int ret;
@@ -743,11 +743,6 @@
 
 static void sd_stop0(struct gspca_dev *gspca_dev)
 {
-}
-
-/* this function is called at close time */
-static void sd_close(struct gspca_dev *gspca_dev)
-{
 	/* This maybe reset or power control */
 	reg_write(gspca_dev->dev, 0x03, 0x03, 0x20);
 	reg_write(gspca_dev->dev, 0x03, 0x01, 0x0);
@@ -825,11 +820,10 @@
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
-	.open = sd_open,
+	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
 	.stop0 = sd_stop0,
-	.close = sd_close,
 	.pkt_scan = sd_pkt_scan,
 };
 
@@ -855,6 +849,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index f622fa7..195dce9 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -313,8 +313,8 @@
 	return 0;
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
 {
 	struct usb_device *dev = gspca_dev->dev;
 
@@ -560,14 +560,6 @@
 	reg_w(dev, 0x03, 0x00, 0x0003);
 }
 
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
-}
-
-static void sd_close(struct gspca_dev *gspca_dev)
-{
-}
-
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
@@ -740,11 +732,9 @@
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
-	.open = sd_open,
+	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
-	.stop0 = sd_stop0,
-	.close = sd_close,
 	.pkt_scan = sd_pkt_scan,
 };
 
@@ -772,6 +762,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index 699340c..281ce02 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -1521,8 +1521,8 @@
 	return 0;			/* success */
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
 {
 /*	write_vector(gspca_dev, spca508_open_data); */
 	return 0;
@@ -1554,15 +1554,6 @@
 	reg_write(gspca_dev->dev, 0x8112, 0x20);
 }
 
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
-}
-
-/* this function is called at close time */
-static void sd_close(struct gspca_dev *gspca_dev)
-{
-}
-
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
@@ -1633,11 +1624,9 @@
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
-	.open = sd_open,
+	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
-	.stop0 = sd_stop0,
-	.close = sd_close,
 	.pkt_scan = sd_pkt_scan,
 };
 
@@ -1667,6 +1656,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index 1073ac3..cfbc9eb 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -32,69 +32,48 @@
 struct sd {
 	struct gspca_dev gspca_dev;	/* !! must be the first item */
 
-	unsigned short contrast;
-	__u8 brightness;
+	__u16 contrast;			/* rev72a only */
+#define CONTRAST_MIN 0x0000
+#define CONTRAST_DEF 0x2000
+#define CONTRAST_MAX 0x3fff
+
+	__u16 exposure;			/* rev12a only */
+#define EXPOSURE_MIN 1
+#define EXPOSURE_DEF 200
+#define EXPOSURE_MAX (4095 - 900) /* see set_exposure */
+
+	__u8 brightness;		/* rev72a only */
+#define BRIGHTNESS_MIN 0
+#define BRIGHTNESS_DEF 32
+#define BRIGHTNESS_MAX 63
+
+	__u8 white;			/* rev12a only */
+#define WHITE_MIN 1
+#define WHITE_DEF 0x40
+#define WHITE_MAX 0x7f
+
 	__u8 autogain;
+#define AUTOGAIN_MIN 0
+#define AUTOGAIN_DEF 1
+#define AUTOGAIN_MAX 1
+
+	__u8 gain;			/* rev12a only */
+#define GAIN_MIN 0x0
+#define GAIN_DEF 0x24
+#define GAIN_MAX 0x24
+
+#define EXPO12A_DEF 3
+	__u8 expo12a;		/* expo/gain? for rev 12a */
 
 	__u8 chip_revision;
+#define Rev012A 0
+#define Rev072A 1
+
 	signed char ag_cnt;
 #define AG_CNT_START 13
 };
 
-/* V4L2 controls supported by the driver */
-static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
-
-static struct ctrl sd_ctrls[] = {
-#define SD_BRIGHTNESS 0
-	{
-	 {
-	  .id = V4L2_CID_BRIGHTNESS,
-	  .type = V4L2_CTRL_TYPE_INTEGER,
-	  .name = "Brightness",
-	  .minimum = 0,
-	  .maximum = 63,
-	  .step = 1,
-	  .default_value = 32,
-	  },
-	 .set = sd_setbrightness,
-	 .get = sd_getbrightness,
-	 },
-#define SD_CONTRAST 1
-	{
-	 {
-	  .id = V4L2_CID_CONTRAST,
-	  .type = V4L2_CTRL_TYPE_INTEGER,
-	  .name = "Contrast",
-	  .minimum = 0,
-	  .maximum = 0x3fff,
-	  .step = 1,
-	  .default_value = 0x2000,
-	  },
-	 .set = sd_setcontrast,
-	 .get = sd_getcontrast,
-	 },
-#define SD_AUTOGAIN 2
-	{
-	 {
-	  .id = V4L2_CID_AUTOGAIN,
-	  .type = V4L2_CTRL_TYPE_BOOLEAN,
-	  .name = "Auto Gain",
-	  .minimum = 0,
-	  .maximum = 1,
-	  .step = 1,
-	  .default_value = 1,
-	  },
-	 .set = sd_setautogain,
-	 .get = sd_getautogain,
-	 },
-};
-
-static struct v4l2_pix_format sif_mode[] = {
+static struct v4l2_pix_format sif_012a_mode[] = {
 	{160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
 		.bytesperline = 160,
 		.sizeimage = 160 * 120,
@@ -117,6 +96,29 @@
 		.priv = 0},
 };
 
+static struct v4l2_pix_format sif_072a_mode[] = {
+	{160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+		.bytesperline = 160,
+		.sizeimage = 160 * 120,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 3},
+	{176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+		.bytesperline = 176,
+		.sizeimage = 176 * 144,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 2},
+	{320, 240, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 320 * 240,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1},
+	{352, 288, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+		.bytesperline = 352,
+		.sizeimage = 352 * 288,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0},
+};
+
 /*
  * Initialization data
  * I'm not very sure how to split initialization from open data
@@ -143,12 +145,8 @@
 #define SPCA561_INDEX_I2C_BASE 0x8800
 #define SPCA561_SNAPBIT 0x20
 #define SPCA561_SNAPCTRL 0x40
-enum {
-	Rev072A = 0,
-	Rev012A,
-};
 
-static void reg_w_val(struct usb_device *dev, __u16 index, __u16 value)
+static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value)
 {
 	int ret;
 
@@ -198,12 +196,6 @@
 			index, gspca_dev->usb_buf, len, 500);
 }
 
-static void i2c_init(struct gspca_dev *gspca_dev, __u8 mode)
-{
-	reg_w_val(gspca_dev->dev, 0x92, 0x8804);
-	reg_w_val(gspca_dev->dev, mode, 0x8802);
-}
-
 static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg)
 {
 	int retry = 60;
@@ -212,9 +204,9 @@
 
 	DataLow = valeur;
 	DataHight = valeur >> 8;
-	reg_w_val(gspca_dev->dev, reg, 0x8801);
-	reg_w_val(gspca_dev->dev, DataLow, 0x8805);
-	reg_w_val(gspca_dev->dev, DataHight, 0x8800);
+	reg_w_val(gspca_dev->dev, 0x8801, reg);
+	reg_w_val(gspca_dev->dev, 0x8805, DataLow);
+	reg_w_val(gspca_dev->dev, 0x8800, DataHight);
 	while (retry--) {
 		reg_r(gspca_dev, 0x8803, 1);
 		if (!gspca_dev->usb_buf[0])
@@ -228,14 +220,14 @@
 	__u8 value;
 	__u8 vallsb;
 
-	reg_w_val(gspca_dev->dev, 0x92, 0x8804);
-	reg_w_val(gspca_dev->dev, reg, 0x8801);
-	reg_w_val(gspca_dev->dev, (mode | 0x01), 0x8802);
-	while (retry--) {
+	reg_w_val(gspca_dev->dev, 0x8804, 0x92);
+	reg_w_val(gspca_dev->dev, 0x8801, reg);
+	reg_w_val(gspca_dev->dev, 0x8802, (mode | 0x01));
+	do {
 		reg_r(gspca_dev, 0x8803, 1);
 		if (!gspca_dev->usb_buf)
 			break;
-	}
+	} while (--retry);
 	if (retry == 0)
 		return -1;
 	reg_r(gspca_dev, 0x8800, 1);
@@ -438,21 +430,10 @@
 	{0x0035, 0x8801},	/* 0x14 - set gain general */
 	{0x001f, 0x8805},	/* 0x14 */
 	{0x0000, 0x8800},
-	{0x0030, 0x8112},
+	{0x000e, 0x8112},	/* white balance - was 30 */
 	{}
 };
 
-static void sensor_reset(struct gspca_dev *gspca_dev)
-{
-	reg_w_val(gspca_dev->dev, 0x8631, 0xc8);
-	reg_w_val(gspca_dev->dev, 0x8634, 0xc8);
-	reg_w_val(gspca_dev->dev, 0x8112, 0x00);
-	reg_w_val(gspca_dev->dev, 0x8114, 0x00);
-	reg_w_val(gspca_dev->dev, 0x8118, 0x21);
-	i2c_init(gspca_dev, 0x14);
-	i2c_write(gspca_dev, 1, 0x0d);
-	i2c_write(gspca_dev, 0, 0x0d);
-}
 
 /******************** QC Express etch2 stuff ********************/
 static const __u16 Pb100_1map8300[][2] = {
@@ -462,9 +443,9 @@
 	{0x8303, 0x0125},	/* image area */
 	{0x8304, 0x0169},
 	{0x8328, 0x000b},
-	{0x833c, 0x0001},
+	{0x833c, 0x0001},		/*fixme: win:07*/
 
-	{0x832f, 0x0419},
+	{0x832f, 0x1904},		/*fixme: was 0419*/
 	{0x8307, 0x00aa},
 	{0x8301, 0x0003},
 	{0x8302, 0x000e},
@@ -478,9 +459,10 @@
 };
 
 static const __u16 spca561_161rev12A_data1[][2] = {
-	{0x21, 0x8118},
-	{0x01, 0x8114},
-	{0x00, 0x8112},
+	{0x29, 0x8118},		/* white balance - was 21 */
+	{0x08, 0x8114},		/* white balance - was 01 */
+	{0x0e, 0x8112},		/* white balance - was 00 */
+	{0x00, 0x8102},		/* white balance - new */
 	{0x92, 0x8804},
 	{0x04, 0x8802},		/* windows uses 08 */
 	{}
@@ -505,14 +487,16 @@
 	{0xb0, 0x8603},
 
 	/* sensor gains */
+	{0x07, 0x8601},		/* white balance - new */
+	{0x07, 0x8602},		/* white balance - new */
 	{0x00, 0x8610},		/* *red */
 	{0x00, 0x8611},		/* 3f   *green */
 	{0x00, 0x8612},		/* green *blue */
 	{0x00, 0x8613},		/* blue *green */
-	{0x35, 0x8614},		/* green *red */
-	{0x35, 0x8615},		/* 40   *green */
-	{0x35, 0x8616},		/* 7a   *blue */
-	{0x35, 0x8617},		/* 40   *green */
+	{0x43, 0x8614},		/* green *red - white balance - was 0x35 */
+	{0x40, 0x8615},		/* 40   *green - white balance - was 0x35 */
+	{0x71, 0x8616},		/* 7a   *blue - white balance - was 0x35 */
+	{0x40, 0x8617},		/* 40   *green - white balance - was 0x35 */
 
 	{0x0c, 0x8620},		/* 0c */
 	{0xc8, 0x8631},		/* c8 */
@@ -527,6 +511,7 @@
 	{0xdf, 0x863c},		/* df */
 	{0xf0, 0x8505},
 	{0x32, 0x850a},
+/*	{0x99, 0x8700},		 * - white balance - new (removed) */
 	{}
 };
 
@@ -545,9 +530,10 @@
 }
 static void init_161rev12A(struct gspca_dev *gspca_dev)
 {
-	sensor_reset(gspca_dev);
+/*	sensor_reset(gspca_dev);	(not in win) */
 	write_vector(gspca_dev, spca561_161rev12A_data1);
 	sensor_mapwrite(gspca_dev, Pb100_1map8300);
+/*fixme: should be in sd_start*/
 	write_vector(gspca_dev, spca561_161rev12A_data2);
 	sensor_mapwrite(gspca_dev, Pb100_2map8300);
 }
@@ -581,35 +567,38 @@
 	}
 
 	cam = &gspca_dev->cam;
-	cam->dev_name = (char *) id->driver_info;
 	cam->epaddr = 0x01;
 	gspca_dev->nbalt = 7 + 1;	/* choose alternate 7 first */
-	cam->cam_mode = sif_mode;
-	cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
 
 	sd->chip_revision = id->driver_info;
-	sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
-	sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
-	sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value;
+	if (sd->chip_revision == Rev012A) {
+		cam->cam_mode = sif_012a_mode;
+		cam->nmodes = ARRAY_SIZE(sif_012a_mode);
+	} else {
+		cam->cam_mode = sif_072a_mode;
+		cam->nmodes = ARRAY_SIZE(sif_072a_mode);
+	}
+	sd->brightness = BRIGHTNESS_DEF;
+	sd->contrast = CONTRAST_DEF;
+	sd->white = WHITE_DEF;
+	sd->exposure = EXPOSURE_DEF;
+	sd->autogain = AUTOGAIN_DEF;
+	sd->gain = GAIN_DEF;
+	sd->expo12a = EXPO12A_DEF;
 	return 0;
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
+/* this function is called at probe and resume time */
+static int sd_init_12a(struct gspca_dev *gspca_dev)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	switch (sd->chip_revision) {
-	case Rev072A:
-		PDEBUG(D_STREAM, "Chip revision id: 072a");
-		write_vector(gspca_dev, spca561_init_data);
-		break;
-	default:
-/*	case Rev012A: */
-		PDEBUG(D_STREAM, "Chip revision id: 012a");
-		init_161rev12A(gspca_dev);
-		break;
-	}
+	PDEBUG(D_STREAM, "Chip revision: 012a");
+	init_161rev12A(gspca_dev);
+	return 0;
+}
+static int sd_init_72a(struct gspca_dev *gspca_dev)
+{
+	PDEBUG(D_STREAM, "Chip revision: 072a");
+	write_vector(gspca_dev, spca561_init_data);
 	return 0;
 }
 
@@ -618,25 +607,20 @@
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct usb_device *dev = gspca_dev->dev;
 	__u8 lowb;
-	int expotimes;
 
 	switch (sd->chip_revision) {
 	case Rev072A:
 		lowb = sd->contrast >> 8;
-		reg_w_val(dev, lowb, 0x8651);
-		reg_w_val(dev, lowb, 0x8652);
-		reg_w_val(dev, lowb, 0x8653);
-		reg_w_val(dev, lowb, 0x8654);
+		reg_w_val(dev, 0x8651, lowb);
+		reg_w_val(dev, 0x8652, lowb);
+		reg_w_val(dev, 0x8653, lowb);
+		reg_w_val(dev, 0x8654, lowb);
 		break;
-	case Rev012A: {
-		__u8 Reg8391[] =
-			{ 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00 };
+	default: {
+/*	case Rev012A: { */
+		static const __u8 Reg8391[] =
+			{ 0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00 };
 
-		/* Write camera sensor settings */
-		expotimes = (sd->contrast >> 5) & 0x07ff;
-		Reg8391[0] = expotimes & 0xff;	/* exposure */
-		Reg8391[1] = 0x18 | (expotimes >> 8);
-		Reg8391[2] = sd->brightness;	/* gain */
 		reg_w_buf(gspca_dev, 0x8391, Reg8391, 8);
 		reg_w_buf(gspca_dev, 0x8390, Reg8391, 8);
 		break;
@@ -644,93 +628,151 @@
 	}
 }
 
+/* rev12a only */
+static void setwhite(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	__u16 white;
+	__u8 reg8614, reg8616;
+
+	white = sd->white;
+	/* try to emulate MS-win as possible */
+	reg8616 = 0x90 - white * 5 / 8;
+	reg_w_val(gspca_dev->dev, 0x8616, reg8616);
+	reg8614 = 0x20 + white * 3 / 8;
+	reg_w_val(gspca_dev->dev, 0x8614, reg8614);
+}
+
+/* rev 12a only */
+static void setexposure(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int expo;
+	int clock_divider;
+	__u8 data[2];
+
+	/* Register 0x8309 controls exposure for the spca561,
+	   the basic exposure setting goes from 1-2047, where 1 is completely
+	   dark and 2047 is very bright. It not only influences exposure but
+	   also the framerate (to allow for longer exposure) from 1 - 300 it
+	   only raises the exposure time then from 300 - 600 it halves the
+	   framerate to be able to further raise the exposure time and for every
+	   300 more it halves the framerate again. This allows for a maximum
+	   exposure time of circa 0.2 - 0.25 seconds (30 / (2000/3000) fps).
+	   Sometimes this is not enough, the 1-2047 uses bits 0-10, bits 11-12
+	   configure a divider for the base framerate which us used at the
+	   exposure setting of 1-300. These bits configure the base framerate
+	   according to the following formula: fps = 60 / (value + 2) */
+	if (sd->exposure < 2048) {
+		expo = sd->exposure;
+		clock_divider = 0;
+	} else {
+		/* Add 900 to make the 0 setting of the second part of the
+		   exposure equal to the 2047 setting of the first part. */
+		expo = (sd->exposure - 2048) + 900;
+		clock_divider = 3;
+	}
+	expo |= clock_divider << 11;
+	data[0] = expo;
+	data[1] = expo >> 8;
+	reg_w_buf(gspca_dev, 0x8309, data, 2);
+}
+
+/* rev 12a only */
+static void setgain(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	__u8 data[2];
+
+	data[0] = sd->gain;
+	data[1] = 0;
+	reg_w_buf(gspca_dev, 0x8335, data, 2);
+}
+
 static void setautogain(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	if (sd->chip_revision == Rev072A) {
-		if (sd->autogain)
-			sd->ag_cnt = AG_CNT_START;
-		else
-			sd->ag_cnt = -1;
-	}
+	if (sd->autogain)
+		sd->ag_cnt = AG_CNT_START;
+	else
+		sd->ag_cnt = -1;
 }
 
-static void sd_start(struct gspca_dev *gspca_dev)
+static void sd_start_12a(struct gspca_dev *gspca_dev)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
 	struct usb_device *dev = gspca_dev->dev;
-	int Clck;
+	int Clck = 0x8a; /* lower 0x8X values lead to fps > 30 */
 	__u8 Reg8307[] = { 0xaa, 0x00 };
 	int mode;
 
 	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
-	switch (sd->chip_revision) {
-	case Rev072A:
-		switch (mode) {
-		default:
-/*		case 0:
-		case 1: */
-			Clck = 0x25;
-			break;
-		case 2:
-			Clck = 0x22;
-			break;
-		case 3:
-			Clck = 0x21;
-			break;
-		}
-		reg_w_val(dev, 0x8500, mode);	/* mode */
-		reg_w_val(dev, 0x8700, Clck);	/* 0x27 clock */
-		reg_w_val(dev, 0x8112, 0x10 | 0x20);
-		setautogain(gspca_dev);
-		break;
+	if (mode <= 1) {
+		/* Use compression on 320x240 and above */
+		reg_w_val(dev, 0x8500, 0x10 | mode);
+	} else {
+		/* I couldn't get the compression to work below 320x240
+		 * Fortunately at these resolutions the bandwidth
+		 * is sufficient to push raw frames at ~20fps */
+		reg_w_val(dev, 0x8500, mode);
+	}		/* -- qq@kuku.eu.org */
+	reg_w_buf(gspca_dev, 0x8307, Reg8307, 2);
+	reg_w_val(gspca_dev->dev, 0x8700, Clck);
+					/* 0x8f 0x85 0x27 clock */
+	reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
+	reg_w_val(gspca_dev->dev, 0x850b, 0x03);
+	setcontrast(gspca_dev);
+	setwhite(gspca_dev);
+	setautogain(gspca_dev);
+	setexposure(gspca_dev);
+}
+static void sd_start_72a(struct gspca_dev *gspca_dev)
+{
+	struct usb_device *dev = gspca_dev->dev;
+	int Clck;
+	int mode;
+
+	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+	switch (mode) {
 	default:
-/*	case Rev012A: */
-		switch (mode) {
-		case 0:
-		case 1:
-			Clck = 0x8a;
-			break;
-		case 2:
-			Clck = 0x85;
-			break;
-		default:
-			Clck = 0x83;
-			break;
-		}
-		if (mode <= 1) {
-			/* Use compression on 320x240 and above */
-			reg_w_val(dev, 0x8500, 0x10 | mode);
-		} else {
-			/* I couldn't get the compression to work below 320x240
-			 * Fortunately at these resolutions the bandwidth
-			 * is sufficient to push raw frames at ~20fps */
-			reg_w_val(dev, 0x8500, mode);
-		}		/* -- qq@kuku.eu.org */
-		reg_w_buf(gspca_dev, 0x8307, Reg8307, 2);
-		reg_w_val(gspca_dev->dev, 0x8700, Clck);
-						/* 0x8f 0x85 0x27 clock */
-		reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
-		reg_w_val(gspca_dev->dev, 0x850b, 0x03);
-		setcontrast(gspca_dev);
+/*	case 0:
+	case 1: */
+		Clck = 0x25;
+		break;
+	case 2:
+		Clck = 0x22;
+		break;
+	case 3:
+		Clck = 0x21;
 		break;
 	}
+	reg_w_val(dev, 0x8500, mode);	/* mode */
+	reg_w_val(dev, 0x8700, Clck);	/* 0x27 clock */
+	reg_w_val(dev, 0x8112, 0x10 | 0x20);
+	setautogain(gspca_dev);
 }
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
 {
-	reg_w_val(gspca_dev->dev, 0x8112, 0x20);
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->chip_revision == Rev012A) {
+		reg_w_val(gspca_dev->dev, 0x8112, 0x0e);
+	} else {
+		reg_w_val(gspca_dev->dev, 0x8112, 0x20);
+/*		reg_w_val(gspca_dev->dev, 0x8102, 0x00); ?? */
+	}
 }
 
 static void sd_stop0(struct gspca_dev *gspca_dev)
 {
-}
+	struct sd *sd = (struct sd *) gspca_dev;
 
-/* this function is called at close time */
-static void sd_close(struct gspca_dev *gspca_dev)
-{
-	reg_w_val(gspca_dev->dev, 0x8114, 0);
+	if (sd->chip_revision == Rev012A) {
+		reg_w_val(gspca_dev->dev, 0x8118, 0x29);
+		reg_w_val(gspca_dev->dev, 0x8114, 0x08);
+	}
+/*	reg_w_val(gspca_dev->dev, 0x8114, 0); */
 }
 
 static void do_autogain(struct gspca_dev *gspca_dev)
@@ -744,6 +786,7 @@
 	__u8 luma_mean = 110;
 	__u8 luma_delta = 20;
 	__u8 spring = 4;
+	__u8 reg8339[2];
 
 	if (sd->ag_cnt < 0)
 		return;
@@ -798,13 +841,16 @@
 		}
 		break;
 	case Rev012A:
-		/* sensor registers is access and memory mapped to 0x8300 */
-		/* readind all 0x83xx block the sensor */
-		/*
-		 * The data from the header seem wrong where is the luma
-		 * and chroma mean value
-		 * at the moment set exposure in contrast set
-		 */
+		reg_r(gspca_dev, 0x8330, 2);
+		if (gspca_dev->usb_buf[1] > 0x08) {
+			reg8339[0] = ++sd->expo12a;
+			reg8339[1] = 0;
+			reg_w_buf(gspca_dev, 0x8339, reg8339, 2);
+		} else if (gspca_dev->usb_buf[1] < 0x02) {
+			reg8339[0] = --sd->expo12a;
+			reg8339[1] = 0;
+			reg_w_buf(gspca_dev, 0x8339, reg8339, 2);
+		}
 		break;
 	}
 }
@@ -814,6 +860,8 @@
 			__u8 *data,		/* isoc packet */
 			int len)		/* iso packet length */
 {
+	struct sd *sd = (struct sd *) gspca_dev;
+
 	switch (data[0]) {
 	case 0:		/* start of frame */
 		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
@@ -826,8 +874,13 @@
 					frame, data, len);
 		} else {
 			/* raw bayer (with a header, which we skip) */
-			data += 20;
-			len -= 20;
+			if (sd->chip_revision == Rev012A) {
+				data += 20;
+				len -= 20;
+			} else {
+				data += 16;
+				len -= 16;
+			}
 			gspca_frame_add(gspca_dev, FIRST_PACKET,
 						frame, data, len);
 		}
@@ -841,24 +894,17 @@
 	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
 }
 
+/* rev 72a only */
 static void setbrightness(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	__u8 value;
 
-	switch (sd->chip_revision) {
-	case Rev072A:
-		value = sd->brightness;
-		reg_w_val(gspca_dev->dev, value, 0x8611);
-		reg_w_val(gspca_dev->dev, value, 0x8612);
-		reg_w_val(gspca_dev->dev, value, 0x8613);
-		reg_w_val(gspca_dev->dev, value, 0x8614);
-		break;
-	default:
-/*	case Rev012A: */
-		setcontrast(gspca_dev);
-		break;
-	}
+	value = sd->brightness;
+	reg_w_val(gspca_dev->dev, 0x8611, value);
+	reg_w_val(gspca_dev->dev, 0x8612, value);
+	reg_w_val(gspca_dev->dev, 0x8613, value);
+	reg_w_val(gspca_dev->dev, 0x8614, value);
 }
 
 static void getbrightness(struct gspca_dev *gspca_dev)
@@ -866,52 +912,38 @@
 	struct sd *sd = (struct sd *) gspca_dev;
 	__u16 tot;
 
-	switch (sd->chip_revision) {
-	case Rev072A:
-		tot = 0;
-		reg_r(gspca_dev, 0x8611, 1);
-		tot += gspca_dev->usb_buf[0];
-		reg_r(gspca_dev, 0x8612, 1);
-		tot += gspca_dev->usb_buf[0];
-		reg_r(gspca_dev, 0x8613, 1);
-		tot += gspca_dev->usb_buf[0];
-		reg_r(gspca_dev, 0x8614, 1);
-		tot += gspca_dev->usb_buf[0];
-		sd->brightness = tot >> 2;
-		break;
-	default:
-/*	case Rev012A: */
-		/* no way to read sensor settings */
-		break;
-	}
+	tot = 0;
+	reg_r(gspca_dev, 0x8611, 1);
+	tot += gspca_dev->usb_buf[0];
+	reg_r(gspca_dev, 0x8612, 1);
+	tot += gspca_dev->usb_buf[0];
+	reg_r(gspca_dev, 0x8613, 1);
+	tot += gspca_dev->usb_buf[0];
+	reg_r(gspca_dev, 0x8614, 1);
+	tot += gspca_dev->usb_buf[0];
+	sd->brightness = tot >> 2;
 }
 
+/* rev72a only */
 static void getcontrast(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	__u16 tot;
 
-	switch (sd->chip_revision) {
-	case Rev072A:
-		tot = 0;
-		reg_r(gspca_dev, 0x8651, 1);
-		tot += gspca_dev->usb_buf[0];
-		reg_r(gspca_dev, 0x8652, 1);
-		tot += gspca_dev->usb_buf[0];
-		reg_r(gspca_dev, 0x8653, 1);
-		tot += gspca_dev->usb_buf[0];
-		reg_r(gspca_dev, 0x8654, 1);
-		tot += gspca_dev->usb_buf[0];
-		sd->contrast = tot << 6;
-		break;
-	default:
-/*	case Rev012A: */
-		/* no way to read sensor settings */
-		break;
-	}
+	tot = 0;
+	reg_r(gspca_dev, 0x8651, 1);
+	tot += gspca_dev->usb_buf[0];
+	reg_r(gspca_dev, 0x8652, 1);
+	tot += gspca_dev->usb_buf[0];
+	reg_r(gspca_dev, 0x8653, 1);
+	tot += gspca_dev->usb_buf[0];
+	reg_r(gspca_dev, 0x8654, 1);
+	tot += gspca_dev->usb_buf[0];
+	sd->contrast = tot << 6;
 	PDEBUG(D_CONF, "get contrast %d", sd->contrast);
 }
 
+/* rev 72a only */
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -931,6 +963,7 @@
 	return 0;
 }
 
+/* rev 72a only */
 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -968,20 +1001,190 @@
 	return 0;
 }
 
+/* rev12a only */
+static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->white = val;
+	if (gspca_dev->streaming)
+		setwhite(gspca_dev);
+	return 0;
+}
+
+static int sd_getwhite(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->white;
+	return 0;
+}
+
+/* rev12a only */
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->exposure = val;
+	if (gspca_dev->streaming)
+		setexposure(gspca_dev);
+	return 0;
+}
+
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->exposure;
+	return 0;
+}
+
+/* rev12a only */
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->gain = val;
+	if (gspca_dev->streaming)
+		setgain(gspca_dev);
+	return 0;
+}
+
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->gain;
+	return 0;
+}
+
+/* control tables */
+static struct ctrl sd_ctrls_12a[] = {
+	{
+	    {
+		.id = V4L2_CID_DO_WHITE_BALANCE,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "While Balance",
+		.minimum = WHITE_MIN,
+		.maximum = WHITE_MAX,
+		.step = 1,
+		.default_value = WHITE_DEF,
+	    },
+	    .set = sd_setwhite,
+	    .get = sd_getwhite,
+	},
+	{
+	    {
+		.id = V4L2_CID_EXPOSURE,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Exposure",
+		.minimum = EXPOSURE_MIN,
+		.maximum = EXPOSURE_MAX,
+		.step = 1,
+		.default_value = EXPOSURE_DEF,
+	    },
+	    .set = sd_setexposure,
+	    .get = sd_getexposure,
+	},
+	{
+	    {
+		.id = V4L2_CID_AUTOGAIN,
+		.type = V4L2_CTRL_TYPE_BOOLEAN,
+		.name = "Auto Gain",
+		.minimum = AUTOGAIN_MIN,
+		.maximum = AUTOGAIN_MAX,
+		.step = 1,
+		.default_value = AUTOGAIN_DEF,
+	    },
+	    .set = sd_setautogain,
+	    .get = sd_getautogain,
+	},
+	{
+	    {
+		.id = V4L2_CID_GAIN,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Gain",
+		.minimum = GAIN_MIN,
+		.maximum = GAIN_MAX,
+		.step = 1,
+		.default_value = GAIN_DEF,
+	    },
+	    .set = sd_setgain,
+	    .get = sd_getgain,
+	},
+};
+
+static struct ctrl sd_ctrls_72a[] = {
+	{
+	   {
+		.id = V4L2_CID_BRIGHTNESS,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Brightness",
+		.minimum = BRIGHTNESS_MIN,
+		.maximum = BRIGHTNESS_MAX,
+		.step = 1,
+		.default_value = BRIGHTNESS_DEF,
+	    },
+	    .set = sd_setbrightness,
+	    .get = sd_getbrightness,
+	},
+	{
+	    {
+		.id = V4L2_CID_CONTRAST,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Contrast",
+		.minimum = CONTRAST_MIN,
+		.maximum = CONTRAST_MAX,
+		.step = 1,
+		.default_value = CONTRAST_DEF,
+	    },
+	    .set = sd_setcontrast,
+	    .get = sd_getcontrast,
+	},
+	{
+	    {
+		.id = V4L2_CID_AUTOGAIN,
+		.type = V4L2_CTRL_TYPE_BOOLEAN,
+		.name = "Auto Gain",
+		.minimum = AUTOGAIN_MIN,
+		.maximum = AUTOGAIN_MAX,
+		.step = 1,
+		.default_value = AUTOGAIN_DEF,
+	    },
+	    .set = sd_setautogain,
+	    .get = sd_getautogain,
+	},
+};
+
 /* sub-driver description */
-static const struct sd_desc sd_desc = {
+static const struct sd_desc sd_desc_12a = {
 	.name = MODULE_NAME,
-	.ctrls = sd_ctrls,
-	.nctrls = ARRAY_SIZE(sd_ctrls),
+	.ctrls = sd_ctrls_12a,
+	.nctrls = ARRAY_SIZE(sd_ctrls_12a),
 	.config = sd_config,
-	.open = sd_open,
-	.start = sd_start,
+	.init = sd_init_12a,
+	.start = sd_start_12a,
 	.stopN = sd_stopN,
 	.stop0 = sd_stop0,
-	.close = sd_close,
+	.pkt_scan = sd_pkt_scan,
+/*	.dq_callback = do_autogain,	 * fixme */
+};
+static const struct sd_desc sd_desc_72a = {
+	.name = MODULE_NAME,
+	.ctrls = sd_ctrls_72a,
+	.nctrls = ARRAY_SIZE(sd_ctrls_72a),
+	.config = sd_config,
+	.init = sd_init_72a,
+	.start = sd_start_72a,
+	.stopN = sd_stopN,
+	.stop0 = sd_stop0,
 	.pkt_scan = sd_pkt_scan,
 	.dq_callback = do_autogain,
 };
+static const struct sd_desc *sd_desc[2] = {
+	&sd_desc_12a,
+	&sd_desc_72a
+};
 
 /* -- module initialisation -- */
 static const __devinitdata struct usb_device_id device_table[] = {
@@ -1009,7 +1212,9 @@
 static int sd_probe(struct usb_interface *intf,
 		    const struct usb_device_id *id)
 {
-	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+	return gspca_dev_probe(intf, id,
+				sd_desc[id->driver_info],
+				sizeof(struct sd),
 			       THIS_MODULE);
 }
 
@@ -1018,6 +1223,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index 16219cf..2f2de42 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -306,8 +306,8 @@
 	return 0;
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
 {
 	int ret;
 
@@ -398,14 +398,6 @@
 	PDEBUG(D_STREAM, "camera stopped");
 }
 
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
-}
-
-static void sd_close(struct gspca_dev *gspca_dev)
-{
-}
-
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
@@ -535,11 +527,9 @@
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
-	.open = sd_open,
+	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
-	.stop0 = sd_stop0,
-	.close = sd_close,
 	.pkt_scan = sd_pkt_scan,
 	.querymenu = sd_querymenu,
 };
@@ -564,6 +554,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index 54efa48..1cfcc6c 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -449,31 +449,47 @@
 	 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
 };
 
-static void reg_r(struct usb_device *dev,
-			   __u16 req,
-			   __u16 index,
-			   __u8 *buffer, __u16 length)
+/* read <len> bytes to gspca_dev->usb_buf */
+static void reg_r(struct gspca_dev *gspca_dev,
+		  __u16 req,
+		  __u16 index,
+		  __u16 len)
 {
-	usb_control_msg(dev,
-			usb_rcvctrlpipe(dev, 0),
+#ifdef GSPCA_DEBUG
+	if (len > USB_BUF_SZ) {
+		err("reg_r: buffer overflow");
+		return;
+	}
+#endif
+	usb_control_msg(gspca_dev->dev,
+			usb_rcvctrlpipe(gspca_dev->dev, 0),
 			req,
 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			0,		/* value */
-			index, buffer, length,
+			index,
+			len ? gspca_dev->usb_buf : NULL, len,
 			500);
 }
 
-static void reg_w(struct usb_device *dev,
-			    __u16 req,
-			    __u16 value,
-			    __u16 index,
-			    __u8 *buffer, __u16 length)
+/* write <len> bytes from gspca_dev->usb_buf */
+static void reg_w(struct gspca_dev *gspca_dev,
+		   __u16 req,
+		   __u16 value,
+		   __u16 index,
+		   __u16 len)
 {
-	usb_control_msg(dev,
-			usb_sndctrlpipe(dev, 0),
+#ifdef GSPCA_DEBUG
+	if (len > USB_BUF_SZ) {
+		err("reg_w: buffer overflow");
+		return;
+	}
+#endif
+	usb_control_msg(gspca_dev->dev,
+			usb_sndctrlpipe(gspca_dev->dev, 0),
 			req,
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-			value, index, buffer, length,
+			value, index,
+			len ? gspca_dev->usb_buf : NULL, len,
 			500);
 }
 
@@ -634,7 +650,7 @@
 	int count = 10;
 
 	while (--count > 0) {
-		reg_r(gspca_dev->dev, 0x21, 0, gspca_dev->usb_buf, 1);
+		reg_r(gspca_dev, 0x21, 0, 1);
 		if ((gspca_dev->usb_buf[0] & 0x01) == 0)
 			break;
 		msleep(10);
@@ -644,15 +660,14 @@
 
 static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
 {
-	struct usb_device *dev = gspca_dev->dev;
 	int count = 50;
 
 	while (--count > 0) {
-		reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1);
+		reg_r(gspca_dev, 0x21, 1, 1);
 		if (gspca_dev->usb_buf[0] != 0) {
 			gspca_dev->usb_buf[0] = 0;
-			reg_w(dev, 0x21, 0, 1, gspca_dev->usb_buf, 1);
-			reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1);
+			reg_w(gspca_dev, 0x21, 0, 1, 1);
+			reg_r(gspca_dev, 0x21, 1, 1);
 			spca504B_PollingDataReady(gspca_dev);
 			break;
 		}
@@ -662,16 +677,14 @@
 
 static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
 {
-	struct usb_device *dev = gspca_dev->dev;
 	__u8 *data;
 
-	data = kmalloc(64, GFP_KERNEL);
-	reg_r(dev, 0x20, 0, data, 5);
+	data = gspca_dev->usb_buf;
+	reg_r(gspca_dev, 0x20, 0, 5);
 	PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ",
 		data[0], data[1], data[2], data[3], data[4]);
-	reg_r(dev, 0x23, 0, data, 64);
-	reg_r(dev, 0x23, 1, data, 64);
-	kfree(data);
+	reg_r(gspca_dev, 0x23, 0, 64);
+	reg_r(gspca_dev, 0x23, 1, 64);
 }
 
 static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
@@ -686,21 +699,21 @@
 	Type = 0;
 	switch (sd->bridge) {
 	case BRIDGE_SPCA533:
-		reg_w(dev, 0x31, 0, 0, NULL, 0);
+		reg_w(gspca_dev, 0x31, 0, 0, 0);
 		spca504B_WaitCmdStatus(gspca_dev);
 		rc = spca504B_PollingDataReady(gspca_dev);
 		spca50x_GetFirmware(gspca_dev);
 		gspca_dev->usb_buf[0] = 2;			/* type */
-		reg_w(dev, 0x24, 0, 8, gspca_dev->usb_buf, 1);
-		reg_r(dev, 0x24, 8, gspca_dev->usb_buf, 1);
+		reg_w(gspca_dev, 0x24, 0, 8, 1);
+		reg_r(gspca_dev, 0x24, 8, 1);
 
 		gspca_dev->usb_buf[0] = Size;
-		reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1);
-		reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1);	/* size */
+		reg_w(gspca_dev, 0x25, 0, 4, 1);
+		reg_r(gspca_dev, 0x25, 4, 1);			/* size */
 		rc = spca504B_PollingDataReady(gspca_dev);
 
 		/* Init the cam width height with some values get on init ? */
-		reg_w(dev, 0x31, 0, 4, NULL, 0);
+		reg_w(gspca_dev, 0x31, 0, 4, 0);
 		spca504B_WaitCmdStatus(gspca_dev);
 		rc = spca504B_PollingDataReady(gspca_dev);
 		break;
@@ -708,12 +721,12 @@
 /* case BRIDGE_SPCA504B: */
 /* case BRIDGE_SPCA536: */
 		gspca_dev->usb_buf[0] = Size;
-		reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1);
-		reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1);	/* size */
+		reg_w(gspca_dev, 0x25, 0, 4, 1);
+		reg_r(gspca_dev, 0x25, 4, 1);			/* size */
 		Type = 6;
 		gspca_dev->usb_buf[0] = Type;
-		reg_w(dev, 0x27, 0, 0, gspca_dev->usb_buf, 1);
-		reg_r(dev, 0x27, 0, gspca_dev->usb_buf, 1);	/* type */
+		reg_w(gspca_dev, 0x27, 0, 0, 1);
+		reg_r(gspca_dev, 0x27, 0, 1);			/* type */
 		rc = spca504B_PollingDataReady(gspca_dev);
 		break;
 	case BRIDGE_SPCA504:
@@ -752,18 +765,15 @@
 
 static void spca504B_setQtable(struct gspca_dev *gspca_dev)
 {
-	struct usb_device *dev = gspca_dev->dev;
-
 	gspca_dev->usb_buf[0] = 3;
-	reg_w(dev, 0x26, 0, 0, gspca_dev->usb_buf, 1);
-	reg_r(dev, 0x26, 0, gspca_dev->usb_buf, 1);
+	reg_w(gspca_dev, 0x26, 0, 0, 1);
+	reg_r(gspca_dev, 0x26, 0, 1);
 	spca504B_PollingDataReady(gspca_dev);
 }
 
 static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	struct usb_device *dev = gspca_dev->dev;
 	int pollreg = 1;
 
 	switch (sd->bridge) {
@@ -774,20 +784,20 @@
 	default:
 /*	case BRIDGE_SPCA533: */
 /*	case BRIDGE_SPCA504B: */
-		reg_w(dev, 0, 0, 0x21a7, NULL, 0);	/* brightness */
-		reg_w(dev, 0, 0x20, 0x21a8, NULL, 0);	/* contrast */
-		reg_w(dev, 0, 0, 0x21ad, NULL, 0);	/* hue */
-		reg_w(dev, 0, 1, 0x21ac, NULL, 0);	/* sat/hue */
-		reg_w(dev, 0, 0x20, 0x21ae, NULL, 0);	/* saturation */
-		reg_w(dev, 0, 0, 0x21a3, NULL, 0);	/* gamma */
+		reg_w(gspca_dev, 0, 0, 0x21a7, 0);	/* brightness */
+		reg_w(gspca_dev, 0, 0x20, 0x21a8, 0);	/* contrast */
+		reg_w(gspca_dev, 0, 0, 0x21ad, 0);	/* hue */
+		reg_w(gspca_dev, 0, 1, 0x21ac, 0);	/* sat/hue */
+		reg_w(gspca_dev, 0, 0x20, 0x21ae, 0);	/* saturation */
+		reg_w(gspca_dev, 0, 0, 0x21a3, 0);	/* gamma */
 		break;
 	case BRIDGE_SPCA536:
-		reg_w(dev, 0, 0, 0x20f0, NULL, 0);
-		reg_w(dev, 0, 0x21, 0x20f1, NULL, 0);
-		reg_w(dev, 0, 0x40, 0x20f5, NULL, 0);
-		reg_w(dev, 0, 1, 0x20f4, NULL, 0);
-		reg_w(dev, 0, 0x40, 0x20f6, NULL, 0);
-		reg_w(dev, 0, 0, 0x2089, NULL, 0);
+		reg_w(gspca_dev, 0, 0, 0x20f0, 0);
+		reg_w(gspca_dev, 0, 0x21, 0x20f1, 0);
+		reg_w(gspca_dev, 0, 0x40, 0x20f5, 0);
+		reg_w(gspca_dev, 0, 1, 0x20f4, 0);
+		reg_w(gspca_dev, 0, 0x40, 0x20f6, 0);
+		reg_w(gspca_dev, 0, 0, 0x2089, 0);
 		break;
 	}
 	if (pollreg)
@@ -799,7 +809,6 @@
 			const struct usb_device_id *id)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	struct usb_device *dev = gspca_dev->dev;
 	struct cam *cam;
 
 	cam = &gspca_dev->cam;
@@ -811,7 +820,7 @@
 	if (sd->subtype == AiptekMiniPenCam13) {
 /* try to get the firmware as some cam answer 2.0.1.2.2
  * and should be a spca504b then overwrite that setting */
-		reg_r(dev, 0x20, 0, gspca_dev->usb_buf, 1);
+		reg_r(gspca_dev, 0x20, 0, 1);
 		switch (gspca_dev->usb_buf[0]) {
 		case 1:
 			break;		/* (right bridge/subtype) */
@@ -848,8 +857,8 @@
 	return 0;
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct usb_device *dev = gspca_dev->dev;
@@ -860,12 +869,12 @@
 
 	switch (sd->bridge) {
 	case BRIDGE_SPCA504B:
-		reg_w(dev, 0x1d, 0, 0, NULL, 0);
-		reg_w(dev, 0, 1, 0x2306, NULL, 0);
-		reg_w(dev, 0, 0, 0x0d04, NULL, 0);
-		reg_w(dev, 0, 0, 0x2000, NULL, 0);
-		reg_w(dev, 0, 0x13, 0x2301, NULL, 0);
-		reg_w(dev, 0, 0, 0x2306, NULL, 0);
+		reg_w(gspca_dev, 0x1d, 0, 0, 0);
+		reg_w(gspca_dev, 0, 1, 0x2306, 0);
+		reg_w(gspca_dev, 0, 0, 0x0d04, 0);
+		reg_w(gspca_dev, 0, 0, 0x2000, 0);
+		reg_w(gspca_dev, 0, 0x13, 0x2301, 0);
+		reg_w(gspca_dev, 0, 0, 0x2306, 0);
 		/* fall thru */
 	case BRIDGE_SPCA533:
 		rc = spca504B_PollingDataReady(gspca_dev);
@@ -873,12 +882,12 @@
 		break;
 	case BRIDGE_SPCA536:
 		spca50x_GetFirmware(gspca_dev);
-		reg_r(dev, 0x00, 0x5002, gspca_dev->usb_buf, 1);
+		reg_r(gspca_dev, 0x00, 0x5002, 1);
 		gspca_dev->usb_buf[0] = 0;
-		reg_w(dev, 0x24, 0, 0, gspca_dev->usb_buf, 1);
-		reg_r(dev, 0x24, 0, gspca_dev->usb_buf, 1);
+		reg_w(gspca_dev, 0x24, 0, 0, 1);
+		reg_r(gspca_dev, 0x24, 0, 1);
 		rc = spca504B_PollingDataReady(gspca_dev);
-		reg_w(dev, 0x34, 0, 0, NULL, 0);
+		reg_w(gspca_dev, 0x34, 0, 0, 0);
 		spca504B_WaitCmdStatus(gspca_dev);
 		break;
 	case BRIDGE_SPCA504C:	/* pccam600 */
@@ -971,12 +980,12 @@
 /*	case BRIDGE_SPCA536: */
 		if (sd->subtype == MegapixV4 ||
 		    sd->subtype == LogitechClickSmart820) {
-			reg_w(dev, 0xf0, 0, 0, NULL, 0);
+			reg_w(gspca_dev, 0xf0, 0, 0, 0);
 			spca504B_WaitCmdStatus(gspca_dev);
-			reg_r(dev, 0xf0, 4, NULL, 0);
+			reg_r(gspca_dev, 0xf0, 4, 0);
 			spca504B_WaitCmdStatus(gspca_dev);
 		} else {
-			reg_w(dev, 0x31, 0, 4, NULL, 0);
+			reg_w(gspca_dev, 0x31, 0, 4, 0);
 			spca504B_WaitCmdStatus(gspca_dev);
 			rc = spca504B_PollingDataReady(gspca_dev);
 		}
@@ -1045,7 +1054,7 @@
 /*	case BRIDGE_SPCA533: */
 /*	case BRIDGE_SPCA536: */
 /*	case BRIDGE_SPCA504B: */
-		reg_w(dev, 0x31, 0, 0, NULL, 0);
+		reg_w(gspca_dev, 0x31, 0, 0, 0);
 		spca504B_WaitCmdStatus(gspca_dev);
 		spca504B_PollingDataReady(gspca_dev);
 		break;
@@ -1069,14 +1078,6 @@
 	}
 }
 
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
-}
-
-static void sd_close(struct gspca_dev *gspca_dev)
-{
-}
-
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
@@ -1369,11 +1370,9 @@
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
-	.open = sd_open,
+	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
-	.stop0 = sd_stop0,
-	.close = sd_close,
 	.pkt_scan = sd_pkt_scan,
 };
 
@@ -1456,6 +1455,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 91b555c..f034c74 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -30,7 +30,7 @@
 
 #define MAX_GAMMA 0x10		/* 0 to 15 */
 
-#define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 3)
+#define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 0)
 
 MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
 MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
@@ -233,7 +233,7 @@
 static struct v4l2_pix_format vga_mode_t16[] = {
 	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 		.bytesperline = 160,
-		.sizeimage = 160 * 120 * 3 / 8 + 590,
+		.sizeimage = 160 * 120 * 4 / 8 + 590,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 4},
 	{176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
@@ -391,7 +391,7 @@
 				NULL, 0, 500);
 		return;
 	}
-	if (len <= sizeof gspca_dev->usb_buf) {
+	if (len <= USB_BUF_SZ) {
 		memcpy(gspca_dev->usb_buf, buffer, len);
 		usb_control_msg(gspca_dev->dev,
 				usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -552,6 +552,13 @@
 	return 0;
 }
 
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+	init_default_parameters(gspca_dev);
+	return 0;
+}
+
 static void setbrightness(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -893,18 +900,6 @@
 	setcolors(gspca_dev);
 }
 
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
-}
-
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
-}
-
-static void sd_close(struct gspca_dev *gspca_dev)
-{
-}
-
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
@@ -972,24 +967,14 @@
 	return -EINVAL;
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
-{
-	init_default_parameters(gspca_dev);
-	return 0;
-}
-
 /* sub-driver description */
 static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
-	.open = sd_open,
+	.init = sd_init,
 	.start = sd_start,
-	.stopN = sd_stopN,
-	.stop0 = sd_stop0,
-	.close = sd_close,
 	.pkt_scan = sd_pkt_scan,
 	.querymenu = sd_querymenu,
 };
@@ -1014,6 +999,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index 1ff8ba2..084af05 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -331,8 +331,8 @@
 	}
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
 {
 	reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
 	reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
@@ -450,14 +450,6 @@
 	reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
 }
 
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
-}
-
-static void sd_close(struct gspca_dev *gspca_dev)
-{
-}
-
 static void tv8532_preprocess(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -611,11 +603,9 @@
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
-	.open = sd_open,
+	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
-	.stop0 = sd_stop0,
-	.close = sd_close,
 	.pkt_scan = sd_pkt_scan,
 };
 
@@ -644,6 +634,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index f4a5295..bd4c226 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -69,6 +69,7 @@
 	    .set = sd_setautogain,
 	    .get = sd_getautogain,
 	},
+#define LIGHTFREQ_IDX 1
 	{
 	    {
 		.id	 = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -87,12 +88,12 @@
 };
 
 static struct v4l2_pix_format vc0321_mode[] = {
-	{320, 240, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE,
+	{320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
 		.bytesperline = 320,
 		.sizeimage = 320 * 240 * 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
 		.priv = 1},
-	{640, 480, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE,
+	{640, 480, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
 		.bytesperline = 640,
 		.sizeimage = 640 * 480 * 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
@@ -1463,6 +1464,8 @@
 	sd->qindex = 7;
 	sd->autogain = AUTOGAIN_DEF;
 	sd->lightfreq = FREQ_DEF;
+	if (sd->sensor != SENSOR_OV7670)
+		gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX);
 
 	if (sd->bridge == BRIDGE_VC0321) {
 		reg_r(gspca_dev, 0x8a, 0, 3);
@@ -1474,8 +1477,8 @@
 	return 0;
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
+/* this function is called at probe and time */
+static int sd_init(struct gspca_dev *gspca_dev)
 {
 	return 0;
 }
@@ -1637,19 +1640,6 @@
 	reg_w(dev, 0x89, 0xffff, 0xffff);
 }
 
-/* this function is called at close time */
-static void sd_close(struct gspca_dev *gspca_dev)
-{
-/*	struct usb_device *dev = gspca_dev->dev;
-	__u8 buffread;
-
-	reg_w(dev, 0x89, 0xffff, 0xffff);
-	reg_w(dev, 0xa0, 0x01, 0xb301);
-	reg_w(dev, 0xa0, 0x09, 0xb303);
-	reg_w(dev, 0x89, 0xffff, 0xffff);
-*/
-}
-
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
@@ -1738,11 +1728,10 @@
 	.ctrls = sd_ctrls,
 	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
-	.open = sd_open,
+	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
 	.stop0 = sd_stop0,
-	.close = sd_close,
 	.pkt_scan = sd_pkt_scan,
 	.querymenu = sd_querymenu,
 };
@@ -1774,6 +1763,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index bc7d0ee..8d7c27e 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -85,6 +85,7 @@
 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
 
 static struct ctrl sd_ctrls[] = {
+#define BRIGHTNESS_IDX 0
 #define SD_BRIGHTNESS 0
 	{
 	    {
@@ -141,6 +142,7 @@
 	    .set = sd_setautogain,
 	    .get = sd_getautogain,
 	},
+#define LIGHTFREQ_IDX 4
 #define SD_FREQ 4
 	{
 	    {
@@ -6964,8 +6966,13 @@
 	case SENSOR_MC501CB:
 		return -1;		/* don't probe */
 	case SENSOR_TAS5130C_VF0250:
-				/* may probe but with write in reg 0x0010 */
+			/* may probe but with no write in reg 0x0010 */
 		return -1;		/* don't probe */
+	case SENSOR_PAS106:
+		sensor =  sif_probe(gspca_dev);
+		if (sensor >= 0)
+			return sensor;
+		break;
 	}
 	sensor = vga_2wr_probe(gspca_dev);
 	if (sensor >= 0) {
@@ -6974,12 +6981,10 @@
 		/* next probe is needed for OmniVision ? */
 	}
 	sensor2 = vga_3wr_probe(gspca_dev);
-	if (sensor2 >= 0) {
-		if (sensor >= 0)
-			return sensor;
-		return sensor2;
-	}
-	return sif_probe(gspca_dev);
+	if (sensor2 >= 0
+	    && sensor >= 0)
+		return sensor;
+	return sensor2;
 }
 
 /* this function is called at probe time */
@@ -7147,13 +7152,27 @@
 	sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value;
 	sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
 
+	switch (sd->sensor) {
+	case SENSOR_GC0305:
+	case SENSOR_OV7620:
+	case SENSOR_PO2030:
+		gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX);
+		break;
+	case SENSOR_HDCS2020:
+	case SENSOR_HV7131B:
+	case SENSOR_HV7131C:
+	case SENSOR_OV7630C:
+		gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX);
+		break;
+	}
+
 	/* switch the led off */
 	reg_w(gspca_dev->dev, 0x01, 0x0000);
 	return 0;
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
 {
 	reg_w(gspca_dev->dev, 0x01, 0x0000);
 	return 0;
@@ -7314,10 +7333,6 @@
 	}
 }
 
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
-}
-
 static void sd_stop0(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -7325,11 +7340,6 @@
 	send_unknown(gspca_dev->dev, sd->sensor);
 }
 
-/* this function is called at close time */
-static void sd_close(struct gspca_dev *gspca_dev)
-{
-}
-
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,
 			__u8 *data,
@@ -7489,37 +7499,30 @@
 	.ctrls = sd_ctrls,
 	.nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0],
 	.config = sd_config,
-	.open = sd_open,
+	.init = sd_init,
 	.start = sd_start,
-	.stopN = sd_stopN,
 	.stop0 = sd_stop0,
-	.close = sd_close,
 	.pkt_scan = sd_pkt_scan,
 	.querymenu = sd_querymenu,
 };
 
 static const __devinitdata struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x041e, 0x041e)},
-#ifndef CONFIG_USB_ZC0301
 	{USB_DEVICE(0x041e, 0x4017)},
-	{USB_DEVICE(0x041e, 0x401c)},
+	{USB_DEVICE(0x041e, 0x401c), .driver_info = SENSOR_PAS106},
 	{USB_DEVICE(0x041e, 0x401e)},
 	{USB_DEVICE(0x041e, 0x401f)},
-#endif
+	{USB_DEVICE(0x041e, 0x4022)},
 	{USB_DEVICE(0x041e, 0x4029)},
-#ifndef CONFIG_USB_ZC0301
-	{USB_DEVICE(0x041e, 0x4034)},
-	{USB_DEVICE(0x041e, 0x4035)},
+	{USB_DEVICE(0x041e, 0x4034), .driver_info = SENSOR_PAS106},
+	{USB_DEVICE(0x041e, 0x4035), .driver_info = SENSOR_PAS106},
 	{USB_DEVICE(0x041e, 0x4036)},
 	{USB_DEVICE(0x041e, 0x403a)},
-#endif
 	{USB_DEVICE(0x041e, 0x4051), .driver_info = SENSOR_TAS5130C_VF0250},
 	{USB_DEVICE(0x041e, 0x4053), .driver_info = SENSOR_TAS5130C_VF0250},
-#ifndef CONFIG_USB_ZC0301
 	{USB_DEVICE(0x0458, 0x7007)},
 	{USB_DEVICE(0x0458, 0x700c)},
 	{USB_DEVICE(0x0458, 0x700f)},
-#endif
 	{USB_DEVICE(0x0461, 0x0a00)},
 	{USB_DEVICE(0x046d, 0x08a0)},
 	{USB_DEVICE(0x046d, 0x08a1)},
@@ -7531,7 +7534,7 @@
 	{USB_DEVICE(0x046d, 0x08aa)},
 	{USB_DEVICE(0x046d, 0x08ac)},
 	{USB_DEVICE(0x046d, 0x08ad)},
-#ifndef CONFIG_USB_ZC0301
+#if !defined CONFIG_USB_ZC0301 && !defined CONFIG_USB_ZC0301_MODULE
 	{USB_DEVICE(0x046d, 0x08ae)},
 #endif
 	{USB_DEVICE(0x046d, 0x08af)},
@@ -7541,27 +7544,25 @@
 	{USB_DEVICE(0x046d, 0x08d8)},
 	{USB_DEVICE(0x046d, 0x08da)},
 	{USB_DEVICE(0x046d, 0x08dd), .driver_info = SENSOR_MC501CB},
-	{USB_DEVICE(0x0471, 0x0325)},
-	{USB_DEVICE(0x0471, 0x0326)},
-	{USB_DEVICE(0x0471, 0x032d)},
-	{USB_DEVICE(0x0471, 0x032e)},
+	{USB_DEVICE(0x0471, 0x0325), .driver_info = SENSOR_PAS106},
+	{USB_DEVICE(0x0471, 0x0326), .driver_info = SENSOR_PAS106},
+	{USB_DEVICE(0x0471, 0x032d), .driver_info = SENSOR_PAS106},
+	{USB_DEVICE(0x0471, 0x032e), .driver_info = SENSOR_PAS106},
 	{USB_DEVICE(0x055f, 0xc005)},
-#ifndef CONFIG_USB_ZC0301
 	{USB_DEVICE(0x055f, 0xd003)},
 	{USB_DEVICE(0x055f, 0xd004)},
-#endif
 	{USB_DEVICE(0x0698, 0x2003)},
+	{USB_DEVICE(0x0ac8, 0x0301), .driver_info = SENSOR_PAS106},
 	{USB_DEVICE(0x0ac8, 0x0302)},
-#ifndef CONFIG_USB_ZC0301
 	{USB_DEVICE(0x0ac8, 0x301b)},
+#if !defined CONFIG_USB_ZC0301 && !defined CONFIG_USB_ZC0301_MODULE
 	{USB_DEVICE(0x0ac8, 0x303b)},
 #endif
 	{USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250},
-#ifndef CONFIG_USB_ZC0301
 	{USB_DEVICE(0x0ac8, 0x307b)},
 	{USB_DEVICE(0x10fd, 0x0128)},
+	{USB_DEVICE(0x10fd, 0x804d)},
 	{USB_DEVICE(0x10fd, 0x8050)},
-#endif
 	{}			/* end of entry */
 };
 #undef DVNAME
@@ -7581,6 +7582,10 @@
 	.id_table = device_table,
 	.probe = sd_probe,
 	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
 };
 
 static int __init sd_mod_init(void)
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index aea1664..4afc7ea 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -688,7 +688,7 @@
 	spin_lock_init(&itv->lock);
 	spin_lock_init(&itv->dma_reg_lock);
 
-	itv->irq_work_queues = create_workqueue(itv->name);
+	itv->irq_work_queues = create_singlethread_workqueue(itv->name);
 	if (itv->irq_work_queues == NULL) {
 		IVTV_ERR("Could not create ivtv workqueue\n");
 		return -1;
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index ab287b4..2ceb522 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -251,6 +251,7 @@
 #define IVTV_F_I_DEC_PAUSED	   20 	/* the decoder is paused */
 #define IVTV_F_I_INITED		   21 	/* set after first open */
 #define IVTV_F_I_FAILED		   22 	/* set if first open failed */
+#define IVTV_F_I_WORK_INITED       23	/* worker thread was initialized */
 
 /* Event notifications */
 #define IVTV_F_I_EV_DEC_STOPPED	   28	/* decoder stopped event */
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index fba150a..34f3ab8 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -76,6 +76,13 @@
 
 	DEFINE_WAIT(wait);
 
+	if (test_and_clear_bit(IVTV_F_I_WORK_INITED, &itv->i_flags)) {
+		struct sched_param param = { .sched_priority = 99 };
+
+		/* This thread must use the FIFO scheduler as it
+		   is realtime sensitive. */
+		sched_setscheduler(current, SCHED_FIFO, &param);
+	}
 	if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags))
 		ivtv_pio_work_handler(itv);
 
@@ -678,34 +685,14 @@
 
 static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
 {
-	struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG];
 	u32 data[CX2341X_MBOX_MAX_DATA];
 	struct ivtv_stream *s;
 
 	IVTV_DEBUG_HI_IRQ("ENC START VBI CAP\n");
 	s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
 
-	/* If more than two VBI buffers are pending, then
-	   clear the old ones and start with this new one.
-	   This can happen during transition stages when MPEG capturing is
-	   started, but the first interrupts haven't arrived yet. During
-	   that period VBI requests can accumulate without being able to
-	   DMA the data. Since at most four VBI DMA buffers are available,
-	   we just drop the old requests when there are already three
-	   requests queued. */
-	if (s->sg_pending_size > 2) {
-		struct ivtv_buffer *buf;
-		list_for_each_entry(buf, &s->q_predma.list, list)
-			ivtv_buf_sync_for_cpu(s, buf);
-		ivtv_queue_move(s, &s->q_predma, NULL, &s->q_free, 0);
-		s->sg_pending_size = 0;
-	}
-	/* if we can append the data, and the MPEG stream isn't capturing,
-	   then start a DMA request for just the VBI data. */
-	if (!stream_enc_dma_append(s, data) &&
-			!test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) {
+	if (!stream_enc_dma_append(s, data))
 		set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
-	}
 }
 
 static void ivtv_irq_dec_vbi_reinsert(struct ivtv *itv)
diff --git a/drivers/media/video/ivtv/ivtv-queue.h b/drivers/media/video/ivtv/ivtv-queue.h
index 7cfc0c9..476556a 100644
--- a/drivers/media/video/ivtv/ivtv-queue.h
+++ b/drivers/media/video/ivtv/ivtv-queue.h
@@ -23,7 +23,7 @@
 #define IVTV_QUEUE_H
 
 #define IVTV_DMA_UNMAPPED	((u32) -1)
-#define SLICED_VBI_PIO 1
+#define SLICED_VBI_PIO 0
 
 /* ivtv_buffer utility functions */
 
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 54d2023..730e85d 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -363,7 +363,7 @@
 	/* Every X number of frames a VBI interrupt arrives (frames as in 25 or 30 fps) */
 	data[1] = 1;
 	/* The VBI frames are stored in a ringbuffer with this size (with a VBI frame as unit) */
-	data[2] = raw ? 4 : 8;
+	data[2] = raw ? 4 : 4 * (itv->vbi.raw_size / itv->vbi.enc_size);
 	/* The start/stop codes determine which VBI lines end up in the raw VBI data area.
 	   The codes are from table 24 in the saa7115 datasheet. Each raw/sliced/video line
 	   is framed with codes FF0000XX where XX is the SAV/EAV (Start/End of Active Video)
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
index 71798f0..1ce9deb 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/drivers/media/video/ivtv/ivtv-vbi.c
@@ -293,6 +293,7 @@
 	u32 line_size = itv->vbi.sliced_decoder_line_size;
 	struct v4l2_decode_vbi_line vbi;
 	int i;
+	unsigned lines = 0;
 
 	/* find the first valid line */
 	for (i = 0; i < size; i++, buf++) {
@@ -313,7 +314,8 @@
 		}
 		vbi.p = p + 4;
 		itv->video_dec_func(itv, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
-		if (vbi.type) {
+		if (vbi.type && !(lines & (1 << vbi.line))) {
+			lines |= 1 << vbi.line;
 			itv->vbi.sliced_data[line].id = vbi.type;
 			itv->vbi.sliced_data[line].field = vbi.is_second_field;
 			itv->vbi.sliced_data[line].line = vbi.line;
diff --git a/drivers/media/video/ivtv/ivtv-version.h b/drivers/media/video/ivtv/ivtv-version.h
index 442f43f..8cd753d 100644
--- a/drivers/media/video/ivtv/ivtv-version.h
+++ b/drivers/media/video/ivtv/ivtv-version.h
@@ -22,7 +22,7 @@
 
 #define IVTV_DRIVER_NAME "ivtv"
 #define IVTV_DRIVER_VERSION_MAJOR 1
-#define IVTV_DRIVER_VERSION_MINOR 3
+#define IVTV_DRIVER_VERSION_MINOR 4
 #define IVTV_DRIVER_VERSION_PATCHLEVEL 0
 
 #define IVTV_VERSION __stringify(IVTV_DRIVER_VERSION_MAJOR) "." __stringify(IVTV_DRIVER_VERSION_MINOR) "." __stringify(IVTV_DRIVER_VERSION_PATCHLEVEL)
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c
index 4895540..2fd4b4a 100644
--- a/drivers/media/video/ks0127.c
+++ b/drivers/media/video/ks0127.c
@@ -679,26 +679,27 @@
 
 	case DECODER_ENABLE_OUTPUT:
 	{
+		int enable;
 
-		int *iarg = arg;
-		int enable = (*iarg != 0);
-			if (enable) {
-				dprintk("ks0127: command "
+		iarg = arg;
+		enable = (*iarg != 0);
+		if (enable) {
+			dprintk("ks0127: command "
 					"DECODER_ENABLE_OUTPUT on "
 					"(%d)\n", enable);
-				/* All output pins on */
-				ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x30);
-				/* Obey the OEN pin */
-				ks0127_and_or(ks, KS_CDEM, 0x7f, 0x00);
-			} else {
-				dprintk("ks0127: command "
+			/* All output pins on */
+			ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x30);
+			/* Obey the OEN pin */
+			ks0127_and_or(ks, KS_CDEM, 0x7f, 0x00);
+		} else {
+			dprintk("ks0127: command "
 					"DECODER_ENABLE_OUTPUT off "
 					"(%d)\n", enable);
-				/* Video output pins off */
-				ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x00);
-				/* Ignore the OEN pin */
-				ks0127_and_or(ks, KS_CDEM, 0x7f, 0x80);
-			}
+			/* Video output pins off */
+			ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x00);
+			/* Ignore the OEN pin */
+			ks0127_and_or(ks, KS_CDEM, 0x7f, 0x80);
+		}
 	}
 		break;
 
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 7c8ef6a..a9ef780 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -1806,6 +1806,7 @@
 	memcpy(meye.video_dev, &meye_template, sizeof(meye_template));
 	meye.video_dev->parent = &meye.mchip_dev->dev;
 
+	ret = -EIO;
 	if ((ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1))) {
 		printk(KERN_ERR "meye: unable to power on the camera\n");
 		printk(KERN_ERR "meye: did you enable the camera in "
@@ -1813,7 +1814,6 @@
 		goto outsonypienable;
 	}
 
-	ret = -EIO;
 	if ((ret = pci_enable_device(meye.mchip_dev))) {
 		printk(KERN_ERR "meye: pci_enable_device failed\n");
 		goto outenabledev;
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index f68e91f..8ef578c 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -931,27 +931,29 @@
 	return 0;
 }
 
-static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
+static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard)
 {
-	struct mxb* mxb = (struct mxb*)dev->ext_priv;
+	struct mxb *mxb = (struct mxb *)dev->ext_priv;
 	int zero = 0;
 	int one = 1;
 
-	if(V4L2_STD_PAL_I == std->id ) {
+	if (V4L2_STD_PAL_I == standard->id) {
 		v4l2_std_id std = V4L2_STD_PAL_I;
+
 		DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));
 		/* set the 7146 gpio register -- I don't know what this does exactly */
 		saa7146_write(dev, GPIO_CTRL, 0x00404050);
 		/* unset the 7111 gpio register -- I don't know what this does exactly */
-		mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero);
+		mxb->saa7111a->driver->command(mxb->saa7111a, DECODER_SET_GPIO, &zero);
 		mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
 	} else {
 		v4l2_std_id std = V4L2_STD_PAL_BG;
+
 		DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));
 		/* set the 7146 gpio register -- I don't know what this does exactly */
 		saa7146_write(dev, GPIO_CTRL, 0x00404050);
 		/* set the 7111 gpio register -- I don't know what this does exactly */
-		mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one);
+		mxb->saa7111a->driver->command(mxb->saa7111a, DECODER_SET_GPIO, &one);
 		mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
 	}
 	return 0;
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c
index 9edaca4..3d3c48d 100644
--- a/drivers/media/video/ov511.c
+++ b/drivers/media/video/ov511.c
@@ -626,9 +626,9 @@
 			break;
 
 		/* Retry until idle */
-		do
+		do {
 			rc = reg_r(ov, R511_I2C_CTL);
-		while (rc > 0 && ((rc&1) == 0));
+		} while (rc > 0 && ((rc&1) == 0));
 		if (rc < 0)
 			break;
 
@@ -703,9 +703,9 @@
 			return rc;
 
 		/* Retry until idle */
-		do
-			 rc = reg_r(ov, R511_I2C_CTL);
-		while (rc > 0 && ((rc&1) == 0));
+		do {
+			rc = reg_r(ov, R511_I2C_CTL);
+		} while (rc > 0 && ((rc & 1) == 0));
 		if (rc < 0)
 			return rc;
 
@@ -729,9 +729,9 @@
 			return rc;
 
 		/* Retry until idle */
-		do
+		do {
 			rc = reg_r(ov, R511_I2C_CTL);
-		while (rc > 0 && ((rc&1) == 0));
+		} while (rc > 0 && ((rc&1) == 0));
 		if (rc < 0)
 			return rc;
 
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index 00425d7..7c84f79 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -1019,10 +1019,23 @@
  *	Initialization and module stuff
  */
 
+#ifndef MODULE
+static int enable;
+module_param(enable, int, 0);
+#endif
+
 static int __init init_pms_cards(void)
 {
 	printk(KERN_INFO "Mediavision Pro Movie Studio driver 0.02\n");
 
+#ifndef MODULE
+	if (!enable) {
+		printk(KERN_INFO "PMS: not enabled, use pms.enable=1 to "
+				 "probe\n");
+		return -ENODEV;
+	}
+#endif
+
 	data_port = io_port +1;
 
 	if(init_mediavision())
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
index 1cccd5c7..dbc5607 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -1635,15 +1635,15 @@
 
 	case VIDIOCPWCGVIDCMD:
 	{
-		ARG_DEF(struct pwc_video_command, cmd);
+		ARG_DEF(struct pwc_video_command, vcmd);
 
-		ARGR(cmd).type = pdev->type;
-		ARGR(cmd).release = pdev->release;
-		ARGR(cmd).command_len = pdev->cmd_len;
-		memcpy(&ARGR(cmd).command_buf, pdev->cmd_buf, pdev->cmd_len);
-		ARGR(cmd).bandlength = pdev->vbandlength;
-		ARGR(cmd).frame_size = pdev->frame_size;
-		ARG_OUT(cmd)
+		ARGR(vcmd).type = pdev->type;
+		ARGR(vcmd).release = pdev->release;
+		ARGR(vcmd).command_len = pdev->cmd_len;
+		memcpy(&ARGR(vcmd).command_buf, pdev->cmd_buf, pdev->cmd_len);
+		ARGR(vcmd).bandlength = pdev->vbandlength;
+		ARGR(vcmd).frame_size = pdev->frame_size;
+		ARG_OUT(vcmd)
 		break;
 	}
 	/*
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 388cf94..cf96b2c 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -1025,9 +1025,9 @@
 	struct pxa_camera_dev *pcdev = ici->priv;
 	int i = 0, ret = 0;
 
-	DRCMR68 = pcdev->dma_chans[0] | DRCMR_MAPVLD;
-	DRCMR69 = pcdev->dma_chans[1] | DRCMR_MAPVLD;
-	DRCMR70 = pcdev->dma_chans[2] | DRCMR_MAPVLD;
+	DRCMR(68) = pcdev->dma_chans[0] | DRCMR_MAPVLD;
+	DRCMR(69) = pcdev->dma_chans[1] | DRCMR_MAPVLD;
+	DRCMR(70) = pcdev->dma_chans[2] | DRCMR_MAPVLD;
 
 	CICR0 = pcdev->save_cicr[i++] & ~CICR0_ENB;
 	CICR1 = pcdev->save_cicr[i++];
@@ -1171,9 +1171,9 @@
 	}
 	dev_dbg(pcdev->dev, "got DMA channel (V) %d\n", pcdev->dma_chans[2]);
 
-	DRCMR68 = pcdev->dma_chans[0] | DRCMR_MAPVLD;
-	DRCMR69 = pcdev->dma_chans[1] | DRCMR_MAPVLD;
-	DRCMR70 = pcdev->dma_chans[2] | DRCMR_MAPVLD;
+	DRCMR(68) = pcdev->dma_chans[0] | DRCMR_MAPVLD;
+	DRCMR(69) = pcdev->dma_chans[1] | DRCMR_MAPVLD;
+	DRCMR(70) = pcdev->dma_chans[2] | DRCMR_MAPVLD;
 
 	/* request irq */
 	err = request_irq(pcdev->irq, pxa_camera_irq, 0, PXA_CAM_DRV_NAME,
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index bcd1c8f..ad733ca 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -1489,10 +1489,9 @@
 		 client->addr << 1, client->adapter->name);
 
 	state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL);
-	i2c_set_clientdata(client, state);
-	if (state == NULL) {
+	if (state == NULL)
 		return -ENOMEM;
-	}
+	i2c_set_clientdata(client, state);
 	state->input = -1;
 	state->output = SAA7115_IPORT_ON;
 	state->enable = 1;
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c
index f481277..acceed5 100644
--- a/drivers/media/video/se401.c
+++ b/drivers/media/video/se401.c
@@ -1397,7 +1397,7 @@
 	mutex_init(&se401->lock);
 	wmb();
 
-	if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
+	if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
 		kfree(se401);
 		err("video_register_device failed");
 		return -EIO;
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index 2340876..2da6938 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -3312,6 +3312,7 @@
 	cam->v4ldev->fops = &sn9c102_fops;
 	cam->v4ldev->minor = video_nr[dev_nr];
 	cam->v4ldev->release = video_device_release;
+	cam->v4ldev->parent = &udev->dev;
 
 	init_completion(&cam->probe);
 
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h
index 6ff489b..90a401d 100644
--- a/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ b/drivers/media/video/sn9c102/sn9c102_devtable.h
@@ -40,11 +40,14 @@
 
 static const struct usb_device_id sn9c102_id_table[] = {
 	/* SN9C101 and SN9C102 */
+#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6001, BRIDGE_SN9C102), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6005, BRIDGE_SN9C102), },
+#endif
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6007, BRIDGE_SN9C102), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), },
+/*	{ SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), }, OV6650 */
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6019, BRIDGE_SN9C102), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6024, BRIDGE_SN9C102), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6025, BRIDGE_SN9C102), },
@@ -53,29 +56,33 @@
 	{ SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), },
-	{ SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), },
+/*	{ SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */
 	{ SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), },
 	/* SN9C103 */
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6080, BRIDGE_SN9C103), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6082, BRIDGE_SN9C103), },
-	{ SN9C102_USB_DEVICE(0x0c45, 0x6083, BRIDGE_SN9C103), },
+/*	{ SN9C102_USB_DEVICE(0x0c45, 0x6083, BRIDGE_SN9C103), }, HY7131D/E */
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6088, BRIDGE_SN9C103), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x608a, BRIDGE_SN9C103), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x608b, BRIDGE_SN9C103), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x608c, BRIDGE_SN9C103), },
-	{ SN9C102_USB_DEVICE(0x0c45, 0x608e, BRIDGE_SN9C103), },
+/*	{ SN9C102_USB_DEVICE(0x0c45, 0x608e, BRIDGE_SN9C103), }, CISVF10 */
+#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
 	{ SN9C102_USB_DEVICE(0x0c45, 0x608f, BRIDGE_SN9C103), },
+#endif
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60a0, BRIDGE_SN9C103), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60a2, BRIDGE_SN9C103), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60a3, BRIDGE_SN9C103), },
-	{ SN9C102_USB_DEVICE(0x0c45, 0x60a8, BRIDGE_SN9C103), },
-	{ SN9C102_USB_DEVICE(0x0c45, 0x60aa, BRIDGE_SN9C103), },
-	{ SN9C102_USB_DEVICE(0x0c45, 0x60ab, BRIDGE_SN9C103), },
+/*	{ SN9C102_USB_DEVICE(0x0c45, 0x60a8, BRIDGE_SN9C103), }, PAS106 */
+/*	{ SN9C102_USB_DEVICE(0x0c45, 0x60aa, BRIDGE_SN9C103), }, TAS5130 */
+/*	{ SN9C102_USB_DEVICE(0x0c45, 0x60ab, BRIDGE_SN9C103), }, TAS5130 */
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60ac, BRIDGE_SN9C103), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60ae, BRIDGE_SN9C103), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60af, BRIDGE_SN9C103), },
+#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60b0, BRIDGE_SN9C103), },
+#endif
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60b2, BRIDGE_SN9C103), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60b3, BRIDGE_SN9C103), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60b8, BRIDGE_SN9C103), },
@@ -105,7 +112,7 @@
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x6130, BRIDGE_SN9C120), },
-	{ SN9C102_USB_DEVICE(0x0c45, 0x6138, BRIDGE_SN9C120), },
+/*	{ SN9C102_USB_DEVICE(0x0c45, 0x6138, BRIDGE_SN9C120), }, MO8000 */
 	{ SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), },
 	{ SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), },
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c
index 56dc3d6..dce9474 100644
--- a/drivers/media/video/stv680.c
+++ b/drivers/media/video/stv680.c
@@ -1462,7 +1462,7 @@
 	mutex_init (&stv680->lock);
 	wmb ();
 
-	if (video_register_device (stv680->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
+	if (video_register_device(stv680->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
 		PDEBUG (0, "STV(e): video_register_device failed");
 		retval = -EIO;
 		goto error_vdev;
diff --git a/drivers/media/video/usbvideo/ibmcam.c b/drivers/media/video/usbvideo/ibmcam.c
index 59166b7..cc27efe 100644
--- a/drivers/media/video/usbvideo/ibmcam.c
+++ b/drivers/media/video/usbvideo/ibmcam.c
@@ -736,12 +736,12 @@
 		 * make black color and quit the horizontal scanning loop.
 		 */
 		if (((frame->curline + 2) >= scanHeight) || (i >= scanLength)) {
-			const int j = i * V4L_BYTES_PER_PIXEL;
+			const int offset = i * V4L_BYTES_PER_PIXEL;
 #if USES_IBMCAM_PUTPIXEL
 			/* Refresh 'f' because we don't use it much with PUTPIXEL */
-			f = frame->data + (v4l_linesize * frame->curline) + j;
+			f = frame->data + (v4l_linesize * frame->curline) + offset;
 #endif
-			memset(f, 0, v4l_linesize - j);
+			memset(f, 0, v4l_linesize - offset);
 			break;
 		}
 
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c
index b779245..2eb4582 100644
--- a/drivers/media/video/usbvideo/vicam.c
+++ b/drivers/media/video/usbvideo/vicam.c
@@ -866,7 +866,7 @@
 	cam->udev = dev;
 	cam->bulkEndpoint = bulkEndpoint;
 
-	if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1) == -1) {
+	if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1) < 0) {
 		kfree(cam);
 		printk(KERN_WARNING "video_register_device failed\n");
 		return -EIO;
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 6f36006..155fdec 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -257,6 +257,9 @@
 	int ret;
 	char *name_base;
 
+	if (vfd == NULL)
+		return -EINVAL;
+
 	switch (type) {
 	case VFL_TYPE_GRABBER:
 		base = MINOR_VFL_TYPE_GRABBER_MIN;
@@ -281,7 +284,7 @@
 	default:
 		printk(KERN_ERR "%s called with unknown type: %d\n",
 		       __func__, type);
-		return -1;
+		return -EINVAL;
 	}
 
 	/* pick a minor number */
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index fdfe773..140ef92 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -499,7 +499,7 @@
 			p->timestamp.tv_sec / 3600,
 			(int)(p->timestamp.tv_sec / 60) % 60,
 			(int)(p->timestamp.tv_sec % 60),
-			p->timestamp.tv_usec,
+			(long)p->timestamp.tv_usec,
 			p->index,
 			prt_names(p->type, v4l2_type_names),
 			p->bytesused, p->flags,
@@ -674,7 +674,7 @@
 	 __video_do_ioctl will be called again, with one or more
 	 V4L2 ioctls.
 	 ********************************************************/
-	if (_IOC_TYPE(cmd) == 'v')
+	if (_IOC_TYPE(cmd) == 'v' && _IOC_NR(cmd) < BASE_VIDIOCPRIVATE)
 		return v4l_compat_translate_ioctl(inode, file, cmd, arg,
 						__video_do_ioctl);
 #endif
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 3518af0..8ba8daa 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -1021,13 +1021,13 @@
 		dev = list_entry(list, struct vivi_dev, vivi_devlist);
 
 		if (-1 != dev->vfd->minor) {
+			printk(KERN_INFO "%s: unregistering /dev/video%d\n",
+				VIVI_MODULE_NAME, dev->vfd->minor);
 			video_unregister_device(dev->vfd);
-			printk(KERN_INFO "%s: /dev/video%d unregistered.\n",
-				VIVI_MODULE_NAME, dev->vfd->minor);
 		} else {
-			video_device_release(dev->vfd);
-			printk(KERN_INFO "%s: /dev/video%d released.\n",
+			printk(KERN_INFO "%s: releasing /dev/video%d\n",
 				VIVI_MODULE_NAME, dev->vfd->minor);
+			video_device_release(dev->vfd);
 		}
 
 		kfree(dev);
@@ -1104,19 +1104,29 @@
 	Initialization and module stuff
    ------------------------------------------------------------------*/
 
+/* This routine allocates from 1 to n_devs virtual drivers.
+
+   The real maximum number of virtual drivers will depend on how many drivers
+   will succeed. This is limited to the maximum number of devices that
+   videodev supports. Since there are 64 minors for video grabbers, this is
+   currently the theoretical maximum limit. However, a further limit does
+   exist at videodev that forbids any driver to register more than 32 video
+   grabbers.
+ */
 static int __init vivi_init(void)
 {
 	int ret = -ENOMEM, i;
 	struct vivi_dev *dev;
 	struct video_device *vfd;
 
+	if (n_devs <= 0)
+		n_devs = 1;
+
 	for (i = 0; i < n_devs; i++) {
 		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-		if (NULL == dev)
+		if (!dev)
 			break;
 
-		list_add_tail(&dev->vivi_devlist, &vivi_devlist);
-
 		/* init video dma queues */
 		INIT_LIST_HEAD(&dev->vidq.active);
 		init_waitqueue_head(&dev->vidq.wq);
@@ -1126,14 +1136,27 @@
 		mutex_init(&dev->mutex);
 
 		vfd = video_device_alloc();
-		if (NULL == vfd)
+		if (!vfd) {
+			kfree(dev);
 			break;
+		}
 
 		*vfd = vivi_template;
 
 		ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
-		if (ret < 0)
+		if (ret < 0) {
+			video_device_release(vfd);
+			kfree(dev);
+
+			/* If some registers succeeded, keep driver */
+			if (i)
+				ret = 0;
+
 			break;
+		}
+
+		/* Now that everything is fine, let's add it to device list */
+		list_add_tail(&dev->vivi_devlist, &vivi_devlist);
 
 		snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",
 			 vivi_template.name, vfd->minor);
@@ -1149,11 +1172,16 @@
 	if (ret < 0) {
 		vivi_release();
 		printk(KERN_INFO "Error %d while loading vivi driver\n", ret);
-	} else
+	} else {
 		printk(KERN_INFO "Video Technology Magazine Virtual Video "
 			"Capture Board ver %u.%u.%u successfully loaded.\n",
 			(VIVI_VERSION >> 16) & 0xFF, (VIVI_VERSION >> 8) & 0xFF,
 			VIVI_VERSION & 0xFF);
+
+		/* n_devs will reflect the actual number of allocated devices */
+		n_devs = i;
+	}
+
 	return ret;
 }
 
@@ -1169,10 +1197,10 @@
 MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
 MODULE_LICENSE("Dual BSD/GPL");
 
-module_param(video_nr, int, 0);
+module_param(video_nr, uint, 0444);
 MODULE_PARM_DESC(video_nr, "video iminor start number");
 
-module_param(n_devs, int, 0);
+module_param(n_devs, uint, 0444);
 MODULE_PARM_DESC(n_devs, "number of video devices to create");
 
 module_param_named(debug, vivi_template.debug, int, 0444);
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index 9402f40..2ff00bc 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -334,7 +334,7 @@
 	memcpy(&cam->vdev, &w9966_template, sizeof(struct video_device));
 	cam->vdev.priv = cam;
 
-	if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) == -1)
+	if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0)
 		return -1;
 
 	w9966_setState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV);
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c
index 550ce7b..0c32877 100644
--- a/drivers/media/video/zc0301/zc0301_core.c
+++ b/drivers/media/video/zc0301/zc0301_core.c
@@ -1988,6 +1988,7 @@
 	cam->v4ldev->fops = &zc0301_fops;
 	cam->v4ldev->minor = video_nr[dev_nr];
 	cam->v4ldev->release = video_device_release;
+	cam->v4ldev->parent = &udev->dev;
 	video_set_drvdata(cam->v4ldev, cam);
 
 	init_completion(&cam->probe);
diff --git a/drivers/media/video/zc0301/zc0301_sensor.h b/drivers/media/video/zc0301/zc0301_sensor.h
index 70fe6fc..b0cd49c 100644
--- a/drivers/media/video/zc0301/zc0301_sensor.h
+++ b/drivers/media/video/zc0301/zc0301_sensor.h
@@ -60,27 +60,8 @@
 
 #define ZC0301_ID_TABLE                                                       \
 static const struct usb_device_id zc0301_id_table[] =  {                      \
-	{ ZC0301_USB_DEVICE(0x041e, 0x4017, 0xff), }, /* ICM105 */            \
-	{ ZC0301_USB_DEVICE(0x041e, 0x401c, 0xff), }, /* PAS106 */            \
-	{ ZC0301_USB_DEVICE(0x041e, 0x401e, 0xff), }, /* HV7131 */            \
-	{ ZC0301_USB_DEVICE(0x041e, 0x401f, 0xff), }, /* TAS5130 */           \
-	{ ZC0301_USB_DEVICE(0x041e, 0x4022, 0xff), },                         \
-	{ ZC0301_USB_DEVICE(0x041e, 0x4034, 0xff), }, /* PAS106 */            \
-	{ ZC0301_USB_DEVICE(0x041e, 0x4035, 0xff), }, /* PAS106 */            \
-	{ ZC0301_USB_DEVICE(0x041e, 0x4036, 0xff), }, /* HV7131 */            \
-	{ ZC0301_USB_DEVICE(0x041e, 0x403a, 0xff), }, /* HV7131 */            \
-	{ ZC0301_USB_DEVICE(0x0458, 0x7007, 0xff), }, /* TAS5130 */           \
-	{ ZC0301_USB_DEVICE(0x0458, 0x700c, 0xff), }, /* TAS5130 */           \
-	{ ZC0301_USB_DEVICE(0x0458, 0x700f, 0xff), }, /* TAS5130 */           \
 	{ ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */            \
-	{ ZC0301_USB_DEVICE(0x055f, 0xd003, 0xff), }, /* TAS5130 */           \
-	{ ZC0301_USB_DEVICE(0x055f, 0xd004, 0xff), }, /* TAS5130 */           \
-	{ ZC0301_USB_DEVICE(0x0ac8, 0x0301, 0xff), },                         \
-	{ ZC0301_USB_DEVICE(0x0ac8, 0x301b, 0xff), }, /* PB-0330/HV7131 */    \
 	{ ZC0301_USB_DEVICE(0x0ac8, 0x303b, 0xff), }, /* PB-0330 */           \
-	{ ZC0301_USB_DEVICE(0x10fd, 0x0128, 0xff), }, /* TAS5130 */           \
-	{ ZC0301_USB_DEVICE(0x10fd, 0x8050, 0xff), }, /* TAS5130 */           \
-	{ ZC0301_USB_DEVICE(0x10fd, 0x804e, 0xff), }, /* TAS5130 */           \
 	{ }                                                                   \
 };
 
diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c
index a380050..cea4690 100644
--- a/drivers/memstick/core/memstick.c
+++ b/drivers/memstick/core/memstick.c
@@ -185,7 +185,7 @@
 }
 
 static struct class memstick_host_class = {
-	.name       = "memstick_host",
+	.name        = "memstick_host",
 	.dev_release = memstick_free
 };
 
@@ -264,7 +264,7 @@
  * @sg - TPC argument
  */
 void memstick_init_req_sg(struct memstick_request *mrq, unsigned char tpc,
-			  struct scatterlist *sg)
+			  const struct scatterlist *sg)
 {
 	mrq->tpc = tpc;
 	if (tpc & 8)
@@ -294,7 +294,7 @@
  * user supplied buffer.
  */
 void memstick_init_req(struct memstick_request *mrq, unsigned char tpc,
-		       void *buf, size_t length)
+		       const void *buf, size_t length)
 {
 	mrq->tpc = tpc;
 	if (tpc & 8)
@@ -439,7 +439,7 @@
 	if (!host->card) {
 		if (memstick_power_on(host))
 			goto out_power_off;
-	} else
+	} else if (host->card->stop)
 		host->card->stop(host->card);
 
 	card = memstick_alloc_card(host);
@@ -458,7 +458,7 @@
 			    || !(host->card->check(host->card))) {
 				device_unregister(&host->card->dev);
 				host->card = NULL;
-			} else
+			} else if (host->card->start)
 				host->card->start(host->card);
 		}
 
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c
index 44b1817..d2d2318 100644
--- a/drivers/memstick/core/mspro_block.c
+++ b/drivers/memstick/core/mspro_block.c
@@ -30,6 +30,8 @@
 #define MSPRO_BLOCK_SIGNATURE        0xa5c3
 #define MSPRO_BLOCK_MAX_ATTRIBUTES   41
 
+#define MSPRO_BLOCK_PART_SHIFT 3
+
 enum {
 	MSPRO_BLOCK_ID_SYSINFO         = 0x10,
 	MSPRO_BLOCK_ID_MODELNAME       = 0x15,
@@ -195,7 +197,7 @@
 static int mspro_block_disk_release(struct gendisk *disk)
 {
 	struct mspro_block_data *msb = disk->private_data;
-	int disk_id = disk->first_minor >> MEMSTICK_PART_SHIFT;
+	int disk_id = disk->first_minor >> MSPRO_BLOCK_PART_SHIFT;
 
 	mutex_lock(&mspro_block_disk_lock);
 
@@ -877,6 +879,7 @@
 	struct mspro_block_data *msb = memstick_get_drvdata(card);
 	int rc = 0;
 
+try_again:
 	if (msb->caps & MEMSTICK_CAP_PAR4)
 		rc = mspro_block_set_interface(card, MEMSTICK_SYS_PAR4);
 	else
@@ -930,6 +933,18 @@
 		rc = memstick_set_rw_addr(card);
 		if (!rc)
 			rc = mspro_block_set_interface(card, msb->system);
+
+		if (!rc) {
+			msleep(150);
+			rc = mspro_block_wait_for_ced(card);
+			if (rc)
+				return rc;
+
+			if (msb->caps & MEMSTICK_CAP_PAR8) {
+				msb->caps &= ~MEMSTICK_CAP_PAR8;
+				goto try_again;
+			}
+		}
 	}
 	return rc;
 }
@@ -1117,14 +1132,16 @@
 		return -EIO;
 
 	msb->caps = host->caps;
+
+	msleep(150);
+	rc = mspro_block_wait_for_ced(card);
+	if (rc)
+		return rc;
+
 	rc = mspro_block_switch_interface(card);
 	if (rc)
 		return rc;
 
-	msleep(200);
-	rc = mspro_block_wait_for_ced(card);
-	if (rc)
-		return rc;
 	dev_dbg(&card->dev, "card activated\n");
 	if (msb->system != MEMSTICK_SYS_SERIAL)
 		msb->caps |= MEMSTICK_CAP_AUTO_GET_INT;
@@ -1192,12 +1209,12 @@
 	if (rc)
 		return rc;
 
-	if ((disk_id << MEMSTICK_PART_SHIFT) > 255) {
+	if ((disk_id << MSPRO_BLOCK_PART_SHIFT) > 255) {
 		rc = -ENOSPC;
 		goto out_release_id;
 	}
 
-	msb->disk = alloc_disk(1 << MEMSTICK_PART_SHIFT);
+	msb->disk = alloc_disk(1 << MSPRO_BLOCK_PART_SHIFT);
 	if (!msb->disk) {
 		rc = -ENOMEM;
 		goto out_release_id;
@@ -1220,7 +1237,7 @@
 				   MSPRO_BLOCK_MAX_PAGES * msb->page_size);
 
 	msb->disk->major = major;
-	msb->disk->first_minor = disk_id << MEMSTICK_PART_SHIFT;
+	msb->disk->first_minor = disk_id << MSPRO_BLOCK_PART_SHIFT;
 	msb->disk->fops = &ms_block_bdops;
 	msb->usage_count = 1;
 	msb->disk->private_data = msb;
@@ -1416,7 +1433,7 @@
 
 static struct memstick_device_id mspro_block_id_tbl[] = {
 	{MEMSTICK_MATCH_ALL, MEMSTICK_TYPE_PRO, MEMSTICK_CATEGORY_STORAGE_DUO,
-	 MEMSTICK_CLASS_GENERIC_DUO},
+	 MEMSTICK_CLASS_DUO},
 	{}
 };
 
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c
index 3485c63..2fb95a5 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -81,6 +81,8 @@
 #define TPC_CODE_SZ_MASK       0x00000700
 #define TPC_DATA_SZ_MASK       0x00000007
 
+#define HOST_CONTROL_TDELAY_EN 0x00040000
+#define HOST_CONTROL_HW_OC_P   0x00010000
 #define HOST_CONTROL_RESET_REQ 0x00008000
 #define HOST_CONTROL_REI       0x00004000
 #define HOST_CONTROL_LED       0x00000400
@@ -88,6 +90,7 @@
 #define HOST_CONTROL_RESET     0x00000100
 #define HOST_CONTROL_POWER_EN  0x00000080
 #define HOST_CONTROL_CLOCK_EN  0x00000040
+#define HOST_CONTROL_REO       0x00000008
 #define HOST_CONTROL_IF_SHIFT  4
 
 #define HOST_CONTROL_IF_SERIAL 0x0
@@ -133,11 +136,15 @@
 #define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000
 
 #define CLOCK_CONTROL_40MHZ   0x00000001
-#define CLOCK_CONTROL_50MHZ   0x00000002
+#define CLOCK_CONTROL_50MHZ   0x0000000a
 #define CLOCK_CONTROL_60MHZ   0x00000008
 #define CLOCK_CONTROL_62_5MHZ 0x0000000c
 #define CLOCK_CONTROL_OFF     0x00000000
 
+#define PCI_CTL_CLOCK_DLY_ADDR   0x000000b0
+#define PCI_CTL_CLOCK_DLY_MASK_A 0x00000f00
+#define PCI_CTL_CLOCK_DLY_MASK_B 0x0000f000
+
 enum {
 	CMD_READY    = 0x01,
 	FIFO_READY   = 0x02,
@@ -367,8 +374,7 @@
 		return host->req->error;
 	}
 
-	dev_dbg(&msh->dev, "control %08x\n",
-		readl(host->addr + HOST_CONTROL));
+	dev_dbg(&msh->dev, "control %08x\n", readl(host->addr + HOST_CONTROL));
 	dev_dbg(&msh->dev, "status %08x\n", readl(host->addr + INT_STATUS));
 	dev_dbg(&msh->dev, "hstatus %08x\n", readl(host->addr + STATUS));
 
@@ -637,7 +643,7 @@
 		ndelay(20);
 	}
 	dev_dbg(&host->chip->pdev->dev, "reset_req timeout\n");
-	return -EIO;
+	/* return -EIO; */
 
 reset_next:
 	writel(HOST_CONTROL_RESET | HOST_CONTROL_CLOCK_EN
@@ -680,7 +686,9 @@
 
 			host_ctl = 7;
 			host_ctl |= HOST_CONTROL_POWER_EN
-				 | HOST_CONTROL_CLOCK_EN;
+				    | HOST_CONTROL_CLOCK_EN
+				    | HOST_CONTROL_HW_OC_P
+				    | HOST_CONTROL_TDELAY_EN;
 			writel(host_ctl, host->addr + HOST_CONTROL);
 
 			writel(host->id ? PAD_PU_PD_ON_MS_SOCK1
@@ -704,33 +712,40 @@
 		break;
 	case MEMSTICK_INTERFACE:
 		host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT);
+		pci_read_config_dword(host->chip->pdev,
+				      PCI_CTL_CLOCK_DLY_ADDR,
+				      &clock_delay);
+		clock_delay &= host->id ? ~PCI_CTL_CLOCK_DLY_MASK_B
+					: ~PCI_CTL_CLOCK_DLY_MASK_A;
 
 		if (value == MEMSTICK_SERIAL) {
 			host_ctl &= ~HOST_CONTROL_FAST_CLK;
+			host_ctl &= ~HOST_CONTROL_REO;
 			host_ctl |= HOST_CONTROL_IF_SERIAL
 				    << HOST_CONTROL_IF_SHIFT;
 			host_ctl |= HOST_CONTROL_REI;
 			clock_ctl = CLOCK_CONTROL_40MHZ;
-			clock_delay = 0;
 		} else if (value == MEMSTICK_PAR4) {
-			host_ctl |= HOST_CONTROL_FAST_CLK;
+			host_ctl |= HOST_CONTROL_FAST_CLK | HOST_CONTROL_REO;
 			host_ctl |= HOST_CONTROL_IF_PAR4
 				    << HOST_CONTROL_IF_SHIFT;
 			host_ctl &= ~HOST_CONTROL_REI;
 			clock_ctl = CLOCK_CONTROL_40MHZ;
-			clock_delay = 4;
+			clock_delay |= host->id ? (4 << 12) : (4 << 8);
 		} else if (value == MEMSTICK_PAR8) {
 			host_ctl |= HOST_CONTROL_FAST_CLK;
 			host_ctl |= HOST_CONTROL_IF_PAR8
 				    << HOST_CONTROL_IF_SHIFT;
-			host_ctl &= ~HOST_CONTROL_REI;
-			clock_ctl = CLOCK_CONTROL_60MHZ;
-			clock_delay = 0;
+			host_ctl &= ~(HOST_CONTROL_REI | HOST_CONTROL_REO);
+			clock_ctl = CLOCK_CONTROL_50MHZ;
 		} else
 			return -EINVAL;
+
 		writel(host_ctl, host->addr + HOST_CONTROL);
 		writel(clock_ctl, host->addr + CLOCK_CONTROL);
-		writel(clock_delay, host->addr + CLOCK_DELAY);
+		pci_write_config_dword(host->chip->pdev,
+				       PCI_CTL_CLOCK_DLY_ADDR,
+				       clock_delay);
 		break;
 	};
 	return 0;
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 10c44d3..5dba165 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -50,6 +50,15 @@
 	  HTC Magician devices, respectively. Actual functionality is
 	  handled by the leds-pasic3 and ds1wm drivers.
 
+config UCB1400_CORE
+	tristate "Philips UCB1400 Core driver"
+	help
+	  This enables support for the Philips UCB1400 core functions.
+	  The UCB1400 is an AC97 audio codec.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ucb1400_core.
+
 config MFD_TMIO
 	bool
 	default n
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 03ad239..6abebe3 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -22,3 +22,4 @@
 ifeq ($(CONFIG_SA1100_ASSABET),y)
 obj-$(CONFIG_MCP_UCB1200)	+= ucb1x00-assabet.o
 endif
+obj-$(CONFIG_UCB1400_CORE)	+= ucb1400_core.o
diff --git a/drivers/mfd/ucb1400_core.c b/drivers/mfd/ucb1400_core.c
new file mode 100644
index 0000000..178159e
--- /dev/null
+++ b/drivers/mfd/ucb1400_core.c
@@ -0,0 +1,106 @@
+/*
+ * Core functions for:
+ *  Philips UCB1400 multifunction chip
+ *
+ * Based on ucb1400_ts.c:
+ *  Author:	Nicolas Pitre
+ *  Created:	September 25, 2006
+ *  Copyright:	MontaVista Software, Inc.
+ *
+ * Spliting done by: Marek Vasut <marek.vasut@gmail.com>
+ * If something doesnt work and it worked before spliting, e-mail me,
+ * dont bother Nicolas please ;-)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This code is heavily based on ucb1x00-*.c copyrighted by Russell King
+ * covering the UCB1100, UCB1200 and UCB1300..  Support for the UCB1400 has
+ * been made separate from ucb1x00-core/ucb1x00-ts on Russell's request.
+ */
+
+#include <linux/module.h>
+#include <linux/ucb1400.h>
+
+static int ucb1400_core_probe(struct device *dev)
+{
+	int err;
+	struct ucb1400 *ucb;
+	struct ucb1400_ts ucb_ts;
+	struct snd_ac97 *ac97;
+
+	memset(&ucb_ts, 0, sizeof(ucb_ts));
+
+	ucb = kzalloc(sizeof(struct ucb1400), GFP_KERNEL);
+	if (!ucb) {
+		err = -ENOMEM;
+		goto err;
+	}
+
+	dev_set_drvdata(dev, ucb);
+
+	ac97 = to_ac97_t(dev);
+
+	ucb_ts.id = ucb1400_reg_read(ac97, UCB_ID);
+	if (ucb_ts.id != UCB_ID_1400) {
+		err = -ENODEV;
+		goto err0;
+	}
+
+	/* TOUCHSCREEN */
+	ucb_ts.ac97 = ac97;
+	ucb->ucb1400_ts = platform_device_alloc("ucb1400_ts", -1);
+	if (!ucb->ucb1400_ts) {
+		err = -ENOMEM;
+		goto err0;
+	}
+	err = platform_device_add_data(ucb->ucb1400_ts, &ucb_ts,
+					sizeof(ucb_ts));
+	if (err)
+		goto err1;
+	err = platform_device_add(ucb->ucb1400_ts);
+	if (err)
+		goto err1;
+
+	return 0;
+
+err1:
+	platform_device_put(ucb->ucb1400_ts);
+err0:
+	kfree(ucb);
+err:
+	return err;
+}
+
+static int ucb1400_core_remove(struct device *dev)
+{
+	struct ucb1400 *ucb = dev_get_drvdata(dev);
+
+	platform_device_unregister(ucb->ucb1400_ts);
+	kfree(ucb);
+	return 0;
+}
+
+static struct device_driver ucb1400_core_driver = {
+	.name	= "ucb1400_core",
+	.bus	= &ac97_bus_type,
+	.probe	= ucb1400_core_probe,
+	.remove	= ucb1400_core_remove,
+};
+
+static int __init ucb1400_core_init(void)
+{
+	return driver_register(&ucb1400_core_driver);
+}
+
+static void __exit ucb1400_core_exit(void)
+{
+	driver_unregister(&ucb1400_core_driver);
+}
+
+module_init(ucb1400_core_init);
+module_exit(ucb1400_core_exit);
+
+MODULE_DESCRIPTION("Philips UCB1400 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/fujitsu-laptop.c b/drivers/misc/fujitsu-laptop.c
index 7a1ef6c..3e56203 100644
--- a/drivers/misc/fujitsu-laptop.c
+++ b/drivers/misc/fujitsu-laptop.c
@@ -463,6 +463,13 @@
 		     DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S6410"),
 		     },
 	 .callback = dmi_check_cb_s6410},
+	{
+	 .ident = "FUJITSU LifeBook P8010",
+	 .matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+		     DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P8010"),
+		    },
+	 .callback = dmi_check_cb_s6410},
 	{}
 };
 
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index 23c91f5..d61cee7 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -445,6 +445,9 @@
 	int order = get_order(sizeof(struct gru_state) *
 			      GRU_CHIPLETS_PER_BLADE);
 
+	if (!IS_UV())
+		return;
+
 	for (i = 0; i < GRU_CHIPLETS_PER_BLADE; i++)
 		free_irq(IRQ_GRU + i, NULL);
 
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index d3eb790..6b93007 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -3086,7 +3086,6 @@
 	.read = wan_read,
 	.write = wan_write,
 	.exit = wan_exit,
-	.flags.experimental = 1,
 };
 
 /*************************************************************************
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 86dbb36..6986f39 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -103,8 +103,10 @@
 			check_disk_change(inode->i_bdev);
 		ret = 0;
 
-		if ((filp->f_mode & FMODE_WRITE) && md->read_only)
+		if ((filp->f_mode & FMODE_WRITE) && md->read_only) {
+			mmc_blk_put(md);
 			ret = -EROFS;
+		}
 	}
 
 	return ret;
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 55093ad..ebfaa99 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -520,7 +520,7 @@
 	/*
 	 * Block length register is only 10 bits before PXA27x.
 	 */
-	mmc->max_blk_size = (cpu_is_pxa21x() || cpu_is_pxa25x()) ? 1023 : 2048;
+	mmc->max_blk_size = cpu_is_pxa25x() ? 1023 : 2048;
 
 	/*
 	 * Block count register is 16 bits.
@@ -554,7 +554,7 @@
 			 MMC_VDD_32_33|MMC_VDD_33_34;
 	mmc->caps = 0;
 	host->cmdat = 0;
-	if (!cpu_is_pxa21x() && !cpu_is_pxa25x()) {
+	if (!cpu_is_pxa25x()) {
 		mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
 		host->cmdat |= CMDAT_SDIO_INT_EN;
 		if (cpu_is_pxa300() || cpu_is_pxa310())
diff --git a/drivers/mtd/nand/atmel_nand_ecc.h b/drivers/mtd/nand/atmel_nand_ecc.h
index 1ee7f99..578c776 100644
--- a/drivers/mtd/nand/atmel_nand_ecc.h
+++ b/drivers/mtd/nand/atmel_nand_ecc.h
@@ -2,6 +2,9 @@
  * Error Corrected Code Controller (ECC) - System peripherals regsters.
  * Based on AT91SAM9260 datasheet revision B.
  *
+ * Copyright (C) 2007 Andrew Victor
+ * Copyright (C) 2007 Atmel Corporation.
+ *
  * 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
diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c
index 9eba3f0..fa129c0 100644
--- a/drivers/mtd/nand/cmx270_nand.c
+++ b/drivers/mtd/nand/cmx270_nand.c
@@ -156,7 +156,7 @@
 	int mtd_parts_nb = 0;
 	int ret;
 
-	if (!machine_is_armcore())
+	if (!(machine_is_armcore() && cpu_is_pxa27x()))
 		return -ENODEV;
 
 	ret = gpio_request(GPIO_NAND_CS, "NAND CS");
diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c
index cbab654..edb1e32 100644
--- a/drivers/mtd/nand/tmio_nand.c
+++ b/drivers/mtd/nand/tmio_nand.c
@@ -109,7 +109,7 @@
 
 	void __iomem *ccr;
 	void __iomem *fcr;
-	unsigned long fcr_phys;
+	unsigned long fcr_base;
 
 	unsigned int irq;
 
@@ -316,8 +316,8 @@
 	tmio_iowrite8(0x81, tmio->ccr + CCR_ICC);
 
 	/* (10h)BaseAddress    0x1000 spba.spba2 */
-	tmio_iowrite16(tmio->fcr_phys, tmio->ccr + CCR_BASE);
-	tmio_iowrite16(tmio->fcr_phys >> 16, tmio->ccr + CCR_BASE + 16);
+	tmio_iowrite16(tmio->fcr_base, tmio->ccr + CCR_BASE);
+	tmio_iowrite16(tmio->fcr_base >> 16, tmio->ccr + CCR_BASE + 2);
 
 	/* (04h)Command Register I/O spcmd */
 	tmio_iowrite8(0x02, tmio->ccr + CCR_COMMAND);
@@ -395,7 +395,7 @@
 		goto err_iomap_ccr;
 	}
 
-	tmio->fcr_phys = (unsigned long)fcr->start;
+	tmio->fcr_base = fcr->start & 0xfffff;
 	tmio->fcr = ioremap(fcr->start, fcr->end - fcr->start + 1);
 	if (!tmio->fcr) {
 		retval = -EIO;
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 4a11296..9df7bb9 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1386,7 +1386,8 @@
 
 config CS89x0
 	tristate "CS89x0 support"
-	depends on NET_PCI && (ISA || MACH_IXDP2351 || ARCH_IXDP2X01 || ARCH_PNX010X)
+	depends on NET_ETHERNET && (ISA || EISA || MACH_IXDP2351 \
+		|| ARCH_IXDP2X01 || ARCH_PNX010X || MACH_MX31ADS)
 	---help---
 	  Support for CS89x0 chipset based Ethernet cards. If you have a
 	  network (Ethernet) card of this type, say Y and read the
@@ -1397,6 +1398,11 @@
 	  To compile this driver as a module, choose M here. The module
 	  will be called cs89x0.
 
+config CS89x0_NONISA_IRQ
+	def_bool y
+	depends on CS89x0 != n
+	depends on MACH_IXDP2351 || ARCH_IXDP2X01 || ARCH_PNX010X || MACH_MX31ADS
+
 config TC35815
 	tristate "TOSHIBA TC35815 Ethernet support"
 	depends on NET_PCI && PCI && MIPS
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index a14dba1..fd705d1 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -151,6 +151,8 @@
 #define PAGES_PER_SGE_SHIFT		0
 #define PAGES_PER_SGE			(1 << PAGES_PER_SGE_SHIFT)
 
+#define BCM_RX_ETH_PAYLOAD_ALIGN	64
+
 /* SGE ring related macros */
 #define NUM_RX_SGE_PAGES		2
 #define RX_SGE_CNT		(BCM_PAGE_SIZE / sizeof(struct eth_rx_sge))
@@ -750,8 +752,7 @@
 
 	u32			rx_csum;
 	u32			rx_offset;
-	u32			rx_buf_use_size;	/* useable size */
-	u32			rx_buf_size;		/* with alignment */
+	u32			rx_buf_size;
 #define ETH_OVREHEAD			(ETH_HLEN + 8)	/* 8 for CRC + VLAN */
 #define ETH_MIN_PACKET_SIZE		60
 #define ETH_MAX_PACKET_SIZE		1500
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 82deea0..a8eb3c4 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -59,8 +59,8 @@
 #include "bnx2x.h"
 #include "bnx2x_init.h"
 
-#define DRV_MODULE_VERSION	"1.45.20"
-#define DRV_MODULE_RELDATE	"2008/08/25"
+#define DRV_MODULE_VERSION	"1.45.21"
+#define DRV_MODULE_RELDATE	"2008/09/03"
 #define BNX2X_BC_VER		0x040200
 
 /* Time in jiffies before concluding the transmitter is hung */
@@ -1027,7 +1027,7 @@
 	if (unlikely(skb == NULL))
 		return -ENOMEM;
 
-	mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size,
+	mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_size,
 				 PCI_DMA_FROMDEVICE);
 	if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) {
 		dev_kfree_skb(skb);
@@ -1169,7 +1169,7 @@
 	/* move empty skb from pool to prod and map it */
 	prod_rx_buf->skb = fp->tpa_pool[queue].skb;
 	mapping = pci_map_single(bp->pdev, fp->tpa_pool[queue].skb->data,
-				 bp->rx_buf_use_size, PCI_DMA_FROMDEVICE);
+				 bp->rx_buf_size, PCI_DMA_FROMDEVICE);
 	pci_unmap_addr_set(prod_rx_buf, mapping, mapping);
 
 	/* move partial skb from cons to pool (don't unmap yet) */
@@ -1276,7 +1276,7 @@
 	   pool entry status to BNX2X_TPA_STOP even if new skb allocation
 	   fails. */
 	pci_unmap_single(bp->pdev, pci_unmap_addr(rx_buf, mapping),
-			 bp->rx_buf_use_size, PCI_DMA_FROMDEVICE);
+			 bp->rx_buf_size, PCI_DMA_FROMDEVICE);
 
 	if (likely(new_skb)) {
 		/* fix ip xsum and give it to the stack */
@@ -1520,7 +1520,7 @@
 			} else if (bnx2x_alloc_rx_skb(bp, fp, bd_prod) == 0) {
 				pci_unmap_single(bp->pdev,
 					pci_unmap_addr(rx_buf, mapping),
-						 bp->rx_buf_use_size,
+						 bp->rx_buf_size,
 						 PCI_DMA_FROMDEVICE);
 				skb_reserve(skb, pad);
 				skb_put(skb, len);
@@ -4229,7 +4229,7 @@
 		if (fp->tpa_state[i] == BNX2X_TPA_START)
 			pci_unmap_single(bp->pdev,
 					 pci_unmap_addr(rx_buf, mapping),
-					 bp->rx_buf_use_size,
+					 bp->rx_buf_size,
 					 PCI_DMA_FROMDEVICE);
 
 		dev_kfree_skb(skb);
@@ -4245,15 +4245,14 @@
 	u16 ring_prod, cqe_ring_prod;
 	int i, j;
 
-	bp->rx_buf_use_size = bp->dev->mtu;
-	bp->rx_buf_use_size += bp->rx_offset + ETH_OVREHEAD;
-	bp->rx_buf_size = bp->rx_buf_use_size + 64;
+	bp->rx_buf_size = bp->dev->mtu;
+	bp->rx_buf_size += bp->rx_offset + ETH_OVREHEAD +
+		BCM_RX_ETH_PAYLOAD_ALIGN;
 
 	if (bp->flags & TPA_ENABLE_FLAG) {
 		DP(NETIF_MSG_IFUP,
-		   "rx_buf_use_size %d  rx_buf_size %d  effective_mtu %d\n",
-		   bp->rx_buf_use_size, bp->rx_buf_size,
-		   bp->dev->mtu + ETH_OVREHEAD);
+		   "rx_buf_size %d  effective_mtu %d\n",
+		   bp->rx_buf_size, bp->dev->mtu + ETH_OVREHEAD);
 
 		for_each_queue(bp, j) {
 			struct bnx2x_fastpath *fp = &bp->fp[j];
@@ -4462,9 +4461,10 @@
 		context->ustorm_st_context.common.status_block_id = sb_id;
 		context->ustorm_st_context.common.flags =
 			USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT;
-		context->ustorm_st_context.common.mc_alignment_size = 64;
+		context->ustorm_st_context.common.mc_alignment_size =
+			BCM_RX_ETH_PAYLOAD_ALIGN;
 		context->ustorm_st_context.common.bd_buff_size =
-						bp->rx_buf_use_size;
+						bp->rx_buf_size;
 		context->ustorm_st_context.common.bd_page_base_hi =
 						U64_HI(fp->rx_desc_mapping);
 		context->ustorm_st_context.common.bd_page_base_lo =
@@ -4717,7 +4717,7 @@
 	}
 
 	/* Init CQ ring mapping and aggregation size */
-	max_agg_size = min((u32)(bp->rx_buf_use_size +
+	max_agg_size = min((u32)(bp->rx_buf_size +
 				 8*BCM_PAGE_SIZE*PAGES_PER_SGE),
 			   (u32)0xffff);
 	for_each_queue(bp, i) {
@@ -5940,7 +5940,7 @@
 
 			pci_unmap_single(bp->pdev,
 					 pci_unmap_addr(rx_buf, mapping),
-					 bp->rx_buf_use_size,
+					 bp->rx_buf_size,
 					 PCI_DMA_FROMDEVICE);
 
 			rx_buf->skb = NULL;
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index ea6144a..5890a91 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -194,6 +194,12 @@
 #define CIRRUS_DEFAULT_IRQ	VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* Event inputs bank 1 - ID 35/bit 3 */
 static unsigned int netcard_portlist[] __used __initdata = {CIRRUS_DEFAULT_BASE, 0};
 static unsigned int cs8900_irq_map[] = {CIRRUS_DEFAULT_IRQ, 0, 0, 0};
+#elif defined(CONFIG_MACH_MX31ADS)
+#include <mach/board-mx31ads.h>
+static unsigned int netcard_portlist[] __used __initdata = {
+	PBC_BASE_ADDRESS + PBC_CS8900A_IOBASE + 0x300, 0
+};
+static unsigned cs8900_irq_map[] = {EXPIO_INT_ENET_INT, 0, 0, 0};
 #else
 static unsigned int netcard_portlist[] __used __initdata =
    { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
@@ -802,7 +808,7 @@
 	} else {
 		i = lp->isa_config & INT_NO_MASK;
 		if (lp->chip_type == CS8900) {
-#if defined(CONFIG_MACH_IXDP2351) || defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX010X)
+#ifdef CONFIG_CS89x0_NONISA_IRQ
 		        i = cs8900_irq_map[0];
 #else
 			/* Translate the IRQ using the IRQ mapping table. */
@@ -1029,6 +1035,7 @@
 
 void  __init reset_chip(struct net_device *dev)
 {
+#if !defined(CONFIG_MACH_MX31ADS)
 #if !defined(CONFIG_MACH_IXDP2351) && !defined(CONFIG_ARCH_IXDP2X01)
 	struct net_local *lp = netdev_priv(dev);
 	int ioaddr = dev->base_addr;
@@ -1057,6 +1064,7 @@
 	reset_start_time = jiffies;
 	while( (readreg(dev, PP_SelfST) & INIT_DONE) == 0 && jiffies - reset_start_time < 2)
 		;
+#endif /* !CONFIG_MACH_MX31ADS */
 }
 
 
@@ -1304,7 +1312,7 @@
 	else
 #endif
 	{
-#if !defined(CONFIG_MACH_IXDP2351) && !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX010X)
+#ifndef CONFIG_CS89x0_NONISA_IRQ
 		if (((1 << dev->irq) & lp->irq_map) == 0) {
 			printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
                                dev->name, dev->irq, lp->irq_map);
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 331b86b..0b6ecef 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -5975,10 +5975,12 @@
 	if (netif_running(dev))
 		nv_close(dev);
 
-	pci_enable_wake(pdev, PCI_D3hot, np->wolenabled);
-	pci_enable_wake(pdev, PCI_D3cold, np->wolenabled);
 	pci_disable_device(pdev);
-	pci_set_power_state(pdev, PCI_D3hot);
+	if (system_state == SYSTEM_POWER_OFF) {
+		if (pci_enable_wake(pdev, PCI_D3cold, np->wolenabled))
+			pci_enable_wake(pdev, PCI_D3hot, np->wolenabled);
+		pci_set_power_state(pdev, PCI_D3hot);
+	}
 }
 #else
 #define nv_suspend NULL
diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c
index 8239939..fbbd3e6 100644
--- a/drivers/net/hp-plus.c
+++ b/drivers/net/hp-plus.c
@@ -139,7 +139,7 @@
 #ifndef MODULE
 struct net_device * __init hp_plus_probe(int unit)
 {
-	struct net_device *dev = alloc_ei_netdev();
+	struct net_device *dev = alloc_eip_netdev();
 	int err;
 
 	if (!dev)
@@ -284,7 +284,7 @@
 	int option_reg;
 	int retval;
 
-	if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) {
+	if ((retval = request_irq(dev->irq, eip_interrupt, 0, dev->name, dev))) {
 	    return retval;
 	}
 
@@ -302,7 +302,7 @@
 	/* Select the operational page. */
 	outw(Perf_Page, ioaddr + HP_PAGING);
 
-	ei_open(dev);
+	eip_open(dev);
 	return 0;
 }
 
@@ -313,7 +313,7 @@
 	int option_reg = inw(ioaddr + HPP_OPTION);
 
 	free_irq(dev->irq, dev);
-	ei_close(dev);
+	eip_close(dev);
 	outw((option_reg & ~EnableIRQ) | MemDisable | NICReset | ChipReset,
 		 ioaddr + HPP_OPTION);
 
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 4aa61a1..c5b02b6 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -572,8 +572,8 @@
 	ICCR2 = ICCR2_TXP | ICCR2_TRIG_32;
 
 	/* configure DMAC */
-	DRCMR17 = si->rxdma | DRCMR_MAPVLD;
-	DRCMR18 = si->txdma | DRCMR_MAPVLD;
+	DRCMR(17) = si->rxdma | DRCMR_MAPVLD;
+	DRCMR(18) = si->txdma | DRCMR_MAPVLD;
 
 	/* force SIR reinitialization */
 	si->speed = 4000000;
@@ -602,8 +602,8 @@
 	/* disable the STUART or FICP clocks */
 	pxa_irda_disable_clk(si);
 
-	DRCMR17 = 0;
-	DRCMR18 = 0;
+	DRCMR(17) = 0;
+	DRCMR(18) = 0;
 
 	local_irq_restore(flags);
 
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 53f41b6..a417be7 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -2304,6 +2304,12 @@
 	int vector, v_budget;
 
 	/*
+	 * Set the default interrupt throttle rate.
+	 */
+	adapter->rx_eitr = (1000000 / IXGBE_DEFAULT_ITR_RX_USECS);
+	adapter->tx_eitr = (1000000 / IXGBE_DEFAULT_ITR_TX_USECS);
+
+	/*
 	 * It's easy to be greedy for MSI-X vectors, but it really
 	 * doesn't do us much good if we have a lot more vectors
 	 * than CPU's.  So let's be conservative and only ask for
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 32bb47a..008fd66 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -359,16 +359,6 @@
 	int i, pos;
 	struct pci_dev *pdev;
 
-	pdev = pci_get_device(0x1166, 0x0140, NULL);
-	if (pdev) {
-		pci_dev_put(pdev);
-		adapter->hw_read_wx(adapter,
-			NETXEN_PCIE_REG(PCIE_TGT_SPLIT_CHICKEN), &chicken, 4);
-		chicken |= 0x4000;
-		adapter->hw_write_wx(adapter,
-			NETXEN_PCIE_REG(PCIE_TGT_SPLIT_CHICKEN), &chicken, 4);
-	}
-
 	pdev = adapter->pdev;
 
 	adapter->hw_read_wx(adapter,
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index e4765b7..e3be81e 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -5984,6 +5984,56 @@
 	niu_enable_interrupts(np, 1);
 }
 
+static void niu_reset_buffers(struct niu *np)
+{
+	int i, j, k, err;
+
+	if (np->rx_rings) {
+		for (i = 0; i < np->num_rx_rings; i++) {
+			struct rx_ring_info *rp = &np->rx_rings[i];
+
+			for (j = 0, k = 0; j < MAX_RBR_RING_SIZE; j++) {
+				struct page *page;
+
+				page = rp->rxhash[j];
+				while (page) {
+					struct page *next =
+						(struct page *) page->mapping;
+					u64 base = page->index;
+					base = base >> RBR_DESCR_ADDR_SHIFT;
+					rp->rbr[k++] = cpu_to_le32(base);
+					page = next;
+				}
+			}
+			for (; k < MAX_RBR_RING_SIZE; k++) {
+				err = niu_rbr_add_page(np, rp, GFP_ATOMIC, k);
+				if (unlikely(err))
+					break;
+			}
+
+			rp->rbr_index = rp->rbr_table_size - 1;
+			rp->rcr_index = 0;
+			rp->rbr_pending = 0;
+			rp->rbr_refill_pending = 0;
+		}
+	}
+	if (np->tx_rings) {
+		for (i = 0; i < np->num_tx_rings; i++) {
+			struct tx_ring_info *rp = &np->tx_rings[i];
+
+			for (j = 0; j < MAX_TX_RING_SIZE; j++) {
+				if (rp->tx_buffs[j].skb)
+					(void) release_tx_packet(np, rp, j);
+			}
+
+			rp->pending = MAX_TX_RING_SIZE;
+			rp->prod = 0;
+			rp->cons = 0;
+			rp->wrap_bit = 0;
+		}
+	}
+}
+
 static void niu_reset_task(struct work_struct *work)
 {
 	struct niu *np = container_of(work, struct niu, reset_task);
@@ -6006,6 +6056,12 @@
 
 	niu_stop_hw(np);
 
+	spin_unlock_irqrestore(&np->lock, flags);
+
+	niu_reset_buffers(np);
+
+	spin_lock_irqsave(&np->lock, flags);
+
 	err = niu_init_hw(np);
 	if (!err) {
 		np->timer.expires = jiffies + HZ;
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 3f682d4..52bf11b 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -784,6 +784,7 @@
 	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEther PCC-TXD", 0x5261440f, 0x436768c5),
 	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEtherII PCC-TXD", 0x5261440f, 0x730df72e),
 	PCMCIA_DEVICE_PROD_ID12("Dynalink", "L100C16", 0x55632fd5, 0x66bc2a90),
+	PCMCIA_DEVICE_PROD_ID12("IO DATA", "ETXPCM", 0x547e66dc, 0x233adac2),
 	PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V3)", 0x0733cc81, 0x232019a8),
 	PCMCIA_DEVICE_PROD_ID12("MELCO", "LPC3-TX", 0x481e0094, 0xf91af609),
 	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "100BASE", 0x281f1c5d, 0x7c2add04),
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 2d4c4ad..ebc1ae6 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -1626,6 +1626,7 @@
 	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-TD", 0x5261440f, 0xc49bd73d),
 	PCMCIA_DEVICE_PROD_ID12("Corega K.K.", "corega EtherII PCC-TD", 0xd4fdcbd8, 0xc49bd73d),
 	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega Ether PCC-T", 0x5261440f, 0x6705fcaa),
+	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega Ether PCC-TD", 0x5261440f, 0x47d5ca83),
 	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FastEther PCC-TX", 0x5261440f, 0x485e85d9),
 	PCMCIA_DEVICE_PROD_ID12("Corega,K.K.", "Ethernet LAN Card", 0x110d26d9, 0x9fd2f0a2),
 	PCMCIA_DEVICE_PROD_ID12("corega,K.K.", "Ethernet LAN Card", 0x9791a90e, 0x9fd2f0a2),
@@ -1737,7 +1738,6 @@
 	PCMCIA_DEVICE_PROD_ID1("CyQ've 10 Base-T LAN CARD", 0x94faf360),
 	PCMCIA_DEVICE_PROD_ID1("EP-210 PCMCIA LAN CARD.", 0x8850b4de),
 	PCMCIA_DEVICE_PROD_ID1("ETHER-C16", 0x06a8514f),
-	PCMCIA_DEVICE_PROD_ID1("IC-CARD", 0x60cb09a6),
 	PCMCIA_DEVICE_PROD_ID1("NE2000 Compatible", 0x75b8ad5a),
 	PCMCIA_DEVICE_PROD_ID2("EN-6200P2", 0xa996d078),
 	/* too generic! */
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 24768c1..e332a51 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -1520,7 +1520,9 @@
 	/* Setup the default Register Modes */
 	lp->tcr_cur_mode = TCR_DEFAULT;
 	lp->rcr_cur_mode = RCR_DEFAULT;
-	lp->rpc_cur_mode = RPC_DEFAULT;
+	lp->rpc_cur_mode = RPC_DEFAULT |
+				lp->cfg.leda << RPC_LSXA_SHFT |
+				lp->cfg.ledb << RPC_LSXB_SHFT;
 
 	/*
 	 * If we are not using a MII interface, we need to
@@ -2157,6 +2159,11 @@
 		lp->cfg.flags |= (nowait) ? SMC91X_NOWAIT : 0;
 	}
 
+	if (!lp->cfg.leda && !lp->cfg.ledb) {
+		lp->cfg.leda = RPC_LSA_DEFAULT;
+		lp->cfg.ledb = RPC_LSB_DEFAULT;
+	}
+
 	ndev->dma = (unsigned char)-1;
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 997e7f1..160873f 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -43,7 +43,8 @@
 #if defined(CONFIG_ARCH_LUBBOCK) ||\
     defined(CONFIG_MACH_MAINSTONE) ||\
     defined(CONFIG_MACH_ZYLONITE) ||\
-    defined(CONFIG_MACH_LITTLETON)
+    defined(CONFIG_MACH_LITTLETON) ||\
+    defined(CONFIG_ARCH_VIPER)
 
 #include <asm/mach-types.h>
 
@@ -778,14 +779,6 @@
 #define RPC_ANEG	0x0800	// When 1 PHY is in Auto-Negotiate Mode
 #define RPC_LSXA_SHFT	5	// Bits to shift LS2A,LS1A,LS0A to lsb
 #define RPC_LSXB_SHFT	2	// Bits to get LS2B,LS1B,LS0B to lsb
-#define RPC_LED_100_10	(0x00)	// LED = 100Mbps OR's with 10Mbps link detect
-#define RPC_LED_RES	(0x01)	// LED = Reserved
-#define RPC_LED_10	(0x02)	// LED = 10Mbps link detect
-#define RPC_LED_FD	(0x03)	// LED = Full Duplex Mode
-#define RPC_LED_TX_RX	(0x04)	// LED = TX or RX packet occurred
-#define RPC_LED_100	(0x05)	// LED = 100Mbps link dectect
-#define RPC_LED_TX	(0x06)	// LED = TX packet occurred
-#define RPC_LED_RX	(0x07)	// LED = RX packet occurred
 
 #ifndef RPC_LSA_DEFAULT
 #define RPC_LSA_DEFAULT	RPC_LED_100
@@ -794,7 +787,7 @@
 #define RPC_LSB_DEFAULT RPC_LED_FD
 #endif
 
-#define RPC_DEFAULT (RPC_ANEG | (RPC_LSA_DEFAULT << RPC_LSXA_SHFT) | (RPC_LSB_DEFAULT << RPC_LSXB_SHFT) | RPC_SPEED | RPC_DPLX)
+#define RPC_DEFAULT (RPC_ANEG | RPC_SPEED | RPC_DPLX)
 
 
 /* Bank 0 0x0C is reserved */
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index a84ba48..8c19307 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -117,7 +117,7 @@
 	case -ENOENT:
 		break;
 	default:
-		if (netif_msg_drv(pegasus))
+		if (netif_msg_drv(pegasus) && printk_ratelimit())
 			dev_dbg(&pegasus->intf->dev, "%s, status %d\n",
 				__FUNCTION__, urb->status);
 	}
@@ -166,7 +166,7 @@
 		set_current_state(TASK_RUNNING);
 		if (ret == -ENODEV)
 			netif_device_detach(pegasus->net);
-		if (netif_msg_drv(pegasus))
+		if (netif_msg_drv(pegasus) && printk_ratelimit())
 			dev_err(&pegasus->intf->dev, "%s, status %d\n",
 					__FUNCTION__, ret);
 		goto out;
@@ -275,7 +275,7 @@
 	if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) {
 		if (ret == -ENODEV)
 			netif_device_detach(pegasus->net);
-		if (netif_msg_drv(pegasus))
+		if (netif_msg_drv(pegasus) && printk_ratelimit())
 			dev_err(&pegasus->intf->dev, "%s, status %d\n",
 					__FUNCTION__, ret);
 		goto out;
@@ -1209,8 +1209,7 @@
 		pegasus->eth_regs[EthCtrl2] |= RX_PROMISCUOUS;
 		if (netif_msg_link(pegasus))
 			pr_info("%s: Promiscuous mode enabled.\n", net->name);
-	} else if (net->mc_count ||
-		   (net->flags & IFF_ALLMULTI)) {
+	} else if (net->mc_count || (net->flags & IFF_ALLMULTI)) {
 		pegasus->eth_regs[EthCtrl0] |= RX_MULTICAST;
 		pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;
 		if (netif_msg_link(pegasus))
@@ -1220,6 +1219,8 @@
 		pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;
 	}
 
+	pegasus->ctrl_urb->status = 0;
+
 	pegasus->flags |= ETH_REGS_CHANGE;
 	ctrl_callback(pegasus->ctrl_urb);
 }
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
index caf5694..00a0eaa 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -209,6 +209,7 @@
 	unsigned int curlen;
 	struct ath_txq *cabq;
 	struct ath_txq *mcastq;
+	struct ieee80211_tx_info *info;
 	avp = sc->sc_vaps[if_id];
 
 	mcastq = &avp->av_mcastq;
@@ -232,6 +233,18 @@
 	 */
 	curlen = skb->len;
 
+	info = IEEE80211_SKB_CB(skb);
+	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+		/*
+		 * TODO: make sure the seq# gets assigned properly (vs. other
+		 * TX frames)
+		 */
+		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+		sc->seq_no += 0x10;
+		hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+		hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
+	}
+
 	/* XXX: spin_lock_bh should not be used here, but sparse bitches
 	 * otherwise. We should fix sparse :) */
 	spin_lock_bh(&mcastq->axq_lock);
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
index 673b3d8..4ee695b 100644
--- a/drivers/net/wireless/ath9k/core.h
+++ b/drivers/net/wireless/ath9k/core.h
@@ -992,6 +992,7 @@
 	u32 sc_txintrperiod;	/* tx interrupt batching */
 	int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME	AC -> h/w qnum */
 	u32 sc_ant_tx[8];	/* recent tx frames/antenna */
+	u16 seq_no; /* TX sequence number */
 
 	/* Beacon */
 	struct ath9k_tx_queue_info sc_beacon_qi;
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 95b3371..99badf1 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -369,6 +369,20 @@
 {
 	struct ath_softc *sc = hw->priv;
 	int hdrlen, padsize;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+	/*
+	 * As a temporary workaround, assign seq# here; this will likely need
+	 * to be cleaned up to work better with Beacon transmission and virtual
+	 * BSSes.
+	 */
+	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+		if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
+			sc->seq_no += 0x10;
+		hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+		hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
+	}
 
 	/* Add the padding after the header if this is not already done */
 	hdrlen = ieee80211_get_hdrlen_from_skb(skb);
@@ -1067,8 +1081,16 @@
 		tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
 		tx_status->flags &= ~ATH_TX_BAR;
 	}
-	if (tx_status->flags)
-		tx_info->status.excessive_retries = 1;
+
+	if (tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY)) {
+		if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
+			/* Frame was not ACKed, but an ACK was expected */
+			tx_info->status.excessive_retries = 1;
+		}
+	} else {
+		/* Frame was ACKed */
+		tx_info->flags |= IEEE80211_TX_STAT_ACK;
+	}
 
 	tx_info->status.retry_count = tx_status->retries;
 
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
index 157f830..550129f 100644
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -357,9 +357,9 @@
 	txctl->flags = ATH9K_TXDESC_CLRDMASK;    /* needed for crypto errors */
 
 	if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
-		tx_info->flags |= ATH9K_TXDESC_NOACK;
+		txctl->flags |= ATH9K_TXDESC_NOACK;
 	if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
-		tx_info->flags |= ATH9K_TXDESC_RTSENA;
+		txctl->flags |= ATH9K_TXDESC_RTSENA;
 
 	/*
 	 * Setup for rate calculations.
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c
index fec5645..34ae125 100644
--- a/drivers/net/wireless/b43/rfkill.c
+++ b/drivers/net/wireless/b43/rfkill.c
@@ -43,23 +43,6 @@
 	return 0;
 }
 
-/* Update the rfkill state */
-static void b43_rfkill_update_state(struct b43_wldev *dev)
-{
-	struct b43_rfkill *rfk = &(dev->wl->rfkill);
-
-	if (!dev->radio_hw_enable) {
-		rfk->rfkill->state = RFKILL_STATE_HARD_BLOCKED;
-		return;
-	}
-
-	if (!dev->phy.radio_on)
-		rfk->rfkill->state = RFKILL_STATE_SOFT_BLOCKED;
-	else
-		rfk->rfkill->state = RFKILL_STATE_UNBLOCKED;
-
-}
-
 /* The poll callback for the hardware button. */
 static void b43_rfkill_poll(struct input_polled_dev *poll_dev)
 {
@@ -77,7 +60,6 @@
 	if (unlikely(enabled != dev->radio_hw_enable)) {
 		dev->radio_hw_enable = enabled;
 		report_change = 1;
-		b43_rfkill_update_state(dev);
 		b43info(wl, "Radio hardware status changed to %s\n",
 			enabled ? "ENABLED" : "DISABLED");
 	}
diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c
index 476add9..b32bf6a 100644
--- a/drivers/net/wireless/b43legacy/rfkill.c
+++ b/drivers/net/wireless/b43legacy/rfkill.c
@@ -44,23 +44,6 @@
 	return 0;
 }
 
-/* Update the rfkill state */
-static void b43legacy_rfkill_update_state(struct b43legacy_wldev *dev)
-{
-	struct b43legacy_rfkill *rfk = &(dev->wl->rfkill);
-
-	if (!dev->radio_hw_enable) {
-		rfk->rfkill->state = RFKILL_STATE_HARD_BLOCKED;
-		return;
-	}
-
-	if (!dev->phy.radio_on)
-		rfk->rfkill->state = RFKILL_STATE_SOFT_BLOCKED;
-	else
-		rfk->rfkill->state = RFKILL_STATE_UNBLOCKED;
-
-}
-
 /* The poll callback for the hardware button. */
 static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev)
 {
@@ -78,7 +61,6 @@
 	if (unlikely(enabled != dev->radio_hw_enable)) {
 		dev->radio_hw_enable = enabled;
 		report_change = 1;
-		b43legacy_rfkill_update_state(dev);
 		b43legacyinfo(wl, "Radio hardware status changed to %s\n",
 			enabled ? "ENABLED" : "DISABLED");
 	}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 754fef5..90a2b6d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -1153,7 +1153,8 @@
 	    !sta->ht_info.ht_supported)
 		return -1;
 
-	if (priv->current_ht_config.tx_mimo_ps_mode == IWL_MIMO_PS_STATIC)
+	if (((sta->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS) >> 2)
+						== IWL_MIMO_PS_STATIC)
 		return -1;
 
 	/* Need both Tx chains/antennas to support MIMO */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index c0b73c4..e01f048 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -181,14 +181,14 @@
 }
 
 /**
- * iwl4965_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
+ * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
  * @priv: staging_rxon is compared to active_rxon
  *
  * If the RXON structure is changing enough to require a new tune,
  * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
  * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
  */
-static int iwl4965_full_rxon_required(struct iwl_priv *priv)
+static int iwl_full_rxon_required(struct iwl_priv *priv)
 {
 
 	/* These items are only settable from the full RXON command */
@@ -207,7 +207,6 @@
 	     priv->active_rxon.ofdm_ht_single_stream_basic_rates) ||
 	    (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates !=
 	     priv->active_rxon.ofdm_ht_dual_stream_basic_rates) ||
-	    (priv->staging_rxon.rx_chain != priv->active_rxon.rx_chain) ||
 	    (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
 		return 1;
 
@@ -263,7 +262,7 @@
 	/* If we don't need to send a full RXON, we can use
 	 * iwl4965_rxon_assoc_cmd which is used to reconfigure filter
 	 * and other flags for the current radio configuration. */
-	if (!iwl4965_full_rxon_required(priv)) {
+	if (!iwl_full_rxon_required(priv)) {
 		ret = iwl_send_rxon_assoc(priv);
 		if (ret) {
 			IWL_ERROR("Error setting RXON_ASSOC (%d)\n", ret);
@@ -587,8 +586,6 @@
 		iwl_conf->supported_chan_width = 0;
 	}
 
-	iwl_conf->tx_mimo_ps_mode =
-		(u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
 	memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16);
 
 	iwl_conf->control_channel = ht_bss_conf->primary_channel;
@@ -2190,7 +2187,10 @@
 	udelay(5);
 
 	/* FIXME: apm_ops.suspend(priv) */
-	priv->cfg->ops->lib->apm_ops.reset(priv);
+	if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status))
+		priv->cfg->ops->lib->apm_ops.stop(priv);
+	else
+		priv->cfg->ops->lib->apm_ops.reset(priv);
 	priv->cfg->ops->lib->free_shared_mem(priv);
 
  exit:
@@ -3588,7 +3588,7 @@
 
 	priv->assoc_id = 0;
 	timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
-	priv->timestamp = le64_to_cpu(timestamp) +  (priv->beacon_int * 1000);
+	priv->timestamp = le64_to_cpu(timestamp);
 
 	IWL_DEBUG_MAC80211("leave\n");
 	spin_unlock_irqrestore(&priv->lock, flags);
@@ -4372,15 +4372,18 @@
 	iwl_dbgfs_unregister(priv);
 	sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);
 
+	/* ieee80211_unregister_hw call wil cause iwl4965_mac_stop to
+	 * to be called and iwl4965_down since we are removing the device
+	 * we need to set STATUS_EXIT_PENDING bit.
+	 */
+	set_bit(STATUS_EXIT_PENDING, &priv->status);
 	if (priv->mac80211_registered) {
 		ieee80211_unregister_hw(priv->hw);
 		priv->mac80211_registered = 0;
+	} else {
+		iwl4965_down(priv);
 	}
 
-	set_bit(STATUS_EXIT_PENDING, &priv->status);
-
-	iwl4965_down(priv);
-
 	/* make sure we flush any pending irq or
 	 * tasklet for the driver
 	 */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index c72f725..80f2f84 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -592,12 +592,11 @@
 	clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
 }
 
-static u8 is_single_rx_stream(struct iwl_priv *priv)
+static bool is_single_rx_stream(struct iwl_priv *priv)
 {
 	return !priv->current_ht_config.is_ht ||
 	       ((priv->current_ht_config.supp_mcs_set[1] == 0) &&
-		(priv->current_ht_config.supp_mcs_set[2] == 0)) ||
-	       priv->ps_mode == IWL_MIMO_PS_STATIC;
+		(priv->current_ht_config.supp_mcs_set[2] == 0));
 }
 
 static u8 iwl_is_channel_extension(struct iwl_priv *priv,
@@ -704,33 +703,39 @@
  * MIMO (dual stream) requires at least 2, but works better with 3.
  * This does not determine *which* chains to use, just how many.
  */
-static int iwlcore_get_rx_chain_counter(struct iwl_priv *priv,
-					u8 *idle_state, u8 *rx_state)
+static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
 {
-	u8 is_single = is_single_rx_stream(priv);
-	u8 is_cam = test_bit(STATUS_POWER_PMI, &priv->status) ? 0 : 1;
+	bool is_single = is_single_rx_stream(priv);
+	bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
 
 	/* # of Rx chains to use when expecting MIMO. */
 	if (is_single || (!is_cam && (priv->ps_mode == IWL_MIMO_PS_STATIC)))
-		*rx_state = 2;
+		return 2;
 	else
-		*rx_state = 3;
+		return 3;
+}
 
+static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
+{
+	int idle_cnt;
+	bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
 	/* # Rx chains when idling and maybe trying to save power */
 	switch (priv->ps_mode) {
 	case IWL_MIMO_PS_STATIC:
 	case IWL_MIMO_PS_DYNAMIC:
-		*idle_state = (is_cam) ? 2 : 1;
+		idle_cnt = (is_cam) ? 2 : 1;
 		break;
 	case IWL_MIMO_PS_NONE:
-		*idle_state = (is_cam) ? *rx_state : 1;
+		idle_cnt = (is_cam) ? active_cnt : 1;
 		break;
+	case IWL_MIMO_PS_INVALID:
 	default:
-		*idle_state = 1;
+		IWL_ERROR("invalide mimo ps mode %d\n", priv->ps_mode);
+		WARN_ON(1);
+		idle_cnt = -1;
 		break;
 	}
-
-	return 0;
+	return idle_cnt;
 }
 
 /**
@@ -741,34 +746,44 @@
  */
 void iwl_set_rxon_chain(struct iwl_priv *priv)
 {
-	u8 is_single = is_single_rx_stream(priv);
-	u8 idle_state, rx_state;
-
-	priv->staging_rxon.rx_chain = 0;
-	rx_state = idle_state = 3;
+	bool is_single = is_single_rx_stream(priv);
+	bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
+	u8 idle_rx_cnt, active_rx_cnt;
+	u16 rx_chain;
 
 	/* Tell uCode which antennas are actually connected.
 	 * Before first association, we assume all antennas are connected.
 	 * Just after first association, iwl_chain_noise_calibration()
 	 *    checks which antennas actually *are* connected. */
-	priv->staging_rxon.rx_chain |=
-		    cpu_to_le16(priv->hw_params.valid_rx_ant <<
-						 RXON_RX_CHAIN_VALID_POS);
+	rx_chain = priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
 
 	/* How many receivers should we use? */
-	iwlcore_get_rx_chain_counter(priv, &idle_state, &rx_state);
-	priv->staging_rxon.rx_chain |=
-		cpu_to_le16(rx_state << RXON_RX_CHAIN_MIMO_CNT_POS);
-	priv->staging_rxon.rx_chain |=
-		cpu_to_le16(idle_state << RXON_RX_CHAIN_CNT_POS);
+	active_rx_cnt = iwl_get_active_rx_chain_count(priv);
+	idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt);
 
-	if (!is_single && (rx_state >= 2) &&
-	    !test_bit(STATUS_POWER_PMI, &priv->status))
+	/* correct rx chain count accoridng hw settings */
+	if (priv->hw_params.rx_chains_num < active_rx_cnt)
+		active_rx_cnt = priv->hw_params.rx_chains_num;
+
+	if (priv->hw_params.rx_chains_num < idle_rx_cnt)
+		idle_rx_cnt = priv->hw_params.rx_chains_num;
+
+	rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
+	rx_chain |= idle_rx_cnt  << RXON_RX_CHAIN_CNT_POS;
+
+	priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain);
+
+	if (!is_single && (active_rx_cnt >= 2) && is_cam)
 		priv->staging_rxon.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
 	else
 		priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
 
-	IWL_DEBUG_ASSOC("rx chain %X\n", priv->staging_rxon.rx_chain);
+	IWL_DEBUG_ASSOC("rx_chain=0x%Xi active=%d idle=%d\n",
+			priv->staging_rxon.rx_chain,
+			active_rx_cnt, idle_rx_cnt);
+
+	WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 ||
+		active_rx_cnt < idle_rx_cnt);
 }
 EXPORT_SYMBOL(iwl_set_rxon_chain);
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index c19db43..cdfb343 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -412,7 +412,6 @@
 	/* self configuration data */
 	u8 is_ht;
 	u8 supported_chan_width;
-	u16 tx_mimo_ps_mode;
 	u8 is_green_field;
 	u8 sgf;			/* HT_SHORT_GI_* short guard interval */
 	u8 max_amsdu_size;
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index f3f6ea4..e81bfc4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -1173,7 +1173,10 @@
 
 	rx_status.antenna = 0;
 	rx_status.flag = 0;
-	rx_status.flag |= RX_FLAG_TSFT;
+
+	/* TSF isn't reliable. In order to allow smooth user experience,
+	 * this W/A doesn't propagate it to the mac80211 */
+	/*rx_status.flag |= RX_FLAG_TSFT;*/
 
 	if ((unlikely(rx_start->cfg_phy_cnt > 20))) {
 		IWL_DEBUG_DROP("dsp size out of range [0,20]: %d/n",
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 9bb6adb..6c8ac3a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -421,7 +421,7 @@
 		else
 			scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
 
-		if ((scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) && n_probes)
+		if (n_probes)
 			scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
 
 		scan_ch->active_dwell = cpu_to_le16(active_dwell);
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index ff879d4..78b1a7a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -402,12 +402,11 @@
 /**
  * iwl_tx_queue_init - Allocate and initialize one tx/cmd queue
  */
-static int iwl_tx_queue_init(struct iwl_priv *priv,
-			     struct iwl_tx_queue *txq,
+static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
 			     int slots_num, u32 txq_id)
 {
 	int i, len;
-	int rc = 0;
+	int ret;
 
 	/*
 	 * Alloc buffer array for commands (Tx or other types of commands).
@@ -428,17 +427,14 @@
 
 		txq->cmd[i] = kmalloc(len, GFP_KERNEL);
 		if (!txq->cmd[i])
-			return -ENOMEM;
+			goto err;
 	}
 
 	/* Alloc driver data array and TFD circular buffer */
-	rc = iwl_tx_queue_alloc(priv, txq, txq_id);
-	if (rc) {
-		for (i = 0; i < slots_num; i++)
-			kfree(txq->cmd[i]);
+	ret = iwl_tx_queue_alloc(priv, txq, txq_id);
+	if (ret)
+		goto err;
 
-		return -ENOMEM;
-	}
 	txq->need_update = 0;
 
 	/* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
@@ -452,6 +448,17 @@
 	iwl_hw_tx_queue_init(priv, txq);
 
 	return 0;
+err:
+	for (i = 0; i < slots_num; i++) {
+		kfree(txq->cmd[i]);
+		txq->cmd[i] = NULL;
+	}
+
+	if (txq_id == IWL_CMD_QUEUE_NUM) {
+		kfree(txq->cmd[slots_num]);
+		txq->cmd[slots_num] = NULL;
+	}
+	return -ENOMEM;
 }
 /**
  * iwl_hw_txq_ctx_free - Free TXQ Context
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
index 40337a0..146ca9c 100644
--- a/drivers/pci/hotplug/fakephp.c
+++ b/drivers/pci/hotplug/fakephp.c
@@ -320,15 +320,15 @@
 			return -ENODEV;
 		}
 
+		/* remove the device from the pci core */
+		pci_remove_bus_device(dev);
+
 		/* queue work item to blow away this sysfs entry and other
 		 * parts.
 		 */
 		INIT_WORK(&dslot->remove_work, remove_slot_worker);
 		queue_work(dummyphp_wq, &dslot->remove_work);
 
-		/* blow away this sysfs entry and other parts. */
-		remove_slot(dslot);
-
 		pci_dev_put(dev);
 	}
 	return 0;
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index ab31f5b..9d934dd 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -258,7 +258,7 @@
 			return 1;
 		}
 	}
-	while (timeout > 1000) {
+	while (timeout > 0) {
 		msleep(10);
 		timeout -= 10;
 		if (!pciehp_readw(ctrl, SLOTSTATUS, &slot_status)) {
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 8d0e60a..c3edcdc 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -2348,11 +2348,34 @@
 
 }
 
+static int blacklist_iommu(const struct dmi_system_id *id)
+{
+	printk(KERN_INFO "%s detected; disabling IOMMU\n",
+	       id->ident);
+	dmar_disabled = 1;
+	return 0;
+}
+
+static struct dmi_system_id __initdata intel_iommu_dmi_table[] = {
+	{	/* Some DG33BU BIOS revisions advertised non-existent VT-d */
+		.callback = blacklist_iommu,
+		.ident = "Intel DG33BU",
+		{	DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
+			DMI_MATCH(DMI_BOARD_NAME, "DG33BU"),
+		}
+	},
+	{ }
+};
+
+
 void __init detect_intel_iommu(void)
 {
 	if (swiotlb || no_iommu || iommu_detected || dmar_disabled)
 		return;
 	if (early_dmar_detect()) {
+		dmi_check_system(intel_iommu_dmi_table);
+		if (dmar_disabled)
+			return;
 		iommu_detected = 1;
 	}
 }
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index cce2f4c..36698e57b 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -304,6 +304,9 @@
 		} else {
 			res->start = l64;
 			res->end = l64 + sz64;
+			printk(KERN_DEBUG "PCI: %s reg %x 64bit mmio: [%llx, %llx]\n",
+				pci_name(dev), pos, (unsigned long long)res->start,
+				(unsigned long long)res->end);
 		}
 	} else {
 		sz = pci_size(l, sz, mask);
@@ -313,6 +316,9 @@
 
 		res->start = l;
 		res->end = l + sz;
+		printk(KERN_DEBUG "PCI: %s reg %x %s: [%llx, %llx]\n", pci_name(dev),
+			pos, (res->flags & IORESOURCE_IO) ? "io port":"32bit mmio",
+			(unsigned long long)res->start, (unsigned long long)res->end);
 	}
 
  out:
@@ -383,7 +389,9 @@
 			res->start = base;
 		if (!res->end)
 			res->end = limit + 0xfff;
-		printk(KERN_INFO "PCI: bridge %s io port: [%llx, %llx]\n", pci_name(dev), res->start, res->end);
+		printk(KERN_DEBUG "PCI: bridge %s io port: [%llx, %llx]\n",
+			pci_name(dev), (unsigned long long) res->start,
+			(unsigned long long) res->end);
 	}
 
 	res = child->resource[1];
@@ -395,7 +403,9 @@
 		res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
 		res->start = base;
 		res->end = limit + 0xfffff;
-		printk(KERN_INFO "PCI: bridge %s 32bit mmio: [%llx, %llx]\n", pci_name(dev), res->start, res->end);
+		printk(KERN_DEBUG "PCI: bridge %s 32bit mmio: [%llx, %llx]\n",
+			pci_name(dev), (unsigned long long) res->start,
+			(unsigned long long) res->end);
 	}
 
 	res = child->resource[2];
@@ -431,7 +441,9 @@
 		res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
 		res->start = base;
 		res->end = limit + 0xfffff;
-		printk(KERN_INFO "PCI: bridge %s %sbit mmio pref: [%llx, %llx]\n", pci_name(dev), (res->flags & PCI_PREF_RANGE_TYPE_64)?"64":"32",res->start, res->end);
+		printk(KERN_DEBUG "PCI: bridge %s %sbit mmio pref: [%llx, %llx]\n",
+			pci_name(dev), (res->flags & PCI_PREF_RANGE_TYPE_64) ? "64" : "32",
+			(unsigned long long) res->start, (unsigned long long) res->end);
 	}
 }
 
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 82634a2..3abbfad 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -352,11 +352,12 @@
 				continue;
 			r_size = r->end - r->start + 1;
 			/* For bridges size != alignment */
-			align = (i < PCI_BRIDGE_RESOURCES) ? r_size : r->start;
+			align = resource_alignment(r);
 			order = __ffs(align) - 20;
 			if (order > 11) {
-				dev_warn(&dev->dev, "BAR %d too large: "
+				dev_warn(&dev->dev, "BAR %d bad alignment %llx: "
 				       "%#016llx-%#016llx\n", i,
+				       (unsigned long long)align,
 				       (unsigned long long)r->start,
 				       (unsigned long long)r->end);
 				r->flags = 0;
@@ -539,7 +540,11 @@
                 if (!res)
                         continue;
 
-		printk(KERN_INFO "bus: %02x index %x %s: [%llx, %llx]\n", bus->number, i, (res->flags & IORESOURCE_IO)? "io port":"mmio", res->start, res->end);
+		printk(KERN_INFO "bus: %02x index %x %s: [%llx, %llx]\n",
+			bus->number, i,
+			(res->flags & IORESOURCE_IO) ? "io port" : "mmio",
+			(unsigned long long) res->start,
+			(unsigned long long) res->end);
         }
 }
 
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index e0f8840..f57eeae 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -220,7 +220,8 @@
 	tristate "PXA2xx support"
 	depends on ARM && ARCH_PXA && PCMCIA
 	depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \
-		    || MACH_ARMCORE || ARCH_PXA_PALM)
+		    || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \
+		    || ARCH_VIPER)
 	help
 	  Say Y here to include support for the PXA2xx PCMCIA controller
 
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 269a9e9..a87902d 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -29,7 +29,6 @@
 obj-$(CONFIG_HD64465_PCMCIA)			+= hd64465_ss.o
 obj-$(CONFIG_PCMCIA_SA1100)			+= sa11xx_core.o sa1100_cs.o
 obj-$(CONFIG_PCMCIA_SA1111)			+= sa11xx_core.o sa1111_cs.o
-obj-$(CONFIG_PCMCIA_PXA2XX)                     += pxa2xx_core.o pxa2xx_cs.o
 obj-$(CONFIG_M32R_PCC)				+= m32r_pcc.o
 obj-$(CONFIG_M32R_CFC)				+= m32r_cfc.o
 obj-$(CONFIG_PCMCIA_AU1X00)			+= au1x00_ss.o
@@ -68,9 +67,14 @@
 sa1100_cs-$(CONFIG_SA1100_SHANNON)		+= sa1100_shannon.o
 sa1100_cs-$(CONFIG_SA1100_SIMPAD)		+= sa1100_simpad.o
 
-pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK)		+= pxa2xx_lubbock.o sa1111_generic.o
-pxa2xx_cs-$(CONFIG_MACH_MAINSTONE)		+= pxa2xx_mainstone.o
-pxa2xx_cs-$(CONFIG_PXA_SHARPSL)			+= pxa2xx_sharpsl.o
-pxa2xx_cs-$(CONFIG_MACH_ARMCORE)		+= pxa2xx_cm_x270.o
-pxa2xx_cs-$(CONFIG_MACH_PALMTX)		+= pxa2xx_palmtx.o
+pxa2xx_lubbock_cs-y				+= pxa2xx_lubbock.o sa1111_generic.o
+pxa2xx-obj-$(CONFIG_ARCH_LUBBOCK)		+= pxa2xx_lubbock_cs.o
+pxa2xx-obj-$(CONFIG_MACH_MAINSTONE)		+= pxa2xx_mainstone.o
+pxa2xx-obj-$(CONFIG_PXA_SHARPSL)		+= pxa2xx_sharpsl.o
+pxa2xx-obj-$(CONFIG_MACH_ARMCORE)		+= pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o
+pxa2xx-obj-$(CONFIG_ARCH_VIPER)			+= pxa2xx_viper.o
+pxa2xx-obj-$(CONFIG_TRIZEPS_PCMCIA)		+= pxa2xx_trizeps.o
+pxa2xx-obj-$(CONFIG_MACH_PALMTX)		+= pxa2xx_palmtx.o
+pxa2xx-obj-$(CONFIG_MACH_PALMLD)		+= pxa2xx_palmld.o
 
+obj-$(CONFIG_PCMCIA_PXA2XX)			+= pxa2xx_core.o $(pxa2xx-obj-y)
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index 1b07af5..13f1e0f 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -30,6 +30,7 @@
 #include <asm/system.h>
 #include <mach/pxa-regs.h>
 #include <mach/pxa2xx-regs.h>
+#include <asm/mach-types.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
@@ -166,18 +167,32 @@
 }
 #endif
 
+static void pxa2xx_configure_sockets(struct device *dev)
+{
+	struct pcmcia_low_level *ops = dev->platform_data;
+
+	/*
+	 * We have at least one socket, so set MECR:CIT
+	 * (Card Is There)
+	 */
+	MECR |= MECR_CIT;
+
+	/* Set MECR:NOS (Number Of Sockets) */
+	if (ops->nr > 1 || machine_is_viper())
+		MECR |= MECR_NOS;
+	else
+		MECR &= ~MECR_NOS;
+}
+
 int __pxa2xx_drv_pcmcia_probe(struct device *dev)
 {
 	int ret;
 	struct pcmcia_low_level *ops;
-	int first, nr;
 
 	if (!dev || !dev->platform_data)
 		return -ENODEV;
 
 	ops = (struct pcmcia_low_level *)dev->platform_data;
-	first = ops->first;
-	nr = ops->nr;
 
 	/* Provide our PXA2xx specific timing routines. */
 	ops->set_timing  = pxa2xx_pcmcia_set_timing;
@@ -185,21 +200,10 @@
 	ops->frequency_change = pxa2xx_pcmcia_frequency_change;
 #endif
 
-	ret = soc_common_drv_pcmcia_probe(dev, ops, first, nr);
+	ret = soc_common_drv_pcmcia_probe(dev, ops, ops->first, ops->nr);
 
-	if (ret == 0) {
-		/*
-		 * We have at least one socket, so set MECR:CIT
-		 * (Card Is There)
-		 */
-		MECR |= MECR_CIT;
-
-		/* Set MECR:NOS (Number Of Sockets) */
-		if (nr > 1)
-			MECR |= MECR_NOS;
-		else
-			MECR &= ~MECR_NOS;
-	}
+	if (!ret)
+		pxa2xx_configure_sockets(dev);
 
 	return ret;
 }
@@ -223,11 +227,7 @@
 
 static int pxa2xx_drv_pcmcia_resume(struct platform_device *dev)
 {
-	struct pcmcia_low_level *ops = dev->dev.platform_data;
-	int nr = ops ? ops->nr : 0;
-
-	MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0);
-
+	pxa2xx_configure_sockets(&dev->dev);
 	return pcmcia_socket_dev_resume(&dev->dev);
 }
 
diff --git a/drivers/pcmcia/pxa2xx_cm_x255.c b/drivers/pcmcia/pxa2xx_cm_x255.c
new file mode 100644
index 0000000..7c8bcb4
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_cm_x255.c
@@ -0,0 +1,154 @@
+/*
+ * linux/drivers/pcmcia/pxa/pxa_cm_x255.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Compulab Ltd., 2003, 2007, 2008
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <mach/pxa-regs.h>
+
+#include "soc_common.h"
+
+#define GPIO_PCMCIA_SKTSEL	(54)
+#define GPIO_PCMCIA_S0_CD_VALID	(16)
+#define GPIO_PCMCIA_S1_CD_VALID	(17)
+#define GPIO_PCMCIA_S0_RDYINT	(6)
+#define GPIO_PCMCIA_S1_RDYINT	(8)
+#define GPIO_PCMCIA_RESET	(9)
+
+#define PCMCIA_S0_CD_VALID	IRQ_GPIO(GPIO_PCMCIA_S0_CD_VALID)
+#define PCMCIA_S1_CD_VALID	IRQ_GPIO(GPIO_PCMCIA_S1_CD_VALID)
+#define PCMCIA_S0_RDYINT	IRQ_GPIO(GPIO_PCMCIA_S0_RDYINT)
+#define PCMCIA_S1_RDYINT	IRQ_GPIO(GPIO_PCMCIA_S1_RDYINT)
+
+
+static struct pcmcia_irqs irqs[] = {
+	{ 0, PCMCIA_S0_CD_VALID, "PCMCIA0 CD" },
+	{ 1, PCMCIA_S1_CD_VALID, "PCMCIA1 CD" },
+};
+
+static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+	int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
+	if (ret)
+		return ret;
+	gpio_direction_output(GPIO_PCMCIA_RESET, 0);
+
+	skt->irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT;
+	ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+	if (!ret)
+		gpio_free(GPIO_PCMCIA_RESET);
+
+	return ret;
+}
+
+static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
+{
+	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+	gpio_free(GPIO_PCMCIA_RESET);
+}
+
+
+static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
+				       struct pcmcia_state *state)
+{
+	int cd = skt->nr ? GPIO_PCMCIA_S1_CD_VALID : GPIO_PCMCIA_S0_CD_VALID;
+	int rdy = skt->nr ? GPIO_PCMCIA_S0_RDYINT : GPIO_PCMCIA_S1_RDYINT;
+
+	state->detect = !gpio_get_value(cd);
+	state->ready  = !!gpio_get_value(rdy);
+	state->bvd1   = 1;
+	state->bvd2   = 1;
+	state->vs_3v  = 0;
+	state->vs_Xv  = 0;
+	state->wrprot = 0;  /* not available */
+}
+
+
+static int cmx255_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+					  const socket_state_t *state)
+{
+	switch (skt->nr) {
+	case 0:
+		if (state->flags & SS_RESET) {
+			gpio_set_value(GPIO_PCMCIA_SKTSEL, 0);
+			udelay(1);
+			gpio_set_value(GPIO_PCMCIA_RESET, 1);
+			udelay(10);
+			gpio_set_value(GPIO_PCMCIA_RESET, 0);
+		}
+		break;
+	case 1:
+		if (state->flags & SS_RESET) {
+			gpio_set_value(GPIO_PCMCIA_SKTSEL, 1);
+			udelay(1);
+			gpio_set_value(GPIO_PCMCIA_RESET, 1);
+			udelay(10);
+			gpio_set_value(GPIO_PCMCIA_RESET, 0);
+		}
+		break;
+	}
+
+	return 0;
+}
+
+static void cmx255_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+{
+}
+
+static void cmx255_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+{
+}
+
+
+static struct pcmcia_low_level cmx255_pcmcia_ops __initdata = {
+	.owner			= THIS_MODULE,
+	.hw_init		= cmx255_pcmcia_hw_init,
+	.hw_shutdown		= cmx255_pcmcia_shutdown,
+	.socket_state		= cmx255_pcmcia_socket_state,
+	.configure_socket	= cmx255_pcmcia_configure_socket,
+	.socket_init		= cmx255_pcmcia_socket_init,
+	.socket_suspend		= cmx255_pcmcia_socket_suspend,
+	.nr			= 1,
+};
+
+static struct platform_device *cmx255_pcmcia_device;
+
+int __init cmx255_pcmcia_init(void)
+{
+	int ret;
+
+	cmx255_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
+
+	if (!cmx255_pcmcia_device)
+		return -ENOMEM;
+
+	ret = platform_device_add_data(cmx255_pcmcia_device, &cmx255_pcmcia_ops,
+				       sizeof(cmx255_pcmcia_ops));
+
+	if (ret == 0) {
+		printk(KERN_INFO "Registering cm-x255 PCMCIA interface.\n");
+		ret = platform_device_add(cmx255_pcmcia_device);
+	}
+
+	if (ret)
+		platform_device_put(cmx255_pcmcia_device);
+
+	return ret;
+}
+
+void __exit cmx255_pcmcia_exit(void)
+{
+	platform_device_unregister(cmx255_pcmcia_device);
+}
diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c
index bcff5cf..6c3aac3 100644
--- a/drivers/pcmcia/pxa2xx_cm_x270.c
+++ b/drivers/pcmcia/pxa2xx_cm_x270.c
@@ -105,13 +105,10 @@
 
 static struct platform_device *cmx270_pcmcia_device;
 
-static int __init cmx270_pcmcia_init(void)
+int __init cmx270_pcmcia_init(void)
 {
 	int ret;
 
-	if (!machine_is_armcore())
-		return -ENODEV;
-
 	cmx270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
 
 	if (!cmx270_pcmcia_device)
@@ -131,14 +128,7 @@
 	return ret;
 }
 
-static void __exit cmx270_pcmcia_exit(void)
+void __exit cmx270_pcmcia_exit(void)
 {
 	platform_device_unregister(cmx270_pcmcia_device);
 }
-
-module_init(cmx270_pcmcia_init);
-module_exit(cmx270_pcmcia_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
-MODULE_DESCRIPTION("CM-x270 PCMCIA driver");
diff --git a/drivers/pcmcia/pxa2xx_cm_x2xx.c b/drivers/pcmcia/pxa2xx_cm_x2xx.c
new file mode 100644
index 0000000..4f09506
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_cm_x2xx.c
@@ -0,0 +1,49 @@
+/*
+ * linux/drivers/pcmcia/pxa/pxa_cm_x2xx.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Compulab Ltd., 2003, 2007, 2008
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ */
+
+#include <linux/module.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <mach/system.h>
+
+int cmx255_pcmcia_init(void);
+int cmx270_pcmcia_init(void);
+void cmx255_pcmcia_exit(void);
+void cmx270_pcmcia_exit(void);
+
+static int __init cmx2xx_pcmcia_init(void)
+{
+	int ret = -ENODEV;
+
+	if (machine_is_armcore() && cpu_is_pxa25x())
+		ret = cmx255_pcmcia_init();
+	else if (machine_is_armcore() && cpu_is_pxa27x())
+		ret = cmx270_pcmcia_init();
+
+	return ret;
+}
+
+static void __exit cmx2xx_pcmcia_exit(void)
+{
+	if (machine_is_armcore() && cpu_is_pxa25x())
+		cmx255_pcmcia_exit();
+	else if (machine_is_armcore() && cpu_is_pxa27x())
+		cmx270_pcmcia_exit();
+}
+
+module_init(cmx2xx_pcmcia_init);
+module_exit(cmx2xx_pcmcia_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
+MODULE_DESCRIPTION("CM-x2xx PCMCIA driver");
diff --git a/drivers/pcmcia/pxa2xx_palmld.c b/drivers/pcmcia/pxa2xx_palmld.c
new file mode 100644
index 0000000..1736c67
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_palmld.c
@@ -0,0 +1,151 @@
+/*
+ * linux/drivers/pcmcia/pxa2xx_palmld.c
+ *
+ * Driver for Palm LifeDrive PCMCIA
+ *
+ * Copyright (C) 2006 Alex Osborne <ato@meshy.org>
+ * Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <mach/palmld.h>
+#include "soc_common.h"
+
+static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+	int ret;
+
+	ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_POWER, "PCMCIA PWR");
+	if (ret)
+		goto err1;
+	ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_POWER, 0);
+	if (ret)
+		goto err2;
+
+	ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_RESET, "PCMCIA RST");
+	if (ret)
+		goto err2;
+	ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_RESET, 1);
+	if (ret)
+		goto err3;
+
+	ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_READY, "PCMCIA RDY");
+	if (ret)
+		goto err3;
+	ret = gpio_direction_input(GPIO_NR_PALMLD_PCMCIA_READY);
+	if (ret)
+		goto err4;
+
+	skt->irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY);
+	return 0;
+
+err4:
+	gpio_free(GPIO_NR_PALMLD_PCMCIA_READY);
+err3:
+	gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET);
+err2:
+	gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER);
+err1:
+	return ret;
+}
+
+static void palmld_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+{
+	gpio_free(GPIO_NR_PALMLD_PCMCIA_READY);
+	gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET);
+	gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER);
+}
+
+static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
+					struct pcmcia_state *state)
+{
+	state->detect = 1; /* always inserted */
+	state->ready  = !!gpio_get_value(GPIO_NR_PALMLD_PCMCIA_READY);
+	state->bvd1   = 1;
+	state->bvd2   = 1;
+	state->wrprot = 0;
+	state->vs_3v  = 1;
+	state->vs_Xv  = 0;
+}
+
+static int palmld_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+					const socket_state_t *state)
+{
+	gpio_set_value(GPIO_NR_PALMLD_PCMCIA_POWER, 1);
+	gpio_set_value(GPIO_NR_PALMLD_PCMCIA_RESET,
+			!!(state->flags & SS_RESET));
+
+	return 0;
+}
+
+static void palmld_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+{
+}
+
+static void palmld_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+{
+}
+
+static struct pcmcia_low_level palmld_pcmcia_ops = {
+	.owner			= THIS_MODULE,
+
+	.first			= 0,
+	.nr			= 2,
+
+	.hw_init		= palmld_pcmcia_hw_init,
+	.hw_shutdown		= palmld_pcmcia_hw_shutdown,
+
+	.socket_state		= palmld_pcmcia_socket_state,
+	.configure_socket	= palmld_pcmcia_configure_socket,
+
+	.socket_init		= palmld_pcmcia_socket_init,
+	.socket_suspend		= palmld_pcmcia_socket_suspend,
+};
+
+static struct platform_device *palmld_pcmcia_device;
+
+static int __init palmld_pcmcia_init(void)
+{
+	int ret;
+
+	if (!machine_is_palmld())
+		return -ENODEV;
+
+	palmld_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
+	if (!palmld_pcmcia_device)
+		return -ENOMEM;
+
+	ret = platform_device_add_data(palmld_pcmcia_device, &palmld_pcmcia_ops,
+					sizeof(palmld_pcmcia_ops));
+
+	if (!ret)
+		ret = platform_device_add(palmld_pcmcia_device);
+
+	if (ret)
+		platform_device_put(palmld_pcmcia_device);
+
+	return ret;
+}
+
+static void __exit palmld_pcmcia_exit(void)
+{
+	platform_device_unregister(palmld_pcmcia_device);
+}
+
+module_init(palmld_pcmcia_init);
+module_exit(palmld_pcmcia_exit);
+
+MODULE_AUTHOR("Alex Osborne <ato@meshy.org>,"
+	    " Marek Vasut <marek.vasut@gmail.com>");
+MODULE_DESCRIPTION("PCMCIA support for Palm LifeDrive");
+MODULE_ALIAS("platform:pxa2xx-pcmcia");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/pxa2xx_trizeps4.c b/drivers/pcmcia/pxa2xx_trizeps4.c
new file mode 100644
index 0000000..36c7a0b
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_trizeps4.c
@@ -0,0 +1,256 @@
+/*
+ * linux/drivers/pcmcia/pxa2xx_trizeps4.c
+ *
+ * TRIZEPS PCMCIA specific routines.
+ *
+ * Author:	Jürgen Schindele
+ * Created:	20 02, 2006
+ * Copyright:	Jürgen Schindele
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/pxa-regs.h>
+#include <mach/trizeps4.h>
+
+#include "soc_common.h"
+
+extern void board_pcmcia_power(int power);
+
+static struct pcmcia_irqs irqs[] = {
+	{ 0, IRQ_GPIO(GPIO_PCD), "cs0_cd" }
+	/* on other baseboards we can have more inputs */
+};
+
+static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+	int ret, i;
+	/* we dont have voltage/card/ready detection
+	 * so we dont need interrupts for it
+	 */
+	switch (skt->nr) {
+	case 0:
+		if (gpio_request(GPIO_PRDY, "cf_irq") < 0) {
+			pr_err("%s: sock %d unable to request gpio %d\n", __func__,
+				skt->nr, GPIO_PRDY);
+			return -EBUSY;
+		}
+		if (gpio_direction_input(GPIO_PRDY) < 0) {
+			pr_err("%s: sock %d unable to set input gpio %d\n", __func__,
+				skt->nr, GPIO_PRDY);
+			gpio_free(GPIO_PRDY);
+			return -EINVAL;
+		}
+		skt->irq = IRQ_GPIO(GPIO_PRDY);
+		break;
+
+#ifndef CONFIG_MACH_TRIZEPS_CONXS
+	case 1:
+#endif
+	default:
+		break;
+	}
+	/* release the reset of this card */
+	pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->irq);
+
+	/* supplementory irqs for the socket */
+	for (i = 0; i < ARRAY_SIZE(irqs); i++) {
+		if (irqs[i].sock != skt->nr)
+			continue;
+		if (gpio_request(IRQ_TO_GPIO(irqs[i].irq), irqs[i].str) < 0) {
+			pr_err("%s: sock %d unable to request gpio %d\n",
+				__func__, skt->nr, IRQ_TO_GPIO(irqs[i].irq));
+			ret = -EBUSY;
+			goto error;
+		}
+		if (gpio_direction_input(IRQ_TO_GPIO(irqs[i].irq)) < 0) {
+			pr_err("%s: sock %d unable to set input gpio %d\n",
+				__func__, skt->nr, IRQ_TO_GPIO(irqs[i].irq));
+			ret = -EINVAL;
+			goto error;
+		}
+	}
+	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+
+error:
+	for (; i >= 0; i--) {
+		gpio_free(IRQ_TO_GPIO(irqs[i].irq));
+	}
+	return (ret);
+}
+
+static void trizeps_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+{
+	int i;
+	/* free allocated gpio's */
+	gpio_free(GPIO_PRDY);
+	for (i = 0; i < ARRAY_SIZE(irqs); i++)
+		gpio_free(IRQ_TO_GPIO(irqs[i].irq));
+}
+
+static unsigned long trizeps_pcmcia_status[2];
+
+static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
+				struct pcmcia_state *state)
+{
+	unsigned short status = 0, change;
+	status = CFSR_readw();
+	change = (status ^ trizeps_pcmcia_status[skt->nr]) &
+				ConXS_CFSR_BVD_MASK;
+	if (change) {
+		trizeps_pcmcia_status[skt->nr] = status;
+		if (status & ConXS_CFSR_BVD1) {
+			/* enable_irq empty */
+		} else {
+			/* disable_irq empty */
+		}
+	}
+
+	switch (skt->nr) {
+	case 0:
+		/* just fill in fix states */
+		state->detect = gpio_get_value(GPIO_PCD) ? 0 : 1;
+		state->ready  = gpio_get_value(GPIO_PRDY) ? 1 : 0;
+		state->bvd1   = (status & ConXS_CFSR_BVD1) ? 1 : 0;
+		state->bvd2   = (status & ConXS_CFSR_BVD2) ? 1 : 0;
+		state->vs_3v  = (status & ConXS_CFSR_VS1) ? 0 : 1;
+		state->vs_Xv  = (status & ConXS_CFSR_VS2) ? 0 : 1;
+		state->wrprot = 0;	/* not available */
+		break;
+
+#ifndef CONFIG_MACH_TRIZEPS_CONXS
+	/* on ConXS we only have one slot. Second is inactive */
+	case 1:
+		state->detect = 0;
+		state->ready  = 0;
+		state->bvd1   = 0;
+		state->bvd2   = 0;
+		state->vs_3v  = 0;
+		state->vs_Xv  = 0;
+		state->wrprot = 0;
+		break;
+
+#endif
+	}
+}
+
+static int trizeps_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+				const socket_state_t *state)
+{
+	int ret = 0;
+	unsigned short power = 0;
+
+	/* we do nothing here just check a bit */
+	switch (state->Vcc) {
+	case 0:  power &= 0xfc; break;
+	case 33: power |= ConXS_BCR_S0_VCC_3V3; break;
+	case 50:
+		pr_err("%s(): Vcc 5V not supported in socket\n", __func__);
+		break;
+	default:
+		pr_err("%s(): bad Vcc %u\n", __func__, state->Vcc);
+		ret = -1;
+	}
+
+	switch (state->Vpp) {
+	case 0:  power &= 0xf3; break;
+	case 33: power |= ConXS_BCR_S0_VPP_3V3; break;
+	case 120:
+		pr_err("%s(): Vpp 12V not supported in socket\n", __func__);
+		break;
+	default:
+		if (state->Vpp != state->Vcc) {
+			pr_err("%s(): bad Vpp %u\n", __func__, state->Vpp);
+			ret = -1;
+		}
+	}
+
+	switch (skt->nr) {
+	case 0:			 /* we only have 3.3V */
+		board_pcmcia_power(power);
+		break;
+
+#ifndef CONFIG_MACH_TRIZEPS_CONXS
+	/* on ConXS we only have one slot. Second is inactive */
+	case 1:
+#endif
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static void trizeps_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+{
+	/* default is on */
+	board_pcmcia_power(0x9);
+}
+
+static void trizeps_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+{
+	board_pcmcia_power(0x0);
+}
+
+static struct pcmcia_low_level trizeps_pcmcia_ops = {
+	.owner			= THIS_MODULE,
+	.hw_init		= trizeps_pcmcia_hw_init,
+	.hw_shutdown		= trizeps_pcmcia_hw_shutdown,
+	.socket_state		= trizeps_pcmcia_socket_state,
+	.configure_socket	= trizeps_pcmcia_configure_socket,
+	.socket_init		= trizeps_pcmcia_socket_init,
+	.socket_suspend		= trizeps_pcmcia_socket_suspend,
+#ifdef CONFIG_MACH_TRIZEPS_CONXS
+	.nr			= 1,
+#else
+	.nr			= 2,
+#endif
+	.first			= 0,
+};
+
+static struct platform_device *trizeps_pcmcia_device;
+
+static int __init trizeps_pcmcia_init(void)
+{
+	int ret;
+
+	trizeps_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
+	if (!trizeps_pcmcia_device)
+		return -ENOMEM;
+
+	ret = platform_device_add_data(trizeps_pcmcia_device,
+			&trizeps_pcmcia_ops, sizeof(trizeps_pcmcia_ops));
+
+	if (ret == 0)
+		ret = platform_device_add(trizeps_pcmcia_device);
+
+	if (ret)
+		platform_device_put(trizeps_pcmcia_device);
+
+	return ret;
+}
+
+static void __exit trizeps_pcmcia_exit(void)
+{
+	platform_device_unregister(trizeps_pcmcia_device);
+}
+
+fs_initcall(trizeps_pcmcia_init);
+module_exit(trizeps_pcmcia_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Juergen Schindele");
+MODULE_ALIAS("platform:pxa2xx-pcmcia");
diff --git a/drivers/pcmcia/pxa2xx_viper.c b/drivers/pcmcia/pxa2xx_viper.c
new file mode 100644
index 0000000..dd10481
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_viper.c
@@ -0,0 +1,179 @@
+/*
+ * VIPER PCMCIA support
+ *   Copyright 2004 Arcom Control Systems
+ *
+ * Maintained by Marc Zyngier <maz@misterjones.org>
+ * 			      <marc.zyngier@altran.com>
+ *
+ * Based on:
+ *   iPAQ h2200 PCMCIA support
+ *   Copyright 2004 Koen Kooi <koen@vestingbar.nl>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <pcmcia/ss.h>
+
+#include <asm/irq.h>
+
+#include <mach/pxa-regs.h>
+#include <mach/viper.h>
+#include <asm/mach-types.h>
+
+#include "soc_common.h"
+#include "pxa2xx_base.h"
+
+static struct pcmcia_irqs irqs[] = {
+	{ 0, gpio_to_irq(VIPER_CF_CD_GPIO),  "PCMCIA_CD" }
+};
+
+static int viper_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+	unsigned long flags;
+
+	skt->irq = gpio_to_irq(VIPER_CF_RDY_GPIO);
+
+	if (gpio_request(VIPER_CF_CD_GPIO, "CF detect"))
+		goto err_request_cd;
+
+	if (gpio_request(VIPER_CF_RDY_GPIO, "CF ready"))
+		goto err_request_rdy;
+
+	if (gpio_request(VIPER_CF_POWER_GPIO, "CF power"))
+		goto err_request_pwr;
+
+	local_irq_save(flags);
+
+	/* GPIO 82 is the CF power enable line. initially off */
+	if (gpio_direction_output(VIPER_CF_POWER_GPIO, 0) ||
+	    gpio_direction_input(VIPER_CF_CD_GPIO) ||
+	    gpio_direction_input(VIPER_CF_RDY_GPIO)) {
+		local_irq_restore(flags);
+		goto err_dir;
+	}
+
+	local_irq_restore(flags);
+
+	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+
+err_dir:
+	gpio_free(VIPER_CF_POWER_GPIO);
+err_request_pwr:
+	gpio_free(VIPER_CF_RDY_GPIO);
+err_request_rdy:
+	gpio_free(VIPER_CF_CD_GPIO);
+err_request_cd:
+	printk(KERN_ERR "viper: Failed to setup PCMCIA GPIOs\n");
+	return -1;
+}
+
+/*
+ * Release all resources.
+ */
+static void viper_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+{
+	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+	gpio_free(VIPER_CF_POWER_GPIO);
+	gpio_free(VIPER_CF_RDY_GPIO);
+	gpio_free(VIPER_CF_CD_GPIO);
+}
+
+static void viper_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
+				      struct pcmcia_state *state)
+{
+	state->detect = gpio_get_value(VIPER_CF_CD_GPIO) ? 0 : 1;
+	state->ready  = gpio_get_value(VIPER_CF_RDY_GPIO) ? 1 : 0;
+	state->bvd1   = 1;
+	state->bvd2   = 1;
+	state->wrprot = 0;
+	state->vs_3v  = 1; /* Can only apply 3.3V */
+	state->vs_Xv  = 0;
+}
+
+static int viper_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+					 const socket_state_t *state)
+{
+	/* Silently ignore Vpp, output enable, speaker enable. */
+	viper_cf_rst(state->flags & SS_RESET);
+
+	/* Apply socket voltage */
+	switch (state->Vcc) {
+	case 0:
+		gpio_set_value(VIPER_CF_POWER_GPIO, 0);
+		break;
+	case 33:
+		gpio_set_value(VIPER_CF_POWER_GPIO, 1);
+		break;
+	default:
+		printk(KERN_ERR "%s: Unsupported Vcc:%d\n",
+		       __func__, state->Vcc);
+		return -1;
+	}
+
+	return 0;
+}
+
+static void viper_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+{
+}
+
+static void viper_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+{
+}
+
+static struct pcmcia_low_level viper_pcmcia_ops __initdata = {
+	.owner          	= THIS_MODULE,
+	.hw_init        	= viper_pcmcia_hw_init,
+	.hw_shutdown		= viper_pcmcia_hw_shutdown,
+	.socket_state		= viper_pcmcia_socket_state,
+	.configure_socket	= viper_pcmcia_configure_socket,
+	.socket_init		= viper_pcmcia_socket_init,
+	.socket_suspend		= viper_pcmcia_socket_suspend,
+	.nr         		= 1,
+};
+
+static struct platform_device *viper_pcmcia_device;
+
+static int __init viper_pcmcia_init(void)
+{
+	int ret;
+
+	if (!machine_is_viper())
+		return -ENODEV;
+
+	viper_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
+	if (!viper_pcmcia_device)
+		return -ENOMEM;
+
+	ret = platform_device_add_data(viper_pcmcia_device,
+				       &viper_pcmcia_ops,
+				       sizeof(viper_pcmcia_ops));
+
+	if (!ret)
+		ret = platform_device_add(viper_pcmcia_device);
+
+	if (ret)
+		platform_device_put(viper_pcmcia_device);
+
+	return ret;
+}
+
+static void __exit viper_pcmcia_exit(void)
+{
+	platform_device_unregister(viper_pcmcia_device);
+}
+
+module_init(viper_pcmcia_init);
+module_exit(viper_pcmcia_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index c48f3f6..da39721 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -748,7 +748,9 @@
 
 		add_timer(&skt->poll_timer);
 
-		device_create_file(&skt->socket.dev, &dev_attr_status);
+		ret = device_create_file(&skt->socket.dev, &dev_attr_status);
+		if (ret)
+			goto out_err_8;
 	}
 
 	dev_set_drvdata(dev, sinfo);
@@ -758,6 +760,8 @@
 	do {
 		skt = &sinfo->skt[i];
 
+		device_remove_file(&skt->socket.dev, &dev_attr_status);
+ out_err_8:
 		del_timer_sync(&skt->poll_timer);
 		pcmcia_unregister_socket(&skt->socket);
 
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index d7e9f21..95015cb 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -405,8 +405,6 @@
 
 	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 		extended_irq = &res->data.extended_irq;
-		if (extended_irq->producer_consumer == ACPI_PRODUCER)
-			return AE_OK;
 
 		if (extended_irq->interrupt_count == 0)
 			pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 9ce5585..1982f8b 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -56,10 +56,10 @@
 	  Say Y to enable support for the battery on the Sharp Zaurus
 	  SL-6000 (tosa) models.
 
-config BATTERY_PALMTX
-	tristate "Palm T|X battery"
-	depends on MACH_PALMTX
+config BATTERY_WM97XX
+	bool "WM97xx generic battery driver"
+	depends on TOUCHSCREEN_WM97XX
 	help
-	  Say Y to enable support for the battery in Palm T|X.
+	  Say Y to enable support for battery measured by WM97xx aux port.
 
 endif # POWER_SUPPLY
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index 4706bf8..4e20026 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -21,4 +21,4 @@
 obj-$(CONFIG_BATTERY_PMU)	+= pmu_battery.o
 obj-$(CONFIG_BATTERY_OLPC)	+= olpc_battery.o
 obj-$(CONFIG_BATTERY_TOSA)	+= tosa_battery.o
-obj-$(CONFIG_BATTERY_PALMTX)	+= palmtx_battery.o
+obj-$(CONFIG_BATTERY_WM97XX)	+= wm97xx_battery.o
\ No newline at end of file
diff --git a/drivers/power/palmtx_battery.c b/drivers/power/palmtx_battery.c
deleted file mode 100644
index 7035bfa..0000000
--- a/drivers/power/palmtx_battery.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * linux/drivers/power/palmtx_battery.c
- *
- * Battery measurement code for Palm T|X Handheld computer
- *
- * based on tosa_battery.c
- *
- * Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/power_supply.h>
-#include <linux/wm97xx.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/gpio.h>
-
-#include <asm/mach-types.h>
-#include <mach/palmtx.h>
-
-static DEFINE_MUTEX(bat_lock);
-static struct work_struct bat_work;
-struct mutex work_lock;
-int bat_status = POWER_SUPPLY_STATUS_DISCHARGING;
-
-static unsigned long palmtx_read_bat(struct power_supply *bat_ps)
-{
-	return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data,
-				    WM97XX_AUX_ID3) * 1000 / 414;
-}
-
-static unsigned long palmtx_read_temp(struct power_supply *bat_ps)
-{
-	return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data,
-				    WM97XX_AUX_ID2);
-}
-
-static int palmtx_bat_get_property(struct power_supply *bat_ps,
-			    enum power_supply_property psp,
-			    union power_supply_propval *val)
-{
-	switch (psp) {
-	case POWER_SUPPLY_PROP_STATUS:
-		val->intval = bat_status;
-		break;
-	case POWER_SUPPLY_PROP_TECHNOLOGY:
-		val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO;
-		break;
-	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
-		val->intval = palmtx_read_bat(bat_ps);
-		break;
-	case POWER_SUPPLY_PROP_VOLTAGE_MAX:
-	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
-		val->intval = PALMTX_BAT_MAX_VOLTAGE;
-		break;
-	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
-		val->intval = PALMTX_BAT_MIN_VOLTAGE;
-		break;
-	case POWER_SUPPLY_PROP_TEMP:
-		val->intval = palmtx_read_temp(bat_ps);
-		break;
-	case POWER_SUPPLY_PROP_PRESENT:
-		val->intval = 1;
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static void palmtx_bat_external_power_changed(struct power_supply *bat_ps)
-{
-	schedule_work(&bat_work);
-}
-
-static char *status_text[] = {
-	[POWER_SUPPLY_STATUS_UNKNOWN] =		"Unknown",
-	[POWER_SUPPLY_STATUS_CHARGING] =	"Charging",
-	[POWER_SUPPLY_STATUS_DISCHARGING] =	"Discharging",
-};
-
-static void palmtx_bat_update(struct power_supply *bat_ps)
-{
-	int old_status = bat_status;
-
-	mutex_lock(&work_lock);
-
-	bat_status = gpio_get_value(GPIO_NR_PALMTX_POWER_DETECT) ?
-				    POWER_SUPPLY_STATUS_CHARGING :
-				    POWER_SUPPLY_STATUS_DISCHARGING;
-
-	if (old_status != bat_status) {
-		pr_debug("%s %s -> %s\n", bat_ps->name,
-				status_text[old_status],
-				status_text[bat_status]);
-		power_supply_changed(bat_ps);
-	}
-
-	mutex_unlock(&work_lock);
-}
-
-static enum power_supply_property palmtx_bat_main_props[] = {
-	POWER_SUPPLY_PROP_STATUS,
-	POWER_SUPPLY_PROP_TECHNOLOGY,
-	POWER_SUPPLY_PROP_VOLTAGE_NOW,
-	POWER_SUPPLY_PROP_VOLTAGE_MAX,
-	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
-	POWER_SUPPLY_PROP_TEMP,
-	POWER_SUPPLY_PROP_PRESENT,
-};
-
-struct power_supply bat_ps = {
-	.name			= "main-battery",
-	.type			= POWER_SUPPLY_TYPE_BATTERY,
-	.properties		= palmtx_bat_main_props,
-	.num_properties		= ARRAY_SIZE(palmtx_bat_main_props),
-	.get_property		= palmtx_bat_get_property,
-	.external_power_changed = palmtx_bat_external_power_changed,
-	.use_for_apm		= 1,
-};
-
-static void palmtx_bat_work(struct work_struct *work)
-{
-	palmtx_bat_update(&bat_ps);
-}
-
-#ifdef CONFIG_PM
-static int palmtx_bat_suspend(struct platform_device *dev, pm_message_t state)
-{
-	flush_scheduled_work();
-	return 0;
-}
-
-static int palmtx_bat_resume(struct platform_device *dev)
-{
-	schedule_work(&bat_work);
-	return 0;
-}
-#else
-#define palmtx_bat_suspend NULL
-#define palmtx_bat_resume NULL
-#endif
-
-static int __devinit palmtx_bat_probe(struct platform_device *dev)
-{
-	int ret = 0;
-
-	if (!machine_is_palmtx())
-		return -ENODEV;
-
-	mutex_init(&work_lock);
-
-	INIT_WORK(&bat_work, palmtx_bat_work);
-
-	ret = power_supply_register(&dev->dev, &bat_ps);
-	if (!ret)
-		schedule_work(&bat_work);
-
-	return ret;
-}
-
-static int __devexit palmtx_bat_remove(struct platform_device *dev)
-{
-	power_supply_unregister(&bat_ps);
-	return 0;
-}
-
-static struct platform_driver palmtx_bat_driver = {
-	.driver.name	= "wm97xx-battery",
-	.driver.owner	= THIS_MODULE,
-	.probe		= palmtx_bat_probe,
-	.remove		= __devexit_p(palmtx_bat_remove),
-	.suspend	= palmtx_bat_suspend,
-	.resume		= palmtx_bat_resume,
-};
-
-static int __init palmtx_bat_init(void)
-{
-	return platform_driver_register(&palmtx_bat_driver);
-}
-
-static void __exit palmtx_bat_exit(void)
-{
-	platform_driver_unregister(&palmtx_bat_driver);
-}
-
-module_init(palmtx_bat_init);
-module_exit(palmtx_bat_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
-MODULE_DESCRIPTION("Palm T|X battery driver");
diff --git a/drivers/power/wm97xx_battery.c b/drivers/power/wm97xx_battery.c
new file mode 100644
index 0000000..8bde921
--- /dev/null
+++ b/drivers/power/wm97xx_battery.c
@@ -0,0 +1,272 @@
+/*
+ * linux/drivers/power/wm97xx_battery.c
+ *
+ * Battery measurement code for WM97xx
+ *
+ * based on tosa_battery.c
+ *
+ * Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/wm97xx.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/wm97xx_batt.h>
+
+static DEFINE_MUTEX(bat_lock);
+static struct work_struct bat_work;
+struct mutex work_lock;
+static int bat_status = POWER_SUPPLY_STATUS_UNKNOWN;
+static struct wm97xx_batt_info *pdata;
+static enum power_supply_property *prop;
+
+static unsigned long wm97xx_read_bat(struct power_supply *bat_ps)
+{
+	return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data,
+					pdata->batt_aux) * pdata->batt_mult /
+					pdata->batt_div;
+}
+
+static unsigned long wm97xx_read_temp(struct power_supply *bat_ps)
+{
+	return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data,
+					pdata->temp_aux) * pdata->temp_mult /
+					pdata->temp_div;
+}
+
+static int wm97xx_bat_get_property(struct power_supply *bat_ps,
+			    enum power_supply_property psp,
+			    union power_supply_propval *val)
+{
+	switch (psp) {
+	case POWER_SUPPLY_PROP_STATUS:
+		val->intval = bat_status;
+		break;
+	case POWER_SUPPLY_PROP_TECHNOLOGY:
+		val->intval = pdata->batt_tech;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		if (pdata->batt_aux >= 0)
+			val->intval = wm97xx_read_bat(bat_ps);
+		else
+			return -EINVAL;
+		break;
+	case POWER_SUPPLY_PROP_TEMP:
+		if (pdata->temp_aux >= 0)
+			val->intval = wm97xx_read_temp(bat_ps);
+		else
+			return -EINVAL;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_MAX:
+		if (pdata->max_voltage >= 0)
+			val->intval = pdata->max_voltage;
+		else
+			return -EINVAL;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_MIN:
+		if (pdata->min_voltage >= 0)
+			val->intval = pdata->min_voltage;
+		else
+			return -EINVAL;
+		break;
+	case POWER_SUPPLY_PROP_PRESENT:
+		val->intval = 1;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static void wm97xx_bat_external_power_changed(struct power_supply *bat_ps)
+{
+	schedule_work(&bat_work);
+}
+
+static void wm97xx_bat_update(struct power_supply *bat_ps)
+{
+	int old_status = bat_status;
+
+	mutex_lock(&work_lock);
+
+	bat_status = (pdata->charge_gpio >= 0) ?
+			(gpio_get_value(pdata->charge_gpio) ?
+			POWER_SUPPLY_STATUS_DISCHARGING :
+			POWER_SUPPLY_STATUS_CHARGING) :
+			POWER_SUPPLY_STATUS_UNKNOWN;
+
+	if (old_status != bat_status) {
+		pr_debug("%s: %i -> %i\n", bat_ps->name, old_status,
+					bat_status);
+		power_supply_changed(bat_ps);
+	}
+
+	mutex_unlock(&work_lock);
+}
+
+static struct power_supply bat_ps = {
+	.type			= POWER_SUPPLY_TYPE_BATTERY,
+	.get_property		= wm97xx_bat_get_property,
+	.external_power_changed = wm97xx_bat_external_power_changed,
+	.use_for_apm		= 1,
+};
+
+static void wm97xx_bat_work(struct work_struct *work)
+{
+	wm97xx_bat_update(&bat_ps);
+}
+
+#ifdef CONFIG_PM
+static int wm97xx_bat_suspend(struct platform_device *dev, pm_message_t state)
+{
+	flush_scheduled_work();
+	return 0;
+}
+
+static int wm97xx_bat_resume(struct platform_device *dev)
+{
+	schedule_work(&bat_work);
+	return 0;
+}
+#else
+#define wm97xx_bat_suspend NULL
+#define wm97xx_bat_resume NULL
+#endif
+
+static int __devinit wm97xx_bat_probe(struct platform_device *dev)
+{
+	int ret = 0;
+	int props = 1;	/* POWER_SUPPLY_PROP_PRESENT */
+	int i = 0;
+
+	if (dev->id != -1)
+		return -EINVAL;
+
+	mutex_init(&work_lock);
+
+	if (!pdata) {
+		dev_err(&dev->dev, "Please use wm97xx_bat_set_pdata\n");
+		return -EINVAL;
+	}
+
+	if (pdata->charge_gpio >= 0 && gpio_is_valid(pdata->charge_gpio)) {
+		ret = gpio_request(pdata->charge_gpio, "BATT CHRG");
+		if (ret)
+			goto err;
+		ret = gpio_direction_input(pdata->charge_gpio);
+		if (ret)
+			goto err2;
+		props++;	/* POWER_SUPPLY_PROP_STATUS */
+	}
+
+	if (pdata->batt_tech >= 0)
+		props++;	/* POWER_SUPPLY_PROP_TECHNOLOGY */
+	if (pdata->temp_aux >= 0)
+		props++;	/* POWER_SUPPLY_PROP_TEMP */
+	if (pdata->batt_aux >= 0)
+		props++;	/* POWER_SUPPLY_PROP_VOLTAGE_NOW */
+	if (pdata->max_voltage >= 0)
+		props++;	/* POWER_SUPPLY_PROP_VOLTAGE_MAX */
+	if (pdata->min_voltage >= 0)
+		props++;	/* POWER_SUPPLY_PROP_VOLTAGE_MIN */
+
+	prop = kzalloc(props * sizeof(*prop), GFP_KERNEL);
+	if (!prop)
+		goto err2;
+
+	prop[i++] = POWER_SUPPLY_PROP_PRESENT;
+	if (pdata->charge_gpio >= 0)
+		prop[i++] = POWER_SUPPLY_PROP_STATUS;
+	if (pdata->batt_tech >= 0)
+		prop[i++] = POWER_SUPPLY_PROP_TECHNOLOGY;
+	if (pdata->temp_aux >= 0)
+		prop[i++] = POWER_SUPPLY_PROP_TEMP;
+	if (pdata->batt_aux >= 0)
+		prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_NOW;
+	if (pdata->max_voltage >= 0)
+		prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_MAX;
+	if (pdata->min_voltage >= 0)
+		prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_MIN;
+
+	INIT_WORK(&bat_work, wm97xx_bat_work);
+
+	if (!pdata->batt_name) {
+		dev_info(&dev->dev, "Please consider setting proper battery "
+				"name in platform definition file, falling "
+				"back to name \"wm97xx-batt\"\n");
+		bat_ps.name = "wm97xx-batt";
+	} else
+		bat_ps.name = pdata->batt_name;
+
+	bat_ps.properties = prop;
+	bat_ps.num_properties = props;
+
+	ret = power_supply_register(&dev->dev, &bat_ps);
+	if (!ret)
+		schedule_work(&bat_work);
+	else
+		goto err3;
+
+	return 0;
+err3:
+	kfree(prop);
+err2:
+	gpio_free(pdata->charge_gpio);
+err:
+	return ret;
+}
+
+static int __devexit wm97xx_bat_remove(struct platform_device *dev)
+{
+	if (pdata && pdata->charge_gpio && pdata->charge_gpio >= 0)
+		gpio_free(pdata->charge_gpio);
+	flush_scheduled_work();
+	power_supply_unregister(&bat_ps);
+	kfree(prop);
+	return 0;
+}
+
+static struct platform_driver wm97xx_bat_driver = {
+	.driver	= {
+		.name	= "wm97xx-battery",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= wm97xx_bat_probe,
+	.remove		= __devexit_p(wm97xx_bat_remove),
+	.suspend	= wm97xx_bat_suspend,
+	.resume		= wm97xx_bat_resume,
+};
+
+static int __init wm97xx_bat_init(void)
+{
+	return platform_driver_register(&wm97xx_bat_driver);
+}
+
+static void __exit wm97xx_bat_exit(void)
+{
+	platform_driver_unregister(&wm97xx_bat_driver);
+}
+
+void __init wm97xx_bat_set_pdata(struct wm97xx_batt_info *data)
+{
+	pdata = data;
+}
+EXPORT_SYMBOL_GPL(wm97xx_bat_set_pdata);
+
+module_init(wm97xx_bat_init);
+module_exit(wm97xx_bat_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
+MODULE_DESCRIPTION("WM97xx battery driver");
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c
index db00b05..f1216cf 100644
--- a/drivers/s390/cio/chp.c
+++ b/drivers/s390/cio/chp.c
@@ -423,7 +423,7 @@
 	ret = sysfs_create_group(&chp->dev.kobj, &chp_attr_group);
 	if (ret) {
 		device_unregister(&chp->dev);
-		goto out_free;
+		goto out;
 	}
 	mutex_lock(&channel_subsystems[chpid.cssid]->mutex);
 	if (channel_subsystems[chpid.cssid]->cm_enabled) {
@@ -432,14 +432,15 @@
 			sysfs_remove_group(&chp->dev.kobj, &chp_attr_group);
 			device_unregister(&chp->dev);
 			mutex_unlock(&channel_subsystems[chpid.cssid]->mutex);
-			goto out_free;
+			goto out;
 		}
 	}
 	channel_subsystems[chpid.cssid]->chps[chpid.id] = chp;
 	mutex_unlock(&channel_subsystems[chpid.cssid]->mutex);
-	return ret;
+	goto out;
 out_free:
 	kfree(chp);
+out:
 	return ret;
 }
 
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 33bff8f..5954b90 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -208,8 +208,10 @@
 	case 1:		/* status pending */
 	case 2:		/* busy */
 		return -EBUSY;
-	default:		/* device/path not operational */
+	case 3:		/* device/path not operational */
 		return cio_start_handle_notoper(sch, lpm);
+	default:
+		return ccode;
 	}
 }
 
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 51489ef..1261e1a 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -633,6 +633,11 @@
 
 	css = to_css(dev);
 	mutex_destroy(&css->mutex);
+	if (css->pseudo_subchannel) {
+		/* Implies that it has been generated but never registered. */
+		css_subchannel_release(&css->pseudo_subchannel->dev);
+		css->pseudo_subchannel = NULL;
+	}
 	kfree(css);
 }
 
@@ -785,11 +790,15 @@
 		}
 		channel_subsystems[i] = css;
 		ret = setup_css(i);
-		if (ret)
-			goto out_free;
+		if (ret) {
+			kfree(channel_subsystems[i]);
+			goto out_unregister;
+		}
 		ret = device_register(&css->device);
-		if (ret)
-			goto out_free_all;
+		if (ret) {
+			put_device(&css->device);
+			goto out_unregister;
+		}
 		if (css_chsc_characteristics.secm) {
 			ret = device_create_file(&css->device,
 						 &dev_attr_cm_enable);
@@ -802,7 +811,7 @@
 	}
 	ret = register_reboot_notifier(&css_reboot_notifier);
 	if (ret)
-		goto out_pseudo;
+		goto out_unregister;
 	css_init_done = 1;
 
 	/* Enable default isc for I/O subchannels. */
@@ -810,18 +819,12 @@
 
 	for_each_subchannel(__init_channel_subsystem, NULL);
 	return 0;
-out_pseudo:
-	device_unregister(&channel_subsystems[i]->pseudo_subchannel->dev);
 out_file:
-	device_remove_file(&channel_subsystems[i]->device,
-			   &dev_attr_cm_enable);
+	if (css_chsc_characteristics.secm)
+		device_remove_file(&channel_subsystems[i]->device,
+				   &dev_attr_cm_enable);
 out_device:
 	device_unregister(&channel_subsystems[i]->device);
-out_free_all:
-	kfree(channel_subsystems[i]->pseudo_subchannel->lock);
-	kfree(channel_subsystems[i]->pseudo_subchannel);
-out_free:
-	kfree(channel_subsystems[i]);
 out_unregister:
 	while (i > 0) {
 		struct channel_subsystem *css;
@@ -829,6 +832,7 @@
 		i--;
 		css = channel_subsystems[i];
 		device_unregister(&css->pseudo_subchannel->dev);
+		css->pseudo_subchannel = NULL;
 		if (css_chsc_characteristics.secm)
 			device_remove_file(&css->device,
 					   &dev_attr_cm_enable);
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 550508d..84cc9ea 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -658,6 +658,13 @@
 {
 	struct subchannel *sch;
 
+	/* Allow ccw_device_offline while disconnected. */
+	if (cdev->private->state == DEV_STATE_DISCONNECTED ||
+	    cdev->private->state == DEV_STATE_NOT_OPER) {
+		cdev->private->flags.donotify = 0;
+		ccw_device_done(cdev, DEV_STATE_NOT_OPER);
+		return 0;
+	}
 	if (ccw_device_is_orphan(cdev)) {
 		ccw_device_done(cdev, DEV_STATE_OFFLINE);
 		return 0;
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index 391dd29..51b6a05 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -152,10 +152,8 @@
  */
 static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
 {
-	struct zfcp_adapter *adapter;
+	struct zfcp_adapter *adapter = dev_get_drvdata(&ccw_device->dev);
 
-	down(&zfcp_data.config_sema);
-	adapter = dev_get_drvdata(&ccw_device->dev);
 	switch (event) {
 	case CIO_GONE:
 		dev_warn(&adapter->ccw_device->dev, "device gone\n");
@@ -174,8 +172,6 @@
 					89, NULL);
 		break;
 	}
-	zfcp_erp_wait(adapter);
-	up(&zfcp_data.config_sema);
 	return 1;
 }
 
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index e984469..56196c9 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -39,18 +39,6 @@
 	struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS];
 };
 
-static struct zfcp_port *zfcp_get_port_by_did(struct zfcp_adapter *adapter,
-					      u32 d_id)
-{
-	struct zfcp_port *port;
-
-	list_for_each_entry(port, &adapter->port_list_head, list)
-		if ((port->d_id == d_id) &&
-		    !atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status))
-			return port;
-	return NULL;
-}
-
 static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
 				   struct fcp_rscn_element *elem)
 {
@@ -341,12 +329,13 @@
 
 	zfcp_port_get(port);
 	retval = zfcp_fc_adisc(port);
-	if (retval == 0 || retval == -EBUSY)
+	if (retval == 0)
 		return;
 
 	/* send of ADISC was not possible */
 	zfcp_port_put(port);
-	zfcp_erp_port_forced_reopen(port, 0, 65, NULL);
+	if (retval != -EBUSY)
+		zfcp_erp_port_forced_reopen(port, 0, 65, NULL);
 }
 
 static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter)
@@ -363,7 +352,6 @@
 		if (ret)
 			return ret;
 		zfcp_erp_wait(adapter);
-		zfcp_port_put(adapter->nameserver_port);
 	}
 	return !atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
 				  &adapter->nameserver_port->status);
@@ -475,7 +463,7 @@
 	struct zfcp_adapter *adapter = ct->port->adapter;
 	struct zfcp_port *port, *tmp;
 	u32 d_id;
-	int ret = 0, x;
+	int ret = 0, x, last = 0;
 
 	if (ct->status)
 		return -EIO;
@@ -492,19 +480,24 @@
 	down(&zfcp_data.config_sema);
 
 	/* first entry is the header */
-	for (x = 1; x < ZFCP_GPN_FT_MAX_ENTRIES; x++) {
+	for (x = 1; x < ZFCP_GPN_FT_MAX_ENTRIES && !last; x++) {
 		if (x % (ZFCP_GPN_FT_ENTRIES + 1))
 			acc++;
 		else
 			acc = sg_virt(++sg);
 
+		last = acc->control & 0x80;
 		d_id = acc->port_id[0] << 16 | acc->port_id[1] << 8 |
 		       acc->port_id[2];
 
 		/* skip the adapter's port and known remote ports */
-		if (acc->wwpn == fc_host_port_name(adapter->scsi_host) ||
-		     zfcp_get_port_by_did(adapter, d_id))
+		if (acc->wwpn == fc_host_port_name(adapter->scsi_host))
 			continue;
+		port = zfcp_get_port_by_wwpn(adapter, acc->wwpn);
+		if (port) {
+			zfcp_port_get(port);
+			continue;
+		}
 
 		port = zfcp_port_enqueue(adapter, acc->wwpn,
 					 ZFCP_STATUS_PORT_DID_DID |
@@ -513,8 +506,6 @@
 			ret = PTR_ERR(port);
 		else
 			zfcp_erp_port_reopen(port, 0, 149, NULL);
-		if (acc->control & 0x80) /* last entry */
-			break;
 	}
 
 	zfcp_erp_wait(adapter);
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 19c1ca9..49dbeb7 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -710,10 +710,10 @@
 
 static int zfcp_fsf_sbal_check(struct zfcp_qdio_queue *queue)
 {
-	spin_lock(&queue->lock);
+	spin_lock_bh(&queue->lock);
 	if (atomic_read(&queue->count))
 		return 1;
-	spin_unlock(&queue->lock);
+	spin_unlock_bh(&queue->lock);
 	return 0;
 }
 
@@ -722,13 +722,13 @@
 	long ret;
 	struct zfcp_qdio_queue *req_q = &adapter->req_q;
 
-	spin_unlock(&req_q->lock);
+	spin_unlock_bh(&req_q->lock);
 	ret = wait_event_interruptible_timeout(adapter->request_wq,
 					zfcp_fsf_sbal_check(req_q), 5 * HZ);
 	if (ret > 0)
 		return 0;
 
-	spin_lock(&req_q->lock);
+	spin_lock_bh(&req_q->lock);
 	return -EIO;
 }
 
@@ -870,14 +870,14 @@
 	volatile struct qdio_buffer_element *sbale;
 	int retval = -EIO;
 
-	spin_lock(&adapter->req_q.lock);
+	spin_lock_bh(&adapter->req_q.lock);
 	if (zfcp_fsf_req_sbal_get(adapter))
 		goto out;
 
 	req = zfcp_fsf_req_create(adapter, FSF_QTCB_UNSOLICITED_STATUS,
 				  ZFCP_REQ_NO_QTCB,
 				  adapter->pool.fsf_req_status_read);
-	if (unlikely(IS_ERR(req))) {
+	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
@@ -910,7 +910,7 @@
 	zfcp_fsf_req_free(req);
 	zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL);
 out:
-	spin_unlock(&adapter->req_q.lock);
+	spin_unlock_bh(&adapter->req_q.lock);
 	return retval;
 }
 
@@ -988,7 +988,7 @@
 		goto out;
 	req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND,
 				  req_flags, adapter->pool.fsf_req_abort);
-	if (unlikely(IS_ERR(req)))
+	if (IS_ERR(req))
 		goto out;
 
 	if (unlikely(!(atomic_read(&unit->status) &
@@ -1106,13 +1106,13 @@
 	struct zfcp_fsf_req *req;
 	int ret = -EIO;
 
-	spin_lock(&adapter->req_q.lock);
+	spin_lock_bh(&adapter->req_q.lock);
 	if (zfcp_fsf_req_sbal_get(adapter))
 		goto out;
 
 	req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_GENERIC,
 				  ZFCP_REQ_AUTO_CLEANUP, pool);
-	if (unlikely(IS_ERR(req))) {
+	if (IS_ERR(req)) {
 		ret = PTR_ERR(req);
 		goto out;
 	}
@@ -1148,7 +1148,7 @@
 	if (erp_action)
 		erp_action->fsf_req = NULL;
 out:
-	spin_unlock(&adapter->req_q.lock);
+	spin_unlock_bh(&adapter->req_q.lock);
 	return ret;
 }
 
@@ -1223,7 +1223,7 @@
 		goto out;
 	req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_ELS,
 				  ZFCP_REQ_AUTO_CLEANUP, NULL);
-	if (unlikely(IS_ERR(req))) {
+	if (IS_ERR(req)) {
 		ret = PTR_ERR(req);
 		goto out;
 	}
@@ -1263,14 +1263,14 @@
 	struct zfcp_adapter *adapter = erp_action->adapter;
 	int retval = -EIO;
 
-	spin_lock(&adapter->req_q.lock);
+	spin_lock_bh(&adapter->req_q.lock);
 	if (!atomic_read(&adapter->req_q.count))
 		goto out;
 	req = zfcp_fsf_req_create(adapter,
 				  FSF_QTCB_EXCHANGE_CONFIG_DATA,
 				  ZFCP_REQ_AUTO_CLEANUP,
 				  adapter->pool.fsf_req_erp);
-	if (unlikely(IS_ERR(req))) {
+	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
@@ -1295,7 +1295,7 @@
 		erp_action->fsf_req = NULL;
 	}
 out:
-	spin_unlock(&adapter->req_q.lock);
+	spin_unlock_bh(&adapter->req_q.lock);
 	return retval;
 }
 
@@ -1306,13 +1306,13 @@
 	struct zfcp_fsf_req *req = NULL;
 	int retval = -EIO;
 
-	spin_lock(&adapter->req_q.lock);
+	spin_lock_bh(&adapter->req_q.lock);
 	if (zfcp_fsf_req_sbal_get(adapter))
 		goto out;
 
 	req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA,
 				  0, NULL);
-	if (unlikely(IS_ERR(req))) {
+	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
@@ -1334,7 +1334,7 @@
 	zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
 	retval = zfcp_fsf_req_send(req);
 out:
-	spin_unlock(&adapter->req_q.lock);
+	spin_unlock_bh(&adapter->req_q.lock);
 	if (!retval)
 		wait_event(req->completion_wq,
 			   req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
@@ -1359,13 +1359,13 @@
 	if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT))
 		return -EOPNOTSUPP;
 
-	spin_lock(&adapter->req_q.lock);
+	spin_lock_bh(&adapter->req_q.lock);
 	if (!atomic_read(&adapter->req_q.count))
 		goto out;
 	req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
 				  ZFCP_REQ_AUTO_CLEANUP,
 				  adapter->pool.fsf_req_erp);
-	if (unlikely(IS_ERR(req))) {
+	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
@@ -1385,7 +1385,7 @@
 		erp_action->fsf_req = NULL;
 	}
 out:
-	spin_unlock(&adapter->req_q.lock);
+	spin_unlock_bh(&adapter->req_q.lock);
 	return retval;
 }
 
@@ -1405,13 +1405,13 @@
 	if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT))
 		return -EOPNOTSUPP;
 
-	spin_lock(&adapter->req_q.lock);
+	spin_lock_bh(&adapter->req_q.lock);
 	if (!atomic_read(&adapter->req_q.count))
 		goto out;
 
 	req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 0,
 				  NULL);
-	if (unlikely(IS_ERR(req))) {
+	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
@@ -1427,7 +1427,7 @@
 	zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
 	retval = zfcp_fsf_req_send(req);
 out:
-	spin_unlock(&adapter->req_q.lock);
+	spin_unlock_bh(&adapter->req_q.lock);
 	if (!retval)
 		wait_event(req->completion_wq,
 			   req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
@@ -1531,7 +1531,7 @@
 	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
-	spin_lock(&adapter->req_q.lock);
+	spin_lock_bh(&adapter->req_q.lock);
 	if (zfcp_fsf_req_sbal_get(adapter))
 		goto out;
 
@@ -1539,7 +1539,7 @@
 				  FSF_QTCB_OPEN_PORT_WITH_DID,
 				  ZFCP_REQ_AUTO_CLEANUP,
 				  adapter->pool.fsf_req_erp);
-	if (unlikely(IS_ERR(req))) {
+	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
@@ -1562,7 +1562,7 @@
 		erp_action->fsf_req = NULL;
 	}
 out:
-	spin_unlock(&adapter->req_q.lock);
+	spin_unlock_bh(&adapter->req_q.lock);
 	return retval;
 }
 
@@ -1603,14 +1603,14 @@
 	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
-	spin_lock(&adapter->req_q.lock);
+	spin_lock_bh(&adapter->req_q.lock);
 	if (zfcp_fsf_req_sbal_get(adapter))
 		goto out;
 
 	req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PORT,
 				  ZFCP_REQ_AUTO_CLEANUP,
 				  adapter->pool.fsf_req_erp);
-	if (unlikely(IS_ERR(req))) {
+	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
@@ -1633,7 +1633,7 @@
 		erp_action->fsf_req = NULL;
 	}
 out:
-	spin_unlock(&adapter->req_q.lock);
+	spin_unlock_bh(&adapter->req_q.lock);
 	return retval;
 }
 
@@ -1700,14 +1700,14 @@
 	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
-	spin_lock(&adapter->req_q.lock);
+	spin_lock_bh(&adapter->req_q.lock);
 	if (zfcp_fsf_req_sbal_get(adapter))
 		goto out;
 
 	req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PHYSICAL_PORT,
 				  ZFCP_REQ_AUTO_CLEANUP,
 				  adapter->pool.fsf_req_erp);
-	if (unlikely(IS_ERR(req))) {
+	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
@@ -1731,7 +1731,7 @@
 		erp_action->fsf_req = NULL;
 	}
 out:
-	spin_unlock(&adapter->req_q.lock);
+	spin_unlock_bh(&adapter->req_q.lock);
 	return retval;
 }
 
@@ -1875,14 +1875,14 @@
 	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
-	spin_lock(&adapter->req_q.lock);
+	spin_lock_bh(&adapter->req_q.lock);
 	if (zfcp_fsf_req_sbal_get(adapter))
 		goto out;
 
 	req = zfcp_fsf_req_create(adapter, FSF_QTCB_OPEN_LUN,
 				  ZFCP_REQ_AUTO_CLEANUP,
 				  adapter->pool.fsf_req_erp);
-	if (unlikely(IS_ERR(req))) {
+	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
@@ -1910,7 +1910,7 @@
 		erp_action->fsf_req = NULL;
 	}
 out:
-	spin_unlock(&adapter->req_q.lock);
+	spin_unlock_bh(&adapter->req_q.lock);
 	return retval;
 }
 
@@ -1965,13 +1965,13 @@
 	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
-	spin_lock(&adapter->req_q.lock);
+	spin_lock_bh(&adapter->req_q.lock);
 	if (zfcp_fsf_req_sbal_get(adapter))
 		goto out;
 	req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_LUN,
 				  ZFCP_REQ_AUTO_CLEANUP,
 				  adapter->pool.fsf_req_erp);
-	if (unlikely(IS_ERR(req))) {
+	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
@@ -1995,7 +1995,7 @@
 		erp_action->fsf_req = NULL;
 	}
 out:
-	spin_unlock(&adapter->req_q.lock);
+	spin_unlock_bh(&adapter->req_q.lock);
 	return retval;
 }
 
@@ -2228,7 +2228,7 @@
 		goto out;
 	req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags,
 				  adapter->pool.fsf_req_scsi);
-	if (unlikely(IS_ERR(req))) {
+	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
@@ -2351,7 +2351,7 @@
 		goto out;
 	req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags,
 				  adapter->pool.fsf_req_scsi);
-	if (unlikely(IS_ERR(req)))
+	if (IS_ERR(req))
 		goto out;
 
 	req->status |= ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT;
@@ -2417,12 +2417,12 @@
 		return ERR_PTR(-EINVAL);
 	}
 
-	spin_lock(&adapter->req_q.lock);
+	spin_lock_bh(&adapter->req_q.lock);
 	if (zfcp_fsf_req_sbal_get(adapter))
 		goto out;
 
 	req = zfcp_fsf_req_create(adapter, fsf_cfdc->command, 0, NULL);
-	if (unlikely(IS_ERR(req))) {
+	if (IS_ERR(req)) {
 		retval = -EPERM;
 		goto out;
 	}
@@ -2447,7 +2447,7 @@
 	zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
 	retval = zfcp_fsf_req_send(req);
 out:
-	spin_unlock(&adapter->req_q.lock);
+	spin_unlock_bh(&adapter->req_q.lock);
 
 	if (!retval) {
 		wait_event(req->completion_wq,
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index d6dbd65..69d632d 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -423,9 +423,9 @@
 
 	/* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */
 	req_q = &adapter->req_q;
-	spin_lock(&req_q->lock);
+	spin_lock_bh(&req_q->lock);
 	atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
-	spin_unlock(&req_q->lock);
+	spin_unlock_bh(&req_q->lock);
 
 	qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR);
 
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index c7f0629..4e0322b 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -63,7 +63,7 @@
 config BLK_DEV_SD
 	tristate "SCSI disk support"
 	depends on SCSI
-	select CRC_T10DIF
+	select CRC_T10DIF if BLK_DEV_INTEGRITY
 	---help---
 	  If you want to use SCSI hard disks, Fibre Channel disks,
 	  Serial ATA (SATA) or Parallel ATA (PATA) hard disks,
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index 994da56..708e475 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -425,7 +425,7 @@
 			/*
 			 * LUN Not Accessible - ALUA state transition
 			 */
-			return NEEDS_RETRY;
+			return ADD_TO_MLQUEUE;
 		if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0b)
 			/*
 			 * LUN Not Accessible -- Target port in standby state
@@ -447,18 +447,18 @@
 			/*
 			 * Power On, Reset, or Bus Device Reset, just retry.
 			 */
-			return NEEDS_RETRY;
+			return ADD_TO_MLQUEUE;
 		if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x06) {
 			/*
 			 * ALUA state changed
 			 */
-			return NEEDS_RETRY;
+			return ADD_TO_MLQUEUE;
 		}
 		if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x07) {
 			/*
 			 * Implicit ALUA state transition failed
 			 */
-			return NEEDS_RETRY;
+			return ADD_TO_MLQUEUE;
 		}
 		break;
 	}
@@ -490,7 +490,7 @@
 		if (!err)
 			return SCSI_DH_IO;
 		err = alua_check_sense(sdev, &sense_hdr);
-		if (retry > 0 && err == NEEDS_RETRY) {
+		if (retry > 0 && err == ADD_TO_MLQUEUE) {
 			retry--;
 			goto retry;
 		}
@@ -535,7 +535,7 @@
 			return SCSI_DH_IO;
 
 		err = alua_check_sense(sdev, &sense_hdr);
-		if (err == NEEDS_RETRY)
+		if (err == ADD_TO_MLQUEUE)
 			goto retry;
 		sdev_printk(KERN_INFO, sdev,
 			    "%s: rtpg sense code %02x/%02x/%02x\n",
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c
index b9d23e9..ef693e84 100644
--- a/drivers/scsi/device_handler/scsi_dh_emc.c
+++ b/drivers/scsi/device_handler/scsi_dh_emc.c
@@ -439,7 +439,7 @@
 			 * Unit Attention Code. This is the first IO
 			 * to the new path, so just retry.
 			 */
-			return NEEDS_RETRY;
+			return ADD_TO_MLQUEUE;
 		break;
 	}
 
@@ -514,7 +514,7 @@
 			return SCSI_DH_IO;
 
 		err = clariion_check_sense(sdev, &sshdr);
-		if (retry > 0 && err == NEEDS_RETRY) {
+		if (retry > 0 && err == ADD_TO_MLQUEUE) {
 			retry--;
 			goto retry;
 		}
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 2dee69d..6e2f130 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -551,7 +551,7 @@
 			 *
 			 * Just retry and wait.
 			 */
-			return NEEDS_RETRY;
+			return ADD_TO_MLQUEUE;
 		break;
 	case ILLEGAL_REQUEST:
 		if (sense_hdr->asc == 0x94 && sense_hdr->ascq == 0x01) {
@@ -568,7 +568,7 @@
 			/*
 			 * Power On, Reset, or Bus Device Reset, just retry.
 			 */
-			return NEEDS_RETRY;
+			return ADD_TO_MLQUEUE;
 		break;
 	}
 	/* success just means we do not care what scsi-ml does */
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 880051c..39ce3ab 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -391,7 +391,7 @@
 
 	case HARDWARE_ERROR:
 		if (scmd->device->retry_hwerror)
-			return NEEDS_RETRY;
+			return ADD_TO_MLQUEUE;
 		else
 			return SUCCESS;
 
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 84b4879..34d0de6 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1080,7 +1080,8 @@
 	 * PDT=1Fh none (no FDD connected to the requested logical unit)
 	 */
 	if (((result[0] >> 5) == 1 || starget->pdt_1f_for_no_lun) &&
-	     (result[0] & 0x1f) == 0x1f) {
+	    (result[0] & 0x1f) == 0x1f &&
+	    !scsi_is_wlun(lun)) {
 		SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
 					"scsi scan: peripheral device type"
 					" of 31, no device added\n"));
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 2a2bc89..e5e7d78 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1875,7 +1875,6 @@
 
 	dev_set_drvdata(dev, sdkp);
 	add_disk(gd);
-	blk_register_filter(gd);
 	sd_dif_config_host(sdkp);
 
 	sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
@@ -1909,7 +1908,6 @@
 	struct scsi_disk *sdkp = dev_get_drvdata(dev);
 
 	device_del(&sdkp->dev);
-	blk_unregister_filter(sdkp->disk);
 	del_gendisk(sdkp->disk);
 	sd_shutdown(dev);
 
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 3292965..27f5bfd 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -656,7 +656,6 @@
 	dev_set_drvdata(dev, cd);
 	disk->flags |= GENHD_FL_REMOVABLE;
 	add_disk(disk);
-	blk_register_filter(disk);
 
 	sdev_printk(KERN_DEBUG, sdev,
 		    "Attached scsi CD-ROM %s\n", cd->cdi.name);
@@ -895,7 +894,6 @@
 {
 	struct scsi_cd *cd = dev_get_drvdata(dev);
 
-	blk_unregister_filter(cd->disk);
 	del_gendisk(cd->disk);
 
 	mutex_lock(&sr_ref_mutex);
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 6a29f93..3f90f1b 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -127,8 +127,13 @@
 #define  UCR3_RXDSEN	 (1<<6)  /* Receive status interrupt enable */
 #define  UCR3_AIRINTEN   (1<<5)  /* Async IR wake interrupt enable */
 #define  UCR3_AWAKEN	 (1<<4)  /* Async wake interrupt enable */
-#define  UCR3_REF25 	 (1<<3)  /* Ref freq 25 MHz */
-#define  UCR3_REF30 	 (1<<2)  /* Ref Freq 30 MHz */
+#ifdef CONFIG_ARCH_IMX
+#define  UCR3_REF25 	 (1<<3)  /* Ref freq 25 MHz, only on mx1 */
+#define  UCR3_REF30 	 (1<<2)  /* Ref Freq 30 MHz, only on mx1 */
+#endif
+#if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3
+#define  UCR3_RXDMUXSEL	 (1<<2)  /* RXD Muxed Input Select, on mx2/mx3 */
+#endif
 #define  UCR3_INVT  	 (1<<1)  /* Inverted Infrared transmission */
 #define  UCR3_BPEN  	 (1<<0)  /* Preset registers enable */
 #define  UCR4_CTSTL_32   (32<<10) /* CTS trigger level (32 chars) */
@@ -445,7 +450,7 @@
 			readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN)
 		imx_txint(irq, dev_id);
 
-	if (sts & USR1_RTSS)
+	if (sts & USR1_RTSD)
 		imx_rtsint(irq, dev_id);
 
 	return IRQ_HANDLED;
@@ -598,6 +603,12 @@
 	temp |= (UCR2_RXEN | UCR2_TXEN);
 	writel(temp, sport->port.membase + UCR2);
 
+#if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3
+	temp = readl(sport->port.membase + UCR3);
+	temp |= UCR3_RXDMUXSEL;
+	writel(temp, sport->port.membase + UCR3);
+#endif
+
 	/*
 	 * Enable modem status interrupts
 	 */
@@ -1133,13 +1144,19 @@
 	if(pdata && (pdata->flags & IMXUART_HAVE_RTSCTS))
 		sport->have_rtscts = 1;
 
-	if (pdata->init)
-		pdata->init(pdev);
+	if (pdata->init) {
+		ret = pdata->init(pdev);
+		if (ret)
+			goto clkput;
+	}
 
 	uart_add_one_port(&imx_reg, &sport->port);
 	platform_set_drvdata(pdev, &sport->port);
 
 	return 0;
+clkput:
+	clk_put(sport->clk);
+	clk_disable(sport->clk);
 unmap:
 	iounmap(sport->port.membase);
 free:
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index f7a0d37..abc00be 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -534,6 +534,11 @@
 
 	serial_out(up, UART_IER, up->ier);
 
+	if (termios->c_cflag & CRTSCTS)
+		up->mcr |= UART_MCR_AFE;
+	else
+		up->mcr &= ~UART_MCR_AFE;
+
 	serial_out(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
 	serial_out(up, UART_DLL, quot & 0xff);		/* LS of divisor */
 	serial_out(up, UART_DLM, quot >> 8);		/* MS of divisor */
diff --git a/drivers/serial/serial_ks8695.c b/drivers/serial/serial_ks8695.c
index b9cbfc8..998e89d 100644
--- a/drivers/serial/serial_ks8695.c
+++ b/drivers/serial/serial_ks8695.c
@@ -63,8 +63,44 @@
 #define UART_DUMMY_LSR_RX	0x100
 #define UART_PORT_SIZE		(KS8695_USR - KS8695_URRB + 4)
 
-#define tx_enabled(port) ((port)->unused[0])
-#define rx_enabled(port) ((port)->unused[1])
+static inline int tx_enabled(struct uart_port *port)
+{
+	return port->unused[0] & 1;
+}
+
+static inline int rx_enabled(struct uart_port *port)
+{
+	return port->unused[0] & 2;
+}
+
+static inline int ms_enabled(struct uart_port *port)
+{
+	return port->unused[0] & 4;
+}
+
+static inline void ms_enable(struct uart_port *port, int enabled)
+{
+	if(enabled)
+		port->unused[0] |= 4;
+	else
+		port->unused[0] &= ~4;
+}
+
+static inline void rx_enable(struct uart_port *port, int enabled)
+{
+	if(enabled)
+		port->unused[0] |= 2;
+	else
+		port->unused[0] &= ~2;
+}
+
+static inline void tx_enable(struct uart_port *port, int enabled)
+{
+	if(enabled)
+		port->unused[0] |= 1;
+	else
+		port->unused[0] &= ~1;
+}
 
 
 #ifdef SUPPORT_SYSRQ
@@ -75,7 +111,7 @@
 {
 	if (tx_enabled(port)) {
 		disable_irq(KS8695_IRQ_UART_TX);
-		tx_enabled(port) = 0;
+		tx_enable(port, 0);
 	}
 }
 
@@ -83,7 +119,7 @@
 {
 	if (!tx_enabled(port)) {
 		enable_irq(KS8695_IRQ_UART_TX);
-		tx_enabled(port) = 1;
+		tx_enable(port, 1);
 	}
 }
 
@@ -91,18 +127,24 @@
 {
 	if (rx_enabled(port)) {
 		disable_irq(KS8695_IRQ_UART_RX);
-		rx_enabled(port) = 0;
+		rx_enable(port, 0);
 	}
 }
 
 static void ks8695uart_enable_ms(struct uart_port *port)
 {
-	enable_irq(KS8695_IRQ_UART_MODEM_STATUS);
+	if (!ms_enabled(port)) {
+		enable_irq(KS8695_IRQ_UART_MODEM_STATUS);
+		ms_enable(port,1);
+	}
 }
 
 static void ks8695uart_disable_ms(struct uart_port *port)
 {
-	disable_irq(KS8695_IRQ_UART_MODEM_STATUS);
+	if (ms_enabled(port)) {
+		disable_irq(KS8695_IRQ_UART_MODEM_STATUS);
+		ms_enable(port,0);
+	}
 }
 
 static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id)
@@ -285,8 +327,9 @@
 	int retval;
 
 	set_irq_flags(KS8695_IRQ_UART_TX, IRQF_VALID | IRQF_NOAUTOEN);
-	tx_enabled(port) = 0;
-	rx_enabled(port) = 1;
+	tx_enable(port, 0);
+	rx_enable(port, 1);
+	ms_enable(port, 1);
 
 	/*
 	 * Allocate the IRQ
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index 34c7c98..0e53354 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -47,9 +47,10 @@
 
 #define MAX_BUSES 3
 
-#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
-#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
-#define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0)
+#define DMA_INT_MASK		(DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
+#define RESET_DMA_CHANNEL	(DCSR_NODESC | DMA_INT_MASK)
+#define IS_DMA_ALIGNED(x)	(((x) & 0x07) == 0)
+#define MAX_DMA_LEN		8191
 
 /*
  * for testing SSCR1 changes that require SSP restart, basically
@@ -144,7 +145,6 @@
 	size_t tx_map_len;
 	u8 n_bytes;
 	u32 dma_width;
-	int cs_change;
 	int (*write)(struct driver_data *drv_data);
 	int (*read)(struct driver_data *drv_data);
 	irqreturn_t (*transfer_handler)(struct driver_data *drv_data);
@@ -406,8 +406,45 @@
 					struct spi_transfer,
 					transfer_list);
 
+	/* Delay if requested before any change in chip select */
+	if (last_transfer->delay_usecs)
+		udelay(last_transfer->delay_usecs);
+
+	/* Drop chip select UNLESS cs_change is true or we are returning
+	 * a message with an error, or next message is for another chip
+	 */
 	if (!last_transfer->cs_change)
 		drv_data->cs_control(PXA2XX_CS_DEASSERT);
+	else {
+		struct spi_message *next_msg;
+
+		/* Holding of cs was hinted, but we need to make sure
+		 * the next message is for the same chip.  Don't waste
+		 * time with the following tests unless this was hinted.
+		 *
+		 * We cannot postpone this until pump_messages, because
+		 * after calling msg->complete (below) the driver that
+		 * sent the current message could be unloaded, which
+		 * could invalidate the cs_control() callback...
+		 */
+
+		/* get a pointer to the next message, if any */
+		spin_lock_irqsave(&drv_data->lock, flags);
+		if (list_empty(&drv_data->queue))
+			next_msg = NULL;
+		else
+			next_msg = list_entry(drv_data->queue.next,
+					struct spi_message, queue);
+		spin_unlock_irqrestore(&drv_data->lock, flags);
+
+		/* see if the next and current messages point
+		 * to the same chip
+		 */
+		if (next_msg && next_msg->spi != msg->spi)
+			next_msg = NULL;
+		if (!next_msg || msg->state == ERROR_STATE)
+			drv_data->cs_control(PXA2XX_CS_DEASSERT);
+	}
 
 	msg->state = NULL;
 	if (msg->complete)
@@ -490,10 +527,9 @@
 	msg->actual_length += drv_data->len -
 				(drv_data->rx_end - drv_data->rx);
 
-	/* Release chip select if requested, transfer delays are
-	 * handled in pump_transfers */
-	if (drv_data->cs_change)
-		drv_data->cs_control(PXA2XX_CS_DEASSERT);
+	/* Transfer delays and chip select release are
+	 * handled in pump_transfers or giveback
+	 */
 
 	/* Move to next transfer */
 	msg->state = next_transfer(drv_data);
@@ -602,10 +638,9 @@
 	drv_data->cur_msg->actual_length += drv_data->len -
 				(drv_data->rx_end - drv_data->rx);
 
-	/* Release chip select if requested, transfer delays are
-	 * handled in pump_transfers */
-	if (drv_data->cs_change)
-		drv_data->cs_control(PXA2XX_CS_DEASSERT);
+	/* Transfer delays and chip select release are
+	 * handled in pump_transfers or giveback
+	 */
 
 	/* Move to next transfer */
 	drv_data->cur_msg->state = next_transfer(drv_data);
@@ -840,23 +875,40 @@
 		return;
 	}
 
-	/* Delay if requested at end of transfer*/
+	/* Delay if requested at end of transfer before CS change */
 	if (message->state == RUNNING_STATE) {
 		previous = list_entry(transfer->transfer_list.prev,
 					struct spi_transfer,
 					transfer_list);
 		if (previous->delay_usecs)
 			udelay(previous->delay_usecs);
+
+		/* Drop chip select only if cs_change is requested */
+		if (previous->cs_change)
+			drv_data->cs_control(PXA2XX_CS_DEASSERT);
 	}
 
-	/* Check transfer length */
-	if (transfer->len > 8191)
-	{
-		dev_warn(&drv_data->pdev->dev, "pump_transfers: transfer "
-				"length greater than 8191\n");
-		message->status = -EINVAL;
-		giveback(drv_data);
-		return;
+	/* Check for transfers that need multiple DMA segments */
+	if (transfer->len > MAX_DMA_LEN && chip->enable_dma) {
+
+		/* reject already-mapped transfers; PIO won't always work */
+		if (message->is_dma_mapped
+				|| transfer->rx_dma || transfer->tx_dma) {
+			dev_err(&drv_data->pdev->dev,
+				"pump_transfers: mapped transfer length "
+				"of %lu is greater than %d\n",
+				transfer->len, MAX_DMA_LEN);
+			message->status = -EINVAL;
+			giveback(drv_data);
+			return;
+		}
+
+		/* warn ... we force this to PIO mode */
+		if (printk_ratelimit())
+			dev_warn(&message->spi->dev, "pump_transfers: "
+				"DMA disabled for transfer length %ld "
+				"greater than %d\n",
+				(long)drv_data->len, MAX_DMA_LEN);
 	}
 
 	/* Setup the transfer state based on the type of transfer */
@@ -878,7 +930,6 @@
 	drv_data->len = transfer->len & DCMD_LENGTH;
 	drv_data->write = drv_data->tx ? chip->write : null_writer;
 	drv_data->read = drv_data->rx ? chip->read : null_reader;
-	drv_data->cs_change = transfer->cs_change;
 
 	/* Change speed and bit per word on a per transfer */
 	cr0 = chip->cr0;
@@ -925,7 +976,7 @@
 							&dma_thresh))
 				if (printk_ratelimit())
 					dev_warn(&message->spi->dev,
-						"pump_transfer: "
+						"pump_transfers: "
 						"DMA burst size reduced to "
 						"match bits_per_word\n");
 		}
@@ -939,8 +990,23 @@
 
 	message->state = RUNNING_STATE;
 
-	/* Try to map dma buffer and do a dma transfer if successful */
-	if ((drv_data->dma_mapped = map_dma_buffers(drv_data))) {
+	/* Try to map dma buffer and do a dma transfer if successful, but
+	 * only if the length is non-zero and less than MAX_DMA_LEN.
+	 *
+	 * Zero-length non-descriptor DMA is illegal on PXA2xx; force use
+	 * of PIO instead.  Care is needed above because the transfer may
+	 * have have been passed with buffers that are already dma mapped.
+	 * A zero-length transfer in PIO mode will not try to write/read
+	 * to/from the buffers
+	 *
+	 * REVISIT large transfers are exactly where we most want to be
+	 * using DMA.  If this happens much, split those transfers into
+	 * multiple DMA segments rather than forcing PIO.
+	 */
+	drv_data->dma_mapped = 0;
+	if (drv_data->len > 0 && drv_data->len <= MAX_DMA_LEN)
+		drv_data->dma_mapped = map_dma_buffers(drv_data);
+	if (drv_data->dma_mapped) {
 
 		/* Ensure we have the correct interrupt handler */
 		drv_data->transfer_handler = dma_transfer;
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index 070c621..ac0e3e4 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -267,16 +267,13 @@
 	cs->hw_mode |= SPMODE_LEN(bits_per_word);
 
 	if ((mpc83xx_spi->spibrg / hz) > 64) {
+		cs->hw_mode |= SPMODE_DIV16;
 		pm = mpc83xx_spi->spibrg / (hz * 64);
 		if (pm > 16) {
-			cs->hw_mode |= SPMODE_DIV16;
-			pm /= 16;
-			if (pm > 16) {
-				dev_err(&spi->dev, "Requested speed is too "
-					"low: %d Hz. Will use %d Hz instead.\n",
-					hz, mpc83xx_spi->spibrg / 1024);
-				pm = 16;
-			}
+			dev_err(&spi->dev, "Requested speed is too "
+				"low: %d Hz. Will use %d Hz instead.\n",
+				hz, mpc83xx_spi->spibrg / 1024);
+			pm = 16;
 		}
 	} else
 		pm = mpc83xx_spi->spibrg / (hz * 4);
@@ -315,11 +312,20 @@
 	if (t->bits_per_word)
 		bits_per_word = t->bits_per_word;
 	len = t->len;
-	if (bits_per_word > 8)
+	if (bits_per_word > 8) {
+		/* invalid length? */
+		if (len & 1)
+			return -EINVAL;
 		len /= 2;
-	if (bits_per_word > 16)
+	}
+	if (bits_per_word > 16) {
+		/* invalid length? */
+		if (len & 1)
+			return -EINVAL;
 		len /= 2;
+	}
 	mpc83xx_spi->count = len;
+
 	INIT_COMPLETION(mpc83xx_spi->done);
 
 	/* enable rx ints */
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c
index 98abc73..3eb414b 100644
--- a/drivers/spi/spi_s3c24xx.c
+++ b/drivers/spi/spi_s3c24xx.c
@@ -430,7 +430,7 @@
 #endif
 
 MODULE_ALIAS("platform:s3c2410-spi");
-static struct platform_driver s3c24xx_spidrv = {
+static struct platform_driver s3c24xx_spi_driver = {
 	.remove		= __exit_p(s3c24xx_spi_remove),
 	.suspend	= s3c24xx_spi_suspend,
 	.resume		= s3c24xx_spi_resume,
@@ -442,12 +442,12 @@
 
 static int __init s3c24xx_spi_init(void)
 {
-        return platform_driver_probe(&s3c24xx_spidrv, s3c24xx_spi_probe);
+        return platform_driver_probe(&s3c24xx_spi_driver, s3c24xx_spi_probe);
 }
 
 static void __exit s3c24xx_spi_exit(void)
 {
-        platform_driver_unregister(&s3c24xx_spidrv);
+        platform_driver_unregister(&s3c24xx_spi_driver);
 }
 
 module_init(s3c24xx_spi_init);
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index 7f0f35c..e294d43 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -23,17 +23,90 @@
 #include <linux/signal.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
-
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h> /* FIXME: for PSSR */
 #include <mach/ohci.h>
 
+/*
+ * UHC: USB Host Controller (OHCI-like) register definitions
+ */
+#define UHCREV		(0x0000) /* UHC HCI Spec Revision */
+#define UHCHCON		(0x0004) /* UHC Host Control Register */
+#define UHCCOMS		(0x0008) /* UHC Command Status Register */
+#define UHCINTS		(0x000C) /* UHC Interrupt Status Register */
+#define UHCINTE		(0x0010) /* UHC Interrupt Enable */
+#define UHCINTD		(0x0014) /* UHC Interrupt Disable */
+#define UHCHCCA		(0x0018) /* UHC Host Controller Comm. Area */
+#define UHCPCED		(0x001C) /* UHC Period Current Endpt Descr */
+#define UHCCHED		(0x0020) /* UHC Control Head Endpt Descr */
+#define UHCCCED		(0x0024) /* UHC Control Current Endpt Descr */
+#define UHCBHED		(0x0028) /* UHC Bulk Head Endpt Descr */
+#define UHCBCED		(0x002C) /* UHC Bulk Current Endpt Descr */
+#define UHCDHEAD	(0x0030) /* UHC Done Head */
+#define UHCFMI		(0x0034) /* UHC Frame Interval */
+#define UHCFMR		(0x0038) /* UHC Frame Remaining */
+#define UHCFMN		(0x003C) /* UHC Frame Number */
+#define UHCPERS		(0x0040) /* UHC Periodic Start */
+#define UHCLS		(0x0044) /* UHC Low Speed Threshold */
+
+#define UHCRHDA		(0x0048) /* UHC Root Hub Descriptor A */
+#define UHCRHDA_NOCP	(1 << 12)	/* No over current protection */
+#define UHCRHDA_OCPM	(1 << 11)	/* Over Current Protection Mode */
+#define UHCRHDA_POTPGT(x) \
+			(((x) & 0xff) << 24) /* Power On To Power Good Time */
+
+#define UHCRHDB		(0x004C) /* UHC Root Hub Descriptor B */
+#define UHCRHS		(0x0050) /* UHC Root Hub Status */
+#define UHCRHPS1	(0x0054) /* UHC Root Hub Port 1 Status */
+#define UHCRHPS2	(0x0058) /* UHC Root Hub Port 2 Status */
+#define UHCRHPS3	(0x005C) /* UHC Root Hub Port 3 Status */
+
+#define UHCSTAT		(0x0060) /* UHC Status Register */
+#define UHCSTAT_UPS3	(1 << 16)	/* USB Power Sense Port3 */
+#define UHCSTAT_SBMAI	(1 << 15)	/* System Bus Master Abort Interrupt*/
+#define UHCSTAT_SBTAI	(1 << 14)	/* System Bus Target Abort Interrupt*/
+#define UHCSTAT_UPRI	(1 << 13)	/* USB Port Resume Interrupt */
+#define UHCSTAT_UPS2	(1 << 12)	/* USB Power Sense Port 2 */
+#define UHCSTAT_UPS1	(1 << 11)	/* USB Power Sense Port 1 */
+#define UHCSTAT_HTA	(1 << 10)	/* HCI Target Abort */
+#define UHCSTAT_HBA	(1 << 8)	/* HCI Buffer Active */
+#define UHCSTAT_RWUE	(1 << 7)	/* HCI Remote Wake Up Event */
+
+#define UHCHR           (0x0064) /* UHC Reset Register */
+#define UHCHR_SSEP3	(1 << 11)	/* Sleep Standby Enable for Port3 */
+#define UHCHR_SSEP2	(1 << 10)	/* Sleep Standby Enable for Port2 */
+#define UHCHR_SSEP1	(1 << 9)	/* Sleep Standby Enable for Port1 */
+#define UHCHR_PCPL	(1 << 7)	/* Power control polarity low */
+#define UHCHR_PSPL	(1 << 6)	/* Power sense polarity low */
+#define UHCHR_SSE	(1 << 5)	/* Sleep Standby Enable */
+#define UHCHR_UIT	(1 << 4)	/* USB Interrupt Test */
+#define UHCHR_SSDC	(1 << 3)	/* Simulation Scale Down Clock */
+#define UHCHR_CGR	(1 << 2)	/* Clock Generation Reset */
+#define UHCHR_FHR	(1 << 1)	/* Force Host Controller Reset */
+#define UHCHR_FSBIR	(1 << 0)	/* Force System Bus Iface Reset */
+
+#define UHCHIE          (0x0068) /* UHC Interrupt Enable Register*/
+#define UHCHIE_UPS3IE	(1 << 14)	/* Power Sense Port3 IntEn */
+#define UHCHIE_UPRIE	(1 << 13)	/* Port Resume IntEn */
+#define UHCHIE_UPS2IE	(1 << 12)	/* Power Sense Port2 IntEn */
+#define UHCHIE_UPS1IE	(1 << 11)	/* Power Sense Port1 IntEn */
+#define UHCHIE_TAIE	(1 << 10)	/* HCI Interface Transfer Abort
+					   Interrupt Enable*/
+#define UHCHIE_HBAIE	(1 << 8)	/* HCI Buffer Active IntEn */
+#define UHCHIE_RWIE	(1 << 7)	/* Remote Wake-up IntEn */
+
+#define UHCHIT          (0x006C) /* UHC Interrupt Test register */
+
 #define PXA_UHC_MAX_PORTNUM    3
 
-#define UHCRHPS(x)              __REG2( 0x4C000050, (x)<<2 )
+struct pxa27x_ohci {
+	/* must be 1st member here for hcd_to_ohci() to work */
+	struct ohci_hcd ohci;
 
-static struct clk *usb_clk;
+	struct device	*dev;
+	struct clk	*clk;
+	void __iomem	*mmio_base;
+};
+
+#define to_pxa27x_ohci(hcd)	(struct pxa27x_ohci *)hcd_to_ohci(hcd)
 
 /*
   PMM_NPS_MODE -- PMM Non-power switching mode
@@ -45,30 +118,35 @@
   PMM_PERPORT_MODE -- PMM per port switching mode
       Ports are powered individually.
  */
-static int pxa27x_ohci_select_pmm( int mode )
+static int pxa27x_ohci_select_pmm(struct pxa27x_ohci *ohci, int mode)
 {
-	switch ( mode ) {
+	uint32_t uhcrhda = __raw_readl(ohci->mmio_base + UHCRHDA);
+	uint32_t uhcrhdb = __raw_readl(ohci->mmio_base + UHCRHDB);
+
+	switch (mode) {
 	case PMM_NPS_MODE:
-		UHCRHDA |= RH_A_NPS;
+		uhcrhda |= RH_A_NPS;
 		break;
 	case PMM_GLOBAL_MODE:
-		UHCRHDA &= ~(RH_A_NPS & RH_A_PSM);
+		uhcrhda &= ~(RH_A_NPS & RH_A_PSM);
 		break;
 	case PMM_PERPORT_MODE:
-		UHCRHDA &= ~(RH_A_NPS);
-		UHCRHDA |= RH_A_PSM;
+		uhcrhda &= ~(RH_A_NPS);
+		uhcrhda |= RH_A_PSM;
 
 		/* Set port power control mask bits, only 3 ports. */
-		UHCRHDB |= (0x7<<17);
+		uhcrhdb |= (0x7<<17);
 		break;
 	default:
 		printk( KERN_ERR
 			"Invalid mode %d, set to non-power switch mode.\n",
 			mode );
 
-		UHCRHDA |= RH_A_NPS;
+		uhcrhda |= RH_A_NPS;
 	}
 
+	__raw_writel(uhcrhda, ohci->mmio_base + UHCRHDA);
+	__raw_writel(uhcrhdb, ohci->mmio_base + UHCRHDB);
 	return 0;
 }
 
@@ -76,57 +154,110 @@
 
 /*-------------------------------------------------------------------------*/
 
-static int pxa27x_start_hc(struct device *dev)
+static inline void pxa27x_setup_hc(struct pxa27x_ohci *ohci,
+				   struct pxaohci_platform_data *inf)
+{
+	uint32_t uhchr = __raw_readl(ohci->mmio_base + UHCHR);
+	uint32_t uhcrhda = __raw_readl(ohci->mmio_base + UHCRHDA);
+
+	if (inf->flags & ENABLE_PORT1)
+		uhchr &= ~UHCHR_SSEP1;
+
+	if (inf->flags & ENABLE_PORT2)
+		uhchr &= ~UHCHR_SSEP2;
+
+	if (inf->flags & ENABLE_PORT3)
+		uhchr &= ~UHCHR_SSEP3;
+
+	if (inf->flags & POWER_CONTROL_LOW)
+		uhchr |= UHCHR_PCPL;
+
+	if (inf->flags & POWER_SENSE_LOW)
+		uhchr |= UHCHR_PSPL;
+
+	if (inf->flags & NO_OC_PROTECTION)
+		uhcrhda |= UHCRHDA_NOCP;
+
+	if (inf->flags & OC_MODE_PERPORT)
+		uhcrhda |= UHCRHDA_OCPM;
+
+	if (inf->power_on_delay) {
+		uhcrhda &= ~UHCRHDA_POTPGT(0xff);
+		uhcrhda |= UHCRHDA_POTPGT(inf->power_on_delay / 2);
+	}
+
+	__raw_writel(uhchr, ohci->mmio_base + UHCHR);
+	__raw_writel(uhcrhda, ohci->mmio_base + UHCRHDA);
+}
+
+static inline void pxa27x_reset_hc(struct pxa27x_ohci *ohci)
+{
+	uint32_t uhchr = __raw_readl(ohci->mmio_base + UHCHR);
+
+	__raw_writel(uhchr | UHCHR_FHR, ohci->mmio_base + UHCHR);
+	udelay(11);
+	__raw_writel(uhchr & ~UHCHR_FHR, ohci->mmio_base + UHCHR);
+}
+
+#ifdef CONFIG_CPU_PXA27x
+extern void pxa27x_clear_otgph(void);
+#else
+#define pxa27x_clear_otgph()	do {} while (0)
+#endif
+
+static int pxa27x_start_hc(struct pxa27x_ohci *ohci, struct device *dev)
 {
 	int retval = 0;
 	struct pxaohci_platform_data *inf;
+	uint32_t uhchr;
 
 	inf = dev->platform_data;
 
-	clk_enable(usb_clk);
+	clk_enable(ohci->clk);
 
-	UHCHR |= UHCHR_FHR;
-	udelay(11);
-	UHCHR &= ~UHCHR_FHR;
+	pxa27x_reset_hc(ohci);
 
-	UHCHR |= UHCHR_FSBIR;
-	while (UHCHR & UHCHR_FSBIR)
+	uhchr = __raw_readl(ohci->mmio_base + UHCHR) | UHCHR_FSBIR;
+	__raw_writel(uhchr, ohci->mmio_base + UHCHR);
+
+	while (__raw_readl(ohci->mmio_base + UHCHR) & UHCHR_FSBIR)
 		cpu_relax();
 
+	pxa27x_setup_hc(ohci, inf);
+
 	if (inf->init)
 		retval = inf->init(dev);
 
 	if (retval < 0)
 		return retval;
 
-	UHCHR &= ~UHCHR_SSE;
-
-	UHCHIE = (UHCHIE_UPRIE | UHCHIE_RWIE);
+	uhchr = __raw_readl(ohci->mmio_base + UHCHR) & ~UHCHR_SSE;
+	__raw_writel(uhchr, ohci->mmio_base + UHCHR);
+	__raw_writel(UHCHIE_UPRIE | UHCHIE_RWIE, ohci->mmio_base + UHCHIE);
 
 	/* Clear any OTG Pin Hold */
-	if (cpu_is_pxa27x() && (PSSR & PSSR_OTGPH))
-		PSSR |= PSSR_OTGPH;
-
+	pxa27x_clear_otgph();
 	return 0;
 }
 
-static void pxa27x_stop_hc(struct device *dev)
+static void pxa27x_stop_hc(struct pxa27x_ohci *ohci, struct device *dev)
 {
 	struct pxaohci_platform_data *inf;
+	uint32_t uhccoms;
 
 	inf = dev->platform_data;
 
 	if (inf->exit)
 		inf->exit(dev);
 
-	UHCHR |= UHCHR_FHR;
-	udelay(11);
-	UHCHR &= ~UHCHR_FHR;
+	pxa27x_reset_hc(ohci);
 
-	UHCCOMS |= 1;
+	/* Host Controller Reset */
+	uhccoms = __raw_readl(ohci->mmio_base + UHCCOMS) | 0x01;
+	__raw_writel(uhccoms, ohci->mmio_base + UHCCOMS);
 	udelay(10);
 
-	clk_disable(usb_clk);
+	clk_disable(ohci->clk);
 }
 
 
@@ -147,18 +278,22 @@
  */
 int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device *pdev)
 {
-	int retval;
+	int retval, irq;
 	struct usb_hcd *hcd;
 	struct pxaohci_platform_data *inf;
+	struct pxa27x_ohci *ohci;
+	struct resource *r;
+	struct clk *usb_clk;
 
 	inf = pdev->dev.platform_data;
 
 	if (!inf)
 		return -ENODEV;
 
-	if (pdev->resource[1].flags != IORESOURCE_IRQ) {
-		pr_debug ("resource[1] is not IORESOURCE_IRQ");
-		return -ENOMEM;
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		pr_err("no resource of IORESOURCE_IRQ");
+		return -ENXIO;
 	}
 
 	usb_clk = clk_get(&pdev->dev, "USBCLK");
@@ -168,8 +303,16 @@
 	hcd = usb_create_hcd (driver, &pdev->dev, "pxa27x");
 	if (!hcd)
 		return -ENOMEM;
-	hcd->rsrc_start = pdev->resource[0].start;
-	hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r) {
+		pr_err("no resource of IORESOURCE_MEM");
+		retval = -ENXIO;
+		goto err1;
+	}
+
+	hcd->rsrc_start = r->start;
+	hcd->rsrc_len = resource_size(r);
 
 	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
 		pr_debug("request_mem_region failed");
@@ -184,24 +327,30 @@
 		goto err2;
 	}
 
-	if ((retval = pxa27x_start_hc(&pdev->dev)) < 0) {
+	/* initialize "struct pxa27x_ohci" */
+	ohci = (struct pxa27x_ohci *)hcd_to_ohci(hcd);
+	ohci->dev = &pdev->dev;
+	ohci->clk = usb_clk;
+	ohci->mmio_base = (void __iomem *)hcd->regs;
+
+	if ((retval = pxa27x_start_hc(ohci, &pdev->dev)) < 0) {
 		pr_debug("pxa27x_start_hc failed");
 		goto err3;
 	}
 
 	/* Select Power Management Mode */
-	pxa27x_ohci_select_pmm(inf->port_mode);
+	pxa27x_ohci_select_pmm(ohci, inf->port_mode);
 
 	if (inf->power_budget)
 		hcd->power_budget = inf->power_budget;
 
 	ohci_hcd_init(hcd_to_ohci(hcd));
 
-	retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_DISABLED);
+	retval = usb_add_hcd(hcd, irq, IRQF_DISABLED);
 	if (retval == 0)
 		return retval;
 
-	pxa27x_stop_hc(&pdev->dev);
+	pxa27x_stop_hc(ohci, &pdev->dev);
  err3:
 	iounmap(hcd->regs);
  err2:
@@ -228,12 +377,14 @@
  */
 void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 {
+	struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
+
 	usb_remove_hcd(hcd);
-	pxa27x_stop_hc(&pdev->dev);
+	pxa27x_stop_hc(ohci, &pdev->dev);
 	iounmap(hcd->regs);
 	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 	usb_put_hcd(hcd);
-	clk_put(usb_clk);
+	clk_put(ohci->clk);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -266,7 +417,7 @@
 static const struct hc_driver ohci_pxa27x_hc_driver = {
 	.description =		hcd_name,
 	.product_desc =		"PXA27x OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
+	.hcd_priv_size =	sizeof(struct pxa27x_ohci),
 
 	/*
 	 * generic hardware linkage
@@ -330,13 +481,13 @@
 static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *pdev, pm_message_t state)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(pdev);
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
 
-	if (time_before(jiffies, ohci->next_statechange))
+	if (time_before(jiffies, ohci->ohci.next_statechange))
 		msleep(5);
-	ohci->next_statechange = jiffies;
+	ohci->ohci.next_statechange = jiffies;
 
-	pxa27x_stop_hc(&pdev->dev);
+	pxa27x_stop_hc(ohci, &pdev->dev);
 	hcd->state = HC_STATE_SUSPENDED;
 
 	return 0;
@@ -345,14 +496,14 @@
 static int ohci_hcd_pxa27x_drv_resume(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(pdev);
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
 	int status;
 
-	if (time_before(jiffies, ohci->next_statechange))
+	if (time_before(jiffies, ohci->ohci.next_statechange))
 		msleep(5);
-	ohci->next_statechange = jiffies;
+	ohci->ohci.next_statechange = jiffies;
 
-	if ((status = pxa27x_start_hc(&pdev->dev)) < 0)
+	if ((status = pxa27x_start_hc(ohci, &pdev->dev)) < 0)
 		return status;
 
 	ohci_finish_controller_resume(hcd);
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index 7b74238..e980766 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -161,7 +161,7 @@
 		if (serial->type->set_termios) {
 			termios->c_cflag = cflag;
 			tty_termios_encode_baud_rate(termios, baud, baud);
-			serial->type->set_termios(NULL, port, &dummy);
+			serial->type->set_termios(tty, port, &dummy);
 
 			port->port.tty = NULL;
 			kfree(termios);
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 70d135e..d85a74c 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -172,11 +172,6 @@
 	bool
 	depends on FB
 
-config FB_METRONOME
-	tristate
-	depends on FB
-	depends on FB_DEFERRED_IO
-
 config FB_HECUBA
 	tristate
 	depends on FB
@@ -1974,19 +1969,6 @@
 	  framebuffer. ML300 carries a 640*480 LCD display on the board,
 	  ML403 uses a standard DB15 VGA connector.
 
-config FB_AM200EPD
-       tristate "AM-200 E-Ink EPD devkit support"
-       depends on FB && ARCH_PXA && MMU
-       select FB_SYS_FILLRECT
-       select FB_SYS_COPYAREA
-       select FB_SYS_IMAGEBLIT
-       select FB_SYS_FOPS
-       select FB_DEFERRED_IO
-       select FB_METRONOME
-       help
-         This enables support for the Metronome display controller used on
-         the E-Ink AM-200 EPD devkit.
-
 config FB_COBALT
 	tristate "Cobalt server LCD frame buffer support"
 	depends on FB && MIPS_COBALT
@@ -2041,6 +2023,19 @@
 	  frame buffer driver.  It communicates with a back-end
 	  in another domain.
 
+config FB_METRONOME
+	tristate "E-Ink Metronome/8track controller support"
+	depends on FB
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_SYS_FOPS
+	select FB_DEFERRED_IO
+	help
+	  This driver implements support for the E-Ink Metronome
+	  controller. The pre-release name for this device was 8track
+	  and could also have been called by some vendors as PVI-nnnn.
+
 source "drivers/video/omap/Kconfig"
 
 source "drivers/video/backlight/Kconfig"
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index a6b5529..ad0330b 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -29,7 +29,6 @@
 
 # Hardware specific drivers go first
 obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p.o
-obj-$(CONFIG_FB_AM200EPD)         += am200epd.o
 obj-$(CONFIG_FB_ARC)              += arcfb.o
 obj-$(CONFIG_FB_CLPS711X)         += clps711xfb.o
 obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o
diff --git a/drivers/video/am200epd.c b/drivers/video/am200epd.c
deleted file mode 100644
index 0c35b8b..0000000
--- a/drivers/video/am200epd.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * linux/drivers/video/am200epd.c -- Platform device for AM200 EPD kit
- *
- * Copyright (C) 2008, Jaya Kumar
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- *
- * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven.
- *
- * This work was made possible by help and equipment support from E-Ink
- * Corporation. http://support.eink.com/community
- *
- * This driver is written to be used with the Metronome display controller.
- * on the AM200 EPD prototype kit/development kit with an E-Ink 800x600
- * Vizplex EPD on a Gumstix board using the Lyre interface board.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/list.h>
-#include <linux/uaccess.h>
-#include <linux/irq.h>
-
-#include <video/metronomefb.h>
-
-#include <mach/pxa-regs.h>
-
-/* register offsets for gpio control */
-#define LED_GPIO_PIN 51
-#define STDBY_GPIO_PIN 48
-#define RST_GPIO_PIN 49
-#define RDY_GPIO_PIN 32
-#define ERR_GPIO_PIN 17
-#define PCBPWR_GPIO_PIN 16
-
-#define AF_SEL_GPIO_N 0x3
-#define GAFR0_U_OFFSET(pin) ((pin - 16) * 2)
-#define GAFR1_L_OFFSET(pin) ((pin - 32) * 2)
-#define GAFR1_U_OFFSET(pin) ((pin - 48) * 2)
-#define GPDR1_OFFSET(pin) (pin - 32)
-#define GPCR1_OFFSET(pin) (pin - 32)
-#define GPSR1_OFFSET(pin) (pin - 32)
-#define GPCR0_OFFSET(pin) (pin)
-#define GPSR0_OFFSET(pin) (pin)
-
-static void am200_set_gpio_output(int pin, int val)
-{
-	u8 index;
-
-	index = pin >> 4;
-
-	switch (index) {
-	case 1:
-		if (val)
-			GPSR0 |= (1 << GPSR0_OFFSET(pin));
-		else
-			GPCR0 |= (1 << GPCR0_OFFSET(pin));
-		break;
-	case 2:
-		break;
-	case 3:
-		if (val)
-			GPSR1 |= (1 << GPSR1_OFFSET(pin));
-		else
-			GPCR1 |= (1 << GPCR1_OFFSET(pin));
-		break;
-	default:
-		printk(KERN_ERR "unimplemented\n");
-	}
-}
-
-static void __devinit am200_init_gpio_pin(int pin, int dir)
-{
-	u8 index;
-	/* dir 0 is output, 1 is input
-	- do 2 things here:
-	- set gpio alternate function to standard gpio
-	- set gpio direction to input or output  */
-
-	index = pin >> 4;
-	switch (index) {
-	case 1:
-		GAFR0_U &= ~(AF_SEL_GPIO_N << GAFR0_U_OFFSET(pin));
-
-		if (dir)
-			GPDR0 &= ~(1 << pin);
-		else
-			GPDR0 |= (1 << pin);
-		break;
-	case 2:
-		GAFR1_L &= ~(AF_SEL_GPIO_N << GAFR1_L_OFFSET(pin));
-
-		if (dir)
-			GPDR1 &= ~(1 << GPDR1_OFFSET(pin));
-		else
-			GPDR1 |= (1 << GPDR1_OFFSET(pin));
-		break;
-	case 3:
-		GAFR1_U &= ~(AF_SEL_GPIO_N << GAFR1_U_OFFSET(pin));
-
-		if (dir)
-			GPDR1 &= ~(1 << GPDR1_OFFSET(pin));
-		else
-			GPDR1 |= (1 << GPDR1_OFFSET(pin));
-		break;
-	default:
-		printk(KERN_ERR "unimplemented\n");
-	}
-}
-
-static void am200_init_gpio_regs(struct metronomefb_par *par)
-{
-	am200_init_gpio_pin(LED_GPIO_PIN, 0);
-	am200_set_gpio_output(LED_GPIO_PIN, 0);
-
-	am200_init_gpio_pin(STDBY_GPIO_PIN, 0);
-	am200_set_gpio_output(STDBY_GPIO_PIN, 0);
-
-	am200_init_gpio_pin(RST_GPIO_PIN, 0);
-	am200_set_gpio_output(RST_GPIO_PIN, 0);
-
-	am200_init_gpio_pin(RDY_GPIO_PIN, 1);
-
-	am200_init_gpio_pin(ERR_GPIO_PIN, 1);
-
-	am200_init_gpio_pin(PCBPWR_GPIO_PIN, 0);
-	am200_set_gpio_output(PCBPWR_GPIO_PIN, 0);
-}
-
-static void am200_disable_lcd_controller(struct metronomefb_par *par)
-{
-	LCSR = 0xffffffff;	/* Clear LCD Status Register */
-	LCCR0 |= LCCR0_DIS;	/* Disable LCD Controller */
-
-	/* we reset and just wait for things to settle */
-	msleep(200);
-}
-
-static void am200_enable_lcd_controller(struct metronomefb_par *par)
-{
-	LCSR = 0xffffffff;
-	FDADR0 = par->metromem_desc_dma;
-	LCCR0 |= LCCR0_ENB;
-}
-
-static void am200_init_lcdc_regs(struct metronomefb_par *par)
-{
-	/* here we do:
-	- disable the lcd controller
-	- setup lcd control registers
-	- setup dma descriptor
-	- reenable lcd controller
-	*/
-
-	/* disable the lcd controller */
-	am200_disable_lcd_controller(par);
-
-	/* setup lcd control registers */
-	LCCR0 = LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM | LCCR0_PAS
-		| LCCR0_QDM | LCCR0_BM | LCCR0_OUM;
-
-	LCCR1 = (par->info->var.xres/2 - 1) /* pixels per line */
-		| (27 << 10) /* hsync pulse width - 1 */
-		| (33 << 16) /* eol pixel count */
-		| (33 << 24); /* bol pixel count */
-
-	LCCR2 = (par->info->var.yres - 1) /* lines per panel */
-		| (24 << 10) /* vsync pulse width - 1 */
-		| (2 << 16) /* eof pixel count */
-		| (0 << 24); /* bof pixel count */
-
-	LCCR3 = 2 /* pixel clock divisor */
-		| (24 << 8) /* AC Bias pin freq */
-		| LCCR3_16BPP /* BPP */
-		| LCCR3_PCP;  /* PCP falling edge */
-
-}
-
-static void am200_post_dma_setup(struct metronomefb_par *par)
-{
-	par->metromem_desc->mFDADR0 = par->metromem_desc_dma;
-	par->metromem_desc->mFSADR0 = par->metromem_dma;
-	par->metromem_desc->mFIDR0 = 0;
-	par->metromem_desc->mLDCMD0 = par->info->var.xres
-					* par->info->var.yres;
-	am200_enable_lcd_controller(par);
-}
-
-static void am200_free_irq(struct fb_info *info)
-{
-	free_irq(IRQ_GPIO(RDY_GPIO_PIN), info);
-}
-
-static irqreturn_t am200_handle_irq(int irq, void *dev_id)
-{
-	struct fb_info *info = dev_id;
-	struct metronomefb_par *par = info->par;
-
-	wake_up_interruptible(&par->waitq);
-	return IRQ_HANDLED;
-}
-
-static int am200_setup_irq(struct fb_info *info)
-{
-	int retval;
-
-	retval = request_irq(IRQ_GPIO(RDY_GPIO_PIN), am200_handle_irq,
-				IRQF_DISABLED, "AM200", info);
-	if (retval) {
-		printk(KERN_ERR "am200epd: request_irq failed: %d\n", retval);
-		return retval;
-	}
-
-	return set_irq_type(IRQ_GPIO(RDY_GPIO_PIN), IRQ_TYPE_EDGE_FALLING);
-}
-
-static void am200_set_rst(struct metronomefb_par *par, int state)
-{
-	am200_set_gpio_output(RST_GPIO_PIN, state);
-}
-
-static void am200_set_stdby(struct metronomefb_par *par, int state)
-{
-	am200_set_gpio_output(STDBY_GPIO_PIN, state);
-}
-
-static int am200_wait_event(struct metronomefb_par *par)
-{
-	return wait_event_timeout(par->waitq, (GPLR1 & 0x01), HZ);
-}
-
-static int am200_wait_event_intr(struct metronomefb_par *par)
-{
-	return wait_event_interruptible_timeout(par->waitq, (GPLR1 & 0x01), HZ);
-}
-
-static struct metronome_board am200_board = {
-	.owner			= THIS_MODULE,
-	.free_irq		= am200_free_irq,
-	.setup_irq		= am200_setup_irq,
-	.init_gpio_regs		= am200_init_gpio_regs,
-	.init_lcdc_regs		= am200_init_lcdc_regs,
-	.post_dma_setup		= am200_post_dma_setup,
-	.set_rst		= am200_set_rst,
-	.set_stdby		= am200_set_stdby,
-	.met_wait_event		= am200_wait_event,
-	.met_wait_event_intr	= am200_wait_event_intr,
-};
-
-static struct platform_device *am200_device;
-
-static int __init am200_init(void)
-{
-	int ret;
-
-	/* request our platform independent driver */
-	request_module("metronomefb");
-
-	am200_device = platform_device_alloc("metronomefb", -1);
-	if (!am200_device)
-		return -ENOMEM;
-
-	platform_device_add_data(am200_device, &am200_board,
-					sizeof(am200_board));
-
-	/* this _add binds metronomefb to am200. metronomefb refcounts am200 */
-	ret = platform_device_add(am200_device);
-
-	if (ret)
-		platform_device_put(am200_device);
-
-	return ret;
-}
-
-static void __exit am200_exit(void)
-{
-	platform_device_unregister(am200_device);
-}
-
-module_init(am200_init);
-module_exit(am200_exit);
-
-MODULE_DESCRIPTION("board driver for am200 metronome epd kit");
-MODULE_AUTHOR("Jaya Kumar");
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 9c59259..d38fd52 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -208,6 +208,36 @@
 	return value;
 }
 
+static void atmel_lcdfb_stop_nowait(struct atmel_lcdfb_info *sinfo)
+{
+	/* Turn off the LCD controller and the DMA controller */
+	lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
+			sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
+
+	/* Wait for the LCDC core to become idle */
+	while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
+		msleep(10);
+
+	lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
+}
+
+static void atmel_lcdfb_stop(struct atmel_lcdfb_info *sinfo)
+{
+	atmel_lcdfb_stop_nowait(sinfo);
+
+	/* Wait for DMA engine to become idle... */
+	while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
+		msleep(10);
+}
+
+static void atmel_lcdfb_start(struct atmel_lcdfb_info *sinfo)
+{
+	lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
+	lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
+		(sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET)
+		| ATMEL_LCDC_PWR);
+}
+
 static void atmel_lcdfb_update_dma(struct fb_info *info,
 			       struct fb_var_screeninfo *var)
 {
@@ -378,6 +408,10 @@
 			var->red.offset = 11;
 			var->blue.offset = 0;
 			var->green.length = 6;
+		} else if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB555) {
+			var->red.offset = 10;
+			var->blue.offset = 0;
+			var->green.length = 5;
 		} else {
 			/* BGR:555 mode */
 			var->red.offset = 0;
@@ -420,26 +454,8 @@
 {
 	might_sleep();
 
-	/* LCD power off */
-	lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
-
-	/* wait for the LCDC core to become idle */
-	while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
-		msleep(10);
-
-	/* DMA disable */
-	lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
-
-	/* wait for DMA engine to become idle */
-	while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
-		msleep(10);
-
-	/* LCD power on */
-	lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
-		(sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR);
-
-	/* DMA enable */
-	lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
+	atmel_lcdfb_stop(sinfo);
+	atmel_lcdfb_start(sinfo);
 }
 
 /**
@@ -471,14 +487,7 @@
 		 info->var.xres, info->var.yres,
 		 info->var.xres_virtual, info->var.yres_virtual);
 
-	/* Turn off the LCD controller and the DMA controller */
-	lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
-
-	/* Wait for the LCDC core to become idle */
-	while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
-		msleep(10);
-
-	lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
+	atmel_lcdfb_stop_nowait(sinfo);
 
 	if (info->var.bits_per_pixel == 1)
 		info->fix.visual = FB_VISUAL_MONO01;
@@ -583,13 +592,7 @@
 	while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
 		msleep(10);
 
-	dev_dbg(info->device, "  * re-enable DMA engine\n");
-	/* ...and enable it with updated configuration */
-	lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
-
-	dev_dbg(info->device, "  * re-enable LCDC core\n");
-	lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
-		(sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR);
+	atmel_lcdfb_start(sinfo);
 
 	dev_dbg(info->device, "  * DONE\n");
 
@@ -939,7 +942,7 @@
 	ret = register_framebuffer(info);
 	if (ret < 0) {
 		dev_err(dev, "failed to register framebuffer device: %d\n", ret);
-		goto free_cmap;
+		goto reset_drvdata;
 	}
 
 	/* add selected videomode to modelist */
@@ -955,7 +958,8 @@
 
 	return 0;
 
-
+reset_drvdata:
+	dev_set_drvdata(dev, NULL);
 free_cmap:
 	fb_dealloc_cmap(&info->cmap);
 unregister_irqs:
@@ -992,10 +996,11 @@
 {
 	struct device *dev = &pdev->dev;
 	struct fb_info *info = dev_get_drvdata(dev);
-	struct atmel_lcdfb_info *sinfo = info->par;
+	struct atmel_lcdfb_info *sinfo;
 
-	if (!sinfo)
+	if (!info || !info->par)
 		return 0;
+	sinfo = info->par;
 
 	cancel_work_sync(&sinfo->task);
 	exit_backlight(sinfo);
@@ -1030,11 +1035,20 @@
 	struct fb_info *info = platform_get_drvdata(pdev);
 	struct atmel_lcdfb_info *sinfo = info->par;
 
+	/*
+	 * We don't want to handle interrupts while the clock is
+	 * stopped. It may take forever.
+	 */
+	lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL);
+
 	sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL);
 	lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0);
 	if (sinfo->atmel_lcdfb_power_control)
 		sinfo->atmel_lcdfb_power_control(0);
+
+	atmel_lcdfb_stop(sinfo);
 	atmel_lcdfb_stop_clock(sinfo);
+
 	return 0;
 }
 
@@ -1044,9 +1058,15 @@
 	struct atmel_lcdfb_info *sinfo = info->par;
 
 	atmel_lcdfb_start_clock(sinfo);
+	atmel_lcdfb_start(sinfo);
 	if (sinfo->atmel_lcdfb_power_control)
 		sinfo->atmel_lcdfb_power_control(1);
 	lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, sinfo->saved_lcdcon);
+
+	/* Enable FIFO & DMA errors */
+	lcdc_writel(sinfo, ATMEL_LCDC_IER, ATMEL_LCDC_UFLWI
+			| ATMEL_LCDC_OWRI | ATMEL_LCDC_MERI);
+
 	return 0;
 }
 
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 452b770..c72a135 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -24,6 +24,13 @@
 	  To have support for your specific LCD panel you will have to
 	  select the proper drivers which depend on this option.
 
+config LCD_CORGI
+	tristate "LCD Panel support for SHARP corgi/spitz model"
+	depends on LCD_CLASS_DEVICE && SPI_MASTER && PXA_SHARPSL
+	help
+	  Say y here to support the LCD panels usually found on SHARP
+	  corgi (C7x0) and spitz (Cxx00) models.
+
 config LCD_LTV350QV
 	tristate "Samsung LTV350QV LCD Panel"
 	depends on LCD_CLASS_DEVICE && SPI_MASTER
@@ -44,6 +51,14 @@
 	  If you have a panel based on the ILI9320 controller chip
 	  then say y to include a power driver for it.
 
+config LCD_TDO24M
+	tristate "Toppoly TDO24M LCD Panels support"
+	depends on LCD_CLASS_DEVICE && SPI_MASTER
+	default n
+	help
+	  If you have a Toppoly TDO24M series LCD panel, say y here to
+	  include the support for it.
+
 config LCD_VGG2432A4
 	tristate "VGG2432A4 LCM device support"
 	depends on BACKLIGHT_LCD_SUPPORT && LCD_CLASS_DEVICE && SPI_MASTER
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index b405aac..3ec551e 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -1,10 +1,12 @@
 # Backlight & LCD drivers
 
 obj-$(CONFIG_LCD_CLASS_DEVICE)     += lcd.o
+obj-$(CONFIG_LCD_CORGI)		   += corgi_lcd.o
 obj-$(CONFIG_LCD_LTV350QV)	   += ltv350qv.o
 obj-$(CONFIG_LCD_ILI9320)	   += ili9320.o
 obj-$(CONFIG_LCD_PLATFORM)	   += platform_lcd.o
 obj-$(CONFIG_LCD_VGG2432A4)	   += vgg2432a4.o
+obj-$(CONFIG_LCD_TDO24M)	   += tdo24m.o
 
 obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
 obj-$(CONFIG_BACKLIGHT_ATMEL_PWM)    += atmel-pwm-bl.o
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c
new file mode 100644
index 0000000..2afd47e
--- /dev/null
+++ b/drivers/video/backlight/corgi_lcd.c
@@ -0,0 +1,641 @@
+/*
+ *  LCD/Backlight Driver for Sharp Zaurus Handhelds (various models)
+ *
+ *  Copyright (c) 2004-2006 Richard Purdie
+ *
+ *  Based on Sharp's 2.4 Backlight Driver
+ *
+ *  Copyright (c) 2008 Marvell International Ltd.
+ *  	Converted to SPI device based LCD/Backlight device driver
+ *  	by Eric Miao <eric.miao@marvell.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/fb.h>
+#include <linux/lcd.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/corgi_lcd.h>
+#include <asm/mach/sharpsl_param.h>
+
+#define POWER_IS_ON(pwr)	((pwr) <= FB_BLANK_NORMAL)
+
+/* Register Addresses */
+#define RESCTL_ADRS     0x00
+#define PHACTRL_ADRS    0x01
+#define DUTYCTRL_ADRS   0x02
+#define POWERREG0_ADRS  0x03
+#define POWERREG1_ADRS  0x04
+#define GPOR3_ADRS      0x05
+#define PICTRL_ADRS     0x06
+#define POLCTRL_ADRS    0x07
+
+/* Register Bit Definitions */
+#define RESCTL_QVGA     0x01
+#define RESCTL_VGA      0x00
+
+#define POWER1_VW_ON    0x01  /* VW Supply FET ON */
+#define POWER1_GVSS_ON  0x02  /* GVSS(-8V) Power Supply ON */
+#define POWER1_VDD_ON   0x04  /* VDD(8V),SVSS(-4V) Power Supply ON */
+
+#define POWER1_VW_OFF   0x00  /* VW Supply FET OFF */
+#define POWER1_GVSS_OFF 0x00  /* GVSS(-8V) Power Supply OFF */
+#define POWER1_VDD_OFF  0x00  /* VDD(8V),SVSS(-4V) Power Supply OFF */
+
+#define POWER0_COM_DCLK 0x01  /* COM Voltage DC Bias DAC Serial Data Clock */
+#define POWER0_COM_DOUT 0x02  /* COM Voltage DC Bias DAC Serial Data Out */
+#define POWER0_DAC_ON   0x04  /* DAC Power Supply ON */
+#define POWER0_COM_ON   0x08  /* COM Power Supply ON */
+#define POWER0_VCC5_ON  0x10  /* VCC5 Power Supply ON */
+
+#define POWER0_DAC_OFF  0x00  /* DAC Power Supply OFF */
+#define POWER0_COM_OFF  0x00  /* COM Power Supply OFF */
+#define POWER0_VCC5_OFF 0x00  /* VCC5 Power Supply OFF */
+
+#define PICTRL_INIT_STATE      0x01
+#define PICTRL_INIOFF          0x02
+#define PICTRL_POWER_DOWN      0x04
+#define PICTRL_COM_SIGNAL_OFF  0x08
+#define PICTRL_DAC_SIGNAL_OFF  0x10
+
+#define POLCTRL_SYNC_POL_FALL  0x01
+#define POLCTRL_EN_POL_FALL    0x02
+#define POLCTRL_DATA_POL_FALL  0x04
+#define POLCTRL_SYNC_ACT_H     0x08
+#define POLCTRL_EN_ACT_L       0x10
+
+#define POLCTRL_SYNC_POL_RISE  0x00
+#define POLCTRL_EN_POL_RISE    0x00
+#define POLCTRL_DATA_POL_RISE  0x00
+#define POLCTRL_SYNC_ACT_L     0x00
+#define POLCTRL_EN_ACT_H       0x00
+
+#define PHACTRL_PHASE_MANUAL   0x01
+#define DEFAULT_PHAD_QVGA     (9)
+#define DEFAULT_COMADJ        (125)
+
+struct corgi_lcd {
+	struct spi_device	*spi_dev;
+	struct lcd_device	*lcd_dev;
+	struct backlight_device	*bl_dev;
+
+	int	limit_mask;
+	int	intensity;
+	int	power;
+	int	mode;
+	char	buf[2];
+
+	int	gpio_backlight_on;
+	int	gpio_backlight_cont;
+	int	gpio_backlight_cont_inverted;
+
+	void (*kick_battery)(void);
+};
+
+static int corgi_ssp_lcdtg_send(struct corgi_lcd *lcd, int reg, uint8_t val);
+
+static struct corgi_lcd *the_corgi_lcd;
+static unsigned long corgibl_flags;
+#define CORGIBL_SUSPENDED     0x01
+#define CORGIBL_BATTLOW       0x02
+
+/*
+ * This is only a psuedo I2C interface. We can't use the standard kernel
+ * routines as the interface is write only. We just assume the data is acked...
+ */
+static void lcdtg_ssp_i2c_send(struct corgi_lcd *lcd, uint8_t data)
+{
+	corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, data);
+	udelay(10);
+}
+
+static void lcdtg_i2c_send_bit(struct corgi_lcd *lcd, uint8_t data)
+{
+	lcdtg_ssp_i2c_send(lcd, data);
+	lcdtg_ssp_i2c_send(lcd, data | POWER0_COM_DCLK);
+	lcdtg_ssp_i2c_send(lcd, data);
+}
+
+static void lcdtg_i2c_send_start(struct corgi_lcd *lcd, uint8_t base)
+{
+	lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK | POWER0_COM_DOUT);
+	lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK);
+	lcdtg_ssp_i2c_send(lcd, base);
+}
+
+static void lcdtg_i2c_send_stop(struct corgi_lcd *lcd, uint8_t base)
+{
+	lcdtg_ssp_i2c_send(lcd, base);
+	lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK);
+	lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK | POWER0_COM_DOUT);
+}
+
+static void lcdtg_i2c_send_byte(struct corgi_lcd *lcd,
+				uint8_t base, uint8_t data)
+{
+	int i;
+	for (i = 0; i < 8; i++) {
+		if (data & 0x80)
+			lcdtg_i2c_send_bit(lcd, base | POWER0_COM_DOUT);
+		else
+			lcdtg_i2c_send_bit(lcd, base);
+		data <<= 1;
+	}
+}
+
+static void lcdtg_i2c_wait_ack(struct corgi_lcd *lcd, uint8_t base)
+{
+	lcdtg_i2c_send_bit(lcd, base);
+}
+
+static void lcdtg_set_common_voltage(struct corgi_lcd *lcd,
+				     uint8_t base_data, uint8_t data)
+{
+	/* Set Common Voltage to M62332FP via I2C */
+	lcdtg_i2c_send_start(lcd, base_data);
+	lcdtg_i2c_send_byte(lcd, base_data, 0x9c);
+	lcdtg_i2c_wait_ack(lcd, base_data);
+	lcdtg_i2c_send_byte(lcd, base_data, 0x00);
+	lcdtg_i2c_wait_ack(lcd, base_data);
+	lcdtg_i2c_send_byte(lcd, base_data, data);
+	lcdtg_i2c_wait_ack(lcd, base_data);
+	lcdtg_i2c_send_stop(lcd, base_data);
+}
+
+static int corgi_ssp_lcdtg_send(struct corgi_lcd *lcd, int adrs, uint8_t data)
+{
+	struct spi_message msg;
+	struct spi_transfer xfer = {
+		.len		= 1,
+		.cs_change	= 1,
+		.tx_buf		= lcd->buf,
+	};
+
+	lcd->buf[0] = ((adrs & 0x07) << 5) | (data & 0x1f);
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+
+	return spi_sync(lcd->spi_dev, &msg);
+}
+
+/* Set Phase Adjust */
+static void lcdtg_set_phadadj(struct corgi_lcd *lcd, int mode)
+{
+	int adj;
+
+	switch(mode) {
+	case CORGI_LCD_MODE_VGA:
+		/* Setting for VGA */
+		adj = sharpsl_param.phadadj;
+		adj = (adj < 0) ? PHACTRL_PHASE_MANUAL :
+				  PHACTRL_PHASE_MANUAL | ((adj & 0xf) << 1);
+		break;
+	case CORGI_LCD_MODE_QVGA:
+	default:
+		/* Setting for QVGA */
+		adj = (DEFAULT_PHAD_QVGA << 1) | PHACTRL_PHASE_MANUAL;
+		break;
+	}
+
+	corgi_ssp_lcdtg_send(lcd, PHACTRL_ADRS, adj);
+}
+
+static void corgi_lcd_power_on(struct corgi_lcd *lcd)
+{
+	int comadj;
+
+	/* Initialize Internal Logic & Port */
+	corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS,
+			PICTRL_POWER_DOWN | PICTRL_INIOFF |
+			PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF |
+			PICTRL_DAC_SIGNAL_OFF);
+
+	corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
+			POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF |
+			POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+	corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
+			POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
+
+	/* VDD(+8V), SVSS(-4V) ON */
+	corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
+			POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
+	mdelay(3);
+
+	/* DAC ON */
+	corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
+			POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON |
+			POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+	/* INIB = H, INI = L  */
+	/* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */
+	corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS,
+			PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF);
+
+	/* Set Common Voltage */
+	comadj = sharpsl_param.comadj;
+	if (comadj < 0)
+		comadj = DEFAULT_COMADJ;
+
+	lcdtg_set_common_voltage(lcd, POWER0_DAC_ON | POWER0_COM_OFF |
+				 POWER0_VCC5_OFF, comadj);
+
+	/* VCC5 ON, DAC ON */
+	corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
+			POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON |
+			POWER0_COM_OFF | POWER0_VCC5_ON);
+
+	/* GVSS(-8V) ON, VDD ON */
+	corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
+			POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
+	mdelay(2);
+
+	/* COM SIGNAL ON (PICTL[3] = L) */
+	corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, PICTRL_INIT_STATE);
+
+	/* COM ON, DAC ON, VCC5_ON */
+	corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
+			POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON |
+			POWER0_COM_ON | POWER0_VCC5_ON);
+
+	/* VW ON, GVSS ON, VDD ON */
+	corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
+			POWER1_VW_ON | POWER1_GVSS_ON | POWER1_VDD_ON);
+
+	/* Signals output enable */
+	corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, 0);
+
+	/* Set Phase Adjust */
+	lcdtg_set_phadadj(lcd, lcd->mode);
+
+	/* Initialize for Input Signals from ATI */
+	corgi_ssp_lcdtg_send(lcd, POLCTRL_ADRS,
+			POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE |
+			POLCTRL_DATA_POL_RISE | POLCTRL_SYNC_ACT_L |
+			POLCTRL_EN_ACT_H);
+	udelay(1000);
+
+	switch (lcd->mode) {
+	case CORGI_LCD_MODE_VGA:
+		corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_VGA);
+		break;
+	case CORGI_LCD_MODE_QVGA:
+	default:
+		corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_QVGA);
+		break;
+	}
+}
+
+static void corgi_lcd_power_off(struct corgi_lcd *lcd)
+{
+	/* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
+	msleep(34);
+
+	/* (1)VW OFF */
+	corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
+			POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
+
+	/* (2)COM OFF */
+	corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF);
+	corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
+			POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON);
+
+	/* (3)Set Common Voltage Bias 0V */
+	lcdtg_set_common_voltage(lcd, POWER0_DAC_ON | POWER0_COM_OFF |
+			POWER0_VCC5_ON, 0);
+
+	/* (4)GVSS OFF */
+	corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
+			POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
+
+	/* (5)VCC5 OFF */
+	corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
+			POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+	/* (6)Set PDWN, INIOFF, DACOFF */
+	corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS,
+			PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF |
+			PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF);
+
+	/* (7)DAC OFF */
+	corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
+			POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+	/* (8)VDD OFF */
+	corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
+			POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
+}
+
+static int corgi_lcd_set_mode(struct lcd_device *ld, struct fb_videomode *m)
+{
+	struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev);
+	int mode = CORGI_LCD_MODE_QVGA;
+
+	if (m->xres == 640 || m->xres == 480)
+		mode = CORGI_LCD_MODE_VGA;
+
+	if (lcd->mode == mode)
+		return 0;
+
+	lcdtg_set_phadadj(lcd, mode);
+
+	switch (mode) {
+	case CORGI_LCD_MODE_VGA:
+		corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_VGA);
+		break;
+	case CORGI_LCD_MODE_QVGA:
+	default:
+		corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_QVGA);
+		break;
+	}
+
+	lcd->mode = mode;
+	return 0;
+}
+
+static int corgi_lcd_set_power(struct lcd_device *ld, int power)
+{
+	struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev);
+
+	if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+		corgi_lcd_power_on(lcd);
+
+	if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+		corgi_lcd_power_off(lcd);
+
+	lcd->power = power;
+	return 0;
+}
+
+static int corgi_lcd_get_power(struct lcd_device *ld)
+{
+	struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev);
+
+	return lcd->power;
+}
+
+static struct lcd_ops corgi_lcd_ops = {
+	.get_power	= corgi_lcd_get_power,
+	.set_power	= corgi_lcd_set_power,
+	.set_mode	= corgi_lcd_set_mode,
+};
+
+static int corgi_bl_get_intensity(struct backlight_device *bd)
+{
+	struct corgi_lcd *lcd = dev_get_drvdata(&bd->dev);
+
+	return lcd->intensity;
+}
+
+static int corgi_bl_set_intensity(struct corgi_lcd *lcd, int intensity)
+{
+	int cont;
+
+	if (intensity > 0x10)
+		intensity += 0x10;
+
+	corgi_ssp_lcdtg_send(lcd, DUTYCTRL_ADRS, intensity);
+
+	/* Bit 5 via GPIO_BACKLIGHT_CONT */
+	cont = !!(intensity & 0x20) ^ lcd->gpio_backlight_cont_inverted;
+
+	if (gpio_is_valid(lcd->gpio_backlight_cont))
+		gpio_set_value(lcd->gpio_backlight_cont, cont);
+
+	if (gpio_is_valid(lcd->gpio_backlight_on))
+		gpio_set_value(lcd->gpio_backlight_on, intensity);
+
+	if (lcd->kick_battery)
+		lcd->kick_battery();
+
+	lcd->intensity = intensity;
+	return 0;
+}
+
+static int corgi_bl_update_status(struct backlight_device *bd)
+{
+	struct corgi_lcd *lcd = dev_get_drvdata(&bd->dev);
+	int intensity = bd->props.brightness;
+
+	if (bd->props.power != FB_BLANK_UNBLANK)
+		intensity = 0;
+
+	if (bd->props.fb_blank != FB_BLANK_UNBLANK)
+		intensity = 0;
+
+	if (corgibl_flags & CORGIBL_SUSPENDED)
+		intensity = 0;
+	if (corgibl_flags & CORGIBL_BATTLOW)
+		intensity &= lcd->limit_mask;
+
+	return corgi_bl_set_intensity(lcd, intensity);
+}
+
+void corgibl_limit_intensity(int limit)
+{
+	if (limit)
+		corgibl_flags |= CORGIBL_BATTLOW;
+	else
+		corgibl_flags &= ~CORGIBL_BATTLOW;
+
+	backlight_update_status(the_corgi_lcd->bl_dev);
+}
+EXPORT_SYMBOL(corgibl_limit_intensity);
+
+static struct backlight_ops corgi_bl_ops = {
+	.get_brightness	= corgi_bl_get_intensity,
+	.update_status  = corgi_bl_update_status,
+};
+
+#ifdef CONFIG_PM
+static int corgi_lcd_suspend(struct spi_device *spi, pm_message_t state)
+{
+	struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev);
+
+	corgibl_flags |= CORGIBL_SUSPENDED;
+	corgi_bl_set_intensity(lcd, 0);
+	corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_POWERDOWN);
+	return 0;
+}
+
+static int corgi_lcd_resume(struct spi_device *spi)
+{
+	struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev);
+
+	corgibl_flags &= ~CORGIBL_SUSPENDED;
+	corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_UNBLANK);
+	backlight_update_status(lcd->bl_dev);
+	return 0;
+}
+#else
+#define corgi_lcd_suspend	NULL
+#define corgi_lcd_resume	NULL
+#endif
+
+static int setup_gpio_backlight(struct corgi_lcd *lcd,
+				struct corgi_lcd_platform_data *pdata)
+{
+	struct spi_device *spi = lcd->spi_dev;
+	int err;
+
+	lcd->gpio_backlight_on = -1;
+	lcd->gpio_backlight_cont = -1;
+
+	if (gpio_is_valid(pdata->gpio_backlight_on)) {
+		err = gpio_request(pdata->gpio_backlight_on, "BL_ON");
+		if (err) {
+			dev_err(&spi->dev, "failed to request GPIO%d for "
+				"backlight_on\n", pdata->gpio_backlight_on);
+			return err;
+		}
+
+		lcd->gpio_backlight_on = pdata->gpio_backlight_on;
+		gpio_direction_output(lcd->gpio_backlight_on, 0);
+	}
+
+	if (gpio_is_valid(pdata->gpio_backlight_cont)) {
+		err = gpio_request(pdata->gpio_backlight_cont, "BL_CONT");
+		if (err) {
+			dev_err(&spi->dev, "failed to request GPIO%d for "
+				"backlight_cont\n", pdata->gpio_backlight_cont);
+			goto err_free_backlight_on;
+		}
+
+		lcd->gpio_backlight_cont = pdata->gpio_backlight_cont;
+
+		/* spitz and akita use both GPIOs for backlight, and
+		 * have inverted polarity of GPIO_BACKLIGHT_CONT
+		 */
+		if (gpio_is_valid(lcd->gpio_backlight_on)) {
+			lcd->gpio_backlight_cont_inverted = 1;
+			gpio_direction_output(lcd->gpio_backlight_cont, 1);
+		} else {
+			lcd->gpio_backlight_cont_inverted = 0;
+			gpio_direction_output(lcd->gpio_backlight_cont, 0);
+		}
+	}
+	return 0;
+
+err_free_backlight_on:
+	if (gpio_is_valid(lcd->gpio_backlight_on))
+		gpio_free(lcd->gpio_backlight_on);
+	return err;
+}
+
+static int __devinit corgi_lcd_probe(struct spi_device *spi)
+{
+	struct corgi_lcd_platform_data *pdata = spi->dev.platform_data;
+	struct corgi_lcd *lcd;
+	int ret = 0;
+
+	if (pdata == NULL) {
+		dev_err(&spi->dev, "platform data not available\n");
+		return -EINVAL;
+	}
+
+	lcd = kzalloc(sizeof(struct corgi_lcd), GFP_KERNEL);
+	if (!lcd) {
+		dev_err(&spi->dev, "failed to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	lcd->spi_dev = spi;
+
+	lcd->lcd_dev = lcd_device_register("corgi_lcd", &spi->dev,
+					lcd, &corgi_lcd_ops);
+	if (IS_ERR(lcd->lcd_dev)) {
+		ret = PTR_ERR(lcd->lcd_dev);
+		goto err_free_lcd;
+	}
+	lcd->power = FB_BLANK_POWERDOWN;
+	lcd->mode = (pdata) ? pdata->init_mode : CORGI_LCD_MODE_VGA;
+
+	lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev,
+					lcd, &corgi_bl_ops);
+	if (IS_ERR(lcd->bl_dev)) {
+		ret = PTR_ERR(lcd->bl_dev);
+		goto err_unregister_lcd;
+	}
+	lcd->bl_dev->props.max_brightness = pdata->max_intensity;
+	lcd->bl_dev->props.brightness = pdata->default_intensity;
+	lcd->bl_dev->props.power = FB_BLANK_UNBLANK;
+
+	ret = setup_gpio_backlight(lcd, pdata);
+	if (ret)
+		goto err_unregister_bl;
+
+	lcd->kick_battery = pdata->kick_battery;
+
+	dev_set_drvdata(&spi->dev, lcd);
+	corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_UNBLANK);
+	backlight_update_status(lcd->bl_dev);
+
+	lcd->limit_mask = pdata->limit_mask;
+	the_corgi_lcd = lcd;
+	return 0;
+
+err_unregister_bl:
+	backlight_device_unregister(lcd->bl_dev);
+err_unregister_lcd:
+	lcd_device_unregister(lcd->lcd_dev);
+err_free_lcd:
+	kfree(lcd);
+	return ret;
+}
+
+static int __devexit corgi_lcd_remove(struct spi_device *spi)
+{
+	struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev);
+
+	lcd->bl_dev->props.power = FB_BLANK_UNBLANK;
+	lcd->bl_dev->props.brightness = 0;
+	backlight_update_status(lcd->bl_dev);
+	backlight_device_unregister(lcd->bl_dev);
+
+	if (gpio_is_valid(lcd->gpio_backlight_on))
+		gpio_free(lcd->gpio_backlight_on);
+
+	if (gpio_is_valid(lcd->gpio_backlight_cont))
+		gpio_free(lcd->gpio_backlight_cont);
+
+	corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_POWERDOWN);
+	lcd_device_unregister(lcd->lcd_dev);
+	kfree(lcd);
+
+	return 0;
+}
+
+static struct spi_driver corgi_lcd_driver = {
+	.driver		= {
+		.name	= "corgi-lcd",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= corgi_lcd_probe,
+	.remove		= __devexit_p(corgi_lcd_remove),
+	.suspend	= corgi_lcd_suspend,
+	.resume		= corgi_lcd_resume,
+};
+
+static int __init corgi_lcd_init(void)
+{
+	return spi_register_driver(&corgi_lcd_driver);
+}
+module_init(corgi_lcd_init);
+
+static void __exit corgi_lcd_exit(void)
+{
+	spi_unregister_driver(&corgi_lcd_driver);
+}
+module_exit(corgi_lcd_exit);
+
+MODULE_DESCRIPTION("LCD and backlight driver for SHARP C7x0/Cxx00");
+MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index b15b2b8..8e1731d 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -27,14 +27,26 @@
 	struct fb_event *evdata = data;
 
 	/* If we aren't interested in this event, skip it immediately ... */
-	if (event != FB_EVENT_BLANK)
+	switch (event) {
+	case FB_EVENT_BLANK:
+	case FB_EVENT_MODE_CHANGE:
+	case FB_EVENT_MODE_CHANGE_ALL:
+		break;
+	default:
 		return 0;
+	}
 
 	ld = container_of(self, struct lcd_device, fb_notif);
+	if (!ld->ops)
+		return 0;
+
 	mutex_lock(&ld->ops_lock);
-	if (ld->ops)
-		if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info))
+	if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) {
+		if (event == FB_EVENT_BLANK)
 			ld->ops->set_power(ld, *(int *)evdata->data);
+		else
+			ld->ops->set_mode(ld, evdata->data);
+	}
 	mutex_unlock(&ld->ops_lock);
 	return 0;
 }
diff --git a/drivers/video/backlight/tdo24m.c b/drivers/video/backlight/tdo24m.c
new file mode 100644
index 0000000..8427669
--- /dev/null
+++ b/drivers/video/backlight/tdo24m.c
@@ -0,0 +1,396 @@
+/*
+ * tdo24m - SPI-based drivers for Toppoly TDO24M series LCD panels
+ *
+ * Copyright (C) 2008 Marvell International Ltd.
+ * 	Eric Miao <eric.miao@marvell.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/fb.h>
+#include <linux/lcd.h>
+
+#define POWER_IS_ON(pwr)	((pwr) <= FB_BLANK_NORMAL)
+
+#define TDO24M_SPI_BUFF_SIZE	(4)
+#define MODE_QVGA	0
+#define MODE_VGA	1
+
+struct tdo24m {
+	struct spi_device	*spi_dev;
+	struct lcd_device	*lcd_dev;
+
+	struct spi_message	msg;
+	struct spi_transfer	xfer;
+	uint8_t			*buf;
+
+	int			power;
+	int			mode;
+};
+
+/* use bit 30, 31 as the indicator of command parameter number */
+#define CMD0(x)		((0 << 30) | (x))
+#define CMD1(x, x1)	((1 << 30) | ((x) << 9) | 0x100 | (x1))
+#define CMD2(x, x1, x2)	((2 << 30) | ((x) << 18) | 0x20000 |\
+			((x1) << 9) | 0x100 | (x2))
+#define CMD_NULL	(-1)
+
+static uint32_t lcd_panel_reset[] = {
+	CMD0(0x1), /* reset */
+	CMD0(0x0), /* nop */
+	CMD0(0x0), /* nop */
+	CMD0(0x0), /* nop */
+	CMD_NULL,
+};
+
+static uint32_t lcd_panel_on[] = {
+	CMD0(0x29),		/* Display ON */
+	CMD2(0xB8, 0xFF, 0xF9),	/* Output Control */
+	CMD0(0x11),		/* Sleep out */
+	CMD1(0xB0, 0x16),	/* Wake */
+	CMD_NULL,
+};
+
+static uint32_t lcd_panel_off[] = {
+	CMD0(0x28),		/* Display OFF */
+	CMD2(0xB8, 0x80, 0x02),	/* Output Control */
+	CMD0(0x10),		/* Sleep in */
+	CMD1(0xB0, 0x00),	/* Deep stand by in */
+	CMD_NULL,
+};
+
+static uint32_t lcd_vga_pass_through[] = {
+	CMD1(0xB0, 0x16),
+	CMD1(0xBC, 0x80),
+	CMD1(0xE1, 0x00),
+	CMD1(0x36, 0x50),
+	CMD1(0x3B, 0x00),
+	CMD_NULL,
+};
+
+static uint32_t lcd_qvga_pass_through[] = {
+	CMD1(0xB0, 0x16),
+	CMD1(0xBC, 0x81),
+	CMD1(0xE1, 0x00),
+	CMD1(0x36, 0x50),
+	CMD1(0x3B, 0x22),
+	CMD_NULL,
+};
+
+static uint32_t lcd_vga_transfer[] = {
+	CMD1(0xcf, 0x02), 	/* Blanking period control (1) */
+	CMD2(0xd0, 0x08, 0x04),	/* Blanking period control (2) */
+	CMD1(0xd1, 0x01),	/* CKV timing control on/off */
+	CMD2(0xd2, 0x14, 0x00),	/* CKV 1,2 timing control */
+	CMD2(0xd3, 0x1a, 0x0f),	/* OEV timing control */
+	CMD2(0xd4, 0x1f, 0xaf),	/* ASW timing control (1) */
+	CMD1(0xd5, 0x14),	/* ASW timing control (2) */
+	CMD0(0x21),		/* Invert for normally black display */
+	CMD0(0x29),		/* Display on */
+	CMD_NULL,
+};
+
+static uint32_t lcd_qvga_transfer[] = {
+	CMD1(0xd6, 0x02),	/* Blanking period control (1) */
+	CMD2(0xd7, 0x08, 0x04),	/* Blanking period control (2) */
+	CMD1(0xd8, 0x01),	/* CKV timing control on/off */
+	CMD2(0xd9, 0x00, 0x08),	/* CKV 1,2 timing control */
+	CMD2(0xde, 0x05, 0x0a),	/* OEV timing control */
+	CMD2(0xdf, 0x0a, 0x19),	/* ASW timing control (1) */
+	CMD1(0xe0, 0x0a),	/* ASW timing control (2) */
+	CMD0(0x21),		/* Invert for normally black display */
+	CMD0(0x29),		/* Display on */
+	CMD_NULL,
+};
+
+static uint32_t lcd_panel_config[] = {
+	CMD2(0xb8, 0xff, 0xf9),	/* Output control */
+	CMD0(0x11),		/* sleep out */
+	CMD1(0xba, 0x01),	/* Display mode (1) */
+	CMD1(0xbb, 0x00),	/* Display mode (2) */
+	CMD1(0x3a, 0x60),	/* Display mode 18-bit RGB */
+	CMD1(0xbf, 0x10),	/* Drive system change control */
+	CMD1(0xb1, 0x56),	/* Booster operation setup */
+	CMD1(0xb2, 0x33),	/* Booster mode setup */
+	CMD1(0xb3, 0x11),	/* Booster frequency setup */
+	CMD1(0xb4, 0x02),	/* Op amp/system clock */
+	CMD1(0xb5, 0x35),	/* VCS voltage */
+	CMD1(0xb6, 0x40),	/* VCOM voltage */
+	CMD1(0xb7, 0x03),	/* External display signal */
+	CMD1(0xbd, 0x00),	/* ASW slew rate */
+	CMD1(0xbe, 0x00),	/* Dummy data for QuadData operation */
+	CMD1(0xc0, 0x11),	/* Sleep out FR count (A) */
+	CMD1(0xc1, 0x11),	/* Sleep out FR count (B) */
+	CMD1(0xc2, 0x11),	/* Sleep out FR count (C) */
+	CMD2(0xc3, 0x20, 0x40),	/* Sleep out FR count (D) */
+	CMD2(0xc4, 0x60, 0xc0),	/* Sleep out FR count (E) */
+	CMD2(0xc5, 0x10, 0x20),	/* Sleep out FR count (F) */
+	CMD1(0xc6, 0xc0),	/* Sleep out FR count (G) */
+	CMD2(0xc7, 0x33, 0x43),	/* Gamma 1 fine tuning (1) */
+	CMD1(0xc8, 0x44),	/* Gamma 1 fine tuning (2) */
+	CMD1(0xc9, 0x33),	/* Gamma 1 inclination adjustment */
+	CMD1(0xca, 0x00),	/* Gamma 1 blue offset adjustment */
+	CMD2(0xec, 0x01, 0xf0),	/* Horizontal clock cycles */
+	CMD_NULL,
+};
+
+static int tdo24m_writes(struct tdo24m *lcd, uint32_t *array)
+{
+	struct spi_transfer *x = &lcd->xfer;
+	uint32_t data, *p = array;
+	int nparams, err = 0;
+
+	for (; *p != CMD_NULL; p++) {
+
+		nparams = (*p >> 30) & 0x3;
+
+		data = *p << (7 - nparams);
+		switch (nparams) {
+		case 0:
+			lcd->buf[0] = (data >> 8) & 0xff;
+			lcd->buf[1] = data & 0xff;
+			break;
+		case 1:
+			lcd->buf[0] = (data >> 16) & 0xff;
+			lcd->buf[1] = (data >> 8) & 0xff;
+			lcd->buf[2] = data & 0xff;
+			break;
+		case 2:
+			lcd->buf[0] = (data >> 24) & 0xff;
+			lcd->buf[1] = (data >> 16) & 0xff;
+			lcd->buf[2] = (data >> 8) & 0xff;
+			lcd->buf[3] = data & 0xff;
+			break;
+		default:
+			continue;
+		}
+		x->len = nparams + 2;
+		err = spi_sync(lcd->spi_dev, &lcd->msg);
+		if (err)
+			break;
+	}
+
+	return err;
+}
+
+static int tdo24m_adj_mode(struct tdo24m *lcd, int mode)
+{
+	switch (mode) {
+	case MODE_VGA:
+		tdo24m_writes(lcd, lcd_vga_pass_through);
+		tdo24m_writes(lcd, lcd_panel_config);
+		tdo24m_writes(lcd, lcd_vga_transfer);
+		break;
+	case MODE_QVGA:
+		tdo24m_writes(lcd, lcd_qvga_pass_through);
+		tdo24m_writes(lcd, lcd_panel_config);
+		tdo24m_writes(lcd, lcd_qvga_transfer);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	lcd->mode = mode;
+	return 0;
+}
+
+static int tdo24m_power_on(struct tdo24m *lcd)
+{
+	int err;
+
+	err = tdo24m_writes(lcd, lcd_panel_on);
+	if (err)
+		goto out;
+
+	err = tdo24m_writes(lcd, lcd_panel_reset);
+	if (err)
+		goto out;
+
+	err = tdo24m_adj_mode(lcd, lcd->mode);
+out:
+	return err;
+}
+
+static int tdo24m_power_off(struct tdo24m *lcd)
+{
+	return tdo24m_writes(lcd, lcd_panel_off);
+}
+
+static int tdo24m_power(struct tdo24m *lcd, int power)
+{
+	int ret = 0;
+
+	if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+		ret = tdo24m_power_on(lcd);
+	else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+		ret = tdo24m_power_off(lcd);
+
+	if (!ret)
+		lcd->power = power;
+
+	return ret;
+}
+
+
+static int tdo24m_set_power(struct lcd_device *ld, int power)
+{
+	struct tdo24m *lcd = lcd_get_data(ld);
+	return tdo24m_power(lcd, power);
+}
+
+static int tdo24m_get_power(struct lcd_device *ld)
+{
+	struct tdo24m *lcd = lcd_get_data(ld);
+	return lcd->power;
+}
+
+static int tdo24m_set_mode(struct lcd_device *ld, struct fb_videomode *m)
+{
+	struct tdo24m *lcd = lcd_get_data(ld);
+	int mode = MODE_QVGA;
+
+	if (m->xres == 640 || m->xres == 480)
+		mode = MODE_VGA;
+
+	if (lcd->mode == mode)
+		return 0;
+
+	return tdo24m_adj_mode(lcd, mode);
+}
+
+static struct lcd_ops tdo24m_ops = {
+	.get_power	= tdo24m_get_power,
+	.set_power	= tdo24m_set_power,
+	.set_mode	= tdo24m_set_mode,
+};
+
+static int __devinit tdo24m_probe(struct spi_device *spi)
+{
+	struct tdo24m *lcd;
+	struct spi_message *m;
+	struct spi_transfer *x;
+	int err;
+
+	spi->bits_per_word = 8;
+	spi->mode = SPI_MODE_3;
+	err = spi_setup(spi);
+	if (err)
+		return err;
+
+	lcd = kzalloc(sizeof(struct tdo24m), GFP_KERNEL);
+	if (!lcd)
+		return -ENOMEM;
+
+	lcd->spi_dev = spi;
+	lcd->power = FB_BLANK_POWERDOWN;
+	lcd->mode = MODE_VGA;	/* default to VGA */
+
+	lcd->buf = kmalloc(TDO24M_SPI_BUFF_SIZE, sizeof(GFP_KERNEL));
+	if (lcd->buf == NULL) {
+		kfree(lcd);
+		return -ENOMEM;
+	}
+
+	m = &lcd->msg;
+	x = &lcd->xfer;
+
+	spi_message_init(m);
+
+	x->tx_buf = &lcd->buf[0];
+	spi_message_add_tail(x, m);
+
+	lcd->lcd_dev = lcd_device_register("tdo24m", &spi->dev,
+					lcd, &tdo24m_ops);
+	if (IS_ERR(lcd->lcd_dev)) {
+		err = PTR_ERR(lcd->lcd_dev);
+		goto out_free;
+	}
+
+	dev_set_drvdata(&spi->dev, lcd);
+	err = tdo24m_power(lcd, FB_BLANK_UNBLANK);
+	if (err)
+		goto out_unregister;
+
+	return 0;
+
+out_unregister:
+	lcd_device_unregister(lcd->lcd_dev);
+out_free:
+	kfree(lcd->buf);
+	kfree(lcd);
+	return err;
+}
+
+static int __devexit tdo24m_remove(struct spi_device *spi)
+{
+	struct tdo24m *lcd = dev_get_drvdata(&spi->dev);
+
+	tdo24m_power(lcd, FB_BLANK_POWERDOWN);
+	lcd_device_unregister(lcd->lcd_dev);
+	kfree(lcd->buf);
+	kfree(lcd);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int tdo24m_suspend(struct spi_device *spi, pm_message_t state)
+{
+	struct tdo24m *lcd = dev_get_drvdata(&spi->dev);
+
+	return tdo24m_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static int tdo24m_resume(struct spi_device *spi)
+{
+	struct tdo24m *lcd = dev_get_drvdata(&spi->dev);
+
+	return tdo24m_power(lcd, FB_BLANK_UNBLANK);
+}
+#else
+#define tdo24m_suspend	NULL
+#define tdo24m_resume	NULL
+#endif
+
+/* Power down all displays on reboot, poweroff or halt */
+static void tdo24m_shutdown(struct spi_device *spi)
+{
+	struct tdo24m *lcd = dev_get_drvdata(&spi->dev);
+
+	tdo24m_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static struct spi_driver tdo24m_driver = {
+	.driver = {
+		.name		= "tdo24m",
+		.owner		= THIS_MODULE,
+	},
+	.probe		= tdo24m_probe,
+	.remove		= __devexit_p(tdo24m_remove),
+	.shutdown	= tdo24m_shutdown,
+	.suspend	= tdo24m_suspend,
+	.resume		= tdo24m_resume,
+};
+
+static int __init tdo24m_init(void)
+{
+	return spi_register_driver(&tdo24m_driver);
+}
+module_init(tdo24m_init);
+
+static void __exit tdo24m_exit(void)
+{
+	spi_unregister_driver(&tdo24m_driver);
+}
+module_exit(tdo24m_exit);
+
+MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
+MODULE_DESCRIPTION("Driver for Toppoly TDO24M LCD Panel");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 98843c2..0737570 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -979,6 +979,7 @@
 
 				info->flags &= ~FBINFO_MISC_USEREVENT;
 				event.info = info;
+				event.data = &mode;
 				fb_notifier_call_chain(evnt, &event);
 			}
 		}
diff --git a/drivers/video/metronomefb.c b/drivers/video/metronomefb.c
index cc4c038..afeed06 100644
--- a/drivers/video/metronomefb.c
+++ b/drivers/video/metronomefb.c
@@ -40,29 +40,63 @@
 
 #include <asm/unaligned.h>
 
-
-#define DEBUG 1
-#ifdef DEBUG
-#define DPRINTK(f, a...) printk(KERN_DEBUG "%s: " f, __func__ , ## a)
-#else
-#define DPRINTK(f, a...)
-#endif
-
-
 /* Display specific information */
 #define DPY_W 832
 #define DPY_H 622
 
+static int user_wfm_size;
+
 /* frame differs from image. frame includes non-visible pixels */
 struct epd_frame {
 	int fw; /* frame width */
 	int fh; /* frame height */
+	u16 config[4];
+	int wfm_size;
 };
 
 static struct epd_frame epd_frame_table[] = {
 	{
-	.fw = 832,
-	.fh = 622
+		.fw = 832,
+		.fh = 622,
+		.config = {
+			15 /* sdlew */
+			| 2 << 8 /* sdosz */
+			| 0 << 11 /* sdor */
+			| 0 << 12 /* sdces */
+			| 0 << 15, /* sdcer */
+			42 /* gdspl */
+			| 1 << 8 /* gdr1 */
+			| 1 << 9 /* sdshr */
+			| 0 << 15, /* gdspp */
+			18 /* gdspw */
+			| 0 << 15, /* dispc */
+			599 /* vdlc */
+			| 0 << 11 /* dsi */
+			| 0 << 12, /* dsic */
+		},
+		.wfm_size = 47001,
+	},
+	{
+		.fw = 1088,
+		.fh = 791,
+		.config = {
+			0x0104,
+			0x031f,
+			0x0088,
+			0x02ff,
+		},
+		.wfm_size = 46770,
+	},
+	{
+		.fw = 1200,
+		.fh = 842,
+		.config = {
+			0x0101,
+			0x030e,
+			0x0012,
+			0x0280,
+		},
+		.wfm_size = 46770,
 	},
 };
 
@@ -134,9 +168,8 @@
 }
 
 /* here we decode the incoming waveform file and populate metromem */
-#define EXP_WFORM_SIZE 47001
-static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t,
-				u8 *frame_count)
+static int __devinit load_waveform(u8 *mem, size_t size, int m, int t,
+				struct metronomefb_par *par)
 {
 	int tta;
 	int wmta;
@@ -148,26 +181,31 @@
 	int wfm_idx, owfm_idx;
 	int mem_idx = 0;
 	struct waveform_hdr *wfm_hdr;
+	u8 *metromem = par->metromem_wfm;
+	struct device *dev = par->info->dev;
 
-	if (size != EXP_WFORM_SIZE) {
-		printk(KERN_ERR "Error: unexpected size %d != %d\n", size,
-					EXP_WFORM_SIZE);
+	if (user_wfm_size)
+		epd_frame_table[par->dt].wfm_size = user_wfm_size;
+
+	if (size != epd_frame_table[par->dt].wfm_size) {
+		dev_err(dev, "Error: unexpected size %d != %d\n", size,
+					epd_frame_table[par->dt].wfm_size);
 		return -EINVAL;
 	}
 
 	wfm_hdr = (struct waveform_hdr *) mem;
 
 	if (wfm_hdr->fvsn != 1) {
-		printk(KERN_ERR "Error: bad fvsn %x\n", wfm_hdr->fvsn);
+		dev_err(dev, "Error: bad fvsn %x\n", wfm_hdr->fvsn);
 		return -EINVAL;
 	}
 	if (wfm_hdr->luts != 0) {
-		printk(KERN_ERR "Error: bad luts %x\n", wfm_hdr->luts);
+		dev_err(dev, "Error: bad luts %x\n", wfm_hdr->luts);
 		return -EINVAL;
 	}
 	cksum = calc_cksum(32, 47, mem);
 	if (cksum != wfm_hdr->wfm_cs) {
-		printk(KERN_ERR "Error: bad cksum %x != %x\n", cksum,
+		dev_err(dev, "Error: bad cksum %x != %x\n", cksum,
 					wfm_hdr->wfm_cs);
 		return -EINVAL;
 	}
@@ -175,7 +213,7 @@
 	wfm_hdr->trc += 1;
 	for (i = 0; i < 5; i++) {
 		if (*(wfm_hdr->stuff2a + i) != 0) {
-			printk(KERN_ERR "Error: unexpected value in padding\n");
+			dev_err(dev, "Error: unexpected value in padding\n");
 			return -EINVAL;
 		}
 	}
@@ -200,7 +238,7 @@
 		return -EINVAL;
 	cksum = calc_cksum(sizeof(*wfm_hdr), cksum_idx, mem);
 	if (cksum != mem[cksum_idx]) {
-		printk(KERN_ERR "Error: bad temperature range table cksum"
+		dev_err(dev, "Error: bad temperature range table cksum"
 				" %x != %x\n", cksum, mem[cksum_idx]);
 		return -EINVAL;
 	}
@@ -212,7 +250,7 @@
 		return -EINVAL;
 	cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem);
 	if (cksum != mem[cksum_idx]) {
-		printk(KERN_ERR "Error: bad mode table address cksum"
+		dev_err(dev, "Error: bad mode table address cksum"
 				" %x != %x\n", cksum, mem[cksum_idx]);
 		return -EINVAL;
 	}
@@ -224,7 +262,7 @@
 		return -EINVAL;
 	cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem);
 	if (cksum != mem[cksum_idx]) {
-		printk(KERN_ERR "Error: bad temperature table address cksum"
+		dev_err(dev, "Error: bad temperature table address cksum"
 			" %x != %x\n", cksum, mem[cksum_idx]);
 		return -EINVAL;
 	}
@@ -259,11 +297,11 @@
 		return -EINVAL;
 	cksum = calc_cksum(owfm_idx, cksum_idx, mem);
 	if (cksum != mem[cksum_idx]) {
-		printk(KERN_ERR "Error: bad waveform data cksum"
+		dev_err(dev, "Error: bad waveform data cksum"
 				" %x != %x\n", cksum, mem[cksum_idx]);
 		return -EINVAL;
 	}
-	*frame_count = (mem_idx/64);
+	par->frame_count = (mem_idx/64);
 
 	return 0;
 }
@@ -274,15 +312,12 @@
 	u16 cs;
 	u16 opcode;
 	static u8 borderval;
-	u8 *ptr;
 
 	/* setup display command
 	we can't immediately set the opcode since the controller
 	will try parse the command before we've set it all up
 	so we just set cs here and set the opcode at the end */
 
-	ptr = par->metromem;
-
 	if (par->metromem_cmd->opcode == 0xCC40)
 		opcode = cs = 0xCC41;
 	else
@@ -335,44 +370,17 @@
 
 static int __devinit metronome_config_cmd(struct metronomefb_par *par)
 {
-	int i;
-	u16 cs;
-
 	/* setup config command
 	we can't immediately set the opcode since the controller
-	will try parse the command before we've set it all up
-	so we just set cs here and set the opcode at the end */
+	will try parse the command before we've set it all up */
 
-	cs = 0xCC10;
-
-	/* set the 12 args ( 8 bytes ) for config. see spec for meanings */
-	i = 0;
-	par->metromem_cmd->args[i] = 	15 /* sdlew */
-					| 2 << 8 /* sdosz */
-					| 0 << 11 /* sdor */
-					| 0 << 12 /* sdces */
-					| 0 << 15; /* sdcer */
-	cs += par->metromem_cmd->args[i++];
-
-	par->metromem_cmd->args[i] = 	42 /* gdspl */
-					| 1 << 8 /* gdr1 */
-					| 1 << 9 /* sdshr */
-					| 0 << 15; /* gdspp */
-	cs += par->metromem_cmd->args[i++];
-
-	par->metromem_cmd->args[i] = 	18 /* gdspw */
-					| 0 << 15; /* dispc */
-	cs += par->metromem_cmd->args[i++];
-
-	par->metromem_cmd->args[i] = 	599 /* vdlc */
-					| 0 << 11 /* dsi */
-					| 0 << 12; /* dsic */
-	cs += par->metromem_cmd->args[i++];
-
+	memcpy(par->metromem_cmd->args, epd_frame_table[par->dt].config,
+		sizeof(epd_frame_table[par->dt].config));
 	/* the rest are 0 */
-	memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2);
+	memset((u8 *) (par->metromem_cmd->args + 4), 0, (32-4)*2);
 
-	par->metromem_cmd->csum = cs;
+	par->metromem_cmd->csum = 0xCC10;
+	par->metromem_cmd->csum += calc_img_cksum(par->metromem_cmd->args, 4);
 	par->metromem_cmd->opcode = 0xCC10; /* config cmd */
 
 	return par->board->met_wait_event(par);
@@ -408,12 +416,9 @@
 {
 	int res;
 
-	par->board->init_gpio_regs(par);
-
-	par->board->init_lcdc_regs(par);
-
-	/* now that lcd is setup, setup dma descriptor */
-	par->board->post_dma_setup(par);
+	res = par->board->setup_io(par);
+	if (res)
+		return res;
 
 	res = metronome_powerup_cmd(par);
 	if (res)
@@ -430,16 +435,16 @@
 
 static void metronomefb_dpy_update(struct metronomefb_par *par)
 {
+	int fbsize;
 	u16 cksum;
 	unsigned char *buf = (unsigned char __force *)par->info->screen_base;
 
+	fbsize = par->info->fix.smem_len;
 	/* copy from vm to metromem */
-	memcpy(par->metromem_img, buf, DPY_W*DPY_H);
+	memcpy(par->metromem_img, buf, fbsize);
 
-	cksum = calc_img_cksum((u16 *) par->metromem_img,
-				(epd_frame_table[0].fw * DPY_H)/2);
-	*((u16 *)(par->metromem_img) +
-			(epd_frame_table[0].fw * DPY_H)/2) = cksum;
+	cksum = calc_img_cksum((u16 *) par->metromem_img, fbsize/2);
+	*((u16 *)(par->metromem_img) + fbsize/2) = cksum;
 	metronome_display_cmd(par);
 }
 
@@ -574,8 +579,10 @@
 	unsigned char *videomemory;
 	struct metronomefb_par *par;
 	const struct firmware *fw_entry;
-	int cmd_size, wfm_size, img_size, padding_size, totalsize;
 	int i;
+	int panel_type;
+	int fw, fh;
+	int epd_dt_index;
 
 	/* pick up board specific routines */
 	board = dev->dev.platform_data;
@@ -586,96 +593,108 @@
 	if (!try_module_get(board->owner))
 		return -ENODEV;
 
+	info = framebuffer_alloc(sizeof(struct metronomefb_par), &dev->dev);
+	if (!info)
+		goto err;
+
 	/* we have two blocks of memory.
 	info->screen_base which is vm, and is the fb used by apps.
 	par->metromem which is physically contiguous memory and
 	contains the display controller commands, waveform,
 	processed image data and padding. this is the data pulled
-	by the device's LCD controller and pushed to Metronome */
+	by the device's LCD controller and pushed to Metronome.
+	the metromem memory is allocated by the board driver and
+	is provided to us */
 
-	videomemorysize = (DPY_W*DPY_H);
+	panel_type = board->get_panel_type();
+	switch (panel_type) {
+	case 6:
+		epd_dt_index = 0;
+		break;
+	case 8:
+		epd_dt_index = 1;
+		break;
+	case 97:
+		epd_dt_index = 2;
+		break;
+	default:
+		dev_err(&dev->dev, "Unexpected panel type. Defaulting to 6\n");
+		epd_dt_index = 0;
+		break;
+	}
+
+	fw = epd_frame_table[epd_dt_index].fw;
+	fh = epd_frame_table[epd_dt_index].fh;
+
+	/* we need to add a spare page because our csum caching scheme walks
+	 * to the end of the page */
+	videomemorysize = PAGE_SIZE + (fw * fh);
 	videomemory = vmalloc(videomemorysize);
 	if (!videomemory)
-		return -ENOMEM;
+		goto err_fb_rel;
 
 	memset(videomemory, 0, videomemorysize);
 
-	info = framebuffer_alloc(sizeof(struct metronomefb_par), &dev->dev);
-	if (!info)
-		goto err_vfree;
-
 	info->screen_base = (char __force __iomem *)videomemory;
 	info->fbops = &metronomefb_ops;
 
+	metronomefb_fix.line_length = fw;
+	metronomefb_var.xres = fw;
+	metronomefb_var.yres = fh;
+	metronomefb_var.xres_virtual = fw;
+	metronomefb_var.yres_virtual = fh;
 	info->var = metronomefb_var;
 	info->fix = metronomefb_fix;
 	info->fix.smem_len = videomemorysize;
 	par = info->par;
 	par->info = info;
 	par->board = board;
+	par->dt = epd_dt_index;
 	init_waitqueue_head(&par->waitq);
 
 	/* this table caches per page csum values. */
 	par->csum_table = vmalloc(videomemorysize/PAGE_SIZE);
 	if (!par->csum_table)
-		goto err_csum_table;
-
-	/* the metromem buffer is divided as follows:
-	command | CRC | padding
-	16kb waveform data | CRC | padding
-	image data | CRC
-	and an extra 256 bytes for dma descriptors
-	eg: IW=832 IH=622 WS=128
-	*/
-
-	cmd_size = 1 * epd_frame_table[0].fw;
-	wfm_size = ((16*1024 + 2 + epd_frame_table[0].fw - 1)
-			/ epd_frame_table[0].fw) * epd_frame_table[0].fw;
-	img_size = epd_frame_table[0].fh * epd_frame_table[0].fw;
-	padding_size = 4 * epd_frame_table[0].fw;
-	totalsize = cmd_size + wfm_size + img_size + padding_size;
-	par->metromemsize = PAGE_ALIGN(totalsize + 256);
-	DPRINTK("desired memory size = %d\n", par->metromemsize);
-	dev->dev.coherent_dma_mask = 0xffffffffull;
-	par->metromem = dma_alloc_writecombine(&dev->dev, par->metromemsize,
-						&par->metromem_dma, GFP_KERNEL);
-	if (!par->metromem) {
-		printk(KERN_ERR
-			"metronomefb: unable to allocate dma buffer\n");
 		goto err_vfree;
+
+	/* the physical framebuffer that we use is setup by
+	 * the platform device driver. It will provide us
+	 * with cmd, wfm and image memory in a contiguous area. */
+	retval = board->setup_fb(par);
+	if (retval) {
+		dev_err(&dev->dev, "Failed to setup fb\n");
+		goto err_csum_table;
+	}
+
+	/* after this point we should have a framebuffer */
+	if ((!par->metromem_wfm) ||  (!par->metromem_img) ||
+		(!par->metromem_dma)) {
+		dev_err(&dev->dev, "fb access failure\n");
+		retval = -EINVAL;
+		goto err_csum_table;
 	}
 
 	info->fix.smem_start = par->metromem_dma;
-	par->metromem_cmd = (struct metromem_cmd *) par->metromem;
-	par->metromem_wfm = par->metromem + cmd_size;
-	par->metromem_img = par->metromem + cmd_size + wfm_size;
-	par->metromem_img_csum = (u16 *) (par->metromem_img +
-					(epd_frame_table[0].fw * DPY_H));
-	DPRINTK("img offset=0x%x\n", cmd_size + wfm_size);
-	par->metromem_desc = (struct metromem_desc *) (par->metromem + cmd_size
-					+ wfm_size + img_size + padding_size);
-	par->metromem_desc_dma = par->metromem_dma + cmd_size + wfm_size
-				 + img_size + padding_size;
 
 	/* load the waveform in. assume mode 3, temp 31 for now
 		a) request the waveform file from userspace
 		b) process waveform and decode into metromem */
 	retval = request_firmware(&fw_entry, "metronome.wbf", &dev->dev);
 	if (retval < 0) {
-		printk(KERN_ERR "metronomefb: couldn't get waveform\n");
-		goto err_dma_free;
+		dev_err(&dev->dev, "Failed to get waveform\n");
+		goto err_csum_table;
 	}
 
-	retval = load_waveform((u8 *) fw_entry->data, fw_entry->size,
-				par->metromem_wfm, 3, 31, &par->frame_count);
+	retval = load_waveform((u8 *) fw_entry->data, fw_entry->size, 3, 31,
+				par);
 	release_firmware(fw_entry);
 	if (retval < 0) {
-		printk(KERN_ERR "metronomefb: couldn't process waveform\n");
-		goto err_dma_free;
+		dev_err(&dev->dev, "Failed processing waveform\n");
+		goto err_csum_table;
 	}
 
 	if (board->setup_irq(info))
-		goto err_dma_free;
+		goto err_csum_table;
 
 	retval = metronome_init_regs(par);
 	if (retval < 0)
@@ -688,8 +707,8 @@
 
 	retval = fb_alloc_cmap(&info->cmap, 8, 0);
 	if (retval < 0) {
-		printk(KERN_ERR "Failed to allocate colormap\n");
-		goto err_fb_rel;
+		dev_err(&dev->dev, "Failed to allocate colormap\n");
+		goto err_free_irq;
 	}
 
 	/* set cmap */
@@ -704,7 +723,7 @@
 
 	platform_set_drvdata(dev, info);
 
-	printk(KERN_INFO
+	dev_dbg(&dev->dev,
 		"fb%d: Metronome frame buffer device, using %dK of video"
 		" memory\n", info->node, videomemorysize >> 10);
 
@@ -712,17 +731,15 @@
 
 err_cmap:
 	fb_dealloc_cmap(&info->cmap);
-err_fb_rel:
-	framebuffer_release(info);
 err_free_irq:
-	board->free_irq(info);
-err_dma_free:
-	dma_free_writecombine(&dev->dev, par->metromemsize, par->metromem,
-				par->metromem_dma);
+	board->cleanup(par);
 err_csum_table:
 	vfree(par->csum_table);
 err_vfree:
 	vfree(videomemory);
+err_fb_rel:
+	framebuffer_release(info);
+err:
 	module_put(board->owner);
 	return retval;
 }
@@ -733,15 +750,15 @@
 
 	if (info) {
 		struct metronomefb_par *par = info->par;
-		fb_deferred_io_cleanup(info);
-		dma_free_writecombine(&dev->dev, par->metromemsize,
-					par->metromem, par->metromem_dma);
-		fb_dealloc_cmap(&info->cmap);
-		vfree(par->csum_table);
+
 		unregister_framebuffer(info);
+		fb_deferred_io_cleanup(info);
+		fb_dealloc_cmap(&info->cmap);
+		par->board->cleanup(par);
+		vfree(par->csum_table);
 		vfree((void __force *)info->screen_base);
-		par->board->free_irq(info);
 		module_put(par->board->owner);
+		dev_dbg(&dev->dev, "calling release\n");
 		framebuffer_release(info);
 	}
 	return 0;
@@ -766,6 +783,9 @@
 	platform_driver_unregister(&metronomefb_driver);
 }
 
+module_param(user_wfm_size, uint, 0);
+MODULE_PARM_DESC(user_wfm_size, "Set custom waveform size");
+
 module_init(metronomefb_init);
 module_exit(metronomefb_exit);
 
diff --git a/drivers/watchdog/ixp4xx_wdt.c b/drivers/watchdog/ixp4xx_wdt.c
index 8302ef0..147b4d5 100644
--- a/drivers/watchdog/ixp4xx_wdt.c
+++ b/drivers/watchdog/ixp4xx_wdt.c
@@ -174,10 +174,8 @@
 static int __init ixp4xx_wdt_init(void)
 {
 	int ret;
-	unsigned long processor_id;
 
-	asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :);
-	if (!(processor_id & 0xf) && !cpu_is_ixp46x()) {
+	if (!(read_cpuid_id() & 0xf) && !cpu_is_ixp46x()) {
 		printk(KERN_ERR "IXP4XXX Watchdog: Rev. A0 IXP42x CPU detected"
 			" - watchdog disabled\n");
 
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index d4427cb..2e15da54 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -60,7 +60,7 @@
 
 #define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10))
 
-#define BALLOON_CLASS_NAME "memory"
+#define BALLOON_CLASS_NAME "xen_memory"
 
 struct balloon_stats {
 	/* We aim for 'current allocation' == 'target allocation'. */
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c
index 87ee5cc..ed8feb0 100644
--- a/fs/bfs/dir.c
+++ b/fs/bfs/dir.c
@@ -125,8 +125,8 @@
 							inode->i_ino);
 	if (err) {
 		inode_dec_link_count(inode);
-		iput(inode);
 		mutex_unlock(&info->bfs_lock);
+		iput(inode);
 		return err;
 	}
 	mutex_unlock(&info->bfs_lock);
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 9abcd2b..e9b2017 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1279,6 +1279,12 @@
 		}
 	}
 
+	if (errors > 0) {
+		dfprintk(MOUNT, "NFS: parsing encountered %d error%s\n",
+				errors, (errors == 1 ? "" : "s"));
+		if (!sloppy)
+			return 0;
+	}
 	return 1;
 
 out_nomem:
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 506c24f..a53da14 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -594,7 +594,7 @@
 		goto bail;
 	}
 
-	if (!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)) && !p_blkno) {
+	if (!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)) && !p_blkno && create) {
 		ocfs2_error(inode->i_sb,
 			    "Inode %llu has a hole at block %llu\n",
 			    (unsigned long long)OCFS2_I(inode)->ip_blkno,
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 7d6b34e..ecc3330 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -499,9 +499,9 @@
 		if (!size)
 			continue;
 		if (from + size > get_capacity(disk)) {
-			printk(KERN_ERR " %s: p%d exceeds device capacity\n",
+			printk(KERN_WARNING
+				"%s: p%d exceeds device capacity\n",
 				disk->disk_name, p);
-			continue;
 		}
 		res = add_partition(disk, p, from, size, state->parts[p].flags);
 		if (res) {
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 0d6eb33..71c9be5 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -337,65 +337,6 @@
 	return 0;
 }
 
-/*
- * Use precise platform statistics if available:
- */
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING
-static cputime_t task_utime(struct task_struct *p)
-{
-	return p->utime;
-}
-
-static cputime_t task_stime(struct task_struct *p)
-{
-	return p->stime;
-}
-#else
-static cputime_t task_utime(struct task_struct *p)
-{
-	clock_t utime = cputime_to_clock_t(p->utime),
-		total = utime + cputime_to_clock_t(p->stime);
-	u64 temp;
-
-	/*
-	 * Use CFS's precise accounting:
-	 */
-	temp = (u64)nsec_to_clock_t(p->se.sum_exec_runtime);
-
-	if (total) {
-		temp *= utime;
-		do_div(temp, total);
-	}
-	utime = (clock_t)temp;
-
-	p->prev_utime = max(p->prev_utime, clock_t_to_cputime(utime));
-	return p->prev_utime;
-}
-
-static cputime_t task_stime(struct task_struct *p)
-{
-	clock_t stime;
-
-	/*
-	 * Use CFS's precise accounting. (we subtract utime from
-	 * the total, to make sure the total observed by userspace
-	 * grows monotonically - apps rely on that):
-	 */
-	stime = nsec_to_clock_t(p->se.sum_exec_runtime) -
-			cputime_to_clock_t(task_utime(p));
-
-	if (stime >= 0)
-		p->prev_stime = max(p->prev_stime, clock_t_to_cputime(stime));
-
-	return p->prev_stime;
-}
-#endif
-
-static cputime_t task_gtime(struct task_struct *p)
-{
-	return p->gtime;
-}
-
 static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
 			struct pid *pid, struct task_struct *task, int whole)
 {
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index bca0f81..7821589 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -547,8 +547,8 @@
 
 	for (tmp = dir->subdir; tmp; tmp = tmp->next)
 		if (strcmp(tmp->name, dp->name) == 0) {
-			printk(KERN_WARNING "proc_dir_entry '%s' already "
-					"registered\n", dp->name);
+			printk(KERN_WARNING "proc_dir_entry '%s/%s' already registered\n",
+				dir->name, dp->name);
 			dump_stack();
 			break;
 		}
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 00f10a2..29e20c6 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -183,6 +183,9 @@
 		"SReclaimable: %8lu kB\n"
 		"SUnreclaim:   %8lu kB\n"
 		"PageTables:   %8lu kB\n"
+#ifdef CONFIG_QUICKLIST
+		"Quicklists:   %8lu kB\n"
+#endif
 		"NFS_Unstable: %8lu kB\n"
 		"Bounce:       %8lu kB\n"
 		"WritebackTmp: %8lu kB\n"
@@ -190,8 +193,7 @@
 		"Committed_AS: %8lu kB\n"
 		"VmallocTotal: %8lu kB\n"
 		"VmallocUsed:  %8lu kB\n"
-		"VmallocChunk: %8lu kB\n"
-		"Quicklists:   %8lu kB\n",
+		"VmallocChunk: %8lu kB\n",
 		K(i.totalram),
 		K(i.freeram),
 		K(i.bufferram),
@@ -216,6 +218,9 @@
 		K(global_page_state(NR_SLAB_RECLAIMABLE)),
 		K(global_page_state(NR_SLAB_UNRECLAIMABLE)),
 		K(global_page_state(NR_PAGETABLE)),
+#ifdef CONFIG_QUICKLIST
+		K(quicklist_total_size()),
+#endif
 		K(global_page_state(NR_UNSTABLE_NFS)),
 		K(global_page_state(NR_BOUNCE)),
 		K(global_page_state(NR_WRITEBACK_TEMP)),
@@ -223,8 +228,7 @@
 		K(committed),
 		(unsigned long)VMALLOC_TOTAL >> 10,
 		vmi.used >> 10,
-		vmi.largest_chunk >> 10,
-		K(quicklist_total_size())
+		vmi.largest_chunk >> 10
 		);
 
 		len += hugetlb_report_meminfo(page + len);
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c
index 15409815..73db464 100644
--- a/fs/ubifs/budget.c
+++ b/fs/ubifs/budget.c
@@ -302,18 +302,6 @@
 	int subtract_lebs;
 	long long available;
 
-	/*
-	 * Force the amount available to the total size reported if the used
-	 * space is zero.
-	 */
-	if (c->lst.total_used <= UBIFS_INO_NODE_SZ &&
-	    c->budg_data_growth + c->budg_dd_growth == 0) {
-		/* Do the same calculation as for c->block_cnt */
-		available = c->main_lebs - 2;
-		available *= c->leb_size - c->dark_wm;
-		return available;
-	}
-
 	available = c->main_bytes - c->lst.total_used;
 
 	/*
@@ -714,34 +702,106 @@
 }
 
 /**
- * ubifs_budg_get_free_space - return amount of free space.
+ * ubifs_reported_space - calculate reported free space.
+ * @c: the UBIFS file-system description object
+ * @free: amount of free space
+ *
+ * This function calculates amount of free space which will be reported to
+ * user-space. User-space application tend to expect that if the file-system
+ * (e.g., via the 'statfs()' call) reports that it has N bytes available, they
+ * are able to write a file of size N. UBIFS attaches node headers to each data
+ * node and it has to write indexind nodes as well. This introduces additional
+ * overhead, and UBIFS it has to report sligtly less free space to meet the
+ * above expectetion.
+ *
+ * This function assumes free space is made up of uncompressed data nodes and
+ * full index nodes (one per data node, tripled because we always allow enough
+ * space to write the index thrice).
+ *
+ * Note, the calculation is pessimistic, which means that most of the time
+ * UBIFS reports less space than it actually has.
+ */
+long long ubifs_reported_space(const struct ubifs_info *c, uint64_t free)
+{
+	int divisor, factor, f;
+
+	/*
+	 * Reported space size is @free * X, where X is UBIFS block size
+	 * divided by UBIFS block size + all overhead one data block
+	 * introduces. The overhead is the node header + indexing overhead.
+	 *
+	 * Indexing overhead calculations are based on the following formula:
+	 * I = N/(f - 1) + 1, where I - number of indexing nodes, N - number
+	 * of data nodes, f - fanout. Because effective UBIFS fanout is twice
+	 * as less than maximum fanout, we assume that each data node
+	 * introduces 3 * @c->max_idx_node_sz / (@c->fanout/2 - 1) bytes.
+	 * Note, the multiplier 3 is because UBIFS reseves thrice as more space
+	 * for the index.
+	 */
+	f = c->fanout > 3 ? c->fanout >> 1 : 2;
+	factor = UBIFS_BLOCK_SIZE;
+	divisor = UBIFS_MAX_DATA_NODE_SZ;
+	divisor += (c->max_idx_node_sz * 3) / (f - 1);
+	free *= factor;
+	do_div(free, divisor);
+	return free;
+}
+
+/**
+ * ubifs_get_free_space - return amount of free space.
  * @c: UBIFS file-system description object
  *
- * This function returns amount of free space on the file-system.
+ * This function calculates amount of free space to report to user-space.
+ *
+ * Because UBIFS may introduce substantial overhead (the index, node headers,
+ * alighment, wastage at the end of eraseblocks, etc), it cannot report real
+ * amount of free flash space it has (well, because not all dirty space is
+ * reclamable, UBIFS does not actually know the real amount). If UBIFS did so,
+ * it would bread user expectetion about what free space is. Users seem to
+ * accustomed to assume that if the file-system reports N bytes of free space,
+ * they would be able to fit a file of N bytes to the FS. This almost works for
+ * traditional file-systems, because they have way less overhead than UBIFS.
+ * So, to keep users happy, UBIFS tries to take the overhead into account.
  */
-long long ubifs_budg_get_free_space(struct ubifs_info *c)
+long long ubifs_get_free_space(struct ubifs_info *c)
 {
-	int min_idx_lebs, rsvd_idx_lebs;
+	int min_idx_lebs, rsvd_idx_lebs, lebs;
 	long long available, outstanding, free;
 
-	/* Do exactly the same calculations as in 'do_budget_space()' */
 	spin_lock(&c->space_lock);
 	min_idx_lebs = ubifs_calc_min_idx_lebs(c);
+	outstanding = c->budg_data_growth + c->budg_dd_growth;
 
+	/*
+	 * Force the amount available to the total size reported if the used
+	 * space is zero.
+	 */
+	if (c->lst.total_used <= UBIFS_INO_NODE_SZ && !outstanding) {
+		spin_unlock(&c->space_lock);
+		return (long long)c->block_cnt << UBIFS_BLOCK_SHIFT;
+	}
+
+	available = ubifs_calc_available(c, min_idx_lebs);
+
+	/*
+	 * When reporting free space to user-space, UBIFS guarantees that it is
+	 * possible to write a file of free space size. This means that for
+	 * empty LEBs we may use more precise calculations than
+	 * 'ubifs_calc_available()' is using. Namely, we know that in empty
+	 * LEBs we would waste only @c->leb_overhead bytes, not @c->dark_wm.
+	 * Thus, amend the available space.
+	 *
+	 * Note, the calculations below are similar to what we have in
+	 * 'do_budget_space()', so refer there for comments.
+	 */
 	if (min_idx_lebs > c->lst.idx_lebs)
 		rsvd_idx_lebs = min_idx_lebs - c->lst.idx_lebs;
 	else
 		rsvd_idx_lebs = 0;
-
-	if (rsvd_idx_lebs > c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt
-				- c->lst.taken_empty_lebs) {
-		spin_unlock(&c->space_lock);
-		return 0;
-	}
-
-	available = ubifs_calc_available(c, min_idx_lebs);
-	outstanding = c->budg_data_growth + c->budg_dd_growth;
-	c->min_idx_lebs = min_idx_lebs;
+	lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt -
+	       c->lst.taken_empty_lebs;
+	lebs -= rsvd_idx_lebs;
+	available += lebs * (c->dark_wm - c->leb_overhead);
 	spin_unlock(&c->space_lock);
 
 	if (available > outstanding)
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 5c96f1f..2b267c9 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -587,7 +587,6 @@
 	if (err) {
 		if (err != -ENOSPC)
 			return err;
-		err = 0;
 		budgeted = 0;
 	}
 
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 4071d1c..3d698e2 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -793,7 +793,7 @@
 	int err;
 	struct ubifs_budget_req req;
 	loff_t old_size = inode->i_size, new_size = attr->ia_size;
-	int offset = new_size & (UBIFS_BLOCK_SIZE - 1);
+	int offset = new_size & (UBIFS_BLOCK_SIZE - 1), budgeted = 1;
 	struct ubifs_inode *ui = ubifs_inode(inode);
 
 	dbg_gen("ino %lu, size %lld -> %lld", inode->i_ino, old_size, new_size);
@@ -811,8 +811,15 @@
 	/* A funny way to budget for truncation node */
 	req.dirtied_ino_d = UBIFS_TRUN_NODE_SZ;
 	err = ubifs_budget_space(c, &req);
-	if (err)
-		return err;
+	if (err) {
+		/*
+		 * Treat truncations to zero as deletion and always allow them,
+		 * just like we do for '->unlink()'.
+		 */
+		if (new_size || err != -ENOSPC)
+			return err;
+		budgeted = 0;
+	}
 
 	err = vmtruncate(inode, new_size);
 	if (err)
@@ -869,7 +876,12 @@
 	err = ubifs_jnl_truncate(c, inode, old_size, new_size);
 	mutex_unlock(&ui->ui_mutex);
 out_budg:
-	ubifs_release_budget(c, &req);
+	if (budgeted)
+		ubifs_release_budget(c, &req);
+	else {
+		c->nospace = c->nospace_rp = 0;
+		smp_wmb();
+	}
 	return err;
 }
 
diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c
index adee7b5..e045c8b 100644
--- a/fs/ubifs/find.c
+++ b/fs/ubifs/find.c
@@ -211,14 +211,8 @@
  * dirty index heap, and it falls-back to LPT scanning if the heaps are empty
  * or do not have an LEB which satisfies the @min_space criteria.
  *
- * Note:
- *   o LEBs which have less than dead watermark of dirty space are never picked
- *   by this function;
- *
- * Returns zero and the LEB properties of
- * found dirty LEB in case of success, %-ENOSPC if no dirty LEB was found and a
- * negative error code in case of other failures. The returned LEB is marked as
- * "taken".
+ * Note, LEBs which have less than dead watermark of free + dirty space are
+ * never picked by this function.
  *
  * The additional @pick_free argument controls if this function has to return a
  * free or freeable LEB if one is present. For example, GC must to set it to %1,
@@ -231,6 +225,10 @@
  *
  * In addition @pick_free is set to %2 by the recovery process in order to
  * recover gc_lnum in which case an index LEB must not be returned.
+ *
+ * This function returns zero and the LEB properties of found dirty LEB in case
+ * of success, %-ENOSPC if no dirty LEB was found and a negative error code in
+ * case of other failures. The returned LEB is marked as "taken".
  */
 int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp,
 			 int min_space, int pick_free)
@@ -245,7 +243,7 @@
 		int lebs, rsvd_idx_lebs = 0;
 
 		spin_lock(&c->space_lock);
-		lebs = c->lst.empty_lebs;
+		lebs = c->lst.empty_lebs + c->idx_gc_cnt;
 		lebs += c->freeable_cnt - c->lst.taken_empty_lebs;
 
 		/*
@@ -317,7 +315,7 @@
 		lp = idx_lp;
 
 	if (lp) {
-		ubifs_assert(lp->dirty >= c->dead_wm);
+		ubifs_assert(lp->free + lp->dirty >= c->dead_wm);
 		goto found;
 	}
 
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c
index d0f3dac..13f1019 100644
--- a/fs/ubifs/gc.c
+++ b/fs/ubifs/gc.c
@@ -344,6 +344,12 @@
 		if (err)
 			goto out;
 
+		/* Allow for races with TNC */
+		c->gced_lnum = lnum;
+		smp_wmb();
+		c->gc_seq += 1;
+		smp_wmb();
+
 		if (c->gc_lnum == -1) {
 			c->gc_lnum = lnum;
 			err = LEB_RETAINED;
diff --git a/fs/ubifs/misc.h b/fs/ubifs/misc.h
index 87dabf9..4c12a92 100644
--- a/fs/ubifs/misc.h
+++ b/fs/ubifs/misc.h
@@ -284,38 +284,6 @@
 }
 
 /**
- * ubifs_reported_space - calculate reported free space.
- * @c: the UBIFS file-system description object
- * @free: amount of free space
- *
- * This function calculates amount of free space which will be reported to
- * user-space. User-space application tend to expect that if the file-system
- * (e.g., via the 'statfs()' call) reports that it has N bytes available, they
- * are able to write a file of size N. UBIFS attaches node headers to each data
- * node and it has to write indexind nodes as well. This introduces additional
- * overhead, and UBIFS it has to report sligtly less free space to meet the
- * above expectetion.
- *
- * This function assumes free space is made up of uncompressed data nodes and
- * full index nodes (one per data node, doubled because we always allow enough
- * space to write the index twice).
- *
- * Note, the calculation is pessimistic, which means that most of the time
- * UBIFS reports less space than it actually has.
- */
-static inline long long ubifs_reported_space(const struct ubifs_info *c,
-					     uint64_t free)
-{
-	int divisor, factor;
-
-	divisor = UBIFS_MAX_DATA_NODE_SZ + (c->max_idx_node_sz * 3);
-	factor = UBIFS_MAX_DATA_NODE_SZ - UBIFS_DATA_NODE_SZ;
-	do_div(free, divisor);
-
-	return free * factor;
-}
-
-/**
  * ubifs_current_time - round current time to time granularity.
  * @inode: inode
  */
@@ -325,4 +293,21 @@
 		current_fs_time(inode->i_sb) : CURRENT_TIME_SEC;
 }
 
+/**
+ * ubifs_tnc_lookup - look up a file-system node.
+ * @c: UBIFS file-system description object
+ * @key: node key to lookup
+ * @node: the node is returned here
+ *
+ * This function look up and reads node with key @key. The caller has to make
+ * sure the @node buffer is large enough to fit the node. Returns zero in case
+ * of success, %-ENOENT if the node was not found, and a negative error code in
+ * case of failure.
+ */
+static inline int ubifs_tnc_lookup(struct ubifs_info *c,
+				   const union ubifs_key *key, void *node)
+{
+	return ubifs_tnc_locate(c, key, node, NULL, NULL);
+}
+
 #endif /* __UBIFS_MISC_H__ */
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index f71e6b8..7562464 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -370,8 +370,9 @@
 {
 	struct ubifs_info *c = dentry->d_sb->s_fs_info;
 	unsigned long long free;
+	__le32 *uuid = (__le32 *)c->uuid;
 
-	free = ubifs_budg_get_free_space(c);
+	free = ubifs_get_free_space(c);
 	dbg_gen("free space %lld bytes (%lld blocks)",
 		free, free >> UBIFS_BLOCK_SHIFT);
 
@@ -386,7 +387,8 @@
 	buf->f_files = 0;
 	buf->f_ffree = 0;
 	buf->f_namelen = UBIFS_MAX_NLEN;
-
+	buf->f_fsid.val[0] = le32_to_cpu(uuid[0]) ^ le32_to_cpu(uuid[2]);
+	buf->f_fsid.val[1] = le32_to_cpu(uuid[1]) ^ le32_to_cpu(uuid[3]);
 	return 0;
 }
 
@@ -530,6 +532,12 @@
 	c->dead_wm = ALIGN(MIN_WRITE_SZ, c->min_io_size);
 	c->dark_wm = ALIGN(UBIFS_MAX_NODE_SZ, c->min_io_size);
 
+	/*
+	 * Calculate how many bytes would be wasted at the end of LEB if it was
+	 * fully filled with data nodes of maximum size. This is used in
+	 * calculations when reporting free space.
+	 */
+	c->leb_overhead = c->leb_size % UBIFS_MAX_DATA_NODE_SZ;
 	return 0;
 }
 
@@ -647,13 +655,11 @@
 	 * internally because it does not make much sense for UBIFS, but it is
 	 * necessary to report something for the 'statfs()' call.
 	 *
-	 * Subtract the LEB reserved for GC and the LEB which is reserved for
-	 * deletions.
-	 *
-	 * Review 'ubifs_calc_available()' if changing this calculation.
+	 * Subtract the LEB reserved for GC, the LEB which is reserved for
+	 * deletions, and assume only one journal head is available.
 	 */
-	tmp64 = c->main_lebs - 2;
-	tmp64 *= (uint64_t)c->leb_size - c->dark_wm;
+	tmp64 = c->main_lebs - 2 - c->jhead_cnt + 1;
+	tmp64 *= (uint64_t)c->leb_size - c->leb_overhead;
 	tmp64 = ubifs_reported_space(c, tmp64);
 	c->block_cnt = tmp64 >> UBIFS_BLOCK_SHIFT;
 
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
index e909f4a..7da209a 100644
--- a/fs/ubifs/tnc.c
+++ b/fs/ubifs/tnc.c
@@ -506,7 +506,7 @@
 		if (keys_cmp(c, key, &node_key) != 0)
 			ret = 0;
 	}
-	if (ret == 0)
+	if (ret == 0 && c->replaying)
 		dbg_mnt("dangling branch LEB %d:%d len %d, key %s",
 			zbr->lnum, zbr->offs, zbr->len, DBGKEY(key));
 	return ret;
@@ -1382,50 +1382,39 @@
 }
 
 /**
- * ubifs_tnc_lookup - look up a file-system node.
+ * maybe_leb_gced - determine if a LEB may have been garbage collected.
  * @c: UBIFS file-system description object
- * @key: node key to lookup
- * @node: the node is returned here
+ * @lnum: LEB number
+ * @gc_seq1: garbage collection sequence number
  *
- * This function look up and reads node with key @key. The caller has to make
- * sure the @node buffer is large enough to fit the node. Returns zero in case
- * of success, %-ENOENT if the node was not found, and a negative error code in
- * case of failure.
+ * This function determines if @lnum may have been garbage collected since
+ * sequence number @gc_seq1. If it may have been then %1 is returned, otherwise
+ * %0 is returned.
  */
-int ubifs_tnc_lookup(struct ubifs_info *c, const union ubifs_key *key,
-		     void *node)
+static int maybe_leb_gced(struct ubifs_info *c, int lnum, int gc_seq1)
 {
-	int found, n, err;
-	struct ubifs_znode *znode;
-	struct ubifs_zbranch zbr, *zt;
+	int gc_seq2, gced_lnum;
 
-	mutex_lock(&c->tnc_mutex);
-	found = ubifs_lookup_level0(c, key, &znode, &n);
-	if (!found) {
-		err = -ENOENT;
-		goto out;
-	} else if (found < 0) {
-		err = found;
-		goto out;
-	}
-	zt = &znode->zbranch[n];
-	if (is_hash_key(c, key)) {
-		/*
-		 * In this case the leaf node cache gets used, so we pass the
-		 * address of the zbranch and keep the mutex locked
-		 */
-		err = tnc_read_node_nm(c, zt, node);
-		goto out;
-	}
-	zbr = znode->zbranch[n];
-	mutex_unlock(&c->tnc_mutex);
-
-	err = ubifs_tnc_read_node(c, &zbr, node);
-	return err;
-
-out:
-	mutex_unlock(&c->tnc_mutex);
-	return err;
+	gced_lnum = c->gced_lnum;
+	smp_rmb();
+	gc_seq2 = c->gc_seq;
+	/* Same seq means no GC */
+	if (gc_seq1 == gc_seq2)
+		return 0;
+	/* Different by more than 1 means we don't know */
+	if (gc_seq1 + 1 != gc_seq2)
+		return 1;
+	/*
+	 * We have seen the sequence number has increased by 1. Now we need to
+	 * be sure we read the right LEB number, so read it again.
+	 */
+	smp_rmb();
+	if (gced_lnum != c->gced_lnum)
+		return 1;
+	/* Finally we can check lnum */
+	if (gced_lnum == lnum)
+		return 1;
+	return 0;
 }
 
 /**
@@ -1436,16 +1425,19 @@
  * @lnum: LEB number is returned here
  * @offs: offset is returned here
  *
- * This function is the same as 'ubifs_tnc_lookup()' but it returns the node
- * location also. See 'ubifs_tnc_lookup()'.
+ * This function look up and reads node with key @key. The caller has to make
+ * sure the @node buffer is large enough to fit the node. Returns zero in case
+ * of success, %-ENOENT if the node was not found, and a negative error code in
+ * case of failure. The node location can be returned in @lnum and @offs.
  */
 int ubifs_tnc_locate(struct ubifs_info *c, const union ubifs_key *key,
 		     void *node, int *lnum, int *offs)
 {
-	int found, n, err;
+	int found, n, err, safely = 0, gc_seq1;
 	struct ubifs_znode *znode;
 	struct ubifs_zbranch zbr, *zt;
 
+again:
 	mutex_lock(&c->tnc_mutex);
 	found = ubifs_lookup_level0(c, key, &znode, &n);
 	if (!found) {
@@ -1456,24 +1448,43 @@
 		goto out;
 	}
 	zt = &znode->zbranch[n];
+	if (lnum) {
+		*lnum = zt->lnum;
+		*offs = zt->offs;
+	}
 	if (is_hash_key(c, key)) {
 		/*
 		 * In this case the leaf node cache gets used, so we pass the
 		 * address of the zbranch and keep the mutex locked
 		 */
-		*lnum = zt->lnum;
-		*offs = zt->offs;
 		err = tnc_read_node_nm(c, zt, node);
 		goto out;
 	}
+	if (safely) {
+		err = ubifs_tnc_read_node(c, zt, node);
+		goto out;
+	}
+	/* Drop the TNC mutex prematurely and race with garbage collection */
 	zbr = znode->zbranch[n];
+	gc_seq1 = c->gc_seq;
 	mutex_unlock(&c->tnc_mutex);
 
-	*lnum = zbr.lnum;
-	*offs = zbr.offs;
+	if (ubifs_get_wbuf(c, zbr.lnum)) {
+		/* We do not GC journal heads */
+		err = ubifs_tnc_read_node(c, &zbr, node);
+		return err;
+	}
 
-	err = ubifs_tnc_read_node(c, &zbr, node);
-	return err;
+	err = fallible_read_node(c, key, &zbr, node);
+	if (maybe_leb_gced(c, zbr.lnum, gc_seq1)) {
+		/*
+		 * The node may have been GC'ed out from under us so try again
+		 * while keeping the TNC mutex locked.
+		 */
+		safely = 1;
+		goto again;
+	}
+	return 0;
 
 out:
 	mutex_unlock(&c->tnc_mutex);
@@ -1498,7 +1509,6 @@
 {
 	int found, n, err;
 	struct ubifs_znode *znode;
-	struct ubifs_zbranch zbr;
 
 	dbg_tnc("name '%.*s' key %s", nm->len, nm->name, DBGKEY(key));
 	mutex_lock(&c->tnc_mutex);
@@ -1522,11 +1532,7 @@
 		goto out_unlock;
 	}
 
-	zbr = znode->zbranch[n];
-	mutex_unlock(&c->tnc_mutex);
-
-	err = tnc_read_node_nm(c, &zbr, node);
-	return err;
+	err = tnc_read_node_nm(c, &znode->zbranch[n], node);
 
 out_unlock:
 	mutex_unlock(&c->tnc_mutex);
diff --git a/fs/ubifs/ubifs-media.h b/fs/ubifs/ubifs-media.h
index bd2121f..a9ecbd9 100644
--- a/fs/ubifs/ubifs-media.h
+++ b/fs/ubifs/ubifs-media.h
@@ -87,7 +87,7 @@
 #define UBIFS_SK_LEN 8
 
 /* Minimum index tree fanout */
-#define UBIFS_MIN_FANOUT 2
+#define UBIFS_MIN_FANOUT 3
 
 /* Maximum number of levels in UBIFS indexing B-tree */
 #define UBIFS_MAX_LEVELS 512
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index d7f706f..17c620b 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -995,6 +995,9 @@
  * @max_idx_node_sz: maximum indexing node aligned on 8-bytes boundary
  * @max_inode_sz: maximum possible inode size in bytes
  * @max_znode_sz: size of znode in bytes
+ *
+ * @leb_overhead: how many bytes are wasted in an LEB when it is filled with
+ *                data nodes of maximum size - used in free space reporting
  * @dead_wm: LEB dead space watermark
  * @dark_wm: LEB dark space watermark
  * @block_cnt: count of 4KiB blocks on the FS
@@ -1028,6 +1031,8 @@
  * @sbuf: a buffer of LEB size used by GC and replay for scanning
  * @idx_gc: list of index LEBs that have been garbage collected
  * @idx_gc_cnt: number of elements on the idx_gc list
+ * @gc_seq: incremented for every non-index LEB garbage collected
+ * @gced_lnum: last non-index LEB that was garbage collected
  *
  * @infos_list: links all 'ubifs_info' objects
  * @umount_mutex: serializes shrinker and un-mount
@@ -1224,6 +1229,8 @@
 	int max_idx_node_sz;
 	long long max_inode_sz;
 	int max_znode_sz;
+
+	int leb_overhead;
 	int dead_wm;
 	int dark_wm;
 	int block_cnt;
@@ -1257,6 +1264,8 @@
 	void *sbuf;
 	struct list_head idx_gc;
 	int idx_gc_cnt;
+	volatile int gc_seq;
+	volatile int gced_lnum;
 
 	struct list_head infos_list;
 	struct mutex umount_mutex;
@@ -1434,9 +1443,10 @@
 				struct ubifs_budget_req *req);
 void ubifs_cancel_ino_op(struct ubifs_info *c, struct inode *inode,
 			 struct ubifs_budget_req *req);
-long long ubifs_budg_get_free_space(struct ubifs_info *c);
+long long ubifs_get_free_space(struct ubifs_info *c);
 int ubifs_calc_min_idx_lebs(struct ubifs_info *c);
 void ubifs_convert_page_budget(struct ubifs_info *c);
+long long ubifs_reported_space(const struct ubifs_info *c, uint64_t free);
 long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs);
 
 /* find.c */
@@ -1451,8 +1461,6 @@
 /* tnc.c */
 int ubifs_lookup_level0(struct ubifs_info *c, const union ubifs_key *key,
 			struct ubifs_znode **zn, int *n);
-int ubifs_tnc_lookup(struct ubifs_info *c, const union ubifs_key *key,
-		     void *node);
 int ubifs_tnc_lookup_nm(struct ubifs_info *c, const union ubifs_key *key,
 			void *node, const struct qstr *nm);
 int ubifs_tnc_locate(struct ubifs_info *c, const union ubifs_key *key,
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 0ed6e14..eb91f3b 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -211,6 +211,7 @@
 	.release		= udf_release_file,
 	.fsync			= udf_fsync_file,
 	.splice_read		= generic_file_splice_read,
+	.llseek			= generic_file_llseek,
 };
 
 const struct inode_operations udf_file_inode_operations = {
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c
index eb9cfa2..a4f2b3c 100644
--- a/fs/udf/ialloc.c
+++ b/fs/udf/ialloc.c
@@ -76,11 +76,24 @@
 	*err = -ENOSPC;
 
 	iinfo = UDF_I(inode);
-	iinfo->i_unique = 0;
-	iinfo->i_lenExtents = 0;
-	iinfo->i_next_alloc_block = 0;
-	iinfo->i_next_alloc_goal = 0;
-	iinfo->i_strat4096 = 0;
+	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE)) {
+		iinfo->i_efe = 1;
+		if (UDF_VERS_USE_EXTENDED_FE > sbi->s_udfrev)
+			sbi->s_udfrev = UDF_VERS_USE_EXTENDED_FE;
+		iinfo->i_ext.i_data = kzalloc(inode->i_sb->s_blocksize -
+					    sizeof(struct extendedFileEntry),
+					    GFP_KERNEL);
+	} else {
+		iinfo->i_efe = 0;
+		iinfo->i_ext.i_data = kzalloc(inode->i_sb->s_blocksize -
+					    sizeof(struct fileEntry),
+					    GFP_KERNEL);
+	}
+	if (!iinfo->i_ext.i_data) {
+		iput(inode);
+		*err = -ENOMEM;
+		return NULL;
+	}
 
 	block = udf_new_block(dir->i_sb, NULL,
 			      dinfo->i_location.partitionReferenceNum,
@@ -111,6 +124,7 @@
 		lvhd->uniqueID = cpu_to_le64(uniqueID);
 		mark_buffer_dirty(sbi->s_lvid_bh);
 	}
+	mutex_unlock(&sbi->s_alloc_mutex);
 	inode->i_mode = mode;
 	inode->i_uid = current->fsuid;
 	if (dir->i_mode & S_ISGID) {
@@ -129,25 +143,6 @@
 	iinfo->i_lenEAttr = 0;
 	iinfo->i_lenAlloc = 0;
 	iinfo->i_use = 0;
-	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE)) {
-		iinfo->i_efe = 1;
-		if (UDF_VERS_USE_EXTENDED_FE > sbi->s_udfrev)
-			sbi->s_udfrev = UDF_VERS_USE_EXTENDED_FE;
-		iinfo->i_ext.i_data = kzalloc(inode->i_sb->s_blocksize -
-					    sizeof(struct extendedFileEntry),
-					    GFP_KERNEL);
-	} else {
-		iinfo->i_efe = 0;
-		iinfo->i_ext.i_data = kzalloc(inode->i_sb->s_blocksize -
-					    sizeof(struct fileEntry),
-					    GFP_KERNEL);
-	}
-	if (!iinfo->i_ext.i_data) {
-		iput(inode);
-		*err = -ENOMEM;
-		mutex_unlock(&sbi->s_alloc_mutex);
-		return NULL;
-	}
 	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB))
 		iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
 	else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
@@ -158,7 +153,6 @@
 		iinfo->i_crtime = current_fs_time(inode->i_sb);
 	insert_inode_hash(inode);
 	mark_inode_dirty(inode);
-	mutex_unlock(&sbi->s_alloc_mutex);
 
 	if (DQUOT_ALLOC_INODE(inode)) {
 		DQUOT_DROP(inode);
diff --git a/include/asm-generic/Kbuild.asm b/include/asm-generic/Kbuild.asm
index 1170dc6..1870d5e 100644
--- a/include/asm-generic/Kbuild.asm
+++ b/include/asm-generic/Kbuild.asm
@@ -1,8 +1,10 @@
-ifneq ($(wildcard $(srctree)/include/asm-$(SRCARCH)/kvm.h),)
+ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm.h \
+      		  $(srctree)/include/asm-$(SRCARCH)/kvm.h),)
 header-y  += kvm.h
 endif
 
-ifneq ($(wildcard $(srctree)/include/asm-$(SRCARCH)/a.out.h),)
+ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/a.out.h \
+      		  $(srctree)/include/asm-$(SRCARCH)/a.out.h),)
 unifdef-y += a.out.h
 endif
 unifdef-y += auxvec.h
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index a3f738c..edc6ba8 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -97,6 +97,16 @@
 	unlikely(__ret_warn_once);				\
 })
 
+#define WARN_ONCE(condition, format...)	({			\
+	static int __warned;					\
+	int __ret_warn_once = !!(condition);			\
+								\
+	if (unlikely(__ret_warn_once))				\
+		if (WARN(!__warned, format)) 			\
+			__warned = 1;				\
+	unlikely(__ret_warn_once);				\
+})
+
 #define WARN_ON_RATELIMIT(condition, state)			\
 		WARN_ON((condition) && __ratelimit(state))
 
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index 8feeae1..79a7ff9 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -14,4 +14,10 @@
 extern char __initdata_begin[], __initdata_end[];
 extern char __start_rodata[], __end_rodata[];
 
+/* function descriptor handling (if any).  Override
+ * in asm/sections.h */
+#ifndef dereference_function_descriptor
+#define dereference_function_descriptor(p) (p)
+#endif
+
 #endif /* _ASM_GENERIC_SECTIONS_H_ */
diff --git a/include/asm-generic/syscall.h b/include/asm-generic/syscall.h
index abcf34c..ea8087b 100644
--- a/include/asm-generic/syscall.h
+++ b/include/asm-generic/syscall.h
@@ -126,7 +126,7 @@
  * @args:	array of argument values to store
  *
  * Changes @n arguments to the system call starting with the @i'th argument.
- * @n'th argument to @val.  Argument @i gets value @args[0], and so on.
+ * Argument @i gets value @args[0], and so on.
  * An arch inline version is probably optimal when @i and @n are constants.
  *
  * It's only valid to call this when @task is stopped for tracing on
diff --git a/include/asm-mips/cacheflush.h b/include/asm-mips/cacheflush.h
index d5c0f2f..03b1d69 100644
--- a/include/asm-mips/cacheflush.h
+++ b/include/asm-mips/cacheflush.h
@@ -63,6 +63,7 @@
 }
 
 extern void (*flush_icache_range)(unsigned long start, unsigned long end);
+extern void (*local_flush_icache_range)(unsigned long start, unsigned long end);
 
 extern void (*__flush_cache_vmap)(void);
 
diff --git a/include/asm-parisc/sections.h b/include/asm-parisc/sections.h
index fdd43ec..9d13c35 100644
--- a/include/asm-parisc/sections.h
+++ b/include/asm-parisc/sections.h
@@ -4,4 +4,9 @@
 /* nothing to see, move along */
 #include <asm-generic/sections.h>
 
+#ifdef CONFIG_64BIT
+#undef dereference_function_descriptor
+void *dereference_function_descriptor(void *);
+#endif
+
 #endif
diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h
index 762f6a6..9489283 100644
--- a/include/asm-x86/cpufeature.h
+++ b/include/asm-x86/cpufeature.h
@@ -72,14 +72,15 @@
 #define X86_FEATURE_UP		(3*32+ 9) /* smp kernel running on up */
 #define X86_FEATURE_FXSAVE_LEAK (3*32+10) /* FXSAVE leaks FOP/FIP/FOP */
 #define X86_FEATURE_ARCH_PERFMON (3*32+11) /* Intel Architectural PerfMon */
-#define X86_FEATURE_PEBS	(3*32+12)  /* Precise-Event Based Sampling */
-#define X86_FEATURE_BTS		(3*32+13)  /* Branch Trace Store */
-#define X86_FEATURE_SYSCALL32	(3*32+14)  /* syscall in ia32 userspace */
-#define X86_FEATURE_SYSENTER32	(3*32+15)  /* sysenter in ia32 userspace */
+#define X86_FEATURE_PEBS	(3*32+12) /* Precise-Event Based Sampling */
+#define X86_FEATURE_BTS		(3*32+13) /* Branch Trace Store */
+#define X86_FEATURE_SYSCALL32	(3*32+14) /* syscall in ia32 userspace */
+#define X86_FEATURE_SYSENTER32	(3*32+15) /* sysenter in ia32 userspace */
 #define X86_FEATURE_REP_GOOD	(3*32+16) /* rep microcode works well on this CPU */
 #define X86_FEATURE_MFENCE_RDTSC (3*32+17) /* Mfence synchronizes RDTSC */
 #define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */
-#define X86_FEATURE_11AP	(3*32+19)  /* Bad local APIC aka 11AP */
+#define X86_FEATURE_11AP	(3*32+19) /* Bad local APIC aka 11AP */
+#define X86_FEATURE_NOPL	(3*32+20) /* The NOPL (0F 1F) instructions */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3	(4*32+ 0) /* Streaming SIMD Extensions-3 */
diff --git a/include/asm-x86/required-features.h b/include/asm-x86/required-features.h
index adec887..5c2ff4b 100644
--- a/include/asm-x86/required-features.h
+++ b/include/asm-x86/required-features.h
@@ -41,6 +41,12 @@
 # define NEED_3DNOW	0
 #endif
 
+#if defined(CONFIG_X86_P6_NOP) || defined(CONFIG_X86_64)
+# define NEED_NOPL	(1<<(X86_FEATURE_NOPL & 31))
+#else
+# define NEED_NOPL	0
+#endif
+
 #ifdef CONFIG_X86_64
 #define NEED_PSE	0
 #define NEED_MSR	(1<<(X86_FEATURE_MSR & 31))
@@ -67,7 +73,7 @@
 #define REQUIRED_MASK1	(NEED_LM|NEED_3DNOW)
 
 #define REQUIRED_MASK2	0
-#define REQUIRED_MASK3	0
+#define REQUIRED_MASK3	(NEED_NOPL)
 #define REQUIRED_MASK4	0
 #define REQUIRED_MASK5	0
 #define REQUIRED_MASK6	0
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 5939125..b68ec09 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -167,7 +167,8 @@
 unifdef-y += adb.h
 unifdef-y += adfs_fs.h
 unifdef-y += agpgart.h
-ifneq ($(wildcard $(srctree)/include/asm-$(SRCARCH)/a.out.h),)
+ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/a.out.h \
+      		  $(srctree)/include/asm-$(SRCARCH)/a.out.h),)
 unifdef-y += a.out.h
 endif
 unifdef-y += apm_bios.h
@@ -258,7 +259,8 @@
 unifdef-y += kernelcapi.h
 unifdef-y += kernel.h
 unifdef-y += keyboard.h
-ifneq ($(wildcard $(srctree)/include/asm-$(SRCARCH)/kvm.h),)
+ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm.h \
+      		  $(srctree)/include/asm-$(SRCARCH)/kvm.h),)
 unifdef-y += kvm.h
 endif
 unifdef-y += llc.h
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 1ce19c1..8a12d71 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -745,7 +745,7 @@
 static inline int lba_28_ok(u64 block, u32 n_block)
 {
 	/* check the ending block number */
-	return ((block + n_block - 1) < ((u64)1 << 28)) && (n_block <= 256);
+	return ((block + n_block) < ((u64)1 << 28)) && (n_block <= 256);
 }
 
 static inline int lba_48_ok(u64 block, u32 n_block)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 44710d7..53ea933 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -843,8 +843,6 @@
 */
 extern int blk_verify_command(struct blk_cmd_filter *filter,
 			      unsigned char *cmd, int has_write_perm);
-extern int blk_register_filter(struct gendisk *disk);
-extern void blk_unregister_filter(struct gendisk *disk);
 extern void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter);
 
 #define MAX_PHYS_SEGMENTS 128
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index c33b0dc..ed3a5d4 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -127,6 +127,8 @@
 extern int clockevents_program_event(struct clock_event_device *dev,
 				     ktime_t expires, ktime_t now);
 
+extern void clockevents_handle_noop(struct clock_event_device *dev);
+
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
 extern void clockevents_notify(unsigned long reason, void *arg);
 #else
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index e8f450c..2691926 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -160,7 +160,7 @@
 
 static inline void rebuild_sched_domains(void)
 {
-	partition_sched_domains(0, NULL, NULL);
+	partition_sched_domains(1, NULL, NULL);
 }
 
 #endif /* !CONFIG_CPUSETS */
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 8d3b7a9..350033e 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -159,9 +159,9 @@
 				struct resource *parent, resource_size_t start,
 				resource_size_t n, const char *name);
 
-#define devm_release_region(start,n) \
+#define devm_release_region(dev, start, n) \
 	__devm_release_region(dev, &ioport_resource, (start), (n))
-#define devm_release_mem_region(start,n) \
+#define devm_release_mem_region(dev, start, n) \
 	__devm_release_region(dev, &iomem_resource, (start), (n))
 
 extern void __devm_release_region(struct device *dev, struct resource *parent,
diff --git a/include/linux/lcd.h b/include/linux/lcd.h
index 173feba..c67feca 100644
--- a/include/linux/lcd.h
+++ b/include/linux/lcd.h
@@ -11,6 +11,7 @@
 #include <linux/device.h>
 #include <linux/mutex.h>
 #include <linux/notifier.h>
+#include <linux/fb.h>
 
 /* Notes on locking:
  *
@@ -45,6 +46,8 @@
 	int (*get_contrast)(struct lcd_device *);
 	/* Set LCD panel contrast */
         int (*set_contrast)(struct lcd_device *, int contrast);
+	/* Set LCD panel mode (resolutions ...) */
+	int (*set_mode)(struct lcd_device *, struct fb_videomode *);
 	/* Check if given framebuffer device is the one LCD is bound to;
 	   return 0 if not, !=0 if it is. If NULL, lcd always matches the fb. */
 	int (*check_fb)(struct lcd_device *, struct fb_info *);
diff --git a/include/linux/list.h b/include/linux/list.h
index db35ef0..969f6e9 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -619,6 +619,19 @@
 		next->next->pprev  = &next->next;
 }
 
+/*
+ * Move a list from one list head to another. Fixup the pprev
+ * reference of the first entry if it exists.
+ */
+static inline void hlist_move_list(struct hlist_head *old,
+				   struct hlist_head *new)
+{
+	new->first = old->first;
+	if (new->first)
+		new->first->pprev = &new->first;
+	old->first = NULL;
+}
+
 #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
 
 #define hlist_for_each(pos, head) \
diff --git a/include/linux/memstick.h b/include/linux/memstick.h
index a9f998a..d0c37e6 100644
--- a/include/linux/memstick.h
+++ b/include/linux/memstick.h
@@ -21,30 +21,30 @@
 struct ms_status_register {
 	unsigned char reserved;
 	unsigned char interrupt;
-#define MEMSTICK_INT_CMDNAK             0x0001
-#define MEMSTICK_INT_IOREQ              0x0008
-#define MEMSTICK_INT_IOBREQ             0x0010
-#define MEMSTICK_INT_BREQ               0x0020
-#define MEMSTICK_INT_ERR                0x0040
-#define MEMSTICK_INT_CED                0x0080
+#define MEMSTICK_INT_CMDNAK 0x01
+#define MEMSTICK_INT_IOREQ  0x08
+#define MEMSTICK_INT_IOBREQ 0x10
+#define MEMSTICK_INT_BREQ   0x20
+#define MEMSTICK_INT_ERR    0x40
+#define MEMSTICK_INT_CED    0x80
 
 	unsigned char status0;
-#define MEMSTICK_STATUS0_WP             0x0001
-#define MEMSTICK_STATUS0_SL             0x0002
-#define MEMSTICK_STATUS0_BF             0x0010
-#define MEMSTICK_STATUS0_BE             0x0020
-#define MEMSTICK_STATUS0_FB0            0x0040
-#define MEMSTICK_STATUS0_MB             0x0080
+#define MEMSTICK_STATUS0_WP  0x01
+#define MEMSTICK_STATUS0_SL  0x02
+#define MEMSTICK_STATUS0_BF  0x10
+#define MEMSTICK_STATUS0_BE  0x20
+#define MEMSTICK_STATUS0_FB0 0x40
+#define MEMSTICK_STATUS0_MB  0x80
 
 	unsigned char status1;
-#define MEMSTICK_STATUS1_UCFG           0x0001
-#define MEMSTICK_STATUS1_FGER           0x0002
-#define MEMSTICK_STATUS1_UCEX           0x0004
-#define MEMSTICK_STATUS1_EXER           0x0008
-#define MEMSTICK_STATUS1_UCDT           0x0010
-#define MEMSTICK_STATUS1_DTER           0x0020
-#define MEMSTICK_STATUS1_FBI            0x0040
-#define MEMSTICK_STATUS1_MB             0x0080
+#define MEMSTICK_STATUS1_UCFG 0x01
+#define MEMSTICK_STATUS1_FGER 0x02
+#define MEMSTICK_STATUS1_UCEX 0x04
+#define MEMSTICK_STATUS1_EXER 0x08
+#define MEMSTICK_STATUS1_UCDT 0x10
+#define MEMSTICK_STATUS1_DTER 0x20
+#define MEMSTICK_STATUS1_FB1  0x40
+#define MEMSTICK_STATUS1_MB   0x80
 } __attribute__((packed));
 
 struct ms_id_register {
@@ -56,32 +56,32 @@
 
 struct ms_param_register {
 	unsigned char system;
-#define MEMSTICK_SYS_ATEN 0xc0
-#define MEMSTICK_SYS_BAMD 0x80
 #define MEMSTICK_SYS_PAM  0x08
+#define MEMSTICK_SYS_BAMD 0x80
 
 	unsigned char block_address_msb;
 	unsigned short block_address;
 	unsigned char cp;
-#define MEMSTICK_CP_BLOCK               0x0000
-#define MEMSTICK_CP_PAGE                0x0020
-#define MEMSTICK_CP_EXTRA               0x0040
-#define MEMSTICK_CP_OVERWRITE           0x0080
+#define MEMSTICK_CP_BLOCK     0x00
+#define MEMSTICK_CP_PAGE      0x20
+#define MEMSTICK_CP_EXTRA     0x40
+#define MEMSTICK_CP_OVERWRITE 0x80
 
 	unsigned char page_address;
 } __attribute__((packed));
 
 struct ms_extra_data_register {
 	unsigned char  overwrite_flag;
-#define MEMSTICK_OVERWRITE_UPDATA       0x0010
-#define MEMSTICK_OVERWRITE_PAGE         0x0060
-#define MEMSTICK_OVERWRITE_BLOCK        0x0080
+#define MEMSTICK_OVERWRITE_UDST  0x10
+#define MEMSTICK_OVERWRITE_PGST1 0x20
+#define MEMSTICK_OVERWRITE_PGST0 0x40
+#define MEMSTICK_OVERWRITE_BKST  0x80
 
 	unsigned char  management_flag;
-#define MEMSTICK_MANAGEMENT_SYSTEM      0x0004
-#define MEMSTICK_MANAGEMENT_TRANS_TABLE 0x0008
-#define MEMSTICK_MANAGEMENT_COPY        0x0010
-#define MEMSTICK_MANAGEMENT_ACCESS      0x0020
+#define MEMSTICK_MANAGEMENT_SYSFLG 0x04
+#define MEMSTICK_MANAGEMENT_ATFLG  0x08
+#define MEMSTICK_MANAGEMENT_SCMS1  0x10
+#define MEMSTICK_MANAGEMENT_SCMS0  0x20
 
 	unsigned short logical_address;
 } __attribute__((packed));
@@ -96,9 +96,9 @@
 
 struct mspro_param_register {
 	unsigned char  system;
-#define MEMSTICK_SYS_SERIAL 0x80
 #define MEMSTICK_SYS_PAR4   0x00
 #define MEMSTICK_SYS_PAR8   0x40
+#define MEMSTICK_SYS_SERIAL 0x80
 
 	unsigned short data_count;
 	unsigned int   data_address;
@@ -147,7 +147,7 @@
 	unsigned char w_length;
 } __attribute__((packed));
 
-enum {
+enum memstick_tpc {
 	MS_TPC_READ_MG_STATUS   = 0x01,
 	MS_TPC_READ_LONG_DATA   = 0x02,
 	MS_TPC_READ_SHORT_DATA  = 0x03,
@@ -167,7 +167,7 @@
 	MS_TPC_SET_CMD          = 0x0e
 };
 
-enum {
+enum memstick_command {
 	MS_CMD_BLOCK_END       = 0x33,
 	MS_CMD_RESET           = 0x3c,
 	MS_CMD_BLOCK_WRITE     = 0x55,
@@ -201,8 +201,6 @@
 
 /*** Driver structures and functions ***/
 
-#define MEMSTICK_PART_SHIFT 3
-
 enum memstick_param { MEMSTICK_POWER = 1, MEMSTICK_INTERFACE };
 
 #define MEMSTICK_POWER_OFF 0
@@ -215,24 +213,27 @@
 struct memstick_host;
 struct memstick_driver;
 
+struct memstick_device_id {
+	unsigned char match_flags;
 #define MEMSTICK_MATCH_ALL            0x01
 
+	unsigned char type;
 #define MEMSTICK_TYPE_LEGACY          0xff
 #define MEMSTICK_TYPE_DUO             0x00
 #define MEMSTICK_TYPE_PRO             0x01
 
+	unsigned char category;
 #define MEMSTICK_CATEGORY_STORAGE     0xff
 #define MEMSTICK_CATEGORY_STORAGE_DUO 0x00
+#define MEMSTICK_CATEGORY_IO          0x01
+#define MEMSTICK_CATEGORY_IO_PRO      0x10
 
-#define MEMSTICK_CLASS_GENERIC        0xff
-#define MEMSTICK_CLASS_GENERIC_DUO    0x00
-
-
-struct memstick_device_id {
-	unsigned char match_flags;
-	unsigned char type;
-	unsigned char category;
 	unsigned char class;
+#define MEMSTICK_CLASS_FLASH          0xff
+#define MEMSTICK_CLASS_DUO            0x00
+#define MEMSTICK_CLASS_ROM            0x01
+#define MEMSTICK_CLASS_RO             0x02
+#define MEMSTICK_CLASS_WP             0x03
 };
 
 struct memstick_request {
@@ -319,9 +320,9 @@
 void memstick_resume_host(struct memstick_host *host);
 
 void memstick_init_req_sg(struct memstick_request *mrq, unsigned char tpc,
-			  struct scatterlist *sg);
+			  const struct scatterlist *sg);
 void memstick_init_req(struct memstick_request *mrq, unsigned char tpc,
-		       void *buf, size_t length);
+		       const void *buf, size_t length);
 int memstick_next_req(struct memstick_host *host,
 		      struct memstick_request **mrq);
 void memstick_new_req(struct memstick_host *host);
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 443bc7c..428328a 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -751,8 +751,9 @@
  *
  * This function returns the next zone at or below a given zone index that is
  * within the allowed nodemask using a cursor as the starting point for the
- * search. The zoneref returned is a cursor that is used as the next starting
- * point for future calls to next_zones_zonelist().
+ * search. The zoneref returned is a cursor that represents the current zone
+ * being examined. It should be advanced by one before calling
+ * next_zones_zonelist again.
  */
 struct zoneref *next_zones_zonelist(struct zoneref *z,
 					enum zone_type highest_zoneidx,
@@ -768,9 +769,8 @@
  *
  * This function returns the first zone at or below a given zone index that is
  * within the allowed nodemask. The zoneref returned is a cursor that can be
- * used to iterate the zonelist with next_zones_zonelist. The cursor should
- * not be used by the caller as it does not match the value of the zone
- * returned.
+ * used to iterate the zonelist with next_zones_zonelist by advancing it by
+ * one before calling.
  */
 static inline struct zoneref *first_zones_zonelist(struct zonelist *zonelist,
 					enum zone_type highest_zoneidx,
@@ -795,7 +795,7 @@
 #define for_each_zone_zonelist_nodemask(zone, z, zlist, highidx, nodemask) \
 	for (z = first_zones_zonelist(zlist, highidx, nodemask, &zone);	\
 		zone;							\
-		z = next_zones_zonelist(z, highidx, nodemask, &zone))	\
+		z = next_zones_zonelist(++z, highidx, nodemask, &zone))	\
 
 /**
  * for_each_zone_zonelist - helper macro to iterate over valid zones in a zonelist at or below a given zone index
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index 1ce54b6..be764e5 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -21,7 +21,14 @@
 /*
  * Resource Management
  */
+#ifdef CONFIG_PNP
 struct resource *pnp_get_resource(struct pnp_dev *, unsigned int, unsigned int);
+#else
+static inline struct resource *pnp_get_resource(struct pnp_dev *dev, unsigned int type, unsigned int num)
+{
+	return NULL;
+}
+#endif
 
 static inline int pnp_resource_valid(struct resource *res)
 {
diff --git a/include/linux/res_counter.h b/include/linux/res_counter.h
index fdeadd9..271c1c2 100644
--- a/include/linux/res_counter.h
+++ b/include/linux/res_counter.h
@@ -166,7 +166,7 @@
 	int ret = -EBUSY;
 
 	spin_lock_irqsave(&cnt->lock, flags);
-	if (cnt->usage < limit) {
+	if (cnt->usage <= limit) {
 		cnt->limit = limit;
 		ret = 0;
 	}
diff --git a/include/linux/sched.h b/include/linux/sched.h
index cfb0d87..3d9120c 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1475,6 +1475,10 @@
 		__put_task_struct(t);
 }
 
+extern cputime_t task_utime(struct task_struct *p);
+extern cputime_t task_stime(struct task_struct *p);
+extern cputime_t task_gtime(struct task_struct *p);
+
 /*
  * Per process flags
  */
diff --git a/include/linux/smc91x.h b/include/linux/smc91x.h
index 3827b92..bc21db5 100644
--- a/include/linux/smc91x.h
+++ b/include/linux/smc91x.h
@@ -16,8 +16,19 @@
 
 #define SMC91X_USE_DMA		(1 << 6)
 
+#define RPC_LED_100_10	(0x00)	/* LED = 100Mbps OR's with 10Mbps link detect */
+#define RPC_LED_RES	(0x01)	/* LED = Reserved */
+#define RPC_LED_10	(0x02)	/* LED = 10Mbps link detect */
+#define RPC_LED_FD	(0x03)	/* LED = Full Duplex Mode */
+#define RPC_LED_TX_RX	(0x04)	/* LED = TX or RX packet occurred */
+#define RPC_LED_100	(0x05)	/* LED = 100Mbps link dectect */
+#define RPC_LED_TX	(0x06)	/* LED = TX packet occurred */
+#define RPC_LED_RX	(0x07)	/* LED = RX packet occurred */
+
 struct smc91x_platdata {
 	unsigned long flags;
+	unsigned char leda;
+	unsigned char ledb;
 };
 
 #endif /* __SMC91X_H__ */
diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h
index daf7440..05eab2f 100644
--- a/include/linux/spi/ads7846.h
+++ b/include/linux/spi/ads7846.h
@@ -43,6 +43,9 @@
 	u16	debounce_tol;		/* tolerance used for filtering */
 	u16	debounce_rep;		/* additional consecutive good readings
 					 * required after the first two */
+	int	gpio_pendown;		/* the GPIO used to decide the pendown
+					 * state if get_pendown_state == NULL
+					 */
 	int	(*get_pendown_state)(void);
 	int	(*filter_init)	(struct ads7846_platform_data *pdata,
 				 void **filter_data);
diff --git a/include/linux/spi/corgi_lcd.h b/include/linux/spi/corgi_lcd.h
new file mode 100644
index 0000000..6692b34
--- /dev/null
+++ b/include/linux/spi/corgi_lcd.h
@@ -0,0 +1,20 @@
+#ifndef __LINUX_SPI_CORGI_LCD_H
+#define __LINUX_SPI_CORGI_LCD_H
+
+#define CORGI_LCD_MODE_QVGA	1
+#define CORGI_LCD_MODE_VGA	2
+
+struct corgi_lcd_platform_data {
+	int	init_mode;
+	int	max_intensity;
+	int	default_intensity;
+	int	limit_mask;
+
+	int	gpio_backlight_on;	/* -1 if n/a */
+	int	gpio_backlight_cont;	/* -1 if n/a */
+
+	void (*notify)(int intensity);
+	void (*kick_battery)(void);
+};
+
+#endif /* __LINUX_SPI_CORGI_LCD_H */
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
index b48d819..6186a78 100644
--- a/include/linux/tracehook.h
+++ b/include/linux/tracehook.h
@@ -272,7 +272,7 @@
  * tracehook_report_clone_complete().  This must prevent the child from
  * self-reaping if tracehook_report_clone_complete() uses the @child
  * pointer; otherwise it might have died and been released by the time
- * tracehook_report_report_clone_complete() is called.
+ * tracehook_report_clone_complete() is called.
  *
  * Called with no locks held, but the child cannot run until this returns.
  */
diff --git a/include/linux/ucb1400.h b/include/linux/ucb1400.h
new file mode 100644
index 0000000..970473b
--- /dev/null
+++ b/include/linux/ucb1400.h
@@ -0,0 +1,161 @@
+/*
+ * Register definitions and functions for:
+ *  Philips UCB1400 driver
+ *
+ * Based on ucb1400_ts:
+ *  Author:	Nicolas Pitre
+ *  Created:	September 25, 2006
+ *  Copyright:	MontaVista Software, Inc.
+ *
+ * Spliting done by: Marek Vasut <marek.vasut@gmail.com>
+ * If something doesnt work and it worked before spliting, e-mail me,
+ * dont bother Nicolas please ;-)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This code is heavily based on ucb1x00-*.c copyrighted by Russell King
+ * covering the UCB1100, UCB1200 and UCB1300..  Support for the UCB1400 has
+ * been made separate from ucb1x00-core/ucb1x00-ts on Russell's request.
+ */
+
+#ifndef _LINUX__UCB1400_H
+#define _LINUX__UCB1400_H
+
+#include <sound/ac97_codec.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+
+/*
+ * UCB1400 AC-link registers
+ */
+
+#define UCB_IO_DATA		0x5a
+#define UCB_IO_DIR		0x5c
+#define UCB_IE_RIS		0x5e
+#define UCB_IE_FAL		0x60
+#define UCB_IE_STATUS		0x62
+#define UCB_IE_CLEAR		0x62
+#define UCB_IE_ADC		(1 << 11)
+#define UCB_IE_TSPX		(1 << 12)
+
+#define UCB_TS_CR		0x64
+#define UCB_TS_CR_TSMX_POW	(1 << 0)
+#define UCB_TS_CR_TSPX_POW	(1 << 1)
+#define UCB_TS_CR_TSMY_POW	(1 << 2)
+#define UCB_TS_CR_TSPY_POW	(1 << 3)
+#define UCB_TS_CR_TSMX_GND	(1 << 4)
+#define UCB_TS_CR_TSPX_GND	(1 << 5)
+#define UCB_TS_CR_TSMY_GND	(1 << 6)
+#define UCB_TS_CR_TSPY_GND	(1 << 7)
+#define UCB_TS_CR_MODE_INT	(0 << 8)
+#define UCB_TS_CR_MODE_PRES	(1 << 8)
+#define UCB_TS_CR_MODE_POS	(2 << 8)
+#define UCB_TS_CR_BIAS_ENA	(1 << 11)
+#define UCB_TS_CR_TSPX_LOW	(1 << 12)
+#define UCB_TS_CR_TSMX_LOW	(1 << 13)
+
+#define UCB_ADC_CR		0x66
+#define UCB_ADC_SYNC_ENA	(1 << 0)
+#define UCB_ADC_VREFBYP_CON	(1 << 1)
+#define UCB_ADC_INP_TSPX	(0 << 2)
+#define UCB_ADC_INP_TSMX	(1 << 2)
+#define UCB_ADC_INP_TSPY	(2 << 2)
+#define UCB_ADC_INP_TSMY	(3 << 2)
+#define UCB_ADC_INP_AD0		(4 << 2)
+#define UCB_ADC_INP_AD1		(5 << 2)
+#define UCB_ADC_INP_AD2		(6 << 2)
+#define UCB_ADC_INP_AD3		(7 << 2)
+#define UCB_ADC_EXT_REF		(1 << 5)
+#define UCB_ADC_START		(1 << 7)
+#define UCB_ADC_ENA		(1 << 15)
+
+#define UCB_ADC_DATA		0x68
+#define UCB_ADC_DAT_VALID	(1 << 15)
+#define UCB_ADC_DAT_MASK	0x3ff
+
+#define UCB_ID			0x7e
+#define UCB_ID_1400             0x4304
+
+struct ucb1400_ts {
+	struct input_dev	*ts_idev;
+	struct task_struct	*ts_task;
+	int			id;
+	wait_queue_head_t	ts_wait;
+	unsigned int		ts_restart:1;
+	int			irq;
+	unsigned int		irq_pending;	/* not bit field shared */
+	struct snd_ac97		*ac97;
+};
+
+struct ucb1400 {
+	struct platform_device	*ucb1400_ts;
+};
+
+static inline u16 ucb1400_reg_read(struct snd_ac97 *ac97, u16 reg)
+{
+	return ac97->bus->ops->read(ac97, reg);
+}
+
+static inline void ucb1400_reg_write(struct snd_ac97 *ac97, u16 reg, u16 val)
+{
+	ac97->bus->ops->write(ac97, reg, val);
+}
+
+static inline u16 ucb1400_gpio_get_value(struct snd_ac97 *ac97, u16 gpio)
+{
+	return ucb1400_reg_read(ac97, UCB_IO_DATA) & (1 << gpio);
+}
+
+static inline void ucb1400_gpio_set_value(struct snd_ac97 *ac97, u16 gpio,
+						u16 val)
+{
+	ucb1400_reg_write(ac97, UCB_IO_DATA, val ?
+			ucb1400_reg_read(ac97, UCB_IO_DATA) | (1 << gpio) :
+			ucb1400_reg_read(ac97, UCB_IO_DATA) & ~(1 << gpio));
+}
+
+static inline u16 ucb1400_gpio_get_direction(struct snd_ac97 *ac97, u16 gpio)
+{
+	return ucb1400_reg_read(ac97, UCB_IO_DIR) & (1 << gpio);
+}
+
+static inline void ucb1400_gpio_set_direction(struct snd_ac97 *ac97, u16 gpio,
+						u16 dir)
+{
+	ucb1400_reg_write(ac97, UCB_IO_DIR, dir ?
+			ucb1400_reg_read(ac97, UCB_IO_DIR) | (1 << gpio) :
+			ucb1400_reg_read(ac97, UCB_IO_DIR) & ~(1 << gpio));
+}
+
+static inline void ucb1400_adc_enable(struct snd_ac97 *ac97)
+{
+	ucb1400_reg_write(ac97, UCB_ADC_CR, UCB_ADC_ENA);
+}
+
+static unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel,
+					int adcsync)
+{
+	unsigned int val;
+
+	if (adcsync)
+		adc_channel |= UCB_ADC_SYNC_ENA;
+
+	ucb1400_reg_write(ac97, UCB_ADC_CR, UCB_ADC_ENA | adc_channel);
+	ucb1400_reg_write(ac97, UCB_ADC_CR, UCB_ADC_ENA | adc_channel |
+				UCB_ADC_START);
+
+	while (!((val = ucb1400_reg_read(ac97, UCB_ADC_DATA))
+			& UCB_ADC_DAT_VALID))
+		schedule_timeout_uninterruptible(1);
+
+	return val & UCB_ADC_DAT_MASK;
+}
+
+static inline void ucb1400_adc_disable(struct snd_ac97 *ac97)
+{
+	ucb1400_reg_write(ac97, UCB_ADC_CR, 0);
+}
+
+#endif
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index e65a6bed..303d93f 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -334,6 +334,8 @@
 #define V4L2_PIX_FMT_SPCA508  v4l2_fourcc('S', '5', '0', '8') /* YUVY per line */
 #define V4L2_PIX_FMT_SPCA561  v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */
 #define V4L2_PIX_FMT_PAC207   v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */
+#define V4L2_PIX_FMT_PJPG     v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */
+#define V4L2_PIX_FMT_YVYU    v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16  YVU 4:2:2     */
 
 /*
  *	F O R M A T   E N U M E R A T I O N
diff --git a/include/linux/wm97xx_batt.h b/include/linux/wm97xx_batt.h
new file mode 100644
index 0000000..9681d1a
--- /dev/null
+++ b/include/linux/wm97xx_batt.h
@@ -0,0 +1,26 @@
+#ifndef _LINUX_WM97XX_BAT_H
+#define _LINUX_WM97XX_BAT_H
+
+#include <linux/wm97xx.h>
+
+struct wm97xx_batt_info {
+	int	batt_aux;
+	int	temp_aux;
+	int	charge_gpio;
+	int	min_voltage;
+	int	max_voltage;
+	int	batt_div;
+	int	batt_mult;
+	int	temp_div;
+	int	temp_mult;
+	int	batt_tech;
+	char	*batt_name;
+};
+
+#ifdef CONFIG_BATTERY_WM97XX
+void __init wm97xx_bat_set_pdata(struct wm97xx_batt_info *data);
+#else
+static inline void wm97xx_bat_set_pdata(struct wm97xx_batt_info *data) {}
+#endif
+
+#endif
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index cbf7510..46a43b7 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -325,7 +325,8 @@
 void hci_conn_hash_flush(struct hci_dev *hdev);
 void hci_conn_check_pending(struct hci_dev *hdev);
 
-struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *src);
+struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 auth_type);
+int hci_conn_check_link_mode(struct hci_conn *conn);
 int hci_conn_auth(struct hci_conn *conn);
 int hci_conn_encrypt(struct hci_conn *conn);
 int hci_conn_change_link_key(struct hci_conn *conn);
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index 95c660c..9132490 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -208,6 +208,9 @@
 extern void inet_twsk_deschedule(struct inet_timewait_sock *tw,
 				 struct inet_timewait_death_row *twdr);
 
+extern void inet_twsk_purge(struct net *net, struct inet_hashinfo *hashinfo,
+			    struct inet_timewait_death_row *twdr, int family);
+
 static inline
 struct net *twsk_net(const struct inet_timewait_sock *twsk)
 {
diff --git a/include/net/netlink.h b/include/net/netlink.h
index 18024b8..208fe5a 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -702,7 +702,7 @@
  */
 static inline int nla_ok(const struct nlattr *nla, int remaining)
 {
-	return remaining >= sizeof(*nla) &&
+	return remaining >= (int) sizeof(*nla) &&
 	       nla->nla_len >= sizeof(*nla) &&
 	       nla->nla_len <= remaining;
 }
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index 5c40cc5..192f871 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -309,6 +309,20 @@
 };
 
 /*
+ * The Well Known LUNS (SAM-3) in our int representation of a LUN
+ */
+#define SCSI_W_LUN_BASE 0xc100
+#define SCSI_W_LUN_REPORT_LUNS (SCSI_W_LUN_BASE + 1)
+#define SCSI_W_LUN_ACCESS_CONTROL (SCSI_W_LUN_BASE + 2)
+#define SCSI_W_LUN_TARGET_LOG_PAGE (SCSI_W_LUN_BASE + 3)
+
+static inline int scsi_is_wlun(unsigned int lun)
+{
+	return (lun & 0xff00) == SCSI_W_LUN_BASE;
+}
+
+
+/*
  *  MESSAGE CODES
  */
 
diff --git a/include/video/atmel_lcdc.h b/include/video/atmel_lcdc.h
index 920c4e9..6ad87f4 100644
--- a/include/video/atmel_lcdc.h
+++ b/include/video/atmel_lcdc.h
@@ -30,6 +30,7 @@
  */
 #define ATMEL_LCDC_WIRING_BGR	0
 #define ATMEL_LCDC_WIRING_RGB	1
+#define ATMEL_LCDC_WIRING_RGB555	2
 
 
  /* LCD Controller info data structure, stored in device platform_data */
diff --git a/include/video/metronomefb.h b/include/video/metronomefb.h
index dab04b4..9863f4b 100644
--- a/include/video/metronomefb.h
+++ b/include/video/metronomefb.h
@@ -12,14 +12,6 @@
 #ifndef _LINUX_METRONOMEFB_H_
 #define _LINUX_METRONOMEFB_H_
 
-/* address and control descriptors used by metronome controller */
-struct metromem_desc {
-	u32 mFDADR0;
-	u32 mFSADR0;
-	u32 mFIDR0;
-	u32 mLDCMD0;
-};
-
 /* command structure used by metronome controller */
 struct metromem_cmd {
 	u16 opcode;
@@ -29,34 +21,37 @@
 
 /* struct used by metronome. board specific stuff comes from *board */
 struct metronomefb_par {
-	unsigned char *metromem;
-	struct metromem_desc *metromem_desc;
 	struct metromem_cmd *metromem_cmd;
 	unsigned char *metromem_wfm;
 	unsigned char *metromem_img;
 	u16 *metromem_img_csum;
 	u16 *csum_table;
-	int metromemsize;
 	dma_addr_t metromem_dma;
-	dma_addr_t metromem_desc_dma;
 	struct fb_info *info;
 	struct metronome_board *board;
 	wait_queue_head_t waitq;
 	u8 frame_count;
+	int extra_size;
+	int dt;
 };
 
-/* board specific routines */
+/* board specific routines and data */
 struct metronome_board {
-	struct module *owner;
-	void (*free_irq)(struct fb_info *);
-	void (*init_gpio_regs)(struct metronomefb_par *);
-	void (*init_lcdc_regs)(struct metronomefb_par *);
-	void (*post_dma_setup)(struct metronomefb_par *);
+	struct module *owner; /* the platform device */
 	void (*set_rst)(struct metronomefb_par *, int);
 	void (*set_stdby)(struct metronomefb_par *, int);
+	void (*cleanup)(struct metronomefb_par *);
 	int (*met_wait_event)(struct metronomefb_par *);
 	int (*met_wait_event_intr)(struct metronomefb_par *);
 	int (*setup_irq)(struct fb_info *);
+	int (*setup_fb)(struct metronomefb_par *);
+	int (*setup_io)(struct metronomefb_par *);
+	int (*get_panel_type)(void);
+	unsigned char *metromem;
+	int fw;
+	int fh;
+	int wfm_size;
+	struct fb_info *host_fbinfo; /* the host LCD controller's fbi */
 };
 
 #endif
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index d5ab79c..827cd9ad 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -14,6 +14,8 @@
  *  2003-10-22 Updates by Stephen Hemminger.
  *  2004 May-July Rework by Paul Jackson.
  *  2006 Rework by Paul Menage to use generic cgroups
+ *  2008 Rework of the scheduler domains and CPU hotplug handling
+ *       by Max Krasnyansky
  *
  *  This file is subject to the terms and conditions of the GNU General Public
  *  License.  See the file COPYING in the main directory of the Linux
@@ -236,9 +238,11 @@
 
 static DEFINE_MUTEX(callback_mutex);
 
-/* This is ugly, but preserves the userspace API for existing cpuset
+/*
+ * This is ugly, but preserves the userspace API for existing cpuset
  * users. If someone tries to mount the "cpuset" filesystem, we
- * silently switch it to mount "cgroup" instead */
+ * silently switch it to mount "cgroup" instead
+ */
 static int cpuset_get_sb(struct file_system_type *fs_type,
 			 int flags, const char *unused_dev_name,
 			 void *data, struct vfsmount *mnt)
@@ -473,10 +477,9 @@
 }
 
 /*
- * Helper routine for rebuild_sched_domains().
+ * Helper routine for generate_sched_domains().
  * Do cpusets a, b have overlapping cpus_allowed masks?
  */
-
 static int cpusets_overlap(struct cpuset *a, struct cpuset *b)
 {
 	return cpus_intersects(a->cpus_allowed, b->cpus_allowed);
@@ -518,26 +521,15 @@
 }
 
 /*
- * rebuild_sched_domains()
+ * generate_sched_domains()
  *
- * This routine will be called to rebuild the scheduler's dynamic
- * sched domains:
- * - if the flag 'sched_load_balance' of any cpuset with non-empty
- *   'cpus' changes,
- * - or if the 'cpus' allowed changes in any cpuset which has that
- *   flag enabled,
- * - or if the 'sched_relax_domain_level' of any cpuset which has
- *   that flag enabled and with non-empty 'cpus' changes,
- * - or if any cpuset with non-empty 'cpus' is removed,
- * - or if a cpu gets offlined.
- *
- * This routine builds a partial partition of the systems CPUs
- * (the set of non-overlappping cpumask_t's in the array 'part'
- * below), and passes that partial partition to the kernel/sched.c
- * partition_sched_domains() routine, which will rebuild the
- * schedulers load balancing domains (sched domains) as specified
- * by that partial partition.  A 'partial partition' is a set of
- * non-overlapping subsets whose union is a subset of that set.
+ * This function builds a partial partition of the systems CPUs
+ * A 'partial partition' is a set of non-overlapping subsets whose
+ * union is a subset of that set.
+ * The output of this function needs to be passed to kernel/sched.c
+ * partition_sched_domains() routine, which will rebuild the scheduler's
+ * load balancing domains (sched domains) as specified by that partial
+ * partition.
  *
  * See "What is sched_load_balance" in Documentation/cpusets.txt
  * for a background explanation of this.
@@ -547,13 +539,7 @@
  * domains when operating in the severe memory shortage situations
  * that could cause allocation failures below.
  *
- * Call with cgroup_mutex held.  May take callback_mutex during
- * call due to the kfifo_alloc() and kmalloc() calls.  May nest
- * a call to the get_online_cpus()/put_online_cpus() pair.
- * Must not be called holding callback_mutex, because we must not
- * call get_online_cpus() while holding callback_mutex.  Elsewhere
- * the kernel nests callback_mutex inside get_online_cpus() calls.
- * So the reverse nesting would risk an ABBA deadlock.
+ * Must be called with cgroup_lock held.
  *
  * The three key local variables below are:
  *    q  - a linked-list queue of cpuset pointers, used to implement a
@@ -588,10 +574,10 @@
  *	element of the partition (one sched domain) to be passed to
  *	partition_sched_domains().
  */
-
-void rebuild_sched_domains(void)
+static int generate_sched_domains(cpumask_t **domains,
+			struct sched_domain_attr **attributes)
 {
-	LIST_HEAD(q);		/* queue of cpusets to be scanned*/
+	LIST_HEAD(q);		/* queue of cpusets to be scanned */
 	struct cpuset *cp;	/* scans q */
 	struct cpuset **csa;	/* array of all cpuset ptrs */
 	int csn;		/* how many cpuset ptrs in csa so far */
@@ -601,23 +587,26 @@
 	int ndoms;		/* number of sched domains in result */
 	int nslot;		/* next empty doms[] cpumask_t slot */
 
-	csa = NULL;
+	ndoms = 0;
 	doms = NULL;
 	dattr = NULL;
+	csa = NULL;
 
 	/* Special case for the 99% of systems with one, full, sched domain */
 	if (is_sched_load_balance(&top_cpuset)) {
-		ndoms = 1;
 		doms = kmalloc(sizeof(cpumask_t), GFP_KERNEL);
 		if (!doms)
-			goto rebuild;
+			goto done;
+
 		dattr = kmalloc(sizeof(struct sched_domain_attr), GFP_KERNEL);
 		if (dattr) {
 			*dattr = SD_ATTR_INIT;
 			update_domain_attr_tree(dattr, &top_cpuset);
 		}
 		*doms = top_cpuset.cpus_allowed;
-		goto rebuild;
+
+		ndoms = 1;
+		goto done;
 	}
 
 	csa = kmalloc(number_of_cpusets * sizeof(cp), GFP_KERNEL);
@@ -680,61 +669,141 @@
 		}
 	}
 
-	/* Convert <csn, csa> to <ndoms, doms> */
+	/*
+	 * Now we know how many domains to create.
+	 * Convert <csn, csa> to <ndoms, doms> and populate cpu masks.
+	 */
 	doms = kmalloc(ndoms * sizeof(cpumask_t), GFP_KERNEL);
-	if (!doms)
-		goto rebuild;
+	if (!doms) {
+		ndoms = 0;
+		goto done;
+	}
+
+	/*
+	 * The rest of the code, including the scheduler, can deal with
+	 * dattr==NULL case. No need to abort if alloc fails.
+	 */
 	dattr = kmalloc(ndoms * sizeof(struct sched_domain_attr), GFP_KERNEL);
 
 	for (nslot = 0, i = 0; i < csn; i++) {
 		struct cpuset *a = csa[i];
+		cpumask_t *dp;
 		int apn = a->pn;
 
-		if (apn >= 0) {
-			cpumask_t *dp = doms + nslot;
-
-			if (nslot == ndoms) {
-				static int warnings = 10;
-				if (warnings) {
-					printk(KERN_WARNING
-					 "rebuild_sched_domains confused:"
-					  " nslot %d, ndoms %d, csn %d, i %d,"
-					  " apn %d\n",
-					  nslot, ndoms, csn, i, apn);
-					warnings--;
-				}
-				continue;
-			}
-
-			cpus_clear(*dp);
-			if (dattr)
-				*(dattr + nslot) = SD_ATTR_INIT;
-			for (j = i; j < csn; j++) {
-				struct cpuset *b = csa[j];
-
-				if (apn == b->pn) {
-					cpus_or(*dp, *dp, b->cpus_allowed);
-					b->pn = -1;
-					if (dattr)
-						update_domain_attr_tree(dattr
-								   + nslot, b);
-				}
-			}
-			nslot++;
+		if (apn < 0) {
+			/* Skip completed partitions */
+			continue;
 		}
+
+		dp = doms + nslot;
+
+		if (nslot == ndoms) {
+			static int warnings = 10;
+			if (warnings) {
+				printk(KERN_WARNING
+				 "rebuild_sched_domains confused:"
+				  " nslot %d, ndoms %d, csn %d, i %d,"
+				  " apn %d\n",
+				  nslot, ndoms, csn, i, apn);
+				warnings--;
+			}
+			continue;
+		}
+
+		cpus_clear(*dp);
+		if (dattr)
+			*(dattr + nslot) = SD_ATTR_INIT;
+		for (j = i; j < csn; j++) {
+			struct cpuset *b = csa[j];
+
+			if (apn == b->pn) {
+				cpus_or(*dp, *dp, b->cpus_allowed);
+				if (dattr)
+					update_domain_attr_tree(dattr + nslot, b);
+
+				/* Done with this partition */
+				b->pn = -1;
+			}
+		}
+		nslot++;
 	}
 	BUG_ON(nslot != ndoms);
 
-rebuild:
-	/* Have scheduler rebuild sched domains */
-	get_online_cpus();
-	partition_sched_domains(ndoms, doms, dattr);
-	put_online_cpus();
-
 done:
 	kfree(csa);
-	/* Don't kfree(doms) -- partition_sched_domains() does that. */
-	/* Don't kfree(dattr) -- partition_sched_domains() does that. */
+
+	*domains    = doms;
+	*attributes = dattr;
+	return ndoms;
+}
+
+/*
+ * Rebuild scheduler domains.
+ *
+ * Call with neither cgroup_mutex held nor within get_online_cpus().
+ * Takes both cgroup_mutex and get_online_cpus().
+ *
+ * Cannot be directly called from cpuset code handling changes
+ * to the cpuset pseudo-filesystem, because it cannot be called
+ * from code that already holds cgroup_mutex.
+ */
+static void do_rebuild_sched_domains(struct work_struct *unused)
+{
+	struct sched_domain_attr *attr;
+	cpumask_t *doms;
+	int ndoms;
+
+	get_online_cpus();
+
+	/* Generate domain masks and attrs */
+	cgroup_lock();
+	ndoms = generate_sched_domains(&doms, &attr);
+	cgroup_unlock();
+
+	/* Have scheduler rebuild the domains */
+	partition_sched_domains(ndoms, doms, attr);
+
+	put_online_cpus();
+}
+
+static DECLARE_WORK(rebuild_sched_domains_work, do_rebuild_sched_domains);
+
+/*
+ * Rebuild scheduler domains, asynchronously via workqueue.
+ *
+ * If the flag 'sched_load_balance' of any cpuset with non-empty
+ * 'cpus' changes, or if the 'cpus' allowed changes in any cpuset
+ * which has that flag enabled, or if any cpuset with a non-empty
+ * 'cpus' is removed, then call this routine to rebuild the
+ * scheduler's dynamic sched domains.
+ *
+ * The rebuild_sched_domains() and partition_sched_domains()
+ * routines must nest cgroup_lock() inside get_online_cpus(),
+ * but such cpuset changes as these must nest that locking the
+ * other way, holding cgroup_lock() for much of the code.
+ *
+ * So in order to avoid an ABBA deadlock, the cpuset code handling
+ * these user changes delegates the actual sched domain rebuilding
+ * to a separate workqueue thread, which ends up processing the
+ * above do_rebuild_sched_domains() function.
+ */
+static void async_rebuild_sched_domains(void)
+{
+	schedule_work(&rebuild_sched_domains_work);
+}
+
+/*
+ * Accomplishes the same scheduler domain rebuild as the above
+ * async_rebuild_sched_domains(), however it directly calls the
+ * rebuild routine synchronously rather than calling it via an
+ * asynchronous work thread.
+ *
+ * This can only be called from code that is not holding
+ * cgroup_mutex (not nested in a cgroup_lock() call.)
+ */
+void rebuild_sched_domains(void)
+{
+	do_rebuild_sched_domains(NULL);
 }
 
 /**
@@ -774,37 +843,25 @@
 /**
  * update_tasks_cpumask - Update the cpumasks of tasks in the cpuset.
  * @cs: the cpuset in which each task's cpus_allowed mask needs to be changed
+ * @heap: if NULL, defer allocating heap memory to cgroup_scan_tasks()
  *
  * Called with cgroup_mutex held
  *
  * The cgroup_scan_tasks() function will scan all the tasks in a cgroup,
  * calling callback functions for each.
  *
- * Return 0 if successful, -errno if not.
+ * No return value. It's guaranteed that cgroup_scan_tasks() always returns 0
+ * if @heap != NULL.
  */
-static int update_tasks_cpumask(struct cpuset *cs)
+static void update_tasks_cpumask(struct cpuset *cs, struct ptr_heap *heap)
 {
 	struct cgroup_scanner scan;
-	struct ptr_heap heap;
-	int retval;
-
-	/*
-	 * cgroup_scan_tasks() will initialize heap->gt for us.
-	 * heap_init() is still needed here for we should not change
-	 * cs->cpus_allowed when heap_init() fails.
-	 */
-	retval = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, NULL);
-	if (retval)
-		return retval;
 
 	scan.cg = cs->css.cgroup;
 	scan.test_task = cpuset_test_cpumask;
 	scan.process_task = cpuset_change_cpumask;
-	scan.heap = &heap;
-	retval = cgroup_scan_tasks(&scan);
-
-	heap_free(&heap);
-	return retval;
+	scan.heap = heap;
+	cgroup_scan_tasks(&scan);
 }
 
 /**
@@ -814,6 +871,7 @@
  */
 static int update_cpumask(struct cpuset *cs, const char *buf)
 {
+	struct ptr_heap heap;
 	struct cpuset trialcs;
 	int retval;
 	int is_load_balanced;
@@ -848,6 +906,10 @@
 	if (cpus_equal(cs->cpus_allowed, trialcs.cpus_allowed))
 		return 0;
 
+	retval = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, NULL);
+	if (retval)
+		return retval;
+
 	is_load_balanced = is_sched_load_balance(&trialcs);
 
 	mutex_lock(&callback_mutex);
@@ -858,12 +920,12 @@
 	 * Scan tasks in the cpuset, and update the cpumasks of any
 	 * that need an update.
 	 */
-	retval = update_tasks_cpumask(cs);
-	if (retval < 0)
-		return retval;
+	update_tasks_cpumask(cs, &heap);
+
+	heap_free(&heap);
 
 	if (is_load_balanced)
-		rebuild_sched_domains();
+		async_rebuild_sched_domains();
 	return 0;
 }
 
@@ -1090,7 +1152,7 @@
 	if (val != cs->relax_domain_level) {
 		cs->relax_domain_level = val;
 		if (!cpus_empty(cs->cpus_allowed) && is_sched_load_balance(cs))
-			rebuild_sched_domains();
+			async_rebuild_sched_domains();
 	}
 
 	return 0;
@@ -1131,7 +1193,7 @@
 	mutex_unlock(&callback_mutex);
 
 	if (cpus_nonempty && balance_flag_changed)
-		rebuild_sched_domains();
+		async_rebuild_sched_domains();
 
 	return 0;
 }
@@ -1492,6 +1554,9 @@
 	default:
 		BUG();
 	}
+
+	/* Unreachable but makes gcc happy */
+	return 0;
 }
 
 static s64 cpuset_read_s64(struct cgroup *cont, struct cftype *cft)
@@ -1504,6 +1569,9 @@
 	default:
 		BUG();
 	}
+
+	/* Unrechable but makes gcc happy */
+	return 0;
 }
 
 
@@ -1692,15 +1760,9 @@
 }
 
 /*
- * Locking note on the strange update_flag() call below:
- *
  * If the cpuset being removed has its flag 'sched_load_balance'
  * enabled, then simulate turning sched_load_balance off, which
- * will call rebuild_sched_domains().  The get_online_cpus()
- * call in rebuild_sched_domains() must not be made while holding
- * callback_mutex.  Elsewhere the kernel nests callback_mutex inside
- * get_online_cpus() calls.  So the reverse nesting would risk an
- * ABBA deadlock.
+ * will call async_rebuild_sched_domains().
  */
 
 static void cpuset_destroy(struct cgroup_subsys *ss, struct cgroup *cont)
@@ -1719,7 +1781,7 @@
 struct cgroup_subsys cpuset_subsys = {
 	.name = "cpuset",
 	.create = cpuset_create,
-	.destroy  = cpuset_destroy,
+	.destroy = cpuset_destroy,
 	.can_attach = cpuset_can_attach,
 	.attach = cpuset_attach,
 	.populate = cpuset_populate,
@@ -1811,7 +1873,7 @@
 }
 
 /*
- * If common_cpu_mem_hotplug_unplug(), below, unplugs any CPUs
+ * If CPU and/or memory hotplug handlers, below, unplug any CPUs
  * or memory nodes, we need to walk over the cpuset hierarchy,
  * removing that CPU or node from all cpusets.  If this removes the
  * last CPU or node from a cpuset, then move the tasks in the empty
@@ -1896,42 +1958,13 @@
 		     nodes_empty(cp->mems_allowed))
 			remove_tasks_in_empty_cpuset(cp);
 		else {
-			update_tasks_cpumask(cp);
+			update_tasks_cpumask(cp, NULL);
 			update_tasks_nodemask(cp, &oldmems);
 		}
 	}
 }
 
 /*
- * The cpus_allowed and mems_allowed nodemasks in the top_cpuset track
- * cpu_online_map and node_states[N_HIGH_MEMORY].  Force the top cpuset to
- * track what's online after any CPU or memory node hotplug or unplug event.
- *
- * Since there are two callers of this routine, one for CPU hotplug
- * events and one for memory node hotplug events, we could have coded
- * two separate routines here.  We code it as a single common routine
- * in order to minimize text size.
- */
-
-static void common_cpu_mem_hotplug_unplug(int rebuild_sd)
-{
-	cgroup_lock();
-
-	top_cpuset.cpus_allowed = cpu_online_map;
-	top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
-	scan_for_empty_cpusets(&top_cpuset);
-
-	/*
-	 * Scheduler destroys domains on hotplug events.
-	 * Rebuild them based on the current settings.
-	 */
-	if (rebuild_sd)
-		rebuild_sched_domains();
-
-	cgroup_unlock();
-}
-
-/*
  * The top_cpuset tracks what CPUs and Memory Nodes are online,
  * period.  This is necessary in order to make cpusets transparent
  * (of no affect) on systems that are actively using CPU hotplug
@@ -1939,40 +1972,52 @@
  *
  * This routine ensures that top_cpuset.cpus_allowed tracks
  * cpu_online_map on each CPU hotplug (cpuhp) event.
+ *
+ * Called within get_online_cpus().  Needs to call cgroup_lock()
+ * before calling generate_sched_domains().
  */
-
-static int cpuset_handle_cpuhp(struct notifier_block *unused_nb,
+static int cpuset_track_online_cpus(struct notifier_block *unused_nb,
 				unsigned long phase, void *unused_cpu)
 {
+	struct sched_domain_attr *attr;
+	cpumask_t *doms;
+	int ndoms;
+
 	switch (phase) {
-	case CPU_UP_CANCELED:
-	case CPU_UP_CANCELED_FROZEN:
-	case CPU_DOWN_FAILED:
-	case CPU_DOWN_FAILED_FROZEN:
 	case CPU_ONLINE:
 	case CPU_ONLINE_FROZEN:
 	case CPU_DEAD:
 	case CPU_DEAD_FROZEN:
-		common_cpu_mem_hotplug_unplug(1);
 		break;
+
 	default:
 		return NOTIFY_DONE;
 	}
 
+	cgroup_lock();
+	top_cpuset.cpus_allowed = cpu_online_map;
+	scan_for_empty_cpusets(&top_cpuset);
+	ndoms = generate_sched_domains(&doms, &attr);
+	cgroup_unlock();
+
+	/* Have scheduler rebuild the domains */
+	partition_sched_domains(ndoms, doms, attr);
+
 	return NOTIFY_OK;
 }
 
 #ifdef CONFIG_MEMORY_HOTPLUG
 /*
  * Keep top_cpuset.mems_allowed tracking node_states[N_HIGH_MEMORY].
- * Call this routine anytime after you change
- * node_states[N_HIGH_MEMORY].
- * See also the previous routine cpuset_handle_cpuhp().
+ * Call this routine anytime after node_states[N_HIGH_MEMORY] changes.
+ * See also the previous routine cpuset_track_online_cpus().
  */
-
 void cpuset_track_online_nodes(void)
 {
-	common_cpu_mem_hotplug_unplug(0);
+	cgroup_lock();
+	top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
+	scan_for_empty_cpusets(&top_cpuset);
+	cgroup_unlock();
 }
 #endif
 
@@ -1987,7 +2032,7 @@
 	top_cpuset.cpus_allowed = cpu_online_map;
 	top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
 
-	hotcpu_notifier(cpuset_handle_cpuhp, 0);
+	hotcpu_notifier(cpuset_track_online_cpus, 0);
 }
 
 /**
diff --git a/kernel/exit.c b/kernel/exit.c
index 25ed2ad..1639564 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -112,9 +112,9 @@
 		 * We won't ever get here for the group leader, since it
 		 * will have been the last reference on the signal_struct.
 		 */
-		sig->utime = cputime_add(sig->utime, tsk->utime);
-		sig->stime = cputime_add(sig->stime, tsk->stime);
-		sig->gtime = cputime_add(sig->gtime, tsk->gtime);
+		sig->utime = cputime_add(sig->utime, task_utime(tsk));
+		sig->stime = cputime_add(sig->stime, task_stime(tsk));
+		sig->gtime = cputime_add(sig->gtime, task_gtime(tsk));
 		sig->min_flt += tsk->min_flt;
 		sig->maj_flt += tsk->maj_flt;
 		sig->nvcsw += tsk->nvcsw;
diff --git a/kernel/sched.c b/kernel/sched.c
index 9a1ddb8..cc1f81b 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4179,6 +4179,65 @@
 }
 
 /*
+ * Use precise platform statistics if available:
+ */
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+cputime_t task_utime(struct task_struct *p)
+{
+	return p->utime;
+}
+
+cputime_t task_stime(struct task_struct *p)
+{
+	return p->stime;
+}
+#else
+cputime_t task_utime(struct task_struct *p)
+{
+	clock_t utime = cputime_to_clock_t(p->utime),
+		total = utime + cputime_to_clock_t(p->stime);
+	u64 temp;
+
+	/*
+	 * Use CFS's precise accounting:
+	 */
+	temp = (u64)nsec_to_clock_t(p->se.sum_exec_runtime);
+
+	if (total) {
+		temp *= utime;
+		do_div(temp, total);
+	}
+	utime = (clock_t)temp;
+
+	p->prev_utime = max(p->prev_utime, clock_t_to_cputime(utime));
+	return p->prev_utime;
+}
+
+cputime_t task_stime(struct task_struct *p)
+{
+	clock_t stime;
+
+	/*
+	 * Use CFS's precise accounting. (we subtract utime from
+	 * the total, to make sure the total observed by userspace
+	 * grows monotonically - apps rely on that):
+	 */
+	stime = nsec_to_clock_t(p->se.sum_exec_runtime) -
+			cputime_to_clock_t(task_utime(p));
+
+	if (stime >= 0)
+		p->prev_stime = max(p->prev_stime, clock_t_to_cputime(stime));
+
+	return p->prev_stime;
+}
+#endif
+
+inline cputime_t task_gtime(struct task_struct *p)
+{
+	return p->gtime;
+}
+
+/*
  * This function gets called by the timer code, with HZ frequency.
  * We call it with interrupts disabled.
  *
@@ -7637,24 +7696,27 @@
  * and partition_sched_domains() will fallback to the single partition
  * 'fallback_doms', it also forces the domains to be rebuilt.
  *
+ * If doms_new==NULL it will be replaced with cpu_online_map.
+ * ndoms_new==0 is a special case for destroying existing domains.
+ * It will not create the default domain.
+ *
  * Call with hotplug lock held
  */
 void partition_sched_domains(int ndoms_new, cpumask_t *doms_new,
 			     struct sched_domain_attr *dattr_new)
 {
-	int i, j;
+	int i, j, n;
 
 	mutex_lock(&sched_domains_mutex);
 
 	/* always unregister in case we don't destroy any domains */
 	unregister_sched_domain_sysctl();
 
-	if (doms_new == NULL)
-		ndoms_new = 0;
+	n = doms_new ? ndoms_new : 0;
 
 	/* Destroy deleted domains */
 	for (i = 0; i < ndoms_cur; i++) {
-		for (j = 0; j < ndoms_new; j++) {
+		for (j = 0; j < n; j++) {
 			if (cpus_equal(doms_cur[i], doms_new[j])
 			    && dattrs_equal(dattr_cur, i, dattr_new, j))
 				goto match1;
@@ -7667,7 +7729,6 @@
 
 	if (doms_new == NULL) {
 		ndoms_cur = 0;
-		ndoms_new = 1;
 		doms_new = &fallback_doms;
 		cpus_andnot(doms_new[0], cpu_online_map, cpu_isolated_map);
 		dattr_new = NULL;
@@ -7704,8 +7765,13 @@
 int arch_reinit_sched_domains(void)
 {
 	get_online_cpus();
+
+	/* Destroy domains first to force the rebuild */
+	partition_sched_domains(0, NULL, NULL);
+
 	rebuild_sched_domains();
 	put_online_cpus();
+
 	return 0;
 }
 
@@ -7789,7 +7855,7 @@
 	case CPU_ONLINE_FROZEN:
 	case CPU_DEAD:
 	case CPU_DEAD_FROZEN:
-		partition_sched_domains(0, NULL, NULL);
+		partition_sched_domains(1, NULL, NULL);
 		return NOTIFY_OK;
 
 	default:
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index fe47133..50ec088 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -159,6 +159,7 @@
 static struct ctl_table root_table[];
 static struct ctl_table_root sysctl_table_root;
 static struct ctl_table_header root_table_header = {
+	.count = 1,
 	.ctl_table = root_table,
 	.ctl_entry = LIST_HEAD_INIT(sysctl_table_root.default_set.list),
 	.root = &sysctl_table_root,
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 3d1e3e1..1876b52 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -177,7 +177,7 @@
 /*
  * Noop handler when we shut down an event device
  */
-static void clockevents_handle_noop(struct clock_event_device *dev)
+void clockevents_handle_noop(struct clock_event_device *dev)
 {
 }
 
@@ -199,7 +199,6 @@
 	 * released list and do a notify add later.
 	 */
 	if (old) {
-		old->event_handler = clockevents_handle_noop;
 		clockevents_set_mode(old, CLOCK_EVT_MODE_UNUSED);
 		list_del(&old->list);
 		list_add(&old->list, &clockevents_released);
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 5125ddd..1ad46f3 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -245,7 +245,7 @@
 	if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2)
 		fail = update_persistent_clock(now);
 
-	next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec;
+	next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec - (TICK_NSEC / 2);
 	if (next.tv_nsec <= 0)
 		next.tv_nsec += NSEC_PER_SEC;
 
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index 31463d3..2f5a382 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -175,6 +175,8 @@
  */
 static void tick_handle_periodic_broadcast(struct clock_event_device *dev)
 {
+	ktime_t next;
+
 	tick_do_periodic_broadcast();
 
 	/*
@@ -185,10 +187,13 @@
 
 	/*
 	 * Setup the next period for devices, which do not have
-	 * periodic mode:
+	 * periodic mode. We read dev->next_event first and add to it
+	 * when the event alrady expired. clockevents_program_event()
+	 * sets dev->next_event only when the event is really
+	 * programmed to the device.
 	 */
-	for (;;) {
-		ktime_t next = ktime_add(dev->next_event, tick_period);
+	for (next = dev->next_event; ;) {
+		next = ktime_add(next, tick_period);
 
 		if (!clockevents_program_event(dev, next, ktime_get()))
 			return;
@@ -205,7 +210,7 @@
 	struct clock_event_device *bc, *dev;
 	struct tick_device *td;
 	unsigned long flags, *reason = why;
-	int cpu;
+	int cpu, bc_stopped;
 
 	spin_lock_irqsave(&tick_broadcast_lock, flags);
 
@@ -223,6 +228,8 @@
 	if (!tick_device_is_functional(dev))
 		goto out;
 
+	bc_stopped = cpus_empty(tick_broadcast_mask);
+
 	switch (*reason) {
 	case CLOCK_EVT_NOTIFY_BROADCAST_ON:
 	case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
@@ -245,9 +252,10 @@
 		break;
 	}
 
-	if (cpus_empty(tick_broadcast_mask))
-		clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
-	else {
+	if (cpus_empty(tick_broadcast_mask)) {
+		if (!bc_stopped)
+			clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
+	} else if (bc_stopped) {
 		if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
 			tick_broadcast_start_periodic(bc);
 		else
@@ -364,16 +372,8 @@
 static int tick_broadcast_set_event(ktime_t expires, int force)
 {
 	struct clock_event_device *bc = tick_broadcast_device.evtdev;
-	ktime_t now = ktime_get();
-	int res;
 
-	for(;;) {
-		res = clockevents_program_event(bc, expires, now);
-		if (!res || !force)
-			return res;
-		now = ktime_get();
-		expires = ktime_add(now, ktime_set(0, bc->min_delta_ns));
-	}
+	return tick_dev_program_event(bc, expires, force);
 }
 
 int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
@@ -491,14 +491,52 @@
 	cpu_clear(cpu, tick_broadcast_oneshot_mask);
 }
 
+static void tick_broadcast_init_next_event(cpumask_t *mask, ktime_t expires)
+{
+	struct tick_device *td;
+	int cpu;
+
+	for_each_cpu_mask_nr(cpu, *mask) {
+		td = &per_cpu(tick_cpu_device, cpu);
+		if (td->evtdev)
+			td->evtdev->next_event = expires;
+	}
+}
+
 /**
  * tick_broadcast_setup_oneshot - setup the broadcast device
  */
 void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
 {
-	bc->event_handler = tick_handle_oneshot_broadcast;
-	clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
-	bc->next_event.tv64 = KTIME_MAX;
+	/* Set it up only once ! */
+	if (bc->event_handler != tick_handle_oneshot_broadcast) {
+		int was_periodic = bc->mode == CLOCK_EVT_MODE_PERIODIC;
+		int cpu = smp_processor_id();
+		cpumask_t mask;
+
+		bc->event_handler = tick_handle_oneshot_broadcast;
+		clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
+
+		/* Take the do_timer update */
+		tick_do_timer_cpu = cpu;
+
+		/*
+		 * We must be careful here. There might be other CPUs
+		 * waiting for periodic broadcast. We need to set the
+		 * oneshot_mask bits for those and program the
+		 * broadcast device to fire.
+		 */
+		mask = tick_broadcast_mask;
+		cpu_clear(cpu, mask);
+		cpus_or(tick_broadcast_oneshot_mask,
+			tick_broadcast_oneshot_mask, mask);
+
+		if (was_periodic && !cpus_empty(mask)) {
+			tick_broadcast_init_next_event(&mask, tick_next_period);
+			tick_broadcast_set_event(tick_next_period, 1);
+		} else
+			bc->next_event.tv64 = KTIME_MAX;
+	}
 }
 
 /*
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index 80c4336..c477719 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -161,6 +161,7 @@
 	} else {
 		handler = td->evtdev->event_handler;
 		next_event = td->evtdev->next_event;
+		td->evtdev->event_handler = clockevents_handle_noop;
 	}
 
 	td->evtdev = newdev;
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index f13f2b7..0ffc291 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -17,6 +17,8 @@
 extern void tick_setup_oneshot(struct clock_event_device *newdev,
 			       void (*handler)(struct clock_event_device *),
 			       ktime_t nextevt);
+extern int tick_dev_program_event(struct clock_event_device *dev,
+				  ktime_t expires, int force);
 extern int tick_program_event(ktime_t expires, int force);
 extern void tick_oneshot_notify(void);
 extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *));
diff --git a/kernel/time/tick-oneshot.c b/kernel/time/tick-oneshot.c
index 450c049..2e8de67 100644
--- a/kernel/time/tick-oneshot.c
+++ b/kernel/time/tick-oneshot.c
@@ -23,21 +23,53 @@
 #include "tick-internal.h"
 
 /**
+ * tick_program_event internal worker function
+ */
+int tick_dev_program_event(struct clock_event_device *dev, ktime_t expires,
+			   int force)
+{
+	ktime_t now = ktime_get();
+	int i;
+
+	for (i = 0;;) {
+		int ret = clockevents_program_event(dev, expires, now);
+
+		if (!ret || !force)
+			return ret;
+
+		/*
+		 * We tried 2 times to program the device with the given
+		 * min_delta_ns. If that's not working then we double it
+		 * and emit a warning.
+		 */
+		if (++i > 2) {
+			/* Increase the min. delta and try again */
+			if (!dev->min_delta_ns)
+				dev->min_delta_ns = 5000;
+			else
+				dev->min_delta_ns += dev->min_delta_ns >> 1;
+
+			printk(KERN_WARNING
+			       "CE: %s increasing min_delta_ns to %lu nsec\n",
+			       dev->name ? dev->name : "?",
+			       dev->min_delta_ns << 1);
+
+			i = 0;
+		}
+
+		now = ktime_get();
+		expires = ktime_add_ns(now, dev->min_delta_ns);
+	}
+}
+
+/**
  * tick_program_event
  */
 int tick_program_event(ktime_t expires, int force)
 {
 	struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
-	ktime_t now = ktime_get();
 
-	while (1) {
-		int ret = clockevents_program_event(dev, expires, now);
-
-		if (!ret || !force)
-			return ret;
-		now = ktime_get();
-		expires = ktime_add(now, ktime_set(0, dev->min_delta_ns));
-	}
+	return tick_dev_program_event(dev, expires, force);
 }
 
 /**
@@ -61,7 +93,7 @@
 {
 	newdev->event_handler = handler;
 	clockevents_set_mode(newdev, CLOCK_EVT_MODE_ONESHOT);
-	clockevents_program_event(newdev, next_event, ktime_get());
+	tick_dev_program_event(newdev, next_event, 1);
 }
 
 /**
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 7a46bde..a87b046 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -162,6 +162,8 @@
 		ts->idle_lastupdate = now;
 		ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta);
 		ts->idle_active = 0;
+
+		sched_clock_idle_wakeup_event(0);
 	}
 }
 
@@ -177,6 +179,7 @@
 	}
 	ts->idle_entrytime = now;
 	ts->idle_active = 1;
+	sched_clock_idle_sleep_event();
 	return now;
 }
 
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 8b5a7d3..0b50481 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -394,7 +394,7 @@
 	bool
 	depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
 	select STACKTRACE
-	select FRAME_POINTER if !X86 && !MIPS
+	select FRAME_POINTER if !X86 && !MIPS && !PPC
 	select KALLSYMS
 	select KALLSYMS_ALL
 
@@ -676,13 +676,13 @@
 	depends on FAULT_INJECTION_DEBUG_FS && STACKTRACE_SUPPORT
 	depends on !X86_64
 	select STACKTRACE
-	select FRAME_POINTER
+	select FRAME_POINTER if !PPC
 	help
 	  Provide stacktrace filter for fault-injection capabilities
 
 config LATENCYTOP
 	bool "Latency measuring infrastructure"
-	select FRAME_POINTER if !MIPS
+	select FRAME_POINTER if !MIPS && !PPC
 	select KALLSYMS
 	select KALLSYMS_ALL
 	select STACKTRACE
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index 45a6bde..e3ab374 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -112,6 +112,7 @@
 
 /*
  * Allocate a new object. If the pool is empty, switch off the debugger.
+ * Must be called with interrupts disabled.
  */
 static struct debug_obj *
 alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr)
@@ -148,17 +149,18 @@
 static void free_object(struct debug_obj *obj)
 {
 	unsigned long idx = (unsigned long)(obj - obj_static_pool);
+	unsigned long flags;
 
 	if (obj_pool_free < ODEBUG_POOL_SIZE || idx < ODEBUG_POOL_SIZE) {
-		spin_lock(&pool_lock);
+		spin_lock_irqsave(&pool_lock, flags);
 		hlist_add_head(&obj->node, &obj_pool);
 		obj_pool_free++;
 		obj_pool_used--;
-		spin_unlock(&pool_lock);
+		spin_unlock_irqrestore(&pool_lock, flags);
 	} else {
-		spin_lock(&pool_lock);
+		spin_lock_irqsave(&pool_lock, flags);
 		obj_pool_used--;
-		spin_unlock(&pool_lock);
+		spin_unlock_irqrestore(&pool_lock, flags);
 		kmem_cache_free(obj_cache, obj);
 	}
 }
@@ -171,6 +173,7 @@
 {
 	struct debug_bucket *db = obj_hash;
 	struct hlist_node *node, *tmp;
+	HLIST_HEAD(freelist);
 	struct debug_obj *obj;
 	unsigned long flags;
 	int i;
@@ -179,11 +182,14 @@
 
 	for (i = 0; i < ODEBUG_HASH_SIZE; i++, db++) {
 		spin_lock_irqsave(&db->lock, flags);
-		hlist_for_each_entry_safe(obj, node, tmp, &db->list, node) {
+		hlist_move_list(&db->list, &freelist);
+		spin_unlock_irqrestore(&db->lock, flags);
+
+		/* Now free them */
+		hlist_for_each_entry_safe(obj, node, tmp, &freelist, node) {
 			hlist_del(&obj->node);
 			free_object(obj);
 		}
-		spin_unlock_irqrestore(&db->lock, flags);
 	}
 }
 
@@ -498,8 +504,9 @@
 		return;
 	default:
 		hlist_del(&obj->node);
+		spin_unlock_irqrestore(&db->lock, flags);
 		free_object(obj);
-		break;
+		return;
 	}
 out_unlock:
 	spin_unlock_irqrestore(&db->lock, flags);
@@ -510,6 +517,7 @@
 {
 	unsigned long flags, oaddr, saddr, eaddr, paddr, chunks;
 	struct hlist_node *node, *tmp;
+	HLIST_HEAD(freelist);
 	struct debug_obj_descr *descr;
 	enum debug_obj_state state;
 	struct debug_bucket *db;
@@ -545,11 +553,18 @@
 				goto repeat;
 			default:
 				hlist_del(&obj->node);
-				free_object(obj);
+				hlist_add_head(&obj->node, &freelist);
 				break;
 			}
 		}
 		spin_unlock_irqrestore(&db->lock, flags);
+
+		/* Now free them */
+		hlist_for_each_entry_safe(obj, node, tmp, &freelist, node) {
+			hlist_del(&obj->node);
+			free_object(obj);
+		}
+
 		if (cnt > debug_objects_maxchain)
 			debug_objects_maxchain = cnt;
 	}
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index 876ba6d..8d2688f 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -422,9 +422,12 @@
 {
 	unsigned int offset = 0;
 	struct sg_mapping_iter miter;
+	unsigned long flags;
 
 	sg_miter_start(&miter, sgl, nents, SG_MITER_ATOMIC);
 
+	local_irq_save(flags);
+
 	while (sg_miter_next(&miter) && offset < buflen) {
 		unsigned int len;
 
@@ -442,6 +445,7 @@
 
 	sg_miter_stop(&miter);
 
+	local_irq_restore(flags);
 	return offset;
 }
 
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 977edbd..8826fdf 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -491,7 +491,7 @@
 		 * the lowest available address range.
 		 */
 		dma_addr_t handle;
-		handle = swiotlb_map_single(NULL, NULL, size, DMA_FROM_DEVICE);
+		handle = swiotlb_map_single(hwdev, NULL, size, DMA_FROM_DEVICE);
 		if (swiotlb_dma_mapping_error(hwdev, handle))
 			return NULL;
 
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index d8d1d11..c399bc1 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -27,6 +27,7 @@
 
 #include <asm/page.h>		/* for PAGE_SIZE */
 #include <asm/div64.h>
+#include <asm/sections.h>	/* for dereference_function_descriptor() */
 
 /* Works only for digits and letters, but small and fast */
 #define TOLOWER(x) ((x) | 0x20)
@@ -513,16 +514,6 @@
 	return buf;
 }
 
-static inline void *dereference_function_descriptor(void *ptr)
-{
-#if defined(CONFIG_IA64) || defined(CONFIG_PPC64)
-	void *p;
-	if (!probe_kernel_address(ptr, p))
-		ptr = p;
-#endif
-	return ptr;
-}
-
 static char *symbol_string(char *buf, char *end, void *ptr, int field_width, int precision, int flags)
 {
 	unsigned long value = (unsigned long) ptr;
diff --git a/mm/mmap.c b/mm/mmap.c
index 339cf5c..e7a5a68 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1030,6 +1030,10 @@
 	} else {
 		switch (flags & MAP_TYPE) {
 		case MAP_SHARED:
+			/*
+			 * Ignore pgoff.
+			 */
+			pgoff = 0;
 			vm_flags |= VM_SHARED | VM_MAYSHARE;
 			break;
 		case MAP_PRIVATE:
diff --git a/mm/mmzone.c b/mm/mmzone.c
index 486ed59..16ce8b9 100644
--- a/mm/mmzone.c
+++ b/mm/mmzone.c
@@ -69,6 +69,6 @@
 				(z->zone && !zref_in_nodemask(z, nodes)))
 			z++;
 
-	*zone = zonelist_zone(z++);
+	*zone = zonelist_zone(z);
 	return z;
 }
diff --git a/mm/slub.c b/mm/slub.c
index fb486d5..0c83e6a 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1932,6 +1932,7 @@
 	INIT_LIST_HEAD(&n->partial);
 #ifdef CONFIG_SLUB_DEBUG
 	atomic_long_set(&n->nr_slabs, 0);
+	atomic_long_set(&n->total_objects, 0);
 	INIT_LIST_HEAD(&n->full);
 #endif
 }
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 1edfdf4..f6348e0 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -49,7 +49,7 @@
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "2.12"
+#define VERSION "2.13"
 
 /* Bluetooth sockets */
 #define BT_MAX_PROTO	8
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index ca8d052..b700242 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -330,7 +330,7 @@
 
 /* Create SCO or ACL connection.
  * Device _must_ be locked */
-struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
+struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 auth_type)
 {
 	struct hci_conn *acl;
 	struct hci_conn *sco;
@@ -344,8 +344,10 @@
 
 	hci_conn_hold(acl);
 
-	if (acl->state == BT_OPEN || acl->state == BT_CLOSED)
+	if (acl->state == BT_OPEN || acl->state == BT_CLOSED) {
+		acl->auth_type = auth_type;
 		hci_acl_connect(acl);
+	}
 
 	if (type == ACL_LINK)
 		return acl;
@@ -374,6 +376,19 @@
 }
 EXPORT_SYMBOL(hci_connect);
 
+/* Check link security requirement */
+int hci_conn_check_link_mode(struct hci_conn *conn)
+{
+	BT_DBG("conn %p", conn);
+
+	if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0 &&
+					!(conn->link_mode & HCI_LM_ENCRYPT))
+		return 0;
+
+	return 1;
+}
+EXPORT_SYMBOL(hci_conn_check_link_mode);
+
 /* Authenticate remote device */
 int hci_conn_auth(struct hci_conn *conn)
 {
@@ -381,7 +396,7 @@
 
 	if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) {
 		if (!(conn->auth_type & 0x01)) {
-			conn->auth_type = HCI_AT_GENERAL_BONDING_MITM;
+			conn->auth_type |= 0x01;
 			conn->link_mode &= ~HCI_LM_AUTH;
 		}
 	}
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index f5b21cb..278a3ac 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -164,6 +164,9 @@
 {
 	int ret;
 
+	if (!test_bit(HCI_UP, &hdev->flags))
+		return -ENETDOWN;
+
 	/* Serialize all requests */
 	hci_req_lock(hdev);
 	ret = __hci_request(hdev, req, opt, timeout);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 0e3db28..ad7a553 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1605,14 +1605,11 @@
 
 		if (conn->state == BT_CONFIG) {
 			if (!ev->status && hdev->ssp_mode > 0 &&
-							conn->ssp_mode > 0) {
-				if (conn->out) {
-					struct hci_cp_auth_requested cp;
-					cp.handle = ev->handle;
-					hci_send_cmd(hdev,
-						HCI_OP_AUTH_REQUESTED,
+					conn->ssp_mode > 0 && conn->out) {
+				struct hci_cp_auth_requested cp;
+				cp.handle = ev->handle;
+				hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
 							sizeof(cp), &cp);
-				}
 			} else {
 				conn->state = BT_CONNECTED;
 				hci_proto_connect_cfm(conn, ev->status);
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 3396d5b..9610a9c 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -55,7 +55,7 @@
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "2.10"
+#define VERSION "2.11"
 
 static u32 l2cap_feat_mask = 0x0000;
 
@@ -778,6 +778,7 @@
 	struct l2cap_conn *conn;
 	struct hci_conn *hcon;
 	struct hci_dev *hdev;
+	__u8 auth_type;
 	int err = 0;
 
 	BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
@@ -789,7 +790,21 @@
 
 	err = -ENOMEM;
 
-	hcon = hci_connect(hdev, ACL_LINK, dst);
+	if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH ||
+			l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT ||
+				l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) {
+		if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001))
+			auth_type = HCI_AT_NO_BONDING_MITM;
+		else
+			auth_type = HCI_AT_GENERAL_BONDING_MITM;
+	} else {
+		if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001))
+			auth_type = HCI_AT_NO_BONDING;
+		else
+			auth_type = HCI_AT_GENERAL_BONDING;
+	}
+
+	hcon = hci_connect(hdev, ACL_LINK, dst, auth_type);
 	if (!hcon)
 		goto done;
 
@@ -1553,10 +1568,10 @@
 	struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
 	struct l2cap_conn_rsp rsp;
 	struct sock *sk, *parent;
-	int result, status = 0;
+	int result, status = L2CAP_CS_NO_INFO;
 
 	u16 dcid = 0, scid = __le16_to_cpu(req->scid);
-	__le16 psm  = req->psm;
+	__le16 psm = req->psm;
 
 	BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
 
@@ -1567,6 +1582,13 @@
 		goto sendresp;
 	}
 
+	/* Check if the ACL is secure enough (if not SDP) */
+	if (psm != cpu_to_le16(0x0001) &&
+				!hci_conn_check_link_mode(conn->hcon)) {
+		result = L2CAP_CR_SEC_BLOCK;
+		goto response;
+	}
+
 	result = L2CAP_CR_NO_MEM;
 
 	/* Check for backlog size */
@@ -2224,7 +2246,7 @@
 			rsp.scid   = cpu_to_le16(l2cap_pi(sk)->dcid);
 			rsp.dcid   = cpu_to_le16(l2cap_pi(sk)->scid);
 			rsp.result = cpu_to_le16(result);
-			rsp.status = cpu_to_le16(0);
+			rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
 			l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
 					L2CAP_CONN_RSP, sizeof(rsp), &rsp);
 		}
@@ -2296,7 +2318,7 @@
 			rsp.scid   = cpu_to_le16(l2cap_pi(sk)->dcid);
 			rsp.dcid   = cpu_to_le16(l2cap_pi(sk)->scid);
 			rsp.result = cpu_to_le16(result);
-			rsp.status = cpu_to_le16(0);
+			rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
 			l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
 					L2CAP_CONN_RSP, sizeof(rsp), &rsp);
 		}
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index a16011f..0cc91e6 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -200,7 +200,7 @@
 	else
 		type = SCO_LINK;
 
-	hcon = hci_connect(hdev, type, dst);
+	hcon = hci_connect(hdev, type, dst, HCI_AT_NO_BONDING);
 	if (!hcon)
 		goto done;
 
diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c
index eeee218..5bbf073 100644
--- a/net/bridge/br_ioctl.c
+++ b/net/bridge/br_ioctl.c
@@ -188,15 +188,21 @@
 		return 0;
 
 	case BRCTL_SET_BRIDGE_HELLO_TIME:
+	{
+		unsigned long t = clock_t_to_jiffies(args[1]);
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
 
+		if (t < HZ)
+			return -EINVAL;
+
 		spin_lock_bh(&br->lock);
-		br->bridge_hello_time = clock_t_to_jiffies(args[1]);
+		br->bridge_hello_time = t;
 		if (br_is_root_bridge(br))
 			br->hello_time = br->bridge_hello_time;
 		spin_unlock_bh(&br->lock);
 		return 0;
+	}
 
 	case BRCTL_SET_BRIDGE_MAX_AGE:
 		if (!capable(CAP_NET_ADMIN))
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index 27d6a51..158dee8 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -29,11 +29,12 @@
  */
 static ssize_t store_bridge_parm(struct device *d,
 				 const char *buf, size_t len,
-				 void (*set)(struct net_bridge *, unsigned long))
+				 int (*set)(struct net_bridge *, unsigned long))
 {
 	struct net_bridge *br = to_bridge(d);
 	char *endp;
 	unsigned long val;
+	int err;
 
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
@@ -43,9 +44,9 @@
 		return -EINVAL;
 
 	spin_lock_bh(&br->lock);
-	(*set)(br, val);
+	err = (*set)(br, val);
 	spin_unlock_bh(&br->lock);
-	return len;
+	return err ? err : len;
 }
 
 
@@ -56,12 +57,13 @@
 	return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->forward_delay));
 }
 
-static void set_forward_delay(struct net_bridge *br, unsigned long val)
+static int set_forward_delay(struct net_bridge *br, unsigned long val)
 {
 	unsigned long delay = clock_t_to_jiffies(val);
 	br->forward_delay = delay;
 	if (br_is_root_bridge(br))
 		br->bridge_forward_delay = delay;
+	return 0;
 }
 
 static ssize_t store_forward_delay(struct device *d,
@@ -80,12 +82,17 @@
 		       jiffies_to_clock_t(to_bridge(d)->hello_time));
 }
 
-static void set_hello_time(struct net_bridge *br, unsigned long val)
+static int set_hello_time(struct net_bridge *br, unsigned long val)
 {
 	unsigned long t = clock_t_to_jiffies(val);
+
+	if (t < HZ)
+		return -EINVAL;
+
 	br->hello_time = t;
 	if (br_is_root_bridge(br))
 		br->bridge_hello_time = t;
+	return 0;
 }
 
 static ssize_t store_hello_time(struct device *d,
@@ -104,12 +111,13 @@
 		       jiffies_to_clock_t(to_bridge(d)->max_age));
 }
 
-static void set_max_age(struct net_bridge *br, unsigned long val)
+static int set_max_age(struct net_bridge *br, unsigned long val)
 {
 	unsigned long t = clock_t_to_jiffies(val);
 	br->max_age = t;
 	if (br_is_root_bridge(br))
 		br->bridge_max_age = t;
+	return 0;
 }
 
 static ssize_t store_max_age(struct device *d, struct device_attribute *attr,
@@ -126,9 +134,10 @@
 	return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->ageing_time));
 }
 
-static void set_ageing_time(struct net_bridge *br, unsigned long val)
+static int set_ageing_time(struct net_bridge *br, unsigned long val)
 {
 	br->ageing_time = clock_t_to_jiffies(val);
+	return 0;
 }
 
 static ssize_t store_ageing_time(struct device *d,
@@ -180,9 +189,10 @@
 		       (br->bridge_id.prio[0] << 8) | br->bridge_id.prio[1]);
 }
 
-static void set_priority(struct net_bridge *br, unsigned long val)
+static int set_priority(struct net_bridge *br, unsigned long val)
 {
 	br_stp_set_bridge_priority(br, (u16) val);
+	return 0;
 }
 
 static ssize_t store_priority(struct device *d, struct device_attribute *attr,
diff --git a/net/core/dev.c b/net/core/dev.c
index 60c51f7..e719ed2 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1991,8 +1991,13 @@
 				spin_unlock(root_lock);
 			} else {
 				if (!test_bit(__QDISC_STATE_DEACTIVATED,
-					      &q->state))
+					      &q->state)) {
 					__netif_reschedule(q);
+				} else {
+					smp_mb__before_clear_bit();
+					clear_bit(__QDISC_STATE_SCHED,
+						  &q->state);
+				}
 			}
 		}
 	}
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index d985bd6..743f011 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -409,3 +409,38 @@
 }
 
 EXPORT_SYMBOL_GPL(inet_twdr_twcal_tick);
+
+void inet_twsk_purge(struct net *net, struct inet_hashinfo *hashinfo,
+		     struct inet_timewait_death_row *twdr, int family)
+{
+	struct inet_timewait_sock *tw;
+	struct sock *sk;
+	struct hlist_node *node;
+	int h;
+
+	local_bh_disable();
+	for (h = 0; h < (hashinfo->ehash_size); h++) {
+		struct inet_ehash_bucket *head =
+			inet_ehash_bucket(hashinfo, h);
+		rwlock_t *lock = inet_ehash_lockp(hashinfo, h);
+restart:
+		write_lock(lock);
+		sk_for_each(sk, node, &head->twchain) {
+
+			tw = inet_twsk(sk);
+			if (!net_eq(twsk_net(tw), net) ||
+			    tw->tw_family != family)
+				continue;
+
+			atomic_inc(&tw->tw_refcnt);
+			write_unlock(lock);
+			inet_twsk_deschedule(tw, twdr);
+			inet_twsk_put(tw);
+
+			goto restart;
+		}
+		write_unlock(lock);
+	}
+	local_bh_enable();
+}
+EXPORT_SYMBOL_GPL(inet_twsk_purge);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 44c1e93..1b4fee2 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2376,6 +2376,7 @@
 static void __net_exit tcp_sk_exit(struct net *net)
 {
 	inet_ctl_sock_destroy(net->ipv4.tcp_sock);
+	inet_twsk_purge(net, &tcp_hashinfo, &tcp_death_row, AF_INET);
 }
 
 static struct pernet_operations __net_initdata tcp_sk_ops = {
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 0e844c2..3df2c44 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -943,39 +943,39 @@
 	}
 
 #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
-		/*
-		 * Here if the dst entry we've looked up
-		 * has a neighbour entry that is in the INCOMPLETE
-		 * state and the src address from the flow is
-		 * marked as OPTIMISTIC, we release the found
-		 * dst entry and replace it instead with the
-		 * dst entry of the nexthop router
-		 */
-		if (!((*dst)->neighbour->nud_state & NUD_VALID)) {
-			struct inet6_ifaddr *ifp;
-			struct flowi fl_gw;
-			int redirect;
+	/*
+	 * Here if the dst entry we've looked up
+	 * has a neighbour entry that is in the INCOMPLETE
+	 * state and the src address from the flow is
+	 * marked as OPTIMISTIC, we release the found
+	 * dst entry and replace it instead with the
+	 * dst entry of the nexthop router
+	 */
+	if ((*dst)->neighbour && !((*dst)->neighbour->nud_state & NUD_VALID)) {
+		struct inet6_ifaddr *ifp;
+		struct flowi fl_gw;
+		int redirect;
 
-			ifp = ipv6_get_ifaddr(net, &fl->fl6_src,
-					      (*dst)->dev, 1);
+		ifp = ipv6_get_ifaddr(net, &fl->fl6_src,
+				      (*dst)->dev, 1);
 
-			redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
-			if (ifp)
-				in6_ifa_put(ifp);
+		redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
+		if (ifp)
+			in6_ifa_put(ifp);
 
-			if (redirect) {
-				/*
-				 * We need to get the dst entry for the
-				 * default router instead
-				 */
-				dst_release(*dst);
-				memcpy(&fl_gw, fl, sizeof(struct flowi));
-				memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr));
-				*dst = ip6_route_output(net, sk, &fl_gw);
-				if ((err = (*dst)->error))
-					goto out_err_release;
-			}
+		if (redirect) {
+			/*
+			 * We need to get the dst entry for the
+			 * default router instead
+			 */
+			dst_release(*dst);
+			memcpy(&fl_gw, fl, sizeof(struct flowi));
+			memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr));
+			*dst = ip6_route_output(net, sk, &fl_gw);
+			if ((err = (*dst)->error))
+				goto out_err_release;
 		}
+	}
 #endif
 
 	return 0;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 5b90b36..b585c85 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -2148,6 +2148,7 @@
 static void tcpv6_net_exit(struct net *net)
 {
 	inet_ctl_sock_destroy(net->ipv6.tcp_sk);
+	inet_twsk_purge(net, &tcp_hashinfo, &tcp_death_row, AF_INET6);
 }
 
 static struct pernet_operations tcpv6_net_ops = {
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 9bb68c6..902cac1 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -478,21 +478,51 @@
 static void ieee80211_sta_send_associnfo(struct net_device *dev,
 					 struct ieee80211_if_sta *ifsta)
 {
+	char *buf;
+	size_t len;
+	int i;
 	union iwreq_data wrqu;
 
+	if (!ifsta->assocreq_ies && !ifsta->assocresp_ies)
+		return;
+
+	buf = kmalloc(50 + 2 * (ifsta->assocreq_ies_len +
+				ifsta->assocresp_ies_len), GFP_KERNEL);
+	if (!buf)
+		return;
+
+	len = sprintf(buf, "ASSOCINFO(");
 	if (ifsta->assocreq_ies) {
-		memset(&wrqu, 0, sizeof(wrqu));
-		wrqu.data.length = ifsta->assocreq_ies_len;
-		wireless_send_event(dev, IWEVASSOCREQIE, &wrqu,
-				    ifsta->assocreq_ies);
+		len += sprintf(buf + len, "ReqIEs=");
+		for (i = 0; i < ifsta->assocreq_ies_len; i++) {
+			len += sprintf(buf + len, "%02x",
+				       ifsta->assocreq_ies[i]);
+		}
+	}
+	if (ifsta->assocresp_ies) {
+		if (ifsta->assocreq_ies)
+			len += sprintf(buf + len, " ");
+		len += sprintf(buf + len, "RespIEs=");
+		for (i = 0; i < ifsta->assocresp_ies_len; i++) {
+			len += sprintf(buf + len, "%02x",
+				       ifsta->assocresp_ies[i]);
+		}
+	}
+	len += sprintf(buf + len, ")");
+
+	if (len > IW_CUSTOM_MAX) {
+		len = sprintf(buf, "ASSOCRESPIE=");
+		for (i = 0; i < ifsta->assocresp_ies_len; i++) {
+			len += sprintf(buf + len, "%02x",
+				       ifsta->assocresp_ies[i]);
+		}
 	}
 
-	if (ifsta->assocresp_ies) {
-		memset(&wrqu, 0, sizeof(wrqu));
-		wrqu.data.length = ifsta->assocresp_ies_len;
-		wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu,
-				    ifsta->assocresp_ies);
-	}
+	memset(&wrqu, 0, sizeof(wrqu));
+	wrqu.data.length = len;
+	wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
+
+	kfree(buf);
 }
 
 
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c
index 1b1226d..20633fd 100644
--- a/net/netfilter/nf_conntrack_irc.c
+++ b/net/netfilter/nf_conntrack_irc.c
@@ -68,11 +68,21 @@
 static int parse_dcc(char *data, const char *data_end, u_int32_t *ip,
 		     u_int16_t *port, char **ad_beg_p, char **ad_end_p)
 {
+	char *tmp;
+
 	/* at least 12: "AAAAAAAA P\1\n" */
 	while (*data++ != ' ')
 		if (data > data_end - 12)
 			return -1;
 
+	/* Make sure we have a newline character within the packet boundaries
+	 * because simple_strtoul parses until the first invalid character. */
+	for (tmp = data; tmp <= data_end; tmp++)
+		if (*tmp == '\n')
+			break;
+	if (tmp > data_end || *tmp != '\n')
+		return -1;
+
 	*ad_beg_p = data;
 	*ip = simple_strtoul(data, &data, 10);
 
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index 654a4f7..9bd0396 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -45,12 +45,12 @@
 
 void nf_ct_gre_keymap_flush(void)
 {
-	struct list_head *pos, *n;
+	struct nf_ct_gre_keymap *km, *tmp;
 
 	write_lock_bh(&nf_ct_gre_lock);
-	list_for_each_safe(pos, n, &gre_keymap_list) {
-		list_del(pos);
-		kfree(pos);
+	list_for_each_entry_safe(km, tmp, &gre_keymap_list, list) {
+		list_del(&km->list);
+		kfree(km);
 	}
 	write_unlock_bh(&nf_ct_gre_lock);
 }
@@ -97,10 +97,14 @@
 	kmp = &help->help.ct_pptp_info.keymap[dir];
 	if (*kmp) {
 		/* check whether it's a retransmission */
+		read_lock_bh(&nf_ct_gre_lock);
 		list_for_each_entry(km, &gre_keymap_list, list) {
-			if (gre_key_cmpfn(km, t) && km == *kmp)
+			if (gre_key_cmpfn(km, t) && km == *kmp) {
+				read_unlock_bh(&nf_ct_gre_lock);
 				return 0;
+			}
 		}
+		read_unlock_bh(&nf_ct_gre_lock);
 		pr_debug("trying to override keymap_%s for ct %p\n",
 			 dir == IP_CT_DIR_REPLY ? "reply" : "orig", ct);
 		return -EEXIST;
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 2f9bbc0..1fa306b 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -1193,7 +1193,6 @@
 static int process_sip_response(struct sk_buff *skb,
 				const char **dptr, unsigned int *datalen)
 {
-	static const struct sip_handler *handler;
 	enum ip_conntrack_info ctinfo;
 	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
 	unsigned int matchoff, matchlen;
@@ -1214,6 +1213,8 @@
 	dataoff = matchoff + matchlen + 1;
 
 	for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) {
+		const struct sip_handler *handler;
+
 		handler = &sip_handlers[i];
 		if (handler->response == NULL)
 			continue;
@@ -1228,13 +1229,14 @@
 static int process_sip_request(struct sk_buff *skb,
 			       const char **dptr, unsigned int *datalen)
 {
-	static const struct sip_handler *handler;
 	enum ip_conntrack_info ctinfo;
 	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
 	unsigned int matchoff, matchlen;
 	unsigned int cseq, i;
 
 	for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) {
+		const struct sip_handler *handler;
+
 		handler = &sip_handlers[i];
 		if (handler->request == NULL)
 			continue;
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 9634091..ec0a083 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -215,10 +215,9 @@
 			    time_after(jiffies, (dev->trans_start +
 						 dev->watchdog_timeo))) {
 				char drivername[64];
-				printk(KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit timed out\n",
+				WARN_ONCE(1, KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit timed out\n",
 				       dev->name, netdev_drivername(dev, drivername, 64));
 				dev->tx_timeout(dev);
-				WARN_ON_ONCE(1);
 			}
 			if (!mod_timer(&dev->watchdog_timer,
 				       round_jiffies(jiffies +
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index b1ff16aa..3ddaff4 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -96,8 +96,8 @@
 	struct media media;
 	struct bcbearer_pair bpairs[MAX_BEARERS];
 	struct bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1];
-	struct node_map remains;
-	struct node_map remains_new;
+	struct tipc_node_map remains;
+	struct tipc_node_map remains_new;
 };
 
 /**
@@ -110,7 +110,7 @@
 
 struct bclink {
 	struct link link;
-	struct node node;
+	struct tipc_node node;
 };
 
 
@@ -149,7 +149,7 @@
  * Called with 'node' locked, bc_lock unlocked
  */
 
-static void bclink_set_gap(struct node *n_ptr)
+static void bclink_set_gap(struct tipc_node *n_ptr)
 {
 	struct sk_buff *buf = n_ptr->bclink.deferred_head;
 
@@ -202,7 +202,7 @@
  * Node is locked, bc_lock unlocked.
  */
 
-void tipc_bclink_acknowledge(struct node *n_ptr, u32 acked)
+void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
 {
 	struct sk_buff *crs;
 	struct sk_buff *next;
@@ -250,7 +250,7 @@
  * tipc_net_lock and node lock set
  */
 
-static void bclink_send_ack(struct node *n_ptr)
+static void bclink_send_ack(struct tipc_node *n_ptr)
 {
 	struct link *l_ptr = n_ptr->active_links[n_ptr->addr & 1];
 
@@ -264,7 +264,7 @@
  * tipc_net_lock and node lock set
  */
 
-static void bclink_send_nack(struct node *n_ptr)
+static void bclink_send_nack(struct tipc_node *n_ptr)
 {
 	struct sk_buff *buf;
 	struct tipc_msg *msg;
@@ -308,7 +308,7 @@
  * tipc_net_lock and node lock set
  */
 
-void tipc_bclink_check_gap(struct node *n_ptr, u32 last_sent)
+void tipc_bclink_check_gap(struct tipc_node *n_ptr, u32 last_sent)
 {
 	if (!n_ptr->bclink.supported ||
 	    less_eq(last_sent, mod(n_ptr->bclink.last_in)))
@@ -328,7 +328,7 @@
 
 static void tipc_bclink_peek_nack(u32 dest, u32 sender_tag, u32 gap_after, u32 gap_to)
 {
-	struct node *n_ptr = tipc_node_find(dest);
+	struct tipc_node *n_ptr = tipc_node_find(dest);
 	u32 my_after, my_to;
 
 	if (unlikely(!n_ptr || !tipc_node_is_up(n_ptr)))
@@ -418,7 +418,7 @@
 	static int rx_count = 0;
 #endif
 	struct tipc_msg *msg = buf_msg(buf);
-	struct node* node = tipc_node_find(msg_prevnode(msg));
+	struct tipc_node* node = tipc_node_find(msg_prevnode(msg));
 	u32 next_in;
 	u32 seqno;
 	struct sk_buff *deferred;
@@ -538,7 +538,7 @@
 	return last_sent;
 }
 
-u32 tipc_bclink_acks_missing(struct node *n_ptr)
+u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr)
 {
 	return (n_ptr->bclink.supported &&
 		(tipc_bclink_get_last_sent() != n_ptr->bclink.acked));
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index a2416fa..5aa024b 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -41,12 +41,12 @@
 #define WSIZE 32
 
 /**
- * struct node_map - set of node identifiers
+ * struct tipc_node_map - set of node identifiers
  * @count: # of nodes in set
  * @map: bitmap of node identifiers that are in the set
  */
 
-struct node_map {
+struct tipc_node_map {
 	u32 count;
 	u32 map[MAX_NODES / WSIZE];
 };
@@ -68,7 +68,7 @@
 };
 
 
-struct node;
+struct tipc_node;
 
 extern char tipc_bclink_name[];
 
@@ -77,7 +77,7 @@
  * nmap_add - add a node to a node map
  */
 
-static inline void tipc_nmap_add(struct node_map *nm_ptr, u32 node)
+static inline void tipc_nmap_add(struct tipc_node_map *nm_ptr, u32 node)
 {
 	int n = tipc_node(node);
 	int w = n / WSIZE;
@@ -93,7 +93,7 @@
  * nmap_remove - remove a node from a node map
  */
 
-static inline void tipc_nmap_remove(struct node_map *nm_ptr, u32 node)
+static inline void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node)
 {
 	int n = tipc_node(node);
 	int w = n / WSIZE;
@@ -109,7 +109,7 @@
  * nmap_equal - test for equality of node maps
  */
 
-static inline int tipc_nmap_equal(struct node_map *nm_a, struct node_map *nm_b)
+static inline int tipc_nmap_equal(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b)
 {
 	return !memcmp(nm_a, nm_b, sizeof(*nm_a));
 }
@@ -121,8 +121,8 @@
  * @nm_diff: output node map A-B (i.e. nodes of A that are not in B)
  */
 
-static inline void tipc_nmap_diff(struct node_map *nm_a, struct node_map *nm_b,
-				  struct node_map *nm_diff)
+static inline void tipc_nmap_diff(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b,
+				  struct tipc_node_map *nm_diff)
 {
 	int stop = sizeof(nm_a->map) / sizeof(u32);
 	int w;
@@ -195,12 +195,12 @@
 
 int  tipc_bclink_init(void);
 void tipc_bclink_stop(void);
-void tipc_bclink_acknowledge(struct node *n_ptr, u32 acked);
+void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked);
 int  tipc_bclink_send_msg(struct sk_buff *buf);
 void tipc_bclink_recv_pkt(struct sk_buff *buf);
 u32  tipc_bclink_get_last_sent(void);
-u32  tipc_bclink_acks_missing(struct node *n_ptr);
-void tipc_bclink_check_gap(struct node *n_ptr, u32 seqno);
+u32  tipc_bclink_acks_missing(struct tipc_node *n_ptr);
+void tipc_bclink_check_gap(struct tipc_node *n_ptr, u32 seqno);
 int  tipc_bclink_stats(char *stats_buf, const u32 buf_size);
 int  tipc_bclink_reset_stats(void);
 int  tipc_bclink_set_queue_limits(u32 limit);
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 6a9aba3..a7a3677 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -599,7 +599,7 @@
 	spin_lock_bh(&b_ptr->publ.lock);
 	b_ptr->publ.blocked = 1;
 	list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
-		struct node *n_ptr = l_ptr->owner;
+		struct tipc_node *n_ptr = l_ptr->owner;
 
 		spin_lock_bh(&n_ptr->lock);
 		tipc_link_reset(l_ptr);
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index 6a36b66..ca57348 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -104,7 +104,7 @@
 	u32 continue_count;
 	int active;
 	char net_plane;
-	struct node_map nodes;
+	struct tipc_node_map nodes;
 };
 
 struct bearer_name {
diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c
index 46ee6c5..689fdef 100644
--- a/net/tipc/cluster.c
+++ b/net/tipc/cluster.c
@@ -48,8 +48,8 @@
 				u32 lower, u32 upper);
 static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest);
 
-struct node **tipc_local_nodes = NULL;
-struct node_map tipc_cltr_bcast_nodes = {0,{0,}};
+struct tipc_node **tipc_local_nodes = NULL;
+struct tipc_node_map tipc_cltr_bcast_nodes = {0,{0,}};
 u32 tipc_highest_allowed_slave = 0;
 
 struct cluster *tipc_cltr_create(u32 addr)
@@ -115,7 +115,7 @@
 
 u32 tipc_cltr_next_node(struct cluster *c_ptr, u32 addr)
 {
-	struct node *n_ptr;
+	struct tipc_node *n_ptr;
 	u32 n_num = tipc_node(addr) + 1;
 
 	if (!c_ptr)
@@ -133,7 +133,7 @@
 	return 0;
 }
 
-void tipc_cltr_attach_node(struct cluster *c_ptr, struct node *n_ptr)
+void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr)
 {
 	u32 n_num = tipc_node(n_ptr->addr);
 	u32 max_n_num = tipc_max_nodes;
@@ -196,7 +196,7 @@
  * Uses deterministic and fair algorithm.
  */
 
-struct node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector)
+struct tipc_node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector)
 {
 	u32 n_num;
 	u32 mask = tipc_max_nodes;
@@ -379,7 +379,7 @@
 {
 	struct tipc_msg *msg = buf_msg(buf);
 	struct cluster *c_ptr;
-	struct node *n_ptr;
+	struct tipc_node *n_ptr;
 	unchar *node_table;
 	u32 table_size;
 	u32 router;
@@ -499,7 +499,7 @@
 			 u32 lower, u32 upper)
 {
 	struct sk_buff *buf_copy;
-	struct node *n_ptr;
+	struct tipc_node *n_ptr;
 	u32 n_num;
 	u32 tstop;
 
@@ -534,7 +534,7 @@
 {
 	struct sk_buff *buf_copy;
 	struct cluster *c_ptr;
-	struct node *n_ptr;
+	struct tipc_node *n_ptr;
 	u32 n_num;
 	u32 tstart;
 	u32 tstop;
diff --git a/net/tipc/cluster.h b/net/tipc/cluster.h
index 62df074..333efb0 100644
--- a/net/tipc/cluster.h
+++ b/net/tipc/cluster.h
@@ -54,24 +54,24 @@
 struct cluster {
 	u32 addr;
 	struct _zone *owner;
-	struct node **nodes;
+	struct tipc_node **nodes;
 	u32 highest_node;
 	u32 highest_slave;
 };
 
 
-extern struct node **tipc_local_nodes;
+extern struct tipc_node **tipc_local_nodes;
 extern u32 tipc_highest_allowed_slave;
-extern struct node_map tipc_cltr_bcast_nodes;
+extern struct tipc_node_map tipc_cltr_bcast_nodes;
 
 void tipc_cltr_remove_as_router(struct cluster *c_ptr, u32 router);
 void tipc_cltr_send_ext_routes(struct cluster *c_ptr, u32 dest);
-struct node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector);
+struct tipc_node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector);
 u32 tipc_cltr_select_router(struct cluster *c_ptr, u32 ref);
 void tipc_cltr_recv_routing_table(struct sk_buff *buf);
 struct cluster *tipc_cltr_create(u32 addr);
 void tipc_cltr_delete(struct cluster *c_ptr);
-void tipc_cltr_attach_node(struct cluster *c_ptr, struct node *n_ptr);
+void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr);
 void tipc_cltr_send_slave_routes(struct cluster *c_ptr, u32 dest);
 void tipc_cltr_broadcast(struct sk_buff *buf);
 int tipc_cltr_init(void);
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 1657f0e..74b7d1e 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -193,7 +193,7 @@
 		/* Always accept link here */
 		struct sk_buff *rbuf;
 		struct tipc_media_addr *addr;
-		struct node *n_ptr = tipc_node_find(orig);
+		struct tipc_node *n_ptr = tipc_node_find(orig);
 		int link_fully_up;
 
 		dbg(" in own cluster\n");
diff --git a/net/tipc/link.c b/net/tipc/link.c
index d60113b..dd4c18b 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1155,7 +1155,7 @@
 int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector)
 {
 	struct link *l_ptr;
-	struct node *n_ptr;
+	struct tipc_node *n_ptr;
 	int res = -ELINKCONG;
 
 	read_lock_bh(&tipc_net_lock);
@@ -1226,7 +1226,7 @@
 int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode)
 {
 	struct link *l_ptr;
-	struct node *n_ptr;
+	struct tipc_node *n_ptr;
 	int res;
 	u32 selector = msg_origport(buf_msg(buf)) & 1;
 	u32 dummy;
@@ -1270,7 +1270,7 @@
 	struct tipc_msg *hdr = &sender->publ.phdr;
 	struct link *l_ptr;
 	struct sk_buff *buf;
-	struct node *node;
+	struct tipc_node *node;
 	int res;
 	u32 selector = msg_origport(hdr) & 1;
 
@@ -1364,7 +1364,7 @@
 				   u32 destaddr)
 {
 	struct link *l_ptr;
-	struct node *node;
+	struct tipc_node *node;
 	struct tipc_msg *hdr = &sender->publ.phdr;
 	u32 dsz = msg_data_sz(hdr);
 	u32 max_pkt,fragm_sz,rest;
@@ -1636,7 +1636,7 @@
 
 static void link_reset_all(unsigned long addr)
 {
-	struct node *n_ptr;
+	struct tipc_node *n_ptr;
 	char addr_string[16];
 	u32 i;
 
@@ -1682,7 +1682,7 @@
 
 		/* Handle failure on broadcast link */
 
-		struct node *n_ptr;
+		struct tipc_node *n_ptr;
 		char addr_string[16];
 
 		tipc_printf(TIPC_OUTPUT, "Msg seq number: %u,  ", msg_seqno(msg));
@@ -1843,7 +1843,7 @@
 	read_lock_bh(&tipc_net_lock);
 	while (head) {
 		struct bearer *b_ptr = (struct bearer *)tb_ptr;
-		struct node *n_ptr;
+		struct tipc_node *n_ptr;
 		struct link *l_ptr;
 		struct sk_buff *crs;
 		struct sk_buff *buf = head;
@@ -2935,7 +2935,7 @@
  * Returns pointer to link (or 0 if invalid link name).
  */
 
-static struct link *link_find_link(const char *name, struct node **node)
+static struct link *link_find_link(const char *name, struct tipc_node **node)
 {
 	struct link_name link_name_parts;
 	struct bearer *b_ptr;
@@ -2965,7 +2965,7 @@
 	struct tipc_link_config *args;
 	u32 new_value;
 	struct link *l_ptr;
-	struct node *node;
+	struct tipc_node *node;
 	int res;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_CONFIG))
@@ -3043,7 +3043,7 @@
 {
 	char *link_name;
 	struct link *l_ptr;
-	struct node *node;
+	struct tipc_node *node;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME))
 		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
@@ -3091,7 +3091,7 @@
 {
 	struct print_buf pb;
 	struct link *l_ptr;
-	struct node *node;
+	struct tipc_node *node;
 	char *status;
 	u32 profile_total = 0;
 
@@ -3207,7 +3207,7 @@
 	int res = -EINVAL;
 	struct link *l_ptr;
 	u32 bearer_id;
-	struct node * node;
+	struct tipc_node * node;
 	u32 a;
 
 	a = link_name2addr(name, &bearer_id);
@@ -3249,7 +3249,7 @@
 
 u32 tipc_link_get_max_pkt(u32 dest, u32 selector)
 {
-	struct node *n_ptr;
+	struct tipc_node *n_ptr;
 	struct link *l_ptr;
 	u32 res = MAX_PKT_DEFAULT;
 
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 52f3e7c..6a51e38 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -116,7 +116,7 @@
 	char name[TIPC_MAX_LINK_NAME];
 	struct tipc_media_addr media_addr;
 	struct timer_list timer;
-	struct node *owner;
+	struct tipc_node *owner;
 	struct list_head link_list;
 
 	/* Management and link supervision data */
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h
index b9e7cd3..139882d 100644
--- a/net/tipc/name_table.h
+++ b/net/tipc/name_table.h
@@ -76,7 +76,7 @@
 	u32 node;
 	u32 ref;
 	u32 key;
-	struct node_subscr subscr;
+	struct tipc_node_subscr subscr;
 	struct list_head local_list;
 	struct list_head pport_list;
 	struct publication *node_list_next;
diff --git a/net/tipc/net.c b/net/tipc/net.c
index ec7b04f..7906608 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -118,7 +118,7 @@
 DEFINE_RWLOCK(tipc_net_lock);
 struct network tipc_net = { NULL };
 
-struct node *tipc_net_select_remote_node(u32 addr, u32 ref)
+struct tipc_node *tipc_net_select_remote_node(u32 addr, u32 ref)
 {
 	return tipc_zone_select_remote_node(tipc_net.zones[tipc_zone(addr)], addr, ref);
 }
diff --git a/net/tipc/net.h b/net/tipc/net.h
index d154ac2..de2b9ad 100644
--- a/net/tipc/net.h
+++ b/net/tipc/net.h
@@ -55,7 +55,7 @@
 void tipc_net_remove_as_router(u32 router);
 void tipc_net_send_external_routes(u32 dest);
 void tipc_net_route_msg(struct sk_buff *buf);
-struct node *tipc_net_select_remote_node(u32 addr, u32 ref);
+struct tipc_node *tipc_net_select_remote_node(u32 addr, u32 ref);
 u32 tipc_net_select_router(u32 addr, u32 ref);
 
 int tipc_net_start(u32 addr);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index ee952ad..20d98c5 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -46,11 +46,11 @@
 #include "bearer.h"
 #include "name_distr.h"
 
-void node_print(struct print_buf *buf, struct node *n_ptr, char *str);
-static void node_lost_contact(struct node *n_ptr);
-static void node_established_contact(struct node *n_ptr);
+void node_print(struct print_buf *buf, struct tipc_node *n_ptr, char *str);
+static void node_lost_contact(struct tipc_node *n_ptr);
+static void node_established_contact(struct tipc_node *n_ptr);
 
-struct node *tipc_nodes = NULL;	/* sorted list of nodes within cluster */
+struct tipc_node *tipc_nodes = NULL;	/* sorted list of nodes within cluster */
 
 static DEFINE_SPINLOCK(node_create_lock);
 
@@ -66,11 +66,11 @@
  * but this is a non-trivial change.)
  */
 
-struct node *tipc_node_create(u32 addr)
+struct tipc_node *tipc_node_create(u32 addr)
 {
 	struct cluster *c_ptr;
-	struct node *n_ptr;
-	struct node **curr_node;
+	struct tipc_node *n_ptr;
+	struct tipc_node **curr_node;
 
 	spin_lock_bh(&node_create_lock);
 
@@ -120,7 +120,7 @@
 	return n_ptr;
 }
 
-void tipc_node_delete(struct node *n_ptr)
+void tipc_node_delete(struct tipc_node *n_ptr)
 {
 	if (!n_ptr)
 		return;
@@ -146,7 +146,7 @@
  * Link becomes active (alone or shared) or standby, depending on its priority.
  */
 
-void tipc_node_link_up(struct node *n_ptr, struct link *l_ptr)
+void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr)
 {
 	struct link **active = &n_ptr->active_links[0];
 
@@ -180,7 +180,7 @@
  * node_select_active_links - select active link
  */
 
-static void node_select_active_links(struct node *n_ptr)
+static void node_select_active_links(struct tipc_node *n_ptr)
 {
 	struct link **active = &n_ptr->active_links[0];
 	u32 i;
@@ -208,7 +208,7 @@
  * tipc_node_link_down - handle loss of link
  */
 
-void tipc_node_link_down(struct node *n_ptr, struct link *l_ptr)
+void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr)
 {
 	struct link **active;
 
@@ -235,30 +235,30 @@
 		node_lost_contact(n_ptr);
 }
 
-int tipc_node_has_active_links(struct node *n_ptr)
+int tipc_node_has_active_links(struct tipc_node *n_ptr)
 {
 	return (n_ptr &&
 		((n_ptr->active_links[0]) || (n_ptr->active_links[1])));
 }
 
-int tipc_node_has_redundant_links(struct node *n_ptr)
+int tipc_node_has_redundant_links(struct tipc_node *n_ptr)
 {
 	return (n_ptr->working_links > 1);
 }
 
-static int tipc_node_has_active_routes(struct node *n_ptr)
+static int tipc_node_has_active_routes(struct tipc_node *n_ptr)
 {
 	return (n_ptr && (n_ptr->last_router >= 0));
 }
 
-int tipc_node_is_up(struct node *n_ptr)
+int tipc_node_is_up(struct tipc_node *n_ptr)
 {
 	return (tipc_node_has_active_links(n_ptr) || tipc_node_has_active_routes(n_ptr));
 }
 
-struct node *tipc_node_attach_link(struct link *l_ptr)
+struct tipc_node *tipc_node_attach_link(struct link *l_ptr)
 {
-	struct node *n_ptr = tipc_node_find(l_ptr->addr);
+	struct tipc_node *n_ptr = tipc_node_find(l_ptr->addr);
 
 	if (!n_ptr)
 		n_ptr = tipc_node_create(l_ptr->addr);
@@ -285,7 +285,7 @@
 	return NULL;
 }
 
-void tipc_node_detach_link(struct node *n_ptr, struct link *l_ptr)
+void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr)
 {
 	n_ptr->links[l_ptr->b_ptr->identity] = NULL;
 	tipc_net.zones[tipc_zone(l_ptr->addr)]->links--;
@@ -338,7 +338,7 @@
  *
  */
 
-static void node_established_contact(struct node *n_ptr)
+static void node_established_contact(struct tipc_node *n_ptr)
 {
 	struct cluster *c_ptr;
 
@@ -384,10 +384,10 @@
 				  tipc_highest_allowed_slave);
 }
 
-static void node_lost_contact(struct node *n_ptr)
+static void node_lost_contact(struct tipc_node *n_ptr)
 {
 	struct cluster *c_ptr;
-	struct node_subscr *ns, *tns;
+	struct tipc_node_subscr *ns, *tns;
 	char addr_string[16];
 	u32 i;
 
@@ -466,9 +466,9 @@
  * Called by when cluster local lookup has failed.
  */
 
-struct node *tipc_node_select_next_hop(u32 addr, u32 selector)
+struct tipc_node *tipc_node_select_next_hop(u32 addr, u32 selector)
 {
-	struct node *n_ptr;
+	struct tipc_node *n_ptr;
 	u32 router_addr;
 
 	if (!tipc_addr_domain_valid(addr))
@@ -513,7 +513,7 @@
  * Uses a deterministic and fair algorithm for selecting router node.
  */
 
-u32 tipc_node_select_router(struct node *n_ptr, u32 ref)
+u32 tipc_node_select_router(struct tipc_node *n_ptr, u32 ref)
 {
 	u32 ulim;
 	u32 mask;
@@ -551,7 +551,7 @@
 	return tipc_addr(own_zone(), own_cluster(), r);
 }
 
-void tipc_node_add_router(struct node *n_ptr, u32 router)
+void tipc_node_add_router(struct tipc_node *n_ptr, u32 router)
 {
 	u32 r_num = tipc_node(router);
 
@@ -562,7 +562,7 @@
 	       !n_ptr->routers[n_ptr->last_router]);
 }
 
-void tipc_node_remove_router(struct node *n_ptr, u32 router)
+void tipc_node_remove_router(struct tipc_node *n_ptr, u32 router)
 {
 	u32 r_num = tipc_node(router);
 
@@ -580,7 +580,7 @@
 }
 
 #if 0
-void node_print(struct print_buf *buf, struct node *n_ptr, char *str)
+void node_print(struct print_buf *buf, struct tipc_node *n_ptr, char *str)
 {
 	u32 i;
 
@@ -597,7 +597,7 @@
 
 u32 tipc_available_nodes(const u32 domain)
 {
-	struct node *n_ptr;
+	struct tipc_node *n_ptr;
 	u32 cnt = 0;
 
 	read_lock_bh(&tipc_net_lock);
@@ -615,7 +615,7 @@
 {
 	u32 domain;
 	struct sk_buff *buf;
-	struct node *n_ptr;
+	struct tipc_node *n_ptr;
 	struct tipc_node_info node_info;
 	u32 payload_size;
 
@@ -667,7 +667,7 @@
 {
 	u32 domain;
 	struct sk_buff *buf;
-	struct node *n_ptr;
+	struct tipc_node *n_ptr;
 	struct tipc_link_info link_info;
 	u32 payload_size;
 
diff --git a/net/tipc/node.h b/net/tipc/node.h
index cd18826..6f990da 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -43,7 +43,7 @@
 #include "bearer.h"
 
 /**
- * struct node - TIPC node structure
+ * struct tipc_node - TIPC node structure
  * @addr: network address of node
  * @lock: spinlock governing access to structure
  * @owner: pointer to cluster that node belongs to
@@ -68,11 +68,11 @@
  *    @defragm: list of partially reassembled b'cast message fragments from node
  */
 
-struct node {
+struct tipc_node {
 	u32 addr;
 	spinlock_t lock;
 	struct cluster *owner;
-	struct node *next;
+	struct tipc_node *next;
 	struct list_head nsub;
 	struct link *active_links[2];
 	struct link *links[MAX_BEARERS];
@@ -94,26 +94,26 @@
 	} bclink;
 };
 
-extern struct node *tipc_nodes;
+extern struct tipc_node *tipc_nodes;
 extern u32 tipc_own_tag;
 
-struct node *tipc_node_create(u32 addr);
-void tipc_node_delete(struct node *n_ptr);
-struct node *tipc_node_attach_link(struct link *l_ptr);
-void tipc_node_detach_link(struct node *n_ptr, struct link *l_ptr);
-void tipc_node_link_down(struct node *n_ptr, struct link *l_ptr);
-void tipc_node_link_up(struct node *n_ptr, struct link *l_ptr);
-int tipc_node_has_active_links(struct node *n_ptr);
-int tipc_node_has_redundant_links(struct node *n_ptr);
-u32 tipc_node_select_router(struct node *n_ptr, u32 ref);
-struct node *tipc_node_select_next_hop(u32 addr, u32 selector);
-int tipc_node_is_up(struct node *n_ptr);
-void tipc_node_add_router(struct node *n_ptr, u32 router);
-void tipc_node_remove_router(struct node *n_ptr, u32 router);
+struct tipc_node *tipc_node_create(u32 addr);
+void tipc_node_delete(struct tipc_node *n_ptr);
+struct tipc_node *tipc_node_attach_link(struct link *l_ptr);
+void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr);
+void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr);
+void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr);
+int tipc_node_has_active_links(struct tipc_node *n_ptr);
+int tipc_node_has_redundant_links(struct tipc_node *n_ptr);
+u32 tipc_node_select_router(struct tipc_node *n_ptr, u32 ref);
+struct tipc_node *tipc_node_select_next_hop(u32 addr, u32 selector);
+int tipc_node_is_up(struct tipc_node *n_ptr);
+void tipc_node_add_router(struct tipc_node *n_ptr, u32 router);
+void tipc_node_remove_router(struct tipc_node *n_ptr, u32 router);
 struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space);
 struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space);
 
-static inline struct node *tipc_node_find(u32 addr)
+static inline struct tipc_node *tipc_node_find(u32 addr)
 {
 	if (likely(in_own_cluster(addr)))
 		return tipc_local_nodes[tipc_node(addr)];
@@ -126,19 +126,19 @@
 	return NULL;
 }
 
-static inline struct node *tipc_node_select(u32 addr, u32 selector)
+static inline struct tipc_node *tipc_node_select(u32 addr, u32 selector)
 {
 	if (likely(in_own_cluster(addr)))
 		return tipc_local_nodes[tipc_node(addr)];
 	return tipc_node_select_next_hop(addr, selector);
 }
 
-static inline void tipc_node_lock(struct node *n_ptr)
+static inline void tipc_node_lock(struct tipc_node *n_ptr)
 {
 	spin_lock_bh(&n_ptr->lock);
 }
 
-static inline void tipc_node_unlock(struct node *n_ptr)
+static inline void tipc_node_unlock(struct tipc_node *n_ptr)
 {
 	spin_unlock_bh(&n_ptr->lock);
 }
diff --git a/net/tipc/node_subscr.c b/net/tipc/node_subscr.c
index 8ecbd0f..19194d4 100644
--- a/net/tipc/node_subscr.c
+++ b/net/tipc/node_subscr.c
@@ -44,7 +44,7 @@
  * tipc_nodesub_subscribe - create "node down" subscription for specified node
  */
 
-void tipc_nodesub_subscribe(struct node_subscr *node_sub, u32 addr,
+void tipc_nodesub_subscribe(struct tipc_node_subscr *node_sub, u32 addr,
 		       void *usr_handle, net_ev_handler handle_down)
 {
 	if (addr == tipc_own_addr) {
@@ -69,7 +69,7 @@
  * tipc_nodesub_unsubscribe - cancel "node down" subscription (if any)
  */
 
-void tipc_nodesub_unsubscribe(struct node_subscr *node_sub)
+void tipc_nodesub_unsubscribe(struct tipc_node_subscr *node_sub)
 {
 	if (!node_sub->node)
 		return;
diff --git a/net/tipc/node_subscr.h b/net/tipc/node_subscr.h
index 5f3f585..006ed73 100644
--- a/net/tipc/node_subscr.h
+++ b/net/tipc/node_subscr.h
@@ -42,22 +42,22 @@
 typedef void (*net_ev_handler) (void *usr_handle);
 
 /**
- * struct node_subscr - "node down" subscription entry
+ * struct tipc_node_subscr - "node down" subscription entry
  * @node: ptr to node structure of interest (or NULL, if none)
  * @handle_node_down: routine to invoke when node fails
  * @usr_handle: argument to pass to routine when node fails
  * @nodesub_list: adjacent entries in list of subscriptions for the node
  */
 
-struct node_subscr {
-	struct node *node;
+struct tipc_node_subscr {
+	struct tipc_node *node;
 	net_ev_handler handle_node_down;
 	void *usr_handle;
 	struct list_head nodesub_list;
 };
 
-void tipc_nodesub_subscribe(struct node_subscr *node_sub, u32 addr,
+void tipc_nodesub_subscribe(struct tipc_node_subscr *node_sub, u32 addr,
 			    void *usr_handle, net_ev_handler handle_down);
-void tipc_nodesub_unsubscribe(struct node_subscr *node_sub);
+void tipc_nodesub_unsubscribe(struct tipc_node_subscr *node_sub);
 
 #endif
diff --git a/net/tipc/port.h b/net/tipc/port.h
index e5f8c16..ff31ee4 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -105,7 +105,7 @@
 	u32 probing_interval;
 	u32 last_in_seqno;
 	struct timer_list timer;
-	struct node_subscr subscription;
+	struct tipc_node_subscr subscription;
 };
 
 extern spinlock_t tipc_port_list_lock;
diff --git a/net/tipc/zone.c b/net/tipc/zone.c
index 3506f85..2c01ba2 100644
--- a/net/tipc/zone.c
+++ b/net/tipc/zone.c
@@ -111,10 +111,10 @@
 	}
 }
 
-struct node *tipc_zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref)
+struct tipc_node *tipc_zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref)
 {
 	struct cluster *c_ptr;
-	struct node *n_ptr;
+	struct tipc_node *n_ptr;
 	u32 c_num;
 
 	if (!z_ptr)
diff --git a/net/tipc/zone.h b/net/tipc/zone.h
index 6e7a08d..7bdc340 100644
--- a/net/tipc/zone.h
+++ b/net/tipc/zone.h
@@ -54,7 +54,7 @@
 	u32 links;
 };
 
-struct node *tipc_zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref);
+struct tipc_node *tipc_zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref);
 u32 tipc_zone_select_router(struct _zone *z_ptr, u32 addr, u32 ref);
 void tipc_zone_remove_as_router(struct _zone *z_ptr, u32 router);
 void tipc_zone_send_external_routes(struct _zone *z_ptr, u32 dest);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 46914b7..b7754b1 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1077,6 +1077,7 @@
 	struct hlist_head *chain = policy_hash_bysel(&pol->selector,
 						     pol->family, dir);
 
+	list_add_tail(&pol->bytype, &xfrm_policy_bytype[pol->type]);
 	hlist_add_head(&pol->bydst, chain);
 	hlist_add_head(&pol->byidx, xfrm_policy_byidx+idx_hash(pol->index));
 	xfrm_policy_count[dir]++;
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 7bd62f6..0a8f09c 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -858,6 +858,7 @@
 
 		if (km_query(x, tmpl, pol) == 0) {
 			x->km.state = XFRM_STATE_ACQ;
+			list_add_tail(&x->all, &xfrm_state_all);
 			hlist_add_head(&x->bydst, xfrm_state_bydst+h);
 			h = xfrm_src_hash(daddr, saddr, family);
 			hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
@@ -1055,6 +1056,7 @@
 		xfrm_state_hold(x);
 		x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
 		add_timer(&x->timer);
+		list_add_tail(&x->all, &xfrm_state_all);
 		hlist_add_head(&x->bydst, xfrm_state_bydst+h);
 		h = xfrm_src_hash(daddr, saddr, family);
 		hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index b52f923..d11a815 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -811,11 +811,12 @@
 	/* Check the validity of the new context. */
 	if (!policydb_context_isvalid(pol, ctx)) {
 		rc = -EINVAL;
-		context_destroy(ctx);
 		goto out;
 	}
 	rc = 0;
 out:
+	if (rc)
+		context_destroy(ctx);
 	return rc;
 }
 
@@ -868,8 +869,7 @@
 	} else if (rc)
 		goto out;
 	rc = sidtab_context_to_sid(&sidtab, &context, sid);
-	if (rc)
-		context_destroy(&context);
+	context_destroy(&context);
 out:
 	read_unlock(&policy_rwlock);
 	kfree(scontext2);
diff --git a/sound/Kconfig b/sound/Kconfig
index a37bee0..8ebf512 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -91,6 +91,9 @@
 
 endif # !M68K
 
+endif # SOUND
+
+# AC97_BUS is used from both sound and ucb1400
 config AC97_BUS
 	tristate
 	help
@@ -99,4 +102,3 @@
 	  sound although they're sharing the AC97 bus. Concerned drivers
 	  should "select" this.
 
-endif # SOUND
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index 199cca3..714b3ba 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -215,7 +215,7 @@
 static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_out = {
 	.name			= "AC97 PCM out",
 	.dev_addr		= __PREG(PCDR),
-	.drcmr			= &DRCMRTXPCDR,
+	.drcmr			= &DRCMR(12),
 	.dcmd			= DCMD_INCSRCADDR | DCMD_FLOWTRG |
 				  DCMD_BURST32 | DCMD_WIDTH4,
 };
@@ -223,7 +223,7 @@
 static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_in = {
 	.name			= "AC97 PCM in",
 	.dev_addr		= __PREG(PCDR),
-	.drcmr			= &DRCMRRXPCDR,
+	.drcmr			= &DRCMR(11),
 	.dcmd			= DCMD_INCTRGADDR | DCMD_FLOWSRC |
 				  DCMD_BURST32 | DCMD_WIDTH4,
 };
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 0a53f72..fa69faa 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -18,13 +18,13 @@
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
 
 #include <asm/mach-types.h>
-#include <asm/hardware/scoop.h>
 #include <mach/pxa-regs.h>
 #include <mach/hardware.h>
 #include <mach/corgi.h>
@@ -54,8 +54,8 @@
 	switch (corgi_jack_func) {
 	case CORGI_HP:
 		/* set = unmute headphone */
-		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
-		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
+		gpio_set_value(CORGI_GPIO_MUTE_L, 1);
+		gpio_set_value(CORGI_GPIO_MUTE_R, 1);
 		snd_soc_dapm_disable_pin(codec, "Mic Jack");
 		snd_soc_dapm_disable_pin(codec, "Line Jack");
 		snd_soc_dapm_enable_pin(codec, "Headphone Jack");
@@ -63,24 +63,24 @@
 		break;
 	case CORGI_MIC:
 		/* reset = mute headphone */
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
+		gpio_set_value(CORGI_GPIO_MUTE_L, 0);
+		gpio_set_value(CORGI_GPIO_MUTE_R, 0);
 		snd_soc_dapm_enable_pin(codec, "Mic Jack");
 		snd_soc_dapm_disable_pin(codec, "Line Jack");
 		snd_soc_dapm_disable_pin(codec, "Headphone Jack");
 		snd_soc_dapm_disable_pin(codec, "Headset Jack");
 		break;
 	case CORGI_LINE:
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
+		gpio_set_value(CORGI_GPIO_MUTE_L, 0);
+		gpio_set_value(CORGI_GPIO_MUTE_R, 0);
 		snd_soc_dapm_disable_pin(codec, "Mic Jack");
 		snd_soc_dapm_enable_pin(codec, "Line Jack");
 		snd_soc_dapm_disable_pin(codec, "Headphone Jack");
 		snd_soc_dapm_disable_pin(codec, "Headset Jack");
 		break;
 	case CORGI_HEADSET:
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
-		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
+		gpio_set_value(CORGI_GPIO_MUTE_L, 0);
+		gpio_set_value(CORGI_GPIO_MUTE_R, 1);
 		snd_soc_dapm_enable_pin(codec, "Mic Jack");
 		snd_soc_dapm_disable_pin(codec, "Line Jack");
 		snd_soc_dapm_disable_pin(codec, "Headphone Jack");
@@ -114,8 +114,8 @@
 	struct snd_soc_codec *codec = rtd->socdev->codec;
 
 	/* set = unmute headphone */
-	set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
-	set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
+	gpio_set_value(CORGI_GPIO_MUTE_L, 1);
+	gpio_set_value(CORGI_GPIO_MUTE_R, 1);
 	return 0;
 }
 
@@ -218,22 +218,14 @@
 static int corgi_amp_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *k, int event)
 {
-	if (SND_SOC_DAPM_EVENT_ON(event))
-		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON);
-	else
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON);
-
+	gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event));
 	return 0;
 }
 
 static int corgi_mic_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *k, int event)
 {
-	if (SND_SOC_DAPM_EVENT_ON(event))
-		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS);
-	else
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS);
-
+	gpio_set_value(CORGI_GPIO_MIC_BIAS, SND_SOC_DAPM_EVENT_ON(event));
 	return 0;
 }
 
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index d94a495..ac8f227 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -244,7 +244,7 @@
 static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = {
 	.name			= "AC97 PCM Stereo out",
 	.dev_addr		= __PREG(PCDR),
-	.drcmr			= &DRCMRTXPCDR,
+	.drcmr			= &DRCMR(12),
 	.dcmd			= DCMD_INCSRCADDR | DCMD_FLOWTRG |
 				  DCMD_BURST32 | DCMD_WIDTH4,
 };
@@ -252,7 +252,7 @@
 static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = {
 	.name			= "AC97 PCM Stereo in",
 	.dev_addr		= __PREG(PCDR),
-	.drcmr			= &DRCMRRXPCDR,
+	.drcmr			= &DRCMR(11),
 	.dcmd			= DCMD_INCTRGADDR | DCMD_FLOWSRC |
 				  DCMD_BURST32 | DCMD_WIDTH4,
 };
@@ -260,7 +260,7 @@
 static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = {
 	.name			= "AC97 Aux PCM (Slot 5) Mono out",
 	.dev_addr		= __PREG(MODR),
-	.drcmr			= &DRCMRTXMODR,
+	.drcmr			= &DRCMR(10),
 	.dcmd			= DCMD_INCSRCADDR | DCMD_FLOWTRG |
 				  DCMD_BURST16 | DCMD_WIDTH2,
 };
@@ -268,7 +268,7 @@
 static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = {
 	.name			= "AC97 Aux PCM (Slot 5) Mono in",
 	.dev_addr		= __PREG(MODR),
-	.drcmr			= &DRCMRRXMODR,
+	.drcmr			= &DRCMR(9),
 	.dcmd			= DCMD_INCTRGADDR | DCMD_FLOWSRC |
 				  DCMD_BURST16 | DCMD_WIDTH2,
 };
@@ -276,7 +276,7 @@
 static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = {
 	.name			= "AC97 Mic PCM (Slot 6) Mono in",
 	.dev_addr		= __PREG(MCDR),
-	.drcmr			= &DRCMRRXMCDR,
+	.drcmr			= &DRCMR(8),
 	.dcmd			= DCMD_INCTRGADDR | DCMD_FLOWSRC |
 				  DCMD_BURST16 | DCMD_WIDTH2,
 };
@@ -293,14 +293,6 @@
 static int pxa2xx_ac97_resume(struct platform_device *pdev,
 	struct snd_soc_dai *dai)
 {
-	pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
-	pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
-	pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
-	pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
-#ifdef CONFIG_PXA27x
-	/* Use GPIO 113 as AC97 Reset on Bulverde */
-	pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
-#endif
 	clk_enable(ac97_clk);
 	return 0;
 }
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index c796b18..ad4c31dd 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -30,6 +30,46 @@
 #include "pxa2xx-pcm.h"
 #include "pxa2xx-i2s.h"
 
+/*
+ * I2S Controller Register and Bit Definitions
+ */
+#define SACR0		__REG(0x40400000)  /* Global Control Register */
+#define SACR1		__REG(0x40400004)  /* Serial Audio I 2 S/MSB-Justified Control Register */
+#define SASR0		__REG(0x4040000C)  /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */
+#define SAIMR		__REG(0x40400014)  /* Serial Audio Interrupt Mask Register */
+#define SAICR		__REG(0x40400018)  /* Serial Audio Interrupt Clear Register */
+#define SADIV		__REG(0x40400060)  /* Audio Clock Divider Register. */
+#define SADR		__REG(0x40400080)  /* Serial Audio Data Register (TX and RX FIFO access Register). */
+
+#define SACR0_RFTH(x)	((x) << 12)	/* Rx FIFO Interrupt or DMA Trigger Threshold */
+#define SACR0_TFTH(x)	((x) << 8)	/* Tx FIFO Interrupt or DMA Trigger Threshold */
+#define SACR0_STRF	(1 << 5)	/* FIFO Select for EFWR Special Function */
+#define SACR0_EFWR	(1 << 4)	/* Enable EFWR Function  */
+#define SACR0_RST	(1 << 3)	/* FIFO, i2s Register Reset */
+#define SACR0_BCKD	(1 << 2) 	/* Bit Clock Direction */
+#define SACR0_ENB	(1 << 0)	/* Enable I2S Link */
+#define SACR1_ENLBF	(1 << 5)	/* Enable Loopback */
+#define SACR1_DRPL	(1 << 4) 	/* Disable Replaying Function */
+#define SACR1_DREC	(1 << 3)	/* Disable Recording Function */
+#define SACR1_AMSL	(1 << 0)	/* Specify Alternate Mode */
+
+#define SASR0_I2SOFF	(1 << 7)	/* Controller Status */
+#define SASR0_ROR	(1 << 6)	/* Rx FIFO Overrun */
+#define SASR0_TUR	(1 << 5)	/* Tx FIFO Underrun */
+#define SASR0_RFS	(1 << 4)	/* Rx FIFO Service Request */
+#define SASR0_TFS	(1 << 3)	/* Tx FIFO Service Request */
+#define SASR0_BSY	(1 << 2)	/* I2S Busy */
+#define SASR0_RNE	(1 << 1)	/* Rx FIFO Not Empty */
+#define SASR0_TNF	(1 << 0) 	/* Tx FIFO Not Empty */
+
+#define SAICR_ROR	(1 << 6)	/* Clear Rx FIFO Overrun Interrupt */
+#define SAICR_TUR	(1 << 5)	/* Clear Tx FIFO Underrun Interrupt */
+
+#define SAIMR_ROR	(1 << 6)	/* Enable Rx FIFO Overrun Condition Interrupt */
+#define SAIMR_TUR	(1 << 5)	/* Enable Tx FIFO Underrun Condition Interrupt */
+#define SAIMR_RFS	(1 << 4)	/* Enable Rx FIFO Service Interrupt */
+#define SAIMR_TFS	(1 << 3)	/* Enable Tx FIFO Service Interrupt */
+
 struct pxa_i2s_port {
 	u32 sadiv;
 	u32 sacr0;
@@ -44,7 +84,7 @@
 static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = {
 	.name			= "I2S PCM Stereo out",
 	.dev_addr		= __PREG(SADR),
-	.drcmr			= &DRCMRTXSADR,
+	.drcmr			= &DRCMR(3),
 	.dcmd			= DCMD_INCSRCADDR | DCMD_FLOWTRG |
 				  DCMD_BURST32 | DCMD_WIDTH4,
 };
@@ -52,7 +92,7 @@
 static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_in = {
 	.name			= "I2S PCM Stereo in",
 	.dev_addr		= __PREG(SADR),
-	.drcmr			= &DRCMRRXSADR,
+	.drcmr			= &DRCMR(2),
 	.dcmd			= DCMD_INCTRGADDR | DCMD_FLOWSRC |
 				  DCMD_BURST32 | DCMD_WIDTH4,
 };
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 37cb768..b89a3ed 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -19,16 +19,15 @@
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
 
 #include <asm/mach-types.h>
-#include <asm/hardware/scoop.h>
 #include <mach/pxa-regs.h>
 #include <mach/hardware.h>
-#include <mach/akita.h>
 #include <mach/spitz.h>
 #include "../codecs/wm8750.h"
 #include "pxa2xx-pcm.h"
@@ -63,8 +62,8 @@
 		snd_soc_dapm_disable_pin(codec, "Mic Jack");
 		snd_soc_dapm_disable_pin(codec, "Line Jack");
 		snd_soc_dapm_enable_pin(codec, "Headphone Jack");
-		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
-		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
+		gpio_set_value(SPITZ_GPIO_MUTE_L, 1);
+		gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
 		break;
 	case SPITZ_MIC:
 		/* enable mic jack and bias, mute hp */
@@ -72,8 +71,8 @@
 		snd_soc_dapm_disable_pin(codec, "Headset Jack");
 		snd_soc_dapm_disable_pin(codec, "Line Jack");
 		snd_soc_dapm_enable_pin(codec, "Mic Jack");
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
+		gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
+		gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
 		break;
 	case SPITZ_LINE:
 		/* enable line jack, disable mic bias and mute hp */
@@ -81,8 +80,8 @@
 		snd_soc_dapm_disable_pin(codec, "Headset Jack");
 		snd_soc_dapm_disable_pin(codec, "Mic Jack");
 		snd_soc_dapm_enable_pin(codec, "Line Jack");
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
+		gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
+		gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
 		break;
 	case SPITZ_HEADSET:
 		/* enable and unmute headset jack enable mic bias, mute L hp */
@@ -90,8 +89,8 @@
 		snd_soc_dapm_enable_pin(codec, "Mic Jack");
 		snd_soc_dapm_disable_pin(codec, "Line Jack");
 		snd_soc_dapm_enable_pin(codec, "Headset Jack");
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
-		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
+		gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
+		gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
 		break;
 	case SPITZ_HP_OFF:
 
@@ -100,8 +99,8 @@
 		snd_soc_dapm_disable_pin(codec, "Headset Jack");
 		snd_soc_dapm_disable_pin(codec, "Mic Jack");
 		snd_soc_dapm_disable_pin(codec, "Line Jack");
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
+		gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
+		gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
 		break;
 	}
 	snd_soc_dapm_sync(codec);
@@ -215,23 +214,14 @@
 static int spitz_mic_bias(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *k, int event)
 {
-	if (machine_is_borzoi() || machine_is_spitz()) {
-		if (SND_SOC_DAPM_EVENT_ON(event))
-			set_scoop_gpio(&spitzscoop2_device.dev,
-				SPITZ_SCP2_MIC_BIAS);
-		else
-			reset_scoop_gpio(&spitzscoop2_device.dev,
-				SPITZ_SCP2_MIC_BIAS);
-	}
+	if (machine_is_borzoi() || machine_is_spitz())
+		gpio_set_value(SPITZ_GPIO_MIC_BIAS,
+				SND_SOC_DAPM_EVENT_ON(event));
 
-	if (machine_is_akita()) {
-		if (SND_SOC_DAPM_EVENT_ON(event))
-			akita_set_ioexp(&akitaioexp_device.dev,
-				AKITA_IOEXP_MIC_BIAS);
-		else
-			akita_reset_ioexp(&akitaioexp_device.dev,
-				AKITA_IOEXP_MIC_BIAS);
-	}
+	if (machine_is_akita())
+		gpio_set_value(AKITA_GPIO_MIC_BIAS,
+				SND_SOC_DAPM_EVENT_ON(event));
+
 	return 0;
 }