[kernel] r10624 - in dists/trunk/linux-2.6/debian/patches: bugfix bugfix/all series

Maximilian Attems maks at alioth.debian.org
Thu Feb 21 14:20:51 UTC 2008


Author: maks
Date: Thu Feb 21 14:20:50 2008
New Revision: 10624

Log:
update to 2.6.25-rc2-git5

nuke merged sata_mv-platform_driver.patch
no further conflicts


Added:
   dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.25-rc2-git5
Removed:
   dists/trunk/linux-2.6/debian/patches/bugfix/sata_mv-platform_driver.patch
Modified:
   dists/trunk/linux-2.6/debian/patches/series/1~experimental.1

Added: dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.25-rc2-git5
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.25-rc2-git5	Thu Feb 21 14:20:50 2008
@@ -0,0 +1,27588 @@
+diff --git a/Documentation/i386/IO-APIC.txt b/Documentation/i386/IO-APIC.txt
+index 435e69e..f951666 100644
+--- a/Documentation/i386/IO-APIC.txt
++++ b/Documentation/i386/IO-APIC.txt
+@@ -1,12 +1,14 @@
+ Most (all) Intel-MP compliant SMP boards have the so-called 'IO-APIC',
+-which is an enhanced interrupt controller, it enables us to route
+-hardware interrupts to multiple CPUs, or to CPU groups.
++which is an enhanced interrupt controller. It enables us to route
++hardware interrupts to multiple CPUs, or to CPU groups. Without an
++IO-APIC, interrupts from hardware will be delivered only to the
++CPU which boots the operating system (usually CPU#0).
+ 
+ Linux supports all variants of compliant SMP boards, including ones with
+-multiple IO-APICs. (multiple IO-APICs are used in high-end servers to
+-distribute IRQ load further).
++multiple IO-APICs. Multiple IO-APICs are used in high-end servers to
++distribute IRQ load further.
+ 
+-There are (a few) known breakages in certain older boards, which bugs are
++There are (a few) known breakages in certain older boards, such bugs are
+ usually worked around by the kernel. If your MP-compliant SMP board does
+ not boot Linux, then consult the linux-smp mailing list archives first.
+ 
+@@ -28,18 +30,18 @@ If your box boots fine with enabled IO-APIC IRQs, then your
+   hell:~>
+   <----------------------------
+ 
+-some interrupts are still listed as 'XT PIC', but this is not a problem,
++Some interrupts are still listed as 'XT PIC', but this is not a problem;
+ none of those IRQ sources is performance-critical.
+ 
+ 
+-in the unlikely case that your board does not create a working mp-table,
++In the unlikely case that your board does not create a working mp-table,
+ you can use the pirq= boot parameter to 'hand-construct' IRQ entries. This
+-is nontrivial though and cannot be automated. One sample /etc/lilo.conf
++is non-trivial though and cannot be automated. One sample /etc/lilo.conf
+ entry:
+ 
+ 	append="pirq=15,11,10"
+ 
+-the actual numbers depend on your system, on your PCI cards and on their
++The actual numbers depend on your system, on your PCI cards and on their
+ PCI slot position. Usually PCI slots are 'daisy chained' before they are
+ connected to the PCI chipset IRQ routing facility (the incoming PIRQ1-4
+ lines):
+@@ -54,7 +56,7 @@ lines):
+      PIRQ1 ----| |-  `----| |-  `----| |-  `----| |--------| |
+                `-'        `-'        `-'        `-'        `-'
+ 
+-every PCI card emits a PCI IRQ, which can be INTA,INTB,INTC,INTD:
++Every PCI card emits a PCI IRQ, which can be INTA, INTB, INTC or INTD:
+ 
+                                ,-.
+                          INTD--| |
+@@ -95,21 +97,21 @@ card (IRQ11) in Slot3, and have Slot1 empty:
+ [value '0' is a generic 'placeholder', reserved for empty (or non-IRQ emitting)
+ slots.]
+ 
+-generally, it's always possible to find out the correct pirq= settings, just
++Generally, it's always possible to find out the correct pirq= settings, just
+ permute all IRQ numbers properly ... it will take some time though. An
+ 'incorrect' pirq line will cause the booting process to hang, or a device
+-won't function properly (if it's inserted as eg. a module).
++won't function properly (e.g. if it's inserted as a module).
+ 
+-If you have 2 PCI buses, then you can use up to 8 pirq values. Although such
++If you have 2 PCI buses, then you can use up to 8 pirq values, although such
+ boards tend to have a good configuration.
+ 
+ Be prepared that it might happen that you need some strange pirq line:
+ 
+ 	append="pirq=0,0,0,0,0,0,9,11"
+ 
+-use smart try-and-err techniques to find out the correct pirq line ...
++Use smart trial-and-error techniques to find out the correct pirq line ...
+ 
+-good luck and mail to linux-smp at vger.kernel.org or
++Good luck and mail to linux-smp at vger.kernel.org or
+ linux-kernel at vger.kernel.org if you have any problems that are not covered
+ by this document.
+ 
+diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
+index a4fc7fc..9a5b665 100644
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -950,6 +950,41 @@ and is between 256 and 4096 characters. It is defined in the file
+ 			when set.
+ 			Format: <int>
+ 
++	libata.force=	[LIBATA] Force configurations.  The format is comma
++			separated list of "[ID:]VAL" where ID is
++			PORT[:DEVICE].  PORT and DEVICE are decimal numbers
++			matching port, link or device.  Basically, it matches
++			the ATA ID string printed on console by libata.  If
++			the whole ID part is omitted, the last PORT and DEVICE
++			values are used.  If ID hasn't been specified yet, the
++			configuration applies to all ports, links and devices.
++
++			If only DEVICE is omitted, the parameter applies to
++			the port and all links and devices behind it.  DEVICE
++			number of 0 either selects the first device or the
++			first fan-out link behind PMP device.  It does not
++			select the host link.  DEVICE number of 15 selects the
++			host link and device attached to it.
++
++			The VAL specifies the configuration to force.  As long
++			as there's no ambiguity shortcut notation is allowed.
++			For example, both 1.5 and 1.5G would work for 1.5Gbps.
++			The following configurations can be forced.
++
++			* Cable type: 40c, 80c, short40c, unk, ign or sata.
++			  Any ID with matching PORT is used.
++
++			* SATA link speed limit: 1.5Gbps or 3.0Gbps.
++
++			* Transfer mode: pio[0-7], mwdma[0-4] and udma[0-7].
++			  udma[/][16,25,33,44,66,100,133] notation is also
++			  allowed.
++
++			* [no]ncq: Turn on or off NCQ.
++
++			If there are multiple matching configurations changing
++			the same attribute, the last one is used.
++
+ 	load_ramdisk=	[RAM] List of ramdisks to load from floppy
+ 			See Documentation/ramdisk.txt.
+ 
+@@ -1056,8 +1091,6 @@ and is between 256 and 4096 characters. It is defined in the file
+ 			[SCSI] Maximum number of LUNs received.
+ 			Should be between 1 and 16384.
+ 
+-	mca-pentium	[BUGS=X86-32]
+-
+ 	mcatest=	[IA-64]
+ 
+ 	mce		[X86-32] Machine Check Exception
+diff --git a/Documentation/networking/tcp.txt b/Documentation/networking/tcp.txt
+index 0121edc..7d11bb5 100644
+--- a/Documentation/networking/tcp.txt
++++ b/Documentation/networking/tcp.txt
+@@ -1,7 +1,7 @@
+ TCP protocol
+ ============
+ 
+-Last updated: 21 June 2005
++Last updated: 9 February 2008
+ 
+ Contents
+ ========
+@@ -52,9 +52,9 @@ research and RFC's before developing new modules.
+ The method that is used to determine which congestion control mechanism is
+ determined by the setting of the sysctl net.ipv4.tcp_congestion_control.
+ The default congestion control will be the last one registered (LIFO);
+-so if you built everything as modules. the default will be reno. If you
+-build with the default's from Kconfig, then BIC will be builtin (not a module)
+-and it will end up the default.
++so if you built everything as modules, the default will be reno. If you
++build with the defaults from Kconfig, then CUBIC will be builtin (not a
++module) and it will end up the default.
+ 
+ If you really want a particular default value then you will need
+ to set it with the sysctl.  If you use a sysctl, the module will be autoloaded
+diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
+index 6a8469f..f40e092 100644
+--- a/Documentation/video4linux/CARDLIST.em28xx
++++ b/Documentation/video4linux/CARDLIST.em28xx
+@@ -8,7 +8,7 @@
+   7 -> Leadtek Winfast USB II                   (em2800)
+   8 -> Kworld USB2800                           (em2800)
+   9 -> Pinnacle Dazzle DVC 90/DVC 100           (em2820/em2840) [2304:0207,2304:021a]
+- 10 -> Hauppauge WinTV HVR 900                  (em2880)        [2040:6500]
++ 10 -> Hauppauge WinTV HVR 900                  (em2880)        [2040:6500,2040:6502]
+  11 -> Terratec Hybrid XS                       (em2880)        [0ccd:0042]
+  12 -> Kworld PVR TV 2800 RF                    (em2820/em2840)
+  13 -> Terratec Prodigy XS                      (em2880)        [0ccd:0047]
+diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
+index 5d3b6b4..0424901 100644
+--- a/Documentation/video4linux/CARDLIST.saa7134
++++ b/Documentation/video4linux/CARDLIST.saa7134
+@@ -92,9 +92,9 @@
+  91 -> AVerMedia A169 B                         [1461:7360]
+  92 -> AVerMedia A169 B1                        [1461:6360]
+  93 -> Medion 7134 Bridge #2                    [16be:0005]
+- 94 -> LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB [5168:3306,5168:3502,4e42:3502]
++ 94 -> LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB [5168:3306,5168:3502,5168:3307,4e42:3502]
+  95 -> LifeView FlyVIDEO3000 (NTSC)             [5169:0138]
+- 96 -> Medion Md8800 Quadro                     [16be:0007,16be:0008]
++ 96 -> Medion Md8800 Quadro                     [16be:0007,16be:0008,16be:000d]
+  97 -> LifeView FlyDVB-S /Acorp TV134DS         [5168:0300,4e42:0300]
+  98 -> Proteus Pro 2309                         [0919:2003]
+  99 -> AVerMedia TV Hybrid A16AR                [1461:2c00]
+@@ -129,3 +129,5 @@
+ 128 -> Beholder BeholdTV Columbus TVFM          [0000:5201]
+ 129 -> Beholder BeholdTV 607 / BeholdTV 609     [5ace:6070,5ace:6071,5ace:6072,5ace:6073,5ace:6090,5ace:6091,5ace:6092,5ace:6093]
+ 130 -> Beholder BeholdTV M6 / BeholdTV M6 Extra [5ace:6190,5ace:6193]
++131 -> Twinhan Hybrid DTV-DVB 3056 PCI          [1822:0022]
++132 -> Genius TVGO AM11MCE
+diff --git a/Documentation/video4linux/zr364xx.txt b/Documentation/video4linux/zr364xx.txt
+index 4d9a0c3..5c81e3a 100644
+--- a/Documentation/video4linux/zr364xx.txt
++++ b/Documentation/video4linux/zr364xx.txt
+@@ -25,7 +25,7 @@ modprobe zr364xx debug=X mode=Y
+  - debug      : set to 1 to enable verbose debug messages
+  - mode       : 0 = 320x240, 1 = 160x120, 2 = 640x480
+ You can then use the camera with V4L2 compatible applications, for example Ekiga.
+-To capture a single image, try this: dd if=/dev/video0 of=test.jpg bs=1 count=1
++To capture a single image, try this: dd if=/dev/video0 of=test.jpg bs=1M count=1
+ 
+ links :
+ http://mxhaard.free.fr/ (support for many others cams including some Aiptek PocketDV)
+@@ -63,3 +63,5 @@ Vendor  Product  Distributor     Model
+ 0x06d6  0x0034   Trust           Powerc at m 750
+ 0x0a17  0x0062   Pentax          Optio 50L
+ 0x06d6  0x003b   Trust           Powerc at m 970Z
++0x0a17  0x004e   Pentax          Optio 50
++0x041e  0x405d   Creative        DiVi CAM 516
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 1d2edb4..082d1ee 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -1924,7 +1924,7 @@ S:	Maintained
+ 
+ IDE/ATAPI CDROM DRIVER
+ P:	Borislav Petkov
+-M:	bbpetkov at yahoo.de
++M:	petkovbb at gmail.com
+ L:	linux-ide at vger.kernel.org
+ S:	Maintained
+ 
+diff --git a/Makefile b/Makefile
+index 67cc457..4a05d81 100644
+--- a/Makefile
++++ b/Makefile
+@@ -507,6 +507,10 @@ else
+ KBUILD_CFLAGS	+= -O2
+ endif
+ 
++# Force gcc to behave correct even for buggy distributions
++# Arch Makefiles may override this setting
++KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
++
+ include $(srctree)/arch/$(SRCARCH)/Makefile
+ 
+ ifdef CONFIG_FRAME_POINTER
+@@ -525,9 +529,6 @@ ifdef CONFIG_DEBUG_SECTION_MISMATCH
+ KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once)
+ endif
+ 
+-# Force gcc to behave correct even for buggy distributions
+-KBUILD_CFLAGS         += $(call cc-option, -fno-stack-protector)
+-
+ # arch Makefile may override CC so keep this after arch Makefile is included
+ NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
+ CHECKFLAGS     += $(NOSTDINC_FLAGS)
+@@ -810,7 +811,9 @@ endif
+ 	$(Q)rm -f .old_version
+ 
+ # build vmlinux.o first to catch section mismatch errors early
+-$(kallsyms.o): vmlinux.o
++ifdef CONFIG_KALLSYMS
++.tmp_vmlinux1: vmlinux.o
++endif
+ vmlinux.o: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) FORCE
+ 	$(call if_changed_rule,vmlinux-modpost)
+ 
+diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
+index ca6a345..f36d7f4 100644
+--- a/arch/frv/kernel/entry.S
++++ b/arch/frv/kernel/entry.S
+@@ -1494,9 +1494,11 @@ sys_call_table:
+ 	.long sys_epoll_pwait
+ 	.long sys_utimensat		/* 320 */
+ 	.long sys_signalfd
+-	.long sys_ni_syscall
++	.long sys_timerfd_create
+ 	.long sys_eventfd
+ 	.long sys_fallocate
++	.long sys_timerfd_settime	/* 325 */
++	.long sys_timerfd_gettime
+ 
+ 
+ syscall_table_size = (. - sys_call_table)
+diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S
+index 17725a5..b95c4ea 100644
+--- a/arch/frv/kernel/vmlinux.lds.S
++++ b/arch/frv/kernel/vmlinux.lds.S
+@@ -76,9 +76,6 @@ SECTIONS
+ 	  *(.data.init_task)
+   }
+ 
+-  . = ALIGN(4096);
+-  .data.page_aligned : { *(.data.idt) }
+-
+   . = ALIGN(L1_CACHE_BYTES);
+   .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+ 
+diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
+index 1b6b0fa..8d36f18 100644
+--- a/arch/mips/bcm47xx/setup.c
++++ b/arch/mips/bcm47xx/setup.c
+@@ -92,17 +92,17 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
+ 	iv->sprom.revision = 3;
+ 
+ 	if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
+-		str2eaddr(buf, iv->sprom.r1.et0mac);
++		str2eaddr(buf, iv->sprom.et0mac);
+ 	if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
+-		str2eaddr(buf, iv->sprom.r1.et1mac);
++		str2eaddr(buf, iv->sprom.et1mac);
+ 	if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0)
+-		iv->sprom.r1.et0phyaddr = simple_strtoul(buf, NULL, 10);
++		iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 10);
+ 	if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0)
+-		iv->sprom.r1.et1phyaddr = simple_strtoul(buf, NULL, 10);
++		iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 10);
+ 	if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0)
+-		iv->sprom.r1.et0mdcport = simple_strtoul(buf, NULL, 10);
++		iv->sprom.et0mdcport = simple_strtoul(buf, NULL, 10);
+ 	if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0)
+-		iv->sprom.r1.et1mdcport = simple_strtoul(buf, NULL, 10);
++		iv->sprom.et1mdcport = simple_strtoul(buf, NULL, 10);
+ 
+ 	return 0;
+ }
+diff --git a/arch/mips/bcm47xx/wgt634u.c b/arch/mips/bcm47xx/wgt634u.c
+index 5a017ea..d1d90c9 100644
+--- a/arch/mips/bcm47xx/wgt634u.c
++++ b/arch/mips/bcm47xx/wgt634u.c
+@@ -9,6 +9,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/module.h>
+ #include <linux/leds.h>
++#include <linux/mtd/physmap.h>
+ #include <linux/ssb/ssb.h>
+ #include <asm/mach-bcm47xx/bcm47xx.h>
+ 
+@@ -43,6 +44,61 @@ static struct platform_device wgt634u_gpio_leds = {
+ 	}
+ };
+ 
++
++/* 8MiB flash. The struct mtd_partition matches original Netgear WGT634U
++   firmware. */
++static struct mtd_partition wgt634u_partitions[] = {
++	{
++		.name       = "cfe",
++		.offset     = 0,
++		.size       = 0x60000,		/* 384k */
++		.mask_flags = MTD_WRITEABLE 	/* force read-only */
++	},
++	{
++		.name   = "config",
++		.offset = 0x60000,
++		.size   = 0x20000		/* 128k */
++	},
++	{
++		.name   = "linux",
++		.offset = 0x80000,
++		.size   = 0x140000 		/* 1280k */
++	},
++	{
++		.name   = "jffs",
++		.offset = 0x1c0000,
++		.size   = 0x620000 		/* 6272k */
++	},
++	{
++		.name   = "nvram",
++		.offset = 0x7e0000,
++		.size   = 0x20000		/* 128k */
++	},
++};
++
++static struct physmap_flash_data wgt634u_flash_data = {
++	.parts    = wgt634u_partitions,
++	.nr_parts = ARRAY_SIZE(wgt634u_partitions)
++};
++
++static struct resource wgt634u_flash_resource = {
++	.flags = IORESOURCE_MEM,
++};
++
++static struct platform_device wgt634u_flash = {
++	.name          = "physmap-flash",
++	.id            = 0,
++	.dev           = { .platform_data = &wgt634u_flash_data, },
++	.resource      = &wgt634u_flash_resource,
++	.num_resources = 1,
++};
++
++/* Platform devices */
++static struct platform_device *wgt634u_devices[] __initdata = {
++	&wgt634u_flash,
++	&wgt634u_gpio_leds,
++};
++
+ static int __init wgt634u_init(void)
+ {
+ 	/* There is no easy way to detect that we are running on a WGT634U
+@@ -50,13 +106,20 @@ static int __init wgt634u_init(void)
+ 	 * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.
+ 	 */
+ 
+-	u8 *et0mac = ssb_bcm47xx.sprom.r1.et0mac;
++	u8 *et0mac = ssb_bcm47xx.sprom.et0mac;
+ 
+ 	if (et0mac[0] == 0x00 &&
+ 	    ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) ||
+-	     (et0mac[1] == 0x0f && et0mac[2] == 0xb5)))
+-		return platform_device_register(&wgt634u_gpio_leds);
+-	else
++	     (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) {
++		struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
++		wgt634u_flash_data.width = mcore->flash_buswidth;
++		wgt634u_flash_resource.start = mcore->flash_window;
++		wgt634u_flash_resource.end = mcore->flash_window
++					   + mcore->flash_window_size
++					   - 1;
++		return platform_add_devices(wgt634u_devices,
++					    ARRAY_SIZE(wgt634u_devices));
++	} else
+ 		return -ENODEV;
+ }
+ 
+diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig
+new file mode 100644
+index 0000000..c0e42e7
+--- /dev/null
++++ b/arch/mips/configs/bcm47xx_defconfig
+@@ -0,0 +1,1939 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.25-rc2
++# Mon Feb 18 11:55:24 2008
++#
++CONFIG_MIPS=y
++
++#
++# Machine selection
++#
++# CONFIG_MACH_ALCHEMY is not set
++# CONFIG_BASLER_EXCITE is not set
++CONFIG_BCM47XX=y
++# CONFIG_MIPS_COBALT is not set
++# CONFIG_MACH_DECSTATION is not set
++# CONFIG_MACH_JAZZ is not set
++# CONFIG_LASAT is not set
++# CONFIG_LEMOTE_FULONG is not set
++# CONFIG_MIPS_ATLAS is not set
++# CONFIG_MIPS_MALTA is not set
++# CONFIG_MIPS_SEAD is not set
++# CONFIG_MIPS_SIM is not set
++# CONFIG_MARKEINS is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PNX8550_JBS is not set
++# CONFIG_PNX8550_STB810 is not set
++# CONFIG_PMC_MSP is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_SGI_IP22 is not set
++# CONFIG_SGI_IP27 is not set
++# CONFIG_SGI_IP28 is not set
++# CONFIG_SGI_IP32 is not set
++# CONFIG_SIBYTE_CRHINE is not set
++# CONFIG_SIBYTE_CARMEL is not set
++# CONFIG_SIBYTE_CRHONE is not set
++# CONFIG_SIBYTE_RHONE is not set
++# CONFIG_SIBYTE_SWARM is not set
++# CONFIG_SIBYTE_LITTLESUR is not set
++# CONFIG_SIBYTE_SENTOSA is not set
++# CONFIG_SIBYTE_BIGSUR is not set
++# CONFIG_SNI_RM is not set
++# CONFIG_TOSHIBA_JMR3927 is not set
++# CONFIG_TOSHIBA_RBTX4927 is not set
++# CONFIG_TOSHIBA_RBTX4938 is not set
++# CONFIG_WR_PPMC is not set
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_ARCH_SUPPORTS_OPROFILE=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
++# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
++CONFIG_CEVT_R4K=y
++CONFIG_CSRC_R4K=y
++CONFIG_CFE=y
++CONFIG_DMA_NONCOHERENT=y
++CONFIG_DMA_NEED_PCI_MAP_STATE=y
++CONFIG_EARLY_PRINTK=y
++CONFIG_SYS_HAS_EARLY_PRINTK=y
++# CONFIG_HOTPLUG_CPU is not set
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_GPIO=y
++# CONFIG_CPU_BIG_ENDIAN is not set
++CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
++CONFIG_IRQ_CPU=y
++CONFIG_MIPS_L1_CACHE_SHIFT=5
++
++#
++# CPU selection
++#
++# CONFIG_CPU_LOONGSON2 is not set
++CONFIG_CPU_MIPS32_R1=y
++# CONFIG_CPU_MIPS32_R2 is not set
++# CONFIG_CPU_MIPS64_R1 is not set
++# CONFIG_CPU_MIPS64_R2 is not set
++# CONFIG_CPU_R3000 is not set
++# CONFIG_CPU_TX39XX is not set
++# CONFIG_CPU_VR41XX is not set
++# CONFIG_CPU_R4300 is not set
++# CONFIG_CPU_R4X00 is not set
++# CONFIG_CPU_TX49XX is not set
++# CONFIG_CPU_R5000 is not set
++# CONFIG_CPU_R5432 is not set
++# CONFIG_CPU_R6000 is not set
++# CONFIG_CPU_NEVADA is not set
++# CONFIG_CPU_R8000 is not set
++# CONFIG_CPU_R10000 is not set
++# CONFIG_CPU_RM7000 is not set
++# CONFIG_CPU_RM9000 is not set
++# CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_MIPS32_R1=y
++CONFIG_CPU_MIPS32=y
++CONFIG_CPU_MIPSR1=y
++CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++
++#
++# Kernel type
++#
++CONFIG_32BIT=y
++# CONFIG_64BIT is not set
++CONFIG_PAGE_SIZE_4KB=y
++# CONFIG_PAGE_SIZE_8KB is not set
++# CONFIG_PAGE_SIZE_16KB is not set
++# CONFIG_PAGE_SIZE_64KB is not set
++CONFIG_CPU_HAS_PREFETCH=y
++CONFIG_MIPS_MT_DISABLED=y
++# CONFIG_MIPS_MT_SMP is not set
++# CONFIG_MIPS_MT_SMTC is not set
++CONFIG_CPU_HAS_LLSC=y
++CONFIG_CPU_HAS_SYNC=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_CPU_SUPPORTS_HIGHMEM=y
++CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++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_SPLIT_PTLOCK_CPUS=4
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_HZ_48 is not set
++# CONFIG_HZ_100 is not set
++# CONFIG_HZ_128 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_256 is not set
++# CONFIG_HZ_1000 is not set
++# CONFIG_HZ_1024 is not set
++CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
++CONFIG_HZ=250
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++CONFIG_RCU_TRACE=y
++CONFIG_KEXEC=y
++# CONFIG_SECCOMP is not set
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_STACKTRACE_SUPPORT=y
++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 is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_BSD_PROCESS_ACCT_V3=y
++CONFIG_TASKSTATS=y
++CONFIG_TASK_DELAY_ACCT=y
++CONFIG_TASK_XACCT=y
++CONFIG_TASK_IO_ACCOUNTING=y
++CONFIG_AUDIT=y
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=17
++CONFIG_CGROUPS=y
++# CONFIG_CGROUP_DEBUG is not set
++CONFIG_CGROUP_NS=y
++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_CGROUP_CPUACCT=y
++# CONFIG_RESOURCE_COUNTERS is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_RELAY=y
++# CONFIG_NAMESPACES is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=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_HAVE_KPROBES is not set
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++CONFIG_MODULE_FORCE_UNLOAD=y
++CONFIG_MODVERSIONS=y
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++CONFIG_LBD=y
++CONFIG_BLK_DEV_IO_TRACE=y
++CONFIG_LSF=y
++# CONFIG_BLK_DEV_BSG 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
++# CONFIG_PREEMPT_RCU is not set
++
++#
++# Bus options (PCI, PCMCIA, EISA, ISA, TC)
++#
++CONFIG_HW_HAS_PCI=y
++CONFIG_PCI=y
++CONFIG_PCI_DOMAINS=y
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++CONFIG_PCI_LEGACY=y
++CONFIG_MMU=y
++# CONFIG_PCCARD is not set
++# CONFIG_HOTPLUG_PCI is not set
++
++#
++# Executable file formats
++#
++CONFIG_BINFMT_ELF=y
++CONFIG_BINFMT_MISC=m
++CONFIG_TRAD_SIGNALS=y
++
++#
++# Power management options
++#
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++# CONFIG_PM is not set
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++CONFIG_XFRM_USER=m
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++CONFIG_NET_KEY=m
++# CONFIG_NET_KEY_MIGRATE is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++CONFIG_ASK_IP_FIB_HASH=y
++# CONFIG_IP_FIB_TRIE is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_MULTIPLE_TABLES=y
++CONFIG_IP_ROUTE_MULTIPATH=y
++CONFIG_IP_ROUTE_VERBOSE=y
++# CONFIG_IP_PNP is not set
++CONFIG_NET_IPIP=m
++CONFIG_NET_IPGRE=m
++CONFIG_NET_IPGRE_BROADCAST=y
++CONFIG_IP_MROUTE=y
++CONFIG_IP_PIMSM_V1=y
++CONFIG_IP_PIMSM_V2=y
++# CONFIG_ARPD is not set
++CONFIG_SYN_COOKIES=y
++CONFIG_INET_AH=m
++CONFIG_INET_ESP=m
++CONFIG_INET_IPCOMP=m
++CONFIG_INET_XFRM_TUNNEL=m
++CONFIG_INET_TUNNEL=m
++CONFIG_INET_XFRM_MODE_TRANSPORT=m
++CONFIG_INET_XFRM_MODE_TUNNEL=m
++CONFIG_INET_XFRM_MODE_BEET=m
++CONFIG_INET_LRO=m
++CONFIG_INET_DIAG=m
++CONFIG_INET_TCP_DIAG=m
++CONFIG_TCP_CONG_ADVANCED=y
++CONFIG_TCP_CONG_BIC=y
++CONFIG_TCP_CONG_CUBIC=m
++CONFIG_TCP_CONG_WESTWOOD=m
++CONFIG_TCP_CONG_HTCP=m
++CONFIG_TCP_CONG_HSTCP=m
++CONFIG_TCP_CONG_HYBLA=m
++CONFIG_TCP_CONG_VEGAS=m
++CONFIG_TCP_CONG_SCALABLE=m
++CONFIG_TCP_CONG_LP=m
++CONFIG_TCP_CONG_VENO=m
++CONFIG_TCP_CONG_YEAH=m
++CONFIG_TCP_CONG_ILLINOIS=m
++CONFIG_DEFAULT_BIC=y
++# CONFIG_DEFAULT_CUBIC is not set
++# CONFIG_DEFAULT_HTCP is not set
++# CONFIG_DEFAULT_VEGAS is not set
++# CONFIG_DEFAULT_WESTWOOD is not set
++# CONFIG_DEFAULT_RENO is not set
++CONFIG_DEFAULT_TCP_CONG="bic"
++# CONFIG_TCP_MD5SIG is not set
++CONFIG_IP_VS=m
++# CONFIG_IP_VS_DEBUG is not set
++CONFIG_IP_VS_TAB_BITS=12
++
++#
++# IPVS transport protocol load balancing support
++#
++CONFIG_IP_VS_PROTO_TCP=y
++CONFIG_IP_VS_PROTO_UDP=y
++CONFIG_IP_VS_PROTO_ESP=y
++CONFIG_IP_VS_PROTO_AH=y
++
++#
++# IPVS scheduler
++#
++CONFIG_IP_VS_RR=m
++CONFIG_IP_VS_WRR=m
++CONFIG_IP_VS_LC=m
++CONFIG_IP_VS_WLC=m
++CONFIG_IP_VS_LBLC=m
++CONFIG_IP_VS_LBLCR=m
++CONFIG_IP_VS_DH=m
++CONFIG_IP_VS_SH=m
++CONFIG_IP_VS_SED=m
++CONFIG_IP_VS_NQ=m
++
++#
++# IPVS application helper
++#
++CONFIG_IP_VS_FTP=m
++CONFIG_IPV6=m
++CONFIG_IPV6_PRIVACY=y
++# CONFIG_IPV6_ROUTER_PREF is not set
++# CONFIG_IPV6_OPTIMISTIC_DAD is not set
++CONFIG_INET6_AH=m
++CONFIG_INET6_ESP=m
++CONFIG_INET6_IPCOMP=m
++# CONFIG_IPV6_MIP6 is not set
++CONFIG_INET6_XFRM_TUNNEL=m
++CONFIG_INET6_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_TRANSPORT=m
++CONFIG_INET6_XFRM_MODE_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_BEET=m
++CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
++CONFIG_IPV6_SIT=m
++CONFIG_IPV6_TUNNEL=m
++CONFIG_IPV6_MULTIPLE_TABLES=y
++CONFIG_IPV6_SUBTREES=y
++CONFIG_NETWORK_SECMARK=y
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_NETFILTER_ADVANCED=y
++CONFIG_BRIDGE_NETFILTER=y
++
++#
++# Core Netfilter Configuration
++#
++CONFIG_NETFILTER_NETLINK=m
++CONFIG_NETFILTER_NETLINK_QUEUE=m
++CONFIG_NETFILTER_NETLINK_LOG=m
++CONFIG_NF_CONNTRACK=m
++CONFIG_NF_CT_ACCT=y
++CONFIG_NF_CONNTRACK_MARK=y
++CONFIG_NF_CONNTRACK_SECMARK=y
++CONFIG_NF_CONNTRACK_EVENTS=y
++CONFIG_NF_CT_PROTO_GRE=m
++CONFIG_NF_CT_PROTO_SCTP=m
++CONFIG_NF_CT_PROTO_UDPLITE=m
++CONFIG_NF_CONNTRACK_AMANDA=m
++CONFIG_NF_CONNTRACK_FTP=m
++CONFIG_NF_CONNTRACK_H323=m
++CONFIG_NF_CONNTRACK_IRC=m
++CONFIG_NF_CONNTRACK_NETBIOS_NS=m
++CONFIG_NF_CONNTRACK_PPTP=m
++CONFIG_NF_CONNTRACK_SANE=m
++CONFIG_NF_CONNTRACK_SIP=m
++CONFIG_NF_CONNTRACK_TFTP=m
++CONFIG_NF_CT_NETLINK=m
++CONFIG_NETFILTER_XTABLES=m
++CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
++CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
++CONFIG_NETFILTER_XT_TARGET_DSCP=m
++CONFIG_NETFILTER_XT_TARGET_MARK=m
++CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
++CONFIG_NETFILTER_XT_TARGET_NFLOG=m
++CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
++# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
++CONFIG_NETFILTER_XT_TARGET_TRACE=m
++CONFIG_NETFILTER_XT_TARGET_SECMARK=m
++CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
++CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
++# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
++CONFIG_NETFILTER_XT_MATCH_COMMENT=m
++CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
++CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
++CONFIG_NETFILTER_XT_MATCH_DCCP=m
++CONFIG_NETFILTER_XT_MATCH_DSCP=m
++CONFIG_NETFILTER_XT_MATCH_ESP=m
++CONFIG_NETFILTER_XT_MATCH_HELPER=m
++# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
++CONFIG_NETFILTER_XT_MATCH_LENGTH=m
++CONFIG_NETFILTER_XT_MATCH_LIMIT=m
++CONFIG_NETFILTER_XT_MATCH_MAC=m
++CONFIG_NETFILTER_XT_MATCH_MARK=m
++# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
++CONFIG_NETFILTER_XT_MATCH_POLICY=m
++CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
++CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
++CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
++CONFIG_NETFILTER_XT_MATCH_QUOTA=m
++# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
++CONFIG_NETFILTER_XT_MATCH_REALM=m
++CONFIG_NETFILTER_XT_MATCH_SCTP=m
++CONFIG_NETFILTER_XT_MATCH_STATE=m
++CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
++CONFIG_NETFILTER_XT_MATCH_STRING=m
++CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
++CONFIG_NETFILTER_XT_MATCH_TIME=m
++CONFIG_NETFILTER_XT_MATCH_U32=m
++CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
++
++#
++# IP: Netfilter Configuration
++#
++CONFIG_NF_CONNTRACK_IPV4=m
++CONFIG_NF_CONNTRACK_PROC_COMPAT=y
++CONFIG_IP_NF_QUEUE=m
++CONFIG_IP_NF_IPTABLES=m
++CONFIG_IP_NF_MATCH_RECENT=m
++CONFIG_IP_NF_MATCH_ECN=m
++CONFIG_IP_NF_MATCH_AH=m
++CONFIG_IP_NF_MATCH_TTL=m
++CONFIG_IP_NF_MATCH_ADDRTYPE=m
++CONFIG_IP_NF_FILTER=m
++CONFIG_IP_NF_TARGET_REJECT=m
++CONFIG_IP_NF_TARGET_LOG=m
++CONFIG_IP_NF_TARGET_ULOG=m
++CONFIG_NF_NAT=m
++CONFIG_NF_NAT_NEEDED=y
++CONFIG_IP_NF_TARGET_MASQUERADE=m
++CONFIG_IP_NF_TARGET_REDIRECT=m
++CONFIG_IP_NF_TARGET_NETMAP=m
++CONFIG_NF_NAT_SNMP_BASIC=m
++CONFIG_NF_NAT_PROTO_GRE=m
++CONFIG_NF_NAT_FTP=m
++CONFIG_NF_NAT_IRC=m
++CONFIG_NF_NAT_TFTP=m
++CONFIG_NF_NAT_AMANDA=m
++CONFIG_NF_NAT_PPTP=m
++CONFIG_NF_NAT_H323=m
++CONFIG_NF_NAT_SIP=m
++CONFIG_IP_NF_MANGLE=m
++CONFIG_IP_NF_TARGET_ECN=m
++CONFIG_IP_NF_TARGET_TTL=m
++CONFIG_IP_NF_TARGET_CLUSTERIP=m
++CONFIG_IP_NF_RAW=m
++CONFIG_IP_NF_ARPTABLES=m
++CONFIG_IP_NF_ARPFILTER=m
++CONFIG_IP_NF_ARP_MANGLE=m
++
++#
++# IPv6: Netfilter Configuration
++#
++CONFIG_NF_CONNTRACK_IPV6=m
++CONFIG_IP6_NF_QUEUE=m
++CONFIG_IP6_NF_IPTABLES=m
++CONFIG_IP6_NF_MATCH_RT=m
++CONFIG_IP6_NF_MATCH_OPTS=m
++CONFIG_IP6_NF_MATCH_FRAG=m
++CONFIG_IP6_NF_MATCH_HL=m
++CONFIG_IP6_NF_MATCH_IPV6HEADER=m
++CONFIG_IP6_NF_MATCH_AH=m
++CONFIG_IP6_NF_MATCH_MH=m
++CONFIG_IP6_NF_MATCH_EUI64=m
++CONFIG_IP6_NF_FILTER=m
++CONFIG_IP6_NF_TARGET_LOG=m
++CONFIG_IP6_NF_TARGET_REJECT=m
++CONFIG_IP6_NF_MANGLE=m
++CONFIG_IP6_NF_TARGET_HL=m
++CONFIG_IP6_NF_RAW=m
++
++#
++# Bridge: Netfilter Configuration
++#
++CONFIG_BRIDGE_NF_EBTABLES=m
++CONFIG_BRIDGE_EBT_BROUTE=m
++CONFIG_BRIDGE_EBT_T_FILTER=m
++CONFIG_BRIDGE_EBT_T_NAT=m
++CONFIG_BRIDGE_EBT_802_3=m
++CONFIG_BRIDGE_EBT_AMONG=m
++CONFIG_BRIDGE_EBT_ARP=m
++CONFIG_BRIDGE_EBT_IP=m
++CONFIG_BRIDGE_EBT_LIMIT=m
++CONFIG_BRIDGE_EBT_MARK=m
++CONFIG_BRIDGE_EBT_PKTTYPE=m
++CONFIG_BRIDGE_EBT_STP=m
++CONFIG_BRIDGE_EBT_VLAN=m
++CONFIG_BRIDGE_EBT_ARPREPLY=m
++CONFIG_BRIDGE_EBT_DNAT=m
++CONFIG_BRIDGE_EBT_MARK_T=m
++CONFIG_BRIDGE_EBT_REDIRECT=m
++CONFIG_BRIDGE_EBT_SNAT=m
++CONFIG_BRIDGE_EBT_LOG=m
++CONFIG_BRIDGE_EBT_ULOG=m
++CONFIG_IP_DCCP=m
++CONFIG_INET_DCCP_DIAG=m
++CONFIG_IP_DCCP_ACKVEC=y
++
++#
++# DCCP CCIDs Configuration (EXPERIMENTAL)
++#
++CONFIG_IP_DCCP_CCID2=m
++# CONFIG_IP_DCCP_CCID2_DEBUG is not set
++CONFIG_IP_DCCP_CCID3=m
++# CONFIG_IP_DCCP_CCID3_DEBUG is not set
++CONFIG_IP_DCCP_CCID3_RTO=100
++CONFIG_IP_DCCP_TFRC_LIB=m
++CONFIG_IP_SCTP=m
++# CONFIG_SCTP_DBG_MSG is not set
++# CONFIG_SCTP_DBG_OBJCNT is not set
++# CONFIG_SCTP_HMAC_NONE is not set
++# CONFIG_SCTP_HMAC_SHA1 is not set
++CONFIG_SCTP_HMAC_MD5=y
++CONFIG_TIPC=m
++CONFIG_TIPC_ADVANCED=y
++CONFIG_TIPC_ZONES=3
++CONFIG_TIPC_CLUSTERS=1
++CONFIG_TIPC_NODES=255
++CONFIG_TIPC_SLAVE_NODES=0
++CONFIG_TIPC_PORTS=8191
++CONFIG_TIPC_LOG=0
++# CONFIG_TIPC_DEBUG is not set
++CONFIG_ATM=m
++CONFIG_ATM_CLIP=m
++# CONFIG_ATM_CLIP_NO_ICMP is not set
++CONFIG_ATM_LANE=m
++CONFIG_ATM_MPOA=m
++CONFIG_ATM_BR2684=m
++# CONFIG_ATM_BR2684_IPFILTER is not set
++CONFIG_BRIDGE=m
++CONFIG_VLAN_8021Q=m
++# CONFIG_DECNET is not set
++CONFIG_LLC=m
++# 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=y
++
++#
++# Queueing/Scheduling
++#
++CONFIG_NET_SCH_CBQ=m
++CONFIG_NET_SCH_HTB=m
++CONFIG_NET_SCH_HFSC=m
++CONFIG_NET_SCH_ATM=m
++CONFIG_NET_SCH_PRIO=m
++CONFIG_NET_SCH_RR=m
++CONFIG_NET_SCH_RED=m
++CONFIG_NET_SCH_SFQ=m
++CONFIG_NET_SCH_TEQL=m
++CONFIG_NET_SCH_TBF=m
++CONFIG_NET_SCH_GRED=m
++CONFIG_NET_SCH_DSMARK=m
++CONFIG_NET_SCH_NETEM=m
++CONFIG_NET_SCH_INGRESS=m
++
++#
++# Classification
++#
++CONFIG_NET_CLS=y
++CONFIG_NET_CLS_BASIC=m
++CONFIG_NET_CLS_TCINDEX=m
++CONFIG_NET_CLS_ROUTE4=m
++CONFIG_NET_CLS_ROUTE=y
++CONFIG_NET_CLS_FW=m
++CONFIG_NET_CLS_U32=m
++CONFIG_CLS_U32_PERF=y
++CONFIG_CLS_U32_MARK=y
++CONFIG_NET_CLS_RSVP=m
++CONFIG_NET_CLS_RSVP6=m
++# CONFIG_NET_CLS_FLOW is not set
++CONFIG_NET_EMATCH=y
++CONFIG_NET_EMATCH_STACK=32
++CONFIG_NET_EMATCH_CMP=m
++CONFIG_NET_EMATCH_NBYTE=m
++CONFIG_NET_EMATCH_U32=m
++CONFIG_NET_EMATCH_META=m
++CONFIG_NET_EMATCH_TEXT=m
++CONFIG_NET_CLS_ACT=y
++CONFIG_NET_ACT_POLICE=m
++CONFIG_NET_ACT_GACT=m
++CONFIG_GACT_PROB=y
++CONFIG_NET_ACT_MIRRED=m
++CONFIG_NET_ACT_IPT=m
++CONFIG_NET_ACT_NAT=m
++CONFIG_NET_ACT_PEDIT=m
++CONFIG_NET_ACT_SIMP=m
++CONFIG_NET_CLS_IND=y
++CONFIG_NET_SCH_FIFO=y
++
++#
++# Network testing
++#
++CONFIG_NET_PKTGEN=m
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++CONFIG_IRDA=m
++
++#
++# IrDA protocols
++#
++CONFIG_IRLAN=m
++CONFIG_IRNET=m
++CONFIG_IRCOMM=m
++# CONFIG_IRDA_ULTRA is not set
++
++#
++# IrDA options
++#
++CONFIG_IRDA_CACHE_LAST_LSAP=y
++CONFIG_IRDA_FAST_RR=y
++# CONFIG_IRDA_DEBUG is not set
++
++#
++# Infrared-port device drivers
++#
++
++#
++# SIR device drivers
++#
++CONFIG_IRTTY_SIR=m
++
++#
++# Dongle support
++#
++CONFIG_DONGLE=y
++CONFIG_ESI_DONGLE=m
++CONFIG_ACTISYS_DONGLE=m
++CONFIG_TEKRAM_DONGLE=m
++CONFIG_TOIM3232_DONGLE=m
++CONFIG_LITELINK_DONGLE=m
++CONFIG_MA600_DONGLE=m
++CONFIG_GIRBIL_DONGLE=m
++CONFIG_MCP2120_DONGLE=m
++CONFIG_OLD_BELKIN_DONGLE=m
++CONFIG_ACT200L_DONGLE=m
++CONFIG_KINGSUN_DONGLE=m
++CONFIG_KSDAZZLE_DONGLE=m
++CONFIG_KS959_DONGLE=m
++
++#
++# FIR device drivers
++#
++CONFIG_USB_IRDA=m
++CONFIG_SIGMATEL_FIR=m
++CONFIG_TOSHIBA_FIR=m
++CONFIG_VLSI_FIR=m
++CONFIG_MCS_FIR=m
++CONFIG_BT=m
++# CONFIG_BT_L2CAP is not set
++# CONFIG_BT_SCO is not set
++
++#
++# Bluetooth device drivers
++#
++CONFIG_BT_HCIUSB=m
++CONFIG_BT_HCIUSB_SCO=y
++CONFIG_BT_HCIUART=m
++CONFIG_BT_HCIUART_H4=y
++CONFIG_BT_HCIUART_BCSP=y
++CONFIG_BT_HCIUART_LL=y
++CONFIG_BT_HCIBCM203X=m
++CONFIG_BT_HCIBPA10X=m
++CONFIG_BT_HCIBFUSB=m
++CONFIG_BT_HCIVHCI=m
++# CONFIG_AF_RXRPC is not set
++CONFIG_FIB_RULES=y
++
++#
++# Wireless
++#
++CONFIG_CFG80211=m
++CONFIG_NL80211=y
++CONFIG_WIRELESS_EXT=y
++CONFIG_MAC80211=m
++
++#
++# Rate control algorithm selection
++#
++CONFIG_MAC80211_RC_DEFAULT_PID=y
++# CONFIG_MAC80211_RC_DEFAULT_SIMPLE is not set
++# CONFIG_MAC80211_RC_DEFAULT_NONE is not set
++
++#
++# Selecting 'y' for an algorithm will
++#
++
++#
++# build the algorithm into mac80211.
++#
++CONFIG_MAC80211_RC_DEFAULT="pid"
++CONFIG_MAC80211_RC_PID=y
++# CONFIG_MAC80211_RC_SIMPLE is not set
++CONFIG_MAC80211_LEDS=y
++# CONFIG_MAC80211_DEBUGFS is not set
++# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set
++# CONFIG_MAC80211_DEBUG 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_IEEE80211_SOFTMAC=m
++# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
++CONFIG_RFKILL=m
++CONFIG_RFKILL_INPUT=m
++CONFIG_RFKILL_LEDS=y
++CONFIG_NET_9P=m
++CONFIG_NET_9P_FD=m
++# CONFIG_NET_9P_DEBUG 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=m
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=m
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_CONCAT=y
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_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=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=y
++CONFIG_MTD_CFI_AMDSTD=y
++CONFIG_MTD_CFI_STAA=y
++CONFIG_MTD_CFI_UTIL=y
++CONFIG_MTD_RAM=y
++CONFIG_MTD_ROM=y
++CONFIG_MTD_ABSENT=y
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=0x8000000
++CONFIG_MTD_PHYSMAP_LEN=0x0
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++# 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
++# 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 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_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=m
++CONFIG_BLK_DEV_CRYPTOLOOP=m
++CONFIG_BLK_DEV_NBD=m
++# 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=16384
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++CONFIG_ATA_OVER_ETH=m
++CONFIG_MISC_DEVICES=y
++# CONFIG_PHANTOM is not set
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_SGI_IOC4 is not set
++# CONFIG_TIFM_CORE is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++CONFIG_RAID_ATTRS=m
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++CONFIG_SCSI_TGT=m
++# 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=m
++CONFIG_CHR_DEV_OSST=m
++CONFIG_BLK_DEV_SR=m
++CONFIG_BLK_DEV_SR_VENDOR=y
++CONFIG_CHR_DEV_SG=m
++CONFIG_CHR_DEV_SCH=m
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++CONFIG_SCSI_MULTI_LUN=y
++CONFIG_SCSI_CONSTANTS=y
++CONFIG_SCSI_LOGGING=y
++CONFIG_SCSI_SCAN_ASYNC=y
++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=m
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++CONFIG_ISCSI_TCP=m
++# 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_STEX is not set
++# CONFIG_SCSI_SYM53C8XX_2 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_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_IFB is not set
++CONFIG_DUMMY=m
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++CONFIG_EQUALIZER=m
++CONFIG_TUN=m
++CONFIG_VETH=m
++# CONFIG_ARCNET is not set
++CONFIG_PHYLIB=m
++
++#
++# MII PHY device drivers
++#
++CONFIG_MARVELL_PHY=m
++CONFIG_DAVICOM_PHY=m
++CONFIG_QSEMI_PHY=m
++CONFIG_LXT_PHY=m
++CONFIG_CICADA_PHY=m
++CONFIG_VITESSE_PHY=m
++CONFIG_SMSC_PHY=m
++CONFIG_BROADCOM_PHY=m
++CONFIG_ICPLUS_PHY=m
++# CONFIG_REALTEK_PHY is not set
++# CONFIG_FIXED_PHY is not set
++CONFIG_MDIO_BITBANG=m
++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_DM9000 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=y
++CONFIG_B44_PCI_AUTOSELECT=y
++CONFIG_B44_PCICORE_AUTOSELECT=y
++CONFIG_B44_PCI=y
++# CONFIG_FORCEDETH is not set
++# CONFIG_TC35815 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 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_IPW2100 is not set
++# CONFIG_IPW2200 is not set
++# CONFIG_LIBERTAS is not set
++# CONFIG_HERMES is not set
++# CONFIG_ATMEL is not set
++# CONFIG_PRISM54 is not set
++# CONFIG_USB_ZD1201 is not set
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++# CONFIG_RTL8180 is not set
++# CONFIG_RTL8187 is not set
++# CONFIG_ADM8211 is not set
++# CONFIG_P54_COMMON is not set
++CONFIG_ATH5K=m
++# CONFIG_IWL4965 is not set
++# CONFIG_IWL3945 is not set
++# CONFIG_HOSTAP is not set
++# CONFIG_BCM43XX is not set
++# CONFIG_B43 is not set
++# CONFIG_B43LEGACY is not set
++CONFIG_ZD1211RW=m
++# CONFIG_ZD1211RW_DEBUG is not set
++# CONFIG_RT2X00 is not set
++
++#
++# USB Network Adapters
++#
++CONFIG_USB_CATC=m
++CONFIG_USB_KAWETH=m
++CONFIG_USB_PEGASUS=m
++CONFIG_USB_RTL8150=m
++CONFIG_USB_USBNET=m
++CONFIG_USB_NET_AX8817X=m
++CONFIG_USB_NET_CDCETHER=m
++CONFIG_USB_NET_DM9601=m
++CONFIG_USB_NET_GL620A=m
++CONFIG_USB_NET_NET1080=m
++CONFIG_USB_NET_PLUSB=m
++CONFIG_USB_NET_MCS7830=m
++CONFIG_USB_NET_RNDIS_HOST=m
++CONFIG_USB_NET_CDC_SUBSET=m
++CONFIG_USB_ALI_M5632=y
++CONFIG_USB_AN2720=y
++CONFIG_USB_BELKIN=y
++CONFIG_USB_ARMLINUX=y
++CONFIG_USB_EPSON2888=y
++CONFIG_USB_KC2190=y
++CONFIG_USB_NET_ZAURUS=m
++# CONFIG_WAN is not set
++CONFIG_ATM_DRIVERS=y
++CONFIG_ATM_DUMMY=m
++CONFIG_ATM_TCP=m
++# CONFIG_ATM_LANAI is not set
++# CONFIG_ATM_ENI is not set
++# CONFIG_ATM_FIRESTREAM is not set
++# CONFIG_ATM_ZATM is not set
++# CONFIG_ATM_NICSTAR is not set
++# CONFIG_ATM_IDT77252 is not set
++# CONFIG_ATM_AMBASSADOR is not set
++# CONFIG_ATM_HORIZON is not set
++# CONFIG_ATM_IA is not set
++# CONFIG_ATM_FORE200E_MAYBE is not set
++# CONFIG_ATM_HE is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI 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_PPP_MPPE=m
++CONFIG_PPPOE=m
++CONFIG_PPPOATM=m
++# CONFIG_PPPOL2TP is not set
++CONFIG_SLIP=m
++# CONFIG_SLIP_COMPRESSED is not set
++CONFIG_SLHC=m
++# CONFIG_SLIP_SMART is not set
++# CONFIG_SLIP_MODE_SLIP6 is not set
++# CONFIG_NET_FC is not set
++CONFIG_NETCONSOLE=y
++# CONFIG_NETCONSOLE_DYNAMIC is not set
++CONFIG_NETPOLL=y
++# CONFIG_NETPOLL_TRAP is not set
++CONFIG_NET_POLL_CONTROLLER=y
++# CONFIG_ISDN is not set
++# CONFIG_PHONE 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=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=m
++# 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 is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_NOZOMI is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++# CONFIG_SERIAL_8250_PCI is not set
++CONFIG_SERIAL_8250_NR_UARTS=2
++CONFIG_SERIAL_8250_RUNTIME_UARTS=2
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
++CONFIG_UNIX98_PTYS=y
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_RTC is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_DEVPORT=y
++# CONFIG_I2C is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++CONFIG_W1=m
++CONFIG_W1_CON=y
++
++#
++# 1-wire Bus Masters
++#
++CONFIG_W1_MASTER_MATROX=m
++CONFIG_W1_MASTER_DS2490=m
++# CONFIG_W1_MASTER_GPIO is not set
++
++#
++# 1-wire Slaves
++#
++CONFIG_W1_SLAVE_THERM=m
++CONFIG_W1_SLAVE_SMEM=m
++CONFIG_W1_SLAVE_DS2433=m
++# CONFIG_W1_SLAVE_DS2433_CRC is not set
++CONFIG_W1_SLAVE_DS2760=m
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++CONFIG_THERMAL=y
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++CONFIG_SSB=y
++CONFIG_SSB_PCIHOST_POSSIBLE=y
++CONFIG_SSB_PCIHOST=y
++# CONFIG_SSB_SILENT is not set
++# CONFIG_SSB_DEBUG is not set
++CONFIG_SSB_SERIAL=y
++CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
++CONFIG_SSB_DRIVER_PCICORE=y
++CONFIG_SSB_PCICORE_HOSTMODE=y
++CONFIG_SSB_DRIVER_MIPS=y
++CONFIG_SSB_DRIVER_EXTIF=y
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++CONFIG_DAB=y
++CONFIG_USB_DABUSB=m
++
++#
++# Graphics support
++#
++# CONFIG_DRM is not set
++# 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=m
++
++#
++# Display hardware drivers
++#
++
++#
++# Sound
++#
++CONFIG_SOUND=m
++
++#
++# Advanced Linux Sound Architecture
++#
++CONFIG_SND=m
++CONFIG_SND_TIMER=m
++CONFIG_SND_PCM=m
++CONFIG_SND_HWDEP=m
++CONFIG_SND_RAWMIDI=m
++CONFIG_SND_SEQUENCER=m
++CONFIG_SND_SEQ_DUMMY=m
++CONFIG_SND_OSSEMUL=y
++CONFIG_SND_MIXER_OSS=m
++CONFIG_SND_PCM_OSS=m
++CONFIG_SND_PCM_OSS_PLUGINS=y
++CONFIG_SND_SEQUENCER_OSS=y
++# 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_DUMMY=m
++CONFIG_SND_VIRMIDI=m
++# 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_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
++
++#
++# ALSA MIPS devices
++#
++
++#
++# USB devices
++#
++CONFIG_SND_USB_AUDIO=m
++# CONFIG_SND_USB_CAIAQ is not set
++
++#
++# System on Chip audio support
++#
++# CONFIG_SND_SOC is not set
++
++#
++# SoC Audio support for SuperH
++#
++
++#
++# ALSA SoC audio for Freescale SOCs
++#
++
++#
++# Open Sound System
++#
++# CONFIG_SOUND_PRIME is not set
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=m
++# CONFIG_HID_DEBUG is not set
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=m
++# CONFIG_USB_HIDINPUT_POWERBOOK is not set
++# CONFIG_HID_FF is not set
++CONFIG_USB_HIDDEV=y
++
++#
++# 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_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++# CONFIG_USB_DEVICE_CLASS is not set
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++CONFIG_USB_EHCI_HCD=y
++CONFIG_USB_EHCI_ROOT_HUB_TT=y
++CONFIG_USB_EHCI_TT_NEWSCHED=y
++# CONFIG_USB_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_HCD_SSB is not set
++# 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_U132_HCD=m
++# CONFIG_USB_SL811_HCD is not set
++CONFIG_USB_R8A66597_HCD=m
++
++#
++# USB Device Class drivers
++#
++CONFIG_USB_ACM=m
++CONFIG_USB_PRINTER=m
++
++#
++# 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=y
++CONFIG_USB_STORAGE_FREECOM=y
++# CONFIG_USB_STORAGE_ISD200 is not set
++CONFIG_USB_STORAGE_DPCM=y
++CONFIG_USB_STORAGE_USBAT=y
++CONFIG_USB_STORAGE_SDDR09=y
++CONFIG_USB_STORAGE_SDDR55=y
++CONFIG_USB_STORAGE_JUMPSHOT=y
++CONFIG_USB_STORAGE_ALAUDA=y
++CONFIG_USB_STORAGE_ONETOUCH=y
++CONFIG_USB_STORAGE_KARMA=y
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++CONFIG_USB_MDC800=m
++CONFIG_USB_MICROTEK=m
++# CONFIG_USB_MON is not set
++
++#
++# USB port drivers
++#
++CONFIG_USB_SERIAL=m
++CONFIG_USB_EZUSB=y
++CONFIG_USB_SERIAL_GENERIC=y
++CONFIG_USB_SERIAL_AIRCABLE=m
++CONFIG_USB_SERIAL_AIRPRIME=m
++CONFIG_USB_SERIAL_ARK3116=m
++CONFIG_USB_SERIAL_BELKIN=m
++CONFIG_USB_SERIAL_CH341=m
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
++CONFIG_USB_SERIAL_CP2101=m
++CONFIG_USB_SERIAL_CYPRESS_M8=m
++CONFIG_USB_SERIAL_EMPEG=m
++CONFIG_USB_SERIAL_FTDI_SIO=m
++CONFIG_USB_SERIAL_FUNSOFT=m
++CONFIG_USB_SERIAL_VISOR=m
++CONFIG_USB_SERIAL_IPAQ=m
++CONFIG_USB_SERIAL_IR=m
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
++CONFIG_USB_SERIAL_GARMIN=m
++CONFIG_USB_SERIAL_IPW=m
++# CONFIG_USB_SERIAL_IUU is not set
++CONFIG_USB_SERIAL_KEYSPAN_PDA=m
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++CONFIG_USB_SERIAL_KLSI=m
++CONFIG_USB_SERIAL_KOBIL_SCT=m
++CONFIG_USB_SERIAL_MCT_U232=m
++CONFIG_USB_SERIAL_MOS7720=m
++CONFIG_USB_SERIAL_MOS7840=m
++CONFIG_USB_SERIAL_NAVMAN=m
++CONFIG_USB_SERIAL_PL2303=m
++CONFIG_USB_SERIAL_OTI6858=m
++CONFIG_USB_SERIAL_HP4X=m
++CONFIG_USB_SERIAL_SAFE=m
++# CONFIG_USB_SERIAL_SAFE_PADDED is not set
++CONFIG_USB_SERIAL_SIERRAWIRELESS=m
++# CONFIG_USB_SERIAL_TI is not set
++CONFIG_USB_SERIAL_CYBERJACK=m
++CONFIG_USB_SERIAL_XIRCOM=m
++CONFIG_USB_SERIAL_OPTION=m
++CONFIG_USB_SERIAL_OMNINET=m
++CONFIG_USB_SERIAL_DEBUG=m
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++CONFIG_USB_ADUTUX=m
++CONFIG_USB_AUERSWALD=m
++CONFIG_USB_RIO500=m
++CONFIG_USB_LEGOTOWER=m
++CONFIG_USB_LCD=m
++CONFIG_USB_BERRY_CHARGE=m
++CONFIG_USB_LED=m
++CONFIG_USB_CYPRESS_CY7C63=m
++CONFIG_USB_CYTHERM=m
++CONFIG_USB_PHIDGET=m
++CONFIG_USB_PHIDGETKIT=m
++CONFIG_USB_PHIDGETMOTORCONTROL=m
++CONFIG_USB_PHIDGETSERVO=m
++CONFIG_USB_IDMOUSE=m
++CONFIG_USB_FTDI_ELAN=m
++# CONFIG_USB_APPLEDISPLAY is not set
++CONFIG_USB_SISUSBVGA=m
++CONFIG_USB_LD=m
++CONFIG_USB_TRANCEVIBRATOR=m
++CONFIG_USB_IOWARRIOR=m
++CONFIG_USB_TEST=m
++CONFIG_USB_ATM=m
++CONFIG_USB_SPEEDTOUCH=m
++CONFIG_USB_CXACRU=m
++CONFIG_USB_UEAGLEATM=m
++CONFIG_USB_XUSBATM=m
++CONFIG_USB_GADGET=m
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++# CONFIG_USB_GADGET_DEBUG_FS 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=y
++CONFIG_USB_NET2280=m
++# CONFIG_USB_GADGET_PXA2XX is not set
++# CONFIG_USB_GADGET_M66592 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=y
++CONFIG_USB_ZERO=m
++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=m
++# CONFIG_USB_G_PRINTER is not set
++# CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++
++#
++# LED drivers
++#
++CONFIG_LEDS_GPIO=y
++
++#
++# LED Triggers
++#
++CONFIG_LEDS_TRIGGERS=y
++CONFIG_LEDS_TRIGGER_TIMER=y
++CONFIG_LEDS_TRIGGER_HEARTBEAT=y
++# CONFIG_INFINIBAND is not set
++CONFIG_RTC_LIB=y
++# CONFIG_RTC_CLASS is not set
++
++#
++# Userspace I/O
++#
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++CONFIG_EXT2_FS_XATTR=y
++CONFIG_EXT2_FS_POSIX_ACL=y
++CONFIG_EXT2_FS_SECURITY=y
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++CONFIG_EXT3_FS_XATTR=y
++CONFIG_EXT3_FS_POSIX_ACL=y
++CONFIG_EXT3_FS_SECURITY=y
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++# CONFIG_JBD_DEBUG is not set
++CONFIG_FS_MBCACHE=y
++CONFIG_REISERFS_FS=m
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_REISERFS_PROC_INFO is not set
++CONFIG_REISERFS_FS_XATTR=y
++CONFIG_REISERFS_FS_POSIX_ACL=y
++CONFIG_REISERFS_FS_SECURITY=y
++CONFIG_JFS_FS=m
++CONFIG_JFS_POSIX_ACL=y
++CONFIG_JFS_SECURITY=y
++# CONFIG_JFS_DEBUG is not set
++# CONFIG_JFS_STATISTICS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_XFS_FS=m
++CONFIG_XFS_QUOTA=y
++CONFIG_XFS_SECURITY=y
++CONFIG_XFS_POSIX_ACL=y
++CONFIG_XFS_RT=y
++CONFIG_GFS2_FS=m
++CONFIG_GFS2_FS_LOCKING_NOLOCK=m
++CONFIG_GFS2_FS_LOCKING_DLM=m
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++CONFIG_QUOTA=y
++CONFIG_QUOTA_NETLINK_INTERFACE=y
++CONFIG_PRINT_QUOTA_WARNING=y
++CONFIG_QFMT_V1=m
++CONFIG_QFMT_V2=m
++CONFIG_QUOTACTL=y
++CONFIG_AUTOFS_FS=m
++CONFIG_AUTOFS4_FS=m
++CONFIG_FUSE_FS=m
++CONFIG_GENERIC_ACL=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++CONFIG_ISO9660_FS=m
++CONFIG_JOLIET=y
++CONFIG_ZISOFS=y
++CONFIG_UDF_FS=m
++CONFIG_UDF_NLS=y
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=m
++CONFIG_MSDOS_FS=m
++CONFIG_VFAT_FS=m
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=m
++# CONFIG_NTFS_DEBUG is not set
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_KCORE=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=m
++
++#
++# Miscellaneous filesystems
++#
++CONFIG_ADFS_FS=m
++# CONFIG_ADFS_FS_RW is not set
++CONFIG_AFFS_FS=m
++CONFIG_HFS_FS=m
++CONFIG_HFSPLUS_FS=m
++CONFIG_BEFS_FS=m
++# CONFIG_BEFS_DEBUG is not set
++CONFIG_BFS_FS=m
++CONFIG_EFS_FS=m
++CONFIG_JFFS2_FS=m
++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=y
++CONFIG_JFFS2_FS_POSIX_ACL=y
++CONFIG_JFFS2_FS_SECURITY=y
++# 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=m
++CONFIG_VXFS_FS=m
++CONFIG_MINIX_FS=m
++CONFIG_HPFS_FS=m
++CONFIG_QNX4FS_FS=m
++CONFIG_ROMFS_FS=m
++CONFIG_SYSV_FS=m
++CONFIG_UFS_FS=m
++# CONFIG_UFS_FS_WRITE is not set
++# CONFIG_UFS_DEBUG is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=m
++CONFIG_NFS_V3=y
++CONFIG_NFS_V3_ACL=y
++CONFIG_NFS_V4=y
++# CONFIG_NFS_DIRECTIO is not set
++CONFIG_NFSD=m
++CONFIG_NFSD_V2_ACL=y
++CONFIG_NFSD_V3=y
++CONFIG_NFSD_V3_ACL=y
++CONFIG_NFSD_V4=y
++CONFIG_NFSD_TCP=y
++CONFIG_LOCKD=m
++CONFIG_LOCKD_V4=y
++CONFIG_EXPORTFS=m
++CONFIG_NFS_ACL_SUPPORT=m
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=m
++CONFIG_SUNRPC_GSS=m
++CONFIG_SUNRPC_BIND34=y
++CONFIG_RPCSEC_GSS_KRB5=m
++CONFIG_RPCSEC_GSS_SPKM3=m
++# 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=y
++CONFIG_CIFS_POSIX=y
++# CONFIG_CIFS_DEBUG2 is not set
++# CONFIG_CIFS_EXPERIMENTAL is not set
++CONFIG_NCP_FS=m
++# CONFIG_NCPFS_PACKET_SIGNING is not set
++# CONFIG_NCPFS_IOCTL_LOCKING is not set
++# CONFIG_NCPFS_STRONG is not set
++CONFIG_NCPFS_NFS_NS=y
++CONFIG_NCPFS_OS2_NS=y
++# CONFIG_NCPFS_SMALLDOS is not set
++CONFIG_NCPFS_NLS=y
++CONFIG_NCPFS_EXTRAS=y
++CONFIG_CODA_FS=m
++# CONFIG_CODA_FS_OLD_API is not set
++# CONFIG_AFS_FS is not set
++CONFIG_9P_FS=m
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++CONFIG_KARMA_PARTITION=y
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION 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=m
++CONFIG_DLM_DEBUG=y
++
++#
++# Kernel hacking
++#
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++CONFIG_DEBUG_FS=y
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_SAMPLES is not set
++CONFIG_CMDLINE=""
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_AEAD=m
++CONFIG_CRYPTO_BLKCIPHER=m
++# CONFIG_CRYPTO_SEQIV is not set
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_HMAC=y
++CONFIG_CRYPTO_XCBC=m
++CONFIG_CRYPTO_NULL=m
++CONFIG_CRYPTO_MD4=m
++CONFIG_CRYPTO_MD5=y
++CONFIG_CRYPTO_SHA1=m
++CONFIG_CRYPTO_SHA256=m
++CONFIG_CRYPTO_SHA512=m
++CONFIG_CRYPTO_WP512=m
++CONFIG_CRYPTO_TGR192=m
++CONFIG_CRYPTO_GF128MUL=m
++CONFIG_CRYPTO_ECB=m
++CONFIG_CRYPTO_CBC=m
++CONFIG_CRYPTO_PCBC=m
++CONFIG_CRYPTO_LRW=m
++CONFIG_CRYPTO_XTS=m
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_DES=m
++CONFIG_CRYPTO_FCRYPT=m
++CONFIG_CRYPTO_BLOWFISH=m
++CONFIG_CRYPTO_TWOFISH=m
++CONFIG_CRYPTO_TWOFISH_COMMON=m
++CONFIG_CRYPTO_SERPENT=m
++CONFIG_CRYPTO_AES=m
++CONFIG_CRYPTO_CAST5=m
++CONFIG_CRYPTO_CAST6=m
++CONFIG_CRYPTO_TEA=m
++CONFIG_CRYPTO_ARC4=m
++CONFIG_CRYPTO_KHAZAD=m
++CONFIG_CRYPTO_ANUBIS=m
++CONFIG_CRYPTO_SEED=m
++# CONFIG_CRYPTO_SALSA20 is not set
++CONFIG_CRYPTO_DEFLATE=m
++CONFIG_CRYPTO_MICHAEL_MIC=m
++CONFIG_CRYPTO_CRC32C=m
++CONFIG_CRYPTO_CAMELLIA=m
++CONFIG_CRYPTO_TEST=m
++CONFIG_CRYPTO_AUTHENC=m
++# CONFIG_CRYPTO_LZO is not set
++CONFIG_CRYPTO_HW=y
++# CONFIG_CRYPTO_DEV_HIFN_795X is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_CRC_CCITT=m
++CONFIG_CRC16=m
++CONFIG_CRC_ITU_T=m
++CONFIG_CRC32=y
++CONFIG_CRC7=m
++CONFIG_LIBCRC32C=m
++CONFIG_AUDIT_GENERIC=y
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
++CONFIG_TEXTSEARCH=y
++CONFIG_TEXTSEARCH_KMP=m
++CONFIG_TEXTSEARCH_BM=m
++CONFIG_TEXTSEARCH_FSM=m
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff --git a/arch/mips/configs/ip28_defconfig b/arch/mips/configs/ip28_defconfig
+new file mode 100644
+index 0000000..ec188be
+--- /dev/null
++++ b/arch/mips/configs/ip28_defconfig
+@@ -0,0 +1,891 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.25-rc1
++# Mon Feb 11 15:58:54 2008
++#
++CONFIG_MIPS=y
++
++#
++# Machine selection
++#
++# CONFIG_MACH_ALCHEMY is not set
++# CONFIG_BASLER_EXCITE is not set
++# CONFIG_BCM47XX is not set
++# CONFIG_MIPS_COBALT is not set
++# CONFIG_MACH_DECSTATION is not set
++# CONFIG_MACH_JAZZ is not set
++# CONFIG_LASAT is not set
++# CONFIG_LEMOTE_FULONG is not set
++# CONFIG_MIPS_ATLAS is not set
++# CONFIG_MIPS_MALTA is not set
++# CONFIG_MIPS_SEAD is not set
++# CONFIG_MIPS_SIM is not set
++# CONFIG_MARKEINS is not set
++# CONFIG_MACH_VR41XX is not set
++# CONFIG_PNX8550_JBS is not set
++# CONFIG_PNX8550_STB810 is not set
++# CONFIG_PMC_MSP is not set
++# CONFIG_PMC_YOSEMITE is not set
++# CONFIG_SGI_IP22 is not set
++# CONFIG_SGI_IP27 is not set
++CONFIG_SGI_IP28=y
++# CONFIG_SGI_IP32 is not set
++# CONFIG_SIBYTE_CRHINE is not set
++# CONFIG_SIBYTE_CARMEL is not set
++# CONFIG_SIBYTE_CRHONE is not set
++# CONFIG_SIBYTE_RHONE is not set
++# CONFIG_SIBYTE_SWARM is not set
++# CONFIG_SIBYTE_LITTLESUR is not set
++# CONFIG_SIBYTE_SENTOSA is not set
++# CONFIG_SIBYTE_BIGSUR is not set
++# CONFIG_SNI_RM is not set
++# CONFIG_TOSHIBA_JMR3927 is not set
++# CONFIG_TOSHIBA_RBTX4927 is not set
++# CONFIG_TOSHIBA_RBTX4938 is not set
++# CONFIG_WR_PPMC is not set
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_ARCH_SUPPORTS_OPROFILE=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CMOS_UPDATE=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
++# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
++CONFIG_ARC=y
++CONFIG_CEVT_R4K=y
++CONFIG_CSRC_R4K=y
++CONFIG_DMA_NONCOHERENT=y
++CONFIG_DMA_NEED_PCI_MAP_STATE=y
++CONFIG_EARLY_PRINTK=y
++CONFIG_SYS_HAS_EARLY_PRINTK=y
++# CONFIG_HOTPLUG_CPU is not set
++CONFIG_I8259=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_ISA_DMA=y
++CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y
++CONFIG_CPU_BIG_ENDIAN=y
++# CONFIG_CPU_LITTLE_ENDIAN is not set
++CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
++CONFIG_IRQ_CPU=y
++CONFIG_SWAP_IO_SPACE=y
++CONFIG_SGI_HAS_DS1286=y
++CONFIG_SGI_HAS_INDYDOG=y
++CONFIG_SGI_HAS_SEEQ=y
++CONFIG_SGI_HAS_WD93=y
++CONFIG_SGI_HAS_ZILOG=y
++CONFIG_SGI_HAS_I8042=y
++CONFIG_DEFAULT_SGI_PARTITION=y
++CONFIG_MIPS_L1_CACHE_SHIFT=7
++CONFIG_ARC_CONSOLE=y
++CONFIG_ARC_PROMLIB=y
++CONFIG_ARC64=y
++CONFIG_BOOT_ELF64=y
++
++#
++# CPU selection
++#
++# CONFIG_CPU_LOONGSON2 is not set
++# CONFIG_CPU_MIPS32_R1 is not set
++# CONFIG_CPU_MIPS32_R2 is not set
++# CONFIG_CPU_MIPS64_R1 is not set
++# CONFIG_CPU_MIPS64_R2 is not set
++# CONFIG_CPU_R3000 is not set
++# CONFIG_CPU_TX39XX is not set
++# CONFIG_CPU_VR41XX is not set
++# CONFIG_CPU_R4300 is not set
++# CONFIG_CPU_R4X00 is not set
++# CONFIG_CPU_TX49XX is not set
++# CONFIG_CPU_R5000 is not set
++# CONFIG_CPU_R5432 is not set
++# CONFIG_CPU_R6000 is not set
++# CONFIG_CPU_NEVADA is not set
++# CONFIG_CPU_R8000 is not set
++CONFIG_CPU_R10000=y
++# CONFIG_CPU_RM7000 is not set
++# CONFIG_CPU_RM9000 is not set
++# CONFIG_CPU_SB1 is not set
++CONFIG_SYS_HAS_CPU_R10000=y
++CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
++CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
++
++#
++# Kernel type
++#
++# CONFIG_32BIT is not set
++CONFIG_64BIT=y
++CONFIG_PAGE_SIZE_4KB=y
++# CONFIG_PAGE_SIZE_8KB is not set
++# CONFIG_PAGE_SIZE_16KB is not set
++# CONFIG_PAGE_SIZE_64KB is not set
++CONFIG_CPU_HAS_PREFETCH=y
++CONFIG_MIPS_MT_DISABLED=y
++# CONFIG_MIPS_MT_SMP is not set
++# CONFIG_MIPS_MT_SMTC is not set
++CONFIG_CPU_HAS_LLSC=y
++CONFIG_CPU_HAS_SYNC=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_CPU_SUPPORTS_HIGHMEM=y
++CONFIG_ARCH_FLATMEM_ENABLE=y
++CONFIG_ARCH_POPULATES_NODE_MAP=y
++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_SPLIT_PTLOCK_CPUS=4
++CONFIG_RESOURCES_64BIT=y
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++# 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_HZ_48 is not set
++# CONFIG_HZ_100 is not set
++# CONFIG_HZ_128 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_256 is not set
++# CONFIG_HZ_1000 is not set
++# CONFIG_HZ_1024 is not set
++CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
++CONFIG_HZ=250
++# CONFIG_PREEMPT_NONE is not set
++CONFIG_PREEMPT_VOLUNTARY=y
++# CONFIG_PREEMPT is not set
++# CONFIG_RCU_TRACE is not set
++# CONFIG_MIPS_INSANE_LARGE is not set
++# CONFIG_KEXEC is not set
++CONFIG_SECCOMP=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_STACKTRACE_SUPPORT=y
++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_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_FAIR_GROUP_SCHED=y
++CONFIG_FAIR_USER_SCHED=y
++# CONFIG_FAIR_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_RELAY=y
++# CONFIG_NAMESPACES is not set
++# CONFIG_BLK_DEV_INITRD is not set
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++# CONFIG_HOTPLUG is not set
++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_HAVE_KPROBES is not set
++# CONFIG_PROC_PAGE_MONITOR is not set
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++CONFIG_MODVERSIONS=y
++CONFIG_MODULE_SRCVERSION_ALL=y
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_BLK_DEV_BSG is not set
++CONFIG_BLOCK_COMPAT=y
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++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
++# CONFIG_PREEMPT_RCU is not set
++
++#
++# Bus options (PCI, PCMCIA, EISA, ISA, TC)
++#
++CONFIG_HW_HAS_EISA=y
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++CONFIG_ISA=y
++CONFIG_EISA=y
++CONFIG_EISA_NAMES=y
++CONFIG_MMU=y
++CONFIG_I8253=y
++
++#
++# Executable file formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_MIPS32_COMPAT=y
++CONFIG_COMPAT=y
++CONFIG_SYSVIPC_COMPAT=y
++CONFIG_MIPS32_O32=y
++CONFIG_MIPS32_N32=y
++CONFIG_BINFMT_ELF32=y
++
++#
++# Power management options
++#
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_PM=y
++# CONFIG_PM_LEGACY is not set
++# CONFIG_PM_DEBUG is not set
++# CONFIG_SUSPEND is not set
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++CONFIG_XFRM_MIGRATE=y
++# CONFIG_XFRM_STATISTICS is not set
++CONFIG_NET_KEY=y
++CONFIG_NET_KEY_MIGRATE=y
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# 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_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
++# 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=y
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL 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_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++# 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 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=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=y
++# CONFIG_BLK_DEV_SR_VENDOR 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 is not set
++CONFIG_SCSI_CONSTANTS=y
++# 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_SGIWD93_SCSI=y
++# CONFIG_SCSI_AHA1740 is not set
++# CONFIG_SCSI_AIC7XXX is not set
++# CONFIG_SCSI_AIC7XXX_OLD is not set
++# CONFIG_SCSI_ADVANSYS is not set
++# CONFIG_SCSI_IN2000 is not set
++# CONFIG_SCSI_DTC3280 is not set
++# CONFIG_SCSI_FUTURE_DOMAIN 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_SIM710 is not set
++# CONFIG_SCSI_SYM53C416 is not set
++# CONFIG_SCSI_T128 is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++CONFIG_DUMMY=m
++# 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 is not set
++# CONFIG_AX88796 is not set
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_NET_VENDOR_SMC is not set
++# CONFIG_DM9000 is not set
++# CONFIG_NET_VENDOR_RACAL is not set
++# CONFIG_NET_TULIP 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 is not set
++# CONFIG_B44 is not set
++CONFIG_SGISEEQ=y
++# 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 is not set
++# CONFIG_WAN is not set
++# CONFIG_FDDI 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
++# CONFIG_PHONE 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=y
++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=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_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++# CONFIG_MOUSE_PS2_ALPS is not set
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++# CONFIG_MOUSE_PS2_SYNAPTICS is not set
++# CONFIG_MOUSE_PS2_LIFEBOOK is not set
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++# 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_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=y
++CONFIG_SERIO_I8042=y
++CONFIG_SERIO_SERPORT=y
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++CONFIG_VT_HW_CONSOLE_BINDING=y
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_IP22_ZILOG=y
++CONFIG_SERIAL_IP22_ZILOG_CONSOLE=y
++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_RTC is not set
++CONFIG_SGI_DS1286=y
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_DEVPORT=y
++# CONFIG_I2C is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_INDYDOG=y
++
++#
++# ISA-based Watchdog Cards
++#
++# CONFIG_PCWATCHDOG is not set
++# CONFIG_MIXCOMWD is not set
++# CONFIG_WDT is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# 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_MDA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++# CONFIG_HID_DEBUG is not set
++# CONFIG_HIDRAW is not set
++CONFIG_USB_SUPPORT=y
++# CONFIG_USB_ARCH_HAS_HCD is not set
++# CONFIG_USB_ARCH_HAS_OHCI is not set
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++# CONFIG_USB_GADGET is not set
++# CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++# CONFIG_RTC_CLASS is not set
++
++#
++# Userspace I/O
++#
++# 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=y
++CONFIG_EXT3_FS_SECURITY=y
++# 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=y
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++CONFIG_QUOTA=y
++# CONFIG_QUOTA_NETLINK_INTERFACE is not set
++CONFIG_PRINT_QUOTA_WARNING=y
++# CONFIG_QFMT_V1 is not set
++# CONFIG_QFMT_V2 is not set
++CONFIG_QUOTACTL=y
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++CONFIG_GENERIC_ACL=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# 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_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_KCORE=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++# 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_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=y
++# CONFIG_NFS_V4 is not set
++# CONFIG_NFS_DIRECTIO is not set
++# CONFIG_NFSD is not set
++CONFIG_ROOT_NFS=y
++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_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=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++CONFIG_SGI_PARTITION=y
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++# CONFIG_NLS is not set
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++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 is not set
++# CONFIG_SAMPLES is not set
++CONFIG_CMDLINE=""
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++# CONFIG_CRYPTO_SEQIV is not set
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_LZO is not set
++# CONFIG_CRYPTO_HW is not set
++
++#
++# Library routines
++#
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++# CONFIG_CRC32 is not set
++# 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/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig
+deleted file mode 100644
+index 72ca147..0000000
+--- a/arch/mips/configs/qemu_defconfig
++++ /dev/null
+@@ -1,800 +0,0 @@
+-#
+-# Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.20
+-# Tue Feb 20 21:47:39 2007
+-#
+-CONFIG_MIPS=y
+-
+-#
+-# Machine selection
+-#
+-CONFIG_ZONE_DMA=y
+-# CONFIG_MIPS_MTX1 is not set
+-# CONFIG_MIPS_BOSPORUS is not set
+-# CONFIG_MIPS_PB1000 is not set
+-# CONFIG_MIPS_PB1100 is not set
+-# CONFIG_MIPS_PB1500 is not set
+-# CONFIG_MIPS_PB1550 is not set
+-# CONFIG_MIPS_PB1200 is not set
+-# CONFIG_MIPS_DB1000 is not set
+-# CONFIG_MIPS_DB1100 is not set
+-# CONFIG_MIPS_DB1500 is not set
+-# CONFIG_MIPS_DB1550 is not set
+-# CONFIG_MIPS_DB1200 is not set
+-# CONFIG_MIPS_MIRAGE is not set
+-# CONFIG_BASLER_EXCITE is not set
+-# CONFIG_MIPS_COBALT is not set
+-# CONFIG_MACH_DECSTATION is not set
+-# CONFIG_MACH_JAZZ is not set
+-# CONFIG_MIPS_ATLAS is not set
+-# CONFIG_MIPS_MALTA is not set
+-# CONFIG_MIPS_SEAD is not set
+-# CONFIG_WR_PPMC is not set
+-# CONFIG_MIPS_SIM is not set
+-# CONFIG_MOMENCO_JAGUAR_ATX is not set
+-# CONFIG_MIPS_XXS1500 is not set
+-# CONFIG_PNX8550_JBS is not set
+-# CONFIG_PNX8550_STB810 is not set
+-# CONFIG_MACH_VR41XX is not set
+-# CONFIG_PMC_YOSEMITE is not set
+-# CONFIG_MARKEINS is not set
+-# CONFIG_SGI_IP22 is not set
+-# CONFIG_SGI_IP27 is not set
+-# CONFIG_SGI_IP32 is not set
+-# CONFIG_SIBYTE_BIGSUR is not set
+-# CONFIG_SIBYTE_SWARM is not set
+-# CONFIG_SIBYTE_SENTOSA is not set
+-# CONFIG_SIBYTE_RHONE is not set
+-# CONFIG_SIBYTE_CARMEL is not set
+-# CONFIG_SIBYTE_LITTLESUR is not set
+-# CONFIG_SIBYTE_CRHINE is not set
+-# CONFIG_SIBYTE_CRHONE is not set
+-# CONFIG_SNI_RM is not set
+-# CONFIG_TOSHIBA_JMR3927 is not set
+-# CONFIG_TOSHIBA_RBTX4927 is not set
+-# CONFIG_TOSHIBA_RBTX4938 is not set
+-CONFIG_RWSEM_GENERIC_SPINLOCK=y
+-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+-CONFIG_GENERIC_FIND_NEXT_BIT=y
+-CONFIG_GENERIC_HWEIGHT=y
+-CONFIG_GENERIC_CALIBRATE_DELAY=y
+-CONFIG_GENERIC_TIME=y
+-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+-CONFIG_DMA_COHERENT=y
+-CONFIG_GENERIC_ISA_DMA=y
+-CONFIG_I8259=y
+-CONFIG_CPU_BIG_ENDIAN=y
+-# CONFIG_CPU_LITTLE_ENDIAN is not set
+-CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+-CONFIG_SWAP_IO_SPACE=y
+-CONFIG_MIPS_L1_CACHE_SHIFT=5
+-CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+-
+-#
+-# CPU selection
+-#
+-CONFIG_CPU_MIPS32_R1=y
+-# CONFIG_CPU_MIPS32_R2 is not set
+-# CONFIG_CPU_MIPS64_R1 is not set
+-# CONFIG_CPU_MIPS64_R2 is not set
+-# CONFIG_CPU_R3000 is not set
+-# CONFIG_CPU_TX39XX is not set
+-# CONFIG_CPU_VR41XX is not set
+-# CONFIG_CPU_R4300 is not set
+-# CONFIG_CPU_R4X00 is not set
+-# CONFIG_CPU_TX49XX is not set
+-# CONFIG_CPU_R5000 is not set
+-# CONFIG_CPU_R5432 is not set
+-# CONFIG_CPU_R6000 is not set
+-# CONFIG_CPU_NEVADA is not set
+-# CONFIG_CPU_R8000 is not set
+-# CONFIG_CPU_R10000 is not set
+-# CONFIG_CPU_RM7000 is not set
+-# CONFIG_CPU_RM9000 is not set
+-# CONFIG_CPU_SB1 is not set
+-CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+-CONFIG_CPU_MIPS32=y
+-CONFIG_CPU_MIPSR1=y
+-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+-
+-#
+-# Kernel type
+-#
+-CONFIG_32BIT=y
+-# CONFIG_64BIT is not set
+-CONFIG_PAGE_SIZE_4KB=y
+-# CONFIG_PAGE_SIZE_8KB is not set
+-# CONFIG_PAGE_SIZE_16KB is not set
+-# CONFIG_PAGE_SIZE_64KB is not set
+-CONFIG_CPU_HAS_PREFETCH=y
+-CONFIG_MIPS_MT_DISABLED=y
+-# CONFIG_MIPS_MT_SMP is not set
+-# CONFIG_MIPS_MT_SMTC is not set
+-# CONFIG_MIPS_VPE_LOADER is not set
+-# CONFIG_64BIT_PHYS_ADDR is not set
+-CONFIG_CPU_HAS_LLSC=y
+-CONFIG_CPU_HAS_SYNC=y
+-CONFIG_GENERIC_HARDIRQS=y
+-CONFIG_GENERIC_IRQ_PROBE=y
+-CONFIG_CPU_SUPPORTS_HIGHMEM=y
+-CONFIG_ARCH_FLATMEM_ENABLE=y
+-CONFIG_ARCH_SPARSEMEM_ENABLE=y
+-CONFIG_FLATMEM=y
+-CONFIG_FLAT_NODE_MEM_MAP=y
+-CONFIG_SPARSEMEM_STATIC=y
+-CONFIG_SPLIT_PTLOCK_CPUS=4
+-# CONFIG_RESOURCES_64BIT is not set
+-CONFIG_ZONE_DMA_FLAG=1
+-# CONFIG_HZ_48 is not set
+-CONFIG_HZ_100=y
+-# CONFIG_HZ_128 is not set
+-# CONFIG_HZ_250 is not set
+-# CONFIG_HZ_256 is not set
+-# CONFIG_HZ_1000 is not set
+-# CONFIG_HZ_1024 is not set
+-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+-CONFIG_HZ=100
+-CONFIG_PREEMPT_NONE=y
+-# CONFIG_PREEMPT_VOLUNTARY is not set
+-# CONFIG_PREEMPT is not set
+-CONFIG_LOCKDEP_SUPPORT=y
+-CONFIG_STACKTRACE_SUPPORT=y
+-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+-
+-#
+-# Code maturity level options
+-#
+-# CONFIG_EXPERIMENTAL is not set
+-CONFIG_BROKEN_ON_SMP=y
+-CONFIG_INIT_ENV_ARG_LIMIT=32
+-
+-#
+-# General setup
+-#
+-CONFIG_LOCALVERSION=""
+-CONFIG_LOCALVERSION_AUTO=y
+-# CONFIG_SWAP is not set
+-# CONFIG_SYSVIPC is not set
+-# CONFIG_BSD_PROCESS_ACCT is not set
+-# CONFIG_TASKSTATS is not set
+-# CONFIG_UTS_NS is not set
+-# CONFIG_AUDIT is not set
+-# CONFIG_IKCONFIG is not set
+-CONFIG_SYSFS_DEPRECATED=y
+-CONFIG_RELAY=y
+-CONFIG_SYSCTL=y
+-CONFIG_EMBEDDED=y
+-CONFIG_SYSCTL_SYSCALL=y
+-CONFIG_KALLSYMS=y
+-# CONFIG_KALLSYMS_EXTRA_PASS is not set
+-# CONFIG_HOTPLUG is not set
+-CONFIG_PRINTK=y
+-# CONFIG_BUG is not set
+-CONFIG_ELF_CORE=y
+-# CONFIG_BASE_FULL is not set
+-# CONFIG_FUTEX is not set
+-# CONFIG_EPOLL is not set
+-# CONFIG_SHMEM is not set
+-CONFIG_SLAB=y
+-CONFIG_VM_EVENT_COUNTERS=y
+-CONFIG_TINY_SHMEM=y
+-CONFIG_BASE_SMALL=1
+-# CONFIG_SLOB is not set
+-
+-#
+-# Loadable module support
+-#
+-# CONFIG_MODULES is not set
+-
+-#
+-# Block layer
+-#
+-CONFIG_BLOCK=y
+-# CONFIG_LBD is not set
+-# CONFIG_BLK_DEV_IO_TRACE is not set
+-# CONFIG_LSF is not set
+-
+-#
+-# IO Schedulers
+-#
+-CONFIG_IOSCHED_NOOP=y
+-# CONFIG_IOSCHED_AS is not set
+-# CONFIG_IOSCHED_DEADLINE is not set
+-# CONFIG_IOSCHED_CFQ is not set
+-# CONFIG_DEFAULT_AS is not set
+-# CONFIG_DEFAULT_DEADLINE is not set
+-# CONFIG_DEFAULT_CFQ is not set
+-CONFIG_DEFAULT_NOOP=y
+-CONFIG_DEFAULT_IOSCHED="noop"
+-
+-#
+-# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+-#
+-CONFIG_ISA=y
+-CONFIG_MMU=y
+-CONFIG_PCSPEAKER=y
+-
+-#
+-# PCCARD (PCMCIA/CardBus) support
+-#
+-
+-#
+-# PCI Hotplug Support
+-#
+-
+-#
+-# Executable file formats
+-#
+-CONFIG_BINFMT_ELF=y
+-# CONFIG_BINFMT_MISC is not set
+-CONFIG_TRAD_SIGNALS=y
+-
+-#
+-# Power management options
+-#
+-CONFIG_PM=y
+-# CONFIG_PM_LEGACY is not set
+-# CONFIG_PM_DEBUG is not set
+-# CONFIG_PM_SYSFS_DEPRECATED is not set
+-
+-#
+-# Networking
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-# CONFIG_NETDEBUG is not set
+-CONFIG_PACKET=y
+-CONFIG_PACKET_MMAP=y
+-CONFIG_UNIX=y
+-CONFIG_XFRM=y
+-# CONFIG_XFRM_USER 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=y
+-CONFIG_IP_PNP_DHCP=y
+-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_IP_MROUTE 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=y
+-CONFIG_INET_XFRM_MODE_TUNNEL=y
+-CONFIG_INET_XFRM_MODE_BEET=y
+-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_IPV6 is not set
+-# CONFIG_INET6_XFRM_TUNNEL is not set
+-# CONFIG_INET6_TUNNEL is not set
+-CONFIG_NETWORK_SECMARK=y
+-# CONFIG_NETFILTER 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
+-
+-#
+-# QoS and/or fair queueing
+-#
+-# CONFIG_NET_SCHED is not set
+-
+-#
+-# Network testing
+-#
+-# CONFIG_NET_PKTGEN is not set
+-# CONFIG_HAMRADIO is not set
+-# CONFIG_IRDA is not set
+-# CONFIG_BT is not set
+-# CONFIG_IEEE80211 is not set
+-
+-#
+-# Device Drivers
+-#
+-
+-#
+-# Generic Driver Options
+-#
+-CONFIG_STANDALONE=y
+-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+-# CONFIG_SYS_HYPERVISOR is not set
+-
+-#
+-# Connector - unified userspace <-> kernelspace linker
+-#
+-CONFIG_CONNECTOR=y
+-CONFIG_PROC_EVENTS=y
+-
+-#
+-# Memory Technology Devices (MTD)
+-#
+-# CONFIG_MTD is not set
+-
+-#
+-# Parallel port support
+-#
+-# CONFIG_PARPORT is not set
+-
+-#
+-# Plug and Play support
+-#
+-# CONFIG_PNP is not set
+-# CONFIG_PNPACPI is not set
+-
+-#
+-# Block devices
+-#
+-# 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_RAM is not set
+-# CONFIG_BLK_DEV_INITRD is not set
+-# CONFIG_CDROM_PKTCDVD is not set
+-# CONFIG_ATA_OVER_ETH is not set
+-
+-#
+-# Misc devices
+-#
+-
+-#
+-# ATA/ATAPI/MFM/RLL support
+-#
+-# CONFIG_IDE is not set
+-
+-#
+-# SCSI device support
+-#
+-# CONFIG_RAID_ATTRS is not set
+-# CONFIG_SCSI is not set
+-# CONFIG_SCSI_NETLINK is not set
+-
+-#
+-# Serial ATA (prod) and Parallel ATA (experimental) drivers
+-#
+-# CONFIG_ATA is not set
+-
+-#
+-# Old CD-ROM drivers (not SCSI, not IDE)
+-#
+-# CONFIG_CD_NO_IDESCSI is not set
+-
+-#
+-# Multi-device support (RAID and LVM)
+-#
+-# CONFIG_MD is not set
+-
+-#
+-# Fusion MPT device support
+-#
+-# CONFIG_FUSION is not set
+-
+-#
+-# IEEE 1394 (FireWire) support
+-#
+-
+-#
+-# I2O device support
+-#
+-
+-#
+-# Network device support
+-#
+-CONFIG_NETDEVICES=y
+-# CONFIG_DUMMY is not set
+-# CONFIG_BONDING is not set
+-# CONFIG_EQUALIZER is not set
+-# CONFIG_TUN is not set
+-
+-#
+-# ARCnet devices
+-#
+-# CONFIG_ARCNET is not set
+-
+-#
+-# PHY device support
+-#
+-# CONFIG_PHYLIB is not set
+-
+-#
+-# Ethernet (10 or 100Mbit)
+-#
+-CONFIG_NET_ETHERNET=y
+-# CONFIG_MII is not set
+-# CONFIG_NET_VENDOR_3COM is not set
+-# CONFIG_NET_VENDOR_SMC is not set
+-# CONFIG_DM9000 is not set
+-# CONFIG_NET_VENDOR_RACAL is not set
+-# CONFIG_DEPCA is not set
+-# CONFIG_HP100 is not set
+-CONFIG_NET_ISA=y
+-# CONFIG_E2100 is not set
+-# CONFIG_EWRK3 is not set
+-# CONFIG_EEXPRESS is not set
+-# CONFIG_EEXPRESS_PRO is not set
+-# CONFIG_HPLAN_PLUS is not set
+-# CONFIG_HPLAN is not set
+-# CONFIG_LP486E is not set
+-# CONFIG_ETH16I is not set
+-CONFIG_NE2000=y
+-# CONFIG_NET_PCI is not set
+-
+-#
+-# Ethernet (1000 Mbit)
+-#
+-
+-#
+-# Ethernet (10000 Mbit)
+-#
+-
+-#
+-# Token Ring devices
+-#
+-# CONFIG_TR is not set
+-
+-#
+-# Wireless LAN (non-hamradio)
+-#
+-# CONFIG_NET_RADIO is not set
+-
+-#
+-# Wan interfaces
+-#
+-# CONFIG_WAN is not set
+-# CONFIG_PPP is not set
+-# CONFIG_SLIP is not set
+-# CONFIG_NETPOLL is not set
+-# CONFIG_NET_POLL_CONTROLLER is not set
+-
+-#
+-# ISDN subsystem
+-#
+-# CONFIG_ISDN is not set
+-
+-#
+-# Telephony Support
+-#
+-# CONFIG_PHONE is not set
+-
+-#
+-# Input device support
+-#
+-CONFIG_INPUT=y
+-# CONFIG_INPUT_FF_MEMLESS is not set
+-
+-#
+-# Userland interfaces
+-#
+-# CONFIG_INPUT_MOUSEDEV is not set
+-# CONFIG_INPUT_JOYDEV is not set
+-# CONFIG_INPUT_TSDEV 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_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_VT_CONSOLE=y
+-CONFIG_HW_CONSOLE=y
+-CONFIG_VT_HW_CONSOLE_BINDING=y
+-# CONFIG_SERIAL_NONSTANDARD is not set
+-
+-#
+-# Serial drivers
+-#
+-CONFIG_SERIAL_8250=y
+-CONFIG_SERIAL_8250_CONSOLE=y
+-CONFIG_SERIAL_8250_NR_UARTS=4
+-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+-# CONFIG_SERIAL_8250_EXTENDED is not set
+-
+-#
+-# Non-8250 serial port support
+-#
+-CONFIG_SERIAL_CORE=y
+-CONFIG_SERIAL_CORE_CONSOLE=y
+-CONFIG_UNIX98_PTYS=y
+-CONFIG_LEGACY_PTYS=y
+-CONFIG_LEGACY_PTY_COUNT=256
+-
+-#
+-# IPMI
+-#
+-# CONFIG_IPMI_HANDLER is not set
+-
+-#
+-# Watchdog Cards
+-#
+-# CONFIG_WATCHDOG is not set
+-# CONFIG_HW_RANDOM is not set
+-# CONFIG_RTC is not set
+-# CONFIG_GEN_RTC is not set
+-# CONFIG_DTLK is not set
+-# CONFIG_R3964 is not set
+-# CONFIG_RAW_DRIVER is not set
+-
+-#
+-# TPM devices
+-#
+-
+-#
+-# I2C support
+-#
+-# CONFIG_I2C is not set
+-
+-#
+-# SPI support
+-#
+-# CONFIG_SPI is not set
+-# CONFIG_SPI_MASTER is not set
+-
+-#
+-# Dallas's 1-wire bus
+-#
+-# CONFIG_W1 is not set
+-
+-#
+-# Hardware Monitoring support
+-#
+-# CONFIG_HWMON is not set
+-# CONFIG_HWMON_VID is not set
+-
+-#
+-# Multimedia devices
+-#
+-# CONFIG_VIDEO_DEV is not set
+-
+-#
+-# Digital Video Broadcasting Devices
+-#
+-# CONFIG_DVB is not set
+-
+-#
+-# Graphics support
+-#
+-# CONFIG_FIRMWARE_EDID is not set
+-# CONFIG_FB is not set
+-
+-#
+-# Console display driver support
+-#
+-CONFIG_VGA_CONSOLE=y
+-# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+-# CONFIG_MDA_CONSOLE is not set
+-CONFIG_DUMMY_CONSOLE=y
+-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+-
+-#
+-# Sound
+-#
+-# CONFIG_SOUND is not set
+-
+-#
+-# HID Devices
+-#
+-CONFIG_HID=y
+-# CONFIG_HID_DEBUG is not set
+-
+-#
+-# USB support
+-#
+-# CONFIG_USB_ARCH_HAS_HCD is not set
+-# CONFIG_USB_ARCH_HAS_OHCI is not set
+-# CONFIG_USB_ARCH_HAS_EHCI is not set
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+-#
+-
+-#
+-# USB Gadget Support
+-#
+-# CONFIG_USB_GADGET is not set
+-
+-#
+-# MMC/SD Card support
+-#
+-# CONFIG_MMC is not set
+-
+-#
+-# LED devices
+-#
+-# CONFIG_NEW_LEDS is not set
+-
+-#
+-# LED drivers
+-#
+-
+-#
+-# LED Triggers
+-#
+-
+-#
+-# InfiniBand support
+-#
+-
+-#
+-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+-#
+-
+-#
+-# Real Time Clock
+-#
+-
+-#
+-# DMA Engine support
+-#
+-# CONFIG_DMA_ENGINE is not set
+-
+-#
+-# DMA Clients
+-#
+-
+-#
+-# DMA Devices
+-#
+-
+-#
+-# Auxiliary Display support
+-#
+-
+-#
+-# Virtualization
+-#
+-
+-#
+-# File systems
+-#
+-# CONFIG_EXT2_FS is not set
+-# CONFIG_EXT3_FS is not set
+-# CONFIG_REISERFS_FS is not set
+-# CONFIG_JFS_FS is not set
+-CONFIG_FS_POSIX_ACL=y
+-# CONFIG_XFS_FS is not set
+-# CONFIG_OCFS2_FS is not set
+-# CONFIG_MINIX_FS is not set
+-# CONFIG_ROMFS_FS is not set
+-CONFIG_INOTIFY=y
+-CONFIG_INOTIFY_USER=y
+-# CONFIG_QUOTA is not set
+-# CONFIG_DNOTIFY is not set
+-# CONFIG_AUTOFS_FS is not set
+-# CONFIG_AUTOFS4_FS is not set
+-CONFIG_FUSE_FS=y
+-CONFIG_GENERIC_ACL=y
+-
+-#
+-# CD-ROM/DVD Filesystems
+-#
+-# 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_NTFS_FS is not set
+-
+-#
+-# Pseudo filesystems
+-#
+-CONFIG_PROC_FS=y
+-CONFIG_PROC_KCORE=y
+-CONFIG_PROC_SYSCTL=y
+-CONFIG_SYSFS=y
+-CONFIG_TMPFS=y
+-CONFIG_TMPFS_POSIX_ACL=y
+-# CONFIG_HUGETLB_PAGE is not set
+-CONFIG_RAMFS=y
+-
+-#
+-# Miscellaneous filesystems
+-#
+-# CONFIG_HFSPLUS_FS is not set
+-# CONFIG_CRAMFS is not set
+-# CONFIG_VXFS_FS is not set
+-# CONFIG_HPFS_FS is not set
+-# CONFIG_QNX4FS_FS is not set
+-# CONFIG_SYSV_FS is not set
+-# CONFIG_UFS_FS is not set
+-
+-#
+-# Network File Systems
+-#
+-CONFIG_NFS_FS=y
+-CONFIG_NFS_V3=y
+-# CONFIG_NFS_V3_ACL is not set
+-CONFIG_NFS_DIRECTIO=y
+-# CONFIG_NFSD is not set
+-CONFIG_ROOT_NFS=y
+-CONFIG_LOCKD=y
+-CONFIG_LOCKD_V4=y
+-CONFIG_NFS_COMMON=y
+-CONFIG_SUNRPC=y
+-# CONFIG_SMB_FS is not set
+-# CONFIG_CIFS is not set
+-# CONFIG_NCP_FS is not set
+-# CONFIG_CODA_FS is not set
+-
+-#
+-# Partition Types
+-#
+-# CONFIG_PARTITION_ADVANCED is not set
+-CONFIG_MSDOS_PARTITION=y
+-
+-#
+-# Native Language Support
+-#
+-# CONFIG_NLS is not set
+-
+-#
+-# Kernel hacking
+-#
+-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+-# CONFIG_PRINTK_TIME is not set
+-CONFIG_ENABLE_MUST_CHECK=y
+-# 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_LOG_BUF_SHIFT=14
+-CONFIG_CROSSCOMPILE=y
+-CONFIG_CMDLINE=""
+-
+-#
+-# Security options
+-#
+-# CONFIG_KEYS is not set
+-# CONFIG_SECURITY is not set
+-
+-#
+-# Cryptographic options
+-#
+-# CONFIG_CRYPTO is not set
+-
+-#
+-# Library routines
+-#
+-CONFIG_BITREVERSE=y
+-# CONFIG_CRC_CCITT is not set
+-# CONFIG_CRC16 is not set
+-CONFIG_CRC32=y
+-# CONFIG_LIBCRC32C is not set
+-CONFIG_HAS_IOMEM=y
+-CONFIG_HAS_IOPORT=y
+diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c
+index 971adf6..fb50cc7 100644
+--- a/arch/mips/kernel/irq-rm7000.c
++++ b/arch/mips/kernel/irq-rm7000.c
+@@ -33,6 +33,7 @@ static struct irq_chip rm7k_irq_controller = {
+ 	.mask = mask_rm7k_irq,
+ 	.mask_ack = mask_rm7k_irq,
+ 	.unmask = unmask_rm7k_irq,
++	.eoi	= unmask_rm7k_irq
+ };
+ 
+ void __init rm7k_cpu_irq_init(void)
+diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c
+index 7b04583..ed9febe 100644
+--- a/arch/mips/kernel/irq-rm9000.c
++++ b/arch/mips/kernel/irq-rm9000.c
+@@ -75,6 +75,7 @@ static struct irq_chip rm9k_irq_controller = {
+ 	.mask = mask_rm9k_irq,
+ 	.mask_ack = mask_rm9k_irq,
+ 	.unmask = unmask_rm9k_irq,
++	.eoi	= unmask_rm9k_irq
+ };
+ 
+ static struct irq_chip rm9k_perfcounter_irq = {
+diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c
+index bb4f00c..df4d3f2 100644
+--- a/arch/mips/kernel/mips-mt-fpaff.c
++++ b/arch/mips/kernel/mips-mt-fpaff.c
+@@ -36,7 +36,7 @@ unsigned long mt_fpemul_threshold = 0;
+  */
+ static inline struct task_struct *find_process_by_pid(pid_t pid)
+ {
+-	return pid ? find_task_by_pid(pid) : current;
++	return pid ? find_task_by_vpid(pid) : current;
+ }
+ 
+ 
+diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
+index f798139..08a9c50 100644
+--- a/arch/mips/kernel/scall32-o32.S
++++ b/arch/mips/kernel/scall32-o32.S
+@@ -663,6 +663,9 @@ einval:	li	v0, -EINVAL
+ 	sys	sys_ni_syscall		0
+ 	sys	sys_eventfd		1
+ 	sys	sys_fallocate		6	/* 4320 */
++	sys	sys_timerfd_create	2
++	sys	sys_timerfd_gettime	2
++	sys	sys_timerfd_settime	4
+ 	.endm
+ 
+ 	/* We pre-compute the number of _instruction_ bytes needed to
+diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
+index a626be6..dc597b6 100644
+--- a/arch/mips/kernel/scall64-64.S
++++ b/arch/mips/kernel/scall64-64.S
+@@ -478,4 +478,7 @@ sys_call_table:
+ 	PTR	sys_ni_syscall
+ 	PTR	sys_eventfd
+ 	PTR	sys_fallocate
++	PTR	sys_timerfd_create		/* 5280 */
++	PTR	sys_timerfd_gettime
++	PTR	sys_timerfd_settime
+ 	.size	sys_call_table,.-sys_call_table
+diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
+index 9d5bcaf..12940ec 100644
+--- a/arch/mips/kernel/scall64-n32.S
++++ b/arch/mips/kernel/scall64-n32.S
+@@ -404,4 +404,7 @@ EXPORT(sysn32_call_table)
+ 	PTR	sys_ni_syscall
+ 	PTR	sys_eventfd
+ 	PTR	sys_fallocate
++	PTR	sys_timerfd_create
++	PTR	sys_timerfd_gettime		/* 5285 */
++	PTR	sys_timerfd_settime
+ 	.size	sysn32_call_table,.-sysn32_call_table
+diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
+index fd2019c..9a275ef 100644
+--- a/arch/mips/kernel/scall64-o32.S
++++ b/arch/mips/kernel/scall64-o32.S
+@@ -526,4 +526,7 @@ sys_call_table:
+ 	PTR	sys_ni_syscall
+ 	PTR	sys_eventfd
+ 	PTR	sys32_fallocate			/* 4320 */
++	PTR	sys_timerfd_create
++	PTR	sys_timerfd_gettime
++	PTR	sys_timerfd_settime
+ 	.size	sys_call_table,.-sys_call_table
+diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
+index 672fba8..c357762 100644
+--- a/arch/mips/kernel/sysirix.c
++++ b/arch/mips/kernel/sysirix.c
+@@ -111,7 +111,7 @@ asmlinkage int irix_prctl(unsigned option, ...)
+ 		printk("irix_prctl[%s:%d]: Wants PR_ISBLOCKED\n",
+ 		       current->comm, current->pid);
+ 		read_lock(&tasklist_lock);
+-		task = find_task_by_pid(va_arg(args, pid_t));
++		task = find_task_by_vpid(va_arg(args, pid_t));
+ 		error = -ESRCH;
+ 		if (error)
+ 			error = (task->run_list.next != NULL);
+diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
+index 53ec052..2c4f7e1 100644
+--- a/arch/mips/mm/c-r4k.c
++++ b/arch/mips/mm/c-r4k.c
+@@ -364,20 +364,23 @@ static inline int has_valid_asid(const struct mm_struct *mm)
+ static inline void local_r4k_flush_cache_range(void * args)
+ {
+ 	struct vm_area_struct *vma = args;
++	int exec = vma->vm_flags & VM_EXEC;
+ 
+ 	if (!(has_valid_asid(vma->vm_mm)))
+ 		return;
+ 
+ 	r4k_blast_dcache();
++	if (exec)
++		r4k_blast_icache();
+ }
+ 
+ static void r4k_flush_cache_range(struct vm_area_struct *vma,
+ 	unsigned long start, unsigned long end)
+ {
+-	if (!cpu_has_dc_aliases)
+-		return;
++	int exec = vma->vm_flags & VM_EXEC;
+ 
+-	r4k_on_each_cpu(local_r4k_flush_cache_range, vma, 1, 1);
++	if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc))
++		r4k_on_each_cpu(local_r4k_flush_cache_range, vma, 1, 1);
+ }
+ 
+ static inline void local_r4k_flush_cache_mm(void * args)
+diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
+index 81f30ac..6a24651 100644
+--- a/arch/mips/mm/cache.c
++++ b/arch/mips/mm/cache.c
+@@ -92,12 +92,17 @@ EXPORT_SYMBOL(__flush_dcache_page);
+ 
+ void __flush_anon_page(struct page *page, unsigned long vmaddr)
+ {
+-	if (pages_do_alias((unsigned long)page_address(page), vmaddr)) {
+-		void *kaddr;
++	unsigned long addr = (unsigned long) page_address(page);
+ 
+-		kaddr = kmap_coherent(page, vmaddr);
+-		flush_data_cache_page((unsigned long)kaddr);
+-		kunmap_coherent();
++	if (pages_do_alias(addr, vmaddr)) {
++		if (page_mapped(page) && !Page_dcache_dirty(page)) {
++			void *kaddr;
++
++			kaddr = kmap_coherent(page, vmaddr);
++			flush_data_cache_page((unsigned long)kaddr);
++			kunmap_coherent();
++		} else
++			flush_data_cache_page(addr);
+ 	}
+ }
+ 
+diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
+index 480dec0..c7aed13 100644
+--- a/arch/mips/mm/init.c
++++ b/arch/mips/mm/init.c
+@@ -211,7 +211,8 @@ void copy_user_highpage(struct page *to, struct page *from,
+ 	void *vfrom, *vto;
+ 
+ 	vto = kmap_atomic(to, KM_USER1);
+-	if (cpu_has_dc_aliases && page_mapped(from)) {
++	if (cpu_has_dc_aliases &&
++	    page_mapped(from) && !Page_dcache_dirty(from)) {
+ 		vfrom = kmap_coherent(from, vaddr);
+ 		copy_page(vto, vfrom);
+ 		kunmap_coherent();
+@@ -234,7 +235,8 @@ void copy_to_user_page(struct vm_area_struct *vma,
+ 	struct page *page, unsigned long vaddr, void *dst, const void *src,
+ 	unsigned long len)
+ {
+-	if (cpu_has_dc_aliases && page_mapped(page)) {
++	if (cpu_has_dc_aliases &&
++	    page_mapped(page) && !Page_dcache_dirty(page)) {
+ 		void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+ 		memcpy(vto, src, len);
+ 		kunmap_coherent();
+@@ -253,7 +255,8 @@ void copy_from_user_page(struct vm_area_struct *vma,
+ 	struct page *page, unsigned long vaddr, void *dst, const void *src,
+ 	unsigned long len)
+ {
+-	if (cpu_has_dc_aliases && page_mapped(page)) {
++	if (cpu_has_dc_aliases &&
++	    page_mapped(page) && !Page_dcache_dirty(page)) {
+ 		void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+ 		memcpy(dst, vfrom, len);
+ 		kunmap_coherent();
+diff --git a/arch/mips/mm/pg-sb1.c b/arch/mips/mm/pg-sb1.c
+index a3e98c2..89925ec 100644
+--- a/arch/mips/mm/pg-sb1.c
++++ b/arch/mips/mm/pg-sb1.c
+@@ -216,7 +216,7 @@ void sb1_dma_init(void)
+ 	int i;
+ 
+ 	for (i = 0; i < DM_NUM_CHANNELS; i++) {
+-		const u64 base_val = CPHYSADDR(&page_descr[i]) |
++		const u64 base_val = CPHYSADDR((unsigned long)&page_descr[i]) |
+ 				     V_DM_DSCR_BASE_RINGSZ(1);
+ 		void *base_reg = IOADDR(A_DM_REGISTER(i, R_DM_DSCR_BASE));
+ 
+@@ -228,11 +228,11 @@ void sb1_dma_init(void)
+ 
+ void clear_page(void *page)
+ {
+-	u64 to_phys = CPHYSADDR(page);
++	u64 to_phys = CPHYSADDR((unsigned long)page);
+ 	unsigned int cpu = smp_processor_id();
+ 
+ 	/* if the page is not in KSEG0, use old way */
+-	if ((long)KSEGX(page) != (long)CKSEG0)
++	if ((long)KSEGX((unsigned long)page) != (long)CKSEG0)
+ 		return clear_page_cpu(page);
+ 
+ 	page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_ZERO_MEM |
+@@ -252,13 +252,13 @@ void clear_page(void *page)
+ 
+ void copy_page(void *to, void *from)
+ {
+-	u64 from_phys = CPHYSADDR(from);
+-	u64 to_phys = CPHYSADDR(to);
++	u64 from_phys = CPHYSADDR((unsigned long)from);
++	u64 to_phys = CPHYSADDR((unsigned long)to);
+ 	unsigned int cpu = smp_processor_id();
+ 
+ 	/* if any page is not in KSEG0, use old way */
+-	if ((long)KSEGX(to) != (long)CKSEG0
+-	    || (long)KSEGX(from) != (long)CKSEG0)
++	if ((long)KSEGX((unsigned long)to) != (long)CKSEG0
++	    || (long)KSEGX((unsigned long)from) != (long)CKSEG0)
+ 		return copy_page_cpu(to, from);
+ 
+ 	page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_L2C_DEST |
+diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
+index 6e6981f..f9471d7 100644
+--- a/arch/mips/pci/pci.c
++++ b/arch/mips/pci/pci.c
+@@ -177,8 +177,15 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask)
+ 			continue;
+ 
+ 		r = &dev->resource[idx];
++		if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
++			continue;
++		if ((idx == PCI_ROM_RESOURCE) &&
++				(!(r->flags & IORESOURCE_ROM_ENABLE)))
++			continue;
+ 		if (!r->start && r->end) {
+-			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev));
++			printk(KERN_ERR "PCI: Device %s not available "
++			       "because of resource collisions\n",
++			       pci_name(dev));
+ 			return -EINVAL;
+ 		}
+ 		if (r->flags & IORESOURCE_IO)
+@@ -186,10 +193,9 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask)
+ 		if (r->flags & IORESOURCE_MEM)
+ 			cmd |= PCI_COMMAND_MEMORY;
+ 	}
+-	if (dev->resource[PCI_ROM_RESOURCE].start)
+-		cmd |= PCI_COMMAND_MEMORY;
+ 	if (cmd != old_cmd) {
+-		printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
++		printk("PCI: Enabling device %s (%04x -> %04x)\n",
++		       pci_name(dev), old_cmd, cmd);
+ 		pci_write_config_word(dev, PCI_COMMAND, cmd);
+ 	}
+ 	return 0;
+diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c
+index 183c460..bd9eeb4 100644
+--- a/arch/mips/sibyte/bcm1480/smp.c
++++ b/arch/mips/sibyte/bcm1480/smp.c
+@@ -110,7 +110,6 @@ static void __cpuinit bcm1480_smp_finish(void)
+ 
+ 	sb1480_clockevent_init();
+ 	local_irq_enable();
+-	bcm1480_smp_finish();
+ }
+ 
+ /*
+diff --git a/arch/mn10300/configs/asb2303_defconfig b/arch/mn10300/configs/asb2303_defconfig
+index ca9876a..3aa8906 100644
+--- a/arch/mn10300/configs/asb2303_defconfig
++++ b/arch/mn10300/configs/asb2303_defconfig
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.24-rc2
+-# Fri Nov 16 13:36:38 2007
++# Linux kernel version: 2.6.25-rc2
++# Tue Feb 19 18:52:24 2008
+ #
+ CONFIG_MN10300=y
+ CONFIG_AM33=y
+@@ -21,6 +21,7 @@ CONFIG_ARCH_HAS_ILOG2_U32=y
+ # CONFIG_ARCH_SUPPORTS_AOUT is not set
+ CONFIG_GENERIC_HARDIRQS=y
+ # CONFIG_HOTPLUG_CPU is not set
++CONFIG_HZ=1000
+ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+ 
+ #
+@@ -38,15 +39,16 @@ CONFIG_SYSVIPC_SYSCTL=y
+ CONFIG_BSD_PROCESS_ACCT=y
+ # CONFIG_BSD_PROCESS_ACCT_V3 is not set
+ # CONFIG_TASKSTATS is not set
+-# CONFIG_USER_NS is not set
+-# CONFIG_PID_NS is not set
+ # CONFIG_AUDIT is not set
+ # CONFIG_IKCONFIG is not set
+ CONFIG_LOG_BUF_SHIFT=14
+ # CONFIG_CGROUPS is not set
+-# CONFIG_FAIR_GROUP_SCHED is not set
++# CONFIG_GROUP_SCHED is not set
++# CONFIG_USER_SCHED is not set
++# CONFIG_CGROUP_SCHED is not set
+ # CONFIG_SYSFS_DEPRECATED is not set
+ # CONFIG_RELAY is not set
++# CONFIG_NAMESPACES is not set
+ # CONFIG_BLK_DEV_INITRD is not set
+ # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+ CONFIG_SYSCTL=y
+@@ -57,22 +59,33 @@ CONFIG_SYSCTL_SYSCALL=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 is not set
+ CONFIG_SLAB=y
+ # CONFIG_SLUB is not set
+ # CONFIG_SLOB is not set
++CONFIG_PROFILING=y
++# CONFIG_MARKERS is not set
++CONFIG_OPROFILE=y
++# CONFIG_HAVE_OPROFILE is not set
++# CONFIG_HAVE_KPROBES is not set
++# CONFIG_PROC_PAGE_MONITOR is not set
++CONFIG_SLABINFO=y
+ CONFIG_RT_MUTEXES=y
+ # CONFIG_TINY_SHMEM is not set
+ CONFIG_BASE_SMALL=0
+ # CONFIG_MODULES is not set
+ # CONFIG_BLOCK is not set
++CONFIG_CLASSIC_RCU=y
++# CONFIG_PREEMPT_RCU is not set
+ 
+ #
+ # Matsushita MN10300 system setup
+@@ -206,6 +219,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
+ #
+ # 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
+@@ -311,6 +325,8 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+ # CONFIG_PARPORT is not set
+ CONFIG_MISC_DEVICES=y
+ # CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_HAVE_IDE is not set
+ 
+ #
+ # SCSI device support
+@@ -345,7 +361,6 @@ CONFIG_SMC91X=y
+ # CONFIG_WAN is not set
+ # CONFIG_PPP is not set
+ # CONFIG_SLIP is not set
+-# CONFIG_SHAPER is not set
+ # CONFIG_NETCONSOLE is not set
+ # CONFIG_NETPOLL is not set
+ # CONFIG_NET_POLL_CONTROLLER is not set
+@@ -405,6 +420,7 @@ CONFIG_RTC=y
+ # CONFIG_W1 is not set
+ # CONFIG_POWER_SUPPLY is not set
+ # CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
+ # CONFIG_WATCHDOG is not set
+ 
+ #
+@@ -444,6 +460,7 @@ CONFIG_SSB_POSSIBLE=y
+ # CONFIG_SOUND is not set
+ # CONFIG_USB_SUPPORT is not set
+ # CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
+ # CONFIG_NEW_LEDS is not set
+ # CONFIG_RTC_CLASS is not set
+ 
+@@ -455,10 +472,10 @@ CONFIG_SSB_POSSIBLE=y
+ #
+ # File systems
+ #
++CONFIG_DNOTIFY=y
+ CONFIG_INOTIFY=y
+ CONFIG_INOTIFY_USER=y
+ # CONFIG_QUOTA is not set
+-CONFIG_DNOTIFY=y
+ # CONFIG_AUTOFS_FS is not set
+ # CONFIG_AUTOFS4_FS is not set
+ # CONFIG_FUSE_FS is not set
+@@ -554,5 +571,3 @@ CONFIG_HAS_DMA=y
+ #
+ # Profiling support
+ #
+-CONFIG_PROFILING=y
+-CONFIG_OPROFILE=y
+diff --git a/arch/mn10300/kernel/gdb-io-ttysm.c b/arch/mn10300/kernel/gdb-io-ttysm.c
+index c545159..e94c25e 100644
+--- a/arch/mn10300/kernel/gdb-io-ttysm.c
++++ b/arch/mn10300/kernel/gdb-io-ttysm.c
+@@ -196,6 +196,7 @@ int gdbstub_io_rx_char(unsigned char *_ch, int nonblock)
+ try_again:
+ 	/* pull chars out of the buffer */
+ 	ix = gdbstub_rx_outp;
++	barrier();
+ 	if (ix == gdbstub_rx_inp) {
+ 		if (nonblock)
+ 			return -EAGAIN;
+@@ -207,6 +208,7 @@ try_again:
+ 
+ 	ch = gdbstub_rx_buffer[ix++];
+ 	st = gdbstub_rx_buffer[ix++];
++	barrier();
+ 	gdbstub_rx_outp = ix & (PAGE_SIZE - 1);
+ 
+ 	st &= SC01STR_RXF | SC01STR_RBF | SC01STR_FEF | SC01STR_PEF |
+diff --git a/arch/mn10300/kernel/time.c b/arch/mn10300/kernel/time.c
+index ff492e3..babb7c2 100644
+--- a/arch/mn10300/kernel/time.c
++++ b/arch/mn10300/kernel/time.c
+@@ -84,11 +84,13 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
+ 		/* advance the kernel's time tracking system */
+ 		profile_tick(CPU_PROFILING);
+ 		do_timer(1);
+-		update_process_times(user_mode(get_irq_regs()));
+ 		check_rtc_time();
+ 	}
+ 
+ 	write_sequnlock(&xtime_lock);
++
++	update_process_times(user_mode(get_irq_regs()));
++
+ 	return IRQ_HANDLED;
+ }
+ 
+diff --git a/arch/mn10300/kernel/traps.c b/arch/mn10300/kernel/traps.c
+index 8b9dc6d..fcb9a03 100644
+--- a/arch/mn10300/kernel/traps.c
++++ b/arch/mn10300/kernel/traps.c
+@@ -391,7 +391,7 @@ static asmlinkage void unsupported_syscall(struct pt_regs *regs,
+ 	if (code == EXCEP_SYSCALL15 && !user_mode(regs)) {
+ 		if (report_bug(regs->pc, regs) == BUG_TRAP_TYPE_BUG) {
+ #ifdef CONFIG_GDBSTUB
+-			__gdbstub_bug_trap();
++			gdbstub_intercept(regs, code);
+ #endif
+ 		}
+ 	}
+diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
+index 6845482..1c6ce35 100644
+--- a/arch/powerpc/Makefile
++++ b/arch/powerpc/Makefile
+@@ -176,7 +176,7 @@ define archhelp
+   @echo '  *_defconfig     - Select default config from arch/$(ARCH)/configs'
+ endef
+ 
+-install: vdso_install
++install:
+ 	$(Q)$(MAKE) $(build)=$(boot) install
+ 
+ vdso_install:
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index 92a4f7b..b21444b 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -100,7 +100,8 @@ config NR_CPUS
+ 	int "Maximum number of CPUs (2-64)"
+ 	range 2 64
+ 	depends on SMP
+-	default "32"
++	default "32" if !64BIT
++	default "64" if 64BIT
+ 	help
+ 	  This allows you to specify the maximum number of CPUs which this
+ 	  kernel will support.  The maximum supported value is 64 and the
+diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
+index a6a4729..1c59ec1 100644
+--- a/arch/s390/kernel/process.c
++++ b/arch/s390/kernel/process.c
+@@ -114,24 +114,27 @@ extern void s390_handle_mcck(void);
+ static void default_idle(void)
+ {
+ 	int cpu, rc;
++	int nr_calls = 0;
++	void *hcpu;
+ #ifdef CONFIG_SMP
+ 	struct s390_idle_data *idle;
+ #endif
+ 
+ 	/* CPU is going idle. */
+ 	cpu = smp_processor_id();
+-
++	hcpu = (void *)(long)cpu;
+ 	local_irq_disable();
+ 	if (need_resched()) {
+ 		local_irq_enable();
+ 		return;
+ 	}
+ 
+-	rc = atomic_notifier_call_chain(&idle_chain,
+-					S390_CPU_IDLE, (void *)(long) cpu);
+-	if (rc != NOTIFY_OK && rc != NOTIFY_DONE)
+-		BUG();
+-	if (rc != NOTIFY_OK) {
++	rc = __atomic_notifier_call_chain(&idle_chain, S390_CPU_IDLE, hcpu, -1,
++					  &nr_calls);
++	if (rc == NOTIFY_BAD) {
++		nr_calls--;
++		__atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE,
++					     hcpu, nr_calls, NULL);
+ 		local_irq_enable();
+ 		return;
+ 	}
+diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
+index 8506065..818bd09 100644
+--- a/arch/s390/kernel/smp.c
++++ b/arch/s390/kernel/smp.c
+@@ -626,13 +626,17 @@ static int __cpuinit smp_alloc_lowcore(int cpu)
+ 	if (!lowcore)
+ 		return -ENOMEM;
+ 	async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER);
+-	if (!async_stack)
+-		goto out_async_stack;
+ 	panic_stack = __get_free_page(GFP_KERNEL);
+-	if (!panic_stack)
+-		goto out_panic_stack;
+-
+-	*lowcore = S390_lowcore;
++	if (!panic_stack || !async_stack)
++		goto out;
++	/*
++	 * Only need to copy the first 512 bytes from address 0. But since
++	 * the compiler emits a warning if src == NULL for memcpy use copy_page
++	 * instead. Copies more than needed but this code is not performance
++	 * critical.
++	 */
++	copy_page(lowcore, &S390_lowcore);
++	memset((void *)lowcore + 512, 0, sizeof(*lowcore) - 512);
+ 	lowcore->async_stack = async_stack + ASYNC_SIZE;
+ 	lowcore->panic_stack = panic_stack + PAGE_SIZE;
+ 
+@@ -653,9 +657,8 @@ static int __cpuinit smp_alloc_lowcore(int cpu)
+ out_save_area:
+ 	free_page(panic_stack);
+ #endif
+-out_panic_stack:
++out:
+ 	free_pages(async_stack, ASYNC_ORDER);
+-out_async_stack:
+ 	free_pages((unsigned long) lowcore, lc_order);
+ 	return -ENOMEM;
+ }
+@@ -719,8 +722,8 @@ int __cpuinit __cpu_up(unsigned int cpu)
+ 	cpu_lowcore->percpu_offset = __per_cpu_offset[cpu];
+ 	cpu_lowcore->current_task = (unsigned long) idle;
+ 	cpu_lowcore->cpu_data.cpu_nr = cpu;
+-	cpu_lowcore->softirq_pending = 0;
+-	cpu_lowcore->ext_call_fast = 0;
++	cpu_lowcore->kernel_asce = S390_lowcore.kernel_asce;
++	cpu_lowcore->ipl_device = S390_lowcore.ipl_device;
+ 	eieio();
+ 
+ 	while (signal_processor(cpu, sigp_restart) == sigp_busy)
+@@ -797,23 +800,43 @@ void cpu_die(void)
+ 
+ void __init smp_prepare_cpus(unsigned int max_cpus)
+ {
++#ifndef CONFIG_64BIT
++	unsigned long save_area = 0;
++#endif
++	unsigned long async_stack, panic_stack;
++	struct _lowcore *lowcore;
+ 	unsigned int cpu;
++	int lc_order;
+ 
+ 	smp_detect_cpus();
+ 
+ 	/* request the 0x1201 emergency signal external interrupt */
+ 	if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0)
+ 		panic("Couldn't request external interrupt 0x1201");
+-	memset(lowcore_ptr, 0, sizeof(lowcore_ptr));
+ 	print_cpu_info(&S390_lowcore.cpu_data);
+-	smp_alloc_lowcore(smp_processor_id());
+ 
++	/* Reallocate current lowcore, but keep its contents. */
++	lc_order = sizeof(long) == 8 ? 1 : 0;
++	lowcore = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, lc_order);
++	panic_stack = __get_free_page(GFP_KERNEL);
++	async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER);
+ #ifndef CONFIG_64BIT
+ 	if (MACHINE_HAS_IEEE)
+-		ctl_set_bit(14, 29); /* enable extended save area */
++		save_area = get_zeroed_page(GFP_KERNEL);
+ #endif
+-	set_prefix((u32)(unsigned long) lowcore_ptr[smp_processor_id()]);
+-
++	local_irq_disable();
++	local_mcck_disable();
++	lowcore_ptr[smp_processor_id()] = lowcore;
++	*lowcore = S390_lowcore;
++	lowcore->panic_stack = panic_stack + PAGE_SIZE;
++	lowcore->async_stack = async_stack + ASYNC_SIZE;
++#ifndef CONFIG_64BIT
++	if (MACHINE_HAS_IEEE)
++		lowcore->extended_save_area_addr = (u32) save_area;
++#endif
++	set_prefix((u32)(unsigned long) lowcore);
++	local_mcck_enable();
++	local_irq_enable();
+ 	for_each_possible_cpu(cpu)
+ 		if (cpu != smp_processor_id())
+ 			smp_create_idle(cpu);
+diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
+index 3bbac12..76a5dd1 100644
+--- a/arch/s390/kernel/time.c
++++ b/arch/s390/kernel/time.c
+@@ -744,7 +744,6 @@ static void etr_adjust_time(unsigned long long clock, unsigned long long delay)
+ 	}
+ }
+ 
+-#ifdef CONFIG_SMP
+ static void etr_sync_cpu_start(void *dummy)
+ {
+ 	int *in_sync = dummy;
+@@ -777,7 +776,6 @@ static void etr_sync_cpu_start(void *dummy)
+ static void etr_sync_cpu_end(void *dummy)
+ {
+ }
+-#endif /* CONFIG_SMP */
+ 
+ /*
+  * Sync the TOD clock using the port refered to by aibp. This port
+diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c
+index 28c4500..d2ffbad 100644
+--- a/arch/s390/lib/uaccess_std.c
++++ b/arch/s390/lib/uaccess_std.c
+@@ -293,10 +293,10 @@ int futex_atomic_cmpxchg_std(int __user *uaddr, int oldval, int newval)
+ 
+ 	asm volatile(
+ 		"   sacf 256\n"
+-		"   cs   %1,%4,0(%5)\n"
+-		"0: lr   %0,%1\n"
+-		"1: sacf 0\n"
+-		EX_TABLE(0b,1b)
++		"0: cs   %1,%4,0(%5)\n"
++		"1: lr   %0,%1\n"
++		"2: sacf 0\n"
++		EX_TABLE(0b,2b) EX_TABLE(1b,2b)
+ 		: "=d" (ret), "+d" (oldval), "=m" (*uaddr)
+ 		: "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr)
+ 		: "cc", "memory" );
+diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
+index 19186ce..0bd69d0 100644
+--- a/arch/sparc/kernel/process.c
++++ b/arch/sparc/kernel/process.c
+@@ -141,16 +141,12 @@ void cpu_idle(void)
+ 
+ extern char reboot_command [];
+ 
+-extern void (*prom_palette)(int);
+-
+ /* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */
+ void machine_halt(void)
+ {
+ 	local_irq_enable();
+ 	mdelay(8);
+ 	local_irq_disable();
+-	if (prom_palette)
+-		prom_palette (1);
+ 	prom_halt();
+ 	panic("Halt failed!");
+ }
+@@ -165,8 +161,6 @@ void machine_restart(char * cmd)
+ 
+ 	p = strchr (reboot_command, '\n');
+ 	if (p) *p = 0;
+-	if (prom_palette)
+-		prom_palette (1);
+ 	if (cmd)
+ 		prom_reboot(cmd);
+ 	if (*reboot_command)
+diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
+index 3cf78f1..3c13137 100644
+--- a/arch/sparc/kernel/setup.c
++++ b/arch/sparc/kernel/setup.c
+@@ -65,7 +65,6 @@ struct screen_info screen_info = {
+  */
+ 
+ extern unsigned long trapbase;
+-void (*prom_palette)(int);
+ 
+ /* Pretty sick eh? */
+ void prom_sync_me(void)
+@@ -80,8 +79,6 @@ void prom_sync_me(void)
+ 			     "nop\n\t"
+ 			     "nop\n\t" : : "r" (&trapbase));
+ 
+-	if (prom_palette)
+-		prom_palette(1);
+ 	prom_printf("PROM SYNC COMMAND...\n");
+ 	show_free_areas();
+ 	if(current->pid != 0) {
+@@ -191,7 +188,6 @@ extern int prom_probe_memory(void);
+ extern void sun4c_probe_vac(void);
+ extern char cputypval;
+ extern unsigned long start, end;
+-extern void panic_setup(char *, int *);
+ 
+ extern unsigned short root_flags;
+ extern unsigned short root_dev;
+diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
+index c0442e8..2375fe9 100644
+--- a/arch/sparc/mm/sun4c.c
++++ b/arch/sparc/mm/sun4c.c
+@@ -1941,9 +1941,7 @@ static pte_t *sun4c_pte_alloc_one_kernel(struct mm_struct *mm, unsigned long add
+ 	if ((pte = sun4c_pte_alloc_one_fast(mm, address)) != NULL)
+ 		return pte;
+ 
+-	pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
+-	if (pte)
+-		memset(pte, 0, PAGE_SIZE);
++	pte = (pte_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
+ 	return pte;
+ }
+ 
+diff --git a/arch/sparc/prom/misc.c b/arch/sparc/prom/misc.c
+index 37cff5f..d9fb3af 100644
+--- a/arch/sparc/prom/misc.c
++++ b/arch/sparc/prom/misc.c
+@@ -45,9 +45,6 @@ prom_feval(char *fstring)
+ 	spin_unlock_irqrestore(&prom_lock, flags);
+ }
+ 
+-/* We want to do this more nicely some day. */
+-extern void (*prom_palette)(int);
+-
+ /* Drop into the prom, with the chance to continue with the 'go'
+  * prom command.
+  */
+@@ -58,8 +55,6 @@ prom_cmdline(void)
+ 	extern void install_linux_ticker(void);
+ 	unsigned long flags;
+ 
+-	if (prom_palette)
+-		prom_palette (1);
+ 	spin_lock_irqsave(&prom_lock, flags);
+ 	install_obp_ticker();
+ 	(*(romvec->pv_abort))();
+@@ -69,8 +64,6 @@ prom_cmdline(void)
+ #ifdef CONFIG_SUN_AUXIO
+ 	set_auxio(AUXIO_LED, 0);
+ #endif
+-	if (prom_palette)
+-		prom_palette (0);
+ }
+ 
+ /* Drop into the prom, but completely terminate the program.
+diff --git a/arch/sparc64/Kconfig.debug b/arch/sparc64/Kconfig.debug
+index a5faa36..6a4d28a 100644
+--- a/arch/sparc64/Kconfig.debug
++++ b/arch/sparc64/Kconfig.debug
+@@ -23,10 +23,6 @@ config STACK_DEBUG
+ 	depends on DEBUG_KERNEL
+ 	bool "Stack Overflow Detection Support"
+ 
+-config DEBUG_BOOTMEM
+-	depends on DEBUG_KERNEL
+-	bool "Debug BOOTMEM initialization"
+-
+ config DEBUG_PAGEALLOC
+ 	bool "Debug page memory allocations"
+ 	depends on DEBUG_KERNEL && !HIBERNATION
+diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile
+index 01159cb..f0c22f8 100644
+--- a/arch/sparc64/Makefile
++++ b/arch/sparc64/Makefile
+@@ -12,39 +12,13 @@ CHECKFLAGS	+= -D__sparc__ -D__sparc_v9__ -m64
+ 
+ CPPFLAGS_vmlinux.lds += -Usparc
+ 
+-CC		:= $(shell if $(CC) -m64 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo $(CC); else echo sparc64-linux-gcc; fi )
+-
+-NEW_GCC := $(call cc-option-yn, -m64 -mcmodel=medlow)
+-NEW_GAS := $(shell if $(LD) -V 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi)
+-UNDECLARED_REGS := $(shell if $(CC) -c -x assembler /dev/null -Wa,--help | grep undeclared-regs > /dev/null; then echo y; else echo n; fi; )
+-
+-ifneq ($(NEW_GAS),y)
+-AS		= sparc64-linux-as
+-LD		= sparc64-linux-ld
+-NM		= sparc64-linux-nm
+-AR		= sparc64-linux-ar
+-RANLIB		= sparc64-linux-ranlib
+-else
+-AS		:= $(AS) -64
+ LDFLAGS		:= -m elf64_sparc
+-endif
+ 
+-ifneq ($(UNDECLARED_REGS),y)
+-CC_UNDECL	=
+-else
+-CC_UNDECL	= -Wa,--undeclared-regs
+-AS		:= $(AS) --undeclared-regs
+-endif
+-
+-ifneq ($(NEW_GCC),y)
+-  KBUILD_CFLAGS += -pipe -mno-fpu -mtune=ultrasparc -mmedlow \
+-	    -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare
+-else
+-  KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow \
+-	    -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare \
+-	    $(CC_UNDECL)
+-  KBUILD_AFLAGS += -m64 -mcpu=ultrasparc $(CC_UNDECL)
+-endif
++KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow \
++	-ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare \
++	-Wa,--undeclared-regs
++KBUILD_CFLAGS += $(call cc-option,-mtune=ultrasparc3)
++KBUILD_AFLAGS += -m64 -mcpu=ultrasparc -Wa,--undeclared-regs
+ 
+ ifeq ($(CONFIG_MCOUNT),y)
+   KBUILD_CFLAGS += -pg
+diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
+index 833d74b..250958d 100644
+--- a/arch/sparc64/defconfig
++++ b/arch/sparc64/defconfig
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.24
+-# Tue Feb  5 17:28:19 2008
++# Linux kernel version: 2.6.25-rc1
++# Sun Feb 17 22:44:12 2008
+ #
+ CONFIG_SPARC=y
+ CONFIG_SPARC64=y
+@@ -10,6 +10,7 @@ CONFIG_GENERIC_CMOS_UPDATE=y
+ CONFIG_GENERIC_CLOCKEVENTS=y
+ CONFIG_64BIT=y
+ CONFIG_MMU=y
++CONFIG_IOMMU_HELPER=y
+ CONFIG_QUICKLIST=y
+ CONFIG_STACKTRACE_SUPPORT=y
+ CONFIG_LOCKDEP_SUPPORT=y
+@@ -21,6 +22,7 @@ CONFIG_HAVE_SETUP_PER_CPU_AREA=y
+ CONFIG_ARCH_NO_VIRT_TO_BUS=y
+ CONFIG_OF=y
+ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_ARCH_SUPPORTS_AOUT=y
+ CONFIG_SPARC64_PAGE_SIZE_8KB=y
+ # CONFIG_SPARC64_PAGE_SIZE_64KB is not set
+ # CONFIG_SPARC64_PAGE_SIZE_512KB is not set
+@@ -49,8 +51,6 @@ CONFIG_SYSVIPC_SYSCTL=y
+ CONFIG_POSIX_MQUEUE=y
+ # CONFIG_BSD_PROCESS_ACCT is not set
+ # CONFIG_TASKSTATS is not set
+-# CONFIG_USER_NS is not set
+-# CONFIG_PID_NS is not set
+ # CONFIG_AUDIT is not set
+ # CONFIG_IKCONFIG is not set
+ CONFIG_LOG_BUF_SHIFT=18
+@@ -60,6 +60,11 @@ CONFIG_FAIR_USER_SCHED=y
+ # CONFIG_FAIR_CGROUP_SCHED is not set
+ CONFIG_SYSFS_DEPRECATED=y
+ CONFIG_RELAY=y
++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
+@@ -74,6 +79,7 @@ CONFIG_HOTPLUG=y
+ CONFIG_PRINTK=y
+ CONFIG_BUG=y
+ CONFIG_ELF_CORE=y
++# CONFIG_COMPAT_BRK is not set
+ CONFIG_BASE_FULL=y
+ CONFIG_FUTEX=y
+ CONFIG_ANON_INODES=y
+@@ -176,13 +182,13 @@ CONFIG_PCI_MSI=y
+ CONFIG_SUN_OPENPROMFS=m
+ CONFIG_SPARC32_COMPAT=y
+ CONFIG_COMPAT=y
+-CONFIG_BINFMT_ELF32=y
+ # CONFIG_BINFMT_AOUT32 is not set
+ 
+ #
+ # Executable file formats
+ #
+ CONFIG_BINFMT_ELF=y
++CONFIG_COMPAT_BINFMT_ELF=y
+ CONFIG_BINFMT_MISC=m
+ CONFIG_SOLARIS_EMUL=y
+ CONFIG_SCHED_SMT=y
+@@ -354,6 +360,8 @@ CONFIG_MISC_DEVICES=y
+ # CONFIG_EEPROM_93CX6 is not set
+ # CONFIG_SGI_IOC4 is not set
+ # CONFIG_TIFM_CORE is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++CONFIG_HAVE_IDE=y
+ CONFIG_IDE=y
+ CONFIG_BLK_DEV_IDE=y
+ 
+@@ -376,6 +384,7 @@ CONFIG_IDE_PROC_FS=y
+ #
+ CONFIG_IDE_GENERIC=y
+ # CONFIG_BLK_DEV_PLATFORM is not set
++CONFIG_BLK_DEV_IDEDMA_SFF=y
+ 
+ #
+ # PCI IDE chipsets support
+@@ -775,7 +784,6 @@ CONFIG_I2C_ALGOBIT=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_TPS65010 is not set
+ # CONFIG_SENSORS_MAX6875 is not set
+@@ -831,6 +839,7 @@ CONFIG_HWMON=y
+ # 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_VIA686A is not set
+ # CONFIG_SENSORS_VT1211 is not set
+@@ -840,9 +849,11 @@ CONFIG_HWMON=y
+ # 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_THERMAL is not set
+ # CONFIG_WATCHDOG is not set
+ 
+ #
+@@ -1201,6 +1212,7 @@ CONFIG_USB_STORAGE=m
+ # CONFIG_USB_TEST is not set
+ # CONFIG_USB_GADGET is not set
+ # CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
+ # CONFIG_NEW_LEDS is not set
+ # CONFIG_INFINIBAND is not set
+ # CONFIG_RTC_CLASS is not set
+@@ -1242,12 +1254,10 @@ CONFIG_FS_POSIX_ACL=y
+ # CONFIG_XFS_FS is not set
+ # CONFIG_GFS2_FS is not set
+ # CONFIG_OCFS2_FS is not set
+-# CONFIG_MINIX_FS is not set
+-# CONFIG_ROMFS_FS is not set
++CONFIG_DNOTIFY=y
+ CONFIG_INOTIFY=y
+ CONFIG_INOTIFY_USER=y
+ # CONFIG_QUOTA is not set
+-CONFIG_DNOTIFY=y
+ # CONFIG_AUTOFS_FS is not set
+ # CONFIG_AUTOFS4_FS is not set
+ # CONFIG_FUSE_FS is not set
+@@ -1291,8 +1301,10 @@ CONFIG_HUGETLB_PAGE=y
+ # CONFIG_EFS_FS is not set
+ # CONFIG_CRAMFS is not set
+ # CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_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
+@@ -1370,6 +1382,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
+ CONFIG_SCHEDSTATS=y
+ # CONFIG_TIMER_STATS 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
+@@ -1385,7 +1398,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
+ # CONFIG_DEBUG_VM is not set
+ # CONFIG_DEBUG_LIST is not set
+ # CONFIG_DEBUG_SG is not set
+-CONFIG_FORCED_INLINING=y
+ # CONFIG_BOOT_PRINTK_DELAY is not set
+ # CONFIG_RCU_TORTURE_TEST is not set
+ # CONFIG_KPROBES_SANITY_TEST is not set
+@@ -1396,7 +1408,6 @@ CONFIG_FORCED_INLINING=y
+ # CONFIG_DEBUG_STACK_USAGE is not set
+ # CONFIG_DEBUG_DCFLUSH is not set
+ # CONFIG_STACK_DEBUG is not set
+-# CONFIG_DEBUG_BOOTMEM is not set
+ # CONFIG_DEBUG_PAGEALLOC is not set
+ 
+ #
+diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
+index d3276eb..0e347ff 100644
+--- a/arch/sparc64/kernel/iommu.c
++++ b/arch/sparc64/kernel/iommu.c
+@@ -200,12 +200,11 @@ int iommu_table_init(struct iommu *iommu, int tsbsize,
+ 	/* Allocate and initialize the dummy page which we
+ 	 * set inactive IO PTEs to point to.
+ 	 */
+-	iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0);
++	iommu->dummy_page = get_zeroed_page(GFP_KERNEL);
+ 	if (!iommu->dummy_page) {
+ 		printk(KERN_ERR "IOMMU: Error, gfp(dummy_page) failed.\n");
+ 		goto out_free_map;
+ 	}
+-	memset((void *)iommu->dummy_page, 0, PAGE_SIZE);
+ 	iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page);
+ 
+ 	/* Now allocate and setup the IOMMU page table itself.  */
+diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
+index a61c38f..545356b 100644
+--- a/arch/sparc64/kernel/pci.c
++++ b/arch/sparc64/kernel/pci.c
+@@ -225,20 +225,6 @@ static int __init pci_controller_init(const char *model_name, int namelen, struc
+ 	return 0;
+ }
+ 
+-static int __init pci_is_controller(const char *model_name, int namelen, struct device_node *dp)
+-{
+-	int i;
+-
+-	for (i = 0; i < PCI_NUM_CONTROLLER_TYPES; i++) {
+-		if (!strncmp(model_name,
+-			     pci_controller_table[i].model_name,
+-			     namelen)) {
+-			return 1;
+-		}
+-	}
+-	return 0;
+-}
+-
+ static int __init pci_controller_scan(int (*handler)(const char *, int, struct device_node *))
+ {
+ 	struct device_node *dp;
+@@ -273,13 +259,6 @@ static int __init pci_controller_scan(int (*handler)(const char *, int, struct d
+ 	return count;
+ }
+ 
+-
+-/* Is there some PCI controller in the system?  */
+-int __init pcic_present(void)
+-{
+-	return pci_controller_scan(pci_is_controller);
+-}
+-
+ /* Find each controller in the system, attach and initialize
+  * software state structure for each and link into the
+  * pci_pbm_root.  Setup the controller enough such
+diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
+index 1b23791..6eceac5 100644
+--- a/arch/sparc64/kernel/process.c
++++ b/arch/sparc64/kernel/process.c
+@@ -113,16 +113,9 @@ void cpu_idle(void)
+ 
+ extern char reboot_command [];
+ 
+-extern void (*prom_palette)(int);
+-extern void (*prom_keyboard)(void);
+-
+ void machine_halt(void)
+ {
+ 	sstate_halt();
+-	if (prom_palette)
+-		prom_palette (1);
+-	if (prom_keyboard)
+-		prom_keyboard();
+ 	prom_halt();
+ 	panic("Halt failed!");
+ }
+@@ -130,10 +123,6 @@ void machine_halt(void)
+ void machine_alt_power_off(void)
+ {
+ 	sstate_poweroff();
+-	if (prom_palette)
+-		prom_palette(1);
+-	if (prom_keyboard)
+-		prom_keyboard();
+ 	prom_halt_power_off();
+ 	panic("Power-off failed!");
+ }
+@@ -145,10 +134,6 @@ void machine_restart(char * cmd)
+ 	sstate_reboot();
+ 	p = strchr (reboot_command, '\n');
+ 	if (p) *p = 0;
+-	if (prom_palette)
+-		prom_palette (1);
+-	if (prom_keyboard)
+-		prom_keyboard();
+ 	if (cmd)
+ 		prom_reboot(cmd);
+ 	if (*reboot_command)
+diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
+index a246e96..68964dd 100644
+--- a/arch/sparc64/kernel/prom.c
++++ b/arch/sparc64/kernel/prom.c
+@@ -1716,7 +1716,6 @@ static void __init of_console_init(void)
+ 
+ 	of_console_device = dp;
+ 
+-	prom_printf(msg, of_console_path);
+ 	printk(msg, of_console_path);
+ }
+ 
+diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
+index 5964d86..d036dbe 100644
+--- a/arch/sparc64/kernel/setup.c
++++ b/arch/sparc64/kernel/setup.c
+@@ -68,33 +68,22 @@ struct screen_info screen_info = {
+ 	16                      /* orig-video-points */
+ };
+ 
+-void (*prom_palette)(int);
+-void (*prom_keyboard)(void);
+-
+ static void
+ prom_console_write(struct console *con, const char *s, unsigned n)
+ {
+ 	prom_write(s, n);
+ }
+ 
+-unsigned int boot_flags = 0;
+-#define BOOTME_DEBUG  0x1
+-
+ /* Exported for mm/init.c:paging_init. */
+ unsigned long cmdline_memory_size = 0;
+ 
+-static struct console prom_debug_console = {
+-	.name =		"debug",
++static struct console prom_early_console = {
++	.name =		"earlyprom",
+ 	.write =	prom_console_write,
+-	.flags =	CON_PRINTBUFFER,
++	.flags =	CON_PRINTBUFFER | CON_BOOT,
+ 	.index =	-1,
+ };
+ 
+-/* XXX Implement this at some point... */
+-void kernel_enter_debugger(void)
+-{
+-}
+-
+ /* 
+  * Process kernel command line switches that are specific to the
+  * SPARC or that require special low-level processing.
+@@ -103,8 +92,6 @@ static void __init process_switch(char c)
+ {
+ 	switch (c) {
+ 	case 'd':
+-		boot_flags |= BOOTME_DEBUG;
+-		break;
+ 	case 's':
+ 		break;
+ 	case 'h':
+@@ -112,8 +99,7 @@ static void __init process_switch(char c)
+ 		prom_halt();
+ 		break;
+ 	case 'p':
+-		/* Use PROM debug console. */
+-		register_console(&prom_debug_console);
++		/* Just ignore, this behavior is now the default.  */
+ 		break;
+ 	case 'P':
+ 		/* Force UltraSPARC-III P-Cache on. */
+@@ -168,8 +154,6 @@ static void __init boot_flags_init(char *commands)
+ 	}
+ }
+ 
+-extern void panic_setup(char *, int *);
+-
+ extern unsigned short root_flags;
+ extern unsigned short root_dev;
+ extern unsigned short ram_flags;
+@@ -296,6 +280,9 @@ void __init setup_arch(char **cmdline_p)
+ 	*cmdline_p = prom_getbootargs();
+ 	strcpy(boot_command_line, *cmdline_p);
+ 
++	boot_flags_init(*cmdline_p);
++	register_console(&prom_early_console);
++
+ 	if (tlb_type == hypervisor)
+ 		printk("ARCH: SUN4V\n");
+ 	else
+@@ -307,8 +294,6 @@ void __init setup_arch(char **cmdline_p)
+ 	conswitchp = &prom_con;
+ #endif
+ 
+-	boot_flags_init(*cmdline_p);
+-
+ 	idprom_init();
+ 
+ 	if (!root_flags)
+diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
+index 68db089..51fa773 100644
+--- a/arch/sparc64/kernel/sparc64_ksyms.c
++++ b/arch/sparc64/kernel/sparc64_ksyms.c
+@@ -85,7 +85,6 @@ extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *);
+ extern long sparc32_open(const char __user * filename, int flags, int mode);
+ extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
+ 	unsigned long pfn, unsigned long size, pgprot_t prot);
+-extern void (*prom_palette)(int);
+ 
+ extern int __ashrdi3(int, int);
+ 
+@@ -355,5 +354,3 @@ EXPORT_SYMBOL(xor_niagara_2);
+ EXPORT_SYMBOL(xor_niagara_3);
+ EXPORT_SYMBOL(xor_niagara_4);
+ EXPORT_SYMBOL(xor_niagara_5);
+-
+-EXPORT_SYMBOL(prom_palette);
+diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c
+index dc7bf1b..1a511e9 100644
+--- a/arch/sparc64/kernel/unaligned.c
++++ b/arch/sparc64/kernel/unaligned.c
+@@ -7,6 +7,7 @@
+  */
+ 
+ 
++#include <linux/jiffies.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+ #include <linux/mm.h>
+@@ -283,7 +284,7 @@ static void log_unaligned(struct pt_regs *regs)
+ {
+ 	static unsigned long count, last_time;
+ 
+-	if (jiffies - last_time > 5 * HZ)
++	if (time_after(jiffies, last_time + 5 * HZ))
+ 		count = 0;
+ 	if (count < 5) {
+ 		last_time = jiffies;
+diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
+index e726c45..9e6bca2 100644
+--- a/arch/sparc64/mm/init.c
++++ b/arch/sparc64/mm/init.c
+@@ -618,9 +618,9 @@ static void __init inherit_prom_mappings(void)
+ 	read_obp_translations();
+ 
+ 	/* Now fixup OBP's idea about where we really are mapped. */
+-	prom_printf("Remapping the kernel... ");
++	printk("Remapping the kernel... ");
+ 	remap_kernel();
+-	prom_printf("done.\n");
++	printk("done.\n");
+ }
+ 
+ void prom_world(int enter)
+@@ -739,11 +739,6 @@ static unsigned long __init choose_bootmap_pfn(unsigned long start_pfn,
+ 	avoid_end = PAGE_ALIGN(initrd_end);
+ #endif
+ 
+-#ifdef CONFIG_DEBUG_BOOTMEM
+-	prom_printf("choose_bootmap_pfn: kern[%lx:%lx] avoid[%lx:%lx]\n",
+-		    kern_base, PAGE_ALIGN(kern_base + kern_size),
+-		    avoid_start, avoid_end);
+-#endif
+ 	for (i = 0; i < pavail_ents; i++) {
+ 		unsigned long start, end;
+ 
+@@ -777,10 +772,6 @@ static unsigned long __init choose_bootmap_pfn(unsigned long start_pfn,
+ 			}
+ 
+ 			/* OK, it doesn't overlap anything, use it.  */
+-#ifdef CONFIG_DEBUG_BOOTMEM
+-			prom_printf("choose_bootmap_pfn: Using %lx [%lx]\n",
+-				    start >> PAGE_SHIFT, start);
+-#endif
+ 			return start >> PAGE_SHIFT;
+ 		}
+ 	}
+@@ -920,10 +911,6 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail,
+ 	unsigned long bootmap_pfn, bytes_avail, size;
+ 	int i;
+ 
+-#ifdef CONFIG_DEBUG_BOOTMEM
+-	prom_printf("bootmem_init: Scan pavail, ");
+-#endif
+-
+ 	bytes_avail = 0UL;
+ 	for (i = 0; i < pavail_ents; i++) {
+ 		end_of_phys_memory = pavail[i].phys_addr +
+@@ -970,33 +957,20 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail,
+ 
+ 	bootmap_pfn = choose_bootmap_pfn(min_low_pfn, end_pfn);
+ 
+-#ifdef CONFIG_DEBUG_BOOTMEM
+-	prom_printf("init_bootmem(min[%lx], bootmap[%lx], max[%lx])\n",
+-		    min_low_pfn, bootmap_pfn, max_low_pfn);
+-#endif
+ 	bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn,
+ 					 min_low_pfn, end_pfn);
+ 
+ 	/* Now register the available physical memory with the
+ 	 * allocator.
+ 	 */
+-	for (i = 0; i < pavail_ents; i++) {
+-#ifdef CONFIG_DEBUG_BOOTMEM
+-		prom_printf("free_bootmem(pavail:%d): base[%lx] size[%lx]\n",
+-			    i, pavail[i].phys_addr, pavail[i].reg_size);
+-#endif
++	for (i = 0; i < pavail_ents; i++)
+ 		free_bootmem(pavail[i].phys_addr, pavail[i].reg_size);
+-	}
+ 
+ #ifdef CONFIG_BLK_DEV_INITRD
+ 	if (initrd_start) {
+ 		size = initrd_end - initrd_start;
+ 
+ 		/* Reserve the initrd image area. */
+-#ifdef CONFIG_DEBUG_BOOTMEM
+-		prom_printf("reserve_bootmem(initrd): base[%llx] size[%lx]\n",
+-			initrd_start, initrd_end);
+-#endif
+ 		reserve_bootmem(initrd_start, size, BOOTMEM_DEFAULT);
+ 
+ 		initrd_start += PAGE_OFFSET;
+@@ -1004,9 +978,6 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail,
+ 	}
+ #endif
+ 	/* Reserve the kernel text/data/bss. */
+-#ifdef CONFIG_DEBUG_BOOTMEM
+-	prom_printf("reserve_bootmem(kernel): base[%lx] size[%lx]\n", kern_base, kern_size);
+-#endif
+ 	reserve_bootmem(kern_base, kern_size, BOOTMEM_DEFAULT);
+ 	*pages_avail -= PAGE_ALIGN(kern_size) >> PAGE_SHIFT;
+ 
+@@ -1020,10 +991,6 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail,
+ 	 * in free_all_bootmem.
+ 	 */
+ 	size = bootmap_size;
+-#ifdef CONFIG_DEBUG_BOOTMEM
+-	prom_printf("reserve_bootmem(bootmap): base[%lx] size[%lx]\n",
+-		    (bootmap_pfn << PAGE_SHIFT), size);
+-#endif
+ 	reserve_bootmem((bootmap_pfn << PAGE_SHIFT), size, BOOTMEM_DEFAULT);
+ 
+ 	for (i = 0; i < pavail_ents; i++) {
+@@ -1031,10 +998,6 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail,
+ 
+ 		start_pfn = pavail[i].phys_addr >> PAGE_SHIFT;
+ 		end_pfn = (start_pfn + (pavail[i].reg_size >> PAGE_SHIFT));
+-#ifdef CONFIG_DEBUG_BOOTMEM
+-		prom_printf("memory_present(0, %lx, %lx)\n",
+-			    start_pfn, end_pfn);
+-#endif
+ 		memory_present(0, start_pfn, end_pfn);
+ 	}
+ 
+@@ -1451,7 +1414,7 @@ void __init paging_init(void)
+ 				    zholes_size);
+ 	}
+ 
+-	prom_printf("Booting Linux...\n");
++	printk("Booting Linux...\n");
+ 
+ 	central_probe();
+ 	cpu_probe();
+@@ -1549,10 +1512,6 @@ void __init mem_init(void)
+ 
+ 	high_memory = __va(last_valid_pfn << PAGE_SHIFT);
+ 
+-#ifdef CONFIG_DEBUG_BOOTMEM
+-	prom_printf("mem_init: Calling free_all_bootmem().\n");
+-#endif
+-
+ 	/* We subtract one to account for the mem_map_zero page
+ 	 * allocated below.
+ 	 */
+diff --git a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c
+index bbec752..47a877a 100644
+--- a/arch/sparc64/prom/misc.c
++++ b/arch/sparc64/prom/misc.c
+@@ -55,9 +55,6 @@ void prom_feval(const char *fstring)
+ 		  P1275_INOUT(1, 1), fstring);
+ }
+ 
+-/* We want to do this more nicely some day. */
+-extern void (*prom_palette)(int);
+-
+ #ifdef CONFIG_SMP
+ extern void smp_capture(void);
+ extern void smp_release(void);
+@@ -72,9 +69,6 @@ void prom_cmdline(void)
+ 
+ 	local_irq_save(flags);
+ 
+-	if (prom_palette)
+-		prom_palette(1);
+-
+ #ifdef CONFIG_SMP
+ 	smp_capture();
+ #endif
+@@ -85,9 +79,6 @@ void prom_cmdline(void)
+ 	smp_release();
+ #endif
+ 
+-	if (prom_palette)
+-		prom_palette(0);
+-
+ 	local_irq_restore(flags);
+ }
+ 
+diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
+index 864affc..702eb39 100644
+--- a/arch/x86/Kconfig.debug
++++ b/arch/x86/Kconfig.debug
+@@ -156,7 +156,7 @@ config IO_DELAY_TYPE_NONE
+ 
+ choice
+ 	prompt "IO delay type"
+-	default IO_DELAY_0XED
++	default IO_DELAY_0X80
+ 
+ config IO_DELAY_0X80
+ 	bool "port 0x80 based port-IO delay [recommended]"
+diff --git a/arch/x86/Makefile b/arch/x86/Makefile
+index 204af43..f1e739a 100644
+--- a/arch/x86/Makefile
++++ b/arch/x86/Makefile
+@@ -229,7 +229,7 @@ zdisk bzdisk: vmlinux
+ fdimage fdimage144 fdimage288 isoimage: vmlinux
+ 	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@
+ 
+-install: vdso_install
++install:
+ 	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
+ 
+ PHONY += vdso_install
+diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
+index 76ec0f8..4eb5ce8 100644
+--- a/arch/x86/kernel/Makefile
++++ b/arch/x86/kernel/Makefile
+@@ -6,7 +6,15 @@ extra-y                := head_$(BITS).o init_task.o vmlinux.lds
+ extra-$(CONFIG_X86_64) += head64.o
+ 
+ CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE)
+-CFLAGS_vsyscall_64.o := $(PROFILING) -g0
++
++#
++# vsyscalls (which work on the user stack) should have
++# no stack-protector checks:
++#
++nostackp := $(call cc-option, -fno-stack-protector)
++CFLAGS_vsyscall_64.o	:= $(PROFILING) -g0 $(nostackp)
++CFLAGS_hpet.o		:= $(nostackp)
++CFLAGS_tsc_64.o		:= $(nostackp)
+ 
+ obj-y			:= process_$(BITS).o signal_$(BITS).o entry_$(BITS).o
+ obj-y			+= traps_$(BITS).o irq_$(BITS).o
+diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
+index afd8446..a33d530 100644
+--- a/arch/x86/kernel/asm-offsets_32.c
++++ b/arch/x86/kernel/asm-offsets_32.c
+@@ -20,10 +20,8 @@
+ 
+ #include <xen/interface/xen.h>
+ 
+-#ifdef CONFIG_LGUEST_GUEST
+ #include <linux/lguest.h>
+ #include "../../../drivers/lguest/lg.h"
+-#endif
+ 
+ #define DEFINE(sym, val) \
+         asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+@@ -134,6 +132,10 @@ void foo(void)
+ 	BLANK();
+ 	OFFSET(LGUEST_DATA_irq_enabled, lguest_data, irq_enabled);
+ 	OFFSET(LGUEST_DATA_pgdir, lguest_data, pgdir);
++#endif
++
++#ifdef CONFIG_LGUEST
++	BLANK();
+ 	OFFSET(LGUEST_PAGES_host_gdt_desc, lguest_pages, state.host_gdt_desc);
+ 	OFFSET(LGUEST_PAGES_host_idt_desc, lguest_pages, state.host_idt_desc);
+ 	OFFSET(LGUEST_PAGES_host_cr3, lguest_pages, state.host_cr3);
+diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
+index 9b95edc..027e5c0 100644
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -25,14 +25,6 @@ static int __init no_halt(char *s)
+ 
+ __setup("no-hlt", no_halt);
+ 
+-static int __init mca_pentium(char *s)
+-{
+-	mca_pentium_flag = 1;
+-	return 1;
+-}
+-
+-__setup("mca-pentium", mca_pentium);
+-
+ static int __init no_387(char *s)
+ {
+ 	boot_cpu_data.hard_math = 0;
+diff --git a/arch/x86/kernel/efi.c b/arch/x86/kernel/efi.c
+index 0c0eeb1..759e02b 100644
+--- a/arch/x86/kernel/efi.c
++++ b/arch/x86/kernel/efi.c
+@@ -54,7 +54,7 @@ EXPORT_SYMBOL(efi);
+ 
+ struct efi_memory_map memmap;
+ 
+-struct efi efi_phys __initdata;
++static struct efi efi_phys __initdata;
+ static efi_system_table_t efi_systab __initdata;
+ 
+ static int __init setup_noefi(char *arg)
+diff --git a/arch/x86/kernel/efi_32.c b/arch/x86/kernel/efi_32.c
+index cb91f98..5d23d85 100644
+--- a/arch/x86/kernel/efi_32.c
++++ b/arch/x86/kernel/efi_32.c
+@@ -28,6 +28,7 @@
+ #include <asm/page.h>
+ #include <asm/pgtable.h>
+ #include <asm/tlbflush.h>
++#include <asm/efi.h>
+ 
+ /*
+  * To make EFI call EFI runtime service in physical addressing mode we need
+diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
+index 824e21b..4b87c32 100644
+--- a/arch/x86/kernel/entry_32.S
++++ b/arch/x86/kernel/entry_32.S
+@@ -409,7 +409,7 @@ restore_nocheck_notrace:
+ 	RESTORE_REGS
+ 	addl $4, %esp			# skip orig_eax/error_code
+ 	CFI_ADJUST_CFA_OFFSET -4
+-ENTRY(irq_return)
++irq_return:
+ 	INTERRUPT_RETURN
+ .section .fixup,"ax"
+ iret_exc:
+diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
+index 6be39a3..2ad9a1b 100644
+--- a/arch/x86/kernel/entry_64.S
++++ b/arch/x86/kernel/entry_64.S
+@@ -583,7 +583,7 @@ retint_restore_args:	/* return to kernel space */
+ restore_args:
+ 	RESTORE_ARGS 0,8,0
+ 
+-ENTRY(irq_return)
++irq_return:
+ 	INTERRUPT_RETURN
+ 
+ 	.section __ex_table, "a"
+diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
+index 24dbf56..ad24408 100644
+--- a/arch/x86/kernel/head64.c
++++ b/arch/x86/kernel/head64.c
+@@ -88,6 +88,9 @@ void __init x86_64_start_kernel(char * real_mode_data)
+ 	/* Make NULL pointers segfault */
+ 	zap_identity_mappings();
+ 
++	/* Cleanup the over mapped high alias */
++	cleanup_highmap();
++
+ 	for (i = 0; i < IDT_ENTRIES; i++) {
+ #ifdef CONFIG_EARLY_PRINTK
+ 		set_intr_gate(i, &early_idt_handlers[i]);
+diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
+index 74ef4a4..25eb985 100644
+--- a/arch/x86/kernel/head_32.S
++++ b/arch/x86/kernel/head_32.S
+@@ -612,7 +612,7 @@ ENTRY(swapper_pg_pmd)
+ ENTRY(swapper_pg_dir)
+ 	.fill 1024,4,0
+ #endif
+-ENTRY(swapper_pg_fixmap)
++swapper_pg_fixmap:
+ 	.fill 1024,4,0
+ ENTRY(empty_zero_page)
+ 	.fill 4096,1,0
+diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
+index 09b38d5..eb41504 100644
+--- a/arch/x86/kernel/head_64.S
++++ b/arch/x86/kernel/head_64.S
+@@ -107,8 +107,13 @@ startup_64:
+ 	movq	%rdx, 0(%rbx, %rax, 8)
+ ident_complete:
+ 
+-	/* Fixup the kernel text+data virtual addresses
++	/*
++	 * Fixup the kernel text+data virtual addresses. Note that
++	 * we might write invalid pmds, when the kernel is relocated
++	 * cleanup_highmap() fixes this up along with the mappings
++	 * beyond _end.
+ 	 */
++
+ 	leaq	level2_kernel_pgt(%rip), %rdi
+ 	leaq	4096(%rdi), %r8
+ 	/* See if it is a valid page table entry */
+@@ -250,7 +255,7 @@ ENTRY(secondary_startup_64)
+ 	lretq
+ 
+ 	/* SMP bootup changes these two */
+-	__CPUINITDATA
++	__REFDATA
+ 	.align	8
+ 	ENTRY(initial_code)
+ 	.quad	x86_64_start_kernel
+diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
+index 26719bd..763dfc4 100644
+--- a/arch/x86/kernel/i387.c
++++ b/arch/x86/kernel/i387.c
+@@ -39,7 +39,7 @@
+ #define HAVE_HWFP 1
+ #endif
+ 
+-unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu;
++static unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu;
+ 
+ void mxcsr_feature_mask_init(void)
+ {
+diff --git a/arch/x86/kernel/i8259_32.c b/arch/x86/kernel/i8259_32.c
+index 2d25b77..fe63196 100644
+--- a/arch/x86/kernel/i8259_32.c
++++ b/arch/x86/kernel/i8259_32.c
+@@ -26,8 +26,6 @@
+  * present in the majority of PC/AT boxes.
+  * plus some generic x86 specific things if generic specifics makes
+  * any sense at all.
+- * this file should become arch/i386/kernel/irq.c when the old irq.c
+- * moves to arch independent land
+  */
+ 
+ static int i8259A_auto_eoi;
+@@ -362,23 +360,12 @@ void __init init_ISA_irqs (void)
+ #endif
+ 	init_8259A(0);
+ 
+-	for (i = 0; i < NR_IRQS; i++) {
+-		irq_desc[i].status = IRQ_DISABLED;
+-		irq_desc[i].action = NULL;
+-		irq_desc[i].depth = 1;
+-
+-		if (i < 16) {
+-			/*
+-			 * 16 old-style INTA-cycle interrupts:
+-			 */
+-			set_irq_chip_and_handler_name(i, &i8259A_chip,
+-						      handle_level_irq, "XT");
+-		} else {
+-			/*
+-			 * 'high' PCI IRQs filled in on demand
+-			 */
+-			irq_desc[i].chip = &no_irq_chip;
+-		}
++	/*
++	 * 16 old-style INTA-cycle interrupts:
++	 */
++	for (i = 0; i < 16; i++) {
++		set_irq_chip_and_handler_name(i, &i8259A_chip,
++					      handle_level_irq, "XT");
+ 	}
+ }
+ 
+diff --git a/arch/x86/kernel/io_delay.c b/arch/x86/kernel/io_delay.c
+index bd49321..c706a30 100644
+--- a/arch/x86/kernel/io_delay.c
++++ b/arch/x86/kernel/io_delay.c
+@@ -13,7 +13,6 @@
+ #include <asm/io.h>
+ 
+ int io_delay_type __read_mostly = CONFIG_DEFAULT_IO_DELAY_TYPE;
+-EXPORT_SYMBOL_GPL(io_delay_type);
+ 
+ static int __initdata io_delay_override;
+ 
+diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
+index a99e764..34a5912 100644
+--- a/arch/x86/kernel/kprobes.c
++++ b/arch/x86/kernel/kprobes.c
+@@ -581,7 +581,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
+  * When a retprobed function returns, this code saves registers and
+  * calls trampoline_handler() runs, which calls the kretprobe's handler.
+  */
+-void __kprobes kretprobe_trampoline_holder(void)
++static void __used __kprobes kretprobe_trampoline_holder(void)
+ {
+ 	asm volatile (
+ 			".global kretprobe_trampoline\n"
+@@ -673,7 +673,7 @@ void __kprobes kretprobe_trampoline_holder(void)
+ /*
+  * Called from kretprobe_trampoline
+  */
+-void * __kprobes trampoline_handler(struct pt_regs *regs)
++static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
+ {
+ 	struct kretprobe_instance *ri = NULL;
+ 	struct hlist_head *head, empty_rp;
+diff --git a/arch/x86/kernel/nmi_32.c b/arch/x86/kernel/nmi_32.c
+index edd4136..6a0aa70 100644
+--- a/arch/x86/kernel/nmi_32.c
++++ b/arch/x86/kernel/nmi_32.c
+@@ -46,9 +46,6 @@ static unsigned int nmi_hz = HZ;
+ 
+ static DEFINE_PER_CPU(short, wd_enabled);
+ 
+-/* local prototypes */
+-static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu);
+-
+ static int endflag __initdata = 0;
+ 
+ #ifdef CONFIG_SMP
+@@ -391,15 +388,6 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
+ 	return rc;
+ }
+ 
+-int do_nmi_callback(struct pt_regs * regs, int cpu)
+-{
+-#ifdef CONFIG_SYSCTL
+-	if (unknown_nmi_panic)
+-		return unknown_nmi_panic_callback(regs, cpu);
+-#endif
+-	return 0;
+-}
+-
+ #ifdef CONFIG_SYSCTL
+ 
+ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)
+@@ -453,6 +441,15 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file,
+ 
+ #endif
+ 
++int do_nmi_callback(struct pt_regs *regs, int cpu)
++{
++#ifdef CONFIG_SYSCTL
++	if (unknown_nmi_panic)
++		return unknown_nmi_panic_callback(regs, cpu);
++#endif
++	return 0;
++}
++
+ void __trigger_all_cpu_backtrace(void)
+ {
+ 	int i;
+diff --git a/arch/x86/kernel/nmi_64.c b/arch/x86/kernel/nmi_64.c
+index fb99484..9a4fde7 100644
+--- a/arch/x86/kernel/nmi_64.c
++++ b/arch/x86/kernel/nmi_64.c
+@@ -46,9 +46,6 @@ static unsigned int nmi_hz = HZ;
+ 
+ static DEFINE_PER_CPU(short, wd_enabled);
+ 
+-/* local prototypes */
+-static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu);
+-
+ /* Run after command line and cpu_init init, but before all other checks */
+ void nmi_watchdog_default(void)
+ {
+@@ -394,15 +391,6 @@ asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code)
+ 	nmi_exit();
+ }
+ 
+-int do_nmi_callback(struct pt_regs * regs, int cpu)
+-{
+-#ifdef CONFIG_SYSCTL
+-	if (unknown_nmi_panic)
+-		return unknown_nmi_panic_callback(regs, cpu);
+-#endif
+-	return 0;
+-}
+-
+ void stop_nmi(void)
+ {
+ 	acpi_nmi_disable();
+@@ -464,6 +452,15 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file,
+ 
+ #endif
+ 
++int do_nmi_callback(struct pt_regs *regs, int cpu)
++{
++#ifdef CONFIG_SYSCTL
++	if (unknown_nmi_panic)
++		return unknown_nmi_panic_callback(regs, cpu);
++#endif
++	return 0;
++}
++
+ void __trigger_all_cpu_backtrace(void)
+ {
+ 	int i;
+diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c
+index 691ab4c..a1d7071 100644
+--- a/arch/x86/kernel/setup_32.c
++++ b/arch/x86/kernel/setup_32.c
+@@ -164,7 +164,6 @@ unsigned long mmu_cr4_features = X86_CR4_PAE;
+ unsigned int machine_id;
+ unsigned int machine_submodel_id;
+ unsigned int BIOS_revision;
+-unsigned int mca_pentium_flag;
+ 
+ /* Boot loader ID as an integer, for the benefit of proc_dointvec */
+ int bootloader_type;
+diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
+index c0d8208..6fd804f 100644
+--- a/arch/x86/kernel/setup_64.c
++++ b/arch/x86/kernel/setup_64.c
+@@ -518,7 +518,7 @@ static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c)
+ }
+ 
+ #ifdef CONFIG_NUMA
+-static int nearby_node(int apicid)
++static int __cpuinit nearby_node(int apicid)
+ {
+ 	int i, node;
+ 
+@@ -791,7 +791,7 @@ static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c)
+ 		return 1;
+ }
+ 
+-static void srat_detect_node(void)
++static void __cpuinit srat_detect_node(void)
+ {
+ #ifdef CONFIG_NUMA
+ 	unsigned node;
+@@ -1046,7 +1046,7 @@ __setup("noclflush", setup_noclflush);
+ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
+ {
+ 	if (c->x86_model_id[0])
+-		printk(KERN_INFO "%s", c->x86_model_id);
++		printk(KERN_CONT "%s", c->x86_model_id);
+ 
+ 	if (c->x86_mask || c->cpuid_level >= 0)
+ 		printk(KERN_CONT " stepping %02x\n", c->x86_mask);
+diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c
+index a40051b..0fcc95a 100644
+--- a/arch/x86/kernel/topology.c
++++ b/arch/x86/kernel/topology.c
+@@ -34,7 +34,7 @@
+ static DEFINE_PER_CPU(struct x86_cpu, cpu_devices);
+ 
+ #ifdef CONFIG_HOTPLUG_CPU
+-int arch_register_cpu(int num)
++int __ref arch_register_cpu(int num)
+ {
+ 	/*
+ 	 * CPU0 cannot be offlined due to several
+diff --git a/arch/x86/kernel/vmlinux_32.lds.S b/arch/x86/kernel/vmlinux_32.lds.S
+index f1148ac..2ffa965 100644
+--- a/arch/x86/kernel/vmlinux_32.lds.S
++++ b/arch/x86/kernel/vmlinux_32.lds.S
+@@ -38,7 +38,7 @@ SECTIONS
+ 
+   /* read-only */
+   .text : AT(ADDR(.text) - LOAD_OFFSET) {
+-	. = ALIGN(4096); /* not really needed, already page aligned */
++	. = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
+ 	*(.text.page_aligned)
+ 	TEXT_TEXT
+ 	SCHED_TEXT
+@@ -70,21 +70,21 @@ SECTIONS
+   RODATA
+ 
+   /* writeable */
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   .data : AT(ADDR(.data) - LOAD_OFFSET) {	/* Data */
+ 	DATA_DATA
+ 	CONSTRUCTORS
+ 	} :data
+ 
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
+   	__nosave_begin = .;
+ 	*(.data.nosave)
+-  	. = ALIGN(4096);
++  	. = ALIGN(PAGE_SIZE);
+   	__nosave_end = .;
+   }
+ 
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
+ 	*(.data.page_aligned)
+ 	*(.data.idt)
+@@ -108,7 +108,7 @@ SECTIONS
+   }
+ 
+   /* might get freed after init */
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
+   	__smp_locks = .;
+ 	*(.smp_locks)
+@@ -120,10 +120,10 @@ SECTIONS
+    * after boot. Always make sure that ALIGN() directive is present after
+    * the section which contains __smp_alt_end.
+    */
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+ 
+   /* will be freed after init */
+-  . = ALIGN(4096);		/* Init code and data */
++  . = ALIGN(PAGE_SIZE);		/* Init code and data */
+   .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
+   	__init_begin = .;
+ 	_sinittext = .;
+@@ -174,23 +174,23 @@ SECTIONS
+ 	EXIT_DATA
+   }
+ #if defined(CONFIG_BLK_DEV_INITRD)
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
+ 	__initramfs_start = .;
+ 	*(.init.ramfs)
+ 	__initramfs_end = .;
+   }
+ #endif
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   .data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
+ 	__per_cpu_start = .;
+ 	*(.data.percpu)
+ 	*(.data.percpu.shared_aligned)
+ 	__per_cpu_end = .;
+   }
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   /* freed after init ends here */
+-	
++
+   .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
+ 	__init_end = .;
+ 	__bss_start = .;		/* BSS */
+@@ -200,7 +200,7 @@ SECTIONS
+ 	__bss_stop = .;
+   	_end = . ;
+ 	/* This is where the kernel creates the early boot page tables */
+-	. = ALIGN(4096);
++	. = ALIGN(PAGE_SIZE);
+ 	pg0 = . ;
+   }
+ 
+diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S
+index 0992b99..fab1322 100644
+--- a/arch/x86/kernel/vmlinux_64.lds.S
++++ b/arch/x86/kernel/vmlinux_64.lds.S
+@@ -37,7 +37,7 @@ SECTIONS
+ 	KPROBES_TEXT
+ 	*(.fixup)
+ 	*(.gnu.warning)
+-	_etext = .;			/* End of text section */
++	_etext = .;		/* End of text section */
+   } :text = 0x9090
+ 
+   . = ALIGN(16);		/* Exception table */
+@@ -60,7 +60,7 @@ SECTIONS
+   	__tracedata_end = .;
+   }
+ 
+-  . = ALIGN(PAGE_SIZE);        /* Align data segment to page size boundary */
++  . = ALIGN(PAGE_SIZE);		/* Align data segment to page size boundary */
+ 				/* Data */
+   .data : AT(ADDR(.data) - LOAD_OFFSET) {
+ 	DATA_DATA
+@@ -119,7 +119,7 @@ SECTIONS
+   .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3))
+ 		{ *(.vsyscall_3) }
+ 
+-  . = VSYSCALL_VIRT_ADDR + 4096;
++  . = VSYSCALL_VIRT_ADDR + PAGE_SIZE;
+ 
+ #undef VSYSCALL_ADDR
+ #undef VSYSCALL_PHYS_ADDR
+@@ -129,28 +129,28 @@ SECTIONS
+ #undef VVIRT_OFFSET
+ #undef VVIRT
+ 
+-  . = ALIGN(8192);		/* init_task */
++  . = ALIGN(THREAD_SIZE);	/* init_task */
+   .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
+ 	*(.data.init_task)
+   }:data.init
+ 
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
+ 	*(.data.page_aligned)
+   }
+ 
+   /* might get freed after init */
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   __smp_alt_begin = .;
+   __smp_locks = .;
+   .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
+ 	*(.smp_locks)
+   }
+   __smp_locks_end = .;
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   __smp_alt_end = .;
+ 
+-  . = ALIGN(4096);		/* Init code and data */
++  . = ALIGN(PAGE_SIZE);		/* Init code and data */
+   __init_begin = .;
+   .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
+ 	_sinittext = .;
+@@ -191,7 +191,7 @@ SECTIONS
+   .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
+ 	*(.altinstructions)
+   }
+-  __alt_instructions_end = .; 
++  __alt_instructions_end = .;
+   .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
+ 	*(.altinstr_replacement)
+   }
+@@ -207,25 +207,25 @@ SECTIONS
+ /* vdso blob that is mapped into user space */
+   vdso_start = . ;
+   .vdso  : AT(ADDR(.vdso) - LOAD_OFFSET) { *(.vdso) }
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   vdso_end = .;
+ 
+ #ifdef CONFIG_BLK_DEV_INITRD
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   __initramfs_start = .;
+   .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
+   __initramfs_end = .;
+ #endif
+ 
+-  PERCPU(4096)
++  PERCPU(PAGE_SIZE)
+ 
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   __init_end = .;
+ 
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   __nosave_begin = .;
+   .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   __nosave_end = .;
+ 
+   __bss_start = .;		/* BSS */
+diff --git a/arch/x86/lib/csum-wrappers_64.c b/arch/x86/lib/csum-wrappers_64.c
+index fd42a4a..459b58a 100644
+--- a/arch/x86/lib/csum-wrappers_64.c
++++ b/arch/x86/lib/csum-wrappers_64.c
+@@ -1,117 +1,129 @@
+-/* Copyright 2002,2003 Andi Kleen, SuSE Labs.
++/*
++ * Copyright 2002, 2003 Andi Kleen, SuSE Labs.
+  * Subject to the GNU Public License v.2
+- * 
++ *
+  * Wrappers of assembly checksum functions for x86-64.
+  */
+-
+ #include <asm/checksum.h>
+ #include <linux/module.h>
+ 
+-/** 
+- * csum_partial_copy_from_user - Copy and checksum from user space. 
+- * @src: source address (user space) 
++/**
++ * csum_partial_copy_from_user - Copy and checksum from user space.
++ * @src: source address (user space)
+  * @dst: destination address
+  * @len: number of bytes to be copied.
+  * @isum: initial sum that is added into the result (32bit unfolded)
+  * @errp: set to -EFAULT for an bad source address.
+- * 
++ *
+  * Returns an 32bit unfolded checksum of the buffer.
+- * src and dst are best aligned to 64bits. 
+- */ 
++ * src and dst are best aligned to 64bits.
++ */
+ __wsum
+ csum_partial_copy_from_user(const void __user *src, void *dst,
+ 			    int len, __wsum isum, int *errp)
+-{ 
++{
+ 	might_sleep();
+ 	*errp = 0;
+-	if (likely(access_ok(VERIFY_READ,src, len))) { 
+-		/* Why 6, not 7? To handle odd addresses aligned we
+-		   would need to do considerable complications to fix the
+-		   checksum which is defined as an 16bit accumulator. The
+-		   fix alignment code is primarily for performance
+-		   compatibility with 32bit and that will handle odd
+-		   addresses slowly too. */
+-		if (unlikely((unsigned long)src & 6)) {			
+-			while (((unsigned long)src & 6) && len >= 2) { 
+-				__u16 val16;			
+-				*errp = __get_user(val16, (const __u16 __user *)src);
+-				if (*errp)
+-					return isum;
+-				*(__u16 *)dst = val16;
+-				isum = (__force __wsum)add32_with_carry(
+-						(__force unsigned)isum, val16);
+-				src += 2; 
+-				dst += 2; 
+-				len -= 2;
+-			}
++
++	if (!likely(access_ok(VERIFY_READ, src, len)))
++		goto out_err;
++
++	/*
++	 * Why 6, not 7? To handle odd addresses aligned we
++	 * would need to do considerable complications to fix the
++	 * checksum which is defined as an 16bit accumulator. The
++	 * fix alignment code is primarily for performance
++	 * compatibility with 32bit and that will handle odd
++	 * addresses slowly too.
++	 */
++	if (unlikely((unsigned long)src & 6)) {
++		while (((unsigned long)src & 6) && len >= 2) {
++			__u16 val16;
++
++			*errp = __get_user(val16, (const __u16 __user *)src);
++			if (*errp)
++				return isum;
++
++			*(__u16 *)dst = val16;
++			isum = (__force __wsum)add32_with_carry(
++					(__force unsigned)isum, val16);
++			src += 2;
++			dst += 2;
++			len -= 2;
+ 		}
+-		isum = csum_partial_copy_generic((__force const void *)src,
+-					dst, len, isum, errp, NULL);
+-		if (likely(*errp == 0)) 
+-			return isum;
+-	} 
++	}
++	isum = csum_partial_copy_generic((__force const void *)src,
++				dst, len, isum, errp, NULL);
++	if (unlikely(*errp))
++		goto out_err;
++
++	return isum;
++
++out_err:
+ 	*errp = -EFAULT;
+-	memset(dst,0,len); 
+-	return isum;		
+-} 
++	memset(dst, 0, len);
+ 
++	return isum;
++}
+ EXPORT_SYMBOL(csum_partial_copy_from_user);
+ 
+-/** 
+- * csum_partial_copy_to_user - Copy and checksum to user space. 
++/**
++ * csum_partial_copy_to_user - Copy and checksum to user space.
+  * @src: source address
+  * @dst: destination address (user space)
+  * @len: number of bytes to be copied.
+  * @isum: initial sum that is added into the result (32bit unfolded)
+  * @errp: set to -EFAULT for an bad destination address.
+- * 
++ *
+  * Returns an 32bit unfolded checksum of the buffer.
+  * src and dst are best aligned to 64bits.
+- */ 
++ */
+ __wsum
+ csum_partial_copy_to_user(const void *src, void __user *dst,
+ 			  int len, __wsum isum, int *errp)
+-{ 
++{
+ 	might_sleep();
++
+ 	if (unlikely(!access_ok(VERIFY_WRITE, dst, len))) {
+ 		*errp = -EFAULT;
+-		return 0; 
++		return 0;
+ 	}
+ 
+ 	if (unlikely((unsigned long)dst & 6)) {
+-		while (((unsigned long)dst & 6) && len >= 2) { 
++		while (((unsigned long)dst & 6) && len >= 2) {
+ 			__u16 val16 = *(__u16 *)src;
++
+ 			isum = (__force __wsum)add32_with_carry(
+ 					(__force unsigned)isum, val16);
+ 			*errp = __put_user(val16, (__u16 __user *)dst);
+ 			if (*errp)
+ 				return isum;
+-			src += 2; 
+-			dst += 2; 
++			src += 2;
++			dst += 2;
+ 			len -= 2;
+ 		}
+ 	}
+ 
+ 	*errp = 0;
+-	return csum_partial_copy_generic(src, (void __force *)dst,len,isum,NULL,errp); 
+-} 
+-
++	return csum_partial_copy_generic(src, (void __force *)dst,
++					 len, isum, NULL, errp);
++}
+ EXPORT_SYMBOL(csum_partial_copy_to_user);
+ 
+-/** 
++/**
+  * csum_partial_copy_nocheck - Copy and checksum.
+  * @src: source address
+  * @dst: destination address
+  * @len: number of bytes to be copied.
+  * @isum: initial sum that is added into the result (32bit unfolded)
+- * 
++ *
+  * Returns an 32bit unfolded checksum of the buffer.
+- */ 
++ */
+ __wsum
+ csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
+-{ 
+-	return csum_partial_copy_generic(src,dst,len,sum,NULL,NULL);
+-} 
++{
++	return csum_partial_copy_generic(src, dst, len, sum, NULL, NULL);
++}
+ EXPORT_SYMBOL(csum_partial_copy_nocheck);
+ 
+ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+@@ -119,17 +131,20 @@ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+ 			__u32 len, unsigned short proto, __wsum sum)
+ {
+ 	__u64 rest, sum64;
+-     
++
+ 	rest = (__force __u64)htonl(len) + (__force __u64)htons(proto) +
+ 		(__force __u64)sum;
+-	asm("  addq (%[saddr]),%[sum]\n"
+-	    "  adcq 8(%[saddr]),%[sum]\n"
+-	    "  adcq (%[daddr]),%[sum]\n" 
+-	    "  adcq 8(%[daddr]),%[sum]\n"
+-	    "  adcq $0,%[sum]\n"
+-	    : [sum] "=r" (sum64) 
+-	    : "[sum]" (rest),[saddr] "r" (saddr), [daddr] "r" (daddr));
+-	return csum_fold((__force __wsum)add32_with_carry(sum64 & 0xffffffff, sum64>>32));
+-}
+ 
++	asm("	addq (%[saddr]),%[sum]\n"
++	    "	adcq 8(%[saddr]),%[sum]\n"
++	    "	adcq (%[daddr]),%[sum]\n"
++	    "	adcq 8(%[daddr]),%[sum]\n"
++	    "	adcq $0,%[sum]\n"
++
++	    : [sum] "=r" (sum64)
++	    : "[sum]" (rest), [saddr] "r" (saddr), [daddr] "r" (daddr));
++
++	return csum_fold(
++	       (__force __wsum)add32_with_carry(sum64 & 0xffffffff, sum64>>32));
++}
+ EXPORT_SYMBOL(csum_ipv6_magic);
+diff --git a/arch/x86/lib/io_64.c b/arch/x86/lib/io_64.c
+index 87b4a4e..3f1eb59 100644
+--- a/arch/x86/lib/io_64.c
++++ b/arch/x86/lib/io_64.c
+@@ -1,23 +1,25 @@
+ #include <linux/string.h>
+-#include <asm/io.h>
+ #include <linux/module.h>
++#include <asm/io.h>
+ 
+-void __memcpy_toio(unsigned long dst,const void*src,unsigned len)
++void __memcpy_toio(unsigned long dst, const void *src, unsigned len)
+ {
+-	__inline_memcpy((void *) dst,src,len);
++	__inline_memcpy((void *)dst, src, len);
+ }
+ EXPORT_SYMBOL(__memcpy_toio);
+ 
+-void __memcpy_fromio(void *dst,unsigned long src,unsigned len)
++void __memcpy_fromio(void *dst, unsigned long src, unsigned len)
+ {
+-	__inline_memcpy(dst,(const void *) src,len);
++	__inline_memcpy(dst, (const void *)src, len);
+ }
+ EXPORT_SYMBOL(__memcpy_fromio);
+ 
+ void memset_io(volatile void __iomem *a, int b, size_t c)
+ {
+-	/* XXX: memset can mangle the IO patterns quite a bit.
+-	   perhaps it would be better to use a dumb one */
+-	memset((void *)a,b,c);
++	/*
++	 * TODO: memset can mangle the IO patterns quite a bit.
++	 * perhaps it would be better to use a dumb one:
++	 */
++	memset((void *)a, b, c);
+ }
+ EXPORT_SYMBOL(memset_io);
+diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
+index a4a9ccc..bb652f5 100644
+--- a/arch/x86/mm/init_64.c
++++ b/arch/x86/mm/init_64.c
+@@ -171,6 +171,33 @@ set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot)
+ 	__flush_tlb_one(vaddr);
+ }
+ 
++/*
++ * The head.S code sets up the kernel high mapping from:
++ * __START_KERNEL_map to __START_KERNEL_map + KERNEL_TEXT_SIZE
++ *
++ * phys_addr holds the negative offset to the kernel, which is added
++ * to the compile time generated pmds. This results in invalid pmds up
++ * to the point where we hit the physaddr 0 mapping.
++ *
++ * We limit the mappings to the region from _text to _end.  _end is
++ * rounded up to the 2MB boundary. This catches the invalid pmds as
++ * well, as they are located before _text:
++ */
++void __init cleanup_highmap(void)
++{
++	unsigned long vaddr = __START_KERNEL_map;
++	unsigned long end = round_up((unsigned long)_end, PMD_SIZE) - 1;
++	pmd_t *pmd = level2_kernel_pgt;
++	pmd_t *last_pmd = pmd + PTRS_PER_PMD;
++
++	for (; pmd < last_pmd; pmd++, vaddr += PMD_SIZE) {
++		if (!pmd_present(*pmd))
++			continue;
++		if (vaddr < (unsigned long) _text || vaddr > end)
++			set_pmd(pmd, __pmd(0));
++	}
++}
++
+ /* NOTE: this is meant to be run only at boot */
+ void __init
+ __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
+diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
+index 9f42d7e..882328e 100644
+--- a/arch/x86/mm/ioremap.c
++++ b/arch/x86/mm/ioremap.c
+@@ -42,6 +42,22 @@ int page_is_ram(unsigned long pagenr)
+ 	unsigned long addr, end;
+ 	int i;
+ 
++	/*
++	 * A special case is the first 4Kb of memory;
++	 * This is a BIOS owned area, not kernel ram, but generally
++	 * not listed as such in the E820 table.
++	 */
++	if (pagenr == 0)
++		return 0;
++
++	/*
++	 * Second special case: Some BIOSen report the PC BIOS
++	 * area (640->1Mb) as ram even though it is not.
++	 */
++	if (pagenr >= (BIOS_BEGIN >> PAGE_SHIFT) &&
++		    pagenr < (BIOS_END >> PAGE_SHIFT))
++		return 0;
++
+ 	for (i = 0; i < e820.nr_map; i++) {
+ 		/*
+ 		 * Not usable memory:
+@@ -51,14 +67,6 @@ int page_is_ram(unsigned long pagenr)
+ 		addr = (e820.map[i].addr + PAGE_SIZE-1) >> PAGE_SHIFT;
+ 		end = (e820.map[i].addr + e820.map[i].size) >> PAGE_SHIFT;
+ 
+-		/*
+-		 * Sanity check: Some BIOSen report areas as RAM that
+-		 * are not. Notably the 640->1Mb area, which is the
+-		 * PCI BIOS area.
+-		 */
+-		if (addr >= (BIOS_BEGIN >> PAGE_SHIFT) &&
+-		    end < (BIOS_END >> PAGE_SHIFT))
+-			continue;
+ 
+ 		if ((pagenr >= addr) && (pagenr < end))
+ 			return 1;
+@@ -126,6 +134,8 @@ static void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
+ 			return NULL;
+ 	}
+ 
++	WARN_ON_ONCE(page_is_ram(pfn));
++
+ 	switch (mode) {
+ 	case IOR_MODE_UNCACHED:
+ 	default:
+diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
+index 1aecc65..59898fb 100644
+--- a/arch/x86/mm/numa_64.c
++++ b/arch/x86/mm/numa_64.c
+@@ -494,11 +494,13 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
+ 	int i;
+ 
+ 	nodes_clear(node_possible_map);
++	nodes_clear(node_online_map);
+ 
+ #ifdef CONFIG_NUMA_EMU
+ 	if (cmdline && !numa_emulation(start_pfn, end_pfn))
+ 		return;
+ 	nodes_clear(node_possible_map);
++	nodes_clear(node_online_map);
+ #endif
+ 
+ #ifdef CONFIG_ACPI_NUMA
+@@ -506,6 +508,7 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
+ 					  end_pfn << PAGE_SHIFT))
+ 		return;
+ 	nodes_clear(node_possible_map);
++	nodes_clear(node_online_map);
+ #endif
+ 
+ #ifdef CONFIG_K8_NUMA
+@@ -513,6 +516,7 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
+ 					end_pfn<<PAGE_SHIFT))
+ 		return;
+ 	nodes_clear(node_possible_map);
++	nodes_clear(node_online_map);
+ #endif
+ 	printk(KERN_INFO "%s\n",
+ 	       numa_off ? "NUMA turned off" : "No NUMA configuration found");
+@@ -524,7 +528,6 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
+ 	memnode_shift = 63;
+ 	memnodemap = memnode.embedded_map;
+ 	memnodemap[0] = 0;
+-	nodes_clear(node_online_map);
+ 	node_set_online(0);
+ 	node_set(0, node_possible_map);
+ 	for (i = 0; i < NR_CPUS; i++)
+diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
+index 4119379..e2a74ea 100644
+--- a/arch/x86/mm/pageattr.c
++++ b/arch/x86/mm/pageattr.c
+@@ -16,6 +16,7 @@
+ #include <asm/sections.h>
+ #include <asm/uaccess.h>
+ #include <asm/pgalloc.h>
++#include <asm/proto.h>
+ 
+ /*
+  * The current flushing context - we pass it instead of 5 arguments:
+@@ -26,8 +27,23 @@ struct cpa_data {
+ 	pgprot_t	mask_clr;
+ 	int		numpages;
+ 	int		flushtlb;
++	unsigned long	pfn;
+ };
+ 
++#ifdef CONFIG_X86_64
++
++static inline unsigned long highmap_start_pfn(void)
++{
++	return __pa(_text) >> PAGE_SHIFT;
++}
++
++static inline unsigned long highmap_end_pfn(void)
++{
++	return __pa(round_up((unsigned long)_end, PMD_SIZE)) >> PAGE_SHIFT;
++}
++
++#endif
++
+ static inline int
+ within(unsigned long addr, unsigned long start, unsigned long end)
+ {
+@@ -123,29 +139,14 @@ static void cpa_flush_range(unsigned long start, int numpages, int cache)
+ 	}
+ }
+ 
+-#define HIGH_MAP_START	__START_KERNEL_map
+-#define HIGH_MAP_END	(__START_KERNEL_map + KERNEL_TEXT_SIZE)
+-
+-
+-/*
+- * Converts a virtual address to a X86-64 highmap address
+- */
+-static unsigned long virt_to_highmap(void *address)
+-{
+-#ifdef CONFIG_X86_64
+-	return __pa((unsigned long)address) + HIGH_MAP_START - phys_base;
+-#else
+-	return (unsigned long)address;
+-#endif
+-}
+-
+ /*
+  * Certain areas of memory on x86 require very specific protection flags,
+  * for example the BIOS area or kernel text. Callers don't always get this
+  * right (again, ioremap() on BIOS memory is not uncommon) so this function
+  * checks and fixes these known static required protection bits.
+  */
+-static inline pgprot_t static_protections(pgprot_t prot, unsigned long address)
++static inline pgprot_t static_protections(pgprot_t prot, unsigned long address,
++				   unsigned long pfn)
+ {
+ 	pgprot_t forbidden = __pgprot(0);
+ 
+@@ -153,30 +154,23 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address)
+ 	 * The BIOS area between 640k and 1Mb needs to be executable for
+ 	 * PCI BIOS based config access (CONFIG_PCI_GOBIOS) support.
+ 	 */
+-	if (within(__pa(address), BIOS_BEGIN, BIOS_END))
++	if (within(pfn, BIOS_BEGIN >> PAGE_SHIFT, BIOS_END >> PAGE_SHIFT))
+ 		pgprot_val(forbidden) |= _PAGE_NX;
+ 
+ 	/*
+ 	 * The kernel text needs to be executable for obvious reasons
+-	 * Does not cover __inittext since that is gone later on
++	 * Does not cover __inittext since that is gone later on. On
++	 * 64bit we do not enforce !NX on the low mapping
+ 	 */
+ 	if (within(address, (unsigned long)_text, (unsigned long)_etext))
+ 		pgprot_val(forbidden) |= _PAGE_NX;
+-	/*
+-	 * Do the same for the x86-64 high kernel mapping
+-	 */
+-	if (within(address, virt_to_highmap(_text), virt_to_highmap(_etext)))
+-		pgprot_val(forbidden) |= _PAGE_NX;
+ 
+-	/* The .rodata section needs to be read-only */
+-	if (within(address, (unsigned long)__start_rodata,
+-				(unsigned long)__end_rodata))
+-		pgprot_val(forbidden) |= _PAGE_RW;
+ 	/*
+-	 * Do the same for the x86-64 high kernel mapping
++	 * The .rodata section needs to be read-only. Using the pfn
++	 * catches all aliases.
+ 	 */
+-	if (within(address, virt_to_highmap(__start_rodata),
+-				virt_to_highmap(__end_rodata)))
++	if (within(pfn, __pa((unsigned long)__start_rodata) >> PAGE_SHIFT,
++		   __pa((unsigned long)__end_rodata) >> PAGE_SHIFT))
+ 		pgprot_val(forbidden) |= _PAGE_RW;
+ 
+ 	prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden));
+@@ -253,7 +247,7 @@ static int
+ try_preserve_large_page(pte_t *kpte, unsigned long address,
+ 			struct cpa_data *cpa)
+ {
+-	unsigned long nextpage_addr, numpages, pmask, psize, flags, addr;
++	unsigned long nextpage_addr, numpages, pmask, psize, flags, addr, pfn;
+ 	pte_t new_pte, old_pte, *tmp;
+ 	pgprot_t old_prot, new_prot;
+ 	int i, do_split = 1;
+@@ -301,7 +295,15 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
+ 
+ 	pgprot_val(new_prot) &= ~pgprot_val(cpa->mask_clr);
+ 	pgprot_val(new_prot) |= pgprot_val(cpa->mask_set);
+-	new_prot = static_protections(new_prot, address);
++
++	/*
++	 * old_pte points to the large page base address. So we need
++	 * to add the offset of the virtual address:
++	 */
++	pfn = pte_pfn(old_pte) + ((address & (psize - 1)) >> PAGE_SHIFT);
++	cpa->pfn = pfn;
++
++	new_prot = static_protections(new_prot, address, pfn);
+ 
+ 	/*
+ 	 * We need to check the full range, whether
+@@ -309,8 +311,9 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
+ 	 * the pages in the range we try to preserve:
+ 	 */
+ 	addr = address + PAGE_SIZE;
+-	for (i = 1; i < cpa->numpages; i++, addr += PAGE_SIZE) {
+-		pgprot_t chk_prot = static_protections(new_prot, addr);
++	pfn++;
++	for (i = 1; i < cpa->numpages; i++, addr += PAGE_SIZE, pfn++) {
++		pgprot_t chk_prot = static_protections(new_prot, addr, pfn);
+ 
+ 		if (pgprot_val(chk_prot) != pgprot_val(new_prot))
+ 			goto out_unlock;
+@@ -505,46 +508,46 @@ out_unlock:
+ 	return 0;
+ }
+ 
+-static int __change_page_attr(unsigned long address, struct cpa_data *cpa)
++static int __change_page_attr(struct cpa_data *cpa, int primary)
+ {
++	unsigned long address = cpa->vaddr;
+ 	int do_split, err;
+ 	unsigned int level;
+-	struct page *kpte_page;
+-	pte_t *kpte;
++	pte_t *kpte, old_pte;
+ 
+ repeat:
+ 	kpte = lookup_address(address, &level);
+ 	if (!kpte)
+-		return -EINVAL;
++		return primary ? -EINVAL : 0;
+ 
+-	kpte_page = virt_to_page(kpte);
+-	BUG_ON(PageLRU(kpte_page));
+-	BUG_ON(PageCompound(kpte_page));
++	old_pte = *kpte;
++	if (!pte_val(old_pte)) {
++		if (!primary)
++			return 0;
++		printk(KERN_WARNING "CPA: called for zero pte. "
++		       "vaddr = %lx cpa->vaddr = %lx\n", address,
++		       cpa->vaddr);
++		WARN_ON(1);
++		return -EINVAL;
++	}
+ 
+ 	if (level == PG_LEVEL_4K) {
+-		pte_t new_pte, old_pte = *kpte;
++		pte_t new_pte;
+ 		pgprot_t new_prot = pte_pgprot(old_pte);
+-
+-		if(!pte_val(old_pte)) {
+-			printk(KERN_WARNING "CPA: called for zero pte. "
+-			       "vaddr = %lx cpa->vaddr = %lx\n", address,
+-				cpa->vaddr);
+-			WARN_ON(1);
+-			return -EINVAL;
+-		}
++		unsigned long pfn = pte_pfn(old_pte);
+ 
+ 		pgprot_val(new_prot) &= ~pgprot_val(cpa->mask_clr);
+ 		pgprot_val(new_prot) |= pgprot_val(cpa->mask_set);
+ 
+-		new_prot = static_protections(new_prot, address);
++		new_prot = static_protections(new_prot, address, pfn);
+ 
+ 		/*
+ 		 * We need to keep the pfn from the existing PTE,
+ 		 * after all we're only going to change it's attributes
+ 		 * not the memory it points to
+ 		 */
+-		new_pte = pfn_pte(pte_pfn(old_pte), canon_pgprot(new_prot));
+-
++		new_pte = pfn_pte(pfn, canon_pgprot(new_prot));
++		cpa->pfn = pfn;
+ 		/*
+ 		 * Do we really change anything ?
+ 		 */
+@@ -581,67 +584,59 @@ repeat:
+ 	return err;
+ }
+ 
+-/**
+- * change_page_attr_addr - Change page table attributes in linear mapping
+- * @address: Virtual address in linear mapping.
+- * @prot:    New page table attribute (PAGE_*)
+- *
+- * Change page attributes of a page in the direct mapping. This is a variant
+- * of change_page_attr() that also works on memory holes that do not have
+- * mem_map entry (pfn_valid() is false).
+- *
+- * See change_page_attr() documentation for more details.
+- *
+- * Modules and drivers should use the set_memory_* APIs instead.
+- */
+-static int change_page_attr_addr(struct cpa_data *cpa)
++static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias);
++
++static int cpa_process_alias(struct cpa_data *cpa)
+ {
+-	int err;
+-	unsigned long address = cpa->vaddr;
++	struct cpa_data alias_cpa;
++	int ret = 0;
+ 
+-#ifdef CONFIG_X86_64
+-	unsigned long phys_addr = __pa(address);
++	if (cpa->pfn > max_pfn_mapped)
++		return 0;
+ 
+ 	/*
+-	 * If we are inside the high mapped kernel range, then we
+-	 * fixup the low mapping first. __va() returns the virtual
+-	 * address in the linear mapping:
++	 * No need to redo, when the primary call touched the direct
++	 * mapping already:
+ 	 */
+-	if (within(address, HIGH_MAP_START, HIGH_MAP_END))
+-		address = (unsigned long) __va(phys_addr);
+-#endif
++	if (!within(cpa->vaddr, PAGE_OFFSET,
++		    PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT))) {
++
++		alias_cpa = *cpa;
++		alias_cpa.vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT);
+ 
+-	err = __change_page_attr(address, cpa);
+-	if (err)
+-		return err;
++		ret = __change_page_attr_set_clr(&alias_cpa, 0);
++	}
+ 
+ #ifdef CONFIG_X86_64
++	if (ret)
++		return ret;
++	/*
++	 * No need to redo, when the primary call touched the high
++	 * mapping already:
++	 */
++	if (within(cpa->vaddr, (unsigned long) _text, (unsigned long) _end))
++		return 0;
++
+ 	/*
+ 	 * If the physical address is inside the kernel map, we need
+ 	 * to touch the high mapped kernel as well:
+ 	 */
+-	if (within(phys_addr, 0, KERNEL_TEXT_SIZE)) {
+-		/*
+-		 * Calc the high mapping address. See __phys_addr()
+-		 * for the non obvious details.
+-		 *
+-		 * Note that NX and other required permissions are
+-		 * checked in static_protections().
+-		 */
+-		address = phys_addr + HIGH_MAP_START - phys_base;
++	if (!within(cpa->pfn, highmap_start_pfn(), highmap_end_pfn()))
++		return 0;
+ 
+-		/*
+-		 * Our high aliases are imprecise, because we check
+-		 * everything between 0 and KERNEL_TEXT_SIZE, so do
+-		 * not propagate lookup failures back to users:
+-		 */
+-		__change_page_attr(address, cpa);
+-	}
++	alias_cpa = *cpa;
++	alias_cpa.vaddr =
++		(cpa->pfn << PAGE_SHIFT) + __START_KERNEL_map - phys_base;
++
++	/*
++	 * The high mapping range is imprecise, so ignore the return value.
++	 */
++	__change_page_attr_set_clr(&alias_cpa, 0);
+ #endif
+-	return err;
++	return ret;
+ }
+ 
+-static int __change_page_attr_set_clr(struct cpa_data *cpa)
++static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias)
+ {
+ 	int ret, numpages = cpa->numpages;
+ 
+@@ -651,10 +646,17 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa)
+ 		 * preservation check.
+ 		 */
+ 		cpa->numpages = numpages;
+-		ret = change_page_attr_addr(cpa);
++
++		ret = __change_page_attr(cpa, checkalias);
+ 		if (ret)
+ 			return ret;
+ 
++		if (checkalias) {
++			ret = cpa_process_alias(cpa);
++			if (ret)
++				return ret;
++		}
++
+ 		/*
+ 		 * Adjust the number of pages with the result of the
+ 		 * CPA operation. Either a large page has been
+@@ -677,7 +679,7 @@ static int change_page_attr_set_clr(unsigned long addr, int numpages,
+ 				    pgprot_t mask_set, pgprot_t mask_clr)
+ {
+ 	struct cpa_data cpa;
+-	int ret, cache;
++	int ret, cache, checkalias;
+ 
+ 	/*
+ 	 * Check, if we are requested to change a not supported
+@@ -703,7 +705,10 @@ static int change_page_attr_set_clr(unsigned long addr, int numpages,
+ 	cpa.mask_clr = mask_clr;
+ 	cpa.flushtlb = 0;
+ 
+-	ret = __change_page_attr_set_clr(&cpa);
++	/* No alias checking for _NX bit modifications */
++	checkalias = (pgprot_val(mask_set) | pgprot_val(mask_clr)) != _PAGE_NX;
++
++	ret = __change_page_attr_set_clr(&cpa, checkalias);
+ 
+ 	/*
+ 	 * Check whether we really changed something:
+@@ -841,7 +846,7 @@ static int __set_pages_p(struct page *page, int numpages)
+ 				.mask_set = __pgprot(_PAGE_PRESENT | _PAGE_RW),
+ 				.mask_clr = __pgprot(0)};
+ 
+-	return __change_page_attr_set_clr(&cpa);
++	return __change_page_attr_set_clr(&cpa, 1);
+ }
+ 
+ static int __set_pages_np(struct page *page, int numpages)
+@@ -851,7 +856,7 @@ static int __set_pages_np(struct page *page, int numpages)
+ 				.mask_set = __pgprot(0),
+ 				.mask_clr = __pgprot(_PAGE_PRESENT | _PAGE_RW)};
+ 
+-	return __change_page_attr_set_clr(&cpa);
++	return __change_page_attr_set_clr(&cpa, 1);
+ }
+ 
+ void kernel_map_pages(struct page *page, int numpages, int enable)
+diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c
+index ecd91ea..845001c 100644
+--- a/arch/x86/mm/srat_64.c
++++ b/arch/x86/mm/srat_64.c
+@@ -166,7 +166,8 @@ static inline int save_add_info(void) {return 0;}
+  * Both SPARSE and RESERVE need nodes_add information.
+  * This code supports one contiguous hot add area per node.
+  */
+-static int reserve_hotadd(int node, unsigned long start, unsigned long end)
++static int __init
++reserve_hotadd(int node, unsigned long start, unsigned long end)
+ {
+ 	unsigned long s_pfn = start >> PAGE_SHIFT;
+ 	unsigned long e_pfn = end >> PAGE_SHIFT;
+diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
+index b7c67a1..7b6e3bb 100644
+--- a/arch/x86/pci/common.c
++++ b/arch/x86/pci/common.c
+@@ -541,7 +541,7 @@ void pcibios_disable_device (struct pci_dev *dev)
+ 		pcibios_disable_irq(dev);
+ }
+ 
+-struct pci_bus *pci_scan_bus_with_sysdata(int busno)
++struct pci_bus *__devinit pci_scan_bus_with_sysdata(int busno)
+ {
+ 	struct pci_bus *bus = NULL;
+ 	struct pci_sysdata *sd;
+diff --git a/arch/x86/power/hibernate_asm_64.S b/arch/x86/power/hibernate_asm_64.S
+index 1deb324..0004159 100644
+--- a/arch/x86/power/hibernate_asm_64.S
++++ b/arch/x86/power/hibernate_asm_64.S
+@@ -20,6 +20,7 @@
+ #include <asm/segment.h>
+ #include <asm/page.h>
+ #include <asm/asm-offsets.h>
++#include <asm/processor-flags.h>
+ 
+ ENTRY(swsusp_arch_suspend)
+ 	movq	$saved_context, %rax
+@@ -60,7 +61,7 @@ ENTRY(restore_image)
+ 	/* Flush TLB */
+ 	movq	mmu_cr4_features(%rip), %rax
+ 	movq	%rax, %rdx
+-	andq	$~(1<<7), %rdx	# PGE
++	andq	$~(X86_CR4_PGE), %rdx
+ 	movq	%rdx, %cr4;  # turn off PGE
+ 	movq	%cr3, %rcx;  # flush TLB
+ 	movq	%rcx, %cr3;
+@@ -112,7 +113,7 @@ ENTRY(restore_registers)
+ 	/* Flush TLB, including "global" things (vmalloc) */
+ 	movq	mmu_cr4_features(%rip), %rax
+ 	movq	%rax, %rdx
+-	andq	$~(1<<7), %rdx;  # PGE
++	andq	$~(X86_CR4_PGE), %rdx
+ 	movq	%rdx, %cr4;  # turn off PGE
+ 	movq	%cr3, %rcx;  # flush TLB
+ 	movq	%rcx, %cr3
+diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile
+index 56685a8..4bd1e14 100644
+--- a/arch/xtensa/Makefile
++++ b/arch/xtensa/Makefile
+@@ -59,7 +59,7 @@ LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
+ head-y		:= arch/xtensa/kernel/head.o
+ core-y		+= arch/xtensa/kernel/ arch/xtensa/mm/
+ ifneq ($(PLATFORM),)
+-core-y		+= arch/xtensa/platform-$(PLATFORM)/
++core-y		+= arch/xtensa/platforms/$(PLATFORM)/
+ endif
+ libs-y		+= arch/xtensa/lib/ $(LIBGCC)
+ 
+diff --git a/arch/xtensa/boot/boot-elf/Makefile b/arch/xtensa/boot/boot-elf/Makefile
+index 734db7f..08e8814 100644
+--- a/arch/xtensa/boot/boot-elf/Makefile
++++ b/arch/xtensa/boot/boot-elf/Makefile
+@@ -14,25 +14,26 @@ OBJCOPY_ARGS    := -O elf32-xtensa-le
+ endif
+ 
+ export OBJCOPY_ARGS
++export CPPFLAGS_boot.lds += -P -C
+ 
+ boot-y		:= bootstrap.o
+ 
+ OBJS		:= $(addprefix $(obj)/,$(boot-y))
+ 
+-Image:	vmlinux $(OBJS)
+-	$(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \
++Image:	vmlinux $(OBJS) arch/$(ARCH)/boot/boot-elf/boot.lds
++	$(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \
+ 		vmlinux vmlinux.tmp
+ 	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
+ 		--add-section image=vmlinux.tmp \
+ 		--set-section-flags image=contents,alloc,load,load,data \
+ 		$(OBJS) $@.tmp
+ 	$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
+-		-T $(srctree)/arch/$(ARCH)/boot/boot-elf/boot.ld \
++		-T arch/$(ARCH)/boot/boot-elf/boot.lds \
+ 		-o arch/$(ARCH)/boot/$@.elf $@.tmp
+ 	rm -f $@.tmp vmlinux.tmp
+ 
+ Image.initrd:	vmlinux $(OBJS)
+-	$(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \
++	$(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \
+ 		--add-section .initrd=arch/$(ARCH)/boot/ramdisk \
+ 		--set-section-flags .initrd=contents,alloc,load,load,data \
+ 		vmlinux vmlinux.tmp
+diff --git a/arch/xtensa/boot/boot-elf/boot.ld b/arch/xtensa/boot/boot-elf/boot.ld
+deleted file mode 100644
+index 4ab06a0..0000000
+--- a/arch/xtensa/boot/boot-elf/boot.ld
++++ /dev/null
+@@ -1,71 +0,0 @@
+-OUTPUT_ARCH(xtensa)
+-
+-SECTIONS
+-{
+-	.start 0xD0000000 : { *(.start) }
+-
+-	.text 0xD0000000:
+-	{
+-		__reloc_start = . ;
+-		_text_start = . ;
+-		*(.literal .text.literal .text)
+-		_text_end = . ;
+-	}
+-
+-	.rodata ALIGN(0x04):
+-	{
+-		*(.rodata)
+-		*(.rodata1)
+-	}
+-
+-	.data ALIGN(0x04):
+-	{
+-		*(.data)
+-		*(.data1)
+-		*(.sdata)
+-		*(.sdata2)
+-		*(.got.plt)
+-		*(.got)
+-		*(.dynamic)
+-	}
+-
+-	__reloc_end = . ;
+-
+-	.initrd ALIGN(0x10) :
+-	{
+-		boot_initrd_start = . ;
+-		*(.initrd)
+-		boot_initrd_end = .;
+-	}
+-
+-	. = ALIGN(0x10);
+-	__image_load = . ;
+-	.image 0xd0001000:
+-	{
+-		_image_start = .;
+-		*(image)
+-		. = (. + 3) & ~ 3;
+-		_image_end = .	;
+-	}
+-
+-
+-	.bss ((LOADADDR(.image) + SIZEOF(.image) + 3) & ~ 3):
+-	{
+-		__bss_start = .;
+-		*(.sbss)
+-		*(.scommon)
+-		*(.dynbss)
+-		*(.bss)
+-		__bss_end = .;
+-	}
+-	_end = .;
+-	_param_start = .;
+-
+-	.ResetVector.text 0xfe000020 :
+-	{
+-		*(.ResetVector.text)
+-	}
+-
+-
+-	PROVIDE (end = .);
+-}
+diff --git a/arch/xtensa/boot/boot-elf/boot.lds.S b/arch/xtensa/boot/boot-elf/boot.lds.S
+new file mode 100644
+index 0000000..849dfca
+--- /dev/null
++++ b/arch/xtensa/boot/boot-elf/boot.lds.S
+@@ -0,0 +1,73 @@
++#include <asm/variant/core.h>
++OUTPUT_ARCH(xtensa)
++ENTRY(_ResetVector)
++
++SECTIONS
++{
++	.start 0xD0000000 : { *(.start) }
++
++	.text 0xD0000000:
++	{
++		__reloc_start = . ;
++		_text_start = . ;
++		*(.literal .text.literal .text)
++		_text_end = . ;
++	}
++
++	.rodata ALIGN(0x04):
++	{
++		*(.rodata)
++		*(.rodata1)
++	}
++
++	.data ALIGN(0x04):
++	{
++		*(.data)
++		*(.data1)
++		*(.sdata)
++		*(.sdata2)
++		*(.got.plt)
++		*(.got)
++		*(.dynamic)
++	}
++
++	__reloc_end = . ;
++
++	.initrd ALIGN(0x10) :
++	{
++		boot_initrd_start = . ;
++		*(.initrd)
++		boot_initrd_end = .;
++	}
++
++	. = ALIGN(0x10);
++	__image_load = . ;
++	.image 0xd0001000:
++	{
++		_image_start = .;
++		*(image)
++		. = (. + 3) & ~ 3;
++		_image_end = .	;
++	}
++
++
++	.bss ((LOADADDR(.image) + SIZEOF(.image) + 3) & ~ 3):
++	{
++		__bss_start = .;
++		*(.sbss)
++		*(.scommon)
++		*(.dynbss)
++		*(.bss)
++		__bss_end = .;
++	}
++	_end = .;
++	_param_start = .;
++
++	.ResetVector.text XCHAL_RESET_VECTOR_VADDR :
++	{
++		*(.ResetVector.text)
++	}
++
++
++	PROVIDE (end = .);
++}
+diff --git a/arch/xtensa/boot/boot-redboot/Makefile b/arch/xtensa/boot/boot-redboot/Makefile
+index 74d15d0..872029b 100644
+--- a/arch/xtensa/boot/boot-redboot/Makefile
++++ b/arch/xtensa/boot/boot-redboot/Makefile
+@@ -22,7 +22,7 @@ LIBS	:= arch/xtensa/boot/lib/lib.a arch/xtensa/lib/lib.a
+ LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
+ 
+ zImage: vmlinux $(OBJS) $(LIBS)
+-	$(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \
++	$(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \
+ 		vmlinux vmlinux.tmp
+ 	gzip -vf9 vmlinux.tmp
+ 	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
+diff --git a/arch/xtensa/boot/boot-redboot/boot.ld b/arch/xtensa/boot/boot-redboot/boot.ld
+index 65b7264..774db20 100644
+--- a/arch/xtensa/boot/boot-redboot/boot.ld
++++ b/arch/xtensa/boot/boot-redboot/boot.ld
+@@ -2,7 +2,7 @@ OUTPUT_ARCH(xtensa)
+ 
+ SECTIONS
+ {
+-	.start 0xD0200000 : { *(.start) }
++	.start 0xD1000000 : { *(.start) }
+ 
+ 	.text :
+ 	{
+diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c
+index d5ffe7b..ef63ada 100644
+--- a/arch/xtensa/kernel/asm-offsets.c
++++ b/arch/xtensa/kernel/asm-offsets.c
+@@ -21,7 +21,6 @@
+ #include <linux/mm.h>
+ 
+ #include <asm/ptrace.h>
+-#include <asm/processor.h>
+ #include <asm/uaccess.h>
+ 
+ #define DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+@@ -64,6 +63,8 @@ int main(void)
+ 	DEFINE(PT_SIZE, sizeof(struct pt_regs));
+ 	DEFINE(PT_AREG_END, offsetof (struct pt_regs, areg[XCHAL_NUM_AREGS]));
+ 	DEFINE(PT_USER_SIZE, offsetof(struct pt_regs, areg[XCHAL_NUM_AREGS]));
++	DEFINE(PT_XTREGS_OPT, offsetof(struct pt_regs, xtregs_opt));
++	DEFINE(XTREGS_OPT_SIZE, sizeof(xtregs_opt_t));
+ 
+ 	/* struct task_struct */
+ 	DEFINE(TASK_PTRACE, offsetof (struct task_struct, ptrace));
+@@ -77,7 +78,19 @@ int main(void)
+ 	/* struct thread_info (offset from start_struct) */
+ 	DEFINE(THREAD_RA, offsetof (struct task_struct, thread.ra));
+ 	DEFINE(THREAD_SP, offsetof (struct task_struct, thread.sp));
+-	DEFINE(THREAD_CP_SAVE, offsetof (struct task_struct, thread.cp_save));
++	DEFINE(THREAD_CPENABLE, offsetof (struct thread_info, cpenable));
++#if XTENSA_HAVE_COPROCESSORS
++	DEFINE(THREAD_XTREGS_CP0, offsetof (struct thread_info, xtregs_cp));
++	DEFINE(THREAD_XTREGS_CP1, offsetof (struct thread_info, xtregs_cp));
++	DEFINE(THREAD_XTREGS_CP2, offsetof (struct thread_info, xtregs_cp));
++	DEFINE(THREAD_XTREGS_CP3, offsetof (struct thread_info, xtregs_cp));
++	DEFINE(THREAD_XTREGS_CP4, offsetof (struct thread_info, xtregs_cp));
++	DEFINE(THREAD_XTREGS_CP5, offsetof (struct thread_info, xtregs_cp));
++	DEFINE(THREAD_XTREGS_CP6, offsetof (struct thread_info, xtregs_cp));
++	DEFINE(THREAD_XTREGS_CP7, offsetof (struct thread_info, xtregs_cp));
++#endif
++	DEFINE(THREAD_XTREGS_USER, offsetof (struct thread_info, xtregs_user));
++	DEFINE(XTREGS_USER_SIZE, sizeof(xtregs_user_t));
+ 	DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, thread.current_ds));
+ 
+ 	/* struct mm_struct */
+diff --git a/arch/xtensa/kernel/coprocessor.S b/arch/xtensa/kernel/coprocessor.S
+index 01bcb9f..2bc1e14 100644
+--- a/arch/xtensa/kernel/coprocessor.S
++++ b/arch/xtensa/kernel/coprocessor.S
+@@ -8,193 +8,328 @@
+  * License.  See the file "COPYING" in the main directory of this archive
+  * for more details.
+  *
+- * Copyright (C) 2003 - 2005 Tensilica Inc.
+- *
+- * Marc Gauthier <marc at tensilica.com> <marc at alumni.uwaterloo.ca>
++ * Copyright (C) 2003 - 2007 Tensilica Inc.
+  */
+ 
+-/*
+- * This module contains a table that describes the layout of the various
+- * custom registers and states associated with each coprocessor, as well
+- * as those not associated with any coprocessor ("extra state").
+- * This table is included with core dumps and is available via the ptrace
+- * interface, allowing the layout of such register/state information to
+- * be modified in the kernel without affecting the debugger.  Each
+- * register or state is identified using a 32-bit "libdb target number"
+- * assigned when the Xtensa processor is generated.
+- */
+ 
+ #include <linux/linkage.h>
++#include <asm/asm-offsets.h>
+ #include <asm/processor.h>
++#include <asm/coprocessor.h>
++#include <asm/thread_info.h>
++#include <asm/uaccess.h>
++#include <asm/unistd.h>
++#include <asm/ptrace.h>
++#include <asm/current.h>
++#include <asm/pgtable.h>
++#include <asm/page.h>
++#include <asm/signal.h>
++#include <asm/tlbflush.h>
+ 
+-#if XCHAL_HAVE_CP
++/*
++ * Entry condition:
++ *
++ *   a0:	trashed, original value saved on stack (PT_AREG0)
++ *   a1:	a1
++ *   a2:	new stack pointer, original in DEPC
++ *   a3:	dispatch table
++ *   depc:	a2, original value saved on stack (PT_DEPC)
++ *   excsave_1:	a3
++ *
++ *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
++ *	     <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
++ */
+ 
+-#define CP_LAST ((XCHAL_CP_MAX - 1) * COPROCESSOR_INFO_SIZE)
++/* IO protection is currently unsupported. */
+ 
+-ENTRY(release_coprocessors)
++ENTRY(fast_io_protect)
++	wsr	a0, EXCSAVE_1
++	movi	a0, unrecoverable_exception
++	callx0	a0
+ 
+-	entry	a1, 16
+-						# a2: task
+-	movi	a3, 1 << XCHAL_CP_MAX 		# a3: coprocessor-bit
+-	movi	a4, coprocessor_info+CP_LAST	# a4: owner-table
+-						# a5: tmp
+-	movi	a6, 0				# a6: 0
+-	rsil	a7, LOCKLEVEL			# a7: PS
++#if XTENSA_HAVE_COPROCESSORS
+ 
+-1:	/* Check if task is coprocessor owner of coprocessor[i]. */
++/*
++ * Macros for lazy context switch. 
++ */
+ 
+-	l32i	a5, a4, COPROCESSOR_INFO_OWNER
+-	srli	a3, a3, 1
+-	beqz	a3, 1f
+-	addi	a4, a4, -8
+-	beq	a2, a5, 1b
++#define SAVE_CP_REGS(x)							\
++	.align 4;							\
++	.Lsave_cp_regs_cp##x:						\
++	.if XTENSA_HAVE_COPROCESSOR(x);					\
++		xchal_cp##x##_store a2 a4 a5 a6 a7;			\
++	.endif;								\
++	jx	a0
+ 
+-	/* Found an entry: Clear entry CPENABLE bit to disable CP. */
++#define SAVE_CP_REGS_TAB(x)						\
++	.if XTENSA_HAVE_COPROCESSOR(x);					\
++		.long .Lsave_cp_regs_cp##x - .Lsave_cp_regs_jump_table;	\
++	.else;								\
++		.long 0;						\
++	.endif;								\
++	.long THREAD_XTREGS_CP##x
+ 
+-	rsr	a5, CPENABLE
+-	s32i	a6, a4, COPROCESSOR_INFO_OWNER
+-	xor	a5, a3, a5
+-	wsr	a5, CPENABLE
+ 
+-	bnez	a3, 1b
++#define LOAD_CP_REGS(x)							\
++	.align 4;							\
++	.Lload_cp_regs_cp##x:						\
++	.if XTENSA_HAVE_COPROCESSOR(x);					\
++		xchal_cp##x##_load a2 a4 a5 a6 a7;			\
++	.endif;								\
++	jx	a0
+ 
+-1:	wsr	a7, PS
+-	rsync
+-	retw
++#define LOAD_CP_REGS_TAB(x)						\
++	.if XTENSA_HAVE_COPROCESSOR(x);					\
++		.long .Lload_cp_regs_cp##x - .Lload_cp_regs_jump_table; \
++	.else;								\
++		.long 0;						\
++	.endif;								\
++	.long THREAD_XTREGS_CP##x
+ 
++	SAVE_CP_REGS(0)
++	SAVE_CP_REGS(1)
++	SAVE_CP_REGS(2)
++	SAVE_CP_REGS(3)
++	SAVE_CP_REGS(4)
++	SAVE_CP_REGS(5)
++	SAVE_CP_REGS(6)
++	SAVE_CP_REGS(7)
+ 
+-ENTRY(disable_coprocessor)
+-	entry	sp, 16
+-	rsil	a7, LOCKLEVEL
+-	rsr	a3, CPENABLE
+-	movi	a4, 1
+-	ssl	a2
+-	sll	a4, a4
+-	and	a4, a3, a4
+-	xor	a3, a3, a4
+-	wsr	a3, CPENABLE
+-	wsr	a7, PS
+-	rsync
+-	retw
++	LOAD_CP_REGS(0)
++	LOAD_CP_REGS(1)
++	LOAD_CP_REGS(2)
++	LOAD_CP_REGS(3)
++	LOAD_CP_REGS(4)
++	LOAD_CP_REGS(5)
++	LOAD_CP_REGS(6)
++	LOAD_CP_REGS(7)
+ 
+-ENTRY(enable_coprocessor)
+-	entry	sp, 16
+-	rsil	a7, LOCKLEVEL
+-	rsr	a3, CPENABLE
+-	movi	a4, 1
+-	ssl	a2
+-	sll	a4, a4
+-	or	a3, a3, a4
+-	wsr	a3, CPENABLE
+-	wsr	a7, PS
+-	rsync
+-	retw
++	.align 4
++.Lsave_cp_regs_jump_table:
++	SAVE_CP_REGS_TAB(0)
++	SAVE_CP_REGS_TAB(1)
++	SAVE_CP_REGS_TAB(2)
++	SAVE_CP_REGS_TAB(3)
++	SAVE_CP_REGS_TAB(4)
++	SAVE_CP_REGS_TAB(5)
++	SAVE_CP_REGS_TAB(6)
++	SAVE_CP_REGS_TAB(7)
+ 
++.Lload_cp_regs_jump_table:
++	LOAD_CP_REGS_TAB(0)
++	LOAD_CP_REGS_TAB(1)
++	LOAD_CP_REGS_TAB(2)
++	LOAD_CP_REGS_TAB(3)
++	LOAD_CP_REGS_TAB(4)
++	LOAD_CP_REGS_TAB(5)
++	LOAD_CP_REGS_TAB(6)
++	LOAD_CP_REGS_TAB(7)
+ 
+-ENTRY(save_coprocessor_extra)
+-	entry	sp, 16
+-	xchal_extra_store_funcbody
+-	retw
++/*
++ * coprocessor_save(buffer, index) 
++ *                    a2      a3
++ * coprocessor_load(buffer, index)
++ *                    a2      a3
++ *
++ * Save or load coprocessor registers for coprocessor 'index'. 
++ * The register values are saved to or loaded from them 'buffer' address.
++ *
++ * Note that these functions don't update the coprocessor_owner information!
++ *
++ */
+ 
+-ENTRY(restore_coprocessor_extra)
+-	entry	sp, 16
+-	xchal_extra_load_funcbody
++ENTRY(coprocessor_save)
++	entry	a1, 32
++	s32i	a0, a1, 0
++	movi	a0, .Lsave_cp_regs_jump_table
++	addx8	a3, a3, a0
++	l32i	a3, a3, 0
++	beqz	a3, 1f
++	add	a0, a0, a3
++	callx0	a0
++1:	l32i	a0, a1, 0
+ 	retw
+ 
+-ENTRY(save_coprocessor_registers)
+-	entry	sp, 16
+-	xchal_cpi_store_funcbody
++ENTRY(coprocessor_load)
++	entry	a1, 32
++	s32i	a0, a1, 0
++	movi	a0, .Lload_cp_regs_jump_table
++	addx4	a3, a3, a0
++	l32i	a3, a3, 0
++	beqz	a3, 1f
++	add	a0, a0, a3
++	callx0	a0
++1:	l32i	a0, a1, 0
+ 	retw
+ 
+-ENTRY(restore_coprocessor_registers)
+-	entry	sp, 16
+-	xchal_cpi_load_funcbody
++/*
++ * coprocessor_flush(struct task_info*, index) 
++ *                             a2        a3
++ * coprocessor_restore(struct task_info*, index)
++ *                              a2         a3
++ *
++ * Save or load coprocessor registers for coprocessor 'index'. 
++ * The register values are saved to or loaded from the coprocessor area 
++ * inside the task_info structure.
++ *
++ * Note that these functions don't update the coprocessor_owner information!
++ *
++ */
++
++
++ENTRY(coprocessor_flush)
++	entry	a1, 32
++	s32i	a0, a1, 0
++	movi	a0, .Lsave_cp_regs_jump_table
++	addx8	a3, a3, a0
++	l32i	a4, a3, 4
++	l32i	a3, a3, 0
++	add	a2, a2, a4
++	beqz	a3, 1f
++	add	a0, a0, a3
++	callx0	a0
++1:	l32i	a0, a1, 0
+ 	retw
+ 
++ENTRY(coprocessor_restore)
++	entry	a1, 32
++	s32i	a0, a1, 0
++	movi	a0, .Lload_cp_regs_jump_table
++	addx4	a3, a3, a0
++	l32i	a4, a3, 4
++	l32i	a3, a3, 0
++	add	a2, a2, a4
++	beqz	a3, 1f
++	add	a0, a0, a3
++	callx0	a0
++1:	l32i	a0, a1, 0
++	retw
+ 
+ /*
+- *  The Xtensa compile-time HAL (core.h) XCHAL_*_SA_CONTENTS_LIBDB macros
+- *  describe the contents of coprocessor & extra save areas in terms of
+- *  undefined CONTENTS_LIBDB_{SREG,UREG,REGF} macros.  We define these
+- *  latter macros here; they expand into a table of the format we want.
+- *  The general format is:
++ * Entry condition:
+  *
+- *	CONTENTS_LIBDB_SREG(libdbnum, offset, size, align, rsv1, name, sregnum,
+- *			    bitmask, rsv2, rsv3)
+- *	CONTENTS_LIBDB_UREG(libdbnum, offset, size, align, rsv1, name, uregnum,
+- *			    bitmask, rsv2, rsv3)
+- *	CONTENTS_LIBDB_REGF(libdbnum, offset, size, align, rsv1, name, index,
+- *			    numentries, contentsize, regname_base,
+- *			    regfile_name, rsv2, rsv3)
++ *   a0:	trashed, original value saved on stack (PT_AREG0)
++ *   a1:	a1
++ *   a2:	new stack pointer, original in DEPC
++ *   a3:	dispatch table
++ *   depc:	a2, original value saved on stack (PT_DEPC)
++ *   excsave_1:	a3
+  *
+- *  For this table, we only care about the <libdbnum>, <offset> and <size>
+- *  fields.
++ *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
++ *	     <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
+  */
+ 
+-/*  Map all XCHAL CONTENTS macros to the reg_entry asm macro defined below:  */
+-
+-#define CONTENTS_LIBDB_SREG(libdbnum,offset,size,align,rsv1,name,sregnum,     \
+-			    bitmask, rsv2, rsv3)			      \
+-		reg_entry libdbnum, offset, size ;
+-#define CONTENTS_LIBDB_UREG(libdbnum,offset,size,align,rsv1,name,uregnum,     \
+-			    bitmask, rsv2, rsv3)			      \
+-		reg_entry libdbnum, offset, size ;
+-#define CONTENTS_LIBDB_REGF(libdbnum, offset, size, align, rsv1, name, index, \
+-			    numentries, contentsize, regname_base,	      \
+-			    regfile_name, rsv2, rsv3)			      \
+-		reg_entry libdbnum, offset, size ;
+-
+-/* A single table entry: */
+-	.macro	reg_entry	libdbnum, offset, size
+-	 .ifne	(__last_offset-(__last_group_offset+\offset))
+-	  /* padding entry */
+-	  .word	(0xFC000000+__last_offset-(__last_group_offset+\offset))
+-	 .endif
+-	 .word	\libdbnum				/* actual entry */
+-	 .set	__last_offset, __last_group_offset+\offset+\size
+-	.endm	/* reg_entry */
+-
+-
+-/* Table entry that marks the beginning of a group (coprocessor or "extra"): */
+-	.macro	reg_group	cpnum, num_entries, align
+-	 .set	__last_group_offset, (__last_offset + \align- 1) & -\align
+-	 .ifne	\num_entries
+-	  .word	0xFD000000+(\cpnum<<16)+\num_entries
+-	 .endif
+-	.endm	/* reg_group */
++ENTRY(fast_coprocessor_double)
++	wsr	a0, EXCSAVE_1
++	movi	a0, unrecoverable_exception
++	callx0	a0
+ 
+-/*
+- * Register info tables.
+- */
+ 
+-	.section .rodata, "a"
+-	.globl	_xtensa_reginfo_tables
+-	.globl	_xtensa_reginfo_table_size
+-	.align	4
+-_xtensa_reginfo_table_size:
+-	.word	_xtensa_reginfo_table_end - _xtensa_reginfo_tables
+-
+-_xtensa_reginfo_tables:
+-	.set	__last_offset, 0
+-	reg_group 0xFF, XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM, XCHAL_EXTRA_SA_ALIGN
+-	XCHAL_EXTRA_SA_CONTENTS_LIBDB
+-	reg_group 0, XCHAL_CP0_SA_CONTENTS_LIBDB_NUM, XCHAL_CP0_SA_ALIGN
+-	XCHAL_CP0_SA_CONTENTS_LIBDB
+-	reg_group 1, XCHAL_CP1_SA_CONTENTS_LIBDB_NUM, XCHAL_CP1_SA_ALIGN
+-	XCHAL_CP1_SA_CONTENTS_LIBDB
+-	reg_group 2, XCHAL_CP2_SA_CONTENTS_LIBDB_NUM, XCHAL_CP2_SA_ALIGN
+-	XCHAL_CP2_SA_CONTENTS_LIBDB
+-	reg_group 3, XCHAL_CP3_SA_CONTENTS_LIBDB_NUM, XCHAL_CP3_SA_ALIGN
+-	XCHAL_CP3_SA_CONTENTS_LIBDB
+-	reg_group 4, XCHAL_CP4_SA_CONTENTS_LIBDB_NUM, XCHAL_CP4_SA_ALIGN
+-	XCHAL_CP4_SA_CONTENTS_LIBDB
+-	reg_group 5, XCHAL_CP5_SA_CONTENTS_LIBDB_NUM, XCHAL_CP5_SA_ALIGN
+-	XCHAL_CP5_SA_CONTENTS_LIBDB
+-	reg_group 6, XCHAL_CP6_SA_CONTENTS_LIBDB_NUM, XCHAL_CP6_SA_ALIGN
+-	XCHAL_CP6_SA_CONTENTS_LIBDB
+-	reg_group 7, XCHAL_CP7_SA_CONTENTS_LIBDB_NUM, XCHAL_CP7_SA_ALIGN
+-	XCHAL_CP7_SA_CONTENTS_LIBDB
+-	.word	0xFC000000	/* invalid register number,marks end of table*/
+-_xtensa_reginfo_table_end:
+-#endif
++ENTRY(fast_coprocessor)
++
++	/* Save remaining registers a1-a3 and SAR */
++
++	xsr	a3, EXCSAVE_1
++	s32i	a3, a2, PT_AREG3
++	rsr	a3, SAR
++	s32i	a1, a2, PT_AREG1
++	s32i	a3, a2, PT_SAR
++	mov	a1, a2
++	rsr	a2, DEPC
++	s32i	a2, a1, PT_AREG2
++
++	/*
++	 * The hal macros require up to 4 temporary registers. We use a3..a6.
++	 */
++
++	s32i	a4, a1, PT_AREG4
++	s32i	a5, a1, PT_AREG5
++	s32i	a6, a1, PT_AREG6
++
++	/* Find coprocessor number. Subtract first CP EXCCAUSE from EXCCAUSE */
++
++	rsr	a3, EXCCAUSE
++	addi	a3, a3, -EXCCAUSE_COPROCESSOR0_DISABLED
++
++	/* Set corresponding CPENABLE bit -> (sar:cp-index, a3: 1<<cp-index)*/
++
++	ssl	a3			# SAR: 32 - coprocessor_number
++	movi	a2, 1
++	rsr	a0, CPENABLE
++	sll	a2, a2
++	or	a0, a0, a2
++	wsr	a0, CPENABLE
++	rsync
++
++	/* Retrieve previous owner. (a3 still holds CP number) */
++
++	movi	a0, coprocessor_owner	# list of owners
++	addx4	a0, a3, a0		# entry for CP
++	l32i	a4, a0, 0
++
++	beqz	a4, 1f			# skip 'save' if no previous owner
++
++	/* Disable coprocessor for previous owner. (a2 = 1 << CP number) */
++
++	l32i	a5, a4, THREAD_CPENABLE
++	xor	a5, a5, a2		# (1 << cp-id) still in a2
++	s32i	a5, a4, THREAD_CPENABLE
++
++	/*
++	 * Get context save area and 'call' save routine. 
++	 * (a4 still holds previous owner (thread_info), a3 CP number)
++	 */
++
++	movi	a5, .Lsave_cp_regs_jump_table
++	movi	a0, 2f			# a0: 'return' address
++	addx8	a3, a3, a5		# a3: coprocessor number
++	l32i	a2, a3, 4		# a2: xtregs offset
++	l32i	a3, a3, 0		# a3: jump offset
++	add	a2, a2, a4
++	add	a4, a3, a5		# a4: address of save routine
++	jx	a4
++
++	/* Note that only a0 and a1 were preserved. */
++
++2:	rsr	a3, EXCCAUSE
++	addi	a3, a3, -EXCCAUSE_COPROCESSOR0_DISABLED
++	movi	a0, coprocessor_owner
++	addx4	a0, a3, a0
++
++	/* Set new 'owner' (a0 points to the CP owner, a3 contains the CP nr) */
++
++1:	GET_THREAD_INFO (a4, a1)
++	s32i	a4, a0, 0
++
++	/* Get context save area and 'call' load routine. */
++
++	movi	a5, .Lload_cp_regs_jump_table
++	movi	a0, 1f
++	addx8	a3, a3, a5
++	l32i	a2, a3, 4		# a2: xtregs offset
++	l32i	a3, a3, 0		# a3: jump offset
++	add	a2, a2, a4
++	add	a4, a3, a5
++	jx	a4
++
++	/* Restore all registers and return from exception handler. */
++
++1:	l32i	a6, a1, PT_AREG6
++	l32i	a5, a1, PT_AREG5
++	l32i	a4, a1, PT_AREG4
++
++	l32i	a0, a1, PT_SAR
++	l32i	a3, a1, PT_AREG3
++	l32i	a2, a1, PT_AREG2
++	wsr	a0, SAR
++	l32i	a0, a1, PT_AREG0
++	l32i	a1, a1, PT_AREG1
++
++	rfe
++
++	.data
++ENTRY(coprocessor_owner)
++	.fill XCHAL_CP_MAX, 4, 0
++
++#endif /* XTENSA_HAVE_COPROCESSORS */
+ 
+diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
+index 91a689e..dfd35dc 100644
+--- a/arch/xtensa/kernel/entry.S
++++ b/arch/xtensa/kernel/entry.S
+@@ -25,10 +25,10 @@
+ #include <asm/page.h>
+ #include <asm/signal.h>
+ #include <asm/tlbflush.h>
++#include <asm/variant/tie-asm.h>
+ 
+ /* Unimplemented features. */
+ 
+-#undef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
+ #undef KERNEL_STACK_OVERFLOW_CHECK
+ #undef PREEMPTIBLE_KERNEL
+ #undef ALLOCA_EXCEPTION_IN_IRAM
+@@ -214,19 +214,7 @@ _user_exception:
+ 
+ 	/* We are back to the original stack pointer (a1) */
+ 
+-2:
+-#if XCHAL_EXTRA_SA_SIZE
+-
+-	/* For user exceptions, save the extra state into the user's TCB.
+-	 * Note: We must assume that xchal_extra_store_funcbody destroys a2..a15
+-	 */
+-
+-	GET_CURRENT(a2,a1)
+-	addi	a2, a2, THREAD_CP_SAVE
+-	xchal_extra_store_funcbody
+-#endif
+-
+-	/* Now, jump to the common exception handler. */
++2:	/* Now, jump to the common exception handler. */
+ 
+ 	j	common_exception
+ 
+@@ -382,6 +370,10 @@ common_exception:
+ 	s32i	a2, a1, PT_LBEG
+ 	s32i	a3, a1, PT_LEND
+ 
++	/* Save optional registers. */
++
++	save_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT
++	
+ 	/* Go to second-level dispatcher. Set up parameters to pass to the
+ 	 * exception handler and call the exception handler.
+ 	 */
+@@ -403,74 +395,49 @@ common_exception_return:
+ 	/* Jump if we are returning from kernel exceptions. */
+ 
+ 1:	l32i	a3, a1, PT_PS
+-	_bbsi.l	a3, PS_UM_BIT, 2f
+-	j	kernel_exception_exit
++	_bbci.l	a3, PS_UM_BIT, 4f
+ 
+ 	/* Specific to a user exception exit:
+ 	 * We need to check some flags for signal handling and rescheduling,
+ 	 * and have to restore WB and WS, extra states, and all registers
+ 	 * in the register file that were in use in the user task.
+-	 */
+-
+-2:	wsr	a3, PS		/* disable interrupts */
+-
+-	/* Check for signals (keep interrupts disabled while we read TI_FLAGS)
+-	 * Note: PS.INTLEVEL = 0, PS.EXCM = 1
++	 * Note that we don't disable interrupts here. 
+ 	 */
+ 
+ 	GET_THREAD_INFO(a2,a1)
+ 	l32i	a4, a2, TI_FLAGS
+ 
+-	/* Enable interrupts again.
+-	 * Note: When we get here, we certainly have handled any interrupts.
+-	 *       (Hint: There is only one user exception frame on stack)
+-	 */
+-
+-	movi	a3, 1 << PS_WOE_BIT
+-
+ 	_bbsi.l	a4, TIF_NEED_RESCHED, 3f
+ 	_bbci.l	a4, TIF_SIGPENDING, 4f
+ 
+-#ifndef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
+ 	l32i	a4, a1, PT_DEPC
+ 	bgeui	a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f
+-#endif
+ 
+-	/* Reenable interrupts and call do_signal() */
++	/* Call do_signal() */
+ 
+-	wsr	a3, PS
+ 	movi	a4, do_signal	# int do_signal(struct pt_regs*, sigset_t*)
+ 	mov	a6, a1
+ 	movi	a7, 0
+ 	callx4	a4
+ 	j	1b
+ 
+-3:	/* Reenable interrupts and reschedule */
++3:	/* Reschedule */
+ 
+-	wsr	a3, PS
+ 	movi	a4, schedule	# void schedule (void)
+ 	callx4	a4
+ 	j	1b
+ 
+-	/* Restore the state of the task and return from the exception. */
+-
+-4:	/* a2 holds GET_CURRENT(a2,a1)  */
+-
+-#if XCHAL_EXTRA_SA_SIZE
++4:	/* Restore optional registers. */
+ 
+-	/* For user exceptions, restore the extra state from the user's TCB. */
++	load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT
+ 
+-	/* Note: a2 still contains GET_CURRENT(a2,a1) */
+-	addi	a2, a2, THREAD_CP_SAVE
+-	xchal_extra_load_funcbody
++	wsr	a3, PS		/* disable interrupts */
+ 
+-	/* We must assume that xchal_extra_store_funcbody destroys
+-	 * registers a2..a15.  FIXME, this list can eventually be
+-	 * reduced once real register requirements of the macro are
+-	 * finalized. */
++	_bbci.l	a3, PS_UM_BIT, kernel_exception_exit
+ 
+-#endif /* XCHAL_EXTRA_SA_SIZE */
++user_exception_exit:
+ 
++	/* Restore the state of the task and return from the exception. */
+ 
+ 	/* Switch to the user thread WINDOWBASE. Save SP temporarily in DEPC */
+ 
+@@ -536,10 +503,6 @@ common_exception_return:
+ 
+ kernel_exception_exit:
+ 
+-	/* Disable interrupts (a3 holds PT_PS) */
+-
+-	wsr	a3, PS
+-
+ #ifdef PREEMPTIBLE_KERNEL
+ 
+ #ifdef CONFIG_PREEMPT
+@@ -618,6 +581,8 @@ kernel_exception_exit:
+ 
+ common_exception_exit:
+ 
++	/* Restore address registers. */
++
+ 	_bbsi.l	a2, 1, 1f
+ 	l32i	a4,  a1, PT_AREG4
+ 	l32i	a5,  a1, PT_AREG5
+@@ -1150,7 +1115,6 @@ CATCH
+  *   excsave_1:	a3
+  *
+  * Note: We assume the stack pointer is EXC_TABLE_KSTK in the fixup handler.
+- * Note: We don't need to save a2 in depc (return value)
+  */
+ 
+ ENTRY(fast_syscall_spill_registers)
+@@ -1166,29 +1130,31 @@ ENTRY(fast_syscall_spill_registers)
+ 
+ 	rsr	a0, SAR
+ 	xsr	a3, EXCSAVE_1		# restore a3 and excsave_1
+-	s32i	a0, a2, PT_AREG4	# store SAR to PT_AREG4
+ 	s32i	a3, a2, PT_AREG3
++	s32i	a4, a2, PT_AREG4
++	s32i	a0, a2, PT_AREG5	# store SAR to PT_AREG5
+ 
+ 	/* The spill routine might clobber a7, a11, and a15. */
+ 
+-	s32i	a7, a2, PT_AREG5
+-	s32i	a11, a2, PT_AREG6
+-	s32i	a15, a2, PT_AREG7
++	s32i	a7, a2, PT_AREG7
++	s32i	a11, a2, PT_AREG11
++	s32i	a15, a2, PT_AREG15
+ 
+-	call0	_spill_registers	# destroys a3, DEPC, and SAR
++	call0	_spill_registers	# destroys a3, a4, and SAR
+ 
+ 	/* Advance PC, restore registers and SAR, and return from exception. */
+ 
+-	l32i	a3, a2, PT_AREG4
++	l32i	a3, a2, PT_AREG5
++	l32i	a4, a2, PT_AREG4
+ 	l32i	a0, a2, PT_AREG0
+ 	wsr	a3, SAR
+ 	l32i	a3, a2, PT_AREG3
+ 
+ 	/* Restore clobbered registers. */
+ 
+-	l32i	a7, a2, PT_AREG5
+-	l32i	a11, a2, PT_AREG6
+-	l32i	a15, a2, PT_AREG7
++	l32i	a7, a2, PT_AREG7
++	l32i	a11, a2, PT_AREG11
++	l32i	a15, a2, PT_AREG15
+ 
+ 	movi	a2, 0
+ 	rfe
+@@ -1247,16 +1213,6 @@ fast_syscall_spill_registers_fixup:
+ 	 * Note: This frame might be the same as above.
+ 	 */
+ 
+-#ifdef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
+-	/* Restore registers we precautiously saved.
+-	 * We have the value of the 'right' a3
+-	 */
+-
+-	l32i	a7, a2, PT_AREG5
+-	l32i	a11, a2, PT_AREG6
+-	l32i	a15, a2, PT_AREG7
+-#endif
+-
+ 	/* Setup stack pointer. */
+ 
+ 	addi	a2, a2, -PT_USER_SIZE
+@@ -1271,9 +1227,9 @@ fast_syscall_spill_registers_fixup:
+ 
+ 	movi	a3, exc_table
+ 	rsr	a0, EXCCAUSE
+-        addx4   a0, a0, a3              	# find entry in table
+-        l32i    a0, a0, EXC_TABLE_FAST_USER     # load handler
+-        jx      a0
++        addx4	a0, a0, a3              	# find entry in table
++        l32i	a0, a0, EXC_TABLE_FAST_USER     # load handler
++        jx	a0
+ 
+ fast_syscall_spill_registers_fixup_return:
+ 
+@@ -1290,14 +1246,6 @@ fast_syscall_spill_registers_fixup_return:
+ 	s32i	a2, a3, EXC_TABLE_PARAM
+ 	l32i	a2, a3, EXC_TABLE_KSTK
+ 
+-#ifdef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
+-	/* Save registers again that might be clobbered. */
+-
+-	s32i	a7, a2, PT_AREG5
+-	s32i	a11, a2, PT_AREG6
+-	s32i	a15, a2, PT_AREG7
+-#endif
+-
+ 	/* Load WB at the time the exception occurred. */
+ 
+ 	rsr	a3, SAR			# WB is still in SAR
+@@ -1319,7 +1267,7 @@ fast_syscall_spill_registers_fixup_return:
+  * This is not a real function. The following conditions must be met:
+  *
+  *  - must be called with call0.
+- *  - uses DEPC, a3 and SAR.
++ *  - uses a3, a4 and SAR.
+  *  - the last 'valid' register of each frame are clobbered.
+  *  - the caller must have registered a fixup handler
+  *    (or be inside a critical section)
+@@ -1331,41 +1279,39 @@ ENTRY(_spill_registers)
+ 	/*
+ 	 * Rotate ws so that the current windowbase is at bit 0.
+ 	 * Assume ws = xxxwww1yy (www1 current window frame).
+-	 * Rotate ws right so that a2 = yyxxxwww1.
++	 * Rotate ws right so that a4 = yyxxxwww1.
+ 	 */
+ 
+-	wsr	a2, DEPC		# preserve a2
+-	rsr	a2, WINDOWBASE
+-	rsr	a3, WINDOWSTART
+-	ssr	a2			# holds WB
+-	slli	a2, a3, WSBITS
+-	or	a3, a3, a2		# a2 = xxxwww1yyxxxwww1yy
+-	srl	a3, a3
++	rsr	a4, WINDOWBASE
++	rsr	a3, WINDOWSTART		# a3 = xxxwww1yy
++	ssr	a4			# holds WB
++	slli	a4, a3, WSBITS
++	or	a3, a3, a4		# a3 = xxxwww1yyxxxwww1yy
++	srl	a3, a3			# a3 = 00xxxwww1yyxxxwww1
+ 
+ 	/* We are done if there are no more than the current register frame. */
+ 
+-	extui	a3, a3, 1, WSBITS-2	# a3 = 0yyxxxwww
+-	movi	a2, (1 << (WSBITS-1))
++	extui	a3, a3, 1, WSBITS-1	# a3 = 0yyxxxwww
++	movi	a4, (1 << (WSBITS-1))
+ 	_beqz	a3, .Lnospill		# only one active frame? jump
+ 
+ 	/* We want 1 at the top, so that we return to the current windowbase */
+ 
+-	or	a3, a3, a2		# 1yyxxxwww
++	or	a3, a3, a4		# 1yyxxxwww
+ 
+ 	/* Skip empty frames - get 'oldest' WINDOWSTART-bit. */
+ 
+ 	wsr	a3, WINDOWSTART		# save shifted windowstart
+-	neg	a2, a3
+-	and	a3, a2, a3		# first bit set from right: 000010000
++	neg	a4, a3
++	and	a3, a4, a3		# first bit set from right: 000010000
+ 
+-	ffs_ws	a2, a3			# a2: shifts to skip empty frames
++	ffs_ws	a4, a3			# a4: shifts to skip empty frames
+ 	movi	a3, WSBITS
+-	sub	a2, a3, a2		# WSBITS-a2:number of 0-bits from right
+-	ssr	a2			# save in SAR for later.
++	sub	a4, a3, a4		# WSBITS-a4:number of 0-bits from right
++	ssr	a4			# save in SAR for later.
+ 
+ 	rsr	a3, WINDOWBASE
+-	add	a3, a3, a2
+-	rsr	a2, DEPC		# restore a2
++	add	a3, a3, a4
+ 	wsr	a3, WINDOWBASE
+ 	rsync
+ 
+@@ -1394,6 +1340,9 @@ ENTRY(_spill_registers)
+ 	l32e	a4, a1, -16
+ 	j	.Lc12c
+ 
++.Lnospill:
++	ret
++
+ .Lloop: _bbsi.l	a3, 1, .Lc4
+ 	_bbci.l	a3, 2, .Lc12
+ 
+@@ -1419,9 +1368,7 @@ ENTRY(_spill_registers)
+ 	movi	a3, 1
+ 	sll	a3, a3
+ 	wsr	a3, WINDOWSTART
+-
+-.Lnospill:
+-	jx	a0
++	ret
+ 
+ .Lc4:	s32e	a4, a9, -16
+ 	s32e	a5, a9, -12
+@@ -1830,154 +1777,6 @@ ENTRY(fast_store_prohibited)
+ 1:	j	_user_exception
+ 
+ 
+-#if XCHAL_EXTRA_SA_SIZE
+-
+-#warning fast_coprocessor untested
+-
+-/*
+- * Entry condition:
+- *
+- *   a0:	trashed, original value saved on stack (PT_AREG0)
+- *   a1:	a1
+- *   a2:	new stack pointer, original in DEPC
+- *   a3:	dispatch table
+- *   depc:	a2, original value saved on stack (PT_DEPC)
+- *   excsave_1:	a3
+- *
+- *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
+- *	     <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
+- */
+-
+-ENTRY(fast_coprocessor_double)
+-	wsr	a0, EXCSAVE_1
+-	movi	a0, unrecoverable_exception
+-	callx0	a0
+-
+-ENTRY(fast_coprocessor)
+-
+-	/* Fatal if we are in a double exception. */
+-
+-	l32i	a0, a2, PT_DEPC
+-	_bgeui	a0, VALID_DOUBLE_EXCEPTION_ADDRESS, fast_coprocessor_double
+-
+-	/* Save some registers a1, a3, a4, SAR */
+-
+-	xsr	a3, EXCSAVE_1
+-	s32i	a3, a2, PT_AREG3
+-	rsr	a3, SAR
+-	s32i	a4, a2, PT_AREG4
+-	s32i	a1, a2, PT_AREG1
+-	s32i	a5, a1, PT_AREG5
+-	s32i	a3, a2, PT_SAR
+-	mov	a1, a2
+-
+-	/* Currently, the HAL macros only guarantee saving a0 and a1.
+-	 * These can and will be refined in the future, but for now,
+-	 * just save the remaining registers of a2...a15.
+-	 */
+-	s32i	a6, a1, PT_AREG6
+-	s32i	a7, a1, PT_AREG7
+-	s32i	a8, a1, PT_AREG8
+-	s32i	a9, a1, PT_AREG9
+-	s32i	a10, a1, PT_AREG10
+-	s32i	a11, a1, PT_AREG11
+-	s32i	a12, a1, PT_AREG12
+-	s32i	a13, a1, PT_AREG13
+-	s32i	a14, a1, PT_AREG14
+-	s32i	a15, a1, PT_AREG15
+-
+-	/* Find coprocessor number. Subtract first CP EXCCAUSE from EXCCAUSE */
+-
+-	rsr	a0, EXCCAUSE
+-	addi	a3, a0, -XCHAL_EXCCAUSE_COPROCESSOR0_DISABLED
+-
+-	/* Set corresponding CPENABLE bit */
+-
+-	movi	a4, 1
+-	ssl	a3			# SAR: 32 - coprocessor_number
+-	rsr	a5, CPENABLE
+-	sll	a4, a4
+-	or	a4, a5, a4
+-	wsr	a4, CPENABLE
+-	rsync
+-	movi	a5, coprocessor_info	# list of owner and offset into cp_save
+-	addx8	a0, a4, a5		# entry for CP
+-
+-	bne	a4, a5, .Lload		# bit wasn't set before, cp not in use
+-
+-	/* Now compare the current task with the owner of the coprocessor.
+-	 * If they are the same, there is no reason to save or restore any
+-	 * coprocessor state. Having already enabled the coprocessor,
+-	 * branch ahead to return.
+-	 */
+-	GET_CURRENT(a5,a1)
+-	l32i	a4, a0, COPROCESSOR_INFO_OWNER	# a4: current owner for this CP
+-	beq	a4, a5, .Ldone
+-
+-	/* Find location to dump current coprocessor state:
+-	 *  task_struct->task_cp_save_offset + coprocessor_offset[coprocessor]
+-	 *
+-	 * Note: a0 pointer to the entry in the coprocessor owner table,
+-	 *	 a3 coprocessor number,
+-         *	 a4 current owner of coprocessor.
+-	 */
+-	l32i	a5, a0, COPROCESSOR_INFO_OFFSET
+-	addi	a2, a4, THREAD_CP_SAVE
+-	add	a2, a2, a5
+-
+-	/* Store current coprocessor states. (a5 still has CP number) */
+-
+-	xchal_cpi_store_funcbody
+-
+-	/* The macro might have destroyed a3 (coprocessor number), but
+-	 * SAR still has 32 - coprocessor_number!
+-	 */
+-	movi	a3, 32
+-	rsr	a4, SAR
+-	sub	a3, a3, a4
+-
+-.Lload:	/* A new task now owns the corpocessors. Save its TCB pointer into
+-	 * the coprocessor owner table.
+-	 *
+-	 * Note: a0 pointer to the entry in the coprocessor owner table,
+-	 *	 a3 coprocessor number.
+-	 */
+-	GET_CURRENT(a4,a1)
+-	s32i	a4, a0, 0
+-
+-	/* Find location from where to restore the current coprocessor state.*/
+-
+-	l32i	a5, a0, COPROCESSOR_INFO_OFFSET
+-	addi	a2, a4, THREAD_CP_SAVE
+-	add	a2, a2, a4
+-
+-	xchal_cpi_load_funcbody
+-
+-	/* We must assume that the xchal_cpi_store_funcbody macro destroyed
+-	 * registers a2..a15.
+-	 */
+-
+-.Ldone:	l32i	a15, a1, PT_AREG15
+-	l32i	a14, a1, PT_AREG14
+-	l32i	a13, a1, PT_AREG13
+-	l32i	a12, a1, PT_AREG12
+-	l32i	a11, a1, PT_AREG11
+-	l32i	a10, a1, PT_AREG10
+-	l32i	a9, a1, PT_AREG9
+-	l32i	a8, a1, PT_AREG8
+-	l32i	a7, a1, PT_AREG7
+-	l32i	a6, a1, PT_AREG6
+-	l32i	a5, a1, PT_AREG5
+-	l32i	a4, a1, PT_AREG4
+-	l32i	a3, a1, PT_AREG3
+-	l32i	a2, a1, PT_AREG2
+-	l32i	a0, a1, PT_AREG0
+-	l32i	a1, a1, PT_AREG1
+-
+-	rfe
+-
+-#endif /* XCHAL_EXTRA_SA_SIZE */
+-
+ /*
+  * System Calls.
+  *
+@@ -2086,20 +1885,36 @@ ENTRY(_switch_to)
+ 
+ 	entry	a1, 16
+ 
+-	mov	a4, a3			# preserve a3
++	mov	a12, a2			# preserve 'prev' (a2)
++	mov	a13, a3			# and 'next' (a3)
++
++	l32i	a4, a2, TASK_THREAD_INFO
++	l32i	a5, a3, TASK_THREAD_INFO
++
++	save_xtregs_user a4 a6 a8 a9 a10 a11 THREAD_XTREGS_USER
+ 
+-	s32i	a0, a2, THREAD_RA	# save return address
+-	s32i	a1, a2, THREAD_SP	# save stack pointer
++	s32i	a0, a12, THREAD_RA	# save return address
++	s32i	a1, a12, THREAD_SP	# save stack pointer
+ 
+-	/* Disable ints while we manipulate the stack pointer; spill regs. */
++	/* Disable ints while we manipulate the stack pointer. */
+ 
+-	movi	a5, (1 << PS_EXCM_BIT) | LOCKLEVEL
+-	xsr	a5, PS
++	movi	a14, (1 << PS_EXCM_BIT) | LOCKLEVEL
++	xsr	a14, PS
+ 	rsr	a3, EXCSAVE_1
+ 	rsync
+ 	s32i	a3, a3, EXC_TABLE_FIXUP	/* enter critical section */
+ 
+-	call0	_spill_registers
++	/* Switch CPENABLE */
++
++#if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS)
++	l32i	a3, a5, THREAD_CPENABLE
++	xsr	a3, CPENABLE
++	s32i	a3, a4, THREAD_CPENABLE
++#endif
++
++	/* Flush register file. */
++
++	call0	_spill_registers	# destroys a3, a4, and SAR
+ 
+ 	/* Set kernel stack (and leave critical section)
+ 	 * Note: It's save to set it here. The stack will not be overwritten
+@@ -2107,19 +1922,21 @@ ENTRY(_switch_to)
+ 	 *       we return from kernel space.
+ 	 */
+ 
+-	l32i	a0, a4, TASK_THREAD_INFO
+ 	rsr	a3, EXCSAVE_1		# exc_table
+-	movi	a1, 0
+-	addi	a0, a0, PT_REGS_OFFSET
+-	s32i	a1, a3, EXC_TABLE_FIXUP
+-	s32i	a0, a3, EXC_TABLE_KSTK
++	movi	a6, 0
++	addi	a7, a5, PT_REGS_OFFSET
++	s32i	a6, a3, EXC_TABLE_FIXUP
++	s32i	a7, a3, EXC_TABLE_KSTK
+ 
+ 	/* restore context of the task that 'next' addresses */
+ 
+-	l32i	a0, a4, THREAD_RA	/* restore return address */
+-	l32i	a1, a4, THREAD_SP	/* restore stack pointer */
++	l32i	a0, a13, THREAD_RA	# restore return address
++	l32i	a1, a13, THREAD_SP	# restore stack pointer
++
++	load_xtregs_user a5 a6 a8 a9 a10 a11 THREAD_XTREGS_USER
+ 
+-	wsr	a5, PS
++	wsr	a14, PS
++	mov	a2, a12			# return 'prev'
+ 	rsync
+ 
+ 	retw
+diff --git a/arch/xtensa/kernel/module.c b/arch/xtensa/kernel/module.c
+index ddf14dc..3981a46 100644
+--- a/arch/xtensa/kernel/module.c
++++ b/arch/xtensa/kernel/module.c
+@@ -28,7 +28,7 @@ void *module_alloc(unsigned long size)
+ {
+ 	if (size == 0)
+ 		return NULL;
+-	return vmalloc(size);
++	return vmalloc_exec(size);
+ }
+ 
+ void module_free(struct module *mod, void *module_region)
+diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
+index f53d7bd..9185597 100644
+--- a/arch/xtensa/kernel/process.c
++++ b/arch/xtensa/kernel/process.c
+@@ -52,6 +52,55 @@ void (*pm_power_off)(void) = NULL;
+ EXPORT_SYMBOL(pm_power_off);
+ 
+ 
++#if XTENSA_HAVE_COPROCESSORS
++
++void coprocessor_release_all(struct thread_info *ti)
++{
++	unsigned long cpenable;
++	int i;
++
++	/* Make sure we don't switch tasks during this operation. */
++
++	preempt_disable();
++
++	/* Walk through all cp owners and release it for the requested one. */
++
++	cpenable = ti->cpenable;
++
++	for (i = 0; i < XCHAL_CP_MAX; i++) {
++		if (coprocessor_owner[i] == ti) {
++			coprocessor_owner[i] = 0;
++			cpenable &= ~(1 << i);
++		}
++	}
++
++	ti->cpenable = cpenable;
++	coprocessor_clear_cpenable();
++
++	preempt_enable();
++}
++
++void coprocessor_flush_all(struct thread_info *ti)
++{
++	unsigned long cpenable;
++	int i;
++
++	preempt_disable();
++
++	cpenable = ti->cpenable;
++
++	for (i = 0; i < XCHAL_CP_MAX; i++) {
++		if ((cpenable & 1) != 0 && coprocessor_owner[i] == ti)
++			coprocessor_flush(ti, i);
++		cpenable >>= 1;
++	}
++
++	preempt_enable();
++}
++
++#endif
++
++
+ /*
+  * Powermanagement idle function, if any is provided by the platform.
+  */
+@@ -71,15 +120,36 @@ void cpu_idle(void)
+ }
+ 
+ /*
+- * Free current thread data structures etc..
++ * This is called when the thread calls exit().
+  */
+-
+ void exit_thread(void)
+ {
++#if XTENSA_HAVE_COPROCESSORS
++	coprocessor_release_all(current_thread_info());
++#endif
+ }
+ 
++/*
++ * Flush thread state. This is called when a thread does an execve()
++ * Note that we flush coprocessor registers for the case execve fails.
++ */
+ void flush_thread(void)
+ {
++#if XTENSA_HAVE_COPROCESSORS
++	struct thread_info *ti = current_thread_info();
++	coprocessor_flush_all(ti);
++	coprocessor_release_all(ti);
++#endif
++}
++
++/*
++ * This is called before the thread is copied. 
++ */
++void prepare_to_copy(struct task_struct *tsk)
++{
++#if XTENSA_HAVE_COPROCESSORS
++	coprocessor_flush_all(task_thread_info(tsk));
++#endif
+ }
+ 
+ /*
+@@ -107,6 +177,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+                 struct task_struct * p, struct pt_regs * regs)
+ {
+ 	struct pt_regs *childregs;
++	struct thread_info *ti;
+ 	unsigned long tos;
+ 	int user_mode = user_mode(regs);
+ 
+@@ -128,13 +199,14 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+ 	p->set_child_tid = p->clear_child_tid = NULL;
+ 	p->thread.ra = MAKE_RA_FOR_CALL((unsigned long)ret_from_fork, 0x1);
+ 	p->thread.sp = (unsigned long)childregs;
++
+ 	if (user_mode(regs)) {
+ 
+ 		int len = childregs->wmask & ~0xf;
+ 		childregs->areg[1] = usp;
+ 		memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4],
+ 		       &regs->areg[XCHAL_NUM_AREGS - len/4], len);
+-
++// FIXME: we need to set THREADPTR in thread_info...
+ 		if (clone_flags & CLONE_SETTLS)
+ 			childregs->areg[2] = childregs->areg[6];
+ 
+@@ -142,6 +214,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+ 		/* In kernel space, we start a new thread with a new stack. */
+ 		childregs->wmask = 1;
+ 	}
++
++#if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS)
++	ti = task_thread_info(p);
++	ti->cpenable = 0;
++#endif
++
+ 	return 0;
+ }
+ 
+@@ -179,10 +257,6 @@ unsigned long get_wchan(struct task_struct *p)
+ }
+ 
+ /*
+- * do_copy_regs() gathers information from 'struct pt_regs' and
+- * 'current->thread.areg[]' to fill in the xtensa_gregset_t
+- * structure.
+- *
+  * xtensa_gregset_t and 'struct pt_regs' are vastly different formats
+  * of processor registers.  Besides different ordering,
+  * xtensa_gregset_t contains non-live register information that
+@@ -191,18 +265,19 @@ unsigned long get_wchan(struct task_struct *p)
+  *
+  */
+ 
+-void do_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs,
+-		   struct task_struct *tsk)
++void xtensa_elf_core_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs)
+ {
+-	int i, n, wb_offset;
++	unsigned long wb, ws, wm;
++	int live, last;
+ 
+-	elfregs->xchal_config_id0 = XCHAL_HW_CONFIGID0;
+-	elfregs->xchal_config_id1 = XCHAL_HW_CONFIGID1;
++	wb = regs->windowbase;
++	ws = regs->windowstart;
++	wm = regs->wmask;
++	ws = ((ws >> wb) | (ws << (WSBITS - wb))) & ((1 << WSBITS) - 1);
+ 
+-	__asm__ __volatile__ ("rsr  %0, 176\n" : "=a" (i));
+- 	elfregs->cpux = i;
+-	__asm__ __volatile__ ("rsr  %0, 208\n" : "=a" (i));
+- 	elfregs->cpuy = i;
++	/* Don't leak any random bits. */
++
++	memset(elfregs, 0, sizeof (elfregs));
+ 
+ 	/* Note:  PS.EXCM is not set while user task is running; its
+ 	 * being set in regs->ps is for exception handling convenience.
+@@ -210,204 +285,22 @@ void do_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs,
+ 
+ 	elfregs->pc		= regs->pc;
+ 	elfregs->ps		= (regs->ps & ~(1 << PS_EXCM_BIT));
+-	elfregs->exccause	= regs->exccause;
+-	elfregs->excvaddr	= regs->excvaddr;
+-	elfregs->windowbase	= regs->windowbase;
+-	elfregs->windowstart	= regs->windowstart;
+ 	elfregs->lbeg		= regs->lbeg;
+ 	elfregs->lend		= regs->lend;
+ 	elfregs->lcount		= regs->lcount;
+ 	elfregs->sar		= regs->sar;
+-	elfregs->syscall	= regs->syscall;
+-
+-	/* Copy register file.
+-	 * The layout looks like this:
+-	 *
+-	 * |  a0 ... a15  | Z ... Z |  arX ... arY  |
+-	 *  current window  unused    saved frames
+-	 */
+-
+-	memset (elfregs->ar, 0, sizeof(elfregs->ar));
++	elfregs->windowstart	= ws;
+ 
+-	wb_offset = regs->windowbase * 4;
+-	n = (regs->wmask&1)? 4 : (regs->wmask&2)? 8 : (regs->wmask&4)? 12 : 16;
+-
+-	for (i = 0; i < n; i++)
+-		elfregs->ar[(wb_offset + i) % XCHAL_NUM_AREGS] = regs->areg[i];
+-
+-	n = (regs->wmask >> 4) * 4;
+-
+-	for (i = XCHAL_NUM_AREGS - n; n > 0; i++, n--)
+-		elfregs->ar[(wb_offset + i) % XCHAL_NUM_AREGS] = regs->areg[i];
++	live = (wm & 2) ? 4 : (wm & 4) ? 8 : (wm & 8) ? 12 : 16;
++	last = XCHAL_NUM_AREGS - (wm >> 4) * 4;
++	memcpy(elfregs->a, regs->areg, live * 4);
++	memcpy(elfregs->a + last, regs->areg + last, (wm >> 4) * 16);
+ }
+ 
+-void xtensa_elf_core_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs)
++int dump_fpu(void)
+ {
+-	do_copy_regs ((xtensa_gregset_t *)elfregs, regs, current);
+-}
+-
+-
+-/* The inverse of do_copy_regs().  No error or sanity checking. */
+-
+-void do_restore_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs,
+-		      struct task_struct *tsk)
+-{
+-	int i, n, wb_offset;
+-
+-	/* Note:  PS.EXCM is not set while user task is running; it
+-	 * needs to be set in regs->ps is for exception handling convenience.
+-	 */
+-
+-	regs->pc		= elfregs->pc;
+-	regs->ps		= (elfregs->ps | (1 << PS_EXCM_BIT));
+-	regs->exccause		= elfregs->exccause;
+-	regs->excvaddr		= elfregs->excvaddr;
+-	regs->windowbase	= elfregs->windowbase;
+-	regs->windowstart	= elfregs->windowstart;
+-	regs->lbeg		= elfregs->lbeg;
+-	regs->lend		= elfregs->lend;
+-	regs->lcount		= elfregs->lcount;
+-	regs->sar		= elfregs->sar;
+-	regs->syscall	= elfregs->syscall;
+-
+-	/* Clear everything. */
+-
+-	memset (regs->areg, 0, sizeof(regs->areg));
+-
+-	/* Copy regs from live window frame. */
+-
+-	wb_offset = regs->windowbase * 4;
+-	n = (regs->wmask&1)? 4 : (regs->wmask&2)? 8 : (regs->wmask&4)? 12 : 16;
+-
+-	for (i = 0; i < n; i++)
+-		regs->areg[(wb_offset+i) % XCHAL_NUM_AREGS] = elfregs->ar[i];
+-
+-	n = (regs->wmask >> 4) * 4;
+-
+-	for (i = XCHAL_NUM_AREGS - n; n > 0; i++, n--)
+-		regs->areg[(wb_offset+i) % XCHAL_NUM_AREGS] = elfregs->ar[i];
+-}
+-
+-/*
+- * do_save_fpregs() gathers information from 'struct pt_regs' and
+- * 'current->thread' to fill in the elf_fpregset_t structure.
+- *
+- * Core files and ptrace use elf_fpregset_t.
+- */
+-
+-void do_save_fpregs (elf_fpregset_t *fpregs, struct pt_regs *regs,
+-		     struct task_struct *tsk)
+-{
+-#if XCHAL_HAVE_CP
+-
+-	extern unsigned char	_xtensa_reginfo_tables[];
+-	extern unsigned		_xtensa_reginfo_table_size;
+-	int i;
+-	unsigned long flags;
+-
+-	/* Before dumping coprocessor state from memory,
+-	 * ensure any live coprocessor contents for this
+-	 * task are first saved to memory:
+-	 */
+-	local_irq_save(flags);
+-
+-	for (i = 0; i < XCHAL_CP_MAX; i++) {
+-		if (tsk == coprocessor_info[i].owner) {
+-			enable_coprocessor(i);
+-			save_coprocessor_registers(
+-			    tsk->thread.cp_save+coprocessor_info[i].offset,i);
+-			disable_coprocessor(i);
+-		}
+-	}
+-
+-	local_irq_restore(flags);
+-
+-	/* Now dump coprocessor & extra state: */
+-	memcpy((unsigned char*)fpregs,
+-		_xtensa_reginfo_tables, _xtensa_reginfo_table_size);
+-	memcpy((unsigned char*)fpregs + _xtensa_reginfo_table_size,
+-		tsk->thread.cp_save, XTENSA_CP_EXTRA_SIZE);
+-#endif
+-}
+-
+-/*
+- * The inverse of do_save_fpregs().
+- * Copies coprocessor and extra state from fpregs into regs and tsk->thread.
+- * Returns 0 on success, non-zero if layout doesn't match.
+- */
+-
+-int  do_restore_fpregs (elf_fpregset_t *fpregs, struct pt_regs *regs,
+-		        struct task_struct *tsk)
+-{
+-#if XCHAL_HAVE_CP
+-
+-	extern unsigned char	_xtensa_reginfo_tables[];
+-	extern unsigned		_xtensa_reginfo_table_size;
+-	int i;
+-	unsigned long flags;
+-
+-	/* Make sure save area layouts match.
+-	 * FIXME:  in the future we could allow restoring from
+-	 * a different layout of the same registers, by comparing
+-	 * fpregs' table with _xtensa_reginfo_tables and matching
+-	 * entries and copying registers one at a time.
+-	 * Not too sure yet whether that's very useful.
+-	 */
+-
+-	if( memcmp((unsigned char*)fpregs,
+-		_xtensa_reginfo_tables, _xtensa_reginfo_table_size) ) {
+-	    return -1;
+-	}
+-
+-	/* Before restoring coprocessor state from memory,
+-	 * ensure any live coprocessor contents for this
+-	 * task are first invalidated.
+-	 */
+-
+-	local_irq_save(flags);
+-
+-	for (i = 0; i < XCHAL_CP_MAX; i++) {
+-		if (tsk == coprocessor_info[i].owner) {
+-			enable_coprocessor(i);
+-			save_coprocessor_registers(
+-			    tsk->thread.cp_save+coprocessor_info[i].offset,i);
+-			coprocessor_info[i].owner = 0;
+-			disable_coprocessor(i);
+-		}
+-	}
+-
+-	local_irq_restore(flags);
+-
+-	/*  Now restore coprocessor & extra state:  */
+-
+-	memcpy(tsk->thread.cp_save,
+-		(unsigned char*)fpregs + _xtensa_reginfo_table_size,
+-		XTENSA_CP_EXTRA_SIZE);
+-#endif
+ 	return 0;
+ }
+-/*
+- * Fill in the CP structure for a core dump for a particular task.
+- */
+-
+-int
+-dump_task_fpu(struct pt_regs *regs, struct task_struct *task, elf_fpregset_t *r)
+-{
+-	return 0;	/* no coprocessors active on this processor */
+-}
+-
+-/*
+- * Fill in the CP structure for a core dump.
+- * This includes any FPU coprocessor.
+- * Here, we dump all coprocessors, and other ("extra") custom state.
+- *
+- * This function is called by elf_core_dump() in fs/binfmt_elf.c
+- * (in which case 'regs' comes from calls to do_coredump, see signals.c).
+- */
+-int  dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
+-{
+-	return dump_task_fpu(regs, current, r);
+-}
+ 
+ asmlinkage
+ long xtensa_clone(unsigned long clone_flags, unsigned long newsp,
+@@ -421,8 +314,8 @@ long xtensa_clone(unsigned long clone_flags, unsigned long newsp,
+ }
+ 
+ /*
+- *  * xtensa_execve() executes a new program.
+- *   */
++ * xtensa_execve() executes a new program.
++ */
+ 
+ asmlinkage
+ long xtensa_execve(char __user *name, char __user * __user *argv,
+@@ -437,7 +330,6 @@ long xtensa_execve(char __user *name, char __user * __user *argv,
+ 	error = PTR_ERR(filename);
+ 	if (IS_ERR(filename))
+ 		goto out;
+-	// FIXME: release coprocessor??
+ 	error = do_execve(filename, argv, envp, regs);
+ 	if (error == 0) {
+ 		task_lock(current);
+diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
+index 5533c78..9486882 100644
+--- a/arch/xtensa/kernel/ptrace.c
++++ b/arch/xtensa/kernel/ptrace.c
+@@ -4,7 +4,7 @@
+  * License.  See the file "COPYING" in the main directory of this archive
+  * for more details.
+  *
+- * Copyright (C) 2001 - 2005  Tensilica Inc.
++ * Copyright (C) 2001 - 2007  Tensilica Inc.
+  *
+  * Joe Taylor	<joe at tensilica.com, joetylr at yahoo.com>
+  * Chris Zankel <chris at zankel.net>
+@@ -28,14 +28,10 @@
+ #include <asm/uaccess.h>
+ #include <asm/ptrace.h>
+ #include <asm/elf.h>
+-
+-#define TEST_KERNEL	// verify kernel operations FIXME: remove
+-
++#include <asm/coprocessor.h>
+ 
+ /*
+- * Called by kernel/ptrace.c when detaching..
+- *
+- * Make sure single step bits etc are not set.
++ * Called by kernel/ptrace.c when detaching to disable single stepping.
+  */
+ 
+ void ptrace_disable(struct task_struct *child)
+@@ -43,136 +39,237 @@ void ptrace_disable(struct task_struct *child)
+ 	/* Nothing to do.. */
+ }
+ 
+-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
++int ptrace_getregs(struct task_struct *child, void __user *uregs)
+ {
+-	int ret = -EPERM;
++	struct pt_regs *regs = task_pt_regs(child);
++	xtensa_gregset_t __user *gregset = uregs;
++	unsigned long wm = regs->wmask;
++	unsigned long wb = regs->windowbase;
++	int live, i;
++
++	if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t)))
++		return -EIO;
++
++	__put_user(regs->pc, &gregset->pc);
++	__put_user(regs->ps & ~(1 << PS_EXCM_BIT), &gregset->ps);
++	__put_user(regs->lbeg, &gregset->lbeg);
++	__put_user(regs->lend, &gregset->lend);
++	__put_user(regs->lcount, &gregset->lcount);
++	__put_user(regs->windowstart, &gregset->windowstart);
++	__put_user(regs->windowbase, &gregset->windowbase);
++
++	live = (wm & 2) ? 4 : (wm & 4) ? 8 : (wm & 8) ? 12 : 16;
++
++	for (i = 0; i < live; i++)
++		__put_user(regs->areg[i],gregset->a+((wb*4+i)%XCHAL_NUM_AREGS));
++	for (i = XCHAL_NUM_AREGS - (wm >> 4) * 4; i < XCHAL_NUM_AREGS; i++)
++		__put_user(regs->areg[i],gregset->a+((wb*4+i)%XCHAL_NUM_AREGS));
++
++	return 0;
++}
+ 
+-	switch (request) {
+-	case PTRACE_PEEKTEXT: /* read word at location addr. */
+-	case PTRACE_PEEKDATA:
+-		ret = generic_ptrace_peekdata(child, addr, data);
+-		goto out;
++int ptrace_setregs(struct task_struct *child, void __user *uregs)
++{
++	struct pt_regs *regs = task_pt_regs(child);
++	xtensa_gregset_t *gregset = uregs;
++	const unsigned long ps_mask = PS_CALLINC_MASK | PS_OWB_MASK;
++	unsigned long ps;
++	unsigned long wb;
+ 
+-	/* Read the word at location addr in the USER area.  */
++	if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t)))
++		return -EIO;
+ 
+-	case PTRACE_PEEKUSR:
+-		{
+-		struct pt_regs *regs;
+-		unsigned long tmp;
++	__get_user(regs->pc, &gregset->pc);
++	__get_user(ps, &gregset->ps);
++	__get_user(regs->lbeg, &gregset->lbeg);
++	__get_user(regs->lend, &gregset->lend);
++	__get_user(regs->lcount, &gregset->lcount);
++	__get_user(regs->windowstart, &gregset->windowstart);
++	__get_user(wb, &gregset->windowbase);
++
++	regs->ps = (regs->ps & ~ps_mask) | (ps & ps_mask) | (1 << PS_EXCM_BIT);
++
++	if (wb >= XCHAL_NUM_AREGS / 4)
++		return -EFAULT;
++
++	regs->windowbase = wb;
++
++	if (wb != 0 &&  __copy_from_user(regs->areg + XCHAL_NUM_AREGS - wb * 4,
++					 gregset->a, wb * 16))
++		return -EFAULT;
++
++	if (__copy_from_user(regs->areg, gregset->a + wb*4, (WSBITS-wb) * 16))
++		return -EFAULT;
++
++	return 0;
++}
++
++
++int ptrace_getxregs(struct task_struct *child, void __user *uregs)
++{
++	struct pt_regs *regs = task_pt_regs(child);
++	struct thread_info *ti = task_thread_info(child);
++	elf_xtregs_t __user *xtregs = uregs;
++	int ret = 0;
++
++	if (!access_ok(VERIFY_WRITE, uregs, sizeof(elf_xtregs_t)))
++		return -EIO;
++
++#if XTENSA_HAVE_COPROCESSORS
++	/* Flush all coprocessor registers to memory. */
++	coprocessor_flush_all(ti);
++	ret |= __copy_to_user(&xtregs->cp0, &ti->xtregs_cp,
++			      sizeof(xtregs_coprocessor_t));
++#endif
++	ret |= __copy_to_user(&xtregs->opt, &regs->xtregs_opt,
++			      sizeof(xtregs->opt));
++	ret |= __copy_to_user(&xtregs->user,&ti->xtregs_user,
++			      sizeof(xtregs->user));
++
++	return ret ? -EFAULT : 0;
++}
++
++int ptrace_setxregs(struct task_struct *child, void __user *uregs)
++{
++	struct thread_info *ti = task_thread_info(child);
++	struct pt_regs *regs = task_pt_regs(child);
++	elf_xtregs_t *xtregs = uregs;
++	int ret = 0;
++
++#if XTENSA_HAVE_COPROCESSORS
++	/* Flush all coprocessors before we overwrite them. */
++	coprocessor_flush_all(ti);
++	coprocessor_release_all(ti);
++
++	ret |= __copy_from_user(&ti->xtregs_cp, &xtregs->cp0, 
++				sizeof(xtregs_coprocessor_t));
++#endif
++	ret |= __copy_from_user(&regs->xtregs_opt, &xtregs->opt,
++				sizeof(xtregs->opt));
++	ret |= __copy_from_user(&ti->xtregs_user, &xtregs->user,
++				sizeof(xtregs->user));
++
++	return ret ? -EFAULT : 0;
++}
++
++int ptrace_peekusr(struct task_struct *child, long regno, long __user *ret)
++{
++	struct pt_regs *regs;
++	unsigned long tmp;
+ 
+-		regs = task_pt_regs(child);
+-		tmp = 0;  /* Default return value. */
++	regs = task_pt_regs(child);
++	tmp = 0;  /* Default return value. */
+ 
+-		switch(addr) {
++	switch(regno) {
+ 
+ 		case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1:
+-			{
+-			int ar = addr - REG_AR_BASE - regs->windowbase * 4;
+-			ar &= (XCHAL_NUM_AREGS - 1);
+-			if (ar < 16 && ar + (regs->wmask >> 4) * 4 >= 0)
+-				tmp = regs->areg[ar];
+-			else
+-				ret = -EIO;
++			tmp = regs->areg[regno - REG_AR_BASE];
+ 			break;
+-			}
++
+ 		case REG_A_BASE ... REG_A_BASE + 15:
+-			tmp = regs->areg[addr - REG_A_BASE];
++			tmp = regs->areg[regno - REG_A_BASE];
+ 			break;
++
+ 		case REG_PC:
+ 			tmp = regs->pc;
+ 			break;
++
+ 		case REG_PS:
+ 			/* Note:  PS.EXCM is not set while user task is running;
+ 			 * its being set in regs is for exception handling
+ 			 * convenience.  */
+ 			tmp = (regs->ps & ~(1 << PS_EXCM_BIT));
+ 			break;
++
+ 		case REG_WB:
+-			tmp = regs->windowbase;
+-			break;
++			break;		/* tmp = 0 */
++
+ 		case REG_WS:
+-			tmp = regs->windowstart;
++		{
++			unsigned long wb = regs->windowbase;
++			unsigned long ws = regs->windowstart;
++			tmp = ((ws>>wb) | (ws<<(WSBITS-wb))) & ((1<<WSBITS)-1);
+ 			break;
++		}
+ 		case REG_LBEG:
+ 			tmp = regs->lbeg;
+ 			break;
++
+ 		case REG_LEND:
+ 			tmp = regs->lend;
+ 			break;
++
+ 		case REG_LCOUNT:
+ 			tmp = regs->lcount;
+ 			break;
++
+ 		case REG_SAR:
+ 			tmp = regs->sar;
+ 			break;
+-		case REG_DEPC:
+-			tmp = regs->depc;
+-			break;
+-		case REG_EXCCAUSE:
+-			tmp = regs->exccause;
+-			break;
+-		case REG_EXCVADDR:
+-			tmp = regs->excvaddr;
+-			break;
++
+ 		case SYSCALL_NR:
+ 			tmp = regs->syscall;
+ 			break;
+-		default:
+-			tmp = 0;
+-			ret = -EIO;
+-			goto out;
+-		}
+-		ret = put_user(tmp, (unsigned long *) data);
+-		goto out;
+-		}
+ 
+-	case PTRACE_POKETEXT: /* write the word at location addr. */
+-	case PTRACE_POKEDATA:
+-		ret = generic_ptrace_pokedata(child, addr, data);
+-		goto out;
++		default:
++			return -EIO;
++	}
++	return put_user(tmp, ret);
++}
+ 
+-	case PTRACE_POKEUSR:
+-		{
+-		struct pt_regs *regs;
+-		regs = task_pt_regs(child);
++int ptrace_pokeusr(struct task_struct *child, long regno, long val)
++{
++	struct pt_regs *regs;
++	regs = task_pt_regs(child);
+ 
+-		switch (addr) {
++	switch (regno) {
+ 		case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1:
+-			{
+-			int ar = addr - REG_AR_BASE - regs->windowbase * 4;
+-			if (ar < 16 && ar + (regs->wmask >> 4) * 4 >= 0)
+-				regs->areg[ar & (XCHAL_NUM_AREGS - 1)] = data;
+-			else
+-				ret = -EIO;
++			regs->areg[regno - REG_AR_BASE] = val;
+ 			break;
+-			}
++
+ 		case REG_A_BASE ... REG_A_BASE + 15:
+-			regs->areg[addr - REG_A_BASE] = data;
++			regs->areg[regno - REG_A_BASE] = val;
+ 			break;
++
+ 		case REG_PC:
+-			regs->pc = data;
++			regs->pc = val;
+ 			break;
++
+ 		case SYSCALL_NR:
+-			regs->syscall = data;
+-			break;
+-#ifdef TEST_KERNEL
+-		case REG_WB:
+-			regs->windowbase = data;
+-			break;
+-		case REG_WS:
+-			regs->windowstart = data;
++			regs->syscall = val;
+ 			break;
+-#endif
+ 
+ 		default:
+-			/* The rest are not allowed. */
+-			ret = -EIO;
+-			break;
+-		}
++			return -EIO;
++	}
++	return 0;
++}
++
++long arch_ptrace(struct task_struct *child, long request, long addr, long data)
++{
++	int ret = -EPERM;
++
++	switch (request) {
++	case PTRACE_PEEKTEXT:	/* read word at location addr. */
++	case PTRACE_PEEKDATA:
++		ret = generic_ptrace_peekdata(child, addr, data);
++		break;
++
++	case PTRACE_PEEKUSR:	/* read register specified by addr. */
++		ret = ptrace_peekusr(child, addr, (void __user *) data);
++		break;
++
++	case PTRACE_POKETEXT:	/* write the word at location addr. */
++	case PTRACE_POKEDATA:
++		ret = generic_ptrace_pokedata(child, addr, data);
++		break;
++
++	case PTRACE_POKEUSR:	/* write register specified by addr. */
++		ret = ptrace_pokeusr(child, addr, data);
+ 		break;
+-		}
+ 
+ 	/* continue and stop at next (return from) syscall */
++
+ 	case PTRACE_SYSCALL:
+ 	case PTRACE_CONT: /* restart after signal. */
+ 	{
+@@ -217,98 +314,26 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+ 		break;
+ 
+ 	case PTRACE_GETREGS:
+-	{
+-		/* 'data' points to user memory in which to write.
+-		 * Mainly due to the non-live register values, we
+-		 * reformat the register values into something more
+-		 * standard.  For convenience, we use the handy
+-		 * elf_gregset_t format. */
+-
+-		xtensa_gregset_t format;
+-		struct pt_regs *regs = task_pt_regs(child);
+-
+-		do_copy_regs (&format, regs, child);
+-
+-		/* Now, copy to user space nice and easy... */
+-		ret = 0;
+-		if (copy_to_user((void *)data, &format, sizeof(elf_gregset_t)))
+-			ret = -EFAULT;
++		ret = ptrace_getregs(child, (void __user *) data);
+ 		break;
+-	}
+ 
+ 	case PTRACE_SETREGS:
+-	{
+-		/* 'data' points to user memory that contains the new
+-		 * values in the elf_gregset_t format. */
+-
+-		xtensa_gregset_t format;
+-		struct pt_regs *regs = task_pt_regs(child);
+-
+-		if (copy_from_user(&format,(void *)data,sizeof(elf_gregset_t))){
+-			ret = -EFAULT;
+-			break;
+-		}
+-
+-		/* FIXME: Perhaps we want some sanity checks on
+-		 * these user-space values?  See ARM version.  Are
+-		 * debuggers a security concern? */
+-
+-		do_restore_regs (&format, regs, child);
+-
+-		ret = 0;
+-		break;
+-	}
+-
+-	case PTRACE_GETFPREGS:
+-	{
+-		/* 'data' points to user memory in which to write.
+-		 * For convenience, we use the handy
+-		 * elf_fpregset_t format. */
+-
+-		elf_fpregset_t fpregs;
+-		struct pt_regs *regs = task_pt_regs(child);
+-
+-		do_save_fpregs (&fpregs, regs, child);
+-
+-		/* Now, copy to user space nice and easy... */
+-		ret = 0;
+-		if (copy_to_user((void *)data, &fpregs, sizeof(elf_fpregset_t)))
+-			ret = -EFAULT;
+-
++		ret = ptrace_setregs(child, (void __user *) data);
+ 		break;
+-	}
+-
+-	case PTRACE_SETFPREGS:
+-	{
+-		/* 'data' points to user memory that contains the new
+-		 * values in the elf_fpregset_t format.
+-		 */
+-		elf_fpregset_t fpregs;
+-		struct pt_regs *regs = task_pt_regs(child);
+ 
+-		ret = 0;
+-		if (copy_from_user(&fpregs, (void *)data, sizeof(elf_fpregset_t))) {
+-			ret = -EFAULT;
+-			break;
+-		}
+-
+-		if (do_restore_fpregs (&fpregs, regs, child))
+-			ret = -EIO;
++	case PTRACE_GETXTREGS:
++		ret = ptrace_getxregs(child, (void __user *) data);
+ 		break;
+-	}
+ 
+-	case PTRACE_GETFPREGSIZE:
+-		/* 'data' points to 'unsigned long' set to the size
+-		 * of elf_fpregset_t
+-		 */
+-		ret = put_user(sizeof(elf_fpregset_t), (unsigned long *) data);
++	case PTRACE_SETXTREGS:
++		ret = ptrace_setxregs(child, (void __user *) data);
+ 		break;
+ 
+ 	default:
+ 		ret = ptrace_request(child, request, addr, data);
+-		goto out;
++		break;
+ 	}
+- out:
++
+ 	return ret;
+ }
+ 
+diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
+index b80f2cb..5e6d75c 100644
+--- a/arch/xtensa/kernel/setup.c
++++ b/arch/xtensa/kernel/setup.c
+@@ -60,11 +60,6 @@ struct ide_ops *ide_ops;
+ extern struct rtc_ops no_rtc_ops;
+ struct rtc_ops *rtc_ops;
+ 
+-#ifdef CONFIG_PC_KEYB
+-extern struct kbd_ops no_kbd_ops;
+-struct kbd_ops *kbd_ops;
+-#endif
+-
+ #ifdef CONFIG_BLK_DEV_INITRD
+ extern void *initrd_start;
+ extern void *initrd_end;
+diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c
+index 033aae0..f2220b5 100644
+--- a/arch/xtensa/kernel/signal.c
++++ b/arch/xtensa/kernel/signal.c
+@@ -35,13 +35,17 @@ asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
+ 
+ extern struct task_struct *coproc_owners[];
+ 
+-extern void release_all_cp (struct task_struct *);
+-
+ struct rt_sigframe
+ {
+ 	struct siginfo info;
+ 	struct ucontext uc;
+-	cp_state_t cpstate;
++	struct {
++		xtregs_opt_t opt;
++		xtregs_user_t user;
++#if XTENSA_HAVE_COPROCESSORS
++		xtregs_coprocessor_t cp;
++#endif
++	} xtregs;
+ 	unsigned char retcode[6];
+ 	unsigned int window[4];
+ };
+@@ -49,8 +53,6 @@ struct rt_sigframe
+ /* 
+  * Flush register windows stored in pt_regs to stack.
+  * Returns 1 for errors.
+- *
+- * Note that windowbase, windowstart, and wmask are not updated!
+  */
+ 
+ int
+@@ -116,6 +118,9 @@ flush_window_regs_user(struct pt_regs *regs)
+ 		base += inc;
+ 	}
+ 
++	regs->wmask = 1;
++	regs->windowstart = 1 << wb;
++
+ 	return 0;
+ 
+ errout:
+@@ -131,9 +136,10 @@ errout:
+  */
+ 
+ static int
+-setup_sigcontext(struct sigcontext __user *sc, cp_state_t *cpstate,
+-		 struct pt_regs *regs, unsigned long mask)
++setup_sigcontext(struct rt_sigframe __user *frame, struct pt_regs *regs)
+ {
++	struct sigcontext __user *sc = &frame->uc.uc_mcontext;
++	struct thread_info *ti = current_thread_info();
+ 	int err = 0;
+ 
+ #define COPY(x)	err |= __put_user(regs->x, &sc->sc_##x)
+@@ -147,23 +153,32 @@ setup_sigcontext(struct sigcontext __user *sc, cp_state_t *cpstate,
+ 
+ 	err |= flush_window_regs_user(regs);
+ 	err |= __copy_to_user (sc->sc_a, regs->areg, 16 * 4);
++	err |= __put_user(0, &sc->sc_xtregs);
+ 
+-	// err |= __copy_to_user (sc->sc_a, regs->areg, XCHAL_NUM_AREGS * 4)
++	if (err)
++		return err;
+ 
+-#if XCHAL_HAVE_CP
+-# error Coprocessors unsupported
+-	err |= save_cpextra(cpstate);
+-	err |= __put_user(err ? NULL : cpstate, &sc->sc_cpstate);
++#if XTENSA_HAVE_COPROCESSORS
++	coprocessor_flush_all(ti);
++	coprocessor_release_all(ti);
++	err |= __copy_to_user(&frame->xtregs.cp, &ti->xtregs_cp,
++			      sizeof (frame->xtregs.cp));
+ #endif
+-	/* non-iBCS2 extensions.. */
+-	err |= __put_user(mask, &sc->oldmask);
++	err |= __copy_to_user(&frame->xtregs.opt, &regs->xtregs_opt,
++			      sizeof (xtregs_opt_t));
++	err |= __copy_to_user(&frame->xtregs.user, &ti->xtregs_user,
++			      sizeof (xtregs_user_t));
++
++	err |= __put_user(err ? NULL : &frame->xtregs, &sc->sc_xtregs);
+ 
+ 	return err;
+ }
+ 
+ static int
+-restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
++restore_sigcontext(struct pt_regs *regs, struct rt_sigframe __user *frame)
+ {
++	struct sigcontext __user *sc = &frame->uc.uc_mcontext;
++	struct thread_info *ti = current_thread_info();
+ 	unsigned int err = 0;
+ 	unsigned long ps;
+ 
+@@ -181,6 +196,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
+ 	regs->windowbase = 0;
+ 	regs->windowstart = 1;
+ 
++	regs->syscall = -1;		/* disable syscall checks */
++
+ 	/* For PS, restore only PS.CALLINC.
+ 	 * Assume that all other bits are either the same as for the signal
+ 	 * handler, or the user mode value doesn't matter (e.g. PS.OWB).
+@@ -196,8 +213,9 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
+ 
+ 	err |= __copy_from_user(regs->areg, sc->sc_a, 16 * 4);
+ 
+-#if XCHAL_HAVE_CP
+-# error Coprocessors unsupported
++	if (err)
++		return err;
++
+  	/* The signal handler may have used coprocessors in which
+ 	 * case they are still enabled.  We disable them to force a
+ 	 * reloading of the original task's CP state by the lazy
+@@ -205,20 +223,20 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
+ 	 * Also, we essentially discard any coprocessor state that the
+ 	 * signal handler created. */
+ 
+-	if (!err) {
+-	  struct task_struct *tsk = current;
+-	  release_all_cp(tsk);
+-	  err |= __copy_from_user(tsk->thread.cpextra, sc->sc_cpstate, 
+-	      			  XTENSA_CP_EXTRA_SIZE);
+-	}
++#if XTENSA_HAVE_COPROCESSORS
++	coprocessor_release_all(ti);
++	err |= __copy_from_user(&ti->xtregs_cp, &frame->xtregs.cp,
++				sizeof (frame->xtregs.cp));
+ #endif
++	err |= __copy_from_user(&ti->xtregs_user, &frame->xtregs.user,
++				sizeof (xtregs_user_t));
++	err |= __copy_from_user(&regs->xtregs_opt, &frame->xtregs.opt,
++				sizeof (xtregs_opt_t));
+ 
+-	regs->syscall = -1;		/* disable syscall checks */
+ 	return err;
+ }
+ 
+ 
+-
+ /*
+  * Do a signal return; undo the signal stack.
+  */
+@@ -247,7 +265,7 @@ asmlinkage long xtensa_rt_sigreturn(long a0, long a1, long a2, long a3,
+ 	recalc_sigpending();
+ 	spin_unlock_irq(&current->sighand->siglock);
+ 
+-	if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
++	if (restore_sigcontext(regs, frame))
+ 		goto badframe;
+ 
+ 	ret = regs->areg[2];
+@@ -360,18 +378,22 @@ static void setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+ 	err |= __put_user(sas_ss_flags(regs->areg[1]),
+ 			  &frame->uc.uc_stack.ss_flags);
+ 	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+-	err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->cpstate,
+-			        regs, set->sig[0]);
++	err |= setup_sigcontext(frame, regs);
+ 	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+ 
+-	/* Create sys_rt_sigreturn syscall in stack frame */
++	if (ka->sa.sa_flags & SA_RESTORER) {
++		ra = (unsigned long)ka->sa.sa_restorer;
++	} else {
+ 
+-	err |= gen_return_code(frame->retcode);
++		/* Create sys_rt_sigreturn syscall in stack frame */
+ 
+-	if (err) {
+-		goto give_sigsegv;
++		err |= gen_return_code(frame->retcode);
++
++		if (err) {
++			goto give_sigsegv;
++		}
++		ra = (unsigned long) frame->retcode;
+ 	}
+-		
+ 
+ 	/* 
+ 	 * Create signal handler execution context.
+@@ -385,7 +407,6 @@ static void setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+ 	/* Set up a stack frame for a call4
+ 	 * Note: PS.CALLINC is set to one by start_thread
+ 	 */
+-	ra = (unsigned long) frame->retcode;
+ 	regs->areg[4] = (((unsigned long) ra) & 0x3fffffff) | 0x40000000;
+ 	regs->areg[6] = (unsigned long) signal;
+ 	regs->areg[7] = (unsigned long) &frame->info;
+diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
+index 397bcd6..c7a021d 100644
+--- a/arch/xtensa/kernel/traps.c
++++ b/arch/xtensa/kernel/traps.c
+@@ -118,28 +118,28 @@ static dispatch_init_table_t __initdata dispatch_init_table[] = {
+ { EXCCAUSE_STORE_CACHE_ATTRIBUTE,	0,	   do_page_fault },
+ { EXCCAUSE_LOAD_CACHE_ATTRIBUTE,	0,	   do_page_fault },
+ /* XCCHAL_EXCCAUSE_FLOATING_POINT unhandled */
+-#if (XCHAL_CP_MASK & 1)
++#if XTENSA_HAVE_COPROCESSOR(0)
+ COPROCESSOR(0),
+ #endif
+-#if (XCHAL_CP_MASK & 2)
++#if XTENSA_HAVE_COPROCESSOR(1)
+ COPROCESSOR(1),
+ #endif
+-#if (XCHAL_CP_MASK & 4)
++#if XTENSA_HAVE_COPROCESSOR(2)
+ COPROCESSOR(2),
+ #endif
+-#if (XCHAL_CP_MASK & 8)
++#if XTENSA_HAVE_COPROCESSOR(3)
+ COPROCESSOR(3),
+ #endif
+-#if (XCHAL_CP_MASK & 16)
++#if XTENSA_HAVE_COPROCESSOR(4)
+ COPROCESSOR(4),
+ #endif
+-#if (XCHAL_CP_MASK & 32)
++#if XTENSA_HAVE_COPROCESSOR(5)
+ COPROCESSOR(5),
+ #endif
+-#if (XCHAL_CP_MASK & 64)
++#if XTENSA_HAVE_COPROCESSOR(6)
+ COPROCESSOR(6),
+ #endif
+-#if (XCHAL_CP_MASK & 128)
++#if XTENSA_HAVE_COPROCESSOR(7)
+ COPROCESSOR(7),
+ #endif
+ { EXCCAUSE_MAPPED_DEBUG,		0,		do_debug },
+@@ -349,9 +349,7 @@ void show_regs(struct pt_regs * regs)
+ 
+ 	wmask = regs->wmask & ~1;
+ 
+-	for (i = 0; i < 32; i++) {
+-		if (wmask & (1 << (i / 4)))
+-			break;
++	for (i = 0; i < 16; i++) {
+ 		if ((i % 8) == 0)
+ 			printk ("\n" KERN_INFO "a%02d: ", i);
+ 		printk("%08lx ", regs->areg[i]);
+diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
+index 7d0f55a..51f4fb6 100644
+--- a/arch/xtensa/kernel/vmlinux.lds.S
++++ b/arch/xtensa/kernel/vmlinux.lds.S
+@@ -136,7 +136,9 @@ SECTIONS
+   __init_begin = .;
+   .init.text : {
+   	_sinittext = .;
+-	*(.init.literal) INIT_TEXT
++	*(.init.literal) *(.cpuinit.literal) 
++	*(.devinit.literal) *(.meminit.literal)
++	INIT_TEXT
+ 	_einittext = .;
+   }
+ 
+@@ -161,6 +163,8 @@ SECTIONS
+ 		   .DoubleExceptionVector.literal);
+     RELOCATE_ENTRY(_DoubleExceptionVector_text,
+ 		   .DoubleExceptionVector.text);
++    RELOCATE_ENTRY(_DebugInterruptVector_text,
++		   .DebugInterruptVector.text);
+   
+     __boot_reloc_table_end = ABSOLUTE(.) ;
+   }
+diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c
+index 9a1fa94..3ba990c 100644
+--- a/arch/xtensa/mm/cache.c
++++ b/arch/xtensa/mm/cache.c
+@@ -25,7 +25,6 @@
+ #include <linux/swap.h>
+ #include <linux/pagemap.h>
+ 
+-#include <asm/pgtable.h>
+ #include <asm/bootparam.h>
+ #include <asm/mmu_context.h>
+ #include <asm/tlb.h>
+@@ -181,9 +180,9 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t pte)
+ #else
+ 	if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)
+ 	    && (vma->vm_flags & VM_EXEC) != 0) {
+-		unsigned long vaddr = addr & PAGE_MASK;
+-		__flush_dcache_page(vaddr);
+-		__invalidate_icache_page(vaddr);
++	    	unsigned long paddr = (unsigned long) page_address(page);
++		__flush_dcache_page(paddr);
++		__invalidate_icache_page(paddr);
+ 		set_bit(PG_arch_1, &page->flags);
+ 	}
+ #endif
+diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c
+index b3086f3..81d0560 100644
+--- a/arch/xtensa/mm/init.c
++++ b/arch/xtensa/mm/init.c
+@@ -309,7 +309,7 @@ void show_mem(void)
+ 
+ struct kmem_cache *pgtable_cache __read_mostly;
+ 
+-static void pgd_ctor(void *addr, struct kmem_cache *cache, unsigned long flags)
++static void pgd_ctor(struct kmem_cache *cache, void* addr)
+ {
+ 	pte_t* ptep = (pte_t*)addr;
+ 	int i;
+diff --git a/arch/xtensa/mm/misc.S b/arch/xtensa/mm/misc.S
+index e1f8803..c885664 100644
+--- a/arch/xtensa/mm/misc.S
++++ b/arch/xtensa/mm/misc.S
+@@ -295,7 +295,7 @@ ENTRY(__tlbtemp_mapping_itlb)
+ ENTRY(__invalidate_icache_page_alias)
+ 	entry	sp, 16
+ 
+-	addi	a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
++	addi	a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE)
+ 	mov	a4, a2
+ 	witlb	a6, a2
+ 	isync
+diff --git a/arch/xtensa/platform-iss/Makefile b/arch/xtensa/platform-iss/Makefile
+deleted file mode 100644
+index af96e31..0000000
+--- a/arch/xtensa/platform-iss/Makefile
++++ /dev/null
+@@ -1,8 +0,0 @@
+-# $Id: Makefile,v 1.1.1.1 2002/08/28 16:10:14 aroll Exp $
+-#
+-# Makefile for the Xtensa Instruction Set Simulator (ISS)
+-# "prom monitor" library routines under Linux.
+-#
+-
+-obj-y			= io.o console.o setup.o network.o
+-
+diff --git a/arch/xtensa/platform-iss/console.c b/arch/xtensa/platform-iss/console.c
+deleted file mode 100644
+index 854677d..0000000
+--- a/arch/xtensa/platform-iss/console.c
++++ /dev/null
+@@ -1,296 +0,0 @@
+-/*
+- * arch/xtensa/platform-iss/console.c
+- *
+- * This file is subject to the terms and conditions of the GNU General Public
+- * License.  See the file "COPYING" in the main directory of this archive
+- * for more details.
+- *
+- * Copyright (C) 2001-2005 Tensilica Inc.
+- *   Authors	Christian Zankel, Joe Taylor
+- */
+-
+-#include <linux/module.h>
+-#include <linux/kernel.h>
+-#include <linux/sched.h>
+-#include <linux/console.h>
+-#include <linux/init.h>
+-#include <linux/slab.h>
+-#include <linux/mm.h>
+-#include <linux/major.h>
+-#include <linux/param.h>
+-#include <linux/serial.h>
+-#include <linux/serialP.h>
+-
+-#include <asm/uaccess.h>
+-#include <asm/irq.h>
+-
+-#include <asm/platform/simcall.h>
+-
+-#include <linux/tty.h>
+-#include <linux/tty_flip.h>
+-
+-#ifdef SERIAL_INLINE
+-#define _INLINE_ inline
+-#endif
+-
+-#define SERIAL_MAX_NUM_LINES 1
+-#define SERIAL_TIMER_VALUE (20 * HZ)
+-
+-static struct tty_driver *serial_driver;
+-static struct timer_list serial_timer;
+-
+-static DEFINE_SPINLOCK(timer_lock);
+-
+-int errno;
+-
+-static int __simc (int a, int b, int c, int d, int e, int f)
+-{
+-	int ret;
+-	__asm__ __volatile__ ("simcall\n"
+-			"mov %0, a2\n"
+-			"mov %1, a3\n" : "=a" (ret), "=a" (errno)
+-			: : "a2", "a3");
+-	return ret;
+-}
+-
+-static char *serial_version = "0.1";
+-static char *serial_name = "ISS serial driver";
+-
+-/*
+- * This routine is called whenever a serial port is opened.  It
+- * enables interrupts for a serial port, linking in its async structure into
+- * the IRQ chain.   It also performs the serial-specific
+- * initialization for the tty structure.
+- */
+-
+-static void rs_poll(unsigned long);
+-
+-static int rs_open(struct tty_struct *tty, struct file * filp)
+-{
+-	int line = tty->index;
+-
+-	if ((line < 0) || (line >= SERIAL_MAX_NUM_LINES))
+-		return -ENODEV;
+-
+-	spin_lock(&timer_lock);
+-
+-	if (tty->count == 1) {
+-		init_timer(&serial_timer);
+-		serial_timer.data = (unsigned long) tty;
+-		serial_timer.function = rs_poll;
+-		mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE);
+-	}
+-	spin_unlock(&timer_lock);
+-
+-	return 0;
+-}
+-
+-
+-/*
+- * ------------------------------------------------------------
+- * iss_serial_close()
+- *
+- * This routine is called when the serial port gets closed.  First, we
+- * wait for the last remaining data to be sent.  Then, we unlink its
+- * async structure from the interrupt chain if necessary, and we free
+- * that IRQ if nothing is left in the chain.
+- * ------------------------------------------------------------
+- */
+-static void rs_close(struct tty_struct *tty, struct file * filp)
+-{
+-	spin_lock(&timer_lock);
+-	if (tty->count == 1)
+-		del_timer_sync(&serial_timer);
+-	spin_unlock(&timer_lock);
+-}
+-
+-
+-static int rs_write(struct tty_struct * tty,
+-		    const unsigned char *buf, int count)
+-{
+-	/* see drivers/char/serialX.c to reference original version */
+-
+-	__simc (SYS_write, 1, (unsigned long)buf, count, 0, 0);
+-	return count;
+-}
+-
+-static void rs_poll(unsigned long priv)
+-{
+-	struct tty_struct* tty = (struct tty_struct*) priv;
+-
+-	struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
+-	int i = 0;
+-	unsigned char c;
+-
+-	spin_lock(&timer_lock);
+-
+-	while (__simc(SYS_select_one, 0, XTISS_SELECT_ONE_READ, (int)&tv,0,0)){
+-		__simc (SYS_read, 0, (unsigned long)&c, 1, 0, 0);
+-		tty_insert_flip_char(tty, c, TTY_NORMAL);
+-		i++;
+-	}
+-
+-	if (i)
+-		tty_flip_buffer_push(tty);
+-
+-
+-	mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE);
+-	spin_unlock(&timer_lock);
+-}
+-
+-
+-static void rs_put_char(struct tty_struct *tty, unsigned char ch)
+-{
+-	char buf[2];
+-
+-	if (!tty)
+-		return;
+-
+-	buf[0] = ch;
+-	buf[1] = '\0';		/* Is this NULL necessary? */
+-	__simc (SYS_write, 1, (unsigned long) buf, 1, 0, 0);
+-}
+-
+-static void rs_flush_chars(struct tty_struct *tty)
+-{
+-}
+-
+-static int rs_write_room(struct tty_struct *tty)
+-{
+-	/* Let's say iss can always accept 2K characters.. */
+-	return 2 * 1024;
+-}
+-
+-static int rs_chars_in_buffer(struct tty_struct *tty)
+-{
+-	/* the iss doesn't buffer characters */
+-	return 0;
+-}
+-
+-static void rs_hangup(struct tty_struct *tty)
+-{
+-	/* Stub, once again.. */
+-}
+-
+-static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
+-{
+-	/* Stub, once again.. */
+-}
+-
+-static int rs_read_proc(char *page, char **start, off_t off, int count,
+-			int *eof, void *data)
+-{
+-	int len = 0;
+-	off_t begin = 0;
+-
+-	len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
+-	*eof = 1;
+-
+-	if (off >= len + begin)
+-		return 0;
+-
+-	*start = page + (off - begin);
+-	return ((count < begin + len - off) ? count : begin + len - off);
+-}
+-
+-
+-static struct tty_operations serial_ops = {
+-	.open = rs_open,
+-	.close = rs_close,
+-	.write = rs_write,
+-	.put_char = rs_put_char,
+-	.flush_chars = rs_flush_chars,
+-	.write_room = rs_write_room,
+-	.chars_in_buffer = rs_chars_in_buffer,
+-	.hangup = rs_hangup,
+-	.wait_until_sent = rs_wait_until_sent,
+-	.read_proc = rs_read_proc
+-};
+-
+-int __init rs_init(void)
+-{
+-	serial_driver = alloc_tty_driver(1);
+-
+-	printk ("%s %s\n", serial_name, serial_version);
+-
+-	/* Initialize the tty_driver structure */
+-
+-	serial_driver->owner = THIS_MODULE;
+-	serial_driver->driver_name = "iss_serial";
+-	serial_driver->name = "ttyS";
+-	serial_driver->major = TTY_MAJOR;
+-	serial_driver->minor_start = 64;
+-	serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
+-	serial_driver->subtype = SERIAL_TYPE_NORMAL;
+-	serial_driver->init_termios = tty_std_termios;
+-	serial_driver->init_termios.c_cflag =
+-		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+-	serial_driver->flags = TTY_DRIVER_REAL_RAW;
+-
+-	tty_set_operations(serial_driver, &serial_ops);
+-
+-	if (tty_register_driver(serial_driver))
+-		panic("Couldn't register serial driver\n");
+-	return 0;
+-}
+-
+-
+-static __exit void rs_exit(void)
+-{
+-	int error;
+-
+-	if ((error = tty_unregister_driver(serial_driver)))
+-		printk("ISS_SERIAL: failed to unregister serial driver (%d)\n",
+-		       error);
+-	put_tty_driver(serial_driver);
+-}
+-
+-
+-/* We use `late_initcall' instead of just `__initcall' as a workaround for
+- * the fact that (1) simcons_tty_init can't be called before tty_init,
+- * (2) tty_init is called via `module_init', (3) if statically linked,
+- * module_init == device_init, and (4) there's no ordering of init lists.
+- * We can do this easily because simcons is always statically linked, but
+- * other tty drivers that depend on tty_init and which must use
+- * `module_init' to declare their init routines are likely to be broken.
+- */
+-
+-late_initcall(rs_init);
+-
+-
+-#ifdef CONFIG_SERIAL_CONSOLE
+-
+-static void iss_console_write(struct console *co, const char *s, unsigned count)
+-{
+-	int len = strlen(s);
+-
+-	if (s != 0 && *s != 0)
+-		__simc (SYS_write, 1, (unsigned long)s,
+-			count < len ? count : len,0,0);
+-}
+-
+-static struct tty_driver* iss_console_device(struct console *c, int *index)
+-{
+-	*index = c->index;
+-	return serial_driver;
+-}
+-
+-
+-static struct console sercons = {
+-	.name = "ttyS",
+-	.write = iss_console_write,
+-	.device = iss_console_device,
+-	.flags = CON_PRINTBUFFER,
+-	.index = -1
+-};
+-
+-static int __init iss_console_init(void)
+-{
+-	register_console(&sercons);
+-	return 0;
+-}
+-
+-console_initcall(iss_console_init);
+-
+-#endif /* CONFIG_SERIAL_CONSOLE */
+-
+diff --git a/arch/xtensa/platform-iss/io.c b/arch/xtensa/platform-iss/io.c
+deleted file mode 100644
+index 5b161a5..0000000
+--- a/arch/xtensa/platform-iss/io.c
++++ /dev/null
+@@ -1,32 +0,0 @@
+-/* This file isn't really needed right now. */
+-
+-#if 0
+-
+-#include <asm/io.h>
+-#include <xtensa/simcall.h>
+-
+-extern int __simc ();
+-
+-
+-char iss_serial_getc()
+-{
+-  char c;
+-  __simc( SYS_read, 0, &c, 1 );
+-  return c;
+-}
+-
+-void iss_serial_putc( char c )
+-{
+-  __simc( SYS_write, 1, &c, 1 );
+-}
+-
+-void iss_serial_puts( char *s )
+-{
+-  if( s != 0 && *s != 0 )
+-    __simc( SYS_write, 1, s, strlen(s) );
+-}
+-
+-/*#error Need I/O ports to specific hardware!*/
+-
+-#endif
+-
+diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c
+deleted file mode 100644
+index f21b9b0..0000000
+--- a/arch/xtensa/platform-iss/network.c
++++ /dev/null
+@@ -1,823 +0,0 @@
+-/*
+- *
+- * arch/xtensa/platform-iss/network.c
+- *
+- * Platform specific initialization.
+- *
+- * Authors: Chris Zankel <chris at zankel.net>
+- * Based on work form the UML team.
+- *
+- * Copyright 2005 Tensilica Inc.
+- *
+- * This program is free software; you can redistribute  it and/or modify it
+- * under  the terms of  the GNU General  Public License as published by the
+- * Free Software Foundation;  either version 2 of the  License, or (at your
+- * option) any later version.
+- *
+- */
+-
+-#include <linux/list.h>
+-#include <linux/irq.h>
+-#include <linux/spinlock.h>
+-#include <linux/slab.h>
+-#include <linux/timer.h>
+-#include <linux/if_ether.h>
+-#include <linux/inetdevice.h>
+-#include <linux/init.h>
+-#include <linux/if_tun.h>
+-#include <linux/etherdevice.h>
+-#include <linux/interrupt.h>
+-#include <linux/ioctl.h>
+-#include <linux/bootmem.h>
+-#include <linux/ethtool.h>
+-#include <linux/rtnetlink.h>
+-#include <linux/timer.h>
+-#include <linux/platform_device.h>
+-
+-#include <asm/platform/simcall.h>
+-
+-#define DRIVER_NAME "iss-netdev"
+-#define ETH_MAX_PACKET 1500
+-#define ETH_HEADER_OTHER 14
+-#define ISS_NET_TIMER_VALUE (2 * HZ)
+-
+-
+-static DEFINE_SPINLOCK(opened_lock);
+-static LIST_HEAD(opened);
+-
+-static DEFINE_SPINLOCK(devices_lock);
+-static LIST_HEAD(devices);
+-
+-/* ------------------------------------------------------------------------- */
+-
+-/* We currently only support the TUNTAP transport protocol. */
+-
+-#define TRANSPORT_TUNTAP_NAME "tuntap"
+-#define TRANSPORT_TUNTAP_MTU ETH_MAX_PACKET
+-
+-struct tuntap_info {
+-	char dev_name[IFNAMSIZ];
+-	int fixed_config;
+-	unsigned char gw[ETH_ALEN];
+-	int fd;
+-};
+-
+-/* ------------------------------------------------------------------------- */
+-
+-
+-/* This structure contains out private information for the driver. */
+-
+-struct iss_net_private {
+-
+-	struct list_head device_list;
+-	struct list_head opened_list;
+-
+-	spinlock_t lock;
+-	struct net_device *dev;
+-	struct platform_device pdev;
+-	struct timer_list tl;
+-	struct net_device_stats stats;
+-
+-	struct timer_list timer;
+-	unsigned int timer_val;
+-
+-	int index;
+-	int mtu;
+-
+-	unsigned char mac[ETH_ALEN];
+-	int have_mac;
+-
+-	struct {
+-		union {
+-			struct tuntap_info tuntap;
+-		} info;
+-
+-		int (*open)(struct iss_net_private *lp);
+-		void (*close)(struct iss_net_private *lp);
+-		int (*read)(struct iss_net_private *lp, struct sk_buff **skb);
+-		int (*write)(struct iss_net_private *lp, struct sk_buff **skb);
+-		unsigned short (*protocol)(struct sk_buff *skb);
+-		int (*poll)(struct iss_net_private *lp);
+-	} tp;
+-
+-};
+-
+-/* ======================= ISS SIMCALL INTERFACE =========================== */
+-
+-/* Note: __simc must _not_ be declared inline! */
+-
+-static int errno;
+-
+-static int __simc (int a, int b, int c, int d, int e, int f)
+-{
+-	int ret;
+-	__asm__ __volatile__ ("simcall\n"
+-	    		      "mov %0, a2\n"
+-			      "mov %1, a3\n" : "=a" (ret), "=a" (errno)
+-			      : : "a2", "a3");
+-	return ret;
+-}
+-
+-static int inline simc_open(char *file, int flags, int mode)
+-{
+-	return __simc(SYS_open, (int) file, flags, mode, 0, 0);
+-}
+-
+-static int inline simc_close(int fd)
+-{
+-	return __simc(SYS_close, fd, 0, 0, 0, 0);
+-}
+-
+-static int inline simc_ioctl(int fd, int request, void *arg)
+-{
+-	return __simc(SYS_ioctl, fd, request, (int) arg, 0, 0);
+-}
+-
+-static int inline simc_read(int fd, void *buf, size_t count)
+-{
+-	return __simc(SYS_read, fd, (int) buf, count, 0, 0);
+-}
+-
+-static int inline simc_write(int fd, void *buf, size_t count)
+-{
+-	return __simc(SYS_write, fd, (int) buf, count, 0, 0);
+-}
+-
+-static int inline simc_poll(int fd)
+-{
+-	struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
+-
+-	return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&tv,0,0);
+-}
+-
+-/* ================================ HELPERS ================================ */
+-
+-
+-static char *split_if_spec(char *str, ...)
+-{
+-	char **arg, *end;
+-	va_list ap;
+-
+-	va_start(ap, str);
+-	while ((arg = va_arg(ap, char**)) != NULL) {
+-		if (*str == '\0')
+-			return NULL;
+-		end = strchr(str, ',');
+-		if (end != str)
+-			*arg = str;
+-		if (end == NULL)
+-			return NULL;
+-		*end ++ = '\0';
+-		str = end;
+-	}
+-	va_end(ap);
+-	return str;
+-}
+-
+-
+-#if 0
+-/* Adjust SKB. */
+-
+-struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
+-{
+-	if ((skb != NULL) && (skb_tailroom(skb) < extra)) {
+-		struct sk_buff *skb2;
+-
+-		skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
+-		dev_kfree_skb(skb);
+-		skb = skb2;
+-	}
+-	if (skb != NULL)
+-		skb_put(skb, extra);
+-
+-	return skb;
+-}
+-#endif
+-
+-/* Return the IP address as a string for a given device. */
+-
+-static void dev_ip_addr(void *d, char *buf, char *bin_buf)
+-{
+-	struct net_device *dev = d;
+-	struct in_device *ip = dev->ip_ptr;
+-	struct in_ifaddr *in;
+-	__be32 addr;
+-
+-	if ((ip == NULL) || ((in = ip->ifa_list) == NULL)) {
+-		printk(KERN_WARNING "Device not assigned an IP address!\n");
+-		return;
+-	}
+-
+-	addr = in->ifa_address;
+-	sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff,
+-		(addr >> 16) & 0xff, addr >> 24);
+-
+-	if (bin_buf) {
+-		bin_buf[0] = addr & 0xff;
+-		bin_buf[1] = (addr >> 8) & 0xff;
+-		bin_buf[2] = (addr >> 16) & 0xff;
+-		bin_buf[3] = addr >> 24;
+-	}
+-}
+-
+-/* Set Ethernet address of the specified device. */
+-
+-static void inline set_ether_mac(void *d, unsigned char *addr)
+-{
+-	struct net_device *dev = d;
+-	memcpy(dev->dev_addr, addr, ETH_ALEN);
+-}
+-
+-
+-/* ======================= TUNTAP TRANSPORT INTERFACE ====================== */
+-
+-static int tuntap_open(struct iss_net_private *lp)
+-{
+-	struct ifreq ifr;
+-	char *dev_name = lp->tp.info.tuntap.dev_name;
+-	int err = -EINVAL;
+-	int fd;
+-
+-	/* We currently only support a fixed configuration. */
+-
+-	if (!lp->tp.info.tuntap.fixed_config)
+-		return -EINVAL;
+-
+-	if ((fd = simc_open("/dev/net/tun", 02, 0)) < 0) {	/* O_RDWR */
+-		printk("Failed to open /dev/net/tun, returned %d "
+-		       "(errno = %d)\n", fd, errno);
+-		return fd;
+-	}
+-
+-	memset(&ifr, 0, sizeof ifr);
+-	ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+-	strlcpy(ifr.ifr_name, dev_name, sizeof ifr.ifr_name);
+-
+-	if ((err = simc_ioctl(fd, TUNSETIFF, (void*) &ifr)) < 0) {
+-		printk("Failed to set interface, returned %d "
+-		       "(errno = %d)\n", err, errno);
+-		simc_close(fd);
+-		return err;
+-	}
+-
+-	lp->tp.info.tuntap.fd = fd;
+-	return err;
+-}
+-
+-static void tuntap_close(struct iss_net_private *lp)
+-{
+-#if 0
+-	if (lp->tp.info.tuntap.fixed_config)
+-		iter_addresses(lp->tp.info.tuntap.dev, close_addr, lp->host.dev_name);
+-#endif
+-	simc_close(lp->tp.info.tuntap.fd);
+-	lp->tp.info.tuntap.fd = -1;
+-}
+-
+-static int tuntap_read (struct iss_net_private *lp, struct sk_buff **skb)
+-{
+-#if 0
+-	*skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
+-	if (*skb == NULL)
+-		return -ENOMEM;
+-#endif
+-
+-	return simc_read(lp->tp.info.tuntap.fd,
+-			(*skb)->data, (*skb)->dev->mtu + ETH_HEADER_OTHER);
+-}
+-
+-static int tuntap_write (struct iss_net_private *lp, struct sk_buff **skb)
+-{
+-	return simc_write(lp->tp.info.tuntap.fd, (*skb)->data, (*skb)->len);
+-}
+-
+-unsigned short tuntap_protocol(struct sk_buff *skb)
+-{
+-	return eth_type_trans(skb, skb->dev);
+-}
+-
+-static int tuntap_poll(struct iss_net_private *lp)
+-{
+-	return simc_poll(lp->tp.info.tuntap.fd);
+-}
+-
+-/*
+- * Currently only a device name is supported.
+- * ethX=tuntap[,[mac address][,[device name]]]
+- */
+-
+-static int tuntap_probe(struct iss_net_private *lp, int index, char *init)
+-{
+-	const int len = strlen(TRANSPORT_TUNTAP_NAME);
+-	char *dev_name = NULL, *mac_str = NULL, *rem = NULL;
+-
+-	/* Transport should be 'tuntap': ethX=tuntap,mac,dev_name */
+-
+-	if (strncmp(init, TRANSPORT_TUNTAP_NAME, len))
+-		return 0;
+-
+-	if (*(init += strlen(TRANSPORT_TUNTAP_NAME)) == ',') {
+-		if ((rem=split_if_spec(init+1, &mac_str, &dev_name)) != NULL) {
+-			printk("Extra garbage on specification : '%s'\n", rem);
+-			return 0;
+-		}
+-	} else if (*init != '\0') {
+-		printk("Invalid argument: %s. Skipping device!\n", init);
+-		return 0;
+-	}
+-
+-	if (dev_name) {
+-		strncpy(lp->tp.info.tuntap.dev_name, dev_name,
+-			 sizeof lp->tp.info.tuntap.dev_name);
+-		lp->tp.info.tuntap.fixed_config = 1;
+-	} else
+-		strcpy(lp->tp.info.tuntap.dev_name, TRANSPORT_TUNTAP_NAME);
+-
+-
+-#if 0
+-	if (setup_etheraddr(mac_str, lp->mac))
+-		lp->have_mac = 1;
+-#endif
+-	lp->mtu = TRANSPORT_TUNTAP_MTU;
+-
+-	//lp->info.tuntap.gate_addr = gate_addr;
+-
+-	lp->tp.info.tuntap.fd = -1;
+-
+-	lp->tp.open = tuntap_open;
+-	lp->tp.close = tuntap_close;
+-	lp->tp.read = tuntap_read;
+-	lp->tp.write = tuntap_write;
+-	lp->tp.protocol = tuntap_protocol;
+-	lp->tp.poll = tuntap_poll;
+-
+-	printk("TUN/TAP backend - ");
+-#if 0
+-	if (lp->host.gate_addr != NULL)
+-		printk("IP = %s", lp->host.gate_addr);
+-#endif
+-	printk("\n");
+-
+-	return 1;
+-}
+-
+-/* ================================ ISS NET ================================ */
+-
+-static int iss_net_rx(struct net_device *dev)
+-{
+-	struct iss_net_private *lp = dev->priv;
+-	int pkt_len;
+-	struct sk_buff *skb;
+-
+-	/* Check if there is any new data. */
+-
+-	if (lp->tp.poll(lp) == 0)
+-		return 0;
+-
+-	/* Try to allocate memory, if it fails, try again next round. */
+-
+-	if ((skb = dev_alloc_skb(dev->mtu + 2 + ETH_HEADER_OTHER)) == NULL) {
+-		lp->stats.rx_dropped++;
+-		return 0;
+-	}
+-
+-	skb_reserve(skb, 2);
+-
+-	/* Setup skb */
+-
+-	skb->dev = dev;
+-	skb_reset_mac_header(skb);
+-	pkt_len = lp->tp.read(lp, &skb);
+-	skb_put(skb, pkt_len);
+-
+-	if (pkt_len > 0) {
+-		skb_trim(skb, pkt_len);
+-		skb->protocol = lp->tp.protocol(skb);
+-
+-		lp->stats.rx_bytes += skb->len;
+-		lp->stats.rx_packets++;
+-	//	netif_rx(skb);
+-		netif_rx_ni(skb);
+-		return pkt_len;
+-	}
+-	kfree_skb(skb);
+-	return pkt_len;
+-}
+-
+-static int iss_net_poll(void)
+-{
+-	struct list_head *ele;
+-	int err, ret = 0;
+-
+-	spin_lock(&opened_lock);
+-
+-	list_for_each(ele, &opened) {
+-		struct iss_net_private *lp;
+-
+-		lp = list_entry(ele, struct iss_net_private, opened_list);
+-
+-		if (!netif_running(lp->dev))
+-			break;
+-
+-		spin_lock(&lp->lock);
+-
+-		while ((err = iss_net_rx(lp->dev)) > 0)
+-			ret++;
+-
+-		spin_unlock(&lp->lock);
+-
+-		if (err < 0) {
+-			printk(KERN_ERR "Device '%s' read returned %d, "
+-			       "shutting it down\n", lp->dev->name, err);
+-			dev_close(lp->dev);
+-		} else {
+-			// FIXME reactivate_fd(lp->fd, ISS_ETH_IRQ);
+-		}
+-	}
+-
+-	spin_unlock(&opened_lock);
+-	return ret;
+-}
+-
+-
+-static void iss_net_timer(unsigned long priv)
+-{
+-	struct iss_net_private* lp = (struct iss_net_private*) priv;
+-
+-	spin_lock(&lp->lock);
+-
+-	iss_net_poll();
+-
+-	mod_timer(&lp->timer, jiffies + lp->timer_val);
+-
+-	spin_unlock(&lp->lock);
+-}
+-
+-
+-static int iss_net_open(struct net_device *dev)
+-{
+-	struct iss_net_private *lp = dev->priv;
+-	char addr[sizeof "255.255.255.255\0"];
+-	int err;
+-
+-	spin_lock(&lp->lock);
+-
+-	if ((err = lp->tp.open(lp)) < 0)
+-		goto out;
+-
+-	if (!lp->have_mac) {
+-		dev_ip_addr(dev, addr, &lp->mac[2]);
+-		set_ether_mac(dev, lp->mac);
+-	}
+-
+-	netif_start_queue(dev);
+-
+-	/* clear buffer - it can happen that the host side of the interface
+-	 * is full when we get here. In this case, new data is never queued,
+-	 * SIGIOs never arrive, and the net never works.
+-	 */
+-	while ((err = iss_net_rx(dev)) > 0)
+-		;
+-
+-	spin_lock(&opened_lock);
+-	list_add(&lp->opened_list, &opened);
+-	spin_unlock(&opened_lock);
+-
+-	init_timer(&lp->timer);
+-	lp->timer_val = ISS_NET_TIMER_VALUE;
+-	lp->timer.data = (unsigned long) lp;
+-	lp->timer.function = iss_net_timer;
+-	mod_timer(&lp->timer, jiffies + lp->timer_val);
+-
+-out:
+-	spin_unlock(&lp->lock);
+-	return err;
+-}
+-
+-static int iss_net_close(struct net_device *dev)
+-{
+-	struct iss_net_private *lp = dev->priv;
+-printk("iss_net_close!\n");
+-	netif_stop_queue(dev);
+-	spin_lock(&lp->lock);
+-
+-	spin_lock(&opened_lock);
+-	list_del(&opened);
+-	spin_unlock(&opened_lock);
+-
+-	del_timer_sync(&lp->timer);
+-
+-	lp->tp.close(lp);
+-
+-	spin_unlock(&lp->lock);
+-	return 0;
+-}
+-
+-static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
+-{
+-	struct iss_net_private *lp = dev->priv;
+-	unsigned long flags;
+-	int len;
+-
+-	netif_stop_queue(dev);
+-	spin_lock_irqsave(&lp->lock, flags);
+-
+-	len = lp->tp.write(lp, &skb);
+-
+-	if (len == skb->len) {
+-		lp->stats.tx_packets++;
+-		lp->stats.tx_bytes += skb->len;
+-		dev->trans_start = jiffies;
+-		netif_start_queue(dev);
+-
+-		/* this is normally done in the interrupt when tx finishes */
+-		netif_wake_queue(dev);
+-
+-	} else if (len == 0) {
+-		netif_start_queue(dev);
+-		lp->stats.tx_dropped++;
+-
+-	} else {
+-		netif_start_queue(dev);
+-		printk(KERN_ERR "iss_net_start_xmit: failed(%d)\n", len);
+-	}
+-
+-	spin_unlock_irqrestore(&lp->lock, flags);
+-
+-	dev_kfree_skb(skb);
+-	return 0;
+-}
+-
+-
+-static struct net_device_stats *iss_net_get_stats(struct net_device *dev)
+-{
+-	struct iss_net_private *lp = dev->priv;
+-	return &lp->stats;
+-}
+-
+-static void iss_net_set_multicast_list(struct net_device *dev)
+-{
+-#if 0
+-	if (dev->flags & IFF_PROMISC)
+-		return;
+-	else if (dev->mc_count)
+-		dev->flags |= IFF_ALLMULTI;
+-	else
+-		dev->flags &= ~IFF_ALLMULTI;
+-#endif
+-}
+-
+-static void iss_net_tx_timeout(struct net_device *dev)
+-{
+-#if 0
+-	dev->trans_start = jiffies;
+-	netif_wake_queue(dev);
+-#endif
+-}
+-
+-static int iss_net_set_mac(struct net_device *dev, void *addr)
+-{
+-#if 0
+-	struct iss_net_private *lp = dev->priv;
+-	struct sockaddr *hwaddr = addr;
+-
+-	spin_lock(&lp->lock);
+-	memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN);
+-	spin_unlock(&lp->lock);
+-#endif
+-
+-	return 0;
+-}
+-
+-static int iss_net_change_mtu(struct net_device *dev, int new_mtu)
+-{
+-#if 0
+-	struct iss_net_private *lp = dev->priv;
+-	int err = 0;
+-
+-	spin_lock(&lp->lock);
+-
+-	// FIXME not needed new_mtu = transport_set_mtu(new_mtu, &lp->user);
+-
+-	if (new_mtu < 0)
+-		err = new_mtu;
+-	else
+-		dev->mtu = new_mtu;
+-
+-	spin_unlock(&lp->lock);
+-	return err;
+-#endif
+-	return -EINVAL;
+-}
+-
+-void iss_net_user_timer_expire(unsigned long _conn)
+-{
+-}
+-
+-
+-static struct platform_driver iss_net_driver = {
+-	.driver = {
+-		.name  = DRIVER_NAME,
+-	},
+-};
+-
+-static int driver_registered;
+-
+-static int iss_net_configure(int index, char *init)
+-{
+-	struct net_device *dev;
+-	struct iss_net_private *lp;
+-	int err;
+-
+-	if ((dev = alloc_etherdev(sizeof *lp)) == NULL) {
+-		printk(KERN_ERR "eth_configure: failed to allocate device\n");
+-		return 1;
+-	}
+-
+-	/* Initialize private element. */
+-
+-	lp = dev->priv;
+-	*lp = ((struct iss_net_private) {
+-		.device_list		= LIST_HEAD_INIT(lp->device_list),
+-		.opened_list		= LIST_HEAD_INIT(lp->opened_list),
+-		.lock			= SPIN_LOCK_UNLOCKED,
+-		.dev			= dev,
+-		.index			= index,
+-		//.fd                   = -1,
+-		.mac			= { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0 },
+-		.have_mac		= 0,
+-		});
+-
+-	/*
+-	 * Try all transport protocols.
+-	 * Note: more protocols can be added by adding '&& !X_init(lp, eth)'.
+-	 */
+-
+-	if (!tuntap_probe(lp, index, init)) {
+-		printk("Invalid arguments. Skipping device!\n");
+-		goto errout;
+-	}
+-
+-	printk(KERN_INFO "Netdevice %d ", index);
+-	if (lp->have_mac)
+-		printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
+-				lp->mac[0], lp->mac[1],
+-				lp->mac[2], lp->mac[3],
+-				lp->mac[4], lp->mac[5]);
+-	printk(": ");
+-
+-	/* sysfs register */
+-
+-	if (!driver_registered) {
+-		platform_driver_register(&iss_net_driver);
+-		driver_registered = 1;
+-	}
+-
+-	spin_lock(&devices_lock);
+-	list_add(&lp->device_list, &devices);
+-	spin_unlock(&devices_lock);
+-
+-	lp->pdev.id = index;
+-	lp->pdev.name = DRIVER_NAME;
+-	platform_device_register(&lp->pdev);
+-	SET_NETDEV_DEV(dev,&lp->pdev.dev);
+-
+-	/*
+-	 * If this name ends up conflicting with an existing registered
+-	 * netdevice, that is OK, register_netdev{,ice}() will notice this
+-	 * and fail.
+-	 */
+-	snprintf(dev->name, sizeof dev->name, "eth%d", index);
+-
+-	dev->mtu = lp->mtu;
+-	dev->open = iss_net_open;
+-	dev->hard_start_xmit = iss_net_start_xmit;
+-	dev->stop = iss_net_close;
+-	dev->get_stats = iss_net_get_stats;
+-	dev->set_multicast_list = iss_net_set_multicast_list;
+-	dev->tx_timeout = iss_net_tx_timeout;
+-	dev->set_mac_address = iss_net_set_mac;
+-	dev->change_mtu = iss_net_change_mtu;
+-	dev->watchdog_timeo = (HZ >> 1);
+-	dev->irq = -1;
+-
+-	rtnl_lock();
+-	err = register_netdevice(dev);
+-	rtnl_unlock();
+-
+-	if (err) {
+-		printk("Error registering net device!\n");
+-		/* XXX: should we call ->remove() here? */
+-		free_netdev(dev);
+-		return 1;
+-	}
+-
+-	init_timer(&lp->tl);
+-	lp->tl.function = iss_net_user_timer_expire;
+-
+-#if 0
+-	if (lp->have_mac)
+-		set_ether_mac(dev, lp->mac);
+-#endif
+-	return 0;
+-
+-errout:
+-	// FIXME: unregister; free, etc..
+-	return -EIO;
+-
+-}
+-
+-/* ------------------------------------------------------------------------- */
+-
+-/* Filled in during early boot */
+-
+-struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line);
+-
+-struct iss_net_init {
+-	struct list_head list;
+-	char *init;		/* init string */
+-	int index;
+-};
+-
+-/*
+- * Parse the command line and look for 'ethX=...' fields, and register all
+- * those fields. They will be later initialized in iss_net_init.
+- */
+-
+-#define ERR KERN_ERR "iss_net_setup: "
+-
+-static int iss_net_setup(char *str)
+-{
+-	struct iss_net_private *device = NULL;
+-	struct iss_net_init *new;
+-	struct list_head *ele;
+-	char *end;
+-	int n;
+-
+-	n = simple_strtoul(str, &end, 0);
+-	if (end == str) {
+-		printk(ERR "Failed to parse '%s'\n", str);
+-		return 1;
+-	}
+-	if (n < 0) {
+-		printk(ERR "Device %d is negative\n", n);
+-		return 1;
+-	}
+-	if (*(str = end) != '=') {
+-		printk(ERR "Expected '=' after device number\n");
+-		return 1;
+-	}
+-
+-	spin_lock(&devices_lock);
+-
+-	list_for_each(ele, &devices) {
+-		device = list_entry(ele, struct iss_net_private, device_list);
+-		if (device->index == n)
+-			break;
+-	}
+-
+-	spin_unlock(&devices_lock);
+-
+-	if (device && device->index == n) {
+-		printk(ERR "Device %d already configured\n", n);
+-		return 1;
+-	}
+-
+-	if ((new = alloc_bootmem(sizeof new)) == NULL) {
+-		printk("Alloc_bootmem failed\n");
+-		return 1;
+-	}
+-
+-	INIT_LIST_HEAD(&new->list);
+-	new->index = n;
+-	new->init = str + 1;
+-
+-	list_add_tail(&new->list, &eth_cmd_line);
+-	return 1;
+-}
+-
+-#undef ERR
+-
+-__setup("eth=", iss_net_setup);
+-
+-/*
+- * Initialize all ISS Ethernet devices previously registered in iss_net_setup.
+- */
+-
+-static int iss_net_init(void)
+-{
+-	struct list_head *ele, *next;
+-
+-	/* Walk through all Ethernet devices specified in the command line. */
+-
+-	list_for_each_safe(ele, next, &eth_cmd_line) {
+-		struct iss_net_init *eth;
+-		eth = list_entry(ele, struct iss_net_init, list);
+-		iss_net_configure(eth->index, eth->init);
+-	}
+-
+-	return 1;
+-}
+-
+-module_init(iss_net_init);
+-
+diff --git a/arch/xtensa/platform-iss/setup.c b/arch/xtensa/platform-iss/setup.c
+deleted file mode 100644
+index f60c8cf..0000000
+--- a/arch/xtensa/platform-iss/setup.c
++++ /dev/null
+@@ -1,110 +0,0 @@
+-/*
+- *
+- * arch/xtensa/platform-iss/setup.c
+- *
+- * Platform specific initialization.
+- *
+- * Authors: Chris Zankel <chris at zankel.net>
+- *          Joe Taylor <joe at tensilica.com>
+- *
+- * Copyright 2001 - 2005 Tensilica Inc.
+- *
+- * This program is free software; you can redistribute  it and/or modify it
+- * under  the terms of  the GNU General  Public License as published by the
+- * Free Software Foundation;  either version 2 of the  License, or (at your
+- * option) any later version.
+- *
+- */
+-#include <linux/stddef.h>
+-#include <linux/kernel.h>
+-#include <linux/init.h>
+-#include <linux/errno.h>
+-#include <linux/reboot.h>
+-#include <linux/kdev_t.h>
+-#include <linux/types.h>
+-#include <linux/major.h>
+-#include <linux/blkdev.h>
+-#include <linux/console.h>
+-#include <linux/delay.h>
+-#include <linux/stringify.h>
+-#include <linux/notifier.h>
+-
+-#include <asm/platform.h>
+-#include <asm/bootparam.h>
+-
+-
+-void __init platform_init(bp_tag_t* bootparam)
+-{
+-
+-}
+-
+-void platform_halt(void)
+-{
+-	printk (" ** Called platform_halt(), looping forever! **\n");
+-	while (1);
+-}
+-
+-void platform_power_off(void)
+-{
+-	printk (" ** Called platform_power_off(), looping forever! **\n");
+-	while (1);
+-}
+-void platform_restart(void)
+-{
+-	/* Flush and reset the mmu, simulate a processor reset, and
+-	 * jump to the reset vector. */
+-
+-	__asm__ __volatile__("movi	a2, 15\n\t"
+-			     "wsr	a2, " __stringify(ICOUNTLEVEL) "\n\t"
+-			     "movi	a2, 0\n\t"
+-			     "wsr	a2, " __stringify(ICOUNT) "\n\t"
+-			     "wsr	a2, " __stringify(IBREAKENABLE) "\n\t"
+-			     "wsr	a2, " __stringify(LCOUNT) "\n\t"
+-			     "movi	a2, 0x1f\n\t"
+-			     "wsr	a2, " __stringify(PS) "\n\t"
+-			     "isync\n\t"
+-			     "jx	%0\n\t"
+-			     :
+-			     : "a" (XCHAL_RESET_VECTOR_VADDR)
+-			     : "a2");
+-
+-	/* control never gets here */
+-}
+-
+-extern void iss_net_poll(void);
+-
+-const char twirl[]="|/-\\|/-\\";
+-
+-void platform_heartbeat(void)
+-{
+-#if 0
+-	static int i = 0, j = 0;
+-
+-	if (--i < 0) {
+-		i = 99;
+-		printk("\r%c\r", twirl[j++]);
+-		if (j == 8)
+-			j = 0;
+-	}
+-#endif
+-}
+-
+-
+-
+-static int
+-iss_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
+-{
+-	__asm__ __volatile__("movi a2, -1; simcall\n");
+-	return NOTIFY_DONE;
+-}
+-
+-static struct notifier_block iss_panic_block = {
+-	iss_panic_event,
+-	NULL,
+-	0
+-};
+-
+-void __init platform_setup(char **p_cmdline)
+-{
+-	atomic_notifier_chain_register(&panic_notifier_list, &iss_panic_block);
+-}
+diff --git a/arch/xtensa/platforms/iss/Makefile b/arch/xtensa/platforms/iss/Makefile
+new file mode 100644
+index 0000000..af96e31
+--- /dev/null
++++ b/arch/xtensa/platforms/iss/Makefile
+@@ -0,0 +1,8 @@
++# $Id: Makefile,v 1.1.1.1 2002/08/28 16:10:14 aroll Exp $
++#
++# Makefile for the Xtensa Instruction Set Simulator (ISS)
++# "prom monitor" library routines under Linux.
++#
++
++obj-y			= io.o console.o setup.o network.o
++
+diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c
+new file mode 100644
+index 0000000..9141e36
+--- /dev/null
++++ b/arch/xtensa/platforms/iss/console.c
+@@ -0,0 +1,297 @@
++/*
++ * arch/xtensa/platform-iss/console.c
++ *
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2001-2005 Tensilica Inc.
++ *   Authors	Christian Zankel, Joe Taylor
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/console.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/mm.h>
++#include <linux/major.h>
++#include <linux/param.h>
++#include <linux/serial.h>
++#include <linux/serialP.h>
++
++#include <asm/uaccess.h>
++#include <asm/irq.h>
++
++#include <asm/platform/simcall.h>
++
++#include <linux/tty.h>
++#include <linux/tty_flip.h>
++
++#ifdef SERIAL_INLINE
++#define _INLINE_ inline
++#endif
++
++#define SERIAL_MAX_NUM_LINES 1
++#define SERIAL_TIMER_VALUE (20 * HZ)
++
++static struct tty_driver *serial_driver;
++static struct timer_list serial_timer;
++
++static DEFINE_SPINLOCK(timer_lock);
++
++int errno;
++
++static int __simc (int a, int b, int c, int d, int e, int f) __attribute__((__noinline__));
++static int __simc (int a, int b, int c, int d, int e, int f)
++{
++	int ret;
++	__asm__ __volatile__ ("simcall\n"
++			"mov %0, a2\n"
++			"mov %1, a3\n" : "=a" (ret), "=a" (errno)
++			: : "a2", "a3");
++	return ret;
++}
++
++static char *serial_version = "0.1";
++static char *serial_name = "ISS serial driver";
++
++/*
++ * This routine is called whenever a serial port is opened.  It
++ * enables interrupts for a serial port, linking in its async structure into
++ * the IRQ chain.   It also performs the serial-specific
++ * initialization for the tty structure.
++ */
++
++static void rs_poll(unsigned long);
++
++static int rs_open(struct tty_struct *tty, struct file * filp)
++{
++	int line = tty->index;
++
++	if ((line < 0) || (line >= SERIAL_MAX_NUM_LINES))
++		return -ENODEV;
++
++	spin_lock(&timer_lock);
++
++	if (tty->count == 1) {
++		init_timer(&serial_timer);
++		serial_timer.data = (unsigned long) tty;
++		serial_timer.function = rs_poll;
++		mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE);
++	}
++	spin_unlock(&timer_lock);
++
++	return 0;
++}
++
++
++/*
++ * ------------------------------------------------------------
++ * iss_serial_close()
++ *
++ * This routine is called when the serial port gets closed.  First, we
++ * wait for the last remaining data to be sent.  Then, we unlink its
++ * async structure from the interrupt chain if necessary, and we free
++ * that IRQ if nothing is left in the chain.
++ * ------------------------------------------------------------
++ */
++static void rs_close(struct tty_struct *tty, struct file * filp)
++{
++	spin_lock(&timer_lock);
++	if (tty->count == 1)
++		del_timer_sync(&serial_timer);
++	spin_unlock(&timer_lock);
++}
++
++
++static int rs_write(struct tty_struct * tty,
++		    const unsigned char *buf, int count)
++{
++	/* see drivers/char/serialX.c to reference original version */
++
++	__simc (SYS_write, 1, (unsigned long)buf, count, 0, 0);
++	return count;
++}
++
++static void rs_poll(unsigned long priv)
++{
++	struct tty_struct* tty = (struct tty_struct*) priv;
++
++	struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
++	int i = 0;
++	unsigned char c;
++
++	spin_lock(&timer_lock);
++
++	while (__simc(SYS_select_one, 0, XTISS_SELECT_ONE_READ, (int)&tv,0,0)){
++		__simc (SYS_read, 0, (unsigned long)&c, 1, 0, 0);
++		tty_insert_flip_char(tty, c, TTY_NORMAL);
++		i++;
++	}
++
++	if (i)
++		tty_flip_buffer_push(tty);
++
++
++	mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE);
++	spin_unlock(&timer_lock);
++}
++
++
++static void rs_put_char(struct tty_struct *tty, unsigned char ch)
++{
++	char buf[2];
++
++	if (!tty)
++		return;
++
++	buf[0] = ch;
++	buf[1] = '\0';		/* Is this NULL necessary? */
++	__simc (SYS_write, 1, (unsigned long) buf, 1, 0, 0);
++}
++
++static void rs_flush_chars(struct tty_struct *tty)
++{
++}
++
++static int rs_write_room(struct tty_struct *tty)
++{
++	/* Let's say iss can always accept 2K characters.. */
++	return 2 * 1024;
++}
++
++static int rs_chars_in_buffer(struct tty_struct *tty)
++{
++	/* the iss doesn't buffer characters */
++	return 0;
++}
++
++static void rs_hangup(struct tty_struct *tty)
++{
++	/* Stub, once again.. */
++}
++
++static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
++{
++	/* Stub, once again.. */
++}
++
++static int rs_read_proc(char *page, char **start, off_t off, int count,
++			int *eof, void *data)
++{
++	int len = 0;
++	off_t begin = 0;
++
++	len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
++	*eof = 1;
++
++	if (off >= len + begin)
++		return 0;
++
++	*start = page + (off - begin);
++	return ((count < begin + len - off) ? count : begin + len - off);
++}
++
++
++static struct tty_operations serial_ops = {
++	.open = rs_open,
++	.close = rs_close,
++	.write = rs_write,
++	.put_char = rs_put_char,
++	.flush_chars = rs_flush_chars,
++	.write_room = rs_write_room,
++	.chars_in_buffer = rs_chars_in_buffer,
++	.hangup = rs_hangup,
++	.wait_until_sent = rs_wait_until_sent,
++	.read_proc = rs_read_proc
++};
++
++int __init rs_init(void)
++{
++	serial_driver = alloc_tty_driver(1);
++
++	printk ("%s %s\n", serial_name, serial_version);
++
++	/* Initialize the tty_driver structure */
++
++	serial_driver->owner = THIS_MODULE;
++	serial_driver->driver_name = "iss_serial";
++	serial_driver->name = "ttyS";
++	serial_driver->major = TTY_MAJOR;
++	serial_driver->minor_start = 64;
++	serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
++	serial_driver->subtype = SERIAL_TYPE_NORMAL;
++	serial_driver->init_termios = tty_std_termios;
++	serial_driver->init_termios.c_cflag =
++		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
++	serial_driver->flags = TTY_DRIVER_REAL_RAW;
++
++	tty_set_operations(serial_driver, &serial_ops);
++
++	if (tty_register_driver(serial_driver))
++		panic("Couldn't register serial driver\n");
++	return 0;
++}
++
++
++static __exit void rs_exit(void)
++{
++	int error;
++
++	if ((error = tty_unregister_driver(serial_driver)))
++		printk("ISS_SERIAL: failed to unregister serial driver (%d)\n",
++		       error);
++	put_tty_driver(serial_driver);
++}
++
++
++/* We use `late_initcall' instead of just `__initcall' as a workaround for
++ * the fact that (1) simcons_tty_init can't be called before tty_init,
++ * (2) tty_init is called via `module_init', (3) if statically linked,
++ * module_init == device_init, and (4) there's no ordering of init lists.
++ * We can do this easily because simcons is always statically linked, but
++ * other tty drivers that depend on tty_init and which must use
++ * `module_init' to declare their init routines are likely to be broken.
++ */
++
++late_initcall(rs_init);
++
++
++#ifdef CONFIG_SERIAL_CONSOLE
++
++static void iss_console_write(struct console *co, const char *s, unsigned count)
++{
++	int len = strlen(s);
++
++	if (s != 0 && *s != 0)
++		__simc (SYS_write, 1, (unsigned long)s,
++			count < len ? count : len,0,0);
++}
++
++static struct tty_driver* iss_console_device(struct console *c, int *index)
++{
++	*index = c->index;
++	return serial_driver;
++}
++
++
++static struct console sercons = {
++	.name = "ttyS",
++	.write = iss_console_write,
++	.device = iss_console_device,
++	.flags = CON_PRINTBUFFER,
++	.index = -1
++};
++
++static int __init iss_console_init(void)
++{
++	register_console(&sercons);
++	return 0;
++}
++
++console_initcall(iss_console_init);
++
++#endif /* CONFIG_SERIAL_CONSOLE */
++
+diff --git a/arch/xtensa/platforms/iss/io.c b/arch/xtensa/platforms/iss/io.c
+new file mode 100644
+index 0000000..5b161a5
+--- /dev/null
++++ b/arch/xtensa/platforms/iss/io.c
+@@ -0,0 +1,32 @@
++/* This file isn't really needed right now. */
++
++#if 0
++
++#include <asm/io.h>
++#include <xtensa/simcall.h>
++
++extern int __simc ();
++
++
++char iss_serial_getc()
++{
++  char c;
++  __simc( SYS_read, 0, &c, 1 );
++  return c;
++}
++
++void iss_serial_putc( char c )
++{
++  __simc( SYS_write, 1, &c, 1 );
++}
++
++void iss_serial_puts( char *s )
++{
++  if( s != 0 && *s != 0 )
++    __simc( SYS_write, 1, s, strlen(s) );
++}
++
++/*#error Need I/O ports to specific hardware!*/
++
++#endif
++
+diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c
+new file mode 100644
+index 0000000..a2e2522
+--- /dev/null
++++ b/arch/xtensa/platforms/iss/network.c
+@@ -0,0 +1,823 @@
++/*
++ *
++ * arch/xtensa/platform-iss/network.c
++ *
++ * Platform specific initialization.
++ *
++ * Authors: Chris Zankel <chris at zankel.net>
++ * Based on work form the UML team.
++ *
++ * Copyright 2005 Tensilica Inc.
++ *
++ * This program is free software; you can redistribute  it and/or modify it
++ * under  the terms of  the GNU General  Public License as published by the
++ * Free Software Foundation;  either version 2 of the  License, or (at your
++ * option) any later version.
++ *
++ */
++
++#include <linux/list.h>
++#include <linux/irq.h>
++#include <linux/spinlock.h>
++#include <linux/slab.h>
++#include <linux/timer.h>
++#include <linux/if_ether.h>
++#include <linux/inetdevice.h>
++#include <linux/init.h>
++#include <linux/if_tun.h>
++#include <linux/etherdevice.h>
++#include <linux/interrupt.h>
++#include <linux/ioctl.h>
++#include <linux/bootmem.h>
++#include <linux/ethtool.h>
++#include <linux/rtnetlink.h>
++#include <linux/platform_device.h>
++
++#include <asm/platform/simcall.h>
++
++#define DRIVER_NAME "iss-netdev"
++#define ETH_MAX_PACKET 1500
++#define ETH_HEADER_OTHER 14
++#define ISS_NET_TIMER_VALUE (2 * HZ)
++
++
++static DEFINE_SPINLOCK(opened_lock);
++static LIST_HEAD(opened);
++
++static DEFINE_SPINLOCK(devices_lock);
++static LIST_HEAD(devices);
++
++/* ------------------------------------------------------------------------- */
++
++/* We currently only support the TUNTAP transport protocol. */
++
++#define TRANSPORT_TUNTAP_NAME "tuntap"
++#define TRANSPORT_TUNTAP_MTU ETH_MAX_PACKET
++
++struct tuntap_info {
++	char dev_name[IFNAMSIZ];
++	int fixed_config;
++	unsigned char gw[ETH_ALEN];
++	int fd;
++};
++
++/* ------------------------------------------------------------------------- */
++
++
++/* This structure contains out private information for the driver. */
++
++struct iss_net_private {
++
++	struct list_head device_list;
++	struct list_head opened_list;
++
++	spinlock_t lock;
++	struct net_device *dev;
++	struct platform_device pdev;
++	struct timer_list tl;
++	struct net_device_stats stats;
++
++	struct timer_list timer;
++	unsigned int timer_val;
++
++	int index;
++	int mtu;
++
++	unsigned char mac[ETH_ALEN];
++	int have_mac;
++
++	struct {
++		union {
++			struct tuntap_info tuntap;
++		} info;
++
++		int (*open)(struct iss_net_private *lp);
++		void (*close)(struct iss_net_private *lp);
++		int (*read)(struct iss_net_private *lp, struct sk_buff **skb);
++		int (*write)(struct iss_net_private *lp, struct sk_buff **skb);
++		unsigned short (*protocol)(struct sk_buff *skb);
++		int (*poll)(struct iss_net_private *lp);
++	} tp;
++
++};
++
++/* ======================= ISS SIMCALL INTERFACE =========================== */
++
++/* Note: __simc must _not_ be declared inline! */
++
++static int errno;
++
++static int __simc (int a, int b, int c, int d, int e, int f) __attribute__((__noinline__));
++static int __simc (int a, int b, int c, int d, int e, int f)
++{
++	int ret;
++	__asm__ __volatile__ ("simcall\n"
++	    		      "mov %0, a2\n"
++			      "mov %1, a3\n" : "=a" (ret), "=a" (errno)
++			      : : "a2", "a3");
++	return ret;
++}
++
++static int inline simc_open(char *file, int flags, int mode)
++{
++	return __simc(SYS_open, (int) file, flags, mode, 0, 0);
++}
++
++static int inline simc_close(int fd)
++{
++	return __simc(SYS_close, fd, 0, 0, 0, 0);
++}
++
++static int inline simc_ioctl(int fd, int request, void *arg)
++{
++	return __simc(SYS_ioctl, fd, request, (int) arg, 0, 0);
++}
++
++static int inline simc_read(int fd, void *buf, size_t count)
++{
++	return __simc(SYS_read, fd, (int) buf, count, 0, 0);
++}
++
++static int inline simc_write(int fd, void *buf, size_t count)
++{
++	return __simc(SYS_write, fd, (int) buf, count, 0, 0);
++}
++
++static int inline simc_poll(int fd)
++{
++	struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
++
++	return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&tv,0,0);
++}
++
++/* ================================ HELPERS ================================ */
++
++
++static char *split_if_spec(char *str, ...)
++{
++	char **arg, *end;
++	va_list ap;
++
++	va_start(ap, str);
++	while ((arg = va_arg(ap, char**)) != NULL) {
++		if (*str == '\0')
++			return NULL;
++		end = strchr(str, ',');
++		if (end != str)
++			*arg = str;
++		if (end == NULL)
++			return NULL;
++		*end ++ = '\0';
++		str = end;
++	}
++	va_end(ap);
++	return str;
++}
++
++
++#if 0
++/* Adjust SKB. */
++
++struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
++{
++	if ((skb != NULL) && (skb_tailroom(skb) < extra)) {
++		struct sk_buff *skb2;
++
++		skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
++		dev_kfree_skb(skb);
++		skb = skb2;
++	}
++	if (skb != NULL)
++		skb_put(skb, extra);
++
++	return skb;
++}
++#endif
++
++/* Return the IP address as a string for a given device. */
++
++static void dev_ip_addr(void *d, char *buf, char *bin_buf)
++{
++	struct net_device *dev = d;
++	struct in_device *ip = dev->ip_ptr;
++	struct in_ifaddr *in;
++	__be32 addr;
++
++	if ((ip == NULL) || ((in = ip->ifa_list) == NULL)) {
++		printk(KERN_WARNING "Device not assigned an IP address!\n");
++		return;
++	}
++
++	addr = in->ifa_address;
++	sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff,
++		(addr >> 16) & 0xff, addr >> 24);
++
++	if (bin_buf) {
++		bin_buf[0] = addr & 0xff;
++		bin_buf[1] = (addr >> 8) & 0xff;
++		bin_buf[2] = (addr >> 16) & 0xff;
++		bin_buf[3] = addr >> 24;
++	}
++}
++
++/* Set Ethernet address of the specified device. */
++
++static void inline set_ether_mac(void *d, unsigned char *addr)
++{
++	struct net_device *dev = d;
++	memcpy(dev->dev_addr, addr, ETH_ALEN);
++}
++
++
++/* ======================= TUNTAP TRANSPORT INTERFACE ====================== */
++
++static int tuntap_open(struct iss_net_private *lp)
++{
++	struct ifreq ifr;
++	char *dev_name = lp->tp.info.tuntap.dev_name;
++	int err = -EINVAL;
++	int fd;
++
++	/* We currently only support a fixed configuration. */
++
++	if (!lp->tp.info.tuntap.fixed_config)
++		return -EINVAL;
++
++	if ((fd = simc_open("/dev/net/tun", 02, 0)) < 0) {	/* O_RDWR */
++		printk("Failed to open /dev/net/tun, returned %d "
++		       "(errno = %d)\n", fd, errno);
++		return fd;
++	}
++
++	memset(&ifr, 0, sizeof ifr);
++	ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
++	strlcpy(ifr.ifr_name, dev_name, sizeof ifr.ifr_name);
++
++	if ((err = simc_ioctl(fd, TUNSETIFF, (void*) &ifr)) < 0) {
++		printk("Failed to set interface, returned %d "
++		       "(errno = %d)\n", err, errno);
++		simc_close(fd);
++		return err;
++	}
++
++	lp->tp.info.tuntap.fd = fd;
++	return err;
++}
++
++static void tuntap_close(struct iss_net_private *lp)
++{
++#if 0
++	if (lp->tp.info.tuntap.fixed_config)
++		iter_addresses(lp->tp.info.tuntap.dev, close_addr, lp->host.dev_name);
++#endif
++	simc_close(lp->tp.info.tuntap.fd);
++	lp->tp.info.tuntap.fd = -1;
++}
++
++static int tuntap_read (struct iss_net_private *lp, struct sk_buff **skb)
++{
++#if 0
++	*skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
++	if (*skb == NULL)
++		return -ENOMEM;
++#endif
++
++	return simc_read(lp->tp.info.tuntap.fd,
++			(*skb)->data, (*skb)->dev->mtu + ETH_HEADER_OTHER);
++}
++
++static int tuntap_write (struct iss_net_private *lp, struct sk_buff **skb)
++{
++	return simc_write(lp->tp.info.tuntap.fd, (*skb)->data, (*skb)->len);
++}
++
++unsigned short tuntap_protocol(struct sk_buff *skb)
++{
++	return eth_type_trans(skb, skb->dev);
++}
++
++static int tuntap_poll(struct iss_net_private *lp)
++{
++	return simc_poll(lp->tp.info.tuntap.fd);
++}
++
++/*
++ * Currently only a device name is supported.
++ * ethX=tuntap[,[mac address][,[device name]]]
++ */
++
++static int tuntap_probe(struct iss_net_private *lp, int index, char *init)
++{
++	const int len = strlen(TRANSPORT_TUNTAP_NAME);
++	char *dev_name = NULL, *mac_str = NULL, *rem = NULL;
++
++	/* Transport should be 'tuntap': ethX=tuntap,mac,dev_name */
++
++	if (strncmp(init, TRANSPORT_TUNTAP_NAME, len))
++		return 0;
++
++	if (*(init += strlen(TRANSPORT_TUNTAP_NAME)) == ',') {
++		if ((rem=split_if_spec(init+1, &mac_str, &dev_name)) != NULL) {
++			printk("Extra garbage on specification : '%s'\n", rem);
++			return 0;
++		}
++	} else if (*init != '\0') {
++		printk("Invalid argument: %s. Skipping device!\n", init);
++		return 0;
++	}
++
++	if (dev_name) {
++		strncpy(lp->tp.info.tuntap.dev_name, dev_name,
++			 sizeof lp->tp.info.tuntap.dev_name);
++		lp->tp.info.tuntap.fixed_config = 1;
++	} else
++		strcpy(lp->tp.info.tuntap.dev_name, TRANSPORT_TUNTAP_NAME);
++
++
++#if 0
++	if (setup_etheraddr(mac_str, lp->mac))
++		lp->have_mac = 1;
++#endif
++	lp->mtu = TRANSPORT_TUNTAP_MTU;
++
++	//lp->info.tuntap.gate_addr = gate_addr;
++
++	lp->tp.info.tuntap.fd = -1;
++
++	lp->tp.open = tuntap_open;
++	lp->tp.close = tuntap_close;
++	lp->tp.read = tuntap_read;
++	lp->tp.write = tuntap_write;
++	lp->tp.protocol = tuntap_protocol;
++	lp->tp.poll = tuntap_poll;
++
++	printk("TUN/TAP backend - ");
++#if 0
++	if (lp->host.gate_addr != NULL)
++		printk("IP = %s", lp->host.gate_addr);
++#endif
++	printk("\n");
++
++	return 1;
++}
++
++/* ================================ ISS NET ================================ */
++
++static int iss_net_rx(struct net_device *dev)
++{
++	struct iss_net_private *lp = dev->priv;
++	int pkt_len;
++	struct sk_buff *skb;
++
++	/* Check if there is any new data. */
++
++	if (lp->tp.poll(lp) == 0)
++		return 0;
++
++	/* Try to allocate memory, if it fails, try again next round. */
++
++	if ((skb = dev_alloc_skb(dev->mtu + 2 + ETH_HEADER_OTHER)) == NULL) {
++		lp->stats.rx_dropped++;
++		return 0;
++	}
++
++	skb_reserve(skb, 2);
++
++	/* Setup skb */
++
++	skb->dev = dev;
++	skb_reset_mac_header(skb);
++	pkt_len = lp->tp.read(lp, &skb);
++	skb_put(skb, pkt_len);
++
++	if (pkt_len > 0) {
++		skb_trim(skb, pkt_len);
++		skb->protocol = lp->tp.protocol(skb);
++
++		lp->stats.rx_bytes += skb->len;
++		lp->stats.rx_packets++;
++	//	netif_rx(skb);
++		netif_rx_ni(skb);
++		return pkt_len;
++	}
++	kfree_skb(skb);
++	return pkt_len;
++}
++
++static int iss_net_poll(void)
++{
++	struct list_head *ele;
++	int err, ret = 0;
++
++	spin_lock(&opened_lock);
++
++	list_for_each(ele, &opened) {
++		struct iss_net_private *lp;
++
++		lp = list_entry(ele, struct iss_net_private, opened_list);
++
++		if (!netif_running(lp->dev))
++			break;
++
++		spin_lock(&lp->lock);
++
++		while ((err = iss_net_rx(lp->dev)) > 0)
++			ret++;
++
++		spin_unlock(&lp->lock);
++
++		if (err < 0) {
++			printk(KERN_ERR "Device '%s' read returned %d, "
++			       "shutting it down\n", lp->dev->name, err);
++			dev_close(lp->dev);
++		} else {
++			// FIXME reactivate_fd(lp->fd, ISS_ETH_IRQ);
++		}
++	}
++
++	spin_unlock(&opened_lock);
++	return ret;
++}
++
++
++static void iss_net_timer(unsigned long priv)
++{
++	struct iss_net_private* lp = (struct iss_net_private*) priv;
++
++	spin_lock(&lp->lock);
++
++	iss_net_poll();
++
++	mod_timer(&lp->timer, jiffies + lp->timer_val);
++
++	spin_unlock(&lp->lock);
++}
++
++
++static int iss_net_open(struct net_device *dev)
++{
++	struct iss_net_private *lp = dev->priv;
++	char addr[sizeof "255.255.255.255\0"];
++	int err;
++
++	spin_lock(&lp->lock);
++
++	if ((err = lp->tp.open(lp)) < 0)
++		goto out;
++
++	if (!lp->have_mac) {
++		dev_ip_addr(dev, addr, &lp->mac[2]);
++		set_ether_mac(dev, lp->mac);
++	}
++
++	netif_start_queue(dev);
++
++	/* clear buffer - it can happen that the host side of the interface
++	 * is full when we get here. In this case, new data is never queued,
++	 * SIGIOs never arrive, and the net never works.
++	 */
++	while ((err = iss_net_rx(dev)) > 0)
++		;
++
++	spin_lock(&opened_lock);
++	list_add(&lp->opened_list, &opened);
++	spin_unlock(&opened_lock);
++
++	init_timer(&lp->timer);
++	lp->timer_val = ISS_NET_TIMER_VALUE;
++	lp->timer.data = (unsigned long) lp;
++	lp->timer.function = iss_net_timer;
++	mod_timer(&lp->timer, jiffies + lp->timer_val);
++
++out:
++	spin_unlock(&lp->lock);
++	return err;
++}
++
++static int iss_net_close(struct net_device *dev)
++{
++	struct iss_net_private *lp = dev->priv;
++printk("iss_net_close!\n");
++	netif_stop_queue(dev);
++	spin_lock(&lp->lock);
++
++	spin_lock(&opened_lock);
++	list_del(&opened);
++	spin_unlock(&opened_lock);
++
++	del_timer_sync(&lp->timer);
++
++	lp->tp.close(lp);
++
++	spin_unlock(&lp->lock);
++	return 0;
++}
++
++static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++	struct iss_net_private *lp = dev->priv;
++	unsigned long flags;
++	int len;
++
++	netif_stop_queue(dev);
++	spin_lock_irqsave(&lp->lock, flags);
++
++	len = lp->tp.write(lp, &skb);
++
++	if (len == skb->len) {
++		lp->stats.tx_packets++;
++		lp->stats.tx_bytes += skb->len;
++		dev->trans_start = jiffies;
++		netif_start_queue(dev);
++
++		/* this is normally done in the interrupt when tx finishes */
++		netif_wake_queue(dev);
++
++	} else if (len == 0) {
++		netif_start_queue(dev);
++		lp->stats.tx_dropped++;
++
++	} else {
++		netif_start_queue(dev);
++		printk(KERN_ERR "iss_net_start_xmit: failed(%d)\n", len);
++	}
++
++	spin_unlock_irqrestore(&lp->lock, flags);
++
++	dev_kfree_skb(skb);
++	return 0;
++}
++
++
++static struct net_device_stats *iss_net_get_stats(struct net_device *dev)
++{
++	struct iss_net_private *lp = dev->priv;
++	return &lp->stats;
++}
++
++static void iss_net_set_multicast_list(struct net_device *dev)
++{
++#if 0
++	if (dev->flags & IFF_PROMISC)
++		return;
++	else if (dev->mc_count)
++		dev->flags |= IFF_ALLMULTI;
++	else
++		dev->flags &= ~IFF_ALLMULTI;
++#endif
++}
++
++static void iss_net_tx_timeout(struct net_device *dev)
++{
++#if 0
++	dev->trans_start = jiffies;
++	netif_wake_queue(dev);
++#endif
++}
++
++static int iss_net_set_mac(struct net_device *dev, void *addr)
++{
++#if 0
++	struct iss_net_private *lp = dev->priv;
++	struct sockaddr *hwaddr = addr;
++
++	spin_lock(&lp->lock);
++	memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN);
++	spin_unlock(&lp->lock);
++#endif
++
++	return 0;
++}
++
++static int iss_net_change_mtu(struct net_device *dev, int new_mtu)
++{
++#if 0
++	struct iss_net_private *lp = dev->priv;
++	int err = 0;
++
++	spin_lock(&lp->lock);
++
++	// FIXME not needed new_mtu = transport_set_mtu(new_mtu, &lp->user);
++
++	if (new_mtu < 0)
++		err = new_mtu;
++	else
++		dev->mtu = new_mtu;
++
++	spin_unlock(&lp->lock);
++	return err;
++#endif
++	return -EINVAL;
++}
++
++void iss_net_user_timer_expire(unsigned long _conn)
++{
++}
++
++
++static struct platform_driver iss_net_driver = {
++	.driver = {
++		.name  = DRIVER_NAME,
++	},
++};
++
++static int driver_registered;
++
++static int iss_net_configure(int index, char *init)
++{
++	struct net_device *dev;
++	struct iss_net_private *lp;
++	int err;
++
++	if ((dev = alloc_etherdev(sizeof *lp)) == NULL) {
++		printk(KERN_ERR "eth_configure: failed to allocate device\n");
++		return 1;
++	}
++
++	/* Initialize private element. */
++
++	lp = dev->priv;
++	*lp = ((struct iss_net_private) {
++		.device_list		= LIST_HEAD_INIT(lp->device_list),
++		.opened_list		= LIST_HEAD_INIT(lp->opened_list),
++		.lock			= SPIN_LOCK_UNLOCKED,
++		.dev			= dev,
++		.index			= index,
++		//.fd                   = -1,
++		.mac			= { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0 },
++		.have_mac		= 0,
++		});
++
++	/*
++	 * Try all transport protocols.
++	 * Note: more protocols can be added by adding '&& !X_init(lp, eth)'.
++	 */
++
++	if (!tuntap_probe(lp, index, init)) {
++		printk("Invalid arguments. Skipping device!\n");
++		goto errout;
++	}
++
++	printk(KERN_INFO "Netdevice %d ", index);
++	if (lp->have_mac)
++		printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
++				lp->mac[0], lp->mac[1],
++				lp->mac[2], lp->mac[3],
++				lp->mac[4], lp->mac[5]);
++	printk(": ");
++
++	/* sysfs register */
++
++	if (!driver_registered) {
++		platform_driver_register(&iss_net_driver);
++		driver_registered = 1;
++	}
++
++	spin_lock(&devices_lock);
++	list_add(&lp->device_list, &devices);
++	spin_unlock(&devices_lock);
++
++	lp->pdev.id = index;
++	lp->pdev.name = DRIVER_NAME;
++	platform_device_register(&lp->pdev);
++	SET_NETDEV_DEV(dev,&lp->pdev.dev);
++
++	/*
++	 * If this name ends up conflicting with an existing registered
++	 * netdevice, that is OK, register_netdev{,ice}() will notice this
++	 * and fail.
++	 */
++	snprintf(dev->name, sizeof dev->name, "eth%d", index);
++
++	dev->mtu = lp->mtu;
++	dev->open = iss_net_open;
++	dev->hard_start_xmit = iss_net_start_xmit;
++	dev->stop = iss_net_close;
++	dev->get_stats = iss_net_get_stats;
++	dev->set_multicast_list = iss_net_set_multicast_list;
++	dev->tx_timeout = iss_net_tx_timeout;
++	dev->set_mac_address = iss_net_set_mac;
++	dev->change_mtu = iss_net_change_mtu;
++	dev->watchdog_timeo = (HZ >> 1);
++	dev->irq = -1;
++
++	rtnl_lock();
++	err = register_netdevice(dev);
++	rtnl_unlock();
++
++	if (err) {
++		printk("Error registering net device!\n");
++		/* XXX: should we call ->remove() here? */
++		free_netdev(dev);
++		return 1;
++	}
++
++	init_timer(&lp->tl);
++	lp->tl.function = iss_net_user_timer_expire;
++
++#if 0
++	if (lp->have_mac)
++		set_ether_mac(dev, lp->mac);
++#endif
++	return 0;
++
++errout:
++	// FIXME: unregister; free, etc..
++	return -EIO;
++
++}
++
++/* ------------------------------------------------------------------------- */
++
++/* Filled in during early boot */
++
++struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line);
++
++struct iss_net_init {
++	struct list_head list;
++	char *init;		/* init string */
++	int index;
++};
++
++/*
++ * Parse the command line and look for 'ethX=...' fields, and register all
++ * those fields. They will be later initialized in iss_net_init.
++ */
++
++#define ERR KERN_ERR "iss_net_setup: "
++
++static int iss_net_setup(char *str)
++{
++	struct iss_net_private *device = NULL;
++	struct iss_net_init *new;
++	struct list_head *ele;
++	char *end;
++	int n;
++
++	n = simple_strtoul(str, &end, 0);
++	if (end == str) {
++		printk(ERR "Failed to parse '%s'\n", str);
++		return 1;
++	}
++	if (n < 0) {
++		printk(ERR "Device %d is negative\n", n);
++		return 1;
++	}
++	if (*(str = end) != '=') {
++		printk(ERR "Expected '=' after device number\n");
++		return 1;
++	}
++
++	spin_lock(&devices_lock);
++
++	list_for_each(ele, &devices) {
++		device = list_entry(ele, struct iss_net_private, device_list);
++		if (device->index == n)
++			break;
++	}
++
++	spin_unlock(&devices_lock);
++
++	if (device && device->index == n) {
++		printk(ERR "Device %d already configured\n", n);
++		return 1;
++	}
++
++	if ((new = alloc_bootmem(sizeof new)) == NULL) {
++		printk("Alloc_bootmem failed\n");
++		return 1;
++	}
++
++	INIT_LIST_HEAD(&new->list);
++	new->index = n;
++	new->init = str + 1;
++
++	list_add_tail(&new->list, &eth_cmd_line);
++	return 1;
++}
++
++#undef ERR
++
++__setup("eth=", iss_net_setup);
++
++/*
++ * Initialize all ISS Ethernet devices previously registered in iss_net_setup.
++ */
++
++static int iss_net_init(void)
++{
++	struct list_head *ele, *next;
++
++	/* Walk through all Ethernet devices specified in the command line. */
++
++	list_for_each_safe(ele, next, &eth_cmd_line) {
++		struct iss_net_init *eth;
++		eth = list_entry(ele, struct iss_net_init, list);
++		iss_net_configure(eth->index, eth->init);
++	}
++
++	return 1;
++}
++
++module_init(iss_net_init);
++
+diff --git a/arch/xtensa/platforms/iss/setup.c b/arch/xtensa/platforms/iss/setup.c
+new file mode 100644
+index 0000000..f60c8cf
+--- /dev/null
++++ b/arch/xtensa/platforms/iss/setup.c
+@@ -0,0 +1,110 @@
++/*
++ *
++ * arch/xtensa/platform-iss/setup.c
++ *
++ * Platform specific initialization.
++ *
++ * Authors: Chris Zankel <chris at zankel.net>
++ *          Joe Taylor <joe at tensilica.com>
++ *
++ * Copyright 2001 - 2005 Tensilica Inc.
++ *
++ * This program is free software; you can redistribute  it and/or modify it
++ * under  the terms of  the GNU General  Public License as published by the
++ * Free Software Foundation;  either version 2 of the  License, or (at your
++ * option) any later version.
++ *
++ */
++#include <linux/stddef.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/errno.h>
++#include <linux/reboot.h>
++#include <linux/kdev_t.h>
++#include <linux/types.h>
++#include <linux/major.h>
++#include <linux/blkdev.h>
++#include <linux/console.h>
++#include <linux/delay.h>
++#include <linux/stringify.h>
++#include <linux/notifier.h>
++
++#include <asm/platform.h>
++#include <asm/bootparam.h>
++
++
++void __init platform_init(bp_tag_t* bootparam)
++{
++
++}
++
++void platform_halt(void)
++{
++	printk (" ** Called platform_halt(), looping forever! **\n");
++	while (1);
++}
++
++void platform_power_off(void)
++{
++	printk (" ** Called platform_power_off(), looping forever! **\n");
++	while (1);
++}
++void platform_restart(void)
++{
++	/* Flush and reset the mmu, simulate a processor reset, and
++	 * jump to the reset vector. */
++
++	__asm__ __volatile__("movi	a2, 15\n\t"
++			     "wsr	a2, " __stringify(ICOUNTLEVEL) "\n\t"
++			     "movi	a2, 0\n\t"
++			     "wsr	a2, " __stringify(ICOUNT) "\n\t"
++			     "wsr	a2, " __stringify(IBREAKENABLE) "\n\t"
++			     "wsr	a2, " __stringify(LCOUNT) "\n\t"
++			     "movi	a2, 0x1f\n\t"
++			     "wsr	a2, " __stringify(PS) "\n\t"
++			     "isync\n\t"
++			     "jx	%0\n\t"
++			     :
++			     : "a" (XCHAL_RESET_VECTOR_VADDR)
++			     : "a2");
++
++	/* control never gets here */
++}
++
++extern void iss_net_poll(void);
++
++const char twirl[]="|/-\\|/-\\";
++
++void platform_heartbeat(void)
++{
++#if 0
++	static int i = 0, j = 0;
++
++	if (--i < 0) {
++		i = 99;
++		printk("\r%c\r", twirl[j++]);
++		if (j == 8)
++			j = 0;
++	}
++#endif
++}
++
++
++
++static int
++iss_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
++{
++	__asm__ __volatile__("movi a2, -1; simcall\n");
++	return NOTIFY_DONE;
++}
++
++static struct notifier_block iss_panic_block = {
++	iss_panic_event,
++	NULL,
++	0
++};
++
++void __init platform_setup(char **p_cmdline)
++{
++	atomic_notifier_chain_register(&panic_notifier_list, &iss_panic_block);
++}
+diff --git a/block/blk-core.c b/block/blk-core.c
+index e9754dc..775c851 100644
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -38,7 +38,7 @@ static int __make_request(struct request_queue *q, struct bio *bio);
+ /*
+  * For the allocated request tables
+  */
+-struct kmem_cache *request_cachep;
++static struct kmem_cache *request_cachep;
+ 
+ /*
+  * For queue allocation
+@@ -127,6 +127,7 @@ void rq_init(struct request_queue *q, struct request *rq)
+ 	rq->nr_hw_segments = 0;
+ 	rq->ioprio = 0;
+ 	rq->special = NULL;
++	rq->raw_data_len = 0;
+ 	rq->buffer = NULL;
+ 	rq->tag = -1;
+ 	rq->errors = 0;
+@@ -2015,6 +2016,7 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
+ 	rq->hard_cur_sectors = rq->current_nr_sectors;
+ 	rq->hard_nr_sectors = rq->nr_sectors = bio_sectors(bio);
+ 	rq->buffer = bio_data(bio);
++	rq->raw_data_len = bio->bi_size;
+ 	rq->data_len = bio->bi_size;
+ 
+ 	rq->bio = rq->biotail = bio;
+diff --git a/block/blk-ioc.c b/block/blk-ioc.c
+index 80245dc..e34df7c 100644
+--- a/block/blk-ioc.c
++++ b/block/blk-ioc.c
+@@ -17,17 +17,13 @@ static struct kmem_cache *iocontext_cachep;
+ 
+ static void cfq_dtor(struct io_context *ioc)
+ {
+-	struct cfq_io_context *cic[1];
+-	int r;
++	if (!hlist_empty(&ioc->cic_list)) {
++		struct cfq_io_context *cic;
+ 
+-	/*
+-	 * We don't have a specific key to lookup with, so use the gang
+-	 * lookup to just retrieve the first item stored. The cfq exit
+-	 * function will iterate the full tree, so any member will do.
+-	 */
+-	r = radix_tree_gang_lookup(&ioc->radix_root, (void **) cic, 0, 1);
+-	if (r > 0)
+-		cic[0]->dtor(ioc);
++		cic = list_entry(ioc->cic_list.first, struct cfq_io_context,
++								cic_list);
++		cic->dtor(ioc);
++	}
+ }
+ 
+ /*
+@@ -57,18 +53,16 @@ EXPORT_SYMBOL(put_io_context);
+ 
+ static void cfq_exit(struct io_context *ioc)
+ {
+-	struct cfq_io_context *cic[1];
+-	int r;
+-
+ 	rcu_read_lock();
+-	/*
+-	 * See comment for cfq_dtor()
+-	 */
+-	r = radix_tree_gang_lookup(&ioc->radix_root, (void **) cic, 0, 1);
+-	rcu_read_unlock();
+ 
+-	if (r > 0)
+-		cic[0]->exit(ioc);
++	if (!hlist_empty(&ioc->cic_list)) {
++		struct cfq_io_context *cic;
++
++		cic = list_entry(ioc->cic_list.first, struct cfq_io_context,
++								cic_list);
++		cic->exit(ioc);
++	}
++	rcu_read_unlock();
+ }
+ 
+ /* Called by the exitting task */
+@@ -105,6 +99,7 @@ struct io_context *alloc_io_context(gfp_t gfp_flags, int node)
+ 		ret->nr_batch_requests = 0; /* because this is 0 */
+ 		ret->aic = NULL;
+ 		INIT_RADIX_TREE(&ret->radix_root, GFP_ATOMIC | __GFP_HIGH);
++		INIT_HLIST_HEAD(&ret->cic_list);
+ 		ret->ioc_data = NULL;
+ 	}
+ 
+@@ -176,7 +171,7 @@ void copy_io_context(struct io_context **pdst, struct io_context **psrc)
+ }
+ EXPORT_SYMBOL(copy_io_context);
+ 
+-int __init blk_ioc_init(void)
++static int __init blk_ioc_init(void)
+ {
+ 	iocontext_cachep = kmem_cache_create("blkdev_ioc",
+ 			sizeof(struct io_context), 0, SLAB_PANIC, NULL);
+diff --git a/block/blk-map.c b/block/blk-map.c
+index 955d75c..09f7fd0 100644
+--- a/block/blk-map.c
++++ b/block/blk-map.c
+@@ -19,6 +19,7 @@ int blk_rq_append_bio(struct request_queue *q, struct request *rq,
+ 		rq->biotail->bi_next = bio;
+ 		rq->biotail = bio;
+ 
++		rq->raw_data_len += bio->bi_size;
+ 		rq->data_len += bio->bi_size;
+ 	}
+ 	return 0;
+@@ -139,10 +140,29 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq,
+ 		ubuf += ret;
+ 	}
+ 
++	/*
++	 * __blk_rq_map_user() copies the buffers if starting address
++	 * or length isn't aligned.  As the copied buffer is always
++	 * page aligned, we know that there's enough room for padding.
++	 * Extend the last bio and update rq->data_len accordingly.
++	 *
++	 * On unmap, bio_uncopy_user() will use unmodified
++	 * bio_map_data pointed to by bio->bi_private.
++	 */
++	if (len & queue_dma_alignment(q)) {
++		unsigned int pad_len = (queue_dma_alignment(q) & ~len) + 1;
++		struct bio *bio = rq->biotail;
++
++		bio->bi_io_vec[bio->bi_vcnt - 1].bv_len += pad_len;
++		bio->bi_size += pad_len;
++		rq->data_len += pad_len;
++	}
++
+ 	rq->buffer = rq->data = NULL;
+ 	return 0;
+ unmap_rq:
+ 	blk_rq_unmap_user(bio);
++	rq->bio = NULL;
+ 	return ret;
+ }
+ EXPORT_SYMBOL(blk_rq_map_user);
+diff --git a/block/blk-merge.c b/block/blk-merge.c
+index d3b84bb..7506c4f 100644
+--- a/block/blk-merge.c
++++ b/block/blk-merge.c
+@@ -220,7 +220,10 @@ new_segment:
+ 		bvprv = bvec;
+ 	} /* segments in rq */
+ 
+-	if (q->dma_drain_size) {
++	if (q->dma_drain_size && q->dma_drain_needed(rq)) {
++		if (rq->cmd_flags & REQ_RW)
++			memset(q->dma_drain_buffer, 0, q->dma_drain_size);
++
+ 		sg->page_link &= ~0x02;
+ 		sg = sg_next(sg);
+ 		sg_set_page(sg, virt_to_page(q->dma_drain_buffer),
+@@ -228,6 +231,7 @@ new_segment:
+ 			    ((unsigned long)q->dma_drain_buffer) &
+ 			    (PAGE_SIZE - 1));
+ 		nsegs++;
++		rq->data_len += q->dma_drain_size;
+ 	}
+ 
+ 	if (sg)
+diff --git a/block/blk-settings.c b/block/blk-settings.c
+index c8d0c57..9a8ffdd 100644
+--- a/block/blk-settings.c
++++ b/block/blk-settings.c
+@@ -296,6 +296,7 @@ EXPORT_SYMBOL(blk_queue_stack_limits);
+  * blk_queue_dma_drain - Set up a drain buffer for excess dma.
+  *
+  * @q:  the request queue for the device
++ * @dma_drain_needed: fn which returns non-zero if drain is necessary
+  * @buf:	physically contiguous buffer
+  * @size:	size of the buffer in bytes
+  *
+@@ -315,14 +316,16 @@ EXPORT_SYMBOL(blk_queue_stack_limits);
+  * device can support otherwise there won't be room for the drain
+  * buffer.
+  */
+-int blk_queue_dma_drain(struct request_queue *q, void *buf,
+-				unsigned int size)
++extern int blk_queue_dma_drain(struct request_queue *q,
++			       dma_drain_needed_fn *dma_drain_needed,
++			       void *buf, unsigned int size)
+ {
+ 	if (q->max_hw_segments < 2 || q->max_phys_segments < 2)
+ 		return -EINVAL;
+ 	/* make room for appending the drain */
+ 	--q->max_hw_segments;
+ 	--q->max_phys_segments;
++	q->dma_drain_needed = dma_drain_needed;
+ 	q->dma_drain_buffer = buf;
+ 	q->dma_drain_size = size;
+ 
+@@ -386,7 +389,7 @@ void blk_queue_update_dma_alignment(struct request_queue *q, int mask)
+ }
+ EXPORT_SYMBOL(blk_queue_update_dma_alignment);
+ 
+-int __init blk_settings_init(void)
++static int __init blk_settings_init(void)
+ {
+ 	blk_max_low_pfn = max_low_pfn - 1;
+ 	blk_max_pfn = max_pfn - 1;
+diff --git a/block/bsg.c b/block/bsg.c
+index 8917c51..7f3c095 100644
+--- a/block/bsg.c
++++ b/block/bsg.c
+@@ -437,14 +437,14 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
+ 	}
+ 
+ 	if (rq->next_rq) {
+-		hdr->dout_resid = rq->data_len;
+-		hdr->din_resid = rq->next_rq->data_len;
++		hdr->dout_resid = rq->raw_data_len;
++		hdr->din_resid = rq->next_rq->raw_data_len;
+ 		blk_rq_unmap_user(bidi_bio);
+ 		blk_put_request(rq->next_rq);
+ 	} else if (rq_data_dir(rq) == READ)
+-		hdr->din_resid = rq->data_len;
++		hdr->din_resid = rq->raw_data_len;
+ 	else
+-		hdr->dout_resid = rq->data_len;
++		hdr->dout_resid = rq->raw_data_len;
+ 
+ 	/*
+ 	 * If the request generated a negative error number, return it
+diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
+index ca198e6..0f962ec 100644
+--- a/block/cfq-iosched.c
++++ b/block/cfq-iosched.c
+@@ -1145,38 +1145,19 @@ static void cfq_put_queue(struct cfq_queue *cfqq)
+ /*
+  * Call func for each cic attached to this ioc. Returns number of cic's seen.
+  */
+-#define CIC_GANG_NR	16
+ static unsigned int
+ call_for_each_cic(struct io_context *ioc,
+ 		  void (*func)(struct io_context *, struct cfq_io_context *))
+ {
+-	struct cfq_io_context *cics[CIC_GANG_NR];
+-	unsigned long index = 0;
+-	unsigned int called = 0;
+-	int nr;
++	struct cfq_io_context *cic;
++	struct hlist_node *n;
++	int called = 0;
+ 
+ 	rcu_read_lock();
+-
+-	do {
+-		int i;
+-
+-		/*
+-		 * Perhaps there's a better way - this just gang lookups from
+-		 * 0 to the end, restarting after each CIC_GANG_NR from the
+-		 * last key + 1.
+-		 */
+-		nr = radix_tree_gang_lookup(&ioc->radix_root, (void **) cics,
+-						index, CIC_GANG_NR);
+-		if (!nr)
+-			break;
+-
+-		called += nr;
+-		index = 1 + (unsigned long) cics[nr - 1]->key;
+-
+-		for (i = 0; i < nr; i++)
+-			func(ioc, cics[i]);
+-	} while (nr == CIC_GANG_NR);
+-
++	hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list) {
++		func(ioc, cic);
++		called++;
++	}
+ 	rcu_read_unlock();
+ 
+ 	return called;
+@@ -1190,6 +1171,7 @@ static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic)
+ 
+ 	spin_lock_irqsave(&ioc->lock, flags);
+ 	radix_tree_delete(&ioc->radix_root, cic->dead_key);
++	hlist_del_rcu(&cic->cic_list);
+ 	spin_unlock_irqrestore(&ioc->lock, flags);
+ 
+ 	kmem_cache_free(cfq_ioc_pool, cic);
+@@ -1280,6 +1262,7 @@ cfq_alloc_io_context(struct cfq_data *cfqd, gfp_t gfp_mask)
+ 	if (cic) {
+ 		cic->last_end_request = jiffies;
+ 		INIT_LIST_HEAD(&cic->queue_list);
++		INIT_HLIST_NODE(&cic->cic_list);
+ 		cic->dtor = cfq_free_io_context;
+ 		cic->exit = cfq_exit_io_context;
+ 		elv_ioc_count_inc(ioc_count);
+@@ -1501,6 +1484,7 @@ cfq_drop_dead_cic(struct cfq_data *cfqd, struct io_context *ioc,
+ 		rcu_assign_pointer(ioc->ioc_data, NULL);
+ 
+ 	radix_tree_delete(&ioc->radix_root, (unsigned long) cfqd);
++	hlist_del_rcu(&cic->cic_list);
+ 	spin_unlock_irqrestore(&ioc->lock, flags);
+ 
+ 	cfq_cic_free(cic);
+@@ -1561,6 +1545,8 @@ static int cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc,
+ 		spin_lock_irqsave(&ioc->lock, flags);
+ 		ret = radix_tree_insert(&ioc->radix_root,
+ 						(unsigned long) cfqd, cic);
++		if (!ret)
++			hlist_add_head_rcu(&cic->cic_list, &ioc->cic_list);
+ 		spin_unlock_irqrestore(&ioc->lock, flags);
+ 
+ 		radix_tree_preload_end();
+diff --git a/block/elevator.c b/block/elevator.c
+index bafbae0..88318c3 100644
+--- a/block/elevator.c
++++ b/block/elevator.c
+@@ -134,6 +134,21 @@ static struct elevator_type *elevator_get(const char *name)
+ 	spin_lock(&elv_list_lock);
+ 
+ 	e = elevator_find(name);
++	if (!e) {
++		char elv[ELV_NAME_MAX + strlen("-iosched")];
++
++		spin_unlock(&elv_list_lock);
++
++		if (!strcmp(name, "anticipatory"))
++			sprintf(elv, "as-iosched");
++		else
++			sprintf(elv, "%s-iosched", name);
++
++		request_module(elv);
++		spin_lock(&elv_list_lock);
++		e = elevator_find(name);
++	}
++
+ 	if (e && !try_module_get(e->elevator_owner))
+ 		e = NULL;
+ 
+diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
+index 9675b34..e993cac 100644
+--- a/block/scsi_ioctl.c
++++ b/block/scsi_ioctl.c
+@@ -266,7 +266,7 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
+ 	hdr->info = 0;
+ 	if (hdr->masked_status || hdr->host_status || hdr->driver_status)
+ 		hdr->info |= SG_INFO_CHECK;
+-	hdr->resid = rq->data_len;
++	hdr->resid = rq->raw_data_len;
+ 	hdr->sb_len_wr = 0;
+ 
+ 	if (rq->sense_len && hdr->sbp) {
+@@ -528,6 +528,7 @@ static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk,
+ 	rq = blk_get_request(q, WRITE, __GFP_WAIT);
+ 	rq->cmd_type = REQ_TYPE_BLOCK_PC;
+ 	rq->data = NULL;
++	rq->raw_data_len = 0;
+ 	rq->data_len = 0;
+ 	rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
+ 	memset(rq->cmd, 0, sizeof(rq->cmd));
+diff --git a/crypto/Kconfig b/crypto/Kconfig
+index c3166a1..898acc5 100644
+--- a/crypto/Kconfig
++++ b/crypto/Kconfig
+@@ -74,6 +74,7 @@ config CRYPTO_XCBC
+ config CRYPTO_NULL
+ 	tristate "Null algorithms"
+ 	select CRYPTO_ALGAPI
++	select CRYPTO_BLKCIPHER
+ 	help
+ 	  These are 'Null' algorithms, used by IPsec, which do nothing.
+ 
+@@ -567,6 +568,7 @@ config CRYPTO_TEST
+ 	depends on m
+ 	select CRYPTO_ALGAPI
+ 	select CRYPTO_AEAD
++	select CRYPTO_BLKCIPHER
+ 	help
+ 	  Quick & dirty crypto test module.
+ 
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index 29e71bd..3c06e45 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -1975,16 +1975,11 @@ static int ahci_port_start(struct ata_port *ap)
+ 	struct ahci_port_priv *pp;
+ 	void *mem;
+ 	dma_addr_t mem_dma;
+-	int rc;
+ 
+ 	pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
+ 	if (!pp)
+ 		return -ENOMEM;
+ 
+-	rc = ata_pad_alloc(ap, dev);
+-	if (rc)
+-		return rc;
+-
+ 	mem = dmam_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma,
+ 				  GFP_KERNEL);
+ 	if (!mem)
+diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
+index 9c2515f..752e7d2 100644
+--- a/drivers/ata/ata_piix.c
++++ b/drivers/ata/ata_piix.c
+@@ -1652,7 +1652,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
+ 		u8 tmp;
+ 		pci_read_config_byte(pdev, PIIX_SCC, &tmp);
+ 		if (tmp == PIIX_AHCI_DEVICE) {
+-			int rc = piix_disable_ahci(pdev);
++			rc = piix_disable_ahci(pdev);
+ 			if (rc)
+ 				return rc;
+ 		}
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index 004dae4..60d1bb5 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -87,6 +87,28 @@ static struct workqueue_struct *ata_wq;
+ 
+ struct workqueue_struct *ata_aux_wq;
+ 
++struct ata_force_param {
++	const char	*name;
++	unsigned int	cbl;
++	int		spd_limit;
++	unsigned long	xfer_mask;
++	unsigned int	horkage_on;
++	unsigned int	horkage_off;
++};
++
++struct ata_force_ent {
++	int			port;
++	int			device;
++	struct ata_force_param	param;
++};
++
++static struct ata_force_ent *ata_force_tbl;
++static int ata_force_tbl_size;
++
++static char ata_force_param_buf[PAGE_SIZE] __initdata;
++module_param_string(force, ata_force_param_buf, sizeof(ata_force_param_buf), 0444);
++MODULE_PARM_DESC(force, "Force ATA configurations including cable type, link speed and transfer mode (see Documentation/kernel-parameters.txt for details)");
++
+ int atapi_enabled = 1;
+ module_param(atapi_enabled, int, 0444);
+ MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)");
+@@ -130,6 +152,179 @@ MODULE_VERSION(DRV_VERSION);
+ 
+ 
+ /**
++ *	ata_force_cbl - force cable type according to libata.force
++ *	@link: ATA link of interest
++ *
++ *	Force cable type according to libata.force and whine about it.
++ *	The last entry which has matching port number is used, so it
++ *	can be specified as part of device force parameters.  For
++ *	example, both "a:40c,1.00:udma4" and "1.00:40c,udma4" have the
++ *	same effect.
++ *
++ *	LOCKING:
++ *	EH context.
++ */
++void ata_force_cbl(struct ata_port *ap)
++{
++	int i;
++
++	for (i = ata_force_tbl_size - 1; i >= 0; i--) {
++		const struct ata_force_ent *fe = &ata_force_tbl[i];
++
++		if (fe->port != -1 && fe->port != ap->print_id)
++			continue;
++
++		if (fe->param.cbl == ATA_CBL_NONE)
++			continue;
++
++		ap->cbl = fe->param.cbl;
++		ata_port_printk(ap, KERN_NOTICE,
++				"FORCE: cable set to %s\n", fe->param.name);
++		return;
++	}
++}
++
++/**
++ *	ata_force_spd_limit - force SATA spd limit according to libata.force
++ *	@link: ATA link of interest
++ *
++ *	Force SATA spd limit according to libata.force and whine about
++ *	it.  When only the port part is specified (e.g. 1:), the limit
++ *	applies to all links connected to both the host link and all
++ *	fan-out ports connected via PMP.  If the device part is
++ *	specified as 0 (e.g. 1.00:), it specifies the first fan-out
++ *	link not the host link.  Device number 15 always points to the
++ *	host link whether PMP is attached or not.
++ *
++ *	LOCKING:
++ *	EH context.
++ */
++static void ata_force_spd_limit(struct ata_link *link)
++{
++	int linkno, i;
++
++	if (ata_is_host_link(link))
++		linkno = 15;
++	else
++		linkno = link->pmp;
++
++	for (i = ata_force_tbl_size - 1; i >= 0; i--) {
++		const struct ata_force_ent *fe = &ata_force_tbl[i];
++
++		if (fe->port != -1 && fe->port != link->ap->print_id)
++			continue;
++
++		if (fe->device != -1 && fe->device != linkno)
++			continue;
++
++		if (!fe->param.spd_limit)
++			continue;
++
++		link->hw_sata_spd_limit = (1 << fe->param.spd_limit) - 1;
++		ata_link_printk(link, KERN_NOTICE,
++			"FORCE: PHY spd limit set to %s\n", fe->param.name);
++		return;
++	}
++}
++
++/**
++ *	ata_force_xfermask - force xfermask according to libata.force
++ *	@dev: ATA device of interest
++ *
++ *	Force xfer_mask according to libata.force and whine about it.
++ *	For consistency with link selection, device number 15 selects
++ *	the first device connected to the host link.
++ *
++ *	LOCKING:
++ *	EH context.
++ */
++static void ata_force_xfermask(struct ata_device *dev)
++{
++	int devno = dev->link->pmp + dev->devno;
++	int alt_devno = devno;
++	int i;
++
++	/* allow n.15 for the first device attached to host port */
++	if (ata_is_host_link(dev->link) && devno == 0)
++		alt_devno = 15;
++
++	for (i = ata_force_tbl_size - 1; i >= 0; i--) {
++		const struct ata_force_ent *fe = &ata_force_tbl[i];
++		unsigned long pio_mask, mwdma_mask, udma_mask;
++
++		if (fe->port != -1 && fe->port != dev->link->ap->print_id)
++			continue;
++
++		if (fe->device != -1 && fe->device != devno &&
++		    fe->device != alt_devno)
++			continue;
++
++		if (!fe->param.xfer_mask)
++			continue;
++
++		ata_unpack_xfermask(fe->param.xfer_mask,
++				    &pio_mask, &mwdma_mask, &udma_mask);
++		if (udma_mask)
++			dev->udma_mask = udma_mask;
++		else if (mwdma_mask) {
++			dev->udma_mask = 0;
++			dev->mwdma_mask = mwdma_mask;
++		} else {
++			dev->udma_mask = 0;
++			dev->mwdma_mask = 0;
++			dev->pio_mask = pio_mask;
++		}
++
++		ata_dev_printk(dev, KERN_NOTICE,
++			"FORCE: xfer_mask set to %s\n", fe->param.name);
++		return;
++	}
++}
++
++/**
++ *	ata_force_horkage - force horkage according to libata.force
++ *	@dev: ATA device of interest
++ *
++ *	Force horkage according to libata.force and whine about it.
++ *	For consistency with link selection, device number 15 selects
++ *	the first device connected to the host link.
++ *
++ *	LOCKING:
++ *	EH context.
++ */
++static void ata_force_horkage(struct ata_device *dev)
++{
++	int devno = dev->link->pmp + dev->devno;
++	int alt_devno = devno;
++	int i;
++
++	/* allow n.15 for the first device attached to host port */
++	if (ata_is_host_link(dev->link) && devno == 0)
++		alt_devno = 15;
++
++	for (i = 0; i < ata_force_tbl_size; i++) {
++		const struct ata_force_ent *fe = &ata_force_tbl[i];
++
++		if (fe->port != -1 && fe->port != dev->link->ap->print_id)
++			continue;
++
++		if (fe->device != -1 && fe->device != devno &&
++		    fe->device != alt_devno)
++			continue;
++
++		if (!(~dev->horkage & fe->param.horkage_on) &&
++		    !(dev->horkage & fe->param.horkage_off))
++			continue;
++
++		dev->horkage |= fe->param.horkage_on;
++		dev->horkage &= ~fe->param.horkage_off;
++
++		ata_dev_printk(dev, KERN_NOTICE,
++			"FORCE: horkage modified (%s)\n", fe->param.name);
++	}
++}
++
++/**
+  *	ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure
+  *	@tf: Taskfile to convert
+  *	@pmp: Port multiplier port
+@@ -2067,6 +2262,7 @@ int ata_dev_configure(struct ata_device *dev)
+ 
+ 	/* set horkage */
+ 	dev->horkage |= ata_dev_blacklisted(dev);
++	ata_force_horkage(dev);
+ 
+ 	/* let ACPI work its magic */
+ 	rc = ata_acpi_on_devcfg(dev);
+@@ -3150,6 +3346,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
+ 			mode_mask = ATA_DMA_MASK_CFA;
+ 
+ 		ata_dev_xfermask(dev);
++		ata_force_xfermask(dev);
+ 
+ 		pio_mask = ata_pack_xfermask(dev->pio_mask, 0, 0);
+ 		dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask);
+@@ -4190,6 +4387,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
+ 	/* Devices which report 1 sector over size HPA */
+ 	{ "ST340823A",		NULL,		ATA_HORKAGE_HPA_SIZE, },
+ 	{ "ST320413A",		NULL,		ATA_HORKAGE_HPA_SIZE, },
++	{ "ST310211A",		NULL,		ATA_HORKAGE_HPA_SIZE, },
+ 
+ 	/* Devices which get the IVB wrong */
+ 	{ "QUANTUM FIREBALLlct10 05", "A03.0900", ATA_HORKAGE_IVB, },
+@@ -4492,30 +4690,13 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
+ 	struct ata_port *ap = qc->ap;
+ 	struct scatterlist *sg = qc->sg;
+ 	int dir = qc->dma_dir;
+-	void *pad_buf = NULL;
+ 
+ 	WARN_ON(sg == NULL);
+ 
+-	VPRINTK("unmapping %u sg elements\n", qc->mapped_n_elem);
++	VPRINTK("unmapping %u sg elements\n", qc->n_elem);
+ 
+-	/* if we padded the buffer out to 32-bit bound, and data
+-	 * xfer direction is from-device, we must copy from the
+-	 * pad buffer back into the supplied buffer
+-	 */
+-	if (qc->pad_len && !(qc->tf.flags & ATA_TFLAG_WRITE))
+-		pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ);
+-
+-	if (qc->mapped_n_elem)
+-		dma_unmap_sg(ap->dev, sg, qc->mapped_n_elem, dir);
+-	/* restore last sg */
+-	if (qc->last_sg)
+-		*qc->last_sg = qc->saved_last_sg;
+-	if (pad_buf) {
+-		struct scatterlist *psg = &qc->extra_sg[1];
+-		void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
+-		memcpy(addr + psg->offset, pad_buf, qc->pad_len);
+-		kunmap_atomic(addr, KM_IRQ0);
+-	}
++	if (qc->n_elem)
++		dma_unmap_sg(ap->dev, sg, qc->n_elem, dir);
+ 
+ 	qc->flags &= ~ATA_QCFLAG_DMAMAP;
+ 	qc->sg = NULL;
+@@ -4658,43 +4839,6 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc)
+ }
+ 
+ /**
+- *	atapi_qc_may_overflow - Check whether data transfer may overflow
+- *	@qc: ATA command in question
+- *
+- *	ATAPI commands which transfer variable length data to host
+- *	might overflow due to application error or hardare bug.  This
+- *	function checks whether overflow should be drained and ignored
+- *	for @qc.
+- *
+- *	LOCKING:
+- *	None.
+- *
+- *	RETURNS:
+- *	1 if @qc may overflow; otherwise, 0.
+- */
+-static int atapi_qc_may_overflow(struct ata_queued_cmd *qc)
+-{
+-	if (qc->tf.protocol != ATAPI_PROT_PIO &&
+-	    qc->tf.protocol != ATAPI_PROT_DMA)
+-		return 0;
+-
+-	if (qc->tf.flags & ATA_TFLAG_WRITE)
+-		return 0;
+-
+-	switch (qc->cdb[0]) {
+-	case READ_10:
+-	case READ_12:
+-	case WRITE_10:
+-	case WRITE_12:
+-	case GPCMD_READ_CD:
+-	case GPCMD_READ_CD_MSF:
+-		return 0;
+-	}
+-
+-	return 1;
+-}
+-
+-/**
+  *	ata_std_qc_defer - Check whether a qc needs to be deferred
+  *	@qc: ATA command in question
+  *
+@@ -4781,97 +4925,6 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
+ 	qc->cursg = qc->sg;
+ }
+ 
+-static unsigned int ata_sg_setup_extra(struct ata_queued_cmd *qc,
+-				       unsigned int *n_elem_extra,
+-				       unsigned int *nbytes_extra)
+-{
+-	struct ata_port *ap = qc->ap;
+-	unsigned int n_elem = qc->n_elem;
+-	struct scatterlist *lsg, *copy_lsg = NULL, *tsg = NULL, *esg = NULL;
+-
+-	*n_elem_extra = 0;
+-	*nbytes_extra = 0;
+-
+-	/* needs padding? */
+-	qc->pad_len = qc->nbytes & 3;
+-
+-	if (likely(!qc->pad_len))
+-		return n_elem;
+-
+-	/* locate last sg and save it */
+-	lsg = sg_last(qc->sg, n_elem);
+-	qc->last_sg = lsg;
+-	qc->saved_last_sg = *lsg;
+-
+-	sg_init_table(qc->extra_sg, ARRAY_SIZE(qc->extra_sg));
+-
+-	if (qc->pad_len) {
+-		struct scatterlist *psg = &qc->extra_sg[1];
+-		void *pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ);
+-		unsigned int offset;
+-
+-		WARN_ON(qc->dev->class != ATA_DEV_ATAPI);
+-
+-		memset(pad_buf, 0, ATA_DMA_PAD_SZ);
+-
+-		/* psg->page/offset are used to copy to-be-written
+-		 * data in this function or read data in ata_sg_clean.
+-		 */
+-		offset = lsg->offset + lsg->length - qc->pad_len;
+-		sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT),
+-			    qc->pad_len, offset_in_page(offset));
+-
+-		if (qc->tf.flags & ATA_TFLAG_WRITE) {
+-			void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
+-			memcpy(pad_buf, addr + psg->offset, qc->pad_len);
+-			kunmap_atomic(addr, KM_IRQ0);
+-		}
+-
+-		sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ);
+-		sg_dma_len(psg) = ATA_DMA_PAD_SZ;
+-
+-		/* Trim the last sg entry and chain the original and
+-		 * padding sg lists.
+-		 *
+-		 * Because chaining consumes one sg entry, one extra
+-		 * sg entry is allocated and the last sg entry is
+-		 * copied to it if the length isn't zero after padded
+-		 * amount is removed.
+-		 *
+-		 * If the last sg entry is completely replaced by
+-		 * padding sg entry, the first sg entry is skipped
+-		 * while chaining.
+-		 */
+-		lsg->length -= qc->pad_len;
+-		if (lsg->length) {
+-			copy_lsg = &qc->extra_sg[0];
+-			tsg = &qc->extra_sg[0];
+-		} else {
+-			n_elem--;
+-			tsg = &qc->extra_sg[1];
+-		}
+-
+-		esg = &qc->extra_sg[1];
+-
+-		(*n_elem_extra)++;
+-		(*nbytes_extra) += 4 - qc->pad_len;
+-	}
+-
+-	if (copy_lsg)
+-		sg_set_page(copy_lsg, sg_page(lsg), lsg->length, lsg->offset);
+-
+-	sg_chain(lsg, 1, tsg);
+-	sg_mark_end(esg);
+-
+-	/* sglist can't start with chaining sg entry, fast forward */
+-	if (qc->sg == lsg) {
+-		qc->sg = tsg;
+-		qc->cursg = tsg;
+-	}
+-
+-	return n_elem;
+-}
+-
+ /**
+  *	ata_sg_setup - DMA-map the scatter-gather table associated with a command.
+  *	@qc: Command with scatter-gather table to be mapped.
+@@ -4888,26 +4941,17 @@ static unsigned int ata_sg_setup_extra(struct ata_queued_cmd *qc,
+ static int ata_sg_setup(struct ata_queued_cmd *qc)
+ {
+ 	struct ata_port *ap = qc->ap;
+-	unsigned int n_elem, n_elem_extra, nbytes_extra;
++	unsigned int n_elem;
+ 
+ 	VPRINTK("ENTER, ata%u\n", ap->print_id);
+ 
+-	n_elem = ata_sg_setup_extra(qc, &n_elem_extra, &nbytes_extra);
++	n_elem = dma_map_sg(ap->dev, qc->sg, qc->n_elem, qc->dma_dir);
++	if (n_elem < 1)
++		return -1;
+ 
+-	if (n_elem) {
+-		n_elem = dma_map_sg(ap->dev, qc->sg, n_elem, qc->dma_dir);
+-		if (n_elem < 1) {
+-			/* restore last sg */
+-			if (qc->last_sg)
+-				*qc->last_sg = qc->saved_last_sg;
+-			return -1;
+-		}
+-		DPRINTK("%d sg elements mapped\n", n_elem);
+-	}
++	DPRINTK("%d sg elements mapped\n", n_elem);
+ 
+-	qc->n_elem = qc->mapped_n_elem = n_elem;
+-	qc->n_elem += n_elem_extra;
+-	qc->nbytes += nbytes_extra;
++	qc->n_elem = n_elem;
+ 	qc->flags |= ATA_QCFLAG_DMAMAP;
+ 
+ 	return 0;
+@@ -5145,46 +5189,22 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc)
+  */
+ static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
+ {
+-	int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
++	int rw = (qc->tf.flags & ATA_TFLAG_WRITE) ? WRITE : READ;
+ 	struct ata_port *ap = qc->ap;
+-	struct ata_eh_info *ehi = &qc->dev->link->eh_info;
++	struct ata_device *dev = qc->dev;
++	struct ata_eh_info *ehi = &dev->link->eh_info;
+ 	struct scatterlist *sg;
+ 	struct page *page;
+ 	unsigned char *buf;
+-	unsigned int offset, count;
++	unsigned int offset, count, consumed;
+ 
+ next_sg:
+ 	sg = qc->cursg;
+ 	if (unlikely(!sg)) {
+-		/*
+-		 * The end of qc->sg is reached and the device expects
+-		 * more data to transfer. In order not to overrun qc->sg
+-		 * and fulfill length specified in the byte count register,
+-		 *    - for read case, discard trailing data from the device
+-		 *    - for write case, padding zero data to the device
+-		 */
+-		u16 pad_buf[1] = { 0 };
+-		unsigned int i;
+-
+-		if (bytes > qc->curbytes - qc->nbytes + ATAPI_MAX_DRAIN) {
+-			ata_ehi_push_desc(ehi, "too much trailing data "
+-					  "buf=%u cur=%u bytes=%u",
+-					  qc->nbytes, qc->curbytes, bytes);
+-			return -1;
+-		}
+-
+-		 /* overflow is exptected for misc ATAPI commands */
+-		if (bytes && !atapi_qc_may_overflow(qc))
+-			ata_dev_printk(qc->dev, KERN_WARNING, "ATAPI %u bytes "
+-				       "trailing data (cdb=%02x nbytes=%u)\n",
+-				       bytes, qc->cdb[0], qc->nbytes);
+-
+-		for (i = 0; i < (bytes + 1) / 2; i++)
+-			ap->ops->data_xfer(qc->dev, (unsigned char *)pad_buf, 2, do_write);
+-
+-		qc->curbytes += bytes;
+-
+-		return 0;
++		ata_ehi_push_desc(ehi, "unexpected or too much trailing data "
++				  "buf=%u cur=%u bytes=%u",
++				  qc->nbytes, qc->curbytes, bytes);
++		return -1;
+ 	}
+ 
+ 	page = sg_page(sg);
+@@ -5210,18 +5230,16 @@ next_sg:
+ 		buf = kmap_atomic(page, KM_IRQ0);
+ 
+ 		/* do the actual data transfer */
+-		ap->ops->data_xfer(qc->dev,  buf + offset, count, do_write);
++		consumed = ap->ops->data_xfer(dev,  buf + offset, count, rw);
+ 
+ 		kunmap_atomic(buf, KM_IRQ0);
+ 		local_irq_restore(flags);
+ 	} else {
+ 		buf = page_address(page);
+-		ap->ops->data_xfer(qc->dev,  buf + offset, count, do_write);
++		consumed = ap->ops->data_xfer(dev,  buf + offset, count, rw);
+ 	}
+ 
+-	bytes -= count;
+-	if ((count & 1) && bytes)
+-		bytes--;
++	bytes -= min(bytes, consumed);
+ 	qc->curbytes += count;
+ 	qc->cursg_ofs += count;
+ 
+@@ -5230,9 +5248,11 @@ next_sg:
+ 		qc->cursg_ofs = 0;
+ 	}
+ 
++	/* consumed can be larger than count only for the last transfer */
++	WARN_ON(qc->cursg && count != consumed);
++
+ 	if (bytes)
+ 		goto next_sg;
+-
+ 	return 0;
+ }
+ 
+@@ -5250,6 +5270,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
+ {
+ 	struct ata_port *ap = qc->ap;
+ 	struct ata_device *dev = qc->dev;
++	struct ata_eh_info *ehi = &dev->link->eh_info;
+ 	unsigned int ireason, bc_lo, bc_hi, bytes;
+ 	int i_write, do_write = (qc->tf.flags & ATA_TFLAG_WRITE) ? 1 : 0;
+ 
+@@ -5267,26 +5288,28 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
+ 
+ 	/* shall be cleared to zero, indicating xfer of data */
+ 	if (unlikely(ireason & (1 << 0)))
+-		goto err_out;
++		goto atapi_check;
+ 
+ 	/* make sure transfer direction matches expected */
+ 	i_write = ((ireason & (1 << 1)) == 0) ? 1 : 0;
+ 	if (unlikely(do_write != i_write))
+-		goto err_out;
++		goto atapi_check;
+ 
+ 	if (unlikely(!bytes))
+-		goto err_out;
++		goto atapi_check;
+ 
+ 	VPRINTK("ata%u: xfering %d bytes\n", ap->print_id, bytes);
+ 
+-	if (__atapi_pio_bytes(qc, bytes))
++	if (unlikely(__atapi_pio_bytes(qc, bytes)))
+ 		goto err_out;
+ 	ata_altstatus(ap); /* flush */
+ 
+ 	return;
+ 
+-err_out:
+-	ata_dev_printk(dev, KERN_INFO, "ATAPI check failed\n");
++ atapi_check:
++	ata_ehi_push_desc(ehi, "ATAPI check failed (ireason=0x%x bytes=%u)",
++			  ireason, bytes);
++ err_out:
+ 	qc->err_mask |= AC_ERR_HSM;
+ 	ap->hsm_task_state = HSM_ST_ERR;
+ }
+@@ -5971,9 +5994,6 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
+ 	 */
+ 	BUG_ON(ata_is_data(prot) && (!qc->sg || !qc->n_elem || !qc->nbytes));
+ 
+-	/* ata_sg_setup() may update nbytes */
+-	qc->raw_nbytes = qc->nbytes;
+-
+ 	if (ata_is_dma(prot) || (ata_is_pio(prot) &&
+ 				 (ap->flags & ATA_FLAG_PIO_DMA)))
+ 		if (ata_sg_setup(qc))
+@@ -6582,19 +6602,12 @@ void ata_host_resume(struct ata_host *host)
+ int ata_port_start(struct ata_port *ap)
+ {
+ 	struct device *dev = ap->dev;
+-	int rc;
+ 
+ 	ap->prd = dmam_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma,
+ 				      GFP_KERNEL);
+ 	if (!ap->prd)
+ 		return -ENOMEM;
+ 
+-	rc = ata_pad_alloc(ap, dev);
+-	if (rc)
+-		return rc;
+-
+-	DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd,
+-		(unsigned long long)ap->prd_dma);
+ 	return 0;
+ }
+ 
+@@ -6681,7 +6694,8 @@ void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp)
+  */
+ int sata_link_init_spd(struct ata_link *link)
+ {
+-	u32 scontrol, spd;
++	u32 scontrol;
++	u8 spd;
+ 	int rc;
+ 
+ 	rc = sata_scr_read(link, SCR_CONTROL, &scontrol);
+@@ -6692,6 +6706,8 @@ int sata_link_init_spd(struct ata_link *link)
+ 	if (spd)
+ 		link->hw_sata_spd_limit &= (1 << spd) - 1;
+ 
++	ata_force_spd_limit(link);
++
+ 	link->sata_spd_limit = link->hw_sata_spd_limit;
+ 
+ 	return 0;
+@@ -7086,7 +7102,6 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
+ 	DPRINTK("probe begin\n");
+ 	for (i = 0; i < host->n_ports; i++) {
+ 		struct ata_port *ap = host->ports[i];
+-		int rc;
+ 
+ 		/* probe */
+ 		if (ap->ops->error_handler) {
+@@ -7403,10 +7418,187 @@ int ata_pci_device_resume(struct pci_dev *pdev)
+ 
+ #endif /* CONFIG_PCI */
+ 
++static int __init ata_parse_force_one(char **cur,
++				      struct ata_force_ent *force_ent,
++				      const char **reason)
++{
++	/* FIXME: Currently, there's no way to tag init const data and
++	 * using __initdata causes build failure on some versions of
++	 * gcc.  Once __initdataconst is implemented, add const to the
++	 * following structure.
++	 */
++	static struct ata_force_param force_tbl[] __initdata = {
++		{ "40c",	.cbl		= ATA_CBL_PATA40 },
++		{ "80c",	.cbl		= ATA_CBL_PATA80 },
++		{ "short40c",	.cbl		= ATA_CBL_PATA40_SHORT },
++		{ "unk",	.cbl		= ATA_CBL_PATA_UNK },
++		{ "ign",	.cbl		= ATA_CBL_PATA_IGN },
++		{ "sata",	.cbl		= ATA_CBL_SATA },
++		{ "1.5Gbps",	.spd_limit	= 1 },
++		{ "3.0Gbps",	.spd_limit	= 2 },
++		{ "noncq",	.horkage_on	= ATA_HORKAGE_NONCQ },
++		{ "ncq",	.horkage_off	= ATA_HORKAGE_NONCQ },
++		{ "pio0",	.xfer_mask	= 1 << (ATA_SHIFT_PIO + 0) },
++		{ "pio1",	.xfer_mask	= 1 << (ATA_SHIFT_PIO + 1) },
++		{ "pio2",	.xfer_mask	= 1 << (ATA_SHIFT_PIO + 2) },
++		{ "pio3",	.xfer_mask	= 1 << (ATA_SHIFT_PIO + 3) },
++		{ "pio4",	.xfer_mask	= 1 << (ATA_SHIFT_PIO + 4) },
++		{ "pio5",	.xfer_mask	= 1 << (ATA_SHIFT_PIO + 5) },
++		{ "pio6",	.xfer_mask	= 1 << (ATA_SHIFT_PIO + 6) },
++		{ "mwdma0",	.xfer_mask	= 1 << (ATA_SHIFT_MWDMA + 0) },
++		{ "mwdma1",	.xfer_mask	= 1 << (ATA_SHIFT_MWDMA + 1) },
++		{ "mwdma2",	.xfer_mask	= 1 << (ATA_SHIFT_MWDMA + 2) },
++		{ "mwdma3",	.xfer_mask	= 1 << (ATA_SHIFT_MWDMA + 3) },
++		{ "mwdma4",	.xfer_mask	= 1 << (ATA_SHIFT_MWDMA + 4) },
++		{ "udma0",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 0) },
++		{ "udma16",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 0) },
++		{ "udma/16",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 0) },
++		{ "udma1",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 1) },
++		{ "udma25",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 1) },
++		{ "udma/25",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 1) },
++		{ "udma2",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 2) },
++		{ "udma33",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 2) },
++		{ "udma/33",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 2) },
++		{ "udma3",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 3) },
++		{ "udma44",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 3) },
++		{ "udma/44",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 3) },
++		{ "udma4",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 4) },
++		{ "udma66",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 4) },
++		{ "udma/66",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 4) },
++		{ "udma5",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 5) },
++		{ "udma100",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 5) },
++		{ "udma/100",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 5) },
++		{ "udma6",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 6) },
++		{ "udma133",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 6) },
++		{ "udma/133",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 6) },
++		{ "udma7",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 7) },
++	};
++	char *start = *cur, *p = *cur;
++	char *id, *val, *endp;
++	const struct ata_force_param *match_fp = NULL;
++	int nr_matches = 0, i;
++
++	/* find where this param ends and update *cur */
++	while (*p != '\0' && *p != ',')
++		p++;
++
++	if (*p == '\0')
++		*cur = p;
++	else
++		*cur = p + 1;
++
++	*p = '\0';
++
++	/* parse */
++	p = strchr(start, ':');
++	if (!p) {
++		val = strstrip(start);
++		goto parse_val;
++	}
++	*p = '\0';
++
++	id = strstrip(start);
++	val = strstrip(p + 1);
++
++	/* parse id */
++	p = strchr(id, '.');
++	if (p) {
++		*p++ = '\0';
++		force_ent->device = simple_strtoul(p, &endp, 10);
++		if (p == endp || *endp != '\0') {
++			*reason = "invalid device";
++			return -EINVAL;
++		}
++	}
++
++	force_ent->port = simple_strtoul(id, &endp, 10);
++	if (p == endp || *endp != '\0') {
++		*reason = "invalid port/link";
++		return -EINVAL;
++	}
++
++ parse_val:
++	/* parse val, allow shortcuts so that both 1.5 and 1.5Gbps work */
++	for (i = 0; i < ARRAY_SIZE(force_tbl); i++) {
++		const struct ata_force_param *fp = &force_tbl[i];
++
++		if (strncasecmp(val, fp->name, strlen(val)))
++			continue;
++
++		nr_matches++;
++		match_fp = fp;
++
++		if (strcasecmp(val, fp->name) == 0) {
++			nr_matches = 1;
++			break;
++		}
++	}
++
++	if (!nr_matches) {
++		*reason = "unknown value";
++		return -EINVAL;
++	}
++	if (nr_matches > 1) {
++		*reason = "ambigious value";
++		return -EINVAL;
++	}
++
++	force_ent->param = *match_fp;
++
++	return 0;
++}
++
++static void __init ata_parse_force_param(void)
++{
++	int idx = 0, size = 1;
++	int last_port = -1, last_device = -1;
++	char *p, *cur, *next;
++
++	/* calculate maximum number of params and allocate force_tbl */
++	for (p = ata_force_param_buf; *p; p++)
++		if (*p == ',')
++			size++;
++
++	ata_force_tbl = kzalloc(sizeof(ata_force_tbl[0]) * size, GFP_KERNEL);
++	if (!ata_force_tbl) {
++		printk(KERN_WARNING "ata: failed to extend force table, "
++		       "libata.force ignored\n");
++		return;
++	}
++
++	/* parse and populate the table */
++	for (cur = ata_force_param_buf; *cur != '\0'; cur = next) {
++		const char *reason = "";
++		struct ata_force_ent te = { .port = -1, .device = -1 };
++
++		next = cur;
++		if (ata_parse_force_one(&next, &te, &reason)) {
++			printk(KERN_WARNING "ata: failed to parse force "
++			       "parameter \"%s\" (%s)\n",
++			       cur, reason);
++			continue;
++		}
++
++		if (te.port == -1) {
++			te.port = last_port;
++			te.device = last_device;
++		}
++
++		ata_force_tbl[idx++] = te;
++
++		last_port = te.port;
++		last_device = te.device;
++	}
++
++	ata_force_tbl_size = idx;
++}
+ 
+ static int __init ata_init(void)
+ {
+ 	ata_probe_timeout *= HZ;
++
++	ata_parse_force_param();
++
+ 	ata_wq = create_workqueue("ata");
+ 	if (!ata_wq)
+ 		return -ENOMEM;
+@@ -7423,6 +7615,7 @@ static int __init ata_init(void)
+ 
+ static void __exit ata_exit(void)
+ {
++	kfree(ata_force_tbl);
+ 	destroy_workqueue(ata_wq);
+ 	destroy_workqueue(ata_aux_wq);
+ }
+diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
+index 4e31071..698ce2c 100644
+--- a/drivers/ata/libata-eh.c
++++ b/drivers/ata/libata-eh.c
+@@ -2393,9 +2393,11 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
+ 	}
+ 
+ 	/* PDIAG- should have been released, ask cable type if post-reset */
+-	if (ata_is_host_link(link) && ap->ops->cable_detect &&
+-	    (ehc->i.flags & ATA_EHI_DID_RESET))
+-		ap->cbl = ap->ops->cable_detect(ap);
++	if ((ehc->i.flags & ATA_EHI_DID_RESET) && ata_is_host_link(link)) {
++		if (ap->ops->cable_detect)
++			ap->cbl = ap->ops->cable_detect(ap);
++		ata_force_cbl(ap);
++	}
+ 
+ 	/* Configure new devices forward such that user doesn't see
+ 	 * device detection messages backwards.
+diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
+index c02c490..f888bab 100644
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -826,30 +826,61 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev)
+ 	sdev->max_device_blocked = 1;
+ }
+ 
+-static void ata_scsi_dev_config(struct scsi_device *sdev,
+-				struct ata_device *dev)
++/**
++ *	atapi_drain_needed - Check whether data transfer may overflow
++ *	@rq: request to be checked
++ *
++ *	ATAPI commands which transfer variable length data to host
++ *	might overflow due to application error or hardare bug.  This
++ *	function checks whether overflow should be drained and ignored
++ *	for @request.
++ *
++ *	LOCKING:
++ *	None.
++ *
++ *	RETURNS:
++ *	1 if ; otherwise, 0.
++ */
++static int atapi_drain_needed(struct request *rq)
++{
++	if (likely(!blk_pc_request(rq)))
++		return 0;
++
++	if (!rq->data_len || (rq->cmd_flags & REQ_RW))
++		return 0;
++
++	return atapi_cmd_type(rq->cmd[0]) == ATAPI_MISC;
++}
++
++static int ata_scsi_dev_config(struct scsi_device *sdev,
++			       struct ata_device *dev)
+ {
+ 	/* configure max sectors */
+ 	blk_queue_max_sectors(sdev->request_queue, dev->max_sectors);
+ 
+-	/* SATA DMA transfers must be multiples of 4 byte, so
+-	 * we need to pad ATAPI transfers using an extra sg.
+-	 * Decrement max hw segments accordingly.
+-	 */
+ 	if (dev->class == ATA_DEV_ATAPI) {
+ 		struct request_queue *q = sdev->request_queue;
+-		blk_queue_max_hw_segments(q, q->max_hw_segments - 1);
++		void *buf;
+ 
+ 		/* set the min alignment */
+ 		blk_queue_update_dma_alignment(sdev->request_queue,
+ 					       ATA_DMA_PAD_SZ - 1);
+-	} else
++
++		/* configure draining */
++		buf = kmalloc(ATAPI_MAX_DRAIN, q->bounce_gfp | GFP_KERNEL);
++		if (!buf) {
++			ata_dev_printk(dev, KERN_ERR,
++				       "drain buffer allocation failed\n");
++			return -ENOMEM;
++		}
++
++		blk_queue_dma_drain(q, atapi_drain_needed, buf, ATAPI_MAX_DRAIN);
++	} else {
+ 		/* ATA devices must be sector aligned */
+ 		blk_queue_update_dma_alignment(sdev->request_queue,
+ 					       ATA_SECT_SIZE - 1);
+-
+-	if (dev->class == ATA_DEV_ATA)
+ 		sdev->manage_start_stop = 1;
++	}
+ 
+ 	if (dev->flags & ATA_DFLAG_AN)
+ 		set_bit(SDEV_EVT_MEDIA_CHANGE, sdev->supported_events);
+@@ -861,6 +892,8 @@ static void ata_scsi_dev_config(struct scsi_device *sdev,
+ 		depth = min(ATA_MAX_QUEUE - 1, depth);
+ 		scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth);
+ 	}
++
++	return 0;
+ }
+ 
+ /**
+@@ -879,13 +912,14 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
+ {
+ 	struct ata_port *ap = ata_shost_to_port(sdev->host);
+ 	struct ata_device *dev = __ata_scsi_find_dev(ap, sdev);
++	int rc = 0;
+ 
+ 	ata_scsi_sdev_config(sdev);
+ 
+ 	if (dev)
+-		ata_scsi_dev_config(sdev, dev);
++		rc = ata_scsi_dev_config(sdev, dev);
+ 
+-	return 0;
++	return rc;
+ }
+ 
+ /**
+@@ -905,6 +939,7 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
+ void ata_scsi_slave_destroy(struct scsi_device *sdev)
+ {
+ 	struct ata_port *ap = ata_shost_to_port(sdev->host);
++	struct request_queue *q = sdev->request_queue;
+ 	unsigned long flags;
+ 	struct ata_device *dev;
+ 
+@@ -920,6 +955,10 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)
+ 		ata_port_schedule_eh(ap);
+ 	}
+ 	spin_unlock_irqrestore(ap->lock, flags);
++
++	kfree(q->dma_drain_buffer);
++	q->dma_drain_buffer = NULL;
++	q->dma_drain_size = 0;
+ }
+ 
+ /**
+@@ -1862,7 +1901,7 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
+  *	spin_lock_irqsave(host lock)
+  */
+ 
+-unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf,
++static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf,
+ 			      unsigned int buflen)
+ {
+ 	u8 pbuf[60];
+@@ -2500,7 +2539,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
+ 	 * want to set it properly, and for DMA where it is
+ 	 * effectively meaningless.
+ 	 */
+-	nbytes = min(qc->nbytes, (unsigned int)63 * 1024);
++	nbytes = min(scmd->request->raw_data_len, (unsigned int)63 * 1024);
+ 
+ 	/* Most ATAPI devices which honor transfer chunk size don't
+ 	 * behave according to the spec when odd chunk size which
+@@ -3555,7 +3594,7 @@ EXPORT_SYMBOL_GPL(ata_sas_port_alloc);
+  *	@ap: Port to initialize
+  *
+  *	Called just after data structures for each port are
+- *	initialized.  Allocates DMA pad.
++ *	initialized.
+  *
+  *	May be used as the port_start() entry in ata_port_operations.
+  *
+@@ -3564,7 +3603,7 @@ EXPORT_SYMBOL_GPL(ata_sas_port_alloc);
+  */
+ int ata_sas_port_start(struct ata_port *ap)
+ {
+-	return ata_pad_alloc(ap, ap->dev);
++	return 0;
+ }
+ EXPORT_SYMBOL_GPL(ata_sas_port_start);
+ 
+@@ -3572,8 +3611,6 @@ EXPORT_SYMBOL_GPL(ata_sas_port_start);
+  *	ata_port_stop - Undo ata_sas_port_start()
+  *	@ap: Port to shut down
+  *
+- *	Frees the DMA pad.
+- *
+  *	May be used as the port_stop() entry in ata_port_operations.
+  *
+  *	LOCKING:
+@@ -3582,7 +3619,6 @@ EXPORT_SYMBOL_GPL(ata_sas_port_start);
+ 
+ void ata_sas_port_stop(struct ata_port *ap)
+ {
+-	ata_pad_free(ap, ap->dev);
+ }
+ EXPORT_SYMBOL_GPL(ata_sas_port_stop);
+ 
+diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
+index 409ffb9..6036ded 100644
+--- a/drivers/ata/libata.h
++++ b/drivers/ata/libata.h
+@@ -61,6 +61,7 @@ extern int atapi_passthru16;
+ extern int libata_fua;
+ extern int libata_noacpi;
+ extern int libata_allow_tpm;
++extern void ata_force_cbl(struct ata_port *ap);
+ extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
+ extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
+ 			   u64 block, u32 n_block, unsigned int tf_flags,
+diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c
+index 244098a..bdc3b9d 100644
+--- a/drivers/ata/pata_acpi.c
++++ b/drivers/ata/pata_acpi.c
+@@ -77,8 +77,8 @@ static int pacpi_cable_detect(struct ata_port *ap)
+ 
+ static void pacpi_error_handler(struct ata_port *ap)
+ {
+-	return ata_bmdma_drive_eh(ap, pacpi_pre_reset, ata_std_softreset,
+-				  NULL, ata_std_postreset);
++	ata_bmdma_drive_eh(ap, pacpi_pre_reset, ata_std_softreset, NULL,
++			   ata_std_postreset);
+ }
+ 
+ /**
+diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
+index ea567e2..4b8d9b5 100644
+--- a/drivers/ata/pata_amd.c
++++ b/drivers/ata/pata_amd.c
+@@ -146,9 +146,8 @@ static int amd_pre_reset(struct ata_link *link, unsigned long deadline)
+ 
+ static void amd_error_handler(struct ata_port *ap)
+ {
+-	return ata_bmdma_drive_eh(ap, amd_pre_reset,
+-				      ata_std_softreset, NULL,
+-				      ata_std_postreset);
++	ata_bmdma_drive_eh(ap, amd_pre_reset, ata_std_softreset, NULL,
++			   ata_std_postreset);
+ }
+ 
+ static int amd_cable_detect(struct ata_port *ap)
+@@ -506,7 +505,6 @@ static struct ata_port_operations amd133_port_ops = {
+ static struct ata_port_operations nv100_port_ops = {
+ 	.set_piomode	= nv100_set_piomode,
+ 	.set_dmamode	= nv100_set_dmamode,
+-	.mode_filter	= ata_pci_default_filter,
+ 	.tf_load	= ata_tf_load,
+ 	.tf_read	= ata_tf_read,
+ 	.check_status 	= ata_check_status,
+@@ -541,7 +539,6 @@ static struct ata_port_operations nv100_port_ops = {
+ static struct ata_port_operations nv133_port_ops = {
+ 	.set_piomode	= nv133_set_piomode,
+ 	.set_dmamode	= nv133_set_dmamode,
+-	.mode_filter	= ata_pci_default_filter,
+ 	.tf_load	= ata_tf_load,
+ 	.tf_read	= ata_tf_read,
+ 	.check_status 	= ata_check_status,
+diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c
+index d753e56..1c4ff9b 100644
+--- a/drivers/ata/pata_cs5536.c
++++ b/drivers/ata/pata_cs5536.c
+@@ -40,7 +40,7 @@
+ #include <asm/msr.h>
+ 
+ #define DRV_NAME	"pata_cs5536"
+-#define DRV_VERSION	"0.0.6"
++#define DRV_VERSION	"0.0.7"
+ 
+ enum {
+ 	CFG			= 0,
+@@ -85,7 +85,7 @@ static const u8 pci_reg[4] = {
+ 	PCI_IDE_CFG, PCI_IDE_DTC, PCI_IDE_CAST, PCI_IDE_ETC,
+ };
+ 
+-static inline int cs5536_read(struct pci_dev *pdev, int reg, int *val)
++static inline int cs5536_read(struct pci_dev *pdev, int reg, u32 *val)
+ {
+ 	if (unlikely(use_msr)) {
+ 		u32 dummy;
+@@ -153,8 +153,8 @@ static void cs5536_set_piomode(struct ata_port *ap, struct ata_device *adev)
+ 	struct ata_device *pair = ata_dev_pair(adev);
+ 	int mode = adev->pio_mode - XFER_PIO_0;
+ 	int cmdmode = mode;
+-	int dshift = ap->port_no ? IDE_D1_SHIFT : IDE_D0_SHIFT;
+-	int cshift = ap->port_no ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT;
++	int dshift = adev->devno ? IDE_D1_SHIFT : IDE_D0_SHIFT;
++	int cshift = adev->devno ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT;
+ 	u32 dtc, cast, etc;
+ 
+ 	if (pair)
+@@ -201,7 +201,7 @@ static void cs5536_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+ 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ 	u32 dtc, etc;
+ 	int mode = adev->dma_mode;
+-	int dshift = ap->port_no ? IDE_D1_SHIFT : IDE_D0_SHIFT;
++	int dshift = adev->devno ? IDE_D1_SHIFT : IDE_D0_SHIFT;
+ 
+ 	if (mode >= XFER_UDMA_0) {
+ 		cs5536_read(pdev, ETC, &etc);
+diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c
+index 5b8586d..f97068b 100644
+--- a/drivers/ata/pata_icside.c
++++ b/drivers/ata/pata_icside.c
+@@ -304,12 +304,6 @@ static int icside_dma_init(struct pata_icside_info *info)
+ }
+ 
+ 
+-static int pata_icside_port_start(struct ata_port *ap)
+-{
+-	/* No PRD to alloc */
+-	return ata_pad_alloc(ap, ap->dev);
+-}
+-
+ static struct scsi_host_template pata_icside_sht = {
+ 	.module			= THIS_MODULE,
+ 	.name			= DRV_NAME,
+@@ -389,8 +383,6 @@ static struct ata_port_operations pata_icside_port_ops = {
+ 	.irq_clear		= ata_dummy_noret,
+ 	.irq_on			= ata_irq_on,
+ 
+-	.port_start		= pata_icside_port_start,
+-
+ 	.bmdma_stop		= pata_icside_bmdma_stop,
+ 	.bmdma_status		= pata_icside_bmdma_status,
+ };
+diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c
+index 5b8174d..00bbbbd 100644
+--- a/drivers/ata/pata_jmicron.c
++++ b/drivers/ata/pata_jmicron.c
+@@ -115,7 +115,8 @@ static int jmicron_pre_reset(struct ata_link *link, unsigned long deadline)
+ 
+ static void jmicron_error_handler(struct ata_port *ap)
+ {
+-	return ata_bmdma_drive_eh(ap, jmicron_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
++	ata_bmdma_drive_eh(ap, jmicron_pre_reset, ata_std_softreset, NULL,
++			   ata_std_postreset);
+ }
+ 
+ /* No PIO or DMA methods needed for this device */
+diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
+index 6c59969..50fe08e 100644
+--- a/drivers/ata/pata_legacy.c
++++ b/drivers/ata/pata_legacy.c
+@@ -774,14 +774,14 @@ static struct ata_port_operations opti82c46x_port_ops = {
+ static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev)
+ {
+ 	struct ata_timing t;
+-	struct legacy_data *qdi = ap->host->private_data;
++	struct legacy_data *ld_qdi = ap->host->private_data;
+ 	int active, recovery;
+ 	u8 timing;
+ 
+ 	/* Get the timing data in cycles */
+ 	ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
+ 
+-	if (qdi->fast) {
++	if (ld_qdi->fast) {
+ 		active = 8 - FIT(t.active, 1, 8);
+ 		recovery = 18 - FIT(t.recover, 3, 18);
+ 	} else {
+@@ -790,9 +790,9 @@ static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev)
+ 	}
+ 	timing = (recovery << 4) | active | 0x08;
+ 
+-	qdi->clock[adev->devno] = timing;
++	ld_qdi->clock[adev->devno] = timing;
+ 
+-	outb(timing, qdi->timing);
++	outb(timing, ld_qdi->timing);
+ }
+ 
+ /**
+@@ -808,14 +808,14 @@ static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev)
+ static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev)
+ {
+ 	struct ata_timing t;
+-	struct legacy_data *qdi = ap->host->private_data;
++	struct legacy_data *ld_qdi = ap->host->private_data;
+ 	int active, recovery;
+ 	u8 timing;
+ 
+ 	/* Get the timing data in cycles */
+ 	ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
+ 
+-	if (qdi->fast) {
++	if (ld_qdi->fast) {
+ 		active = 8 - FIT(t.active, 1, 8);
+ 		recovery = 18 - FIT(t.recover, 3, 18);
+ 	} else {
+@@ -824,12 +824,12 @@ static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev)
+ 	}
+ 	timing = (recovery << 4) | active | 0x08;
+ 
+-	qdi->clock[adev->devno] = timing;
++	ld_qdi->clock[adev->devno] = timing;
+ 
+-	outb(timing, qdi->timing + 2 * ap->port_no);
++	outb(timing, ld_qdi->timing + 2 * ap->port_no);
+ 	/* Clear the FIFO */
+ 	if (adev->class != ATA_DEV_ATA)
+-		outb(0x5F, qdi->timing + 3);
++		outb(0x5F, ld_qdi->timing + 3);
+ }
+ 
+ /**
+@@ -845,14 +845,14 @@ static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev)
+ static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev)
+ {
+ 	struct ata_timing t;
+-	struct legacy_data *qdi = ap->host->private_data;
++	struct legacy_data *ld_qdi = ap->host->private_data;
+ 	int active, recovery;
+ 	u8 timing;
+ 
+ 	/* Get the timing data in cycles */
+ 	ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
+ 
+-	if (qdi->fast) {
++	if (ld_qdi->fast) {
+ 		active = 8 - FIT(t.active, 1, 8);
+ 		recovery = 18 - FIT(t.recover, 3, 18);
+ 	} else {
+@@ -860,11 +860,11 @@ static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev)
+ 		recovery = 15 - FIT(t.recover, 0, 15);
+ 	}
+ 	timing = (recovery << 4) | active | 0x08;
+-	qdi->clock[adev->devno] = timing;
+-	outb(timing, qdi->timing + 2 * adev->devno);
++	ld_qdi->clock[adev->devno] = timing;
++	outb(timing, ld_qdi->timing + 2 * adev->devno);
+ 	/* Clear the FIFO */
+ 	if (adev->class != ATA_DEV_ATA)
+-		outb(0x5F, qdi->timing + 3);
++		outb(0x5F, ld_qdi->timing + 3);
+ }
+ 
+ /**
+@@ -879,12 +879,12 @@ static unsigned int qdi_qc_issue_prot(struct ata_queued_cmd *qc)
+ {
+ 	struct ata_port *ap = qc->ap;
+ 	struct ata_device *adev = qc->dev;
+-	struct legacy_data *qdi = ap->host->private_data;
++	struct legacy_data *ld_qdi = ap->host->private_data;
+ 
+-	if (qdi->clock[adev->devno] != qdi->last) {
++	if (ld_qdi->clock[adev->devno] != ld_qdi->last) {
+ 		if (adev->pio_mode) {
+-			qdi->last = qdi->clock[adev->devno];
+-			outb(qdi->clock[adev->devno], qdi->timing +
++			ld_qdi->last = ld_qdi->clock[adev->devno];
++			outb(ld_qdi->clock[adev->devno], ld_qdi->timing +
+ 							2 * ap->port_no);
+ 		}
+ 	}
+@@ -1037,12 +1037,12 @@ static u8 winbond_readcfg(unsigned long port, u8 reg)
+ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
+ {
+ 	struct ata_timing t;
+-	struct legacy_data *winbond = ap->host->private_data;
++	struct legacy_data *ld_winbond = ap->host->private_data;
+ 	int active, recovery;
+ 	u8 reg;
+ 	int timing = 0x88 + (ap->port_no * 4) + (adev->devno * 2);
+ 
+-	reg = winbond_readcfg(winbond->timing, 0x81);
++	reg = winbond_readcfg(ld_winbond->timing, 0x81);
+ 
+ 	/* Get the timing data in cycles */
+ 	if (reg & 0x40)		/* Fast VLB bus, assume 50MHz */
+@@ -1053,7 +1053,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
+ 	active = (FIT(t.active, 3, 17) - 1) & 0x0F;
+ 	recovery = (FIT(t.recover, 1, 15) + 1) & 0x0F;
+ 	timing = (active << 4) | recovery;
+-	winbond_writecfg(winbond->timing, timing, reg);
++	winbond_writecfg(ld_winbond->timing, timing, reg);
+ 
+ 	/* Load the setup timing */
+ 
+@@ -1063,7 +1063,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
+ 	if (!ata_pio_need_iordy(adev))
+ 		reg |= 0x02;	/* IORDY off */
+ 	reg |= (FIT(t.setup, 0, 3) << 6);
+-	winbond_writecfg(winbond->timing, timing + 1, reg);
++	winbond_writecfg(ld_winbond->timing, timing + 1, reg);
+ }
+ 
+ static int winbond_port(struct platform_device *dev,
+@@ -1278,8 +1278,6 @@ static __init int legacy_init_one(struct legacy_probe *probe)
+ 		}
+ 	}
+ fail:
+-	if (host)
+-		ata_host_detach(host);
+ 	platform_device_unregister(pdev);
+ 	return ret;
+ }
+diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c
+index 9afc8a3..a81f25d 100644
+--- a/drivers/ata/pata_marvell.c
++++ b/drivers/ata/pata_marvell.c
+@@ -85,8 +85,8 @@ static int marvell_cable_detect(struct ata_port *ap)
+ 
+ static void marvell_error_handler(struct ata_port *ap)
+ {
+-	return ata_bmdma_drive_eh(ap, marvell_pre_reset, ata_std_softreset,
+-				  NULL, ata_std_postreset);
++	ata_bmdma_drive_eh(ap, marvell_pre_reset, ata_std_softreset, NULL,
++			   ata_std_postreset);
+ }
+ 
+ /* No PIO or DMA methods needed for this device */
+diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
+index 55055b2..6c016de 100644
+--- a/drivers/ata/pata_scc.c
++++ b/drivers/ata/pata_scc.c
+@@ -1007,6 +1007,8 @@ static const struct ata_port_operations scc_pata_ops = {
+ 	.qc_issue		= ata_qc_issue_prot,
+ 
+ 	.freeze			= scc_bmdma_freeze,
++	.thaw			= ata_bmdma_thaw,
++
+ 	.error_handler		= scc_error_handler,
+ 	.post_internal_cmd	= scc_bmdma_stop,
+ 
+diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
+index efcb66b..9323dd0 100644
+--- a/drivers/ata/sata_fsl.c
++++ b/drivers/ata/sata_fsl.c
+@@ -601,21 +601,9 @@ static int sata_fsl_port_start(struct ata_port *ap)
+ 	if (!pp)
+ 		return -ENOMEM;
+ 
+-	/*
+-	 * allocate per command dma alignment pad buffer, which is used
+-	 * internally by libATA to ensure that all transfers ending on
+-	 * unaligned boundaries are padded, to align on Dword boundaries
+-	 */
+-	retval = ata_pad_alloc(ap, dev);
+-	if (retval) {
+-		kfree(pp);
+-		return retval;
+-	}
+-
+ 	mem = dma_alloc_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ, &mem_dma,
+ 				 GFP_KERNEL);
+ 	if (!mem) {
+-		ata_pad_free(ap, dev);
+ 		kfree(pp);
+ 		return -ENOMEM;
+ 	}
+@@ -694,7 +682,6 @@ static void sata_fsl_port_stop(struct ata_port *ap)
+ 	dma_free_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ,
+ 			  pp->cmdslot, pp->cmdslot_paddr);
+ 
+-	ata_pad_free(ap, dev);
+ 	kfree(pp);
+ }
+ 
+diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
+index 04b5717..6ebebde 100644
+--- a/drivers/ata/sata_mv.c
++++ b/drivers/ata/sata_mv.c
+@@ -870,7 +870,7 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
+ 		struct mv_host_priv *hpriv = ap->host->private_data;
+ 		int hard_port = mv_hardport_from_port(ap->port_no);
+ 		void __iomem *hc_mmio = mv_hc_base_from_port(
+-				ap->host->iomap[MV_PRIMARY_BAR], hard_port);
++					mv_host_base(ap->host), hard_port);
+ 		u32 hc_irq_cause, ipending;
+ 
+ 		/* clear EDMA event indicators, if any */
+@@ -1158,17 +1158,13 @@ static int mv_port_start(struct ata_port *ap)
+ 	struct mv_port_priv *pp;
+ 	void __iomem *port_mmio = mv_ap_base(ap);
+ 	unsigned long flags;
+-	int tag, rc;
++	int tag;
+ 
+ 	pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
+ 	if (!pp)
+ 		return -ENOMEM;
+ 	ap->private_data = pp;
+ 
+-	rc = ata_pad_alloc(ap, dev);
+-	if (rc)
+-		return rc;
+-
+ 	pp->crqb = dma_pool_alloc(hpriv->crqb_pool, GFP_KERNEL, &pp->crqb_dma);
+ 	if (!pp->crqb)
+ 		return -ENOMEM;
+@@ -1542,7 +1538,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
+ 		eh_freeze_mask = EDMA_EH_FREEZE_5;
+ 
+ 		if (edma_err_cause & EDMA_ERR_SELF_DIS_5) {
+-			struct mv_port_priv *pp	= ap->private_data;
++			pp = ap->private_data;
+ 			pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+ 			ata_ehi_push_desc(ehi, "EDMA self-disable");
+ 		}
+@@ -1550,7 +1546,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
+ 		eh_freeze_mask = EDMA_EH_FREEZE;
+ 
+ 		if (edma_err_cause & EDMA_ERR_SELF_DIS) {
+-			struct mv_port_priv *pp	= ap->private_data;
++			pp = ap->private_data;
+ 			pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+ 			ata_ehi_push_desc(ehi, "EDMA self-disable");
+ 		}
+@@ -2951,7 +2947,8 @@ static int mv_platform_probe(struct platform_device *pdev)
+ 	hpriv->n_ports = n_ports;
+ 
+ 	host->iomap = NULL;
+-	hpriv->base = ioremap(res->start, res->end - res->start + 1);
++	hpriv->base = devm_ioremap(&pdev->dev, res->start,
++				   res->end - res->start + 1);
+ 	hpriv->base -= MV_SATAHC0_REG_BASE;
+ 
+ 	rc = mv_create_dma_pools(hpriv, &pdev->dev);
+@@ -2983,11 +2980,8 @@ static int __devexit mv_platform_remove(struct platform_device *pdev)
+ {
+ 	struct device *dev = &pdev->dev;
+ 	struct ata_host *host = dev_get_drvdata(dev);
+-	struct mv_host_priv *hpriv = host->private_data;
+-	void __iomem *base = hpriv->base;
+ 
+ 	ata_host_detach(host);
+-	iounmap(base);
+ 	return 0;
+ }
+ 
+@@ -3198,6 +3192,7 @@ MODULE_DESCRIPTION("SCSI low-level driver for Marvell SATA controllers");
+ MODULE_LICENSE("GPL");
+ MODULE_DEVICE_TABLE(pci, mv_pci_tbl);
+ MODULE_VERSION(DRV_VERSION);
++MODULE_ALIAS("platform:sata_mv");
+ 
+ #ifdef CONFIG_PCI
+ module_param(msi, int, 0444);
+diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
+index a07d319..f251a5f 100644
+--- a/drivers/ata/sata_promise.c
++++ b/drivers/ata/sata_promise.c
+@@ -543,7 +543,7 @@ static void pdc_fill_sg(struct ata_queued_cmd *qc)
+ 	idx = 0;
+ 	for_each_sg(qc->sg, sg, qc->n_elem, si) {
+ 		u32 addr, offset;
+-		u32 sg_len, len;
++		u32 sg_len;
+ 
+ 		/* determine if physical DMA addr spans 64K boundary.
+ 		 * Note h/w doesn't support 64-bit, so we unconditionally
+diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
+index b4b1f91..df7988d 100644
+--- a/drivers/ata/sata_sil24.c
++++ b/drivers/ata/sata_sil24.c
+@@ -1234,7 +1234,6 @@ static int sil24_port_start(struct ata_port *ap)
+ 	union sil24_cmd_block *cb;
+ 	size_t cb_size = sizeof(*cb) * SIL24_MAX_CMDS;
+ 	dma_addr_t cb_dma;
+-	int rc;
+ 
+ 	pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
+ 	if (!pp)
+@@ -1247,10 +1246,6 @@ static int sil24_port_start(struct ata_port *ap)
+ 		return -ENOMEM;
+ 	memset(cb, 0, cb_size);
+ 
+-	rc = ata_pad_alloc(ap, dev);
+-	if (rc)
+-		return rc;
+-
+ 	pp->cmd_block = cb;
+ 	pp->cmd_block_dma = cb_dma;
+ 
+diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
+index 30caa03..0d03f44 100644
+--- a/drivers/ata/sata_via.c
++++ b/drivers/ata/sata_via.c
+@@ -333,8 +333,8 @@ static int vt6420_prereset(struct ata_link *link, unsigned long deadline)
+ 
+ static void vt6420_error_handler(struct ata_port *ap)
+ {
+-	return ata_bmdma_drive_eh(ap, vt6420_prereset, ata_std_softreset,
+-				  NULL, ata_std_postreset);
++	ata_bmdma_drive_eh(ap, vt6420_prereset, ata_std_softreset, NULL,
++			   ata_std_postreset);
+ }
+ 
+ static int vt6421_pata_cable_detect(struct ata_port *ap)
+diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
+index 87be464..d286699 100644
+--- a/drivers/char/agp/amd-k7-agp.c
++++ b/drivers/char/agp/amd-k7-agp.c
+@@ -41,6 +41,7 @@ static int amd_create_page_map(struct amd_page_map *page_map)
+ 	if (page_map->real == NULL)
+ 		return -ENOMEM;
+ 
++#ifndef CONFIG_X86
+ 	SetPageReserved(virt_to_page(page_map->real));
+ 	global_cache_flush();
+ 	page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
+@@ -52,6 +53,10 @@ static int amd_create_page_map(struct amd_page_map *page_map)
+ 		return -ENOMEM;
+ 	}
+ 	global_cache_flush();
++#else
++	set_memory_uc((unsigned long)page_map->real, 1);
++	page_map->remapped = page_map->real;
++#endif
+ 
+ 	for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
+ 		writel(agp_bridge->scratch_page, page_map->remapped+i);
+@@ -63,8 +68,12 @@ static int amd_create_page_map(struct amd_page_map *page_map)
+ 
+ static void amd_free_page_map(struct amd_page_map *page_map)
+ {
++#ifndef CONFIG_X86
+ 	iounmap(page_map->remapped);
+ 	ClearPageReserved(virt_to_page(page_map->real));
++#else
++	set_memory_wb((unsigned long)page_map->real, 1);
++#endif
+ 	free_page((unsigned long) page_map->real);
+ }
+ 
+diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
+index 2d46b71..55c97f6 100644
+--- a/drivers/char/agp/ati-agp.c
++++ b/drivers/char/agp/ati-agp.c
+@@ -60,18 +60,9 @@ static int ati_create_page_map(struct ati_page_map *page_map)
+ 	if (page_map->real == NULL)
+ 		return -ENOMEM;
+ 
+-	SetPageReserved(virt_to_page(page_map->real));
++	set_memory_uc((unsigned long)page_map->real, 1);
+ 	err = map_page_into_agp(virt_to_page(page_map->real));
+-	page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
+-					    PAGE_SIZE);
+-	if (page_map->remapped == NULL || err) {
+-		ClearPageReserved(virt_to_page(page_map->real));
+-		free_page((unsigned long) page_map->real);
+-		page_map->real = NULL;
+-		return -ENOMEM;
+-	}
+-	/*CACHE_FLUSH();*/
+-	global_cache_flush();
++	page_map->remapped = page_map->real;
+ 
+ 	for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
+ 		writel(agp_bridge->scratch_page, page_map->remapped+i);
+@@ -85,8 +76,7 @@ static int ati_create_page_map(struct ati_page_map *page_map)
+ static void ati_free_page_map(struct ati_page_map *page_map)
+ {
+ 	unmap_page_from_agp(virt_to_page(page_map->real));
+-	iounmap(page_map->remapped);
+-	ClearPageReserved(virt_to_page(page_map->real));
++	set_memory_wb((unsigned long)page_map->real, 1);
+ 	free_page((unsigned long) page_map->real);
+ }
+ 
+diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
+index 7484bc7..7fc0c99 100644
+--- a/drivers/char/agp/generic.c
++++ b/drivers/char/agp/generic.c
+@@ -932,9 +932,14 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
+ 	agp_gatt_table = (void *)table;
+ 
+ 	bridge->driver->cache_flush();
++#ifdef CONFIG_X86
++	set_memory_uc((unsigned long)table, 1 << page_order);
++	bridge->gatt_table = (void *)table;
++#else
+ 	bridge->gatt_table = ioremap_nocache(virt_to_gart(table),
+ 					(PAGE_SIZE * (1 << page_order)));
+ 	bridge->driver->cache_flush();
++#endif
+ 
+ 	if (bridge->gatt_table == NULL) {
+ 		for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
+@@ -991,7 +996,11 @@ int agp_generic_free_gatt_table(struct agp_bridge_data *bridge)
+ 	 * called, then all agp memory is deallocated and removed
+ 	 * from the table. */
+ 
++#ifdef CONFIG_X86
++	set_memory_wb((unsigned long)bridge->gatt_table, 1 << page_order);
++#else
+ 	iounmap(bridge->gatt_table);
++#endif
+ 	table = (char *) bridge->gatt_table_real;
+ 	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
+ 
+diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
+index eb1a1c7..b679184 100644
+--- a/drivers/char/agp/sis-agp.c
++++ b/drivers/char/agp/sis-agp.c
+@@ -14,6 +14,9 @@
+ #define SIS_TLBCNTRL	0x97
+ #define SIS_TLBFLUSH	0x98
+ 
++#define PCI_DEVICE_ID_SI_662	0x0662
++#define PCI_DEVICE_ID_SI_671	0x0671
++
+ static int __devinitdata agp_sis_force_delay = 0;
+ static int __devinitdata agp_sis_agp_spec = -1;
+ 
+@@ -27,8 +30,8 @@ static int sis_fetch_size(void)
+ 	values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
+ 	for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
+ 		if ((temp_size == values[i].size_value) ||
+-		    ((temp_size & ~(0x03)) ==
+-		     (values[i].size_value & ~(0x03)))) {
++		    ((temp_size & ~(0x07)) ==
++		     (values[i].size_value & ~(0x07)))) {
+ 			agp_bridge->previous_size =
+ 			    agp_bridge->current_size = (void *) (values + i);
+ 
+@@ -214,6 +217,26 @@ static void __devexit agp_sis_remove(struct pci_dev *pdev)
+ 	agp_put_bridge(bridge);
+ }
+ 
++#ifdef CONFIG_PM
++
++static int agp_sis_suspend(struct pci_dev *pdev, pm_message_t state)
++{
++	pci_save_state(pdev);
++	pci_set_power_state(pdev, pci_choose_state(pdev, state));
++
++	return 0;
++}
++
++static int agp_sis_resume(struct pci_dev *pdev)
++{
++	pci_set_power_state(pdev, PCI_D0);
++	pci_restore_state(pdev);
++
++	return sis_driver.configure();
++}
++
++#endif /* CONFIG_PM */
++
+ static struct pci_device_id agp_sis_pci_table[] = {
+ 	{
+ 		.class		= (PCI_CLASS_BRIDGE_HOST << 8),
+@@ -331,6 +354,22 @@ static struct pci_device_id agp_sis_pci_table[] = {
+ 		.class		= (PCI_CLASS_BRIDGE_HOST << 8),
+ 		.class_mask	= ~0,
+ 		.vendor		= PCI_VENDOR_ID_SI,
++		.device		= PCI_DEVICE_ID_SI_662,
++		.subvendor	= PCI_ANY_ID,
++		.subdevice	= PCI_ANY_ID,
++	},
++	{
++		.class		= (PCI_CLASS_BRIDGE_HOST << 8),
++		.class_mask	= ~0,
++		.vendor		= PCI_VENDOR_ID_SI,
++		.device		= PCI_DEVICE_ID_SI_671,
++		.subvendor	= PCI_ANY_ID,
++		.subdevice	= PCI_ANY_ID,
++	},
++	{
++		.class		= (PCI_CLASS_BRIDGE_HOST << 8),
++		.class_mask	= ~0,
++		.vendor		= PCI_VENDOR_ID_SI,
+ 		.device		= PCI_DEVICE_ID_SI_730,
+ 		.subvendor	= PCI_ANY_ID,
+ 		.subdevice	= PCI_ANY_ID,
+@@ -393,6 +432,10 @@ static struct pci_driver agp_sis_pci_driver = {
+ 	.id_table	= agp_sis_pci_table,
+ 	.probe		= agp_sis_probe,
+ 	.remove		= agp_sis_remove,
++#ifdef CONFIG_PM
++	.suspend	= agp_sis_suspend,
++	.resume		= agp_sis_resume,
++#endif
+ };
+ 
+ static int __init agp_sis_init(void)
+diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
+index 551ef25..e08934e 100644
+--- a/drivers/char/agp/sworks-agp.c
++++ b/drivers/char/agp/sworks-agp.c
+@@ -52,28 +52,20 @@ static int serverworks_create_page_map(struct serverworks_page_map *page_map)
+ 	if (page_map->real == NULL) {
+ 		return -ENOMEM;
+ 	}
+-	SetPageReserved(virt_to_page(page_map->real));
+-	global_cache_flush();
+-	page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
+-					    PAGE_SIZE);
+-	if (page_map->remapped == NULL) {
+-		ClearPageReserved(virt_to_page(page_map->real));
+-		free_page((unsigned long) page_map->real);
+-		page_map->real = NULL;
+-		return -ENOMEM;
+-	}
+-	global_cache_flush();
++
++	set_memory_uc((unsigned long)page_map->real, 1);
++	page_map->remapped = page_map->real;
+ 
+ 	for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++)
+ 		writel(agp_bridge->scratch_page, page_map->remapped+i);
++		/* Red Pen: Everyone else does pci posting flush here */
+ 
+ 	return 0;
+ }
+ 
+ static void serverworks_free_page_map(struct serverworks_page_map *page_map)
+ {
+-	iounmap(page_map->remapped);
+-	ClearPageReserved(virt_to_page(page_map->real));
++	set_memory_wb((unsigned long)page_map->real, 1);
+ 	free_page((unsigned long) page_map->real);
+ }
+ 
+diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
+index 19d3be5..a6789f2 100644
+--- a/drivers/char/drm/drmP.h
++++ b/drivers/char/drm/drmP.h
+@@ -568,7 +568,7 @@ struct drm_driver {
+ 	void (*postclose) (struct drm_device *, struct drm_file *);
+ 	void (*lastclose) (struct drm_device *);
+ 	int (*unload) (struct drm_device *);
+-	int (*suspend) (struct drm_device *);
++	int (*suspend) (struct drm_device *, pm_message_t state);
+ 	int (*resume) (struct drm_device *);
+ 	int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv);
+ 	void (*dma_ready) (struct drm_device *);
+diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
+index f524688..715b361 100644
+--- a/drivers/char/drm/drm_pciids.h
++++ b/drivers/char/drm/drm_pciids.h
+@@ -83,6 +83,7 @@
+ 	{0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
+ 	{0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
+ 	{0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
++	{0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
+ 	{0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ 	{0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ 	{0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+@@ -236,6 +237,7 @@
+ 	{0x1002, 0x7297, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \
+ 	{0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \
+ 	{0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
++	{0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
+ 	{0, 0, 0}
+ 
+ #define r128_PCI_IDS \
+@@ -313,6 +315,7 @@
+ 	{0x1039, 0x5300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ 	{0x1039, 0x6300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ 	{0x1039, 0x6330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
++	{0x1039, 0x6351, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ 	{0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ 	{0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
+ 	{0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
+diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c
+index fa36153..05ed504 100644
+--- a/drivers/char/drm/drm_sysfs.c
++++ b/drivers/char/drm/drm_sysfs.c
+@@ -36,7 +36,7 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state)
+ 	printk(KERN_ERR "%s\n", __FUNCTION__);
+ 
+ 	if (drm_dev->driver->suspend)
+-		return drm_dev->driver->suspend(drm_dev);
++		return drm_dev->driver->suspend(drm_dev, state);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
+index cea4105..3d65c4d 100644
+--- a/drivers/char/drm/drm_vm.c
++++ b/drivers/char/drm/drm_vm.c
+@@ -66,7 +66,7 @@ static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma)
+ }
+ 
+ /**
+- * \c nopage method for AGP virtual memory.
++ * \c fault method for AGP virtual memory.
+  *
+  * \param vma virtual memory area.
+  * \param address access address.
+@@ -76,8 +76,7 @@ static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma)
+  * map, get the page, increment the use count and return it.
+  */
+ #if __OS_HAS_AGP
+-static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
+-						unsigned long address)
++static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+ {
+ 	struct drm_file *priv = vma->vm_file->private_data;
+ 	struct drm_device *dev = priv->head->dev;
+@@ -89,19 +88,24 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
+ 	 * Find the right map
+ 	 */
+ 	if (!drm_core_has_AGP(dev))
+-		goto vm_nopage_error;
++		goto vm_fault_error;
+ 
+ 	if (!dev->agp || !dev->agp->cant_use_aperture)
+-		goto vm_nopage_error;
++		goto vm_fault_error;
+ 
+ 	if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash))
+-		goto vm_nopage_error;
++		goto vm_fault_error;
+ 
+ 	r_list = drm_hash_entry(hash, struct drm_map_list, hash);
+ 	map = r_list->map;
+ 
+ 	if (map && map->type == _DRM_AGP) {
+-		unsigned long offset = address - vma->vm_start;
++		/*
++		 * Using vm_pgoff as a selector forces us to use this unusual
++		 * addressing scheme.
++		 */
++		unsigned long offset = (unsigned long)vmf->virtual_address -
++								vma->vm_start;
+ 		unsigned long baddr = map->offset + offset;
+ 		struct drm_agp_mem *agpmem;
+ 		struct page *page;
+@@ -123,7 +127,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
+ 		}
+ 
+ 		if (!agpmem)
+-			goto vm_nopage_error;
++			goto vm_fault_error;
+ 
+ 		/*
+ 		 * Get the page, inc the use count, and return it
+@@ -131,22 +135,21 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
+ 		offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
+ 		page = virt_to_page(__va(agpmem->memory->memory[offset]));
+ 		get_page(page);
++		vmf->page = page;
+ 
+ 		DRM_DEBUG
+ 		    ("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
+ 		     baddr, __va(agpmem->memory->memory[offset]), offset,
+ 		     page_count(page));
+-
+-		return page;
++		return 0;
+ 	}
+-      vm_nopage_error:
+-	return NOPAGE_SIGBUS;	/* Disallow mremap */
++vm_fault_error:
++	return VM_FAULT_SIGBUS;	/* Disallow mremap */
+ }
+ #else				/* __OS_HAS_AGP */
+-static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
+-						unsigned long address)
++static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+ {
+-	return NOPAGE_SIGBUS;
++	return VM_FAULT_SIGBUS;
+ }
+ #endif				/* __OS_HAS_AGP */
+ 
+@@ -160,28 +163,26 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
+  * Get the mapping, find the real physical page to map, get the page, and
+  * return it.
+  */
+-static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
+-						    unsigned long address)
++static int drm_do_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+ {
+ 	struct drm_map *map = (struct drm_map *) vma->vm_private_data;
+ 	unsigned long offset;
+ 	unsigned long i;
+ 	struct page *page;
+ 
+-	if (address > vma->vm_end)
+-		return NOPAGE_SIGBUS;	/* Disallow mremap */
+ 	if (!map)
+-		return NOPAGE_SIGBUS;	/* Nothing allocated */
++		return VM_FAULT_SIGBUS;	/* Nothing allocated */
+ 
+-	offset = address - vma->vm_start;
++	offset = (unsigned long)vmf->virtual_address - vma->vm_start;
+ 	i = (unsigned long)map->handle + offset;
+ 	page = vmalloc_to_page((void *)i);
+ 	if (!page)
+-		return NOPAGE_SIGBUS;
++		return VM_FAULT_SIGBUS;
+ 	get_page(page);
++	vmf->page = page;
+ 
+-	DRM_DEBUG("0x%lx\n", address);
+-	return page;
++	DRM_DEBUG("shm_fault 0x%lx\n", offset);
++	return 0;
+ }
+ 
+ /**
+@@ -263,7 +264,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
+ }
+ 
+ /**
+- * \c nopage method for DMA virtual memory.
++ * \c fault method for DMA virtual memory.
+  *
+  * \param vma virtual memory area.
+  * \param address access address.
+@@ -271,8 +272,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
+  *
+  * Determine the page number from the page offset and get it from drm_device_dma::pagelist.
+  */
+-static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
+-						    unsigned long address)
++static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+ {
+ 	struct drm_file *priv = vma->vm_file->private_data;
+ 	struct drm_device *dev = priv->head->dev;
+@@ -282,24 +282,23 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
+ 	struct page *page;
+ 
+ 	if (!dma)
+-		return NOPAGE_SIGBUS;	/* Error */
+-	if (address > vma->vm_end)
+-		return NOPAGE_SIGBUS;	/* Disallow mremap */
++		return VM_FAULT_SIGBUS;	/* Error */
+ 	if (!dma->pagelist)
+-		return NOPAGE_SIGBUS;	/* Nothing allocated */
++		return VM_FAULT_SIGBUS;	/* Nothing allocated */
+ 
+-	offset = address - vma->vm_start;	/* vm_[pg]off[set] should be 0 */
+-	page_nr = offset >> PAGE_SHIFT;
++	offset = (unsigned long)vmf->virtual_address - vma->vm_start;	/* vm_[pg]off[set] should be 0 */
++	page_nr = offset >> PAGE_SHIFT; /* page_nr could just be vmf->pgoff */
+ 	page = virt_to_page((dma->pagelist[page_nr] + (offset & (~PAGE_MASK))));
+ 
+ 	get_page(page);
++	vmf->page = page;
+ 
+-	DRM_DEBUG("0x%lx (page %lu)\n", address, page_nr);
+-	return page;
++	DRM_DEBUG("dma_fault 0x%lx (page %lu)\n", offset, page_nr);
++	return 0;
+ }
+ 
+ /**
+- * \c nopage method for scatter-gather virtual memory.
++ * \c fault method for scatter-gather virtual memory.
+  *
+  * \param vma virtual memory area.
+  * \param address access address.
+@@ -307,8 +306,7 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
+  *
+  * Determine the map offset from the page offset and get it from drm_sg_mem::pagelist.
+  */
+-static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
+-						   unsigned long address)
++static int drm_do_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+ {
+ 	struct drm_map *map = (struct drm_map *) vma->vm_private_data;
+ 	struct drm_file *priv = vma->vm_file->private_data;
+@@ -320,77 +318,64 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
+ 	struct page *page;
+ 
+ 	if (!entry)
+-		return NOPAGE_SIGBUS;	/* Error */
+-	if (address > vma->vm_end)
+-		return NOPAGE_SIGBUS;	/* Disallow mremap */
++		return VM_FAULT_SIGBUS;	/* Error */
+ 	if (!entry->pagelist)
+-		return NOPAGE_SIGBUS;	/* Nothing allocated */
++		return VM_FAULT_SIGBUS;	/* Nothing allocated */
+ 
+-	offset = address - vma->vm_start;
++	offset = (unsigned long)vmf->virtual_address - vma->vm_start;
+ 	map_offset = map->offset - (unsigned long)dev->sg->virtual;
+ 	page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
+ 	page = entry->pagelist[page_offset];
+ 	get_page(page);
++	vmf->page = page;
+ 
+-	return page;
++	return 0;
+ }
+ 
+-static struct page *drm_vm_nopage(struct vm_area_struct *vma,
+-				  unsigned long address, int *type)
++static int drm_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+ {
+-	if (type)
+-		*type = VM_FAULT_MINOR;
+-	return drm_do_vm_nopage(vma, address);
++	return drm_do_vm_fault(vma, vmf);
+ }
+ 
+-static struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
+-				      unsigned long address, int *type)
++static int drm_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+ {
+-	if (type)
+-		*type = VM_FAULT_MINOR;
+-	return drm_do_vm_shm_nopage(vma, address);
++	return drm_do_vm_shm_fault(vma, vmf);
+ }
+ 
+-static struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
+-				      unsigned long address, int *type)
++static int drm_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+ {
+-	if (type)
+-		*type = VM_FAULT_MINOR;
+-	return drm_do_vm_dma_nopage(vma, address);
++	return drm_do_vm_dma_fault(vma, vmf);
+ }
+ 
+-static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma,
+-				     unsigned long address, int *type)
++static int drm_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+ {
+-	if (type)
+-		*type = VM_FAULT_MINOR;
+-	return drm_do_vm_sg_nopage(vma, address);
++	return drm_do_vm_sg_fault(vma, vmf);
+ }
+ 
+ /** AGP virtual memory operations */
+ static struct vm_operations_struct drm_vm_ops = {
+-	.nopage = drm_vm_nopage,
++	.fault = drm_vm_fault,
+ 	.open = drm_vm_open,
+ 	.close = drm_vm_close,
+ };
+ 
+ /** Shared virtual memory operations */
+ static struct vm_operations_struct drm_vm_shm_ops = {
+-	.nopage = drm_vm_shm_nopage,
++	.fault = drm_vm_shm_fault,
+ 	.open = drm_vm_open,
+ 	.close = drm_vm_shm_close,
+ };
+ 
+ /** DMA virtual memory operations */
+ static struct vm_operations_struct drm_vm_dma_ops = {
+-	.nopage = drm_vm_dma_nopage,
++	.fault = drm_vm_dma_fault,
+ 	.open = drm_vm_open,
+ 	.close = drm_vm_close,
+ };
+ 
+ /** Scatter-gather virtual memory operations */
+ static struct vm_operations_struct drm_vm_sg_ops = {
+-	.nopage = drm_vm_sg_nopage,
++	.fault = drm_vm_sg_fault,
+ 	.open = drm_vm_open,
+ 	.close = drm_vm_close,
+ };
+@@ -604,7 +589,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
+ 			/*
+ 			 * On some platforms we can't talk to bus dma address from the CPU, so for
+ 			 * memory of type DRM_AGP, we'll deal with sorting out the real physical
+-			 * pages and mappings in nopage()
++			 * pages and mappings in fault()
+ 			 */
+ #if defined(__powerpc__)
+ 			pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
+@@ -634,7 +619,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
+ 		break;
+ 	case _DRM_CONSISTENT:
+ 		/* Consistent memory is really like shared memory. But
+-		 * it's allocated in a different way, so avoid nopage */
++		 * it's allocated in a different way, so avoid fault */
+ 		if (remap_pfn_range(vma, vma->vm_start,
+ 		    page_to_pfn(virt_to_page(map->handle)),
+ 		    vma->vm_end - vma->vm_start, vma->vm_page_prot))
+diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
+index 43986d8..e9d6663 100644
+--- a/drivers/char/drm/i915_dma.c
++++ b/drivers/char/drm/i915_dma.c
+@@ -171,7 +171,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
+ 	dev_priv->allow_batchbuffer = 1;
+ 
+ 	/* Program Hardware Status Page */
+-	if (!IS_G33(dev)) {
++	if (!I915_NEED_GFX_HWS(dev)) {
+ 		dev_priv->status_page_dmah =
+ 			drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
+ 
+@@ -720,6 +720,9 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
+ 	drm_i915_private_t *dev_priv = dev->dev_private;
+ 	drm_i915_hws_addr_t *hws = data;
+ 
++	if (!I915_NEED_GFX_HWS(dev))
++		return -EINVAL;
++
+ 	if (!dev_priv) {
+ 		DRM_ERROR("called with no initialization\n");
+ 		return -EINVAL;
+diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
+index 52e5103..4048f39 100644
+--- a/drivers/char/drm/i915_drv.c
++++ b/drivers/char/drm/i915_drv.c
+@@ -160,6 +160,7 @@ static void i915_save_vga(struct drm_device *dev)
+ 		dev_priv->saveAR[i] = i915_read_ar(st01, i, 0);
+ 	inb(st01);
+ 	outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX);
++	inb(st01);
+ 
+ 	/* Graphics controller registers */
+ 	for (i = 0; i < 9; i++)
+@@ -225,6 +226,7 @@ static void i915_restore_vga(struct drm_device *dev)
+ 		i915_write_ar(st01, i, dev_priv->saveAR[i], 0);
+ 	inb(st01); /* switch back to index mode */
+ 	outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX);
++	inb(st01);
+ 
+ 	/* VGA color palette registers */
+ 	outb(dev_priv->saveDACMASK, VGA_DACMASK);
+@@ -236,7 +238,7 @@ static void i915_restore_vga(struct drm_device *dev)
+ 
+ }
+ 
+-static int i915_suspend(struct drm_device *dev)
++static int i915_suspend(struct drm_device *dev, pm_message_t state)
+ {
+ 	struct drm_i915_private *dev_priv = dev->dev_private;
+ 	int i;
+@@ -247,6 +249,9 @@ static int i915_suspend(struct drm_device *dev)
+ 		return -ENODEV;
+ 	}
+ 
++	if (state.event == PM_EVENT_PRETHAW)
++		return 0;
++
+ 	pci_save_state(dev->pdev);
+ 	pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
+ 
+@@ -276,6 +281,7 @@ static int i915_suspend(struct drm_device *dev)
+ 		dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
+ 	}
+ 	i915_save_palette(dev, PIPE_A);
++	dev_priv->savePIPEASTAT = I915_READ(I915REG_PIPEASTAT);
+ 
+ 	/* Pipe & plane B info */
+ 	dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
+@@ -303,6 +309,7 @@ static int i915_suspend(struct drm_device *dev)
+ 		dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
+ 	}
+ 	i915_save_palette(dev, PIPE_B);
++	dev_priv->savePIPEBSTAT = I915_READ(I915REG_PIPEBSTAT);
+ 
+ 	/* CRT state */
+ 	dev_priv->saveADPA = I915_READ(ADPA);
+@@ -329,12 +336,26 @@ static int i915_suspend(struct drm_device *dev)
+ 	dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2);
+ 	dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
+ 
++	/* Interrupt state */
++	dev_priv->saveIIR = I915_READ(I915REG_INT_IDENTITY_R);
++	dev_priv->saveIER = I915_READ(I915REG_INT_ENABLE_R);
++	dev_priv->saveIMR = I915_READ(I915REG_INT_MASK_R);
++
+ 	/* VGA state */
+ 	dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0);
+ 	dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1);
+ 	dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV);
+ 	dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
+ 
++	/* Clock gating state */
++	dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D);
++
++	/* Cache mode state */
++	dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
++
++	/* Memory Arbitration state */
++	dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE);
++
+ 	/* Scratch space */
+ 	for (i = 0; i < 16; i++) {
+ 		dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2));
+@@ -345,9 +366,11 @@ static int i915_suspend(struct drm_device *dev)
+ 
+ 	i915_save_vga(dev);
+ 
+-	/* Shut down the device */
+-	pci_disable_device(dev->pdev);
+-	pci_set_power_state(dev->pdev, PCI_D3hot);
++	if (state.event == PM_EVENT_SUSPEND) {
++		/* Shut down the device */
++		pci_disable_device(dev->pdev);
++		pci_set_power_state(dev->pdev, PCI_D3hot);
++	}
+ 
+ 	return 0;
+ }
+@@ -400,9 +423,7 @@ static int i915_resume(struct drm_device *dev)
+ 		I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF);
+ 	}
+ 
+-	if ((dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) &&
+-	    (dev_priv->saveDPLL_A & DPLL_VGA_MODE_DIS))
+-		I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF);
++	I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF);
+ 
+ 	i915_restore_palette(dev, PIPE_A);
+ 	/* Enable the plane */
+@@ -444,10 +465,9 @@ static int i915_resume(struct drm_device *dev)
+ 		I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF);
+ 	}
+ 
+-	if ((dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) &&
+-	    (dev_priv->saveDPLL_B & DPLL_VGA_MODE_DIS))
+-		I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF);
+-	i915_restore_palette(dev, PIPE_A);
++	I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF);
++
++	i915_restore_palette(dev, PIPE_B);
+ 	/* Enable the plane */
+ 	I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
+ 	I915_WRITE(DSPBBASE, I915_READ(DSPBBASE));
+@@ -485,6 +505,15 @@ static int i915_resume(struct drm_device *dev)
+ 	I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV);
+ 	udelay(150);
+ 
++	/* Clock gating state */
++	I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
++
++	/* Cache mode state */
++	I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
++
++	/* Memory arbitration state */
++	I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000);
++
+ 	for (i = 0; i < 16; i++) {
+ 		I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]);
+ 		I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]);
+diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
+index f8308bf..c10d128 100644
+--- a/drivers/char/drm/i915_drv.h
++++ b/drivers/char/drm/i915_drv.h
+@@ -134,6 +134,7 @@ typedef struct drm_i915_private {
+ 	u32 saveVBLANK_A;
+ 	u32 saveVSYNC_A;
+ 	u32 saveBCLRPAT_A;
++	u32 savePIPEASTAT;
+ 	u32 saveDSPASTRIDE;
+ 	u32 saveDSPASIZE;
+ 	u32 saveDSPAPOS;
+@@ -154,6 +155,7 @@ typedef struct drm_i915_private {
+ 	u32 saveVBLANK_B;
+ 	u32 saveVSYNC_B;
+ 	u32 saveBCLRPAT_B;
++	u32 savePIPEBSTAT;
+ 	u32 saveDSPBSTRIDE;
+ 	u32 saveDSPBSIZE;
+ 	u32 saveDSPBPOS;
+@@ -182,6 +184,12 @@ typedef struct drm_i915_private {
+ 	u32 saveFBC_LL_BASE;
+ 	u32 saveFBC_CONTROL;
+ 	u32 saveFBC_CONTROL2;
++	u32 saveIER;
++	u32 saveIIR;
++	u32 saveIMR;
++	u32 saveCACHE_MODE_0;
++	u32 saveDSPCLK_GATE_D;
++	u32 saveMI_ARB_STATE;
+ 	u32 saveSWF0[16];
+ 	u32 saveSWF1[16];
+ 	u32 saveSWF2[3];
+@@ -450,6 +458,10 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
+  */
+ #define DMA_FADD_S		0x20d4
+ 
++/* Memory Interface Arbitration State
++ */
++#define MI_ARB_STATE		0x20e4
++
+ /* Cache mode 0 reg.
+  *  - Manipulating render cache behaviour is central
+  *    to the concept of zone rendering, tuning this reg can help avoid
+@@ -460,6 +472,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
+  * bit of interest either set or cleared.  EG: (BIT<<16) | BIT to set.
+  */
+ #define Cache_Mode_0		0x2120
++#define CACHE_MODE_0		0x2120
+ #define CM0_MASK_SHIFT          16
+ #define CM0_IZ_OPT_DISABLE      (1<<6)
+ #define CM0_ZR_OPT_DISABLE      (1<<5)
+@@ -655,6 +668,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
+ /** P1 value is 2 greater than this field */
+ # define VGA0_PD_P1_MASK	(0x1f << 0)
+ 
++#define DSPCLK_GATE_D	0x6200
++
+ /* I830 CRTC registers */
+ #define HTOTAL_A	0x60000
+ #define HBLANK_A	0x60004
+@@ -1101,6 +1116,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
+ #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
+ 			IS_I945GM(dev) || IS_I965GM(dev) || IS_IGD_GM(dev))
+ 
++#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_IGD_GM(dev))
++
+ #define PRIMARY_RINGBUFFER_SIZE         (128*1024)
+ 
+ #endif
+diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
+index 5dc799a..833abc7 100644
+--- a/drivers/char/drm/radeon_cp.c
++++ b/drivers/char/drm/radeon_cp.c
+@@ -825,11 +825,19 @@ static u32 RADEON_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
+ 	return ret;
+ }
+ 
++static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
++{
++	RADEON_WRITE(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK));
++	return RADEON_READ(RS690_MC_DATA);
++}
++
+ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
+ {
+ 
+ 	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+ 		return RADEON_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION);
++	else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
++		return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION);
+ 	else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
+ 		return RADEON_READ_MCIND(dev_priv, R520_MC_FB_LOCATION);
+ 	else
+@@ -840,6 +848,8 @@ static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
+ {
+ 	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+ 		RADEON_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc);
++	else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
++		RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc);
+ 	else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
+ 		RADEON_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc);
+ 	else
+@@ -850,6 +860,8 @@ static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_lo
+ {
+ 	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+ 		RADEON_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc);
++	else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
++		RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc);
+ 	else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
+ 		RADEON_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc);
+ 	else
+@@ -1362,6 +1374,70 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
+        }
+ }
+ 
++/* Enable or disable RS690 GART on the chip */
++static void radeon_set_rs690gart(drm_radeon_private_t *dev_priv, int on)
++{
++	u32 temp;
++
++	if (on) {
++		DRM_DEBUG("programming rs690 gart %08X %08lX %08X\n",
++			  dev_priv->gart_vm_start,
++			  (long)dev_priv->gart_info.bus_addr,
++			  dev_priv->gart_size);
++
++		temp = RS690_READ_MCIND(dev_priv, RS690_MC_MISC_CNTL);
++		RS690_WRITE_MCIND(RS690_MC_MISC_CNTL, 0x5000);
++
++		RS690_WRITE_MCIND(RS690_MC_AGP_SIZE,
++				  RS690_MC_GART_EN | RS690_MC_AGP_SIZE_32MB);
++
++		temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_FEATURE_ID);
++		RS690_WRITE_MCIND(RS690_MC_GART_FEATURE_ID, 0x42040800);
++
++		RS690_WRITE_MCIND(RS690_MC_GART_BASE,
++				  dev_priv->gart_info.bus_addr);
++
++		temp = RS690_READ_MCIND(dev_priv, RS690_MC_AGP_MODE_CONTROL);
++		RS690_WRITE_MCIND(RS690_MC_AGP_MODE_CONTROL, 0x01400000);
++
++		RS690_WRITE_MCIND(RS690_MC_AGP_BASE,
++				  (unsigned int)dev_priv->gart_vm_start);
++
++		dev_priv->gart_size = 32*1024*1024;
++		temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) &
++			 0xffff0000) | (dev_priv->gart_vm_start >> 16));
++
++		RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, temp);
++
++		temp = RS690_READ_MCIND(dev_priv, RS690_MC_AGP_SIZE);
++		RS690_WRITE_MCIND(RS690_MC_AGP_SIZE,
++				  RS690_MC_GART_EN | RS690_MC_AGP_SIZE_32MB);
++
++		do {
++			temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_CACHE_CNTL);
++			if ((temp & RS690_MC_GART_CLEAR_STATUS) ==
++			    RS690_MC_GART_CLEAR_DONE)
++				break;
++			DRM_UDELAY(1);
++		} while (1);
++
++		RS690_WRITE_MCIND(RS690_MC_GART_CACHE_CNTL,
++				  RS690_MC_GART_CC_CLEAR);
++		do {
++			temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_CACHE_CNTL);
++			if ((temp & RS690_MC_GART_CLEAR_STATUS) ==
++				   RS690_MC_GART_CLEAR_DONE)
++				break;
++			DRM_UDELAY(1);
++		} while (1);
++
++		RS690_WRITE_MCIND(RS690_MC_GART_CACHE_CNTL,
++				  RS690_MC_GART_CC_NO_CHANGE);
++	} else {
++		RS690_WRITE_MCIND(RS690_MC_AGP_SIZE, RS690_MC_GART_DIS);
++	}
++}
++
+ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
+ {
+ 	u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL);
+@@ -1396,6 +1472,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
+ {
+ 	u32 tmp;
+ 
++	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) {
++		radeon_set_rs690gart(dev_priv, on);
++		return;
++	}
++
+ 	if (dev_priv->flags & RADEON_IS_IGPGART) {
+ 		radeon_set_igpgart(dev_priv, on);
+ 		return;
+diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
+index 4434332..173ae62 100644
+--- a/drivers/char/drm/radeon_drv.h
++++ b/drivers/char/drm/radeon_drv.h
+@@ -123,6 +123,7 @@ enum radeon_family {
+ 	CHIP_R420,
+ 	CHIP_RV410,
+ 	CHIP_RS400,
++	CHIP_RS690,
+ 	CHIP_RV515,
+ 	CHIP_R520,
+ 	CHIP_RV530,
+@@ -467,6 +468,36 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
+ #define RADEON_IGPGART_ENABLE           0x38
+ #define RADEON_IGPGART_UNK_39           0x39
+ 
++#define RS690_MC_INDEX                  0x78
++#   define RS690_MC_INDEX_MASK          0x1ff
++#   define RS690_MC_INDEX_WR_EN         (1 << 9)
++#   define RS690_MC_INDEX_WR_ACK        0x7f
++#define RS690_MC_DATA                   0x7c
++
++#define RS690_MC_MISC_CNTL              0x18
++#define RS690_MC_GART_FEATURE_ID        0x2b
++#define RS690_MC_GART_BASE              0x2c
++#define RS690_MC_GART_CACHE_CNTL	0x2e
++#   define RS690_MC_GART_CC_NO_CHANGE   0x0
++#   define RS690_MC_GART_CC_CLEAR       0x1
++#   define RS690_MC_GART_CLEAR_STATUS   (1 << 1)
++#       define RS690_MC_GART_CLEAR_DONE     (0 << 1)
++#       define RS690_MC_GART_CLEAR_PENDING  (1 << 1)
++#define RS690_MC_AGP_SIZE               0x38
++#   define RS690_MC_GART_DIS            0x0
++#   define RS690_MC_GART_EN             0x1
++#   define RS690_MC_AGP_SIZE_32MB       (0 << 1)
++#   define RS690_MC_AGP_SIZE_64MB       (1 << 1)
++#   define RS690_MC_AGP_SIZE_128MB      (2 << 1)
++#   define RS690_MC_AGP_SIZE_256MB      (3 << 1)
++#   define RS690_MC_AGP_SIZE_512MB      (4 << 1)
++#   define RS690_MC_AGP_SIZE_1GB        (5 << 1)
++#   define RS690_MC_AGP_SIZE_2GB        (6 << 1)
++#define RS690_MC_AGP_MODE_CONTROL       0x39
++#define RS690_MC_FB_LOCATION            0x100
++#define RS690_MC_AGP_LOCATION           0x101
++#define RS690_MC_AGP_BASE               0x102
++
+ #define R520_MC_IND_INDEX 0x70
+ #define R520_MC_IND_WR_EN (1<<24)
+ #define R520_MC_IND_DATA  0x74
+@@ -1076,6 +1107,13 @@ do {									\
+ 		RADEON_WRITE(R520_MC_IND_INDEX, 0);	\
+ 	} while (0)
+ 
++#define RS690_WRITE_MCIND( addr, val )					\
++do {								\
++	RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_EN | ((addr) & RS690_MC_INDEX_MASK));	\
++	RADEON_WRITE(RS690_MC_DATA, val);			\
++	RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK);	\
++} while (0)
++
+ #define CP_PACKET0( reg, n )						\
+ 	(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
+ #define CP_PACKET0_TABLE( reg, n )					\
+diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
+index dfbf24c..3110bf7 100644
+--- a/drivers/crypto/hifn_795x.c
++++ b/drivers/crypto/hifn_795x.c
+@@ -463,7 +463,7 @@ struct hifn_device
+ 
+ 	unsigned int		pk_clk_freq;
+ 
+-#ifdef CRYPTO_DEV_HIFN_795X_RNG
++#ifdef CONFIG_CRYPTO_DEV_HIFN_795X_RNG
+ 	unsigned int		rng_wait_time;
+ 	ktime_t			rngtime;
+ 	struct hwrng		rng;
+@@ -795,7 +795,7 @@ static struct pci2id {
+ 	}
+ };
+ 
+-#ifdef CRYPTO_DEV_HIFN_795X_RNG
++#ifdef CONFIG_CRYPTO_DEV_HIFN_795X_RNG
+ static int hifn_rng_data_present(struct hwrng *rng, int wait)
+ {
+ 	struct hifn_device *dev = (struct hifn_device *)rng->priv;
+@@ -880,7 +880,7 @@ static int hifn_init_pubrng(struct hifn_device *dev)
+ 	dprintk("Chip %s: RNG engine has been successfully initialised.\n",
+ 			dev->name);
+ 
+-#ifdef CRYPTO_DEV_HIFN_795X_RNG
++#ifdef CONFIG_CRYPTO_DEV_HIFN_795X_RNG
+ 	/* First value must be discarded */
+ 	hifn_read_1(dev, HIFN_1_RNG_DATA);
+ 	dev->rngtime = ktime_get();
+diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
+index 354c91d..310e497 100644
+--- a/drivers/ide/ide-cd.c
++++ b/drivers/ide/ide-cd.c
+@@ -1207,9 +1207,13 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
+ end_request:
+ 	if (blk_pc_request(rq)) {
+ 		unsigned long flags;
++		unsigned int dlen = rq->data_len;
++
++		if (dma)
++			rq->data_len = 0;
+ 
+ 		spin_lock_irqsave(&ide_lock, flags);
+-		if (__blk_end_request(rq, 0, rq->data_len))
++		if (__blk_end_request(rq, 0, dlen))
+ 			BUG();
+ 		HWGROUP(drive)->rq = NULL;
+ 		spin_unlock_irqrestore(&ide_lock, flags);
+diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
+index aed8b31..8f5bed4 100644
+--- a/drivers/ide/ide-disk.c
++++ b/drivers/ide/ide-disk.c
+@@ -397,6 +397,7 @@ static inline int idedisk_supports_lba48(const struct hd_driveid *id)
+ static const struct drive_list_entry hpa_list[] = {
+ 	{ "ST340823A",	NULL },
+ 	{ "ST320413A",	NULL },
++	{ "ST310211A",	NULL },
+ 	{ NULL,		NULL }
+ };
+ 
+diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c
+index 709b9e4..9ebec08 100644
+--- a/drivers/ide/ide-generic.c
++++ b/drivers/ide/ide-generic.c
+@@ -17,9 +17,6 @@ static int __init ide_generic_init(void)
+ 	u8 idx[MAX_HWIFS];
+ 	int i;
+ 
+-	if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET])
+-		ide_get_lock(NULL, NULL); /* for atari only */
+-
+ 	for (i = 0; i < MAX_HWIFS; i++) {
+ 		ide_hwif_t *hwif = &ide_hwifs[i];
+ 
+@@ -31,9 +28,6 @@ static int __init ide_generic_init(void)
+ 
+ 	ide_device_add_all(idx, NULL);
+ 
+-	if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET])
+-		ide_release_lock();	/* for atari only */
+-
+ 	return 0;
+ }
+ 
+diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c
+index f044048..8949ce7 100644
+--- a/drivers/ide/legacy/falconide.c
++++ b/drivers/ide/legacy/falconide.c
+@@ -54,7 +54,7 @@ static void __init falconide_setup_ports(hw_regs_t *hw)
+ 	for (i = 1; i < 8; i++)
+ 		hw->io_ports[i] = ATA_HD_BASE + 1 + i * 4;
+ 
+-	hw->io_ports[IDE_CONTROL_OFFSET] = ATA_HD_CONTROL;
++	hw->io_ports[IDE_CONTROL_OFFSET] = ATA_HD_BASE + ATA_HD_CONTROL;
+ 
+ 	hw->irq = IRQ_MFP_IDE;
+ 	hw->ack_intr = NULL;
+@@ -84,7 +84,9 @@ static int __init falconide_init(void)
+ 		ide_init_port_data(hwif, index);
+ 		ide_init_port_hw(hwif, &hw);
+ 
++		ide_get_lock(NULL, NULL);
+ 		ide_device_add(idx, NULL);
++		ide_release_lock();
+ 	}
+ 
+ 	return 0;
+diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c
+index 02d12c7..78ca68e 100644
+--- a/drivers/ide/legacy/ht6560b.c
++++ b/drivers/ide/legacy/ht6560b.c
+@@ -21,18 +21,21 @@
+  *                      "Prefetch" mode bit OFF for ide disks and
+  *                      ON for anything else.
+  *
++ *  Version 0.08        Need to force prefetch for CDs and other non-disk
++ *                      devices. (not sure which devices exactly need
++ *                      prefetch)
+  *
+  *  HT-6560B EIDE-controller support
+  *  To activate controller support use kernel parameter "ide0=ht6560b".
+  *  Use hdparm utility to enable PIO mode support.
+  *
+  *  Author:    Mikko Ala-Fossi            <maf at iki.fi>
+- *             Jan Evert van Grootheest   <janevert at iae.nl>
++ *             Jan Evert van Grootheest   <janevert at caiway.nl>
+  *
+  *  Try:  http://www.maf.iki.fi/~maf/ht6560b/
+  */
+ 
+-#define HT6560B_VERSION "v0.07"
++#define HT6560B_VERSION "v0.08"
+ 
+ #include <linux/module.h>
+ #include <linux/types.h>
+@@ -130,15 +133,20 @@ static void ht6560b_selectproc (ide_drive_t *drive)
+ 	u8 select, timing;
+ 	
+ 	local_irq_save(flags);
+-	
++
+ 	select = HT_CONFIG(drive);
+ 	timing = HT_TIMING(drive);
+-	
++
++	/*
++	 * Need to enforce prefetch sometimes because otherwise
++	 * it'll hang (hard).
++	 */
++	if (drive->media != ide_disk || !drive->present)
++		select |= HT_PREFETCH_MODE;
++
+ 	if (select != current_select || timing != current_timing) {
+ 		current_select = select;
+ 		current_timing = timing;
+-		if (drive->media != ide_disk || !drive->present)
+-			select |= HT_PREFETCH_MODE;
+ 		(void)inb(HT_CONFIG_PORT);
+ 		(void)inb(HT_CONFIG_PORT);
+ 		(void)inb(HT_CONFIG_PORT);
+@@ -188,11 +196,12 @@ static int __init try_to_init_ht6560b(void)
+ 	outb(HT_TIMING_DEFAULT, 0x1f6);  /* IDE_SELECT_REG */
+ 	(void) inb(0x1f7);               /* IDE_STATUS_REG */
+ 	
+-	printk("\nht6560b " HT6560B_VERSION
++	printk("ht6560b " HT6560B_VERSION
+ 	       ": chipset detected and initialized"
+ #ifdef DEBUG
+ 	       " with debug enabled"
+ #endif
++	       "\n"
+ 		);
+ 	return 1;
+ }
+@@ -323,7 +332,7 @@ static const struct ide_port_info ht6560b_port_info __initdata = {
+ 				  IDE_HFLAG_NO_DMA |
+ 				  IDE_HFLAG_NO_AUTOTUNE |
+ 				  IDE_HFLAG_ABUSE_PREFETCH,
+-	.pio_mask		= ATA_PIO5,
++	.pio_mask		= ATA_PIO4,
+ };
+ 
+ static int __init ht6560b_init(void)
+diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c
+index a61e607..9a79098 100644
+--- a/drivers/ide/legacy/macide.c
++++ b/drivers/ide/legacy/macide.c
+@@ -74,7 +74,7 @@ static void __init macide_setup_ports(hw_regs_t *hw, unsigned long base,
+ 	for (i = 0; i < 8; i++)
+ 		hw->io_ports[i] = base + i * 4;
+ 
+-	hw->io_ports[IDE_CONTROL_OFFSET] = IDE_CONTROL;
++	hw->io_ports[IDE_CONTROL_OFFSET] = base + IDE_CONTROL;
+ 
+ 	hw->irq = irq;
+ 	hw->ack_intr = ack_intr;
+diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
+index f3f79f8..9004e75 100644
+--- a/drivers/ide/pci/via82cxxx.c
++++ b/drivers/ide/pci/via82cxxx.c
+@@ -479,6 +479,7 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i
+ static const struct pci_device_id via_pci_tbl[] = {
+ 	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1),  0 },
+ 	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1),  0 },
++	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_CX700_IDE), 0 },
+ 	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410),      1 },
+ 	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), 1 },
+ 	{ 0, },
+diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
+index c864ef7..5a4b2e6 100644
+--- a/drivers/infiniband/core/sysfs.c
++++ b/drivers/infiniband/core/sysfs.c
+@@ -686,8 +686,10 @@ int ib_device_register_sysfs(struct ib_device *device)
+ 
+ 	device->ports_parent = kobject_create_and_add("ports",
+ 					kobject_get(&class_dev->kobj));
+-	if (!device->ports_parent)
++	if (!device->ports_parent) {
++		ret = -ENOMEM;
+ 		goto err_put;
++	}
+ 
+ 	if (device->node_type == RDMA_NODE_IB_SWITCH) {
+ 		ret = add_port(device, 0);
+diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c
+index 3b69855..3538da1 100644
+--- a/drivers/infiniband/hw/mthca/mthca_mr.c
++++ b/drivers/infiniband/hw/mthca/mthca_mr.c
+@@ -686,7 +686,7 @@ err_out_table:
+ 	mthca_table_put(dev, dev->mr_table.mpt_table, key);
+ 
+ err_out_mpt_free:
+-	mthca_free(&dev->mr_table.mpt_alloc, mr->ibmr.lkey);
++	mthca_free(&dev->mr_table.mpt_alloc, key);
+ 	return err;
+ }
+ 
+diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
+index b6cc265..eee77da 100644
+--- a/drivers/infiniband/hw/nes/nes_nic.c
++++ b/drivers/infiniband/hw/nes/nes_nic.c
+@@ -148,14 +148,15 @@ static int nes_netdev_open(struct net_device *netdev)
+ 	struct nes_device *nesdev = nesvnic->nesdev;
+ 	int ret;
+ 	int i;
+-	struct nes_vnic *first_nesvnic;
++	struct nes_vnic *first_nesvnic = NULL;
+ 	u32 nic_active_bit;
+ 	u32 nic_active;
++	struct list_head *list_pos, *list_temp;
+ 
+ 	assert(nesdev != NULL);
+ 
+-	first_nesvnic = list_entry(nesdev->nesadapter->nesvnic_list[nesdev->mac_index].next,
+-			struct nes_vnic, list);
++	if (nesvnic->netdev_open == 1)
++		return 0;
+ 
+ 	if (netif_msg_ifup(nesvnic))
+ 		printk(KERN_INFO PFX "%s: enabling interface\n", netdev->name);
+@@ -225,7 +226,18 @@ static int nes_netdev_open(struct net_device *netdev)
+ 	nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT |
+ 			nesvnic->nic_cq.cq_number);
+ 	nes_read32(nesdev->regs+NES_CQE_ALLOC);
+-
++	list_for_each_safe(list_pos, list_temp, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]) {
++		first_nesvnic = container_of(list_pos, struct nes_vnic, list);
++		if (first_nesvnic->netdev_open == 1)
++			break;
++	}
++	if (first_nesvnic->netdev_open == 0) {
++		nes_debug(NES_DBG_INIT, "Setting up MAC interrupt mask.\n");
++		nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK + (0x200 * nesdev->mac_index),
++				~(NES_MAC_INT_LINK_STAT_CHG | NES_MAC_INT_XGMII_EXT |
++				NES_MAC_INT_TX_UNDERFLOW | NES_MAC_INT_TX_ERROR));
++		first_nesvnic = nesvnic;
++	}
+ 	if (first_nesvnic->linkup) {
+ 		/* Enable network packets */
+ 		nesvnic->linkup = 1;
+@@ -248,6 +260,8 @@ static int nes_netdev_stop(struct net_device *netdev)
+ 	struct nes_device *nesdev = nesvnic->nesdev;
+ 	u32 nic_active_mask;
+ 	u32 nic_active;
++	struct nes_vnic *first_nesvnic = NULL;
++	struct list_head *list_pos, *list_temp;
+ 
+ 	nes_debug(NES_DBG_SHUTDOWN, "nesvnic=%p, nesdev=%p, netdev=%p %s\n",
+ 			nesvnic, nesdev, netdev, netdev->name);
+@@ -260,9 +274,20 @@ static int nes_netdev_stop(struct net_device *netdev)
+ 	/* Disable network packets */
+ 	napi_disable(&nesvnic->napi);
+ 	netif_stop_queue(netdev);
+-	if ((nesdev->netdev[0] == netdev) & (nesvnic->logical_port == nesdev->mac_index)) {
+-		nes_write_indexed(nesdev,
+-				NES_IDX_MAC_INT_MASK+(0x200*nesdev->mac_index), 0xffffffff);
++	list_for_each_safe(list_pos, list_temp, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]) {
++		first_nesvnic = container_of(list_pos, struct nes_vnic, list);
++		if ((first_nesvnic->netdev_open == 1) && (first_nesvnic != nesvnic))
++			break;
++	}
++
++	if (first_nesvnic->netdev_open == 0)
++		nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK+(0x200*nesdev->mac_index), 0xffffffff);
++	else if ((first_nesvnic != nesvnic) &&
++		 (PCI_FUNC(first_nesvnic->nesdev->pcidev->devfn) != PCI_FUNC(nesvnic->nesdev->pcidev->devfn))) {
++		nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK + (0x200 * nesdev->mac_index), 0xffffffff);
++		nes_write_indexed(first_nesvnic->nesdev, NES_IDX_MAC_INT_MASK + (0x200 * first_nesvnic->nesdev->mac_index),
++				~(NES_MAC_INT_LINK_STAT_CHG | NES_MAC_INT_XGMII_EXT |
++				NES_MAC_INT_TX_UNDERFLOW | NES_MAC_INT_TX_ERROR));
+ 	}
+ 
+ 	nic_active_mask = ~((u32)(1 << nesvnic->nic_index));
+@@ -859,7 +884,6 @@ void nes_netdev_set_multicast_list(struct net_device *netdev)
+ 		for (mc_index=0; mc_index < NES_MULTICAST_PF_MAX; mc_index++) {
+ 			while (multicast_addr && nesvnic->mcrq_mcast_filter && ((mc_nic_index = nesvnic->mcrq_mcast_filter(nesvnic, multicast_addr->dmi_addr)) == 0))
+ 				multicast_addr = multicast_addr->next;
+-
+ 			if (mc_nic_index < 0)
+ 				mc_nic_index = nesvnic->nic_index;
+ 			if (multicast_addr) {
+@@ -908,7 +932,7 @@ static int nes_netdev_change_mtu(struct	net_device *netdev,	int	new_mtu)
+ 		return -EINVAL;
+ 
+ 	netdev->mtu	= new_mtu;
+-	nesvnic->max_frame_size	= new_mtu+ETH_HLEN;
++	nesvnic->max_frame_size	= new_mtu + VLAN_ETH_HLEN;
+ 
+ 	if (netdev->mtu	> 1500)	{
+ 		jumbomode=1;
+@@ -1470,10 +1494,15 @@ static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_g
+ {
+ 	struct nes_vnic *nesvnic = netdev_priv(netdev);
+ 	struct nes_device *nesdev = nesvnic->nesdev;
++	struct nes_adapter *nesadapter = nesdev->nesadapter;
+ 	u32 u32temp;
++	unsigned long flags;
+ 
++	spin_lock_irqsave(&nesadapter->phy_lock, flags);
+ 	nesvnic->vlan_grp = grp;
+ 
++	nes_debug(NES_DBG_NETDEV, "%s: %s\n", __func__, netdev->name);
++
+ 	/* Enable/Disable VLAN Stripping */
+ 	u32temp = nes_read_indexed(nesdev, NES_IDX_PCIX_DIAG);
+ 	if (grp)
+@@ -1482,6 +1511,7 @@ static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_g
+ 		u32temp	|= 0x02000000;
+ 
+ 	nes_write_indexed(nesdev, NES_IDX_PCIX_DIAG, u32temp);
++	spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
+ }
+ 
+ 
+@@ -1540,7 +1570,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
+ 	nesvnic->msg_enable = netif_msg_init(debug, default_msg);
+ 	nesvnic->netdev_index = nesdev->netdev_count;
+ 	nesvnic->perfect_filter_index = nesdev->nesadapter->netdev_count;
+-	nesvnic->max_frame_size = netdev->mtu+netdev->hard_header_len;
++	nesvnic->max_frame_size = netdev->mtu + netdev->hard_header_len + VLAN_HLEN;
+ 
+ 	curr_qp_map = nic_qp_mapping_per_function[PCI_FUNC(nesdev->pcidev->devfn)];
+ 	nesvnic->nic.qp_id = curr_qp_map[nesdev->netdev_count].qpid;
+@@ -1610,7 +1640,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
+ 	list_add_tail(&nesvnic->list, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]);
+ 
+ 	if ((nesdev->netdev_count == 0) &&
+-			(PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index)) {
++	    (PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index)) {
+ 		nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n",
+ 				NES_IDX_PHY_PCS_CONTROL_STATUS0+(0x200*(nesvnic->logical_port&1)));
+ 		u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
+@@ -1648,18 +1678,14 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
+ 				nesvnic->linkup = 1;
+ 			}
+ 		}
+-		nes_debug(NES_DBG_INIT, "Setting up MAC interrupt mask.\n");
+ 		/* clear the MAC interrupt status, assumes direct logical to physical mapping */
+-		u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS+(0x200*nesvnic->logical_port));
++		u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index));
+ 		nes_debug(NES_DBG_INIT, "Phy interrupt status = 0x%X.\n", u32temp);
+-		nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS+(0x200*nesvnic->logical_port), u32temp);
++		nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index), u32temp);
+ 
+-		if (nesdev->nesadapter->phy_type[nesvnic->logical_port] != NES_PHY_TYPE_IRIS)
++		if (nesdev->nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_IRIS)
+ 			nes_init_phy(nesdev);
+ 
+-		nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK+(0x200*nesvnic->logical_port),
+-				~(NES_MAC_INT_LINK_STAT_CHG | NES_MAC_INT_XGMII_EXT |
+-				NES_MAC_INT_TX_UNDERFLOW | NES_MAC_INT_TX_ERROR));
+ 	}
+ 
+ 	return netdev;
+diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
+index ffd4b42..4dafbe1 100644
+--- a/drivers/infiniband/hw/nes/nes_verbs.c
++++ b/drivers/infiniband/hw/nes/nes_verbs.c
+@@ -1337,7 +1337,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd,
+ 								   NES_MAX_USER_WQ_REGIONS, nes_ucontext->first_free_wq);
+ 					/* nes_debug(NES_DBG_QP, "find_first_zero_biton wqs returned %u\n",
+ 							nespd->mmap_db_index); */
+-					if (nesqp->mmap_sq_db_index > NES_MAX_USER_WQ_REGIONS) {
++					if (nesqp->mmap_sq_db_index >= NES_MAX_USER_WQ_REGIONS) {
+ 						nes_debug(NES_DBG_QP,
+ 							  "db index > max user regions, failing create QP\n");
+ 						nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num);
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+index 7dd2ec4..52b1beb 100644
+--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+@@ -824,7 +824,6 @@ void ipoib_cm_dev_stop(struct net_device *dev)
+ 	struct ipoib_dev_priv *priv = netdev_priv(dev);
+ 	struct ipoib_cm_rx *p;
+ 	unsigned long begin;
+-	LIST_HEAD(list);
+ 	int ret;
+ 
+ 	if (!IPOIB_CM_SUPPORTED(dev->dev_addr) || !priv->cm.id)
+@@ -857,9 +856,12 @@ void ipoib_cm_dev_stop(struct net_device *dev)
+ 			/*
+ 			 * assume the HW is wedged and just free up everything.
+ 			 */
+-			list_splice_init(&priv->cm.rx_flush_list, &list);
+-			list_splice_init(&priv->cm.rx_error_list, &list);
+-			list_splice_init(&priv->cm.rx_drain_list, &list);
++			list_splice_init(&priv->cm.rx_flush_list,
++					 &priv->cm.rx_reap_list);
++			list_splice_init(&priv->cm.rx_error_list,
++					 &priv->cm.rx_reap_list);
++			list_splice_init(&priv->cm.rx_drain_list,
++					 &priv->cm.rx_reap_list);
+ 			break;
+ 		}
+ 		spin_unlock_irq(&priv->lock);
+diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
+index 2928ef2..5160587 100644
+--- a/drivers/md/dm-raid1.c
++++ b/drivers/md/dm-raid1.c
+@@ -1695,14 +1695,15 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio,
+ 			 * information for a retry or there was no other
+ 			 * mirror in-sync.
+ 			 */
+-			DMERR_LIMIT("Mirror read failed from %s.",
+-				    m->dev->name);
++			DMERR_LIMIT("Mirror read failed.");
+ 			return -EIO;
+ 		}
++
++		m = read_record->m;
++
+ 		DMERR("Mirror read failed from %s. Trying alternative device.",
+ 		      m->dev->name);
+ 
+-		m = read_record->m;
+ 		fail_mirror(m, DM_RAID1_READ_ERROR);
+ 
+ 		/*
+diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
+index 8f4a453..1195069 100644
+--- a/drivers/media/Kconfig
++++ b/drivers/media/Kconfig
+@@ -25,11 +25,16 @@ config VIDEO_DEV
+ 	  To compile this driver as a module, choose M here: the
+ 	  module will be called videodev.
+ 
++config VIDEO_V4L2_COMMON
++	tristate
++	depends on (I2C || I2C=n) && VIDEO_DEV
++	default (I2C || I2C=n) && VIDEO_DEV
++
+ config VIDEO_V4L1
+ 	bool "Enable Video For Linux API 1 (DEPRECATED)"
+-	depends on VIDEO_DEV
++	depends on VIDEO_DEV && VIDEO_V4L2_COMMON
++	default VIDEO_DEV && VIDEO_V4L2_COMMON
+ 	select VIDEO_V4L1_COMPAT
+-	default y
+ 	---help---
+ 	  Enables a compatibility API used by most V4L2 devices to allow
+ 	  its usage with legacy applications that supports only V4L1 api.
+@@ -39,7 +44,7 @@ config VIDEO_V4L1
+ config VIDEO_V4L1_COMPAT
+ 	bool "Enable Video For Linux API 1 compatible Layer"
+ 	depends on VIDEO_DEV
+-	default y
++	default VIDEO_DEV
+ 	---help---
+ 	  This api were developed to be used at Kernel 2.2 and 2.4, but
+ 	  lacks support for several video standards. There are several
+@@ -55,8 +60,8 @@ config VIDEO_V4L1_COMPAT
+ 
+ config VIDEO_V4L2
+ 	bool
+-	depends on VIDEO_DEV
+-	default y
++	depends on VIDEO_DEV && VIDEO_V4L2_COMMON
++	default VIDEO_DEV && VIDEO_V4L2_COMMON
+ 
+ source "drivers/media/video/Kconfig"
+ 
+@@ -93,7 +98,7 @@ if VIDEO_TUNER_CUSTOMIZE
+ 
+ config TUNER_XC2028
+ 	tristate "XCeive xc2028/xc3028 tuners"
+-	depends on I2C
++	depends on I2C && FW_LOADER
+ 	default m if VIDEO_TUNER_CUSTOMIZE
+ 	help
+ 	  Say Y here to include support for the xc2028/xc3028 tuners.
+@@ -180,7 +185,6 @@ config VIDEO_TVEEPROM
+ 
+ config DAB
+ 	boolean "DAB adapters"
+-	default y
+ 	---help---
+ 	  Allow selecting support for for Digital Audio Broadcasting (DAB)
+ 	  Receiver adapters.
+diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig
+index 06ca759..769c6f8 100644
+--- a/drivers/media/common/Kconfig
++++ b/drivers/media/common/Kconfig
+@@ -4,6 +4,6 @@ config VIDEO_SAA7146
+ 
+ config VIDEO_SAA7146_VV
+ 	tristate
+-	depends on VIDEO_DEV
++	depends on VIDEO_V4L2
+ 	select VIDEOBUF_DMA_SG
+ 	select VIDEO_SAA7146
+diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
+index a4a937c..2ab5a12 100644
+--- a/drivers/media/common/ir-keymaps.c
++++ b/drivers/media/common/ir-keymaps.c
+@@ -1987,3 +1987,49 @@ IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE] = {
+ };
+ 
+ EXPORT_SYMBOL_GPL(ir_codes_behold);
++
++/*
++ * Remote control for the Genius TVGO A11MCE
++ * Adrian Pardini <pardo.bsso at gmail.com>
++ */
++IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE] = {
++	/* Keys 0 to 9 */
++	[0x48] = KEY_0,
++	[0x09] = KEY_1,
++	[0x1d] = KEY_2,
++	[0x1f] = KEY_3,
++	[0x19] = KEY_4,
++	[0x1b] = KEY_5,
++	[0x11] = KEY_6,
++	[0x17] = KEY_7,
++	[0x12] = KEY_8,
++	[0x16] = KEY_9,
++
++	[0x54] = KEY_RECORD,		/* recording */
++	[0x06] = KEY_MUTE,		/* mute */
++	[0x10] = KEY_POWER,
++	[0x40] = KEY_LAST,		/* recall */
++	[0x4c] = KEY_CHANNELUP,		/* channel / program + */
++	[0x00] = KEY_CHANNELDOWN,	/* channel / program - */
++	[0x0d] = KEY_VOLUMEUP,
++	[0x15] = KEY_VOLUMEDOWN,
++	[0x4d] = KEY_OK,		/* also labeled as Pause */
++	[0x1c] = KEY_ZOOM,		/* full screen and Stop*/
++	[0x02] = KEY_MODE,		/* AV Source or Rewind*/
++	[0x04] = KEY_LIST,		/* -/-- */
++	/* small arrows above numbers */
++	[0x1a] = KEY_NEXT,		/* also Fast Forward */
++	[0x0e] = KEY_PREVIOUS,	/* also Rewind */
++	/* these are in a rather non standard layout and have
++	an alternate name written */
++	[0x1e] = KEY_UP,		/* Video Setting */
++	[0x0a] = KEY_DOWN,		/* Video Default */
++	[0x05] = KEY_LEFT,		/* Snapshot */
++	[0x0c] = KEY_RIGHT,		/* Hide Panel */
++	/* Four buttons without label */
++	[0x49] = KEY_RED,
++	[0x0b] = KEY_GREEN,
++	[0x13] = KEY_YELLOW,
++	[0x50] = KEY_BLUE,
++};
++EXPORT_SYMBOL_GPL(ir_codes_genius_tvgo_a11mce);
+diff --git a/drivers/media/common/saa7146_vbi.c b/drivers/media/common/saa7146_vbi.c
+index c32dda9..bfbd5a8 100644
+--- a/drivers/media/common/saa7146_vbi.c
++++ b/drivers/media/common/saa7146_vbi.c
+@@ -413,7 +413,6 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
+ 			    V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
+ 			    sizeof(struct saa7146_buf),
+ 			    file);
+-	mutex_init(&fh->vbi_q.lock);
+ 
+ 	init_timer(&fh->vbi_read_timeout);
+ 	fh->vbi_read_timeout.function = vbi_read_timeout;
+diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
+index c31ab48..66fdbd0 100644
+--- a/drivers/media/common/saa7146_video.c
++++ b/drivers/media/common/saa7146_video.c
+@@ -1417,8 +1417,6 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
+ 			    sizeof(struct saa7146_buf),
+ 			    file);
+ 
+-	mutex_init(&fh->video_q.lock);
+-
+ 	return 0;
+ }
+ 
+diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
+index c7bbb40..56d8fab 100644
+--- a/drivers/media/dvb/bt8xx/bt878.c
++++ b/drivers/media/dvb/bt8xx/bt878.c
+@@ -75,7 +75,11 @@ EXPORT_SYMBOL(bt878);
+ #if defined(dprintk)
+ #undef dprintk
+ #endif
+-#define dprintk if(bt878_debug) printk
++#define dprintk(fmt, arg...) \
++	do { \
++		if (bt878_debug) \
++			printk(KERN_DEBUG fmt, ##arg); \
++	} while (0)
+ 
+ static void bt878_mem_free(struct bt878 *bt)
+ {
+@@ -154,7 +158,7 @@ static int bt878_make_risc(struct bt878 *bt)
+ 	}
+ 
+ 	if (bt->line_count > 255) {
+-		printk("bt878: buffer size error!\n");
++		printk(KERN_ERR "bt878: buffer size error!\n");
+ 		return -EINVAL;
+ 	}
+ 	return 0;
+@@ -285,7 +289,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id)
+ 
+ 		if (astat & (BT878_ASCERR | BT878_AOCERR)) {
+ 			if (bt878_verbose) {
+-				printk("bt878(%d): irq%s%s risc_pc=%08x\n",
++				printk(KERN_INFO
++				       "bt878(%d): irq%s%s risc_pc=%08x\n",
+ 				       bt->nr,
+ 				       (astat & BT878_ASCERR) ? " SCERR" :
+ 				       "",
+@@ -295,8 +300,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id)
+ 		}
+ 		if (astat & (BT878_APABORT | BT878_ARIPERR | BT878_APPERR)) {
+ 			if (bt878_verbose) {
+-				printk
+-				    ("bt878(%d): irq%s%s%s risc_pc=%08x\n",
++				printk(KERN_INFO
++				     "bt878(%d): irq%s%s%s risc_pc=%08x\n",
+ 				     bt->nr,
+ 				     (astat & BT878_APABORT) ? " PABORT" :
+ 				     "",
+@@ -308,8 +313,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id)
+ 		}
+ 		if (astat & (BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS)) {
+ 			if (bt878_verbose) {
+-				printk
+-				    ("bt878(%d): irq%s%s%s risc_pc=%08x\n",
++				printk(KERN_INFO
++				     "bt878(%d): irq%s%s%s risc_pc=%08x\n",
+ 				     bt->nr,
+ 				     (astat & BT878_AFDSR) ? " FDSR" : "",
+ 				     (astat & BT878_AFTRGT) ? " FTRGT" :
+@@ -510,7 +515,7 @@ static int __devinit bt878_probe(struct pci_dev *dev,
+ */
+ 
+ 	if ((result = bt878_mem_alloc(bt))) {
+-		printk("bt878: failed to allocate memory!\n");
++		printk(KERN_ERR "bt878: failed to allocate memory!\n");
+ 		goto fail2;
+ 	}
+ 
+@@ -536,7 +541,7 @@ static void __devexit bt878_remove(struct pci_dev *pci_dev)
+ 	struct bt878 *bt = pci_get_drvdata(pci_dev);
+ 
+ 	if (bt878_verbose)
+-		printk("bt878(%d): unloading\n", bt->nr);
++		printk(KERN_INFO "bt878(%d): unloading\n", bt->nr);
+ 
+ 	/* turn off all capturing, DMA and IRQs */
+ 	btand(~0x13, BT878_AGPIO_DMA_CTL);
+diff --git a/drivers/media/dvb/dvb-usb/ttusb2.c b/drivers/media/dvb/dvb-usb/ttusb2.c
+index 88dc436..3b9da9c 100644
+--- a/drivers/media/dvb/dvb-usb/ttusb2.c
++++ b/drivers/media/dvb/dvb-usb/ttusb2.c
+@@ -144,6 +144,7 @@ static int ttusb2_power_ctrl(struct dvb_usb_device *d, int onoff)
+ static struct tda10086_config tda10086_config = {
+ 	.demod_address = 0x0e,
+ 	.invert = 0,
++	.diseqc_tone = 1,
+ };
+ 
+ static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap)
+diff --git a/drivers/media/dvb/frontends/tda10086.c b/drivers/media/dvb/frontends/tda10086.c
+index 9d26ace..0d2b69a 100644
+--- a/drivers/media/dvb/frontends/tda10086.c
++++ b/drivers/media/dvb/frontends/tda10086.c
+@@ -106,9 +106,12 @@ static int tda10086_write_mask(struct tda10086_state *state, int reg, int mask,
+ static int tda10086_init(struct dvb_frontend* fe)
+ {
+ 	struct tda10086_state* state = fe->demodulator_priv;
++	u8 t22k_off = 0x80;
+ 
+ 	dprintk ("%s\n", __FUNCTION__);
+ 
++	if (state->config->diseqc_tone)
++		t22k_off = 0;
+ 	// reset
+ 	tda10086_write_byte(state, 0x00, 0x00);
+ 	msleep(10);
+@@ -158,7 +161,7 @@ static int tda10086_init(struct dvb_frontend* fe)
+ 	tda10086_write_byte(state, 0x3d, 0x80);
+ 
+ 	// setup SEC
+-	tda10086_write_byte(state, 0x36, 0x80); // all SEC off, no 22k tone
++	tda10086_write_byte(state, 0x36, t22k_off); // all SEC off, 22k tone
+ 	tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000)));      // } tone frequency
+ 	tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8); // }
+ 
+@@ -180,16 +183,20 @@ static void tda10086_diseqc_wait(struct tda10086_state *state)
+ static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+ {
+ 	struct tda10086_state* state = fe->demodulator_priv;
++	u8 t22k_off = 0x80;
+ 
+ 	dprintk ("%s\n", __FUNCTION__);
+ 
++	if (state->config->diseqc_tone)
++		t22k_off = 0;
++
+ 	switch (tone) {
+ 	case SEC_TONE_OFF:
+-		tda10086_write_byte(state, 0x36, 0x80);
++		tda10086_write_byte(state, 0x36, t22k_off);
+ 		break;
+ 
+ 	case SEC_TONE_ON:
+-		tda10086_write_byte(state, 0x36, 0x81);
++		tda10086_write_byte(state, 0x36, 0x01 + t22k_off);
+ 		break;
+ 	}
+ 
+@@ -202,9 +209,13 @@ static int tda10086_send_master_cmd (struct dvb_frontend* fe,
+ 	struct tda10086_state* state = fe->demodulator_priv;
+ 	int i;
+ 	u8 oldval;
++	u8 t22k_off = 0x80;
+ 
+ 	dprintk ("%s\n", __FUNCTION__);
+ 
++	if (state->config->diseqc_tone)
++		t22k_off = 0;
++
+ 	if (cmd->msg_len > 6)
+ 		return -EINVAL;
+ 	oldval = tda10086_read_byte(state, 0x36);
+@@ -212,7 +223,8 @@ static int tda10086_send_master_cmd (struct dvb_frontend* fe,
+ 	for(i=0; i< cmd->msg_len; i++) {
+ 		tda10086_write_byte(state, 0x48+i, cmd->msg[i]);
+ 	}
+-	tda10086_write_byte(state, 0x36, 0x88 | ((cmd->msg_len - 1) << 4));
++	tda10086_write_byte(state, 0x36, (0x08 + t22k_off)
++					| ((cmd->msg_len - 1) << 4));
+ 
+ 	tda10086_diseqc_wait(state);
+ 
+@@ -225,16 +237,20 @@ static int tda10086_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minic
+ {
+ 	struct tda10086_state* state = fe->demodulator_priv;
+ 	u8 oldval = tda10086_read_byte(state, 0x36);
++	u8 t22k_off = 0x80;
+ 
+ 	dprintk ("%s\n", __FUNCTION__);
+ 
++	if (state->config->diseqc_tone)
++		t22k_off = 0;
++
+ 	switch(minicmd) {
+ 	case SEC_MINI_A:
+-		tda10086_write_byte(state, 0x36, 0x84);
++		tda10086_write_byte(state, 0x36, 0x04 + t22k_off);
+ 		break;
+ 
+ 	case SEC_MINI_B:
+-		tda10086_write_byte(state, 0x36, 0x86);
++		tda10086_write_byte(state, 0x36, 0x06 + t22k_off);
+ 		break;
+ 	}
+ 
+diff --git a/drivers/media/dvb/frontends/tda10086.h b/drivers/media/dvb/frontends/tda10086.h
+index ed584a8..eeceaee 100644
+--- a/drivers/media/dvb/frontends/tda10086.h
++++ b/drivers/media/dvb/frontends/tda10086.h
+@@ -33,6 +33,9 @@ struct tda10086_config
+ 
+ 	/* does the "inversion" need inverted? */
+ 	u8 invert;
++
++	/* do we need the diseqc signal with carrier? */
++	u8 diseqc_tone;
+ };
+ 
+ #if defined(CONFIG_DVB_TDA10086) || (defined(CONFIG_DVB_TDA10086_MODULE) && defined(MODULE))
+diff --git a/drivers/media/dvb/frontends/tda18271-common.c b/drivers/media/dvb/frontends/tda18271-common.c
+index cebb6b9..bca5709 100644
+--- a/drivers/media/dvb/frontends/tda18271-common.c
++++ b/drivers/media/dvb/frontends/tda18271-common.c
+@@ -171,7 +171,7 @@ int tda18271_read_extended(struct dvb_frontend *fe)
+ 	if (ret != 2)
+ 		tda_err("ERROR: i2c_transfer returned: %d\n", ret);
+ 
+-	for (i = 0; i <= TDA18271_NUM_REGS; i++) {
++	for (i = 0; i < TDA18271_NUM_REGS; i++) {
+ 		/* don't update write-only registers */
+ 		if ((i != R_EB9)  &&
+ 		    (i != R_EB16) &&
+diff --git a/drivers/media/dvb/frontends/xc5000.h b/drivers/media/dvb/frontends/xc5000.h
+index e0e8456..32a5f1c 100644
+--- a/drivers/media/dvb/frontends/xc5000.h
++++ b/drivers/media/dvb/frontends/xc5000.h
+@@ -45,7 +45,8 @@ struct xc5000_config {
+ /* xc5000 callback command */
+ #define XC5000_TUNER_RESET		0
+ 
+-#if defined(CONFIG_DVB_TUNER_XC5000) || defined(CONFIG_DVB_TUNER_XC5000_MODULE)
++#if defined(CONFIG_DVB_TUNER_XC5000) || \
++    (defined(CONFIG_DVB_TUNER_XC5000_MODULE) && defined(MODULE))
+ extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
+ 					  struct i2c_adapter *i2c,
+ 					  struct xc5000_config *cfg);
+diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
+index aef6e36..3e6b650 100644
+--- a/drivers/media/dvb/ttpci/av7110_av.c
++++ b/drivers/media/dvb/ttpci/av7110_av.c
+@@ -966,6 +966,7 @@ static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x
+ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock)
+ {
+ 	int i, n;
++	int progressive = 0;
+ 
+ 	dprintk(2, "av7110:%p, \n", av7110);
+ 
+@@ -974,6 +975,14 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len
+ 			return -EBUSY;
+ 	}
+ 
++	for (i = 0; i < len - 5; i++) {
++		/* get progressive flag from picture extension */
++		if (buf[i] == 0x00 && buf[i+1] == 0x00 &&
++		    buf[i+2] == 0x01 && (unsigned char)buf[i+3] == 0xb5 &&
++		    (buf[i+4] & 0xf0) == 0x10)
++			progressive = buf[i+5] & 0x08;
++	}
++
+ 	/* setting n always > 1, fixes problems when playing stillframes
+ 	   consisting of I- and P-Frames */
+ 	n = MIN_IFRAME / len + 1;
+@@ -985,7 +994,11 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len
+ 		dvb_play(av7110, buf, len, 0, 1);
+ 
+ 	av7110_ipack_flush(&av7110->ipack[1]);
+-	return 0;
++
++	if (progressive)
++		return vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1);
++	else
++		return 0;
+ }
+ 
+ 
+diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
+index 3439c98..2d64d55 100644
+--- a/drivers/media/dvb/ttpci/budget-av.c
++++ b/drivers/media/dvb/ttpci/budget-av.c
+@@ -896,6 +896,7 @@ static u8 read_pwm(struct budget_av *budget_av)
+ #define SUBID_DVBS_CINERGY1200		0x1154
+ #define SUBID_DVBS_CYNERGY1200N 	0x1155
+ #define SUBID_DVBS_TV_STAR		0x0014
++#define SUBID_DVBS_TV_STAR_PLUS_X4	0x0015
+ #define SUBID_DVBS_TV_STAR_CI		0x0016
+ #define SUBID_DVBS_EASYWATCH_1  	0x001a
+ #define SUBID_DVBS_EASYWATCH_2  	0x001b
+@@ -910,6 +911,7 @@ static u8 read_pwm(struct budget_av *budget_av)
+ #define SUBID_DVBC_CINERGY1200		0x1156
+ #define SUBID_DVBC_CINERGY1200_MK3	0x1176
+ 
++#define SUBID_DVBT_EASYWATCH		0x003a
+ #define SUBID_DVBT_KNC1_PLUS		0x0031
+ #define SUBID_DVBT_KNC1			0x0030
+ #define SUBID_DVBT_CINERGY1200		0x1157
+@@ -957,6 +959,7 @@ static void frontend_init(struct budget_av *budget_av)
+ 		break;
+ 
+ 	case SUBID_DVBS_TV_STAR:
++	case SUBID_DVBS_TV_STAR_PLUS_X4:
+ 	case SUBID_DVBS_TV_STAR_CI:
+ 	case SUBID_DVBS_CYNERGY1200N:
+ 	case SUBID_DVBS_EASYWATCH:
+@@ -1018,6 +1021,7 @@ static void frontend_init(struct budget_av *budget_av)
+ 		}
+ 		break;
+ 
++	case SUBID_DVBT_EASYWATCH:
+ 	case SUBID_DVBT_KNC1:
+ 	case SUBID_DVBT_KNC1_PLUS:
+ 	case SUBID_DVBT_CINERGY1200:
+@@ -1248,7 +1252,9 @@ MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
+ MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S);
+ MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
+ MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3);
++MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T);
+ MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
++MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP);
+ MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
+ MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3);
+ MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3);
+@@ -1266,12 +1272,14 @@ static struct pci_device_id pci_tbl[] = {
+ 	MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
+ 	MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011),
+ 	MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
++	MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015),
+ 	MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
+ 	MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
+ 	MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
+ 	MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b),
+ 	MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
+ 	MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c),
++	MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a),
+ 	MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
+ 	MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
+ 	MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022),
+diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
+index 9268a82..14b00f5 100644
+--- a/drivers/media/dvb/ttpci/budget.c
++++ b/drivers/media/dvb/ttpci/budget.c
+@@ -351,6 +351,7 @@ static struct s5h1420_config s5h1420_config = {
+ static struct tda10086_config tda10086_config = {
+ 	.demod_address = 0x0e,
+ 	.invert = 0,
++	.diseqc_tone = 1,
+ };
+ 
+ static u8 read_pwm(struct budget* budget)
+diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
+index 8d5214f..1b41b3f 100644
+--- a/drivers/media/radio/Kconfig
++++ b/drivers/media/radio/Kconfig
+@@ -4,12 +4,12 @@
+ 
+ menuconfig RADIO_ADAPTERS
+ 	bool "Radio Adapters"
+-	depends on VIDEO_DEV
++	depends on VIDEO_V4L2
+ 	default y
+ 	---help---
+ 	  Say Y here to enable selecting AM/FM radio adapters.
+ 
+-if RADIO_ADAPTERS && VIDEO_DEV
++if RADIO_ADAPTERS && VIDEO_V4L2
+ 
+ config RADIO_CADET
+ 	tristate "ADS Cadet AM/FM Tuner"
+diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
+index 3118bda..53e1148 100644
+--- a/drivers/media/radio/radio-sf16fmi.c
++++ b/drivers/media/radio/radio-sf16fmi.c
+@@ -361,6 +361,7 @@ static int __init fmi_init(void)
+ 	}
+ 	if (!request_region(io, 2, "radio-sf16fmi")) {
+ 		printk(KERN_ERR "radio-sf16fmi: port 0x%x already in use\n", io);
++		pnp_device_detach(dev);
+ 		return -EBUSY;
+ 	}
+ 
+diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
+index f7c8b00..ebc5fbb 100644
+--- a/drivers/media/radio/radio-sf16fmr2.c
++++ b/drivers/media/radio/radio-sf16fmr2.c
+@@ -470,9 +470,8 @@ static int __init fmr2_init(void)
+ 
+ 	mutex_init(&lock);
+ 
+-	if (request_region(io, 2, "sf16fmr2"))
+-	{
+-		printk(KERN_ERR "fmr2: port 0x%x already in use\n", io);
++	if (!request_region(io, 2, "sf16fmr2")) {
++		printk(KERN_ERR "radio-sf16fmr2: request_region failed!\n");
+ 		return -EBUSY;
+ 	}
+ 
+diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
+index 8e4bd47..649f14d 100644
+--- a/drivers/media/radio/radio-si470x.c
++++ b/drivers/media/radio/radio-si470x.c
+@@ -62,6 +62,29 @@
+  *		- code cleaned of unnecessary rds_commands
+  *		- USB Vendor/Product ID for ADS/Tech FM Radio Receiver verified
+  *		  (thanks to Guillaume RAMOUSSE)
++ * 2008-01-27	Tobias Lorenz <tobias.lorenz at gmx.net>
++ *		Version 1.0.5
++ *		- number of seek_retries changed to tune_timeout
++ *		- fixed problem with incomplete tune operations by own buffers
++ *		- optimization of variables and printf types
++ *		- improved error logging
++ * 2008-01-31	Tobias Lorenz <tobias.lorenz at gmx.net>
++ *		Oliver Neukum <oliver at neukum.org>
++ *		Version 1.0.6
++ *		- fixed coverity checker warnings in *_usb_driver_disconnect
++ *		- probe()/open() race by correct ordering in probe()
++ *		- DMA coherency rules by separate allocation of all buffers
++ *		- use of endianness macros
++ *		- abuse of spinlock, replaced by mutex
++ *		- racy handling of timer in disconnect,
++ *		  replaced by delayed_work
++ *		- racy interruptible_sleep_on(),
++ *		  replaced with wait_event_interruptible()
++ *		- handle signals in read()
++ * 2008-02-08	Tobias Lorenz <tobias.lorenz at gmx.net>
++ *		Oliver Neukum <oliver at neukum.org>
++ *		Version 1.0.7
++ *		- usb autosuspend support
+  *
+  * ToDo:
+  * - add seeking support
+@@ -74,9 +97,10 @@
+ /* driver definitions */
+ #define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz at gmx.net>"
+ #define DRIVER_NAME "radio-si470x"
+-#define DRIVER_VERSION KERNEL_VERSION(1, 0, 4)
++#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 6)
+ #define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
+ #define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
++#define DRIVER_VERSION "1.0.6"
+ 
+ 
+ /* kernel includes */
+@@ -89,8 +113,10 @@
+ #include <linux/hid.h>
+ #include <linux/version.h>
+ #include <linux/videodev2.h>
++#include <linux/mutex.h>
+ #include <media/v4l2-common.h>
+ #include <media/rds.h>
++#include <asm/unaligned.h>
+ 
+ 
+ /* USB Device ID List */
+@@ -119,56 +145,56 @@ MODULE_PARM_DESC(radio_nr, "Radio Nr");
+ /* 0: 200 kHz (USA, Australia) */
+ /* 1: 100 kHz (Europe, Japan) */
+ /* 2:  50 kHz */
+-static int space = 2;
+-module_param(space, int, 0);
++static unsigned short space = 2;
++module_param(space, ushort, 0);
+ MODULE_PARM_DESC(radio_nr, "Spacing: 0=200kHz 1=100kHz *2=50kHz*");
+ 
+ /* Bottom of Band (MHz) */
+ /* 0: 87.5 - 108 MHz (USA, Europe)*/
+ /* 1: 76   - 108 MHz (Japan wide band) */
+ /* 2: 76   -  90 MHz (Japan) */
+-static int band = 1;
+-module_param(band, int, 0);
++static unsigned short band = 1;
++module_param(band, ushort, 0);
+ MODULE_PARM_DESC(radio_nr, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz");
+ 
+ /* De-emphasis */
+ /* 0: 75 us (USA) */
+ /* 1: 50 us (Europe, Australia, Japan) */
+-static int de = 1;
+-module_param(de, int, 0);
++static unsigned short de = 1;
++module_param(de, ushort, 0);
+ MODULE_PARM_DESC(radio_nr, "De-emphasis: 0=75us *1=50us*");
+ 
+ /* USB timeout */
+-static int usb_timeout = 500;
+-module_param(usb_timeout, int, 0);
++static unsigned int usb_timeout = 500;
++module_param(usb_timeout, uint, 0);
+ MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*");
+ 
+-/* Seek retries */
+-static int seek_retries = 100;
+-module_param(seek_retries, int, 0);
+-MODULE_PARM_DESC(seek_retries, "Seek retries: *100*");
++/* Tune timeout */
++static unsigned int tune_timeout = 3000;
++module_param(tune_timeout, uint, 0);
++MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*");
+ 
+ /* RDS buffer blocks */
+-static int rds_buf = 100;
+-module_param(rds_buf, int, 0);
++static unsigned int rds_buf = 100;
++module_param(rds_buf, uint, 0);
+ MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
+ 
+ /* RDS maximum block errors */
+-static int max_rds_errors = 1;
++static unsigned short max_rds_errors = 1;
+ /* 0 means   0  errors requiring correction */
+ /* 1 means 1-2  errors requiring correction (used by original USBRadio.exe) */
+ /* 2 means 3-5  errors requiring correction */
+ /* 3 means   6+ errors or errors in checkword, correction not possible */
+-module_param(max_rds_errors, int, 0);
++module_param(max_rds_errors, ushort, 0);
+ MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
+ 
+ /* RDS poll frequency */
+-static int rds_poll_time = 40;
++static unsigned int rds_poll_time = 40;
+ /* 40 is used by the original USBRadio.exe */
+ /* 50 is used by radio-cadet */
+ /* 75 should be okay */
+ /* 80 is the usual RDS receive interval */
+-module_param(rds_poll_time, int, 0);
++module_param(rds_poll_time, uint, 0);
+ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
+ 
+ 
+@@ -393,22 +419,19 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
+ struct si470x_device {
+ 	/* reference to USB and video device */
+ 	struct usb_device *usbdev;
++	struct usb_interface *intf;
+ 	struct video_device *videodev;
+ 
+-	/* are these really necessary ? */
+-	int users;
+-
+-	/* report buffer (maximum 64 bytes) */
+-	unsigned char buf[64];
++	/* driver management */
++	unsigned int users;
+ 
+ 	/* Silabs internal registers (0..15) */
+ 	unsigned short registers[RADIO_REGISTER_NUM];
+ 
+ 	/* RDS receive buffer */
+-	struct work_struct work;
++	struct delayed_work work;
+ 	wait_queue_head_t read_queue;
+-	struct timer_list timer;
+-	spinlock_t lock;		/* buffer locking */
++	struct mutex lock;		/* buffer locking */
+ 	unsigned char *buffer;		/* size is always multiple of three */
+ 	unsigned int buf_size;
+ 	unsigned int rd_index;
+@@ -434,28 +457,46 @@ struct si470x_device {
+ /*
+  * si470x_get_report - receive a HID report
+  */
+-static int si470x_get_report(struct si470x_device *radio, int size)
++static int si470x_get_report(struct si470x_device *radio, void *buf, int size)
+ {
+-	return usb_control_msg(radio->usbdev,
++	unsigned char *report = (unsigned char *) buf;
++	int retval;
++
++	retval = usb_control_msg(radio->usbdev,
+ 		usb_rcvctrlpipe(radio->usbdev, 0),
+ 		HID_REQ_GET_REPORT,
+ 		USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
+-		radio->buf[0], 2,
+-		radio->buf, size, usb_timeout);
++		report[0], 2,
++		buf, size, usb_timeout);
++	if (retval < 0)
++		printk(KERN_WARNING DRIVER_NAME
++			": si470x_get_report: usb_control_msg returned %d\n",
++			retval);
++
++	return retval;
+ }
+ 
+ 
+ /*
+  * si470x_set_report - send a HID report
+  */
+-static int si470x_set_report(struct si470x_device *radio, int size)
++static int si470x_set_report(struct si470x_device *radio, void *buf, int size)
+ {
+-	return usb_control_msg(radio->usbdev,
++	unsigned char *report = (unsigned char *) buf;
++	int retval;
++
++	retval = usb_control_msg(radio->usbdev,
+ 		usb_sndctrlpipe(radio->usbdev, 0),
+ 		HID_REQ_SET_REPORT,
+ 		USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
+-		radio->buf[0], 2,
+-		radio->buf, size, usb_timeout);
++		report[0], 2,
++		buf, size, usb_timeout);
++	if (retval < 0)
++		printk(KERN_WARNING DRIVER_NAME
++			": si470x_set_report: usb_control_msg returned %d\n",
++			retval);
++
++	return retval;
+ }
+ 
+ 
+@@ -464,13 +505,16 @@ static int si470x_set_report(struct si470x_device *radio, int size)
+  */
+ static int si470x_get_register(struct si470x_device *radio, int regnr)
+ {
++	unsigned char buf[REGISTER_REPORT_SIZE];
+ 	int retval;
+ 
+-	radio->buf[0] = REGISTER_REPORT(regnr);
++	buf[0] = REGISTER_REPORT(regnr);
++
++	retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
+ 
+-	retval = si470x_get_report(radio, REGISTER_REPORT_SIZE);
+ 	if (retval >= 0)
+-		radio->registers[regnr] = (radio->buf[1] << 8) | radio->buf[2];
++		radio->registers[regnr] = be16_to_cpu(get_unaligned(
++			(unsigned short *) &buf[1]));
+ 
+ 	return (retval < 0) ? -EINVAL : 0;
+ }
+@@ -481,13 +525,14 @@ static int si470x_get_register(struct si470x_device *radio, int regnr)
+  */
+ static int si470x_set_register(struct si470x_device *radio, int regnr)
+ {
++	unsigned char buf[REGISTER_REPORT_SIZE];
+ 	int retval;
+ 
+-	radio->buf[0] = REGISTER_REPORT(regnr);
+-	radio->buf[1] = (radio->registers[regnr] & 0xff00) >> 8;
+-	radio->buf[2] = (radio->registers[regnr] & 0x00ff);
++	buf[0] = REGISTER_REPORT(regnr);
++	put_unaligned(cpu_to_be16(radio->registers[regnr]),
++		(unsigned short *) &buf[1]);
+ 
+-	retval = si470x_set_report(radio, REGISTER_REPORT_SIZE);
++	retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
+ 
+ 	return (retval < 0) ? -EINVAL : 0;
+ }
+@@ -498,18 +543,19 @@ static int si470x_set_register(struct si470x_device *radio, int regnr)
+  */
+ static int si470x_get_all_registers(struct si470x_device *radio)
+ {
++	unsigned char buf[ENTIRE_REPORT_SIZE];
+ 	int retval;
+-	int regnr;
++	unsigned char regnr;
+ 
+-	radio->buf[0] = ENTIRE_REPORT;
++	buf[0] = ENTIRE_REPORT;
+ 
+-	retval = si470x_get_report(radio, ENTIRE_REPORT_SIZE);
++	retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
+ 
+ 	if (retval >= 0)
+ 		for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
+-			radio->registers[regnr] =
+-			(radio->buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) |
+-			 radio->buf[regnr * RADIO_REGISTER_SIZE + 2];
++			radio->registers[regnr] = be16_to_cpu(get_unaligned(
++				(unsigned short *)
++				&buf[regnr * RADIO_REGISTER_SIZE + 1]));
+ 
+ 	return (retval < 0) ? -EINVAL : 0;
+ }
+@@ -520,21 +566,28 @@ static int si470x_get_all_registers(struct si470x_device *radio)
+  */
+ static int si470x_get_rds_registers(struct si470x_device *radio)
+ {
++	unsigned char buf[RDS_REPORT_SIZE];
+ 	int retval;
+-	int regnr;
+ 	int size;
++	unsigned char regnr;
+ 
+-	radio->buf[0] = RDS_REPORT;
++	buf[0] = RDS_REPORT;
+ 
+ 	retval = usb_interrupt_msg(radio->usbdev,
+-		usb_rcvctrlpipe(radio->usbdev, 1),
+-		radio->buf, RDS_REPORT_SIZE, &size, usb_timeout);
++		usb_rcvintpipe(radio->usbdev, 1),
++		(void *) &buf, sizeof(buf), &size, usb_timeout);
++	if (size != sizeof(buf))
++		printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_register: "
++			"return size differs: %d != %zu\n", size, sizeof(buf));
++	if (retval < 0)
++		printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
++			"usb_interrupt_msg returned %d\n", retval);
+ 
+ 	if (retval >= 0)
+ 		for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
+ 			radio->registers[STATUSRSSI + regnr] =
+-			(radio->buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) |
+-			 radio->buf[regnr * RADIO_REGISTER_SIZE + 2];
++				be16_to_cpu(get_unaligned((unsigned short *)
++				&buf[regnr * RADIO_REGISTER_SIZE + 1]));
+ 
+ 	return (retval < 0) ? -EINVAL : 0;
+ }
+@@ -543,9 +596,11 @@ static int si470x_get_rds_registers(struct si470x_device *radio)
+ /*
+  * si470x_set_chan - set the channel
+  */
+-static int si470x_set_chan(struct si470x_device *radio, int chan)
++static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
+ {
+-	int retval, i;
++	int retval;
++	unsigned long timeout;
++	bool timed_out = 0;
+ 
+ 	/* start tuning */
+ 	radio->registers[CHANNEL] &= ~CHANNEL_CHAN;
+@@ -555,16 +610,17 @@ static int si470x_set_chan(struct si470x_device *radio, int chan)
+ 		return retval;
+ 
+ 	/* wait till seek operation has completed */
+-	i = 0;
++	timeout = jiffies + msecs_to_jiffies(tune_timeout);
+ 	do {
+ 		retval = si470x_get_register(radio, STATUSRSSI);
+ 		if (retval < 0)
+ 			return retval;
+-	} while ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) &&
+-		(++i < seek_retries));
+-	if (i >= seek_retries)
++		timed_out = time_after(jiffies, timeout);
++	} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
++		(!timed_out));
++	if (timed_out)
+ 		printk(KERN_WARNING DRIVER_NAME
+-			": seek does not finish after %d tries\n", i);
++			": seek does not finish after %u ms\n", tune_timeout);
+ 
+ 	/* stop tuning */
+ 	radio->registers[CHANNEL] &= ~CHANNEL_TUNE;
+@@ -575,9 +631,10 @@ static int si470x_set_chan(struct si470x_device *radio, int chan)
+ /*
+  * si470x_get_freq - get the frequency
+  */
+-static int si470x_get_freq(struct si470x_device *radio)
++static unsigned int si470x_get_freq(struct si470x_device *radio)
+ {
+-	int spacing, band_bottom, chan, freq;
++	unsigned int spacing, band_bottom, freq;
++	unsigned short chan;
+ 	int retval;
+ 
+ 	/* Spacing (kHz) */
+@@ -616,9 +673,10 @@ static int si470x_get_freq(struct si470x_device *radio)
+ /*
+  * si470x_set_freq - set the frequency
+  */
+-static int si470x_set_freq(struct si470x_device *radio, int freq)
++static int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
+ {
+-	int spacing, band_bottom, chan;
++	unsigned int spacing, band_bottom;
++	unsigned short chan;
+ 
+ 	/* Spacing (kHz) */
+ 	switch (space) {
+@@ -709,9 +767,17 @@ static int si470x_stop(struct si470x_device *radio)
+  */
+ static int si470x_rds_on(struct si470x_device *radio)
+ {
++	int retval;
++
+ 	/* sysconfig 1 */
++	mutex_lock(&radio->lock);
+ 	radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDS;
+-	return si470x_set_register(radio, SYSCONFIG1);
++	retval = si470x_set_register(radio, SYSCONFIG1);
++	if (retval < 0)
++		radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS;
++	mutex_unlock(&radio->lock);
++
++	return retval;
+ }
+ 
+ 
+@@ -725,11 +791,10 @@ static int si470x_rds_on(struct si470x_device *radio)
+  */
+ static void si470x_rds(struct si470x_device *radio)
+ {
+-	unsigned char tmpbuf[3];
+ 	unsigned char blocknum;
+-	unsigned char bler; /* rds block errors */
++	unsigned short bler; /* rds block errors */
+ 	unsigned short rds;
+-	unsigned int i;
++	unsigned char tmpbuf[3];
+ 
+ 	/* get rds blocks */
+ 	if (si470x_get_rds_registers(radio) < 0)
+@@ -743,63 +808,58 @@ static void si470x_rds(struct si470x_device *radio)
+ 		return;
+ 	}
+ 
+-	/* copy four RDS blocks to internal buffer */
+-	if (spin_trylock(&radio->lock)) {
+-		/* process each rds block */
+-		for (blocknum = 0; blocknum < 4; blocknum++) {
+-			switch (blocknum) {
+-			default:
+-				bler = (radio->registers[STATUSRSSI] &
+-						STATUSRSSI_BLERA) >> 9;
+-				rds = radio->registers[RDSA];
+-				break;
+-			case 1:
+-				bler = (radio->registers[READCHAN] &
+-						READCHAN_BLERB) >> 14;
+-				rds = radio->registers[RDSB];
+-				break;
+-			case 2:
+-				bler = (radio->registers[READCHAN] &
+-						READCHAN_BLERC) >> 12;
+-				rds = radio->registers[RDSC];
+-				break;
+-			case 3:
+-				bler = (radio->registers[READCHAN] &
+-						READCHAN_BLERD) >> 10;
+-				rds = radio->registers[RDSD];
+-				break;
+-			};
+-
+-			/* Fill the V4L2 RDS buffer */
+-			tmpbuf[0] = rds & 0x00ff;	/* LSB */
+-			tmpbuf[1] = (rds & 0xff00) >> 8;/* MSB */
+-			tmpbuf[2] = blocknum;		/* offset name */
+-			tmpbuf[2] |= blocknum << 3;	/* received offset */
+-			if (bler > max_rds_errors)
+-				tmpbuf[2] |= 0x80; /* uncorrectable errors */
+-			else if (bler > 0)
+-				tmpbuf[2] |= 0x40; /* corrected error(s) */
+-
+-			/* copy RDS block to internal buffer */
+-			for (i = 0; i < 3; i++) {
+-				radio->buffer[radio->wr_index] = tmpbuf[i];
+-				radio->wr_index++;
+-			}
+-
+-			/* wrap write pointer */
+-			if (radio->wr_index >= radio->buf_size)
+-				radio->wr_index = 0;
+-
+-			/* check for overflow */
+-			if (radio->wr_index == radio->rd_index) {
+-				/* increment and wrap read pointer */
+-				radio->rd_index += 3;
+-				if (radio->rd_index >= radio->buf_size)
+-					radio->rd_index = 0;
+-			}
++	/* copy all four RDS blocks to internal buffer */
++	mutex_lock(&radio->lock);
++	for (blocknum = 0; blocknum < 4; blocknum++) {
++		switch (blocknum) {
++		default:
++			bler = (radio->registers[STATUSRSSI] &
++					STATUSRSSI_BLERA) >> 9;
++			rds = radio->registers[RDSA];
++			break;
++		case 1:
++			bler = (radio->registers[READCHAN] &
++					READCHAN_BLERB) >> 14;
++			rds = radio->registers[RDSB];
++			break;
++		case 2:
++			bler = (radio->registers[READCHAN] &
++					READCHAN_BLERC) >> 12;
++			rds = radio->registers[RDSC];
++			break;
++		case 3:
++			bler = (radio->registers[READCHAN] &
++					READCHAN_BLERD) >> 10;
++			rds = radio->registers[RDSD];
++			break;
++		};
++
++		/* Fill the V4L2 RDS buffer */
++		put_unaligned(cpu_to_le16(rds), (unsigned short *) &tmpbuf);
++		tmpbuf[2] = blocknum;		/* offset name */
++		tmpbuf[2] |= blocknum << 3;	/* received offset */
++		if (bler > max_rds_errors)
++			tmpbuf[2] |= 0x80; /* uncorrectable errors */
++		else if (bler > 0)
++			tmpbuf[2] |= 0x40; /* corrected error(s) */
++
++		/* copy RDS block to internal buffer */
++		memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3);
++		radio->wr_index += 3;
++
++		/* wrap write pointer */
++		if (radio->wr_index >= radio->buf_size)
++			radio->wr_index = 0;
++
++		/* check for overflow */
++		if (radio->wr_index == radio->rd_index) {
++			/* increment and wrap read pointer */
++			radio->rd_index += 3;
++			if (radio->rd_index >= radio->buf_size)
++				radio->rd_index = 0;
+ 		}
+-		spin_unlock(&radio->lock);
+ 	}
++	mutex_unlock(&radio->lock);
+ 
+ 	/* wake up read queue */
+ 	if (radio->wr_index != radio->rd_index)
+@@ -808,29 +868,18 @@ static void si470x_rds(struct si470x_device *radio)
+ 
+ 
+ /*
+- * si470x_timer - rds timer function
+- */
+-static void si470x_timer(unsigned long data)
+-{
+-	struct si470x_device *radio = (struct si470x_device *) data;
+-
+-	schedule_work(&radio->work);
+-}
+-
+-
+-/*
+  * si470x_work - rds work function
+  */
+ static void si470x_work(struct work_struct *work)
+ {
+ 	struct si470x_device *radio = container_of(work, struct si470x_device,
+-		work);
++		work.work);
+ 
+ 	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
+ 		return;
+ 
+ 	si470x_rds(radio);
+-	mod_timer(&radio->timer, jiffies + msecs_to_jiffies(rds_poll_time));
++	schedule_delayed_work(&radio->work, msecs_to_jiffies(rds_poll_time));
+ }
+ 
+ 
+@@ -852,44 +901,44 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf,
+ 	/* switch on rds reception */
+ 	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
+ 		si470x_rds_on(radio);
+-		schedule_work(&radio->work);
++		schedule_delayed_work(&radio->work,
++			msecs_to_jiffies(rds_poll_time));
+ 	}
+ 
+ 	/* block if no new data available */
+ 	while (radio->wr_index == radio->rd_index) {
+ 		if (file->f_flags & O_NONBLOCK)
+ 			return -EWOULDBLOCK;
+-		interruptible_sleep_on(&radio->read_queue);
++		if (wait_event_interruptible(radio->read_queue,
++			radio->wr_index != radio->rd_index) < 0)
++			return -EINTR;
+ 	}
+ 
+ 	/* calculate block count from byte count */
+ 	count /= 3;
+ 
+ 	/* copy RDS block out of internal buffer and to user buffer */
+-	if (spin_trylock(&radio->lock)) {
+-		while (block_count < count) {
+-			if (radio->rd_index == radio->wr_index)
+-				break;
+-
+-			/* always transfer rds complete blocks */
+-			if (copy_to_user(buf,
+-					&radio->buffer[radio->rd_index], 3))
+-				/* retval = -EFAULT; */
+-				break;
+-
+-			/* increment and wrap read pointer */
+-			radio->rd_index += 3;
+-			if (radio->rd_index >= radio->buf_size)
+-				radio->rd_index = 0;
+-
+-			/* increment counters */
+-			block_count++;
+-			buf += 3;
+-			retval += 3;
+-		}
+-
+-		spin_unlock(&radio->lock);
++	mutex_lock(&radio->lock);
++	while (block_count < count) {
++		if (radio->rd_index == radio->wr_index)
++			break;
++
++		/* always transfer rds complete blocks */
++		if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3))
++			/* retval = -EFAULT; */
++			break;
++
++		/* increment and wrap read pointer */
++		radio->rd_index += 3;
++		if (radio->rd_index >= radio->buf_size)
++			radio->rd_index = 0;
++
++		/* increment counters */
++		block_count++;
++		buf += 3;
++		retval += 3;
+ 	}
++	mutex_unlock(&radio->lock);
+ 
+ 	return retval;
+ }
+@@ -906,7 +955,8 @@ static unsigned int si470x_fops_poll(struct file *file,
+ 	/* switch on rds reception */
+ 	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
+ 		si470x_rds_on(radio);
+-		schedule_work(&radio->work);
++		schedule_delayed_work(&radio->work,
++			msecs_to_jiffies(rds_poll_time));
+ 	}
+ 
+ 	poll_wait(file, &radio->read_queue, pts);
+@@ -924,10 +974,22 @@ static unsigned int si470x_fops_poll(struct file *file,
+ static int si470x_fops_open(struct inode *inode, struct file *file)
+ {
+ 	struct si470x_device *radio = video_get_drvdata(video_devdata(file));
++	int retval;
+ 
+ 	radio->users++;
+-	if (radio->users == 1)
+-		return si470x_start(radio);
++
++	retval = usb_autopm_get_interface(radio->intf);
++	if (retval < 0) {
++		radio->users--;
++		return -EIO;
++	}
++
++	if (radio->users == 1) {
++		retval = si470x_start(radio);
++		if (retval < 0)
++			usb_autopm_put_interface(radio->intf);
++		return retval;
++	}
+ 
+ 	return 0;
+ }
+@@ -939,6 +1001,7 @@ static int si470x_fops_open(struct inode *inode, struct file *file)
+ static int si470x_fops_release(struct inode *inode, struct file *file)
+ {
+ 	struct si470x_device *radio = video_get_drvdata(video_devdata(file));
++	int retval;
+ 
+ 	if (!radio)
+ 		return -ENODEV;
+@@ -946,13 +1009,14 @@ static int si470x_fops_release(struct inode *inode, struct file *file)
+ 	radio->users--;
+ 	if (radio->users == 0) {
+ 		/* stop rds reception */
+-		del_timer_sync(&radio->timer);
+-		flush_scheduled_work();
++		cancel_delayed_work_sync(&radio->work);
+ 
+ 		/* cancel read processes */
+ 		wake_up_interruptible(&radio->read_queue);
+ 
+-		return si470x_stop(radio);
++		retval = si470x_stop(radio);
++		usb_autopm_put_interface(radio->intf);
++		return retval;
+ 	}
+ 
+ 	return 0;
+@@ -1030,7 +1094,7 @@ static int si470x_vidioc_querycap(struct file *file, void *priv,
+ 	strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
+ 	strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
+ 	sprintf(capability->bus_info, "USB");
+-	capability->version = DRIVER_VERSION;
++	capability->version = DRIVER_KERNEL_VERSION;
+ 	capability->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+ 
+ 	return 0;
+@@ -1067,16 +1131,21 @@ static int si470x_vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+ static int si470x_vidioc_queryctrl(struct file *file, void *priv,
+ 		struct v4l2_queryctrl *qc)
+ {
+-	int i;
++	unsigned char i;
++	int retval = -EINVAL;
+ 
+ 	for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) {
+ 		if (qc->id && qc->id == si470x_v4l2_queryctrl[i].id) {
+ 			memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc));
+-			return 0;
++			retval = 0;
++			break;
+ 		}
+ 	}
++	if (retval < 0)
++		printk(KERN_WARNING DRIVER_NAME
++			": query control failed with %d\n", retval);
+ 
+-	return -EINVAL;
++	return retval;
+ }
+ 
+ 
+@@ -1110,21 +1179,29 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv,
+ 		struct v4l2_control *ctrl)
+ {
+ 	struct si470x_device *radio = video_get_drvdata(video_devdata(file));
++	int retval;
+ 
+ 	switch (ctrl->id) {
+ 	case V4L2_CID_AUDIO_VOLUME:
+ 		radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME;
+ 		radio->registers[SYSCONFIG2] |= ctrl->value;
+-		return si470x_set_register(radio, SYSCONFIG2);
++		retval = si470x_set_register(radio, SYSCONFIG2);
++		break;
+ 	case V4L2_CID_AUDIO_MUTE:
+ 		if (ctrl->value == 1)
+ 			radio->registers[POWERCFG] &= ~POWERCFG_DMUTE;
+ 		else
+ 			radio->registers[POWERCFG] |= POWERCFG_DMUTE;
+-		return si470x_set_register(radio, POWERCFG);
++		retval = si470x_set_register(radio, POWERCFG);
++		break;
++	default:
++		retval = -EINVAL;
+ 	}
++	if (retval < 0)
++		printk(KERN_WARNING DRIVER_NAME
++			": set control failed with %d\n", retval);
+ 
+-	return -EINVAL;
++	return retval;
+ }
+ 
+ 
+@@ -1163,8 +1240,8 @@ static int si470x_vidioc_s_audio(struct file *file, void *priv,
+ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
+ 		struct v4l2_tuner *tuner)
+ {
+-	int retval;
+ 	struct si470x_device *radio = video_get_drvdata(video_devdata(file));
++	int retval;
+ 
+ 	if (tuner->index > 0)
+ 		return -EINVAL;
+@@ -1220,6 +1297,7 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
+ 		struct v4l2_tuner *tuner)
+ {
+ 	struct si470x_device *radio = video_get_drvdata(video_devdata(file));
++	int retval;
+ 
+ 	if (tuner->index > 0)
+ 		return -EINVAL;
+@@ -1229,7 +1307,12 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
+ 	else
+ 		radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */
+ 
+-	return si470x_set_register(radio, POWERCFG);
++	retval = si470x_set_register(radio, POWERCFG);
++	if (retval < 0)
++		printk(KERN_WARNING DRIVER_NAME
++			": set tuner failed with %d\n", retval);
++
++	return retval;
+ }
+ 
+ 
+@@ -1255,11 +1338,17 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv,
+ 		struct v4l2_frequency *freq)
+ {
+ 	struct si470x_device *radio = video_get_drvdata(video_devdata(file));
++	int retval;
+ 
+ 	if (freq->type != V4L2_TUNER_RADIO)
+ 		return -EINVAL;
+ 
+-	return si470x_set_freq(radio, freq->frequency);
++	retval = si470x_set_freq(radio, freq->frequency);
++	if (retval < 0)
++		printk(KERN_WARNING DRIVER_NAME
++			": set frequency failed with %d\n", retval);
++
++	return 0;
+ }
+ 
+ 
+@@ -1299,71 +1388,116 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
+ 		const struct usb_device_id *id)
+ {
+ 	struct si470x_device *radio;
++	int retval = -ENOMEM;
+ 
+-	/* memory and interface allocations */
+-	radio = kmalloc(sizeof(struct si470x_device), GFP_KERNEL);
++	/* private data allocation */
++	radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL);
+ 	if (!radio)
+-		return -ENOMEM;
++		goto err_initial;
++
++	/* video device allocation */
+ 	radio->videodev = video_device_alloc();
+-	if (!radio->videodev) {
+-		kfree(radio);
+-		return -ENOMEM;
+-	}
++	if (!radio->videodev)
++		goto err_radio;
++
++	/* initial configuration */
+ 	memcpy(radio->videodev, &si470x_viddev_template,
+ 			sizeof(si470x_viddev_template));
+ 	radio->users = 0;
+ 	radio->usbdev = interface_to_usbdev(intf);
++	radio->intf = intf;
++	mutex_init(&radio->lock);
+ 	video_set_drvdata(radio->videodev, radio);
+-	if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
+-		printk(KERN_WARNING DRIVER_NAME
+-				": Could not register video device\n");
+-		video_device_release(radio->videodev);
+-		kfree(radio);
+-		return -EIO;
+-	}
+-	usb_set_intfdata(intf, radio);
+ 
+ 	/* show some infos about the specific device */
+-	if (si470x_get_all_registers(radio) < 0) {
+-		video_device_release(radio->videodev);
+-		kfree(radio);
+-		return -EIO;
+-	}
+-	printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4x ChipID=0x%4.4x\n",
++	retval = -EIO;
++	if (si470x_get_all_registers(radio) < 0)
++		goto err_all;
++	printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
+ 			radio->registers[DEVICEID], radio->registers[CHIPID]);
+ 
+ 	/* check if firmware is current */
+ 	if ((radio->registers[CHIPID] & CHIPID_FIRMWARE)
+-			< RADIO_SW_VERSION_CURRENT)
++			< RADIO_SW_VERSION_CURRENT) {
++		printk(KERN_WARNING DRIVER_NAME
++			": This driver is known to work with "
++			"firmware version %hu,\n", RADIO_SW_VERSION_CURRENT);
++		printk(KERN_WARNING DRIVER_NAME
++			": but the device has firmware version %hu.\n",
++			radio->registers[CHIPID] & CHIPID_FIRMWARE);
++		printk(KERN_WARNING DRIVER_NAME
++			": If you have some trouble using this driver,\n");
+ 		printk(KERN_WARNING DRIVER_NAME
+-			": This driver is known to work with chip version %d, "
+-			"but the device has firmware %d.\n"
+-			DRIVER_NAME
+-			"If you have some trouble using this driver, please "
+-			"report to V4L ML at video4linux-list at redhat.com\n",
+-			radio->registers[CHIPID] & CHIPID_FIRMWARE,
+-			RADIO_SW_VERSION_CURRENT);
++			": please report to V4L ML at "
++			"video4linux-list at redhat.com\n");
++	}
+ 
+ 	/* set initial frequency */
+ 	si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
+ 
+-	/* rds initialization */
++	/* rds buffer allocation */
+ 	radio->buf_size = rds_buf * 3;
+ 	radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
+-	if (!radio->buffer) {
+-		video_device_release(radio->videodev);
+-		kfree(radio);
+-		return -ENOMEM;
+-	}
++	if (!radio->buffer)
++		goto err_all;
++
++	/* rds buffer configuration */
+ 	radio->wr_index = 0;
+ 	radio->rd_index = 0;
+ 	init_waitqueue_head(&radio->read_queue);
+ 
+-	/* prepare polling via eventd */
+-	INIT_WORK(&radio->work, si470x_work);
+-	init_timer(&radio->timer);
+-	radio->timer.function = si470x_timer;
+-	radio->timer.data = (unsigned long) radio;
++	/* prepare rds work function */
++	INIT_DELAYED_WORK(&radio->work, si470x_work);
++
++	/* register video device */
++	if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
++		printk(KERN_WARNING DRIVER_NAME
++				": Could not register video device\n");
++		goto err_all;
++	}
++	usb_set_intfdata(intf, radio);
++
++	return 0;
++err_all:
++	video_device_release(radio->videodev);
++	kfree(radio->buffer);
++err_radio:
++	kfree(radio);
++err_initial:
++	return retval;
++}
++
++
++/*
++ * si470x_usb_driver_suspend - suspend the device
++ */
++static int si470x_usb_driver_suspend(struct usb_interface *intf,
++		pm_message_t message)
++{
++	struct si470x_device *radio = usb_get_intfdata(intf);
++
++	printk(KERN_INFO DRIVER_NAME ": suspending now...\n");
++
++	cancel_delayed_work_sync(&radio->work);
++
++	return 0;
++}
++
++
++/*
++ * si470x_usb_driver_resume - resume the device
++ */
++static int si470x_usb_driver_resume(struct usb_interface *intf)
++{
++	struct si470x_device *radio = usb_get_intfdata(intf);
++
++	printk(KERN_INFO DRIVER_NAME ": resuming now...\n");
++
++	mutex_lock(&radio->lock);
++	if (radio->users && radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS)
++		schedule_delayed_work(&radio->work,
++			msecs_to_jiffies(rds_poll_time));
++	mutex_unlock(&radio->lock);
+ 
+ 	return 0;
+ }
+@@ -1376,15 +1510,11 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf)
+ {
+ 	struct si470x_device *radio = usb_get_intfdata(intf);
+ 
+-	del_timer_sync(&radio->timer);
+-	flush_scheduled_work();
+-
++	cancel_delayed_work_sync(&radio->work);
+ 	usb_set_intfdata(intf, NULL);
+-	if (radio) {
+-		video_unregister_device(radio->videodev);
+-		kfree(radio->buffer);
+-		kfree(radio);
+-	}
++	video_unregister_device(radio->videodev);
++	kfree(radio->buffer);
++	kfree(radio);
+ }
+ 
+ 
+@@ -1392,10 +1522,13 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf)
+  * si470x_usb_driver - usb driver interface
+  */
+ static struct usb_driver si470x_usb_driver = {
+-	.name		= DRIVER_NAME,
+-	.probe		= si470x_usb_driver_probe,
+-	.disconnect	= si470x_usb_driver_disconnect,
+-	.id_table	= si470x_usb_driver_id_table,
++	.name			= DRIVER_NAME,
++	.probe			= si470x_usb_driver_probe,
++	.disconnect		= si470x_usb_driver_disconnect,
++	.suspend		= si470x_usb_driver_suspend,
++	.resume			= si470x_usb_driver_resume,
++	.id_table		= si470x_usb_driver_id_table,
++	.supports_autosuspend	= 1,
+ };
+ 
+ 
+@@ -1409,7 +1542,7 @@ static struct usb_driver si470x_usb_driver = {
+  */
+ static int __init si470x_module_init(void)
+ {
+-	printk(KERN_INFO DRIVER_DESC "\n");
++	printk(KERN_INFO DRIVER_DESC ", Version " DRIVER_VERSION "\n");
+ 	return usb_register(&si470x_usb_driver);
+ }
+ 
+@@ -1429,4 +1562,4 @@ module_exit(si470x_module_exit);
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR(DRIVER_AUTHOR);
+ MODULE_DESCRIPTION(DRIVER_DESC);
+-MODULE_VERSION("1.0.4");
++MODULE_VERSION(DRIVER_VERSION);
+diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
+index a2e8987..37072a2 100644
+--- a/drivers/media/video/Kconfig
++++ b/drivers/media/video/Kconfig
+@@ -4,14 +4,14 @@
+ 
+ menuconfig VIDEO_CAPTURE_DRIVERS
+ 	bool "Video capture adapters"
+-	depends on VIDEO_DEV
++	depends on VIDEO_V4L2
+ 	default y
+ 	---help---
+ 	  Say Y here to enable selecting the video adapters for
+ 	  webcams, analog TV, and hybrid analog/digital TV.
+ 	  Some of those devices also supports FM radio.
+ 
+-if VIDEO_CAPTURE_DRIVERS && VIDEO_DEV
++if VIDEO_CAPTURE_DRIVERS && VIDEO_V4L2
+ 
+ config VIDEO_ADV_DEBUG
+ 	bool "Enable advanced debug functionality"
+diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
+index 850b8c6..3f209b3 100644
+--- a/drivers/media/video/Makefile
++++ b/drivers/media/video/Makefile
+@@ -10,8 +10,9 @@ msp3400-objs	:=	msp3400-driver.o msp3400-kthreads.o
+ 
+ stkwebcam-objs	:=	stk-webcam.o stk-sensor.o
+ 
+-obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o compat_ioctl32.o \
+-			   v4l2-int-device.o
++obj-$(CONFIG_VIDEO_DEV) += videodev.o compat_ioctl32.o v4l2-int-device.o
++
++obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o
+ 
+ ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y)
+   obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o
+diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
+index 907dc62..5404fcc 100644
+--- a/drivers/media/video/bt8xx/bttv-driver.c
++++ b/drivers/media/video/bt8xx/bttv-driver.c
+@@ -2354,8 +2354,8 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv,
+ 		BUG();
+ 	}
+ 
+-	mutex_lock(&fh->cap.lock);
+-		kfree(fh->ov.clips);
++	mutex_lock(&fh->cap.vb_lock);
++	kfree(fh->ov.clips);
+ 	fh->ov.clips    = clips;
+ 	fh->ov.nclips   = n;
+ 
+@@ -2376,7 +2376,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv,
+ 		bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
+ 		retval = bttv_switch_overlay(btv,fh,new);
+ 	}
+-	mutex_unlock(&fh->cap.lock);
++	mutex_unlock(&fh->cap.vb_lock);
+ 	return retval;
+ }
+ 
+@@ -2576,7 +2576,7 @@ static int bttv_s_fmt_cap(struct file *file, void *priv,
+ 	fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+ 
+ 	/* update our state informations */
+-	mutex_lock(&fh->cap.lock);
++	mutex_lock(&fh->cap.vb_lock);
+ 	fh->fmt              = fmt;
+ 	fh->cap.field        = f->fmt.pix.field;
+ 	fh->cap.last         = V4L2_FIELD_NONE;
+@@ -2585,7 +2585,7 @@ static int bttv_s_fmt_cap(struct file *file, void *priv,
+ 	btv->init.fmt        = fmt;
+ 	btv->init.width      = f->fmt.pix.width;
+ 	btv->init.height     = f->fmt.pix.height;
+-	mutex_unlock(&fh->cap.lock);
++	mutex_unlock(&fh->cap.vb_lock);
+ 
+ 	return 0;
+ }
+@@ -2611,11 +2611,11 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
+ 	unsigned int i;
+ 	struct bttv_fh *fh = priv;
+ 
+-	mutex_lock(&fh->cap.lock);
++	mutex_lock(&fh->cap.vb_lock);
+ 	retval = videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize,
+ 				     V4L2_MEMORY_MMAP);
+ 	if (retval < 0) {
+-		mutex_unlock(&fh->cap.lock);
++		mutex_unlock(&fh->cap.vb_lock);
+ 		return retval;
+ 	}
+ 
+@@ -2627,7 +2627,7 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
+ 	for (i = 0; i < gbuffers; i++)
+ 		mbuf->offsets[i] = i * gbufsize;
+ 
+-	mutex_unlock(&fh->cap.lock);
++	mutex_unlock(&fh->cap.vb_lock);
+ 	return 0;
+ }
+ #endif
+@@ -2756,10 +2756,11 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on)
+ 	if (!check_alloc_btres(btv, fh, RESOURCE_OVERLAY))
+ 		return -EBUSY;
+ 
+-	mutex_lock(&fh->cap.lock);
++	mutex_lock(&fh->cap.vb_lock);
+ 	if (on) {
+ 		fh->ov.tvnorm = btv->tvnorm;
+ 		new = videobuf_pci_alloc(sizeof(*new));
++		new->crop = btv->crop[!!fh->do_crop].rect;
+ 		bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
+ 	} else {
+ 		new = NULL;
+@@ -2767,7 +2768,7 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on)
+ 
+ 	/* switch over */
+ 	retval = bttv_switch_overlay(btv, fh, new);
+-	mutex_unlock(&fh->cap.lock);
++	mutex_unlock(&fh->cap.vb_lock);
+ 	return retval;
+ }
+ 
+@@ -2806,7 +2807,7 @@ static int bttv_s_fbuf(struct file *file, void *f,
+ 	}
+ 
+ 	/* ok, accept it */
+-	mutex_lock(&fh->cap.lock);
++	mutex_lock(&fh->cap.vb_lock);
+ 	btv->fbuf.base       = fb->base;
+ 	btv->fbuf.fmt.width  = fb->fmt.width;
+ 	btv->fbuf.fmt.height = fb->fmt.height;
+@@ -2838,7 +2839,7 @@ static int bttv_s_fbuf(struct file *file, void *f,
+ 			retval = bttv_switch_overlay(btv, fh, new);
+ 		}
+ 	}
+-	mutex_unlock(&fh->cap.lock);
++	mutex_unlock(&fh->cap.vb_lock);
+ 	return retval;
+ }
+ 
+@@ -3090,7 +3091,7 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
+ 
+ 	fh->do_crop = 1;
+ 
+-	mutex_lock(&fh->cap.lock);
++	mutex_lock(&fh->cap.vb_lock);
+ 
+ 	if (fh->width < c.min_scaled_width) {
+ 		fh->width = c.min_scaled_width;
+@@ -3108,7 +3109,7 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
+ 		btv->init.height = c.max_scaled_height;
+ 	}
+ 
+-	mutex_unlock(&fh->cap.lock);
++	mutex_unlock(&fh->cap.vb_lock);
+ 
+ 	return 0;
+ }
+@@ -3177,30 +3178,25 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
+ 		buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream);
+ 	} else {
+ 		/* read() capture */
+-		mutex_lock(&fh->cap.lock);
++		mutex_lock(&fh->cap.vb_lock);
+ 		if (NULL == fh->cap.read_buf) {
+ 			/* need to capture a new frame */
+-			if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM)) {
+-				mutex_unlock(&fh->cap.lock);
+-				return POLLERR;
+-			}
++			if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM))
++				goto err;
+ 			fh->cap.read_buf = videobuf_pci_alloc(fh->cap.msize);
+-			if (NULL == fh->cap.read_buf) {
+-				mutex_unlock(&fh->cap.lock);
+-				return POLLERR;
+-			}
++			if (NULL == fh->cap.read_buf)
++				goto err;
+ 			fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR;
+ 			field = videobuf_next_field(&fh->cap);
+ 			if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) {
+ 				kfree (fh->cap.read_buf);
+ 				fh->cap.read_buf = NULL;
+-				mutex_unlock(&fh->cap.lock);
+-				return POLLERR;
++				goto err;
+ 			}
+ 			fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
+ 			fh->cap.read_off = 0;
+ 		}
+-		mutex_unlock(&fh->cap.lock);
++		mutex_unlock(&fh->cap.vb_lock);
+ 		buf = (struct bttv_buffer*)fh->cap.read_buf;
+ 	}
+ 
+@@ -3209,6 +3205,9 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
+ 	    buf->vb.state == VIDEOBUF_ERROR)
+ 		return POLLIN|POLLRDNORM;
+ 	return 0;
++err:
++	mutex_unlock(&fh->cap.vb_lock);
++	return POLLERR;
+ }
+ 
+ static int bttv_open(struct inode *inode, struct file *file)
+diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c
+index 1f0cc79..75fa82c 100644
+--- a/drivers/media/video/bt8xx/bttv-vbi.c
++++ b/drivers/media/video/bt8xx/bttv-vbi.c
+@@ -352,13 +352,13 @@ int bttv_s_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt)
+ 	   because vbi_fmt.end counts field lines times two. */
+ 	end = max(frt->fmt.vbi.start[0], start1) * 2 + 2;
+ 
+-	mutex_lock(&fh->vbi.lock);
++	mutex_lock(&fh->vbi.vb_lock);
+ 
+ 	fh->vbi_fmt.fmt    = frt->fmt.vbi;
+ 	fh->vbi_fmt.tvnorm = tvnorm;
+ 	fh->vbi_fmt.end    = end;
+ 
+-	mutex_unlock(&fh->vbi.lock);
++	mutex_unlock(&fh->vbi.vb_lock);
+ 
+ 	rc = 0;
+ 
+diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
+index 0aedbea..e357f41 100644
+--- a/drivers/media/video/cx88/cx88-mpeg.c
++++ b/drivers/media/video/cx88/cx88-mpeg.c
+@@ -609,13 +609,19 @@ static int cx8802_request_acquire(struct cx8802_driver *drv)
+ 	struct cx88_core *core = drv->core;
+ 
+ 	/* Fail a request for hardware if the device is busy. */
+-	if (core->active_type_id != CX88_BOARD_NONE)
++	if (core->active_type_id != CX88_BOARD_NONE &&
++	    core->active_type_id != drv->type_id)
+ 		return -EBUSY;
+ 
+ 	if (drv->advise_acquire)
+ 	{
+-		core->active_type_id = drv->type_id;
+-		drv->advise_acquire(drv);
++		mutex_lock(&drv->core->lock);
++		core->active_ref++;
++		if (core->active_type_id == CX88_BOARD_NONE) {
++			core->active_type_id = drv->type_id;
++			drv->advise_acquire(drv);
++		}
++		mutex_unlock(&drv->core->lock);
+ 
+ 		mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO));
+ 	}
+@@ -628,12 +634,14 @@ static int cx8802_request_release(struct cx8802_driver *drv)
+ {
+ 	struct cx88_core *core = drv->core;
+ 
+-	if (drv->advise_release)
++	mutex_lock(&drv->core->lock);
++	if (drv->advise_release && --core->active_ref == 0)
+ 	{
+ 		drv->advise_release(drv);
+ 		core->active_type_id = CX88_BOARD_NONE;
+ 		mpeg_dbg(1,"%s() Post release GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO));
+ 	}
++	mutex_unlock(&drv->core->lock);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
+index 4e823f2..37e6d2e 100644
+--- a/drivers/media/video/cx88/cx88.h
++++ b/drivers/media/video/cx88/cx88.h
+@@ -336,6 +336,7 @@ struct cx88_core {
+ 	/* cx88-video needs to access cx8802 for hybrid tuner pll access. */
+ 	struct cx8802_dev          *dvbdev;
+ 	enum cx88_board_type       active_type_id;
++	int			   active_ref;
+ };
+ 
+ struct cx8800_dev;
+diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
+index 941357c..8c67f67 100644
+--- a/drivers/media/video/em28xx/em28xx-audio.c
++++ b/drivers/media/video/em28xx/em28xx-audio.c
+@@ -35,7 +35,6 @@
+ #include <linux/vmalloc.h>
+ #include <linux/proc_fs.h>
+ #include <linux/module.h>
+-#include <sound/driver.h>
+ #include <sound/core.h>
+ #include <sound/pcm.h>
+ #include <sound/pcm_params.h>
+@@ -270,8 +269,11 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
+ 	dprintk("opening device and trying to acquire exclusive lock\n");
+ 
+ 	/* Sets volume, mute, etc */
++
+ 	dev->mute = 0;
++	mutex_lock(&dev->lock);
+ 	ret = em28xx_audio_analog_set(dev);
++	mutex_unlock(&dev->lock);
+ 	if (ret < 0)
+ 		goto err;
+ 
+@@ -303,7 +305,9 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
+ 	dprintk("closing device\n");
+ 
+ 	dev->mute = 1;
++	mutex_lock(&dev->lock);
+ 	em28xx_audio_analog_set(dev);
++	mutex_unlock(&dev->lock);
+ 
+ 	if (dev->adev->users == 0 && dev->adev->shutdown == 1) {
+ 		dprintk("audio users: %d\n", dev->adev->users);
+diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
+index 2159d01..aae7753 100644
+--- a/drivers/media/video/em28xx/em28xx-cards.c
++++ b/drivers/media/video/em28xx/em28xx-cards.c
+@@ -393,15 +393,15 @@ struct em28xx_board em28xx_boards[] = {
+ 		.input          = { {
+ 			.type     = EM28XX_VMUX_TELEVISION,
+ 			.vmux     = SAA7115_COMPOSITE2,
+-			.amux     = 1,
++			.amux     = EM28XX_AMUX_LINE_IN,
+ 		}, {
+ 			.type     = EM28XX_VMUX_COMPOSITE1,
+ 			.vmux     = SAA7115_COMPOSITE0,
+-			.amux     = 1,
++			.amux     = EM28XX_AMUX_LINE_IN,
+ 		}, {
+ 			.type     = EM28XX_VMUX_SVIDEO,
+ 			.vmux     = SAA7115_SVIDEO3,
+-			.amux     = 1,
++			.amux     = EM28XX_AMUX_LINE_IN,
+ 		} },
+ 	},
+ };
+@@ -441,6 +441,8 @@ struct usb_device_id em28xx_id_table [] = {
+ 			.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
+ 	{ USB_DEVICE(0x2040, 0x6500),
+ 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
++	{ USB_DEVICE(0x2040, 0x6502),
++			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
+ 	{ USB_DEVICE(0x2040, 0x6513),
+ 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+ 	{ USB_DEVICE(0x0ccd, 0x0042),
+diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
+index f6b7835..7d1537c 100644
+--- a/drivers/media/video/em28xx/em28xx-core.c
++++ b/drivers/media/video/em28xx/em28xx-core.c
+@@ -72,7 +72,8 @@ u32 em28xx_request_buffers(struct em28xx *dev, u32 count)
+ 	const size_t imagesize = PAGE_ALIGN(dev->frame_size);	/*needs to be page aligned cause the buffers can be mapped individually! */
+ 	void *buff = NULL;
+ 	u32 i;
+-	em28xx_coredbg("requested %i buffers with size %zi", count, imagesize);
++	em28xx_coredbg("requested %i buffers with size %zi\n",
++			count, imagesize);
+ 	if (count > EM28XX_NUM_FRAMES)
+ 		count = EM28XX_NUM_FRAMES;
+ 
+@@ -150,7 +151,7 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
+ 	if (reg_debug){
+ 		printk(ret < 0 ? " failed!\n" : "%02x values: ", ret);
+ 		for (byte = 0; byte < len; byte++) {
+-			printk(" %02x", buf[byte]);
++			printk(" %02x", (unsigned char)buf[byte]);
+ 		}
+ 		printk("\n");
+ 	}
+@@ -177,7 +178,8 @@ int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg)
+ 			      0x0000, reg, &val, 1, HZ);
+ 
+ 	if (reg_debug)
+-		printk(ret < 0 ? " failed!\n" : "%02x\n", val);
++		printk(ret < 0 ? " failed!\n" :
++				 "%02x\n", (unsigned char) val);
+ 
+ 	if (ret < 0)
+ 		return ret;
+@@ -237,7 +239,7 @@ int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len)
+  * sets only some bits (specified by bitmask) of a register, by first reading
+  * the actual value
+  */
+-int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
++static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
+ 				 u8 bitmask)
+ {
+ 	int oldval;
+@@ -254,26 +256,31 @@ int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
+  */
+ static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val)
+ {
+-	int ret;
++	int ret, i;
+ 	u8 addr = reg & 0x7f;
+ 	if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0)
+ 		return ret;
+ 	if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0)
+ 		return ret;
+-	if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
+-		return ret;
+-	else if (((u8) ret) & 0x01) {
+-		em28xx_warn ("AC97 command still being executed: not handled properly!\n");
++
++	/* Wait up to 50 ms for AC97 command to complete */
++	for (i = 0; i < 10; i++) {
++		if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
++			return ret;
++		if (!((u8) ret) & 0x01)
++			return 0;
++		msleep(5);
+ 	}
++	em28xx_warn ("AC97 command still being executed: not handled properly!\n");
+ 	return 0;
+ }
+ 
+-int em28xx_set_audio_source(struct em28xx *dev)
++static int em28xx_set_audio_source(struct em28xx *dev)
+ {
+ 	static char *enable  = "\x08\x08";
+ 	static char *disable = "\x08\x88";
+ 	char *video = enable, *line = disable;
+-	int ret, no_ac97;
++	int ret;
+ 	u8 input;
+ 
+ 	if (dev->is_em2800) {
+@@ -293,11 +300,9 @@ int em28xx_set_audio_source(struct em28xx *dev)
+ 		switch (dev->ctl_ainput) {
+ 		case EM28XX_AMUX_VIDEO:
+ 			input = EM28XX_AUDIO_SRC_TUNER;
+-			no_ac97 = 1;
+ 			break;
+ 		case EM28XX_AMUX_LINE_IN:
+ 			input = EM28XX_AUDIO_SRC_LINE;
+-			no_ac97 = 1;
+ 			break;
+ 		case EM28XX_AMUX_AC97_VIDEO:
+ 			input = EM28XX_AUDIO_SRC_LINE;
+@@ -313,12 +318,11 @@ int em28xx_set_audio_source(struct em28xx *dev)
+ 	ret = em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0);
+ 	if (ret < 0)
+ 		return ret;
++	msleep(5);
+ 
+-	if (no_ac97)
+-		return 0;
+-
+-	/* Sets AC97 mixer registers */
+-
++	/* Sets AC97 mixer registers
++	   This is seems to be needed, even for non-ac97 configs
++	 */
+ 	ret = em28xx_write_ac97(dev, VIDEO_AC97, video);
+ 	if (ret < 0)
+ 		return ret;
+@@ -337,9 +341,10 @@ int em28xx_audio_analog_set(struct em28xx *dev)
+ 	s[0] |= 0x1f - dev->volume;
+ 	s[1] |= 0x1f - dev->volume;
+ 
+-	if (dev->mute)
+-		s[1] |= 0x80;
++	/* Mute */
++	s[1] |= 0x80;
+ 	ret = em28xx_write_ac97(dev, MASTER_AC97, s);
++
+ 	if (ret < 0)
+ 		return ret;
+ 
+@@ -357,6 +362,11 @@ int em28xx_audio_analog_set(struct em28xx *dev)
+ 	/* Selects the proper audio input */
+ 	ret = em28xx_set_audio_source(dev);
+ 
++	/* Unmute device */
++	if (!dev->mute)
++		s[1] &= ~0x80;
++	ret = em28xx_write_ac97(dev, MASTER_AC97, s);
++
+ 	return ret;
+ }
+ EXPORT_SYMBOL_GPL(em28xx_audio_analog_set);
+@@ -667,7 +677,7 @@ static void em28xx_isocIrq(struct urb *urb)
+ 				continue;
+ 			}
+ 			if (urb->iso_frame_desc[i].actual_length >
+-						 dev->max_pkt_size) {
++			    urb->iso_frame_desc[i].length) {
+ 				em28xx_isocdbg("packet bigger than packet size");
+ 				continue;
+ 			}
+@@ -713,8 +723,11 @@ void em28xx_uninit_isoc(struct em28xx *dev)
+ 	for (i = 0; i < EM28XX_NUM_BUFS; i++) {
+ 		if (dev->urb[i]) {
+ 			usb_kill_urb(dev->urb[i]);
+-			if (dev->transfer_buffer[i]){
+-				usb_buffer_free(dev->udev,(EM28XX_NUM_PACKETS*dev->max_pkt_size),dev->transfer_buffer[i],dev->urb[i]->transfer_dma);
++			if (dev->transfer_buffer[i]) {
++				usb_buffer_free(dev->udev,
++						dev->urb[i]->transfer_buffer_length,
++						dev->transfer_buffer[i],
++						dev->urb[i]->transfer_dma);
+ 			}
+ 			usb_free_urb(dev->urb[i]);
+ 		}
+@@ -732,7 +745,10 @@ int em28xx_init_isoc(struct em28xx *dev)
+ {
+ 	/* change interface to 3 which allows the biggest packet sizes */
+ 	int i, errCode;
+-	const int sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size;
++	int sb_size;
++
++	em28xx_set_alternate(dev);
++	sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size;
+ 
+ 	/* reset streaming vars */
+ 	dev->frame_current = NULL;
+@@ -741,7 +757,7 @@ int em28xx_init_isoc(struct em28xx *dev)
+ 	/* allocate urbs */
+ 	for (i = 0; i < EM28XX_NUM_BUFS; i++) {
+ 		struct urb *urb;
+-		int j, k;
++		int j;
+ 		/* allocate transfer buffer */
+ 		urb = usb_alloc_urb(EM28XX_NUM_PACKETS, GFP_KERNEL);
+ 		if (!urb){
+@@ -749,7 +765,9 @@ int em28xx_init_isoc(struct em28xx *dev)
+ 			em28xx_uninit_isoc(dev);
+ 			return -ENOMEM;
+ 		}
+-		dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,&urb->transfer_dma);
++		dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size,
++							   GFP_KERNEL,
++							   &urb->transfer_dma);
+ 		if (!dev->transfer_buffer[i]) {
+ 			em28xx_errdev
+ 					("unable to allocate %i bytes for transfer buffer %i\n",
+@@ -762,22 +780,22 @@ int em28xx_init_isoc(struct em28xx *dev)
+ 		urb->dev = dev->udev;
+ 		urb->context = dev;
+ 		urb->pipe = usb_rcvisocpipe(dev->udev, 0x82);
+-		urb->transfer_flags = URB_ISO_ASAP;
++		urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
+ 		urb->interval = 1;
+ 		urb->transfer_buffer = dev->transfer_buffer[i];
+ 		urb->complete = em28xx_isocIrq;
+ 		urb->number_of_packets = EM28XX_NUM_PACKETS;
+ 		urb->transfer_buffer_length = sb_size;
+-		for (j = k = 0; j < EM28XX_NUM_PACKETS;
+-				j++, k += dev->max_pkt_size) {
+-			urb->iso_frame_desc[j].offset = k;
+-			urb->iso_frame_desc[j].length =
+-				dev->max_pkt_size;
++		for (j = 0; j < EM28XX_NUM_PACKETS; j++) {
++			urb->iso_frame_desc[j].offset = j * dev->max_pkt_size;
++			urb->iso_frame_desc[j].length = dev->max_pkt_size;
+ 		}
+ 		dev->urb[i] = urb;
+ 	}
+ 
+ 	/* submit urbs */
++	em28xx_coredbg("Submitting %d urbs of %d packets (%d each)\n",
++		       EM28XX_NUM_BUFS, EM28XX_NUM_PACKETS, dev->max_pkt_size);
+ 	for (i = 0; i < EM28XX_NUM_BUFS; i++) {
+ 		errCode = usb_submit_urb(dev->urb[i], GFP_KERNEL);
+ 		if (errCode) {
+@@ -794,22 +812,31 @@ int em28xx_init_isoc(struct em28xx *dev)
+ int em28xx_set_alternate(struct em28xx *dev)
+ {
+ 	int errCode, prev_alt = dev->alt;
+-	dev->alt = alt;
+-	if (dev->alt == 0) {
+-		int i;
+-		for(i=0;i< dev->num_alt; i++)
+-			if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt])
+-				dev->alt=i;
+-	}
++	int i;
++	unsigned int min_pkt_size = dev->bytesperline+4;
++
++	/* When image size is bigger than a ceirtain value,
++	   the frame size should be increased, otherwise, only
++	   green screen will be received.
++	 */
++	if (dev->frame_size > 720*240*2)
++		min_pkt_size *= 2;
++
++	for (i = 0; i < dev->num_alt; i++)
++		if (dev->alt_max_pkt_size[i] >= min_pkt_size)
++			break;
++	dev->alt = i;
+ 
+ 	if (dev->alt != prev_alt) {
++		em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n",
++				min_pkt_size, dev->alt);
+ 		dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt];
+-		em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", dev->alt,
+-		       dev->max_pkt_size);
++		em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n",
++			       dev->alt, dev->max_pkt_size);
+ 		errCode = usb_set_interface(dev->udev, 0, dev->alt);
+ 		if (errCode < 0) {
+ 			em28xx_errdev ("cannot change alternate number to %d (error=%i)\n",
+-							dev->alt, errCode);
++					dev->alt, errCode);
+ 			return errCode;
+ 		}
+ 	}
+diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
+index a0c3346..4abe670 100644
+--- a/drivers/media/video/em28xx/em28xx-video.c
++++ b/drivers/media/video/em28xx/em28xx-video.c
+@@ -189,7 +189,7 @@ static void video_mux(struct em28xx *dev, int index)
+ 		em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ 	}
+ 
+-	em28xx_set_audio_source(dev);
++	em28xx_audio_analog_set(dev);
+ }
+ 
+ /* Usage lock check functions */
+@@ -830,6 +830,63 @@ static int vidioc_s_frequency(struct file *file, void *priv,
+ 	return 0;
+ }
+ 
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int em28xx_reg_len(int reg)
++{
++	switch (reg) {
++	case AC97LSB_REG:
++	case HSCALELOW_REG:
++	case VSCALELOW_REG:
++		return 2;
++	default:
++		return 1;
++	}
++}
++
++static int vidioc_g_register(struct file *file, void *priv,
++			     struct v4l2_register *reg)
++{
++	struct em28xx_fh      *fh  = priv;
++	struct em28xx         *dev = fh->dev;
++	int ret;
++
++	if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
++		return -EINVAL;
++
++	if (em28xx_reg_len(reg->reg) == 1) {
++		ret = em28xx_read_reg(dev, reg->reg);
++		if (ret < 0)
++			return ret;
++
++		reg->val = ret;
++	} else {
++		u64 val = 0;
++		ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS,
++						   reg->reg, (char *)&val, 2);
++		if (ret < 0)
++			return ret;
++
++		reg->val = cpu_to_le64((__u64)val);
++	}
++
++	return 0;
++}
++
++static int vidioc_s_register(struct file *file, void *priv,
++			     struct v4l2_register *reg)
++{
++	struct em28xx_fh      *fh  = priv;
++	struct em28xx         *dev = fh->dev;
++	u64 buf;
++
++	buf = le64_to_cpu((__u64)reg->val);
++
++	return em28xx_write_regs(dev, reg->reg, (char *)&buf,
++				 em28xx_reg_len(reg->reg));
++}
++#endif
++
++
+ static int vidioc_cropcap(struct file *file, void *priv,
+ 					struct v4l2_cropcap *cc)
+ {
+@@ -1295,8 +1352,6 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
+ 	filp->private_data = fh;
+ 
+ 	if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
+-		em28xx_set_alternate(dev);
+-
+ 		dev->width = norm_maxw(dev);
+ 		dev->height = norm_maxh(dev);
+ 		dev->frame_size = dev->width * dev->height * 2;
+@@ -1305,6 +1360,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
+ 		dev->hscale = 0;
+ 		dev->vscale = 0;
+ 
++		em28xx_set_alternate(dev);
+ 		em28xx_capture_start(dev, 1);
+ 		em28xx_resolution_set(dev);
+ 
+@@ -1730,6 +1786,10 @@ static const struct video_device em28xx_video_template = {
+ 	.vidioc_s_tuner             = vidioc_s_tuner,
+ 	.vidioc_g_frequency         = vidioc_g_frequency,
+ 	.vidioc_s_frequency         = vidioc_s_frequency,
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++	.vidioc_g_register          = vidioc_g_register,
++	.vidioc_s_register          = vidioc_s_register,
++#endif
+ 
+ 	.tvnorms                    = V4L2_STD_ALL,
+ 	.current_norm               = V4L2_STD_PAL,
+@@ -1752,6 +1812,10 @@ static struct video_device em28xx_radio_template = {
+ 	.vidioc_s_ctrl        = vidioc_s_ctrl,
+ 	.vidioc_g_frequency   = vidioc_g_frequency,
+ 	.vidioc_s_frequency   = vidioc_s_frequency,
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++	.vidioc_g_register    = vidioc_g_register,
++	.vidioc_s_register    = vidioc_s_register,
++#endif
+ };
+ 
+ /******************************** usb interface *****************************************/
+@@ -1796,10 +1860,10 @@ void em28xx_unregister_extension(struct em28xx_ops *ops)
+ }
+ EXPORT_SYMBOL(em28xx_unregister_extension);
+ 
+-struct video_device *em28xx_vdev_init(struct em28xx *dev,
+-				      const struct video_device *template,
+-				      const int type,
+-				      const char *type_name)
++static struct video_device *em28xx_vdev_init(struct em28xx *dev,
++					     const struct video_device *template,
++					     const int type,
++					     const char *type_name)
+ {
+ 	struct video_device *vfd;
+ 
+@@ -2064,6 +2128,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
+ 	snprintf(dev->name, 29, "em28xx #%d", nr);
+ 	dev->devno = nr;
+ 	dev->model = id->driver_info;
++	dev->alt   = -1;
+ 
+ 	/* Checks if audio is provided by some interface */
+ 	for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {
+diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
+index f3bad0c..04e0e48 100644
+--- a/drivers/media/video/em28xx/em28xx.h
++++ b/drivers/media/video/em28xx/em28xx.h
+@@ -33,7 +33,7 @@
+ #define UNSET -1
+ 
+ /* maximum number of em28xx boards */
+-#define EM28XX_MAXBOARDS 1 /*FIXME: should be bigger */
++#define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */
+ 
+ /* maximum number of frames that can be queued */
+ #define EM28XX_NUM_FRAMES 5
+@@ -345,9 +345,6 @@ int em28xx_read_reg(struct em28xx *dev, u16 reg);
+ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
+ 			  int len);
+ int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len);
+-int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
+-			  u8 bitmask);
+-int em28xx_set_audio_source(struct em28xx *dev);
+ int em28xx_audio_analog_set(struct em28xx *dev);
+ 
+ int em28xx_colorlevels_set_default(struct em28xx *dev);
+diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
+index 7d7f383..262830d 100644
+--- a/drivers/media/video/saa7134/saa7134-cards.c
++++ b/drivers/media/video/saa7134/saa7134-cards.c
+@@ -928,27 +928,38 @@ struct saa7134_board saa7134_boards[] = {
+ 		.tuner_addr	= ADDR_UNSET,
+ 		.radio_addr	= ADDR_UNSET,
+ 		.tda9887_conf   = TDA9887_PRESENT,
++		.gpiomask	= 0x03,
+ 		.inputs         = {{
+ 			.name = name_tv,
+ 			.vmux = 1,
+ 			.amux = TV,
+ 			.tv   = 1,
+-		},{
++			.gpio = 0x00,
++		}, {
+ 			.name = name_comp1,
+-			.vmux = 0,
+-			.amux = LINE2,
+-		},{
+-			.name = name_comp2,
+ 			.vmux = 3,
+-			.amux = LINE2,
+-		},{
++			.amux = LINE1,
++			.gpio = 0x02,
++		}, {
++			.name = name_comp2,
++			.vmux = 0,
++			.amux = LINE1,
++			.gpio = 0x02,
++		}, {
+ 			.name = name_svideo,
+ 			.vmux = 8,
+-			.amux = LINE2,
+-		}},
++			.amux = LINE1,
++			.gpio = 0x02,
++		} },
+ 		.radio = {
+ 			.name = name_radio,
+-			.amux = LINE2,
++			.amux = LINE1,
++			.gpio = 0x01,
++		},
++		.mute  = {
++			.name = name_mute,
++			.amux = TV,
++			.gpio = 0x00,
+ 		},
+ 	},
+ 	[SAA7134_BOARD_BMK_MPEX_TUNER] = {
+@@ -3912,6 +3923,74 @@ struct saa7134_board saa7134_boards[] = {
+ 		},
+ 		.mpeg  = SAA7134_MPEG_EMPRESS,
+ 	},
++	[SAA7134_BOARD_TWINHAN_DTV_DVB_3056] = {
++		.name           = "Twinhan Hybrid DTV-DVB 3056 PCI",
++		.audio_clock    = 0x00187de7,
++		.tuner_type     = TUNER_PHILIPS_TDA8290,
++		.radio_type     = UNSET,
++		.tuner_addr	= ADDR_UNSET,
++		.radio_addr	= ADDR_UNSET,
++		.tuner_config   = 2,
++		.mpeg           = SAA7134_MPEG_DVB,
++		.gpiomask       = 0x0200000,
++		.inputs = {{
++			.name   = name_tv,
++			.vmux   = 1,
++			.amux   = TV,
++			.tv     = 1,
++		}, {
++			.name   = name_comp1,
++			.vmux   = 3,
++			.amux   = LINE1,
++		}, {
++			.name   = name_svideo,
++			.vmux   = 8,		/* untested */
++			.amux   = LINE1,
++		} },
++		.radio = {
++			.name   = name_radio,
++			.amux   = TV,
++			.gpio   = 0x0200000,
++		},
++	},
++	[SAA7134_BOARD_GENIUS_TVGO_A11MCE] = {
++		/* Adrian Pardini <pardo.bsso at gmail.com> */
++		.name		= "Genius TVGO AM11MCE",
++		.audio_clock	= 0x00200000,
++		.tuner_type	= TUNER_TNF_5335MF,
++		.radio_type     = UNSET,
++		.tuner_addr	= ADDR_UNSET,
++		.radio_addr	= ADDR_UNSET,
++		.gpiomask       = 0xf000,
++		.inputs         = {{
++			.name = name_tv_mono,
++			.vmux = 1,
++			.amux = LINE2,
++			.gpio = 0x0000,
++			.tv   = 1,
++		}, {
++			.name = name_comp1,
++			.vmux = 3,
++			.amux = LINE1,
++			.gpio = 0x2000,
++			.tv = 1
++		}, {
++			.name = name_svideo,
++			.vmux = 8,
++			.amux = LINE1,
++			.gpio = 0x2000,
++	} },
++		.radio = {
++			.name = name_radio,
++			.amux = LINE2,
++			.gpio = 0x1000,
++		},
++		.mute = {
++			.name = name_mute,
++			.amux = LINE2,
++			.gpio = 0x6000,
++		},
++	},
+ };
+ 
+ const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
+@@ -4511,6 +4590,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
+ 	},{
+ 		.vendor       = PCI_VENDOR_ID_PHILIPS,
+ 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
++		.subvendor    = 0x5168,
++		.subdevice    = 0x3307, /* FlyDVB-T Hybrid Mini PCI */
++		.driver_data  = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
++	}, {
++		.vendor       = PCI_VENDOR_ID_PHILIPS,
++		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ 		.subvendor    = 0x16be,
+ 		.subdevice    = 0x0007,
+ 		.driver_data  = SAA7134_BOARD_MEDION_MD8800_QUADRO,
+@@ -4523,6 +4608,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
+ 	},{
+ 		.vendor       = PCI_VENDOR_ID_PHILIPS,
+ 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
++		.subvendor    = 0x16be,
++		.subdevice    = 0x000d, /* triple CTX948_V1.1.1 */
++		.driver_data  = SAA7134_BOARD_MEDION_MD8800_QUADRO,
++	}, {
++		.vendor       = PCI_VENDOR_ID_PHILIPS,
++		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ 		.subvendor    = 0x1461,
+ 		.subdevice    = 0x2c05,
+ 		.driver_data  = SAA7134_BOARD_AVERMEDIA_777,
+@@ -4843,7 +4934,13 @@ struct pci_device_id saa7134_pci_tbl[] = {
+ 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ 		.subvendor    = 0x4e42,
+ 		.subdevice    = 0x3502,
+-		.driver_data  = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS
++		.driver_data  = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
++	}, {
++		.vendor       = PCI_VENDOR_ID_PHILIPS,
++		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
++		.subvendor    = 0x1822, /*Twinhan Technology Co. Ltd*/
++		.subdevice    = 0x0022,
++		.driver_data  = SAA7134_BOARD_TWINHAN_DTV_DVB_3056,
+ 	},{
+ 		/* --- boards without eeprom + subsystem ID --- */
+ 		.vendor       = PCI_VENDOR_ID_PHILIPS,
+@@ -4995,6 +5092,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
+ 	case SAA7134_BOARD_BEHOLD_409:
+ 	case SAA7134_BOARD_BEHOLD_505FM:
+ 	case SAA7134_BOARD_BEHOLD_507_9FM:
++	case SAA7134_BOARD_GENIUS_TVGO_A11MCE:
+ 		dev->has_remote = SAA7134_REMOTE_GPIO;
+ 		break;
+ 	case SAA7134_BOARD_FLYDVBS_LR300:
+@@ -5232,7 +5330,8 @@ int saa7134_board_init2(struct saa7134_dev *dev)
+ 	case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
+ 	case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
+ 	case SAA7134_BOARD_MEDION_MD8800_QUADRO:
+-       case SAA7134_BOARD_AVERMEDIA_SUPER_007:
++	case SAA7134_BOARD_AVERMEDIA_SUPER_007:
++	case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
+ 		/* this is a hybrid board, initialize to analog mode
+ 		 * and configure firmware eeprom address
+ 		 */
+diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
+index a9ca573..ea2be9e 100644
+--- a/drivers/media/video/saa7134/saa7134-dvb.c
++++ b/drivers/media/video/saa7134/saa7134-dvb.c
+@@ -779,6 +779,21 @@ static struct tda1004x_config avermedia_super_007_config = {
+ 	.request_firmware = philips_tda1004x_request_firmware
+ };
+ 
++static struct tda1004x_config twinhan_dtv_dvb_3056_config = {
++	.demod_address = 0x08,
++	.invert        = 1,
++	.invert_oclk   = 0,
++	.xtal_freq     = TDA10046_XTAL_16M,
++	.agc_config    = TDA10046_AGC_TDA827X,
++	.gpio_config   = TDA10046_GP01_I,
++	.if_freq       = TDA10046_FREQ_045,
++	.i2c_gate      = 0x42,
++	.tuner_address = 0x61,
++	.tuner_config  = 2,
++	.antenna_switch = 1,
++	.request_firmware = philips_tda1004x_request_firmware
++};
++
+ /* ------------------------------------------------------------------
+  * special case: this card uses saa713x GPIO22 for the mode switch
+  */
+@@ -826,6 +841,7 @@ static struct tda1004x_config ads_tech_duo_config = {
+ static struct tda10086_config flydvbs = {
+ 	.demod_address = 0x0e,
+ 	.invert = 0,
++	.diseqc_tone = 0,
+ };
+ 
+ /* ==================================================================
+@@ -940,9 +956,9 @@ static int dvb_init(struct saa7134_dev *dev)
+ 		configure_tda827x_fe(dev, &tda827x_lifeview_config);
+ 		break;
+ 	case SAA7134_BOARD_FLYDVB_TRIO:
+-		if(! use_frontend) {	//terrestrial
++		if(! use_frontend) {	/* terrestrial */
+ 			configure_tda827x_fe(dev, &lifeview_trio_config);
+-		} else {  	      //satellite
++		} else {  	        /* satellite */
+ 			dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
+ 			if (dev->dvb.frontend) {
+ 				if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63,
+@@ -1007,8 +1023,9 @@ static int dvb_init(struct saa7134_dev *dev)
+ 		}
+ 		break;
+ 	case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
+-		dev->dvb.frontend = tda10046_attach(&medion_cardbus,
+-						    &dev->i2c_adap);
++		dev->dvb.frontend = dvb_attach(tda10046_attach,
++					       &medion_cardbus,
++					       &dev->i2c_adap);
+ 		if (dev->dvb.frontend) {
+ 			dev->original_demod_sleep = dev->dvb.frontend->ops.sleep;
+ 			dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
+@@ -1044,6 +1061,9 @@ static int dvb_init(struct saa7134_dev *dev)
+ 	case SAA7134_BOARD_AVERMEDIA_SUPER_007:
+ 		configure_tda827x_fe(dev, &avermedia_super_007_config);
+ 		break;
++	case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
++		configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config);
++		break;
+ 	default:
+ 		wprintk("Huh? unknown DVB card?\n");
+ 		break;
+diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
+index b1b01fa..3d2ec30 100644
+--- a/drivers/media/video/saa7134/saa7134-empress.c
++++ b/drivers/media/video/saa7134/saa7134-empress.c
+@@ -87,7 +87,7 @@ static int ts_open(struct inode *inode, struct file *file)
+ 
+ 	dprintk("open minor=%d\n",minor);
+ 	err = -EBUSY;
+-	if (!mutex_trylock(&dev->empress_tsq.lock))
++	if (!mutex_trylock(&dev->empress_tsq.vb_lock))
+ 		goto done;
+ 	if (dev->empress_users)
+ 		goto done_up;
+@@ -101,7 +101,7 @@ static int ts_open(struct inode *inode, struct file *file)
+ 	err = 0;
+ 
+ done_up:
+-	mutex_unlock(&dev->empress_tsq.lock);
++	mutex_unlock(&dev->empress_tsq.vb_lock);
+ done:
+ 	return err;
+ }
+@@ -110,7 +110,6 @@ static int ts_release(struct inode *inode, struct file *file)
+ {
+ 	struct saa7134_dev *dev = file->private_data;
+ 
+-	mutex_lock(&dev->empress_tsq.lock);
+ 	videobuf_stop(&dev->empress_tsq);
+ 	videobuf_mmap_free(&dev->empress_tsq);
+ 	dev->empress_users--;
+@@ -122,7 +121,6 @@ static int ts_release(struct inode *inode, struct file *file)
+ 	saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
+ 		saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
+ 
+-	mutex_unlock(&dev->empress_tsq.lock);
+ 	return 0;
+ }
+ 
+diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
+index 0db955c..b418881 100644
+--- a/drivers/media/video/saa7134/saa7134-input.c
++++ b/drivers/media/video/saa7134/saa7134-input.c
+@@ -406,6 +406,12 @@ int saa7134_input_init1(struct saa7134_dev *dev)
+ 		mask_keyup   = 0x8000000;
+ 		polling      = 50; //ms
+ 		break;
++	case SAA7134_BOARD_GENIUS_TVGO_A11MCE:
++		ir_codes     = ir_codes_genius_tvgo_a11mce;
++		mask_keycode = 0xff;
++		mask_keydown = 0xf00000;
++		polling = 50; /* ms */
++		break;
+ 	}
+ 	if (NULL == ir_codes) {
+ 		printk("%s: Oops: IR config error [card=%d]\n",
+diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
+index 1184d35..39c41ad 100644
+--- a/drivers/media/video/saa7134/saa7134-video.c
++++ b/drivers/media/video/saa7134/saa7134-video.c
+@@ -1414,21 +1414,17 @@ video_poll(struct file *file, struct poll_table_struct *wait)
+ 		if (!list_empty(&fh->cap.stream))
+ 			buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream);
+ 	} else {
+-		mutex_lock(&fh->cap.lock);
++		mutex_lock(&fh->cap.vb_lock);
+ 		if (UNSET == fh->cap.read_off) {
+ 			/* need to capture a new frame */
+-			if (res_locked(fh->dev,RESOURCE_VIDEO)) {
+-				mutex_unlock(&fh->cap.lock);
+-				return POLLERR;
+-			}
+-			if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
+-				mutex_unlock(&fh->cap.lock);
+-				return POLLERR;
+-			}
++			if (res_locked(fh->dev,RESOURCE_VIDEO))
++				goto err;
++			if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field))
++				goto err;
+ 			fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
+ 			fh->cap.read_off = 0;
+ 		}
+-		mutex_unlock(&fh->cap.lock);
++		mutex_unlock(&fh->cap.vb_lock);
+ 		buf = fh->cap.read_buf;
+ 	}
+ 
+@@ -1440,6 +1436,10 @@ video_poll(struct file *file, struct poll_table_struct *wait)
+ 	    buf->state == VIDEOBUF_ERROR)
+ 		return POLLIN|POLLRDNORM;
+ 	return 0;
++
++err:
++	mutex_unlock(&fh->cap.vb_lock);
++	return POLLERR;
+ }
+ 
+ static int video_release(struct inode *inode, struct file *file)
+diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
+index b88ca99..f940d02 100644
+--- a/drivers/media/video/saa7134/saa7134.h
++++ b/drivers/media/video/saa7134/saa7134.h
+@@ -252,6 +252,8 @@ struct saa7134_format {
+ #define SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM 128
+ #define SAA7134_BOARD_BEHOLD_607_9FM	129
+ #define SAA7134_BOARD_BEHOLD_M6		130
++#define SAA7134_BOARD_TWINHAN_DTV_DVB_3056 131
++#define SAA7134_BOARD_GENIUS_TVGO_A11MCE 132
+ 
+ #define SAA7134_MAXBOARDS 8
+ #define SAA7134_INPUT_MAX 8
+diff --git a/drivers/media/video/stk-sensor.c b/drivers/media/video/stk-sensor.c
+index 4a9a0b6..e546b01 100644
+--- a/drivers/media/video/stk-sensor.c
++++ b/drivers/media/video/stk-sensor.c
+@@ -225,7 +225,7 @@
+ 
+ 
+ /* Returns 0 if OK */
+-int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val)
++static int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val)
+ {
+ 	int i = 0;
+ 	int tmpval = 0;
+@@ -250,7 +250,7 @@ int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val)
+ 		return 0;
+ }
+ 
+-int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val)
++static int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val)
+ {
+ 	int i = 0;
+ 	int tmpval = 0;
+@@ -380,7 +380,7 @@ int stk_sensor_init(struct stk_camera *dev)
+ 		STK_ERROR("Strange error reading sensor ID\n");
+ 		return -ENODEV;
+ 	}
+-	if (idh != 0x7F || idl != 0xA2) {
++	if (idh != 0x7f || idl != 0xa2) {
+ 		STK_ERROR("Huh? you don't have a sensor from ovt\n");
+ 		return -ENODEV;
+ 	}
+@@ -409,6 +409,19 @@ static struct regval ov_fmt_uyvy[] = {
+ 	{REG_COM15, COM15_R00FF },
+ 	{0xff, 0xff}, /* END MARKER */
+ };
++/* V4L2_PIX_FMT_YUYV */
++static struct regval ov_fmt_yuyv[] = {
++	{REG_TSLB, 0 },
++	{ 0x4f, 0x80 }, 	/* "matrix coefficient 1" */
++	{ 0x50, 0x80 }, 	/* "matrix coefficient 2" */
++	{ 0x51, 0    },		/* vb */
++	{ 0x52, 0x22 }, 	/* "matrix coefficient 4" */
++	{ 0x53, 0x5e }, 	/* "matrix coefficient 5" */
++	{ 0x54, 0x80 }, 	/* "matrix coefficient 6" */
++	{REG_COM13, COM13_UVSAT|COM13_CMATRIX},
++	{REG_COM15, COM15_R00FF },
++	{0xff, 0xff}, /* END MARKER */
++};
+ 
+ /* V4L2_PIX_FMT_RGB565X rrrrrggg gggbbbbb */
+ static struct regval ov_fmt_rgbr[] = {
+@@ -519,6 +532,10 @@ int stk_sensor_configure(struct stk_camera *dev)
+ 		com7 |= COM7_YUV;
+ 		rv = ov_fmt_uyvy;
+ 		break;
++	case V4L2_PIX_FMT_YUYV:
++		com7 |= COM7_YUV;
++		rv = ov_fmt_yuyv;
++		break;
+ 	case V4L2_PIX_FMT_RGB565:
+ 		com7 |= COM7_RGB;
+ 		rv = ov_fmt_rgbp;
+diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
+index d37e5e2..ceba45a 100644
+--- a/drivers/media/video/stk-webcam.c
++++ b/drivers/media/video/stk-webcam.c
+@@ -63,7 +63,7 @@ static struct usb_device_id stkwebcam_table[] = {
+ };
+ MODULE_DEVICE_TABLE(usb, stkwebcam_table);
+ 
+-void stk_camera_cleanup(struct kref *kref)
++static void stk_camera_cleanup(struct kref *kref)
+ {
+ 	struct stk_camera *dev = to_stk_camera(kref);
+ 
+@@ -682,6 +682,7 @@ static int v4l_stk_open(struct inode *inode, struct file *fp)
+ 		return -ENXIO;
+ 	fp->private_data = vdev;
+ 	kref_get(&dev->kref);
++	usb_autopm_get_interface(dev->interface);
+ 
+ 	return 0;
+ }
+@@ -703,6 +704,7 @@ static int v4l_stk_release(struct inode *inode, struct file *fp)
+ 	}
+ 
+ 	if (dev->owner != fp) {
++		usb_autopm_put_interface(dev->interface);
+ 		kref_put(&dev->kref, stk_camera_cleanup);
+ 		return 0;
+ 	}
+@@ -713,6 +715,7 @@ static int v4l_stk_release(struct inode *inode, struct file *fp)
+ 
+ 	dev->owner = NULL;
+ 
++	usb_autopm_put_interface(dev->interface);
+ 	kref_put(&dev->kref, stk_camera_cleanup);
+ 
+ 	return 0;
+@@ -993,6 +996,10 @@ static int stk_vidioc_enum_fmt_cap(struct file *filp,
+ 		fmtd->pixelformat = V4L2_PIX_FMT_SBGGR8;
+ 		strcpy(fmtd->description, "Raw bayer");
+ 		break;
++	case 4:
++		fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
++		strcpy(fmtd->description, "yuv4:2:2");
++		break;
+ 	default:
+ 		return -EINVAL;
+ 	}
+@@ -1048,6 +1055,7 @@ static int stk_vidioc_try_fmt_cap(struct file *filp,
+ 	case V4L2_PIX_FMT_RGB565:
+ 	case V4L2_PIX_FMT_RGB565X:
+ 	case V4L2_PIX_FMT_UYVY:
++	case V4L2_PIX_FMT_YUYV:
+ 	case V4L2_PIX_FMT_SBGGR8:
+ 		break;
+ 	default:
+@@ -1080,6 +1088,42 @@ static int stk_vidioc_try_fmt_cap(struct file *filp,
+ 	return 0;
+ }
+ 
++static int stk_setup_format(struct stk_camera *dev)
++{
++	int i = 0;
++	int depth;
++	if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8)
++		depth = 1;
++	else
++		depth = 2;
++	while (stk_sizes[i].m != dev->vsettings.mode
++			&& i < ARRAY_SIZE(stk_sizes))
++		i++;
++	if (i == ARRAY_SIZE(stk_sizes)) {
++		STK_ERROR("Something is broken in %s\n", __FUNCTION__);
++		return -EFAULT;
++	}
++	/* This registers controls some timings, not sure of what. */
++	stk_camera_write_reg(dev, 0x001b, 0x0e);
++	if (dev->vsettings.mode == MODE_SXGA)
++		stk_camera_write_reg(dev, 0x001c, 0x0e);
++	else
++		stk_camera_write_reg(dev, 0x001c, 0x46);
++	/*
++	 * Registers 0x0115 0x0114 are the size of each line (bytes),
++	 * regs 0x0117 0x0116 are the heigth of the image.
++	 */
++	stk_camera_write_reg(dev, 0x0115,
++		((stk_sizes[i].w * depth) >> 8) & 0xff);
++	stk_camera_write_reg(dev, 0x0114,
++		(stk_sizes[i].w * depth) & 0xff);
++	stk_camera_write_reg(dev, 0x0117,
++		(stk_sizes[i].h >> 8) & 0xff);
++	stk_camera_write_reg(dev, 0x0116,
++		stk_sizes[i].h & 0xff);
++	return stk_sensor_configure(dev);
++}
++
+ static int stk_vidioc_s_fmt_cap(struct file *filp,
+ 		void *priv, struct v4l2_format *fmtd)
+ {
+@@ -1094,10 +1138,10 @@ static int stk_vidioc_s_fmt_cap(struct file *filp,
+ 		return -EBUSY;
+ 	if (dev->owner && dev->owner != filp)
+ 		return -EBUSY;
+-	dev->owner = filp;
+ 	ret = stk_vidioc_try_fmt_cap(filp, priv, fmtd);
+ 	if (ret)
+ 		return ret;
++	dev->owner = filp;
+ 
+ 	dev->vsettings.palette = fmtd->fmt.pix.pixelformat;
+ 	stk_free_buffers(dev);
+@@ -1105,25 +1149,7 @@ static int stk_vidioc_s_fmt_cap(struct file *filp,
+ 	dev->vsettings.mode = stk_sizes[fmtd->fmt.pix.priv].m;
+ 
+ 	stk_initialise(dev);
+-	/* This registers controls some timings, not sure of what. */
+-	stk_camera_write_reg(dev, 0x001b, 0x0e);
+-	if (dev->vsettings.mode == MODE_SXGA)
+-		stk_camera_write_reg(dev, 0x001c, 0x0e);
+-	else
+-		stk_camera_write_reg(dev, 0x001c, 0x46);
+-	/*
+-	 * Registers 0x0115 0x0114 are the size of each line (bytes),
+-	 * regs 0x0117 0x0116 are the heigth of the image.
+-	 */
+-	stk_camera_write_reg(dev, 0x0115,
+-		(fmtd->fmt.pix.bytesperline >> 8) & 0xff);
+-	stk_camera_write_reg(dev, 0x0114,
+-		fmtd->fmt.pix.bytesperline & 0xff);
+-	stk_camera_write_reg(dev, 0x0117,
+-		(fmtd->fmt.pix.height >> 8) & 0xff);
+-	stk_camera_write_reg(dev, 0x0116,
+-		fmtd->fmt.pix.height & 0xff);
+-	return stk_sensor_configure(dev);
++	return stk_setup_format(dev);
+ }
+ 
+ static int stk_vidioc_reqbufs(struct file *filp,
+@@ -1288,6 +1314,9 @@ static struct file_operations v4l_stk_fops = {
+ 	.poll = v4l_stk_poll,
+ 	.mmap = v4l_stk_mmap,
+ 	.ioctl = video_ioctl2,
++#ifdef CONFIG_COMPAT
++	.compat_ioctl = v4l_compat_ioctl32,
++#endif
+ 	.llseek = no_llseek
+ };
+ 
+@@ -1403,7 +1432,7 @@ static int stk_camera_probe(struct usb_interface *interface,
+ 	dev->vsettings.brightness = 0x7fff;
+ 	dev->vsettings.palette = V4L2_PIX_FMT_RGB565;
+ 	dev->vsettings.mode = MODE_VGA;
+-	dev->frame_size = 640*480*2;
++	dev->frame_size = 640 * 480 * 2;
+ 
+ 	INIT_LIST_HEAD(&dev->sio_avail);
+ 	INIT_LIST_HEAD(&dev->sio_full);
+@@ -1417,6 +1446,7 @@ static int stk_camera_probe(struct usb_interface *interface,
+ 	}
+ 
+ 	stk_create_sysfs_files(&dev->vdev);
++	usb_autopm_enable(dev->interface);
+ 
+ 	return 0;
+ }
+@@ -1434,11 +1464,41 @@ static void stk_camera_disconnect(struct usb_interface *interface)
+ 	kref_put(&dev->kref, stk_camera_cleanup);
+ }
+ 
++#ifdef CONFIG_PM
++int stk_camera_suspend(struct usb_interface *intf, pm_message_t message)
++{
++	struct stk_camera *dev = usb_get_intfdata(intf);
++	if (is_streaming(dev)) {
++		stk_stop_stream(dev);
++		/* yes, this is ugly */
++		set_streaming(dev);
++	}
++	return 0;
++}
++
++int stk_camera_resume(struct usb_interface *intf)
++{
++	struct stk_camera *dev = usb_get_intfdata(intf);
++	if (!is_initialised(dev))
++		return 0;
++	unset_initialised(dev);
++	stk_initialise(dev);
++	stk_setup_format(dev);
++	if (is_streaming(dev))
++		stk_start_stream(dev);
++	return 0;
++}
++#endif
++
+ static struct usb_driver stk_camera_driver = {
+ 	.name = "stkwebcam",
+ 	.probe = stk_camera_probe,
+ 	.disconnect = stk_camera_disconnect,
+ 	.id_table = stkwebcam_table,
++#ifdef CONFIG_PM
++	.suspend = stk_camera_suspend,
++	.resume = stk_camera_resume,
++#endif
+ };
+ 
+ 
+diff --git a/drivers/media/video/stk-webcam.h b/drivers/media/video/stk-webcam.h
+index 7e989d1..df4dfef 100644
+--- a/drivers/media/video/stk-webcam.h
++++ b/drivers/media/video/stk-webcam.h
+@@ -79,6 +79,7 @@ enum stk_status {
+ #define unset_present(dev)	((dev)->status &= \
+ 					~(S_PRESENT|S_INITIALISED|S_STREAMING))
+ #define set_initialised(dev)	((dev)->status |= S_INITIALISED)
++#define unset_initialised(dev)	((dev)->status &= ~S_INITIALISED)
+ #define set_memallocd(dev)	((dev)->status |= S_MEMALLOCD)
+ #define unset_memallocd(dev)	((dev)->status &= ~S_MEMALLOCD)
+ #define set_streaming(dev)	((dev)->status |= S_STREAMING)
+@@ -127,8 +128,6 @@ void stk_camera_delete(struct kref *);
+ int stk_camera_write_reg(struct stk_camera *, u16, u8);
+ int stk_camera_read_reg(struct stk_camera *, u16, int *);
+ 
+-int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val);
+-int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val);
+ int stk_sensor_init(struct stk_camera *);
+ int stk_sensor_configure(struct stk_camera *);
+ int stk_sensor_sleep(struct stk_camera *dev);
+diff --git a/drivers/media/video/tcm825x.c b/drivers/media/video/tcm825x.c
+index 41cd6a0..fb895f6 100644
+--- a/drivers/media/video/tcm825x.c
++++ b/drivers/media/video/tcm825x.c
+@@ -851,7 +851,7 @@ static int tcm825x_probe(struct i2c_client *client)
+ 	sensor->platform_data = client->dev.platform_data;
+ 
+ 	if (sensor->platform_data == NULL
+-	    && !sensor->platform_data->is_okay())
++	    || !sensor->platform_data->is_okay())
+ 		return -ENODEV;
+ 
+ 	sensor->v4l2_int_device = &tcm825x_int_device;
+diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
+index ba538f6..78a09a2 100644
+--- a/drivers/media/video/tuner-core.c
++++ b/drivers/media/video/tuner-core.c
+@@ -1038,7 +1038,7 @@ static int tuner_resume(struct i2c_client *c)
+ 
+ /* ---------------------------------------------------------------------- */
+ 
+-LIST_HEAD(tuner_list);
++static LIST_HEAD(tuner_list);
+ 
+ /* Search for existing radio and/or TV tuners on the given I2C adapter.
+    Note that when this function is called from tuner_probe you can be
+diff --git a/drivers/media/video/tuner-xc2028.c b/drivers/media/video/tuner-xc2028.c
+index f191f6a..50cf876 100644
+--- a/drivers/media/video/tuner-xc2028.c
++++ b/drivers/media/video/tuner-xc2028.c
+@@ -754,6 +754,9 @@ skip_std_specific:
+ 		goto check_device;
+ 	}
+ 
++	if (new_fw.type & FM)
++		goto check_device;
++
+ 	/* Load SCODE firmware, if exists */
+ 	tuner_dbg("Trying to load scode %d\n", new_fw.scode_nr);
+ 
+diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
+index a755605..01ebcec 100644
+--- a/drivers/media/video/tvaudio.c
++++ b/drivers/media/video/tvaudio.c
+@@ -1571,14 +1571,14 @@ static int tvaudio_get_ctrl(struct CHIPSTATE *chip,
+ 		ctrl->value=chip->muted;
+ 		return 0;
+ 	case V4L2_CID_AUDIO_VOLUME:
+-		if (!desc->flags & CHIP_HAS_VOLUME)
++		if (!(desc->flags & CHIP_HAS_VOLUME))
+ 			break;
+ 		ctrl->value = max(chip->left,chip->right);
+ 		return 0;
+ 	case V4L2_CID_AUDIO_BALANCE:
+ 	{
+ 		int volume;
+-		if (!desc->flags & CHIP_HAS_VOLUME)
++		if (!(desc->flags & CHIP_HAS_VOLUME))
+ 			break;
+ 		volume = max(chip->left,chip->right);
+ 		if (volume)
+@@ -1621,7 +1621,7 @@ static int tvaudio_set_ctrl(struct CHIPSTATE *chip,
+ 	{
+ 		int volume,balance;
+ 
+-		if (!desc->flags & CHIP_HAS_VOLUME)
++		if (!(desc->flags & CHIP_HAS_VOLUME))
+ 			break;
+ 
+ 		volume = max(chip->left,chip->right);
+@@ -1642,7 +1642,7 @@ static int tvaudio_set_ctrl(struct CHIPSTATE *chip,
+ 	case V4L2_CID_AUDIO_BALANCE:
+ 	{
+ 		int volume, balance;
+-		if (!desc->flags & CHIP_HAS_VOLUME)
++		if (!(desc->flags & CHIP_HAS_VOLUME))
+ 			break;
+ 
+ 		volume = max(chip->left,chip->right);
+@@ -1702,7 +1702,7 @@ static int chip_command(struct i2c_client *client,
+ 				break;
+ 			case V4L2_CID_AUDIO_VOLUME:
+ 			case V4L2_CID_AUDIO_BALANCE:
+-				if (!desc->flags & CHIP_HAS_VOLUME)
++				if (!(desc->flags & CHIP_HAS_VOLUME))
+ 					return -EINVAL;
+ 				break;
+ 			case V4L2_CID_AUDIO_BASS:
+diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
+index 0b8fbad..dc0da44 100644
+--- a/drivers/media/video/tveeprom.c
++++ b/drivers/media/video/tveeprom.c
+@@ -242,7 +242,7 @@ hauppauge_tuner[] =
+ 	{ TUNER_ABSENT,        		"TCL M2523_3DBH_E"},
+ 	{ TUNER_ABSENT,        		"TCL M2523_3DIH_E"},
+ 	{ TUNER_ABSENT,        		"TCL MFPE05_2_U"},
+-	{ TUNER_ABSENT,        		"Philips FMD1216MEX"},
++	{ TUNER_PHILIPS_FMD1216ME_MK3,	"Philips FMD1216MEX"},
+ 	{ TUNER_ABSENT,        		"Philips FRH2036B"},
+ 	{ TUNER_ABSENT,        		"Panasonic ENGF75_01GF"},
+ 	{ TUNER_ABSENT,        		"MaxLinear MXL5005"},
+diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
+index c056ff6..34deb68 100644
+--- a/drivers/media/video/v4l2-common.c
++++ b/drivers/media/video/v4l2-common.c
+@@ -56,7 +56,6 @@
+ #include <asm/pgtable.h>
+ #include <asm/io.h>
+ #include <asm/div64.h>
+-#include <linux/video_decoder.h>
+ #define __OLD_VIDIOC_ /* To allow fixing old calls*/
+ #include <media/v4l2-common.h>
+ #include <media/v4l2-chip-ident.h>
+@@ -82,108 +81,6 @@ MODULE_LICENSE("GPL");
+  */
+ 
+ 
+-char *v4l2_norm_to_name(v4l2_std_id id)
+-{
+-	char *name;
+-	u32 myid = id;
+-
+-	/* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
+-	   64 bit comparations. So, on that architecture, with some gcc variants,
+-	   compilation fails. Currently, the max value is 30bit wide.
+-	 */
+-	BUG_ON(myid != id);
+-
+-	switch (myid) {
+-	case V4L2_STD_PAL:
+-		name="PAL";		break;
+-	case V4L2_STD_PAL_BG:
+-		name="PAL-BG";		break;
+-	case V4L2_STD_PAL_DK:
+-		name="PAL-DK";		break;
+-	case V4L2_STD_PAL_B:
+-		name="PAL-B";		break;
+-	case V4L2_STD_PAL_B1:
+-		name="PAL-B1";		break;
+-	case V4L2_STD_PAL_G:
+-		name="PAL-G";		break;
+-	case V4L2_STD_PAL_H:
+-		name="PAL-H";		break;
+-	case V4L2_STD_PAL_I:
+-		name="PAL-I";		break;
+-	case V4L2_STD_PAL_D:
+-		name="PAL-D";		break;
+-	case V4L2_STD_PAL_D1:
+-		name="PAL-D1";		break;
+-	case V4L2_STD_PAL_K:
+-		name="PAL-K";		break;
+-	case V4L2_STD_PAL_M:
+-		name="PAL-M";		break;
+-	case V4L2_STD_PAL_N:
+-		name="PAL-N";		break;
+-	case V4L2_STD_PAL_Nc:
+-		name="PAL-Nc";		break;
+-	case V4L2_STD_PAL_60:
+-		name="PAL-60";		break;
+-	case V4L2_STD_NTSC:
+-		name="NTSC";		break;
+-	case V4L2_STD_NTSC_M:
+-		name="NTSC-M";		break;
+-	case V4L2_STD_NTSC_M_JP:
+-		name="NTSC-M-JP";	break;
+-	case V4L2_STD_NTSC_443:
+-		name="NTSC-443";	break;
+-	case V4L2_STD_NTSC_M_KR:
+-		name="NTSC-M-KR";	break;
+-	case V4L2_STD_SECAM:
+-		name="SECAM";		break;
+-	case V4L2_STD_SECAM_DK:
+-		name="SECAM-DK";	break;
+-	case V4L2_STD_SECAM_B:
+-		name="SECAM-B";		break;
+-	case V4L2_STD_SECAM_D:
+-		name="SECAM-D";		break;
+-	case V4L2_STD_SECAM_G:
+-		name="SECAM-G";		break;
+-	case V4L2_STD_SECAM_H:
+-		name="SECAM-H";		break;
+-	case V4L2_STD_SECAM_K:
+-		name="SECAM-K";		break;
+-	case V4L2_STD_SECAM_K1:
+-		name="SECAM-K1";	break;
+-	case V4L2_STD_SECAM_L:
+-		name="SECAM-L";		break;
+-	case V4L2_STD_SECAM_LC:
+-		name="SECAM-LC";	break;
+-	default:
+-		name="Unknown";		break;
+-	}
+-
+-	return name;
+-}
+-
+-/* Fill in the fields of a v4l2_standard structure according to the
+-   'id' and 'transmission' parameters.  Returns negative on error.  */
+-int v4l2_video_std_construct(struct v4l2_standard *vs,
+-			     int id, char *name)
+-{
+-	u32 index = vs->index;
+-
+-	memset(vs, 0, sizeof(struct v4l2_standard));
+-	vs->index = index;
+-	vs->id    = id;
+-	if (id & V4L2_STD_525_60) {
+-		vs->frameperiod.numerator = 1001;
+-		vs->frameperiod.denominator = 30000;
+-		vs->framelines = 525;
+-	} else {
+-		vs->frameperiod.numerator = 1;
+-		vs->frameperiod.denominator = 25;
+-		vs->framelines = 625;
+-	}
+-	strlcpy(vs->name,name,sizeof(vs->name));
+-	return 0;
+-}
+-
+ /* ----------------------------------------------------------------- */
+ /* priority handling                                                 */
+ 
+@@ -196,6 +93,7 @@ int v4l2_prio_init(struct v4l2_prio_state *global)
+ 	memset(global,0,sizeof(*global));
+ 	return 0;
+ }
++EXPORT_SYMBOL(v4l2_prio_init);
+ 
+ int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
+ 		     enum v4l2_priority new)
+@@ -211,11 +109,13 @@ int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
+ 	*local = new;
+ 	return 0;
+ }
++EXPORT_SYMBOL(v4l2_prio_change);
+ 
+ int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)
+ {
+ 	return v4l2_prio_change(global,local,V4L2_PRIORITY_DEFAULT);
+ }
++EXPORT_SYMBOL(v4l2_prio_open);
+ 
+ int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local)
+ {
+@@ -223,6 +123,7 @@ int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local)
+ 		atomic_dec(&global->prios[*local]);
+ 	return 0;
+ }
++EXPORT_SYMBOL(v4l2_prio_close);
+ 
+ enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
+ {
+@@ -234,6 +135,7 @@ enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
+ 		return V4L2_PRIORITY_BACKGROUND;
+ 	return V4L2_PRIORITY_UNSET;
+ }
++EXPORT_SYMBOL(v4l2_prio_max);
+ 
+ int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local)
+ {
+@@ -241,225 +143,7 @@ int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local)
+ 		return -EBUSY;
+ 	return 0;
+ }
+-
+-
+-/* ----------------------------------------------------------------- */
+-/* some arrays for pretty-printing debug messages of enum types      */
+-
+-char *v4l2_field_names[] = {
+-	[V4L2_FIELD_ANY]        = "any",
+-	[V4L2_FIELD_NONE]       = "none",
+-	[V4L2_FIELD_TOP]        = "top",
+-	[V4L2_FIELD_BOTTOM]     = "bottom",
+-	[V4L2_FIELD_INTERLACED] = "interlaced",
+-	[V4L2_FIELD_SEQ_TB]     = "seq-tb",
+-	[V4L2_FIELD_SEQ_BT]     = "seq-bt",
+-	[V4L2_FIELD_ALTERNATE]  = "alternate",
+-	[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
+-	[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
+-};
+-
+-char *v4l2_type_names[] = {
+-	[V4L2_BUF_TYPE_VIDEO_CAPTURE]      = "video-cap",
+-	[V4L2_BUF_TYPE_VIDEO_OVERLAY]      = "video-over",
+-	[V4L2_BUF_TYPE_VIDEO_OUTPUT]       = "video-out",
+-	[V4L2_BUF_TYPE_VBI_CAPTURE]        = "vbi-cap",
+-	[V4L2_BUF_TYPE_VBI_OUTPUT]         = "vbi-out",
+-	[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
+-	[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT]  = "sliced-vbi-out",
+-	[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
+-};
+-
+-
+-#define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
+-
+-/* ------------------------------------------------------------------ */
+-/* debug help functions                                               */
+-
+-#ifdef CONFIG_VIDEO_V4L1_COMPAT
+-static const char *v4l1_ioctls[] = {
+-	[_IOC_NR(VIDIOCGCAP)]       = "VIDIOCGCAP",
+-	[_IOC_NR(VIDIOCGCHAN)]      = "VIDIOCGCHAN",
+-	[_IOC_NR(VIDIOCSCHAN)]      = "VIDIOCSCHAN",
+-	[_IOC_NR(VIDIOCGTUNER)]     = "VIDIOCGTUNER",
+-	[_IOC_NR(VIDIOCSTUNER)]     = "VIDIOCSTUNER",
+-	[_IOC_NR(VIDIOCGPICT)]      = "VIDIOCGPICT",
+-	[_IOC_NR(VIDIOCSPICT)]      = "VIDIOCSPICT",
+-	[_IOC_NR(VIDIOCCAPTURE)]    = "VIDIOCCAPTURE",
+-	[_IOC_NR(VIDIOCGWIN)]       = "VIDIOCGWIN",
+-	[_IOC_NR(VIDIOCSWIN)]       = "VIDIOCSWIN",
+-	[_IOC_NR(VIDIOCGFBUF)]      = "VIDIOCGFBUF",
+-	[_IOC_NR(VIDIOCSFBUF)]      = "VIDIOCSFBUF",
+-	[_IOC_NR(VIDIOCKEY)]        = "VIDIOCKEY",
+-	[_IOC_NR(VIDIOCGFREQ)]      = "VIDIOCGFREQ",
+-	[_IOC_NR(VIDIOCSFREQ)]      = "VIDIOCSFREQ",
+-	[_IOC_NR(VIDIOCGAUDIO)]     = "VIDIOCGAUDIO",
+-	[_IOC_NR(VIDIOCSAUDIO)]     = "VIDIOCSAUDIO",
+-	[_IOC_NR(VIDIOCSYNC)]       = "VIDIOCSYNC",
+-	[_IOC_NR(VIDIOCMCAPTURE)]   = "VIDIOCMCAPTURE",
+-	[_IOC_NR(VIDIOCGMBUF)]      = "VIDIOCGMBUF",
+-	[_IOC_NR(VIDIOCGUNIT)]      = "VIDIOCGUNIT",
+-	[_IOC_NR(VIDIOCGCAPTURE)]   = "VIDIOCGCAPTURE",
+-	[_IOC_NR(VIDIOCSCAPTURE)]   = "VIDIOCSCAPTURE",
+-	[_IOC_NR(VIDIOCSPLAYMODE)]  = "VIDIOCSPLAYMODE",
+-	[_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
+-	[_IOC_NR(VIDIOCGPLAYINFO)]  = "VIDIOCGPLAYINFO",
+-	[_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
+-	[_IOC_NR(VIDIOCGVBIFMT)]    = "VIDIOCGVBIFMT",
+-	[_IOC_NR(VIDIOCSVBIFMT)]    = "VIDIOCSVBIFMT"
+-};
+-#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
+-#endif
+-
+-static const char *v4l2_ioctls[] = {
+-	[_IOC_NR(VIDIOC_QUERYCAP)]         = "VIDIOC_QUERYCAP",
+-	[_IOC_NR(VIDIOC_RESERVED)]         = "VIDIOC_RESERVED",
+-	[_IOC_NR(VIDIOC_ENUM_FMT)]         = "VIDIOC_ENUM_FMT",
+-	[_IOC_NR(VIDIOC_G_FMT)]            = "VIDIOC_G_FMT",
+-	[_IOC_NR(VIDIOC_S_FMT)]            = "VIDIOC_S_FMT",
+-	[_IOC_NR(VIDIOC_REQBUFS)]          = "VIDIOC_REQBUFS",
+-	[_IOC_NR(VIDIOC_QUERYBUF)]         = "VIDIOC_QUERYBUF",
+-	[_IOC_NR(VIDIOC_G_FBUF)]           = "VIDIOC_G_FBUF",
+-	[_IOC_NR(VIDIOC_S_FBUF)]           = "VIDIOC_S_FBUF",
+-	[_IOC_NR(VIDIOC_OVERLAY)]          = "VIDIOC_OVERLAY",
+-	[_IOC_NR(VIDIOC_QBUF)]             = "VIDIOC_QBUF",
+-	[_IOC_NR(VIDIOC_DQBUF)]            = "VIDIOC_DQBUF",
+-	[_IOC_NR(VIDIOC_STREAMON)]         = "VIDIOC_STREAMON",
+-	[_IOC_NR(VIDIOC_STREAMOFF)]        = "VIDIOC_STREAMOFF",
+-	[_IOC_NR(VIDIOC_G_PARM)]           = "VIDIOC_G_PARM",
+-	[_IOC_NR(VIDIOC_S_PARM)]           = "VIDIOC_S_PARM",
+-	[_IOC_NR(VIDIOC_G_STD)]            = "VIDIOC_G_STD",
+-	[_IOC_NR(VIDIOC_S_STD)]            = "VIDIOC_S_STD",
+-	[_IOC_NR(VIDIOC_ENUMSTD)]          = "VIDIOC_ENUMSTD",
+-	[_IOC_NR(VIDIOC_ENUMINPUT)]        = "VIDIOC_ENUMINPUT",
+-	[_IOC_NR(VIDIOC_G_CTRL)]           = "VIDIOC_G_CTRL",
+-	[_IOC_NR(VIDIOC_S_CTRL)]           = "VIDIOC_S_CTRL",
+-	[_IOC_NR(VIDIOC_G_TUNER)]          = "VIDIOC_G_TUNER",
+-	[_IOC_NR(VIDIOC_S_TUNER)]          = "VIDIOC_S_TUNER",
+-	[_IOC_NR(VIDIOC_G_AUDIO)]          = "VIDIOC_G_AUDIO",
+-	[_IOC_NR(VIDIOC_S_AUDIO)]          = "VIDIOC_S_AUDIO",
+-	[_IOC_NR(VIDIOC_QUERYCTRL)]        = "VIDIOC_QUERYCTRL",
+-	[_IOC_NR(VIDIOC_QUERYMENU)]        = "VIDIOC_QUERYMENU",
+-	[_IOC_NR(VIDIOC_G_INPUT)]          = "VIDIOC_G_INPUT",
+-	[_IOC_NR(VIDIOC_S_INPUT)]          = "VIDIOC_S_INPUT",
+-	[_IOC_NR(VIDIOC_G_OUTPUT)]         = "VIDIOC_G_OUTPUT",
+-	[_IOC_NR(VIDIOC_S_OUTPUT)]         = "VIDIOC_S_OUTPUT",
+-	[_IOC_NR(VIDIOC_ENUMOUTPUT)]       = "VIDIOC_ENUMOUTPUT",
+-	[_IOC_NR(VIDIOC_G_AUDOUT)]         = "VIDIOC_G_AUDOUT",
+-	[_IOC_NR(VIDIOC_S_AUDOUT)]         = "VIDIOC_S_AUDOUT",
+-	[_IOC_NR(VIDIOC_G_MODULATOR)]      = "VIDIOC_G_MODULATOR",
+-	[_IOC_NR(VIDIOC_S_MODULATOR)]      = "VIDIOC_S_MODULATOR",
+-	[_IOC_NR(VIDIOC_G_FREQUENCY)]      = "VIDIOC_G_FREQUENCY",
+-	[_IOC_NR(VIDIOC_S_FREQUENCY)]      = "VIDIOC_S_FREQUENCY",
+-	[_IOC_NR(VIDIOC_CROPCAP)]          = "VIDIOC_CROPCAP",
+-	[_IOC_NR(VIDIOC_G_CROP)]           = "VIDIOC_G_CROP",
+-	[_IOC_NR(VIDIOC_S_CROP)]           = "VIDIOC_S_CROP",
+-	[_IOC_NR(VIDIOC_G_JPEGCOMP)]       = "VIDIOC_G_JPEGCOMP",
+-	[_IOC_NR(VIDIOC_S_JPEGCOMP)]       = "VIDIOC_S_JPEGCOMP",
+-	[_IOC_NR(VIDIOC_QUERYSTD)]         = "VIDIOC_QUERYSTD",
+-	[_IOC_NR(VIDIOC_TRY_FMT)]          = "VIDIOC_TRY_FMT",
+-	[_IOC_NR(VIDIOC_ENUMAUDIO)]        = "VIDIOC_ENUMAUDIO",
+-	[_IOC_NR(VIDIOC_ENUMAUDOUT)]       = "VIDIOC_ENUMAUDOUT",
+-	[_IOC_NR(VIDIOC_G_PRIORITY)]       = "VIDIOC_G_PRIORITY",
+-	[_IOC_NR(VIDIOC_S_PRIORITY)]       = "VIDIOC_S_PRIORITY",
+-	[_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
+-	[_IOC_NR(VIDIOC_LOG_STATUS)]       = "VIDIOC_LOG_STATUS",
+-	[_IOC_NR(VIDIOC_G_EXT_CTRLS)]      = "VIDIOC_G_EXT_CTRLS",
+-	[_IOC_NR(VIDIOC_S_EXT_CTRLS)]      = "VIDIOC_S_EXT_CTRLS",
+-	[_IOC_NR(VIDIOC_TRY_EXT_CTRLS)]    = "VIDIOC_TRY_EXT_CTRLS",
+-#if 1
+-	[_IOC_NR(VIDIOC_ENUM_FRAMESIZES)]  = "VIDIOC_ENUM_FRAMESIZES",
+-	[_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
+-	[_IOC_NR(VIDIOC_G_ENC_INDEX)] 	   = "VIDIOC_G_ENC_INDEX",
+-	[_IOC_NR(VIDIOC_ENCODER_CMD)] 	   = "VIDIOC_ENCODER_CMD",
+-	[_IOC_NR(VIDIOC_TRY_ENCODER_CMD)]  = "VIDIOC_TRY_ENCODER_CMD",
+-
+-	[_IOC_NR(VIDIOC_DBG_S_REGISTER)]   = "VIDIOC_DBG_S_REGISTER",
+-	[_IOC_NR(VIDIOC_DBG_G_REGISTER)]   = "VIDIOC_DBG_G_REGISTER",
+-
+-	[_IOC_NR(VIDIOC_G_CHIP_IDENT)]     = "VIDIOC_G_CHIP_IDENT",
+-#endif
+-};
+-#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
+-
+-static const char *v4l2_int_ioctls[] = {
+-#ifdef CONFIG_VIDEO_V4L1_COMPAT
+-	[_IOC_NR(DECODER_GET_CAPABILITIES)]    = "DECODER_GET_CAPABILITIES",
+-	[_IOC_NR(DECODER_GET_STATUS)]          = "DECODER_GET_STATUS",
+-	[_IOC_NR(DECODER_SET_NORM)]            = "DECODER_SET_NORM",
+-	[_IOC_NR(DECODER_SET_INPUT)]           = "DECODER_SET_INPUT",
+-	[_IOC_NR(DECODER_SET_OUTPUT)]          = "DECODER_SET_OUTPUT",
+-	[_IOC_NR(DECODER_ENABLE_OUTPUT)]       = "DECODER_ENABLE_OUTPUT",
+-	[_IOC_NR(DECODER_SET_PICTURE)]         = "DECODER_SET_PICTURE",
+-	[_IOC_NR(DECODER_SET_GPIO)]            = "DECODER_SET_GPIO",
+-	[_IOC_NR(DECODER_INIT)]                = "DECODER_INIT",
+-	[_IOC_NR(DECODER_SET_VBI_BYPASS)]      = "DECODER_SET_VBI_BYPASS",
+-	[_IOC_NR(DECODER_DUMP)]                = "DECODER_DUMP",
+-#endif
+-	[_IOC_NR(AUDC_SET_RADIO)]              = "AUDC_SET_RADIO",
+-
+-	[_IOC_NR(TUNER_SET_TYPE_ADDR)]         = "TUNER_SET_TYPE_ADDR",
+-	[_IOC_NR(TUNER_SET_STANDBY)]           = "TUNER_SET_STANDBY",
+-	[_IOC_NR(TUNER_SET_CONFIG)]            = "TUNER_SET_CONFIG",
+-
+-	[_IOC_NR(VIDIOC_INT_S_TUNER_MODE)]     = "VIDIOC_INT_S_TUNER_MODE",
+-	[_IOC_NR(VIDIOC_INT_RESET)]            = "VIDIOC_INT_RESET",
+-	[_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
+-	[_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)]  = "VIDIOC_INT_DECODE_VBI_LINE",
+-	[_IOC_NR(VIDIOC_INT_S_VBI_DATA)]       = "VIDIOC_INT_S_VBI_DATA",
+-	[_IOC_NR(VIDIOC_INT_G_VBI_DATA)]       = "VIDIOC_INT_G_VBI_DATA",
+-	[_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)]   = "VIDIOC_INT_I2S_CLOCK_FREQ",
+-	[_IOC_NR(VIDIOC_INT_S_STANDBY)]        = "VIDIOC_INT_S_STANDBY",
+-	[_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)]  = "VIDIOC_INT_S_AUDIO_ROUTING",
+-	[_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)]  = "VIDIOC_INT_G_AUDIO_ROUTING",
+-	[_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)]  = "VIDIOC_INT_S_VIDEO_ROUTING",
+-	[_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)]  = "VIDIOC_INT_G_VIDEO_ROUTING",
+-	[_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)]   = "VIDIOC_INT_S_CRYSTAL_FREQ",
+-	[_IOC_NR(VIDIOC_INT_INIT)]   	       = "VIDIOC_INT_INIT",
+-	[_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)]     = "VIDIOC_INT_G_STD_OUTPUT",
+-	[_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)]     = "VIDIOC_INT_S_STD_OUTPUT",
+-};
+-#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
+-
+-
+-/* Common ioctl debug function. This function can be used by
+-   external ioctl messages as well as internal V4L ioctl */
+-void v4l_printk_ioctl(unsigned int cmd)
+-{
+-	char *dir;
+-
+-	switch (_IOC_DIR(cmd)) {
+-	case _IOC_NONE:              dir = "--"; break;
+-	case _IOC_READ:              dir = "r-"; break;
+-	case _IOC_WRITE:             dir = "-w"; break;
+-	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
+-	default:                     dir = "*ERR*"; break;
+-	}
+-	switch (_IOC_TYPE(cmd)) {
+-	case 'd':
+-		printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n",
+-		       (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ?
+-		       v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
+-		break;
+-#ifdef CONFIG_VIDEO_V4L1_COMPAT
+-	case 'v':
+-		printk("v4l1 ioctl %s, dir=%s (0x%08x)\n",
+-		       (_IOC_NR(cmd) < V4L1_IOCTLS) ?
+-		       v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
+-		break;
+-#endif
+-	case 'V':
+-		printk("v4l2 ioctl %s, dir=%s (0x%08x)\n",
+-		       (_IOC_NR(cmd) < V4L2_IOCTLS) ?
+-		       v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
+-		break;
+-
+-	default:
+-		printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n",
+-		       _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
+-	}
+-}
+-
++EXPORT_SYMBOL(v4l2_prio_check);
+ 
+ /* ----------------------------------------------------------------- */
+ 
+@@ -488,6 +172,7 @@ int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
+ 	}
+ 	return 0;
+ }
++EXPORT_SYMBOL(v4l2_ctrl_check);
+ 
+ /* Returns NULL or a character pointer array containing the menu for
+    the given control ID. The pointer array ends with a NULL pointer.
+@@ -648,6 +333,7 @@ const char **v4l2_ctrl_get_menu(u32 id)
+ 			return NULL;
+ 	}
+ }
++EXPORT_SYMBOL(v4l2_ctrl_get_menu);
+ 
+ /* Fill in a struct v4l2_queryctrl */
+ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def)
+@@ -770,6 +456,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
+ 	snprintf(qctrl->name, sizeof(qctrl->name), name);
+ 	return 0;
+ }
++EXPORT_SYMBOL(v4l2_ctrl_query_fill);
+ 
+ /* Fill in a struct v4l2_queryctrl with standard values based on
+    the control ID. */
+@@ -904,6 +591,7 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl)
+ 		return -EINVAL;
+ 	}
+ }
++EXPORT_SYMBOL(v4l2_ctrl_query_fill_std);
+ 
+ /* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and
+    the menu. The qctrl pointer may be NULL, in which case it is ignored. */
+@@ -922,6 +610,7 @@ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qc
+ 	qmenu->reserved = 0;
+ 	return 0;
+ }
++EXPORT_SYMBOL(v4l2_ctrl_query_menu);
+ 
+ /* ctrl_classes points to an array of u32 pointers, the last element is
+    a NULL pointer. Each u32 array is a 0-terminated array of control IDs.
+@@ -972,7 +661,20 @@ u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id)
+ 		return 0;
+ 	return **ctrl_classes;
+ }
++EXPORT_SYMBOL(v4l2_ctrl_next);
+ 
++int v4l2_chip_match_host(u32 match_type, u32 match_chip)
++{
++	switch (match_type) {
++	case V4L2_CHIP_MATCH_HOST:
++		return match_chip == 0;
++	default:
++		return 0;
++	}
++}
++EXPORT_SYMBOL(v4l2_chip_match_host);
++
++#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
+ int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_chip)
+ {
+ 	switch (match_type) {
+@@ -984,6 +686,7 @@ int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_c
+ 		return 0;
+ 	}
+ }
++EXPORT_SYMBOL(v4l2_chip_match_i2c_client);
+ 
+ int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chip,
+ 		u32 ident, u32 revision)
+@@ -1000,16 +703,7 @@ int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chi
+ 	}
+ 	return 0;
+ }
+-
+-int v4l2_chip_match_host(u32 match_type, u32 match_chip)
+-{
+-	switch (match_type) {
+-	case V4L2_CHIP_MATCH_HOST:
+-		return match_chip == 0;
+-	default:
+-		return 0;
+-	}
+-}
++EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
+ 
+ /* ----------------------------------------------------------------- */
+ 
+@@ -1038,38 +732,5 @@ int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver
+ 	}
+ 	return err != -ENOMEM ? 0 : err;
+ }
+-
+-/* ----------------------------------------------------------------- */
+-
+-EXPORT_SYMBOL(v4l2_norm_to_name);
+-EXPORT_SYMBOL(v4l2_video_std_construct);
+-
+-EXPORT_SYMBOL(v4l2_prio_init);
+-EXPORT_SYMBOL(v4l2_prio_change);
+-EXPORT_SYMBOL(v4l2_prio_open);
+-EXPORT_SYMBOL(v4l2_prio_close);
+-EXPORT_SYMBOL(v4l2_prio_max);
+-EXPORT_SYMBOL(v4l2_prio_check);
+-
+-EXPORT_SYMBOL(v4l2_field_names);
+-EXPORT_SYMBOL(v4l2_type_names);
+-EXPORT_SYMBOL(v4l_printk_ioctl);
+-
+-EXPORT_SYMBOL(v4l2_ctrl_next);
+-EXPORT_SYMBOL(v4l2_ctrl_check);
+-EXPORT_SYMBOL(v4l2_ctrl_get_menu);
+-EXPORT_SYMBOL(v4l2_ctrl_query_menu);
+-EXPORT_SYMBOL(v4l2_ctrl_query_fill);
+-EXPORT_SYMBOL(v4l2_ctrl_query_fill_std);
+-
+-EXPORT_SYMBOL(v4l2_chip_match_i2c_client);
+-EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
+-EXPORT_SYMBOL(v4l2_chip_match_host);
+-
+ EXPORT_SYMBOL(v4l2_i2c_attach);
+-
+-/*
+- * Local variables:
+- * c-basic-offset: 8
+- * End:
+- */
++#endif
+diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
+index 80a14da..eab79ff 100644
+--- a/drivers/media/video/videobuf-core.c
++++ b/drivers/media/video/videobuf-core.c
+@@ -147,7 +147,7 @@ void videobuf_queue_core_init(struct videobuf_queue *q,
+ 	/* Having implementations for abstract methods are mandatory */
+ 	BUG_ON(!q->int_ops);
+ 
+-	mutex_init(&q->lock);
++	mutex_init(&q->vb_lock);
+ 	INIT_LIST_HEAD(&q->stream);
+ }
+ 
+@@ -189,7 +189,7 @@ int videobuf_queue_is_busy(struct videobuf_queue *q)
+ 	return 0;
+ }
+ 
+-/* Locking: Caller holds q->lock */
++/* Locking: Caller holds q->vb_lock */
+ void videobuf_queue_cancel(struct videobuf_queue *q)
+ {
+ 	unsigned long flags = 0;
+@@ -220,7 +220,7 @@ void videobuf_queue_cancel(struct videobuf_queue *q)
+ 
+ /* --------------------------------------------------------------------- */
+ 
+-/* Locking: Caller holds q->lock */
++/* Locking: Caller holds q->vb_lock */
+ enum v4l2_field videobuf_next_field(struct videobuf_queue *q)
+ {
+ 	enum v4l2_field field = q->field;
+@@ -239,7 +239,7 @@ enum v4l2_field videobuf_next_field(struct videobuf_queue *q)
+ 	return field;
+ }
+ 
+-/* Locking: Caller holds q->lock */
++/* Locking: Caller holds q->vb_lock */
+ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
+ 			    struct videobuf_buffer *vb, enum v4l2_buf_type type)
+ {
+@@ -295,7 +295,7 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
+ 	b->sequence  = vb->field_count >> 1;
+ }
+ 
+-/* Locking: Caller holds q->lock */
++/* Locking: Caller holds q->vb_lock */
+ static int __videobuf_mmap_free(struct videobuf_queue *q)
+ {
+ 	int i;
+@@ -328,13 +328,13 @@ static int __videobuf_mmap_free(struct videobuf_queue *q)
+ int videobuf_mmap_free(struct videobuf_queue *q)
+ {
+ 	int ret;
+-	mutex_lock(&q->lock);
++	mutex_lock(&q->vb_lock);
+ 	ret = __videobuf_mmap_free(q);
+-	mutex_unlock(&q->lock);
++	mutex_unlock(&q->vb_lock);
+ 	return ret;
+ }
+ 
+-/* Locking: Caller holds q->lock */
++/* Locking: Caller holds q->vb_lock */
+ static int __videobuf_mmap_setup(struct videobuf_queue *q,
+ 			unsigned int bcount, unsigned int bsize,
+ 			enum v4l2_memory memory)
+@@ -384,9 +384,9 @@ int videobuf_mmap_setup(struct videobuf_queue *q,
+ 			enum v4l2_memory memory)
+ {
+ 	int ret;
+-	mutex_lock(&q->lock);
++	mutex_lock(&q->vb_lock);
+ 	ret = __videobuf_mmap_setup(q, bcount, bsize, memory);
+-	mutex_unlock(&q->lock);
++	mutex_unlock(&q->vb_lock);
+ 	return ret;
+ }
+ 
+@@ -408,7 +408,7 @@ int videobuf_reqbufs(struct videobuf_queue *q,
+ 		return -EINVAL;
+ 	}
+ 
+-	mutex_lock(&q->lock);
++	mutex_lock(&q->vb_lock);
+ 	if (req->type != q->type) {
+ 		dprintk(1, "reqbufs: queue type invalid\n");
+ 		retval = -EINVAL;
+@@ -444,7 +444,7 @@ int videobuf_reqbufs(struct videobuf_queue *q,
+ 	req->count = retval;
+ 
+  done:
+-	mutex_unlock(&q->lock);
++	mutex_unlock(&q->vb_lock);
+ 	return retval;
+ }
+ 
+@@ -452,7 +452,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
+ {
+ 	int ret = -EINVAL;
+ 
+-	mutex_lock(&q->lock);
++	mutex_lock(&q->vb_lock);
+ 	if (unlikely(b->type != q->type)) {
+ 		dprintk(1, "querybuf: Wrong type.\n");
+ 		goto done;
+@@ -470,7 +470,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
+ 
+ 	ret = 0;
+ done:
+-	mutex_unlock(&q->lock);
++	mutex_unlock(&q->vb_lock);
+ 	return ret;
+ }
+ 
+@@ -487,7 +487,7 @@ int videobuf_qbuf(struct videobuf_queue *q,
+ 	if (b->memory == V4L2_MEMORY_MMAP)
+ 		down_read(&current->mm->mmap_sem);
+ 
+-	mutex_lock(&q->lock);
++	mutex_lock(&q->vb_lock);
+ 	retval = -EBUSY;
+ 	if (q->reading) {
+ 		dprintk(1, "qbuf: Reading running...\n");
+@@ -573,7 +573,7 @@ int videobuf_qbuf(struct videobuf_queue *q,
+ 	retval = 0;
+ 
+  done:
+-	mutex_unlock(&q->lock);
++	mutex_unlock(&q->vb_lock);
+ 
+ 	if (b->memory == V4L2_MEMORY_MMAP)
+ 		up_read(&current->mm->mmap_sem);
+@@ -589,7 +589,7 @@ int videobuf_dqbuf(struct videobuf_queue *q,
+ 
+ 	MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
+ 
+-	mutex_lock(&q->lock);
++	mutex_lock(&q->vb_lock);
+ 	retval = -EBUSY;
+ 	if (q->reading) {
+ 		dprintk(1, "dqbuf: Reading running...\n");
+@@ -632,7 +632,7 @@ int videobuf_dqbuf(struct videobuf_queue *q,
+ 	videobuf_status(q, b, buf, q->type);
+ 
+  done:
+-	mutex_unlock(&q->lock);
++	mutex_unlock(&q->vb_lock);
+ 	return retval;
+ }
+ 
+@@ -642,7 +642,7 @@ int videobuf_streamon(struct videobuf_queue *q)
+ 	unsigned long flags = 0;
+ 	int retval;
+ 
+-	mutex_lock(&q->lock);
++	mutex_lock(&q->vb_lock);
+ 	retval = -EBUSY;
+ 	if (q->reading)
+ 		goto done;
+@@ -659,11 +659,11 @@ int videobuf_streamon(struct videobuf_queue *q)
+ 		spin_unlock_irqrestore(q->irqlock, flags);
+ 
+  done:
+-	mutex_unlock(&q->lock);
++	mutex_unlock(&q->vb_lock);
+ 	return retval;
+ }
+ 
+-/* Locking: Caller holds q->lock */
++/* Locking: Caller holds q->vb_lock */
+ static int __videobuf_streamoff(struct videobuf_queue *q)
+ {
+ 	if (!q->streaming)
+@@ -679,14 +679,14 @@ int videobuf_streamoff(struct videobuf_queue *q)
+ {
+ 	int retval;
+ 
+-	mutex_lock(&q->lock);
++	mutex_lock(&q->vb_lock);
+ 	retval = __videobuf_streamoff(q);
+-	mutex_unlock(&q->lock);
++	mutex_unlock(&q->vb_lock);
+ 
+ 	return retval;
+ }
+ 
+-/* Locking: Caller holds q->lock */
++/* Locking: Caller holds q->vb_lock */
+ static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q,
+ 				      char __user *data,
+ 				      size_t count, loff_t *ppos)
+@@ -745,7 +745,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
+ 
+ 	MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
+ 
+-	mutex_lock(&q->lock);
++	mutex_lock(&q->vb_lock);
+ 
+ 	nbufs = 1; size = 0;
+ 	q->ops->buf_setup(q, &nbufs, &size);
+@@ -817,11 +817,11 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
+ 	}
+ 
+  done:
+-	mutex_unlock(&q->lock);
++	mutex_unlock(&q->vb_lock);
+ 	return retval;
+ }
+ 
+-/* Locking: Caller holds q->lock */
++/* Locking: Caller holds q->vb_lock */
+ static int __videobuf_read_start(struct videobuf_queue *q)
+ {
+ 	enum v4l2_field field;
+@@ -882,23 +882,23 @@ int videobuf_read_start(struct videobuf_queue *q)
+ {
+ 	int rc;
+ 
+-	mutex_lock(&q->lock);
++	mutex_lock(&q->vb_lock);
+ 	rc = __videobuf_read_start(q);
+-	mutex_unlock(&q->lock);
++	mutex_unlock(&q->vb_lock);
+ 
+ 	return rc;
+ }
+ 
+ void videobuf_read_stop(struct videobuf_queue *q)
+ {
+-	mutex_lock(&q->lock);
++	mutex_lock(&q->vb_lock);
+ 	__videobuf_read_stop(q);
+-	mutex_unlock(&q->lock);
++	mutex_unlock(&q->vb_lock);
+ }
+ 
+ void videobuf_stop(struct videobuf_queue *q)
+ {
+-	mutex_lock(&q->lock);
++	mutex_lock(&q->vb_lock);
+ 
+ 	if (q->streaming)
+ 		__videobuf_streamoff(q);
+@@ -906,7 +906,7 @@ void videobuf_stop(struct videobuf_queue *q)
+ 	if (q->reading)
+ 		__videobuf_read_stop(q);
+ 
+-	mutex_unlock(&q->lock);
++	mutex_unlock(&q->vb_lock);
+ }
+ 
+ 
+@@ -920,7 +920,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
+ 	MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
+ 
+ 	dprintk(2, "%s\n", __FUNCTION__);
+-	mutex_lock(&q->lock);
++	mutex_lock(&q->vb_lock);
+ 	retval = -EBUSY;
+ 	if (q->streaming)
+ 		goto done;
+@@ -980,7 +980,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
+ 	}
+ 
+  done:
+-	mutex_unlock(&q->lock);
++	mutex_unlock(&q->vb_lock);
+ 	return retval;
+ }
+ 
+@@ -991,7 +991,7 @@ unsigned int videobuf_poll_stream(struct file *file,
+ 	struct videobuf_buffer *buf = NULL;
+ 	unsigned int rc = 0;
+ 
+-	mutex_lock(&q->lock);
++	mutex_lock(&q->vb_lock);
+ 	if (q->streaming) {
+ 		if (!list_empty(&q->stream))
+ 			buf = list_entry(q->stream.next,
+@@ -1019,7 +1019,7 @@ unsigned int videobuf_poll_stream(struct file *file,
+ 		    buf->state == VIDEOBUF_ERROR)
+ 			rc = POLLIN|POLLRDNORM;
+ 	}
+-	mutex_unlock(&q->lock);
++	mutex_unlock(&q->vb_lock);
+ 	return rc;
+ }
+ 
+@@ -1030,10 +1030,10 @@ int videobuf_mmap_mapper(struct videobuf_queue *q,
+ 
+ 	MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
+ 
+-	mutex_lock(&q->lock);
++	mutex_lock(&q->vb_lock);
+ 	retval = CALL(q, mmap_mapper, q, vma);
+ 	q->is_mmapped = 1;
+-	mutex_unlock(&q->lock);
++	mutex_unlock(&q->vb_lock);
+ 
+ 	return retval;
+ }
+diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
+index 98efd7a..53fed4b 100644
+--- a/drivers/media/video/videobuf-dma-sg.c
++++ b/drivers/media/video/videobuf-dma-sg.c
+@@ -356,7 +356,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
+ 	map->count--;
+ 	if (0 == map->count) {
+ 		dprintk(1,"munmap %p q=%p\n",map,q);
+-		mutex_lock(&q->lock);
++		mutex_lock(&q->vb_lock);
+ 		for (i = 0; i < VIDEO_MAX_FRAME; i++) {
+ 			if (NULL == q->bufs[i])
+ 				continue;
+@@ -373,7 +373,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
+ 			q->bufs[i]->baddr = 0;
+ 			q->ops->buf_release(q,q->bufs[i]);
+ 		}
+-		mutex_unlock(&q->lock);
++		mutex_unlock(&q->vb_lock);
+ 		kfree(map);
+ 	}
+ 	return;
+diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
+index 9b38983..5266ecc 100644
+--- a/drivers/media/video/videobuf-vmalloc.c
++++ b/drivers/media/video/videobuf-vmalloc.c
+@@ -70,7 +70,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
+ 	map->count--;
+ 	if (0 == map->count) {
+ 		dprintk(1,"munmap %p q=%p\n",map,q);
+-		mutex_lock(&q->lock);
++		mutex_lock(&q->vb_lock);
+ 		for (i = 0; i < VIDEO_MAX_FRAME; i++) {
+ 			if (NULL == q->bufs[i])
+ 				continue;
+@@ -83,7 +83,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
+ 			q->bufs[i]->map   = NULL;
+ 			q->bufs[i]->baddr = 0;
+ 		}
+-		mutex_unlock(&q->lock);
++		mutex_unlock(&q->vb_lock);
+ 		kfree(map);
+ 	}
+ 	return;
+@@ -107,7 +107,7 @@ static struct vm_operations_struct videobuf_vm_ops =
+ 
+ static void *__videobuf_alloc(size_t size)
+ {
+-	struct videbuf_vmalloc_memory *mem;
++	struct videobuf_vmalloc_memory *mem;
+ 	struct videobuf_buffer *vb;
+ 
+ 	vb = kzalloc(size+sizeof(*mem),GFP_KERNEL);
+@@ -127,9 +127,7 @@ static int __videobuf_iolock (struct videobuf_queue* q,
+ 			      struct v4l2_framebuffer *fbuf)
+ {
+ 	int pages;
+-
+-	struct videbuf_vmalloc_memory *mem=vb->priv;
+-
++	struct videobuf_vmalloc_memory *mem=vb->priv;
+ 
+ 	BUG_ON(!mem);
+ 
+@@ -195,7 +193,7 @@ static int __videobuf_mmap_free(struct videobuf_queue *q)
+ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
+ 			 struct vm_area_struct *vma)
+ {
+-	struct videbuf_vmalloc_memory *mem;
++	struct videobuf_vmalloc_memory *mem;
+ 	struct videobuf_mapping *map;
+ 	unsigned int first;
+ 	int retval;
+@@ -267,7 +265,7 @@ static int __videobuf_copy_to_user ( struct videobuf_queue *q,
+ 				char __user *data, size_t count,
+ 				int nonblocking )
+ {
+-	struct videbuf_vmalloc_memory *mem=q->read_buf->priv;
++	struct videobuf_vmalloc_memory *mem=q->read_buf->priv;
+ 	BUG_ON (!mem);
+ 	MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
+ 
+@@ -288,7 +286,7 @@ static int __videobuf_copy_stream ( struct videobuf_queue *q,
+ 				int vbihack, int nonblocking )
+ {
+ 	unsigned int  *fc;
+-	struct videbuf_vmalloc_memory *mem=q->read_buf->priv;
++	struct videobuf_vmalloc_memory *mem=q->read_buf->priv;
+ 	BUG_ON (!mem);
+ 	MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
+ 
+@@ -341,7 +339,7 @@ EXPORT_SYMBOL_GPL(videobuf_queue_vmalloc_init);
+ 
+ void *videobuf_to_vmalloc (struct videobuf_buffer *buf)
+ {
+-	struct videbuf_vmalloc_memory *mem=buf->priv;
++	struct videobuf_vmalloc_memory *mem=buf->priv;
+ 	BUG_ON (!mem);
+ 	MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
+ 
+@@ -351,7 +349,7 @@ EXPORT_SYMBOL_GPL(videobuf_to_vmalloc);
+ 
+ void videobuf_vmalloc_free (struct videobuf_buffer *buf)
+ {
+-	struct videbuf_vmalloc_memory *mem=buf->priv;
++	struct videobuf_vmalloc_memory *mem=buf->priv;
+ 	BUG_ON (!mem);
+ 
+ 	MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
+diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
+index 28655f8..0d9b637 100644
+--- a/drivers/media/video/videodev.c
++++ b/drivers/media/video/videodev.c
+@@ -46,10 +46,373 @@
+ #include <linux/videodev.h>
+ #endif
+ #include <media/v4l2-common.h>
++#include <linux/video_decoder.h>
+ 
+ #define VIDEO_NUM_DEVICES	256
+ #define VIDEO_NAME              "video4linux"
+ 
++/* video4linux standard ID conversion to standard name
++ */
++char *v4l2_norm_to_name(v4l2_std_id id)
++{
++	char *name;
++	u32 myid = id;
++
++	/* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
++	   64 bit comparations. So, on that architecture, with some gcc
++	   variants, compilation fails. Currently, the max value is 30bit wide.
++	 */
++	BUG_ON(myid != id);
++
++	switch (myid) {
++	case V4L2_STD_PAL:
++		name = "PAL";
++		break;
++	case V4L2_STD_PAL_BG:
++		name = "PAL-BG";
++		break;
++	case V4L2_STD_PAL_DK:
++		name = "PAL-DK";
++		break;
++	case V4L2_STD_PAL_B:
++		name = "PAL-B";
++		break;
++	case V4L2_STD_PAL_B1:
++		name = "PAL-B1";
++		break;
++	case V4L2_STD_PAL_G:
++		name = "PAL-G";
++		break;
++	case V4L2_STD_PAL_H:
++		name = "PAL-H";
++		break;
++	case V4L2_STD_PAL_I:
++		name = "PAL-I";
++		break;
++	case V4L2_STD_PAL_D:
++		name = "PAL-D";
++		break;
++	case V4L2_STD_PAL_D1:
++		name = "PAL-D1";
++		break;
++	case V4L2_STD_PAL_K:
++		name = "PAL-K";
++		break;
++	case V4L2_STD_PAL_M:
++		name = "PAL-M";
++		break;
++	case V4L2_STD_PAL_N:
++		name = "PAL-N";
++		break;
++	case V4L2_STD_PAL_Nc:
++		name = "PAL-Nc";
++		break;
++	case V4L2_STD_PAL_60:
++		name = "PAL-60";
++		break;
++	case V4L2_STD_NTSC:
++		name = "NTSC";
++		break;
++	case V4L2_STD_NTSC_M:
++		name = "NTSC-M";
++		break;
++	case V4L2_STD_NTSC_M_JP:
++		name = "NTSC-M-JP";
++		break;
++	case V4L2_STD_NTSC_443:
++		name = "NTSC-443";
++		break;
++	case V4L2_STD_NTSC_M_KR:
++		name = "NTSC-M-KR";
++		break;
++	case V4L2_STD_SECAM:
++		name = "SECAM";
++		break;
++	case V4L2_STD_SECAM_DK:
++		name = "SECAM-DK";
++		break;
++	case V4L2_STD_SECAM_B:
++		name = "SECAM-B";
++		break;
++	case V4L2_STD_SECAM_D:
++		name = "SECAM-D";
++		break;
++	case V4L2_STD_SECAM_G:
++		name = "SECAM-G";
++		break;
++	case V4L2_STD_SECAM_H:
++		name = "SECAM-H";
++		break;
++	case V4L2_STD_SECAM_K:
++		name = "SECAM-K";
++		break;
++	case V4L2_STD_SECAM_K1:
++		name = "SECAM-K1";
++		break;
++	case V4L2_STD_SECAM_L:
++		name = "SECAM-L";
++		break;
++	case V4L2_STD_SECAM_LC:
++		name = "SECAM-LC";
++		break;
++	default:
++		name = "Unknown";
++		break;
++	}
++
++	return name;
++}
++EXPORT_SYMBOL(v4l2_norm_to_name);
++
++/* Fill in the fields of a v4l2_standard structure according to the
++   'id' and 'transmission' parameters.  Returns negative on error.  */
++int v4l2_video_std_construct(struct v4l2_standard *vs,
++			     int id, char *name)
++{
++	u32 index = vs->index;
++
++	memset(vs, 0, sizeof(struct v4l2_standard));
++	vs->index = index;
++	vs->id    = id;
++	if (id & V4L2_STD_525_60) {
++		vs->frameperiod.numerator = 1001;
++		vs->frameperiod.denominator = 30000;
++		vs->framelines = 525;
++	} else {
++		vs->frameperiod.numerator = 1;
++		vs->frameperiod.denominator = 25;
++		vs->framelines = 625;
++	}
++	strlcpy(vs->name, name, sizeof(vs->name));
++	return 0;
++}
++EXPORT_SYMBOL(v4l2_video_std_construct);
++
++/* ----------------------------------------------------------------- */
++/* some arrays for pretty-printing debug messages of enum types      */
++
++char *v4l2_field_names[] = {
++	[V4L2_FIELD_ANY]        = "any",
++	[V4L2_FIELD_NONE]       = "none",
++	[V4L2_FIELD_TOP]        = "top",
++	[V4L2_FIELD_BOTTOM]     = "bottom",
++	[V4L2_FIELD_INTERLACED] = "interlaced",
++	[V4L2_FIELD_SEQ_TB]     = "seq-tb",
++	[V4L2_FIELD_SEQ_BT]     = "seq-bt",
++	[V4L2_FIELD_ALTERNATE]  = "alternate",
++	[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
++	[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
++};
++EXPORT_SYMBOL(v4l2_field_names);
++
++char *v4l2_type_names[] = {
++	[V4L2_BUF_TYPE_VIDEO_CAPTURE]      = "video-cap",
++	[V4L2_BUF_TYPE_VIDEO_OVERLAY]      = "video-over",
++	[V4L2_BUF_TYPE_VIDEO_OUTPUT]       = "video-out",
++	[V4L2_BUF_TYPE_VBI_CAPTURE]        = "vbi-cap",
++	[V4L2_BUF_TYPE_VBI_OUTPUT]         = "vbi-out",
++	[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
++	[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT]  = "sliced-vbi-out",
++	[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
++};
++EXPORT_SYMBOL(v4l2_type_names);
++
++static char *v4l2_memory_names[] = {
++	[V4L2_MEMORY_MMAP]    = "mmap",
++	[V4L2_MEMORY_USERPTR] = "userptr",
++	[V4L2_MEMORY_OVERLAY] = "overlay",
++};
++
++#define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
++			   arr[a] : "unknown")
++
++/* ------------------------------------------------------------------ */
++/* debug help functions                                               */
++
++#ifdef CONFIG_VIDEO_V4L1_COMPAT
++static const char *v4l1_ioctls[] = {
++	[_IOC_NR(VIDIOCGCAP)]       = "VIDIOCGCAP",
++	[_IOC_NR(VIDIOCGCHAN)]      = "VIDIOCGCHAN",
++	[_IOC_NR(VIDIOCSCHAN)]      = "VIDIOCSCHAN",
++	[_IOC_NR(VIDIOCGTUNER)]     = "VIDIOCGTUNER",
++	[_IOC_NR(VIDIOCSTUNER)]     = "VIDIOCSTUNER",
++	[_IOC_NR(VIDIOCGPICT)]      = "VIDIOCGPICT",
++	[_IOC_NR(VIDIOCSPICT)]      = "VIDIOCSPICT",
++	[_IOC_NR(VIDIOCCAPTURE)]    = "VIDIOCCAPTURE",
++	[_IOC_NR(VIDIOCGWIN)]       = "VIDIOCGWIN",
++	[_IOC_NR(VIDIOCSWIN)]       = "VIDIOCSWIN",
++	[_IOC_NR(VIDIOCGFBUF)]      = "VIDIOCGFBUF",
++	[_IOC_NR(VIDIOCSFBUF)]      = "VIDIOCSFBUF",
++	[_IOC_NR(VIDIOCKEY)]        = "VIDIOCKEY",
++	[_IOC_NR(VIDIOCGFREQ)]      = "VIDIOCGFREQ",
++	[_IOC_NR(VIDIOCSFREQ)]      = "VIDIOCSFREQ",
++	[_IOC_NR(VIDIOCGAUDIO)]     = "VIDIOCGAUDIO",
++	[_IOC_NR(VIDIOCSAUDIO)]     = "VIDIOCSAUDIO",
++	[_IOC_NR(VIDIOCSYNC)]       = "VIDIOCSYNC",
++	[_IOC_NR(VIDIOCMCAPTURE)]   = "VIDIOCMCAPTURE",
++	[_IOC_NR(VIDIOCGMBUF)]      = "VIDIOCGMBUF",
++	[_IOC_NR(VIDIOCGUNIT)]      = "VIDIOCGUNIT",
++	[_IOC_NR(VIDIOCGCAPTURE)]   = "VIDIOCGCAPTURE",
++	[_IOC_NR(VIDIOCSCAPTURE)]   = "VIDIOCSCAPTURE",
++	[_IOC_NR(VIDIOCSPLAYMODE)]  = "VIDIOCSPLAYMODE",
++	[_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
++	[_IOC_NR(VIDIOCGPLAYINFO)]  = "VIDIOCGPLAYINFO",
++	[_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
++	[_IOC_NR(VIDIOCGVBIFMT)]    = "VIDIOCGVBIFMT",
++	[_IOC_NR(VIDIOCSVBIFMT)]    = "VIDIOCSVBIFMT"
++};
++#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
++#endif
++
++static const char *v4l2_ioctls[] = {
++	[_IOC_NR(VIDIOC_QUERYCAP)]         = "VIDIOC_QUERYCAP",
++	[_IOC_NR(VIDIOC_RESERVED)]         = "VIDIOC_RESERVED",
++	[_IOC_NR(VIDIOC_ENUM_FMT)]         = "VIDIOC_ENUM_FMT",
++	[_IOC_NR(VIDIOC_G_FMT)]            = "VIDIOC_G_FMT",
++	[_IOC_NR(VIDIOC_S_FMT)]            = "VIDIOC_S_FMT",
++	[_IOC_NR(VIDIOC_REQBUFS)]          = "VIDIOC_REQBUFS",
++	[_IOC_NR(VIDIOC_QUERYBUF)]         = "VIDIOC_QUERYBUF",
++	[_IOC_NR(VIDIOC_G_FBUF)]           = "VIDIOC_G_FBUF",
++	[_IOC_NR(VIDIOC_S_FBUF)]           = "VIDIOC_S_FBUF",
++	[_IOC_NR(VIDIOC_OVERLAY)]          = "VIDIOC_OVERLAY",
++	[_IOC_NR(VIDIOC_QBUF)]             = "VIDIOC_QBUF",
++	[_IOC_NR(VIDIOC_DQBUF)]            = "VIDIOC_DQBUF",
++	[_IOC_NR(VIDIOC_STREAMON)]         = "VIDIOC_STREAMON",
++	[_IOC_NR(VIDIOC_STREAMOFF)]        = "VIDIOC_STREAMOFF",
++	[_IOC_NR(VIDIOC_G_PARM)]           = "VIDIOC_G_PARM",
++	[_IOC_NR(VIDIOC_S_PARM)]           = "VIDIOC_S_PARM",
++	[_IOC_NR(VIDIOC_G_STD)]            = "VIDIOC_G_STD",
++	[_IOC_NR(VIDIOC_S_STD)]            = "VIDIOC_S_STD",
++	[_IOC_NR(VIDIOC_ENUMSTD)]          = "VIDIOC_ENUMSTD",
++	[_IOC_NR(VIDIOC_ENUMINPUT)]        = "VIDIOC_ENUMINPUT",
++	[_IOC_NR(VIDIOC_G_CTRL)]           = "VIDIOC_G_CTRL",
++	[_IOC_NR(VIDIOC_S_CTRL)]           = "VIDIOC_S_CTRL",
++	[_IOC_NR(VIDIOC_G_TUNER)]          = "VIDIOC_G_TUNER",
++	[_IOC_NR(VIDIOC_S_TUNER)]          = "VIDIOC_S_TUNER",
++	[_IOC_NR(VIDIOC_G_AUDIO)]          = "VIDIOC_G_AUDIO",
++	[_IOC_NR(VIDIOC_S_AUDIO)]          = "VIDIOC_S_AUDIO",
++	[_IOC_NR(VIDIOC_QUERYCTRL)]        = "VIDIOC_QUERYCTRL",
++	[_IOC_NR(VIDIOC_QUERYMENU)]        = "VIDIOC_QUERYMENU",
++	[_IOC_NR(VIDIOC_G_INPUT)]          = "VIDIOC_G_INPUT",
++	[_IOC_NR(VIDIOC_S_INPUT)]          = "VIDIOC_S_INPUT",
++	[_IOC_NR(VIDIOC_G_OUTPUT)]         = "VIDIOC_G_OUTPUT",
++	[_IOC_NR(VIDIOC_S_OUTPUT)]         = "VIDIOC_S_OUTPUT",
++	[_IOC_NR(VIDIOC_ENUMOUTPUT)]       = "VIDIOC_ENUMOUTPUT",
++	[_IOC_NR(VIDIOC_G_AUDOUT)]         = "VIDIOC_G_AUDOUT",
++	[_IOC_NR(VIDIOC_S_AUDOUT)]         = "VIDIOC_S_AUDOUT",
++	[_IOC_NR(VIDIOC_G_MODULATOR)]      = "VIDIOC_G_MODULATOR",
++	[_IOC_NR(VIDIOC_S_MODULATOR)]      = "VIDIOC_S_MODULATOR",
++	[_IOC_NR(VIDIOC_G_FREQUENCY)]      = "VIDIOC_G_FREQUENCY",
++	[_IOC_NR(VIDIOC_S_FREQUENCY)]      = "VIDIOC_S_FREQUENCY",
++	[_IOC_NR(VIDIOC_CROPCAP)]          = "VIDIOC_CROPCAP",
++	[_IOC_NR(VIDIOC_G_CROP)]           = "VIDIOC_G_CROP",
++	[_IOC_NR(VIDIOC_S_CROP)]           = "VIDIOC_S_CROP",
++	[_IOC_NR(VIDIOC_G_JPEGCOMP)]       = "VIDIOC_G_JPEGCOMP",
++	[_IOC_NR(VIDIOC_S_JPEGCOMP)]       = "VIDIOC_S_JPEGCOMP",
++	[_IOC_NR(VIDIOC_QUERYSTD)]         = "VIDIOC_QUERYSTD",
++	[_IOC_NR(VIDIOC_TRY_FMT)]          = "VIDIOC_TRY_FMT",
++	[_IOC_NR(VIDIOC_ENUMAUDIO)]        = "VIDIOC_ENUMAUDIO",
++	[_IOC_NR(VIDIOC_ENUMAUDOUT)]       = "VIDIOC_ENUMAUDOUT",
++	[_IOC_NR(VIDIOC_G_PRIORITY)]       = "VIDIOC_G_PRIORITY",
++	[_IOC_NR(VIDIOC_S_PRIORITY)]       = "VIDIOC_S_PRIORITY",
++	[_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
++	[_IOC_NR(VIDIOC_LOG_STATUS)]       = "VIDIOC_LOG_STATUS",
++	[_IOC_NR(VIDIOC_G_EXT_CTRLS)]      = "VIDIOC_G_EXT_CTRLS",
++	[_IOC_NR(VIDIOC_S_EXT_CTRLS)]      = "VIDIOC_S_EXT_CTRLS",
++	[_IOC_NR(VIDIOC_TRY_EXT_CTRLS)]    = "VIDIOC_TRY_EXT_CTRLS",
++#if 1
++	[_IOC_NR(VIDIOC_ENUM_FRAMESIZES)]  = "VIDIOC_ENUM_FRAMESIZES",
++	[_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
++	[_IOC_NR(VIDIOC_G_ENC_INDEX)] 	   = "VIDIOC_G_ENC_INDEX",
++	[_IOC_NR(VIDIOC_ENCODER_CMD)] 	   = "VIDIOC_ENCODER_CMD",
++	[_IOC_NR(VIDIOC_TRY_ENCODER_CMD)]  = "VIDIOC_TRY_ENCODER_CMD",
++
++	[_IOC_NR(VIDIOC_DBG_S_REGISTER)]   = "VIDIOC_DBG_S_REGISTER",
++	[_IOC_NR(VIDIOC_DBG_G_REGISTER)]   = "VIDIOC_DBG_G_REGISTER",
++
++	[_IOC_NR(VIDIOC_G_CHIP_IDENT)]     = "VIDIOC_G_CHIP_IDENT",
++#endif
++};
++#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
++
++static const char *v4l2_int_ioctls[] = {
++#ifdef CONFIG_VIDEO_V4L1_COMPAT
++	[_IOC_NR(DECODER_GET_CAPABILITIES)]    = "DECODER_GET_CAPABILITIES",
++	[_IOC_NR(DECODER_GET_STATUS)]          = "DECODER_GET_STATUS",
++	[_IOC_NR(DECODER_SET_NORM)]            = "DECODER_SET_NORM",
++	[_IOC_NR(DECODER_SET_INPUT)]           = "DECODER_SET_INPUT",
++	[_IOC_NR(DECODER_SET_OUTPUT)]          = "DECODER_SET_OUTPUT",
++	[_IOC_NR(DECODER_ENABLE_OUTPUT)]       = "DECODER_ENABLE_OUTPUT",
++	[_IOC_NR(DECODER_SET_PICTURE)]         = "DECODER_SET_PICTURE",
++	[_IOC_NR(DECODER_SET_GPIO)]            = "DECODER_SET_GPIO",
++	[_IOC_NR(DECODER_INIT)]                = "DECODER_INIT",
++	[_IOC_NR(DECODER_SET_VBI_BYPASS)]      = "DECODER_SET_VBI_BYPASS",
++	[_IOC_NR(DECODER_DUMP)]                = "DECODER_DUMP",
++#endif
++	[_IOC_NR(AUDC_SET_RADIO)]              = "AUDC_SET_RADIO",
++
++	[_IOC_NR(TUNER_SET_TYPE_ADDR)]         = "TUNER_SET_TYPE_ADDR",
++	[_IOC_NR(TUNER_SET_STANDBY)]           = "TUNER_SET_STANDBY",
++	[_IOC_NR(TUNER_SET_CONFIG)]            = "TUNER_SET_CONFIG",
++
++	[_IOC_NR(VIDIOC_INT_S_TUNER_MODE)]     = "VIDIOC_INT_S_TUNER_MODE",
++	[_IOC_NR(VIDIOC_INT_RESET)]            = "VIDIOC_INT_RESET",
++	[_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
++	[_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)]  = "VIDIOC_INT_DECODE_VBI_LINE",
++	[_IOC_NR(VIDIOC_INT_S_VBI_DATA)]       = "VIDIOC_INT_S_VBI_DATA",
++	[_IOC_NR(VIDIOC_INT_G_VBI_DATA)]       = "VIDIOC_INT_G_VBI_DATA",
++	[_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)]   = "VIDIOC_INT_I2S_CLOCK_FREQ",
++	[_IOC_NR(VIDIOC_INT_S_STANDBY)]        = "VIDIOC_INT_S_STANDBY",
++	[_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)]  = "VIDIOC_INT_S_AUDIO_ROUTING",
++	[_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)]  = "VIDIOC_INT_G_AUDIO_ROUTING",
++	[_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)]  = "VIDIOC_INT_S_VIDEO_ROUTING",
++	[_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)]  = "VIDIOC_INT_G_VIDEO_ROUTING",
++	[_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)]   = "VIDIOC_INT_S_CRYSTAL_FREQ",
++	[_IOC_NR(VIDIOC_INT_INIT)]   	       = "VIDIOC_INT_INIT",
++	[_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)]     = "VIDIOC_INT_G_STD_OUTPUT",
++	[_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)]     = "VIDIOC_INT_S_STD_OUTPUT",
++};
++#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
++
++/* Common ioctl debug function. This function can be used by
++   external ioctl messages as well as internal V4L ioctl */
++void v4l_printk_ioctl(unsigned int cmd)
++{
++	char *dir;
++
++	switch (_IOC_DIR(cmd)) {
++	case _IOC_NONE:              dir = "--"; break;
++	case _IOC_READ:              dir = "r-"; break;
++	case _IOC_WRITE:             dir = "-w"; break;
++	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
++	default:                     dir = "*ERR*"; break;
++	}
++	switch (_IOC_TYPE(cmd)) {
++	case 'd':
++		printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n",
++		       (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ?
++		       v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
++		break;
++#ifdef CONFIG_VIDEO_V4L1_COMPAT
++	case 'v':
++		printk("v4l1 ioctl %s, dir=%s (0x%08x)\n",
++		       (_IOC_NR(cmd) < V4L1_IOCTLS) ?
++		       v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
++		break;
++#endif
++	case 'V':
++		printk("v4l2 ioctl %s, dir=%s (0x%08x)\n",
++		       (_IOC_NR(cmd) < V4L2_IOCTLS) ?
++		       v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
++		break;
++
++	default:
++		printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n",
++		       _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
++	}
++}
++EXPORT_SYMBOL(v4l_printk_ioctl);
++
+ /*
+  *	sysfs stuff
+  */
+@@ -69,11 +432,13 @@ struct video_device *video_device_alloc(void)
+ 	vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
+ 	return vfd;
+ }
++EXPORT_SYMBOL(video_device_alloc);
+ 
+ void video_device_release(struct video_device *vfd)
+ {
+ 	kfree(vfd);
+ }
++EXPORT_SYMBOL(video_device_release);
+ 
+ static void video_release(struct device *cd)
+ {
+@@ -110,6 +475,7 @@ struct video_device* video_devdata(struct file *file)
+ {
+ 	return video_device[iminor(file->f_path.dentry->d_inode)];
+ }
++EXPORT_SYMBOL(video_devdata);
+ 
+ /*
+  *	Open a video device - FIXME: Obsoleted
+@@ -278,6 +644,7 @@ out:
+ 	kfree(mbuf);
+ 	return err;
+ }
++EXPORT_SYMBOL(video_usercopy);
+ 
+ /*
+  * open/release helper functions -- handle exclusive opens
+@@ -297,6 +664,7 @@ int video_exclusive_open(struct inode *inode, struct file *file)
+ 	mutex_unlock(&vfl->lock);
+ 	return retval;
+ }
++EXPORT_SYMBOL(video_exclusive_open);
+ 
+ int video_exclusive_release(struct inode *inode, struct file *file)
+ {
+@@ -305,41 +673,7 @@ int video_exclusive_release(struct inode *inode, struct file *file)
+ 	vfl->users--;
+ 	return 0;
+ }
+-
+-static char *v4l2_memory_names[] = {
+-	[V4L2_MEMORY_MMAP]    = "mmap",
+-	[V4L2_MEMORY_USERPTR] = "userptr",
+-	[V4L2_MEMORY_OVERLAY] = "overlay",
+-};
+-
+-
+-/* FIXME: Those stuff are replicated also on v4l2-common.c */
+-static char *v4l2_type_names_FIXME[] = {
+-	[V4L2_BUF_TYPE_VIDEO_CAPTURE]      = "video-cap",
+-	[V4L2_BUF_TYPE_VIDEO_OVERLAY]      = "video-over",
+-	[V4L2_BUF_TYPE_VIDEO_OUTPUT]       = "video-out",
+-	[V4L2_BUF_TYPE_VBI_CAPTURE]        = "vbi-cap",
+-	[V4L2_BUF_TYPE_VBI_OUTPUT]         = "vbi-out",
+-	[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT]  = "sliced-vbi-out",
+-	[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture",
+-	[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
+-	[V4L2_BUF_TYPE_PRIVATE]            = "private",
+-};
+-
+-static char *v4l2_field_names_FIXME[] = {
+-	[V4L2_FIELD_ANY]        = "any",
+-	[V4L2_FIELD_NONE]       = "none",
+-	[V4L2_FIELD_TOP]        = "top",
+-	[V4L2_FIELD_BOTTOM]     = "bottom",
+-	[V4L2_FIELD_INTERLACED] = "interlaced",
+-	[V4L2_FIELD_SEQ_TB]     = "seq-tb",
+-	[V4L2_FIELD_SEQ_BT]     = "seq-bt",
+-	[V4L2_FIELD_ALTERNATE]  = "alternate",
+-	[V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
+-	[V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
+-};
+-
+-#define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
++EXPORT_SYMBOL(video_exclusive_release);
+ 
+ static void dbgbuf(unsigned int cmd, struct video_device *vfd,
+ 					struct v4l2_buffer *p)
+@@ -354,10 +688,10 @@ static void dbgbuf(unsigned int cmd, struct video_device *vfd,
+ 			(int)(p->timestamp.tv_sec%60),
+ 			p->timestamp.tv_usec,
+ 			p->index,
+-			prt_names(p->type,v4l2_type_names_FIXME),
+-			p->bytesused,p->flags,
+-			p->field,p->sequence,
+-			prt_names(p->memory,v4l2_memory_names),
++			prt_names(p->type, v4l2_type_names),
++			p->bytesused, p->flags,
++			p->field, p->sequence,
++			prt_names(p->memory, v4l2_memory_names),
+ 			p->m.userptr, p->length);
+ 	dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
+ 		"flags=0x%08d, frames=%d, userbits=0x%08x\n",
+@@ -382,8 +716,8 @@ static inline void v4l_print_pix_fmt (struct video_device *vfd,
+ 		(fmt->pixelformat >>  8) & 0xff,
+ 		(fmt->pixelformat >> 16) & 0xff,
+ 		(fmt->pixelformat >> 24) & 0xff,
+-		prt_names(fmt->field,v4l2_field_names_FIXME),
+-		fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
++		prt_names(fmt->field, v4l2_field_names),
++		fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
+ };
+ 
+ 
+@@ -597,7 +931,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
+ 
+ 		/* FIXME: Should be one dump per type */
+ 		dbgarg (cmd, "type=%s\n", prt_names(type,
+-					v4l2_type_names_FIXME));
++					v4l2_type_names));
+ 
+ 		switch (type) {
+ 		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+@@ -650,7 +984,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
+ 
+ 		/* FIXME: Should be one dump per type */
+ 		dbgarg (cmd, "type=%s\n", prt_names(f->type,
+-					v4l2_type_names_FIXME));
++					v4l2_type_names));
+ 
+ 		switch (f->type) {
+ 		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+@@ -702,7 +1036,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
+ 
+ 		/* FIXME: Should be one dump per type */
+ 		dbgarg (cmd, "type=%s\n", prt_names(f->type,
+-						v4l2_type_names_FIXME));
++						v4l2_type_names));
+ 		switch (f->type) {
+ 		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ 			if (vfd->vidioc_try_fmt_cap)
+@@ -768,8 +1102,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
+ 		ret=vfd->vidioc_reqbufs(file, fh, p);
+ 		dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
+ 				p->count,
+-				prt_names(p->type,v4l2_type_names_FIXME),
+-				prt_names(p->memory,v4l2_memory_names));
++				prt_names(p->type, v4l2_type_names),
++				prt_names(p->memory, v4l2_memory_names));
+ 		break;
+ 	}
+ 	case VIDIOC_QUERYBUF:
+@@ -858,7 +1192,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
+ 		enum v4l2_buf_type i = *(int *)arg;
+ 		if (!vfd->vidioc_streamon)
+ 			break;
+-		dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
++		dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
+ 		ret=vfd->vidioc_streamon(file, fh,i);
+ 		break;
+ 	}
+@@ -868,7 +1202,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
+ 
+ 		if (!vfd->vidioc_streamoff)
+ 			break;
+-		dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
++		dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
+ 		ret=vfd->vidioc_streamoff(file, fh, i);
+ 		break;
+ 	}
+@@ -1624,7 +1958,7 @@ out:
+ 	kfree(mbuf);
+ 	return err;
+ }
+-
++EXPORT_SYMBOL(video_ioctl2);
+ 
+ static const struct file_operations video_fops;
+ 
+@@ -1743,6 +2077,7 @@ fail_minor:
+ 	mutex_unlock(&videodev_lock);
+ 	return ret;
+ }
++EXPORT_SYMBOL(video_register_device);
+ 
+ /**
+  *	video_unregister_device - unregister a video4linux device
+@@ -1762,6 +2097,7 @@ void video_unregister_device(struct video_device *vfd)
+ 	device_unregister(&vfd->class_dev);
+ 	mutex_unlock(&videodev_lock);
+ }
++EXPORT_SYMBOL(video_unregister_device);
+ 
+ /*
+  * Video fs operations
+@@ -1806,16 +2142,6 @@ static void __exit videodev_exit(void)
+ module_init(videodev_init)
+ module_exit(videodev_exit)
+ 
+-EXPORT_SYMBOL(video_register_device);
+-EXPORT_SYMBOL(video_unregister_device);
+-EXPORT_SYMBOL(video_devdata);
+-EXPORT_SYMBOL(video_usercopy);
+-EXPORT_SYMBOL(video_exclusive_open);
+-EXPORT_SYMBOL(video_exclusive_release);
+-EXPORT_SYMBOL(video_ioctl2);
+-EXPORT_SYMBOL(video_device_alloc);
+-EXPORT_SYMBOL(video_device_release);
+-
+ MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab at infradead.org>");
+ MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
+ MODULE_LICENSE("GPL");
+diff --git a/drivers/media/video/zoran.h b/drivers/media/video/zoran.h
+index 937c4a6..498a43c 100644
+--- a/drivers/media/video/zoran.h
++++ b/drivers/media/video/zoran.h
+@@ -221,15 +221,15 @@ enum zoran_map_mode {
+ };
+ 
+ enum gpio_type {
+-	GPIO_JPEG_SLEEP = 0,
+-	GPIO_JPEG_RESET,
+-	GPIO_JPEG_FRAME,
+-	GPIO_VID_DIR,
+-	GPIO_VID_EN,
+-	GPIO_VID_RESET,
+-	GPIO_CLK_SEL1,
+-	GPIO_CLK_SEL2,
+-	GPIO_MAX,
++	ZR_GPIO_JPEG_SLEEP = 0,
++	ZR_GPIO_JPEG_RESET,
++	ZR_GPIO_JPEG_FRAME,
++	ZR_GPIO_VID_DIR,
++	ZR_GPIO_VID_EN,
++	ZR_GPIO_VID_RESET,
++	ZR_GPIO_CLK_SEL1,
++	ZR_GPIO_CLK_SEL2,
++	ZR_GPIO_MAX,
+ };
+ 
+ enum gpcs_type {
+@@ -378,11 +378,11 @@ struct card_info {
+ 
+ 	u32 jpeg_int;		/* JPEG interrupt */
+ 	u32 vsync_int;		/* VSYNC interrupt */
+-	s8 gpio[GPIO_MAX];
++	s8 gpio[ZR_GPIO_MAX];
+ 	u8 gpcs[GPCS_MAX];
+ 
+ 	struct vfe_polarity vfe_pol;
+-	u8 gpio_pol[GPIO_MAX];
++	u8 gpio_pol[ZR_GPIO_MAX];
+ 
+ 	/* is the /GWS line conected? */
+ 	u8 gws_not_connected;
+diff --git a/drivers/media/video/zoran_device.c b/drivers/media/video/zoran_device.c
+index 68c7c50..f97c206 100644
+--- a/drivers/media/video/zoran_device.c
++++ b/drivers/media/video/zoran_device.c
+@@ -250,7 +250,7 @@ void
+ jpeg_codec_sleep (struct zoran *zr,
+ 		  int           sleep)
+ {
+-	GPIO(zr, zr->card.gpio[GPIO_JPEG_SLEEP], !sleep);
++	GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_SLEEP], !sleep);
+ 	if (!sleep) {
+ 		dprintk(3,
+ 			KERN_DEBUG
+@@ -277,9 +277,9 @@ jpeg_codec_reset (struct zoran *zr)
+ 				  0);
+ 		udelay(2);
+ 	} else {
+-		GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 0);
++		GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 0);
+ 		udelay(2);
+-		GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 1);
++		GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 1);
+ 		udelay(2);
+ 	}
+ 
+@@ -688,7 +688,7 @@ static inline void
+ set_frame (struct zoran *zr,
+ 	   int           val)
+ {
+-	GPIO(zr, zr->card.gpio[GPIO_JPEG_FRAME], val);
++	GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_FRAME], val);
+ }
+ 
+ static void
+@@ -704,8 +704,8 @@ set_videobus_dir (struct zoran *zr,
+ 			GPIO(zr, 5, 1);
+ 		break;
+ 	default:
+-		GPIO(zr, zr->card.gpio[GPIO_VID_DIR],
+-		     zr->card.gpio_pol[GPIO_VID_DIR] ? !val : val);
++		GPIO(zr, zr->card.gpio[ZR_GPIO_VID_DIR],
++		     zr->card.gpio_pol[ZR_GPIO_VID_DIR] ? !val : val);
+ 		break;
+ 	}
+ }
+diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
+index 1fdbb46..1b44784 100644
+--- a/drivers/media/video/zr364xx.c
++++ b/drivers/media/video/zr364xx.c
+@@ -93,6 +93,8 @@ static struct usb_device_id device_table[] = {
+ 	{USB_DEVICE(0x06d6, 0x0034), .driver_info = METHOD0 },
+ 	{USB_DEVICE(0x0a17, 0x0062), .driver_info = METHOD2 },
+ 	{USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 },
++	{USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 },
++	{USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 },
+ 	{}			/* Terminating entry */
+ };
+ 
+diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
+index d876787..85e66f4 100644
+--- a/drivers/net/e1000/e1000_ethtool.c
++++ b/drivers/net/e1000/e1000_ethtool.c
+@@ -50,7 +50,7 @@ struct e1000_stats {
+ 	int stat_offset;
+ };
+ 
+-#define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \
++#define E1000_STAT(m) FIELD_SIZEOF(struct e1000_adapter, m), \
+ 		      offsetof(struct e1000_adapter, m)
+ static const struct e1000_stats e1000_gstrings_stats[] = {
+ 	{ "rx_packets", E1000_STAT(stats.gprc) },
+diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
+index d4ee8ec..0991648 100644
+--- a/drivers/net/e1000/e1000_main.c
++++ b/drivers/net/e1000/e1000_main.c
+@@ -1195,6 +1195,14 @@ e1000_probe(struct pci_dev *pdev,
+ 
+ 	printk("%s\n", print_mac(mac, netdev->dev_addr));
+ 
++	if (adapter->hw.bus_type == e1000_bus_type_pci_express) {
++		DPRINTK(PROBE, WARNING, "This device (id %04x:%04x) will no "
++			"longer be supported by this driver in the future.\n",
++			pdev->vendor, pdev->device);
++		DPRINTK(PROBE, WARNING, "please use the \"e1000e\" "
++			"driver instead.\n");
++	}
++
+ 	/* reset the hardware with the new settings */
+ 	e1000_reset(adapter);
+ 
+diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
+index f58f017..3031d6d 100644
+--- a/drivers/net/e1000e/netdev.c
++++ b/drivers/net/e1000e/netdev.c
+@@ -1055,23 +1055,6 @@ static void e1000_release_hw_control(struct e1000_adapter *adapter)
+ 	}
+ }
+ 
+-static void e1000_release_manageability(struct e1000_adapter *adapter)
+-{
+-	if (adapter->flags & FLAG_MNG_PT_ENABLED) {
+-		struct e1000_hw *hw = &adapter->hw;
+-
+-		u32 manc = er32(MANC);
+-
+-		/* re-enable hardware interception of ARP */
+-		manc |= E1000_MANC_ARP_EN;
+-		manc &= ~E1000_MANC_EN_MNG2HOST;
+-
+-		/* don't explicitly have to mess with MANC2H since
+-		 * MANC has an enable disable that gates MANC2H */
+-		ew32(MANC, manc);
+-	}
+-}
+-
+ /**
+  * @e1000_alloc_ring - allocate memory for a ring structure
+  **/
+@@ -1561,9 +1544,6 @@ static void e1000_init_manageability(struct e1000_adapter *adapter)
+ 
+ 	manc = er32(MANC);
+ 
+-	/* disable hardware interception of ARP */
+-	manc &= ~(E1000_MANC_ARP_EN);
+-
+ 	/* enable receiving management packets to the host. this will probably
+ 	 * generate destination unreachable messages from the host OS, but
+ 	 * the packets will be handled on SMBUS */
+@@ -1690,6 +1670,9 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
+ 	else
+ 		rctl |= E1000_RCTL_LPE;
+ 
++	/* Enable hardware CRC frame stripping */
++	rctl |= E1000_RCTL_SECRC;
++
+ 	/* Setup buffer sizes */
+ 	rctl &= ~E1000_RCTL_SZ_4096;
+ 	rctl |= E1000_RCTL_BSEX;
+@@ -1755,9 +1738,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
+ 
+ 		/* Enable Packet split descriptors */
+ 		rctl |= E1000_RCTL_DTYP_PS;
+-		
+-		/* Enable hardware CRC frame stripping */
+-		rctl |= E1000_RCTL_SECRC;
+ 
+ 		psrctl |= adapter->rx_ps_bsize0 >>
+ 			E1000_PSRCTL_BSIZE0_SHIFT;
+@@ -2008,7 +1988,7 @@ static void e1000_power_down_phy(struct e1000_adapter *adapter)
+ 	u16 mii_reg;
+ 
+ 	/* WoL is enabled */
+-	if (!adapter->wol)
++	if (adapter->wol)
+ 		return;
+ 
+ 	/* non-copper PHY? */
+@@ -2140,8 +2120,6 @@ void e1000e_reset(struct e1000_adapter *adapter)
+ 		phy_data &= ~IGP02E1000_PM_SPD;
+ 		e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
+ 	}
+-
+-	e1000_release_manageability(adapter);
+ }
+ 
+ int e1000e_up(struct e1000_adapter *adapter)
+@@ -3487,8 +3465,6 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
+ 		pci_enable_wake(pdev, PCI_D3cold, 0);
+ 	}
+ 
+-	e1000_release_manageability(adapter);
+-
+ 	/* make sure adapter isn't asleep if manageability is enabled */
+ 	if (adapter->flags & FLAG_MNG_PT_ENABLED) {
+ 		pci_enable_wake(pdev, PCI_D3hot, 1);
+@@ -4054,8 +4030,6 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
+ 
+ 	flush_scheduled_work();
+ 
+-	e1000_release_manageability(adapter);
+-
+ 	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
+ 	 * would have already happened in close and is redundant. */
+ 	e1000_release_hw_control(adapter);
+diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
+index 0431e9e..4244fc2 100644
+--- a/drivers/net/gianfar.c
++++ b/drivers/net/gianfar.c
+@@ -130,8 +130,8 @@ static void free_skb_resources(struct gfar_private *priv);
+ static void gfar_set_multi(struct net_device *dev);
+ static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
+ static void gfar_configure_serdes(struct net_device *dev);
+-extern int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id, int regnum, u16 value);
+-extern int gfar_local_mdio_read(struct gfar_mii *regs, int mii_id, int regnum);
++extern int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id, int regnum, u16 value);
++extern int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum);
+ #ifdef CONFIG_GFAR_NAPI
+ static int gfar_poll(struct napi_struct *napi, int budget);
+ #endif
+diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
+index 6a647d9..2432762 100644
+--- a/drivers/net/gianfar_mii.c
++++ b/drivers/net/gianfar_mii.c
+@@ -51,7 +51,7 @@
+  * the local mdio pins, which may not be the same as system mdio bus, used for
+  * controlling the external PHYs, for example.
+  */
+-int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id,
++int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
+ 			  int regnum, u16 value)
+ {
+ 	/* Set the PHY address and the register address we want to write */
+@@ -77,7 +77,7 @@ int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id,
+  * and are always tied to the local mdio pins, which may not be the
+  * same as system mdio bus, used for controlling the external PHYs, for eg.
+  */
+-int gfar_local_mdio_read(struct gfar_mii *regs, int mii_id, int regnum)
++int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum)
+ 
+ {
+ 	u16 value;
+diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
+index cfcd15a..30c9b3b 100644
+--- a/drivers/net/hamradio/mkiss.c
++++ b/drivers/net/hamradio/mkiss.c
+@@ -289,7 +289,6 @@ static void ax_bump(struct mkiss *ax)
+ 			*ax->rbuff &= ~0x20;
+ 		}
+  	}
+-	spin_unlock_bh(&ax->buflock);
+ 
+ 	count = ax->rcount;
+ 
+@@ -297,17 +296,17 @@ static void ax_bump(struct mkiss *ax)
+ 		printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n",
+ 		       ax->dev->name);
+ 		ax->stats.rx_dropped++;
++		spin_unlock_bh(&ax->buflock);
+ 		return;
+ 	}
+ 
+-	spin_lock_bh(&ax->buflock);
+ 	memcpy(skb_put(skb,count), ax->rbuff, count);
+-	spin_unlock_bh(&ax->buflock);
+ 	skb->protocol = ax25_type_trans(skb, ax->dev);
+ 	netif_rx(skb);
+ 	ax->dev->last_rx = jiffies;
+ 	ax->stats.rx_packets++;
+ 	ax->stats.rx_bytes += count;
++	spin_unlock_bh(&ax->buflock);
+ }
+ 
+ static void kiss_unesc(struct mkiss *ax, unsigned char s)
+diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
+index f69721e..0447f9b 100644
+--- a/drivers/net/igb/igb_ethtool.c
++++ b/drivers/net/igb/igb_ethtool.c
+@@ -43,7 +43,7 @@ struct igb_stats {
+ 	int stat_offset;
+ };
+ 
+-#define IGB_STAT(m) sizeof(((struct igb_adapter *)0)->m), \
++#define IGB_STAT(m) FIELD_SIZEOF(struct igb_adapter, m), \
+ 		      offsetof(struct igb_adapter, m)
+ static const struct igb_stats igb_gstrings_stats[] = {
+ 	{ "rx_packets", IGB_STAT(stats.gprc) },
+diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
+index d4eb8e2..bff280e 100644
+--- a/drivers/net/igb/igb_main.c
++++ b/drivers/net/igb/igb_main.c
+@@ -606,9 +606,6 @@ static void igb_init_manageability(struct igb_adapter *adapter)
+ 		u32 manc2h = rd32(E1000_MANC2H);
+ 		u32 manc = rd32(E1000_MANC);
+ 
+-		/* disable hardware interception of ARP */
+-		manc &= ~(E1000_MANC_ARP_EN);
+-
+ 		/* enable receiving management packets to the host */
+ 		/* this will probably generate destination unreachable messages
+ 		 * from the host OS, but the packets will be handled on SMBUS */
+@@ -623,25 +620,6 @@ static void igb_init_manageability(struct igb_adapter *adapter)
+ 	}
+ }
+ 
+-static void igb_release_manageability(struct igb_adapter *adapter)
+-{
+-	struct e1000_hw *hw = &adapter->hw;
+-
+-	if (adapter->en_mng_pt) {
+-		u32 manc = rd32(E1000_MANC);
+-
+-		/* re-enable hardware interception of ARP */
+-		manc |= E1000_MANC_ARP_EN;
+-		manc &= ~E1000_MANC_EN_MNG2HOST;
+-
+-		/* don't explicitly have to mess with MANC2H since
+-		 * MANC has an enable disable that gates MANC2H */
+-
+-		/* XXX stop the hardware watchdog ? */
+-		wr32(E1000_MANC, manc);
+-	}
+-}
+-
+ /**
+  * igb_configure - configure the hardware for RX and TX
+  * @adapter: private board structure
+@@ -844,7 +822,6 @@ void igb_reset(struct igb_adapter *adapter)
+ 
+ 	igb_reset_adaptive(&adapter->hw);
+ 	adapter->hw.phy.ops.get_phy_info(&adapter->hw);
+-	igb_release_manageability(adapter);
+ }
+ 
+ /**
+@@ -1178,9 +1155,6 @@ static void __devexit igb_remove(struct pci_dev *pdev)
+ 
+ 	flush_scheduled_work();
+ 
+-
+-	igb_release_manageability(adapter);
+-
+ 	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
+ 	 * would have already happened in close and is redundant. */
+ 	igb_release_hw_control(adapter);
+@@ -3955,8 +3929,6 @@ static int igb_suspend(struct pci_dev *pdev, pm_message_t state)
+ 		pci_enable_wake(pdev, PCI_D3cold, 0);
+ 	}
+ 
+-	igb_release_manageability(adapter);
+-
+ 	/* make sure adapter isn't asleep if manageability is enabled */
+ 	if (adapter->en_mng_pt) {
+ 		pci_enable_wake(pdev, PCI_D3hot, 1);
+diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
+index a267dd8..53a9fd0 100644
+--- a/drivers/net/ixgb/ixgb_ethtool.c
++++ b/drivers/net/ixgb/ixgb_ethtool.c
+@@ -49,7 +49,7 @@ struct ixgb_stats {
+ 	int stat_offset;
+ };
+ 
+-#define IXGB_STAT(m) sizeof(((struct ixgb_adapter *)0)->m), \
++#define IXGB_STAT(m) FIELD_SIZEOF(struct ixgb_adapter, m), \
+ 		      offsetof(struct ixgb_adapter, m)
+ static struct ixgb_stats ixgb_gstrings_stats[] = {
+ 	{"rx_packets", IXGB_STAT(net_stats.rx_packets)},
+diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
+index ead49e5..23d0a4a 100644
+--- a/drivers/net/ixgbe/ixgbe_main.c
++++ b/drivers/net/ixgbe/ixgbe_main.c
+@@ -220,7 +220,6 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
+ 			tx_ring->stats.bytes += tx_buffer_info->length;
+ 			if (cleaned) {
+ 				struct sk_buff *skb = tx_buffer_info->skb;
+-#ifdef NETIF_F_TSO
+ 				unsigned int segs, bytecount;
+ 				segs = skb_shinfo(skb)->gso_segs ?: 1;
+ 				/* multiply data chunks by size of headers */
+@@ -228,10 +227,6 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
+ 					    skb->len;
+ 				total_tx_packets += segs;
+ 				total_tx_bytes += bytecount;
+-#else
+-				total_tx_packets++;
+-				total_tx_bytes += skb->len;
+-#endif
+ 			}
+ 			ixgbe_unmap_and_free_tx_resource(adapter,
+ 							 tx_buffer_info);
+@@ -1942,6 +1937,10 @@ static int ixgbe_open(struct net_device *netdev)
+ 	int err;
+ 	u32 num_rx_queues = adapter->num_rx_queues;
+ 
++	/* disallow open during test */
++	if (test_bit(__IXGBE_TESTING, &adapter->state))
++		return -EBUSY;
++
+ try_intr_reinit:
+ 	/* allocate transmit descriptors */
+ 	err = ixgbe_setup_all_tx_resources(adapter);
+@@ -2278,11 +2277,29 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
+ 				    IXGBE_ADVTXD_DTYP_CTXT);
+ 
+ 		if (skb->ip_summed == CHECKSUM_PARTIAL) {
+-			if (skb->protocol == htons(ETH_P_IP))
++			switch (skb->protocol) {
++			case __constant_htons(ETH_P_IP):
+ 				type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
++				if (ip_hdr(skb)->protocol == IPPROTO_TCP)
++					type_tucmd_mlhl |=
++						IXGBE_ADVTXD_TUCMD_L4T_TCP;
++				break;
++
++			case __constant_htons(ETH_P_IPV6):
++				/* XXX what about other V6 headers?? */
++				if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
++					type_tucmd_mlhl |=
++						IXGBE_ADVTXD_TUCMD_L4T_TCP;
++				break;
+ 
+-			if (skb->sk->sk_protocol == IPPROTO_TCP)
+-				type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP;
++			default:
++				if (unlikely(net_ratelimit())) {
++					DPRINTK(PROBE, WARNING,
++					 "partial checksum but proto=%x!\n",
++					 skb->protocol);
++				}
++				break;
++			}
+ 		}
+ 
+ 		context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl);
+@@ -2778,6 +2795,14 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
+ 		 hw->mac.type, hw->phy.type,
+ 		 (part_num >> 8), (part_num & 0xff));
+ 
++	if (link_width <= IXGBE_PCI_LINK_WIDTH_4) {
++		dev_warn(&pdev->dev, "PCI-Express bandwidth available for "
++			 "this card is not sufficient for optimal "
++			 "performance.\n");
++		dev_warn(&pdev->dev, "For optimal performance a x8 "
++			 "PCI-Express slot is required.\n");
++	}
++
+ 	/* reset the hardware with the new settings */
+ 	ixgbe_start_hw(hw);
+ 
+diff --git a/drivers/net/niu.c b/drivers/net/niu.c
+index 2fe14b0..e98ce1e 100644
+--- a/drivers/net/niu.c
++++ b/drivers/net/niu.c
+@@ -33,8 +33,8 @@
+ 
+ #define DRV_MODULE_NAME		"niu"
+ #define PFX DRV_MODULE_NAME	": "
+-#define DRV_MODULE_VERSION	"0.6"
+-#define DRV_MODULE_RELDATE	"January 5, 2008"
++#define DRV_MODULE_VERSION	"0.7"
++#define DRV_MODULE_RELDATE	"February 18, 2008"
+ 
+ static char version[] __devinitdata =
+ 	DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
+@@ -5147,7 +5147,12 @@ static void niu_set_rx_mode(struct net_device *dev)
+ 			index++;
+ 		}
+ 	} else {
+-		for (i = 0; i < niu_num_alt_addr(np); i++) {
++		int alt_start;
++		if (np->flags & NIU_FLAGS_XMAC)
++			alt_start = 0;
++		else
++			alt_start = 1;
++		for (i = alt_start; i < niu_num_alt_addr(np); i++) {
+ 			err = niu_enable_alt_mac(np, i, 0);
+ 			if (err)
+ 				printk(KERN_WARNING PFX "%s: Error %d "
+diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
+index f18eca9..250eb19 100644
+--- a/drivers/net/pcmcia/smc91c92_cs.c
++++ b/drivers/net/pcmcia/smc91c92_cs.c
+@@ -559,8 +559,16 @@ static int mhz_setup(struct pcmcia_device *link)
+ 
+     /* Read the station address from the CIS.  It is stored as the last
+        (fourth) string in the Version 1 Version/ID tuple. */
+-    if (link->prod_id[3]) {
+-	station_addr = link->prod_id[3];
++    tuple->DesiredTuple = CISTPL_VERS_1;
++    if (first_tuple(link, tuple, parse) != CS_SUCCESS) {
++	rc = -1;
++	goto free_cfg_mem;
++    }
++    /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
++    if (next_tuple(link, tuple, parse) != CS_SUCCESS)
++	first_tuple(link, tuple, parse);
++    if (parse->version_1.ns > 3) {
++	station_addr = parse->version_1.str + parse->version_1.ofs[3];
+ 	if (cvt_ascii_address(dev, station_addr) == 0) {
+ 		rc = 0;
+ 		goto free_cfg_mem;
+diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
+index 35d15e8..6f33f84 100644
+--- a/drivers/net/tsi108_eth.c
++++ b/drivers/net/tsi108_eth.c
+@@ -36,6 +36,7 @@
+ #include <linux/net.h>
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
++#include <linux/ethtool.h>
+ #include <linux/skbuff.h>
+ #include <linux/slab.h>
+ #include <linux/spinlock.h>
+@@ -297,18 +298,11 @@ static void tsi108_check_phy(struct net_device *dev)
+ 	u32 speed;
+ 	unsigned long flags;
+ 
+-	/* Do a dummy read, as for some reason the first read
+-	 * after a link becomes up returns link down, even if
+-	 * it's been a while since the link came up.
+-	 */
+-
+ 	spin_lock_irqsave(&phy_lock, flags);
+ 
+ 	if (!data->phy_ok)
+ 		goto out;
+ 
+-	tsi108_read_mii(data, MII_BMSR);
+-
+ 	duplex = mii_check_media(&data->mii_if, netif_msg_link(data), data->init_media);
+ 	data->init_media = 0;
+ 
+@@ -345,22 +339,21 @@ static void tsi108_check_phy(struct net_device *dev)
+ 
+ 			TSI_WRITE(TSI108_MAC_CFG2, mac_cfg2_reg);
+ 			TSI_WRITE(TSI108_EC_PORTCTRL, portctrl_reg);
++		}
+ 
+-			if (data->link_up == 0) {
+-				/* The manual says it can take 3-4 usecs for the speed change
+-				 * to take effect.
+-				 */
+-				udelay(5);
++		if (data->link_up == 0) {
++			/* The manual says it can take 3-4 usecs for the speed change
++			 * to take effect.
++			 */
++			udelay(5);
+ 
+-				spin_lock(&data->txlock);
+-				if (is_valid_ether_addr(dev->dev_addr) && data->txfree)
+-					netif_wake_queue(dev);
++			spin_lock(&data->txlock);
++			if (is_valid_ether_addr(dev->dev_addr) && data->txfree)
++				netif_wake_queue(dev);
+ 
+-				data->link_up = 1;
+-				spin_unlock(&data->txlock);
+-			}
++			data->link_up = 1;
++			spin_unlock(&data->txlock);
+ 		}
+-
+ 	} else {
+ 		if (data->link_up == 1) {
+ 			netif_stop_queue(dev);
+@@ -1274,12 +1267,11 @@ static void tsi108_init_phy(struct net_device *dev)
+ 	 * PHY_STAT register before the link up status bit is set.
+ 	 */
+ 
+-	data->link_up = 1;
++	data->link_up = 0;
+ 
+ 	while (!((phyval = tsi108_read_mii(data, MII_BMSR)) &
+ 		 BMSR_LSTATUS)) {
+ 		if (i++ > (MII_READ_DELAY / 10)) {
+-			data->link_up = 0;
+ 			break;
+ 		}
+ 		spin_unlock_irqrestore(&phy_lock, flags);
+@@ -1287,6 +1279,7 @@ static void tsi108_init_phy(struct net_device *dev)
+ 		spin_lock_irqsave(&phy_lock, flags);
+ 	}
+ 
++	data->mii_if.supports_gmii = mii_check_gmii_support(&data->mii_if);
+ 	printk(KERN_DEBUG "PHY_STAT reg contains %08x\n", phyval);
+ 	data->phy_ok = 1;
+ 	data->init_media = 1;
+@@ -1527,12 +1520,46 @@ static void tsi108_init_mac(struct net_device *dev)
+ 	TSI_WRITE(TSI108_EC_INTMASK, ~0);
+ }
+ 
++static int tsi108_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++	struct tsi108_prv_data *data = netdev_priv(dev);
++	unsigned long flags;
++	int rc;
++	
++	spin_lock_irqsave(&data->txlock, flags);
++	rc = mii_ethtool_gset(&data->mii_if, cmd);
++	spin_unlock_irqrestore(&data->txlock, flags);
++
++	return rc;
++}
++
++static int tsi108_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++	struct tsi108_prv_data *data = netdev_priv(dev);
++	unsigned long flags;
++	int rc;
++
++	spin_lock_irqsave(&data->txlock, flags);
++	rc = mii_ethtool_sset(&data->mii_if, cmd);
++	spin_unlock_irqrestore(&data->txlock, flags);
++	
++	return rc;
++}
++
+ static int tsi108_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+ {
+ 	struct tsi108_prv_data *data = netdev_priv(dev);
++	if (!netif_running(dev))
++		return -EINVAL;
+ 	return generic_mii_ioctl(&data->mii_if, if_mii(rq), cmd, NULL);
+ }
+ 
++static const struct ethtool_ops tsi108_ethtool_ops = {
++	.get_link 	= ethtool_op_get_link,
++	.get_settings	= tsi108_get_settings,
++	.set_settings	= tsi108_set_settings,
++};
++
+ static int
+ tsi108_init_one(struct platform_device *pdev)
+ {
+@@ -1584,7 +1611,6 @@ tsi108_init_one(struct platform_device *pdev)
+ 	data->mii_if.phy_id = einfo->phy;
+ 	data->mii_if.phy_id_mask = 0x1f;
+ 	data->mii_if.reg_num_mask = 0x1f;
+-	data->mii_if.supports_gmii = mii_check_gmii_support(&data->mii_if);
+ 
+ 	data->phy = einfo->phy;
+ 	data->phy_type = einfo->phy_type;
+@@ -1598,6 +1624,7 @@ tsi108_init_one(struct platform_device *pdev)
+ 	dev->get_stats = tsi108_get_stats;
+ 	netif_napi_add(dev, &data->napi, tsi108_poll, 64);
+ 	dev->do_ioctl = tsi108_do_ioctl;
++	dev->ethtool_ops = &tsi108_ethtool_ops;
+ 
+ 	/* Apparently, the Linux networking code won't use scatter-gather
+ 	 * if the hardware doesn't do checksums.  However, it's faster
+@@ -1629,6 +1656,7 @@ tsi108_init_one(struct platform_device *pdev)
+ 		goto register_fail;
+ 	}
+ 
++	platform_set_drvdata(pdev, dev);
+ 	printk(KERN_INFO "%s: Tsi108 Gigabit Ethernet, MAC: %s\n",
+ 	       dev->name, print_mac(mac, dev->dev_addr));
+ #ifdef DEBUG
+diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
+index ddc8714..dfdaec0 100644
+--- a/drivers/net/wireless/ath5k/base.c
++++ b/drivers/net/wireless/ath5k/base.c
+@@ -1256,7 +1256,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
+ 	if (ctl->flags & IEEE80211_TXCTL_NO_ACK)
+ 		flags |= AR5K_TXDESC_NOACK;
+ 
+-	pktlen = skb->len + FCS_LEN;
++	pktlen = skb->len;
+ 
+ 	if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) {
+ 		keyidx = ctl->key_idx;
+@@ -1952,7 +1952,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
+ 	}
+ 
+ 	ds->ds_data = bf->skbaddr;
+-	ret = ah->ah_setup_tx_desc(ah, ds, skb->len + FCS_LEN,
++	ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
+ 			ieee80211_get_hdrlen_from_skb(skb),
+ 			AR5K_PKT_TYPE_BEACON, (ctl->power_level * 2), ctl->tx_rate, 1,
+ 			AR5K_TXKEYIX_INVALID, antenna, flags, 0, 0);
+diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
+index 3a4bf40..1ab57aa 100644
+--- a/drivers/net/wireless/ath5k/hw.c
++++ b/drivers/net/wireless/ath5k/hw.c
+@@ -3506,7 +3506,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
+ {
+ 	u32 frame_type;
+ 	struct ath5k_hw_2w_tx_desc *tx_desc;
+-	unsigned int buff_len;
++	unsigned int frame_len;
+ 
+ 	tx_desc = (struct ath5k_hw_2w_tx_desc *)&desc->ds_ctl0;
+ 
+@@ -3537,22 +3537,25 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
+ 	/* Setup control descriptor */
+ 
+ 	/* Verify and set frame length */
+-	if (pkt_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
++
++	/* remove padding we might have added before */
++	frame_len = pkt_len - (hdr_len & 3) + FCS_LEN;
++
++	if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
+ 		return -EINVAL;
+ 
+-	tx_desc->tx_control_0 = pkt_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
++	tx_desc->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
+ 
+ 	/* Verify and set buffer length */
+-	buff_len = pkt_len - FCS_LEN;
+ 
+ 	/* NB: beacon's BufLen must be a multiple of 4 bytes */
+ 	if(type == AR5K_PKT_TYPE_BEACON)
+-		buff_len = roundup(buff_len, 4);
++		pkt_len = roundup(pkt_len, 4);
+ 
+-	if (buff_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
++	if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
+ 		return -EINVAL;
+ 
+-	tx_desc->tx_control_1 = buff_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
++	tx_desc->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
+ 
+ 	/*
+ 	 * Verify and set header length
+@@ -3634,7 +3637,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
+ {
+ 	struct ath5k_hw_4w_tx_desc *tx_desc;
+ 	struct ath5k_hw_tx_status *tx_status;
+-	unsigned int buff_len;
++	unsigned int frame_len;
+ 
+ 	ATH5K_TRACE(ah->ah_sc);
+ 	tx_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0;
+@@ -3669,22 +3672,25 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
+ 	/* Setup control descriptor */
+ 
+ 	/* Verify and set frame length */
+-	if (pkt_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
++
++	/* remove padding we might have added before */
++	frame_len = pkt_len - (hdr_len & 3) + FCS_LEN;
++
++	if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
+ 		return -EINVAL;
+ 
+-	tx_desc->tx_control_0 = pkt_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
++	tx_desc->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
+ 
+ 	/* Verify and set buffer length */
+-	buff_len = pkt_len - FCS_LEN;
+ 
+ 	/* NB: beacon's BufLen must be a multiple of 4 bytes */
+ 	if(type == AR5K_PKT_TYPE_BEACON)
+-		buff_len = roundup(buff_len, 4);
++		pkt_len = roundup(pkt_len, 4);
+ 
+-	if (buff_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
++	if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
+ 		return -EINVAL;
+ 
+-	tx_desc->tx_control_1 = buff_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
++	tx_desc->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
+ 
+ 	tx_desc->tx_control_0 |=
+ 		AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
+diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
+index 08a011f..f13346b 100644
+--- a/drivers/net/wireless/b43/b43.h
++++ b/drivers/net/wireless/b43/b43.h
+@@ -14,6 +14,12 @@
+ #include "lo.h"
+ #include "phy.h"
+ 
++
++/* The unique identifier of the firmware that's officially supported by
++ * this driver version. */
++#define B43_SUPPORTED_FIRMWARE_ID	"FW13"
++
++
+ #ifdef CONFIG_B43_DEBUG
+ # define B43_DEBUG	1
+ #else
+diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
+index ef65c41..51dfce1 100644
+--- a/drivers/net/wireless/b43/main.c
++++ b/drivers/net/wireless/b43/main.c
+@@ -58,6 +58,8 @@ MODULE_AUTHOR("Stefano Brivio");
+ MODULE_AUTHOR("Michael Buesch");
+ MODULE_LICENSE("GPL");
+ 
++MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID);
++
+ 
+ static int modparam_bad_frames_preempt;
+ module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
+@@ -1859,11 +1861,11 @@ static int b43_upload_microcode(struct b43_wldev *dev)
+ 		err = -EOPNOTSUPP;
+ 		goto error;
+ 	}
+-	b43dbg(dev->wl, "Loading firmware version %u.%u "
+-	       "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
+-	       fwrev, fwpatch,
+-	       (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF,
+-	       (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, fwtime & 0x1F);
++	b43info(dev->wl, "Loading firmware version %u.%u "
++		"(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
++		fwrev, fwpatch,
++		(fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF,
++		(fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, fwtime & 0x1F);
+ 
+ 	dev->fw.rev = fwrev;
+ 	dev->fw.patch = fwpatch;
+@@ -4200,6 +4202,33 @@ static struct ssb_driver b43_ssb_driver = {
+ 	.resume		= b43_resume,
+ };
+ 
++static void b43_print_driverinfo(void)
++{
++	const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "",
++		   *feat_leds = "", *feat_rfkill = "";
++
++#ifdef CONFIG_B43_PCI_AUTOSELECT
++	feat_pci = "P";
++#endif
++#ifdef CONFIG_B43_PCMCIA
++	feat_pcmcia = "M";
++#endif
++#ifdef CONFIG_B43_NPHY
++	feat_nphy = "N";
++#endif
++#ifdef CONFIG_B43_LEDS
++	feat_leds = "L";
++#endif
++#ifdef CONFIG_B43_RFKILL
++	feat_rfkill = "R";
++#endif
++	printk(KERN_INFO "Broadcom 43xx driver loaded "
++	       "[ Features: %s%s%s%s%s, Firmware-ID: "
++	       B43_SUPPORTED_FIRMWARE_ID " ]\n",
++	       feat_pci, feat_pcmcia, feat_nphy,
++	       feat_leds, feat_rfkill);
++}
++
+ static int __init b43_init(void)
+ {
+ 	int err;
+@@ -4211,6 +4240,7 @@ static int __init b43_init(void)
+ 	err = ssb_driver_register(&b43_ssb_driver);
+ 	if (err)
+ 		goto err_pcmcia_exit;
++	b43_print_driverinfo();
+ 
+ 	return err;
+ 
+diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h
+index c80edd2..93d45b7 100644
+--- a/drivers/net/wireless/b43legacy/b43legacy.h
++++ b/drivers/net/wireless/b43legacy/b43legacy.h
+@@ -23,6 +23,10 @@
+ #include "phy.h"
+ 
+ 
++/* The unique identifier of the firmware that's officially supported by this
++ * driver version. */
++#define B43legacy_SUPPORTED_FIRMWARE_ID	"FW10"
++
+ #define B43legacy_IRQWAIT_MAX_RETRIES	20
+ 
+ #define B43legacy_RX_MAX_SSI		60 /* best guess at max ssi */
+diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
+index 6e08405..e87b427 100644
+--- a/drivers/net/wireless/b43legacy/dma.c
++++ b/drivers/net/wireless/b43legacy/dma.c
+@@ -354,7 +354,8 @@ return 0;
+ }
+ 
+ 
+-u16 b43legacy_dmacontroller_base(int dma64bit, int controller_idx)
++static u16 b43legacy_dmacontroller_base(enum b43legacy_dmatype type,
++					int controller_idx)
+ {
+ 	static const u16 map64[] = {
+ 		B43legacy_MMIO_DMA64_BASE0,
+@@ -373,7 +374,7 @@ u16 b43legacy_dmacontroller_base(int dma64bit, int controller_idx)
+ 		B43legacy_MMIO_DMA32_BASE5,
+ 	};
+ 
+-	if (dma64bit) {
++	if (type == B43legacy_DMA_64BIT) {
+ 		B43legacy_WARN_ON(!(controller_idx >= 0 &&
+ 				  controller_idx < ARRAY_SIZE(map64)));
+ 		return map64[controller_idx];
+@@ -480,8 +481,9 @@ static void free_ringmemory(struct b43legacy_dmaring *ring)
+ }
+ 
+ /* Reset the RX DMA channel */
+-int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev,
+-				     u16 mmio_base, int dma64)
++static int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev,
++					    u16 mmio_base,
++					    enum b43legacy_dmatype type)
+ {
+ 	int i;
+ 	u32 value;
+@@ -489,13 +491,14 @@ int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev,
+ 
+ 	might_sleep();
+ 
+-	offset = dma64 ? B43legacy_DMA64_RXCTL : B43legacy_DMA32_RXCTL;
++	offset = (type == B43legacy_DMA_64BIT) ?
++		 B43legacy_DMA64_RXCTL : B43legacy_DMA32_RXCTL;
+ 	b43legacy_write32(dev, mmio_base + offset, 0);
+ 	for (i = 0; i < 10; i++) {
+-		offset = dma64 ? B43legacy_DMA64_RXSTATUS :
+-			 B43legacy_DMA32_RXSTATUS;
++		offset = (type == B43legacy_DMA_64BIT) ?
++			 B43legacy_DMA64_RXSTATUS : B43legacy_DMA32_RXSTATUS;
+ 		value = b43legacy_read32(dev, mmio_base + offset);
+-		if (dma64) {
++		if (type == B43legacy_DMA_64BIT) {
+ 			value &= B43legacy_DMA64_RXSTAT;
+ 			if (value == B43legacy_DMA64_RXSTAT_DISABLED) {
+ 				i = -1;
+@@ -519,8 +522,9 @@ int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev,
+ }
+ 
+ /* Reset the RX DMA channel */
+-int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev,
+-				     u16 mmio_base, int dma64)
++static int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev,
++					    u16 mmio_base,
++					    enum b43legacy_dmatype type)
+ {
+ 	int i;
+ 	u32 value;
+@@ -529,10 +533,10 @@ int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev,
+ 	might_sleep();
+ 
+ 	for (i = 0; i < 10; i++) {
+-		offset = dma64 ? B43legacy_DMA64_TXSTATUS :
+-			 B43legacy_DMA32_TXSTATUS;
++		offset = (type == B43legacy_DMA_64BIT) ?
++			 B43legacy_DMA64_TXSTATUS : B43legacy_DMA32_TXSTATUS;
+ 		value = b43legacy_read32(dev, mmio_base + offset);
+-		if (dma64) {
++		if (type == B43legacy_DMA_64BIT) {
+ 			value &= B43legacy_DMA64_TXSTAT;
+ 			if (value == B43legacy_DMA64_TXSTAT_DISABLED ||
+ 			    value == B43legacy_DMA64_TXSTAT_IDLEWAIT ||
+@@ -547,13 +551,14 @@ int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev,
+ 		}
+ 		msleep(1);
+ 	}
+-	offset = dma64 ? B43legacy_DMA64_TXCTL : B43legacy_DMA32_TXCTL;
++	offset = (type == B43legacy_DMA_64BIT) ? B43legacy_DMA64_TXCTL :
++						 B43legacy_DMA32_TXCTL;
+ 	b43legacy_write32(dev, mmio_base + offset, 0);
+ 	for (i = 0; i < 10; i++) {
+-		offset = dma64 ? B43legacy_DMA64_TXSTATUS :
+-			 B43legacy_DMA32_TXSTATUS;
++		offset = (type == B43legacy_DMA_64BIT) ?
++			 B43legacy_DMA64_TXSTATUS : B43legacy_DMA32_TXSTATUS;
+ 		value = b43legacy_read32(dev, mmio_base + offset);
+-		if (dma64) {
++		if (type == B43legacy_DMA_64BIT) {
+ 			value &= B43legacy_DMA64_TXSTAT;
+ 			if (value == B43legacy_DMA64_TXSTAT_DISABLED) {
+ 				i = -1;
+@@ -578,6 +583,32 @@ int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev,
+ 	return 0;
+ }
+ 
++/* Check if a DMA mapping address is invalid. */
++static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring,
++					dma_addr_t addr,
++					size_t buffersize)
++{
++	if (unlikely(dma_mapping_error(addr)))
++		return 1;
++
++	switch (ring->type) {
++	case B43legacy_DMA_30BIT:
++		if ((u64)addr + buffersize > (1ULL << 30))
++			return 1;
++		break;
++	case B43legacy_DMA_32BIT:
++		if ((u64)addr + buffersize > (1ULL << 32))
++			return 1;
++		break;
++	case B43legacy_DMA_64BIT:
++		/* Currently we can't have addresses beyond 64 bits in the kernel. */
++		break;
++	}
++
++	/* The address is OK. */
++	return 0;
++}
++
+ static int setup_rx_descbuffer(struct b43legacy_dmaring *ring,
+ 			       struct b43legacy_dmadesc_generic *desc,
+ 			       struct b43legacy_dmadesc_meta *meta,
+@@ -595,7 +626,7 @@ static int setup_rx_descbuffer(struct b43legacy_dmaring *ring,
+ 		return -ENOMEM;
+ 	dmaaddr = map_descbuffer(ring, skb->data,
+ 				 ring->rx_buffersize, 0);
+-	if (dma_mapping_error(dmaaddr)) {
++	if (b43legacy_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) {
+ 		/* ugh. try to realloc in zone_dma */
+ 		gfp_flags |= GFP_DMA;
+ 
+@@ -608,7 +639,7 @@ static int setup_rx_descbuffer(struct b43legacy_dmaring *ring,
+ 					 ring->rx_buffersize, 0);
+ 	}
+ 
+-	if (dma_mapping_error(dmaaddr)) {
++	if (b43legacy_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) {
+ 		dev_kfree_skb_any(skb);
+ 		return -EIO;
+ 	}
+@@ -674,7 +705,7 @@ static int dmacontroller_setup(struct b43legacy_dmaring *ring)
+ 	u32 trans = ssb_dma_translation(ring->dev->dev);
+ 
+ 	if (ring->tx) {
+-		if (ring->dma64) {
++		if (ring->type == B43legacy_DMA_64BIT) {
+ 			u64 ringbase = (u64)(ring->dmabase);
+ 
+ 			addrext = ((ringbase >> 32) & SSB_DMA_TRANSLATION_MASK)
+@@ -709,7 +740,7 @@ static int dmacontroller_setup(struct b43legacy_dmaring *ring)
+ 		err = alloc_initial_descbuffers(ring);
+ 		if (err)
+ 			goto out;
+-		if (ring->dma64) {
++		if (ring->type == B43legacy_DMA_64BIT) {
+ 			u64 ringbase = (u64)(ring->dmabase);
+ 
+ 			addrext = ((ringbase >> 32) & SSB_DMA_TRANSLATION_MASK)
+@@ -760,16 +791,16 @@ static void dmacontroller_cleanup(struct b43legacy_dmaring *ring)
+ {
+ 	if (ring->tx) {
+ 		b43legacy_dmacontroller_tx_reset(ring->dev, ring->mmio_base,
+-						 ring->dma64);
+-		if (ring->dma64) {
++						 ring->type);
++		if (ring->type == B43legacy_DMA_64BIT) {
+ 			b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGLO, 0);
+ 			b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGHI, 0);
+ 		} else
+ 			b43legacy_dma_write(ring, B43legacy_DMA32_TXRING, 0);
+ 	} else {
+ 		b43legacy_dmacontroller_rx_reset(ring->dev, ring->mmio_base,
+-						 ring->dma64);
+-		if (ring->dma64) {
++						 ring->type);
++		if (ring->type == B43legacy_DMA_64BIT) {
+ 			b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGLO, 0);
+ 			b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGHI, 0);
+ 		} else
+@@ -824,11 +855,10 @@ static u64 supported_dma_mask(struct b43legacy_wldev *dev)
+ 
+ /* Main initialization function. */
+ static
+-struct b43legacy_dmaring *b43legacy_setup_dmaring(
+-					struct b43legacy_wldev *dev,
+-					int controller_index,
+-					int for_tx,
+-					int dma64)
++struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
++						  int controller_index,
++						  int for_tx,
++						  enum b43legacy_dmatype type)
+ {
+ 	struct b43legacy_dmaring *ring;
+ 	int err;
+@@ -838,6 +868,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(
+ 	ring = kzalloc(sizeof(*ring), GFP_KERNEL);
+ 	if (!ring)
+ 		goto out;
++	ring->type = type;
+ 
+ 	nr_slots = B43legacy_RXRING_SLOTS;
+ 	if (for_tx)
+@@ -855,12 +886,12 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(
+ 			goto err_kfree_meta;
+ 
+ 		/* test for ability to dma to txhdr_cache */
+-		dma_test = dma_map_single(dev->dev->dev,
+-				ring->txhdr_cache,
+-				sizeof(struct b43legacy_txhdr_fw3),
+-				DMA_TO_DEVICE);
++		dma_test = dma_map_single(dev->dev->dev, ring->txhdr_cache,
++					  sizeof(struct b43legacy_txhdr_fw3),
++					  DMA_TO_DEVICE);
+ 
+-		if (dma_mapping_error(dma_test)) {
++		if (b43legacy_dma_mapping_error(ring, dma_test,
++					sizeof(struct b43legacy_txhdr_fw3))) {
+ 			/* ugh realloc */
+ 			kfree(ring->txhdr_cache);
+ 			ring->txhdr_cache = kcalloc(nr_slots,
+@@ -874,7 +905,8 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(
+ 					sizeof(struct b43legacy_txhdr_fw3),
+ 					DMA_TO_DEVICE);
+ 
+-			if (dma_mapping_error(dma_test))
++			if (b43legacy_dma_mapping_error(ring, dma_test,
++					sizeof(struct b43legacy_txhdr_fw3)))
+ 				goto err_kfree_txhdr_cache;
+ 		}
+ 
+@@ -885,11 +917,9 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(
+ 
+ 	ring->dev = dev;
+ 	ring->nr_slots = nr_slots;
+-	ring->mmio_base = b43legacy_dmacontroller_base(dma64,
+-						       controller_index);
++	ring->mmio_base = b43legacy_dmacontroller_base(type, controller_index);
+ 	ring->index = controller_index;
+-	ring->dma64 = !!dma64;
+-	if (dma64)
++	if (type == B43legacy_DMA_64BIT)
+ 		ring->ops = &dma64_ops;
+ 	else
+ 		ring->ops = &dma32_ops;
+@@ -939,10 +969,10 @@ static void b43legacy_destroy_dmaring(struct b43legacy_dmaring *ring)
+ 	if (!ring)
+ 		return;
+ 
+-	b43legacydbg(ring->dev->wl, "DMA-%s 0x%04X (%s) max used slots:"
+-		     " %d/%d\n", (ring->dma64) ? "64" : "32", ring->mmio_base,
+-		     (ring->tx) ? "TX" : "RX",
+-		     ring->max_used_slots, ring->nr_slots);
++	b43legacydbg(ring->dev->wl, "DMA-%u 0x%04X (%s) max used slots:"
++		     " %d/%d\n", (unsigned int)(ring->type), ring->mmio_base,
++		     (ring->tx) ? "TX" : "RX", ring->max_used_slots,
++		     ring->nr_slots);
+ 	/* Device IRQs are disabled prior entering this function,
+ 	 * so no need to take care of concurrency with rx handler stuff.
+ 	 */
+@@ -988,11 +1018,22 @@ int b43legacy_dma_init(struct b43legacy_wldev *dev)
+ 	struct b43legacy_dmaring *ring;
+ 	int err;
+ 	u64 dmamask;
+-	int dma64 = 0;
++	enum b43legacy_dmatype type;
+ 
+ 	dmamask = supported_dma_mask(dev);
+-	if (dmamask == DMA_64BIT_MASK)
+-		dma64 = 1;
++	switch (dmamask) {
++	default:
++		B43legacy_WARN_ON(1);
++	case DMA_30BIT_MASK:
++		type = B43legacy_DMA_30BIT;
++		break;
++	case DMA_32BIT_MASK:
++		type = B43legacy_DMA_32BIT;
++		break;
++	case DMA_64BIT_MASK:
++		type = B43legacy_DMA_64BIT;
++		break;
++	}
+ 
+ 	err = ssb_dma_set_mask(dev->dev, dmamask);
+ 	if (err) {
+@@ -1010,52 +1051,50 @@ int b43legacy_dma_init(struct b43legacy_wldev *dev)
+ 
+ 	err = -ENOMEM;
+ 	/* setup TX DMA channels. */
+-	ring = b43legacy_setup_dmaring(dev, 0, 1, dma64);
++	ring = b43legacy_setup_dmaring(dev, 0, 1, type);
+ 	if (!ring)
+ 		goto out;
+ 	dma->tx_ring0 = ring;
+ 
+-	ring = b43legacy_setup_dmaring(dev, 1, 1, dma64);
++	ring = b43legacy_setup_dmaring(dev, 1, 1, type);
+ 	if (!ring)
+ 		goto err_destroy_tx0;
+ 	dma->tx_ring1 = ring;
+ 
+-	ring = b43legacy_setup_dmaring(dev, 2, 1, dma64);
++	ring = b43legacy_setup_dmaring(dev, 2, 1, type);
+ 	if (!ring)
+ 		goto err_destroy_tx1;
+ 	dma->tx_ring2 = ring;
+ 
+-	ring = b43legacy_setup_dmaring(dev, 3, 1, dma64);
++	ring = b43legacy_setup_dmaring(dev, 3, 1, type);
+ 	if (!ring)
+ 		goto err_destroy_tx2;
+ 	dma->tx_ring3 = ring;
+ 
+-	ring = b43legacy_setup_dmaring(dev, 4, 1, dma64);
++	ring = b43legacy_setup_dmaring(dev, 4, 1, type);
+ 	if (!ring)
+ 		goto err_destroy_tx3;
+ 	dma->tx_ring4 = ring;
+ 
+-	ring = b43legacy_setup_dmaring(dev, 5, 1, dma64);
++	ring = b43legacy_setup_dmaring(dev, 5, 1, type);
+ 	if (!ring)
+ 		goto err_destroy_tx4;
+ 	dma->tx_ring5 = ring;
+ 
+ 	/* setup RX DMA channels. */
+-	ring = b43legacy_setup_dmaring(dev, 0, 0, dma64);
++	ring = b43legacy_setup_dmaring(dev, 0, 0, type);
+ 	if (!ring)
+ 		goto err_destroy_tx5;
+ 	dma->rx_ring0 = ring;
+ 
+ 	if (dev->dev->id.revision < 5) {
+-		ring = b43legacy_setup_dmaring(dev, 3, 0, dma64);
++		ring = b43legacy_setup_dmaring(dev, 3, 0, type);
+ 		if (!ring)
+ 			goto err_destroy_rx0;
+ 		dma->rx_ring3 = ring;
+ 	}
+ 
+-	b43legacydbg(dev->wl, "%d-bit DMA initialized\n",
+-	       (dmamask == DMA_64BIT_MASK) ? 64 :
+-	       (dmamask == DMA_32BIT_MASK) ? 32 : 30);
++	b43legacydbg(dev->wl, "%u-bit DMA initialized\n", (unsigned int)type);
+ 	err = 0;
+ out:
+ 	return err;
+@@ -1194,9 +1233,13 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
+ 	}
+ 
+ 	meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header,
+-				       sizeof(struct b43legacy_txhdr_fw3), 1);
+-	if (dma_mapping_error(meta_hdr->dmaaddr))
++					   sizeof(struct b43legacy_txhdr_fw3), 1);
++	if (b43legacy_dma_mapping_error(ring, meta_hdr->dmaaddr,
++					sizeof(struct b43legacy_txhdr_fw3))) {
++		ring->current_slot = old_top_slot;
++		ring->used_slots = old_used_slots;
+ 		return -EIO;
++	}
+ 	ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr,
+ 			     sizeof(struct b43legacy_txhdr_fw3), 1, 0, 0);
+ 
+@@ -1211,7 +1254,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
+ 
+ 	meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
+ 	/* create a bounce buffer in zone_dma on mapping failure. */
+-	if (dma_mapping_error(meta->dmaaddr)) {
++	if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len)) {
+ 		bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
+ 		if (!bounce_skb) {
+ 			ring->current_slot = old_top_slot;
+@@ -1225,7 +1268,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
+ 		skb = bounce_skb;
+ 		meta->skb = skb;
+ 		meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
+-		if (dma_mapping_error(meta->dmaaddr)) {
++		if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len)) {
+ 			ring->current_slot = old_top_slot;
+ 			ring->used_slots = old_used_slots;
+ 			err = -EIO;
+diff --git a/drivers/net/wireless/b43legacy/dma.h b/drivers/net/wireless/b43legacy/dma.h
+index 26f6ab0..2dd488c 100644
+--- a/drivers/net/wireless/b43legacy/dma.h
++++ b/drivers/net/wireless/b43legacy/dma.h
+@@ -218,6 +218,12 @@ struct b43legacy_dma_ops {
+ 	void (*set_current_rxslot)(struct b43legacy_dmaring *ring, int slot);
+ };
+ 
++enum b43legacy_dmatype {
++	B43legacy_DMA_30BIT = 30,
++	B43legacy_DMA_32BIT = 32,
++	B43legacy_DMA_64BIT = 64,
++};
++
+ struct b43legacy_dmaring {
+ 	/* Lowlevel DMA ops. */
+ 	const struct b43legacy_dma_ops *ops;
+@@ -250,8 +256,8 @@ struct b43legacy_dmaring {
+ 	int index;
+ 	/* Boolean. Is this a TX ring? */
+ 	bool tx;
+-	/* Boolean. 64bit DMA if true, 32bit DMA otherwise. */
+-	bool dma64;
++	/* The type of DMA engine used. */
++	enum b43legacy_dmatype type;
+ 	/* Boolean. Is this ring stopped at ieee80211 level? */
+ 	bool stopped;
+ 	/* Lock, only used for TX. */
+@@ -284,15 +290,6 @@ void b43legacy_dma_write(struct b43legacy_dmaring *ring,
+ int b43legacy_dma_init(struct b43legacy_wldev *dev);
+ void b43legacy_dma_free(struct b43legacy_wldev *dev);
+ 
+-int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev,
+-				     u16 dmacontroller_mmio_base,
+-				     int dma64);
+-int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev,
+-				     u16 dmacontroller_mmio_base,
+-				     int dma64);
+-
+-u16 b43legacy_dmacontroller_base(int dma64bit, int dmacontroller_idx);
+-
+ void b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev);
+ void b43legacy_dma_tx_resume(struct b43legacy_wldev *dev);
+ 
+@@ -320,20 +317,6 @@ void b43legacy_dma_free(struct b43legacy_wldev *dev)
+ {
+ }
+ static inline
+-int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev,
+-				     u16 dmacontroller_mmio_base,
+-				     int dma64)
+-{
+-	return 0;
+-}
+-static inline
+-int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev,
+-				     u16 dmacontroller_mmio_base,
+-				     int dma64)
+-{
+-	return 0;
+-}
+-static inline
+ void b43legacy_dma_get_tx_stats(struct b43legacy_wldev *dev,
+ 				struct ieee80211_tx_queue_stats *stats)
+ {
+diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
+index 53f7f2e..c39de42 100644
+--- a/drivers/net/wireless/b43legacy/main.c
++++ b/drivers/net/wireless/b43legacy/main.c
+@@ -3,7 +3,7 @@
+  *  Broadcom B43legacy wireless driver
+  *
+  *  Copyright (c) 2005 Martin Langer <martin-langer at gmx.de>
+- *  Copyright (c) 2005-2007 Stefano Brivio <stefano.brivio at polimi.it>
++ *  Copyright (c) 2005-2008 Stefano Brivio <stefano.brivio at polimi.it>
+  *  Copyright (c) 2005, 2006 Michael Buesch <mb at bu3sch.de>
+  *  Copyright (c) 2005 Danny van Dyk <kugelfang at gentoo.org>
+  *  Copyright (c) 2005 Andreas Jaggi <andreas.jaggi at waterwave.ch>
+@@ -60,6 +60,8 @@ MODULE_AUTHOR("Stefano Brivio");
+ MODULE_AUTHOR("Michael Buesch");
+ MODULE_LICENSE("GPL");
+ 
++MODULE_FIRMWARE(B43legacy_SUPPORTED_FIRMWARE_ID);
++
+ #if defined(CONFIG_B43LEGACY_DMA) && defined(CONFIG_B43LEGACY_PIO)
+ static int modparam_pio;
+ module_param_named(pio, modparam_pio, int, 0444);
+@@ -1640,10 +1642,11 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
+ 		err = -EOPNOTSUPP;
+ 		goto error;
+ 	}
+-	b43legacydbg(dev->wl, "Loading firmware version 0x%X, patch level %u "
+-	       "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", fwrev, fwpatch,
+-	       (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF,
+-	       (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, fwtime & 0x1F);
++	b43legacyinfo(dev->wl, "Loading firmware version 0x%X, patch level %u "
++		      "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", fwrev, fwpatch,
++		      (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF,
++		      (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F,
++		      fwtime & 0x1F);
+ 
+ 	dev->fw.rev = fwrev;
+ 	dev->fw.patch = fwpatch;
+@@ -3806,6 +3809,32 @@ static struct ssb_driver b43legacy_ssb_driver = {
+ 	.resume		= b43legacy_resume,
+ };
+ 
++static void b43legacy_print_driverinfo(void)
++{
++	const char *feat_pci = "", *feat_leds = "", *feat_rfkill = "",
++		   *feat_pio = "", *feat_dma = "";
++
++#ifdef CONFIG_B43LEGACY_PCI_AUTOSELECT
++	feat_pci = "P";
++#endif
++#ifdef CONFIG_B43LEGACY_LEDS
++	feat_leds = "L";
++#endif
++#ifdef CONFIG_B43LEGACY_RFKILL
++	feat_rfkill = "R";
++#endif
++#ifdef CONFIG_B43LEGACY_PIO
++	feat_pio = "I";
++#endif
++#ifdef CONFIG_B43LEGACY_DMA
++	feat_dma = "D";
++#endif
++	printk(KERN_INFO "Broadcom 43xx driver loaded "
++	       "[ Features: %s%s%s%s%s, Firmware-ID: "
++	       B43legacy_SUPPORTED_FIRMWARE_ID " ]\n",
++	       feat_pci, feat_leds, feat_rfkill, feat_pio, feat_dma);
++}
++
+ static int __init b43legacy_init(void)
+ {
+ 	int err;
+@@ -3816,6 +3845,8 @@ static int __init b43legacy_init(void)
+ 	if (err)
+ 		goto err_dfs_exit;
+ 
++	b43legacy_print_driverinfo();
++
+ 	return err;
+ 
+ err_dfs_exit:
+diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
+index 3e6ad7b..a56d9fc 100644
+--- a/drivers/net/wireless/ipw2200.c
++++ b/drivers/net/wireless/ipw2200.c
+@@ -3365,7 +3365,6 @@ static void ipw_rx_queue_reset(struct ipw_priv *priv,
+ 	/* Set us so that we have processed and used all buffers, but have
+ 	 * not restocked the Rx queue with fresh buffers */
+ 	rxq->read = rxq->write = 0;
+-	rxq->processed = RX_QUEUE_SIZE - 1;
+ 	rxq->free_count = 0;
+ 	spin_unlock_irqrestore(&rxq->lock, flags);
+ }
+@@ -3607,7 +3606,22 @@ static int ipw_load(struct ipw_priv *priv)
+  * Driver allocates buffers of this size for Rx
+  */
+ 
+-static inline int ipw_queue_space(const struct clx2_queue *q)
++/**
++ * ipw_rx_queue_space - Return number of free slots available in queue.
++ */
++static int ipw_rx_queue_space(const struct ipw_rx_queue *q)
++{
++	int s = q->read - q->write;
++	if (s <= 0)
++		s += RX_QUEUE_SIZE;
++	/* keep some buffer to not confuse full and empty queue */
++	s -= 2;
++	if (s < 0)
++		s = 0;
++	return s;
++}
++
++static inline int ipw_tx_queue_space(const struct clx2_queue *q)
+ {
+ 	int s = q->last_used - q->first_empty;
+ 	if (s <= 0)
+@@ -4947,7 +4961,7 @@ static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
+ 		priv->tx_packets++;
+ 	}
+       done:
+-	if ((ipw_queue_space(q) > q->low_mark) &&
++	if ((ipw_tx_queue_space(q) > q->low_mark) &&
+ 	    (qindex >= 0) &&
+ 	    (priv->status & STATUS_ASSOCIATED) && netif_running(priv->net_dev))
+ 		netif_wake_queue(priv->net_dev);
+@@ -4965,7 +4979,7 @@ static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf,
+ 	struct clx2_queue *q = &txq->q;
+ 	struct tfd_frame *tfd;
+ 
+-	if (ipw_queue_space(q) < (sync ? 1 : 2)) {
++	if (ipw_tx_queue_space(q) < (sync ? 1 : 2)) {
+ 		IPW_ERROR("No space for Tx\n");
+ 		return -EBUSY;
+ 	}
+@@ -5070,7 +5084,7 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv)
+ 
+ 	spin_lock_irqsave(&rxq->lock, flags);
+ 	write = rxq->write;
+-	while ((rxq->write != rxq->processed) && (rxq->free_count)) {
++	while ((ipw_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
+ 		element = rxq->rx_free.next;
+ 		rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
+ 		list_del(element);
+@@ -5187,7 +5201,6 @@ static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *priv)
+ 	/* Set us so that we have processed and used all buffers, but have
+ 	 * not restocked the Rx queue with fresh buffers */
+ 	rxq->read = rxq->write = 0;
+-	rxq->processed = RX_QUEUE_SIZE - 1;
+ 	rxq->free_count = 0;
+ 
+ 	return rxq;
+@@ -8223,13 +8236,17 @@ static void ipw_rx(struct ipw_priv *priv)
+ 	struct ieee80211_hdr_4addr *header;
+ 	u32 r, w, i;
+ 	u8 network_packet;
++	u8 fill_rx = 0;
+ 	DECLARE_MAC_BUF(mac);
+ 	DECLARE_MAC_BUF(mac2);
+ 	DECLARE_MAC_BUF(mac3);
+ 
+ 	r = ipw_read32(priv, IPW_RX_READ_INDEX);
+ 	w = ipw_read32(priv, IPW_RX_WRITE_INDEX);
+-	i = (priv->rxq->processed + 1) % RX_QUEUE_SIZE;
++	i = priv->rxq->read;
++
++	if (ipw_rx_queue_space (priv->rxq) > (RX_QUEUE_SIZE / 2))
++		fill_rx = 1;
+ 
+ 	while (i != r) {
+ 		rxb = priv->rxq->queue[i];
+@@ -8404,11 +8421,17 @@ static void ipw_rx(struct ipw_priv *priv)
+ 		list_add_tail(&rxb->list, &priv->rxq->rx_used);
+ 
+ 		i = (i + 1) % RX_QUEUE_SIZE;
++
++		/* If there are a lot of unsued frames, restock the Rx queue
++		 * so the ucode won't assert */
++		if (fill_rx) {
++			priv->rxq->read = i;
++			ipw_rx_queue_replenish(priv);
++		}
+ 	}
+ 
+ 	/* Backtrack one entry */
+-	priv->rxq->processed = (i ? i : RX_QUEUE_SIZE) - 1;
+-
++	priv->rxq->read = i;
+ 	ipw_rx_queue_restock(priv);
+ }
+ 
+@@ -10336,7 +10359,7 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
+ 	q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
+ 	ipw_write32(priv, q->reg_w, q->first_empty);
+ 
+-	if (ipw_queue_space(q) < q->high_mark)
++	if (ipw_tx_queue_space(q) < q->high_mark)
+ 		netif_stop_queue(priv->net_dev);
+ 
+ 	return NETDEV_TX_OK;
+@@ -10357,7 +10380,7 @@ static int ipw_net_is_queue_full(struct net_device *dev, int pri)
+ 	struct clx2_tx_queue *txq = &priv->txq[0];
+ #endif				/* CONFIG_IPW2200_QOS */
+ 
+-	if (ipw_queue_space(&txq->q) < txq->q.high_mark)
++	if (ipw_tx_queue_space(&txq->q) < txq->q.high_mark)
+ 		return 1;
+ 
+ 	return 0;
+diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
+index 5ee1ad6..40b71bc 100644
+--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
++++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
+@@ -687,6 +687,12 @@ static int iwl3945_enqueue_hcmd(struct iwl3945_priv *priv, struct iwl3945_host_c
+ 	BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
+ 	       !(cmd->meta.flags & CMD_SIZE_HUGE));
+ 
++
++	if (iwl3945_is_rfkill(priv)) {
++		IWL_DEBUG_INFO("Not sending command - RF KILL");
++		return -EIO;
++	}
++
+ 	if (iwl3945_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
+ 		IWL_ERROR("No space for Tx\n");
+ 		return -ENOSPC;
+@@ -1580,7 +1586,7 @@ static inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv)
+  */
+ int iwl3945_eeprom_init(struct iwl3945_priv *priv)
+ {
+-	__le16 *e = (__le16 *)&priv->eeprom;
++	u16 *e = (u16 *)&priv->eeprom;
+ 	u32 gp = iwl3945_read32(priv, CSR_EEPROM_GP);
+ 	u32 r;
+ 	int sz = sizeof(priv->eeprom);
+@@ -1623,7 +1629,7 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv)
+ 			IWL_ERROR("Time out reading EEPROM[%d]", addr);
+ 			return -ETIMEDOUT;
+ 		}
+-		e[addr / 2] = cpu_to_le16(r >> 16);
++		e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
+ 	}
+ 
+ 	return 0;
+@@ -2806,7 +2812,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
+ #endif
+ 
+ 	/* drop all data frame if we are not associated */
+-	if ((!iwl3945_is_associated(priv) || !priv->assoc_id) &&
++	if ((!iwl3945_is_associated(priv) ||
++	     ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) &&
+ 	    ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
+ 		IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
+ 		goto drop_unlock;
+@@ -4281,7 +4288,7 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
+ 	int reclaim;
+ 	unsigned long flags;
+ 	u8 fill_rx = 0;
+-	u32 count = 0;
++	u32 count = 8;
+ 
+ 	/* uCode's read index (stored in shared DRAM) indicates the last Rx
+ 	 * buffer that the driver may process (last buffer filled by ucode). */
+@@ -6256,6 +6263,8 @@ static void __iwl3945_down(struct iwl3945_priv *priv)
+ 					STATUS_RF_KILL_HW |
+ 			       test_bit(STATUS_RF_KILL_SW, &priv->status) <<
+ 					STATUS_RF_KILL_SW |
++			       test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
++					STATUS_GEO_CONFIGURED |
+ 			       test_bit(STATUS_IN_SUSPEND, &priv->status) <<
+ 					STATUS_IN_SUSPEND;
+ 		goto exit;
+@@ -6267,6 +6276,8 @@ static void __iwl3945_down(struct iwl3945_priv *priv)
+ 				STATUS_RF_KILL_HW |
+ 			test_bit(STATUS_RF_KILL_SW, &priv->status) <<
+ 				STATUS_RF_KILL_SW |
++			test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
++				STATUS_GEO_CONFIGURED |
+ 			test_bit(STATUS_IN_SUSPEND, &priv->status) <<
+ 				STATUS_IN_SUSPEND |
+ 			test_bit(STATUS_FW_ERROR, &priv->status) <<
+diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
+index f423241..a23d479 100644
+--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
++++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
+@@ -692,6 +692,11 @@ static int iwl4965_enqueue_hcmd(struct iwl4965_priv *priv, struct iwl4965_host_c
+ 	BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
+ 	       !(cmd->meta.flags & CMD_SIZE_HUGE));
+ 
++	if (iwl4965_is_rfkill(priv)) {
++		IWL_DEBUG_INFO("Not sending command - RF KILL");
++		return -EIO;
++	}
++
+ 	if (iwl4965_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
+ 		IWL_ERROR("No space for Tx\n");
+ 		return -ENOSPC;
+@@ -1654,7 +1659,7 @@ static inline void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv)
+  */
+ int iwl4965_eeprom_init(struct iwl4965_priv *priv)
+ {
+-	__le16 *e = (__le16 *)&priv->eeprom;
++	u16 *e = (u16 *)&priv->eeprom;
+ 	u32 gp = iwl4965_read32(priv, CSR_EEPROM_GP);
+ 	u32 r;
+ 	int sz = sizeof(priv->eeprom);
+@@ -1698,7 +1703,7 @@ int iwl4965_eeprom_init(struct iwl4965_priv *priv)
+ 			rc = -ETIMEDOUT;
+ 			goto done;
+ 		}
+-		e[addr / 2] = cpu_to_le16(r >> 16);
++		e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
+ 	}
+ 	rc = 0;
+ 
+@@ -2935,7 +2940,7 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv,
+ 	/* drop all data frame if we are not associated */
+ 	if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
+ 	   (!iwl4965_is_associated(priv) ||
+-	    !priv->assoc_id ||
++	    ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id) ||
+ 	    !priv->assoc_station_added)) {
+ 		IWL_DEBUG_DROP("Dropping - !iwl4965_is_associated\n");
+ 		goto drop_unlock;
+@@ -4664,7 +4669,7 @@ static void iwl4965_rx_handle(struct iwl4965_priv *priv)
+ 	int reclaim;
+ 	unsigned long flags;
+ 	u8 fill_rx = 0;
+-	u32 count = 0;
++	u32 count = 8;
+ 
+ 	/* uCode's read index (stored in shared DRAM) indicates the last Rx
+ 	 * buffer that the driver may process (last buffer filled by ucode). */
+@@ -6680,6 +6685,8 @@ static void __iwl4965_down(struct iwl4965_priv *priv)
+ 					STATUS_RF_KILL_HW |
+ 			       test_bit(STATUS_RF_KILL_SW, &priv->status) <<
+ 					STATUS_RF_KILL_SW |
++			       test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
++					STATUS_GEO_CONFIGURED |
+ 			       test_bit(STATUS_IN_SUSPEND, &priv->status) <<
+ 					STATUS_IN_SUSPEND;
+ 		goto exit;
+@@ -6691,6 +6698,8 @@ static void __iwl4965_down(struct iwl4965_priv *priv)
+ 				STATUS_RF_KILL_HW |
+ 			test_bit(STATUS_RF_KILL_SW, &priv->status) <<
+ 				STATUS_RF_KILL_SW |
++			test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
++				STATUS_GEO_CONFIGURED |
+ 			test_bit(STATUS_IN_SUSPEND, &priv->status) <<
+ 				STATUS_IN_SUSPEND |
+ 			test_bit(STATUS_FW_ERROR, &priv->status) <<
+diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
+index d3ecf89..8ce2ddf 100644
+--- a/drivers/net/wireless/rndis_wlan.c
++++ b/drivers/net/wireless/rndis_wlan.c
+@@ -2300,7 +2300,7 @@ static void rndis_update_wireless_stats(struct work_struct *work)
+ 	struct usbnet *usbdev = priv->usbdev;
+ 	struct iw_statistics iwstats;
+ 	__le32 rssi, tmp;
+-	int len, ret, bitrate, j;
++	int len, ret, j;
+ 	unsigned long flags;
+ 	int update_jiffies = STATS_UPDATE_JIFFIES;
+ 	void *buf;
+@@ -2352,14 +2352,10 @@ static void rndis_update_wireless_stats(struct work_struct *work)
+ 	if (ret == 0)
+ 		iwstats.discard.misc += le32_to_cpu(tmp);
+ 
+-	/* Workaround transfer stalls on poor quality links. */
+-	len = sizeof(tmp);
+-	ret = rndis_query_oid(usbdev, OID_GEN_LINK_SPEED, &tmp, &len);
+-	if (ret == 0) {
+-		bitrate = le32_to_cpu(tmp) * 100;
+-		if (bitrate > 11000000)
+-			goto end;
+-
++	/* Workaround transfer stalls on poor quality links.
++	 * TODO: find right way to fix these stalls (as stalls do not happen
++	 * with ndiswrapper/windows driver). */
++	if (iwstats.qual.qual <= 25) {
+ 		/* Decrease stats worker interval to catch stalls.
+ 		 * faster. Faster than 400-500ms causes packet loss,
+ 		 * Slower doesn't catch stalls fast enough.
+diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
+index 86ded40..4ca9730 100644
+--- a/drivers/net/wireless/rt2x00/rt2500usb.c
++++ b/drivers/net/wireless/rt2x00/rt2500usb.c
+@@ -1839,11 +1839,11 @@ static struct usb_device_id rt2500usb_device_table[] = {
+ 	/* Hercules */
+ 	{ USB_DEVICE(0x06f8, 0xe000), USB_DEVICE_DATA(&rt2500usb_ops) },
+ 	/* Melco */
++	{ USB_DEVICE(0x0411, 0x005e), USB_DEVICE_DATA(&rt2500usb_ops) },
+ 	{ USB_DEVICE(0x0411, 0x0066), USB_DEVICE_DATA(&rt2500usb_ops) },
+ 	{ USB_DEVICE(0x0411, 0x0067), USB_DEVICE_DATA(&rt2500usb_ops) },
+ 	{ USB_DEVICE(0x0411, 0x008b), USB_DEVICE_DATA(&rt2500usb_ops) },
+ 	{ USB_DEVICE(0x0411, 0x0097), USB_DEVICE_DATA(&rt2500usb_ops) },
+-
+ 	/* MSI */
+ 	{ USB_DEVICE(0x0db0, 0x6861), USB_DEVICE_DATA(&rt2500usb_ops) },
+ 	{ USB_DEVICE(0x0db0, 0x6865), USB_DEVICE_DATA(&rt2500usb_ops) },
+diff --git a/drivers/net/wireless/wavelan.h b/drivers/net/wireless/wavelan.h
+index 27172cd..9ab3605 100644
+--- a/drivers/net/wireless/wavelan.h
++++ b/drivers/net/wireless/wavelan.h
+@@ -85,7 +85,7 @@ union hacs_u
+ #define		HASR_MMC_INTR		0x0002	/* Interrupt request from MMC */
+ #define		HASR_MMC_BUSY		0x0004	/* MMC busy indication */
+ #define		HASR_PSA_BUSY		0x0008	/* LAN parameter storage area busy */
+-};
++} __attribute__ ((packed));
+ 
+ typedef struct ha_t	ha_t;
+ struct ha_t
+@@ -292,7 +292,7 @@ struct mmw_t
+ #define	MMW_EXT_ANT_INTERNAL	0x00	/* Internal antenna */
+ #define	MMW_EXT_ANT_EXTERNAL	0x03	/* External antenna */
+ #define	MMW_EXT_ANT_IQ_TEST	0x1C	/* IQ test pattern (set to 0) */
+-};
++} __attribute__ ((packed));
+ 
+ #define	MMW_SIZE	37
+ 
+@@ -347,7 +347,7 @@ struct mmr_t
+   unsigned char	mmr_unused4[1];		/* unused */
+   unsigned char	mmr_fee_data_l;		/* Read data from EEPROM (low) */
+   unsigned char	mmr_fee_data_h;		/* Read data from EEPROM (high) */
+-};
++} __attribute__ ((packed));
+ 
+ #define	MMR_SIZE	36
+ 
+diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
+index d984e0f..ccf46c9 100644
+--- a/drivers/s390/block/dasd.c
++++ b/drivers/s390/block/dasd.c
+@@ -1149,12 +1149,14 @@ static void __dasd_device_process_final_queue(struct dasd_device *device,
+ {
+ 	struct list_head *l, *n;
+ 	struct dasd_ccw_req *cqr;
++	struct dasd_block *block;
+ 
+ 	list_for_each_safe(l, n, final_queue) {
+ 		cqr = list_entry(l, struct dasd_ccw_req, devlist);
+ 		list_del_init(&cqr->devlist);
+-		if (cqr->block)
+-			spin_lock_bh(&cqr->block->queue_lock);
++		block = cqr->block;
++		if (block)
++			spin_lock_bh(&block->queue_lock);
+ 		switch (cqr->status) {
+ 		case DASD_CQR_SUCCESS:
+ 			cqr->status = DASD_CQR_DONE;
+@@ -1172,15 +1174,13 @@ static void __dasd_device_process_final_queue(struct dasd_device *device,
+ 				    cqr, cqr->status);
+ 			BUG();
+ 		}
+-		if (cqr->block)
+-			spin_unlock_bh(&cqr->block->queue_lock);
+ 		if (cqr->callback != NULL)
+ 			(cqr->callback)(cqr, cqr->callback_data);
++		if (block)
++			spin_unlock_bh(&block->queue_lock);
+ 	}
+ }
+ 
+-
+-
+ /*
+  * Take a look at the first request on the ccw queue and check
+  * if it reached its expire time. If so, terminate the IO.
+diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
+index 3faf053..e6c94db 100644
+--- a/drivers/s390/block/dcssblk.c
++++ b/drivers/s390/block/dcssblk.c
+@@ -666,7 +666,7 @@ dcssblk_make_request(struct request_queue *q, struct bio *bio)
+ 		page_addr = (unsigned long)
+ 			page_address(bvec->bv_page) + bvec->bv_offset;
+ 		source_addr = dev_info->start + (index<<12) + bytes_done;
+-		if (unlikely(page_addr & 4095) != 0 || (bvec->bv_len & 4095) != 0)
++		if (unlikely((page_addr & 4095) != 0) || (bvec->bv_len & 4095) != 0)
+ 			// More paranoia.
+ 			goto fail;
+ 		if (bio_data_dir(bio) == READ) {
+diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
+index 25629b9..2c7a1ee 100644
+--- a/drivers/s390/char/sclp.c
++++ b/drivers/s390/char/sclp.c
+@@ -29,10 +29,10 @@ static ext_int_info_t ext_int_info_hwc;
+ /* Lock to protect internal data consistency. */
+ static DEFINE_SPINLOCK(sclp_lock);
+ 
+-/* Mask of events that we can receive from the sclp interface. */
++/* Mask of events that we can send to the sclp interface. */
+ static sccb_mask_t sclp_receive_mask;
+ 
+-/* Mask of events that we can send to the sclp interface. */
++/* Mask of events that we can receive from the sclp interface. */
+ static sccb_mask_t sclp_send_mask;
+ 
+ /* List of registered event listeners and senders. */
+@@ -380,7 +380,7 @@ sclp_interrupt_handler(__u16 code)
+ 		}
+ 		sclp_running_state = sclp_running_state_idle;
+ 	}
+-	if (evbuf_pending && sclp_receive_mask != 0 &&
++	if (evbuf_pending &&
+ 	    sclp_activation_state == sclp_activation_state_active)
+ 		__sclp_queue_read_req();
+ 	spin_unlock(&sclp_lock);
+@@ -459,8 +459,8 @@ sclp_dispatch_state_change(void)
+ 		reg = NULL;
+ 		list_for_each(l, &sclp_reg_list) {
+ 			reg = list_entry(l, struct sclp_register, list);
+-			receive_mask = reg->receive_mask & sclp_receive_mask;
+-			send_mask = reg->send_mask & sclp_send_mask;
++			receive_mask = reg->send_mask & sclp_receive_mask;
++			send_mask = reg->receive_mask & sclp_send_mask;
+ 			if (reg->sclp_receive_mask != receive_mask ||
+ 			    reg->sclp_send_mask != send_mask) {
+ 				reg->sclp_receive_mask = receive_mask;
+@@ -615,8 +615,8 @@ struct init_sccb {
+ 	u16 mask_length;
+ 	sccb_mask_t receive_mask;
+ 	sccb_mask_t send_mask;
+-	sccb_mask_t sclp_send_mask;
+ 	sccb_mask_t sclp_receive_mask;
++	sccb_mask_t sclp_send_mask;
+ } __attribute__((packed));
+ 
+ /* Prepare init mask request. Called while sclp_lock is locked. */
+diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h
+index aa8186d..bac80e8 100644
+--- a/drivers/s390/char/sclp.h
++++ b/drivers/s390/char/sclp.h
+@@ -122,11 +122,13 @@ struct sclp_req {
+ /* of some routines it wants to be called from the low level driver */
+ struct sclp_register {
+ 	struct list_head list;
+-	/* event masks this user is registered for */
++	/* User wants to receive: */
+ 	sccb_mask_t receive_mask;
++	/* User wants to send: */
+ 	sccb_mask_t send_mask;
+-	/* actually present events */
++	/* H/W can receive: */
+ 	sccb_mask_t sclp_receive_mask;
++	/* H/W can send: */
+ 	sccb_mask_t sclp_send_mask;
+ 	/* called if event type availability changes */
+ 	void (*state_change_fn)(struct sclp_register *);
+diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c
+index 9dc77f1..b8f35bc 100644
+--- a/drivers/s390/char/sclp_config.c
++++ b/drivers/s390/char/sclp_config.c
+@@ -64,7 +64,7 @@ static int __init sclp_conf_init(void)
+ 		return rc;
+ 	}
+ 
+-	if (!(sclp_conf_register.sclp_receive_mask & EVTYP_CONFMGMDATA_MASK)) {
++	if (!(sclp_conf_register.sclp_send_mask & EVTYP_CONFMGMDATA_MASK)) {
+ 		printk(KERN_WARNING TAG "no configuration management.\n");
+ 		sclp_unregister(&sclp_conf_register);
+ 		rc = -ENOSYS;
+diff --git a/drivers/s390/char/sclp_cpi_sys.c b/drivers/s390/char/sclp_cpi_sys.c
+index 4161703..9f37456 100644
+--- a/drivers/s390/char/sclp_cpi_sys.c
++++ b/drivers/s390/char/sclp_cpi_sys.c
+@@ -129,7 +129,7 @@ static int cpi_req(void)
+ 			"to hardware console.\n");
+ 		goto out;
+ 	}
+-	if (!(sclp_cpi_event.sclp_send_mask & EVTYP_CTLPROGIDENT_MASK)) {
++	if (!(sclp_cpi_event.sclp_receive_mask & EVTYP_CTLPROGIDENT_MASK)) {
+ 		printk(KERN_WARNING "cpi: no control program "
+ 			"identification support\n");
+ 		rc = -EOPNOTSUPP;
+diff --git a/drivers/s390/char/sclp_rw.c b/drivers/s390/char/sclp_rw.c
+index ad7195d..da09781 100644
+--- a/drivers/s390/char/sclp_rw.c
++++ b/drivers/s390/char/sclp_rw.c
+@@ -452,10 +452,10 @@ sclp_emit_buffer(struct sclp_buffer *buffer,
+ 		return -EIO;
+ 
+ 	sccb = buffer->sccb;
+-	if (sclp_rw_event.sclp_send_mask & EVTYP_MSG_MASK)
++	if (sclp_rw_event.sclp_receive_mask & EVTYP_MSG_MASK)
+ 		/* Use normal write message */
+ 		sccb->msg_buf.header.type = EVTYP_MSG;
+-	else if (sclp_rw_event.sclp_send_mask & EVTYP_PMSGCMD_MASK)
++	else if (sclp_rw_event.sclp_receive_mask & EVTYP_PMSGCMD_MASK)
+ 		/* Use write priority message */
+ 		sccb->msg_buf.header.type = EVTYP_PMSGCMD;
+ 	else
+diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
+index f47f4a7..92f5272 100644
+--- a/drivers/s390/char/sclp_vt220.c
++++ b/drivers/s390/char/sclp_vt220.c
+@@ -202,7 +202,7 @@ sclp_vt220_callback(struct sclp_req *request, void *data)
+ static int
+ __sclp_vt220_emit(struct sclp_vt220_request *request)
+ {
+-	if (!(sclp_vt220_register.sclp_send_mask & EVTYP_VT220MSG_MASK)) {
++	if (!(sclp_vt220_register.sclp_receive_mask & EVTYP_VT220MSG_MASK)) {
+ 		request->sclp_req.status = SCLP_REQ_FAILED;
+ 		return -EIO;
+ 	}
+diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
+index d35dc3f..fec004f 100644
+--- a/drivers/s390/cio/device.c
++++ b/drivers/s390/cio/device.c
+@@ -32,7 +32,7 @@
+ #include "io_sch.h"
+ 
+ static struct timer_list recovery_timer;
+-static spinlock_t recovery_lock;
++static DEFINE_SPINLOCK(recovery_lock);
+ static int recovery_phase;
+ static const unsigned long recovery_delay[] = { 3, 30, 300 };
+ 
+@@ -1535,7 +1535,7 @@ static int recovery_check(struct device *dev, void *data)
+ 	return 0;
+ }
+ 
+-static void recovery_func(unsigned long data)
++static void recovery_work_func(struct work_struct *unused)
+ {
+ 	int redo = 0;
+ 
+@@ -1553,6 +1553,17 @@ static void recovery_func(unsigned long data)
+ 		CIO_MSG_EVENT(2, "recovery: end\n");
+ }
+ 
++static DECLARE_WORK(recovery_work, recovery_work_func);
++
++static void recovery_func(unsigned long data)
++{
++	/*
++	 * We can't do our recovery in softirq context and it's not
++	 * performance critical, so we schedule it.
++	 */
++	schedule_work(&recovery_work);
++}
++
+ void ccw_device_schedule_recovery(void)
+ {
+ 	unsigned long flags;
+diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
+index 097fc09..2b5bfb7 100644
+--- a/drivers/s390/cio/qdio.c
++++ b/drivers/s390/cio/qdio.c
+@@ -32,7 +32,7 @@
+ 
+ #include <linux/module.h>
+ #include <linux/init.h>
+-
++#include <linux/delay.h>
+ #include <linux/slab.h>
+ #include <linux/kernel.h>
+ #include <linux/proc_fs.h>
+@@ -1215,9 +1215,6 @@ tiqdio_is_inbound_q_done(struct qdio_q *q)
+ 
+ 	if (!no_used)
+ 		return 1;
+-	if (!q->siga_sync && !irq->is_qebsm)
+-		/* we'll check for more primed buffers in qeth_stop_polling */
+-		return 0;
+ 	if (irq->is_qebsm) {
+ 		count = 1;
+ 		start_buf = q->first_to_check;
+@@ -3332,13 +3329,7 @@ qdio_activate(struct ccw_device *cdev, int flags)
+ 		}
+ 	}
+ 
+-	wait_event_interruptible_timeout(cdev->private->wait_q,
+-					 ((irq_ptr->state ==
+-					  QDIO_IRQ_STATE_STOPPED) ||
+-					  (irq_ptr->state ==
+-					   QDIO_IRQ_STATE_ERR)),
+-					 QDIO_ACTIVATE_TIMEOUT);
+-
++	msleep(QDIO_ACTIVATE_TIMEOUT);
+ 	switch (irq_ptr->state) {
+ 	case QDIO_IRQ_STATE_STOPPED:
+ 	case QDIO_IRQ_STATE_ERR:
+diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
+index 37870e4..da8a272 100644
+--- a/drivers/s390/cio/qdio.h
++++ b/drivers/s390/cio/qdio.h
+@@ -57,10 +57,10 @@
+ 					    of the queue to 0 */
+ 
+ #define QDIO_ESTABLISH_TIMEOUT (1*HZ)
+-#define QDIO_ACTIVATE_TIMEOUT (5*HZ)
+ #define QDIO_CLEANUP_CLEAR_TIMEOUT (20*HZ)
+ #define QDIO_CLEANUP_HALT_TIMEOUT (10*HZ)
+ #define QDIO_FORCE_CHECK_TIMEOUT (10*HZ)
++#define QDIO_ACTIVATE_TIMEOUT (5) /* 5 ms */
+ 
+ enum qdio_irq_states {
+ 	QDIO_IRQ_STATE_INACTIVE,
+diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
+index 2074701..c72014a 100644
+--- a/drivers/scsi/ipr.c
++++ b/drivers/scsi/ipr.c
+@@ -5140,7 +5140,7 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd,
+ 	struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
+ 	struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
+ 	struct ipr_ioadl_desc *last_ioadl = NULL;
+-	int len = qc->nbytes + qc->pad_len;
++	int len = qc->nbytes;
+ 	struct scatterlist *sg;
+ 	unsigned int si;
+ 
+@@ -5206,7 +5206,7 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc)
+ 	ioarcb->cmd_pkt.request_type = IPR_RQTYPE_ATA_PASSTHRU;
+ 	ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC;
+ 	ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK;
+-	ipr_cmd->dma_use_sg = qc->pad_len ? qc->n_elem + 1 : qc->n_elem;
++	ipr_cmd->dma_use_sg = qc->n_elem;
+ 
+ 	ipr_build_ata_ioadl(ipr_cmd, qc);
+ 	regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION;
+diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
+index 0996f86..7cd05b5 100644
+--- a/drivers/scsi/libsas/sas_ata.c
++++ b/drivers/scsi/libsas/sas_ata.c
+@@ -178,8 +178,8 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
+ 	task->uldd_task = qc;
+ 	if (ata_is_atapi(qc->tf.protocol)) {
+ 		memcpy(task->ata_task.atapi_packet, qc->cdb, qc->dev->cdb_len);
+-		task->total_xfer_len = qc->nbytes + qc->pad_len;
+-		task->num_scatter = qc->pad_len ? qc->n_elem + 1 : qc->n_elem;
++		task->total_xfer_len = qc->nbytes;
++		task->num_scatter = qc->n_elem;
+ 	} else {
+ 		for_each_sg(qc->sg, sg, qc->n_elem, si)
+ 			xfer += sg->length;
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index 135c1d0..ba21d97 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -1014,10 +1014,6 @@ static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb,
+ 	}
+ 
+ 	req->buffer = NULL;
+-	if (blk_pc_request(req))
+-		sdb->length = req->data_len;
+-	else
+-		sdb->length = req->nr_sectors << 9;
+ 
+ 	/* 
+ 	 * Next, walk the list, and fill in the addresses and sizes of
+@@ -1026,6 +1022,10 @@ static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb,
+ 	count = blk_rq_map_sg(req->q, req, sdb->table.sgl);
+ 	BUG_ON(count > sdb->table.nents);
+ 	sdb->table.nents = count;
++	if (blk_pc_request(req))
++		sdb->length = req->data_len;
++	else
++		sdb->length = req->nr_sectors << 9;
+ 	return BLKPREP_OK;
+ }
+ 
+diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
+index d775eb6..62f9c6e 100644
+--- a/drivers/video/aty/atyfb_base.c
++++ b/drivers/video/aty/atyfb_base.c
+@@ -1913,61 +1913,6 @@ static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+ 		par->mmaped = 1;
+ 	return 0;
+ }
+-
+-static struct {
+-	u32 yoffset;
+-	u8 r[2][256];
+-	u8 g[2][256];
+-	u8 b[2][256];
+-} atyfb_save;
+-
+-static void atyfb_save_palette(struct atyfb_par *par, int enter)
+-{
+-	int i, tmp;
+-
+-	for (i = 0; i < 256; i++) {
+-		tmp = aty_ld_8(DAC_CNTL, par) & 0xfc;
+-		if (M64_HAS(EXTRA_BRIGHT))
+-			tmp |= 0x2;
+-		aty_st_8(DAC_CNTL, tmp, par);
+-		aty_st_8(DAC_MASK, 0xff, par);
+-
+-		aty_st_8(DAC_R_INDEX, i, par);
+-		atyfb_save.r[enter][i] = aty_ld_8(DAC_DATA, par);
+-		atyfb_save.g[enter][i] = aty_ld_8(DAC_DATA, par);
+-		atyfb_save.b[enter][i] = aty_ld_8(DAC_DATA, par);
+-		aty_st_8(DAC_W_INDEX, i, par);
+-		aty_st_8(DAC_DATA, atyfb_save.r[1 - enter][i], par);
+-		aty_st_8(DAC_DATA, atyfb_save.g[1 - enter][i], par);
+-		aty_st_8(DAC_DATA, atyfb_save.b[1 - enter][i], par);
+-	}
+-}
+-
+-static void atyfb_palette(int enter)
+-{
+-	struct atyfb_par *par;
+-	struct fb_info *info;
+-	int i;
+-
+-	for (i = 0; i < FB_MAX; i++) {
+-		info = registered_fb[i];
+-		if (info && info->fbops == &atyfb_ops) {
+-			par = (struct atyfb_par *) info->par;
+-			
+-			atyfb_save_palette(par, enter);
+-			if (enter) {
+-				atyfb_save.yoffset = info->var.yoffset;
+-				info->var.yoffset = 0;
+-				set_off_pitch(par, info);
+-			} else {
+-				info->var.yoffset = atyfb_save.yoffset;
+-				set_off_pitch(par, info);
+-			}
+-			aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
+-			break;
+-		}
+-	}
+-}
+ #endif /* __sparc__ */
+ 
+ 
+@@ -2670,10 +2615,6 @@ static int __devinit aty_init(struct fb_info *info)
+ 		goto aty_init_exit;
+ 	}
+ 
+-#ifdef __sparc__
+-	atyfb_save_palette(par, 0);
+-#endif
+-
+ #ifdef CONFIG_FB_ATY_CT
+ 	if (!noaccel && M64_HAS(INTEGRATED))
+ 		aty_init_cursor(info);
+@@ -2900,8 +2841,6 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ 
+ #ifdef __sparc__
+ 
+-extern void (*prom_palette) (int);
+-
+ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
+ 			struct fb_info *info, unsigned long addr)
+ {
+@@ -3536,9 +3475,6 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi
+ 		goto err_release_io;
+ 
+ #ifdef __sparc__
+-	if (!prom_palette)
+-		prom_palette = atyfb_palette;
+-
+ 	/*
+ 	 * Add /dev/fb mmap values.
+ 	 */
+diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
+index 41f6dbf..fdc9f43 100644
+--- a/drivers/video/cg14.c
++++ b/drivers/video/cg14.c
+@@ -16,6 +16,7 @@
+ #include <linux/init.h>
+ #include <linux/fb.h>
+ #include <linux/mm.h>
++#include <linux/uaccess.h>
+ 
+ #include <asm/io.h>
+ #include <asm/prom.h>
+diff --git a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c
+index 963a454..4deaac0 100644
+--- a/drivers/video/sbuslib.c
++++ b/drivers/video/sbuslib.c
+@@ -9,6 +9,7 @@
+ #include <linux/string.h>
+ #include <linux/fb.h>
+ #include <linux/mm.h>
++#include <linux/uaccess.h>
+ 
+ #include <asm/oplib.h>
+ #include <asm/fbio.h>
+diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
+index afcdc69..254d115 100644
+--- a/drivers/watchdog/Kconfig
++++ b/drivers/watchdog/Kconfig
+@@ -402,6 +402,18 @@ config IT8712F_WDT
+ 	  To compile this driver as a module, choose M here: the
+ 	  module will be called it8712f_wdt.
+ 
++config HP_WATCHDOG
++	tristate "HP Proliant iLO 2 Hardware Watchdog Timer"
++	depends on X86
++	help
++	  A software monitoring watchdog and NMI sourcing driver. This driver
++	  will detect lockups and provide stack trace. Also, when an NMI
++	  occurs this driver will make the necessary BIOS calls to log
++	  the cause of the NMI. This is a driver that will only load on a
++	  HP ProLiant system with a minimum of iLO2 support.
++	  To compile this driver as a module, choose M here: the
++	  module will be called hpwdt.
++
+ config SC1200_WDT
+ 	tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog"
+ 	depends on X86
+@@ -633,6 +645,19 @@ config WDT_RM9K_GPI
+ 	  To compile this driver as a module, choose M here: the
+ 	  module will be called rm9k_wdt.
+ 
++config SIBYTE_WDOG
++	tristate "Sibyte SoC hardware watchdog"
++	depends on CPU_SB1
++	help
++	  Watchdog driver for the built in watchdog hardware in Sibyte
++	  SoC processors.  There are apparently two watchdog timers
++	  on such processors; this driver supports only the first one,
++	  because currently Linux only supports exporting one watchdog
++	  to userspace.
++
++	  To compile this driver as a loadable module, choose M here.
++	  The module will be called sb_wdog.
++
+ config AR7_WDT
+ 	tristate "TI AR7 Watchdog Timer"
+ 	depends on AR7
+diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
+index ebc2114..f3fb170 100644
+--- a/drivers/watchdog/Makefile
++++ b/drivers/watchdog/Makefile
+@@ -67,6 +67,7 @@ obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
+ obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o
+ obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o iTCO_vendor_support.o
+ obj-$(CONFIG_IT8712F_WDT) += it8712f_wdt.o
++obj-$(CONFIG_HP_WATCHDOG) += hpwdt.o
+ obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
+ obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
+ obj-$(CONFIG_PC87413_WDT) += pc87413_wdt.o
+@@ -92,6 +93,7 @@ obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o
+ obj-$(CONFIG_INDYDOG) += indydog.o
+ obj-$(CONFIG_WDT_MTX1)	+= mtx-1_wdt.o
+ obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o
++obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
+ obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
+ obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
+ 
+diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c
+index 472be10..1237113 100644
+--- a/drivers/watchdog/bfin_wdt.c
++++ b/drivers/watchdog/bfin_wdt.c
+@@ -29,6 +29,7 @@
+ 
+ #define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args)
+ #define stampit() stamp("here i am")
++#define pr_init(fmt, args...) ({ static const __initdata char __fmt[] = fmt; printk(__fmt, ## args); })
+ 
+ #define WATCHDOG_NAME "bfin-wdt"
+ #define PFX WATCHDOG_NAME ": "
+@@ -445,19 +446,19 @@ static int __init bfin_wdt_init(void)
+ 
+ 	ret = register_reboot_notifier(&bfin_wdt_notifier);
+ 	if (ret) {
+-		printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret);
++		pr_init(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret);
+ 		return ret;
+ 	}
+ 
+ 	ret = misc_register(&bfin_wdt_miscdev);
+ 	if (ret) {
+-		printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
++		pr_init(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+ 		       WATCHDOG_MINOR, ret);
+ 		unregister_reboot_notifier(&bfin_wdt_notifier);
+ 		return ret;
+ 	}
+ 
+-	printk(KERN_INFO PFX "initialized: timeout=%d sec (nowayout=%d)\n",
++	pr_init(KERN_INFO PFX "initialized: timeout=%d sec (nowayout=%d)\n",
+ 	       timeout, nowayout);
+ 
+ 	return 0;
+diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
+new file mode 100644
+index 0000000..a2e174b
+--- /dev/null
++++ b/drivers/watchdog/hpwdt.c
+@@ -0,0 +1,926 @@
++/*
++ *	HP WatchDog Driver
++ *	based on
++ *
++ *	SoftDog	0.05:	A Software Watchdog Device
++ *
++ *	(c) Copyright 2007 Hewlett-Packard Development Company, L.P.
++ *	Thomas Mingarelli <thomas.mingarelli at hp.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/device.h>
++#include <linux/fs.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/irq.h>
++#include <linux/kernel.h>
++#include <linux/miscdevice.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/kdebug.h>
++#include <linux/moduleparam.h>
++#include <linux/notifier.h>
++#include <linux/pci.h>
++#include <linux/pci_ids.h>
++#include <linux/reboot.h>
++#include <linux/sched.h>
++#include <linux/timer.h>
++#include <linux/types.h>
++#include <linux/uaccess.h>
++#include <linux/watchdog.h>
++#include <linux/dmi.h>
++#include <linux/efi.h>
++#include <linux/string.h>
++#include <linux/bootmem.h>
++#include <linux/slab.h>
++#include <asm/dmi.h>
++#include <asm/desc.h>
++#include <asm/kdebug.h>
++
++#define PCI_BIOS32_SD_VALUE		0x5F32335F	/* "_32_" */
++#define CRU_BIOS_SIGNATURE_VALUE	0x55524324
++#define PCI_BIOS32_PARAGRAPH_LEN	16
++#define PCI_ROM_BASE1			0x000F0000
++#define ROM_SIZE			0x10000
++
++struct bios32_service_dir {
++	u32 signature;
++	u32 entry_point;
++	u8 revision;
++	u8 length;
++	u8 checksum;
++	u8 reserved[5];
++};
++
++/*
++ * smbios_entry_point     - defines SMBIOS entry point structure
++ *
++ * anchor[4]              - anchor string (_SM_)
++ * checksum               - checksum of the entry point structure
++ * length                 - length of the entry point structure
++ * major_ver              - major version (02h for revision 2.1)
++ * minor_ver              - minor version (01h for revision 2.1)
++ * max_struct_size        - size of the largest SMBIOS structure
++ * revision               - entry point structure revision implemented
++ * formatted_area[5]      - reserved
++ * intermediate_anchor[5] - intermediate anchor string (_DMI_)
++ * intermediate_checksum  - intermediate checksum
++ * table_length           - structure table length
++ * table_address          - structure table address
++ * table_num_structs      - number of SMBIOS structures present
++ * bcd_revision           - BCD revision
++ */
++struct smbios_entry_point {
++	u8 anchor[4];
++	u8 checksum;
++	u8 length;
++	u8 major_ver;
++	u8 minor_ver;
++	u16 max_struct_size;
++	u8 revision;
++	u8 formatted_area[5];
++	u8 intermediate_anchor[5];
++	u8 intermediate_checksum;
++	u16 table_length;
++	u64 table_address;
++	u16 table_num_structs;
++	u8 bcd_revision;
++};
++
++/* type 212 */
++struct smbios_cru64_info {
++	u8 type;
++	u8 byte_length;
++	u16 handle;
++	u32 signature;
++	u64 physical_address;
++	u32 double_length;
++	u32 double_offset;
++};
++#define SMBIOS_CRU64_INFORMATION	212
++
++struct cmn_registers {
++	union {
++		struct {
++			u8 ral;
++			u8 rah;
++			u16 rea2;
++		};
++		u32 reax;
++	} u1;
++	union {
++		struct {
++			u8 rbl;
++			u8 rbh;
++			u8 reb2l;
++			u8 reb2h;
++		};
++		u32 rebx;
++	} u2;
++	union {
++		struct {
++			u8 rcl;
++			u8 rch;
++			u16 rec2;
++		};
++		u32 recx;
++	} u3;
++	union {
++		struct {
++			u8 rdl;
++			u8 rdh;
++			u16 red2;
++		};
++		u32 redx;
++	} u4;
++
++	u32 resi;
++	u32 redi;
++	u16 rds;
++	u16 res;
++	u32 reflags;
++}  __attribute__((packed));
++
++#define DEFAULT_MARGIN	30
++static unsigned int soft_margin = DEFAULT_MARGIN;	/* in seconds */
++static unsigned int reload;			/* the computed soft_margin */
++static int nowayout = WATCHDOG_NOWAYOUT;
++static char expect_release;
++static unsigned long hpwdt_is_open;
++
++static void __iomem *pci_mem_addr;		/* the PCI-memory address */
++static unsigned long __iomem *hpwdt_timer_reg;
++static unsigned long __iomem *hpwdt_timer_con;
++
++static DEFINE_SPINLOCK(rom_lock);
++
++static void *cru_rom_addr;
++
++static struct cmn_registers cmn_regs;
++
++static struct pci_device_id hpwdt_devices[] = {
++	{
++	 .vendor = PCI_VENDOR_ID_COMPAQ,
++	 .device = 0xB203,
++	 .subvendor = PCI_ANY_ID,
++	 .subdevice = PCI_ANY_ID,
++	},
++	{0},			/* terminate list */
++};
++MODULE_DEVICE_TABLE(pci, hpwdt_devices);
++
++/*
++ *	bios_checksum
++ */
++static int __devinit bios_checksum(const char __iomem *ptr, int len)
++{
++	char sum = 0;
++	int i;
++
++	/*
++	 * calculate checksum of size bytes. This should add up
++	 * to zero if we have a valid header.
++	 */
++	for (i = 0; i < len; i++)
++		sum += ptr[i];
++
++	return ((sum == 0) && (len > 0));
++}
++
++#ifndef CONFIG_X86_64
++/* --32 Bit Bios------------------------------------------------------------ */
++
++#define HPWDT_ARCH	32
++
++asmlinkage void asminline_call(struct cmn_registers *pi86Regs,
++			       unsigned long *pRomEntry)
++{
++	asm("pushl       %ebp               \n\t"
++	    "movl        %esp, %ebp         \n\t"
++	    "pusha                          \n\t"
++	    "pushf                          \n\t"
++	    "push        %es                \n\t"
++	    "push        %ds                \n\t"
++	    "pop         %es                \n\t"
++	    "movl        8(%ebp),%eax       \n\t"
++	    "movl        4(%eax),%ebx       \n\t"
++	    "movl        8(%eax),%ecx       \n\t"
++	    "movl        12(%eax),%edx      \n\t"
++	    "movl        16(%eax),%esi      \n\t"
++	    "movl        20(%eax),%edi      \n\t"
++	    "movl        (%eax),%eax        \n\t"
++	    "push        %cs                \n\t"
++	    "call        *12(%ebp)          \n\t"
++	    "pushf                          \n\t"
++	    "pushl       %eax               \n\t"
++	    "movl        8(%ebp),%eax       \n\t"
++	    "movl        %ebx,4(%eax)       \n\t"
++	    "movl        %ecx,8(%eax)       \n\t"
++	    "movl        %edx,12(%eax)      \n\t"
++	    "movl        %esi,16(%eax)      \n\t"
++	    "movl        %edi,20(%eax)      \n\t"
++	    "movw        %ds,24(%eax)       \n\t"
++	    "movw        %es,26(%eax)       \n\t"
++	    "popl        %ebx               \n\t"
++	    "movl        %ebx,(%eax)        \n\t"
++	    "popl        %ebx               \n\t"
++	    "movl        %ebx,28(%eax)      \n\t"
++	    "pop         %es                \n\t"
++	    "popf                           \n\t"
++	    "popa                           \n\t"
++	    "leave                          \n\t" "ret");
++}
++
++/*
++ *	cru_detect
++ *
++ *	Routine Description:
++ *	This function uses the 32-bit BIOS Service Directory record to
++ *	search for a $CRU record.
++ *
++ *	Return Value:
++ *	0        :  SUCCESS
++ *	<0       :  FAILURE
++ */
++static int __devinit cru_detect(unsigned long map_entry,
++	unsigned long map_offset)
++{
++	void *bios32_map;
++	unsigned long *bios32_entrypoint;
++	unsigned long cru_physical_address;
++	unsigned long cru_length;
++	unsigned long physical_bios_base = 0;
++	unsigned long physical_bios_offset = 0;
++	int retval = -ENODEV;
++
++	bios32_map = ioremap(map_entry, (2 * PAGE_SIZE));
++
++	if (bios32_map == NULL)
++		return -ENODEV;
++
++	bios32_entrypoint = bios32_map + map_offset;
++
++	cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE;
++
++	asminline_call(&cmn_regs, bios32_entrypoint);
++
++	if (cmn_regs.u1.ral != 0) {
++		printk(KERN_WARNING
++		       "hpwdt: Call succeeded but with an error: 0x%x\n",
++		       cmn_regs.u1.ral);
++	} else {
++		physical_bios_base = cmn_regs.u2.rebx;
++		physical_bios_offset = cmn_regs.u4.redx;
++		cru_length = cmn_regs.u3.recx;
++		cru_physical_address =
++		    physical_bios_base + physical_bios_offset;
++
++		/* If the values look OK, then map it in. */
++		if ((physical_bios_base + physical_bios_offset)) {
++			cru_rom_addr =
++			    ioremap(cru_physical_address, cru_length);
++			if (cru_rom_addr)
++				retval = 0;
++		}
++
++		printk(KERN_DEBUG "hpwdt: CRU Base Address:   0x%lx\n",
++			physical_bios_base);
++		printk(KERN_DEBUG "hpwdt: CRU Offset Address: 0x%lx\n",
++			physical_bios_offset);
++		printk(KERN_DEBUG "hpwdt: CRU Length:         0x%lx\n",
++			cru_length);
++		printk(KERN_DEBUG "hpwdt: CRU Mapped Address: 0x%x\n",
++			(unsigned int)&cru_rom_addr);
++	}
++	iounmap(bios32_map);
++	return retval;
++}
++
++/*
++ *	bios32_present
++ *
++ *	Routine Description:
++ *	This function finds the 32-bit BIOS Service Directory
++ *
++ *	Return Value:
++ *	0        :  SUCCESS
++ *	<0       :  FAILURE
++ */
++static int __devinit bios32_present(const char __iomem *p)
++{
++	struct bios32_service_dir *bios_32_ptr;
++	int length;
++	unsigned long map_entry, map_offset;
++
++	bios_32_ptr = (struct bios32_service_dir *) p;
++
++	/*
++	 * Search for signature by checking equal to the swizzled value
++	 * instead of calling another routine to perform a strcmp.
++	 */
++	if (bios_32_ptr->signature == PCI_BIOS32_SD_VALUE) {
++		length = bios_32_ptr->length * PCI_BIOS32_PARAGRAPH_LEN;
++		if (bios_checksum(p, length)) {
++			/*
++			 * According to the spec, we're looking for the
++			 * first 4KB-aligned address below the entrypoint
++			 * listed in the header. The Service Directory code
++			 * is guaranteed to occupy no more than 2 4KB pages.
++			 */
++			map_entry = bios_32_ptr->entry_point & ~(PAGE_SIZE - 1);
++			map_offset = bios_32_ptr->entry_point - map_entry;
++
++			return cru_detect(map_entry, map_offset);
++		}
++	}
++	return -ENODEV;
++}
++
++static int __devinit detect_cru_service(void)
++{
++	char __iomem *p, *q;
++	int rc = -1;
++
++	/*
++	 * Search from 0x0f0000 through 0x0fffff, inclusive.
++	 */
++	p = ioremap(PCI_ROM_BASE1, ROM_SIZE);
++	if (p == NULL)
++		return -ENOMEM;
++
++	for (q = p; q < p + ROM_SIZE; q += 16) {
++		rc = bios32_present(q);
++		if (!rc)
++			break;
++	}
++	iounmap(p);
++	return rc;
++}
++
++#else
++/* --64 Bit Bios------------------------------------------------------------ */
++
++#define HPWDT_ARCH	64
++
++asmlinkage void asminline_call(struct cmn_registers *pi86Regs,
++			       unsigned long *pRomEntry)
++{
++	asm("pushq      %rbp            \n\t"
++	    "movq       %rsp, %rbp      \n\t"
++	    "pushq      %rax            \n\t"
++	    "pushq      %rbx            \n\t"
++	    "pushq      %rdx            \n\t"
++	    "pushq      %r12            \n\t"
++	    "pushq      %r9             \n\t"
++	    "movq       %rsi, %r12      \n\t"
++	    "movq       %rdi, %r9       \n\t"
++	    "movl       4(%r9),%ebx     \n\t"
++	    "movl       8(%r9),%ecx     \n\t"
++	    "movl       12(%r9),%edx    \n\t"
++	    "movl       16(%r9),%esi    \n\t"
++	    "movl       20(%r9),%edi    \n\t"
++	    "movl       (%r9),%eax      \n\t"
++	    "call       *%r12           \n\t"
++	    "pushfq                     \n\t"
++	    "popq        %r12           \n\t"
++	    "popfq                      \n\t"
++	    "movl       %eax, (%r9)     \n\t"
++	    "movl       %ebx, 4(%r9)    \n\t"
++	    "movl       %ecx, 8(%r9)    \n\t"
++	    "movl       %edx, 12(%r9)   \n\t"
++	    "movl       %esi, 16(%r9)   \n\t"
++	    "movl       %edi, 20(%r9)   \n\t"
++	    "movq       %r12, %rax      \n\t"
++	    "movl       %eax, 28(%r9)   \n\t"
++	    "popq       %r9             \n\t"
++	    "popq       %r12            \n\t"
++	    "popq       %rdx            \n\t"
++	    "popq       %rbx            \n\t"
++	    "popq       %rax            \n\t"
++	    "leave                      \n\t" "ret");
++}
++
++/*
++ *	dmi_find_cru
++ *
++ *	Routine Description:
++ *	This function checks wether or not a SMBIOS/DMI record is
++ *	the 64bit CRU info or not
++ *
++ *	Return Value:
++ *	0        :  SUCCESS - if record found
++ *	<0       :  FAILURE - if record not found
++ */
++static void __devinit dmi_find_cru(const struct dmi_header *dm)
++{
++	struct smbios_cru64_info *smbios_cru64_ptr;
++	unsigned long cru_physical_address;
++
++	if (dm->type == SMBIOS_CRU64_INFORMATION) {
++		smbios_cru64_ptr = (struct smbios_cru64_info *) dm;
++		if (smbios_cru64_ptr->signature == CRU_BIOS_SIGNATURE_VALUE) {
++			cru_physical_address =
++			    smbios_cru64_ptr->physical_address +
++			    smbios_cru64_ptr->double_offset;
++			cru_rom_addr = ioremap(cru_physical_address,
++				    smbios_cru64_ptr->double_length);
++		}
++	}
++}
++
++/*
++ *	dmi_table
++ *
++ *	Routine Description:
++ *	Decode the SMBIOS/DMI table and check if we have a 64bit CRU record
++ *	or not.
++ *
++ *	We have to be cautious here. We have seen BIOSes with DMI pointers
++ *	pointing to completely the wrong place for example
++ */
++static void __devinit dmi_table(u8 *buf, int len, int num,
++		      void (*decode)(const struct dmi_header *))
++{
++	u8 *data = buf;
++	int i = 0;
++
++	/*
++	 *	Stop when we see all the items the table claimed to have
++	 *	OR we run off the end of the table (also happens)
++	 */
++	while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) {
++		const struct dmi_header *dm = (const struct dmi_header *)data;
++
++		/*
++		 *  We want to know the total length (formated area and strings)
++		 *  before decoding to make sure we won't run off the table in
++		 *  dmi_decode or dmi_string
++		 */
++		data += dm->length;
++		while ((data - buf < len - 1) && (data[0] || data[1]))
++			data++;
++		if (data - buf < len - 1)
++			decode(dm);
++		data += 2;
++		i++;
++	}
++}
++
++/*
++ *	smbios_present
++ *
++ *	Routine Description:
++ *	This function parses the SMBIOS entry point table to retrieve
++ *	the 64 bit CRU Service.
++ *
++ *	Return Value:
++ *	0        :  SUCCESS
++ *	<0       :  FAILURE
++ */
++static int __devinit smbios_present(const char __iomem *p)
++{
++	struct smbios_entry_point *eps =
++		(struct smbios_entry_point *) p;
++	int length;
++	u8 *buf;
++
++	/* check if we have indeed the SMBIOS table entry point */
++	if ((strncmp((char *)eps->anchor, "_SM_",
++			     sizeof(eps->anchor))) == 0) {
++		length = eps->length;
++
++		/* SMBIOS v2.1 implementation might use 0x1e */
++		if ((length == 0x1e) &&
++		    (eps->major_ver == 2) &&
++		    (eps->minor_ver == 1))
++			length = 0x1f;
++
++		/*
++		 * Now we will check:
++		 * - SMBIOS checksum must be 0
++		 * - intermediate anchor should be _DMI_
++		 * - intermediate checksum should be 0
++		 */
++		if ((bios_checksum(p, length)) &&
++		    (strncmp((char *)eps->intermediate_anchor, "_DMI_",
++		             sizeof(eps->intermediate_anchor)) == 0) &&
++		    (bios_checksum(p+0x10, 15))) {
++			buf = ioremap(eps->table_address, eps->table_length);
++			if (buf == NULL)
++				return -ENODEV;
++
++
++			/* Scan the DMI table for the 64 bit CRU service */
++			dmi_table(buf, eps->table_length,
++			          eps->table_num_structs, dmi_find_cru);
++
++			iounmap(buf);
++			return 0;
++		}
++	}
++
++	return -ENODEV;
++}
++
++static int __devinit smbios_scan_machine(void)
++{
++	char __iomem *p, *q;
++	int rc;
++
++	if (efi_enabled) {
++		if (efi.smbios == EFI_INVALID_TABLE_ADDR)
++			return -ENODEV;
++
++		p = ioremap(efi.smbios, 32);
++		if (p == NULL)
++			return -ENOMEM;
++
++		rc = smbios_present(p);
++		iounmap(p);
++	} else {
++		/*
++		 * Search from 0x0f0000 through 0x0fffff, inclusive.
++		 */
++		p = ioremap(PCI_ROM_BASE1, ROM_SIZE);
++		if (p == NULL)
++			return -ENOMEM;
++
++		for (q = p; q < p + ROM_SIZE; q += 16) {
++			rc = smbios_present(q);
++			if (!rc) {
++				break;
++			}
++		}
++		iounmap(p);
++	}
++}
++
++static int __devinit detect_cru_service(void)
++{
++	cru_rom_addr = NULL;
++
++	smbios_scan_machine();	/* will become dmi_walk(dmi_find_cru); */
++
++	/* if cru_rom_addr has been set then we found a CRU service */
++	return ((cru_rom_addr != NULL)? 0: -ENODEV);
++}
++
++/* ------------------------------------------------------------------------- */
++
++#endif
++
++/*
++ *	NMI Handler
++ */
++static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason,
++			    void *data)
++{
++	static unsigned long rom_pl;
++	static int die_nmi_called;
++
++	if (ulReason != DIE_NMI && ulReason != DIE_NMI_IPI)
++		return NOTIFY_OK;
++
++	spin_lock_irqsave(&rom_lock, rom_pl);
++	if (!die_nmi_called)
++		asminline_call(&cmn_regs, cru_rom_addr);
++	die_nmi_called = 1;
++	spin_unlock_irqrestore(&rom_lock, rom_pl);
++	if (cmn_regs.u1.ral == 0) {
++		printk(KERN_WARNING "hpwdt: An NMI occurred, "
++		       "but unable to determine source.\n");
++	} else {
++		panic("An NMI occurred, please see the Integrated "
++			"Management Log for details.\n");
++	}
++
++	return NOTIFY_STOP;
++}
++
++/*
++ *	Watchdog operations
++ */
++static void hpwdt_start(void)
++{
++	reload = (soft_margin * 1000) / 128;
++	iowrite16(reload, hpwdt_timer_reg);
++	iowrite16(0x85, hpwdt_timer_con);
++}
++
++static void hpwdt_stop(void)
++{
++	unsigned long data;
++
++	data = ioread16(hpwdt_timer_con);
++	data &= 0xFE;
++	iowrite16(data, hpwdt_timer_con);
++}
++
++static void hpwdt_ping(void)
++{
++	iowrite16(reload, hpwdt_timer_reg);
++}
++
++static int hpwdt_change_timer(int new_margin)
++{
++	/* Arbitrary, can't find the card's limits */
++	if (new_margin < 30 || new_margin > 600) {
++		printk(KERN_WARNING
++			"hpwdt: New value passed in is invalid: %d seconds.\n",
++			new_margin);
++		return -EINVAL;
++	}
++
++	soft_margin = new_margin;
++	printk(KERN_DEBUG
++		"hpwdt: New timer passed in is %d seconds.\n",
++		new_margin);
++	reload = (soft_margin * 1000) / 128;
++
++	return 0;
++}
++
++/*
++ *	/dev/watchdog handling
++ */
++static int hpwdt_open(struct inode *inode, struct file *file)
++{
++	/* /dev/watchdog can only be opened once */
++	if (test_and_set_bit(0, &hpwdt_is_open))
++		return -EBUSY;
++
++	/* Start the watchdog */
++	hpwdt_start();
++	hpwdt_ping();
++
++	return nonseekable_open(inode, file);
++}
++
++static int hpwdt_release(struct inode *inode, struct file *file)
++{
++	/* Stop the watchdog */
++	if (expect_release == 42) {
++		hpwdt_stop();
++	} else {
++		printk(KERN_CRIT
++			"hpwdt: Unexpected close, not stopping watchdog!\n");
++		hpwdt_ping();
++	}
++
++	expect_release = 0;
++
++	/* /dev/watchdog is being closed, make sure it can be re-opened */
++	clear_bit(0, &hpwdt_is_open);
++
++	return 0;
++}
++
++static ssize_t hpwdt_write(struct file *file, const char __user *data,
++	size_t len, loff_t *ppos)
++{
++	/* See if we got the magic character 'V' and reload the timer */
++	if (len) {
++		if (!nowayout) {
++			size_t i;
++
++			/* note: just in case someone wrote the magic character
++			 * five months ago... */
++			expect_release = 0;
++
++			/* scan to see whether or not we got the magic char. */
++			for (i = 0; i != len; i++) {
++				char c;
++				if (get_user(c, data+i))
++					return -EFAULT;
++				if (c == 'V')
++					expect_release = 42;
++			}
++		}
++
++		/* someone wrote to us, we should reload the timer */
++		hpwdt_ping();
++	}
++
++	return len;
++}
++
++static struct watchdog_info ident = {
++	.options = WDIOF_SETTIMEOUT |
++		   WDIOF_KEEPALIVEPING |
++		   WDIOF_MAGICCLOSE,
++	.identity = "HP iLO2 HW Watchdog Timer",
++};
++
++static long hpwdt_ioctl(struct file *file, unsigned int cmd,
++	unsigned long arg)
++{
++	void __user *argp = (void __user *)arg;
++	int __user *p = argp;
++	int new_margin;
++	int ret = -ENOTTY;
++
++	switch (cmd) {
++	case WDIOC_GETSUPPORT:
++		ret = 0;
++		if (copy_to_user(argp, &ident, sizeof(ident)))
++			ret = -EFAULT;
++		break;
++
++	case WDIOC_GETSTATUS:
++	case WDIOC_GETBOOTSTATUS:
++		ret = put_user(0, p);
++		break;
++
++	case WDIOC_KEEPALIVE:
++		hpwdt_ping();
++		ret = 0;
++		break;
++
++	case WDIOC_SETTIMEOUT:
++		ret = get_user(new_margin, p);
++		if (ret)
++			break;
++
++		ret = hpwdt_change_timer(new_margin);
++		if (ret)
++			break;
++
++		hpwdt_ping();
++		/* Fall */
++	case WDIOC_GETTIMEOUT:
++		ret = put_user(soft_margin, p);
++		break;
++	}
++	return ret;
++}
++
++/*
++ *	Kernel interfaces
++ */
++static struct file_operations hpwdt_fops = {
++	.owner = THIS_MODULE,
++	.llseek = no_llseek,
++	.write = hpwdt_write,
++	.unlocked_ioctl = hpwdt_ioctl,
++	.open = hpwdt_open,
++	.release = hpwdt_release,
++};
++
++static struct miscdevice hpwdt_miscdev = {
++	.minor = WATCHDOG_MINOR,
++	.name = "watchdog",
++	.fops = &hpwdt_fops,
++};
++
++static struct notifier_block die_notifier = {
++	.notifier_call = hpwdt_pretimeout,
++	.priority = 0x7FFFFFFF,
++};
++
++/*
++ *	Init & Exit
++ */
++
++static int __devinit hpwdt_init_one(struct pci_dev *dev,
++				    const struct pci_device_id *ent)
++{
++	int retval;
++
++	/*
++	 * First let's find out if we are on an iLO2 server. We will
++	 * not run on a legacy ASM box.
++	 */
++	if (dev->subsystem_vendor != PCI_VENDOR_ID_HP) {
++		dev_warn(&dev->dev,
++		       "This server does not have an iLO2 ASIC.\n");
++		return -ENODEV;
++	}
++
++	if (pci_enable_device(dev)) {
++		dev_warn(&dev->dev,
++			"Not possible to enable PCI Device: 0x%x:0x%x.\n",
++			ent->vendor, ent->device);
++		return -ENODEV;
++	}
++
++	pci_mem_addr = pci_iomap(dev, 1, 0x80);
++	if (!pci_mem_addr) {
++		dev_warn(&dev->dev,
++			"Unable to detect the iLO2 server memory.\n");
++		retval = -ENOMEM;
++		goto error_pci_iomap;
++	}
++	hpwdt_timer_reg = pci_mem_addr + 0x70;
++	hpwdt_timer_con = pci_mem_addr + 0x72;
++
++	/* Make sure that we have a valid soft_margin */
++	if (hpwdt_change_timer(soft_margin))
++		hpwdt_change_timer(DEFAULT_MARGIN);
++
++	/*
++	 * We need to map the ROM to get the CRU service.
++	 * For 32 bit Operating Systems we need to go through the 32 Bit
++	 * BIOS Service Directory
++	 * For 64 bit Operating Systems we get that service through SMBIOS.
++	 */
++	retval = detect_cru_service();
++	if (retval < 0) {
++		dev_warn(&dev->dev,
++		       "Unable to detect the %d Bit CRU Service.\n",
++			HPWDT_ARCH);
++		goto error_get_cru;
++	}
++
++	/*
++	 * We know this is the only CRU call we need to make so lets keep as
++	 * few instructions as possible once the NMI comes in.
++	 */
++	cmn_regs.u1.rah = 0x0D;
++	cmn_regs.u1.ral = 0x02;
++
++	retval = register_die_notifier(&die_notifier);
++	if (retval != 0) {
++		dev_warn(&dev->dev,
++		       "Unable to register a die notifier (err=%d).\n",
++			retval);
++		goto error_die_notifier;
++	}
++
++	retval = misc_register(&hpwdt_miscdev);
++	if (retval < 0) {
++		dev_warn(&dev->dev,
++			"Unable to register miscdev on minor=%d (err=%d).\n",
++			WATCHDOG_MINOR, retval);
++		goto error_misc_register;
++	}
++
++	printk(KERN_INFO
++		"hp Watchdog Timer Driver: 1.00"
++		", timer margin: %d seconds( nowayout=%d).\n",
++		soft_margin, nowayout);
++
++	return 0;
++
++error_misc_register:
++	unregister_die_notifier(&die_notifier);
++error_die_notifier:
++	if (cru_rom_addr)
++		iounmap(cru_rom_addr);
++error_get_cru:
++	pci_iounmap(dev, pci_mem_addr);
++error_pci_iomap:
++	pci_disable_device(dev);
++	return retval;
++}
++
++static void __devexit hpwdt_exit(struct pci_dev *dev)
++{
++	if (!nowayout)
++		hpwdt_stop();
++
++	misc_deregister(&hpwdt_miscdev);
++	unregister_die_notifier(&die_notifier);
++
++	if (cru_rom_addr)
++		iounmap(cru_rom_addr);
++	pci_iounmap(dev, pci_mem_addr);
++	pci_disable_device(dev);
++}
++
++static struct pci_driver hpwdt_driver = {
++	.name = "hpwdt",
++	.id_table = hpwdt_devices,
++	.probe = hpwdt_init_one,
++	.remove = __devexit_p(hpwdt_exit),
++};
++
++static void __exit hpwdt_cleanup(void)
++{
++	pci_unregister_driver(&hpwdt_driver);
++}
++
++static int __init hpwdt_init(void)
++{
++	return pci_register_driver(&hpwdt_driver);
++}
++
++MODULE_AUTHOR("Tom Mingarelli");
++MODULE_DESCRIPTION("hp watchdog driver");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
++
++module_param(soft_margin, int, 0);
++MODULE_PARM_DESC(soft_margin, "Watchdog timeout in seconds");
++
++module_param(nowayout, int, 0);
++MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
++		__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
++
++module_init(hpwdt_init);
++module_exit(hpwdt_cleanup);
+diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c
+index 9845174..789831b 100644
+--- a/drivers/watchdog/mtx-1_wdt.c
++++ b/drivers/watchdog/mtx-1_wdt.c
+@@ -45,10 +45,13 @@
+ #include <linux/completion.h>
+ #include <linux/jiffies.h>
+ #include <linux/watchdog.h>
++#include <linux/platform_device.h>
++
+ #include <asm/io.h>
+ #include <asm/uaccess.h>
+ 
+ #include <asm/mach-au1x00/au1000.h>
++#include <asm/gpio.h>
+ 
+ #define MTX1_WDT_INTERVAL	(5 * HZ)
+ 
+@@ -61,6 +64,7 @@ static struct {
+ 	volatile int queue;
+ 	int default_ticks;
+ 	unsigned long inuse;
++	unsigned gpio;
+ } mtx1_wdt_device;
+ 
+ static void mtx1_wdt_trigger(unsigned long unused)
+@@ -73,7 +77,8 @@ static void mtx1_wdt_trigger(unsigned long unused)
+ 	 * toggle GPIO2_15
+ 	 */
+ 	tmp = au_readl(GPIO2_DIR);
+-	tmp = (tmp & ~(1<<15)) | ((~tmp) & (1<<15));
++	tmp = (tmp & ~(1 << mtx1_wdt_device.gpio)) |
++	      ((~tmp) & (1 << mtx1_wdt_device.gpio));
+ 	au_writel (tmp, GPIO2_DIR);
+ 
+ 	if (mtx1_wdt_device.queue && ticks)
+@@ -93,7 +98,7 @@ static void mtx1_wdt_start(void)
+ {
+ 	if (!mtx1_wdt_device.queue) {
+ 		mtx1_wdt_device.queue = 1;
+-		au_writel (au_readl(GPIO2_DIR) | (u32)(1<<15), GPIO2_DIR);
++		gpio_set_value(mtx1_wdt_device.gpio, 1);
+ 		mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL);
+ 	}
+ 	mtx1_wdt_device.running++;
+@@ -103,7 +108,7 @@ static int mtx1_wdt_stop(void)
+ {
+ 	if (mtx1_wdt_device.queue) {
+ 		mtx1_wdt_device.queue = 0;
+-		au_writel (au_readl(GPIO2_DIR) & ~((u32)(1<<15)), GPIO2_DIR);
++		gpio_set_value(mtx1_wdt_device.gpio, 0);
+ 	}
+ 
+ 	ticks = mtx1_wdt_device.default_ticks;
+@@ -197,10 +202,12 @@ static struct miscdevice mtx1_wdt_misc = {
+ };
+ 
+ 
+-static int __init mtx1_wdt_init(void)
++static int mtx1_wdt_probe(struct platform_device *pdev)
+ {
+ 	int ret;
+ 
++	mtx1_wdt_device.gpio = pdev->resource[0].start;
++
+ 	if ((ret = misc_register(&mtx1_wdt_misc)) < 0) {
+ 		printk(KERN_ERR " mtx-1_wdt : failed to register\n");
+ 		return ret;
+@@ -222,13 +229,30 @@ static int __init mtx1_wdt_init(void)
+ 	return 0;
+ }
+ 
+-static void __exit mtx1_wdt_exit(void)
++static int mtx1_wdt_remove(struct platform_device *pdev)
+ {
+ 	if (mtx1_wdt_device.queue) {
+ 		mtx1_wdt_device.queue = 0;
+ 		wait_for_completion(&mtx1_wdt_device.stop);
+ 	}
+ 	misc_deregister(&mtx1_wdt_misc);
++	return 0;
++}
++
++static struct platform_driver mtx1_wdt = {
++	.probe = mtx1_wdt_probe,
++	.remove = mtx1_wdt_remove,
++	.driver.name = "mtx1-wdt",
++};
++
++static int __init mtx1_wdt_init(void)
++{
++	return platform_driver_register(&mtx1_wdt);
++}
++
++static void __exit mtx1_wdt_exit(void)
++{
++	platform_driver_unregister(&mtx1_wdt);
+ }
+ 
+ module_init(mtx1_wdt_init);
+@@ -237,3 +261,4 @@ module_exit(mtx1_wdt_exit);
+ MODULE_AUTHOR("Michael Stickel, Florian Fainelli");
+ MODULE_DESCRIPTION("Driver for the MTX-1 watchdog");
+ MODULE_LICENSE("GPL");
++MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c
+new file mode 100644
+index 0000000..b944314
+--- /dev/null
++++ b/drivers/watchdog/sb_wdog.c
+@@ -0,0 +1,353 @@
++/*
++ * Watchdog driver for SiByte SB1 SoCs
++ *
++ * Copyright (C) 2007 OnStor, Inc. * Andrew Sharp <andy.sharp at onstor.com>
++ *
++ * This driver is intended to make the second of two hardware watchdogs
++ * on the Sibyte 12XX and 11XX SoCs available to the user.  There are two
++ * such devices available on the SoC, but it seems that there isn't an
++ * enumeration class for watchdogs in Linux like there is for RTCs.
++ * The second is used rather than the first because it uses IRQ 1,
++ * thereby avoiding all that IRQ 0 problematic nonsense.
++ *
++ * I have not tried this driver on a 1480 processor; it might work
++ * just well enough to really screw things up.
++ *
++ * It is a simple timer, and there is an interrupt that is raised the
++ * first time the timer expires.  The second time it expires, the chip
++ * is reset and there is no way to redirect that NMI.  Which could
++ * be problematic in some cases where this chip is sitting on the HT
++ * bus and has just taken responsibility for providing a cache block.
++ * Since the reset can't be redirected to the external reset pin, it is
++ * possible that other HT connected processors might hang and not reset.
++ * For Linux, a soft reset would probably be even worse than a hard reset.
++ * There you have it.
++ *
++ * The timer takes 23 bits of a 64 bit register (?) as a count value,
++ * and decrements the count every microsecond, for a max value of
++ * 0x7fffff usec or about 8.3ish seconds.
++ *
++ * This watchdog borrows some user semantics from the softdog driver,
++ * in that if you close the fd, it leaves the watchdog running, unless
++ * you previously wrote a 'V' to the fd, in which case it disables
++ * the watchdog when you close the fd like some other drivers.
++ *
++ * Based on various other watchdog drivers, which are probably all
++ * loosely based on something Alan Cox wrote years ago.
++ *
++ *	(c) Copyright 1996 Alan Cox <alan at redhat.com>, All Rights Reserved.
++ *				http://www.redhat.com
++ *
++ *	This program is free software; you can redistribute it and/or
++ *	modify it under the terms of the GNU General Public License
++ *	version 1 or 2 as published by the Free Software Foundation.
++ *
++ */
++#include <linux/module.h>
++#include <linux/io.h>
++#include <linux/uaccess.h>
++#include <linux/fs.h>
++#include <linux/reboot.h>
++#include <linux/miscdevice.h>
++#include <linux/watchdog.h>
++#include <linux/interrupt.h>
++
++#include <asm/sibyte/sb1250.h>
++#include <asm/sibyte/sb1250_regs.h>
++#include <asm/sibyte/sb1250_int.h>
++#include <asm/sibyte/sb1250_scd.h>
++
++
++/*
++ * set the initial count value of a timer
++ *
++ * wdog is the iomem address of the cfg register
++ */
++void sbwdog_set(char __iomem *wdog, unsigned long t)
++{
++	__raw_writeb(0, wdog - 0x10);
++	__raw_writeq(t & 0x7fffffUL, wdog);
++}
++
++/*
++ * cause the timer to [re]load it's initial count and start counting
++ * all over again
++ *
++ * wdog is the iomem address of the cfg register
++ */
++void sbwdog_pet(char __iomem *wdog)
++{
++	__raw_writeb(__raw_readb(wdog) | 1, wdog);
++}
++
++static unsigned long sbwdog_gate; /* keeps it to one thread only */
++static char __iomem *kern_dog = (char __iomem *)(IO_BASE + (A_SCD_WDOG_CFG_0));
++static char __iomem *user_dog = (char __iomem *)(IO_BASE + (A_SCD_WDOG_CFG_1));
++static unsigned long timeout = 0x7fffffUL;	/* useconds: 8.3ish secs. */
++static int expect_close;
++
++static struct watchdog_info ident = {
++	.options	= WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
++	.identity	= "SiByte Watchdog",
++};
++
++/*
++ * Allow only a single thread to walk the dog
++ */
++static int sbwdog_open(struct inode *inode, struct file *file)
++{
++	nonseekable_open(inode, file);
++	if (test_and_set_bit(0, &sbwdog_gate)) {
++		return -EBUSY;
++	}
++	__module_get(THIS_MODULE);
++
++	/*
++	 * Activate the timer
++	 */
++	sbwdog_set(user_dog, timeout);
++	__raw_writeb(1, user_dog);
++
++	return 0;
++}
++
++/*
++ * Put the dog back in the kennel.
++ */
++static int sbwdog_release(struct inode *inode, struct file *file)
++{
++	if (expect_close == 42) {
++		__raw_writeb(0, user_dog);
++		module_put(THIS_MODULE);
++	} else {
++		printk(KERN_CRIT "%s: Unexpected close, not stopping watchdog!\n",
++			ident.identity);
++		sbwdog_pet(user_dog);
++	}
++	clear_bit(0, &sbwdog_gate);
++	expect_close = 0;
++
++	return 0;
++}
++
++/*
++ * 42 - the answer
++ */
++static ssize_t sbwdog_write(struct file *file, const char __user *data,
++			size_t len, loff_t *ppos)
++{
++	int i;
++
++	if (len) {
++		/*
++		 * restart the timer
++		 */
++		expect_close = 0;
++
++		for (i = 0; i != len; i++) {
++			char c;
++
++			if (get_user(c, data + i)) {
++				return -EFAULT;
++			}
++			if (c == 'V') {
++				expect_close = 42;
++			}
++		}
++		sbwdog_pet(user_dog);
++	}
++
++	return len;
++}
++
++static int sbwdog_ioctl(struct inode *inode, struct file *file,
++			unsigned int cmd, unsigned long arg)
++{
++	int ret = -ENOTTY;
++	unsigned long time;
++	void __user *argp = (void __user *)arg;
++	int __user *p = argp;
++
++	switch (cmd) {
++	case WDIOC_GETSUPPORT:
++		ret = copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
++		break;
++
++	case WDIOC_GETSTATUS:
++	case WDIOC_GETBOOTSTATUS:
++		ret = put_user(0, p);
++		break;
++
++	case WDIOC_SETTIMEOUT:
++		ret = get_user(time, p);
++		if (ret) {
++			break;
++		}
++
++		time *= 1000000;
++		if (time > 0x7fffffUL) {
++			ret = -EINVAL;
++			break;
++		}
++		timeout = time;
++		sbwdog_set(user_dog, timeout);
++		sbwdog_pet(user_dog);
++
++	case WDIOC_GETTIMEOUT:
++		/*
++		 * get the remaining count from the ... count register
++		 * which is 1*8 before the config register
++		 */
++		ret = put_user(__raw_readq(user_dog - 8) / 1000000, p);
++		break;
++
++	case WDIOC_KEEPALIVE:
++		sbwdog_pet(user_dog);
++		ret = 0;
++		break;
++	}
++	return ret;
++}
++
++/*
++ *	Notifier for system down
++ */
++static int
++sbwdog_notify_sys(struct notifier_block *this, unsigned long code, void *erf)
++{
++	if (code == SYS_DOWN || code == SYS_HALT) {
++		/*
++		 * sit and sit
++		 */
++		__raw_writeb(0, user_dog);
++		__raw_writeb(0, kern_dog);
++	}
++
++	return NOTIFY_DONE;
++}
++
++static const struct file_operations sbwdog_fops =
++{
++	.owner		= THIS_MODULE,
++	.llseek		= no_llseek,
++	.write		= sbwdog_write,
++	.ioctl		= sbwdog_ioctl,
++	.open		= sbwdog_open,
++	.release	= sbwdog_release,
++};
++
++static struct miscdevice sbwdog_miscdev =
++{
++	.minor		= WATCHDOG_MINOR,
++	.name		= "watchdog",
++	.fops		= &sbwdog_fops,
++};
++
++static struct notifier_block sbwdog_notifier = {
++	.notifier_call	= sbwdog_notify_sys,
++};
++
++/*
++ * interrupt handler
++ *
++ * doesn't do a whole lot for user, but oh so cleverly written so kernel
++ * code can use it to re-up the watchdog, thereby saving the kernel from
++ * having to create and maintain a timer, just to tickle another timer,
++ * which is just so wrong.
++ */
++irqreturn_t sbwdog_interrupt(int irq, void *addr)
++{
++	unsigned long wd_init;
++	char *wd_cfg_reg = (char *)addr;
++	u8 cfg;
++
++	cfg = __raw_readb(wd_cfg_reg);
++	wd_init = __raw_readq(wd_cfg_reg - 8) & 0x7fffff;
++
++	/*
++	 * if it's the second watchdog timer, it's for those users
++	 */
++	if (wd_cfg_reg == user_dog) {
++		printk(KERN_CRIT
++			"%s in danger of initiating system reset in %ld.%01ld seconds\n",
++			ident.identity, wd_init / 1000000, (wd_init / 100000) % 10);
++	} else {
++		cfg |= 1;
++	}
++
++	__raw_writeb(cfg, wd_cfg_reg);
++
++	return IRQ_HANDLED;
++}
++
++static int __init sbwdog_init(void)
++{
++	int ret;
++
++	/*
++	 * register a reboot notifier
++	 */
++	ret = register_reboot_notifier(&sbwdog_notifier);
++	if (ret) {
++		printk (KERN_ERR "%s: cannot register reboot notifier (err=%d)\n",
++			ident.identity, ret);
++		return ret;
++	}
++
++	/*
++	 * get the resources
++	 */
++	ret = misc_register(&sbwdog_miscdev);
++	if (ret == 0) {
++		printk(KERN_INFO "%s: timeout is %ld.%ld secs\n", ident.identity,
++			timeout / 1000000, (timeout / 100000) % 10);
++	}
++
++	ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED,
++		ident.identity, (void *)user_dog);
++	if (ret) {
++		printk(KERN_ERR "%s: failed to request irq 1 - %d\n", ident.identity,
++			ret);
++		misc_deregister(&sbwdog_miscdev);
++	}
++
++	return ret;
++}
++
++static void __exit sbwdog_exit(void)
++{
++	misc_deregister(&sbwdog_miscdev);
++}
++
++module_init(sbwdog_init);
++module_exit(sbwdog_exit);
++
++MODULE_AUTHOR("Andrew Sharp <andy.sharp at onstor.com>");
++MODULE_DESCRIPTION("SiByte Watchdog");
++
++module_param(timeout, ulong, 0);
++MODULE_PARM_DESC(timeout,
++	"Watchdog timeout in microseconds (max/default 8388607 or 8.3ish secs)");
++
++MODULE_LICENSE("GPL");
++MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
++
++/*
++ * example code that can be put in a platform code area to utilize the
++ * first watchdog timer for the kernels own purpose.
++
++ void
++platform_wd_setup(void)
++{
++	int ret;
++
++	ret = request_irq(0, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED,
++		"Kernel Watchdog", IOADDR(A_SCD_WDOG_CFG_0));
++	if (ret) {
++		printk(KERN_CRIT "Watchdog IRQ zero(0) failed to be requested - %d\n",
++			ret);
++	}
++}
++
++
++ */
+diff --git a/fs/bio.c b/fs/bio.c
+index 242e409..3312fcc 100644
+--- a/fs/bio.c
++++ b/fs/bio.c
+@@ -903,7 +903,7 @@ void bio_set_pages_dirty(struct bio *bio)
+ 	}
+ }
+ 
+-void bio_release_pages(struct bio *bio)
++static void bio_release_pages(struct bio *bio)
+ {
+ 	struct bio_vec *bvec = bio->bi_io_vec;
+ 	int i;
+diff --git a/fs/block_dev.c b/fs/block_dev.c
+index 67fe72c..7d822fa 100644
+--- a/fs/block_dev.c
++++ b/fs/block_dev.c
+@@ -31,6 +31,8 @@ struct bdev_inode {
+ 	struct inode vfs_inode;
+ };
+ 
++static const struct address_space_operations def_blk_aops;
++
+ static inline struct bdev_inode *BDEV_I(struct inode *inode)
+ {
+ 	return container_of(inode, struct bdev_inode, vfs_inode);
+@@ -171,203 +173,6 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
+ 				iov, offset, nr_segs, blkdev_get_blocks, NULL);
+ }
+ 
+-#if 0
+-static void blk_end_aio(struct bio *bio, int error)
+-{
+-	struct kiocb *iocb = bio->bi_private;
+-	atomic_t *bio_count = &iocb->ki_bio_count;
+-
+-	if (bio_data_dir(bio) == READ)
+-		bio_check_pages_dirty(bio);
+-	else {
+-		bio_release_pages(bio);
+-		bio_put(bio);
+-	}
+-
+-	/* iocb->ki_nbytes stores error code from LLDD */
+-	if (error)
+-		iocb->ki_nbytes = -EIO;
+-
+-	if (atomic_dec_and_test(bio_count)) {
+-		if ((long)iocb->ki_nbytes < 0)
+-			aio_complete(iocb, iocb->ki_nbytes, 0);
+-		else
+-			aio_complete(iocb, iocb->ki_left, 0);
+-	}
+-
+-	return 0;
+-}
+-
+-#define VEC_SIZE	16
+-struct pvec {
+-	unsigned short nr;
+-	unsigned short idx;
+-	struct page *page[VEC_SIZE];
+-};
+-
+-#define PAGES_SPANNED(addr, len)	\
+-	(DIV_ROUND_UP((addr) + (len), PAGE_SIZE) - (addr) / PAGE_SIZE);
+-
+-/*
+- * get page pointer for user addr, we internally cache struct page array for
+- * (addr, count) range in pvec to avoid frequent call to get_user_pages.  If
+- * internal page list is exhausted, a batch count of up to VEC_SIZE is used
+- * to get next set of page struct.
+- */
+-static struct page *blk_get_page(unsigned long addr, size_t count, int rw,
+-				 struct pvec *pvec)
+-{
+-	int ret, nr_pages;
+-	if (pvec->idx == pvec->nr) {
+-		nr_pages = PAGES_SPANNED(addr, count);
+-		nr_pages = min(nr_pages, VEC_SIZE);
+-		down_read(&current->mm->mmap_sem);
+-		ret = get_user_pages(current, current->mm, addr, nr_pages,
+-				     rw == READ, 0, pvec->page, NULL);
+-		up_read(&current->mm->mmap_sem);
+-		if (ret < 0)
+-			return ERR_PTR(ret);
+-		pvec->nr = ret;
+-		pvec->idx = 0;
+-	}
+-	return pvec->page[pvec->idx++];
+-}
+-
+-/* return a page back to pvec array */
+-static void blk_unget_page(struct page *page, struct pvec *pvec)
+-{
+-	pvec->page[--pvec->idx] = page;
+-}
+-
+-static ssize_t
+-blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
+-		 loff_t pos, unsigned long nr_segs)
+-{
+-	struct inode *inode = iocb->ki_filp->f_mapping->host;
+-	unsigned blkbits = blksize_bits(bdev_hardsect_size(I_BDEV(inode)));
+-	unsigned blocksize_mask = (1 << blkbits) - 1;
+-	unsigned long seg = 0;	/* iov segment iterator */
+-	unsigned long nvec;	/* number of bio vec needed */
+-	unsigned long cur_off;	/* offset into current page */
+-	unsigned long cur_len;	/* I/O len of current page, up to PAGE_SIZE */
+-
+-	unsigned long addr;	/* user iovec address */
+-	size_t count;		/* user iovec len */
+-	size_t nbytes = iocb->ki_nbytes = iocb->ki_left; /* total xfer size */
+-	loff_t size;		/* size of block device */
+-	struct bio *bio;
+-	atomic_t *bio_count = &iocb->ki_bio_count;
+-	struct page *page;
+-	struct pvec pvec;
+-
+-	pvec.nr = 0;
+-	pvec.idx = 0;
+-
+-	if (pos & blocksize_mask)
+-		return -EINVAL;
+-
+-	size = i_size_read(inode);
+-	if (pos + nbytes > size) {
+-		nbytes = size - pos;
+-		iocb->ki_left = nbytes;
+-	}
+-
+-	/*
+-	 * check first non-zero iov alignment, the remaining
+-	 * iov alignment is checked inside bio loop below.
+-	 */
+-	do {
+-		addr = (unsigned long) iov[seg].iov_base;
+-		count = min(iov[seg].iov_len, nbytes);
+-		if (addr & blocksize_mask || count & blocksize_mask)
+-			return -EINVAL;
+-	} while (!count && ++seg < nr_segs);
+-	atomic_set(bio_count, 1);
+-
+-	while (nbytes) {
+-		/* roughly estimate number of bio vec needed */
+-		nvec = (nbytes + PAGE_SIZE - 1) / PAGE_SIZE;
+-		nvec = max(nvec, nr_segs - seg);
+-		nvec = min(nvec, (unsigned long) BIO_MAX_PAGES);
+-
+-		/* bio_alloc should not fail with GFP_KERNEL flag */
+-		bio = bio_alloc(GFP_KERNEL, nvec);
+-		bio->bi_bdev = I_BDEV(inode);
+-		bio->bi_end_io = blk_end_aio;
+-		bio->bi_private = iocb;
+-		bio->bi_sector = pos >> blkbits;
+-same_bio:
+-		cur_off = addr & ~PAGE_MASK;
+-		cur_len = PAGE_SIZE - cur_off;
+-		if (count < cur_len)
+-			cur_len = count;
+-
+-		page = blk_get_page(addr, count, rw, &pvec);
+-		if (unlikely(IS_ERR(page)))
+-			goto backout;
+-
+-		if (bio_add_page(bio, page, cur_len, cur_off)) {
+-			pos += cur_len;
+-			addr += cur_len;
+-			count -= cur_len;
+-			nbytes -= cur_len;
+-
+-			if (count)
+-				goto same_bio;
+-			while (++seg < nr_segs) {
+-				addr = (unsigned long) iov[seg].iov_base;
+-				count = iov[seg].iov_len;
+-				if (!count)
+-					continue;
+-				if (unlikely(addr & blocksize_mask ||
+-					     count & blocksize_mask)) {
+-					page = ERR_PTR(-EINVAL);
+-					goto backout;
+-				}
+-				count = min(count, nbytes);
+-				goto same_bio;
+-			}
+-		} else {
+-			blk_unget_page(page, &pvec);
+-		}
+-
+-		/* bio is ready, submit it */
+-		if (rw == READ)
+-			bio_set_pages_dirty(bio);
+-		atomic_inc(bio_count);
+-		submit_bio(rw, bio);
+-	}
+-
+-completion:
+-	iocb->ki_left -= nbytes;
+-	nbytes = iocb->ki_left;
+-	iocb->ki_pos += nbytes;
+-
+-	blk_run_address_space(inode->i_mapping);
+-	if (atomic_dec_and_test(bio_count))
+-		aio_complete(iocb, nbytes, 0);
+-
+-	return -EIOCBQUEUED;
+-
+-backout:
+-	/*
+-	 * back out nbytes count constructed so far for this bio,
+-	 * we will throw away current bio.
+-	 */
+-	nbytes += bio->bi_size;
+-	bio_release_pages(bio);
+-	bio_put(bio);
+-
+-	/*
+-	 * if no bio was submmitted, return the error code.
+-	 * otherwise, proceed with pending I/O completion.
+-	 */
+-	if (atomic_read(bio_count) == 1)
+-		return PTR_ERR(page);
+-	goto completion;
+-}
+-#endif
+-
+ static int blkdev_writepage(struct page *page, struct writeback_control *wbc)
+ {
+ 	return block_write_full_page(page, blkdev_get_block, wbc);
+@@ -1334,7 +1139,7 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg)
+ 	return blkdev_ioctl(file->f_mapping->host, file, cmd, arg);
+ }
+ 
+-const struct address_space_operations def_blk_aops = {
++static const struct address_space_operations def_blk_aops = {
+ 	.readpage	= blkdev_readpage,
+ 	.writepage	= blkdev_writepage,
+ 	.sync_page	= block_sync_page,
+diff --git a/fs/xfs/Kbuild b/fs/xfs/Kbuild
+deleted file mode 100644
+index 2566e96..0000000
+--- a/fs/xfs/Kbuild
++++ /dev/null
+@@ -1,6 +0,0 @@
+-#
+-# The xfs people like to share Makefile with 2.6 and 2.4.
+-# Utilise file named Kbuild file which has precedence over Makefile.
+-#
+-
+-include $(srctree)/$(obj)/Makefile-linux-2.6
+diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
+index 49e3e7e..36ec614 100644
+--- a/fs/xfs/Makefile
++++ b/fs/xfs/Makefile
+@@ -1 +1,117 @@
+-include $(TOPDIR)/fs/xfs/Makefile-linux-$(VERSION).$(PATCHLEVEL)
++#
++# Copyright (c) 2000-2005 Silicon Graphics, Inc.
++# All Rights Reserved.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of the GNU General Public License as
++# published by the Free Software Foundation.
++#
++# This program is distributed in the hope that it would 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 the Free Software Foundation,
++# Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++#
++
++EXTRA_CFLAGS +=	 -I$(src) -I$(src)/linux-2.6 -funsigned-char
++
++XFS_LINUX := linux-2.6
++
++ifeq ($(CONFIG_XFS_DEBUG),y)
++	EXTRA_CFLAGS += -g
++endif
++
++obj-$(CONFIG_XFS_FS)		+= xfs.o
++
++xfs-$(CONFIG_XFS_QUOTA)		+= $(addprefix quota/, \
++				   xfs_dquot.o \
++				   xfs_dquot_item.o \
++				   xfs_trans_dquot.o \
++				   xfs_qm_syscalls.o \
++				   xfs_qm_bhv.o \
++				   xfs_qm.o)
++
++ifeq ($(CONFIG_XFS_QUOTA),y)
++xfs-$(CONFIG_PROC_FS)		+= quota/xfs_qm_stats.o
++endif
++
++xfs-$(CONFIG_XFS_RT)		+= xfs_rtalloc.o
++xfs-$(CONFIG_XFS_POSIX_ACL)	+= xfs_acl.o
++xfs-$(CONFIG_PROC_FS)		+= $(XFS_LINUX)/xfs_stats.o
++xfs-$(CONFIG_SYSCTL)		+= $(XFS_LINUX)/xfs_sysctl.o
++xfs-$(CONFIG_COMPAT)		+= $(XFS_LINUX)/xfs_ioctl32.o
++
++
++xfs-y				+= xfs_alloc.o \
++				   xfs_alloc_btree.o \
++				   xfs_attr.o \
++				   xfs_attr_leaf.o \
++				   xfs_bit.o \
++				   xfs_bmap.o \
++				   xfs_bmap_btree.o \
++				   xfs_btree.o \
++				   xfs_buf_item.o \
++				   xfs_da_btree.o \
++				   xfs_dir2.o \
++				   xfs_dir2_block.o \
++				   xfs_dir2_data.o \
++				   xfs_dir2_leaf.o \
++				   xfs_dir2_node.o \
++				   xfs_dir2_sf.o \
++				   xfs_error.o \
++				   xfs_extfree_item.o \
++				   xfs_filestream.o \
++				   xfs_fsops.o \
++				   xfs_ialloc.o \
++				   xfs_ialloc_btree.o \
++				   xfs_iget.o \
++				   xfs_inode.o \
++				   xfs_inode_item.o \
++				   xfs_iomap.o \
++				   xfs_itable.o \
++				   xfs_dfrag.o \
++				   xfs_log.o \
++				   xfs_log_recover.o \
++				   xfs_mount.o \
++				   xfs_mru_cache.o \
++				   xfs_rename.o \
++				   xfs_trans.o \
++				   xfs_trans_ail.o \
++				   xfs_trans_buf.o \
++				   xfs_trans_extfree.o \
++				   xfs_trans_inode.o \
++				   xfs_trans_item.o \
++				   xfs_utils.o \
++				   xfs_vfsops.o \
++				   xfs_vnodeops.o \
++				   xfs_rw.o \
++				   xfs_dmops.o \
++				   xfs_qmops.o
++
++xfs-$(CONFIG_XFS_TRACE)		+= xfs_dir2_trace.o
++
++# Objects in linux/
++xfs-y				+= $(addprefix $(XFS_LINUX)/, \
++				   kmem.o \
++				   xfs_aops.o \
++				   xfs_buf.o \
++				   xfs_export.o \
++				   xfs_file.o \
++				   xfs_fs_subr.o \
++				   xfs_globals.o \
++				   xfs_ioctl.o \
++				   xfs_iops.o \
++				   xfs_lrw.o \
++				   xfs_super.o \
++				   xfs_vnode.o)
++
++# Objects in support/
++xfs-y				+= $(addprefix support/, \
++				   debug.o \
++				   uuid.o)
++
++xfs-$(CONFIG_XFS_TRACE)		+= support/ktrace.o
++
+diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6
+deleted file mode 100644
+index 9731645..0000000
+--- a/fs/xfs/Makefile-linux-2.6
++++ /dev/null
+@@ -1,117 +0,0 @@
+-#
+-# Copyright (c) 2000-2005 Silicon Graphics, Inc.
+-# All Rights Reserved.
+-#
+-# This program is free software; you can redistribute it and/or
+-# modify it under the terms of the GNU General Public License as
+-# published by the Free Software Foundation.
+-#
+-# This program is distributed in the hope that it would 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 the Free Software Foundation,
+-# Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+-#
+-
+-EXTRA_CFLAGS +=	 -Ifs/xfs -Ifs/xfs/linux-2.6 -funsigned-char
+-
+-XFS_LINUX := linux-2.6
+-
+-ifeq ($(CONFIG_XFS_DEBUG),y)
+-	EXTRA_CFLAGS += -g
+-endif
+-
+-obj-$(CONFIG_XFS_FS)		+= xfs.o
+-
+-xfs-$(CONFIG_XFS_QUOTA)		+= $(addprefix quota/, \
+-				   xfs_dquot.o \
+-				   xfs_dquot_item.o \
+-				   xfs_trans_dquot.o \
+-				   xfs_qm_syscalls.o \
+-				   xfs_qm_bhv.o \
+-				   xfs_qm.o)
+-
+-ifeq ($(CONFIG_XFS_QUOTA),y)
+-xfs-$(CONFIG_PROC_FS)		+= quota/xfs_qm_stats.o
+-endif
+-
+-xfs-$(CONFIG_XFS_RT)		+= xfs_rtalloc.o
+-xfs-$(CONFIG_XFS_POSIX_ACL)	+= xfs_acl.o
+-xfs-$(CONFIG_PROC_FS)		+= $(XFS_LINUX)/xfs_stats.o
+-xfs-$(CONFIG_SYSCTL)		+= $(XFS_LINUX)/xfs_sysctl.o
+-xfs-$(CONFIG_COMPAT)		+= $(XFS_LINUX)/xfs_ioctl32.o
+-
+-
+-xfs-y				+= xfs_alloc.o \
+-				   xfs_alloc_btree.o \
+-				   xfs_attr.o \
+-				   xfs_attr_leaf.o \
+-				   xfs_bit.o \
+-				   xfs_bmap.o \
+-				   xfs_bmap_btree.o \
+-				   xfs_btree.o \
+-				   xfs_buf_item.o \
+-				   xfs_da_btree.o \
+-				   xfs_dir2.o \
+-				   xfs_dir2_block.o \
+-				   xfs_dir2_data.o \
+-				   xfs_dir2_leaf.o \
+-				   xfs_dir2_node.o \
+-				   xfs_dir2_sf.o \
+-				   xfs_error.o \
+-				   xfs_extfree_item.o \
+-				   xfs_filestream.o \
+-				   xfs_fsops.o \
+-				   xfs_ialloc.o \
+-				   xfs_ialloc_btree.o \
+-				   xfs_iget.o \
+-				   xfs_inode.o \
+-				   xfs_inode_item.o \
+-				   xfs_iomap.o \
+-				   xfs_itable.o \
+-				   xfs_dfrag.o \
+-				   xfs_log.o \
+-				   xfs_log_recover.o \
+-				   xfs_mount.o \
+-				   xfs_mru_cache.o \
+-				   xfs_rename.o \
+-				   xfs_trans.o \
+-				   xfs_trans_ail.o \
+-				   xfs_trans_buf.o \
+-				   xfs_trans_extfree.o \
+-				   xfs_trans_inode.o \
+-				   xfs_trans_item.o \
+-				   xfs_utils.o \
+-				   xfs_vfsops.o \
+-				   xfs_vnodeops.o \
+-				   xfs_rw.o \
+-				   xfs_dmops.o \
+-				   xfs_qmops.o
+-
+-xfs-$(CONFIG_XFS_TRACE)		+= xfs_dir2_trace.o
+-
+-# Objects in linux/
+-xfs-y				+= $(addprefix $(XFS_LINUX)/, \
+-				   kmem.o \
+-				   xfs_aops.o \
+-				   xfs_buf.o \
+-				   xfs_export.o \
+-				   xfs_file.o \
+-				   xfs_fs_subr.o \
+-				   xfs_globals.o \
+-				   xfs_ioctl.o \
+-				   xfs_iops.o \
+-				   xfs_lrw.o \
+-				   xfs_super.o \
+-				   xfs_vnode.o)
+-
+-# Objects in support/
+-xfs-y				+= $(addprefix support/, \
+-				   debug.o \
+-				   uuid.o)
+-
+-xfs-$(CONFIG_XFS_TRACE)		+= support/ktrace.o
+-
+diff --git a/include/asm-frv/unistd.h b/include/asm-frv/unistd.h
+index e8c9866..f184eb8 100644
+--- a/include/asm-frv/unistd.h
++++ b/include/asm-frv/unistd.h
+@@ -328,9 +328,11 @@
+ #define __NR_epoll_pwait	319
+ #define __NR_utimensat		320
+ #define __NR_signalfd		321
+-/* #define __NR_timerfd		322 removed */
++#define __NR_timerfd_create	322
+ #define __NR_eventfd		323
+ #define __NR_fallocate		324
++#define __NR_timerfd_settime	325
++#define __NR_timerfd_gettime	326
+ 
+ #ifdef __KERNEL__
+ 
+diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
+index f784d2f..f054778 100644
+--- a/include/asm-generic/vmlinux.lds.h
++++ b/include/asm-generic/vmlinux.lds.h
+@@ -238,6 +238,9 @@
+ 		*(.kprobes.text)					\
+ 		VMLINUX_SYMBOL(__kprobes_text_end) = .;
+ 
++/* Section used for early init (in .S files) */
++#define HEAD_TEXT  *(.head.text)
++
+ /* init and exit section handling */
+ #define INIT_DATA							\
+ 	*(.init.data)							\
+diff --git a/include/asm-mips/mach-ip27/dma-coherence.h b/include/asm-mips/mach-ip27/dma-coherence.h
+index 3fdbbf6..ed7e622 100644
+--- a/include/asm-mips/mach-ip27/dma-coherence.h
++++ b/include/asm-mips/mach-ip27/dma-coherence.h
+@@ -35,7 +35,7 @@ static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
+ 
+ static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+ {
+-	return dma_addr & (0xffUL << 56);
++	return dma_addr & ~(0xffUL << 56);
+ }
+ 
+ static inline void plat_unmap_dma_mem(dma_addr_t dma_addr)
+diff --git a/include/asm-mips/qemu.h b/include/asm-mips/qemu.h
+deleted file mode 100644
+index 487ced4..0000000
+--- a/include/asm-mips/qemu.h
++++ /dev/null
+@@ -1,30 +0,0 @@
+-/*
+- * This file is subject to the terms and conditions of the GNU General Public
+- * License.  See the file "COPYING" in the main directory of this archive
+- * for more details.
+- *
+- * Copyright (C) 2005 by Ralf Baechle (ralf at linux-mips.org)
+- */
+-#ifndef __ASM_QEMU_H
+-#define __ASM_QEMU_H
+-
+-/*
+- * Interrupt numbers
+- */
+-#define Q_PIC_IRQ_BASE		0
+-#define Q_COUNT_COMPARE_IRQ	23
+-
+-/*
+- * Qemu clock rate.  Unlike on real MIPS this has no relation to the
+- * instruction issue rate, so the choosen value is pure fiction, just needs
+- * to match the value in Qemu itself.
+- */
+-#define QEMU_C0_COUNTER_CLOCK	100000000
+-
+-/*
+- * Magic qemu system control location.
+- */
+-#define QEMU_RESTART_REG	0xBFBF0000
+-#define QEMU_HALT_REG		0xBFBF0004
+-
+-#endif /* __ASM_QEMU_H */
+diff --git a/include/asm-mips/sni.h b/include/asm-mips/sni.h
+index e716447..8c1eb02 100644
+--- a/include/asm-mips/sni.h
++++ b/include/asm-mips/sni.h
+@@ -228,7 +228,14 @@ extern void sni_pcimt_irq_init(void);
+ extern void sni_cpu_time_init(void);
+ 
+ /* eisa init for RM200/400 */
++#ifdef CONFIG_EISA
+ extern int sni_eisa_root_init(void);
++#else
++static inline int sni_eisa_root_init(void)
++{
++	return 0;
++}
++#endif
+ 
+ /* common irq stuff */
+ extern void (*sni_hwint)(void);
+diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h
+index fa9a587..4964c82 100644
+--- a/include/asm-mips/unistd.h
++++ b/include/asm-mips/unistd.h
+@@ -341,16 +341,19 @@
+ #define __NR_timerfd			(__NR_Linux + 318)
+ #define __NR_eventfd			(__NR_Linux + 319)
+ #define __NR_fallocate			(__NR_Linux + 320)
++#define __NR_timerfd_create		(__NR_Linux + 321)
++#define __NR_timerfd_gettime		(__NR_Linux + 322)
++#define __NR_timerfd_settime		(__NR_Linux + 323)
+ 
+ /*
+  * Offset of the last Linux o32 flavoured syscall
+  */
+-#define __NR_Linux_syscalls		320
++#define __NR_Linux_syscalls		323
+ 
+ #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
+ 
+ #define __NR_O32_Linux			4000
+-#define __NR_O32_Linux_syscalls		320
++#define __NR_O32_Linux_syscalls		323
+ 
+ #if _MIPS_SIM == _MIPS_SIM_ABI64
+ 
+@@ -638,16 +641,19 @@
+ #define __NR_timerfd			(__NR_Linux + 277)
+ #define __NR_eventfd			(__NR_Linux + 278)
+ #define __NR_fallocate			(__NR_Linux + 279)
++#define __NR_timerfd_create		(__NR_Linux + 280)
++#define __NR_timerfd_gettime		(__NR_Linux + 281)
++#define __NR_timerfd_settime		(__NR_Linux + 282)
+ 
+ /*
+  * Offset of the last Linux 64-bit flavoured syscall
+  */
+-#define __NR_Linux_syscalls		279
++#define __NR_Linux_syscalls		282
+ 
+ #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
+ 
+ #define __NR_64_Linux			5000
+-#define __NR_64_Linux_syscalls		279
++#define __NR_64_Linux_syscalls		282
+ 
+ #if _MIPS_SIM == _MIPS_SIM_NABI32
+ 
+@@ -939,16 +945,19 @@
+ #define __NR_timerfd			(__NR_Linux + 281)
+ #define __NR_eventfd			(__NR_Linux + 282)
+ #define __NR_fallocate			(__NR_Linux + 283)
++#define __NR_timerfd_create		(__NR_Linux + 284)
++#define __NR_timerfd_gettime		(__NR_Linux + 285)
++#define __NR_timerfd_settime		(__NR_Linux + 286)
+ 
+ /*
+  * Offset of the last N32 flavoured syscall
+  */
+-#define __NR_Linux_syscalls		283
++#define __NR_Linux_syscalls		286
+ 
+ #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
+ 
+ #define __NR_N32_Linux			6000
+-#define __NR_N32_Linux_syscalls		283
++#define __NR_N32_Linux_syscalls		286
+ 
+ #ifdef __KERNEL__
+ 
+diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h
+index ab83c84..965394e 100644
+--- a/include/asm-s390/bitops.h
++++ b/include/asm-s390/bitops.h
+@@ -456,16 +456,18 @@ static inline unsigned long __ffz_word_loop(const unsigned long *addr,
+ 
+ 	asm volatile(
+ #ifndef __s390x__
+-		"	ahi	%1,31\n"
+-		"	srl	%1,5\n"
++		"	ahi	%1,-1\n"
++		"	sra	%1,5\n"
++		"	jz	1f\n"
+ 		"0:	c	%2,0(%0,%3)\n"
+ 		"	jne	1f\n"
+ 		"	la	%0,4(%0)\n"
+ 		"	brct	%1,0b\n"
+ 		"1:\n"
+ #else
+-		"	aghi	%1,63\n"
+-		"	srlg	%1,%1,6\n"
++		"	aghi	%1,-1\n"
++		"	srag	%1,%1,6\n"
++		"	jz	1f\n"
+ 		"0:	cg	%2,0(%0,%3)\n"
+ 		"	jne	1f\n"
+ 		"	la	%0,8(%0)\n"
+@@ -491,16 +493,18 @@ static inline unsigned long __ffs_word_loop(const unsigned long *addr,
+ 
+ 	asm volatile(
+ #ifndef __s390x__
+-		"	ahi	%1,31\n"
+-		"	srl	%1,5\n"
++		"	ahi	%1,-1\n"
++		"	sra	%1,5\n"
++		"	jz	1f\n"
+ 		"0:	c	%2,0(%0,%3)\n"
+ 		"	jne	1f\n"
+ 		"	la	%0,4(%0)\n"
+ 		"	brct	%1,0b\n"
+ 		"1:\n"
+ #else
+-		"	aghi	%1,63\n"
+-		"	srlg	%1,%1,6\n"
++		"	aghi	%1,-1\n"
++		"	srag	%1,%1,6\n"
++		"	jz	1f\n"
+ 		"0:	cg	%2,0(%0,%3)\n"
+ 		"	jne	1f\n"
+ 		"	la	%0,8(%0)\n"
+diff --git a/include/asm-sparc64/ptrace.h b/include/asm-sparc64/ptrace.h
+index 8617c3a..67341cf 100644
+--- a/include/asm-sparc64/ptrace.h
++++ b/include/asm-sparc64/ptrace.h
+@@ -102,6 +102,7 @@ do {	current_thread_info()->syscall_noerror = 1; \
+ } while (0)
+ #define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV))
+ #define instruction_pointer(regs) ((regs)->tpc)
++#define regs_return_value(regs) ((regs)->u_regs[UREG_I0])
+ #ifdef CONFIG_SMP
+ extern unsigned long profile_pc(struct pt_regs *);
+ #else
+diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h
+deleted file mode 100644
+index 8b13789..0000000
+--- a/include/asm-x86/desc_64.h
++++ /dev/null
+@@ -1 +0,0 @@
+-
+diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h
+index 6b1895c..f377b76 100644
+--- a/include/asm-x86/i387.h
++++ b/include/asm-x86/i387.h
+@@ -20,7 +20,6 @@
+ #include <asm/uaccess.h>
+ 
+ extern void fpu_init(void);
+-extern unsigned int mxcsr_feature_mask;
+ extern void mxcsr_feature_mask_init(void);
+ extern void init_fpu(struct task_struct *child);
+ extern asmlinkage void math_state_restore(void);
+diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h
+index bd4740a..0a0b77b 100644
+--- a/include/asm-x86/pgtable_64.h
++++ b/include/asm-x86/pgtable_64.h
+@@ -188,6 +188,7 @@ static inline unsigned long pmd_bad(pmd_t pmd)
+ #define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
+ #define pgd_offset_k(address) (init_level4_pgt + pgd_index(address))
+ #define pgd_present(pgd) (pgd_val(pgd) & _PAGE_PRESENT)
++static inline int pgd_large(pgd_t pgd) { return 0; }
+ #define mk_kernel_pgd(address) ((pgd_t){ (address) | _KERNPG_TABLE })
+ 
+ /* PUD - Level3 access */
+@@ -246,6 +247,7 @@ static inline int pud_large(pud_t pte)
+ #define __swp_entry_to_pte(x)		((pte_t) { .pte = (x).val })
+ 
+ extern int kern_addr_valid(unsigned long addr); 
++extern void cleanup_highmap(void);
+ 
+ #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
+ 		remap_pfn_range(vma, vaddr, pfn, size, prot)
+diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h
+index 149920d..45a2f0a 100644
+--- a/include/asm-x86/processor.h
++++ b/include/asm-x86/processor.h
+@@ -302,10 +302,6 @@ union i387_union {
+ };
+ 
+ #ifdef CONFIG_X86_32
+-/*
+- * the following now lives in the per cpu area:
+- * extern	int cpu_llc_id[NR_CPUS];
+- */
+ DECLARE_PER_CPU(u8, cpu_llc_id);
+ #else
+ DECLARE_PER_CPU(struct orig_ist, orig_ist);
+@@ -671,7 +667,6 @@ extern void init_gdt(int cpu);
+ extern unsigned int machine_id;
+ extern unsigned int machine_submodel_id;
+ extern unsigned int BIOS_revision;
+-extern unsigned int mca_pentium_flag;
+ 
+ /* Boot loader type from the setup header */
+ extern int bootloader_type;
+diff --git a/include/asm-xtensa/cacheflush.h b/include/asm-xtensa/cacheflush.h
+index b773c57..94c4c53 100644
+--- a/include/asm-xtensa/cacheflush.h
++++ b/include/asm-xtensa/cacheflush.h
+@@ -70,6 +70,8 @@ extern void __flush_invalidate_dcache_page_alias(unsigned long, unsigned long);
+ #endif
+ #if (ICACHE_WAY_SIZE > PAGE_SIZE)
+ extern void __invalidate_icache_page_alias(unsigned long, unsigned long);
++#else
++# define __invalidate_icache_page_alias(v,p)	do { } while(0)
+ #endif
+ 
+ /*
+diff --git a/include/asm-xtensa/coprocessor.h b/include/asm-xtensa/coprocessor.h
+index aa21210..1cbcf90 100644
+--- a/include/asm-xtensa/coprocessor.h
++++ b/include/asm-xtensa/coprocessor.h
+@@ -5,81 +5,173 @@
+  * License.  See the file "COPYING" in the main directory of this archive
+  * for more details.
+  *
+- * Copyright (C) 2003 - 2005 Tensilica Inc.
++ * Copyright (C) 2003 - 2007 Tensilica Inc.
+  */
+ 
++
+ #ifndef _XTENSA_COPROCESSOR_H
+ #define _XTENSA_COPROCESSOR_H
+ 
+-#include <asm/variant/core.h>
++#include <linux/stringify.h>
+ #include <asm/variant/tie.h>
++#include <asm/types.h>
++
++#ifdef __ASSEMBLY__
++# include <asm/variant/tie-asm.h>
++
++.macro	xchal_sa_start  a b
++	.set .Lxchal_pofs_, 0
++	.set .Lxchal_ofs_, 0
++.endm
++
++.macro	xchal_sa_align  ptr minofs maxofs ofsalign totalign
++	.set	.Lxchal_ofs_, .Lxchal_ofs_ + .Lxchal_pofs_ + \totalign - 1
++	.set	.Lxchal_ofs_, (.Lxchal_ofs_ & -\totalign) - .Lxchal_pofs_
++.endm
++
++#define _SELECT	(  XTHAL_SAS_TIE | XTHAL_SAS_OPT \
++		 | XTHAL_SAS_CC \
++		 | XTHAL_SAS_CALR | XTHAL_SAS_CALE )
++
++.macro save_xtregs_opt ptr clb at1 at2 at3 at4 offset
++	.if XTREGS_OPT_SIZE > 0
++		addi	\clb, \ptr, \offset
++		xchal_ncp_store \clb \at1 \at2 \at3 \at4 select=_SELECT
++	.endif
++.endm
++
++.macro load_xtregs_opt ptr clb at1 at2 at3 at4 offset
++	.if XTREGS_OPT_SIZE > 0
++		addi	\clb, \ptr, \offset
++		xchal_ncp_load \clb \at1 \at2 \at3 \at4 select=_SELECT
++	.endif
++.endm
++#undef _SELECT
++
++#define _SELECT	(  XTHAL_SAS_TIE | XTHAL_SAS_OPT \
++		 | XTHAL_SAS_NOCC \
++		 | XTHAL_SAS_CALR | XTHAL_SAS_CALE | XTHAL_SAS_GLOB )
++
++.macro save_xtregs_user ptr clb at1 at2 at3 at4 offset
++	.if XTREGS_USER_SIZE > 0
++		addi	\clb, \ptr, \offset
++		xchal_ncp_store \clb \at1 \at2 \at3 \at4 select=_SELECT
++	.endif
++.endm
++
++.macro load_xtregs_user ptr clb at1 at2 at3 at4 offset
++	.if XTREGS_USER_SIZE > 0
++		addi	\clb, \ptr, \offset
++		xchal_ncp_load \clb \at1 \at2 \at3 \at4 select=_SELECT
++	.endif
++.endm
++#undef _SELECT
++
++
++
++#endif	/* __ASSEMBLY__ */
+ 
+-#if !XCHAL_HAVE_CP
+-
+-#define XTENSA_CP_EXTRA_OFFSET 	0
+-#define XTENSA_CP_EXTRA_ALIGN	1	/* must be a power of 2 */
+-#define XTENSA_CP_EXTRA_SIZE	0
+-
+-#else
+-
+-#define XTOFS(last_start,last_size,align) \
+-	((last_start+last_size+align-1) & -align)
+-
+-#define XTENSA_CP_EXTRA_OFFSET	0
+-#define XTENSA_CP_EXTRA_ALIGN	XCHAL_EXTRA_SA_ALIGN
+-
+-#define XTENSA_CPE_CP0_OFFSET	\
+-	XTOFS(XTENSA_CP_EXTRA_OFFSET, XCHAL_EXTRA_SA_SIZE, XCHAL_CP0_SA_ALIGN)
+-#define XTENSA_CPE_CP1_OFFSET	\
+-	XTOFS(XTENSA_CPE_CP0_OFFSET, XCHAL_CP0_SA_SIZE, XCHAL_CP1_SA_ALIGN)
+-#define XTENSA_CPE_CP2_OFFSET	\
+-	XTOFS(XTENSA_CPE_CP1_OFFSET, XCHAL_CP1_SA_SIZE, XCHAL_CP2_SA_ALIGN)
+-#define XTENSA_CPE_CP3_OFFSET	\
+-	XTOFS(XTENSA_CPE_CP2_OFFSET, XCHAL_CP2_SA_SIZE, XCHAL_CP3_SA_ALIGN)
+-#define XTENSA_CPE_CP4_OFFSET	\
+-	XTOFS(XTENSA_CPE_CP3_OFFSET, XCHAL_CP3_SA_SIZE, XCHAL_CP4_SA_ALIGN)
+-#define XTENSA_CPE_CP5_OFFSET	\
+-	XTOFS(XTENSA_CPE_CP4_OFFSET, XCHAL_CP4_SA_SIZE, XCHAL_CP5_SA_ALIGN)
+-#define XTENSA_CPE_CP6_OFFSET	\
+-	XTOFS(XTENSA_CPE_CP5_OFFSET, XCHAL_CP5_SA_SIZE, XCHAL_CP6_SA_ALIGN)
+-#define XTENSA_CPE_CP7_OFFSET	\
+-	XTOFS(XTENSA_CPE_CP6_OFFSET, XCHAL_CP6_SA_SIZE, XCHAL_CP7_SA_ALIGN)
+-#define XTENSA_CP_EXTRA_SIZE	\
+-	XTOFS(XTENSA_CPE_CP7_OFFSET, XCHAL_CP7_SA_SIZE, 16)
+-
+-#if XCHAL_CP_NUM > 0
+-# ifndef __ASSEMBLY__
+ /*
+- * Tasks that own contents of (last user) each coprocessor.
+- * Entries are 0 for not-owned or non-existent coprocessors.
+- * Note: The size of this structure is fixed to 8 bytes in entry.S
++ * XTENSA_HAVE_COPROCESSOR(x) returns 1 if coprocessor x is configured.
++ *
++ * XTENSA_HAVE_IO_PORT(x) returns 1 if io-port x is configured.
++ *
+  */
+-typedef struct {
+-	struct task_struct *owner;	/* owner */
+-	int offset;			/* offset in cpextra space. */
+-} coprocessor_info_t;
+-# else
+-#  define COPROCESSOR_INFO_OWNER 0
+-#  define COPROCESSOR_INFO_OFFSET 4
+-#  define COPROCESSOR_INFO_SIZE 8
+-# endif
+-#endif
+-#endif	/* XCHAL_HAVE_CP */
+ 
++#define XTENSA_HAVE_COPROCESSOR(x)					\
++	((XCHAL_CP_MASK ^ XCHAL_CP_PORT_MASK) & (1 << (x)))
++#define XTENSA_HAVE_COPROCESSORS					\
++	(XCHAL_CP_MASK ^ XCHAL_CP_PORT_MASK)
++#define XTENSA_HAVE_IO_PORT(x)						\
++	(XCHAL_CP_PORT_MASK & (1 << (x)))
++#define XTENSA_HAVE_IO_PORTS						\
++	XCHAL_CP_PORT_MASK
+ 
+ #ifndef __ASSEMBLY__
+-# if XCHAL_CP_NUM > 0
+-struct task_struct;
+-extern void release_coprocessors (struct task_struct*);
+-extern void save_coprocessor_registers(void*, int);
+-# else
+-#  define release_coprocessors(task)
+-# endif
+ 
+-typedef unsigned char cp_state_t[XTENSA_CP_EXTRA_SIZE]
+-	__attribute__ ((aligned (XTENSA_CP_EXTRA_ALIGN)));
+ 
+-#endif	/* !__ASSEMBLY__ */
++#if XCHAL_HAVE_CP
++
++#define RSR_CPENABLE(x)	do {						  \
++	__asm__ __volatile__("rsr %0," __stringify(CPENABLE) : "=a" (x)); \
++	} while(0);
++#define WSR_CPENABLE(x)	do {						  \
++  	__asm__ __volatile__("wsr %0," __stringify(CPENABLE) "; rsync" 	  \
++	    		     :: "a" (x));				  \
++	} while(0);
+ 
++#endif /* XCHAL_HAVE_CP */
+ 
++
++/*
++ * Additional registers.
++ * We define three types of additional registers:
++ *  ext: extra registers that are used by the compiler
++ *  cpn: optional registers that can be used by a user application
++ *  cpX: coprocessor registers that can only be used if the corresponding
++ *       CPENABLE bit is set.
++ */
++
++#define XCHAL_SA_REG(list,cc,abi,type,y,name,z,align,size,...)	\
++	__REG ## list (cc, abi, type, name, size, align)
++
++#define __REG0(cc,abi,t,name,s,a)	__REG0_ ## cc (abi,name)
++#define __REG1(cc,abi,t,name,s,a)	__REG1_ ## cc (name)
++#define __REG2(cc,abi,type,...)		__REG2_ ## type (__VA_ARGS__)
++
++#define __REG0_0(abi,name)
++#define __REG0_1(abi,name)		__REG0_1 ## abi (name)
++#define __REG0_10(name)	__u32 name;
++#define __REG0_11(name)	__u32 name;
++#define __REG0_12(name)
++
++#define __REG1_0(name)	__u32 name;
++#define __REG1_1(name)
++
++#define __REG2_0(n,s,a)	__u32 name;
++#define __REG2_1(n,s,a)	unsigned char n[s] __attribute__ ((aligned(a)));
++#define __REG2_2(n,s,a) unsigned char n[s] __attribute__ ((aligned(a)));
++
++typedef struct { XCHAL_NCP_SA_LIST(0) } xtregs_opt_t
++	__attribute__ ((aligned (XCHAL_NCP_SA_ALIGN)));
++typedef struct { XCHAL_NCP_SA_LIST(1) } xtregs_user_t
++	__attribute__ ((aligned (XCHAL_NCP_SA_ALIGN)));
++
++#if XTENSA_HAVE_COPROCESSORS
++
++typedef struct { XCHAL_CP0_SA_LIST(2) } xtregs_cp0_t
++	__attribute__ ((aligned (XCHAL_CP0_SA_ALIGN)));
++typedef struct { XCHAL_CP1_SA_LIST(2) } xtregs_cp1_t
++	__attribute__ ((aligned (XCHAL_CP1_SA_ALIGN)));
++typedef struct { XCHAL_CP2_SA_LIST(2) } xtregs_cp2_t
++	__attribute__ ((aligned (XCHAL_CP2_SA_ALIGN)));
++typedef struct { XCHAL_CP3_SA_LIST(2) } xtregs_cp3_t
++	__attribute__ ((aligned (XCHAL_CP3_SA_ALIGN)));
++typedef struct { XCHAL_CP4_SA_LIST(2) } xtregs_cp4_t
++	__attribute__ ((aligned (XCHAL_CP4_SA_ALIGN)));
++typedef struct { XCHAL_CP5_SA_LIST(2) } xtregs_cp5_t
++	__attribute__ ((aligned (XCHAL_CP5_SA_ALIGN)));
++typedef struct { XCHAL_CP6_SA_LIST(2) } xtregs_cp6_t
++	__attribute__ ((aligned (XCHAL_CP6_SA_ALIGN)));
++typedef struct { XCHAL_CP7_SA_LIST(2) } xtregs_cp7_t
++	__attribute__ ((aligned (XCHAL_CP7_SA_ALIGN)));
++
++extern struct thread_info* coprocessor_owner[XCHAL_CP_MAX];
++extern void coprocessor_save(void*, int);
++extern void coprocessor_load(void*, int);
++extern void coprocessor_flush(struct thread_info*, int);
++extern void coprocessor_restore(struct thread_info*, int);
++
++extern void coprocessor_release_all(struct thread_info*);
++extern void coprocessor_flush_all(struct thread_info*);
++
++static inline void coprocessor_clear_cpenable(void)
++{
++	unsigned long i = 0;
++	WSR_CPENABLE(i);
++}
++
++#endif	/* XTENSA_HAVE_COPROCESSORS */
++
++#endif	/* !__ASSEMBLY__ */
+ #endif	/* _XTENSA_COPROCESSOR_H */
+diff --git a/include/asm-xtensa/elf.h b/include/asm-xtensa/elf.h
+index 4673845..ca6e510 100644
+--- a/include/asm-xtensa/elf.h
++++ b/include/asm-xtensa/elf.h
+@@ -72,115 +72,32 @@
+ 
+ /* ELF register definitions. This is needed for core dump support.  */
+ 
+-/*
+- * elf_gregset_t contains the application-level state in the following order:
+- * Processor info: 	config_version, cpuxy
+- * Processor state:	pc, ps, exccause, excvaddr, wb, ws,
+- *			lbeg, lend, lcount, sar
+- * GP regs:		ar0 - arXX
+- */
+-
+ typedef unsigned long elf_greg_t;
+ 
+ typedef struct {
+-	elf_greg_t xchal_config_id0;
+-	elf_greg_t xchal_config_id1;
+-	elf_greg_t cpux;
+-	elf_greg_t cpuy;
+ 	elf_greg_t pc;
+ 	elf_greg_t ps;
+-	elf_greg_t exccause;
+-	elf_greg_t excvaddr;
+-	elf_greg_t windowbase;
+-	elf_greg_t windowstart;
+ 	elf_greg_t lbeg;
+ 	elf_greg_t lend;
+ 	elf_greg_t lcount;
+ 	elf_greg_t sar;
+-	elf_greg_t syscall;
+-	elf_greg_t ar[64];
++	elf_greg_t windowstart;
++	elf_greg_t windowbase;
++	elf_greg_t reserved[8+48];
++	elf_greg_t a[64];
+ } xtensa_gregset_t;
+ 
+ #define ELF_NGREG	(sizeof(xtensa_gregset_t) / sizeof(elf_greg_t))
+ 
+ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+ 
+-/*
+- *  Compute the size of the coprocessor and extra state layout (register info)
+- *  table (in bytes).
+- *  This is actually the maximum size of the table, as opposed to the size,
+- *  which is available from the _xtensa_reginfo_table_size global variable.
+- *
+- *  (See also arch/xtensa/kernel/coprocessor.S)
+- *
+- */
+-
+-#ifndef XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM
+-# define XTENSA_CPE_LTABLE_SIZE		0
+-#else
+-# define XTENSA_CPE_SEGMENT(num)	(num ? (1+num) : 0)
+-# define XTENSA_CPE_LTABLE_ENTRIES	\
+-		( XTENSA_CPE_SEGMENT(XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM)	\
+-		+ XTENSA_CPE_SEGMENT(XCHAL_CP0_SA_CONTENTS_LIBDB_NUM)	\
+-		+ XTENSA_CPE_SEGMENT(XCHAL_CP1_SA_CONTENTS_LIBDB_NUM)	\
+-		+ XTENSA_CPE_SEGMENT(XCHAL_CP2_SA_CONTENTS_LIBDB_NUM)	\
+-		+ XTENSA_CPE_SEGMENT(XCHAL_CP3_SA_CONTENTS_LIBDB_NUM)	\
+-		+ XTENSA_CPE_SEGMENT(XCHAL_CP4_SA_CONTENTS_LIBDB_NUM)	\
+-		+ XTENSA_CPE_SEGMENT(XCHAL_CP5_SA_CONTENTS_LIBDB_NUM)	\
+-		+ XTENSA_CPE_SEGMENT(XCHAL_CP6_SA_CONTENTS_LIBDB_NUM)	\
+-		+ XTENSA_CPE_SEGMENT(XCHAL_CP7_SA_CONTENTS_LIBDB_NUM)	\
+-		+ 1		/* final entry */			\
+-		)
+-# define XTENSA_CPE_LTABLE_SIZE		(XTENSA_CPE_LTABLE_ENTRIES * 8)
+-#endif
+-
+-
+-/*
+- * Instantiations of the elf_fpregset_t type contain, in most
+- * architectures, the floating point (FPU) register set.
+- * For Xtensa, this type is extended to contain all custom state,
+- * ie. coprocessor and "extra" (non-coprocessor) state (including,
+- * for example, TIE-defined states and register files; as well
+- * as other optional processor state).
+- * This includes FPU state if a floating-point coprocessor happens
+- * to have been configured within the Xtensa processor.
+- *
+- * TOTAL_FPREGS_SIZE is the required size (without rounding)
+- * of elf_fpregset_t.  It provides space for the following:
+- *
+- *  a)	32-bit mask of active coprocessors for this task (similar
+- *	to CPENABLE in single-threaded Xtensa processor systems)
+- *
+- *  b)	table describing the layout of custom states (ie. of
+- *      individual registers, etc) within the save areas
+- *
+- *  c)  save areas for each coprocessor and for non-coprocessor
+- *      ("extra") state
+- *
+- * Note that save areas may require up to 16-byte alignment when
+- * accessed by save/restore sequences.  We do not need to ensure
+- * such alignment in an elf_fpregset_t structure because custom
+- * state is not directly loaded/stored into it; rather, save area
+- * contents are copied to elf_fpregset_t from the active save areas
+- * (see 'struct task_struct' definition in processor.h for that)
+- * using memcpy().  But we do allow space for such alignment,
+- * to allow optimizations of layout and copying.
+- */
+-#if 0
+-#define TOTAL_FPREGS_SIZE						\
+-  	(4 + XTENSA_CPE_LTABLE_SIZE + XTENSA_CP_EXTRA_SIZE)
+-#define ELF_NFPREG							\
+-	((TOTAL_FPREGS_SIZE + sizeof(elf_fpreg_t) - 1) / sizeof(elf_fpreg_t))
+-#else
+-#define TOTAL_FPREGS_SIZE	0
+-#define ELF_NFPREG		0
+-#endif
++#define ELF_NFPREG	18
+ 
+ typedef unsigned int elf_fpreg_t;
+ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+ 
+ #define ELF_CORE_COPY_REGS(_eregs, _pregs) 				\
+-	xtensa_elf_core_copy_regs (&_eregs, _pregs);
++	xtensa_elf_core_copy_regs ((xtensa_gregset_t*)&(_eregs), _pregs);
+ 
+ extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *);
+ 
+@@ -257,6 +174,21 @@ extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *);
+        _r->areg[12]=0; _r->areg[13]=0;   _r->areg[14]=0; _r->areg[15]=0; \
+   } while (0)
+ 
++typedef struct {
++	xtregs_opt_t	opt;
++	xtregs_user_t	user;
++#if XTENSA_HAVE_COPROCESSORS
++	xtregs_cp0_t	cp0;
++	xtregs_cp1_t	cp1;
++	xtregs_cp2_t	cp2;
++	xtregs_cp3_t	cp3;
++	xtregs_cp4_t	cp4;
++	xtregs_cp5_t	cp5;
++	xtregs_cp6_t	cp6;
++	xtregs_cp7_t	cp7;
++#endif
++} elf_xtregs_t;
++
+ #define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
+ 
+ struct task_struct;
+diff --git a/include/asm-xtensa/module.h b/include/asm-xtensa/module.h
+index ffb25bf..d9b34be 100644
+--- a/include/asm-xtensa/module.h
++++ b/include/asm-xtensa/module.h
+@@ -15,9 +15,11 @@
+ 
+ struct mod_arch_specific
+ {
+-	/* Module support is not completely implemented. */
++	/* No special elements, yet. */
+ };
+ 
++#define MODULE_ARCH_VERMAGIC "xtensa-" __stringify(XCHAL_CORE_ID) " "
++
+ #define Elf_Shdr Elf32_Shdr
+ #define Elf_Sym Elf32_Sym
+ #define Elf_Ehdr Elf32_Ehdr
+diff --git a/include/asm-xtensa/pgalloc.h b/include/asm-xtensa/pgalloc.h
+index 8d1544e..4f4a798 100644
+--- a/include/asm-xtensa/pgalloc.h
++++ b/include/asm-xtensa/pgalloc.h
+@@ -47,7 +47,7 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+ 	return kmem_cache_alloc(pgtable_cache, GFP_KERNEL|__GFP_REPEAT);
+ }
+ 
+-static inline pte_token_t pte_alloc_one(struct mm_struct *mm,
++static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
+ 					unsigned long addr)
+ {
+ 	struct page *page;
+diff --git a/include/asm-xtensa/pgtable.h b/include/asm-xtensa/pgtable.h
+index c0fcc1c..c8b024a 100644
+--- a/include/asm-xtensa/pgtable.h
++++ b/include/asm-xtensa/pgtable.h
+@@ -66,11 +66,9 @@
+  */
+ 
+ #define VMALLOC_START		0xC0000000
+-#define VMALLOC_END		0xC6FEFFFF
+-#define TLBTEMP_BASE_1		0xC6FF0000
+-#define TLBTEMP_BASE_2		0xC6FF8000
+-#define MODULE_START		0xC7000000
+-#define MODULE_END		0xC7FFFFFF
++#define VMALLOC_END		0xC7FEFFFF
++#define TLBTEMP_BASE_1		0xC7FF0000
++#define TLBTEMP_BASE_2		0xC7FF8000
+ 
+ /*
+  * Xtensa Linux config PTE layout (when present):
+diff --git a/include/asm-xtensa/processor.h b/include/asm-xtensa/processor.h
+index 96408f4..4918a4e 100644
+--- a/include/asm-xtensa/processor.h
++++ b/include/asm-xtensa/processor.h
+@@ -103,10 +103,6 @@ struct thread_struct {
+ 	unsigned long dbreaka[XCHAL_NUM_DBREAK];
+ 	unsigned long dbreakc[XCHAL_NUM_DBREAK];
+ 
+-	/* Allocate storage for extra state and coprocessor state. */
+-	unsigned char cp_save[XTENSA_CP_EXTRA_SIZE]
+-		__attribute__ ((aligned(XTENSA_CP_EXTRA_ALIGN)));
+-
+ 	/* Make structure 16 bytes aligned. */
+ 	int align[0] __attribute__ ((aligned(16)));
+ };
+@@ -162,21 +158,16 @@ struct thread_struct {
+ struct task_struct;
+ struct mm_struct;
+ 
+-// FIXME: do we need release_thread for CP??
+ /* Free all resources held by a thread. */
+ #define release_thread(thread) do { } while(0)
+ 
+-// FIXME: do we need prepare_to_copy (lazy status) for CP??
+ /* Prepare to copy thread state - unlazy all lazy status */
+-#define prepare_to_copy(tsk)	do { } while (0)
++extern void prepare_to_copy(struct task_struct*);
+ 
+-/*
+- * create a kernel thread without removing it from tasklists
+- */
++/* Create a kernel thread without removing it from tasklists */
+ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+ 
+ /* Copy and release all segment info associated with a VM */
+-
+ #define copy_segments(p, mm)	do { } while(0)
+ #define release_segments(mm)	do { } while(0)
+ #define forget_segments()	do { } while (0)
+diff --git a/include/asm-xtensa/ptrace.h b/include/asm-xtensa/ptrace.h
+index 77ff02d..422c73e 100644
+--- a/include/asm-xtensa/ptrace.h
++++ b/include/asm-xtensa/ptrace.h
+@@ -53,33 +53,30 @@
+ 
+ /* Registers used by strace */
+ 
+-#define REG_A_BASE	0xfc000000
+-#define REG_AR_BASE	0x04000000
+-#define REG_PC		0x14000000
+-#define REG_PS		0x080000e6
+-#define REG_WB		0x08000048
+-#define REG_WS		0x08000049
+-#define REG_LBEG	0x08000000
+-#define REG_LEND	0x08000001
+-#define REG_LCOUNT	0x08000002
+-#define REG_SAR		0x08000003
+-#define REG_DEPC	0x080000c0
+-#define	REG_EXCCAUSE	0x080000e8
+-#define REG_EXCVADDR	0x080000ee
+-#define SYSCALL_NR	0x1
+-
+-#define AR_REGNO_TO_A_REGNO(ar, wb) (ar - wb*4) & ~(XCHAL_NUM_AREGS - 1)
++#define REG_A_BASE	0x0000
++#define REG_AR_BASE	0x0100
++#define REG_PC		0x0020
++#define REG_PS		0x02e6
++#define REG_WB		0x0248
++#define REG_WS		0x0249
++#define REG_LBEG	0x0200
++#define REG_LEND	0x0201
++#define REG_LCOUNT	0x0202
++#define REG_SAR		0x0203
++
++#define SYSCALL_NR	0x00ff
+ 
+ /* Other PTRACE_ values defined in <linux/ptrace.h> using values 0-9,16,17,24 */
+ 
+-#define PTRACE_GETREGS            12
+-#define PTRACE_SETREGS            13
+-#define PTRACE_GETFPREGS          14
+-#define PTRACE_SETFPREGS          15
+-#define PTRACE_GETFPREGSIZE       18
++#define PTRACE_GETREGS		12
++#define PTRACE_SETREGS		13
++#define PTRACE_GETXTREGS	18
++#define PTRACE_SETXTREGS	19
+ 
+ #ifndef __ASSEMBLY__
+ 
++#ifdef __KERNEL__
++
+ /*
+  * This struct defines the way the registers are stored on the
+  * kernel stack during a system call or other kernel entry.
+@@ -102,6 +99,9 @@ struct pt_regs {
+ 	unsigned long icountlevel;	/*  60 */
+ 	int reserved[1];		/*  64 */
+ 
++	/* Additional configurable registers that are used by the compiler. */
++	xtregs_opt_t xtregs_opt;
++
+ 	/* Make sure the areg field is 16 bytes aligned. */
+ 	int align[0] __attribute__ ((aligned(16)));
+ 
+@@ -111,8 +111,6 @@ struct pt_regs {
+ 	unsigned long areg[16];		/* 128 (64) */
+ };
+ 
+-#ifdef __KERNEL__
+-
+ #include <asm/variant/core.h>
+ 
+ # define task_pt_regs(tsk) ((struct pt_regs*) \
+diff --git a/include/asm-xtensa/regs.h b/include/asm-xtensa/regs.h
+index c913d25..d4baed2 100644
+--- a/include/asm-xtensa/regs.h
++++ b/include/asm-xtensa/regs.h
+@@ -100,7 +100,14 @@
+ #define EXCCAUSE_DTLB_SIZE_RESTRICTION		27
+ #define EXCCAUSE_LOAD_CACHE_ATTRIBUTE		28
+ #define EXCCAUSE_STORE_CACHE_ATTRIBUTE		29
+-#define EXCCAUSE_FLOATING_POINT			40
++#define EXCCAUSE_COPROCESSOR0_DISABLED		32
++#define EXCCAUSE_COPROCESSOR1_DISABLED		33
++#define EXCCAUSE_COPROCESSOR2_DISABLED		34
++#define EXCCAUSE_COPROCESSOR3_DISABLED		35
++#define EXCCAUSE_COPROCESSOR4_DISABLED		36
++#define EXCCAUSE_COPROCESSOR5_DISABLED		37
++#define EXCCAUSE_COPROCESSOR6_DISABLED		38
++#define EXCCAUSE_COPROCESSOR7_DISABLED		39
+ 
+ /*  PS register fields.  */
+ 
+diff --git a/include/asm-xtensa/sigcontext.h b/include/asm-xtensa/sigcontext.h
+index e3381ce..03383af 100644
+--- a/include/asm-xtensa/sigcontext.h
++++ b/include/asm-xtensa/sigcontext.h
+@@ -13,9 +13,6 @@
+ 
+ 
+ struct sigcontext {
+-	unsigned long	oldmask;
+-
+-	/* CPU registers */
+ 	unsigned long sc_pc;
+ 	unsigned long sc_ps;
+ 	unsigned long sc_lbeg;
+@@ -25,6 +22,7 @@ struct sigcontext {
+ 	unsigned long sc_acclo;
+ 	unsigned long sc_acchi;
+ 	unsigned long sc_a[16];
++	void *sc_xtregs;
+ };
+ 
+ #endif /* _XTENSA_SIGCONTEXT_H */
+diff --git a/include/asm-xtensa/stat.h b/include/asm-xtensa/stat.h
+index 149f4bc..c499203 100644
+--- a/include/asm-xtensa/stat.h
++++ b/include/asm-xtensa/stat.h
+@@ -5,25 +5,23 @@
+  * License.  See the file "COPYING" in the main directory of this archive
+  * for more details.
+  *
+- * Copyright (C) 2001 - 2005 Tensilica Inc.
++ * Copyright (C) 2001 - 2007 Tensilica Inc.
+  */
+ 
+ #ifndef _XTENSA_STAT_H
+ #define _XTENSA_STAT_H
+ 
+-#include <linux/types.h>
+-
+ #define STAT_HAVE_NSEC 1
+ 
+ struct stat {
+ 	unsigned long	st_dev;
+-	ino_t		st_ino;
+-	mode_t		st_mode;
+-	nlink_t		st_nlink;
+-	uid_t		st_uid;
+-	gid_t		st_gid;
+-	unsigned int	st_rdev;
+-	off_t		st_size;
++	unsigned long	st_ino;
++	unsigned int	st_mode;
++	unsigned int	st_nlink;
++	unsigned int	st_uid;
++	unsigned int	st_gid;
++	unsigned long	st_rdev;
++	long		st_size;
+ 	unsigned long	st_blksize;
+ 	unsigned long	st_blocks;
+ 	unsigned long	st_atime;
+@@ -36,8 +34,6 @@ struct stat {
+ 	unsigned long	__unused5;
+ };
+ 
+-/* This matches struct stat64 in glibc-2.3 */
+-
+ struct stat64  {
+ 	unsigned long long st_dev;	/* Device */
+ 	unsigned long long st_ino;	/* File serial number */
+@@ -47,20 +43,14 @@ struct stat64  {
+ 	unsigned int  st_gid;		/* Group ID of the file's group. */
+ 	unsigned long long st_rdev;	/* Device number, if device. */
+ 	long long st_size;		/* Size of file, in bytes. */
+-	long st_blksize;		/* Optimal block size for I/O. */
++	unsigned long st_blksize;	/* Optimal block size for I/O. */
+ 	unsigned long __unused2;
+-#ifdef __XTENSA_EB__
+-	unsigned long __unused3;
+-	long st_blocks;			/* Number 512-byte blocks allocated. */
+-#else
+-	long st_blocks;			/* Number 512-byte blocks allocated. */
+-	unsigned long __unused3;
+-#endif
+-	long st_atime;			/* Time of last access. */
++	unsigned long long st_blocks;	/* Number 512-byte blocks allocated. */
++	unsigned long st_atime;		/* Time of last access. */
+ 	unsigned long st_atime_nsec;
+-	long st_mtime;			/* Time of last modification. */
++	unsigned long st_mtime;		/* Time of last modification. */
+ 	unsigned long st_mtime_nsec;
+-	long st_ctime;			/* Time of last status change. */
++	unsigned long st_ctime;		/* Time of last status change. */
+ 	unsigned long st_ctime_nsec;
+ 	unsigned long __unused4;
+ 	unsigned long __unused5;
+diff --git a/include/asm-xtensa/system.h b/include/asm-xtensa/system.h
+index e0cb911..62b1e8f 100644
+--- a/include/asm-xtensa/system.h
++++ b/include/asm-xtensa/system.h
+@@ -46,42 +46,6 @@ static inline int irqs_disabled(void)
+ 	return flags & 0xf;
+ }
+ 
+-#define RSR_CPENABLE(x)	do {						  \
+-	__asm__ __volatile__("rsr %0," __stringify(CPENABLE) : "=a" (x)); \
+-	} while(0);
+-#define WSR_CPENABLE(x)	do {						  \
+-  	__asm__ __volatile__("wsr %0," __stringify(CPENABLE)";rsync" 	  \
+-	    		     :: "a" (x));} while(0);
+-
+-#define clear_cpenable() __clear_cpenable()
+-
+-static inline void __clear_cpenable(void)
+-{
+-#if XCHAL_HAVE_CP
+-	unsigned long i = 0;
+-	WSR_CPENABLE(i);
+-#endif
+-}
+-
+-static inline void enable_coprocessor(int i)
+-{
+-#if XCHAL_HAVE_CP
+-	int cp;
+-	RSR_CPENABLE(cp);
+-	cp |= 1 << i;
+-	WSR_CPENABLE(cp);
+-#endif
+-}
+-
+-static inline void disable_coprocessor(int i)
+-{
+-#if XCHAL_HAVE_CP
+-	int cp;
+-	RSR_CPENABLE(cp);
+-	cp &= ~(1 << i);
+-	WSR_CPENABLE(cp);
+-#endif
+-}
+ 
+ #define smp_read_barrier_depends() do { } while(0)
+ #define read_barrier_depends() do { } while(0)
+@@ -111,7 +75,6 @@ extern void *_switch_to(void *last, void *next);
+ 
+ #define switch_to(prev,next,last)		\
+ do {						\
+-	clear_cpenable();			\
+ 	(last) = _switch_to(prev, next);	\
+ } while(0)
+ 
+@@ -244,7 +207,7 @@ static inline void spill_registers(void)
+ 		"wsr	a13," __stringify(SAR) "\n\t"
+ 		"wsr	a14," __stringify(PS) "\n\t"
+ 		:: "a" (&a0), "a" (&ps)
+-		: "a2", "a3", "a12", "a13", "a14", "a15", "memory");
++		: "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", "memory");
+ }
+ 
+ #define arch_align_stack(x) (x)
+diff --git a/include/asm-xtensa/thread_info.h b/include/asm-xtensa/thread_info.h
+index 52c9582..a2c6406 100644
+--- a/include/asm-xtensa/thread_info.h
++++ b/include/asm-xtensa/thread_info.h
+@@ -27,6 +27,21 @@
+ 
+ #ifndef __ASSEMBLY__
+ 
++#if XTENSA_HAVE_COPROCESSORS
++
++typedef struct xtregs_coprocessor {
++	xtregs_cp0_t cp0;
++	xtregs_cp1_t cp1;
++	xtregs_cp2_t cp2;
++	xtregs_cp3_t cp3;
++	xtregs_cp4_t cp4;
++	xtregs_cp5_t cp5;
++	xtregs_cp6_t cp6;
++	xtregs_cp7_t cp7;
++} xtregs_coprocessor_t;
++
++#endif
++
+ struct thread_info {
+ 	struct task_struct	*task;		/* main task structure */
+ 	struct exec_domain	*exec_domain;	/* execution domain */
+@@ -38,7 +53,13 @@ struct thread_info {
+ 	mm_segment_t		addr_limit;	/* thread address space */
+ 	struct restart_block    restart_block;
+ 
++	unsigned long		cpenable;
+ 
++	/* Allocate storage for extra user states and coprocessor states. */
++#if XTENSA_HAVE_COPROCESSORS
++	xtregs_coprocessor_t	xtregs_cp;
++#endif
++	xtregs_user_t		xtregs_user;
+ };
+ 
+ #else /* !__ASSEMBLY__ */
+diff --git a/include/asm-xtensa/timex.h b/include/asm-xtensa/timex.h
+index a5fca59..b83a818 100644
+--- a/include/asm-xtensa/timex.h
++++ b/include/asm-xtensa/timex.h
+@@ -63,10 +63,10 @@ extern cycles_t cacheflush_time;
+  * Register access.
+  */
+ 
+-#define WSR_CCOUNT(r)	  __asm__("wsr %0,"__stringify(CCOUNT) :: "a" (r))
+-#define RSR_CCOUNT(r)	  __asm__("rsr %0,"__stringify(CCOUNT) : "=a" (r))
+-#define WSR_CCOMPARE(x,r) __asm__("wsr %0,"__stringify(CCOMPARE)"+"__stringify(x) :: "a"(r))
+-#define RSR_CCOMPARE(x,r) __asm__("rsr %0,"__stringify(CCOMPARE)"+"__stringify(x) : "=a"(r))
++#define WSR_CCOUNT(r)	  asm volatile ("wsr %0,"__stringify(CCOUNT) :: "a" (r))
++#define RSR_CCOUNT(r)	  asm volatile ("rsr %0,"__stringify(CCOUNT) : "=a" (r))
++#define WSR_CCOMPARE(x,r) asm volatile ("wsr %0,"__stringify(CCOMPARE)"+"__stringify(x) :: "a"(r))
++#define RSR_CCOMPARE(x,r) asm volatile ("rsr %0,"__stringify(CCOMPARE)"+"__stringify(x) : "=a"(r))
+ 
+ static inline unsigned long get_ccount (void)
+ {
+diff --git a/include/asm-xtensa/uaccess.h b/include/asm-xtensa/uaccess.h
+index d6352da..b852842 100644
+--- a/include/asm-xtensa/uaccess.h
++++ b/include/asm-xtensa/uaccess.h
+@@ -26,6 +26,7 @@
+ #include <asm/current.h>
+ #include <asm/asm-offsets.h>
+ #include <asm/processor.h>
++#include <asm/types.h>
+ 
+ /*
+  * These assembly macros mirror the C macros that follow below.  They
+@@ -118,7 +119,7 @@
+  * 	<at>	destroyed (actually, (TASK_SIZE + 1 - size))
+  */
+ 	.macro	user_ok	aa, as, at, error
+-	movi	\at, (TASK_SIZE+1)
++	movi	\at, __XTENSA_UL_CONST(TASK_SIZE)
+ 	bgeu	\as, \at, \error
+ 	sub	\at, \at, \as
+ 	bgeu	\aa, \at, \error
+@@ -226,20 +227,21 @@ extern long __put_user_bad(void);
+ 	__pu_err;						\
+ })
+ 
+-#define __put_user_size(x,ptr,size,retval)			\
+-do {								\
+-	retval = 0;						\
+-	switch (size) {						\
+-        case 1: __put_user_asm(x,ptr,retval,1,"s8i");  break;	\
+-        case 2: __put_user_asm(x,ptr,retval,2,"s16i"); break;   \
+-        case 4: __put_user_asm(x,ptr,retval,4,"s32i"); break;   \
+-        case 8: {						\
+-		     __typeof__(*ptr) __v64 = x;		\
+-		     retval = __copy_to_user(ptr,&__v64,8);	\
+-		     break;					\
+-	        }						\
+-	default: __put_user_bad();				\
+-	}							\
++#define __put_user_size(x,ptr,size,retval)				\
++do {									\
++	int __cb;							\
++	retval = 0;							\
++	switch (size) {							\
++        case 1: __put_user_asm(x,ptr,retval,1,"s8i",__cb);  break;	\
++        case 2: __put_user_asm(x,ptr,retval,2,"s16i",__cb); break;	\
++        case 4: __put_user_asm(x,ptr,retval,4,"s32i",__cb); break;	\
++        case 8: {							\
++		     __typeof__(*ptr) __v64 = x;			\
++		     retval = __copy_to_user(ptr,&__v64,8);		\
++		     break;						\
++	        }							\
++	default: __put_user_bad();					\
++	}								\
+ } while (0)
+ 
+ 
+@@ -267,14 +269,14 @@ do {								\
+ #define __check_align_1  ""
+ 
+ #define __check_align_2				\
+-	"   _bbci.l %2,  0, 1f		\n"	\
+-	"   movi    %0, %3		\n"	\
++	"   _bbci.l %3,  0, 1f		\n"	\
++	"   movi    %0, %4		\n"	\
+ 	"   _j      2f			\n"
+ 
+ #define __check_align_4				\
+-	"   _bbsi.l %2,  0, 0f		\n"	\
+-	"   _bbci.l %2,  1, 1f		\n"	\
+-	"0: movi    %0, %3		\n"	\
++	"   _bbsi.l %3,  0, 0f		\n"	\
++	"   _bbci.l %3,  1, 1f		\n"	\
++	"0: movi    %0, %4		\n"	\
+ 	"   _j      2f			\n"
+ 
+ 
+@@ -286,24 +288,24 @@ do {								\
+  * WARNING: If you modify this macro at all, verify that the
+  * __check_align_* macros still work.
+  */
+-#define __put_user_asm(x, addr, err, align, insn) \
+-   __asm__ __volatile__(			\
+-	__check_align_##align			\
+-	"1: "insn"  %1, %2, 0		\n"	\
+-	"2:				\n"	\
+-	"   .section  .fixup,\"ax\"	\n"	\
+-	"   .align 4			\n"	\
+-	"4:				\n"	\
+-	"   .long  2b			\n"	\
+-	"5:				\n"	\
+-	"   l32r   %2, 4b		\n"	\
+-        "   movi   %0, %3		\n"	\
+-        "   jx     %2			\n"	\
+-	"   .previous			\n"	\
+-	"   .section  __ex_table,\"a\"	\n"	\
+-	"   .long	1b, 5b		\n"	\
+-	"   .previous"				\
+-	:"=r" (err)				\
++#define __put_user_asm(x, addr, err, align, insn, cb)	\
++   __asm__ __volatile__(				\
++	__check_align_##align				\
++	"1: "insn"  %2, %3, 0		\n"		\
++	"2:				\n"		\
++	"   .section  .fixup,\"ax\"	\n"		\
++	"   .align 4			\n"		\
++	"4:				\n"		\
++	"   .long  2b			\n"		\
++	"5:				\n"		\
++	"   l32r   %1, 4b		\n"		\
++        "   movi   %0, %4		\n"		\
++        "   jx     %1			\n"		\
++	"   .previous			\n"		\
++	"   .section  __ex_table,\"a\"	\n"		\
++	"   .long	1b, 5b		\n"		\
++	"   .previous"					\
++	:"=r" (err), "=r" (cb)				\
+ 	:"r" ((int)(x)), "r" (addr), "i" (-EFAULT), "0" (err))
+ 
+ #define __get_user_nocheck(x,ptr,size)				\
+@@ -328,11 +330,12 @@ extern long __get_user_bad(void);
+ 
+ #define __get_user_size(x,ptr,size,retval)				\
+ do {									\
++	int __cb;							\
+ 	retval = 0;							\
+         switch (size) {							\
+-          case 1: __get_user_asm(x,ptr,retval,1,"l8ui");  break;	\
+-          case 2: __get_user_asm(x,ptr,retval,2,"l16ui"); break;	\
+-          case 4: __get_user_asm(x,ptr,retval,4,"l32i");  break;	\
++          case 1: __get_user_asm(x,ptr,retval,1,"l8ui",__cb);  break;	\
++          case 2: __get_user_asm(x,ptr,retval,2,"l16ui",__cb); break;	\
++          case 4: __get_user_asm(x,ptr,retval,4,"l32i",__cb);  break;	\
+           case 8: retval = __copy_from_user(&x,ptr,8);    break;	\
+           default: (x) = __get_user_bad();				\
+         }								\
+@@ -343,25 +346,25 @@ do {									\
+  * WARNING: If you modify this macro at all, verify that the
+  * __check_align_* macros still work.
+  */
+-#define __get_user_asm(x, addr, err, align, insn) \
++#define __get_user_asm(x, addr, err, align, insn, cb) \
+    __asm__ __volatile__(			\
+ 	__check_align_##align			\
+-	"1: "insn"  %1, %2, 0		\n"	\
++	"1: "insn"  %2, %3, 0		\n"	\
+ 	"2:				\n"	\
+ 	"   .section  .fixup,\"ax\"	\n"	\
+ 	"   .align 4			\n"	\
+ 	"4:				\n"	\
+ 	"   .long  2b			\n"	\
+ 	"5:				\n"	\
+-	"   l32r   %2, 4b		\n"	\
+-	"   movi   %1, 0		\n"	\
+-        "   movi   %0, %3		\n"	\
+-        "   jx     %2			\n"	\
++	"   l32r   %1, 4b		\n"	\
++	"   movi   %2, 0		\n"	\
++        "   movi   %0, %4		\n"	\
++        "   jx     %1			\n"	\
+ 	"   .previous			\n"	\
+ 	"   .section  __ex_table,\"a\"	\n"	\
+ 	"   .long	1b, 5b		\n"	\
+ 	"   .previous"				\
+-	:"=r" (err), "=r" (x)			\
++	:"=r" (err), "=r" (cb), "=r" (x)	\
+ 	:"r" (addr), "i" (-EFAULT), "0" (err))
+ 
+ 
+diff --git a/include/asm-xtensa/variant-fsf/tie-asm.h b/include/asm-xtensa/variant-fsf/tie-asm.h
+new file mode 100644
+index 0000000..68a73bf
+--- /dev/null
++++ b/include/asm-xtensa/variant-fsf/tie-asm.h
+@@ -0,0 +1,70 @@
++/*
++ * This header file contains assembly-language definitions (assembly
++ * macros, etc.) for this specific Xtensa processor's TIE extensions
++ * and options.  It is customized to this Xtensa processor configuration.
++ *
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 1999-2008 Tensilica Inc.
++ */
++
++#ifndef _XTENSA_CORE_TIE_ASM_H
++#define _XTENSA_CORE_TIE_ASM_H
++
++/*  Selection parameter values for save-area save/restore macros:  */
++/*  Option vs. TIE:  */
++#define XTHAL_SAS_TIE	0x0001	/* custom extension or coprocessor */
++#define XTHAL_SAS_OPT	0x0002	/* optional (and not a coprocessor) */
++/*  Whether used automatically by compiler:  */
++#define XTHAL_SAS_NOCC	0x0004	/* not used by compiler w/o special opts/code */
++#define XTHAL_SAS_CC	0x0008	/* used by compiler without special opts/code */
++/*  ABI handling across function calls:  */
++#define XTHAL_SAS_CALR	0x0010	/* caller-saved */
++#define XTHAL_SAS_CALE	0x0020	/* callee-saved */
++#define XTHAL_SAS_GLOB	0x0040	/* global across function calls (in thread) */
++/*  Misc  */
++#define XTHAL_SAS_ALL	0xFFFF	/* include all default NCP contents */
++
++
++
++/* Macro to save all non-coprocessor (extra) custom TIE and optional state
++ * (not including zero-overhead loop registers).
++ * Save area ptr (clobbered):  ptr  (1 byte aligned)
++ * Scratch regs  (clobbered):  at1..at4  (only first XCHAL_NCP_NUM_ATMPS needed)
++ */
++	.macro xchal_ncp_store  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL
++	xchal_sa_start	\continue, \ofs
++	.ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~\select
++	xchal_sa_align	\ptr, 0, 1024-4, 4, 4
++	rur	\at1, THREADPTR		// threadptr option
++	s32i	\at1, \ptr, .Lxchal_ofs_ + 0
++	.set	.Lxchal_ofs_, .Lxchal_ofs_ + 4
++	.endif
++	.endm	// xchal_ncp_store
++
++/* Macro to save all non-coprocessor (extra) custom TIE and optional state
++ * (not including zero-overhead loop registers).
++ * Save area ptr (clobbered):  ptr  (1 byte aligned)
++ * Scratch regs  (clobbered):  at1..at4  (only first XCHAL_NCP_NUM_ATMPS needed)
++ */
++	.macro xchal_ncp_load  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL
++	xchal_sa_start	\continue, \ofs
++	.ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~\select
++	xchal_sa_align	\ptr, 0, 1024-4, 4, 4
++	l32i	\at1, \ptr, .Lxchal_ofs_ + 0
++	wur	\at1, THREADPTR		// threadptr option
++	.set	.Lxchal_ofs_, .Lxchal_ofs_ + 4
++	.endif
++	.endm	// xchal_ncp_load
++
++
++
++#define XCHAL_NCP_NUM_ATMPS	1
++
++
++#define XCHAL_SA_NUM_ATMPS	1
++
++#endif /*_XTENSA_CORE_TIE_ASM_H*/
++
+diff --git a/include/asm-xtensa/variant-fsf/tie.h b/include/asm-xtensa/variant-fsf/tie.h
+index a73c716..bf40201 100644
+--- a/include/asm-xtensa/variant-fsf/tie.h
++++ b/include/asm-xtensa/variant-fsf/tie.h
+@@ -1,22 +1,77 @@
+ /*
+- * Xtensa processor core configuration information.
++ * This header file describes this specific Xtensa processor's TIE extensions
++ * that extend basic Xtensa core functionality.  It is customized to this
++ * Xtensa processor configuration.
+  *
+  * This file is subject to the terms and conditions of the GNU General Public
+  * License.  See the file "COPYING" in the main directory of this archive
+  * for more details.
+  *
+- * Copyright (C) 1999-2006 Tensilica Inc.
++ * Copyright (C) 1999-2007 Tensilica Inc.
+  */
+ 
+-#ifndef XTENSA_TIE_H
+-#define XTENSA_TIE_H
+-
+-/*----------------------------------------------------------------------
+-			COPROCESSORS and EXTRA STATE
+-  ----------------------------------------------------------------------*/
++#ifndef _XTENSA_CORE_TIE_H
++#define _XTENSA_CORE_TIE_H
+ 
+ #define XCHAL_CP_NUM			0	/* number of coprocessors */
+-#define XCHAL_CP_MASK			0x00
++#define XCHAL_CP_MAX			0	/* max CP ID + 1 (0 if none) */
++#define XCHAL_CP_MASK			0x00	/* bitmask of all CPs by ID */
++#define XCHAL_CP_PORT_MASK		0x00	/* bitmask of only port CPs */
++
++/*  Basic parameters of each coprocessor:  */
++#define XCHAL_CP7_NAME			"XTIOP"
++#define XCHAL_CP7_IDENT			XTIOP
++#define XCHAL_CP7_SA_SIZE		0	/* size of state save area */
++#define XCHAL_CP7_SA_ALIGN		1	/* min alignment of save area */
++#define XCHAL_CP_ID_XTIOP		7	/* coprocessor ID (0..7) */
++
++/*  Filler info for unassigned coprocessors, to simplify arrays etc:  */
++#define XCHAL_NCP_SA_SIZE		0
++#define XCHAL_NCP_SA_ALIGN		1
++#define XCHAL_CP0_SA_SIZE		0
++#define XCHAL_CP0_SA_ALIGN		1
++#define XCHAL_CP1_SA_SIZE		0
++#define XCHAL_CP1_SA_ALIGN		1
++#define XCHAL_CP2_SA_SIZE		0
++#define XCHAL_CP2_SA_ALIGN		1
++#define XCHAL_CP3_SA_SIZE		0
++#define XCHAL_CP3_SA_ALIGN		1
++#define XCHAL_CP4_SA_SIZE		0
++#define XCHAL_CP4_SA_ALIGN		1
++#define XCHAL_CP5_SA_SIZE		0
++#define XCHAL_CP5_SA_ALIGN		1
++#define XCHAL_CP6_SA_SIZE		0
++#define XCHAL_CP6_SA_ALIGN		1
++
++/*  Save area for non-coprocessor optional and custom (TIE) state:  */
++#define XCHAL_NCP_SA_SIZE		0
++#define XCHAL_NCP_SA_ALIGN		1
++
++/*  Total save area for optional and custom state (NCP + CPn):  */
++#define XCHAL_TOTAL_SA_SIZE		0	/* with 16-byte align padding */
++#define XCHAL_TOTAL_SA_ALIGN		1	/* actual minimum alignment */
++
++#define XCHAL_NCP_SA_NUM	0
++#define XCHAL_NCP_SA_LIST(s)
++#define XCHAL_CP0_SA_NUM	0
++#define XCHAL_CP0_SA_LIST(s)
++#define XCHAL_CP1_SA_NUM	0
++#define XCHAL_CP1_SA_LIST(s)
++#define XCHAL_CP2_SA_NUM	0
++#define XCHAL_CP2_SA_LIST(s)
++#define XCHAL_CP3_SA_NUM	0
++#define XCHAL_CP3_SA_LIST(s)
++#define XCHAL_CP4_SA_NUM	0
++#define XCHAL_CP4_SA_LIST(s)
++#define XCHAL_CP5_SA_NUM	0
++#define XCHAL_CP5_SA_LIST(s)
++#define XCHAL_CP6_SA_NUM	0
++#define XCHAL_CP6_SA_LIST(s)
++#define XCHAL_CP7_SA_NUM	0
++#define XCHAL_CP7_SA_LIST(s)
++
++/* Byte length of instruction from its first nibble (op0 field), per FLIX.  */
++#define XCHAL_OP0_FORMAT_LENGTHS	3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3
+ 
+-#endif /*XTENSA_CONFIG_TIE_H*/
++#endif /*_XTENSA_CORE_TIE_H*/
+ 
+diff --git a/include/linux/Kbuild b/include/linux/Kbuild
+index 5cae9b5..aada32f 100644
+--- a/include/linux/Kbuild
++++ b/include/linux/Kbuild
+@@ -70,7 +70,6 @@ header-y += fuse.h
+ header-y += genetlink.h
+ header-y += gen_stats.h
+ header-y += gigaset_dev.h
+-header-y += hdsmart.h
+ header-y += hysdn_if.h
+ header-y += i2o-dev.h
+ header-y += i8k.h
+@@ -211,6 +210,7 @@ unifdef-y += hayesesp.h
+ unifdef-y += hdlcdrv.h
+ unifdef-y += hdlc.h
+ unifdef-y += hdreg.h
++unifdef-y += hdsmart.h
+ unifdef-y += hiddev.h
+ unifdef-y += hpet.h
+ unifdef-y += i2c.h
+diff --git a/include/linux/aio.h b/include/linux/aio.h
+index a9931e2..0d0b7f6 100644
+--- a/include/linux/aio.h
++++ b/include/linux/aio.h
+@@ -105,7 +105,6 @@ struct kiocb {
+ 	wait_queue_t		ki_wait;
+ 	loff_t			ki_pos;
+ 
+-	atomic_t		ki_bio_count;	/* num bio used for this iocb */
+ 	void			*private;
+ 	/* State that we remember to be able to restart/retry  */
+ 	unsigned short		ki_opcode;
+diff --git a/include/linux/bio.h b/include/linux/bio.h
+index 4da4413..4c59bdc 100644
+--- a/include/linux/bio.h
++++ b/include/linux/bio.h
+@@ -326,7 +326,6 @@ extern struct bio *bio_map_kern(struct request_queue *, void *, unsigned int,
+ 				gfp_t);
+ extern void bio_set_pages_dirty(struct bio *bio);
+ extern void bio_check_pages_dirty(struct bio *bio);
+-extern void bio_release_pages(struct bio *bio);
+ extern struct bio *bio_copy_user(struct request_queue *, unsigned long, unsigned int, int);
+ extern int bio_uncopy_user(struct bio *);
+ void zero_fill_bio(struct bio *bio);
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index e1888cc..6fe67d1 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -216,6 +216,7 @@ struct request {
+ 	unsigned int cmd_len;
+ 	unsigned char cmd[BLK_MAX_CDB];
+ 
++	unsigned int raw_data_len;
+ 	unsigned int data_len;
+ 	unsigned int sense_len;
+ 	void *data;
+@@ -258,6 +259,7 @@ struct bio_vec;
+ typedef int (merge_bvec_fn) (struct request_queue *, struct bio *, struct bio_vec *);
+ typedef void (prepare_flush_fn) (struct request_queue *, struct request *);
+ typedef void (softirq_done_fn)(struct request *);
++typedef int (dma_drain_needed_fn)(struct request *);
+ 
+ enum blk_queue_state {
+ 	Queue_down,
+@@ -294,6 +296,7 @@ struct request_queue
+ 	merge_bvec_fn		*merge_bvec_fn;
+ 	prepare_flush_fn	*prepare_flush_fn;
+ 	softirq_done_fn		*softirq_done_fn;
++	dma_drain_needed_fn	*dma_drain_needed;
+ 
+ 	/*
+ 	 * Dispatch queue sorting
+@@ -698,8 +701,9 @@ extern void blk_queue_max_hw_segments(struct request_queue *, unsigned short);
+ extern void blk_queue_max_segment_size(struct request_queue *, unsigned int);
+ extern void blk_queue_hardsect_size(struct request_queue *, unsigned short);
+ extern void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b);
+-extern int blk_queue_dma_drain(struct request_queue *q, void *buf,
+-			       unsigned int size);
++extern int blk_queue_dma_drain(struct request_queue *q,
++			       dma_drain_needed_fn *dma_drain_needed,
++			       void *buf, unsigned int size);
+ extern void blk_queue_segment_boundary(struct request_queue *, unsigned long);
+ extern void blk_queue_prep_rq(struct request_queue *, prep_rq_fn *pfn);
+ extern void blk_queue_merge_bvec(struct request_queue *, merge_bvec_fn *);
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 98ffb6e..b84b848 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1590,7 +1590,6 @@ extern void bd_set_size(struct block_device *, loff_t size);
+ extern void bd_forget(struct inode *inode);
+ extern void bdput(struct block_device *);
+ extern struct block_device *open_by_devnum(dev_t, unsigned);
+-extern const struct address_space_operations def_blk_aops;
+ #else
+ static inline void bd_forget(struct inode *inode) {}
+ #endif
+diff --git a/include/linux/hdsmart.h b/include/linux/hdsmart.h
+index e691921..4f4faf9 100644
+--- a/include/linux/hdsmart.h
++++ b/include/linux/hdsmart.h
+@@ -17,7 +17,7 @@
+ #ifndef _LINUX_HDSMART_H
+ #define _LINUX_HDSMART_H
+ 
+-#ifndef __KERNEL
++#ifndef __KERNEL__
+ #define OFFLINE_FULL_SCAN		0
+ #define SHORT_SELF_TEST			1
+ #define EXTEND_SELF_TEST		2
+@@ -121,6 +121,6 @@ typedef struct ata_smart_selftestlog_s {
+ 	unsigned char			resevered[2];
+ 	unsigned char			chksum;
+ } __attribute__ ((packed)) ata_smart_selftestlog_t;
+-#endif /* __KERNEL__ *
++#endif /* __KERNEL__ */
+ 
+ #endif	/* _LINUX_HDSMART_H */
+diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
+index e157c13..42dc6a3 100644
+--- a/include/linux/if_ether.h
++++ b/include/linux/if_ether.h
+@@ -129,8 +129,7 @@ extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len);
+ /*
+  *	Display a 6 byte device address (MAC) in a readable format.
+  */
+-extern char *print_mac(char *buf, const unsigned char *addr);
+-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
++extern __pure char *print_mac(char *buf, const unsigned char *addr);
+ #define MAC_BUF_SIZE	18
+ #define DECLARE_MAC_BUF(var) char var[MAC_BUF_SIZE] __maybe_unused
+ 
+diff --git a/include/linux/init.h b/include/linux/init.h
+index a404a00..fb58c04 100644
+--- a/include/linux/init.h
++++ b/include/linux/init.h
+@@ -42,6 +42,7 @@
+    discard it in modules) */
+ #define __init		__section(.init.text) __cold
+ #define __initdata	__section(.init.data)
++#define __initconst	__section(.init.rodata)
+ #define __exitdata	__section(.exit.data)
+ #define __exit_call	__used __section(.exitcall.exit)
+ 
+@@ -106,6 +107,7 @@
+ #define __memexitconst   __section(.memexit.rodata)
+ 
+ /* For assembly routines */
++#define __HEAD		.section	".head.text","ax"
+ #define __INIT		.section	".init.text","ax"
+ #define __FINIT		.previous
+ 
+diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h
+index 593b222..1b4ccf2 100644
+--- a/include/linux/iocontext.h
++++ b/include/linux/iocontext.h
+@@ -50,6 +50,7 @@ struct cfq_io_context {
+ 	sector_t seek_mean;
+ 
+ 	struct list_head queue_list;
++	struct hlist_node cic_list;
+ 
+ 	void (*dtor)(struct io_context *); /* destructor */
+ 	void (*exit)(struct io_context *); /* called on task exit */
+@@ -77,6 +78,7 @@ struct io_context {
+ 
+ 	struct as_io_context *aic;
+ 	struct radix_tree_root radix_root;
++	struct hlist_head cic_list;
+ 	void *ioc_data;
+ };
+ 
+diff --git a/include/linux/libata.h b/include/linux/libata.h
+index bc5a8d0..ce7603a 100644
+--- a/include/linux/libata.h
++++ b/include/linux/libata.h
+@@ -278,7 +278,6 @@ enum {
+ 
+ 	/* size of buffer to pad xfers ending on unaligned boundaries */
+ 	ATA_DMA_PAD_SZ		= 4,
+-	ATA_DMA_PAD_BUF_SZ	= ATA_DMA_PAD_SZ * ATA_MAX_QUEUE,
+ 
+ 	/* ering size */
+ 	ATA_ERING_SIZE		= 32,
+@@ -457,24 +456,18 @@ struct ata_queued_cmd {
+ 	unsigned long		flags;		/* ATA_QCFLAG_xxx */
+ 	unsigned int		tag;
+ 	unsigned int		n_elem;
+-	unsigned int		mapped_n_elem;
+ 
+ 	int			dma_dir;
+ 
+-	unsigned int		pad_len;
+ 	unsigned int		sect_size;
+ 
+ 	unsigned int		nbytes;
+-	unsigned int		raw_nbytes;
+ 	unsigned int		curbytes;
+ 
+ 	struct scatterlist	*cursg;
+ 	unsigned int		cursg_ofs;
+ 
+-	struct scatterlist	*last_sg;
+-	struct scatterlist	saved_last_sg;
+ 	struct scatterlist	sgent;
+-	struct scatterlist	extra_sg[2];
+ 
+ 	struct scatterlist	*sg;
+ 
+@@ -619,9 +612,6 @@ struct ata_port {
+ 	struct ata_prd		*prd;	 /* our SG list */
+ 	dma_addr_t		prd_dma; /* and its DMA mapping */
+ 
+-	void			*pad;	/* array of DMA pad buffers */
+-	dma_addr_t		pad_dma;
+-
+ 	struct ata_ioports	ioaddr;	/* ATA cmd/ctl/dma register blocks */
+ 
+ 	u8			ctl;	/* cache of ATA control register */
+@@ -1207,7 +1197,7 @@ static inline struct ata_link *ata_port_next_link(struct ata_link *link)
+ 		return ap->pmp_link;
+ 	}
+ 
+-	if (++link - ap->pmp_link < ap->nr_pmp_links)
++	if (++link < ap->nr_pmp_links + ap->pmp_link)
+ 		return link;
+ 	return NULL;
+ }
+@@ -1363,12 +1353,9 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
+ 	qc->flags = 0;
+ 	qc->cursg = NULL;
+ 	qc->cursg_ofs = 0;
+-	qc->nbytes = qc->raw_nbytes = qc->curbytes = 0;
++	qc->nbytes = qc->curbytes = 0;
+ 	qc->n_elem = 0;
+-	qc->mapped_n_elem = 0;
+ 	qc->err_mask = 0;
+-	qc->pad_len = 0;
+-	qc->last_sg = NULL;
+ 	qc->sect_size = ATA_SECT_SIZE;
+ 
+ 	ata_tf_init(qc->dev, &qc->tf);
+@@ -1423,19 +1410,6 @@ static inline unsigned int __ac_err_mask(u8 status)
+ 	return mask;
+ }
+ 
+-static inline int ata_pad_alloc(struct ata_port *ap, struct device *dev)
+-{
+-	ap->pad_dma = 0;
+-	ap->pad = dmam_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ,
+-				      &ap->pad_dma, GFP_KERNEL);
+-	return (ap->pad == NULL) ? -ENOMEM : 0;
+-}
+-
+-static inline void ata_pad_free(struct ata_port *ap, struct device *dev)
+-{
+-	dmam_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma);
+-}
+-
+ static inline struct ata_port *ata_shost_to_port(struct Scsi_Host *host)
+ {
+ 	return *(struct ata_port **)&host->hostdata[0];
+diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
+index df6dd79..0519e53 100644
+--- a/include/linux/pci_ids.h
++++ b/include/linux/pci_ids.h
+@@ -1351,6 +1351,7 @@
+ #define PCI_DEVICE_ID_VIA_8231_4	0x8235
+ #define PCI_DEVICE_ID_VIA_8365_1	0x8305
+ #define PCI_DEVICE_ID_VIA_CX700		0x8324
++#define PCI_DEVICE_ID_VIA_CX700_IDE	0x0581
+ #define PCI_DEVICE_ID_VIA_VX800		0x8353
+ #define PCI_DEVICE_ID_VIA_8371_1	0x8391
+ #define PCI_DEVICE_ID_VIA_82C598_1	0x8598
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
+index 412672a..bbd8d00 100644
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -232,6 +232,8 @@ typedef unsigned char *sk_buff_data_t;
+  *	@mark: Generic packet mark
+  *	@nfct: Associated connection, if any
+  *	@ipvs_property: skbuff is owned by ipvs
++ *	@peeked: this packet has been seen already, so stats have been
++ *		done for it, don't do them again
+  *	@nf_trace: netfilter packet trace flag
+  *	@nfctinfo: Relationship of this skb to the connection
+  *	@nfct_reasm: netfilter conntrack re-assembly pointer
+diff --git a/include/linux/videodev.h b/include/linux/videodev.h
+index 52e3d5f..9385a56 100644
+--- a/include/linux/videodev.h
++++ b/include/linux/videodev.h
+@@ -12,6 +12,7 @@
+ #ifndef __LINUX_VIDEODEV_H
+ #define __LINUX_VIDEODEV_H
+ 
++#include <linux/ioctl.h>
+ #include <linux/videodev2.h>
+ 
+ #if defined(CONFIG_VIDEO_V4L1_COMPAT) || !defined (__KERNEL__)
+diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
+index 439474f..17a8017 100644
+--- a/include/linux/videodev2.h
++++ b/include/linux/videodev2.h
+@@ -62,6 +62,7 @@
+ #define __user
+ #include <sys/time.h>
+ #endif
++#include <linux/ioctl.h>
+ #include <linux/types.h>
+ 
+ /*
+diff --git a/include/media/ir-common.h b/include/media/ir-common.h
+index 831547d..a427420 100644
+--- a/include/media/ir-common.h
++++ b/include/media/ir-common.h
+@@ -142,6 +142,7 @@ extern IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE];
+ extern IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE];
+ extern IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE];
+ extern IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE];
++extern IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE];
+ 
+ #endif
+ 
+diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
+index 475d0d8..316a584 100644
+--- a/include/media/v4l2-common.h
++++ b/include/media/v4l2-common.h
+@@ -61,8 +61,6 @@
+ 			v4l_client_printk(KERN_DEBUG, client, fmt , ## arg); \
+ 	} while (0)
+ 
+-/* Prints the ioctl in a human-readable format */
+-extern void v4l_printk_ioctl(unsigned int cmd);
+ 
+ /* Use this macro for non-I2C drivers. Pass the driver name as the first arg. */
+ #define v4l_print_ioctl(name, cmd)  		 \
+diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
+index c544c6f..f211445 100644
+--- a/include/media/v4l2-dev.h
++++ b/include/media/v4l2-dev.h
+@@ -44,6 +44,8 @@ extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs);
+ extern char *v4l2_norm_to_name(v4l2_std_id id);
+ extern int v4l2_video_std_construct(struct v4l2_standard *vs,
+ 				    int id, char *name);
++/* Prints the ioctl in a human-readable format */
++extern void v4l_printk_ioctl(unsigned int cmd);
+ 
+ /* prority handling */
+ struct v4l2_prio_state {
+diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h
+index 97f14d4..9903394 100644
+--- a/include/media/videobuf-core.h
++++ b/include/media/videobuf-core.h
+@@ -149,7 +149,7 @@ struct videobuf_qtype_ops {
+ };
+ 
+ struct videobuf_queue {
+-	struct mutex               lock;
++	struct mutex               vb_lock;
+ 	spinlock_t                 *irqlock;
+ 	void			   *dev; /* on pci, points to struct pci_dev */
+ 
+diff --git a/include/media/videobuf-vmalloc.h b/include/media/videobuf-vmalloc.h
+index 26a8958..ec63ab0 100644
+--- a/include/media/videobuf-vmalloc.h
++++ b/include/media/videobuf-vmalloc.h
+@@ -17,7 +17,7 @@
+ 
+ /* --------------------------------------------------------------------- */
+ 
+-struct videbuf_vmalloc_memory
++struct videobuf_vmalloc_memory
+ {
+ 	u32                 magic;
+ 
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 8a7889b..fd98760 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -180,6 +180,7 @@ struct sock_common {
+   *	@sk_sndmsg_off: cached offset for sendmsg
+   *	@sk_send_head: front of stuff to transmit
+   *	@sk_security: used by security modules
++  *	@sk_mark: generic packet mark
+   *	@sk_write_pending: a write to stream socket waits to start
+   *	@sk_state_change: callback to indicate change in the state of the sock
+   *	@sk_data_ready: callback to indicate there is data to be processed
+diff --git a/kernel/auditsc.c b/kernel/auditsc.c
+index ac6d9b2..2087d6d 100644
+--- a/kernel/auditsc.c
++++ b/kernel/auditsc.c
+@@ -1000,9 +1000,10 @@ static int audit_log_single_execve_arg(struct audit_context *context,
+ 	 * for strings that are too long, we should not have created
+ 	 * any.
+ 	 */
+-	if (unlikely((len  = -1) || len > MAX_ARG_STRLEN - 1)) {
++	if (unlikely((len == -1) || len > MAX_ARG_STRLEN - 1)) {
+ 		WARN_ON(1);
+ 		send_sig(SIGKILL, current, 0);
++		return -1;
+ 	}
+ 
+ 	/* walk the whole argument looking for non-ascii chars */
+@@ -1020,6 +1021,7 @@ static int audit_log_single_execve_arg(struct audit_context *context,
+ 		if (ret) {
+ 			WARN_ON(1);
+ 			send_sig(SIGKILL, current, 0);
++			return -1;
+ 		}
+ 		buf[to_send] = '\0';
+ 		has_cntl = audit_string_contains_control(buf, to_send);
+@@ -1083,6 +1085,7 @@ static int audit_log_single_execve_arg(struct audit_context *context,
+ 		if (ret) {
+ 			WARN_ON(1);
+ 			send_sig(SIGKILL, current, 0);
++			return -1;
+ 		}
+ 		buf[to_send] = '\0';
+ 
+diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
+index cc54c62..fdb3fbe 100644
+--- a/kernel/irq/chip.c
++++ b/kernel/irq/chip.c
+@@ -246,6 +246,17 @@ static unsigned int default_startup(unsigned int irq)
+ }
+ 
+ /*
++ * default shutdown function
++ */
++static void default_shutdown(unsigned int irq)
++{
++	struct irq_desc *desc = irq_desc + irq;
++
++	desc->chip->mask(irq);
++	desc->status |= IRQ_MASKED;
++}
++
++/*
+  * Fixup enable/disable function pointers
+  */
+ void irq_chip_set_defaults(struct irq_chip *chip)
+@@ -256,8 +267,15 @@ void irq_chip_set_defaults(struct irq_chip *chip)
+ 		chip->disable = default_disable;
+ 	if (!chip->startup)
+ 		chip->startup = default_startup;
++	/*
++	 * We use chip->disable, when the user provided its own. When
++	 * we have default_disable set for chip->disable, then we need
++	 * to use default_shutdown, otherwise the irq line is not
++	 * disabled on free_irq():
++	 */
+ 	if (!chip->shutdown)
+-		chip->shutdown = chip->disable;
++		chip->shutdown = chip->disable != default_disable ?
++			chip->disable : default_shutdown;
+ 	if (!chip->name)
+ 		chip->name = chip->typename;
+ 	if (!chip->end)
+diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
+index a6b2bc8..088dabb 100644
+--- a/kernel/irq/spurious.c
++++ b/kernel/irq/spurious.c
+@@ -6,6 +6,7 @@
+  * This file contains spurious interrupt handling.
+  */
+ 
++#include <linux/jiffies.h>
+ #include <linux/irq.h>
+ #include <linux/module.h>
+ #include <linux/kallsyms.h>
+@@ -179,7 +180,7 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
+ 		 * otherwise the couter becomes a doomsday timer for otherwise
+ 		 * working systems
+ 		 */
+-		if (jiffies - desc->last_unhandled > HZ/10)
++		if (time_after(jiffies, desc->last_unhandled + HZ/10))
+ 			desc->irqs_unhandled = 1;
+ 		else
+ 			desc->irqs_unhandled++;
+diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
+index d3d94c1..67fe8fc 100644
+--- a/kernel/time/timer_list.c
++++ b/kernel/time/timer_list.c
+@@ -65,9 +65,9 @@ print_timer(struct seq_file *m, struct hrtimer *timer, int idx, u64 now)
+ 	SEQ_printf(m, ", %s/%d", tmp, timer->start_pid);
+ #endif
+ 	SEQ_printf(m, "\n");
+-	SEQ_printf(m, " # expires at %Lu nsecs [in %Lu nsecs]\n",
++	SEQ_printf(m, " # expires at %Lu nsecs [in %Ld nsecs]\n",
+ 		(unsigned long long)ktime_to_ns(timer->expires),
+-		(unsigned long long)(ktime_to_ns(timer->expires) - now));
++		(long long)(ktime_to_ns(timer->expires) - now));
+ }
+ 
+ static void
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index a370fe8..ab408aa 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -82,6 +82,9 @@ config HEADERS_CHECK
+ config DEBUG_SECTION_MISMATCH
+ 	bool "Enable full Section mismatch analysis"
+ 	depends on UNDEFINED
++	# This option is on purpose disabled for now.
++	# It will be enabled when we are down to a resonable number
++	# of section mismatch warnings (< 10 for an allyesconfig build)
+ 	help
+ 	  The section mismatch analysis checks if there are illegal
+ 	  references from one section to another section.
+diff --git a/mm/slub.c b/mm/slub.c
+index 4b3895c..74c65af 100644
+--- a/mm/slub.c
++++ b/mm/slub.c
+@@ -149,13 +149,6 @@ static inline void ClearSlabDebug(struct page *page)
+ /* Enable to test recovery from slab corruption on boot */
+ #undef SLUB_RESILIENCY_TEST
+ 
+-/*
+- * Currently fastpath is not supported if preemption is enabled.
+- */
+-#if defined(CONFIG_FAST_CMPXCHG_LOCAL) && !defined(CONFIG_PREEMPT)
+-#define SLUB_FASTPATH
+-#endif
+-
+ #if PAGE_SHIFT <= 12
+ 
+ /*
+@@ -1514,11 +1507,7 @@ static void *__slab_alloc(struct kmem_cache *s,
+ {
+ 	void **object;
+ 	struct page *new;
+-#ifdef SLUB_FASTPATH
+-	unsigned long flags;
+ 
+-	local_irq_save(flags);
+-#endif
+ 	if (!c->page)
+ 		goto new_slab;
+ 
+@@ -1541,9 +1530,6 @@ load_freelist:
+ unlock_out:
+ 	slab_unlock(c->page);
+ 	stat(c, ALLOC_SLOWPATH);
+-#ifdef SLUB_FASTPATH
+-	local_irq_restore(flags);
+-#endif
+ 	return object;
+ 
+ another_slab:
+@@ -1575,9 +1561,7 @@ new_slab:
+ 		c->page = new;
+ 		goto load_freelist;
+ 	}
+-#ifdef SLUB_FASTPATH
+-	local_irq_restore(flags);
+-#endif
++
+ 	/*
+ 	 * No memory available.
+ 	 *
+@@ -1619,34 +1603,6 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
+ {
+ 	void **object;
+ 	struct kmem_cache_cpu *c;
+-
+-/*
+- * The SLUB_FASTPATH path is provisional and is currently disabled if the
+- * kernel is compiled with preemption or if the arch does not support
+- * fast cmpxchg operations. There are a couple of coming changes that will
+- * simplify matters and allow preemption. Ultimately we may end up making
+- * SLUB_FASTPATH the default.
+- *
+- * 1. The introduction of the per cpu allocator will avoid array lookups
+- *    through get_cpu_slab(). A special register can be used instead.
+- *
+- * 2. The introduction of per cpu atomic operations (cpu_ops) means that
+- *    we can realize the logic here entirely with per cpu atomics. The
+- *    per cpu atomic ops will take care of the preemption issues.
+- */
+-
+-#ifdef SLUB_FASTPATH
+-	c = get_cpu_slab(s, raw_smp_processor_id());
+-	do {
+-		object = c->freelist;
+-		if (unlikely(is_end(object) || !node_match(c, node))) {
+-			object = __slab_alloc(s, gfpflags, node, addr, c);
+-			break;
+-		}
+-		stat(c, ALLOC_FASTPATH);
+-	} while (cmpxchg_local(&c->freelist, object, object[c->offset])
+-								!= object);
+-#else
+ 	unsigned long flags;
+ 
+ 	local_irq_save(flags);
+@@ -1661,7 +1617,6 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
+ 		stat(c, ALLOC_FASTPATH);
+ 	}
+ 	local_irq_restore(flags);
+-#endif
+ 
+ 	if (unlikely((gfpflags & __GFP_ZERO) && object))
+ 		memset(object, 0, c->objsize);
+@@ -1698,11 +1653,6 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
+ 	void **object = (void *)x;
+ 	struct kmem_cache_cpu *c;
+ 
+-#ifdef SLUB_FASTPATH
+-	unsigned long flags;
+-
+-	local_irq_save(flags);
+-#endif
+ 	c = get_cpu_slab(s, raw_smp_processor_id());
+ 	stat(c, FREE_SLOWPATH);
+ 	slab_lock(page);
+@@ -1734,9 +1684,6 @@ checks_ok:
+ 
+ out_unlock:
+ 	slab_unlock(page);
+-#ifdef SLUB_FASTPATH
+-	local_irq_restore(flags);
+-#endif
+ 	return;
+ 
+ slab_empty:
+@@ -1749,9 +1696,6 @@ slab_empty:
+ 	}
+ 	slab_unlock(page);
+ 	stat(c, FREE_SLAB);
+-#ifdef SLUB_FASTPATH
+-	local_irq_restore(flags);
+-#endif
+ 	discard_slab(s, page);
+ 	return;
+ 
+@@ -1777,34 +1721,6 @@ static __always_inline void slab_free(struct kmem_cache *s,
+ {
+ 	void **object = (void *)x;
+ 	struct kmem_cache_cpu *c;
+-
+-#ifdef SLUB_FASTPATH
+-	void **freelist;
+-
+-	c = get_cpu_slab(s, raw_smp_processor_id());
+-	debug_check_no_locks_freed(object, s->objsize);
+-	do {
+-		freelist = c->freelist;
+-		barrier();
+-		/*
+-		 * If the compiler would reorder the retrieval of c->page to
+-		 * come before c->freelist then an interrupt could
+-		 * change the cpu slab before we retrieve c->freelist. We
+-		 * could be matching on a page no longer active and put the
+-		 * object onto the freelist of the wrong slab.
+-		 *
+-		 * On the other hand: If we already have the freelist pointer
+-		 * then any change of cpu_slab will cause the cmpxchg to fail
+-		 * since the freelist pointers are unique per slab.
+-		 */
+-		if (unlikely(page != c->page || c->node < 0)) {
+-			__slab_free(s, page, x, addr, c->offset);
+-			break;
+-		}
+-		object[c->offset] = freelist;
+-		stat(c, FREE_FASTPATH);
+-	} while (cmpxchg_local(&c->freelist, freelist, object) != freelist);
+-#else
+ 	unsigned long flags;
+ 
+ 	local_irq_save(flags);
+@@ -1818,7 +1734,6 @@ static __always_inline void slab_free(struct kmem_cache *s,
+ 		__slab_free(s, page, x, addr, c->offset);
+ 
+ 	local_irq_restore(flags);
+-#endif
+ }
+ 
+ void kmem_cache_free(struct kmem_cache *s, void *x)
+diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
+index 77f04e4..fc60c6d 100644
+--- a/net/8021q/vlan_dev.c
++++ b/net/8021q/vlan_dev.c
+@@ -366,7 +366,8 @@ static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+ 	struct net_device_stats *stats = &dev->stats;
+ 	struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data);
+-
++	DECLARE_MAC_BUF(mac);
++	DECLARE_MAC_BUF(mac2);
+ 	/* Handle non-VLAN frames if they are sent to us, for example by DHCP.
+ 	 *
+ 	 * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING
+@@ -404,11 +405,8 @@ static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 
+ 	pr_debug("%s: about to send skb: %p to dev: %s\n",
+ 		__FUNCTION__, skb, skb->dev->name);
+-	pr_debug("  " MAC_FMT " " MAC_FMT " %4hx %4hx %4hx\n",
+-		 veth->h_dest[0], veth->h_dest[1], veth->h_dest[2],
+-		 veth->h_dest[3], veth->h_dest[4], veth->h_dest[5],
+-		 veth->h_source[0], veth->h_source[1], veth->h_source[2],
+-		 veth->h_source[3], veth->h_source[4], veth->h_source[5],
++	pr_debug("  %s %s %4hx %4hx %4hx\n",
++		 print_mac(mac, veth->h_dest), print_mac(mac2, veth->h_source),
+ 		 veth->h_vlan_proto, veth->h_vlan_TCI,
+ 		 veth->h_vlan_encapsulated_proto);
+ 
+diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
+index 0117b9f..9e3d81c 100644
+--- a/net/9p/trans_virtio.c
++++ b/net/9p/trans_virtio.c
+@@ -183,8 +183,7 @@ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data,
+ 		sg_set_buf(&sg[index++], data, s);
+ 		count -= s;
+ 		data += s;
+-		if (index > limit)
+-			BUG();
++		BUG_ON(index > limit);
+ 	}
+ 
+ 	return index-start;
+diff --git a/net/ax25/ax25_out.c b/net/ax25/ax25_out.c
+index 92b517a..bf706f8 100644
+--- a/net/ax25/ax25_out.c
++++ b/net/ax25/ax25_out.c
+@@ -117,6 +117,12 @@ void ax25_output(ax25_cb *ax25, int paclen, struct sk_buff *skb)
+ 	unsigned char *p;
+ 	int frontlen, len, fragno, ka9qfrag, first = 1;
+ 
++	if (paclen < 16) {
++		WARN_ON_ONCE(1);
++		kfree_skb(skb);
++		return;
++	}
++
+ 	if ((skb->len - 1) > paclen) {
+ 		if (*skb->data == AX25_P_TEXT) {
+ 			skb_pull(skb, 1); /* skip PID */
+@@ -251,8 +257,6 @@ void ax25_kick(ax25_cb *ax25)
+ 	if (start == end)
+ 		return;
+ 
+-	ax25->vs = start;
+-
+ 	/*
+ 	 * Transmit data until either we're out of data to send or
+ 	 * the window is full. Send a poll on the final I frame if
+@@ -261,8 +265,13 @@ void ax25_kick(ax25_cb *ax25)
+ 
+ 	/*
+ 	 * Dequeue the frame and copy it.
++	 * Check for race with ax25_clear_queues().
+ 	 */
+ 	skb  = skb_dequeue(&ax25->write_queue);
++	if (!skb)
++		return;
++
++	ax25->vs = start;
+ 
+ 	do {
+ 		if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index 5fc7be2..f888026 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -260,7 +260,6 @@ int hci_conn_del(struct hci_conn *conn)
+ 	tasklet_enable(&hdev->tx_task);
+ 	skb_queue_purge(&conn->data_q);
+ 	hci_conn_del_sysfs(conn);
+-	hci_dev_put(hdev);
+ 
+ 	return 0;
+ }
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 372b0d3..930b58e 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -24,6 +24,7 @@
+ 
+ /* Bluetooth HCI core. */
+ 
++#include <linux/jiffies.h>
+ #include <linux/module.h>
+ #include <linux/kmod.h>
+ 
+@@ -1321,7 +1322,7 @@ static inline void hci_sched_acl(struct hci_dev *hdev)
+ 	if (!test_bit(HCI_RAW, &hdev->flags)) {
+ 		/* ACL tx timeout must be longer than maximum
+ 		 * link supervision timeout (40.9 seconds) */
+-		if (!hdev->acl_cnt && (jiffies - hdev->acl_last_tx) > (HZ * 45))
++		if (!hdev->acl_cnt && time_after(jiffies, hdev->acl_last_tx + HZ * 45))
+ 			hci_acl_tx_to(hdev);
+ 	}
+ 
+@@ -1543,7 +1544,7 @@ static void hci_cmd_task(unsigned long arg)
+ 
+ 	BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
+ 
+-	if (!atomic_read(&hdev->cmd_cnt) && (jiffies - hdev->cmd_last_tx) > HZ) {
++	if (!atomic_read(&hdev->cmd_cnt) && time_after(jiffies, hdev->cmd_last_tx + HZ)) {
+ 		BT_ERR("%s command tx timeout", hdev->name);
+ 		atomic_set(&hdev->cmd_cnt, 1);
+ 	}
+diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
+index e13cf5e..84360c1 100644
+--- a/net/bluetooth/hci_sysfs.c
++++ b/net/bluetooth/hci_sysfs.c
+@@ -320,28 +320,34 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
+ 	queue_work(btaddconn, &conn->work);
+ }
+ 
++/*
++ * The rfcomm tty device will possibly retain even when conn
++ * is down, and sysfs doesn't support move zombie device,
++ * so we should move the device before conn device is destroyed.
++ */
+ static int __match_tty(struct device *dev, void *data)
+ {
+-	/* The rfcomm tty device will possibly retain even when conn
+-	 * is down, and sysfs doesn't support move zombie device,
+-	 * so we should move the device before conn device is destroyed.
+-	 * Due to the only child device of hci_conn dev is rfcomm
+-	 * tty_dev, here just return 1
+-	 */
+-	return 1;
++	return !strncmp(dev->bus_id, "rfcomm", 6);
+ }
+ 
+ static void del_conn(struct work_struct *work)
+ {
+-	struct device *dev;
+ 	struct hci_conn *conn = container_of(work, struct hci_conn, work);
++	struct hci_dev *hdev = conn->hdev;
++
++	while (1) {
++		struct device *dev;
+ 
+-	while (dev = device_find_child(&conn->dev, NULL, __match_tty)) {
++		dev = device_find_child(&conn->dev, NULL, __match_tty);
++		if (!dev)
++			break;
+ 		device_move(dev, NULL);
+ 		put_device(dev);
+ 	}
++
+ 	device_del(&conn->dev);
+ 	put_device(&conn->dev);
++	hci_dev_put(hdev);
+ }
+ 
+ void hci_conn_del_sysfs(struct hci_conn *conn)
+diff --git a/net/core/neighbour.c b/net/core/neighbour.c
+index 7bb6a9a..a16cf1e 100644
+--- a/net/core/neighbour.c
++++ b/net/core/neighbour.c
+@@ -834,12 +834,18 @@ static void neigh_timer_handler(unsigned long arg)
+ 	}
+ 	if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) {
+ 		struct sk_buff *skb = skb_peek(&neigh->arp_queue);
+-
++		/* keep skb alive even if arp_queue overflows */
++		if (skb)
++			skb_get(skb);
++		write_unlock(&neigh->lock);
+ 		neigh->ops->solicit(neigh, skb);
+ 		atomic_inc(&neigh->probes);
+-	}
++		if (skb)
++			kfree_skb(skb);
++	} else {
+ out:
+-	write_unlock(&neigh->lock);
++		write_unlock(&neigh->lock);
++	}
+ 
+ 	if (notify)
+ 		neigh_update_notify(neigh);
+diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
+index ecb02af..61ac8d0 100644
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -504,7 +504,7 @@ int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst, u32 id,
+ 
+ EXPORT_SYMBOL_GPL(rtnl_put_cacheinfo);
+ 
+-static int set_operstate(struct net_device *dev, unsigned char transition, bool send_notification)
++static void set_operstate(struct net_device *dev, unsigned char transition)
+ {
+ 	unsigned char operstate = dev->operstate;
+ 
+@@ -527,12 +527,8 @@ static int set_operstate(struct net_device *dev, unsigned char transition, bool
+ 		write_lock_bh(&dev_base_lock);
+ 		dev->operstate = operstate;
+ 		write_unlock_bh(&dev_base_lock);
+-
+-		if (send_notification)
+-			netdev_state_change(dev);
+-		return 1;
+-	} else
+-		return 0;
++		netdev_state_change(dev);
++	}
+ }
+ 
+ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
+@@ -826,7 +822,6 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
+ 	if (tb[IFLA_BROADCAST]) {
+ 		nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len);
+ 		send_addr_notify = 1;
+-		modified = 1;
+ 	}
+ 
+ 	if (ifm->ifi_flags || ifm->ifi_change) {
+@@ -839,23 +834,16 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
+ 		dev_change_flags(dev, flags);
+ 	}
+ 
+-	if (tb[IFLA_TXQLEN]) {
+-		if (dev->tx_queue_len != nla_get_u32(tb[IFLA_TXQLEN])) {
+-			dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
+-			modified = 1;
+-		}
+-	}
++	if (tb[IFLA_TXQLEN])
++		dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
+ 
+ 	if (tb[IFLA_OPERSTATE])
+-		modified |= set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]), false);
++		set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
+ 
+ 	if (tb[IFLA_LINKMODE]) {
+-		if (dev->link_mode != nla_get_u8(tb[IFLA_LINKMODE])) {
+-			write_lock_bh(&dev_base_lock);
+-			dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
+-			write_lock_bh(&dev_base_lock);
+-			modified = 1;
+-		}
++		write_lock_bh(&dev_base_lock);
++		dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
++		write_unlock_bh(&dev_base_lock);
+ 	}
+ 
+ 	err = 0;
+@@ -869,10 +857,6 @@ errout:
+ 
+ 	if (send_addr_notify)
+ 		call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
+-
+-	if (modified)
+-		netdev_state_change(dev);
+-
+ 	return err;
+ }
+ 
+@@ -990,7 +974,7 @@ struct net_device *rtnl_create_link(struct net *net, char *ifname,
+ 	if (tb[IFLA_TXQLEN])
+ 		dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
+ 	if (tb[IFLA_OPERSTATE])
+-		set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]), true);
++		set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
+ 	if (tb[IFLA_LINKMODE])
+ 		dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
+ 
+diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
+index c663fa5..8e17f65 100644
+--- a/net/ipv4/arp.c
++++ b/net/ipv4/arp.c
+@@ -368,6 +368,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
+ 		if (!(neigh->nud_state&NUD_VALID))
+ 			printk(KERN_DEBUG "trying to ucast probe in NUD_INVALID\n");
+ 		dst_ha = neigh->ha;
++		read_lock_bh(&neigh->lock);
+ 	} else if ((probes -= neigh->parms->app_probes) < 0) {
+ #ifdef CONFIG_ARPD
+ 		neigh_app_ns(neigh);
+@@ -377,6 +378,8 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
+ 
+ 	arp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,
+ 		 dst_ha, dev->dev_addr, NULL);
++	if (dst_ha)
++		read_unlock_bh(&neigh->lock);
+ }
+ 
+ static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip)
+diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
+index a52b585..10013cc 100644
+--- a/net/ipv4/ipconfig.c
++++ b/net/ipv4/ipconfig.c
+@@ -1390,7 +1390,7 @@ static int __init ip_auto_config(void)
+ 	 * Clue in the operator.
+ 	 */
+ 	printk("IP-Config: Complete:");
+-	printk("\n      device=%s", ic_dev->name);
++	printk("\n     device=%s", ic_dev->name);
+ 	printk(", addr=%u.%u.%u.%u", NIPQUAD(ic_myaddr));
+ 	printk(", mask=%u.%u.%u.%u", NIPQUAD(ic_netmask));
+ 	printk(", gw=%u.%u.%u.%u", NIPQUAD(ic_gateway));
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index 63414ea..00156bf 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -719,7 +719,7 @@ static void tcp_v4_reqsk_send_ack(struct sk_buff *skb,
+ }
+ 
+ /*
+- *	Send a SYN-ACK after having received an ACK.
++ *	Send a SYN-ACK after having received a SYN.
+  *	This still operates on a request_sock only, not on a big
+  *	socket.
+  */
+diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
+index bddac0e..f0aa977 100644
+--- a/net/ipv6/af_inet6.c
++++ b/net/ipv6/af_inet6.c
+@@ -752,14 +752,6 @@ static int __init inet6_init(void)
+ 
+ 	BUILD_BUG_ON(sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb));
+ 
+-#ifdef MODULE
+-#if 0 /* FIXME --RR */
+-	if (!mod_member_present(&__this_module, can_unload))
+-	  return -EINVAL;
+-
+-	__this_module.can_unload = &ipv6_unload;
+-#endif
+-#endif
+ 	err = proto_register(&tcpv6_prot, 1);
+ 	if (err)
+ 		goto out;
+diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
+index f93407c..bab72b6 100644
+--- a/net/ipv6/ip6_fib.c
++++ b/net/ipv6/ip6_fib.c
+@@ -1151,7 +1151,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
+ 			fn = fn->parent;
+ 		}
+ 		/* No more references are possible at this point. */
+-		if (atomic_read(&rt->rt6i_ref) != 1) BUG();
++		BUG_ON(atomic_read(&rt->rt6i_ref) != 1);
+ 	}
+ 
+ 	inet6_rt_notify(RTM_DELROUTE, rt, info);
+diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
+index 9031e52..cd94064 100644
+--- a/net/ipv6/ip6_tunnel.c
++++ b/net/ipv6/ip6_tunnel.c
+@@ -550,6 +550,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+ 			ip_rt_put(rt);
+ 			goto out;
+ 		}
++		skb2->dst = (struct dst_entry *)rt;
+ 	} else {
+ 		ip_rt_put(rt);
+ 		if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos,
+diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
+index 67b7c75..28bcdf9 100644
+--- a/net/mac80211/ieee80211.c
++++ b/net/mac80211/ieee80211.c
+@@ -165,6 +165,7 @@ static int ieee80211_open(struct net_device *dev)
+ 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+ 	struct ieee80211_if_init_conf conf;
+ 	int res;
++	bool need_hw_reconfig = 0;
+ 
+ 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ 
+@@ -218,7 +219,7 @@ static int ieee80211_open(struct net_device *dev)
+ 			res = local->ops->start(local_to_hw(local));
+ 		if (res)
+ 			return res;
+-		ieee80211_hw_config(local);
++		need_hw_reconfig = 1;
+ 		ieee80211_led_radio(local, local->hw.conf.radio_enabled);
+ 	}
+ 
+@@ -282,6 +283,8 @@ static int ieee80211_open(struct net_device *dev)
+ 		atomic_inc(&local->iff_promiscs);
+ 
+ 	local->open_count++;
++	if (need_hw_reconfig)
++		ieee80211_hw_config(local);
+ 
+ 	netif_start_queue(dev);
+ 
+diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
+index c7ad64d..fdc14a0 100644
+--- a/net/netlabel/netlabel_cipso_v4.c
++++ b/net/netlabel/netlabel_cipso_v4.c
+@@ -718,36 +718,35 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
+  * NetLabel Generic NETLINK Command Definitions
+  */
+ 
+-static struct genl_ops netlbl_cipsov4_genl_c_add = {
++static struct genl_ops netlbl_cipsov4_ops[] = {
++	{
+ 	.cmd = NLBL_CIPSOV4_C_ADD,
+ 	.flags = GENL_ADMIN_PERM,
+ 	.policy = netlbl_cipsov4_genl_policy,
+ 	.doit = netlbl_cipsov4_add,
+ 	.dumpit = NULL,
+-};
+-
+-static struct genl_ops netlbl_cipsov4_genl_c_remove = {
++	},
++	{
+ 	.cmd = NLBL_CIPSOV4_C_REMOVE,
+ 	.flags = GENL_ADMIN_PERM,
+ 	.policy = netlbl_cipsov4_genl_policy,
+ 	.doit = netlbl_cipsov4_remove,
+ 	.dumpit = NULL,
+-};
+-
+-static struct genl_ops netlbl_cipsov4_genl_c_list = {
++	},
++	{
+ 	.cmd = NLBL_CIPSOV4_C_LIST,
+ 	.flags = 0,
+ 	.policy = netlbl_cipsov4_genl_policy,
+ 	.doit = netlbl_cipsov4_list,
+ 	.dumpit = NULL,
+-};
+-
+-static struct genl_ops netlbl_cipsov4_genl_c_listall = {
++	},
++	{
+ 	.cmd = NLBL_CIPSOV4_C_LISTALL,
+ 	.flags = 0,
+ 	.policy = netlbl_cipsov4_genl_policy,
+ 	.doit = NULL,
+ 	.dumpit = netlbl_cipsov4_listall,
++	},
+ };
+ 
+ /*
+@@ -762,30 +761,20 @@ static struct genl_ops netlbl_cipsov4_genl_c_listall = {
+  * mechanism.  Returns zero on success, negative values on failure.
+  *
+  */
+-int netlbl_cipsov4_genl_init(void)
++int __init netlbl_cipsov4_genl_init(void)
+ {
+-	int ret_val;
++	int ret_val, i;
+ 
+ 	ret_val = genl_register_family(&netlbl_cipsov4_gnl_family);
+ 	if (ret_val != 0)
+ 		return ret_val;
+ 
+-	ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
+-				    &netlbl_cipsov4_genl_c_add);
+-	if (ret_val != 0)
+-		return ret_val;
+-	ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
+-				    &netlbl_cipsov4_genl_c_remove);
+-	if (ret_val != 0)
+-		return ret_val;
+-	ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
+-				    &netlbl_cipsov4_genl_c_list);
+-	if (ret_val != 0)
+-		return ret_val;
+-	ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
+-				    &netlbl_cipsov4_genl_c_listall);
+-	if (ret_val != 0)
+-		return ret_val;
++	for (i = 0; i < ARRAY_SIZE(netlbl_cipsov4_ops); i++) {
++		ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
++				&netlbl_cipsov4_ops[i]);
++		if (ret_val != 0)
++			return ret_val;
++	}
+ 
+ 	return 0;
+ }
+diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c
+index fd46231..02c2f7c 100644
+--- a/net/netlabel/netlabel_domainhash.c
++++ b/net/netlabel/netlabel_domainhash.c
+@@ -171,7 +171,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)
+  * values on error.
+  *
+  */
+-int netlbl_domhsh_init(u32 size)
++int __init netlbl_domhsh_init(u32 size)
+ {
+ 	u32 iter;
+ 	struct netlbl_domhsh_tbl *hsh_tbl;
+diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
+index e2258dc..22c1912 100644
+--- a/net/netlabel/netlabel_mgmt.c
++++ b/net/netlabel/netlabel_mgmt.c
+@@ -517,68 +517,63 @@ version_failure:
+  * NetLabel Generic NETLINK Command Definitions
+  */
+ 
+-static struct genl_ops netlbl_mgmt_genl_c_add = {
++static struct genl_ops netlbl_mgmt_genl_ops[] = {
++	{
+ 	.cmd = NLBL_MGMT_C_ADD,
+ 	.flags = GENL_ADMIN_PERM,
+ 	.policy = netlbl_mgmt_genl_policy,
+ 	.doit = netlbl_mgmt_add,
+ 	.dumpit = NULL,
+-};
+-
+-static struct genl_ops netlbl_mgmt_genl_c_remove = {
++	},
++	{
+ 	.cmd = NLBL_MGMT_C_REMOVE,
+ 	.flags = GENL_ADMIN_PERM,
+ 	.policy = netlbl_mgmt_genl_policy,
+ 	.doit = netlbl_mgmt_remove,
+ 	.dumpit = NULL,
+-};
+-
+-static struct genl_ops netlbl_mgmt_genl_c_listall = {
++	},
++	{
+ 	.cmd = NLBL_MGMT_C_LISTALL,
+ 	.flags = 0,
+ 	.policy = netlbl_mgmt_genl_policy,
+ 	.doit = NULL,
+ 	.dumpit = netlbl_mgmt_listall,
+-};
+-
+-static struct genl_ops netlbl_mgmt_genl_c_adddef = {
++	},
++	{
+ 	.cmd = NLBL_MGMT_C_ADDDEF,
+ 	.flags = GENL_ADMIN_PERM,
+ 	.policy = netlbl_mgmt_genl_policy,
+ 	.doit = netlbl_mgmt_adddef,
+ 	.dumpit = NULL,
+-};
+-
+-static struct genl_ops netlbl_mgmt_genl_c_removedef = {
++	},
++	{
+ 	.cmd = NLBL_MGMT_C_REMOVEDEF,
+ 	.flags = GENL_ADMIN_PERM,
+ 	.policy = netlbl_mgmt_genl_policy,
+ 	.doit = netlbl_mgmt_removedef,
+ 	.dumpit = NULL,
+-};
+-
+-static struct genl_ops netlbl_mgmt_genl_c_listdef = {
++	},
++	{
+ 	.cmd = NLBL_MGMT_C_LISTDEF,
+ 	.flags = 0,
+ 	.policy = netlbl_mgmt_genl_policy,
+ 	.doit = netlbl_mgmt_listdef,
+ 	.dumpit = NULL,
+-};
+-
+-static struct genl_ops netlbl_mgmt_genl_c_protocols = {
++	},
++	{
+ 	.cmd = NLBL_MGMT_C_PROTOCOLS,
+ 	.flags = 0,
+ 	.policy = netlbl_mgmt_genl_policy,
+ 	.doit = NULL,
+ 	.dumpit = netlbl_mgmt_protocols,
+-};
+-
+-static struct genl_ops netlbl_mgmt_genl_c_version = {
++	},
++	{
+ 	.cmd = NLBL_MGMT_C_VERSION,
+ 	.flags = 0,
+ 	.policy = netlbl_mgmt_genl_policy,
+ 	.doit = netlbl_mgmt_version,
+ 	.dumpit = NULL,
++	},
+ };
+ 
+ /*
+@@ -593,46 +588,20 @@ static struct genl_ops netlbl_mgmt_genl_c_version = {
+  * mechanism.  Returns zero on success, negative values on failure.
+  *
+  */
+-int netlbl_mgmt_genl_init(void)
++int __init netlbl_mgmt_genl_init(void)
+ {
+-	int ret_val;
++	int ret_val, i;
+ 
+ 	ret_val = genl_register_family(&netlbl_mgmt_gnl_family);
+ 	if (ret_val != 0)
+ 		return ret_val;
+ 
+-	ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
+-				    &netlbl_mgmt_genl_c_add);
+-	if (ret_val != 0)
+-		return ret_val;
+-	ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
+-				    &netlbl_mgmt_genl_c_remove);
+-	if (ret_val != 0)
+-		return ret_val;
+-	ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
+-				    &netlbl_mgmt_genl_c_listall);
+-	if (ret_val != 0)
+-		return ret_val;
+-	ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
+-				    &netlbl_mgmt_genl_c_adddef);
+-	if (ret_val != 0)
+-		return ret_val;
+-	ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
+-				    &netlbl_mgmt_genl_c_removedef);
+-	if (ret_val != 0)
+-		return ret_val;
+-	ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
+-				    &netlbl_mgmt_genl_c_listdef);
+-	if (ret_val != 0)
+-		return ret_val;
+-	ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
+-				    &netlbl_mgmt_genl_c_protocols);
+-	if (ret_val != 0)
+-		return ret_val;
+-	ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
+-				    &netlbl_mgmt_genl_c_version);
+-	if (ret_val != 0)
+-		return ret_val;
++	for (i = 0; i < ARRAY_SIZE(netlbl_mgmt_genl_ops); i++) {
++		ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
++				&netlbl_mgmt_genl_ops[i]);
++		if (ret_val != 0)
++			return ret_val;
++	}
+ 
+ 	return 0;
+ }
+diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
+index 3e745b7..4478f2f 100644
+--- a/net/netlabel/netlabel_unlabeled.c
++++ b/net/netlabel/netlabel_unlabeled.c
+@@ -1553,68 +1553,63 @@ unlabel_staticlistdef_return:
+  * NetLabel Generic NETLINK Command Definitions
+  */
+ 
+-static struct genl_ops netlbl_unlabel_genl_c_staticadd = {
++static struct genl_ops netlbl_unlabel_genl_ops[] = {
++	{
+ 	.cmd = NLBL_UNLABEL_C_STATICADD,
+ 	.flags = GENL_ADMIN_PERM,
+ 	.policy = netlbl_unlabel_genl_policy,
+ 	.doit = netlbl_unlabel_staticadd,
+ 	.dumpit = NULL,
+-};
+-
+-static struct genl_ops netlbl_unlabel_genl_c_staticremove = {
++	},
++	{
+ 	.cmd = NLBL_UNLABEL_C_STATICREMOVE,
+ 	.flags = GENL_ADMIN_PERM,
+ 	.policy = netlbl_unlabel_genl_policy,
+ 	.doit = netlbl_unlabel_staticremove,
+ 	.dumpit = NULL,
+-};
+-
+-static struct genl_ops netlbl_unlabel_genl_c_staticlist = {
++	},
++	{
+ 	.cmd = NLBL_UNLABEL_C_STATICLIST,
+ 	.flags = 0,
+ 	.policy = netlbl_unlabel_genl_policy,
+ 	.doit = NULL,
+ 	.dumpit = netlbl_unlabel_staticlist,
+-};
+-
+-static struct genl_ops netlbl_unlabel_genl_c_staticadddef = {
++	},
++	{
+ 	.cmd = NLBL_UNLABEL_C_STATICADDDEF,
+ 	.flags = GENL_ADMIN_PERM,
+ 	.policy = netlbl_unlabel_genl_policy,
+ 	.doit = netlbl_unlabel_staticadddef,
+ 	.dumpit = NULL,
+-};
+-
+-static struct genl_ops netlbl_unlabel_genl_c_staticremovedef = {
++	},
++	{
+ 	.cmd = NLBL_UNLABEL_C_STATICREMOVEDEF,
+ 	.flags = GENL_ADMIN_PERM,
+ 	.policy = netlbl_unlabel_genl_policy,
+ 	.doit = netlbl_unlabel_staticremovedef,
+ 	.dumpit = NULL,
+-};
+-
+-static struct genl_ops netlbl_unlabel_genl_c_staticlistdef = {
++	},
++	{
+ 	.cmd = NLBL_UNLABEL_C_STATICLISTDEF,
+ 	.flags = 0,
+ 	.policy = netlbl_unlabel_genl_policy,
+ 	.doit = NULL,
+ 	.dumpit = netlbl_unlabel_staticlistdef,
+-};
+-
+-static struct genl_ops netlbl_unlabel_genl_c_accept = {
++	},
++	{
+ 	.cmd = NLBL_UNLABEL_C_ACCEPT,
+ 	.flags = GENL_ADMIN_PERM,
+ 	.policy = netlbl_unlabel_genl_policy,
+ 	.doit = netlbl_unlabel_accept,
+ 	.dumpit = NULL,
+-};
+-
+-static struct genl_ops netlbl_unlabel_genl_c_list = {
++	},
++	{
+ 	.cmd = NLBL_UNLABEL_C_LIST,
+ 	.flags = 0,
+ 	.policy = netlbl_unlabel_genl_policy,
+ 	.doit = netlbl_unlabel_list,
+ 	.dumpit = NULL,
++	},
+ };
+ 
+ /*
+@@ -1629,53 +1624,20 @@ static struct genl_ops netlbl_unlabel_genl_c_list = {
+  * mechanism.  Returns zero on success, negative values on failure.
+  *
+  */
+-int netlbl_unlabel_genl_init(void)
++int __init netlbl_unlabel_genl_init(void)
+ {
+-	int ret_val;
++	int ret_val, i;
+ 
+ 	ret_val = genl_register_family(&netlbl_unlabel_gnl_family);
+ 	if (ret_val != 0)
+ 		return ret_val;
+ 
+-	ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
+-				    &netlbl_unlabel_genl_c_staticadd);
+-	if (ret_val != 0)
+-		return ret_val;
+-
+-	ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
+-				    &netlbl_unlabel_genl_c_staticremove);
+-	if (ret_val != 0)
+-		return ret_val;
+-
+-	ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
+-				    &netlbl_unlabel_genl_c_staticlist);
+-	if (ret_val != 0)
+-		return ret_val;
+-
+-	ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
+-				    &netlbl_unlabel_genl_c_staticadddef);
+-	if (ret_val != 0)
+-		return ret_val;
+-
+-	ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
+-				    &netlbl_unlabel_genl_c_staticremovedef);
+-	if (ret_val != 0)
+-		return ret_val;
+-
+-	ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
+-				    &netlbl_unlabel_genl_c_staticlistdef);
+-	if (ret_val != 0)
+-		return ret_val;
+-
+-	ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
+-				    &netlbl_unlabel_genl_c_accept);
+-	if (ret_val != 0)
+-		return ret_val;
+-
+-	ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
+-				    &netlbl_unlabel_genl_c_list);
+-	if (ret_val != 0)
+-		return ret_val;
++	for (i = 0; i < ARRAY_SIZE(netlbl_unlabel_genl_ops); i++) {
++		ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
++				&netlbl_unlabel_genl_ops[i]);
++		if (ret_val != 0)
++			return ret_val;
++	}
+ 
+ 	return 0;
+ }
+@@ -1699,7 +1661,7 @@ static struct notifier_block netlbl_unlhsh_netdev_notifier = {
+  * non-zero values on error.
+  *
+  */
+-int netlbl_unlabel_init(u32 size)
++int __init netlbl_unlabel_init(u32 size)
+ {
+ 	u32 iter;
+ 	struct netlbl_unlhsh_tbl *hsh_tbl;
+@@ -1803,7 +1765,7 @@ unlabel_getattr_nolabel:
+  * and to send unlabeled network traffic by default.
+  *
+  */
+-int netlbl_unlabel_defconf(void)
++int __init netlbl_unlabel_defconf(void)
+ {
+ 	int ret_val;
+ 	struct netlbl_dom_map *entry;
+diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c
+index 023fc8f..b17d420 100644
+--- a/net/netlabel/netlabel_user.c
++++ b/net/netlabel/netlabel_user.c
+@@ -59,7 +59,7 @@
+  * non-zero on failure.
+  *
+  */
+-int netlbl_netlink_init(void)
++int __init netlbl_netlink_init(void)
+ {
+ 	int ret_val;
+ 
+diff --git a/net/rxrpc/ar-accept.c b/net/rxrpc/ar-accept.c
+index 92a87fd..bdfb774 100644
+--- a/net/rxrpc/ar-accept.c
++++ b/net/rxrpc/ar-accept.c
+@@ -156,8 +156,7 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local,
+ 						  false);
+ 			spin_unlock(&call->lock);
+ 			notification = NULL;
+-			if (ret < 0)
+-				BUG();
++			BUG_ON(ret < 0);
+ 		}
+ 		spin_unlock(&call->conn->state_lock);
+ 
+diff --git a/net/rxrpc/ar-ack.c b/net/rxrpc/ar-ack.c
+index 657ee69..3ac1672 100644
+--- a/net/rxrpc/ar-ack.c
++++ b/net/rxrpc/ar-ack.c
+@@ -814,8 +814,7 @@ static int rxrpc_post_message(struct rxrpc_call *call, u32 mark, u32 error,
+ 		spin_lock_bh(&call->lock);
+ 		ret = rxrpc_queue_rcv_skb(call, skb, true, fatal);
+ 		spin_unlock_bh(&call->lock);
+-		if (ret < 0)
+-			BUG();
++		BUG_ON(ret < 0);
+ 	}
+ 
+ 	return 0;
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index 47219f9..9fc4c31 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -331,15 +331,31 @@ static void xfrm_dst_hash_transfer(struct hlist_head *list,
+ 				   struct hlist_head *ndsttable,
+ 				   unsigned int nhashmask)
+ {
+-	struct hlist_node *entry, *tmp;
++	struct hlist_node *entry, *tmp, *entry0 = NULL;
+ 	struct xfrm_policy *pol;
++	unsigned int h0 = 0;
+ 
++redo:
+ 	hlist_for_each_entry_safe(pol, entry, tmp, list, bydst) {
+ 		unsigned int h;
+ 
+ 		h = __addr_hash(&pol->selector.daddr, &pol->selector.saddr,
+ 				pol->family, nhashmask);
+-		hlist_add_head(&pol->bydst, ndsttable+h);
++		if (!entry0) {
++			hlist_del(entry);
++			hlist_add_head(&pol->bydst, ndsttable+h);
++			h0 = h;
++		} else {
++			if (h != h0)
++				continue;
++			hlist_del(entry);
++			hlist_add_after(entry0, &pol->bydst);
++		}
++		entry0 = entry;
++	}
++	if (!hlist_empty(list)) {
++		entry0 = NULL;
++		goto redo;
+ 	}
+ }
+ 
+diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
+index 3929e5b..4a03191 100644
+--- a/scripts/kconfig/symbol.c
++++ b/scripts/kconfig/symbol.c
+@@ -298,22 +298,30 @@ void sym_calc_value(struct symbol *sym)
+ 		if (sym_is_choice_value(sym) && sym->visible == yes) {
+ 			prop = sym_get_choice_prop(sym);
+ 			newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
+-		} else if (EXPR_OR(sym->visible, sym->rev_dep.tri) != no) {
+-			sym->flags |= SYMBOL_WRITE;
+-			if (sym_has_value(sym))
+-				newval.tri = sym->def[S_DEF_USER].tri;
+-			else if (!sym_is_choice(sym)) {
+-				prop = sym_get_default_prop(sym);
+-				if (prop)
+-					newval.tri = expr_calc_value(prop->expr);
++		} else {
++			if (sym->visible != no) {
++				/* if the symbol is visible use the user value
++				 * if available, otherwise try the default value
++				 */
++				sym->flags |= SYMBOL_WRITE;
++				if (sym_has_value(sym)) {
++					newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
++							      sym->visible);
++					goto calc_newval;
++				}
+ 			}
+-			newval.tri = EXPR_OR(EXPR_AND(newval.tri, sym->visible), sym->rev_dep.tri);
+-		} else if (!sym_is_choice(sym)) {
+-			prop = sym_get_default_prop(sym);
+-			if (prop) {
++			if (sym->rev_dep.tri != no)
+ 				sym->flags |= SYMBOL_WRITE;
+-				newval.tri = expr_calc_value(prop->expr);
++			if (!sym_is_choice(sym)) {
++				prop = sym_get_default_prop(sym);
++				if (prop) {
++					sym->flags |= SYMBOL_WRITE;
++					newval.tri = EXPR_AND(expr_calc_value(prop->expr),
++							      prop->visible.tri);
++				}
+ 			}
++		calc_newval:
++			newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
+ 		}
+ 		if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
+ 			newval.tri = yes;
+diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
+index 6174277..695b5d6 100644
+--- a/scripts/mod/modpost.c
++++ b/scripts/mod/modpost.c
+@@ -1200,7 +1200,7 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
+ 		"annotate %s with a matching annotation.\n",
+ 		from, sec2annotation(fromsec), fromsym, from_p,
+ 		to, sec2annotation(tosec), tosym, to_p,
+-		fromsym, tosym, fromsym);
++		tosym, fromsym, tosym);
+ 		break;
+ 	case INIT_TO_EXIT:
+ 		fprintf(stderr,
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index 2b5d6f7..25cbfa3 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -1251,9 +1251,8 @@ static void smack_to_secattr(char *smack, struct netlbl_lsm_secattr *nlsp)
+ 
+ 	switch (smack_net_nltype) {
+ 	case NETLBL_NLTYPE_CIPSOV4:
+-		nlsp->domain = NULL;
+-		nlsp->flags = NETLBL_SECATTR_DOMAIN;
+-		nlsp->flags |= NETLBL_SECATTR_MLS_LVL;
++		nlsp->domain = kstrdup(smack, GFP_ATOMIC);
++		nlsp->flags = NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL;
+ 
+ 		rc = smack_to_cipso(smack, &cipso);
+ 		if (rc == 0) {
+@@ -1282,15 +1281,14 @@ static int smack_netlabel(struct sock *sk)
+ {
+ 	struct socket_smack *ssp;
+ 	struct netlbl_lsm_secattr secattr;
+-	int rc = 0;
++	int rc;
+ 
+ 	ssp = sk->sk_security;
+ 	netlbl_secattr_init(&secattr);
+ 	smack_to_secattr(ssp->smk_out, &secattr);
+-	if (secattr.flags != NETLBL_SECATTR_NONE)
+-		rc = netlbl_sock_setattr(sk, &secattr);
+-
++	rc = netlbl_sock_setattr(sk, &secattr);
+ 	netlbl_secattr_destroy(&secattr);
++
+ 	return rc;
+ }
+ 
+@@ -1313,6 +1311,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
+ 	struct inode_smack *nsp = inode->i_security;
+ 	struct socket_smack *ssp;
+ 	struct socket *sock;
++	int rc = 0;
+ 
+ 	if (value == NULL || size > SMK_LABELLEN)
+ 		return -EACCES;
+@@ -1341,7 +1340,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
+ 		ssp->smk_in = sp;
+ 	else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
+ 		ssp->smk_out = sp;
+-		return smack_netlabel(sock->sk);
++		rc = smack_netlabel(sock->sk);
++		if (rc != 0)
++			printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n",
++			       __func__, -rc);
+ 	} else
+ 		return -EOPNOTSUPP;
+ 
+@@ -2214,6 +2216,9 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent)
+ 	ssp->smk_packet[0] = '\0';
+ 
+ 	rc = smack_netlabel(sk);
++	if (rc != 0)
++		printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n",
++		       __func__, -rc);
+ }
+ 
+ /**
+@@ -2346,6 +2351,20 @@ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+ }
+ 
+ /*
++ * smack_secctx_to_secid - return the secid for a smack label
++ * @secdata: smack label
++ * @seclen: how long result is
++ * @secid: outgoing integer
++ *
++ * Exists for audit and networking code.
++ */
++static int smack_secctx_to_secid(char *secdata, u32 seclen, u32 *secid)
++{
++	*secid = smack_to_secid(secdata);
++	return 0;
++}
++
++/*
+  * smack_release_secctx - don't do anything.
+  * @key_ref: unused
+  * @context: unused
+@@ -2475,6 +2494,7 @@ static struct security_operations smack_ops = {
+ 	.key_permission = 		smack_key_permission,
+ #endif /* CONFIG_KEYS */
+ 	.secid_to_secctx = 		smack_secid_to_secctx,
++	.secctx_to_secid = 		smack_secctx_to_secid,
+ 	.release_secctx = 		smack_release_secctx,
+ };
+ 
+diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
+index 15aa37f..358c92c 100644
+--- a/security/smack/smackfs.c
++++ b/security/smack/smackfs.c
+@@ -24,6 +24,7 @@
+ #include <net/cipso_ipv4.h>
+ #include <linux/seq_file.h>
+ #include <linux/ctype.h>
++#include <linux/audit.h>
+ #include "smack.h"
+ 
+ /*
+@@ -45,6 +46,7 @@ enum smk_inos {
+  */
+ static DEFINE_MUTEX(smack_list_lock);
+ static DEFINE_MUTEX(smack_cipso_lock);
++static DEFINE_MUTEX(smack_ambient_lock);
+ 
+ /*
+  * This is the "ambient" label for network traffic.
+@@ -342,6 +344,9 @@ void smk_cipso_doi(void)
+ 	struct cipso_v4_doi *doip;
+ 	struct netlbl_audit audit_info;
+ 
++	audit_info.loginuid = audit_get_loginuid(current);
++	audit_info.secid = smack_to_secid(current->security);
++
+ 	rc = netlbl_cfg_map_del(NULL, &audit_info);
+ 	if (rc != 0)
+ 		printk(KERN_WARNING "%s:%d remove rc = %d\n",
+@@ -363,6 +368,30 @@ void smk_cipso_doi(void)
+ 		       __func__, __LINE__, rc);
+ }
+ 
++/**
++ * smk_unlbl_ambient - initialize the unlabeled domain
++ */
++void smk_unlbl_ambient(char *oldambient)
++{
++	int rc;
++	struct netlbl_audit audit_info;
++
++	audit_info.loginuid = audit_get_loginuid(current);
++	audit_info.secid = smack_to_secid(current->security);
++
++	if (oldambient != NULL) {
++		rc = netlbl_cfg_map_del(oldambient, &audit_info);
++		if (rc != 0)
++			printk(KERN_WARNING "%s:%d remove rc = %d\n",
++			       __func__, __LINE__, rc);
++	}
++
++	rc = netlbl_cfg_unlbl_add_map(smack_net_ambient, &audit_info);
++	if (rc != 0)
++		printk(KERN_WARNING "%s:%d add rc = %d\n",
++		       __func__, __LINE__, rc);
++}
++
+ /*
+  * Seq_file read operations for /smack/cipso
+  */
+@@ -709,7 +738,6 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
+ 				size_t cn, loff_t *ppos)
+ {
+ 	ssize_t rc;
+-	char out[SMK_LABELLEN];
+ 	int asize;
+ 
+ 	if (*ppos != 0)
+@@ -717,23 +745,18 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
+ 	/*
+ 	 * Being careful to avoid a problem in the case where
+ 	 * smack_net_ambient gets changed in midstream.
+-	 * Since smack_net_ambient is always set with a value
+-	 * from the label list, including initially, and those
+-	 * never get freed, the worst case is that the pointer
+-	 * gets changed just after this strncpy, in which case
+-	 * the value passed up is incorrect. Locking around
+-	 * smack_net_ambient wouldn't be any better than this
+-	 * copy scheme as by the time the caller got to look
+-	 * at the ambient value it would have cleared the lock
+-	 * and been changed.
+ 	 */
+-	strncpy(out, smack_net_ambient, SMK_LABELLEN);
+-	asize = strlen(out) + 1;
++	mutex_lock(&smack_ambient_lock);
+ 
+-	if (cn < asize)
+-		return -EINVAL;
++	asize = strlen(smack_net_ambient) + 1;
++
++	if (cn >= asize)
++		rc = simple_read_from_buffer(buf, cn, ppos,
++					     smack_net_ambient, asize);
++	else
++		rc = -EINVAL;
+ 
+-	rc = simple_read_from_buffer(buf, cn, ppos, out, asize);
++	mutex_unlock(&smack_ambient_lock);
+ 
+ 	return rc;
+ }
+@@ -751,6 +774,7 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
+ 				 size_t count, loff_t *ppos)
+ {
+ 	char in[SMK_LABELLEN];
++	char *oldambient;
+ 	char *smack;
+ 
+ 	if (!capable(CAP_MAC_ADMIN))
+@@ -766,7 +790,13 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
+ 	if (smack == NULL)
+ 		return -EINVAL;
+ 
++	mutex_lock(&smack_ambient_lock);
++
++	oldambient = smack_net_ambient;
+ 	smack_net_ambient = smack;
++	smk_unlbl_ambient(oldambient);
++
++	mutex_unlock(&smack_ambient_lock);
+ 
+ 	return count;
+ }
+@@ -974,6 +1004,7 @@ static int __init init_smk_fs(void)
+ 
+ 	sema_init(&smack_write_sem, 1);
+ 	smk_cipso_doi();
++	smk_unlbl_ambient(NULL);
+ 
+ 	return err;
+ }

Modified: dists/trunk/linux-2.6/debian/patches/series/1~experimental.1
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/1~experimental.1	(original)
+++ dists/trunk/linux-2.6/debian/patches/series/1~experimental.1	Thu Feb 21 14:20:50 2008
@@ -1,3 +1,4 @@
++ bugfix/all/patch-2.6.25-rc2-git5
 + debian/version.patch
 + debian/kernelvariables.patch
 + debian/doc-build-parallel.patch
@@ -31,6 +32,4 @@
 + bugfix/arm/disable-r6040.patch
 + features/all/at76.patch 
 #the following will be fixed before 2.6.25 is out:
-+ bugfix/sata_mv-platform_driver.patch
 + bugfix/arm/ignore-invalid-memtags.patch
-



More information about the Kernel-svn-changes mailing list